tango-app-api-store-builder 1.0.33 → 1.0.35
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tango-app-api-store-builder",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.35",
|
|
4
4
|
"description": "storeBuilder",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"path": "^0.12.7",
|
|
33
33
|
"selenium-webdriver": "^4.31.0",
|
|
34
34
|
"sharp": "^0.34.1",
|
|
35
|
-
"tango-api-schema": "^2.5.
|
|
35
|
+
"tango-api-schema": "^2.5.26",
|
|
36
36
|
"tango-app-api-middleware": "3.1.48",
|
|
37
37
|
"url": "^0.11.4",
|
|
38
38
|
"winston": "^3.17.0",
|
|
@@ -125,7 +125,6 @@ export async function getplanoFeedback( req, res ) {
|
|
|
125
125
|
let data = {};
|
|
126
126
|
if ( aiDetails?.body?.hits?.hits.length ) {
|
|
127
127
|
data = aiDetails?.body?.hits?.hits?.[0]?._source;
|
|
128
|
-
console.log( data, 'data' );
|
|
129
128
|
delete data.isEmpty;
|
|
130
129
|
delete data.fixtureFound;
|
|
131
130
|
}
|
|
@@ -787,6 +786,7 @@ export async function updateStorePlano( req, res ) {
|
|
|
787
786
|
{ _id: new mongoose.Types.ObjectId( floorId ) },
|
|
788
787
|
{
|
|
789
788
|
layoutPolygon: layoutPolygon,
|
|
789
|
+
cadLayout:false,
|
|
790
790
|
...( req.body?.editMode === true && { isEdited: true } ),
|
|
791
791
|
},
|
|
792
792
|
);
|
|
@@ -1782,7 +1782,6 @@ export async function getAllPlanoRevisions( req, res ) {
|
|
|
1782
1782
|
|
|
1783
1783
|
res.sendSuccess( revisions );
|
|
1784
1784
|
} catch ( e ) {
|
|
1785
|
-
console.log( e );
|
|
1786
1785
|
logger.error( { functionName: 'getAllPlanoRevisions', error: e } );
|
|
1787
1786
|
res.sendError( 'Failed to fetch plano revisions', 500 );
|
|
1788
1787
|
}
|
|
@@ -2370,15 +2369,15 @@ export async function createPlanoFromCAD(req, res) {
|
|
|
2370
2369
|
const file = req.files.file;
|
|
2371
2370
|
const { storeId, floorNumber } = req.body;
|
|
2372
2371
|
|
|
2373
|
-
if (!req?.files?.file) return res.sendError('File is required', 400);
|
|
2372
|
+
if (!req?.files?.file) return res.sendError({ errMsg: 'File is required' }, 400);
|
|
2374
2373
|
|
|
2375
|
-
if (!storeId || !floorNumber) return res.sendError('storeId and floorNumber are required', 400);
|
|
2374
|
+
if (!storeId || !floorNumber) return res.sendError({ errMsg: 'storeId and floorNumber are required' }, 400);
|
|
2376
2375
|
|
|
2377
|
-
if (!file.name.endsWith('.dxf')) return res.sendError('Only DXF files are allowed', 400);
|
|
2376
|
+
if (!file.name.endsWith('.dxf')) return res.sendError({ errMsg: 'Only DXF files are allowed' }, 400);
|
|
2378
2377
|
|
|
2379
2378
|
|
|
2380
2379
|
// if (file.size > 20 * 1024 * 1024) {
|
|
2381
|
-
// return res.sendError('File size exceeds 20MB limit', 400);
|
|
2380
|
+
// return res.sendError({errMsg:'File size exceeds 20MB limit'}, 400);
|
|
2382
2381
|
// }
|
|
2383
2382
|
|
|
2384
2383
|
// File Upload
|
|
@@ -2392,7 +2391,7 @@ export async function createPlanoFromCAD(req, res) {
|
|
|
2392
2391
|
|
|
2393
2392
|
const fileRes = await fileUpload(fileUploadPayload);
|
|
2394
2393
|
|
|
2395
|
-
if (!fileRes?.Key) return res.sendError('Failed to upload file to storage', 502);
|
|
2394
|
+
if (!fileRes?.Key) return res.sendError({ errMsg: 'Failed to upload file to storage' }, 502);
|
|
2396
2395
|
|
|
2397
2396
|
// CAD Extraction
|
|
2398
2397
|
const dataExtractPayload = {
|
|
@@ -2412,7 +2411,7 @@ export async function createPlanoFromCAD(req, res) {
|
|
|
2412
2411
|
if (!cadRes.ok) {
|
|
2413
2412
|
const errorText = await cadRes.text();
|
|
2414
2413
|
logger.error({ cadLambdaError: errorText });
|
|
2415
|
-
return res.sendError('CAD extraction service failed', 502);
|
|
2414
|
+
return res.sendError({ errMsg: 'CAD extraction service failed' }, 502);
|
|
2416
2415
|
}
|
|
2417
2416
|
|
|
2418
2417
|
const cadData = await cadRes.json();
|
|
@@ -2426,7 +2425,11 @@ export async function createPlanoFromCAD(req, res) {
|
|
|
2426
2425
|
cadData?.status !== 'success' ||
|
|
2427
2426
|
!cadData?.data?.layoutPolygon
|
|
2428
2427
|
) {
|
|
2429
|
-
return res.sendError(
|
|
2428
|
+
return res.sendError(
|
|
2429
|
+
{
|
|
2430
|
+
errMsg: 'Invalid CAD layout data',
|
|
2431
|
+
errInfo: { cadData, input: dataExtractPayload }
|
|
2432
|
+
}, 502);
|
|
2430
2433
|
}
|
|
2431
2434
|
|
|
2432
2435
|
const userMeta = {
|
|
@@ -2440,7 +2443,7 @@ export async function createPlanoFromCAD(req, res) {
|
|
|
2440
2443
|
|
|
2441
2444
|
if (!planoData) {
|
|
2442
2445
|
const storeData = await storeService.findOne({ storeId }, { clientId: 1, storeName: 1 });
|
|
2443
|
-
if (!storeData) return res.sendError('Unable to find the store to create planogram', 400);
|
|
2446
|
+
if (!storeData) return res.sendError({ errMsg: 'Unable to find the store to create planogram' }, 400);
|
|
2444
2447
|
|
|
2445
2448
|
const newPlano = {
|
|
2446
2449
|
clientId: storeData.clientId,
|
|
@@ -2456,7 +2459,7 @@ export async function createPlanoFromCAD(req, res) {
|
|
|
2456
2459
|
};
|
|
2457
2460
|
|
|
2458
2461
|
planoData = await planoService.create(newPlano);
|
|
2459
|
-
if (!planoData) return res.sendError('Failed to create new planogram', 400);
|
|
2462
|
+
if (!planoData) return res.sendError({ errMsg: 'Failed to create new planogram' }, 400);
|
|
2460
2463
|
}
|
|
2461
2464
|
|
|
2462
2465
|
const floorPayload = {
|
|
@@ -2484,7 +2487,7 @@ export async function createPlanoFromCAD(req, res) {
|
|
|
2484
2487
|
};
|
|
2485
2488
|
|
|
2486
2489
|
floorData = await floorService.create(newFloor);
|
|
2487
|
-
if (!floorData) return res.sendError('Failed to create new floor layout', 400);
|
|
2490
|
+
if (!floorData) return res.sendError({ errMsg: 'Failed to create new floor layout' }, 400);
|
|
2488
2491
|
}
|
|
2489
2492
|
|
|
2490
2493
|
const meta = {
|
|
@@ -2497,13 +2500,17 @@ export async function createPlanoFromCAD(req, res) {
|
|
|
2497
2500
|
|
|
2498
2501
|
// Create Fixtures
|
|
2499
2502
|
const processedFixtures = createStoreFixtures(cadData.data, meta);
|
|
2500
|
-
|
|
2503
|
+
const storeFixtures = []
|
|
2501
2504
|
try {
|
|
2502
2505
|
await storeFixtureService.deleteMany({ floorId: meta.floorId });
|
|
2503
2506
|
await fixtureShelfService.deleteMany({ floorId: meta.floorId });
|
|
2504
2507
|
for (let i = 0; i < processedFixtures.length; i++) {
|
|
2505
2508
|
const fix = processedFixtures[i];
|
|
2506
|
-
await storeFixtureService.create(fix);
|
|
2509
|
+
const fixRes = await storeFixtureService.create(fix);
|
|
2510
|
+
if (fixRes) {
|
|
2511
|
+
const fixture = fixRes.toObject();
|
|
2512
|
+
storeFixtures.push({ ...fixture, shelfConfig: fix.shelfConfig });
|
|
2513
|
+
}
|
|
2507
2514
|
}
|
|
2508
2515
|
} catch (e) {
|
|
2509
2516
|
logger.error({
|
|
@@ -2512,6 +2519,18 @@ export async function createPlanoFromCAD(req, res) {
|
|
|
2512
2519
|
});
|
|
2513
2520
|
}
|
|
2514
2521
|
|
|
2522
|
+
|
|
2523
|
+
try {
|
|
2524
|
+
const updateStoreFixtures = await processFixtureTemplates({ fixtures: storeFixtures });
|
|
2525
|
+
|
|
2526
|
+
if (updateStoreFixtures.length) await storeFixtureService.bulkUpsert(updateStoreFixtures);
|
|
2527
|
+
} catch (e) {
|
|
2528
|
+
logger.error({
|
|
2529
|
+
functionName: 'createPlanoFromCAD [Update Fixtures]',
|
|
2530
|
+
error: e,
|
|
2531
|
+
});
|
|
2532
|
+
}
|
|
2533
|
+
|
|
2515
2534
|
return res.sendSuccess(meta);
|
|
2516
2535
|
|
|
2517
2536
|
} catch (error) {
|
|
@@ -2520,7 +2539,7 @@ export async function createPlanoFromCAD(req, res) {
|
|
|
2520
2539
|
error,
|
|
2521
2540
|
});
|
|
2522
2541
|
|
|
2523
|
-
return res.sendError('Failed to create planogram.', 500);
|
|
2542
|
+
return res.sendError({ errMsg: 'Failed to create planogram.' }, 500);
|
|
2524
2543
|
}
|
|
2525
2544
|
}
|
|
2526
2545
|
|
|
@@ -2598,11 +2617,13 @@ function processFixtureData(data) {
|
|
|
2598
2617
|
fixtureWidth: f?.fixtureWidth,
|
|
2599
2618
|
fixtureLength: f?.fixtureLength,
|
|
2600
2619
|
fixtureNumber: f?.fixtureNumber,
|
|
2620
|
+
templateGroupName: f?.templateGroupName ?? f?.header?.label,
|
|
2621
|
+
fixtureCategory: f?.fixtureCategory,
|
|
2601
2622
|
associatedElementNumber: data?.wallNumber,
|
|
2602
2623
|
associatedElementFixtureNumber: data.fixtureNumber,
|
|
2603
2624
|
associatedElementType: f?.associatedElementType === 'wall' ? 'wall' : undefined,
|
|
2604
2625
|
productBrandName: Array.isArray(f?.productBrandName) ? f?.productBrandName?.map(normalizeCadText) : normalizeCadText(f?.productBrandName),
|
|
2605
|
-
|
|
2626
|
+
shelfConfig: f?.shelfConfig ?? [],
|
|
2606
2627
|
fixtureHeight: {
|
|
2607
2628
|
value: 0,
|
|
2608
2629
|
unit: 'mm',
|
|
@@ -2620,4 +2641,114 @@ function processFixtureData(data) {
|
|
|
2620
2641
|
isMerchEdited: false,
|
|
2621
2642
|
isVmEdited: false,
|
|
2622
2643
|
};
|
|
2644
|
+
}
|
|
2645
|
+
|
|
2646
|
+
async function processFixtureTemplates(data) {
|
|
2647
|
+
const updateStoreFixtures = [];
|
|
2648
|
+
const newFixtureTemplates = [];
|
|
2649
|
+
|
|
2650
|
+
for (let i = 0; i < data.fixtures.length; i++) {
|
|
2651
|
+
let fixture = data.fixtures[i];
|
|
2652
|
+
const mapKey = `${fixture.fixtureCategory}${fixture.fixtureWidth.value}${fixture.fixtureWidth.unit}${fixture.header.label}`;
|
|
2653
|
+
|
|
2654
|
+
const subTemplateQuery = [
|
|
2655
|
+
{
|
|
2656
|
+
$addFields: {
|
|
2657
|
+
crestMapKey: { $toLower: '$crestMapKey' },
|
|
2658
|
+
},
|
|
2659
|
+
},
|
|
2660
|
+
{
|
|
2661
|
+
$match: {
|
|
2662
|
+
crestMapKey: mapKey.toLowerCase(),
|
|
2663
|
+
templateType: 'sub',
|
|
2664
|
+
},
|
|
2665
|
+
},
|
|
2666
|
+
];
|
|
2667
|
+
|
|
2668
|
+
const masterTemplateQuery = [
|
|
2669
|
+
{
|
|
2670
|
+
$addFields: {
|
|
2671
|
+
crestMapKey: { $toLower: '$crestMapKey' },
|
|
2672
|
+
},
|
|
2673
|
+
},
|
|
2674
|
+
{
|
|
2675
|
+
$match: {
|
|
2676
|
+
crestMapKey: mapKey.toLowerCase(),
|
|
2677
|
+
templateType: 'master',
|
|
2678
|
+
},
|
|
2679
|
+
},
|
|
2680
|
+
];
|
|
2681
|
+
|
|
2682
|
+
let [subTemplate, masterTemplate] = await Promise.all([
|
|
2683
|
+
await fixtureConfigService.aggregate(subTemplateQuery),
|
|
2684
|
+
await fixtureConfigService.aggregate(masterTemplateQuery),
|
|
2685
|
+
]);
|
|
2686
|
+
|
|
2687
|
+
|
|
2688
|
+
if (!subTemplate?.length) {
|
|
2689
|
+
const templateGroupName = fixture.header.label;
|
|
2690
|
+
let templateIndex = 1;
|
|
2691
|
+
|
|
2692
|
+
let newTemplateData = {
|
|
2693
|
+
...fixture,
|
|
2694
|
+
templateGroupName: templateGroupName,
|
|
2695
|
+
status: 'complete',
|
|
2696
|
+
templateIndex: masterTemplate.length ? masterTemplate.length + 1 : 1,
|
|
2697
|
+
crestMapKey: mapKey,
|
|
2698
|
+
}
|
|
2699
|
+
|
|
2700
|
+
delete newTemplateData._id;
|
|
2701
|
+
|
|
2702
|
+
if (!masterTemplate.length) {
|
|
2703
|
+
const newMasterTemplate = {
|
|
2704
|
+
...newTemplateData,
|
|
2705
|
+
fixtureName: `${newTemplateData?.header?.label}-${newTemplateData?.fixtureCategory}`,
|
|
2706
|
+
templateType: 'master',
|
|
2707
|
+
crestMapKey: mapKey,
|
|
2708
|
+
}
|
|
2709
|
+
masterTemplate = await fixtureConfigService.create(newMasterTemplate);
|
|
2710
|
+
} else {
|
|
2711
|
+
masterTemplate = masterTemplate[0];
|
|
2712
|
+
|
|
2713
|
+
const masterTempIndexQuery = [
|
|
2714
|
+
{
|
|
2715
|
+
$match: {
|
|
2716
|
+
masterTemplateId: new mongoose.Types.ObjectId(masterTemplate._id),
|
|
2717
|
+
},
|
|
2718
|
+
}, {
|
|
2719
|
+
$group: {
|
|
2720
|
+
_id: '',
|
|
2721
|
+
tempId: { $max: '$templateIndex' },
|
|
2722
|
+
},
|
|
2723
|
+
},
|
|
2724
|
+
];
|
|
2725
|
+
|
|
2726
|
+
const getMaxTempIndex = await fixtureConfigService.aggregate(masterTempIndexQuery);
|
|
2727
|
+
templateIndex = getMaxTempIndex?.[0]?.tempId + 1;
|
|
2728
|
+
}
|
|
2729
|
+
|
|
2730
|
+
newTemplateData.fixtureName = `${fixture?.header?.label}-${fixture?.fixtureCategory}-${fixture?.fixtureWidth?.value}-${fixture?.fixtureWidth?.unit}-variant-${templateIndex}`;
|
|
2731
|
+
newTemplateData.templateType = 'sub';
|
|
2732
|
+
newTemplateData.masterTemplateId = masterTemplate._id;
|
|
2733
|
+
newTemplateData.templateIndex = templateIndex;
|
|
2734
|
+
newTemplateData.createdAt = new Date();
|
|
2735
|
+
newTemplateData.updatedAt = new Date();
|
|
2736
|
+
|
|
2737
|
+
subTemplate = await fixtureConfigService.create(newTemplateData);
|
|
2738
|
+
|
|
2739
|
+
fixture.fixtureConfigId = subTemplate._id;
|
|
2740
|
+
fixture.masterTemplateId = masterTemplate._id;
|
|
2741
|
+
fixture.fixtureName = newTemplateData.fixtureName;
|
|
2742
|
+
} else {
|
|
2743
|
+
const sub = subTemplate?.[0];
|
|
2744
|
+
fixture.fixtureName = sub.fixtureName;
|
|
2745
|
+
fixture.fixtureConfigId = sub?._id;
|
|
2746
|
+
fixture.masterTemplateId = sub?.masterTemplateId;
|
|
2747
|
+
}
|
|
2748
|
+
|
|
2749
|
+
newFixtureTemplates.push(subTemplate);
|
|
2750
|
+
updateStoreFixtures.push(fixture);
|
|
2751
|
+
}
|
|
2752
|
+
|
|
2753
|
+
return updateStoreFixtures;
|
|
2623
2754
|
}
|
|
@@ -9055,7 +9055,7 @@ async function convertFixtureStructure( req ) {
|
|
|
9055
9055
|
centerFixture: centerFixturesWithStatus,
|
|
9056
9056
|
otherElements: otherElements,
|
|
9057
9057
|
lastUpdate: dayjs( floor?.updatedAt ).format( 'Do MMMM YYYY hh:mm A' ),
|
|
9058
|
-
...( floors.length > 1 ) ? { floorNum: `Floor ${index + 1}/${floors.length}` } : { floorNum:
|
|
9058
|
+
...( floors.length > 1 ) ? { floorNum: `Floor ${floor?.floorNumber ?? index + 1}/${floors.length}` } : { floorNum: `Floor ${floor?.floorNumber ?? 1}` },
|
|
9059
9059
|
};
|
|
9060
9060
|
|
|
9061
9061
|
let planoProductCount = 0;
|