tango-app-api-store-zone 3.3.1-beta.9 → 3.3.2

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.
@@ -13,13 +13,42 @@ export const validateAddTagParams = {
13
13
  body: addTagSchema,
14
14
  };
15
15
 
16
+ // zone tagging
17
+ export const zoneAddTagSchema = joi.object( {
18
+ clientId: joi.string().required(),
19
+ tagName: joi.string().required(),
20
+ productName: joi.string().required(),
21
+ rgbColor: joi.string().required(),
22
+ rgbBorderColor: joi.string().required(),
23
+ groupName: joi.string().allow( '', null ).optional(),
24
+ isExistingGroup: joi.boolean().optional(),
25
+ } );
26
+
27
+ export const validateZoneAddTagParams = {
28
+ body: zoneAddTagSchema,
29
+ };
30
+
31
+ // zone grouping
32
+ export const zoneGroupAddTagSchema = joi.object( {
33
+ clientId: joi.string().required(),
34
+ groupName: joi.string().required(),
35
+ productName: joi.string().required(),
36
+ tagName: joi.string().optional(),
37
+ zonesTagged: joi.array().items( joi.string() ).optional(),
38
+ } );
39
+
40
+ export const validateZoneGroupAddTagParams = {
41
+ body: zoneGroupAddTagSchema,
42
+ };
43
+
16
44
  export const tagSchema = joi.object( {
17
45
  clientId: joi.string().required(),
18
46
  storeId: joi.string().required(),
47
+ tagName: joi.string().optional(),
19
48
  } );
20
49
 
21
50
  export const validateTagParams = {
22
- query: tagSchema,
51
+ body: tagSchema,
23
52
  };
24
53
 
