tango-app-api-infra 3.9.5-vms.21 → 3.9.5-vms.23

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.9.5-vms.21",
3
+ "version": "3.9.5-vms.23",
4
4
  "description": "infra",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -831,7 +831,6 @@ export async function getTickets( req, res ) {
831
831
  return item;
832
832
  } );
833
833
 
834
- logger.info( { revopSources: processedRevopSources } );
835
834
  if ( finalResponse?.length == 0 || !finalResponse ) {
836
835
  if ( inputData.storeId?.length > 0 ) {
837
836
  const getStoreName = await findOneStore( { storeId: response?.[0]?._source?.storeId }, { storeName: 1 } );
@@ -1940,3 +1939,72 @@ export async function updateTempStatus( req, res ) {
1940
1939
  }
1941
1940
  }
1942
1941
 
1942
+ export async function updateUserTicketStatus( req, res ) {
1943
+ try {
1944
+ const openSearch = JSON.parse( process.env.OPENSEARCH );
1945
+ const { storeId, dateString } = req.body || {};
1946
+
1947
+ if ( !storeId || !dateString ) {
1948
+ return res.sendError( 'storeId and dateString are required', 400 );
1949
+ }
1950
+
1951
+ const docId = `${storeId}_${dateString}_footfall-directory-tagging`;
1952
+
1953
+ // Fetch existing ticket so we can validate mappingInfo state
1954
+ const existingDoc = await getOpenSearchById( openSearch.footfallDirectory, docId );
1955
+ const ticketSource = existingDoc?.body?._source;
1956
+
1957
+ if ( !ticketSource ) {
1958
+ return res.sendError( 'Ticket not found', 404 );
1959
+ }
1960
+
1961
+ const mappingInfo = Array.isArray( ticketSource.mappingInfo ) ? ticketSource.mappingInfo : [];
1962
+ if ( mappingInfo.length === 0 ) {
1963
+ return res.sendError( 'mappingInfo is missing for this ticket', 400 );
1964
+ }
1965
+
1966
+ const lastIndex = mappingInfo.length - 1;
1967
+ const lastEntry = mappingInfo[lastIndex];
1968
+
1969
+ if ( !lastEntry ) {
1970
+ return res.sendError( 'Unable to determine current ticket status', 400 );
1971
+ }
1972
+
1973
+ if ( String( lastEntry.status ).toLowerCase() !== 'open' ) {
1974
+ return res.sendError( 'Ticket is already picked by another user', 409 );
1975
+ }
1976
+
1977
+ const currentTime = new Date();
1978
+ const updatedMappingInfo = [ ...mappingInfo ];
1979
+ updatedMappingInfo[lastIndex] = {
1980
+ ...lastEntry,
1981
+ status: 'In-Progress',
1982
+ updatedAt: currentTime,
1983
+ };
1984
+
1985
+ const updatePayload = {
1986
+ doc: {
1987
+ status: 'In-Progress',
1988
+ mappingInfo: updatedMappingInfo,
1989
+ updatedAt: currentTime,
1990
+ },
1991
+ };
1992
+
1993
+ const updateResult = await updateOpenSearchData(
1994
+ openSearch.footfallDirectory,
1995
+ docId,
1996
+ updatePayload,
1997
+ );
1998
+
1999
+
2000
+ if ( !updateResult || !( updateResult.statusCode === 200 || updateResult.statusCode === 201 ) ) {
2001
+ return res.sendError( 'Failed to update ticket status', 500 );
2002
+ }
2003
+ return res.sendSuccess( 'Ticket status updated successfully' );
2004
+ } catch ( error ) {
2005
+ const err = error.message;
2006
+ logger.info( { error: err, function: 'updateUserTicketStatus' } );
2007
+ return res.sendError( err, 500 );
2008
+ }
2009
+ }
2010
+
@@ -3,7 +3,22 @@ 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(),
9
24
  comments: Joi.string().optional(),
@@ -491,3 +506,14 @@ export const updateTempStatusSchema = Joi.object().keys( {
491
506
  export const updateTempStatusValid = {
492
507
  body: updateTempStatusSchema,
493
508
  };
509
+
510
+ export const updateTicketStatusSchema = Joi.object().keys( {
511
+ storeId: Joi.string().required(),
512
+ dateString: Joi.string().required(),
513
+ mode: Joi.string().required(),
514
+
515
+ } );
516
+
517
+ export const updateTicketStatusValid = {
518
+ body: updateTicketStatusSchema,
519
+ };
@@ -1,7 +1,7 @@
1
1
  import express from 'express';
2
2
  import { getClusters, getConfig, isGrantedUsers, isTicketExists, ticketApprove, ticketCreation, ticketReview } 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';
3
+ import { assignTicket, createTicket, downloadTickets, getTaggedStores, getTickets, openTicketList, reviewerList, ticketList, ticketSummary, updateStatus, updateTempStatus, updateUserTicketStatus } from '../controllers/footfallDirectory.controllers.js';
4
+ import { createTicketValid, downloadTicketsValid, getTaggedStoresValid, getTicketsValid, openTicketListValid, reviewerListValid, ticketListValid, ticketSummaryValid, updateStatusValid, assignTicketValid, updateTempStatusValid, updateTicketStatusValid } 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();
@@ -19,5 +19,6 @@ footfallDirectoryRouter.get( '/reviewer-list', isAllowedSessionHandler, bulkVali
19
19
  footfallDirectoryRouter.post( '/open-ticket-list', isAllowedSessionHandler, bulkValidate( openTicketListValid ), openTicketList );
20
20
  footfallDirectoryRouter.post( '/assign-ticket', isAllowedSessionHandler, bulkValidate( assignTicketValid ), assignTicket );
21
21
  footfallDirectoryRouter.post( '/update-temp-status', isAllowedSessionHandler, bulkValidate( updateTempStatusValid ), updateTempStatus );
22
+ footfallDirectoryRouter.post( '/update-ticket-status', isAllowedSessionHandler, bulkValidate( updateTicketStatusValid ), updateUserTicketStatus );
22
23
 
23
24