tango-app-api-infra 3.9.5-vms.7 → 3.9.5-vms.71

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.
@@ -3,9 +3,25 @@ import dayjs from 'dayjs';
3
3
 
4
4
  export const createTicketSchema = Joi.object().keys( {
5
5
 
6
- dateString: Joi.string().required(),
6
+ dateString: Joi.string().required().custom( ( value, helpers ) => {
7
+ const inputDate = dayjs( value, 'YYYY-MM-DD', true );
8
+ const today = dayjs();
9
+
10
+ if ( !inputDate.isValid() ) {
11
+ return helpers.error( 'any.invalid' );
12
+ }
13
+
14
+ const diff = today.diff( inputDate, 'day' );
15
+
16
+ if ( diff > 3 ) {
17
+ return helpers.message( 'Ticket Creation is not allowed for a period exceeding 3 days' );
18
+ }
19
+
20
+ return value;
21
+ } ),
7
22
  storeId: Joi.string().required(),
8
23
  ticketName: Joi.string().required(),
24
+ comments: Joi.string().optional(),
9
25
  type: Joi.string()
10
26
  .required()
11
27
  .valid( 'create', 'review', 'approve', 'tangRreview' )
@@ -23,6 +39,51 @@ export const createTicketValid = {
23
39
  body: createTicketSchema,
24
40
  };
25
41
 
42
+ export const tangoReviewTicketSchema = Joi.object().keys( {
43
+
44
+ dateString: Joi.string().required().custom( ( value, helpers ) => {
45
+ const inputDate = dayjs( value, 'YYYY-MM-DD', true );
46
+
47
+ if ( !inputDate.isValid() ) {
48
+ return helpers.error( 'any.invalid' );
49
+ }
50
+
51
+ return value;
52
+ } ),
53
+ storeId: Joi.string().required(),
54
+ comments: Joi.string().optional(),
55
+ ticketType: Joi.string().optional(),
56
+ mappingInfo: Joi.object().keys( {
57
+ type: Joi.string().required(),
58
+ mode: Joi.string().required(),
59
+ revicedFootfall: Joi.number().required(),
60
+ revicedPerc: Joi.string().required(),
61
+ count: Joi.array().required(),
62
+ revisedDetail: Joi.array().required(),
63
+ createdByEmail: Joi.string().optional(),
64
+ createdByUserName: Joi.string().optional(),
65
+ createdByRole: Joi.string().optional(),
66
+ status: Joi.string().optional(),
67
+
68
+
69
+ } ).required(),
70
+ } );
71
+
72
+ export const tangoReviewTicketValid = {
73
+ body: tangoReviewTicketSchema,
74
+ };
75
+ export const tangoReviewAccuracyClosedTicketSchema = Joi.object().keys( {
76
+ storeId: Joi.string().required(),
77
+ dateString: Joi.string().required(),
78
+ comments: Joi.string().required(),
79
+ subComment: Joi.string().required(),
80
+
81
+ } );
82
+
83
+ export const tangoReviewAccuracyClosedTicketValid = {
84
+ body: tangoReviewAccuracyClosedTicketSchema,
85
+ };
86
+
26
87
  export const ticketSummarySchema = Joi.object().keys( {
27
88
  clientId: Joi.string().required(),
28
89
 
@@ -93,8 +154,16 @@ export const ticketListSchema = Joi.object().keys( {
93
154
  offset: Joi.number().optional(),
94
155
  isExport: Joi.boolean().optional(),
95
156
  sortBy: Joi.string().optional().allow( '' ),
157
+ status: Joi.string().optional(),
96
158
  sortOrder: Joi.number().valid( -1, 1 ).optional(),
97
159
  tangoType: Joi.string().valid( 'store', 'internal', '' ).optional(),
160
+ permissionType: Joi.string().valid( 'review', 'approve' ).optional(),
161
+ filterByStatus: Joi.array().items( Joi.string().required() ).optional(),
162
+ filterByReviewer: Joi.string().optional(),
163
+ filterByApprover: Joi.string().optional(),
164
+ filterByTango: Joi.string().optional(),
165
+ filterByReviewedBy: Joi.array().items( Joi.string().required() ).optional(),
166
+ fileterByApprovedBy: Joi.array().items( Joi.string().required() ).optional(),
98
167
  fromDate: Joi.string()
99
168
  .pattern( /^\d{4}-\d{2}-\d{2}$/, 'YYYY-MM-DD format' )
100
169
  .required()
@@ -154,73 +223,75 @@ export const ticketListValid = {
154
223
  };
155
224
 
156
225
  export const getTicketsSchema = Joi.object().keys( {
157
- storeId: Joi.string().required().allow( '' ),
158
- dateString: Joi.string().optional(),
159
- fromDate: Joi.string()
160
- .pattern( /^\d{4}-\d{2}-\d{2}$/, 'YYYY-MM-DD format' )
161
- .required()
162
- .messages( {
163
- 'string.pattern.name': `'fromDate' must be in the format YYYY-MM-DD (e.g., 2025-07-19).`,
164
- 'string.empty': `'fromDate' is required.`,
165
- } )
166
- .custom( ( value, helpers ) => {
167
- const from = dayjs( value );
168
- if ( !from.isValid() ) {
169
- return helpers.error( 'any.invalid', { message: 'Invalid fromDate' } );
170
- }
171
- return value;
172
- } ),
173
-
174
- toDate: Joi.string()
175
- .pattern( /^\d{4}-\d{2}-\d{2}$/, 'YYYY-MM-DD format' )
176
- .required()
177
- .messages( {
178
- 'string.pattern.name': `'toDate' must be in the format YYYY-MM-DD (e.g., 2025-07-19).`,
179
- 'string.empty': `'toDate' is required.`,
180
- } )
181
- .custom( ( value, helpers ) => {
182
- const to = dayjs( value );
183
- const today = dayjs();
184
-
185
- if ( !to.isValid() ) {
186
- return helpers.error( 'any.invalid', { message: 'Invalid toDate' } );
187
- }
188
- if ( to.isAfter( today, 'day' ) ) {
189
- return helpers.error( 'any.invalid', { message: 'toDate cannot be in the future' } );
190
- }
191
-
192
- return value;
193
- } ),
194
- status: Joi.string().optional(),
226
+ // storeId: Joi.string().required().allow( '' ),
227
+ // dateString: Joi.string().required(),
228
+ // fromDate: Joi.string()
229
+ // .pattern( /^\d{4}-\d{2}-\d{2}$/, 'YYYY-MM-DD format' )
230
+ // .required()
231
+ // .messages( {
232
+ // 'string.pattern.name': `'fromDate' must be in the format YYYY-MM-DD (e.g., 2025-07-19).`,
233
+ // 'string.empty': `'fromDate' is required.`,
234
+ // } )
235
+ // .custom( ( value, helpers ) => {
236
+ // const from = dayjs( value );
237
+ // if ( !from.isValid() ) {
238
+ // return helpers.error( 'any.invalid', { message: 'Invalid fromDate' } );
239
+ // }
240
+ // return value;
241
+ // } ),
242
+
243
+ // toDate: Joi.string()
244
+ // .pattern( /^\d{4}-\d{2}-\d{2}$/, 'YYYY-MM-DD format' )
245
+ // .required()
246
+ // .messages( {
247
+ // 'string.pattern.name': `'toDate' must be in the format YYYY-MM-DD (e.g., 2025-07-19).`,
248
+ // 'string.empty': `'toDate' is required.`,
249
+ // } )
250
+ // .custom( ( value, helpers ) => {
251
+ // const to = dayjs( value );
252
+ // const today = dayjs();
253
+
254
+ // if ( !to.isValid() ) {
255
+ // return helpers.error( 'any.invalid', { message: 'Invalid toDate' } );
256
+ // }
257
+ // if ( to.isAfter( today, 'day' ) ) {
258
+ // return helpers.error( 'any.invalid', { message: 'toDate cannot be in the future' } );
259
+ // }
260
+
261
+ // return value;
262
+ // } ),
263
+ ticketId: Joi.string().required(),
264
+ // status: Joi.string().optional(),
195
265
  action: Joi.string().optional(),
196
- revopsType: Joi.string().optional(),
197
- limit: Joi.number().required(),
198
- offset: Joi.number().optional(),
266
+ // revopsType: Joi.string().optional(),
267
+ // limit: Joi.number().required(),
268
+ // offset: Joi.number().optional(),
199
269
 
200
- } ).custom( ( value, helpers ) => {
201
- const from = dayjs( value.fromDate );
202
- const to = dayjs( value.toDate );
270
+ } );
271
+ // .custom( ( value, helpers ) => {
272
+ // const from = dayjs( value.fromDate );
273
+ // const to = dayjs( value.toDate );
203
274
 
204
- if ( !from.isValid() || !to.isValid() ) {
205
- return helpers.error( 'any.invalid', { message: 'Invalid dates' } );
206
- }
275
+ // if ( !from.isValid() || !to.isValid() ) {
276
+ // return helpers.error( 'any.invalid', { message: 'Invalid dates' } );
277
+ // }
207
278
 
208
- if ( from.isAfter( to ) ) {
209
- return helpers.error( 'any.invalid', { message: 'fromDate cannot be after toDate' } );
210
- }
279
+ // if ( from.isAfter( to ) ) {
280
+ // return helpers.error( 'any.invalid', { message: 'fromDate cannot be after toDate' } );
281
+ // }
211
282
 
212
- if ( to.diff( from, 'day' ) > 90 ) {
213
- return helpers.error( 'any.invalid', { message: 'Date range cannot exceed 90 days' } );
214
- }
283
+ // if ( to.diff( from, 'day' ) > 90 ) {
284
+ // return helpers.error( 'any.invalid', { message: 'Date range cannot exceed 90 days' } );
285
+ // }
215
286
 
216
- return value;
217
- } );
287
+ // return value;
288
+ // } );
218
289
 
219
290
  export const getTicketsValid = {
220
291
  query: getTicketsSchema,
221
292
  };
222
293
 
223
- export const updateStatusSchemea =Joi.object().keys( {
294
+ export const updateStatusSchemea = Joi.object().keys( {
224
295
  data: Joi.array().items(
225
296
  Joi.object( {
226
297
  _id: Joi.string().required(),
@@ -442,6 +513,7 @@ export const downloadTicketsValid = {
442
513
 
443
514
  export const reviewerListSchema = Joi.object().keys( {
444
515
  clientId: Joi.string().required(),
516
+ type: Joi.string().required().allow( 'approve', 'review' ),
445
517
  } );
446
518
 
447
519
  export const reviewerListValid = {
@@ -454,6 +526,8 @@ export const openTicketListSchema = Joi.object().keys( {
454
526
  clientId: Joi.array().items(
455
527
  Joi.string().required(),
456
528
  ).required(),
529
+ type: Joi.string().required().allow( 'review', 'approve' ),
530
+ sortOrder: Joi.number().allow( 1, -1 ).optional(),
457
531
 
458
532
 
459
533
  } );
@@ -468,7 +542,8 @@ export const assignTicketSchema = Joi.object().keys( {
468
542
  userName: Joi.string().optional(),
469
543
  role: Joi.string().optional(),
470
544
  actionType: Joi.string().required(),
471
- ticketId: Joi.string().required(),
545
+ storeId: Joi.string().required(),
546
+ dateString: Joi.string().required(),
472
547
 
473
548
 
474
549
  } );
@@ -480,7 +555,8 @@ export const assignTicketValid = {
480
555
  export const updateTempStatusSchema = Joi.object().keys( {
481
556
  id: Joi.array().items( Joi.string().required() ).required(),
482
557
  status: Joi.string().required(),
483
- type: Joi.string().required(),
558
+ type: Joi.string().required().allow( 'review', 'approve' ),
559
+ comments: Joi.string().optional().allow( '' ),
484
560
 
485
561
 
486
562
  } );
@@ -488,3 +564,28 @@ export const updateTempStatusSchema = Joi.object().keys( {
488
564
  export const updateTempStatusValid = {
489
565
  body: updateTempStatusSchema,
490
566
  };
567
+
568
+ export const updateTicketStatusSchema = Joi.object().keys( {
569
+ storeId: Joi.string().required(),
570
+ dateString: Joi.string().required(),
571
+ mode: Joi.string().required(),
572
+
573
+ } );
574
+
575
+ export const updateTicketStatusValid = {
576
+ body: updateTicketStatusSchema,
577
+ };
578
+
579
+ export const multiCloseTicketSchema = Joi.object().keys( {
580
+
581
+ ticketList: Joi.array().items( Joi.object().keys( {
582
+ storeId: Joi.string().required(),
583
+ dateString: Joi.string().required(),
584
+ } ) ),
585
+ mode: Joi.string().required(),
586
+
587
+ } );
588
+
589
+ export const multiCloseTicketValid = {
590
+ body: multiCloseTicketSchema,
591
+ };
@@ -1,12 +1,18 @@
1
1
  import express from 'express';
2
- import { getClusters, getConfig, isGrantedUsers, isTicketExists, ticketCreation } from '../validations/footfallDirectory.validation.js';
3
- import { assignTicket, createTicket, downloadTickets, getTaggedStores, getTickets, openTicketList, reviewerList, ticketList, ticketSummary, updateStatus, updateTempStatus } from '../controllers/footfallDirectory.controllers.js';
4
- import { createTicketValid, downloadTicketsValid, getTaggedStoresValid, getTicketsValid, openTicketListValid, reviewerListValid, ticketListValid, ticketSummaryValid, updateStatusValid, assignTicketValid, updateTempStatusValid } from '../dtos/footfallDirectory.dtos.js';
2
+ import { getClusters, getConfig, isGrantedUsers, isTicketExists, ticketApprove, ticketCreation, ticketReview } from '../validations/footfallDirectory.validation.js';
3
+ import { assignTicket, createTicket, downloadTickets, getTaggedStores, getTickets, multiCloseTicket, openTicketList, reviewerList, tangoReviewTicket, ticketList, ticketSummary, updateStatus, updateTempStatus, updateUserTicketStatus, createinternalTicket, checkTicketExists, tangoReviewAccuracyClosedTicket } from '../controllers/footfallDirectory.controllers.js';
4
+ import { createTicketValid, downloadTicketsValid, getTaggedStoresValid, getTicketsValid, openTicketListValid, reviewerListValid, ticketListValid, ticketSummaryValid, updateStatusValid, assignTicketValid, updateTempStatusValid, updateTicketStatusValid, tangoReviewTicketValid, multiCloseTicketValid, tangoReviewAccuracyClosedTicketValid } from '../dtos/footfallDirectory.dtos.js';
5
5
  import { bulkValidate, getAssinedStore, isAllowedSessionHandler, validate } from 'tango-app-api-middleware';
6
6
 
7
7
  export const footfallDirectoryRouter = express.Router();
8
8
 
9
- footfallDirectoryRouter.post( '/create-ticket', isAllowedSessionHandler, validate( createTicketValid ), isGrantedUsers, getConfig, ticketCreation, createTicket );
9
+ footfallDirectoryRouter.post( '/create-ticket', isAllowedSessionHandler, validate( createTicketValid ), isGrantedUsers, getConfig, ticketCreation, ticketReview, ticketApprove, createTicket );
10
+ footfallDirectoryRouter.post( '/create-internalticket', isAllowedSessionHandler, createinternalTicket );
11
+ footfallDirectoryRouter.post( '/checkTicketExists', isAllowedSessionHandler, checkTicketExists );
12
+
13
+ footfallDirectoryRouter.post( '/tango-review-ticket', isAllowedSessionHandler, validate( tangoReviewTicketValid ), tangoReviewTicket );
14
+ footfallDirectoryRouter.post( '/tango-review-ticket', isAllowedSessionHandler, validate( tangoReviewAccuracyClosedTicketValid ), tangoReviewAccuracyClosedTicket );
15
+
10
16
  footfallDirectoryRouter.get( '/ticket-summary', isAllowedSessionHandler, bulkValidate( ticketSummaryValid ), ticketSummary );
11
17
 
12
18
  footfallDirectoryRouter.get( '/ticket-list', isAllowedSessionHandler, bulkValidate( ticketListValid ), ticketList );
@@ -19,5 +25,7 @@ footfallDirectoryRouter.get( '/reviewer-list', isAllowedSessionHandler, bulkVali
19
25
  footfallDirectoryRouter.post( '/open-ticket-list', isAllowedSessionHandler, bulkValidate( openTicketListValid ), openTicketList );
20
26
  footfallDirectoryRouter.post( '/assign-ticket', isAllowedSessionHandler, bulkValidate( assignTicketValid ), assignTicket );
21
27
  footfallDirectoryRouter.post( '/update-temp-status', isAllowedSessionHandler, bulkValidate( updateTempStatusValid ), updateTempStatus );
28
+ footfallDirectoryRouter.post( '/update-ticket-status', isAllowedSessionHandler, bulkValidate( updateTicketStatusValid ), updateUserTicketStatus );
29
+ footfallDirectoryRouter.post( '/multi-close-tickets', isAllowedSessionHandler, bulkValidate( multiCloseTicketValid ), multiCloseTicket );
22
30
 
23
31