@7365admin1/core 2.8.0 → 2.10.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 +12 -0
- package/dist/index.d.ts +98 -8
- package/dist/index.js +758 -82
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +830 -151
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -36,6 +36,7 @@ __export(src_exports, {
|
|
|
36
36
|
EAccessCardUserTypes: () => EAccessCardUserTypes,
|
|
37
37
|
MAccessCard: () => MAccessCard,
|
|
38
38
|
MAccessCardTransaction: () => MAccessCardTransaction,
|
|
39
|
+
MAddress: () => MAddress,
|
|
39
40
|
MAttendance: () => MAttendance,
|
|
40
41
|
MAttendanceSettings: () => MAttendanceSettings,
|
|
41
42
|
MBillingConfiguration: () => MBillingConfiguration,
|
|
@@ -170,6 +171,7 @@ __export(src_exports, {
|
|
|
170
171
|
siteSchema: () => siteSchema,
|
|
171
172
|
tokenSchema: () => tokenSchema,
|
|
172
173
|
useAccessManagementController: () => useAccessManagementController,
|
|
174
|
+
useAddressRepo: () => useAddressRepo,
|
|
173
175
|
useAttendanceController: () => useAttendanceController,
|
|
174
176
|
useAttendanceRepository: () => useAttendanceRepository,
|
|
175
177
|
useAttendanceSettingsController: () => useAttendanceSettingsController,
|
|
@@ -669,7 +671,8 @@ function useFeedbackRepo() {
|
|
|
669
671
|
query.$or = [
|
|
670
672
|
{ subject: { $regex: search, $options: "i" } },
|
|
671
673
|
{ description: { $regex: search, $options: "i" } },
|
|
672
|
-
{ createdByName: { $regex: search, $options: "i" } }
|
|
674
|
+
{ createdByName: { $regex: search, $options: "i" } },
|
|
675
|
+
{ category: { $regex: search, $options: "i" } }
|
|
673
676
|
];
|
|
674
677
|
cacheOptions.search = search;
|
|
675
678
|
}
|
|
@@ -1281,7 +1284,9 @@ function useWorkOrderRepo() {
|
|
|
1281
1284
|
if (search) {
|
|
1282
1285
|
query.$or = [
|
|
1283
1286
|
{ subject: { $regex: search, $options: "i" } },
|
|
1284
|
-
{ createdByName: { $regex: search, $options: "i" } }
|
|
1287
|
+
{ createdByName: { $regex: search, $options: "i" } },
|
|
1288
|
+
{ description: { $regex: search, $options: "i" } },
|
|
1289
|
+
{ category: { $regex: search, $options: "i" } }
|
|
1285
1290
|
];
|
|
1286
1291
|
cacheOptions.search = search;
|
|
1287
1292
|
}
|
|
@@ -2084,6 +2089,14 @@ function useOccurrenceEntryRepo() {
|
|
|
2084
2089
|
throw new Error("Invalid signature ID.");
|
|
2085
2090
|
}
|
|
2086
2091
|
}
|
|
2092
|
+
if (value.incidentReportId && typeof value.incidentReportId === "string") {
|
|
2093
|
+
try {
|
|
2094
|
+
value.incidentReportId = new import_mongodb7.ObjectId(value.incidentReportId);
|
|
2095
|
+
} catch {
|
|
2096
|
+
throw new Error("Invalid incident report ID.");
|
|
2097
|
+
}
|
|
2098
|
+
}
|
|
2099
|
+
console.log("Updating occurrence entry:", _id, value);
|
|
2087
2100
|
try {
|
|
2088
2101
|
const res = await collection.updateOne(
|
|
2089
2102
|
{ _id },
|
|
@@ -3463,7 +3476,8 @@ var allowedFieldsSite = [
|
|
|
3463
3476
|
"metadata.block",
|
|
3464
3477
|
"metadata.guardPosts",
|
|
3465
3478
|
"metadata.gracePeriod",
|
|
3466
|
-
"metadata.incidentCounter"
|
|
3479
|
+
"metadata.incidentCounter",
|
|
3480
|
+
"metadata.incidentLogo"
|
|
3467
3481
|
];
|
|
3468
3482
|
var siteSchema = import_joi8.default.object({
|
|
3469
3483
|
name: import_joi8.default.string().required(),
|
|
@@ -10921,7 +10935,8 @@ function useFeedbackController() {
|
|
|
10921
10935
|
}
|
|
10922
10936
|
async function deleteFeedback(req, res, next) {
|
|
10923
10937
|
const validation = import_joi28.default.string().hex().required();
|
|
10924
|
-
const _id = req.
|
|
10938
|
+
const _id = req.query.id;
|
|
10939
|
+
console.log(_id);
|
|
10925
10940
|
const { error } = validation.validate(_id);
|
|
10926
10941
|
if (error) {
|
|
10927
10942
|
import_node_server_utils55.logger.log({ level: "error", message: error.message });
|
|
@@ -11285,7 +11300,8 @@ function useWorkOrderController() {
|
|
|
11285
11300
|
}
|
|
11286
11301
|
async function deleteWorkOrder(req, res, next) {
|
|
11287
11302
|
const validation = import_joi29.default.string().hex().required();
|
|
11288
|
-
const _id = req.
|
|
11303
|
+
const _id = req.query.id;
|
|
11304
|
+
console.log(_id);
|
|
11289
11305
|
const { error } = validation.validate(_id);
|
|
11290
11306
|
if (error) {
|
|
11291
11307
|
import_node_server_utils57.logger.log({ level: "error", message: error.message });
|
|
@@ -12796,7 +12812,7 @@ function useSiteController() {
|
|
|
12796
12812
|
const validation = import_joi36.default.object({
|
|
12797
12813
|
_id: import_joi36.default.string().hex().required(),
|
|
12798
12814
|
field: import_joi36.default.string().valid(...allowedFieldsSite).required(),
|
|
12799
|
-
value: import_joi36.default.number().integer().min(0).required()
|
|
12815
|
+
value: import_joi36.default.alternatives().try(import_joi36.default.number().integer().min(0), import_joi36.default.string().hex().length(24)).required()
|
|
12800
12816
|
});
|
|
12801
12817
|
const _id = req.params.id ?? "";
|
|
12802
12818
|
const field = req.body.field ?? "";
|
|
@@ -12998,8 +13014,8 @@ var schemaBuildingUnit = import_joi38.default.object({
|
|
|
12998
13014
|
buildingUnitFiles: import_joi38.default.array().items(import_joi38.default.string()).optional().allow("", null),
|
|
12999
13015
|
companyName: import_joi38.default.string().optional().allow("", null),
|
|
13000
13016
|
companyRegistrationNumber: import_joi38.default.string().optional().allow("", null),
|
|
13001
|
-
leaseStart: import_joi38.default.date().
|
|
13002
|
-
leaseEnd: import_joi38.default.date().
|
|
13017
|
+
leaseStart: import_joi38.default.date().optional(),
|
|
13018
|
+
leaseEnd: import_joi38.default.date().optional(),
|
|
13003
13019
|
owner: import_joi38.default.string().hex().optional().allow("", null),
|
|
13004
13020
|
ownerName: import_joi38.default.string().optional().allow("", null),
|
|
13005
13021
|
billing: import_joi38.default.array().items(schemaBilling).optional().allow("", null)
|
|
@@ -14341,8 +14357,8 @@ function useBuildingUnitController() {
|
|
|
14341
14357
|
buildingUnitFiles: import_joi40.default.array().items(import_joi40.default.string()).optional(),
|
|
14342
14358
|
companyName: import_joi40.default.string().optional().allow("", null),
|
|
14343
14359
|
companyRegistrationNumber: import_joi40.default.string().optional().allow("", null),
|
|
14344
|
-
leaseStart: import_joi40.default.date().
|
|
14345
|
-
leaseEnd: import_joi40.default.date().
|
|
14360
|
+
leaseStart: import_joi40.default.date().optional(),
|
|
14361
|
+
leaseEnd: import_joi40.default.date().optional()
|
|
14346
14362
|
}),
|
|
14347
14363
|
qty: import_joi40.default.number().integer().min(1).max(20).optional().default(1)
|
|
14348
14364
|
});
|
|
@@ -17523,7 +17539,11 @@ function useAttendanceSettingsRepository() {
|
|
|
17523
17539
|
isLocationEnabled: 1,
|
|
17524
17540
|
location: 1,
|
|
17525
17541
|
isGeofencingEnabled: 1,
|
|
17526
|
-
mile: 1
|
|
17542
|
+
mile: 1,
|
|
17543
|
+
postalCode: 1,
|
|
17544
|
+
country: 1,
|
|
17545
|
+
city: 1,
|
|
17546
|
+
address: 1
|
|
17527
17547
|
}
|
|
17528
17548
|
}
|
|
17529
17549
|
]).toArray();
|
|
@@ -27042,11 +27062,11 @@ var EAccessCardTypes = /* @__PURE__ */ ((EAccessCardTypes2) => {
|
|
|
27042
27062
|
EAccessCardTypes2["QR"] = "QRCODE";
|
|
27043
27063
|
return EAccessCardTypes2;
|
|
27044
27064
|
})(EAccessCardTypes || {});
|
|
27045
|
-
var EAccessCardUserTypes = /* @__PURE__ */ ((
|
|
27046
|
-
|
|
27047
|
-
|
|
27048
|
-
|
|
27049
|
-
return
|
|
27065
|
+
var EAccessCardUserTypes = /* @__PURE__ */ ((EAccessCardUserTypes4) => {
|
|
27066
|
+
EAccessCardUserTypes4["RESIDENT"] = "Resident/Tenant";
|
|
27067
|
+
EAccessCardUserTypes4["CONTRACTOR"] = "Contractor";
|
|
27068
|
+
EAccessCardUserTypes4["VISITOR"] = "Visitor";
|
|
27069
|
+
return EAccessCardUserTypes4;
|
|
27050
27070
|
})(EAccessCardUserTypes || {});
|
|
27051
27071
|
var AccessTypeProps = /* @__PURE__ */ ((AccessTypeProps2) => {
|
|
27052
27072
|
AccessTypeProps2["NORMAL"] = "Normal";
|
|
@@ -27108,7 +27128,8 @@ var MAccessCard = class {
|
|
|
27108
27128
|
doorName,
|
|
27109
27129
|
liftName,
|
|
27110
27130
|
replacementStatus,
|
|
27111
|
-
vmsRemarks
|
|
27131
|
+
vmsRemarks,
|
|
27132
|
+
isWinsland = false
|
|
27112
27133
|
} = {}) {
|
|
27113
27134
|
this._id = _id;
|
|
27114
27135
|
this.userId = userId;
|
|
@@ -27135,6 +27156,7 @@ var MAccessCard = class {
|
|
|
27135
27156
|
this.liftName = liftName;
|
|
27136
27157
|
this.replacementStatus = replacementStatus;
|
|
27137
27158
|
this.vmsRemarks = vmsRemarks;
|
|
27159
|
+
this.isWinsland = isWinsland;
|
|
27138
27160
|
}
|
|
27139
27161
|
};
|
|
27140
27162
|
|
|
@@ -27184,6 +27206,15 @@ function UseAccessManagementRepo() {
|
|
|
27184
27206
|
return Promise.reject("Failed to create Access cards indexes.");
|
|
27185
27207
|
}
|
|
27186
27208
|
}
|
|
27209
|
+
async function createIndexForEntrypass() {
|
|
27210
|
+
try {
|
|
27211
|
+
const entrypass = collectionName("entrypass-settings");
|
|
27212
|
+
await Promise.all([entrypass.createIndex({ site: 1 })]);
|
|
27213
|
+
return Promise.resolve("Access cards indexes created.");
|
|
27214
|
+
} catch (error) {
|
|
27215
|
+
return Promise.reject("Failed to create Access cards indexes.");
|
|
27216
|
+
}
|
|
27217
|
+
}
|
|
27187
27218
|
async function addPhysicalCardRepo({
|
|
27188
27219
|
payload
|
|
27189
27220
|
}) {
|
|
@@ -27274,7 +27305,8 @@ function UseAccessManagementRepo() {
|
|
|
27274
27305
|
liftName: params.liftName,
|
|
27275
27306
|
assignedUnit: new import_mongodb83.ObjectId(units[i]),
|
|
27276
27307
|
createdAt: new Date(params.createdAt),
|
|
27277
|
-
updatedAt: new Date(params.updatedAt)
|
|
27308
|
+
updatedAt: new Date(params.updatedAt),
|
|
27309
|
+
isWinsland: params.isWinsland
|
|
27278
27310
|
});
|
|
27279
27311
|
try {
|
|
27280
27312
|
const result = await collection().insertOne(newCard);
|
|
@@ -27326,7 +27358,8 @@ function UseAccessManagementRepo() {
|
|
|
27326
27358
|
liftName: params.liftName,
|
|
27327
27359
|
assignedUnit: null,
|
|
27328
27360
|
createdAt: new Date(params.createdAt),
|
|
27329
|
-
updatedAt: new Date(params.updatedAt)
|
|
27361
|
+
updatedAt: new Date(params.updatedAt),
|
|
27362
|
+
isWinsland: params.isWinsland
|
|
27330
27363
|
});
|
|
27331
27364
|
try {
|
|
27332
27365
|
const result = await collection().insertOne(newCard);
|
|
@@ -27358,10 +27391,362 @@ function UseAccessManagementRepo() {
|
|
|
27358
27391
|
throw new Error(error.message);
|
|
27359
27392
|
}
|
|
27360
27393
|
}
|
|
27394
|
+
async function accessManagementSettingsRepo(params) {
|
|
27395
|
+
try {
|
|
27396
|
+
params.site = new import_mongodb83.ObjectId(params.site);
|
|
27397
|
+
const result = collectionName("entrypass-settings").updateOne(
|
|
27398
|
+
{ site: params.site },
|
|
27399
|
+
{
|
|
27400
|
+
$set: {
|
|
27401
|
+
...params,
|
|
27402
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
27403
|
+
},
|
|
27404
|
+
$setOnInsert: {
|
|
27405
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
27406
|
+
}
|
|
27407
|
+
},
|
|
27408
|
+
{ upsert: true }
|
|
27409
|
+
);
|
|
27410
|
+
await createIndexForEntrypass();
|
|
27411
|
+
return result;
|
|
27412
|
+
} catch (error) {
|
|
27413
|
+
throw new Error(error.message);
|
|
27414
|
+
}
|
|
27415
|
+
}
|
|
27416
|
+
async function allAccessCardsCountsRepo(params) {
|
|
27417
|
+
try {
|
|
27418
|
+
const site = new import_mongodb83.ObjectId(params.site);
|
|
27419
|
+
const userType = params.userType;
|
|
27420
|
+
const result = await collection().aggregate([
|
|
27421
|
+
{
|
|
27422
|
+
$match: { site, userType }
|
|
27423
|
+
},
|
|
27424
|
+
{
|
|
27425
|
+
$facet: {
|
|
27426
|
+
available_physical: [{ $match: { assignedUnit: { $eq: null }, type: "NFC" /* NFC */ } }, { $count: "count" }],
|
|
27427
|
+
available_non_physical: [{ $match: { assignedUnit: { $eq: null }, type: "QRCODE" /* QR */ } }, { $count: "count" }],
|
|
27428
|
+
assigned_physical: [{ $match: { assignedUnit: { $ne: null }, type: "NFC" /* NFC */ } }, { $count: "count" }],
|
|
27429
|
+
assigned_non_physical: [{ $match: { assignedUnit: { $ne: null }, type: "QRCODE" /* QR */ } }, { $count: "count" }]
|
|
27430
|
+
}
|
|
27431
|
+
}
|
|
27432
|
+
]).toArray();
|
|
27433
|
+
const totalCardCount = {
|
|
27434
|
+
available_physical: result[0].available_physical[0] ? result[0].available_physical[0].count : 0,
|
|
27435
|
+
available_non_physical: result[0].available_non_physical[0] ? result[0].available_non_physical[0].count : 0,
|
|
27436
|
+
assigned_physical: result[0].assigned_physical[0] ? result[0].assigned_physical[0].count : 0,
|
|
27437
|
+
assigned_non_physical: result[0].assigned_non_physical[0] ? result[0].assigned_non_physical[0].count : 0
|
|
27438
|
+
};
|
|
27439
|
+
return totalCardCount;
|
|
27440
|
+
} catch (error) {
|
|
27441
|
+
throw new Error(error.message);
|
|
27442
|
+
}
|
|
27443
|
+
}
|
|
27444
|
+
async function availableAccessCardsRepo(params) {
|
|
27445
|
+
try {
|
|
27446
|
+
const site = new import_mongodb83.ObjectId(params.site);
|
|
27447
|
+
const userType = params.userType;
|
|
27448
|
+
const type = params.type;
|
|
27449
|
+
const query = {
|
|
27450
|
+
site: { $in: [site] },
|
|
27451
|
+
userType,
|
|
27452
|
+
assignedUnit: null,
|
|
27453
|
+
type,
|
|
27454
|
+
isActivated: true
|
|
27455
|
+
};
|
|
27456
|
+
const result = await collection().aggregate([
|
|
27457
|
+
{
|
|
27458
|
+
$match: { ...query }
|
|
27459
|
+
},
|
|
27460
|
+
{
|
|
27461
|
+
$project: {
|
|
27462
|
+
accessLevel: 1,
|
|
27463
|
+
liftAccessLevel: 1,
|
|
27464
|
+
doorName: 1,
|
|
27465
|
+
liftName: 1
|
|
27466
|
+
}
|
|
27467
|
+
},
|
|
27468
|
+
{
|
|
27469
|
+
$group: {
|
|
27470
|
+
_id: {
|
|
27471
|
+
accessLevel: "$accessLevel",
|
|
27472
|
+
liftAccessLevel: "$liftAccessLevel",
|
|
27473
|
+
doorName: "$doorName",
|
|
27474
|
+
liftName: "$liftName"
|
|
27475
|
+
},
|
|
27476
|
+
count: { $sum: 1 }
|
|
27477
|
+
}
|
|
27478
|
+
},
|
|
27479
|
+
{
|
|
27480
|
+
$project: {
|
|
27481
|
+
_id: 0,
|
|
27482
|
+
accessLevel: "$_id.accessLevel",
|
|
27483
|
+
liftAccessLevel: "$_id.liftAccessLevel",
|
|
27484
|
+
doorName: "$_id.doorName",
|
|
27485
|
+
liftName: "$_id.liftName",
|
|
27486
|
+
count: 1
|
|
27487
|
+
}
|
|
27488
|
+
}
|
|
27489
|
+
]).toArray();
|
|
27490
|
+
return result;
|
|
27491
|
+
} catch (error) {
|
|
27492
|
+
throw new Error(error.message);
|
|
27493
|
+
}
|
|
27494
|
+
}
|
|
27495
|
+
function buildSearchQuery(search) {
|
|
27496
|
+
if (!search) {
|
|
27497
|
+
return {};
|
|
27498
|
+
}
|
|
27499
|
+
const terms = search.split("/").map((s) => s.trim()).filter(Boolean);
|
|
27500
|
+
if (search.includes("/") && terms.length <= 3) {
|
|
27501
|
+
switch (terms.length) {
|
|
27502
|
+
case 3:
|
|
27503
|
+
return {
|
|
27504
|
+
$and: [
|
|
27505
|
+
{ $expr: { $eq: [{ $toLower: "$name" }, terms[0].toLowerCase()] } },
|
|
27506
|
+
{ $expr: { $eq: [{ $toLower: "$level.level" }, terms[1].toLowerCase()] } },
|
|
27507
|
+
{ $expr: { $eq: [{ $toLower: "$level.units.name" }, terms[2].toLowerCase()] } }
|
|
27508
|
+
]
|
|
27509
|
+
};
|
|
27510
|
+
case 2:
|
|
27511
|
+
return {
|
|
27512
|
+
$and: [
|
|
27513
|
+
{ $expr: { $eq: [{ $toLower: "$name" }, terms[0].toLowerCase()] } },
|
|
27514
|
+
{ $expr: { $eq: [{ $toLower: "$level.level" }, terms[1].toLowerCase()] } }
|
|
27515
|
+
]
|
|
27516
|
+
};
|
|
27517
|
+
default:
|
|
27518
|
+
return {
|
|
27519
|
+
$expr: { $eq: [{ $toLower: "$name" }, terms[0].toLowerCase()] }
|
|
27520
|
+
};
|
|
27521
|
+
}
|
|
27522
|
+
}
|
|
27523
|
+
return {
|
|
27524
|
+
$or: [
|
|
27525
|
+
{ name: { $regex: search.trim(), $options: "i" } },
|
|
27526
|
+
{ "level.level": { $regex: search.trim(), $options: "i" } },
|
|
27527
|
+
{ "level.units.name": { $regex: search.trim(), $options: "i" } }
|
|
27528
|
+
]
|
|
27529
|
+
};
|
|
27530
|
+
}
|
|
27531
|
+
async function userTypeAccessCardsRepo(params) {
|
|
27532
|
+
try {
|
|
27533
|
+
const site = new import_mongodb83.ObjectId(params.site);
|
|
27534
|
+
const userType = params.userType;
|
|
27535
|
+
const page = params.page ? Number(params.page) - 1 : 0;
|
|
27536
|
+
const limit = Number(params.limit) || 10;
|
|
27537
|
+
const search = params.search;
|
|
27538
|
+
const defaultQuery = {
|
|
27539
|
+
site
|
|
27540
|
+
};
|
|
27541
|
+
const searchQuery = buildSearchQuery(search);
|
|
27542
|
+
const result = await collectionName("buildings").aggregate([
|
|
27543
|
+
// ✅ Match early with index-friendly query
|
|
27544
|
+
{
|
|
27545
|
+
$match: {
|
|
27546
|
+
...defaultQuery,
|
|
27547
|
+
status: { $ne: "deleted" }
|
|
27548
|
+
}
|
|
27549
|
+
},
|
|
27550
|
+
// ✅ Only project needed fields before heavy lookups
|
|
27551
|
+
{
|
|
27552
|
+
$project: {
|
|
27553
|
+
_id: 1,
|
|
27554
|
+
name: 1,
|
|
27555
|
+
site: 1
|
|
27556
|
+
}
|
|
27557
|
+
},
|
|
27558
|
+
// ✅ Use localField/foreignField for better index usage
|
|
27559
|
+
{
|
|
27560
|
+
$lookup: {
|
|
27561
|
+
from: "building-levels",
|
|
27562
|
+
localField: "_id",
|
|
27563
|
+
foreignField: "block",
|
|
27564
|
+
pipeline: [
|
|
27565
|
+
{ $match: { status: { $ne: "deleted" } } },
|
|
27566
|
+
{
|
|
27567
|
+
$lookup: {
|
|
27568
|
+
from: "building-units",
|
|
27569
|
+
localField: "_id",
|
|
27570
|
+
foreignField: "level",
|
|
27571
|
+
pipeline: [
|
|
27572
|
+
{ $match: { status: { $ne: "deleted" } } },
|
|
27573
|
+
{ $project: { _id: 1, name: 1 } }
|
|
27574
|
+
],
|
|
27575
|
+
as: "units"
|
|
27576
|
+
}
|
|
27577
|
+
},
|
|
27578
|
+
{
|
|
27579
|
+
$match: { "units.0": { $exists: true } }
|
|
27580
|
+
},
|
|
27581
|
+
{
|
|
27582
|
+
$project: {
|
|
27583
|
+
_id: 1,
|
|
27584
|
+
level: 1,
|
|
27585
|
+
units: 1
|
|
27586
|
+
}
|
|
27587
|
+
}
|
|
27588
|
+
],
|
|
27589
|
+
as: "level"
|
|
27590
|
+
}
|
|
27591
|
+
},
|
|
27592
|
+
// ✅ Filter out buildings with no levels early
|
|
27593
|
+
{
|
|
27594
|
+
$match: { "level.0": { $exists: true } }
|
|
27595
|
+
},
|
|
27596
|
+
// ✅ Unwind to flatten the hierarchy
|
|
27597
|
+
{
|
|
27598
|
+
$unwind: {
|
|
27599
|
+
path: "$level",
|
|
27600
|
+
preserveNullAndEmptyArrays: false
|
|
27601
|
+
}
|
|
27602
|
+
},
|
|
27603
|
+
{
|
|
27604
|
+
$unwind: {
|
|
27605
|
+
path: "$level.units",
|
|
27606
|
+
preserveNullAndEmptyArrays: false
|
|
27607
|
+
}
|
|
27608
|
+
},
|
|
27609
|
+
// Groups by unit _id and keeps only the first occurrence
|
|
27610
|
+
{
|
|
27611
|
+
$group: {
|
|
27612
|
+
_id: "$level.units._id",
|
|
27613
|
+
doc: { $first: "$$ROOT" }
|
|
27614
|
+
}
|
|
27615
|
+
},
|
|
27616
|
+
{
|
|
27617
|
+
$replaceRoot: { newRoot: "$doc" }
|
|
27618
|
+
},
|
|
27619
|
+
// ✅ Apply search filter
|
|
27620
|
+
{
|
|
27621
|
+
$match: {
|
|
27622
|
+
...searchQuery
|
|
27623
|
+
}
|
|
27624
|
+
},
|
|
27625
|
+
{
|
|
27626
|
+
$facet: {
|
|
27627
|
+
totalCount: [{ $count: "count" }],
|
|
27628
|
+
items: [
|
|
27629
|
+
// ✅ Sort BEFORE skip/limit for correct pagination
|
|
27630
|
+
{ $sort: { _id: -1 } },
|
|
27631
|
+
{ $skip: page * limit },
|
|
27632
|
+
{ $limit: limit },
|
|
27633
|
+
// ✅ Users lookup - optimized with index hint
|
|
27634
|
+
{
|
|
27635
|
+
$lookup: {
|
|
27636
|
+
from: "users",
|
|
27637
|
+
let: { unit: "$level.units._id" },
|
|
27638
|
+
pipeline: [
|
|
27639
|
+
{
|
|
27640
|
+
$match: {
|
|
27641
|
+
$expr: { $eq: ["$unitNumber", "$$unit"] },
|
|
27642
|
+
residentType: "House/Unit Owner"
|
|
27643
|
+
}
|
|
27644
|
+
},
|
|
27645
|
+
{ $limit: 1 },
|
|
27646
|
+
{ $project: { _id: 1, givenName: 1, surname: 1 } }
|
|
27647
|
+
],
|
|
27648
|
+
as: "unitOwner"
|
|
27649
|
+
}
|
|
27650
|
+
},
|
|
27651
|
+
// ✅ Access card lookup - optimized query
|
|
27652
|
+
{
|
|
27653
|
+
$lookup: {
|
|
27654
|
+
from: "access-cards",
|
|
27655
|
+
let: { unit: "$level.units._id" },
|
|
27656
|
+
pipeline: [
|
|
27657
|
+
{
|
|
27658
|
+
$match: {
|
|
27659
|
+
$expr: {
|
|
27660
|
+
$in: [
|
|
27661
|
+
"$$unit",
|
|
27662
|
+
{ $cond: [{ $isArray: "$assignedUnit" }, "$assignedUnit", ["$assignedUnit"]] }
|
|
27663
|
+
]
|
|
27664
|
+
},
|
|
27665
|
+
userType
|
|
27666
|
+
}
|
|
27667
|
+
},
|
|
27668
|
+
{ $project: { _id: 1, userId: 1, type: 1, cardNo: 1, isActivated: 1 } }
|
|
27669
|
+
],
|
|
27670
|
+
as: "accessCards"
|
|
27671
|
+
}
|
|
27672
|
+
},
|
|
27673
|
+
// ✅ Compute all card categorization and counts in ONE stage
|
|
27674
|
+
{
|
|
27675
|
+
$addFields: {
|
|
27676
|
+
f_Available: {
|
|
27677
|
+
$filter: {
|
|
27678
|
+
input: "$accessCards",
|
|
27679
|
+
as: "card",
|
|
27680
|
+
cond: { $and: [{ $eq: ["$$card.userId", null] }, { $eq: ["$$card.isActivated", true] }] }
|
|
27681
|
+
}
|
|
27682
|
+
},
|
|
27683
|
+
f_Assigned: {
|
|
27684
|
+
$filter: {
|
|
27685
|
+
input: "$accessCards",
|
|
27686
|
+
as: "card",
|
|
27687
|
+
cond: { $ne: ["$$card.userId", null] }
|
|
27688
|
+
}
|
|
27689
|
+
}
|
|
27690
|
+
}
|
|
27691
|
+
},
|
|
27692
|
+
// ✅ Final projection with all computed fields
|
|
27693
|
+
{
|
|
27694
|
+
$project: {
|
|
27695
|
+
_id: "$level.units._id",
|
|
27696
|
+
name: "$level.units.name",
|
|
27697
|
+
level: { _id: "$level._id", level: "$level.level" },
|
|
27698
|
+
block: { _id: "$_id", name: "$name" },
|
|
27699
|
+
site: "$site",
|
|
27700
|
+
unit_owner: { $arrayElemAt: ["$unitOwner", 0] },
|
|
27701
|
+
available: {
|
|
27702
|
+
physical: { $filter: { input: "$f_Available", as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } },
|
|
27703
|
+
non_physical: { $filter: { input: "$f_Available", as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } }
|
|
27704
|
+
},
|
|
27705
|
+
assigned: {
|
|
27706
|
+
physical: { $filter: { input: "$f_Assigned", as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } },
|
|
27707
|
+
non_physical: { $filter: { input: "$f_Assigned", as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } }
|
|
27708
|
+
},
|
|
27709
|
+
cardCounts: {
|
|
27710
|
+
available: {
|
|
27711
|
+
physical: { $size: { $filter: { input: { $ifNull: ["$f_Available", []] }, as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } } },
|
|
27712
|
+
non_physical: { $size: { $filter: { input: { $ifNull: ["$f_Available", []] }, as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } } }
|
|
27713
|
+
},
|
|
27714
|
+
assigned: {
|
|
27715
|
+
physical: { $size: { $filter: { input: { $ifNull: ["$f_Assigned", []] }, as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } } },
|
|
27716
|
+
non_physical: { $size: { $filter: { input: { $ifNull: ["$f_Assigned", []] }, as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } } }
|
|
27717
|
+
}
|
|
27718
|
+
},
|
|
27719
|
+
totalCardCount: {
|
|
27720
|
+
$add: [
|
|
27721
|
+
{ $size: { $filter: { input: { $ifNull: ["$f_Available", []] }, as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } } },
|
|
27722
|
+
{ $size: { $filter: { input: { $ifNull: ["$f_Available", []] }, as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } } },
|
|
27723
|
+
{ $size: { $filter: { input: { $ifNull: ["$f_Assigned", []] }, as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } } },
|
|
27724
|
+
{ $size: { $filter: { input: { $ifNull: ["$f_Assigned", []] }, as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } } }
|
|
27725
|
+
]
|
|
27726
|
+
}
|
|
27727
|
+
}
|
|
27728
|
+
}
|
|
27729
|
+
]
|
|
27730
|
+
}
|
|
27731
|
+
}
|
|
27732
|
+
], { allowDiskUse: true }).toArray();
|
|
27733
|
+
const totalCount = result[0]?.totalCount?.[0]?.count ?? 0;
|
|
27734
|
+
const items = result[0]?.items ?? [];
|
|
27735
|
+
const paginatedResult = (0, import_node_server_utils149.paginate)(items, page, limit, totalCount);
|
|
27736
|
+
return paginatedResult;
|
|
27737
|
+
} catch (error) {
|
|
27738
|
+
throw new Error(error.message);
|
|
27739
|
+
}
|
|
27740
|
+
}
|
|
27361
27741
|
return {
|
|
27362
27742
|
createIndexes,
|
|
27743
|
+
createIndexForEntrypass,
|
|
27363
27744
|
addPhysicalCardRepo,
|
|
27364
|
-
addNonPhysicalCardRepo
|
|
27745
|
+
addNonPhysicalCardRepo,
|
|
27746
|
+
accessManagementSettingsRepo,
|
|
27747
|
+
allAccessCardsCountsRepo,
|
|
27748
|
+
availableAccessCardsRepo,
|
|
27749
|
+
userTypeAccessCardsRepo
|
|
27365
27750
|
};
|
|
27366
27751
|
}
|
|
27367
27752
|
|
|
@@ -27467,7 +27852,14 @@ var formatAccessGroup = (data, search) => {
|
|
|
27467
27852
|
// src/services/access-management.service.ts
|
|
27468
27853
|
var import_xml2js = require("xml2js");
|
|
27469
27854
|
function useAccessManagementSvc() {
|
|
27470
|
-
const {
|
|
27855
|
+
const {
|
|
27856
|
+
addPhysicalCardRepo,
|
|
27857
|
+
addNonPhysicalCardRepo,
|
|
27858
|
+
accessManagementSettingsRepo,
|
|
27859
|
+
allAccessCardsCountsRepo,
|
|
27860
|
+
availableAccessCardsRepo,
|
|
27861
|
+
userTypeAccessCardsRepo
|
|
27862
|
+
} = UseAccessManagementRepo();
|
|
27471
27863
|
const addPhysicalCardSvc = async (payload) => {
|
|
27472
27864
|
try {
|
|
27473
27865
|
const response = await addPhysicalCardRepo({ payload });
|
|
@@ -27514,7 +27906,39 @@ function useAccessManagementSvc() {
|
|
|
27514
27906
|
const format = await formatAccessGroup(res);
|
|
27515
27907
|
return format;
|
|
27516
27908
|
} catch (err) {
|
|
27517
|
-
|
|
27909
|
+
throw new Error(err.message);
|
|
27910
|
+
}
|
|
27911
|
+
};
|
|
27912
|
+
const accessManagementSettingsSvc = async (settings) => {
|
|
27913
|
+
try {
|
|
27914
|
+
const response = await accessManagementSettingsRepo({ ...settings });
|
|
27915
|
+
return response;
|
|
27916
|
+
} catch (err) {
|
|
27917
|
+
throw new Error(err.message);
|
|
27918
|
+
}
|
|
27919
|
+
};
|
|
27920
|
+
const allAccessCardsCountsSvc = async (params) => {
|
|
27921
|
+
try {
|
|
27922
|
+
const response = await allAccessCardsCountsRepo({ ...params });
|
|
27923
|
+
return response;
|
|
27924
|
+
} catch (err) {
|
|
27925
|
+
throw new Error(err.message);
|
|
27926
|
+
}
|
|
27927
|
+
};
|
|
27928
|
+
const availableAccessCardsSvc = async (params) => {
|
|
27929
|
+
try {
|
|
27930
|
+
const response = await availableAccessCardsRepo({ ...params });
|
|
27931
|
+
return response;
|
|
27932
|
+
} catch (err) {
|
|
27933
|
+
throw new Error(err.message);
|
|
27934
|
+
}
|
|
27935
|
+
};
|
|
27936
|
+
const userTypeAccessCardsSvc = async (params) => {
|
|
27937
|
+
try {
|
|
27938
|
+
const response = await userTypeAccessCardsRepo({ ...params });
|
|
27939
|
+
return response;
|
|
27940
|
+
} catch (err) {
|
|
27941
|
+
throw new Error(err.message);
|
|
27518
27942
|
}
|
|
27519
27943
|
};
|
|
27520
27944
|
return {
|
|
@@ -27522,7 +27946,11 @@ function useAccessManagementSvc() {
|
|
|
27522
27946
|
addNonPhysicalCardSvc,
|
|
27523
27947
|
doorAccessLevelsSvc,
|
|
27524
27948
|
liftAccessLevelsSvc,
|
|
27525
|
-
accessGroupsSvc
|
|
27949
|
+
accessGroupsSvc,
|
|
27950
|
+
accessManagementSettingsSvc,
|
|
27951
|
+
allAccessCardsCountsSvc,
|
|
27952
|
+
availableAccessCardsSvc,
|
|
27953
|
+
userTypeAccessCardsSvc
|
|
27526
27954
|
};
|
|
27527
27955
|
}
|
|
27528
27956
|
|
|
@@ -27533,7 +27961,11 @@ function useAccessManagementController() {
|
|
|
27533
27961
|
addNonPhysicalCardSvc,
|
|
27534
27962
|
doorAccessLevelsSvc,
|
|
27535
27963
|
liftAccessLevelsSvc,
|
|
27536
|
-
accessGroupsSvc
|
|
27964
|
+
accessGroupsSvc,
|
|
27965
|
+
accessManagementSettingsSvc,
|
|
27966
|
+
allAccessCardsCountsSvc,
|
|
27967
|
+
availableAccessCardsSvc,
|
|
27968
|
+
userTypeAccessCardsSvc
|
|
27537
27969
|
} = useAccessManagementSvc();
|
|
27538
27970
|
const addPhysicalCard = async (req, res) => {
|
|
27539
27971
|
try {
|
|
@@ -27593,7 +28025,8 @@ function useAccessManagementController() {
|
|
|
27593
28025
|
createdAt,
|
|
27594
28026
|
updatedAt,
|
|
27595
28027
|
startDate,
|
|
27596
|
-
endDate
|
|
28028
|
+
endDate,
|
|
28029
|
+
isWinsland
|
|
27597
28030
|
} = req.body;
|
|
27598
28031
|
const schema2 = import_joi85.default.object({
|
|
27599
28032
|
site: import_joi85.default.string().hex().required(),
|
|
@@ -27609,7 +28042,8 @@ function useAccessManagementController() {
|
|
|
27609
28042
|
startDate: import_joi85.default.date().required(),
|
|
27610
28043
|
endDate: import_joi85.default.date().required(),
|
|
27611
28044
|
createdAt: import_joi85.default.date().required(),
|
|
27612
|
-
updatedAt: import_joi85.default.date().required()
|
|
28045
|
+
updatedAt: import_joi85.default.date().required(),
|
|
28046
|
+
isWinsland: import_joi85.default.boolean().optional().allow(null)
|
|
27613
28047
|
});
|
|
27614
28048
|
const { error } = schema2.validate({
|
|
27615
28049
|
site,
|
|
@@ -27625,7 +28059,8 @@ function useAccessManagementController() {
|
|
|
27625
28059
|
startDate,
|
|
27626
28060
|
endDate,
|
|
27627
28061
|
createdAt,
|
|
27628
|
-
updatedAt
|
|
28062
|
+
updatedAt,
|
|
28063
|
+
isWinsland
|
|
27629
28064
|
});
|
|
27630
28065
|
if (error) {
|
|
27631
28066
|
throw new Error(`${error.message}`);
|
|
@@ -27644,7 +28079,8 @@ function useAccessManagementController() {
|
|
|
27644
28079
|
startDate,
|
|
27645
28080
|
endDate,
|
|
27646
28081
|
createdAt,
|
|
27647
|
-
updatedAt
|
|
28082
|
+
updatedAt,
|
|
28083
|
+
isWinsland
|
|
27648
28084
|
});
|
|
27649
28085
|
return res.status(201).json({
|
|
27650
28086
|
data: result,
|
|
@@ -27702,12 +28138,100 @@ function useAccessManagementController() {
|
|
|
27702
28138
|
});
|
|
27703
28139
|
}
|
|
27704
28140
|
};
|
|
28141
|
+
const accessManagementSettings = async (req, res) => {
|
|
28142
|
+
try {
|
|
28143
|
+
const settings = req.body;
|
|
28144
|
+
const result = await accessManagementSettingsSvc(settings);
|
|
28145
|
+
return res.status(201).json({ message: "Success", data: result });
|
|
28146
|
+
} catch (error) {
|
|
28147
|
+
return res.status(400).json({
|
|
28148
|
+
data: null,
|
|
28149
|
+
message: error.message
|
|
28150
|
+
});
|
|
28151
|
+
}
|
|
28152
|
+
};
|
|
28153
|
+
const allAccessCardsCounts = async (req, res) => {
|
|
28154
|
+
try {
|
|
28155
|
+
const { site, userType } = req.query;
|
|
28156
|
+
const schema2 = import_joi85.default.object({
|
|
28157
|
+
site: import_joi85.default.string().hex().required(),
|
|
28158
|
+
userType: import_joi85.default.string().required()
|
|
28159
|
+
});
|
|
28160
|
+
const { error } = schema2.validate({ site, userType });
|
|
28161
|
+
if (error) {
|
|
28162
|
+
throw new Error(`${error.message}`);
|
|
28163
|
+
}
|
|
28164
|
+
const result = await allAccessCardsCountsSvc({ site, userType });
|
|
28165
|
+
return res.status(200).json({ message: "Success", data: result });
|
|
28166
|
+
} catch (error) {
|
|
28167
|
+
return res.status(400).json({
|
|
28168
|
+
data: null,
|
|
28169
|
+
message: error.message
|
|
28170
|
+
});
|
|
28171
|
+
}
|
|
28172
|
+
};
|
|
28173
|
+
const availableAccessCards = async (req, res) => {
|
|
28174
|
+
try {
|
|
28175
|
+
const { site, userType, type } = req.query;
|
|
28176
|
+
const schema2 = import_joi85.default.object({
|
|
28177
|
+
site: import_joi85.default.string().hex().required(),
|
|
28178
|
+
userType: import_joi85.default.string().optional().allow("", null),
|
|
28179
|
+
type: import_joi85.default.string().optional().allow("", null)
|
|
28180
|
+
});
|
|
28181
|
+
const { error } = schema2.validate({ site, userType, type });
|
|
28182
|
+
if (error) {
|
|
28183
|
+
return res.status(400).json({ message: error.message });
|
|
28184
|
+
}
|
|
28185
|
+
const result = await availableAccessCardsSvc({ site, userType, type });
|
|
28186
|
+
return res.status(200).json({ message: "Success", data: result });
|
|
28187
|
+
} catch (error) {
|
|
28188
|
+
return res.status(400).json({
|
|
28189
|
+
data: null,
|
|
28190
|
+
message: error.message
|
|
28191
|
+
});
|
|
28192
|
+
}
|
|
28193
|
+
};
|
|
28194
|
+
const userTypeAccessCards = async (req, res) => {
|
|
28195
|
+
try {
|
|
28196
|
+
const {
|
|
28197
|
+
page = 1,
|
|
28198
|
+
limit = 10,
|
|
28199
|
+
search = "",
|
|
28200
|
+
site,
|
|
28201
|
+
organization,
|
|
28202
|
+
userType
|
|
28203
|
+
} = req.query;
|
|
28204
|
+
const schema2 = import_joi85.default.object({
|
|
28205
|
+
page: import_joi85.default.number().required(),
|
|
28206
|
+
limit: import_joi85.default.number().optional().default(10),
|
|
28207
|
+
site: import_joi85.default.string().hex().required(),
|
|
28208
|
+
organization: import_joi85.default.string().hex().optional().allow("", null),
|
|
28209
|
+
search: import_joi85.default.string().optional().allow("", null),
|
|
28210
|
+
userType: import_joi85.default.string().required()
|
|
28211
|
+
});
|
|
28212
|
+
const { error } = schema2.validate({ page, limit, site, organization, search, userType });
|
|
28213
|
+
if (error) {
|
|
28214
|
+
return res.status(400).json({ message: error.message });
|
|
28215
|
+
}
|
|
28216
|
+
const result = await userTypeAccessCardsSvc({ page, limit, search, site, organization, userType });
|
|
28217
|
+
return res.status(200).json({ message: "Success", data: result });
|
|
28218
|
+
} catch (error) {
|
|
28219
|
+
return res.status(500).json({
|
|
28220
|
+
data: null,
|
|
28221
|
+
message: error.message
|
|
28222
|
+
});
|
|
28223
|
+
}
|
|
28224
|
+
};
|
|
27705
28225
|
return {
|
|
27706
28226
|
addPhysicalCard,
|
|
27707
28227
|
addNonPhysicalCard,
|
|
27708
28228
|
doorAccessLevels,
|
|
27709
28229
|
liftAccessLevels,
|
|
27710
|
-
accessGroups
|
|
28230
|
+
accessGroups,
|
|
28231
|
+
accessManagementSettings,
|
|
28232
|
+
allAccessCardsCounts,
|
|
28233
|
+
availableAccessCards,
|
|
28234
|
+
userTypeAccessCards
|
|
27711
28235
|
};
|
|
27712
28236
|
}
|
|
27713
28237
|
|
|
@@ -29701,6 +30225,7 @@ function useStatementOfAccountService() {
|
|
|
29701
30225
|
try {
|
|
29702
30226
|
const browser = await (0, import_puppeteer.launch)({
|
|
29703
30227
|
headless: true,
|
|
30228
|
+
executablePath: process.env.CHROME_BINARY,
|
|
29704
30229
|
args: [`--no-sandbox`, `--disable-gpu`, `--disable-dev-shm-usage`]
|
|
29705
30230
|
});
|
|
29706
30231
|
const page = await browser.newPage();
|
|
@@ -31325,6 +31850,27 @@ var actionStatusSchema = import_joi99.default.object({
|
|
|
31325
31850
|
status: import_joi99.default.string().optional(),
|
|
31326
31851
|
time: import_joi99.default.string().optional()
|
|
31327
31852
|
});
|
|
31853
|
+
var affectedInjuredStatusSchema = import_joi99.default.object({
|
|
31854
|
+
name: import_joi99.default.string().required(),
|
|
31855
|
+
contact: import_joi99.default.string().optional().allow(null, ""),
|
|
31856
|
+
nric: import_joi99.default.string().optional().allow(null, "")
|
|
31857
|
+
});
|
|
31858
|
+
var anyoneDamageToPropertyStatusSchema = import_joi99.default.object({
|
|
31859
|
+
description: import_joi99.default.string().optional().allow(null, ""),
|
|
31860
|
+
block: import_joi99.default.number().optional().allow(null, ""),
|
|
31861
|
+
level: import_joi99.default.string().optional().allow(null, ""),
|
|
31862
|
+
unit: import_joi99.default.string().optional().allow(null, ""),
|
|
31863
|
+
blkLevelUnit: import_joi99.default.string().optional().allow(null, ""),
|
|
31864
|
+
name: import_joi99.default.string().optional().allow(null, ""),
|
|
31865
|
+
contact: import_joi99.default.string().optional().allow(null, "")
|
|
31866
|
+
});
|
|
31867
|
+
var authoritiesCalledStatusSchema = import_joi99.default.object({
|
|
31868
|
+
type: import_joi99.default.string().optional().allow(null, ""),
|
|
31869
|
+
vehicleNumber: import_joi99.default.string().optional().allow(null, ""),
|
|
31870
|
+
personInCharge: import_joi99.default.string().optional().allow(null, ""),
|
|
31871
|
+
caseReportReference: import_joi99.default.string().optional().allow(null, ""),
|
|
31872
|
+
description: import_joi99.default.string().optional().allow(null, "")
|
|
31873
|
+
});
|
|
31328
31874
|
var schemaIncidentReport = import_joi99.default.object({
|
|
31329
31875
|
reportId: import_joi99.default.string().required(),
|
|
31330
31876
|
incidentInformation: import_joi99.default.object({
|
|
@@ -31337,7 +31883,7 @@ var schemaIncidentReport = import_joi99.default.object({
|
|
|
31337
31883
|
placeOfIncident: import_joi99.default.object({
|
|
31338
31884
|
block: import_joi99.default.number().optional().allow(null, ""),
|
|
31339
31885
|
level: import_joi99.default.string().optional().allow(null, ""),
|
|
31340
|
-
unit: import_joi99.default.string().
|
|
31886
|
+
unit: import_joi99.default.string().optional().allow(null, ""),
|
|
31341
31887
|
other: import_joi99.default.string().allow(null, "").optional().allow(null, ""),
|
|
31342
31888
|
isOther: import_joi99.default.boolean().required(),
|
|
31343
31889
|
incidentLocation: import_joi99.default.string().optional().allow(null, "")
|
|
@@ -31374,13 +31920,13 @@ var schemaIncidentReport = import_joi99.default.object({
|
|
|
31374
31920
|
anyUnitAffectedValue: import_joi99.default.string().valid("yes", "no").required(),
|
|
31375
31921
|
affectedUnit: import_joi99.default.any().optional(),
|
|
31376
31922
|
anyoneAffectedValue: import_joi99.default.string().valid("yes", "no").required(),
|
|
31377
|
-
affectedInjured: import_joi99.default.array().items(
|
|
31923
|
+
affectedInjured: import_joi99.default.array().items(affectedInjuredStatusSchema).optional().allow(null, ""),
|
|
31378
31924
|
anyPropertyAffectedValue: import_joi99.default.string().valid("yes", "no").required(),
|
|
31379
|
-
anyoneDamageToProperty: import_joi99.default.array().items(
|
|
31380
|
-
}).
|
|
31925
|
+
anyoneDamageToProperty: import_joi99.default.array().items(anyoneDamageToPropertyStatusSchema).optional()
|
|
31926
|
+
}).optional().allow(null, ""),
|
|
31381
31927
|
authorities: import_joi99.default.object({
|
|
31382
31928
|
authoritiesValue: import_joi99.default.string().valid("yes", "no").required(),
|
|
31383
|
-
authoritiesCalled: import_joi99.default.array().items(
|
|
31929
|
+
authoritiesCalled: import_joi99.default.array().items(authoritiesCalledStatusSchema).optional().allow(null, ""),
|
|
31384
31930
|
incidentThereAfter: import_joi99.default.string().optional().allow("", null),
|
|
31385
31931
|
managementNotified: actionStatusSchema.optional(),
|
|
31386
31932
|
incidentResolved: import_joi99.default.string().optional().allow("", null),
|
|
@@ -31404,7 +31950,7 @@ var schemaIncidentReport = import_joi99.default.object({
|
|
|
31404
31950
|
photos: import_joi99.default.array().items(import_joi99.default.string()).optional(),
|
|
31405
31951
|
approvedBy: import_joi99.default.string().hex().allow(null, "").optional(),
|
|
31406
31952
|
approvedByName: import_joi99.default.string().optional().allow("", null),
|
|
31407
|
-
|
|
31953
|
+
remarks: import_joi99.default.string().optional().allow("", null),
|
|
31408
31954
|
status: import_joi99.default.string().valid("pending", "approved", "rejected").default("pending")
|
|
31409
31955
|
});
|
|
31410
31956
|
var schemaUpdateIncidentReport = import_joi99.default.object({
|
|
@@ -31419,7 +31965,7 @@ var schemaUpdateIncidentReport = import_joi99.default.object({
|
|
|
31419
31965
|
placeOfIncident: import_joi99.default.object({
|
|
31420
31966
|
block: import_joi99.default.number().optional().allow(null, ""),
|
|
31421
31967
|
level: import_joi99.default.string().optional().allow(null, ""),
|
|
31422
|
-
unit: import_joi99.default.string().
|
|
31968
|
+
unit: import_joi99.default.string().optional().allow(null, ""),
|
|
31423
31969
|
other: import_joi99.default.string().allow(null, "").optional().allow(null, ""),
|
|
31424
31970
|
isOther: import_joi99.default.boolean().allow(null, ""),
|
|
31425
31971
|
incidentLocation: import_joi99.default.string().optional().allow(null, "")
|
|
@@ -31456,13 +32002,13 @@ var schemaUpdateIncidentReport = import_joi99.default.object({
|
|
|
31456
32002
|
anyUnitAffectedValue: import_joi99.default.string().valid("yes", "no").allow(null, ""),
|
|
31457
32003
|
affectedUnit: import_joi99.default.any().optional(),
|
|
31458
32004
|
anyoneAffectedValue: import_joi99.default.string().valid("yes", "no").allow(null, ""),
|
|
31459
|
-
affectedInjured: import_joi99.default.array().items(
|
|
32005
|
+
affectedInjured: import_joi99.default.array().items(affectedInjuredStatusSchema).optional().allow(null, ""),
|
|
31460
32006
|
anyPropertyAffectedValue: import_joi99.default.string().valid("yes", "no").allow(null, ""),
|
|
31461
|
-
anyoneDamageToProperty: import_joi99.default.array().items(
|
|
31462
|
-
}).allow(null, ""),
|
|
32007
|
+
anyoneDamageToProperty: import_joi99.default.array().items(anyoneDamageToPropertyStatusSchema).optional().allow(null, "")
|
|
32008
|
+
}).optional().allow(null, ""),
|
|
31463
32009
|
authorities: import_joi99.default.object({
|
|
31464
32010
|
authoritiesValue: import_joi99.default.string().valid("yes", "no").allow(null, ""),
|
|
31465
|
-
authoritiesCalled: import_joi99.default.array().items(
|
|
32011
|
+
authoritiesCalled: import_joi99.default.array().items(authoritiesCalledStatusSchema).optional().allow(null, ""),
|
|
31466
32012
|
incidentThereAfter: import_joi99.default.string().optional().allow("", null),
|
|
31467
32013
|
managementNotified: actionStatusSchema.optional(),
|
|
31468
32014
|
incidentResolved: import_joi99.default.string().optional().allow("", null),
|
|
@@ -31486,7 +32032,7 @@ var schemaUpdateIncidentReport = import_joi99.default.object({
|
|
|
31486
32032
|
photos: import_joi99.default.array().items(import_joi99.default.string()).optional(),
|
|
31487
32033
|
approvedBy: import_joi99.default.string().hex().allow(null, "").optional(),
|
|
31488
32034
|
approvedByName: import_joi99.default.string().optional().allow("", null),
|
|
31489
|
-
|
|
32035
|
+
remarks: import_joi99.default.string().optional().allow("", null),
|
|
31490
32036
|
status: import_joi99.default.string().valid("pending", "approved", "rejected").default("pending")
|
|
31491
32037
|
});
|
|
31492
32038
|
function MIncidentReport(value) {
|
|
@@ -31528,14 +32074,6 @@ function MIncidentReport(value) {
|
|
|
31528
32074
|
throw new Error("Invalid siteInfo.site ID.");
|
|
31529
32075
|
}
|
|
31530
32076
|
}
|
|
31531
|
-
const place = incidentInformation?.placeOfIncident;
|
|
31532
|
-
if (place?.unit && typeof place.unit === "string") {
|
|
31533
|
-
try {
|
|
31534
|
-
place.unit = new import_mongodb96.ObjectId(place.unit);
|
|
31535
|
-
} catch {
|
|
31536
|
-
throw new Error("Invalid unit ID.");
|
|
31537
|
-
}
|
|
31538
|
-
}
|
|
31539
32077
|
if (incidentInformation?.incidentTypeAndTime?.dateOfIncident && typeof incidentInformation.incidentTypeAndTime.dateOfIncident !== "string") {
|
|
31540
32078
|
incidentInformation.incidentTypeAndTime.dateOfIncident = incidentInformation.incidentTypeAndTime.dateOfIncident.toISOString();
|
|
31541
32079
|
}
|
|
@@ -31557,7 +32095,7 @@ function MIncidentReport(value) {
|
|
|
31557
32095
|
photos: value.photos ?? [],
|
|
31558
32096
|
approvedBy: value.approvedBy ?? null,
|
|
31559
32097
|
approvedByName: value.approvedByName ?? "",
|
|
31560
|
-
|
|
32098
|
+
remarks: value.remarks ?? null,
|
|
31561
32099
|
status: value.status ?? "pending",
|
|
31562
32100
|
createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
|
|
31563
32101
|
updatedAt: value.updatedAt,
|
|
@@ -31756,6 +32294,37 @@ function useIncidentReportRepo() {
|
|
|
31756
32294
|
} catch (error) {
|
|
31757
32295
|
throw new import_node_server_utils173.BadRequestError("Invalid ID format.");
|
|
31758
32296
|
}
|
|
32297
|
+
if (value.organization && typeof value.organization === "string") {
|
|
32298
|
+
try {
|
|
32299
|
+
value.organization = new import_mongodb97.ObjectId(value.organization);
|
|
32300
|
+
} catch {
|
|
32301
|
+
throw new Error("Invalid organization ID.");
|
|
32302
|
+
}
|
|
32303
|
+
}
|
|
32304
|
+
if (value.site && typeof value.site === "string") {
|
|
32305
|
+
try {
|
|
32306
|
+
value.site = new import_mongodb97.ObjectId(value.site);
|
|
32307
|
+
} catch {
|
|
32308
|
+
throw new Error("Invalid site ID.");
|
|
32309
|
+
}
|
|
32310
|
+
}
|
|
32311
|
+
if (value.approvedBy && typeof value.approvedBy === "string") {
|
|
32312
|
+
try {
|
|
32313
|
+
value.approvedBy = new import_mongodb97.ObjectId(value.approvedBy);
|
|
32314
|
+
} catch {
|
|
32315
|
+
throw new Error("Invalid approvedBy ID.");
|
|
32316
|
+
}
|
|
32317
|
+
}
|
|
32318
|
+
const { incidentInformation } = value;
|
|
32319
|
+
if (incidentInformation?.siteInfo?.site && typeof incidentInformation.siteInfo.site === "string") {
|
|
32320
|
+
try {
|
|
32321
|
+
incidentInformation.siteInfo.site = new import_mongodb97.ObjectId(
|
|
32322
|
+
incidentInformation.siteInfo.site
|
|
32323
|
+
);
|
|
32324
|
+
} catch {
|
|
32325
|
+
throw new Error("Invalid siteInfo.site ID.");
|
|
32326
|
+
}
|
|
32327
|
+
}
|
|
31759
32328
|
try {
|
|
31760
32329
|
const res = await collection.updateOne(
|
|
31761
32330
|
{ _id },
|
|
@@ -31809,6 +32378,37 @@ function useIncidentReportRepo() {
|
|
|
31809
32378
|
throw error;
|
|
31810
32379
|
}
|
|
31811
32380
|
}
|
|
32381
|
+
async function reviewIncidentReport(_id, value, session) {
|
|
32382
|
+
value.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
32383
|
+
try {
|
|
32384
|
+
_id = new import_mongodb97.ObjectId(_id);
|
|
32385
|
+
} catch (error) {
|
|
32386
|
+
throw new import_node_server_utils173.BadRequestError("Invalid ID format.");
|
|
32387
|
+
}
|
|
32388
|
+
try {
|
|
32389
|
+
const res = await collection.updateOne(
|
|
32390
|
+
{ _id },
|
|
32391
|
+
{ $set: value },
|
|
32392
|
+
{ session }
|
|
32393
|
+
);
|
|
32394
|
+
if (res.modifiedCount === 0) {
|
|
32395
|
+
throw new import_node_server_utils173.InternalServerError(
|
|
32396
|
+
`Unable to ${value.status} incident report.`
|
|
32397
|
+
);
|
|
32398
|
+
}
|
|
32399
|
+
delNamespace().then(() => {
|
|
32400
|
+
import_node_server_utils173.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
32401
|
+
}).catch((err) => {
|
|
32402
|
+
import_node_server_utils173.logger.error(
|
|
32403
|
+
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
32404
|
+
err
|
|
32405
|
+
);
|
|
32406
|
+
});
|
|
32407
|
+
return res;
|
|
32408
|
+
} catch (error) {
|
|
32409
|
+
throw error;
|
|
32410
|
+
}
|
|
32411
|
+
}
|
|
31812
32412
|
return {
|
|
31813
32413
|
add,
|
|
31814
32414
|
getAll,
|
|
@@ -31816,20 +32416,29 @@ function useIncidentReportRepo() {
|
|
|
31816
32416
|
updateIncidentReportById,
|
|
31817
32417
|
deleteIncidentReportById,
|
|
31818
32418
|
createIndexes,
|
|
31819
|
-
createTextIndex
|
|
32419
|
+
createTextIndex,
|
|
32420
|
+
reviewIncidentReport
|
|
31820
32421
|
};
|
|
31821
32422
|
}
|
|
31822
32423
|
|
|
31823
32424
|
// src/services/incident-report.service.ts
|
|
31824
32425
|
var import_openai = __toESM(require("openai"));
|
|
31825
32426
|
function useIncidentReportService() {
|
|
31826
|
-
const {
|
|
32427
|
+
const {
|
|
32428
|
+
add: _add,
|
|
32429
|
+
updateIncidentReportById: _updateIncidentReportById,
|
|
32430
|
+
reviewIncidentReport: _reviewIncidentReport,
|
|
32431
|
+
getIncidentReportById: _getIncidentReportById
|
|
32432
|
+
} = useIncidentReportRepo();
|
|
31827
32433
|
const {
|
|
31828
32434
|
updateSiteIncidentCounter: _updateSiteIncidentCounter,
|
|
31829
32435
|
getSiteById: _getSiteById
|
|
31830
32436
|
} = useSiteRepo();
|
|
32437
|
+
const { updateStatusById } = useFileRepo();
|
|
32438
|
+
const { getUserById } = useUserRepo();
|
|
31831
32439
|
const { getById: _getUnitById } = useBuildingUnitRepo();
|
|
31832
32440
|
const { getById: _getOrganizationById } = useOrgRepo();
|
|
32441
|
+
const { deleteFile } = useFileService();
|
|
31833
32442
|
async function add(value) {
|
|
31834
32443
|
const session = import_node_server_utils174.useAtlas.getClient()?.startSession();
|
|
31835
32444
|
session?.startTransaction();
|
|
@@ -31847,23 +32456,22 @@ function useIncidentReportService() {
|
|
|
31847
32456
|
);
|
|
31848
32457
|
}
|
|
31849
32458
|
}
|
|
31850
|
-
|
|
31851
|
-
|
|
31852
|
-
|
|
31853
|
-
|
|
31854
|
-
|
|
31855
|
-
|
|
31856
|
-
|
|
31857
|
-
"Building unit not found for the provided place of incident."
|
|
32459
|
+
const incidentAttachments = value?.photos ?? [];
|
|
32460
|
+
if (incidentAttachments.length > 0) {
|
|
32461
|
+
for (const attachment of incidentAttachments) {
|
|
32462
|
+
const file = await updateStatusById(
|
|
32463
|
+
attachment,
|
|
32464
|
+
{ status: "active" },
|
|
32465
|
+
session
|
|
31858
32466
|
);
|
|
32467
|
+
if (!file) {
|
|
32468
|
+
throw new import_node_server_utils174.NotFoundError("File not found.");
|
|
32469
|
+
}
|
|
31859
32470
|
}
|
|
31860
|
-
value.incidentInformation.placeOfIncident.incidentLocation = value.incidentInformation.placeOfIncident.block?.toString() + "-" + value.incidentInformation.placeOfIncident.level + "-" + unit?.name;
|
|
31861
|
-
} else {
|
|
31862
|
-
value.incidentInformation.placeOfIncident.incidentLocation = value.incidentInformation.placeOfIncident.other;
|
|
31863
32471
|
}
|
|
31864
|
-
await _add(value, session);
|
|
32472
|
+
const result = await _add(value, session);
|
|
31865
32473
|
await session?.commitTransaction();
|
|
31866
|
-
return
|
|
32474
|
+
return result;
|
|
31867
32475
|
} catch (error) {
|
|
31868
32476
|
await session?.abortTransaction();
|
|
31869
32477
|
throw error;
|
|
@@ -31875,6 +32483,26 @@ function useIncidentReportService() {
|
|
|
31875
32483
|
const session = import_node_server_utils174.useAtlas.getClient()?.startSession();
|
|
31876
32484
|
session?.startTransaction();
|
|
31877
32485
|
try {
|
|
32486
|
+
const incidentReport = await _getIncidentReportById(id);
|
|
32487
|
+
const dataAttchments = value?.photos || [];
|
|
32488
|
+
const incidentAttachments = incidentReport?.photos || [];
|
|
32489
|
+
const deletedFiles = [];
|
|
32490
|
+
incidentAttachments.forEach((id2) => {
|
|
32491
|
+
if (!dataAttchments.includes(id2)) {
|
|
32492
|
+
deletedFiles.push(id2);
|
|
32493
|
+
}
|
|
32494
|
+
});
|
|
32495
|
+
if (deletedFiles.length > 0) {
|
|
32496
|
+
await Promise.all(
|
|
32497
|
+
deletedFiles.map(async (id2) => {
|
|
32498
|
+
try {
|
|
32499
|
+
await deleteFile(id2);
|
|
32500
|
+
} catch (error) {
|
|
32501
|
+
throw error;
|
|
32502
|
+
}
|
|
32503
|
+
})
|
|
32504
|
+
);
|
|
32505
|
+
}
|
|
31878
32506
|
await _updateIncidentReportById(id, value, session);
|
|
31879
32507
|
await session?.commitTransaction();
|
|
31880
32508
|
return "Successfully updated incident report.";
|
|
@@ -31910,19 +32538,10 @@ function useIncidentReportService() {
|
|
|
31910
32538
|
value.site = site.name;
|
|
31911
32539
|
}
|
|
31912
32540
|
}
|
|
31913
|
-
if (value?.
|
|
31914
|
-
const
|
|
31915
|
-
|
|
31916
|
-
|
|
31917
|
-
);
|
|
31918
|
-
if (unit) {
|
|
31919
|
-
value.incidentInformation.placeOfIncident.unit = unit.name;
|
|
31920
|
-
}
|
|
31921
|
-
if (value?.organization) {
|
|
31922
|
-
const org = await _getOrganizationById(value.organization);
|
|
31923
|
-
if (org) {
|
|
31924
|
-
value.organization = org.name;
|
|
31925
|
-
}
|
|
32541
|
+
if (value?.organization) {
|
|
32542
|
+
const org = await _getOrganizationById(value.organization);
|
|
32543
|
+
if (org) {
|
|
32544
|
+
value.organization = org.name;
|
|
31926
32545
|
}
|
|
31927
32546
|
}
|
|
31928
32547
|
const completion = await openai.chat.completions.create({
|
|
@@ -31945,10 +32564,32 @@ function useIncidentReportService() {
|
|
|
31945
32564
|
throw error;
|
|
31946
32565
|
}
|
|
31947
32566
|
}
|
|
32567
|
+
async function reviewIncidentReport(id, value) {
|
|
32568
|
+
const session = import_node_server_utils174.useAtlas.getClient()?.startSession();
|
|
32569
|
+
session?.startTransaction();
|
|
32570
|
+
try {
|
|
32571
|
+
if (value.approvedBy) {
|
|
32572
|
+
const approvedBy = await getUserById(value.approvedBy);
|
|
32573
|
+
if (!approvedBy || !approvedBy.name)
|
|
32574
|
+
throw new import_node_server_utils174.BadRequestError("Created by not found.");
|
|
32575
|
+
value.approvedByName = approvedBy.name;
|
|
32576
|
+
value.approvedBy = approvedBy._id;
|
|
32577
|
+
}
|
|
32578
|
+
await _reviewIncidentReport(id, value, session);
|
|
32579
|
+
await session?.commitTransaction();
|
|
32580
|
+
return `Successfully ${value.status} incident report.`;
|
|
32581
|
+
} catch (error) {
|
|
32582
|
+
await session?.abortTransaction();
|
|
32583
|
+
throw error;
|
|
32584
|
+
} finally {
|
|
32585
|
+
session?.endSession();
|
|
32586
|
+
}
|
|
32587
|
+
}
|
|
31948
32588
|
return {
|
|
31949
32589
|
add,
|
|
31950
32590
|
updateIncidentReportById,
|
|
31951
|
-
createIncidentSummary
|
|
32591
|
+
createIncidentSummary,
|
|
32592
|
+
reviewIncidentReport
|
|
31952
32593
|
};
|
|
31953
32594
|
}
|
|
31954
32595
|
|
|
@@ -31959,7 +32600,8 @@ function useIncidentReportController() {
|
|
|
31959
32600
|
const {
|
|
31960
32601
|
add: _add,
|
|
31961
32602
|
updateIncidentReportById: _updateIncidentReportById,
|
|
31962
|
-
createIncidentSummary: _createIncidentSummary
|
|
32603
|
+
createIncidentSummary: _createIncidentSummary,
|
|
32604
|
+
reviewIncidentReport: _reviewIncidentReport
|
|
31963
32605
|
} = useIncidentReportService();
|
|
31964
32606
|
const {
|
|
31965
32607
|
getAll: _getAll,
|
|
@@ -31979,7 +32621,7 @@ function useIncidentReportController() {
|
|
|
31979
32621
|
}
|
|
31980
32622
|
try {
|
|
31981
32623
|
const data = await _add(payload);
|
|
31982
|
-
res.status(201).json(data);
|
|
32624
|
+
res.status(201).json({ data });
|
|
31983
32625
|
return;
|
|
31984
32626
|
} catch (error2) {
|
|
31985
32627
|
import_node_server_utils175.logger.log({ level: "error", message: error2.message });
|
|
@@ -32127,13 +32769,45 @@ function useIncidentReportController() {
|
|
|
32127
32769
|
return;
|
|
32128
32770
|
}
|
|
32129
32771
|
}
|
|
32772
|
+
async function reviewIncidentReport(req, res, next) {
|
|
32773
|
+
const cookies = req.headers.cookie?.split(";").map((cookie) => cookie.trim().split("=")).reduce(
|
|
32774
|
+
(acc, [key, value]) => ({ ...acc, [key]: value }),
|
|
32775
|
+
{}
|
|
32776
|
+
);
|
|
32777
|
+
req.body.approvedBy = cookies?.["user"].toString() ?? "";
|
|
32778
|
+
const _id = req.params.id;
|
|
32779
|
+
const payload = { _id, ...req.body };
|
|
32780
|
+
const schema2 = import_joi100.default.object({
|
|
32781
|
+
_id: import_joi100.default.string().hex().required(),
|
|
32782
|
+
status: import_joi100.default.string().valid("approved", "rejected").required(),
|
|
32783
|
+
approvedBy: import_joi100.default.string().required(),
|
|
32784
|
+
remarks: import_joi100.default.string().optional().allow("", null)
|
|
32785
|
+
});
|
|
32786
|
+
const { error } = schema2.validate(payload);
|
|
32787
|
+
if (error) {
|
|
32788
|
+
const messages = error.details.map((d) => d.message).join(", ");
|
|
32789
|
+
import_node_server_utils175.logger.log({ level: "error", message: messages });
|
|
32790
|
+
next(new import_node_server_utils175.BadRequestError(messages));
|
|
32791
|
+
return;
|
|
32792
|
+
}
|
|
32793
|
+
try {
|
|
32794
|
+
const result = await _reviewIncidentReport(_id, req.body);
|
|
32795
|
+
res.status(200).json({ message: result });
|
|
32796
|
+
return;
|
|
32797
|
+
} catch (error2) {
|
|
32798
|
+
import_node_server_utils175.logger.log({ level: "error", message: error2.message });
|
|
32799
|
+
next(error2);
|
|
32800
|
+
return;
|
|
32801
|
+
}
|
|
32802
|
+
}
|
|
32130
32803
|
return {
|
|
32131
32804
|
add,
|
|
32132
32805
|
getAll,
|
|
32133
32806
|
getIncidentReportById,
|
|
32134
32807
|
updateIncidentReportById,
|
|
32135
32808
|
deleteIncidentReportById,
|
|
32136
|
-
createIncidentSummary
|
|
32809
|
+
createIncidentSummary,
|
|
32810
|
+
reviewIncidentReport
|
|
32137
32811
|
};
|
|
32138
32812
|
}
|
|
32139
32813
|
|
|
@@ -34047,6 +34721,7 @@ function useNfcPatrolLogController() {
|
|
|
34047
34721
|
EAccessCardUserTypes,
|
|
34048
34722
|
MAccessCard,
|
|
34049
34723
|
MAccessCardTransaction,
|
|
34724
|
+
MAddress,
|
|
34050
34725
|
MAttendance,
|
|
34051
34726
|
MAttendanceSettings,
|
|
34052
34727
|
MBillingConfiguration,
|
|
@@ -34181,6 +34856,7 @@ function useNfcPatrolLogController() {
|
|
|
34181
34856
|
siteSchema,
|
|
34182
34857
|
tokenSchema,
|
|
34183
34858
|
useAccessManagementController,
|
|
34859
|
+
useAddressRepo,
|
|
34184
34860
|
useAttendanceController,
|
|
34185
34861
|
useAttendanceRepository,
|
|
34186
34862
|
useAttendanceSettingsController,
|