@configura/web-api 2.0.0-alpha.20 → 2.0.0-alpha.22

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.
Files changed (32) hide show
  1. package/.eslintrc.json +1 -14
  2. package/dist/CatalogueAPI.d.ts +41 -0
  3. package/dist/CatalogueAPI.js +1 -0
  4. package/dist/CfgProduct.d.ts +29 -15
  5. package/dist/CfgProduct.js +172 -55
  6. package/dist/ConfigurationConverter.d.ts +4 -0
  7. package/dist/ConfigurationConverter.js +9 -0
  8. package/dist/io/CfgHistoryManager.js +0 -6
  9. package/dist/io/CfgHistoryToProdConfConnector.d.ts +6 -2
  10. package/dist/io/CfgHistoryToProdConfConnector.js +11 -8
  11. package/dist/io/CfgIOProdConfConnector.d.ts +17 -9
  12. package/dist/io/CfgIOProdConfConnector.js +48 -57
  13. package/dist/io/CfgObservableStateToProdConfConnector.d.ts +2 -2
  14. package/dist/io/CfgObservableStateToProdConfConnector.js +3 -3
  15. package/dist/io/CfgWindowMessageToProdConfConnector.d.ts +2 -2
  16. package/dist/io/CfgWindowMessageToProdConfConnector.js +3 -3
  17. package/dist/productConfiguration/CfgFeature.d.ts +5 -1
  18. package/dist/productConfiguration/CfgFeature.js +13 -0
  19. package/dist/productConfiguration/CfgOption.d.ts +6 -1
  20. package/dist/productConfiguration/CfgOption.js +17 -0
  21. package/dist/productLoader.js +1 -1
  22. package/dist/syncGroups/SyncGroupsHandler.d.ts +5 -1
  23. package/dist/syncGroups/SyncGroupsHandler.js +9 -2
  24. package/dist/syncGroups/SyncGroupsState.d.ts +5 -1
  25. package/dist/syncGroups/SyncGroupsState.js +44 -2
  26. package/dist/tests/testData/testDataAdditionalProductInAdditionalProductInProductForTest.js +14 -10
  27. package/dist/tests/testData/testDataCachedGetProduct.js +2 -1
  28. package/dist/tests/testData/testDataCachedPostValidate.js +1 -0
  29. package/dist/tests/testData/testDataProductAggregatedPrice.js +2 -1
  30. package/dist/tests/testData/testDataUpcharge.js +1 -0
  31. package/dist/utilitiesNumericValues.js +13 -8
  32. package/package.json +3 -3
@@ -19,17 +19,27 @@ export var CfgProdConfMessageVersions;
19
19
  CfgProdConfMessageVersions[CfgProdConfMessageVersions["V1dot0"] = 1] = "V1dot0";
20
20
  CfgProdConfMessageVersions[CfgProdConfMessageVersions["V2dot0"] = 2] = "V2dot0";
21
21
  })(CfgProdConfMessageVersions || (CfgProdConfMessageVersions = {}));
22
+ /**
23
+ * @param ExtendedData Includes extra data, i.e. units and groupCodes
24
+ * @param ProductParams Includes what Product this was generated for, and the same for any Additional Products.
25
+ * @param SyncGroupState Includes the current sync group state
26
+ */
27
+ export var CfgProdConfParts;
28
+ (function (CfgProdConfParts) {
29
+ CfgProdConfParts[CfgProdConfParts["NoExtra"] = 0] = "NoExtra";
30
+ CfgProdConfParts[CfgProdConfParts["ExtendedData"] = 1] = "ExtendedData";
31
+ CfgProdConfParts[CfgProdConfParts["ProdParams"] = 2] = "ProdParams";
32
+ CfgProdConfParts[CfgProdConfParts["SyncGroupState"] = 4] = "SyncGroupState";
33
+ })(CfgProdConfParts || (CfgProdConfParts = {}));
22
34
  export const STAGE_PROD_CONF_MESSAGE_KEY = "stageprodconf";
23
35
  /**
24
36
  * Base class for connecting the product configuration to an IO channel
25
37
  */
