tango-app-api-trax 3.9.33 → 3.9.34
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 +2 -1
- package/package.json +1 -1
- package/src/controllers/internalTrax.controller.js +112 -73
- package/src/controllers/mobileTrax.controller.js +69 -29
- package/src/controllers/trax.controller.js +7 -1
- package/src/controllers/traxDashboard.controllers.js +63 -54
- package/src/hbs/flag.hbs +1 -1
- package/src/hbs/login-otp.hbs +943 -943
- package/src/hbs/template.hbs +7 -0
- package/src/hbs/visit-checklist.hbs +51 -1
- package/src/logging/activityLogFlusher.js +59 -0
- package/src/logging/activityLogMiddleware.js +45 -0
- package/src/logging/activityLogStore.js +91 -0
- package/src/logging/compressBatches.js +83 -0
- package/src/logging/config.js +24 -0
- package/src/logging/createLoggableService.js +46 -0
- package/src/logging/logExternalCall.js +37 -0
- package/src/services/app.service.js +15 -9
- package/src/services/approver.service.js +23 -15
- package/src/services/authentication.service.js +9 -3
- package/src/services/camera.service.js +19 -13
- package/src/services/checklist.service.js +35 -27
- package/src/services/checklistAssign.service.js +43 -38
- package/src/services/checklistQuestion.service.js +39 -34
- package/src/services/checklistlog.service.js +39 -34
- package/src/services/clientRequest.service.js +9 -2
- package/src/services/clients.services.js +23 -18
- package/src/services/cluster.service.js +31 -23
- package/src/services/domain.service.js +23 -18
- package/src/services/download.services.js +35 -25
- package/src/services/group.service.js +23 -17
- package/src/services/lenskartEmployeeMapping.service.js +15 -10
- package/src/services/locus.service.js +35 -28
- package/src/services/notification.service.js +35 -26
- package/src/services/otp.service.js +20 -13
- package/src/services/planogram.service.js +9 -2
- package/src/services/processedTaskConfig.service.js +35 -27
- package/src/services/processedTaskList.service.js +32 -26
- package/src/services/processedchecklist.services.js +55 -47
- package/src/services/processedchecklistconfig.services.js +39 -34
- package/src/services/recurringFlagTracker.service.js +39 -32
- package/src/services/runAIFeatures.services.js +32 -27
- package/src/services/runAIRequest.services.js +43 -38
- package/src/services/store.service.js +32 -27
- package/src/services/tagging.service.js +9 -2
- package/src/services/taskConfig.service.js +35 -27
- package/src/services/teams.service.js +35 -24
- package/src/services/ticket.service.js +15 -10
- package/src/services/user.service.js +27 -20
- package/src/services/userAssignedstores.service.js +12 -5
- package/src/utils/visitChecklistPdf.utils.js +114 -11
|
@@ -1,39 +1,44 @@
|
|
|
1
1
|
import model from 'tango-api-schema';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
2
|
+
import { createLoggableService } from '../logging/createLoggableService.js';
|
|
3
|
+
|
|
4
|
+
const _methods = {
|
|
5
|
+
async findOne( query={}, field={} ) {
|
|
6
|
+
return model.runAIRequestModel.findOne( query, field );
|
|
7
|
+
},
|
|
8
|
+
async find( query={}, field={} ) {
|
|
9
|
+
return model.runAIRequestModel.find( query, field );
|
|
10
|
+
},
|
|
11
|
+
async create( document = {} ) {
|
|
12
|
+
return model.runAIRequestModel.create( document );
|
|
13
|
+
},
|
|
14
|
+
async insertMany( document = {} ) {
|
|
15
|
+
return model.runAIRequestModel.insertMany( document );
|
|
16
|
+
},
|
|
17
|
+
async deleteMany( query = {} ) {
|
|
18
|
+
return model.runAIRequestModel.deleteMany( query );
|
|
19
|
+
},
|
|
20
|
+
async deleteOne( query = {} ) {
|
|
21
|
+
return model.runAIRequestModel.deleteOne( query );
|
|
22
|
+
},
|
|
23
|
+
async updateOne( query = {}, record={} ) {
|
|
24
|
+
return model.runAIRequestModel.updateOne( query, { $set: record } );
|
|
25
|
+
},
|
|
26
|
+
async aggregate( query = {} ) {
|
|
27
|
+
return model.runAIRequestModel.aggregate( query );
|
|
28
|
+
},
|
|
29
|
+
async count( query = {} ) {
|
|
30
|
+
return model.runAIRequestModel.countDocuments( query );
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const _svc = createLoggableService( _methods, 'runairequests' );
|
|
35
|
+
|
|
36
|
+
export const findOne = ( ...args ) => _svc.findOne( ...args );
|
|
37
|
+
export const find = ( ...args ) => _svc.find( ...args );
|
|
38
|
+
export const create = ( ...args ) => _svc.create( ...args );
|
|
39
|
+
export const insertMany = ( ...args ) => _svc.insertMany( ...args );
|
|
40
|
+
export const deleteMany = ( ...args ) => _svc.deleteMany( ...args );
|
|
41
|
+
export const deleteOne = ( ...args ) => _svc.deleteOne( ...args );
|
|
42
|
+
export const updateOne = ( ...args ) => _svc.updateOne( ...args );
|
|
43
|
+
export const aggregate = ( ...args ) => _svc.aggregate( ...args );
|
|
44
|
+
export const count = ( ...args ) => _svc.count( ...args );
|
|
@@ -1,31 +1,36 @@
|
|
|
1
1
|
import model from 'tango-api-schema';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export const count = async ( query = {} ) => {
|
|
28
|
-
return model.storeModel.countDocuments( query );
|
|
2
|
+
import { createLoggableService } from '../logging/createLoggableService.js';
|
|
3
|
+
|
|
4
|
+
const _methods = {
|
|
5
|
+
async findOne( query={}, field={} ) {
|
|
6
|
+
return model.storeModel.findOne( query, field );
|
|
7
|
+
},
|
|
8
|
+
async find( query={}, field={} ) {
|
|
9
|
+
return model.storeModel.find( query, field );
|
|
10
|
+
},
|
|
11
|
+
async create( document = {} ) {
|
|
12
|
+
return model.storeModel.create( document );
|
|
13
|
+
},
|
|
14
|
+
async deleteOne( query = {} ) {
|
|
15
|
+
return model.storeModel.deleteOne( query );
|
|
16
|
+
},
|
|
17
|
+
async updateOne( query = {}, record={} ) {
|
|
18
|
+
return model.storeModel.updateOne( query, { $set: record } );
|
|
19
|
+
},
|
|
20
|
+
async aggregate( query = {} ) {
|
|
21
|
+
return model.storeModel.aggregate( query );
|
|
22
|
+
},
|
|
23
|
+
async count( query = {} ) {
|
|
24
|
+
return model.storeModel.countDocuments( query );
|
|
25
|
+
},
|
|
29
26
|
};
|
|
30
27
|
|
|
28
|
+
const _svc = createLoggableService( _methods, 'stores' );
|
|
31
29
|
|
|
30
|
+
export const findOne = ( ...args ) => _svc.findOne( ...args );
|
|
31
|
+
export const find = ( ...args ) => _svc.find( ...args );
|
|
32
|
+
export const create = ( ...args ) => _svc.create( ...args );
|
|
33
|
+
export const deleteOne = ( ...args ) => _svc.deleteOne( ...args );
|
|
34
|
+
export const updateOne = ( ...args ) => _svc.updateOne( ...args );
|
|
35
|
+
export const aggregate = ( ...args ) => _svc.aggregate( ...args );
|
|
36
|
+
export const count = ( ...args ) => _svc.count( ...args );
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import model from 'tango-api-schema';
|
|
2
|
+
import { createLoggableService } from '../logging/createLoggableService.js';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
const _methods = {
|
|
5
|
+
async aggregate( query={} ) {
|
|
6
|
+
return model.taggingModel.aggregate( query );
|
|
7
|
+
},
|
|
5
8
|
};
|
|
9
|
+
|
|
10
|
+
const _svc = createLoggableService( _methods, 'taggings' );
|
|
11
|
+
|
|
12
|
+
export const aggregate = ( ...args ) => _svc.aggregate( ...args );
|
|
@@ -1,32 +1,40 @@
|
|
|
1
1
|
import model from 'tango-api-schema';
|
|
2
|
+
import { createLoggableService } from '../logging/createLoggableService.js';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
const _methods = {
|
|
5
|
+
async find( query = {}, field={} ) {
|
|
6
|
+
return model.taskConfigModel.find( query, field );
|
|
7
|
+
},
|
|
8
|
+
async findOne( query = {}, field={} ) {
|
|
9
|
+
return model.taskConfigModel.findOne( query, field );
|
|
10
|
+
},
|
|
11
|
+
async updateMany( query = {}, record={} ) {
|
|
12
|
+
return model.taskConfigModel.updateMany( query, { $set: record } );
|
|
13
|
+
},
|
|
14
|
+
async updateOne( query = {}, record={} ) {
|
|
15
|
+
return model.taskConfigModel.updateOne( query, { $set: record } );
|
|
16
|
+
},
|
|
17
|
+
async insertMany( data = [] ) {
|
|
18
|
+
return model.taskConfigModel.insertMany( data );
|
|
19
|
+
},
|
|
20
|
+
async deleteMany( query = [] ) {
|
|
21
|
+
return model.taskConfigModel.deleteMany( query );
|
|
22
|
+
},
|
|
23
|
+
async aggregate( query = [] ) {
|
|
24
|
+
return model.taskConfigModel.aggregate( query );
|
|
25
|
+
},
|
|
26
|
+
async insert( data = [] ) {
|
|
27
|
+
return model.taskConfigModel.create( data );
|
|
28
|
+
},
|
|
5
29
|
};
|
|
6
30
|
|
|
7
|
-
|
|
8
|
-
return model.taskConfigModel.findOne( query, field );
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export const updateMany = async ( query = {}, record={} ) => {
|
|
12
|
-
return model.taskConfigModel.updateMany( query, { $set: record } );
|
|
13
|
-
};
|
|
14
|
-
export const updateOne = async ( query = {}, record={} ) => {
|
|
15
|
-
return model.taskConfigModel.updateOne( query, { $set: record } );
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export const insertMany = async ( data = [] ) => {
|
|
19
|
-
return model.taskConfigModel.insertMany( data );
|
|
20
|
-
};
|
|
31
|
+
const _svc = createLoggableService( _methods, 'taskconfigs' );
|
|
21
32
|
|
|
22
|
-
export const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
export const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
export const insert = async ( data = [] ) => {
|
|
31
|
-
return model.taskConfigModel.create( data );
|
|
32
|
-
};
|
|
33
|
+
export const find = ( ...args ) => _svc.find( ...args );
|
|
34
|
+
export const findOne = ( ...args ) => _svc.findOne( ...args );
|
|
35
|
+
export const updateMany = ( ...args ) => _svc.updateMany( ...args );
|
|
36
|
+
export const updateOne = ( ...args ) => _svc.updateOne( ...args );
|
|
37
|
+
export const insertMany = ( ...args ) => _svc.insertMany( ...args );
|
|
38
|
+
export const deleteMany = ( ...args ) => _svc.deleteMany( ...args );
|
|
39
|
+
export const aggregate = ( ...args ) => _svc.aggregate( ...args );
|
|
40
|
+
export const insert = ( ...args ) => _svc.insert( ...args );
|
|
@@ -1,30 +1,41 @@
|
|
|
1
1
|
import teamsModel from 'tango-api-schema/schema/teams.model.js';
|
|
2
|
+
import { createLoggableService } from '../logging/createLoggableService.js';
|
|
2
3
|
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
5
|
+
const _methods = {
|
|
6
|
+
async createTeamsModel( data ) {
|
|
7
|
+
return await teamsModel.create( data );
|
|
8
|
+
},
|
|
9
|
+
async updateOneTeams( query, record ) {
|
|
10
|
+
return await teamsModel.updateOne( query, { $set: record }, { upsert: true } );
|
|
11
|
+
},
|
|
12
|
+
async aggregateTeams( query ) {
|
|
13
|
+
return await teamsModel.aggregate( query );
|
|
14
|
+
},
|
|
15
|
+
async deleteTeams( query ={} ) {
|
|
16
|
+
return await teamsModel.deleteOne( query );
|
|
17
|
+
},
|
|
18
|
+
async findOneTeams( query ={}, field={} ) {
|
|
19
|
+
return await teamsModel.findOne( query, field );
|
|
20
|
+
},
|
|
21
|
+
async findteams( query ={}, field={} ) {
|
|
22
|
+
return await teamsModel.find( query, field );
|
|
23
|
+
},
|
|
24
|
+
async updateOneTeamModel( query, record ) {
|
|
25
|
+
return await teamsModel.updateOne( query, record );
|
|
26
|
+
},
|
|
27
|
+
countDocumentsTeams( query ) {
|
|
28
|
+
return teamsModel.countDocuments( query );
|
|
29
|
+
},
|
|
16
30
|
};
|
|
17
31
|
|
|
18
|
-
|
|
19
|
-
return await teamsModel.findOne( query, field );
|
|
20
|
-
};
|
|
21
|
-
export async function findteams( query ={}, field={} ) {
|
|
22
|
-
return await teamsModel.find( query, field );
|
|
23
|
-
};
|
|
32
|
+
const _svc = createLoggableService( _methods, 'teams' );
|
|
24
33
|
|
|
25
|
-
export
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
export
|
|
29
|
-
|
|
30
|
-
|
|
34
|
+
export const createTeamsModel = ( ...args ) => _svc.createTeamsModel( ...args );
|
|
35
|
+
export const updateOneTeams = ( ...args ) => _svc.updateOneTeams( ...args );
|
|
36
|
+
export const aggregateTeams = ( ...args ) => _svc.aggregateTeams( ...args );
|
|
37
|
+
export const deleteTeams = ( ...args ) => _svc.deleteTeams( ...args );
|
|
38
|
+
export const findOneTeams = ( ...args ) => _svc.findOneTeams( ...args );
|
|
39
|
+
export const findteams = ( ...args ) => _svc.findteams( ...args );
|
|
40
|
+
export const updateOneTeamModel = ( ...args ) => _svc.updateOneTeamModel( ...args );
|
|
41
|
+
export const countDocumentsTeams = ( ...args ) => _svc.countDocumentsTeams( ...args );
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
import model from 'tango-api-schema';
|
|
2
|
+
import { createLoggableService } from '../logging/createLoggableService.js';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
4
|
+
const _methods = {
|
|
5
|
+
async findOne( query={}, field={} ) {
|
|
6
|
+
return model.aiTicketConfigModel.findOne( query, field );
|
|
7
|
+
},
|
|
8
|
+
async create( document = {} ) {
|
|
9
|
+
return model.aiTicketConfigModel.create( document );
|
|
10
|
+
},
|
|
11
|
+
async deleteOne( query = {} ) {
|
|
12
|
+
return model.aiTicketConfigModel.deleteOne( query );
|
|
13
|
+
},
|
|
13
14
|
};
|
|
14
15
|
|
|
16
|
+
const _svc = createLoggableService( _methods, 'tickets' );
|
|
15
17
|
|
|
18
|
+
export const findOne = ( ...args ) => _svc.findOne( ...args );
|
|
19
|
+
export const create = ( ...args ) => _svc.create( ...args );
|
|
20
|
+
export const deleteOne = ( ...args ) => _svc.deleteOne( ...args );
|
|
@@ -1,25 +1,32 @@
|
|
|
1
1
|
import model from 'tango-api-schema';
|
|
2
|
+
import { createLoggableService } from '../logging/createLoggableService.js';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
const _methods = {
|
|
5
|
+
async findOne( query={}, field={} ) {
|
|
6
|
+
return model.userModel.findOne( query, field ).sort( { userName: 1 } );
|
|
7
|
+
},
|
|
8
|
+
async find( query={}, field={} ) {
|
|
9
|
+
return model.userModel.find( query, field ).sort( { userName: 1 } );
|
|
10
|
+
},
|
|
11
|
+
async create( document = {} ) {
|
|
12
|
+
return model.userModel.create( document );
|
|
13
|
+
},
|
|
14
|
+
async deleteOne( query = {} ) {
|
|
15
|
+
return model.userModel.deleteOne( query );
|
|
16
|
+
},
|
|
17
|
+
async updateOne( query = {}, record={} ) {
|
|
18
|
+
return model.userModel.updateOne( query, { $set: record } );
|
|
19
|
+
},
|
|
20
|
+
async aggregate( query = {} ) {
|
|
21
|
+
return model.userModel.aggregate( query );
|
|
22
|
+
},
|
|
5
23
|
};
|
|
6
24
|
|
|
7
|
-
|
|
8
|
-
return model.userModel.find( query, field ).sort( { userName: 1 } );
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export const create = async ( document = {} ) => {
|
|
12
|
-
return model.userModel.create( document );
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export const deleteOne = async ( query = {} ) => {
|
|
16
|
-
return model.userModel.deleteOne( query );
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export const updateOne = async ( query = {}, record={} ) => {
|
|
20
|
-
return model.userModel.updateOne( query, { $set: record } );
|
|
21
|
-
};
|
|
25
|
+
const _svc = createLoggableService( _methods, 'users' );
|
|
22
26
|
|
|
23
|
-
export const
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
export const findOne = ( ...args ) => _svc.findOne( ...args );
|
|
28
|
+
export const find = ( ...args ) => _svc.find( ...args );
|
|
29
|
+
export const create = ( ...args ) => _svc.create( ...args );
|
|
30
|
+
export const deleteOne = ( ...args ) => _svc.deleteOne( ...args );
|
|
31
|
+
export const updateOne = ( ...args ) => _svc.updateOne( ...args );
|
|
32
|
+
export const aggregate = ( ...args ) => _svc.aggregate( ...args );
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import userAssignedStoreModel from 'tango-api-schema/schema/userAssignedStore.model.js';
|
|
2
|
+
import { createLoggableService } from '../logging/createLoggableService.js';
|
|
2
3
|
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
const _methods = {
|
|
6
|
+
async aggregateUserAssignedStore( query ) {
|
|
7
|
+
return await userAssignedStoreModel.aggregate( query );
|
|
8
|
+
},
|
|
9
|
+
async findUserAssignedStore( query ) {
|
|
10
|
+
return await userAssignedStoreModel.find( query );
|
|
11
|
+
},
|
|
6
12
|
};
|
|
7
13
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
14
|
+
const _svc = createLoggableService( _methods, 'userassignedstores' );
|
|
15
|
+
|
|
16
|
+
export const aggregateUserAssignedStore = ( ...args ) => _svc.aggregateUserAssignedStore( ...args );
|
|
17
|
+
export const findUserAssignedStore = ( ...args ) => _svc.findUserAssignedStore( ...args );
|
|
@@ -180,11 +180,21 @@ function buildQuestionAnswerEntries( question ) {
|
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
182
|
const validationImage = flattenImageRefs( userAnswer?.validationImage );
|
|
183
|
+
// Videos captured alongside 'Capture Multiple Image with description' validation (no runAI; shown as links).
|
|
184
|
+
const validationVideo = flattenImageRefs( userAnswer?.validationVideo );
|
|
185
|
+
|
|
186
|
+
const referenceImage = userAnswer?.referenceImage || matchedAnswer?.referenceImage || '';
|
|
187
|
+
// Left column shows a reference image only for non-image/video, non-multipleImage answer types.
|
|
188
|
+
// When there is no reference image, uploaded/validation media is rendered on the left instead of the right.
|
|
189
|
+
const hasReferenceImage = question?.answerType !== 'image/video' &&
|
|
190
|
+
question?.answerType !== 'multipleImage' &&
|
|
191
|
+
Boolean( referenceImage || multiReferenceImage.length );
|
|
183
192
|
|
|
184
193
|
return {
|
|
185
194
|
answer: userAnswer?.answer || '',
|
|
186
195
|
answerType: getMediaDisplayType( question?.answerType, userAnswer ),
|
|
187
|
-
referenceImage
|
|
196
|
+
referenceImage,
|
|
197
|
+
hasReferenceImage,
|
|
188
198
|
multiReferenceImage,
|
|
189
199
|
remarks: userAnswer?.remarks || '',
|
|
190
200
|
sopFlag: userAnswer?.sopFlag ?? matchedAnswer?.sopFlag ?? false,
|
|
@@ -192,12 +202,40 @@ function buildQuestionAnswerEntries( question ) {
|
|
|
192
202
|
validationType,
|
|
193
203
|
validationAnswer,
|
|
194
204
|
validationImage,
|
|
205
|
+
validationVideo,
|
|
195
206
|
validationDisplayType: getValidationDisplayType( validationType ),
|
|
196
207
|
};
|
|
197
208
|
} );
|
|
198
209
|
}
|
|
199
210
|
|
|
200
211
|
|
|
212
|
+
/**
|
|
213
|
+
* Extracts every 'Matched/Not Matched' value from a userAnswer's runAIData.
|
|
214
|
+
* Handles both shapes:
|
|
215
|
+
* - [ { answerImage, results: [ { featureName, value } ] } ] (per-image nested)
|
|
216
|
+
* - [ { featureName, value } ] (flat)
|
|
217
|
+
* @param {Array} runAIData
|
|
218
|
+
* @return {string[]} list of 'True' / 'False' values (in source order)
|
|
219
|
+
*/
|
|
220
|
+
function getRunAIMatchValues( runAIData ) {
|
|
221
|
+
if ( !Array.isArray( runAIData ) ) return [];
|
|
222
|
+
|
|
223
|
+
const values = [];
|
|
224
|
+
|
|
225
|
+
runAIData.forEach( ( item ) => {
|
|
226
|
+
if ( Array.isArray( item?.results ) ) {
|
|
227
|
+
item.results.forEach( ( res ) => {
|
|
228
|
+
if ( res?.featureName === 'Matched/Not Matched' ) values.push( res.value );
|
|
229
|
+
} );
|
|
230
|
+
} else if ( item?.featureName === 'Matched/Not Matched' ) {
|
|
231
|
+
values.push( item.value );
|
|
232
|
+
}
|
|
233
|
+
} );
|
|
234
|
+
|
|
235
|
+
return values;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
|
|
201
239
|
/**
|
|
202
240
|
|
|
203
241
|
* Map section array { sectionName, questions[] } (view API or processed checklist) to scores / template sections.
|
|
@@ -247,14 +285,18 @@ function mapSectionsFromQuestionAnswer( questionAnswer ) {
|
|
|
247
285
|
let score = q.compliance ? Math.max( ...q?.userAnswer?.map( ( o ) => o?.complianceScore ?? 0 ) ) : 0;
|
|
248
286
|
|
|
249
287
|
|
|
250
|
-
if ( q.answerType
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
288
|
+
if ( q.compliance && ( q.answerType === 'image' || q.answerType === 'image/video' ) ) {
|
|
289
|
+
// image/video questions mix image + video entries in userAnswer, so only score the images.
|
|
290
|
+
const imageAnswers = q.answerType === 'image/video' ?
|
|
291
|
+
( q.userAnswer || [] ).filter( ( ua ) => ua?.answerType === 'image' ) :
|
|
292
|
+
( q.userAnswer || [] );
|
|
293
|
+
|
|
294
|
+
const matchValues = imageAnswers.flatMap( ( ua ) => getRunAIMatchValues( ua?.runAIData ) );
|
|
295
|
+
|
|
296
|
+
if ( matchValues.length ) {
|
|
297
|
+
// All images must be matched ('True'); if any one is not, treat as not matched.
|
|
298
|
+
const allMatched = matchValues.every( ( value ) => value === 'True' );
|
|
299
|
+
score = allMatched ? ( q?.answers?.[0]?.matchedCount ?? 0 ) : ( q?.answers?.[0]?.notMatchedCount ?? 0 );
|
|
258
300
|
}
|
|
259
301
|
}
|
|
260
302
|
|
|
@@ -481,6 +523,9 @@ export function buildVisitChecklistTemplateDataFromProcessed( processedDoc, bran
|
|
|
481
523
|
|
|
482
524
|
let referenceId = doc.coverage == 'store' ? doc?.storeName : doc?.userName;
|
|
483
525
|
|
|
526
|
+
const userImage = doc.userImage || '';
|
|
527
|
+
const userSignature = doc.userSignature || '';
|
|
528
|
+
|
|
484
529
|
return {
|
|
485
530
|
|
|
486
531
|
|
|
@@ -512,6 +557,12 @@ export function buildVisitChecklistTemplateDataFromProcessed( processedDoc, bran
|
|
|
512
557
|
|
|
513
558
|
country: doc.country || '--',
|
|
514
559
|
|
|
560
|
+
userImage,
|
|
561
|
+
|
|
562
|
+
userSignature,
|
|
563
|
+
|
|
564
|
+
showUserVerification: Boolean( userImage || userSignature ),
|
|
565
|
+
|
|
515
566
|
hasCompliancePage,
|
|
516
567
|
|
|
517
568
|
detailPageStart,
|
|
@@ -622,6 +673,9 @@ function buildFromViewChecklistApi( getchecklistData, viewchecklistData, brandIn
|
|
|
622
673
|
} );
|
|
623
674
|
}
|
|
624
675
|
|
|
676
|
+
const userImage = checklistAnswer?.userImage || checklistInfo?.userImage || '';
|
|
677
|
+
const userSignature = checklistAnswer?.userSignature || checklistInfo?.userSignature || '';
|
|
678
|
+
|
|
625
679
|
return {
|
|
626
680
|
|
|
627
681
|
brandLogo: brandInfo.brandLogo || '',
|
|
@@ -656,6 +710,12 @@ function buildFromViewChecklistApi( getchecklistData, viewchecklistData, brandIn
|
|
|
656
710
|
|
|
657
711
|
country: storeProfile?.Country || '--',
|
|
658
712
|
|
|
713
|
+
userImage,
|
|
714
|
+
|
|
715
|
+
userSignature,
|
|
716
|
+
|
|
717
|
+
showUserVerification: Boolean( userImage || userSignature ),
|
|
718
|
+
|
|
659
719
|
hasCompliancePage,
|
|
660
720
|
|
|
661
721
|
detailPageStart,
|
|
@@ -782,6 +842,16 @@ export function createImageCache() {
|
|
|
782
842
|
}
|
|
783
843
|
|
|
784
844
|
|
|
845
|
+
if ( resolvedData.userImage && resolvedData.userImage.startsWith( 'http' ) ) {
|
|
846
|
+
urls.add( resolvedData.userImage );
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
|
|
850
|
+
if ( resolvedData.userSignature && resolvedData.userSignature.startsWith( 'http' ) ) {
|
|
851
|
+
urls.add( resolvedData.userSignature );
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
|
|
785
855
|
const collectFromSection = ( section ) => {
|
|
786
856
|
section.questions?.forEach( ( q ) => {
|
|
787
857
|
if ( q.questionReferenceImage && q.questionReferenceImage.startsWith( 'http' ) ) urls.add( q.questionReferenceImage );
|
|
@@ -842,6 +912,16 @@ export function createImageCache() {
|
|
|
842
912
|
}
|
|
843
913
|
|
|
844
914
|
|
|
915
|
+
if ( resolvedData.userImage ) {
|
|
916
|
+
resolvedData.userImage = cache.get( resolvedData.userImage ) || resolvedData.userImage;
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
|
|
920
|
+
if ( resolvedData.userSignature ) {
|
|
921
|
+
resolvedData.userSignature = cache.get( resolvedData.userSignature ) || resolvedData.userSignature;
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
|
|
845
925
|
const replaceInSection = ( section ) => {
|
|
846
926
|
section.questions?.forEach( ( q ) => {
|
|
847
927
|
if ( q.questionReferenceImage && cache.has( q.questionReferenceImage ) ) q.questionReferenceImage = cache.get( q.questionReferenceImage );
|
|
@@ -936,6 +1016,10 @@ export function resolveTemplateUrls( templateData, baseUrl = 'https://d1r0hc2ssk
|
|
|
936
1016
|
ua.validationImage = ua.validationImage.map( ( ele ) => resolveUrl( ele ) );
|
|
937
1017
|
}
|
|
938
1018
|
|
|
1019
|
+
if ( ua?.validationVideo?.length ) {
|
|
1020
|
+
ua.validationVideo = ua.validationVideo.map( ( ele ) => resolveUrl( ele ) );
|
|
1021
|
+
}
|
|
1022
|
+
|
|
939
1023
|
|
|
940
1024
|
if ( ua.answer && ua.answerType !== 'text' ) {
|
|
941
1025
|
ua.answer = resolveUrl( ua.answer );
|
|
@@ -954,11 +1038,18 @@ export function resolveTemplateUrls( templateData, baseUrl = 'https://d1r0hc2ssk
|
|
|
954
1038
|
|
|
955
1039
|
resolvedData.sections?.forEach( resolveQuestionMedia );
|
|
956
1040
|
|
|
957
|
-
|
|
958
|
-
if ( resolvedData.brandLogo && !resolvedData.brandLogo.startsWith( 'http' ) ) {
|
|
1041
|
+
if ( resolvedData?.brandLogo && !resolvedData?.brandLogo?.startsWith( 'http' ) ) {
|
|
959
1042
|
resolvedData.brandLogo = resolveUrl( resolvedData.brandLogo );
|
|
960
1043
|
}
|
|
961
1044
|
|
|
1045
|
+
if ( resolvedData?.userImage && !resolvedData.userImage.startsWith( 'http' ) && !resolvedData.userImage.startsWith( 'data:' ) ) {
|
|
1046
|
+
resolvedData.userImage = resolveUrl( resolvedData.userImage );
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
if ( resolvedData?.userSignature && !resolvedData.userSignature.startsWith( 'http' ) && !resolvedData.userSignature.startsWith( 'data:' ) ) {
|
|
1050
|
+
resolvedData.userSignature = resolveUrl( resolvedData.userSignature );
|
|
1051
|
+
}
|
|
1052
|
+
|
|
962
1053
|
|
|
963
1054
|
return resolvedData;
|
|
964
1055
|
}
|
|
@@ -1070,6 +1161,10 @@ export async function generateVisitChecklistPDF( templateData, baseUrl = 'https:
|
|
|
1070
1161
|
ua.validationImage = ua.validationImage.map( ( ele ) => resolveUrl( ele ) );
|
|
1071
1162
|
}
|
|
1072
1163
|
|
|
1164
|
+
if ( ua.validationVideo?.length ) {
|
|
1165
|
+
ua.validationVideo = ua.validationVideo.map( ( ele ) => resolveUrl( ele ) );
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1073
1168
|
if ( ua.answer && ua.answerType !== 'text' ) {
|
|
1074
1169
|
ua.answer = resolveUrl( ua.answer );
|
|
1075
1170
|
}
|
|
@@ -1087,6 +1182,14 @@ export async function generateVisitChecklistPDF( templateData, baseUrl = 'https:
|
|
|
1087
1182
|
resolvedData.brandLogo = resolveUrl( resolvedData.brandLogo );
|
|
1088
1183
|
}
|
|
1089
1184
|
|
|
1185
|
+
if ( resolvedData.userImage && !resolvedData.userImage.startsWith( 'http' ) && !resolvedData.userImage.startsWith( 'data:' ) ) {
|
|
1186
|
+
resolvedData.userImage = resolveUrl( resolvedData.userImage );
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
if ( resolvedData.userSignature && !resolvedData.userSignature.startsWith( 'http' ) && !resolvedData.userSignature.startsWith( 'data:' ) ) {
|
|
1190
|
+
resolvedData.userSignature = resolveUrl( resolvedData.userSignature );
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1090
1193
|
|
|
1091
1194
|
const html = template( resolvedData );
|
|
1092
1195
|
|