@7365admin1/core 3.6.0 → 3.7.1

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
@@ -12253,9 +12253,7 @@ function useVerificationService() {
12253
12253
  ...metadata,
12254
12254
  app
12255
12255
  },
12256
- expireAt: new Date(
12257
- Date.now() + 72 * 60 * 60 * 1e3
12258
- ).toISOString(),
12256
+ expireAt: new Date(Date.now() + 72 * 60 * 60 * 1e3).toISOString(),
12259
12257
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
12260
12258
  };
12261
12259
  const createdId = await add(value);
@@ -12274,10 +12272,7 @@ function useVerificationService() {
12274
12272
  hasPestControl: app === "pest_control_services",
12275
12273
  hasPoolMaintenance: app === "pool_maintenance_services"
12276
12274
  },
12277
- filePath: (0, import_node_server_utils21.getDirectory)(
12278
- __dirname,
12279
- "./public/handlebars/user-invite"
12280
- )
12275
+ filePath: (0, import_node_server_utils21.getDirectory)(__dirname, "./public/handlebars/user-invite")
12281
12276
  });
12282
12277
  await mailer.sendMail({
12283
12278
  to: email,
@@ -12420,7 +12415,15 @@ function useVerificationService() {
12420
12415
  throw error2;
12421
12416
  }
12422
12417
  }
12423
- async function createSimpleServiceProviderInvite({ email, app, name, role, orgId, siteId, siteName }) {
12418
+ async function createSimpleServiceProviderInvite({
12419
+ email,
12420
+ app,
12421
+ name,
12422
+ role,
12423
+ orgId,
12424
+ siteId,
12425
+ siteName
12426
+ }) {
12424
12427
  const schema2 = import_joi11.default.object({
12425
12428
  email: import_joi11.default.string().email().lowercase().required(),
12426
12429
  app: import_joi11.default.string().allow("", null),
@@ -12462,7 +12465,10 @@ function useVerificationService() {
12462
12465
  };
12463
12466
  try {
12464
12467
  const id = await _add(value);
12465
- const filePath = (0, import_node_server_utils21.getDirectory)(__dirname, `./public/handlebars/${value.type}`);
12468
+ const filePath = (0, import_node_server_utils21.getDirectory)(
12469
+ __dirname,
12470
+ `./public/handlebars/${value.type}`
12471
+ );
12466
12472
  const link = `${APP_MAIN}/verify/${value.type}/${id}`;
12467
12473
  const emailContent = (0, import_node_server_utils21.compileHandlebar)({
12468
12474
  context: {
@@ -18813,7 +18819,7 @@ function useServiceProviderRepo() {
18813
18819
  }) {
18814
18820
  page = page > 0 ? page - 1 : 0;
18815
18821
  const query = { status };
18816
- const cacheOptions = { status };
18822
+ const cacheOptions = { status, page, limit };
18817
18823
  sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
18818
18824
  cacheOptions.sort = JSON.stringify(sort);
18819
18825
  if (search) {
@@ -21254,6 +21260,15 @@ async function convertObjectIdUtil(id) {
21254
21260
  return Promise.reject("Invalid ID conversion to ObjectId");
21255
21261
  }
21256
21262
  }
21263
+ async function convertObjectIdUtil2(id, fieldName) {
21264
+ try {
21265
+ if (!id)
21266
+ throw new Error(`Invalid ID conversion to ObjectId of ${fieldName}.`);
21267
+ return new import_mongodb40.ObjectId(id);
21268
+ } catch (_) {
21269
+ throw new Error(`Invalid ID conversion to ObjectId of ${fieldName}.`);
21270
+ }
21271
+ }
21257
21272
 
21258
21273
  // src/repositories/visitor-transaction.repo.ts
21259
21274
  var import_moment_timezone = __toESM(require("moment-timezone"));
@@ -21614,6 +21629,10 @@ function useVisitorTransactionRepo() {
21614
21629
  const data = (0, import_node_server_utils69.paginate)(items, page, limit, totalCount);
21615
21630
  return data;
21616
21631
  } catch (error) {
21632
+ import_node_server_utils69.logger.error("Error in getAll visitor transaction repo", {
21633
+ message: error.message,
21634
+ stack: error.stack
21635
+ });
21617
21636
  throw error;
21618
21637
  }
21619
21638
  }
@@ -21686,6 +21705,22 @@ function useVisitorTransactionRepo() {
21686
21705
  ]).toArray();
21687
21706
  return result;
21688
21707
  } catch (error) {
21708
+ if (error instanceof Error) {
21709
+ import_node_server_utils69.logger.error(
21710
+ "Error in getVisitorTransactionById visitor transaction repo",
21711
+ {
21712
+ message: error.message,
21713
+ stack: error.stack
21714
+ }
21715
+ );
21716
+ } else {
21717
+ import_node_server_utils69.logger.error(
21718
+ "Unknown error in getVisitorTransactionById visitor transaction repo",
21719
+ {
21720
+ error
21721
+ }
21722
+ );
21723
+ }
21689
21724
  throw error;
21690
21725
  }
21691
21726
  }
@@ -21700,9 +21735,19 @@ function useVisitorTransactionRepo() {
21700
21735
  const data = await collection.findOne(query);
21701
21736
  return data;
21702
21737
  } catch (error) {
21703
- throw new import_node_server_utils69.InternalServerError(
21704
- "Failed to fetch visitor transaction by plate number."
21705
- );
21738
+ if (error instanceof Error) {
21739
+ import_node_server_utils69.logger.error("Error in getOpenByPlateNumber visitor transaction repo", {
21740
+ message: error.message,
21741
+ stack: error.stack
21742
+ });
21743
+ } else {
21744
+ import_node_server_utils69.logger.error(
21745
+ "Unknown error in getOpenByPlateNumber visitor transaction repo",
21746
+ {
21747
+ error
21748
+ }
21749
+ );
21750
+ }
21706
21751
  }
21707
21752
  }
21708
21753
  async function updateById(_id, value, session, isManualCheckOut = true) {
@@ -23017,6 +23062,38 @@ function useVehicleRepo() {
23017
23062
  throw error;
23018
23063
  }
23019
23064
  }
23065
+ async function getBlocklistedVehicleByPlateNumber(plateNumber, site) {
23066
+ if (!plateNumber) {
23067
+ throw new import_node_server_utils71.BadRequestError("Plate number is required");
23068
+ }
23069
+ const baseQuery = {
23070
+ type: "blocklist" /* BLOCKLIST */,
23071
+ plateNumber,
23072
+ ...site && {
23073
+ site: typeof site === "string" ? new import_mongodb43.ObjectId(site) : site
23074
+ }
23075
+ };
23076
+ try {
23077
+ const pipeline = [
23078
+ { $match: baseQuery },
23079
+ {
23080
+ $addFields: {
23081
+ latestDate: { $max: ["$createdAt", "$updatedAt"] }
23082
+ }
23083
+ },
23084
+ { $sort: { latestDate: -1 } },
23085
+ {
23086
+ $project: {
23087
+ latestDate: 0
23088
+ }
23089
+ }
23090
+ ];
23091
+ const [result] = await collection.aggregate(pipeline).toArray();
23092
+ return result;
23093
+ } catch (error) {
23094
+ throw error;
23095
+ }
23096
+ }
23020
23097
  return {
23021
23098
  createIndex,
23022
23099
  createTextIndex,
@@ -23035,7 +23112,8 @@ function useVehicleRepo() {
23035
23112
  bulkUpsertVehicles,
23036
23113
  getSpecificVehicleById,
23037
23114
  getBlocklistedVehicles,
23038
- getVehicleBySiteAndPlateNumber
23115
+ getVehicleBySiteAndPlateNumber,
23116
+ getBlocklistedVehicleByPlateNumber
23039
23117
  };
23040
23118
  }
23041
23119
 
@@ -25958,7 +26036,6 @@ function useBuildingUnitRepo() {
25958
26036
  const buildingCollection = await db?.collection("buildings").findOne({ _id: (0, import_node_server_utils76.toObjectId)(block) });
25959
26037
  const blockNumber = buildingCollection?.block;
25960
26038
  query.block = blockNumber !== void 0 ? blockNumber : block;
25961
- console.log("Query for getBuildingUnits:", query);
25962
26039
  try {
25963
26040
  const data = await collection.aggregate([{ $match: query }, { $project: { name: 1 } }]).toArray();
25964
26041
  setCache(cacheKey, data, 15 * 60).then(() => {
@@ -26015,6 +26092,20 @@ function useBuildingUnitRepo() {
26015
26092
  try {
26016
26093
  const data = await collection.aggregate([
26017
26094
  { $match: query },
26095
+ {
26096
+ $lookup: {
26097
+ from: "buildings",
26098
+ localField: "building",
26099
+ foreignField: "_id",
26100
+ pipeline: [{ $project: { _id: 0, name: 1 } }],
26101
+ as: "_blockData"
26102
+ }
26103
+ },
26104
+ {
26105
+ $unwind: { path: "$_blockData", preserveNullAndEmptyArrays: true }
26106
+ },
26107
+ { $addFields: { blockName: { $ifNull: ["$_blockData.name", ""] } } },
26108
+ { $unset: "_blockData" },
26018
26109
  {
26019
26110
  $lookup: {
26020
26111
  from: "building-levels",
@@ -26024,7 +26115,9 @@ function useBuildingUnitRepo() {
26024
26115
  as: "_levelData"
26025
26116
  }
26026
26117
  },
26027
- { $unwind: { path: "$_levelData", preserveNullAndEmptyArrays: true } },
26118
+ {
26119
+ $unwind: { path: "$_levelData", preserveNullAndEmptyArrays: true }
26120
+ },
26028
26121
  { $addFields: { levelName: { $ifNull: ["$_levelData.name", ""] } } },
26029
26122
  { $unset: "_levelData" }
26030
26123
  ]).toArray();
@@ -26130,7 +26223,6 @@ function useBuildingUnitRepo() {
26130
26223
  level,
26131
26224
  status: "active"
26132
26225
  };
26133
- console.log(query);
26134
26226
  const result = await collection.findOne(query);
26135
26227
  setCache(cacheKey, result, 300).then(() => {
26136
26228
  import_node_server_utils76.logger.log({
@@ -33356,6 +33448,71 @@ var KeyRepo = class {
33356
33448
  return Promise.reject("Failed to delete key");
33357
33449
  }
33358
33450
  }
33451
+ static async getById2(id) {
33452
+ return this.collection().aggregate([
33453
+ { $match: { _id: new import_mongodb61.ObjectId(id) } },
33454
+ {
33455
+ $lookup: {
33456
+ from: "qr-code-templates",
33457
+ localField: "template",
33458
+ foreignField: "_id",
33459
+ as: "QRTemplateInfo"
33460
+ }
33461
+ },
33462
+ {
33463
+ $unwind: {
33464
+ path: "$QRTemplateInfo",
33465
+ preserveNullAndEmptyArrays: true
33466
+ }
33467
+ },
33468
+ {
33469
+ $addFields: {
33470
+ prefixPass: { $toUpper: "$QRTemplateInfo.prefixPass" },
33471
+ prefixKey: { $toUpper: "$QRTemplateInfo.prefixKey" },
33472
+ templateName: "$QRTemplateInfo.name"
33473
+ }
33474
+ },
33475
+ {
33476
+ $addFields: {
33477
+ prefixAndName: {
33478
+ $cond: {
33479
+ if: { $or: [{ $not: "$prefixPass" }, { $not: "$prefixKey" }] },
33480
+ then: "$name",
33481
+ else: {
33482
+ $cond: {
33483
+ if: { $eq: ["$passType", "pass-key"] },
33484
+ then: { $concat: ["$prefixKey", "$name"] },
33485
+ else: { $concat: ["$prefixPass", "$name"] }
33486
+ }
33487
+ }
33488
+ }
33489
+ }
33490
+ }
33491
+ }
33492
+ ]).toArray().then((results) => results.length ? results[0] : null);
33493
+ }
33494
+ static async checkPassKeyAvailability(visitorPass, passKeys) {
33495
+ if (Array.isArray(visitorPass) && visitorPass.length > 0) {
33496
+ for (let i = 0; i < visitorPass.length; i++) {
33497
+ let pass = await convertObjectIdUtil2(visitorPass[i].keyId, "Pass ID");
33498
+ const getPass = await this.getById2(pass);
33499
+ if (!getPass)
33500
+ throw new Error("Pass not found");
33501
+ if (getPass?.status && getPass?.status.toLowerCase() != "Available".toLowerCase())
33502
+ throw new Error(`Pass ${getPass?.prefixAndName} is ${getPass?.status}`);
33503
+ }
33504
+ }
33505
+ if (Array.isArray(passKeys) && passKeys.length > 0) {
33506
+ for (let i = 0; i < passKeys.length; i++) {
33507
+ let key = await convertObjectIdUtil2(passKeys[i].keyId, "Key ID");
33508
+ const getPass = await this.getById2(key);
33509
+ if (!getPass)
33510
+ throw new Error(`Key not found`);
33511
+ if (getPass?.status && getPass?.status.toLowerCase() != "Available".toLowerCase())
33512
+ throw new Error(`Pass ${getPass?.prefixAndName} is ${getPass?.status}`);
33513
+ }
33514
+ }
33515
+ }
33359
33516
  };
33360
33517
 
33361
33518
  // src/services/visitor-transaction.service.ts
@@ -33392,7 +33549,9 @@ function useVisitorTransactionService() {
33392
33549
  } = useDahuaService();
33393
33550
  const { getAllSites: _getAllSites } = useSiteRepo();
33394
33551
  const { getByUserId: _getByUserId } = usePersonRepo();
33395
- const { add: addVehicle } = useVehicleRepo();
33552
+ const {
33553
+ getBlocklistedVehicleByPlateNumber: _getBlocklistedVehicleByPlateNumber
33554
+ } = useVehicleRepo();
33396
33555
  const { getById: _getUnitById } = useBuildingUnitRepo();
33397
33556
  function extractKeyId(item) {
33398
33557
  if (!item)
@@ -33470,6 +33629,13 @@ function useVisitorTransactionService() {
33470
33629
  const start = value.checkIn ? new Date(value.checkIn) : /* @__PURE__ */ new Date();
33471
33630
  try {
33472
33631
  session?.startTransaction();
33632
+ if (value.plateNumber) {
33633
+ const result2 = await _getBlocklistedVehicleByPlateNumber(
33634
+ value.plateNumber
33635
+ );
33636
+ if (result2)
33637
+ throw new import_node_server_utils106.BadRequestError("Plate number is blocklisted");
33638
+ }
33473
33639
  let camera;
33474
33640
  if (value.site && value.plateNumber) {
33475
33641
  try {
@@ -33535,6 +33701,7 @@ function useVisitorTransactionService() {
33535
33701
  for (let i = 0; i < value.members.length; i += chunkSize) {
33536
33702
  const chunk = value.members.slice(i, i + chunkSize);
33537
33703
  for (const member of chunk) {
33704
+ await KeyRepo.checkPassKeyAvailability(member.visitorPass, member.passKeys);
33538
33705
  if (member.visitorPass && Array.isArray(member.visitorPass) && member.visitorPass.length > 0) {
33539
33706
  for (const vp of member.visitorPass) {
33540
33707
  try {
@@ -33621,6 +33788,7 @@ function useVisitorTransactionService() {
33621
33788
  if (found === 1)
33622
33789
  throw new import_node_server_utils106.BadRequestError("This plate number is blocklisted");
33623
33790
  }
33791
+ await KeyRepo.checkPassKeyAvailability(value.visitorPass, value.passKeys);
33624
33792
  if (value.visitorPass && Array.isArray(value.visitorPass) && value.visitorPass.length > 0 && value.visitorPass) {
33625
33793
  for (const vp of value.visitorPass) {
33626
33794
  try {
@@ -33668,7 +33836,9 @@ function useVisitorTransactionService() {
33668
33836
  password,
33669
33837
  plateNumber: value?.plateNumber
33670
33838
  });
33671
- import_node_server_utils106.logger.info(`Barrier command sent successfully to ${host}`, { response: openBarrier });
33839
+ import_node_server_utils106.logger.info(`Barrier command sent successfully to ${host}`, {
33840
+ response: openBarrier
33841
+ });
33672
33842
  } catch (error) {
33673
33843
  import_node_server_utils106.logger.error(
33674
33844
  `Failed to open barrier at host ${host}. Critical system error:`,
@@ -33808,7 +33978,9 @@ function useVisitorTransactionService() {
33808
33978
  password,
33809
33979
  plateNumber: value?.plateNumber
33810
33980
  });
33811
- import_node_server_utils106.logger.info(`Barrier command sent successfully to ${host}`, { response: openBarrier });
33981
+ import_node_server_utils106.logger.info(`Barrier command sent successfully to ${host}`, {
33982
+ response: openBarrier
33983
+ });
33812
33984
  } catch (error) {
33813
33985
  import_node_server_utils106.logger.error(
33814
33986
  `Failed to open barrier at host ${host}. Critical system error:`,
@@ -34021,7 +34193,12 @@ function useVisitorTransactionController() {
34021
34193
  return;
34022
34194
  } catch (error) {
34023
34195
  import_node_server_utils107.logger.log({ level: "error", message: error.message });
34024
- next(error);
34196
+ console.log("error", error);
34197
+ if (error?.message) {
34198
+ next(new import_node_server_utils107.BadRequestError(error?.message));
34199
+ } else {
34200
+ next(error);
34201
+ }
34025
34202
  return;
34026
34203
  }
34027
34204
  }
@@ -43992,14 +44169,14 @@ function useSiteUnitBillingService() {
43992
44169
  billing_item.units,
43993
44170
  billing_item.site?.toString() || ""
43994
44171
  );
43995
- if (unitsWithOwner?.length) {
44172
+ if (unitsWithOwner?.length > 0) {
43996
44173
  const buildUnitBilling = (unit) => ({
43997
- site: billing_item.site,
43998
- org: billing_item.org,
44174
+ site: billing_item.site.toString(),
44175
+ org: billing_item.org.toString(),
43999
44176
  billItem: billing_item._id,
44000
44177
  billName: billing_item.name,
44001
- unitId: unit._id,
44002
- unit: unit.block + " / " + unit.level + " / " + unit.name,
44178
+ unitId: unit._id.toString(),
44179
+ unit: unit.blockName + " / " + unit.levelName + " / " + unit.name,
44003
44180
  unitOwner: unit.ownerName,
44004
44181
  email: unit.email,
44005
44182
  contactNumber: unit.contact,
@@ -44025,6 +44202,7 @@ function useSiteUnitBillingService() {
44025
44202
  );
44026
44203
  await session.commitTransaction();
44027
44204
  } catch (error) {
44205
+ console.log("BILLING ERROR:", error.message, error);
44028
44206
  import_node_server_utils155.logger.log({
44029
44207
  level: "error",
44030
44208
  message: `Failed to proccess cron billing: ${error.message}`
@@ -56412,6 +56590,7 @@ function useNewDashboardRepo() {
56412
56590
  const area_checklist_namespace_collection = "site.cleaning.schedule.areas";
56413
56591
  const supply_namespace_collection = "site.supplies";
56414
56592
  const work_order_namespace_collection = "work-orders2";
56593
+ const facility_bookings_namespace_collection2 = "facilities-booking";
56415
56594
  const areaChecklistCollection = db.collection(
56416
56595
  area_checklist_namespace_collection
56417
56596
  );
@@ -56427,171 +56606,724 @@ function useNewDashboardRepo() {
56427
56606
  pest_control_services: "Pest Control",
56428
56607
  pool_maintenance_services: "Pool Maintenance"
56429
56608
  };
56430
- async function getMetric(collectionString, siteId, period) {
56431
- const site = (0, import_node_server_utils199.toObjectId)(siteId);
56432
- const range = getPeriodRangeWithPrevious(period);
56433
- const collection = db.collection(collectionString);
56434
- const current = await collection.countDocuments({
56435
- site,
56436
- $or: [
56609
+ function formatEndDate(date) {
56610
+ if (typeof date === "string") {
56611
+ const dateWithoutTimezone = date.replace(/\s*\+\d{2}:\d{2}$/, "");
56612
+ date = new Date(dateWithoutTimezone);
56613
+ }
56614
+ const singaporeMoment = import_moment.default.tz(date, "Asia/Singapore");
56615
+ singaporeMoment.set({
56616
+ hour: 23,
56617
+ minute: 59,
56618
+ second: 59,
56619
+ millisecond: 999
56620
+ });
56621
+ return singaporeMoment.toDate();
56622
+ }
56623
+ function getDateRange(p) {
56624
+ const start = /* @__PURE__ */ new Date();
56625
+ start.setHours(0, 0, 0, 0);
56626
+ if (p === "today") {
56627
+ return { $gte: start, $lte: formatEndDate(start) };
56628
+ }
56629
+ const days = p === "thisWeek" ? 7 : 30;
56630
+ const rangeStart = /* @__PURE__ */ new Date();
56631
+ rangeStart.setDate(start.getDate() - days);
56632
+ rangeStart.setHours(0, 0, 0, 0);
56633
+ return { $gte: rangeStart, $lte: formatEndDate(/* @__PURE__ */ new Date()) };
56634
+ }
56635
+ const calculatePercentageChange = (currentCount, previousCount) => {
56636
+ if (previousCount === 0) {
56637
+ return currentCount > 0 ? 100 : 0;
56638
+ }
56639
+ return Math.round((currentCount - previousCount) / previousCount * 100 * 100) / 100;
56640
+ };
56641
+ async function getSecurityDashboard({
56642
+ siteId = "",
56643
+ period = "today" /* TODAY */,
56644
+ type
56645
+ }) {
56646
+ const siteIdObj = (0, import_node_server_utils199.toObjectId)(siteId);
56647
+ const visitorMatchObj = {};
56648
+ if (type) {
56649
+ visitorMatchObj.type = type;
56650
+ }
56651
+ const today = /* @__PURE__ */ new Date();
56652
+ today.setHours(0, 0, 0, 0);
56653
+ const yesterday = /* @__PURE__ */ new Date();
56654
+ yesterday.setDate(today.getDate() - 1);
56655
+ yesterday.setHours(0, 0, 0, 0);
56656
+ const yesterdayEnd = new Date(yesterday);
56657
+ yesterdayEnd.setHours(23, 59, 59, 999);
56658
+ const todayEnd = formatEndDate(/* @__PURE__ */ new Date());
56659
+ const periodRange = getDateRange(period);
56660
+ const incidentCollection = db.collection(incidents_namespace_collection);
56661
+ const visitorCollection = db.collection(visitors_namespace_collection);
56662
+ const nfcPatrolLogCollection = db.collection("nfc-patrol-logs");
56663
+ const [
56664
+ workOrderReport,
56665
+ yesterdayWorkOrderReport,
56666
+ todayWorkOrderReport,
56667
+ incidentReport,
56668
+ yesterdayIncidentReport,
56669
+ todayIncidentReport,
56670
+ visitorReport,
56671
+ yesterdayVisitorReport,
56672
+ todayVisitorReport,
56673
+ currentlyOnSiteCount,
56674
+ patrolReport,
56675
+ yesterdayPatrolReport,
56676
+ todayPatrolReport
56677
+ ] = await Promise.all([
56678
+ workOrderCollection.aggregate([
56437
56679
  {
56438
- createdAt: {
56439
- $gte: range.current.start,
56440
- $lte: range.current.end
56680
+ $match: {
56681
+ site: { $in: [siteIdObj, siteId] },
56682
+ service: "Security",
56683
+ createdAt: periodRange,
56684
+ status: { $nin: ["completed"] }
56441
56685
  }
56442
56686
  },
56443
56687
  {
56444
- createdAt: {
56445
- $gte: new Date(range.current.start),
56446
- $lte: new Date(range.current.end)
56688
+ $facet: {
56689
+ total: [{ $count: "count" }],
56690
+ inProgress: [
56691
+ { $match: { status: "in-progress" } },
56692
+ { $count: "count" }
56693
+ ]
56447
56694
  }
56448
56695
  }
56449
- ]
56450
- });
56451
- const previous = await collection.countDocuments({
56452
- site,
56453
- $or: [
56696
+ ]).toArray(),
56697
+ workOrderCollection.aggregate([
56698
+ {
56699
+ $match: {
56700
+ site: { $in: [siteIdObj, siteId] },
56701
+ service: "Security",
56702
+ createdAt: { $gte: yesterday, $lte: yesterdayEnd },
56703
+ status: { $nin: ["completed"] }
56704
+ }
56705
+ },
56706
+ { $count: "count" }
56707
+ ]).toArray(),
56708
+ workOrderCollection.aggregate([
56709
+ {
56710
+ $match: {
56711
+ site: { $in: [siteIdObj, siteId] },
56712
+ service: "Security",
56713
+ createdAt: { $gte: today, $lte: todayEnd },
56714
+ status: { $nin: ["completed"] }
56715
+ }
56716
+ },
56717
+ { $count: "count" }
56718
+ ]).toArray(),
56719
+ incidentCollection.aggregate([
56720
+ {
56721
+ $match: {
56722
+ site: { $in: [siteIdObj, siteId] },
56723
+ status: { $in: ["pending", "Pending"] },
56724
+ createdAt: periodRange
56725
+ }
56726
+ },
56727
+ { $count: "count" }
56728
+ ]).toArray(),
56729
+ incidentCollection.aggregate([
56730
+ {
56731
+ $match: {
56732
+ site: { $in: [siteIdObj, siteId] },
56733
+ status: { $in: ["pending", "Pending"] },
56734
+ createdAt: { $gte: yesterday, $lte: yesterdayEnd }
56735
+ }
56736
+ },
56737
+ { $count: "count" }
56738
+ ]).toArray(),
56739
+ incidentCollection.aggregate([
56740
+ {
56741
+ $match: {
56742
+ site: { $in: [siteIdObj, siteId] },
56743
+ status: { $in: ["pending", "Pending"] },
56744
+ createdAt: { $gte: today, $lte: todayEnd }
56745
+ }
56746
+ },
56747
+ { $count: "count" }
56748
+ ]).toArray(),
56749
+ visitorCollection.aggregate([
56750
+ {
56751
+ $match: {
56752
+ site: { $in: [siteIdObj, siteId] },
56753
+ ...visitorMatchObj,
56754
+ createdAt: periodRange,
56755
+ status: { $ne: "deleted" }
56756
+ }
56757
+ },
56758
+ { $count: "count" }
56759
+ ]).toArray(),
56760
+ visitorCollection.aggregate([
56761
+ {
56762
+ $match: {
56763
+ site: { $in: [siteIdObj, siteId] },
56764
+ ...visitorMatchObj,
56765
+ createdAt: { $gte: yesterday, $lte: yesterdayEnd },
56766
+ status: { $ne: "deleted" }
56767
+ }
56768
+ },
56769
+ { $count: "count" }
56770
+ ]).toArray(),
56771
+ visitorCollection.aggregate([
56454
56772
  {
56455
- createdAt: {
56456
- $gte: range.previous.start,
56457
- $lte: range.previous.end
56773
+ $match: {
56774
+ site: { $in: [siteIdObj, siteId] },
56775
+ ...visitorMatchObj,
56776
+ createdAt: { $gte: today, $lte: todayEnd },
56777
+ status: { $ne: "deleted" }
56458
56778
  }
56459
56779
  },
56780
+ { $count: "count" }
56781
+ ]).toArray(),
56782
+ visitorCollection.countDocuments({
56783
+ site: { $in: [siteIdObj, siteId] },
56784
+ ...visitorMatchObj,
56785
+ checkIn: { $ne: null },
56786
+ checkOut: null,
56787
+ status: { $ne: "deleted" }
56788
+ }),
56789
+ nfcPatrolLogCollection.aggregate([
56460
56790
  {
56461
- createdAt: {
56462
- $gte: new Date(range.previous.start),
56463
- $lte: new Date(range.previous.end)
56791
+ $match: {
56792
+ site: { $in: [siteIdObj, siteId] },
56793
+ createdAt: periodRange
56794
+ }
56795
+ },
56796
+ {
56797
+ $unwind: "$checkPoints"
56798
+ },
56799
+ {
56800
+ $facet: {
56801
+ total: [{ $count: "count" }],
56802
+ completed: [
56803
+ { $match: { "checkPoints.status": "Completed" } },
56804
+ { $count: "count" }
56805
+ ],
56806
+ skipped: [
56807
+ { $match: { "checkPoints.status": "Skipped" } },
56808
+ { $count: "count" }
56809
+ ]
56464
56810
  }
56465
56811
  }
56466
- ]
56467
- });
56468
- return {
56469
- count: current,
56470
- percentage: calculatePercentage(current, previous)
56812
+ ]).toArray(),
56813
+ nfcPatrolLogCollection.aggregate([
56814
+ {
56815
+ $match: {
56816
+ site: { $in: [siteIdObj, siteId] },
56817
+ createdAt: { $gte: yesterday, $lte: yesterdayEnd }
56818
+ }
56819
+ },
56820
+ {
56821
+ $unwind: "$checkPoints"
56822
+ },
56823
+ {
56824
+ $facet: {
56825
+ total: [{ $count: "count" }],
56826
+ completed: [
56827
+ { $match: { "checkPoints.status": "Completed" } },
56828
+ { $count: "count" }
56829
+ ],
56830
+ skipped: [
56831
+ { $match: { "checkPoints.status": "Skipped" } },
56832
+ { $count: "count" }
56833
+ ]
56834
+ }
56835
+ }
56836
+ ]).toArray(),
56837
+ nfcPatrolLogCollection.aggregate([
56838
+ {
56839
+ $match: {
56840
+ site: { $in: [siteIdObj, siteId] },
56841
+ createdAt: { $gte: today, $lte: todayEnd }
56842
+ }
56843
+ },
56844
+ {
56845
+ $unwind: "$checkPoints"
56846
+ },
56847
+ {
56848
+ $facet: {
56849
+ total: [{ $count: "count" }],
56850
+ completed: [
56851
+ { $match: { "checkPoints.status": "Completed" } },
56852
+ { $count: "count" }
56853
+ ],
56854
+ skipped: [
56855
+ { $match: { "checkPoints.status": "Skipped" } },
56856
+ { $count: "count" }
56857
+ ]
56858
+ }
56859
+ }
56860
+ ]).toArray()
56861
+ ]);
56862
+ const wFacet = workOrderReport[0] ?? { total: [], inProgress: [] };
56863
+ const pFacet = patrolReport[0] ?? {
56864
+ total: [],
56865
+ completed: [],
56866
+ skipped: []
56471
56867
  };
56472
- }
56473
- async function getSecurityDashboard({
56474
- siteId = "",
56475
- feedback = "today" /* TODAY */,
56476
- workOrder = "today" /* TODAY */,
56477
- vehicle = "today" /* TODAY */,
56478
- building = "today" /* TODAY */,
56479
- visitor = "today" /* TODAY */,
56480
- incident = "today" /* TODAY */,
56481
- guest = "today" /* TODAY */
56482
- }) {
56483
- const feedbacks = await getMetric(
56484
- feedbacks_namespace_collection,
56485
- siteId,
56486
- feedback
56487
- );
56488
- const workOrders = await getMetric(
56489
- work_orders_namespace_collection,
56490
- siteId,
56491
- workOrder
56492
- );
56493
- const vehicles = await getMetric(
56494
- vehicles_namespace_collection,
56495
- siteId,
56496
- vehicle
56497
- );
56498
- const buildings = await getMetric(
56499
- buildings_namespace_collection,
56500
- siteId,
56501
- building
56502
- );
56503
- const visitors = await getMetric(
56504
- visitors_namespace_collection,
56505
- siteId,
56506
- visitor
56507
- );
56508
- const incidents = await getMetric(
56509
- incidents_namespace_collection,
56510
- siteId,
56511
- incident
56868
+ const totalCheckpoints = pFacet.total[0]?.count ?? 0;
56869
+ const completedCheckpoints = pFacet.completed[0]?.count ?? 0;
56870
+ const skippedCheckpoints = pFacet.skipped[0]?.count ?? 0;
56871
+ const complianceRate = totalCheckpoints > 0 ? Math.round(completedCheckpoints / totalCheckpoints * 100 * 100) / 100 : 100;
56872
+ const yPatrolFacet = yesterdayPatrolReport[0] ?? {
56873
+ total: [],
56874
+ completed: []
56875
+ };
56876
+ const yTotal = yPatrolFacet.total[0]?.count ?? 0;
56877
+ const yCompleted = yPatrolFacet.completed[0]?.count ?? 0;
56878
+ const yesterdayCompliance = yTotal > 0 ? yCompleted / yTotal * 100 : 0;
56879
+ const tPatrolFacet = todayPatrolReport[0] ?? {
56880
+ total: [],
56881
+ completed: []
56882
+ };
56883
+ const tTotal = tPatrolFacet.total[0]?.count ?? 0;
56884
+ const tCompleted = tPatrolFacet.completed[0]?.count ?? 0;
56885
+ const todayCompliance = tTotal > 0 ? tCompleted / tTotal * 100 : 0;
56886
+ const todayString = import_moment.default.tz("Asia/Singapore").format("YYYY-MM-DD");
56887
+ const dayIndex = import_moment.default.tz("Asia/Singapore").day();
56888
+ const routes = await db.collection("nfc-patrol-routes").find({
56889
+ site: { $in: [siteIdObj, siteId] },
56890
+ days: { $in: [dayIndex] },
56891
+ status: { $ne: "Inactive" }
56892
+ }).toArray();
56893
+ const expandedRoutes = [];
56894
+ for (const route of routes) {
56895
+ if (route.startTimes && Array.isArray(route.startTimes)) {
56896
+ for (const startTime of route.startTimes) {
56897
+ expandedRoutes.push({
56898
+ route,
56899
+ startTime,
56900
+ itemIndex: 0
56901
+ });
56902
+ }
56903
+ }
56904
+ }
56905
+ expandedRoutes.sort((a, b) => a.startTime.localeCompare(b.startTime));
56906
+ const limitedRoutes = expandedRoutes.slice(0, 4);
56907
+ limitedRoutes.forEach((item, idx) => {
56908
+ item.itemIndex = idx + 1;
56909
+ });
56910
+ const activePatrolItems = await Promise.all(
56911
+ limitedRoutes.map(async ({ route, startTime, itemIndex }) => {
56912
+ const log = await db.collection("nfc-patrol-logs").findOne({
56913
+ site: { $in: [siteIdObj, siteId] },
56914
+ date: todayString,
56915
+ "route._id": { $in: [route._id, route._id.toString()] },
56916
+ "route.startTime": startTime
56917
+ });
56918
+ let person = "Unassigned";
56919
+ if (log && log.createdBy) {
56920
+ const userDoc = await db.collection("users").findOne({
56921
+ _id: (0, import_node_server_utils199.toObjectId)(log.createdBy)
56922
+ });
56923
+ if (userDoc && userDoc.name) {
56924
+ person = userDoc.name;
56925
+ }
56926
+ }
56927
+ let status = "pending";
56928
+ if (log) {
56929
+ status = "completed";
56930
+ } else {
56931
+ const routeTime = import_moment.default.tz(
56932
+ `${todayString} ${startTime}`,
56933
+ "YYYY-MM-DD HH:mm",
56934
+ "Asia/Singapore"
56935
+ );
56936
+ const nowSg = import_moment.default.tz("Asia/Singapore");
56937
+ const diffMinutes = nowSg.diff(routeTime, "minutes");
56938
+ if (diffMinutes >= 0) {
56939
+ if (diffMinutes <= 120) {
56940
+ status = "on paused";
56941
+ } else {
56942
+ status = "incomplete";
56943
+ }
56944
+ } else {
56945
+ status = "pending";
56946
+ }
56947
+ }
56948
+ return {
56949
+ id: `${route._id.toString()}_${startTime}`,
56950
+ title: route.name,
56951
+ subtitle: `ID${String(itemIndex).padStart(3, "0")}`,
56952
+ person,
56953
+ status,
56954
+ time: startTime
56955
+ };
56956
+ })
56512
56957
  );
56513
- const guests = await getMetric(guests_namespace_collection, siteId, guest);
56514
56958
  const data = {
56515
- feedbacks,
56516
- workOrders,
56517
- vehicles,
56518
- buildings,
56519
- visitors,
56520
- incidents,
56521
- guests
56959
+ openWorkOrder: {
56960
+ count: wFacet.total[0]?.count ?? 0,
56961
+ inProgress: wFacet.inProgress[0]?.count ?? 0,
56962
+ percentage: calculatePercentageChange(
56963
+ todayWorkOrderReport[0]?.count ?? 0,
56964
+ yesterdayWorkOrderReport[0]?.count ?? 0
56965
+ )
56966
+ },
56967
+ openIncidents: {
56968
+ count: incidentReport[0]?.count ?? 0,
56969
+ highSeverity: 0,
56970
+ percentage: calculatePercentageChange(
56971
+ todayIncidentReport[0]?.count ?? 0,
56972
+ yesterdayIncidentReport[0]?.count ?? 0
56973
+ )
56974
+ },
56975
+ visitors: {
56976
+ count: visitorReport[0]?.count ?? 0,
56977
+ currentlyOnSite: currentlyOnSiteCount,
56978
+ percentage: calculatePercentageChange(
56979
+ todayVisitorReport[0]?.count ?? 0,
56980
+ yesterdayVisitorReport[0]?.count ?? 0
56981
+ )
56982
+ },
56983
+ patrolCompliance: {
56984
+ count: complianceRate,
56985
+ missedCheckpoints: skippedCheckpoints,
56986
+ missed: skippedCheckpoints,
56987
+ percentage: calculatePercentageChange(
56988
+ todayCompliance,
56989
+ yesterdayCompliance
56990
+ )
56991
+ },
56992
+ activePatrolItems
56522
56993
  };
56523
56994
  return data;
56524
56995
  }
56525
- async function getPropertyManagementDashboard({
56526
- siteId = "",
56527
- feedback = "today" /* TODAY */,
56528
- workOrder = "today" /* TODAY */,
56529
- sitePeople = "today" /* TODAY */,
56530
- facilityBooking = "today" /* TODAY */,
56531
- bulletinBoard = "today" /* TODAY */,
56532
- event = "today" /* TODAY */,
56533
- vehicle = "today" /* TODAY */,
56534
- building = "today" /* TODAY */,
56535
- visitor = "today" /* TODAY */,
56536
- incident = "today" /* TODAY */
56537
- }) {
56538
- const feedbacks = await getMetric(
56539
- feedbacks_namespace_collection,
56540
- siteId,
56541
- feedback
56542
- );
56543
- const workOrders = await getMetric(
56544
- work_orders_namespace_collection,
56545
- siteId,
56546
- workOrder
56547
- );
56548
- const vehicles = await getMetric(
56549
- vehicles_namespace_collection,
56550
- siteId,
56551
- vehicle
56552
- );
56553
- const buildings = await getMetric(
56554
- buildings_namespace_collection,
56555
- siteId,
56556
- building
56557
- );
56558
- const visitors = await getMetric(
56559
- visitors_namespace_collection,
56560
- siteId,
56561
- visitor
56562
- );
56563
- const incidents = await getMetric(
56564
- incidents_namespace_collection,
56565
- siteId,
56566
- incident
56567
- );
56568
- const _sitePeople = await getMetric(
56569
- site_people_namespace_collection,
56570
- siteId,
56571
- sitePeople
56996
+ async function getPropertyManagementDashboard(siteId, period = "today" /* TODAY */, type, facility) {
56997
+ const siteIdObj = (0, import_node_server_utils199.toObjectId)(siteId);
56998
+ const startOfToday = import_moment.default.tz("Asia/Singapore").startOf("day").toDate();
56999
+ const endOfToday = import_moment.default.tz("Asia/Singapore").endOf("day").toDate();
57000
+ const upcomingEvents = await db.collection(events_namespace_collection).find({
57001
+ site: { $in: [siteIdObj, siteId] },
57002
+ status: { $nin: ["deleted", "Deleted"] },
57003
+ $or: [
57004
+ { dateTime: { $gte: startOfToday } },
57005
+ { dateTime: { $gte: startOfToday.toISOString() } }
57006
+ ]
57007
+ }).sort({ dateTime: 1 }).limit(4).toArray();
57008
+ const todayReminders = await db.collection(events_namespace_collection).find({
57009
+ site: { $in: [siteIdObj, siteId] },
57010
+ status: { $nin: ["deleted", "Deleted"] },
57011
+ $or: [
57012
+ { dateTime: { $gte: startOfToday, $lte: endOfToday } },
57013
+ {
57014
+ dateTime: {
57015
+ $gte: startOfToday.toISOString(),
57016
+ $lte: endOfToday.toISOString()
57017
+ }
57018
+ }
57019
+ ]
57020
+ }).sort({ dateTime: 1 }).limit(4).toArray();
57021
+ const [pendingIncidentDocs, pendingFacilityBookingDocs] = await Promise.all(
57022
+ [
57023
+ db.collection(incidents_namespace_collection).find({
57024
+ site: { $in: [siteIdObj, siteId] },
57025
+ status: { $in: ["pending", "Pending"] }
57026
+ }).sort({ createdAt: -1 }).toArray(),
57027
+ db.collection(facility_bookings_namespace_collection2).find({
57028
+ site: { $in: [siteIdObj, siteId] },
57029
+ status: { $in: ["Pending", "pending", "For Review", "for review"] }
57030
+ }).sort({ createdAt: -1 }).toArray()
57031
+ ]
56572
57032
  );
56573
- const bulletinBoards = await getMetric(
56574
- bulletin_boards_namespace_collection,
56575
- siteId,
56576
- bulletinBoard
57033
+ const pendingIncidentCount = pendingIncidentDocs.length;
57034
+ const pendingFacilityBookingCount = pendingFacilityBookingDocs.length;
57035
+ const todayAttentions = [];
57036
+ if (pendingIncidentCount > 0) {
57037
+ todayAttentions.push({
57038
+ id: "incidents-pending",
57039
+ title: `${pendingIncidentCount} incident${pendingIncidentCount === 1 ? "" : "s"} pending acknowledge`,
57040
+ createdAt: pendingIncidentDocs[0].updatedAt || pendingIncidentDocs[0].createdAt || /* @__PURE__ */ new Date()
57041
+ });
57042
+ }
57043
+ if (pendingFacilityBookingCount > 0) {
57044
+ todayAttentions.push({
57045
+ id: "facility-booking-pending",
57046
+ title: `${pendingFacilityBookingCount} facility booking${pendingFacilityBookingCount === 1 ? "" : "s"} need approval`,
57047
+ createdAt: pendingFacilityBookingDocs[0].createdAt || /* @__PURE__ */ new Date()
57048
+ });
57049
+ }
57050
+ todayAttentions.sort(
57051
+ (a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
56577
57052
  );
56578
- const events = await getMetric(events_namespace_collection, siteId, event);
56579
- const facilityBookings = await getMetric(
56580
- facility_bookings_namespace_collection,
56581
- siteId,
56582
- facilityBooking
57053
+ const visitorMatchObj = {};
57054
+ if (type) {
57055
+ visitorMatchObj.type = type;
57056
+ }
57057
+ const facilityMatchObj = {};
57058
+ if (facility) {
57059
+ try {
57060
+ facilityMatchObj.facility = { $in: [facility, new import_mongodb121.ObjectId(facility)] };
57061
+ } catch (e) {
57062
+ facilityMatchObj.facility = facility;
57063
+ }
57064
+ }
57065
+ const today = /* @__PURE__ */ new Date();
57066
+ today.setHours(0, 0, 0, 0);
57067
+ const yesterday = /* @__PURE__ */ new Date();
57068
+ yesterday.setDate(today.getDate() - 1);
57069
+ yesterday.setHours(0, 0, 0, 0);
57070
+ const yesterdayEnd = new Date(yesterday);
57071
+ yesterdayEnd.setHours(23, 59, 59, 999);
57072
+ const todayEnd = formatEndDate(/* @__PURE__ */ new Date());
57073
+ const periodRange = getDateRange(period);
57074
+ const incidentCollection = db.collection(incidents_namespace_collection);
57075
+ const visitorCollection = db.collection(visitors_namespace_collection);
57076
+ const facilityCollection = db.collection(
57077
+ facility_bookings_namespace_collection2
56583
57078
  );
57079
+ const [
57080
+ workOrderReport,
57081
+ yesterdayWorkOrderReport,
57082
+ todayWorkOrderReport,
57083
+ incidentReport,
57084
+ yesterdayIncidentReport,
57085
+ todayIncidentReport,
57086
+ visitorReport,
57087
+ yesterdayVisitorReport,
57088
+ todayVisitorReport,
57089
+ currentlyOnSiteCount,
57090
+ facilityReport,
57091
+ yesterdayFacilityReport,
57092
+ todayFacilityReport
57093
+ ] = await Promise.all([
57094
+ workOrderCollection.aggregate([
57095
+ {
57096
+ $match: {
57097
+ site: { $in: [siteIdObj, siteId] },
57098
+ createdAt: periodRange,
57099
+ status: { $nin: ["completed"] }
57100
+ }
57101
+ },
57102
+ {
57103
+ $facet: {
57104
+ total: [{ $count: "count" }],
57105
+ inProgress: [
57106
+ { $match: { status: "in-progress" } },
57107
+ { $count: "count" }
57108
+ ]
57109
+ }
57110
+ }
57111
+ ]).toArray(),
57112
+ workOrderCollection.aggregate([
57113
+ {
57114
+ $match: {
57115
+ site: { $in: [siteIdObj, siteId] },
57116
+ createdAt: { $gte: yesterday, $lte: yesterdayEnd },
57117
+ status: { $nin: ["completed"] }
57118
+ }
57119
+ },
57120
+ { $count: "count" }
57121
+ ]).toArray(),
57122
+ workOrderCollection.aggregate([
57123
+ {
57124
+ $match: {
57125
+ site: { $in: [siteIdObj, siteId] },
57126
+ createdAt: { $gte: today, $lte: todayEnd },
57127
+ status: { $nin: ["completed"] }
57128
+ }
57129
+ },
57130
+ { $count: "count" }
57131
+ ]).toArray(),
57132
+ incidentCollection.aggregate([
57133
+ {
57134
+ $match: {
57135
+ site: { $in: [siteIdObj, siteId] },
57136
+ status: { $in: ["pending", "Pending"] },
57137
+ createdAt: periodRange
57138
+ }
57139
+ },
57140
+ { $count: "count" }
57141
+ ]).toArray(),
57142
+ incidentCollection.aggregate([
57143
+ {
57144
+ $match: {
57145
+ site: { $in: [siteIdObj, siteId] },
57146
+ status: { $in: ["pending", "Pending"] },
57147
+ createdAt: { $gte: yesterday, $lte: yesterdayEnd }
57148
+ }
57149
+ },
57150
+ { $count: "count" }
57151
+ ]).toArray(),
57152
+ incidentCollection.aggregate([
57153
+ {
57154
+ $match: {
57155
+ site: { $in: [siteIdObj, siteId] },
57156
+ status: { $in: ["pending", "Pending"] },
57157
+ createdAt: { $gte: today, $lte: todayEnd }
57158
+ }
57159
+ },
57160
+ { $count: "count" }
57161
+ ]).toArray(),
57162
+ visitorCollection.aggregate([
57163
+ {
57164
+ $match: {
57165
+ site: { $in: [siteIdObj, siteId] },
57166
+ ...visitorMatchObj,
57167
+ createdAt: periodRange,
57168
+ status: { $ne: "deleted" }
57169
+ }
57170
+ },
57171
+ { $count: "count" }
57172
+ ]).toArray(),
57173
+ visitorCollection.aggregate([
57174
+ {
57175
+ $match: {
57176
+ site: { $in: [siteIdObj, siteId] },
57177
+ ...visitorMatchObj,
57178
+ createdAt: { $gte: yesterday, $lte: yesterdayEnd },
57179
+ status: { $ne: "deleted" }
57180
+ }
57181
+ },
57182
+ { $count: "count" }
57183
+ ]).toArray(),
57184
+ visitorCollection.aggregate([
57185
+ {
57186
+ $match: {
57187
+ site: { $in: [siteIdObj, siteId] },
57188
+ ...visitorMatchObj,
57189
+ createdAt: { $gte: today, $lte: todayEnd },
57190
+ status: { $ne: "deleted" }
57191
+ }
57192
+ },
57193
+ { $count: "count" }
57194
+ ]).toArray(),
57195
+ visitorCollection.countDocuments({
57196
+ site: { $in: [siteIdObj, siteId] },
57197
+ ...visitorMatchObj,
57198
+ checkIn: { $ne: null },
57199
+ checkOut: null,
57200
+ status: { $ne: "deleted" }
57201
+ }),
57202
+ facilityCollection.aggregate([
57203
+ {
57204
+ $match: {
57205
+ site: { $in: [siteIdObj, siteId] },
57206
+ ...facilityMatchObj,
57207
+ $or: [
57208
+ { createdAt: periodRange },
57209
+ {
57210
+ createdAt: {
57211
+ $gte: periodRange.$gte.toISOString(),
57212
+ $lte: periodRange.$lte.toISOString()
57213
+ }
57214
+ }
57215
+ ],
57216
+ status: { $nin: ["deleted", "Deleted"] }
57217
+ }
57218
+ },
57219
+ {
57220
+ $facet: {
57221
+ total: [{ $count: "count" }],
57222
+ ongoing: [
57223
+ {
57224
+ $match: {
57225
+ status: {
57226
+ $in: ["Approved", "Ongoing"]
57227
+ }
57228
+ }
57229
+ },
57230
+ { $count: "count" }
57231
+ ],
57232
+ waitingApproval: [
57233
+ {
57234
+ $match: {
57235
+ status: {
57236
+ $in: ["Pending", "pending", "For Review", "for review"]
57237
+ }
57238
+ }
57239
+ },
57240
+ { $count: "count" }
57241
+ ]
57242
+ }
57243
+ }
57244
+ ]).toArray(),
57245
+ facilityCollection.aggregate([
57246
+ {
57247
+ $match: {
57248
+ site: { $in: [siteIdObj, siteId] },
57249
+ ...facilityMatchObj,
57250
+ $or: [
57251
+ { createdAt: { $gte: yesterday, $lte: yesterdayEnd } },
57252
+ {
57253
+ createdAt: {
57254
+ $gte: yesterday.toISOString(),
57255
+ $lte: yesterdayEnd.toISOString()
57256
+ }
57257
+ }
57258
+ ],
57259
+ status: { $nin: ["deleted", "Deleted"] }
57260
+ }
57261
+ },
57262
+ { $count: "count" }
57263
+ ]).toArray(),
57264
+ facilityCollection.aggregate([
57265
+ {
57266
+ $match: {
57267
+ site: { $in: [siteIdObj, siteId] },
57268
+ ...facilityMatchObj,
57269
+ $or: [
57270
+ { createdAt: { $gte: today, $lte: todayEnd } },
57271
+ {
57272
+ createdAt: {
57273
+ $gte: today.toISOString(),
57274
+ $lte: todayEnd.toISOString()
57275
+ }
57276
+ }
57277
+ ],
57278
+ status: { $nin: ["deleted", "Deleted"] }
57279
+ }
57280
+ },
57281
+ { $count: "count" }
57282
+ ]).toArray()
57283
+ ]);
57284
+ const wFacet = workOrderReport[0] ?? { total: [], inProgress: [] };
57285
+ const fFacet = facilityReport[0] ?? {
57286
+ total: [],
57287
+ ongoing: [],
57288
+ waitingApproval: []
57289
+ };
56584
57290
  const data = {
56585
- feedbacks,
56586
- workOrders,
56587
- vehicles,
56588
- buildings,
56589
- visitors,
56590
- incidents,
56591
- sitePeople: _sitePeople,
56592
- bulletinBoards,
56593
- events,
56594
- facilityBookings
57291
+ openWorkOrder: {
57292
+ count: wFacet.total[0]?.count ?? 0,
57293
+ inProgress: wFacet.inProgress[0]?.count ?? 0,
57294
+ percentage: calculatePercentageChange(
57295
+ todayWorkOrderReport[0]?.count ?? 0,
57296
+ yesterdayWorkOrderReport[0]?.count ?? 0
57297
+ )
57298
+ },
57299
+ openIncidents: {
57300
+ count: incidentReport[0]?.count ?? 0,
57301
+ highSeverity: 0,
57302
+ percentage: calculatePercentageChange(
57303
+ todayIncidentReport[0]?.count ?? 0,
57304
+ yesterdayIncidentReport[0]?.count ?? 0
57305
+ )
57306
+ },
57307
+ visitors: {
57308
+ count: visitorReport[0]?.count ?? 0,
57309
+ currentlyOnSite: currentlyOnSiteCount,
57310
+ percentage: calculatePercentageChange(
57311
+ todayVisitorReport[0]?.count ?? 0,
57312
+ yesterdayVisitorReport[0]?.count ?? 0
57313
+ )
57314
+ },
57315
+ facilityBooking: {
57316
+ count: fFacet.total[0]?.count ?? 0,
57317
+ ongoing: fFacet.ongoing[0]?.count ?? 0,
57318
+ waitingApproval: fFacet.waitingApproval[0]?.count ?? 0,
57319
+ percentage: calculatePercentageChange(
57320
+ todayFacilityReport[0]?.count ?? 0,
57321
+ yesterdayFacilityReport[0]?.count ?? 0
57322
+ )
57323
+ },
57324
+ upcomingEvents,
57325
+ todayReminders,
57326
+ todayAttentions
56595
57327
  };
56596
57328
  return data;
56597
57329
  }
@@ -56621,61 +57353,13 @@ function useNewDashboardRepo() {
56621
57353
  async function getServiceDashboard({
56622
57354
  site,
56623
57355
  serviceType,
56624
- period = "today" /* TODAY */,
56625
- type,
56626
- facility
57356
+ period = "today" /* TODAY */
56627
57357
  }) {
56628
57358
  try {
56629
57359
  site = new import_mongodb121.ObjectId(site);
56630
57360
  } catch (error) {
56631
57361
  throw new import_node_server_utils199.BadRequestError("Invalid site ID format.");
56632
57362
  }
56633
- const visitorMatchObj = {};
56634
- if (type) {
56635
- visitorMatchObj.type = type;
56636
- }
56637
- const facilityMatchObj = {};
56638
- if (facility) {
56639
- try {
56640
- facilityMatchObj.facility = { $in: [facility, new import_mongodb121.ObjectId(facility)] };
56641
- } catch (e) {
56642
- facilityMatchObj.facility = facility;
56643
- }
56644
- }
56645
- function formatEndDate(date) {
56646
- if (typeof date === "string") {
56647
- const dateWithoutTimezone = date.replace(/\s*\+\d{2}:\d{2}$/, "");
56648
- date = new Date(dateWithoutTimezone);
56649
- }
56650
- const singaporeMoment = import_moment.default.tz(date, "Asia/Singapore");
56651
- singaporeMoment.set({
56652
- hour: 23,
56653
- minute: 59,
56654
- second: 59,
56655
- millisecond: 999
56656
- });
56657
- return singaporeMoment.toDate();
56658
- }
56659
- function getDateRange(p) {
56660
- const start = /* @__PURE__ */ new Date();
56661
- start.setHours(0, 0, 0, 0);
56662
- if (p === "today") {
56663
- return { $gte: start, $lte: formatEndDate(start) };
56664
- }
56665
- const days = p === "thisWeek" ? 7 : 30;
56666
- const rangeStart = /* @__PURE__ */ new Date();
56667
- rangeStart.setDate(start.getDate() - days);
56668
- rangeStart.setHours(0, 0, 0, 0);
56669
- return { $gte: rangeStart, $lte: formatEndDate(/* @__PURE__ */ new Date()) };
56670
- }
56671
- const calculatePercentageChange = (currentCount, previousCount) => {
56672
- if (previousCount === 0) {
56673
- return currentCount > 0 ? 100 : 0;
56674
- }
56675
- return Math.round(
56676
- (currentCount - previousCount) / previousCount * 100 * 100
56677
- ) / 100;
56678
- };
56679
57363
  const today = /* @__PURE__ */ new Date();
56680
57364
  today.setHours(0, 0, 0, 0);
56681
57365
  const yesterday = /* @__PURE__ */ new Date();
@@ -56686,530 +57370,6 @@ function useNewDashboardRepo() {
56686
57370
  const todayEnd = formatEndDate(/* @__PURE__ */ new Date());
56687
57371
  const periodRange = getDateRange(period);
56688
57372
  try {
56689
- if (serviceType === "property_management_agency" /* PROPERTY_MANAGEMENT_AGENCY */) {
56690
- const incidentCollection = db.collection(
56691
- incidents_namespace_collection
56692
- );
56693
- const visitorCollection = db.collection(visitors_namespace_collection);
56694
- const facilityCollection = db.collection(
56695
- facility_bookings_namespace_collection
56696
- );
56697
- const [
56698
- workOrderReport2,
56699
- yesterdayWorkOrderReport2,
56700
- todayWorkOrderReport2,
56701
- incidentReport,
56702
- yesterdayIncidentReport,
56703
- todayIncidentReport,
56704
- visitorReport,
56705
- yesterdayVisitorReport,
56706
- todayVisitorReport,
56707
- currentlyOnSiteCount,
56708
- facilityReport,
56709
- yesterdayFacilityReport,
56710
- todayFacilityReport
56711
- ] = await Promise.all([
56712
- workOrderCollection.aggregate([
56713
- {
56714
- $match: {
56715
- site,
56716
- createdAt: periodRange,
56717
- status: { $nin: ["completed"] }
56718
- }
56719
- },
56720
- {
56721
- $facet: {
56722
- total: [{ $count: "count" }],
56723
- inProgress: [
56724
- { $match: { status: "in-progress" } },
56725
- { $count: "count" }
56726
- ]
56727
- }
56728
- }
56729
- ]).toArray(),
56730
- workOrderCollection.aggregate([
56731
- {
56732
- $match: {
56733
- site,
56734
- createdAt: { $gte: yesterday, $lte: yesterdayEnd },
56735
- status: { $nin: ["completed"] }
56736
- }
56737
- },
56738
- { $count: "count" }
56739
- ]).toArray(),
56740
- workOrderCollection.aggregate([
56741
- {
56742
- $match: {
56743
- site,
56744
- createdAt: { $gte: today, $lte: todayEnd },
56745
- status: { $nin: ["completed"] }
56746
- }
56747
- },
56748
- { $count: "count" }
56749
- ]).toArray(),
56750
- incidentCollection.aggregate([
56751
- {
56752
- $match: {
56753
- site,
56754
- status: "pending",
56755
- createdAt: periodRange
56756
- }
56757
- },
56758
- { $count: "count" }
56759
- ]).toArray(),
56760
- incidentCollection.aggregate([
56761
- {
56762
- $match: {
56763
- site,
56764
- status: "pending",
56765
- createdAt: { $gte: yesterday, $lte: yesterdayEnd }
56766
- }
56767
- },
56768
- { $count: "count" }
56769
- ]).toArray(),
56770
- incidentCollection.aggregate([
56771
- {
56772
- $match: {
56773
- site,
56774
- status: "pending",
56775
- createdAt: { $gte: today, $lte: todayEnd }
56776
- }
56777
- },
56778
- { $count: "count" }
56779
- ]).toArray(),
56780
- visitorCollection.aggregate([
56781
- {
56782
- $match: {
56783
- site,
56784
- ...visitorMatchObj,
56785
- createdAt: periodRange,
56786
- status: { $ne: "deleted" }
56787
- }
56788
- },
56789
- { $count: "count" }
56790
- ]).toArray(),
56791
- visitorCollection.aggregate([
56792
- {
56793
- $match: {
56794
- site,
56795
- ...visitorMatchObj,
56796
- createdAt: { $gte: yesterday, $lte: yesterdayEnd },
56797
- status: { $ne: "deleted" }
56798
- }
56799
- },
56800
- { $count: "count" }
56801
- ]).toArray(),
56802
- visitorCollection.aggregate([
56803
- {
56804
- $match: {
56805
- site,
56806
- ...visitorMatchObj,
56807
- createdAt: { $gte: today, $lte: todayEnd },
56808
- status: { $ne: "deleted" }
56809
- }
56810
- },
56811
- { $count: "count" }
56812
- ]).toArray(),
56813
- visitorCollection.countDocuments({
56814
- site,
56815
- ...visitorMatchObj,
56816
- checkIn: { $ne: null },
56817
- checkOut: null,
56818
- status: { $ne: "deleted" }
56819
- }),
56820
- facilityCollection.aggregate([
56821
- {
56822
- $match: {
56823
- site,
56824
- ...facilityMatchObj,
56825
- $or: [
56826
- { createdAt: periodRange },
56827
- {
56828
- createdAt: {
56829
- $gte: periodRange.$gte.toISOString(),
56830
- $lte: periodRange.$lte.toISOString()
56831
- }
56832
- }
56833
- ],
56834
- status: { $nin: ["deleted", "Deleted"] }
56835
- }
56836
- },
56837
- {
56838
- $facet: {
56839
- total: [{ $count: "count" }],
56840
- ongoing: [
56841
- {
56842
- $match: {
56843
- status: {
56844
- $in: ["Approved", "Ongoing"]
56845
- }
56846
- }
56847
- },
56848
- { $count: "count" }
56849
- ],
56850
- waitingApproval: [
56851
- {
56852
- $match: {
56853
- status: {
56854
- $in: ["Pending", "For Review"]
56855
- }
56856
- }
56857
- },
56858
- { $count: "count" }
56859
- ]
56860
- }
56861
- }
56862
- ]).toArray(),
56863
- facilityCollection.aggregate([
56864
- {
56865
- $match: {
56866
- site,
56867
- ...facilityMatchObj,
56868
- $or: [
56869
- { createdAt: { $gte: yesterday, $lte: yesterdayEnd } },
56870
- {
56871
- createdAt: {
56872
- $gte: yesterday.toISOString(),
56873
- $lte: yesterdayEnd.toISOString()
56874
- }
56875
- }
56876
- ],
56877
- status: { $nin: ["deleted", "Deleted"] }
56878
- }
56879
- },
56880
- { $count: "count" }
56881
- ]).toArray(),
56882
- facilityCollection.aggregate([
56883
- {
56884
- $match: {
56885
- site,
56886
- ...facilityMatchObj,
56887
- $or: [
56888
- { createdAt: { $gte: today, $lte: todayEnd } },
56889
- {
56890
- createdAt: {
56891
- $gte: today.toISOString(),
56892
- $lte: todayEnd.toISOString()
56893
- }
56894
- }
56895
- ],
56896
- status: { $nin: ["deleted", "Deleted"] }
56897
- }
56898
- },
56899
- { $count: "count" }
56900
- ]).toArray()
56901
- ]);
56902
- const wFacet2 = workOrderReport2[0] ?? { total: [], inProgress: [] };
56903
- const fFacet = facilityReport[0] ?? {
56904
- total: [],
56905
- ongoing: [],
56906
- waitingApproval: []
56907
- };
56908
- const result2 = {
56909
- openWorkOrder: {
56910
- count: wFacet2.total[0]?.count ?? 0,
56911
- inProgress: wFacet2.inProgress[0]?.count ?? 0,
56912
- percentage: calculatePercentageChange(
56913
- todayWorkOrderReport2[0]?.count ?? 0,
56914
- yesterdayWorkOrderReport2[0]?.count ?? 0
56915
- )
56916
- },
56917
- openIncidents: {
56918
- count: incidentReport[0]?.count ?? 0,
56919
- highSeverity: 0,
56920
- percentage: calculatePercentageChange(
56921
- todayIncidentReport[0]?.count ?? 0,
56922
- yesterdayIncidentReport[0]?.count ?? 0
56923
- )
56924
- },
56925
- visitors: {
56926
- count: visitorReport[0]?.count ?? 0,
56927
- currentlyOnSite: currentlyOnSiteCount,
56928
- percentage: calculatePercentageChange(
56929
- todayVisitorReport[0]?.count ?? 0,
56930
- yesterdayVisitorReport[0]?.count ?? 0
56931
- )
56932
- },
56933
- facilityBooking: {
56934
- count: fFacet.total[0]?.count ?? 0,
56935
- ongoing: fFacet.ongoing[0]?.count ?? 0,
56936
- waitingApproval: fFacet.waitingApproval[0]?.count ?? 0,
56937
- percentage: calculatePercentageChange(
56938
- todayFacilityReport[0]?.count ?? 0,
56939
- yesterdayFacilityReport[0]?.count ?? 0
56940
- )
56941
- }
56942
- };
56943
- return result2;
56944
- }
56945
- if (serviceType === "security_agency" /* SECURITY_AGENCY */) {
56946
- const incidentCollection = db.collection(
56947
- incidents_namespace_collection
56948
- );
56949
- const visitorCollection = db.collection(visitors_namespace_collection);
56950
- const nfcPatrolLogCollection = db.collection("nfc-patrol-logs");
56951
- const [
56952
- workOrderReport2,
56953
- yesterdayWorkOrderReport2,
56954
- todayWorkOrderReport2,
56955
- incidentReport,
56956
- yesterdayIncidentReport,
56957
- todayIncidentReport,
56958
- visitorReport,
56959
- yesterdayVisitorReport,
56960
- todayVisitorReport,
56961
- currentlyOnSiteCount,
56962
- patrolReport,
56963
- yesterdayPatrolReport,
56964
- todayPatrolReport
56965
- ] = await Promise.all([
56966
- workOrderCollection.aggregate([
56967
- {
56968
- $match: {
56969
- site,
56970
- service: "Security",
56971
- createdAt: periodRange,
56972
- status: { $nin: ["completed"] }
56973
- }
56974
- },
56975
- {
56976
- $facet: {
56977
- total: [{ $count: "count" }],
56978
- inProgress: [
56979
- { $match: { status: "in-progress" } },
56980
- { $count: "count" }
56981
- ]
56982
- }
56983
- }
56984
- ]).toArray(),
56985
- workOrderCollection.aggregate([
56986
- {
56987
- $match: {
56988
- site,
56989
- service: "Security",
56990
- createdAt: { $gte: yesterday, $lte: yesterdayEnd },
56991
- status: { $nin: ["completed"] }
56992
- }
56993
- },
56994
- { $count: "count" }
56995
- ]).toArray(),
56996
- workOrderCollection.aggregate([
56997
- {
56998
- $match: {
56999
- site,
57000
- service: "Security",
57001
- createdAt: { $gte: today, $lte: todayEnd },
57002
- status: { $nin: ["completed"] }
57003
- }
57004
- },
57005
- { $count: "count" }
57006
- ]).toArray(),
57007
- incidentCollection.aggregate([
57008
- {
57009
- $match: {
57010
- site,
57011
- status: "pending",
57012
- createdAt: periodRange
57013
- }
57014
- },
57015
- { $count: "count" }
57016
- ]).toArray(),
57017
- incidentCollection.aggregate([
57018
- {
57019
- $match: {
57020
- site,
57021
- status: "pending",
57022
- createdAt: { $gte: yesterday, $lte: yesterdayEnd }
57023
- }
57024
- },
57025
- { $count: "count" }
57026
- ]).toArray(),
57027
- incidentCollection.aggregate([
57028
- {
57029
- $match: {
57030
- site,
57031
- status: "pending",
57032
- createdAt: { $gte: today, $lte: todayEnd }
57033
- }
57034
- },
57035
- { $count: "count" }
57036
- ]).toArray(),
57037
- visitorCollection.aggregate([
57038
- {
57039
- $match: {
57040
- site,
57041
- ...visitorMatchObj,
57042
- createdAt: periodRange,
57043
- status: { $ne: "deleted" }
57044
- }
57045
- },
57046
- { $count: "count" }
57047
- ]).toArray(),
57048
- visitorCollection.aggregate([
57049
- {
57050
- $match: {
57051
- site,
57052
- ...visitorMatchObj,
57053
- createdAt: { $gte: yesterday, $lte: yesterdayEnd },
57054
- status: { $ne: "deleted" }
57055
- }
57056
- },
57057
- { $count: "count" }
57058
- ]).toArray(),
57059
- visitorCollection.aggregate([
57060
- {
57061
- $match: {
57062
- site,
57063
- ...visitorMatchObj,
57064
- createdAt: { $gte: today, $lte: todayEnd },
57065
- status: { $ne: "deleted" }
57066
- }
57067
- },
57068
- { $count: "count" }
57069
- ]).toArray(),
57070
- visitorCollection.countDocuments({
57071
- site,
57072
- ...visitorMatchObj,
57073
- checkIn: { $ne: null },
57074
- checkOut: null,
57075
- status: { $ne: "deleted" }
57076
- }),
57077
- nfcPatrolLogCollection.aggregate([
57078
- {
57079
- $match: {
57080
- site,
57081
- createdAt: periodRange
57082
- }
57083
- },
57084
- {
57085
- $unwind: "$checkPoints"
57086
- },
57087
- {
57088
- $facet: {
57089
- total: [{ $count: "count" }],
57090
- completed: [
57091
- { $match: { "checkPoints.status": "Completed" } },
57092
- { $count: "count" }
57093
- ],
57094
- skipped: [
57095
- { $match: { "checkPoints.status": "Skipped" } },
57096
- { $count: "count" }
57097
- ]
57098
- }
57099
- }
57100
- ]).toArray(),
57101
- nfcPatrolLogCollection.aggregate([
57102
- {
57103
- $match: {
57104
- site,
57105
- createdAt: { $gte: yesterday, $lte: yesterdayEnd }
57106
- }
57107
- },
57108
- {
57109
- $unwind: "$checkPoints"
57110
- },
57111
- {
57112
- $facet: {
57113
- total: [{ $count: "count" }],
57114
- completed: [
57115
- { $match: { "checkPoints.status": "Completed" } },
57116
- { $count: "count" }
57117
- ],
57118
- skipped: [
57119
- { $match: { "checkPoints.status": "Skipped" } },
57120
- { $count: "count" }
57121
- ]
57122
- }
57123
- }
57124
- ]).toArray(),
57125
- nfcPatrolLogCollection.aggregate([
57126
- {
57127
- $match: {
57128
- site,
57129
- createdAt: { $gte: today, $lte: todayEnd }
57130
- }
57131
- },
57132
- {
57133
- $unwind: "$checkPoints"
57134
- },
57135
- {
57136
- $facet: {
57137
- total: [{ $count: "count" }],
57138
- completed: [
57139
- { $match: { "checkPoints.status": "Completed" } },
57140
- { $count: "count" }
57141
- ],
57142
- skipped: [
57143
- { $match: { "checkPoints.status": "Skipped" } },
57144
- { $count: "count" }
57145
- ]
57146
- }
57147
- }
57148
- ]).toArray()
57149
- ]);
57150
- const wFacet2 = workOrderReport2[0] ?? { total: [], inProgress: [] };
57151
- const pFacet = patrolReport[0] ?? {
57152
- total: [],
57153
- completed: [],
57154
- skipped: []
57155
- };
57156
- const totalCheckpoints = pFacet.total[0]?.count ?? 0;
57157
- const completedCheckpoints = pFacet.completed[0]?.count ?? 0;
57158
- const skippedCheckpoints = pFacet.skipped[0]?.count ?? 0;
57159
- const complianceRate = totalCheckpoints > 0 ? Math.round(
57160
- completedCheckpoints / totalCheckpoints * 100 * 100
57161
- ) / 100 : 100;
57162
- const yPatrolFacet = yesterdayPatrolReport[0] ?? {
57163
- total: [],
57164
- completed: []
57165
- };
57166
- const yTotal = yPatrolFacet.total[0]?.count ?? 0;
57167
- const yCompleted = yPatrolFacet.completed[0]?.count ?? 0;
57168
- const yesterdayCompliance = yTotal > 0 ? yCompleted / yTotal * 100 : 0;
57169
- const tPatrolFacet = todayPatrolReport[0] ?? {
57170
- total: [],
57171
- completed: []
57172
- };
57173
- const tTotal = tPatrolFacet.total[0]?.count ?? 0;
57174
- const tCompleted = tPatrolFacet.completed[0]?.count ?? 0;
57175
- const todayCompliance = tTotal > 0 ? tCompleted / tTotal * 100 : 0;
57176
- const result2 = {
57177
- openWorkOrder: {
57178
- count: wFacet2.total[0]?.count ?? 0,
57179
- inProgress: wFacet2.inProgress[0]?.count ?? 0,
57180
- percentage: calculatePercentageChange(
57181
- todayWorkOrderReport2[0]?.count ?? 0,
57182
- yesterdayWorkOrderReport2[0]?.count ?? 0
57183
- )
57184
- },
57185
- openIncidents: {
57186
- count: incidentReport[0]?.count ?? 0,
57187
- highSeverity: 0,
57188
- percentage: calculatePercentageChange(
57189
- todayIncidentReport[0]?.count ?? 0,
57190
- yesterdayIncidentReport[0]?.count ?? 0
57191
- )
57192
- },
57193
- visitors: {
57194
- count: visitorReport[0]?.count ?? 0,
57195
- currentlyOnSite: currentlyOnSiteCount,
57196
- percentage: calculatePercentageChange(
57197
- todayVisitorReport[0]?.count ?? 0,
57198
- yesterdayVisitorReport[0]?.count ?? 0
57199
- )
57200
- },
57201
- patrolCompliance: {
57202
- count: complianceRate,
57203
- missedCheckpoints: skippedCheckpoints,
57204
- missed: skippedCheckpoints,
57205
- percentage: calculatePercentageChange(
57206
- todayCompliance,
57207
- yesterdayCompliance
57208
- )
57209
- }
57210
- };
57211
- return result2;
57212
- }
57213
57373
  const workOrderService = workOrderServiceMap[serviceType] ?? serviceType;
57214
57374
  const [
57215
57375
  workOrderReport,
@@ -57716,13 +57876,8 @@ function useNewDashboardController() {
57716
57876
  try {
57717
57877
  const schema2 = import_joi112.default.object({
57718
57878
  site: import_joi112.default.string().hex().length(24).required(),
57719
- feedbackPeriod: periodField,
57720
- workOrderPeriod: periodField,
57721
- vehiclePeriod: periodField,
57722
- buildingPeriod: periodField,
57723
- visitorPeriod: periodField,
57724
- incidentPeriod: periodField,
57725
- guestPeriod: periodField
57879
+ period: periodField,
57880
+ type: import_joi112.default.string().optional().allow("", null)
57726
57881
  });
57727
57882
  const { error, value } = schema2.validate({
57728
57883
  site: req.params.site,
@@ -57734,25 +57889,11 @@ function useNewDashboardController() {
57734
57889
  next(new import_node_server_utils200.BadRequestError(messages));
57735
57890
  return;
57736
57891
  }
57737
- const {
57738
- site,
57739
- feedbackPeriod,
57740
- workOrderPeriod,
57741
- vehiclePeriod,
57742
- buildingPeriod,
57743
- visitorPeriod,
57744
- incidentPeriod,
57745
- guestPeriod
57746
- } = value;
57892
+ const { site, period, type } = value;
57747
57893
  const data = await _getSecurityDashboard({
57748
57894
  siteId: site,
57749
- feedback: feedbackPeriod,
57750
- workOrder: workOrderPeriod,
57751
- vehicle: vehiclePeriod,
57752
- building: buildingPeriod,
57753
- visitor: visitorPeriod,
57754
- incident: incidentPeriod,
57755
- guest: guestPeriod
57895
+ period,
57896
+ type
57756
57897
  });
57757
57898
  res.status(200).json(data);
57758
57899
  return;
@@ -57766,16 +57907,9 @@ function useNewDashboardController() {
57766
57907
  try {
57767
57908
  const schema2 = import_joi112.default.object({
57768
57909
  site: import_joi112.default.string().hex().length(24).required(),
57769
- feedbackPeriod: periodField,
57770
- workOrderPeriod: periodField,
57771
- vehiclePeriod: periodField,
57772
- buildingPeriod: periodField,
57773
- visitorPeriod: periodField,
57774
- incidentPeriod: periodField,
57775
- sitePeoplePeriod: periodField,
57776
- bulletinBoardPeriod: periodField,
57777
- eventPeriod: periodField,
57778
- facilityBookingPeriod: periodField
57910
+ period: periodField,
57911
+ type: import_joi112.default.string().optional().allow("", null),
57912
+ facility: import_joi112.default.string().hex().optional().allow("", null)
57779
57913
  });
57780
57914
  const { error, value } = schema2.validate({
57781
57915
  site: req.params.site,
@@ -57787,32 +57921,13 @@ function useNewDashboardController() {
57787
57921
  next(new import_node_server_utils200.BadRequestError(messages));
57788
57922
  return;
57789
57923
  }
57790
- const {
57924
+ const { site, period, type, facility } = value;
57925
+ const data = await _getPropertyManagementDashboard(
57791
57926
  site,
57792
- feedbackPeriod,
57793
- workOrderPeriod,
57794
- vehiclePeriod,
57795
- buildingPeriod,
57796
- visitorPeriod,
57797
- incidentPeriod,
57798
- sitePeoplePeriod,
57799
- bulletinBoardPeriod,
57800
- eventPeriod,
57801
- facilityBookingPeriod
57802
- } = value;
57803
- const data = await _getPropertyManagementDashboard({
57804
- siteId: site,
57805
- feedback: feedbackPeriod,
57806
- workOrder: workOrderPeriod,
57807
- vehicle: vehiclePeriod,
57808
- building: buildingPeriod,
57809
- visitor: visitorPeriod,
57810
- incident: incidentPeriod,
57811
- sitePeople: sitePeoplePeriod,
57812
- bulletinBoard: bulletinBoardPeriod,
57813
- event: eventPeriod,
57814
- facilityBooking: facilityBookingPeriod
57815
- });
57927
+ period,
57928
+ type,
57929
+ facility
57930
+ );
57816
57931
  res.status(200).json(data);
57817
57932
  return;
57818
57933
  } catch (error) {
@@ -57826,9 +57941,7 @@ function useNewDashboardController() {
57826
57941
  const validation = import_joi112.default.object({
57827
57942
  site: import_joi112.default.string().hex().required(),
57828
57943
  serviceType: import_joi112.default.string().valid(...Object.values(AppServiceType)).required(),
57829
- period: import_joi112.default.string().valid(...Object.values(Period)).default("today" /* TODAY */),
57830
- type: import_joi112.default.string().optional().allow("", null),
57831
- facility: import_joi112.default.string().hex().optional().allow("", null)
57944
+ period: import_joi112.default.string().valid(...Object.values(Period)).default("today" /* TODAY */)
57832
57945
  });
57833
57946
  const { error } = validation.validate(query);
57834
57947
  if (error) {
@@ -57839,15 +57952,11 @@ function useNewDashboardController() {
57839
57952
  const site = req.params.site ?? "";
57840
57953
  const serviceType = req.params.serviceType;
57841
57954
  const period = req.query.period;
57842
- const type = req.query.type;
57843
- const facility = req.query.facility;
57844
57955
  try {
57845
57956
  const data = await _getServiceDashboard({
57846
57957
  site,
57847
57958
  period,
57848
- serviceType,
57849
- type,
57850
- facility
57959
+ serviceType
57851
57960
  });
57852
57961
  res.json(data);
57853
57962
  return;
@@ -57872,7 +57981,11 @@ function useNewDashboardController() {
57872
57981
  }
57873
57982
  const { site, serviceType, period } = value;
57874
57983
  try {
57875
- const data = await _getServiceWeeklyActivity({ site, serviceType, period });
57984
+ const data = await _getServiceWeeklyActivity({
57985
+ site,
57986
+ serviceType,
57987
+ period
57988
+ });
57876
57989
  res.json(data);
57877
57990
  return;
57878
57991
  } catch (error2) {
@@ -65968,6 +66081,7 @@ function useChannelPrelovedRepo() {
65968
66081
  if (!db)
65969
66082
  throw new import_node_server_utils246.InternalServerError("Unable to connect to server.");
65970
66083
  const CHANNEL_COLLECTION = "channel-preloved";
66084
+ const CHAT_COLLECTION = "chat-preloved";
65971
66085
  const collection = db.collection(CHANNEL_COLLECTION);
65972
66086
  async function add(value, session) {
65973
66087
  try {
@@ -65986,7 +66100,85 @@ function useChannelPrelovedRepo() {
65986
66100
  };
65987
66101
  return collection.findOne(query, { session });
65988
66102
  }
65989
- return { add, getByParticipants };
66103
+ async function getChannelMessages(channelId, page = 1, limit = 10, isLoadMore = false, lastMessageId = null) {
66104
+ const chatCollection = db.collection(CHAT_COLLECTION);
66105
+ const normalizedPage = page > 0 ? page - 1 : 0;
66106
+ const normalizedLimit = limit || 10;
66107
+ const matchCriteria = {
66108
+ channelId: new import_mongodb148.ObjectId(channelId),
66109
+ deletedAt: null
66110
+ };
66111
+ if (isLoadMore && lastMessageId) {
66112
+ matchCriteria._id = { $lt: new import_mongodb148.ObjectId(lastMessageId) };
66113
+ }
66114
+ try {
66115
+ const result = await chatCollection.aggregate([
66116
+ { $match: matchCriteria },
66117
+ {
66118
+ $lookup: {
66119
+ from: "users",
66120
+ localField: "senderId",
66121
+ foreignField: "_id",
66122
+ pipeline: [
66123
+ {
66124
+ $project: {
66125
+ name: 1,
66126
+ profile: 1,
66127
+ type: 1
66128
+ }
66129
+ }
66130
+ ],
66131
+ as: "senderId"
66132
+ }
66133
+ },
66134
+ { $unwind: { path: "$senderId", preserveNullAndEmptyArrays: true } },
66135
+ {
66136
+ $lookup: {
66137
+ from: "bid-preloved",
66138
+ localField: "bidId",
66139
+ foreignField: "_id",
66140
+ pipeline: [
66141
+ { $project: { price: 1, message: 1, status: 1, type: 1 } }
66142
+ ],
66143
+ as: "bidId"
66144
+ }
66145
+ },
66146
+ { $unwind: { path: "$bidId", preserveNullAndEmptyArrays: true } },
66147
+ {
66148
+ $lookup: {
66149
+ from: "post-preloved",
66150
+ localField: "postId",
66151
+ foreignField: "_id",
66152
+ pipeline: [{ $project: { title: 1, status: 1, reserverId: 1 } }],
66153
+ as: "postDetails"
66154
+ }
66155
+ },
66156
+ {
66157
+ $unwind: {
66158
+ path: "$postDetails",
66159
+ preserveNullAndEmptyArrays: true
66160
+ }
66161
+ },
66162
+ { $sort: { createdAt: -1 } },
66163
+ {
66164
+ $facet: {
66165
+ totalCount: [{ $count: "count" }],
66166
+ items: [
66167
+ { $skip: normalizedPage * normalizedLimit },
66168
+ { $limit: normalizedLimit }
66169
+ ]
66170
+ }
66171
+ }
66172
+ ]).toArray();
66173
+ const totalCount = result[0].totalCount[0]?.count ?? 0;
66174
+ const items = result[0].items;
66175
+ items.reverse();
66176
+ return (0, import_node_server_utils246.paginate)(items, normalizedPage, normalizedLimit, totalCount);
66177
+ } catch (error) {
66178
+ throw error;
66179
+ }
66180
+ }
66181
+ return { add, getByParticipants, getChannelMessages };
65990
66182
  }
65991
66183
 
65992
66184
  // src/services/chat-preloved.service.ts
@@ -66102,8 +66294,9 @@ function useChatPrelovedController() {
66102
66294
 
66103
66295
  // src/controllers/channel-preloved.controller.ts
66104
66296
  var import_node_server_utils249 = require("@7365admin1/node-server-utils");
66297
+ var import_joi144 = __toESM(require("joi"));
66105
66298
  function useChannelPrelovedController() {
66106
- const { add: _add } = useChannelPrelovedRepo();
66299
+ const { add: _add, getChannelMessages: _getChannelMessages } = useChannelPrelovedRepo();
66107
66300
  async function add(req, res, next) {
66108
66301
  const { error, value } = schemaChannelPreloved.validate(req.body, {
66109
66302
  abortEarly: false
@@ -66122,11 +66315,51 @@ function useChannelPrelovedController() {
66122
66315
  next(error2);
66123
66316
  }
66124
66317
  }
66125
- return { add };
66318
+ async function getChannelMessages(req, res, next) {
66319
+ const paramsSchema = import_joi144.default.object({
66320
+ id: import_joi144.default.string().hex().length(24).required()
66321
+ });
66322
+ const querySchema = import_joi144.default.object({
66323
+ page: import_joi144.default.number().integer().min(1).default(1),
66324
+ limit: import_joi144.default.number().integer().min(1).max(100).default(10),
66325
+ isLoadMore: import_joi144.default.boolean().default(false),
66326
+ lastMessageId: import_joi144.default.string().hex().length(24).optional().allow("", null)
66327
+ });
66328
+ const { error: paramError, value: params } = paramsSchema.validate(
66329
+ req.params
66330
+ );
66331
+ if (paramError) {
66332
+ import_node_server_utils249.logger.log({ level: "error", message: paramError.message });
66333
+ next(new import_node_server_utils249.BadRequestError(paramError.message));
66334
+ return;
66335
+ }
66336
+ const { error: queryError, value: query } = querySchema.validate(
66337
+ req.query
66338
+ );
66339
+ if (queryError) {
66340
+ import_node_server_utils249.logger.log({ level: "error", message: queryError.message });
66341
+ next(new import_node_server_utils249.BadRequestError(queryError.message));
66342
+ return;
66343
+ }
66344
+ try {
66345
+ const data = await _getChannelMessages(
66346
+ params.id,
66347
+ query.page,
66348
+ query.limit,
66349
+ query.isLoadMore,
66350
+ query.lastMessageId || null
66351
+ );
66352
+ res.status(200).json(data);
66353
+ } catch (error) {
66354
+ import_node_server_utils249.logger.log({ level: "error", message: error.message });
66355
+ next(error);
66356
+ }
66357
+ }
66358
+ return { add, getChannelMessages };
66126
66359
  }
66127
66360
 
66128
66361
  // src/models/online-forms-v2.model.ts
66129
- var import_joi144 = __toESM(require("joi"));
66362
+ var import_joi145 = __toESM(require("joi"));
66130
66363
  var import_mongodb149 = require("mongodb");
66131
66364
  var FormEntryStatus = /* @__PURE__ */ ((FormEntryStatus2) => {
66132
66365
  FormEntryStatus2["ACTIVE"] = "active";
@@ -66134,49 +66367,49 @@ var FormEntryStatus = /* @__PURE__ */ ((FormEntryStatus2) => {
66134
66367
  FormEntryStatus2["DELETED"] = "deleted";
66135
66368
  return FormEntryStatus2;
66136
66369
  })(FormEntryStatus || {});
66137
- var schemaFormEntry = import_joi144.default.object({
66138
- _id: import_joi144.default.string().hex().optional().allow("", null),
66139
- formType: import_joi144.default.string().required(),
66140
- block: import_joi144.default.string().optional().allow(null, ""),
66141
- level: import_joi144.default.string().optional().allow(null, ""),
66142
- unit: import_joi144.default.string().optional().allow(null, ""),
66143
- name: import_joi144.default.string().optional().allow(null, ""),
66144
- phoneNumber: import_joi144.default.string().optional().allow(null, ""),
66145
- createdBy: import_joi144.default.string().required(),
66146
- fields: import_joi144.default.object().pattern(
66147
- import_joi144.default.string(),
66148
- import_joi144.default.alternatives().try(
66149
- import_joi144.default.string(),
66150
- import_joi144.default.number(),
66151
- import_joi144.default.boolean(),
66152
- import_joi144.default.valid(null)
66370
+ var schemaFormEntry = import_joi145.default.object({
66371
+ _id: import_joi145.default.string().hex().optional().allow("", null),
66372
+ formType: import_joi145.default.string().required(),
66373
+ block: import_joi145.default.string().optional().allow(null, ""),
66374
+ level: import_joi145.default.string().optional().allow(null, ""),
66375
+ unit: import_joi145.default.string().optional().allow(null, ""),
66376
+ name: import_joi145.default.string().optional().allow(null, ""),
66377
+ phoneNumber: import_joi145.default.string().optional().allow(null, ""),
66378
+ createdBy: import_joi145.default.string().required(),
66379
+ fields: import_joi145.default.object().pattern(
66380
+ import_joi145.default.string(),
66381
+ import_joi145.default.alternatives().try(
66382
+ import_joi145.default.string(),
66383
+ import_joi145.default.number(),
66384
+ import_joi145.default.boolean(),
66385
+ import_joi145.default.valid(null)
66153
66386
  )
66154
66387
  ).required(),
66155
- status: import_joi144.default.string().optional().allow("", null),
66156
- org: import_joi144.default.string().hex().optional().allow("", null),
66157
- site: import_joi144.default.string().hex().optional().allow("", null),
66158
- createdAt: import_joi144.default.date().optional().allow("", null),
66159
- updatedAt: import_joi144.default.date().optional().allow("", null),
66160
- deletedAt: import_joi144.default.date().optional().allow("", null)
66388
+ status: import_joi145.default.string().optional().allow("", null),
66389
+ org: import_joi145.default.string().hex().optional().allow("", null),
66390
+ site: import_joi145.default.string().hex().optional().allow("", null),
66391
+ createdAt: import_joi145.default.date().optional().allow("", null),
66392
+ updatedAt: import_joi145.default.date().optional().allow("", null),
66393
+ deletedAt: import_joi145.default.date().optional().allow("", null)
66161
66394
  });
66162
- var schemaUpdateFormEntry = import_joi144.default.object({
66163
- _id: import_joi144.default.string().hex().required(),
66164
- formType: import_joi144.default.string().optional().allow("", null),
66165
- block: import_joi144.default.string().optional().allow(null, ""),
66166
- level: import_joi144.default.string().optional().allow(null, ""),
66167
- unit: import_joi144.default.string().optional().allow(null, ""),
66168
- fields: import_joi144.default.object().pattern(
66169
- import_joi144.default.string(),
66170
- import_joi144.default.alternatives().try(
66171
- import_joi144.default.string(),
66172
- import_joi144.default.number(),
66173
- import_joi144.default.boolean(),
66174
- import_joi144.default.valid(null)
66395
+ var schemaUpdateFormEntry = import_joi145.default.object({
66396
+ _id: import_joi145.default.string().hex().required(),
66397
+ formType: import_joi145.default.string().optional().allow("", null),
66398
+ block: import_joi145.default.string().optional().allow(null, ""),
66399
+ level: import_joi145.default.string().optional().allow(null, ""),
66400
+ unit: import_joi145.default.string().optional().allow(null, ""),
66401
+ fields: import_joi145.default.object().pattern(
66402
+ import_joi145.default.string(),
66403
+ import_joi145.default.alternatives().try(
66404
+ import_joi145.default.string(),
66405
+ import_joi145.default.number(),
66406
+ import_joi145.default.boolean(),
66407
+ import_joi145.default.valid(null)
66175
66408
  )
66176
66409
  ).optional(),
66177
- status: import_joi144.default.string().optional().allow("", null),
66178
- updatedAt: import_joi144.default.date().optional().allow("", null),
66179
- deletedAt: import_joi144.default.date().optional().allow("", null)
66410
+ status: import_joi145.default.string().optional().allow("", null),
66411
+ updatedAt: import_joi145.default.date().optional().allow("", null),
66412
+ deletedAt: import_joi145.default.date().optional().allow("", null)
66180
66413
  });
66181
66414
  function MFormEntry(value) {
66182
66415
  const { error } = schemaFormEntry.validate(value);
@@ -66221,34 +66454,34 @@ function MFormEntry(value) {
66221
66454
  deletedAt: value.deletedAt ?? null
66222
66455
  };
66223
66456
  }
66224
- var residentFormEntry = import_joi144.default.object({
66225
- _id: import_joi144.default.string().hex().optional().allow("", null),
66226
- typeOfForm: import_joi144.default.string().optional().allow("", null),
66227
- unitNumber: import_joi144.default.string().optional().allow(null, ""),
66228
- fields: import_joi144.default.object().pattern(
66229
- import_joi144.default.string(),
66230
- import_joi144.default.alternatives().try(
66231
- import_joi144.default.string(),
66232
- import_joi144.default.number(),
66233
- import_joi144.default.boolean(),
66234
- import_joi144.default.valid(null)
66457
+ var residentFormEntry = import_joi145.default.object({
66458
+ _id: import_joi145.default.string().hex().optional().allow("", null),
66459
+ typeOfForm: import_joi145.default.string().optional().allow("", null),
66460
+ unitNumber: import_joi145.default.string().optional().allow(null, ""),
66461
+ fields: import_joi145.default.object().pattern(
66462
+ import_joi145.default.string(),
66463
+ import_joi145.default.alternatives().try(
66464
+ import_joi145.default.string(),
66465
+ import_joi145.default.number(),
66466
+ import_joi145.default.boolean(),
66467
+ import_joi145.default.valid(null)
66235
66468
  )
66236
66469
  ).optional().allow(null, ""),
66237
- status: import_joi144.default.string().optional().allow("", null),
66238
- org: import_joi144.default.string().hex().optional().allow("", null),
66239
- site: import_joi144.default.string().hex().optional().allow("", null),
66240
- userId: import_joi144.default.string().hex().optional().allow("", null),
66241
- createdAt: import_joi144.default.date().optional().allow("", null),
66242
- updatedAt: import_joi144.default.date().optional().allow("", null),
66243
- deletedAt: import_joi144.default.date().optional().allow("", null),
66244
- remarks: import_joi144.default.string().optional().allow("", null),
66245
- managementValues: import_joi144.default.object().pattern(
66246
- import_joi144.default.string(),
66247
- import_joi144.default.alternatives().try(
66248
- import_joi144.default.string(),
66249
- import_joi144.default.number(),
66250
- import_joi144.default.boolean(),
66251
- import_joi144.default.valid(null)
66470
+ status: import_joi145.default.string().optional().allow("", null),
66471
+ org: import_joi145.default.string().hex().optional().allow("", null),
66472
+ site: import_joi145.default.string().hex().optional().allow("", null),
66473
+ userId: import_joi145.default.string().hex().optional().allow("", null),
66474
+ createdAt: import_joi145.default.date().optional().allow("", null),
66475
+ updatedAt: import_joi145.default.date().optional().allow("", null),
66476
+ deletedAt: import_joi145.default.date().optional().allow("", null),
66477
+ remarks: import_joi145.default.string().optional().allow("", null),
66478
+ managementValues: import_joi145.default.object().pattern(
66479
+ import_joi145.default.string(),
66480
+ import_joi145.default.alternatives().try(
66481
+ import_joi145.default.string(),
66482
+ import_joi145.default.number(),
66483
+ import_joi145.default.boolean(),
66484
+ import_joi145.default.valid(null)
66252
66485
  )
66253
66486
  ).optional().allow(null, "")
66254
66487
  });
@@ -66509,7 +66742,7 @@ function useFormEntryRepo() {
66509
66742
 
66510
66743
  // src/controllers/online-forms-v2.controller.ts
66511
66744
  var import_node_server_utils251 = require("@7365admin1/node-server-utils");
66512
- var import_joi145 = __toESM(require("joi"));
66745
+ var import_joi146 = __toESM(require("joi"));
66513
66746
  var import_exceljs3 = __toESM(require("exceljs"));
66514
66747
  var import_fs7 = __toESM(require("fs"));
66515
66748
  function useFormEntryController() {
@@ -66585,13 +66818,13 @@ function useFormEntryController() {
66585
66818
  }
66586
66819
  async function getAll(req, res, next) {
66587
66820
  try {
66588
- const schema2 = import_joi145.default.object({
66589
- search: import_joi145.default.string().optional().allow("", null),
66590
- page: import_joi145.default.number().integer().min(1).allow("", null).default(1),
66591
- limit: import_joi145.default.number().integer().min(1).max(100).allow("", null).default(10),
66592
- status: import_joi145.default.string().optional().allow(null, ""),
66593
- org: import_joi145.default.string().hex().optional().allow("", null),
66594
- site: import_joi145.default.string().hex().optional().allow("", null)
66821
+ const schema2 = import_joi146.default.object({
66822
+ search: import_joi146.default.string().optional().allow("", null),
66823
+ page: import_joi146.default.number().integer().min(1).allow("", null).default(1),
66824
+ limit: import_joi146.default.number().integer().min(1).max(100).allow("", null).default(10),
66825
+ status: import_joi146.default.string().optional().allow(null, ""),
66826
+ org: import_joi146.default.string().hex().optional().allow("", null),
66827
+ site: import_joi146.default.string().hex().optional().allow("", null)
66595
66828
  });
66596
66829
  const { error, value } = schema2.validate(req.query);
66597
66830
  if (error) {
@@ -66612,8 +66845,8 @@ function useFormEntryController() {
66612
66845
  }
66613
66846
  async function getFormEntryById(req, res, next) {
66614
66847
  try {
66615
- const schema2 = import_joi145.default.object({
66616
- _id: import_joi145.default.string().hex().length(24).required()
66848
+ const schema2 = import_joi146.default.object({
66849
+ _id: import_joi146.default.string().hex().length(24).required()
66617
66850
  });
66618
66851
  const { error, value } = schema2.validate({ _id: req.params.id });
66619
66852
  if (error) {
@@ -66656,7 +66889,7 @@ function useFormEntryController() {
66656
66889
  }
66657
66890
  async function deleteFormEntryById(req, res, next) {
66658
66891
  try {
66659
- const validation = import_joi145.default.string().hex().required();
66892
+ const validation = import_joi146.default.string().hex().required();
66660
66893
  const _id = req.params.id;
66661
66894
  const { error } = validation.validate(_id);
66662
66895
  if (error) {
@@ -66723,10 +66956,10 @@ function useFormEntryController() {
66723
66956
  async function residentForm(req, res, next) {
66724
66957
  try {
66725
66958
  const { site, userId, org } = req.query;
66726
- const residentFormPayload = import_joi145.default.object({
66727
- org: import_joi145.default.string().hex().required(),
66728
- site: import_joi145.default.string().hex().required(),
66729
- userId: import_joi145.default.string().hex().required()
66959
+ const residentFormPayload = import_joi146.default.object({
66960
+ org: import_joi146.default.string().hex().required(),
66961
+ site: import_joi146.default.string().hex().required(),
66962
+ userId: import_joi146.default.string().hex().required()
66730
66963
  });
66731
66964
  const { error } = residentFormPayload.validate({ site, userId, org }, { abortEarly: true });
66732
66965
  if (error) {
@@ -66795,7 +67028,7 @@ function useBuildingLevelService() {
66795
67028
 
66796
67029
  // src/controllers/building-level.controller.ts
66797
67030
  var import_node_server_utils253 = require("@7365admin1/node-server-utils");
66798
- var import_joi146 = __toESM(require("joi"));
67031
+ var import_joi147 = __toESM(require("joi"));
66799
67032
  function useBuildingLevelController() {
66800
67033
  const { add: _add, updateLevelById: _updateLevelById } = useBuildingLevelService();
66801
67034
  const {
@@ -66824,12 +67057,12 @@ function useBuildingLevelController() {
66824
67057
  }
66825
67058
  async function getAll(req, res, next) {
66826
67059
  try {
66827
- const validation = import_joi146.default.object({
66828
- page: import_joi146.default.number().min(1).optional().default(1),
66829
- limit: import_joi146.default.number().min(1).optional().default(20),
66830
- search: import_joi146.default.string().optional().allow("", null),
66831
- site: import_joi146.default.string().hex().length(24).optional().allow("", null),
66832
- status: import_joi146.default.string().valid(...Object.values(BuildingLevelStatus)).default("active" /* ACTIVE */)
67060
+ const validation = import_joi147.default.object({
67061
+ page: import_joi147.default.number().min(1).optional().default(1),
67062
+ limit: import_joi147.default.number().min(1).optional().default(20),
67063
+ search: import_joi147.default.string().optional().allow("", null),
67064
+ site: import_joi147.default.string().hex().length(24).optional().allow("", null),
67065
+ status: import_joi147.default.string().valid(...Object.values(BuildingLevelStatus)).default("active" /* ACTIVE */)
66833
67066
  });
66834
67067
  const { error, value } = validation.validate(req.query, {
66835
67068
  abortEarly: false
@@ -66856,8 +67089,8 @@ function useBuildingLevelController() {
66856
67089
  }
66857
67090
  async function getById(req, res, next) {
66858
67091
  try {
66859
- const schema2 = import_joi146.default.object({
66860
- id: import_joi146.default.string().hex().length(24).required()
67092
+ const schema2 = import_joi147.default.object({
67093
+ id: import_joi147.default.string().hex().length(24).required()
66861
67094
  });
66862
67095
  const { error, value } = schema2.validate({ id: req.params.id });
66863
67096
  if (error) {
@@ -66895,8 +67128,8 @@ function useBuildingLevelController() {
66895
67128
  }
66896
67129
  async function deleteById(req, res, next) {
66897
67130
  try {
66898
- const schema2 = import_joi146.default.object({
66899
- id: import_joi146.default.string().hex().required()
67131
+ const schema2 = import_joi147.default.object({
67132
+ id: import_joi147.default.string().hex().required()
66900
67133
  });
66901
67134
  const { error, value } = schema2.validate({ id: req.params.id });
66902
67135
  if (error) {
@@ -66915,11 +67148,11 @@ function useBuildingLevelController() {
66915
67148
  }
66916
67149
  async function batchUpdateByIds(req, res, next) {
66917
67150
  try {
66918
- const schema2 = import_joi146.default.array().items(
66919
- import_joi146.default.object({
66920
- _id: import_joi146.default.string().hex().length(24).required(),
66921
- value: import_joi146.default.object({
66922
- name: import_joi146.default.string().optional().allow("", null)
67151
+ const schema2 = import_joi147.default.array().items(
67152
+ import_joi147.default.object({
67153
+ _id: import_joi147.default.string().hex().length(24).required(),
67154
+ value: import_joi147.default.object({
67155
+ name: import_joi147.default.string().optional().allow("", null)
66923
67156
  }).required()
66924
67157
  })
66925
67158
  );
@@ -66942,9 +67175,9 @@ function useBuildingLevelController() {
66942
67175
  }
66943
67176
  async function getBuildingLevelList(req, res, next) {
66944
67177
  try {
66945
- const schema2 = import_joi146.default.object({
66946
- site: import_joi146.default.string().hex().length(24).required(),
66947
- block: import_joi146.default.string().hex().length(24).required()
67178
+ const schema2 = import_joi147.default.object({
67179
+ site: import_joi147.default.string().hex().length(24).required(),
67180
+ block: import_joi147.default.string().hex().length(24).required()
66948
67181
  });
66949
67182
  const { error, value } = schema2.validate({
66950
67183
  site: req.params.siteId,