tango-app-api-infra 3.8.1-beta.13 → 3.8.1-beta.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { download, logger, sendMessageToQueue } from 'tango-app-api-middleware';
|
|
2
|
-
import { bulkUpdate, getOpenSearchCount, getOpenSearchData, insertWithId, updateOpenSearchData } from 'tango-app-api-middleware/src/utils/openSearch.js';
|
|
2
|
+
import { bulkUpdate, getOpenSearchById, getOpenSearchCount, getOpenSearchData, insertWithId, updateOpenSearchData } from 'tango-app-api-middleware/src/utils/openSearch.js';
|
|
3
3
|
import { findOneStore } from '../services/store.service.js';
|
|
4
4
|
import dayjs from 'dayjs';
|
|
5
5
|
|
|
@@ -593,47 +593,94 @@ export async function updateTicketStatus( data, openSearch, temp ) {
|
|
|
593
593
|
const splitId = id.split( '_' );
|
|
594
594
|
const storeId = splitId[0];
|
|
595
595
|
const dateString = splitId[1];
|
|
596
|
-
|
|
596
|
+
const {
|
|
597
|
+
duplicateStatus,
|
|
598
|
+
employeeStatus,
|
|
599
|
+
houseKeepingStatus,
|
|
600
|
+
} = data;
|
|
601
|
+
const statusList = [ duplicateStatus, employeeStatus, houseKeepingStatus ];
|
|
602
|
+
// Filter out undefined/null statuses
|
|
603
|
+
const existingStatuses = statusList.filter( ( status ) => status != null );
|
|
604
|
+
|
|
605
|
+
// Check if **none** of the existing statuses are 'pending'
|
|
606
|
+
const allNotPending = existingStatuses.every( ( status ) => status !== 'pending' );
|
|
607
|
+
|
|
608
|
+
if ( allNotPending && existingStatuses.length > 0 ) {
|
|
597
609
|
data.status = 'closed';
|
|
598
610
|
}
|
|
599
611
|
let tempId = [];
|
|
600
612
|
const { _id, ...updateData } = data;
|
|
601
|
-
await
|
|
613
|
+
const getExistingOne = await getOpenSearchById( openSearch.footfallDirectory, _id );
|
|
614
|
+
const source = getExistingOne?.body?._source;
|
|
602
615
|
let bulkBody = [];
|
|
603
616
|
if ( data?.duplicateImages?.length > 0 ) {
|
|
604
|
-
|
|
617
|
+
updateData.duplicateImages = await mergeDuplicateImagesWithUncheck( getExistingOne?.body?._source?.duplicateImages, data?.duplicateImages, data?.duplicateStatus );
|
|
618
|
+
logger.info( { updateData: updateData, existeg: getExistingOne?.body?._source?.duplicateImages, sttaus: data?.duplicateStatus } );
|
|
619
|
+
await updateOpenSearchData( openSearch.footfallDirectory, _id, { doc: updateData } );
|
|
620
|
+
for ( let duplicate of updateData?.duplicateImages ) {
|
|
605
621
|
bulkBody.push(
|
|
606
622
|
{ update: { _index: openSearch.revop, _id: `${storeId}_${dateString}_${duplicate.timeRange}_${duplicate.tempId}` } },
|
|
607
|
-
{ doc: { duplicateImage: duplicate.
|
|
623
|
+
{ doc: { duplicateImage: duplicate.duplicateImages } },
|
|
608
624
|
);
|
|
609
625
|
duplicate?.data?.map( ( item ) => {
|
|
610
626
|
item.isChecked == true ? tempId.push( item.tempId ) : null;
|
|
611
627
|
bulkBody.push(
|
|
612
628
|
{ update: { _index: openSearch.revop, _id: `${storeId}_${dateString}_${item.timeRange}_${item.tempId}` } },
|
|
613
|
-
{ doc: { isChecked: item.isChecked } },
|
|
629
|
+
{ doc: { isChecked: item.isChecked, status: item?.isChecked == true? 'approved':'rejected' } },
|
|
614
630
|
);
|
|
615
631
|
} );
|
|
616
632
|
}
|
|
633
|
+
logger.info( { tempId: tempId } );
|
|
634
|
+
await updateOpenSearchData( openSearch.footfallDirectory, _id, { doc: { duplicateACCount: tempId?.length || 0 } } );
|
|
617
635
|
}
|
|
618
636
|
if ( data?.employee?.length > 0 ) {
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
637
|
+
const updatedEmployee = updateEmployeeCheckFlags(
|
|
638
|
+
source.employee,
|
|
639
|
+
updateData.employee,
|
|
640
|
+
data.employeeStatus,
|
|
641
|
+
);
|
|
642
|
+
updateData.employee = updatedEmployee;
|
|
643
|
+
await updateOpenSearchData( openSearch.footfallDirectory, _id, { doc: updateData } );
|
|
644
|
+
for ( let employee of updateData?.employee ) {
|
|
645
|
+
( employee.isChecked == true ) ? tempId.push( employee.tempId ) : null;
|
|
646
|
+
bulkBody.push(
|
|
647
|
+
{ update: { _index: openSearch.revop, _id: `${storeId}_${dateString}_${employee.timeRange}_${employee.tempId}` } },
|
|
648
|
+
{ doc: { isChecked: employee.isChecked, status: employee?.isChecked == true? 'approved':'rejected' } },
|
|
649
|
+
);
|
|
625
650
|
}
|
|
651
|
+
await updateOpenSearchData( openSearch.footfallDirectory, _id, { doc: { employeeACCount: tempId?.length || 0 } } );
|
|
626
652
|
}
|
|
627
653
|
if ( data?.houseKeeping?.length > 0 ) {
|
|
628
|
-
|
|
654
|
+
const updatedHouseKeeping = updateEmployeeCheckFlags(
|
|
655
|
+
source?.houseKeeping,
|
|
656
|
+
updateData?.houseKeeping,
|
|
657
|
+
data.houseKeepingStatus,
|
|
658
|
+
);
|
|
659
|
+
updateData.houseKeeping = updatedHouseKeeping;
|
|
660
|
+
|
|
661
|
+
await updateOpenSearchData( openSearch.footfallDirectory, _id, { doc: updateData } );
|
|
662
|
+
|
|
663
|
+
|
|
664
|
+
for ( let houseKeeping of updateData?.houseKeeping ) {
|
|
629
665
|
houseKeeping.isChecked == true ? tempId.push( houseKeeping.tempId ) : null;
|
|
630
666
|
bulkBody.push(
|
|
631
667
|
{ update: { _index: openSearch.revop, _id: `${storeId}_${dateString}_${houseKeeping.timeRange}_${houseKeeping.tempId}` } },
|
|
632
|
-
{ doc: { isChecked: houseKeeping.isChecked } },
|
|
668
|
+
{ doc: { isChecked: houseKeeping.isChecked, status: houseKeeping?.isChecked == true? 'approved':'rejected' } },
|
|
633
669
|
);
|
|
634
670
|
}
|
|
671
|
+
await updateOpenSearchData( openSearch.footfallDirectory, _id, { doc: { houseKeepingACCount: tempId?.length || 0 } } );
|
|
635
672
|
}
|
|
636
673
|
temp.push( storeId );
|
|
674
|
+
if ( bulkBody.length > 0 ) {
|
|
675
|
+
const res = await bulkUpdate( bulkBody );
|
|
676
|
+
if ( res?.errors ) {
|
|
677
|
+
logger.error( 'Bulk update errors:', res.items );
|
|
678
|
+
return { success: false, errors: res.items };
|
|
679
|
+
} else {
|
|
680
|
+
logger.error( 'Bulk status update successful.' );
|
|
681
|
+
return { success: true };
|
|
682
|
+
}
|
|
683
|
+
}
|
|
637
684
|
// if ( inputData.status == 'closed' ) {
|
|
638
685
|
// const isSendMessge = await sendSqsMessage( inputData, tempId );
|
|
639
686
|
// if ( isSendMessge ==true ) {
|
|
@@ -647,6 +694,84 @@ export async function updateTicketStatus( data, openSearch, temp ) {
|
|
|
647
694
|
// }
|
|
648
695
|
}
|
|
649
696
|
|
|
697
|
+
function updateEmployeeCheckFlags( existingEmployees, inputEmployees, status ) {
|
|
698
|
+
// Step 1: Create a Set of tempIds from input (which are all isChecked: true)
|
|
699
|
+
const checkedTempIds = new Set( inputEmployees.map( ( emp ) => emp.tempId ) );
|
|
700
|
+
|
|
701
|
+
// Step 2: Loop through all existing and update isChecked accordingly
|
|
702
|
+
const updatedEmployees = existingEmployees.map( ( emp ) => ( {
|
|
703
|
+
...emp,
|
|
704
|
+
isChecked: status === 'rejected'? !checkedTempIds.has( emp.tempId ):checkedTempIds.has( emp.tempId ),
|
|
705
|
+
} ) );
|
|
706
|
+
|
|
707
|
+
return updatedEmployees;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
|
|
711
|
+
// function mergeDuplicateImagesWithUncheck( existingData, inputData, status ) {
|
|
712
|
+
// const inputImageMap = new Map();
|
|
713
|
+
|
|
714
|
+
// // Step 1: Build a Map of parentTempId -> Set of childTempId from input
|
|
715
|
+
// for ( const parent of inputData ) {
|
|
716
|
+
// inputImageMap.set( parent.tempId, new Set( ( parent.data || [] ).map( ( child ) => child.tempId ) ) );
|
|
717
|
+
// }
|
|
718
|
+
|
|
719
|
+
// // Step 2: Loop through existing data and update isChecked flags
|
|
720
|
+
// return existingData.map( ( existingParent ) => {
|
|
721
|
+
// const parentTempId = existingParent.tempId;
|
|
722
|
+
// const allowedCheckedChildIds = inputImageMap.get( parentTempId ) || new Set();
|
|
723
|
+
|
|
724
|
+
// const updatedData = ( existingParent.data || [] ).map( ( child ) => ( {
|
|
725
|
+
// ...child,
|
|
726
|
+
// isChecked: status === 'rejected'? !allowedCheckedChildIds.has( child.tempId ):allowedCheckedChildIds.has( child.tempId ),
|
|
727
|
+
// } ) );
|
|
728
|
+
// return {
|
|
729
|
+
// ...existingParent,
|
|
730
|
+
// data: updatedData,
|
|
731
|
+
// };
|
|
732
|
+
// } );
|
|
733
|
+
// }
|
|
734
|
+
|
|
735
|
+
function mergeDuplicateImagesWithUncheck( existingData, inputData, status ) {
|
|
736
|
+
const inputImageMap = new Map();
|
|
737
|
+
|
|
738
|
+
// Step 1: Build map of parentTempId -> Set of selected childTempIds
|
|
739
|
+
for ( const parent of inputData ) {
|
|
740
|
+
const selectedChildIds = new Set(
|
|
741
|
+
( parent.data || [] )
|
|
742
|
+
.filter( ( child ) => child.selected )
|
|
743
|
+
.map( ( child ) => child.tempId ),
|
|
744
|
+
);
|
|
745
|
+
inputImageMap.set( parent.tempId, selectedChildIds );
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
// Step 2: Merge isChecked correctly per parent-child match
|
|
749
|
+
return existingData.map( ( existingParent ) => {
|
|
750
|
+
const parentTempId = existingParent.tempId;
|
|
751
|
+
|
|
752
|
+
// Get selected children for this specific parent
|
|
753
|
+
const selectedChildIds = inputImageMap.get( parentTempId ) || new Set();
|
|
754
|
+
|
|
755
|
+
const updatedData = ( existingParent.data || [] ).map( ( child ) => {
|
|
756
|
+
return {
|
|
757
|
+
...child,
|
|
758
|
+
isChecked:
|
|
759
|
+
status === 'approved' ? selectedChildIds.has( child.tempId ) : false,
|
|
760
|
+
};
|
|
761
|
+
} );
|
|
762
|
+
|
|
763
|
+
// Also update the parent isChecked if all children are false
|
|
764
|
+
const anyChildChecked = updatedData.some( ( child ) => child.isChecked );
|
|
765
|
+
|
|
766
|
+
return {
|
|
767
|
+
...existingParent,
|
|
768
|
+
isChecked: anyChildChecked,
|
|
769
|
+
data: updatedData,
|
|
770
|
+
};
|
|
771
|
+
} );
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
|
|
650
775
|
export async function sendSqsMessage( inputData, tempId ) {
|
|
651
776
|
const sqs = JSON.parse( process.env.sqs );
|
|
652
777
|
const sqsProduceQueue = {
|
|
@@ -284,6 +284,7 @@ export const updateStatusSchemea =Joi.object().keys( {
|
|
|
284
284
|
exitTime: Joi.string().required(),
|
|
285
285
|
timeRange: Joi.string().required(),
|
|
286
286
|
isChecked: Joi.boolean().required(),
|
|
287
|
+
selected: Joi.boolean().optional(),
|
|
287
288
|
data: Joi.array().items(
|
|
288
289
|
Joi.object( {
|
|
289
290
|
tempId: Joi.number().required(),
|
|
@@ -292,6 +293,7 @@ export const updateStatusSchemea =Joi.object().keys( {
|
|
|
292
293
|
exitTime: Joi.string().required(),
|
|
293
294
|
timeRange: Joi.string().required(),
|
|
294
295
|
isChecked: Joi.boolean().required(),
|
|
296
|
+
selected: Joi.boolean().optional(),
|
|
295
297
|
} ),
|
|
296
298
|
).optional(),
|
|
297
299
|
} ) ).optional(),
|
|
@@ -302,6 +304,7 @@ export const updateStatusSchemea =Joi.object().keys( {
|
|
|
302
304
|
exitTime: Joi.string().required(),
|
|
303
305
|
timeRange: Joi.string().required(),
|
|
304
306
|
isChecked: Joi.boolean().required(),
|
|
307
|
+
selected: Joi.boolean().optional(),
|
|
305
308
|
|
|
306
309
|
} ) ).optional(),
|
|
307
310
|
employee: Joi.array().items( Joi.object( {
|
|
@@ -311,11 +314,12 @@ export const updateStatusSchemea =Joi.object().keys( {
|
|
|
311
314
|
exitTime: Joi.string().required(),
|
|
312
315
|
timeRange: Joi.string().required(),
|
|
313
316
|
isChecked: Joi.boolean().required(),
|
|
317
|
+
selected: Joi.boolean().optional(),
|
|
314
318
|
|
|
315
319
|
} ) ).optional(),
|
|
316
|
-
duplicateStatus: Joi.string().
|
|
317
|
-
employeeStatus: Joi.string().
|
|
318
|
-
houseKeepingStatus: Joi.string().
|
|
320
|
+
duplicateStatus: Joi.string().optional(),
|
|
321
|
+
employeeStatus: Joi.string().optional(),
|
|
322
|
+
houseKeepingStatus: Joi.string().optional(),
|
|
319
323
|
} ) ).required(),
|
|
320
324
|
|
|
321
325
|
} );
|
|
@@ -12,6 +12,5 @@ footfallDirectoryRouter.get( '/ticket-summary', isAllowedSessionHandler, bulkVal
|
|
|
12
12
|
footfallDirectoryRouter.get( '/ticket-list', isAllowedSessionHandler, bulkValidate( ticketListValid ), ticketList );
|
|
13
13
|
footfallDirectoryRouter.get( '/get-tickets', isAllowedSessionHandler, bulkValidate( getTicketsValid ), getTickets );
|
|
14
14
|
footfallDirectoryRouter.get( '/get-tagged-stores', isAllowedSessionHandler, bulkValidate( getTaggedStoresValid ), getAssinedStore, getClusters, getTaggedStores );
|
|
15
|
-
|
|
16
15
|
footfallDirectoryRouter.put( '/update-status', isAllowedSessionHandler, bulkValidate( updateStatusValid ), updateStatus );
|
|
17
16
|
|