Delivery PRD
Everything all at once
Product Requirements Document (PRD)
Narayanganj Distribution Hub — Field Sales & Warehouse Management System
| Field | Detail |
|---|---|
| Document Version | 1.0 |
| Status | Draft — Ready for Engineering Review |
| Product Owner | Head of P.S & A.S (Mr. Imtiaj) |
| Prepared By | Business Analysis / Product Team |
| Primary Stakeholders | Business Head, WH Manager, Sales Head, SCM Manager, Regional Manager |
| Engineering Owner | TBD |
| Effective Date | May 2026 |
| Based On | BRD v1.1 — Narayanganj Distribution Hub |
| Review Cycle | Bi-weekly during build; quarterly post-launch |
Table of Contents
-
Product Vision & Problem Statement
-
Goals & Anti-Goals
-
User Personas
-
System Architecture Overview
-
Module Specifications
-
5.1 Outlet & Market Mapping
-
5.2 Route Planning & Beat Management
-
5.3 SO Field Sales App
-
5.4 Target Setting & Performance
-
5.5 Warehouse Management
-
5.6 Procurement & Vendor Management
-
5.7 Dispatch & VLS Management
-
5.8 DSR Delivery App
-
5.9 Cash & Accounts
-
5.10 Admin Panel & Reporting
-
Data Model
-
API Design Principles
-
Integration Specifications
-
Non-Functional Requirements
-
Go-Live Readiness Gate
-
KPI Thresholds & Alert Configuration
-
Enum Values Reference
-
Open Questions
1. Product Vision & Problem Statement
1.1 What the System Is
The Narayanganj Distribution Hub System is a purpose-built field sales and warehouse management platform for an FMCG distribution hub operating across Narayanganj Town, Bandor, and Munshiganj. It is composed of two mobile applications (SO Field App and DSR Delivery App, both Android) and a web-based management portal used by warehouse, accounts, sales management, procurement, and executive stakeholders.
1.2 The Problem Being Solved
Today, the hub operates on a combination of paper forms, WhatsApp messages, verbal instructions, and manual spreadsheets. This creates five compounding failure modes:
-
Invisible field activity: There is no real-time record of SO visits, outlet orders, or strike rates. Management discovers problems days later, not hours.
-
Stock opacity: Stock moves in and out of the warehouse without a single authoritative record. Shortages are discovered at loading time, not the night before.
-
Cash leakage: Cash collected by DSRs is reconciled manually. Discrepancies are common and resolved informally, with no audit trail.
-
Procurement delays: The SCM Manager has no systematic view of stock levels, leading to either over-stocking (cash locked in inventory) or stockouts (lost revenue).
-
No accountability baseline: Because nothing is formally recorded, it is impossible to hold any individual accountable for any measurable outcome.
1.3 Core Principle
If it is not in the system, it did not happen.
Every order, every visit, every delivery, every cash collection, every stock movement, and every exception must be recorded digitally, in real time, by the person responsible for the activity.
1.4 What Success Looks Like
At the end of Day 1, the Business Head can open a single dashboard screen and see: how many outlets each SO visited, the total order value submitted, what stock left the warehouse, how much cash each DSR collected, and whether any discrepancy exists. No phone calls required.
2. Goals & Anti-Goals
2.1 Goals
| # | Goal | Measurement |
|---|---|---|
| G-01 | 100% of SO outlet visits logged in the system on the day they occur | Visit log completeness rate = 100% |
| G-02 | 100% of stock movements (inbound and outbound) have a corresponding system record | Zero unrecorded stock movements per weekly count |
| G-03 | Daily cash reconciliation completed by 7:00 PM for all DSRs | Reconciliation on-time rate = 100% |
| G-04 | All supplier payments made within agreed credit terms, with zero payments blocked by outstanding Debit Notes | Payment compliance rate = 100% |
| G-05 | Business Head receives a complete daily operations summary by 7:00 PM | Daily summary delivery rate = 100% |
| G-06 | System supports scale-out from 2,700 to 5,400 outlets without re-architecture | No performance degradation at 5,400 outlets |
| G-07 | SO incentive accrual visible in real time in app; zero manual calculation of incentive | 100% incentive calculations system-generated |
| G-08 | Go-Live Readiness Gate prevents Day 1 operations until all 8 data categories are verified | Gate enforced; no bypass available |
2.2 Anti-Goals (Explicit Out-of-Scope)
| # | Anti-Goal | Rationale |
|---|---|---|
| AG-01 | The system does NOT manage HR, payroll, or disciplinary actions | Head Office HR system is responsible |
| AG-02 | The system does NOT support credit sales to retail outlets | All retail is cash-only by policy |
| AG-03 | The system does NOT provide a B2C or e-commerce portal for outlet owners | Out of scope for this deployment |
| AG-04 | The system does NOT integrate with Tally/SAP in Phase 1 | Export only in Phase 2 |
| AG-05 | The system does NOT manage modern trade or key account negotiations | Different commercial model |
| AG-06 | The system does NOT manage multiple warehouses or hubs | Single-hub system |
| AG-07 | The system does NOT do demand forecasting or advanced ML analytics | Outside current capability requirement |
| AG-08 | The system does NOT track GPS location of vehicles in transit | 3PL manages fleet externally |
3. User Personas
3.1 Sales Officer (SO)
Role: Sales Officer (Field App User) Count: 6 SOs active in Phase 1
Primary Job-to-Be-Done: Visit 75 P1 outlets daily across an assigned geographic block, take orders, and submit them digitally via the app before the 8:00 PM cut-off.
Pain Points the System Solves:
-
Currently carries a paper route card and calls in orders verbally — orders are lost, misheard, or delayed.
-
Has no visibility into whether their target is achievable; discovers miss at month-end.
-
Cannot see outlet outstanding balance before visiting, leading to awkward collection conversations.
-
Incentive calculation is done manually at month-end by the manager; SOs distrust the numbers.
Key Success Metric: Strike rate >70%; order value vs daily target visible in real time; incentive tier progression visible in app.
3.2 Delivery Sales Representative (DSR)
Role: DSR (Delivery App User) Count: Variable; at least 1 per active vehicle/route
Primary Job-to-Be-Done: Load vehicle per VLS, deliver stock to outlets in sequence, collect cash per invoice, and return to warehouse by 6:00 PM with correct cash, signed challans, and unsold stock.
Pain Points the System Solves:
-
Currently receives handwritten VLS; loads from memory; quantities are disputed at return.
-
Has no formal record of cash collected per outlet during the day; does mental arithmetic at day-end.
-
Is blamed for shortages with no evidence trail.
-
Arrival and departure times are not formally tracked; no accountability for late starts.
Key Success Metric: Day-end reconciliation variance = 0; departure by 8:30 AM 100% of days; zero disputed cash at day-end.
3.3 WH Manager
Role: WH Manager (Web App User) Count: 1 (currently Warehouse In-Charge position, noted as vacant; will be filled before go-live)
Primary Job-to-Be-Done: Manage all physical stock movements — receive inbound goods, generate VLS each night, oversee DSR loading, reconcile returns at day-end, and submit stock and cash reports by 7:00 PM.
Pain Points the System Solves:
-
Currently maintains a manual stock register that is always at least one day behind.
-
Generates VLS by hand each night from paper orders; prone to errors.
-
Has no formal mechanism to record vehicle condition checks or DSR arrival times.
-
Day-end reconciliation is time-consuming; discrepancies are resolved informally.
Key Success Metric: Opening stock report auto-generated at 7:00 AM; VLS generated in <5 minutes after order cut-off; day-end reconciliation closed by 7:00 PM daily.
3.4 SCM Manager
Role: SCM Manager (Web App User) Count: 1
Primary Job-to-Be-Done: Monitor stock levels, raise RFQs for uncontracted SKUs, issue approved POs to vendors by Monday 10:00 AM, and receive the weekly stock position report from the WH Manager every Sunday.
Pain Points the System Solves:
-
Currently receives stock data via WhatsApp messages from the WH Manager; data is informal and often incomplete.
-
Has no system to track vendor RFQ responses or PO acknowledgement status.
-
Cannot see which SKUs are approaching the 30-day max stock cap or below minimum cover thresholds.
Key Success Metric: 100% of POs issued to vendors by Monday 10:00 AM; 0 RFQ responses missed past 48-hour deadline; stock position report received every Sunday before 7:00 PM.
3.5 Sales Head
Role: Sales Head / Supervisor (Web App User) Count: 1 (Regional Manager, Mr. Shahariyar)
Primary Job-to-Be-Done: Oversee daily SO performance across all 6 routes; classify outlets; approve route changes; validate monthly targets; review weekly strike rates and coverage metrics.
Pain Points the System Solves:
-
Currently receives SO performance data as verbal reports or end-of-day WhatsApp summaries.
-
Cannot identify underperforming SOs until the week or month has passed.
-
Route changes are made informally, with no audit trail.
Key Success Metric: Monday morning SO performance review takes <15 minutes using dashboard; zero route changes made without system approval trail.
3.6 Business Head
Role: Business Head (Web App User — executive oversight) Count: 1 (Head of P.S & A.S, Mr. Imtiaj)
Primary Job-to-Be-Done: Receive the daily operations summary by 7:00 PM; approve high-value actions (POs, target revisions, vendor registrations, Debit Note resolutions); sign off on monthly P&L; execute the Go-Live Readiness Gate before Day 1.
Pain Points the System Solves:
-
Currently has no single view of hub performance; must call multiple people to understand daily status.
-
Cannot track whether incentive thresholds are being met or whether cash reconciliation is clean.
-
No formal mechanism to approve or reject financial decisions with audit trail.
Key Success Metric: Daily operations summary received by 7:00 PM; all approval actions completed within system (zero off-system approvals).
3.7 Accounts
Role: Accounts (Web App User) Count: 1–2 (Head Office accounts team)
Primary Job-to-Be-Done: Process daily cash receipts from WH Manager, generate invoices, manage supplier payables per credit terms, and submit daily/weekly/monthly financial reports.
Pain Points the System Solves:
-
Currently receives cash summary via phone or paper; re-enters data into spreadsheets.
-
Has no automated mechanism to check whether an open Debit Note exists before processing a vendor payment.
-
Monthly P&L takes multiple days to compile due to manual data collection.
Key Success Metric: Daily financial summary submitted by 7:00 PM without manual data collection; zero vendor payments processed with open Debit Notes.
3.8 App Admin
Role: App Admin (Web App User — system administration) Count: 1 (dedicated technical admin)
Primary Job-to-Be-Done: Load and maintain all master data (outlet master, SKU master, route plans, user accounts, promotional schemes, targets); perform daily backup verification; manage role assignments; execute the Go-Live Readiness data load.
Pain Points the System Solves:
-
No system currently; all setup done in spreadsheets.
-
No audit trail for master data changes.
-
No automated backup or integrity check mechanism.
Key Success Metric: All 8 Go-Live Readiness items verified before Day 1; 100% of master data edits logged with full audit trail; zero unauthorized data changes.
4. System Architecture Overview
4.1 Three-Tier Structure
┌─────────────────────────────────────────────────────────────────┐ │ CLIENT LAYER │ │ │ │ ┌─────────────────────────┐ ┌──────────────────────────────┐ │ │ │ SO Field Sales App │ │ DSR Delivery App │ │ │ │ (Android — Offline │ │ (Android — Offline First) │ │ │ │ First) │ │ │ │ │ └─────────────────────────┘ └──────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ Web Application (React / SPA) │ │ │ │ WH Manager | Accounts | Sales Head | Business Head │ │ │ │ SCM Manager | App Admin │ │ │ └─────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ │ HTTPS / REST ┌─────────────────────────────────────────────────────────────────┐ │ BACKEND API LAYER │ │ │ │ ┌────────────┐ ┌─────────────┐ ┌──────────────┐ │ │ │ Auth │ │ Business │ │ Notification │ │ │ │ Service │ │ Logic API │ │ Service │ │ │ │ (JWT/RBAC) │ │ (REST) │ │ (FCM/SMS) │ │ │ └────────────┘ └─────────────┘ └──────────────┘ │ │ │ │ ┌────────────┐ ┌─────────────┐ ┌──────────────┐ │ │ │ Sync │ │ Report │ │ File/Media │ │ │ │ Engine │ │ Engine │ │ Service │ │ │ │ (Offline) │ │ │ │ (Photos) │ │ │ └────────────┘ └─────────────┘ └──────────────┘ │ └─────────────────────────────────────────────────────────────────┘ │ ┌─────────────────────────────────────────────────────────────────┐ │ DATA LAYER │ │ │ │ ┌─────────────────────────┐ ┌──────────────────────────────┐ │ │ │ Primary Relational DB │ │ Object/File Storage │ │ │ │ (PostgreSQL) │ │ (Photos, Documents) │ │ │ └─────────────────────────┘ └──────────────────────────────┘ │ │ │ │ ┌─────────────────────────┐ ┌──────────────────────────────┐ │ │ │ Local SQLite DB │ │ Push Queue │ │ │ │ (Mobile Offline Store)│ │ (Notifications) │ │ │ └─────────────────────────┘ └──────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘
4.2 Key Architectural Principles
Offline-First Mobile Architecture: Both the SO Field App and DSR Delivery App must function fully offline. The apps maintain a local SQLite database that is the source of truth for all in-progress field operations. Connectivity to the server is treated as a bonus, not a requirement, for core field workflows.
Conflict Resolution Strategy:
-
Mobile writes are append-only (new visit logs, new orders, new delivery logs).
-
Server-side writes are the source of truth for master data (outlet master, SKU master, route plans, targets).
-
On reconnect, the mobile app pushes all locally queued events to the server in chronological order.
-
Conflicts (e.g., outlet master updated while SO was offline) are resolved by accepting the server version and notifying the mobile user of any changes.
Data Sync Strategy:
-
Master data (outlets, SKUs, routes, targets) syncs at app launch and every 30 minutes when connected.
-
Transactional data (visit logs, orders, delivery logs, cash entries) queues locally and pushes on every available connection window.
-
Sync status is displayed in the mobile app header: "Synced 3 min ago" / "Offline — 5 records pending sync".
Security:
-
All API endpoints require JWT Bearer token authentication.
-
RBAC enforced at the API layer — each endpoint validates the caller's role before returning data.
-
SO tokens are scoped to their assigned route only; any attempt to access another SO's data returns 403.
-
All data in transit: TLS 1.2 minimum.
-
Sensitive data at rest (credentials, bank details): AES-256 encrypted.
5. Module Specifications
5.1 Outlet & Market Mapping Module
Module Purpose: Maintain the authoritative master record of every retail outlet in the distribution universe, including GPS location, classification, and SO assignment.
User Stories
| ID | User Story |
|---|---|
| US-OM-01 | As a Sales Officer, I want to register a new outlet using my phone's GPS so that I don't have to manually type coordinates or look up addresses. |
| US-OM-02 | As a Sales Officer, I want the app to warn me if I'm registering an outlet that already exists within 50 metres of my current location so that duplicates are avoided. |
| US-OM-03 | As a Sales Head, I want to classify any outlet as P1 or P2 from the web portal so that the route planning team can build routes based on priority. |
| US-OM-04 | As an App Admin, I want to bulk-import outlets via CSV so that the initial data load before go-live can be completed efficiently. |
| US-OM-05 | As a Sales Head, I want the system to flag any P1 outlet that has had no recorded visit for 3 consecutive weeks so that I can review and possibly reclassify it as P2. |
Acceptance Criteria
-
The "Register Outlet" screen on the SO app auto-populates GPS coordinates from the device; the SO cannot proceed without GPS lock.
-
On submission of a new outlet, the system checks for any existing outlet within a 50-metre radius; if found, it displays the existing outlet name and address and requires the SO to confirm "This is a different outlet" before saving.
-
Mandatory fields — outlet name, owner name, address, zone, outlet type, contact number, drop size tier — must all be populated before the registration form can be submitted; the system highlights missing fields.
-
Only the App Admin can edit an existing outlet record; every edit is logged with: editor user ID, timestamp, field changed, old value, new value.
-
The Sales Head can change any outlet's priority tier (P1/P2) from the web portal; the change takes effect for the next beat day's route generation.
-
The system enforces a maximum of 2,700 outlets in P1 status; if this cap is reached, the Sales Head must demote a P1 outlet before promoting a new one.
-
Bulk CSV import validates all rows before processing; import fails on any row with a missing mandatory field; a validation error report is returned to the App Admin listing all failed rows with reasons.
-
The system automatically generates a weekly flag report every Monday morning listing all P1 outlets with zero recorded visits in the last 3 consecutive weeks; this report is sent to the Sales Head via dashboard notification.
Business Rules Enforced
-
OM-03: Duplicate detection radius = 50 metres (configurable by App Admin).
-
OM-08: P1 cap = 2,700; P2 cap = 2,700.
-
OM-09: 3-week no-visit flag for P1 outlets.
Edge Cases & Error States
-
GPS unavailable: App prompts SO to enable location services; manual coordinate entry is not allowed (prevents spoofing).
-
Offline registration: Outlet is saved locally with sync_status = pending; uploaded on next connection. Duplicate check is performed against locally cached outlet list; server re-validates on sync.
-
CSV import with duplicate outlets: System compares by GPS proximity; flags potential duplicates in the validation report for App Admin to resolve manually.
5.2 Route Planning & Beat Management Module
Module Purpose: Define and maintain the structured weekly beat schedule assigning each P1 outlet to a specific SO and day of week, following the geographic blocking principle.
User Stories
| ID | User Story |
|---|---|
| US-RP-01 | As a Sales Head, I want to assign outlets to SOs and beat days so that each SO has a structured daily route of exactly 75 P1 outlets. |
| US-RP-02 | As a Sales Head, I want to see a map view of all SO routes so that I can verify geographic contiguity (blocking principle) before locking the plan. |
| US-RP-03 | As an App Admin, I want to make route changes only after a Sales Head approval is recorded in the system so that route integrity is maintained. |
| US-RP-04 | As a Sales Officer, I want to see a P2 backup pool of up to 10 outlets for my beat day so that if a P1 outlet is closed, I can activate a P2 replacement. |
| US-RP-05 | As a Sales Head, I want the system to flag any route where the 75-outlet target cannot feasibly be completed between 8:00 AM and 6:00 PM so that routes are physically achievable. |
Acceptance Criteria
-
The beat schedule only allows assignment to Sat, Sun, Mon, Tue, Wed, or Thurs; Friday cannot be assigned as a beat day for any outlet.
-
Each outlet can be assigned to exactly one SO and one beat day; the system rejects any attempt to assign an outlet that is already assigned.
-
Each SO's route for any beat day must have exactly 75 P1 outlets to be considered complete; the system displays a completion indicator (e.g., "45/75 outlets assigned") as the Sales Head builds the route.
-
The route map view renders all outlets on a geographic map (Google Maps / OpenStreetMap integration), colour-coded by SO, allowing the Sales Head to visually verify blocking principle compliance.
-
Route lock is enforced for a minimum of 4 weeks from go-live; any attempt to edit a locked route by the App Admin without a prior Sales Head approval record results in a system error ("Route is locked — approval required").
-
Route change approval workflow: Sales Head submits a change request in system (with reason) → App Admin receives notification → App Admin applies change → before/after state logged permanently.
-
Each SO's route includes a P2 backup pool of up to 10 outlets per beat day; P2 outlets are distinct from the P1 list and from each other.
-
When a SO activates a P2 outlet, they must select a reason code from the configured list; the system records: outlet ID, reason code, SO user ID, timestamp.
-
The system calculates estimated route duration based on outlet count and average inter-outlet travel time (sourced from route map clustering); if estimated duration exceeds 10 hours (8:00 AM to 6:00 PM), the system flags the route as infeasible and prevents lock until resolved.
Business Rules Enforced
-
RP-03: One outlet, one SO — no sharing.
-
RP-04: 4-week route lock.
-
RP-10: Blocking principle — contiguous outlets per SO per beat day.
-
RP-11: Sat–Thurs beat schedule; Friday excluded.
-
RP-12: Route must complete within 8:00 AM–6:00 PM window.
Edge Cases & Error States
-
Route has fewer than 75 P1 outlets: System allows save in draft state; Sales Head cannot lock until 75 outlets are assigned.
-
SO changed mid-route-lock-period: Sales Head must submit change request; existing outlet assignments for the departing SO must be manually re-assigned; system generates a task list for Sales Head.
-
P2 pool exhausted: If all 10 P2 outlets are activated or unavailable in a single day, SO receives in-app notification; remaining unvisited P1 outlets are flagged for next cycle.
5.3 SO Field Sales App Module
Module Purpose: Enable Sales Officers to execute their daily beat route — GPS check-in, order taking, visit logging, and real-time performance tracking — on their Android device, fully offline-capable.
User Stories
| ID | User Story |
|---|---|
| US-SA-01 | As a Sales Officer, I want to see my full day's outlet route in order at the start of the day so that I know exactly which outlets to visit and in what sequence. |
| US-SA-02 | As a Sales Officer, I want to check in to each outlet via GPS before I can enter an order so that the system records my physical presence at the outlet. |
| US-SA-03 | As a Sales Officer, I want to see the outlet's outstanding balance before I enter an order so that I can address any unpaid invoices at the outlet. |
| US-SA-04 | As a Sales Officer, I want to see my live progress — visits completed, order value vs target, and strike rate — throughout the day so that I can adjust my effort before the cut-off. |
| US-SA-05 | As a Sales Officer, I want to see my running incentive accrual against the tier thresholds so that I know how close I am to the next incentive level. |
| US-SA-06 | As a Sales Officer, I want active promotional schemes to be auto-applied when I add qualifying SKUs so that I never miss applying a valid promotion. |
| US-SA-07 | As a Sales Officer, I want to log a P2 outlet activation with a reason code when a P1 outlet is unavailable so that there is a formal record of why the P1 was not visited. |
Acceptance Criteria
-
On app launch, the SO sees today's beat route: ordered list of outlets, daily visit target (75), daily order value target (calculated from SO monthly target ÷ working days), and number of P2 backups available.
-
GPS check-in is the first mandatory action at each outlet; the "Enter Order" and "Log Visit" buttons are greyed out until a valid GPS check-in is recorded.
-
GPS check-in is valid if the device GPS coordinate is within 100 metres (configurable) of the outlet's registered GPS pin; if outside 100 metres, the system shows a warning with the measured distance and requires the SO to confirm they are at the correct outlet (override logged for audit).
-
Before order entry, the system displays: outlet name, owner name, outstanding balance (BDT), last order date, and today's outlet-level target (SO target ÷ active outlet count on route).
-
If the outlet has an outstanding balance > 0, order entry is blocked; a message reads: "This outlet has an unpaid balance of BDT [X]. Please collect payment before placing a new order."
-
The order entry screen shows the full active SKU list; the SO selects SKUs and quantities; approved promotional schemes are auto-applied and displayed as line items.
-
The SO cannot enter a price or discount that exceeds the approved SKU master price; the price field is read-only, pre-populated from SKU master.
-
Order cut-off is 8:00 PM; at 8:00 PM, the system auto-closes order entry; any in-progress order that has not been submitted is saved as a draft locally and flagged as "Not Submitted — After Cut-Off".
-
Visit outcome must be selected before navigating to the next outlet: Order Placed / Closed / Owner Absent / Refused / Competitor Only.
-
Running dashboard updates in real time: (a) Memos visited / 75 target, (b) Order value BDT vs daily target BDT, (c) Strike rate %, (d) Incentive tier progress bar showing current accrual vs Test / 1st Step / BEP thresholds.
-
All data entered while offline is stored in local SQLite; on reconnection, the app automatically pushes queued records; sync status is visible in the app header.
-
The SO app only loads data for their assigned route; attempting to access any other SO's outlet data returns an error screen.
Business Rules Enforced
-
SA-04: Own route only.
-
SA-05/SA-06: GPS check-in mandatory; radius = 100m.
-
SA-08: Outstanding balance blocks order entry.
-
SA-14: 8:00 PM order cut-off is system-enforced.
-
SA-15/SA-16: Price ceiling enforced; promotions auto-applied.
-
BR-01: No credit field — all orders are cash-on-delivery.
-
TS-09: Outlet-level target displayed at check-in.
Edge Cases & Error States
-
SO GPS signal weak in dense urban area: App displays "Low GPS accuracy" warning; SO can retry GPS lock or accept with documented override.
-
SKU not in master: SO cannot enter a free-text SKU; they must select from the approved list. If an outlet requests an unlisted SKU, SO can log it as a "competitor observation" or "new SKU request" using the notes field.
-
Outlet GPS pin is incorrect: SO can flag the outlet GPS location as incorrect from the check-in screen; App Admin is notified for correction; the visit is logged with the flag.
5.4 Target Setting & Performance Module
Module Purpose: Configure monthly revenue targets and incentive thresholds at WH and SO levels; track daily performance against targets; trigger performance alerts.
User Stories
| ID | User Story |
|---|---|
| US-TS-01 | As a Business Head, I want to set the monthly WH revenue target so that the system auto-distributes per-SO targets and validates against the BDT 3.5 Cr budget floor. |
| US-TS-02 | As a Sales Head, I want to see each SO's weekly performance against their target every Monday morning so that I can address underperformers before the week is lost. |
| US-TS-03 | As a Sales Officer, I want to see my outlet-level target at each outlet check-in so that I know the minimum expected order value for that outlet. |
| US-TS-04 | As a Sales Head, I want to validate the monthly WH target calculation before it is locked so that I confirm it meets the BDT 3.5 Cr minimum. |
Acceptance Criteria
-
The monthly target configuration workflow: Business Head enters WH-level target → system calculates per-SO target using formula: (WH target ÷ 6, adjusted by route potential based on weighted average drop size of outlets on each SO's route) → Sales Head sees proposed targets and validates → Sales Head confirms "Meets BDT 3.5 Cr floor" (system blocks confirmation if calculated total < BDT 3.5 Cr) → Business Head approves and locks.
-
The target calculation uses: weighted average drop size × 2,700 P1 outlets × visit frequency; the system shows this calculation workings to the Sales Head for review.
-
Targets must be loaded into the app by the 1st of each month; the App Admin receives a reminder notification 5 days before month-end.
-
Weekly milestone targets are auto-generated as monthly target ÷ 4; displayed in the Sales Head dashboard.
-
Every Monday morning, the system sends an automated alert to the Sales Head listing any SO whose actual revenue for the previous week is below 80% of their weekly milestone target.
-
Mid-month target revision is system-locked; the Business Head must initiate a revision request; the system logs the request with reason, old target, proposed new target, and approval timestamp.
-
Incentive tier thresholds (Test: BDT 750/SO, 1st Step: BDT 17,500/SO, BEP: BDT 27,500/SO) are configured once per month and visible to each SO in the app as a progress bar.
-
The outlet-level target is calculated and displayed dynamically: SO monthly target ÷ number of active outlets on that SO's route; updated if outlet count changes mid-month.
-
Performance metrics tracked and displayed per SO: Memos/day, Strike Rate %, LPC, EC %, Order Value/Memo, SKU Distribution %.
Business Rules Enforced
-
TS-02: Targets loaded by 1st of month.
-
TS-04: Mid-month revision requires Business Head approval.
-
TS-07: Monday morning flag for SOs below 80% weekly target.
-
TS-09: Outlet-level target visible at check-in.
-
TS-10: Budget floor validation at BDT 3.5 Cr.
Edge Cases & Error States
-
Target not loaded by 1st of month: SO app displays "Target not yet configured" message; App Admin receives escalation alert; target can be backdated with Business Head approval and the audit log records the backdating.
-
Route changes mid-month: Outlet-level target recalculates automatically when outlet count changes; SO is notified of the revision.
5.5 Warehouse Management Module
Module Purpose: Manage all physical stock movements at the warehouse — inbound receiving (GRN), storage, FEFO/FIFO dispatch, shortage allocation, and weekly reporting to SCM Manager.
User Stories
| ID | User Story |
|---|---|
| US-WH-01 | As a WH Manager, I want to raise a GRN against a matching PO when goods arrive so that received stock is immediately recorded in the system. |
| US-WH-02 | As a WH Manager, I want the system to block GRN entry for any item with expiry less than 60 days so that near-expiry stock is never accepted. |
| US-WH-03 | As a WH Manager, I want to log goods rejected during GRN so that the system automatically raises a Debit Note against the vendor. |
| US-WH-04 | As a WH Manager, I want the opening stock report auto-generated at 7:00 AM every day so that I begin each day with a confirmed stock position. |
| US-WH-05 | As a WH Manager, I want the system to calculate shortage allocation pro-rata across all routes so that no single route is favoured when stock is short. |
| US-WH-06 | As a SCM Manager, I want to receive the weekly stock position report from the WH Manager every Sunday by 7:00 PM so that I can plan the weekly PO cycle. |
Acceptance Criteria
-
GRN creation requires selection of an existing open PO; free-form GRN (without a matching PO) is system-blocked with error: "No open PO found for this vendor. Cannot receive goods."
-
During GRN, the WH Manager selects each SKU and enters: qty received, batch number, expiry date, and condition (Acceptable / Damaged / Near-Expiry). The system calculates days to expiry from delivery date; if < 60 days, the item is auto-flagged as "Reject — Expiry" and cannot be accepted into stock.
-
The GRN handover location must be recorded: "Receiving Bay" (default) or "Other" (requires a text note). This validates supplier compliance with the no-storage-zone-entry rule.
-
If any item is marked "Reject", the WH Manager must confirm "Same-day return to supplier confirmed" before the GRN can be submitted; upon submission, the system automatically generates a Debit Note with: GRN reference, vendor ID, rejected SKUs and quantities, total value, raised_by (WH Manager), raised_at (timestamp), status = Open.
-
Any discrepancy between PO quantity and received quantity (excluding rejections) is flagged to the SCM Manager with a photo attachment field; the WH Manager must attach a photo within 2 hours.
-
GRN must be digitally signed by the WH Manager before stock is accepted; signature timestamp is recorded.
-
Stock is accepted into inventory under FIFO principle; the system assigns the received batch to the back of the storage queue.
-
For dispatch, the system enforces FEFO: the soonest-expiring batch is always allocated first for outbound VLS.
-
Opening stock report is auto-generated at 7:00 AM daily; visible to WH Manager and Business Head; includes: SKU name, current quantity, stock cover days (at current consumption rate), cover category (Fast/Medium/Slow), and flag colour (Red = below minimum, Amber = approaching minimum, Green = OK).
-
Near-expiry alert fires automatically for any item within the configured threshold (default 30 days to expiry); notification sent to WH Manager and Business Head.
-
Shortage allocation: if total available quantity for a SKU < total ordered quantity across all routes, the system calculates: allocated_qty_per_route = available_qty × (route_ordered_qty / total_ordered_qty). Each route receives exactly its pro-rata share, rounded down to whole units. Remainder units (from rounding) are flagged for manual allocation by WH Manager.
-
The weekly stock position report is submitted to the SCM Manager by the WH Manager every Sunday by 7:00 PM; system generates the report automatically at 6:30 PM Sunday and prompts the WH Manager to review and submit; if not submitted by 7:00 PM, an escalation alert is sent to the Business Head.
Business Rules Enforced
-
WH-01: GRN blocked without open PO.
-
WH-04: Expiry < 60 days = auto-reject.
-
WH-07/WH-11: FIFO inbound, FEFO outbound.
-
WH-16 (clarified): Pro-rata shortage allocation.
-
VM-13: Handover at receiving bay only.
-
VM-14 / BR-15: Rejected goods → same-day return → auto Debit Note.
Edge Cases & Error States
-
PO already fully received: System shows "This PO is closed" and blocks new GRN; WH Manager must raise a discrepancy report.
-
Stock variance after weekly count: System generates variance report (expected vs counted); WH Manager must record reason for each variance > 1%; variance > 3% triggers Business Head notification.
-
All stock for a SKU in near-expiry status: System flags for immediate dispatch priority; WH Manager and Sales Head are notified.
5.6 Procurement & Vendor Management Module
Module Purpose: Manage the full procurement lifecycle from vendor registration through RFQ, PO issuance, goods receipt, and vendor payment compliance, with the SCM Manager as the primary actor.
User Stories
| ID | User Story |
|---|---|
| US-VM-01 | As a SCM Manager, I want to register a new vendor with all required details so that POs can be raised against them after Business Head approval. |
| US-VM-02 | As a SCM Manager, I want to raise an RFQ and track vendor responses within 48 hours so that I have competitive pricing before recommending a PO. |
| US-VM-03 | As a SCM Manager, I want to raise a PO and submit it for Business Head approval so that it can be issued to the vendor by Monday 10:00 AM. |
| US-VM-04 | As an Accounts user, I want the system to block vendor payment if an open Debit Note exists for that vendor so that rejected goods are formally resolved before payment. |
| US-VM-05 | As a Business Head, I want to receive an alert 7 days before any vendor contract expires so that renewal can be initiated without disruption. |
Acceptance Criteria
-
Vendor registration form requires all mandatory fields: legal name, contact person, SKU list, DP per SKU, credit terms, lead time (days), margin/GPM %, exclusivity scope, contract expiry date, bank details. Business Head must approve the registration before any PO can be raised for that vendor.
-
RFQ workflow: SCM Manager creates RFQ specifying SKU(s), quantity, and delivery date → system records RFQ issue timestamp → system sends notification to tagged vendors → vendors' responses (price, availability, lead time) are logged against the RFQ record → system flags any vendor that has not responded within 48 hours of RFQ issue with a "Non-Responsive" status → SCM Manager reviews responses and marks their recommendation → Business Head approves → PO raised against winning vendor.
-
PO form requires: vendor selection (from registered vendor list only), SKU(s) with quantities and agreed DP, required delivery date, WH receiving address. System blocks PO creation if vendor is not registered and approved.
-
PO must be approved by Business Head before it is issued; approved POs issued to vendor by Monday 10:00 AM; system records issue timestamp.
-
On PO issue, vendor has 24 hours to acknowledge; system tracks acknowledgement timestamp; unacknowledged POs after 24 hours are flagged to SCM Manager.
-
Any amendment to a PO after it has been issued requires: Business Head approval, system record of the amendment (field changed, old value, new value), and a notification to the vendor.
-
7-day contract expiry alert is sent to SCM Manager and Business Head as a dashboard notification and push notification.
-
For uncontracted SKUs, the RFQ process requires a minimum of 2 vendor quotes before SCM Manager can make a recommendation.
Business Rules Enforced
-
VM-01/VM-03: Unregistered vendor blocks PO; Business Head must approve.
-
VM-07: PO requires Business Head approval.
-
VM-08: Monday 10:00 AM PO issuance cadence.
-
VM-09: 24-hour vendor PO acknowledgement window.
-
VM-12: 48-hour RFQ response window.
-
VM-13: Receiving bay handover enforced at GRN.
-
VM-14: Rejection → auto Debit Note.
-
AC-17: Open Debit Note blocks vendor payment.
Edge Cases & Error States
-
Only one vendor available for a SKU: System allows waiver of the 2-vendor RFQ minimum with Business Head approval; waiver is logged.
-
Vendor fails to acknowledge PO within 24 hours: SCM Manager must follow up offline; the PO remains open until vendor acknowledges or SCM Manager marks "Manually Confirmed".
-
Debit Note amount exceeds vendor outstanding payable: System logs the excess as a credit to be applied against next invoice; Business Head is notified.
5.7 Dispatch & VLS Management Module
Module Purpose: Generate and manage the Vehicle Stock Allocation Sheet (VLS) each night post-order-cut-off, oversee the picking and staging process, and control DSR loading and departure.
User Stories
| ID | User Story |
|---|---|
| US-DS-01 | As a WH Manager, I want the VLS to be auto-generated from the day's orders immediately after the 8:00 PM cut-off so that the picking team can begin work without delay. |
| US-DS-02 | As a WH Manager, I want to record a designated checker's verification of staged goods against the VLS before the vehicle is sealed so that loading errors are caught before departure. |
| US-DS-03 | As a WH Manager, I want to log the DSR's vehicle condition check before authorising departure so that unsafe vehicles do not leave the warehouse. |
| US-DS-04 | As a DSR, I want to sign the VLS digitally to accept stock accountability before loading so that my responsibility for the stock is formally recorded. |
| US-DS-05 | As a WH Manager, I want to log and flag any DSR who arrives late or departs late so that punctuality is tracked and visible to management. |
Acceptance Criteria
-
At 8:00 PM, the system auto-closes order entry and generates a Delivery Order (DO) consolidating all submitted orders. The WH Manager accesses the DO and generates VLS; the VLS generation action is available from 8:00 PM onwards.
-
VLS document includes: DSR name, vehicle ID, route/beat area, outlet delivery sequence (ordered by geography), per-outlet SKU list (item name, qty ordered, qty to deliver), total qty per SKU on vehicle, and shortage flags (if pro-rata allocation has reduced any qty).
-
VLS is printed per vehicle (PDF generated by system); print action available to WH Manager only; target print completion time: before 9:00 PM.
-
Picking workflow: WH Manager assigns the VLS to the picking team → picking team stages goods → a designated checker (a different person from the picker, assigned by WH Manager in the system) verifies each line of the VLS against staged goods → checker clicks "Confirm All Lines Verified" in system → system records: checker user ID, verification timestamp → VLS status changes to "Staged — Pending Signature".
-
DSR signs the VLS digitally in the system (DSR user ID + timestamp); system blocks loading confirmation until DSR signature is recorded.
-
WH Manager counter-signs the VLS digitally (WH Manager user ID + timestamp); system blocks DSR departure until counter-sign is recorded.
-
DSR arrival time is logged by WH Manager at the start of morning operations; if arrival time > 7:00 AM, system flags the record as "Late Arrival" with the logged timestamp.
-
Vehicle condition check is recorded by WH Manager: fuel level (OK / Low), tyres (OK / Defective), lights (OK / Defective). If any item is "Defective", the system blocks vehicle clearance for departure and generates an alert to Sales Head.
-
DSR departure time is logged when WH Manager marks "Vehicle Departed"; if departure time > 8:30 AM, system flags "Late Departure" with timestamp; alert sent to Sales Head.
-
The VLS is printed in two copies: original travels with the DSR in the vehicle, copy retained by WH Manager; system records document custody status.
Business Rules Enforced
-
BR-16: WH Manager VLS counter-sign required before DSR can depart.
-
DS-01a: Checker verification before staging sealing.
-
DS-24: 7:00 AM DSR arrival — late flagged.
-
DS-25: Vehicle condition check before departure.
-
DS-26: 8:30 AM departure deadline — late flagged.
Edge Cases & Error States
-
No orders submitted for a route: VLS for that route has zero items; system alerts WH Manager and Sales Head; no VLS is generated for that DSR for the day.
-
Shortage causes a route VLS to have zero qty for a SKU: That SKU is listed on the VLS as "0 — Shortage" for all affected outlets; outlet-level notes on the challan flag the shortage.
-
DSR absent: WH Manager can mark DSR absent; VLS status is set to "Undelivered — DSR Absent"; Sales Head is notified immediately.
5.8 DSR Delivery App Module
Module Purpose: Enable DSRs to execute delivery routes — GPS check-in, outlet identity confirmation, delivery logging, cash collection per outlet, and day-end return processing — fully offline-capable.
User Stories
| ID | User Story |
|---|---|
| US-DSR-01 | As a DSR, I want to see my full delivery sequence for the day in the app so that I visit outlets in the most efficient order. |
| US-DSR-02 | As a DSR, I want to confirm the outlet identity in the app before I unload goods so that I never deliver to the wrong outlet. |
| US-DSR-03 | As a DSR, I want to log cash collected at each outlet immediately after delivery so that there is a real-time record of my cash position throughout the day. |
| US-DSR-04 | As a DSR, I want to generate a challan at each outlet so that the outlet owner receives a signed delivery receipt. |
| US-DSR-05 | As a DSR, I want the app to block delivery completion at an outlet with an unpaid balance so that I do not leave goods without collecting the prior outstanding. |
Acceptance Criteria
-
The DSR app shows today's delivery route from the VLS: ordered outlet list, per-outlet SKU list with quantities, total vehicle load summary, and any shortage flags from the VLS.
-
GPS check-in at each outlet is mandatory before the delivery logging screen is unlocked.
-
Before the unloading screen is activated, the app displays a mandatory Outlet Identity Confirmation step: outlet name, owner name, and address are shown; the DSR must tap "Confirm — This is [Outlet Name]" to proceed. If the DSR taps "Wrong Outlet", delivery is blocked and an alert is sent to the WH Manager.
-
If the outlet has an unpaid previous invoice, the delivery completion button is blocked; the screen shows: "Outstanding balance: BDT [X]. Collect payment before completing delivery."
-
DSR logs per outlet: items delivered (each SKU and qty delivered — may differ from VLS if outlet refuses partial items), cash collected (BDT), challan number. Any qty variance from VLS must include a reason code.
-
Challan is generated in the app at delivery completion: outlet name, items ordered, items delivered, unit price, total value, delivery date. The challan is printed/shown on a receipt printer or displayed as a PDF for outlet owner sign-off; the signed original is left with the outlet; DSR retains a copy reference in the app.
-
Cash must be logged per outlet immediately after each delivery; the app does not allow navigation to the next outlet until the current outlet's delivery is marked as complete (delivered or closed/absent with reason).
-
If an outlet is closed or the owner is absent, the DSR logs reason code; no goods are left at the outlet; the items are retained on the vehicle and returned to WH at day-end.
-
Day-end return workflow: DSR taps "Return to Warehouse"; WH Manager opens the day-end reconciliation screen; WH Manager confirms receipt of: (a) cash envelope with total cash amount, (b) all signed challan copies, (c) all unsold/returned stock. The system shows the expected values for each from the VLS. WH Manager must confirm all three before closing the reconciliation; if any component is missing, reconciliation cannot close.
-
The DSR return time is logged when WH Manager initiates the day-end reconciliation; return times after 6:00 PM are flagged as "Late Return".
Business Rules Enforced
-
DS-06: GPS check-in mandatory.
-
DS-08: Cash logged per outlet — not end-of-day.
-
DS-09: Outstanding balance blocks delivery completion.
-
DS-28: Outlet identity confirmation before unloading.
-
DS-27: Original challan stays with outlet; DSR retains copy.
-
BR-17: Cash + challans + unsold stock must all be submitted together.
-
BR-16: Departure blocked until VLS counter-signed.
Edge Cases & Error States
-
DSR app offline all day: All delivery logs, cash entries, and challan data queued locally in SQLite; uploaded in bulk on first connection; day-end reconciliation can proceed via WH Manager's paper VLS copy and physical count.
-
Outlet GPS pin is far from actual outlet: DSR checks in with a GPS override (logs measured distance); WH Manager is notified; the outlet's GPS pin is flagged for correction.
-
Returns from outlet: DSR can only accept a return with explicit SO or WH Manager approval logged in the system; return reason is documented; items are added to "Returns" section of day-end reconciliation.
5.9 Cash & Accounts Module
Module Purpose: Process all daily cash flows — invoice generation, cash receipt from DSRs, supplier payables management, Debit Note tracking, and financial reporting.
User Stories
| ID | User Story |
|---|---|
| US-AC-01 | As an Accounts user, I want invoices to be auto-generated from confirmed SO orders so that I never have to manually create an invoice. |
| US-AC-02 | As an Accounts user, I want to match DSR cash receipts against invoices daily so that any discrepancy is flagged immediately. |
| US-AC-03 | As an Accounts user, I want the system to block vendor payment if an open Debit Note exists so that I cannot accidentally pay a vendor with unresolved rejected goods. |
| US-AC-04 | As a Business Head, I want a daily financial summary delivered to my dashboard by 7:00 PM so that I have a complete picture of the day's financials. |
| US-AC-05 | As an Accounts user, I want to generate the monthly P&L summary by the 5th of the following month from system-generated data so that I don't need to manually compile figures. |
Acceptance Criteria
-
Invoice is auto-generated when an SO order is confirmed (status = Submitted); invoice includes: outlet name, SO name, order date, SKUs with quantities, unit prices (from SKU master), applicable discounts (from promotional schemes), VAT/tax, and total BDT value. All retail invoices have payment_type = Cash; no credit field is present.
-
Invoice must be generated before goods leave the warehouse; system enforces this by requiring invoice issuance before the DSR's VLS can be marked "Ready for Departure".
-
Supplier payment schedule is auto-generated based on GRN date + vendor credit terms (e.g., GRN date + 30 days for a 30-day credit term). Accounts cannot process a payment before the scheduled date without Business Head approval.
-
Before processing any vendor payment, the system checks for open Debit Notes for that vendor. If any Debit Note with status = "Open" exists, the payment button is blocked with message: "Vendor payment blocked: open Debit Note [DN-XXXXX] of BDT [X] requires Business Head resolution."
-
Debit Note tracking dashboard: shows all Debit Notes with status (Open / Resolved / Credited), vendor name, value, age (days since raised), and linked GRN. Accounts can view; Business Head can resolve.
-
Cash Receipt Voucher is generated by the system after WH Manager confirms day-end reconciliation; signed digitally by DSR and WH Manager; stored against the reconciliation record.
-
Daily financial summary is auto-generated at 7:00 PM and sent to the Business Head's dashboard and as a push notification: total cash received (all DSRs), total invoices issued, total outstanding receivables, total supplier payments due this week, and any open discrepancies.
-
Outstanding receivable per outlet is maintained in real time; if an outlet's balance is > 0, all new order attempts for that outlet are blocked across the system (both SO app and system).
-
Monthly P&L summary is auto-generated by the system on the 5th working day of each month for the previous month; Accounts reviews and submits to Business Head.
-
Supplier invoice three-way match: Accounts can only process a supplier payment after confirming: (a) PO exists and is approved, (b) GRN is raised and signed, (c) supplier invoice matches PO price and GRN quantity. Any mismatch blocks payment.
Business Rules Enforced
-
BR-01: No credit for retail outlets.
-
BR-07: Supplier payment follows credit terms.
-
BR-08: Segregation of duty (WH Manager handles stock; Accounts handles cash).
-
AC-17: Open Debit Note blocks vendor payment.
-
AC-10: Three-way match (PO + GRN + supplier invoice) before payment.
Edge Cases & Error States
-
DSR cash collected > invoiced amount: Excess cash is logged as an overpayment against the outlet; Accounts is notified; credited against next invoice.
-
Supplier invoice amount differs from PO agreed DP: System flags the discrepancy; Accounts must get SCM Manager and Business Head sign-off before processing the payment at the invoiced amount.
-
Debit Note partially resolved: If vendor credits only part of the Debit Note value, Accounts logs the partial credit; remaining balance stays as Open; payment is still blocked for the remaining outstanding value.
5.10 Admin Panel & Reporting Module
Module Purpose: Provide master data management, role-based dashboards, governance controls, audit trail, and operational reporting across all modules.
User Stories
| ID | User Story |
|---|---|
| US-AD-01 | As an App Admin, I want to manage all master data (outlets, SKUs, routes, users, targets, promotions) from a single web interface so that the system remains accurate and up-to-date. |
| US-AD-02 | As a Business Head, I want a single dashboard showing all key operations metrics so that I can assess hub health without navigating multiple screens. |
| US-AD-03 | As a Business Head, I want to initiate a surprise stock or cash count in the system so that the count result is formally recorded and auditable. |
| US-AD-04 | As an App Admin, I want to view the complete audit log for any master data change so that I can trace the history of any record. |
Acceptance Criteria
-
App Admin can create, edit, and deactivate records for: outlets, SKUs, users, routes, promotional schemes, and targets. All edits are logged with: user ID, timestamp, entity type, record ID, field changed, old value, new value. Audit logs cannot be deleted or edited.
-
Business Head dashboard displays, on a single screen: (a) Visit Tracker — today's SO visit count vs target, (b) Order Summary — total order value vs WH daily target, (c) Cash Summary — total expected cash vs total collected, (d) Stock Alert — count of SKUs in Red/Amber coverage status, (e) Discrepancy Alerts — open cash discrepancies count, (f) Debit Note Alerts — count of open Debit Notes, (g) DSR Punctuality — count of late arrivals and departures today.
-
All dashboards update at a maximum 5-minute refresh interval; Business Head and Sales Head can manually refresh.
-
Surprise count workflow: Business Head triggers a "Surprise Count" for stock and/or cash from the admin panel → WH Manager receives in-app notification with instructions → WH Manager completes the count and enters findings → any variance is logged against the routine weekly variance record for trend analysis.
-
Route change approval workflow: Sales Head submits a route change request (outlet, proposed change, reason) → App Admin receives notification → App Admin applies change after Sales Head approval is recorded → before/after state logged permanently.
-
System generates the following scheduled reports automatically:
-
Daily: Opening stock report (7:00 AM), Cash summary (7:00 PM), Financial summary (7:00 PM).
-
Weekly: Stock position report to SCM Manager (Sunday 7:00 PM), SO performance flag report (Monday 7:00 AM).
-
Monthly: P&L summary (5th working day), Expense report, Stock valuation report.
- The Go-Live Readiness Checklist is accessible to Business Head and App Admin from the Admin Panel; it shows real-time completion status for all 8 data categories; the "Sign-Off and Unlock Day 1" button is shown only to the Business Head and is active only when all 8 items are complete.
Business Rules Enforced
-
AD-01/AD-02: Full audit trail; route change trail.
-
AD-03: Automated backups; monthly integrity audit.
-
AD-04: Paper fallback protocol.
-
AD-05: Surprise count workflow.
Edge Cases & Error States
-
App Admin accidentally deactivates a live SO user: System prompts confirmation; deactivated user cannot log in; all active routes remain in the system; Sales Head is notified immediately.
-
Promotional scheme expired but still in system: System auto-deactivates promotions past their validity end date; any order submitted after expiry does not receive the promotion; the scheme is moved to "Archived" status.
6. Data Model
6.1 Entities and Fields
OUTLET
-
outlet_id (PK, UUID)
-
outlet_name (string, required)
-
owner_name (string, required)
-
address (string, required)
-
zone (enum: Narayanganj Town / Bandor / Munshiganj)
-
outlet_type (enum: Grocery / Pharmacy / General Trade / Kiosk)
-
gps_lat (decimal, required)
-
gps_lng (decimal, required)
-
priority_tier (enum: P1 / P2)
-
drop_size_tier (enum: Small / Medium / Large)
-
estimated_drop_size_bdt (decimal)
-
contact_number (string, required)
-
so_assignment_id (FK → USER)
-
beat_day (enum: Sat / Sun / Mon / Tue / Wed / Thurs)
-
visit_frequency (enum: Weekly / Fortnightly)
-
competitor_brands (text)
-
status (enum: Active / Inactive / Permanently Closed)
-
outstanding_balance_bdt (decimal, default 0)
-
registration_date (date)
-
created_by (FK → USER)
-
last_modified_at (timestamp)
-
last_modified_by (FK → USER)
USER
-
user_id (PK, UUID)
-
name (string, required)
-
role (enum: SO / DSR / WH Manager / SCM Manager / Accounts / Sales Head / Business Head / App Admin)
-
assigned_zone (enum: Narayanganj Town / Bandor / Munshiganj / All)
-
login_credentials (hashed password + salt)
-
status (Active / Inactive)
-
created_at (timestamp)
-
last_login_at (timestamp)
ROUTE
-
route_id (PK, UUID)
-
so_id (FK → USER, role = SO)
-
beat_day (enum: Sat / Sun / Mon / Tue / Wed / Thurs)
-
outlet_list (FK[] → OUTLET)
-
p2_backup_pool (FK[] → OUTLET)
-
effective_from_date (date)
-
locked_until_date (date)
-
change_log (JSON array: [{changed_at, changed_by, reason, before_state, after_state}])
SKU
-
sku_id (PK, UUID)
-
sku_code (string, unique, required)
-
sku_name (string, required)
-
category (enum: Cosmetics / Food / General)
-
tp_bdt (decimal — Trade Price)
-
mrp_bdt (decimal — Maximum Retail Price)
-
unit_of_measure (string, e.g. PCS / BOX / KG)
-
stock_cover_category (enum: Fast / Medium / Slow)
-
is_active (boolean)
VENDOR
-
vendor_id (PK, UUID)
-
vendor_name (string, required)
-
contact_person (string, required)
-
sku_list (FK[] → SKU)
-
dp_per_sku (JSON: {sku_id: dp_bdt})
-
credit_terms (enum: CAD / 15-day / 30-day / Advance)
-
lead_time_days (integer)
-
margin_gpm_pct (decimal)
-
exclusivity_scope (text)
-
contract_expiry_date (date)
-
bank_details (encrypted text)
-
status (Active / Inactive / Pending Approval)
-
approved_by (FK → USER)
-
approved_at (timestamp)
PURCHASE_ORDER (PO)
-
po_id (PK, UUID)
-
vendor_id (FK → VENDOR)
-
sku_list_qty (JSON: [{sku_id, qty_ordered, agreed_dp_bdt}])
-
delivery_date (date)
-
wh_address (string)
-
status (enum: Draft / Approved / Issued / Acknowledged / Partially Received / Closed / Cancelled)
-
created_by (FK → USER — SCM Manager)
-
approved_by (FK → USER — Business Head)
-
approved_at (timestamp)
-
issued_at (timestamp)
-
vendor_acknowledged_at (timestamp)
GRN (Goods Received Note)
-
grn_id (PK, UUID)
-
po_id (FK → PO)
-
received_date (date)
-
handover_location (enum: Receiving Bay / Other)
-
handover_location_note (text, required if Other)
-
items_received (JSON: [{sku_id, batch_number, expiry_date, qty_ordered, qty_received, condition}])
-
items_rejected (JSON: [{sku_id, qty_rejected, rejection_reason}])
-
discrepancy_photos (file references)
-
discrepancy_notes (text)
-
same_day_return_confirmed (boolean)
-
wh_manager_sign_id (FK → USER)
-
signed_at (timestamp)
-
status (enum: Draft / Signed / Partial / Closed)
DEBIT_NOTE
-
debit_note_id (PK, UUID)
-
grn_id (FK → GRN)
-
vendor_id (FK → VENDOR)
-
items_rejected (JSON: [{sku_id, sku_name, qty_rejected, rejection_reason, unit_dp_bdt}])
-
total_value_bdt (decimal)
-
raised_by (FK → USER)
-
raised_at (timestamp)
-
status (enum: Open / Resolved / Credited)
-
resolution_notes (text)
-
resolved_by (FK → USER)
-
resolved_at (timestamp)
STOCK_LEDGER
-
ledger_id (PK, UUID)
-
sku_id (FK → SKU)
-
transaction_type (enum: GRN / Dispatch / Return / Adjustment / Rejected)
-
quantity (integer — positive for inbound, negative for outbound)
-
batch_number (string)
-
expiry_date (date)
-
reference_id (string — PO ID / DO ID / VLS ID / Adjustment reference)
-
reference_type (enum: PO / DO / VLS / Adjustment)
-
performed_by (FK → USER)
-
timestamp (timestamp)
ORDER
-
order_id (PK, UUID)
-
outlet_id (FK → OUTLET)
-
so_id (FK → USER)
-
order_date (date)
-
sku_list_qty (JSON: [{sku_id, qty, unit_price_bdt, discount_applied, promotion_id}])
-
total_value_bdt (decimal)
-
status (enum: Submitted / Processing / Dispatched / Delivered / Partially Delivered / Cancelled)
-
submitted_at (timestamp — must be ≤ 8:00 PM cut-off)
-
is_cutoff_compliant (boolean)
DELIVERY_ORDER (DO)
-
do_id (PK, UUID)
-
order_id (FK → ORDER)
-
dsr_id (FK → USER)
-
vehicle_id (string)
-
route_id (FK → ROUTE)
-
generated_at (timestamp)
VLS (Vehicle Stock Allocation Sheet)
-
vls_id (PK, UUID)
-
do_ids (FK[] → DELIVERY_ORDER)
-
dsr_id (FK → USER)
-
vehicle_id (string)
-
outlet_sequence (JSON: ordered array of outlet_ids with per-outlet SKU/qty lists)
-
shortage_flags (JSON: [{sku_id, ordered_qty, allocated_qty, shortage_pct}])
-
checker_user_id (FK → USER)
-
checker_confirmed_at (timestamp)
-
dsr_signature (boolean)
-
dsr_signed_at (timestamp)
-
wh_manager_signature (boolean)
-
wh_manager_signed_at (timestamp)
-
status (enum: Generated / Staged / Checker Verified / DSR Signed / WH Countersigned / Departed / Returned / Reconciled)
-
printed_at (timestamp)
DSR_ATTENDANCE_LOG
-
log_id (PK, UUID)
-
dsr_id (FK → USER)
-
date (date)
-
arrival_time (timestamp)
-
arrival_status (enum: On Time / Late)
-
vehicle_id (string)
-
vehicle_check_fuel (enum: OK / Low)
-
vehicle_check_tyres (enum: OK / Defective)
-
vehicle_check_lights (enum: OK / Defective)
-
vehicle_cleared_for_departure (boolean)
-
departure_time (timestamp)
-
departure_status (enum: On Time / Late)
-
logged_by (FK → USER — WH Manager)
CHALLAN (Delivery Note)
-
challan_id (PK, UUID)
-
vls_id (FK → VLS)
-
outlet_id (FK → OUTLET)
-
dsr_id (FK → USER)
-
delivery_date (date)
-
items_ordered (JSON: [{sku_id, qty_ordered}])
-
items_delivered (JSON: [{sku_id, qty_delivered, variance_reason}])
-
cash_collected_bdt (decimal)
-
outlet_identity_confirmed (boolean)
-
outlet_identity_confirmed_at (timestamp)
-
outlet_signature (boolean)
-
outlet_signed_at (timestamp)
-
delivery_outcome (enum: Delivered / Partially Delivered / Closed / Owner Absent / Refused / Wrong Outlet)
-
delivery_timestamp (timestamp)
-
challan_copy_with_dsr (boolean)
CASH_RECONCILIATION
-
recon_id (PK, UUID)
-
dsr_id (FK → USER)
-
vls_id (FK → VLS)
-
date (date)
-
total_invoiced_bdt (decimal)
-
total_cash_expected_bdt (decimal)
-
total_cash_collected_bdt (decimal)
-
unsold_stock_returned (JSON: [{sku_id, qty}])
-
challans_submitted_count (integer)
-
cash_envelope_confirmed (boolean)
-
challans_confirmed (boolean)
-
unsold_stock_confirmed (boolean)
-
variance_bdt (decimal)
-
variance_reason (text)
-
so_verification_required (boolean)
-
so_findings (text)
-
management_resolution (text)
-
status (enum: Pending / Complete / Discrepancy — Under Review / Resolved / Escalated)
-
closed_by (FK → USER)
-
closed_at (timestamp)
INVOICE
-
invoice_id (PK, UUID)
-
order_id (FK → ORDER)
-
outlet_id (FK → OUTLET)
-
items (JSON: [{sku_id, qty, unit_price_bdt, discount_bdt, vat_bdt, line_total_bdt}])
-
subtotal_bdt (decimal)
-
total_discount_bdt (decimal)
-
total_vat_bdt (decimal)
-
total_bdt (decimal)
-
payment_type (constant: Cash)
-
issued_at (timestamp)
-
issued_by (FK → USER — Accounts)
VISIT_LOG
-
visit_id (PK, UUID)
-
so_id (FK → USER)
-
outlet_id (FK → OUTLET)
-
visit_date (date)
-
gps_checkin_lat (decimal)
-
gps_checkin_lng (decimal)
-
gps_match_status (enum: Pass / Fail / Override)
-
gps_distance_metres (decimal)
-
visit_outcome (enum: Order Placed / Closed / Owner Absent / Refused / Competitor Only)
-
p2_activation (boolean)
-
p2_reason_code (enum: Closed / Owner Absent / Refusing / Permanently Shut)
-
order_id (FK → ORDER, nullable — if visit outcome = Order Placed)
-
checkin_timestamp (timestamp)
PROMOTIONAL_SCHEME
-
scheme_id (PK, UUID)
-
scheme_name (string)
-
sku_id (FK → SKU)
-
trigger_qty (integer — buy X)
-
bonus_qty (integer — get Y)
-
discount_pct (decimal — or flat discount)
-
valid_from (date)
-
valid_to (date)
-
is_active (boolean)
-
created_by (FK → USER)
6.2 Entity Relationships
ORDER →belongs to→ OUTLET ORDER →placed by→ USER (role: SO) ORDER →generates→ INVOICE ORDER →generates→ DELIVERY_ORDER DELIVERY_ORDER →assigned to→ USER (role: DSR) DELIVERY_ORDER →grouped into→ VLS VLS →signed by→ USER (role: DSR) VLS →counter-signed by→ USER (role: WH Manager) VLS →checker verified by→ USER (role: designated checker) VLS →generates→ CHALLAN (one per outlet) CHALLAN →belongs to→ OUTLET CHALLAN →references→ VLS CHALLAN →closes→ CASH_RECONCILIATION (aggregated) DSR_ATTENDANCE_LOG →belongs to→ USER (role: DSR) PURCHASE_ORDER →raised by→ USER (role: SCM Manager) PURCHASE_ORDER →approved by→ USER (role: Business Head) PURCHASE_ORDER →received as→ GRN GRN →belongs to→ PURCHASE_ORDER GRN →matched to→ VENDOR GRN →generates→ DEBIT_NOTE (on rejection) DEBIT_NOTE →against→ VENDOR DEBIT_NOTE →resolved by→ USER (role: Business Head) STOCK_LEDGER →references→ SKU STOCK_LEDGER →references→ PURCHASE_ORDER / VLS VISIT_LOG →belongs to→ USER (role: SO) VISIT_LOG →records visit to→ OUTLET OUTLET →assigned to→ USER (role: SO) OUTLET →belongs to→ ROUTE ROUTE →owned by→ USER (role: SO)
7. API Design Principles
7.1 REST Conventions
-
All APIs follow RESTful conventions: resources as nouns, HTTP verbs for actions (GET, POST, PUT, PATCH, DELETE).
-
Base URL pattern: https://api.dist-hub.example.com/v1/{resource}
-
All responses: JSON format with envelope { "status": "success|error", "data": {...}, "message": "..." }.
-
Pagination: cursor-based for large collections (visit logs, stock ledger); page-size default = 50, maximum = 500.
-
Timestamps: ISO 8601 format (UTC). Client devices must handle timezone conversion to local BDT (UTC+6).
-
Error codes: standard HTTP status codes (200, 201, 400, 401, 403, 404, 409, 422, 500) with machine-readable error codes in response body.
7.2 Authentication & Authorization
-
All endpoints require a valid JWT Bearer token in the Authorization header.
-
Token expiry: 12 hours for web app; 7 days for mobile app (with refresh token rotation).
-
RBAC enforcement: each API endpoint declares the minimum required role; the auth middleware validates the caller's role before processing.
-
SO data scoping: any endpoint that returns outlet, order, or visit data applies an automatic WHERE so_id = {caller.user_id} filter for users with role = SO; this is enforced at the API layer, not relying on client-side filtering.
-
Rate limiting: 100 requests/minute per user; 500 requests/minute per IP.
7.3 Offline Sync Strategy for Mobile
-
Mobile apps maintain a local SQLite database as the primary data store for field operations.
-
Master data pull (server → device): Full sync at app launch; delta sync every 30 minutes when connected. Master data includes: outlet list, SKU master, route plan, active promotions, daily targets.
-
Transaction push (device → server): All write operations (visit logs, orders, delivery logs, cash entries) are written locally first with sync_status = pending. A background sync worker pushes pending records to server at every available connection window. Server returns sync_id for each accepted record; device updates sync_status = synced.
-
Conflict strategy: Master data conflicts: server wins. Transaction conflicts (duplicate visit log for same outlet/time): server rejects with 409; device logs are kept locally with sync_status = conflict; App Admin is notified.
-
Sync status display: Mobile header shows: "Synced [X min ago]" / "Offline — [N] records pending".
7.4 Key API Resource Groups
| Resource Group | Base Path | Primary Operations |
|---|---|---|
| Auth | /auth | POST /login, POST /refresh, POST /logout |
| Users | /users | CRUD (App Admin only for write) |
| Outlets | /outlets | CRUD + bulk import + GPS proximity check |
| Routes | /routes | GET route by SO, POST beat assignment, PUT lock/unlock |
| SKUs | /skus | CRUD, GET active list |
| Orders | /orders | POST new order, GET by SO/date/outlet, PATCH status |
| Visit Logs | /visit-logs | POST new visit, GET by SO/date/route |
| VLS | /vls | GET by date/DSR, POST generate, PATCH sign/counter-sign/checker-confirm |
| Challans | /challans | POST create, PATCH delivery-complete, GET by DSR/date |
| GRN | /grn | POST create, PATCH sign, GET by PO/vendor |
| Debit Notes | /debit-notes | POST create (auto), PATCH resolve, GET by vendor/status |
| Purchase Orders | /purchase-orders | POST create, PATCH approve/issue/acknowledge, GET by vendor/status |
| Vendors | /vendors | CRUD, GET by SKU |
| Stock Ledger | /stock-ledger | GET current stock, GET by SKU/date, POST adjustment |
| Cash Reconciliation | /reconciliations | POST create, PATCH close, GET by DSR/date |
| Targets | /targets | GET by SO/month, POST set monthly, PATCH revise |
| Reports | /reports | GET daily-summary, GET weekly-performance, GET monthly-pl |
| DSR Attendance | /dsr-attendance | POST log-arrival, PATCH vehicle-check, PATCH log-departure |
| Notifications | /notifications | GET unread, PATCH mark-read |
| Go-Live Checklist | /go-live-checklist | GET status, POST sign-off |
8. Integration Specifications
| Integration | Type | Provider Options | Trigger | Data Sent | Data Received | Phase |
|---|---|---|---|---|---|---|
| GPS / Maps | REST API (inbound) | Google Maps Platform; fallback: OpenStreetMap/Nominatim | Outlet GPS check-in; outlet registration; route map render | GPS coordinates | Reverse geocode address; nearest outlet proximity check; map tile rendering | Phase 1 |
| Push Notifications — Mobile | Outbound push | Firebase Cloud Messaging (FCM) | System-generated alerts: late DSR, stock alert, missed outlet, target flag, discrepancy | Alert type, message text, recipient user_id, deep link | Delivery confirmation (delivered / failed) | Phase 1 |
| SMS Gateway — Backup Alerts | Outbound SMS | Local Bangladesh SMS API (e.g., SSL Wireless, SSLCOMMERZ SMS) | Critical events: cash discrepancy, major stock shortage, system downtime alert | Recipient phone number, message text | Delivery status | Phase 1 |
| Photo / File Storage | Object storage | AWS S3 / compatible (e.g., MinIO self-hosted) | GRN discrepancy photo upload; SO damage/expiry photo upload | Image file (JPEG/PNG, max 5 MB) | File URL / key for storage in DB | Phase 1 |
| Bank / Cash Deposit | Manual entry (Phase 1); API (Phase 2) | Local bank API (to be identified) | Daily cash deposit by Accounts | Deposit amount, date, reference number | Bank confirmation reference | Phase 1: Manual; Phase 2: API |
| Logistics Vendor (3PL) | Manual coordination (Phase 1) | N/A | Daily vehicle assignment for DSR routes | Vehicle ID, DSR name, route area (via email/phone) | Vehicle confirmation | Phase 1: Manual; Phase 2: API integration |
| Head Office HR System | Outbound API (Phase 2) | HR platform TBD | Weekly or on-event (disciplinary action logged) | User ID, attendance data, disciplinary record | Employee record confirmation | Phase 2 |
| Accounting Software (ERP) | Export (Phase 1); API (Phase 2) | Tally / SAP / custom (to be identified) | Monthly: P&L export; daily: financial summary export | Invoice records, payment records, P&L data (CSV/JSON) | Import confirmation | Phase 1: Export; Phase 2: API |
9. Non-Functional Requirements
| Category | Requirement | Specification |
|---|---|---|
| Availability | System uptime target | 99.5% minimum; equates to <44 hours downtime per year |
| Availability | Critical operating window | 7:00 AM – 9:00 PM daily (Sat–Thurs); highest availability priority during this window |
| Performance | API response time (web) | <2 seconds for 95th percentile of all web app requests under normal load |
| Performance | API response time (mobile critical paths) | <3 seconds for GPS check-in submission, order submission, and delivery log submission |
| Performance | Report generation | Standard daily reports generated in <10 seconds; monthly P&L report in <60 seconds |
| Performance | VLS generation | VLS generation for 6 routes (after order cut-off) completes in <2 minutes |
| Offline Mode | SO app offline capability | Full route execution (check-in, order entry, visit log, P2 activation) must work with zero server connectivity; no feature degradation for core workflows |
| Offline Mode | DSR app offline capability | Full delivery execution (outlet confirmation, delivery log, cash entry, challan generation) must work with zero server connectivity |
| Offline Mode | Local data retention | Offline data must persist across app restarts; no data loss if device battery dies and restarts |
| Offline Mode | Sync completion time | All queued records must sync to server within 60 seconds of re-establishing connectivity |
| Data Backup | Backup frequency | Automated full database backup: daily (2:00 AM); transaction log backup: every 4 hours |
| Data Backup | Recovery Point Objective (RPO) | Maximum data loss on failure: 4 hours |
| Data Backup | Recovery Time Objective (RTO) | System restored and operational within 4 hours of declared outage |
| Data Backup | Backup retention | Daily backups retained for 90 days; monthly backups retained for 3 years |
| Security | Authentication | JWT Bearer tokens; no session cookies; token expiry: 12 hours (web), 7 days (mobile with refresh) |
| Security | Authorization | RBAC enforced at API layer for every endpoint; role validation is server-side, never client-side |
| Security | Data in transit | TLS 1.2 minimum for all API communication; TLS 1.3 preferred |
| Security | Data at rest | AES-256 encryption for: user credentials, vendor bank details, any PII fields |
| Security | SO data isolation | SO API tokens are scoped; any request by an SO for data outside their assigned route returns HTTP 403 |
| Security | Audit log integrity | Audit logs are append-only at the database level; no DELETE or UPDATE operations permitted on audit tables |
| Scalability | Outlet universe | System architecture must handle 5,400 outlets (full P1+P2) without schema changes or performance degradation |
| Scalability | Concurrent users | Support minimum 50 concurrent users (6 SOs + DSRs + web users) in Phase 1; architecture must scale to 200 concurrent users for Phase 2 without re-architecture |
| Scalability | Transaction volume | Support 500+ orders per day, 200+ delivery logs per day, 50+ GRN line items per event |
| Device Support | Mobile (SO/DSR apps) | Android 8.0 (API level 26) and above; minimum 2 GB RAM device; tested on common Bangladesh market Android devices |
| Device Support | Web app | Chrome (latest 2 versions), Firefox (latest 2 versions), Microsoft Edge (latest 2 versions); minimum 1280×720 screen resolution |
| Language | UI language | English throughout; BDT (Bengali Taka) currency formatting with comma separators (e.g., 1,00,000) |
| Audit Trail | Scope | Every CREATE, UPDATE, and DELETE operation on any business entity is logged permanently |
| Audit Trail | Log fields | Entity type, entity ID, operation type, changed fields (old/new values), user ID, timestamp, IP address |
| Audit Trail | Immutability | Audit log records cannot be modified or deleted by any user including App Admin |
| Downtime Protocol | Paper fallback | Paper versions of VLS, challan, and GRN forms are pre-printed and available at the warehouse; all paper data is back-entered into the system within 24 hours of restoration |
| Downtime Protocol | Notification | System downtime triggers automatic SMS alert to WH Manager, Sales Head, and Business Head |
10. Go-Live Readiness Gate
10.1 Purpose
The Go-Live Readiness Gate is a formal system control that prevents Day 1 operations from commencing until the Business Head has verified that all foundational data is correctly loaded and configured. No SO leaves the warehouse on Day 1, and no DSR receives a VLS, until the Business Head executes the "Sign-Off and Unlock Day 1" action.
10.2 The 8-Item Checklist
| # | Data Category | What "Verified" Means | Responsible to Load | Verified By |
|---|---|---|---|---|
| 1 | Outlet Master | All P1 + P2 outlets loaded with: outlet name, owner name, address, GPS coordinates (within 50m accuracy), zone, outlet type, priority tier, SO assignment, beat day, drop size tier. Zero outlets with missing mandatory fields. | App Admin | Business Head |
| 2 | Route / Beat Plan | Every P1 outlet in the system is assigned to exactly one SO and one beat day (Sat–Thurs only). Each SO has exactly 75 P1 outlets on their route. P2 backup pool (up to 10 per SO per beat day) is assigned. Route lock is activated. | App Admin | Business Head |
| 3 | SKU Master | All active SKUs loaded with: SKU code, SKU name, category, trade price (TP), MRP, unit of measure, stock cover category. Zero SKUs with missing prices. | App Admin | Business Head |
| 4 | Monthly Targets | SO-level monthly revenue target and memo target loaded for the current operating month. WH-level target validated against BDT 3.5 Cr budget floor. All 6 SO targets are distinct and sum to the WH target. | App Admin | Business Head |
| 5 | Incentive Thresholds | Three incentive tier values configured per SO: Test (BDT 750), 1st Step (BDT 17,500), BEP (BDT 27,500). Tier thresholds visible in each SO's app. | App Admin | Business Head |
| 6 | SO User Accounts | Unique login credentials created for all 6 SOs. Each SO's account is scoped to their own route only. Each SO has successfully logged in and confirmed app access in a pre-launch test. | App Admin | Business Head |
| 7 | Promotional Schemes | All active promotional schemes (if any) loaded with: scheme name, qualifying SKU, trigger quantity, bonus/discount, validity start date, validity end date. No scheme with a past expiry date is in Active status. | App Admin | Business Head |
| 8 | Access Roles | All system roles configured and assigned: SO (6), DSR (per fleet), WH Manager (1), SCM Manager (1), Accounts (1+), Sales Head (1), Business Head (1), App Admin (1). All non-SO users have logged into the web app and confirmed access. | App Admin | Business Head |
10.3 System Sign-Off Process
-
App Admin completes data loading for each item and marks it as "Ready for Review" in the Go-Live Checklist screen.
-
The system automatically validates completeness for items 1–8 (e.g., counts outlets with missing fields, checks SKU prices are non-zero, verifies each SO has exactly 75 route outlets).
-
System shows a real-time completion status next to each item: a green checkmark if validation passes, a red X with item count if validation fails.
-
Once all 8 items show green checkmarks, the "Sign-Off and Unlock Day 1" button becomes active for the Business Head.
-
Business Head clicks the button; a confirmation modal shows: "You are signing off that all 8 data categories are complete and verified. Day 1 operations will be unlocked. This action cannot be undone." Business Head confirms.
-
System records: sign-off user ID, timestamp; sets system state go_live_unlocked = true.
-
From this moment, SOs can log in and access their routes; DSRs can log in; WH Manager can generate VLS for Day 1.
11. KPI Thresholds & Alert Configuration
| KPI | Definition | Target Value | Alert Threshold | Alert Recipient | Measurement Frequency | System Source |
|---|---|---|---|---|---|---|
| Memos/Day per SO | Number of outlet visits logged by SO in a single day | ≥ 30 per day | < 25 in a day | Sales Head | Daily (end of day) | VISIT_LOG count per so_id per date |
| Strike Rate | % of SO visits that result in a submitted order | > 70% | < 60% | Sales Head | Daily | (ORDER count / VISIT_LOG count) × 100 per SO per date |
| LPC (Lines Per Call) | Average number of distinct SKUs per submitted order | > 2.5 SKUs per order | < 2.0 | Sales Head | Daily | Sum(SKU line count per order) / Order count per SO per date |
| Effective Coverage (EC) | % of assigned P1 outlets visited at least once in the current month | > 85% | < 75% | Sales Head | Monthly (calculated daily, alerted monthly) | (Distinct outlet_ids in VISIT_LOG this month) / (Total P1 outlets on route) |
| Order Value per Memo | Average BDT order value per outlet visit | BDT 12,222 (at BEP target) | — (tracked, not alerted) | Business Head | Daily | Sum(ORDER.total_value_bdt) / Visit count per SO per date |
| SKU Distribution | % of target SKUs placed in at least one order per outlet per month | > 60% | — (tracked weekly) | Sales Head | Weekly | (Distinct SKUs ordered at outlet this month) / (Total active SKUs) per outlet |
| P1 Outlet Strike Rate | % of assigned P1 outlets with at least one order in the week | > 85% | < 80% | Sales Head | Weekly (Monday morning) | (P1 outlets with ORDER this week) / (Total P1 on route) |
| P2 Activations/Day | % of route that is P2 on a given day | < 10% of route per day | > 10% in a day | Sales Head | Daily | P2 VISIT_LOG count / (75 P1 + P2 activations) per SO per date |
| Weekly Target Attainment | SO's actual order revenue vs weekly milestone target | ≥ 100% | < 80% | Sales Head (Monday alert) | Weekly | Sum(ORDER.total_value_bdt this week) / Weekly_target_bdt per SO |
| Outlets Visited/Day | Total P1 outlets visited by SO in a day | 75 minimum | < 60 | Sales Head | Daily | VISIT_LOG count per so_id per date (P1 only) |
| Stock Variance | Difference between system stock and physical count | < 1% per SKU per week | > 1% for any SKU | WH Manager, Business Head | Weekly (on stock count entry) | (Counted qty − System qty) / System qty × 100 per SKU |
| GRN Timeliness | % of GRNs raised within 1 hour of completed physical count | 100% | Any GRN > 1 hour after delivery completion | WH Manager | Per event | GRN.signed_at − delivery_arrival_time > 60 minutes |
| DSR Departure Compliance | % of DSR departures on or before 8:30 AM | 100% | Any departure after 8:30 AM | WH Manager, Sales Head | Daily | DSR_ATTENDANCE_LOG.departure_time > 08:30 |
| DSR Return Compliance | % of DSR returns by 6:00 PM | > 95% | Any return after 6:00 PM | WH Manager | Daily | CASH_RECONCILIATION.reconciliation_start_time > 18:00 |
| Cash Reconciliation Rate | % of DSRs with zero cash variance at day-end | 100% | Any DSR with variance > BDT 0 | WH Manager, Business Head | Daily | CASH_RECONCILIATION.variance_bdt ≠ 0 |
| Stock Cover — Fast SKUs | Days of stock remaining at current consumption rate | ≥ 14 days | < 14 days | WH Manager, SCM Manager | Daily | Current_stock_qty / Avg_daily_dispatch_qty |
| Stock Cover — Medium SKUs | Days of stock remaining at current consumption rate | ≥ 10 days | < 10 days | WH Manager, SCM Manager | Daily | Current_stock_qty / Avg_daily_dispatch_qty |
| Stock Cover — Slow SKUs | Days of stock remaining at current consumption rate | ≥ 7 days | < 7 days | WH Manager, SCM Manager | Daily | Current_stock_qty / Avg_daily_dispatch_qty |
| Max Stock Cap | Days of stock held for any SKU | ≤ 30 days | > 30 days | Business Head | Daily | Current_stock_qty / Avg_daily_dispatch_qty > 30 |
| Vendor PO Acknowledgement | % of POs acknowledged by vendor within 24 hours | 100% | Any PO unacknowledged after 24 hours | SCM Manager | Per event | PURCHASE_ORDER.vendor_acknowledged_at − issued_at > 24 hours |
| RFQ Response Timeliness | % of RFQ responses received within 48 hours | 100% | Any vendor not responding within 48 hours | SCM Manager | Per event | RFQ.response_received_at − rfq_issued_at > 48 hours |
| Open Debit Notes Age | Age of oldest open Debit Note per vendor | < 7 days | Any open Debit Note > 7 days old | Accounts, Business Head | Daily | DEBIT_NOTE.raised_at − today > 7 days AND status = Open |
| DSR Arrival Compliance | % of DSR arrivals by 7:00 AM | 100% | Any arrival after 7:00 AM | WH Manager | Daily | DSR_ATTENDANCE_LOG.arrival_time > 07:00 |
12. Enum Values Reference
This section is the definitive reference for all dropdown/enum values used across the system. Engineering must implement exactly these values as the allowed set; no free-text alternatives are accepted for enum fields.
12.1 Outlet Types
Grocery Pharmacy General Trade Kiosk
12.2 Priority Tiers
P1 P2
12.3 Drop Size Tiers
Small (BDT 500 – 2,000) Medium (BDT 2,001 – 8,000) Large (BDT 8,001 and above)
12.4 Beat / Visit Days
Sat Sun Mon Tue Wed Thurs
Friday is excluded; Friday must not appear as an assignable beat day anywhere in the system.
12.5 Visit Outcomes (SO Visit Log)
Order Placed Closed Owner Absent Refused Competitor Only
12.6 P2 Activation Reason Codes
Closed Owner Absent Refusing Permanently Shut
12.7 Delivery Outcomes (DSR Challan)
Delivered Partially Delivered Closed Owner Absent Refused Wrong Outlet
12.8 Delivery Variance Reasons (Challan line item)
Outlet Refused Item Shortage — Pro-Rata Damaged in Transit Expiry Concern at Outlet Outlet Requested Reduction Other (requires text note)
12.9 PO Statuses
Draft Approved Issued Acknowledged Partially Received Closed Cancelled
12.10 GRN Item Conditions
Acceptable Damaged Near-Expiry Wrong Item Quantity Short
12.11 GRN Rejection Reasons
Expiry < 60 Days Damaged Packaging Quantity Mismatch Wrong SKU Delivered Non-Conforming Quality
12.12 GRN Handover Locations
Receiving Bay Other
12.13 Credit Terms (Vendor)
CAD (Cash Against Delivery) 15-Day 30-Day Advance
12.14 SKU Categories
Cosmetics Food General
12.15 Stock Cover Categories
Fast (minimum cover: 14 days) Medium (minimum cover: 10 days) Slow (minimum cover: 7 days)
12.16 Stock Ledger Transaction Types
GRN Dispatch Return Adjustment Rejected
12.17 Reconciliation Statuses
Pending Complete Discrepancy — Under Review Resolved Escalated
12.18 Debit Note Statuses
Open Resolved Credited
12.19 User Roles
SO DSR WH Manager SCM Manager Accounts Sales Head Business Head App Admin
12.20 Zones
Narayanganj Town Bandor Munshiganj All (for users with cross-zone access: Sales Head, Business Head, App Admin)
12.21 VLS Statuses
Generated Staged Checker Verified DSR Signed WH Countersigned Departed Returned Reconciled
12.22 Vehicle Condition Check Values
Fuel: OK | Low Tyres: OK | Defective Lights: OK | Defective
12.23 GPS Check-In Statuses
Pass (within configured radius) Fail (outside radius — blocked) Override (outside radius — SO confirmed with audit log)
12.24 Outlet Statuses
Active Inactive Permanently Closed
12.25 Order Statuses
Submitted Processing Dispatched Delivered Partially Delivered Cancelled
12.26 DSR Arrival / Departure Statuses
On Time Late
13. Open Questions
The following questions require explicit product and business decisions before engineering implementation can begin. Each question is listed with context and the implication if not resolved.
OQ-01: Who physically performs the checker role for VLS verification, and how is this managed in the system?
Context: Business Rule DS-01a requires that a "designated checker" — different from the picker — verifies staged goods against the VLS before sealing. The system must record the checker's user ID.
Decision needed: Is the checker a fixed role (a specific person per shift), or does the WH Manager designate a different person each day? If it varies daily, the WH Manager must assign the checker in the system before the picking session begins. If it is a fixed role, a permanent "Checker" user account must be created. This affects user role design and the permissions matrix.
Implication if unresolved: Engineering cannot build the checker assignment workflow correctly.
OQ-02: What is the exact mechanism for printing challans — does each DSR have a mobile printer, or is the challan a digital PDF shown to the outlet owner?
Context: Requirement DS-27 states the signed original challan must remain with the outlet. This implies a physical paper challan. However, no printer hardware has been specified.
Decision needed: (a) Will each DSR vehicle be equipped with a Bluetooth thermal printer for printing challans at the outlet? Or (b) will challans be digital — shown on DSR phone screen for outlet owner to "sign" via a touchscreen signature? Or (c) will challans be pre-printed at the warehouse against the VLS the night before?
Implication if unresolved: The DSR app architecture (specifically the challan generation flow) differs significantly depending on the answer. Option (a) requires Bluetooth printer SDK integration. Option (b) requires digital signature capture. Option (c) requires pre-print logic and a different reconciliation model.
OQ-03: What is the daily cash deposit process — is there a specific bank account, deposit time window, and authorization chain?
Context: AC-16 requires daily cash deposit to bank to be recorded and reconciled. Currently, the system captures this as a manual entry.
Decision needed: Who physically deposits cash (WH Manager, Accounts, or a runner)? What is the target deposit time? Is there a single bank account or multiple? Is there a minimum deposit amount that triggers a separate approval?
Implication if unresolved: The cash deposit workflow in the Accounts module cannot be finalized; the daily cash summary report structure depends on this.
OQ-04: How should the system handle a DSR who misses the 6:00 PM return deadline — what is the escalation protocol and what does the WH Manager do with the day's stock and cash if the DSR is unreachable?
Context: DS-19 requires WH Manager to record DSR return time. No formal protocol is defined for late or non-return.
Decision needed: Should the system auto-escalate to Sales Head and Business Head after a configurable late threshold (e.g., 30 minutes late)? Can the WH Manager close a DSR's day-end with "DSR Not Returned — Escalated" status? What happens to the stock and cash accounting when this state is triggered?
Implication if unresolved: The day-end reconciliation state machine cannot be fully defined; the WH Manager will have no clear system guidance in an emergency.
OQ-05: What is the exact formula and weighting used for per-SO target adjustment in TS-01 ("WH target ÷ 6, adjusted by route potential")?
Context: Monthly targets are distributed across 6 SOs, with an adjustment for "route potential." The BRD references this but does not define the formula precisely.
Decision needed: Is route potential based on: (a) weighted average drop size of outlets on the route, (b) historical order value per SO from prior months, (c) total P1 outlet count on the route, or (d) a combination? Who defines the weighting factor and can it change monthly?
Implication if unresolved: The target auto-calculation logic in TS-01 and TS-10 cannot be implemented; the system cannot generate SO-level targets from the WH-level target without this formula.
OQ-06: How should the system handle a situation where the SCM Manager role is unfilled or on leave — who acts as backup, and does the Business Head have temporary PO-raise access?
Context: The SCM Manager is now a first-class system role responsible for raising RFQs and POs. If this role is vacant (as noted, Warehouse In-Charge is currently vacant), there is a risk of procurement blockage.
Decision needed: Should the system support a "delegate" feature where Business Head can temporarily grant SCM Manager permissions to another user? Or should PO-raise access default to Business Head if no SCM Manager user is active?
Implication if unresolved: The system may block procurement if the SCM Manager account is not set up or the person is unavailable, with no formal bypass.
OQ-07: What is the policy for handling returns from outlets — specifically, what approval level is required (SO only, or WH Manager only, or either) and how quickly must a returned SKU be re-assessed before returning to sellable stock?
Context: DS-13 states returns require "manager/SO approval" but does not specify which manager or what the re-inspection process is for returned goods before they re-enter inventory.
Decision needed: (a) Can an SO approve a return from the field app, or must the WH Manager approve it at the warehouse? (b) Do returned goods go directly back to stock or to the "Return Product Store" first for condition assessment? (c) If re-assessment finds the goods are not sellable, does a Debit Note apply to the outlet or is it a write-off?
Implication if unresolved: The returns workflow in both the DSR app and the WH module cannot be fully implemented; the STOCK_LEDGER transaction type for returns is ambiguous.
OQ-08: What is the system behaviour at the exact order cut-off moment (8:00 PM) for orders that are in progress but not yet submitted?
Context: SA-14 states the system auto-closes order entry at 8:00 PM. However, an SO may be mid-entry at 7:59 PM.
Decision needed: If an SO has started entering an order (SKUs selected, quantities entered) but has not tapped "Submit" by 8:00 PM: (a) should the system auto-submit the in-progress order as-is, (b) should it discard it and notify the SO, or (c) should it save the draft locally but mark it as "After Cut-Off — Not Submitted" for supervisor review? Each option has different implications for data integrity and SO fairness.
Implication if unresolved: The order cut-off logic in the SO app cannot be finalized; there is a risk of revenue loss or SO disputes if not explicitly decided.
Document Control: PRD Version 1.0 | May 2026 | Product Owner: Head of P.S & A.S Based on: BRD v1.1 — Narayanganj Distribution Hub Engineering decisions made against this PRD require written acknowledgement from the Product Owner. Open Questions in Section 13 must be resolved before sprint planning for affected modules begins.
Last updated on