@happyvertical/smrt-manufacturing 0.53.4 → 0.53.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +45 -6
- package/README.md +161 -3
- package/dist/collections/AssemblyCollection.d.ts +15 -0
- package/dist/collections/AssemblyCollection.d.ts.map +1 -0
- package/dist/collections/OperationCollection.d.ts +20 -0
- package/dist/collections/OperationCollection.d.ts.map +1 -0
- package/dist/collections/RoutingStepCollection.d.ts +15 -0
- package/dist/collections/RoutingStepCollection.d.ts.map +1 -0
- package/dist/collections/index.d.ts +3 -0
- package/dist/collections/index.d.ts.map +1 -1
- package/dist/index.d.ts +13 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +756 -29
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +1248 -128
- package/dist/models/Assembly.d.ts +62 -0
- package/dist/models/Assembly.d.ts.map +1 -0
- package/dist/models/BillOfMaterials.d.ts +12 -4
- package/dist/models/BillOfMaterials.d.ts.map +1 -1
- package/dist/models/BomLine.d.ts +11 -5
- package/dist/models/BomLine.d.ts.map +1 -1
- package/dist/models/Operation.d.ts +59 -0
- package/dist/models/Operation.d.ts.map +1 -0
- package/dist/models/RoutingStep.d.ts +46 -0
- package/dist/models/RoutingStep.d.ts.map +1 -0
- package/dist/models/index.d.ts +3 -0
- package/dist/models/index.d.ts.map +1 -1
- package/dist/operation-types.d.ts +99 -0
- package/dist/operation-types.d.ts.map +1 -0
- package/dist/services/AssemblyService.d.ts +217 -0
- package/dist/services/AssemblyService.d.ts.map +1 -0
- package/dist/services/BomService.d.ts +25 -1
- package/dist/services/BomService.d.ts.map +1 -1
- package/dist/services/OperationService.d.ts +48 -0
- package/dist/services/OperationService.d.ts.map +1 -0
- package/dist/services/RoutingService.d.ts +50 -0
- package/dist/services/RoutingService.d.ts.map +1 -0
- package/dist/services/index.d.ts +3 -0
- package/dist/services/index.d.ts.map +1 -1
- package/dist/smrt-knowledge.json +1138 -81
- package/dist/svelte/components/AssemblyForm.svelte +69 -0
- package/dist/svelte/components/AssemblyForm.svelte.d.ts +38 -0
- package/dist/svelte/components/AssemblyForm.svelte.d.ts.map +1 -0
- package/dist/svelte/components/AssemblyList.svelte +229 -0
- package/dist/svelte/components/AssemblyList.svelte.d.ts +28 -0
- package/dist/svelte/components/AssemblyList.svelte.d.ts.map +1 -0
- package/dist/svelte/components/BomEditor.svelte +575 -0
- package/dist/svelte/components/BomEditor.svelte.d.ts +29 -0
- package/dist/svelte/components/BomEditor.svelte.d.ts.map +1 -0
- package/dist/svelte/components/BomStructureTree.svelte +164 -0
- package/dist/svelte/components/BomStructureTree.svelte.d.ts +16 -0
- package/dist/svelte/components/BomStructureTree.svelte.d.ts.map +1 -0
- package/dist/svelte/components/OperationForm.svelte +258 -0
- package/dist/svelte/components/OperationForm.svelte.d.ts +17 -0
- package/dist/svelte/components/OperationForm.svelte.d.ts.map +1 -0
- package/dist/svelte/components/OperationList.svelte +170 -0
- package/dist/svelte/components/OperationList.svelte.d.ts +17 -0
- package/dist/svelte/components/OperationList.svelte.d.ts.map +1 -0
- package/dist/svelte/i18n.d.ts +87 -0
- package/dist/svelte/i18n.d.ts.map +1 -0
- package/dist/svelte/i18n.js +87 -0
- package/dist/svelte/index.d.ts +28 -0
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +29 -0
- package/dist/svelte/types.d.ts +170 -0
- package/dist/svelte/types.d.ts.map +1 -0
- package/dist/svelte/types.js +126 -0
- package/dist/ui.d.ts +17 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +72 -0
- package/dist/ui.js.map +1 -0
- package/package.json +39 -10
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Assembly — the product that is made, the counterpart to `Material` (the
|
|
3
|
+
* product that is consumed).
|
|
4
|
+
*
|
|
5
|
+
* A single-table-inheritance subtype of `@happyvertical/smrt-products`
|
|
6
|
+
* `Product`: assembly rows live in the shared `products` table with
|
|
7
|
+
* `productType: 'assembly'` and `_meta_type:
|
|
8
|
+
* '@happyvertical/smrt-manufacturing:Assembly'`. Its own fields are
|
|
9
|
+
* ordinary columns that this package adds to that table.
|
|
10
|
+
*
|
|
11
|
+
* Everything else comes from a neighbour and is deliberately not repeated
|
|
12
|
+
* here:
|
|
13
|
+
*
|
|
14
|
+
* - name, description, price, category and tags from `Product`;
|
|
15
|
+
* - part number, barcode and stock from its `Sku` (`smrt-products`) and the
|
|
16
|
+
* stock levels in `smrt-inventory`;
|
|
17
|
+
* - what it is made of from its {@link BillOfMaterials} and {@link BomLine}s;
|
|
18
|
+
* - specs, plans and drawings from `ProductAsset` links.
|
|
19
|
+
*
|
|
20
|
+
* **Nesting lives in the bill, not on the assembly.** A sub-assembly is a
|
|
21
|
+
* bill line whose component SKU belongs to another `Assembly`; there is no
|
|
22
|
+
* children list to keep in sync. Use {@link AssemblyService.resolveComponent}
|
|
23
|
+
* to tell a sub-assembly from a material or a bought item.
|
|
24
|
+
*
|
|
25
|
+
* @packageDocumentation
|
|
26
|
+
*/
|
|
27
|
+
import { Product, type ProductOptions, ProductType } from '@happyvertical/smrt-products/models';
|
|
28
|
+
/**
|
|
29
|
+
* Options accepted by the {@link Assembly} constructor.
|
|
30
|
+
*/
|
|
31
|
+
export interface AssemblyOptions extends ProductOptions {
|
|
32
|
+
estimatedLabourMinutes?: number;
|
|
33
|
+
defaultOperationId?: string | null;
|
|
34
|
+
partReference?: string;
|
|
35
|
+
}
|
|
36
|
+
export declare class Assembly extends Product {
|
|
37
|
+
productType: ProductType;
|
|
38
|
+
/**
|
|
39
|
+
* Labour to build one unit, in whole minutes. A planning estimate until
|
|
40
|
+
* routing steps (smrt#3445) provide labour per operation; `0` means not
|
|
41
|
+
* estimated.
|
|
42
|
+
*/
|
|
43
|
+
estimatedLabourMinutes: number;
|
|
44
|
+
/**
|
|
45
|
+
* The {@link Operation} that work on this assembly is booked to by
|
|
46
|
+
* default, or `null` for none. `RESTRICT`, like `RoutingStep.operationId`:
|
|
47
|
+
* operations are retired, never deleted.
|
|
48
|
+
*/
|
|
49
|
+
defaultOperationId: string | null;
|
|
50
|
+
/**
|
|
51
|
+
* The organization's own drawing or part number for this assembly,
|
|
52
|
+
* alongside (not instead of) the SKU code.
|
|
53
|
+
*/
|
|
54
|
+
partReference: string;
|
|
55
|
+
constructor(options?: AssemblyOptions);
|
|
56
|
+
/**
|
|
57
|
+
* Refuses a labour estimate that is not a whole number of minutes of zero
|
|
58
|
+
* or more, on every save (generated REST and collection writes included).
|
|
59
|
+
*/
|
|
60
|
+
protected validateBeforeSave(): Promise<void>;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=Assembly.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Assembly.d.ts","sourceRoot":"","sources":["../../src/models/Assembly.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAQH,OAAO,EACL,OAAO,EACP,KAAK,cAAc,EACnB,WAAW,EACZ,MAAM,qCAAqC,CAAC;AAI7C;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACrD,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAOD,qBAUa,QAAS,SAAQ,OAAO;IAC1B,WAAW,EAAE,WAAW,CAAwB;IAEzD;;;;OAIG;IAEH,sBAAsB,EAAE,MAAM,CAAK;IAEnC;;;;OAIG;IAEH,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEzC;;;OAGG;IAEH,aAAa,EAAE,MAAM,CAAM;gBAEf,OAAO,GAAE,eAAoB;IAUzC;;;OAGG;cACsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;CAW7D"}
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
* other vertical that builds finished goods from components.
|
|
13
13
|
*
|
|
14
14
|
* Cross-package references (`productId`) are plain string ids — never
|
|
15
|
-
* `@foreignKey()` — so
|
|
16
|
-
*
|
|
15
|
+
* `@foreignKey()` — so the schema does not couple to the catalog package's
|
|
16
|
+
* table layout. The product is usually an `Assembly`.
|
|
17
17
|
*
|
|
18
18
|
* @packageDocumentation
|
|
19
19
|
*/
|
|
@@ -37,8 +37,8 @@ export declare class BillOfMaterials extends SmrtObject {
|
|
|
37
37
|
/**
|
|
38
38
|
* Plain string reference to the upstream product this BOM produces.
|
|
39
39
|
* Typically a `Product.id` (or any STI subtype thereof) from
|
|
40
|
-
* `@happyvertical/smrt-products`. Cross-package
|
|
41
|
-
* a `@foreignKey()
|
|
40
|
+
* `@happyvertical/smrt-products`, usually an `Assembly`. Cross-package
|
|
41
|
+
* id, intentionally not a `@foreignKey()`.
|
|
42
42
|
*/
|
|
43
43
|
productId: string;
|
|
44
44
|
/**
|
|
@@ -74,5 +74,13 @@ export declare class BillOfMaterials extends SmrtObject {
|
|
|
74
74
|
*/
|
|
75
75
|
currency: string;
|
|
76
76
|
constructor(options?: BillOfMaterialsOptions);
|
|
77
|
+
/**
|
|
78
|
+
* Refuses saving the bill as `active` when one of its lines would make
|
|
79
|
+
* its product contain itself, directly or through sub-assemblies' active
|
|
80
|
+
* bills, with a `BomCycleError` naming the path. Draft and superseded
|
|
81
|
+
* bills are not part of the structure and are not checked here (their
|
|
82
|
+
* lines are checked as they are saved).
|
|
83
|
+
*/
|
|
84
|
+
protected validateBeforeSave(): Promise<void>;
|
|
77
85
|
}
|
|
78
86
|
//# sourceMappingURL=BillOfMaterials.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BillOfMaterials.d.ts","sourceRoot":"","sources":["../../src/models/BillOfMaterials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAEL,UAAU,EACV,KAAK,iBAAiB,EAEvB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,sBAAuB,SAAQ,iBAAiB;IAC/D,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAAC;IACrC,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAUa,eAAgB,SAAQ,UAAU;IAC7C,6DAA6D;IAE7D,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B;;;;;OAKG;IAEH,SAAS,EAAE,MAAM,CAAM;IAEvB;;;;;OAKG;IAEH,OAAO,EAAE,MAAM,CAAK;IAEpB;;;;OAIG;IACH,aAAa,EAAE,IAAI,GAAG,IAAI,CAAQ;IAElC;;;;;;OAMG;IAEH,MAAM,EAAE,SAAS,CAAW;IAE5B;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAM;IAEnB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAS;gBAEb,OAAO,GAAE,sBAA2B;
|
|
1
|
+
{"version":3,"file":"BillOfMaterials.d.ts","sourceRoot":"","sources":["../../src/models/BillOfMaterials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAEL,UAAU,EACV,KAAK,iBAAiB,EAEvB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,sBAAuB,SAAQ,iBAAiB;IAC/D,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAAC;IACrC,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAUa,eAAgB,SAAQ,UAAU;IAC7C,6DAA6D;IAE7D,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B;;;;;OAKG;IAEH,SAAS,EAAE,MAAM,CAAM;IAEvB;;;;;OAKG;IAEH,OAAO,EAAE,MAAM,CAAK;IAEpB;;;;OAIG;IACH,aAAa,EAAE,IAAI,GAAG,IAAI,CAAQ;IAElC;;;;;;OAMG;IAEH,MAAM,EAAE,SAAS,CAAW;IAE5B;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAM;IAEnB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAS;gBAEb,OAAO,GAAE,sBAA2B;IAkBhD;;;;;;OAMG;cACsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ7D"}
|
package/dist/models/BomLine.d.ts
CHANGED
|
@@ -9,11 +9,10 @@
|
|
|
9
9
|
* material consumed but not incorporated into a finished unit.
|
|
10
10
|
*
|
|
11
11
|
* Cross-package references (`componentSkuId`) are plain string ids — never
|
|
12
|
-
* `@foreignKey()
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* always travel together.
|
|
12
|
+
* `@foreignKey()`. The `Sku` model lives in `@happyvertical/smrt-products`
|
|
13
|
+
* and `@happyvertical/smrt-inventory` holds the stock levels and movements
|
|
14
|
+
* addressed by the id. When the SKU belongs to an `Assembly`, the line is a
|
|
15
|
+
* sub-assembly: `AssemblyService.resolveComponent` says which.
|
|
17
16
|
*
|
|
18
17
|
* @packageDocumentation
|
|
19
18
|
*/
|
|
@@ -84,5 +83,12 @@ export declare class BomLine extends SmrtObject {
|
|
|
84
83
|
* `effectiveQty = qtyPerUnit * (1 + wastePercent / 100)`
|
|
85
84
|
*/
|
|
86
85
|
effectiveQtyPerUnit(): number;
|
|
86
|
+
/**
|
|
87
|
+
* Refuses a line that would make its bill's product contain itself,
|
|
88
|
+
* directly or through sub-assemblies' active bills, with a
|
|
89
|
+
* `BomCycleError` naming the path. Runs on every save, so the generated
|
|
90
|
+
* REST `create`/`update` routes refuse it too.
|
|
91
|
+
*/
|
|
92
|
+
protected validateBeforeSave(): Promise<void>;
|
|
87
93
|
}
|
|
88
94
|
//# sourceMappingURL=BomLine.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BomLine.d.ts","sourceRoot":"","sources":["../../src/models/BomLine.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"BomLine.d.ts","sourceRoot":"","sources":["../../src/models/BomLine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAEL,UAAU,EACV,KAAK,iBAAiB,EAEvB,MAAM,0BAA0B,CAAC;AAGlC;;GAEG;AACH,MAAM,WAAW,cAAe,SAAQ,iBAAiB;IACvD,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAaa,OAAQ,SAAQ,UAAU;IACrC,8DAA8D;IAE9D,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B;;;;;;OAMG;IAEH,KAAK,EAAE,MAAM,CAAM;IAEnB;;;;;;OAMG;IAEH,cAAc,EAAE,MAAM,CAAM;IAE5B;;;;OAIG;IAEH,UAAU,EAAE,MAAM,CAAO;IAEzB;;;;;;OAMG;IACH,GAAG,EAAE,MAAM,CAAU;IAErB;;;;;;OAMG;IAEH,YAAY,EAAE,MAAM,CAAO;IAE3B;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAM;gBAEP,OAAO,GAAE,cAAmB;IAaxC;;;;;OAKG;IACH,mBAAmB,IAAI,MAAM;IAM7B;;;;;OAKG;cACsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;CAO7D"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Operation — one kind of work done to build something: cut, weld, assemble,
|
|
3
|
+
* inspect, bake, pack. A managed list per tenant that routing steps point at.
|
|
4
|
+
*
|
|
5
|
+
* Retiring an operation (`isActive = false`) keeps it on every routing and
|
|
6
|
+
* history that already names it and takes it out of pickers; an operation is
|
|
7
|
+
* never deleted. Time recorded against an operation is not modelled here — it
|
|
8
|
+
* stays in `@happyvertical/smrt-timesheets` or the application.
|
|
9
|
+
*
|
|
10
|
+
* Strictly industry-neutral.
|
|
11
|
+
*
|
|
12
|
+
* @packageDocumentation
|
|
13
|
+
*/
|
|
14
|
+
import { SmrtObject, type SmrtObjectOptions } from '@happyvertical/smrt-core';
|
|
15
|
+
/**
|
|
16
|
+
* Options accepted by the {@link Operation} constructor.
|
|
17
|
+
*/
|
|
18
|
+
export interface OperationOptions extends SmrtObjectOptions {
|
|
19
|
+
tenantId?: string | null;
|
|
20
|
+
code?: string;
|
|
21
|
+
name?: string;
|
|
22
|
+
category?: string;
|
|
23
|
+
isActive?: boolean;
|
|
24
|
+
requiredQualificationId?: string | null;
|
|
25
|
+
}
|
|
26
|
+
export declare class Operation extends SmrtObject {
|
|
27
|
+
/** Tenant scope. `null` means the operation is a global record. */
|
|
28
|
+
tenantId: string | null;
|
|
29
|
+
/**
|
|
30
|
+
* Short stable code, unique per tenant (`CUT`, `WELD`). Treated as the
|
|
31
|
+
* operation's identity by {@link OperationService}: it is set when the
|
|
32
|
+
* operation is defined and is not changed afterwards; rename the `name`.
|
|
33
|
+
*/
|
|
34
|
+
code: string;
|
|
35
|
+
/** Human-readable name shown in lists and pickers. */
|
|
36
|
+
name: string;
|
|
37
|
+
/**
|
|
38
|
+
* Free-text grouping for lists (`fabrication`, `finishing`, `quality`).
|
|
39
|
+
* Empty when the operation is not grouped.
|
|
40
|
+
*/
|
|
41
|
+
category: string;
|
|
42
|
+
/**
|
|
43
|
+
* `false` once the operation is retired. A retired operation stays on the
|
|
44
|
+
* routings and history that name it and is left out of pickers.
|
|
45
|
+
*/
|
|
46
|
+
isActive: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Optional id of the qualification definition a worker needs to start this
|
|
49
|
+
* operation: a `Qualification` from `@happyvertical/smrt-human-resources`.
|
|
50
|
+
* Declared as a cross-package reference (metadata only: this package takes no
|
|
51
|
+
* dependency on it and does not validate the id); an application reads it to
|
|
52
|
+
* decide who may start the operation. `null` when none is required.
|
|
53
|
+
*/
|
|
54
|
+
requiredQualificationId: string | null;
|
|
55
|
+
constructor(options?: OperationOptions);
|
|
56
|
+
/** Operations are retired, never deleted, so history keeps resolving. */
|
|
57
|
+
delete(): Promise<void>;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=Operation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Operation.d.ts","sourceRoot":"","sources":["../../src/models/Operation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAGL,UAAU,EACV,KAAK,iBAAiB,EAEvB,MAAM,0BAA0B,CAAC;AAGlC;;GAEG;AACH,MAAM,WAAW,gBAAiB,SAAQ,iBAAiB;IACzD,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzC;AAED,qBAWa,SAAU,SAAQ,UAAU;IACvC,mEAAmE;IAEnE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B;;;;OAIG;IAEH,IAAI,EAAE,MAAM,CAAM;IAElB,sDAAsD;IAEtD,IAAI,EAAE,MAAM,CAAM;IAElB;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAM;IAEtB;;;OAGG;IACH,QAAQ,EAAE,OAAO,CAAQ;IAEzB;;;;;;OAMG;IAIH,uBAAuB,EAAE,MAAM,GAAG,IAAI,CAAQ;gBAElC,OAAO,GAAE,gBAAqB;IAW1C,yEAAyE;IAC1D,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;CAKvC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RoutingStep — one operation in the routing of a {@link BillOfMaterials}.
|
|
3
|
+
*
|
|
4
|
+
* A routing is the ordered list of steps for building one unit of the bill's
|
|
5
|
+
* product. It is optional: a bill with no routing steps behaves exactly as a
|
|
6
|
+
* bill always has. Steps are ordered by `sequence`, unique within the bill.
|
|
7
|
+
*
|
|
8
|
+
* Cross-package-style references (`bomId`, `operationId`) are plain string ids,
|
|
9
|
+
* as elsewhere in this package.
|
|
10
|
+
*
|
|
11
|
+
* @packageDocumentation
|
|
12
|
+
*/
|
|
13
|
+
import { SmrtObject, type SmrtObjectOptions } from '@happyvertical/smrt-core';
|
|
14
|
+
/**
|
|
15
|
+
* Options accepted by the {@link RoutingStep} constructor.
|
|
16
|
+
*/
|
|
17
|
+
export interface RoutingStepOptions extends SmrtObjectOptions {
|
|
18
|
+
tenantId?: string | null;
|
|
19
|
+
bomId?: string;
|
|
20
|
+
operationId?: string;
|
|
21
|
+
sequence?: number;
|
|
22
|
+
estimatedMinutes?: number;
|
|
23
|
+
notes?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare class RoutingStep extends SmrtObject {
|
|
26
|
+
/** Tenant scope. `null` means the step is a global record. */
|
|
27
|
+
tenantId: string | null;
|
|
28
|
+
/**
|
|
29
|
+
* The owning {@link BillOfMaterials}. Cascade: a routing belongs to its bill.
|
|
30
|
+
* (`BomLine.bomId` is still a plain string; see AGENTS.md.)
|
|
31
|
+
*/
|
|
32
|
+
bomId: string;
|
|
33
|
+
/** The {@link Operation} performed here. Restrict: operations are retired, never deleted. */
|
|
34
|
+
operationId: string;
|
|
35
|
+
/** Position in the routing, starting at 1 and without gaps. */
|
|
36
|
+
sequence: number;
|
|
37
|
+
/**
|
|
38
|
+
* Estimated working minutes at this step to build one unit of the bill's
|
|
39
|
+
* product. Decimal so `7.5` round-trips.
|
|
40
|
+
*/
|
|
41
|
+
estimatedMinutes: number;
|
|
42
|
+
/** Optional free-form note for this step. */
|
|
43
|
+
notes: string;
|
|
44
|
+
constructor(options?: RoutingStepOptions);
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=RoutingStep.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RoutingStep.d.ts","sourceRoot":"","sources":["../../src/models/RoutingStep.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAGL,UAAU,EACV,KAAK,iBAAiB,EAEvB,MAAM,0BAA0B,CAAC;AAKlC;;GAEG;AACH,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IAC3D,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBASa,WAAY,SAAQ,UAAU;IACzC,8DAA8D;IAE9D,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B;;;OAGG;IAEH,KAAK,EAAE,MAAM,CAAM;IAEnB,6FAA6F;IAE7F,WAAW,EAAE,MAAM,CAAM;IAEzB,+DAA+D;IAE/D,QAAQ,EAAE,MAAM,CAAK;IAErB;;;OAGG;IAEH,gBAAgB,EAAE,MAAM,CAAO;IAE/B,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAM;gBAEP,OAAO,GAAE,kBAAuB;CAW7C"}
|
package/dist/models/index.d.ts
CHANGED
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
* @packageDocumentation
|
|
10
10
|
*/
|
|
11
11
|
import '../__smrt-register__.js';
|
|
12
|
+
export { Assembly, type AssemblyOptions } from './Assembly.js';
|
|
12
13
|
export { BillOfMaterials, type BillOfMaterialsOptions, } from './BillOfMaterials.js';
|
|
13
14
|
export { BomLine, type BomLineOptions } from './BomLine.js';
|
|
15
|
+
export { Operation, type OperationOptions } from './Operation.js';
|
|
16
|
+
export { RoutingStep, type RoutingStepOptions } from './RoutingStep.js';
|
|
14
17
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,yBAAyB,CAAC;AAEjC,OAAO,EACL,eAAe,EACf,KAAK,sBAAsB,GAC5B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,yBAAyB,CAAC;AAEjC,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,EACL,eAAe,EACf,KAAK,sBAAsB,GAC5B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types and error classes for operations, routing and the labour estimate.
|
|
3
|
+
*
|
|
4
|
+
* Strictly industry-neutral.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
import type { Operation } from './models/Operation.js';
|
|
9
|
+
/**
|
|
10
|
+
* Callback that returns the hourly labour rate for an operation, in the bill's
|
|
11
|
+
* currency, or `null` / `undefined` when no rate is known. The package holds no
|
|
12
|
+
* rates: the caller decides where they come from (a price list, a rate class
|
|
13
|
+
* the application keeps against the operation code, a timesheet rate). Mirrors
|
|
14
|
+
* `ComponentCostResolver` for materials.
|
|
15
|
+
*/
|
|
16
|
+
export type OperationRateResolver = (operation: Operation) => Promise<number | null | undefined> | number | null | undefined;
|
|
17
|
+
/** One step of {@link LabourEstimate}. */
|
|
18
|
+
export interface RoutingStepEstimate {
|
|
19
|
+
/** The routing step id. */
|
|
20
|
+
stepId: string;
|
|
21
|
+
/** Position in the routing, starting at 1. */
|
|
22
|
+
sequence: number;
|
|
23
|
+
/** Plain string id of the operation. */
|
|
24
|
+
operationId: string;
|
|
25
|
+
/** Operation code, or `''` if the operation row is missing. */
|
|
26
|
+
operationCode: string;
|
|
27
|
+
/** Operation name, or `''` if the operation row is missing. */
|
|
28
|
+
operationName: string;
|
|
29
|
+
/** Estimated working minutes per produced unit. */
|
|
30
|
+
estimatedMinutes: number;
|
|
31
|
+
/** Hourly rate from the resolver, or `0` when unavailable. */
|
|
32
|
+
hourlyRate: number;
|
|
33
|
+
/** `estimatedMinutes / 60 * hourlyRate`; `0` when the rate is unavailable. */
|
|
34
|
+
stepCost: number;
|
|
35
|
+
/** `true` when no resolver was supplied or it returned no rate. */
|
|
36
|
+
rateUnavailable: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Estimated labour per produced unit, returned by
|
|
40
|
+
* `BomService.computeLabourEstimate`. A bill with no routing returns an empty
|
|
41
|
+
* `steps` array and zero totals.
|
|
42
|
+
*/
|
|
43
|
+
export interface LabourEstimate {
|
|
44
|
+
/** The bill that was rolled up. */
|
|
45
|
+
bomId: string;
|
|
46
|
+
/** `true` when the bill has at least one routing step. */
|
|
47
|
+
hasRouting: boolean;
|
|
48
|
+
/** Total estimated working minutes per produced unit. */
|
|
49
|
+
totalMinutes: number;
|
|
50
|
+
/** Total estimated labour cost per unit; counts only steps with a rate. */
|
|
51
|
+
totalCost: number;
|
|
52
|
+
/** ISO 4217 currency code of the bill. */
|
|
53
|
+
currency: string;
|
|
54
|
+
/** Steps in routing order. */
|
|
55
|
+
steps: RoutingStepEstimate[];
|
|
56
|
+
/** `true` when a step's rate was unavailable, so `totalCost` is a lower bound. */
|
|
57
|
+
hasMissingRates: boolean;
|
|
58
|
+
}
|
|
59
|
+
/** One step handed to `RoutingService.replaceRouting`. */
|
|
60
|
+
export interface RoutingStepInput {
|
|
61
|
+
/** Plain string id of the operation to perform. */
|
|
62
|
+
operationId: string;
|
|
63
|
+
/** Estimated working minutes per produced unit; zero or more. */
|
|
64
|
+
estimatedMinutes: number;
|
|
65
|
+
/** Optional free-form note. */
|
|
66
|
+
notes?: string;
|
|
67
|
+
}
|
|
68
|
+
/** Input for `OperationService.define`. */
|
|
69
|
+
export interface DefineOperationInput {
|
|
70
|
+
/** Unique per tenant; not changed afterwards. */
|
|
71
|
+
code: string;
|
|
72
|
+
name: string;
|
|
73
|
+
category?: string;
|
|
74
|
+
/** Plain string id of a `smrt-human-resources` qualification definition. */
|
|
75
|
+
requiredQualificationId?: string;
|
|
76
|
+
}
|
|
77
|
+
/** Thrown when an operation id does not exist. */
|
|
78
|
+
export declare class OperationNotFoundError extends Error {
|
|
79
|
+
readonly operationId: string;
|
|
80
|
+
name: string;
|
|
81
|
+
constructor(operationId: string);
|
|
82
|
+
}
|
|
83
|
+
/** Thrown when defining an operation whose code is already in use. */
|
|
84
|
+
export declare class DuplicateOperationCodeError extends Error {
|
|
85
|
+
readonly code: string;
|
|
86
|
+
name: string;
|
|
87
|
+
constructor(code: string);
|
|
88
|
+
}
|
|
89
|
+
/** Thrown when a routing would newly add a retired operation. */
|
|
90
|
+
export declare class OperationRetiredError extends Error {
|
|
91
|
+
readonly operationId: string;
|
|
92
|
+
name: string;
|
|
93
|
+
constructor(operationId: string);
|
|
94
|
+
}
|
|
95
|
+
/** Thrown for invalid operation or routing input. */
|
|
96
|
+
export declare class InvalidOperationInputError extends Error {
|
|
97
|
+
name: string;
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=operation-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operation-types.d.ts","sourceRoot":"","sources":["../src/operation-types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEvD;;;;;;GAMG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAClC,SAAS,EAAE,SAAS,KACjB,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;AAEpE,0CAA0C;AAC1C,MAAM,WAAW,mBAAmB;IAClC,2BAA2B;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,+DAA+D;IAC/D,aAAa,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,aAAa,EAAE,MAAM,CAAC;IACtB,mDAAmD;IACnD,gBAAgB,EAAE,MAAM,CAAC;IACzB,8DAA8D;IAC9D,UAAU,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,UAAU,EAAE,OAAO,CAAC;IACpB,yDAAyD;IACzD,YAAY,EAAE,MAAM,CAAC;IACrB,2EAA2E;IAC3E,SAAS,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,KAAK,EAAE,mBAAmB,EAAE,CAAC;IAC7B,kFAAkF;IAClF,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,0DAA0D;AAC1D,MAAM,WAAW,gBAAgB;IAC/B,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,gBAAgB,EAAE,MAAM,CAAC;IACzB,+BAA+B;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,2CAA2C;AAC3C,MAAM,WAAW,oBAAoB;IACnC,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC;AAED,kDAAkD;AAClD,qBAAa,sBAAuB,SAAQ,KAAK;aAGnB,WAAW,EAAE,MAAM;IAFtC,IAAI,SAA4B;gBAEb,WAAW,EAAE,MAAM;CAGhD;AAED,sEAAsE;AACtE,qBAAa,2BAA4B,SAAQ,KAAK;aAGxB,IAAI,EAAE,MAAM;IAF/B,IAAI,SAAiC;gBAElB,IAAI,EAAE,MAAM;CAGzC;AAED,iEAAiE;AACjE,qBAAa,qBAAsB,SAAQ,KAAK;aAGlB,WAAW,EAAE,MAAM;IAFtC,IAAI,SAA2B;gBAEZ,WAAW,EAAE,MAAM;CAKhD;AAED,qDAAqD;AACrD,qBAAa,0BAA2B,SAAQ,KAAK;IAC1C,IAAI,SAAgC;CAC9C"}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AssemblyService — the link between a bill line and the thing it names.
|
|
3
|
+
*
|
|
4
|
+
* A {@link BomLine} points at a component SKU. That SKU belongs to a
|
|
5
|
+
* `Product` row in `@happyvertical/smrt-products`, and the row's subtype
|
|
6
|
+
* decides what the line means:
|
|
7
|
+
*
|
|
8
|
+
* | Component SKU belongs to | Kind | Meaning |
|
|
9
|
+
* |---|---|---|
|
|
10
|
+
* | an {@link Assembly} | `assembly` | a sub-assembly; it is built from its own active bill, if it has one |
|
|
11
|
+
* | a `Material` | `material` | a consumed input; the leaf of the structure |
|
|
12
|
+
* | any other `Product` | `bought` | an item that is bought, not built here |
|
|
13
|
+
* | nothing (unknown SKU or product) | `missing` | the line points at a record that does not exist |
|
|
14
|
+
*
|
|
15
|
+
* {@link AssemblyService.resolveComponent} answers that question for one
|
|
16
|
+
* SKU, and also returns the assembly's active bill. It is the step a
|
|
17
|
+
* multi-level explosion repeats: resolve each line's component, recurse into
|
|
18
|
+
* every `assembly` that has an `activeBom`, stop at everything else.
|
|
19
|
+
*
|
|
20
|
+
* The service also owns the **cycle refusal**: an assembly may not contain
|
|
21
|
+
* itself, directly or through sub-assemblies. {@link BomLine} and
|
|
22
|
+
* {@link BillOfMaterials} call {@link AssemblyService.assertLineAcyclic} and
|
|
23
|
+
* {@link AssemblyService.assertBillAcyclic} before every save, so the
|
|
24
|
+
* generated REST routes refuse a cycle too.
|
|
25
|
+
*
|
|
26
|
+
* @packageDocumentation
|
|
27
|
+
*/
|
|
28
|
+
import { type DatabaseConfig, ValidationError } from '@happyvertical/smrt-core';
|
|
29
|
+
import { ProductCollection, SkuCollection } from '@happyvertical/smrt-products/collections';
|
|
30
|
+
import { type Product, type Sku } from '@happyvertical/smrt-products/models';
|
|
31
|
+
import { BillOfMaterialsCollection } from '../collections/BillOfMaterialsCollection.js';
|
|
32
|
+
import { BomLineCollection } from '../collections/BomLineCollection.js';
|
|
33
|
+
import { Assembly } from '../models/Assembly.js';
|
|
34
|
+
import type { BillOfMaterials } from '../models/BillOfMaterials.js';
|
|
35
|
+
import type { BomLine } from '../models/BomLine.js';
|
|
36
|
+
/**
|
|
37
|
+
* What a component SKU is, as far as building goes. See the table in the
|
|
38
|
+
* {@link AssemblyService} module documentation.
|
|
39
|
+
*/
|
|
40
|
+
export type ComponentKind = 'assembly' | 'material' | 'bought' | 'missing';
|
|
41
|
+
/**
|
|
42
|
+
* The answer to "what is this component SKU?" returned by
|
|
43
|
+
* {@link AssemblyService.resolveComponent}.
|
|
44
|
+
*/
|
|
45
|
+
export interface ResolvedComponent {
|
|
46
|
+
/** The component SKU id that was resolved. */
|
|
47
|
+
skuId: string;
|
|
48
|
+
/** What the SKU is; see {@link ComponentKind}. */
|
|
49
|
+
kind: ComponentKind;
|
|
50
|
+
/** The SKU row, or `null` when no SKU has this id. */
|
|
51
|
+
sku: Sku | null;
|
|
52
|
+
/**
|
|
53
|
+
* The product the SKU belongs to (an `Assembly`, a `Material` or a plain
|
|
54
|
+
* `Product`), or `null` when the SKU or its product does not exist.
|
|
55
|
+
*/
|
|
56
|
+
product: Product | null;
|
|
57
|
+
/** The assembly, when {@link kind} is `assembly`; otherwise `null`. */
|
|
58
|
+
assembly: Assembly | null;
|
|
59
|
+
/**
|
|
60
|
+
* The assembly's active bill (the highest active version), or `null` for
|
|
61
|
+
* an assembly that has no active bill yet and for every other kind.
|
|
62
|
+
*/
|
|
63
|
+
activeBom: BillOfMaterials | null;
|
|
64
|
+
/**
|
|
65
|
+
* `true` only for an assembly with an active bill: the component *can* be
|
|
66
|
+
* built here. Whether a shortage is built or bought is the application's
|
|
67
|
+
* decision; this only reports the fact.
|
|
68
|
+
*/
|
|
69
|
+
buildable: boolean;
|
|
70
|
+
}
|
|
71
|
+
/** One bill line together with the component it resolves to. */
|
|
72
|
+
export interface BillStructureLine {
|
|
73
|
+
/** The bill line as stored. */
|
|
74
|
+
line: BomLine;
|
|
75
|
+
/** The line's component SKU, resolved. */
|
|
76
|
+
component: ResolvedComponent;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* One level of an assembly's structure, returned by
|
|
80
|
+
* {@link AssemblyService.getBillStructure}. Sub-assembly lines carry their
|
|
81
|
+
* own `activeBom`; pass its id back to `getBillStructure` to open the next
|
|
82
|
+
* level.
|
|
83
|
+
*/
|
|
84
|
+
export interface BillStructure {
|
|
85
|
+
/** The bill that was read. */
|
|
86
|
+
bom: BillOfMaterials;
|
|
87
|
+
/** Its lines in component-SKU order, each resolved. */
|
|
88
|
+
lines: BillStructureLine[];
|
|
89
|
+
}
|
|
90
|
+
/** One product on a cycle path reported by {@link BomCycleError}. */
|
|
91
|
+
export interface BomCyclePathEntry {
|
|
92
|
+
/** The product id (an assembly, or the bill's own product). */
|
|
93
|
+
productId: string;
|
|
94
|
+
/** The product's name, or its id when it has no name or cannot be read. */
|
|
95
|
+
name: string;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Thrown when saving a bill line, or saving a bill as active, would make a
|
|
99
|
+
* product contain itself. `path` starts and ends with the bill's product,
|
|
100
|
+
* listing each assembly in between: `Frame → Side panel → Frame`.
|
|
101
|
+
*/
|
|
102
|
+
export declare class BomCycleError extends ValidationError {
|
|
103
|
+
/** The bill being saved (or the bill of the line being saved). */
|
|
104
|
+
readonly bomId: string;
|
|
105
|
+
/** The cycle, from the bill's product back to itself. */
|
|
106
|
+
readonly path: BomCyclePathEntry[];
|
|
107
|
+
name: string;
|
|
108
|
+
constructor(
|
|
109
|
+
/** The bill being saved (or the bill of the line being saved). */
|
|
110
|
+
bomId: string,
|
|
111
|
+
/** The cycle, from the bill's product back to itself. */
|
|
112
|
+
path: BomCyclePathEntry[]);
|
|
113
|
+
}
|
|
114
|
+
/** Options for {@link AssemblyService.resolveComponent} and the walks built on it. */
|
|
115
|
+
export interface ResolveComponentOptions {
|
|
116
|
+
/**
|
|
117
|
+
* The tenant whose structure is being read. When given (including `null`
|
|
118
|
+
* for global records), an assembly's active bill is chosen only among
|
|
119
|
+
* bills with exactly this `tenantId`, and a SKU, product or bill line
|
|
120
|
+
* belonging to another tenant is treated as missing (global rows stay
|
|
121
|
+
* visible), whatever tenant context is active. When omitted, the active
|
|
122
|
+
* tenant context decides what is visible.
|
|
123
|
+
*/
|
|
124
|
+
tenantId?: string | null;
|
|
125
|
+
}
|
|
126
|
+
/** Options accepted by {@link AssemblyService.create}. */
|
|
127
|
+
export interface AssemblyServiceOptions {
|
|
128
|
+
/** Database config or live handle shared by every collection. */
|
|
129
|
+
db: DatabaseConfig;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Resolves components and refuses cycles. Construct with
|
|
133
|
+
* {@link AssemblyService.create} or {@link createAssemblyService}.
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```typescript
|
|
137
|
+
* const assemblies = await AssemblyService.create({ db });
|
|
138
|
+
* const component = await assemblies.resolveComponent(line.componentSkuId);
|
|
139
|
+
* if (component.kind === 'assembly' && component.activeBom) {
|
|
140
|
+
* // a sub-assembly that can be built: walk component.activeBom next
|
|
141
|
+
* }
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
export declare class AssemblyService {
|
|
145
|
+
/** Every `Product` row, any subtype. */
|
|
146
|
+
readonly products: ProductCollection;
|
|
147
|
+
/** The SKU catalog. */
|
|
148
|
+
readonly skus: SkuCollection;
|
|
149
|
+
/** Bills of materials. */
|
|
150
|
+
readonly boms: BillOfMaterialsCollection;
|
|
151
|
+
/** Bill lines. */
|
|
152
|
+
readonly lines: BomLineCollection;
|
|
153
|
+
private constructor();
|
|
154
|
+
/** Factory — prefer {@link createAssemblyService}. */
|
|
155
|
+
static create(options: AssemblyServiceOptions): Promise<AssemblyService>;
|
|
156
|
+
/**
|
|
157
|
+
* Resolve a component SKU to what it is: an assembly (with its active bill,
|
|
158
|
+
* or `null` when it has none), a material, a bought item, or missing. Never
|
|
159
|
+
* throws for an unknown id; it reports `missing` instead.
|
|
160
|
+
*
|
|
161
|
+
* This is the documented link a multi-level explosion walks: recurse into
|
|
162
|
+
* `activeBom` while `kind === 'assembly'`, stop at every other kind. Pass
|
|
163
|
+
* the parent bill's `tenantId` so a shared assembly resolves to that
|
|
164
|
+
* tenant's bill, not another tenant's.
|
|
165
|
+
*/
|
|
166
|
+
resolveComponent(skuId: string, options?: ResolveComponentOptions): Promise<ResolvedComponent>;
|
|
167
|
+
/**
|
|
168
|
+
* The highest-version active bill for a product, limited to one tenant's
|
|
169
|
+
* bills when `options.tenantId` is given.
|
|
170
|
+
*/
|
|
171
|
+
findActiveBom(productId: string, options?: ResolveComponentOptions): Promise<BillOfMaterials | null>;
|
|
172
|
+
/** `true` when the SKU belongs to an {@link Assembly}. */
|
|
173
|
+
isAssembly(skuId: string): Promise<boolean>;
|
|
174
|
+
/**
|
|
175
|
+
* Read one bill and resolve every line's component. Sub-assembly lines say
|
|
176
|
+
* whether they have an active bill of their own (`component.activeBom`);
|
|
177
|
+
* the caller opens the next level by passing that id back in.
|
|
178
|
+
*
|
|
179
|
+
* @throws {BomNotFoundError} when no bill has this id.
|
|
180
|
+
*/
|
|
181
|
+
getBillStructure(bomId: string): Promise<BillStructure>;
|
|
182
|
+
/**
|
|
183
|
+
* Find the path by which adding `componentSkuIds` to a bill for
|
|
184
|
+
* `productId` would make that product contain itself, or `null` when none
|
|
185
|
+
* would. The walk follows each sub-assembly's **active** bill only; a
|
|
186
|
+
* draft or superseded bill is not part of the structure. Pass the bill's
|
|
187
|
+
* `tenantId` so the walk reads that tenant's structure.
|
|
188
|
+
*/
|
|
189
|
+
findCycle(productId: string, componentSkuIds: readonly string[], options?: ResolveComponentOptions): Promise<BomCyclePathEntry[] | null>;
|
|
190
|
+
/**
|
|
191
|
+
* Refuse a bill line that would make its bill's product contain itself.
|
|
192
|
+
* A line on a draft bill is checked too, so a cycle is refused when it is
|
|
193
|
+
* written rather than when the bill is activated. A line whose bill does
|
|
194
|
+
* not exist is left to the caller.
|
|
195
|
+
*
|
|
196
|
+
* @throws {BomCycleError} naming the path.
|
|
197
|
+
*/
|
|
198
|
+
assertLineAcyclic(line: Pick<BomLine, 'bomId' | 'componentSkuId'>): Promise<void>;
|
|
199
|
+
/**
|
|
200
|
+
* Refuse saving a bill as `active` when any of its lines would make its
|
|
201
|
+
* product contain itself. Bills in any other status are not part of the
|
|
202
|
+
* structure and pass.
|
|
203
|
+
*
|
|
204
|
+
* The lines checked are the bill's own and those of any stored bill with
|
|
205
|
+
* the same natural key (`productId`, `version`, and the bill's tenant, or
|
|
206
|
+
* the active tenant when the bill has none yet): saving a new
|
|
207
|
+
* instance with that key upserts onto the stored bill and activates its
|
|
208
|
+
* lines, so they are part of what the save makes active.
|
|
209
|
+
*
|
|
210
|
+
* @throws {BomCycleError} naming the path.
|
|
211
|
+
*/
|
|
212
|
+
assertBillAcyclic(bom: Pick<BillOfMaterials, 'id' | 'productId' | 'status' | 'version' | 'tenantId'>): Promise<void>;
|
|
213
|
+
private resolveCached;
|
|
214
|
+
}
|
|
215
|
+
/** Convenience factory for {@link AssemblyService}. */
|
|
216
|
+
export declare function createAssemblyService(options: AssemblyServiceOptions): Promise<AssemblyService>;
|
|
217
|
+
//# sourceMappingURL=AssemblyService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssemblyService.d.ts","sourceRoot":"","sources":["../../src/services/AssemblyService.ts"],"names":[],"mappings":"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"}
|