# 08 — Sales Agent Controls **Status**: Not Started **Depends On**: 07 — Ride Close & Reconciliation --- ## Goal Wire role levels to concrete business limits and approval chains. Covers the approval-routing half of [mainPlan.md §1](./mainPlan.md#1-order-management) (`submitOrderForApproval`, `approveOrder`, `rejectOrder`) and the performance-tracking functions from [§10 SFA/CRM](./mainPlan.md#10-sales-force-automation-sfa--crm) (`trackTargetVsAchievement`, `calculateIncentive`). Lead/interaction functions from §10 (`logCustomerInteraction`, `createLead`, `convertLeadToStore`) are out of scope here — see [16_sfa_crm.md](./16_sfa_crm.md). --- ## Background / Context `Role.Level` already exists and drives the permission seed (`Data/Seed/RoleAndPermissionSeed.cs`), but nothing today turns a level into a discount limit, credit limit, or approval threshold — it only gates which API endpoints a role can call. --- ## Data Model Changes ### Agent Limit Configuration (per role level) `RoleId`, `MaxDiscountPercent`, `MaxSingleTransactionValue` — read by both [06_sale_ride.md](./06_sale_ride.md) (line-item discount check) and order approval routing here. ### Override Log `OverrideById` (the supervisor), `TargetType`/`TargetId` (e.g. `Order`, `FieldInvoice`), `OldValue`, `NewValue`, `Reason`, `CreatedAt` — a one-time exception, logged against the supervisor's account. ### Customer Credit Profile Reuses `Store.CreditLimit`/`Store.OutstandingBalance` once added (gap #8 in [00_existing_gaps.md](./00_existing_gaps.md)) rather than a separate entity. --- ## API Endpoints | Function reference | Endpoint intent | |---|---| | `submitOrderForApproval(orderId)` (§1) | Triggered automatically when an order exceeds its agent's limit | | `approveOrder(orderId, approverId)` / `rejectOrder(orderId, reason)` (§1) | `POST /api/orders/{id}/approve`, `POST /api/orders/{id}/reject` | | `trackTargetVsAchievement(userId, period)` (§10) | `GET /api/agents/{userId}/performance?period=...` | | `calculateIncentive(userId, period)` (§10) | `GET /api/agents/{userId}/incentive?period=...` | | — | `POST /api/orders/{id}/override` — supervisor one-time exception, writes an Override Log entry | --- ## Business Rules - An order/invoice whose value or discount exceeds the agent's `Agent Limit Configuration` cannot proceed without either supervisor approval or a logged override — no silent pass-through. - `calculateIncentive` reads only settled/closed rides (post-[07_ride_reconciliation.md](./07_ride_reconciliation.md)), never in-flight ones. --- ## Fraud / Control Considerations - Every `Override Log` entry is permanent and immutable once written — feeds [09_fraud_controls.md](./09_fraud_controls.md)'s anomaly detection (agents with unusually frequent overrides). --- ## Open Questions - Are discount/transaction limits configured per `Role`, or can an individual `User` have a tighter/looser override of their role's default? - What sales target source feeds `trackTargetVsAchievement` — is there a target-setting endpoint needed here, or does it come from §2's `setRegionalTarget` rolled down to the individual? --- ## Implementation Notes > Fill this section in during planning discussion before writing any code.