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

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.7",
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.54",
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','isFootfallDirectoryonlyTango', '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,
@@ -1148,7 +1148,9 @@ export async function updateFeatureConfiguration( req, res ) {
1148
1148
  Billing: previousData?.featureConfigs?.isbillingDisabled == true ? 'Enabled' : 'Disabled',
1149
1149
  CameraBlurring: previousData?.featureConfigs?.isCameraDisabled == true ? 'Enabled' : 'Disabled',
1150
1150
  FootfallDirectory: previousData?.featureConfigs?.isFootfallDirectory == true ? 'Enabled' : 'Disabled',
1151
+ FootfallDirectory: previousData?.featureConfigs?.isFootfallDirectoryonlyTango == true ? 'Enabled' : 'Disabled',
1151
1152
  NOBStatus: previousData?.featureConfigs?.isNOB == true ? 'Enabled' : 'Disabled',
1153
+ NOBStatus: previousData?.featureConfigs?.isZonewiseNOB == true ? 'Enabled' : 'Disabled',
1152
1154
  EnableAnalyze: previousData?.featureConfigs?.isNewDashboard == true ? 'Enabled' : 'Disabled',
1153
1155
  Traffic: previousData?.featureConfigs?.isNewTraffic == true ? 'Enabled' : 'Disabled',
1154
1156
  Zone: previousData?.featureConfigs?.isNewZone == true ? 'Enabled' : 'Disabled',
@@ -1190,7 +1192,9 @@ export async function updateFeatureConfiguration( req, res ) {
1190
1192
  Billing: postData?.featureConfigs?.isbillingDisabled == true ? 'Enabled' : 'Disabled',
1191
1193
  CameraBlurring: postData?.featureConfigs?.isCameraDisabled == true ? 'Enabled' : 'Disabled',
1192
1194
  FootfallDirectory: postData?.featureConfigs?.isFootfallDirectory == true ? 'Enabled' : 'Disabled',
1195
+ FootfallDirectory: postData?.featureConfigs?.isFootfallDirectoryonlyTango == true ? 'Enabled' : 'Disabled',
1193
1196
  NOBStatus: postData?.featureConfigs?.isNOB == true ? 'Enabled' : 'Disabled',
1197
+ NOBStatus: postData?.featureConfigs?.isZonewiseNOB == true ? 'Enabled' : 'Disabled',
1194
1198
  EnableAnalyze: postData?.featureConfigs?.isNewDashboard == true ? 'Enabled' : 'Disabled',
1195
1199
  Traffic: postData?.featureConfigs?.isNewTraffic == true ? 'Enabled' : 'Disabled',
1196
1200
  Zone: postData?.featureConfigs?.isNewZone == true ? 'Enabled' : 'Disabled',
@@ -1907,7 +1911,6 @@ export async function clientListV1( req, res ) {
1907
1911
  try {
1908
1912
  const inputData = req.body;
1909
1913
  let clientQuery = [];
1910
- logger.info( { message: req?.user?.role } );
1911
1914
  if ( req?.user?.role !== 'superadmin' ) {
1912
1915
  const query = [
1913
1916
  {
@@ -2039,6 +2042,7 @@ export async function clientListV1( req, res ) {
2039
2042
  $cond: [ { $and: [ { $ne: [ '$stores.status', 'active' ] } ] }, 1, 0,
2040
2043
  ],
2041
2044
  },
2045
+ stores: 1,
2042
2046
  },
2043
2047
  },
2044
2048
  {
@@ -2053,6 +2057,7 @@ export async function clientListV1( req, res ) {
2053
2057
  clientName: { $first: '$clientName' },
2054
2058
  subscriptionPlan: { $first: '$subscriptionType' },
2055
2059
  PaymentPlan: { $first: '$PaymentPlan' },
2060
+ stores: { $first: '$stores' },
2056
2061
  },
2057
2062
  },
2058
2063
  {
@@ -2095,6 +2100,9 @@ export async function clientListV1( req, res ) {
2095
2100
  installedStore: 1,
2096
2101
  activeStores: 1,
2097
2102
  InactiveStores: 1,
2103
+ installedPendingwithActive: {
2104
+ $cond: [ { $and: [ { $ne: [ '$ticket.status', 'closed' ] }, { $ne: [ '$stores.status', 'deactive' ] } ] }, 1, 0 ],
2105
+ },
2098
2106
  installedPending: {
2099
2107
  $cond: [ { $and: [ { $ne: [ '$ticket.status', 'closed' ] } ] }, 1, 0 ],
2100
2108
  },
@@ -2115,6 +2123,7 @@ export async function clientListV1( req, res ) {
2115
2123
  clientName: { $first: '$clientName' },
2116
2124
  subscriptionPlan: { $first: '$subscriptionPlan' },
2117
2125
  PaymentPlan: { $first: '$PaymentPlan' },
2126
+ installedPendingwithActive: { $sum: '$installedPendingwithActive' },
2118
2127
  installedPending: { $sum: '$installedPending' },
2119
2128
  installedFailed: { $sum: '$installedFailed' },
2120
2129
  },
@@ -2126,7 +2135,7 @@ export async function clientListV1( req, res ) {
2126
2135
  installedStore: 1,
2127
2136
  activeStores: {
2128
2137
  $max: [
2129
- { $subtract: [ '$activeStores', '$installedPending' ] },
2138
+ { $subtract: [ '$activeStores', '$installedPendingwithActive' ] },
2130
2139
  0,
2131
2140
  ],
2132
2141
  },
@@ -2150,6 +2159,8 @@ export async function clientListV1( req, res ) {
2150
2159
  },
2151
2160
  installedPending: 1,
2152
2161
  installedFailed: 1,
2162
+ installedPendingwithActive: 1,
2163
+ activeStores1: '$activeStores',
2153
2164
  ProgressBar: {
2154
2165
  $cond: {
2155
2166
  if: { $eq: [ '$onboardedStores', 0 ] },
@@ -2217,7 +2228,6 @@ export async function clientListV1( req, res ) {
2217
2228
  );
2218
2229
  }
2219
2230
  const clientList = await aggregateClient( clientQuery );
2220
-
2221
2231
  if ( inputData.isExport ) {
2222
2232
  const exportResult = [];
2223
2233
  for ( let client of clientList ) {
@@ -2946,12 +2956,76 @@ export async function getrevopconfig( req, res ) {
2946
2956
  export async function updateFDConfig( req, res ) {
2947
2957
  try {
2948
2958
  const inputData = req.body;
2959
+ const { taggingLimitation, ...otherData } = inputData;
2949
2960
  const inputQuery = req.query;
2950
2961
  const query ={
2951
2962
  clientId: inputQuery.clientId,
2952
2963
  };
2964
+ if ( taggingLimitation ) {
2965
+ const newValues = taggingLimitation;
2966
+ const today = new Date().toISOString().split( 'T' )[0];
2967
+ const getUpdateData = await clientModel.updateOne(
2968
+ {
2969
+ 'clientId': inputQuery.clientId,
2970
+ 'footfallDirectoryConfigs.taggingLimitation.effectiveFrom': today,
2971
+ },
2972
+ {
2973
+ $set: {
2974
+ 'footfallDirectoryConfigs.taggingLimitation.$.values': newValues,
2975
+ },
2976
+ },
2977
+ );
2978
+
2979
+ if ( getUpdateData?.matchedCount === 0 ) {
2980
+ await clientModel.updateOne(
2981
+ { clientId: inputQuery.clientId },
2982
+ {
2983
+ $push: {
2984
+ 'footfallDirectoryConfigs.taggingLimitation': {
2985
+ effectiveFrom: today,
2986
+ values: newValues,
2987
+ },
2988
+ },
2989
+ },
2990
+ );
2991
+ }
2992
+ }
2993
+
2953
2994
  // update the footfall directory configuration data
2954
- let result = await updateOneClient( query, { footfallDirectoryConfigs: inputData } );
2995
+ let record = {};
2996
+ if ( otherData?.contactEmail ) {
2997
+ record['footfallDirectoryConfigs.contactEmail'] =otherData?.contactEmail;
2998
+ }
2999
+
3000
+ if ( otherData?.revision ) {
3001
+ record['footfallDirectoryConfigs.revision'] =otherData?.revision;
3002
+ }
3003
+
3004
+ if ( otherData?.allowImageView ) {
3005
+ record['footfallDirectoryConfigs.allowImageView'] =otherData?.allowImageView;
3006
+ }
3007
+
3008
+ if ( otherData?.allowTicketCreation ) {
3009
+ record['footfallDirectoryConfigs.allowTicketCreation'] =otherData?.allowTicketCreation;
3010
+ }
3011
+
3012
+ if ( otherData?.isAutoCloseEnable ) {
3013
+ record['footfallDirectoryConfigs.isAutoCloseEnable'] =otherData?.isAutoCloseEnable;
3014
+ }
3015
+
3016
+ if ( otherData?.autoCloseAccuracy ) {
3017
+ record['footfallDirectoryConfigs.autoCloseAccuracy'] =otherData?.autoCloseAccuracy;
3018
+ }
3019
+
3020
+ if ( otherData?.accuracyBreach ) {
3021
+ record['footfallDirectoryConfigs.accuracyBreach'] =otherData?.accuracyBreach;
3022
+ }
3023
+
3024
+ if ( otherData?.tangoReview ) {
3025
+ record['footfallDirectoryConfigs.tangoReview'] =otherData?.tangoReview;
3026
+ }
3027
+
3028
+ let result = await updateOneClient( query, record );
2955
3029
  if ( result?.acknowledged === true ) {
2956
3030
  return res.sendSuccess( result );
2957
3031
  } else {
@@ -2967,10 +3041,89 @@ export async function updateFDConfig( req, res ) {
2967
3041
  export async function getFDConfig( req, res ) {
2968
3042
  try {
2969
3043
  const inputData = req.query;
2970
- let result = await findOneClient( { clientId: inputData.clientId }, { footfallDirectoryConfigs: 1 } );
2971
- if ( result===null ) {
3044
+ // let result = await findOneClient( { clientId: inputData.clientId }, { footfallDirectoryConfigs: 1 } );
3045
+ const configQuery = [
3046
+ {
3047
+ $match: {
3048
+ clientId: inputData?.clientId,
3049
+ },
3050
+ },
3051
+
3052
+ // Convert all effectiveFrom to proper Date
3053
+ {
3054
+ $addFields: {
3055
+ taggingLimitationWithDate: {
3056
+ $map: {
3057
+ input: '$footfallDirectoryConfigs.taggingLimitation',
3058
+ as: 'item',
3059
+ in: {
3060
+ effectiveFrom: { $toDate: '$$item.effectiveFrom' },
3061
+ values: '$$item.values',
3062
+ },
3063
+ },
3064
+ },
3065
+ },
3066
+ },
3067
+
3068
+ // Filter items <= input date
3069
+ {
3070
+ $addFields: {
3071
+ matchedLimitation: {
3072
+ $filter: {
3073
+ input: '$taggingLimitationWithDate',
3074
+ as: 'item',
3075
+ cond: {
3076
+ $lte: [
3077
+ '$$item.effectiveFrom',
3078
+ { $toDate: inputData.dateString },
3079
+ ],
3080
+ },
3081
+ },
3082
+ },
3083
+ },
3084
+ },
3085
+
3086
+ // Sort DESC and pick ONLY top 1 -> latest effective record
3087
+ {
3088
+ $addFields: {
3089
+ effectiveLimitation: {
3090
+ $arrayElemAt: [
3091
+ {
3092
+ $slice: [
3093
+ {
3094
+ $sortArray: {
3095
+ input: '$matchedLimitation',
3096
+ sortBy: { effectiveFrom: -1 },
3097
+ },
3098
+ },
3099
+ 1,
3100
+ ],
3101
+ },
3102
+ 0,
3103
+ ],
3104
+ },
3105
+ },
3106
+ },
3107
+
3108
+ {
3109
+ $project: {
3110
+ 'config': 1,
3111
+ 'effectiveLimitation': 1,
3112
+ 'footfallDirectoryConfigs': 1,
3113
+
3114
+ },
3115
+ },
3116
+ ];
3117
+
3118
+
3119
+ const getData = await aggregateClient( configQuery );
3120
+ let result = getData[0];
3121
+ if ( !result || result===null ) {
2972
3122
  return res.sendError( 'no data found', 204 );
2973
3123
  }
3124
+ result.footfallDirectoryConfigs.taggingLimitation = result?.effectiveLimitation?.values;
3125
+ delete result.effectiveLimitation;
3126
+
2974
3127
  return res.sendSuccess( result );
2975
3128
  } catch ( error ) {
2976
3129
  const err = error.message || 'Internal Server Error';
@@ -2983,38 +3136,38 @@ export async function getFDConfig( req, res ) {
2983
3136
  export async function updateTaggingType( req, res ) {
2984
3137
  try {
2985
3138
  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 },
3139
+ const newValues = inputData.taggingLimitation;
3140
+ const today = new Date().toISOString().split( 'T' )[0];
3141
+ logger.info( { today, newValues } );
3142
+ const result = await clientModel.updateOne(
2992
3143
  {
2993
- $pull: {
2994
- 'footfallDirectoryConfigs.taggingLimitation': {
2995
- type: { $in: types },
2996
- },
2997
- },
3144
+ 'clientId': inputData?.clientId,
3145
+ 'footfallDirectoryConfigs.taggingLimitation.effectiveFrom': today,
2998
3146
  },
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
3147
  {
3008
- $addToSet: {
3009
- 'footfallDirectoryConfigs.taggingLimitation': {
3010
- $each: uniqueData,
3011
- },
3148
+ $set: {
3149
+ 'footfallDirectoryConfigs.taggingLimitation.$.values': newValues,
3012
3150
  },
3013
3151
  },
3014
3152
  );
3153
+ logger.info( { result } );
3154
+ if ( result?.matchedCount === 0 ) {
3155
+ await clientModel.updateOne(
3156
+ { clientId: inputData.clientId },
3157
+ {
3158
+ $push: {
3159
+ 'footfallDirectoryConfigs.taggingLimitation': {
3160
+ effectiveFrom: today,
3161
+ values: newValues,
3162
+ },
3163
+ },
3164
+ },
3165
+ );
3166
+ }
3167
+
3015
3168
 
3016
3169
  if ( result?.acknowledged === true ) {
3017
- return res.sendSuccess( result );
3170
+ return res.sendSuccess( 'Tagging limitation has been updated' );
3018
3171
  } else {
3019
3172
  return res.sendError( 'no data', 204 );
3020
3173
  }
@@ -3025,14 +3178,14 @@ export async function updateTaggingType( req, res ) {
3025
3178
  }
3026
3179
  }
3027
3180
 
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
- }
3181
+ // function uniqueByType( arr ) {
3182
+ // const seen = new Set();
3183
+ // return arr.filter( ( item ) => {
3184
+ // if ( seen.has( item.type ) ) return false;
3185
+ // seen.add( item.type );
3186
+ // return true;
3187
+ // } );
3188
+ // }
3036
3189
 
3037
3190
  export async function createStoreRequest( req, res ) {
3038
3191
  try {
@@ -3050,11 +3203,11 @@ export async function createStoreRequest( req, res ) {
3050
3203
  const upsertRecord = await updateOneUpsertVmsStoreRequest( { storeId: inputData?.storeId, dateString: inputData?.dateString }, record );
3051
3204
  logger.info( { upsertRecord } );
3052
3205
  if ( upsertRecord?.upsertedCount === 1 ) {
3053
- return res.sendSuccess( 'The Request has been sent Successfully' );
3206
+ return res.sendTemp( 'The Request has been sent Successfully' );
3054
3207
  } else if ( upsertRecord?.matchedCount === 1 && upsertRecord?.modifiedCount === 1 ) {
3055
- return res.sendSuccess( 'The Request has been updated Successfully' );
3208
+ return res.sendTemp( 'The Request has been updated Successfully' );
3056
3209
  } else if ( upsertRecord?.matchedCount === 1 && upsertRecord?.modifiedCount === 0 ) {
3057
- return res.sendSuccess( 'The Request already exists and nothing to update' );
3210
+ return res.sendTemp( 'The Request already exists and nothing to update' );
3058
3211
  } else {
3059
3212
  return res.sendError( 'Internal Server Error', 500 );
3060
3213
  }
@@ -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
+
@@ -110,6 +110,7 @@ export const featureConfigurationSchemaBody = joi.object(
110
110
  isNormalized: joi.boolean().optional(),
111
111
  isPasserByData: joi.boolean().optional(),
112
112
  isFootfallDirectory: joi.boolean().optional(),
113
+ isFootfallDirectoryonlyTango: joi.boolean().optional(),
113
114
  isExcludedArea: joi.boolean().optional(),
114
115
  isCameraDisabled: joi.boolean().optional(),
115
116
  isbillingDisabled: joi.boolean().optional(),
@@ -119,6 +120,7 @@ export const featureConfigurationSchemaBody = joi.object(
119
120
  isNewZone: joi.boolean().optional(),
120
121
  isNewReports: joi.boolean().optional(),
121
122
  isNOB: joi.boolean().optional(),
123
+ isZonewiseNOB: joi.boolean().optional(),
122
124
  isNewZoneV2: joi.boolean().optional(),
123
125
  isTrax: joi.boolean().optional(),
124
126
  isRevops: joi.boolean().optional(),
@@ -370,6 +372,7 @@ export const updateFDConfigBodySchema = joi.object( {
370
372
  unit: joi.string().required(),
371
373
  key: joi.string().required(),
372
374
  } ) ).optional(),
375
+ contactEmail: joi.string().optional().allow( '' ),
373
376
 
374
377
  } );
375
378
 
@@ -377,8 +380,12 @@ export const updateFDConfigQuerySchema = joi.object( {
377
380
  clientId: joi.string().required(),
378
381
  } );
379
382
 
383
+
384
+ const todayDate = () => new Date().toISOString().split( 'T' )[0];
385
+
380
386
  export const getFDConfigSchema = joi.object( {
381
387
  clientId: joi.string().required(),
388
+ dateString: joi.string().optional().default( () => todayDate() ),
382
389
  } );
383
390
 
384
391
  export const updateFDConfigValid = {
@@ -395,6 +402,9 @@ export const updateTaggingTypeSchema = joi.object( {
395
402
  type: joi.string().required(),
396
403
  value: joi.number().required(),
397
404
  unit: joi.string().required(),
405
+ name: joi.string().required(),
406
+ iconName: joi.string().required(),
407
+ key: joi.string().required(),
398
408
  } ) ).required(),
399
409
 
400
410
  } );
@@ -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 );
@@ -148,6 +148,7 @@ export function featureConfigurationUpdate( query, inputData ) {
148
148
  'featureConfigs.isNormalized': inputData?.isNormalized,
149
149
  'featureConfigs.isPasserByData': inputData?.isPasserByData,
150
150
  'featureConfigs.isFootfallDirectory': inputData?.isFootfallDirectory,
151
+ 'featureConfigs.isFootfallDirectoryonlyTango': inputData?.isFootfallDirectoryonlyTango,
151
152
  'featureConfigs.isExcludedArea': inputData?.isExcludedArea,
152
153
  'featureConfigs.updateFeatureConfig': false,
153
154
  'featureConfigs.isCameraDisabled': inputData?.isCameraDisabled,
@@ -158,6 +159,7 @@ export function featureConfigurationUpdate( query, inputData ) {
158
159
  'featureConfigs.isNewZone': inputData?.isNewZone,
159
160
  'featureConfigs.isNewReports': inputData?.isNewReports,
160
161
  'featureConfigs.isNOB': inputData?.isNOB,
162
+ 'featureConfigs.isZonewiseNOB': inputData?.isZonewiseNOB,
161
163
  'featureConfigs.isNewZoneV2': inputData?.isNewZoneV2,
162
164
  'featureConfigs.isTrax': inputData?.isTrax,
163
165
  '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
+ }