tango-app-api-infra 3.0.55-dev → 3.0.57-dev

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.0.55-dev",
3
+ "version": "3.0.57-dev",
4
4
  "description": "infra",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -211,10 +211,10 @@ export async function installationCard( req, res ) {
211
211
  $group: {
212
212
  _id: '$ticketId',
213
213
  ticketId: { $first: '$ticketId' },
214
- issueStatus: { $first: '$issueStatus' },
215
- ticketType: { $first: '$ticketType' },
216
- issueIdentifiedBy: { $first: '$issueIdentifiedBy' },
217
- primaryIssue: { $first: '$primaryIssue' },
214
+ issueStatus: { $last: '$issueStatus' },
215
+ ticketType: { $last: '$ticketType' },
216
+ issueIdentifiedBy: { $last: '$issueIdentifiedBy' },
217
+ primaryIssue: { $last: '$primaryIssue' },
218
218
  },
219
219
  },
220
220
  ];
@@ -461,8 +461,8 @@ export async function InstallationIssuesTable( req, res ) {
461
461
  storeId: { $first: '$storeId' },
462
462
  clientId: { $first: '$clientId' },
463
463
  storeName: { $first: '$storeName' },
464
- status: { $first: '$status' },
465
- primaryIssue: { $first: '$primaryIssue' },
464
+ status: { $last: '$status' },
465
+ primaryIssue: { $last: '$primaryIssue' },
466
466
  },
467
467
  },
468
468
  ];
@@ -1,9 +1,9 @@
1
1
 
2
2
 
3
- import { aggregateTangoTicket, createTangoTicket, findOneTangoTicket, updateOneTangoTicket } from '../services/tangoTicket.service.js';
3
+ import { aggregateTangoTicket, createTangoTicket, findOneTangoTicket, updateOneTangoTicket, updateManyTangoTicket, findTangoTicket } from '../services/tangoTicket.service.js';
4
4
  import { createinfraReason, findinfraReason } from '../services/infraReason.service.js';
5
5
  import { updateOneStore, findStore } from '../services/store.service.js';
6
- import { logger, fileUpload, signedUrl, sendEmailWithSES, getOpenSearchData, appConfig } from 'tango-app-api-middleware';
6
+ import { logger, fileUpload, signedUrl, sendEmailWithSES, getOpenSearchData, appConfig, getUTC } from 'tango-app-api-middleware';
7
7
  import { aggregateUser, updateOneUser } from '../services/user.service.js';
8
8
  import { updateoneClient } from '../services/client.service.js';
9
9
  import dayjs from 'dayjs';
