Refactor production and stock tests to remove UOM dependency

- Updated production.spec.ts, stock-adjustments.spec.ts, and stock-transfers.spec.ts to eliminate UOM references in API seeder and test cases.
- Adjusted ApiSeeder methods to remove UOM parameters from stock receiving and production template creation.
- Revised documentation to reflect changes in UOM handling, emphasizing that stock is counted in base UOM only.
- Introduced new enums for MeasureUnit and StageQtyUnit to clarify content size and stage input quantities.
- Implemented ItemContent service to validate and normalize content sizes.
- Updated smoke tests to validate production stage inputs expressed in content units, ensuring correct consumption calculations.
- Modified frontend UOM label handling to reflect the removal of per-line UOMs in document lines.
This commit is contained in:
2026-08-11 11:32:40 +05:30
parent d37824cecc
commit 15ddac178c
108 changed files with 1221 additions and 987 deletions
+11 -9
View File
@@ -118,14 +118,14 @@ export class ApiSeeder {
}
/** Direct (no-PO) GRN, confirmed immediately, so the item has on-hand stock to test against. */
async receiveStock(opts: { warehouseId: number; vendorId: number; itemId: number; uomId: number; qty: number; unitCost: number }) {
async receiveStock(opts: { warehouseId: number; vendorId: number; itemId: number; qty: number; unitCost: number }) {
const grn = await this.post<{ grnId: number }>("/grns", {
vendorId: opts.vendorId,
warehouseId: opts.warehouseId,
lines: [
{
itemId: opts.itemId,
uomId: opts.uomId,
qty: opts.qty,
unitCost: opts.unitCost,
discountPct: 0,
@@ -139,14 +139,14 @@ export class ApiSeeder {
}
/** Direct GRN with the line held for inspection, confirmed - gives the detail page a line with Release/Reject actions. */
async receiveStockOnHold(opts: { warehouseId: number; vendorId: number; itemId: number; uomId: number; qty: number; unitCost: number }) {
async receiveStockOnHold(opts: { warehouseId: number; vendorId: number; itemId: number; qty: number; unitCost: number }) {
const grn = await this.post<{ grnId: number; lines: { grnLineId: number }[] }>("/grns", {
vendorId: opts.vendorId,
warehouseId: opts.warehouseId,
lines: [
{
itemId: opts.itemId,
uomId: opts.uomId,
qty: opts.qty,
unitCost: opts.unitCost,
discountPct: 0,
@@ -159,13 +159,13 @@ export class ApiSeeder {
return grn
}
async createPurchaseOrder(opts: { vendorId: number; warehouseId: number; itemId: number; uomId: number; qty: number; unitPrice: number }) {
async createPurchaseOrder(opts: { vendorId: number; warehouseId: number; itemId: number; qty: number; unitPrice: number }) {
return this.post<{ poId: number; docNo: string }>("/purchase-orders", {
vendorId: opts.vendorId,
lines: [
{
itemId: opts.itemId,
uomId: opts.uomId,
warehouseId: opts.warehouseId,
qty: opts.qty,
unitPrice: opts.unitPrice,
@@ -181,7 +181,7 @@ export class ApiSeeder {
* smallest graph ProductionGraphValidator accepts (Backend/ERPCore/Services/Production/
* ProductionGraphValidator.cs: exactly one terminal, terminal has exactly one item output).
*/
async createSingleStageTemplate(opts: { rawItemId: number; finishedItemId: number; uomId: number }) {
async createSingleStageTemplate(opts: { rawItemId: number; finishedItemId: number }) {
const suffix = uniqueSuffix()
return this.post<{ templateId: number; code: string; name: string }>("/production-templates", {
code: `E2E-TPL-${suffix}`,
@@ -194,8 +194,10 @@ export class ApiSeeder {
posX: 0,
posY: 0,
fieldDefs: [],
inputs: [{ source: "Stock", itemId: opts.rawItemId, uomId: opts.uomId, qtyPerBatch: 1 }],
outputs: [{ key: "out-1", itemId: opts.finishedItemId, name: "Finished good", uomId: opts.uomId, qtyPerBatch: 1 }],
// No unit on either row: an input is a pack count unless it says otherwise, and the
// terminal output takes its unit from the finished item.
inputs: [{ source: "Stock", itemId: opts.rawItemId, qtyPerBatch: 1 }],
outputs: [{ key: "out-1", itemId: opts.finishedItemId, name: "Finished good", qtyPerBatch: 1 }],
},
],
edges: [],