tango-app-api-infra 3.0.66-dev → 3.0.67-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.
@@ -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, download, 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';
@@ -75,9 +75,9 @@ export async function createTicket( req, res ) {
75
75
  let Uidomain = `${appConfig.url.domain}/manage/stores/infra-ticket?storeId=${req.body.basicDetails.storeId}`;
76
76
 
77
77
  const html = htmlContent( { ...req.body, Uidomain: Uidomain, domain: appConfig.url.apiDomain, date: dayjs( req.body.issueDate ).format( 'YYYY-MM-DD' ), downtimetotal: downtimetotal, Timestamp: Timestamp } );
78
- await sendEmailWithSES( req.body.spocEmail, subject, html, attachments, appConfig.cloud.aws.ses.adminEmail );
79
-
80
-
78
+ if ( req.body.emailAlert && req.body.spocEmail && req.body.issueType == 'infra' && isValidEmail( req.body.spocEmail ) ) {
79
+ await sendEmailWithSES( req.body.spocEmail, subject, html, attachments, appConfig.cloud.aws.ses.adminEmail );
80
+ }
81
81
  if ( create ) {
82
82
  res.sendSuccess( 'Ticket Created Successfully' );
83
83
  }
@@ -86,6 +86,10 @@ export async function createTicket( req, res ) {
86
86
  return res.sendError( error, 500 );
87
87
  }
88
88
  }
