Files
Zumri-Backend/Documentation/PHASE_5_INVENTORY_MERCHANDISING.md
T
Sathira Sri Sathara 5643d89236 feat: implement business pricing service and money utilities
- Added `businessPricing.service.js` to handle business customer pricing logic.
- Introduced `money.js` for money parsing, formatting, and calculations.
- Created `pricing.service.js` to manage variant quoting and promotion application.
- Updated validation schemas in `catalogue.schemas.js` and `inventoryMerchandising.schemas.js` for new pricing and inventory features.
- Implemented cron job for inventory reservation expiry in `inventoryReservationExpiry.cron.js`.
- Created database migrations for catalogue and inventory structures.
- Added unit tests for catalogue localization, validation, and inventory merchandising functionalities.
2026-09-03 19:25:13 +05:30

4.3 KiB

ZUMRI Phase 5 Inventory and Merchandising

Objective

Provide authoritative multi-warehouse stock, reservation primitives, wholesale pricing, price quotes, promotions, coupons, and scheduled localized banners for Phase 6 consumers.

Existing Components Reused

ProductVariant, BusinessCustomer, Upload, authorization middleware, audit queue, cron bootstrap, Zod, Sequelize, and catalogue localization are reused.

Inventory Architecture

Catalogue never stores stock. InventoryBalance is authoritative per warehouse/variant; availability is onHand - reserved. All writes pass through one service and append an immutable ledger event.

Warehouses

Multiple active/inactive warehouses and a transactionally selected default are supported. Default warehouse selection is deterministic.

Inventory Balance

Quantities are integers. Service invariants prevent negative stock and reserved > onHand.

Inventory Ledger

Every adjustment, reservation lifecycle event, and transfer has a unique event ID. There is no ledger update API.

Stock Adjustments

Adjustments lock balances, enforce invariants, append a ledger row, support HTTP idempotency keys, and emit audit events.

Transfers

Synchronous transfers lock warehouse IDs in sorted order, then create paired OUT/IN ledger rows.

Reservation Architecture

Unique reservation keys make reserve/release/consume idempotent. Generic references avoid premature cart/order coupling.

Reservation Concurrency

MySQL transactions and row-level FOR UPDATE locks serialize competitors for final units. Real multi-connection InnoDB validation remains a staging prerequisite.

Reservation Expiry

A no-overlap minute cron reconciles up to 100 expired ACTIVE records per run; each record is locked and the database state is authoritative.

Availability Projection

Public responses expose status and boolean sale availability only. Out-of-stock catalogue items remain visible.

Low Stock

Low stock is centrally defined as available quantity less than or equal to the configured balance threshold.

Business Pricing

Wholesale rules remain separate from retail base price and are limited to approved ACTIVE business accounts.

Business Tiers

Business customers may reference an active tier; customer-specific negotiated rules are also supported.

MOQ

MOQ belongs to a wholesale rule and never applies to retail fallback.

Volume Pricing

Integer, non-overlapping ranges select the greatest eligible minimum quantity; final maximum may be null.

Pricing Precedence

Retail -> eligible customer override (preferred over tier) -> volume tier -> highest-priority automatic promotion -> permitted coupon. Effective price floors at zero.

Promotions

Percentage, fixed amount, and fixed price campaigns support dates, priority, minimum quantity, audiences, stacking, and normalized targets.

Coupons

Codes are uppercase and validated against coupon/promotion state and schedule. Redemption counters are not fabricated before orders.

Banners

Placements are string-configurable. Status, schedule, sort order, audience, and optional business tier drive projection.

Localization

Banner translations use en, si, and ta, with requested locale then English fallback.

Permissions

Inventory read/adjust/transfer/reservation/warehouse, business pricing read/manage, promotion read/manage, and banner manage permissions were added.

Audit Events

Warehouse, adjustment, transfer, business-price, promotion, coupon, and banner mutations enqueue sanitized Phase 2 audit activities.

Database Changes

The forward-only 20260903050000 migration adds 13 domain tables and the BusinessCustomer tier reference. Earlier migrations are unchanged.

Tests

Unit coverage verifies decimal precision, zero floor, availability states, strict input, coupon normalization, and permission boundaries. Existing regression tests remain green.

Remaining Known Issues

Patch endpoints for promotion/coupon/banner/business pricing and real infrastructure integration tests remain follow-up hardening. No production migration was run.

Phase 6 Prerequisites

Run legacy-data prechecks and migration on staging; validate constraints and concurrent reservations using two real InnoDB connections; verify cron in a multi-instance deployment; seed permissions and warehouse data.