Add md file features in region, route, store, fleet, pricing, procurement, SFA, promotions, returns, finance, reporting, notifications, integration, and mobile capabilities

This commit is contained in:
2026-08-19 15:18:31 +05:30
parent 45f374133f
commit d2390e7b12
25 changed files with 1565 additions and 88 deletions
+35 -9
View File
@@ -7,13 +7,18 @@
## Goal
Introduce stock-per-location as a first-class, transaction-driven concept. Covers
[mainPlan.md §8](./mainPlan.md#8-enterprise-wide-inventory--stock) in full,
plus the location-query half of §6 (`getStockByLocation`, `putawayStock`). Everything downstream —
loading events, delivery/sale ride execution, reconciliation — reads or writes through this ledger.
---
## Background / Context
Nothing in the current schema tracks quantity of an `Item` anywhere. `checkStockAvailability` (§1)
and every warehouse function in §6 have no data source to query today. This step must land before
[04_loading_event.md](./04_loading_event.md).
---
@@ -21,39 +26,60 @@
### Stock Balance (per location)
A denormalized running balance per `(ItemId, LocationId)` pair, kept in sync by the movement
transaction table below — never edited directly by any service.
### Stock Movement Transaction
One row per stock change: `ItemId`, `LocationId`, `Quantity` (signed: +load/return, -sale/damage),
`MovementType` (`Load`, `Sale`, `Return`, `Damage`, `Adjustment`), `ReferenceId` (the order/ride/GRN
that caused it), `CreatedAt`. This is the source of truth; the balance is its running sum.
### Location Abstraction (Warehouse vs Vehicle)
A `Location` concept that can resolve to either a `Warehouse` or a `Vehicle` (once a ride is open —
see [03_ride_lifecycle.md](./03_ride_lifecycle.md)), so the same movement/balance model serves both
`getMultiLocationStock` (§8) and the vehicle-as-temporary-warehouse pattern.
---
## API Endpoints
| Function reference | Endpoint intent |
|---|---|
| `getMultiLocationStock(sku)` (§8) | `GET /api/stock/items/{sku}` — balance across every location |
| `getStockByLocation(warehouseId, sku)` (§6) | `GET /api/stock/locations/{locationId}/items/{sku}` |
| `setReorderPoint(sku, warehouseId, threshold)` (§8) | `PUT /api/stock/locations/{locationId}/items/{sku}/reorder-point` |
| `createStockTransfer(fromWarehouseId, toWarehouseId, items[])` (§8) | `POST /api/stock/transfers` |
| `trackBatchExpiry(sku, batchNo, expiryDate)` (§8) | Deferred — see Open Questions |
| `calculateStockValuation(warehouseId, method)` (§8) | `GET /api/stock/locations/{locationId}/valuation?method=fifo\|weighted-average` |
---
## Business Rules
- Stock is never edited directly — every change is a `Stock Movement Transaction`; the balance is
always the running sum, recalculated or cached but never hand-edited.
- A movement cannot take a balance negative unless explicitly flagged as an `Adjustment` (physical
count correction).
- Every movement must carry a `ReferenceId` back to the business event that caused it — no
freestanding movements outside of documented `Adjustment`s.
---
## Fraud / Control Considerations
- `Adjustment` movements should be restricted to Supervisor level and above (see role-permission
mapping in `Data/Seed/RoleAndPermissionSeed.cs`), and should require a reason code once
[09_fraud_controls.md](./09_fraud_controls.md) lands.
---
## Open Questions
- Is batch/expiry tracking (`trackBatchExpiry`) needed in v1, or can it be deferred until a
regulated/perishable product line requires FEFO enforcement?
- FIFO vs weighted-average valuation — does the business need both, or a single fixed method?
---