tango-app-api-client 3.6.5-vms.9 → 3.6.6

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 CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { clientRouter } from './src/routes/client.routes.js';
4
4
  import { clientDocs } from './src/docs/client.docs.js';
5
+ import { vmsauditRouter } from './src/routes/vmsAudit.routes.js';
5
6
 
6
- export { clientRouter, clientDocs };
7
+ export { clientRouter, clientDocs, vmsauditRouter };
7
8
 
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "tango-app-api-client",
3
- "version": "3.6.5-vms.9",
3
+ "version": "3.6.6",
4
4
  "description": "client",
5
5
  "main": "index.js",
6
- "type": "module",
6
+ "type": "module",
7
7
  "scripts": {
8
8
  "start": "nodemon --exec \"eslint --fix . && node app.js\"",
9
9
  "build:patch": "node build.js patch && npm publish",
@@ -31,8 +31,8 @@
31
31
  "npm": "^10.9.1",
32
32
  "sharp": "^0.34.3",
33
33
  "swagger-ui-express": "^5.0.0",
34
- "tango-api-schema": "^2.4.27",
35
- "tango-app-api-middleware": "^3.6.0",
34
+ "tango-api-schema": "^2.5.25",
35
+ "tango-app-api-middleware": "^3.6.11",
36
36
  "winston": "^3.11.0",
37
37
  "winston-daily-rotate-file": "^5.0.0"
38
38
  },
@@ -1124,7 +1124,7 @@ export async function updateFeatureConfiguration( req, res ) {
1124
1124
  // await postApi( `${url.oldapidomain}/oldBrandUpdate/${data?._id}`, { brandConfigs: data.brandConfigs } );
1125
1125
 
1126
1126
  const keysArray = [
1127
- 'isExcludedArea', 'isPasserByData', 'isNormalized', 'isbillingDisabled', 'isCameraDisabled', 'isFootfallDirectory', 'isNOB', 'isNewTraffic', 'isTrax', 'isNewZone', 'isNewReports', 'isNewDashboard', 'streamBy', 'isFootfallView', 'isAIManager', 'isAIManagerAccessControl', 'isCameraEdit' ];
1127
+ 'isExcludedArea', 'isPasserByData', 'isNormalized', 'isbillingDisabled', 'isCameraDisabled', 'isFootfallDirectory', 'isNOB', 'isZonewiseNOB', 'isNewTraffic', 'isTrax', 'isNewZone', 'isNewReports', 'isNewDashboard', 'streamBy', 'isFootfallView', 'isAIManager', 'isAIManagerAccessControl', 'isCameraEdit' ];
1128
1128
  // Map and rename keys from previous client info for UI display and logging
