tango-app-api-infra 3.0.73-dev → 3.0.74-dev

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tango-app-api-infra",
3
- "version": "3.0.73-dev",
3
+ "version": "3.0.74-dev",
4
4
  "description": "infra",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -25,8 +25,8 @@
25
25
  "joi-to-swagger": "^6.2.0",
26
26
  "mongodb": "^6.4.0",
27
27
  "nodemon": "^3.1.0",
28
- "tango-api-schema": "^2.0.94",
29
- "tango-app-api-middleware": "^1.0.63-dev",
28
+ "tango-api-schema": "^2.0.100",
29
+ "tango-app-api-middleware": "^1.0.67-dev",
30
30
  "winston": "^3.12.0",
31
31
  "winston-daily-rotate-file": "^5.0.0"
32
32
  },
@@ -1,6 +1,6 @@
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 } from 'tango-app-api-middleware';
4
4
  export async function createTicket( req, res ) {
5
5
  try {
6
6
  let ticketExist = await findOneTangoTicket( { 'issueType': req.body.issueType, 'issueDate': ( new Date( req.body.Date ) ), 'basicDetails.storeId': req.body.storeId } );
@@ -8,11 +8,47 @@ export async function createTicket( req, res ) {
8
8
  if ( ticketExist ) {
9
9
  return res.sendSuccess( 'MAT Ticket Already Exists for the store' );
10
10
  }
11
+ let actionBy = '';
12
+ if ( req.user.userType == 'tango' ) {
13
+ actionBy = 'Tango';
14
+ } else if ( req.user.userType == 'client' ) {
15
+ actionBy = 'User';
16
+ }
11
17
  req.body.ticketDetails = {};
12
- req.body.ticketDetails.dataMismatch = req.body.dataMismatch;
18
+ req.body.dataMismatch ={
19
+ actualCount: req.body.actualCount,
20
+ expectedCount: req.body.expectedCount,
21
+ contactEmail: req.body.contactEmail,
22
+ };
13
23
  req.body.issueDate = new Date( req.body.Date );
14
24
  req.body.ticketId = 'TE_DM_' + new Date().valueOf();
15
25
  let create = await createTangoTicket( req.body );
26
+ let getObject = {};
27
+ if ( req.files ) {
28
+ let params = {
29
+ Bucket: appConfig.cloud.aws.bucket.ticket,
30
+ Key: create.ticketId + '/',
31
+ ContentType: 'multipart/form-data',
32
+ body: req.files.img.data,
33
+ fileName: req.files.img.name,
34
+ };
35
+ let upload = await fileUpload( params );
36
+ if ( upload ) {
37
+ getObject = {
38
+ fileName: req.files.img.name,
39
+ filePath: create.ticketId + '/' + req.files.img.name,
40
+ };
41
+ }
42
+ }
43
+ req.body.ticketActivity = [ {
44
+ actionType: 'Created',
45
+ timeStamp: new Date(),
46
+ actionBy: actionBy,
47
+ IdentifiedBy: req.user.userName,
48
+ description: req.body.description,
49
+ attachments: [ getObject ],
50
+ } ];
51
+ await updateOneTangoTicket( { ticketId: create.ticketId }, { ticketActivity: req.body.ticketActivity } );
16
52
  if ( create ) {
17
53
  res.sendSuccess( 'Ticket Created Successfully' );
18
54
  }
@@ -21,3 +57,165 @@ export async function createTicket( req, res ) {
21
57
  return res.sendError( error, 500 );
22
58
  }
23
59
  }
60
+
61
+ export async function updateMat( req, res ) {
62
+ try {
63
+ let updateValue = {};
64
+ if ( req.body.actionType && req.body.actionType != '' ) {
65
+ let actionBy = '';
66
+ if ( req.user.userType == 'tango' ) {
67
+ actionBy = 'Tango';
68
+ } else if ( req.user.userType == 'client' ) {
69
+ actionBy = 'User';
70
+ }
71
+ req.body.ticketActivity.push( {
72
+ actionType: req.body.actionType,
73
+ actionBy: actionBy,
74
+ timeStamp: new Date(),
75
+ IdentifiedBy: req.user.userName,
76
+ description: req.body.description,
77
+ attachments: req.body.attachments,
78
+ } );
79
+ updateValue = { ticketActivity: req.body.ticketActivity };
80
+ }
81
+
82
+ let updateTicket = await updateOneTangoTicket( { ticketId: req.body.ticketId }, updateValue );
83
+ if ( updateTicket ) {
84
+ res.sendSuccess( 'Ticket Updated Successfully' );
85
+ }
86
+ } catch ( error ) {
87
+ logger.error( { error: error, function: 'updateMat' } );
88
+ return res.sendError( error, 500 );
89
+ }
90
+ }
91
+
92
+
93
+ export async function activityList( req, res ) {
94
+ try {
95
+ let date = await getUTC( new Date( req.body.fromDate ), new Date( req.body.toDate ) );
96
+ let query = [ {
97
+ $match: {
98
+ $and: [
99
+ { 'basicDetails.storeId': req.body.storeId },
100
+ { issueType: { $in: [ 'lowcount', 'highcount' ] } },
101
+ { createdAt: { $gte: date.start } },
102
+ { createdAt: { $lte: date.end } },
103
+ ],
104
+ },
105
+ },
106
+ {
107
+ $project: {
108
+ storeId: '$basicDetails.storeId',
109
+ status: 1,
110
+ issueDate: '$issueDate',
111
+ Date: { $dateToString: { format: '%d-%m-%Y', date: '$createdAt' } },
112
+ issueClosedDate: 1,
113
+ ticketId: 1,
114
+ issueType: 1,
115
+ ticketActivity: 1,
116
+ comments: { $size: '$ticketActivity' },
117
+ },
118
+ },
119
+ {
120
+ $unwind: {
121
+ path: '$ticketActivity', preserveNullAndEmptyArrays: true,
122
+ },
123
+ },
124
+ {
125
+ $group: {
126
+ _id: '$ticketId',
127
+ storeId: { $first: '$storeId' },
128
+ Date: { $first: '$Date' },
129
+ issueClosedDate: { $first: '$issueClosedDate' },
130
+ status: { $first: '$status' },
131
+ issueDate: { $first: '$issueDate' },
132
+ ticketId: { $first: '$ticketId' },
133
+ issueType: { $first: '$issueType' },
134
+ comments: { $first: '$comments' },
135
+ description: { $last: '$ticketActivity.description' },
136
+ },
137
+ },
138
+ {
139
+ $sort: {
140
+ issueDate: -1,
141
+ },
142
+ },
143
+ ];
144
+
145
+ if ( req.body.filter && req.body.filter !== '' ) {
146
+ query.push( {
147
+ $match: {
148
+ issueType: req.body.filter,
149
+ },
150
+ } );
151
+ }
152
+ let ticketList = await aggregateTangoTicket( query );
153
+ if ( req.body.export && ticketList.length > 0 ) {
154
+ const exportdata = [];
155
+ ticketList.forEach( ( element ) => {
156
+ exportdata.push( {
157
+ 'STORE ID': element.storeId,
158
+ 'TICKET ID': element.ticketId,
159
+ 'DATE': element.Date,
160
+ 'ISSUE CLOSED DATE': element.issueClosedDate,
161
+ 'STATUS': element.status,
162
+ 'COMMENT': element.description,
163
+ } );
164
+ } );
165
+ await download( exportdata, res );
166
+ return;
167
+ }
168
+ if ( ticketList.length ) {
169
+ let highCount = await countDocumentsTangoTicket( {
170
+ $and: [
171
+ { 'basicDetails.storeId': req.body.storeId },
172
+ { issueType: 'highcount' },
173
+ { createdAt: { $gte: date.start } },
174
+ { createdAt: { $lte: date.end } },
175
+ ],
176
+ } );
177
+ let lowCount = await countDocumentsTangoTicket( {
178
+ $and: [
179
+ { 'basicDetails.storeId': req.body.storeId },
180
+ { issueType: 'lowcount' },
181
+ { createdAt: { $gte: date.start } },
182
+ { createdAt: { $lte: date.end } },
183
+ ],
184
+ } );
185
+
186
+ res.sendSuccess( {
187
+ count: ticketList.length,
188
+ data: ticketList,
189
+ highCount: highCount,
190
+ lowCount: lowCount,
191
+ } );
192
+ } else {
193
+ return res.sendError( 'NO data', 204 );
194
+ }
195
+ } catch ( error ) {
196
+ logger.error( { error: error, function: 'activityList' } );
197
+ return res.sendError( error, 500 );
198
+ }
199
+ }
200
+
201
+
202
+ export async function showActivity( req, res ) {
203
+ try {
204
+ for ( let activity of req.body.ticketActivity ) {
205
+ if ( activity.attachments&&activity.attachments.length>0 ) {
206
+ for ( let attchment of activity.attachments ) {
207
+ let params = {
208
+ Bucket: appConfig.cloud.aws.bucket.ticket,
209
+ file_path: attchment.filePath,
210
+ };
211
+ let attachments = await signedUrl( params );
212
+ attchment.signedUrl = attachments;
213
+ }
214
+ }
215
+ }
216
+ res.sendSuccess( req.body );
217
+ } catch ( error ) {
218
+ logger.error( { error: error, function: 'showActivity' } );
219
+ return res.sendError( error, 500 );
220
+ }
221
+ }
@@ -18,7 +18,6 @@ import { aggregateCamera } from '../services/camera.service.js';
18
18
  export async function createTicket( req, res ) {
19
19
  try {
20
20
  req.body.issueDate = new Date( req.body.Date );
21
- req.body.ticketDetails.filesCount = req.body.filesCount;
22
21
  if ( req.body.issueType == 'infra' ) {
23
22
  req.body.ticketId = 'TE_INF_' + new Date().valueOf();
24
23
  req.body.ticketActivity = [ {
@@ -1470,3 +1469,4 @@ export async function storeFilter( req, res ) {
1470
1469
  return res.sendError( error, 500 );
1471
1470
  }
1472
1471
  }
1472
+
@@ -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: {
@@ -590,23 +589,23 @@ export async function infraReportSent( req, res ) {
590
589
  count: 0,
591
590
  } ) );
592
591
  }
593
- let reportdate = dayjs().format( 'YYYY-MM-DD' );
592
+
594
593
  let attachments = null;
595
594
  let buffer = await download( exportdata );
596
595
  attachments = {
597
- filename: `dailyInfraReport- ${reportdate}.xlsx`,
596
+ filename: `dailyInfraReport- ${date}.xlsx`,
598
597
  content: buffer,
599
598
  contentType: 'application/xlsx', // e.g., 'application/pdf'
600
599
  };
601
600
 
602
601
 
603
- const subject = `Daily Digest - Infra Downtime Report - ${reportdate}`;
602
+ const subject = `Daily Digest - Infra Downtime Report - ${date}`;
604
603
  const fileContent = readFileSync( join() + '/src/hbs/dailyInfraReport.hbs', 'utf8' );
605
604
  const htmlContent = handlebars.compile( fileContent );
606
605
  let Uidomain = `${appConfig.url.domain}`;
607
606
 
608
607
 
609
- const html = htmlContent( { ...req.body, Uidomain: Uidomain, issueCount: issueCount, avgDownTime: avgDownTime, reportdate: reportdate, content: response, date: date, domain: appConfig.url.apiDomain } );
608
+ const html = htmlContent( { ...req.body, Uidomain: Uidomain, issueCount: issueCount, avgDownTime: avgDownTime, reportdate: date, content: response, date: date, domain: appConfig.url.apiDomain } );
610
609
  if ( isValidEmail( req.body.email ) ) {
611
610
  const result = await sendEmailWithSES( req.body.email, subject, html, attachments, appConfig.cloud.aws.ses.adminEmail );
612
611
  res.sendSuccess( result );
@@ -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' );
@@ -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';
3
+ import { createTicket, updateMat, activityList, showActivity } from '../controllers/dataMismatch.controller.js';
4
+ import { ticketExists, validateDetails } from '../validations/infra.validation.js';
5
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 );
@@ -80,3 +80,4 @@ infraRouter.post( '/get-infra-issues', isAllowedSessionHandler, authorize( {
80
80
  userType: [ 'client', 'tango' ], access: [
81
81
  { featureName: 'manage', name: 'tickets', permissions: [ 'isView' ] } ],
82
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 ) {