tango-app-api-store-builder 1.0.0-beta-95 → 1.0.0-beta-97
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/index.js +4 -1
- package/inputjson/layoutverification.json +111 -0
- package/package.json +3 -2
- package/response.json +647 -0
- package/src/controllers/fixtureTemplate.controller.js +451 -0
- package/src/controllers/managePlano.controller.js +131 -0
- package/src/controllers/planoLibrary.controller.js +1313 -0
- package/src/controllers/script.controller.js +1978 -352
- package/src/controllers/storeBuilder.controller.js +531 -288
- package/src/controllers/task.controller.js +131 -52
- package/src/dtos/validation.dtos.js +218 -0
- package/src/routes/fixtureTemplate.routes.js +17 -0
- package/src/routes/managePlano.routes.js +12 -0
- package/src/routes/planoLibrary.routes.js +40 -0
- package/src/routes/script.routes.js +3 -1
- package/src/routes/storeBuilder.routes.js +5 -1
- package/src/routes/task.routes.js +1 -0
- package/src/service/fixtureConfig.service.js +26 -3
- package/src/service/planoLibrary.service.js +37 -0
- package/src/service/planoStaticData.service.js +3 -0
- package/src/service/planoVm.service.js +49 -0
- package/src/service/planoproductCategory.service.js +39 -0
- package/src/service/vmType.service.js +33 -0
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
// import { writeFileSync } from 'fs';
|
|
2
2
|
import xlsx from 'xlsx';
|
|
3
|
-
import { logger } from 'tango-app-api-middleware';
|
|
3
|
+
import { logger, fileUpload } from 'tango-app-api-middleware';
|
|
4
4
|
import * as storeBuilderService from '../service/storeBuilder.service.js';
|
|
5
5
|
import * as storeService from '../service/store.service.js';
|
|
6
6
|
import * as planoService from '../service/planogram.service.js';
|
|
7
7
|
import * as storeFixtureService from '../service/storeFixture.service.js';
|
|
8
8
|
import * as fixtureShelfService from '../service/fixtureShelf.service.js';
|
|
9
9
|
import * as planoProductService from '../service/planoProduct.service.js';
|
|
10
|
+
import * as planoVmService from '../service/planoVm.service.js';
|
|
10
11
|
import * as planoMappingService from '../service/planoMapping.service.js';
|
|
11
12
|
import * as planoTaskService from '../service/planoTask.service.js';
|
|
12
13
|
import * as processedTaskService from '../service/processedTaskservice.js';
|
|
@@ -14,11 +15,12 @@ import * as processedTaskService from '../service/processedTaskservice.js';
|
|
|
14
15
|
// import * as planoTaskComplianceService from '../service/planoTask.service.js';
|
|
15
16
|
// import * as planoQrConversionRequestService from '../service/planoQrConversionRequest.service.js';
|
|
16
17
|
import * as fixtureConfigService from '../service/fixtureConfig.service.js';
|
|
18
|
+
import * as fixtureLibraryService from '../service/planoLibrary.service.js';
|
|
17
19
|
import mongoose from 'mongoose';
|
|
18
20
|
import JSZip from 'jszip';
|
|
19
21
|
import { signedUrl } from 'tango-app-api-middleware';
|
|
20
22
|
import fs from 'fs';
|
|
21
|
-
import https from 'https';
|
|
23
|
+
// import https from 'https';
|
|
22
24
|
import os from 'os';
|
|
23
25
|
import { fileURLToPath } from 'url';
|
|
24
26
|
import path from 'path';
|
|
@@ -1135,7 +1137,7 @@ export async function updateFixturesShelves( req, res ) {
|
|
|
1135
1137
|
|
|
1136
1138
|
const createdFixture = await storeFixtureService.findOneAndUpdate2( { storeName: layoutDoc.storeName, fixtureNumber: fixture?.['fixtureNumber'] }, { fixtureCode: fixture?.['Fixture ID'] } );
|
|
1137
1139
|
|
|
1138
|
-
|
|
1140
|
+
console.log( 'Fixture Data', fixtureData );
|
|
1139
1141
|
|
|
1140
1142
|
|
|
1141
1143
|
const vms = typeof fixture?.['VM Template ID'] === 'string' ? fixture?.['VM Template ID']?.split( ', ' ).map( ( item ) => item.trim() ) : [];
|
|
@@ -1251,7 +1253,7 @@ export async function updateFixturesShelves( req, res ) {
|
|
|
1251
1253
|
|
|
1252
1254
|
const createdFixture = await storeFixtureService.findOneAndUpdate2( { storeName: layoutDoc.storeName, fixtureNumber: fixture?.['fixtureNumber'] }, { fixtureCode: fixture?.['Fixture ID'] } );
|
|
1253
1255
|
|
|
1254
|
-
|
|
1256
|
+
console.log( 'Fixture Data', fixtureData );
|
|
1255
1257
|
|
|
1256
1258
|
const vms = typeof fixture?.['VM Template ID'] === 'string' ? fixture?.['VM Template ID']?.split( ', ' ).map( ( item ) => item.trim() ) : [];
|
|
1257
1259
|
|
|
@@ -1300,7 +1302,7 @@ export async function updateFixturesShelves( req, res ) {
|
|
|
1300
1302
|
|
|
1301
1303
|
const createdShelf = await fixtureShelfService.create( shelfData );
|
|
1302
1304
|
|
|
1303
|
-
|
|
1305
|
+
console.log( 'Shelf Data:', createdShelf );
|
|
1304
1306
|
|
|
1305
1307
|
shelfIndex++;
|
|
1306
1308
|
}
|
|
@@ -1362,7 +1364,7 @@ export async function updateFixturesShelves( req, res ) {
|
|
|
1362
1364
|
|
|
1363
1365
|
const createdFixture = await storeFixtureService.findOneAndUpdate2( { storeName: layoutDoc.storeName, fixtureNumber: fixture?.['fixtureNumber'] }, { fixtureCode: fixture?.['Fixture ID'] } );
|
|
1364
1366
|
|
|
1365
|
-
|
|
1367
|
+
console.log( 'Fixture Data', fixtureData );
|
|
1366
1368
|
|
|
1367
1369
|
const vms = typeof fixture?.['VM Template ID'] === 'string' ? fixture?.['VM Template ID']?.split( ', ' ).map( ( item ) => item.trim() ) : [];
|
|
1368
1370
|
|
|
@@ -1487,7 +1489,7 @@ export async function updateFixturesShelves( req, res ) {
|
|
|
1487
1489
|
};
|
|
1488
1490
|
|
|
1489
1491
|
const createdFixture = await storeFixtureService.findOneAndUpdate2( { storeName: layoutDoc.storeName, fixtureNumber: fixture?.['fixtureNumber'] }, { fixtureCode: fixture?.['Fixture ID'] } );
|
|
1490
|
-
|
|
1492
|
+
console.log( 'Fixture Data', fixtureData );
|
|
1491
1493
|
|
|
1492
1494
|
const vms = typeof fixture?.['VM Template ID'] === 'string' ? fixture?.['VM Template ID']?.split( ', ' ).map( ( item ) => item.trim() ) : [];
|
|
1493
1495
|
|
|
@@ -1700,6 +1702,7 @@ export async function updateInventory( req, res ) {
|
|
|
1700
1702
|
console.log( updateData );
|
|
1701
1703
|
|
|
1702
1704
|
const product = await planoProductService.create( updateData );
|
|
1705
|
+
console.log( product );
|
|
1703
1706
|
}
|
|
1704
1707
|
|
|
1705
1708
|
|
|
@@ -1824,6 +1827,7 @@ export async function updatelayoutFeedback( req, res ) {
|
|
|
1824
1827
|
const layoutDoc = layoutFeedbacks[i].toObject();
|
|
1825
1828
|
|
|
1826
1829
|
const [ q1, q2, q3 ] = layoutDoc.answers;
|
|
1830
|
+
console.log( q3 );
|
|
1827
1831
|
|
|
1828
1832
|
if ( q1.value === false ) {
|
|
1829
1833
|
const floor = await storeBuilderService.findOne( { _id: layoutDoc.floorId } );
|
|
@@ -2136,6 +2140,7 @@ export async function updateFixtureFeedback( req, res ) {
|
|
|
2136
2140
|
const vmTask = vmTaskList[j].toObject();
|
|
2137
2141
|
|
|
2138
2142
|
const [ q1, q2 ] = vmTask.answers;
|
|
2143
|
+
console.log( q2 );
|
|
2139
2144
|
|
|
2140
2145
|
if ( q1.value ) continue;
|
|
2141
2146
|
|
|
@@ -2317,73 +2322,75 @@ export async function updateVmData( req, res ) {
|
|
|
2317
2322
|
}
|
|
2318
2323
|
|
|
2319
2324
|
|
|
2320
|
-
async function scrapeCrest() {
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
}
|
|
2325
|
+
// async function scrapeCrest() {
|
|
2326
|
+
// const storeIds = [ 'LKST682' ];
|
|
2327
|
+
// const apiUrl = 'https://api.getcrest.ai/api/ms_shelfsensei/layout/';
|
|
2328
|
+
// const bearerToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzQ4ODUwMzMyLCJpYXQiOjE3NDg4NDY3MzIsImp0aSI6ImNkNmRmNWZhYTg4ZDRmMjQ4YmZkYzFkMzkzZWYzMTg5IiwidXNlcl9pZCI6MTA4NSwiaWQiOjEwODUsImlzX21lZXNlZWtfYWNjb3VudCI6ZmFsc2UsImN1c3RvbWVyX2dyb3VwIjozOTgsImxpY2VuY2Vfc2NvcGVzIjpbeyJyZXNvdXJjZV9zZXQiOiJwcF9zZXQiLCJzY29wZV9yb2xlIjoiY29udHJpYnV0b3IifSx7InJlc291cmNlX3NldCI6ImRwX3NldCIsInNjb3BlX3JvbGUiOiJjb250cmlidXRvciJ9LHsicmVzb3VyY2Vfc2V0IjoiZGZfc2V0Iiwic2NvcGVfcm9sZSI6ImNvbnRyaWJ1dG9yIn0seyJyZXNvdXJjZV9zZXQiOiJkZWZhdWx0X3NldCIsInNjb3BlX3JvbGUiOiJjb250cmlidXRvciJ9XX0.8fclGcH6koHsKVmtGAQLscS80yNaVqPRkcpLhI3cnsk';
|
|
2329
|
+
// const filePath = 'response.json';
|
|
2330
|
+
// let allResults = [];
|
|
2331
|
+
|
|
2332
|
+
// if ( fs.existsSync( filePath ) ) {
|
|
2333
|
+
// try {
|
|
2334
|
+
// const existingData = fs.readFileSync( filePath, 'utf8' );
|
|
2335
|
+
// allResults = JSON.parse( existingData );
|
|
2336
|
+
// if ( !Array.isArray( allResults ) ) {
|
|
2337
|
+
// allResults = [];
|
|
2338
|
+
// }
|
|
2339
|
+
// } catch ( error ) {
|
|
2340
|
+
// console.error( 'Error reading existing JSON file:', error.message );
|
|
2341
|
+
// allResults = [];
|
|
2342
|
+
// }
|
|
2343
|
+
// }
|
|
2344
|
+
|
|
2345
|
+
// for ( const storeId of storeIds ) {
|
|
2346
|
+
// try {
|
|
2347
|
+
// const result = await new Promise( ( resolve ) => {
|
|
2348
|
+
// const payload = JSON.stringify( { store_id: storeId } );
|
|
2349
|
+
// const options = {
|
|
2350
|
+
// method: 'POST',
|
|
2351
|
+
// headers: {
|
|
2352
|
+
// 'Authorization': `Bearer ${bearerToken}`,
|
|
2353
|
+
// 'Content-Type': 'application/json',
|
|
2354
|
+
// 'Content-Length': Buffer.byteLength( payload ),
|
|
2355
|
+
// },
|
|
2356
|
+
// };
|
|
2357
|
+
|
|
2358
|
+
// const req = https.request( apiUrl, options, ( res ) => {
|
|
2359
|
+
// let data = '';
|
|
2360
|
+
// res.on( 'data', ( chunk ) => {
|
|
2361
|
+
// data += chunk;
|
|
2362
|
+
// } );
|
|
2363
|
+
// res.on( 'end', () => {
|
|
2364
|
+
// try {
|
|
2365
|
+
// const jsonData = JSON.parse( data );
|
|
2366
|
+
// const result = { storeName: storeId, data: jsonData };
|
|
2367
|
+
// allResults.push( result );
|
|
2368
|
+
// fs.writeFileSync( filePath, JSON.stringify( allResults, null, 2 ) );
|
|
2369
|
+
// console.log( 'Received Data:', result );
|
|
2370
|
+
// resolve( result );
|
|
2371
|
+
// } catch ( error ) {
|
|
2372
|
+
// console.error( `Error parsing JSON for ${storeId}:`, error.message );
|
|
2373
|
+
// resolve( { storeName: storeId, data: null } );
|
|
2374
|
+
// }
|
|
2375
|
+
// } );
|
|
2376
|
+
// } );
|
|
2377
|
+
|
|
2378
|
+
// req.on( 'error', ( error ) => {
|
|
2379
|
+
// console.error( `Error fetching data for ${storeId}:`, error.message );
|
|
2380
|
+
// resolve( { storeName: storeId, data: null } );
|
|
2381
|
+
// } );
|
|
2382
|
+
|
|
2383
|
+
// req.write( payload );
|
|
2384
|
+
// req.end();
|
|
2385
|
+
// } );
|
|
2386
|
+
// } catch ( error ) {
|
|
2387
|
+
// console.error( `Unexpected error for ${storeId}:`, error.message );
|
|
2388
|
+
// }
|
|
2389
|
+
// await new Promise( ( resolve ) => setTimeout( resolve, 1000 ) );
|
|
2390
|
+
// }
|
|
2391
|
+
// }
|
|
2392
|
+
|
|
2393
|
+
// scrapeCrest()
|
|
2387
2394
|
|
|
2388
2395
|
export async function createCrestPlanogram( req, res ) {
|
|
2389
2396
|
try {
|
|
@@ -3317,246 +3324,248 @@ export async function updateCrestVms( req, res ) {
|
|
|
3317
3324
|
}
|
|
3318
3325
|
|
|
3319
3326
|
|
|
3320
|
-
async function filterStores() {
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
const rawData = fs.readFileSync( 'crest_scrap_v1.json', 'utf8' );
|
|
3339
|
-
const allStores = JSON.parse( rawData );
|
|
3340
|
-
|
|
3341
|
-
const filteredStores = allStores.filter( ( store ) => stores.includes( store.storeName ) );
|
|
3342
|
-
|
|
3343
|
-
fs.writeFileSync( 'crest_filtered.json', JSON.stringify( filteredStores, null, 2 ) );
|
|
3344
|
-
}
|
|
3345
|
-
|
|
3346
|
-
import fsp from 'fs/promises';
|
|
3347
|
-
|
|
3348
|
-
import sharp from 'sharp';
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
const stitchImagesFromZips = async () => {
|
|
3352
|
-
const zip1Path = 'crest_plano.zip';
|
|
3353
|
-
const zip2Path = 'tango_plano.zip';
|
|
3354
|
-
const outputDir = 'stitched';
|
|
3355
|
-
|
|
3356
|
-
const loadZip = async ( zipPath ) => {
|
|
3357
|
-
const buffer = await fsp.readFile( zipPath );
|
|
3358
|
-
return await JSZip.loadAsync( buffer );
|
|
3359
|
-
};
|
|
3360
|
-
|
|
3361
|
-
const extractImages = async ( zip ) => {
|
|
3362
|
-
const imageFiles = {};
|
|
3363
|
-
const imageRegex = /\.(png|jpe?g)$/i;
|
|
3364
|
-
|
|
3365
|
-
for ( const [ name, file ] of Object.entries( zip.files ) ) {
|
|
3366
|
-
const base = path.basename( name );
|
|
3367
|
-
if ( !file.dir && imageRegex.test( base ) ) {
|
|
3368
|
-
imageFiles[base] = await file.async( 'nodebuffer' );
|
|
3369
|
-
}
|
|
3370
|
-
}
|
|
3371
|
-
|
|
3372
|
-
return imageFiles;
|
|
3373
|
-
};
|
|
3374
|
-
|
|
3375
|
-
const stitchOrCenter = async ( buffer1, buffer2, outputPath ) => {
|
|
3376
|
-
const totalWidth = 7000;
|
|
3377
|
-
const width1 = Math.round( totalWidth * 0.3 );
|
|
3378
|
-
const width2 = Math.round( totalWidth * 0.7 );
|
|
3379
|
-
|
|
3380
|
-
let img1 = buffer1 ? await sharp( buffer1 ).resize( { width: width1 } ).toBuffer() : null;
|
|
3381
|
-
let img2 = buffer2 ? await sharp( buffer2 ).resize( { width: width2 } ).toBuffer() : null;
|
|
3327
|
+
// async function filterStores() {
|
|
3328
|
+
// const stores = [
|
|
3329
|
+
// 'ST338', 'LKST1304', 'ST303', 'LKST1228', 'LKST499', 'LKST479', 'ST320',
|
|
3330
|
+
// 'LKST515', 'LKST406', 'ST392', 'ST328', 'ST332', 'LKST487', 'ST312',
|
|
3331
|
+
// 'LKST615', 'LKST352', 'LKST457', 'LKST439', 'LKST347', 'LKST1084',
|
|
3332
|
+
// 'LKST380', 'ST298', 'LKST356', 'LKST223', 'LKST480', 'ST30', 'ST285',
|
|
3333
|
+
// 'LKST500', 'LKST466', 'LKST321', 'LKST678', 'LKST383', 'LKST365',
|
|
3334
|
+
// 'LKST374', 'ST302', 'LKST420', 'LKST394', 'LKST444', 'LKST314',
|
|
3335
|
+
// 'LKST01', 'LKST357', 'LKST465', 'LKST331', 'LKST440', 'LKST345',
|
|
3336
|
+
// 'LKST389', 'ST330', 'LKST299', 'ST244', 'LKST294', 'ST314', 'LKST361',
|
|
3337
|
+
// 'LKST377', 'LKST390', 'ST335', 'LKST416', 'ST293', 'LKST341', 'LKST501',
|
|
3338
|
+
// 'LKST408', 'LKST227', 'LKST353', 'LKST364', 'ST318', 'LKST326',
|
|
3339
|
+
// 'LKST344', 'ST321', 'LKST384', 'LKST496', 'LKST427', 'LKST325',
|
|
3340
|
+
// 'LKST282', 'ST197', 'LKST388', 'LKST338', 'LKST371', 'ST326', 'LKST428',
|
|
3341
|
+
// 'LKST112', 'LKST334', 'ST319', 'LKST464', 'LKST490', 'LKST11',
|
|
3342
|
+
// 'LKST502', 'LKST1438',
|
|
3343
|
+
// ];
|
|
3382
3344
|
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
img2 ? sharp( img2 ).metadata() : Promise.resolve( { height: 0 } ),
|
|
3386
|
-
] );
|
|
3345
|
+
// const rawData = fs.readFileSync( 'crest_scrap_v1.json', 'utf8' );
|
|
3346
|
+
// const allStores = JSON.parse( rawData );
|
|
3387
3347
|
|
|
3388
|
-
|
|
3348
|
+
// const filteredStores = allStores.filter( ( store ) => stores.includes( store.storeName ) );
|
|
3389
3349
|
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
if ( img2 ) composites.push( { input: img2, top: 0, left: width1 } );
|
|
3393
|
-
|
|
3394
|
-
await sharp( {
|
|
3395
|
-
create: {
|
|
3396
|
-
width: totalWidth,
|
|
3397
|
-
height: maxHeight,
|
|
3398
|
-
channels: 4,
|
|
3399
|
-
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
|
3400
|
-
},
|
|
3401
|
-
} )
|
|
3402
|
-
.composite( composites )
|
|
3403
|
-
.png()
|
|
3404
|
-
.toFile( outputPath );
|
|
3405
|
-
};
|
|
3406
|
-
|
|
3407
|
-
try {
|
|
3408
|
-
await fsp.mkdir( outputDir, { recursive: true } );
|
|
3350
|
+
// fs.writeFileSync( 'crest_filtered.json', JSON.stringify( filteredStores, null, 2 ) );
|
|
3351
|
+
// }
|
|
3409
3352
|
|
|
3410
|
-
|
|
3411
|
-
const [ images1, images2 ] = await Promise.all( [ extractImages( zip1 ), extractImages( zip2 ) ] );
|
|
3353
|
+
// import fsp from 'fs/promises';
|
|
3412
3354
|
|
|
3413
|
-
|
|
3355
|
+
import sharp from 'sharp';
|
|
3414
3356
|
|
|
3415
|
-
for ( const name of allFilenames ) {
|
|
3416
|
-
const buffer1 = images1[name] || null;
|
|
3417
|
-
const buffer2 = images2[name] || null;
|
|
3418
|
-
const outputPath = path.join( outputDir, `${name.replace( /\.[^/.]+$/, '' )}.png` );
|
|
3419
3357
|
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3358
|
+
// const stitchImagesFromZips = async () => {
|
|
3359
|
+
// const zip1Path = 'crest_plano.zip';
|
|
3360
|
+
// const zip2Path = 'tango_plano.zip';
|
|
3361
|
+
// const outputDir = 'stitched';
|
|
3362
|
+
|
|
3363
|
+
// const loadZip = async ( zipPath ) => {
|
|
3364
|
+
// const buffer = await fsp.readFile( zipPath );
|
|
3365
|
+
// return await JSZip.loadAsync( buffer );
|
|
3366
|
+
// };
|
|
3367
|
+
|
|
3368
|
+
// const extractImages = async ( zip ) => {
|
|
3369
|
+
// const imageFiles = {};
|
|
3370
|
+
// const imageRegex = /\.(png|jpe?g)$/i;
|
|
3371
|
+
|
|
3372
|
+
// for ( const [ name, file ] of Object.entries( zip.files ) ) {
|
|
3373
|
+
// const base = path.basename( name );
|
|
3374
|
+
// if ( !file.dir && imageRegex.test( base ) ) {
|
|
3375
|
+
// imageFiles[base] = await file.async( 'nodebuffer' );
|
|
3376
|
+
// }
|
|
3377
|
+
// }
|
|
3378
|
+
|
|
3379
|
+
// return imageFiles;
|
|
3380
|
+
// };
|
|
3381
|
+
|
|
3382
|
+
// const stitchOrCenter = async ( buffer1, buffer2, outputPath ) => {
|
|
3383
|
+
// const totalWidth = 7000;
|
|
3384
|
+
// const width1 = Math.round( totalWidth * 0.3 );
|
|
3385
|
+
// const width2 = Math.round( totalWidth * 0.7 );
|
|
3386
|
+
|
|
3387
|
+
// let img1 = buffer1 ? await sharp( buffer1 ).resize( { width: width1 } ).toBuffer() : null;
|
|
3388
|
+
// let img2 = buffer2 ? await sharp( buffer2 ).resize( { width: width2 } ).toBuffer() : null;
|
|
3389
|
+
|
|
3390
|
+
// const [ meta1, meta2 ] = await Promise.all( [
|
|
3391
|
+
// img1 ? sharp( img1 ).metadata() : Promise.resolve( { height: 0 } ),
|
|
3392
|
+
// img2 ? sharp( img2 ).metadata() : Promise.resolve( { height: 0 } ),
|
|
3393
|
+
// ] );
|
|
3394
|
+
|
|
3395
|
+
// const maxHeight = Math.max( meta1.height, meta2.height );
|
|
3396
|
+
|
|
3397
|
+
// const composites = [];
|
|
3398
|
+
// if ( img1 ) composites.push( { input: img1, top: 0, left: 0 } );
|
|
3399
|
+
// if ( img2 ) composites.push( { input: img2, top: 0, left: width1 } );
|
|
3400
|
+
|
|
3401
|
+
// await sharp( {
|
|
3402
|
+
// create: {
|
|
3403
|
+
// width: totalWidth,
|
|
3404
|
+
// height: maxHeight,
|
|
3405
|
+
// channels: 4,
|
|
3406
|
+
// background: { r: 255, g: 255, b: 255, alpha: 0 },
|
|
3407
|
+
// },
|
|
3408
|
+
// } )
|
|
3409
|
+
// .composite( composites )
|
|
3410
|
+
// .png()
|
|
3411
|
+
// .toFile( outputPath );
|
|
3412
|
+
// };
|
|
3413
|
+
|
|
3414
|
+
// try {
|
|
3415
|
+
// await fsp.mkdir( outputDir, { recursive: true } );
|
|
3416
|
+
|
|
3417
|
+
// const [ zip1, zip2 ] = await Promise.all( [ loadZip( zip1Path ), loadZip( zip2Path ) ] );
|
|
3418
|
+
// const [ images1, images2 ] = await Promise.all( [ extractImages( zip1 ), extractImages( zip2 ) ] );
|
|
3419
|
+
|
|
3420
|
+
// const allFilenames = new Set( [ ...Object.keys( images1 ), ...Object.keys( images2 ) ] );
|
|
3421
|
+
|
|
3422
|
+
// for ( const name of allFilenames ) {
|
|
3423
|
+
// const buffer1 = images1[name] || null;
|
|
3424
|
+
// const buffer2 = images2[name] || null;
|
|
3425
|
+
// const outputPath = path.join( outputDir, `${name.replace( /\.[^/.]+$/, '' )}.png` );
|
|
3426
|
+
|
|
3427
|
+
// try {
|
|
3428
|
+
// await stitchOrCenter( buffer1, buffer2, outputPath );
|
|
3429
|
+
// console.log( ` Processed: ${name}` );
|
|
3430
|
+
// } catch ( err ) {
|
|
3431
|
+
// console.error( ` Error processing ${name}:`, err.message );
|
|
3432
|
+
// }
|
|
3433
|
+
// }
|
|
3434
|
+
// } catch ( err ) {
|
|
3435
|
+
// console.error( ' Unexpected error:', err.message );
|
|
3436
|
+
// }
|
|
3437
|
+
// };
|
|
3431
3438
|
|
|
3432
3439
|
// stitchImagesFromZips();
|
|
3433
3440
|
|
|
3434
3441
|
|
|
3435
|
-
import { Builder
|
|
3436
|
-
import chrome from 'selenium-webdriver/chrome.js';
|
|
3442
|
+
import { Builder } from 'selenium-webdriver';
|
|
3443
|
+
// import chrome from 'selenium-webdriver/chrome.js';
|
|
3437
3444
|
import fetch from 'node-fetch';
|
|
3438
3445
|
|
|
3439
3446
|
import fetchCookie from 'fetch-cookie';
|
|
3440
3447
|
|
|
3441
3448
|
|
|
3442
|
-
async function downloadCrestImages() {
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
}
|
|
3449
|
+
// async function downloadCrestImages() {
|
|
3450
|
+
// const storeList = await planoService.find( {} );
|
|
3451
|
+
// // const storeIds = storeList.map( ( store ) => store.toObject().storeName );
|
|
3452
|
+
// const storeIds = [ 'LKST1304' ];
|
|
3453
|
+
|
|
3454
|
+
|
|
3455
|
+
// const invalidateUrl = 'https://app.getcrest.ai/api/ms_iam/user/session/override/';
|
|
3456
|
+
// const tokenUrl = 'https://app.getcrest.ai/api/ms_iam/token/';
|
|
3457
|
+
|
|
3458
|
+
// let authToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzQ3NTEwNDAxLCJpYXQiOjE3NDc1MDY4MDEsImp0aSI6IjQ0YzNjOWNkZjUzYjQ5ZWE5OGQ3NWQxOTI1NGMxMGRkIiwidXNlcl9pZCI6MTA4NSwiaWQiOjEwODUsImlzX21lZXNlZWtfYWNjb3VudCI6ZmFsc2UsImN1c3RvbWVyX2dyb3VwIjozOTgsImxpY2VuY2Vfc2NvcGVzIjpbeyJyZXNvdXJjZV9zZXQiOiJwcF9zZXQiLCJzY29wZV9yb2xlIjoiY29udHJpYnV0b3IifSx7InJlc291cmNlX3NldCI6ImRwX3NldCIsInNjb3BlX3JvbGUiOiJjb250cmlidXRvciJ9LHsicmVzb3VyY2Vfc2V0IjoiZGZfc2V0Iiwic2NvcGVfcm9sZSI6ImNvbnRyaWJ1dG9yIn0seyJyZXNvdXJjZV9zZXQiOiJkZWZhdWx0X3NldCIsInNjb3BlX3JvbGUiOiJjb250cmlidXRvciJ9XX0.5OYkUq4kIWDUXothNCCfk6GIQHlhiMdOuHzuczWt6QM';
|
|
3459
|
+
|
|
3460
|
+
// const fetchWithCookies = fetchCookie( fetch );
|
|
3461
|
+
|
|
3462
|
+
// async function fetchNewToken() {
|
|
3463
|
+
// const invalidate = await fetchWithCookies( invalidateUrl, {
|
|
3464
|
+
// 'method': 'POST',
|
|
3465
|
+
// 'headers': { 'Content-Type': 'application/json' },
|
|
3466
|
+
// 'body': JSON.stringify( { 'email': 'tango.lenskart@getcrest.ai', 'password': 'Tangolenskart@123' } ),
|
|
3467
|
+
// } );
|
|
3468
|
+
|
|
3469
|
+
// const invalidateData = await invalidate.json();
|
|
3470
|
+
|
|
3471
|
+
// console.log( invalidateData );
|
|
3472
|
+
|
|
3473
|
+
// console.log( 'Fetching new token...' );
|
|
3474
|
+
// const res = await fetchWithCookies( tokenUrl, {
|
|
3475
|
+
// 'method': 'POST',
|
|
3476
|
+
// 'Accept': 'application/json, text/javascript, */*; q=0.01',
|
|
3477
|
+
// 'headers': { 'Content-Type': 'application/json' },
|
|
3478
|
+
// 'body': JSON.stringify( { 'email': 'tango.lenskart@getcrest.ai', 'password': 'Tangolenskart@123' } ),
|
|
3479
|
+
// } );
|
|
3480
|
+
|
|
3481
|
+
// if ( !res.ok ) {
|
|
3482
|
+
// throw new Error( `Failed to fetch token: ${res.status}` );
|
|
3483
|
+
// }
|
|
3484
|
+
|
|
3485
|
+
// const data = await res.json();
|
|
3486
|
+
// console.log( data );
|
|
3487
|
+
// authToken = data.access;
|
|
3488
|
+
// return authToken;
|
|
3489
|
+
// }
|
|
3490
|
+
|
|
3491
|
+
// async function runAutomation( token, storeId, retries = 3 ) {
|
|
3492
|
+
// let attempts = 0;
|
|
3493
|
+
|
|
3494
|
+
// while ( attempts < retries ) {
|
|
3495
|
+
// const options = new chrome.Options();
|
|
3496
|
+
// // options.addArguments( 'headless' );
|
|
3497
|
+
// options.addArguments( 'disable-gpu' );
|
|
3498
|
+
|
|
3499
|
+
// const driver = await new Builder()
|
|
3500
|
+
// .forBrowser( 'chrome' )
|
|
3501
|
+
// .setChromeOptions( options )
|
|
3502
|
+
// .build();
|
|
3503
|
+
|
|
3504
|
+
// try {
|
|
3505
|
+
// const url = `https://app.getcrest.ai/pvt/?auth=${token}&module=planno&store_id=${storeId}`;
|
|
3506
|
+
// await driver.get( url );
|
|
3507
|
+
// const currentUrl = await driver.getCurrentUrl();
|
|
3508
|
+
// if ( currentUrl.includes( '/login' ) ) {
|
|
3509
|
+
// console.warn( `Redirected to login for store ${storeId}. Retrying with new token...` );
|
|
3510
|
+
// await driver.quit();
|
|
3511
|
+
// const newToken = await fetchNewToken();
|
|
3512
|
+
// return await runAutomation( newToken, storeId, retries );
|
|
3513
|
+
// }
|
|
3514
|
+
|
|
3515
|
+
// const button = await driver.wait( until.elementLocated(
|
|
3516
|
+
// By.xpath( '//*[contains(@class, "MuiButtonBase-root") and contains(@class, "MuiButton-root") and contains(@class, "MuiButton-text") and contains(@class, "MuiButton-disableElevation") and contains(@class, "jss35") and contains(@class, "jss47") and contains(@class, "jss37") and contains(@class, "jss144")]' ),
|
|
3517
|
+
// ), 10000 );
|
|
3518
|
+
// await button.click();
|
|
3519
|
+
|
|
3520
|
+
// const checkbox = await driver.wait(
|
|
3521
|
+
// until.elementLocated(
|
|
3522
|
+
// By.xpath( '//*[contains(@class, "MuiCheckbox-root") and contains(@class, "MuiIconButton-root")]//input[@type="checkbox"]' ),
|
|
3523
|
+
// ),
|
|
3524
|
+
// 10000,
|
|
3525
|
+
// );
|
|
3526
|
+
// await checkbox.click();
|
|
3527
|
+
|
|
3528
|
+
// const downloadIcon = await driver.wait(
|
|
3529
|
+
// until.elementLocated(
|
|
3530
|
+
// By.xpath( '//button[contains(@class, "cool-tooltip")]' ),
|
|
3531
|
+
// ),
|
|
3532
|
+
// 10000,
|
|
3533
|
+
// );
|
|
3534
|
+
// await downloadIcon.click();
|
|
3535
|
+
|
|
3536
|
+
|
|
3537
|
+
// console.log( `Download triggered for store: ${storeId}` );
|
|
3538
|
+
// await driver.sleep( 5000 );
|
|
3539
|
+
// return;
|
|
3540
|
+
// } catch ( err ) {
|
|
3541
|
+
// attempts++;
|
|
3542
|
+
// console.error( `Error for store ${storeId}, attempt ${attempts}: ${err.message}` );
|
|
3543
|
+
// if ( attempts >= retries ) {
|
|
3544
|
+
// console.error( `Failed for store ${storeId} after ${retries} attempts` );
|
|
3545
|
+
// } else {
|
|
3546
|
+
// console.log( `Retrying for store ${storeId}, attempt ${attempts + 1}` );
|
|
3547
|
+
// }
|
|
3548
|
+
// } finally {
|
|
3549
|
+
// try {
|
|
3550
|
+
// if ( driver && ( await driver.getSession() ) ) {
|
|
3551
|
+
// await driver.quit();
|
|
3552
|
+
// }
|
|
3553
|
+
// } catch ( e ) {
|
|
3554
|
+
|
|
3555
|
+
// }
|
|
3556
|
+
// }
|
|
3557
|
+
// }
|
|
3558
|
+
// }
|
|
3559
|
+
|
|
3560
|
+
// for ( const storeId of storeIds ) {
|
|
3561
|
+
// try {
|
|
3562
|
+
// console.log( `Starting automation for store: ${storeId}` );
|
|
3563
|
+
// await runAutomation( authToken, storeId );
|
|
3564
|
+
// } catch ( error ) {
|
|
3565
|
+
// console.error( `Automation failed for store ${storeId}: ${error.message}` );
|
|
3566
|
+
// }
|
|
3567
|
+
// }
|
|
3568
|
+
// }
|
|
3560
3569
|
|
|
3561
3570
|
// downloadCrestImages();
|
|
3562
3571
|
export async function updatePlanoFixtureLayout( planoId, floorId ) {
|
|
@@ -4131,36 +4140,12 @@ export async function downloadPlanoImage( req, res ) {
|
|
|
4131
4140
|
date_string: { $gte: req.body.fromDate, $lte: req.body.toDate },
|
|
4132
4141
|
type: 'layout',
|
|
4133
4142
|
status: 'incomplete',
|
|
4143
|
+
storeName: { $in: req.body.store },
|
|
4134
4144
|
},
|
|
4135
4145
|
},
|
|
4136
|
-
{
|
|
4137
|
-
$lookup: {
|
|
4138
|
-
from: 'planograms',
|
|
4139
|
-
let: { plano_id: '$planoId' },
|
|
4140
|
-
pipeline: [
|
|
4141
|
-
{
|
|
4142
|
-
$match: {
|
|
4143
|
-
$expr: {
|
|
4144
|
-
$and: [
|
|
4145
|
-
{ $eq: [ '$_id', '$$plano_id' ] },
|
|
4146
|
-
],
|
|
4147
|
-
},
|
|
4148
|
-
},
|
|
4149
|
-
},
|
|
4150
|
-
{
|
|
4151
|
-
$project: {
|
|
4152
|
-
storeName: 1,
|
|
4153
|
-
_id: 0,
|
|
4154
|
-
},
|
|
4155
|
-
},
|
|
4156
|
-
],
|
|
4157
|
-
as: 'planogram',
|
|
4158
|
-
},
|
|
4159
|
-
},
|
|
4160
|
-
{ $unwind: { path: '$planogram', preserveNullAndEmptyArrays: true } },
|
|
4161
4146
|
{
|
|
4162
4147
|
$project: {
|
|
4163
|
-
storeName:
|
|
4148
|
+
storeName: 1,
|
|
4164
4149
|
answers: 1,
|
|
4165
4150
|
type: 1,
|
|
4166
4151
|
status: 1,
|
|
@@ -4174,17 +4159,18 @@ export async function downloadPlanoImage( req, res ) {
|
|
|
4174
4159
|
if ( !taskDetails.length ) {
|
|
4175
4160
|
return res.sendError( 'No data found', 204 );
|
|
4176
4161
|
}
|
|
4177
|
-
let planoList = taskDetails.map( ( ele ) => ele.planoId );
|
|
4178
|
-
|
|
4162
|
+
let planoList = [ ...new Set( taskDetails.map( ( ele ) => ele.planoId ) ) ];
|
|
4163
|
+
console.log( planoList );
|
|
4164
|
+
let storeList = [ ...new Set( taskDetails.map( ( ele ) => ele.storeName ) ) ];
|
|
4165
|
+
console.log( storeList );
|
|
4179
4166
|
async function sleep( ms ) {
|
|
4180
4167
|
return new Promise( ( resolve ) => setTimeout( resolve, ms ) );
|
|
4181
4168
|
}
|
|
4182
4169
|
|
|
4183
4170
|
async function openPlanoUrls( planoList ) {
|
|
4184
4171
|
for ( let id of planoList ) {
|
|
4185
|
-
const url = `
|
|
4172
|
+
const url = `https://plano-builder.tangoeye.ai/#/plano?planoId=${id}&token&download=1&url=http://localhost:3008`;
|
|
4186
4173
|
const driver = await new Builder().forBrowser( 'chrome' ).build();
|
|
4187
|
-
|
|
4188
4174
|
try {
|
|
4189
4175
|
await driver.get( url );
|
|
4190
4176
|
await sleep( 20000 );
|
|
@@ -4204,6 +4190,7 @@ export async function downloadPlanoImage( req, res ) {
|
|
|
4204
4190
|
if ( !req.body?.merge ) {
|
|
4205
4191
|
const downloadsPath = path.join( os.homedir(), 'Downloads' );
|
|
4206
4192
|
const targetFolder = path.join( __dirname, '..', '..', `${req.body.file}Images` );
|
|
4193
|
+
console.log( 'test' );
|
|
4207
4194
|
await openPlanoUrls( planoList );
|
|
4208
4195
|
if ( !fs.existsSync( targetFolder ) ) {
|
|
4209
4196
|
fs.mkdirSync( targetFolder, { recursive: true } );
|
|
@@ -4343,6 +4330,8 @@ export async function updateCrestPlanogram( req, res ) {
|
|
|
4343
4330
|
|
|
4344
4331
|
const layoutApiUrl = 'https://api.getcrest.ai/api/ms_shelfsensei/layout/';
|
|
4345
4332
|
let staticToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzQ1NTE3MjQxLCJpYXQiOjE3NDU1MTM2NDEsImp0aSI6Ijg3MWVlNTA3ODY2OTQ5OTVhMTQ0YTk4NzQyNzY0MzEzIiwidXNlcl9pZCI6MTA4NSwiaWQiOjEwODUsImlzX21lZXNlZWtfYWNjb3VudCI6ZmFsc2UsImN1c3RvbWVyX2dyb3VwIjozOTgsImxpY2VuY2Vfc2NvcGVzIjpbeyJyZXNvdXJjZV9zZXQiOiJwcF9zZXQiLCJzY29wZV9yb2xlIjoiY29udHJpYnV0b3IifSx7InJlc291cmNlX3NldCI6ImRwX3NldCIsInNjb3BlX3JvbGUiOiJjb250cmlidXRvciJ9LHsicmVzb3VyY2Vfc2V0IjoiZGZfc2V0Iiwic2NvcGVfcm9sZSI6ImNvbnRyaWJ1dG9yIn0seyJyZXNvdXJjZV9zZXQiOiJkZWZhdWx0X3NldCIsInNjb3BlX3JvbGUiOiJjb250cmlidXRvciJ9XX0.eGzTMGwwstr13M0Hu1Ls5-gkE_oSPMJJBL2wgygT6Ac';
|
|
4333
|
+
const fetchWithCookies = fetchCookie( fetch );
|
|
4334
|
+
|
|
4346
4335
|
|
|
4347
4336
|
async function fetchStoreData( store, bearerToken, res ) {
|
|
4348
4337
|
const payload = JSON.stringify( { store_id: store.toObject().storeName?.toUpperCase() } );
|
|
@@ -4392,8 +4381,6 @@ export async function updateCrestPlanogram( req, res ) {
|
|
|
4392
4381
|
|
|
4393
4382
|
|
|
4394
4383
|
const fetchNewToken = async () => {
|
|
4395
|
-
const fetchWithCookies = fetchCookie( fetch );
|
|
4396
|
-
|
|
4397
4384
|
const email = 'tango.lenskart@getcrest.ai';
|
|
4398
4385
|
const password = 'Tangolenskart@123';
|
|
4399
4386
|
|
|
@@ -4434,6 +4421,62 @@ export async function updateCrestPlanogram( req, res ) {
|
|
|
4434
4421
|
}
|
|
4435
4422
|
};
|
|
4436
4423
|
|
|
4424
|
+
const fetchVmImage = async ( attachmentId ) => {
|
|
4425
|
+
try {
|
|
4426
|
+
const response = await fetchWithCookies( `https://api.getcrest.ai/api/ms_data_preparation/master_data/attachment/?preview=0&attachment_id=${attachmentId}`, {
|
|
4427
|
+
method: 'GET',
|
|
4428
|
+
headers: {
|
|
4429
|
+
'Authorization': `Bearer ${staticToken}`,
|
|
4430
|
+
'Cookie': 'prod_session_key=w144dqljxlh096487nc33rm09vwtossh',
|
|
4431
|
+
},
|
|
4432
|
+
} );
|
|
4433
|
+
|
|
4434
|
+
if ( !response.ok ) {
|
|
4435
|
+
throw new Error( `Failed to fetch image: ${response.status}` );
|
|
4436
|
+
}
|
|
4437
|
+
|
|
4438
|
+
// const dest = fs.createWriteStream( `${attachmentId}.png` );
|
|
4439
|
+
// response.body.pipe( dest );
|
|
4440
|
+
|
|
4441
|
+
// return await response.buffer();
|
|
4442
|
+
|
|
4443
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
4444
|
+
return Buffer.from( arrayBuffer );
|
|
4445
|
+
} catch ( error ) {
|
|
4446
|
+
console.error( 'Error fetching image buffer:', error.message );
|
|
4447
|
+
throw error;
|
|
4448
|
+
}
|
|
4449
|
+
};
|
|
4450
|
+
|
|
4451
|
+
const getImageMetadata = async ( imageBuffer ) => {
|
|
4452
|
+
try {
|
|
4453
|
+
const metadata = await sharp( imageBuffer ).metadata();
|
|
4454
|
+
const { width, height, format } = metadata;
|
|
4455
|
+
|
|
4456
|
+
if ( !width || !height || !format ) throw new Error( 'Invalid image metadata' );
|
|
4457
|
+
|
|
4458
|
+
const ratio = width / height;
|
|
4459
|
+
const normalizedRatio = ratio > 1 ? ratio : 1 / ratio;
|
|
4460
|
+
const squareThreshold = 1.2;
|
|
4461
|
+
const imageShape = normalizedRatio <= squareThreshold ? 'square' : 'rectangle';
|
|
4462
|
+
|
|
4463
|
+
const fileExtension = format === 'jpeg' ? 'jpg' : format;
|
|
4464
|
+
const contentType = `image/${format}`;
|
|
4465
|
+
|
|
4466
|
+
return {
|
|
4467
|
+
imageShape,
|
|
4468
|
+
width,
|
|
4469
|
+
height,
|
|
4470
|
+
fileExtension,
|
|
4471
|
+
contentType,
|
|
4472
|
+
};
|
|
4473
|
+
} catch ( error ) {
|
|
4474
|
+
console.error( 'Error processing image buffer:', error.message );
|
|
4475
|
+
throw error;
|
|
4476
|
+
}
|
|
4477
|
+
};
|
|
4478
|
+
|
|
4479
|
+
|
|
4437
4480
|
if ( !req?.body?.storeName ) {
|
|
4438
4481
|
return res.sendError( 'No store supplied', 200 );
|
|
4439
4482
|
}
|
|
@@ -4442,7 +4485,7 @@ export async function updateCrestPlanogram( req, res ) {
|
|
|
4442
4485
|
clientId: '11',
|
|
4443
4486
|
$and: [
|
|
4444
4487
|
{ storeName: req.body.storeName },
|
|
4445
|
-
{ storeName: { $nin: [ 'LKST98', 'LKST1193' ] } },
|
|
4488
|
+
// { storeName: { $nin: [ 'LKST98', 'LKST1193' ] } },
|
|
4446
4489
|
],
|
|
4447
4490
|
};
|
|
4448
4491
|
|
|
@@ -4470,11 +4513,11 @@ export async function updateCrestPlanogram( req, res ) {
|
|
|
4470
4513
|
const existingPlanogram = await planoService.findOne( { storeName: storeData.storeName } );
|
|
4471
4514
|
|
|
4472
4515
|
if ( existingPlanogram ) {
|
|
4473
|
-
const checkTaskSubmitted = await planoTaskService.findOne( { planoId: existingPlanogram.toObject()._id } );
|
|
4516
|
+
// const checkTaskSubmitted = await planoTaskService.findOne( { planoId: existingPlanogram.toObject()._id } );
|
|
4474
4517
|
|
|
4475
4518
|
const checkTaskCreated = await processedTaskService.findOne( { storeName: storeData.storeName, date_string: dayjs().format( 'YYYY-MM-DD' ), isPlano: true } );
|
|
4476
4519
|
|
|
4477
|
-
if (
|
|
4520
|
+
if ( checkTaskCreated ) {
|
|
4478
4521
|
continue;
|
|
4479
4522
|
}
|
|
4480
4523
|
}
|
|
@@ -4789,6 +4832,37 @@ export async function updateCrestPlanogram( req, res ) {
|
|
|
4789
4832
|
|
|
4790
4833
|
if ( !configData ) return;
|
|
4791
4834
|
|
|
4835
|
+
let attachmentId = '';
|
|
4836
|
+
let imgPath = '';
|
|
4837
|
+
let imageMeta = null;
|
|
4838
|
+
|
|
4839
|
+
|
|
4840
|
+
if ( zone.preview_image_url ) {
|
|
4841
|
+
const parsedUrl = new URL( zone.preview_image_url );
|
|
4842
|
+
attachmentId = parsedUrl.searchParams.get( 'attachment_id' );
|
|
4843
|
+
|
|
4844
|
+
const isVmImageExist = await planoProductService.findOne( { crestImageId: attachmentId } );
|
|
4845
|
+
|
|
4846
|
+
|
|
4847
|
+
if ( !isVmImageExist ) {
|
|
4848
|
+
const vmImageData = await fetchVmImage( attachmentId );
|
|
4849
|
+
|
|
4850
|
+
imageMeta = await getImageMetadata( vmImageData );
|
|
4851
|
+
|
|
4852
|
+
const params = {
|
|
4853
|
+
Bucket: JSON.parse( process.env.BUCKET ).storeBuilder,
|
|
4854
|
+
Key: `crestVms/`,
|
|
4855
|
+
fileName: `${attachmentId}.${imageMeta.fileExtension}`,
|
|
4856
|
+
ContentType: imageMeta.contentType,
|
|
4857
|
+
body: vmImageData,
|
|
4858
|
+
};
|
|
4859
|
+
|
|
4860
|
+
const imgUpload = await fileUpload( params );
|
|
4861
|
+
|
|
4862
|
+
imgPath = imgUpload.Key;
|
|
4863
|
+
}
|
|
4864
|
+
}
|
|
4865
|
+
|
|
4792
4866
|
const insertData = {
|
|
4793
4867
|
'clientId': '11',
|
|
4794
4868
|
'productId': 'VMCR',
|
|
@@ -4808,6 +4882,30 @@ export async function updateCrestPlanogram( req, res ) {
|
|
|
4808
4882
|
'fixtureConfigId': fixtureConfig._id,
|
|
4809
4883
|
};
|
|
4810
4884
|
|
|
4885
|
+
if ( attachmentId && imgPath ) {
|
|
4886
|
+
insertData.crestImageId = attachmentId;
|
|
4887
|
+
insertData.productImageUrl = imgPath;
|
|
4888
|
+
|
|
4889
|
+
const shelfData = fixtureConfigDoc.shelfConfig
|
|
4890
|
+
.filter( ( shelf ) => shelf.shelfZone === configData.position )
|
|
4891
|
+
.sort( ( a, b ) => a.shelfNumber - b.shelfNumber );
|
|
4892
|
+
|
|
4893
|
+
if ( imageMeta.imageShape === 'square' ) {
|
|
4894
|
+
insertData.productHeight.value = 100;
|
|
4895
|
+
insertData.productWidth.value = 230;
|
|
4896
|
+
|
|
4897
|
+
if ( shelfData.length ) {
|
|
4898
|
+
insertData.startYPosition = shelfData[0].shelfNumber;
|
|
4899
|
+
insertData.endYPosition = shelfData[shelfData.length - 1].shelfNumber;
|
|
4900
|
+
}
|
|
4901
|
+
}
|
|
4902
|
+
|
|
4903
|
+
// if ( imageMeta.imageShape === 'rectangle' ) {
|
|
4904
|
+
// insertData.productHeight.value = 100;
|
|
4905
|
+
// insertData.productWidth.value = 905;
|
|
4906
|
+
// }
|
|
4907
|
+
}
|
|
4908
|
+
|
|
4811
4909
|
const vmTemplate = await planoProductService.upsertOne(
|
|
4812
4910
|
{
|
|
4813
4911
|
'productName': vm.productName,
|
|
@@ -4966,6 +5064,37 @@ export async function updateCrestPlanogram( req, res ) {
|
|
|
4966
5064
|
|
|
4967
5065
|
if ( !configData ) return;
|
|
4968
5066
|
|
|
5067
|
+
let attachmentId = '';
|
|
5068
|
+
let imgPath = '';
|
|
5069
|
+
let imageMeta = null;
|
|
5070
|
+
|
|
5071
|
+
|
|
5072
|
+
if ( zone.preview_image_url ) {
|
|
5073
|
+
const parsedUrl = new URL( zone.preview_image_url );
|
|
5074
|
+
attachmentId = parsedUrl.searchParams.get( 'attachment_id' );
|
|
5075
|
+
|
|
5076
|
+
const isVmImageExist = await planoProductService.findOne( { crestImageId: attachmentId } );
|
|
5077
|
+
|
|
5078
|
+
|
|
5079
|
+
if ( !isVmImageExist ) {
|
|
5080
|
+
const vmImageData = await fetchVmImage( attachmentId );
|
|
5081
|
+
|
|
5082
|
+
imageMeta = await getImageMetadata( vmImageData );
|
|
5083
|
+
|
|
5084
|
+
const params = {
|
|
5085
|
+
Bucket: JSON.parse( process.env.BUCKET ).storeBuilder,
|
|
5086
|
+
Key: `crestVms/`,
|
|
5087
|
+
fileName: `${attachmentId}.${imageMeta.fileExtension}`,
|
|
5088
|
+
ContentType: imageMeta.contentType,
|
|
5089
|
+
body: vmImageData,
|
|
5090
|
+
};
|
|
5091
|
+
|
|
5092
|
+
const imgUpload = await fileUpload( params );
|
|
5093
|
+
|
|
5094
|
+
imgPath = imgUpload.Key;
|
|
5095
|
+
}
|
|
5096
|
+
}
|
|
5097
|
+
|
|
4969
5098
|
const insertData = {
|
|
4970
5099
|
'clientId': '11',
|
|
4971
5100
|
'productId': 'VMCR',
|
|
@@ -4985,6 +5114,30 @@ export async function updateCrestPlanogram( req, res ) {
|
|
|
4985
5114
|
'fixtureConfigId': fixtureConfig._id,
|
|
4986
5115
|
};
|
|
4987
5116
|
|
|
5117
|
+
if ( attachmentId && imgPath ) {
|
|
5118
|
+
insertData.crestImageId = attachmentId;
|
|
5119
|
+
insertData.productImageUrl = imgPath;
|
|
5120
|
+
|
|
5121
|
+
const shelfData = fixtureConfigDoc.shelfConfig
|
|
5122
|
+
.filter( ( shelf ) => shelf.shelfZone === configData.position )
|
|
5123
|
+
.sort( ( a, b ) => a.shelfNumber - b.shelfNumber );
|
|
5124
|
+
|
|
5125
|
+
if ( imageMeta.imageShape === 'square' ) {
|
|
5126
|
+
insertData.productHeight.value = 100;
|
|
5127
|
+
insertData.productWidth.value = 230;
|
|
5128
|
+
|
|
5129
|
+
if ( shelfData.length ) {
|
|
5130
|
+
insertData.startYPosition = shelfData[0].shelfNumber;
|
|
5131
|
+
insertData.endYPosition = shelfData[shelfData.length - 1].shelfNumber;
|
|
5132
|
+
}
|
|
5133
|
+
}
|
|
5134
|
+
|
|
5135
|
+
// if ( imageMeta.imageShape === 'rectangle' ) {
|
|
5136
|
+
// insertData.productHeight.value = 100;
|
|
5137
|
+
// insertData.productWidth.value = 905;
|
|
5138
|
+
// }
|
|
5139
|
+
}
|
|
5140
|
+
|
|
4988
5141
|
const vmTemplate = await planoProductService.upsertOne(
|
|
4989
5142
|
{
|
|
4990
5143
|
'productName': vm.productName,
|
|
@@ -5142,6 +5295,38 @@ export async function updateCrestPlanogram( req, res ) {
|
|
|
5142
5295
|
|
|
5143
5296
|
if ( !configData ) return;
|
|
5144
5297
|
|
|
5298
|
+
let attachmentId = '';
|
|
5299
|
+
let imgPath = '';
|
|
5300
|
+
let imageMeta = null;
|
|
5301
|
+
|
|
5302
|
+
|
|
5303
|
+
if ( zone.preview_image_url ) {
|
|
5304
|
+
const parsedUrl = new URL( zone.preview_image_url );
|
|
5305
|
+
attachmentId = parsedUrl.searchParams.get( 'attachment_id' );
|
|
5306
|
+
|
|
5307
|
+
const isVmImageExist = await planoProductService.findOne( { crestImageId: attachmentId } );
|
|
5308
|
+
|
|
5309
|
+
|
|
5310
|
+
if ( !isVmImageExist ) {
|
|
5311
|
+
const vmImageData = await fetchVmImage( attachmentId );
|
|
5312
|
+
|
|
5313
|
+
imageMeta = await getImageMetadata( vmImageData );
|
|
5314
|
+
|
|
5315
|
+
const params = {
|
|
5316
|
+
Bucket: JSON.parse( process.env.BUCKET ).storeBuilder,
|
|
5317
|
+
Key: `crestVms/`,
|
|
5318
|
+
fileName: `${attachmentId}.${imageMeta.fileExtension}`,
|
|
5319
|
+
ContentType: imageMeta.contentType,
|
|
5320
|
+
body: vmImageData,
|
|
5321
|
+
};
|
|
5322
|
+
|
|
5323
|
+
const imgUpload = await fileUpload( params );
|
|
5324
|
+
|
|
5325
|
+
imgPath = imgUpload.Key;
|
|
5326
|
+
}
|
|
5327
|
+
}
|
|
5328
|
+
|
|
5329
|
+
|
|
5145
5330
|
const insertData = {
|
|
5146
5331
|
'clientId': '11',
|
|
5147
5332
|
'productId': 'VMCR',
|
|
@@ -5161,6 +5346,30 @@ export async function updateCrestPlanogram( req, res ) {
|
|
|
5161
5346
|
'fixtureConfigId': fixtureConfig._id,
|
|
5162
5347
|
};
|
|
5163
5348
|
|
|
5349
|
+
if ( attachmentId && imgPath ) {
|
|
5350
|
+
insertData.crestImageId = attachmentId;
|
|
5351
|
+
insertData.productImageUrl = imgPath;
|
|
5352
|
+
|
|
5353
|
+
const shelfData = fixtureConfigDoc.shelfConfig
|
|
5354
|
+
.filter( ( shelf ) => shelf.shelfZone === configData.position )
|
|
5355
|
+
.sort( ( a, b ) => a.shelfNumber - b.shelfNumber );
|
|
5356
|
+
|
|
5357
|
+
if ( imageMeta.imageShape === 'square' ) {
|
|
5358
|
+
insertData.productHeight.value = 100;
|
|
5359
|
+
insertData.productWidth.value = 230;
|
|
5360
|
+
|
|
5361
|
+
if ( shelfData.length ) {
|
|
5362
|
+
insertData.startYPosition = shelfData[0].shelfNumber;
|
|
5363
|
+
insertData.endYPosition = shelfData[shelfData.length - 1].shelfNumber;
|
|
5364
|
+
}
|
|
5365
|
+
}
|
|
5366
|
+
|
|
5367
|
+
// if ( imageMeta.imageShape === 'rectangle' ) {
|
|
5368
|
+
// insertData.productHeight.value = 100;
|
|
5369
|
+
// insertData.productWidth.value = 905;
|
|
5370
|
+
// }
|
|
5371
|
+
}
|
|
5372
|
+
|
|
5164
5373
|
const vmTemplate = await planoProductService.upsertOne(
|
|
5165
5374
|
{
|
|
5166
5375
|
'productName': vm.productName,
|
|
@@ -5498,7 +5707,7 @@ export async function getVideoLinks( req, res ) {
|
|
|
5498
5707
|
continue;
|
|
5499
5708
|
}
|
|
5500
5709
|
const [ q1, q2, q3 ] = data.answers;
|
|
5501
|
-
|
|
5710
|
+
console.log( q1, q2 );
|
|
5502
5711
|
const params = {
|
|
5503
5712
|
Bucket: 'tango-planogram',
|
|
5504
5713
|
file_path: q3?.video || null,
|
|
@@ -6791,28 +7000,28 @@ export async function updateExcelPlanogram( req, res ) {
|
|
|
6791
7000
|
}
|
|
6792
7001
|
}
|
|
6793
7002
|
|
|
6794
|
-
async function downloadImage() {
|
|
6795
|
-
|
|
7003
|
+
// async function downloadImage() {
|
|
7004
|
+
// const url = 'https://api.getcrest.ai/api/ms_data_preparation/master_data/attachment/?preview=0&attachment_id=2934';
|
|
6796
7005
|
|
|
6797
|
-
|
|
6798
|
-
|
|
6799
|
-
|
|
6800
|
-
|
|
6801
|
-
|
|
6802
|
-
|
|
6803
|
-
|
|
7006
|
+
// try {
|
|
7007
|
+
// const response = await fetch( url, {
|
|
7008
|
+
// headers: {
|
|
7009
|
+
// Authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzQ3MjE0MjcxLCJpYXQiOjE3NDcyMTA2NzEsImp0aSI6ImM4ZjQ4ZDY2YWJkYzRmNDU4MWI4OGE4MTMwODVjOTUwIiwidXNlcl9pZCI6MTA4NSwiaWQiOjEwODUsImlzX21lZXNlZWtfYWNjb3VudCI6ZmFsc2UsImN1c3RvbWVyX2dyb3VwIjozOTgsImxpY2VuY2Vfc2NvcGVzIjpbeyJyZXNvdXJjZV9zZXQiOiJwcF9zZXQiLCJzY29wZV9yb2xlIjoiY29udHJpYnV0b3IifSx7InJlc291cmNlX3NldCI6ImRwX3NldCIsInNjb3BlX3JvbGUiOiJjb250cmlidXRvciJ9LHsicmVzb3VyY2Vfc2V0IjoiZGZfc2V0Iiwic2NvcGVfcm9sZSI6ImNvbnRyaWJ1dG9yIn0seyJyZXNvdXJjZV9zZXQiOiJkZWZhdWx0X3NldCIsInNjb3BlX3JvbGUiOiJjb250cmlidXRvciJ9XX0.IOw_0yNA6CMBCIn7cxjPR0FqHI949WplCKzlkr8aK7g',
|
|
7010
|
+
// Cookie: 'prod_session_key=w144dqljxlh096487nc33rm09vwtossh; prod_session_key=7mljy9k7niwpw4btbbyvuhkz7otbdh6v',
|
|
7011
|
+
// },
|
|
7012
|
+
// } );
|
|
6804
7013
|
|
|
6805
|
-
|
|
7014
|
+
// if ( !response.ok ) throw new Error( `HTTP error! Status: ${response.status}` );
|
|
6806
7015
|
|
|
6807
|
-
|
|
6808
|
-
|
|
7016
|
+
// const dest = fs.createWriteStream( '2934.png' );
|
|
7017
|
+
// response.body.pipe( dest );
|
|
6809
7018
|
|
|
6810
|
-
|
|
6811
|
-
|
|
6812
|
-
|
|
6813
|
-
|
|
6814
|
-
|
|
6815
|
-
}
|
|
7019
|
+
// dest.on( 'finish', () => console.log( 'Image saved as image.jpg' ) );
|
|
7020
|
+
// dest.on( 'error', ( err ) => console.error( 'File write error:', err ) );
|
|
7021
|
+
// } catch ( err ) {
|
|
7022
|
+
// console.error( 'Fetch error:', err );
|
|
7023
|
+
// }
|
|
7024
|
+
// }
|
|
6816
7025
|
|
|
6817
7026
|
// downloadImage();
|
|
6818
7027
|
|
|
@@ -6857,3 +7066,1420 @@ export async function recorrectTaskData( req, res ) {
|
|
|
6857
7066
|
return res.sendError( e, 500 );
|
|
6858
7067
|
}
|
|
6859
7068
|
}
|
|
7069
|
+
|
|
7070
|
+
|
|
7071
|
+
export async function migrateCrestv1( req, res ) {
|
|
7072
|
+
try {
|
|
7073
|
+
if ( req?.headers?.authorization?.split( ' ' )[1] !== 'hwjXfCD6TgMvc82cuSGZ9bNv9MuXsaiQ6uvx' ) {
|
|
7074
|
+
return res.sendError( 'Unauthorized', 401 );
|
|
7075
|
+
}
|
|
7076
|
+
|
|
7077
|
+
const startTime = Date.now();
|
|
7078
|
+
|
|
7079
|
+
const layoutApiUrl = 'https://api.getcrest.ai/api/ms_shelfsensei/layout/';
|
|
7080
|
+
let staticToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzQ1NTE3MjQxLCJpYXQiOjE3NDU1MTM2NDEsImp0aSI6Ijg3MWVlNTA3ODY2OTQ5OTVhMTQ0YTk4NzQyNzY0MzEzIiwidXNlcl9pZCI6MTA4NSwiaWQiOjEwODUsImlzX21lZXNlZWtfYWNjb3VudCI6ZmFsc2UsImN1c3RvbWVyX2dyb3VwIjozOTgsImxpY2VuY2Vfc2NvcGVzIjpbeyJyZXNvdXJjZV9zZXQiOiJwcF9zZXQiLCJzY29wZV9yb2xlIjoiY29udHJpYnV0b3IifSx7InJlc291cmNlX3NldCI6ImRwX3NldCIsInNjb3BlX3JvbGUiOiJjb250cmlidXRvciJ9LHsicmVzb3VyY2Vfc2V0IjoiZGZfc2V0Iiwic2NvcGVfcm9sZSI6ImNvbnRyaWJ1dG9yIn0seyJyZXNvdXJjZV9zZXQiOiJkZWZhdWx0X3NldCIsInNjb3BlX3JvbGUiOiJjb250cmlidXRvciJ9XX0.eGzTMGwwstr13M0Hu1Ls5-gkE_oSPMJJBL2wgygT6Ac';
|
|
7081
|
+
const fetchWithCookies = fetchCookie( fetch );
|
|
7082
|
+
|
|
7083
|
+
|
|
7084
|
+
async function fetchStoreData( store, bearerToken, res ) {
|
|
7085
|
+
const payload = JSON.stringify( { store_id: store.toObject().storeName?.toUpperCase() } );
|
|
7086
|
+
|
|
7087
|
+
try {
|
|
7088
|
+
const response = await fetch( layoutApiUrl, {
|
|
7089
|
+
method: 'POST',
|
|
7090
|
+
headers: {
|
|
7091
|
+
'Authorization': `Bearer ${bearerToken}`,
|
|
7092
|
+
'Content-Type': 'application/json',
|
|
7093
|
+
'Content-Length': Buffer.byteLength( payload ),
|
|
7094
|
+
},
|
|
7095
|
+
body: payload,
|
|
7096
|
+
} );
|
|
7097
|
+
|
|
7098
|
+
const data = await response.text();
|
|
7099
|
+
let jsonData = null;
|
|
7100
|
+
|
|
7101
|
+
try {
|
|
7102
|
+
jsonData = JSON.parse( data );
|
|
7103
|
+
} catch ( parseError ) {
|
|
7104
|
+
logger.error( { functionName: `Warning: Received invalid JSON for store ${store.toObject().storeName}`, error: parseError } );
|
|
7105
|
+
console.warn( `Warning: Received invalid JSON for store ${store.toObject().storeName}` );
|
|
7106
|
+
return { storeName: store.toObject().storeName, data: null };
|
|
7107
|
+
}
|
|
7108
|
+
|
|
7109
|
+
if ( jsonData.result === 'Token is invalid or expired' ) {
|
|
7110
|
+
console.log( 'Token expired, retrying...' );
|
|
7111
|
+
try {
|
|
7112
|
+
const newToken = await fetchNewToken();
|
|
7113
|
+
staticToken = newToken;
|
|
7114
|
+
return await fetchStoreData( store, newToken, res );
|
|
7115
|
+
} catch ( retryError ) {
|
|
7116
|
+
logger.error( { functionName: 'Failed to refresh token', error: retryError } );
|
|
7117
|
+
console.log( retryError );
|
|
7118
|
+
return res.sendError( 'Failed to refresh token', 401 );
|
|
7119
|
+
}
|
|
7120
|
+
}
|
|
7121
|
+
|
|
7122
|
+
return { storeName: store.toObject().storeName, data: jsonData };
|
|
7123
|
+
} catch ( error ) {
|
|
7124
|
+
logger.error( { functionName: `Error fetching data for ${store.toObject().storeName}:`, error } );
|
|
7125
|
+
console.error( `Error fetching data for ${store.toObject().storeName}:`, error.message );
|
|
7126
|
+
return { storeName: store.toObject().storeName, data: null };
|
|
7127
|
+
}
|
|
7128
|
+
}
|
|
7129
|
+
|
|
7130
|
+
|
|
7131
|
+
const fetchNewToken = async () => {
|
|
7132
|
+
const email = 'tango.lenskart@getcrest.ai';
|
|
7133
|
+
const password = 'Tangolenskart@123';
|
|
7134
|
+
|
|
7135
|
+
const credentials = JSON.stringify( { email, password } );
|
|
7136
|
+
|
|
7137
|
+
const invalidateUrl = 'https://app.getcrest.ai/api/ms_iam/user/session/override/';
|
|
7138
|
+
const tokenUrl = 'https://app.getcrest.ai/api/ms_iam/token/';
|
|
7139
|
+
|
|
7140
|
+
try {
|
|
7141
|
+
const invalidateRes = await fetchWithCookies( invalidateUrl, {
|
|
7142
|
+
method: 'POST',
|
|
7143
|
+
headers: {
|
|
7144
|
+
'Content-Type': 'application/json',
|
|
7145
|
+
},
|
|
7146
|
+
body: credentials,
|
|
7147
|
+
} );
|
|
7148
|
+
|
|
7149
|
+
const invalidateData = await invalidateRes.json();
|
|
7150
|
+
console.log( 'Invalidate response:', invalidateData );
|
|
7151
|
+
|
|
7152
|
+
console.log( 'Fetching new token...' );
|
|
7153
|
+
const tokenRes = await fetchWithCookies( tokenUrl, {
|
|
7154
|
+
method: 'POST',
|
|
7155
|
+
headers: {
|
|
7156
|
+
'Content-Type': 'application/json',
|
|
7157
|
+
'Accept': 'application/json, text/javascript, */*; q=0.01',
|
|
7158
|
+
},
|
|
7159
|
+
body: credentials,
|
|
7160
|
+
} );
|
|
7161
|
+
|
|
7162
|
+
const tokenData = await tokenRes.json();
|
|
7163
|
+
console.log( 'Token response:', tokenData );
|
|
7164
|
+
|
|
7165
|
+
return tokenData.access;
|
|
7166
|
+
} catch ( error ) {
|
|
7167
|
+
console.error( 'Error fetching new token:', error );
|
|
7168
|
+
throw error;
|
|
7169
|
+
}
|
|
7170
|
+
};
|
|
7171
|
+
|
|
7172
|
+
const fetchVmImage = async ( attachmentId ) => {
|
|
7173
|
+
try {
|
|
7174
|
+
const response = await fetchWithCookies( `https://api.getcrest.ai/api/ms_data_preparation/master_data/attachment/?preview=0&attachment_id=${attachmentId}`, {
|
|
7175
|
+
method: 'GET',
|
|
7176
|
+
headers: {
|
|
7177
|
+
'Authorization': `Bearer ${staticToken}`,
|
|
7178
|
+
'Cookie': 'prod_session_key=w144dqljxlh096487nc33rm09vwtossh',
|
|
7179
|
+
},
|
|
7180
|
+
} );
|
|
7181
|
+
|
|
7182
|
+
|
|
7183
|
+
if ( !response.ok ) {
|
|
7184
|
+
return;
|
|
7185
|
+
// throw new Error( `Failed to fetch image: ${response.status}` );
|
|
7186
|
+
}
|
|
7187
|
+
|
|
7188
|
+
// const dest = fs.createWriteStream( `${attachmentId}.png` );
|
|
7189
|
+
// response.body.pipe( dest );
|
|
7190
|
+
|
|
7191
|
+
return await response.buffer();
|
|
7192
|
+
} catch ( error ) {
|
|
7193
|
+
console.error( 'Error fetching image buffer:', error.message );
|
|
7194
|
+
throw error;
|
|
7195
|
+
}
|
|
7196
|
+
};
|
|
7197
|
+
|
|
7198
|
+
const getImageMetadata = async ( imageBuffer ) => {
|
|
7199
|
+
try {
|
|
7200
|
+
const metadata = await sharp( imageBuffer ).metadata();
|
|
7201
|
+
const { width, height, format } = metadata;
|
|
7202
|
+
|
|
7203
|
+
if ( !width || !height || !format ) throw new Error( 'Invalid image metadata' );
|
|
7204
|
+
|
|
7205
|
+
const ratio = width / height;
|
|
7206
|
+
const normalizedRatio = ratio > 1 ? ratio : 1 / ratio;
|
|
7207
|
+
const squareThreshold = 1.2;
|
|
7208
|
+
const imageShape = normalizedRatio <= squareThreshold ? 'square' : 'rectangle';
|
|
7209
|
+
|
|
7210
|
+
const fileExtension = format === 'jpeg' ? 'jpg' : format;
|
|
7211
|
+
const contentType = `image/${format}`;
|
|
7212
|
+
|
|
7213
|
+
return {
|
|
7214
|
+
imageShape,
|
|
7215
|
+
width,
|
|
7216
|
+
height,
|
|
7217
|
+
fileExtension,
|
|
7218
|
+
contentType,
|
|
7219
|
+
};
|
|
7220
|
+
} catch ( error ) {
|
|
7221
|
+
console.error( 'Error processing image buffer:', error.message );
|
|
7222
|
+
throw error;
|
|
7223
|
+
}
|
|
7224
|
+
};
|
|
7225
|
+
|
|
7226
|
+
|
|
7227
|
+
async function generateFixtureTemplateName( baseName, fixtureWidth ) {
|
|
7228
|
+
function escapeRegex( str ) {
|
|
7229
|
+
return str.replace( /[.*+?^${}()|[\]\\]/g, '\\$&' );
|
|
7230
|
+
}
|
|
7231
|
+
|
|
7232
|
+
const escapedBase = escapeRegex( baseName );
|
|
7233
|
+
const regexPattern = new RegExp( `^Template-(\\d+)-${escapedBase}$` );
|
|
7234
|
+
|
|
7235
|
+
const existingFixtures = await fixtureConfigService.find( {
|
|
7236
|
+
fixtureName: { $regex: new RegExp( `^Template-(\\d+)-${escapedBase}$` ) },
|
|
7237
|
+
fixtureWidth: fixtureWidth,
|
|
7238
|
+
} );
|
|
7239
|
+
|
|
7240
|
+
const usedNumbers = existingFixtures
|
|
7241
|
+
.map( ( doc ) => {
|
|
7242
|
+
const match = doc.fixtureName.match( regexPattern );
|
|
7243
|
+
return match ? parseInt( match[1], 10 ) : null;
|
|
7244
|
+
} )
|
|
7245
|
+
.filter( ( num ) => num !== null );
|
|
7246
|
+
|
|
7247
|
+
const nextNumber = usedNumbers.length > 0 ? Math.max( ...usedNumbers ) + 1 : 1;
|
|
7248
|
+
|
|
7249
|
+
return `Template-${nextNumber}-${baseName}`;
|
|
7250
|
+
}
|
|
7251
|
+
|
|
7252
|
+
|
|
7253
|
+
if ( !req?.body?.storeName ) {
|
|
7254
|
+
return res.sendError( 'No store supplied', 200 );
|
|
7255
|
+
}
|
|
7256
|
+
|
|
7257
|
+
let storeQuery = {
|
|
7258
|
+
clientId: '11',
|
|
7259
|
+
$and: [
|
|
7260
|
+
{ storeName: req.body.storeName },
|
|
7261
|
+
// { storeName: { $in: [ 'LKST98' ] } },
|
|
7262
|
+
// { storeName: { $nin: [ 'LKST98', 'LKST1193' ] } },
|
|
7263
|
+
],
|
|
7264
|
+
};
|
|
7265
|
+
|
|
7266
|
+
let storeList = await storeService.find( storeQuery );
|
|
7267
|
+
|
|
7268
|
+
const constantFixtureLength = 1220;
|
|
7269
|
+
const constantDetailedFixtureLength = 1220;
|
|
7270
|
+
|
|
7271
|
+
const constantFixtureWidth = 610;
|
|
7272
|
+
const constantDetailedFixtureWidth = 1524;
|
|
7273
|
+
|
|
7274
|
+
const mmToFeet = 305;
|
|
7275
|
+
|
|
7276
|
+
function roundToTwo( num ) {
|
|
7277
|
+
return Math.round( num * 100 ) / 100;
|
|
7278
|
+
}
|
|
7279
|
+
|
|
7280
|
+
|
|
7281
|
+
for ( let i = 0; i < storeList.length; i++ ) {
|
|
7282
|
+
const storeData = await fetchStoreData( storeList[i], staticToken, res );
|
|
7283
|
+
|
|
7284
|
+
if ( storeData?.data?.message !== 'SUCCESS' ) continue;
|
|
7285
|
+
|
|
7286
|
+
|
|
7287
|
+
const storeDetails = storeList[i];
|
|
7288
|
+
|
|
7289
|
+
const existingPlanogram = await planoService.findOne( { storeName: storeData.storeName } );
|
|
7290
|
+
|
|
7291
|
+
if ( existingPlanogram ) {
|
|
7292
|
+
const checkTaskSubmitted = await planoTaskService.findOne( { planoId: existingPlanogram.toObject()._id } );
|
|
7293
|
+
|
|
7294
|
+
const checkTaskCreated = await processedTaskService.findOne( { storeName: storeData.storeName, date_string: dayjs().format( 'YYYY-MM-DD' ), isPlano: true } );
|
|
7295
|
+
|
|
7296
|
+
if ( checkTaskSubmitted || checkTaskCreated ) {
|
|
7297
|
+
continue;
|
|
7298
|
+
}
|
|
7299
|
+
}
|
|
7300
|
+
|
|
7301
|
+
|
|
7302
|
+
if ( existingPlanogram?.toObject()?._id && mongoose.Types.ObjectId.isValid( existingPlanogram?.toObject()?._id ) ) {
|
|
7303
|
+
await Promise.all( [ planoService.deleteOne( { _id: existingPlanogram?.toObject()?._id } ), storeBuilderService.deleteMany( { planoId: existingPlanogram?.toObject()?._id } ),
|
|
7304
|
+
storeFixtureService.deleteMany( { planoId: existingPlanogram?.toObject()?._id } ), fixtureShelfService.deleteMany( { planoId: existingPlanogram?.toObject()?._id } ),
|
|
7305
|
+
planoMappingService.deleteMany( { planoId: existingPlanogram?.toObject()?._id } ),
|
|
7306
|
+
] );
|
|
7307
|
+
}
|
|
7308
|
+
|
|
7309
|
+
|
|
7310
|
+
const planoInsertData = {
|
|
7311
|
+
storeName: storeData.storeName,
|
|
7312
|
+
storeId: storeDetails?.toObject()?.storeId ? storeDetails.toObject().storeId : 'nil',
|
|
7313
|
+
layoutName: `${storeData.storeName} - Layout`,
|
|
7314
|
+
clientId: '11',
|
|
7315
|
+
attachments: [],
|
|
7316
|
+
createdBy: new mongoose.Types.ObjectId( '66a78cd82734f4f857cd6db6' ),
|
|
7317
|
+
createdByName: 'Bejan',
|
|
7318
|
+
createdByEmail: 'bejan@tangotech.co.in',
|
|
7319
|
+
status: 'completed',
|
|
7320
|
+
floorNumber: 1,
|
|
7321
|
+
productResolutionLevel: 'L2',
|
|
7322
|
+
scanType: 'qr',
|
|
7323
|
+
};
|
|
7324
|
+
|
|
7325
|
+
const insertedPlano = await planoService.upsertOne( { storeName: storeData.storeName }, planoInsertData );
|
|
7326
|
+
const planoDoc = insertedPlano.toObject();
|
|
7327
|
+
|
|
7328
|
+
const floors = new Set();
|
|
7329
|
+
|
|
7330
|
+
for ( const item of storeData.data.result ) {
|
|
7331
|
+
if ( item.floor ) {
|
|
7332
|
+
floors.add( item.floor );
|
|
7333
|
+
}
|
|
7334
|
+
|
|
7335
|
+
if ( Array.isArray( item.fixtures ) ) {
|
|
7336
|
+
for ( const fixture of item.fixtures ) {
|
|
7337
|
+
if ( fixture.floor ) {
|
|
7338
|
+
floors.add( fixture.floor );
|
|
7339
|
+
}
|
|
7340
|
+
}
|
|
7341
|
+
}
|
|
7342
|
+
}
|
|
7343
|
+
|
|
7344
|
+
const floorArray = Array.from( floors );
|
|
7345
|
+
|
|
7346
|
+
let isFloorKeyExist = true;
|
|
7347
|
+
|
|
7348
|
+
if ( !floorArray.length ) {
|
|
7349
|
+
isFloorKeyExist = false;
|
|
7350
|
+
floorArray.push( 'GROUND' );
|
|
7351
|
+
}
|
|
7352
|
+
|
|
7353
|
+
for ( let floorIndex = 0; floorIndex < floorArray.length; floorIndex++ ) {
|
|
7354
|
+
const leftWall = storeData.data.result.filter( ( entry ) => entry['main'] === 'LEFT WALL' );
|
|
7355
|
+
let leftFixtures = leftWall.flatMap( ( wall ) => wall.fixtures );
|
|
7356
|
+
if ( isFloorKeyExist ) {
|
|
7357
|
+
leftFixtures = leftFixtures.filter( ( fixture ) => fixture.floor === floorArray[floorIndex] );
|
|
7358
|
+
}
|
|
7359
|
+
const rightWall = storeData.data.result.filter( ( entry ) => entry['main'] === 'RIGHT WALL' );
|
|
7360
|
+
let rightFixtures = rightWall.flatMap( ( wall ) => wall.fixtures );
|
|
7361
|
+
if ( isFloorKeyExist ) {
|
|
7362
|
+
rightFixtures = rightFixtures.filter( ( fixture ) => fixture.floor === floorArray[floorIndex] );
|
|
7363
|
+
}
|
|
7364
|
+
const backWall = storeData.data.result.filter( ( entry ) => entry['main'] === 'RIGHT VERTICAL WALL' );
|
|
7365
|
+
let backFixtures = backWall.flatMap( ( wall ) => wall.fixtures );
|
|
7366
|
+
if ( isFloorKeyExist ) {
|
|
7367
|
+
backFixtures = backFixtures.filter( ( fixture ) => fixture.floor === floorArray[floorIndex] );
|
|
7368
|
+
}
|
|
7369
|
+
let floorFixtures = storeData.data.result.filter(
|
|
7370
|
+
( entry ) => entry['main'] === 'Euro Center' || entry['main'] === 'Euro Center Dr',
|
|
7371
|
+
);
|
|
7372
|
+
if ( isFloorKeyExist ) {
|
|
7373
|
+
floorFixtures = floorFixtures.filter( ( fixture ) => fixture.floor === floorArray[floorIndex] );
|
|
7374
|
+
}
|
|
7375
|
+
|
|
7376
|
+
const leftXDistanceFeet = leftFixtures.length ? roundToTwo( ( leftFixtures.length * ( constantFixtureLength / mmToFeet ) ) ) : 0;
|
|
7377
|
+
const leftXDetailedDistanceFeet = leftFixtures.length ? roundToTwo( ( leftFixtures.length * ( constantDetailedFixtureLength / mmToFeet ) ) ) : 0;
|
|
7378
|
+
|
|
7379
|
+
const leftYDistanceFeet = leftFixtures.length ? roundToTwo( ( ( constantFixtureWidth / mmToFeet ) ) ) : 0;
|
|
7380
|
+
const leftYDetailedDistanceFeet = leftFixtures.length ? roundToTwo( ( ( constantDetailedFixtureWidth / mmToFeet ) ) ) : 0;
|
|
7381
|
+
|
|
7382
|
+
const rightXDistanceFeet = rightFixtures.length ? roundToTwo( ( rightFixtures.length * ( constantFixtureLength / mmToFeet ) ) ) : 0;
|
|
7383
|
+
const rightXDetailedDistanceFeet = rightFixtures.length ? roundToTwo( ( rightFixtures.length * ( constantDetailedFixtureLength / mmToFeet ) ) ) : 0;
|
|
7384
|
+
|
|
7385
|
+
const rightYDistanceFeet = rightFixtures.length ? roundToTwo( ( constantFixtureWidth / mmToFeet ) ) : 0;
|
|
7386
|
+
const rightYDetailedDistanceFeet = rightFixtures.length ? roundToTwo( ( constantDetailedFixtureWidth / mmToFeet ) ): 0;
|
|
7387
|
+
|
|
7388
|
+
const maxFixturesPerRow = floorFixtures.length/2;
|
|
7389
|
+
const totalRows = 2;
|
|
7390
|
+
|
|
7391
|
+
const floorXDistanceFeet = floorFixtures.length ? roundToTwo( ( ( floorFixtures.length/2 ) * ( constantFixtureLength / mmToFeet ) ) ) : 0;
|
|
7392
|
+
const floorXDetailedDistanceFeet = floorFixtures.length ? roundToTwo( ( ( floorFixtures.length/2 ) * ( constantDetailedFixtureLength / mmToFeet ) ) ): 0;
|
|
7393
|
+
|
|
7394
|
+
const floorYDistanceFeet = floorFixtures.length ? roundToTwo( ( 2 * ( constantFixtureWidth/ mmToFeet ) ) ): 0;
|
|
7395
|
+
const floorYDetailedDistanceFeet = floorFixtures.length ? roundToTwo( 2 * ( constantDetailedFixtureWidth/mmToFeet ) ): 0;
|
|
7396
|
+
|
|
7397
|
+
const backXDistanceFeet = backFixtures.length ? roundToTwo( ( constantFixtureWidth / mmToFeet ) ) : 0;
|
|
7398
|
+
const backXDetailedDistanceFeet = backFixtures.length ? roundToTwo( ( constantDetailedFixtureLength / mmToFeet ) ) : 0;
|
|
7399
|
+
|
|
7400
|
+
const backYDistanceFeet = backFixtures.length ? roundToTwo( ( ( backFixtures.length * ( constantFixtureLength / mmToFeet ) ) + ( ( ( leftFixtures.length ? 1 : 0 ) + ( rightFixtures.length ? 1 : 0 ) * constantFixtureWidth )/mmToFeet ) ) ) : 0;
|
|
7401
|
+
const backYDetailedDistanceFeet = backFixtures.length ? roundToTwo( ( ( backFixtures.length * ( constantDetailedFixtureWidth / mmToFeet ) ) + ( ( ( leftFixtures.length ? 1 : 0 ) + ( rightFixtures.length ? 1 : 0 ) * constantDetailedFixtureWidth )/mmToFeet ) ) ): 0;
|
|
7402
|
+
|
|
7403
|
+
const maxXDistance = Math.max( leftXDistanceFeet, rightXDistanceFeet, floorXDistanceFeet );
|
|
7404
|
+
const maxXDetailedDistance = Math.max( leftXDetailedDistanceFeet, rightXDetailedDistanceFeet, floorXDetailedDistanceFeet );
|
|
7405
|
+
|
|
7406
|
+
const maxYDistance = Math.max( floorYDistanceFeet, backYDistanceFeet );
|
|
7407
|
+
const maxYDetailedDistance = Math.max( floorYDetailedDistanceFeet, backYDetailedDistanceFeet );
|
|
7408
|
+
|
|
7409
|
+
const finalXDistance = roundToTwo( ( maxXDistance < ( backXDistanceFeet + floorXDistanceFeet )? ( ( backXDistanceFeet + floorXDistanceFeet ) + ( ( 2 * constantFixtureLength )/mmToFeet ) ) : ( floorFixtures.length && backFixtures.length ) ? ( maxXDistance + ( ( 2 * constantFixtureLength )/mmToFeet ) ) : maxXDistance ) );
|
|
7410
|
+
const finalXDetailedDistance = roundToTwo( ( maxXDetailedDistance < ( backXDetailedDistanceFeet + floorXDetailedDistanceFeet )? ( ( backXDetailedDistanceFeet + floorXDetailedDistanceFeet ) + ( ( 2 * constantDetailedFixtureLength )/mmToFeet ) ) : ( floorFixtures.length && backFixtures.length ) ? ( maxXDetailedDistance + ( ( 2 * constantDetailedFixtureLength )/mmToFeet ) ) : maxXDetailedDistance ) );
|
|
7411
|
+
|
|
7412
|
+
const finalYDistance = roundToTwo( ( maxYDistance < ( leftYDistanceFeet + rightYDistanceFeet + floorYDistanceFeet ) ? ( ( leftYDistanceFeet + rightYDistanceFeet + floorYDistanceFeet ) + ( ( 2 * constantFixtureWidth )/mmToFeet ) ) : ( maxYDistance + ( ( constantFixtureWidth )/mmToFeet ) ) ) );
|
|
7413
|
+
const finalYDetailedDistance = roundToTwo( ( maxYDetailedDistance < ( leftYDetailedDistanceFeet + rightYDetailedDistanceFeet + floorYDetailedDistanceFeet ) ? ( ( leftYDetailedDistanceFeet + rightYDetailedDistanceFeet + floorYDetailedDistanceFeet ) + ( ( 2 * constantDetailedFixtureWidth )/mmToFeet ) ) : ( maxYDetailedDistance + ( ( constantDetailedFixtureWidth )/mmToFeet ) ) ) );
|
|
7414
|
+
|
|
7415
|
+
|
|
7416
|
+
const floorInsertData = {
|
|
7417
|
+
storeName: planoDoc.storeName,
|
|
7418
|
+
storeId: storeDetails?.toObject()?.storeId ? storeDetails.toObject().storeId : 'nil',
|
|
7419
|
+
layoutName: `${planoDoc.storeName} - Layout`,
|
|
7420
|
+
clientId: '11',
|
|
7421
|
+
floorNumber: floorIndex + 1,
|
|
7422
|
+
floorName: `${floorArray[floorIndex].toLowerCase()} floor`,
|
|
7423
|
+
crestLayout: true,
|
|
7424
|
+
layoutPolygon: [
|
|
7425
|
+
{
|
|
7426
|
+
elementType: 'wall',
|
|
7427
|
+
distance: finalXDistance,
|
|
7428
|
+
unit: 'ft',
|
|
7429
|
+
direction: 'right',
|
|
7430
|
+
angle: 90,
|
|
7431
|
+
elementNumber: 1,
|
|
7432
|
+
detailedDistance: finalXDetailedDistance,
|
|
7433
|
+
},
|
|
7434
|
+
{
|
|
7435
|
+
elementType: 'wall',
|
|
7436
|
+
distance: finalYDistance,
|
|
7437
|
+
unit: 'ft',
|
|
7438
|
+
direction: 'down',
|
|
7439
|
+
angle: 90,
|
|
7440
|
+
elementNumber: 2,
|
|
7441
|
+
detailedDistance: finalYDetailedDistance,
|
|
7442
|
+
},
|
|
7443
|
+
{
|
|
7444
|
+
elementType: 'wall',
|
|
7445
|
+
distance: finalXDistance,
|
|
7446
|
+
unit: 'ft',
|
|
7447
|
+
direction: 'left',
|
|
7448
|
+
angle: 90,
|
|
7449
|
+
elementNumber: 3,
|
|
7450
|
+
detailedDistance: finalXDetailedDistance,
|
|
7451
|
+
},
|
|
7452
|
+
{
|
|
7453
|
+
elementType: 'wall',
|
|
7454
|
+
distance: roundToTwo( ( ( finalYDistance * 40 ) / 100 ) ),
|
|
7455
|
+
unit: 'ft',
|
|
7456
|
+
direction: 'up',
|
|
7457
|
+
angle: 90,
|
|
7458
|
+
elementNumber: 4,
|
|
7459
|
+
detailedDistance: roundToTwo( ( ( finalYDetailedDistance * 35 ) / 100 ) ),
|
|
7460
|
+
},
|
|
7461
|
+
{
|
|
7462
|
+
elementType: 'entrance',
|
|
7463
|
+
distance: roundToTwo( ( ( finalYDistance * 20 ) / 100 ) ),
|
|
7464
|
+
unit: 'ft',
|
|
7465
|
+
direction: 'up',
|
|
7466
|
+
angle: 90,
|
|
7467
|
+
elementNumber: 1,
|
|
7468
|
+
detailedDistance: roundToTwo( ( ( finalYDetailedDistance * 30 ) / 100 ) ),
|
|
7469
|
+
},
|
|
7470
|
+
{
|
|
7471
|
+
elementType: 'wall',
|
|
7472
|
+
distance: roundToTwo( ( ( finalYDistance * 40 ) / 100 ) ),
|
|
7473
|
+
unit: 'ft',
|
|
7474
|
+
direction: 'up',
|
|
7475
|
+
angle: 90,
|
|
7476
|
+
elementNumber: 5,
|
|
7477
|
+
detailedDistance: roundToTwo( ( ( finalYDetailedDistance * 35 ) / 100 ) ),
|
|
7478
|
+
},
|
|
7479
|
+
],
|
|
7480
|
+
createdBy: new mongoose.Types.ObjectId( '66a78cd82734f4f857cd6db6' ),
|
|
7481
|
+
createdByName: 'Bejan',
|
|
7482
|
+
createdByEmail: 'bejan@tangotech.co.in',
|
|
7483
|
+
status: 'completed',
|
|
7484
|
+
planoId: planoDoc._id,
|
|
7485
|
+
};
|
|
7486
|
+
|
|
7487
|
+
const layoutDoc = await storeBuilderService.upsertOne( { planoId: planoDoc._id, floorNumber: floorIndex + 1 }, floorInsertData );
|
|
7488
|
+
|
|
7489
|
+
let fixtureCounter = 1;
|
|
7490
|
+
|
|
7491
|
+
|
|
7492
|
+
for ( let index = 0; index < leftFixtures.length; index++ ) {
|
|
7493
|
+
const fixture = leftFixtures[index];
|
|
7494
|
+
|
|
7495
|
+
const fixtureConfig = await fixtureLibraryService.findOne( { fixtureCategory: fixture.fixtureType } );
|
|
7496
|
+
if ( !fixtureConfig ) continue;
|
|
7497
|
+
const fixtureConfigDoc = fixtureConfig.toObject();
|
|
7498
|
+
|
|
7499
|
+
let mapKey = `${fixtureConfigDoc.fixtureCategory}${fixtureConfigDoc.fixtureWidth.value}${fixtureConfigDoc.fixtureWidth.unit},${fixture.header}`;
|
|
7500
|
+
|
|
7501
|
+
const fixtureProductSubBrandName = new Set();
|
|
7502
|
+
|
|
7503
|
+
|
|
7504
|
+
const shelfTemplate = fixtureConfigDoc.shelfConfig.map( ( configShelf, j ) => {
|
|
7505
|
+
const shelfZone = fixture.productZones.find( ( zone ) => zone.zoneName === configShelf.shelfZone );
|
|
7506
|
+
const shelfSection = shelfZone?.products.find( ( product ) => !product.isMerchandisingElement );
|
|
7507
|
+
|
|
7508
|
+
const shelfIdentifier = `shelf${j + 1}=${shelfSection?.productName}`;
|
|
7509
|
+
|
|
7510
|
+
mapKey += ','+shelfIdentifier;
|
|
7511
|
+
|
|
7512
|
+
const productSubBrandName = shelfSection?.productName?.replace( /\s*PIDs\b/g, '' )?.split( /\s*\+\s*/ ) || [];
|
|
7513
|
+
|
|
7514
|
+
productSubBrandName.forEach( ( item ) => fixtureProductSubBrandName.add( item ) );
|
|
7515
|
+
|
|
7516
|
+
return {
|
|
7517
|
+
shelfNumber: j+1,
|
|
7518
|
+
shelfType: configShelf?.shelfType,
|
|
7519
|
+
productPerShelf: configShelf?.productPerShelf,
|
|
7520
|
+
trayRows: configShelf?.trayRows,
|
|
7521
|
+
productBrandName: productSubBrandName,
|
|
7522
|
+
zone: configShelf.shelfZone,
|
|
7523
|
+
};
|
|
7524
|
+
} );
|
|
7525
|
+
|
|
7526
|
+
const vmConfig = fixture.productZones?.flatMap( ( zone ) => {
|
|
7527
|
+
const vms = zone.products.filter( ( vm ) => vm.isMerchandisingElement );
|
|
7528
|
+
const vmConfig = fixtureConfigDoc.vmConfig.filter( ( vm ) => vm.position === zone.zoneName );
|
|
7529
|
+
const pids = zone.products.filter( ( vm ) => !vm.isMerchandisingElement );
|
|
7530
|
+
|
|
7531
|
+
return vms.map( ( vm, k ) => {
|
|
7532
|
+
let configData = vmConfig[0];
|
|
7533
|
+
|
|
7534
|
+
if ( vm.productName === 'Creatr' && zone.zoneName === 'Mid' ) {
|
|
7535
|
+
configData = vmConfig.find( ( config ) => config.vmWidthmm === 905 );
|
|
7536
|
+
configData.zone = 'stretch';
|
|
7537
|
+
}
|
|
7538
|
+
|
|
7539
|
+
if ( vm.productName === 'Creatr' && zone.zoneName === 'Mid' && pids.length ) {
|
|
7540
|
+
configData = vmConfig.find( ( config ) => config.vmWidthmm === 230 );
|
|
7541
|
+
}
|
|
7542
|
+
|
|
7543
|
+
if ( !configData ) return;
|
|
7544
|
+
|
|
7545
|
+
const vmIdentifier = `vm${k+1}=${vm.productName}+${configData.vmHeightmm}+${configData.vmWidthmm}+${configData.startShelf}+${configData.endShelf}+${configData.zone}`;
|
|
7546
|
+
|
|
7547
|
+
mapKey += ','+vmIdentifier;
|
|
7548
|
+
|
|
7549
|
+
return {
|
|
7550
|
+
startYPosition: configData.startShelf,
|
|
7551
|
+
endYPosition: configData.endShelf,
|
|
7552
|
+
xZone: configData.zone,
|
|
7553
|
+
vmName: vm.productName,
|
|
7554
|
+
vmHeight: configData.vmHeightmm,
|
|
7555
|
+
vmWidth: configData.vmWidthmm,
|
|
7556
|
+
imageUrl: zone?.actual_image_url,
|
|
7557
|
+
};
|
|
7558
|
+
} );
|
|
7559
|
+
} );
|
|
7560
|
+
|
|
7561
|
+
const vmTemplate = await Promise.all( vmConfig.map( async ( vmTemplate ) => {
|
|
7562
|
+
const vmInsertData = {
|
|
7563
|
+
clientId: '11',
|
|
7564
|
+
vmName: vmTemplate.vmName,
|
|
7565
|
+
vmHeight: {
|
|
7566
|
+
value: vmTemplate.vmHeight,
|
|
7567
|
+
unit: 'mm',
|
|
7568
|
+
},
|
|
7569
|
+
vmWidth: {
|
|
7570
|
+
value: vmTemplate.vmWidth,
|
|
7571
|
+
unit: 'mm',
|
|
7572
|
+
},
|
|
7573
|
+
status: 'complete',
|
|
7574
|
+
vmBrand: vmTemplate.vmBrand,
|
|
7575
|
+
};
|
|
7576
|
+
if ( vmTemplate?.imageUrl ) {
|
|
7577
|
+
const parsedUrl = new URL( vmTemplate.imageUrl );
|
|
7578
|
+
const attachmentId = parsedUrl.searchParams.get( 'attachment_id' );
|
|
7579
|
+
|
|
7580
|
+
const isVmImageExist = await planoVmService.findOne( { crestImageId: attachmentId } );
|
|
7581
|
+
|
|
7582
|
+
if ( !isVmImageExist ) {
|
|
7583
|
+
const vmImageData = await fetchVmImage( attachmentId );
|
|
7584
|
+
|
|
7585
|
+
const imageMeta = await getImageMetadata( vmImageData );
|
|
7586
|
+
|
|
7587
|
+
const params = {
|
|
7588
|
+
Bucket: JSON.parse( process.env.BUCKET ).storeBuilder,
|
|
7589
|
+
Key: `vmType/`,
|
|
7590
|
+
fileName: `${attachmentId}.${imageMeta.fileExtension}`,
|
|
7591
|
+
ContentType: imageMeta.contentType,
|
|
7592
|
+
body: vmImageData,
|
|
7593
|
+
};
|
|
7594
|
+
|
|
7595
|
+
const imgUpload = await fileUpload( params );
|
|
7596
|
+
|
|
7597
|
+
vmInsertData.crestImageId = attachmentId;
|
|
7598
|
+
vmInsertData.vmImageUrl = imgUpload.Key;
|
|
7599
|
+
|
|
7600
|
+
|
|
7601
|
+
if ( imageMeta.imageShape === 'square' ) {
|
|
7602
|
+
vmInsertData.vmHeight.value = 100;
|
|
7603
|
+
vmInsertData.vmWidth.value = 230;
|
|
7604
|
+
}
|
|
7605
|
+
} else {
|
|
7606
|
+
vmInsertData.crestImageId = attachmentId;
|
|
7607
|
+
vmInsertData.vmImageUrl = isVmImageExist.toObject().vmImageUrl;
|
|
7608
|
+
}
|
|
7609
|
+
}
|
|
7610
|
+
|
|
7611
|
+
const vmDetails = await planoVmService.upsertOne(
|
|
7612
|
+
{
|
|
7613
|
+
'productName': vmInsertData.vmName,
|
|
7614
|
+
},
|
|
7615
|
+
vmInsertData,
|
|
7616
|
+
);
|
|
7617
|
+
|
|
7618
|
+
return {
|
|
7619
|
+
vmId: vmDetails.toObject()._id,
|
|
7620
|
+
startYPosition: vmTemplate.startYPosition,
|
|
7621
|
+
endYPosition: vmTemplate.endYPosition,
|
|
7622
|
+
xZone: vmTemplate.xZone,
|
|
7623
|
+
};
|
|
7624
|
+
} ) );
|
|
7625
|
+
|
|
7626
|
+
const baseFixtureName = `${fixtureConfigDoc.fixtureCategory}`;
|
|
7627
|
+
const uniqueFixtureName = await generateFixtureTemplateName( baseFixtureName, fixtureConfigDoc.fixtureWidth );
|
|
7628
|
+
|
|
7629
|
+
|
|
7630
|
+
const fixtureTemplateData = {
|
|
7631
|
+
...fixtureConfigDoc,
|
|
7632
|
+
'shelfConfig': shelfTemplate,
|
|
7633
|
+
'vmConfig': vmTemplate,
|
|
7634
|
+
'clientId': fixtureConfigDoc.clientId,
|
|
7635
|
+
'fixtureName': uniqueFixtureName,
|
|
7636
|
+
'header': {
|
|
7637
|
+
label: fixture.header ? fixture.header : fixture.fixtureSubname[0],
|
|
7638
|
+
isEnabled: true,
|
|
7639
|
+
},
|
|
7640
|
+
'footer': {
|
|
7641
|
+
label: fixture.footer,
|
|
7642
|
+
isEnabled: true,
|
|
7643
|
+
},
|
|
7644
|
+
'isBodyEnabled': true,
|
|
7645
|
+
'productResolutionLevel': 'L3',
|
|
7646
|
+
'productBrandName': [ ...fixtureProductSubBrandName ],
|
|
7647
|
+
'fixtureLibraryId': fixtureConfigDoc._id,
|
|
7648
|
+
'crestMapKey': mapKey,
|
|
7649
|
+
};
|
|
7650
|
+
|
|
7651
|
+
delete fixtureTemplateData._id;
|
|
7652
|
+
|
|
7653
|
+
|
|
7654
|
+
const fixtureTemplate = await fixtureConfigService.upsertOne(
|
|
7655
|
+
{ crestMapKey: mapKey },
|
|
7656
|
+
fixtureTemplateData,
|
|
7657
|
+
);
|
|
7658
|
+
|
|
7659
|
+
const fixtureData = {
|
|
7660
|
+
...fixtureTemplate.toObject(),
|
|
7661
|
+
'storeName': layoutDoc.storeName,
|
|
7662
|
+
'storeId': storeDetails?.toObject()?.storeId ? storeDetails.toObject().storeId : 'nil',
|
|
7663
|
+
'planoId': layoutDoc.planoId,
|
|
7664
|
+
'floorId': layoutDoc._id,
|
|
7665
|
+
'associatedElementType': 'wall',
|
|
7666
|
+
'associatedElementNumber': 1,
|
|
7667
|
+
'relativePosition': {
|
|
7668
|
+
'x': roundToTwo( ( index * ( constantFixtureLength / mmToFeet ) ) ),
|
|
7669
|
+
'y': 0,
|
|
7670
|
+
'unit': 'ft',
|
|
7671
|
+
},
|
|
7672
|
+
'fixtureNumber': fixtureCounter,
|
|
7673
|
+
'relativeDetailedPosition': {
|
|
7674
|
+
'x': roundToTwo( ( index * ( constantDetailedFixtureLength / mmToFeet ) ) ),
|
|
7675
|
+
'y': 0,
|
|
7676
|
+
'unit': 'ft',
|
|
7677
|
+
},
|
|
7678
|
+
'associatedElementFixtureNumber': index+1,
|
|
7679
|
+
'fixtureConfigId': fixtureTemplate.toObject()._id,
|
|
7680
|
+
};
|
|
7681
|
+
|
|
7682
|
+
delete fixtureData._id;
|
|
7683
|
+
delete fixtureData.shelfConfig;
|
|
7684
|
+
|
|
7685
|
+
const createdFixture = await storeFixtureService.upsertOne(
|
|
7686
|
+
{
|
|
7687
|
+
floorId: layoutDoc._id,
|
|
7688
|
+
fixtureNumber: fixtureCounter++,
|
|
7689
|
+
},
|
|
7690
|
+
fixtureData,
|
|
7691
|
+
);
|
|
7692
|
+
|
|
7693
|
+
if ( !fixtureConfigDoc.shelfConfig.length || fixture.header === 'CL' || fixture.fixtureSubname?.includes( 'CL' ) ) continue;
|
|
7694
|
+
|
|
7695
|
+
fixtureTemplate.shelfConfig.forEach( async ( configShelf, j ) => {
|
|
7696
|
+
const shelfData = {
|
|
7697
|
+
'clientId': '11',
|
|
7698
|
+
'storeName': layoutDoc.storeName,
|
|
7699
|
+
'storeId': storeDetails?.toObject()?.storeId ? storeDetails.toObject().storeId : 'nil',
|
|
7700
|
+
'planoId': layoutDoc.planoId,
|
|
7701
|
+
'floorId': layoutDoc._id,
|
|
7702
|
+
'fixtureId': createdFixture._id,
|
|
7703
|
+
'shelfNumber': j + 1,
|
|
7704
|
+
'shelfOrder': 'LTR',
|
|
7705
|
+
'shelfCapacity': configShelf.shelfCapacity,
|
|
7706
|
+
'productBrandName': configShelf.productBrandName,
|
|
7707
|
+
'shelfType': configShelf.shelfType,
|
|
7708
|
+
'productPerShelf': configShelf.productPerShelf,
|
|
7709
|
+
'trayRows': configShelf.trayRows,
|
|
7710
|
+
'productPerTray': configShelf.productPerTray,
|
|
7711
|
+
'zone': configShelf.zone,
|
|
7712
|
+
};
|
|
7713
|
+
|
|
7714
|
+
await fixtureShelfService.upsertOne(
|
|
7715
|
+
{
|
|
7716
|
+
fixtureId: createdFixture._id,
|
|
7717
|
+
shelfNumber: j + 1,
|
|
7718
|
+
},
|
|
7719
|
+
shelfData,
|
|
7720
|
+
);
|
|
7721
|
+
} );
|
|
7722
|
+
}
|
|
7723
|
+
|
|
7724
|
+
for ( let index = 0; index < backFixtures.length; index++ ) {
|
|
7725
|
+
const fixture = backFixtures[index];
|
|
7726
|
+
|
|
7727
|
+
const fixtureConfig = await fixtureLibraryService.findOne( { fixtureCategory: fixture.fixtureType } );
|
|
7728
|
+
if ( !fixtureConfig ) continue;
|
|
7729
|
+
const fixtureConfigDoc = fixtureConfig.toObject();
|
|
7730
|
+
|
|
7731
|
+
let mapKey = `${fixtureConfigDoc.fixtureCategory}${fixtureConfigDoc.fixtureWidth.value}${fixtureConfigDoc.fixtureWidth.unit},${fixture.header}`;
|
|
7732
|
+
|
|
7733
|
+
const fixtureProductSubBrandName = new Set();
|
|
7734
|
+
|
|
7735
|
+
|
|
7736
|
+
const shelfTemplate = fixtureConfigDoc.shelfConfig.map( ( configShelf, j ) => {
|
|
7737
|
+
const shelfZone = fixture.productZones.find( ( zone ) => zone.zoneName === configShelf.shelfZone );
|
|
7738
|
+
const shelfSection = shelfZone?.products.find( ( product ) => !product.isMerchandisingElement );
|
|
7739
|
+
|
|
7740
|
+
const shelfIdentifier = `shelf${j + 1}=${shelfSection?.productName}`;
|
|
7741
|
+
|
|
7742
|
+
mapKey += ','+shelfIdentifier;
|
|
7743
|
+
|
|
7744
|
+
const productSubBrandName = shelfSection?.productName?.replace( /\s*PIDs\b/g, '' )?.split( /\s*\+\s*/ ) || [];
|
|
7745
|
+
|
|
7746
|
+
productSubBrandName.forEach( ( item ) => fixtureProductSubBrandName.add( item ) );
|
|
7747
|
+
|
|
7748
|
+
return {
|
|
7749
|
+
shelfNumber: j+1,
|
|
7750
|
+
shelfType: configShelf?.shelfType,
|
|
7751
|
+
productPerShelf: configShelf?.productPerShelf,
|
|
7752
|
+
trayRows: configShelf?.trayRows,
|
|
7753
|
+
productBrandName: productSubBrandName,
|
|
7754
|
+
zone: configShelf.shelfZone,
|
|
7755
|
+
};
|
|
7756
|
+
} );
|
|
7757
|
+
|
|
7758
|
+
const vmConfig = fixture.productZones?.flatMap( ( zone ) => {
|
|
7759
|
+
const vms = zone.products.filter( ( vm ) => vm.isMerchandisingElement );
|
|
7760
|
+
const vmConfig = fixtureConfigDoc.vmConfig.filter( ( vm ) => vm.position === zone.zoneName );
|
|
7761
|
+
const pids = zone.products.filter( ( vm ) => !vm.isMerchandisingElement );
|
|
7762
|
+
|
|
7763
|
+
return vms.map( ( vm, k ) => {
|
|
7764
|
+
let configData = vmConfig[0];
|
|
7765
|
+
|
|
7766
|
+
if ( vm.productName === 'Creatr' && zone.zoneName === 'Mid' ) {
|
|
7767
|
+
configData = vmConfig.find( ( config ) => config.vmWidthmm === 905 );
|
|
7768
|
+
configData.zone = 'stretch';
|
|
7769
|
+
}
|
|
7770
|
+
|
|
7771
|
+
if ( vm.productName === 'Creatr' && zone.zoneName === 'Mid' && pids.length ) {
|
|
7772
|
+
configData = vmConfig.find( ( config ) => config.vmWidthmm === 230 );
|
|
7773
|
+
}
|
|
7774
|
+
|
|
7775
|
+
if ( !configData ) return;
|
|
7776
|
+
|
|
7777
|
+
const vmIdentifier = `vm${k+1}=${vm.productName}+${configData.vmHeightmm}+${configData.vmWidthmm}+${configData.startShelf}+${configData.endShelf}+${configData.zone}`;
|
|
7778
|
+
|
|
7779
|
+
mapKey += ','+vmIdentifier;
|
|
7780
|
+
|
|
7781
|
+
return {
|
|
7782
|
+
startYPosition: configData.startShelf,
|
|
7783
|
+
endYPosition: configData.endShelf,
|
|
7784
|
+
xZone: configData.zone,
|
|
7785
|
+
vmName: vm.productName,
|
|
7786
|
+
vmHeight: configData.vmHeightmm,
|
|
7787
|
+
vmWidth: configData.vmWidthmm,
|
|
7788
|
+
imageUrl: zone?.actual_image_url,
|
|
7789
|
+
};
|
|
7790
|
+
} );
|
|
7791
|
+
} );
|
|
7792
|
+
|
|
7793
|
+
const vmTemplate = await Promise.all( vmConfig.map( async ( vmTemplate ) => {
|
|
7794
|
+
const vmInsertData = {
|
|
7795
|
+
clientId: '11',
|
|
7796
|
+
vmName: vmTemplate.vmName,
|
|
7797
|
+
vmHeight: {
|
|
7798
|
+
value: vmTemplate.vmHeight,
|
|
7799
|
+
unit: 'mm',
|
|
7800
|
+
},
|
|
7801
|
+
vmWidth: {
|
|
7802
|
+
value: vmTemplate.vmWidth,
|
|
7803
|
+
unit: 'mm',
|
|
7804
|
+
},
|
|
7805
|
+
status: 'complete',
|
|
7806
|
+
vmBrand: vmTemplate.vmBrand,
|
|
7807
|
+
};
|
|
7808
|
+
if ( vmTemplate?.imageUrl ) {
|
|
7809
|
+
const parsedUrl = new URL( vmTemplate.imageUrl );
|
|
7810
|
+
const attachmentId = parsedUrl.searchParams.get( 'attachment_id' );
|
|
7811
|
+
|
|
7812
|
+
const isVmImageExist = await planoVmService.findOne( { crestImageId: attachmentId } );
|
|
7813
|
+
|
|
7814
|
+
if ( !isVmImageExist ) {
|
|
7815
|
+
const vmImageData = await fetchVmImage( attachmentId );
|
|
7816
|
+
|
|
7817
|
+
const imageMeta = await getImageMetadata( vmImageData );
|
|
7818
|
+
|
|
7819
|
+
const params = {
|
|
7820
|
+
Bucket: JSON.parse( process.env.BUCKET ).storeBuilder,
|
|
7821
|
+
Key: `vmType/`,
|
|
7822
|
+
fileName: `${attachmentId}.${imageMeta.fileExtension}`,
|
|
7823
|
+
ContentType: imageMeta.contentType,
|
|
7824
|
+
body: vmImageData,
|
|
7825
|
+
};
|
|
7826
|
+
|
|
7827
|
+
const imgUpload = await fileUpload( params );
|
|
7828
|
+
|
|
7829
|
+
|
|
7830
|
+
vmInsertData.crestImageId = attachmentId;
|
|
7831
|
+
vmInsertData.vmImageUrl = imgUpload.Key;
|
|
7832
|
+
|
|
7833
|
+
|
|
7834
|
+
if ( imageMeta.imageShape === 'square' ) {
|
|
7835
|
+
vmInsertData.vmHeight.value = 100;
|
|
7836
|
+
vmInsertData.vmWidth.value = 230;
|
|
7837
|
+
}
|
|
7838
|
+
} else {
|
|
7839
|
+
vmInsertData.crestImageId = attachmentId;
|
|
7840
|
+
vmInsertData.vmImageUrl = isVmImageExist.toObject().vmImageUrl;
|
|
7841
|
+
}
|
|
7842
|
+
}
|
|
7843
|
+
|
|
7844
|
+
const vmDetails = await planoVmService.upsertOne(
|
|
7845
|
+
{
|
|
7846
|
+
'productName': vmInsertData.vmName,
|
|
7847
|
+
},
|
|
7848
|
+
vmInsertData,
|
|
7849
|
+
);
|
|
7850
|
+
|
|
7851
|
+
return {
|
|
7852
|
+
vmId: vmDetails.toObject()._id,
|
|
7853
|
+
startYPosition: vmTemplate.startYPosition,
|
|
7854
|
+
endYPosition: vmTemplate.endYPosition,
|
|
7855
|
+
xZone: vmTemplate.xZone,
|
|
7856
|
+
};
|
|
7857
|
+
} ) );
|
|
7858
|
+
|
|
7859
|
+
const baseFixtureName = `${fixtureConfigDoc.fixtureCategory}`;
|
|
7860
|
+
const uniqueFixtureName = await generateFixtureTemplateName( baseFixtureName, fixtureConfigDoc.fixtureWidth );
|
|
7861
|
+
|
|
7862
|
+
|
|
7863
|
+
const fixtureTemplateData = {
|
|
7864
|
+
...fixtureConfigDoc,
|
|
7865
|
+
'shelfConfig': shelfTemplate,
|
|
7866
|
+
'vmConfig': vmTemplate,
|
|
7867
|
+
'clientId': fixtureConfigDoc.clientId,
|
|
7868
|
+
'fixtureName': uniqueFixtureName,
|
|
7869
|
+
'header': {
|
|
7870
|
+
label: fixture.header ? fixture.header : fixture.fixtureSubname[0],
|
|
7871
|
+
isEnabled: true,
|
|
7872
|
+
},
|
|
7873
|
+
'footer': {
|
|
7874
|
+
label: fixture.footer,
|
|
7875
|
+
isEnabled: true,
|
|
7876
|
+
},
|
|
7877
|
+
'isBodyEnabled': true,
|
|
7878
|
+
'productResolutionLevel': 'L3',
|
|
7879
|
+
'productBrandName': [ ...fixtureProductSubBrandName ],
|
|
7880
|
+
'fixtureLibraryId': fixtureConfigDoc._id,
|
|
7881
|
+
'crestMapKey': mapKey,
|
|
7882
|
+
};
|
|
7883
|
+
|
|
7884
|
+
delete fixtureTemplateData._id;
|
|
7885
|
+
|
|
7886
|
+
|
|
7887
|
+
const fixtureTemplate = await fixtureConfigService.upsertOne(
|
|
7888
|
+
{ crestMapKey: mapKey },
|
|
7889
|
+
fixtureTemplateData,
|
|
7890
|
+
);
|
|
7891
|
+
|
|
7892
|
+
const fixtureData = {
|
|
7893
|
+
...fixtureTemplate.toObject(),
|
|
7894
|
+
'storeName': layoutDoc.storeName,
|
|
7895
|
+
'storeId': storeDetails?.toObject()?.storeId ? storeDetails.toObject().storeId : 'nil',
|
|
7896
|
+
'planoId': layoutDoc.planoId,
|
|
7897
|
+
'floorId': layoutDoc._id,
|
|
7898
|
+
'associatedElementType': 'wall',
|
|
7899
|
+
'associatedElementNumber': 2,
|
|
7900
|
+
'relativePosition': {
|
|
7901
|
+
'x': roundToTwo( ( finalXDistance - ( constantFixtureWidth/mmToFeet ) ) ),
|
|
7902
|
+
'y': roundToTwo( ( ( index * ( ( constantFixtureLength/mmToFeet ) ) ) + ( ( leftFixtures.length ? 1 : 0 ) * constantFixtureWidth/mmToFeet ) ) ),
|
|
7903
|
+
'unit': 'ft',
|
|
7904
|
+
},
|
|
7905
|
+
'fixtureNumber': fixtureCounter,
|
|
7906
|
+
'relativeDetailedPosition': {
|
|
7907
|
+
'x': roundToTwo( ( finalXDetailedDistance - ( constantDetailedFixtureLength/mmToFeet ) ) ),
|
|
7908
|
+
'y': roundToTwo( ( ( index * ( ( constantDetailedFixtureWidth/mmToFeet ) ) ) + ( ( leftFixtures.length ? 1 : 0 ) * constantDetailedFixtureWidth/mmToFeet ) ) ),
|
|
7909
|
+
'unit': 'ft',
|
|
7910
|
+
},
|
|
7911
|
+
'associatedElementFixtureNumber': index+1,
|
|
7912
|
+
'fixtureConfigId': fixtureTemplate.toObject()._id,
|
|
7913
|
+
};
|
|
7914
|
+
|
|
7915
|
+
delete fixtureData._id;
|
|
7916
|
+
delete fixtureData.shelfConfig;
|
|
7917
|
+
|
|
7918
|
+
const createdFixture = await storeFixtureService.upsertOne(
|
|
7919
|
+
{
|
|
7920
|
+
floorId: layoutDoc._id,
|
|
7921
|
+
fixtureNumber: fixtureCounter++,
|
|
7922
|
+
},
|
|
7923
|
+
fixtureData,
|
|
7924
|
+
);
|
|
7925
|
+
|
|
7926
|
+
if ( !fixtureConfigDoc.shelfConfig.length || fixture.header === 'CL' || fixture.fixtureSubname?.includes( 'CL' ) ) continue;
|
|
7927
|
+
|
|
7928
|
+
fixtureTemplate.shelfConfig.forEach( async ( configShelf, j ) => {
|
|
7929
|
+
const shelfData = {
|
|
7930
|
+
'clientId': '11',
|
|
7931
|
+
'storeName': layoutDoc.storeName,
|
|
7932
|
+
'storeId': storeDetails?.toObject()?.storeId ? storeDetails.toObject().storeId : 'nil',
|
|
7933
|
+
'planoId': layoutDoc.planoId,
|
|
7934
|
+
'floorId': layoutDoc._id,
|
|
7935
|
+
'fixtureId': createdFixture._id,
|
|
7936
|
+
'shelfNumber': j + 1,
|
|
7937
|
+
'shelfOrder': 'LTR',
|
|
7938
|
+
'shelfCapacity': configShelf.shelfCapacity,
|
|
7939
|
+
'productBrandName': configShelf.productBrandName,
|
|
7940
|
+
'shelfType': configShelf.shelfType,
|
|
7941
|
+
'productPerShelf': configShelf.productPerShelf,
|
|
7942
|
+
'trayRows': configShelf.trayRows,
|
|
7943
|
+
'productPerTray': configShelf.productPerTray,
|
|
7944
|
+
'zone': configShelf.zone,
|
|
7945
|
+
};
|
|
7946
|
+
|
|
7947
|
+
await fixtureShelfService.upsertOne(
|
|
7948
|
+
{
|
|
7949
|
+
fixtureId: createdFixture._id,
|
|
7950
|
+
shelfNumber: j + 1,
|
|
7951
|
+
},
|
|
7952
|
+
shelfData,
|
|
7953
|
+
);
|
|
7954
|
+
} );
|
|
7955
|
+
}
|
|
7956
|
+
|
|
7957
|
+
for ( let index = 0; index < rightFixtures.length; index++ ) {
|
|
7958
|
+
const fixture = rightFixtures[index];
|
|
7959
|
+
|
|
7960
|
+
const fixtureConfig = await fixtureLibraryService.findOne( { fixtureCategory: fixture.fixtureType } );
|
|
7961
|
+
if ( !fixtureConfig ) continue;
|
|
7962
|
+
const fixtureConfigDoc = fixtureConfig.toObject();
|
|
7963
|
+
|
|
7964
|
+
let mapKey = `${fixtureConfigDoc.fixtureCategory}${fixtureConfigDoc.fixtureWidth.value}${fixtureConfigDoc.fixtureWidth.unit},${fixture.header}`;
|
|
7965
|
+
|
|
7966
|
+
const fixtureProductSubBrandName = new Set();
|
|
7967
|
+
|
|
7968
|
+
|
|
7969
|
+
const shelfTemplate = fixtureConfigDoc.shelfConfig.map( ( configShelf, j ) => {
|
|
7970
|
+
const shelfZone = fixture.productZones.find( ( zone ) => zone.zoneName === configShelf.shelfZone );
|
|
7971
|
+
const shelfSection = shelfZone?.products.find( ( product ) => !product.isMerchandisingElement );
|
|
7972
|
+
|
|
7973
|
+
const shelfIdentifier = `shelf${j + 1}=${shelfSection?.productName}`;
|
|
7974
|
+
|
|
7975
|
+
mapKey += ','+shelfIdentifier;
|
|
7976
|
+
|
|
7977
|
+
const productSubBrandName = shelfSection?.productName?.replace( /\s*PIDs\b/g, '' )?.split( /\s*\+\s*/ ) || [];
|
|
7978
|
+
|
|
7979
|
+
productSubBrandName.forEach( ( item ) => fixtureProductSubBrandName.add( item ) );
|
|
7980
|
+
|
|
7981
|
+
return {
|
|
7982
|
+
shelfNumber: j+1,
|
|
7983
|
+
shelfType: configShelf?.shelfType,
|
|
7984
|
+
productPerShelf: configShelf?.productPerShelf,
|
|
7985
|
+
trayRows: configShelf?.trayRows,
|
|
7986
|
+
productBrandName: productSubBrandName,
|
|
7987
|
+
zone: configShelf.shelfZone,
|
|
7988
|
+
};
|
|
7989
|
+
} );
|
|
7990
|
+
|
|
7991
|
+
const vmConfig = fixture.productZones?.flatMap( ( zone ) => {
|
|
7992
|
+
const vms = zone.products.filter( ( vm ) => vm.isMerchandisingElement );
|
|
7993
|
+
const vmConfig = fixtureConfigDoc.vmConfig.filter( ( vm ) => vm.position === zone.zoneName );
|
|
7994
|
+
const pids = zone.products.filter( ( vm ) => !vm.isMerchandisingElement );
|
|
7995
|
+
|
|
7996
|
+
return vms.map( ( vm, k ) => {
|
|
7997
|
+
let configData = vmConfig[0];
|
|
7998
|
+
|
|
7999
|
+
if ( vm.productName === 'Creatr' && zone.zoneName === 'Mid' ) {
|
|
8000
|
+
configData = vmConfig.find( ( config ) => config.vmWidthmm === 905 );
|
|
8001
|
+
configData.zone = 'stretch';
|
|
8002
|
+
}
|
|
8003
|
+
|
|
8004
|
+
if ( vm.productName === 'Creatr' && zone.zoneName === 'Mid' && pids.length ) {
|
|
8005
|
+
configData = vmConfig.find( ( config ) => config.vmWidthmm === 230 );
|
|
8006
|
+
}
|
|
8007
|
+
|
|
8008
|
+
if ( !configData ) return;
|
|
8009
|
+
|
|
8010
|
+
const vmIdentifier = `vm${k+1}=${vm.productName}+${configData.vmHeightmm}+${configData.vmWidthmm}+${configData.startShelf}+${configData.endShelf}+${configData.zone}`;
|
|
8011
|
+
|
|
8012
|
+
mapKey += ','+vmIdentifier;
|
|
8013
|
+
|
|
8014
|
+
return {
|
|
8015
|
+
startYPosition: configData.startShelf,
|
|
8016
|
+
endYPosition: configData.endShelf,
|
|
8017
|
+
xZone: configData.zone,
|
|
8018
|
+
vmName: vm.productName,
|
|
8019
|
+
vmHeight: configData.vmHeightmm,
|
|
8020
|
+
vmWidth: configData.vmWidthmm,
|
|
8021
|
+
imageUrl: zone?.actual_image_url,
|
|
8022
|
+
};
|
|
8023
|
+
} );
|
|
8024
|
+
} );
|
|
8025
|
+
|
|
8026
|
+
const vmTemplate = await Promise.all( vmConfig.map( async ( vmTemplate ) => {
|
|
8027
|
+
const vmInsertData = {
|
|
8028
|
+
clientId: '11',
|
|
8029
|
+
vmName: vmTemplate.vmName,
|
|
8030
|
+
vmHeight: {
|
|
8031
|
+
value: vmTemplate.vmHeight,
|
|
8032
|
+
unit: 'mm',
|
|
8033
|
+
},
|
|
8034
|
+
vmWidth: {
|
|
8035
|
+
value: vmTemplate.vmWidth,
|
|
8036
|
+
unit: 'mm',
|
|
8037
|
+
},
|
|
8038
|
+
status: 'complete',
|
|
8039
|
+
vmBrand: vmTemplate.vmBrand,
|
|
8040
|
+
};
|
|
8041
|
+
if ( vmTemplate?.imageUrl ) {
|
|
8042
|
+
const parsedUrl = new URL( vmTemplate.imageUrl );
|
|
8043
|
+
const attachmentId = parsedUrl.searchParams.get( 'attachment_id' );
|
|
8044
|
+
|
|
8045
|
+
const isVmImageExist = await planoVmService.findOne( { crestImageId: attachmentId } );
|
|
8046
|
+
|
|
8047
|
+
if ( !isVmImageExist ) {
|
|
8048
|
+
const vmImageData = await fetchVmImage( attachmentId );
|
|
8049
|
+
|
|
8050
|
+
const imageMeta = await getImageMetadata( vmImageData );
|
|
8051
|
+
|
|
8052
|
+
const params = {
|
|
8053
|
+
Bucket: JSON.parse( process.env.BUCKET ).storeBuilder,
|
|
8054
|
+
Key: `vmType/`,
|
|
8055
|
+
fileName: `${attachmentId}.${imageMeta.fileExtension}`,
|
|
8056
|
+
ContentType: imageMeta.contentType,
|
|
8057
|
+
body: vmImageData,
|
|
8058
|
+
};
|
|
8059
|
+
|
|
8060
|
+
const imgUpload = await fileUpload( params );
|
|
8061
|
+
|
|
8062
|
+
vmInsertData.crestImageId = attachmentId;
|
|
8063
|
+
vmInsertData.vmImageUrl = imgUpload.Key;
|
|
8064
|
+
|
|
8065
|
+
|
|
8066
|
+
if ( imageMeta.imageShape === 'square' ) {
|
|
8067
|
+
vmInsertData.vmHeight.value = 100;
|
|
8068
|
+
vmInsertData.vmWidth.value = 230;
|
|
8069
|
+
}
|
|
8070
|
+
} else {
|
|
8071
|
+
vmInsertData.crestImageId = attachmentId;
|
|
8072
|
+
vmInsertData.vmImageUrl = isVmImageExist.toObject().vmImageUrl;
|
|
8073
|
+
}
|
|
8074
|
+
}
|
|
8075
|
+
|
|
8076
|
+
const vmDetails = await planoVmService.upsertOne(
|
|
8077
|
+
{
|
|
8078
|
+
'productName': vmInsertData.vmName,
|
|
8079
|
+
},
|
|
8080
|
+
vmInsertData,
|
|
8081
|
+
);
|
|
8082
|
+
|
|
8083
|
+
return {
|
|
8084
|
+
vmId: vmDetails.toObject()._id,
|
|
8085
|
+
startYPosition: vmTemplate.startYPosition,
|
|
8086
|
+
endYPosition: vmTemplate.endYPosition,
|
|
8087
|
+
xZone: vmTemplate.xZone,
|
|
8088
|
+
};
|
|
8089
|
+
} ) );
|
|
8090
|
+
|
|
8091
|
+
const baseFixtureName = `${fixtureConfigDoc.fixtureCategory}`;
|
|
8092
|
+
const uniqueFixtureName = await generateFixtureTemplateName( baseFixtureName, fixtureConfigDoc.fixtureWidth );
|
|
8093
|
+
|
|
8094
|
+
|
|
8095
|
+
const fixtureTemplateData = {
|
|
8096
|
+
...fixtureConfigDoc,
|
|
8097
|
+
'shelfConfig': shelfTemplate,
|
|
8098
|
+
'vmConfig': vmTemplate,
|
|
8099
|
+
'clientId': fixtureConfigDoc.clientId,
|
|
8100
|
+
'fixtureName': uniqueFixtureName,
|
|
8101
|
+
'header': {
|
|
8102
|
+
label: fixture.header ? fixture.header : fixture.fixtureSubname[0],
|
|
8103
|
+
isEnabled: true,
|
|
8104
|
+
},
|
|
8105
|
+
'footer': {
|
|
8106
|
+
label: fixture.footer,
|
|
8107
|
+
isEnabled: true,
|
|
8108
|
+
},
|
|
8109
|
+
'isBodyEnabled': true,
|
|
8110
|
+
'productResolutionLevel': 'L3',
|
|
8111
|
+
'productBrandName': [ ...fixtureProductSubBrandName ],
|
|
8112
|
+
'fixtureLibraryId': fixtureConfigDoc._id,
|
|
8113
|
+
'crestMapKey': mapKey,
|
|
8114
|
+
};
|
|
8115
|
+
|
|
8116
|
+
delete fixtureTemplateData._id;
|
|
8117
|
+
|
|
8118
|
+
|
|
8119
|
+
const fixtureTemplate = await fixtureConfigService.upsertOne(
|
|
8120
|
+
{ crestMapKey: mapKey },
|
|
8121
|
+
fixtureTemplateData,
|
|
8122
|
+
);
|
|
8123
|
+
|
|
8124
|
+
const fixtureData = {
|
|
8125
|
+
...fixtureTemplate.toObject(),
|
|
8126
|
+
'storeName': layoutDoc.storeName,
|
|
8127
|
+
'storeId': storeDetails?.toObject()?.storeId ? storeDetails.toObject().storeId : 'nil',
|
|
8128
|
+
'planoId': layoutDoc.planoId,
|
|
8129
|
+
'floorId': layoutDoc._id,
|
|
8130
|
+
'associatedElementType': 'wall',
|
|
8131
|
+
'associatedElementNumber': 3,
|
|
8132
|
+
'relativePosition': {
|
|
8133
|
+
'x': roundToTwo( ( index * ( constantFixtureLength / mmToFeet ) ) ),
|
|
8134
|
+
'y': roundToTwo( ( finalYDistance - ( constantFixtureWidth / mmToFeet ) ) ),
|
|
8135
|
+
'unit': 'ft',
|
|
8136
|
+
},
|
|
8137
|
+
'fixtureNumber': fixtureCounter,
|
|
8138
|
+
'relativeDetailedPosition': {
|
|
8139
|
+
'x': roundToTwo( ( index * ( constantDetailedFixtureLength / mmToFeet ) ) ),
|
|
8140
|
+
'y': roundToTwo( ( finalYDetailedDistance - ( constantDetailedFixtureWidth / mmToFeet ) ) ),
|
|
8141
|
+
'unit': 'ft',
|
|
8142
|
+
},
|
|
8143
|
+
'associatedElementFixtureNumber': index+1,
|
|
8144
|
+
'fixtureConfigId': fixtureTemplate.toObject()._id,
|
|
8145
|
+
};
|
|
8146
|
+
|
|
8147
|
+
delete fixtureData._id;
|
|
8148
|
+
delete fixtureData.shelfConfig;
|
|
8149
|
+
|
|
8150
|
+
const createdFixture = await storeFixtureService.upsertOne(
|
|
8151
|
+
{
|
|
8152
|
+
floorId: layoutDoc._id,
|
|
8153
|
+
fixtureNumber: fixtureCounter++,
|
|
8154
|
+
},
|
|
8155
|
+
fixtureData,
|
|
8156
|
+
);
|
|
8157
|
+
|
|
8158
|
+
if ( !fixtureConfigDoc.shelfConfig.length || fixture.header === 'CL' || fixture.fixtureSubname?.includes( 'CL' ) ) continue;
|
|
8159
|
+
|
|
8160
|
+
fixtureTemplate.shelfConfig.forEach( async ( configShelf, j ) => {
|
|
8161
|
+
const shelfData = {
|
|
8162
|
+
'clientId': '11',
|
|
8163
|
+
'storeName': layoutDoc.storeName,
|
|
8164
|
+
'storeId': storeDetails?.toObject()?.storeId ? storeDetails.toObject().storeId : 'nil',
|
|
8165
|
+
'planoId': layoutDoc.planoId,
|
|
8166
|
+
'floorId': layoutDoc._id,
|
|
8167
|
+
'fixtureId': createdFixture._id,
|
|
8168
|
+
'shelfNumber': j + 1,
|
|
8169
|
+
'shelfOrder': 'LTR',
|
|
8170
|
+
'shelfCapacity': configShelf.shelfCapacity,
|
|
8171
|
+
'productBrandName': configShelf.productBrandName,
|
|
8172
|
+
'shelfType': configShelf.shelfType,
|
|
8173
|
+
'productPerShelf': configShelf.productPerShelf,
|
|
8174
|
+
'trayRows': configShelf.trayRows,
|
|
8175
|
+
'productPerTray': configShelf.productPerTray,
|
|
8176
|
+
'zone': configShelf.zone,
|
|
8177
|
+
};
|
|
8178
|
+
|
|
8179
|
+
await fixtureShelfService.upsertOne(
|
|
8180
|
+
{
|
|
8181
|
+
fixtureId: createdFixture._id,
|
|
8182
|
+
shelfNumber: j + 1,
|
|
8183
|
+
},
|
|
8184
|
+
shelfData,
|
|
8185
|
+
);
|
|
8186
|
+
} );
|
|
8187
|
+
}
|
|
8188
|
+
|
|
8189
|
+
for ( let index = 0; index < floorFixtures.length; index++ ) {
|
|
8190
|
+
const fixture = floorFixtures[index];
|
|
8191
|
+
|
|
8192
|
+
const centerRow = Math.floor( totalRows / 2 );
|
|
8193
|
+
|
|
8194
|
+
const startingX = roundToTwo( ( finalXDistance / 2 - ( maxFixturesPerRow / 2 ) * ( constantFixtureLength / mmToFeet ) ) );
|
|
8195
|
+
const detailedStartingX = roundToTwo( ( finalXDetailedDistance / 2 - ( maxFixturesPerRow / 2 ) * ( constantDetailedFixtureLength / mmToFeet ) ) );
|
|
8196
|
+
|
|
8197
|
+
const startingY = finalYDistance / 2 - centerRow * ( constantFixtureWidth / mmToFeet );
|
|
8198
|
+
const detailedStartingY = finalYDetailedDistance / 2 - centerRow * ( constantDetailedFixtureWidth / mmToFeet );
|
|
8199
|
+
|
|
8200
|
+
const colIndex = Math.floor( index / 2 );
|
|
8201
|
+
const rowIndex = index % 2 === 0 ? 1 : 0;
|
|
8202
|
+
|
|
8203
|
+
const xPos = roundToTwo( startingX + colIndex * ( constantFixtureLength / mmToFeet ) );
|
|
8204
|
+
const yPos = roundToTwo( startingY + rowIndex * ( constantFixtureWidth / mmToFeet ) );
|
|
8205
|
+
|
|
8206
|
+
const detailedXPos = roundToTwo( ( detailedStartingX + colIndex * ( constantDetailedFixtureLength / mmToFeet ) ) );
|
|
8207
|
+
const detailedYPos = roundToTwo( ( detailedStartingY + rowIndex * ( constantDetailedFixtureWidth / mmToFeet ) ) );
|
|
8208
|
+
|
|
8209
|
+
const fixtureConfig = await fixtureLibraryService.findOne( { fixtureCategory: fixture.main } );
|
|
8210
|
+
if ( !fixtureConfig ) continue;
|
|
8211
|
+
const fixtureConfigDoc = fixtureConfig.toObject();
|
|
8212
|
+
|
|
8213
|
+
let mapKey = `${fixtureConfigDoc.fixtureCategory}${fixtureConfigDoc.fixtureWidth.value}${fixtureConfigDoc.fixtureWidth.unit},${fixture.header}`;
|
|
8214
|
+
|
|
8215
|
+
const fixtureProductSubBrandName = new Set();
|
|
8216
|
+
|
|
8217
|
+
|
|
8218
|
+
const shelfTemplate = fixtureConfigDoc.shelfConfig.map( ( configShelf, j ) => {
|
|
8219
|
+
const shelfSection = fixture?.centerSuperSubMain?.find( ( product ) => !product.isVisualMerchandiser );
|
|
8220
|
+
|
|
8221
|
+
const shelfIdentifier = `shelf${j + 1}=${shelfSection?.productName}`;
|
|
8222
|
+
|
|
8223
|
+
mapKey += ','+shelfIdentifier;
|
|
8224
|
+
|
|
8225
|
+
|
|
8226
|
+
let productSubBrandName = fixture.centerSubMain.replace( /\s*PIDs\b/g, '' )?.split( /\s*\+\s*/ ) || [];
|
|
8227
|
+
|
|
8228
|
+
if ( shelfSection ) {
|
|
8229
|
+
productSubBrandName = shelfSection.name.replace( /\s*PIDs\b/g, '' )?.split( /\s*\+\s*/ ) || [];
|
|
8230
|
+
}
|
|
8231
|
+
|
|
8232
|
+
productSubBrandName.forEach( ( item ) => fixtureProductSubBrandName.add( item ) );
|
|
8233
|
+
|
|
8234
|
+
return {
|
|
8235
|
+
shelfNumber: j+1,
|
|
8236
|
+
shelfType: configShelf?.shelfType,
|
|
8237
|
+
productPerShelf: configShelf?.productPerShelf,
|
|
8238
|
+
trayRows: configShelf?.trayRows,
|
|
8239
|
+
productBrandName: productSubBrandName,
|
|
8240
|
+
zone: configShelf.shelfZone,
|
|
8241
|
+
};
|
|
8242
|
+
} );
|
|
8243
|
+
|
|
8244
|
+
const vmConfig = fixture.centerSuperSubMain?.flatMap( ( vm ) => {
|
|
8245
|
+
if ( !vm?.isVisualMerchandiser ) {
|
|
8246
|
+
return [];
|
|
8247
|
+
}
|
|
8248
|
+
const vmConfig = fixtureConfigDoc.vmConfig;
|
|
8249
|
+
|
|
8250
|
+
const [ configData1, configData2 ] = [ vmConfig[0], vmConfig[1] ];
|
|
8251
|
+
|
|
8252
|
+
return [
|
|
8253
|
+
{
|
|
8254
|
+
startYPosition: configData1.startShelf,
|
|
8255
|
+
endYPosition: configData1.endShelf,
|
|
8256
|
+
xZone: configData1.zone,
|
|
8257
|
+
vmName: vm.name + ' - 1',
|
|
8258
|
+
vmHeight: configData1.vmHeightmm,
|
|
8259
|
+
vmWidth: configData1.vmWidthmm,
|
|
8260
|
+
},
|
|
8261
|
+
{
|
|
8262
|
+
startYPosition: configData2.startShelf,
|
|
8263
|
+
endYPosition: configData2.endShelf,
|
|
8264
|
+
xZone: configData2.zone,
|
|
8265
|
+
vmName: vm.name + ' - 2',
|
|
8266
|
+
vmHeight: configData2.vmHeightmm,
|
|
8267
|
+
vmWidth: configData2.vmWidthmm,
|
|
8268
|
+
},
|
|
8269
|
+
];
|
|
8270
|
+
} );
|
|
8271
|
+
|
|
8272
|
+
const vmTemplate = await Promise.all( vmConfig.map( async ( vmTemplate ) => {
|
|
8273
|
+
const vmInsertData = {
|
|
8274
|
+
clientId: '11',
|
|
8275
|
+
vmName: vmTemplate.vmName,
|
|
8276
|
+
vmHeight: {
|
|
8277
|
+
value: vmTemplate.vmHeight,
|
|
8278
|
+
unit: 'mm',
|
|
8279
|
+
},
|
|
8280
|
+
vmWidth: {
|
|
8281
|
+
value: vmTemplate.vmWidth,
|
|
8282
|
+
unit: 'mm',
|
|
8283
|
+
},
|
|
8284
|
+
status: 'complete',
|
|
8285
|
+
vmBrand: vmTemplate.vmBrand,
|
|
8286
|
+
};
|
|
8287
|
+
|
|
8288
|
+
const vmDetails = await planoVmService.upsertOne(
|
|
8289
|
+
{
|
|
8290
|
+
'vmName': vmInsertData.vmName,
|
|
8291
|
+
},
|
|
8292
|
+
vmInsertData,
|
|
8293
|
+
);
|
|
8294
|
+
|
|
8295
|
+
return {
|
|
8296
|
+
vmId: vmDetails.toObject()._id,
|
|
8297
|
+
startYPosition: vmTemplate.startYPosition,
|
|
8298
|
+
endYPosition: vmTemplate.endYPosition,
|
|
8299
|
+
xZone: vmTemplate.xZone,
|
|
8300
|
+
};
|
|
8301
|
+
} ) );
|
|
8302
|
+
|
|
8303
|
+
const baseFixtureName = `${fixtureConfigDoc.fixtureCategory}`;
|
|
8304
|
+
const uniqueFixtureName = await generateFixtureTemplateName( baseFixtureName, fixtureConfigDoc.fixtureWidth );
|
|
8305
|
+
|
|
8306
|
+
|
|
8307
|
+
const fixtureTemplateData = {
|
|
8308
|
+
...fixtureConfigDoc,
|
|
8309
|
+
'shelfConfig': shelfTemplate,
|
|
8310
|
+
'vmConfig': vmTemplate,
|
|
8311
|
+
'clientId': fixtureConfigDoc.clientId,
|
|
8312
|
+
'fixtureName': uniqueFixtureName,
|
|
8313
|
+
'header': {
|
|
8314
|
+
label: fixture.centerSubMain,
|
|
8315
|
+
isEnabled: true,
|
|
8316
|
+
},
|
|
8317
|
+
'footer': {
|
|
8318
|
+
label: 'Storage Box',
|
|
8319
|
+
isEnabled: true,
|
|
8320
|
+
},
|
|
8321
|
+
'isBodyEnabled': true,
|
|
8322
|
+
'productResolutionLevel': 'L3',
|
|
8323
|
+
'productBrandName': [ ...fixtureProductSubBrandName ],
|
|
8324
|
+
'fixtureLibraryId': fixtureConfigDoc._id,
|
|
8325
|
+
'crestMapKey': mapKey,
|
|
8326
|
+
};
|
|
8327
|
+
|
|
8328
|
+
|
|
8329
|
+
delete fixtureTemplateData._id;
|
|
8330
|
+
|
|
8331
|
+
|
|
8332
|
+
const fixtureTemplate = await fixtureConfigService.upsertOne(
|
|
8333
|
+
{ crestMapKey: mapKey },
|
|
8334
|
+
fixtureTemplateData,
|
|
8335
|
+
);
|
|
8336
|
+
|
|
8337
|
+
const fixtureData = {
|
|
8338
|
+
...fixtureTemplate.toObject(),
|
|
8339
|
+
'storeName': layoutDoc.storeName,
|
|
8340
|
+
'storeId': storeDetails?.toObject()?.storeId ? storeDetails.toObject().storeId : 'nil',
|
|
8341
|
+
'planoId': layoutDoc.planoId,
|
|
8342
|
+
'floorId': layoutDoc._id,
|
|
8343
|
+
'relativePosition': {
|
|
8344
|
+
'x': xPos,
|
|
8345
|
+
'y': yPos,
|
|
8346
|
+
'unit': 'ft',
|
|
8347
|
+
},
|
|
8348
|
+
'fixtureNumber': fixtureCounter,
|
|
8349
|
+
'relativeDetailedPosition': {
|
|
8350
|
+
'x': detailedXPos,
|
|
8351
|
+
'y': detailedYPos,
|
|
8352
|
+
'unit': 'ft',
|
|
8353
|
+
},
|
|
8354
|
+
'associatedElementFixtureNumber': index+1,
|
|
8355
|
+
'fixtureConfigId': fixtureTemplate.toObject()._id,
|
|
8356
|
+
};
|
|
8357
|
+
|
|
8358
|
+
delete fixtureData._id;
|
|
8359
|
+
delete fixtureData.shelfConfig;
|
|
8360
|
+
|
|
8361
|
+
const createdFixture = await storeFixtureService.upsertOne(
|
|
8362
|
+
{
|
|
8363
|
+
floorId: layoutDoc._id,
|
|
8364
|
+
fixtureNumber: fixtureCounter++,
|
|
8365
|
+
},
|
|
8366
|
+
fixtureData,
|
|
8367
|
+
);
|
|
8368
|
+
|
|
8369
|
+
if ( !fixtureConfigDoc.shelfConfig.length || fixture.header === 'CL' || fixture.fixtureSubname?.includes( 'CL' ) ) continue;
|
|
8370
|
+
|
|
8371
|
+
fixtureTemplate.shelfConfig.forEach( async ( configShelf, j ) => {
|
|
8372
|
+
const shelfData = {
|
|
8373
|
+
'clientId': '11',
|
|
8374
|
+
'storeName': layoutDoc.storeName,
|
|
8375
|
+
'storeId': storeDetails?.toObject()?.storeId ? storeDetails.toObject().storeId : 'nil',
|
|
8376
|
+
'planoId': layoutDoc.planoId,
|
|
8377
|
+
'floorId': layoutDoc._id,
|
|
8378
|
+
'fixtureId': createdFixture._id,
|
|
8379
|
+
'shelfNumber': j + 1,
|
|
8380
|
+
'shelfOrder': 'LTR',
|
|
8381
|
+
'shelfCapacity': configShelf.shelfCapacity,
|
|
8382
|
+
'productBrandName': configShelf.productBrandName,
|
|
8383
|
+
'shelfType': configShelf.shelfType,
|
|
8384
|
+
'productPerShelf': configShelf.productPerShelf,
|
|
8385
|
+
'trayRows': configShelf.trayRows,
|
|
8386
|
+
'productPerTray': configShelf.productPerTray,
|
|
8387
|
+
'zone': configShelf.zone,
|
|
8388
|
+
};
|
|
8389
|
+
|
|
8390
|
+
await fixtureShelfService.upsertOne(
|
|
8391
|
+
{
|
|
8392
|
+
fixtureId: createdFixture._id,
|
|
8393
|
+
shelfNumber: j + 1,
|
|
8394
|
+
},
|
|
8395
|
+
shelfData,
|
|
8396
|
+
);
|
|
8397
|
+
} );
|
|
8398
|
+
}
|
|
8399
|
+
|
|
8400
|
+
|
|
8401
|
+
const now = Date.now();
|
|
8402
|
+
const elapsedMinutes = ( now - startTime ) / 1000 / 60;
|
|
8403
|
+
console.log( `Store name: ${storeData.storeName},Floor name: ${floorArray[floorIndex]} Iteration ${i + 1}/${storeList?.length}: total elapsed time = ${elapsedMinutes.toFixed( 2 )} minutes` );
|
|
8404
|
+
logger.info( { functionName: 'updateCrestPlanogram', body: `Store name: ${storeData.storeName},Floor name: ${floorArray[floorIndex]} Iteration ${i + 1}/${storeList?.length}: total elapsed time = ${elapsedMinutes.toFixed( 2 )} minutes` } );
|
|
8405
|
+
}
|
|
8406
|
+
}
|
|
8407
|
+
|
|
8408
|
+
res.sendSuccess( 'Updated Successfully' );
|
|
8409
|
+
} catch ( e ) {
|
|
8410
|
+
logger.error( { functionName: 'updateCrestPlanogram', error: e } );
|
|
8411
|
+
return res.sendError( e.message || 'Internal Server Error', 500 );
|
|
8412
|
+
}
|
|
8413
|
+
}
|
|
8414
|
+
// function fillFeedbackFromJson( excelPath, jsonData, outputPath ) {
|
|
8415
|
+
// const workbook = xlsx.readFile( excelPath );
|
|
8416
|
+
// const sheetName = workbook.SheetNames[0];
|
|
8417
|
+
// const sheet = workbook.Sheets[sheetName];
|
|
8418
|
+
|
|
8419
|
+
// const data = xlsx.utils.sheet_to_json( sheet, { defval: 'Transformed by Data.Page' } );
|
|
8420
|
+
|
|
8421
|
+
// const feedbackMap = {};
|
|
8422
|
+
// jsonData.forEach( ( entry ) => {
|
|
8423
|
+
// feedbackMap[entry.store] = entry.videoUrl;
|
|
8424
|
+
// } );
|
|
8425
|
+
|
|
8426
|
+
// const updatedData = data.map( ( row ) => {
|
|
8427
|
+
// const store = row.storeName;
|
|
8428
|
+
// if ( feedbackMap[store] ) {
|
|
8429
|
+
// row.FeedBack = feedbackMap[store];
|
|
8430
|
+
// }
|
|
8431
|
+
// return row;
|
|
8432
|
+
// } );
|
|
8433
|
+
|
|
8434
|
+
// const newSheet = xlsx.utils.json_to_sheet( updatedData );
|
|
8435
|
+
|
|
8436
|
+
// workbook.Sheets[sheetName] = newSheet;
|
|
8437
|
+
|
|
8438
|
+
// xlsx.writeFile( workbook, outputPath );
|
|
8439
|
+
// }
|
|
8440
|
+
|
|
8441
|
+
// fillFeedbackFromJson('input.xlsx', feedbackJson, 'output.xlsx');
|
|
8442
|
+
|
|
8443
|
+
|
|
8444
|
+
// function exportFixtureJsonToExcel( fixtures, filePath ) {
|
|
8445
|
+
// const fixtureInfoArr = [];
|
|
8446
|
+
// const shelfConfigArr = [];
|
|
8447
|
+
// const vmConfigArr = [];
|
|
8448
|
+
|
|
8449
|
+
// for ( const fixture of fixtures ) {
|
|
8450
|
+
// fixtureInfoArr.push( {
|
|
8451
|
+
// clientId: fixture.clientId,
|
|
8452
|
+
// fixtureCode: fixture.fixtureCode,
|
|
8453
|
+
// fixtureCategory: fixture.fixtureCategory,
|
|
8454
|
+
// fixtureConfigType: fixture.fixtureConfigType,
|
|
8455
|
+
// fixtureLength: `${fixture.fixtureLength?.value} ${fixture.fixtureLength?.unit}`,
|
|
8456
|
+
// fixtureCapacity: fixture.fixtureCapacity,
|
|
8457
|
+
// } );
|
|
8458
|
+
|
|
8459
|
+
// ( fixture.shelfConfig || [] ).forEach( ( shelf ) => {
|
|
8460
|
+
// shelfConfigArr.push( {
|
|
8461
|
+
// fixtureCode: fixture.fixtureCode,
|
|
8462
|
+
// ...shelf,
|
|
8463
|
+
// } );
|
|
8464
|
+
// } );
|
|
8465
|
+
|
|
8466
|
+
// ( fixture.vmConfig || [] ).forEach( ( vm ) => {
|
|
8467
|
+
// vmConfigArr.push( {
|
|
8468
|
+
// fixtureCode: fixture.fixtureCode,
|
|
8469
|
+
// ...vm,
|
|
8470
|
+
// } );
|
|
8471
|
+
// } );
|
|
8472
|
+
// }
|
|
8473
|
+
|
|
8474
|
+
// const workbook = xlsx.utils.book_new();
|
|
8475
|
+
// xlsx.utils.book_append_sheet( workbook, xlsx.utils.json_to_sheet( fixtureInfoArr ), 'Fixture Info' );
|
|
8476
|
+
// xlsx.utils.book_append_sheet( workbook, xlsx.utils.json_to_sheet( shelfConfigArr ), 'Shelf Config' );
|
|
8477
|
+
// xlsx.utils.book_append_sheet( workbook, xlsx.utils.json_to_sheet( vmConfigArr ), 'VM Config' );
|
|
8478
|
+
|
|
8479
|
+
// xlsx.writeFile( workbook, filePath );
|
|
8480
|
+
// }
|
|
8481
|
+
|
|
8482
|
+
// const fixtures = JSON.parse( fs.readFileSync( './input.json', 'utf-8' ) );
|
|
8483
|
+
// exportFixtureJsonToExcel( fixtures, 'output.xlsx' );
|
|
8484
|
+
|
|
8485
|
+
|