tango-app-api-store-builder 1.0.0-beta-197 → 1.0.0-beta-199

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tango-app-api-store-builder",
3
- "version": "1.0.0-beta-197",
3
+ "version": "1.0.0-beta-199",
4
4
  "description": "storeBuilder",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -866,7 +866,6 @@ export async function TemplateStoresList( req, res ) {
866
866
  export async function replaceFixtureDetails( req, res ) {
867
867
  try {
868
868
  let inputData = req.body;
869
- console.log( inputData );
870
869
  let replaceFixtureData = await fixtureConfigService.findOne( { _id: inputData.replaceFixture } );
871
870
 
872
871
  if ( !replaceFixtureData ) {
@@ -908,6 +907,16 @@ export async function replaceFixtureDetails( req, res ) {
908
907
  await templateLogService.create( data );
909
908
  }
910
909
  if ( inputData.storeList.length ) {
910
+ let storeList = inputData.storeList.map( ( ele ) => ele.storeId );
911
+ let getDetails = await storeFixtureService.find( { storeId: { $in: storeList }, fixtureConfigId: inputData.findFixture, $or: [ { isMerchEdited: true }, { isVmEdited: true } ] }, { storeId: 1 } );
912
+ if ( getDetails.length ) {
913
+ await Promise.all( getDetails.map( async ( ele ) => {
914
+ let taskDetails = await processedTaskService.findOne( { store_id: ele.storeId, isPlano: true, planoType: [ 'merchRollout', 'vmRollout' ] }, {}, { _id: -1 } );
915
+ if ( taskDetails ) {
916
+ await processedTaskService.deleteOne( { _id: taskDetails._id } );
917
+ }
918
+ } ) );
919
+ }
911
920
  const updateData = {
912
921
  ...replaceFixtureData.toObject(),
913
922
  fixtureConfigId: replaceFixtureData._id,
@@ -933,19 +933,34 @@ export async function updateGlobalComment( req, res ) {
933
933
  return res.sendError( e, 500 );
934
934
  }
935
935
  }
936
- export async function getGlobalComment( req, res ) {
936
+ export async function getGlobalComment(req, res) {
937
937
  try {
938
- let layoutComment = await planoGlobalCommentService.find( {
939
- planoId: new mongoose.Types.ObjectId( req.body.planoId ),
940
- floorId: new mongoose.Types.ObjectId( req.body.floorId ),
941
- taskType: req.body.taskType,
942
- } );
938
+ // let layoutComment = await planoGlobalCommentService.find( {
939
+ // planoId: new mongoose.Types.ObjectId( req.body.planoId ),
940
+ // floorId: new mongoose.Types.ObjectId( req.body.floorId ),
941
+ // taskType: req.body.taskType,
942
+ // } );
943
+
944
+ let taskId = [];
945
+ if (req.body?.taskId) {
946
+ taskId.push(new mongoose.Types.ObjectId(req.body.taskId));
947
+ }
943
948
 
949
+ if (req.body?.refTaskId) {
950
+ taskId.push(new mongoose.Types.ObjectId(req.body.refTaskId));
951
+ }
952
+
953
+ let layoutComment = await planoGlobalCommentService.find({
954
+ planoId: new mongoose.Types.ObjectId(req.body.planoId),
955
+ floorId: new mongoose.Types.ObjectId(req.body.floorId),
956
+ ...(taskId.length && { taskId: { $in: taskId } }),
957
+ taskType: req.body.taskType,
958
+ });
944
959
 
945
- res.sendSuccess( layoutComment );
946
- } catch ( e ) {
947
- logger.error( { functionName: 'getGlobalComment', error: e } );
948
- return res.sendError( e, 500 );
960
+ res.sendSuccess(layoutComment);
961
+ } catch (e) {
962
+ logger.error({ functionName: 'getGlobalComment', error: e });
963
+ return res.sendError(e, 500);
949
964
  }
950
965
  }
951
966
 
@@ -9549,57 +9549,148 @@ async function updateHeaders() {
9549
9549
  } );
9550
9550
  }
9551
9551
 
9552
-
9553
- export async function readExcel( req, res ) {
9552
+ export async function productMappings(req, res) {
9554
9553
  try {
9555
- const workbook = xlsx.read( req.files.file.data, { type: 'buffer' } );
9556
- const sheetName = 'Updated - 275';
9557
- const raw = xlsx.utils.sheet_to_json( workbook.Sheets[sheetName] );
9558
- // const sheetName1 = 'Zone Level Allocation with No o';
9559
- const sheetName1 = 'Zone Level Allocation with > 1 ';
9560
- const rawZone = xlsx.utils.sheet_to_json( workbook.Sheets[sheetName1] );
9561
- console.log( rawZone );
9562
- let data = [];
9563
- function cleanFixtures( obj ) {
9564
- const cleaned = {};
9565
- for ( const key in obj ) {
9566
- // Skip keys that match pattern "Fixture number_number"
9567
- if ( /^Fixture \d+_\d+$/.test( key ) ) continue;
9568
- cleaned[key] = obj[key];
9554
+ const CLEAR_COL_BEFORE_INSERT = false;
9555
+ if (req?.headers?.authorization?.split(" ")[1] !== "hwjXfCD6TgMvc82cuSGZ9bNv9MuXsaiQ6uvx") {
9556
+ return res.sendError("Unauthorized", 401);
9557
+ }
9558
+
9559
+ if (!req.files?.file) {
9560
+ return res.sendError("Excel file is required", 400);
9561
+ }
9562
+
9563
+ const payload = JSON.parse(req.body.payload);
9564
+
9565
+ const { fixtureId, Top, Mid, Bottom } = payload;
9566
+
9567
+ const storeName = "LKST98";
9568
+ const storeId = "11-4";
9569
+
9570
+ if (!fixtureId) {
9571
+ return res.sendError("fixtureId is required", 400);
9572
+ }
9573
+
9574
+ const fixtureData = { Top, Mid, Bottom };
9575
+
9576
+ const workbook = xlsx.read(req.files.file.data, { type: "buffer" });
9577
+ const sheetName = "Unique Mapping";
9578
+ const raw = xlsx.utils.sheet_to_json(workbook.Sheets[sheetName]);
9579
+
9580
+ const pidsList = Object.values(fixtureData).flat();
9581
+
9582
+ let pDetailsList = [];
9583
+ for (const pid of pidsList) {
9584
+ const pDetails = raw.find((pd) => pd["product_id"] == pid);
9585
+ if (pDetails) {
9586
+ pDetailsList.push({
9587
+ clientId: "11",
9588
+ productId: pDetails.product_id,
9589
+ productName: pDetails.parent_brand,
9590
+ pid: pDetails.product_id,
9591
+ rfId: pDetails.barcode,
9592
+ productImageUrl: pDetails.image_front,
9593
+ productType: pDetails.classification_name ?? "",
9594
+ brandName: pDetails.collection ?? "",
9595
+ category: pDetails.collection_group ?? "",
9596
+ subCategory: pDetails.sub_collection ?? "",
9597
+ type: "product",
9598
+ });
9569
9599
  }
9570
- return cleaned;
9571
9600
  }
9572
- raw.forEach( ( ele ) => {
9573
- ele = cleanFixtures( ele );
9574
- let keys = Object.keys( ele );
9575
- let category = ele['Category'];
9576
- let fixture = [];
9577
- keys.splice( 0, 1 );
9578
- keys.forEach( ( key ) => {
9579
- let topValue = rawZone.find( ( zone ) => zone.Category == category && zone.r == keys.length && zone.Category_1 == 'Top' );
9580
- let midValue = rawZone.find( ( zone ) => zone.Category == category && zone.r == keys.length && zone.Category_1 == 'Mid' );
9581
- let midValue1 = rawZone.find( ( zone ) => zone.Category == category && zone.r == keys.length && zone.Category_1 == 'Mid 2' || zone.Category_1 == 'Mid _2' );
9582
- let bottomValue = rawZone.find( ( zone ) => zone.Category == category && zone.r == keys.length && zone.Category_1 == 'Bottom' );
9583
- if ( midValue1 && midValue1[key] != '-' ) {
9584
- midValue[key] = midValue[key] + ' + ' + midValue1[key];
9585
- }
9586
- fixture.push( {
9587
- header: ele[key],
9588
- top: topValue[key],
9589
- mid: midValue[key],
9590
- bottom: bottomValue[key],
9591
- } );
9592
- } );
9593
- data.push( {
9594
- category: category,
9595
- fixtureCount: fixture.length,
9596
- fixtures: fixture,
9597
- } );
9598
- } );
9599
- return res.sendSuccess( data );
9600
- } catch ( e ) {
9601
- console.log( e );
9602
- logger.error( { functionName: 'readExcel', error: e } );
9603
- return res.sendError( e, 500 );
9601
+
9602
+ if(CLEAR_COL_BEFORE_INSERT) await planoProductService.deleteMany({});
9603
+
9604
+ // const uniqueProducts = await fixtureShelfService.find();
9605
+
9606
+ const fixtureTemplateData = await fixtureShelfService.find({ fixtureId });
9607
+
9608
+ if (!fixtureTemplateData?.length) {
9609
+ return res.sendError("No shelves found for fixtureId", 404);
9610
+ }
9611
+
9612
+ const planoId = fixtureTemplateData[0].planoId;
9613
+ const floorId = fixtureTemplateData[0].floorId;
9614
+
9615
+ const fixtureShelve = fixtureTemplateData.map((f) => ({
9616
+ id: f._id,
9617
+ zone: f.zone,
9618
+ }));
9619
+
9620
+ const result = await planoProductService.insertMany(pDetailsList);
9621
+
9622
+ let planoMappings = result.map((pd) => ({
9623
+ clientId: "11",
9624
+ storeName: storeName,
9625
+ storeId: storeId,
9626
+ type: "product",
9627
+ productId: pd._id,
9628
+ pid: pd.pid,
9629
+ planoId,
9630
+ floorId,
9631
+ fixtureId,
9632
+ shelfId: "temp", // will be reassigned in transformProducts
9633
+ }));
9634
+
9635
+ if(CLEAR_COL_BEFORE_INSERT) await planoMappingService.deleteMany({});
9636
+
9637
+ const shelfGroups = {
9638
+ Top: fixtureShelve.filter((f) => f.zone === "Top").map((f) => f.id),
9639
+ Mid: fixtureShelve.filter((f) => f.zone === "Mid").map((f) => f.id),
9640
+ Bottom: fixtureShelve.filter((f) => f.zone === "Bottom").map((f) => f.id),
9641
+ };
9642
+
9643
+ const transformed = transformProducts(planoMappings, shelfGroups, fixtureData);
9644
+
9645
+ const result2 = await planoMappingService.insertMany(transformed);
9646
+
9647
+ res.sendSuccess({
9648
+ fixtureData,
9649
+ shelfGroups,
9650
+ planoMappings: result2,
9651
+ });
9652
+ } catch (error) {
9653
+ console.log("@@ ~ error:", error);
9654
+ res.sendError("Internal Server Error", 500);
9655
+ }
9656
+ }
9657
+
9658
+ function transformProducts(products, shelvesByZone, fixtureData) {
9659
+ const result = [];
9660
+
9661
+ // Build lookup: pid → zone
9662
+ const pidToZone = {};
9663
+ for (const [zone, pids] of Object.entries(fixtureData)) {
9664
+ pids.forEach(pid => {
9665
+ pidToZone[pid] = zone;
9666
+ });
9667
+ }
9668
+
9669
+ // Group products by zone
9670
+ const productsByZone = {};
9671
+ for (const doc of products) {
9672
+ const zone = pidToZone[doc.pid];
9673
+ if (!zone) continue;
9674
+ if (!productsByZone[zone]) productsByZone[zone] = [];
9675
+ productsByZone[zone].push(doc);
9604
9676
  }
9677
+
9678
+ // Round-robin distribute products across shelves
9679
+ for (const [zone, docs] of Object.entries(productsByZone)) {
9680
+ const shelves = shelvesByZone[zone] || [];
9681
+ if (shelves.length === 0) {
9682
+ result.push(...docs);
9683
+ continue;
9684
+ }
9685
+
9686
+ docs.forEach((doc, idx) => {
9687
+ const shelfId = shelves[idx % shelves.length]; // cycle through shelves
9688
+ result.push({
9689
+ ...doc,
9690
+ shelfId
9691
+ });
9692
+ });
9693
+ }
9694
+
9695
+ return result;
9605
9696
  }
@@ -3240,7 +3240,7 @@ export async function planoList( req, res ) {
3240
3240
  let page = inputData?.offset - 1 || 0;
3241
3241
  let skip = limit * page;
3242
3242
 
3243
- let storeDetails = await storeService.find( { clientId: inputData.clientId, status: 'active' }, { storeId: 1 } );
3243
+ let storeDetails = await storeService.find( { clientId: inputData.clientId, status: 'active', ...( inputData?.stores?.length && { storeId: { $in: inputData.stores } } ) }, { storeId: 1 } );
3244
3244
  storeDetails = storeDetails.map( ( ele ) => ele.storeId );
3245
3245
 
3246
3246
  let query = [
@@ -4553,7 +4553,7 @@ export async function getRolloutDetails( req, res ) {
4553
4553
  let page = req?.body?.offset || 1;
4554
4554
  let limit = req.body?.limit || 10;
4555
4555
  let skip = ( page -1 ) * limit;
4556
- let storeDetails = await storeService.find( { clientId: req.body.clientId, status: 'active' }, { storeId: 1 } );
4556
+ let storeDetails = await storeService.find( { clientId: req.body.clientId, status: 'active', ...( req.body?.stores?.length && { storeId: { $in: req.body.stores } } ) }, { storeId: 1 } );
4557
4557
  storeDetails = storeDetails.map( ( ele ) => ele.storeId );
4558
4558
  let query = [
4559
4559
  {
@@ -32,5 +32,5 @@ scriptRouter
32
32
  .post( '/recorrectTaskData', scriptController.recorrectTaskData )
33
33
  .post( '/migrateCrest', scriptController.migrateCrestv1 )
34
34
  .post( '/updatePlanoMappings', scriptController.updatePlanoMappings )
35
- .post( '/readExcel', scriptController.readExcel )
35
+ .post( '/productMappings', scriptController.productMappings )
36
36
  ;
@@ -16,6 +16,10 @@ export async function deleteMany( query = {} ) {
16
16
  return model.taskProcessedModel.deleteMany( query );
17
17
  }
18
18
 
19
+ export async function deleteOne( query = {} ) {
20
+ return model.taskProcessedModel.deleteOne( query );
21
+ }
22
+
19
23
  export async function aggregate( query = {} ) {
20
24
  return model.taskProcessedModel.aggregate( query );
21
25
  }