@@ -626,23 +626,194 @@ function inWords( num ) {
626
626
  export async function infraTable( req, res ) {
627
627
  try {
628
628
  let query = [];
629
-
629
+ let date = await getUTC( new Date( req.body.fromDate ), new Date( req.body.toDate ) );
630
+ if ( req.body.clientId && req.body.clientId.length > 0 ) {
631
+ query.push( {
632
+ $match: {
633
+ 'basicDetails.clientId': { $in: req.body.clientId },
634
+ },
635
+ } );
636
+ }
630
637
  query.push( {
631
638
  $match: {
632
639
  $and: [
633
640
  { issueType: 'infra' },
634
- { 'basicDetails.clientId': { $in: req.body.clientId } },
635
641
  { createdAt: { $gte: date.start } },
636
642
  { createdAt: { $lte: date.end } },
637
643
  ],
638
644
  },
639
- } );
645
+ }, {
646
+ $project: {
647
+ storeId: '$basicDetails.storeId',
648
+ clientId: '$basicDetails.clientId',
649
+ ticketId: 1,
650
+ storeName: '$basicDetails.storeName',
651
+ clientName: '$basicDetails.clientName',
652
+ status: 1,
653
+ createdAt: 1,
654
+ issueDate: 1,
655
+ addressingUser: { $toObjectId: '$ticketDetails.addressingUser' },
656
+ primaryIssue: {
657
+ $filter: {
658
+ input: '$ticketActivity',
659
+ as: 'item',
660
+ cond: { $eq: [ '$$item.actionType', 'issueUpdate' ] },
661
+ },
662
+ },
663
+ },
664
+ },
665
+ {
666
+ $unwind: {
667
+ path: '$primaryIssue', preserveNullAndEmptyArrays: true,
668
+ },
669
+ },
670
+ {
671
+ $unwind: {
672
+ path: '$primaryIssue.reasons', preserveNullAndEmptyArrays: true,
673
+ },
674
+ },
675
+ {
676
+ $unwind: {
677
+ path: '$primaryIssue.reasons.secondaryIssue', preserveNullAndEmptyArrays: true,
678
+ },
679
+ },
680
+ {
681
+ $project: {
682
+ storeId: 1,
683
+ clientId: 1,
684
+ storeName: 1,
685
+ clientName: 1,
686
+ createdAt: 1,
687
+ addressingUser: 1,
688
+ ticketId: 1,
689
+ issueDate: { $ifNull: [ '$issueDate', '' ] },
690
+ status: 1,
691
+ primaryIssue: { $ifNull: [ '$primaryIssue.reasons.primaryIssue', '-' ] },
692
+ secondaryIssue: { $ifNull: [ '$primaryIssue.reasons.secondaryIssue.name', '-' ] },
693
+ },
694
+ },
695
+ {
696
+ '$lookup': {
697
+ 'from': 'users',
698
+ 'let': { 'userId': '$addressingUser' },
699
+ 'pipeline': [
700
+ {
701
+ '$match': {
702
+ '$expr': {
703
+ '$eq': [ '$_id', '$$userId' ],
704
+ },
705
+ },
706
+ },
707
+ {
708
+ '$project': {
709
+ 'userName': 1,
710
+ 'email': 1,
711
+ 'role': 1,
712
+ },
713
+ },
714
+ ],
715
+ 'as': 'user',
716
+ },
717
+ },
718
+
719
+ {
720
+ $unwind: {
721
+ path: '$user',
722
+ preserveNullAndEmptyArrays: true,
723
+ },
724
+ },
725
+ {
726
+ $group: {
727
+ _id: '$ticketId',
728
+ storeId: { $first: '$storeId' },
729
+ clientId: { $first: '$clientId' },
730
+ ticketId: { $first: '$ticketId' },
731
+ storeName: { $first: '$storeName' },
732
+ userName: { $first: { $ifNull: [ '$user.userName', '-' ] } },
733
+ userEmail: { $first: { $ifNull: [ '$user.email', '-' ] } },
734
+ clientName: { $first: '$clientName' },
735
+ createdAt: { $first: '$createdAt' },
736
+ issueDate: { $last: '$issueDate' },
737
+ status: { $last: '$status' },
738
+ primaryIssue: { $last: '$primaryIssue' },
739
+ secondaryIssue: { $last: '$secondaryIssue' },
740
+ },
741
+ },
742
+ );
640
743
  if ( req.body.sortColumName && req.body.sortColumName !== '' && req.body.sortBy ) {
641
744
  query.push( {
642
745
  $sort: { [req.body.sortColumName]: req.body.sortBy },
643
746
  } );
644
747
  }
748
+ if ( req.body.storeIdFilter && req.body.storeIdFilter.length > 0 ) {
749
+ query.push( {
750
+ $match: {
751
+ storeId: { $in: req.body.storeIdFilter },
752
+ },
753
+ } );
754
+ }
755
+ if ( req.body.statusFilter && req.body.statusFilter.length > 0 ) {
756
+ query.push( {
757
+ $match: {
758
+ status: { $in: req.body.statusFilter },
759
+ },
760
+ } );
761
+ }
762
+ if ( req.body.userFilter && req.body.userFilter.length > 0 ) {
763
+ query.push( {
764
+ $match: {
765
+ userEmail: { $in: req.body.userFilter },
766
+ },
767
+ } );
768
+ }
769
+ let ticketList = await aggregateTangoTicket( query );
770
+ let issueList = await findinfraReason( { parentId: { '$exists': false } } );
771
+ const categoryCounts = {};
772
+ let response;
773
+ if ( ticketList.length > 0 ) {
774
+ ticketList.forEach( ( item ) => {
775
+ const categoryName = item.primaryIssue;
776
+ if ( categoryCounts[categoryName] ) {
777
+ categoryCounts[categoryName]++;
778
+ } else {
779
+ categoryCounts[categoryName] = 1;
780
+ }
781
+ } );
782
+ response = issueList.map( ( category ) => ( {
783
+ name: category.name,
784
+ count: categoryCounts[category.name] || 0,
785
+ } ) );
786
+ } else {
787
+ response = issueList.map( ( category ) => ( {
788
+ name: category.name,
789
+ count: 0,
790
+ } ) );
791
+ }
792
+ response.push( {
793
+ 'name': 'total',
794
+ 'count': ticketList.length,
795
+
796
+ } );
797
+ if ( req.body.filterIssue && req.body.filterIssue != '' && req.body.filterIssue != 'total' ) {
798
+ query.push( {
799
+ $match: {
800
+ primaryIssue: req.body.filterIssue,
801
+ },
802
+ } );
803
+ }
804
+
805
+ if ( req.body.searchValue && req.body.searchValue != '' ) {
806
+ query.push( {
807
+ $match: {
808
+ $or: [
809
+ { storeId: { $regex: req.body.searchValue, $options: 'i' } },
810
+ { storeName: { $regex: req.body.searchValue, $options: 'i' } },
811
+ ],
812
+ },
813
+ } );
814
+ }
645
815
  let count = await aggregateTangoTicket( query );
816
+
646
817
  if ( req.body.limit && req.body.offset && !req.body.export ) {
647
818
  query.push(
648
819
  { $skip: ( req.body.offset - 1 ) * req.body.limit },
@@ -662,6 +833,7 @@ export async function infraTable( req, res ) {
662
833
  }
663
834
  if ( result.length > 0 ) {
664
835
  res.sendSuccess( {
836
+ response: response,
665
837
  count: count.length,
666
838
  result: result,
667
839
  } );
@@ -673,3 +845,256 @@ export async function infraTable( req, res ) {
673
845
  return res.sendError( error, 500 );
674
846
  }
675
847
  }
848
+ export async function installationTable( req, res ) {
849
+ try {
850
+ let query = [];
851
+ let date = await getUTC( new Date( req.body.fromDate ), new Date( req.body.toDate ) );
852
+ if ( req.body.clientId && req.body.clientId.length > 0 ) {
853
+ query.push( {
854
+ $match: {
855
+ 'basicDetails.clientId': { $in: req.body.clientId },
856
+ },
857
+ } );
858
+ }
859
+
860
+ query.push( {
861
+ $match: {
862
+ $and: [
863
+ { issueType: 'installation' },
864
+ { createdAt: { $gte: date.start } },
865
+ { createdAt: { $lte: date.end } },
866
+ ],
867
+ },
868
+ },
869
+ {
870
+ $project: {
871
+ storeId: '$basicDetails.storeId',
872
+ clientId: '$basicDetails.clientId',
873
+ ticketId: 1,
874
+ storeName: '$basicDetails.storeName',
875
+ clientName: '$basicDetails.clientName',
876
+ status: 1,
877
+ createdAt: 1,
878
+ addressingUser: '$ticketDetails.addressingUser',
879
+ installationStatus: '$ticketDetails.installationStatus',
880
+ issueDate: 1,
881
+ primaryIssue: {
882
+ $filter: {
883
+ input: '$ticketActivity',
884
+ as: 'item',
885
+ cond: { $eq: [ '$$item.actionType', 'issueUpdate' ] },
886
+ },
887
+ },
888
+ },
889
+ },
890
+ {
891
+ $unwind: {
892
+ path: '$primaryIssue', preserveNullAndEmptyArrays: true,
893
+ },
894
+ },
895
+ {
896
+ $unwind: {
897
+ path: '$primaryIssue.reasons', preserveNullAndEmptyArrays: true,
898
+ },
899
+ },
900
+ {
901
+ $unwind: {
902
+ path: '$primaryIssue.reasons.secondaryIssue', preserveNullAndEmptyArrays: true,
903
+ },
904
+ },
905
+ {
906
+ $project: {
907
+ storeId: 1,
908
+ clientId: 1,
909
+ storeName: 1,
910
+ clientName: 1,
911
+ createdAt: 1,
912
+ ticketId: 1,
913
+ addressingUser: 1,
914
+ installationStatus: 1,
915
+ issueDate: { $ifNull: [ '$issueDate', '' ] },
916
+ status: 1,
917
+ primaryIssue: { $ifNull: [ '$primaryIssue.reasons.primaryIssue', '-' ] },
918
+ secondaryIssue: { $ifNull: [ '$primaryIssue.reasons.secondaryIssue.name', '-' ] },
919
+ },
920
+ },
921
+ {
922
+ '$lookup': {
923
+ 'from': 'users',
924
+ 'let': { 'userId': '$addressingUser' },
925
+ 'pipeline': [
926
+ {
927
+ '$match': {
928
+ '$expr': {
929
+ '$eq': [ '$_id', '$$userId' ],
930
+ },
931
+ },
932
+ },
933
+ {
934
+ '$project': {
935
+ 'userName': 1,
936
+ 'email': 1,
937
+ 'role': 1,
938
+ },
939
+ },
940
+ ],
941
+ 'as': 'user',
942
+ },
943
+ },
944
+
945
+ {
946
+ $unwind: {
947
+ path: '$user',
948
+ preserveNullAndEmptyArrays: true,
949
+ },
950
+ },
951
+ {
952
+ $group: {
953
+ _id: '$ticketId',
954
+ storeId: { $first: '$storeId' },
955
+ clientId: { $first: '$clientId' },
956
+ ticketId: { $first: '$ticketId' },
957
+ storeName: { $first: '$storeName' },
958
+ userName: { $first: { $ifNull: [ '$user.userName', '-' ] } },
959
+ userEmail: { $first: { $ifNull: [ '$user.email', '-' ] } },
960
+ clientName: { $first: '$clientName' },
961
+ createdAt: { $first: '$createdAt' },
962
+ issueDate: { $last: '$issueDate' },
963
+ installationStatus: { $last: '$installationStatus' },
964
+ status: { $last: '$status' },
965
+ primaryIssue: { $last: '$primaryIssue' },
966
+ secondaryIssue: { $last: '$secondaryIssue' },
967
+ },
968
+ },
969
+ );
970
+ if ( req.body.sortColumName && req.body.sortColumName !== '' && req.body.sortBy ) {
971
+ query.push( {
972
+ $sort: { [req.body.sortColumName]: req.body.sortBy },
973
+ } );
974
+ }
975
+ if ( req.body.storeIdFilter && req.body.storeIdFilter.length > 0 ) {
976
+ query.push( {
977
+ $match: {
978
+ storeId: { $in: req.body.storeIdFilter },
979
+ },
980
+ } );
981
+ }
982
+ if ( req.body.statusFilter && req.body.statusFilter.length > 0 ) {
983
+ query.push( {
984
+ $match: {
985
+ installationStatus: { $in: req.body.statusFilter },
986
+ },
987
+ } );
988
+ }
989
+ if ( req.body.userFilter && req.body.userFilter.length > 0 ) {
990
+ query.push( {
991
+ $match: {
992
+ userEmail: { $in: req.body.userFilter },
993
+ },
994
+ } );
995
+ }
996
+ let ticketList = await aggregateTangoTicket( query );
997
+ let issueList = await findinfraReason( { parentId: { '$exists': false } } );
998
+ const categoryCounts = {};
999
+ let response;
1000
+ if ( ticketList.length > 0 ) {
1001
+ ticketList.forEach( ( item ) => {
1002
+ const categoryName = item.primaryIssue;
1003
+ if ( categoryCounts[categoryName] ) {
1004
+ categoryCounts[categoryName]++;
1005
+ } else {
1006
+ categoryCounts[categoryName] = 1;
1007
+ }
1008
+ } );
1009
+ response = issueList.map( ( category ) => ( {
1010
+ name: category.name,
1011
+ count: categoryCounts[category.name] || 0,
1012
+ } ) );
1013
+ } else {
1014
+ response = issueList.map( ( category ) => ( {
1015
+ name: category.name,
1016
+ count: 0,
1017
+ } ) );
1018
+ }
1019
+ response.push( {
1020
+ 'name': 'total',
1021
+ 'count': ticketList.length,
1022
+
1023
+ } );
1024
+ if ( req.body.filterIssue && req.body.filterIssue != '' && req.body.filterIssue != 'total' ) {
1025
+ query.push( {
1026
+ $match: {
1027
+ primaryIssue: req.body.filterIssue,
1028
+ },
1029
+ } );
1030
+ }
1031
+ if ( req.body.searchValue && req.body.searchValue != '' ) {
1032
+ query.push( {
1033
+ $match: {
1034
+ $or: [
1035
+ { storeId: { $regex: req.body.searchValue, $options: 'i' } },
1036
+ { storeName: { $regex: req.body.searchValue, $options: 'i' } },
1037
+ ],
1038
+ },
1039
+ } );
1040
+ }
1041
+ let count = await aggregateTangoTicket( query );
1042
+ if ( req.body.limit && req.body.offset && !req.body.export ) {
1043
+ query.push(
1044
+ { $skip: ( req.body.offset - 1 ) * req.body.limit },
1045
+ { $limit: Number( req.body.limit ) },
1046
+ );
1047
+ }
1048
+ let result = await aggregateTangoTicket( query );
1049
+
1050
+ if ( req.body.export && result.length > 0 ) {
1051
+ const exportdata = [];
1052
+ result.forEach( ( element ) => {
1053
+ exportdata.push( {
1054
+
1055
+ } );
1056
+ } );
1057
+ await download( exportdata, res );
1058
+ return;
1059
+ }
1060
+ if ( result.length > 0 ) {
1061
+ res.sendSuccess( {
1062
+ response: response,
1063
+ count: count.length,
1064
+ result: result,
1065
+ } );
1066
+ } else {
1067
+ res.sendError( 'no data', 204 );
1068
+ }
1069
+ } catch ( error ) {
1070
+ logger.error( { error: error, function: 'installationTable' } );
1071
+ return res.sendError( error, 500 );
1072
+ }
1073
+ }
1074
+ export async function assignTicket( req, res ) {
1075
+ try {
1076
+ let tickets = await updateManyTangoTicket( { ticketId: { $in: req.body.tickets } }, { 'ticketDetails.assigntoUser': true, 'ticketDetails.addressingUser': req.body.user } );
1077
+ if ( tickets ) {
1078
+ res.sendSuccess( 'Ticket Assigned Successfully' );
1079
+ }
1080
+ } catch ( error ) {
1081
+ logger.error( { error: error, function: 'assignTicket' } );
1082
+ return res.sendError( error, 500 );
1083
+ }
1084
+ }
1085
+ export async function storeFilter( req, res ) {
1086
+ try {
1087
+ let stores = await findTangoTicket( { 'issueType': req.body.issueType, 'basicDetails.storeId': { $exists: true } }, { 'basicDetails.storeId': 1 } );
1088
+ const uniqueStoreIds = [ ...new Set( stores.map( ( store ) => store.basicDetails.storeId ) ) ];
1089
+ const uniqueStoreObjects = uniqueStoreIds.map( ( storeId ) => ( { 'storeId': storeId } ) );
1090
+
1091
+ if ( uniqueStoreObjects.length>0 ) {
1092
+ res.sendSuccess( { count: uniqueStoreObjects.length, data: uniqueStoreObjects } );
1093
+ } else {
1094
+ res.sendError( 'No data' );
1095
+ }
1096
+ } catch ( error ) {
1097
+ logger.error( { error: error, function: 'storeFilter' } );
1098
+ return res.sendError( error, 500 );
1099
+ }
1100
+ }
@@ -337,7 +337,7 @@ export async function edgeAppLogTable( req, res ) {
337
337
  const average = sum / streamwiseDowntime.length;
338
338
  obj.downtime = Math.round( average );
339
339
  } else {
340
- obj.downtime = 0;
340
+ obj.downtime ='';
341
341
  }
342
342
  let appStatusQuery = {
343
343
  'size': 1,
@@ -4,7 +4,7 @@ import { isAllowedSessionHandler, authorize } from 'tango-app-api-middleware';
4
4
  import { validateDetails, bulkvalidateDetails, validateTicket, bulkvalidateTicket, ticketExists, infraReasonExists, InfrastepstoResolve, InfraAlert } from '../validations/infra.validation.js';
5
5
  import { createTicket, bulkcreateTicket, updateStatus, createReason, PrimaryReasons,
6
6
  secondaryReason, updateTicketIssue, viewTicket, AlertTicketReply, uploadAttachments,
7
- updateInstallationTicket, emailUserList, saveInfraEmailConfig, invoice, infraTable } from '../controllers/infra.controllers.js';
7
+ updateInstallationTicket, emailUserList, saveInfraEmailConfig, invoice, infraTable, storeFilter, assignTicket, installationTable } from '../controllers/infra.controllers.js';
8
8
 
9
9
 
10
10
  export const infraRouter = express.Router();
@@ -57,5 +57,17 @@ infraRouter.post( '/saveInfraEmailConfig', isAllowedSessionHandler, authorize( {
57
57
  infraRouter.post( '/invoice', invoice );
58
58
  infraRouter.post( '/infraTable', isAllowedSessionHandler, authorize( {
59
59
  userType: [ 'client', 'tango' ], access: [
60
- { featureName: 'manage', name: 'tickets', permissions: [ 'isEdit', 'isView' ] } ],
60
+ { featureName: 'manage', name: 'tickets', permissions: [ 'isView' ] } ],
61
61
  } ), infraTable );
62
+ infraRouter.post( '/installationTable', isAllowedSessionHandler, authorize( {
63
+ userType: [ 'client', 'tango' ], access: [
64
+ { featureName: 'manage', name: 'tickets', permissions: [ 'isView' ] } ],
65
+ } ), installationTable );
66
+ infraRouter.post( '/assignTicket', isAllowedSessionHandler, authorize( {
67
+ userType: [ 'client', 'tango' ], access: [
68
+ { featureName: 'manage', name: 'tickets', permissions: [ 'isEdit', 'isView' ] } ],
69
+ } ), assignTicket );
70
+ infraRouter.post( '/storeFilter', isAllowedSessionHandler, authorize( {
71
+ userType: [ 'tango' ], access: [
72
+ { featureName: 'manage', name: 'tickets', permissions: [ 'isView' ] } ],
73
+ } ), storeFilter );
@@ -13,6 +13,9 @@ export async function findOneTangoTicket( query, project ) {
13
13
  export async function updateOneTangoTicket( query, data ) {
14
14
  return await dataModel.tangoTicketModel.updateOne( query, { $set: data } );
15
15
  }
16
+ export async function updateManyTangoTicket( query, data ) {
17
+ return await dataModel.tangoTicketModel.updateMany( query, { $set: data } );
18
+ }
16
19
  export async function countDocumentsTangoTicket( query, data ) {
17
20
  return await dataModel.tangoTicketModel.countDocuments( query );
18
21
  }
@@ -325,7 +325,6 @@ export async function InfraAlert( req, res, next ) {
325
325
  await updateOneStore( { storeId: req.body.basicDetails.storeId }, { 'ticketConfigs.hibernation': new Date( req.body.hibernationDays ) } );
326
326
 
327
327
  await updateOneTangoTicket( { ticketId: req.body.ticketId }, { 'hibernation': new Date( req.body.hibernationDays ) } );
328
- console.log( req.body.ticketActivity );
329
328
  } else {
330
329
  if ( req.body.issueType == 'infra' ) {
331
330
  let client = await findOneClient( { clientId: req.body.basicDetails.clientId }, { ticketConfigs: 1 } );