tango-app-api-infra 3.9.5-vms.7 → 3.9.5-vms.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tango-app-api-infra",
3
- "version": "3.9.5-vms.7",
3
+ "version": "3.9.5-vms.9",
4
4
  "description": "infra",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -27,7 +27,7 @@
27
27
  "mongodb": "^6.4.0",
28
28
  "nodemon": "^3.1.0",
29
29
  "swagger-ui-express": "^5.0.0",
30
- "tango-api-schema": "^2.4.20",
30
+ "tango-api-schema": "^2.4.28",
31
31
  "tango-app-api-middleware": "^3.1.93",
32
32
  "winston": "^3.12.0",
33
33
  "winston-daily-rotate-file": "^5.0.0"
@@ -491,671 +491,153 @@ export async function ticketList1( req, res ) {
491
491
 
492
492
  export async function ticketList( req, res ) {
493
493
  try {
494
- let result = '';
494
+ const openSearch = JSON.parse( process.env.OPENSEARCH );
495
495
  const inputData= req.query;
496
496
  const userInfo = req.user;
497
+ const limit =inputData?.limit || 10;
498
+ const offset = inputData.offset == 0 ? 0 : ( inputData.offset - 1 ) * limit || 0;
499
+
497
500
  const ticketsFeature = userInfo?.rolespermission?.some( ( f ) => f.featureName === 'FootfallDirectory' && ( f.modules.find( ( m ) => m.name =='reviewer' && ( m.isAdd==true || m.isEdit==true ) ) ) );
498
501
 
499
- if ( req.user.userType =='tango' ) {
500
- result =inputData.tangotype == 'store'?
502
+ // Get ticket list from the footfallDirectory index in OpenSearch
503
+ // Assumes you have openSearch and getOpenSearchData available in this scope.
504
+ // `openSearch.footfallDirectory` is the index for the tickets.
505
+ // Uses req.query for any filter (add additional filtering logic per your requirements).
501
506
 
507
+ const searchQuery = {
502
508
 
503
- [
504
- {
505
- ticketId: 'TE_FDT_1763539990306',
506
- storeId: '11-1716',
507
- storeName: 'LKST1916',
508
- ticketRaised: '2025-11-16',
509
- issueDate: '2025-11-16',
510
- dueDate: '2025-11-18',
511
- footfall: 1200,
512
- storeRevisedAccuracy: '98%',
513
- reviewerRevisedAccuracy: '97%',
514
- approverRevisedAccuracy: '98%',
515
- tangoRevisedAccuracy: '98%',
516
- status: 'Closed',
517
- },
518
- {
519
- ticketId: 'TE_FDT_1763860421803',
520
- storeId: '11-1716',
521
- storeName: 'LKST1916',
522
- ticketRaised: '2025-11-21',
523
- issueDate: '2025-11-20',
524
- dueDate: '2025-11-26',
525
- footfall: 94,
526
- storeRevisedAccuracy: '90%',
527
- reviewerRevisedAccuracy: '--',
528
- approverRevisedAccuracy: '--',
529
- tangoRevisedAccuracy: '--',
530
- status: 'Open',
531
- },
532
- {
533
- ticketId: 'TE_FDT_1763711403163',
534
- storeId: '11-1716',
535
- storeName: 'LKST1916',
536
- ticketRaised: '2025-11-20',
537
- issueDate: '2025-11-19',
538
- dueDate: 'Due Today',
539
- footfall: 94,
540
- storeRevisedAccuracy: '95%',
541
- reviewerRevisedAccuracy: '--',
542
- approverRevisedAccuracy: '--',
543
- tangoRevisedAccuracy: '--',
544
- status: 'Open',
545
- },
546
- {
547
- ticketId: 'TE_FDT_1763539990309',
548
- storeId: '11-2000',
549
- storeName: 'LKST2368',
550
- ticketRaised: '2025-11-13',
551
- issueDate: '2025-11-13',
552
- dueDate: '2025-11-15',
553
- footfall: 1280,
554
- storeRevisedAccuracy: '98%',
555
- reviewerRevisedAccuracy: '98%',
556
- approverRevisedAccuracy: '97%',
557
- tangoRevisedAccuracy: '97%',
558
- status: 'Closed',
559
- },
560
- {
561
- ticketId: 'TE_FDT_1763539990310',
562
- storeId: '11-2000',
563
- storeName: 'LKST2368',
564
- ticketRaised: '2025-11-14',
565
- issueDate: '2025-11-14',
566
- dueDate: '2025-11-16',
567
- footfall: 1300,
568
- storeRevisedAccuracy: '96%',
569
- reviewerRevisedAccuracy: '95%',
570
- approverRevisedAccuracy: '96%',
571
- tangoRevisedAccuracy: '95%',
572
- status: 'Open',
573
- },
574
- {
575
- ticketId: 'TE_FDT_1763539990311',
576
- storeId: '11-2000',
577
- storeName: 'LKST2368',
578
- ticketRaised: '2025-11-15',
579
- issueDate: '2025-11-15',
580
- dueDate: '2025-11-17',
581
- footfall: 1350,
582
- storeRevisedAccuracy: '99%',
583
- reviewerRevisedAccuracy: '98%',
584
- approverRevisedAccuracy: '98%',
585
- tangoRevisedAccuracy: '99%',
586
- status: 'Closed',
587
- },
588
- {
589
- ticketId: 'TE_FDT_1763539990312',
590
- storeId: '11-2000',
591
- storeName: 'LKST2368',
592
- ticketRaised: '2025-11-16',
593
- issueDate: '2025-11-16',
594
- dueDate: '2025-11-18',
595
- footfall: 1400,
596
- storeRevisedAccuracy: '97%',
597
- reviewerRevisedAccuracy: '96%',
598
- approverRevisedAccuracy: '97%',
599
- tangoRevisedAccuracy: '96%',
600
- status: 'Closed',
601
- },
602
- {
603
- ticketId: 'TE_FDT_1763539990313',
604
- storeId: '11-10',
605
- storeName: 'LKST80',
606
- ticketRaised: '2023-11-14',
607
- issueDate: '2023-11-14',
608
- dueDate: '2023-11-16',
609
- footfall: 900,
610
- storeRevisedAccuracy: '95%',
611
- reviewerRevisedAccuracy: '94%',
612
- approverRevisedAccuracy: '95%',
613
- tangoRevisedAccuracy: '95%',
614
- status: 'Inprogress',
615
- },
616
- {
617
- ticketId: 'TE_FDT_1763539990314',
618
- storeId: '11-10',
619
- storeName: 'LKST80',
620
- ticketRaised: '2023-11-15',
621
- issueDate: '2023-11-15',
622
- dueDate: '2023-11-17',
623
- footfall: 1000,
624
- storeRevisedAccuracy: '98%',
625
- reviewerRevisedAccuracy: '97%',
626
- approverRevisedAccuracy: '97%',
627
- tangoRevisedAccuracy: '98%',
628
- status: 'Closed',
629
- },
630
- {
631
- ticketId: 'TE_FDT_1763539990315',
632
- storeId: '11-10',
633
- storeName: 'LKST80',
634
- ticketRaised: '2023-11-16',
635
- issueDate: '2023-11-16',
636
- dueDate: '2023-11-18',
637
- footfall: 1050,
638
- storeRevisedAccuracy: '96%',
639
- reviewerRevisedAccuracy: '96%',
640
- approverRevisedAccuracy: '96%',
641
- tangoRevisedAccuracy: '97%',
642
- status: 'Open',
643
- },
644
- {
645
- ticketId: 'TE_FDT_1763539990316',
646
- storeId: '11-10',
647
- storeName: 'LKST80',
648
- ticketRaised: '2023-11-17',
649
- issueDate: '2023-11-17',
650
- dueDate: '2023-11-19',
651
- footfall: 1100,
652
- storeRevisedAccuracy: '97%',
653
- reviewerRevisedAccuracy: '97%',
654
- approverRevisedAccuracy: '97%',
655
- tangoRevisedAccuracy: '97%',
656
- status: 'Closed',
657
- },
658
- {
659
- ticketId: 'TE_FDT_1763539990317',
660
- storeId: '12-1111',
661
- storeName: 'LKST3030',
662
- ticketRaised: '2025-10-12',
663
- issueDate: '2025-10-12',
664
- dueDate: '2025-10-14',
665
- footfall: 1200,
666
- storeRevisedAccuracy: '97%',
667
- reviewerRevisedAccuracy: '97%',
668
- approverRevisedAccuracy: '97%',
669
- tangoRevisedAccuracy: '96%',
670
- status: 'Open',
671
- },
672
- {
673
- ticketId: 'TE_FDT_176353999018',
674
- storeId: '12-1111',
675
- storeName: 'LKST3030',
676
- ticketRaised: '2025-10-13',
677
- issueDate: '2025-10-13',
678
- dueDate: '2025-10-15',
679
- footfall: 1095,
680
- storeRevisedAccuracy: '95%',
681
- reviewerRevisedAccuracy: '96%',
682
- approverRevisedAccuracy: '97%',
683
- tangoRevisedAccuracy: '95%',
684
- status: 'Open-Accuracy Issue',
685
- },
686
- {
687
- ticketId: 'TE_FDT_1763539990319',
688
- storeId: '12-1111',
689
- storeName: 'LKST3030',
690
- ticketRaised: '2025-10-14',
691
- issueDate: '2025-10-14',
692
- dueDate: '2025-10-16',
693
- footfall: 987,
694
- storeRevisedAccuracy: '98%',
695
- reviewerRevisedAccuracy: '99%',
696
- approverRevisedAccuracy: '99%',
697
- tangoRevisedAccuracy: '99%',
698
- status: 'closed-Accuracy Issue',
699
- },
700
- {
701
- ticketId: 'TE_FDT_1763539990320',
702
- storeId: '14-8002',
703
- storeName: 'LKST4590',
704
- ticketRaised: '2025-09-12',
705
- issueDate: '2025-09-12',
706
- dueDate: '2025-09-14',
707
- footfall: 1080,
708
- storeRevisedAccuracy: '98%',
709
- reviewerRevisedAccuracy: '97%',
710
- approverRevisedAccuracy: '99%',
711
- tangoRevisedAccuracy: '99%',
712
- status: 'Closed',
509
+ size: limit, // or use parseInt(req.query.limit) for dynamic
510
+ from: offset, // or use parseInt(req.query.offset) for dynamic
511
+ sort: [ { 'createdAt': { order: 'desc' } } ],
512
+ query: {
513
+ bool: {
514
+ must: [],
713
515
  },
516
+ },
517
+ };
714
518
 
715
- ] :
716
- [
519
+ // Example: Filtering by storeId if present in the query
520
+ if ( inputData.storeId ) {
521
+ searchQuery.query.bool.must.push( {
522
+ term: { 'storeId.keyword': inputData.storeId },
523
+ } );
524
+ }
525
+ // Example: Filtering by status if provided
526
+ if ( inputData.status ) {
527
+ searchQuery.query.bool.must.push( {
528
+ term: { 'status.keyword': inputData.status },
529
+ } );
530
+ }
717
531
 
718
- {
719
- ticketId: 'TE_FDT_1763860421803',
720
- storeId: '11-1716',
721
- storeName: 'LKST1916',
722
- ticketRaised: '2025-11-21',
723
- issueDate: '2025-11-20',
724
- footfall: 94,
725
- type: 'store',
726
- storeRevisedAccuracy: '95%',
727
- reviewerRevisedAccuracy: '--',
728
- approverRevisedAccuracy: '--',
729
- tangoRevisedAccuracy: '--',
730
- status: 'Open',
731
- tangoStatus: 'Open',
732
- },
733
- {
734
- ticketId: 'TE_FDT_1763539990307',
735
- storeId: '11-1716',
736
- storeName: 'LKST1916',
737
- ticketRaised: '2025-11-13',
738
- issueDate: '2025-11-13',
739
- footfall: 1150,
740
- type: 'store',
741
- storeRevisedAccuracy: '99%',
742
- reviewerRevisedAccuracy: '99%',
743
- approverRevisedAccuracy: '98%',
744
- tangoRevisedAccuracy: '97%',
745
- status: 'Closed',
746
- tangoStatus: 'open',
747
- },
748
- {
749
- ticketId: 'TE_FDT_1763539990308',
750
- storeId: '11-1716',
751
- storeName: 'LKST1916',
752
- ticketRaised: '2025-11-14',
753
- issueDate: '2025-11-14',
754
- footfall: 1100,
755
- type: 'store',
756
- storeRevisedAccuracy: '97%',
757
- reviewerRevisedAccuracy: '96%',
758
- approverRevisedAccuracy: '97%',
759
- status: 'Closed',
760
- tangoStatus: 'In-Progress',
761
- },
762
- {
763
- ticketId: 'TE_FDT_1763539990309',
764
- storeId: '11-2000',
765
- storeName: 'LKST2368',
766
- ticketRaised: '2025-11-13',
767
- issueDate: '2025-11-13',
768
- footfall: 1280,
769
- type: 'internal',
770
- storeRevisedAccuracy: '98%',
771
- reviewerRevisedAccuracy: '98%',
772
- approverRevisedAccuracy: '97%',
773
- tangoRevisedAccuracy: '97%',
774
- status: 'Closed-Accuracy Issue',
775
- tangoStatus: 'Open',
776
- },
777
- {
778
- ticketId: 'TE_FDT_1763539990310',
779
- storeId: '11-2000',
780
- storeName: 'LKST2368',
781
- ticketRaised: '2025-11-14',
782
- issueDate: '2025-11-14',
783
- footfall: 300,
784
- type: 'store',
785
- storeRevisedAccuracy: '96%',
786
- reviewerRevisedAccuracy: '95%',
787
- approverRevisedAccuracy: '96%',
788
- tangoRevisedAccuracy: '95%',
789
- status: 'Closed',
790
- tangoStatus: 'In-Progress',
791
- },
792
- {
793
- ticketId: 'TE_FDT_1763539990311',
794
- storeId: '11-2000',
795
- storeName: 'LKST2368',
796
- ticketRaised: '2025-11-15',
797
- issueDate: '2025-11-15',
798
- footfall: 350,
799
- type: 'internal',
800
- storeRevisedAccuracy: '99%',
801
- reviewerRevisedAccuracy: '98%',
802
- approverRevisedAccuracy: '98%',
803
- tangoRevisedAccuracy: '99%',
804
- status: 'Closed',
805
- tangoStatus: 'In-Progress',
806
- },
807
- {
808
- ticketId: 'TE_FDT_1763539990312',
809
- storeId: '11-2000',
810
- storeName: 'LKST2368',
811
- ticketRaised: '2025-11-16',
812
- issueDate: '2025-11-16',
813
- footfall: 400,
814
- type: 'internal',
815
- storeRevisedAccuracy: '97%',
816
- reviewerRevisedAccuracy: '96%',
817
- approverRevisedAccuracy: '97%',
818
- tangoRevisedAccuracy: '96%',
819
- status: 'Open-Accuracy Issue',
820
- tangoStatus: 'Open',
821
- },
822
- {
823
- ticketId: 'TE_FDT_1763539990313',
824
- storeId: '11-10',
825
- storeName: 'LKST80',
826
- ticketRaised: '2023-11-14',
827
- issueDate: '2023-11-14',
828
- footfall: 900,
829
- type: 'internal',
830
- storeRevisedAccuracy: '95%',
831
- reviewerRevisedAccuracy: '94%',
832
- approverRevisedAccuracy: '95%',
833
- tangoRevisedAccuracy: '95%',
834
- status: 'Closed',
835
- tangoStatus: 'Closed',
836
- },
837
- {
838
- ticketId: 'TE_FDT_1763539990314',
839
- storeId: '11-10',
840
- storeName: 'LKST80',
841
- ticketRaised: '2023-11-15',
842
- issueDate: '2023-11-15',
843
- type: 'store',
844
- footfall: 100,
845
- storeRevisedAccuracy: '98%',
846
- reviewerRevisedAccuracy: '97%',
847
- approverRevisedAccuracy: '97%',
848
- tangoRevisedAccuracy: '98%',
849
- status: 'closed-Accuracy Issue',
850
- tangoStatus: 'Closed',
851
- },
852
- {
853
- ticketId: 'TE_FDT_1763539990320',
854
- storeId: '14-8002',
855
- storeName: 'LKST4590',
856
- ticketRaised: '2025-09-12',
857
- issueDate: '2025-09-12',
858
- type: 'internal',
859
- footfall: 80,
860
- storeRevisedAccuracy: '98%',
861
- reviewerRevisedAccuracy: '97%',
862
- approverRevisedAccuracy: '99%',
863
- tangoRevisedAccuracy: '99%',
864
- status: 'Closed-Accuracy Issue',
865
- tangoStatus: 'Closed',
866
- },
867
- ];
532
+ // You can add more filters as needed
533
+ logger.info( { searchQuery, index: openSearch.footfallDirectory } );
534
+ const searchResult = await getOpenSearchData( openSearch.footfallDirectory, searchQuery );
535
+
536
+
537
+ const count = searchResult?.body?.hits?.total?.value || 0;
538
+ if ( count === 0 ) {
539
+ return res.sendError( 'no data found', 204 );
540
+ }
541
+ const ticketListData = searchResult?.body?.hits?.hits?.map( ( hit ) => hit._source ) || [];
542
+
543
+ let temp =[];
544
+ if ( req.user.userType =='tango' ) {
545
+ if ( inputData.tangotype == 'store' ) {
546
+ for ( let item of ticketListData ) {
547
+ temp.push( {
548
+
549
+ ticketId: item?.ticketId,
550
+ storeId: item?.storeId,
551
+ storeName: item?.storeName,
552
+
553
+ ticketRaised: item?.mappingInfo?.find( ( f ) => f.type === 'tagging' )?.createdAt,
554
+ issueDate: item?.dateString,
555
+ dueDate: '',
556
+ footfall: item?.footfall,
557
+ storeRevisedAccuracy: item?.mappingInfo?.find( ( f ) => f.type === 'tagging' )?.revicedPerc || '--',
558
+ reviewerRevisedAccuracy: item?.mappingInfo?.find( ( f ) => f.type === 'review' )?.revicedPerc|| '--',
559
+ approverRevisedAccuracy: item?.mappingInfo?.find( ( f ) => f.type === 'approve' )?.revicedPerc||'--',
560
+ tangoRevisedAccuracy: item?.mappingInfo?.find( ( f ) => f.type === 'tangoreview' )?.revicedPerc || '--',
561
+ status: item?.status,
562
+
563
+ } );
564
+ }
565
+ } else {
566
+ for ( let item of ticketListData ) {
567
+ temp.push( {
568
+
569
+ ticketId: item?.ticketId,
570
+ storeId: item?.storeId,
571
+ storeName: item?.storeName,
572
+
573
+ ticketRaised: item?.mappingInfo?.find( ( f ) => f.type === 'tagging' )?.createdAt,
574
+ issueDate: item?.dateString,
575
+ footfall: item?.footfall,
576
+ dueDate: '',
577
+ type: item.type || 'store',
578
+ storeRevisedAccuracy: item?.mappingInfo?.find( ( f ) => f.type === 'tagging' )?.revicedPerc || '--',
579
+ reviewerRevisedAccuracy: item?.mappingInfo?.find( ( f ) => f.type === 'review' )?.revicedPerc|| '--',
580
+ approverRevisedAccuracy: item?.mappingInfo?.find( ( f ) => f.type === 'approve' )?.revicedPerc||'--',
581
+ tangoRevisedAccuracy: item?.mappingInfo?.find( ( f ) => f.type === 'tangoreview' )?.revicedPerc || '--',
582
+ status: item?.status,
583
+ tangoStatus: item?.mappingInfo?.find( ( f ) => f.type === 'tangoreview' )?.revicedPerc || '--',
584
+
585
+ } );
586
+ }
587
+ }
868
588
  } else {
869
- result = req.user.role === 'superadmin'?
870
- [
871
- {
872
- ticketId: 'TE_FDT_1763539990320',
873
- storeId: '11-1716',
874
- storeName: 'LKST1916',
875
- ticketRaised: '2025-11-13',
876
- issueDate: '2025-11-12',
877
- dueDate: '2025-11-14',
878
- footfall: 60,
879
- storeRevisedAccuracy: '45%',
880
- reviewerRevisedAccuracy: '67%',
881
- approverRevisedAccuracy: '87%',
882
- tangoRevisedAccuracy: '93%',
883
- status: 'Open',
884
- approvedBy: '',
885
- },
886
- {
887
- ticketId: 'TE_FDT_1763539990321',
888
- storeId: '11-1716',
889
- storeName: 'LKST1916',
890
- ticketRaised: '2025-11-11',
891
- issueDate: '2025-11-10',
892
- dueDate: '2025-11-12',
893
- footfall: 69,
894
- storeRevisedAccuracy: '79%',
895
- reviewerRevisedAccuracy: '80%',
896
- approverRevisedAccuracy: '90%',
897
- tangoRevisedAccuracy: '90%',
898
- status: 'In-Progress',
899
- approvedBy: 'mu_mu@yopmail.com',
900
- },
901
- {
902
- ticketId: 'TE_FDT_1763860421803',
903
- storeId: '11-1716',
904
- storeName: 'LKST1916',
905
- ticketRaised: '2025-11-21',
906
- issueDate: '2025-11-20',
907
- dueDate: '2025-11-26',
908
- footfall: 94,
909
- storeRevisedAccuracy: '90%',
910
- reviewerRevisedAccuracy: '90%',
911
- approverRevisedAccuracy: '90%',
912
- tangoRevisedAccuracy: '90%',
913
- status: 'Closed',
914
- approvedBy: 'mu_mu@yopmail.com',
915
- },
916
- {
917
- ticketId: 'TE_FDT_1763711403163',
918
- storeId: '11-1716',
919
- storeName: 'LKST1916',
920
- ticketRaised: '2025-11-20',
921
- issueDate: '2025-11-19',
922
- dueDate: 'Due Today',
923
- footfall: 94,
924
- storeRevisedAccuracy: '95%',
925
- reviewerRevisedAccuracy: '--',
926
- approverRevisedAccuracy: '--',
927
- tangoRevisedAccuracy: '--',
928
- status: 'In-Progress',
929
- approvedBy: 'mu_mu@yopmail.com',
930
- },
931
- {
932
- ticketId: 'TE_FDT_1763539990320',
933
- storeId: '11-1716',
934
- storeName: 'LKST1916',
935
- ticketRaised: '2025-11-15',
936
- issueDate: '2025-11-14',
937
- dueDate: '2025-11-17',
938
- footfall: 110,
939
- storeRevisedAccuracy: '90%',
940
- reviewerRevisedAccuracy: '--',
941
- approverRevisedAccuracy: '--',
942
- tangoRevisedAccuracy: '--',
943
- status: 'Open',
944
- approvedBy: '',
945
- },
946
- {
947
- ticketId: 'TE_FDT_1763539990323',
948
- storeId: '11-10',
949
- storeName: 'LKST80',
950
- ticketRaised: '2025-11-13',
951
- issueDate: '2025-11-12',
952
- dueDate: '2025-11-14',
953
- footfall: 170,
954
- storeRevisedAccuracy: '90%',
955
- reviewerRevisedAccuracy: '90%',
956
- approverRevisedAccuracy: '--',
957
- tangoRevisedAccuracy: '--',
958
- status: 'Open',
959
- approvedBy: '',
960
- },
961
- {
962
- ticketId: 'TE_FDT_1763539990328',
963
- storeId: '11-10',
964
- storeName: 'LKST80',
965
- ticketRaised: '2025-11-12',
966
- issueDate: '2025-11-11',
967
- dueDate: '2025-11-14',
968
- footfall: 170,
969
- storeRevisedAccuracy: '90%',
970
- reviewerRevisedAccuracy: '90%',
971
- approverRevisedAccuracy: '90%',
972
- tangoRevisedAccuracy: '--',
973
- status: 'Expired',
974
- approvedBy: 'mu_mu@yopmail.com',
975
- },
976
- {
977
- ticketId: 'TE_FDT_1763539990330',
978
- storeId: '11-10',
979
- storeName: 'LKST80',
980
- ticketRaised: '2025-11-18',
981
- issueDate: '2025-11-15',
982
- dueDate: 'Due Today',
983
- footfall: 230,
984
- storeRevisedAccuracy: '90%',
985
- reviewerRevisedAccuracy: '90%',
986
- approverRevisedAccuracy: '90%',
987
- tangoRevisedAccuracy: '90%',
988
- status: 'Closed',
989
- approvedBy: 'mu_mu@yopmail.com',
990
- },
991
- {
992
- ticketId: 'TE_FDT_1763539990332',
993
- storeId: '11-10',
994
- storeName: 'LKST80',
995
- ticketRaised: '2025-11-17',
996
- issueDate: '2025-11-16',
997
- dueDate: '2025-11-20',
998
- footfall: 812,
999
- storeRevisedAccuracy: '80%',
1000
- reviewerRevisedAccuracy: '80%',
1001
- approverRevisedAccuracy: '80%',
1002
- tangoRevisedAccuracy: '--',
1003
- status: 'Open',
1004
- approvedBy: 'mu_mu@yopmail.com',
1005
- },
1006
- {
1007
- ticketId: 'TE_FDT_176353999034',
1008
- storeId: '11-2000',
1009
- storeName: 'LKST2368',
1010
- ticketRaised: '2025-11-15',
1011
- issueDate: '2025-11-14',
1012
- dueDate: '2025-11-19',
1013
- footfall: '',
1014
- storeRevisedAccuracy: '--',
1015
- reviewerRevisedAccuracy: '--',
1016
- approverRevisedAccuracy: '--',
1017
- tangoRevisedAccuracy: '--',
1018
- status: 'Open',
1019
- approvedBy: '',
1020
- },
1021
- ] :
1022
- req.user.role === 'user'? 'NA':
1023
- ticketsFeature?
1024
- [
1025
- {
1026
- ticketId: 'TE_FDT_1763860421803',
1027
- storeId: '11-1716',
1028
- storeName: 'LKST1916',
1029
- ticketRaised: '2025-11-21',
1030
- issueDate: '2025-11-20',
1031
- dueDate: 'Due Today',
1032
- footfall: 90,
1033
- storeRevisedAccuracy: '90%',
1034
- reviewerRevisedAccuracy: '0%',
1035
- status: 'Open',
1036
- ReviewedBy: '',
1037
- },
1038
- {
1039
- ticketId: 'TE_FDT_1763539990346',
1040
- storeId: '11-2000',
1041
- storeName: 'LKST2368',
1042
- ticketRaised: '2025-11-21',
1043
- issueDate: '2025-11-20',
1044
- dueDate: '2025-11-26',
1045
- footfall: 90,
1046
- storeRevisedAccuracy: '90%',
1047
- reviewerRevisedAccuracy: '--',
1048
- status: 'In-Progress',
1049
- ReviewedBy: 'mu_mu@yopmail.com',
1050
- },
1051
- {
1052
- ticketId: 'TE_FDT_176353999048',
1053
- storeId: '11-2000',
1054
- storeName: 'LKST2368',
1055
- ticketRaised: '2025-11-16',
1056
- issueDate: '2025-11-15',
1057
- dueDate: '2025-11-19',
1058
- footfall: 100,
1059
- storeRevisedAccuracy: '90%',
1060
- reviewerRevisedAccuracy: '90%',
1061
- status: 'Closed',
1062
- ReviewedBy: 'ayyanar@yopmail.com',
1063
- },
1064
- {
1065
- ticketId: 'TE_FDT_176353999048',
1066
- storeId: '11-10',
1067
- storeName: 'LKST80',
1068
- ticketRaised: '2025-11-08',
1069
- issueDate: '2025-11-06',
1070
- dueDate: '2025-11-09',
1071
- footfall: 120,
1072
- storeRevisedAccuracy: '90%',
1073
- reviewerRevisedAccuracy: '0%',
1074
- status: 'Expired',
1075
- ReviewedBy: '',
1076
- },
1077
- {
1078
- ticketId: 'TE_FDT_1763539990341',
1079
- storeId: '11-2000',
1080
- storeName: 'LKST2368',
1081
- ticketRaised: '2025-11-6',
1082
- issueDate: '2025-11-15',
1083
- dueDate: 'Due Today',
1084
- footfall: 510,
1085
- storeRevisedAccuracy: '90%',
1086
- reviewerRevisedAccuracy: '--',
1087
- status: 'Open',
1088
- ReviewedBy: '',
1089
- },
1090
- {
1091
- ticketId: 'TE_FDT_1763539990340',
1092
- storeId: '11-10',
1093
- storeName: 'LKST80',
1094
- ticketRaised: '2025-11-14',
1095
- issueDate: '2025-11-12',
1096
- dueDate: '2025-11-15',
1097
- footfall: 100,
1098
- storeRevisedAccuracy: '0%',
1099
- reviewerRevisedAccuracy: '0%',
1100
- status: 'Expired',
1101
- ReviewedBy: '',
1102
- },
1103
- {
1104
- ticketId: 'TE_FDT_1763539990339',
1105
- storeId: '11-2000',
1106
- storeName: 'LKST2368',
1107
- ticketRaised: '2025-11-16',
1108
- issueDate: '2025-11-15',
1109
- dueDate: '2025-11-17',
1110
- footfall: 140,
1111
- storeRevisedAccuracy: '90%',
1112
- reviewerRevisedAccuracy: '90%',
1113
- status: 'Closed',
1114
- ReviewedBy: 'sornanithya@yopmail.com',
1115
- },
1116
- {
1117
- ticketId: 'TE_FDT_1763539990337',
1118
- storeId: '11-10',
1119
- storeName: 'LKST80',
1120
- ticketRaised: '2025-11-16',
1121
- issueDate: '2025-11-15',
1122
- dueDate: '2025-11-18',
1123
- footfall: '',
1124
- storeRevisedAccuracy: '90%',
1125
- reviewerRevisedAccuracy: '--',
1126
- status: 'Expired',
1127
- ReviewedBy: '',
1128
- },
1129
- {
1130
- ticketId: 'TE_FDT_1763539990338',
1131
- storeId: '11-2000',
1132
- storeName: 'LKST2368',
1133
- ticketRaised: '2025-11-17',
1134
- issueDate: '2025-11-16',
1135
- dueDate: 'Due today',
1136
- footfall: 110,
1137
- storeRevisedAccuracy: '90%',
1138
- reviewerRevisedAccuracy: '--',
1139
- status: 'In-Progress',
1140
- ReviewedBy: 'vinoth@yopmail.com',
1141
- },
1142
- {
1143
- ticketId: 'TE_FDT_1763539990335',
1144
- storeId: '11-2000',
1145
- storeName: 'LKST2368',
1146
- ticketRaised: '2025-11-17',
1147
- issueDate: '2025-11-16',
1148
- dueDate: 'Due today',
1149
- footfall: 100,
1150
- storeRevisedAccuracy: '90%',
1151
- reviewerRevisedAccuracy: '0%',
1152
- status: 'In-Progress',
1153
- ReviewedBy: 'sornanithya@yopmail.com',
1154
- },
1155
- ]: 'NA';
589
+ if ( req.user.role === 'superadmin' ) {
590
+ for ( let item of ticketListData ) {
591
+ temp.push( {
592
+
593
+ ticketId: item?.ticketId,
594
+ storeId: item?.storeId,
595
+ storeName: item?.storeName,
596
+
597
+ ticketRaised: item?.mappingInfo?.find( ( f ) => f.type === 'tagging' )?.createdAt,
598
+ issueDate: item?.dateString,
599
+ dueDate: '',
600
+ footfall: item?.footfall,
601
+
602
+ type: item.type || 'store',
603
+ storeRevisedAccuracy: item?.mappingInfo?.find( ( f ) => f.type === 'tagging' )?.revicedPerc || '--',
604
+ reviewerRevisedAccuracy: item?.mappingInfo?.find( ( f ) => f.type === 'review' )?.revicedPerc|| '--',
605
+ approverRevisedAccuracy: item?.mappingInfo?.find( ( f ) => f.type === 'approve' )?.revicedPerc||'--',
606
+ tangoRevisedAccuracy: item?.mappingInfo?.find( ( f ) => f.type === 'tangoreview' )?.revicedPerc || '--',
607
+ status: item?.status,
608
+ tangoStatus: item?.mappingInfo?.find( ( f ) => f.type === 'tangoreview' )?.revicedPerc || '--',
609
+ approvedBy: item?.mappingInfo?.find( ( f ) => f.type === 'approve' )?.createdByEmail||'--',
610
+
611
+ } );
612
+ }
613
+ } else if ( req.user.role === 'user' ) {
614
+ temp = [];
615
+ } else if ( ticketsFeature ) {
616
+ for ( let item of ticketListData ) {
617
+ temp.push( {
618
+
619
+ ticketId: item?.ticketId,
620
+ storeId: item?.storeId,
621
+ storeName: item?.storeName,
622
+ ticketRaised: item?.mappingInfo?.find( ( f ) => f.type === 'tagging' )?.createdAt,
623
+ issueDate: item?.dateString,
624
+ footfall: item?.footfall,
625
+ dueDate: '',
626
+ type: item.type || 'store',
627
+ storeRevisedAccuracy: item?.mappingInfo?.find( ( f ) => f.type === 'tagging' )?.revicedPerc || '--',
628
+ reviewerRevisedAccuracy: item?.mappingInfo?.find( ( f ) => f.type === 'review' )?.revicedPerc|| '--',
629
+
630
+ status: item?.mappingInfo?.find( ( f ) => f.type === 'review' )?.status|| '--',
631
+ ReviewedBy: item?.mappingInfo?.find( ( f ) => f.type === 'review' )?.createdByEmail||'--',
632
+
633
+ } );
634
+ }
635
+ } else {
636
+ temp =[];
637
+ }
1156
638
  }
1157
639
 
1158
- return res.sendSuccess( { result: result } );
640
+ return res.sendSuccess( { result: temp } );
1159
641
  } catch ( error ) {
1160
642
  const err = error.message || 'Internal Server Error';
1161
643
  logger.error( { error: error, messgage: req.query } );
@@ -228,14 +228,13 @@ export async function ticketCreation( req, res, next ) {
228
228
  // check the createtion permission from the user permission
229
229
  const userInfo = req?.user;
230
230
  const ticketsFeature = userInfo?.rolespermission?.some( ( f ) => f.featureName === 'FootfallDirectory' && ( f.modules.find( ( m ) => m.name =='creator' && ( m.isAdd==true || m.isEdit==true ) ) ) );
231
- logger.info( { ticketsFeature } );
232
231
  if ( !ticketsFeature ) {
233
232
  return res.sendError( 'Forbidden to Create Ticket', 403 );
234
233
  }
235
234
 
236
235
  // get store info by the storeId into mongo db
237
236
  const getstoreName = await findOneStore( { storeId: inputData.storeId, status: 'active' }, { storeId: 1, storeName: 1, clientId: 1 } );
238
- logger.info( { getstoreName } );
237
+
239
238
  if ( !getstoreName || getstoreName == null ) {
240
239
  return res.sendError( 'The store ID is either inActive or not found', 400 );
241
240
  }
@@ -261,22 +260,20 @@ export async function ticketCreation( req, res, next ) {
261
260
 
262
261
  const getFootfallCount = await getOpenSearchData( openSearch.footfall, getQuery );
263
262
  const hits = getFootfallCount?.body?.hits?.hits || [];
264
- logger.info( { hits } );
265
263
  if ( hits?.[0]?._source?.footfall_count <= 0 ) {
266
264
  return res.sendError( 'You can’t create a ticket because this store has 0 footfall data' );
267
265
  }
268
266
 
269
267
  // get category details from the client level configuration
270
268
  const getConfig = await findOneClient( { clientId: getstoreName.clientId }, { footfallDirectoryConfigs: 1 } );
271
- logger.info( { getConfig, ta123: getConfig?.footfallDirectoryConfigs } );
272
269
  if ( !getConfig || getConfig == null ) {
273
270
  return res.sendError( 'The Client ID is either not configured or not found', 400 );
274
271
  }
275
272
 
276
273
  // Get taggingLimitation from config (check both possible paths)
277
274
  const taggingLimitation = getConfig?.footfallDirectoryConfigs?.taggingLimitation;
278
- logger.info( { taggingLimitation, tagginngs: getConfig?.footfallDirectoryConfigs } );
279
275
  // Initialize count object from taggingLimitation
276
+ const tempAcc = [];
280
277
  const getCategory = taggingLimitation?.reduce( ( acc, item ) => {
281
278
  if ( item?.type ) {
282
279
  // Convert type to camelCase with "Count" suffix
@@ -289,11 +286,21 @@ export async function ticketCreation( req, res, next ) {
289
286
  // Convert first letter to lowercase and append "Count"
290
287
  key = typeLower.charAt( 0 ) + typeLower.slice( 1 ) + 'Count';
291
288
  }
292
- acc[key] = 0;
289
+
290
+
291
+ // To change from an object to the desired array structure, assemble an array of objects:
292
+ tempAcc.push( {
293
+ name: item.name,
294
+ value: 0,
295
+ key: key,
296
+ type: item.type,
297
+ } );
298
+
299
+
300
+ return acc;
293
301
  }
294
- return acc;
295
302
  }, {} ) || {};
296
- logger.info( { getCategory } );
303
+
297
304
  // Query OpenSearch revop index to get actual counts for each type
298
305
  if ( taggingLimitation && taggingLimitation.length > 0 ) {
299
306
  const revopQuery = {
@@ -324,51 +331,38 @@ export async function ticketCreation( req, res, next ) {
324
331
  },
325
332
  };
326
333
 
327
- try {
328
- const revopData = await getOpenSearchData( openSearch.revop, revopQuery );
329
- logger.info( { revopData: revopData } );
330
- const buckets = revopData?.body?.aggregations?.type_counts?.buckets || [];
331
-
332
- // Map OpenSearch revopsType values to count object keys
333
- buckets.forEach( ( bucket ) => {
334
- const revopsType = bucket.key?.toLowerCase();
335
- const count = bucket.doc_count || 0;
336
-
337
- // Map the revopsType to the correct count key
338
- // Handle variations: duplicate, duplicateImages, duplicateimages
339
- if ( revopsType === 'duplicate' ) {
340
- if ( getCategory.hasOwnProperty( 'duplicateCount' ) ) {
341
- getCategory.duplicateCount = count;
342
- }
343
- } else if ( revopsType === 'employee' ) {
344
- if ( getCategory.hasOwnProperty( 'employeeCount' ) ) {
345
- getCategory.employeeCount = count;
346
- }
347
- } else if ( revopsType === 'housekeeping' ) {
348
- if ( getCategory.hasOwnProperty( 'houseKeepingCount' ) ) {
349
- getCategory.houseKeepingCount = count;
350
- }
351
- } else if ( revopsType === 'junk' ) {
352
- if ( getCategory.hasOwnProperty( 'junkCount' ) ) {
353
- getCategory.junkCount = count;
354
- }
334
+
335
+ const revopData = await getOpenSearchData( openSearch.revop, revopQuery );
336
+ const buckets = revopData?.body?.aggregations?.type_counts?.buckets || [];
337
+
338
+ // Map OpenSearch revopsType values to count object keys
339
+ buckets.forEach( ( bucket ) => {
340
+ const revopsType = bucket.key;
341
+ const count = bucket.doc_count || 0;
342
+
343
+
344
+ if ( Array.isArray( tempAcc ) ) {
345
+ // Find the tempAcc entry whose type (case-insensitive) matches revopsType
346
+ const accMatch = tempAcc.find(
347
+ ( acc ) =>
348
+ acc.type &&
349
+ acc.type === revopsType,
350
+ );
351
+
352
+ if ( accMatch && accMatch.key ) {
353
+ tempAcc.find( ( a ) => a.key === accMatch.key ).value = count;
355
354
  }
356
- } );
357
- } catch ( error ) {
358
- logger.error( { error: error, message: 'Error fetching revop counts', function: 'footfallDirectoryTicket-ticketCreation' } );
359
- // Continue with default 0 values if query fails
360
- }
355
+ }
356
+ } );
361
357
  }
362
358
 
363
- logger.info( { getCategory: getCategory } );
364
359
 
365
360
  // Calculate revisedFootfall: footfallCount - (sum of all counts)
366
- const totalCount = ( getCategory.duplicateCount || 0 ) +
367
- ( getCategory.employeeCount || 0 ) +
368
- ( getCategory.houseKeepingCount || 0 ) +
369
- ( getCategory.junkCount || 0 );
361
+
362
+ const totalCount = Array.isArray( tempAcc ) ?
363
+ tempAcc.reduce( ( sum, acc ) => sum + ( acc.value || 0 ), 0 ) :
364
+ 0;
370
365
  const footfallCount = hits?.[0]?._source?.footfall_count || 0;
371
- logger.info( { footfallCount, totalCount } );
372
366
  const revisedFootfall = Math.max( 0, footfallCount - totalCount );
373
367
  if ( footfallCount - revisedFootfall == 0 ) {
374
368
  return res.sendError( 'Cannot create a ticket because footfall hasn’t changed', 400 );
@@ -400,10 +394,10 @@ export async function ticketCreation( req, res, next ) {
400
394
  return res.sendError( 'You don’t have any tagged images right now', 400 );
401
395
  }
402
396
  const formattedTaggingData = formatRevopTaggingHits( taggingImages );
403
- logger.info( { revopTaggingData: formattedTaggingData } );
404
397
 
405
398
  const record = {
406
399
  storeId: inputData.storeId,
400
+ type: 'store',
407
401
  dateString: inputData.dateString,
408
402
  storeName: getstoreName?.storeName,
409
403
  ticketName: inputData.ticketName|| 'footfall-directory',
@@ -420,12 +414,14 @@ export async function ticketCreation( req, res, next ) {
420
414
  type: 'tagging',
421
415
  mode: inputData.mode,
422
416
  revicedFootfall: revisedFootfall,
423
- count: getCategory,
417
+ revicedPerc: Math.round( ( revisedFootfall/footfallCount ) * 100 || 0 ) + '%',
418
+ count: tempAcc,
424
419
  revisedDetail: formattedTaggingData,
425
420
  status: 'raised',
426
421
  createdByEmail: req?.user?.email,
427
422
  createdByUserName: req?.user?.userName,
428
423
  createdByRole: req?.user?.role,
424
+ createdAt: new Date(),
429
425
  },
430
426
  ],
431
427
  };
@@ -462,6 +458,7 @@ export async function ticketCreation( req, res, next ) {
462
458
  type: 'tagging',
463
459
  mode: inputData.mode,
464
460
  revicedFootfall: revisedFootfall,
461
+ revicedPerc: Math.round( ( revisedFootfall/footfallCount ) * 100 || 0 ) + '%',
465
462
  count: getCategory,
466
463
  revisedDetail: formattedTaggingData,
467
464
  status: 'closed',
@@ -492,6 +489,7 @@ export async function ticketCreation( req, res, next ) {
492
489
  revisionMapping = {
493
490
  type: 'review',
494
491
  revicedFootfall: revisedFootfall,
492
+ revicedPerc: Math.round( ( revisedFootfall/footfallCount ) * 100 || 0 ) + '%',
495
493
  count: getCategory,
496
494
  revisedDetail: formattedTaggingData,
497
495
  status: 'open',
@@ -500,6 +498,7 @@ export async function ticketCreation( req, res, next ) {
500
498
  approverMapping = {
501
499
  type: 'approver',
502
500
  revicedFootfall: revisedFootfall,
501
+ revicedPerc: Math.round( ( revisedFootfall/footfallCount ) * 100 || 0 ) + '%',
503
502
  count: getCategory,
504
503
  revisedDetail: formattedTaggingData,
505
504
  status: 'open',
@@ -508,6 +507,7 @@ export async function ticketCreation( req, res, next ) {
508
507
  tangoReviewMapping = {
509
508
  type: 'tango-review',
510
509
  revicedFootfall: revisedFootfall,
510
+ revicedPerc: Math.round( ( revisedFootfall/footfallCount ) * 100 || 0 ) + '%',
511
511
  count: getCategory,
512
512
  revisedDetail: formattedTaggingData,
513
513
  status: 'open',