tango-app-api-infra 3.0.12 → 3.0.14
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 +3 -3
- package/src/controllers/clientInfra.controller.js +166 -12
- package/src/controllers/infra.controllers.js +15 -9
- package/src/controllers/internalInfra.controller.js +26 -4
- package/src/controllers/userInfra.controller.js +192 -8
- package/src/routes/clientInfra.routes.js +7 -7
- package/src/routes/infra.routes.js +9 -7
- package/src/routes/internalInfra.routes.js +3 -1
- package/src/routes/storeInfra.routes.js +5 -4
- package/src/routes/userInfra.routes.js +7 -5
- package/src/services/store.service.js +3 -0
- package/src/validations/infra.validation.js +44 -11
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tango-app-api-infra",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.14",
|
|
4
4
|
"description": "infra",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"handlebars": "^4.7.8",
|
|
21
21
|
"mongodb": "^6.4.0",
|
|
22
22
|
"nodemon": "^3.1.0",
|
|
23
|
-
"tango-api-schema": "^2.0.
|
|
24
|
-
"tango-app-api-middleware": "^1.0.
|
|
23
|
+
"tango-api-schema": "^2.0.39",
|
|
24
|
+
"tango-app-api-middleware": "^1.0.21",
|
|
25
25
|
"winston": "^3.12.0",
|
|
26
26
|
"winston-daily-rotate-file": "^5.0.0"
|
|
27
27
|
},
|
|
@@ -13,8 +13,13 @@ export async function infraCard( req, res ) {
|
|
|
13
13
|
let infraStoreCount = await aggregateTangoTicket( [
|
|
14
14
|
{
|
|
15
15
|
$match: {
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
$and: [
|
|
17
|
+
{ issueType: 'infra' },
|
|
18
|
+
{ 'status': { $ne: 'closed' } },
|
|
19
|
+
{ 'basicDetails.clientId': { $in: req.body.clientId } },
|
|
20
|
+
{ createdAt: { $gte: new Date( req.body.fromDate ) } },
|
|
21
|
+
{ createdAt: { $lte: new Date( req.body.toDate ) } },
|
|
22
|
+
],
|
|
18
23
|
},
|
|
19
24
|
},
|
|
20
25
|
{
|
|
@@ -42,8 +47,14 @@ export async function infraCard( req, res ) {
|
|
|
42
47
|
] );
|
|
43
48
|
let query = [ {
|
|
44
49
|
$match: {
|
|
45
|
-
|
|
46
|
-
|
|
50
|
+
$and: [
|
|
51
|
+
{ issueType: 'infra' },
|
|
52
|
+
{ 'status': { $ne: 'closed' } },
|
|
53
|
+
{ 'basicDetails.clientId': { $in: req.body.clientId } },
|
|
54
|
+
{ 'infraTicketDetails.issueStatus': 'identified' },
|
|
55
|
+
{ createdAt: { $gte: new Date( req.body.fromDate ) } },
|
|
56
|
+
{ createdAt: { $lte: new Date( req.body.toDate ) } },
|
|
57
|
+
],
|
|
47
58
|
},
|
|
48
59
|
},
|
|
49
60
|
{
|
|
@@ -115,12 +126,18 @@ export async function infraCard( req, res ) {
|
|
|
115
126
|
}
|
|
116
127
|
}
|
|
117
128
|
|
|
118
|
-
|
|
119
129
|
export async function infraIssuesTable( req, res ) {
|
|
120
130
|
try {
|
|
121
131
|
let query = [ {
|
|
122
132
|
$match: {
|
|
123
|
-
|
|
133
|
+
$and: [
|
|
134
|
+
{ issueType: 'infra' },
|
|
135
|
+
{ status: { $ne: 'closed' } },
|
|
136
|
+
{ 'basicDetails.clientId': { $in: req.body.clientId } },
|
|
137
|
+
{ 'infraTicketDetails.issueStatus': 'identified' },
|
|
138
|
+
{ createdAt: { $gte: new Date( req.body.fromDate ) } },
|
|
139
|
+
{ createdAt: { $lte: new Date( req.body.toDate ) } },
|
|
140
|
+
],
|
|
124
141
|
},
|
|
125
142
|
},
|
|
126
143
|
{
|
|
@@ -149,7 +166,13 @@ export async function infraIssuesTable( req, res ) {
|
|
|
149
166
|
$unwind: {
|
|
150
167
|
path: '$primaryIssue.reasons', preserveNullAndEmptyArrays: true,
|
|
151
168
|
},
|
|
152
|
-
},
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
$unwind: {
|
|
172
|
+
path: '$primaryIssue.reasons.secondaryIssue', preserveNullAndEmptyArrays: true,
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
{
|
|
153
176
|
$project: {
|
|
154
177
|
storeId: 1,
|
|
155
178
|
storeName: 1,
|
|
@@ -157,9 +180,45 @@ export async function infraIssuesTable( req, res ) {
|
|
|
157
180
|
issueIdentifiedDate: { $ifNull: [ '$issueIdentifiedDate', '-' ] },
|
|
158
181
|
issueClosedDate: { $ifNull: [ '$issueClosedDate', '-' ] },
|
|
159
182
|
status: 1,
|
|
160
|
-
|
|
183
|
+
primaryIssue: { $ifNull: [ '$primaryIssue.reasons.primaryIssue', '-' ] },
|
|
184
|
+
secondaryIssue: { $ifNull: [ '$primaryIssue.reasons.secondaryIssue.name', '-' ] },
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
$group: {
|
|
189
|
+
_id: '$storeId',
|
|
190
|
+
storeName: { $first: '$storeName' },
|
|
191
|
+
createdAt: { $first: '$createdAt' },
|
|
192
|
+
issueIdentifiedDate: { $first: '$issueIdentifiedDate' },
|
|
193
|
+
issueClosedDate: { $first: '$issueClosedDate' },
|
|
194
|
+
status: { $first: '$status' },
|
|
195
|
+
primaryIssue: { $first: '$primaryIssue' },
|
|
196
|
+
secondaryIssue: { $first: '$secondaryIssue' },
|
|
161
197
|
},
|
|
162
|
-
}
|
|
198
|
+
},
|
|
199
|
+
];
|
|
200
|
+
if ( req.body.filterIssue && req.body.filterIssue !== '' ) {
|
|
201
|
+
query.push( {
|
|
202
|
+
$match: {
|
|
203
|
+
primaryIssue: req.body.filterIssue,
|
|
204
|
+
},
|
|
205
|
+
} );
|
|
206
|
+
}
|
|
207
|
+
if ( req.body.searchValue && req.body.searchValue !== '' ) {
|
|
208
|
+
query.push( {
|
|
209
|
+
$match: {
|
|
210
|
+
$or: [
|
|
211
|
+
{ storeId: { $regex: req.body.searchValue, $options: 'i' } },
|
|
212
|
+
{ storeName: { $regex: req.body.searchValue, $options: 'i' } },
|
|
213
|
+
],
|
|
214
|
+
},
|
|
215
|
+
} );
|
|
216
|
+
}
|
|
217
|
+
if ( req.body.sortColumName && req.body.sortColumName !== '' && req.body.sortBy ) {
|
|
218
|
+
query.push( {
|
|
219
|
+
$sort: { [req.body.sortColumName]: req.body.sortBy },
|
|
220
|
+
} );
|
|
221
|
+
}
|
|
163
222
|
let count = await aggregateTangoTicket( query );
|
|
164
223
|
if ( req.body.limit && req.body.offset && !req.body.export ) {
|
|
165
224
|
query.push(
|
|
@@ -168,17 +227,112 @@ export async function infraIssuesTable( req, res ) {
|
|
|
168
227
|
);
|
|
169
228
|
}
|
|
170
229
|
let result = await aggregateTangoTicket( query );
|
|
230
|
+
if ( req.body.export ) {
|
|
231
|
+
const exportdata = [];
|
|
232
|
+
result.forEach( ( element ) => {
|
|
233
|
+
exportdata.push( {
|
|
234
|
+
'STORE ID': element.storeId,
|
|
235
|
+
'STORE NAME': element.storeName,
|
|
236
|
+
'STATUS': element.status,
|
|
237
|
+
'CITY': element.city,
|
|
238
|
+
'STATE': element.state,
|
|
239
|
+
'COUNTRY': element.country,
|
|
240
|
+
'SPOC EMAIL': element.spocEmail,
|
|
241
|
+
'SPOC CONTACT': element.spocContact,
|
|
242
|
+
'DOWNTIME': element.downTime,
|
|
243
|
+
'STATUS DETAIL': element.statusDetail,
|
|
244
|
+
} );
|
|
245
|
+
} );
|
|
246
|
+
await download( exportdata, res );
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
if ( result.length > 0 ) {
|
|
250
|
+
res.sendSuccess( {
|
|
251
|
+
count: count.length,
|
|
252
|
+
result: result,
|
|
253
|
+
} );
|
|
254
|
+
} else {
|
|
255
|
+
res.sendError( 'no data', 204 );
|
|
256
|
+
}
|
|
257
|
+
} catch ( error ) {
|
|
258
|
+
logger.error( { error: error, function: 'infraIssuesTable' } );
|
|
259
|
+
return res.sendError( error, 500 );
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
export async function InstallationIssuesTable( req, res ) {
|
|
263
|
+
try {
|
|
264
|
+
let query = [
|
|
265
|
+
{
|
|
266
|
+
$match: {
|
|
267
|
+
$and: [
|
|
268
|
+
{ issueType: 'installation' },
|
|
269
|
+
{ 'basicDetails.clientId': { $in: req.body.clientId } },
|
|
270
|
+
{ createdAt: { $gte: new Date( req.body.fromDate ) } },
|
|
271
|
+
// { createdAt: { $lte: new Date( req.body.toDate ) } },
|
|
272
|
+
],
|
|
273
|
+
},
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
$project: {
|
|
277
|
+
createdAt: 1,
|
|
278
|
+
clientName: '$basicDetails.clientName',
|
|
279
|
+
storeId: '$basicDetails.storeId',
|
|
280
|
+
storeName: '$basicDetails.storeName',
|
|
281
|
+
status: '$basicDetails.status',
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
];
|
|
285
|
+
if ( req.body.searchValue && req.body.searchValue !== '' ) {
|
|
286
|
+
query.push( {
|
|
287
|
+
$match: {
|
|
288
|
+
$or: [
|
|
289
|
+
{ storeId: { $regex: req.body.searchValue, $options: 'i' } },
|
|
290
|
+
{ storeName: { $regex: req.body.searchValue, $options: 'i' } },
|
|
291
|
+
{ clientName: { $regex: req.body.searchValue, $options: 'i' } },
|
|
292
|
+
{ status: { $regex: req.body.searchValue, $options: 'i' } },
|
|
293
|
+
],
|
|
294
|
+
},
|
|
295
|
+
} );
|
|
296
|
+
}
|
|
297
|
+
if ( req.body.sortColumName && req.body.sortColumName !== '' && req.body.sortBy ) {
|
|
298
|
+
query.push( {
|
|
299
|
+
$sort: { [req.body.sortColumName]: req.body.sortBy },
|
|
300
|
+
} );
|
|
301
|
+
}
|
|
302
|
+
let count = await aggregateTangoTicket( query );
|
|
303
|
+
if ( req.body.limit && req.body.offset && !req.body.export ) {
|
|
304
|
+
query.push(
|
|
305
|
+
{ $skip: ( req.body.offset - 1 ) * req.body.limit },
|
|
306
|
+
{ $limit: Number( req.body.limit ) },
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
let storesList = await aggregateTangoTicket( query );
|
|
310
|
+
if ( storesList.length == 0 ) {
|
|
311
|
+
return res.sendError( 'no data', 204 );
|
|
312
|
+
}
|
|
313
|
+
if ( req.body.export ) {
|
|
314
|
+
const exportdata = [];
|
|
315
|
+
infrastoreList.forEach( ( element ) => {
|
|
316
|
+
exportdata.push( {
|
|
317
|
+
'CLIENT NAME': element.clientName,
|
|
318
|
+
'STORE ID': element.storeId,
|
|
319
|
+
'STORE NAME': element.storeName,
|
|
320
|
+
'STATUS': element.status,
|
|
321
|
+
} );
|
|
322
|
+
} );
|
|
323
|
+
await download( exportdata, res );
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
171
326
|
res.sendSuccess( {
|
|
172
327
|
count: count.length,
|
|
173
|
-
result:
|
|
328
|
+
result: storesList,
|
|
174
329
|
} );
|
|
175
330
|
} catch ( error ) {
|
|
176
|
-
logger.error( { error: error, function: '
|
|
331
|
+
logger.error( { error: error, function: 'InstallationIssuesTable' } );
|
|
177
332
|
return res.sendError( error, 500 );
|
|
178
333
|
}
|
|
179
334
|
}
|
|
180
335
|
|
|
181
|
-
|
|
182
336
|
export async function hourWiseDownClients( req, res ) {
|
|
183
337
|
try {
|
|
184
338
|
let inputData = req.body;
|
|
@@ -24,16 +24,8 @@ export async function createTicket( req, res ) {
|
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
|
|
28
27
|
export async function updateStatus( req, res ) {
|
|
29
28
|
try {
|
|
30
|
-
if ( req.body.status == 'closed' ) {
|
|
31
|
-
req.body.issueClosedDate = new Date();
|
|
32
|
-
req.body.infraActivity.push( {
|
|
33
|
-
actionType: 'dataRecived',
|
|
34
|
-
actionBy: 'Tango',
|
|
35
|
-
} );
|
|
36
|
-
}
|
|
37
29
|
if ( req.body.status == 'inprogress' ) {
|
|
38
30
|
req.body.infraActivity.push( {
|
|
39
31
|
actionType: 'statusChange',
|
|
@@ -68,7 +60,7 @@ export async function PrimaryReasons( req, res ) {
|
|
|
68
60
|
try {
|
|
69
61
|
let list = await findinfraReason( { parentId: { $exists: false } }, { name: 1, order: 1 } );
|
|
70
62
|
if ( list.length > 0 ) {
|
|
71
|
-
res.
|
|
63
|
+
res.sendSuccess( {
|
|
72
64
|
count: list.length,
|
|
73
65
|
result: list,
|
|
74
66
|
} );
|
|
@@ -120,3 +112,17 @@ export async function viewTicket( req, res ) {
|
|
|
120
112
|
return res.sendError( error, 500 );
|
|
121
113
|
}
|
|
122
114
|
}
|
|
115
|
+
export async function AlertTicketReply( req, res ) {
|
|
116
|
+
try {
|
|
117
|
+
req.body.infraActivity = req.body.infraActivity.filter( ( data ) => data.action !='statusCheck' );
|
|
118
|
+
req.body.infraActivity.push( {
|
|
119
|
+
actionType: 'statusCheckReply',
|
|
120
|
+
actionBy: 'Tango',
|
|
121
|
+
statusCheckReply: req.body.statusCheckReply,
|
|
122
|
+
hibernationDays: req.body.hibernationDays,
|
|
123
|
+
} );
|
|
124
|
+
} catch ( error ) {
|
|
125
|
+
logger.error( { error: error, function: 'AlertTicketReply' } );
|
|
126
|
+
return res.sendError( error, 500 );
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -3,7 +3,7 @@ import { logger } from 'tango-app-api-middleware';
|
|
|
3
3
|
import dayjs from 'dayjs';
|
|
4
4
|
import { createClient, findClient } from '../services/client.service.js';
|
|
5
5
|
import { createStore, findStore, updateOneStore } from '../services/store.service.js';
|
|
6
|
-
import { findTangoTicket, updateOneTangoTicket } from '../services/tangoTicket.service.js';
|
|
6
|
+
import { findTangoTicket, findOneTangoTicket, updateOneTangoTicket } from '../services/tangoTicket.service.js';
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
export async function migrateClient() {
|
|
@@ -51,8 +51,6 @@ export async function migrateStores() {
|
|
|
51
51
|
close: oldstores[i].configuration.storeCloseTime,
|
|
52
52
|
timeZone: oldstores[i].timezone,
|
|
53
53
|
},
|
|
54
|
-
|
|
55
|
-
|
|
56
54
|
};
|
|
57
55
|
|
|
58
56
|
await createStore( framedStores );
|
|
@@ -116,7 +114,7 @@ export async function openTicketList( req, res ) {
|
|
|
116
114
|
try {
|
|
117
115
|
let openTicketList = await findTangoTicket( { status: { $ne: 'closed' } }, { ticketId: 1, basicDetails: 1, createdAt: 1, updateAt: 1, infraTicketDetails: 1 } );
|
|
118
116
|
if ( openTicketList.length ) {
|
|
119
|
-
res.
|
|
117
|
+
res.sendSuccess( {
|
|
120
118
|
count: openTicketList.length,
|
|
121
119
|
data: openTicketList,
|
|
122
120
|
} );
|
|
@@ -147,3 +145,27 @@ export async function updateRefreshTicket( req, res ) {
|
|
|
147
145
|
res.sendError( error, 500 );
|
|
148
146
|
}
|
|
149
147
|
}
|
|
148
|
+
export async function closeTicket( req, res ) {
|
|
149
|
+
try {
|
|
150
|
+
for ( let ticket of req.body.TicketList ) {
|
|
151
|
+
let getTicket = await findOneTangoTicket( { ticketId: ticket.ticketId } );
|
|
152
|
+
if ( ticket.status == 'closed' ) {
|
|
153
|
+
getTicket.infraActivity.push( {
|
|
154
|
+
actionType: 'dataRecived',
|
|
155
|
+
actionBy: 'Tango',
|
|
156
|
+
} );
|
|
157
|
+
}
|
|
158
|
+
await updateOneTangoTicket( { ticketId: ticket.ticketId },
|
|
159
|
+
{
|
|
160
|
+
status: ticket.status,
|
|
161
|
+
infraActivity: getTicket.infraActivity,
|
|
162
|
+
issueClosedDate: new Date(),
|
|
163
|
+
},
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
res.sendSuccess( 'updated Successfully' );
|
|
167
|
+
} catch ( error ) {
|
|
168
|
+
logger.error( { error: error, function: 'closeTicket' } );
|
|
169
|
+
res.sendError( error, 500 );
|
|
170
|
+
}
|
|
171
|
+
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
|
|
2
2
|
import { findOneTangoTicket, updateOneTangoTicket, aggregateTangoTicket, countDocumentsTangoTicket } from '../services/tangoTicket.service.js';
|
|
3
|
-
import { logger } from 'tango-app-api-middleware';
|
|
3
|
+
import { logger, download } from 'tango-app-api-middleware';
|
|
4
4
|
import { findOneUser } from '../services/user.service.js';
|
|
5
|
+
import { aggregateStore } from '../services/store.service.js';
|
|
6
|
+
|
|
5
7
|
import mongoose from 'mongoose';
|
|
6
8
|
|
|
7
9
|
export async function userTakeTicket( req, res ) {
|
|
@@ -24,11 +26,34 @@ export async function userTicketList( req, res ) {
|
|
|
24
26
|
try {
|
|
25
27
|
let query = [ {
|
|
26
28
|
$match: {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
$and: [
|
|
30
|
+
{ 'status': req.body.status },
|
|
31
|
+
{ 'infraTicketDetails.addressingUser': new mongoose.Types.ObjectId( req.body.userId ) },
|
|
32
|
+
],
|
|
29
33
|
},
|
|
30
|
-
}
|
|
31
|
-
|
|
34
|
+
} ];
|
|
35
|
+
|
|
36
|
+
if ( req.body.status != 'closed' ) {
|
|
37
|
+
query.push( {
|
|
38
|
+
$match: {
|
|
39
|
+
$and: [
|
|
40
|
+
{ createdAt: { $gte: new Date( req.body.fromDate ) } },
|
|
41
|
+
{ createdAt: { $lte: new Date( req.body.toDate ) } },
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
} );
|
|
45
|
+
} else {
|
|
46
|
+
query.push( {
|
|
47
|
+
$match: {
|
|
48
|
+
$and: [
|
|
49
|
+
{ createdAt: { $gte: new Date() } },
|
|
50
|
+
],
|
|
51
|
+
},
|
|
52
|
+
} );
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
query.push( {
|
|
32
57
|
$project: {
|
|
33
58
|
storeId: '$basicDetails.storeId',
|
|
34
59
|
Date: { $dateToString: { format: '%d-%m-%Y', date: '$issueDate' } },
|
|
@@ -62,7 +87,7 @@ export async function userTicketList( req, res ) {
|
|
|
62
87
|
ticketType: 1,
|
|
63
88
|
infraIssue: '$primaryIssue.reasons.primaryIssue',
|
|
64
89
|
},
|
|
65
|
-
}
|
|
90
|
+
} );
|
|
66
91
|
let ticketList = await aggregateTangoTicket( query );
|
|
67
92
|
if ( ticketList.length ) {
|
|
68
93
|
res.sendSuccess( {
|
|
@@ -106,8 +131,12 @@ export async function workHistory( req, res ) {
|
|
|
106
131
|
try {
|
|
107
132
|
let query = [ {
|
|
108
133
|
$match: {
|
|
109
|
-
|
|
110
|
-
|
|
134
|
+
$and: [
|
|
135
|
+
{ 'status': 'closed' },
|
|
136
|
+
{ 'infraTicketDetails.addressingUser': new mongoose.Types.ObjectId( req.body.userId ) },
|
|
137
|
+
{ createdAt: { $gte: new Date( req.body.fromDate ) } },
|
|
138
|
+
{ createdAt: { $lte: new Date( req.body.toDate ) } },
|
|
139
|
+
],
|
|
111
140
|
},
|
|
112
141
|
},
|
|
113
142
|
{
|
|
@@ -118,6 +147,7 @@ export async function workHistory( req, res ) {
|
|
|
118
147
|
clientName: '$basicDetails.clientName',
|
|
119
148
|
issueDate: { $dateToString: { format: '%d-%m-%Y', date: '$issueDate' } },
|
|
120
149
|
issueClosedDate: { $dateToString: { format: '%d-%m-%Y', date: '$issueClosedDate' } },
|
|
150
|
+
issueIdentifiedDate: { $dateToString: { format: '%d-%m-%Y', date: '$infraTicketDetails.issueIdentifiedDate' } },
|
|
121
151
|
ticketId: 1,
|
|
122
152
|
issueStatus: '$infraTicketDetails.issueStatus',
|
|
123
153
|
ticketType: '$infraTicketDetails.ticketType',
|
|
@@ -146,6 +176,7 @@ export async function workHistory( req, res ) {
|
|
|
146
176
|
clientId: 1,
|
|
147
177
|
clientName: 1,
|
|
148
178
|
issueDate: 1,
|
|
179
|
+
issueIdentifiedDate: 1,
|
|
149
180
|
issueClosedDate: 1,
|
|
150
181
|
ticketId: 1,
|
|
151
182
|
issueStatus: 1,
|
|
@@ -153,6 +184,25 @@ export async function workHistory( req, res ) {
|
|
|
153
184
|
infraIssue: { $ifNull: [ '$primaryIssue.reasons.primaryIssue', '' ] },
|
|
154
185
|
},
|
|
155
186
|
} ];
|
|
187
|
+
if ( req.body.searchValue && req.body.searchValue !== '' ) {
|
|
188
|
+
query.push( {
|
|
189
|
+
$match: {
|
|
190
|
+
$or: [
|
|
191
|
+
{ storeId: { $regex: req.body.searchValue, $options: 'i' } },
|
|
192
|
+
{ storeName: { $regex: req.body.searchValue, $options: 'i' } },
|
|
193
|
+
{ clientId: { $regex: req.body.searchValue, $options: 'i' } },
|
|
194
|
+
{ clientName: { $regex: req.body.searchValue, $options: 'i' } },
|
|
195
|
+
{ ticketId: { $regex: req.body.searchValue, $options: 'i' } },
|
|
196
|
+
{ infraIssue: { $regex: req.body.searchValue, $options: 'i' } },
|
|
197
|
+
],
|
|
198
|
+
},
|
|
199
|
+
} );
|
|
200
|
+
}
|
|
201
|
+
if ( req.body.sortColumName && req.body.sortColumName !== '' && req.body.sortBy ) {
|
|
202
|
+
query.push( {
|
|
203
|
+
$sort: { [req.body.sortColumName]: req.body.sortBy },
|
|
204
|
+
} );
|
|
205
|
+
}
|
|
156
206
|
let count = await aggregateTangoTicket( query );
|
|
157
207
|
if ( req.body.limit && req.body.offset && !req.body.export ) {
|
|
158
208
|
query.push(
|
|
@@ -161,6 +211,28 @@ export async function workHistory( req, res ) {
|
|
|
161
211
|
);
|
|
162
212
|
}
|
|
163
213
|
let result = await aggregateTangoTicket( query );
|
|
214
|
+
if ( req.body.export ) {
|
|
215
|
+
const exportdata = [];
|
|
216
|
+
result.forEach( ( element ) => {
|
|
217
|
+
exportdata.push( {
|
|
218
|
+
'CREATED ON': element.createdAt,
|
|
219
|
+
'TICKET ID': element.ticketId,
|
|
220
|
+
'STORE ID': element.storeId,
|
|
221
|
+
'STORE NAME': element.storeName,
|
|
222
|
+
'CLIENT ID': element.clientId,
|
|
223
|
+
'CLIENT NAME': element.clientName,
|
|
224
|
+
'CREATED STATUS': element.status,
|
|
225
|
+
'ISSUE IDENTIFIED DATE': element.issueIdentifiedDate,
|
|
226
|
+
'CLOSED ON': element.issueClosedDate,
|
|
227
|
+
'STATUS': element.status,
|
|
228
|
+
} );
|
|
229
|
+
} );
|
|
230
|
+
await download( exportdata, res );
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
if ( result.length == 0 ) {
|
|
234
|
+
return res.sendError( 'no data', 204 );
|
|
235
|
+
}
|
|
164
236
|
res.sendSuccess( {
|
|
165
237
|
count: count.length,
|
|
166
238
|
result: result,
|
|
@@ -171,3 +243,115 @@ export async function workHistory( req, res ) {
|
|
|
171
243
|
}
|
|
172
244
|
}
|
|
173
245
|
|
|
246
|
+
|
|
247
|
+
export async function storeInfraList( req, res ) {
|
|
248
|
+
try {
|
|
249
|
+
let query = [
|
|
250
|
+
{
|
|
251
|
+
$match: {
|
|
252
|
+
$and: [
|
|
253
|
+
{ clientId: { $in: req.body.clientId } },
|
|
254
|
+
{ createdAt: { $lte: new Date( req.body.toDate ) } },
|
|
255
|
+
],
|
|
256
|
+
},
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
$project: {
|
|
260
|
+
storeId: 1,
|
|
261
|
+
storeName: 1,
|
|
262
|
+
storeProfile: 1,
|
|
263
|
+
status: 1,
|
|
264
|
+
spocDetails: 1,
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
$unwind: {
|
|
269
|
+
path: '$spocDetails', preserveNullAndEmptyArrays: true,
|
|
270
|
+
},
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
$group: {
|
|
274
|
+
_id: '$storeId',
|
|
275
|
+
storeId: { $first: '$storeId' },
|
|
276
|
+
storeName: { $first: '$storeName' },
|
|
277
|
+
status: { $first: '$status' },
|
|
278
|
+
city: { $first: '$storeProfile.city' },
|
|
279
|
+
state: { $first: '$storeProfile.state' },
|
|
280
|
+
country: { $first: '$storeProfile.country' },
|
|
281
|
+
spocEmail: { $first: { $ifNull: [ '$spocDetails.email', '' ] } },
|
|
282
|
+
spocContact: { $first: { $ifNull: [ '$spocDetails.contact', '' ] } },
|
|
283
|
+
},
|
|
284
|
+
},
|
|
285
|
+
];
|
|
286
|
+
|
|
287
|
+
if ( req.body.searchValue && req.body.searchValue !== '' ) {
|
|
288
|
+
query.push( {
|
|
289
|
+
$match: {
|
|
290
|
+
$or: [
|
|
291
|
+
{ storeId: { $regex: req.body.searchValue, $options: 'i' } },
|
|
292
|
+
{ storeName: { $regex: req.body.searchValue, $options: 'i' } },
|
|
293
|
+
],
|
|
294
|
+
},
|
|
295
|
+
} );
|
|
296
|
+
}
|
|
297
|
+
if ( req.body.sortColumName && req.body.sortColumName !== '' && req.body.sortBy ) {
|
|
298
|
+
query.push( {
|
|
299
|
+
$sort: { [req.body.sortColumName]: req.body.sortBy },
|
|
300
|
+
} );
|
|
301
|
+
}
|
|
302
|
+
let count = await aggregateStore( query );
|
|
303
|
+
if ( req.body.limit && req.body.offset && !req.body.export ) {
|
|
304
|
+
query.push(
|
|
305
|
+
{ $skip: ( req.body.offset - 1 ) * req.body.limit },
|
|
306
|
+
{ $limit: Number( req.body.limit ) },
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
let storesList = await aggregateStore( query );
|
|
310
|
+
if ( storesList.length == 0 ) {
|
|
311
|
+
return res.sendError( 'no data', 204 );
|
|
312
|
+
}
|
|
313
|
+
let infrastoreList = [];
|
|
314
|
+
for ( let store of storesList ) {
|
|
315
|
+
store.downTime = 'NA';
|
|
316
|
+
let infracheck = await findOneTangoTicket( { 'basicDetails.storeId': store.storeId, 'issueDate': new Date() } );
|
|
317
|
+
if ( infracheck ) {
|
|
318
|
+
store.status = 'Infra Issue';
|
|
319
|
+
} else {
|
|
320
|
+
if ( store.status == 'active' ) {
|
|
321
|
+
store.status = 'Live';
|
|
322
|
+
store.statusDetail = 'Connected';
|
|
323
|
+
} else {
|
|
324
|
+
store.statusDetail = 'Disconnected';
|
|
325
|
+
store.status = 'Deactivated';
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
infrastoreList.push( store );
|
|
329
|
+
}
|
|
330
|
+
if ( req.body.export ) {
|
|
331
|
+
const exportdata = [];
|
|
332
|
+
infrastoreList.forEach( ( element ) => {
|
|
333
|
+
exportdata.push( {
|
|
334
|
+
'STORE ID': element.storeId,
|
|
335
|
+
'STORE NAME': element.storeName,
|
|
336
|
+
'STATUS': element.status,
|
|
337
|
+
'CITY': element.city,
|
|
338
|
+
'STATE': element.state,
|
|
339
|
+
'COUNTRY': element.country,
|
|
340
|
+
'SPOC EMAIL': element.spocEmail,
|
|
341
|
+
'SPOC CONTACT': element.spocContact,
|
|
342
|
+
'DOWNTIME': element.downTime,
|
|
343
|
+
'STATUS DETAIL': element.statusDetail,
|
|
344
|
+
} );
|
|
345
|
+
} );
|
|
346
|
+
await download( exportdata, res );
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
res.sendSuccess( {
|
|
350
|
+
count: count.length,
|
|
351
|
+
result: infrastoreList,
|
|
352
|
+
} );
|
|
353
|
+
} catch ( error ) {
|
|
354
|
+
logger.error( { error: error, function: 'storeInfraList' } );
|
|
355
|
+
return res.sendError( error, 500 );
|
|
356
|
+
}
|
|
357
|
+
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
|
|
2
2
|
import express from 'express';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import { infraCard, infraIssuesTable, hourWiseDownClients, hourWiseDownstores } from '../controllers/clientInfra.controller.js';
|
|
3
|
+
import { isAllowedSessionHandler } from 'tango-app-api-middleware';
|
|
4
|
+
import { infraCard, InstallationIssuesTable, infraIssuesTable, hourWiseDownClients, hourWiseDownstores } from '../controllers/clientInfra.controller.js';
|
|
6
5
|
|
|
7
6
|
export const clientInfraRouter = express.Router();
|
|
8
7
|
|
|
9
8
|
|
|
10
|
-
clientInfraRouter.post( '/infraCard', infraCard );
|
|
11
|
-
clientInfraRouter.post( '/infraIssuesTable', infraIssuesTable );
|
|
12
|
-
clientInfraRouter.post( '/
|
|
13
|
-
clientInfraRouter.post( '/
|
|
9
|
+
clientInfraRouter.post( '/infraCard', isAllowedSessionHandler, infraCard );
|
|
10
|
+
clientInfraRouter.post( '/infraIssuesTable', isAllowedSessionHandler, infraIssuesTable );
|
|
11
|
+
clientInfraRouter.post( '/InstallationIssuesTable', isAllowedSessionHandler, InstallationIssuesTable );
|
|
12
|
+
clientInfraRouter.post( '/hourWiseDownClients', isAllowedSessionHandler, hourWiseDownClients );
|
|
13
|
+
clientInfraRouter.post( '/hourWiseDownstores', isAllowedSessionHandler, hourWiseDownstores );
|
|
14
14
|
|
|
15
15
|
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
|
|
2
2
|
import express from 'express';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { isAllowedSessionHandler } from 'tango-app-api-middleware';
|
|
4
|
+
import { validateDetails, validateTicket, ticketExists, infraReasonExists, InfrastepstoResolve, InfraAlert } from '../validations/infra.validation.js';
|
|
5
|
+
import { createTicket, updateStatus, createReason, PrimaryReasons, secondaryReason, updateTicketIssue, viewTicket, AlertTicketReply } from '../controllers/infra.controllers.js';
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
export const infraRouter = express.Router();
|
|
8
9
|
|
|
9
10
|
infraRouter.post( '/createTicket', validateDetails, validateTicket, createTicket );
|
|
10
|
-
infraRouter.post( '/updateStatus', ticketExists, updateStatus );
|
|
11
|
+
infraRouter.post( '/updateStatus', isAllowedSessionHandler, ticketExists, updateStatus );
|
|
11
12
|
infraRouter.post( '/createReason', createReason );
|
|
12
|
-
infraRouter.get( '/PrimaryReasons', PrimaryReasons );
|
|
13
|
-
infraRouter.post( '/secondaryReason', secondaryReason );
|
|
14
|
-
infraRouter.post( '/updateTicketIssue', ticketExists, infraReasonExists, InfrastepstoResolve, updateTicketIssue );
|
|
15
|
-
infraRouter.post( '/viewTicket', ticketExists, viewTicket );
|
|
13
|
+
infraRouter.get( '/PrimaryReasons', isAllowedSessionHandler, PrimaryReasons );
|
|
14
|
+
infraRouter.post( '/secondaryReason', isAllowedSessionHandler, secondaryReason );
|
|
15
|
+
infraRouter.post( '/updateTicketIssue', isAllowedSessionHandler, ticketExists, infraReasonExists, InfrastepstoResolve, InfraAlert, updateTicketIssue );
|
|
16
|
+
infraRouter.post( '/viewTicket', isAllowedSessionHandler, ticketExists, viewTicket );
|
|
17
|
+
infraRouter.post( '/AlertTicketReply', isAllowedSessionHandler, ticketExists, AlertTicketReply );
|
|
16
18
|
|
|
17
19
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import express from 'express';
|
|
3
3
|
import {
|
|
4
4
|
migrateClient, migrateStores, basicList, clientList, setTicketTime, downStoresList,
|
|
5
|
-
openTicketList, assigntoUser, updateRefreshTicket,
|
|
5
|
+
openTicketList, assigntoUser, updateRefreshTicket, closeTicket,
|
|
6
6
|
} from '../controllers/internalInfra.controller.js';
|
|
7
7
|
|
|
8
8
|
export const internalInfraRouter = express.Router();
|
|
@@ -16,4 +16,6 @@ internalInfraRouter.post( '/downStoresList', downStoresList );
|
|
|
16
16
|
internalInfraRouter.get( '/openTicketList', openTicketList );
|
|
17
17
|
internalInfraRouter.post( '/assigntoUser', assigntoUser );
|
|
18
18
|
internalInfraRouter.post( '/updateRefreshTicket', updateRefreshTicket );
|
|
19
|
+
internalInfraRouter.post( '/closeTicket', closeTicket );
|
|
20
|
+
|
|
19
21
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
|
|
2
2
|
import express from 'express';
|
|
3
|
+
import { isAllowedSessionHandler } from 'tango-app-api-middleware';
|
|
3
4
|
import { storeTicketList, storeTicketcard, edgeAppLogTable, viewedgeAppLog } from '../controllers/storeInfra.controlller.js';
|
|
4
5
|
export const storeInfraRouter = express.Router();
|
|
5
6
|
|
|
6
|
-
storeInfraRouter.post( '/storeTicketList', storeTicketList );
|
|
7
|
-
storeInfraRouter.post( '/storeTicketcard', storeTicketcard );
|
|
8
|
-
storeInfraRouter.post( '/edgeAppLogTable', edgeAppLogTable );
|
|
9
|
-
storeInfraRouter.post( '/viewedgeAppLog', viewedgeAppLog );
|
|
7
|
+
storeInfraRouter.post( '/storeTicketList', isAllowedSessionHandler, storeTicketList );
|
|
8
|
+
storeInfraRouter.post( '/storeTicketcard', isAllowedSessionHandler, storeTicketcard );
|
|
9
|
+
storeInfraRouter.post( '/edgeAppLogTable', isAllowedSessionHandler, edgeAppLogTable );
|
|
10
|
+
storeInfraRouter.post( '/viewedgeAppLog', isAllowedSessionHandler, viewedgeAppLog );
|
|
10
11
|
|
|
11
12
|
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import express from 'express';
|
|
2
|
-
import {
|
|
2
|
+
import { isAllowedSessionHandler } from 'tango-app-api-middleware';
|
|
3
|
+
import { userTakeTicket, userTicketList, basicDetails, workHistory, storeInfraList } from '../controllers/userInfra.controller.js';
|
|
3
4
|
|
|
4
5
|
export const userInfraRouter = express.Router();
|
|
5
6
|
|
|
6
7
|
|
|
7
|
-
userInfraRouter.post( '/userTakeTicket', userTakeTicket );
|
|
8
|
-
userInfraRouter.post( '/userTicketList', userTicketList );
|
|
9
|
-
userInfraRouter.post( '/basicDetails', basicDetails );
|
|
10
|
-
userInfraRouter.post( '/workHistory', workHistory );
|
|
8
|
+
userInfraRouter.post( '/userTakeTicket', isAllowedSessionHandler, userTakeTicket );
|
|
9
|
+
userInfraRouter.post( '/userTicketList', isAllowedSessionHandler, userTicketList );
|
|
10
|
+
userInfraRouter.post( '/basicDetails', isAllowedSessionHandler, basicDetails );
|
|
11
|
+
userInfraRouter.post( '/workHistory', isAllowedSessionHandler, workHistory );
|
|
12
|
+
userInfraRouter.post( '/storeInfraList', isAllowedSessionHandler, storeInfraList );
|
|
11
13
|
|
|
12
14
|
|
|
@@ -20,3 +20,6 @@ export async function updateOneStore( query, data ) {
|
|
|
20
20
|
export async function countDocumentsStore( query ) {
|
|
21
21
|
return await dataModel.storeModel.countDocuments( query );
|
|
22
22
|
}
|
|
23
|
+
export async function aggregateStore( query ) {
|
|
24
|
+
return await dataModel.storeModel.aggregate( query );
|
|
25
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import dayjs from 'dayjs';
|
|
2
|
-
import { findOneTangoTicket } from '../services/tangoTicket.service.js';
|
|
2
|
+
import { findOneTangoTicket, updateOneTangoTicket } from '../services/tangoTicket.service.js';
|
|
3
3
|
import { findOneClient } from '../services/client.service.js';
|
|
4
|
-
import { findOneStore } from '../services/store.service.js';
|
|
4
|
+
import { findOneStore, updateOneStore } from '../services/store.service.js';
|
|
5
5
|
import { findOneinfraReason } from '../services/infraReason.service.js';
|
|
6
6
|
import { logger } from 'tango-app-api-middleware';
|
|
7
7
|
|
|
@@ -34,14 +34,16 @@ export async function validateDetails( req, res, next ) {
|
|
|
34
34
|
|
|
35
35
|
export async function validateTicket( req, res, next ) {
|
|
36
36
|
try {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
37
|
+
if ( req.body.issueType == 'infra' ) {
|
|
38
|
+
let Ticket = await findOneTangoTicket(
|
|
39
|
+
{
|
|
40
|
+
'basicDetails.storeId': req.body.basicDetails.storeId,
|
|
41
|
+
'issueDate': new Date( req.body.Date ),
|
|
42
|
+
},
|
|
43
|
+
);
|
|
44
|
+
if ( Ticket ) {
|
|
45
|
+
return res.sendSuccess( 'Ticket Already Exists for the day' );
|
|
46
|
+
}
|
|
45
47
|
}
|
|
46
48
|
next();
|
|
47
49
|
} catch ( error ) {
|
|
@@ -59,6 +61,7 @@ export async function ticketExists( req, res, next ) {
|
|
|
59
61
|
if ( !Ticket ) {
|
|
60
62
|
return res.sendError( 'Ticket Not Found', 204 );
|
|
61
63
|
}
|
|
64
|
+
req.body.basicDetails = Ticket.basicDetails;
|
|
62
65
|
req.body.infraActivity = Ticket.infraActivity;
|
|
63
66
|
next();
|
|
64
67
|
} catch ( error ) {
|
|
@@ -136,7 +139,37 @@ export async function InfrastepstoResolve( req, res, next ) {
|
|
|
136
139
|
} );
|
|
137
140
|
next();
|
|
138
141
|
} catch ( error ) {
|
|
139
|
-
logger.error( { error: error, function: '
|
|
142
|
+
logger.error( { error: error, function: 'InfrastepstoResolve' } );
|
|
140
143
|
return res.sendError( error, 500 );
|
|
141
144
|
}
|
|
142
145
|
};
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
export async function InfraAlert( req, res, next ) {
|
|
149
|
+
try {
|
|
150
|
+
if ( req.body.hibernationDays ) {
|
|
151
|
+
req.body.hibernationDays = dayjs().add( req.body.hibernationDays, 'days' ).format( 'YYYY-MM-DD' );
|
|
152
|
+
await updateOneStore( { storeId: req.body.basicDetails.storeId }, { 'ticketConfigs.hibernation': new Date( req.body.hibernationDays ) } );
|
|
153
|
+
req.body.infraActivity.push( {
|
|
154
|
+
actionType: 'statusCheckReply',
|
|
155
|
+
actionBy: 'Tango',
|
|
156
|
+
hibernationDays: req.body.hibernationDays,
|
|
157
|
+
} );
|
|
158
|
+
await updateOneTangoTicket( { ticketId: req.body.ticketId }, { 'hibernation': new Date( req.body.hibernationDays ) } );
|
|
159
|
+
} else {
|
|
160
|
+
let client = await findOneClient( { clientId: req.body.basicDetails.clientId }, { ticketConfigs: 1 } );
|
|
161
|
+
let statusCheckAlertTime = dayjs().add( client.ticketConfigs.statusCheckAlert, 'hours' ).format( 'YYYY-MM-DD hh:mm' );
|
|
162
|
+
req.body.infraActivity.push( {
|
|
163
|
+
actionType: 'statusCheck',
|
|
164
|
+
actionBy: 'Tango',
|
|
165
|
+
statusCheckAlertTime: statusCheckAlertTime,
|
|
166
|
+
} );
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
next();
|
|
170
|
+
} catch ( error ) {
|
|
171
|
+
logger.error( { error: error, function: 'InfraAlert' } );
|
|
172
|
+
return res.sendError( error, 500 );
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|