@contrail/flexplm 1.7.4-alpha.879820c → 1.7.4-alpha.8ba0056
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.
|
@@ -12,7 +12,6 @@ export declare class ItemFamilyChanges {
|
|
|
12
12
|
colorDeletes: string[];
|
|
13
13
|
colorUpdates: string[];
|
|
14
14
|
colorUnchanged: string[];
|
|
15
|
-
colorSuppressed: string[];
|
|
16
15
|
assortmentItemFullChangeMap: Map<string, any>;
|
|
17
16
|
assortmentItemDeleteMap: Map<string, any>;
|
|
18
17
|
itemToFederatedIdMapping: Map<string, string>;
|
|
@@ -14,7 +14,6 @@ class ItemFamilyChanges {
|
|
|
14
14
|
this.colorDeletes = [];
|
|
15
15
|
this.colorUpdates = [];
|
|
16
16
|
this.colorUnchanged = [];
|
|
17
|
-
this.colorSuppressed = []; // changed this window, but excluded by the lifecycle filter
|
|
18
17
|
this.assortmentItemFullChangeMap = new Map();
|
|
19
18
|
this.assortmentItemDeleteMap = new Map();
|
|
20
19
|
this.itemToFederatedIdMapping = new Map();
|
|
@@ -33,7 +32,6 @@ class ItemFamilyChanges {
|
|
|
33
32
|
s += ' colorDeletes: [' + this.colorDeletes + ']\n';
|
|
34
33
|
s += ' colorUpdates: [' + this.colorUpdates + ']\n';
|
|
35
34
|
s += ' colorUnchanged: [' + this.colorUnchanged + ']\n';
|
|
36
|
-
s += ' colorSuppressed: [' + this.colorSuppressed + ']\n';
|
|
37
35
|
s += 'assortmentItemFullChangeMap:\n';
|
|
38
36
|
s += 'size: ' + this.assortmentItemFullChangeMap.size + '\n[';
|
|
39
37
|
for (const key of this.assortmentItemFullChangeMap.keys()) {
|
|
@@ -493,15 +493,18 @@ class BaseProcessPublishAssortment {
|
|
|
493
493
|
const item = aItem?.item;
|
|
494
494
|
const itemId = item?.id;
|
|
495
495
|
const itemFamilyId = item?.itemFamilyId;
|
|
496
|
+
// ET-243: meets criteria is separated out for itemId and familyId separately
|
|
496
497
|
if (meetsCriteria) {
|
|
497
498
|
releasedForDevelopmentItemIds.push(itemId);
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
499
|
+
}
|
|
500
|
+
if (!itemFamilySet.has(itemFamilyId) && itemId !== itemFamilyId) {
|
|
501
|
+
const familyItem = item?.itemFamily;
|
|
502
|
+
if (familyItem) {
|
|
503
|
+
if (this.meetsCriteria({ item: familyItem })
|
|
504
|
+
&& !releasedForDevelopmentItemIds.includes(itemFamilyId)) {
|
|
502
505
|
releasedForDevelopmentItemIds.push(itemFamilyId);
|
|
503
506
|
}
|
|
504
|
-
itemFamilySet.add(itemFamilyId);
|
|
507
|
+
itemFamilySet.add(itemFamilyId); // only mark resolved when we had data to judge
|
|
505
508
|
}
|
|
506
509
|
}
|
|
507
510
|
}
|
|
@@ -512,18 +515,19 @@ class BaseProcessPublishAssortment {
|
|
|
512
515
|
const itemFamilyId = item?.itemFamilyId;
|
|
513
516
|
if (meetsCriteria) {
|
|
514
517
|
releasedForDevelopmentItemIds.push(itemId);
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
}
|
|
524
|
-
else {
|
|
525
|
-
itemFamilySet.add(itemFamilyId);
|
|
518
|
+
}
|
|
519
|
+
if (!itemFamilySet.has(itemFamilyId) && itemId !== itemFamilyId) {
|
|
520
|
+
const familyItem = item?.itemFamily;
|
|
521
|
+
if (familyItem) {
|
|
522
|
+
const familyItemMeetsCriteria = this.meetsCriteria({ item: familyItem });
|
|
523
|
+
if (familyItemMeetsCriteria
|
|
524
|
+
&& !releasedForDevelopmentItemIds.includes(itemFamilyId)) {
|
|
525
|
+
releasedForDevelopmentItemIds.push(itemFamilyId);
|
|
526
526
|
}
|
|
527
|
+
itemFamilySet.add(itemFamilyId);
|
|
528
|
+
}
|
|
529
|
+
else {
|
|
530
|
+
itemFamilySet.add(itemFamilyId);
|
|
527
531
|
}
|
|
528
532
|
}
|
|
529
533
|
}
|
|
@@ -730,7 +734,7 @@ class BaseProcessPublishAssortment {
|
|
|
730
734
|
for (const [itemId, aItem] of assortmentItemFullChangeMap) {
|
|
731
735
|
const projectItem = aItem?.projectItem;
|
|
732
736
|
const itemFamilyId = aItem?.item?.itemFamilyId;
|
|
733
|
-
if (!pcd.releasedForDevelopmentItemIds.includes(itemFamilyId)) {
|
|
737
|
+
if (!pcd.releasedForDevelopmentItemIds.includes(itemFamilyId) || !pcd.releasedForDevelopmentItemIds.includes(itemId)) {
|
|
734
738
|
continue;
|
|
735
739
|
}
|
|
736
740
|
const ifc = itemFamilyChanges.get(itemFamilyId) || new item_family_changes_1.ItemFamilyChanges(itemFamilyId, pcd.sinceDate);
|
|
@@ -742,20 +746,6 @@ class BaseProcessPublishAssortment {
|
|
|
742
746
|
if (pcd.itemToFederatedIdMapping.has(itemId)) {
|
|
743
747
|
ifc.itemToFederatedIdMapping.set(itemId, pcd.itemToFederatedIdMapping.get(itemId));
|
|
744
748
|
}
|
|
745
|
-
// ---- NEW Step to enable ItemFamily publish ET-243: option is pre-development. It must not produce an
|
|
746
|
-
// LCSSKUSeasonLink, but a change to it still makes the family publishable. ----
|
|
747
|
-
if (!pcd.releasedForDevelopmentItemIds.includes(itemId)) {
|
|
748
|
-
const changedInWindow = addIds.includes(itemId)
|
|
749
|
-
|| deleteIds.includes(itemId)
|
|
750
|
-
|| updateIds.includes(itemId)
|
|
751
|
-
|| this.updatedSinceDate(projectItem, pcd.sinceDate)
|
|
752
|
-
|| this.updatedSinceDate(aItem?.item, pcd.sinceDate);
|
|
753
|
-
if (changedInWindow) {
|
|
754
|
-
ifc.colorSuppressed.push(itemId);
|
|
755
|
-
}
|
|
756
|
-
continue;
|
|
757
|
-
}
|
|
758
|
-
// NEW Step - ends
|
|
759
749
|
if (itemId === itemFamilyId) {
|
|
760
750
|
if (addIds.includes(itemId))
|
|
761
751
|
ifc.familyAdd = true;
|
|
@@ -771,12 +761,6 @@ class BaseProcessPublishAssortment {
|
|
|
771
761
|
ifc.familyUpdate = true;
|
|
772
762
|
}
|
|
773
763
|
}
|
|
774
|
-
// NEW Step to enable ItemFamily publish ET-243: item-level edits (incl. lifecycleStage) must publish
|
|
775
|
-
// the family. Guarded so the "first option added" flow stays suppressed. ----
|
|
776
|
-
if (!ifc.familyItemRemoved && this.updatedSinceDate(aItem?.item, pcd.sinceDate)) {
|
|
777
|
-
ifc.familyUpdate = true;
|
|
778
|
-
}
|
|
779
|
-
// NEW Step - ends
|
|
780
764
|
if (projectItem && !projectItem?.roles && aItem?.item?.roles) {
|
|
781
765
|
projectItem.roles = aItem?.item?.roles;
|
|
782
766
|
}
|
|
@@ -875,10 +859,8 @@ class BaseProcessPublishAssortment {
|
|
|
875
859
|
const LCSSeason = Object.assign({}, seasonFed);
|
|
876
860
|
const assortment = await this.getAssortment(assortmentId);
|
|
877
861
|
const projectItem = this.getProjectItem(itemFamilyChanges, itemFamilyChanges.itemFamilyId);
|
|
878
|
-
// ---- NEW Step to enable ItemFamily publish ET-243: added color suppressed length to existing condition, no other changes on familyAssortmentItem boolean
|
|
879
862
|
const familyAssortmentItem = itemFamilyChanges.familyAdd || itemFamilyChanges.familyUpdate || itemFamilyChanges.familyDelete
|
|
880
863
|
|| itemFamilyChanges.colorAdds.length > 0 || itemFamilyChanges.colorUpdates.length > 0 || itemFamilyChanges.colorDeletes.length > 0
|
|
881
|
-
|| itemFamilyChanges.colorSuppressed.length > 0
|
|
882
864
|
|| (projectItem && this.updatedSinceDate(projectItem, itemFamilyChanges.sinceDate));
|
|
883
865
|
//familyItemRemoved is used when adding the first option to an assortment
|
|
884
866
|
//and will have updates for the family item.
|
|
@@ -1337,150 +1337,6 @@ describe('getItemFamilyChanges', () => {
|
|
|
1337
1337
|
expect(ifc.colorDeletes.length).toEqual(1);
|
|
1338
1338
|
});
|
|
1339
1339
|
});
|
|
1340
|
-
describe('getItemFamilyChanges - lifecycle-suppressed options', () => {
|
|
1341
|
-
const familyId = 'AERfdvdAt1HHEVvQ';
|
|
1342
|
-
const maroonId = 'YwWKVoL_vGN8khLy';
|
|
1343
|
-
const limeId = 'rsmWhWiXRNv_XBJG';
|
|
1344
|
-
const sinceDate = new Date('2026-08-01T00:00:00.000Z');
|
|
1345
|
-
const afterSince = '2026-08-26T00:00:00.000Z';
|
|
1346
|
-
const beforeSince = '2026-05-11T00:00:00.000Z';
|
|
1347
|
-
const noDetailChanges = () => ({ adds: [], deletes: [], updates: [], familyItemsRemoved: [] });
|
|
1348
|
-
const buildPpa = () => {
|
|
1349
|
-
const config = {};
|
|
1350
|
-
const mapFileUtil = new transform_data_1.MapFileUtil(new sdk_1.Entities());
|
|
1351
|
-
const dc = new data_converter_1.DataConverter(config, mapFileUtil);
|
|
1352
|
-
return new base_process_publish_assortment_1.BaseProcessPublishAssortment(config, dc, mapFileUtil);
|
|
1353
|
-
};
|
|
1354
|
-
const buildPcd = (releasedIds) => {
|
|
1355
|
-
const seasonFed = {
|
|
1356
|
-
entityReference: 'assortment:11EZML5dMn3tREuT',
|
|
1357
|
-
objectClass: 'LCSSeason'
|
|
1358
|
-
};
|
|
1359
|
-
const pcd = new publish_change_data_1.PublishChangeData('11EZML5dMn3tREuT', seasonFed, 'Pg3y2x5IclYxk3hM', sinceDate);
|
|
1360
|
-
pcd.itemToFederatedIdMapping = new Map();
|
|
1361
|
-
releasedIds.forEach(id => pcd.releasedForDevelopmentItemIds.push(id));
|
|
1362
|
-
return pcd;
|
|
1363
|
-
};
|
|
1364
|
-
const familyItem = (updatedOn = beforeSince, lifecycleStage = 'released') => ({
|
|
1365
|
-
id: familyId, itemFamilyId: familyId, lifecycleStage, name: 'Sweatpant', updatedOn
|
|
1366
|
-
});
|
|
1367
|
-
const familyRow = (updatedOn = beforeSince, lifecycleStage = 'released') => ({
|
|
1368
|
-
itemId: familyId,
|
|
1369
|
-
item: familyItem(updatedOn, lifecycleStage),
|
|
1370
|
-
projectItem: { id: 'pi-' + familyId, updatedOn: beforeSince }
|
|
1371
|
-
});
|
|
1372
|
-
const optionRow = (id, updatedOn, lifecycleStage = 'concept') => ({
|
|
1373
|
-
itemId: id,
|
|
1374
|
-
item: { id, itemFamilyId: familyId, lifecycleStage, updatedOn, itemFamily: familyItem() },
|
|
1375
|
-
projectItem: { id: 'pi-' + id, updatedOn: beforeSince },
|
|
1376
|
-
familyProjectItem: { id: 'pi-' + familyId, updatedOn: beforeSince }
|
|
1377
|
-
});
|
|
1378
|
-
it('records changed concept options as suppressed, not as colour updates', () => {
|
|
1379
|
-
const ppa = buildPpa();
|
|
1380
|
-
const fullChangeMap = ppa.getFullChangeAssortmentMap({
|
|
1381
|
-
assortmentItems: [familyRow(), optionRow(maroonId, afterSince), optionRow(limeId, afterSince)]
|
|
1382
|
-
});
|
|
1383
|
-
const pcd = buildPcd([familyId]);
|
|
1384
|
-
pcd.itemFamilyChanges = ppa.getItemFamilyChanges(pcd, noDetailChanges(), fullChangeMap, new Map());
|
|
1385
|
-
expect(pcd.itemFamilyChanges.size).toEqual(1);
|
|
1386
|
-
const ifc = pcd.itemFamilyChanges.get(familyId);
|
|
1387
|
-
expect(ifc.colorSuppressed).toEqual([maroonId, limeId]);
|
|
1388
|
-
expect(ifc.colorAdds.length).toEqual(0);
|
|
1389
|
-
expect(ifc.colorUpdates.length).toEqual(0);
|
|
1390
|
-
expect(ifc.colorDeletes.length).toEqual(0);
|
|
1391
|
-
expect(ifc.familyUpdate).toBe(false); // family itself unchanged
|
|
1392
|
-
});
|
|
1393
|
-
it('keeps the family reachable when only concept option rows are in the baseline', () => {
|
|
1394
|
-
const ppa = buildPpa();
|
|
1395
|
-
const fullChangeMap = ppa.getFullChangeAssortmentMap({
|
|
1396
|
-
assortmentItems: [optionRow(maroonId, afterSince), optionRow(limeId, afterSince)]
|
|
1397
|
-
});
|
|
1398
|
-
const pcd = buildPcd([familyId]);
|
|
1399
|
-
pcd.itemFamilyChanges = ppa.getItemFamilyChanges(pcd, noDetailChanges(), fullChangeMap, new Map());
|
|
1400
|
-
expect(pcd.itemFamilyChanges.size).toEqual(1);
|
|
1401
|
-
const ifc = pcd.itemFamilyChanges.get(familyId);
|
|
1402
|
-
expect(ifc.itemFamilyObject.id).toEqual(familyId);
|
|
1403
|
-
expect(ifc.colorSuppressed.length).toEqual(2);
|
|
1404
|
-
// the suppressed option must stay in the map so the family's project item is reachable
|
|
1405
|
-
expect(ppa.getProjectItem(ifc, familyId)).toEqual({ id: 'pi-' + familyId, updatedOn: beforeSince });
|
|
1406
|
-
});
|
|
1407
|
-
it('does not suppress-record an unchanged concept option', () => {
|
|
1408
|
-
const ppa = buildPpa();
|
|
1409
|
-
const fullChangeMap = ppa.getFullChangeAssortmentMap({
|
|
1410
|
-
assortmentItems: [familyRow(), optionRow(maroonId, beforeSince)]
|
|
1411
|
-
});
|
|
1412
|
-
const pcd = buildPcd([familyId]);
|
|
1413
|
-
pcd.itemFamilyChanges = ppa.getItemFamilyChanges(pcd, noDetailChanges(), fullChangeMap, new Map());
|
|
1414
|
-
const ifc = pcd.itemFamilyChanges.get(familyId);
|
|
1415
|
-
expect(ifc.colorSuppressed.length).toEqual(0);
|
|
1416
|
-
});
|
|
1417
|
-
it('picks up a concept option listed in the change detail even when timestamps are stale', () => {
|
|
1418
|
-
const ppa = buildPpa();
|
|
1419
|
-
const fullChangeMap = ppa.getFullChangeAssortmentMap({
|
|
1420
|
-
assortmentItems: [familyRow(), optionRow(maroonId, beforeSince)]
|
|
1421
|
-
});
|
|
1422
|
-
const details = noDetailChanges();
|
|
1423
|
-
details.updates = [{ id: maroonId }];
|
|
1424
|
-
const pcd = buildPcd([familyId]);
|
|
1425
|
-
pcd.itemFamilyChanges = ppa.getItemFamilyChanges(pcd, details, fullChangeMap, new Map());
|
|
1426
|
-
expect(pcd.itemFamilyChanges.get(familyId).colorSuppressed).toEqual([maroonId]);
|
|
1427
|
-
});
|
|
1428
|
-
it('skips everything when the family itself is pre-development', () => {
|
|
1429
|
-
const ppa = buildPpa();
|
|
1430
|
-
const fullChangeMap = ppa.getFullChangeAssortmentMap({
|
|
1431
|
-
assortmentItems: [familyRow(afterSince, 'concept'), optionRow(maroonId, afterSince)]
|
|
1432
|
-
});
|
|
1433
|
-
const pcd = buildPcd([]); // nothing released
|
|
1434
|
-
pcd.itemFamilyChanges = ppa.getItemFamilyChanges(pcd, noDetailChanges(), fullChangeMap, new Map());
|
|
1435
|
-
expect(pcd.itemFamilyChanges.size).toEqual(0);
|
|
1436
|
-
});
|
|
1437
|
-
it('still classifies released options normally', () => {
|
|
1438
|
-
const ppa = buildPpa();
|
|
1439
|
-
const fullChangeMap = ppa.getFullChangeAssortmentMap({
|
|
1440
|
-
assortmentItems: [familyRow(), optionRow(maroonId, afterSince, 'released')]
|
|
1441
|
-
});
|
|
1442
|
-
const details = noDetailChanges();
|
|
1443
|
-
details.adds = [{ id: maroonId }];
|
|
1444
|
-
const pcd = buildPcd([familyId, maroonId]);
|
|
1445
|
-
pcd.itemFamilyChanges = ppa.getItemFamilyChanges(pcd, details, fullChangeMap, new Map());
|
|
1446
|
-
const ifc = pcd.itemFamilyChanges.get(familyId);
|
|
1447
|
-
expect(ifc.colorAdds).toEqual([maroonId]);
|
|
1448
|
-
expect(ifc.colorSuppressed.length).toEqual(0);
|
|
1449
|
-
});
|
|
1450
|
-
it('publishes a family-only row whose lifecycle just flipped (item-level edit)', () => {
|
|
1451
|
-
const ppa = buildPpa();
|
|
1452
|
-
const fullChangeMap = ppa.getFullChangeAssortmentMap({
|
|
1453
|
-
assortmentItems: [familyRow(afterSince)] // item.updatedOn moved, projectItem did not
|
|
1454
|
-
});
|
|
1455
|
-
const pcd = buildPcd([familyId]);
|
|
1456
|
-
pcd.itemFamilyChanges = ppa.getItemFamilyChanges(pcd, noDetailChanges(), fullChangeMap, new Map());
|
|
1457
|
-
const ifc = pcd.itemFamilyChanges.get(familyId);
|
|
1458
|
-
expect(ifc.familyUpdate).toBe(true); // fails without Step 3
|
|
1459
|
-
expect(ifc.colorSuppressed.length).toEqual(0);
|
|
1460
|
-
});
|
|
1461
|
-
it('leaves an unchanged family-only row with no flags', () => {
|
|
1462
|
-
const ppa = buildPpa();
|
|
1463
|
-
const fullChangeMap = ppa.getFullChangeAssortmentMap({ assortmentItems: [familyRow()] });
|
|
1464
|
-
const pcd = buildPcd([familyId]);
|
|
1465
|
-
pcd.itemFamilyChanges = ppa.getItemFamilyChanges(pcd, noDetailChanges(), fullChangeMap, new Map());
|
|
1466
|
-
const ifc = pcd.itemFamilyChanges.get(familyId);
|
|
1467
|
-
expect(ifc.familyAdd).toBe(false);
|
|
1468
|
-
expect(ifc.familyUpdate).toBe(false);
|
|
1469
|
-
expect(ifc.familyDelete).toBe(false);
|
|
1470
|
-
expect(ifc.colorSuppressed.length).toEqual(0);
|
|
1471
|
-
});
|
|
1472
|
-
it('does not set familyUpdate when the family item was removed', () => {
|
|
1473
|
-
const ppa = buildPpa();
|
|
1474
|
-
const fullChangeMap = ppa.getFullChangeAssortmentMap({ assortmentItems: [familyRow(afterSince)] });
|
|
1475
|
-
const details = noDetailChanges();
|
|
1476
|
-
details.familyItemsRemoved = [{ itemId: familyId }]; // note: itemId, not id
|
|
1477
|
-
const pcd = buildPcd([familyId]);
|
|
1478
|
-
pcd.itemFamilyChanges = ppa.getItemFamilyChanges(pcd, details, fullChangeMap, new Map());
|
|
1479
|
-
const ifc = pcd.itemFamilyChanges.get(familyId);
|
|
1480
|
-
expect(ifc.familyItemRemoved).toBe(true);
|
|
1481
|
-
expect(ifc.familyUpdate).toBe(false); // fails if the !familyItemRemoved guard is dropped
|
|
1482
|
-
});
|
|
1483
|
-
});
|
|
1484
1340
|
describe('getProjectItem', () => {
|
|
1485
1341
|
const config = {
|
|
1486
1342
|
identifierAtts: {
|