Commit Graph
77 Commits
Author SHA1 Message Date
efrilmandClaude Opus 5.5 e5db0325cc feat(wallet): serve customer balances and history from the wallet
GET /customer/wallet now reads the EnakPoint & EnakCoin wallet
(docs/prd-point-coin.md F6, PC-106): spendable point and coin balances, the
rupiah value of one EnakPoint and of the balance, the nearest day each
currency loses balance (grouped by Asia/Jakarta day), and recent ledger
rows. The fields of the pre-wallet response stay, filled from the wallet, so
app versions that read them keep working.

Adds GET /customer/wallet/transactions with pagination and filters for
currency, one or more types, and an inclusive date range. Each row shows
where the value came from (additions) or went to (deductions) as in §8.1,
and additions list their lots and earliest expiry. The counterparty id, the
admin and the metadata are left out; the description already carries the
masked name. A malformed query answers 400, a missing customer 404.

/customer/points and /customer/tokens keep their shape and now read the
wallet too, so customer_points_repository is no longer used for balances.

Balances are what the customer can spend: lots that have expired but that
the expiry job has not processed are not counted. The point value is read
from organization_settings (loyalty.point.value, default 1) through a small
repository that the typed settings reader in PC-109 will build on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 09:15:26 +07:00
efrilmandClaude Opus 5.5 41b75810fd feat(wallet): migrate legacy points and tokens into the wallet
Adds cmd/wallet-migrate (make wallet-migrate, args=-dry-run to only report),
which moves customer_points and customer_tokens into the wallet
(docs/prd-point-coin.md §10, PC-105). Each customer gets a MIGRATION ledger
row and a non-expiring lot per currency, written through WalletProcessor in
one transaction per customer. EnakCoin is the sum of every token type (Q6),
with the legacy rows listed in the row's metadata.

It credits the difference between the legacy balance and what earlier runs
migrated, so running it again never doubles a balance and picks up only
what the old code added since. A legacy balance that shrank after being
migrated is reported and left alone, since only an admin adjustment may
take balance away, and the command then exits non-zero. It ends with a
legacy / migrated / wallet total per currency.

Migration 000092 renames TOKENS to COINS in campaigns.type and
campaign_rules.reward_type. The campaign API now validates COINS; it still
accepts TOKENS, including as a list filter, and stores it as COINS so older
dashboards keep working while they are updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 08:47:48 +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 9ae5be2c33 feat(purchasae): added team with category parent and central 2026-08-11 21:00:39 +07:00
Efril a7c2d6cbb3 feat(category): update list filter category 2026-08-06 21:21:41 +07:00
Efril b9ac97178f feat: profit sharing 2026-08-05 19:28:38 +07:00
Efril e345aeee97 feat: new users role 2026-06-19 13:31:33 +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 4b6cbb69c1 Add exclusive-summary 2026-06-17 18:17:08 +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
ryan 29aeb58fc0 Fix formatting 2026-06-08 12:30:39 +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
Efril afa1aa5b75 Merge branch 'main' of https://gits.altru.id/apksel-dev/apskel-pos-backend 2026-06-03 22:02:14 +07:00
Efril 328336ea5a fix log error and omset tracker scheduled 2026-06-03 22:01:58 +07:00
ryan 094e8b2a47 Add expense analytics 2026-06-03 14:56:27 +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
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 23ac572e3f add print_to_checker at product outlet 2026-05-28 13:49:57 +07:00
Efril 66a8126da0 expense filter by outlet and date range 2026-05-28 11:52:16 +07:00
ryan 024d9ee637 Update profit-loss 2026-05-26 14:59:56 +07:00
ryan da87d659df Add expense CRUD 2026-05-25 14:59:40 +07:00
Efril 91960f0e57 categories add outlet id 2026-05-21 21:27:57 +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 d38a770ec5 Add omset milestone scheduler with owner role and revenue tracking 2026-05-13 09:48:17 +07:00
Efril f73a5d533c add notif at create order 2026-05-10 23:36:22 +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
Efril bbd6666299 user devices 2026-05-10 10:42:09 +07:00
ryan 07b186c986 Barcode generation with Boombuler 2026-05-09 01:01:25 +07:00
ryan 3c103b7692 Token and session implementation with Redis 2026-05-08 18:41:14 +07:00
Efril a7022dd4c1 ingredient composition 2026-04-27 21:17:12 +07:00
Efril eb95459578 fix if order amount 0 2026-04-26 23:40:01 +07:00
Aditya Siregar b29677a192 Fix Product Analysitcs 2025-09-22 22:12:54 +07:00
Aditya Siregar 26ac7a2752 update refresh token 2025-09-20 17:24:39 +07:00
Aditya Siregar f85929c575 Add Refresh token 2025-09-20 17:17:00 +07:00
Aditya Siregar a520d0ed11 fix campaign rules 2025-09-18 13:39:37 +07:00
Aditya Siregar be92ec8b23 test wheels 2025-09-18 12:01:20 +07:00