fix(money,orders): wage/gram-debt parity, atomic document confirm, expert edit, made-to-order, QA fixes
- Rial wage and gram-debt arithmetic matched to the reference; order corrections keep debt in sync - Document confirm/un-confirm is a compare-and-swap (no double-applied cache under concurrency) - Settlement document and expert inputs validated (400 instead of 500) - Expert: edit / activate-deactivate own customers, adjust raw weights only - Made-to-order flow in the app, PreOrder.quantity migration - Order grids: customer column, sort keys; panel select search; pre-order quantity save - Rebuilt release artifacts Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
959a272227
commit
6514b05d18
@@ -305,7 +305,7 @@ Target: `apps/api/src/modules/admin-documents/admin-documents.service.ts` (447 l
|
||||
| Operation | Reference | Target | Status |
|
||||
|---|---|---|---|
|
||||
| List documents | `index` + TableEngine | `list` scoped to REPAYMENT types | ✅ |
|
||||
| Create document (4 types) | `store` auto-confirms | `create` delegates to LedgerService | ✅ |
|
||||
| Create document (4 types) | `store` auto-confirms | `create` delegates to LedgerService and posts it confirmed (2026-10-29) | ✅ |
|
||||
| Update document | `update` | `update` — refuses amount change on confirmed | ✅ stricter |
|
||||
| Toggle confirm | `toggleConfiremCash` + SMS + notification | `toggleConfirm` → LedgerService (balance reversal on unconfirm) | ✅ |
|
||||
| Delete document | `destroy` | `remove` — refuses confirmed entries | ✅ stricter |
|
||||
|
||||
@@ -1435,3 +1435,102 @@ _No schema change, no data deleted._
|
||||
- **Matrix row:** n/a
|
||||
|
||||
_No schema change, no data deleted._
|
||||
|
||||
---
|
||||
|
||||
## 2026-10-29 — Money audit against henza_server/henza_pwa — wage, rial wage, gram debt
|
||||
|
||||
Unit confirmed by the owner: `rial_pay`, `rial_remain` and every rial figure are
|
||||
**ریال** (the reference PWA's «تومان» suffix was a labelling slip). Nothing to convert.
|
||||
|
||||
- **Verified equal to the reference (parity test, hand-typed PHP):** order grams /
|
||||
making-charge grams / rial charge (`setOrder`), debt only while delivered
|
||||
(`updateRemain`), melted-gold and cash conversions (`CashController::store`).
|
||||
`accounting/reference-parity.spec.ts`.
|
||||
- **Fixed — formula:** the promotion exclusion list («استثنا») is honoured when pricing
|
||||
(`pricing/wage.service.ts`; reference `checkIgnoreList`). A product, category, brand or
|
||||
customer on it no longer gets a discount taken off its making charge.
|
||||
- **Fixed — gram debt:** editing an unconfirmed melted-gold / cash document recomputes
|
||||
the credited grams from the corrected raw figures and stores the karat / price per gram
|
||||
(`admin-documents.service.ts`, shared `repaymentToGrams`). A document an admin files is
|
||||
confirmed at once, as `CashController::store` does (`confirmed = 1`); only a customer's own
|
||||
submission would wait (`set-findoc`, not built).
|
||||
- **Fixed — rial wage display:** the app cart, cart total and order detail show «اجرت
|
||||
ریالی»; the wholesale and sourcing grids bind the columns the API now returns (`input`,
|
||||
`wage`, `rial_input`, `discount`) and the order modal shows each line's weight and rial
|
||||
charge × quantity.
|
||||
- **Added — reference features that were missing:** admin line edit / delete
|
||||
(`order-item/edit`, `DELETE major/order_item/{id}`) and the sales expert's real-weight
|
||||
entry + «ثبت نهایی» (`PUT order/child/{id}`). Both recompute the order's totals and the
|
||||
debt server-side (a correction entry on the ledger) and re-queue an already-sent accounting
|
||||
document. Reference defects NOT copied: `orderItemEdit` set the order's `wage` to its whole
|
||||
weight and left `rial_input` stale; `updateChildOrder` dropped the making charge (read a
|
||||
`percent_pay` its lines do not have) and let any customer edit any order.
|
||||
- **Fixed — consistency:** a cancelled order no longer counts in «میزان فروش» (legacy
|
||||
deleted it); the panel's order builder prices a line with no typed percent like the app
|
||||
does (customer % + variant % − promotion); the accounting document's weight check allows
|
||||
for the four-decimal rounding of stored unit weights (`accounting-sync/document-check.ts`).
|
||||
- **Left alone, owner's call:** dashboard «طلای فروشرفته» counts delivered orders only
|
||||
(reference summed all; area is in PROTECTED.md).
|
||||
|
||||
## 2026-10-29 — Reference app menus that were missing in user-app-v2
|
||||
|
||||
Checked every entry of `henza_pwa` (router, dashboard, «مشتریان من») against the app.
|
||||
«سفارش مشتریان» (`ChildOrder`) already existed. What was missing, now added:
|
||||
|
||||
- **«مشتریان من» — فعال/غیرفعال کردن and ویرایش** (reference `customer/toggle-active`,
|
||||
`customer/update`): `PUT expert/customers/:id`, `POST expert/customers/:id/toggle-active`
|
||||
(`sales-expert-app`). Scoped to the expert's OWN customers (the reference toggle checked
|
||||
nothing). The edit takes contact details only — name, mobile (one-mobile-one-person rule),
|
||||
phones, store, pasazh, address, national code, birth date, city — and never the percent,
|
||||
credit limit, kind, expert or account switches, whatever the request carries. Switching a
|
||||
customer back on texts them, as the reference did.
|
||||
- **«سفارش ساخت»** (`makeOrder` / `makeOrder_status`, reference `create-custom-order`,
|
||||
`get-custom-orders`): `POST|GET customer/me/pre-orders`, two app screens
|
||||
(`MakeOrderView`, `MakeOrderStatusView`), a dashboard row with the reference's two-button
|
||||
choice. New column `PreOrder.quantity` (legacy `sum`; migration
|
||||
`20261029120000_preorder_quantity`), shown and editable in the admin grid instead of a
|
||||
hard-coded 1. The reference's «تایید سفارش / ارسال سفارش» buttons for workshop users are
|
||||
not carried over (both posted the same status, with no ownership check).
|
||||
- **Not added, owner's call:** adding a NEW customer from the app (reference `addUser`,
|
||||
`customer/create` with `from_reagent`) — it created the account with a fixed 100 g credit
|
||||
limit and 3 % percent; that is a money decision.
|
||||
|
||||
## 2026-10-29 — Browser run against the real stack (Chrome, scratch database)
|
||||
|
||||
API (migrated from empty by its own runner), admin panel and user app were started and
|
||||
driven in Chrome. The earlier fixes held; three defects that unit tests could not see were
|
||||
found and fixed:
|
||||
|
||||
- **Order grids showed no customer.** The «مشتری» column of «لیست سفارشهای عمده» / «لیست
|
||||
تامین» binds `customer.name`, which the row never carried (blank cell for every order, since
|
||||
before this audit). `admin-orders.service.ts` now sends `customer.name`; covered by a spec.
|
||||
- **Typed search in the panel selects found nothing.** ant-design-vue 4 hands a custom
|
||||
`filter-option` the option slot as a function, so the legacy `option.children[0].children`
|
||||
was always undefined. New `admin-panel/src/utils/select.ts` (`optionText`) replaces it in all
|
||||
11 views that had the pattern (order builders, documents, invoices, branches, categories,
|
||||
promotions, …).
|
||||
- **«سفارش ساختنی»: quantity edited in the panel was not saved** — the edit field existed but
|
||||
the save only sent colours. `MakeOrder.vue` now sends `sum` too.
|
||||
|
||||
Not touched: `/add/findoc` (direct link) renders blank — `open` is a Boolean prop, so Vue
|
||||
makes it `false` rather than `undefined` and the page thinks it is a modal. Nothing links to
|
||||
the route (the list page opens the form as a modal), so it was left.
|
||||
|
||||
## 2026-10-29 — QA round: money paths, sorting, malformed input
|
||||
|
||||
- **Money — fixed:** confirming / un-confirming a settlement document was check-then-update, so
|
||||
simultaneous requests (a double-click, two admins) each moved the cached balance. 10 at once
|
||||
left the book at 8.04 g and `Customer.goldDebtGrams` at 71.44 g. `LedgerService.setConfirmed` now flips
|
||||
the flag as a compare-and-swap and only the winner moves the balance, in one transaction;
|
||||
`AdminDocumentsService.toggleConfirm` and `confirmEntry` use it, and the customer is texted only when
|
||||
the state really changed. Re-run live: cache = book = recomputed after 10 simultaneous toggles.
|
||||
- **500s turned into 400s:** settlement-document figures that are not numbers or do not fit their
|
||||
columns; the expert weight entry when `items` is not a list; expert edit fields that are objects.
|
||||
An order line is capped at 100 000 pieces (the panel line edit already was).
|
||||
- **Order grids:** sorting by «جمع کل سفارش», «اجرت ریالی», «مشتری» answered 400 on the wholesale and
|
||||
sourcing grids. The grid now sorts by a column's filter key when it has one, and the API keeps the
|
||||
default order for a sort field it cannot map instead of failing the request.
|
||||
- **Not changed on purpose:** the wallet charge (`customers-omde/wallet/charge`) still answers 500 to
|
||||
a non-numeric value; the wallet belongs to the retail site (owner). An admin can still move a
|
||||
credit-limit-SUSPENDED order straight to delivered (the limit is checked at placement only).
|
||||
|
||||
Reference in New Issue
Block a user