@7365admin1/core 2.65.0 → 2.66.0
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/CHANGELOG.md +6 -0
- package/dist/index.d.ts +75 -13
- package/dist/index.js +1636 -626
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1635 -626
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -55,6 +55,7 @@ __export(src_exports, {
|
|
|
55
55
|
EventType: () => EventType,
|
|
56
56
|
FacilitySort: () => FacilitySort,
|
|
57
57
|
FacilityStatus: () => FacilityStatus,
|
|
58
|
+
FormEntryStatus: () => FormEntryStatus,
|
|
58
59
|
GuestSort: () => GuestSort,
|
|
59
60
|
GuestStatus: () => GuestStatus,
|
|
60
61
|
MAccessCard: () => MAccessCard,
|
|
@@ -76,6 +77,7 @@ __export(src_exports, {
|
|
|
76
77
|
MEventManagement: () => MEventManagement,
|
|
77
78
|
MFeedback: () => MFeedback,
|
|
78
79
|
MFile: () => MFile,
|
|
80
|
+
MFormEntry: () => MFormEntry,
|
|
79
81
|
MGuestManagement: () => MGuestManagement,
|
|
80
82
|
MIncidentReport: () => MIncidentReport,
|
|
81
83
|
MManpowerDesignations: () => MManpowerDesignations,
|
|
@@ -187,6 +189,7 @@ __export(src_exports, {
|
|
|
187
189
|
nfcPatrolSettingsSchema: () => nfcPatrolSettingsSchema,
|
|
188
190
|
nfcPatrolSettingsSchemaUpdate: () => nfcPatrolSettingsSchemaUpdate,
|
|
189
191
|
occurrence_book_namespace_collection: () => occurrence_book_namespace_collection,
|
|
192
|
+
online_forms_namespace_collection: () => online_forms_namespace_collection,
|
|
190
193
|
orgSchema: () => orgSchema,
|
|
191
194
|
overnight_parking_requests_namespace_collection: () => overnight_parking_requests_namespace_collection,
|
|
192
195
|
parseDahuaFind: () => parseDahuaFind,
|
|
@@ -211,6 +214,7 @@ __export(src_exports, {
|
|
|
211
214
|
schemaEntryPassSettings: () => schemaEntryPassSettings,
|
|
212
215
|
schemaEventManagement: () => schemaEventManagement,
|
|
213
216
|
schemaFiles: () => schemaFiles,
|
|
217
|
+
schemaFormEntry: () => schemaFormEntry,
|
|
214
218
|
schemaGuestManagement: () => schemaGuestManagement,
|
|
215
219
|
schemaIncidentReport: () => schemaIncidentReport,
|
|
216
220
|
schemaNfcPatrolLog: () => schemaNfcPatrolLog,
|
|
@@ -241,6 +245,7 @@ __export(src_exports, {
|
|
|
241
245
|
schemaUpdateDocumentManagement: () => schemaUpdateDocumentManagement,
|
|
242
246
|
schemaUpdateEntryPassSettings: () => schemaUpdateEntryPassSettings,
|
|
243
247
|
schemaUpdateEventManagement: () => schemaUpdateEventManagement,
|
|
248
|
+
schemaUpdateFormEntry: () => schemaUpdateFormEntry,
|
|
244
249
|
schemaUpdateGuestManagement: () => schemaUpdateGuestManagement,
|
|
245
250
|
schemaUpdateIncidentReport: () => schemaUpdateIncidentReport,
|
|
246
251
|
schemaUpdateOccurrenceBook: () => schemaUpdateOccurrenceBook,
|
|
@@ -324,6 +329,8 @@ __export(src_exports, {
|
|
|
324
329
|
useFileController: () => useFileController,
|
|
325
330
|
useFileRepo: () => useFileRepo,
|
|
326
331
|
useFileService: () => useFileService,
|
|
332
|
+
useFormEntryController: () => useFormEntryController,
|
|
333
|
+
useFormEntryRepo: () => useFormEntryRepo,
|
|
327
334
|
useGuestManagementController: () => useGuestManagementController,
|
|
328
335
|
useGuestManagementRepo: () => useGuestManagementRepo,
|
|
329
336
|
useGuestManagementService: () => useGuestManagementService,
|
|
@@ -588,7 +595,15 @@ var userSchema = import_joi2.default.object({
|
|
|
588
595
|
email: import_joi2.default.string().email().required(),
|
|
589
596
|
password: import_joi2.default.string().min(8).required(),
|
|
590
597
|
name: import_joi2.default.string().required(),
|
|
591
|
-
defaultOrg: import_joi2.default.string().hex().optional().allow("", null)
|
|
598
|
+
defaultOrg: import_joi2.default.string().hex().optional().allow("", null),
|
|
599
|
+
status: import_joi2.default.string().optional().allow("", null),
|
|
600
|
+
block: import_joi2.default.number().optional().allow(null),
|
|
601
|
+
level: import_joi2.default.string().optional().allow("", null),
|
|
602
|
+
type: import_joi2.default.string().optional().allow("", null),
|
|
603
|
+
unitName: import_joi2.default.string().optional().allow("", null),
|
|
604
|
+
contact: import_joi2.default.string().optional().allow("", null),
|
|
605
|
+
site: import_joi2.default.string().hex().optional().allow("", null),
|
|
606
|
+
unitId: import_joi2.default.string().hex().optional().allow("", null)
|
|
592
607
|
});
|
|
593
608
|
function MUser(value) {
|
|
594
609
|
const { error } = userSchema.validate(value);
|
|
@@ -602,12 +617,33 @@ function MUser(value) {
|
|
|
602
617
|
throw new import_node_server_utils3.BadRequestError("Invalid default org ID format.");
|
|
603
618
|
}
|
|
604
619
|
}
|
|
620
|
+
if (value.site && typeof value.site === "string") {
|
|
621
|
+
try {
|
|
622
|
+
value.site = new import_mongodb.ObjectId(value.site);
|
|
623
|
+
} catch {
|
|
624
|
+
throw new import_node_server_utils3.BadRequestError("Invalid site ID format.");
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
if (value.unitId && typeof value.unitId === "string") {
|
|
628
|
+
try {
|
|
629
|
+
value.unitId = new import_mongodb.ObjectId(value.unitId);
|
|
630
|
+
} catch {
|
|
631
|
+
throw new import_node_server_utils3.BadRequestError("Invalid unit ID format.");
|
|
632
|
+
}
|
|
633
|
+
}
|
|
605
634
|
return {
|
|
606
635
|
email: value.email,
|
|
607
636
|
password: value.password,
|
|
608
637
|
name: value.name ?? "",
|
|
609
638
|
defaultOrg: value.defaultOrg ?? "",
|
|
610
|
-
status: "active" /* ACTIVE */,
|
|
639
|
+
status: value.status ?? "active" /* ACTIVE */,
|
|
640
|
+
block: value.block ?? null,
|
|
641
|
+
level: value.level ?? "",
|
|
642
|
+
type: value.type ?? "",
|
|
643
|
+
unitName: value.unitName ?? "",
|
|
644
|
+
contact: value.contact ?? "",
|
|
645
|
+
site: value.site ?? "",
|
|
646
|
+
unitId: value.unitId ?? "",
|
|
611
647
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
612
648
|
updatedAt: value.updatedAt ?? "",
|
|
613
649
|
deletedAt: value.deletedAt ?? ""
|
|
@@ -4753,6 +4789,30 @@ function useOrgRepo() {
|
|
|
4753
4789
|
throw error;
|
|
4754
4790
|
}
|
|
4755
4791
|
}
|
|
4792
|
+
async function getOrgsByEmail(email) {
|
|
4793
|
+
const cacheKey = (0, import_node_server_utils17.makeCacheKey)(namespace_collection, {
|
|
4794
|
+
type: "many",
|
|
4795
|
+
email
|
|
4796
|
+
});
|
|
4797
|
+
const cachedData = await getCache(cacheKey);
|
|
4798
|
+
if (cachedData) {
|
|
4799
|
+
import_node_server_utils17.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
4800
|
+
return cachedData;
|
|
4801
|
+
}
|
|
4802
|
+
try {
|
|
4803
|
+
const data = await collection.find({
|
|
4804
|
+
email
|
|
4805
|
+
}).toArray();
|
|
4806
|
+
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
4807
|
+
import_node_server_utils17.logger.info(`Cache set for key: ${cacheKey}`);
|
|
4808
|
+
}).catch((err) => {
|
|
4809
|
+
import_node_server_utils17.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
4810
|
+
});
|
|
4811
|
+
return data;
|
|
4812
|
+
} catch (error) {
|
|
4813
|
+
throw error;
|
|
4814
|
+
}
|
|
4815
|
+
}
|
|
4756
4816
|
async function updateFieldById({
|
|
4757
4817
|
_id,
|
|
4758
4818
|
field,
|
|
@@ -4855,7 +4915,8 @@ function useOrgRepo() {
|
|
|
4855
4915
|
getByEmail,
|
|
4856
4916
|
updateFieldById,
|
|
4857
4917
|
updateStatusById,
|
|
4858
|
-
deleteById
|
|
4918
|
+
deleteById,
|
|
4919
|
+
getOrgsByEmail
|
|
4859
4920
|
};
|
|
4860
4921
|
}
|
|
4861
4922
|
|
|
@@ -5855,7 +5916,6 @@ function useVerificationService() {
|
|
|
5855
5916
|
await getSiteById(metadata.siteId);
|
|
5856
5917
|
}
|
|
5857
5918
|
const verificationIds = [];
|
|
5858
|
-
const invitedApps = [];
|
|
5859
5919
|
for (const app of apps) {
|
|
5860
5920
|
await useVerificationRepo().findOne({
|
|
5861
5921
|
type,
|
|
@@ -5878,34 +5938,32 @@ function useVerificationService() {
|
|
|
5878
5938
|
};
|
|
5879
5939
|
const createdId = await add(value);
|
|
5880
5940
|
verificationIds.push(createdId.toString());
|
|
5881
|
-
|
|
5941
|
+
const link = `${APP_MAIN}/verify/invitation/${createdId}`;
|
|
5942
|
+
const emailContent = (0, import_node_server_utils21.compileHandlebar)({
|
|
5943
|
+
context: {
|
|
5944
|
+
email,
|
|
5945
|
+
validity: VERIFICATION_USER_INVITE_DURATION,
|
|
5946
|
+
link,
|
|
5947
|
+
hasPropertyManagement: app === "property_management_agency",
|
|
5948
|
+
hasSecurity: app === "security_agency",
|
|
5949
|
+
hasCleaning: app === "cleaning_services",
|
|
5950
|
+
hasMechanical: app === "mechanical_electrical_services",
|
|
5951
|
+
hasLandscape: app === "landscaping_services",
|
|
5952
|
+
hasPestControl: app === "pest_control_services",
|
|
5953
|
+
hasPoolMaintenance: app === "pool_maintenance_services"
|
|
5954
|
+
},
|
|
5955
|
+
filePath: (0, import_node_server_utils21.getDirectory)(
|
|
5956
|
+
__dirname,
|
|
5957
|
+
"./public/handlebars/user-invite"
|
|
5958
|
+
)
|
|
5959
|
+
});
|
|
5960
|
+
await mailer.sendMail({
|
|
5961
|
+
to: email,
|
|
5962
|
+
subject: "User Invite",
|
|
5963
|
+
html: emailContent,
|
|
5964
|
+
sender: "iService365"
|
|
5965
|
+
});
|
|
5882
5966
|
}
|
|
5883
|
-
const link = `${APP_MAIN}/verify/invitation/${verificationIds[0]}`;
|
|
5884
|
-
const appsSet = new Set(invitedApps);
|
|
5885
|
-
const emailContent = (0, import_node_server_utils21.compileHandlebar)({
|
|
5886
|
-
context: {
|
|
5887
|
-
email,
|
|
5888
|
-
validity: VERIFICATION_USER_INVITE_DURATION,
|
|
5889
|
-
link,
|
|
5890
|
-
hasPropertyManagement: appsSet.has("property_management_agency"),
|
|
5891
|
-
hasSecurity: appsSet.has("security_agency"),
|
|
5892
|
-
hasCleaning: appsSet.has("cleaning_services"),
|
|
5893
|
-
hasMechanical: appsSet.has("mechanical_electrical_services"),
|
|
5894
|
-
hasLandscape: appsSet.has("landscaping_services"),
|
|
5895
|
-
hasPestControl: appsSet.has("pest_control_services"),
|
|
5896
|
-
hasPoolMaintenance: appsSet.has("pool_maintenance_services")
|
|
5897
|
-
},
|
|
5898
|
-
filePath: (0, import_node_server_utils21.getDirectory)(
|
|
5899
|
-
__dirname,
|
|
5900
|
-
"./public/handlebars/user-invite"
|
|
5901
|
-
)
|
|
5902
|
-
});
|
|
5903
|
-
await mailer.sendMail({
|
|
5904
|
-
to: email,
|
|
5905
|
-
subject: "User Invite",
|
|
5906
|
-
html: emailContent,
|
|
5907
|
-
sender: "iService365"
|
|
5908
|
-
});
|
|
5909
5967
|
return verificationIds;
|
|
5910
5968
|
}
|
|
5911
5969
|
async function createSimpleMemberInvite({
|
|
@@ -8375,7 +8433,7 @@ function useVerificationController() {
|
|
|
8375
8433
|
siteId: import_joi16.default.string().hex().optional().allow("", null),
|
|
8376
8434
|
siteName: import_joi16.default.string().optional().allow("", null)
|
|
8377
8435
|
});
|
|
8378
|
-
const { error } = validation.validate(payload);
|
|
8436
|
+
const { error, value } = validation.validate(payload);
|
|
8379
8437
|
if (error) {
|
|
8380
8438
|
import_node_server_utils32.logger.log({
|
|
8381
8439
|
level: "error",
|
|
@@ -8384,15 +8442,17 @@ function useVerificationController() {
|
|
|
8384
8442
|
next(new import_node_server_utils32.BadRequestError(error.message));
|
|
8385
8443
|
return;
|
|
8386
8444
|
}
|
|
8387
|
-
const email = req.body.email ?? "";
|
|
8388
|
-
const app = req.body.app ?? [];
|
|
8389
|
-
const role = req.body.role ?? "";
|
|
8390
|
-
const name = req.body.name ?? "";
|
|
8391
|
-
const org = req.body.org ?? "";
|
|
8392
|
-
const siteId = req.body.siteId ?? "";
|
|
8393
|
-
const siteName = req.body.siteName ?? "";
|
|
8394
8445
|
try {
|
|
8395
|
-
|
|
8446
|
+
const {
|
|
8447
|
+
email,
|
|
8448
|
+
app,
|
|
8449
|
+
role,
|
|
8450
|
+
name,
|
|
8451
|
+
org,
|
|
8452
|
+
siteId,
|
|
8453
|
+
siteName
|
|
8454
|
+
} = value;
|
|
8455
|
+
const verificationIds = await _createSimpleUserInvite({
|
|
8396
8456
|
email,
|
|
8397
8457
|
metadata: {
|
|
8398
8458
|
app,
|
|
@@ -8404,7 +8464,9 @@ function useVerificationController() {
|
|
|
8404
8464
|
}
|
|
8405
8465
|
});
|
|
8406
8466
|
res.status(201).json({
|
|
8407
|
-
message: "Successfully invited user."
|
|
8467
|
+
message: "Successfully invited user.",
|
|
8468
|
+
totalInvites: verificationIds.length,
|
|
8469
|
+
verificationIds
|
|
8408
8470
|
});
|
|
8409
8471
|
return;
|
|
8410
8472
|
} catch (error2) {
|
|
@@ -8860,7 +8922,8 @@ function useOrgController() {
|
|
|
8860
8922
|
getByEmail: _getByEmail,
|
|
8861
8923
|
getAll: _getAll,
|
|
8862
8924
|
add: _add,
|
|
8863
|
-
update: _update
|
|
8925
|
+
update: _update,
|
|
8926
|
+
getOrgsByEmail: _getOrgsByEmail
|
|
8864
8927
|
} = useOrgRepo();
|
|
8865
8928
|
async function add(req, res, next) {
|
|
8866
8929
|
const validation = import_joi18.default.object({
|
|
@@ -9044,6 +9107,30 @@ function useOrgController() {
|
|
|
9044
9107
|
return;
|
|
9045
9108
|
}
|
|
9046
9109
|
}
|
|
9110
|
+
async function getOrgsByEmail(req, res, next) {
|
|
9111
|
+
const validation = import_joi18.default.object({
|
|
9112
|
+
email: import_joi18.default.string().email().required()
|
|
9113
|
+
});
|
|
9114
|
+
const query = {
|
|
9115
|
+
email: req.params.email
|
|
9116
|
+
};
|
|
9117
|
+
const { error } = validation.validate(query);
|
|
9118
|
+
if (error) {
|
|
9119
|
+
import_node_server_utils35.logger.log({ level: "error", message: error.message });
|
|
9120
|
+
next(new import_node_server_utils35.BadRequestError(error.message));
|
|
9121
|
+
return;
|
|
9122
|
+
}
|
|
9123
|
+
const email = req.params.email;
|
|
9124
|
+
try {
|
|
9125
|
+
const data = await _getOrgsByEmail(email);
|
|
9126
|
+
res.json(data);
|
|
9127
|
+
return;
|
|
9128
|
+
} catch (error2) {
|
|
9129
|
+
import_node_server_utils35.logger.log({ level: "error", message: error2.message });
|
|
9130
|
+
next(error2);
|
|
9131
|
+
return;
|
|
9132
|
+
}
|
|
9133
|
+
}
|
|
9047
9134
|
async function update(req, res, next) {
|
|
9048
9135
|
const validation = import_joi18.default.object({
|
|
9049
9136
|
name: import_joi18.default.string().optional(),
|
|
@@ -9077,7 +9164,8 @@ function useOrgController() {
|
|
|
9077
9164
|
getByName,
|
|
9078
9165
|
getById,
|
|
9079
9166
|
getByEmail,
|
|
9080
|
-
update
|
|
9167
|
+
update,
|
|
9168
|
+
getOrgsByEmail
|
|
9081
9169
|
};
|
|
9082
9170
|
}
|
|
9083
9171
|
|
|
@@ -26659,7 +26747,14 @@ function usePersonService() {
|
|
|
26659
26747
|
password: hashedPassword,
|
|
26660
26748
|
name: value.name,
|
|
26661
26749
|
status: value.platform == "mobile" ? "pending" : "active",
|
|
26662
|
-
defaultOrg: value.org?.toString() || ""
|
|
26750
|
+
defaultOrg: value.org?.toString() || "",
|
|
26751
|
+
block: value.block,
|
|
26752
|
+
level: value.level,
|
|
26753
|
+
type: value.type,
|
|
26754
|
+
unitName: value.unitName,
|
|
26755
|
+
contact: value.contact,
|
|
26756
|
+
site: value.site?.toString() || "",
|
|
26757
|
+
unitId: value.unit?.toString() || ""
|
|
26663
26758
|
};
|
|
26664
26759
|
const userId = await addUser(user, session);
|
|
26665
26760
|
value.user = userId.toString();
|
|
@@ -36305,10 +36400,42 @@ function UseAccessManagementRepo() {
|
|
|
36305
36400
|
},
|
|
36306
36401
|
{
|
|
36307
36402
|
$facet: {
|
|
36308
|
-
available_physical: [
|
|
36309
|
-
|
|
36310
|
-
|
|
36311
|
-
|
|
36403
|
+
available_physical: [
|
|
36404
|
+
{
|
|
36405
|
+
$match: {
|
|
36406
|
+
assignedUnit: { $eq: null },
|
|
36407
|
+
type: "NFC" /* NFC */
|
|
36408
|
+
}
|
|
36409
|
+
},
|
|
36410
|
+
{ $count: "count" }
|
|
36411
|
+
],
|
|
36412
|
+
available_non_physical: [
|
|
36413
|
+
{
|
|
36414
|
+
$match: {
|
|
36415
|
+
assignedUnit: { $eq: null },
|
|
36416
|
+
type: "QRCODE" /* QR */
|
|
36417
|
+
}
|
|
36418
|
+
},
|
|
36419
|
+
{ $count: "count" }
|
|
36420
|
+
],
|
|
36421
|
+
assigned_physical: [
|
|
36422
|
+
{
|
|
36423
|
+
$match: {
|
|
36424
|
+
assignedUnit: { $ne: null },
|
|
36425
|
+
type: "NFC" /* NFC */
|
|
36426
|
+
}
|
|
36427
|
+
},
|
|
36428
|
+
{ $count: "count" }
|
|
36429
|
+
],
|
|
36430
|
+
assigned_non_physical: [
|
|
36431
|
+
{
|
|
36432
|
+
$match: {
|
|
36433
|
+
assignedUnit: { $ne: null },
|
|
36434
|
+
type: "QRCODE" /* QR */
|
|
36435
|
+
}
|
|
36436
|
+
},
|
|
36437
|
+
{ $count: "count" }
|
|
36438
|
+
]
|
|
36312
36439
|
}
|
|
36313
36440
|
}
|
|
36314
36441
|
]).toArray();
|
|
@@ -36393,16 +36520,35 @@ function UseAccessManagementRepo() {
|
|
|
36393
36520
|
case terms.length >= 3:
|
|
36394
36521
|
return {
|
|
36395
36522
|
$and: [
|
|
36396
|
-
{
|
|
36397
|
-
|
|
36398
|
-
|
|
36523
|
+
{
|
|
36524
|
+
$expr: { $eq: [{ $toLower: "$name" }, terms[0].toLowerCase()] }
|
|
36525
|
+
},
|
|
36526
|
+
{
|
|
36527
|
+
$expr: {
|
|
36528
|
+
$eq: [{ $toLower: "$level.level" }, terms[1].toLowerCase()]
|
|
36529
|
+
}
|
|
36530
|
+
},
|
|
36531
|
+
{
|
|
36532
|
+
$expr: {
|
|
36533
|
+
$eq: [
|
|
36534
|
+
{ $toLower: "$level.units.name" },
|
|
36535
|
+
getAfterSecondSlash(search)
|
|
36536
|
+
]
|
|
36537
|
+
}
|
|
36538
|
+
}
|
|
36399
36539
|
]
|
|
36400
36540
|
};
|
|
36401
36541
|
case terms.length === 2:
|
|
36402
36542
|
return {
|
|
36403
36543
|
$and: [
|
|
36404
|
-
{
|
|
36405
|
-
|
|
36544
|
+
{
|
|
36545
|
+
$expr: { $eq: [{ $toLower: "$name" }, terms[0].toLowerCase()] }
|
|
36546
|
+
},
|
|
36547
|
+
{
|
|
36548
|
+
$expr: {
|
|
36549
|
+
$eq: [{ $toLower: "$level.level" }, terms[1].toLowerCase()]
|
|
36550
|
+
}
|
|
36551
|
+
}
|
|
36406
36552
|
]
|
|
36407
36553
|
};
|
|
36408
36554
|
default:
|
|
@@ -36430,220 +36576,386 @@ function UseAccessManagementRepo() {
|
|
|
36430
36576
|
site
|
|
36431
36577
|
};
|
|
36432
36578
|
const searchQuery = buildSearchQuery(search);
|
|
36433
|
-
const result = await collectionName("buildings").aggregate(
|
|
36434
|
-
|
|
36435
|
-
|
|
36436
|
-
|
|
36437
|
-
|
|
36438
|
-
|
|
36439
|
-
|
|
36440
|
-
|
|
36441
|
-
|
|
36442
|
-
|
|
36443
|
-
|
|
36444
|
-
|
|
36445
|
-
|
|
36446
|
-
|
|
36447
|
-
|
|
36448
|
-
|
|
36449
|
-
|
|
36450
|
-
|
|
36451
|
-
|
|
36452
|
-
|
|
36453
|
-
|
|
36454
|
-
|
|
36455
|
-
|
|
36456
|
-
|
|
36457
|
-
|
|
36458
|
-
|
|
36459
|
-
|
|
36460
|
-
|
|
36461
|
-
|
|
36462
|
-
|
|
36463
|
-
|
|
36464
|
-
|
|
36465
|
-
|
|
36466
|
-
|
|
36467
|
-
|
|
36468
|
-
|
|
36469
|
-
|
|
36470
|
-
|
|
36471
|
-
|
|
36472
|
-
|
|
36473
|
-
|
|
36474
|
-
|
|
36475
|
-
|
|
36476
|
-
|
|
36477
|
-
|
|
36579
|
+
const result = await collectionName("buildings").aggregate(
|
|
36580
|
+
[
|
|
36581
|
+
// ✅ Match early with index-friendly query
|
|
36582
|
+
{
|
|
36583
|
+
$match: {
|
|
36584
|
+
...defaultQuery,
|
|
36585
|
+
status: { $eq: "active" }
|
|
36586
|
+
}
|
|
36587
|
+
},
|
|
36588
|
+
// ✅ Only project needed fields before heavy lookups
|
|
36589
|
+
{
|
|
36590
|
+
$project: {
|
|
36591
|
+
_id: 1,
|
|
36592
|
+
name: 1,
|
|
36593
|
+
site: 1,
|
|
36594
|
+
block: 1
|
|
36595
|
+
}
|
|
36596
|
+
},
|
|
36597
|
+
// ✅ Use localField/foreignField for better index usage
|
|
36598
|
+
{
|
|
36599
|
+
$lookup: {
|
|
36600
|
+
from: "building-levels",
|
|
36601
|
+
localField: "_id",
|
|
36602
|
+
foreignField: "block",
|
|
36603
|
+
pipeline: [
|
|
36604
|
+
{ $match: { status: { $ne: "deleted" } } },
|
|
36605
|
+
{
|
|
36606
|
+
$lookup: {
|
|
36607
|
+
from: "building-units",
|
|
36608
|
+
localField: "_id",
|
|
36609
|
+
foreignField: "level",
|
|
36610
|
+
pipeline: [
|
|
36611
|
+
{ $match: { status: { $ne: "deleted" }, site } },
|
|
36612
|
+
{ $project: { _id: 1, name: 1 } }
|
|
36613
|
+
],
|
|
36614
|
+
as: "units"
|
|
36615
|
+
}
|
|
36616
|
+
},
|
|
36617
|
+
{
|
|
36618
|
+
$match: { "units.0": { $exists: true } }
|
|
36619
|
+
},
|
|
36620
|
+
{
|
|
36621
|
+
$project: {
|
|
36622
|
+
_id: 1,
|
|
36623
|
+
level: 1,
|
|
36624
|
+
units: 1
|
|
36625
|
+
}
|
|
36478
36626
|
}
|
|
36479
|
-
|
|
36480
|
-
|
|
36481
|
-
|
|
36482
|
-
}
|
|
36483
|
-
|
|
36484
|
-
|
|
36485
|
-
|
|
36486
|
-
|
|
36487
|
-
|
|
36488
|
-
|
|
36489
|
-
|
|
36490
|
-
|
|
36491
|
-
|
|
36492
|
-
|
|
36493
|
-
}
|
|
36494
|
-
|
|
36495
|
-
|
|
36496
|
-
|
|
36497
|
-
|
|
36498
|
-
|
|
36499
|
-
}
|
|
36500
|
-
|
|
36501
|
-
|
|
36502
|
-
|
|
36503
|
-
|
|
36504
|
-
|
|
36505
|
-
|
|
36506
|
-
|
|
36507
|
-
|
|
36508
|
-
|
|
36509
|
-
|
|
36510
|
-
|
|
36511
|
-
|
|
36512
|
-
|
|
36513
|
-
|
|
36514
|
-
|
|
36515
|
-
}
|
|
36516
|
-
|
|
36517
|
-
|
|
36518
|
-
|
|
36519
|
-
|
|
36520
|
-
|
|
36521
|
-
|
|
36522
|
-
|
|
36523
|
-
|
|
36524
|
-
|
|
36525
|
-
|
|
36526
|
-
|
|
36527
|
-
|
|
36528
|
-
|
|
36529
|
-
|
|
36530
|
-
|
|
36531
|
-
|
|
36532
|
-
|
|
36533
|
-
|
|
36627
|
+
],
|
|
36628
|
+
as: "level"
|
|
36629
|
+
}
|
|
36630
|
+
},
|
|
36631
|
+
// ✅ Filter out buildings with no levels early
|
|
36632
|
+
{
|
|
36633
|
+
$match: { "level.0": { $exists: true } }
|
|
36634
|
+
},
|
|
36635
|
+
// ✅ Unwind to flatten the hierarchy
|
|
36636
|
+
{
|
|
36637
|
+
$unwind: {
|
|
36638
|
+
path: "$level",
|
|
36639
|
+
preserveNullAndEmptyArrays: false
|
|
36640
|
+
}
|
|
36641
|
+
},
|
|
36642
|
+
{
|
|
36643
|
+
$unwind: {
|
|
36644
|
+
path: "$level.units",
|
|
36645
|
+
preserveNullAndEmptyArrays: false
|
|
36646
|
+
}
|
|
36647
|
+
},
|
|
36648
|
+
// // Groups by unit _id and keeps only the first occurrence
|
|
36649
|
+
// {
|
|
36650
|
+
// $group: {
|
|
36651
|
+
// _id: "$level.units._id",
|
|
36652
|
+
// doc: { $first: "$$ROOT" },
|
|
36653
|
+
// },
|
|
36654
|
+
// },
|
|
36655
|
+
// {
|
|
36656
|
+
// $replaceRoot: { newRoot: "$doc" },
|
|
36657
|
+
// },
|
|
36658
|
+
// ✅ Apply search filter
|
|
36659
|
+
{
|
|
36660
|
+
$match: {
|
|
36661
|
+
...searchQuery
|
|
36662
|
+
}
|
|
36663
|
+
},
|
|
36664
|
+
{
|
|
36665
|
+
$facet: {
|
|
36666
|
+
totalCount: [{ $count: "count" }],
|
|
36667
|
+
items: [
|
|
36668
|
+
// ✅ Sort BEFORE skip/limit for correct pagination
|
|
36669
|
+
{ $skip: page * limit },
|
|
36670
|
+
{ $limit: limit },
|
|
36671
|
+
// ✅ Users lookup - optimized with index hint
|
|
36672
|
+
{
|
|
36673
|
+
$lookup: {
|
|
36674
|
+
from: "users",
|
|
36675
|
+
let: { unit: "$level.units._id" },
|
|
36676
|
+
pipeline: [
|
|
36677
|
+
{
|
|
36678
|
+
$match: {
|
|
36679
|
+
$expr: { $eq: ["$unitNumber", "$$unit"] },
|
|
36680
|
+
residentType: "House/Unit Owner"
|
|
36681
|
+
}
|
|
36682
|
+
},
|
|
36683
|
+
{ $limit: 1 },
|
|
36684
|
+
{ $project: { _id: 1, givenName: 1, surname: 1 } }
|
|
36685
|
+
],
|
|
36686
|
+
as: "unitOwner"
|
|
36687
|
+
}
|
|
36688
|
+
},
|
|
36689
|
+
// ✅ Access card lookup - optimized query
|
|
36690
|
+
{
|
|
36691
|
+
$lookup: {
|
|
36692
|
+
from: "access-cards",
|
|
36693
|
+
let: { unit: "$level.units._id" },
|
|
36694
|
+
pipeline: [
|
|
36695
|
+
{
|
|
36696
|
+
$match: {
|
|
36697
|
+
$expr: {
|
|
36698
|
+
$in: [
|
|
36699
|
+
"$$unit",
|
|
36700
|
+
{
|
|
36701
|
+
$cond: [
|
|
36702
|
+
{ $isArray: "$assignedUnit" },
|
|
36703
|
+
"$assignedUnit",
|
|
36704
|
+
["$assignedUnit"]
|
|
36705
|
+
]
|
|
36706
|
+
}
|
|
36707
|
+
]
|
|
36708
|
+
},
|
|
36709
|
+
userType
|
|
36710
|
+
}
|
|
36711
|
+
},
|
|
36712
|
+
{
|
|
36713
|
+
$project: {
|
|
36714
|
+
_id: 1,
|
|
36715
|
+
userId: 1,
|
|
36716
|
+
type: 1,
|
|
36717
|
+
cardNo: 1,
|
|
36718
|
+
isActivated: 1,
|
|
36719
|
+
replacementStatus: 1
|
|
36720
|
+
}
|
|
36721
|
+
}
|
|
36722
|
+
],
|
|
36723
|
+
as: "accessCards"
|
|
36724
|
+
}
|
|
36725
|
+
},
|
|
36726
|
+
// ✅ Compute all card categorization and counts in ONE stage
|
|
36727
|
+
{
|
|
36728
|
+
$addFields: {
|
|
36729
|
+
f_Available: {
|
|
36730
|
+
$filter: {
|
|
36731
|
+
input: "$accessCards",
|
|
36732
|
+
as: "card",
|
|
36733
|
+
cond: {
|
|
36734
|
+
$and: [
|
|
36735
|
+
{ $eq: ["$$card.userId", null] },
|
|
36736
|
+
{ $eq: ["$$card.isActivated", true] }
|
|
36737
|
+
]
|
|
36738
|
+
}
|
|
36534
36739
|
}
|
|
36535
36740
|
},
|
|
36536
|
-
|
|
36537
|
-
|
|
36538
|
-
|
|
36539
|
-
|
|
36540
|
-
|
|
36541
|
-
|
|
36542
|
-
|
|
36543
|
-
|
|
36544
|
-
$lookup: {
|
|
36545
|
-
from: "access-cards",
|
|
36546
|
-
let: { unit: "$level.units._id" },
|
|
36547
|
-
pipeline: [
|
|
36548
|
-
{
|
|
36549
|
-
$match: {
|
|
36550
|
-
$expr: {
|
|
36551
|
-
$in: [
|
|
36552
|
-
"$$unit",
|
|
36553
|
-
{ $cond: [{ $isArray: "$assignedUnit" }, "$assignedUnit", ["$assignedUnit"]] }
|
|
36741
|
+
f_Assigned: {
|
|
36742
|
+
$filter: {
|
|
36743
|
+
input: "$accessCards",
|
|
36744
|
+
as: "card",
|
|
36745
|
+
cond: {
|
|
36746
|
+
$and: [
|
|
36747
|
+
{ $ne: ["$$card.userId", null] },
|
|
36748
|
+
{ $eq: ["$$card.isActivated", true] }
|
|
36554
36749
|
]
|
|
36555
|
-
}
|
|
36556
|
-
userType
|
|
36750
|
+
}
|
|
36557
36751
|
}
|
|
36558
36752
|
},
|
|
36559
|
-
|
|
36560
|
-
|
|
36561
|
-
|
|
36562
|
-
|
|
36563
|
-
|
|
36564
|
-
|
|
36565
|
-
|
|
36566
|
-
|
|
36567
|
-
|
|
36568
|
-
|
|
36569
|
-
|
|
36570
|
-
|
|
36571
|
-
|
|
36572
|
-
|
|
36573
|
-
|
|
36574
|
-
|
|
36575
|
-
|
|
36576
|
-
|
|
36577
|
-
|
|
36578
|
-
|
|
36579
|
-
|
|
36580
|
-
|
|
36581
|
-
|
|
36582
|
-
$filter: {
|
|
36583
|
-
input: "$accessCards",
|
|
36584
|
-
as: "card",
|
|
36585
|
-
cond: { $and: [{ $eq: ["$$card.isActivated", false] }, { $ne: ["$$card.replacementStatus", null] }] }
|
|
36586
|
-
}
|
|
36587
|
-
},
|
|
36588
|
-
f_deleted: {
|
|
36589
|
-
$filter: {
|
|
36590
|
-
input: "$accessCards",
|
|
36591
|
-
as: "card",
|
|
36592
|
-
cond: { $and: [{ $eq: ["$$card.isActivated", false] }, { $eq: ["$$card.replacementStatus", null] }] }
|
|
36753
|
+
f_replaced: {
|
|
36754
|
+
$filter: {
|
|
36755
|
+
input: "$accessCards",
|
|
36756
|
+
as: "card",
|
|
36757
|
+
cond: {
|
|
36758
|
+
$and: [
|
|
36759
|
+
{ $eq: ["$$card.isActivated", false] },
|
|
36760
|
+
{ $ne: ["$$card.replacementStatus", null] }
|
|
36761
|
+
]
|
|
36762
|
+
}
|
|
36763
|
+
}
|
|
36764
|
+
},
|
|
36765
|
+
f_deleted: {
|
|
36766
|
+
$filter: {
|
|
36767
|
+
input: "$accessCards",
|
|
36768
|
+
as: "card",
|
|
36769
|
+
cond: {
|
|
36770
|
+
$and: [
|
|
36771
|
+
{ $eq: ["$$card.isActivated", false] },
|
|
36772
|
+
{ $eq: ["$$card.replacementStatus", null] }
|
|
36773
|
+
]
|
|
36774
|
+
}
|
|
36775
|
+
}
|
|
36593
36776
|
}
|
|
36594
36777
|
}
|
|
36595
|
-
}
|
|
36596
|
-
|
|
36597
|
-
|
|
36598
|
-
|
|
36599
|
-
|
|
36600
|
-
|
|
36601
|
-
|
|
36602
|
-
|
|
36603
|
-
|
|
36604
|
-
|
|
36605
|
-
unit_owner: { $arrayElemAt: ["$unitOwner", 0] },
|
|
36606
|
-
available: {
|
|
36607
|
-
physical: { $filter: { input: "$f_Available", as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } },
|
|
36608
|
-
non_physical: { $filter: { input: "$f_Available", as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } }
|
|
36609
|
-
},
|
|
36610
|
-
assigned: {
|
|
36611
|
-
physical: { $filter: { input: "$f_Assigned", as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } },
|
|
36612
|
-
non_physical: { $filter: { input: "$f_Assigned", as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } }
|
|
36613
|
-
},
|
|
36614
|
-
cardCounts: {
|
|
36778
|
+
},
|
|
36779
|
+
// ✅ Final projection with all computed fields
|
|
36780
|
+
{
|
|
36781
|
+
$project: {
|
|
36782
|
+
_id: "$level.units._id",
|
|
36783
|
+
name: "$level.units.name",
|
|
36784
|
+
level: { _id: "$level._id", level: "$level.level" },
|
|
36785
|
+
block: { _id: "$_id", name: "$name", block: "$block" },
|
|
36786
|
+
site: "$site",
|
|
36787
|
+
unit_owner: { $arrayElemAt: ["$unitOwner", 0] },
|
|
36615
36788
|
available: {
|
|
36616
|
-
physical: {
|
|
36617
|
-
|
|
36789
|
+
physical: {
|
|
36790
|
+
$filter: {
|
|
36791
|
+
input: "$f_Available",
|
|
36792
|
+
as: "c",
|
|
36793
|
+
cond: { $eq: ["$$c.type", "NFC" /* NFC */] }
|
|
36794
|
+
}
|
|
36795
|
+
},
|
|
36796
|
+
non_physical: {
|
|
36797
|
+
$filter: {
|
|
36798
|
+
input: "$f_Available",
|
|
36799
|
+
as: "c",
|
|
36800
|
+
cond: { $eq: ["$$c.type", "QRCODE" /* QR */] }
|
|
36801
|
+
}
|
|
36802
|
+
}
|
|
36618
36803
|
},
|
|
36619
36804
|
assigned: {
|
|
36620
|
-
physical: {
|
|
36621
|
-
|
|
36805
|
+
physical: {
|
|
36806
|
+
$filter: {
|
|
36807
|
+
input: "$f_Assigned",
|
|
36808
|
+
as: "c",
|
|
36809
|
+
cond: { $eq: ["$$c.type", "NFC" /* NFC */] }
|
|
36810
|
+
}
|
|
36811
|
+
},
|
|
36812
|
+
non_physical: {
|
|
36813
|
+
$filter: {
|
|
36814
|
+
input: "$f_Assigned",
|
|
36815
|
+
as: "c",
|
|
36816
|
+
cond: { $eq: ["$$c.type", "QRCODE" /* QR */] }
|
|
36817
|
+
}
|
|
36818
|
+
}
|
|
36819
|
+
},
|
|
36820
|
+
cardCounts: {
|
|
36821
|
+
available: {
|
|
36822
|
+
physical: {
|
|
36823
|
+
$size: {
|
|
36824
|
+
$filter: {
|
|
36825
|
+
input: { $ifNull: ["$f_Available", []] },
|
|
36826
|
+
as: "c",
|
|
36827
|
+
cond: {
|
|
36828
|
+
$eq: ["$$c.type", "NFC" /* NFC */]
|
|
36829
|
+
}
|
|
36830
|
+
}
|
|
36831
|
+
}
|
|
36832
|
+
},
|
|
36833
|
+
non_physical: {
|
|
36834
|
+
$size: {
|
|
36835
|
+
$filter: {
|
|
36836
|
+
input: { $ifNull: ["$f_Available", []] },
|
|
36837
|
+
as: "c",
|
|
36838
|
+
cond: {
|
|
36839
|
+
$eq: ["$$c.type", "QRCODE" /* QR */]
|
|
36840
|
+
}
|
|
36841
|
+
}
|
|
36842
|
+
}
|
|
36843
|
+
}
|
|
36844
|
+
},
|
|
36845
|
+
assigned: {
|
|
36846
|
+
physical: {
|
|
36847
|
+
$size: {
|
|
36848
|
+
$filter: {
|
|
36849
|
+
input: { $ifNull: ["$f_Assigned", []] },
|
|
36850
|
+
as: "c",
|
|
36851
|
+
cond: {
|
|
36852
|
+
$eq: ["$$c.type", "NFC" /* NFC */]
|
|
36853
|
+
}
|
|
36854
|
+
}
|
|
36855
|
+
}
|
|
36856
|
+
},
|
|
36857
|
+
non_physical: {
|
|
36858
|
+
$size: {
|
|
36859
|
+
$filter: {
|
|
36860
|
+
input: { $ifNull: ["$f_Assigned", []] },
|
|
36861
|
+
as: "c",
|
|
36862
|
+
cond: {
|
|
36863
|
+
$eq: ["$$c.type", "QRCODE" /* QR */]
|
|
36864
|
+
}
|
|
36865
|
+
}
|
|
36866
|
+
}
|
|
36867
|
+
}
|
|
36868
|
+
}
|
|
36869
|
+
},
|
|
36870
|
+
replaced: {
|
|
36871
|
+
physical: {
|
|
36872
|
+
$filter: {
|
|
36873
|
+
input: "$f_replaced",
|
|
36874
|
+
as: "c",
|
|
36875
|
+
cond: { $eq: ["$$c.type", "NFC" /* NFC */] }
|
|
36876
|
+
}
|
|
36877
|
+
},
|
|
36878
|
+
non_physical: {
|
|
36879
|
+
$filter: {
|
|
36880
|
+
input: "$f_replaced",
|
|
36881
|
+
as: "c",
|
|
36882
|
+
cond: { $eq: ["$$c.type", "QRCODE" /* QR */] }
|
|
36883
|
+
}
|
|
36884
|
+
}
|
|
36885
|
+
},
|
|
36886
|
+
deleted: {
|
|
36887
|
+
physical: {
|
|
36888
|
+
$filter: {
|
|
36889
|
+
input: "$f_deleted",
|
|
36890
|
+
as: "c",
|
|
36891
|
+
cond: { $eq: ["$$c.type", "NFC" /* NFC */] }
|
|
36892
|
+
}
|
|
36893
|
+
},
|
|
36894
|
+
non_physical: {
|
|
36895
|
+
$filter: {
|
|
36896
|
+
input: "$f_deleted",
|
|
36897
|
+
as: "c",
|
|
36898
|
+
cond: { $eq: ["$$c.type", "QRCODE" /* QR */] }
|
|
36899
|
+
}
|
|
36900
|
+
}
|
|
36901
|
+
},
|
|
36902
|
+
totalCardCount: {
|
|
36903
|
+
$add: [
|
|
36904
|
+
{
|
|
36905
|
+
$size: {
|
|
36906
|
+
$filter: {
|
|
36907
|
+
input: { $ifNull: ["$f_Available", []] },
|
|
36908
|
+
as: "c",
|
|
36909
|
+
cond: {
|
|
36910
|
+
$eq: ["$$c.type", "NFC" /* NFC */]
|
|
36911
|
+
}
|
|
36912
|
+
}
|
|
36913
|
+
}
|
|
36914
|
+
},
|
|
36915
|
+
{
|
|
36916
|
+
$size: {
|
|
36917
|
+
$filter: {
|
|
36918
|
+
input: { $ifNull: ["$f_Available", []] },
|
|
36919
|
+
as: "c",
|
|
36920
|
+
cond: {
|
|
36921
|
+
$eq: ["$$c.type", "QRCODE" /* QR */]
|
|
36922
|
+
}
|
|
36923
|
+
}
|
|
36924
|
+
}
|
|
36925
|
+
},
|
|
36926
|
+
{
|
|
36927
|
+
$size: {
|
|
36928
|
+
$filter: {
|
|
36929
|
+
input: { $ifNull: ["$f_Assigned", []] },
|
|
36930
|
+
as: "c",
|
|
36931
|
+
cond: {
|
|
36932
|
+
$eq: ["$$c.type", "NFC" /* NFC */]
|
|
36933
|
+
}
|
|
36934
|
+
}
|
|
36935
|
+
}
|
|
36936
|
+
},
|
|
36937
|
+
{
|
|
36938
|
+
$size: {
|
|
36939
|
+
$filter: {
|
|
36940
|
+
input: { $ifNull: ["$f_Assigned", []] },
|
|
36941
|
+
as: "c",
|
|
36942
|
+
cond: {
|
|
36943
|
+
$eq: ["$$c.type", "QRCODE" /* QR */]
|
|
36944
|
+
}
|
|
36945
|
+
}
|
|
36946
|
+
}
|
|
36947
|
+
}
|
|
36948
|
+
]
|
|
36622
36949
|
}
|
|
36623
|
-
},
|
|
36624
|
-
replaced: {
|
|
36625
|
-
physical: { $filter: { input: "$f_replaced", as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } },
|
|
36626
|
-
non_physical: { $filter: { input: "$f_replaced", as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } }
|
|
36627
|
-
},
|
|
36628
|
-
deleted: {
|
|
36629
|
-
physical: { $filter: { input: "$f_deleted", as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } },
|
|
36630
|
-
non_physical: { $filter: { input: "$f_deleted", as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } }
|
|
36631
|
-
},
|
|
36632
|
-
totalCardCount: {
|
|
36633
|
-
$add: [
|
|
36634
|
-
{ $size: { $filter: { input: { $ifNull: ["$f_Available", []] }, as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } } },
|
|
36635
|
-
{ $size: { $filter: { input: { $ifNull: ["$f_Available", []] }, as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } } },
|
|
36636
|
-
{ $size: { $filter: { input: { $ifNull: ["$f_Assigned", []] }, as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } } },
|
|
36637
|
-
{ $size: { $filter: { input: { $ifNull: ["$f_Assigned", []] }, as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } } }
|
|
36638
|
-
]
|
|
36639
36950
|
}
|
|
36640
|
-
}
|
|
36641
|
-
|
|
36642
|
-
|
|
36643
|
-
|
|
36951
|
+
},
|
|
36952
|
+
{ $sort: { totalCardCount: -1 } }
|
|
36953
|
+
]
|
|
36954
|
+
}
|
|
36644
36955
|
}
|
|
36645
|
-
|
|
36646
|
-
|
|
36956
|
+
],
|
|
36957
|
+
{ allowDiskUse: true }
|
|
36958
|
+
).toArray();
|
|
36647
36959
|
const totalCount = result[0]?.totalCount?.[0]?.count ?? 0;
|
|
36648
36960
|
const items = result[0]?.items ?? [];
|
|
36649
36961
|
const paginatedResult = (0, import_node_server_utils154.paginate)(items, page, limit, totalCount);
|
|
@@ -36662,157 +36974,162 @@ function UseAccessManagementRepo() {
|
|
|
36662
36974
|
site: { $in: [site] }
|
|
36663
36975
|
};
|
|
36664
36976
|
const searchQuery = buildSearchQuery(search);
|
|
36665
|
-
const result = await collectionName("buildings").aggregate(
|
|
36666
|
-
|
|
36667
|
-
|
|
36668
|
-
|
|
36669
|
-
|
|
36670
|
-
|
|
36671
|
-
|
|
36672
|
-
|
|
36673
|
-
|
|
36674
|
-
|
|
36675
|
-
|
|
36676
|
-
|
|
36677
|
-
|
|
36678
|
-
|
|
36679
|
-
|
|
36680
|
-
|
|
36681
|
-
|
|
36682
|
-
|
|
36683
|
-
|
|
36684
|
-
|
|
36685
|
-
|
|
36686
|
-
|
|
36687
|
-
|
|
36688
|
-
|
|
36689
|
-
|
|
36690
|
-
|
|
36691
|
-
|
|
36692
|
-
|
|
36693
|
-
|
|
36694
|
-
|
|
36695
|
-
|
|
36696
|
-
|
|
36697
|
-
|
|
36698
|
-
|
|
36699
|
-
|
|
36700
|
-
|
|
36701
|
-
|
|
36702
|
-
|
|
36703
|
-
|
|
36704
|
-
|
|
36705
|
-
|
|
36706
|
-
|
|
36707
|
-
|
|
36708
|
-
|
|
36709
|
-
|
|
36710
|
-
|
|
36711
|
-
|
|
36712
|
-
|
|
36713
|
-
|
|
36714
|
-
|
|
36715
|
-
|
|
36716
|
-
|
|
36717
|
-
|
|
36718
|
-
$
|
|
36719
|
-
|
|
36720
|
-
|
|
36721
|
-
|
|
36722
|
-
|
|
36723
|
-
|
|
36724
|
-
|
|
36977
|
+
const result = await collectionName("buildings").aggregate(
|
|
36978
|
+
[
|
|
36979
|
+
// ✅ Match early with index-friendly query
|
|
36980
|
+
{
|
|
36981
|
+
$match: {
|
|
36982
|
+
...query,
|
|
36983
|
+
status: { $ne: "deleted" }
|
|
36984
|
+
}
|
|
36985
|
+
},
|
|
36986
|
+
// ✅ Only project needed fields before heavy lookups
|
|
36987
|
+
{
|
|
36988
|
+
$project: {
|
|
36989
|
+
_id: 1,
|
|
36990
|
+
name: 1,
|
|
36991
|
+
site: 1
|
|
36992
|
+
}
|
|
36993
|
+
},
|
|
36994
|
+
// ✅ Use localField/foreignField for better index usage
|
|
36995
|
+
{
|
|
36996
|
+
$lookup: {
|
|
36997
|
+
from: "building-levels",
|
|
36998
|
+
localField: "_id",
|
|
36999
|
+
foreignField: "block",
|
|
37000
|
+
pipeline: [
|
|
37001
|
+
{ $match: { status: { $ne: "deleted" } } },
|
|
37002
|
+
{
|
|
37003
|
+
$lookup: {
|
|
37004
|
+
from: "building-units",
|
|
37005
|
+
localField: "_id",
|
|
37006
|
+
foreignField: "level",
|
|
37007
|
+
pipeline: [
|
|
37008
|
+
{ $match: { status: { $ne: "deleted" } } },
|
|
37009
|
+
{ $project: { _id: 1, name: 1 } },
|
|
37010
|
+
{
|
|
37011
|
+
$lookup: {
|
|
37012
|
+
from: "access-cards",
|
|
37013
|
+
localField: "_id",
|
|
37014
|
+
foreignField: "assignedUnit",
|
|
37015
|
+
pipeline: [
|
|
37016
|
+
{
|
|
37017
|
+
$match: {
|
|
37018
|
+
isActivated: true,
|
|
37019
|
+
userType,
|
|
37020
|
+
type
|
|
37021
|
+
}
|
|
37022
|
+
},
|
|
37023
|
+
{
|
|
37024
|
+
$group: {
|
|
37025
|
+
_id: null,
|
|
37026
|
+
accessLevels: { $addToSet: "$accessLevel" },
|
|
37027
|
+
liftAccessLevels: {
|
|
37028
|
+
$addToSet: "$liftAccessLevel"
|
|
37029
|
+
},
|
|
37030
|
+
doorNames: { $addToSet: "$doorName" },
|
|
37031
|
+
liftNames: { $addToSet: "$liftName" },
|
|
37032
|
+
cards: {
|
|
37033
|
+
$push: {
|
|
37034
|
+
_id: "$_id",
|
|
37035
|
+
cardNo: "$cardNo",
|
|
37036
|
+
accessLevel: "$accessLevel",
|
|
37037
|
+
liftAccessLevel: "$liftAccessLevel",
|
|
37038
|
+
doorName: "$doorName",
|
|
37039
|
+
liftName: "$liftName"
|
|
37040
|
+
}
|
|
36725
37041
|
}
|
|
36726
37042
|
}
|
|
37043
|
+
},
|
|
37044
|
+
{
|
|
37045
|
+
$project: {
|
|
37046
|
+
_id: 0,
|
|
37047
|
+
accessCardCount: {
|
|
37048
|
+
$size: "$cards"
|
|
37049
|
+
},
|
|
37050
|
+
accessLevels: 1,
|
|
37051
|
+
liftAccessLevels: 1,
|
|
37052
|
+
doorNames: 1,
|
|
37053
|
+
liftNames: 1
|
|
37054
|
+
}
|
|
36727
37055
|
}
|
|
36728
|
-
|
|
36729
|
-
|
|
36730
|
-
|
|
36731
|
-
|
|
36732
|
-
|
|
36733
|
-
|
|
36734
|
-
|
|
36735
|
-
|
|
36736
|
-
liftAccessLevels: 1,
|
|
36737
|
-
doorNames: 1,
|
|
36738
|
-
liftNames: 1
|
|
36739
|
-
}
|
|
36740
|
-
}
|
|
36741
|
-
],
|
|
36742
|
-
as: "fAccessCards"
|
|
36743
|
-
}
|
|
36744
|
-
},
|
|
36745
|
-
{
|
|
36746
|
-
$match: {
|
|
36747
|
-
"fAccessCards.0": { $exists: true }
|
|
37056
|
+
],
|
|
37057
|
+
as: "fAccessCards"
|
|
37058
|
+
}
|
|
37059
|
+
},
|
|
37060
|
+
{
|
|
37061
|
+
$match: {
|
|
37062
|
+
"fAccessCards.0": { $exists: true }
|
|
37063
|
+
}
|
|
36748
37064
|
}
|
|
36749
|
-
|
|
36750
|
-
|
|
36751
|
-
|
|
36752
|
-
}
|
|
36753
|
-
|
|
36754
|
-
|
|
36755
|
-
|
|
36756
|
-
|
|
36757
|
-
|
|
36758
|
-
|
|
36759
|
-
|
|
36760
|
-
|
|
36761
|
-
|
|
37065
|
+
],
|
|
37066
|
+
as: "units"
|
|
37067
|
+
}
|
|
37068
|
+
},
|
|
37069
|
+
{
|
|
37070
|
+
$match: { "units.0": { $exists: true } }
|
|
37071
|
+
},
|
|
37072
|
+
{
|
|
37073
|
+
$project: {
|
|
37074
|
+
_id: 1,
|
|
37075
|
+
level: 1,
|
|
37076
|
+
units: 1
|
|
37077
|
+
}
|
|
36762
37078
|
}
|
|
36763
|
-
|
|
36764
|
-
|
|
36765
|
-
|
|
36766
|
-
}
|
|
36767
|
-
|
|
36768
|
-
|
|
36769
|
-
|
|
36770
|
-
|
|
36771
|
-
|
|
36772
|
-
|
|
36773
|
-
|
|
36774
|
-
|
|
36775
|
-
|
|
36776
|
-
|
|
36777
|
-
}
|
|
36778
|
-
|
|
36779
|
-
|
|
36780
|
-
|
|
36781
|
-
|
|
36782
|
-
|
|
36783
|
-
}
|
|
36784
|
-
|
|
36785
|
-
|
|
36786
|
-
|
|
36787
|
-
|
|
36788
|
-
|
|
36789
|
-
}
|
|
36790
|
-
|
|
36791
|
-
|
|
36792
|
-
|
|
36793
|
-
|
|
36794
|
-
|
|
36795
|
-
|
|
36796
|
-
}
|
|
36797
|
-
|
|
36798
|
-
|
|
36799
|
-
|
|
36800
|
-
|
|
36801
|
-
|
|
36802
|
-
|
|
36803
|
-
|
|
36804
|
-
|
|
36805
|
-
}
|
|
36806
|
-
|
|
36807
|
-
|
|
36808
|
-
|
|
36809
|
-
|
|
36810
|
-
|
|
36811
|
-
|
|
36812
|
-
|
|
37079
|
+
],
|
|
37080
|
+
as: "level"
|
|
37081
|
+
}
|
|
37082
|
+
},
|
|
37083
|
+
// ✅ Filter out buildings with no levels early
|
|
37084
|
+
{
|
|
37085
|
+
$match: { "level.0": { $exists: true } }
|
|
37086
|
+
},
|
|
37087
|
+
// ✅ Unwind to flatten the hierarchy
|
|
37088
|
+
{
|
|
37089
|
+
$unwind: {
|
|
37090
|
+
path: "$level",
|
|
37091
|
+
preserveNullAndEmptyArrays: false
|
|
37092
|
+
}
|
|
37093
|
+
},
|
|
37094
|
+
{
|
|
37095
|
+
$unwind: {
|
|
37096
|
+
path: "$level.units",
|
|
37097
|
+
preserveNullAndEmptyArrays: false
|
|
37098
|
+
}
|
|
37099
|
+
},
|
|
37100
|
+
{
|
|
37101
|
+
$unwind: {
|
|
37102
|
+
path: "$level.units.fAccessCards",
|
|
37103
|
+
preserveNullAndEmptyArrays: false
|
|
37104
|
+
}
|
|
37105
|
+
},
|
|
37106
|
+
// // Groups by unit _id and keeps only the first occurrence
|
|
37107
|
+
{
|
|
37108
|
+
$group: {
|
|
37109
|
+
_id: "$level.units._id",
|
|
37110
|
+
doc: { $first: "$$ROOT" }
|
|
37111
|
+
}
|
|
37112
|
+
},
|
|
37113
|
+
{
|
|
37114
|
+
$replaceRoot: { newRoot: "$doc" }
|
|
37115
|
+
},
|
|
37116
|
+
// ✅ Apply search filter
|
|
37117
|
+
{
|
|
37118
|
+
$match: {
|
|
37119
|
+
...searchQuery
|
|
37120
|
+
}
|
|
37121
|
+
},
|
|
37122
|
+
{
|
|
37123
|
+
$project: {
|
|
37124
|
+
name: 1,
|
|
37125
|
+
"level.level": 1,
|
|
37126
|
+
"level.units.name": 1,
|
|
37127
|
+
"level.units.fAccessCards": 1
|
|
37128
|
+
}
|
|
36813
37129
|
}
|
|
36814
|
-
|
|
36815
|
-
|
|
37130
|
+
],
|
|
37131
|
+
{ allowDiskUse: true }
|
|
37132
|
+
).toArray();
|
|
36816
37133
|
return result;
|
|
36817
37134
|
} catch (error) {
|
|
36818
37135
|
throw new Error(error.message);
|
|
@@ -36823,8 +37140,12 @@ function UseAccessManagementRepo() {
|
|
|
36823
37140
|
try {
|
|
36824
37141
|
session?.startTransaction();
|
|
36825
37142
|
const { userId, cardId, site } = params;
|
|
36826
|
-
const allUserId = await Promise.all(
|
|
36827
|
-
|
|
37143
|
+
const allUserId = await Promise.all(
|
|
37144
|
+
userId.map(async (id) => new import_mongodb90.ObjectId(id))
|
|
37145
|
+
);
|
|
37146
|
+
const allCardId = await Promise.all(
|
|
37147
|
+
cardId.map(async (id) => new import_mongodb90.ObjectId(id))
|
|
37148
|
+
);
|
|
36828
37149
|
const siteId = new import_mongodb90.ObjectId(site);
|
|
36829
37150
|
const result = await collection().updateMany(
|
|
36830
37151
|
{
|
|
@@ -36867,16 +37188,19 @@ function UseAccessManagementRepo() {
|
|
|
36867
37188
|
liftAccessLevel,
|
|
36868
37189
|
isActivated: true
|
|
36869
37190
|
};
|
|
36870
|
-
const result = await collection().aggregate(
|
|
36871
|
-
|
|
36872
|
-
|
|
36873
|
-
|
|
36874
|
-
|
|
36875
|
-
|
|
36876
|
-
|
|
37191
|
+
const result = await collection().aggregate(
|
|
37192
|
+
[
|
|
37193
|
+
{
|
|
37194
|
+
$match: query
|
|
37195
|
+
},
|
|
37196
|
+
{
|
|
37197
|
+
$facet: {
|
|
37198
|
+
counts: [{ $count: "count" }]
|
|
37199
|
+
}
|
|
36877
37200
|
}
|
|
36878
|
-
|
|
36879
|
-
|
|
37201
|
+
],
|
|
37202
|
+
{ allowDiskUse: true }
|
|
37203
|
+
).toArray();
|
|
36880
37204
|
return result;
|
|
36881
37205
|
} catch (error) {
|
|
36882
37206
|
throw new Error(error.message);
|
|
@@ -36910,7 +37234,9 @@ function UseAccessManagementRepo() {
|
|
|
36910
37234
|
availableCardNo.push(num);
|
|
36911
37235
|
num++;
|
|
36912
37236
|
}
|
|
36913
|
-
const cardNumbers = availableCardNo.map(
|
|
37237
|
+
const cardNumbers = availableCardNo.map(
|
|
37238
|
+
(no) => no.toString().padStart(10, "0")
|
|
37239
|
+
);
|
|
36914
37240
|
const accessCards = [];
|
|
36915
37241
|
const convertedUnits = unit.map((obj) => new import_mongodb90.ObjectId(obj));
|
|
36916
37242
|
for (let j = 0; j < (unit.length > 0 ? unit.length : quantity); j++) {
|
|
@@ -36970,10 +37296,18 @@ function UseAccessManagementRepo() {
|
|
|
36970
37296
|
liftAccessEndDate: formatEntryPassDate(item.liftAccessEndDate) || "19770510",
|
|
36971
37297
|
accessGroup: ag
|
|
36972
37298
|
};
|
|
36973
|
-
return readTemplate(
|
|
37299
|
+
return readTemplate(
|
|
37300
|
+
`${item.accessLevel !== null ? "add-card" : "add-card-lift"}`,
|
|
37301
|
+
{ ...command }
|
|
37302
|
+
);
|
|
36974
37303
|
}).flat();
|
|
36975
|
-
const response = await sendCommand(
|
|
36976
|
-
|
|
37304
|
+
const response = await sendCommand(
|
|
37305
|
+
commands.join("").toString(),
|
|
37306
|
+
params.acm_url
|
|
37307
|
+
);
|
|
37308
|
+
const result = await (0, import_xml2js2.parseStringPromise)(response, {
|
|
37309
|
+
explicitArray: false
|
|
37310
|
+
});
|
|
36977
37311
|
if (result && result.RESULT.$.STCODE !== "0") {
|
|
36978
37312
|
throw new Error("Command failed, server error.");
|
|
36979
37313
|
}
|
|
@@ -37007,7 +37341,11 @@ function UseAccessManagementRepo() {
|
|
|
37007
37341
|
} else {
|
|
37008
37342
|
updateFields.isActivated = true;
|
|
37009
37343
|
}
|
|
37010
|
-
const res = await collection().updateOne(
|
|
37344
|
+
const res = await collection().updateOne(
|
|
37345
|
+
{ _id: card._id },
|
|
37346
|
+
{ $set: updateFields },
|
|
37347
|
+
{ session }
|
|
37348
|
+
);
|
|
37011
37349
|
results.push({ nfcId: nfc._id, modifiedCount: res.modifiedCount });
|
|
37012
37350
|
}
|
|
37013
37351
|
}
|
|
@@ -37034,8 +37372,20 @@ function UseAccessManagementRepo() {
|
|
|
37034
37372
|
assignedUnit: null,
|
|
37035
37373
|
userId: null,
|
|
37036
37374
|
$or: [
|
|
37037
|
-
{
|
|
37038
|
-
|
|
37375
|
+
{
|
|
37376
|
+
$and: [
|
|
37377
|
+
{ doorName: { $ne: null } },
|
|
37378
|
+
{ doorName: { $ne: "" } },
|
|
37379
|
+
{ accessLevel: { $ne: null } }
|
|
37380
|
+
]
|
|
37381
|
+
},
|
|
37382
|
+
{
|
|
37383
|
+
$and: [
|
|
37384
|
+
{ liftName: { $ne: null } },
|
|
37385
|
+
{ liftName: { $ne: "" } },
|
|
37386
|
+
{ liftAccessLevel: { $ne: null } }
|
|
37387
|
+
]
|
|
37388
|
+
}
|
|
37039
37389
|
]
|
|
37040
37390
|
}
|
|
37041
37391
|
},
|
|
@@ -37049,7 +37399,13 @@ function UseAccessManagementRepo() {
|
|
|
37049
37399
|
accessLevels: {
|
|
37050
37400
|
$addToSet: {
|
|
37051
37401
|
$cond: [
|
|
37052
|
-
{
|
|
37402
|
+
{
|
|
37403
|
+
$and: [
|
|
37404
|
+
{ $ne: ["$doorName", null] },
|
|
37405
|
+
{ $ne: ["$doorName", ""] },
|
|
37406
|
+
{ $ne: ["$accessLevel", null] }
|
|
37407
|
+
]
|
|
37408
|
+
},
|
|
37053
37409
|
{ name: "$doorName", no: "$accessLevel" },
|
|
37054
37410
|
"$$REMOVE"
|
|
37055
37411
|
]
|
|
@@ -37058,7 +37414,13 @@ function UseAccessManagementRepo() {
|
|
|
37058
37414
|
liftAccessLevels: {
|
|
37059
37415
|
$addToSet: {
|
|
37060
37416
|
$cond: [
|
|
37061
|
-
{
|
|
37417
|
+
{
|
|
37418
|
+
$and: [
|
|
37419
|
+
{ $ne: ["$liftName", null] },
|
|
37420
|
+
{ $ne: ["$liftName", ""] },
|
|
37421
|
+
{ $ne: ["$liftAccessLevel", null] }
|
|
37422
|
+
]
|
|
37423
|
+
},
|
|
37062
37424
|
{ name: "$liftName", no: "$liftAccessLevel" },
|
|
37063
37425
|
"$$REMOVE"
|
|
37064
37426
|
]
|
|
@@ -37094,7 +37456,14 @@ function UseAccessManagementRepo() {
|
|
|
37094
37456
|
const sessionResult = await Promise.all([
|
|
37095
37457
|
await collection().findOneAndUpdate(
|
|
37096
37458
|
{ _id: id },
|
|
37097
|
-
{
|
|
37459
|
+
{
|
|
37460
|
+
$set: {
|
|
37461
|
+
remarks,
|
|
37462
|
+
replacementStatus: "Complete",
|
|
37463
|
+
requestDate: /* @__PURE__ */ new Date(),
|
|
37464
|
+
isActivated: false
|
|
37465
|
+
}
|
|
37466
|
+
},
|
|
37098
37467
|
{ returnDocument: "after", session }
|
|
37099
37468
|
),
|
|
37100
37469
|
await collection().findOneAndUpdate(
|
|
@@ -37126,7 +37495,10 @@ function UseAccessManagementRepo() {
|
|
|
37126
37495
|
isActivated: true
|
|
37127
37496
|
};
|
|
37128
37497
|
if (search) {
|
|
37129
|
-
query.$or = [
|
|
37498
|
+
query.$or = [
|
|
37499
|
+
{ accessLevel: { $regex: search, $options: "i" } },
|
|
37500
|
+
{ cardNo: { $regex: search, $options: "i" } }
|
|
37501
|
+
];
|
|
37130
37502
|
}
|
|
37131
37503
|
if (type) {
|
|
37132
37504
|
query.userType = type;
|
|
@@ -37151,14 +37523,22 @@ function UseAccessManagementRepo() {
|
|
|
37151
37523
|
{
|
|
37152
37524
|
$addFields: {
|
|
37153
37525
|
extractedCardNo: {
|
|
37154
|
-
$substr: [
|
|
37526
|
+
$substr: [
|
|
37527
|
+
"$cardNo",
|
|
37528
|
+
{ $subtract: [{ $strLenCP: "$cardNo" }, 5] },
|
|
37529
|
+
5
|
|
37530
|
+
]
|
|
37155
37531
|
}
|
|
37156
37532
|
}
|
|
37157
37533
|
},
|
|
37158
37534
|
{
|
|
37159
37535
|
$facet: {
|
|
37160
37536
|
totalCount: [{ $count: "count" }],
|
|
37161
|
-
items: [
|
|
37537
|
+
items: [
|
|
37538
|
+
{ $sort: { _id: -1 } },
|
|
37539
|
+
{ $skip: page * limit },
|
|
37540
|
+
{ $limit: limit }
|
|
37541
|
+
]
|
|
37162
37542
|
}
|
|
37163
37543
|
}
|
|
37164
37544
|
]).toArray();
|
|
@@ -37189,145 +37569,151 @@ function UseAccessManagementRepo() {
|
|
|
37189
37569
|
query.replacementStatus = statusFilter;
|
|
37190
37570
|
}
|
|
37191
37571
|
if (dateFrom && dateTo) {
|
|
37192
|
-
query.requestDate = {
|
|
37572
|
+
query.requestDate = {
|
|
37573
|
+
$gte: new Date(dateFrom),
|
|
37574
|
+
$lte: new Date(dateTo)
|
|
37575
|
+
};
|
|
37193
37576
|
} else if (dateFrom) {
|
|
37194
37577
|
query.requestDate = { $gte: new Date(dateFrom) };
|
|
37195
37578
|
} else if (dateTo) {
|
|
37196
37579
|
query.requestDate = { $lte: new Date(dateTo) };
|
|
37197
37580
|
}
|
|
37198
|
-
const res = await collection().aggregate(
|
|
37199
|
-
|
|
37200
|
-
|
|
37201
|
-
|
|
37202
|
-
|
|
37203
|
-
|
|
37204
|
-
|
|
37205
|
-
|
|
37206
|
-
|
|
37207
|
-
|
|
37208
|
-
|
|
37209
|
-
$
|
|
37210
|
-
$
|
|
37581
|
+
const res = await collection().aggregate(
|
|
37582
|
+
[
|
|
37583
|
+
{
|
|
37584
|
+
$match: { ...query }
|
|
37585
|
+
},
|
|
37586
|
+
{
|
|
37587
|
+
$lookup: {
|
|
37588
|
+
from: "building-units",
|
|
37589
|
+
let: { unit: "$assignedUnit" },
|
|
37590
|
+
pipeline: [
|
|
37591
|
+
{
|
|
37592
|
+
$match: {
|
|
37593
|
+
$expr: {
|
|
37594
|
+
$eq: ["$_id", "$$unit"]
|
|
37595
|
+
}
|
|
37211
37596
|
}
|
|
37212
|
-
}
|
|
37213
|
-
|
|
37214
|
-
|
|
37215
|
-
|
|
37216
|
-
|
|
37217
|
-
|
|
37218
|
-
level: 1
|
|
37219
|
-
}
|
|
37220
|
-
}
|
|
37221
|
-
],
|
|
37222
|
-
as: "unit"
|
|
37223
|
-
}
|
|
37224
|
-
},
|
|
37225
|
-
{
|
|
37226
|
-
$unwind: { path: "$unit", preserveNullAndEmptyArrays: true }
|
|
37227
|
-
},
|
|
37228
|
-
{
|
|
37229
|
-
$lookup: {
|
|
37230
|
-
from: "building-levels",
|
|
37231
|
-
let: { level: "$unit.level" },
|
|
37232
|
-
pipeline: [
|
|
37233
|
-
{
|
|
37234
|
-
$match: {
|
|
37235
|
-
$expr: {
|
|
37236
|
-
$eq: ["$_id", "$$level"]
|
|
37597
|
+
},
|
|
37598
|
+
{
|
|
37599
|
+
$project: {
|
|
37600
|
+
_id: 1,
|
|
37601
|
+
name: 1,
|
|
37602
|
+
level: 1
|
|
37237
37603
|
}
|
|
37238
37604
|
}
|
|
37239
|
-
|
|
37240
|
-
|
|
37241
|
-
|
|
37242
|
-
|
|
37243
|
-
|
|
37244
|
-
|
|
37245
|
-
|
|
37246
|
-
|
|
37247
|
-
|
|
37248
|
-
|
|
37249
|
-
|
|
37250
|
-
|
|
37251
|
-
|
|
37252
|
-
|
|
37253
|
-
|
|
37254
|
-
|
|
37255
|
-
|
|
37256
|
-
|
|
37257
|
-
|
|
37258
|
-
|
|
37259
|
-
|
|
37260
|
-
|
|
37261
|
-
|
|
37262
|
-
|
|
37605
|
+
],
|
|
37606
|
+
as: "unit"
|
|
37607
|
+
}
|
|
37608
|
+
},
|
|
37609
|
+
{
|
|
37610
|
+
$unwind: { path: "$unit", preserveNullAndEmptyArrays: true }
|
|
37611
|
+
},
|
|
37612
|
+
{
|
|
37613
|
+
$lookup: {
|
|
37614
|
+
from: "building-levels",
|
|
37615
|
+
let: { level: "$unit.level" },
|
|
37616
|
+
pipeline: [
|
|
37617
|
+
{
|
|
37618
|
+
$match: {
|
|
37619
|
+
$expr: {
|
|
37620
|
+
$eq: ["$_id", "$$level"]
|
|
37621
|
+
}
|
|
37622
|
+
}
|
|
37623
|
+
},
|
|
37624
|
+
{
|
|
37625
|
+
$project: {
|
|
37626
|
+
_id: 1,
|
|
37627
|
+
level: 1,
|
|
37628
|
+
block: 1
|
|
37263
37629
|
}
|
|
37264
37630
|
}
|
|
37265
|
-
|
|
37266
|
-
|
|
37267
|
-
|
|
37268
|
-
|
|
37269
|
-
|
|
37270
|
-
|
|
37271
|
-
|
|
37272
|
-
|
|
37273
|
-
|
|
37274
|
-
|
|
37275
|
-
|
|
37276
|
-
|
|
37277
|
-
|
|
37278
|
-
|
|
37279
|
-
|
|
37280
|
-
|
|
37281
|
-
|
|
37282
|
-
|
|
37283
|
-
|
|
37284
|
-
|
|
37285
|
-
|
|
37286
|
-
|
|
37287
|
-
|
|
37631
|
+
],
|
|
37632
|
+
as: "level"
|
|
37633
|
+
}
|
|
37634
|
+
},
|
|
37635
|
+
{
|
|
37636
|
+
$unwind: { path: "$level", preserveNullAndEmptyArrays: true }
|
|
37637
|
+
},
|
|
37638
|
+
{
|
|
37639
|
+
$lookup: {
|
|
37640
|
+
from: "buildings",
|
|
37641
|
+
let: { block: "$level.block" },
|
|
37642
|
+
pipeline: [
|
|
37643
|
+
{
|
|
37644
|
+
$match: {
|
|
37645
|
+
$expr: {
|
|
37646
|
+
$eq: ["$_id", "$$block"]
|
|
37647
|
+
}
|
|
37648
|
+
}
|
|
37649
|
+
},
|
|
37650
|
+
{
|
|
37651
|
+
$project: {
|
|
37652
|
+
_id: 1,
|
|
37653
|
+
name: 1
|
|
37288
37654
|
}
|
|
37289
37655
|
}
|
|
37290
|
-
|
|
37291
|
-
|
|
37292
|
-
|
|
37293
|
-
|
|
37294
|
-
|
|
37656
|
+
],
|
|
37657
|
+
as: "building"
|
|
37658
|
+
}
|
|
37659
|
+
},
|
|
37660
|
+
{
|
|
37661
|
+
$unwind: { path: "$building", preserveNullAndEmptyArrays: true }
|
|
37662
|
+
},
|
|
37663
|
+
{
|
|
37664
|
+
$lookup: {
|
|
37665
|
+
from: "users",
|
|
37666
|
+
let: { id: "$userId" },
|
|
37667
|
+
pipeline: [
|
|
37668
|
+
{
|
|
37669
|
+
$match: {
|
|
37670
|
+
$expr: {
|
|
37671
|
+
$eq: ["$_id", "$$id"]
|
|
37672
|
+
}
|
|
37673
|
+
}
|
|
37674
|
+
},
|
|
37675
|
+
{
|
|
37676
|
+
$project: {
|
|
37677
|
+
givenName: 1,
|
|
37678
|
+
surname: 1
|
|
37679
|
+
}
|
|
37295
37680
|
}
|
|
37296
|
-
|
|
37297
|
-
|
|
37298
|
-
|
|
37299
|
-
}
|
|
37300
|
-
|
|
37301
|
-
|
|
37302
|
-
|
|
37303
|
-
|
|
37304
|
-
|
|
37305
|
-
|
|
37306
|
-
|
|
37307
|
-
|
|
37308
|
-
|
|
37309
|
-
|
|
37310
|
-
|
|
37311
|
-
|
|
37312
|
-
|
|
37313
|
-
|
|
37314
|
-
|
|
37315
|
-
|
|
37316
|
-
|
|
37317
|
-
|
|
37318
|
-
|
|
37319
|
-
|
|
37320
|
-
|
|
37321
|
-
|
|
37322
|
-
|
|
37323
|
-
|
|
37681
|
+
],
|
|
37682
|
+
as: "user"
|
|
37683
|
+
}
|
|
37684
|
+
},
|
|
37685
|
+
{
|
|
37686
|
+
$unwind: { path: "$user", preserveNullAndEmptyArrays: true }
|
|
37687
|
+
},
|
|
37688
|
+
{
|
|
37689
|
+
$match: { ...searchQuery }
|
|
37690
|
+
},
|
|
37691
|
+
{
|
|
37692
|
+
$facet: {
|
|
37693
|
+
data: [
|
|
37694
|
+
{ $skip: page * limit },
|
|
37695
|
+
{ $limit: limit },
|
|
37696
|
+
{
|
|
37697
|
+
$project: {
|
|
37698
|
+
_id: 1,
|
|
37699
|
+
cardNo: 1,
|
|
37700
|
+
accessLevel: 1,
|
|
37701
|
+
liftAccessLevel: 1,
|
|
37702
|
+
replacementStatus: 1,
|
|
37703
|
+
remarks: 1,
|
|
37704
|
+
block: "$building.name",
|
|
37705
|
+
level: "$level.level",
|
|
37706
|
+
unit: "$unit.name",
|
|
37707
|
+
user: "$user"
|
|
37708
|
+
}
|
|
37324
37709
|
}
|
|
37325
|
-
|
|
37326
|
-
|
|
37327
|
-
|
|
37710
|
+
],
|
|
37711
|
+
totalCount: [{ $count: "count" }]
|
|
37712
|
+
}
|
|
37328
37713
|
}
|
|
37329
|
-
|
|
37330
|
-
|
|
37714
|
+
],
|
|
37715
|
+
{ allowDiskUse: true }
|
|
37716
|
+
).toArray();
|
|
37331
37717
|
const count = res[0]?.totalCount[0] ? res[0].totalCount[0].count : 0;
|
|
37332
37718
|
const pagination = (0, import_node_server_utils154.paginate)(res[0].data, page, limit, count);
|
|
37333
37719
|
return pagination;
|
|
@@ -37339,7 +37725,10 @@ function UseAccessManagementRepo() {
|
|
|
37339
37725
|
try {
|
|
37340
37726
|
const { site } = params;
|
|
37341
37727
|
const siteId = new import_mongodb90.ObjectId(site);
|
|
37342
|
-
const res = await collectionName("entrypass-settings").findOne(
|
|
37728
|
+
const res = await collectionName("entrypass-settings").findOne(
|
|
37729
|
+
{ site: siteId },
|
|
37730
|
+
{ allowDiskUse: true }
|
|
37731
|
+
);
|
|
37343
37732
|
return res;
|
|
37344
37733
|
} catch (error) {
|
|
37345
37734
|
throw new Error(error.message);
|
|
@@ -37349,13 +37738,19 @@ function UseAccessManagementRepo() {
|
|
|
37349
37738
|
const session = import_node_server_utils154.useAtlas.getClient()?.startSession();
|
|
37350
37739
|
try {
|
|
37351
37740
|
const { dataJson, site } = params;
|
|
37352
|
-
const rawItems = JSON.parse(dataJson).filter(
|
|
37741
|
+
const rawItems = JSON.parse(dataJson).filter(
|
|
37742
|
+
(_, index) => index !== -1
|
|
37743
|
+
);
|
|
37353
37744
|
const items = await Promise.all(
|
|
37354
37745
|
rawItems.map(async (item) => {
|
|
37355
37746
|
const date = new Date(item["startDate (format MM/DD/YYYY)"]);
|
|
37356
37747
|
const endDate = new Date(date.setFullYear(date.getFullYear() + 10));
|
|
37357
|
-
const cardNumber = String(
|
|
37358
|
-
|
|
37748
|
+
const cardNumber = String(
|
|
37749
|
+
Number(item["cardNo (number 0-65535 ex. 301)"] || 0)
|
|
37750
|
+
).padStart(6, "0");
|
|
37751
|
+
const facilityCode = String(
|
|
37752
|
+
Number(item["facilityCode (number 0-255 ex. 11)"] || 0)
|
|
37753
|
+
).padStart(4, "0");
|
|
37359
37754
|
const pin = item["pin (number 6 digits only)"] ? item["pin (number 6 digits only)"].toString().padStart(6, "0") : "123456";
|
|
37360
37755
|
const match = item["accessLevel (number ex. 1)"];
|
|
37361
37756
|
const accessLevel = match ? match : null;
|
|
@@ -37386,7 +37781,10 @@ function UseAccessManagementRepo() {
|
|
|
37386
37781
|
});
|
|
37387
37782
|
})
|
|
37388
37783
|
);
|
|
37389
|
-
const result = await collection().insertMany(items, {
|
|
37784
|
+
const result = await collection().insertMany(items, {
|
|
37785
|
+
session,
|
|
37786
|
+
ordered: false
|
|
37787
|
+
});
|
|
37390
37788
|
const mapping = items.map((item, i) => ({
|
|
37391
37789
|
cardNo: item.cardNo,
|
|
37392
37790
|
insertedId: result.insertedIds[i]
|
|
@@ -37401,8 +37799,19 @@ function UseAccessManagementRepo() {
|
|
|
37401
37799
|
let isAborted = false;
|
|
37402
37800
|
try {
|
|
37403
37801
|
await session?.startTransaction();
|
|
37404
|
-
const {
|
|
37405
|
-
|
|
37802
|
+
const {
|
|
37803
|
+
units,
|
|
37804
|
+
quantity,
|
|
37805
|
+
type,
|
|
37806
|
+
site,
|
|
37807
|
+
userType,
|
|
37808
|
+
accessLevel,
|
|
37809
|
+
liftAccessLevel
|
|
37810
|
+
} = params;
|
|
37811
|
+
const [convertedUnits, convertedSite] = await Promise.all([
|
|
37812
|
+
Promise.all(units.map((id) => new import_mongodb90.ObjectId(id))),
|
|
37813
|
+
new import_mongodb90.ObjectId(site)
|
|
37814
|
+
]);
|
|
37406
37815
|
const totalRequired = quantity * convertedUnits.length;
|
|
37407
37816
|
const availableCards = await collection().find({
|
|
37408
37817
|
assignedUnit: null,
|
|
@@ -37422,16 +37831,18 @@ function UseAccessManagementRepo() {
|
|
|
37422
37831
|
message: `Insufficient ${type} access cards. Need ${totalRequired}, but only ${availableCards.length} available.`
|
|
37423
37832
|
};
|
|
37424
37833
|
}
|
|
37425
|
-
const bulkUpdates = availableCards.map(
|
|
37426
|
-
|
|
37427
|
-
|
|
37428
|
-
|
|
37429
|
-
|
|
37430
|
-
|
|
37834
|
+
const bulkUpdates = availableCards.map(
|
|
37835
|
+
(card, index) => ({
|
|
37836
|
+
updateOne: {
|
|
37837
|
+
filter: { _id: card._id },
|
|
37838
|
+
update: {
|
|
37839
|
+
$set: {
|
|
37840
|
+
assignedUnit: convertedUnits[Math.floor(index / quantity)]
|
|
37841
|
+
}
|
|
37431
37842
|
}
|
|
37432
37843
|
}
|
|
37433
|
-
}
|
|
37434
|
-
|
|
37844
|
+
})
|
|
37845
|
+
);
|
|
37435
37846
|
await collection().bulkWrite(bulkUpdates, { session });
|
|
37436
37847
|
await session?.commitTransaction();
|
|
37437
37848
|
return {
|
|
@@ -37452,7 +37863,18 @@ function UseAccessManagementRepo() {
|
|
|
37452
37863
|
try {
|
|
37453
37864
|
const { cardId, remarks } = params;
|
|
37454
37865
|
const id = new import_mongodb90.ObjectId(cardId);
|
|
37455
|
-
const result = await collection().findOneAndUpdate(
|
|
37866
|
+
const result = await collection().findOneAndUpdate(
|
|
37867
|
+
{ _id: id },
|
|
37868
|
+
{
|
|
37869
|
+
$set: {
|
|
37870
|
+
isActivated: false,
|
|
37871
|
+
updatedAt: /* @__PURE__ */ new Date(),
|
|
37872
|
+
remarks,
|
|
37873
|
+
requestDate: /* @__PURE__ */ new Date()
|
|
37874
|
+
}
|
|
37875
|
+
},
|
|
37876
|
+
{ returnDocument: "after" }
|
|
37877
|
+
);
|
|
37456
37878
|
return result;
|
|
37457
37879
|
} catch (error) {
|
|
37458
37880
|
throw new Error(error.message);
|
|
@@ -37513,7 +37935,13 @@ function UseAccessManagementRepo() {
|
|
|
37513
37935
|
const { site, payload } = params;
|
|
37514
37936
|
const id = new import_mongodb90.ObjectId(site);
|
|
37515
37937
|
const highestCardNo = await collection().aggregate([
|
|
37516
|
-
{
|
|
37938
|
+
{
|
|
37939
|
+
$match: {
|
|
37940
|
+
site: id,
|
|
37941
|
+
type: "NFC" /* NFC */,
|
|
37942
|
+
userType: "Visitor/Resident" /* DEFAULT */
|
|
37943
|
+
}
|
|
37944
|
+
},
|
|
37517
37945
|
{
|
|
37518
37946
|
$addFields: {
|
|
37519
37947
|
qrTagCardNoNumeric: { $toInt: "$qrTagCardNo" }
|
|
@@ -37533,14 +37961,19 @@ function UseAccessManagementRepo() {
|
|
|
37533
37961
|
if (highestCardNo.length > 0) {
|
|
37534
37962
|
start = highestCardNo[0].qrTagCardNoNumeric || 0;
|
|
37535
37963
|
}
|
|
37536
|
-
const nextCardNumbers = Array.from(
|
|
37964
|
+
const nextCardNumbers = Array.from(
|
|
37965
|
+
{ length: payload.length },
|
|
37966
|
+
(_, i) => String(start + i + 1).padStart(5, "0")
|
|
37967
|
+
);
|
|
37537
37968
|
const bulkOps = await Promise.all(
|
|
37538
37969
|
payload.map(async (doc, index) => {
|
|
37539
37970
|
const id2 = new import_mongodb90.ObjectId(doc._id);
|
|
37540
37971
|
return {
|
|
37541
37972
|
updateOne: {
|
|
37542
37973
|
filter: { _id: id2 },
|
|
37543
|
-
update: {
|
|
37974
|
+
update: {
|
|
37975
|
+
$set: { qrTag: doc.qrTag, qrTagCardNo: nextCardNumbers[index] }
|
|
37976
|
+
}
|
|
37544
37977
|
}
|
|
37545
37978
|
};
|
|
37546
37979
|
})
|
|
@@ -37582,7 +38015,11 @@ function UseAccessManagementRepo() {
|
|
|
37582
38015
|
{
|
|
37583
38016
|
$addFields: {
|
|
37584
38017
|
extractedCardNo: {
|
|
37585
|
-
$substr: [
|
|
38018
|
+
$substr: [
|
|
38019
|
+
"$cardNo",
|
|
38020
|
+
{ $subtract: [{ $strLenCP: "$cardNo" }, 5] },
|
|
38021
|
+
5
|
|
38022
|
+
]
|
|
37586
38023
|
}
|
|
37587
38024
|
}
|
|
37588
38025
|
},
|
|
@@ -37620,7 +38057,11 @@ function UseAccessManagementRepo() {
|
|
|
37620
38057
|
},
|
|
37621
38058
|
{
|
|
37622
38059
|
$facet: {
|
|
37623
|
-
items: [
|
|
38060
|
+
items: [
|
|
38061
|
+
{ $skip: page * limit },
|
|
38062
|
+
{ $limit: limit },
|
|
38063
|
+
{ $project: { cardNo: 1 } }
|
|
38064
|
+
],
|
|
37624
38065
|
totalCounts: [{ $count: "count" }]
|
|
37625
38066
|
}
|
|
37626
38067
|
}
|
|
@@ -37631,7 +38072,9 @@ function UseAccessManagementRepo() {
|
|
|
37631
38072
|
_id: unitId
|
|
37632
38073
|
}
|
|
37633
38074
|
},
|
|
37634
|
-
{
|
|
38075
|
+
{
|
|
38076
|
+
$project: { _id: 1, name: 1, buildingName: 1, block: 1, level: 1 }
|
|
38077
|
+
},
|
|
37635
38078
|
{
|
|
37636
38079
|
$lookup: {
|
|
37637
38080
|
from: "building-levels",
|
|
@@ -37719,7 +38162,18 @@ function UseAccessManagementRepo() {
|
|
|
37719
38162
|
items: [
|
|
37720
38163
|
{ $skip: 0 },
|
|
37721
38164
|
{ $limit: 1 },
|
|
37722
|
-
{
|
|
38165
|
+
{
|
|
38166
|
+
$project: {
|
|
38167
|
+
_id: -1,
|
|
38168
|
+
accessLevel: 1,
|
|
38169
|
+
accessGroup: 1,
|
|
38170
|
+
userType: 1,
|
|
38171
|
+
doorName: 1,
|
|
38172
|
+
liftName: 1,
|
|
38173
|
+
liftAccessLevel: 1,
|
|
38174
|
+
isLiftCard: 1
|
|
38175
|
+
}
|
|
38176
|
+
}
|
|
37723
38177
|
]
|
|
37724
38178
|
}
|
|
37725
38179
|
}
|
|
@@ -37768,13 +38222,25 @@ function UseAccessManagementRepo() {
|
|
|
37768
38222
|
cardsToAttach = [...cardsId];
|
|
37769
38223
|
} else if (type === "NFC" /* NFC */) {
|
|
37770
38224
|
if (nfcCards && nfcCards.length > 0) {
|
|
37771
|
-
const objectIds = nfcCards.map(
|
|
38225
|
+
const objectIds = nfcCards.map(
|
|
38226
|
+
(card) => new import_mongodb90.ObjectId(card._id)
|
|
38227
|
+
);
|
|
37772
38228
|
cards = await collection().find({ _id: { $in: objectIds } }).toArray();
|
|
37773
|
-
const nfcList = objectIds.map((card) => ({
|
|
38229
|
+
const nfcList = objectIds.map((card) => ({
|
|
38230
|
+
_id: card,
|
|
38231
|
+
status: "In use",
|
|
38232
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
38233
|
+
}));
|
|
37774
38234
|
cardsToAttach = [...nfcList];
|
|
37775
38235
|
}
|
|
37776
38236
|
}
|
|
37777
|
-
const result = await collectionName(
|
|
38237
|
+
const result = await collectionName(
|
|
38238
|
+
"visitor.transactions"
|
|
38239
|
+
).findOneAndUpdate(
|
|
38240
|
+
{ _id: visitorId },
|
|
38241
|
+
{ $push: { cards: cardsToAttach } },
|
|
38242
|
+
{ session, returnDocument: "after" }
|
|
38243
|
+
);
|
|
37778
38244
|
const updatedVisitor = result?._id;
|
|
37779
38245
|
const assignCards = cards.map((card) => card._id);
|
|
37780
38246
|
if (assignCards.length > 0) {
|
|
@@ -37830,10 +38296,18 @@ function UseAccessManagementRepo() {
|
|
|
37830
38296
|
liftAccessEndDate: formatEntryPassDate(item.liftAccessEndDate) || "19770510",
|
|
37831
38297
|
accessGroup: ag
|
|
37832
38298
|
};
|
|
37833
|
-
return readTemplate(
|
|
38299
|
+
return readTemplate(
|
|
38300
|
+
`${item.accessLevel !== null ? "add-card" : "add-card-lift"}`,
|
|
38301
|
+
{ ...command }
|
|
38302
|
+
);
|
|
37834
38303
|
}).flat();
|
|
37835
|
-
const response = await sendCommand(
|
|
37836
|
-
|
|
38304
|
+
const response = await sendCommand(
|
|
38305
|
+
commands.join("").toString(),
|
|
38306
|
+
acm_url
|
|
38307
|
+
);
|
|
38308
|
+
serverResult = await (0, import_xml2js2.parseStringPromise)(response, {
|
|
38309
|
+
explicitArray: false
|
|
38310
|
+
});
|
|
37837
38311
|
if (result && serverResult.RESULT.$.STCODE !== "0") {
|
|
37838
38312
|
throw new Error("Command failed, server error.");
|
|
37839
38313
|
}
|
|
@@ -37882,7 +38356,10 @@ function UseAccessManagementRepo() {
|
|
|
37882
38356
|
try {
|
|
37883
38357
|
await session?.startTransaction();
|
|
37884
38358
|
const userId = new import_mongodb90.ObjectId(params.userId);
|
|
37885
|
-
const result = await collection().updateMany(
|
|
38359
|
+
const result = await collection().updateMany(
|
|
38360
|
+
{ userId },
|
|
38361
|
+
{ $set: { userId: null, status: "Available", updatedAt: /* @__PURE__ */ new Date() } }
|
|
38362
|
+
);
|
|
37886
38363
|
await session?.commitTransaction();
|
|
37887
38364
|
return result;
|
|
37888
38365
|
} catch (error) {
|
|
@@ -37926,7 +38403,15 @@ function UseAccessManagementRepo() {
|
|
|
37926
38403
|
foreignField: "level",
|
|
37927
38404
|
pipeline: [
|
|
37928
38405
|
{ $match: { status: { $ne: "deleted" } } },
|
|
37929
|
-
{
|
|
38406
|
+
{
|
|
38407
|
+
$project: {
|
|
38408
|
+
_id: 1,
|
|
38409
|
+
name: 1,
|
|
38410
|
+
buildingName: 1,
|
|
38411
|
+
level: 1,
|
|
38412
|
+
block: 1
|
|
38413
|
+
}
|
|
38414
|
+
}
|
|
37930
38415
|
],
|
|
37931
38416
|
as: "units"
|
|
37932
38417
|
}
|
|
@@ -37947,11 +38432,20 @@ function UseAccessManagementRepo() {
|
|
|
37947
38432
|
throw new Error(error.message);
|
|
37948
38433
|
}
|
|
37949
38434
|
}
|
|
37950
|
-
async function getTransactionsRepo({
|
|
38435
|
+
async function getTransactionsRepo({
|
|
38436
|
+
page = 1,
|
|
38437
|
+
limit = 10,
|
|
38438
|
+
site,
|
|
38439
|
+
cardNo,
|
|
38440
|
+
url
|
|
38441
|
+
}) {
|
|
37951
38442
|
page = page ? page - 1 : 0;
|
|
37952
38443
|
site = new import_mongodb90.ObjectId(site);
|
|
37953
38444
|
try {
|
|
37954
|
-
let index = await collectionName("access-card-transactions").findOne(
|
|
38445
|
+
let index = await collectionName("access-card-transactions").findOne(
|
|
38446
|
+
{},
|
|
38447
|
+
{ sort: { index: -1 } }
|
|
38448
|
+
);
|
|
37955
38449
|
index = index ? index.index : 0;
|
|
37956
38450
|
const response = await getTransactions(index, url);
|
|
37957
38451
|
if (response && Array.isArray(response.items) && response.items.length > 0) {
|
|
@@ -37960,7 +38454,9 @@ function UseAccessManagementRepo() {
|
|
|
37960
38454
|
data: JSON.parse(item.data),
|
|
37961
38455
|
timestamp: item.timestamp
|
|
37962
38456
|
}));
|
|
37963
|
-
result2 = result2.filter(
|
|
38457
|
+
result2 = result2.filter(
|
|
38458
|
+
(item) => item.data.Event.ETYPE === "0" && item.data.Event.CARDNO !== ""
|
|
38459
|
+
);
|
|
37964
38460
|
if (result2.length > 0) {
|
|
37965
38461
|
const transactions = result2.map(
|
|
37966
38462
|
(item) => new MAccessCardTransaction({
|
|
@@ -37971,11 +38467,16 @@ function UseAccessManagementRepo() {
|
|
|
37971
38467
|
accessType: item.data.Event.DEVNAME,
|
|
37972
38468
|
accessStatus: item.data.Event.TRCODE,
|
|
37973
38469
|
description: item.data.Event.TRDESC,
|
|
37974
|
-
accessTime: entryPassDate(
|
|
38470
|
+
accessTime: entryPassDate(
|
|
38471
|
+
item.data.Event.TRDATE,
|
|
38472
|
+
item.data.Event.TRTIME
|
|
38473
|
+
),
|
|
37975
38474
|
createdAt: /* @__PURE__ */ new Date()
|
|
37976
38475
|
})
|
|
37977
38476
|
);
|
|
37978
|
-
await collectionName("access-card-transactions").insertMany(
|
|
38477
|
+
await collectionName("access-card-transactions").insertMany(
|
|
38478
|
+
transactions
|
|
38479
|
+
);
|
|
37979
38480
|
}
|
|
37980
38481
|
}
|
|
37981
38482
|
const result = await collectionName("access-card-transactions").aggregate([
|
|
@@ -38046,7 +38547,11 @@ function UseAccessManagementRepo() {
|
|
|
38046
38547
|
{
|
|
38047
38548
|
$facet: {
|
|
38048
38549
|
totalCount: [{ $count: "count" }],
|
|
38049
|
-
items: [
|
|
38550
|
+
items: [
|
|
38551
|
+
{ $sort: { _id: -1 } },
|
|
38552
|
+
{ $skip: page * limit },
|
|
38553
|
+
{ $limit: limit }
|
|
38554
|
+
]
|
|
38050
38555
|
}
|
|
38051
38556
|
}
|
|
38052
38557
|
]).toArray();
|
|
@@ -38069,7 +38574,9 @@ function UseAccessManagementRepo() {
|
|
|
38069
38574
|
if (assignees.length < 1) {
|
|
38070
38575
|
throw new Error("No user to Assign.");
|
|
38071
38576
|
}
|
|
38072
|
-
assignees = assignees.map(
|
|
38577
|
+
assignees = assignees.map(
|
|
38578
|
+
(data) => new import_mongodb90.ObjectId(data)
|
|
38579
|
+
);
|
|
38073
38580
|
unit = new import_mongodb90.ObjectId(unit);
|
|
38074
38581
|
let availableCards = [];
|
|
38075
38582
|
let update = [];
|
|
@@ -38079,7 +38586,18 @@ function UseAccessManagementRepo() {
|
|
|
38079
38586
|
$match: {
|
|
38080
38587
|
$expr: {
|
|
38081
38588
|
$and: [
|
|
38082
|
-
{
|
|
38589
|
+
{
|
|
38590
|
+
$in: [
|
|
38591
|
+
unit,
|
|
38592
|
+
{
|
|
38593
|
+
$cond: [
|
|
38594
|
+
{ $isArray: "$assignedUnit" },
|
|
38595
|
+
"$assignedUnit",
|
|
38596
|
+
["$assignedUnit"]
|
|
38597
|
+
]
|
|
38598
|
+
}
|
|
38599
|
+
]
|
|
38600
|
+
},
|
|
38083
38601
|
{ $eq: ["$userId", null] },
|
|
38084
38602
|
{ $eq: ["$type", type] },
|
|
38085
38603
|
{ $eq: ["$isActivated", true] }
|
|
@@ -38096,7 +38614,10 @@ function UseAccessManagementRepo() {
|
|
|
38096
38614
|
card.staffNo = userId.toString().slice(-10);
|
|
38097
38615
|
return card;
|
|
38098
38616
|
});
|
|
38099
|
-
update = availableCards.slice(0, assignees.length).map((card, index) => ({
|
|
38617
|
+
update = availableCards.slice(0, assignees.length).map((card, index) => ({
|
|
38618
|
+
_id: card._id,
|
|
38619
|
+
userId: new import_mongodb90.ObjectId(assignees[index])
|
|
38620
|
+
}));
|
|
38100
38621
|
const commands = cards.map((item, index) => {
|
|
38101
38622
|
let ag = null;
|
|
38102
38623
|
if (item.accessGroup !== void 0) {
|
|
@@ -38126,16 +38647,27 @@ function UseAccessManagementRepo() {
|
|
|
38126
38647
|
liftAccessEndDate: formatEntryPassDate(item.liftAccessEndDate) || "19770510",
|
|
38127
38648
|
accessGroup: ag
|
|
38128
38649
|
};
|
|
38129
|
-
return readTemplate(
|
|
38650
|
+
return readTemplate(
|
|
38651
|
+
`${item.accessLevel !== null ? "add-card" : "add-card-lift"}`,
|
|
38652
|
+
{ ...command }
|
|
38653
|
+
);
|
|
38130
38654
|
}).flat();
|
|
38131
38655
|
const response = await sendCommand(commands.join("").toString(), acm_url);
|
|
38132
|
-
const result = await (0, import_xml2js2.parseStringPromise)(response, {
|
|
38656
|
+
const result = await (0, import_xml2js2.parseStringPromise)(response, {
|
|
38657
|
+
explicitArray: false
|
|
38658
|
+
});
|
|
38133
38659
|
console.log("status code", result.RESULT.$.STCODE);
|
|
38134
38660
|
if (result && result.RESULT.$.STCODE !== "0") {
|
|
38135
38661
|
throw new Error("Command failed, server error.");
|
|
38136
38662
|
}
|
|
38137
38663
|
for (const { _id, userId } of update) {
|
|
38138
|
-
await collection().updateOne(
|
|
38664
|
+
await collection().updateOne(
|
|
38665
|
+
{ _id },
|
|
38666
|
+
{
|
|
38667
|
+
$set: { userId, staffNo: `STAFF-${userId.toString().slice(-10)}` }
|
|
38668
|
+
},
|
|
38669
|
+
{ session }
|
|
38670
|
+
);
|
|
38139
38671
|
}
|
|
38140
38672
|
await session?.commitTransaction();
|
|
38141
38673
|
return "Cards assigned successfully.";
|
|
@@ -38151,7 +38683,11 @@ function UseAccessManagementRepo() {
|
|
|
38151
38683
|
try {
|
|
38152
38684
|
session?.startTransaction();
|
|
38153
38685
|
const id = new import_mongodb90.ObjectId(userId);
|
|
38154
|
-
await collection().updateMany(
|
|
38686
|
+
await collection().updateMany(
|
|
38687
|
+
{ userId: id },
|
|
38688
|
+
{ $set: { userId: null, status: "Available" } },
|
|
38689
|
+
{ session }
|
|
38690
|
+
);
|
|
38155
38691
|
session?.commitTransaction();
|
|
38156
38692
|
return "Successful Checkout";
|
|
38157
38693
|
} catch (error) {
|
|
@@ -38161,7 +38697,11 @@ function UseAccessManagementRepo() {
|
|
|
38161
38697
|
await session?.endSession();
|
|
38162
38698
|
}
|
|
38163
38699
|
}
|
|
38164
|
-
async function uploadTemplateRepo({
|
|
38700
|
+
async function uploadTemplateRepo({
|
|
38701
|
+
site,
|
|
38702
|
+
id,
|
|
38703
|
+
name
|
|
38704
|
+
}) {
|
|
38165
38705
|
site = new import_mongodb90.ObjectId(site);
|
|
38166
38706
|
id = new import_mongodb90.ObjectId(id);
|
|
38167
38707
|
try {
|
|
@@ -38174,6 +38714,46 @@ function UseAccessManagementRepo() {
|
|
|
38174
38714
|
throw new Error(error.message);
|
|
38175
38715
|
}
|
|
38176
38716
|
}
|
|
38717
|
+
async function getResidentsRepo({
|
|
38718
|
+
orgId,
|
|
38719
|
+
siteId,
|
|
38720
|
+
unitId
|
|
38721
|
+
}) {
|
|
38722
|
+
try {
|
|
38723
|
+
orgId = new import_mongodb90.ObjectId(orgId);
|
|
38724
|
+
siteId = new import_mongodb90.ObjectId(siteId);
|
|
38725
|
+
unitId = new import_mongodb90.ObjectId(unitId);
|
|
38726
|
+
const result = await collectionName("users").aggregate([
|
|
38727
|
+
{
|
|
38728
|
+
$match: {
|
|
38729
|
+
$expr: {
|
|
38730
|
+
$and: [
|
|
38731
|
+
{ $eq: ["$defaultOrg", orgId] },
|
|
38732
|
+
{ $eq: ["$site", siteId] },
|
|
38733
|
+
{ $eq: ["$unitId", unitId] }
|
|
38734
|
+
]
|
|
38735
|
+
}
|
|
38736
|
+
}
|
|
38737
|
+
},
|
|
38738
|
+
{
|
|
38739
|
+
$project: {
|
|
38740
|
+
_id: 1,
|
|
38741
|
+
email: 1,
|
|
38742
|
+
unitName: 1,
|
|
38743
|
+
type: 1,
|
|
38744
|
+
status: 1,
|
|
38745
|
+
name: 1,
|
|
38746
|
+
defaultOrg: 1,
|
|
38747
|
+
site: 1,
|
|
38748
|
+
unitId: 1
|
|
38749
|
+
}
|
|
38750
|
+
}
|
|
38751
|
+
]).toArray();
|
|
38752
|
+
return result;
|
|
38753
|
+
} catch (error) {
|
|
38754
|
+
throw new Error(error.message);
|
|
38755
|
+
}
|
|
38756
|
+
}
|
|
38177
38757
|
return {
|
|
38178
38758
|
createIndexes,
|
|
38179
38759
|
createIndexForEntrypass,
|
|
@@ -38209,7 +38789,8 @@ function UseAccessManagementRepo() {
|
|
|
38209
38789
|
getTransactionsRepo,
|
|
38210
38790
|
assignMultipleCardsRepo,
|
|
38211
38791
|
visitorCheckoutRepo,
|
|
38212
|
-
uploadTemplateRepo
|
|
38792
|
+
uploadTemplateRepo,
|
|
38793
|
+
getResidentsRepo
|
|
38213
38794
|
};
|
|
38214
38795
|
}
|
|
38215
38796
|
|
|
@@ -38253,7 +38834,8 @@ function useAccessManagementSvc() {
|
|
|
38253
38834
|
getTransactionsRepo,
|
|
38254
38835
|
assignMultipleCardsRepo,
|
|
38255
38836
|
visitorCheckoutRepo,
|
|
38256
|
-
uploadTemplateRepo
|
|
38837
|
+
uploadTemplateRepo,
|
|
38838
|
+
getResidentsRepo
|
|
38257
38839
|
} = UseAccessManagementRepo();
|
|
38258
38840
|
const addPhysicalCardSvc = async (payload) => {
|
|
38259
38841
|
try {
|
|
@@ -38545,17 +39127,39 @@ function useAccessManagementSvc() {
|
|
|
38545
39127
|
throw new Error(err.message);
|
|
38546
39128
|
}
|
|
38547
39129
|
};
|
|
38548
|
-
const getTransactionsSvc = async ({
|
|
39130
|
+
const getTransactionsSvc = async ({
|
|
39131
|
+
page,
|
|
39132
|
+
limit,
|
|
39133
|
+
site,
|
|
39134
|
+
cardNo,
|
|
39135
|
+
url
|
|
39136
|
+
}) => {
|
|
38549
39137
|
try {
|
|
38550
|
-
const response = await getTransactionsRepo({
|
|
39138
|
+
const response = await getTransactionsRepo({
|
|
39139
|
+
page,
|
|
39140
|
+
limit,
|
|
39141
|
+
site,
|
|
39142
|
+
cardNo,
|
|
39143
|
+
url
|
|
39144
|
+
});
|
|
38551
39145
|
return response;
|
|
38552
39146
|
} catch (err) {
|
|
38553
39147
|
throw new Error(err.message);
|
|
38554
39148
|
}
|
|
38555
39149
|
};
|
|
38556
|
-
const assignMultipleCardsSvc = async ({
|
|
39150
|
+
const assignMultipleCardsSvc = async ({
|
|
39151
|
+
assignees,
|
|
39152
|
+
unit,
|
|
39153
|
+
type,
|
|
39154
|
+
acm_url
|
|
39155
|
+
}) => {
|
|
38557
39156
|
try {
|
|
38558
|
-
const response = await assignMultipleCardsRepo({
|
|
39157
|
+
const response = await assignMultipleCardsRepo({
|
|
39158
|
+
assignees,
|
|
39159
|
+
unit,
|
|
39160
|
+
type,
|
|
39161
|
+
acm_url
|
|
39162
|
+
});
|
|
38559
39163
|
return response;
|
|
38560
39164
|
} catch (err) {
|
|
38561
39165
|
throw new Error(err.message);
|
|
@@ -38569,7 +39173,11 @@ function useAccessManagementSvc() {
|
|
|
38569
39173
|
throw new Error(err.message);
|
|
38570
39174
|
}
|
|
38571
39175
|
};
|
|
38572
|
-
const uploadTemplateSvc = async ({
|
|
39176
|
+
const uploadTemplateSvc = async ({
|
|
39177
|
+
site,
|
|
39178
|
+
id,
|
|
39179
|
+
name
|
|
39180
|
+
}) => {
|
|
38573
39181
|
try {
|
|
38574
39182
|
const response = await uploadTemplateRepo({ site, id, name });
|
|
38575
39183
|
return response;
|
|
@@ -38577,6 +39185,18 @@ function useAccessManagementSvc() {
|
|
|
38577
39185
|
throw new Error(err.message);
|
|
38578
39186
|
}
|
|
38579
39187
|
};
|
|
39188
|
+
const getResidentsSvc = async ({
|
|
39189
|
+
orgId,
|
|
39190
|
+
siteId,
|
|
39191
|
+
unitId
|
|
39192
|
+
}) => {
|
|
39193
|
+
try {
|
|
39194
|
+
const response = await getResidentsRepo({ orgId, siteId, unitId });
|
|
39195
|
+
return response;
|
|
39196
|
+
} catch (err) {
|
|
39197
|
+
throw new Error(err.message);
|
|
39198
|
+
}
|
|
39199
|
+
};
|
|
38580
39200
|
return {
|
|
38581
39201
|
addPhysicalCardSvc,
|
|
38582
39202
|
addNonPhysicalCardSvc,
|
|
@@ -38615,7 +39235,8 @@ function useAccessManagementSvc() {
|
|
|
38615
39235
|
getTransactionsSvc,
|
|
38616
39236
|
assignMultipleCardsSvc,
|
|
38617
39237
|
visitorCheckoutSvc,
|
|
38618
|
-
uploadTemplateSvc
|
|
39238
|
+
uploadTemplateSvc,
|
|
39239
|
+
getResidentsSvc
|
|
38619
39240
|
};
|
|
38620
39241
|
}
|
|
38621
39242
|
|
|
@@ -38659,7 +39280,8 @@ function useAccessManagementController() {
|
|
|
38659
39280
|
getTransactionsSvc,
|
|
38660
39281
|
assignMultipleCardsSvc,
|
|
38661
39282
|
visitorCheckoutSvc,
|
|
38662
|
-
uploadTemplateSvc
|
|
39283
|
+
uploadTemplateSvc,
|
|
39284
|
+
getResidentsSvc
|
|
38663
39285
|
} = useAccessManagementSvc();
|
|
38664
39286
|
const addPhysicalCard = async (req, res) => {
|
|
38665
39287
|
try {
|
|
@@ -38908,11 +39530,25 @@ function useAccessManagementController() {
|
|
|
38908
39530
|
search: import_joi86.default.string().optional().allow("", null),
|
|
38909
39531
|
userType: import_joi86.default.string().required()
|
|
38910
39532
|
});
|
|
38911
|
-
const { error } = schema2.validate({
|
|
39533
|
+
const { error } = schema2.validate({
|
|
39534
|
+
page,
|
|
39535
|
+
limit,
|
|
39536
|
+
site,
|
|
39537
|
+
organization,
|
|
39538
|
+
search,
|
|
39539
|
+
userType
|
|
39540
|
+
});
|
|
38912
39541
|
if (error) {
|
|
38913
39542
|
return res.status(400).json({ message: error.message });
|
|
38914
39543
|
}
|
|
38915
|
-
const result = await userTypeAccessCardsSvc({
|
|
39544
|
+
const result = await userTypeAccessCardsSvc({
|
|
39545
|
+
page,
|
|
39546
|
+
limit,
|
|
39547
|
+
search,
|
|
39548
|
+
site,
|
|
39549
|
+
organization,
|
|
39550
|
+
userType
|
|
39551
|
+
});
|
|
38916
39552
|
return res.status(200).json({ message: "Success", data: result });
|
|
38917
39553
|
} catch (error) {
|
|
38918
39554
|
return res.status(500).json({
|
|
@@ -38923,7 +39559,12 @@ function useAccessManagementController() {
|
|
|
38923
39559
|
};
|
|
38924
39560
|
const assignedAccessCards = async (req, res) => {
|
|
38925
39561
|
try {
|
|
38926
|
-
const {
|
|
39562
|
+
const {
|
|
39563
|
+
site,
|
|
39564
|
+
userType,
|
|
39565
|
+
type,
|
|
39566
|
+
search = ""
|
|
39567
|
+
} = req.query;
|
|
38927
39568
|
const schema2 = import_joi86.default.object({
|
|
38928
39569
|
site: import_joi86.default.string().hex().required(),
|
|
38929
39570
|
userType: import_joi86.default.string().required(),
|
|
@@ -38934,7 +39575,12 @@ function useAccessManagementController() {
|
|
|
38934
39575
|
if (error) {
|
|
38935
39576
|
return res.status(400).json({ message: error.message });
|
|
38936
39577
|
}
|
|
38937
|
-
const result = await assignedAccessCardsSvc({
|
|
39578
|
+
const result = await assignedAccessCardsSvc({
|
|
39579
|
+
site,
|
|
39580
|
+
userType,
|
|
39581
|
+
type,
|
|
39582
|
+
search
|
|
39583
|
+
});
|
|
38938
39584
|
return res.status(200).json({ message: "Success", data: result });
|
|
38939
39585
|
} catch (error) {
|
|
38940
39586
|
return res.status(500).json({
|
|
@@ -38980,11 +39626,23 @@ function useAccessManagementController() {
|
|
|
38980
39626
|
userType: import_joi86.default.string().valid(...Object.values(EAccessCardUserTypes)).required(),
|
|
38981
39627
|
type: import_joi86.default.string().valid(...Object.values(EAccessCardTypes)).required()
|
|
38982
39628
|
});
|
|
38983
|
-
const { error } = schema2.validate({
|
|
39629
|
+
const { error } = schema2.validate({
|
|
39630
|
+
accessLevel,
|
|
39631
|
+
liftAccessLevel,
|
|
39632
|
+
site,
|
|
39633
|
+
userType,
|
|
39634
|
+
type
|
|
39635
|
+
});
|
|
38984
39636
|
if (error) {
|
|
38985
39637
|
return res.status(400).json({ message: error.message });
|
|
38986
39638
|
}
|
|
38987
|
-
const result = await accessandLiftCardsSvc({
|
|
39639
|
+
const result = await accessandLiftCardsSvc({
|
|
39640
|
+
accessLevel,
|
|
39641
|
+
liftAccessLevel,
|
|
39642
|
+
site,
|
|
39643
|
+
userType,
|
|
39644
|
+
type
|
|
39645
|
+
});
|
|
38988
39646
|
return res.status(200).json({ message: "Success", data: result });
|
|
38989
39647
|
} catch (error) {
|
|
38990
39648
|
return res.status(500).json({
|
|
@@ -39071,11 +39729,23 @@ function useAccessManagementController() {
|
|
|
39071
39729
|
issuedCardId: import_joi86.default.string().required(),
|
|
39072
39730
|
userId: import_joi86.default.string().hex().required()
|
|
39073
39731
|
});
|
|
39074
|
-
const { error } = schema2.validate({
|
|
39732
|
+
const { error } = schema2.validate({
|
|
39733
|
+
cardId,
|
|
39734
|
+
remarks,
|
|
39735
|
+
unitId,
|
|
39736
|
+
issuedCardId,
|
|
39737
|
+
userId
|
|
39738
|
+
});
|
|
39075
39739
|
if (error) {
|
|
39076
39740
|
return res.status(400).json({ message: error.message });
|
|
39077
39741
|
}
|
|
39078
|
-
const result = await cardReplacementSvc({
|
|
39742
|
+
const result = await cardReplacementSvc({
|
|
39743
|
+
cardId,
|
|
39744
|
+
remarks,
|
|
39745
|
+
unitId,
|
|
39746
|
+
issuedCardId,
|
|
39747
|
+
userId
|
|
39748
|
+
});
|
|
39079
39749
|
return res.status(200).json({ message: "Success", data: result });
|
|
39080
39750
|
} catch (error) {
|
|
39081
39751
|
return res.status(500).json({
|
|
@@ -39104,7 +39774,13 @@ function useAccessManagementController() {
|
|
|
39104
39774
|
if (error) {
|
|
39105
39775
|
return res.status(400).json({ message: error.message });
|
|
39106
39776
|
}
|
|
39107
|
-
const result = await visitorAccessCardsSvc({
|
|
39777
|
+
const result = await visitorAccessCardsSvc({
|
|
39778
|
+
site,
|
|
39779
|
+
page,
|
|
39780
|
+
limit,
|
|
39781
|
+
type,
|
|
39782
|
+
search
|
|
39783
|
+
});
|
|
39108
39784
|
return res.status(200).json({ message: "Success", data: result });
|
|
39109
39785
|
} catch (error) {
|
|
39110
39786
|
return res.status(500).json({
|
|
@@ -39133,11 +39809,27 @@ function useAccessManagementController() {
|
|
|
39133
39809
|
limit: import_joi86.default.number().optional().default(10),
|
|
39134
39810
|
site: import_joi86.default.string().hex().required()
|
|
39135
39811
|
});
|
|
39136
|
-
const { error } = schema2.validate({
|
|
39812
|
+
const { error } = schema2.validate({
|
|
39813
|
+
search,
|
|
39814
|
+
statusFilter,
|
|
39815
|
+
dateFrom,
|
|
39816
|
+
dateTo,
|
|
39817
|
+
page,
|
|
39818
|
+
limit,
|
|
39819
|
+
site
|
|
39820
|
+
});
|
|
39137
39821
|
if (error) {
|
|
39138
39822
|
return res.status(400).json({ message: error.message });
|
|
39139
39823
|
}
|
|
39140
|
-
const result = await getCardReplacementSvc({
|
|
39824
|
+
const result = await getCardReplacementSvc({
|
|
39825
|
+
site,
|
|
39826
|
+
page,
|
|
39827
|
+
limit,
|
|
39828
|
+
search,
|
|
39829
|
+
statusFilter,
|
|
39830
|
+
dateFrom,
|
|
39831
|
+
dateTo
|
|
39832
|
+
});
|
|
39141
39833
|
return res.status(200).json({ message: "Success", data: result });
|
|
39142
39834
|
} catch (error) {
|
|
39143
39835
|
return res.status(500).json({
|
|
@@ -39183,7 +39875,15 @@ function useAccessManagementController() {
|
|
|
39183
39875
|
};
|
|
39184
39876
|
const assignAccessCardToUnit = async (req, res) => {
|
|
39185
39877
|
try {
|
|
39186
|
-
const {
|
|
39878
|
+
const {
|
|
39879
|
+
units,
|
|
39880
|
+
type,
|
|
39881
|
+
quantity,
|
|
39882
|
+
site,
|
|
39883
|
+
userType,
|
|
39884
|
+
accessLevel,
|
|
39885
|
+
liftAccessLevel
|
|
39886
|
+
} = req.body;
|
|
39187
39887
|
const schema2 = import_joi86.default.object({
|
|
39188
39888
|
units: import_joi86.default.array().items(import_joi86.default.string().hex()).required(),
|
|
39189
39889
|
quantity: import_joi86.default.number().required(),
|
|
@@ -39193,11 +39893,27 @@ function useAccessManagementController() {
|
|
|
39193
39893
|
accessLevel: import_joi86.default.string().optional().allow("", null),
|
|
39194
39894
|
liftAccessLevel: import_joi86.default.string().optional().allow("", null)
|
|
39195
39895
|
});
|
|
39196
|
-
const { error } = schema2.validate({
|
|
39896
|
+
const { error } = schema2.validate({
|
|
39897
|
+
units,
|
|
39898
|
+
quantity,
|
|
39899
|
+
type,
|
|
39900
|
+
site,
|
|
39901
|
+
userType,
|
|
39902
|
+
accessLevel,
|
|
39903
|
+
liftAccessLevel
|
|
39904
|
+
});
|
|
39197
39905
|
if (error) {
|
|
39198
39906
|
return res.status(400).json({ message: error.message });
|
|
39199
39907
|
}
|
|
39200
|
-
const result = await assignAccessCardToUnitSvc({
|
|
39908
|
+
const result = await assignAccessCardToUnitSvc({
|
|
39909
|
+
units,
|
|
39910
|
+
quantity,
|
|
39911
|
+
type,
|
|
39912
|
+
site,
|
|
39913
|
+
userType,
|
|
39914
|
+
accessLevel,
|
|
39915
|
+
liftAccessLevel
|
|
39916
|
+
});
|
|
39201
39917
|
return res.status(200).json({ message: "Success", data: result });
|
|
39202
39918
|
} catch (error) {
|
|
39203
39919
|
return res.status(500).json({
|
|
@@ -39295,7 +40011,12 @@ function useAccessManagementController() {
|
|
|
39295
40011
|
};
|
|
39296
40012
|
const availableCardContractors = async (req, res) => {
|
|
39297
40013
|
try {
|
|
39298
|
-
const {
|
|
40014
|
+
const {
|
|
40015
|
+
siteId,
|
|
40016
|
+
unitId,
|
|
40017
|
+
page = 1,
|
|
40018
|
+
limit = 20
|
|
40019
|
+
} = req.query;
|
|
39299
40020
|
const type = req.params.type;
|
|
39300
40021
|
const schema2 = import_joi86.default.object({
|
|
39301
40022
|
siteId: import_joi86.default.string().hex().required(),
|
|
@@ -39308,7 +40029,13 @@ function useAccessManagementController() {
|
|
|
39308
40029
|
if (error) {
|
|
39309
40030
|
return res.status(400).json({ message: error.message });
|
|
39310
40031
|
}
|
|
39311
|
-
const result = await availableCardContractorsSvc({
|
|
40032
|
+
const result = await availableCardContractorsSvc({
|
|
40033
|
+
siteId,
|
|
40034
|
+
unitId,
|
|
40035
|
+
page,
|
|
40036
|
+
limit,
|
|
40037
|
+
type
|
|
40038
|
+
});
|
|
39312
40039
|
return res.status(200).json({ message: "Success", data: result });
|
|
39313
40040
|
} catch (error) {
|
|
39314
40041
|
return res.status(500).json({
|
|
@@ -39319,7 +40046,11 @@ function useAccessManagementController() {
|
|
|
39319
40046
|
};
|
|
39320
40047
|
const vmsgenerateQrCodes = async (req, res) => {
|
|
39321
40048
|
try {
|
|
39322
|
-
const {
|
|
40049
|
+
const {
|
|
40050
|
+
site,
|
|
40051
|
+
unitId,
|
|
40052
|
+
quantity = 100
|
|
40053
|
+
} = req.body;
|
|
39323
40054
|
const schema2 = import_joi86.default.object({
|
|
39324
40055
|
site: import_joi86.default.string().hex().length(24).required(),
|
|
39325
40056
|
unitId: import_joi86.default.string().hex().length(24).required(),
|
|
@@ -39330,7 +40061,12 @@ function useAccessManagementController() {
|
|
|
39330
40061
|
return res.status(400).json({ message: error.message });
|
|
39331
40062
|
}
|
|
39332
40063
|
const normalizedUnitId = [unitId];
|
|
39333
|
-
const result = await vmsgenerateQrCodesSvc({
|
|
40064
|
+
const result = await vmsgenerateQrCodesSvc({
|
|
40065
|
+
site,
|
|
40066
|
+
unitId,
|
|
40067
|
+
normalizedUnitId,
|
|
40068
|
+
quantity
|
|
40069
|
+
});
|
|
39334
40070
|
return res.status(200).json({ message: "Success", data: result });
|
|
39335
40071
|
} catch (error) {
|
|
39336
40072
|
return res.status(500).json({
|
|
@@ -39341,21 +40077,50 @@ function useAccessManagementController() {
|
|
|
39341
40077
|
};
|
|
39342
40078
|
const addVisitorAccessCard = async (req, res) => {
|
|
39343
40079
|
try {
|
|
39344
|
-
const {
|
|
40080
|
+
const {
|
|
40081
|
+
site,
|
|
40082
|
+
unitId,
|
|
40083
|
+
quantity = 1,
|
|
40084
|
+
type,
|
|
40085
|
+
nfcCards,
|
|
40086
|
+
visitorId,
|
|
40087
|
+
acm_url
|
|
40088
|
+
} = req.body;
|
|
39345
40089
|
const schema2 = import_joi86.default.object({
|
|
39346
40090
|
site: import_joi86.default.string().hex().length(24).required(),
|
|
39347
40091
|
unitId: import_joi86.default.string().hex().length(24).required(),
|
|
39348
40092
|
quantity: import_joi86.default.number().allow(null, "").optional(),
|
|
39349
40093
|
type: import_joi86.default.string().required(),
|
|
39350
|
-
nfcCards: import_joi86.default.array().items(
|
|
40094
|
+
nfcCards: import_joi86.default.array().items(
|
|
40095
|
+
import_joi86.default.object({
|
|
40096
|
+
_id: import_joi86.default.string().hex().required(),
|
|
40097
|
+
cardNo: import_joi86.default.string().required()
|
|
40098
|
+
})
|
|
40099
|
+
).required(),
|
|
39351
40100
|
acm_url: import_joi86.default.string().required(),
|
|
39352
40101
|
visitorId: import_joi86.default.string().hex().length(24).required()
|
|
39353
40102
|
});
|
|
39354
|
-
const { error } = schema2.validate({
|
|
40103
|
+
const { error } = schema2.validate({
|
|
40104
|
+
site,
|
|
40105
|
+
unitId,
|
|
40106
|
+
quantity,
|
|
40107
|
+
type,
|
|
40108
|
+
nfcCards,
|
|
40109
|
+
visitorId,
|
|
40110
|
+
acm_url
|
|
40111
|
+
});
|
|
39355
40112
|
if (error) {
|
|
39356
40113
|
return res.status(400).json({ message: error.message });
|
|
39357
40114
|
}
|
|
39358
|
-
const result = await addVisitorAccessCardSvc({
|
|
40115
|
+
const result = await addVisitorAccessCardSvc({
|
|
40116
|
+
site,
|
|
40117
|
+
unitId,
|
|
40118
|
+
quantity,
|
|
40119
|
+
type,
|
|
40120
|
+
nfcCards,
|
|
40121
|
+
visitorId,
|
|
40122
|
+
acm_url
|
|
40123
|
+
});
|
|
39359
40124
|
return res.status(200).json({ message: "Success", data: result });
|
|
39360
40125
|
} catch (error) {
|
|
39361
40126
|
return res.status(500).json({
|
|
@@ -39403,7 +40168,11 @@ function useAccessManagementController() {
|
|
|
39403
40168
|
});
|
|
39404
40169
|
}
|
|
39405
40170
|
};
|
|
39406
|
-
const removeAccessCard = async ({
|
|
40171
|
+
const removeAccessCard = async ({
|
|
40172
|
+
cardNo,
|
|
40173
|
+
staffNo,
|
|
40174
|
+
url
|
|
40175
|
+
}) => {
|
|
39407
40176
|
return removeAccessGroup({ cardNo, staffNo, url });
|
|
39408
40177
|
};
|
|
39409
40178
|
const getBlockLevelAndUnitList = async (req, res) => {
|
|
@@ -39422,7 +40191,13 @@ function useAccessManagementController() {
|
|
|
39422
40191
|
}
|
|
39423
40192
|
};
|
|
39424
40193
|
const getTransactions2 = async (req, res) => {
|
|
39425
|
-
const {
|
|
40194
|
+
const {
|
|
40195
|
+
page = 1,
|
|
40196
|
+
limit = 10,
|
|
40197
|
+
site,
|
|
40198
|
+
cardNo,
|
|
40199
|
+
url
|
|
40200
|
+
} = req.query;
|
|
39426
40201
|
const schema2 = import_joi86.default.object({
|
|
39427
40202
|
page: import_joi86.default.number().required(),
|
|
39428
40203
|
limit: import_joi86.default.number().optional().default(10),
|
|
@@ -39461,7 +40236,12 @@ function useAccessManagementController() {
|
|
|
39461
40236
|
if (error) {
|
|
39462
40237
|
throw new Error(`${error.message}`);
|
|
39463
40238
|
}
|
|
39464
|
-
const result = await assignMultipleCardsSvc({
|
|
40239
|
+
const result = await assignMultipleCardsSvc({
|
|
40240
|
+
assignees,
|
|
40241
|
+
unit,
|
|
40242
|
+
type,
|
|
40243
|
+
acm_url
|
|
40244
|
+
});
|
|
39465
40245
|
return res.status(200).json({ message: "Success", data: result });
|
|
39466
40246
|
} catch (error) {
|
|
39467
40247
|
return res.status(400).json({
|
|
@@ -39504,6 +40284,27 @@ function useAccessManagementController() {
|
|
|
39504
40284
|
});
|
|
39505
40285
|
}
|
|
39506
40286
|
};
|
|
40287
|
+
const getResidents = async (req, res) => {
|
|
40288
|
+
try {
|
|
40289
|
+
const { orgId, siteId, unitId } = req.query;
|
|
40290
|
+
const schema2 = import_joi86.default.object({
|
|
40291
|
+
orgId: import_joi86.default.string().hex().required(),
|
|
40292
|
+
siteId: import_joi86.default.string().hex().required(),
|
|
40293
|
+
unitId: import_joi86.default.string().hex().required()
|
|
40294
|
+
});
|
|
40295
|
+
const { error } = schema2.validate({ orgId, siteId, unitId });
|
|
40296
|
+
if (error) {
|
|
40297
|
+
return res.status(400).json({ message: error.message });
|
|
40298
|
+
}
|
|
40299
|
+
const result = await getResidentsSvc({ orgId, siteId, unitId });
|
|
40300
|
+
return res.status(200).json({ data: result });
|
|
40301
|
+
} catch (error) {
|
|
40302
|
+
return res.status(400).json({
|
|
40303
|
+
data: null,
|
|
40304
|
+
message: error.message
|
|
40305
|
+
});
|
|
40306
|
+
}
|
|
40307
|
+
};
|
|
39507
40308
|
return {
|
|
39508
40309
|
addPhysicalCard,
|
|
39509
40310
|
addNonPhysicalCard,
|
|
@@ -39540,7 +40341,8 @@ function useAccessManagementController() {
|
|
|
39540
40341
|
getTransactions: getTransactions2,
|
|
39541
40342
|
assignMultipleCards,
|
|
39542
40343
|
visitorCheckout,
|
|
39543
|
-
uploadTemplate
|
|
40344
|
+
uploadTemplate,
|
|
40345
|
+
getResidents
|
|
39544
40346
|
};
|
|
39545
40347
|
}
|
|
39546
40348
|
|
|
@@ -54004,6 +54806,207 @@ function usePostPrelovedController() {
|
|
|
54004
54806
|
updateStatus
|
|
54005
54807
|
};
|
|
54006
54808
|
}
|
|
54809
|
+
|
|
54810
|
+
// src/models/online-forms-v2.model.ts
|
|
54811
|
+
var import_joi134 = __toESM(require("joi"));
|
|
54812
|
+
var import_mongodb131 = require("mongodb");
|
|
54813
|
+
var FormEntryStatus = /* @__PURE__ */ ((FormEntryStatus2) => {
|
|
54814
|
+
FormEntryStatus2["ACTIVE"] = "active";
|
|
54815
|
+
FormEntryStatus2["INACTIVE"] = "inactive";
|
|
54816
|
+
FormEntryStatus2["DELETED"] = "deleted";
|
|
54817
|
+
return FormEntryStatus2;
|
|
54818
|
+
})(FormEntryStatus || {});
|
|
54819
|
+
var schemaFormEntry = import_joi134.default.object({
|
|
54820
|
+
_id: import_joi134.default.string().hex().optional().allow("", null),
|
|
54821
|
+
formType: import_joi134.default.string().required(),
|
|
54822
|
+
fields: import_joi134.default.object().pattern(
|
|
54823
|
+
import_joi134.default.string(),
|
|
54824
|
+
import_joi134.default.alternatives().try(
|
|
54825
|
+
import_joi134.default.string(),
|
|
54826
|
+
import_joi134.default.number(),
|
|
54827
|
+
import_joi134.default.boolean(),
|
|
54828
|
+
import_joi134.default.valid(null)
|
|
54829
|
+
)
|
|
54830
|
+
).required(),
|
|
54831
|
+
status: import_joi134.default.string().optional().allow("", null),
|
|
54832
|
+
org: import_joi134.default.string().hex().optional().allow("", null),
|
|
54833
|
+
site: import_joi134.default.string().hex().optional().allow("", null),
|
|
54834
|
+
createdAt: import_joi134.default.date().optional().allow("", null),
|
|
54835
|
+
updatedAt: import_joi134.default.date().optional().allow("", null),
|
|
54836
|
+
deletedAt: import_joi134.default.date().optional().allow("", null)
|
|
54837
|
+
});
|
|
54838
|
+
var schemaUpdateFormEntry = import_joi134.default.object({
|
|
54839
|
+
_id: import_joi134.default.string().hex().required(),
|
|
54840
|
+
formType: import_joi134.default.string().optional().allow("", null),
|
|
54841
|
+
fields: import_joi134.default.object().pattern(
|
|
54842
|
+
import_joi134.default.string(),
|
|
54843
|
+
import_joi134.default.alternatives().try(
|
|
54844
|
+
import_joi134.default.string(),
|
|
54845
|
+
import_joi134.default.number(),
|
|
54846
|
+
import_joi134.default.boolean(),
|
|
54847
|
+
import_joi134.default.valid(null)
|
|
54848
|
+
)
|
|
54849
|
+
).optional(),
|
|
54850
|
+
status: import_joi134.default.string().optional().allow("", null),
|
|
54851
|
+
createdAt: import_joi134.default.date().optional().allow("", null),
|
|
54852
|
+
updatedAt: import_joi134.default.date().optional().allow("", null),
|
|
54853
|
+
deletedAt: import_joi134.default.date().optional().allow("", null)
|
|
54854
|
+
});
|
|
54855
|
+
function MFormEntry(value) {
|
|
54856
|
+
const { error } = schemaFormEntry.validate(value);
|
|
54857
|
+
if (error) {
|
|
54858
|
+
throw new Error(error.details[0].message);
|
|
54859
|
+
}
|
|
54860
|
+
if (value._id && typeof value._id === "string") {
|
|
54861
|
+
try {
|
|
54862
|
+
value._id = new import_mongodb131.ObjectId(value._id);
|
|
54863
|
+
} catch {
|
|
54864
|
+
throw new Error("Invalid ID.");
|
|
54865
|
+
}
|
|
54866
|
+
}
|
|
54867
|
+
if (value.org && typeof value.org === "string") {
|
|
54868
|
+
try {
|
|
54869
|
+
value.org = new import_mongodb131.ObjectId(value.org);
|
|
54870
|
+
} catch {
|
|
54871
|
+
throw new Error("Invalid org ID.");
|
|
54872
|
+
}
|
|
54873
|
+
}
|
|
54874
|
+
if (value.site && typeof value.site === "string") {
|
|
54875
|
+
try {
|
|
54876
|
+
value.site = new import_mongodb131.ObjectId(value.site);
|
|
54877
|
+
} catch {
|
|
54878
|
+
throw new Error("Invalid site ID.");
|
|
54879
|
+
}
|
|
54880
|
+
}
|
|
54881
|
+
return {
|
|
54882
|
+
_id: value._id,
|
|
54883
|
+
formType: value.formType,
|
|
54884
|
+
fields: value.fields,
|
|
54885
|
+
status: value.status,
|
|
54886
|
+
org: value.org,
|
|
54887
|
+
site: value.site,
|
|
54888
|
+
createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
|
|
54889
|
+
updatedAt: value.updatedAt ?? null,
|
|
54890
|
+
deletedAt: value.deletedAt ?? null
|
|
54891
|
+
};
|
|
54892
|
+
}
|
|
54893
|
+
|
|
54894
|
+
// src/repositories/online-forms-v2.repository.ts
|
|
54895
|
+
var import_node_server_utils234 = require("@7365admin1/node-server-utils");
|
|
54896
|
+
var online_forms_namespace_collection = "online-forms";
|
|
54897
|
+
function useFormEntryRepo() {
|
|
54898
|
+
const db = import_node_server_utils234.useAtlas.getDb();
|
|
54899
|
+
if (!db) {
|
|
54900
|
+
throw new import_node_server_utils234.InternalServerError("Unable to connect to server.");
|
|
54901
|
+
}
|
|
54902
|
+
const collection = db.collection(online_forms_namespace_collection);
|
|
54903
|
+
const { delNamespace, getCache, setCache } = (0, import_node_server_utils234.useCache)(
|
|
54904
|
+
online_forms_namespace_collection
|
|
54905
|
+
);
|
|
54906
|
+
async function createTextIndex() {
|
|
54907
|
+
try {
|
|
54908
|
+
await collection.createIndex({
|
|
54909
|
+
name: "text"
|
|
54910
|
+
});
|
|
54911
|
+
} catch (error) {
|
|
54912
|
+
throw new import_node_server_utils234.InternalServerError(
|
|
54913
|
+
"Failed to create text index on online form."
|
|
54914
|
+
);
|
|
54915
|
+
}
|
|
54916
|
+
}
|
|
54917
|
+
async function add(value, session) {
|
|
54918
|
+
try {
|
|
54919
|
+
value = MFormEntry(value);
|
|
54920
|
+
const res = await collection.insertOne(value, { session });
|
|
54921
|
+
delNamespace().then(() => {
|
|
54922
|
+
import_node_server_utils234.logger.info(
|
|
54923
|
+
`Cache cleared for namespace: ${online_forms_namespace_collection}`
|
|
54924
|
+
);
|
|
54925
|
+
}).catch((err) => {
|
|
54926
|
+
import_node_server_utils234.logger.error(
|
|
54927
|
+
`Failed to clear cache for namespace: ${online_forms_namespace_collection}`,
|
|
54928
|
+
err
|
|
54929
|
+
);
|
|
54930
|
+
});
|
|
54931
|
+
return res.insertedId;
|
|
54932
|
+
} catch (error) {
|
|
54933
|
+
const isDuplicated = error.message.includes("duplicate");
|
|
54934
|
+
if (isDuplicated) {
|
|
54935
|
+
throw new import_node_server_utils234.BadRequestError("Online Form already exists.");
|
|
54936
|
+
}
|
|
54937
|
+
throw error;
|
|
54938
|
+
}
|
|
54939
|
+
}
|
|
54940
|
+
return {
|
|
54941
|
+
add,
|
|
54942
|
+
createTextIndex
|
|
54943
|
+
};
|
|
54944
|
+
}
|
|
54945
|
+
|
|
54946
|
+
// src/controllers/online-forms-v2.controller.ts
|
|
54947
|
+
var import_node_server_utils235 = require("@7365admin1/node-server-utils");
|
|
54948
|
+
var import_exceljs3 = __toESM(require("exceljs"));
|
|
54949
|
+
var import_fs6 = __toESM(require("fs"));
|
|
54950
|
+
function useFormEntryController() {
|
|
54951
|
+
const { add: _add } = useFormEntryRepo();
|
|
54952
|
+
function toCamelCase(str) {
|
|
54953
|
+
return str.replace(/\s(.)/g, (_, char) => char.toUpperCase()).replace(/\s+/g, "").replace(/^(.)/, (_, char) => char.toLowerCase());
|
|
54954
|
+
}
|
|
54955
|
+
function normalizeKeys(obj) {
|
|
54956
|
+
const normalized = {};
|
|
54957
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
54958
|
+
normalized[toCamelCase(key)] = value;
|
|
54959
|
+
}
|
|
54960
|
+
return normalized;
|
|
54961
|
+
}
|
|
54962
|
+
async function uploadFormEntrys(req, res, next) {
|
|
54963
|
+
try {
|
|
54964
|
+
if (!req.file) {
|
|
54965
|
+
next(new import_node_server_utils235.BadRequestError("Excel file is required."));
|
|
54966
|
+
return;
|
|
54967
|
+
}
|
|
54968
|
+
const workbook = new import_exceljs3.default.Workbook();
|
|
54969
|
+
await workbook.xlsx.readFile(req.file.path);
|
|
54970
|
+
const worksheet = workbook.worksheets[0];
|
|
54971
|
+
if (!worksheet) {
|
|
54972
|
+
next(new import_node_server_utils235.BadRequestError("No worksheet found in uploaded Excel file."));
|
|
54973
|
+
return;
|
|
54974
|
+
}
|
|
54975
|
+
const headerRow = worksheet.getRow(1);
|
|
54976
|
+
const headers = headerRow.values.slice(1).map((h) => String(h ?? "").trim());
|
|
54977
|
+
const fields = {};
|
|
54978
|
+
headers.forEach((header) => {
|
|
54979
|
+
fields[header] = null;
|
|
54980
|
+
});
|
|
54981
|
+
const formType = req.file.originalname.replace(/\.[^/.]+$/, "");
|
|
54982
|
+
const normalizedFields = normalizeKeys(fields);
|
|
54983
|
+
const payload = {
|
|
54984
|
+
formType,
|
|
54985
|
+
fields: normalizedFields,
|
|
54986
|
+
status: "active" /* ACTIVE */
|
|
54987
|
+
};
|
|
54988
|
+
const { error, value } = schemaFormEntry.validate(payload, {
|
|
54989
|
+
abortEarly: false
|
|
54990
|
+
});
|
|
54991
|
+
if (error) {
|
|
54992
|
+
const messages = error.details.map((d) => d.message).join(", ");
|
|
54993
|
+
import_node_server_utils235.logger.log({ level: "error", message: messages });
|
|
54994
|
+
next(new import_node_server_utils235.BadRequestError(messages));
|
|
54995
|
+
return;
|
|
54996
|
+
}
|
|
54997
|
+
const result = await _add(value);
|
|
54998
|
+
res.status(201).json(result);
|
|
54999
|
+
import_fs6.default.unlink(req.file.path, () => {
|
|
55000
|
+
});
|
|
55001
|
+
} catch (error) {
|
|
55002
|
+
import_node_server_utils235.logger.log({ level: "error", message: error.message });
|
|
55003
|
+
next(error);
|
|
55004
|
+
}
|
|
55005
|
+
}
|
|
55006
|
+
return {
|
|
55007
|
+
uploadFormEntrys
|
|
55008
|
+
};
|
|
55009
|
+
}
|
|
54007
55010
|
// Annotate the CommonJS export names for ESM import in node:
|
|
54008
55011
|
0 && (module.exports = {
|
|
54009
55012
|
ANPRMode,
|
|
@@ -54031,6 +55034,7 @@ function usePostPrelovedController() {
|
|
|
54031
55034
|
EventType,
|
|
54032
55035
|
FacilitySort,
|
|
54033
55036
|
FacilityStatus,
|
|
55037
|
+
FormEntryStatus,
|
|
54034
55038
|
GuestSort,
|
|
54035
55039
|
GuestStatus,
|
|
54036
55040
|
MAccessCard,
|
|
@@ -54052,6 +55056,7 @@ function usePostPrelovedController() {
|
|
|
54052
55056
|
MEventManagement,
|
|
54053
55057
|
MFeedback,
|
|
54054
55058
|
MFile,
|
|
55059
|
+
MFormEntry,
|
|
54055
55060
|
MGuestManagement,
|
|
54056
55061
|
MIncidentReport,
|
|
54057
55062
|
MManpowerDesignations,
|
|
@@ -54163,6 +55168,7 @@ function usePostPrelovedController() {
|
|
|
54163
55168
|
nfcPatrolSettingsSchema,
|
|
54164
55169
|
nfcPatrolSettingsSchemaUpdate,
|
|
54165
55170
|
occurrence_book_namespace_collection,
|
|
55171
|
+
online_forms_namespace_collection,
|
|
54166
55172
|
orgSchema,
|
|
54167
55173
|
overnight_parking_requests_namespace_collection,
|
|
54168
55174
|
parseDahuaFind,
|
|
@@ -54187,6 +55193,7 @@ function usePostPrelovedController() {
|
|
|
54187
55193
|
schemaEntryPassSettings,
|
|
54188
55194
|
schemaEventManagement,
|
|
54189
55195
|
schemaFiles,
|
|
55196
|
+
schemaFormEntry,
|
|
54190
55197
|
schemaGuestManagement,
|
|
54191
55198
|
schemaIncidentReport,
|
|
54192
55199
|
schemaNfcPatrolLog,
|
|
@@ -54217,6 +55224,7 @@ function usePostPrelovedController() {
|
|
|
54217
55224
|
schemaUpdateDocumentManagement,
|
|
54218
55225
|
schemaUpdateEntryPassSettings,
|
|
54219
55226
|
schemaUpdateEventManagement,
|
|
55227
|
+
schemaUpdateFormEntry,
|
|
54220
55228
|
schemaUpdateGuestManagement,
|
|
54221
55229
|
schemaUpdateIncidentReport,
|
|
54222
55230
|
schemaUpdateOccurrenceBook,
|
|
@@ -54300,6 +55308,8 @@ function usePostPrelovedController() {
|
|
|
54300
55308
|
useFileController,
|
|
54301
55309
|
useFileRepo,
|
|
54302
55310
|
useFileService,
|
|
55311
|
+
useFormEntryController,
|
|
55312
|
+
useFormEntryRepo,
|
|
54303
55313
|
useGuestManagementController,
|
|
54304
55314
|
useGuestManagementRepo,
|
|
54305
55315
|
useGuestManagementService,
|