@7365admin1/core 3.6.0 → 3.7.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
@@ -18813,7 +18813,7 @@ function useServiceProviderRepo() {
18813
18813
  }) {
18814
18814
  page = page > 0 ? page - 1 : 0;
18815
18815
  const query = { status };
18816
- const cacheOptions = { status };
18816
+ const cacheOptions = { status, page, limit };
18817
18817
  sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
18818
18818
  cacheOptions.sort = JSON.stringify(sort);
18819
18819
  if (search) {
@@ -21614,6 +21614,10 @@ function useVisitorTransactionRepo() {
21614
21614
  const data = (0, import_node_server_utils69.paginate)(items, page, limit, totalCount);
21615
21615
  return data;
21616
21616
  } catch (error) {
21617
+ import_node_server_utils69.logger.error("Error in getAll visitor transaction repo", {
21618
+ message: error.message,
21619
+ stack: error.stack
21620
+ });
21617
21621
  throw error;
21618
21622
  }
21619
21623
  }
@@ -21686,6 +21690,22 @@ function useVisitorTransactionRepo() {
21686
21690
  ]).toArray();
21687
21691
  return result;
21688
21692
  } catch (error) {
21693
+ if (error instanceof Error) {
21694
+ import_node_server_utils69.logger.error(
21695
+ "Error in getVisitorTransactionById visitor transaction repo",
21696
+ {
21697
+ message: error.message,
21698
+ stack: error.stack
21699
+ }
21700
+ );
21701
+ } else {
21702
+ import_node_server_utils69.logger.error(
21703
+ "Unknown error in getVisitorTransactionById visitor transaction repo",
21704
+ {
21705
+ error
21706
+ }
21707
+ );
21708
+ }
21689
21709
  throw error;
21690
21710
  }
21691
21711
  }
@@ -21700,9 +21720,19 @@ function useVisitorTransactionRepo() {
21700
21720
  const data = await collection.findOne(query);
21701
21721
  return data;
21702
21722
  } catch (error) {
21703
- throw new import_node_server_utils69.InternalServerError(
21704
- "Failed to fetch visitor transaction by plate number."
21705
- );
21723
+ if (error instanceof Error) {
21724
+ import_node_server_utils69.logger.error("Error in getOpenByPlateNumber visitor transaction repo", {
21725
+ message: error.message,
21726
+ stack: error.stack
21727
+ });
21728
+ } else {
21729
+ import_node_server_utils69.logger.error(
21730
+ "Unknown error in getOpenByPlateNumber visitor transaction repo",
21731
+ {
21732
+ error
21733
+ }
21734
+ );
21735
+ }
21706
21736
  }
21707
21737
  }
