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
@@ -0,0 +1,47 @@
-- ============================================================================
-- Order.salesAgentId / Order.referrerCustomerId — additive, idempotent.
--
-- Owner ruling 2026-10-08: keep legacy's rule exactly. An order is credited to
-- the expert who was the customer's referrer WHEN IT WAS PLACED (legacy
-- `orders.reagent_id`, set once at creation), so a customer moving to another
-- expert later never changes past sales or commission. The app used to credit
-- an order to the customer's CURRENT referrer, which disagreed with legacy for
-- 8 of 49 experts on the imported data.
--
-- No row is deleted and no existing column changes.
-- ============================================================================
ALTER TABLE "Order" ADD COLUMN IF NOT EXISTS "salesAgentId" TEXT;
ALTER TABLE "Order" ADD COLUMN IF NOT EXISTS "referrerCustomerId" TEXT;
DO $$ BEGIN
ALTER TABLE "Order" ADD CONSTRAINT "Order_salesAgentId_fkey"
FOREIGN KEY ("salesAgentId") REFERENCES "AdminUser"("id") ON DELETE SET NULL ON UPDATE CASCADE;
EXCEPTION WHEN duplicate_object THEN NULL;
END $$;
DO $$ BEGIN
ALTER TABLE "Order" ADD CONSTRAINT "Order_referrerCustomerId_fkey"
FOREIGN KEY ("referrerCustomerId") REFERENCES "Customer"("id") ON DELETE SET NULL ON UPDATE CASCADE;
EXCEPTION WHEN duplicate_object THEN NULL;
END $$;
CREATE INDEX IF NOT EXISTS "Order_salesAgentId_idx" ON "Order"("salesAgentId");
CREATE INDEX IF NOT EXISTS "Order_referrerCustomerId_idx" ON "Order"("referrerCustomerId");
-- Orders placed in the new app before this column existed: the customer's
-- referrer today is the best record there is (these are recent). Orders
-- brought over from legacy (orderNumber 'H-<id>') are NOT guessed here — the
-- import writes their real `orders.reagent_id`.
UPDATE "Order" o
SET "salesAgentId" = c."referredByAgentId"
FROM "Customer" c
WHERE c."id" = o."customerId"
AND o."salesAgentId" IS NULL
AND c."referredByAgentId" IS NOT NULL
AND o."orderNumber" NOT LIKE 'H-%';
COMMENT ON COLUMN "Order"."salesAgentId" IS
'Sales expert credited with this order, fixed when it is placed (legacy orders.reagent_id). Never follows a later change of the customer''s referrer.';
COMMENT ON COLUMN "Order"."referrerCustomerId" IS
'History only: legacy orders.reagent_id when it named a customer who is not a sales expert. Never set for new orders.';