@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/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.params.id;
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.params.id;
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().required(),
13002
- leaseEnd: import_joi38.default.date().required(),
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().required(),
14345
- leaseEnd: import_joi40.default.date().required()
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__ */ ((EAccessCardUserTypes2) => {
27046
- EAccessCardUserTypes2["RESIDENT"] = "Resident/Tenant";
27047
- EAccessCardUserTypes2["CONTRACTOR"] = "Contractor";
27048
- EAccessCardUserTypes2["VISITOR"] = "Visitor";
27049
- return EAccessCardUserTypes2;
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 { addPhysicalCardRepo, addNonPhysicalCardRepo } = UseAccessManagementRepo();
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
- console.error("Failed to connect:", err);
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().hex().optional().allow(null, ""),
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(import_joi99.default.string()).required(),
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(import_joi99.default.string()).required()
31380
- }).required(),
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(import_joi99.default.string()).required(),
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
- reasonForReject: import_joi99.default.string().optional().allow("", null),
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().hex().optional().allow(null, ""),
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(import_joi99.default.string()).allow(null, ""),
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(import_joi99.default.string()).allow(null, "")
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(import_joi99.default.string()).allow(null, ""),
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
- reasonForReject: import_joi99.default.string().optional().allow("", null),
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
- reasonForReject: value.reasonForReject ?? null,
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 { add: _add, updateIncidentReportById: _updateIncidentReportById } = useIncidentReportRepo();
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
- if (!value.incidentInformation.placeOfIncident.isOther) {
31851
- const unit = await _getUnitById(
31852
- value.incidentInformation.placeOfIncident.unit,
31853
- session
31854
- );
31855
- if (!unit) {
31856
- throw new Error(
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 "Successfully added incident report.";
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?.incidentInformation?.placeOfIncident?.unit) {
31914
- const unit = await _getUnitById(
31915
- value?.incidentInformation?.placeOfIncident?.unit,
31916
- session
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,