tango-app-api-store-builder 1.0.0-beta-157 → 1.0.0-beta-159
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 +1 -0
- package/src/controllers/managePlano.controller.js +56 -1
- package/src/controllers/planoLibrary.controller.js +3 -20
- package/src/controllers/script.controller.js +8 -8
- package/src/controllers/storeBuilder.controller.js +831 -1
- package/src/controllers/task.controller.js +132 -114
- package/src/dtos/validation.dtos.js +1 -0
- package/src/routes/managePlano.routes.js +2 -1
- package/src/routes/storeBuilder.routes.js +3 -1
package/package.json
CHANGED
|
@@ -178,6 +178,7 @@ export async function duplicateTemplate( req, res ) {
|
|
|
178
178
|
templateDetails = templateDetails.toObject();
|
|
179
179
|
delete templateDetails._id;
|
|
180
180
|
templateDetails.fixtureName = newFixtureName;
|
|
181
|
+
templateDetails.status = 'draft';
|
|
181
182
|
let duplicateDetails = await fixtureConfigService.create( templateDetails );
|
|
182
183
|
return res.sendSuccess( { message: 'Fixture template duplicated successfully', id: duplicateDetails._id } );
|
|
183
184
|
} catch ( e ) {
|
|
@@ -307,7 +307,7 @@ function buildPipelineByType( type, planoId, floorId, filterByStatus, filterByAp
|
|
|
307
307
|
pipeline.push( { $sort: { _id: -1 } } );
|
|
308
308
|
}
|
|
309
309
|
|
|
310
|
-
|
|
310
|
+
console.log( pipeline );
|
|
311
311
|
return pipeline;
|
|
312
312
|
}
|
|
313
313
|
|
|
@@ -890,5 +890,60 @@ export async function getPlanoRevisionById( req, res ) {
|
|
|
890
890
|
res.sendError( 'Failed to fetch plano revision', 500 );
|
|
891
891
|
}
|
|
892
892
|
}
|
|
893
|
+
export async function getRolloutFeedback( req, res ) {
|
|
894
|
+
try {
|
|
895
|
+
const taskTypes = req.body.filterByTask && req.body.filterByTask.length > 0 ? req.body.filterByTask : [ 'merchRollout', 'vmRollout' ];
|
|
896
|
+
const filterByStatus = req.body.filterByStatus || [];
|
|
897
|
+
const filterByApprovalStatus = req.body.filterByApprovalStatus || '';
|
|
898
|
+
const resultMap = {};
|
|
899
|
+
const commentMap = {};
|
|
900
|
+
await Promise.all(
|
|
901
|
+
taskTypes.map( async ( type, index ) => {
|
|
902
|
+
console.log( type );
|
|
903
|
+
const pipeline = buildPipelineByType( type, req.body.planoId, req.body.floorId, filterByStatus, filterByApprovalStatus, req.body.showtask );
|
|
904
|
+
|
|
905
|
+
let data = await planoTaskService.aggregate( pipeline );
|
|
906
|
+
console.log( data );
|
|
907
|
+
if ( filterByApprovalStatus && filterByApprovalStatus !== '' ) {
|
|
908
|
+
console.log( '-------------1', filterByApprovalStatus );
|
|
909
|
+
data.forEach( ( element ) => {
|
|
910
|
+
element.answers?.forEach( ( ans ) => {
|
|
911
|
+
ans.issues = ans.issues?.filter(
|
|
912
|
+
( issue ) => issue.Details && issue.Details.length > 0,
|
|
913
|
+
);
|
|
914
|
+
} );
|
|
915
|
+
element.answers = element.answers?.filter(
|
|
916
|
+
( ans ) => ans.issues && ans.issues.length > 0,
|
|
917
|
+
);
|
|
918
|
+
} );
|
|
919
|
+
data = data.filter(
|
|
920
|
+
( element ) => element.answers && element.answers.length > 0,
|
|
921
|
+
);
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
|
|
925
|
+
resultMap[type] = data;
|
|
926
|
+
|
|
927
|
+
const comments = await planoGlobalCommentService.find( {
|
|
928
|
+
planoId: new mongoose.Types.ObjectId( req.body.planoId ),
|
|
929
|
+
floorId: new mongoose.Types.ObjectId( req.body.floorId ),
|
|
930
|
+
taskType: type,
|
|
931
|
+
} );
|
|
932
|
+
commentMap[type] = comments;
|
|
933
|
+
} ),
|
|
934
|
+
);
|
|
935
|
+
const response = {
|
|
936
|
+
merchRolloutData: resultMap['merchRollout'] || [],
|
|
937
|
+
vmRolloutData: resultMap['vmRollout'] || [],
|
|
938
|
+
merchRolloutComment: commentMap['merchRollout'] || [],
|
|
939
|
+
vmRolloutComment: commentMap['vmRollout'] || [],
|
|
940
|
+
};
|
|
941
|
+
|
|
942
|
+
res.sendSuccess( response );
|
|
943
|
+
} catch ( e ) {
|
|
944
|
+
logger.error( { functionName: 'getRolloutFeedback', error: e } );
|
|
945
|
+
return res.sendError( e, 500 );
|
|
946
|
+
}
|
|
947
|
+
}
|
|
893
948
|
|
|
894
949
|
|
|
@@ -123,24 +123,6 @@ async function getMaxFixtureLibCode() {
|
|
|
123
123
|
export async function createFixture( req, res ) {
|
|
124
124
|
try {
|
|
125
125
|
let FixLibCode = await getMaxFixtureLibCode();
|
|
126
|
-
let query = [
|
|
127
|
-
{
|
|
128
|
-
$addFields: {
|
|
129
|
-
fixtureCategoryLower: { $toLower: '$fixtureCategory' },
|
|
130
|
-
},
|
|
131
|
-
},
|
|
132
|
-
{
|
|
133
|
-
$match: {
|
|
134
|
-
'clientId': req.body.clientId,
|
|
135
|
-
'fixtureCategoryLower': req.body.fixtureCategory.toLowerCase(),
|
|
136
|
-
'fixtureWidth.value': 10,
|
|
137
|
-
},
|
|
138
|
-
},
|
|
139
|
-
];
|
|
140
|
-
let fixLibDetails = await planoLibraryService.aggregate( query );
|
|
141
|
-
if ( fixLibDetails.length ) {
|
|
142
|
-
return res.sendError( `Fixture Name ${req.body.fixtureCategory} already Exists`, 400 );
|
|
143
|
-
}
|
|
144
126
|
let data ={
|
|
145
127
|
clientId: req.body.clientId,
|
|
146
128
|
fixtureCategory: req.body.fixtureCategory,
|
|
@@ -184,7 +166,7 @@ export async function updateFixture( req, res ) {
|
|
|
184
166
|
'clientId': req.body.clientId,
|
|
185
167
|
'fixtureCategoryLower': req.body.fixtureCategory.toLowerCase(),
|
|
186
168
|
'fixtureWidth.value': req.body.fixtureWidth.value,
|
|
187
|
-
'_id': { $ne: req.params.fixtureId },
|
|
169
|
+
'_id': { $ne: new ObjectId( req.params.fixtureId ) },
|
|
188
170
|
},
|
|
189
171
|
},
|
|
190
172
|
];
|
|
@@ -200,7 +182,6 @@ export async function updateFixture( req, res ) {
|
|
|
200
182
|
await planoLibraryService.updateOne( { _id: req.params.fixtureId }, fixtureData );
|
|
201
183
|
return res.sendSuccess( 'Fixture library details updated successfully' );
|
|
202
184
|
} catch ( e ) {
|
|
203
|
-
console.log( e );
|
|
204
185
|
logger.error( { functionName: 'updateFixture', error: e } );
|
|
205
186
|
return res.sendError( e, 500 );
|
|
206
187
|
}
|
|
@@ -541,6 +522,7 @@ export async function duplicateFixture( req, res ) {
|
|
|
541
522
|
fixtureLibDetails.fixtureCategory = newFixName;
|
|
542
523
|
let FixLibCode = await getMaxFixtureLibCode();
|
|
543
524
|
fixtureLibDetails.fixtureLibCode = FixLibCode;
|
|
525
|
+
fixtureLibDetails.status = 'draft';
|
|
544
526
|
let duplicateData = await planoLibraryService.create( fixtureLibDetails );
|
|
545
527
|
return res.sendSuccess( { message: 'Fixture duplicated successfully', id: duplicateData._id } );
|
|
546
528
|
} catch ( e ) {
|
|
@@ -1252,6 +1234,7 @@ export async function duplicateVmLib( req, res ) {
|
|
|
1252
1234
|
}
|
|
1253
1235
|
}
|
|
1254
1236
|
vmDetails.vmName = newVMName;
|
|
1237
|
+
vmDetails.status = 'draft';
|
|
1255
1238
|
vmDetails.vmLibCode = await getMaxVMLibCode();
|
|
1256
1239
|
let duplicateData = await vmService.create( vmDetails );
|
|
1257
1240
|
return res.sendSuccess( { message: 'VM duplicated successfully', id: duplicateData._id } );
|
|
@@ -7400,7 +7400,7 @@ export async function migrateCrestv1( req, res ) {
|
|
|
7400
7400
|
clientId: '11',
|
|
7401
7401
|
$and: [
|
|
7402
7402
|
{ storeName: req.body.storeName },
|
|
7403
|
-
// { storeName: { $in: [ '
|
|
7403
|
+
// { storeName: { $in: ['LKST98', 'LKST682', 'ST185', 'ST36', 'LKST1193'] } },
|
|
7404
7404
|
// { storeName: { $nin: [ 'LKST98', 'LKST1193' ] } },
|
|
7405
7405
|
],
|
|
7406
7406
|
};
|
|
@@ -7430,15 +7430,15 @@ export async function migrateCrestv1( req, res ) {
|
|
|
7430
7430
|
|
|
7431
7431
|
const existingPlanogram = await planoService.findOne( { storeName: storeData.storeName } );
|
|
7432
7432
|
|
|
7433
|
-
|
|
7434
|
-
|
|
7433
|
+
if ( existingPlanogram ) {
|
|
7434
|
+
const checkTaskSubmitted = await planoTaskService.findOne( { planoId: existingPlanogram.toObject()._id } );
|
|
7435
7435
|
|
|
7436
|
-
|
|
7436
|
+
const checkTaskCreated = await processedTaskService.findOne( { storeName: storeData.storeName, date_string: dayjs().format( 'YYYY-MM-DD' ), isPlano: true } );
|
|
7437
7437
|
|
|
7438
|
-
|
|
7439
|
-
|
|
7440
|
-
|
|
7441
|
-
|
|
7438
|
+
if ( checkTaskSubmitted || checkTaskCreated ) {
|
|
7439
|
+
continue;
|
|
7440
|
+
}
|
|
7441
|
+
}
|
|
7442
7442
|
|
|
7443
7443
|
|
|
7444
7444
|
if ( existingPlanogram?.toObject()?._id && mongoose.Types.ObjectId.isValid( existingPlanogram?.toObject()?._id ) ) {
|
|
@@ -1467,7 +1467,7 @@ export async function updateMissing( req, res ) {
|
|
|
1467
1467
|
|
|
1468
1468
|
await Promise.all(
|
|
1469
1469
|
productMappings.map( async ( mapping ) => {
|
|
1470
|
-
const productData = productMap.get( mapping
|
|
1470
|
+
const productData = productMap.get( mapping.productId.toString() );
|
|
1471
1471
|
if ( !productData ) {
|
|
1472
1472
|
return { ...mapping.toObject(), status: '' };
|
|
1473
1473
|
}
|
|
@@ -4507,3 +4507,833 @@ export async function getPlanoUser( req, res ) {
|
|
|
4507
4507
|
return res.sendError( e, 500 );
|
|
4508
4508
|
}
|
|
4509
4509
|
}
|
|
4510
|
+
|
|
4511
|
+
export async function getRolloutDetails( req, res ) {
|
|
4512
|
+
try {
|
|
4513
|
+
let page = req?.body?.offset || 1;
|
|
4514
|
+
let limit = req.body?.limit || 10;
|
|
4515
|
+
let skip = ( page -1 ) * limit;
|
|
4516
|
+
let storeDetails = await storeService.find( { clientId: req.body.clientId, status: 'active' }, { storeId: 1 } );
|
|
4517
|
+
storeDetails = storeDetails.map( ( ele ) => ele.storeId );
|
|
4518
|
+
let query = [
|
|
4519
|
+
{
|
|
4520
|
+
$match: {
|
|
4521
|
+
clientId: req.body.clientId,
|
|
4522
|
+
planoProgress: 100,
|
|
4523
|
+
storeId: { $in: storeDetails },
|
|
4524
|
+
},
|
|
4525
|
+
},
|
|
4526
|
+
{
|
|
4527
|
+
$lookup: {
|
|
4528
|
+
from: 'storefixtures',
|
|
4529
|
+
let: { floor: '$_id' },
|
|
4530
|
+
pipeline: [
|
|
4531
|
+
{
|
|
4532
|
+
$match: {
|
|
4533
|
+
$expr: {
|
|
4534
|
+
$eq: [ '$floorId', '$$floor' ],
|
|
4535
|
+
},
|
|
4536
|
+
},
|
|
4537
|
+
},
|
|
4538
|
+
{
|
|
4539
|
+
$group: {
|
|
4540
|
+
_id: '',
|
|
4541
|
+
fixtureCount: { $sum: 1 },
|
|
4542
|
+
vmCount: { $sum: { $size: '$vmConfig' } },
|
|
4543
|
+
fixtureCapacity: { $sum: '$fixtureCapacity' },
|
|
4544
|
+
},
|
|
4545
|
+
},
|
|
4546
|
+
],
|
|
4547
|
+
as: 'fixtureDetails',
|
|
4548
|
+
},
|
|
4549
|
+
},
|
|
4550
|
+
{ $unwind: { path: '$fixtureDetails', preserveNullAndEmptyArrays: true } },
|
|
4551
|
+
{
|
|
4552
|
+
$project: {
|
|
4553
|
+
_id: 0,
|
|
4554
|
+
planoId: 1,
|
|
4555
|
+
layoutName: 1,
|
|
4556
|
+
floorId: '$_id',
|
|
4557
|
+
floorNumber: 1,
|
|
4558
|
+
floorName: 1,
|
|
4559
|
+
planoProgress: 1,
|
|
4560
|
+
fixtureCount: '$fixtureDetails.fixtureCount',
|
|
4561
|
+
vmCount: '$fixtureDetails.vmCount',
|
|
4562
|
+
fixtureCapacity: '$fixtureDetails.fixtureCapacity',
|
|
4563
|
+
storeId: 1,
|
|
4564
|
+
storeName: 1,
|
|
4565
|
+
lastUpdate: '$updatedAt',
|
|
4566
|
+
},
|
|
4567
|
+
},
|
|
4568
|
+
{
|
|
4569
|
+
$lookup: {
|
|
4570
|
+
from: 'processedtasks',
|
|
4571
|
+
let: { floorId: '$floorId' },
|
|
4572
|
+
pipeline: [
|
|
4573
|
+
{
|
|
4574
|
+
$match: {
|
|
4575
|
+
$expr: {
|
|
4576
|
+
$and: [
|
|
4577
|
+
{ $lte: [ '$date_iso', new Date( dayjs().format( 'YYYY-MM-DD' ) ) ] },
|
|
4578
|
+
{ $eq: [ '$floorId', '$$floorId' ] },
|
|
4579
|
+
{ $eq: [ '$isPlano', true ] },
|
|
4580
|
+
{ $in: [ '$planoType', [ 'merchRollout', 'vmRollout' ] ] },
|
|
4581
|
+
],
|
|
4582
|
+
},
|
|
4583
|
+
},
|
|
4584
|
+
},
|
|
4585
|
+
{
|
|
4586
|
+
$sort: { _id: -1 },
|
|
4587
|
+
},
|
|
4588
|
+
{
|
|
4589
|
+
$group: {
|
|
4590
|
+
_id: '$planoType',
|
|
4591
|
+
type: { $first: '$planoType' },
|
|
4592
|
+
status: { $first: '$checklistStatus' },
|
|
4593
|
+
taskId: { $last: '$_id' },
|
|
4594
|
+
scheduleEndTime_iso: { $last: '$scheduleEndTime_iso' },
|
|
4595
|
+
},
|
|
4596
|
+
},
|
|
4597
|
+
{
|
|
4598
|
+
$project: {
|
|
4599
|
+
_id: 0,
|
|
4600
|
+
type: 1,
|
|
4601
|
+
status: 1,
|
|
4602
|
+
taskId: 1,
|
|
4603
|
+
breach: {
|
|
4604
|
+
$cond: {
|
|
4605
|
+
if: {
|
|
4606
|
+
$gte: [ '$scheduleEndTime_iso', new Date() ],
|
|
4607
|
+
},
|
|
4608
|
+
then: false,
|
|
4609
|
+
else: true,
|
|
4610
|
+
},
|
|
4611
|
+
},
|
|
4612
|
+
},
|
|
4613
|
+
},
|
|
4614
|
+
],
|
|
4615
|
+
as: 'taskDetails',
|
|
4616
|
+
},
|
|
4617
|
+
},
|
|
4618
|
+
{
|
|
4619
|
+
$lookup: {
|
|
4620
|
+
from: 'planotaskcompliances',
|
|
4621
|
+
let: { floorId: '$floorId', taskId: '$taskDetails.taskId' },
|
|
4622
|
+
pipeline: [
|
|
4623
|
+
{
|
|
4624
|
+
$match: {
|
|
4625
|
+
$expr: {
|
|
4626
|
+
$and: [
|
|
4627
|
+
{ $eq: [ '$floorId', '$$floorId' ] },
|
|
4628
|
+
{ $in: [ '$taskId', '$$taskId' ] },
|
|
4629
|
+
{ $in: [ '$type', [ 'merchRollout', 'vmRollout' ] ] },
|
|
4630
|
+
{ $eq: [ '$status', 'incomplete' ] },
|
|
4631
|
+
],
|
|
4632
|
+
},
|
|
4633
|
+
},
|
|
4634
|
+
},
|
|
4635
|
+
{
|
|
4636
|
+
$sort: { _id: -1 },
|
|
4637
|
+
},
|
|
4638
|
+
{
|
|
4639
|
+
$set: {
|
|
4640
|
+
hasPendingIssues: {
|
|
4641
|
+
$anyElementTrue: {
|
|
4642
|
+
$map: {
|
|
4643
|
+
input: {
|
|
4644
|
+
$reduce: {
|
|
4645
|
+
input: '$answers',
|
|
4646
|
+
initialValue: [],
|
|
4647
|
+
in: {
|
|
4648
|
+
$concatArrays: [
|
|
4649
|
+
'$$value',
|
|
4650
|
+
{
|
|
4651
|
+
$reduce: {
|
|
4652
|
+
input: { $ifNull: [ '$$this.issues', [] ] },
|
|
4653
|
+
initialValue: [],
|
|
4654
|
+
in: {
|
|
4655
|
+
$concatArrays: [
|
|
4656
|
+
'$$value',
|
|
4657
|
+
{ $ifNull: [ '$$this.Details', [] ] },
|
|
4658
|
+
],
|
|
4659
|
+
},
|
|
4660
|
+
},
|
|
4661
|
+
},
|
|
4662
|
+
],
|
|
4663
|
+
},
|
|
4664
|
+
},
|
|
4665
|
+
},
|
|
4666
|
+
as: 'detail',
|
|
4667
|
+
in: {
|
|
4668
|
+
$or: [
|
|
4669
|
+
{ $eq: [ '$$detail.status', 'pending' ] },
|
|
4670
|
+
],
|
|
4671
|
+
},
|
|
4672
|
+
},
|
|
4673
|
+
},
|
|
4674
|
+
},
|
|
4675
|
+
hasDisagreeIssues: {
|
|
4676
|
+
$anyElementTrue: {
|
|
4677
|
+
$map: {
|
|
4678
|
+
input: {
|
|
4679
|
+
$reduce: {
|
|
4680
|
+
input: '$answers',
|
|
4681
|
+
initialValue: [],
|
|
4682
|
+
in: {
|
|
4683
|
+
$concatArrays: [
|
|
4684
|
+
'$$value',
|
|
4685
|
+
{
|
|
4686
|
+
$reduce: {
|
|
4687
|
+
input: { $ifNull: [ '$$this.issues', [] ] },
|
|
4688
|
+
initialValue: [],
|
|
4689
|
+
in: {
|
|
4690
|
+
$concatArrays: [
|
|
4691
|
+
'$$value',
|
|
4692
|
+
{ $ifNull: [ '$$this.Details', [] ] },
|
|
4693
|
+
],
|
|
4694
|
+
},
|
|
4695
|
+
},
|
|
4696
|
+
},
|
|
4697
|
+
],
|
|
4698
|
+
},
|
|
4699
|
+
},
|
|
4700
|
+
},
|
|
4701
|
+
as: 'detail',
|
|
4702
|
+
in: {
|
|
4703
|
+
$or: [
|
|
4704
|
+
{ $eq: [ '$$detail.status', 'disagree' ] },
|
|
4705
|
+
],
|
|
4706
|
+
},
|
|
4707
|
+
},
|
|
4708
|
+
},
|
|
4709
|
+
},
|
|
4710
|
+
},
|
|
4711
|
+
},
|
|
4712
|
+
{
|
|
4713
|
+
$group: {
|
|
4714
|
+
_id: '$floorId',
|
|
4715
|
+
merchCount: {
|
|
4716
|
+
$sum: { $cond: [ { $eq: [ '$type', 'merchRollout' ] }, 1, 0 ] },
|
|
4717
|
+
},
|
|
4718
|
+
vmCount: {
|
|
4719
|
+
$sum: { $cond: [ { $eq: [ '$type', 'vmRollout' ] }, 1, 0 ] },
|
|
4720
|
+
},
|
|
4721
|
+
merchPending: {
|
|
4722
|
+
$sum: {
|
|
4723
|
+
$cond: [
|
|
4724
|
+
{ $and: [ { $eq: [ '$type', 'merchRollout' ] }, '$hasPendingIssues' ] },
|
|
4725
|
+
1,
|
|
4726
|
+
0,
|
|
4727
|
+
],
|
|
4728
|
+
},
|
|
4729
|
+
},
|
|
4730
|
+
vmPending: {
|
|
4731
|
+
$sum: {
|
|
4732
|
+
$cond: [
|
|
4733
|
+
{ $and: [ { $eq: [ '$type', 'vmRollout' ] }, '$hasPendingIssues' ] },
|
|
4734
|
+
1,
|
|
4735
|
+
0,
|
|
4736
|
+
],
|
|
4737
|
+
},
|
|
4738
|
+
},
|
|
4739
|
+
merchDisagree: {
|
|
4740
|
+
$sum: {
|
|
4741
|
+
$cond: [
|
|
4742
|
+
{ $and: [ { $eq: [ '$type', 'merchRollout' ] }, '$hasDisagreeIssues' ] },
|
|
4743
|
+
1,
|
|
4744
|
+
0,
|
|
4745
|
+
],
|
|
4746
|
+
},
|
|
4747
|
+
},
|
|
4748
|
+
vmDisagree: {
|
|
4749
|
+
$sum: {
|
|
4750
|
+
$cond: [
|
|
4751
|
+
{ $and: [ { $eq: [ '$type', 'vmRollout' ] }, '$hasDisagreeIssues' ] },
|
|
4752
|
+
1,
|
|
4753
|
+
0,
|
|
4754
|
+
],
|
|
4755
|
+
},
|
|
4756
|
+
},
|
|
4757
|
+
},
|
|
4758
|
+
},
|
|
4759
|
+
{
|
|
4760
|
+
$project: {
|
|
4761
|
+
_id: 0,
|
|
4762
|
+
fixtureStatus: {
|
|
4763
|
+
$switch: {
|
|
4764
|
+
branches: [
|
|
4765
|
+
{
|
|
4766
|
+
case: { $and: [ { $gt: [ '$merchCount', 0 ] }, { $gt: [ '$merchPending', 0 ] } ] },
|
|
4767
|
+
then: 'merchPending',
|
|
4768
|
+
},
|
|
4769
|
+
{
|
|
4770
|
+
case: { $and: [ { $gt: [ '$merchCount', 0 ] }, { $gt: [ '$merchDisagree', 0 ] } ] },
|
|
4771
|
+
then: 'merchDisagree',
|
|
4772
|
+
},
|
|
4773
|
+
],
|
|
4774
|
+
default: '',
|
|
4775
|
+
},
|
|
4776
|
+
},
|
|
4777
|
+
vmStatus: {
|
|
4778
|
+
$switch: {
|
|
4779
|
+
branches: [
|
|
4780
|
+
{
|
|
4781
|
+
case: { $and: [ { $gt: [ '$vmCount', 0 ] }, { $gt: [ '$vmPending', 0 ] } ] },
|
|
4782
|
+
then: 'vmPending',
|
|
4783
|
+
},
|
|
4784
|
+
{
|
|
4785
|
+
case: { $and: [ { $gt: [ '$vmCount', 0 ] }, { $gt: [ '$vmDisagree', 0 ] } ] },
|
|
4786
|
+
then: 'vmDisagree',
|
|
4787
|
+
},
|
|
4788
|
+
],
|
|
4789
|
+
default: '',
|
|
4790
|
+
},
|
|
4791
|
+
},
|
|
4792
|
+
},
|
|
4793
|
+
},
|
|
4794
|
+
],
|
|
4795
|
+
as: 'taskFeedback',
|
|
4796
|
+
},
|
|
4797
|
+
},
|
|
4798
|
+
];
|
|
4799
|
+
|
|
4800
|
+
if ( req.body?.filter?.type == 'rollout' ) {
|
|
4801
|
+
query.push( {
|
|
4802
|
+
$match: {
|
|
4803
|
+
$expr: {
|
|
4804
|
+
$gt: [ { $size: '$taskDetails' }, 0 ],
|
|
4805
|
+
},
|
|
4806
|
+
},
|
|
4807
|
+
} );
|
|
4808
|
+
}
|
|
4809
|
+
if ( [ 'vm', 'merch' ].includes( req.body?.filter?.type ) ) {
|
|
4810
|
+
let andCondition;
|
|
4811
|
+
if ( req.body.filter.type == 'merch' ) {
|
|
4812
|
+
andCondition = [
|
|
4813
|
+
{
|
|
4814
|
+
taskDetails: { $elemMatch: { type: 'merchRollout', status: 'submit' } },
|
|
4815
|
+
},
|
|
4816
|
+
{
|
|
4817
|
+
compliance: { $elemMatch: { feedbackStatus: 'merchPending' } },
|
|
4818
|
+
},
|
|
4819
|
+
];
|
|
4820
|
+
} else {
|
|
4821
|
+
andCondition = [
|
|
4822
|
+
{
|
|
4823
|
+
taskDetails: { $elemMatch: { type: 'vmRollout', status: 'submit' } },
|
|
4824
|
+
},
|
|
4825
|
+
{
|
|
4826
|
+
compliance: { $elemMatch: { feedbackStatus: 'vmPending' } },
|
|
4827
|
+
},
|
|
4828
|
+
];
|
|
4829
|
+
}
|
|
4830
|
+
|
|
4831
|
+
query.push( {
|
|
4832
|
+
$match: {
|
|
4833
|
+
$and: andCondition,
|
|
4834
|
+
},
|
|
4835
|
+
} );
|
|
4836
|
+
}
|
|
4837
|
+
|
|
4838
|
+
if ( req.body.filter?.type == 'flag' ) {
|
|
4839
|
+
query.push( {
|
|
4840
|
+
$match: {
|
|
4841
|
+
$and: [
|
|
4842
|
+
{
|
|
4843
|
+
taskDetails: { $elemMatch: { breach: true } },
|
|
4844
|
+
},
|
|
4845
|
+
],
|
|
4846
|
+
},
|
|
4847
|
+
} );
|
|
4848
|
+
}
|
|
4849
|
+
|
|
4850
|
+
let extraCondition = [];
|
|
4851
|
+
|
|
4852
|
+
if ( req.body.searchValue ) {
|
|
4853
|
+
extraCondition.push( {
|
|
4854
|
+
$match: {
|
|
4855
|
+
storeName: { $regex: req.body.searchValue, $options: 'i' },
|
|
4856
|
+
},
|
|
4857
|
+
} );
|
|
4858
|
+
}
|
|
4859
|
+
|
|
4860
|
+
extraCondition.push(
|
|
4861
|
+
{ $skip: skip },
|
|
4862
|
+
{ $limit: limit },
|
|
4863
|
+
);
|
|
4864
|
+
|
|
4865
|
+
if ( req.body.sortColumnName && req.body.sortBy ) {
|
|
4866
|
+
query.push(
|
|
4867
|
+
{ $sort: { [req.body.sortColumnName]: req.body.sortBy } },
|
|
4868
|
+
);
|
|
4869
|
+
}
|
|
4870
|
+
|
|
4871
|
+
|
|
4872
|
+
query.push( {
|
|
4873
|
+
$facet: {
|
|
4874
|
+
totalStore: [
|
|
4875
|
+
{
|
|
4876
|
+
$group: {
|
|
4877
|
+
_id: '',
|
|
4878
|
+
storeList: { $addToSet: '$storeId' },
|
|
4879
|
+
},
|
|
4880
|
+
},
|
|
4881
|
+
{
|
|
4882
|
+
$project: {
|
|
4883
|
+
_id: 0,
|
|
4884
|
+
count: { $size: '$storeList' },
|
|
4885
|
+
},
|
|
4886
|
+
},
|
|
4887
|
+
],
|
|
4888
|
+
rollOutStore: [
|
|
4889
|
+
{
|
|
4890
|
+
$match: {
|
|
4891
|
+
$expr: { $gt: [ { $size: '$taskDetails' }, 0 ] },
|
|
4892
|
+
},
|
|
4893
|
+
},
|
|
4894
|
+
{ $count: 'count' },
|
|
4895
|
+
],
|
|
4896
|
+
merchPending: [
|
|
4897
|
+
{
|
|
4898
|
+
$match: {
|
|
4899
|
+
$and: [
|
|
4900
|
+
{
|
|
4901
|
+
taskDetails: {
|
|
4902
|
+
$elemMatch: { type: 'merchRollout', status: 'submit' },
|
|
4903
|
+
},
|
|
4904
|
+
},
|
|
4905
|
+
{
|
|
4906
|
+
compliance: {
|
|
4907
|
+
$elemMatch: { feedbackStatus: 'merchPending' },
|
|
4908
|
+
},
|
|
4909
|
+
},
|
|
4910
|
+
],
|
|
4911
|
+
},
|
|
4912
|
+
},
|
|
4913
|
+
{ $count: 'count' },
|
|
4914
|
+
],
|
|
4915
|
+
vmPending: [
|
|
4916
|
+
{
|
|
4917
|
+
$match: {
|
|
4918
|
+
$and: [
|
|
4919
|
+
{
|
|
4920
|
+
taskDetails: {
|
|
4921
|
+
$elemMatch: { type: 'vmRollout', status: 'submit' },
|
|
4922
|
+
},
|
|
4923
|
+
},
|
|
4924
|
+
{
|
|
4925
|
+
compliance: {
|
|
4926
|
+
$elemMatch: { feedbackStatus: 'vmPending' },
|
|
4927
|
+
},
|
|
4928
|
+
},
|
|
4929
|
+
],
|
|
4930
|
+
},
|
|
4931
|
+
},
|
|
4932
|
+
{ $count: 'count' },
|
|
4933
|
+
],
|
|
4934
|
+
flag: [
|
|
4935
|
+
{
|
|
4936
|
+
$match: {
|
|
4937
|
+
taskDetails: {
|
|
4938
|
+
$elemMatch: { breach: true },
|
|
4939
|
+
},
|
|
4940
|
+
},
|
|
4941
|
+
},
|
|
4942
|
+
{ $count: 'count' },
|
|
4943
|
+
],
|
|
4944
|
+
doubleFloorStore: [
|
|
4945
|
+
{
|
|
4946
|
+
$group: {
|
|
4947
|
+
_id: '$storeId',
|
|
4948
|
+
count: { $sum: 1 },
|
|
4949
|
+
},
|
|
4950
|
+
},
|
|
4951
|
+
{
|
|
4952
|
+
$match: {
|
|
4953
|
+
count: { $gt: 1 },
|
|
4954
|
+
},
|
|
4955
|
+
},
|
|
4956
|
+
{
|
|
4957
|
+
$group: {
|
|
4958
|
+
_id: '',
|
|
4959
|
+
doubleFloorList: { $addToSet: '$_id' },
|
|
4960
|
+
},
|
|
4961
|
+
},
|
|
4962
|
+
{
|
|
4963
|
+
$project: {
|
|
4964
|
+
doubleFloorList: 1,
|
|
4965
|
+
},
|
|
4966
|
+
},
|
|
4967
|
+
],
|
|
4968
|
+
data: extraCondition,
|
|
4969
|
+
count: [
|
|
4970
|
+
...extraCondition,
|
|
4971
|
+
{ $count: 'total' },
|
|
4972
|
+
],
|
|
4973
|
+
},
|
|
4974
|
+
} );
|
|
4975
|
+
|
|
4976
|
+
|
|
4977
|
+
let rolloutDetails = await storeBuilderService.aggregate( query );
|
|
4978
|
+
let result = {
|
|
4979
|
+
cardData: {
|
|
4980
|
+
totalStore: rolloutDetails?.[0]?.totalStore?.[0]?.count || 0,
|
|
4981
|
+
rolloutStore: rolloutDetails?.[0]?.rollOutStore?.[0]?.count || 0,
|
|
4982
|
+
merchPendingStore: rolloutDetails?.[0]?.merchPending?.[0]?.count || 0,
|
|
4983
|
+
vmPendingStore: rolloutDetails?.[0]?.vmPending?.[0]?.count || 0,
|
|
4984
|
+
flagStore: rolloutDetails?.[0]?.flag?.[0]?.count || 0,
|
|
4985
|
+
flagStore: rolloutDetails?.[0]?.flag?.[0]?.count || 0,
|
|
4986
|
+
doubleFloorStore: rolloutDetails?.[0]?.doubleFloorStore?.[0]?.doubleFloorList || [],
|
|
4987
|
+
},
|
|
4988
|
+
tableData: {
|
|
4989
|
+
count: rolloutDetails?.[0]?.count?.[0]?.total || 0,
|
|
4990
|
+
data: rolloutDetails?.[0]?.data || 0,
|
|
4991
|
+
},
|
|
4992
|
+
};
|
|
4993
|
+
return res.sendSuccess( result );
|
|
4994
|
+
} catch ( e ) {
|
|
4995
|
+
logger.error( { functionName: 'getRolloutDetails', error: e } );
|
|
4996
|
+
return res.sendError( e, 500 );
|
|
4997
|
+
}
|
|
4998
|
+
}
|
|
4999
|
+
|
|
5000
|
+
export async function getRolloutTaskDetails( req, res ) {
|
|
5001
|
+
try {
|
|
5002
|
+
if ( !req.query.planoId ) {
|
|
5003
|
+
return res.sendError( 'PlanoId is required', 400 );
|
|
5004
|
+
}
|
|
5005
|
+
let query = [
|
|
5006
|
+
{
|
|
5007
|
+
$match: {
|
|
5008
|
+
planoId: new mongoose.Types.ObjectId( req.query.planoId ),
|
|
5009
|
+
isPlano: true,
|
|
5010
|
+
date_iso: { $lte: new Date( dayjs().format( 'YYYY-MM-DD' ) ) },
|
|
5011
|
+
floorId: new mongoose.Types.ObjectId( req.query.floorId ),
|
|
5012
|
+
planoType: { $in: [ 'merchRollout', 'vmRollout' ] },
|
|
5013
|
+
},
|
|
5014
|
+
},
|
|
5015
|
+
{
|
|
5016
|
+
$group: {
|
|
5017
|
+
_id: { type: '$planoType', floorId: '$floorId' },
|
|
5018
|
+
dateString: { $last: '$date_string' },
|
|
5019
|
+
checklistStatus: { $last: '$checklistStatus' },
|
|
5020
|
+
taskId: { $last: '$_id' },
|
|
5021
|
+
redoStatus: { $last: '$redoStatus' },
|
|
5022
|
+
scheduleEndTime_iso: { $last: '$scheduleEndTime_iso' },
|
|
5023
|
+
},
|
|
5024
|
+
},
|
|
5025
|
+
{
|
|
5026
|
+
$group: {
|
|
5027
|
+
_id: null,
|
|
5028
|
+
taskStatus: {
|
|
5029
|
+
$push: {
|
|
5030
|
+
type: '$_id.type',
|
|
5031
|
+
status: '$checklistStatus',
|
|
5032
|
+
date: '$dateString',
|
|
5033
|
+
floorId: '$_id.floorId',
|
|
5034
|
+
redoStatus: '$redoStatus',
|
|
5035
|
+
endTime: '$scheduleEndTime_iso',
|
|
5036
|
+
breach: {
|
|
5037
|
+
$cond: {
|
|
5038
|
+
if: {
|
|
5039
|
+
$gte: [ '$scheduleEndTime_iso', new Date() ],
|
|
5040
|
+
},
|
|
5041
|
+
then: false,
|
|
5042
|
+
else: true,
|
|
5043
|
+
},
|
|
5044
|
+
},
|
|
5045
|
+
},
|
|
5046
|
+
},
|
|
5047
|
+
taskIds: { $push: '$taskId' },
|
|
5048
|
+
},
|
|
5049
|
+
},
|
|
5050
|
+
{
|
|
5051
|
+
$lookup: {
|
|
5052
|
+
from: 'planotaskcompliances',
|
|
5053
|
+
let: {
|
|
5054
|
+
task: '$taskIds',
|
|
5055
|
+
},
|
|
5056
|
+
pipeline: [
|
|
5057
|
+
{
|
|
5058
|
+
$match: {
|
|
5059
|
+
$expr: {
|
|
5060
|
+
$and: [
|
|
5061
|
+
{ $eq: [ '$planoId', new mongoose.Types.ObjectId( req.query.planoId ) ] },
|
|
5062
|
+
{ $in: [ '$taskId', '$$task' ] },
|
|
5063
|
+
{ $eq: [ '$status', 'incomplete' ] },
|
|
5064
|
+
{ $in: [ '$type', [ 'merchRollout', 'vmRollout' ] ] },
|
|
5065
|
+
],
|
|
5066
|
+
},
|
|
5067
|
+
},
|
|
5068
|
+
},
|
|
5069
|
+
{ $sort: { _id: -1 } },
|
|
5070
|
+
{
|
|
5071
|
+
$set: {
|
|
5072
|
+
hasPendingIssues: {
|
|
5073
|
+
$anyElementTrue: {
|
|
5074
|
+
$map: {
|
|
5075
|
+
input: {
|
|
5076
|
+
$reduce: {
|
|
5077
|
+
input: '$answers',
|
|
5078
|
+
initialValue: [],
|
|
5079
|
+
in: {
|
|
5080
|
+
$concatArrays: [
|
|
5081
|
+
'$$value',
|
|
5082
|
+
{
|
|
5083
|
+
$reduce: {
|
|
5084
|
+
input: { $ifNull: [ '$$this.issues', [] ] },
|
|
5085
|
+
initialValue: [],
|
|
5086
|
+
in: {
|
|
5087
|
+
$concatArrays: [
|
|
5088
|
+
'$$value',
|
|
5089
|
+
{ $ifNull: [ '$$this.Details', [] ] },
|
|
5090
|
+
],
|
|
5091
|
+
},
|
|
5092
|
+
},
|
|
5093
|
+
},
|
|
5094
|
+
],
|
|
5095
|
+
},
|
|
5096
|
+
},
|
|
5097
|
+
},
|
|
5098
|
+
as: 'detail',
|
|
5099
|
+
in: {
|
|
5100
|
+
$or: [
|
|
5101
|
+
{ $eq: [ '$$detail.status', 'pending' ] },
|
|
5102
|
+
],
|
|
5103
|
+
},
|
|
5104
|
+
},
|
|
5105
|
+
},
|
|
5106
|
+
},
|
|
5107
|
+
hasDisagreeIssues: {
|
|
5108
|
+
$anyElementTrue: {
|
|
5109
|
+
$map: {
|
|
5110
|
+
input: {
|
|
5111
|
+
$reduce: {
|
|
5112
|
+
input: '$answers',
|
|
5113
|
+
initialValue: [],
|
|
5114
|
+
in: {
|
|
5115
|
+
$concatArrays: [
|
|
5116
|
+
'$$value',
|
|
5117
|
+
{
|
|
5118
|
+
$reduce: {
|
|
5119
|
+
input: { $ifNull: [ '$$this.issues', [] ] },
|
|
5120
|
+
initialValue: [],
|
|
5121
|
+
in: {
|
|
5122
|
+
$concatArrays: [
|
|
5123
|
+
'$$value',
|
|
5124
|
+
{ $ifNull: [ '$$this.Details', [] ] },
|
|
5125
|
+
],
|
|
5126
|
+
},
|
|
5127
|
+
},
|
|
5128
|
+
},
|
|
5129
|
+
],
|
|
5130
|
+
},
|
|
5131
|
+
},
|
|
5132
|
+
},
|
|
5133
|
+
as: 'detail',
|
|
5134
|
+
in: {
|
|
5135
|
+
$or: [
|
|
5136
|
+
{ $eq: [ '$$detail.status', 'disagree' ] },
|
|
5137
|
+
],
|
|
5138
|
+
},
|
|
5139
|
+
},
|
|
5140
|
+
},
|
|
5141
|
+
},
|
|
5142
|
+
},
|
|
5143
|
+
},
|
|
5144
|
+
{
|
|
5145
|
+
$group: {
|
|
5146
|
+
_id: '$floorId',
|
|
5147
|
+
merchCount: {
|
|
5148
|
+
$sum: { $cond: [ { $eq: [ '$type', 'merchRollout' ] }, 1, 0 ] },
|
|
5149
|
+
},
|
|
5150
|
+
vmCount: {
|
|
5151
|
+
$sum: { $cond: [ { $eq: [ '$type', 'vmRollout' ] }, 1, 0 ] },
|
|
5152
|
+
},
|
|
5153
|
+
merchPending: {
|
|
5154
|
+
$sum: {
|
|
5155
|
+
$cond: [
|
|
5156
|
+
{ $and: [ { $eq: [ '$type', 'merchRollout' ] }, '$hasPendingIssues' ] },
|
|
5157
|
+
1,
|
|
5158
|
+
0,
|
|
5159
|
+
],
|
|
5160
|
+
},
|
|
5161
|
+
},
|
|
5162
|
+
vmPending: {
|
|
5163
|
+
$sum: {
|
|
5164
|
+
$cond: [
|
|
5165
|
+
{ $and: [ { $eq: [ '$type', 'vmRollout' ] }, '$hasPendingIssues' ] },
|
|
5166
|
+
1,
|
|
5167
|
+
0,
|
|
5168
|
+
],
|
|
5169
|
+
},
|
|
5170
|
+
},
|
|
5171
|
+
merchDisagree: {
|
|
5172
|
+
$sum: {
|
|
5173
|
+
$cond: [
|
|
5174
|
+
{ $and: [ { $eq: [ '$type', 'merchRollout' ] }, '$hasDisagreeIssues' ] },
|
|
5175
|
+
1,
|
|
5176
|
+
0,
|
|
5177
|
+
],
|
|
5178
|
+
},
|
|
5179
|
+
},
|
|
5180
|
+
vmDisagree: {
|
|
5181
|
+
$sum: {
|
|
5182
|
+
$cond: [
|
|
5183
|
+
{ $and: [ { $eq: [ '$type', 'vmRollout' ] }, '$hasDisagreeIssues' ] },
|
|
5184
|
+
1,
|
|
5185
|
+
0,
|
|
5186
|
+
],
|
|
5187
|
+
},
|
|
5188
|
+
},
|
|
5189
|
+
},
|
|
5190
|
+
},
|
|
5191
|
+
{
|
|
5192
|
+
$project: {
|
|
5193
|
+
_id: 0,
|
|
5194
|
+
merchStatus: {
|
|
5195
|
+
$cond: {
|
|
5196
|
+
if: {
|
|
5197
|
+
$and: [
|
|
5198
|
+
{ $gt: [ '$merchCount', 0 ] },
|
|
5199
|
+
{ $eq: [ '$merchPending', 0 ] },
|
|
5200
|
+
{ $eq: [ '$merchDisagree', 0 ] },
|
|
5201
|
+
],
|
|
5202
|
+
},
|
|
5203
|
+
then: 'complete',
|
|
5204
|
+
else: {
|
|
5205
|
+
$cond: {
|
|
5206
|
+
if: {
|
|
5207
|
+
$and: [
|
|
5208
|
+
{
|
|
5209
|
+
$gt: [ '$merchCount', 0 ],
|
|
5210
|
+
},
|
|
5211
|
+
{
|
|
5212
|
+
$gt: [
|
|
5213
|
+
'$merchPending',
|
|
5214
|
+
0,
|
|
5215
|
+
],
|
|
5216
|
+
},
|
|
5217
|
+
],
|
|
5218
|
+
},
|
|
5219
|
+
then: 'pending',
|
|
5220
|
+
else: {
|
|
5221
|
+
$cond: {
|
|
5222
|
+
if: {
|
|
5223
|
+
$and: [
|
|
5224
|
+
{
|
|
5225
|
+
$gt: [ '$merchCount', 0 ],
|
|
5226
|
+
},
|
|
5227
|
+
{
|
|
5228
|
+
$gt: [
|
|
5229
|
+
'$merchDisagree',
|
|
5230
|
+
0,
|
|
5231
|
+
],
|
|
5232
|
+
},
|
|
5233
|
+
],
|
|
5234
|
+
},
|
|
5235
|
+
then: 'disagree',
|
|
5236
|
+
else: '',
|
|
5237
|
+
},
|
|
5238
|
+
},
|
|
5239
|
+
},
|
|
5240
|
+
},
|
|
5241
|
+
},
|
|
5242
|
+
},
|
|
5243
|
+
vmStatus: {
|
|
5244
|
+
$cond: {
|
|
5245
|
+
if: {
|
|
5246
|
+
$and: [
|
|
5247
|
+
{ $gt: [ '$vmCount', 0 ] },
|
|
5248
|
+
{ $eq: [ '$vmPending', 0 ] },
|
|
5249
|
+
{ $eq: [ '$vmDisagree', 0 ] },
|
|
5250
|
+
],
|
|
5251
|
+
},
|
|
5252
|
+
then: 'complete',
|
|
5253
|
+
else: {
|
|
5254
|
+
$cond: {
|
|
5255
|
+
if: {
|
|
5256
|
+
$and: [
|
|
5257
|
+
{ $gt: [ '$vmCount', 0 ] },
|
|
5258
|
+
{ $gt: [ '$vmPending', 0 ] },
|
|
5259
|
+
],
|
|
5260
|
+
},
|
|
5261
|
+
then: 'pending',
|
|
5262
|
+
else: {
|
|
5263
|
+
$cond: {
|
|
5264
|
+
if: {
|
|
5265
|
+
$and: [
|
|
5266
|
+
{
|
|
5267
|
+
$gt: [ '$vmCount', 0 ],
|
|
5268
|
+
},
|
|
5269
|
+
{
|
|
5270
|
+
$gt: [
|
|
5271
|
+
'$vmDisagree',
|
|
5272
|
+
0,
|
|
5273
|
+
],
|
|
5274
|
+
},
|
|
5275
|
+
],
|
|
5276
|
+
},
|
|
5277
|
+
then: 'disagree',
|
|
5278
|
+
else: '',
|
|
5279
|
+
},
|
|
5280
|
+
},
|
|
5281
|
+
},
|
|
5282
|
+
},
|
|
5283
|
+
},
|
|
5284
|
+
},
|
|
5285
|
+
},
|
|
5286
|
+
},
|
|
5287
|
+
],
|
|
5288
|
+
as: 'taskDetails',
|
|
5289
|
+
},
|
|
5290
|
+
},
|
|
5291
|
+
{
|
|
5292
|
+
$project: {
|
|
5293
|
+
_id: 0,
|
|
5294
|
+
taskStatus: {
|
|
5295
|
+
$map: {
|
|
5296
|
+
input: '$taskStatus',
|
|
5297
|
+
as: 'task',
|
|
5298
|
+
in: {
|
|
5299
|
+
type: '$$task.type',
|
|
5300
|
+
status: '$$task.status',
|
|
5301
|
+
date: '$$task.date',
|
|
5302
|
+
floorId: '$$task.floorId',
|
|
5303
|
+
redoStatus: '$$task.redoStatus',
|
|
5304
|
+
endTime: '$$task.endTime',
|
|
5305
|
+
breach: '$$task.breach',
|
|
5306
|
+
feedbackStatus: {
|
|
5307
|
+
$switch: {
|
|
5308
|
+
branches: [
|
|
5309
|
+
{
|
|
5310
|
+
case: { $eq: [ '$$task.type', 'merchRollout' ] },
|
|
5311
|
+
then: { $arrayElemAt: [ '$taskDetails.merchStatus', 0 ] },
|
|
5312
|
+
},
|
|
5313
|
+
{
|
|
5314
|
+
case: { $eq: [ '$$task.type', 'vmRollout' ] },
|
|
5315
|
+
then: { $arrayElemAt: [ '$taskDetails.vmStatus', 0 ] },
|
|
5316
|
+
},
|
|
5317
|
+
],
|
|
5318
|
+
default: '',
|
|
5319
|
+
},
|
|
5320
|
+
},
|
|
5321
|
+
},
|
|
5322
|
+
},
|
|
5323
|
+
},
|
|
5324
|
+
},
|
|
5325
|
+
},
|
|
5326
|
+
|
|
5327
|
+
];
|
|
5328
|
+
|
|
5329
|
+
let taskInfo = await planotaskService.aggregate( query );
|
|
5330
|
+
const [ merchCount, vmCount ] = await Promise.all( [
|
|
5331
|
+
await layoutService.count( { _id: req.query.floorId, isMerchEdited: true } ),
|
|
5332
|
+
await layoutService.count( { _id: req.query.floorId, isVmEdited: true } ),
|
|
5333
|
+
] );
|
|
5334
|
+
return res.sendSuccess( { taskDetails: taskInfo, merchCount, vmCount } );
|
|
5335
|
+
} catch ( e ) {
|
|
5336
|
+
logger.error( { functionName: 'getTaskDetails', error: e } );
|
|
5337
|
+
return res.sendError( e, 500 );
|
|
5338
|
+
}
|
|
5339
|
+
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import * as taskService from '../service/task.service.js';
|
|
2
1
|
import * as processedService from '../service/processedTaskservice.js';
|
|
3
2
|
import * as storeService from '../service/store.service.js';
|
|
4
3
|
import * as processedChecklistService from '../service/processedchecklist.service.js';
|
|
@@ -11,7 +10,7 @@ import * as checklistService from '../service/checklist.service.js';
|
|
|
11
10
|
import timeZone from 'dayjs/plugin/timezone.js';
|
|
12
11
|
import * as planoProductService from '../service/planoProduct.service.js';
|
|
13
12
|
import mongoose from 'mongoose';
|
|
14
|
-
|
|
13
|
+
const ObjectId = mongoose.Types.ObjectId;
|
|
15
14
|
import * as floorService from '../service/storeBuilder.service.js';
|
|
16
15
|
import * as planoStaticService from '../service/planoStaticData.service.js';
|
|
17
16
|
import * as assignService from '../service/assignService.service.js';
|
|
@@ -128,10 +127,13 @@ export async function createTask( req, res ) {
|
|
|
128
127
|
await processedService.updateOne( { _id: req.body.taskId }, { checklistStatus: 'open', redoStatus: true, date_iso: new Date( dayjs().format( 'YYYY-MM-DD' ) ), scheduleStartTime_iso: dayjs.utc( '12:00 AM', 'hh:mm A' ).format(), scheduleEndTime_iso: dayjs.utc( scheduleEndTime, 'hh:mm A' ).format(), date_string: dayjs().format( 'YYYY-MM-DD' ), date_iso: new Date( dayjs().format( 'YYYY-MM-DD' ) ) } );
|
|
129
128
|
return res.sendSuccess( 'Task redo triggered successfully' );
|
|
130
129
|
} else {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
return res.sendError( 'No data found', 204 );
|
|
130
|
+
if ( !req.body?.checkListName ) {
|
|
131
|
+
return res.sendError( 'ChecklistName is required', 400 );
|
|
134
132
|
}
|
|
133
|
+
// let taskDetails = await taskService.find( { isPlano: true, ...( req.body.checkListName )? { checkListName: req.body.checkListName } : {} } );
|
|
134
|
+
// if ( !taskDetails.length ) {
|
|
135
|
+
// return res.sendError( 'No data found', 204 );
|
|
136
|
+
// }
|
|
135
137
|
let userDetails;
|
|
136
138
|
let storeList;
|
|
137
139
|
let endDate;
|
|
@@ -200,104 +202,113 @@ export async function createTask( req, res ) {
|
|
|
200
202
|
await createUser( userData );
|
|
201
203
|
}
|
|
202
204
|
}
|
|
203
|
-
await Promise.all( taskDetails.map( async ( task ) => {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
205
|
+
// await Promise.all( taskDetails.map( async ( task ) => {
|
|
206
|
+
let taskId = new ObjectId();
|
|
207
|
+
let [ first ] = req.body?.checkListName.split( ' ' );
|
|
208
|
+
first = first.toLowerCase();
|
|
209
|
+
if ( req.body?.checkListName.toLowerCase().includes( 'rollout' ) ) {
|
|
210
|
+
if ( req.body.checkListName.toLowerCase().includes( 'visual' ) ) {
|
|
211
|
+
first = 'vmRollout';
|
|
212
|
+
} else {
|
|
213
|
+
first = 'merchRollout';
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
let data = {
|
|
217
|
+
client_id: req.body.clientId,
|
|
218
|
+
date_iso: new Date( dayjs().format( 'YYYY-MM-DD' ) ),
|
|
219
|
+
date_string: dayjs().format( 'YYYY-MM-DD' ),
|
|
220
|
+
sourceCheckList_id: taskId,
|
|
221
|
+
checkListName: req.body.checkListName,
|
|
222
|
+
checkListId: taskId,
|
|
223
|
+
scheduleStartTime: '12:00 AM',
|
|
224
|
+
scheduleEndTime: scheduleEndTime,
|
|
225
|
+
scheduleStartTime_iso: dayjs.utc( '12:00 AM', 'hh:mm A' ).format(),
|
|
226
|
+
scheduleEndTime_iso: dayjs.utc( endDate, 'YYYY-MM-DD hh:mm A' ).format(),
|
|
227
|
+
allowedOverTime: false,
|
|
228
|
+
allowedStoreLocation: req.body?.geoFencing || false,
|
|
229
|
+
createdBy: req?.user?._id,
|
|
230
|
+
createdByName: req?.user?.userName,
|
|
231
|
+
questionAnswers: [],
|
|
232
|
+
isdeleted: false,
|
|
233
|
+
questionCount: 0,
|
|
234
|
+
storeCount: 0,
|
|
235
|
+
locationCount: 0,
|
|
236
|
+
checkListType: 'task',
|
|
237
|
+
country: '',
|
|
238
|
+
store_id: '',
|
|
239
|
+
storeName: '',
|
|
240
|
+
userId: '',
|
|
241
|
+
userName: '',
|
|
242
|
+
userEmail: '',
|
|
243
|
+
checklistStatus: 'open',
|
|
244
|
+
timeFlagStatus: true,
|
|
245
|
+
timeFlag: 0,
|
|
246
|
+
questionFlag: 0,
|
|
247
|
+
mobileDetectionFlag: 0,
|
|
248
|
+
storeOpenCloseFlag: 0,
|
|
249
|
+
reinitiateStatus: false,
|
|
250
|
+
markasread: false,
|
|
251
|
+
uniformDetectionFlag: 0,
|
|
252
|
+
scheduleRepeatedType: 'daily',
|
|
253
|
+
approvalStatus: false,
|
|
254
|
+
approvalEnable: false,
|
|
255
|
+
redoStatus: false,
|
|
256
|
+
isPlano: true,
|
|
257
|
+
planoType: first,
|
|
258
|
+
};
|
|
259
|
+
let query = [
|
|
260
|
+
{
|
|
261
|
+
$addFields: {
|
|
262
|
+
store: { $toLower: '$storeName' },
|
|
254
263
|
},
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
},
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
$match: {
|
|
267
|
+
clientId: req.body.clientId,
|
|
268
|
+
store: { $in: storeList },
|
|
260
269
|
},
|
|
261
|
-
|
|
270
|
+
},
|
|
271
|
+
];
|
|
262
272
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
},
|
|
273
|
+
let storeDetails = await storeService.aggregate( query );
|
|
274
|
+
await Promise.all( storeDetails.map( async ( store ) => {
|
|
275
|
+
let getUserEmail = req.body.stores.find( ( ele ) => ele.store.toLowerCase() == store.storeName.toLowerCase() );
|
|
276
|
+
let planoDetails = await planoService.findOne( { storeName: store.storeName } );
|
|
277
|
+
if ( planoDetails ) {
|
|
278
|
+
const [ floorDetails, floorCount ] = await Promise.all( [
|
|
279
|
+
await floorService.find( { planoId: planoDetails._id, ...( req.body?.floorId ) ? { _id: req.body?.floorId }:{} }, { _id: 1, floorName: 1 } ),
|
|
280
|
+
await floorService.count( { planoId: planoDetails._id } ),
|
|
281
|
+
] );
|
|
282
|
+
for ( let i=0; i<floorDetails.length; i++ ) {
|
|
283
|
+
if ( getUserEmail ) {
|
|
284
|
+
let query = [
|
|
285
|
+
{
|
|
286
|
+
$addFields: {
|
|
287
|
+
emailLower: { $toLower: '$email' },
|
|
279
288
|
},
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
$match: {
|
|
292
|
+
clientId: req.body.clientId,
|
|
293
|
+
emailLower: getUserEmail.email.toLowerCase(),
|
|
285
294
|
},
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
295
|
+
},
|
|
296
|
+
];
|
|
297
|
+
userDetails = await userService.aggregate( query );
|
|
298
|
+
userDetails = userDetails[0];
|
|
299
|
+
}
|
|
300
|
+
let taskData = { ...data };
|
|
301
|
+
if ( floorCount > 1 ) {
|
|
302
|
+
taskData.checkListName = taskData.checkListName +' - '+ floorDetails[i].floorName;
|
|
303
|
+
}
|
|
304
|
+
taskData.floorId = floorDetails[i]._id;
|
|
305
|
+
taskData.store_id = store.storeId;
|
|
306
|
+
taskData.storeName = store.storeName;
|
|
307
|
+
taskData.userId = userDetails._id;
|
|
308
|
+
taskData.userName = userDetails.userName;
|
|
309
|
+
taskData.userEmail = userDetails.email;
|
|
310
|
+
taskData.planoId = planoDetails?._id;
|
|
311
|
+
if ( !req.body?.checkListName.toLowerCase().includes( 'rollout' ) ) {
|
|
301
312
|
let planoProgress = req.body.checkListName == 'Fixture Verification' ? 50 : req.body.checkListName == 'VM Verification' ? 75 : 25;
|
|
302
313
|
if ( req.body?.checkListName && req.body.checkListName == 'Layout Verification' ) {
|
|
303
314
|
await planoTaskService.deleteMany( { planoId: planoDetails?._id, floorId: taskData?.floorId } );
|
|
@@ -308,19 +319,17 @@ export async function createTask( req, res ) {
|
|
|
308
319
|
await planoTaskService.deleteMany( { planoId: planoDetails?._id, floorId: taskData?.floorId, type: type } );
|
|
309
320
|
}
|
|
310
321
|
await floorService.updateOne( { _id: taskData?.floorId }, { planoProgress } );
|
|
311
|
-
for ( let j=0; j<req.body.days; j++ ) {
|
|
312
|
-
let currDate = dayjs().add( j, 'day' );
|
|
313
|
-
let time = '12:00 AM';
|
|
314
|
-
if ( currDate.format( 'YYYY-MM-DD' ) == dayjs().format( 'YYYY-MM-DD' ) ) {
|
|
315
|
-
time = dayjs().format( 'hh:mm A' );
|
|
316
|
-
}
|
|
317
|
-
let insertData = { ...taskData, date_string: currDate.format( 'YYYY-MM-DD' ), date_iso: new Date( currDate.format( 'YYYY-MM-DD' ) ), scheduleStartTime_iso: dayjs.utc( `${currDate.format( 'YYYY-MM-DD' )} ${time}`, 'YYYY-MM-DD hh:mm A' ).format() };
|
|
318
|
-
await processedService.updateOne( { date_string: currDate.format( 'YYYY-MM-DD' ), store_id: insertData.store_id, userEmail: insertData.userEmail, planoId: insertData.planoId, sourceCheckList_id: task._id, ...( taskData?.floorId ) ? { floorId: taskData.floorId }:{} }, insertData );
|
|
319
|
-
}
|
|
320
322
|
}
|
|
323
|
+
// for ( let j=0; j<req.body.days; j++ ) {
|
|
324
|
+
let currDate = dayjs();
|
|
325
|
+
let time = dayjs().format( 'hh:mm A' );
|
|
326
|
+
let insertData = { ...taskData, date_string: currDate.format( 'YYYY-MM-DD' ), date_iso: new Date( currDate.format( 'YYYY-MM-DD' ) ), scheduleStartTime_iso: dayjs.utc( `${currDate.format( 'YYYY-MM-DD' )} ${time}`, 'YYYY-MM-DD hh:mm A' ).format() };
|
|
327
|
+
await processedService.updateOne( { date_string: currDate.format( 'YYYY-MM-DD' ), store_id: insertData.store_id, userEmail: insertData.userEmail, planoId: insertData.planoId, planoType: taskData.planoType, ...( taskData?.floorId ) ? { floorId: taskData.floorId }:{} }, insertData );
|
|
328
|
+
// }
|
|
321
329
|
}
|
|
322
|
-
}
|
|
330
|
+
}
|
|
323
331
|
} ) );
|
|
332
|
+
// } ) );
|
|
324
333
|
return res.sendSuccess( 'Task created successfully' );
|
|
325
334
|
}
|
|
326
335
|
} catch ( e ) {
|
|
@@ -528,13 +537,13 @@ export async function updateStatus( req, res ) {
|
|
|
528
537
|
email: req.user.email,
|
|
529
538
|
comment: req.body.comments,
|
|
530
539
|
};
|
|
531
|
-
if ( req.body.status == 'inprogress' ) {
|
|
532
|
-
|
|
533
|
-
}
|
|
540
|
+
// if ( req.body.status == 'inprogress' ) {
|
|
541
|
+
// await processedService.updateOne( { planoId: taskDetails.planoId, userEmail: taskDetails.userEmail, store_id: taskDetails.store_id, ...( taskDetails?.floorId ) ? { floorId: taskDetails.floorId } : {}, date_iso: { $gt: new Date( dayjs().format( 'YYYY-MM-DD' ) ) } }, { checklistStatus: 'inprogress', startTime_string: timeString } );
|
|
542
|
+
// }
|
|
534
543
|
await processedService.updateOne( { _id: req.body.taskId }, { checklistStatus: req.body.status, ...( req.body.status == 'inprogress' ) ? { startTime_string: timeString } : { submitTime_string: timeString }, comments: { $push: comments } } );
|
|
535
|
-
if ( req.body.status == 'submit' ) {
|
|
536
|
-
|
|
537
|
-
}
|
|
544
|
+
// if ( req.body.status == 'submit' ) {
|
|
545
|
+
// await processedService.deleteMany( { planoId: taskDetails.planoId, userEmail: taskDetails.userEmail, store_id: taskDetails.store_id, ...( taskDetails?.floorId ) ? { floorId: taskDetails.floorId } : {}, date_iso: { $gt: new Date( dayjs().format( 'YYYY-MM-DD' ) ) } } );
|
|
546
|
+
// }
|
|
538
547
|
let vmTask = await planoTaskService.find(
|
|
539
548
|
{
|
|
540
549
|
planoId: new mongoose.Types.ObjectId( taskDetails.planoId ),
|
|
@@ -1019,3 +1028,12 @@ export async function redoTask( req, res ) {
|
|
|
1019
1028
|
return res.sendError( e, 500 );
|
|
1020
1029
|
}
|
|
1021
1030
|
}
|
|
1031
|
+
|
|
1032
|
+
export async function revokeTask( req, res ) {
|
|
1033
|
+
try {
|
|
1034
|
+
await processedService.deleteMany( { checklistName: req.body.checkListName, date_string: dayjs().format( 'YYYY-MM-DD' ), planoId: req.body.planoId, floorId: req.body.floorId } );
|
|
1035
|
+
} catch ( e ) {
|
|
1036
|
+
logger.error( { functionName: 'revokeTask', error: e } );
|
|
1037
|
+
return res.sendError( e, 500 );
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
@@ -110,6 +110,7 @@ export const updateFixtureSchema = joi.object( {
|
|
|
110
110
|
status: joi.string().required(),
|
|
111
111
|
fixtureCapacity: joi.number().required(),
|
|
112
112
|
isBodyEnabled: joi.boolean().required(),
|
|
113
|
+
clientId: joi.string().required(),
|
|
113
114
|
} );
|
|
114
115
|
|
|
115
116
|
export const fixtureIdSchema = joi.object( {
|
|
@@ -20,4 +20,5 @@ managePlanoRouter
|
|
|
20
20
|
.post( '/getGlobalComment', isAllowedSessionHandler, managePlanoController.getGlobalComment )
|
|
21
21
|
.post( '/createRevision', managePlanoController.createPlanoRevision )
|
|
22
22
|
.post( '/getRevisions', managePlanoController.getAllPlanoRevisions )
|
|
23
|
-
.post( '/getRevisionData', managePlanoController.getPlanoRevisionById )
|
|
23
|
+
.post( '/getRevisionData', managePlanoController.getPlanoRevisionById )
|
|
24
|
+
.post( '/getRolloutFeedback', managePlanoController.getRolloutFeedback );
|
|
@@ -51,4 +51,6 @@ storeBuilderRouter
|
|
|
51
51
|
storeBuilderRouter
|
|
52
52
|
.post( '/planoList', isAllowedSessionHandler, storeBuilderController.planoList )
|
|
53
53
|
.get( '/taskDetails', isAllowedSessionHandler, storeBuilderController.getTaskDetails )
|
|
54
|
-
.get( '/getPlanoUser', isAllowedSessionHandler, storeBuilderController.getPlanoUser )
|
|
54
|
+
.get( '/getPlanoUser', isAllowedSessionHandler, storeBuilderController.getPlanoUser )
|
|
55
|
+
.post( '/planoRolloutList', isAllowedSessionHandler, storeBuilderController.getRolloutDetails )
|
|
56
|
+
.get( '/getRolloutTaskDetails', isAllowedSessionHandler, storeBuilderController.getRolloutTaskDetails );
|