Commit Graph
145 Commits
Author SHA1 Message Date
efrilmandClaude Opus 5 ebf666c004 feat(product): require a unit for weight-based products
A product sold by weight with no unit produces order lines with nothing to
print: the receipt would read "4,2" with no idea of what. Until now nothing
stopped that — the mistake only surfaced at the cashier.

Enforce it in two places, because neither alone sees the whole picture. On
create, the validator has everything it needs. On update, the request may
omit unit_id for a product that already has one, so the check runs in the
processor against the merged product: what is rejected is the end state, a
product sold by weight with no unit.

Also fixes two things this uncovered:

The struct tags on the product contracts are decorative — this validator is
hand-written and never calls validator.Struct — so `oneof=unit weight` was
never enforced, and an unknown sell_by was silently rewritten to "unit" by
the mapper. It is now rejected with a message that names the valid values.

The update validator's "at least one field" guard did not list unit_id,
sell_by or print_to_checker, so an update carrying only one of those was
turned away as an empty request.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-06 17:29:34 +07:00
efrilmandClaude Opus 5 992bb04816 feat(order): support weight-based products
Products like fish are sold per weighing (4.2 ons, 5.6 ons), which the
order line could not represent: quantity is INTEGER and prices are always
computed as quantity * unit_price.

Model one weighing as one order line. quantity stays INTEGER and keeps
meaning "how many items"; the measured amount goes into a new nullable
order_items.weight, and the line is priced weight * unit_price. Two
weighings of the same product are two lines, never merged into one.

Keeping quantity integral avoids float comparisons in void, refund and
split bill, where accumulated rounding error would silently misbehave —
"1.4 + 1.4 + 1.4" is not 4.2 in float64, which would leave a fully paid
split-bill item marked unpaid.

BillableQuantity() is now the single place that decides between weight
and count; every price and cost calculation goes through it. Missing one
would bill a 4.2 ons fish as a single ons — wrong money, no error.

Two database constraints back the design: a weighed line always carries a
positive weight, and its quantity is pinned to 1. The latter also makes
void all-or-nothing for weighed lines, so the row-splitting branch can
never produce a zero-weight remainder row.

Also wires product.unit_id through the API, which was previously not
settable at all, and corrects the misleading comment on the request's
unit_price field — that value has never been used; price always comes
from the database.

Design notes and the audit of every price multiplication site are in
docs/rfc-weight-based-products.md.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-06 17:14:42 +07:00
Efril 2c6864147b feat: cash advance 2026-08-13 14:38:28 +07:00
Efril e6078e3c0b feat(purchase 2026-08-11 22:41:10 +07:00
efrilm dbc143954c feat(purchase): unwired unit convertions 2026-08-11 21:24:24 +07:00
efrilm 0726fcecf0 feat(ingredients): make units nullable 2026-08-11 21:20:17 +07:00
efrilm 9ae5be2c33 feat(purchasae): added team with category parent and central 2026-08-11 21:00:39 +07:00
Efril b9ac97178f feat: profit sharing 2026-08-05 19:28:38 +07:00
Efril 9b0fc9a63b feat: updat analytic profit loss add purchasing 2026-06-24 00:11:04 +07:00
Efril 793919cf10 feat: add outlet name at analytic response and new overview dashboard 2026-06-23 22:18:16 +07:00
ryan 66d4c9f0af Update purchase order with outlet id 2026-06-18 15:27:20 +07:00
ryan 55119b3e91 Add MTD 2026-06-18 14:19:45 +07:00
ryan c1d859ebdd Make vendor nullable 2026-06-18 11:04:59 +07:00
ryan 2ad9e2f85f Fix total_amount to use base price 2026-06-18 09:52:16 +07:00
ryan 0db838e2c4 Fix bank 2026-06-17 18:26:40 +07:00
ryan 4b6cbb69c1 Add exclusive-summary 2026-06-17 18:17:08 +07:00
ryan 1718c5adab Fix expense to be nullable without raw material. 2026-06-10 14:25:23 +07:00
ryan d0c090a657 Update purchase analytics 2026-06-10 13:18:49 +07:00
ryan c3db919531 Update expense for product category (non-inventory type) 2026-06-10 12:42:53 +07:00
ryan e09feff36d Update purchase for product category (inventory type) 2026-06-09 15:59:34 +07:00
ryan e7dd9660da Merge remote-tracking branch 'origin' into feature/expense
# Conflicts:
#	internal/router/router.go
2026-06-09 13:25:09 +07:00
Efril c57620beeb feat: update product analytic 2026-06-08 19:32:30 +07:00
ryan 69d8c8ce5e Add category table 2026-06-08 12:29:59 +07:00
Efril ea9dceb333 fix: prevent race condition on order subtotal calculation 2026-06-03 23:59:15 +07:00
ryan 094e8b2a47 Add expense analytics 2026-06-03 14:56:27 +07:00
ryan b90a3cde4a Fix coa summary zero 2026-06-03 13:00:50 +07:00
ryan 7c8c7fb7db update expense coa 2026-06-02 16:32:20 +07:00
ryan 47fa21d739 reinstate profit loss overview 2026-06-01 13:13:40 +07:00
ryan dc13bb5f93 update due date and range date 2026-05-29 18:24:14 +07:00
ryan d26f5c5354 add status to expense 2026-05-29 15:44:59 +07:00
ryan 1b7bec4f81 update expense item name 2026-05-29 13:25:38 +07:00
Efril f7399fd0e7 Merge branch 'main' of https://gits.altru.id/apksel-dev/apskel-pos-backend into feature/expense 2026-05-29 12:34:34 +07:00
Efril 84222fc7f4 update 2026-05-28 15:30:18 +07:00
Efril 23ac572e3f add print_to_checker at product outlet 2026-05-28 13:49:57 +07:00
ryan a55a3f4ee2 add expense_name 2026-05-26 15:25:47 +07:00
ryan 024d9ee637 Update profit-loss 2026-05-26 14:59:56 +07:00
Efril 957c1ae53d update order response 2026-05-25 20:28:24 +07:00
ryan b8be29e110 Add item_expense 2026-05-25 16:19:36 +07:00
ryan da87d659df Add expense CRUD 2026-05-25 14:59:40 +07:00
Efril d0378b5ac4 update category 2026-05-21 23:05:25 +07:00
Efril 72f67cb519 create or update product assign to product outlet 2026-05-21 21:20:54 +07:00
ryan 35e7152abb add purchasing in analytics endpoint 2026-05-19 14:45:26 +07:00
Efril 50d633ee3a fix products 2026-05-14 01:19:45 +07:00
Efril 21fa21d089 get products all 2026-05-14 00:15:28 +07:00
ryan 5f379faf17 change product list to retrieve its data from product outlets 2026-05-13 23:15:09 +07:00
ryan 3b62504798 fix 2026-05-13 22:30:55 +07:00
ryan 4130cb66df refactor and add outlet product table 2026-05-13 21:58:54 +07:00
ryan 6064ef8fde Update QR token generation 2026-05-10 14:52:02 +07:00
ryan 2c34578a98 Merge remote-tracking branch 'origin/feature/notification' into self-order+notification
# Conflicts:
#	go.mod
#	go.sum
#	internal/app/app.go
#	internal/router/router.go
2026-05-10 12:23:16 +07:00
Efril 9d71b339b5 notification 2026-05-10 10:57:38 +07:00