Files
Zumri-Backend/Documentation/API_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

2.3 KiB

Inventory and Merchandising API

All routes use the /api/v1 prefix. Admin routes require authentication and the named Phase 5 permission.

Inventory and warehouses

  • GET /admin/inventory (inventory.read)
  • GET /admin/inventory/:variantId (inventory.read)
  • GET /admin/inventory/ledger (inventory.read)
  • GET /admin/inventory/low-stock (inventory.read)
  • POST /admin/inventory/adjustments (inventory.adjust); send Idempotency-Key
  • POST /admin/inventory/transfers (inventory.transfer); send Idempotency-Key
  • GET /admin/warehouses (inventory.read)
  • POST /admin/warehouses, PATCH /admin/warehouses/:id (inventory.warehouses.manage)
  • GET /availability/:variantId returns only IN_STOCK, LOW_STOCK, or OUT_OF_STOCK and availableForSale; it never exposes warehouse quantities.

Inventory mutations are internal service operations: reserveStock, releaseReservation, and consumeReservation. Reservations default to INVENTORY_RESERVATION_TTL_MINUTES=15. The minute reconciliation job expires bounded batches of 100; the database remains authoritative.

Business pricing

  • GET /admin/business-pricing (pricing.business.read)
  • POST /admin/business-pricing (pricing.business.manage)

Rules support exactly one tier or customer audience, effective dates, MOQ, and non-overlapping volume ranges. Precedence is customer override, business tier, then retail. Money is stored as DECIMAL and calculated using integer-scaled helpers.

Promotions and coupons

  • GET|POST /admin/promotions (promotions.read / promotions.manage)
  • GET|POST /admin/coupons (promotions.read / promotions.manage)

The quote boundary resolves retail/business base price, then the highest-priority eligible automatic promotion, then a coupon only when stacking permits. Discounts floor at zero. Coupon codes are canonical uppercase. Usage redemption is intentionally deferred until orders exist.

Banners

  • GET /banners?placement=&locale= returns active, scheduled, audience-eligible localized banners.
  • GET|POST /admin/banners requires merchandising.banners.manage.

Banner media reuses Upload records and only returns safe upload identifiers, never bucket/object keys.

Not implemented

Cart, checkout, orders, coupon redemption, shipping, tax, payment, and delivery remain outside Phase 5.