tango-app-api-store-builder 1.0.0-beta-113 → 1.0.0-beta-114

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.
@@ -15,6 +15,7 @@ import * as planoTaskComplianceService from '../service/planoTask.service.js';
15
15
  import * as planoQrConversionRequestService from '../service/planoQrConversionRequest.service.js';
16
16
  import * as fixtureConfigService from '../service/fixtureConfig.service.js';
17
17
  import * as planoStaticData from '../service/planoStaticData.service.js';
18
+ import * as planoVmService from '../service/planoVm.service.js';
18
19
 
19
20
 
20
21
  dayjs.extend( utc );
@@ -769,7 +770,7 @@ export async function storeFixturesv1( req, res ) {
769
770
  } ),
770
771
  );
771
772
 
772
- const productCount = await planoMappingService.count( { floorId: floor._id } );
773
+ // const productCount = await planoMappingService.count( { floorId: floor._id } );
773
774
 
774
775
  const otherElements = await storeFixtureService.find( {
775
776
  floorId: floor._id,
@@ -877,158 +878,6 @@ export async function updateStatus( req, res ) {
877
878
  }
878
879
  }
879
880
 
880
- export async function fixtureShelfProduct( req, res ) {
881
- try {
882
- if ( !req.body.fixtureId ) {
883
- return res.sendError( 'Fixture id is required', 400 );
884
- }
885
-
886
- let fixtureDetails = await storeFixtureService.findOne( { _id: req.body.fixtureId } );
887
- if ( !fixtureDetails ) {
888
- return res.sendError( 'Fixture not found', 204 );
889
- }
890
- // let planoDetails = await planoService.findOne( { _id: fixtureDetails.planoId } );
891
- let shelfDetails = await fixtureShelfService.find( { fixtureId: req.body.fixtureId } );
892
- // let query;
893
- // switch ( planoDetails.productResolutionLevel ) {
894
- // case 'L1':
895
- // query = { floorId: fixtureDetails.floorId };
896
- // break;
897
- // default:
898
- // query = { floorId: fixtureDetails.floorId, fixtureId: req.body.fixtureId };
899
- // break;
900
- // }
901
- // query = {
902
- // ...query,
903
- // ...( [ 'L3', 'L4' ].includes( planoDetails.productResolutionLevel ) ) ? { shelfId: shelf._id } : {},
904
- // productId: { $in: productIdList },
905
- // date: new Date( dayjs().format( 'YYYY-MM-DD' ) ),
906
- // };
907
- let shelfList = [];
908
- for ( let shelf of shelfDetails ) {
909
- let data = { ...shelf._doc, products: [] };
910
- let productMappingDetails = await planoMappingService.find( { shelfId: shelf._id } );
911
- let productIdList = productMappingDetails.map( ( item ) => item.productId );
912
- let productDetails = await planoProductService.find( { _id: productIdList } );
913
- let productComplianceDetails = await planoComplianceService.find( { date: new Date( dayjs().format( 'YYYY-MM-DD' ) ), shelfId: shelf._id } );
914
- let product = [];
915
- productDetails.forEach( ( item ) => {
916
- let data = { ...item._doc, status: 'missing', rfId: '' };
917
- let getPosition = productMappingDetails.find( ( ele ) => ele.productId.toString() == item._id.toString() );
918
- let findCompliance = productComplianceDetails.find( ( ele ) => ele.shelfPosition == getPosition.shelfPosition );
919
- if ( findCompliance ) {
920
- data.status = findCompliance.compliance;
921
- }
922
- data.rfId = getPosition.rfId;
923
- product.push( data );
924
- } );
925
- data.products = product;
926
- shelfList.push( data );
927
- }
928
- fixtureDetails = { ...fixtureDetails._doc, shelves: shelfList };
929
- return res.sendSuccess( fixtureDetails );
930
- } catch ( e ) {
931
- logger.error( { functionName: 'fixtureShelfProduct', error: e } );
932
- return res.sendError( e, 500 );
933
- }
934
- }
935
-
936
- // export async function fixtureShelfProductv1( req, res ) {
937
- // try {
938
- // const { planoId, fixtureId } = req.body;
939
-
940
- // const [ planogram, fixture ] = await Promise.all( [
941
- // planoService.findOne(
942
- // { _id: new mongoose.Types.ObjectId( planoId ) },
943
- // { storeId: 1, storeName: 1, planoId: '$_id', productResolutionLevel: 1 },
944
- // ),
945
- // storeFixtureService.findOne( {
946
- // _id: new mongoose.Types.ObjectId( fixtureId ),
947
- // } ),
948
- // ] );
949
-
950
- // if ( !planogram ) return res.sendError( 'Planogram not found', 204 );
951
- // if ( !fixture ) return res.sendError( 'Fixture not found', 204 );
952
-
953
- // const currentDate = new Date( dayjs().format( 'YYYY-MM-DD' ) );
954
-
955
- // const getProductsAndVms = async ( mappings ) => {
956
- // const productIds = mappings.map( ( mapping ) => mapping.productId );
957
- // const [ products, vms ] = await Promise.all( [
958
- // planoProductService.find( { _id: { $in: productIds }, type: 'product' } ),
959
- // planoProductService.find( { _id: { $in: productIds }, type: 'vm' } ),
960
- // ] );
961
-
962
- // const productMap = new Map( products.map( ( product ) => [ product._id.toString(), product.toObject() ] ) );
963
- // const vmMap = new Map( vms.map( ( vm ) => [ vm._id.toString(), vm.toObject() ] ) );
964
-
965
- // const productDetails = await Promise.all(
966
- // mappings.filter( ( item ) => item.type === 'product' ).map( async ( mapping ) => {
967
- // const productData = productMap.get( mapping.productId.toString() ) || {};
968
- // const mappingCompliance = await planoComplianceService.findOne( {
969
- // planoMappingId: mapping._id,
970
- // date: currentDate,
971
- // } );
972
- // const status = mappingCompliance ? mappingCompliance.compliance : '';
973
- // return { ...mapping.toObject(), ...productData, status };
974
- // } ),
975
- // );
976
-
977
- // const vmDetails = await Promise.all(
978
- // mappings.filter( ( item ) => item.type === 'vm' ).map( async ( mapping ) => {
979
- // const vmData = vmMap.get( mapping.productId.toString() ) || {};
980
- // return { ...mapping.toObject(), ...vmData };
981
- // } ),
982
- // );
983
-
984
- // return { productDetails, vmDetails };
985
- // };
986
-
987
- // if ( fixture.toObject().productResolutionLevel === 'L1' ) {
988
- // const productMappings = await planoMappingService.find( { fixtureId: new mongoose.Types.ObjectId( fixtureId ) } );
989
- // const { productDetails, vmDetails } = await getProductsAndVms( productMappings );
990
- // return res.sendSuccess( { ...fixture.toObject(), products: productDetails, vms: vmDetails } );
991
- // }
992
- // if ( fixture.toObject().productResolutionLevel === 'L2' || fixture.toObject().productResolutionLevel === 'L4' ) {
993
- // const fixtureShelves = await fixtureShelfService.find( { fixtureId: new mongoose.Types.ObjectId( fixtureId ) } );
994
- // if ( !fixtureShelves.length ) return res.sendError( 'No shelves found for the fixture', 204 );
995
- // const shelfProducts = await Promise.all(
996
- // fixtureShelves.map( async ( shelf ) => {
997
- // const productMappings = await planoMappingService.find( { shelfId: shelf._id } );
998
- // const { productDetails, vmDetails } = await getProductsAndVms( productMappings );
999
- // return { ...shelf.toObject(), products: productDetails, vms: vmDetails };
1000
- // } ),
1001
- // );
1002
- // return res.sendSuccess( { ...fixture.toObject(), shelves: shelfProducts } );
1003
- // }
1004
- // if ( fixture.toObject().productResolutionLevel === 'L3' ) {
1005
- // const fixtureShelves = await fixtureShelfService.find( { fixtureId: new mongoose.Types.ObjectId( fixtureId ) } );
1006
- // if ( !fixtureShelves.length ) return res.sendError( 'No shelves found for the fixture', 204 );
1007
- // const groupedShelves = await ( async () => {
1008
- // const shelfProducts = await Promise.all(
1009
- // fixtureShelves.map( async ( shelf ) => {
1010
- // const productMappings = await planoMappingService.find( { shelfId: shelf._id } );
1011
- // const { productDetails, vmDetails } = await getProductsAndVms( productMappings );
1012
- // return { ...shelf.toObject(), products: productDetails, vms: vmDetails };
1013
- // } ),
1014
- // );
1015
- // return shelfProducts.reduce( ( acc, shelf ) => {
1016
- // const sectionName = shelf.sectionName || 'Unknown';
1017
- // if ( !acc[sectionName] ) {
1018
- // acc[sectionName] = [];
1019
- // }
1020
- // acc[sectionName].push( shelf );
1021
- // return acc;
1022
- // }, {} );
1023
- // } )();
1024
- // return res.sendSuccess( { ...fixture.toObject(), categories: groupedShelves } );
1025
- // }
1026
- // return res.sendError( 'Incorrect resolution level', 400 );
1027
- // } catch ( e ) {
1028
- // logger.error( { functionName: 'fixtureShelfProductv1', error: e, message: req.body } );
1029
- // return res.sendError( e, 500 );
1030
- // }
1031
- // }
1032
881
 
1033
882
  export async function fixtureShelfProductv1( req, res ) {
1034
883
  try {
@@ -1136,140 +985,6 @@ export async function fixtureShelfProductv1( req, res ) {
1136
985
  }
1137
986
 
1138
987
 
1139
- export async function scan( req, res ) {
1140
- try {
1141
- let shelfId;
1142
- if ( !req.body.planoId ) {
1143
- return res.sendError( 'Plano id is required', 400 );
1144
- }
1145
- if ( !req.body.rfId ) {
1146
- return res.sendError( 'RFID is required', 400 );
1147
- }
1148
- let planoDetails = await planoService.findOne( { _id: req.body.planoId } );
1149
- if ( !planoDetails ) {
1150
- return res.sendError( 'No data found', 204 );
1151
- }
1152
- if ( ![ 'L1', 'L2' ].includes( planoDetails.productResolutionLevel ) ) {
1153
- if ( !req.body.shelfId ) {
1154
- let shelfDetails = await fixtureShelfService.findOne( { rfId: req.body.rfId } );
1155
- if ( !shelfDetails ) {
1156
- return res.sendError( 'Please scan shelf first', 400 );
1157
- }
1158
- return res.sendSuccess( shelfDetails._id );
1159
- }
1160
- }
1161
- if ( planoDetails.productResolutionLevel == 'L5' ) {
1162
- let shelfDetails = await fixtureShelfService.findOne( { _id: req.body.shelfId } );
1163
- if ( !shelfDetails ) {
1164
- return res.sendError( 'No data found', 204 );
1165
- }
1166
- if ( shelfDetails.shelfCapacity < req.body.shelfPosition ) {
1167
- return res.sendError( 'Shelf capacity exceeded', 400 );
1168
- }
1169
- shelfDetails = await fixtureShelfService.find( { sectionName: shelfDetails?.sectionName } );
1170
- shelfId = req.body.shelfId;
1171
- req.body.shelfId = shelfDetails.map( ( ele ) => ele._id );
1172
- }
1173
- let productCheck = await planoMappingService.findOne( { rfId: req.body.rfId } );
1174
- if ( !productCheck ) {
1175
- return res.sendError( 'Product not found', 400 );
1176
- }
1177
- let query;
1178
- switch ( planoDetails.productResolutionLevel ) {
1179
- case 'L1':
1180
- if ( !req.body.floorId ) {
1181
- return res.sendError( 'Floor id is required', 400 );
1182
- }
1183
- query = { floorId: req.body.floorId };
1184
- break;
1185
- case 'L2':
1186
- if ( !req.body.floorId ) {
1187
- return res.sendError( 'Floor id is required', 400 );
1188
- }
1189
- if ( !req.body.fixtureId ) {
1190
- return res.sendError( 'Fixture id is required', 400 );
1191
- }
1192
- query = { floorId: req.body.floorId, fixtureId: req.body.fixtureId };
1193
- break;
1194
- case 'L3':
1195
- if ( !req.body.floorId ) {
1196
- return res.sendError( 'Floor id is required', 400 );
1197
- }
1198
- if ( !req.body.fixtureId ) {
1199
- return res.sendError( 'Fixture id is required', 400 );
1200
- }
1201
- if ( !req.body.shelfId ) {
1202
- return res.sendError( 'Shelf id is required', 400 );
1203
- }
1204
- query = { floorId: req.body.floorId, fixtureId: req.body.fixtureId, shelfId: req.body.shelfId };
1205
- break;
1206
- case 'L4':
1207
- if ( !req.body.floorId ) {
1208
- return res.sendError( 'Floor id is required', 400 );
1209
- }
1210
- if ( !req.body.fixtureId ) {
1211
- return res.sendError( 'Fixture id is required', 400 );
1212
- }
1213
- if ( !req.body.shelfId ) {
1214
- return res.sendError( 'Shelf id is required', 400 );
1215
- }
1216
- if ( !req.body.shelfPosition ) {
1217
- return res.sendError( 'Shelf position is required', 400 );
1218
- }
1219
- query = { floorId: req.body.floorId, fixtureId: req.body.fixtureId, shelfId: req.body.shelfId, shelfPosition: req.body.shelfPosition };
1220
- break;
1221
- case 'L5':
1222
- if ( !req.body.floorId ) {
1223
- return res.sendError( 'Floor id is required', 400 );
1224
- }
1225
- if ( !req.body.fixtureId ) {
1226
- return res.sendError( 'Fixture id is required', 400 );
1227
- }
1228
- if ( !req.body.shelfId ) {
1229
- return res.sendError( 'Shelf id is required', 400 );
1230
- }
1231
- query = { floorId: req.body.floorId, fixtureId: req.body.fixtureId, shelfId: { $in: req.body.shelfId } };
1232
- break;
1233
- default:
1234
- return res.sendError( 'Product not found', 400 );
1235
- break;
1236
- }
1237
- query = { ...query, rfId: req.body.rfId };
1238
-
1239
- let planoProductDetails = await planoMappingService.findOne( query );
1240
- // let data = {
1241
- // ...( planoProductDetails ) ? { ...planoProductDetails._doc } : { planoId: req.body?.planoId, floorId: req.body?.floorId, fixtureId: req.body?.fixtureId, shelfId: shelfId, clientId: planoDetails.clientId, storeName: planoDetails.storeName, storeId: planoDetails.storeId, shelfPosition: req.body?.shelfPosition },
1242
- // rfId: req.body.rfId,
1243
- // compliance: !planoProductDetails ? 'misplaced' : 'proper',
1244
- // date: new Date( dayjs().format( 'YYYY-MM-DD' ) ),
1245
- // };
1246
- let data = {
1247
- planoId: req.body?.planoId,
1248
- floorId: req.body?.floorId,
1249
- fixtureId: req.body?.fixtureId,
1250
- shelfId: shelfId,
1251
- clientId: planoDetails.clientId,
1252
- storeName: planoDetails.storeName,
1253
- storeId: planoDetails.storeId,
1254
- shelfPosition: req.body?.shelfPosition,
1255
- rfId: req.body.rfId,
1256
- compliance: !planoProductDetails ? 'misplaced' : 'proper',
1257
- date: new Date( dayjs().format( 'YYYY-MM-DD' ) ),
1258
- };
1259
- delete data._id;
1260
- delete query.rfId;
1261
- query = { ...query, date: new Date( dayjs().format( 'YYYY-MM-DD' ) ), shelfPosition: req.body.shelfPosition };
1262
- await planoComplianceService.updateOne( query, data );
1263
- if ( !planoProductDetails ) {
1264
- return res.sendSuccess( false );
1265
- }
1266
- return res.sendSuccess( true );
1267
- } catch ( e ) {
1268
- logger.error( { functonName: 'scan', error: e } );
1269
- return res.sendError( e, 500 );
1270
- }
1271
- }
1272
-
1273
988
  export async function scanv1( req, res ) {
1274
989
  try {
1275
990
  if ( !req.body.floorId ) return res.sendError( 'Floor id is required', 400 );
@@ -1886,7 +1601,8 @@ export const uploadImage = async ( req, res ) => {
1886
1601
  return res.sendError( { message: 'Something went Wrong' }, 500 );
1887
1602
  }
1888
1603
 
1889
- return res.sendSuccess( { message: 'Uploaded Successfully', imgUrl: imgUrl } );
1604
+
1605
+ return res.sendSuccess( { message: 'Uploaded Successfully', imgUrl: imgUrl, path: imgUrl.Key } );
1890
1606
  } catch ( e ) {
1891
1607
  logger.error( 'uploadImage =>', e );
1892
1608
  return res.sendError( e, 500 );
@@ -2089,7 +1805,7 @@ export async function storeFixturesTask( req, res ) {
2089
1805
  } ),
2090
1806
  );
2091
1807
 
2092
- const productCount = await planoMappingService.count( { floorId: floor._id } );
1808
+ // const productCount = await planoMappingService.count( { floorId: floor._id } );
2093
1809
 
2094
1810
  const otherElements = await storeFixtureService.find( {
2095
1811
  floorId: floor._id,
@@ -2913,3 +2629,663 @@ export async function qrScan( req, res ) {
2913
2629
  return res.sendError( e, 500 );
2914
2630
  }
2915
2631
  }
2632
+
2633
+ export async function storeFixturesv2( req, res ) {
2634
+ try {
2635
+ const planoIds = req.body.id
2636
+ .filter( ( id ) => mongoose.Types.ObjectId.isValid( id ) )
2637
+ .map( ( id ) => new mongoose.Types.ObjectId( id ) );
2638
+
2639
+ const planograms = await planoService.find(
2640
+ {
2641
+ $or: [
2642
+ { _id: { $in: planoIds } },
2643
+ { storeId: { $in: req.body.id } },
2644
+ ],
2645
+ },
2646
+ { storeId: 1, storeName: 1, planoId: '$_id', productResolutionLevel: 1, scanType: 1, clientId: 1, validateShelfSections: 1 },
2647
+ );
2648
+
2649
+ if ( !planograms?.length ) return res.sendError( 'No data found', 204 );
2650
+
2651
+ const currentDate = new Date( dayjs().format( 'YYYY-MM-DD' ) );
2652
+
2653
+ const storeLayout = await Promise.all(
2654
+ planograms.map( async ( planogram ) => {
2655
+ const floors = await storeBuilderService.find(
2656
+ { planoId: planogram._id },
2657
+ { floorName: 1, layoutPolygon: 1, planoId: 1 },
2658
+ );
2659
+
2660
+ const floorsWithFixtures = await Promise.all(
2661
+ floors.map( async ( floor ) => {
2662
+ let productCapacity = 0;
2663
+ let fixtureCount = 0;
2664
+ let totalVmCount = 0;
2665
+ const layoutPolygonWithFixtures = await Promise.all(
2666
+ floor.layoutPolygon.map( async ( element ) => {
2667
+ const fixtures = await storeFixtureService.findAndSort( {
2668
+ floorId: floor._id,
2669
+ associatedElementType: element.elementType,
2670
+ associatedElementNumber: element.elementNumber,
2671
+ fixtureType: 'wall',
2672
+ }, { shelfcount: 0 }, { fixtureNumber: 1 } );
2673
+
2674
+ const fixturesWithStatus = await Promise.all(
2675
+ fixtures.map( async ( fixture ) => {
2676
+ if ( fixture?.imageUrl ) {
2677
+ let params = {
2678
+ Bucket: JSON.parse( process.env.BUCKET ).storeBuilder,
2679
+ file_path: fixture.imageUrl,
2680
+ };
2681
+ fixture.imageUrl = await signedUrl( params );
2682
+ } else {
2683
+ fixture.imageUrl = '';
2684
+ }
2685
+ productCapacity += fixture.toObject().fixtureCapacity;
2686
+ fixtureCount += 1;
2687
+ const productCount = await planoMappingService.count( { fixtureId: fixture._id, type: 'product' } );
2688
+
2689
+ const vmCount = await planoMappingService.count( { fixtureId: fixture._id, type: 'vm' } );
2690
+
2691
+ const complianceCount = await planoComplianceService.count( {
2692
+ fixtureId: fixture._id,
2693
+ compliance: 'proper',
2694
+ date: currentDate,
2695
+ } );
2696
+
2697
+ const shelves = await fixtureShelfService.findAndSort( { fixtureId: fixture._id }, { }, { shelfNumber: 1 } );
2698
+
2699
+ const shelfDetails = await Promise.all(
2700
+ shelves.map( async ( shelf ) => {
2701
+ const productCount = await planoMappingService.count( { fixtureId: fixture._id, shelfId: shelf.toObject(), type: 'product' } );
2702
+
2703
+ const vmCount = await planoMappingService.count( { fixtureId: fixture._id, shelfId: shelf.toObject(), type: 'vm' } );
2704
+
2705
+ return {
2706
+ ...shelf.toObject(),
2707
+ productCount: productCount,
2708
+ vmCount: vmCount,
2709
+ };
2710
+ } ),
2711
+ );
2712
+
2713
+ let fixtureStatus;
2714
+
2715
+ const cvProcessStatus = await planoQrConversionRequestService.count( { fixtureId: fixture._id, date: currentDate, status: 'initiated' } );
2716
+
2717
+ if ( cvProcessStatus ) {
2718
+ fixtureStatus = 'inprogress';
2719
+ } else {
2720
+ const missingCount = await planoComplianceService.count( {
2721
+ fixtureId: fixture._id,
2722
+ compliance: 'missing',
2723
+ date: currentDate,
2724
+ } );
2725
+ fixtureStatus = complianceCount === 0 && !missingCount ? '' : complianceCount === productCount ? 'complete' : 'incomplete';
2726
+ }
2727
+
2728
+
2729
+ const vmDetails = await Promise.all( fixture.toObject()?.vmConfig?.map( async ( vm ) => {
2730
+ totalVmCount += 1;
2731
+ const vmInfo = await planoVmService.findOne( { _id: vm.vmId } );
2732
+ return {
2733
+ ...vm,
2734
+ ...vmInfo?.toObject(),
2735
+ };
2736
+ } ) );
2737
+
2738
+ return {
2739
+ ...fixture.toObject(),
2740
+ status: fixtureStatus,
2741
+ shelfCount: shelves.length,
2742
+ productCount: productCount,
2743
+ vmCount: vmCount,
2744
+ shelfConfig: shelfDetails,
2745
+ vmConfig: vmDetails,
2746
+ };
2747
+ } ),
2748
+ );
2749
+
2750
+ const otherElements = await storeFixtureService.find( {
2751
+ floorId: floor._id,
2752
+ associatedElementType: element.elementType,
2753
+ associatedElementNumber: element.elementNumber,
2754
+ fixtureType: 'other',
2755
+ } );
2756
+
2757
+ return {
2758
+ ...element,
2759
+ fixtures: fixturesWithStatus,
2760
+ otherElements: otherElements,
2761
+ };
2762
+ } ),
2763
+ );
2764
+
2765
+ const centerFixtures = await storeFixtureService.find( {
2766
+ floorId: floor._id,
2767
+ fixtureType: 'floor',
2768
+ } );
2769
+
2770
+ const centerFixturesWithStatus = await Promise.all(
2771
+ centerFixtures.map( async ( fixture ) => {
2772
+ if ( fixture?.imageUrl ) {
2773
+ let params = {
2774
+ Bucket: JSON.parse( process.env.BUCKET ).storeBuilder,
2775
+ file_path: fixture.imageUrl,
2776
+ };
2777
+ fixture.imageUrl = await signedUrl( params );
2778
+ } else {
2779
+ fixture.imageUrl = '';
2780
+ }
2781
+ productCapacity += fixture.toObject().fixtureCapacity;
2782
+ fixtureCount += 1;
2783
+ const productCount = await planoMappingService.count( { fixtureId: fixture._id, type: 'product' } );
2784
+
2785
+ const vmCount = await planoMappingService.count( { fixtureId: fixture._id, type: 'vm' } );
2786
+
2787
+ const complianceCount = await planoComplianceService.count( {
2788
+ fixtureId: fixture._id,
2789
+ compliance: 'proper',
2790
+ date: currentDate,
2791
+ } );
2792
+
2793
+ const shelves = await fixtureShelfService.findAndSort( { fixtureId: fixture._id }, { }, { shelfNumber: 1 } );
2794
+
2795
+ const shelfDetails = await Promise.all(
2796
+ shelves.map( async ( shelf ) => {
2797
+ const productCount = await planoMappingService.count( { fixtureId: fixture._id, shelfId: shelf.toObject(), type: 'product' } );
2798
+
2799
+ const vmCount = await planoMappingService.count( { fixtureId: fixture._id, shelfId: shelf.toObject(), type: 'vm' } );
2800
+
2801
+ return {
2802
+ ...shelf.toObject(),
2803
+ productCount: productCount,
2804
+ vmCount: vmCount,
2805
+ };
2806
+ } ),
2807
+ );
2808
+
2809
+ let fixtureStatus;
2810
+
2811
+ const cvProcessStatus = await planoQrConversionRequestService.count( { fixtureId: fixture._id, date: currentDate, status: 'initiated' } );
2812
+
2813
+ if ( cvProcessStatus ) {
2814
+ fixtureStatus = 'inprogress';
2815
+ } else {
2816
+ const missingCount = await planoComplianceService.count( {
2817
+ fixtureId: fixture._id,
2818
+ compliance: 'missing',
2819
+ date: currentDate,
2820
+ } );
2821
+ fixtureStatus = complianceCount === 0 && !missingCount ? '' : complianceCount === productCount ? 'complete' : 'incomplete';
2822
+ }
2823
+
2824
+
2825
+ const vmDetails = await Promise.all( fixture.toObject().vmConfig.map( async ( vm ) => {
2826
+ totalVmCount += 1;
2827
+ const vmInfo = await planoVmService.findOne( { _id: vm.vmId } );
2828
+
2829
+ return {
2830
+ ...vm,
2831
+ ...vmInfo?.toObject(),
2832
+ };
2833
+ } ) );
2834
+
2835
+ return {
2836
+ ...fixture.toObject(),
2837
+ status: fixtureStatus,
2838
+ shelfCount: shelves.shelves,
2839
+ productCount: productCount,
2840
+ vmCount: vmCount,
2841
+ shelfConfig: shelfDetails,
2842
+ vmConfig: vmDetails,
2843
+
2844
+ };
2845
+ } ),
2846
+ );
2847
+
2848
+
2849
+ const otherElements = await storeFixtureService.find( {
2850
+ floorId: floor._id,
2851
+ associatedElementType: { $exists: false },
2852
+ associatedElementNumber: { $exists: false },
2853
+ fixtureType: 'other',
2854
+ } );
2855
+
2856
+ return {
2857
+ ...floor.toObject(),
2858
+ fixtureCount: fixtureCount,
2859
+ vmCount: totalVmCount,
2860
+ layoutPolygon: layoutPolygonWithFixtures,
2861
+ centerFixture: centerFixturesWithStatus,
2862
+ productCount: productCapacity,
2863
+ // productCapacity: productCapacity,
2864
+ otherElements: otherElements,
2865
+ };
2866
+ } ),
2867
+ );
2868
+
2869
+ return {
2870
+ ...planogram.toObject(),
2871
+ floors: floorsWithFixtures,
2872
+ };
2873
+ } ),
2874
+ );
2875
+
2876
+ return res.sendSuccess( storeLayout );
2877
+ } catch ( e ) {
2878
+ logger.error( { functionName: 'storeFixturesv1', error: e, message: req.body } );
2879
+ return res.sendError( e, 500 );
2880
+ }
2881
+ }
2882
+
2883
+ export async function fixtureShelfProductv2( req, res ) {
2884
+ try {
2885
+ const { planoId, fixtureId } = req.body;
2886
+
2887
+ const [ planogram, fixture ] = await Promise.all( [
2888
+ planoService.findOne(
2889
+ { _id: new mongoose.Types.ObjectId( planoId ) },
2890
+ { storeId: 1, storeName: 1, planoId: '$_id', productResolutionLevel: 1 },
2891
+ ),
2892
+ storeFixtureService.findOne( { _id: new mongoose.Types.ObjectId( fixtureId ) } ),
2893
+ ] );
2894
+
2895
+ if ( !planogram ) return res.sendError( 'Planogram not found', 204 );
2896
+ if ( !fixture ) return res.sendError( 'Fixture not found', 204 );
2897
+
2898
+
2899
+ const currentDate = new Date( dayjs().format( 'YYYY-MM-DD' ) );
2900
+
2901
+ const getProducts = async ( mappings ) => {
2902
+ const productIds = mappings.map( ( mapping ) => mapping.productId );
2903
+ const products = await planoProductService.find( { _id: { $in: productIds }, type: 'product' } );
2904
+ const productMap = new Map( products.map( ( product ) => [ product._id.toString(), product.toObject() ] ) );
2905
+
2906
+ return await Promise.all(
2907
+ mappings.map( async ( mapping ) => {
2908
+ const productData = productMap.get( mapping?.productId?.toString() ) || {};
2909
+ delete productData._id;
2910
+ const mappingCompliance = await planoComplianceService.findOne( {
2911
+ planoMappingId: mapping._id,
2912
+ date: currentDate,
2913
+ } );
2914
+ const status = mappingCompliance ? mappingCompliance.compliance : '';
2915
+ return { ...mapping.toObject(), ...productData, status };
2916
+ } ),
2917
+ );
2918
+ };
2919
+
2920
+ const vmDetails = await Promise.all( fixture.toObject()?.vmConfig?.map( async ( vm ) => {
2921
+ const vmInfo = await planoVmService.findOne( { _id: vm.vmId } );
2922
+ return {
2923
+ ...vm,
2924
+ ...vmInfo?.toObject(),
2925
+ };
2926
+ } ) );
2927
+
2928
+ if ( fixture.toObject().productResolutionLevel === 'L1' ) {
2929
+ const productMappings = await planoMappingService.find( { fixtureId: new mongoose.Types.ObjectId( fixtureId ), type: 'product' } );
2930
+ const productDetails = await getProducts( productMappings );
2931
+ return res.sendSuccess( { ...fixture.toObject(), products: productDetails, vmConfig: vmDetails, productCount: productMappings.length } );
2932
+ }
2933
+
2934
+ if ( [ 'L2', 'L3', 'L4' ].includes( fixture.toObject().productResolutionLevel ) ) {
2935
+ const fixtureShelves = await fixtureShelfService.findAndSort( { fixtureId: new mongoose.Types.ObjectId( fixtureId ) }, {}, { shelfNumber: 1 } );
2936
+ const productCount = await planoMappingService.count( { fixtureId: new mongoose.Types.ObjectId( fixtureId ), type: 'product' } );
2937
+ const shelfProducts = await Promise.all(
2938
+ fixtureShelves.map( async ( shelf ) => {
2939
+ const productMappings = await planoMappingService.find( { shelfId: shelf._id, type: 'product' } );
2940
+ const productDetails = await getProducts( productMappings );
2941
+ return { ...shelf.toObject(), products: productDetails };
2942
+ } ),
2943
+ );
2944
+ return res.sendSuccess( { ...fixture.toObject(), shelves: shelfProducts, vmConfig: vmDetails, productCount: productCount } );
2945
+ }
2946
+
2947
+ return res.sendError( 'Incorrect resolution level', 400 );
2948
+ } catch ( e ) {
2949
+ logger.error( { functionName: 'fixtureShelfProductv1', error: e, message: req.body } );
2950
+ return res.sendError( e, 500 );
2951
+ }
2952
+ }
2953
+
2954
+ export async function storeFixturesTaskv2( req, res ) {
2955
+ try {
2956
+ const planoIds = req.body.id
2957
+ .filter( ( id ) => mongoose.Types.ObjectId.isValid( id ) )
2958
+ .map( ( id ) => new mongoose.Types.ObjectId( id ) );
2959
+
2960
+ const planograms = await planoService.find(
2961
+ {
2962
+ $or: [
2963
+ { _id: { $in: planoIds } },
2964
+ { storeId: { $in: req.body.id } },
2965
+ ],
2966
+ },
2967
+ { storeId: 1, storeName: 1, planoId: '$_id', productResolutionLevel: 1, scanType: 1, validateShelfSections: 1 },
2968
+ );
2969
+
2970
+ if ( !planograms?.length ) return res.sendError( 'No data found', 204 );
2971
+
2972
+
2973
+ const storeLayout = await Promise.all(
2974
+ planograms.map( async ( planogram ) => {
2975
+ const floors = await storeBuilderService.find(
2976
+ { planoId: planogram._id },
2977
+ { floorName: 1, layoutPolygon: 1, planoId: 1 },
2978
+ );
2979
+
2980
+ const floorsWithFixtures = await Promise.all(
2981
+ floors.map( async ( floor ) => {
2982
+ let productCapacity = 0;
2983
+ let fixtureCount = 0;
2984
+ let totalVmCount = 0;
2985
+ const layoutPolygonWithFixtures = await Promise.all(
2986
+ floor.layoutPolygon.map( async ( element ) => {
2987
+ const fixtures = await storeFixtureService.findAndSort( {
2988
+ floorId: floor._id,
2989
+ associatedElementType: element.elementType,
2990
+ associatedElementNumber: element.elementNumber,
2991
+ fixtureType: 'wall',
2992
+ }, { shelfcount: 0 }, { fixtureNumber: 1 } );
2993
+
2994
+ const fixturesWithStatus = await Promise.all(
2995
+ fixtures.map( async ( fixture ) => {
2996
+ if ( fixture?.imageUrl || fixture.vmImageUrl ) {
2997
+ let params = {
2998
+ Bucket: JSON.parse( process.env.BUCKET ).storeBuilder,
2999
+ file_path: req.body.type == 'vm' ? fixture.vmImageUrl : fixture.imageUrl,
3000
+ };
3001
+ fixture.imageUrl = await signedUrl( params );
3002
+ } else {
3003
+ fixture.imageUrl = '';
3004
+ }
3005
+ productCapacity += fixture.toObject().fixtureCapacity;
3006
+ fixtureCount += 1;
3007
+ const productCount = await planoMappingService.count( { fixtureId: fixture._id, type: 'product' } );
3008
+
3009
+ const vmCount = await planoMappingService.count( { fixtureId: fixture._id, type: 'vm' } );
3010
+
3011
+ const compliance = await planoTaskComplianceService.findOne( {
3012
+ fixtureId: fixture._id,
3013
+ type: req.body?.type ? req.body.type : 'fixture',
3014
+ date_string: req.body?.date,
3015
+ }, { status: 1, answers: 1 } );
3016
+
3017
+ const shelves = await fixtureShelfService.findAndSort( { fixtureId: fixture._id }, { }, { shelfNumber: 1 } );
3018
+
3019
+ const shelfDetails = await Promise.all(
3020
+ shelves.map( async ( shelf ) => {
3021
+ const productCount = await planoMappingService.count( { fixtureId: fixture._id, shelfId: shelf.toObject(), type: 'product' } );
3022
+
3023
+ const vmCount = await planoMappingService.count( { fixtureId: fixture._id, shelfId: shelf.toObject(), type: 'vm' } );
3024
+
3025
+ return {
3026
+ ...shelf.toObject(),
3027
+ productCount: productCount,
3028
+ vmCount: vmCount,
3029
+ };
3030
+ } ),
3031
+ );
3032
+
3033
+
3034
+ const vmDetails = await Promise.all( fixture.toObject()?.vmConfig?.map( async ( vm ) => {
3035
+ totalVmCount += 1;
3036
+ const vmInfo = await planoVmService.findOne( { _id: vm.vmId } );
3037
+ return {
3038
+ ...vm,
3039
+ ...vmInfo?.toObject(),
3040
+ };
3041
+ } ) );
3042
+
3043
+ let disabled = true;
3044
+ if ( compliance?.status && compliance.status == 'incomplete' ) {
3045
+ let issueDetails = compliance?.answers?.[0]?.issues.find( ( ele ) => ele.status == 'disagree' );
3046
+ if ( issueDetails ) {
3047
+ disabled = false;
3048
+ }
3049
+ }
3050
+
3051
+ return {
3052
+ ...fixture.toObject(),
3053
+ status: compliance?.status ? compliance.status : '',
3054
+ shelfCount: shelves.length,
3055
+ productCount: productCount,
3056
+ disabled: disabled,
3057
+ vmCount: vmCount,
3058
+ shelfConfig: shelfDetails,
3059
+ vmConfig: vmDetails,
3060
+ };
3061
+ } ),
3062
+ );
3063
+
3064
+ const otherElements = await storeFixtureService.find( {
3065
+ floorId: floor._id,
3066
+ associatedElementType: element.elementType,
3067
+ associatedElementNumber: element.elementNumber,
3068
+ fixtureType: 'other',
3069
+ } );
3070
+
3071
+ return {
3072
+ ...element,
3073
+ fixtures: fixturesWithStatus,
3074
+ otherElements: otherElements,
3075
+ };
3076
+ } ),
3077
+ );
3078
+
3079
+ const centerFixtures = await storeFixtureService.find( {
3080
+ floorId: floor._id,
3081
+ fixtureType: 'floor',
3082
+ } );
3083
+
3084
+ const centerFixturesWithStatus = await Promise.all(
3085
+ centerFixtures.map( async ( fixture ) => {
3086
+ if ( fixture?.imageUrl || fixture.vmImageUrl ) {
3087
+ let params = {
3088
+ Bucket: JSON.parse( process.env.BUCKET ).storeBuilder,
3089
+ file_path: req.body.type == 'vm' ? fixture.vmImageUrl : fixture.imageUrl,
3090
+ };
3091
+ fixture.imageUrl = await signedUrl( params );
3092
+ } else {
3093
+ fixture.imageUrl = '';
3094
+ }
3095
+ productCapacity += fixture.toObject().fixtureCapacity;
3096
+ fixtureCount += 1;
3097
+ const productCount = await planoMappingService.count( { fixtureId: fixture._id, type: 'product' } );
3098
+
3099
+ const vmCount = await planoMappingService.count( { fixtureId: fixture._id, type: 'vm' } );
3100
+
3101
+ const compliance = await planoTaskComplianceService.findOne( {
3102
+ fixtureId: fixture._id,
3103
+ type: req.body?.type ? req.body.type : 'fixture',
3104
+ date_string: req.body?.date,
3105
+ }, { status: 1 } );
3106
+
3107
+ const shelves = await fixtureShelfService.findAndSort( { fixtureId: fixture._id }, { }, { shelfNumber: 1 } );
3108
+
3109
+ const shelfDetails = await Promise.all(
3110
+ shelves.map( async ( shelf ) => {
3111
+ const productCount = await planoMappingService.count( { fixtureId: fixture._id, shelfId: shelf.toObject(), type: 'product' } );
3112
+
3113
+ const vmCount = await planoMappingService.count( { fixtureId: fixture._id, shelfId: shelf.toObject(), type: 'vm' } );
3114
+
3115
+ return {
3116
+ ...shelf.toObject(),
3117
+ productCount: productCount,
3118
+ vmCount: vmCount,
3119
+ };
3120
+ } ),
3121
+ );
3122
+
3123
+ const vmDetails = await Promise.all( fixture.toObject()?.vmConfig?.map( async ( vm ) => {
3124
+ totalVmCount += 1;
3125
+ const vmInfo = await planoVmService.findOne( { _id: vm.vmId } );
3126
+ return {
3127
+ ...vm,
3128
+ ...vmInfo?.toObject(),
3129
+ };
3130
+ } ) );
3131
+
3132
+ return {
3133
+ ...fixture.toObject(),
3134
+ status: compliance?.status ? compliance.status : '',
3135
+ shelfCount: shelves.shelves,
3136
+ productCount: productCount,
3137
+ vmCount: vmCount,
3138
+ shelfConfig: shelfDetails,
3139
+ vms: vmDetails,
3140
+ };
3141
+ } ),
3142
+ );
3143
+
3144
+ // const productCount = await planoMappingService.count( { floorId: floor._id } );
3145
+
3146
+ const otherElements = await storeFixtureService.find( {
3147
+ floorId: floor._id,
3148
+ associatedElementType: { $exists: false },
3149
+ associatedElementNumber: { $exists: false },
3150
+ fixtureType: 'other',
3151
+ } );
3152
+
3153
+ return {
3154
+ ...floor.toObject(),
3155
+ fixtureCount: fixtureCount,
3156
+ vmCount: totalVmCount,
3157
+ layoutPolygon: layoutPolygonWithFixtures,
3158
+ centerFixture: centerFixturesWithStatus,
3159
+ productCount: productCapacity,
3160
+ // productCapacity: productCapacity,
3161
+ otherElements: otherElements,
3162
+ };
3163
+ } ),
3164
+ );
3165
+
3166
+ return {
3167
+ ...planogram.toObject(),
3168
+ floors: floorsWithFixtures,
3169
+ };
3170
+ } ),
3171
+ );
3172
+
3173
+ return res.sendSuccess( storeLayout );
3174
+ } catch ( e ) {
3175
+ logger.error( { functionName: 'storeFixturesTask', error: e, message: req.body } );
3176
+ return res.sendError( e, 500 );
3177
+ }
3178
+ }
3179
+
3180
+ export async function planoList( req, res ) {
3181
+ try {
3182
+ let inputData = req.body;
3183
+ let limit = inputData?.limit || 10;
3184
+ let page = inputData?.offset - 1 || 0;
3185
+ let skip = limit * page;
3186
+ let query = [
3187
+ {
3188
+ $match: {
3189
+ clientId: inputData.clientId,
3190
+ },
3191
+ },
3192
+ {
3193
+ $lookup: {
3194
+ from: 'storelayouts',
3195
+ let: { plano: '$_id' },
3196
+ pipeline: [
3197
+ {
3198
+ $match: {
3199
+ $expr: {
3200
+ $eq: [ '$planoId', '$$plano' ],
3201
+ },
3202
+ },
3203
+ },
3204
+ {
3205
+ $group: {
3206
+ _id: '',
3207
+ layoutDetails: { $push: { k: '$_id', v: '$status', planoId: '$$plano' } },
3208
+ },
3209
+ },
3210
+ ],
3211
+ as: 'layout',
3212
+ },
3213
+ },
3214
+ { $unwind: { path: '$layout', preserveNullAndEmptyArrays: true } },
3215
+ {
3216
+ $lookup: {
3217
+ from: 'storefixtures',
3218
+ let: { plano: '$_id' },
3219
+ pipeline: [
3220
+ {
3221
+ $match: {
3222
+ $expr: {
3223
+ $eq: [ '$planoId', '$$plano' ],
3224
+ },
3225
+ },
3226
+ },
3227
+ {
3228
+ $group: {
3229
+ _id: '',
3230
+ fixtureCount: { $sum: 1 },
3231
+ vmCount: { $sum: { $size: '$vmConfig' } },
3232
+ fixtureCapacity: { $sum: '$fixtureCapacity' },
3233
+ },
3234
+ },
3235
+ ],
3236
+ as: 'fixtureDetails',
3237
+ },
3238
+ },
3239
+ { $unwind: { path: '$fixtureDetails', preserveNullAndEmptyArrays: true } },
3240
+ {
3241
+ $project: {
3242
+ storeName: 1,
3243
+ layoutName: 1,
3244
+ layoutDetails: '$layout.layoutDetails',
3245
+ fixtureCount: '$fixtureDetails.fixtureCount',
3246
+ vmCount: '$fixtureDetails.vmCount',
3247
+ fixtureCapacity: '$fixtureDetails.fixtureCapacity',
3248
+ status: 1,
3249
+ planoProgress: 1,
3250
+ },
3251
+ },
3252
+ ];
3253
+ if ( inputData.sortColumnName && inputData.sortBy ) {
3254
+ query.push( { $sort: { [inputData.sortColumnName]: inputData.sortBy } } );
3255
+ }
3256
+ if ( inputData.searchValue ) {
3257
+ query.push( {
3258
+ $match: {
3259
+ storeName: { $regex: inputData.searchValue, $options: 'i' },
3260
+ },
3261
+ } );
3262
+ }
3263
+
3264
+ query.push( {
3265
+ $facet: {
3266
+ data: [
3267
+ { $skip: skip },
3268
+ { $limit: limit },
3269
+ ],
3270
+ count: [
3271
+ { $count: 'total' },
3272
+ ],
3273
+ },
3274
+ } );
3275
+
3276
+ let planoDetails = await planoService.aggregate( query );
3277
+
3278
+ if ( !planoDetails[0].data.length ) {
3279
+ return res.sendError( 'No data found', 204 );
3280
+ }
3281
+ let result = {
3282
+ data: planoDetails[0].data,
3283
+ count: planoDetails?.[0]?.count?.[0]?.total || 0,
3284
+ };
3285
+ return res.sendSuccess( result );
3286
+ } catch ( e ) {
3287
+ console.log( e );
3288
+ logger.error( { functionName: 'planoList', error: e } );
3289
+ return res.sendError( e, 500 );
3290
+ }
3291
+ }