tango-app-api-client 3.6.5-vms.5 → 3.6.5-vms.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/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "tango-app-api-client",
3
- "version": "3.6.5-vms.5",
3
+ "version": "3.6.5-vms.6",
4
4
  "description": "client",
5
5
  "main": "index.js",
6
6
  "type": "module",
7
7
  "scripts": {
8
- "start": "nodemon --exec \"eslint --fix . && node app.js\"",
8
+ "start": "nodemon --exec \"eslint --fix . && node index.js\"",
9
9
  "build:patch": "node build.js patch && npm publish",
10
10
  "build:minor": "node build.js minor && npm publish",
11
11
  "build:major": "node build.js major && npm publish"
@@ -31,7 +31,7 @@
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.20",
34
+ "tango-api-schema": "^2.4.27",
35
35
  "tango-app-api-middleware": "^3.6.0",
36
36
  "winston": "^3.11.0",
37
37
  "winston-daily-rotate-file": "^5.0.0"
@@ -2950,9 +2950,6 @@ export async function updateFDConfig( req, res ) {
2950
2950
  const query ={
2951
2951
  clientId: inputQuery.clientId,
2952
2952
  };
2953
- if(inputData.rvision){
2954
-
2955
- }
2956
2953
  // update the footfall directory configuration data
2957
2954
  let result = await updateOneClient( query, { footfallDirectoryConfigs: inputData } );
2958
2955
  if ( result?.acknowledged === true ) {
@@ -0,0 +1,329 @@
1
+ import { logger, searchOpenSearchData } from 'tango-app-api-middleware';
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';
5
+ import { insertOpenSearchData, clearScroll, scrollResponse } from 'tango-app-api-middleware';
6
+ import { findOneUser } from '../service/user.service.js';
7
+ import dayjs from 'dayjs';
8
+ import utc from 'dayjs/plugin/utc.js';
9
+ import timezone from 'dayjs/plugin/timezone.js';
10
+
11
+ dayjs.extend( utc );
12
+ dayjs.extend( timezone );
13
+ export async function getAuditFile( req, res ) {
14
+ try {
15
+ // const bucket = JSON.parse( process.env.BUCKET );
16
+ const url = JSON.parse( process.env.URL );
17
+ const openSearch = JSON.parse( process.env.OPENSEARCH );
18
+ const inputData = req.query;
19
+ const files = [];
20
+ const storeQuery = {
21
+ storeId: inputData.storeId,
22
+ };
23
+ const storeFields = {
24
+ storeName: 1,
25
+ clientId: 1,
26
+ address: '$storeProfile.address',
27
+ };
28
+ const storeInfo = await findOneStore( storeQuery, storeFields );
29
+
30
+ const userQuery = [
31
+ {
32
+ $match: {
33
+ $and: [
34
+ { userId: req.user._id },
35
+ { auditStatus: { $nin: [ 'completed', 'skipped' ] } },
36
+ { storeId: inputData.storeId },
37
+ { fileDate: inputData.Date },
38
+ ],
39
+ },
40
+ },
41
+ {
42
+ $sort: { createdAt: -1 },
43
+ },
44
+ {
45
+ $limit: 1,
46
+ },
47
+ ];
48
+
49
+ const userDetails = await aggregatevmsUserAudit( userQuery );
50
+ const auditStatus = userDetails && userDetails.length > 0 ? userDetails[0].auditStatus : null;
51
+ if ( auditStatus === 'drafted' ) {
52
+ const log = await findOnevmsAuditLog(
53
+ {
54
+ userId: userDetails[0].userId,
55
+ fileDate: userDetails[0].fileDate,
56
+ storeId: userDetails[0].storeId,
57
+ totalCount: userDetails[0].beforeCount,
58
+ },
59
+ {},
60
+ { createdAt: -1 },
61
+ );
62
+ if ( !log ) {
63
+ await updateOnevmsUserAudit(
64
+ { _id: userDetails[0]._id },
65
+ { $set: { isDraft: false, auditStatus: 'skipped' } },
66
+ );
67
+ logger.info( 'audit update in drafted', {
68
+ _id: userDetails[0]._id,
69
+ isDraft: false,
70
+ auditStatus: 'skipped',
71
+ } );
72
+ return res.sendError( 'User saved data has been deleted', 204 );
73
+ }
74
+
75
+ const file = {
76
+ auditId: userDetails[0]._id,
77
+ storeId: userDetails[0].storeId,
78
+ Date: userDetails[0].fileDate,
79
+ userId: log.userId,
80
+ timeSpent: log.timeSpent,
81
+ clientId: userDetails[0].clientId,
82
+ };
83
+ const userdata = await findOneUser( { _id: log.userId } );
84
+ if (
85
+ !inputData.nextId ||
86
+ inputData.nextId === '' ||
87
+ inputData.nextId == null
88
+ ) {
89
+ const logData = {
90
+ userId: log.userId,
91
+ userName: userdata.userName,
92
+ logType: 'vmsaudit',
93
+ logSubType: 'auditStart',
94
+ logData: {
95
+ fileDate: userDetails[0].fileDate,
96
+ storeId: userDetails[0].storeId,
97
+ auditId: userDetails[0]._id,
98
+ beforeCount: userDetails[0].beforeCount,
99
+ },
100
+ createdAt: new Date(),
101
+ };
102
+ await insertOpenSearchData( openSearch.vmsauditLog, logData );
103
+ }
104
+ const storeQuery = {
105
+ storeId: userDetails[0].storeId,
106
+ };
107
+ const storeFields = {
108
+ storeId: 1,
109
+ storeName: 1,
110
+ address: '$storeProfile.address',
111
+ };
112
+ const storeDetails = await findOneStore( storeQuery, storeFields );
113
+ return res.sendSuccess( {
114
+ result: log.draftedData,
115
+ storeId: storeDetails?.storeId,
116
+ storeName: storeDetails?.storeName,
117
+ address: storeDetails?.address || '',
118
+ count: log.totalCount,
119
+ timeSpent: log.timeSpent,
120
+ file: file,
121
+ isDraft: userDetails[0].isDraft,
122
+ } );
123
+ }
124
+ console.log( inputData );
125
+
126
+ const query = {
127
+ size: inputData?.limit || 2,
128
+ _source: [ 'module', 'status', 'date', 'store_id', 'outputCluster', 'personPath', 'REIDCluster', 'isEmployee', 'isJunk', 'EmployeeStatusFinal' ], // Only fetch necessary fields
129
+
130
+ query: {
131
+ bool: {
132
+ 'must': [
133
+ {
134
+ term: { 'store_id.keyword': inputData.storeId },
135
+ },
136
+ {
137
+ term: { 'date.keyword': dayjs( inputData.Date ).format( 'DD-MM-YYYY' ) },
138
+ },
139
+ {
140
+ term: { 'module.keyword': 'CUSTOMER' },
141
+ },
142
+ {
143
+ term: { 'status.keyword': 'PP_CLUSTER_FORMED' },
144
+ },
145
+ {
146
+ terms: { EmployeeStatusFinal: [ 1, 2 ] },
147
+ },
148
+ ],
149
+ 'should': [
150
+ { 'term': { 'isJunk': false } },
151
+ { 'bool': { 'must_not': { 'exists': { 'field': 'isJunk' } } } },
152
+ ],
153
+ 'minimum_should_match': 1,
154
+ },
155
+ },
156
+
157
+ };
158
+ console.log( openSearch.vmsAudit );
159
+ let list =inputData.nextId? await scrollResponse( inputData.nextId ): await searchOpenSearchData( openSearch.vmsAudit, query );
160
+ const folderPath = list?.body?.hits?.hits;
161
+ if ( list?.body?.hits?.hits?.length ==0 ) {
162
+ await clearScroll( list?.body?._scroll_id );
163
+ }
164
+ if ( folderPath?.length > 0 ) {
165
+ for ( let i = 0; i < folderPath.length; i++ ) {
166
+ const img = folderPath[i]?._source?.personPath?.split( '/' );
167
+ const image = img[3]?.split( '.' );
168
+ const indexes = folderPath[i]?._source?.outputCluster === 50000 ? folderPath[i]?._source?.REIDCluster : folderPath[i]?._source?.outputCluster;
169
+ // fetchData.file_path = folderPath[i]?._source?.personPath;
170
+ const data = `${url.trackInput}${folderPath[i]?._source?.personPath}`;
171
+ const mapimg = {
172
+ img_path: data,
173
+ img_name: indexes,
174
+ img_id: image[0],
175
+ };
176
+ addUniqueFile( files, {
177
+ img_path: data,
178
+ img_name: indexes,
179
+ img_id: image[0],
180
+ selected: false,
181
+ dropped: false,
182
+ demographic: '',
183
+ count: 1,
184
+ mappedid: [ mapimg ],
185
+ } );
186
+ }
187
+ }
188
+ const [ year, month, day ] = inputData.Date.split( '-' );
189
+ const temp = `${year}-${month}-${day}`;
190
+ console.log( temp );
191
+ let start = new Date( temp );
192
+ const userTimezoneOffset = start.getTimezoneOffset() * 60000;
193
+ start = new Date( start.getTime() - userTimezoneOffset );
194
+ start.setUTCHours( 0, 0, 0, 0 );
195
+ console.log( start );
196
+ const record = {
197
+ userId: req.user._id,
198
+ storeId: inputData.storeId,
199
+ clientId: storeInfo?.clientId,
200
+ fileDate: inputData.Date,
201
+ beforeCount: files.length,
202
+ auditStatus: 'inprogress',
203
+ fileDateISO: start,
204
+ timeSpent: 0,
205
+ startTime: new Date(),
206
+ };
207
+ const insertData = await createvmsUserAudit( record );
208
+ if ( inputData.nextId !== '' && inputData.nextId !== null && inputData.nextId !== undefined && inputData.moduleType === 'track' ) {
209
+ if ( !list ) {
210
+ return res.sendError( 'token expired', 404 );
211
+ }
212
+ list.body._scroll_id = '';
213
+ }
214
+ return res.sendSuccess( {
215
+ result: files,
216
+ count: inputData.count,
217
+ storeId: inputData.storeId,
218
+ storeName: storeInfo?.storeName,
219
+ address: storeInfo?.address,
220
+ file: {
221
+ clientId: storeInfo?.clientId,
222
+ storeId: inputData.storeId,
223
+ Date: inputData.Date,
224
+ auditId: insertData._id,
225
+ userId: insertData.userId,
226
+ nextToken: list?.body?._scroll_id ?list?.body?._scroll_id:null,
227
+
228
+ },
229
+ isDraft: insertData.isDraft,
230
+ } );
231
+ } catch ( error ) {
232
+ const err = error.message || 'Internal Server Error';
233
+ logger.error( {
234
+ error: error,
235
+ message: req.query,
236
+ function: 'getAuditFile',
237
+ } );
238
+ return res.sendError( err, 500 );
239
+ }
240
+ }
241
+ function addUniqueFile( files, newFile ) {
242
+ const exists = files.some( ( file ) => file.img_name === newFile.img_name );
243
+ if ( !exists ) {
244
+ files.push( newFile );
245
+ }
246
+ }
247
+ export async function saveDraft( req, res ) {
248
+ try {
249
+ const openSearch = JSON.parse( process.env.OPENSEARCH );
250
+ const inputData = req.body;
251
+ inputData.userId = req.user._id;
252
+ const getUserAuditData = await findOnevmsUserAudit( { _id: inputData.auditId } );
253
+ if ( !getUserAuditData ) {
254
+ return res.sendError( 'No Data Found', 204 );
255
+ }
256
+ if ( getUserAuditData.auditStatus == 'skipped' ) {
257
+ return res.sendError( 'File Assigned to Someone else', 203 );
258
+ }
259
+
260
+ const userQuery = {
261
+ _id: inputData.auditId,
262
+ };
263
+ let userRecord = {
264
+ isDraft: true,
265
+ auditStatus: 'drafted',
266
+ };
267
+
268
+
269
+ if ( getUserAuditData?.startTime ) {
270
+ userRecord.timeSpent = inputData.timeSpent;
271
+ }
272
+
273
+ if ( inputData.userCommands ) {
274
+ userRecord.userCommands = inputData.userCommands;
275
+ const logData = {
276
+ userId: req.user._id,
277
+ userName: req.user.userName,
278
+ logType: 'vmsaudit',
279
+ logSubType: 'auditDraft',
280
+ logData: {
281
+ fileDate: inputData.fileDate,
282
+ storeId: inputData.storeId,
283
+ beforeCount: inputData.totalCount,
284
+ afterCount: inputData.customerCount,
285
+ timeSpent: inputData.timeSpent,
286
+ auditId: inputData.auditId,
287
+ },
288
+ createdAt: new Date(),
289
+ };
290
+ await insertOpenSearchData( openSearch.vmsauditLog, logData );
291
+ }
292
+ await createvmsAuditLog( inputData );
293
+ await updateOnevmsUserAudit( userQuery, userRecord );
294
+ return res.sendSuccess( {
295
+ result: 'The file has been drafted successfully',
296
+ } );
297
+ } catch ( error ) {
298
+ const err = error.message || 'Internal Server Error';
299
+ logger.error( { error: error, message: req.body, function: 'saveDraft' } );
300
+ return res.sendError( err, 500 );
301
+ }
302
+ }
303
+ export async function getDraftedData( req, res ) {
304
+ try {
305
+ const inputData = req.query;
306
+ const userId = inputData.userId || req.user._id;
307
+ const query = {
308
+ fileDate: inputData.fileDate,
309
+ storeId: inputData.storeId,
310
+ userId: userId,
311
+ auditId: inputData.auditId,
312
+ };
313
+ console.log( query );
314
+ const result = await findOnevmsAuditLog( query, {}, { createdAt: -1 }, 1 );
315
+
316
+ if ( !result ) {
317
+ return res.sendError( 'No Data Found', 204 );
318
+ }
319
+ return res.sendSuccess( { result: result } );
320
+ } catch ( error ) {
321
+ const err = error.message || 'Internal Server Error';
322
+ logger.error( {
323
+ error: error,
324
+ message: req.query,
325
+ function: 'getDraftedData',
326
+ } );
327
+ return res.sendError( err, 500 );
328
+ }
329
+ }
@@ -360,12 +360,10 @@ export const updateFDConfigBodySchema = joi.object( {
360
360
  tangoReview: joi.string().optional(),
361
361
  revision: joi.array().items( joi.object( {
362
362
  actionType: joi.string().required(),
363
- isChecked: joi.boolean().optional().default(false),
363
+ isChecked: joi.boolean().required(),
364
364
  } ) ).optional(),
365
365
  taggingLimitation: joi.array().items( joi.object( {
366
- iconName:joi.string().optional(),
367
- name:joi.string().optional(),
368
- type: joi.string().required(),
366
+ type: joi.string().required(),
369
367
  value: joi.number().required(),
370
368
  unit: joi.string().required(),
371
369
  } ) ).optional(),
@@ -0,0 +1,24 @@
1
+
2
+ import joi from 'joi';
3
+ export const getDraftedDataSchema = joi.object( {
4
+ storeId: joi.string().required(),
5
+ fileDate: joi.string().required(),
6
+ userId: joi.string().optional(),
7
+ auditId: joi.string().required(),
8
+ } );
9
+ export const getFileSchema = joi.object( {
10
+ nextId: joi.string().optional().allow( '' ),
11
+ limit: joi.number().optional(),
12
+ storeId: joi.string().required(),
13
+ Date: joi.string().required(),
14
+ count: joi.string().required(),
15
+ } );
16
+
17
+
18
+ export const getDraftedDataValid = {
19
+ query: getDraftedDataSchema,
20
+ };
21
+
22
+ export const getFileValid = {
23
+ query: getFileSchema,
24
+ };
@@ -0,0 +1,10 @@
1
+ import express from 'express';
2
+ import { accessVerification, isAllowedSessionHandler, validate } from 'tango-app-api-middleware';
3
+ import { getDraftedDataValid, getFileValid } from '../dtos/vmsAudit.dtos.js';
4
+ import { getAuditFile, getDraftedData, saveDraft } from '../controllers/vmsAudit.controller.js';
5
+ export const vmsauditRouter = express.Router();
6
+
7
+
8
+ vmsauditRouter.get( '/get-file', isAllowedSessionHandler, accessVerification( { userType: [ 'tango' ] } ), validate( getFileValid ), getAuditFile );
9
+ vmsauditRouter.post( '/save-draft', isAllowedSessionHandler, accessVerification( { userType: [ 'tango' ] } ), saveDraft );
10
+ vmsauditRouter.get( '/get-drafted-data', isAllowedSessionHandler, accessVerification( { userType: [ 'tango' ] } ), validate( getDraftedDataValid ), getDraftedData );
@@ -0,0 +1,10 @@
1
+ import vmsauditLogsModel from 'tango-api-schema/schema/vmsauditLogs.model.js';
2
+
3
+
4
+ export function createvmsAuditLog( record ) {
5
+ return vmsauditLogsModel.create( record );
6
+ }
7
+
8
+ export function findOnevmsAuditLog( query, fields={}, sort={ createdAt: -1 }, limit=10 ) {
9
+ return vmsauditLogsModel.findOne( query, fields ).sort( sort ).limit( limit );
10
+ }
@@ -0,0 +1,22 @@
1
+ import vmsuserAuditModel from 'tango-api-schema/schema/vmsuserAudit.model.js';
2
+
3
+
4
+ export function aggregatevmsUserAudit( query ) {
5
+ return vmsuserAuditModel.aggregate( query, { collation: { locale: 'en', strength: 2 } } );
6
+ }
7
+
8
+ export function updateOnevmsUserAudit( query, record ) {
9
+ return vmsuserAuditModel.updateOne( query, { $set: record } );
10
+ }
11
+
12
+ export function createvmsUserAudit( record ) {
13
+ return vmsuserAuditModel.create( record );
14
+ }
15
+
16
+ export function findOnevmsUserAudit( query, fields ) {
17
+ return vmsuserAuditModel.findOne( query, fields );
18
+ }
19
+
20
+ export function aggregatevmsUserAuditCount( query ) {
21
+ return vmsuserAuditModel.aggregate( query );
22
+ }