1129
1129
  const oldData = {
1130
1130
  StoreOpenTime: previousData?.featureConfigs?.open,
@@ -1149,6 +1149,7 @@ export async function updateFeatureConfiguration( req, res ) {
1149
1149
  CameraBlurring: previousData?.featureConfigs?.isCameraDisabled == true ? 'Enabled' : 'Disabled',
1150
1150
  FootfallDirectory: previousData?.featureConfigs?.isFootfallDirectory == true ? 'Enabled' : 'Disabled',
1151
1151
  NOBStatus: previousData?.featureConfigs?.isNOB == true ? 'Enabled' : 'Disabled',
1152
+ NOBStatus: previousData?.featureConfigs?.isZonewiseNOB == true ? 'Enabled' : 'Disabled',
1152
1153
  EnableAnalyze: previousData?.featureConfigs?.isNewDashboard == true ? 'Enabled' : 'Disabled',
1153
1154
  Traffic: previousData?.featureConfigs?.isNewTraffic == true ? 'Enabled' : 'Disabled',
1154
1155
  Zone: previousData?.featureConfigs?.isNewZone == true ? 'Enabled' : 'Disabled',
@@ -1191,6 +1192,7 @@ export async function updateFeatureConfiguration( req, res ) {
1191
1192
  CameraBlurring: postData?.featureConfigs?.isCameraDisabled == true ? 'Enabled' : 'Disabled',
1192
1193
  FootfallDirectory: postData?.featureConfigs?.isFootfallDirectory == true ? 'Enabled' : 'Disabled',
1193
1194
  NOBStatus: postData?.featureConfigs?.isNOB == true ? 'Enabled' : 'Disabled',
1195
+ NOBStatus: postData?.featureConfigs?.isZonewiseNOB == true ? 'Enabled' : 'Disabled',
1194
1196
  EnableAnalyze: postData?.featureConfigs?.isNewDashboard == true ? 'Enabled' : 'Disabled',
1195
1197
  Traffic: postData?.featureConfigs?.isNewTraffic == true ? 'Enabled' : 'Disabled',
1196
1198
  Zone: postData?.featureConfigs?.isNewZone == true ? 'Enabled' : 'Disabled',
@@ -1907,7 +1909,6 @@ export async function clientListV1( req, res ) {
1907
1909
  try {
1908
1910
  const inputData = req.body;
1909
1911
  let clientQuery = [];
1910
- logger.info( { message: req?.user?.role } );
1911
1912
  if ( req?.user?.role !== 'superadmin' ) {
1912
1913
  const query = [
1913
1914
  {
@@ -2039,6 +2040,7 @@ export async function clientListV1( req, res ) {
2039
2040
  $cond: [ { $and: [ { $ne: [ '$stores.status', 'active' ] } ] }, 1, 0,
2040
2041
  ],
2041
2042
  },
2043
+ stores: 1,
2042
2044
  },
2043
2045
  },
2044
2046
  {
@@ -2053,6 +2055,7 @@ export async function clientListV1( req, res ) {
2053
2055
  clientName: { $first: '$clientName' },
2054
2056
  subscriptionPlan: { $first: '$subscriptionType' },
2055
2057
  PaymentPlan: { $first: '$PaymentPlan' },
2058
+ stores: { $first: '$stores' },
2056
2059
  },
2057
2060
  },
2058
2061
  {
@@ -2095,6 +2098,9 @@ export async function clientListV1( req, res ) {
2095
2098
  installedStore: 1,
2096
2099
  activeStores: 1,
2097
2100
  InactiveStores: 1,
2101
+ installedPendingwithActive: {
2102
+ $cond: [ { $and: [ { $ne: [ '$ticket.status', 'closed' ] }, { $ne: [ '$stores.status', 'deactive' ] } ] }, 1, 0 ],
2103
+ },
2098
2104
  installedPending: {
2099
2105
  $cond: [ { $and: [ { $ne: [ '$ticket.status', 'closed' ] } ] }, 1, 0 ],
2100
2106
  },
@@ -2115,6 +2121,7 @@ export async function clientListV1( req, res ) {
2115
2121
  clientName: { $first: '$clientName' },
2116
2122
  subscriptionPlan: { $first: '$subscriptionPlan' },
2117
2123
  PaymentPlan: { $first: '$PaymentPlan' },
2124
+ installedPendingwithActive: { $sum: '$installedPendingwithActive' },
2118
2125
  installedPending: { $sum: '$installedPending' },
2119
2126
  installedFailed: { $sum: '$installedFailed' },
2120
2127
  },
@@ -2126,7 +2133,7 @@ export async function clientListV1( req, res ) {
2126
2133
  installedStore: 1,
2127
2134
  activeStores: {
2128
2135
  $max: [
2129
- { $subtract: [ '$activeStores', '$installedPending' ] },
2136
+ { $subtract: [ '$activeStores', '$installedPendingwithActive' ] },
2130
2137
  0,
2131
2138
  ],
2132
2139
  },
@@ -2150,6 +2157,8 @@ export async function clientListV1( req, res ) {
2150
2157
  },
2151
2158
  installedPending: 1,
2152
2159
  installedFailed: 1,
2160
+ installedPendingwithActive: 1,
2161
+ activeStores1: '$activeStores',
2153
2162
  ProgressBar: {
2154
2163
  $cond: {
2155
2164
  if: { $eq: [ '$onboardedStores', 0 ] },
@@ -2217,7 +2226,6 @@ export async function clientListV1( req, res ) {
2217
2226
  );
2218
2227
  }
2219
2228
  const clientList = await aggregateClient( clientQuery );
2220
-
2221
2229
  if ( inputData.isExport ) {
2222
2230
  const exportResult = [];
2223
2231
  for ( let client of clientList ) {
@@ -2946,12 +2954,76 @@ export async function getrevopconfig( req, res ) {
2946
2954
  export async function updateFDConfig( req, res ) {
2947
2955
  try {
2948
2956
  const inputData = req.body;
2957
+ const { taggingLimitation, ...otherData } = inputData;
2949
2958
  const inputQuery = req.query;
2950
2959
  const query ={
2951
2960
  clientId: inputQuery.clientId,
2952
2961
  };
2962
+ if ( taggingLimitation ) {
2963
+ const newValues = taggingLimitation;
2964
+ const today = new Date().toISOString().split( 'T' )[0];
2965
+ const getUpdateData = await clientModel.updateOne(
2966
+ {
2967
+ 'clientId': inputQuery.clientId,
2968
+ 'footfallDirectoryConfigs.taggingLimitation.effectiveFrom': today,
2969
+ },
2970
+ {
2971
+ $set: {
2972
+ 'footfallDirectoryConfigs.taggingLimitation.$.values': newValues,
2973
+ },
2974
+ },
2975
+ );
2976
+
2977
+ if ( getUpdateData?.matchedCount === 0 ) {
2978
+ await clientModel.updateOne(
2979
+ { clientId: inputQuery.clientId },
2980
+ {
2981
+ $push: {
2982
+ 'footfallDirectoryConfigs.taggingLimitation': {
2983
+ effectiveFrom: today,
2984
+ values: newValues,
2985
+ },
2986
+ },
2987
+ },
2988
+ );
2989
+ }
2990
+ }
2991
+
2953
2992
  // update the footfall directory configuration data
2954
- let result = await updateOneClient( query, { footfallDirectoryConfigs: inputData } );
2993
+ let record = {};
2994
+ if ( otherData?.contactEmail ) {
2995
+ record['footfallDirectoryConfigs.contactEmail'] =otherData?.contactEmail;
2996
+ }
2997
+
2998
+ if ( otherData?.revision ) {
2999
+ record['footfallDirectoryConfigs.revision'] =otherData?.revision;
3000
+ }
3001
+
3002
+ if ( otherData?.allowImageView ) {
3003
+ record['footfallDirectoryConfigs.allowImageView'] =otherData?.allowImageView;
3004
+ }
3005
+
3006
+ if ( otherData?.allowTicketCreation ) {
3007
+ record['footfallDirectoryConfigs.allowTicketCreation'] =otherData?.allowTicketCreation;
3008
+ }
3009
+
3010
+ if ( otherData?.isAutoCloseEnable ) {
3011
+ record['footfallDirectoryConfigs.isAutoCloseEnable'] =otherData?.isAutoCloseEnable;
3012
+ }
3013
+
3014
+ if ( otherData?.autoCloseAccuracy ) {
3015
+ record['footfallDirectoryConfigs.autoCloseAccuracy'] =otherData?.autoCloseAccuracy;
3016
+ }
3017
+
3018
+ if ( otherData?.accuracyBreach ) {
3019
+ record['footfallDirectoryConfigs.accuracyBreach'] =otherData?.accuracyBreach;
3020
+ }
3021
+
3022
+ if ( otherData?.tangoReview ) {
3023
+ record['footfallDirectoryConfigs.tangoReview'] =otherData?.tangoReview;
3024
+ }
3025
+
3026
+ let result = await updateOneClient( query, record );
2955
3027
  if ( result?.acknowledged === true ) {
2956
3028
  return res.sendSuccess( result );
2957
3029
  } else {
@@ -2967,10 +3039,89 @@ export async function updateFDConfig( req, res ) {
2967
3039
  export async function getFDConfig( req, res ) {
2968
3040
  try {
2969
3041
  const inputData = req.query;
2970
- let result = await findOneClient( { clientId: inputData.clientId }, { footfallDirectoryConfigs: 1 } );
2971
- if ( result===null ) {
3042
+ // let result = await findOneClient( { clientId: inputData.clientId }, { footfallDirectoryConfigs: 1 } );
3043
+ const configQuery = [
3044
+ {
3045
+ $match: {
3046
+ clientId: inputData?.clientId,
3047
+ },
3048
+ },
3049
+
3050
+ // Convert all effectiveFrom to proper Date
3051
+ {
3052
+ $addFields: {
3053
+ taggingLimitationWithDate: {
3054
+ $map: {
3055
+ input: '$footfallDirectoryConfigs.taggingLimitation',
3056
+ as: 'item',
3057
+ in: {
3058
+ effectiveFrom: { $toDate: '$$item.effectiveFrom' },
3059
+ values: '$$item.values',
3060
+ },
3061
+ },
3062
+ },
3063
+ },
3064
+ },
3065
+
3066
+ // Filter items <= input date
3067
+ {
3068
+ $addFields: {
3069
+ matchedLimitation: {
3070
+ $filter: {
3071
+ input: '$taggingLimitationWithDate',
3072
+ as: 'item',
3073
+ cond: {
3074
+ $lte: [
3075
+ '$$item.effectiveFrom',
3076
+ { $toDate: inputData.dateString },
3077
+ ],
3078
+ },
3079
+ },
3080
+ },
3081
+ },
3082
+ },
3083
+
3084
+ // Sort DESC and pick ONLY top 1 -> latest effective record
3085
+ {
3086
+ $addFields: {
3087
+ effectiveLimitation: {
3088
+ $arrayElemAt: [
3089
+ {
3090
+ $slice: [
3091
+ {
3092
+ $sortArray: {
3093
+ input: '$matchedLimitation',
3094
+ sortBy: { effectiveFrom: -1 },
3095
+ },
3096
+ },
3097
+ 1,
3098
+ ],
3099
+ },
3100
+ 0,
3101
+ ],
3102
+ },
3103
+ },
3104
+ },
3105
+
3106
+ {
3107
+ $project: {
3108
+ 'config': 1,
3109
+ 'effectiveLimitation': 1,
3110
+ 'footfallDirectoryConfigs': 1,
3111
+
3112
+ },
3113
+ },
3114
+ ];
3115
+
3116
+
3117
+ const getData = await aggregateClient( configQuery );
3118
+ let result = getData[0];
3119
+ if ( !result || result===null ) {
2972
3120
  return res.sendError( 'no data found', 204 );
2973
3121
  }
3122
+ result.footfallDirectoryConfigs.taggingLimitation = result?.effectiveLimitation?.values;
3123
+ delete result.effectiveLimitation;
3124
+
2974
3125
  return res.sendSuccess( result );
2975
3126
  } catch ( error ) {
2976
3127
  const err = error.message || 'Internal Server Error';
@@ -2983,38 +3134,38 @@ export async function getFDConfig( req, res ) {
2983
3134
  export async function updateTaggingType( req, res ) {
2984
3135
  try {
2985
3136
  const inputData = req.body;
2986
-
2987
- const inputQuery = req.query; // up
2988
- const types = inputData?.taggingLimitation?.map( ( x ) => x.type );
2989
- // Step 1: remove existing items with same "type"
2990
- await clientModel.updateOne(
2991
- { clientId: inputQuery.clientId },
3137
+ const newValues = inputData.taggingLimitation;
3138
+ const today = new Date().toISOString().split( 'T' )[0];
3139
+ logger.info( { today, newValues } );
3140
+ const result = await clientModel.updateOne(
2992
3141
  {
2993
- $pull: {
2994
- 'footfallDirectoryConfigs.taggingLimitation': {
2995
- type: { $in: types },
2996
- },
2997
- },
3142
+ 'clientId': inputData?.clientId,
3143
+ 'footfallDirectoryConfigs.taggingLimitation.effectiveFrom': today,
2998
3144
  },
2999
- );
3000
-
3001
- // Remove duplicate entries by type
3002
- const uniqueData = uniqueByType( inputData.taggingLimitation );
3003
-
3004
- // Step 2: insert fresh new items
3005
- let result =await clientModel.updateOne(
3006
- { clientId: inputQuery.clientId },
3007
3145
  {
3008
- $addToSet: {
3009
- 'footfallDirectoryConfigs.taggingLimitation': {
3010
- $each: uniqueData,
3011
- },
3146
+ $set: {
3147
+ 'footfallDirectoryConfigs.taggingLimitation.$.values': newValues,
3012
3148
  },
3013
3149
  },
3014
3150
  );
3151
+ logger.info( { result } );
3152
+ if ( result?.matchedCount === 0 ) {
3153
+ await clientModel.updateOne(
3154
+ { clientId: inputData.clientId },
3155
+ {
3156
+ $push: {
3157
+ 'footfallDirectoryConfigs.taggingLimitation': {
3158
+ effectiveFrom: today,
3159
+ values: newValues,
3160
+ },
3161
+ },
3162
+ },
3163
+ );
3164
+ }
3165
+
3015
3166
 
3016
3167
  if ( result?.acknowledged === true ) {
3017
- return res.sendSuccess( result );
3168
+ return res.sendSuccess( 'Tagging limitation has been updated' );
3018
3169
  } else {
3019
3170
  return res.sendError( 'no data', 204 );
3020
3171
  }
@@ -3025,14 +3176,14 @@ export async function updateTaggingType( req, res ) {
3025
3176
  }
3026
3177
  }
3027
3178
 
3028
- function uniqueByType( arr ) {
3029
- const seen = new Set();
3030
- return arr.filter( ( item ) => {
3031
- if ( seen.has( item.type ) ) return false;
3032
- seen.add( item.type );
3033
- return true;
3034
- } );
3035
- }
3179
+ // function uniqueByType( arr ) {
3180
+ // const seen = new Set();
3181
+ // return arr.filter( ( item ) => {
3182
+ // if ( seen.has( item.type ) ) return false;
3183
+ // seen.add( item.type );
3184
+ // return true;
3185
+ // } );
3186
+ // }
3036
3187
 
3037
3188
  export async function createStoreRequest( req, res ) {
3038
3189
  try {
@@ -3050,11 +3201,11 @@ export async function createStoreRequest( req, res ) {
3050
3201
  const upsertRecord = await updateOneUpsertVmsStoreRequest( { storeId: inputData?.storeId, dateString: inputData?.dateString }, record );
3051
3202
  logger.info( { upsertRecord } );
3052
3203
  if ( upsertRecord?.upsertedCount === 1 ) {
3053
- return res.sendSuccess( 'The Request has been sent Successfully' );
3204
+ return res.sendTemp( 'The Request has been sent Successfully' );
3054
3205
  } else if ( upsertRecord?.matchedCount === 1 && upsertRecord?.modifiedCount === 1 ) {
3055
- return res.sendSuccess( 'The Request has been updated Successfully' );
3206
+ return res.sendTemp( 'The Request has been updated Successfully' );
3056
3207
  } else if ( upsertRecord?.matchedCount === 1 && upsertRecord?.modifiedCount === 0 ) {
3057
- return res.sendSuccess( 'The Request already exists and nothing to update' );
3208
+ return res.sendTemp( 'The Request already exists and nothing to update' );
3058
3209
  } else {
3059
3210
  return res.sendError( 'Internal Server Error', 500 );
3060
3211
  }
@@ -1,7 +1,7 @@
1
- import { logger, searchOpenSearchData } from 'tango-app-api-middleware';
1
+ import { logger, searchOpenSearchData, getOpenSearchById, updateOpenSearchData, deleteById } from 'tango-app-api-middleware';
2
2
  import { findOneStore } from '../service/store.service.js';
3
- import { aggregatevmsUserAudit, createvmsUserAudit, findOnevmsUserAudit, updateOnevmsUserAudit } from '../service/vmsuserAudit.service.js';
4
- import { createvmsAuditLog, findOnevmsAuditLog } from '../service/vmsauditLog.service.js';
3
+ import { aggregatevmsUserAudit, createvmsUserAudit, findOnevmsUserAudit, updateOnevmsUserAudit, updatemanyvmsUserAudit, deletevmsUserAudit } from '../service/vmsuserAudit.service.js';
4
+ import { createvmsAuditLog, findOnevmsAuditLog, deletevmsAuditLog } from '../service/vmsauditLog.service.js';
5
5
  import { insertOpenSearchData, clearScroll, scrollResponse } from 'tango-app-api-middleware';
6
6
  import { findOneUser } from '../service/user.service.js';
7
7
  import dayjs from 'dayjs';
@@ -112,6 +112,51 @@ export async function getAuditFile( req, res ) {
112
112
  address: '$storeProfile.address',
113
113
  };
114
114
  const storeDetails = await findOneStore( storeQuery, storeFields );
115
+ let docId = `${inputData.storeId}_${inputData.Date}_footfall-directory-tagging`;
116
+ if ( inputData.tickettype === 'internal' ) {
117
+ docId = `${inputData.storeId}_${inputData.Date}_internal_footfall-directory-tagging`;
118
+ }
119
+ console.log( '🚀 ~ getAuditFile ~ docId:draft', docId );
120
+ const existinginternalDoc = await getOpenSearchById( openSearch.footfallDirectory, docId );
121
+ let ticketSource = existinginternalDoc?.body?._source;
122
+ const currentTime = new Date();
123
+ const updatePayload = {
124
+ doc: {
125
+
126
+ updatedAt: currentTime,
127
+ createdByRole: req?.user?.role || '',
128
+ createdByEmail: req?.user?.email || '',
129
+ createdByUserName: req?.user?.userName || '',
130
+ createdByUserId: req?.user?._id || '',
131
+ },
132
+ };
133
+ console.log( '🚀 ~ getAuditFile ~ updatePayload:', updatePayload );
134
+ console.log( '🚀 ~ getAuditFile ~ ticketSource:', ticketSource );
135
+ if ( ticketSource ) {
136
+ ticketSource.mappingInfo.map( ( data ) => {
137
+ if ( data.type === 'tangoreview' ) {
138
+ data.status = 'In-Progress';
139
+ }
140
+ } );
141
+ ticketSource.status = 'In-Progress';
142
+ ticketSource.createdByRole = req?.user?.role || '';
143
+ ticketSource.createdByEmail = req?.user?.email || '';
144
+ ticketSource.createdByUserName = req?.user?.userName || '';
145
+ ticketSource.createdByUserId = req?.user?._id || '';
146
+ console.log( '🚀 ~ getAuditFile ~ ticketSource:', ticketSource );
147
+ await updateOpenSearchData(
148
+ openSearch.footfallDirectory,
149
+ docId,
150
+ { doc: ticketSource },
151
+
152
+ );
153
+ } else if ( ticketSource && inputData.tickettype === 'internal' ) {
154
+ await updateOpenSearchData(
155
+ openSearch.footfallDirectory,
156
+ docId,
157
+ updatePayload,
158
+ );
159
+ }
115
160
  return res.sendSuccess( {
116
161
  result: log.draftedData,
117
162
  storeId: storeDetails?.storeId,
@@ -148,6 +193,9 @@ export async function getAuditFile( req, res ) {
148
193
  terms: { EmployeeStatusFinal: [ 1, 2 ] },
149
194
  },
150
195
  ],
196
+ 'must_not': [
197
+ { term: { outputCluster: 0 } },
198
+ ],
151
199
  'should': [
152
200
  { 'term': { 'isJunk': false } },
153
201
  { 'bool': { 'must_not': { 'exists': { 'field': 'isJunk' } } } },
@@ -158,9 +206,55 @@ export async function getAuditFile( req, res ) {
158
206
 
159
207
  };
160
208
  console.log( openSearch.vmsAudit );
161
- let list =inputData.nextId? await scrollResponse( inputData.nextId ): await searchOpenSearchData( openSearch.vmsAudit, query );
209
+ let list = inputData.nextId ? await scrollResponse( inputData.nextId ) : await searchOpenSearchData( openSearch.vmsAudit, query );
210
+
211
+ let docId = `${inputData.storeId}_${inputData.Date}_footfall-directory-tagging`;
212
+ if ( inputData.tickettype === 'internal' ) {
213
+ docId = `${inputData.storeId}_${inputData.Date}_internal_footfall-directory-tagging`;
214
+ }
215
+ console.log( '🚀 ~ getAuditFile ~ docId:draft', docId );
216
+ const existinginternalDoc = await getOpenSearchById( openSearch.footfallDirectory, docId );
217
+ let ticketSource = existinginternalDoc?.body?._source;
218
+ const currentTime = new Date();
219
+ const updatePayload = {
220
+ doc: {
221
+
222
+ updatedAt: currentTime,
223
+ createdByRole: req?.user?.role || '',
224
+ createdByEmail: req?.user?.email || '',
225
+ createdByUserName: req?.user?.userName || '',
226
+ createdByUserId: req?.user?._id || '',
227
+ },
228
+ };
229
+ console.log( '🚀 ~ getAuditFile ~ updatePayload:', updatePayload );
230
+ console.log( '🚀 ~ getAuditFile ~ ticketSource:', ticketSource );
231
+ if ( ticketSource ) {
232
+ ticketSource.mappingInfo.map( ( data ) => {
233
+ if ( data.type === 'tangoreview' ) {
234
+ data.status = 'In-Progress';
235
+ console.log( '🚀 ~ getAuditFile ~ data.status:', data.status );
236
+ }
237
+ } );
238
+ ticketSource.status = 'In-Progress';
239
+ ticketSource.createdByRole = req?.user?.role || '';
240
+ ticketSource.createdByEmail = req?.user?.email || '';
241
+ ticketSource.createdByUserName = req?.user?.userName || '';
242
+ ticketSource.createdByUserId = req?.user?._id || '';
243
+ console.log( '🚀 ~ getAuditFile ~ ticketSource:', ticketSource );
244
+ await updateOpenSearchData(
245
+ openSearch.footfallDirectory,
246
+ docId,
247
+ { doc: ticketSource },
248
+ );
249
+ } else if ( ticketSource && inputData.tickettype === 'internal' ) {
250
+ await updateOpenSearchData(
251
+ openSearch.footfallDirectory,
252
+ docId,
253
+ updatePayload,
254
+ );
255
+ }
162
256
  const folderPath = list?.body?.hits?.hits;
163
- if ( list?.body?.hits?.hits?.length ==0 ) {
257
+ if ( list?.body?.hits?.hits?.length == 0 ) {
164
258
  await clearScroll( list?.body?._scroll_id );
165
259
  }
166
260
  if ( folderPath?.length > 0 ) {
@@ -238,7 +332,7 @@ export async function getAuditFile( req, res ) {
238
332
  Date: inputData.Date,
239
333
  auditId: insertData._id,
240
334
  userId: insertData.userId,
241
- nextToken: list?.body?._scroll_id ?list?.body?._scroll_id:null,
335
+ nextToken: list?.body?._scroll_id ? list?.body?._scroll_id : null,
242
336
 
243
337
  },
244
338
  isDraft: insertData.isDraft,
@@ -343,3 +437,88 @@ export async function getDraftedData( req, res ) {
343
437
  return res.sendError( err, 500 );
344
438
  }
345
439
  }
440
+
441
+
442
+ export async function reAssignAudit( req, res ) {
443
+ try {
444
+ const openSearch = JSON.parse( process.env.OPENSEARCH );
445
+ let inputData = req.body;
446
+ let docId = `${inputData.storeId}_${inputData.dateString}_internal_footfall-directory-tagging`;
447
+ if ( inputData.tickettype === 'store' ) {
448
+ docId = `${inputData.storeId}_${inputData.dateString}_footfall-directory-tagging`;
449
+ }
450
+ console.log( '🚀 ~ getAuditFile ~ docId:draft', docId );
451
+ const existingDoc = await getOpenSearchById( openSearch.footfallDirectory, docId );
452
+ const ticketSource = existingDoc?.body?._source;
453
+ const currentTime = new Date();
454
+ const userdata = await findOneUser( { email: inputData.email } );
455
+ const updatePayload = {
456
+ doc: {
457
+ status: 'In-Progress',
458
+ updatedAt: currentTime,
459
+ createdByRole: userdata?.role || '',
460
+ createdByEmail: userdata?.email || '',
461
+ createdByUserName: userdata?.userName || '',
462
+ createdByUserId: userdata?._id || '',
463
+ },
464
+ };
465
+ console.log( '🚀 ~ getAuditFile ~ updatePayload:', updatePayload );
466
+ console.log( '🚀 ~ getAuditFile ~ ticketSource:', ticketSource );
467
+ if ( ticketSource ) {
468
+ await updateOpenSearchData(
469
+ openSearch.footfallDirectory,
470
+ docId,
471
+ updatePayload,
472
+ );
473
+ }
474
+
475
+ console.log( '🚀 ~ reAssignAudit ~ inputData.dateString:', inputData.dateString );
476
+ await updatemanyvmsUserAudit(
477
+ { auditStatus: { $ne: 'completed' }, storeId: inputData.storeId, fileDate: inputData.dateString },
478
+ { status: 'skipped' } );
479
+
480
+
481
+ return res.sendSuccess( 'Ticket Reassigned Successfully' );
482
+ } catch ( error ) {
483
+ const err = error.message || 'Internal Server Error';
484
+ logger.error( {
485
+ error: error,
486
+ message: req.query,
487
+ function: 'reAssignAudit',
488
+ } );
489
+ return res.sendError( err, 500 );
490
+ }
491
+ }
492
+
493
+ export async function StartNewaudit( req, res ) {
494
+ try {
495
+ const openSearch = JSON.parse( process.env.OPENSEARCH );
496
+ console.log( req.body );
497
+ let docId = `${req.body.storeId}_${req.body.Date}_internal_footfall-directory-tagging`;
498
+ const existingDoc = await getOpenSearchById( openSearch.footfallDirectory, docId );
499
+ const ticketSource = existingDoc?.body?._source;
500
+ if ( ticketSource ) {
501
+ let detete = await deleteById( openSearch.footfallDirectory, docId );
502
+ console.log( '🚀 ~ StartNewaudit ~ detete:', detete );
503
+ }
504
+
505
+ let deleteQuery = {
506
+ storeId: req.body.storeId,
507
+ fileDate: req.body.Date,
508
+ };
509
+ await deletevmsAuditLog( deleteQuery );
510
+ await deletevmsUserAudit( deleteQuery );
511
+
512
+ return res.sendSuccess( 'deleted successfully' );
513
+ } catch ( error ) {
514
+ const err = error.message || 'Internal Server Error';
515
+ logger.error( {
516
+ error: error,
517
+ message: req.body,
518
+ function: 'StartNewaudit',
519
+ } );
520
+ return res.sendError( err, 500 );
521
+ }
522
+ }
523
+
524
+
@@ -119,6 +119,7 @@ export const featureConfigurationSchemaBody = joi.object(
119
119
  isNewZone: joi.boolean().optional(),
120
120
  isNewReports: joi.boolean().optional(),
121
121
  isNOB: joi.boolean().optional(),
122
+ isZonewiseNOB: joi.boolean().optional(),
122
123
  isNewZoneV2: joi.boolean().optional(),
123
124
  isTrax: joi.boolean().optional(),
124
125
  isRevops: joi.boolean().optional(),
@@ -370,6 +371,7 @@ export const updateFDConfigBodySchema = joi.object( {
370
371
  unit: joi.string().required(),
371
372
  key: joi.string().required(),
372
373
  } ) ).optional(),
374
+ contactEmail: joi.string().optional().allow( '' ),
373
375
 
374
376
  } );
375
377
 
@@ -377,8 +379,12 @@ export const updateFDConfigQuerySchema = joi.object( {
377
379
  clientId: joi.string().required(),
378
380
  } );
379
381
 
382
+
383
+ const todayDate = () => new Date().toISOString().split( 'T' )[0];
384
+
380
385
  export const getFDConfigSchema = joi.object( {
381
386
  clientId: joi.string().required(),
387
+ dateString: joi.string().optional().default( () => todayDate() ),
382
388
  } );
383
389
 
384
390
  export const updateFDConfigValid = {
@@ -395,6 +401,9 @@ export const updateTaggingTypeSchema = joi.object( {
395
401
  type: joi.string().required(),
396
402
  value: joi.number().required(),
397
403
  unit: joi.string().required(),
404
+ name: joi.string().required(),
405
+ iconName: joi.string().required(),
406
+ key: joi.string().required(),
398
407
  } ) ).required(),
399
408
 
400
409
  } );
@@ -12,6 +12,7 @@ export const getFileSchema = joi.object( {
12
12
  storeId: joi.string().required(),
13
13
  Date: joi.string().required(),
14
14
  count: joi.string().required(),
15
+ tickettype: joi.string().required(),
15
16
  } );
16
17
 
17
18
 
@@ -1,10 +1,12 @@
1
1
  import express from 'express';
2
2
  import { accessVerification, isAllowedSessionHandler, validate } from 'tango-app-api-middleware';
3
3
  import { getDraftedDataValid, getFileValid } from '../dtos/vmsAudit.dtos.js';
4
- import { getAuditFile, getDraftedData, saveDraft } from '../controllers/vmsAudit.controller.js';
4
+ import { getAuditFile, getDraftedData, saveDraft, reAssignAudit, StartNewaudit } from '../controllers/vmsAudit.controller.js';
5
5
  export const vmsauditRouter = express.Router();
6
6
 
7
7
 
8
8
  vmsauditRouter.get( '/get-file', isAllowedSessionHandler, accessVerification( { userType: [ 'tango' ] } ), validate( getFileValid ), getAuditFile );
9
9
  vmsauditRouter.post( '/save-draft', isAllowedSessionHandler, accessVerification( { userType: [ 'tango' ] } ), saveDraft );
10
10
  vmsauditRouter.get( '/get-drafted-data', isAllowedSessionHandler, accessVerification( { userType: [ 'tango' ] } ), validate( getDraftedDataValid ), getDraftedData );
11
+ vmsauditRouter.post( '/reAssign-audit', isAllowedSessionHandler, accessVerification( { userType: [ 'tango' ] } ), reAssignAudit );
12
+ vmsauditRouter.post( '/StartNewaudit', isAllowedSessionHandler, accessVerification( { userType: [ 'tango' ] } ), StartNewaudit );
@@ -158,6 +158,7 @@ export function featureConfigurationUpdate( query, inputData ) {
158
158
  'featureConfigs.isNewZone': inputData?.isNewZone,
159
159
  'featureConfigs.isNewReports': inputData?.isNewReports,
160
160
  'featureConfigs.isNOB': inputData?.isNOB,
161
+ 'featureConfigs.isZonewiseNOB': inputData?.isZonewiseNOB,
161
162
  'featureConfigs.isNewZoneV2': inputData?.isNewZoneV2,
162
163
  'featureConfigs.isTrax': inputData?.isTrax,
163
164
  'featureConfigs.isRevops': inputData?.isRevops,
@@ -4,6 +4,9 @@ import vmsauditLogsModel from 'tango-api-schema/schema/vmsauditLogs.model.js';
4
4
  export function createvmsAuditLog( record ) {
5
5
  return vmsauditLogsModel.create( record );
6
6
  }
7
+ export function deletevmsAuditLog( record ) {
8
+ return vmsauditLogsModel.deleteMany( record );
9
+ }
7
10
 
8
11
  export function findOnevmsAuditLog( query, fields={}, sort={ createdAt: -1 }, limit=10 ) {
9
12
  return vmsauditLogsModel.findOne( query, fields ).sort( sort ).limit( limit );
@@ -8,6 +8,9 @@ export function aggregatevmsUserAudit( query ) {
8
8
  export function updateOnevmsUserAudit( query, record ) {
9
9
  return vmsuserAuditModel.updateOne( query, { $set: record } );
10
10
  }
11
+ export function updatemanyvmsUserAudit( query, record ) {
12
+ return vmsuserAuditModel.updateMany( query, { $set: record } );
13
+ }
11
14
 
12
15
  export function createvmsUserAudit( record ) {
13
16
  return vmsuserAuditModel.create( record );
@@ -20,3 +23,6 @@ export function findOnevmsUserAudit( query, fields ) {
20
23
  export function aggregatevmsUserAuditCount( query ) {
21
24
  return vmsuserAuditModel.aggregate( query );
22
25
  }
26
+ export function deletevmsUserAudit( query ) {
27
+ return vmsuserAuditModel.deleteMany( query );
28
+ }