25
54
  export const validateUpdateTagSchema = joi.object( {
@@ -33,6 +62,20 @@ export const validateUpdateTagParams = {
33
62
  body: validateUpdateTagSchema,
34
63
  };
35
64
 
65
+ export const validateZoneUpdateTagSchema = joi.object( {
66
+ clientId: joi.string().required(),
67
+ tagName: joi.string().required(),
68
+ productName: joi.string().required(),
69
+ _id: joi.string().optional(),
70
+ groupName: joi.string().allow( '', null ).optional(),
71
+ isExistingGroup: joi.boolean().optional(),
72
+ oldTag: joi.string().optional(),
73
+ } );
74
+
75
+ export const validateZoneUpdateTagParams = {
76
+ body: validateZoneUpdateTagSchema,
77
+ };
78
+
36
79
 
37
80
  export const validateDeleteTagSchema = joi.object( {
38
81
  tagName: joi.string().required(),
@@ -44,6 +87,25 @@ export const validateDeleteTagParams = {
44
87
  body: validateDeleteTagSchema,
45
88
  };
46
89
 
90
+ export const validateZoneDeleteTagSchema = joi.object( {
91
+ tagName: joi.string().required(),
92
+ clientId: joi.string().required(),
93
+ } );
94
+
95
+ export const validateZoneDeleteTagParams = {
96
+ body: validateZoneDeleteTagSchema,
97
+ };
98
+
99
+ export const validateZoneGroupDeleteTagSchema = joi.object( {
100
+ groupName: joi.string().required(),
101
+ clientId: joi.string().required(),
102
+ _id: joi.string().required(),
103
+ } );
104
+
105
+ export const validateZoneGroupDeleteTagParams = {
106
+ body: validateZoneGroupDeleteTagSchema,
107
+ };
108
+
47
109
  export const validateTaggingSchema = joi.object( {
48
110
  clientId: joi.string().required(),
49
111
  storeId: joi.string().required(),
@@ -100,3 +162,83 @@ export const updateCoordinatesSchema= joi.object( {
100
162
  export const updateCoordinatesParams = {
101
163
  body: updateCoordinatesSchema,
102
164
  };
165
+
166
+ export const getStreamSchema= joi.object( {
167
+ storeId: joi.string().required(),
168
+ clientId: joi.string().required(),
169
+ streamName: joi.string().required(),
170
+ } );
171
+
172
+ export const getStreamParams = {
173
+ body: getStreamSchema,
174
+ };
175
+
176
+ export const validateZoneConfigTaggingSchema = joi.object( {
177
+ clientId: joi.string().required(),
178
+ limit: joi.number().integer().min( 1 ).optional(),
179
+ offset: joi.number().integer().min( 0 ).optional(),
180
+ searchValue: joi.string().allow( '' ).optional(),
181
+ export: joi.boolean().optional(),
182
+ sortBy: joi.number().optional(),
183
+ sortColumName: joi.string().allow( '' ).optional(),
184
+ } );
185
+
186
+ export const validateZoneConfigTaggingParams = {
187
+ body: validateZoneConfigTaggingSchema,
188
+ };
189
+
190
+ export const validateZoneGroupSchema = joi.object( {
191
+ clientId: joi.string().required(),
192
+ limit: joi.number().integer().min( 1 ).optional(),
193
+ offset: joi.number().integer().min( 0 ).optional(),
194
+ searchValue: joi.string().allow( '' ).optional(),
195
+ export: joi.boolean().optional(),
196
+ sortBy: joi.number().optional(),
197
+ sortColumName: joi.string().allow( '' ).optional(),
198
+ } );
199
+
200
+ export const validateZoneGroupingParams = {
201
+ body: validateZoneGroupSchema,
202
+ };
203
+
204
+ // bulk zone tagging - array of zones (request body is array directly)
205
+ export const bulkZoneAddTagSchema = joi.array().items(
206
+ joi.object( {
207
+ clientId: joi.string().required(),
208
+ tagName: joi.string().required(),
209
+ productName: joi.string().required(),
210
+ rgbColor: joi.string().required(),
211
+ rgbBorderColor: joi.string().required(),
212
+ groupName: joi.string().allow( '', null ).optional(),
213
+ } ),
214
+ ).min( 1 ).required();
215
+
216
+ export const validateBulkZoneAddTagParams = {
217
+ body: bulkZoneAddTagSchema,
218
+ };
219
+
220
+ // bulk zone-group (request body)
221
+ export const bulkZoneGroupAddTagSchema = joi.array().items(
222
+ joi.object( {
223
+ clientId: joi.string().required(),
224
+ groupName: joi.string().required(),
225
+ productName: joi.string().required(),
226
+ } ),
227
+ ).min( 1 ).required();
228
+
229
+ export const validateBulkZoneGroupAddTagParams = {
230
+ body: bulkZoneGroupAddTagSchema,
231
+ };
232
+
233
+ export const validateZoneGroupUpdateSchema = joi.object( {
234
+ _id: joi.string().optional(),
235
+ clientId: joi.string().required(),
236
+ groupName: joi.string().required(),
237
+ oldGroupName: joi.string().optional(),
238
+ productName: joi.string().required(),
239
+ zonesTagged: joi.array().items( joi.string() ).optional(),
240
+ } );
241
+
242
+ export const validateZoneGroupUpdateParams = {
243
+ body: validateZoneGroupUpdateSchema,
244
+ };
@@ -4,23 +4,39 @@ import express from 'express';
4
4
  import { isAllowedSessionHandler, validate, accessVerification } from 'tango-app-api-middleware';
5
5
  import * as validation from '../dtos/validation.dtos.js';
6
6
  import * as tagController from '../controllers/zoneTagging.controller.js';
7
+ import { bulkZoneExists, bulkZoneGroupExists } from '../validations/zone.validations.js';
7
8
 
8
9
  export const zoneTaggingRouter = express.Router();
9
10
 
10
11
  zoneTaggingRouter.post( '/addCustomTag', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoEye', name: 'ZoneTag', permissions: [ 'isAdd' ] } ] } ), validate( validation.validateAddTagParams ), tagController.addCustomTag );
11
12
  zoneTaggingRouter.get( '/customTagList', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoEye', name: 'ZoneTag', permissions: [ ] } ] } ), validate( validation.validateTagParams ), tagController.customTagList );
12
13
  zoneTaggingRouter.get( '/customTagListv2', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoEye', name: 'ZoneTag', permissions: [ ] } ] } ), tagController.customTagListv2 );
14
+ zoneTaggingRouter.get( '/customTagListv3', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoEye', name: 'ZoneTag', permissions: [ ] } ] } ), tagController.customTagListv3 );
13
15
  zoneTaggingRouter.post( '/tagging', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoEye', name: 'ZoneTag', permissions: [ 'isEdit' ] } ] } ), validate( validation.validateTaggingParams ), tagController.tagging );
14
16
  zoneTaggingRouter.get( '/cameraList', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoEye', name: 'ZoneTag', permissions: [ ] } ] } ), validate( validation.validateTagParams ), tagController.getCameraList );
15
- zoneTaggingRouter.get( '/cameraListv2', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoEye', name: 'ZoneTag', permissions: [ ] } ] } ), validate( validation.validateTagParams ), tagController.getCameraListv2 );
17
+ zoneTaggingRouter.post( '/cameraListv2', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoEye', name: 'ZoneTag', permissions: [ ] } ] } ), validate( validation.validateTagParams ), tagController.getCameraListv2 );
16
18
  zoneTaggingRouter.post( '/updateCustomTag', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoEye', name: 'ZoneTag', permissions: [ 'isEdit' ] } ] } ), validate( validation.validateUpdateTagParams ), tagController.updateTag );
17
19
  zoneTaggingRouter.post( '/deleteCustomTag', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoEye', name: 'ZoneTag', permissions: [ 'isEdit' ] } ] } ), validate( validation.validateDeleteTagParams ), tagController.deleteTag );
18
20
  zoneTaggingRouter.get( '/getCameraTagging', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoEye', name: 'ZoneTag', permissions: [ ] } ] } ), validate( validation.validateCameraTagParams ), tagController.getCameraTagging );
19
21
  zoneTaggingRouter.get( '/getZoneTagging', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoEye', name: 'ZoneTag', permissions: [ ] } ] } ), validate( validation.validateZonetagParams ), tagController.getZoneList );
20
22
  zoneTaggingRouter.post( '/updatezoneTagging', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoEye', name: 'ZoneTag', permissions: [ 'isEdit' ] } ] } ), validate( validation.validateCamZonetagParams ), tagController.updatezoneTagging );
21
23
  zoneTaggingRouter.post( '/deleteZoneTag', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoEye', name: 'ZoneTag', permissions: [ 'isEdit' ] } ] } ), validate( validation.updateCoordinatesParams ), tagController.deletezoneTagging );
24
+ zoneTaggingRouter.post( '/getStreamDetails', isAllowedSessionHandler, validate( validation.getStreamParams ), tagController.getCameraStreamList );
22
25
  zoneTaggingRouter.post( '/updateCamera', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoEye', name: 'ZoneTag', permissions: [ 'isEdit' ] } ] } ), tagController.updateCamera );
23
26
 
24
27
  zoneTaggingRouter.get( '/updateOldZone', tagController.updateOldData );
25
28
 
29
+ // settings config - zone routes
30
+ zoneTaggingRouter.post( '/getZoneTaggingDetails', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoEye', name: 'ZoneTag', permissions: [ ] } ] } ), validate( validation.validateZoneConfigTaggingParams ), tagController.getZoneTaggingDetails );
31
+ zoneTaggingRouter.post( '/addZoneCustomTag', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoEye', name: 'ZoneTag', permissions: [ 'isAdd' ] } ] } ), validate( validation.validateZoneAddTagParams ), tagController.addZoneCustomTag );
32
+ // bulk zone upload
33
+ zoneTaggingRouter.post( '/bulkZoneUpload', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoEye', name: 'ZoneTag', permissions: [ 'isAdd' ] } ] } ), validate( validation.validateBulkZoneAddTagParams ), bulkZoneExists, tagController.uploadBulkZoneTag );
34
+ zoneTaggingRouter.post( '/updateZoneCustomTag', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoEye', name: 'ZoneTag', permissions: [ 'isEdit' ] } ] } ), validate( validation.validateZoneUpdateTagParams ), tagController.updateZoneCustomTag );
35
+ zoneTaggingRouter.post( '/deleteZoneCustomTag', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoEye', name: 'ZoneTag', permissions: [ 'isEdit' ] } ] } ), validate( validation.validateZoneDeleteTagSchema ), tagController.deleteZoneCustomTag );
26
36
 
37
+ // settings config - zoneGrouping routes
38
+ zoneTaggingRouter.post( '/getZoneGroupDetails', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoEye', name: 'ZoneTag', permissions: [ ] } ] } ), validate( validation.validateZoneGroupingParams ), tagController.getZoneGroupDetails );
39
+ zoneTaggingRouter.post( '/addZoneGroup', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoEye', name: 'ZoneTag', permissions: [ 'isAdd' ] } ] } ), validate( validation.validateZoneGroupAddTagParams ), tagController.addZoneGroup );
40
+ zoneTaggingRouter.post( '/bulkZoneGroupUpload', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoEye', name: 'ZoneTag', permissions: [ 'isAdd' ] } ] } ), validate( validation.validateBulkZoneGroupAddTagParams ), bulkZoneGroupExists, tagController.uploadBulkZoneGroup );
41
+ zoneTaggingRouter.post( '/updateZoneGroup', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoEye', name: 'ZoneTag', permissions: [ 'isEdit' ] } ] } ), validate( validation.validateZoneGroupUpdateParams ), tagController.updateZoneGroup );
42
+ zoneTaggingRouter.post( '/deleteZoneGroup', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoEye', name: 'ZoneTag', permissions: [ 'isEdit' ] } ] } ), validate( validation.validateZoneGroupDeleteTagParams ), tagController.deleteZoneGroup );
@@ -0,0 +1,31 @@
1
+ import model from 'tango-api-schema';
2
+
3
+ export const findOne = async ( query={}, field={} ) => {
4
+ return model.checklistconfigModel.findOne( query, field );
5
+ };
6
+
7
+ export const find = async ( query={}, field={} ) => {
8
+ return model.checklistconfigModel.find( query, field );
9
+ };
10
+
11
+ export const create = async ( document = {} ) => {
12
+ return model.checklistconfigModel.create( document );
13
+ };
14
+
15
+ export const deleteOne = async ( query = {} ) => {
16
+ return model.checklistconfigModel.deleteOne( query );
17
+ };
18
+
19
+ export const updateOne = async ( query = {}, record={} ) => {
20
+ return model.checklistconfigModel.updateOne( query, { $set: record }, { upsert: true } );
21
+ };
22
+
23
+ export const updateMany = async ( query = {}, record={} ) => {
24
+ return model.checklistconfigModel.updateMany( query, { $set: record } );
25
+ };
26
+
27
+ export const aggregate = async ( query = {} ) => {
28
+ return model.checklistconfigModel.aggregate( query );
29
+ };
30
+
31
+
@@ -0,0 +1,55 @@
1
+ import model from 'tango-api-schema';
2
+
3
+ export const findOne = async ( query ={}, record = {} ) => {
4
+ return await model.zonegroupsModel.findOne( query, record );
5
+ };
6
+
7
+ export const find = async ( query = {}, record = {}, options = {} ) => {
8
+ let queryBuilder = model.zonegroupsModel.find( query, record );
9
+
10
+ // Apply pagination if provided
11
+ if ( options.skip !== undefined ) {
12
+ queryBuilder = queryBuilder.skip( options.skip );
13
+ }
14
+ if ( options.limit !== undefined ) {
15
+ queryBuilder = queryBuilder.limit( options.limit );
16
+ }
17
+ if ( options.sort !== undefined ) {
18
+ queryBuilder = queryBuilder.sort( options.sort );
19
+ }
20
+
21
+ return await queryBuilder;
22
+ };
23
+
24
+ export const aggregate = async ( query ={} ) => {
25
+ return await model.zonegroupsModel.aggregate( query );
26
+ };
27
+
28
+ // export const deleteMany = async ( query = {} ) => {
29
+ // return await model.zonegroupsModel.deleteMany( query );
30
+ // };
31
+
32
+ export const deleteOne = async ( query = {} ) => {
33
+ return await model.zonegroupsModel.deleteOne( query );
34
+ };
35
+
36
+ // export const insertMany = async ( data = [] ) => {
37
+ // return await model.zonegroupsModel.insertMany( data );
38
+ // };
39
+
40
+ // export const updateMany = async ( query = {}, record ={} ) => {
41
+ // return await model.zonegroupsModel.updateMany( query, record );
42
+ // };
43
+
44
+ export const updateOne = async ( query = {}, record ={} ) => {
45
+ return await model.zonegroupsModel.updateOne( query, record );
46
+ };
47
+
48
+ export const create = async ( data = [] ) => {
49
+ return await model.zonegroupsModel.create( data );
50
+ };
51
+
52
+ export const count = async ( query = {} ) => {
53
+ return await model.zonegroupsModel.countDocuments( query );
54
+ };
55
+
@@ -0,0 +1,56 @@
1
+ import model from 'tango-api-schema';
2
+
3
+ export const findOne = async ( query ={}, record = {} ) => {
4
+ console.log( 'customZoneTagService findOne query :', query );
5
+ return await model.customZonetagsModel.findOne( query, record );
6
+ };
7
+
8
+ export const find = async ( query = {}, record = {}, options = {} ) => {
9
+ let queryBuilder = model.customZonetagsModel.find( query, record );
10
+
11
+ // Apply pagination if provided
12
+ if ( options.skip !== undefined ) {
13
+ queryBuilder = queryBuilder.skip( options.skip );
14
+ }
15
+ if ( options.limit !== undefined ) {
16
+ queryBuilder = queryBuilder.limit( options.limit );
17
+ }
18
+ if ( options.sort !== undefined ) {
19
+ queryBuilder = queryBuilder.sort( options.sort );
20
+ }
21
+
22
+ return await queryBuilder;
23
+ };
24
+
25
+ export const aggregate = async ( query ={}, record = {} ) => {
26
+ return await model.customZonetagsModel.aggregate( query );
27
+ };
28
+
29
+ // export const deleteMany = async ( query = {} ) => {
30
+ // return await model.customZonetagsModel.deleteMany( query );
31
+ // };
32
+
33
+ export const deleteOne = async ( query = {} ) => {
34
+ return await model.customZonetagsModel.deleteOne( query );
35
+ };
36
+
37
+ // export const insertMany = async ( data = [] ) => {
38
+ // return await model.customZonetagsModel.insertMany( data );
39
+ // };
40
+
41
+ export const updateMany = async ( query = {}, record ={} ) => {
42
+ return await model.customZonetagsModel.updateMany( query, record );
43
+ };
44
+
45
+ export const updateOne = async ( query = {}, record ={} ) => {
46
+ return await model.customZonetagsModel.updateOne( query, record );
47
+ };
48
+
49
+ export const create = async ( data = [] ) => {
50
+ return await model.customZonetagsModel.create( data );
51
+ };
52
+
53
+ export const count = async ( query = {} ) => {
54
+ return await model.customZonetagsModel.countDocuments( query );
55
+ };
56
+
@@ -36,3 +36,6 @@ export const create = async ( data = [] ) => {
36
36
  return await model.taggingModel.create( data );
37
37
  };
38
38
 
39
+ export const getDistinct = async ( fieldName, filter = {} ) => {
40
+ return await model.taggingModel.distinct( fieldName, filter );
41
+ };
@@ -0,0 +1,110 @@
1
+ import { logger } from 'tango-app-api-middleware';
2
+ import * as customZoneTagService from '../services/customzonetag.service.js';
3
+ import * as customzonegrouping from '../services/customzonegrouping.service.js';
4
+
5
+
6
+ export async function bulkZoneExists( req, res, next ) {
7
+ try {
8
+ const zonesArray = req.body;
9
+
10
+ // Validate zones array exists and is not empty
11
+ if ( !zonesArray || !Array.isArray( zonesArray ) || zonesArray.length === 0 ) {
12
+ return res.sendError( 'zone file should not be empty', 400 );
13
+ }
14
+
15
+ // Validate all zones have the same clientId
16
+ const clientIds = zonesArray.map( ( zone ) => zone.clientId );
17
+ const uniqueClientIds = [ ...new Set( clientIds ) ];
18
+ if ( uniqueClientIds.length > 1 ) {
19
+ return res.sendError( 'All zones must have the same clientId', 400 );
20
+ }
21
+ console.log( 'uniqueClientIds :', uniqueClientIds );
22
+ if ( !uniqueClientIds[0] ) {
23
+ return res.sendError( 'clientId is required for all zones', 400 );
24
+ }
25
+ const clientId = uniqueClientIds[0];
26
+
27
+ // Check for duplicate tagNames within the request
28
+ const tagNameList = zonesArray.map( ( zone ) => zone.tagName );
29
+ const tagNameListLower = tagNameList.map( ( name ) => name.toLowerCase() );
30
+ const uniqueTagNamesLower = [ ...new Set( tagNameListLower ) ];
31
+ if ( uniqueTagNamesLower.length !== tagNameListLower.length ) {
32
+ return res.sendError( `Duplicate zone name found in request.`, 400 );
33
+ }
34
+
35
+ // Fetch all existing tags for this client and compare
36
+ const existingZones = await customZoneTagService.find( {
37
+ clientId: clientId,
38
+ } );
39
+
40
+ if ( existingZones && existingZones.length > 0 ) {
41
+ const existingTagNamesLower = existingZones.map( ( zone ) => zone.tagName?.toLowerCase() ).filter( Boolean );
42
+ const hasDuplicate = tagNameListLower.some( ( tagNameLower ) => existingTagNamesLower.includes( tagNameLower ) );
43
+ if ( hasDuplicate ) {
44
+ return res.sendError( `Zone names already exist for this client.`, 409 );
45
+ }
46
+ }
47
+
48
+ // Attach clientId to req for use in controller
49
+ req.bulkZoneClientId = clientId;
50
+ next();
51
+ } catch ( error ) {
52
+ const err = error.message || 'Internal Server Error';
53
+ logger.error( { error: error, message: req.body, function: 'bulkZoneExists' } );
54
+ return res.sendError( err, 500 );
55
+ }
56
+ }
57
+
58
+
59
+ export async function bulkZoneGroupExists( req, res, next ) {
60
+ try {
61
+ const groupsArray = req.body;
62
+
63
+ // Validate groups array exists and is not empty
64
+ if ( !groupsArray || !Array.isArray( groupsArray ) || groupsArray.length === 0 ) {
65
+ return res.sendError( 'group file should not be empty', 400 );
66
+ }
67
+
68
+ // Validate all groups have the same clientId
69
+ const clientIds = groupsArray.map( ( group ) => group.clientId );
70
+ const uniqueClientIds = [ ...new Set( clientIds ) ];
71
+ if ( uniqueClientIds.length > 1 ) {
72
+ return res.sendError( 'All groups must have the same clientId', 400 );
73
+ }
74
+ console.log( 'uniqueClientIds :', uniqueClientIds );
75
+ if ( !uniqueClientIds[0] ) {
76
+ return res.sendError( 'clientId is required for all groups', 400 );
77
+ }
78
+ const clientId = uniqueClientIds[0];
79
+
80
+ // Check for duplicate groupNames within the request (case-insensitive)
81
+ const groupNameList = groupsArray.map( ( group ) => group.groupName );
82
+ const groupNameListLower = groupNameList.map( ( name ) => name.toLowerCase() );
83
+ const uniqueGroupNamesLower = [ ...new Set( groupNameListLower ) ];
84
+ if ( uniqueGroupNamesLower.length !== groupNameListLower.length ) {
85
+ return res.sendError( `Duplicate group names found in request.`, 400 );
86
+ }
87
+
88
+ // Check if any groupNames already exist in the database for this client (case-insensitive)
89
+ // Fetch all existing groups for this client and compare case-insensitively
90
+ const existingGroups = await customzonegrouping.find( {
91
+ clientId: clientId,
92
+ } );
93
+
94
+ if ( existingGroups && existingGroups.length > 0 ) {
95
+ const existingGroupNamesLower = existingGroups.map( ( group ) => group.groupName?.toLowerCase() ).filter( Boolean );
96
+ const hasDuplicate = groupNameListLower.some( ( groupNameLower ) => existingGroupNamesLower.includes( groupNameLower ) );
97
+ if ( hasDuplicate ) {
98
+ return res.sendError( `Group names already exist for this client.`, 409 );
99
+ }
100
+ }
101
+
102
+ // Attach clientId to req for use in controller
103
+ req.bulkZoneClientId = clientId;
104
+ next();
105
+ } catch ( error ) {
106
+ const err = error.message || 'Internal Server Error';
107
+ logger.error( { error: error, message: req.body, function: 'bulkZoneGroupExists' } );
108
+ return res.sendError( err, 500 );
109
+ }
110
+ }
@@ -1,35 +0,0 @@
1
- import model from 'tango-api-schema';
2
-
3
- export const find = ( query = {}, record = {} ) => {
4
- return model.processedchecklistconfigModel.find( query, record );
5
- };
6
-
7
- export const findOne = ( query = {}, record = {} ) => {
8
- return model.processedchecklistconfigModel.findOne( query, record ).sort( { updatedAt: -1 } );
9
- };
10
-
11
- export const updateOne = ( query = {}, record = {} ) => {
12
- return model.processedchecklistconfigModel.updateOne( query, { $set: record }, { upsert: true } );
13
- };
14
-
15
- export const updateMany = ( query = {}, record = {} ) => {
16
- return model.processedchecklistconfigModel.updateMany( query, { $set: record } );
17
- };
18
-
19
- export const deleteMany = ( query = {} ) => {
20
- return model.processedchecklistconfigModel.deleteMany( query );
21
- };
22
-
23
- export const aggregate = ( query = [] ) => {
24
- return model.processedchecklistconfigModel.aggregate( query );
25
- };
26
-
27
- export const getClientCount = ( query = {} ) => {
28
- return model.processedchecklistconfigModel.count( query );
29
- };
30
-
31
- export const insert = ( document={} ) => {
32
- return model.processedchecklistconfigModel.create( document );
33
- };
34
-
35
-