137 lines
3.0 KiB
Markdown
137 lines
3.0 KiB
Markdown
# 15 · BACKEND — Bundle Sales API
|
|
|
|
> **Authoritative for:** fixed-composition bundle sales, templates, posting, and print data.
|
|
> **Navigation:** start from `00-CORE.md`. This module follows the same repository/UoW/ETag/audit patterns as invoices and slips.
|
|
|
|
---
|
|
|
|
## 1. Concept
|
|
|
|
Bundle sales are a separate sales document family for fixed bundle compositions.
|
|
|
|
Rules:
|
|
- a bundle sale is created from a bundle template
|
|
- the bundle template defines fixed component stock lines
|
|
- posting consumes stock from the component items, not from a synthetic bundle SKU
|
|
- the bundle header carries the commercial sale value
|
|
- print views show both bundle summary and component breakdown
|
|
|
|
---
|
|
|
|
## 2. API
|
|
|
|
### `GET /api/v1/bundle-sales`
|
|
Query:
|
|
- `page`
|
|
- `pageSize`
|
|
- `q`
|
|
- `customerId`
|
|
- `warehouseId`
|
|
|
|
### `GET /api/v1/bundle-sales/{bundleSaleId}`
|
|
Returns the bundle sale header and all component lines.
|
|
|
|
### `GET /api/v1/bundle-sales/{bundleSaleId}/posting-check`
|
|
Validates component stock before posting.
|
|
|
|
### `POST /api/v1/bundle-sales`
|
|
Creates a draft bundle sale from a fixed bundle template.
|
|
|
|
### `PUT /api/v1/bundle-sales/{bundleSaleId}`
|
|
Updates a draft bundle sale. Requires `If-Match`.
|
|
|
|
### `POST /api/v1/bundle-sales/{bundleSaleId}/post`
|
|
Consumes stock from included component lines and marks the bundle as posted.
|
|
|
|
### `POST /api/v1/bundle-sales/{bundleSaleId}/cancel`
|
|
Cancels a draft bundle sale.
|
|
|
|
---
|
|
|
|
## 3. Template Rules
|
|
|
|
- bundle templates are fixed in composition
|
|
- each template line maps to one component stock item
|
|
- component quantities are expanded into the sale draft at creation time
|
|
- price override is allowed only when the caller is permitted by business rules
|
|
|
|
---
|
|
|
|
## 4. Data Model
|
|
|
|
### `BundleSaleTemplate`
|
|
- `BundleSaleTemplateId`
|
|
- `TemplateCode`
|
|
- `TemplateName`
|
|
- `Description`
|
|
- `Status`
|
|
- `CreatedAt`
|
|
- `UpdatedAt`
|
|
- `RowVersion`
|
|
|
|
### `BundleSaleTemplateLine`
|
|
- `BundleSaleTemplateLineId`
|
|
- `BundleSaleTemplateId`
|
|
- `ItemId`
|
|
- `UomId`
|
|
- `WarehouseId`
|
|
- `Qty`
|
|
- `UnitPrice`
|
|
- `IncludeInBundle`
|
|
- `SortOrder`
|
|
|
|
### `BundleSale`
|
|
- `BundleSaleId`
|
|
- `BundleNo`
|
|
- `BundleDate`
|
|
- `CustomerId`
|
|
- `CustomerSnapshotName`
|
|
- `WarehouseId`
|
|
- `CashierUserId`
|
|
- `BundleSaleTemplateId`
|
|
- `BundleName`
|
|
- `BundleCode`
|
|
- `Status`
|
|
- `ComponentSubtotal`
|
|
- `BundlePrice`
|
|
- `MarginAmount`
|
|
- `DiscountTotal`
|
|
- `TaxTotal`
|
|
- `GrandTotal`
|
|
- `CreatedAt`
|
|
- `UpdatedAt`
|
|
- `RowVersion`
|
|
|
|
### `BundleSaleLine`
|
|
- `BundleSaleLineId`
|
|
- `BundleSaleId`
|
|
- `ItemId`
|
|
- `Description`
|
|
- `Qty`
|
|
- `UomId`
|
|
- `WarehouseId`
|
|
- `UnitPrice`
|
|
- `LineTotal`
|
|
- `IncludeInBundle`
|
|
- `IsComponent`
|
|
- `ParentLineId`
|
|
- `RowVersion`
|
|
|
|
---
|
|
|
|
## 5. Posting
|
|
|
|
Posting behavior:
|
|
- validate each included component line has sufficient stock
|
|
- consume FIFO layers from the component items
|
|
- write stock ledger rows for each component
|
|
- mark the bundle as posted in the same transaction
|
|
|
|
---
|
|
|
|
## 6. Notes
|
|
|
|
- This module is intentionally separate from invoices and slips.
|
|
- Bundle sales are for fixed compositions only in this phase.
|
|
- Print views should mirror the existing sales document print behavior without the dashboard shell.
|