@campfire-interactive/master-data-client 4.3.0 → 4.8.0
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/dist/companies.d.ts +5 -1
- package/dist/companies.d.ts.map +1 -1
- package/dist/companies.js +16 -0
- package/dist/companies.js.map +1 -1
- package/dist/engineeringChanges.d.ts +8 -6
- package/dist/engineeringChanges.d.ts.map +1 -1
- package/dist/engineeringChanges.js +8 -6
- package/dist/engineeringChanges.js.map +1 -1
- package/dist/equipment.d.ts +5 -1
- package/dist/equipment.d.ts.map +1 -1
- package/dist/equipment.js +18 -2
- package/dist/equipment.js.map +1 -1
- package/dist/exchangeRates.d.ts +6 -1
- package/dist/exchangeRates.d.ts.map +1 -1
- package/dist/exchangeRates.js +11 -0
- package/dist/exchangeRates.js.map +1 -1
- package/dist/imports.d.ts +7 -1
- package/dist/imports.d.ts.map +1 -1
- package/dist/imports.js +9 -0
- package/dist/imports.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/materials.d.ts +5 -1
- package/dist/materials.d.ts.map +1 -1
- package/dist/materials.js +16 -0
- package/dist/materials.js.map +1 -1
- package/dist/partAttributes.d.ts +7 -1
- package/dist/partAttributes.d.ts.map +1 -1
- package/dist/partAttributes.js +18 -0
- package/dist/partAttributes.js.map +1 -1
- package/dist/partCategories.d.ts +7 -1
- package/dist/partCategories.d.ts.map +1 -1
- package/dist/partCategories.js +18 -0
- package/dist/partCategories.js.map +1 -1
- package/dist/partTypes.d.ts +6 -1
- package/dist/partTypes.d.ts.map +1 -1
- package/dist/partTypes.js +17 -0
- package/dist/partTypes.js.map +1 -1
- package/dist/parts.d.ts +5 -1
- package/dist/parts.d.ts.map +1 -1
- package/dist/parts.js +16 -0
- package/dist/parts.js.map +1 -1
- package/dist/plants.d.ts +8 -1
- package/dist/plants.d.ts.map +1 -1
- package/dist/plants.js +21 -2
- package/dist/plants.js.map +1 -1
- package/dist/processFamilies.d.ts +6 -2
- package/dist/processFamilies.d.ts.map +1 -1
- package/dist/processFamilies.js +18 -2
- package/dist/processFamilies.js.map +1 -1
- package/dist/programs.d.ts +5 -1
- package/dist/programs.d.ts.map +1 -1
- package/dist/programs.js +16 -0
- package/dist/programs.js.map +1 -1
- package/dist/quotes.d.ts +9 -1
- package/dist/quotes.d.ts.map +1 -1
- package/dist/quotes.js +14 -0
- package/dist/quotes.js.map +1 -1
- package/dist/rateCatalog.d.ts +46 -1
- package/dist/rateCatalog.d.ts.map +1 -1
- package/dist/rateCatalog.js +73 -6
- package/dist/rateCatalog.js.map +1 -1
- package/dist/schedulePeriods.d.ts +16 -0
- package/dist/schedulePeriods.d.ts.map +1 -0
- package/dist/schedulePeriods.js +81 -0
- package/dist/schedulePeriods.js.map +1 -0
- package/dist/types.d.ts +159 -6
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/suppliers.d.ts +0 -14
- package/dist/suppliers.d.ts.map +0 -1
- package/dist/suppliers.js +0 -84
- package/dist/suppliers.js.map +0 -1
package/dist/rateCatalog.js
CHANGED
|
@@ -6,10 +6,14 @@ class UomResource {
|
|
|
6
6
|
constructor(http) {
|
|
7
7
|
this.http = http;
|
|
8
8
|
}
|
|
9
|
+
/** Bug fix: this previously sent an `active` boolean param the backend
|
|
10
|
+
* never read (listUoms had no status concept at all) — the Archived/All
|
|
11
|
+
* filter silently no-opped. Now sends `status`, matching every other
|
|
12
|
+
* entity's convention, paired with Uom's newly-added soft archive. */
|
|
9
13
|
async list(options) {
|
|
10
14
|
const query = {};
|
|
11
|
-
if (options?.
|
|
12
|
-
query.
|
|
15
|
+
if (options?.status)
|
|
16
|
+
query.status = options.status;
|
|
13
17
|
return this.http.request({
|
|
14
18
|
method: 'GET',
|
|
15
19
|
path: '/v1/rate-catalog/uoms',
|
|
@@ -30,24 +34,46 @@ class UomResource {
|
|
|
30
34
|
body: input,
|
|
31
35
|
});
|
|
32
36
|
}
|
|
37
|
+
/** Hard delete. Prefer {@link batchArchive} for reversible removal. */
|
|
33
38
|
async remove(id) {
|
|
34
39
|
await this.http.request({
|
|
35
40
|
method: 'DELETE',
|
|
36
41
|
path: `/v1/rate-catalog/uoms/${encodeURIComponent(id)}`,
|
|
37
42
|
});
|
|
38
43
|
}
|
|
44
|
+
/** Archive many UoMs in one call (soft, flips `active`; distinct from the
|
|
45
|
+
* hard {@link remove} above — new capability). Reversible via
|
|
46
|
+
* {@link batchRestore}. */
|
|
47
|
+
async batchArchive(ids) {
|
|
48
|
+
return this.http.request({
|
|
49
|
+
method: 'POST',
|
|
50
|
+
path: '/v1/rate-catalog/uoms/batch-archive',
|
|
51
|
+
body: { ids },
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/** Restore (un-archive) many UoMs in one call. */
|
|
55
|
+
async batchRestore(ids) {
|
|
56
|
+
return this.http.request({
|
|
57
|
+
method: 'POST',
|
|
58
|
+
path: '/v1/rate-catalog/uoms/batch-restore',
|
|
59
|
+
body: { ids },
|
|
60
|
+
});
|
|
61
|
+
}
|
|
39
62
|
}
|
|
40
63
|
class RateLineResource {
|
|
41
64
|
http;
|
|
42
65
|
constructor(http) {
|
|
43
66
|
this.http = http;
|
|
44
67
|
}
|
|
68
|
+
/** Bug fix: this previously sent an `active` boolean param the backend
|
|
69
|
+
* never read (it reads `status`) — the Archived/All filter silently
|
|
70
|
+
* no-opped. Now sends `status`, matching every other entity. */
|
|
45
71
|
async list(options) {
|
|
46
72
|
const query = {};
|
|
47
73
|
if (options?.binding)
|
|
48
74
|
query.binding = options.binding;
|
|
49
|
-
if (options?.
|
|
50
|
-
query.
|
|
75
|
+
if (options?.status)
|
|
76
|
+
query.status = options.status;
|
|
51
77
|
return this.http.request({
|
|
52
78
|
method: 'GET',
|
|
53
79
|
path: '/v1/rate-catalog/lines',
|
|
@@ -68,22 +94,44 @@ class RateLineResource {
|
|
|
68
94
|
body: input,
|
|
69
95
|
});
|
|
70
96
|
}
|
|
97
|
+
/** Hard delete. 2026-07-24: previously soft-archived (matched Archive), which made
|
|
98
|
+
* the two indistinguishable; now really deletes. Prefer {@link batchArchive}
|
|
99
|
+
* for reversible removal. */
|
|
71
100
|
async remove(id) {
|
|
72
101
|
await this.http.request({
|
|
73
102
|
method: 'DELETE',
|
|
74
103
|
path: `/v1/rate-catalog/lines/${encodeURIComponent(id)}`,
|
|
75
104
|
});
|
|
76
105
|
}
|
|
106
|
+
/** Archive many rate lines in one call. Reversible via {@link batchRestore}. */
|
|
107
|
+
async batchArchive(ids) {
|
|
108
|
+
return this.http.request({
|
|
109
|
+
method: 'POST',
|
|
110
|
+
path: '/v1/rate-catalog/lines/batch-archive',
|
|
111
|
+
body: { ids },
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
/** Restore (un-archive) many rate lines in one call. */
|
|
115
|
+
async batchRestore(ids) {
|
|
116
|
+
return this.http.request({
|
|
117
|
+
method: 'POST',
|
|
118
|
+
path: '/v1/rate-catalog/lines/batch-restore',
|
|
119
|
+
body: { ids },
|
|
120
|
+
});
|
|
121
|
+
}
|
|
77
122
|
}
|
|
78
123
|
class RateGradeResource {
|
|
79
124
|
http;
|
|
80
125
|
constructor(http) {
|
|
81
126
|
this.http = http;
|
|
82
127
|
}
|
|
128
|
+
/** Bug fix: this previously sent an `active` boolean param the backend
|
|
129
|
+
* never read (it reads `status`) — the Archived/All filter silently
|
|
130
|
+
* no-opped. Now sends `status`, matching every other entity. */
|
|
83
131
|
async list(options) {
|
|
84
132
|
const query = {};
|
|
85
|
-
if (options?.
|
|
86
|
-
query.
|
|
133
|
+
if (options?.status)
|
|
134
|
+
query.status = options.status;
|
|
87
135
|
return this.http.request({
|
|
88
136
|
method: 'GET',
|
|
89
137
|
path: '/v1/rate-catalog/grades',
|
|
@@ -104,12 +152,31 @@ class RateGradeResource {
|
|
|
104
152
|
body: input,
|
|
105
153
|
});
|
|
106
154
|
}
|
|
155
|
+
/** Hard delete. 2026-07-24: previously soft-archived (matched Archive), which made
|
|
156
|
+
* the two indistinguishable; now really deletes. Prefer {@link batchArchive}
|
|
157
|
+
* for reversible removal. */
|
|
107
158
|
async remove(id) {
|
|
108
159
|
await this.http.request({
|
|
109
160
|
method: 'DELETE',
|
|
110
161
|
path: `/v1/rate-catalog/grades/${encodeURIComponent(id)}`,
|
|
111
162
|
});
|
|
112
163
|
}
|
|
164
|
+
/** Archive many rate grades in one call. Reversible via {@link batchRestore}. */
|
|
165
|
+
async batchArchive(ids) {
|
|
166
|
+
return this.http.request({
|
|
167
|
+
method: 'POST',
|
|
168
|
+
path: '/v1/rate-catalog/grades/batch-archive',
|
|
169
|
+
body: { ids },
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
/** Restore (un-archive) many rate grades in one call. */
|
|
173
|
+
async batchRestore(ids) {
|
|
174
|
+
return this.http.request({
|
|
175
|
+
method: 'POST',
|
|
176
|
+
path: '/v1/rate-catalog/grades/batch-restore',
|
|
177
|
+
body: { ids },
|
|
178
|
+
});
|
|
179
|
+
}
|
|
113
180
|
}
|
|
114
181
|
/**
|
|
115
182
|
* Rate reference catalogs (UoM / RateLine / RateGrade) — the vocabulary a rate
|
package/dist/rateCatalog.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rateCatalog.js","sourceRoot":"","sources":["../src/rateCatalog.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"rateCatalog.js","sourceRoot":"","sources":["../src/rateCatalog.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { SchedulePeriod } from './types';
|
|
2
|
+
/** The recognisable shapes a span can take. `custom` = anything else. */
|
|
3
|
+
export type SchedulePeriodGranularity = 'year' | 'quarter' | 'month' | 'fiscal-year' | 'custom';
|
|
4
|
+
/**
|
|
5
|
+
* Classify a span by its shape. A period is only a `year` / `quarter` / `month`
|
|
6
|
+
* if it covers exactly that unit — a stretch that merely starts on Jan 1 but
|
|
7
|
+
* ends in November is `custom`, not a year, because calling it "2027" would
|
|
8
|
+
* overstate what the customer committed to.
|
|
9
|
+
*/
|
|
10
|
+
export declare function schedulePeriodGranularity(period: SchedulePeriod): SchedulePeriodGranularity;
|
|
11
|
+
/**
|
|
12
|
+
* Human label for a span: `2027`, `Q2 2027`, `Mar 2027`, `FY 2026-27`, or a raw
|
|
13
|
+
* `2027-03-15 – 2027-04-28` range when the span matches no convention.
|
|
14
|
+
*/
|
|
15
|
+
export declare function formatSchedulePeriod(period: SchedulePeriod): string;
|
|
16
|
+
//# sourceMappingURL=schedulePeriods.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedulePeriods.d.ts","sourceRoot":"","sources":["../src/schedulePeriods.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAoB9C,yEAAyE;AACzE,MAAM,MAAM,yBAAyB,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,aAAa,GAAG,QAAQ,CAAC;AAmBhG;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,cAAc,GAAG,yBAAyB,CAmB3F;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAiBnE"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.schedulePeriodGranularity = schedulePeriodGranularity;
|
|
4
|
+
exports.formatSchedulePeriod = formatSchedulePeriod;
|
|
5
|
+
/**
|
|
6
|
+
* Display helpers for arbitrary-period schedules (`effectiveVolumesByPeriod` /
|
|
7
|
+
* `effectivePricesByPeriod`).
|
|
8
|
+
*
|
|
9
|
+
* Granularity is NOT stored on a schedule point — it's derivable from the span,
|
|
10
|
+
* and a stored label can contradict the dates. It lives here rather than in each
|
|
11
|
+
* consumer so every app labels the same span identically.
|
|
12
|
+
*
|
|
13
|
+
* Note there is deliberately no rollup helper here: the yearly rollup CPQ costs
|
|
14
|
+
* against is computed server-side at write time, so there is exactly one
|
|
15
|
+
* implementation of it and clients can't disagree with the stored column.
|
|
16
|
+
*/
|
|
17
|
+
const MONTHS = [
|
|
18
|
+
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
|
|
19
|
+
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',
|
|
20
|
+
];
|
|
21
|
+
function parts(iso) {
|
|
22
|
+
const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(iso);
|
|
23
|
+
if (!m)
|
|
24
|
+
return null;
|
|
25
|
+
return { year: Number(m[1]), month: Number(m[2]), day: Number(m[3]) };
|
|
26
|
+
}
|
|
27
|
+
function lastDayOfMonth(year, month) {
|
|
28
|
+
return new Date(Date.UTC(year, month, 0)).getUTCDate();
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Classify a span by its shape. A period is only a `year` / `quarter` / `month`
|
|
32
|
+
* if it covers exactly that unit — a stretch that merely starts on Jan 1 but
|
|
33
|
+
* ends in November is `custom`, not a year, because calling it "2027" would
|
|
34
|
+
* overstate what the customer committed to.
|
|
35
|
+
*/
|
|
36
|
+
function schedulePeriodGranularity(period) {
|
|
37
|
+
const start = parts(period.periodStart);
|
|
38
|
+
const end = parts(period.periodEnd);
|
|
39
|
+
if (!start || !end)
|
|
40
|
+
return 'custom';
|
|
41
|
+
const endsMonth = end.day === lastDayOfMonth(end.year, end.month);
|
|
42
|
+
if (start.day !== 1 || !endsMonth)
|
|
43
|
+
return 'custom';
|
|
44
|
+
if (start.year === end.year) {
|
|
45
|
+
if (start.month === 1 && end.month === 12)
|
|
46
|
+
return 'year';
|
|
47
|
+
if (start.month === end.month)
|
|
48
|
+
return 'month';
|
|
49
|
+
// Calendar quarters only — Feb-Apr is a 3-month custom block, not "Q1".
|
|
50
|
+
if (end.month - start.month === 2 && (start.month - 1) % 3 === 0)
|
|
51
|
+
return 'quarter';
|
|
52
|
+
return 'custom';
|
|
53
|
+
}
|
|
54
|
+
// A 12-month span crossing exactly one year boundary reads as a fiscal year.
|
|
55
|
+
if (end.year === start.year + 1 && end.month === start.month - 1)
|
|
56
|
+
return 'fiscal-year';
|
|
57
|
+
return 'custom';
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Human label for a span: `2027`, `Q2 2027`, `Mar 2027`, `FY 2026-27`, or a raw
|
|
61
|
+
* `2027-03-15 – 2027-04-28` range when the span matches no convention.
|
|
62
|
+
*/
|
|
63
|
+
function formatSchedulePeriod(period) {
|
|
64
|
+
const start = parts(period.periodStart);
|
|
65
|
+
const end = parts(period.periodEnd);
|
|
66
|
+
if (!start || !end)
|
|
67
|
+
return `${period.periodStart} – ${period.periodEnd}`;
|
|
68
|
+
switch (schedulePeriodGranularity(period)) {
|
|
69
|
+
case 'year':
|
|
70
|
+
return String(start.year);
|
|
71
|
+
case 'quarter':
|
|
72
|
+
return `Q${Math.floor((start.month - 1) / 3) + 1} ${start.year}`;
|
|
73
|
+
case 'month':
|
|
74
|
+
return `${MONTHS[start.month - 1]} ${start.year}`;
|
|
75
|
+
case 'fiscal-year':
|
|
76
|
+
return `FY ${start.year}-${String(end.year % 100).padStart(2, '0')}`;
|
|
77
|
+
default:
|
|
78
|
+
return `${period.periodStart} – ${period.periodEnd}`;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=schedulePeriods.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedulePeriods.js","sourceRoot":"","sources":["../src/schedulePeriods.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -194,6 +194,9 @@ export interface Quote {
|
|
|
194
194
|
* — the figure CPQ costs against. Seeded from OMSF's vehicle→part conversion
|
|
195
195
|
* (VI vehicle × take rate), then the rep's edit over it. Independent of
|
|
196
196
|
* {@link effectiveVolumesByYear}; neither is auto-derived from the other.
|
|
197
|
+
*
|
|
198
|
+
* **Unless {@link effectiveVolumesByPeriod} is set**, in which case this is
|
|
199
|
+
* DERIVED from it (the mean of the rolled-up years) and writing it is a 422.
|
|
197
200
|
*/
|
|
198
201
|
effectiveAnnualVolume: number | null;
|
|
199
202
|
/**
|
|
@@ -201,8 +204,36 @@ export interface Quote {
|
|
|
201
204
|
* NOT vehicle/program) — the primary figure CPQ costs against. Stored as
|
|
202
205
|
* JSONB; shape pinned here and at the API boundary. Seeded from OMSF's
|
|
203
206
|
* vehicle→part conversion at quote creation, then refined by the rep.
|
|
207
|
+
*
|
|
208
|
+
* **Unless {@link effectiveVolumesByPeriod} is set**, in which case this is
|
|
209
|
+
* DERIVED from it at write time (day-count pro-rated for spans that straddle a
|
|
210
|
+
* year) and writing it is a 422. Readers need no change either way — this
|
|
211
|
+
* column stays the canonical yearly curve.
|
|
204
212
|
*/
|
|
205
213
|
effectiveVolumesByYear: EffectiveVolumeByYear[] | null;
|
|
214
|
+
/**
|
|
215
|
+
* Customer-committed PART volume on ARBITRARY periods — the general form of
|
|
216
|
+
* {@link effectiveVolumesByYear}, for deals tracked at a granularity the year
|
|
217
|
+
* key can't express (monthly launch ramp with annual out-years, fiscal years,
|
|
218
|
+
* irregular blocks). When non-empty it is AUTHORITATIVE and the two fields
|
|
219
|
+
* above are derived from it.
|
|
220
|
+
*
|
|
221
|
+
* Independent of {@link effectivePricesByPeriod}: no point pairs with a price
|
|
222
|
+
* point, either may exist alone, and the two period grids may disagree.
|
|
223
|
+
* Overlapping periods within this series are rejected (422). (4.8.0)
|
|
224
|
+
*/
|
|
225
|
+
effectiveVolumesByPeriod: EffectiveVolumeByPeriod[] | null;
|
|
226
|
+
/**
|
|
227
|
+
* Customer-committed unit price on ARBITRARY periods — the price walk / LTA
|
|
228
|
+
* step-down the customer agreed to.
|
|
229
|
+
*
|
|
230
|
+
* **Derives nothing.** {@link effectiveUnitPrice} keeps its adapter-written
|
|
231
|
+
* provenance (`effectivePriceSource` / `effectivePricedAt` / …) and is
|
|
232
|
+
* untouched by this field, so no margin figure moves when a schedule is
|
|
233
|
+
* imported. Readers wanting one headline number from this series must decide
|
|
234
|
+
* how to weight it (volume-weighted, not a mean). (4.8.0)
|
|
235
|
+
*/
|
|
236
|
+
effectivePricesByPeriod: EffectivePriceByPeriod[] | null;
|
|
206
237
|
status: QuoteStatus;
|
|
207
238
|
/** rfq | eco — see {@link QuoteType}. Immutable post-create. (3.0.2) */
|
|
208
239
|
quoteType: QuoteType;
|
|
@@ -231,6 +262,28 @@ export interface EffectiveVolumeByYear {
|
|
|
231
262
|
year: number;
|
|
232
263
|
effectiveVolume: number;
|
|
233
264
|
}
|
|
265
|
+
/**
|
|
266
|
+
* One inclusive period in an arbitrary-period schedule. Every granularity is a
|
|
267
|
+
* span, so yearly (`2027-01-01`→`2027-12-31`), quarterly, monthly, fiscal
|
|
268
|
+
* (`2026-07-01`→`2027-06-30`) and irregular stretches are all the same shape,
|
|
269
|
+
* and a single quote may mix them. Granularity is deliberately not stored —
|
|
270
|
+
* derive it from the span (see `formatSchedulePeriod`). (4.8.0)
|
|
271
|
+
*/
|
|
272
|
+
export interface SchedulePeriod {
|
|
273
|
+
/** ISO date, inclusive. */
|
|
274
|
+
periodStart: string;
|
|
275
|
+
/** ISO date, inclusive. */
|
|
276
|
+
periodEnd: string;
|
|
277
|
+
}
|
|
278
|
+
/** Row inside {@link Quote.effectiveVolumesByPeriod}. (4.8.0) */
|
|
279
|
+
export interface EffectiveVolumeByPeriod extends SchedulePeriod {
|
|
280
|
+
effectiveVolume: number;
|
|
281
|
+
}
|
|
282
|
+
/** Row inside {@link Quote.effectivePricesByPeriod}. Decimal-as-string, like
|
|
283
|
+
* {@link Quote.targetPrice}. (4.8.0) */
|
|
284
|
+
export interface EffectivePriceByPeriod extends SchedulePeriod {
|
|
285
|
+
effectiveUnitPrice: string;
|
|
286
|
+
}
|
|
234
287
|
export interface SetEffectiveCostInput {
|
|
235
288
|
unitCost: number;
|
|
236
289
|
/** 'cpq' | 'manual' | 'external' — declared by the adapter. */
|
|
@@ -285,6 +338,11 @@ export interface CreateQuoteInput {
|
|
|
285
338
|
eopPrecision?: SopEopPrecision;
|
|
286
339
|
effectiveAnnualVolume?: number;
|
|
287
340
|
effectiveVolumesByYear?: EffectiveVolumeByYear[];
|
|
341
|
+
/** Arbitrary-period committed volume. Non-empty makes the two fields above
|
|
342
|
+
* derived — passing either alongside it is a 422. (4.8.0) */
|
|
343
|
+
effectiveVolumesByPeriod?: EffectiveVolumeByPeriod[];
|
|
344
|
+
/** Arbitrary-period committed unit price. Storage only. (4.8.0) */
|
|
345
|
+
effectivePricesByPeriod?: EffectivePriceByPeriod[];
|
|
288
346
|
/**
|
|
289
347
|
* Quote type — defaults to 'rfq'. Immutable post-create. When 'eco',
|
|
290
348
|
* `referenceQuoteId` becomes REQUIRED and must point to an in-tenant,
|
|
@@ -296,6 +354,8 @@ export interface CreateQuoteInput {
|
|
|
296
354
|
baselineUnitPrice?: number | string;
|
|
297
355
|
/** ECO-only (422 otherwise): frozen as-awarded unit cost. (3.0.2) */
|
|
298
356
|
baselineUnitCost?: number | string;
|
|
357
|
+
/** Defaults to 'draft' (the model default) if omitted. */
|
|
358
|
+
quality?: 'draft' | 'verified';
|
|
299
359
|
}
|
|
300
360
|
/**
|
|
301
361
|
* Non-status fields only. Status changes go through `transitionStatus(...)`
|
|
@@ -325,6 +385,13 @@ export interface UpdateQuoteInput {
|
|
|
325
385
|
eopPrecision?: SopEopPrecision | null;
|
|
326
386
|
effectiveAnnualVolume?: number | null;
|
|
327
387
|
effectiveVolumesByYear?: EffectiveVolumeByYear[] | null;
|
|
388
|
+
/** Full replace. Non-empty makes the yearly fields derived (writing them is a
|
|
389
|
+
* 422); `null` or `[]` clears the schedule and hands them back. The last
|
|
390
|
+
* derived values are left in place — clearing stops maintaining them, it
|
|
391
|
+
* doesn't wipe the curve. (4.8.0) */
|
|
392
|
+
effectiveVolumesByPeriod?: EffectiveVolumeByPeriod[] | null;
|
|
393
|
+
/** Full replace. Storage only, independent of the volume schedule. (4.8.0) */
|
|
394
|
+
effectivePricesByPeriod?: EffectivePriceByPeriod[] | null;
|
|
328
395
|
quality?: 'draft' | 'verified';
|
|
329
396
|
}
|
|
330
397
|
export interface TransitionQuoteStatusInput {
|
|
@@ -374,8 +441,48 @@ export interface GetQuoteOptions {
|
|
|
374
441
|
export type EcStatus = 'requested' | 'triaged' | 'converted' | 'partially_applied' | 'applied' | 'cancelled';
|
|
375
442
|
/** Engineering-change driver taxonomy — mirrors CPQ's EcChangeDriver (F6). */
|
|
376
443
|
export type EcChangeDriver = 'material' | 'routing' | 'capital' | 'other';
|
|
377
|
-
/** Which app is writing — gated per-endpoint server-side.
|
|
378
|
-
|
|
444
|
+
/** Which app is writing — gated per-endpoint server-side. `bom` and `omsf` are
|
|
445
|
+
* create-only intake sources; convert + status are `cpq`/`admin`. */
|
|
446
|
+
export type EcCallerRole = 'omsf' | 'bom' | 'cpq' | 'admin';
|
|
447
|
+
/** A part/assembly reference inside {@link EngineeringChangeDetail}. */
|
|
448
|
+
export interface EngineeringChangeDetailPartRef {
|
|
449
|
+
partId: string;
|
|
450
|
+
partNumber: string;
|
|
451
|
+
name: string;
|
|
452
|
+
}
|
|
453
|
+
/** Per-BOM impact inside {@link EngineeringChangeDetail}. */
|
|
454
|
+
export interface EngineeringChangeDetailBomImpact {
|
|
455
|
+
bomType: string;
|
|
456
|
+
bomVersionId: string;
|
|
457
|
+
partsAffectedCount: number;
|
|
458
|
+
costDeltaCents: number;
|
|
459
|
+
marginDeltaBps: number | null;
|
|
460
|
+
annualImpactCents: number;
|
|
461
|
+
summary: string;
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Structured change detail authored by a rich intake source (BOM) so the EC is
|
|
465
|
+
* self-describing for CPQ + Program Management without reaching back into the
|
|
466
|
+
* originating app. Discriminated by `source`; validated server-side on write.
|
|
467
|
+
* Absent (null) for thin intake (OMSF sends free-text `description` only). See
|
|
468
|
+
* the BOM cutover plan bom/docs/plans/2026-07-23-bom-raises-engineering-change.md (D6).
|
|
469
|
+
*/
|
|
470
|
+
export interface EngineeringChangeDetail {
|
|
471
|
+
/** The only rich shape defined in v1. */
|
|
472
|
+
source: 'bom';
|
|
473
|
+
changeType: string;
|
|
474
|
+
fromValue: string | null;
|
|
475
|
+
toValue: string | null;
|
|
476
|
+
reason: string | null;
|
|
477
|
+
affectedParts: EngineeringChangeDetailPartRef[];
|
|
478
|
+
affectedAssemblies: EngineeringChangeDetailPartRef[];
|
|
479
|
+
affectedBoms: EngineeringChangeDetailBomImpact[];
|
|
480
|
+
totals: {
|
|
481
|
+
partsAffectedCount: number;
|
|
482
|
+
subassembliesAffectedCount: number;
|
|
483
|
+
totalCostDeltaCents: number;
|
|
484
|
+
};
|
|
485
|
+
}
|
|
379
486
|
/**
|
|
380
487
|
* An engineering change — the grouping entity correlating the N member ECO
|
|
381
488
|
* quotes one change fans out to. master-data owns this identity; OMSF and CPQ
|
|
@@ -404,6 +511,10 @@ export interface EngineeringChange {
|
|
|
404
511
|
/** Stored, inert in v1 — effectivity semantics (phasing, per-part) are not
|
|
405
512
|
* yet decided, so no consumer may compute off this. Date serialized as string. */
|
|
406
513
|
effectiveDate: string | null;
|
|
514
|
+
/** Structured change detail (D6) authored by a rich intake source (BOM).
|
|
515
|
+
* Null for thin intake (OMSF). Descriptive metadata — not structural
|
|
516
|
+
* membership (that stays quote-grain via {@link memberQuoteIds}). */
|
|
517
|
+
changeDetail: EngineeringChangeDetail | null;
|
|
407
518
|
createdAt: string;
|
|
408
519
|
updatedAt: string;
|
|
409
520
|
/** Member ECO quote ids (quote-grain membership). Populated on {@link get}. */
|
|
@@ -415,8 +526,11 @@ export interface CreateEngineeringChangeInput {
|
|
|
415
526
|
description: string;
|
|
416
527
|
requestedById: string;
|
|
417
528
|
requestedByName: string;
|
|
418
|
-
/** Gated server-side to 'omsf' | 'cpq'. */
|
|
529
|
+
/** Gated server-side to 'omsf' | 'bom' | 'cpq' | 'admin' (create is intake). */
|
|
419
530
|
callerRole: EcCallerRole;
|
|
531
|
+
/** Optional structured change detail (D6). Validated server-side against the
|
|
532
|
+
* {@link EngineeringChangeDetail} shape; omit for thin intake (OMSF). */
|
|
533
|
+
changeDetail?: EngineeringChangeDetail;
|
|
420
534
|
}
|
|
421
535
|
/** Fan-out conversion — CPQ stamps number, title, driver, and members. */
|
|
422
536
|
export interface ConvertEngineeringChangeInput {
|
|
@@ -558,6 +672,11 @@ export interface ListPlantsOptions {
|
|
|
558
672
|
cursor?: string;
|
|
559
673
|
sort?: string;
|
|
560
674
|
q?: string;
|
|
675
|
+
status?: 'active' | 'archived' | 'all';
|
|
676
|
+
/** @deprecated Never actually reached the backend filter (it reads
|
|
677
|
+
* `status`, not `active`) — use `status` instead. Kept only so any
|
|
678
|
+
* existing caller that sets this doesn't hit a type error; has no
|
|
679
|
+
* effect. */
|
|
561
680
|
active?: boolean;
|
|
562
681
|
country?: string;
|
|
563
682
|
region?: string;
|
|
@@ -965,6 +1084,10 @@ export interface ListEquipmentOptions {
|
|
|
965
1084
|
q?: string;
|
|
966
1085
|
plantId?: string;
|
|
967
1086
|
processFamily?: string;
|
|
1087
|
+
status?: 'active' | 'archived' | 'all';
|
|
1088
|
+
/** @deprecated Never actually reached the backend filter (it reads
|
|
1089
|
+
* `status`, not `active`) — use `status` instead. Kept only so any
|
|
1090
|
+
* existing caller that sets this doesn't hit a type error; has no effect. */
|
|
968
1091
|
active?: boolean;
|
|
969
1092
|
}
|
|
970
1093
|
export interface ProcessFamily {
|
|
@@ -1640,7 +1763,7 @@ export interface UpdateLocationInput {
|
|
|
1640
1763
|
country?: string;
|
|
1641
1764
|
}
|
|
1642
1765
|
export type ImportStatus = 'pending_upload' | 'pending_parse' | 'pending_mapping' | 'pending_validation' | 'validated' | 'committed' | 'failed';
|
|
1643
|
-
export type ImportEntityType = 'company' | 'contact' | 'location' | 'plant' | 'material' | 'rate_library' | 'rate_entries';
|
|
1766
|
+
export type ImportEntityType = 'company' | 'contact' | 'location' | 'plant' | 'material' | 'part' | 'part_category' | 'program' | 'rate_library' | 'rate_entries' | 'equipment' | 'process_family' | 'part_type' | 'exchange_rate' | 'quote' | 'part_attribute' | 'uom' | 'rate_line' | 'rate_grade';
|
|
1644
1767
|
export type ImportSheetAssignment = ImportEntityType | 'skip';
|
|
1645
1768
|
/** Identifies which app initiated an import session. Cross-app callers
|
|
1646
1769
|
* (anything other than 'master-data') are limited to a subset of entity
|
|
@@ -1657,7 +1780,7 @@ export type SourceApp = 'master-data' | 'erfq' | 'cpq' | 'bom' | 'forecast' | 'o
|
|
|
1657
1780
|
* "Empty" means SQL NULL only — a stored '', 0, false, or 0.0 counts as
|
|
1658
1781
|
* populated and will not be overwritten by fill_empty. */
|
|
1659
1782
|
export type MergePolicy = 'overwrite' | 'fill_empty';
|
|
1660
|
-
export type ImportTargetField = 'name' | 'legalName' | 'code' | 'taxId' | 'dunsNumber' | 'website' | 'logoUrl' | 'roles' | 'email' | 'phone' | 'role' | 'type' | 'description' | 'street' | 'city' | 'stateProvince' | 'postalCode' | 'country' | 'category' | 'parent_company_ref' | 'companyCode' | 'locationCode' | 'region' | 'headcount' | 'annualCapacityHours' | 'currentUtilization' | 'riskLevel' | 'numShifts' | 'hoursPerShift' | 'workingDaysPerYear' | 'indirectHeadcountPct' | 'currency' | 'effectiveDate' | 'effectiveTo' | 'libraryCode' | 'kind' | 'plantCode' | 'skillTier' | 'materialCode' | 'regionCode' | 'lane' | 'rate' | 'unit' | 'sourcingMode' | 'indexRef' | 'notes';
|
|
1783
|
+
export type ImportTargetField = 'name' | 'legalName' | 'code' | 'taxId' | 'dunsNumber' | 'website' | 'logoUrl' | 'roles' | 'email' | 'phone' | 'role' | 'type' | 'description' | 'street' | 'city' | 'stateProvince' | 'postalCode' | 'country' | 'category' | 'parent_company_ref' | 'companyCode' | 'locationCode' | 'region' | 'headcount' | 'annualCapacityHours' | 'currentUtilization' | 'riskLevel' | 'numShifts' | 'hoursPerShift' | 'workingDaysPerYear' | 'indirectHeadcountPct' | 'currency' | 'effectiveDate' | 'effectiveTo' | 'libraryCode' | 'kind' | 'plantCode' | 'skillTier' | 'materialCode' | 'regionCode' | 'lane' | 'rate' | 'unit' | 'sourcingMode' | 'indexRef' | 'notes' | 'partNumber' | 'manufacturingPartNumber' | 'customerPartNumber' | 'partType' | 'manufacturer' | 'partCategoryCode' | 'quality' | 'revision' | 'uom' | 'weightPerUnit' | 'recycledPct' | 'pcfPerUnit' | 'releaseStatus' | 'leadTime' | 'customerCompanyCode' | 'customerCompanyName' | 'sopDate' | 'eopDate' | 'displayOrder' | 'label' | 'sortOrder' | 'processFamily' | 'capacityHoursPerYear' | 'cavities' | 'availabilityPct' | 'performancePct' | 'defaultHeadcount' | 'defaultAutomationPct' | 'defaultMachinesPerOperator' | 'defaultSetupCrew' | 'perUsd' | 'effectiveFrom' | 'quoteNumber' | 'programCode' | 'partId' | 'regionName' | 'annualVolume' | 'apw' | 'mpw' | 'targetPrice' | 'dueDate' | 'key' | 'dataType' | 'options' | 'group' | 'required' | 'min' | 'max' | 'regex' | 'precision' | 'basis' | 'bindings' | 'perBaseFactor' | 'needsDensity' | 'binding' | 'allowedUoms' | 'defaultUom' | 'escalationDefault' | 'density' | 'densityUnit';
|
|
1661
1784
|
export interface ImportSession {
|
|
1662
1785
|
id: string;
|
|
1663
1786
|
tenantId: string;
|
|
@@ -1682,7 +1805,7 @@ export interface CreateImportInput {
|
|
|
1682
1805
|
filename: string;
|
|
1683
1806
|
/** Session root entity type. The workbook may contain other entity types in
|
|
1684
1807
|
* additional sheets, but this names the "primary" import. */
|
|
1685
|
-
entityType: 'company' | 'plant' | 'material' | 'rate_library';
|
|
1808
|
+
entityType: 'company' | 'plant' | 'material' | 'part' | 'part_category' | 'program' | 'rate_library' | 'equipment' | 'process_family' | 'part_type' | 'exchange_rate' | 'quote' | 'part_attribute' | 'uom';
|
|
1686
1809
|
/** Which app is initiating this upload. Cross-app callers (non-'master-data')
|
|
1687
1810
|
* are gated to a subset of entity types via the server's allowlist. Default
|
|
1688
1811
|
* is 'master-data'. */
|
|
@@ -1895,6 +2018,10 @@ export interface ImportCommitResult {
|
|
|
1895
2018
|
locations?: BatchCreateChildResult;
|
|
1896
2019
|
plants?: BatchCreateChildResult;
|
|
1897
2020
|
materials?: BatchCreateMaterialsResult;
|
|
2021
|
+
/** Parts share the material-style extended summary (mergedFields/untouched). */
|
|
2022
|
+
parts?: BatchCreateMaterialsResult;
|
|
2023
|
+
programs?: BatchCreateChildResult;
|
|
2024
|
+
partCategories?: BatchCreateChildResult;
|
|
1898
2025
|
rateLibraries?: BatchCreateChildResult;
|
|
1899
2026
|
rateEntries?: BatchCreateChildResult;
|
|
1900
2027
|
/** Child rows skipped because their parent failed to commit (contacts /
|
|
@@ -1903,6 +2030,32 @@ export interface ImportCommitResult {
|
|
|
1903
2030
|
* materialCode/regionCode didn't resolve). */
|
|
1904
2031
|
orphansSkipped: number;
|
|
1905
2032
|
}
|
|
2033
|
+
/** Downloadable blank import template. Served inline as base64 (no storage
|
|
2034
|
+
* round-trip; works identically in local dev and prod). The client decodes
|
|
2035
|
+
* `contentBase64` → Blob and triggers a browser download. */
|
|
2036
|
+
export interface TemplateDownload {
|
|
2037
|
+
filename: string;
|
|
2038
|
+
mimeType: string;
|
|
2039
|
+
contentBase64: string;
|
|
2040
|
+
}
|
|
2041
|
+
/** Result envelope for bulk archive / restore. `ok` counts rows whose status
|
|
2042
|
+
* flipped (or were already in the target state — idempotent). */
|
|
2043
|
+
export interface BulkArchiveResult {
|
|
2044
|
+
results: Array<{
|
|
2045
|
+
id: string;
|
|
2046
|
+
status: 'ok';
|
|
2047
|
+
} | {
|
|
2048
|
+
id: string;
|
|
2049
|
+
status: 'error';
|
|
2050
|
+
error: string;
|
|
2051
|
+
code: string;
|
|
2052
|
+
}>;
|
|
2053
|
+
summary: {
|
|
2054
|
+
total: number;
|
|
2055
|
+
ok: number;
|
|
2056
|
+
errors: number;
|
|
2057
|
+
};
|
|
2058
|
+
}
|
|
1906
2059
|
export interface ApiMeta {
|
|
1907
2060
|
requestId: string;
|
|
1908
2061
|
timestamp: string;
|