Update docs for procurement and shop PO processes, including GRN rework functionality
This commit is contained in:
@@ -97,11 +97,18 @@ PurchaseOrderItem
|
||||
├── IsCancelled (bool) — true once this line is individually cancelled, default false
|
||||
```
|
||||
|
||||
> **Update (GRN rework):** a goods receipt no longer requires a PO — see "Direct goods receipt" and
|
||||
> the costing / free-issue / tax additions in
|
||||
> [refactor_docs/grn_costing_and_taxes.md](./refactor_docs/grn_costing_and_taxes.md). The tree
|
||||
> below shows the original design plus those changes, marked *(later)*.
|
||||
|
||||
### GoodsReceipt
|
||||
```
|
||||
GoodsReceipt
|
||||
├── Id (Guid) — PK, from Template
|
||||
├── FK_PurchaseOrderId (Guid) — required
|
||||
├── FK_PurchaseOrderId (Guid?) — nullable *(later)*: null = direct receipt (no PO)
|
||||
├── FK_SupplierId (Guid?) — *(later)* set on a direct receipt; a PO receipt reaches the supplier via the PO
|
||||
├── DiscountPercent, VatPercent, NbtPercent (decimal 5,2) — *(later)* GRN-wide defaults for lines
|
||||
├── FK_ReceivedByUserId (Guid) — required
|
||||
├── FK_WarehouseId (Guid) — required; the warehouse the accepted quantities are received into.
|
||||
│ Not anticipated in the original design — added because
|
||||
@@ -116,9 +123,13 @@ GoodsReceipt
|
||||
GoodsReceiptItem
|
||||
├── Id (Guid) — PK, from Template
|
||||
├── FK_GoodsReceiptId (Guid) — required
|
||||
├── FK_PurchaseOrderItemId (Guid) — required, ties the receipt line back to its ordered line
|
||||
├── FK_PurchaseOrderItemId (Guid?) — ties the receipt line back to its ordered line; null on a direct receipt
|
||||
├── FK_ItemId (Guid?) — *(later)* the item, on a direct receipt line
|
||||
├── AcceptedQuantity (int) — added to warehouse stock
|
||||
├── RejectedQuantity (int) — damaged/short at receipt, default 0, not added to stock
|
||||
├── FreeQuantity (int) — *(later)* free-issue units: added to stock, not costed, not counted against the PO
|
||||
├── UnitCost (decimal 18,2) — *(later)* cost per unit; PO receipts default to the PO line's UnitCost
|
||||
├── DiscountPercent, NbtPercent, VatPercent (decimal 5,2) — *(later)* per-line rates
|
||||
```
|
||||
|
||||
### PurchaseReturn
|
||||
@@ -154,11 +165,16 @@ gives one receiving warehouse per PO in practice; see Open Questions for the mul
|
||||
|
||||
## Migrations
|
||||
|
||||
One migration, applied:
|
||||
1. **AddProcurement** (`20260824110925_AddProcurement`) — created `PurchaseOrders`,
|
||||
`PurchaseOrderItems`, `GoodsReceipts`, `GoodsReceiptItems`, `PurchaseReturns`,
|
||||
`PurchaseReturnItems`, with FKs to `Suppliers`/`Items`/`Warehouses` and indexes on every FK
|
||||
column. Applied via `dotnet ef database update`.
|
||||
2. **AddDirectGoodsReceipt** (`20261006070042`) — made the PO links nullable and added the supplier /
|
||||
item links for direct receipts.
|
||||
3. **AddGrnPricing**, **AddGrnFreeQuantity**, **AddGrnNbt** (`20261007…`, `20261008…`) — GRN costing,
|
||||
free issues and NBT. Pricing and free quantity are applied; **AddGrnNbt was still pending** when
|
||||
last checked, and GRN reads/writes fail until it is applied — see
|
||||
[refactor_docs/grn_costing_and_taxes.md](./refactor_docs/grn_costing_and_taxes.md) §7.
|
||||
|
||||
---
|
||||
|
||||
@@ -182,11 +198,17 @@ One migration, applied:
|
||||
| `resolveInvoiceVariance(poId, variance, resolution)` | `POST /api/purchase-orders/{id}/resolve-variance` |
|
||||
|
||||
### Goods Receipt (`Features/Grn`)
|
||||
> A PO is **not mandatory** for a goods receipt: `POST /api/goods-receipts/direct` receives stock
|
||||
> with no PO (no ordered-quantity limit, no PO status, no purchase returns / invoice matching for
|
||||
> it). See [refactor_docs/grn_costing_and_taxes.md](./refactor_docs/grn_costing_and_taxes.md) §1 for
|
||||
> when to use which.
|
||||
| Function reference | Endpoint |
|
||||
|---|---|
|
||||
| `createGoodsReceipt(poId, warehouseId, items[])` | `POST /api/purchase-orders/{id}/goods-receipts` |
|
||||
| `createGoodsReceipt(poId, warehouseId, items[])` | `POST /api/purchase-orders/{id}/goods-receipts` (also `POST /api/goods-receipts` with `purchaseOrderId` in the body) |
|
||||
| `createDirectGoodsReceipt(warehouseId, supplierId?, items[])` | `POST /api/goods-receipts/direct` |
|
||||
| `getGoodsReceipt(grnId)` | `GET /api/goods-receipts/{id}` |
|
||||
| `listGoodsReceipts(poId)` | `GET /api/purchase-orders/{id}/goods-receipts` |
|
||||
| `listGoodsReceipts(page)` | `GET /api/goods-receipts` |
|
||||
|
||||
### Purchase Returns (`Features/PurchaseReturn`)
|
||||
| Function reference | Endpoint |
|
||||
@@ -215,8 +237,12 @@ One migration, applied:
|
||||
{ "purchaseOrderItemId": "...", "acceptedQuantity": 95, "rejectedQuantity": 5 }
|
||||
] }
|
||||
```
|
||||
`rejectedQuantity` defaults to 0 if omitted; only `acceptedQuantity` is credited to
|
||||
`StockBalance`.
|
||||
`rejectedQuantity` defaults to 0 if omitted. `acceptedQuantity` **plus `freeQuantity`** (free-issue
|
||||
units, default 0) is credited to `StockBalance`; only accepted units are costed and only accepted
|
||||
units advance the PO line's `ReceivedQuantity`. Optional pricing fields (`unitCost`,
|
||||
`discountPercent`, `vatPercent`, `nbtPercent` per line; `discountPercent`, `vatPercent`,
|
||||
`nbtPercent` for the whole GRN) are described in
|
||||
[refactor_docs/grn_costing_and_taxes.md](./refactor_docs/grn_costing_and_taxes.md).
|
||||
|
||||
### POST `/api/purchase-orders/{id}/returns`
|
||||
```json
|
||||
@@ -297,9 +323,10 @@ above) per 14's existing target design.
|
||||
- Where should cost-vs-sale-price margin reporting (`PurchaseOrderItem.UnitCost` vs
|
||||
`PriceListItem.Price`/`Item.SalePrice`) live — a read-only endpoint/report in this step, or a
|
||||
later analytics/reporting step? Not a blocker for the core PO→GRN flow.
|
||||
- Landed cost (freight, duty, taxes allocated onto received stock) is out of scope —
|
||||
`PurchaseOrderItem.UnitCost` is the only cost basis captured. Defer unless accurate per-unit cost
|
||||
is needed sooner.
|
||||
- Landed cost (freight, duty allocated onto received stock) is out of scope. The GRN now records
|
||||
unit cost, discount, NBT and VAT per line (see
|
||||
[refactor_docs/grn_costing_and_taxes.md](./refactor_docs/grn_costing_and_taxes.md)), but these do
|
||||
not feed stock valuation or `Item.CostPrice`, and the PO itself carries no discount or tax.
|
||||
- Reorder triggers (`setReorderPoint`/`sendLowStockAlert`) are not wired to procurement — restocking
|
||||
stays fully manual until Notifications & Alerts exists.
|
||||
- `createPurchaseReturn` assumes a single receiving warehouse per PO (uses the most recent
|
||||
|
||||
Reference in New Issue
Block a user