tango-app-api-infra 3.1.12 → 3.1.13
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/index.js +3 -2
- package/package.json +5 -3
- package/src/controllers/dataMismatch.controller.js +214 -3
- package/src/controllers/employeeTraning.controller.js +13 -0
- package/src/controllers/infra.controllers.js +240 -26
- package/src/controllers/internalInfra.controller.js +34 -41
- package/src/controllers/storeInfra.controlller.js +34 -5
- package/src/controllers/userInfra.controller.js +55 -9
- package/src/docs/infra.docs.js +28 -0
- package/src/dtos/infra.dtos.js +12 -0
- package/src/routes/dataMismatch.routes.js +16 -4
- package/src/routes/employeetrainig.routes.js +5 -1
- package/src/routes/infra.routes.js +8 -2
- package/src/services/camera.service.js +5 -0
- package/src/validations/infra.validation.js +3 -5
package/index.js
CHANGED
|
@@ -6,9 +6,10 @@ import { userInfraRouter } from './src/routes/userInfra.routes.js';
|
|
|
6
6
|
import { storeInfraRouter } from './src/routes/storeInfra.routes.js';
|
|
7
7
|
import { clientInfraRouter } from './src/routes/clientInfra.routes.js';
|
|
8
8
|
import { employeeTrainigRouter } from './src/routes/employeetrainig.routes.js';
|
|
9
|
-
import {
|
|
9
|
+
import { dataMismatchTicketRouter } from './src/routes/dataMismatch.routes.js';
|
|
10
|
+
import { infraDocs } from './src/docs/infra.docs.js';
|
|
10
11
|
|
|
11
12
|
|
|
12
|
-
export { infraRouter, internalInfraRouter, userInfraRouter, storeInfraRouter,
|
|
13
|
+
export { infraRouter, internalInfraRouter, userInfraRouter, storeInfraRouter, dataMismatchTicketRouter, clientInfraRouter, employeeTrainigRouter, infraDocs };
|
|
13
14
|
|
|
14
15
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tango-app-api-infra",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.13",
|
|
4
4
|
"description": "infra",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -22,10 +22,12 @@
|
|
|
22
22
|
"express-fileupload": "^1.5.0",
|
|
23
23
|
"handlebars": "^4.7.8",
|
|
24
24
|
"html-pdf-node": "^1.0.8",
|
|
25
|
+
"joi-to-swagger": "^6.2.0",
|
|
25
26
|
"mongodb": "^6.4.0",
|
|
26
27
|
"nodemon": "^3.1.0",
|
|
27
|
-
"
|
|
28
|
-
"tango-
|
|
28
|
+
"swagger-ui-express": "^5.0.0",
|
|
29
|
+
"tango-api-schema": "^2.0.103",
|
|
30
|
+
"tango-app-api-middleware": "^3.1.10",
|
|
29
31
|
"winston": "^3.12.0",
|
|
30
32
|
"winston-daily-rotate-file": "^5.0.0"
|
|
31
33
|
},
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
|
|
2
|
-
import { findOneTangoTicket, createTangoTicket } from '../services/tangoTicket.service.js';
|
|
3
|
-
import { logger } from 'tango-app-api-middleware';
|
|
2
|
+
import { findOneTangoTicket, createTangoTicket, updateOneTangoTicket, aggregateTangoTicket, countDocumentsTangoTicket } from '../services/tangoTicket.service.js';
|
|
3
|
+
import { logger, getUTC, appConfig, fileUpload, signedUrl, sendMessageToQueue } from 'tango-app-api-middleware';
|
|
4
|
+
import dayjs from 'dayjs';
|
|
5
|
+
|
|
4
6
|
export async function createTicket( req, res ) {
|
|
5
7
|
try {
|
|
6
8
|
let ticketExist = await findOneTangoTicket( { 'issueType': req.body.issueType, 'issueDate': ( new Date( req.body.Date ) ), 'basicDetails.storeId': req.body.storeId } );
|
|
@@ -8,11 +10,58 @@ export async function createTicket( req, res ) {
|
|
|
8
10
|
if ( ticketExist ) {
|
|
9
11
|
return res.sendSuccess( 'MAT Ticket Already Exists for the store' );
|
|
10
12
|
}
|
|
13
|
+
let actionBy = '';
|
|
14
|
+
if ( req.user.userType == 'tango' ) {
|
|
15
|
+
actionBy = 'Tango';
|
|
16
|
+
} else if ( req.user.userType == 'client' ) {
|
|
17
|
+
actionBy = 'User';
|
|
18
|
+
}
|
|
11
19
|
req.body.ticketDetails = {};
|
|
12
|
-
req.body.
|
|
20
|
+
req.body.dataMismatch ={
|
|
21
|
+
actualCount: req.body.actualCount,
|
|
22
|
+
expectedCount: req.body.expectedCount,
|
|
23
|
+
contactEmail: req.body.contactEmail,
|
|
24
|
+
};
|
|
13
25
|
req.body.issueDate = new Date( req.body.Date );
|
|
14
26
|
req.body.ticketId = 'TE_DM_' + new Date().valueOf();
|
|
15
27
|
let create = await createTangoTicket( req.body );
|
|
28
|
+
let getObject = {};
|
|
29
|
+
if ( req.files ) {
|
|
30
|
+
let params = {
|
|
31
|
+
Bucket: appConfig.cloud.aws.bucket.ticket,
|
|
32
|
+
Key: create.ticketId + '/',
|
|
33
|
+
ContentType: 'multipart/form-data',
|
|
34
|
+
body: req.files.img.data,
|
|
35
|
+
fileName: req.files.img.name,
|
|
36
|
+
};
|
|
37
|
+
let upload = await fileUpload( params );
|
|
38
|
+
if ( upload ) {
|
|
39
|
+
getObject = {
|
|
40
|
+
fileName: req.files.img.name,
|
|
41
|
+
filePath: create.ticketId + '/' + req.files.img.name,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
req.body.ticketActivity = [ {
|
|
46
|
+
actionType: 'Created',
|
|
47
|
+
timeStamp: new Date(),
|
|
48
|
+
actionBy: actionBy,
|
|
49
|
+
IdentifiedBy: req.user.userName,
|
|
50
|
+
description: req.body.description,
|
|
51
|
+
attachments: [ getObject ],
|
|
52
|
+
} ];
|
|
53
|
+
await updateOneTangoTicket( { ticketId: create.ticketId }, { ticketActivity: req.body.ticketActivity } );
|
|
54
|
+
|
|
55
|
+
const ticket = await findOneTangoTicket( { ticketId: req.body.ticketId }, { 'issueDate': 1, 'basicDetails': 1, 'issueType': 1, 'dataMismatch.contactEmail': 1, '_id': 0 } );
|
|
56
|
+
|
|
57
|
+
const obj = {
|
|
58
|
+
storeId: ticket.basicDetails.storeId,
|
|
59
|
+
issueDate: dayjs( ticket.issueDate ).format( 'DD-MM-YYYY' ),
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
if ( req.body.issueType === 'highcount' ) {
|
|
63
|
+
await sendMessageToQueue( `${appConfig.cloud.aws.sqs.url}${appConfig.cloud.aws.sqs.highcountTopic}`, JSON.stringify( obj ) );
|
|
64
|
+
}
|
|
16
65
|
if ( create ) {
|
|
17
66
|
res.sendSuccess( 'Ticket Created Successfully' );
|
|
18
67
|
}
|
|
@@ -21,3 +70,165 @@ export async function createTicket( req, res ) {
|
|
|
21
70
|
return res.sendError( error, 500 );
|
|
22
71
|
}
|
|
23
72
|
}
|
|
73
|
+
|
|
74
|
+
export async function updateMat( req, res ) {
|
|
75
|
+
try {
|
|
76
|
+
let updateValue = {};
|
|
77
|
+
if ( req.body.actionType && req.body.actionType != '' ) {
|
|
78
|
+
let actionBy = '';
|
|
79
|
+
if ( req.user.userType == 'tango' ) {
|
|
80
|
+
actionBy = 'Tango';
|
|
81
|
+
} else if ( req.user.userType == 'client' ) {
|
|
82
|
+
actionBy = 'User';
|
|
83
|
+
}
|
|
84
|
+
req.body.ticketActivity.push( {
|
|
85
|
+
actionType: req.body.actionType,
|
|
86
|
+
actionBy: actionBy,
|
|
87
|
+
timeStamp: new Date(),
|
|
88
|
+
IdentifiedBy: req.user.userName,
|
|
89
|
+
description: req.body.description,
|
|
90
|
+
attachments: req.body.attachments,
|
|
91
|
+
} );
|
|
92
|
+
updateValue = { ticketActivity: req.body.ticketActivity };
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
let updateTicket = await updateOneTangoTicket( { ticketId: req.body.ticketId }, updateValue );
|
|
96
|
+
if ( updateTicket ) {
|
|
97
|
+
res.sendSuccess( 'Ticket Updated Successfully' );
|
|
98
|
+
}
|
|
99
|
+
} catch ( error ) {
|
|
100
|
+
logger.error( { error: error, function: 'updateMat' } );
|
|
101
|
+
return res.sendError( error, 500 );
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
export async function activityList( req, res ) {
|
|
107
|
+
try {
|
|
108
|
+
let date = await getUTC( new Date( req.body.fromDate ), new Date( req.body.toDate ) );
|
|
109
|
+
let query = [ {
|
|
110
|
+
$match: {
|
|
111
|
+
$and: [
|
|
112
|
+
{ 'basicDetails.storeId': req.body.storeId },
|
|
113
|
+
{ issueType: { $in: [ 'lowcount', 'highcount' ] } },
|
|
114
|
+
{ createdAt: { $gte: date.start } },
|
|
115
|
+
{ createdAt: { $lte: date.end } },
|
|
116
|
+
],
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
$project: {
|
|
121
|
+
storeId: '$basicDetails.storeId',
|
|
122
|
+
status: 1,
|
|
123
|
+
issueDate: '$issueDate',
|
|
124
|
+
Date: { $dateToString: { format: '%d-%m-%Y', date: '$createdAt' } },
|
|
125
|
+
issueClosedDate: 1,
|
|
126
|
+
ticketId: 1,
|
|
127
|
+
issueType: 1,
|
|
128
|
+
ticketActivity: 1,
|
|
129
|
+
comments: { $size: '$ticketActivity' },
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
$unwind: {
|
|
134
|
+
path: '$ticketActivity', preserveNullAndEmptyArrays: true,
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
$group: {
|
|
139
|
+
_id: '$ticketId',
|
|
140
|
+
storeId: { $first: '$storeId' },
|
|
141
|
+
Date: { $first: '$Date' },
|
|
142
|
+
issueClosedDate: { $first: '$issueClosedDate' },
|
|
143
|
+
status: { $first: '$status' },
|
|
144
|
+
issueDate: { $first: '$issueDate' },
|
|
145
|
+
ticketId: { $first: '$ticketId' },
|
|
146
|
+
issueType: { $first: '$issueType' },
|
|
147
|
+
comments: { $first: '$comments' },
|
|
148
|
+
description: { $last: '$ticketActivity.description' },
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
$sort: {
|
|
153
|
+
issueDate: -1,
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
];
|
|
157
|
+
|
|
158
|
+
if ( req.body.filter && req.body.filter !== '' ) {
|
|
159
|
+
query.push( {
|
|
160
|
+
$match: {
|
|
161
|
+
issueType: req.body.filter,
|
|
162
|
+
},
|
|
163
|
+
} );
|
|
164
|
+
}
|
|
165
|
+
let ticketList = await aggregateTangoTicket( query );
|
|
166
|
+
if ( req.body.export && ticketList.length > 0 ) {
|
|
167
|
+
const exportdata = [];
|
|
168
|
+
ticketList.forEach( ( element ) => {
|
|
169
|
+
exportdata.push( {
|
|
170
|
+
'STORE ID': element.storeId,
|
|
171
|
+
'TICKET ID': element.ticketId,
|
|
172
|
+
'DATE': element.Date,
|
|
173
|
+
'ISSUE CLOSED DATE': element.issueClosedDate,
|
|
174
|
+
'STATUS': element.status,
|
|
175
|
+
'COMMENT': element.description,
|
|
176
|
+
} );
|
|
177
|
+
} );
|
|
178
|
+
await download( exportdata, res );
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
if ( ticketList.length ) {
|
|
182
|
+
let highCount = await countDocumentsTangoTicket( {
|
|
183
|
+
$and: [
|
|
184
|
+
{ 'basicDetails.storeId': req.body.storeId },
|
|
185
|
+
{ issueType: 'highcount' },
|
|
186
|
+
{ createdAt: { $gte: date.start } },
|
|
187
|
+
{ createdAt: { $lte: date.end } },
|
|
188
|
+
],
|
|
189
|
+
} );
|
|
190
|
+
let lowCount = await countDocumentsTangoTicket( {
|
|
191
|
+
$and: [
|
|
192
|
+
{ 'basicDetails.storeId': req.body.storeId },
|
|
193
|
+
{ issueType: 'lowcount' },
|
|
194
|
+
{ createdAt: { $gte: date.start } },
|
|
195
|
+
{ createdAt: { $lte: date.end } },
|
|
196
|
+
],
|
|
197
|
+
} );
|
|
198
|
+
|
|
199
|
+
res.sendSuccess( {
|
|
200
|
+
count: ticketList.length,
|
|
201
|
+
data: ticketList,
|
|
202
|
+
highCount: highCount,
|
|
203
|
+
lowCount: lowCount,
|
|
204
|
+
} );
|
|
205
|
+
} else {
|
|
206
|
+
return res.sendError( 'NO data', 204 );
|
|
207
|
+
}
|
|
208
|
+
} catch ( error ) {
|
|
209
|
+
logger.error( { error: error, function: 'activityList' } );
|
|
210
|
+
return res.sendError( error, 500 );
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
export async function showActivity( req, res ) {
|
|
216
|
+
try {
|
|
217
|
+
for ( let activity of req.body.ticketActivity ) {
|
|
218
|
+
if ( activity.attachments&&activity.attachments.length>0 ) {
|
|
219
|
+
for ( let attchment of activity.attachments ) {
|
|
220
|
+
let params = {
|
|
221
|
+
Bucket: appConfig.cloud.aws.bucket.ticket,
|
|
222
|
+
file_path: attchment.filePath,
|
|
223
|
+
};
|
|
224
|
+
let attachments = await signedUrl( params );
|
|
225
|
+
attchment.signedUrl = attachments;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
res.sendSuccess( req.body );
|
|
230
|
+
} catch ( error ) {
|
|
231
|
+
logger.error( { error: error, function: 'showActivity' } );
|
|
232
|
+
return res.sendError( error, 500 );
|
|
233
|
+
}
|
|
234
|
+
}
|
|
@@ -48,3 +48,16 @@ export async function activityLog( req, res ) {
|
|
|
48
48
|
return res.sendError( error, 500 );
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
export async function updateMatStatus( req, res ) {
|
|
54
|
+
try {
|
|
55
|
+
let update = await updateOneTangoTicket( { ticketId: req.body.ticketId }, { 'ticketDetails.matStatus': req.body.matStatus } );
|
|
56
|
+
if ( update ) {
|
|
57
|
+
res.sendSuccess( 'Updated Successfully' );
|
|
58
|
+
}
|
|
59
|
+
} catch ( error ) {
|
|
60
|
+
logger.error( { error: error, function: 'updateMatStatus' } );
|
|
61
|
+
return res.sendError( error, 500 );
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -13,10 +13,11 @@ import handlebars from 'handlebars';
|
|
|
13
13
|
import { findOneGroup } from '../services/group.service.js';
|
|
14
14
|
import htmlpdf from 'html-pdf-node';
|
|
15
15
|
import mongoose from 'mongoose';
|
|
16
|
+
import _ from 'lodash';
|
|
17
|
+
import { aggregateCamera } from '../services/camera.service.js';
|
|
16
18
|
export async function createTicket( req, res ) {
|
|
17
19
|
try {
|
|
18
20
|
req.body.issueDate = new Date( req.body.Date );
|
|
19
|
-
req.body.ticketDetails.filesCount = req.body.filesCount;
|
|
20
21
|
if ( req.body.issueType == 'infra' ) {
|
|
21
22
|
req.body.ticketId = 'TE_INF_' + new Date().valueOf();
|
|
22
23
|
req.body.ticketActivity = [ {
|
|
@@ -125,33 +126,28 @@ export async function bulkcreateTicket( req, res ) {
|
|
|
125
126
|
|
|
126
127
|
export async function updateStatus( req, res ) {
|
|
127
128
|
try {
|
|
128
|
-
console.log( req.user.userType );
|
|
129
129
|
if ( req.user.userType == 'tango' ) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
req.body.status ='inprogress';
|
|
138
|
-
}
|
|
130
|
+
req.body.ticketActivity.push( {
|
|
131
|
+
actionType: 'statusChange',
|
|
132
|
+
timeStamp: new Date(),
|
|
133
|
+
actionBy: 'Tango',
|
|
134
|
+
IdentifiedBy: req.user.userName,
|
|
135
|
+
} );
|
|
136
|
+
req.body.status = 'inprogress';
|
|
139
137
|
req.body.ticketDetails.addressingUser = req.user._id;
|
|
140
|
-
console.log( req.body );
|
|
141
138
|
let updateTicket = await updateOneTangoTicket( { ticketId: req.body.ticketId }, req.body );
|
|
142
139
|
if ( updateTicket ) {
|
|
143
140
|
res.sendSuccess( 'Ticket Updated Successfully' );
|
|
144
141
|
}
|
|
145
142
|
} else if ( req.user.userType == 'client' ) {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
}
|
|
143
|
+
req.body.ticketActivity.push( {
|
|
144
|
+
actionType: 'statusChange',
|
|
145
|
+
timeStamp: new Date(),
|
|
146
|
+
actionBy: 'User',
|
|
147
|
+
IdentifiedBy: req.user.userName,
|
|
148
|
+
} );
|
|
149
|
+
req.body.status = 'inprogress';
|
|
150
|
+
|
|
155
151
|
req.body.ticketDetails.addressingClient = req.user._id;
|
|
156
152
|
let updateTicket = await updateOneTangoTicket( { ticketId: req.body.ticketId }, req.body );
|
|
157
153
|
if ( updateTicket ) {
|
|
@@ -611,6 +607,217 @@ export async function invoice( req, res ) {
|
|
|
611
607
|
} );
|
|
612
608
|
}
|
|
613
609
|
|
|
610
|
+
export async function getInfraIssues( req, res ) {
|
|
611
|
+
try {
|
|
612
|
+
const inputData = req.body;
|
|
613
|
+
const query=[
|
|
614
|
+
{
|
|
615
|
+
$match: {
|
|
616
|
+
$and: [
|
|
617
|
+
{
|
|
618
|
+
'issueType': { $eq: 'infra' },
|
|
619
|
+
|
|
620
|
+
},
|
|
621
|
+
{
|
|
622
|
+
'basicDetails.storeId': { $eq: inputData.storeId },
|
|
623
|
+
|
|
624
|
+
},
|
|
625
|
+
{
|
|
626
|
+
'issueDate': { $gte: new Date( inputData.fromDate ) },
|
|
627
|
+
|
|
628
|
+
},
|
|
629
|
+
{
|
|
630
|
+
'issueDate': { $lte: new Date( inputData.toDate ) },
|
|
631
|
+
|
|
632
|
+
},
|
|
633
|
+
{
|
|
634
|
+
'ticketDetails.issueStatus': { $eq: 'identified' },
|
|
635
|
+
|
|
636
|
+
},
|
|
637
|
+
|
|
638
|
+
],
|
|
639
|
+
},
|
|
640
|
+
},
|
|
641
|
+
{
|
|
642
|
+
$project: {
|
|
643
|
+
issueType: 1,
|
|
644
|
+
issueDate: { $dateToString: { format: '%Y-%m-%d', date: '$issueDate' } },
|
|
645
|
+
ticketActivity: {
|
|
646
|
+
$filter: {
|
|
647
|
+
input: '$ticketActivity',
|
|
648
|
+
as: 'item',
|
|
649
|
+
cond: { $eq: [ '$$item.actionType', 'issueUpdate' ] },
|
|
650
|
+
},
|
|
651
|
+
},
|
|
652
|
+
},
|
|
653
|
+
},
|
|
654
|
+
|
|
655
|
+
{
|
|
656
|
+
$unwind: {
|
|
657
|
+
path: '$ticketActivity', preserveNullAndEmptyArrays: true,
|
|
658
|
+
},
|
|
659
|
+
},
|
|
660
|
+
{
|
|
661
|
+
$unwind: {
|
|
662
|
+
path: '$ticketActivity.reasons', preserveNullAndEmptyArrays: true,
|
|
663
|
+
},
|
|
664
|
+
},
|
|
665
|
+
{
|
|
666
|
+
$group: {
|
|
667
|
+
_id: { reason: '$ticketActivity.reasons', issueDate: '$issueDate' },
|
|
668
|
+
issueDate: { $first: '$issueDate' },
|
|
669
|
+
primaryIssue: { $last: '$ticketActivity.reasons.primaryIssue' },
|
|
670
|
+
secondaryIssue: { $last: '$ticketActivity.reasons.secondaryIssue' },
|
|
671
|
+
|
|
672
|
+
},
|
|
673
|
+
},
|
|
674
|
+
{
|
|
675
|
+
$unwind: {
|
|
676
|
+
path: '$secondaryIssue', preserveNullAndEmptyArrays: true,
|
|
677
|
+
},
|
|
678
|
+
},
|
|
679
|
+
{
|
|
680
|
+
$group: {
|
|
681
|
+
_id: { issue: '$primaryIssue', issueDate: '$issueDate' },
|
|
682
|
+
issueDate: { $first: '$issueDate' },
|
|
683
|
+
primaryIssue: { $last: '$primaryIssue' },
|
|
684
|
+
secondaryReason: { $push: '$secondaryIssue.name' },
|
|
685
|
+
|
|
686
|
+
},
|
|
687
|
+
},
|
|
688
|
+
{
|
|
689
|
+
$project: {
|
|
690
|
+
_id: 0,
|
|
691
|
+
issueDate: 1,
|
|
692
|
+
primaryIssue: 1,
|
|
693
|
+
secondaryReason: 1,
|
|
694
|
+
downTime: { $ifNull: [ 0, 0 ] },
|
|
695
|
+
speedTest: { $ifNull: [ 0.5, 0.5 ] },
|
|
696
|
+
},
|
|
697
|
+
|
|
698
|
+
},
|
|
699
|
+
];
|
|
700
|
+
|
|
701
|
+
|
|
702
|
+
let retVal = [];
|
|
703
|
+
let current = new Date( inputData.fromDate );
|
|
704
|
+
let end = new Date( inputData.toDate );
|
|
705
|
+
|
|
706
|
+
while ( current <= end ) {
|
|
707
|
+
retVal.push( { issueDate: dayjs( current ).format( 'YYYY-MM-DD' ), downTime: 0, speedTest: 0.6 } );
|
|
708
|
+
current.setDate( current.getDate() + 1 );
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
const result = await aggregateTangoTicket( query );
|
|
712
|
+
|
|
713
|
+
const mergeValue =_.values(
|
|
714
|
+
_.merge(
|
|
715
|
+
_.keyBy( retVal, 'issueDate' ),
|
|
716
|
+
_.keyBy( result, 'issueDate' ),
|
|
717
|
+
),
|
|
718
|
+
);
|
|
719
|
+
logger.info( { message: mergeValue, value1: result } );
|
|
720
|
+
|
|
721
|
+
if ( mergeValue.length == 0 ) {
|
|
722
|
+
return res.sendError( 'NO Data Found', 204 );
|
|
723
|
+
}
|
|
724
|
+
for ( let i =0; i< mergeValue.length; i++ ) {
|
|
725
|
+
const downTime = await getOpenSearchData( 'live_downtime_hourly',
|
|
726
|
+
{
|
|
727
|
+
'size': 100,
|
|
728
|
+
'query': {
|
|
729
|
+
'bool': {
|
|
730
|
+
'must': [
|
|
731
|
+
{
|
|
732
|
+
'term': {
|
|
733
|
+
'doc.date.keyword': dayjs( mergeValue[i].issueDate ).format( 'DD-MM-YYYY' ),
|
|
734
|
+
},
|
|
735
|
+
},
|
|
736
|
+
{
|
|
737
|
+
'term': {
|
|
738
|
+
'doc.store_id.keyword': inputData.storeId,
|
|
739
|
+
},
|
|
740
|
+
},
|
|
741
|
+
|
|
742
|
+
],
|
|
743
|
+
|
|
744
|
+
},
|
|
745
|
+
},
|
|
746
|
+
|
|
747
|
+
} );
|
|
748
|
+
let streamwiseDowntime = [];
|
|
749
|
+
logger.info( { streamwiseDowntime: downTime.body.hits.hits.length } );
|
|
750
|
+
if ( downTime.body.hits.hits.length > 0 ) {
|
|
751
|
+
for ( let i = 0; i< downTime.body.hits.hits.length; i++ ) {
|
|
752
|
+
const sum = streamwiseDowntime.reduce( ( accumulator, currentValue ) => {
|
|
753
|
+
return accumulator + currentValue.down_time;
|
|
754
|
+
}, 0 );
|
|
755
|
+
const average = sum / streamwiseDowntime.length;
|
|
756
|
+
mergeValue.downTime = Math.round( average );
|
|
757
|
+
// streamwiseDowntime.push( ...downTime.body.hits.hits[i]._source.doc.streamwise_downtime );
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
const camQuery = [
|
|
762
|
+
{
|
|
763
|
+
$match: {
|
|
764
|
+
$and: [
|
|
765
|
+
{ isUp: { $eq: true } },
|
|
766
|
+
{ isActivated: { $eq: true } },
|
|
767
|
+
{ storeId: inputData.storeId },
|
|
768
|
+
],
|
|
769
|
+
},
|
|
770
|
+
},
|
|
771
|
+
{
|
|
772
|
+
$project: {
|
|
773
|
+
_id: 0,
|
|
774
|
+
streamName: 1,
|
|
775
|
+
cameraNumber: 1,
|
|
776
|
+
thumbnailImage: await signedUrl( { Bucket: appConfig.cloud.aws.bucket.baseImage, file_path: '$thumbnailImage' } ),
|
|
777
|
+
},
|
|
778
|
+
},
|
|
779
|
+
];
|
|
780
|
+
|
|
781
|
+
const highCountQuery =[
|
|
782
|
+
{
|
|
783
|
+
$match: {
|
|
784
|
+
$and: [
|
|
785
|
+
{ 'basicDetails.storeId': inputData.storeId },
|
|
786
|
+
{ issueType: { $in: [ 'highcount', 'lowcount' ] } },
|
|
787
|
+
|
|
788
|
+
],
|
|
789
|
+
},
|
|
790
|
+
},
|
|
791
|
+
{
|
|
792
|
+
$group: {
|
|
793
|
+
_id: null,
|
|
794
|
+
total: { $sum: 1 },
|
|
795
|
+
successRate: { $avg: '$dataMismatch.successPercentage' },
|
|
796
|
+
},
|
|
797
|
+
},
|
|
798
|
+
{
|
|
799
|
+
$project: {
|
|
800
|
+
_id: 0,
|
|
801
|
+
total: 1,
|
|
802
|
+
successRate: 1,
|
|
803
|
+
},
|
|
804
|
+
},
|
|
805
|
+
];
|
|
806
|
+
const defaultValue= {
|
|
807
|
+
total: 0,
|
|
808
|
+
successRate: 0,
|
|
809
|
+
};
|
|
810
|
+
const getHighCountTicket = await aggregateTangoTicket( highCountQuery );
|
|
811
|
+
logger.info( { getHighCountTicket: getHighCountTicket } );
|
|
812
|
+
const camera = await aggregateCamera( camQuery );
|
|
813
|
+
logger.info( { message: camera } );
|
|
814
|
+
return res.sendSuccess( { result: mergeValue, streams: camera, highCountTicketDetails: getHighCountTicket[0] || defaultValue } );
|
|
815
|
+
} catch ( error ) {
|
|
816
|
+
logger.error( { error: error, function: 'getInfraIssues' } );
|
|
817
|
+
return res.sendError( error, 500 );
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
|
|
614
821
|
|
|
615
822
|
function inWords( num ) {
|
|
616
823
|
let a = [ '', 'one ', 'two ', 'three ', 'four ', 'five ', 'six ', 'seven ', 'eight ', 'nine ', 'ten ', 'eleven ', 'twelve ', 'thirteen ', 'fourteen ', 'fifteen ', 'sixteen ', 'seventeen ', 'eighteen ', 'nineteen ' ]; let b = [ '', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety' ];
|
|
@@ -1237,14 +1444,14 @@ export async function matTable( req, res ) {
|
|
|
1237
1444
|
result.forEach( ( element ) => {
|
|
1238
1445
|
exportdata.push( {
|
|
1239
1446
|
'ticketId': element.ticketId,
|
|
1240
|
-
'
|
|
1447
|
+
'Date': dayjs( element.issueDate ).format( 'DD-MM-YYYY' ),
|
|
1241
1448
|
'storeId': element.storeId,
|
|
1242
1449
|
'storeName': element.storeName,
|
|
1243
1450
|
'clientId': element.clientId,
|
|
1244
1451
|
'clientName': element.clientName,
|
|
1245
1452
|
'userName': element.userName,
|
|
1246
1453
|
'userEmail': element.userEmail,
|
|
1247
|
-
'Status': element.
|
|
1454
|
+
'Status': element.status,
|
|
1248
1455
|
} );
|
|
1249
1456
|
} );
|
|
1250
1457
|
await download( exportdata, res );
|
|
@@ -1276,18 +1483,25 @@ export async function assignTicket( req, res ) {
|
|
|
1276
1483
|
}
|
|
1277
1484
|
export async function storeFilter( req, res ) {
|
|
1278
1485
|
try {
|
|
1279
|
-
|
|
1486
|
+
const inputData = req.body;
|
|
1487
|
+
let query = { 'issueType': inputData.issueType, 'basicDetails.clientId': inputData.clientId, 'basicDetails.storeId': { $exists: true } };
|
|
1488
|
+
if ( inputData.issueType == 'dataMismatch' ) {
|
|
1489
|
+
query ={
|
|
1490
|
+
'issueType': { '$in': [ 'highcount', 'lowcount' ] }, 'basicDetails.clientId': inputData.clientId, 'basicDetails.storeId': { $exists: true },
|
|
1491
|
+
};
|
|
1492
|
+
}
|
|
1493
|
+
let stores = await findTangoTicket( query, { 'basicDetails.storeId': 1 } );
|
|
1280
1494
|
const uniqueStoreIds = [ ...new Set( stores.map( ( store ) => store.basicDetails.storeId ) ) ];
|
|
1281
1495
|
const uniqueStoreObjects = uniqueStoreIds.map( ( storeId ) => ( { 'storeId': storeId } ) );
|
|
1282
1496
|
|
|
1283
|
-
if ( uniqueStoreObjects.length>0 ) {
|
|
1497
|
+
if ( uniqueStoreObjects.length > 0 ) {
|
|
1284
1498
|
res.sendSuccess( { count: uniqueStoreObjects.length, data: uniqueStoreObjects } );
|
|
1285
1499
|
} else {
|
|
1286
1500
|
res.sendError( 'No data', 204 );
|
|
1287
1501
|
}
|
|
1288
1502
|
} catch ( error ) {
|
|
1289
|
-
// console.log( error );
|
|
1290
1503
|
logger.error( { error: error, function: 'storeFilter' } );
|
|
1291
1504
|
return res.sendError( error, 500 );
|
|
1292
1505
|
}
|
|
1293
1506
|
}
|
|
1507
|
+
|
|
@@ -445,11 +445,10 @@ export async function emailUserList( req, res ) {
|
|
|
445
445
|
}
|
|
446
446
|
export async function infraReportSent( req, res ) {
|
|
447
447
|
try {
|
|
448
|
-
let date;
|
|
449
448
|
// if ( req.body.type == 'start' ) {
|
|
450
449
|
// date = dayjs().subtract( 1, 'day' ).format( 'YYYY-MM-DD' );
|
|
451
450
|
// } else if ( req.body.type == 'end' ) {
|
|
452
|
-
date = dayjs().format( 'YYYY-MM-DD' );
|
|
451
|
+
let date = dayjs( ).format( 'YYYY-MM-DD' );
|
|
453
452
|
// };
|
|
454
453
|
let query = [ {
|
|
455
454
|
$match: {
|
|
@@ -468,6 +467,13 @@ export async function infraReportSent( req, res ) {
|
|
|
468
467
|
status: 1,
|
|
469
468
|
ticketDetails: 1,
|
|
470
469
|
issueClosedDate: 1,
|
|
470
|
+
otherscomment: {
|
|
471
|
+
$filter: {
|
|
472
|
+
input: '$ticketActivity',
|
|
473
|
+
as: 'item',
|
|
474
|
+
cond: { $eq: [ '$$item.actionType', 'comment' ] },
|
|
475
|
+
},
|
|
476
|
+
},
|
|
471
477
|
primaryIssue: {
|
|
472
478
|
$filter: {
|
|
473
479
|
input: '$ticketActivity',
|
|
@@ -477,6 +483,11 @@ export async function infraReportSent( req, res ) {
|
|
|
477
483
|
},
|
|
478
484
|
},
|
|
479
485
|
},
|
|
486
|
+
{
|
|
487
|
+
$unwind: {
|
|
488
|
+
path: '$otherscomment', preserveNullAndEmptyArrays: true,
|
|
489
|
+
},
|
|
490
|
+
},
|
|
480
491
|
{
|
|
481
492
|
$unwind: {
|
|
482
493
|
path: '$primaryIssue', preserveNullAndEmptyArrays: true,
|
|
@@ -500,6 +511,8 @@ export async function infraReportSent( req, res ) {
|
|
|
500
511
|
status: 1,
|
|
501
512
|
ticketDetails: 1,
|
|
502
513
|
issueClosedDate: 1,
|
|
514
|
+
ommentText: { $ifNull: [ '$primaryIssue.comment', '-' ] },
|
|
515
|
+
otherscomment: { $ifNull: [ '$otherscomment.comment', '-' ] },
|
|
503
516
|
primaryIssue: { $ifNull: [ '$primaryIssue.reasons.primaryIssue', '-' ] },
|
|
504
517
|
secondaryIssue: { $ifNull: [ '$primaryIssue.reasons.secondaryIssue.name', '-' ] },
|
|
505
518
|
},
|
|
@@ -510,11 +523,12 @@ export async function infraReportSent( req, res ) {
|
|
|
510
523
|
ticketDetails: { $first: '$ticketDetails' },
|
|
511
524
|
issueClosedDate: { $first: '$issueClosedDate' },
|
|
512
525
|
basicDetails: { $first: '$basicDetails' },
|
|
526
|
+
commentText: { $last: '$commentText' },
|
|
513
527
|
primaryIssue: { $last: '$primaryIssue' },
|
|
514
528
|
secondaryIssue: { $last: '$secondaryIssue' },
|
|
529
|
+
otherscomment: { $last: '$otherscomment' },
|
|
515
530
|
createdAt: { $first: '$createdAt' },
|
|
516
531
|
status: { $last: '$status' },
|
|
517
|
-
|
|
518
532
|
},
|
|
519
533
|
},
|
|
520
534
|
];
|
|
@@ -527,7 +541,7 @@ export async function infraReportSent( req, res ) {
|
|
|
527
541
|
exportdata.push( {
|
|
528
542
|
'Client ID': element.basicDetails.clientId,
|
|
529
543
|
'Client Name': element.basicDetails.clientName,
|
|
530
|
-
'Ticket Created Date & Time': dayjs( element.createdAt ).format( 'YYYY-MM-DD HH:mm A' ),
|
|
544
|
+
'Ticket Created Date & Time': dayjs( element.createdAt ).tz( 'Asia/Kolkata' ).format( 'YYYY-MM-DD HH:mm A' ),
|
|
531
545
|
'Store ID': element.basicDetails.storeId,
|
|
532
546
|
'Store Name': element.basicDetails.storeName,
|
|
533
547
|
'Issue ': element.primaryIssue,
|
|
@@ -535,9 +549,12 @@ export async function infraReportSent( req, res ) {
|
|
|
535
549
|
'Status ': element.status,
|
|
536
550
|
'Responded By': clientuser && clientuser.userName ? clientuser.userName : '-',
|
|
537
551
|
'Resolved By': tangouser && tangouser.userName ? tangouser.userName : '-',
|
|
538
|
-
'Ticket Closed Date & Time': element.issueClosedDate ? dayjs( element.issueClosedDate ).format( 'YYYY-MM-DD HH:mm A' ) : '-',
|
|
539
|
-
'Latest Comment':
|
|
540
|
-
'Activity Log':
|
|
552
|
+
'Ticket Closed Date & Time': element.issueClosedDate ? dayjs( element.issueClosedDate ).tz( 'Asia/Kolkata' ).format( 'YYYY-MM-DD HH:mm A' ) : '-',
|
|
553
|
+
'Latest Comment': element.otherscomment?element.otherscomment:element.commentText,
|
|
554
|
+
'Activity Log': {
|
|
555
|
+
label: 'Link',
|
|
556
|
+
url: `${appConfig.url.domain+'/manage/stores/infra-ticket?storeId='+element.basicDetails.storeId}`,
|
|
557
|
+
},
|
|
541
558
|
} );
|
|
542
559
|
}
|
|
543
560
|
|
|
@@ -572,40 +589,23 @@ export async function infraReportSent( req, res ) {
|
|
|
572
589
|
count: 0,
|
|
573
590
|
} ) );
|
|
574
591
|
}
|
|
575
|
-
|
|
592
|
+
|
|
576
593
|
let attachments = null;
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
594
|
+
let buffer = await download( exportdata );
|
|
595
|
+
attachments = {
|
|
596
|
+
filename: `dailyInfraReport- ${date}.xlsx`,
|
|
597
|
+
content: buffer,
|
|
598
|
+
contentType: 'application/xlsx', // e.g., 'application/pdf'
|
|
599
|
+
};
|
|
581
600
|
|
|
582
|
-
for ( let i = 0; i < headers.length; i++ ) {
|
|
583
|
-
ws.cell( 1, i + 1 ).string( headers[i] );
|
|
584
|
-
};
|
|
585
|
-
for ( let i = 0; i < exportdata.length; i++ ) {
|
|
586
|
-
const dataRow = exportdata[i];
|
|
587
|
-
for ( let j = 0; j < headers.length; j++ ) {
|
|
588
|
-
const header = headers[j];
|
|
589
|
-
const value = dataRow[header];
|
|
590
|
-
ws.cell( i + 2, j + 1 ).string( value?.toString() );
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
let buffer = await wb.writeToBuffer();
|
|
594
601
|
|
|
595
|
-
|
|
596
|
-
filename: `dailyInfraReport- ${reportdate}.xlsx`,
|
|
597
|
-
content: buffer,
|
|
598
|
-
contentType: 'application/xlsx', // e.g., 'application/pdf'
|
|
599
|
-
};
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
const subject = `Daily Digest - Infra Downtime Report - ${reportdate}`;
|
|
602
|
+
const subject = `Daily Digest - Infra Downtime Report - ${date}`;
|
|
603
603
|
const fileContent = readFileSync( join() + '/src/hbs/dailyInfraReport.hbs', 'utf8' );
|
|
604
604
|
const htmlContent = handlebars.compile( fileContent );
|
|
605
605
|
let Uidomain = `${appConfig.url.domain}`;
|
|
606
606
|
|
|
607
607
|
|
|
608
|
-
const html = htmlContent( { ...req.body, Uidomain: Uidomain, issueCount: issueCount, avgDownTime: avgDownTime, reportdate:
|
|
608
|
+
const html = htmlContent( { ...req.body, Uidomain: Uidomain, issueCount: issueCount, avgDownTime: avgDownTime, reportdate: date, content: response, date: date, domain: appConfig.url.apiDomain } );
|
|
609
609
|
if ( isValidEmail( req.body.email ) ) {
|
|
610
610
|
const result = await sendEmailWithSES( req.body.email, subject, html, attachments, appConfig.cloud.aws.ses.adminEmail );
|
|
611
611
|
res.sendSuccess( result );
|
|
@@ -724,8 +724,7 @@ export async function download( data ) {
|
|
|
724
724
|
for ( let j = 0; j < headers.length; j++ ) {
|
|
725
725
|
const header = headers[j];
|
|
726
726
|
const value = dataRow[header];
|
|
727
|
-
|
|
728
|
-
if ( typeof value === 'object' && value.hasOwnProperty( 'label' ) && value.hasOwnProperty( 'url' ) ) {
|
|
727
|
+
if ( value&& typeof value === 'object' && value.hasOwnProperty( 'label' ) && value.hasOwnProperty( 'url' ) ) {
|
|
729
728
|
ws.cell( i + 2, j + 1 ).link( value.url );
|
|
730
729
|
ws.cell( i + 2, j + 1 ).string( value.label );
|
|
731
730
|
} else {
|
|
@@ -884,11 +883,9 @@ export async function edgeApplogsCheck( req, res ) {
|
|
|
884
883
|
let findissueEdgeApp = {};
|
|
885
884
|
if ( result.length>0 ) {
|
|
886
885
|
for ( let findissue of result ) {
|
|
887
|
-
// console.log( ticket.ticketId );
|
|
888
886
|
const istTimestamp = dayjs.utc( ticket.createdAt ).tz( 'Asia/Kolkata' ).format( 'HH:mm:ss' );
|
|
889
887
|
|
|
890
888
|
if ( findissue.code == '1003' ) {
|
|
891
|
-
// Compare the times
|
|
892
889
|
const occurringTimeParsed = dayjs( `${req.body.date} ${findissue.edgelog.occuringTime}` );
|
|
893
890
|
const ticketCreatedParsed = dayjs( `${req.body.date} ${istTimestamp}` );
|
|
894
891
|
const isOccurringTimeEarlier = occurringTimeParsed.isBefore( ticketCreatedParsed );
|
|
@@ -902,7 +899,6 @@ export async function edgeApplogsCheck( req, res ) {
|
|
|
902
899
|
};
|
|
903
900
|
updateIssue( findissueEdgeApp );
|
|
904
901
|
finalresult.push( findissueEdgeApp );
|
|
905
|
-
// console.log( findissueEdgeApp );
|
|
906
902
|
}
|
|
907
903
|
} else if ( findissue.code == '1024' ) {
|
|
908
904
|
const occurringTimeParsed = dayjs( `${req.body.date} ${findissue.edgelog.data.occuringTime}` );
|
|
@@ -938,7 +934,6 @@ export async function edgeApplogsCheck( req, res ) {
|
|
|
938
934
|
};
|
|
939
935
|
updateIssue( findissueEdgeApp );
|
|
940
936
|
finalresult.push( findissueEdgeApp );
|
|
941
|
-
// console.log( findissueEdgeApp );
|
|
942
937
|
}
|
|
943
938
|
} else if ( findissue.code ==='1005' ) {
|
|
944
939
|
const occurringTimeParsed = dayjs( `${req.body.date} ${findissue.edgelog.occuringTime}` );
|
|
@@ -954,7 +949,6 @@ export async function edgeApplogsCheck( req, res ) {
|
|
|
954
949
|
};
|
|
955
950
|
updateIssue( findissueEdgeApp );
|
|
956
951
|
finalresult.push( findissueEdgeApp );
|
|
957
|
-
// console.log( findissueEdgeApp );
|
|
958
952
|
}
|
|
959
953
|
}
|
|
960
954
|
}
|
|
@@ -1054,7 +1048,6 @@ export async function updateIssue( data ) {
|
|
|
1054
1048
|
'status': 'inprogress',
|
|
1055
1049
|
};
|
|
1056
1050
|
await updateOneTangoTicket( { ticketId: data.ticketId }, query );
|
|
1057
|
-
// console.log( data );
|
|
1058
1051
|
} catch ( error ) {
|
|
1059
1052
|
logger.error( { error: error, function: 'updateAutomaticIssue' } );
|
|
1060
1053
|
res.sendError( error, 500 );
|
|
@@ -28,7 +28,20 @@ export async function storeTicketList( req, res ) {
|
|
|
28
28
|
ticketId: 1,
|
|
29
29
|
issueStatus: '$ticketDetails.issueStatus',
|
|
30
30
|
ticketType: '$ticketDetails.ticketType',
|
|
31
|
-
|
|
31
|
+
otherscomment: {
|
|
32
|
+
$filter: {
|
|
33
|
+
input: '$ticketActivity',
|
|
34
|
+
as: 'item',
|
|
35
|
+
cond: { $eq: [ '$$item.actionType', 'comment' ] },
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
comments: {
|
|
39
|
+
$filter: {
|
|
40
|
+
input: '$ticketActivity',
|
|
41
|
+
as: 'item',
|
|
42
|
+
cond: { $ne: [ '$$item.actionType', 'statusChange' ] },
|
|
43
|
+
},
|
|
44
|
+
},
|
|
32
45
|
primaryIssue: {
|
|
33
46
|
$filter: {
|
|
34
47
|
input: '$ticketActivity',
|
|
@@ -43,11 +56,21 @@ export async function storeTicketList( req, res ) {
|
|
|
43
56
|
path: '$primaryIssue', preserveNullAndEmptyArrays: true,
|
|
44
57
|
},
|
|
45
58
|
},
|
|
59
|
+
{
|
|
60
|
+
$unwind: {
|
|
61
|
+
path: '$otherscomment', preserveNullAndEmptyArrays: true,
|
|
62
|
+
},
|
|
63
|
+
},
|
|
46
64
|
{
|
|
47
65
|
$unwind: {
|
|
48
66
|
path: '$primaryIssue.reasons', preserveNullAndEmptyArrays: true,
|
|
49
67
|
},
|
|
50
68
|
},
|
|
69
|
+
{
|
|
70
|
+
$unwind: {
|
|
71
|
+
path: '$primaryIssue.reasons.secondaryIssue', preserveNullAndEmptyArrays: true,
|
|
72
|
+
},
|
|
73
|
+
},
|
|
51
74
|
{
|
|
52
75
|
$project: {
|
|
53
76
|
storeId: 1,
|
|
@@ -57,10 +80,12 @@ export async function storeTicketList( req, res ) {
|
|
|
57
80
|
ticketId: 1,
|
|
58
81
|
issueStatus: 1,
|
|
59
82
|
ticketType: 1,
|
|
60
|
-
comments:
|
|
83
|
+
comments: { $size: '$comments' },
|
|
61
84
|
issueDate: 1,
|
|
85
|
+
commentText: '$primaryIssue.comment',
|
|
62
86
|
primaryIssue: '$primaryIssue.reasons.primaryIssue',
|
|
63
|
-
secondaryIssue: '$primaryIssue.reasons.secondaryIssue',
|
|
87
|
+
secondaryIssue: '$primaryIssue.reasons.secondaryIssue.name',
|
|
88
|
+
otherscomment: '$otherscomment.comment',
|
|
64
89
|
},
|
|
65
90
|
},
|
|
66
91
|
{
|
|
@@ -75,8 +100,11 @@ export async function storeTicketList( req, res ) {
|
|
|
75
100
|
issueStatus: { $first: '$issueStatus' },
|
|
76
101
|
ticketType: { $first: '$ticketType' },
|
|
77
102
|
comments: { $first: '$comments' },
|
|
103
|
+
commentText: { $last: '$commentText' },
|
|
78
104
|
primaryIssue: { $last: '$primaryIssue' },
|
|
79
105
|
secondaryIssue: { $last: '$secondaryIssue' },
|
|
106
|
+
otherscomment: { $last: '$otherscomment' },
|
|
107
|
+
|
|
80
108
|
},
|
|
81
109
|
},
|
|
82
110
|
{
|
|
@@ -102,8 +130,10 @@ export async function storeTicketList( req, res ) {
|
|
|
102
130
|
'TICKET ID': element.ticketId,
|
|
103
131
|
'DATE': element.Date,
|
|
104
132
|
'ISSUE CLOSED DATE': element.issueClosedDate,
|
|
105
|
-
'ISSUE': element.primaryIssue,
|
|
133
|
+
'PRIMARY ISSUE': element.primaryIssue,
|
|
134
|
+
'SECONDARY ISSUE': element.secondaryIssue,
|
|
106
135
|
'STATUS': element.status,
|
|
136
|
+
'COMMENT': element.otherscomment?element.otherscomment:element.commentText,
|
|
107
137
|
} );
|
|
108
138
|
} );
|
|
109
139
|
await download( exportdata, res );
|
|
@@ -330,7 +360,6 @@ export async function edgeAppLogTable( req, res ) {
|
|
|
330
360
|
};
|
|
331
361
|
const downtime = await getOpenSearchData( 'live_downtime_hourly', downTimeQuery );
|
|
332
362
|
let streamwiseDowntime = downtime.body.hits.hits.length > 0 ? downtime.body.hits.hits[0]._source.doc.streamwise_downtime : [];
|
|
333
|
-
// console.log( obj.hour, streamwiseDowntime );
|
|
334
363
|
if ( streamwiseDowntime.length > 0 ) {
|
|
335
364
|
const sum = streamwiseDowntime.reduce( ( accumulator, currentValue ) => {
|
|
336
365
|
return accumulator + currentValue.down_time;
|
|
@@ -92,7 +92,7 @@ export async function userTakeTicket( req, res ) {
|
|
|
92
92
|
}
|
|
93
93
|
userTicket = await findOneTangoTicket( query );
|
|
94
94
|
}
|
|
95
|
-
if ( userTicket ) {
|
|
95
|
+
if ( userTicket&&userTicket.ticketId ) {
|
|
96
96
|
let assignTicket = await updateOneTangoTicket( { ticketId: userTicket.ticketId }, { 'ticketDetails.addressingUser': req.body.userId } );
|
|
97
97
|
if ( assignTicket ) {
|
|
98
98
|
res.sendSuccess( 'Ticket Assigned Successfully' );
|
|
@@ -113,6 +113,7 @@ export async function userTicketList( req, res ) {
|
|
|
113
113
|
query.push( {
|
|
114
114
|
$match: {
|
|
115
115
|
$and: [
|
|
116
|
+
{ 'basicDetails.clientId': { $in: req.body.clientId } },
|
|
116
117
|
{ issueType: req.body.issueType },
|
|
117
118
|
{ 'ticketDetails.addressingUser': new mongoose.Types.ObjectId( req.body.userId ) },
|
|
118
119
|
],
|
|
@@ -122,6 +123,7 @@ export async function userTicketList( req, res ) {
|
|
|
122
123
|
query.push( {
|
|
123
124
|
$match: {
|
|
124
125
|
$and: [
|
|
126
|
+
{ 'basicDetails.clientId': { $in: req.body.clientId } },
|
|
125
127
|
{ issueType: { $in: [ 'highcount', 'lowcount' ] } },
|
|
126
128
|
{ 'ticketDetails.addressingUser': new mongoose.Types.ObjectId( req.body.userId ) },
|
|
127
129
|
],
|
|
@@ -163,6 +165,7 @@ export async function userTicketList( req, res ) {
|
|
|
163
165
|
issueStatus: '$ticketDetails.issueStatus',
|
|
164
166
|
ticketType: '$ticketDetails.ticketType',
|
|
165
167
|
installationStatus: '$ticketDetails.installationStatus',
|
|
168
|
+
matStatus: '$ticketDetails.matStatus',
|
|
166
169
|
primaryIssue: {
|
|
167
170
|
$filter: {
|
|
168
171
|
input: '$ticketActivity',
|
|
@@ -194,6 +197,7 @@ export async function userTicketList( req, res ) {
|
|
|
194
197
|
status: 1,
|
|
195
198
|
issueType: 1,
|
|
196
199
|
installationStatus: 1,
|
|
200
|
+
matStatus: 1,
|
|
197
201
|
infraIssue: '$primaryIssue.reasons.primaryIssue',
|
|
198
202
|
},
|
|
199
203
|
},
|
|
@@ -208,6 +212,7 @@ export async function userTicketList( req, res ) {
|
|
|
208
212
|
issueType: { $first: '$issueType' },
|
|
209
213
|
status: { $first: '$status' },
|
|
210
214
|
installationStatus: { $first: '$installationStatus' },
|
|
215
|
+
matStatus: { $first: '$matStatus' },
|
|
211
216
|
issueStatus: { $first: '$issueStatus' },
|
|
212
217
|
ticketType: { $first: '$ticketType' },
|
|
213
218
|
infraIssue: { $last: '$infraIssue' },
|
|
@@ -232,6 +237,7 @@ export async function userTicketList( req, res ) {
|
|
|
232
237
|
$or: [
|
|
233
238
|
{ issueStatus: req.body.filter },
|
|
234
239
|
{ infraIssue: req.body.filter },
|
|
240
|
+
{ issueType: req.body.filter },
|
|
235
241
|
],
|
|
236
242
|
},
|
|
237
243
|
} );
|
|
@@ -240,13 +246,23 @@ export async function userTicketList( req, res ) {
|
|
|
240
246
|
if ( req.body.export ) {
|
|
241
247
|
const exportdata = [];
|
|
242
248
|
ticketList.forEach( ( element ) => {
|
|
243
|
-
|
|
249
|
+
let data = {
|
|
244
250
|
'DATE': element.Date,
|
|
245
251
|
'TICKET ID': element.ticketId,
|
|
246
252
|
'STORE ID': element.storeId,
|
|
247
|
-
'
|
|
253
|
+
'STORE NAME': element.storeName,
|
|
248
254
|
'STATUS': element.status,
|
|
249
|
-
}
|
|
255
|
+
};
|
|
256
|
+
if ( req.body.issueType ==='infra' ) {
|
|
257
|
+
data = { ...data, ...{ 'ISSUE': element.issueStatus } };
|
|
258
|
+
}
|
|
259
|
+
if ( req.body.issueType ==='installation' ) {
|
|
260
|
+
data = { ...data, ...{ 'ISSUE': element.issueStatus } };
|
|
261
|
+
}
|
|
262
|
+
if ( req.body.issueType ==='dataMismatch' ) {
|
|
263
|
+
data = { ...data, ...{ 'ISSUE TYPE': element.issueType } };
|
|
264
|
+
}
|
|
265
|
+
exportdata.push( data );
|
|
250
266
|
} );
|
|
251
267
|
await download( exportdata, res );
|
|
252
268
|
return;
|
|
@@ -334,6 +350,7 @@ export async function workHistory( req, res ) {
|
|
|
334
350
|
query.push( {
|
|
335
351
|
$match: {
|
|
336
352
|
$and: [
|
|
353
|
+
{ 'basicDetails.clientId': { $in: req.body.clientId } },
|
|
337
354
|
{ 'status': 'closed' },
|
|
338
355
|
{ issueType: req.body.issueType },
|
|
339
356
|
{ 'ticketDetails.addressingUser': new mongoose.Types.ObjectId( req.body.userId ) },
|
|
@@ -344,6 +361,7 @@ export async function workHistory( req, res ) {
|
|
|
344
361
|
query.push( {
|
|
345
362
|
$match: {
|
|
346
363
|
$and: [
|
|
364
|
+
{ 'basicDetails.clientId': { $in: req.body.clientId } },
|
|
347
365
|
{ 'status': 'closed' },
|
|
348
366
|
{ issueType: { $in: [ 'highcount', 'lowcount' ] } },
|
|
349
367
|
{ 'ticketDetails.addressingUser': new mongoose.Types.ObjectId( req.body.userId ) },
|
|
@@ -373,6 +391,18 @@ export async function workHistory( req, res ) {
|
|
|
373
391
|
{ 'issueClosedDate': { $lte: date.end } },
|
|
374
392
|
],
|
|
375
393
|
|
|
394
|
+
},
|
|
395
|
+
},
|
|
396
|
+
);
|
|
397
|
+
} else if ( req.body.dateFilter === 'issueDate' ) {
|
|
398
|
+
query.push(
|
|
399
|
+
{
|
|
400
|
+
$match: {
|
|
401
|
+
$and: [
|
|
402
|
+
{ 'issueDate': { $gte: date.start } },
|
|
403
|
+
{ 'issueDate': { $lte: date.end } },
|
|
404
|
+
],
|
|
405
|
+
|
|
376
406
|
},
|
|
377
407
|
},
|
|
378
408
|
);
|
|
@@ -407,6 +437,7 @@ export async function workHistory( req, res ) {
|
|
|
407
437
|
storeName: '$basicDetails.storeName',
|
|
408
438
|
clientId: '$basicDetails.clientId',
|
|
409
439
|
clientName: '$basicDetails.clientName',
|
|
440
|
+
issueType: 1,
|
|
410
441
|
issueDate: { $dateToString: { format: '%Y-%m-%d', date: '$createdAt' } },
|
|
411
442
|
issueClosedDate: { $dateToString: { format: '%Y-%m-%d', date: '$issueClosedDate' } },
|
|
412
443
|
issueIdentifiedDate: { $dateToString: { format: '%Y-%m-%d', date: '$ticketDetails.issueIdentifiedDate' } },
|
|
@@ -436,6 +467,7 @@ export async function workHistory( req, res ) {
|
|
|
436
467
|
$project: {
|
|
437
468
|
storeId: 1,
|
|
438
469
|
storeName: 1,
|
|
470
|
+
issueType: 1,
|
|
439
471
|
clientId: 1,
|
|
440
472
|
clientName: 1,
|
|
441
473
|
issueDate: 1,
|
|
@@ -443,17 +475,25 @@ export async function workHistory( req, res ) {
|
|
|
443
475
|
issueClosedDate: 1,
|
|
444
476
|
ticketId: 1,
|
|
445
477
|
issueStatus: 1,
|
|
478
|
+
status: 1,
|
|
446
479
|
ticketType: 1,
|
|
447
480
|
infraIssue: { $ifNull: [ '$primaryIssue.reasons.primaryIssue', '' ] },
|
|
448
481
|
},
|
|
449
482
|
} );
|
|
450
|
-
if ( req.body.issueFilter && req.body.issueFilter.length>0 ) {
|
|
483
|
+
if ( req.body.issueFilter && req.body.issueFilter.length>0&&req.body.issueType!='dataMismatch' ) {
|
|
451
484
|
query.push( {
|
|
452
485
|
$match: {
|
|
453
486
|
infraIssue: { $in: req.body.issueFilter },
|
|
454
487
|
},
|
|
455
488
|
} );
|
|
456
489
|
}
|
|
490
|
+
if ( req.body.issueFilter && req.body.issueFilter.length>0&&req.body.issueType==='dataMismatch' ) {
|
|
491
|
+
query.push( {
|
|
492
|
+
$match: {
|
|
493
|
+
issueType: { $in: req.body.issueFilter },
|
|
494
|
+
},
|
|
495
|
+
} );
|
|
496
|
+
}
|
|
457
497
|
if ( req.body.searchValue && req.body.searchValue !== '' ) {
|
|
458
498
|
query.push( {
|
|
459
499
|
$match: {
|
|
@@ -484,19 +524,25 @@ export async function workHistory( req, res ) {
|
|
|
484
524
|
if ( req.body.export ) {
|
|
485
525
|
const exportdata = [];
|
|
486
526
|
result.forEach( ( element ) => {
|
|
487
|
-
|
|
527
|
+
let data ={
|
|
488
528
|
'CREATED ON': dayjs( element.issueDate ).format( 'DD-MM-YYYY' ),
|
|
489
529
|
'TICKET ID': element.ticketId,
|
|
490
530
|
'STORE ID': element.storeId,
|
|
491
531
|
'STORE NAME': element.storeName,
|
|
492
532
|
'CLIENT ID': element.clientId,
|
|
493
533
|
'CLIENT NAME': element.clientName,
|
|
494
|
-
'ISSUE IDENTIFIED DATE': element.issueIdentifiedDate,
|
|
495
534
|
'CLOSED ON': element.issueClosedDate,
|
|
496
|
-
'ISSUE': element.infraIssue?element.infraIssue:'-',
|
|
497
535
|
'STATUS': element.status,
|
|
498
|
-
}
|
|
536
|
+
};
|
|
537
|
+
if ( req.body.issueType==='infra'||req.body.issueType==='installation' ) {
|
|
538
|
+
data = { ...data, ...{ 'ISSUE': element.infraIssue?element.infraIssue:'-', 'ISSUE IDENTIFIED DATE': element.issueIdentifiedDate } };
|
|
539
|
+
}
|
|
540
|
+
if ( req.body.issueType==='dataMismatch' ) {
|
|
541
|
+
data = { ...data, ...{ 'issueType': element.issueType?element.issueType:'-' } };
|
|
542
|
+
}
|
|
543
|
+
exportdata.push( data );
|
|
499
544
|
} );
|
|
545
|
+
|
|
500
546
|
await download( exportdata, res );
|
|
501
547
|
return;
|
|
502
548
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import j2s from 'joi-to-swagger';
|
|
2
|
+
import { getInfraIssueSchema } from '../dtos/infra.dtos.js';
|
|
3
|
+
|
|
4
|
+
export const infraDocs = {
|
|
5
|
+
|
|
6
|
+
'/v3/infra/get-infra-issues': {
|
|
7
|
+
post: {
|
|
8
|
+
tags: [ 'infra' ],
|
|
9
|
+
description: `Get infra issues against store`,
|
|
10
|
+
operationId: 'get-infra-issues',
|
|
11
|
+
parameters: {},
|
|
12
|
+
requestBody: {
|
|
13
|
+
content: {
|
|
14
|
+
'application/json': {
|
|
15
|
+
schema: j2s( getInfraIssueSchema ).swagger,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
responses: {
|
|
20
|
+
200: { description: 'Group has been created successfully' },
|
|
21
|
+
401: { description: 'Unauthorized User' },
|
|
22
|
+
422: { description: 'Field Error' },
|
|
23
|
+
500: { description: 'Server Error' },
|
|
24
|
+
204: { description: 'Not Found' },
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import Joi from 'joi';
|
|
2
|
+
|
|
3
|
+
export const getInfraIssueSchema = Joi.object().keys( {
|
|
4
|
+
fromDate: Joi.string().required(),
|
|
5
|
+
toDate: Joi.string().required(),
|
|
6
|
+
storeId: Joi.string().required(),
|
|
7
|
+
|
|
8
|
+
} );
|
|
9
|
+
|
|
10
|
+
export const getInfraIssueValid = {
|
|
11
|
+
body: getInfraIssueSchema,
|
|
12
|
+
};
|
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
import express from 'express';
|
|
2
2
|
import { isAllowedSessionHandler, authorize } from 'tango-app-api-middleware';
|
|
3
|
-
import { createTicket } from '../controllers/dataMismatch.controller.js';
|
|
4
|
-
import { validateDetails } from '../validations/infra.validation.js';
|
|
5
|
-
export const
|
|
3
|
+
import { createTicket, updateMat, activityList, showActivity } from '../controllers/dataMismatch.controller.js';
|
|
4
|
+
import { ticketExists, validateDetails } from '../validations/infra.validation.js';
|
|
5
|
+
export const dataMismatchTicketRouter = express.Router();
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
dataMismatchTicketRouter.post( '/createTicket', isAllowedSessionHandler, authorize( {
|
|
8
8
|
userType: [ 'client', 'tango' ], access: [
|
|
9
9
|
{ featureName: 'manage', name: 'tickets', permissions: [ 'isView', 'isEdit' ] } ],
|
|
10
10
|
} ), validateDetails, createTicket );
|
|
11
|
+
dataMismatchTicketRouter.post( '/updateMat', isAllowedSessionHandler, authorize( {
|
|
12
|
+
userType: [ 'client', 'tango' ], access: [
|
|
13
|
+
{ featureName: 'manage', name: 'tickets', permissions: [ 'isView' ] } ],
|
|
14
|
+
} ), ticketExists, updateMat );
|
|
15
|
+
dataMismatchTicketRouter.post( '/activityList', isAllowedSessionHandler, authorize( {
|
|
16
|
+
userType: [ 'client', 'tango' ], access: [
|
|
17
|
+
{ featureName: 'manage', name: 'tickets', permissions: [ 'isView' ] } ],
|
|
18
|
+
} ), activityList );
|
|
19
|
+
dataMismatchTicketRouter.post( '/showActivity', isAllowedSessionHandler, authorize( {
|
|
20
|
+
userType: [ 'client', 'tango' ], access: [
|
|
21
|
+
{ featureName: 'manage', name: 'tickets', permissions: [ 'isView' ] } ],
|
|
22
|
+
} ), ticketExists, showActivity );
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createTicket, updatecomment, activityLog } from '../controllers/employeeTraning.controller.js';
|
|
1
|
+
import { createTicket, updatecomment, activityLog, updateMatStatus } from '../controllers/employeeTraning.controller.js';
|
|
2
2
|
import { ticketExists, validateDetails } from '../validations/infra.validation.js';
|
|
3
3
|
import express from 'express';
|
|
4
4
|
import { isAllowedSessionHandler, authorize } from 'tango-app-api-middleware';
|
|
@@ -15,3 +15,7 @@ employeeTrainigRouter.post( '/activityLog', isAllowedSessionHandler, authorize(
|
|
|
15
15
|
userType: [ 'tango' ], access: [
|
|
16
16
|
{ featureName: 'manage', name: 'tickets', permissions: [ 'isView' ] } ],
|
|
17
17
|
} ), ticketExists, activityLog );
|
|
18
|
+
employeeTrainigRouter.post( '/updateMatStatus', isAllowedSessionHandler, authorize( {
|
|
19
|
+
userType: [ 'tango' ], access: [
|
|
20
|
+
{ featureName: 'manage', name: 'tickets', permissions: [ 'isView' ] } ],
|
|
21
|
+
} ), ticketExists, updateMatStatus );
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
|
|
2
2
|
import express from 'express';
|
|
3
|
-
import { isAllowedSessionHandler, authorize } from 'tango-app-api-middleware';
|
|
3
|
+
import { isAllowedSessionHandler, authorize, validate } from 'tango-app-api-middleware';
|
|
4
4
|
import { validateDetails, bulkvalidateDetails, validateTicket, bulkvalidateTicket, validateTicketstatus, ticketExists, infraReasonExists, InfrastepstoResolve, InfraAlert } from '../validations/infra.validation.js';
|
|
5
5
|
import { createTicket, bulkcreateTicket, updateStatus, createReason, PrimaryReasons, matTable,
|
|
6
|
-
secondaryReason, updateTicketIssue, viewTicket, AlertTicketReply, uploadAttachments,
|
|
6
|
+
secondaryReason, updateTicketIssue, viewTicket, AlertTicketReply, uploadAttachments, getInfraIssues,
|
|
7
7
|
updateInstallationTicket, emailUserList, saveInfraEmailConfig, invoice, infraTable, storeFilter, assignTicket, installationTable } from '../controllers/infra.controllers.js';
|
|
8
|
+
import { getInfraIssueValid } from '../dtos/infra.dtos.js';
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
export const infraRouter = express.Router();
|
|
@@ -75,3 +76,8 @@ infraRouter.post( '/storeFilter', isAllowedSessionHandler, authorize( {
|
|
|
75
76
|
userType: [ 'client', 'tango' ], access: [
|
|
76
77
|
{ featureName: 'manage', name: 'tickets', permissions: [ 'isView' ] } ],
|
|
77
78
|
} ), storeFilter );
|
|
79
|
+
infraRouter.post( '/get-infra-issues', isAllowedSessionHandler, authorize( {
|
|
80
|
+
userType: [ 'client', 'tango' ], access: [
|
|
81
|
+
{ featureName: 'manage', name: 'tickets', permissions: [ 'isView' ] } ],
|
|
82
|
+
} ), validate( getInfraIssueValid ), getInfraIssues );
|
|
83
|
+
|
|
@@ -9,11 +9,11 @@ export async function validateDetails( req, res, next ) {
|
|
|
9
9
|
try {
|
|
10
10
|
let store = await findOneStore( { storeId: req.body.storeId } );
|
|
11
11
|
if ( !store ) {
|
|
12
|
-
return res.sendError( 'Store Not Available' );
|
|
12
|
+
return res.sendError( 'Store Not Available', 500 );
|
|
13
13
|
}
|
|
14
14
|
let client = await findOneClient( { clientId: store.clientId } );
|
|
15
15
|
if ( !client ) {
|
|
16
|
-
return res.sendError( 'Client Not Available' );
|
|
16
|
+
return res.sendError( 'Client Not Available', 500 );
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
if ( store.spocDetails && store.spocDetails.length > 0 ) {
|
|
@@ -186,7 +186,7 @@ export async function ticketExists( req, res, next ) {
|
|
|
186
186
|
req.body.ticketActivity = Ticket.ticketActivity;
|
|
187
187
|
req.body.status = Ticket.status;
|
|
188
188
|
req.body.issueDate = Ticket.issueDate;
|
|
189
|
-
|
|
189
|
+
req.body.dataMismatch = Ticket.dataMismatch;
|
|
190
190
|
|
|
191
191
|
next();
|
|
192
192
|
} catch ( error ) {
|
|
@@ -202,8 +202,6 @@ export async function validateTicketstatus( req, res, next ) {
|
|
|
202
202
|
if ( req.body.status == 'closed' ) {
|
|
203
203
|
return res.sendSuccess( 'Ticket already closed' );
|
|
204
204
|
}
|
|
205
|
-
console.log( req.body.ticketDetails );
|
|
206
|
-
|
|
207
205
|
if ( req.body.ticketDetails.ticketType==='firsttimeticket'&&req.body.ticketDetails.issueStatus==='identified' ) {
|
|
208
206
|
return res.sendSuccess( 'Ticket already Addressed' );
|
|
209
207
|
}
|