@iservice365/module-hygiene 0.1.0 → 0.1.2

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
@@ -31,19 +31,27 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var src_exports = {};
32
32
  __export(src_exports, {
33
33
  MArea: () => MArea,
34
+ MAreaChecklist: () => MAreaChecklist,
34
35
  MParentChecklist: () => MParentChecklist,
35
36
  MScheduleTaskArea: () => MScheduleTaskArea,
36
37
  MToiletLocation: () => MToiletLocation,
37
38
  MUnit: () => MUnit,
39
+ MUnitChecklist: () => MUnitChecklist,
40
+ allowedStatus: () => allowedStatus,
41
+ allowedTypes: () => allowedTypes,
42
+ areaChecklistSchema: () => areaChecklistSchema,
38
43
  areaSchema: () => areaSchema,
39
44
  parentChecklistSchema: () => parentChecklistSchema,
40
45
  scheduleTaskAreaSchema: () => scheduleTaskAreaSchema,
41
46
  toiletLocationSchema: () => toiletLocationSchema,
47
+ unitChecklistSchema: () => unitChecklistSchema,
42
48
  unitSchema: () => unitSchema,
49
+ useAreaChecklistController: () => useAreaChecklistController,
50
+ useAreaChecklistRepo: () => useAreaChecklistRepo,
43
51
  useAreaController: () => useAreaController,
44
52
  useAreaRepository: () => useAreaRepository,
45
53
  useAreaService: () => useAreaService,
46
- useParentCheckilstController: () => useParentCheckilstController,
54
+ useParentChecklistController: () => useParentChecklistController,
47
55
  useParentChecklistRepo: () => useParentChecklistRepo,
48
56
  useScheduleTaskAreaController: () => useScheduleTaskAreaController,
49
57
  useScheduleTaskAreaRepository: () => useScheduleTaskAreaRepository,
@@ -51,6 +59,8 @@ __export(src_exports, {
51
59
  useToiletLocationController: () => useToiletLocationController,
52
60
  useToiletLocationRepository: () => useToiletLocationRepository,
53
61
  useToiletLocationService: () => useToiletLocationService,
62
+ useUnitChecklistController: () => useUnitChecklistController,
63
+ useUnitChecklistRepo: () => useUnitChecklistRepo,
54
64
  useUnitController: () => useUnitController,
55
65
  useUnitRepository: () => useUnitRepository,
56
66
  useUnitService: () => useUnitService
@@ -1469,33 +1479,56 @@ function useToiletLocationController() {
1469
1479
  // src/models/hygiene-parent-checklist.model.ts
1470
1480
  var import_node_server_utils9 = require("@iservice365/node-server-utils");
1471
1481
  var import_joi5 = __toESM(require("joi"));
1482
+ var import_mongodb5 = require("mongodb");
1483
+ var allowedTypes = ["cleaner", "toilet"];
1484
+ var allowedStatus = [
1485
+ "To Do",
1486
+ "Pending",
1487
+ "In Progress",
1488
+ "Completed",
1489
+ "Expired"
1490
+ ];
1472
1491
  var parentChecklistSchema = import_joi5.default.object({
1473
1492
  date: import_joi5.default.date().required(),
1474
1493
  status: import_joi5.default.array().items(
1475
1494
  import_joi5.default.object({
1476
- site: import_joi5.default.string().hex().required(),
1477
- status: import_joi5.default.string().required(),
1478
- completedAt: import_joi5.default.date().required(),
1479
- type: import_joi5.default.string().required()
1495
+ type: import_joi5.default.string().required().valid(...allowedTypes),
1496
+ site: import_joi5.default.string().hex().required()
1480
1497
  })
1481
- ).optional(),
1482
- updatedAt: import_joi5.default.date().optional().allow("", null)
1498
+ ).optional()
1483
1499
  });
1484
1500
  function MParentChecklist(value) {
1485
1501
  const { error } = parentChecklistSchema.validate(value);
1486
1502
  if (error) {
1503
+ import_node_server_utils9.logger.info(`Hygiene Parent Checklist Model: ${error.message}`);
1487
1504
  throw new import_node_server_utils9.BadRequestError(error.message);
1488
1505
  }
1506
+ if (value.status && Array.isArray(value.status)) {
1507
+ value.status = value.status.map((item) => {
1508
+ try {
1509
+ return {
1510
+ ...item,
1511
+ site: new import_mongodb5.ObjectId(item.site),
1512
+ status: item.status || "To Do",
1513
+ completedAt: item.completedAt || ""
1514
+ };
1515
+ } catch (error2) {
1516
+ throw new import_node_server_utils9.BadRequestError(
1517
+ `Invalid status site ID format: ${item.site}`
1518
+ );
1519
+ }
1520
+ });
1521
+ }
1489
1522
  return {
1490
- date: value.date,
1523
+ date: new Date(value.date),
1491
1524
  status: value.status,
1492
1525
  createdAt: /* @__PURE__ */ new Date(),
1493
- updatedAt: value.updatedAt ?? "",
1494
- deletedAt: value.deletedAt ?? ""
1526
+ updatedAt: value.updatedAt ?? ""
1495
1527
  };
1496
1528
  }
1497
1529
 
1498
1530
  // src/repositories/hygiene-parent-checklist.repository.ts
1531
+ var import_mongodb6 = require("mongodb");
1499
1532
  var import_node_server_utils10 = require("@iservice365/node-server-utils");
1500
1533
  function useParentChecklistRepo() {
1501
1534
  const db = import_node_server_utils10.useAtlas.getDb();
@@ -1504,31 +1537,39 @@ function useParentChecklistRepo() {
1504
1537
  }
1505
1538
  const namespace_collection = "hygiene-parent-checklist";
1506
1539
  const collection = db.collection(namespace_collection);
1507
- const { delNamespace, setCache, getCache, delCache } = (0, import_node_server_utils10.useCache)(namespace_collection);
1508
- async function createIndexes() {
1540
+ const { delNamespace, setCache, getCache } = (0, import_node_server_utils10.useCache)(namespace_collection);
1541
+ async function createIndex() {
1509
1542
  try {
1510
1543
  await collection.createIndexes([
1511
- { key: { date: "text" } }
1544
+ { key: { date: 1 } },
1545
+ { key: { "status.type": 1, "status.site": 1 } }
1512
1546
  ]);
1513
1547
  } catch (error) {
1514
- throw new import_node_server_utils10.InternalServerError("Failed to create index on site.");
1548
+ throw new import_node_server_utils10.InternalServerError(
1549
+ "Failed to create index on hygiene parent checklist."
1550
+ );
1515
1551
  }
1516
1552
  }
1517
- async function create(value, session) {
1553
+ async function createParentChecklist(value, session) {
1518
1554
  try {
1519
- const currentDate = /* @__PURE__ */ new Date();
1555
+ const currentDate = value.date ? new Date(value.date) : /* @__PURE__ */ new Date();
1520
1556
  const startOfDay = new Date(currentDate);
1521
- startOfDay.setDate(currentDate.getDate());
1522
1557
  startOfDay.setUTCHours(0, 0, 0, 0);
1523
1558
  const endOfDay = new Date(currentDate);
1524
- endOfDay.setDate(currentDate.getDate());
1525
1559
  endOfDay.setUTCHours(23, 59, 59, 999);
1526
- const checklistRecord = await collection.findOne({
1560
+ const existingChecklist = await collection.findOne({
1527
1561
  date: {
1528
1562
  $gte: startOfDay,
1529
1563
  $lte: endOfDay
1530
1564
  }
1531
1565
  });
1566
+ if (existingChecklist) {
1567
+ const dateStr2 = currentDate.toISOString().split("T")[0];
1568
+ import_node_server_utils10.logger.info(`Parent checklist already exists for today: ${dateStr2}`);
1569
+ return existingChecklist._id;
1570
+ }
1571
+ const processedValue = MParentChecklist(value);
1572
+ const result = await collection.insertOne(processedValue, { session });
1532
1573
  delNamespace().then(() => {
1533
1574
  import_node_server_utils10.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
1534
1575
  }).catch((err) => {
@@ -1537,186 +1578,379 @@ function useParentChecklistRepo() {
1537
1578
  err
1538
1579
  );
1539
1580
  });
1540
- if (!checklistRecord) {
1541
- value = MParentChecklist(value);
1542
- const res = await collection.insertOne(value, { session });
1543
- return res.insertedId;
1544
- }
1545
- return checklistRecord;
1581
+ const dateStr = currentDate.toISOString().split("T")[0];
1582
+ import_node_server_utils10.logger.info(
1583
+ `Created new parent checklist ${result.insertedId} for today: ${dateStr}`
1584
+ );
1585
+ return result.insertedId;
1546
1586
  } catch (error) {
1587
+ import_node_server_utils10.logger.error("Failed to create daily parent checklist", error);
1547
1588
  throw error;
1548
1589
  }
1549
1590
  }
1550
- async function get({
1591
+ async function getAllParentChecklist({
1551
1592
  page = 1,
1552
1593
  limit = 10,
1553
1594
  search = "",
1554
- sort = {},
1595
+ site,
1596
+ type,
1555
1597
  startDate = "",
1556
1598
  endDate = ""
1557
1599
  }) {
1558
1600
  page = page > 0 ? page - 1 : 0;
1559
- let dateFilter = {};
1560
- const query = {
1561
- createdAt: {
1562
- createdAt: {
1563
- $gte: new Date(startDate),
1564
- $lte: new Date(endDate)
1565
- }
1566
- }
1567
- };
1601
+ const query = {};
1568
1602
  const cacheOptions = {
1569
- createdAt: {
1570
- createdAt: {
1571
- $gte: new Date(startDate),
1572
- $lte: new Date(endDate)
1573
- }
1603
+ page,
1604
+ limit
1605
+ };
1606
+ try {
1607
+ site = new import_mongodb6.ObjectId(site);
1608
+ cacheOptions.site = site.toString();
1609
+ } catch (error) {
1610
+ throw new import_node_server_utils10.BadRequestError("Invalid site ID format.");
1611
+ }
1612
+ cacheOptions.type = type;
1613
+ query.status = {
1614
+ $elemMatch: {
1615
+ site: new import_mongodb6.ObjectId(site),
1616
+ type
1574
1617
  }
1575
1618
  };
1576
- sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
1577
- cacheOptions.sort = JSON.stringify(sort);
1578
1619
  if (search) {
1579
1620
  query.$or = [{ name: { $regex: search, $options: "i" } }];
1580
1621
  cacheOptions.search = search;
1581
1622
  }
1582
- delNamespace().then(() => {
1583
- import_node_server_utils10.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
1584
- }).catch((err) => {
1585
- import_node_server_utils10.logger.error(
1586
- `Failed to clear cache for namespace: ${namespace_collection}`,
1587
- err
1588
- );
1589
- });
1623
+ if (startDate && endDate) {
1624
+ query.createdAt = {
1625
+ $gte: new Date(startDate),
1626
+ $lte: new Date(endDate)
1627
+ };
1628
+ cacheOptions.startDate = new Date(startDate).toISOString().split("T")[0];
1629
+ cacheOptions.endDate = new Date(endDate).toISOString().split("T")[0];
1630
+ } else if (startDate) {
1631
+ query.createdAt = { $gte: new Date(startDate) };
1632
+ cacheOptions.startDate = new Date(startDate).toISOString().split("T")[0];
1633
+ } else if (endDate) {
1634
+ query.createdAt = { $lte: new Date(endDate) };
1635
+ cacheOptions.endDate = new Date(endDate).toISOString().split("T")[0];
1636
+ }
1590
1637
  const cacheKey = (0, import_node_server_utils10.makeCacheKey)(namespace_collection, cacheOptions);
1591
1638
  const cachedData = await getCache(cacheKey);
1592
1639
  if (cachedData) {
1593
1640
  import_node_server_utils10.logger.info(`Cache hit for key: ${cacheKey}`);
1594
1641
  return cachedData;
1595
1642
  }
1596
- if (startDate && endDate) {
1597
- dateFilter = {
1598
- createdAt: {
1599
- $gte: new Date(startDate),
1600
- $lte: new Date(endDate)
1643
+ try {
1644
+ const pipeline = [{ $match: query }];
1645
+ const filterConditions = [];
1646
+ filterConditions.push({ $eq: ["$$this.site", new import_mongodb6.ObjectId(site)] });
1647
+ filterConditions.push({ $eq: ["$$this.type", type] });
1648
+ pipeline.push({
1649
+ $addFields: {
1650
+ filteredStatus: {
1651
+ $filter: {
1652
+ input: "$status",
1653
+ cond: { $and: filterConditions }
1654
+ }
1655
+ }
1601
1656
  }
1602
- };
1603
- } else if (startDate) {
1604
- dateFilter = { createdAt: { $gte: new Date(startDate) } };
1605
- } else if (endDate) {
1606
- dateFilter = { createdAt: { $lte: new Date(endDate) } };
1657
+ });
1658
+ pipeline.push({
1659
+ $match: {
1660
+ filteredStatus: { $ne: [] }
1661
+ }
1662
+ });
1663
+ pipeline.push({
1664
+ $addFields: {
1665
+ statusObj: { $arrayElemAt: ["$filteredStatus", 0] }
1666
+ }
1667
+ });
1668
+ pipeline.push({
1669
+ $project: {
1670
+ _id: 1,
1671
+ date: 1,
1672
+ status: "$statusObj.status",
1673
+ completedAt: "$statusObj.completedAt",
1674
+ createdAt: 1
1675
+ }
1676
+ });
1677
+ pipeline.push(
1678
+ { $sort: { _id: -1 } },
1679
+ { $skip: page * limit },
1680
+ { $limit: limit }
1681
+ );
1682
+ const items = await collection.aggregate(pipeline).toArray();
1683
+ const length = await collection.countDocuments(query);
1684
+ const data = (0, import_node_server_utils10.paginate)(items, page, limit, length);
1685
+ setCache(cacheKey, data, 15 * 60).then(() => {
1686
+ import_node_server_utils10.logger.info(`Cache set for key: ${cacheKey}`);
1687
+ }).catch((err) => {
1688
+ import_node_server_utils10.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
1689
+ });
1690
+ return data;
1691
+ } catch (error) {
1692
+ throw error;
1607
1693
  }
1694
+ }
1695
+ async function updateParentChecklistStatuses(date) {
1608
1696
  try {
1609
- const items = await collection.aggregate([
1697
+ const currentDate = /* @__PURE__ */ new Date();
1698
+ const dateToUpdate = date || new Date(currentDate.getTime() - 24 * 60 * 60 * 1e3);
1699
+ const startOfDay = new Date(dateToUpdate);
1700
+ startOfDay.setUTCHours(0, 0, 0, 0);
1701
+ const endOfDay = new Date(dateToUpdate);
1702
+ endOfDay.setUTCHours(23, 59, 59, 999);
1703
+ import_node_server_utils10.logger.info(
1704
+ `Updating parent checklist statuses for date: ${dateToUpdate.toISOString().split("T")[0]}`
1705
+ );
1706
+ const statusUpdates = await collection.aggregate([
1610
1707
  {
1611
1708
  $match: {
1612
- ...dateFilter
1709
+ createdAt: {
1710
+ $gte: startOfDay,
1711
+ $lte: endOfDay
1712
+ }
1613
1713
  }
1614
1714
  },
1615
1715
  {
1616
- $facet: {
1617
- totalCount: [{ $count: "count" }],
1618
- items: [
1619
- { $sort: { createdAt: -1 } },
1620
- { $skip: page * limit },
1621
- { $limit: limit }
1622
- ]
1716
+ $lookup: {
1717
+ from: "hygiene-checklist.areas",
1718
+ localField: "_id",
1719
+ foreignField: "parentChecklist",
1720
+ pipeline: [
1721
+ {
1722
+ $group: {
1723
+ _id: {
1724
+ site: "$site",
1725
+ type: "$type"
1726
+ },
1727
+ completedCount: {
1728
+ $sum: {
1729
+ $cond: [{ $eq: ["$status", "Completed"] }, 1, 0]
1730
+ }
1731
+ },
1732
+ inProgressCount: {
1733
+ $sum: {
1734
+ $cond: [{ $eq: ["$status", "In Progress"] }, 1, 0]
1735
+ }
1736
+ },
1737
+ toDoCount: {
1738
+ $sum: {
1739
+ $cond: [
1740
+ {
1741
+ $or: [
1742
+ { $eq: ["$status", "To Do"] },
1743
+ { $eq: ["$status", "Pending"] }
1744
+ ]
1745
+ },
1746
+ 1,
1747
+ 0
1748
+ ]
1749
+ }
1750
+ },
1751
+ totalCount: { $sum: 1 }
1752
+ }
1753
+ },
1754
+ {
1755
+ $addFields: {
1756
+ finalStatus: {
1757
+ $cond: {
1758
+ if: {
1759
+ $and: [
1760
+ { $gt: ["$completedCount", 0] },
1761
+ { $eq: ["$inProgressCount", 0] },
1762
+ { $eq: ["$toDoCount", 0] }
1763
+ ]
1764
+ },
1765
+ then: "Completed",
1766
+ else: {
1767
+ $cond: {
1768
+ if: {
1769
+ $and: [
1770
+ { $eq: ["$completedCount", 0] },
1771
+ { $eq: ["$inProgressCount", 0] }
1772
+ ]
1773
+ },
1774
+ then: "Expired",
1775
+ else: "In Progress"
1776
+ }
1777
+ }
1778
+ }
1779
+ },
1780
+ completedAt: {
1781
+ $cond: {
1782
+ if: {
1783
+ $and: [
1784
+ { $gt: ["$completedCount", 0] },
1785
+ { $eq: ["$inProgressCount", 0] },
1786
+ { $eq: ["$toDoCount", 0] }
1787
+ ]
1788
+ },
1789
+ then: /* @__PURE__ */ new Date(),
1790
+ else: null
1791
+ }
1792
+ }
1793
+ }
1794
+ }
1795
+ ],
1796
+ as: "areaStats"
1797
+ }
1798
+ },
1799
+ {
1800
+ $addFields: {
1801
+ newStatus: {
1802
+ $map: {
1803
+ input: "$areaStats",
1804
+ as: "stat",
1805
+ in: {
1806
+ site: "$$stat._id.site",
1807
+ type: "$$stat._id.type",
1808
+ status: "$$stat.finalStatus",
1809
+ completedAt: "$$stat.completedAt"
1810
+ }
1811
+ }
1812
+ }
1813
+ }
1814
+ },
1815
+ { $match: { newStatus: { $ne: [] } } },
1816
+ {
1817
+ $project: {
1818
+ _id: 1,
1819
+ newStatus: 1
1623
1820
  }
1624
1821
  }
1625
1822
  ]).toArray();
1626
- const length = await collection.countDocuments(dateFilter);
1627
- const data = (0, import_node_server_utils10.paginate)(items, page, limit, length);
1628
- setCache(cacheKey, data, 15 * 60).then(() => {
1629
- import_node_server_utils10.logger.info(`Cache set for key: ${cacheKey}`);
1630
- }).catch((err) => {
1631
- import_node_server_utils10.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
1823
+ import_node_server_utils10.logger.info(
1824
+ `Found ${statusUpdates.length} parent checklists to potentially update`
1825
+ );
1826
+ if (statusUpdates.length === 0) {
1827
+ import_node_server_utils10.logger.info(
1828
+ `No parent checklists found for date range: ${startOfDay.toISOString()} to ${endOfDay.toISOString()}`
1829
+ );
1830
+ return null;
1831
+ }
1832
+ const bulkOps = statusUpdates.map((update) => {
1833
+ const statusTypes = update.newStatus.map((s) => `${s.type}(${s.status})`).join(", ");
1834
+ import_node_server_utils10.logger.info(
1835
+ `Updating parent checklist ${update._id} with ${update.newStatus.length} status entries: [${statusTypes}]`
1836
+ );
1837
+ return {
1838
+ updateOne: {
1839
+ filter: { _id: update._id },
1840
+ update: {
1841
+ $set: {
1842
+ status: update.newStatus,
1843
+ updatedAt: /* @__PURE__ */ new Date()
1844
+ }
1845
+ }
1846
+ }
1847
+ };
1632
1848
  });
1633
- return data;
1849
+ let result = null;
1850
+ if (bulkOps.length > 0) {
1851
+ result = await collection.bulkWrite(bulkOps);
1852
+ delNamespace().then(() => {
1853
+ import_node_server_utils10.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
1854
+ }).catch((err) => {
1855
+ import_node_server_utils10.logger.error(
1856
+ `Failed to clear cache for namespace: ${namespace_collection}`,
1857
+ err
1858
+ );
1859
+ });
1860
+ }
1861
+ import_node_server_utils10.logger.info(`Updated statuses for ${bulkOps.length} parent checklists.`);
1862
+ return result;
1634
1863
  } catch (error) {
1864
+ import_node_server_utils10.logger.error("Failed to update parent checklist statuses", error);
1635
1865
  throw error;
1636
1866
  }
1637
1867
  }
1638
1868
  return {
1639
- createIndexes,
1640
- create,
1641
- get
1869
+ createIndex,
1870
+ createParentChecklist,
1871
+ getAllParentChecklist,
1872
+ updateParentChecklistStatuses
1642
1873
  };
1643
1874
  }
1644
1875
 
1645
1876
  // src/controllers/hygiene-parent-checklist.controller.ts
1646
1877
  var import_node_server_utils11 = require("@iservice365/node-server-utils");
1647
1878
  var import_joi6 = __toESM(require("joi"));
1648
- function useParentCheckilstController() {
1879
+ function useParentChecklistController() {
1649
1880
  const {
1650
- get: _getAll,
1651
- create: _create
1881
+ createParentChecklist: _createParentChecklist,
1882
+ getAllParentChecklist: _getAllParentChecklist
1652
1883
  } = useParentChecklistRepo();
1653
- async function getAll(req, res, next) {
1654
- const query = req.query;
1655
- const validation = import_joi6.default.object({
1656
- page: import_joi6.default.number().min(1).optional().allow("", null),
1657
- limit: import_joi6.default.number().min(1).optional().allow("", null)
1658
- });
1659
- const { error } = validation.validate(query);
1884
+ async function createParentChecklist(req, res, next) {
1885
+ const payload = req.body;
1886
+ const { error } = parentChecklistSchema.validate(payload);
1660
1887
  if (error) {
1888
+ import_node_server_utils11.logger.log({ level: "error", message: error.message });
1661
1889
  next(new import_node_server_utils11.BadRequestError(error.message));
1662
1890
  return;
1663
1891
  }
1664
- const page = parseInt(req.query.page) ?? 1;
1665
- let limit = parseInt(req.query.limit) ?? 20;
1666
- limit = isNaN(limit) ? 20 : limit;
1667
- const sort = req.query.sort ? String(req.query.sort).split(",") : "";
1668
- const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
1669
- const sortObj = {};
1670
- if (sort && Array.isArray(sort) && sort.length && sortOrder && Array.isArray(sortOrder) && sortOrder.length) {
1671
- sort.forEach((field, index) => {
1672
- sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
1673
- });
1674
- }
1675
- const site = req.query.site ?? "";
1676
- const search = req.query.search ?? "";
1677
1892
  try {
1678
- const buildings = await _getAll({
1679
- page,
1680
- limit,
1681
- sort: sortObj,
1682
- site,
1683
- search
1684
- });
1685
- res.json(buildings);
1893
+ const id = await _createParentChecklist(payload);
1894
+ res.status(201).json({ message: "Parent checklist created successfully.", id });
1686
1895
  return;
1687
1896
  } catch (error2) {
1897
+ import_node_server_utils11.logger.log({ level: "error", message: error2.message });
1688
1898
  next(error2);
1899
+ return;
1689
1900
  }
1690
1901
  }
1691
- async function create(req, res, next) {
1692
- const value = req.body;
1693
- const schema = import_joi6.default.object({
1694
- date: import_joi6.default.string().required()
1902
+ async function getAllParentChecklist(req, res, next) {
1903
+ const query = { ...req.query, ...req.params };
1904
+ const validation = import_joi6.default.object({
1905
+ page: import_joi6.default.number().min(1).optional().allow("", null),
1906
+ limit: import_joi6.default.number().min(1).optional().allow("", null),
1907
+ search: import_joi6.default.string().optional().allow("", null),
1908
+ site: import_joi6.default.string().hex().required(),
1909
+ type: import_joi6.default.string().required().valid(...allowedTypes),
1910
+ startDate: import_joi6.default.alternatives().try(import_joi6.default.date(), import_joi6.default.string()).optional().allow("", null),
1911
+ endDate: import_joi6.default.alternatives().try(import_joi6.default.date(), import_joi6.default.string()).optional().allow("", null)
1695
1912
  });
1696
- const { error } = schema.validate(value);
1913
+ const { error } = validation.validate(query);
1697
1914
  if (error) {
1915
+ import_node_server_utils11.logger.log({ level: "error", message: error.message });
1698
1916
  next(new import_node_server_utils11.BadRequestError(error.message));
1699
- import_node_server_utils11.logger.info(`Controller: ${error.message}`);
1700
1917
  return;
1701
1918
  }
1919
+ const page = parseInt(req.query.page) ?? 1;
1920
+ const limit = parseInt(req.query.limit) ?? 20;
1921
+ const search = req.query.search ?? "";
1922
+ const site = req.params.site ?? "";
1923
+ const type = req.params.type ?? "";
1924
+ const startDate = req.query.startDate ?? "";
1925
+ const endDate = req.query.endDate ?? "";
1702
1926
  try {
1703
- const result = await _create(value);
1704
- res.status(201).json(result);
1927
+ const data = await _getAllParentChecklist({
1928
+ page,
1929
+ limit,
1930
+ search,
1931
+ site,
1932
+ type,
1933
+ startDate,
1934
+ endDate
1935
+ });
1936
+ res.json(data);
1705
1937
  return;
1706
1938
  } catch (error2) {
1939
+ import_node_server_utils11.logger.log({ level: "error", message: error2.message });
1707
1940
  next(error2);
1941
+ return;
1708
1942
  }
1709
1943
  }
1710
1944
  return {
1711
- getAll,
1712
- create
1945
+ createParentChecklist,
1946
+ getAllParentChecklist
1713
1947
  };
1714
1948
  }
1715
1949
 
1716
1950
  // src/models/hygiene-unit.model.ts
1717
1951
  var import_node_server_utils12 = require("@iservice365/node-server-utils");
1718
1952
  var import_joi7 = __toESM(require("joi"));
1719
- var import_mongodb5 = require("mongodb");
1953
+ var import_mongodb7 = require("mongodb");
1720
1954
  var unitSchema = import_joi7.default.object({
1721
1955
  name: import_joi7.default.string().required(),
1722
1956
  site: import_joi7.default.string().hex().required(),
@@ -1730,14 +1964,14 @@ function MUnit(value) {
1730
1964
  }
1731
1965
  if (value.site) {
1732
1966
  try {
1733
- value.site = new import_mongodb5.ObjectId(value.site);
1967
+ value.site = new import_mongodb7.ObjectId(value.site);
1734
1968
  } catch (error2) {
1735
1969
  throw new import_node_server_utils12.BadRequestError("Invalid site ID format.");
1736
1970
  }
1737
1971
  }
1738
1972
  if (value.createdBy) {
1739
1973
  try {
1740
- value.createdBy = new import_mongodb5.ObjectId(value.createdBy);
1974
+ value.createdBy = new import_mongodb7.ObjectId(value.createdBy);
1741
1975
  } catch (error2) {
1742
1976
  throw new import_node_server_utils12.BadRequestError("Invalid createdBy ID format.");
1743
1977
  }
@@ -1757,7 +1991,7 @@ function MUnit(value) {
1757
1991
  var import_node_server_utils14 = require("@iservice365/node-server-utils");
1758
1992
 
1759
1993
  // src/repositories/hygiene-unit.repository.ts
1760
- var import_mongodb6 = require("mongodb");
1994
+ var import_mongodb8 = require("mongodb");
1761
1995
  var import_node_server_utils13 = require("@iservice365/node-server-utils");
1762
1996
  function useUnitRepository() {
1763
1997
  const db = import_node_server_utils13.useAtlas.getDb();
@@ -1830,7 +2064,7 @@ function useUnitRepository() {
1830
2064
  }) {
1831
2065
  page = page > 0 ? page - 1 : 0;
1832
2066
  try {
1833
- site = new import_mongodb6.ObjectId(site);
2067
+ site = new import_mongodb8.ObjectId(site);
1834
2068
  } catch (error) {
1835
2069
  throw new import_node_server_utils13.BadRequestError("Invalid site ID format.");
1836
2070
  }
@@ -1930,7 +2164,7 @@ function useUnitRepository() {
1930
2164
  async function getUnitByName(name, site) {
1931
2165
  try {
1932
2166
  if (site)
1933
- site = new import_mongodb6.ObjectId(site);
2167
+ site = new import_mongodb8.ObjectId(site);
1934
2168
  } catch (error) {
1935
2169
  throw new import_node_server_utils13.BadRequestError("Invalid site ID format.");
1936
2170
  }
@@ -1945,13 +2179,13 @@ function useUnitRepository() {
1945
2179
  }
1946
2180
  async function getUnitById(id, site) {
1947
2181
  try {
1948
- id = typeof id === "string" ? new import_mongodb6.ObjectId(id) : id;
2182
+ id = typeof id === "string" ? new import_mongodb8.ObjectId(id) : id;
1949
2183
  } catch (error) {
1950
2184
  throw new import_node_server_utils13.BadRequestError("Invalid unit ID format.");
1951
2185
  }
1952
2186
  try {
1953
2187
  if (site)
1954
- site = new import_mongodb6.ObjectId(site);
2188
+ site = new import_mongodb8.ObjectId(site);
1955
2189
  } catch (error) {
1956
2190
  throw new import_node_server_utils13.BadRequestError(
1957
2191
  "Unable to fetch unit by ID, Invalid site ID format."
@@ -1965,7 +2199,7 @@ function useUnitRepository() {
1965
2199
  }
1966
2200
  async function updateUnit(_id, value) {
1967
2201
  try {
1968
- _id = new import_mongodb6.ObjectId(_id);
2202
+ _id = new import_mongodb8.ObjectId(_id);
1969
2203
  } catch (error) {
1970
2204
  throw new import_node_server_utils13.BadRequestError("Invalid unit ID format.");
1971
2205
  }
@@ -1994,7 +2228,7 @@ function useUnitRepository() {
1994
2228
  }
1995
2229
  async function deleteUnit(_id, session) {
1996
2230
  try {
1997
- _id = new import_mongodb6.ObjectId(_id);
2231
+ _id = new import_mongodb8.ObjectId(_id);
1998
2232
  } catch (error) {
1999
2233
  throw new import_node_server_utils13.BadRequestError("Invalid unit ID format.");
2000
2234
  }
@@ -2261,7 +2495,7 @@ function useUnitController() {
2261
2495
  // src/models/hygiene-schedule-task-area.model.ts
2262
2496
  var import_node_server_utils16 = require("@iservice365/node-server-utils");
2263
2497
  var import_joi9 = __toESM(require("joi"));
2264
- var import_mongodb7 = require("mongodb");
2498
+ var import_mongodb9 = require("mongodb");
2265
2499
  var scheduleTaskAreaSchema = import_joi9.default.object({
2266
2500
  name: import_joi9.default.string().required(),
2267
2501
  site: import_joi9.default.string().hex().required(),
@@ -2282,14 +2516,14 @@ function MScheduleTaskArea(value) {
2282
2516
  }
2283
2517
  if (value.site) {
2284
2518
  try {
2285
- value.site = new import_mongodb7.ObjectId(value.site);
2519
+ value.site = new import_mongodb9.ObjectId(value.site);
2286
2520
  } catch (error2) {
2287
2521
  throw new import_node_server_utils16.BadRequestError("Invalid site ID format.");
2288
2522
  }
2289
2523
  }
2290
2524
  if (value.createdBy) {
2291
2525
  try {
2292
- value.createdBy = new import_mongodb7.ObjectId(value.createdBy);
2526
+ value.createdBy = new import_mongodb9.ObjectId(value.createdBy);
2293
2527
  } catch (error2) {
2294
2528
  throw new import_node_server_utils16.BadRequestError("Invalid createdBy ID format.");
2295
2529
  }
@@ -2299,7 +2533,7 @@ function MScheduleTaskArea(value) {
2299
2533
  try {
2300
2534
  return {
2301
2535
  ...item,
2302
- _id: new import_mongodb7.ObjectId(item._id)
2536
+ _id: new import_mongodb9.ObjectId(item._id)
2303
2537
  };
2304
2538
  } catch (error2) {
2305
2539
  throw new import_node_server_utils16.BadRequestError(
@@ -2321,7 +2555,7 @@ function MScheduleTaskArea(value) {
2321
2555
  }
2322
2556
 
2323
2557
  // src/repositories/hygiene-schedule-task-area.repository.ts
2324
- var import_mongodb8 = require("mongodb");
2558
+ var import_mongodb10 = require("mongodb");
2325
2559
  var import_node_server_utils17 = require("@iservice365/node-server-utils");
2326
2560
  function useScheduleTaskAreaRepository() {
2327
2561
  const db = import_node_server_utils17.useAtlas.getDb();
@@ -2341,6 +2575,18 @@ function useScheduleTaskAreaRepository() {
2341
2575
  throw new import_node_server_utils17.InternalServerError("Failed to create index on site.");
2342
2576
  }
2343
2577
  }
2578
+ async function createUniqueIndex() {
2579
+ try {
2580
+ await collection.createIndex(
2581
+ { name: 1, site: 1, deletedAt: 1 },
2582
+ { unique: true }
2583
+ );
2584
+ } catch (error) {
2585
+ throw new import_node_server_utils17.InternalServerError(
2586
+ "Failed to create unique index on hygiene area."
2587
+ );
2588
+ }
2589
+ }
2344
2590
  async function createScheduleTaskArea(value, session) {
2345
2591
  try {
2346
2592
  value = MScheduleTaskArea(value);
@@ -2355,18 +2601,22 @@ function useScheduleTaskAreaRepository() {
2355
2601
  });
2356
2602
  return res.insertedId;
2357
2603
  } catch (error) {
2604
+ const isDuplicated = error.message.includes("duplicate");
2605
+ if (isDuplicated) {
2606
+ throw new import_node_server_utils17.BadRequestError("Area already exists.");
2607
+ }
2358
2608
  throw error;
2359
2609
  }
2360
2610
  }
2361
2611
  async function updateScheduleTaskArea(_id, params) {
2362
2612
  try {
2363
- _id = new import_mongodb8.ObjectId(_id);
2613
+ _id = new import_mongodb10.ObjectId(_id);
2364
2614
  } catch (error) {
2365
2615
  throw new import_node_server_utils17.BadRequestError("Invalid area ID format.");
2366
2616
  }
2367
2617
  try {
2368
- const value = MScheduleTaskArea({ ...params, updatedAt: /* @__PURE__ */ new Date() });
2369
- const res = await collection.updateOne({ _id }, { $set: value });
2618
+ const updateValue = { ...params, updatedAt: /* @__PURE__ */ new Date() };
2619
+ const res = await collection.updateOne({ _id }, { $set: updateValue });
2370
2620
  if (res.modifiedCount === 0) {
2371
2621
  throw new import_node_server_utils17.InternalServerError("Unable to update cleaning area.");
2372
2622
  }
@@ -2380,12 +2630,16 @@ function useScheduleTaskAreaRepository() {
2380
2630
  });
2381
2631
  return res.modifiedCount;
2382
2632
  } catch (error) {
2633
+ const isDuplicated = error.message.includes("duplicate");
2634
+ if (isDuplicated) {
2635
+ throw new import_node_server_utils17.BadRequestError("Area already exists.");
2636
+ }
2383
2637
  throw error;
2384
2638
  }
2385
2639
  }
2386
2640
  async function deleteScheduleTaskArea(_id, session) {
2387
2641
  try {
2388
- _id = new import_mongodb8.ObjectId(_id);
2642
+ _id = new import_mongodb10.ObjectId(_id);
2389
2643
  } catch (error) {
2390
2644
  throw new import_node_server_utils17.BadRequestError("Invalid area ID format.");
2391
2645
  }
@@ -2400,13 +2654,16 @@ function useScheduleTaskAreaRepository() {
2400
2654
  { $set: updateValue },
2401
2655
  { session }
2402
2656
  );
2403
- if (res.modifiedCount === 0)
2657
+ if (res.modifiedCount === 0) {
2404
2658
  throw new import_node_server_utils17.InternalServerError("Unable to delete area.");
2405
- const cacheKey = (0, import_node_server_utils17.makeCacheKey)(namespace_collection, { _id });
2406
- delCache(cacheKey).then(() => {
2407
- import_node_server_utils17.logger.info(`Cache deleted for key: ${cacheKey}`);
2659
+ }
2660
+ delNamespace().then(() => {
2661
+ import_node_server_utils17.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
2408
2662
  }).catch((err) => {
2409
- import_node_server_utils17.logger.error(`Failed to delete cache for key: ${cacheKey}`, err);
2663
+ import_node_server_utils17.logger.error(
2664
+ `Failed to clear cache for namespace: ${namespace_collection}`,
2665
+ err
2666
+ );
2410
2667
  });
2411
2668
  return res.modifiedCount;
2412
2669
  } catch (error) {
@@ -2417,63 +2674,54 @@ function useScheduleTaskAreaRepository() {
2417
2674
  page = 1,
2418
2675
  limit = 10,
2419
2676
  search = "",
2420
- sort = {},
2421
2677
  startDate = "",
2422
2678
  endDate = "",
2423
2679
  site = ""
2424
2680
  }) {
2425
2681
  page = page > 0 ? page - 1 : 0;
2426
- let dateFilter = {};
2427
- try {
2428
- site = new import_mongodb8.ObjectId(site);
2429
- } catch (error) {
2430
- throw new import_node_server_utils17.BadRequestError("Invalid site ID format.");
2431
- }
2432
2682
  const query = {
2433
2683
  status: { $ne: "deleted" }
2434
2684
  };
2435
2685
  const cacheOptions = {
2436
- site: site.toString()
2686
+ page,
2687
+ limit
2437
2688
  };
2438
- sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
2439
- cacheOptions.sort = JSON.stringify(sort);
2689
+ if (site) {
2690
+ try {
2691
+ site = new import_mongodb10.ObjectId(site);
2692
+ cacheOptions.site = site.toString();
2693
+ } catch (error) {
2694
+ throw new import_node_server_utils17.BadRequestError("Invalid site ID format.");
2695
+ }
2696
+ }
2440
2697
  if (search) {
2441
2698
  query.$or = [{ name: { $regex: search, $options: "i" } }];
2442
2699
  cacheOptions.search = search;
2443
2700
  }
2444
- delNamespace().then(() => {
2445
- import_node_server_utils17.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
2446
- }).catch((err) => {
2447
- import_node_server_utils17.logger.error(
2448
- `Failed to clear cache for namespace: ${namespace_collection}`,
2449
- err
2450
- );
2451
- });
2452
- const cacheKey = (0, import_node_server_utils17.makeCacheKey)(namespace_collection, cacheOptions);
2453
- const cachedData = await getCache(cacheKey);
2454
- if (cachedData) {
2455
- import_node_server_utils17.logger.info(`Cache hit for key: ${cacheKey}`);
2456
- return cachedData;
2457
- }
2458
2701
  if (startDate && endDate) {
2459
- dateFilter = {
2460
- createdAt: {
2461
- $gte: new Date(startDate),
2462
- $lte: new Date(endDate)
2463
- }
2702
+ query.createdAt = {
2703
+ $gte: new Date(startDate),
2704
+ $lte: new Date(endDate)
2464
2705
  };
2706
+ cacheOptions.startDate = new Date(startDate).toISOString().split("T")[0];
2707
+ cacheOptions.endDate = new Date(endDate).toISOString().split("T")[0];
2465
2708
  } else if (startDate) {
2466
- dateFilter = { createdAt: { $gte: new Date(startDate) } };
2709
+ query.createdAt = { $gte: new Date(startDate) };
2710
+ cacheOptions.startDate = new Date(startDate).toISOString().split("T")[0];
2467
2711
  } else if (endDate) {
2468
- dateFilter = { createdAt: { $lte: new Date(endDate) } };
2712
+ query.createdAt = { $lte: new Date(endDate) };
2713
+ cacheOptions.endDate = new Date(endDate).toISOString().split("T")[0];
2714
+ }
2715
+ const cacheKey = (0, import_node_server_utils17.makeCacheKey)(namespace_collection, cacheOptions);
2716
+ const cachedData = await getCache(cacheKey);
2717
+ if (cachedData) {
2718
+ import_node_server_utils17.logger.info(`Cache hit for key: ${cacheKey}`);
2719
+ return cachedData;
2469
2720
  }
2470
2721
  try {
2471
2722
  const items = await collection.aggregate([
2472
2723
  {
2473
- $match: {
2474
- ...dateFilter,
2475
- ...query
2476
- }
2724
+ $match: query
2477
2725
  },
2478
2726
  {
2479
2727
  $lookup: {
@@ -2506,15 +2754,19 @@ function useScheduleTaskAreaRepository() {
2506
2754
  }
2507
2755
  },
2508
2756
  {
2509
- $facet: {
2510
- totalCount: [{ $count: "count" }],
2511
- items: [
2512
- { $sort: { createdAt: -1 } },
2513
- { $skip: page * limit },
2514
- { $limit: limit }
2515
- ]
2757
+ $project: {
2758
+ name: 1,
2759
+ site: "$site._id",
2760
+ siteName: "$site.name",
2761
+ createdByName: "$createdBy.name",
2762
+ checklist: 1,
2763
+ status: 1,
2764
+ createdAt: 1
2516
2765
  }
2517
- }
2766
+ },
2767
+ { $sort: { _id: -1 } },
2768
+ { $skip: page * limit },
2769
+ { $limit: limit }
2518
2770
  ]).toArray();
2519
2771
  const length = await collection.countDocuments(query);
2520
2772
  const data = (0, import_node_server_utils17.paginate)(items, page, limit, length);
@@ -2531,7 +2783,7 @@ function useScheduleTaskAreaRepository() {
2531
2783
  async function getScheduleTaskAreaByName(name, site) {
2532
2784
  try {
2533
2785
  if (site)
2534
- site = new import_mongodb8.ObjectId(site);
2786
+ site = new import_mongodb10.ObjectId(site);
2535
2787
  } catch (error) {
2536
2788
  throw new import_node_server_utils17.BadRequestError("Invalid site ID format.");
2537
2789
  }
@@ -2546,13 +2798,13 @@ function useScheduleTaskAreaRepository() {
2546
2798
  }
2547
2799
  async function getScheduleTaskAreaById(id, site) {
2548
2800
  try {
2549
- id = typeof id === "string" ? new import_mongodb8.ObjectId(id) : id;
2801
+ id = typeof id === "string" ? new import_mongodb10.ObjectId(id) : id;
2550
2802
  } catch (error) {
2551
2803
  throw new import_node_server_utils17.BadRequestError("Invalid unit ID format.");
2552
2804
  }
2553
2805
  try {
2554
2806
  if (site)
2555
- site = new import_mongodb8.ObjectId(site);
2807
+ site = new import_mongodb10.ObjectId(site);
2556
2808
  } catch (error) {
2557
2809
  throw new import_node_server_utils17.BadRequestError(
2558
2810
  "Unable to fetch schedule task area by ID, Invalid site ID format."
@@ -2564,63 +2816,120 @@ function useScheduleTaskAreaRepository() {
2564
2816
  throw new import_node_server_utils17.BadRequestError("Unable to fetch schedule task area by id.");
2565
2817
  }
2566
2818
  }
2819
+ async function getAreaById(_id) {
2820
+ try {
2821
+ _id = new import_mongodb10.ObjectId(_id);
2822
+ } catch (error) {
2823
+ throw new import_node_server_utils17.BadRequestError("Invalid area ID format.");
2824
+ }
2825
+ const query = {
2826
+ _id,
2827
+ status: { $ne: "deleted" }
2828
+ };
2829
+ const cacheKey = (0, import_node_server_utils17.makeCacheKey)(namespace_collection, {
2830
+ _id: _id.toString()
2831
+ });
2832
+ const cachedData = await getCache(cacheKey);
2833
+ if (cachedData) {
2834
+ import_node_server_utils17.logger.info(`Cache hit for key: ${cacheKey}`);
2835
+ return cachedData;
2836
+ }
2837
+ try {
2838
+ const data = await collection.aggregate([
2839
+ { $match: query },
2840
+ {
2841
+ $project: {
2842
+ name: 1,
2843
+ checklist: 1
2844
+ }
2845
+ }
2846
+ ]).toArray();
2847
+ if (!data || !data.length) {
2848
+ throw new import_node_server_utils17.NotFoundError("Area not found.");
2849
+ }
2850
+ setCache(cacheKey, data[0], 15 * 60).then(() => {
2851
+ import_node_server_utils17.logger.info(`Cache set for key: ${cacheKey}`);
2852
+ }).catch((err) => {
2853
+ import_node_server_utils17.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
2854
+ });
2855
+ return data[0];
2856
+ } catch (error) {
2857
+ throw error;
2858
+ }
2859
+ }
2567
2860
  return {
2861
+ createUniqueIndex,
2568
2862
  createScheduleTaskArea,
2569
2863
  updateScheduleTaskArea,
2570
2864
  deleteScheduleTaskArea,
2571
2865
  getScheduleTaskAreas,
2572
2866
  createIndexes,
2573
2867
  getScheduleTaskAreaByName,
2574
- getScheduleTaskAreaById
2868
+ getScheduleTaskAreaById,
2869
+ getAreaById
2575
2870
  };
2576
2871
  }
2577
2872
 
2578
2873
  // src/services/hygiene-schedule-task-area.service.ts
2579
2874
  var import_node_server_utils18 = require("@iservice365/node-server-utils");
2580
2875
  function useScheduleTaskAreaService() {
2581
- const {
2582
- getScheduleTaskAreas: _getAll,
2583
- createScheduleTaskArea: _create,
2584
- updateScheduleTaskArea: _updateById,
2585
- deleteScheduleTaskArea: _deleteById,
2586
- getScheduleTaskAreaByName: _getScheduleTaskAreaByName,
2587
- getScheduleTaskAreaById: _getScheduleTaskAreaById
2588
- } = useScheduleTaskAreaRepository();
2589
- async function getAll(query) {
2590
- return await _getAll(query);
2591
- }
2592
- async function create(scheduleTaskArea) {
2593
- const result = await _getScheduleTaskAreaByName(
2594
- scheduleTaskArea.name,
2595
- scheduleTaskArea.site
2596
- );
2597
- if (result)
2598
- throw new import_node_server_utils18.InternalServerError(
2599
- "Schedule Task Area name already exists in this site."
2600
- );
2601
- return await _create(scheduleTaskArea);
2602
- }
2603
- async function updateById(id, scheduleTaskArea) {
2604
- const result = await _getScheduleTaskAreaByName(
2605
- scheduleTaskArea.name,
2606
- scheduleTaskArea.site
2607
- );
2608
- const resultId = result?._id.toString() ?? "";
2609
- if (result && id != resultId) {
2610
- throw new import_node_server_utils18.InternalServerError(
2611
- "Schedule Task Area name already exists in this site."
2612
- );
2876
+ const { createScheduleTaskArea: _create } = useScheduleTaskAreaRepository();
2877
+ async function uploadByFile({
2878
+ dataJson,
2879
+ createdBy,
2880
+ site
2881
+ }) {
2882
+ let dataArray;
2883
+ try {
2884
+ dataArray = JSON.parse(dataJson);
2885
+ } catch (error) {
2886
+ throw new import_node_server_utils18.BadRequestError("Invalid JSON format for data in excel");
2887
+ }
2888
+ if (!dataArray || dataArray.length === 0) {
2889
+ throw new import_node_server_utils18.NotFoundError("No data found in the uploaded file");
2890
+ }
2891
+ const session = import_node_server_utils18.useAtlas.getClient()?.startSession();
2892
+ const insertedAreaIds = [];
2893
+ try {
2894
+ session?.startTransaction();
2895
+ for (const row of dataArray) {
2896
+ if (!row?.AREA_NAME) {
2897
+ import_node_server_utils18.logger.warn("Skipping row with missing AREA_NAME:", row);
2898
+ continue;
2899
+ }
2900
+ try {
2901
+ const insertedId = await _create(
2902
+ {
2903
+ name: String(row.AREA_NAME).trim(),
2904
+ site,
2905
+ createdBy
2906
+ },
2907
+ session
2908
+ );
2909
+ insertedAreaIds.push(insertedId);
2910
+ } catch (error) {
2911
+ import_node_server_utils18.logger.error(
2912
+ `Error creating area "${row.AREA_NAME}":`,
2913
+ error.message
2914
+ );
2915
+ continue;
2916
+ }
2917
+ }
2918
+ await session?.commitTransaction();
2919
+ import_node_server_utils18.logger.info(`Successfully uploaded ${insertedAreaIds.length} areas`);
2920
+ return {
2921
+ message: `Successfully uploaded ${insertedAreaIds.length} areas`
2922
+ };
2923
+ } catch (error) {
2924
+ await session?.abortTransaction();
2925
+ import_node_server_utils18.logger.error("Error while uploading area information", error);
2926
+ throw error;
2927
+ } finally {
2928
+ session?.endSession();
2613
2929
  }
2614
- return await _updateById(id, scheduleTaskArea);
2615
- }
2616
- async function deleteById(id) {
2617
- return await _deleteById(id);
2618
2930
  }
2619
2931
  return {
2620
- getAll,
2621
- create,
2622
- updateById,
2623
- deleteById
2932
+ uploadByFile
2624
2933
  };
2625
2934
  }
2626
2935
 
@@ -2628,18 +2937,22 @@ function useScheduleTaskAreaService() {
2628
2937
  var import_node_server_utils19 = require("@iservice365/node-server-utils");
2629
2938
  var import_joi10 = __toESM(require("joi"));
2630
2939
  function useScheduleTaskAreaController() {
2940
+ const { uploadByFile: _uploadByFile } = useScheduleTaskAreaService();
2631
2941
  const {
2632
- getAll: _getAll,
2633
- create: _createScheduleTaskArea,
2634
- updateById: _updateScheduleTaskArea,
2635
- deleteById: _deleteById
2636
- } = useScheduleTaskAreaService();
2942
+ getScheduleTaskAreas: _getAll,
2943
+ createScheduleTaskArea: _createScheduleTaskArea,
2944
+ updateScheduleTaskArea: _updateScheduleTaskArea,
2945
+ deleteScheduleTaskArea: _deleteById,
2946
+ getAreaById: _getAreaById
2947
+ } = useScheduleTaskAreaRepository();
2637
2948
  async function getAll(req, res, next) {
2638
2949
  const query = req.query;
2639
2950
  const validation = import_joi10.default.object({
2640
2951
  page: import_joi10.default.number().min(1).optional().allow("", null),
2641
2952
  limit: import_joi10.default.number().min(1).optional().allow("", null),
2642
2953
  search: import_joi10.default.string().optional().allow("", null),
2954
+ startDate: import_joi10.default.alternatives().try(import_joi10.default.date(), import_joi10.default.string()).optional().allow("", null),
2955
+ endDate: import_joi10.default.alternatives().try(import_joi10.default.date(), import_joi10.default.string()).optional().allow("", null),
2643
2956
  site: import_joi10.default.string().hex().optional().allow("", null)
2644
2957
  });
2645
2958
  const { error } = validation.validate(query);
@@ -2648,84 +2961,71 @@ function useScheduleTaskAreaController() {
2648
2961
  return;
2649
2962
  }
2650
2963
  const page = parseInt(req.query.page) ?? 1;
2651
- let limit = parseInt(req.query.limit) ?? 20;
2652
- limit = isNaN(limit) ? 20 : limit;
2653
- const sort = req.query.sort ? String(req.query.sort).split(",") : "";
2654
- const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
2655
- const sortObj = {};
2656
- if (sort && Array.isArray(sort) && sort.length && sortOrder && Array.isArray(sortOrder) && sortOrder.length) {
2657
- sort.forEach((field, index) => {
2658
- sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
2659
- });
2660
- }
2661
- const site = req.query.site ?? "";
2964
+ const limit = parseInt(req.query.limit) ?? 20;
2662
2965
  const search = req.query.search ?? "";
2966
+ const site = req.query.site ?? "";
2967
+ const startDate = req.query.startDate ?? "";
2968
+ const endDate = req.query.endDate ?? "";
2663
2969
  try {
2664
- const scheduleTaskAreas = await _getAll({
2970
+ const data = await _getAll({
2665
2971
  page,
2666
2972
  limit,
2667
- sort: sortObj,
2973
+ search,
2668
2974
  site,
2669
- search
2975
+ startDate,
2976
+ endDate
2670
2977
  });
2671
- res.json(scheduleTaskAreas);
2978
+ res.json(data);
2672
2979
  return;
2673
2980
  } catch (error2) {
2674
2981
  next(error2);
2982
+ return;
2675
2983
  }
2676
2984
  }
2677
2985
  async function createScheduleTaskArea(req, res, next) {
2678
- const value = req.body;
2679
- const schema = import_joi10.default.object({
2680
- name: import_joi10.default.string().required(),
2681
- site: import_joi10.default.string().hex().optional().allow("", null),
2682
- createdBy: import_joi10.default.string().hex().optional().allow("", null)
2683
- });
2684
- const { error } = schema.validate(value);
2986
+ const cookies = req.headers.cookie ? req.headers.cookie.split(";").map((cookie) => cookie.trim().split("=")).reduce(
2987
+ (acc, [key, value]) => ({ ...acc, [key]: value }),
2988
+ {}
2989
+ ) : {};
2990
+ const createdBy = cookies["user"] || "";
2991
+ const payload = { ...req.body, createdBy };
2992
+ const { error } = scheduleTaskAreaSchema.validate(payload);
2685
2993
  if (error) {
2994
+ import_node_server_utils19.logger.log({ level: "error", message: error.message });
2686
2995
  next(new import_node_server_utils19.BadRequestError(error.message));
2687
- import_node_server_utils19.logger.info(`Controller: ${error.message}`);
2688
2996
  return;
2689
2997
  }
2690
2998
  try {
2691
- const result = await _createScheduleTaskArea(value);
2692
- res.status(201).json(result);
2999
+ const id = await _createScheduleTaskArea(payload);
3000
+ res.status(201).json({ message: "Area created successfully.", id });
2693
3001
  return;
2694
3002
  } catch (error2) {
3003
+ import_node_server_utils19.logger.log({ level: "error", message: error2.message });
2695
3004
  next(error2);
3005
+ return;
2696
3006
  }
2697
3007
  }
2698
3008
  async function updateScheduleTaskArea(req, res, next) {
2699
- const { name, site, createdBy } = req.body;
2700
- const id = req.params.id;
3009
+ const payload = { id: req.params.id, ...req.body };
2701
3010
  const schema = import_joi10.default.object({
2702
3011
  id: import_joi10.default.string().hex().required(),
2703
- name: import_joi10.default.string().required(),
2704
- site: import_joi10.default.string().required(),
2705
- checklist: import_joi10.default.array().optional().items(
2706
- import_joi10.default.object({
2707
- _id: import_joi10.default.string().optional().required(),
2708
- name: import_joi10.default.string().optional().required()
2709
- })
2710
- ),
2711
- createdBy: import_joi10.default.string().hex().optional().allow("", null)
3012
+ name: import_joi10.default.string().required()
2712
3013
  });
2713
- const { error } = schema.validate({ id, name, createdBy, site });
3014
+ const { error } = schema.validate(payload);
2714
3015
  if (error) {
2715
3016
  next(new import_node_server_utils19.BadRequestError(error.message));
2716
3017
  import_node_server_utils19.logger.info(`Controller: ${error.message}`);
2717
3018
  return;
2718
3019
  }
2719
3020
  try {
2720
- const result = await _updateScheduleTaskArea(id, {
2721
- name,
2722
- createdBy,
2723
- site
2724
- });
2725
- res.json(result);
3021
+ const { id, ...value } = payload;
3022
+ await _updateScheduleTaskArea(id, value);
3023
+ res.json({ message: "Area updated successfully." });
2726
3024
  return;
2727
3025
  } catch (error2) {
3026
+ import_node_server_utils19.logger.log({ level: "error", message: error2.message });
2728
3027
  next(error2);
3028
+ return;
2729
3029
  }
2730
3030
  }
2731
3031
  async function deleteScheduleTaskArea(req, res, next) {
@@ -2735,40 +3035,1637 @@ function useScheduleTaskAreaController() {
2735
3035
  });
2736
3036
  const { error } = validation.validate({ id });
2737
3037
  if (error) {
3038
+ import_node_server_utils19.logger.log({ level: "error", message: error.message });
2738
3039
  next(new import_node_server_utils19.BadRequestError(error.message));
2739
3040
  return;
2740
3041
  }
2741
3042
  try {
2742
- const message = await _deleteById(id);
2743
- res.json(message);
3043
+ await _deleteById(id);
3044
+ res.json({ message: "Area deleted successfully." });
3045
+ return;
3046
+ } catch (error2) {
3047
+ import_node_server_utils19.logger.log({ level: "error", message: error2.message });
3048
+ next(error2);
3049
+ return;
3050
+ }
3051
+ }
3052
+ async function uploadByFile(req, res, next) {
3053
+ if (!req.file) {
3054
+ next(new import_node_server_utils19.BadRequestError("File is required!"));
3055
+ return;
3056
+ }
3057
+ const cookies = req.headers.cookie ? req.headers.cookie.split(";").map((cookie) => cookie.trim().split("=")).reduce(
3058
+ (acc, [key, value]) => ({ ...acc, [key]: value }),
3059
+ {}
3060
+ ) : {};
3061
+ const createdBy = cookies["user"] || "";
3062
+ const { site } = req.body;
3063
+ const schema = import_joi10.default.object({
3064
+ site: import_joi10.default.string().hex().optional().allow("", null),
3065
+ createdBy: import_joi10.default.string().hex().required()
3066
+ });
3067
+ const { error } = schema.validate({ site, createdBy });
3068
+ if (error) {
3069
+ import_node_server_utils19.logger.log({ level: "error", message: error.message });
3070
+ next(new import_node_server_utils19.BadRequestError(error.message));
3071
+ return;
3072
+ }
3073
+ try {
3074
+ const xlsData = await convertBufferFile(req.file.buffer);
3075
+ const dataJson = JSON.stringify(xlsData);
3076
+ const result = await _uploadByFile({ dataJson, createdBy, site });
3077
+ return res.status(201).json(result);
3078
+ } catch (error2) {
3079
+ import_node_server_utils19.logger.log({ level: "error", message: error2.message });
3080
+ next(error2);
3081
+ return;
3082
+ }
3083
+ }
3084
+ async function getAreaById(req, res, next) {
3085
+ const validation = import_joi10.default.string().hex().required();
3086
+ const _id = req.params.id;
3087
+ const { error } = validation.validate(_id);
3088
+ if (error) {
3089
+ import_node_server_utils19.logger.log({ level: "error", message: error.message });
3090
+ next(new import_node_server_utils19.BadRequestError(error.message));
3091
+ return;
3092
+ }
3093
+ try {
3094
+ const data = await _getAreaById(_id);
3095
+ res.json(data);
2744
3096
  return;
2745
3097
  } catch (error2) {
3098
+ import_node_server_utils19.logger.log({ level: "error", message: error2.message });
2746
3099
  next(error2);
3100
+ return;
2747
3101
  }
2748
3102
  }
2749
3103
  return {
2750
3104
  getAll,
3105
+ getAreaById,
2751
3106
  createScheduleTaskArea,
2752
3107
  updateScheduleTaskArea,
2753
- deleteScheduleTaskArea
3108
+ deleteScheduleTaskArea,
3109
+ uploadByFile
3110
+ };
3111
+ }
3112
+
3113
+ // src/models/hygiene-area-checklist.model.ts
3114
+ var import_node_server_utils20 = require("@iservice365/node-server-utils");
3115
+ var import_joi11 = __toESM(require("joi"));
3116
+ var import_mongodb11 = require("mongodb");
3117
+ var areaChecklistSchema = import_joi11.default.object({
3118
+ type: import_joi11.default.string().required().valid(...allowedTypes),
3119
+ site: import_joi11.default.string().hex().required(),
3120
+ parentChecklist: import_joi11.default.string().hex().required(),
3121
+ area: import_joi11.default.string().hex().required(),
3122
+ name: import_joi11.default.string().optional().allow("", null),
3123
+ createdBy: import_joi11.default.string().hex().optional().allow("", null)
3124
+ });
3125
+ function MAreaChecklist(value) {
3126
+ const { error } = areaChecklistSchema.validate(value);
3127
+ if (error) {
3128
+ import_node_server_utils20.logger.info(`Hygiene Checklist Area Model: ${error.message}`);
3129
+ throw new import_node_server_utils20.BadRequestError(error.message);
3130
+ }
3131
+ if (value.site) {
3132
+ try {
3133
+ value.site = new import_mongodb11.ObjectId(value.site);
3134
+ } catch (error2) {
3135
+ throw new import_node_server_utils20.BadRequestError("Invalid site ID format.");
3136
+ }
3137
+ }
3138
+ if (value.parentChecklist) {
3139
+ try {
3140
+ value.parentChecklist = new import_mongodb11.ObjectId(value.parentChecklist);
3141
+ } catch (error2) {
3142
+ throw new import_node_server_utils20.BadRequestError("Invalid checklist ID format.");
3143
+ }
3144
+ }
3145
+ if (value.area) {
3146
+ try {
3147
+ value.area = new import_mongodb11.ObjectId(value.area);
3148
+ } catch (error2) {
3149
+ throw new import_node_server_utils20.BadRequestError("Invalid area ID format.");
3150
+ }
3151
+ }
3152
+ if (value.createdBy) {
3153
+ try {
3154
+ value.createdBy = new import_mongodb11.ObjectId(value.createdBy);
3155
+ } catch (error2) {
3156
+ throw new import_node_server_utils20.BadRequestError("Invalid createdBy ID format.");
3157
+ }
3158
+ }
3159
+ if (value.acceptedBy) {
3160
+ try {
3161
+ value.acceptedBy = new import_mongodb11.ObjectId(value.acceptedBy);
3162
+ } catch (error2) {
3163
+ throw new import_node_server_utils20.BadRequestError("Invalid acceptedBy ID format.");
3164
+ }
3165
+ }
3166
+ return {
3167
+ type: value.type,
3168
+ site: value.site,
3169
+ parentChecklist: value.parentChecklist,
3170
+ area: value.area,
3171
+ name: value.name ?? "",
3172
+ status: value.status ?? "To Do",
3173
+ createdBy: value.createdBy ?? "",
3174
+ createdAt: /* @__PURE__ */ new Date(),
3175
+ acceptedBy: value.acceptedBy ?? "",
3176
+ acceptedAt: value.acceptedAt ?? "",
3177
+ startedAt: value.startedAt ?? "",
3178
+ endedAt: value.endedAt ?? "",
3179
+ signature: value.signature ?? "",
3180
+ updatedAt: value.updatedAt ?? ""
3181
+ };
3182
+ }
3183
+
3184
+ // src/repositories/hygiene-area-checklist.repository.ts
3185
+ var import_node_server_utils21 = require("@iservice365/node-server-utils");
3186
+ var import_mongodb12 = require("mongodb");
3187
+ function useAreaChecklistRepo() {
3188
+ const db = import_node_server_utils21.useAtlas.getDb();
3189
+ if (!db) {
3190
+ throw new import_node_server_utils21.InternalServerError("Unable to connect to server.");
3191
+ }
3192
+ const namespace_collection = "hygiene-checklist.areas";
3193
+ const unit_checklist_collection = "hygiene-checklist.units";
3194
+ const collection = db.collection(namespace_collection);
3195
+ const unitChecklistCollection = db.collection(unit_checklist_collection);
3196
+ const { delNamespace, setCache, getCache } = (0, import_node_server_utils21.useCache)(namespace_collection);
3197
+ const { delNamespace: delUnitNamespace } = (0, import_node_server_utils21.useCache)(
3198
+ unit_checklist_collection
3199
+ );
3200
+ async function createIndex() {
3201
+ try {
3202
+ await collection.createIndexes([
3203
+ { key: { type: 1 } },
3204
+ { key: { site: 1 } },
3205
+ { key: { parentChecklist: 1 } },
3206
+ { key: { area: 1 } },
3207
+ { key: { createdAt: 1 } },
3208
+ { key: { acceptedBy: 1 } }
3209
+ ]);
3210
+ } catch (error) {
3211
+ throw new import_node_server_utils21.InternalServerError(
3212
+ "Failed to create index on hygiene checklist area."
3213
+ );
3214
+ }
3215
+ }
3216
+ async function createTextIndex() {
3217
+ try {
3218
+ await collection.createIndex({ name: "text" });
3219
+ } catch (error) {
3220
+ throw new import_node_server_utils21.InternalServerError(
3221
+ "Failed to create text index on hygiene checklist area."
3222
+ );
3223
+ }
3224
+ }
3225
+ async function createAreaChecklist(value, session) {
3226
+ try {
3227
+ const siteId = new import_mongodb12.ObjectId(value.site);
3228
+ const parentChecklistId = new import_mongodb12.ObjectId(value.parentChecklist);
3229
+ const areaId = new import_mongodb12.ObjectId(value.area);
3230
+ const currentDate = /* @__PURE__ */ new Date();
3231
+ const startOfDay = new Date(currentDate);
3232
+ startOfDay.setUTCHours(0, 0, 0, 0);
3233
+ const endOfDay = new Date(currentDate);
3234
+ endOfDay.setUTCHours(23, 59, 59, 999);
3235
+ const existingChecklist = await collection.findOne({
3236
+ type: value.type,
3237
+ site: siteId,
3238
+ parentChecklist: parentChecklistId,
3239
+ area: areaId,
3240
+ createdAt: {
3241
+ $gte: startOfDay,
3242
+ $lte: endOfDay
3243
+ }
3244
+ });
3245
+ if (existingChecklist) {
3246
+ import_node_server_utils21.logger.info(
3247
+ `Area checklist already exists for area ${areaId} on ${currentDate.toISOString().split("T")[0]}`
3248
+ );
3249
+ return existingChecklist._id;
3250
+ }
3251
+ const processedValue = MAreaChecklist(value);
3252
+ const result = await collection.insertOne(processedValue, { session });
3253
+ delNamespace().then(() => {
3254
+ import_node_server_utils21.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
3255
+ }).catch((err) => {
3256
+ import_node_server_utils21.logger.error(
3257
+ `Failed to clear cache for namespace: ${namespace_collection}`,
3258
+ err
3259
+ );
3260
+ });
3261
+ return result.insertedId;
3262
+ } catch (error) {
3263
+ throw error;
3264
+ }
3265
+ }
3266
+ async function getAllAreaChecklist({
3267
+ page = 1,
3268
+ limit = 10,
3269
+ search = "",
3270
+ site,
3271
+ type,
3272
+ parentChecklist
3273
+ }) {
3274
+ page = page > 0 ? page - 1 : 0;
3275
+ const query = { type };
3276
+ const cacheOptions = {
3277
+ page,
3278
+ limit
3279
+ };
3280
+ try {
3281
+ query.site = new import_mongodb12.ObjectId(site);
3282
+ cacheOptions.site = site.toString();
3283
+ } catch (error) {
3284
+ throw new import_node_server_utils21.BadRequestError("Invalid site ID format.");
3285
+ }
3286
+ try {
3287
+ query.parentChecklist = new import_mongodb12.ObjectId(parentChecklist);
3288
+ cacheOptions.parentChecklist = parentChecklist.toString();
3289
+ } catch (error) {
3290
+ throw new import_node_server_utils21.BadRequestError("Invalid parent checklist ID format.");
3291
+ }
3292
+ if (search) {
3293
+ query.$text = { $search: search };
3294
+ cacheOptions.search = search;
3295
+ }
3296
+ const cacheKey = (0, import_node_server_utils21.makeCacheKey)(namespace_collection, cacheOptions);
3297
+ const cachedData = await getCache(cacheKey);
3298
+ if (cachedData) {
3299
+ import_node_server_utils21.logger.info(`Cache hit for key: ${cacheKey}`);
3300
+ return cachedData;
3301
+ }
3302
+ try {
3303
+ const pipeline = [
3304
+ { $match: query },
3305
+ {
3306
+ $lookup: {
3307
+ from: "users",
3308
+ localField: "acceptedBy",
3309
+ foreignField: "_id",
3310
+ pipeline: [{ $project: { name: 1 } }],
3311
+ as: "acceptedBy"
3312
+ }
3313
+ },
3314
+ {
3315
+ $unwind: {
3316
+ path: "$acceptedBy",
3317
+ preserveNullAndEmptyArrays: true
3318
+ }
3319
+ },
3320
+ {
3321
+ $project: {
3322
+ name: 1,
3323
+ acceptedByName: "$acceptedBy.name",
3324
+ status: 1,
3325
+ createdAt: 1
3326
+ }
3327
+ },
3328
+ { $sort: { _id: -1 } },
3329
+ { $skip: page * limit },
3330
+ { $limit: limit }
3331
+ ];
3332
+ const items = await collection.aggregate(pipeline).toArray();
3333
+ const length = await collection.countDocuments(query);
3334
+ const data = (0, import_node_server_utils21.paginate)(items, page, limit, length);
3335
+ setCache(cacheKey, data, 15 * 60).then(() => {
3336
+ import_node_server_utils21.logger.info(`Cache set for key: ${cacheKey}`);
3337
+ }).catch((err) => {
3338
+ import_node_server_utils21.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
3339
+ });
3340
+ return data;
3341
+ } catch (error) {
3342
+ throw error;
3343
+ }
3344
+ }
3345
+ async function getAreaChecklistHistory({
3346
+ page = 1,
3347
+ limit = 10,
3348
+ search = "",
3349
+ site,
3350
+ type,
3351
+ parentChecklist,
3352
+ status,
3353
+ createdAt,
3354
+ user
3355
+ }) {
3356
+ page = page > 0 ? page - 1 : 0;
3357
+ const query = { type };
3358
+ const cacheOptions = {
3359
+ page,
3360
+ limit
3361
+ };
3362
+ try {
3363
+ query.site = new import_mongodb12.ObjectId(site);
3364
+ cacheOptions.site = site.toString();
3365
+ } catch (error) {
3366
+ throw new import_node_server_utils21.BadRequestError("Invalid site ID format.");
3367
+ }
3368
+ try {
3369
+ query.parentChecklist = new import_mongodb12.ObjectId(parentChecklist);
3370
+ cacheOptions.parentChecklist = parentChecklist.toString();
3371
+ } catch (error) {
3372
+ throw new import_node_server_utils21.BadRequestError("Invalid parent checklist ID format.");
3373
+ }
3374
+ if (search) {
3375
+ query.$text = { $search: search };
3376
+ cacheOptions.search = search;
3377
+ }
3378
+ if (createdAt) {
3379
+ query.createdAt = {
3380
+ $gte: /* @__PURE__ */ new Date(`${createdAt}T00:00:00Z`),
3381
+ $lte: /* @__PURE__ */ new Date(`${createdAt}T23:59:59Z`)
3382
+ };
3383
+ cacheOptions.createdAt = new Date(createdAt).toISOString().split("T")[0];
3384
+ }
3385
+ if (status) {
3386
+ query.status = status;
3387
+ cacheOptions.status = status;
3388
+ } else {
3389
+ query.status = { $in: ["In Progress", "Completed"] };
3390
+ }
3391
+ if (user) {
3392
+ try {
3393
+ query.acceptedBy = new import_mongodb12.ObjectId(user);
3394
+ cacheOptions.user = user.toString();
3395
+ } catch (error) {
3396
+ throw new import_node_server_utils21.BadRequestError("Invalid user ID format.");
3397
+ }
3398
+ }
3399
+ const cacheKey = (0, import_node_server_utils21.makeCacheKey)(namespace_collection, cacheOptions);
3400
+ const cachedData = await getCache(cacheKey);
3401
+ if (cachedData) {
3402
+ import_node_server_utils21.logger.info(`Cache hit for key: ${cacheKey}`);
3403
+ return cachedData;
3404
+ }
3405
+ try {
3406
+ const pipeline = [
3407
+ { $match: query },
3408
+ {
3409
+ $lookup: {
3410
+ from: "users",
3411
+ localField: "acceptedBy",
3412
+ foreignField: "_id",
3413
+ pipeline: [
3414
+ ...search ? [{ $match: { name: { $regex: search, $options: "i" } } }] : [],
3415
+ { $project: { name: 1 } }
3416
+ ],
3417
+ as: "acceptedBy"
3418
+ }
3419
+ },
3420
+ {
3421
+ $unwind: {
3422
+ path: "$acceptedBy",
3423
+ preserveNullAndEmptyArrays: true
3424
+ }
3425
+ },
3426
+ {
3427
+ $project: {
3428
+ name: 1,
3429
+ createdAt: 1,
3430
+ acceptedByName: "$acceptedBy.name",
3431
+ status: 1,
3432
+ startedAt: 1,
3433
+ endedAt: 1
3434
+ }
3435
+ },
3436
+ { $sort: { status: 1 } },
3437
+ { $skip: page * limit },
3438
+ { $limit: limit }
3439
+ ];
3440
+ const items = await collection.aggregate(pipeline).toArray();
3441
+ const length = await collection.countDocuments(query);
3442
+ const data = (0, import_node_server_utils21.paginate)(items, page, limit, length);
3443
+ setCache(cacheKey, data, 15 * 60).then(() => {
3444
+ import_node_server_utils21.logger.info(`Cache set for key: ${cacheKey}`);
3445
+ }).catch((err) => {
3446
+ import_node_server_utils21.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
3447
+ });
3448
+ return data;
3449
+ } catch (error) {
3450
+ throw error;
3451
+ }
3452
+ }
3453
+ async function getAreaChecklistHistoryDetails(_id) {
3454
+ try {
3455
+ _id = new import_mongodb12.ObjectId(_id);
3456
+ } catch (error) {
3457
+ throw new import_node_server_utils21.BadRequestError("Invalid area checklist ID format.");
3458
+ }
3459
+ const cacheKey = (0, import_node_server_utils21.makeCacheKey)(namespace_collection, {
3460
+ _id: _id.toString()
3461
+ });
3462
+ const cachedData = await getCache(cacheKey);
3463
+ if (cachedData) {
3464
+ import_node_server_utils21.logger.info(`Cache hit for key: ${cacheKey}`);
3465
+ return cachedData;
3466
+ }
3467
+ try {
3468
+ const areaPipeline = [
3469
+ { $match: { _id } },
3470
+ {
3471
+ $lookup: {
3472
+ from: "users",
3473
+ localField: "createdBy",
3474
+ foreignField: "_id",
3475
+ pipeline: [{ $project: { name: 1 } }],
3476
+ as: "createdBy"
3477
+ }
3478
+ },
3479
+ {
3480
+ $unwind: {
3481
+ path: "$createdBy",
3482
+ preserveNullAndEmptyArrays: true
3483
+ }
3484
+ },
3485
+ {
3486
+ $lookup: {
3487
+ from: "users",
3488
+ localField: "acceptedBy",
3489
+ foreignField: "_id",
3490
+ pipeline: [{ $project: { name: 1 } }],
3491
+ as: "acceptedBy"
3492
+ }
3493
+ },
3494
+ {
3495
+ $unwind: {
3496
+ path: "$acceptedBy",
3497
+ preserveNullAndEmptyArrays: true
3498
+ }
3499
+ },
3500
+ {
3501
+ $project: {
3502
+ name: 1,
3503
+ createdAt: 1,
3504
+ createdByName: "$createdBy.name",
3505
+ startedAt: 1,
3506
+ endedAt: 1,
3507
+ status: 1,
3508
+ signature: 1,
3509
+ acceptedByName: "$acceptedBy.name"
3510
+ }
3511
+ }
3512
+ ];
3513
+ const unitPipeline = [
3514
+ { $match: { areaChecklist: _id } },
3515
+ {
3516
+ $project: {
3517
+ name: 1,
3518
+ remarks: "$metadata.remarks",
3519
+ attachments: "$metadata.attachments",
3520
+ approve: { $ifNull: ["$approve", null] },
3521
+ reject: { $ifNull: ["$reject", null] }
3522
+ }
3523
+ }
3524
+ ];
3525
+ const [area, units] = await Promise.all([
3526
+ collection.aggregate(areaPipeline).toArray(),
3527
+ unitChecklistCollection.aggregate(unitPipeline).toArray()
3528
+ ]);
3529
+ if (!area.length) {
3530
+ throw new import_node_server_utils21.BadRequestError("Area checklist not found.");
3531
+ }
3532
+ const items = {
3533
+ area: area[0],
3534
+ units
3535
+ };
3536
+ setCache(cacheKey, items, 15 * 60).then(() => {
3537
+ import_node_server_utils21.logger.info(`Cache set for key: ${cacheKey}`);
3538
+ }).catch((err) => {
3539
+ import_node_server_utils21.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
3540
+ });
3541
+ return items;
3542
+ } catch (error) {
3543
+ throw error;
3544
+ }
3545
+ }
3546
+ async function acceptAreaChecklist(_id, acceptedBy) {
3547
+ try {
3548
+ _id = new import_mongodb12.ObjectId(_id);
3549
+ } catch (error) {
3550
+ throw new import_node_server_utils21.BadRequestError("Invalid area ID format.");
3551
+ }
3552
+ try {
3553
+ acceptedBy = new import_mongodb12.ObjectId(acceptedBy);
3554
+ } catch (error) {
3555
+ throw new import_node_server_utils21.BadRequestError("Invalid acceptedBy ID format.");
3556
+ }
3557
+ try {
3558
+ const now = /* @__PURE__ */ new Date();
3559
+ const updateValue = {
3560
+ acceptedBy,
3561
+ acceptedAt: now,
3562
+ startedAt: now,
3563
+ updatedAt: now
3564
+ };
3565
+ const res = await collection.updateOne({ _id }, { $set: updateValue });
3566
+ if (res.modifiedCount === 0) {
3567
+ throw new import_node_server_utils21.InternalServerError("Unable to update cleaning area.");
3568
+ }
3569
+ delNamespace().then(() => {
3570
+ import_node_server_utils21.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
3571
+ }).catch((err) => {
3572
+ import_node_server_utils21.logger.error(
3573
+ `Failed to clear cache for namespace: ${namespace_collection}`,
3574
+ err
3575
+ );
3576
+ });
3577
+ return res.modifiedCount;
3578
+ } catch (error) {
3579
+ throw error;
3580
+ }
3581
+ }
3582
+ async function attachImageAreaChecklist(_id, attachments, session) {
3583
+ try {
3584
+ _id = new import_mongodb12.ObjectId(_id);
3585
+ } catch (error) {
3586
+ throw new import_node_server_utils21.BadRequestError("Invalid area checklist ID format.");
3587
+ }
3588
+ try {
3589
+ const now = /* @__PURE__ */ new Date();
3590
+ const updateValue = {
3591
+ metadata: { attachments },
3592
+ updatedAt: now
3593
+ };
3594
+ const res = await collection.updateOne(
3595
+ { _id },
3596
+ { $set: updateValue },
3597
+ { session }
3598
+ );
3599
+ if (res.modifiedCount === 0) {
3600
+ throw new import_node_server_utils21.InternalServerError(
3601
+ "Unable to update cleaning area checklist."
3602
+ );
3603
+ }
3604
+ delNamespace().then(() => {
3605
+ import_node_server_utils21.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
3606
+ }).catch((err) => {
3607
+ import_node_server_utils21.logger.error(
3608
+ `Failed to clear cache for namespace: ${namespace_collection}`,
3609
+ err
3610
+ );
3611
+ });
3612
+ delUnitNamespace().then(() => {
3613
+ import_node_server_utils21.logger.info(
3614
+ `Cache cleared for namespace: ${unit_checklist_collection}`
3615
+ );
3616
+ }).catch((err) => {
3617
+ import_node_server_utils21.logger.error(
3618
+ `Failed to clear cache for namespace: ${unit_checklist_collection}`,
3619
+ err
3620
+ );
3621
+ });
3622
+ return res.modifiedCount;
3623
+ } catch (error) {
3624
+ throw error;
3625
+ }
3626
+ }
3627
+ async function submitAreaChecklist(_id, signature) {
3628
+ try {
3629
+ _id = new import_mongodb12.ObjectId(_id);
3630
+ } catch (error) {
3631
+ throw new import_node_server_utils21.BadRequestError("Invalid area ID format.");
3632
+ }
3633
+ try {
3634
+ const now = /* @__PURE__ */ new Date();
3635
+ const updateValue = {
3636
+ signature,
3637
+ status: "In Progress",
3638
+ endedAt: now,
3639
+ updatedAt: now
3640
+ };
3641
+ const res = await collection.updateOne({ _id }, { $set: updateValue });
3642
+ if (res.modifiedCount === 0) {
3643
+ throw new import_node_server_utils21.InternalServerError("Unable to update cleaning area.");
3644
+ }
3645
+ delNamespace().then(() => {
3646
+ import_node_server_utils21.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
3647
+ }).catch((err) => {
3648
+ import_node_server_utils21.logger.error(
3649
+ `Failed to clear cache for namespace: ${namespace_collection}`,
3650
+ err
3651
+ );
3652
+ });
3653
+ return res.modifiedCount;
3654
+ } catch (error) {
3655
+ throw error;
3656
+ }
3657
+ }
3658
+ async function completeAreaChecklist(_id, signature) {
3659
+ try {
3660
+ _id = new import_mongodb12.ObjectId(_id);
3661
+ } catch (error) {
3662
+ throw new import_node_server_utils21.BadRequestError("Invalid area ID format.");
3663
+ }
3664
+ try {
3665
+ const now = /* @__PURE__ */ new Date();
3666
+ const updateValue = {
3667
+ signature,
3668
+ status: "Completed",
3669
+ endedAt: now,
3670
+ updatedAt: now
3671
+ };
3672
+ const res = await collection.updateOne({ _id }, { $set: updateValue });
3673
+ if (res.modifiedCount === 0) {
3674
+ throw new import_node_server_utils21.InternalServerError("Unable to update cleaning area.");
3675
+ }
3676
+ delNamespace().then(() => {
3677
+ import_node_server_utils21.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
3678
+ }).catch((err) => {
3679
+ import_node_server_utils21.logger.error(
3680
+ `Failed to clear cache for namespace: ${namespace_collection}`,
3681
+ err
3682
+ );
3683
+ });
3684
+ return res.modifiedCount;
3685
+ } catch (error) {
3686
+ throw error;
3687
+ }
3688
+ }
3689
+ return {
3690
+ createIndex,
3691
+ createTextIndex,
3692
+ createAreaChecklist,
3693
+ getAllAreaChecklist,
3694
+ getAreaChecklistHistory,
3695
+ getAreaChecklistHistoryDetails,
3696
+ acceptAreaChecklist,
3697
+ attachImageAreaChecklist,
3698
+ submitAreaChecklist,
3699
+ completeAreaChecklist
3700
+ };
3701
+ }
3702
+
3703
+ // src/controllers/hygiene-area-checklist.controller.ts
3704
+ var import_node_server_utils23 = require("@iservice365/node-server-utils");
3705
+ var import_joi12 = __toESM(require("joi"));
3706
+
3707
+ // src/services/hygiene-area-checklist.service.ts
3708
+ var import_node_server_utils22 = require("@iservice365/node-server-utils");
3709
+ function useAreaChecklistService() {
3710
+ const { createAreaChecklist: _createAreaChecklist } = useAreaChecklistRepo();
3711
+ const { getAreas } = useAreaRepository();
3712
+ const { getToiletLocations } = useToiletLocationRepository();
3713
+ async function createAreaChecklist(value) {
3714
+ try {
3715
+ const results = [];
3716
+ if (value.type === "cleaner") {
3717
+ const cleanerAreasResult = await getAreas({
3718
+ site: value.site
3719
+ });
3720
+ const cleanerAreas = cleanerAreasResult.items || [];
3721
+ if (cleanerAreas.length === 0) {
3722
+ import_node_server_utils22.logger.warn(`No cleaner areas found for site: ${value.site}`);
3723
+ return results;
3724
+ }
3725
+ for (const area of cleanerAreas) {
3726
+ const checklistData = {
3727
+ type: "cleaner",
3728
+ site: value.site,
3729
+ parentChecklist: value.parentChecklist,
3730
+ area: area._id.toString(),
3731
+ name: area.name,
3732
+ createdBy: value.createdBy
3733
+ };
3734
+ const insertedId = await _createAreaChecklist(checklistData);
3735
+ results.push(insertedId);
3736
+ }
3737
+ import_node_server_utils22.logger.info(
3738
+ `Created ${results.length} cleaner area checklists for site: ${value.site}`
3739
+ );
3740
+ }
3741
+ if (value.type === "toilet") {
3742
+ const toiletAreasResult = await getToiletLocations({
3743
+ site: value.site
3744
+ });
3745
+ const toiletAreas = toiletAreasResult.items || [];
3746
+ if (toiletAreas.length === 0) {
3747
+ import_node_server_utils22.logger.warn(`No toilet locations found for site: ${value.site}`);
3748
+ return results;
3749
+ }
3750
+ for (const toiletLocation of toiletAreas) {
3751
+ const checklistData = {
3752
+ type: "toilet",
3753
+ site: value.site,
3754
+ parentChecklist: value.parentChecklist,
3755
+ area: toiletLocation._id,
3756
+ name: toiletLocation.name,
3757
+ createdBy: value.createdBy
3758
+ };
3759
+ const insertedId = await _createAreaChecklist(checklistData);
3760
+ results.push(insertedId);
3761
+ }
3762
+ import_node_server_utils22.logger.info(
3763
+ `Created ${results.length} toilet area checklists for site: ${value.site}`
3764
+ );
3765
+ }
3766
+ return results;
3767
+ } catch (error) {
3768
+ import_node_server_utils22.logger.error(`Error generating area checklists:`, error);
3769
+ throw error;
3770
+ }
3771
+ }
3772
+ return { createAreaChecklist };
3773
+ }
3774
+
3775
+ // src/controllers/hygiene-area-checklist.controller.ts
3776
+ function useAreaChecklistController() {
3777
+ const {
3778
+ getAllAreaChecklist: _getAllAreaChecklist,
3779
+ getAreaChecklistHistory: _getAreaChecklistHistory,
3780
+ getAreaChecklistHistoryDetails: _getAreaChecklistHistoryDetails,
3781
+ acceptAreaChecklist: _acceptAreaChecklist,
3782
+ attachImageAreaChecklist: _attachImageAreaChecklist,
3783
+ submitAreaChecklist: _submitAreaChecklist,
3784
+ completeAreaChecklist: _completeAreaChecklist
3785
+ } = useAreaChecklistRepo();
3786
+ const { createAreaChecklist: _createAreaChecklist } = useAreaChecklistService();
3787
+ async function createAreaChecklist(req, res, next) {
3788
+ const cookies = req.headers.cookie ? req.headers.cookie.split(";").map((cookie) => cookie.trim().split("=")).reduce(
3789
+ (acc, [key, value]) => ({ ...acc, [key]: value }),
3790
+ {}
3791
+ ) : {};
3792
+ const createdBy = cookies["user"] || "";
3793
+ const payload = { ...req.body, ...req.params, createdBy };
3794
+ const validation = import_joi12.default.object({
3795
+ type: import_joi12.default.string().required().valid(...allowedTypes),
3796
+ site: import_joi12.default.string().hex().required(),
3797
+ parentChecklist: import_joi12.default.string().hex().required(),
3798
+ createdBy: import_joi12.default.string().hex().optional().allow("", null)
3799
+ });
3800
+ const { error } = validation.validate(payload);
3801
+ if (error) {
3802
+ import_node_server_utils23.logger.log({ level: "error", message: error.message });
3803
+ next(new import_node_server_utils23.BadRequestError(error.message));
3804
+ return;
3805
+ }
3806
+ try {
3807
+ await _createAreaChecklist(payload);
3808
+ res.status(201).json({ message: "Area checklists generated successfully." });
3809
+ return;
3810
+ } catch (error2) {
3811
+ import_node_server_utils23.logger.log({ level: "error", message: error2.message });
3812
+ next(error2);
3813
+ return;
3814
+ }
3815
+ }
3816
+ async function getAllAreaChecklist(req, res, next) {
3817
+ const query = { ...req.query, ...req.params };
3818
+ const validation = import_joi12.default.object({
3819
+ page: import_joi12.default.number().min(1).optional().allow("", null),
3820
+ limit: import_joi12.default.number().min(1).optional().allow("", null),
3821
+ search: import_joi12.default.string().optional().allow("", null),
3822
+ site: import_joi12.default.string().hex().required(),
3823
+ type: import_joi12.default.string().valid(...allowedTypes).required(),
3824
+ parentChecklist: import_joi12.default.string().hex().required()
3825
+ });
3826
+ const { error } = validation.validate(query);
3827
+ if (error) {
3828
+ import_node_server_utils23.logger.log({ level: "error", message: error.message });
3829
+ next(new import_node_server_utils23.BadRequestError(error.message));
3830
+ return;
3831
+ }
3832
+ const page = parseInt(req.query.page) ?? 1;
3833
+ const limit = parseInt(req.query.limit) ?? 20;
3834
+ const search = req.query.search ?? "";
3835
+ const site = req.params.site ?? "";
3836
+ const type = req.params.type ?? "";
3837
+ const parentChecklist = req.params.parentChecklist ?? "";
3838
+ try {
3839
+ const data = await _getAllAreaChecklist({
3840
+ page,
3841
+ limit,
3842
+ search,
3843
+ site,
3844
+ type,
3845
+ parentChecklist
3846
+ });
3847
+ res.json(data);
3848
+ return;
3849
+ } catch (error2) {
3850
+ import_node_server_utils23.logger.log({ level: "error", message: error2.message });
3851
+ next(error2);
3852
+ return;
3853
+ }
3854
+ }
3855
+ async function getAreaChecklistHistory(req, res, next) {
3856
+ const cookies = req.headers.cookie ? req.headers.cookie.split(";").map((cookie) => cookie.trim().split("=")).reduce(
3857
+ (acc, [key, value]) => ({ ...acc, [key]: value }),
3858
+ {}
3859
+ ) : {};
3860
+ const user = cookies["user"] || "";
3861
+ const query = { ...req.query, ...req.params, user };
3862
+ const validation = import_joi12.default.object({
3863
+ page: import_joi12.default.number().min(1).optional().allow("", null),
3864
+ limit: import_joi12.default.number().min(1).optional().allow("", null),
3865
+ search: import_joi12.default.string().optional().allow("", null),
3866
+ site: import_joi12.default.string().hex().required(),
3867
+ type: import_joi12.default.string().valid(...allowedTypes).required(),
3868
+ parentChecklist: import_joi12.default.string().hex().required(),
3869
+ status: import_joi12.default.string().allow("", null, ...allowedStatus),
3870
+ createdAt: import_joi12.default.alternatives().try(import_joi12.default.date(), import_joi12.default.string()).optional().allow("", null),
3871
+ user: import_joi12.default.string().hex().optional().allow("", null)
3872
+ });
3873
+ const { error } = validation.validate(query);
3874
+ if (error) {
3875
+ import_node_server_utils23.logger.log({ level: "error", message: error.message });
3876
+ next(new import_node_server_utils23.BadRequestError(error.message));
3877
+ return;
3878
+ }
3879
+ const page = parseInt(req.query.page) ?? 1;
3880
+ const limit = parseInt(req.query.limit) ?? 20;
3881
+ const search = req.query.search ?? "";
3882
+ const site = req.params.site ?? "";
3883
+ const type = req.params.type ?? "";
3884
+ const parentChecklist = req.params.parentChecklist ?? "";
3885
+ const status = req.query.status ?? "";
3886
+ const createdAt = req.query.createdAt ?? "";
3887
+ try {
3888
+ const data = await _getAreaChecklistHistory({
3889
+ page,
3890
+ limit,
3891
+ search,
3892
+ site,
3893
+ type,
3894
+ parentChecklist,
3895
+ status,
3896
+ createdAt,
3897
+ user
3898
+ });
3899
+ res.json(data);
3900
+ return;
3901
+ } catch (error2) {
3902
+ import_node_server_utils23.logger.log({ level: "error", message: error2.message });
3903
+ next(error2);
3904
+ return;
3905
+ }
3906
+ }
3907
+ async function getAreaChecklistHistoryDetails(req, res, next) {
3908
+ const validation = import_joi12.default.string().hex().required();
3909
+ const _id = req.params.id;
3910
+ const { error } = validation.validate(_id);
3911
+ if (error) {
3912
+ import_node_server_utils23.logger.log({ level: "error", message: error.message });
3913
+ next(new import_node_server_utils23.BadRequestError(error.message));
3914
+ return;
3915
+ }
3916
+ try {
3917
+ const data = await _getAreaChecklistHistoryDetails(_id);
3918
+ res.json(data);
3919
+ return;
3920
+ } catch (error2) {
3921
+ import_node_server_utils23.logger.log({ level: "error", message: error2.message });
3922
+ next(error2);
3923
+ return;
3924
+ }
3925
+ }
3926
+ async function acceptAreaChecklist(req, res, next) {
3927
+ const cookies = req.headers.cookie ? req.headers.cookie.split(";").map((cookie) => cookie.trim().split("=")).reduce(
3928
+ (acc, [key, value]) => ({ ...acc, [key]: value }),
3929
+ {}
3930
+ ) : {};
3931
+ const acceptedBy = cookies["user"] || "";
3932
+ const payload = { id: req.params.id, acceptedBy };
3933
+ const validation = import_joi12.default.object({
3934
+ id: import_joi12.default.string().hex().required(),
3935
+ acceptedBy: import_joi12.default.string().hex().required()
3936
+ });
3937
+ const { error } = validation.validate(payload);
3938
+ if (error) {
3939
+ import_node_server_utils23.logger.log({ level: "error", message: error.message });
3940
+ next(new import_node_server_utils23.BadRequestError(error.message));
3941
+ return;
3942
+ }
3943
+ try {
3944
+ await _acceptAreaChecklist(payload.id, payload.acceptedBy);
3945
+ res.json({ message: "Area checklist updated successfully." });
3946
+ return;
3947
+ } catch (error2) {
3948
+ import_node_server_utils23.logger.log({ level: "error", message: error2.message });
3949
+ next(error2);
3950
+ return;
3951
+ }
3952
+ }
3953
+ async function attachImageAreaChecklist(req, res, next) {
3954
+ const payload = { id: req.params.id, attachments: req.body.attachments };
3955
+ const validation = import_joi12.default.object({
3956
+ id: import_joi12.default.string().hex().required(),
3957
+ attachments: import_joi12.default.array().items(import_joi12.default.string()).optional()
3958
+ });
3959
+ const { error } = validation.validate(payload);
3960
+ if (error) {
3961
+ import_node_server_utils23.logger.log({ level: "error", message: error.message });
3962
+ next(new import_node_server_utils23.BadRequestError(error.message));
3963
+ return;
3964
+ }
3965
+ try {
3966
+ await _attachImageAreaChecklist(payload.id, payload.attachments);
3967
+ res.json({ message: "Area checklist attachments updated successfully." });
3968
+ return;
3969
+ } catch (error2) {
3970
+ import_node_server_utils23.logger.log({ level: "error", message: error2.message });
3971
+ next(error2);
3972
+ return;
3973
+ }
3974
+ }
3975
+ async function submitAreaChecklist(req, res, next) {
3976
+ const payload = { id: req.params.id, signature: req.body.signature };
3977
+ const validation = import_joi12.default.object({
3978
+ id: import_joi12.default.string().hex().required(),
3979
+ signature: import_joi12.default.string().required()
3980
+ });
3981
+ const { error } = validation.validate(payload);
3982
+ if (error) {
3983
+ import_node_server_utils23.logger.log({ level: "error", message: error.message });
3984
+ next(new import_node_server_utils23.BadRequestError(error.message));
3985
+ return;
3986
+ }
3987
+ try {
3988
+ await _submitAreaChecklist(payload.id, payload.signature);
3989
+ res.json({ message: "Area checklist submitted successfully." });
3990
+ return;
3991
+ } catch (error2) {
3992
+ import_node_server_utils23.logger.log({ level: "error", message: error2.message });
3993
+ next(error2);
3994
+ return;
3995
+ }
3996
+ }
3997
+ async function completeAreaChecklist(req, res, next) {
3998
+ const payload = { id: req.params.id, signature: req.body.signature };
3999
+ const validation = import_joi12.default.object({
4000
+ id: import_joi12.default.string().hex().required(),
4001
+ signature: import_joi12.default.string().required()
4002
+ });
4003
+ const { error } = validation.validate(payload);
4004
+ if (error) {
4005
+ import_node_server_utils23.logger.log({ level: "error", message: error.message });
4006
+ next(new import_node_server_utils23.BadRequestError(error.message));
4007
+ return;
4008
+ }
4009
+ try {
4010
+ await _completeAreaChecklist(payload.id, payload.signature);
4011
+ res.json({ message: "Area checklist completed successfully." });
4012
+ return;
4013
+ } catch (error2) {
4014
+ import_node_server_utils23.logger.log({ level: "error", message: error2.message });
4015
+ next(error2);
4016
+ return;
4017
+ }
4018
+ }
4019
+ return {
4020
+ createAreaChecklist,
4021
+ getAllAreaChecklist,
4022
+ getAreaChecklistHistory,
4023
+ getAreaChecklistHistoryDetails,
4024
+ acceptAreaChecklist,
4025
+ attachImageAreaChecklist,
4026
+ submitAreaChecklist,
4027
+ completeAreaChecklist
4028
+ };
4029
+ }
4030
+
4031
+ // src/models/hygiene-unit-checklist.model.ts
4032
+ var import_node_server_utils24 = require("@iservice365/node-server-utils");
4033
+ var import_joi13 = __toESM(require("joi"));
4034
+ var import_mongodb13 = require("mongodb");
4035
+ var unitChecklistSchema = import_joi13.default.object({
4036
+ site: import_joi13.default.string().hex().required(),
4037
+ type: import_joi13.default.string().valid(...allowedTypes).required(),
4038
+ parentChecklist: import_joi13.default.string().hex().required(),
4039
+ areaChecklist: import_joi13.default.string().hex().required(),
4040
+ unit: import_joi13.default.string().hex().required(),
4041
+ name: import_joi13.default.string().optional().allow("", null),
4042
+ createdBy: import_joi13.default.string().hex().optional().allow("", null)
4043
+ });
4044
+ function MUnitChecklist(value) {
4045
+ const { error } = unitChecklistSchema.validate(value);
4046
+ if (error) {
4047
+ import_node_server_utils24.logger.info(`Hygiene Checklist Unit Model: ${error.message}`);
4048
+ throw new import_node_server_utils24.BadRequestError(error.message);
4049
+ }
4050
+ if (value.site) {
4051
+ try {
4052
+ value.site = new import_mongodb13.ObjectId(value.site);
4053
+ } catch (error2) {
4054
+ throw new import_node_server_utils24.BadRequestError("Invalid site ID format.");
4055
+ }
4056
+ }
4057
+ if (value.parentChecklist) {
4058
+ try {
4059
+ value.parentChecklist = new import_mongodb13.ObjectId(value.parentChecklist);
4060
+ } catch (error2) {
4061
+ throw new import_node_server_utils24.BadRequestError("Invalid parent checklist ID format.");
4062
+ }
4063
+ }
4064
+ if (value.areaChecklist) {
4065
+ try {
4066
+ value.areaChecklist = new import_mongodb13.ObjectId(value.areaChecklist);
4067
+ } catch (error2) {
4068
+ throw new import_node_server_utils24.BadRequestError("Invalid area checklist ID format.");
4069
+ }
4070
+ }
4071
+ if (value.unit) {
4072
+ try {
4073
+ value.unit = new import_mongodb13.ObjectId(value.unit);
4074
+ } catch (error2) {
4075
+ throw new import_node_server_utils24.BadRequestError("Invalid unit ID format.");
4076
+ }
4077
+ }
4078
+ if (value.createdBy) {
4079
+ try {
4080
+ value.createdBy = new import_mongodb13.ObjectId(value.createdBy);
4081
+ } catch (error2) {
4082
+ throw new import_node_server_utils24.BadRequestError("Invalid createdBy ID format.");
4083
+ }
4084
+ }
4085
+ return {
4086
+ site: value.site,
4087
+ type: value.type,
4088
+ parentChecklist: value.parentChecklist,
4089
+ areaChecklist: value.areaChecklist,
4090
+ unit: value.unit,
4091
+ name: value.name ?? "",
4092
+ approve: false,
4093
+ reject: false,
4094
+ createdBy: value.createdBy ?? "",
4095
+ createdAt: /* @__PURE__ */ new Date(),
4096
+ updatedAt: value.updatedAt ?? ""
4097
+ };
4098
+ }
4099
+
4100
+ // src/repositories/hygiene-unit-checklist.repository.ts
4101
+ var import_node_server_utils25 = require("@iservice365/node-server-utils");
4102
+ var import_mongodb14 = require("mongodb");
4103
+ function useUnitChecklistRepo() {
4104
+ const db = import_node_server_utils25.useAtlas.getDb();
4105
+ if (!db) {
4106
+ throw new import_node_server_utils25.InternalServerError("Unable to connect to server.");
4107
+ }
4108
+ const namespace_collection = "hygiene-checklist.units";
4109
+ const collection = db.collection(namespace_collection);
4110
+ const { delNamespace, setCache, getCache } = (0, import_node_server_utils25.useCache)(namespace_collection);
4111
+ async function createIndex() {
4112
+ try {
4113
+ await collection.createIndexes([
4114
+ { key: { site: 1 } },
4115
+ { key: { type: 1 } },
4116
+ { key: { parentChecklist: 1 } },
4117
+ { key: { areaChecklist: 1 } },
4118
+ { key: { "metadata.workOrder.category": 1 } },
4119
+ { key: { "metadata.workOrder.createdBy": 1 } },
4120
+ { key: { "metadata.workOrder.serviceProvider": 1 } },
4121
+ { key: { "metadata.workOrder.organization": 1 } },
4122
+ { key: { "metadata.workOrder.site": 1 } }
4123
+ ]);
4124
+ } catch (error) {
4125
+ throw new import_node_server_utils25.InternalServerError(
4126
+ "Failed to create index on hygiene unit checklist."
4127
+ );
4128
+ }
4129
+ }
4130
+ async function createTextIndex() {
4131
+ try {
4132
+ await collection.createIndex({ name: "text" });
4133
+ } catch (error) {
4134
+ throw new import_node_server_utils25.InternalServerError(
4135
+ "Failed to create text index on hygiene unit checklist."
4136
+ );
4137
+ }
4138
+ }
4139
+ async function createUnitChecklist(value, session) {
4140
+ try {
4141
+ value = MUnitChecklist(value);
4142
+ const res = await collection.insertOne(value, { session });
4143
+ delNamespace().then(() => {
4144
+ import_node_server_utils25.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
4145
+ }).catch((err) => {
4146
+ import_node_server_utils25.logger.error(
4147
+ `Failed to clear cache for namespace: ${namespace_collection}`,
4148
+ err
4149
+ );
4150
+ });
4151
+ return res.insertedId;
4152
+ } catch (error) {
4153
+ throw error;
4154
+ }
4155
+ }
4156
+ async function getAllUnitChecklist({
4157
+ page = 1,
4158
+ limit = 10,
4159
+ search = "",
4160
+ site,
4161
+ type,
4162
+ parentChecklist,
4163
+ areaChecklist
4164
+ }) {
4165
+ page = page > 0 ? page - 1 : 0;
4166
+ const query = { type };
4167
+ const cacheOptions = {
4168
+ page,
4169
+ limit
4170
+ };
4171
+ try {
4172
+ query.site = new import_mongodb14.ObjectId(site);
4173
+ cacheOptions.site = site.toString();
4174
+ } catch (error) {
4175
+ throw new import_node_server_utils25.BadRequestError("Invalid site ID format.");
4176
+ }
4177
+ try {
4178
+ query.parentChecklist = new import_mongodb14.ObjectId(parentChecklist);
4179
+ cacheOptions.parentChecklist = parentChecklist.toString();
4180
+ } catch (error) {
4181
+ throw new import_node_server_utils25.BadRequestError("Invalid parent checklist ID format.");
4182
+ }
4183
+ try {
4184
+ query.areaChecklist = new import_mongodb14.ObjectId(areaChecklist);
4185
+ cacheOptions.areaChecklist = areaChecklist.toString();
4186
+ } catch (error) {
4187
+ throw new import_node_server_utils25.BadRequestError("Invalid area checklist ID format.");
4188
+ }
4189
+ if (search) {
4190
+ query.$text = { $search: search };
4191
+ cacheOptions.search = search;
4192
+ }
4193
+ const cacheKey = (0, import_node_server_utils25.makeCacheKey)(namespace_collection, cacheOptions);
4194
+ const cachedData = await getCache(cacheKey);
4195
+ if (cachedData) {
4196
+ import_node_server_utils25.logger.info(`Cache hit for key: ${cacheKey}`);
4197
+ return cachedData;
4198
+ }
4199
+ try {
4200
+ const areaAttachmentsResult = await collection.aggregate([
4201
+ { $match: query },
4202
+ {
4203
+ $lookup: {
4204
+ from: "hygiene-checklist.areas",
4205
+ localField: "areaChecklist",
4206
+ foreignField: "_id",
4207
+ pipeline: [
4208
+ { $project: { attachments: "$metadata.attachments" } }
4209
+ ],
4210
+ as: "areaChecklistData"
4211
+ }
4212
+ },
4213
+ {
4214
+ $unwind: {
4215
+ path: "$areaChecklistData",
4216
+ preserveNullAndEmptyArrays: true
4217
+ }
4218
+ },
4219
+ {
4220
+ $group: {
4221
+ _id: null,
4222
+ attachments: { $first: "$areaChecklistData.attachments" }
4223
+ }
4224
+ }
4225
+ ]).toArray();
4226
+ const areaAttachments = areaAttachmentsResult.length > 0 ? areaAttachmentsResult[0].attachments || [] : [];
4227
+ const pipeline = [
4228
+ { $match: query },
4229
+ {
4230
+ $lookup: {
4231
+ from: "organizations",
4232
+ localField: "metadata.workOrder.category",
4233
+ foreignField: "_id",
4234
+ pipeline: [{ $project: { nature: 1 } }],
4235
+ as: "categoryData"
4236
+ }
4237
+ },
4238
+ {
4239
+ $lookup: {
4240
+ from: "users",
4241
+ localField: "metadata.workOrder.createdBy",
4242
+ foreignField: "_id",
4243
+ pipeline: [{ $project: { name: 1 } }],
4244
+ as: "createdByData"
4245
+ }
4246
+ },
4247
+ {
4248
+ $lookup: {
4249
+ from: "service-providers",
4250
+ localField: "metadata.workOrder.serviceProvider",
4251
+ foreignField: "_id",
4252
+ pipeline: [{ $project: { name: 1 } }],
4253
+ as: "serviceProviderData"
4254
+ }
4255
+ },
4256
+ {
4257
+ $lookup: {
4258
+ from: "organizations",
4259
+ localField: "metadata.workOrder.organization",
4260
+ foreignField: "_id",
4261
+ pipeline: [{ $project: { name: 1 } }],
4262
+ as: "organizationData"
4263
+ }
4264
+ },
4265
+ {
4266
+ $lookup: {
4267
+ from: "sites",
4268
+ localField: "metadata.workOrder.site",
4269
+ foreignField: "_id",
4270
+ pipeline: [{ $project: { name: 1 } }],
4271
+ as: "siteData"
4272
+ }
4273
+ },
4274
+ {
4275
+ $addFields: {
4276
+ "metadata.workOrder.categoryName": {
4277
+ $arrayElemAt: ["$categoryData.nature", 0]
4278
+ },
4279
+ "metadata.workOrder.createdByName": {
4280
+ $arrayElemAt: ["$createdByData.name", 0]
4281
+ },
4282
+ "metadata.workOrder.serviceProviderName": {
4283
+ $arrayElemAt: ["$serviceProviderData.name", 0]
4284
+ },
4285
+ "metadata.workOrder.organizationName": {
4286
+ $arrayElemAt: ["$organizationData.name", 0]
4287
+ },
4288
+ "metadata.workOrder.siteName": {
4289
+ $arrayElemAt: ["$siteData.name", 0]
4290
+ }
4291
+ }
4292
+ },
4293
+ {
4294
+ $project: {
4295
+ name: 1,
4296
+ remarks: "$metadata.remarks",
4297
+ attachments: "$metadata.attachments",
4298
+ workOrder: "$metadata.workOrder",
4299
+ approve: { $ifNull: ["$approve", null] },
4300
+ reject: { $ifNull: ["$reject", null] }
4301
+ }
4302
+ },
4303
+ { $sort: { _id: -1 } },
4304
+ { $skip: page * limit },
4305
+ { $limit: limit }
4306
+ ];
4307
+ const items = await collection.aggregate(pipeline).toArray();
4308
+ const length = await collection.countDocuments(query);
4309
+ const paginatedData = (0, import_node_server_utils25.paginate)(items, page, limit, length);
4310
+ const data = {
4311
+ attachments: areaAttachments,
4312
+ ...paginatedData
4313
+ };
4314
+ setCache(cacheKey, data, 15 * 60).then(() => {
4315
+ import_node_server_utils25.logger.info(`Cache set for key: ${cacheKey}`);
4316
+ }).catch((err) => {
4317
+ import_node_server_utils25.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
4318
+ });
4319
+ return data;
4320
+ } catch (error) {
4321
+ throw error;
4322
+ }
4323
+ }
4324
+ async function getUnitChecklistById(_id) {
4325
+ try {
4326
+ _id = new import_mongodb14.ObjectId(_id);
4327
+ } catch (error) {
4328
+ throw new import_node_server_utils25.BadRequestError("Invalid unit checklist ID format.");
4329
+ }
4330
+ try {
4331
+ return await collection.findOne({ _id });
4332
+ } catch (error) {
4333
+ throw error;
4334
+ }
4335
+ }
4336
+ async function updateUnitChecklist(_id, value, session) {
4337
+ try {
4338
+ _id = new import_mongodb14.ObjectId(_id);
4339
+ } catch (error) {
4340
+ throw new import_node_server_utils25.BadRequestError("Invalid unit checklist ID format.");
4341
+ }
4342
+ if (value.checkedBy && typeof value.checkedBy === "string") {
4343
+ try {
4344
+ value.checkedBy = new import_mongodb14.ObjectId(value.checkedBy);
4345
+ } catch (error) {
4346
+ throw new import_node_server_utils25.BadRequestError("Invalid checkedBy ID format.");
4347
+ }
4348
+ }
4349
+ if ("metadata" in value && value.metadata?.workOrder) {
4350
+ const workOrder = value.metadata.workOrder;
4351
+ if (workOrder.category && typeof workOrder.category === "string") {
4352
+ try {
4353
+ workOrder.category = new import_mongodb14.ObjectId(workOrder.category);
4354
+ } catch (error) {
4355
+ throw new import_node_server_utils25.BadRequestError("Invalid category ID format.");
4356
+ }
4357
+ }
4358
+ if (workOrder.createdBy && typeof workOrder.createdBy === "string") {
4359
+ try {
4360
+ workOrder.createdBy = new import_mongodb14.ObjectId(workOrder.createdBy);
4361
+ } catch (error) {
4362
+ throw new import_node_server_utils25.BadRequestError("Invalid createdBy ID format.");
4363
+ }
4364
+ }
4365
+ if (workOrder.serviceProvider && typeof workOrder.serviceProvider === "string") {
4366
+ try {
4367
+ workOrder.serviceProvider = new import_mongodb14.ObjectId(workOrder.serviceProvider);
4368
+ } catch (error) {
4369
+ throw new import_node_server_utils25.BadRequestError("Invalid serviceProvider ID format.");
4370
+ }
4371
+ }
4372
+ if (workOrder.organization && typeof workOrder.organization === "string") {
4373
+ try {
4374
+ workOrder.organization = new import_mongodb14.ObjectId(workOrder.organization);
4375
+ } catch (error) {
4376
+ throw new import_node_server_utils25.BadRequestError("Invalid organization ID format.");
4377
+ }
4378
+ }
4379
+ if (workOrder.site && typeof workOrder.site === "string") {
4380
+ try {
4381
+ workOrder.site = new import_mongodb14.ObjectId(workOrder.site);
4382
+ } catch (error) {
4383
+ throw new import_node_server_utils25.BadRequestError("Invalid site ID format.");
4384
+ }
4385
+ }
4386
+ }
4387
+ try {
4388
+ const updateValue = { ...value, updatedAt: /* @__PURE__ */ new Date() };
4389
+ const res = await collection.updateOne(
4390
+ { _id },
4391
+ { $set: updateValue },
4392
+ { session }
4393
+ );
4394
+ if (res.modifiedCount === 0) {
4395
+ throw new import_node_server_utils25.InternalServerError("Unable to update unit checklist.");
4396
+ }
4397
+ delNamespace().then(() => {
4398
+ import_node_server_utils25.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
4399
+ }).catch((err) => {
4400
+ import_node_server_utils25.logger.error(
4401
+ `Failed to clear cache for namespace: ${namespace_collection}`,
4402
+ err
4403
+ );
4404
+ });
4405
+ return res.modifiedCount;
4406
+ } catch (error) {
4407
+ throw error;
4408
+ }
4409
+ }
4410
+ return {
4411
+ createIndex,
4412
+ createTextIndex,
4413
+ createUnitChecklist,
4414
+ getAllUnitChecklist,
4415
+ getUnitChecklistById,
4416
+ updateUnitChecklist
4417
+ };
4418
+ }
4419
+
4420
+ // src/controllers/hygiene-unit-checklist.controller.ts
4421
+ var import_node_server_utils27 = require("@iservice365/node-server-utils");
4422
+ var import_joi14 = __toESM(require("joi"));
4423
+
4424
+ // src/services/hygiene-unit-checklist.service.ts
4425
+ var import_node_server_utils26 = require("@iservice365/node-server-utils");
4426
+ var import_core = require("@iservice365/core");
4427
+ function useUnitChecklistService() {
4428
+ const {
4429
+ getUnitChecklistById: _getUnitChecklistById,
4430
+ updateUnitChecklist: _updateUnitChecklist
4431
+ } = useUnitChecklistRepo();
4432
+ const { getSiteById } = (0, import_core.useSiteRepo)();
4433
+ const { createWorkOrder } = (0, import_core.useWorkOrderService)();
4434
+ async function approveUnitChecklist(id, value) {
4435
+ try {
4436
+ value.approve = true;
4437
+ value.reject = false;
4438
+ const result = await _updateUnitChecklist(id, value);
4439
+ return result;
4440
+ } catch (error) {
4441
+ import_node_server_utils26.logger.error(`Error updating unit checklist with id ${id}:`, error);
4442
+ throw error;
4443
+ }
4444
+ }
4445
+ async function rejectUnitChecklist(id, value, fullHost) {
4446
+ try {
4447
+ value.reject = true;
4448
+ value.approve = false;
4449
+ if (value.metadata?.workOrder) {
4450
+ const existingChecklist = await _getUnitChecklistById(id);
4451
+ if (!existingChecklist)
4452
+ throw new import_node_server_utils26.NotFoundError("Unit checklist not found.");
4453
+ const site = await getSiteById(
4454
+ existingChecklist.site
4455
+ );
4456
+ if (!site)
4457
+ throw new import_node_server_utils26.NotFoundError("Site not found.");
4458
+ const workOrderData = {
4459
+ ...value.metadata.workOrder,
4460
+ attachments: value.metadata.attachments,
4461
+ createdBy: value.checkedBy,
4462
+ organization: site.orgId,
4463
+ site: site._id
4464
+ };
4465
+ const workOrder = await createWorkOrder(
4466
+ workOrderData,
4467
+ fullHost
4468
+ );
4469
+ if (!workOrder)
4470
+ throw new import_node_server_utils26.NotFoundError("Failed to create work order.");
4471
+ }
4472
+ const result = await _updateUnitChecklist(id, value);
4473
+ return result;
4474
+ } catch (error) {
4475
+ import_node_server_utils26.logger.error(`Error updating unit checklist with id ${id}:`, error);
4476
+ throw error;
4477
+ }
4478
+ }
4479
+ return {
4480
+ approveUnitChecklist,
4481
+ rejectUnitChecklist
4482
+ };
4483
+ }
4484
+
4485
+ // src/controllers/hygiene-unit-checklist.controller.ts
4486
+ var import_core2 = require("@iservice365/core");
4487
+ function useUnitChecklistController() {
4488
+ const {
4489
+ createUnitChecklist: _createUnitChecklist,
4490
+ getAllUnitChecklist: _getAllUnitChecklist
4491
+ } = useUnitChecklistRepo();
4492
+ const {
4493
+ approveUnitChecklist: _approveUnitChecklist,
4494
+ rejectUnitChecklist: _rejectUnitChecklist
4495
+ } = useUnitChecklistService();
4496
+ async function createUnitChecklist(req, res, next) {
4497
+ const cookies = req.headers.cookie ? req.headers.cookie.split(";").map((cookie) => cookie.trim().split("=")).reduce(
4498
+ (acc, [key, value]) => ({ ...acc, [key]: value }),
4499
+ {}
4500
+ ) : {};
4501
+ const createdBy = cookies["user"] || "";
4502
+ const payload = { ...req.body, ...req.params, createdBy };
4503
+ const { error } = unitChecklistSchema.validate(payload);
4504
+ if (error) {
4505
+ import_node_server_utils27.logger.log({ level: "error", message: error.message });
4506
+ next(new import_node_server_utils27.BadRequestError(error.message));
4507
+ return;
4508
+ }
4509
+ try {
4510
+ const id = await _createUnitChecklist(payload);
4511
+ res.status(201).json({ message: "Unit checklist created successfully.", id });
4512
+ return;
4513
+ } catch (error2) {
4514
+ import_node_server_utils27.logger.log({ level: "error", message: error2.message });
4515
+ next(error2);
4516
+ return;
4517
+ }
4518
+ }
4519
+ async function getAllUnitChecklist(req, res, next) {
4520
+ const query = { ...req.query, ...req.params };
4521
+ const validation = import_joi14.default.object({
4522
+ page: import_joi14.default.number().min(1).optional().allow("", null),
4523
+ limit: import_joi14.default.number().min(1).optional().allow("", null),
4524
+ search: import_joi14.default.string().optional().allow("", null),
4525
+ site: import_joi14.default.string().hex().required(),
4526
+ type: import_joi14.default.string().valid(...allowedTypes).required(),
4527
+ parentChecklist: import_joi14.default.string().hex().required(),
4528
+ areaChecklist: import_joi14.default.string().hex().required()
4529
+ });
4530
+ const { error } = validation.validate(query);
4531
+ if (error) {
4532
+ import_node_server_utils27.logger.log({ level: "error", message: error.message });
4533
+ next(new import_node_server_utils27.BadRequestError(error.message));
4534
+ return;
4535
+ }
4536
+ const page = parseInt(req.query.page) ?? 1;
4537
+ const limit = parseInt(req.query.limit) ?? 20;
4538
+ const search = req.query.search ?? "";
4539
+ const site = req.params.site ?? "";
4540
+ const type = req.params.type ?? "";
4541
+ const parentChecklist = req.params.parentChecklist ?? "";
4542
+ const areaChecklist = req.params.areaChecklist ?? "";
4543
+ try {
4544
+ const data = await _getAllUnitChecklist({
4545
+ page,
4546
+ limit,
4547
+ search,
4548
+ site,
4549
+ type,
4550
+ parentChecklist,
4551
+ areaChecklist
4552
+ });
4553
+ res.json(data);
4554
+ return;
4555
+ } catch (error2) {
4556
+ import_node_server_utils27.logger.log({ level: "error", message: error2.message });
4557
+ next(error2);
4558
+ return;
4559
+ }
4560
+ }
4561
+ async function approveUnitChecklist(req, res, next) {
4562
+ const cookies = req.headers.cookie ? req.headers.cookie.split(";").map((cookie) => cookie.trim().split("=")).reduce(
4563
+ (acc, [key, value]) => ({ ...acc, [key]: value }),
4564
+ {}
4565
+ ) : {};
4566
+ const checkedBy = cookies["user"] || "";
4567
+ const payload = { id: req.params.id, checkedBy };
4568
+ const validation = import_joi14.default.object({
4569
+ id: import_joi14.default.string().hex().required(),
4570
+ checkedBy: import_joi14.default.string().hex().required()
4571
+ });
4572
+ const { error } = validation.validate(payload);
4573
+ if (error) {
4574
+ import_node_server_utils27.logger.log({ level: "error", message: error.message });
4575
+ next(new import_node_server_utils27.BadRequestError(error.message));
4576
+ return;
4577
+ }
4578
+ try {
4579
+ const { id, ...value } = payload;
4580
+ await _approveUnitChecklist(id, value);
4581
+ res.json({ message: "Unit checklist approved successfully." });
4582
+ return;
4583
+ } catch (error2) {
4584
+ import_node_server_utils27.logger.log({ level: "error", message: error2.message });
4585
+ next(error2);
4586
+ return;
4587
+ }
4588
+ }
4589
+ async function rejectUnitChecklist(req, res, next) {
4590
+ const cookies = req.headers.cookie ? req.headers.cookie.split(";").map((cookie) => cookie.trim().split("=")).reduce(
4591
+ (acc, [key, value]) => ({ ...acc, [key]: value }),
4592
+ {}
4593
+ ) : {};
4594
+ const checkedBy = cookies["user"] || "";
4595
+ if (req.body.workOrder) {
4596
+ req.body.workOrder.createdBy = checkedBy;
4597
+ }
4598
+ const payload = { id: req.params.id, checkedBy, ...req.body };
4599
+ const validation = import_joi14.default.object({
4600
+ id: import_joi14.default.string().hex().required(),
4601
+ attachments: import_joi14.default.array().items(import_joi14.default.string()).optional(),
4602
+ remarks: import_joi14.default.string().required(),
4603
+ workOrder: import_core2.workOrderSchema.optional(),
4604
+ checkedBy: import_joi14.default.string().hex().required()
4605
+ });
4606
+ const { error } = validation.validate(payload);
4607
+ if (error) {
4608
+ import_node_server_utils27.logger.log({ level: "error", message: error.message });
4609
+ next(new import_node_server_utils27.BadRequestError(error.message));
4610
+ return;
4611
+ }
4612
+ try {
4613
+ const { id, attachments, remarks, workOrder, ...value } = payload;
4614
+ value.metadata = {
4615
+ attachments: attachments || [],
4616
+ remarks: remarks || "",
4617
+ workOrder
4618
+ };
4619
+ if (value.metadata.workOrder) {
4620
+ if (value.metadata.workOrder.category) {
4621
+ value.metadata.workOrder.category = value.metadata.workOrder.category;
4622
+ }
4623
+ if (value.metadata.workOrder.serviceProvider) {
4624
+ value.metadata.workOrder.serviceProvider = value.metadata.workOrder.serviceProvider;
4625
+ }
4626
+ value.metadata.workOrder.createdBy = checkedBy;
4627
+ }
4628
+ const fullHost = req.headers.origin;
4629
+ await _rejectUnitChecklist(id, value, fullHost);
4630
+ res.json({ message: "Unit checklist rejected successfully." });
4631
+ return;
4632
+ } catch (error2) {
4633
+ import_node_server_utils27.logger.log({ level: "error", message: error2.message });
4634
+ next(error2);
4635
+ return;
4636
+ }
4637
+ }
4638
+ return {
4639
+ createUnitChecklist,
4640
+ getAllUnitChecklist,
4641
+ approveUnitChecklist,
4642
+ rejectUnitChecklist
2754
4643
  };
2755
4644
  }
2756
4645
  // Annotate the CommonJS export names for ESM import in node:
2757
4646
  0 && (module.exports = {
2758
4647
  MArea,
4648
+ MAreaChecklist,
2759
4649
  MParentChecklist,
2760
4650
  MScheduleTaskArea,
2761
4651
  MToiletLocation,
2762
4652
  MUnit,
4653
+ MUnitChecklist,
4654
+ allowedStatus,
4655
+ allowedTypes,
4656
+ areaChecklistSchema,
2763
4657
  areaSchema,
2764
4658
  parentChecklistSchema,
2765
4659
  scheduleTaskAreaSchema,
2766
4660
  toiletLocationSchema,
4661
+ unitChecklistSchema,
2767
4662
  unitSchema,
4663
+ useAreaChecklistController,
4664
+ useAreaChecklistRepo,
2768
4665
  useAreaController,
2769
4666
  useAreaRepository,
2770
4667
  useAreaService,
2771
- useParentCheckilstController,
4668
+ useParentChecklistController,
2772
4669
  useParentChecklistRepo,
2773
4670
  useScheduleTaskAreaController,
2774
4671
  useScheduleTaskAreaRepository,
@@ -2776,6 +4673,8 @@ function useScheduleTaskAreaController() {
2776
4673
  useToiletLocationController,
2777
4674
  useToiletLocationRepository,
2778
4675
  useToiletLocationService,
4676
+ useUnitChecklistController,
4677
+ useUnitChecklistRepo,
2779
4678
  useUnitController,
2780
4679
  useUnitRepository,
2781
4680
  useUnitService