tango-app-api-store-builder 1.0.32 → 1.0.33
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 +1 -1
- package/src/controllers/fixtureTemplate.controller.js +339 -0
- package/src/controllers/managePlano.controller.js +8 -8
- package/src/controllers/script.controller.js +2 -2
- package/src/controllers/storeBuilder.controller.js +509 -101
- package/src/routes/storeBuilder.routes.js +5 -4
package/package.json
CHANGED
|
@@ -690,6 +690,8 @@ export async function TemplateStoresList( req, res ) {
|
|
|
690
690
|
storeName: 1,
|
|
691
691
|
planoId: 1,
|
|
692
692
|
floorId: 1,
|
|
693
|
+
isMerchEdited: 1,
|
|
694
|
+
isVmEdited: 1,
|
|
693
695
|
},
|
|
694
696
|
},
|
|
695
697
|
{
|
|
@@ -699,6 +701,8 @@ export async function TemplateStoresList( req, res ) {
|
|
|
699
701
|
planoId: { $first: '$planoId' },
|
|
700
702
|
storeId: { $first: '$storeId' },
|
|
701
703
|
floorId: { $first: '$floorId' },
|
|
704
|
+
isMerchEdited: { $push: '$isMerchEdited' },
|
|
705
|
+
isVmEdited: { $push: '$isVmEdited' },
|
|
702
706
|
},
|
|
703
707
|
},
|
|
704
708
|
{
|
|
@@ -758,6 +762,8 @@ export async function TemplateStoresList( req, res ) {
|
|
|
758
762
|
spocEmail: { $ifNull: [ '$storeData.spocDetails.email', '' ] },
|
|
759
763
|
floorDetails: 1,
|
|
760
764
|
_id: '$_id.store',
|
|
765
|
+
isMerchEdited: 1,
|
|
766
|
+
isVmEdited: 1,
|
|
761
767
|
},
|
|
762
768
|
},
|
|
763
769
|
);
|
|
@@ -818,6 +824,335 @@ export async function TemplateStoresList( req, res ) {
|
|
|
818
824
|
);
|
|
819
825
|
}
|
|
820
826
|
|
|
827
|
+
query.push(
|
|
828
|
+
{
|
|
829
|
+
$lookup: {
|
|
830
|
+
from: 'processedtasks',
|
|
831
|
+
let: { store: '$storeId' },
|
|
832
|
+
pipeline: [
|
|
833
|
+
{
|
|
834
|
+
$match: {
|
|
835
|
+
$expr: {
|
|
836
|
+
$and: [
|
|
837
|
+
{ $lte: [ '$date_iso', new Date( dayjs().format( 'YYYY-MM-DD' ) ) ] },
|
|
838
|
+
{ $eq: [ '$store_id', '$$store' ] },
|
|
839
|
+
{ $eq: [ '$isPlano', true ] },
|
|
840
|
+
{ $in: [ '$planoType', [ 'merchRollout', 'vmRollout' ] ] },
|
|
841
|
+
],
|
|
842
|
+
},
|
|
843
|
+
},
|
|
844
|
+
},
|
|
845
|
+
{
|
|
846
|
+
$sort: { _id: -1 },
|
|
847
|
+
},
|
|
848
|
+
{
|
|
849
|
+
$group: {
|
|
850
|
+
_id: '$planoType',
|
|
851
|
+
type: { $first: '$planoType' },
|
|
852
|
+
status: { $first: '$checklistStatus' },
|
|
853
|
+
taskId: { $first: '$_id' },
|
|
854
|
+
scheduleEndTime_iso: { $first: '$scheduleEndTime_iso' },
|
|
855
|
+
},
|
|
856
|
+
},
|
|
857
|
+
{
|
|
858
|
+
$project: {
|
|
859
|
+
_id: 0,
|
|
860
|
+
type: 1,
|
|
861
|
+
status: 1,
|
|
862
|
+
taskId: 1,
|
|
863
|
+
breach: {
|
|
864
|
+
$cond: {
|
|
865
|
+
if: {
|
|
866
|
+
$gte: [ '$scheduleEndTime_iso', new Date() ],
|
|
867
|
+
},
|
|
868
|
+
then: false,
|
|
869
|
+
else: true,
|
|
870
|
+
},
|
|
871
|
+
},
|
|
872
|
+
},
|
|
873
|
+
},
|
|
874
|
+
],
|
|
875
|
+
as: 'taskDetails',
|
|
876
|
+
},
|
|
877
|
+
},
|
|
878
|
+
{
|
|
879
|
+
$lookup: {
|
|
880
|
+
from: 'planotaskcompliances',
|
|
881
|
+
let: { taskId: '$taskDetails.taskId' },
|
|
882
|
+
pipeline: [
|
|
883
|
+
{
|
|
884
|
+
$match: {
|
|
885
|
+
$expr: {
|
|
886
|
+
$and: [
|
|
887
|
+
{ $in: [ '$taskId', '$$taskId' ] },
|
|
888
|
+
{ $in: [ '$type', [ 'merchRollout', 'vmRollout' ] ] },
|
|
889
|
+
// { $eq: [ '$status', 'incomplete' ] },
|
|
890
|
+
],
|
|
891
|
+
},
|
|
892
|
+
},
|
|
893
|
+
},
|
|
894
|
+
{
|
|
895
|
+
$sort: { _id: -1 },
|
|
896
|
+
},
|
|
897
|
+
{
|
|
898
|
+
$set: {
|
|
899
|
+
hasCompletedAnswers: {
|
|
900
|
+
$anyElementTrue: {
|
|
901
|
+
$map: {
|
|
902
|
+
input: '$answers',
|
|
903
|
+
as: 'ans',
|
|
904
|
+
in: { $eq: [ '$$ans.status', null ] },
|
|
905
|
+
},
|
|
906
|
+
},
|
|
907
|
+
},
|
|
908
|
+
hasPendingIssues: {
|
|
909
|
+
$anyElementTrue: {
|
|
910
|
+
$map: {
|
|
911
|
+
input: {
|
|
912
|
+
$concatArrays: [
|
|
913
|
+
{
|
|
914
|
+
$reduce: {
|
|
915
|
+
input: '$answers',
|
|
916
|
+
initialValue: [],
|
|
917
|
+
in: {
|
|
918
|
+
$concatArrays: [
|
|
919
|
+
'$$value',
|
|
920
|
+
{
|
|
921
|
+
$reduce: {
|
|
922
|
+
input: { $ifNull: [ '$$this.issues', [] ] },
|
|
923
|
+
initialValue: [],
|
|
924
|
+
in: {
|
|
925
|
+
$concatArrays: [
|
|
926
|
+
'$$value',
|
|
927
|
+
{ $ifNull: [ '$$this.Details', [] ] },
|
|
928
|
+
],
|
|
929
|
+
},
|
|
930
|
+
},
|
|
931
|
+
},
|
|
932
|
+
],
|
|
933
|
+
},
|
|
934
|
+
},
|
|
935
|
+
},
|
|
936
|
+
],
|
|
937
|
+
},
|
|
938
|
+
as: 'detail',
|
|
939
|
+
in: {
|
|
940
|
+
$or: [ { $eq: [ '$$detail.status', 'pending' ] } ],
|
|
941
|
+
},
|
|
942
|
+
},
|
|
943
|
+
},
|
|
944
|
+
},
|
|
945
|
+
hasDisagreeIssues: {
|
|
946
|
+
$anyElementTrue: {
|
|
947
|
+
$map: {
|
|
948
|
+
input: {
|
|
949
|
+
$concatArrays: [
|
|
950
|
+
'$answers',
|
|
951
|
+
{
|
|
952
|
+
$reduce: {
|
|
953
|
+
input: '$answers',
|
|
954
|
+
initialValue: [],
|
|
955
|
+
in: {
|
|
956
|
+
$concatArrays: [
|
|
957
|
+
'$$value',
|
|
958
|
+
{
|
|
959
|
+
$reduce: {
|
|
960
|
+
input: { $ifNull: [ '$$this.issues', [] ] },
|
|
961
|
+
initialValue: [],
|
|
962
|
+
in: {
|
|
963
|
+
$concatArrays: [
|
|
964
|
+
'$$value',
|
|
965
|
+
{ $ifNull: [ '$$this.Details', [] ] },
|
|
966
|
+
],
|
|
967
|
+
},
|
|
968
|
+
},
|
|
969
|
+
},
|
|
970
|
+
],
|
|
971
|
+
},
|
|
972
|
+
},
|
|
973
|
+
},
|
|
974
|
+
],
|
|
975
|
+
},
|
|
976
|
+
as: 'detail',
|
|
977
|
+
in: {
|
|
978
|
+
$or: [ { $eq: [ '$$detail.status', 'disagree' ] } ],
|
|
979
|
+
},
|
|
980
|
+
},
|
|
981
|
+
},
|
|
982
|
+
},
|
|
983
|
+
},
|
|
984
|
+
},
|
|
985
|
+
{
|
|
986
|
+
$group: {
|
|
987
|
+
_id: { taskId: '$taskId' },
|
|
988
|
+
|
|
989
|
+
// merch counters
|
|
990
|
+
merchDisagree: {
|
|
991
|
+
$sum: {
|
|
992
|
+
$cond: [
|
|
993
|
+
{ $and: [ { $eq: [ '$type', 'merchRollout' ] }, '$hasDisagreeIssues' ] },
|
|
994
|
+
1,
|
|
995
|
+
0,
|
|
996
|
+
],
|
|
997
|
+
},
|
|
998
|
+
},
|
|
999
|
+
merchPending: {
|
|
1000
|
+
$sum: {
|
|
1001
|
+
$cond: [
|
|
1002
|
+
{
|
|
1003
|
+
$and: [
|
|
1004
|
+
{ $eq: [ '$type', 'merchRollout' ] },
|
|
1005
|
+
{ $or: [ '$hasPendingIssues', '$hasCompletedAnswers' ] },
|
|
1006
|
+
],
|
|
1007
|
+
},
|
|
1008
|
+
1,
|
|
1009
|
+
0,
|
|
1010
|
+
],
|
|
1011
|
+
},
|
|
1012
|
+
},
|
|
1013
|
+
merchApproved: {
|
|
1014
|
+
$push: {
|
|
1015
|
+
$cond: [
|
|
1016
|
+
{
|
|
1017
|
+
$and: [
|
|
1018
|
+
{ $eq: [ '$type', 'merchRollout' ] },
|
|
1019
|
+
{ $eq: [ '$approvalStatus', 'approved' ] },
|
|
1020
|
+
],
|
|
1021
|
+
},
|
|
1022
|
+
'$approvalStatus',
|
|
1023
|
+
'$$REMOVE',
|
|
1024
|
+
],
|
|
1025
|
+
},
|
|
1026
|
+
},
|
|
1027
|
+
|
|
1028
|
+
// vm counters
|
|
1029
|
+
vmDisagree: {
|
|
1030
|
+
$sum: {
|
|
1031
|
+
$cond: [
|
|
1032
|
+
{ $and: [ { $eq: [ '$type', 'vmRollout' ] }, '$hasDisagreeIssues' ] },
|
|
1033
|
+
1,
|
|
1034
|
+
0,
|
|
1035
|
+
],
|
|
1036
|
+
},
|
|
1037
|
+
},
|
|
1038
|
+
vmPending: {
|
|
1039
|
+
$sum: {
|
|
1040
|
+
$cond: [
|
|
1041
|
+
{
|
|
1042
|
+
$and: [
|
|
1043
|
+
{ $eq: [ '$type', 'vmRollout' ] },
|
|
1044
|
+
{ $or: [ '$hasPendingIssues', '$hasCompletedAnswers' ] },
|
|
1045
|
+
],
|
|
1046
|
+
},
|
|
1047
|
+
1,
|
|
1048
|
+
0,
|
|
1049
|
+
],
|
|
1050
|
+
},
|
|
1051
|
+
},
|
|
1052
|
+
vmApproved: {
|
|
1053
|
+
$push: {
|
|
1054
|
+
$cond: [
|
|
1055
|
+
{
|
|
1056
|
+
$and: [
|
|
1057
|
+
{ $eq: [ '$type', 'vmRollout' ] },
|
|
1058
|
+
{ $eq: [ '$approvalStatus', 'approved' ] },
|
|
1059
|
+
],
|
|
1060
|
+
},
|
|
1061
|
+
'$approvalStatus',
|
|
1062
|
+
'$$REMOVE',
|
|
1063
|
+
],
|
|
1064
|
+
},
|
|
1065
|
+
},
|
|
1066
|
+
|
|
1067
|
+
// counts
|
|
1068
|
+
merchCount: {
|
|
1069
|
+
$sum: {
|
|
1070
|
+
$cond: [ { $eq: [ '$type', 'merchRollout' ] }, 1, 0 ],
|
|
1071
|
+
},
|
|
1072
|
+
},
|
|
1073
|
+
vmCount: {
|
|
1074
|
+
$sum: {
|
|
1075
|
+
$cond: [ { $eq: [ '$type', 'vmRollout' ] }, 1, 0 ],
|
|
1076
|
+
},
|
|
1077
|
+
},
|
|
1078
|
+
},
|
|
1079
|
+
},
|
|
1080
|
+
{
|
|
1081
|
+
$project: {
|
|
1082
|
+
_id: 0,
|
|
1083
|
+
fixtureStatus: {
|
|
1084
|
+
$switch: {
|
|
1085
|
+
branches: [
|
|
1086
|
+
{
|
|
1087
|
+
case: { $eq: [ '$merchCount', 0 ] },
|
|
1088
|
+
then: '',
|
|
1089
|
+
},
|
|
1090
|
+
{
|
|
1091
|
+
case: { $gt: [ '$merchPending', 0 ] },
|
|
1092
|
+
then: 'pending',
|
|
1093
|
+
},
|
|
1094
|
+
{
|
|
1095
|
+
case: { $gt: [ '$merchDisagree', 0 ] },
|
|
1096
|
+
then: 'disagree',
|
|
1097
|
+
},
|
|
1098
|
+
{
|
|
1099
|
+
case: {
|
|
1100
|
+
$and: [
|
|
1101
|
+
{ $eq: [ '$merchPending', 0 ] },
|
|
1102
|
+
{ $eq: [ '$merchDisagree', 0 ] },
|
|
1103
|
+
{ $eq: [ { $size: '$merchApproved' }, '$merchCount' ] },
|
|
1104
|
+
],
|
|
1105
|
+
},
|
|
1106
|
+
then: 'complete',
|
|
1107
|
+
},
|
|
1108
|
+
],
|
|
1109
|
+
default: 'pending',
|
|
1110
|
+
},
|
|
1111
|
+
},
|
|
1112
|
+
vmStatus: {
|
|
1113
|
+
$switch: {
|
|
1114
|
+
branches: [
|
|
1115
|
+
{
|
|
1116
|
+
case: { $eq: [ '$vmCount', 0 ] },
|
|
1117
|
+
then: '',
|
|
1118
|
+
},
|
|
1119
|
+
{
|
|
1120
|
+
case: { $gt: [ '$vmPending', 0 ] },
|
|
1121
|
+
then: 'pending',
|
|
1122
|
+
},
|
|
1123
|
+
{
|
|
1124
|
+
case: { $gt: [ '$vmDisagree', 0 ] },
|
|
1125
|
+
then: 'disagree',
|
|
1126
|
+
},
|
|
1127
|
+
{
|
|
1128
|
+
case: {
|
|
1129
|
+
$and: [
|
|
1130
|
+
{ $eq: [ '$vmPending', 0 ] },
|
|
1131
|
+
{ $eq: [ '$vmDisagree', 0 ] },
|
|
1132
|
+
{ $eq: [ { $size: '$vmApproved' }, '$vmCount' ] },
|
|
1133
|
+
],
|
|
1134
|
+
},
|
|
1135
|
+
then: 'complete',
|
|
1136
|
+
},
|
|
1137
|
+
],
|
|
1138
|
+
default: 'pending',
|
|
1139
|
+
},
|
|
1140
|
+
},
|
|
1141
|
+
},
|
|
1142
|
+
},
|
|
1143
|
+
],
|
|
1144
|
+
as: 'taskFeedback',
|
|
1145
|
+
},
|
|
1146
|
+
},
|
|
1147
|
+
{
|
|
1148
|
+
$set: {
|
|
1149
|
+
taskFeedback: {
|
|
1150
|
+
$ifNull: [ { $arrayElemAt: [ '$taskFeedback', 0 ] }, {} ],
|
|
1151
|
+
},
|
|
1152
|
+
},
|
|
1153
|
+
},
|
|
1154
|
+
);
|
|
1155
|
+
|
|
821
1156
|
let floorQuery = [
|
|
822
1157
|
{
|
|
823
1158
|
$match: {
|
|
@@ -873,6 +1208,10 @@ export async function replaceFixtureDetails( req, res ) {
|
|
|
873
1208
|
if ( !replaceFixtureData ) {
|
|
874
1209
|
return res.sendError( 'No data found', 204 );
|
|
875
1210
|
}
|
|
1211
|
+
|
|
1212
|
+
if ( inputData?.revoke && inputData?.assignedStores?.length ) {
|
|
1213
|
+
await processedTaskService.deleteMany( { storeName: { $in: inputData?.assignedStores }, isPlano: true, planoType: { $nin: [ 'layout', 'fixture' ] }, checklistStatus: { $ne: 'submit' } } );
|
|
1214
|
+
}
|
|
876
1215
|
if ( inputData.storeList.length == 0 && inputData.publishAll ) {
|
|
877
1216
|
await fixtureConfigService.updateOne( { _id: inputData.replaceFixture }, { isEdited: false } );
|
|
878
1217
|
let query = [
|
|
@@ -1826,9 +1826,9 @@ export async function createPlanoRevision( req, res ) {
|
|
|
1826
1826
|
await planoRevisionService.create( data );
|
|
1827
1827
|
|
|
1828
1828
|
await storeBuilderService.updateOne( { _id: floorId },
|
|
1829
|
-
{ ...( req.body.type
|
|
1830
|
-
...( req.body.type
|
|
1831
|
-
...( !
|
|
1829
|
+
{ ...( req.body.type.includes( 'merchRollout' ) ) ? { merchRolloutStatus: true } :{},
|
|
1830
|
+
...( req.body.type.includes( 'vmRollout' ) ) ? { vmRolloutStatus: true } : {},
|
|
1831
|
+
...( !req.body?.type && { verificationStatus: true } ), planoProgress: 100 } );
|
|
1832
1832
|
|
|
1833
1833
|
res.sendSuccess( 'Plano published successfully' );
|
|
1834
1834
|
} catch ( e ) {
|
|
@@ -2417,6 +2417,11 @@ export async function createPlanoFromCAD(req, res) {
|
|
|
2417
2417
|
|
|
2418
2418
|
const cadData = await cadRes.json();
|
|
2419
2419
|
|
|
2420
|
+
logger.info({
|
|
2421
|
+
functionName: 'CAD DATA: ',
|
|
2422
|
+
body: { cadData, input: dataExtractPayload },
|
|
2423
|
+
});
|
|
2424
|
+
|
|
2420
2425
|
if (
|
|
2421
2426
|
cadData?.status !== 'success' ||
|
|
2422
2427
|
!cadData?.data?.layoutPolygon
|
|
@@ -2490,11 +2495,6 @@ export async function createPlanoFromCAD(req, res) {
|
|
|
2490
2495
|
floorId: floorData._id,
|
|
2491
2496
|
}
|
|
2492
2497
|
|
|
2493
|
-
logger.info({
|
|
2494
|
-
functionName: 'CAD DATA: ',
|
|
2495
|
-
body: cadData.data,
|
|
2496
|
-
});
|
|
2497
|
-
|
|
2498
2498
|
// Create Fixtures
|
|
2499
2499
|
const processedFixtures = createStoreFixtures(cadData.data, meta);
|
|
2500
2500
|
|
|
@@ -9573,8 +9573,8 @@ export async function productMappings( req, res ) {
|
|
|
9573
9573
|
|
|
9574
9574
|
const { fixtureId, Top, Mid, Bottom } = payload;
|
|
9575
9575
|
|
|
9576
|
-
const storeName = '
|
|
9577
|
-
const storeId = '11-
|
|
9576
|
+
const storeName = 'LKST2681';
|
|
9577
|
+
const storeId = '11-2362';
|
|
9578
9578
|
const clientId = '11';
|
|
9579
9579
|
|
|
9580
9580
|
if ( !fixtureId ) {
|
|
@@ -2792,7 +2792,7 @@ export async function storeFixturesv2( req, res ) {
|
|
|
2792
2792
|
planograms.map( async ( planogram ) => {
|
|
2793
2793
|
const floors = await storeBuilderService.find(
|
|
2794
2794
|
{ planoId: planogram._id, ...( req.body?.floorId && { _id: req.body.floorId } ) },
|
|
2795
|
-
{ floorName: 1, layoutPolygon: 1, planoId: 1, isEdited: 1, planoProgress: 1, updatedAt: 1, verificationStatus: 1, merchRolloutStatus: 1, vmRolloutStatus: 1,cadLayout:1 },
|
|
2795
|
+
{ floorName: 1, layoutPolygon: 1, planoId: 1, isEdited: 1, planoProgress: 1, updatedAt: 1, verificationStatus: 1, merchRolloutStatus: 1, vmRolloutStatus: 1, cadLayout: 1 },
|
|
2796
2796
|
);
|
|
2797
2797
|
|
|
2798
2798
|
const floorsWithFixtures = await Promise.all(
|
|
@@ -5154,8 +5154,8 @@ export async function planoList( req, res ) {
|
|
|
5154
5154
|
clientId: inputData.clientId,
|
|
5155
5155
|
status: 'active',
|
|
5156
5156
|
...( inputData?.stores?.length && { storeId: { $in: inputData.stores } } ),
|
|
5157
|
-
...( req.body.filter
|
|
5158
|
-
...( req.body.filter
|
|
5157
|
+
...( req.body.filter?.country?.length && { 'storeProfile.country': { $in: req.body.filter.country } } ),
|
|
5158
|
+
...( req.body.filter?.city?.length && { 'storeProfile.city': { $in: req.body.filter.city } } ),
|
|
5159
5159
|
...( req.body?.assignedStores?.length && { storeId: { $in: req.body?.assignedStores } } ) }, { storeId: 1, storeProfile: 1 } );
|
|
5160
5160
|
|
|
5161
5161
|
let storeDetails = storeList.map( ( ele ) => ele.storeId );
|
|
@@ -6095,19 +6095,27 @@ export async function planoList( req, res ) {
|
|
|
6095
6095
|
if ( req.body.export ) {
|
|
6096
6096
|
let exportData = [];
|
|
6097
6097
|
planoDetails[0].data.forEach( ( ele ) => {
|
|
6098
|
+
let findStore = storeList.find( ( store ) => ele.storeId == store.storeId );
|
|
6099
|
+
if ( findStore ) {
|
|
6100
|
+
ele['country'] = findStore.storeProfile.country;
|
|
6101
|
+
ele['city'] = findStore.storeProfile.city;
|
|
6102
|
+
}
|
|
6103
|
+
let fixtureStatus = ele?.taskDetails.fixtureStatus == 'complete' ? 'Completed' : ele?.taskDetails.fixtureStatus == 'pending' ? 'Review Pending' : 'Yet to assign';
|
|
6098
6104
|
exportData.push( {
|
|
6099
6105
|
'Store Name': ele?.storeName ?? '--',
|
|
6100
6106
|
'Layout Name': ele?.layoutName ?? '--',
|
|
6107
|
+
'Country': ele?.country ?? '--',
|
|
6108
|
+
'City': ele?.City ?? '--',
|
|
6101
6109
|
'Plano Completion %': ele?.taskDetails.layoutStatus == 'complete' && ele?.taskDetails.fixtureStatus == 'complete' ? 100 : ele?.taskDetails.layoutStatus == 'complete' ? 50 : 25,
|
|
6102
6110
|
'Layout': ele?.layoutCount ?? 0,
|
|
6103
6111
|
'Layout Status': ele?.taskDetails.layoutStatus == 'complete' ? 'Completed' : 'Yet to assign',
|
|
6104
6112
|
'No of Fixtures': ele?.fixtureCount ?? 0,
|
|
6105
|
-
'Fixture Status':
|
|
6113
|
+
'Fixture Status': fixtureStatus,
|
|
6106
6114
|
'No of VMs': ele?.vmCount ?? 0,
|
|
6107
|
-
'VM Status':
|
|
6115
|
+
'VM Status': fixtureStatus,
|
|
6108
6116
|
'Store Capacity': ele?.fixtureCapacity ?? 0,
|
|
6109
6117
|
'Last update': ele?.lastUpdate ? dayjs( ele.lastUpdate ).format( 'MMM DD, YYYY' ) : '--',
|
|
6110
|
-
'Planogram Status': ( ele?.taskDetails.fixtureStatus == 'complete' && ele?.taskDetails.layoutStatus == 'complete' && ele.layoutStatus.includes( false ) ) ? 'Yet to Publish' : !ele.layoutStatus.includes( false ) ? 'Published' :
|
|
6118
|
+
'Planogram Status': ( ele?.taskDetails.fixtureStatus == 'complete' && ele?.taskDetails.layoutStatus == 'complete' && ele.layoutStatus.includes( false ) ) ? 'Yet to Publish' : !ele.layoutStatus.includes( false ) ? 'Published' : fixtureStatus,
|
|
6111
6119
|
} );
|
|
6112
6120
|
} );
|
|
6113
6121
|
return await download( exportData, res );
|
|
@@ -6806,8 +6814,8 @@ export async function getRolloutDetails( req, res ) {
|
|
|
6806
6814
|
clientId: req.body.clientId,
|
|
6807
6815
|
status: 'active',
|
|
6808
6816
|
...( req.body?.stores?.length && { storeId: { $in: req.body.stores } } ),
|
|
6809
|
-
...( req.body.filter
|
|
6810
|
-
...( req.body.filter
|
|
6817
|
+
...( req.body.filter?.country?.length && { 'storeProfile.country': { $in: req.body.filter.country } } ),
|
|
6818
|
+
...( req.body.filter?.city?.length && { 'storeProfile.city': { $in: req.body.filter.city } } ),
|
|
6811
6819
|
...( req.body?.assignedStores?.length && { storeId: { $in: req.body?.assignedStores } } ) }, { storeId: 1, storeProfile: 1 } );
|
|
6812
6820
|
|
|
6813
6821
|
let storeDetails = storeList.map( ( ele ) => ele.storeId );
|
|
@@ -6833,7 +6841,8 @@ export async function getRolloutDetails( req, res ) {
|
|
|
6833
6841
|
updatedAt: { $first: '$updatedAt' },
|
|
6834
6842
|
floorNumber: { $first: '$floorNumber' },
|
|
6835
6843
|
layoutCount: { $sum: 1 },
|
|
6836
|
-
|
|
6844
|
+
merchStatus: { $push: '$merchRolloutStatus' },
|
|
6845
|
+
vmStatus: { $push: '$vmRolloutStatus' },
|
|
6837
6846
|
},
|
|
6838
6847
|
},
|
|
6839
6848
|
{
|
|
@@ -6888,8 +6897,9 @@ export async function getRolloutDetails( req, res ) {
|
|
|
6888
6897
|
lastUpdate: '$updatedAt',
|
|
6889
6898
|
merchEditedCount: '$fixtureDetails.merchEditedCount',
|
|
6890
6899
|
vmEditedCount: '$fixtureDetails.vmEditedCount',
|
|
6900
|
+
merchStatus: 1,
|
|
6901
|
+
vmStatus: 1,
|
|
6891
6902
|
layoutCount: 1,
|
|
6892
|
-
layoutStatus: 1,
|
|
6893
6903
|
},
|
|
6894
6904
|
},
|
|
6895
6905
|
{
|
|
@@ -7663,15 +7673,21 @@ export async function getRolloutDetails( req, res ) {
|
|
|
7663
7673
|
if ( req.body.export ) {
|
|
7664
7674
|
let exportData = [];
|
|
7665
7675
|
result.tableData.data.forEach( ( ele ) => {
|
|
7676
|
+
let merchStatus = ele?.taskDetails.fixtureStatus == 'complete' ? 'Completed' : ele?.taskDetails.fixtureStatus == 'pending' ? 'Review Pending' : 'Yet to Assign';
|
|
7677
|
+
let vmStatus = ele?.taskDetails.fixtureStatus == 'complete' ? 'Completed' : ele?.taskDetails.fixtureStatus == 'pending' ? 'Review Pending' : 'Yet to Assign';
|
|
7678
|
+
let planoStatus = [ merchStatus, vmStatus ];
|
|
7666
7679
|
exportData.push( {
|
|
7667
7680
|
'Store Name': ele?.storeName ?? '--',
|
|
7668
7681
|
'Plano Name': ele?.layoutName ?? '--',
|
|
7682
|
+
'Country': ele?.country ?? '--',
|
|
7683
|
+
'city': ele?.city ?? '--',
|
|
7684
|
+
'Floor': ele?.layoutCount ?? 0,
|
|
7669
7685
|
'Merch Fixtures': ele?.fixtureCount ?? 0,
|
|
7670
|
-
'Merch Status':
|
|
7686
|
+
'Merch Status': merchStatus,
|
|
7671
7687
|
'Visual Merch': ele?.vmCount ?? 0,
|
|
7672
|
-
'VM Status':
|
|
7688
|
+
'VM Status': vmStatus,
|
|
7673
7689
|
'Last update': ele?.lastUpdate ? dayjs( ele.lastUpdate ).format( 'MMM dd, YYYY' ) : '--',
|
|
7674
|
-
'Planogram Status': (
|
|
7690
|
+
'Planogram Status': planoStatus.includes( 'Review Pending' ) ? 'Review Pending' : planoStatus.includes( 'Yet to Assign' ) ? 'Yet to Assign' : ( planoStatus.every( ( ele ) => ele == 'Completed' ) && ( merchStatus.includes( false ) || vmStatus.includes( false ) ) ) ? 'Ready to Publish' : ( planoStatus.every( ( ele ) => ele == 'Completed' ) && ( !merchStatus.includes( false ) || !vmStatus.includes( false ) ) ) ? 'Published' : 'Task Assigned',
|
|
7675
7691
|
} );
|
|
7676
7692
|
} );
|
|
7677
7693
|
return await download( exportData, res );
|
|
@@ -8001,54 +8017,56 @@ export async function updateProductMapping( req, res ) {
|
|
|
8001
8017
|
let mappingData = [];
|
|
8002
8018
|
let complianceData = [];
|
|
8003
8019
|
await Promise.all( data.map( async ( ele ) => {
|
|
8004
|
-
|
|
8005
|
-
|
|
8006
|
-
|
|
8007
|
-
|
|
8008
|
-
|
|
8009
|
-
|
|
8010
|
-
|
|
8020
|
+
if ( ele?.data ) {
|
|
8021
|
+
let fixtureDetails = await storeFixtureService.find( { readerId: ele?.data?.MAC } );
|
|
8022
|
+
if ( fixtureDetails.length ) {
|
|
8023
|
+
let getShelfDetails = await fixtureShelfService.findOne( { fixtureId: { $in: fixtureDetails?.map( ( fixt ) => fixt._id ) }, antennaNo: { $in: [ ele?.data?.antenna ] } } );
|
|
8024
|
+
if ( !getShelfDetails ) {
|
|
8025
|
+
fixtureDetails = fixtureDetails.find( ( fixt ) => fixt?.footer?.antennaNo?.includes( ele.data.antenna ) );
|
|
8026
|
+
if ( fixtureDetails ) {
|
|
8027
|
+
getShelfDetails = { shelfType: 'storage' };
|
|
8028
|
+
}
|
|
8029
|
+
} else {
|
|
8030
|
+
fixtureDetails = fixtureDetails.find( ( fixt ) => fixt._id.toString() == getShelfDetails.fixtureId.toString() );
|
|
8011
8031
|
}
|
|
8012
|
-
|
|
8013
|
-
|
|
8014
|
-
|
|
8015
|
-
|
|
8016
|
-
|
|
8017
|
-
|
|
8018
|
-
|
|
8019
|
-
|
|
8020
|
-
|
|
8021
|
-
|
|
8022
|
-
|
|
8023
|
-
|
|
8024
|
-
|
|
8025
|
-
|
|
8026
|
-
|
|
8027
|
-
|
|
8028
|
-
|
|
8029
|
-
|
|
8030
|
-
|
|
8031
|
-
|
|
8032
|
-
|
|
8033
|
-
|
|
8034
|
-
|
|
8035
|
-
|
|
8036
|
-
|
|
8037
|
-
|
|
8038
|
-
|
|
8039
|
-
|
|
8040
|
-
|
|
8041
|
-
|
|
8042
|
-
|
|
8043
|
-
|
|
8044
|
-
|
|
8045
|
-
|
|
8046
|
-
|
|
8047
|
-
|
|
8048
|
-
|
|
8049
|
-
|
|
8050
|
-
|
|
8051
|
-
// await planoComplianceService.create( productData );
|
|
8032
|
+
if ( getShelfDetails ) {
|
|
8033
|
+
let productDetails = await planoProductService.findOne( { rfId: ele.data.idHex } );
|
|
8034
|
+
if ( productDetails ) {
|
|
8035
|
+
let data = {
|
|
8036
|
+
clientId: req.body.clientId,
|
|
8037
|
+
storeName: fixtureDetails.storeName,
|
|
8038
|
+
storeId: fixtureDetails.storeId,
|
|
8039
|
+
type: getShelfDetails?.shelfType != 'storage' ? 'product' : 'storageBox',
|
|
8040
|
+
productId: productDetails._id,
|
|
8041
|
+
pid: productDetails.pid,
|
|
8042
|
+
planoId: fixtureDetails.planoId,
|
|
8043
|
+
floorId: fixtureDetails.floorId,
|
|
8044
|
+
fixtureId: fixtureDetails._id,
|
|
8045
|
+
...( getShelfDetails?.shelfType != 'storage' && { shelfId: getShelfDetails._id } ),
|
|
8046
|
+
};
|
|
8047
|
+
mappingData.push( data );
|
|
8048
|
+
|
|
8049
|
+
// let mappingDetails = await planoMappingService.create( data );
|
|
8050
|
+
|
|
8051
|
+
let productData = {
|
|
8052
|
+
'planoMappingId': '',
|
|
8053
|
+
'date': dayjs().format( 'YYYY-MM-DD' ),
|
|
8054
|
+
'clientId': req.body.clientId,
|
|
8055
|
+
'compliance': getShelfDetails?.shelfType != 'storage' ? getShelfDetails.productBrandName.includes( productDetails.brandName ) ? 'proper' : 'misplaced' : '',
|
|
8056
|
+
'fixtureId': fixtureDetails._id,
|
|
8057
|
+
'floorId': fixtureDetails.floorId,
|
|
8058
|
+
'planoId': fixtureDetails.planoId,
|
|
8059
|
+
'productId': productDetails._id,
|
|
8060
|
+
'rfId': ele.data.idHex,
|
|
8061
|
+
'shelfId': getShelfDetails._id,
|
|
8062
|
+
'storeId': fixtureDetails.storeId,
|
|
8063
|
+
'storeName': fixtureDetails.storeName,
|
|
8064
|
+
'type': getShelfDetails?.shelfType != 'storage' ? 'product' : 'storageBox',
|
|
8065
|
+
};
|
|
8066
|
+
complianceData.push( productData );
|
|
8067
|
+
|
|
8068
|
+
// await planoComplianceService.create( productData );
|
|
8069
|
+
}
|
|
8052
8070
|
}
|
|
8053
8071
|
}
|
|
8054
8072
|
}
|
|
@@ -8455,7 +8473,7 @@ export async function getPlanogramListOld( req, res ) {
|
|
|
8455
8473
|
|
|
8456
8474
|
return res.sendSuccess( { data, count: total } );
|
|
8457
8475
|
} catch ( err ) {
|
|
8458
|
-
logger.error( { functionName: '
|
|
8476
|
+
logger.error( { functionName: 'getPlanogramListOld', error: err } );
|
|
8459
8477
|
return res.sendError( err, 500 );
|
|
8460
8478
|
}
|
|
8461
8479
|
}
|
|
@@ -8582,15 +8600,16 @@ export async function getPlanogramList( req, res ) {
|
|
|
8582
8600
|
merchCompliance: {
|
|
8583
8601
|
$floor: [
|
|
8584
8602
|
{
|
|
8585
|
-
$
|
|
8586
|
-
{
|
|
8603
|
+
$cond: {
|
|
8604
|
+
if: { $gt: [ { $ifNull: [ '$productCount', 0 ] }, 0 ] },
|
|
8605
|
+
then: {
|
|
8587
8606
|
$divide: [
|
|
8588
8607
|
{ $ifNull: [ { $arrayElemAt: [ '$complianceCount.count', 0 ] }, 0 ] },
|
|
8589
|
-
|
|
8608
|
+
'$productCount',
|
|
8590
8609
|
],
|
|
8591
8610
|
},
|
|
8592
|
-
|
|
8593
|
-
|
|
8611
|
+
else: 0,
|
|
8612
|
+
},
|
|
8594
8613
|
},
|
|
8595
8614
|
],
|
|
8596
8615
|
},
|
|
@@ -8642,6 +8661,35 @@ export async function getPlanogramList( req, res ) {
|
|
|
8642
8661
|
const total = result?.[0]?.count?.[0]?.total || 0;
|
|
8643
8662
|
|
|
8644
8663
|
if ( !data.length ) {
|
|
8664
|
+
if ( searchValue?.trim() ) {
|
|
8665
|
+
let query = [
|
|
8666
|
+
{
|
|
8667
|
+
$project: {
|
|
8668
|
+
storeName: 1,
|
|
8669
|
+
planoId: 1,
|
|
8670
|
+
_id: 1,
|
|
8671
|
+
},
|
|
8672
|
+
},
|
|
8673
|
+
];
|
|
8674
|
+
const values = searchValue.split( ',' ).map( ( s ) => s.trim().toLowerCase() );
|
|
8675
|
+
query.push(
|
|
8676
|
+
{ $addFields: { store: { $toLower: '$storeName' } } },
|
|
8677
|
+
);
|
|
8678
|
+
if ( values.length > 1 ) {
|
|
8679
|
+
query.push(
|
|
8680
|
+
{ $match: { store: { $in: values } } },
|
|
8681
|
+
);
|
|
8682
|
+
} else {
|
|
8683
|
+
query.push( {
|
|
8684
|
+
$match: { store: searchValue.toLowerCase() },
|
|
8685
|
+
} );
|
|
8686
|
+
}
|
|
8687
|
+
|
|
8688
|
+
let planoDetails = await storeBuilderService.aggregate( query );
|
|
8689
|
+
if ( planoDetails.length ) {
|
|
8690
|
+
return res.sendSuccess( { message: 'planogram', planoData: planoDetails } );
|
|
8691
|
+
}
|
|
8692
|
+
}
|
|
8645
8693
|
return res.sendError( 'No data found', 204 );
|
|
8646
8694
|
}
|
|
8647
8695
|
|
|
@@ -8683,81 +8731,441 @@ export async function getPlanogramList( req, res ) {
|
|
|
8683
8731
|
|
|
8684
8732
|
return res.sendSuccess( { data, count: total } );
|
|
8685
8733
|
} catch ( err ) {
|
|
8686
|
-
logger.error( { functionName: '
|
|
8734
|
+
logger.error( { functionName: 'getPlanogramList', error: err } );
|
|
8687
8735
|
return res.sendError( err, 500 );
|
|
8688
8736
|
}
|
|
8689
8737
|
}
|
|
8690
8738
|
|
|
8691
|
-
export async function
|
|
8739
|
+
export async function revisionData( req, res ) {
|
|
8740
|
+
try {
|
|
8741
|
+
let storeList = req.body.store;
|
|
8742
|
+
await Promise.all( storeList.map( async ( ele ) => {
|
|
8743
|
+
console.log( ele );
|
|
8744
|
+
req.body = { id: [ ele ] };
|
|
8745
|
+
await convertFixtureStructure( req, res );
|
|
8746
|
+
} ) );
|
|
8747
|
+
return res.sendSuccess( 'Updated Successfully' );
|
|
8748
|
+
} catch ( e ) {
|
|
8749
|
+
logger.error( { functionName: 'revisionData', error: e } );
|
|
8750
|
+
return res.sendError( e, 500 );
|
|
8751
|
+
}
|
|
8752
|
+
}
|
|
8753
|
+
|
|
8754
|
+
async function convertFixtureStructure( req ) {
|
|
8692
8755
|
try {
|
|
8756
|
+
const planoIds = req.body.id
|
|
8757
|
+
.filter( ( id ) => mongoose.Types.ObjectId.isValid( id ) )
|
|
8758
|
+
.map( ( id ) => new mongoose.Types.ObjectId( id ) );
|
|
8759
|
+
|
|
8760
|
+
const planograms = await planoService.find(
|
|
8761
|
+
{
|
|
8762
|
+
$or: [
|
|
8763
|
+
{ _id: { $in: planoIds } },
|
|
8764
|
+
{ storeId: { $in: req.body.id } },
|
|
8765
|
+
],
|
|
8766
|
+
},
|
|
8767
|
+
{ storeId: 1, storeName: 1, planoId: '$_id', productResolutionLevel: 1, scanType: 1, clientId: 1, validateShelfSections: 1, layoutName: 1 },
|
|
8768
|
+
);
|
|
8769
|
+
|
|
8770
|
+
if ( !planograms?.length ) return false;
|
|
8771
|
+
|
|
8772
|
+
const currentDate = new Date( dayjs().format( 'YYYY-MM-DD' ) );
|
|
8773
|
+
|
|
8774
|
+
await Promise.all(
|
|
8775
|
+
planograms.map( async ( planogram ) => {
|
|
8776
|
+
const floors = await storeBuilderService.find(
|
|
8777
|
+
{ planoId: planogram._id, ...( req.body?.floorId && { _id: req.body.floorId } ) },
|
|
8778
|
+
{ floorName: 1, layoutPolygon: 1, planoId: 1, isEdited: 1, planoProgress: 1, updatedAt: 1, verificationStatus: 1, merchRolloutStatus: 1, vmRolloutStatus: 1 },
|
|
8779
|
+
);
|
|
8780
|
+
|
|
8781
|
+
await Promise.all(
|
|
8782
|
+
floors.map( async ( floor, index ) => {
|
|
8783
|
+
let fixtureCount = 0;
|
|
8784
|
+
let totalVmCount = 0;
|
|
8785
|
+
let productCapacity = 0;
|
|
8786
|
+
const masterTemplateIds = new Set();
|
|
8787
|
+
const layoutPolygonWithFixtures = await Promise.all(
|
|
8788
|
+
floor.layoutPolygon.map( async ( element ) => {
|
|
8789
|
+
const fixtures = await storeFixtureService.findAndSort( {
|
|
8790
|
+
floorId: floor._id,
|
|
8791
|
+
associatedElementType: element.elementType,
|
|
8792
|
+
associatedElementNumber: element.elementNumber,
|
|
8793
|
+
fixtureType: { $ne: 'other' },
|
|
8794
|
+
}, { shelfcount: 0 }, { associatedElementFixtureNumber: 1 } );
|
|
8795
|
+
|
|
8796
|
+
const fixturesWithStatus = await Promise.all(
|
|
8797
|
+
fixtures.map( async ( fixture ) => {
|
|
8798
|
+
if ( fixture?.masterTemplateId && mongoose.Types.ObjectId.isValid( fixture?.masterTemplateId ) ) {
|
|
8799
|
+
masterTemplateIds.add( fixture?.masterTemplateId );
|
|
8800
|
+
}
|
|
8801
|
+
if ( fixture?.imageUrl ) {
|
|
8802
|
+
let params = {
|
|
8803
|
+
Bucket: JSON.parse( process.env.BUCKET ).storeBuilder,
|
|
8804
|
+
file_path: fixture.imageUrl,
|
|
8805
|
+
};
|
|
8806
|
+
fixture.imageUrl = await signedUrl( params );
|
|
8807
|
+
} else {
|
|
8808
|
+
fixture.imageUrl = '';
|
|
8809
|
+
}
|
|
8810
|
+
productCapacity += fixture.toObject().fixtureCapacity;
|
|
8811
|
+
fixtureCount += 1;
|
|
8812
|
+
const productCount = await planoMappingService.count( { fixtureId: fixture._id, type: 'product' } );
|
|
8813
|
+
|
|
8814
|
+
const vmCount = await planoMappingService.count( { fixtureId: fixture._id, type: 'vm' } );
|
|
8815
|
+
|
|
8816
|
+
const complianceCount = await planoComplianceService.count( {
|
|
8817
|
+
fixtureId: fixture._id,
|
|
8818
|
+
compliance: 'proper',
|
|
8819
|
+
date: currentDate,
|
|
8820
|
+
} );
|
|
8821
|
+
|
|
8822
|
+
const shelves = await fixtureShelfService.findAndSort( { fixtureId: fixture._id }, { }, { shelfNumber: 1 } );
|
|
8823
|
+
|
|
8824
|
+
const shelfDetails = await Promise.all(
|
|
8825
|
+
shelves.map( async ( shelf ) => {
|
|
8826
|
+
const productDetails = await planoMappingService.find( { fixtureId: fixture._id, shelfId: shelf._id, type: 'product' }, { _id: 1 } );
|
|
8827
|
+
let productIdList = productDetails.map( ( ele ) => ele._id );
|
|
8828
|
+
let complianceQuery = [
|
|
8829
|
+
{
|
|
8830
|
+
$match: {
|
|
8831
|
+
fixtureId: fixture._id,
|
|
8832
|
+
shelfId: shelf._id,
|
|
8833
|
+
date: currentDate,
|
|
8834
|
+
planoMappingId: { $in: productIdList },
|
|
8835
|
+
},
|
|
8836
|
+
},
|
|
8837
|
+
{
|
|
8838
|
+
$group: {
|
|
8839
|
+
_id: '$createdAt',
|
|
8840
|
+
status: { $push: '$compliance' },
|
|
8841
|
+
},
|
|
8842
|
+
},
|
|
8843
|
+
{
|
|
8844
|
+
$sort: { _id: -1 },
|
|
8845
|
+
},
|
|
8846
|
+
{
|
|
8847
|
+
$limit: 1,
|
|
8848
|
+
},
|
|
8849
|
+
];
|
|
8850
|
+
let complianceStatus = await planoComplianceService.aggregate( complianceQuery );
|
|
8851
|
+
const compliance = complianceStatus?.[0]?.status?.length ? ( ( complianceStatus?.[0]?.status?.length != shelf.productPerShelf ) || complianceStatus?.[0]?.status.includes( 'misplaced' ) ) ? 'improper' : 'proper' : 'improper';
|
|
8852
|
+
|
|
8853
|
+
const vmCount = await planoMappingService.count( { fixtureId: fixture._id, shelfId: shelf._id, type: 'vm' } );
|
|
8854
|
+
|
|
8855
|
+
return {
|
|
8856
|
+
...shelf.toObject(),
|
|
8857
|
+
productCount: productDetails.length,
|
|
8858
|
+
vmCount: vmCount,
|
|
8859
|
+
compliance,
|
|
8860
|
+
};
|
|
8861
|
+
} ),
|
|
8862
|
+
);
|
|
8863
|
+
|
|
8864
|
+
let fixtureStatus;
|
|
8865
|
+
|
|
8866
|
+
const cvProcessStatus = await planoQrConversionRequestService.count( { fixtureId: fixture._id, date: currentDate, status: 'initiated' } );
|
|
8867
|
+
|
|
8868
|
+
if ( cvProcessStatus ) {
|
|
8869
|
+
fixtureStatus = 'inprogress';
|
|
8870
|
+
} else {
|
|
8871
|
+
const missingCount = await planoComplianceService.count( {
|
|
8872
|
+
fixtureId: fixture._id,
|
|
8873
|
+
compliance: 'missing',
|
|
8874
|
+
date: currentDate,
|
|
8875
|
+
} );
|
|
8876
|
+
fixtureStatus = complianceCount === 0 && !missingCount ? '' : complianceCount === productCount ? 'complete' : 'incomplete';
|
|
8877
|
+
}
|
|
8878
|
+
|
|
8879
|
+
|
|
8880
|
+
const vmDetails = await Promise.all( fixture.toObject()?.vmConfig?.map( async ( vm ) => {
|
|
8881
|
+
totalVmCount += 1;
|
|
8882
|
+
const vmInfo = await planoVmService.findOne( { _id: vm.vmId } );
|
|
8883
|
+
return {
|
|
8884
|
+
...vm,
|
|
8885
|
+
...vmInfo?.toObject(),
|
|
8886
|
+
};
|
|
8887
|
+
} ) );
|
|
8888
|
+
|
|
8889
|
+
return {
|
|
8890
|
+
...fixture.toObject(),
|
|
8891
|
+
status: fixtureStatus,
|
|
8892
|
+
shelfCount: shelves.length,
|
|
8893
|
+
productCount: productCount,
|
|
8894
|
+
vmCount: vmCount,
|
|
8895
|
+
shelfConfig: shelfDetails,
|
|
8896
|
+
vmConfig: vmDetails,
|
|
8897
|
+
};
|
|
8898
|
+
} ),
|
|
8899
|
+
);
|
|
8900
|
+
|
|
8901
|
+
const otherElements = await storeFixtureService.find( {
|
|
8902
|
+
floorId: floor._id,
|
|
8903
|
+
associatedElementType: element.elementType,
|
|
8904
|
+
associatedElementNumber: element.elementNumber,
|
|
8905
|
+
fixtureType: 'other',
|
|
8906
|
+
} );
|
|
8907
|
+
|
|
8908
|
+
return {
|
|
8909
|
+
...element,
|
|
8910
|
+
fixtures: fixturesWithStatus,
|
|
8911
|
+
otherElements: otherElements,
|
|
8912
|
+
};
|
|
8913
|
+
} ),
|
|
8914
|
+
);
|
|
8915
|
+
|
|
8916
|
+
const centerFixtures = await storeFixtureService.findAndSort( {
|
|
8917
|
+
floorId: floor._id,
|
|
8918
|
+
$and: [
|
|
8919
|
+
{ associatedElementType: { $exists: false } },
|
|
8920
|
+
{ associatedElementNumber: { $exists: false } },
|
|
8921
|
+
{ fixtureType: { $ne: 'other' } },
|
|
8922
|
+
],
|
|
8923
|
+
}, { shelfcount: 0 }, { associatedElementFixtureNumber: 1 } );
|
|
8924
|
+
|
|
8925
|
+
|
|
8926
|
+
const centerFixturesWithStatus = await Promise.all(
|
|
8927
|
+
centerFixtures.map( async ( fixture ) => {
|
|
8928
|
+
if ( fixture?.masterTemplateId && mongoose.Types.ObjectId.isValid( fixture?.masterTemplateId ) ) {
|
|
8929
|
+
masterTemplateIds.add( fixture?.masterTemplateId );
|
|
8930
|
+
}
|
|
8931
|
+
if ( fixture?.imageUrl ) {
|
|
8932
|
+
let params = {
|
|
8933
|
+
Bucket: JSON.parse( process.env.BUCKET ).storeBuilder,
|
|
8934
|
+
file_path: fixture.imageUrl,
|
|
8935
|
+
};
|
|
8936
|
+
fixture.imageUrl = await signedUrl( params );
|
|
8937
|
+
} else {
|
|
8938
|
+
fixture.imageUrl = '';
|
|
8939
|
+
}
|
|
8940
|
+
productCapacity += fixture.toObject().fixtureCapacity;
|
|
8941
|
+
fixtureCount += 1;
|
|
8942
|
+
const productCount = await planoMappingService.count( { fixtureId: fixture._id, type: 'product' } );
|
|
8943
|
+
|
|
8944
|
+
const vmCount = await planoMappingService.count( { fixtureId: fixture._id, type: 'vm' } );
|
|
8945
|
+
|
|
8946
|
+
const complianceCount = await planoComplianceService.count( {
|
|
8947
|
+
fixtureId: fixture._id,
|
|
8948
|
+
compliance: 'proper',
|
|
8949
|
+
date: currentDate,
|
|
8950
|
+
} );
|
|
8951
|
+
|
|
8952
|
+
const shelves = await fixtureShelfService.findAndSort( { fixtureId: fixture._id }, { }, { shelfNumber: 1 } );
|
|
8953
|
+
|
|
8954
|
+
const shelfDetails = await Promise.all(
|
|
8955
|
+
shelves.map( async ( shelf ) => {
|
|
8956
|
+
const productDetails = await planoMappingService.find( { fixtureId: fixture._id, shelfId: shelf._id, type: 'product' }, { _id: 1 } );
|
|
8957
|
+
let productIdList = productDetails.map( ( ele ) => ele._id );
|
|
8958
|
+
let complianceQuery = [
|
|
8959
|
+
{
|
|
8960
|
+
$match: {
|
|
8961
|
+
fixtureId: fixture._id,
|
|
8962
|
+
shelfId: shelf._id,
|
|
8963
|
+
date: currentDate,
|
|
8964
|
+
planoMappingId: { $in: productIdList },
|
|
8965
|
+
},
|
|
8966
|
+
},
|
|
8967
|
+
{
|
|
8968
|
+
$group: {
|
|
8969
|
+
_id: '$createdAt',
|
|
8970
|
+
status: { $push: '$compliance' },
|
|
8971
|
+
},
|
|
8972
|
+
},
|
|
8973
|
+
{
|
|
8974
|
+
$sort: { _id: -1 },
|
|
8975
|
+
},
|
|
8976
|
+
{
|
|
8977
|
+
$limit: 1,
|
|
8978
|
+
},
|
|
8979
|
+
];
|
|
8980
|
+
let complianceStatus = await planoComplianceService.aggregate( complianceQuery );
|
|
8981
|
+
const compliance = complianceStatus?.[0]?.status.length ? ( ( complianceStatus?.[0]?.status?.length != shelf.productPerShelf ) || complianceStatus?.[0]?.status?.includes( 'misplaced' ) ) ? 'improper' : 'proper' : 'improper';
|
|
8693
8982
|
|
|
8983
|
+
|
|
8984
|
+
const vmCount = await planoMappingService.count( { fixtureId: fixture._id, shelfId: shelf._id, type: 'vm' } );
|
|
8985
|
+
|
|
8986
|
+
return {
|
|
8987
|
+
...shelf.toObject(),
|
|
8988
|
+
productCount: productDetails.length,
|
|
8989
|
+
vmCount: vmCount,
|
|
8990
|
+
compliance,
|
|
8991
|
+
};
|
|
8992
|
+
} ),
|
|
8993
|
+
);
|
|
8994
|
+
|
|
8995
|
+
let fixtureStatus;
|
|
8996
|
+
|
|
8997
|
+
const cvProcessStatus = await planoQrConversionRequestService.count( { fixtureId: fixture._id, date: currentDate, status: 'initiated' } );
|
|
8998
|
+
|
|
8999
|
+
if ( cvProcessStatus ) {
|
|
9000
|
+
fixtureStatus = 'inprogress';
|
|
9001
|
+
} else {
|
|
9002
|
+
const missingCount = await planoComplianceService.count( {
|
|
9003
|
+
fixtureId: fixture._id,
|
|
9004
|
+
compliance: 'missing',
|
|
9005
|
+
date: currentDate,
|
|
9006
|
+
} );
|
|
9007
|
+
fixtureStatus = complianceCount === 0 && !missingCount ? '' : complianceCount === productCount ? 'complete' : 'incomplete';
|
|
9008
|
+
}
|
|
9009
|
+
|
|
9010
|
+
|
|
9011
|
+
const vmDetails = await Promise.all( fixture.toObject().vmConfig.map( async ( vm ) => {
|
|
9012
|
+
totalVmCount += 1;
|
|
9013
|
+
const vmInfo = await planoVmService.findOne( { _id: vm.vmId } );
|
|
9014
|
+
|
|
9015
|
+
return {
|
|
9016
|
+
...vm,
|
|
9017
|
+
...vmInfo?.toObject(),
|
|
9018
|
+
};
|
|
9019
|
+
} ) );
|
|
9020
|
+
|
|
9021
|
+
return {
|
|
9022
|
+
...fixture.toObject(),
|
|
9023
|
+
status: fixtureStatus,
|
|
9024
|
+
shelfCount: shelves.length,
|
|
9025
|
+
productCount: productCount,
|
|
9026
|
+
vmCount: vmCount,
|
|
9027
|
+
shelfConfig: shelfDetails,
|
|
9028
|
+
vmConfig: vmDetails,
|
|
9029
|
+
};
|
|
9030
|
+
} ),
|
|
9031
|
+
);
|
|
9032
|
+
|
|
9033
|
+
|
|
9034
|
+
const otherElements = await storeFixtureService.find( {
|
|
9035
|
+
floorId: floor._id,
|
|
9036
|
+
associatedElementType: { $exists: false },
|
|
9037
|
+
associatedElementNumber: { $exists: false },
|
|
9038
|
+
fixtureType: 'other',
|
|
9039
|
+
} );
|
|
9040
|
+
|
|
9041
|
+
|
|
9042
|
+
let masterTempArr = [ ...masterTemplateIds ];
|
|
9043
|
+
|
|
9044
|
+
|
|
9045
|
+
if ( masterTempArr?.length && req.body?.treeView ) {
|
|
9046
|
+
masterTempArr = await fixtureConfigService.find( { _id: { $in: [ ...masterTemplateIds ] } } );
|
|
9047
|
+
}
|
|
9048
|
+
|
|
9049
|
+
let floorData = {
|
|
9050
|
+
...floor.toObject(),
|
|
9051
|
+
updatedAt: dayjs( floor?.updatedAt ).format( 'Do MMM YYYY' ),
|
|
9052
|
+
fixtureCount: fixtureCount,
|
|
9053
|
+
vmCount: totalVmCount,
|
|
9054
|
+
layoutPolygon: layoutPolygonWithFixtures,
|
|
9055
|
+
centerFixture: centerFixturesWithStatus,
|
|
9056
|
+
otherElements: otherElements,
|
|
9057
|
+
lastUpdate: dayjs( floor?.updatedAt ).format( 'Do MMMM YYYY hh:mm A' ),
|
|
9058
|
+
...( floors.length > 1 ) ? { floorNum: `Floor ${index + 1}/${floors.length}` } : { floorNum: 'Floor 1' },
|
|
9059
|
+
};
|
|
9060
|
+
|
|
9061
|
+
let planoProductCount = 0;
|
|
9062
|
+
layoutPolygonWithFixtures.forEach( ( poly ) => {
|
|
9063
|
+
poly.fixtures.forEach( ( fixt ) => {
|
|
9064
|
+
planoProductCount += fixt.fixtureCapacity;
|
|
9065
|
+
} );
|
|
9066
|
+
} );
|
|
9067
|
+
|
|
9068
|
+
centerFixturesWithStatus.forEach( ( fixt ) => {
|
|
9069
|
+
planoProductCount += fixt.fixtureCapacity;
|
|
9070
|
+
} );
|
|
9071
|
+
|
|
9072
|
+
floorData = { ...floorData, planoProductCount };
|
|
9073
|
+
|
|
9074
|
+
const data = {
|
|
9075
|
+
storeName: planogram.storeName,
|
|
9076
|
+
storeId: planogram.storeId,
|
|
9077
|
+
clientId: planogram.clientId,
|
|
9078
|
+
planoId: planogram._id,
|
|
9079
|
+
productResolutionLevel: planogram.productResolutionLevel,
|
|
9080
|
+
scanType: planogram.scanType,
|
|
9081
|
+
createdByName: 'Bejan',
|
|
9082
|
+
createdByEmail: 'Bejan@tangotech.co.in',
|
|
9083
|
+
createdBy: new mongoose.Types.ObjectId( '66a78cd82734f4f857cd6db6' ),
|
|
9084
|
+
layoutName: planogram.layoutName,
|
|
9085
|
+
floorId: floorData._id,
|
|
9086
|
+
floorData: floorData,
|
|
9087
|
+
};
|
|
9088
|
+
|
|
9089
|
+
console.log( data, 'data' );
|
|
9090
|
+
|
|
9091
|
+
await planoRevisionService.create( data );
|
|
9092
|
+
} ),
|
|
9093
|
+
);
|
|
9094
|
+
} ),
|
|
9095
|
+
);
|
|
9096
|
+
} catch ( e ) {
|
|
9097
|
+
console.log( e );
|
|
9098
|
+
logger.error( { functionName: 'storeFixturesv2', error: e, message: req.body } );
|
|
9099
|
+
return e;
|
|
9100
|
+
}
|
|
9101
|
+
}
|
|
9102
|
+
|
|
9103
|
+
export async function getStoreFloorsList( req, res ) {
|
|
9104
|
+
try {
|
|
8694
9105
|
const { storeId } = req.query;
|
|
8695
9106
|
|
|
8696
|
-
if (!storeId) {
|
|
8697
|
-
return res.sendError('storeId is required');
|
|
9107
|
+
if ( !storeId ) {
|
|
9108
|
+
return res.sendError( 'storeId is required' );
|
|
8698
9109
|
}
|
|
8699
9110
|
|
|
8700
9111
|
const query = [
|
|
8701
9112
|
{
|
|
8702
9113
|
$match: {
|
|
8703
|
-
storeId: storeId
|
|
8704
|
-
}
|
|
9114
|
+
storeId: storeId,
|
|
9115
|
+
},
|
|
8705
9116
|
},
|
|
8706
9117
|
{
|
|
8707
9118
|
$lookup: {
|
|
8708
|
-
from:
|
|
8709
|
-
let: { planoId:
|
|
9119
|
+
from: 'storelayouts',
|
|
9120
|
+
let: { planoId: '$_id' },
|
|
8710
9121
|
pipeline: [
|
|
8711
9122
|
{
|
|
8712
9123
|
$match: {
|
|
8713
|
-
$expr: { $eq: [
|
|
8714
|
-
}
|
|
9124
|
+
$expr: { $eq: [ '$planoId', '$$planoId' ] },
|
|
9125
|
+
},
|
|
8715
9126
|
},
|
|
8716
9127
|
{
|
|
8717
9128
|
$project: {
|
|
8718
9129
|
_id: 1,
|
|
8719
9130
|
floorNumber: 1,
|
|
8720
|
-
floorName: 1
|
|
8721
|
-
}
|
|
8722
|
-
}
|
|
9131
|
+
floorName: 1,
|
|
9132
|
+
},
|
|
9133
|
+
},
|
|
8723
9134
|
],
|
|
8724
|
-
as:
|
|
8725
|
-
}
|
|
9135
|
+
as: 'floors',
|
|
9136
|
+
},
|
|
8726
9137
|
},
|
|
8727
9138
|
{
|
|
8728
9139
|
$project: {
|
|
8729
9140
|
_id: 0,
|
|
8730
|
-
floors: 1
|
|
8731
|
-
}
|
|
8732
|
-
}
|
|
8733
|
-
]
|
|
8734
|
-
|
|
9141
|
+
floors: 1,
|
|
9142
|
+
},
|
|
9143
|
+
},
|
|
9144
|
+
];
|
|
8735
9145
|
|
|
8736
|
-
const floorsRes = await planoService.aggregate(query);
|
|
8737
9146
|
|
|
8738
|
-
|
|
9147
|
+
const floorsRes = await planoService.aggregate( query );
|
|
8739
9148
|
|
|
8740
|
-
|
|
8741
|
-
|
|
8742
|
-
|
|
9149
|
+
return res.sendSuccess( floorsRes?.[0]?.floors ?? [] );
|
|
9150
|
+
} catch ( e ) {
|
|
9151
|
+
logger.error( { functionName: 'getStoreFloorsList', error: e } );
|
|
9152
|
+
return res.sendError( e, 500 );
|
|
8743
9153
|
}
|
|
8744
9154
|
}
|
|
8745
9155
|
|
|
8746
|
-
export async function getAllStores(req, res) {
|
|
9156
|
+
export async function getAllStores( req, res ) {
|
|
8747
9157
|
try {
|
|
8748
|
-
|
|
8749
9158
|
const { clientId } = req.query;
|
|
8750
9159
|
|
|
8751
|
-
if (!clientId) {
|
|
8752
|
-
return res.sendError('clientId is required', 400);
|
|
9160
|
+
if ( !clientId ) {
|
|
9161
|
+
return res.sendError( 'clientId is required', 400 );
|
|
8753
9162
|
}
|
|
8754
9163
|
|
|
8755
|
-
const storeRes = await storeService.find({ clientId: clientId, status: 'active' }, { storeId: 1, storeName: 1, _id: 0 })
|
|
8756
|
-
|
|
8757
|
-
return res.sendSuccess(storeRes);
|
|
9164
|
+
const storeRes = await storeService.find( { clientId: clientId, status: 'active' }, { storeId: 1, storeName: 1, _id: 0 } );
|
|
8758
9165
|
|
|
8759
|
-
|
|
8760
|
-
|
|
8761
|
-
|
|
9166
|
+
return res.sendSuccess( storeRes );
|
|
9167
|
+
} catch ( e ) {
|
|
9168
|
+
logger.error( { functionName: 'getAllStores', error: e } );
|
|
9169
|
+
return res.sendError( e, 500 );
|
|
8762
9170
|
}
|
|
8763
9171
|
}
|
|
@@ -61,14 +61,15 @@ storeBuilderRouter
|
|
|
61
61
|
.post( '/planoList', isAllowedSessionHandler, getAssinedStore, storeBuilderController.planoList )
|
|
62
62
|
.get( '/taskDetails', isAllowedSessionHandler, storeBuilderController.getTaskDetails )
|
|
63
63
|
.get( '/getPlanoUser', isAllowedSessionHandler, storeBuilderController.getPlanoUser )
|
|
64
|
-
.post( '/planoRolloutList', isAllowedSessionHandler, storeBuilderController.getRolloutDetails )
|
|
64
|
+
.post( '/planoRolloutList', isAllowedSessionHandler, getAssinedStore, storeBuilderController.getRolloutDetails )
|
|
65
65
|
.get( '/getRolloutTaskDetails', isAllowedSessionHandler, storeBuilderController.getRolloutTaskDetails )
|
|
66
66
|
.get( '/getScandid', storeBuilderController.getScandid )
|
|
67
67
|
.get( '/getPlanoStoreList', isAllowedSessionHandler, getAssinedStore, storeBuilderController.getPlanoStoreList )
|
|
68
68
|
.get( '/getFixtureAIDetails', isAllowedSessionHandler, storeBuilderController.getFixtureAIDetails )
|
|
69
69
|
.post( '/updateProductMapping', storeBuilderController.updateProductMapping )
|
|
70
70
|
.post( '/calculateCompliance', isAllowedSessionHandler, storeBuilderController.calculateCompliance )
|
|
71
|
-
.post( '/getPlanogramList', isAllowedSessionHandler, storeBuilderController.getPlanogramList )
|
|
72
|
-
.
|
|
73
|
-
.get('/
|
|
71
|
+
.post( '/getPlanogramList', isAllowedSessionHandler, getAssinedStore, storeBuilderController.getPlanogramList )
|
|
72
|
+
.post( '/revisionUpdate', storeBuilderController.revisionData )
|
|
73
|
+
.get( '/getAllStores', isAllowedSessionHandler, storeBuilderController.getAllStores )
|
|
74
|
+
.get( '/getStoreFloorsList', isAllowedSessionHandler, storeBuilderController.getStoreFloorsList )
|
|
74
75
|
;
|