89
+ function isValidEmail( email ) {
90
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
91
+ return emailRegex.test( email );
92
+ }
89
93
  export async function bulkcreateTicket( req, res ) {
90
94
  try {
91
95
  let response = {};
@@ -122,28 +126,27 @@ export async function bulkcreateTicket( req, res ) {
122
126
  export async function updateStatus( req, res ) {
123
127
  try {
124
128
  if ( req.user.userType == 'tango' ) {
125
- if ( req.body.status == 'inprogress' ) {
126
- req.body.ticketActivity.push( {
127
- actionType: 'statusChange',
128
- timeStamp: new Date(),
129
- actionBy: 'Tango',
130
- IdentifiedBy: req.user.userName,
131
- } );
132
- }
129
+ req.body.ticketActivity.push( {
130
+ actionType: 'statusChange',
131
+ timeStamp: new Date(),
132
+ actionBy: 'Tango',
133
+ IdentifiedBy: req.user.userName,
134
+ } );
135
+ req.body.status = 'inprogress';
133
136
  req.body.ticketDetails.addressingUser = req.user._id;
134
137
  let updateTicket = await updateOneTangoTicket( { ticketId: req.body.ticketId }, req.body );
135
138
  if ( updateTicket ) {
136
139
  res.sendSuccess( 'Ticket Updated Successfully' );
137
140
  }
138
141
  } else if ( req.user.userType == 'client' ) {
139
- if ( req.body.status == 'inprogress' ) {
140
- req.body.ticketActivity.push( {
141
- actionType: 'statusChange',
142
- timeStamp: new Date(),
143
- actionBy: 'User',
144
- IdentifiedBy: req.user.userName,
145
- } );
146
- }
142
+ req.body.ticketActivity.push( {
143
+ actionType: 'statusChange',
144
+ timeStamp: new Date(),
145
+ actionBy: 'User',
146
+ IdentifiedBy: req.user.userName,
147
+ } );
148
+ req.body.status = 'inprogress';
149
+
147
150
  req.body.ticketDetails.addressingClient = req.user._id;
148
151
  let updateTicket = await updateOneTangoTicket( { ticketId: req.body.ticketId }, req.body );
149
152
  if ( updateTicket ) {
@@ -284,7 +287,7 @@ export async function viewTicket( req, res ) {
284
287
  if ( ticket.attachments.hasOwnProperty( index ) ) {
285
288
  let file = ticket.attachments[index];
286
289
  let params = {
287
- Bucket: 'tango-client-sandbox',
290
+ Bucket: appConfig.cloud.aws.bucket.ticket,
288
291
  file_path: file.filePath,
289
292
  };
290
293
  let attachments = await signedUrl( params );
@@ -336,7 +339,7 @@ export async function uploadAttachments( req, res ) {
336
339
  for ( let singleImg in req.files.img ) {
337
340
  if ( req.files.img.hasOwnProperty( singleImg ) ) {
338
341
  let params = {
339
- Bucket: 'tango-client-sandbox',
342
+ Bucket: appConfig.cloud.aws.bucket.ticket,
340
343
  Key: req.params.ticketId + '/',
341
344
  ContentType: 'multipart/form-data',
342
345
  body: req.files.img[singleImg].data,
@@ -360,7 +363,7 @@ export async function uploadAttachments( req, res ) {
360
363
  let oldticket = await findOneTangoTicket( { ticketId: req.params.ticketId } );
361
364
  let attachments = oldticket.attachments;
362
365
  let params = {
363
- Bucket: 'tango-client-sandbox',
366
+ Bucket: appConfig.cloud.aws.bucket.ticket,
364
367
  Key: req.params.ticketId + '/',
365
368
  ContentType: 'multipart/form-data',
366
369
  body: req.files.img.data,
@@ -712,3 +715,668 @@ function inWords( num ) {
712
715
 
713
716
  return str.toLowerCase().split( ' ' ).map( ( word ) => word.charAt( 0 ).toUpperCase() + word.slice( 1 ) ).join( ' ' );
714
717
  }
718
+
719
+
720
+ export async function infraTable( req, res ) {
721
+ try {
722
+ let query = [];
723
+ let date = await getUTC( new Date( req.body.fromDate ), new Date( req.body.toDate ) );
724
+ if ( req.body.clientId && req.body.clientId.length > 0 ) {
725
+ query.push( {
726
+ $match: {
727
+ 'basicDetails.clientId': { $in: req.body.clientId },
728
+ },
729
+ } );
730
+ }
731
+ query.push( {
732
+ $match: {
733
+ $and: [
734
+ { issueType: 'infra' },
735
+ { createdAt: { $gte: date.start } },
736
+ { createdAt: { $lte: date.end } },
737
+ ],
738
+ },
739
+ },
740
+ {
741
+ $project: {
742
+ storeId: '$basicDetails.storeId',
743
+ clientId: '$basicDetails.clientId',
744
+ ticketId: 1,
745
+ storeName: '$basicDetails.storeName',
746
+ clientName: '$basicDetails.clientName',
747
+ status: 1,
748
+ createdAt: 1,
749
+ issueDate: 1,
750
+ addressingUser: { $toObjectId: '$ticketDetails.addressingUser' },
751
+ primaryIssue: {
752
+ $filter: {
753
+ input: '$ticketActivity',
754
+ as: 'item',
755
+ cond: { $eq: [ '$$item.actionType', 'issueUpdate' ] },
756
+ },
757
+ },
758
+ },
759
+ },
760
+ {
761
+ $unwind: {
762
+ path: '$primaryIssue', preserveNullAndEmptyArrays: true,
763
+ },
764
+ },
765
+ {
766
+ $unwind: {
767
+ path: '$primaryIssue.reasons', preserveNullAndEmptyArrays: true,
768
+ },
769
+ },
770
+ {
771
+ $unwind: {
772
+ path: '$primaryIssue.reasons.secondaryIssue', preserveNullAndEmptyArrays: true,
773
+ },
774
+ },
775
+ {
776
+ $project: {
777
+ storeId: 1,
778
+ clientId: 1,
779
+ storeName: 1,
780
+ clientName: 1,
781
+ createdAt: 1,
782
+ addressingUser: 1,
783
+ ticketId: 1,
784
+ issueDate: { $ifNull: [ '$issueDate', '' ] },
785
+ status: 1,
786
+ primaryIssue: { $ifNull: [ '$primaryIssue.reasons.primaryIssue', '-' ] },
787
+ secondaryIssue: { $ifNull: [ '$primaryIssue.reasons.secondaryIssue.name', '-' ] },
788
+ },
789
+ },
790
+ {
791
+ '$lookup': {
792
+ 'from': 'users',
793
+ 'let': { 'userId': '$addressingUser' },
794
+ 'pipeline': [
795
+ {
796
+ '$match': {
797
+ '$expr': {
798
+ '$eq': [ '$_id', '$$userId' ],
799
+ },
800
+ },
801
+ },
802
+ {
803
+ '$project': {
804
+ 'userName': 1,
805
+ 'email': 1,
806
+ 'role': 1,
807
+ },
808
+ },
809
+ ],
810
+ 'as': 'user',
811
+ },
812
+ },
813
+
814
+ {
815
+ $unwind: {
816
+ path: '$user',
817
+ preserveNullAndEmptyArrays: true,
818
+ },
819
+ },
820
+ {
821
+ $group: {
822
+ _id: '$ticketId',
823
+ storeId: { $first: '$storeId' },
824
+ clientId: { $first: '$clientId' },
825
+ ticketId: { $first: '$ticketId' },
826
+ storeName: { $first: '$storeName' },
827
+ userName: { $first: { $ifNull: [ '$user.userName', '-' ] } },
828
+ userEmail: { $first: { $ifNull: [ '$user.email', '-' ] } },
829
+ clientName: { $first: '$clientName' },
830
+ createdAt: { $first: '$createdAt' },
831
+ issueDate: { $last: '$issueDate' },
832
+ status: { $last: '$status' },
833
+ primaryIssue: { $last: '$primaryIssue' },
834
+ secondaryIssue: { $last: '$secondaryIssue' },
835
+ },
836
+ },
837
+ {
838
+ $sort: {
839
+ ticketId: -1,
840
+ },
841
+ },
842
+ );
843
+ if ( req.body.sortColumName && req.body.sortColumName !== '' && req.body.sortBy ) {
844
+ query.push( {
845
+ $sort: { [req.body.sortColumName]: req.body.sortBy },
846
+ } );
847
+ }
848
+ if ( req.body.storeIdFilter && req.body.storeIdFilter.length > 0 ) {
849
+ query.push( {
850
+ $match: {
851
+ storeId: { $in: req.body.storeIdFilter },
852
+ },
853
+ } );
854
+ }
855
+ if ( req.body.statusFilter && req.body.statusFilter.length > 0 ) {
856
+ query.push( {
857
+ $match: {
858
+ status: { $in: req.body.statusFilter },
859
+ },
860
+ } );
861
+ }
862
+ if ( req.body.userFilter && req.body.userFilter.length > 0 ) {
863
+ query.push( {
864
+ $match: {
865
+ userEmail: { $in: req.body.userFilter },
866
+ },
867
+ } );
868
+ }
869
+ let ticketList = await aggregateTangoTicket( query );
870
+ let issueList = await findinfraReason( { parentId: { '$exists': false } } );
871
+ const categoryCounts = {};
872
+ let response;
873
+ if ( ticketList.length > 0 ) {
874
+ ticketList.forEach( ( item ) => {
875
+ const categoryName = item.primaryIssue;
876
+ if ( categoryCounts[categoryName] ) {
877
+ categoryCounts[categoryName]++;
878
+ } else {
879
+ categoryCounts[categoryName] = 1;
880
+ }
881
+ } );
882
+ response = issueList.map( ( category ) => ( {
883
+ name: category.name,
884
+ count: categoryCounts[category.name] || 0,
885
+ } ) );
886
+ } else {
887
+ response = issueList.map( ( category ) => ( {
888
+ name: category.name,
889
+ count: 0,
890
+ } ) );
891
+ }
892
+ response.push( {
893
+ 'name': 'total',
894
+ 'count': ticketList.length,
895
+
896
+ } );
897
+ if ( req.body.filterIssue && req.body.filterIssue != '' && req.body.filterIssue != 'total' ) {
898
+ query.push( {
899
+ $match: {
900
+ primaryIssue: req.body.filterIssue,
901
+ },
902
+ } );
903
+ }
904
+
905
+ if ( req.body.searchValue && req.body.searchValue != '' ) {
906
+ query.push( {
907
+ $match: {
908
+ $or: [
909
+ { storeId: { $regex: req.body.searchValue, $options: 'i' } },
910
+ { storeName: { $regex: req.body.searchValue, $options: 'i' } },
911
+ ],
912
+ },
913
+ } );
914
+ }
915
+ let count = await aggregateTangoTicket( query );
916
+
917
+ if ( req.body.limit && req.body.offset && !req.body.export ) {
918
+ query.push(
919
+ { $skip: ( req.body.offset - 1 ) * req.body.limit },
920
+ { $limit: Number( req.body.limit ) },
921
+ );
922
+ }
923
+ let result = await aggregateTangoTicket( query );
924
+ if ( req.body.export && result.length > 0 ) {
925
+ const exportdata = [];
926
+ result.forEach( ( element ) => {
927
+ exportdata.push( {
928
+ 'ticketId': element.ticketId,
929
+ 'issueDate': dayjs( element.issueDate ).format( 'DD-MM-YYYY' ),
930
+ 'storeId': element.storeId,
931
+ 'storeName': element.storeName,
932
+ 'clientId': element.clientId,
933
+ 'clientName': element.clientName,
934
+ 'userName': element.userName,
935
+ 'userEmail': element.userEmail,
936
+ 'Status': element.status,
937
+ 'StatusDetails': element.primaryIssue,
938
+ 'SubIssue': element.secondaryIssue,
939
+ } );
940
+ } );
941
+ await download( exportdata, res );
942
+ return;
943
+ }
944
+ res.sendSuccess( {
945
+ response: response,
946
+ count: count.length,
947
+ result: result,
948
+ } );
949
+ } catch ( error ) {
950
+ logger.error( { error: error, function: 'infraTable' } );
951
+ return res.sendError( error, 500 );
952
+ }
953
+ }
954
+ export async function installationTable( req, res ) {
955
+ try {
956
+ let query = [];
957
+ let date = await getUTC( new Date( req.body.fromDate ), new Date( req.body.toDate ) );
958
+ if ( req.body.clientId && req.body.clientId.length > 0 ) {
959
+ query.push( {
960
+ $match: {
961
+ 'basicDetails.clientId': { $in: req.body.clientId },
962
+ },
963
+ } );
964
+ }
965
+
966
+ query.push( {
967
+ $match: {
968
+ $and: [
969
+ { issueType: 'installation' },
970
+ { createdAt: { $gte: date.start } },
971
+ { createdAt: { $lte: date.end } },
972
+ ],
973
+ },
974
+ },
975
+ {
976
+ $project: {
977
+ storeId: '$basicDetails.storeId',
978
+ clientId: '$basicDetails.clientId',
979
+ ticketId: 1,
980
+ storeName: '$basicDetails.storeName',
981
+ clientName: '$basicDetails.clientName',
982
+ status: 1,
983
+ createdAt: 1,
984
+ addressingUser: '$ticketDetails.addressingUser',
985
+ installationStatus: '$ticketDetails.installationStatus',
986
+ issueDate: 1,
987
+ primaryIssue: {
988
+ $filter: {
989
+ input: '$ticketActivity',
990
+ as: 'item',
991
+ cond: { $eq: [ '$$item.actionType', 'issueUpdate' ] },
992
+ },
993
+ },
994
+ },
995
+ },
996
+ {
997
+ $unwind: {
998
+ path: '$primaryIssue', preserveNullAndEmptyArrays: true,
999
+ },
1000
+ },
1001
+ {
1002
+ $unwind: {
1003
+ path: '$primaryIssue.reasons', preserveNullAndEmptyArrays: true,
1004
+ },
1005
+ },
1006
+ {
1007
+ $unwind: {
1008
+ path: '$primaryIssue.reasons.secondaryIssue', preserveNullAndEmptyArrays: true,
1009
+ },
1010
+ },
1011
+ {
1012
+ $project: {
1013
+ storeId: 1,
1014
+ clientId: 1,
1015
+ storeName: 1,
1016
+ clientName: 1,
1017
+ createdAt: 1,
1018
+ ticketId: 1,
1019
+ addressingUser: 1,
1020
+ installationStatus: { $ifNull: [ '$installationStatus', '-' ] },
1021
+ issueDate: { $ifNull: [ '$issueDate', '' ] },
1022
+ status: 1,
1023
+ primaryIssue: { $ifNull: [ '$primaryIssue.reasons.primaryIssue', '-' ] },
1024
+ secondaryIssue: { $ifNull: [ '$primaryIssue.reasons.secondaryIssue.name', '-' ] },
1025
+ },
1026
+ },
1027
+ {
1028
+ '$lookup': {
1029
+ 'from': 'users',
1030
+ 'let': { 'userId': '$addressingUser' },
1031
+ 'pipeline': [
1032
+ {
1033
+ '$match': {
1034
+ '$expr': {
1035
+ '$eq': [ '$_id', '$$userId' ],
1036
+ },
1037
+ },
1038
+ },
1039
+ {
1040
+ '$project': {
1041
+ 'userName': 1,
1042
+ 'email': 1,
1043
+ 'role': 1,
1044
+ },
1045
+ },
1046
+ ],
1047
+ 'as': 'user',
1048
+ },
1049
+ },
1050
+
1051
+ {
1052
+ $unwind: {
1053
+ path: '$user',
1054
+ preserveNullAndEmptyArrays: true,
1055
+ },
1056
+ },
1057
+ {
1058
+ $group: {
1059
+ _id: '$ticketId',
1060
+ storeId: { $first: '$storeId' },
1061
+ clientId: { $first: '$clientId' },
1062
+ ticketId: { $first: '$ticketId' },
1063
+ storeName: { $first: '$storeName' },
1064
+ userName: { $first: { $ifNull: [ '$user.userName', '-' ] } },
1065
+ userEmail: { $first: { $ifNull: [ '$user.email', '-' ] } },
1066
+ clientName: { $first: '$clientName' },
1067
+ createdAt: { $first: '$createdAt' },
1068
+ issueDate: { $last: '$issueDate' },
1069
+ installationStatus: { $last: '$installationStatus' },
1070
+ status: { $last: '$status' },
1071
+ primaryIssue: { $last: '$primaryIssue' },
1072
+ secondaryIssue: { $last: '$secondaryIssue' },
1073
+ },
1074
+ },
1075
+ {
1076
+ $sort: {
1077
+ ticketId: -1,
1078
+ },
1079
+ },
1080
+ );
1081
+ if ( req.body.sortColumName && req.body.sortColumName !== '' && req.body.sortBy ) {
1082
+ query.push( {
1083
+ $sort: { [req.body.sortColumName]: req.body.sortBy },
1084
+ } );
1085
+ }
1086
+ if ( req.body.storeIdFilter && req.body.storeIdFilter.length > 0 ) {
1087
+ query.push( {
1088
+ $match: {
1089
+ storeId: { $in: req.body.storeIdFilter },
1090
+ },
1091
+ } );
1092
+ }
1093
+ if ( req.body.statusFilter && req.body.statusFilter.length > 0 ) {
1094
+ query.push( {
1095
+ $match: {
1096
+ installationStatus: { $in: req.body.statusFilter },
1097
+ },
1098
+ } );
1099
+ }
1100
+ if ( req.body.userFilter && req.body.userFilter.length > 0 ) {
1101
+ query.push( {
1102
+ $match: {
1103
+ userEmail: { $in: req.body.userFilter },
1104
+ },
1105
+ } );
1106
+ }
1107
+ let ticketList = await aggregateTangoTicket( query );
1108
+ let issueList = await findinfraReason( { parentId: { '$exists': false } } );
1109
+ const categoryCounts = {};
1110
+ let response;
1111
+ if ( ticketList.length > 0 ) {
1112
+ ticketList.forEach( ( item ) => {
1113
+ const categoryName = item.primaryIssue;
1114
+ if ( categoryCounts[categoryName] ) {
1115
+ categoryCounts[categoryName]++;
1116
+ } else {
1117
+ categoryCounts[categoryName] = 1;
1118
+ }
1119
+ } );
1120
+ response = issueList.map( ( category ) => ( {
1121
+ name: category.name,
1122
+ count: categoryCounts[category.name] || 0,
1123
+ } ) );
1124
+ } else {
1125
+ response = issueList.map( ( category ) => ( {
1126
+ name: category.name,
1127
+ count: 0,
1128
+ } ) );
1129
+ }
1130
+ response.push( {
1131
+ 'name': 'total',
1132
+ 'count': ticketList.length,
1133
+
1134
+ } );
1135
+ if ( req.body.filterIssue && req.body.filterIssue != '' && req.body.filterIssue != 'total' ) {
1136
+ query.push( {
1137
+ $match: {
1138
+ primaryIssue: req.body.filterIssue,
1139
+ },
1140
+ } );
1141
+ }
1142
+ if ( req.body.searchValue && req.body.searchValue != '' ) {
1143
+ query.push( {
1144
+ $match: {
1145
+ $or: [
1146
+ { storeId: { $regex: req.body.searchValue, $options: 'i' } },
1147
+ { storeName: { $regex: req.body.searchValue, $options: 'i' } },
1148
+ ],
1149
+ },
1150
+ } );
1151
+ }
1152
+ let count = await aggregateTangoTicket( query );
1153
+ if ( req.body.limit && req.body.offset && !req.body.export ) {
1154
+ query.push(
1155
+ { $skip: ( req.body.offset - 1 ) * req.body.limit },
1156
+ { $limit: Number( req.body.limit ) },
1157
+ );
1158
+ }
1159
+ let result = await aggregateTangoTicket( query );
1160
+
1161
+ if ( req.body.export && result.length > 0 ) {
1162
+ const exportdata = [];
1163
+ result.forEach( ( element ) => {
1164
+ exportdata.push( {
1165
+ 'ticketId': element.ticketId,
1166
+ 'issueDate': dayjs( element.issueDate ).format( 'DD-MM-YYYY' ),
1167
+ 'storeId': element.storeId,
1168
+ 'storeName': element.storeName,
1169
+ 'clientId': element.clientId,
1170
+ 'clientName': element.clientName,
1171
+ 'userName': element.userName,
1172
+ 'userEmail': element.userEmail,
1173
+ 'Status': element.installationStatus,
1174
+ 'StatusDetails': element.primaryIssue,
1175
+ 'SubIssue': element.secondaryIssue,
1176
+ } );
1177
+ } );
1178
+ await download( exportdata, res );
1179
+ return;
1180
+ }
1181
+ res.sendSuccess( {
1182
+ response: response,
1183
+ count: count.length,
1184
+ result: result,
1185
+ } );
1186
+ } catch ( error ) {
1187
+ logger.error( { error: error, function: 'installationTable' } );
1188
+ return res.sendError( error, 500 );
1189
+ }
1190
+ }
1191
+ export async function matTable( req, res ) {
1192
+ try {
1193
+ let query = [];
1194
+ let date = await getUTC( new Date( req.body.fromDate ), new Date( req.body.toDate ) );
1195
+ if ( req.body.clientId && req.body.clientId.length > 0 ) {
1196
+ query.push( {
1197
+ $match: {
1198
+ 'basicDetails.clientId': { $in: req.body.clientId },
1199
+ },
1200
+ } );
1201
+ }
1202
+
1203
+ query.push( {
1204
+ $match: {
1205
+ $and: [
1206
+ { issueType: 'mat' },
1207
+ { createdAt: { $gte: date.start } },
1208
+ { createdAt: { $lte: date.end } },
1209
+ ],
1210
+ },
1211
+ },
1212
+ {
1213
+ $project: {
1214
+ storeId: '$basicDetails.storeId',
1215
+ clientId: '$basicDetails.clientId',
1216
+ ticketId: 1,
1217
+ storeName: '$basicDetails.storeName',
1218
+ clientName: '$basicDetails.clientName',
1219
+ status: 1,
1220
+ createdAt: 1,
1221
+ addressingUser: '$ticketDetails.addressingUser',
1222
+ issueDate: 1,
1223
+ },
1224
+ },
1225
+
1226
+ {
1227
+ '$lookup': {
1228
+ 'from': 'users',
1229
+ 'let': { 'userId': '$addressingUser' },
1230
+ 'pipeline': [
1231
+ {
1232
+ '$match': {
1233
+ '$expr': {
1234
+ '$eq': [ '$_id', '$$userId' ],
1235
+ },
1236
+ },
1237
+ },
1238
+ {
1239
+ '$project': {
1240
+ 'userName': 1,
1241
+ 'email': 1,
1242
+ 'role': 1,
1243
+ },
1244
+ },
1245
+ ],
1246
+ 'as': 'user',
1247
+ },
1248
+ },
1249
+
1250
+ {
1251
+ $unwind: {
1252
+ path: '$user',
1253
+ preserveNullAndEmptyArrays: true,
1254
+ },
1255
+ },
1256
+ {
1257
+ $group: {
1258
+ _id: '$ticketId',
1259
+ storeId: { $first: '$storeId' },
1260
+ clientId: { $first: '$clientId' },
1261
+ ticketId: { $first: '$ticketId' },
1262
+ storeName: { $first: '$storeName' },
1263
+ userName: { $first: { $ifNull: [ '$user.userName', '-' ] } },
1264
+ userEmail: { $first: { $ifNull: [ '$user.email', '-' ] } },
1265
+ clientName: { $first: '$clientName' },
1266
+ createdAt: { $first: '$createdAt' },
1267
+ issueDate: { $last: '$issueDate' },
1268
+ status: { $last: '$status' },
1269
+ },
1270
+ },
1271
+ );
1272
+ if ( req.body.sortColumName && req.body.sortColumName !== '' && req.body.sortBy ) {
1273
+ query.push( {
1274
+ $sort: { [req.body.sortColumName]: req.body.sortBy },
1275
+ } );
1276
+ }
1277
+ if ( req.body.storeIdFilter && req.body.storeIdFilter.length > 0 ) {
1278
+ query.push( {
1279
+ $match: {
1280
+ storeId: { $in: req.body.storeIdFilter },
1281
+ },
1282
+ } );
1283
+ }
1284
+ if ( req.body.statusFilter && req.body.statusFilter.length > 0 ) {
1285
+ query.push( {
1286
+ $match: {
1287
+ status: { $in: req.body.statusFilter },
1288
+ },
1289
+ } );
1290
+ }
1291
+ if ( req.body.userFilter && req.body.userFilter.length > 0 ) {
1292
+ query.push( {
1293
+ $match: {
1294
+ userEmail: { $in: req.body.userFilter },
1295
+ },
1296
+ } );
1297
+ }
1298
+
1299
+ if ( req.body.filterIssue && req.body.filterIssue != '' && req.body.filterIssue != 'total' ) {
1300
+ query.push( {
1301
+ $match: {
1302
+ primaryIssue: req.body.filterIssue,
1303
+ },
1304
+ } );
1305
+ }
1306
+ if ( req.body.searchValue && req.body.searchValue != '' ) {
1307
+ query.push( {
1308
+ $match: {
1309
+ $or: [
1310
+ { storeId: { $regex: req.body.searchValue, $options: 'i' } },
1311
+ { storeName: { $regex: req.body.searchValue, $options: 'i' } },
1312
+ ],
1313
+ },
1314
+ } );
1315
+ }
1316
+ let count = await aggregateTangoTicket( query );
1317
+ if ( req.body.limit && req.body.offset && !req.body.export ) {
1318
+ query.push(
1319
+ { $skip: ( req.body.offset - 1 ) * req.body.limit },
1320
+ { $limit: Number( req.body.limit ) },
1321
+ );
1322
+ }
1323
+ let result = await aggregateTangoTicket( query );
1324
+
1325
+ if ( req.body.export && result.length > 0 ) {
1326
+ const exportdata = [];
1327
+ result.forEach( ( element ) => {
1328
+ exportdata.push( {
1329
+ 'ticketId': element.ticketId,
1330
+ 'issueDate': dayjs( element.issueDate ).format( 'DD-MM-YYYY' ),
1331
+ 'storeId': element.storeId,
1332
+ 'storeName': element.storeName,
1333
+ 'clientId': element.clientId,
1334
+ 'clientName': element.clientName,
1335
+ 'userName': element.userName,
1336
+ 'userEmail': element.userEmail,
1337
+ 'Status': element.installationStatus,
1338
+ } );
1339
+ } );
1340
+ await download( exportdata, res );
1341
+ return;
1342
+ }
1343
+ if ( result.length > 0 ) {
1344
+ res.sendSuccess( {
1345
+ count: count.length,
1346
+ result: result,
1347
+ } );
1348
+ } else {
1349
+ res.sendError( 'no data', 204 );
1350
+ }
1351
+ } catch ( error ) {
1352
+ logger.error( { error: error, function: 'installationTable' } );
1353
+ return res.sendError( error, 500 );
1354
+ }
1355
+ }
1356
+ export async function assignTicket( req, res ) {
1357
+ try {
1358
+ let tickets = await updateManyTangoTicket( { ticketId: { $in: req.body.tickets } }, { 'ticketDetails.assigntoUser': true, 'ticketDetails.addressingUser': req.body.user } );
1359
+ if ( tickets ) {
1360
+ res.sendSuccess( 'Ticket Assigned Successfully' );
1361
+ }
1362
+ } catch ( error ) {
1363
+ logger.error( { error: error, function: 'assignTicket' } );
1364
+ return res.sendError( error, 500 );
1365
+ }
1366
+ }
1367
+ export async function storeFilter( req, res ) {
1368
+ try {
1369
+ let stores = await findTangoTicket( { 'issueType': req.body.issueType, 'basicDetails.clientId': req.body.clientId, 'basicDetails.storeId': { $exists: true } }, { 'basicDetails.storeId': 1 } );
1370
+ const uniqueStoreIds = [ ...new Set( stores.map( ( store ) => store.basicDetails.storeId ) ) ];
1371
+ const uniqueStoreObjects = uniqueStoreIds.map( ( storeId ) => ( { 'storeId': storeId } ) );
1372
+
1373
+ if ( uniqueStoreObjects.length > 0 ) {
1374
+ res.sendSuccess( { count: uniqueStoreObjects.length, data: uniqueStoreObjects } );
1375
+ } else {
1376
+ res.sendError( 'No data', 204 );
1377
+ }
1378
+ } catch ( error ) {
1379
+ logger.error( { error: error, function: 'storeFilter' } );
1380
+ return res.sendError( error, 500 );
1381
+ }
1382
+ }