feat(orders): credit each order to the expert who placed it, as legacy did

Legacy fixed `orders.reagent_id` once, when the order was placed, and its
«میزان فروش» summed `customer_id = X OR reagent_id = X`. The app credited
orders to the customer's CURRENT referrer and left out an expert's own
orders, so 9 of 49 imported experts showed a different figure.

- Order.salesAgentId (+ referrerCustomerId for 17 legacy orders whose
  referrer was not an expert); additive migration, recent app orders
  backfilled from the customer's referrer
- createOrder records the expert at placement time
- one shared filter (agent-orders.ts) for the experts list, expert
  detail, dashboard and the expert app; child orders follow salesAgentId
- customer page gets its «میزان فروش» back
- import carries orders.reagent_id as is; ex-experts kept as admins keep
  their profile so their own orders stay linked
- reconcile-sales: 1,557 of 1,558 match legacy's own formula; balances
  unchanged

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
s.esmaeili
2026-10-08 10:40:21 +03:30
co-authored by Claude Opus 5.5
parent 8c5d971d1f
commit 29084904e9
14 changed files with 267 additions and 26 deletions
@@ -50,10 +50,11 @@ export class SalesExpertAppService {
const search = (params.search ?? '').trim();
const scope: Prisma.OrderWhereInput = {
// The order belongs to one of THIS expert's referred customers. An
// expert can never see another expert's customers, and no id from the
// request takes part in this.
customer: { referredByAgentId: agentId },
// Legacy getChildOrder: `where('reagent_id', auth()->id())`
// (ApiMobileController.php:779) — the orders credited to THIS expert when
// they were placed (Order.salesAgentId), not the customer's current
// referrer. No id from the request takes part in this.
salesAgentId: agentId,
status: OrderStatus.DELIVERED_TO_AGENT,
};