@7365admin1/module-hygiene 4.12.0 → 4.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/index.d.ts +74 -29
- package/dist/index.js +334 -229
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +338 -230
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
// src/models/hygiene-base.model.ts
|
|
2
|
+
var ServiceType = /* @__PURE__ */ ((ServiceType2) => {
|
|
3
|
+
ServiceType2["REAL_ESTATE_DEVELOPER"] = "real_estate_developer";
|
|
4
|
+
ServiceType2["PROPERTY_MANAGEMENT_AGENCY"] = "property_management_agency";
|
|
5
|
+
ServiceType2["SECURITY_AGENCY"] = "security_agency";
|
|
6
|
+
ServiceType2["CLEANING_SERVICES"] = "cleaning_services";
|
|
7
|
+
ServiceType2["MECHANICAL_ELECTRICAL_SERVICES"] = "mechanical_electrical_services";
|
|
8
|
+
ServiceType2["LANDSCAPING_SERVICES"] = "landscaping_services";
|
|
9
|
+
ServiceType2["PEST_CONTROL_SERVICES"] = "pest_control_services";
|
|
10
|
+
ServiceType2["POOL_MAINTENANCE_SERVICES"] = "pool_maintenance_services";
|
|
11
|
+
return ServiceType2;
|
|
12
|
+
})(ServiceType || {});
|
|
2
13
|
var allowedTypes = ["common", "toilet"];
|
|
3
14
|
var allowedStatus = [
|
|
4
15
|
"open",
|
|
@@ -547,6 +558,7 @@ import { ObjectId as ObjectId2 } from "mongodb";
|
|
|
547
558
|
import { BadRequestError as BadRequestError3, logger as logger3 } from "@7365admin1/node-server-utils";
|
|
548
559
|
var areaSchema = Joi2.object({
|
|
549
560
|
site: Joi2.string().hex().required(),
|
|
561
|
+
serviceType: Joi2.string().valid(...Object.values(ServiceType)).required(),
|
|
550
562
|
name: Joi2.string().required(),
|
|
551
563
|
type: Joi2.string().valid(...allowedTypes).required(),
|
|
552
564
|
set: Joi2.number().min(0).optional(),
|
|
@@ -586,6 +598,7 @@ function MArea(value) {
|
|
|
586
598
|
}
|
|
587
599
|
return {
|
|
588
600
|
site: value.site,
|
|
601
|
+
serviceType: value.serviceType,
|
|
589
602
|
name: value.name,
|
|
590
603
|
type: value.type,
|
|
591
604
|
set: value.set ?? 0,
|
|
@@ -630,6 +643,7 @@ function useAreaRepo() {
|
|
|
630
643
|
try {
|
|
631
644
|
await collection.createIndexes([
|
|
632
645
|
{ key: { site: 1 } },
|
|
646
|
+
{ key: { serviceType: 1 } },
|
|
633
647
|
{ key: { type: 1 } },
|
|
634
648
|
{ key: { status: 1 } },
|
|
635
649
|
{ key: { "units.unit": 1 } }
|
|
@@ -650,7 +664,7 @@ function useAreaRepo() {
|
|
|
650
664
|
async function createUniqueIndex() {
|
|
651
665
|
try {
|
|
652
666
|
await collection.createIndex(
|
|
653
|
-
{ site: 1, name: 1, type: 1, deletedAt: 1 },
|
|
667
|
+
{ site: 1, serviceType: 1, name: 1, type: 1, deletedAt: 1 },
|
|
654
668
|
{ unique: true }
|
|
655
669
|
);
|
|
656
670
|
} catch (error) {
|
|
@@ -687,15 +701,18 @@ function useAreaRepo() {
|
|
|
687
701
|
limit = 10,
|
|
688
702
|
search = "",
|
|
689
703
|
type = "all",
|
|
690
|
-
site
|
|
704
|
+
site,
|
|
705
|
+
serviceType
|
|
691
706
|
}) {
|
|
692
707
|
page = page > 0 ? page - 1 : 0;
|
|
693
708
|
const query = {
|
|
694
|
-
status: { $ne: "deleted" }
|
|
709
|
+
status: { $ne: "deleted" },
|
|
710
|
+
serviceType
|
|
695
711
|
};
|
|
696
712
|
const cacheOptions = {
|
|
697
713
|
page,
|
|
698
|
-
limit
|
|
714
|
+
limit,
|
|
715
|
+
serviceType
|
|
699
716
|
};
|
|
700
717
|
try {
|
|
701
718
|
site = new ObjectId3(site);
|
|
@@ -744,9 +761,12 @@ function useAreaRepo() {
|
|
|
744
761
|
throw error;
|
|
745
762
|
}
|
|
746
763
|
}
|
|
747
|
-
async function getAreasForChecklist(site) {
|
|
748
|
-
const query = {
|
|
749
|
-
|
|
764
|
+
async function getAreasForChecklist(site, serviceType) {
|
|
765
|
+
const query = {
|
|
766
|
+
status: { $ne: "deleted" },
|
|
767
|
+
serviceType
|
|
768
|
+
};
|
|
769
|
+
const cacheOptions = { serviceType };
|
|
750
770
|
try {
|
|
751
771
|
site = new ObjectId3(site);
|
|
752
772
|
query.site = site;
|
|
@@ -826,28 +846,6 @@ function useAreaRepo() {
|
|
|
826
846
|
throw error;
|
|
827
847
|
}
|
|
828
848
|
}
|
|
829
|
-
async function getAreaByMultipleId(_id) {
|
|
830
|
-
for (let i = 0; i < _id.length; i++) {
|
|
831
|
-
try {
|
|
832
|
-
_id[i] = new ObjectId3(_id[i]);
|
|
833
|
-
} catch (error) {
|
|
834
|
-
throw new BadRequestError4("Invalid area ID format.");
|
|
835
|
-
}
|
|
836
|
-
}
|
|
837
|
-
const query = {
|
|
838
|
-
_id: { $in: _id },
|
|
839
|
-
status: { $ne: "deleted" }
|
|
840
|
-
};
|
|
841
|
-
try {
|
|
842
|
-
const data = await collection.aggregate([{ $match: query }]).toArray();
|
|
843
|
-
if (!data || data.length === 0) {
|
|
844
|
-
throw new NotFoundError("Area not found.");
|
|
845
|
-
}
|
|
846
|
-
return data;
|
|
847
|
-
} catch (error) {
|
|
848
|
-
throw error;
|
|
849
|
-
}
|
|
850
|
-
}
|
|
851
849
|
async function verifyAreaByUnitId(unitId) {
|
|
852
850
|
try {
|
|
853
851
|
unitId = new ObjectId3(unitId);
|
|
@@ -1009,7 +1007,6 @@ function useAreaRepo() {
|
|
|
1009
1007
|
getAreas,
|
|
1010
1008
|
getAreasForChecklist,
|
|
1011
1009
|
getAreaById,
|
|
1012
|
-
getAreaByMultipleId,
|
|
1013
1010
|
verifyAreaByUnitId,
|
|
1014
1011
|
updateArea,
|
|
1015
1012
|
updateAreaChecklist,
|
|
@@ -1088,6 +1085,7 @@ import { ObjectId as ObjectId4 } from "mongodb";
|
|
|
1088
1085
|
import { BadRequestError as BadRequestError5, logger as logger6 } from "@7365admin1/node-server-utils";
|
|
1089
1086
|
var unitSchema = Joi3.object({
|
|
1090
1087
|
site: Joi3.string().hex().required(),
|
|
1088
|
+
serviceType: Joi3.string().valid(...Object.values(ServiceType)).required(),
|
|
1091
1089
|
name: Joi3.string().required()
|
|
1092
1090
|
});
|
|
1093
1091
|
function MUnit(value) {
|
|
@@ -1105,6 +1103,7 @@ function MUnit(value) {
|
|
|
1105
1103
|
}
|
|
1106
1104
|
return {
|
|
1107
1105
|
site: value.site,
|
|
1106
|
+
serviceType: value.serviceType,
|
|
1108
1107
|
name: value.name,
|
|
1109
1108
|
status: "active",
|
|
1110
1109
|
createdAt: /* @__PURE__ */ new Date(),
|
|
@@ -1126,6 +1125,7 @@ function useUnitRepository() {
|
|
|
1126
1125
|
try {
|
|
1127
1126
|
await collection.createIndexes([
|
|
1128
1127
|
{ key: { site: 1 } },
|
|
1128
|
+
{ key: { serviceType: 1 } },
|
|
1129
1129
|
{ key: { status: 1 } }
|
|
1130
1130
|
]);
|
|
1131
1131
|
} catch (error) {
|
|
@@ -1144,7 +1144,7 @@ function useUnitRepository() {
|
|
|
1144
1144
|
async function createUniqueIndex() {
|
|
1145
1145
|
try {
|
|
1146
1146
|
await collection.createIndex(
|
|
1147
|
-
{ site: 1, name: 1, deletedAt: 1 },
|
|
1147
|
+
{ site: 1, serviceType: 1, name: 1, deletedAt: 1 },
|
|
1148
1148
|
{ unique: true }
|
|
1149
1149
|
);
|
|
1150
1150
|
} catch (error) {
|
|
@@ -1178,7 +1178,8 @@ function useUnitRepository() {
|
|
|
1178
1178
|
page = 1,
|
|
1179
1179
|
limit = 10,
|
|
1180
1180
|
search = "",
|
|
1181
|
-
site
|
|
1181
|
+
site,
|
|
1182
|
+
serviceType
|
|
1182
1183
|
}) {
|
|
1183
1184
|
page = page > 0 ? page - 1 : 0;
|
|
1184
1185
|
const query = {
|
|
@@ -1195,6 +1196,10 @@ function useUnitRepository() {
|
|
|
1195
1196
|
} catch (error) {
|
|
1196
1197
|
throw new BadRequestError6("Invalid site ID format.");
|
|
1197
1198
|
}
|
|
1199
|
+
if (serviceType) {
|
|
1200
|
+
query.serviceType = serviceType;
|
|
1201
|
+
cacheOptions.serviceType = serviceType;
|
|
1202
|
+
}
|
|
1198
1203
|
if (search) {
|
|
1199
1204
|
query.$or = [{ name: { $regex: search, $options: "i" } }];
|
|
1200
1205
|
cacheOptions.search = search;
|
|
@@ -1253,7 +1258,7 @@ function useUnitRepository() {
|
|
|
1253
1258
|
} catch (error) {
|
|
1254
1259
|
const isDuplicated = error.message.includes("duplicate");
|
|
1255
1260
|
if (isDuplicated) {
|
|
1256
|
-
throw new BadRequestError6("
|
|
1261
|
+
throw new BadRequestError6("Unit already exists.");
|
|
1257
1262
|
}
|
|
1258
1263
|
throw error;
|
|
1259
1264
|
}
|
|
@@ -1309,7 +1314,8 @@ function useAreaService() {
|
|
|
1309
1314
|
const { getUnits: _getUnits } = useUnitRepository();
|
|
1310
1315
|
async function importArea({
|
|
1311
1316
|
dataJson,
|
|
1312
|
-
site
|
|
1317
|
+
site,
|
|
1318
|
+
serviceType
|
|
1313
1319
|
}) {
|
|
1314
1320
|
let dataArray;
|
|
1315
1321
|
try {
|
|
@@ -1330,7 +1336,8 @@ function useAreaService() {
|
|
|
1330
1336
|
page: 1,
|
|
1331
1337
|
limit: 999999,
|
|
1332
1338
|
search: "",
|
|
1333
|
-
site
|
|
1339
|
+
site,
|
|
1340
|
+
serviceType
|
|
1334
1341
|
});
|
|
1335
1342
|
if (unitsData && unitsData.items) {
|
|
1336
1343
|
availableUnits = unitsData.items;
|
|
@@ -1377,7 +1384,8 @@ function useAreaService() {
|
|
|
1377
1384
|
const areaData = {
|
|
1378
1385
|
type: areaType,
|
|
1379
1386
|
name: areaName,
|
|
1380
|
-
site
|
|
1387
|
+
site,
|
|
1388
|
+
serviceType
|
|
1381
1389
|
};
|
|
1382
1390
|
if (row.SET !== void 0 && row.SET !== null && row.SET !== "") {
|
|
1383
1391
|
const setNumber = parseInt(String(row.SET).trim());
|
|
@@ -1471,9 +1479,12 @@ function useAreaService() {
|
|
|
1471
1479
|
}
|
|
1472
1480
|
}
|
|
1473
1481
|
}
|
|
1474
|
-
async function exportAreas(
|
|
1482
|
+
async function exportAreas({
|
|
1483
|
+
site,
|
|
1484
|
+
serviceType
|
|
1485
|
+
}) {
|
|
1475
1486
|
try {
|
|
1476
|
-
const areas = await getAreasForChecklist(site);
|
|
1487
|
+
const areas = await getAreasForChecklist(site, serviceType);
|
|
1477
1488
|
if (!areas || !Array.isArray(areas) || areas.length === 0) {
|
|
1478
1489
|
throw new BadRequestError7(
|
|
1479
1490
|
"There are no areas to export yet. Please add some areas first, then try again."
|
|
@@ -1560,7 +1571,8 @@ function useAreaController() {
|
|
|
1560
1571
|
limit: Joi4.number().min(1).optional().allow("", null),
|
|
1561
1572
|
search: Joi4.string().optional().allow("", null),
|
|
1562
1573
|
type: Joi4.string().valid("all", ...allowedTypes).optional().allow("", null),
|
|
1563
|
-
site: Joi4.string().hex().required()
|
|
1574
|
+
site: Joi4.string().hex().required(),
|
|
1575
|
+
serviceType: Joi4.string().valid(...Object.values(ServiceType)).required()
|
|
1564
1576
|
});
|
|
1565
1577
|
const { error } = validation.validate(query);
|
|
1566
1578
|
if (error) {
|
|
@@ -1573,13 +1585,15 @@ function useAreaController() {
|
|
|
1573
1585
|
const search = req.query.search ?? "";
|
|
1574
1586
|
const type = req.query.type ?? "all";
|
|
1575
1587
|
const site = req.params.site ?? "";
|
|
1588
|
+
const serviceType = req.query.serviceType ?? "";
|
|
1576
1589
|
try {
|
|
1577
1590
|
const data = await _getAreas({
|
|
1578
1591
|
page,
|
|
1579
1592
|
limit,
|
|
1580
1593
|
search,
|
|
1581
1594
|
type,
|
|
1582
|
-
site
|
|
1595
|
+
site,
|
|
1596
|
+
serviceType
|
|
1583
1597
|
});
|
|
1584
1598
|
res.json(data);
|
|
1585
1599
|
return;
|
|
@@ -1664,9 +1678,12 @@ function useAreaController() {
|
|
|
1664
1678
|
next(new BadRequestError8("File is required!"));
|
|
1665
1679
|
return;
|
|
1666
1680
|
}
|
|
1667
|
-
const
|
|
1668
|
-
const
|
|
1669
|
-
|
|
1681
|
+
const query = { ...req.query, ...req.params };
|
|
1682
|
+
const validation = Joi4.object({
|
|
1683
|
+
site: Joi4.string().hex().required(),
|
|
1684
|
+
serviceType: Joi4.string().valid(...Object.values(ServiceType)).required()
|
|
1685
|
+
});
|
|
1686
|
+
const { error, value } = validation.validate(query);
|
|
1670
1687
|
if (error) {
|
|
1671
1688
|
logger9.log({ level: "error", message: error.message });
|
|
1672
1689
|
next(new BadRequestError8(error.message));
|
|
@@ -1675,7 +1692,7 @@ function useAreaController() {
|
|
|
1675
1692
|
try {
|
|
1676
1693
|
const xlsData = await convertBufferFile(req.file.buffer);
|
|
1677
1694
|
const dataJson = JSON.stringify(xlsData);
|
|
1678
|
-
const result = await _importArea({ dataJson,
|
|
1695
|
+
const result = await _importArea({ dataJson, ...value });
|
|
1679
1696
|
return res.status(201).json(result);
|
|
1680
1697
|
} catch (error2) {
|
|
1681
1698
|
logger9.log({ level: "error", message: error2.message });
|
|
@@ -1684,9 +1701,12 @@ function useAreaController() {
|
|
|
1684
1701
|
}
|
|
1685
1702
|
}
|
|
1686
1703
|
async function exportAreas(req, res, next) {
|
|
1687
|
-
const
|
|
1688
|
-
const validation = Joi4.
|
|
1689
|
-
|
|
1704
|
+
const query = { ...req.query, ...req.params };
|
|
1705
|
+
const validation = Joi4.object({
|
|
1706
|
+
site: Joi4.string().hex().required(),
|
|
1707
|
+
serviceType: Joi4.string().valid(...Object.values(ServiceType)).required()
|
|
1708
|
+
});
|
|
1709
|
+
const { error, value } = validation.validate(query);
|
|
1690
1710
|
if (error) {
|
|
1691
1711
|
logger9.log({ level: "error", message: error.message });
|
|
1692
1712
|
next(new BadRequestError8(error.message));
|
|
@@ -1782,7 +1802,8 @@ function useUnitService() {
|
|
|
1782
1802
|
} = useUnitRepository();
|
|
1783
1803
|
async function importUnit({
|
|
1784
1804
|
dataJson,
|
|
1785
|
-
site
|
|
1805
|
+
site,
|
|
1806
|
+
serviceType
|
|
1786
1807
|
}) {
|
|
1787
1808
|
let dataArray;
|
|
1788
1809
|
try {
|
|
@@ -1823,7 +1844,8 @@ function useUnitService() {
|
|
|
1823
1844
|
try {
|
|
1824
1845
|
const insertedId = await _createUnit({
|
|
1825
1846
|
name: unitName,
|
|
1826
|
-
site
|
|
1847
|
+
site,
|
|
1848
|
+
serviceType
|
|
1827
1849
|
});
|
|
1828
1850
|
insertedUnitIds.push(insertedId);
|
|
1829
1851
|
logger11.info(`Successfully created unit: ${unitName}`);
|
|
@@ -1928,7 +1950,10 @@ function useUnitService() {
|
|
|
1928
1950
|
session?.endSession();
|
|
1929
1951
|
}
|
|
1930
1952
|
}
|
|
1931
|
-
async function exportUnits(
|
|
1953
|
+
async function exportUnits({
|
|
1954
|
+
site,
|
|
1955
|
+
serviceType
|
|
1956
|
+
}) {
|
|
1932
1957
|
const { generateUnitExcel: _generateUnitExcel } = useUnitExportService();
|
|
1933
1958
|
const { getUnits: _getUnits } = useUnitRepository();
|
|
1934
1959
|
try {
|
|
@@ -1936,7 +1961,8 @@ function useUnitService() {
|
|
|
1936
1961
|
page: 1,
|
|
1937
1962
|
limit: 999999,
|
|
1938
1963
|
search: "",
|
|
1939
|
-
site
|
|
1964
|
+
site,
|
|
1965
|
+
serviceType
|
|
1940
1966
|
});
|
|
1941
1967
|
if (!data || !data.items || data.items.length === 0) {
|
|
1942
1968
|
throw new BadRequestError9(
|
|
@@ -1993,7 +2019,8 @@ function useUnitController() {
|
|
|
1993
2019
|
page: Joi5.number().min(1).optional().allow("", null),
|
|
1994
2020
|
limit: Joi5.number().min(1).optional().allow("", null),
|
|
1995
2021
|
search: Joi5.string().optional().allow("", null),
|
|
1996
|
-
site: Joi5.string().hex().required()
|
|
2022
|
+
site: Joi5.string().hex().required(),
|
|
2023
|
+
serviceType: Joi5.string().valid(...Object.values(ServiceType)).required()
|
|
1997
2024
|
});
|
|
1998
2025
|
const { error } = validation.validate(query);
|
|
1999
2026
|
if (error) {
|
|
@@ -2005,12 +2032,14 @@ function useUnitController() {
|
|
|
2005
2032
|
const limit = parseInt(req.query.limit) ?? 10;
|
|
2006
2033
|
const search = req.query.search ?? "";
|
|
2007
2034
|
const site = req.params.site ?? "";
|
|
2035
|
+
const serviceType = req.query.serviceType ?? "";
|
|
2008
2036
|
try {
|
|
2009
2037
|
const data = await _getUnits({
|
|
2010
2038
|
page,
|
|
2011
2039
|
limit,
|
|
2012
2040
|
search,
|
|
2013
|
-
site
|
|
2041
|
+
site,
|
|
2042
|
+
serviceType
|
|
2014
2043
|
});
|
|
2015
2044
|
res.json(data);
|
|
2016
2045
|
return;
|
|
@@ -2069,9 +2098,12 @@ function useUnitController() {
|
|
|
2069
2098
|
next(new BadRequestError10("File is required!"));
|
|
2070
2099
|
return;
|
|
2071
2100
|
}
|
|
2072
|
-
const
|
|
2073
|
-
const validation = Joi5.
|
|
2074
|
-
|
|
2101
|
+
const query = { ...req.query, ...req.params };
|
|
2102
|
+
const validation = Joi5.object({
|
|
2103
|
+
site: Joi5.string().hex().required(),
|
|
2104
|
+
serviceType: Joi5.string().valid(...Object.values(ServiceType)).required()
|
|
2105
|
+
});
|
|
2106
|
+
const { error, value } = validation.validate(query);
|
|
2075
2107
|
if (error) {
|
|
2076
2108
|
logger12.log({ level: "error", message: error.message });
|
|
2077
2109
|
next(new BadRequestError10(error.message));
|
|
@@ -2080,7 +2112,7 @@ function useUnitController() {
|
|
|
2080
2112
|
try {
|
|
2081
2113
|
const xlsData = await convertBufferFile(req.file.buffer);
|
|
2082
2114
|
const dataJson = JSON.stringify(xlsData);
|
|
2083
|
-
const result = await _importUnit({ dataJson,
|
|
2115
|
+
const result = await _importUnit({ dataJson, ...value });
|
|
2084
2116
|
return res.status(201).json(result);
|
|
2085
2117
|
} catch (error2) {
|
|
2086
2118
|
logger12.log({ level: "error", message: error2.message });
|
|
@@ -2089,9 +2121,12 @@ function useUnitController() {
|
|
|
2089
2121
|
}
|
|
2090
2122
|
}
|
|
2091
2123
|
async function exportUnits(req, res, next) {
|
|
2092
|
-
const
|
|
2093
|
-
const validation = Joi5.
|
|
2094
|
-
|
|
2124
|
+
const query = { ...req.query, ...req.params };
|
|
2125
|
+
const validation = Joi5.object({
|
|
2126
|
+
site: Joi5.string().hex().required(),
|
|
2127
|
+
serviceType: Joi5.string().valid(...Object.values(ServiceType)).required()
|
|
2128
|
+
});
|
|
2129
|
+
const { error, value } = validation.validate(query);
|
|
2095
2130
|
if (error) {
|
|
2096
2131
|
logger12.log({ level: "error", message: error.message });
|
|
2097
2132
|
next(new BadRequestError10(error.message));
|
|
@@ -2137,7 +2172,8 @@ import { ObjectId as ObjectId6 } from "mongodb";
|
|
|
2137
2172
|
import { BadRequestError as BadRequestError11, logger as logger13 } from "@7365admin1/node-server-utils";
|
|
2138
2173
|
var parentChecklistSchema = Joi6.object({
|
|
2139
2174
|
createdAt: Joi6.alternatives().try(Joi6.date(), Joi6.string()).optional().allow("", null),
|
|
2140
|
-
site: Joi6.string().hex().required()
|
|
2175
|
+
site: Joi6.string().hex().required(),
|
|
2176
|
+
serviceType: Joi6.string().valid(...Object.values(ServiceType)).required()
|
|
2141
2177
|
});
|
|
2142
2178
|
function MParentChecklist(value) {
|
|
2143
2179
|
const { error } = parentChecklistSchema.validate(value);
|
|
@@ -2154,6 +2190,7 @@ function MParentChecklist(value) {
|
|
|
2154
2190
|
}
|
|
2155
2191
|
return {
|
|
2156
2192
|
site: value.site,
|
|
2193
|
+
serviceType: value.serviceType,
|
|
2157
2194
|
status: "open",
|
|
2158
2195
|
createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
|
|
2159
2196
|
updatedAt: value.updatedAt ?? ""
|
|
@@ -2184,6 +2221,7 @@ function useParentChecklistRepo() {
|
|
|
2184
2221
|
async function createIndex() {
|
|
2185
2222
|
try {
|
|
2186
2223
|
await collection.createIndexes([
|
|
2224
|
+
{ key: { serviceType: 1 } },
|
|
2187
2225
|
{ key: { createdAt: 1 } },
|
|
2188
2226
|
{ key: { site: 1 } },
|
|
2189
2227
|
{ key: { status: 1 } }
|
|
@@ -2201,60 +2239,80 @@ function useParentChecklistRepo() {
|
|
|
2201
2239
|
startOfDay.setUTCHours(0, 0, 0, 0);
|
|
2202
2240
|
const endOfDay = new Date(currentDate);
|
|
2203
2241
|
endOfDay.setUTCHours(23, 59, 59, 999);
|
|
2204
|
-
const
|
|
2205
|
-
|
|
2206
|
-
$gte: startOfDay,
|
|
2207
|
-
$lte: endOfDay
|
|
2208
|
-
}
|
|
2209
|
-
};
|
|
2242
|
+
const allServiceTypes = Object.values(ServiceType);
|
|
2243
|
+
const dateStr = currentDate.toISOString().split("T")[0];
|
|
2210
2244
|
if (value.site) {
|
|
2245
|
+
let siteObjectId;
|
|
2211
2246
|
try {
|
|
2212
|
-
|
|
2213
|
-
logger14.info(
|
|
2214
|
-
`createParentChecklist: Looking for existing checklist with query: ${JSON.stringify(
|
|
2215
|
-
{ ...existingQuery, site: value.site }
|
|
2216
|
-
)}`
|
|
2217
|
-
);
|
|
2247
|
+
siteObjectId = new ObjectId7(value.site);
|
|
2218
2248
|
} catch (error) {
|
|
2219
2249
|
throw new BadRequestError12("Invalid site ID format.");
|
|
2220
2250
|
}
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2251
|
+
if (value.serviceType) {
|
|
2252
|
+
const existingChecklist = await collection.findOne({
|
|
2253
|
+
createdAt: { $gte: startOfDay, $lte: endOfDay },
|
|
2254
|
+
site: siteObjectId,
|
|
2255
|
+
serviceType: value.serviceType
|
|
2256
|
+
});
|
|
2257
|
+
if (existingChecklist) {
|
|
2258
|
+
logger14.info(
|
|
2259
|
+
`Parent checklist already exists for site ${value.site} / ${value.serviceType} on ${dateStr}. _id: ${existingChecklist._id}`
|
|
2260
|
+
);
|
|
2261
|
+
return existingChecklist._id;
|
|
2262
|
+
}
|
|
2263
|
+
const doc = MParentChecklist({
|
|
2264
|
+
site: value.site,
|
|
2265
|
+
createdAt: currentDate,
|
|
2266
|
+
serviceType: value.serviceType
|
|
2267
|
+
});
|
|
2268
|
+
const result3 = await collection.insertOne(doc, { session });
|
|
2269
|
+
delNamespace().catch((err) => {
|
|
2270
|
+
logger14.error(
|
|
2271
|
+
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
2272
|
+
err
|
|
2273
|
+
);
|
|
2274
|
+
});
|
|
2275
|
+
logger14.info(
|
|
2276
|
+
`Created parent checklist for site ${value.site} / ${value.serviceType} for today: ${dateStr}`
|
|
2277
|
+
);
|
|
2278
|
+
return result3.insertedId;
|
|
2279
|
+
}
|
|
2280
|
+
const existingServiceTypes = await collection.distinct("serviceType", {
|
|
2281
|
+
createdAt: { $gte: startOfDay, $lte: endOfDay },
|
|
2282
|
+
site: siteObjectId,
|
|
2283
|
+
serviceType: { $exists: true, $ne: null }
|
|
2284
|
+
});
|
|
2285
|
+
const missingServiceTypes = allServiceTypes.filter(
|
|
2286
|
+
(st) => !existingServiceTypes.includes(st)
|
|
2226
2287
|
);
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2288
|
+
if (missingServiceTypes.length === 0) {
|
|
2289
|
+
logger14.info(
|
|
2290
|
+
`All serviceType checklists already exist for site ${value.site} on ${dateStr}`
|
|
2291
|
+
);
|
|
2292
|
+
const first = await collection.findOne({
|
|
2293
|
+
createdAt: { $gte: startOfDay, $lte: endOfDay },
|
|
2294
|
+
site: siteObjectId
|
|
2295
|
+
});
|
|
2296
|
+
return first._id;
|
|
2297
|
+
}
|
|
2298
|
+
const checklistDocs2 = missingServiceTypes.map(
|
|
2299
|
+
(serviceType) => MParentChecklist({
|
|
2300
|
+
site: value.site,
|
|
2301
|
+
createdAt: currentDate,
|
|
2302
|
+
serviceType
|
|
2303
|
+
})
|
|
2236
2304
|
);
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
if (value.site) {
|
|
2240
|
-
const checklistDoc = MParentChecklist({
|
|
2241
|
-
site: value.site,
|
|
2242
|
-
createdAt: currentDate
|
|
2243
|
-
});
|
|
2244
|
-
const result2 = await collection.insertOne(checklistDoc, { session });
|
|
2245
|
-
delNamespace().then(() => {
|
|
2246
|
-
logger14.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
2247
|
-
}).catch((err) => {
|
|
2305
|
+
const result2 = await collection.insertMany(checklistDocs2, { session });
|
|
2306
|
+
delNamespace().catch((err) => {
|
|
2248
2307
|
logger14.error(
|
|
2249
2308
|
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
2250
2309
|
err
|
|
2251
2310
|
);
|
|
2252
2311
|
});
|
|
2253
|
-
const dateStr2 = currentDate.toISOString().split("T")[0];
|
|
2254
2312
|
logger14.info(
|
|
2255
|
-
`Created parent
|
|
2313
|
+
`Created ${checklistDocs2.length} parent checklists for site ${value.site} for today: ${dateStr}`
|
|
2256
2314
|
);
|
|
2257
|
-
return result2.
|
|
2315
|
+
return Object.values(result2.insertedIds);
|
|
2258
2316
|
}
|
|
2259
2317
|
const siteIds = await getHygieneSiteIds();
|
|
2260
2318
|
if (!Array.isArray(siteIds)) {
|
|
@@ -2265,15 +2323,41 @@ function useParentChecklistRepo() {
|
|
|
2265
2323
|
logger14.warn("No sites found for creating parent checklist");
|
|
2266
2324
|
throw new BadRequestError12("No sites available for checklist creation");
|
|
2267
2325
|
}
|
|
2326
|
+
const existingPairs = await collection.find(
|
|
2327
|
+
{
|
|
2328
|
+
createdAt: { $gte: startOfDay, $lte: endOfDay },
|
|
2329
|
+
serviceType: { $exists: true, $ne: null }
|
|
2330
|
+
},
|
|
2331
|
+
{ projection: { site: 1, serviceType: 1 } }
|
|
2332
|
+
).toArray();
|
|
2333
|
+
const existingSet = new Set(
|
|
2334
|
+
existingPairs.map(
|
|
2335
|
+
(doc) => `${doc.site?.toString()}|${doc.serviceType}`
|
|
2336
|
+
)
|
|
2337
|
+
);
|
|
2268
2338
|
const checklistDocs = [];
|
|
2269
2339
|
for (const site of siteIds) {
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2340
|
+
for (const serviceType of allServiceTypes) {
|
|
2341
|
+
if (!existingSet.has(`${site}|${serviceType}`)) {
|
|
2342
|
+
checklistDocs.push(
|
|
2343
|
+
MParentChecklist({
|
|
2344
|
+
site,
|
|
2345
|
+
createdAt: currentDate,
|
|
2346
|
+
serviceType
|
|
2347
|
+
})
|
|
2348
|
+
);
|
|
2349
|
+
}
|
|
2350
|
+
}
|
|
2351
|
+
}
|
|
2352
|
+
if (checklistDocs.length === 0) {
|
|
2353
|
+
logger14.info(
|
|
2354
|
+
`All site+serviceType checklists already exist for today: ${dateStr}`
|
|
2275
2355
|
);
|
|
2356
|
+
return [];
|
|
2276
2357
|
}
|
|
2358
|
+
logger14.info(
|
|
2359
|
+
`createParentChecklist: Creating ${checklistDocs.length} missing site+serviceType checklist(s) for today: ${dateStr}`
|
|
2360
|
+
);
|
|
2277
2361
|
const result = await collection.insertMany(checklistDocs, { session });
|
|
2278
2362
|
delNamespace().then(() => {
|
|
2279
2363
|
logger14.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
@@ -2283,7 +2367,6 @@ function useParentChecklistRepo() {
|
|
|
2283
2367
|
err
|
|
2284
2368
|
);
|
|
2285
2369
|
});
|
|
2286
|
-
const dateStr = currentDate.toISOString().split("T")[0];
|
|
2287
2370
|
logger14.info(
|
|
2288
2371
|
`Created ${Object.keys(result.insertedIds).length} parent checklists for today: ${dateStr}`
|
|
2289
2372
|
);
|
|
@@ -2300,13 +2383,15 @@ function useParentChecklistRepo() {
|
|
|
2300
2383
|
site,
|
|
2301
2384
|
startDate = "",
|
|
2302
2385
|
endDate = "",
|
|
2303
|
-
status = "all"
|
|
2386
|
+
status = "all",
|
|
2387
|
+
serviceType
|
|
2304
2388
|
}) {
|
|
2305
2389
|
page = page > 0 ? page - 1 : 0;
|
|
2306
|
-
const query = {};
|
|
2390
|
+
const query = { serviceType };
|
|
2307
2391
|
const cacheOptions = {
|
|
2308
2392
|
page,
|
|
2309
|
-
limit
|
|
2393
|
+
limit,
|
|
2394
|
+
serviceType
|
|
2310
2395
|
};
|
|
2311
2396
|
try {
|
|
2312
2397
|
site = new ObjectId7(site);
|
|
@@ -2389,6 +2474,23 @@ function useParentChecklistRepo() {
|
|
|
2389
2474
|
throw error;
|
|
2390
2475
|
}
|
|
2391
2476
|
}
|
|
2477
|
+
async function getParentChecklistById(_id) {
|
|
2478
|
+
try {
|
|
2479
|
+
_id = new ObjectId7(_id);
|
|
2480
|
+
} catch (error) {
|
|
2481
|
+
throw new BadRequestError12("Invalid parent checklist ID format.");
|
|
2482
|
+
}
|
|
2483
|
+
try {
|
|
2484
|
+
const data = await collection.findOne({ _id });
|
|
2485
|
+
if (!data) {
|
|
2486
|
+
throw new BadRequestError12("Parent checklist not found.");
|
|
2487
|
+
}
|
|
2488
|
+
return data;
|
|
2489
|
+
} catch (error) {
|
|
2490
|
+
logger14.error("Failed to get parent checklist by ID", error);
|
|
2491
|
+
throw error;
|
|
2492
|
+
}
|
|
2493
|
+
}
|
|
2392
2494
|
async function updateParentChecklistStatuses(_id, status, session) {
|
|
2393
2495
|
try {
|
|
2394
2496
|
_id = new ObjectId7(_id);
|
|
@@ -2503,13 +2605,38 @@ function useParentChecklistRepo() {
|
|
|
2503
2605
|
throw error;
|
|
2504
2606
|
}
|
|
2505
2607
|
}
|
|
2608
|
+
async function getTodayParentChecklistsForAreaGen() {
|
|
2609
|
+
const now = /* @__PURE__ */ new Date();
|
|
2610
|
+
const start = new Date(now);
|
|
2611
|
+
start.setUTCHours(0, 0, 0, 0);
|
|
2612
|
+
const end = new Date(now);
|
|
2613
|
+
end.setUTCHours(23, 59, 59, 999);
|
|
2614
|
+
try {
|
|
2615
|
+
const items = await collection.find(
|
|
2616
|
+
{
|
|
2617
|
+
createdAt: { $gte: start, $lte: end },
|
|
2618
|
+
serviceType: { $exists: true, $ne: null }
|
|
2619
|
+
},
|
|
2620
|
+
{ projection: { _id: 1, site: 1, serviceType: 1 } }
|
|
2621
|
+
).toArray();
|
|
2622
|
+
return items;
|
|
2623
|
+
} catch (error) {
|
|
2624
|
+
logger14.error(
|
|
2625
|
+
"Failed to get today's parent checklists for area generation",
|
|
2626
|
+
error
|
|
2627
|
+
);
|
|
2628
|
+
throw error;
|
|
2629
|
+
}
|
|
2630
|
+
}
|
|
2506
2631
|
return {
|
|
2507
2632
|
createIndex,
|
|
2508
2633
|
createParentChecklist,
|
|
2509
2634
|
getAllParentChecklist,
|
|
2635
|
+
getParentChecklistById,
|
|
2510
2636
|
updateParentChecklistStatuses,
|
|
2511
2637
|
closeExpiredParentChecklists,
|
|
2512
|
-
getTodayParentChecklists
|
|
2638
|
+
getTodayParentChecklists,
|
|
2639
|
+
getTodayParentChecklistsForAreaGen
|
|
2513
2640
|
};
|
|
2514
2641
|
}
|
|
2515
2642
|
|
|
@@ -2546,6 +2673,7 @@ function useParentChecklistController() {
|
|
|
2546
2673
|
limit: Joi7.number().min(1).optional().allow("", null),
|
|
2547
2674
|
search: Joi7.string().optional().allow("", null),
|
|
2548
2675
|
site: Joi7.string().hex().required(),
|
|
2676
|
+
serviceType: Joi7.string().valid(...Object.values(ServiceType)).required(),
|
|
2549
2677
|
startDate: Joi7.alternatives().try(Joi7.date(), Joi7.string()).optional().allow("", null),
|
|
2550
2678
|
endDate: Joi7.alternatives().try(Joi7.date(), Joi7.string()).optional().allow("", null),
|
|
2551
2679
|
status: Joi7.string().valid(...allowedStatus, "all").optional().allow("", null)
|
|
@@ -2560,6 +2688,7 @@ function useParentChecklistController() {
|
|
|
2560
2688
|
const limit = parseInt(req.query.limit) ?? 10;
|
|
2561
2689
|
const search = req.query.search ?? "";
|
|
2562
2690
|
const site = req.params.site ?? "";
|
|
2691
|
+
const serviceType = req.query.serviceType ?? "";
|
|
2563
2692
|
const startDate = req.query.startDate ?? "";
|
|
2564
2693
|
const endDate = req.query.endDate ?? "";
|
|
2565
2694
|
const status = req.query.status ?? "all";
|
|
@@ -2569,6 +2698,7 @@ function useParentChecklistController() {
|
|
|
2569
2698
|
limit,
|
|
2570
2699
|
search,
|
|
2571
2700
|
site,
|
|
2701
|
+
serviceType,
|
|
2572
2702
|
startDate,
|
|
2573
2703
|
endDate,
|
|
2574
2704
|
status
|
|
@@ -2594,6 +2724,7 @@ import { BadRequestError as BadRequestError14, logger as logger16 } from "@7365a
|
|
|
2594
2724
|
var allowedChecklistStatus = ["open", "completed", "closed"];
|
|
2595
2725
|
var areaChecklistSchema = Joi8.object({
|
|
2596
2726
|
schedule: Joi8.string().hex().required(),
|
|
2727
|
+
serviceType: Joi8.string().valid(...Object.values(ServiceType)).optional(),
|
|
2597
2728
|
area: Joi8.string().hex().required(),
|
|
2598
2729
|
name: Joi8.string().required(),
|
|
2599
2730
|
type: Joi8.string().valid(...allowedTypes).required(),
|
|
@@ -2660,6 +2791,7 @@ function MAreaChecklist(value) {
|
|
|
2660
2791
|
}
|
|
2661
2792
|
return {
|
|
2662
2793
|
schedule: value.schedule,
|
|
2794
|
+
serviceType: value.serviceType,
|
|
2663
2795
|
area: value.area,
|
|
2664
2796
|
name: value.name,
|
|
2665
2797
|
type: value.type,
|
|
@@ -2781,7 +2913,8 @@ function useAreaChecklistRepo() {
|
|
|
2781
2913
|
search = "",
|
|
2782
2914
|
type = "all",
|
|
2783
2915
|
status = "all",
|
|
2784
|
-
schedule
|
|
2916
|
+
schedule,
|
|
2917
|
+
serviceType
|
|
2785
2918
|
}, session) {
|
|
2786
2919
|
page = page > 0 ? page - 1 : 0;
|
|
2787
2920
|
const query = {};
|
|
@@ -2795,6 +2928,10 @@ function useAreaChecklistRepo() {
|
|
|
2795
2928
|
} catch (error) {
|
|
2796
2929
|
throw new BadRequestError15("Invalid parent checklist ID format.");
|
|
2797
2930
|
}
|
|
2931
|
+
if (serviceType) {
|
|
2932
|
+
query.serviceType = serviceType;
|
|
2933
|
+
cacheOptions.serviceType = serviceType;
|
|
2934
|
+
}
|
|
2798
2935
|
if (type && type !== "all") {
|
|
2799
2936
|
query.type = type;
|
|
2800
2937
|
cacheOptions.type = type;
|
|
@@ -3190,6 +3327,7 @@ function useAreaChecklistRepo() {
|
|
|
3190
3327
|
page = 1,
|
|
3191
3328
|
limit = 10,
|
|
3192
3329
|
search = "",
|
|
3330
|
+
serviceType,
|
|
3193
3331
|
_id
|
|
3194
3332
|
}, session) {
|
|
3195
3333
|
page = page > 0 ? page - 1 : 0;
|
|
@@ -3204,6 +3342,10 @@ function useAreaChecklistRepo() {
|
|
|
3204
3342
|
} catch (error) {
|
|
3205
3343
|
throw new BadRequestError15("Invalid area checklist ID format.");
|
|
3206
3344
|
}
|
|
3345
|
+
if (serviceType) {
|
|
3346
|
+
query.serviceType = serviceType;
|
|
3347
|
+
cacheOptions.serviceType = serviceType;
|
|
3348
|
+
}
|
|
3207
3349
|
if (search) {
|
|
3208
3350
|
query.$text = { $search: search };
|
|
3209
3351
|
cacheOptions.search = search;
|
|
@@ -3427,7 +3569,12 @@ function useAreaChecklistRepo() {
|
|
|
3427
3569
|
throw error;
|
|
3428
3570
|
}
|
|
3429
3571
|
}
|
|
3430
|
-
async function getAreaChecklistByAreaAndSchedule(
|
|
3572
|
+
async function getAreaChecklistByAreaAndSchedule({
|
|
3573
|
+
schedule,
|
|
3574
|
+
serviceType,
|
|
3575
|
+
area,
|
|
3576
|
+
session
|
|
3577
|
+
}) {
|
|
3431
3578
|
try {
|
|
3432
3579
|
schedule = new ObjectId9(schedule);
|
|
3433
3580
|
area = new ObjectId9(area);
|
|
@@ -3435,7 +3582,10 @@ function useAreaChecklistRepo() {
|
|
|
3435
3582
|
throw new BadRequestError15("Invalid area checklist ID format.");
|
|
3436
3583
|
}
|
|
3437
3584
|
try {
|
|
3438
|
-
const data = await collection.findOne(
|
|
3585
|
+
const data = await collection.findOne(
|
|
3586
|
+
{ schedule, serviceType, area },
|
|
3587
|
+
{ session }
|
|
3588
|
+
);
|
|
3439
3589
|
if (!data) {
|
|
3440
3590
|
throw new BadRequestError15("Area checklist not found.");
|
|
3441
3591
|
}
|
|
@@ -3644,7 +3794,7 @@ function useAreaChecklistRepo() {
|
|
|
3644
3794
|
throw error;
|
|
3645
3795
|
}
|
|
3646
3796
|
}
|
|
3647
|
-
async function pushScheduleTaskSets(scheduleId, areaId, scheduleTaskId, newSets) {
|
|
3797
|
+
async function pushScheduleTaskSets(scheduleId, serviceType, areaId, scheduleTaskId, newSets) {
|
|
3648
3798
|
try {
|
|
3649
3799
|
const schedule = new ObjectId9(scheduleId);
|
|
3650
3800
|
const area = new ObjectId9(areaId);
|
|
@@ -3652,6 +3802,7 @@ function useAreaChecklistRepo() {
|
|
|
3652
3802
|
const result = await collection.updateOne(
|
|
3653
3803
|
{
|
|
3654
3804
|
schedule,
|
|
3805
|
+
serviceType,
|
|
3655
3806
|
area,
|
|
3656
3807
|
checklist: { $not: { $elemMatch: { scheduleTaskId: taskId } } }
|
|
3657
3808
|
},
|
|
@@ -3674,13 +3825,14 @@ function useAreaChecklistRepo() {
|
|
|
3674
3825
|
throw error;
|
|
3675
3826
|
}
|
|
3676
3827
|
}
|
|
3677
|
-
async function insertAutoGenSets(scheduleId, areaId, newSets) {
|
|
3828
|
+
async function insertAutoGenSets(scheduleId, serviceType, areaId, newSets) {
|
|
3678
3829
|
try {
|
|
3679
3830
|
const schedule = new ObjectId9(scheduleId);
|
|
3680
3831
|
const area = new ObjectId9(areaId);
|
|
3681
3832
|
const result = await collection.updateOne(
|
|
3682
3833
|
{
|
|
3683
3834
|
schedule,
|
|
3835
|
+
serviceType,
|
|
3684
3836
|
area,
|
|
3685
3837
|
checklist: {
|
|
3686
3838
|
$not: { $elemMatch: { isScheduleTask: { $ne: true } } }
|
|
@@ -3826,14 +3978,25 @@ function useAreaChecklistService() {
|
|
|
3826
3978
|
updateAreaChecklistStatus,
|
|
3827
3979
|
insertAutoGenSets
|
|
3828
3980
|
} = useAreaChecklistRepo();
|
|
3829
|
-
const { updateParentChecklistStatuses } = useParentChecklistRepo();
|
|
3981
|
+
const { updateParentChecklistStatuses, getParentChecklistById } = useParentChecklistRepo();
|
|
3830
3982
|
const { getUserById } = useUserRepo();
|
|
3831
3983
|
async function createAreaChecklist(value) {
|
|
3832
3984
|
const results = [];
|
|
3833
3985
|
let totalChecklistsCreated = 0;
|
|
3834
3986
|
try {
|
|
3835
3987
|
const BATCH_SIZE = 10;
|
|
3836
|
-
const
|
|
3988
|
+
const schedule = await getParentChecklistById(value.schedule.toString());
|
|
3989
|
+
const serviceType = schedule.serviceType;
|
|
3990
|
+
if (!serviceType) {
|
|
3991
|
+
logger18.warn(
|
|
3992
|
+
`createAreaChecklist: Parent checklist ${value.schedule} has no serviceType, skipping area checklist generation`
|
|
3993
|
+
);
|
|
3994
|
+
return results;
|
|
3995
|
+
}
|
|
3996
|
+
const areasResult = await getAreasForChecklist(
|
|
3997
|
+
value.site,
|
|
3998
|
+
serviceType
|
|
3999
|
+
);
|
|
3837
4000
|
const areas = areasResult || [];
|
|
3838
4001
|
if (areas.length > 0) {
|
|
3839
4002
|
for (let i = 0; i < areas.length; i += BATCH_SIZE) {
|
|
@@ -3847,10 +4010,11 @@ function useAreaChecklistService() {
|
|
|
3847
4010
|
}
|
|
3848
4011
|
let existing = null;
|
|
3849
4012
|
try {
|
|
3850
|
-
existing = await getAreaChecklistByAreaAndSchedule(
|
|
3851
|
-
value.schedule.toString(),
|
|
3852
|
-
|
|
3853
|
-
|
|
4013
|
+
existing = await getAreaChecklistByAreaAndSchedule({
|
|
4014
|
+
schedule: value.schedule.toString(),
|
|
4015
|
+
serviceType,
|
|
4016
|
+
area: area._id.toString()
|
|
4017
|
+
});
|
|
3854
4018
|
} catch (_) {
|
|
3855
4019
|
}
|
|
3856
4020
|
if (existing) {
|
|
@@ -3898,6 +4062,7 @@ function useAreaChecklistService() {
|
|
|
3898
4062
|
);
|
|
3899
4063
|
await insertAutoGenSets(
|
|
3900
4064
|
value.schedule.toString(),
|
|
4065
|
+
serviceType,
|
|
3901
4066
|
area._id.toString(),
|
|
3902
4067
|
autoGenSets
|
|
3903
4068
|
);
|
|
@@ -3906,6 +4071,7 @@ function useAreaChecklistService() {
|
|
|
3906
4071
|
const setCount = Number(area.set) || 1;
|
|
3907
4072
|
const checklistData = {
|
|
3908
4073
|
schedule: value.schedule,
|
|
4074
|
+
serviceType,
|
|
3909
4075
|
area: area._id.toString(),
|
|
3910
4076
|
name: area.name,
|
|
3911
4077
|
type: area.type,
|
|
@@ -4036,7 +4202,11 @@ function useAreaChecklistService() {
|
|
|
4036
4202
|
|
|
4037
4203
|
// src/controllers/hygiene-area-checklist.controller.ts
|
|
4038
4204
|
import Joi9 from "joi";
|
|
4039
|
-
import {
|
|
4205
|
+
import {
|
|
4206
|
+
BadRequestError as BadRequestError16,
|
|
4207
|
+
InternalServerError as InternalServerError7,
|
|
4208
|
+
logger as logger20
|
|
4209
|
+
} from "@7365admin1/node-server-utils";
|
|
4040
4210
|
|
|
4041
4211
|
// src/services/hygiene-checklist-pdf.service.ts
|
|
4042
4212
|
import { launch } from "puppeteer";
|
|
@@ -4305,7 +4475,8 @@ function useAreaChecklistController() {
|
|
|
4305
4475
|
search: Joi9.string().optional().allow("", null),
|
|
4306
4476
|
type: Joi9.string().valid(...allowedTypes, "all").optional().allow("", null),
|
|
4307
4477
|
status: Joi9.string().valid(...allowedStatus, "all").optional().allow("", null),
|
|
4308
|
-
schedule: Joi9.string().hex().required()
|
|
4478
|
+
schedule: Joi9.string().hex().required(),
|
|
4479
|
+
serviceType: Joi9.string().valid(...Object.values(ServiceType)).required()
|
|
4309
4480
|
});
|
|
4310
4481
|
const { error } = validation.validate(query);
|
|
4311
4482
|
if (error) {
|
|
@@ -4319,6 +4490,7 @@ function useAreaChecklistController() {
|
|
|
4319
4490
|
const type = req.query.type ?? "all";
|
|
4320
4491
|
const status = req.query.status ?? "all";
|
|
4321
4492
|
const schedule = req.params.schedule ?? "";
|
|
4493
|
+
const serviceType = req.query.serviceType ?? "";
|
|
4322
4494
|
try {
|
|
4323
4495
|
const data = await _getAllAreaChecklist({
|
|
4324
4496
|
page,
|
|
@@ -4326,7 +4498,8 @@ function useAreaChecklistController() {
|
|
|
4326
4498
|
search,
|
|
4327
4499
|
type,
|
|
4328
4500
|
status,
|
|
4329
|
-
schedule
|
|
4501
|
+
schedule,
|
|
4502
|
+
serviceType
|
|
4330
4503
|
});
|
|
4331
4504
|
res.json(data);
|
|
4332
4505
|
return;
|
|
@@ -4403,6 +4576,7 @@ function useAreaChecklistController() {
|
|
|
4403
4576
|
page: Joi9.number().min(1).optional().allow("", null),
|
|
4404
4577
|
limit: Joi9.number().min(1).optional().allow("", null),
|
|
4405
4578
|
search: Joi9.string().optional().allow("", null),
|
|
4579
|
+
serviceType: Joi9.string().valid(...Object.values(ServiceType)).required(),
|
|
4406
4580
|
id: Joi9.string().hex().required()
|
|
4407
4581
|
});
|
|
4408
4582
|
const { error } = validation.validate(query);
|
|
@@ -4414,12 +4588,14 @@ function useAreaChecklistController() {
|
|
|
4414
4588
|
const page = parseInt(req.query.page) ?? 1;
|
|
4415
4589
|
const limit = parseInt(req.query.limit) ?? 10;
|
|
4416
4590
|
const search = req.query.search ?? "";
|
|
4591
|
+
const serviceType = req.query.serviceType ?? "";
|
|
4417
4592
|
const _id = req.params.id ?? "";
|
|
4418
4593
|
try {
|
|
4419
4594
|
const data = await _getAreaChecklistUnits({
|
|
4420
4595
|
page,
|
|
4421
4596
|
limit,
|
|
4422
4597
|
search,
|
|
4598
|
+
serviceType,
|
|
4423
4599
|
_id
|
|
4424
4600
|
});
|
|
4425
4601
|
res.json(data);
|
|
@@ -4491,12 +4667,15 @@ function useAreaChecklistController() {
|
|
|
4491
4667
|
try {
|
|
4492
4668
|
const pdfBuffer = await _generateChecklistPdf(value);
|
|
4493
4669
|
if (!pdfBuffer || pdfBuffer.length === 0) {
|
|
4494
|
-
throw new InternalServerError7(
|
|
4670
|
+
throw new InternalServerError7(
|
|
4671
|
+
"Generated checklist PDF is empty or invalid."
|
|
4672
|
+
);
|
|
4495
4673
|
}
|
|
4496
4674
|
const date = /* @__PURE__ */ new Date();
|
|
4497
|
-
const formattedDate = `${String(date.getDate()).padStart(
|
|
4498
|
-
|
|
4499
|
-
|
|
4675
|
+
const formattedDate = `${String(date.getDate()).padStart(
|
|
4676
|
+
2,
|
|
4677
|
+
"0"
|
|
4678
|
+
)}_${String(date.getMonth() + 1).padStart(2, "0")}_${date.getFullYear()}`;
|
|
4500
4679
|
res.setHeader("Content-Type", "application/pdf");
|
|
4501
4680
|
res.setHeader(
|
|
4502
4681
|
"Content-Disposition",
|
|
@@ -5796,6 +5975,7 @@ import Joi16 from "joi";
|
|
|
5796
5975
|
import { ObjectId as ObjectId18 } from "mongodb";
|
|
5797
5976
|
var scheduleTaskSchema = Joi16.object({
|
|
5798
5977
|
site: Joi16.string().hex().required(),
|
|
5978
|
+
serviceType: Joi16.string().valid(...Object.values(ServiceType)).required(),
|
|
5799
5979
|
title: Joi16.string().required(),
|
|
5800
5980
|
time: Joi16.string().pattern(/^([0-1]\d|2[0-3]):([0-5]\d)$/).required(),
|
|
5801
5981
|
dates: Joi16.array().min(1).items(
|
|
@@ -5844,6 +6024,7 @@ function MScheduleTask(value) {
|
|
|
5844
6024
|
}
|
|
5845
6025
|
return {
|
|
5846
6026
|
site: value.site,
|
|
6027
|
+
serviceType: value.serviceType,
|
|
5847
6028
|
title: value.title,
|
|
5848
6029
|
time: value.time,
|
|
5849
6030
|
dates: value.dates,
|
|
@@ -5881,6 +6062,7 @@ function useScheduleTaskRepository() {
|
|
|
5881
6062
|
try {
|
|
5882
6063
|
await collection.createIndexes([
|
|
5883
6064
|
{ key: { site: 1 } },
|
|
6065
|
+
{ key: { serviceType: 1 } },
|
|
5884
6066
|
{ key: { status: 1 } }
|
|
5885
6067
|
]);
|
|
5886
6068
|
} catch (error) {
|
|
@@ -5919,15 +6101,18 @@ function useScheduleTaskRepository() {
|
|
|
5919
6101
|
page = 1,
|
|
5920
6102
|
limit = 10,
|
|
5921
6103
|
search = "",
|
|
5922
|
-
site
|
|
6104
|
+
site,
|
|
6105
|
+
serviceType
|
|
5923
6106
|
}) {
|
|
5924
6107
|
page = page > 0 ? page - 1 : 0;
|
|
5925
6108
|
const query = {
|
|
5926
|
-
status: { $ne: "deleted" }
|
|
6109
|
+
status: { $ne: "deleted" },
|
|
6110
|
+
serviceType
|
|
5927
6111
|
};
|
|
5928
6112
|
const cacheOptions = {
|
|
5929
6113
|
page,
|
|
5930
|
-
limit
|
|
6114
|
+
limit,
|
|
6115
|
+
serviceType
|
|
5931
6116
|
};
|
|
5932
6117
|
try {
|
|
5933
6118
|
site = new ObjectId19(site);
|
|
@@ -5983,62 +6168,6 @@ function useScheduleTaskRepository() {
|
|
|
5983
6168
|
throw error;
|
|
5984
6169
|
}
|
|
5985
6170
|
}
|
|
5986
|
-
async function getTasksForScheduleTask({
|
|
5987
|
-
page = 1,
|
|
5988
|
-
limit = 10,
|
|
5989
|
-
search = "",
|
|
5990
|
-
site
|
|
5991
|
-
}) {
|
|
5992
|
-
page = page > 0 ? page - 1 : 0;
|
|
5993
|
-
const query = {
|
|
5994
|
-
status: { $ne: "deleted" }
|
|
5995
|
-
};
|
|
5996
|
-
const cacheOptions = {
|
|
5997
|
-
page,
|
|
5998
|
-
limit
|
|
5999
|
-
};
|
|
6000
|
-
try {
|
|
6001
|
-
site = new ObjectId19(site);
|
|
6002
|
-
query.site = site;
|
|
6003
|
-
cacheOptions.site = site.toString();
|
|
6004
|
-
} catch (error) {
|
|
6005
|
-
throw new BadRequestError29("Invalid site ID format.");
|
|
6006
|
-
}
|
|
6007
|
-
if (search) {
|
|
6008
|
-
query.$or = [{ name: { $regex: search, $options: "i" } }];
|
|
6009
|
-
cacheOptions.search = search;
|
|
6010
|
-
}
|
|
6011
|
-
const cacheKey = makeCacheKey9(namespace_collection, cacheOptions);
|
|
6012
|
-
const cachedData = await getCache(cacheKey);
|
|
6013
|
-
if (cachedData) {
|
|
6014
|
-
logger31.info(`Cache hit for key: ${cacheKey}`);
|
|
6015
|
-
return cachedData;
|
|
6016
|
-
}
|
|
6017
|
-
try {
|
|
6018
|
-
const items = await collection.aggregate([
|
|
6019
|
-
{ $match: query },
|
|
6020
|
-
{
|
|
6021
|
-
$project: {
|
|
6022
|
-
createdAt: 1,
|
|
6023
|
-
title: 1
|
|
6024
|
-
}
|
|
6025
|
-
},
|
|
6026
|
-
{ $sort: { _id: -1 } },
|
|
6027
|
-
{ $skip: page * limit },
|
|
6028
|
-
{ $limit: limit }
|
|
6029
|
-
]).toArray();
|
|
6030
|
-
const length = await collection.countDocuments(query);
|
|
6031
|
-
const data = paginate8(items, page, limit, length);
|
|
6032
|
-
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
6033
|
-
logger31.info(`Cache set for key: ${cacheKey}`);
|
|
6034
|
-
}).catch((err) => {
|
|
6035
|
-
logger31.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
6036
|
-
});
|
|
6037
|
-
return data;
|
|
6038
|
-
} catch (error) {
|
|
6039
|
-
throw error;
|
|
6040
|
-
}
|
|
6041
|
-
}
|
|
6042
6171
|
async function getScheduleTaskById(_id, session) {
|
|
6043
6172
|
try {
|
|
6044
6173
|
_id = new ObjectId19(_id);
|
|
@@ -6138,7 +6267,6 @@ function useScheduleTaskRepository() {
|
|
|
6138
6267
|
createScheduleTask,
|
|
6139
6268
|
getScheduleTasks,
|
|
6140
6269
|
getAllScheduleTask,
|
|
6141
|
-
getTasksForScheduleTask,
|
|
6142
6270
|
getScheduleTaskById,
|
|
6143
6271
|
updateScheduleTask
|
|
6144
6272
|
};
|
|
@@ -6156,7 +6284,7 @@ function useScheduleTaskService() {
|
|
|
6156
6284
|
pushScheduleTaskSets
|
|
6157
6285
|
} = useAreaChecklistRepo();
|
|
6158
6286
|
const { getAreaById } = useAreaRepo();
|
|
6159
|
-
function checkScheduleConditions(schedule, currentDate = /* @__PURE__ */ new Date()) {
|
|
6287
|
+
function checkScheduleConditions(schedule, serviceType, currentDate = /* @__PURE__ */ new Date()) {
|
|
6160
6288
|
try {
|
|
6161
6289
|
const now = currentDate;
|
|
6162
6290
|
const timeString = now.toLocaleTimeString("en-US", {
|
|
@@ -6247,12 +6375,17 @@ function useScheduleTaskService() {
|
|
|
6247
6375
|
const validatedTasks = [];
|
|
6248
6376
|
for (const scheduleTask of scheduleTasks) {
|
|
6249
6377
|
try {
|
|
6378
|
+
const serviceType = scheduleTask.serviceType;
|
|
6250
6379
|
logger32.info(
|
|
6251
6380
|
`Checking schedule ${scheduleTask._id} - ${scheduleTask.title}: time=${scheduleTask.time}, dates=${JSON.stringify(
|
|
6252
6381
|
scheduleTask.dates
|
|
6253
6382
|
)}`
|
|
6254
6383
|
);
|
|
6255
|
-
const shouldRun = checkScheduleConditions(
|
|
6384
|
+
const shouldRun = checkScheduleConditions(
|
|
6385
|
+
scheduleTask,
|
|
6386
|
+
serviceType,
|
|
6387
|
+
currentDate
|
|
6388
|
+
);
|
|
6256
6389
|
if (!shouldRun) {
|
|
6257
6390
|
logger32.info(
|
|
6258
6391
|
`Schedule ${scheduleTask._id} conditions not met, skipping`
|
|
@@ -6275,6 +6408,7 @@ function useScheduleTaskService() {
|
|
|
6275
6408
|
);
|
|
6276
6409
|
const parentChecklistIds = await createParentChecklist({
|
|
6277
6410
|
site: scheduleTask.site.toString(),
|
|
6411
|
+
serviceType,
|
|
6278
6412
|
createdAt: /* @__PURE__ */ new Date()
|
|
6279
6413
|
});
|
|
6280
6414
|
const parentChecklistId = Array.isArray(parentChecklistIds) ? parentChecklistIds[0] : parentChecklistIds;
|
|
@@ -6312,8 +6446,11 @@ function useScheduleTaskService() {
|
|
|
6312
6446
|
let existingAreaChecklist;
|
|
6313
6447
|
try {
|
|
6314
6448
|
existingAreaChecklist = await getAreaChecklistByAreaAndSchedule(
|
|
6315
|
-
|
|
6316
|
-
|
|
6449
|
+
{
|
|
6450
|
+
schedule: parentChecklistId.toString(),
|
|
6451
|
+
serviceType,
|
|
6452
|
+
area: areaId
|
|
6453
|
+
}
|
|
6317
6454
|
);
|
|
6318
6455
|
logger32.info(
|
|
6319
6456
|
`Area ${area.name} (${areaId}): Existing area checklist found: ${existingAreaChecklist ? "Yes" : "No"}`
|
|
@@ -6350,6 +6487,7 @@ function useScheduleTaskService() {
|
|
|
6350
6487
|
);
|
|
6351
6488
|
const modified = await pushScheduleTaskSets(
|
|
6352
6489
|
parentChecklistId.toString(),
|
|
6490
|
+
serviceType,
|
|
6353
6491
|
areaId,
|
|
6354
6492
|
scheduleTask._id.toString(),
|
|
6355
6493
|
newSets
|
|
@@ -6377,6 +6515,7 @@ function useScheduleTaskService() {
|
|
|
6377
6515
|
);
|
|
6378
6516
|
const checklistData = {
|
|
6379
6517
|
schedule: parentChecklistId.toString(),
|
|
6518
|
+
serviceType,
|
|
6380
6519
|
area: areaId,
|
|
6381
6520
|
name: area.name,
|
|
6382
6521
|
type: areaDetails.type || "common",
|
|
@@ -6431,7 +6570,6 @@ function useScheduleTaskController() {
|
|
|
6431
6570
|
const {
|
|
6432
6571
|
createScheduleTask: _createScheduleTask,
|
|
6433
6572
|
getScheduleTasks: _getScheduleTasks,
|
|
6434
|
-
getTasksForScheduleTask: _getTasksForScheduleTask,
|
|
6435
6573
|
getScheduleTaskById: _getScheduleTaskById,
|
|
6436
6574
|
updateScheduleTask: _updateScheduleTask
|
|
6437
6575
|
} = useScheduleTaskRepository();
|
|
@@ -6464,7 +6602,8 @@ function useScheduleTaskController() {
|
|
|
6464
6602
|
page: Joi17.number().min(1).optional().allow("", null),
|
|
6465
6603
|
limit: Joi17.number().min(1).optional().allow("", null),
|
|
6466
6604
|
search: Joi17.string().optional().allow("", null),
|
|
6467
|
-
site: Joi17.string().hex().required()
|
|
6605
|
+
site: Joi17.string().hex().required(),
|
|
6606
|
+
serviceType: Joi17.string().valid(...Object.values(ServiceType)).required()
|
|
6468
6607
|
});
|
|
6469
6608
|
const { error } = validation.validate(query);
|
|
6470
6609
|
if (error) {
|
|
@@ -6476,45 +6615,14 @@ function useScheduleTaskController() {
|
|
|
6476
6615
|
const limit = parseInt(req.query.limit) ?? 10;
|
|
6477
6616
|
const search = req.query.search ?? "";
|
|
6478
6617
|
const site = req.params.site ?? "";
|
|
6618
|
+
const serviceType = req.query.serviceType ?? "";
|
|
6479
6619
|
try {
|
|
6480
6620
|
const data = await _getScheduleTasks({
|
|
6481
6621
|
page,
|
|
6482
6622
|
limit,
|
|
6483
6623
|
search,
|
|
6484
|
-
site
|
|
6485
|
-
|
|
6486
|
-
res.json(data);
|
|
6487
|
-
return;
|
|
6488
|
-
} catch (error2) {
|
|
6489
|
-
logger33.log({ level: "error", message: error2.message });
|
|
6490
|
-
next(error2);
|
|
6491
|
-
return;
|
|
6492
|
-
}
|
|
6493
|
-
}
|
|
6494
|
-
async function getTasksForScheduleTask(req, res, next) {
|
|
6495
|
-
const query = { ...req.query, ...req.params };
|
|
6496
|
-
const validation = Joi17.object({
|
|
6497
|
-
page: Joi17.number().min(1).optional().allow("", null),
|
|
6498
|
-
limit: Joi17.number().min(1).optional().allow("", null),
|
|
6499
|
-
search: Joi17.string().optional().allow("", null),
|
|
6500
|
-
site: Joi17.string().hex().required()
|
|
6501
|
-
});
|
|
6502
|
-
const { error } = validation.validate(query);
|
|
6503
|
-
if (error) {
|
|
6504
|
-
logger33.log({ level: "error", message: error.message });
|
|
6505
|
-
next(new BadRequestError30(error.message));
|
|
6506
|
-
return;
|
|
6507
|
-
}
|
|
6508
|
-
const page = parseInt(req.query.page) ?? 1;
|
|
6509
|
-
const limit = parseInt(req.query.limit) ?? 10;
|
|
6510
|
-
const search = req.query.search ?? "";
|
|
6511
|
-
const site = req.params.site ?? "";
|
|
6512
|
-
try {
|
|
6513
|
-
const data = await _getTasksForScheduleTask({
|
|
6514
|
-
page,
|
|
6515
|
-
limit,
|
|
6516
|
-
search,
|
|
6517
|
-
site
|
|
6624
|
+
site,
|
|
6625
|
+
serviceType
|
|
6518
6626
|
});
|
|
6519
6627
|
res.json(data);
|
|
6520
6628
|
return;
|
|
@@ -6580,7 +6688,6 @@ function useScheduleTaskController() {
|
|
|
6580
6688
|
return {
|
|
6581
6689
|
createScheduleTask,
|
|
6582
6690
|
getScheduleTasks,
|
|
6583
|
-
getTasksForScheduleTask,
|
|
6584
6691
|
getScheduleTaskById,
|
|
6585
6692
|
updateScheduleTask
|
|
6586
6693
|
};
|
|
@@ -6872,6 +6979,7 @@ export {
|
|
|
6872
6979
|
MStock,
|
|
6873
6980
|
MSupply,
|
|
6874
6981
|
MUnit,
|
|
6982
|
+
ServiceType,
|
|
6875
6983
|
allowedCheckOutItemStatus,
|
|
6876
6984
|
allowedChecklistStatus,
|
|
6877
6985
|
allowedPeriods,
|