26
38
  export class CfgIOProdConfConnector {
27
- constructor(_ioManager, _includeExtendedDataInSend, // Only for v2.0
28
- _includeProdParamsInSend // Only for v2.0
39
+ constructor(_ioManager, _includeInSend // Only for v2.0
29
40
  ) {
30
41
  this._ioManager = _ioManager;
31
- this._includeExtendedDataInSend = _includeExtendedDataInSend;
32
- this._includeProdParamsInSend = _includeProdParamsInSend;
42
+ this._includeInSend = _includeInSend;
33
43
  this._stopListenToMessage = undefined;
34
44
  this._stopListenToProdConf = undefined;
35
45
  this.setProduct = (product) => __awaiter(this, void 0, void 0, function* () {
@@ -50,19 +60,7 @@ export class CfgIOProdConfConnector {
50
60
  if (newProduct === undefined) {
51
61
  return;
52
62
  }
53
- // We only try to load initial configuration at first load
54
- if (currentProduct === undefined) {
55
- try {
56
- const initialProdConf = this.getInitialProdConf();
57
- if (initialProdConf !== undefined) {
58
- yield newProduct.setDtoConf(initialProdConf);
59
- }
60
- }
61
- catch (err) {
62
- console.error(err);
63
- }
64
- }
65
- this._send(this.makeSendData(newProduct.getDtoConf(this._includeExtendedDataInSend, this._includeProdParamsInSend), true));
63
+ this._send(this.makeSendData(newProduct.getDtoConf(this._includeInSend), true));
66
64
  this._stopListenToMessage = CfgIOProdConfConnector.listenForMessage((messages) => __awaiter(this, void 0, void 0, function* () {
67
65
  const subMessages = messages.subMessages;
68
66
  if (subMessages.length === 0) {
@@ -80,7 +78,7 @@ export class CfgIOProdConfConnector {
80
78
  }
81
79
  throw new Error("Unknown message version");
82
80
  }), this._ioManager);
83
- this._stopListenToProdConf = CfgIOProdConfConnector.listenForProdConf(newProduct, (conf) => __awaiter(this, void 0, void 0, function* () { return this._send(this.makeSendData(conf, false)); }), this._includeExtendedDataInSend, this._includeProdParamsInSend);
81
+ this._stopListenToProdConf = CfgIOProdConfConnector.listenForProdConf(newProduct, (conf) => __awaiter(this, void 0, void 0, function* () { return this._send(this.makeSendData(conf, false)); }), this._includeInSend);
84
82
  });
85
83
  this._send = (data) => this._ioManager.send(STAGE_PROD_CONF_MESSAGE_KEY, data);
86
84
  _ioManager.addWarningSupplier(this);
@@ -100,35 +98,6 @@ export class CfgIOProdConfConnector {
100
98
  }
101
99
  return [];
102
100
  }
103
- getInitialProdConf() {
104
- return undefined;
105
- }
106
- static makeMessage(conf, initial, sendVersions) {
107
- const result = [];
108
- if ((sendVersions & CfgProdConfMessageVersions.V1dot0) ===
109
- CfgProdConfMessageVersions.V1dot0) {
110
- const v1 = {
111
- version: "1.0",
112
- conf: convertDtoProductConfToV1(conf, true),
113
- };
114
- result.push(v1);
115
- }
116
- if ((sendVersions & CfgProdConfMessageVersions.V2dot0) ===
117
- CfgProdConfMessageVersions.V2dot0) {
118
- const v2 = {
119
- version: "2.0",
120
- conf,
121
- };
122
- result.push(v2);
123
- }
124
- return { subMessages: result, initial };
125
- }
126
- static makeMessageListener(callback) {
127
- return (message) => __awaiter(this, void 0, void 0, function* () {
128
- const prodConfMessage = message;
129
- yield callback(prodConfMessage);
130
- });
131
- }
132
101
  /**
133
102
  * Register the callback to listen for Product Configuration messages
134
103
  * @returns A function which when called will cancel listening
@@ -140,19 +109,41 @@ export class CfgIOProdConfConnector {
140
109
  ioManager.stopListenForMessage(listener);
141
110
  };
142
111
  }
143
- static makeProdConfListener(callback, includeExtendedDataInSend, includeProdParamsInSend) {
144
- return (n) => {
145
- if (!n.committed) {
146
- return;
147
- }
148
- callback(n.freshRef.getDtoConf(includeExtendedDataInSend, includeProdParamsInSend));
149
- };
150
- }
151
- static listenForProdConf(product, callback, includeExtendedDataInSend, includeProdParamsInSend) {
152
- const listener = this.makeProdConfListener(callback, includeExtendedDataInSend, includeProdParamsInSend);
112
+ static listenForProdConf(product, callback, includeInSend) {
113
+ const listener = this.makeProdConfListener(callback, includeInSend);
153
114
  product.listenForChange(listener);
154
115
  return () => {
155
116
  product.stopListenForChange(listener);
156
117
  };
157
118
  }
158
119
  }
120
+ CfgIOProdConfConnector.makeMessage = (conf, initial, sendVersions) => {
121
+ const result = [];
122
+ if ((sendVersions & CfgProdConfMessageVersions.V1dot0) ===
123
+ CfgProdConfMessageVersions.V1dot0) {
124
+ const v1 = {
125
+ version: "1.0",
126
+ conf: convertDtoProductConfToV1(conf, true),
127
+ };
128
+ result.push(v1);
129
+ }
130
+ if ((sendVersions & CfgProdConfMessageVersions.V2dot0) ===
131
+ CfgProdConfMessageVersions.V2dot0) {
132
+ const v2 = {
133
+ version: "2.0",
134
+ conf,
135
+ };
136
+ result.push(v2);
137
+ }
138
+ return { subMessages: result, initial };
139
+ };
140
+ CfgIOProdConfConnector.makeMessageListener = (callback) => (message) => __awaiter(void 0, void 0, void 0, function* () {
141
+ const prodConfMessage = message;
142
+ yield callback(prodConfMessage);
143
+ });
144
+ CfgIOProdConfConnector.makeProdConfListener = (callback, includeInSend) => (n) => {
145
+ if (!n.committed) {
146
+ return;
147
+ }
148
+ callback(n.freshRef.getDtoConf(includeInSend));
149
+ };
@@ -1,5 +1,5 @@
1
1
  import { DtoProductConf } from "../CatalogueAPI.js";
2
- import { CfgIOProdConfConnector, CfgProdConfMessage, CfgProdConfMessageVersions } from "./CfgIOProdConfConnector.js";
2
+ import { CfgIOProdConfConnector, CfgProdConfMessage, CfgProdConfMessageVersions, CfgProdConfParts } from "./CfgIOProdConfConnector.js";
3
3
  import { CfgObservableStateManager } from "./CfgObservableStateManager.js";
4
4
  /**
5
5
  * Instantiating this will make the observable state update with the product configuration.
@@ -9,7 +9,7 @@ import { CfgObservableStateManager } from "./CfgObservableStateManager.js";
9
9
  */
10
10
  export declare class CfgObservableStateToProdConfConnector extends CfgIOProdConfConnector<CfgProdConfMessage> {
11
11
  private _sendVersions;
12
- constructor(manager: CfgObservableStateManager, _sendVersions?: CfgProdConfMessageVersions, includeExtendedDataInSend?: boolean, includeProdParamsInSend?: boolean);
12
+ constructor(manager: CfgObservableStateManager, _sendVersions?: CfgProdConfMessageVersions, includeInSend?: CfgProdConfParts);
13
13
  protected makeSendData(conf: DtoProductConf, initial: boolean): CfgProdConfMessage;
14
14
  }
15
15
  //# sourceMappingURL=CfgObservableStateToProdConfConnector.d.ts.map
@@ -1,4 +1,4 @@
1
- import { CfgIOProdConfConnector, CfgProdConfMessageVersions, } from "./CfgIOProdConfConnector.js";
1
+ import { CfgIOProdConfConnector, CfgProdConfMessageVersions, CfgProdConfParts, } from "./CfgIOProdConfConnector.js";
2
2
  /**
3
3
  * Instantiating this will make the observable state update with the product configuration.
4
4
  * @param sendVersions What versions of the productConfiguration shall be sent? Multiple can be selected
@@ -6,8 +6,8 @@ import { CfgIOProdConfConnector, CfgProdConfMessageVersions, } from "./CfgIOProd
6
6
  * @param includeProdParamsInSend Only for version 2.0. Includes product params, in both main and additional products.
7
7
  */
8
8
  export class CfgObservableStateToProdConfConnector extends CfgIOProdConfConnector {
9
- constructor(manager, _sendVersions = CfgProdConfMessageVersions.V2dot0, includeExtendedDataInSend = false, includeProdParamsInSend = false) {
10
- super(manager, includeExtendedDataInSend, includeProdParamsInSend);
9
+ constructor(manager, _sendVersions = CfgProdConfMessageVersions.V2dot0, includeInSend = CfgProdConfParts.NoExtra) {
10
+ super(manager, includeInSend);
11
11
  this._sendVersions = _sendVersions;
12
12
  }
13
13
  makeSendData(conf, initial) {
@@ -1,5 +1,5 @@
1
1
  import { DtoProductConf } from "../CatalogueAPI.js";
2
- import { CfgIOProdConfConnector, CfgProdConfMessage, CfgProdConfMessageVersions } from "./CfgIOProdConfConnector.js";
2
+ import { CfgIOProdConfConnector, CfgProdConfMessage, CfgProdConfMessageVersions, CfgProdConfParts } from "./CfgIOProdConfConnector.js";
3
3
  import { CfgWindowMessageManager } from "./CfgWindowMessageManager.js";
4
4
  /**
5
5
  * Instantiating this will make Stage send product configuration changes using the post message-API.
@@ -11,7 +11,7 @@ import { CfgWindowMessageManager } from "./CfgWindowMessageManager.js";
11
11
  */
12
12
  export declare class CfgWindowMessageToProdConfConnector extends CfgIOProdConfConnector<CfgProdConfMessage> {
13
13
  private _sendVersions;
14
- constructor(manager: CfgWindowMessageManager, _sendVersions?: CfgProdConfMessageVersions, includeExtendedDataInSend?: boolean, includeProdParamsInSend?: boolean);
14
+ constructor(manager: CfgWindowMessageManager, _sendVersions?: CfgProdConfMessageVersions, includeInSend?: CfgProdConfParts);
15
15
  protected makeSendData(conf: DtoProductConf, initial: boolean): CfgProdConfMessage;
16
16
  }
17
17
  //# sourceMappingURL=CfgWindowMessageToProdConfConnector.d.ts.map
@@ -1,4 +1,4 @@
1
- import { CfgIOProdConfConnector, CfgProdConfMessageVersions, } from "./CfgIOProdConfConnector.js";
1
+ import { CfgIOProdConfConnector, CfgProdConfMessageVersions, CfgProdConfParts, } from "./CfgIOProdConfConnector.js";
2
2
  /**
3
3
  * Instantiating this will make Stage send product configuration changes using the post message-API.
4
4
  * It will also make Stage listen for incoming product configuration update messages.
@@ -8,8 +8,8 @@ import { CfgIOProdConfConnector, CfgProdConfMessageVersions, } from "./CfgIOProd
8
8
  * @param includeProdParamsInSend Only for version 2.0. Includes product params, in both main and additional products.
9
9
  */
10
10
  export class CfgWindowMessageToProdConfConnector extends CfgIOProdConfConnector {
11
- constructor(manager, _sendVersions = CfgProdConfMessageVersions.V2dot0, includeExtendedDataInSend = false, includeProdParamsInSend = false) {
12
- super(manager, includeExtendedDataInSend, includeProdParamsInSend);
11
+ constructor(manager, _sendVersions = CfgProdConfMessageVersions.V2dot0, includeInSend = CfgProdConfParts.NoExtra) {
12
+ super(manager, includeInSend);
13
13
  this._sendVersions = _sendVersions;
14
14
  }
15
15
  makeSendData(conf, initial) {
@@ -1,5 +1,5 @@
1
1
  import { LengthUnit, Observable, SingleArgCallback } from "@configura/web-utilities";
2
- import { DtoFeature, DtoFeatureConf, DtoSelectedOption, DtoSyncGroup, DtoSyncGroupMethods } from "../CatalogueAPI.js";
2
+ import { DtoFeature, DtoFeatureConf, DtoNote, DtoSelectedOption, DtoSyncGroup, DtoSyncGroupMethods } from "../CatalogueAPI.js";
3
3
  import { CfgProduct, _CfgProductInternal } from "../CfgProduct.js";
4
4
  import { CfgMtrlApplication } from "../material/CfgMtrlApplication.js";
5
5
  import { SyncCode } from "../syncGroups/SyncGroupsHandler.js";
@@ -50,10 +50,12 @@ export declare class _CfgFeatureInternal {
50
50
  get groupCode(): string | undefined;
51
51
  get key(): string;
52
52
  set key(k: string);
53
+ get notes(): DtoNote[];
53
54
  get isUseNumericValue(): boolean;
54
55
  get numericValue(): number | undefined;
55
56
  setNumericValue: (val: number) => Promise<boolean>;
56
57
  get description(): string;
58
+ get omitOnOrder(): boolean;
57
59
  get syncGroup(): DtoSyncGroup | undefined;
58
60
  /**
59
61
  * @return one of the following, in order:
@@ -150,6 +152,7 @@ export declare class CfgFeature {
150
152
  get key(): string;
151
153
  get code(): string;
152
154
  get groupCode(): string | undefined;
155
+ get notes(): DtoNote[];
153
156
  /**
154
157
  * If true the options in the feature is selected by both sending its code and numeric value
155
158
  * when selecting.
@@ -164,6 +167,7 @@ export declare class CfgFeature {
164
167
  setNumericValue: (val: number) => Promise<boolean>;
165
168
  get unit(): LengthUnit;
166
169
  get description(): string;
170
+ get omitOnOrder(): boolean;
167
171
  get hasUpcharge(): boolean | undefined;
168
172
  get selectedOptions(): CfgOption[];
169
173
  /** Are all ancestors up to the CfgProductConfiguration selected? */
@@ -419,6 +419,10 @@ export class _CfgFeatureInternal {
419
419
  set key(k) {
420
420
  this._key = k;
421
421
  }
422
+ get notes() {
423
+ var _a;
424
+ return this.parentProduct.getNotes((_a = this.rawFeature.noteRefs) !== null && _a !== void 0 ? _a : []);
425
+ }
422
426
  get isUseNumericValue() {
423
427
  return this.rawFeature.numericOrder;
424
428
  }
@@ -442,6 +446,9 @@ export class _CfgFeatureInternal {
442
446
  get description() {
443
447
  return this.rawFeature.description;
444
448
  }
449
+ get omitOnOrder() {
450
+ return this.rawFeature.omitOnOrder === true;
451
+ }
445
452
  get syncGroup() {
446
453
  return this.rawFeature.syncGroup;
447
454
  }
@@ -613,6 +620,9 @@ export class CfgFeature {
613
620
  get groupCode() {
614
621
  return this._internal.groupCode;
615
622
  }
623
+ get notes() {
624
+ return this._internal.notes;
625
+ }
616
626
  /**
617
627
  * If true the options in the feature is selected by both sending its code and numeric value
618
628
  * when selecting.
@@ -630,6 +640,9 @@ export class CfgFeature {
630
640
  get description() {
631
641
  return this._internal.description;
632
642
  }
643
+ get omitOnOrder() {
644
+ return this._internal.omitOnOrder;
645
+ }
633
646
  get hasUpcharge() {
634
647
  return this._internal.hasUpcharge;
635
648
  }
@@ -1,5 +1,5 @@
1
1
  import { LengthUnit, Observable, SingleArgCallback } from "@configura/web-utilities";
2
- import { DtoFeature, DtoOption, DtoOptionConf, DtoSelectedOption } from "../CatalogueAPI.js";
2
+ import { DtoFeature, DtoMiscFile, DtoNote, DtoOption, DtoOptionConf, DtoSelectedOption } from "../CatalogueAPI.js";
3
3
  import { CfgProduct, _CfgProductInternal } from "../CfgProduct.js";
4
4
  import { CfgMtrlApplication } from "../material/CfgMtrlApplication.js";
5
5
  import { NumericValuesSelection } from "../utilitiesNumericValues.js";
@@ -74,6 +74,8 @@ export declare class _CfgOptionInternal {
74
74
  isAllowedNumericValue(val: number): boolean;
75
75
  readonly changeObservable: Observable<OptionChangeNotification>;
76
76
  get code(): string;
77
+ get notes(): DtoNote[];
78
+ get miscFiles(): DtoMiscFile[];
77
79
  get isUseNumericValue(): boolean;
78
80
  get numericValue(): number | undefined;
79
81
  setNumericValue(val: number, doSelectOption: boolean): Promise<boolean>;
@@ -114,10 +116,13 @@ export declare class CfgOption {
114
116
  private constructor();
115
117
  isBackedBySame: (other: CfgOption) => boolean;
116
118
  get parentProduct(): CfgProduct;
119
+ get parent(): CfgFeature;
117
120
  get rootProduct(): CfgProduct;
118
121
  get rawOption(): DtoOption;
119
122
  get key(): string;
120
123
  get code(): string;
124
+ get notes(): DtoNote[];
125
+ get miscFiles(): DtoMiscFile[];
121
126
  get isUseNumericValue(): boolean;
122
127
  get numericValue(): number | undefined;
123
128
  setNumericValue: (val: number, doSelectOption: boolean) => Promise<boolean>;
@@ -206,6 +206,14 @@ export class _CfgOptionInternal {
206
206
  get code() {
207
207
  return this.rawOption.code;
208
208
  }
209
+ get notes() {
210
+ var _a;
211
+ return this.parentProduct.getNotes((_a = this.rawOption.noteRefs) !== null && _a !== void 0 ? _a : []);
212
+ }
213
+ get miscFiles() {
214
+ var _a;
215
+ return (_a = this.rawOption.miscFiles) !== null && _a !== void 0 ? _a : [];
216
+ }
209
217
  get isUseNumericValue() {
210
218
  return this.parent.isUseNumericValue;
211
219
  }
@@ -363,6 +371,9 @@ export class CfgOption {
363
371
  get parentProduct() {
364
372
  return CfgProduct._makeNewRefFrom(this._internal.parentProduct);
365
373
  }
374
+ get parent() {
375
+ return CfgFeature._makeNewRefFrom(this._internal.parent);
376
+ }
366
377
  get rootProduct() {
367
378
  return CfgProduct._makeNewRefFrom(this._internal.rootProduct);
368
379
  }
@@ -375,6 +386,12 @@ export class CfgOption {
375
386
  get code() {
376
387
  return this._internal.code;
377
388
  }
389
+ get notes() {
390
+ return this._internal.notes;
391
+ }
392
+ get miscFiles() {
393
+ return this._internal.miscFiles;
394
+ }
378
395
  get isUseNumericValue() {
379
396
  return this._internal.isUseNumericValue;
380
397
  }
@@ -37,7 +37,7 @@ export function wrapWithGetProductCache(getProduct) {
37
37
  export function wrapWithPostValidateCache(postValidate) {
38
38
  const cache = new PromiseCache();
39
39
  return (params, body) => __awaiter(this, void 0, void 0, function* () {
40
- return cache.get(`${makeProductKey(params)}-${makeSelOptionsKey(body.selOptions)}`, () => postValidate(params, body));
40
+ return cache.get(`${makeProductKey(params)}-${makeSelOptionsKey(body.selOptions)}-${body.knownFeatureCodes.join(",")}`, () => postValidate(params, body));
41
41
  });
42
42
  }
43
43
  /** Does both wrapWithGetProductCache and wrapWithPostValidateCache. */
@@ -1,4 +1,5 @@
1
1
  import { AggregatedLoadingObservable } from "@configura/web-utilities";
2
+ import { DtoSyncGroupState } from "../CatalogueAPI.js";
2
3
  import { _CfgProductInternal } from "../CfgProduct.js";
3
4
  import { _CfgOptionInternal } from "../productConfiguration/CfgOption.js";
4
5
  import { ProductLoader } from "../productLoader.js";
@@ -18,10 +19,13 @@ export declare class SyncGroupsHandler {
18
19
  /**
19
20
  * @param verboseLogging Set to true to get verbose sync state changes logged to the console.
20
21
  */
21
- static make(updateMode?: SyncGroupsApplyMode, loadingObservable?: AggregatedLoadingObservable, verboseLogging?: boolean): SyncGroupsHandler;
22
+ static make(updateMode?: SyncGroupsApplyMode, loadingObservable?: AggregatedLoadingObservable, initial?: DtoSyncGroupState, verboseLogging?: boolean): SyncGroupsHandler;
22
23
  private constructor();
23
24
  /** Please note that clones will use the same loadingObservable as their source. */
24
25
  clone(): SyncGroupsHandler;
26
+ getCompactSyncGroupState(): DtoSyncGroupState;
27
+ /** Overwrites the sync state */
28
+ setCompactSyncGroupState(s: DtoSyncGroupState): void;
25
29
  get verboseLogging(): boolean;
26
30
  set verboseLogging(v: boolean);
27
31
  /**
@@ -263,13 +263,20 @@ export class SyncGroupsHandler {
263
263
  /**
264
264
  * @param verboseLogging Set to true to get verbose sync state changes logged to the console.
265
265
  */
266
- static make(updateMode = SyncGroupsApplyMode.Strict, loadingObservable, verboseLogging = false) {
267
- return new SyncGroupsHandler(new SyncGroupsState(verboseLogging), updateMode, loadingObservable);
266
+ static make(updateMode = SyncGroupsApplyMode.Strict, loadingObservable, initial, verboseLogging = false) {
267
+ return new SyncGroupsHandler(new SyncGroupsState(verboseLogging, initial), updateMode, loadingObservable);
268
268
  }
269
269
  /** Please note that clones will use the same loadingObservable as their source. */
270
270
  clone() {
271
271
  return new SyncGroupsHandler(this._syncState.clone(), this.updateMode, this._loadingObservable);
272
272
  }
273
+ getCompactSyncGroupState() {
274
+ return this._syncState.getCompact();
275
+ }
276
+ /** Overwrites the sync state */
277
+ setCompactSyncGroupState(s) {
278
+ this._syncState.setCompact(s);
279
+ }
273
280
  get verboseLogging() {
274
281
  return this._syncState.verboseLogging;
275
282
  }
@@ -1,3 +1,4 @@
1
+ import { DtoSyncGroupState } from "../CatalogueAPI.js";
1
2
  import { OptionCode, SyncCode } from "./SyncGroupsHandler.js";
2
3
  /**
3
4
  * The SyncState is used to keep track of the current value of the SyncGroups.
@@ -12,7 +13,7 @@ export declare class SyncGroupsState {
12
13
  /**
13
14
  * @param verboseLogging Set to true to get verbose sync state changes logged to the console.
14
15
  */
15
- constructor(_verboseLogging: boolean);
16
+ constructor(_verboseLogging: boolean, initial: DtoSyncGroupState | undefined);
16
17
  get verboseLogging(): boolean;
17
18
  /**
18
19
  * Set to true to get verbose sync state changes logged to the console.
@@ -31,6 +32,9 @@ export declare class SyncGroupsState {
31
32
  setForSelectMany(syncCode: SyncCode, optionCode: OptionCode, selected: boolean): void;
32
33
  getForSelectOne(syncCode: SyncCode): OptionCode | undefined;
33
34
  getForSelectMany(syncCode: SyncCode, optionCode: OptionCode): boolean | undefined;
35
+ /** Overrides the current sync state */
36
+ setCompact(s: DtoSyncGroupState): void;
37
+ getCompact(): DtoSyncGroupState;
34
38
  log(syncCode?: SyncCode, optionCode?: OptionCode, selected?: boolean): void;
35
39
  }
36
40
  //# sourceMappingURL=SyncGroupsState.d.ts.map
@@ -8,10 +8,11 @@ export class SyncGroupsState {
8
8
  /**
9
9
  * @param verboseLogging Set to true to get verbose sync state changes logged to the console.
10
10
  */
11
- constructor(_verboseLogging) {
11
+ constructor(_verboseLogging, initial) {
12
12
  this._verboseLogging = _verboseLogging;
13
13
  this._selectOne = new Map();
14
14
  this._selectMany = new Map();
15
+ this.setCompact(initial !== null && initial !== void 0 ? initial : {});
15
16
  }
16
17
  get verboseLogging() {
17
18
  return this._verboseLogging;
@@ -26,7 +27,7 @@ export class SyncGroupsState {
26
27
  * @returns a deep copy of the SyncGroupState.
27
28
  */
28
29
  clone() {
29
- return new SyncGroupsState(this._verboseLogging).copyFrom(this);
30
+ return new SyncGroupsState(this._verboseLogging, this.getCompact());
30
31
  }
31
32
  /**
32
33
  * Replaces the internal state of this SyncGroupState with a deep copy of the one in source.
@@ -67,6 +68,47 @@ export class SyncGroupsState {
67
68
  var _a;
68
69
  return (_a = this._selectMany.get(syncCode)) === null || _a === void 0 ? void 0 : _a.get(optionCode);
69
70
  }
71
+ /** Overrides the current sync state */
72
+ setCompact(s) {
73
+ this._selectOne.clear();
74
+ this._selectMany.clear();
75
+ const { selectOne, selectMany } = s;
76
+ if (selectOne !== undefined) {
77
+ for (const { syncCode, optionCode } of selectOne) {
78
+ this._selectOne.set(syncCode, optionCode);
79
+ }
80
+ }
81
+ if (selectMany !== undefined) {
82
+ for (const { syncCode, optionCode, selected } of selectMany) {
83
+ let entry = this._selectMany.get(syncCode);
84
+ if (entry === undefined) {
85
+ entry = new Map();
86
+ this._selectMany.set(syncCode, entry);
87
+ }
88
+ entry.set(optionCode, selected);
89
+ }
90
+ }
91
+ }
92
+ getCompact() {
93
+ const result = {};
94
+ if (this._selectOne.size !== 0) {
95
+ const resultSelectOne = [];
96
+ for (const [syncCode, optionCode] of this._selectOne) {
97
+ resultSelectOne.push({ syncCode, optionCode });
98
+ }
99
+ result.selectOne = resultSelectOne;
100
+ }
101
+ if (this._selectMany.size !== 0) {
102
+ const resultSelectMany = [];
103
+ for (const [syncCode, optionCodeToSelected] of this._selectMany) {
104
+ for (const [optionCode, selected] of optionCodeToSelected) {
105
+ resultSelectMany.push({ syncCode, optionCode, selected });
106
+ }
107
+ }
108
+ result.selectMany = resultSelectMany;
109
+ }
110
+ return result;
111
+ }
70
112
  log(syncCode, optionCode, selected) {
71
113
  if (!this._verboseLogging) {
72
114
  return;
@@ -222,17 +222,20 @@ export const cfgProductTest = (testFunc, prepFunc) => __awaiter(void 0, void 0,
222
222
  getProduct: getTestProduct,
223
223
  postValidate: (params, _body) => __awaiter(void 0, void 0, void 0, function* () {
224
224
  const productData = (yield getTestProduct(params)).productData;
225
- productData.partsData.selOptions = [
226
- {
227
- code: "!~!",
228
- next: {
229
- [letterOptionCodeC]: {
230
- code: letterOptionCodeC,
225
+ const partNumber = params.partNumber;
226
+ if (partNumber !== "D") {
227
+ productData.partsData.selOptions = [
228
+ {
229
+ code: "!~!",
230
+ next: {
231
+ [letterOptionCodeC]: {
232
+ code: letterOptionCodeC,
233
+ },
231
234
  },
232
235
  },
233
- },
234
- ];
235
- if (params.partNumber === "A") {
236
+ ];
237
+ }
238
+ if (partNumber === "A") {
236
239
  productData.partsData.selOptions.push({
237
240
  code: "!~!",
238
241
  next: {
@@ -252,9 +255,10 @@ export const cfgProductTest = (testFunc, prepFunc) => __awaiter(void 0, void 0,
252
255
  }
253
256
  const validateResponse = {
254
257
  uuid: "",
258
+ unit: "m",
255
259
  validated: true,
256
260
  productData,
257
- features: []
261
+ features: [],
258
262
  };
259
263
  collect.pushNotification(`Validate ${params.enterprise} ${params.prdCat} ${params.prdCatVersion} ${params.priceList} ${params.vendor} ${params.partNumber}`);
260
264
  return validateResponse;
@@ -171,9 +171,10 @@ export const cachedProductLoaderTest = () => __awaiter(void 0, void 0, void 0, f
171
171
  ];
172
172
  const validateResponse = {
173
173
  uuid: "",
174
+ unit: "m",
174
175
  validated: true,
175
176
  productData,
176
- features: []
177
+ features: [],
177
178
  };
178
179
  return validateResponse;
179
180
  }),
@@ -171,6 +171,7 @@ export const cachedProductLoaderTest = () => __awaiter(void 0, void 0, void 0, f
171
171
  const productData = (yield getProduct(params)).productData;
172
172
  const validateResponse = {
173
173
  uuid: "",
174
+ unit: "m",
174
175
  validated: true,
175
176
  productData,
176
177
  features: [],
@@ -169,11 +169,12 @@ export const cfgProductPriceTest = (testFunc, featureOption) => __awaiter(void 0
169
169
  getProduct: getTestProduct,
170
170
  postValidate: (params, _body) => __awaiter(void 0, void 0, void 0, function* () {
171
171
  const productData = (yield getTestProduct(params)).productData;
172
- if (featureOption !== undefined) {
172
+ if (featureOption !== undefined && params.partNumber === "A") {
173
173
  productData.partsData.selOptions = getSelOptions(featureOption);
174
174
  }
175
175
  const validateResponse = {
176
176
  uuid: "",
177
+ unit: "m",
177
178
  validated: true,
178
179
  productData,
179
180
  features: [],
@@ -97,6 +97,7 @@ export const getUpchargeProduct = (testFunc) => __awaiter(void 0, void 0, void 0
97
97
  const productData = (yield getProduct(params)).productData;
98
98
  const validateResponse = {
99
99
  uuid: "",
100
+ unit: "m",
100
101
  validated: true,
101
102
  productData,
102
103
  features: [],
@@ -44,6 +44,7 @@ export class NumericValueDiscrete {
44
44
  return `${round(this.value)}`;
45
45
  }
46
46
  }
47
+ const ACCEPTABLE_STEP_DEVIATION = 0.0000001;
47
48
  export class NumericValueRangeDefinition {
48
49
  constructor(rawRange) {
49
50
  const { minValue, maxValue, increment } = rawRange;
@@ -56,19 +57,19 @@ export class NumericValueRangeDefinition {
56
57
  if (value < start || end < value) {
57
58
  return false;
58
59
  }
59
- // TODO: This comparison will often fail due to the fact that all the values used are
60
+ // This comparison would often fail due to the fact that all the values used are
60
61
  // base-2 (binary) floating point numbers based on base-10 (decimal) input strings.
61
62
  //
62
63
  // Such calculations are often not 100% accurate as is visible in JS by simply
63
64
  // computing "0.1 + 0.2" which should equal about "0.30000000000000004" != "0.3".
64
65
  //
65
- // The easiest workaround is to define an static accuracy, say "6 decimals" and round
66
- // everything when comparing. One could also use a scaled version of Number.EPSILON to
67
- // dynamically match the precision to the precision of the input numbers.
66
+ // We have used the easiest workaround, to simply be a bit fuzzy with the checks and
67
+ // allow values that are very, very close to being on a step.
68
68
  //
69
- // Both workarounds share the same problem however; an infinite number of numbers will be
70
- // included in the range since an "infinite" number of values will map to the same rounded
71
- // actual number.
69
+ // This workaround comes with two major compromises:
70
+ // 1. The fuzziness needed depends on how many steps the checked values pass on the way.
71
+ // 2. An infinite number of numbers will be included in the range since many an "infinite"
72
+ // number of values close to each step will map to it.
72
73
  //
73
74
  // The proper fix is probably to use a fixed point mathematics, where we either define a
74
75
  // maximum of say 6 decimals or the number of decimals vary on the number of decimals given
@@ -79,7 +80,11 @@ export class NumericValueRangeDefinition {
79
80
  // and that is how the numbers are stored in CatCreator if you use a db3-file. If it is a
80
81
  // string there as well, everything is dandy. Otherwise we might get problems with rounding
81
82
  // or infinite decimals during the conversions to/from the db3-file.
82
- return step === undefined || (value - start) % step === 0;
83
+ if (step === undefined) {
84
+ return true;
85
+ }
86
+ const deviation = (value - start) % step;
87
+ return (deviation < ACCEPTABLE_STEP_DEVIATION || step - deviation < ACCEPTABLE_STEP_DEVIATION);
83
88
  }
84
89
  get first() {
85
90
  return this.minValue;