21708
21738
  async function updateById(_id, value, session, isManualCheckOut = true) {
@@ -25958,7 +25988,6 @@ function useBuildingUnitRepo() {
25958
25988
  const buildingCollection = await db?.collection("buildings").findOne({ _id: (0, import_node_server_utils76.toObjectId)(block) });
25959
25989
  const blockNumber = buildingCollection?.block;
25960
25990
  query.block = blockNumber !== void 0 ? blockNumber : block;
25961
- console.log("Query for getBuildingUnits:", query);
25962
25991
  try {
25963
25992
  const data = await collection.aggregate([{ $match: query }, { $project: { name: 1 } }]).toArray();
25964
25993
  setCache(cacheKey, data, 15 * 60).then(() => {
@@ -26015,6 +26044,20 @@ function useBuildingUnitRepo() {
26015
26044
  try {
26016
26045
  const data = await collection.aggregate([
26017
26046
  { $match: query },
26047
+ {
26048
+ $lookup: {
26049
+ from: "buildings",
26050
+ localField: "building",
26051
+ foreignField: "_id",
26052
+ pipeline: [{ $project: { _id: 0, name: 1 } }],
26053
+ as: "_blockData"
26054
+ }
26055
+ },
26056
+ {
26057
+ $unwind: { path: "$_blockData", preserveNullAndEmptyArrays: true }
26058
+ },
26059
+ { $addFields: { blockName: { $ifNull: ["$_blockData.name", ""] } } },
26060
+ { $unset: "_blockData" },
26018
26061
  {
26019
26062
  $lookup: {
26020
26063
  from: "building-levels",
@@ -26024,7 +26067,9 @@ function useBuildingUnitRepo() {
26024
26067
  as: "_levelData"
26025
26068
  }
26026
26069
  },
26027
- { $unwind: { path: "$_levelData", preserveNullAndEmptyArrays: true } },
26070
+ {
26071
+ $unwind: { path: "$_levelData", preserveNullAndEmptyArrays: true }
26072
+ },
26028
26073
  { $addFields: { levelName: { $ifNull: ["$_levelData.name", ""] } } },
26029
26074
  { $unset: "_levelData" }
26030
26075
  ]).toArray();
@@ -26130,7 +26175,6 @@ function useBuildingUnitRepo() {
26130
26175
  level,
26131
26176
  status: "active"
26132
26177
  };
26133
- console.log(query);
26134
26178
  const result = await collection.findOne(query);
26135
26179
  setCache(cacheKey, result, 300).then(() => {
26136
26180
  import_node_server_utils76.logger.log({
@@ -43992,14 +44036,14 @@ function useSiteUnitBillingService() {
43992
44036
  billing_item.units,
43993
44037
  billing_item.site?.toString() || ""
43994
44038
  );
43995
- if (unitsWithOwner?.length) {
44039
+ if (unitsWithOwner?.length > 0) {
43996
44040
  const buildUnitBilling = (unit) => ({
43997
- site: billing_item.site,
43998
- org: billing_item.org,
44041
+ site: billing_item.site.toString(),
44042
+ org: billing_item.org.toString(),
43999
44043
  billItem: billing_item._id,
44000
44044
  billName: billing_item.name,
44001
- unitId: unit._id,
44002
- unit: unit.block + " / " + unit.level + " / " + unit.name,
44045
+ unitId: unit._id.toString(),
44046
+ unit: unit.blockName + " / " + unit.levelName + " / " + unit.name,
44003
44047
  unitOwner: unit.ownerName,
44004
44048
  email: unit.email,
44005
44049
  contactNumber: unit.contact,
@@ -44025,6 +44069,7 @@ function useSiteUnitBillingService() {
44025
44069
  );
44026
44070
  await session.commitTransaction();
44027
44071
  } catch (error) {
44072
+ console.log("BILLING ERROR:", error.message, error);
44028
44073
  import_node_server_utils155.logger.log({
44029
44074
  level: "error",
44030
44075
  message: `Failed to proccess cron billing: ${error.message}`
@@ -56412,6 +56457,7 @@ function useNewDashboardRepo() {
56412
56457
  const area_checklist_namespace_collection = "site.cleaning.schedule.areas";
56413
56458
  const supply_namespace_collection = "site.supplies";
56414
56459
  const work_order_namespace_collection = "work-orders2";
56460
+ const facility_bookings_namespace_collection2 = "facilities-booking";
56415
56461
  const areaChecklistCollection = db.collection(
56416
56462
  area_checklist_namespace_collection
56417
56463
  );
@@ -56427,171 +56473,724 @@ function useNewDashboardRepo() {
56427
56473
  pest_control_services: "Pest Control",
56428
56474
  pool_maintenance_services: "Pool Maintenance"
56429
56475
  };
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: [
56476
+ function formatEndDate(date) {
56477
+ if (typeof date === "string") {
56478
+ const dateWithoutTimezone = date.replace(/\s*\+\d{2}:\d{2}$/, "");
56479
+ date = new Date(dateWithoutTimezone);
56480
+ }
56481
+ const singaporeMoment = import_moment.default.tz(date, "Asia/Singapore");
56482
+ singaporeMoment.set({
56483
+ hour: 23,
56484
+ minute: 59,
56485
+ second: 59,
56486
+ millisecond: 999
56487
+ });
56488
+ return singaporeMoment.toDate();
56489
+ }
56490
+ function getDateRange(p) {
56491
+ const start = /* @__PURE__ */ new Date();
56492
+ start.setHours(0, 0, 0, 0);
56493
+ if (p === "today") {
56494
+ return { $gte: start, $lte: formatEndDate(start) };
56495
+ }
56496
+ const days = p === "thisWeek" ? 7 : 30;
56497
+ const rangeStart = /* @__PURE__ */ new Date();
56498
+ rangeStart.setDate(start.getDate() - days);
56499
+ rangeStart.setHours(0, 0, 0, 0);
56500
+ return { $gte: rangeStart, $lte: formatEndDate(/* @__PURE__ */ new Date()) };
56501
+ }
56502
+ const calculatePercentageChange = (currentCount, previousCount) => {
56503
+ if (previousCount === 0) {
56504
+ return currentCount > 0 ? 100 : 0;
56505
+ }
56506
+ return Math.round((currentCount - previousCount) / previousCount * 100 * 100) / 100;
56507
+ };
56508
+ async function getSecurityDashboard({
56509
+ siteId = "",
56510
+ period = "today" /* TODAY */,
56511
+ type
56512
+ }) {
56513
+ const siteIdObj = (0, import_node_server_utils199.toObjectId)(siteId);
56514
+ const visitorMatchObj = {};
56515
+ if (type) {
56516
+ visitorMatchObj.type = type;
56517
+ }
56518
+ const today = /* @__PURE__ */ new Date();
56519
+ today.setHours(0, 0, 0, 0);
56520
+ const yesterday = /* @__PURE__ */ new Date();
56521
+ yesterday.setDate(today.getDate() - 1);
56522
+ yesterday.setHours(0, 0, 0, 0);
56523
+ const yesterdayEnd = new Date(yesterday);
56524
+ yesterdayEnd.setHours(23, 59, 59, 999);
56525
+ const todayEnd = formatEndDate(/* @__PURE__ */ new Date());
56526
+ const periodRange = getDateRange(period);
56527
+ const incidentCollection = db.collection(incidents_namespace_collection);
56528
+ const visitorCollection = db.collection(visitors_namespace_collection);
56529
+ const nfcPatrolLogCollection = db.collection("nfc-patrol-logs");
56530
+ const [
56531
+ workOrderReport,
56532
+ yesterdayWorkOrderReport,
56533
+ todayWorkOrderReport,
56534
+ incidentReport,
56535
+ yesterdayIncidentReport,
56536
+ todayIncidentReport,
56537
+ visitorReport,
56538
+ yesterdayVisitorReport,
56539
+ todayVisitorReport,
56540
+ currentlyOnSiteCount,
56541
+ patrolReport,
56542
+ yesterdayPatrolReport,
56543
+ todayPatrolReport
56544
+ ] = await Promise.all([
56545
+ workOrderCollection.aggregate([
56437
56546
  {
56438
- createdAt: {
56439
- $gte: range.current.start,
56440
- $lte: range.current.end
56547
+ $match: {
56548
+ site: { $in: [siteIdObj, siteId] },
56549
+ service: "Security",
56550
+ createdAt: periodRange,
56551
+ status: { $nin: ["completed"] }
56441
56552
  }
56442
56553
  },
56443
56554
  {
56444
- createdAt: {
56445
- $gte: new Date(range.current.start),
56446
- $lte: new Date(range.current.end)
56555
+ $facet: {
56556
+ total: [{ $count: "count" }],
56557
+ inProgress: [
56558
+ { $match: { status: "in-progress" } },
56559
+ { $count: "count" }
56560
+ ]
56447
56561
  }
56448
56562
  }
56449
- ]
56450
- });
56451
- const previous = await collection.countDocuments({
56452
- site,
56453
- $or: [
56563
+ ]).toArray(),
56564
+ workOrderCollection.aggregate([
56565
+ {
56566
+ $match: {
56567
+ site: { $in: [siteIdObj, siteId] },
56568
+ service: "Security",
56569
+ createdAt: { $gte: yesterday, $lte: yesterdayEnd },
56570
+ status: { $nin: ["completed"] }
56571
+ }
56572
+ },
56573
+ { $count: "count" }
56574
+ ]).toArray(),
56575
+ workOrderCollection.aggregate([
56576
+ {
56577
+ $match: {
56578
+ site: { $in: [siteIdObj, siteId] },
56579
+ service: "Security",
56580
+ createdAt: { $gte: today, $lte: todayEnd },
56581
+ status: { $nin: ["completed"] }
56582
+ }
56583
+ },
56584
+ { $count: "count" }
56585
+ ]).toArray(),
56586
+ incidentCollection.aggregate([
56587
+ {
56588
+ $match: {
56589
+ site: { $in: [siteIdObj, siteId] },
56590
+ status: { $in: ["pending", "Pending"] },
56591
+ createdAt: periodRange
56592
+ }
56593
+ },
56594
+ { $count: "count" }
56595
+ ]).toArray(),
56596
+ incidentCollection.aggregate([
56597
+ {
56598
+ $match: {
56599
+ site: { $in: [siteIdObj, siteId] },
56600
+ status: { $in: ["pending", "Pending"] },
56601
+ createdAt: { $gte: yesterday, $lte: yesterdayEnd }
56602
+ }
56603
+ },
56604
+ { $count: "count" }
56605
+ ]).toArray(),
56606
+ incidentCollection.aggregate([
56607
+ {
56608
+ $match: {
56609
+ site: { $in: [siteIdObj, siteId] },
56610
+ status: { $in: ["pending", "Pending"] },
56611
+ createdAt: { $gte: today, $lte: todayEnd }
56612
+ }
56613
+ },
56614
+ { $count: "count" }
56615
+ ]).toArray(),
56616
+ visitorCollection.aggregate([
56617
+ {
56618
+ $match: {
56619
+ site: { $in: [siteIdObj, siteId] },
56620
+ ...visitorMatchObj,
56621
+ createdAt: periodRange,
56622
+ status: { $ne: "deleted" }
56623
+ }
56624
+ },
56625
+ { $count: "count" }
56626
+ ]).toArray(),
56627
+ visitorCollection.aggregate([
56454
56628
  {
56455
- createdAt: {
56456
- $gte: range.previous.start,
56457
- $lte: range.previous.end
56629
+ $match: {
56630
+ site: { $in: [siteIdObj, siteId] },
56631
+ ...visitorMatchObj,
56632
+ createdAt: { $gte: yesterday, $lte: yesterdayEnd },
56633
+ status: { $ne: "deleted" }
56634
+ }
56635
+ },
56636
+ { $count: "count" }
56637
+ ]).toArray(),
56638
+ visitorCollection.aggregate([
56639
+ {
56640
+ $match: {
56641
+ site: { $in: [siteIdObj, siteId] },
56642
+ ...visitorMatchObj,
56643
+ createdAt: { $gte: today, $lte: todayEnd },
56644
+ status: { $ne: "deleted" }
56645
+ }
56646
+ },
56647
+ { $count: "count" }
56648
+ ]).toArray(),
56649
+ visitorCollection.countDocuments({
56650
+ site: { $in: [siteIdObj, siteId] },
56651
+ ...visitorMatchObj,
56652
+ checkIn: { $ne: null },
56653
+ checkOut: null,
56654
+ status: { $ne: "deleted" }
56655
+ }),
56656
+ nfcPatrolLogCollection.aggregate([
56657
+ {
56658
+ $match: {
56659
+ site: { $in: [siteIdObj, siteId] },
56660
+ createdAt: periodRange
56458
56661
  }
56459
56662
  },
56460
56663
  {
56461
- createdAt: {
56462
- $gte: new Date(range.previous.start),
56463
- $lte: new Date(range.previous.end)
56664
+ $unwind: "$checkPoints"
56665
+ },
56666
+ {
56667
+ $facet: {
56668
+ total: [{ $count: "count" }],
56669
+ completed: [
56670
+ { $match: { "checkPoints.status": "Completed" } },
56671
+ { $count: "count" }
56672
+ ],
56673
+ skipped: [
56674
+ { $match: { "checkPoints.status": "Skipped" } },
56675
+ { $count: "count" }
56676
+ ]
56464
56677
  }
56465
56678
  }
56466
- ]
56467
- });
56468
- return {
56469
- count: current,
56470
- percentage: calculatePercentage(current, previous)
56679
+ ]).toArray(),
56680
+ nfcPatrolLogCollection.aggregate([
56681
+ {
56682
+ $match: {
56683
+ site: { $in: [siteIdObj, siteId] },
56684
+ createdAt: { $gte: yesterday, $lte: yesterdayEnd }
56685
+ }
56686
+ },
56687
+ {
56688
+ $unwind: "$checkPoints"
56689
+ },
56690
+ {
56691
+ $facet: {
56692
+ total: [{ $count: "count" }],
56693
+ completed: [
56694
+ { $match: { "checkPoints.status": "Completed" } },
56695
+ { $count: "count" }
56696
+ ],
56697
+ skipped: [
56698
+ { $match: { "checkPoints.status": "Skipped" } },
56699
+ { $count: "count" }
56700
+ ]
56701
+ }
56702
+ }
56703
+ ]).toArray(),
56704
+ nfcPatrolLogCollection.aggregate([
56705
+ {
56706
+ $match: {
56707
+ site: { $in: [siteIdObj, siteId] },
56708
+ createdAt: { $gte: today, $lte: todayEnd }
56709
+ }
56710
+ },
56711
+ {
56712
+ $unwind: "$checkPoints"
56713
+ },
56714
+ {
56715
+ $facet: {
56716
+ total: [{ $count: "count" }],
56717
+ completed: [
56718
+ { $match: { "checkPoints.status": "Completed" } },
56719
+ { $count: "count" }
56720
+ ],
56721
+ skipped: [
56722
+ { $match: { "checkPoints.status": "Skipped" } },
56723
+ { $count: "count" }
56724
+ ]
56725
+ }
56726
+ }
56727
+ ]).toArray()
56728
+ ]);
56729
+ const wFacet = workOrderReport[0] ?? { total: [], inProgress: [] };
56730
+ const pFacet = patrolReport[0] ?? {
56731
+ total: [],
56732
+ completed: [],
56733
+ skipped: []
56471
56734
  };
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
56735
+ const totalCheckpoints = pFacet.total[0]?.count ?? 0;
56736
+ const completedCheckpoints = pFacet.completed[0]?.count ?? 0;
56737
+ const skippedCheckpoints = pFacet.skipped[0]?.count ?? 0;
56738
+ const complianceRate = totalCheckpoints > 0 ? Math.round(completedCheckpoints / totalCheckpoints * 100 * 100) / 100 : 100;
56739
+ const yPatrolFacet = yesterdayPatrolReport[0] ?? {
56740
+ total: [],
56741
+ completed: []
56742
+ };
56743
+ const yTotal = yPatrolFacet.total[0]?.count ?? 0;
56744
+ const yCompleted = yPatrolFacet.completed[0]?.count ?? 0;
56745
+ const yesterdayCompliance = yTotal > 0 ? yCompleted / yTotal * 100 : 0;
56746
+ const tPatrolFacet = todayPatrolReport[0] ?? {
56747
+ total: [],
56748
+ completed: []
56749
+ };
56750
+ const tTotal = tPatrolFacet.total[0]?.count ?? 0;
56751
+ const tCompleted = tPatrolFacet.completed[0]?.count ?? 0;
56752
+ const todayCompliance = tTotal > 0 ? tCompleted / tTotal * 100 : 0;
56753
+ const todayString = import_moment.default.tz("Asia/Singapore").format("YYYY-MM-DD");
56754
+ const dayIndex = import_moment.default.tz("Asia/Singapore").day();
56755
+ const routes = await db.collection("nfc-patrol-routes").find({
56756
+ site: { $in: [siteIdObj, siteId] },
56757
+ days: { $in: [dayIndex] },
56758
+ status: { $ne: "Inactive" }
56759
+ }).toArray();
56760
+ const expandedRoutes = [];
56761
+ for (const route of routes) {
56762
+ if (route.startTimes && Array.isArray(route.startTimes)) {
56763
+ for (const startTime of route.startTimes) {
56764
+ expandedRoutes.push({
56765
+ route,
56766
+ startTime,
56767
+ itemIndex: 0
56768
+ });
56769
+ }
56770
+ }
56771
+ }
56772
+ expandedRoutes.sort((a, b) => a.startTime.localeCompare(b.startTime));
56773
+ const limitedRoutes = expandedRoutes.slice(0, 4);
56774
+ limitedRoutes.forEach((item, idx) => {
56775
+ item.itemIndex = idx + 1;
56776
+ });
56777
+ const activePatrolItems = await Promise.all(
56778
+ limitedRoutes.map(async ({ route, startTime, itemIndex }) => {
56779
+ const log = await db.collection("nfc-patrol-logs").findOne({
56780
+ site: { $in: [siteIdObj, siteId] },
56781
+ date: todayString,
56782
+ "route._id": { $in: [route._id, route._id.toString()] },
56783
+ "route.startTime": startTime
56784
+ });
56785
+ let person = "Unassigned";
56786
+ if (log && log.createdBy) {
56787
+ const userDoc = await db.collection("users").findOne({
56788
+ _id: (0, import_node_server_utils199.toObjectId)(log.createdBy)
56789
+ });
56790
+ if (userDoc && userDoc.name) {
56791
+ person = userDoc.name;
56792
+ }
56793
+ }
56794
+ let status = "pending";
56795
+ if (log) {
56796
+ status = "completed";
56797
+ } else {
56798
+ const routeTime = import_moment.default.tz(
56799
+ `${todayString} ${startTime}`,
56800
+ "YYYY-MM-DD HH:mm",
56801
+ "Asia/Singapore"
56802
+ );
56803
+ const nowSg = import_moment.default.tz("Asia/Singapore");
56804
+ const diffMinutes = nowSg.diff(routeTime, "minutes");
56805
+ if (diffMinutes >= 0) {
56806
+ if (diffMinutes <= 120) {
56807
+ status = "on paused";
56808
+ } else {
56809
+ status = "incomplete";
56810
+ }
56811
+ } else {
56812
+ status = "pending";
56813
+ }
56814
+ }
56815
+ return {
56816
+ id: `${route._id.toString()}_${startTime}`,
56817
+ title: route.name,
56818
+ subtitle: `ID${String(itemIndex).padStart(3, "0")}`,
56819
+ person,
56820
+ status,
56821
+ time: startTime
56822
+ };
56823
+ })
56512
56824
  );
56513
- const guests = await getMetric(guests_namespace_collection, siteId, guest);
56514
56825
  const data = {
56515
- feedbacks,
56516
- workOrders,
56517
- vehicles,
56518
- buildings,
56519
- visitors,
56520
- incidents,
56521
- guests
56826
+ openWorkOrder: {
56827
+ count: wFacet.total[0]?.count ?? 0,
56828
+ inProgress: wFacet.inProgress[0]?.count ?? 0,
56829
+ percentage: calculatePercentageChange(
56830
+ todayWorkOrderReport[0]?.count ?? 0,
56831
+ yesterdayWorkOrderReport[0]?.count ?? 0
56832
+ )
56833
+ },
56834
+ openIncidents: {
56835
+ count: incidentReport[0]?.count ?? 0,
56836
+ highSeverity: 0,
56837
+ percentage: calculatePercentageChange(
56838
+ todayIncidentReport[0]?.count ?? 0,
56839
+ yesterdayIncidentReport[0]?.count ?? 0
56840
+ )
56841
+ },
56842
+ visitors: {
56843
+ count: visitorReport[0]?.count ?? 0,
56844
+ currentlyOnSite: currentlyOnSiteCount,
56845
+ percentage: calculatePercentageChange(
56846
+ todayVisitorReport[0]?.count ?? 0,
56847
+ yesterdayVisitorReport[0]?.count ?? 0
56848
+ )
56849
+ },
56850
+ patrolCompliance: {
56851
+ count: complianceRate,
56852
+ missedCheckpoints: skippedCheckpoints,
56853
+ missed: skippedCheckpoints,
56854
+ percentage: calculatePercentageChange(
56855
+ todayCompliance,
56856
+ yesterdayCompliance
56857
+ )
56858
+ },
56859
+ activePatrolItems
56522
56860
  };
56523
56861
  return data;
56524
56862
  }
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
56863
+ async function getPropertyManagementDashboard(siteId, period = "today" /* TODAY */, type, facility) {
56864
+ const siteIdObj = (0, import_node_server_utils199.toObjectId)(siteId);
56865
+ const startOfToday = import_moment.default.tz("Asia/Singapore").startOf("day").toDate();
56866
+ const endOfToday = import_moment.default.tz("Asia/Singapore").endOf("day").toDate();
56867
+ const upcomingEvents = await db.collection(events_namespace_collection).find({
56868
+ site: { $in: [siteIdObj, siteId] },
56869
+ status: { $nin: ["deleted", "Deleted"] },
56870
+ $or: [
56871
+ { dateTime: { $gte: startOfToday } },
56872
+ { dateTime: { $gte: startOfToday.toISOString() } }
56873
+ ]
56874
+ }).sort({ dateTime: 1 }).limit(4).toArray();
56875
+ const todayReminders = await db.collection(events_namespace_collection).find({
56876
+ site: { $in: [siteIdObj, siteId] },
56877
+ status: { $nin: ["deleted", "Deleted"] },
56878
+ $or: [
56879
+ { dateTime: { $gte: startOfToday, $lte: endOfToday } },
56880
+ {
56881
+ dateTime: {
56882
+ $gte: startOfToday.toISOString(),
56883
+ $lte: endOfToday.toISOString()
56884
+ }
56885
+ }
56886
+ ]
56887
+ }).sort({ dateTime: 1 }).limit(4).toArray();
56888
+ const [pendingIncidentDocs, pendingFacilityBookingDocs] = await Promise.all(
56889
+ [
56890
+ db.collection(incidents_namespace_collection).find({
56891
+ site: { $in: [siteIdObj, siteId] },
56892
+ status: { $in: ["pending", "Pending"] }
56893
+ }).sort({ createdAt: -1 }).toArray(),
56894
+ db.collection(facility_bookings_namespace_collection2).find({
56895
+ site: { $in: [siteIdObj, siteId] },
56896
+ status: { $in: ["Pending", "pending", "For Review", "for review"] }
56897
+ }).sort({ createdAt: -1 }).toArray()
56898
+ ]
56572
56899
  );
56573
- const bulletinBoards = await getMetric(
56574
- bulletin_boards_namespace_collection,
56575
- siteId,
56576
- bulletinBoard
56900
+ const pendingIncidentCount = pendingIncidentDocs.length;
56901
+ const pendingFacilityBookingCount = pendingFacilityBookingDocs.length;
56902
+ const todayAttentions = [];
56903
+ if (pendingIncidentCount > 0) {
56904
+ todayAttentions.push({
56905
+ id: "incidents-pending",
56906
+ title: `${pendingIncidentCount} incident${pendingIncidentCount === 1 ? "" : "s"} pending acknowledge`,
56907
+ createdAt: pendingIncidentDocs[0].updatedAt || pendingIncidentDocs[0].createdAt || /* @__PURE__ */ new Date()
56908
+ });
56909
+ }
56910
+ if (pendingFacilityBookingCount > 0) {
56911
+ todayAttentions.push({
56912
+ id: "facility-booking-pending",
56913
+ title: `${pendingFacilityBookingCount} facility booking${pendingFacilityBookingCount === 1 ? "" : "s"} need approval`,
56914
+ createdAt: pendingFacilityBookingDocs[0].createdAt || /* @__PURE__ */ new Date()
56915
+ });
56916
+ }
56917
+ todayAttentions.sort(
56918
+ (a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
56577
56919
  );
56578
- const events = await getMetric(events_namespace_collection, siteId, event);
56579
- const facilityBookings = await getMetric(
56580
- facility_bookings_namespace_collection,
56581
- siteId,
56582
- facilityBooking
56920
+ const visitorMatchObj = {};
56921
+ if (type) {
56922
+ visitorMatchObj.type = type;
56923
+ }
56924
+ const facilityMatchObj = {};
56925
+ if (facility) {
56926
+ try {
56927
+ facilityMatchObj.facility = { $in: [facility, new import_mongodb121.ObjectId(facility)] };
56928
+ } catch (e) {
56929
+ facilityMatchObj.facility = facility;
56930
+ }
56931
+ }
56932
+ const today = /* @__PURE__ */ new Date();
56933
+ today.setHours(0, 0, 0, 0);
56934
+ const yesterday = /* @__PURE__ */ new Date();
56935
+ yesterday.setDate(today.getDate() - 1);
56936
+ yesterday.setHours(0, 0, 0, 0);
56937
+ const yesterdayEnd = new Date(yesterday);
56938
+ yesterdayEnd.setHours(23, 59, 59, 999);
56939
+ const todayEnd = formatEndDate(/* @__PURE__ */ new Date());
56940
+ const periodRange = getDateRange(period);
56941
+ const incidentCollection = db.collection(incidents_namespace_collection);
56942
+ const visitorCollection = db.collection(visitors_namespace_collection);
56943
+ const facilityCollection = db.collection(
56944
+ facility_bookings_namespace_collection2
56583
56945
  );
56946
+ const [
56947
+ workOrderReport,
56948
+ yesterdayWorkOrderReport,
56949
+ todayWorkOrderReport,
56950
+ incidentReport,
56951
+ yesterdayIncidentReport,
56952
+ todayIncidentReport,
56953
+ visitorReport,
56954
+ yesterdayVisitorReport,
56955
+ todayVisitorReport,
56956
+ currentlyOnSiteCount,
56957
+ facilityReport,
56958
+ yesterdayFacilityReport,
56959
+ todayFacilityReport
56960
+ ] = await Promise.all([
56961
+ workOrderCollection.aggregate([
56962
+ {
56963
+ $match: {
56964
+ site: { $in: [siteIdObj, siteId] },
56965
+ createdAt: periodRange,
56966
+ status: { $nin: ["completed"] }
56967
+ }
56968
+ },
56969
+ {
56970
+ $facet: {
56971
+ total: [{ $count: "count" }],
56972
+ inProgress: [
56973
+ { $match: { status: "in-progress" } },
56974
+ { $count: "count" }
56975
+ ]
56976
+ }
56977
+ }
56978
+ ]).toArray(),
56979
+ workOrderCollection.aggregate([
56980
+ {
56981
+ $match: {
56982
+ site: { $in: [siteIdObj, siteId] },
56983
+ createdAt: { $gte: yesterday, $lte: yesterdayEnd },
56984
+ status: { $nin: ["completed"] }
56985
+ }
56986
+ },
56987
+ { $count: "count" }
56988
+ ]).toArray(),
56989
+ workOrderCollection.aggregate([
56990
+ {
56991
+ $match: {
56992
+ site: { $in: [siteIdObj, siteId] },
56993
+ createdAt: { $gte: today, $lte: todayEnd },
56994
+ status: { $nin: ["completed"] }
56995
+ }
56996
+ },
56997
+ { $count: "count" }
56998
+ ]).toArray(),
56999
+ incidentCollection.aggregate([
57000
+ {
57001
+ $match: {
57002
+ site: { $in: [siteIdObj, siteId] },
57003
+ status: { $in: ["pending", "Pending"] },
57004
+ createdAt: periodRange
57005
+ }
57006
+ },
57007
+ { $count: "count" }
57008
+ ]).toArray(),
57009
+ incidentCollection.aggregate([
57010
+ {
57011
+ $match: {
57012
+ site: { $in: [siteIdObj, siteId] },
57013
+ status: { $in: ["pending", "Pending"] },
57014
+ createdAt: { $gte: yesterday, $lte: yesterdayEnd }
57015
+ }
57016
+ },
57017
+ { $count: "count" }
57018
+ ]).toArray(),
57019
+ incidentCollection.aggregate([
57020
+ {
57021
+ $match: {
57022
+ site: { $in: [siteIdObj, siteId] },
57023
+ status: { $in: ["pending", "Pending"] },
57024
+ createdAt: { $gte: today, $lte: todayEnd }
57025
+ }
57026
+ },
57027
+ { $count: "count" }
57028
+ ]).toArray(),
57029
+ visitorCollection.aggregate([
57030
+ {
57031
+ $match: {
57032
+ site: { $in: [siteIdObj, siteId] },
57033
+ ...visitorMatchObj,
57034
+ createdAt: periodRange,
57035
+ status: { $ne: "deleted" }
57036
+ }
57037
+ },
57038
+ { $count: "count" }
57039
+ ]).toArray(),
57040
+ visitorCollection.aggregate([
57041
+ {
57042
+ $match: {
57043
+ site: { $in: [siteIdObj, siteId] },
57044
+ ...visitorMatchObj,
57045
+ createdAt: { $gte: yesterday, $lte: yesterdayEnd },
57046
+ status: { $ne: "deleted" }
57047
+ }
57048
+ },
57049
+ { $count: "count" }
57050
+ ]).toArray(),
57051
+ visitorCollection.aggregate([
57052
+ {
57053
+ $match: {
57054
+ site: { $in: [siteIdObj, siteId] },
57055
+ ...visitorMatchObj,
57056
+ createdAt: { $gte: today, $lte: todayEnd },
57057
+ status: { $ne: "deleted" }
57058
+ }
57059
+ },
57060
+ { $count: "count" }
57061
+ ]).toArray(),
57062
+ visitorCollection.countDocuments({
57063
+ site: { $in: [siteIdObj, siteId] },
57064
+ ...visitorMatchObj,
57065
+ checkIn: { $ne: null },
57066
+ checkOut: null,
57067
+ status: { $ne: "deleted" }
57068
+ }),
57069
+ facilityCollection.aggregate([
57070
+ {
57071
+ $match: {
57072
+ site: { $in: [siteIdObj, siteId] },
57073
+ ...facilityMatchObj,
57074
+ $or: [
57075
+ { createdAt: periodRange },
57076
+ {
57077
+ createdAt: {
57078
+ $gte: periodRange.$gte.toISOString(),
57079
+ $lte: periodRange.$lte.toISOString()
57080
+ }
57081
+ }
57082
+ ],
57083
+ status: { $nin: ["deleted", "Deleted"] }
57084
+ }
57085
+ },
57086
+ {
57087
+ $facet: {
57088
+ total: [{ $count: "count" }],
57089
+ ongoing: [
57090
+ {
57091
+ $match: {
57092
+ status: {
57093
+ $in: ["Approved", "Ongoing"]
57094
+ }
57095
+ }
57096
+ },
57097
+ { $count: "count" }
57098
+ ],
57099
+ waitingApproval: [
57100
+ {
57101
+ $match: {
57102
+ status: {
57103
+ $in: ["Pending", "pending", "For Review", "for review"]
57104
+ }
57105
+ }
57106
+ },
57107
+ { $count: "count" }
57108
+ ]
57109
+ }
57110
+ }
57111
+ ]).toArray(),
57112
+ facilityCollection.aggregate([
57113
+ {
57114
+ $match: {
57115
+ site: { $in: [siteIdObj, siteId] },
57116
+ ...facilityMatchObj,
57117
+ $or: [
57118
+ { createdAt: { $gte: yesterday, $lte: yesterdayEnd } },
57119
+ {
57120
+ createdAt: {
57121
+ $gte: yesterday.toISOString(),
57122
+ $lte: yesterdayEnd.toISOString()
57123
+ }
57124
+ }
57125
+ ],
57126
+ status: { $nin: ["deleted", "Deleted"] }
57127
+ }
57128
+ },
57129
+ { $count: "count" }
57130
+ ]).toArray(),
57131
+ facilityCollection.aggregate([
57132
+ {
57133
+ $match: {
57134
+ site: { $in: [siteIdObj, siteId] },
57135
+ ...facilityMatchObj,
57136
+ $or: [
57137
+ { createdAt: { $gte: today, $lte: todayEnd } },
57138
+ {
57139
+ createdAt: {
57140
+ $gte: today.toISOString(),
57141
+ $lte: todayEnd.toISOString()
57142
+ }
57143
+ }
57144
+ ],
57145
+ status: { $nin: ["deleted", "Deleted"] }
57146
+ }
57147
+ },
57148
+ { $count: "count" }
57149
+ ]).toArray()
57150
+ ]);
57151
+ const wFacet = workOrderReport[0] ?? { total: [], inProgress: [] };
57152
+ const fFacet = facilityReport[0] ?? {
57153
+ total: [],
57154
+ ongoing: [],
57155
+ waitingApproval: []
57156
+ };
56584
57157
  const data = {
56585
- feedbacks,
56586
- workOrders,
56587
- vehicles,
56588
- buildings,
56589
- visitors,
56590
- incidents,
56591
- sitePeople: _sitePeople,
56592
- bulletinBoards,
56593
- events,
56594
- facilityBookings
57158
+ openWorkOrder: {
57159
+ count: wFacet.total[0]?.count ?? 0,
57160
+ inProgress: wFacet.inProgress[0]?.count ?? 0,
57161
+ percentage: calculatePercentageChange(
57162
+ todayWorkOrderReport[0]?.count ?? 0,
57163
+ yesterdayWorkOrderReport[0]?.count ?? 0
57164
+ )
57165
+ },
57166
+ openIncidents: {
57167
+ count: incidentReport[0]?.count ?? 0,
57168
+ highSeverity: 0,
57169
+ percentage: calculatePercentageChange(
57170
+ todayIncidentReport[0]?.count ?? 0,
57171
+ yesterdayIncidentReport[0]?.count ?? 0
57172
+ )
57173
+ },
57174
+ visitors: {
57175
+ count: visitorReport[0]?.count ?? 0,
57176
+ currentlyOnSite: currentlyOnSiteCount,
57177
+ percentage: calculatePercentageChange(
57178
+ todayVisitorReport[0]?.count ?? 0,
57179
+ yesterdayVisitorReport[0]?.count ?? 0
57180
+ )
57181
+ },
57182
+ facilityBooking: {
57183
+ count: fFacet.total[0]?.count ?? 0,
57184
+ ongoing: fFacet.ongoing[0]?.count ?? 0,
57185
+ waitingApproval: fFacet.waitingApproval[0]?.count ?? 0,
57186
+ percentage: calculatePercentageChange(
57187
+ todayFacilityReport[0]?.count ?? 0,
57188
+ yesterdayFacilityReport[0]?.count ?? 0
57189
+ )
57190
+ },
57191
+ upcomingEvents,
57192
+ todayReminders,
57193
+ todayAttentions
56595
57194
  };
56596
57195
  return data;
56597
57196
  }
@@ -56621,61 +57220,13 @@ function useNewDashboardRepo() {
56621
57220
  async function getServiceDashboard({
56622
57221
  site,
56623
57222
  serviceType,
56624
- period = "today" /* TODAY */,
56625
- type,
56626
- facility
57223
+ period = "today" /* TODAY */
56627
57224
  }) {
56628
57225
  try {
56629
57226
  site = new import_mongodb121.ObjectId(site);
56630
57227
  } catch (error) {
56631
57228
  throw new import_node_server_utils199.BadRequestError("Invalid site ID format.");
56632
57229
  }
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
57230
  const today = /* @__PURE__ */ new Date();
56680
57231
  today.setHours(0, 0, 0, 0);
56681
57232
  const yesterday = /* @__PURE__ */ new Date();
@@ -56686,530 +57237,6 @@ function useNewDashboardRepo() {
56686
57237
  const todayEnd = formatEndDate(/* @__PURE__ */ new Date());
56687
57238
  const periodRange = getDateRange(period);
56688
57239
  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
57240
  const workOrderService = workOrderServiceMap[serviceType] ?? serviceType;
57214
57241
  const [
57215
57242
  workOrderReport,
@@ -57716,13 +57743,8 @@ function useNewDashboardController() {
57716
57743
  try {
57717
57744
  const schema2 = import_joi112.default.object({
57718
57745
  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
57746
+ period: periodField,
57747
+ type: import_joi112.default.string().optional().allow("", null)
57726
57748
  });
57727
57749
  const { error, value } = schema2.validate({
57728
57750
  site: req.params.site,
@@ -57734,25 +57756,11 @@ function useNewDashboardController() {
57734
57756
  next(new import_node_server_utils200.BadRequestError(messages));
57735
57757
  return;
57736
57758
  }
57737
- const {
57738
- site,
57739
- feedbackPeriod,
57740
- workOrderPeriod,
57741
- vehiclePeriod,
57742
- buildingPeriod,
57743
- visitorPeriod,
57744
- incidentPeriod,
57745
- guestPeriod
57746
- } = value;
57759
+ const { site, period, type } = value;
57747
57760
  const data = await _getSecurityDashboard({
57748
57761
  siteId: site,
57749
- feedback: feedbackPeriod,
57750
- workOrder: workOrderPeriod,
57751
- vehicle: vehiclePeriod,
57752
- building: buildingPeriod,
57753
- visitor: visitorPeriod,
57754
- incident: incidentPeriod,
57755
- guest: guestPeriod
57762
+ period,
57763
+ type
57756
57764
  });
57757
57765
  res.status(200).json(data);
57758
57766
  return;
@@ -57766,16 +57774,9 @@ function useNewDashboardController() {
57766
57774
  try {
57767
57775
  const schema2 = import_joi112.default.object({
57768
57776
  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
57777
+ period: periodField,
57778
+ type: import_joi112.default.string().optional().allow("", null),
57779
+ facility: import_joi112.default.string().hex().optional().allow("", null)
57779
57780
  });
57780
57781
  const { error, value } = schema2.validate({
57781
57782
  site: req.params.site,
@@ -57787,32 +57788,13 @@ function useNewDashboardController() {
57787
57788
  next(new import_node_server_utils200.BadRequestError(messages));
57788
57789
  return;
57789
57790
  }
57790
- const {
57791
+ const { site, period, type, facility } = value;
57792
+ const data = await _getPropertyManagementDashboard(
57791
57793
  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
- });
57794
+ period,
57795
+ type,
57796
+ facility
57797
+ );
57816
57798
  res.status(200).json(data);
57817
57799
  return;
57818
57800
  } catch (error) {
@@ -57826,9 +57808,7 @@ function useNewDashboardController() {
57826
57808
  const validation = import_joi112.default.object({
57827
57809
  site: import_joi112.default.string().hex().required(),
57828
57810
  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)
57811
+ period: import_joi112.default.string().valid(...Object.values(Period)).default("today" /* TODAY */)
57832
57812
  });
57833
57813
  const { error } = validation.validate(query);
57834
57814
  if (error) {
@@ -57839,15 +57819,11 @@ function useNewDashboardController() {
57839
57819
  const site = req.params.site ?? "";
57840
57820
  const serviceType = req.params.serviceType;
57841
57821
  const period = req.query.period;
57842
- const type = req.query.type;
57843
- const facility = req.query.facility;
57844
57822
  try {
57845
57823
  const data = await _getServiceDashboard({
57846
57824
  site,
57847
57825
  period,
57848
- serviceType,
57849
- type,
57850
- facility
57826
+ serviceType
57851
57827
  });
57852
57828
  res.json(data);
57853
57829
  return;
@@ -57872,7 +57848,11 @@ function useNewDashboardController() {
57872
57848
  }
57873
57849
  const { site, serviceType, period } = value;
57874
57850
  try {
57875
- const data = await _getServiceWeeklyActivity({ site, serviceType, period });
57851
+ const data = await _getServiceWeeklyActivity({
57852
+ site,
57853
+ serviceType,
57854
+ period
57855
+ });
57876
57856
  res.json(data);
57877
57857
  return;
57878
57858
  } catch (error2) {
@@ -65968,6 +65948,7 @@ function useChannelPrelovedRepo() {
65968
65948
  if (!db)
65969
65949
  throw new import_node_server_utils246.InternalServerError("Unable to connect to server.");
65970
65950
  const CHANNEL_COLLECTION = "channel-preloved";
65951
+ const CHAT_COLLECTION = "chat-preloved";
65971
65952
  const collection = db.collection(CHANNEL_COLLECTION);
65972
65953
  async function add(value, session) {
65973
65954
  try {
@@ -65986,7 +65967,85 @@ function useChannelPrelovedRepo() {
65986
65967
  };
65987
65968
  return collection.findOne(query, { session });
65988
65969
  }
65989
- return { add, getByParticipants };
65970
+ async function getChannelMessages(channelId, page = 1, limit = 10, isLoadMore = false, lastMessageId = null) {
65971
+ const chatCollection = db.collection(CHAT_COLLECTION);
65972
+ const normalizedPage = page > 0 ? page - 1 : 0;
65973
+ const normalizedLimit = limit || 10;
65974
+ const matchCriteria = {
65975
+ channelId: new import_mongodb148.ObjectId(channelId),
65976
+ deletedAt: null
65977
+ };
65978
+ if (isLoadMore && lastMessageId) {
65979
+ matchCriteria._id = { $lt: new import_mongodb148.ObjectId(lastMessageId) };
65980
+ }
65981
+ try {
65982
+ const result = await chatCollection.aggregate([
65983
+ { $match: matchCriteria },
65984
+ {
65985
+ $lookup: {
65986
+ from: "users",
65987
+ localField: "senderId",
65988
+ foreignField: "_id",
65989
+ pipeline: [
65990
+ {
65991
+ $project: {
65992
+ name: 1,
65993
+ profile: 1,
65994
+ type: 1
65995
+ }
65996
+ }
65997
+ ],
65998
+ as: "senderId"
65999
+ }
66000
+ },
66001
+ { $unwind: { path: "$senderId", preserveNullAndEmptyArrays: true } },
66002
+ {
66003
+ $lookup: {
66004
+ from: "bid-preloved",
66005
+ localField: "bidId",
66006
+ foreignField: "_id",
66007
+ pipeline: [
66008
+ { $project: { price: 1, message: 1, status: 1, type: 1 } }
66009
+ ],
66010
+ as: "bidId"
66011
+ }
66012
+ },
66013
+ { $unwind: { path: "$bidId", preserveNullAndEmptyArrays: true } },
66014
+ {
66015
+ $lookup: {
66016
+ from: "post-preloved",
66017
+ localField: "postId",
66018
+ foreignField: "_id",
66019
+ pipeline: [{ $project: { title: 1, status: 1, reserverId: 1 } }],
66020
+ as: "postDetails"
66021
+ }
66022
+ },
66023
+ {
66024
+ $unwind: {
66025
+ path: "$postDetails",
66026
+ preserveNullAndEmptyArrays: true
66027
+ }
66028
+ },
66029
+ { $sort: { createdAt: -1 } },
66030
+ {
66031
+ $facet: {
66032
+ totalCount: [{ $count: "count" }],
66033
+ items: [
66034
+ { $skip: normalizedPage * normalizedLimit },
66035
+ { $limit: normalizedLimit }
66036
+ ]
66037
+ }
66038
+ }
66039
+ ]).toArray();
66040
+ const totalCount = result[0].totalCount[0]?.count ?? 0;
66041
+ const items = result[0].items;
66042
+ items.reverse();
66043
+ return (0, import_node_server_utils246.paginate)(items, normalizedPage, normalizedLimit, totalCount);
66044
+ } catch (error) {
66045
+ throw error;
66046
+ }
66047
+ }
66048
+ return { add, getByParticipants, getChannelMessages };
65990
66049
  }
65991
66050
 
65992
66051
  // src/services/chat-preloved.service.ts
@@ -66102,8 +66161,9 @@ function useChatPrelovedController() {
66102
66161
 
66103
66162
  // src/controllers/channel-preloved.controller.ts
66104
66163
  var import_node_server_utils249 = require("@7365admin1/node-server-utils");
66164
+ var import_joi144 = __toESM(require("joi"));
66105
66165
  function useChannelPrelovedController() {
66106
- const { add: _add } = useChannelPrelovedRepo();
66166
+ const { add: _add, getChannelMessages: _getChannelMessages } = useChannelPrelovedRepo();
66107
66167
  async function add(req, res, next) {
66108
66168
  const { error, value } = schemaChannelPreloved.validate(req.body, {
66109
66169
  abortEarly: false
@@ -66122,11 +66182,51 @@ function useChannelPrelovedController() {
66122
66182
  next(error2);
66123
66183
  }
66124
66184
  }
66125
- return { add };
66185
+ async function getChannelMessages(req, res, next) {
66186
+ const paramsSchema = import_joi144.default.object({
66187
+ id: import_joi144.default.string().hex().length(24).required()
66188
+ });
66189
+ const querySchema = import_joi144.default.object({
66190
+ page: import_joi144.default.number().integer().min(1).default(1),
66191
+ limit: import_joi144.default.number().integer().min(1).max(100).default(10),
66192
+ isLoadMore: import_joi144.default.boolean().default(false),
66193
+ lastMessageId: import_joi144.default.string().hex().length(24).optional().allow("", null)
66194
+ });
66195
+ const { error: paramError, value: params } = paramsSchema.validate(
66196
+ req.params
66197
+ );
66198
+ if (paramError) {
66199
+ import_node_server_utils249.logger.log({ level: "error", message: paramError.message });
66200
+ next(new import_node_server_utils249.BadRequestError(paramError.message));
66201
+ return;
66202
+ }
66203
+ const { error: queryError, value: query } = querySchema.validate(
66204
+ req.query
66205
+ );
66206
+ if (queryError) {
66207
+ import_node_server_utils249.logger.log({ level: "error", message: queryError.message });
66208
+ next(new import_node_server_utils249.BadRequestError(queryError.message));
66209
+ return;
66210
+ }
66211
+ try {
66212
+ const data = await _getChannelMessages(
66213
+ params.id,
66214
+ query.page,
66215
+ query.limit,
66216
+ query.isLoadMore,
66217
+ query.lastMessageId || null
66218
+ );
66219
+ res.status(200).json(data);
66220
+ } catch (error) {
66221
+ import_node_server_utils249.logger.log({ level: "error", message: error.message });
66222
+ next(error);
66223
+ }
66224
+ }
66225
+ return { add, getChannelMessages };
66126
66226
  }
66127
66227
 
66128
66228
  // src/models/online-forms-v2.model.ts
66129
- var import_joi144 = __toESM(require("joi"));
66229
+ var import_joi145 = __toESM(require("joi"));
66130
66230
  var import_mongodb149 = require("mongodb");
66131
66231
  var FormEntryStatus = /* @__PURE__ */ ((FormEntryStatus2) => {
66132
66232
  FormEntryStatus2["ACTIVE"] = "active";
@@ -66134,49 +66234,49 @@ var FormEntryStatus = /* @__PURE__ */ ((FormEntryStatus2) => {
66134
66234
  FormEntryStatus2["DELETED"] = "deleted";
66135
66235
  return FormEntryStatus2;
66136
66236
  })(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)
66237
+ var schemaFormEntry = import_joi145.default.object({
66238
+ _id: import_joi145.default.string().hex().optional().allow("", null),
66239
+ formType: import_joi145.default.string().required(),
66240
+ block: import_joi145.default.string().optional().allow(null, ""),
66241
+ level: import_joi145.default.string().optional().allow(null, ""),
66242
+ unit: import_joi145.default.string().optional().allow(null, ""),
66243
+ name: import_joi145.default.string().optional().allow(null, ""),
66244
+ phoneNumber: import_joi145.default.string().optional().allow(null, ""),
66245
+ createdBy: import_joi145.default.string().required(),
66246
+ fields: import_joi145.default.object().pattern(
66247
+ import_joi145.default.string(),
66248
+ import_joi145.default.alternatives().try(
66249
+ import_joi145.default.string(),
66250
+ import_joi145.default.number(),
66251
+ import_joi145.default.boolean(),
66252
+ import_joi145.default.valid(null)
66153
66253
  )
66154
66254
  ).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)
66255
+ status: import_joi145.default.string().optional().allow("", null),
66256
+ org: import_joi145.default.string().hex().optional().allow("", null),
66257
+ site: import_joi145.default.string().hex().optional().allow("", null),
66258
+ createdAt: import_joi145.default.date().optional().allow("", null),
66259
+ updatedAt: import_joi145.default.date().optional().allow("", null),
66260
+ deletedAt: import_joi145.default.date().optional().allow("", null)
66161
66261
  });
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)
66262
+ var schemaUpdateFormEntry = import_joi145.default.object({
66263
+ _id: import_joi145.default.string().hex().required(),
66264
+ formType: import_joi145.default.string().optional().allow("", null),
66265
+ block: import_joi145.default.string().optional().allow(null, ""),
66266
+ level: import_joi145.default.string().optional().allow(null, ""),
66267
+ unit: import_joi145.default.string().optional().allow(null, ""),
66268
+ fields: import_joi145.default.object().pattern(
66269
+ import_joi145.default.string(),
66270
+ import_joi145.default.alternatives().try(
66271
+ import_joi145.default.string(),
66272
+ import_joi145.default.number(),
66273
+ import_joi145.default.boolean(),
66274
+ import_joi145.default.valid(null)
66175
66275
  )
66176
66276
  ).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)
66277
+ status: import_joi145.default.string().optional().allow("", null),
66278
+ updatedAt: import_joi145.default.date().optional().allow("", null),
66279
+ deletedAt: import_joi145.default.date().optional().allow("", null)
66180
66280
  });
66181
66281
  function MFormEntry(value) {
66182
66282
  const { error } = schemaFormEntry.validate(value);
@@ -66221,34 +66321,34 @@ function MFormEntry(value) {
66221
66321
  deletedAt: value.deletedAt ?? null
66222
66322
  };
66223
66323
  }
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)
66324
+ var residentFormEntry = import_joi145.default.object({
66325
+ _id: import_joi145.default.string().hex().optional().allow("", null),
66326
+ typeOfForm: import_joi145.default.string().optional().allow("", null),
66327
+ unitNumber: import_joi145.default.string().optional().allow(null, ""),
66328
+ fields: import_joi145.default.object().pattern(
66329
+ import_joi145.default.string(),
66330
+ import_joi145.default.alternatives().try(
66331
+ import_joi145.default.string(),
66332
+ import_joi145.default.number(),
66333
+ import_joi145.default.boolean(),
66334
+ import_joi145.default.valid(null)
66235
66335
  )
66236
66336
  ).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)
66337
+ status: import_joi145.default.string().optional().allow("", null),
66338
+ org: import_joi145.default.string().hex().optional().allow("", null),
66339
+ site: import_joi145.default.string().hex().optional().allow("", null),
66340
+ userId: import_joi145.default.string().hex().optional().allow("", null),
66341
+ createdAt: import_joi145.default.date().optional().allow("", null),
66342
+ updatedAt: import_joi145.default.date().optional().allow("", null),
66343
+ deletedAt: import_joi145.default.date().optional().allow("", null),
66344
+ remarks: import_joi145.default.string().optional().allow("", null),
66345
+ managementValues: import_joi145.default.object().pattern(
66346
+ import_joi145.default.string(),
66347
+ import_joi145.default.alternatives().try(
66348
+ import_joi145.default.string(),
66349
+ import_joi145.default.number(),
66350
+ import_joi145.default.boolean(),
66351
+ import_joi145.default.valid(null)
66252
66352
  )
66253
66353
  ).optional().allow(null, "")
66254
66354
  });
@@ -66509,7 +66609,7 @@ function useFormEntryRepo() {
66509
66609
 
66510
66610
  // src/controllers/online-forms-v2.controller.ts
66511
66611
  var import_node_server_utils251 = require("@7365admin1/node-server-utils");
66512
- var import_joi145 = __toESM(require("joi"));
66612
+ var import_joi146 = __toESM(require("joi"));
66513
66613
  var import_exceljs3 = __toESM(require("exceljs"));
66514
66614
  var import_fs7 = __toESM(require("fs"));
66515
66615
  function useFormEntryController() {
@@ -66585,13 +66685,13 @@ function useFormEntryController() {
66585
66685
  }
66586
66686
  async function getAll(req, res, next) {
66587
66687
  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)
66688
+ const schema2 = import_joi146.default.object({
66689
+ search: import_joi146.default.string().optional().allow("", null),
66690
+ page: import_joi146.default.number().integer().min(1).allow("", null).default(1),
66691
+ limit: import_joi146.default.number().integer().min(1).max(100).allow("", null).default(10),
66692
+ status: import_joi146.default.string().optional().allow(null, ""),
66693
+ org: import_joi146.default.string().hex().optional().allow("", null),
66694
+ site: import_joi146.default.string().hex().optional().allow("", null)
66595
66695
  });
66596
66696
  const { error, value } = schema2.validate(req.query);
66597
66697
  if (error) {
@@ -66612,8 +66712,8 @@ function useFormEntryController() {
66612
66712
  }
66613
66713
  async function getFormEntryById(req, res, next) {
66614
66714
  try {
66615
- const schema2 = import_joi145.default.object({
66616
- _id: import_joi145.default.string().hex().length(24).required()
66715
+ const schema2 = import_joi146.default.object({
66716
+ _id: import_joi146.default.string().hex().length(24).required()
66617
66717
  });
66618
66718
  const { error, value } = schema2.validate({ _id: req.params.id });
66619
66719
  if (error) {
@@ -66656,7 +66756,7 @@ function useFormEntryController() {
66656
66756
  }
66657
66757
  async function deleteFormEntryById(req, res, next) {
66658
66758
  try {
66659
- const validation = import_joi145.default.string().hex().required();
66759
+ const validation = import_joi146.default.string().hex().required();
66660
66760
  const _id = req.params.id;
66661
66761
  const { error } = validation.validate(_id);
66662
66762
  if (error) {
@@ -66723,10 +66823,10 @@ function useFormEntryController() {
66723
66823
  async function residentForm(req, res, next) {
66724
66824
  try {
66725
66825
  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()
66826
+ const residentFormPayload = import_joi146.default.object({
66827
+ org: import_joi146.default.string().hex().required(),
66828
+ site: import_joi146.default.string().hex().required(),
66829
+ userId: import_joi146.default.string().hex().required()
66730
66830
  });
66731
66831
  const { error } = residentFormPayload.validate({ site, userId, org }, { abortEarly: true });
66732
66832
  if (error) {
@@ -66795,7 +66895,7 @@ function useBuildingLevelService() {
66795
66895
 
66796
66896
  // src/controllers/building-level.controller.ts
66797
66897
  var import_node_server_utils253 = require("@7365admin1/node-server-utils");
66798
- var import_joi146 = __toESM(require("joi"));
66898
+ var import_joi147 = __toESM(require("joi"));
66799
66899
  function useBuildingLevelController() {
66800
66900
  const { add: _add, updateLevelById: _updateLevelById } = useBuildingLevelService();
66801
66901
  const {
@@ -66824,12 +66924,12 @@ function useBuildingLevelController() {
66824
66924
  }
66825
66925
  async function getAll(req, res, next) {
66826
66926
  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 */)
66927
+ const validation = import_joi147.default.object({
66928
+ page: import_joi147.default.number().min(1).optional().default(1),
66929
+ limit: import_joi147.default.number().min(1).optional().default(20),
66930
+ search: import_joi147.default.string().optional().allow("", null),
66931
+ site: import_joi147.default.string().hex().length(24).optional().allow("", null),
66932
+ status: import_joi147.default.string().valid(...Object.values(BuildingLevelStatus)).default("active" /* ACTIVE */)
66833
66933
  });
66834
66934
  const { error, value } = validation.validate(req.query, {
66835
66935
  abortEarly: false
@@ -66856,8 +66956,8 @@ function useBuildingLevelController() {
66856
66956
  }
66857
66957
  async function getById(req, res, next) {
66858
66958
  try {
66859
- const schema2 = import_joi146.default.object({
66860
- id: import_joi146.default.string().hex().length(24).required()
66959
+ const schema2 = import_joi147.default.object({
66960
+ id: import_joi147.default.string().hex().length(24).required()
66861
66961
  });
66862
66962
  const { error, value } = schema2.validate({ id: req.params.id });
66863
66963
  if (error) {
@@ -66895,8 +66995,8 @@ function useBuildingLevelController() {
66895
66995
  }
66896
66996
  async function deleteById(req, res, next) {
66897
66997
  try {
66898
- const schema2 = import_joi146.default.object({
66899
- id: import_joi146.default.string().hex().required()
66998
+ const schema2 = import_joi147.default.object({
66999
+ id: import_joi147.default.string().hex().required()
66900
67000
  });
66901
67001
  const { error, value } = schema2.validate({ id: req.params.id });
66902
67002
  if (error) {
@@ -66915,11 +67015,11 @@ function useBuildingLevelController() {
66915
67015
  }
66916
67016
  async function batchUpdateByIds(req, res, next) {
66917
67017
  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)
67018
+ const schema2 = import_joi147.default.array().items(
67019
+ import_joi147.default.object({
67020
+ _id: import_joi147.default.string().hex().length(24).required(),
67021
+ value: import_joi147.default.object({
67022
+ name: import_joi147.default.string().optional().allow("", null)
66923
67023
  }).required()
66924
67024
  })
66925
67025
  );
@@ -66942,9 +67042,9 @@ function useBuildingLevelController() {
66942
67042
  }
66943
67043
  async function getBuildingLevelList(req, res, next) {
66944
67044
  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()
67045
+ const schema2 = import_joi147.default.object({
67046
+ site: import_joi147.default.string().hex().length(24).required(),
67047
+ block: import_joi147.default.string().hex().length(24).required()
66948
67048
  });
66949
67049
  const { error, value } = schema2.validate({
66950
67050
  site: req.params.siteId,