@7365admin1/module-hygiene 4.3.0 → 4.5.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 +43 -1
- package/dist/index.js +1235 -705
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1076 -550
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -3
package/dist/index.js
CHANGED
|
@@ -55,6 +55,7 @@ __export(src_exports, {
|
|
|
55
55
|
useAreaChecklistRepo: () => useAreaChecklistRepo,
|
|
56
56
|
useAreaChecklistService: () => useAreaChecklistService,
|
|
57
57
|
useAreaController: () => useAreaController,
|
|
58
|
+
useAreaExportService: () => useAreaExportService,
|
|
58
59
|
useAreaRepo: () => useAreaRepo,
|
|
59
60
|
useAreaService: () => useAreaService,
|
|
60
61
|
useCheckOutItemController: () => useCheckOutItemController,
|
|
@@ -64,6 +65,8 @@ __export(src_exports, {
|
|
|
64
65
|
useHygieneDashboardRepository: () => useHygieneDashboardRepository,
|
|
65
66
|
useParentChecklistController: () => useParentChecklistController,
|
|
66
67
|
useParentChecklistRepo: () => useParentChecklistRepo,
|
|
68
|
+
useQRController: () => useQRController,
|
|
69
|
+
useQRService: () => useQRService,
|
|
67
70
|
useScheduleTaskController: () => useScheduleTaskController,
|
|
68
71
|
useScheduleTaskRepository: () => useScheduleTaskRepository,
|
|
69
72
|
useScheduleTaskService: () => useScheduleTaskService,
|
|
@@ -73,6 +76,7 @@ __export(src_exports, {
|
|
|
73
76
|
useSupplyController: () => useSupplyController,
|
|
74
77
|
useSupplyRepository: () => useSupplyRepository,
|
|
75
78
|
useUnitController: () => useUnitController,
|
|
79
|
+
useUnitExportService: () => useUnitExportService,
|
|
76
80
|
useUnitRepository: () => useUnitRepository,
|
|
77
81
|
useUnitService: () => useUnitService
|
|
78
82
|
});
|
|
@@ -1077,9 +1081,283 @@ function useAreaRepo() {
|
|
|
1077
1081
|
}
|
|
1078
1082
|
|
|
1079
1083
|
// src/services/hygiene-area.service.ts
|
|
1084
|
+
var import_node_server_utils8 = require("@7365admin1/node-server-utils");
|
|
1085
|
+
|
|
1086
|
+
// src/services/hygiene-area-export.service.ts
|
|
1080
1087
|
var import_node_server_utils5 = require("@7365admin1/node-server-utils");
|
|
1088
|
+
var xlsx = __toESM(require("xlsx"));
|
|
1089
|
+
function useAreaExportService() {
|
|
1090
|
+
async function generateAreaExcel(areas) {
|
|
1091
|
+
try {
|
|
1092
|
+
const rows = [];
|
|
1093
|
+
rows.push(["AREA", "TYPE", "SET", "UNITS"]);
|
|
1094
|
+
for (const area of areas) {
|
|
1095
|
+
const areaName = area.name || "";
|
|
1096
|
+
const areaType = area.type || "";
|
|
1097
|
+
const areaSet = String(area.set || 0);
|
|
1098
|
+
const unitsString = area.units && area.units.length > 0 ? area.units.map((u) => u.name || "").join(", ") : "";
|
|
1099
|
+
rows.push([areaName, areaType, areaSet, unitsString]);
|
|
1100
|
+
}
|
|
1101
|
+
const workbook = xlsx.utils.book_new();
|
|
1102
|
+
const worksheet = xlsx.utils.aoa_to_sheet(rows);
|
|
1103
|
+
worksheet["!cols"] = [
|
|
1104
|
+
{ width: 30 },
|
|
1105
|
+
// AREA
|
|
1106
|
+
{ width: 20 },
|
|
1107
|
+
// TYPE
|
|
1108
|
+
{ width: 10 },
|
|
1109
|
+
// SET
|
|
1110
|
+
{ width: 40 }
|
|
1111
|
+
// UNITS
|
|
1112
|
+
];
|
|
1113
|
+
xlsx.utils.book_append_sheet(workbook, worksheet, "Areas");
|
|
1114
|
+
const excelBuffer = xlsx.write(workbook, {
|
|
1115
|
+
type: "buffer",
|
|
1116
|
+
bookType: "xlsx"
|
|
1117
|
+
});
|
|
1118
|
+
return excelBuffer;
|
|
1119
|
+
} catch (error) {
|
|
1120
|
+
import_node_server_utils5.logger.log({
|
|
1121
|
+
level: "error",
|
|
1122
|
+
message: `Failed to generate area Excel: ${error.message}`
|
|
1123
|
+
});
|
|
1124
|
+
throw error;
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
return {
|
|
1128
|
+
generateAreaExcel
|
|
1129
|
+
};
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
// src/repositories/hygiene-unit.repository.ts
|
|
1133
|
+
var import_mongodb5 = require("mongodb");
|
|
1134
|
+
var import_node_server_utils7 = require("@7365admin1/node-server-utils");
|
|
1135
|
+
|
|
1136
|
+
// src/models/hygiene-unit.model.ts
|
|
1137
|
+
var import_joi3 = __toESM(require("joi"));
|
|
1138
|
+
var import_mongodb4 = require("mongodb");
|
|
1139
|
+
var import_node_server_utils6 = require("@7365admin1/node-server-utils");
|
|
1140
|
+
var unitSchema = import_joi3.default.object({
|
|
1141
|
+
site: import_joi3.default.string().hex().required(),
|
|
1142
|
+
name: import_joi3.default.string().required()
|
|
1143
|
+
});
|
|
1144
|
+
function MUnit(value) {
|
|
1145
|
+
const { error } = unitSchema.validate(value);
|
|
1146
|
+
if (error) {
|
|
1147
|
+
import_node_server_utils6.logger.info(`Hygiene Unit Model: ${error.message}`);
|
|
1148
|
+
throw new import_node_server_utils6.BadRequestError(error.message);
|
|
1149
|
+
}
|
|
1150
|
+
if (value.site) {
|
|
1151
|
+
try {
|
|
1152
|
+
value.site = new import_mongodb4.ObjectId(value.site);
|
|
1153
|
+
} catch (error2) {
|
|
1154
|
+
throw new import_node_server_utils6.BadRequestError("Invalid site ID format.");
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
return {
|
|
1158
|
+
site: value.site,
|
|
1159
|
+
name: value.name,
|
|
1160
|
+
status: "active",
|
|
1161
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
1162
|
+
updatedAt: "",
|
|
1163
|
+
deletedAt: ""
|
|
1164
|
+
};
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
// src/repositories/hygiene-unit.repository.ts
|
|
1168
|
+
function useUnitRepository() {
|
|
1169
|
+
const db = import_node_server_utils7.useAtlas.getDb();
|
|
1170
|
+
if (!db) {
|
|
1171
|
+
throw new import_node_server_utils7.InternalServerError("Unable to connect to server.");
|
|
1172
|
+
}
|
|
1173
|
+
const namespace_collection = "site.cleaning.area.unit";
|
|
1174
|
+
const collection = db.collection(namespace_collection);
|
|
1175
|
+
const { delNamespace, setCache, getCache } = (0, import_node_server_utils7.useCache)(namespace_collection);
|
|
1176
|
+
async function createIndex() {
|
|
1177
|
+
try {
|
|
1178
|
+
await collection.createIndexes([
|
|
1179
|
+
{ key: { site: 1 } },
|
|
1180
|
+
{ key: { status: 1 } }
|
|
1181
|
+
]);
|
|
1182
|
+
} catch (error) {
|
|
1183
|
+
throw new import_node_server_utils7.InternalServerError("Failed to create index on hygiene unit.");
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
async function createTextIndex() {
|
|
1187
|
+
try {
|
|
1188
|
+
await collection.createIndex({ name: "text" });
|
|
1189
|
+
} catch (error) {
|
|
1190
|
+
throw new import_node_server_utils7.InternalServerError(
|
|
1191
|
+
"Failed to create text index on hygiene unit."
|
|
1192
|
+
);
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
async function createUniqueIndex() {
|
|
1196
|
+
try {
|
|
1197
|
+
await collection.createIndex(
|
|
1198
|
+
{ site: 1, name: 1, deletedAt: 1 },
|
|
1199
|
+
{ unique: true }
|
|
1200
|
+
);
|
|
1201
|
+
} catch (error) {
|
|
1202
|
+
throw new import_node_server_utils7.InternalServerError(
|
|
1203
|
+
"Failed to create unique index on hygiene unit."
|
|
1204
|
+
);
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
async function createUnit(value, session) {
|
|
1208
|
+
try {
|
|
1209
|
+
value = MUnit(value);
|
|
1210
|
+
const res = await collection.insertOne(value, { session });
|
|
1211
|
+
delNamespace().then(() => {
|
|
1212
|
+
import_node_server_utils7.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
1213
|
+
}).catch((err) => {
|
|
1214
|
+
import_node_server_utils7.logger.error(
|
|
1215
|
+
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
1216
|
+
err
|
|
1217
|
+
);
|
|
1218
|
+
});
|
|
1219
|
+
return res.insertedId;
|
|
1220
|
+
} catch (error) {
|
|
1221
|
+
const isDuplicated = error.message.includes("duplicate");
|
|
1222
|
+
if (isDuplicated) {
|
|
1223
|
+
throw new import_node_server_utils7.BadRequestError("Unit already exists.");
|
|
1224
|
+
}
|
|
1225
|
+
throw error;
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
async function getUnits({
|
|
1229
|
+
page = 1,
|
|
1230
|
+
limit = 10,
|
|
1231
|
+
search = "",
|
|
1232
|
+
site
|
|
1233
|
+
}) {
|
|
1234
|
+
page = page > 0 ? page - 1 : 0;
|
|
1235
|
+
const query = {
|
|
1236
|
+
status: { $ne: "deleted" }
|
|
1237
|
+
};
|
|
1238
|
+
const cacheOptions = {
|
|
1239
|
+
page,
|
|
1240
|
+
limit
|
|
1241
|
+
};
|
|
1242
|
+
try {
|
|
1243
|
+
site = new import_mongodb5.ObjectId(site);
|
|
1244
|
+
query.site = site;
|
|
1245
|
+
cacheOptions.site = site.toString();
|
|
1246
|
+
} catch (error) {
|
|
1247
|
+
throw new import_node_server_utils7.BadRequestError("Invalid site ID format.");
|
|
1248
|
+
}
|
|
1249
|
+
if (search) {
|
|
1250
|
+
query.$or = [{ name: { $regex: search, $options: "i" } }];
|
|
1251
|
+
cacheOptions.search = search;
|
|
1252
|
+
}
|
|
1253
|
+
const cacheKey = (0, import_node_server_utils7.makeCacheKey)(namespace_collection, cacheOptions);
|
|
1254
|
+
const cachedData = await getCache(cacheKey);
|
|
1255
|
+
if (cachedData) {
|
|
1256
|
+
import_node_server_utils7.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
1257
|
+
return cachedData;
|
|
1258
|
+
}
|
|
1259
|
+
try {
|
|
1260
|
+
const items = await collection.aggregate([
|
|
1261
|
+
{ $match: query },
|
|
1262
|
+
{ $project: { name: 1 } },
|
|
1263
|
+
{ $sort: { _id: -1 } },
|
|
1264
|
+
{ $skip: page * limit },
|
|
1265
|
+
{ $limit: limit }
|
|
1266
|
+
]).toArray();
|
|
1267
|
+
const length = await collection.countDocuments(query);
|
|
1268
|
+
const data = (0, import_node_server_utils7.paginate)(items, page, limit, length);
|
|
1269
|
+
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
1270
|
+
import_node_server_utils7.logger.info(`Cache set for key: ${cacheKey}`);
|
|
1271
|
+
}).catch((err) => {
|
|
1272
|
+
import_node_server_utils7.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
1273
|
+
});
|
|
1274
|
+
return data;
|
|
1275
|
+
} catch (error) {
|
|
1276
|
+
throw error;
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
async function updateUnit(_id, value, session) {
|
|
1280
|
+
try {
|
|
1281
|
+
_id = new import_mongodb5.ObjectId(_id);
|
|
1282
|
+
} catch (error) {
|
|
1283
|
+
throw new import_node_server_utils7.BadRequestError("Invalid unit ID format.");
|
|
1284
|
+
}
|
|
1285
|
+
try {
|
|
1286
|
+
const updateValue = { ...value, updatedAt: /* @__PURE__ */ new Date() };
|
|
1287
|
+
const res = await collection.updateOne(
|
|
1288
|
+
{ _id },
|
|
1289
|
+
{ $set: updateValue },
|
|
1290
|
+
{ session }
|
|
1291
|
+
);
|
|
1292
|
+
if (res.modifiedCount === 0) {
|
|
1293
|
+
throw new import_node_server_utils7.InternalServerError("Unable to update cleaning unit.");
|
|
1294
|
+
}
|
|
1295
|
+
delNamespace().then(() => {
|
|
1296
|
+
import_node_server_utils7.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
1297
|
+
}).catch((err) => {
|
|
1298
|
+
import_node_server_utils7.logger.error(
|
|
1299
|
+
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
1300
|
+
err
|
|
1301
|
+
);
|
|
1302
|
+
});
|
|
1303
|
+
return res.modifiedCount;
|
|
1304
|
+
} catch (error) {
|
|
1305
|
+
const isDuplicated = error.message.includes("duplicate");
|
|
1306
|
+
if (isDuplicated) {
|
|
1307
|
+
throw new import_node_server_utils7.BadRequestError("Area already exists.");
|
|
1308
|
+
}
|
|
1309
|
+
throw error;
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
async function deleteUnit(_id, session) {
|
|
1313
|
+
try {
|
|
1314
|
+
_id = new import_mongodb5.ObjectId(_id);
|
|
1315
|
+
} catch (error) {
|
|
1316
|
+
throw new import_node_server_utils7.BadRequestError("Invalid unit ID format.");
|
|
1317
|
+
}
|
|
1318
|
+
try {
|
|
1319
|
+
const updateValue = {
|
|
1320
|
+
status: "deleted",
|
|
1321
|
+
updatedAt: /* @__PURE__ */ new Date(),
|
|
1322
|
+
deletedAt: /* @__PURE__ */ new Date()
|
|
1323
|
+
};
|
|
1324
|
+
const res = await collection.updateOne(
|
|
1325
|
+
{ _id },
|
|
1326
|
+
{ $set: updateValue },
|
|
1327
|
+
{ session }
|
|
1328
|
+
);
|
|
1329
|
+
if (res.modifiedCount === 0) {
|
|
1330
|
+
throw new import_node_server_utils7.InternalServerError("Unable to delete unit.");
|
|
1331
|
+
}
|
|
1332
|
+
delNamespace().then(() => {
|
|
1333
|
+
import_node_server_utils7.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
1334
|
+
}).catch((err) => {
|
|
1335
|
+
import_node_server_utils7.logger.error(
|
|
1336
|
+
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
1337
|
+
err
|
|
1338
|
+
);
|
|
1339
|
+
});
|
|
1340
|
+
return res.modifiedCount;
|
|
1341
|
+
} catch (error) {
|
|
1342
|
+
throw error;
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
return {
|
|
1346
|
+
createIndex,
|
|
1347
|
+
createTextIndex,
|
|
1348
|
+
createUniqueIndex,
|
|
1349
|
+
createUnit,
|
|
1350
|
+
getUnits,
|
|
1351
|
+
updateUnit,
|
|
1352
|
+
deleteUnit
|
|
1353
|
+
};
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
// src/services/hygiene-area.service.ts
|
|
1081
1357
|
function useAreaService() {
|
|
1082
|
-
const { createArea: _createArea } = useAreaRepo();
|
|
1358
|
+
const { createArea: _createArea, getAreasForChecklist } = useAreaRepo();
|
|
1359
|
+
const { generateAreaExcel } = useAreaExportService();
|
|
1360
|
+
const { getUnits: _getUnits } = useUnitRepository();
|
|
1083
1361
|
async function importArea({
|
|
1084
1362
|
dataJson,
|
|
1085
1363
|
site
|
|
@@ -1088,10 +1366,24 @@ function useAreaService() {
|
|
|
1088
1366
|
try {
|
|
1089
1367
|
dataArray = JSON.parse(dataJson);
|
|
1090
1368
|
} catch (error) {
|
|
1091
|
-
throw new
|
|
1369
|
+
throw new import_node_server_utils8.BadRequestError("Invalid JSON format for data in excel");
|
|
1092
1370
|
}
|
|
1093
1371
|
if (!dataArray || dataArray.length === 0) {
|
|
1094
|
-
throw new
|
|
1372
|
+
throw new import_node_server_utils8.NotFoundError("No data found in the uploaded file");
|
|
1373
|
+
}
|
|
1374
|
+
let availableUnits = [];
|
|
1375
|
+
try {
|
|
1376
|
+
const unitsData = await _getUnits({
|
|
1377
|
+
page: 1,
|
|
1378
|
+
limit: 999999,
|
|
1379
|
+
search: "",
|
|
1380
|
+
site
|
|
1381
|
+
});
|
|
1382
|
+
if (unitsData && unitsData.items) {
|
|
1383
|
+
availableUnits = unitsData.items;
|
|
1384
|
+
}
|
|
1385
|
+
} catch (error) {
|
|
1386
|
+
import_node_server_utils8.logger.warn(`Failed to fetch units for site: ${error}`);
|
|
1095
1387
|
}
|
|
1096
1388
|
const insertedAreaIds = [];
|
|
1097
1389
|
const duplicateAreas = [];
|
|
@@ -1101,37 +1393,74 @@ function useAreaService() {
|
|
|
1101
1393
|
for (let i = 0; i < dataArray.length; i++) {
|
|
1102
1394
|
const row = dataArray[i];
|
|
1103
1395
|
if (!row?.TYPE) {
|
|
1104
|
-
|
|
1396
|
+
import_node_server_utils8.logger.warn(`Skipping row ${i + 1} with missing TYPE:`, row);
|
|
1105
1397
|
skippedRows.push(i + 1);
|
|
1106
1398
|
continue;
|
|
1107
1399
|
}
|
|
1108
1400
|
const areaType = String(row.TYPE).trim().toLowerCase();
|
|
1109
1401
|
if (!areaType) {
|
|
1110
|
-
|
|
1402
|
+
import_node_server_utils8.logger.warn(`Skipping row ${i + 1} with empty area type`);
|
|
1111
1403
|
skippedRows.push(i + 1);
|
|
1112
1404
|
continue;
|
|
1113
1405
|
}
|
|
1114
|
-
|
|
1115
|
-
|
|
1406
|
+
const areaNameValue = row?.NAME || row?.AREA;
|
|
1407
|
+
if (!areaNameValue) {
|
|
1408
|
+
import_node_server_utils8.logger.warn(`Skipping row ${i + 1} with missing NAME/AREA:`, row);
|
|
1116
1409
|
skippedRows.push(i + 1);
|
|
1117
1410
|
continue;
|
|
1118
1411
|
}
|
|
1119
|
-
const areaName = String(
|
|
1412
|
+
const areaName = String(areaNameValue).trim();
|
|
1120
1413
|
if (!areaName) {
|
|
1121
|
-
|
|
1414
|
+
import_node_server_utils8.logger.warn(`Skipping row ${i + 1} with empty ${areaType} area name`);
|
|
1415
|
+
skippedRows.push(i + 1);
|
|
1416
|
+
continue;
|
|
1417
|
+
}
|
|
1418
|
+
if (areaName.startsWith("Sample:")) {
|
|
1419
|
+
import_node_server_utils8.logger.warn(`Skipping row ${i + 1} with sample area: ${areaName}`);
|
|
1122
1420
|
skippedRows.push(i + 1);
|
|
1123
1421
|
continue;
|
|
1124
1422
|
}
|
|
1125
1423
|
try {
|
|
1126
|
-
const
|
|
1424
|
+
const areaData = {
|
|
1127
1425
|
type: areaType,
|
|
1128
1426
|
name: areaName,
|
|
1129
1427
|
site
|
|
1130
|
-
}
|
|
1428
|
+
};
|
|
1429
|
+
if (row.SET !== void 0 && row.SET !== null && row.SET !== "") {
|
|
1430
|
+
const setNumber = parseInt(String(row.SET).trim());
|
|
1431
|
+
if (!isNaN(setNumber) && setNumber >= 0) {
|
|
1432
|
+
areaData.set = setNumber;
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
if (row.UNITS && availableUnits.length > 0) {
|
|
1436
|
+
const unitNames = String(row.UNITS).split(",").map((u) => u.trim()).filter((u) => u);
|
|
1437
|
+
if (unitNames.length > 0) {
|
|
1438
|
+
const areaUnits = [];
|
|
1439
|
+
for (const unitName of unitNames) {
|
|
1440
|
+
const foundUnit = availableUnits.find(
|
|
1441
|
+
(u) => u.name.toLowerCase() === unitName.toLowerCase()
|
|
1442
|
+
);
|
|
1443
|
+
if (foundUnit) {
|
|
1444
|
+
areaUnits.push({
|
|
1445
|
+
unit: foundUnit._id,
|
|
1446
|
+
name: foundUnit.name
|
|
1447
|
+
});
|
|
1448
|
+
} else {
|
|
1449
|
+
import_node_server_utils8.logger.warn(
|
|
1450
|
+
`Unit "${unitName}" not found in site for area "${areaName}"`
|
|
1451
|
+
);
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1454
|
+
if (areaUnits.length > 0) {
|
|
1455
|
+
areaData.units = areaUnits;
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
const insertedId = await _createArea(areaData);
|
|
1131
1460
|
insertedAreaIds.push(insertedId);
|
|
1132
|
-
|
|
1461
|
+
import_node_server_utils8.logger.info(`Successfully created ${areaType} area: ${areaName}`);
|
|
1133
1462
|
} catch (error) {
|
|
1134
|
-
|
|
1463
|
+
import_node_server_utils8.logger.error(
|
|
1135
1464
|
`Error creating ${areaType} area "${areaName}": ${error.message}`
|
|
1136
1465
|
);
|
|
1137
1466
|
if (error.message.includes("duplicate")) {
|
|
@@ -1151,18 +1480,18 @@ function useAreaService() {
|
|
|
1151
1480
|
if (skippedRows.length > 0) {
|
|
1152
1481
|
message += `, ${skippedRows.length} rows skipped (invalid data)`;
|
|
1153
1482
|
}
|
|
1154
|
-
|
|
1483
|
+
import_node_server_utils8.logger.info(message);
|
|
1155
1484
|
if (insertedAreaIds.length === 0) {
|
|
1156
1485
|
if (duplicateAreas.length > 0 && failedAreas.length === 0 && skippedRows.length === 0) {
|
|
1157
1486
|
return {
|
|
1158
1487
|
message: `No new areas were created. All ${duplicateAreas.length} areas already exist in the system: ${duplicateAreas.join(", ")}`
|
|
1159
1488
|
};
|
|
1160
1489
|
} else if (failedAreas.length > 0) {
|
|
1161
|
-
throw new
|
|
1490
|
+
throw new import_node_server_utils8.BadRequestError(
|
|
1162
1491
|
`No areas were created. ${failedAreas.length} areas failed due to errors. Please check your data format and ensure area names are valid.`
|
|
1163
1492
|
);
|
|
1164
1493
|
} else if (skippedRows.length > 0 && duplicateAreas.length === 0) {
|
|
1165
|
-
throw new
|
|
1494
|
+
throw new import_node_server_utils8.BadRequestError(
|
|
1166
1495
|
`No areas were created. All ${skippedRows.length} rows contained invalid or missing data.`
|
|
1167
1496
|
);
|
|
1168
1497
|
} else {
|
|
@@ -1173,30 +1502,46 @@ function useAreaService() {
|
|
|
1173
1502
|
}
|
|
1174
1503
|
return { message };
|
|
1175
1504
|
} catch (error) {
|
|
1176
|
-
|
|
1177
|
-
if (error instanceof
|
|
1505
|
+
import_node_server_utils8.logger.error("Error while uploading area information", error);
|
|
1506
|
+
if (error instanceof import_node_server_utils8.BadRequestError) {
|
|
1178
1507
|
throw error;
|
|
1179
1508
|
} else if (error.message.includes("validation")) {
|
|
1180
|
-
throw new
|
|
1509
|
+
throw new import_node_server_utils8.BadRequestError(
|
|
1181
1510
|
"Upload failed due to invalid data format. Please check that all required fields are properly filled."
|
|
1182
1511
|
);
|
|
1183
1512
|
} else {
|
|
1184
|
-
throw new
|
|
1513
|
+
throw new import_node_server_utils8.BadRequestError(
|
|
1185
1514
|
`Upload failed: ${error.message || "Please check your data format and try again."}`
|
|
1186
1515
|
);
|
|
1187
1516
|
}
|
|
1188
1517
|
}
|
|
1189
1518
|
}
|
|
1190
|
-
|
|
1519
|
+
async function exportAreas(site) {
|
|
1520
|
+
try {
|
|
1521
|
+
const areas = await getAreasForChecklist(site);
|
|
1522
|
+
if (!areas || !Array.isArray(areas) || areas.length === 0) {
|
|
1523
|
+
throw new import_node_server_utils8.BadRequestError("No data found to export");
|
|
1524
|
+
}
|
|
1525
|
+
const excelBuffer = await generateAreaExcel(areas);
|
|
1526
|
+
if (!excelBuffer || excelBuffer.length === 0) {
|
|
1527
|
+
throw new Error("Generated Excel file is empty or invalid.");
|
|
1528
|
+
}
|
|
1529
|
+
return excelBuffer;
|
|
1530
|
+
} catch (error) {
|
|
1531
|
+
import_node_server_utils8.logger.error(`Error downloading areas: ${error.message}`);
|
|
1532
|
+
throw error;
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
return { importArea, exportAreas };
|
|
1191
1536
|
}
|
|
1192
1537
|
|
|
1193
1538
|
// src/controllers/hygiene-area.controller.ts
|
|
1194
|
-
var
|
|
1195
|
-
var
|
|
1539
|
+
var import_joi4 = __toESM(require("joi"));
|
|
1540
|
+
var import_node_server_utils9 = require("@7365admin1/node-server-utils");
|
|
1196
1541
|
|
|
1197
1542
|
// src/utils/convert-excel.util.ts
|
|
1198
1543
|
var import_stream = require("stream");
|
|
1199
|
-
var
|
|
1544
|
+
var xlsx2 = __toESM(require("xlsx"));
|
|
1200
1545
|
function convertBufferFile(bufferFile) {
|
|
1201
1546
|
return new Promise((resolve, reject) => {
|
|
1202
1547
|
const fileStream = import_stream.Readable.from(bufferFile);
|
|
@@ -1206,10 +1551,10 @@ function convertBufferFile(bufferFile) {
|
|
|
1206
1551
|
});
|
|
1207
1552
|
fileStream.on("end", () => {
|
|
1208
1553
|
try {
|
|
1209
|
-
const workbook =
|
|
1554
|
+
const workbook = xlsx2.read(fileBuffer, { type: "buffer" });
|
|
1210
1555
|
const sheetName = workbook.SheetNames[0];
|
|
1211
1556
|
const sheet = workbook.Sheets[sheetName];
|
|
1212
|
-
const jsonData =
|
|
1557
|
+
const jsonData = xlsx2.utils.sheet_to_json(sheet);
|
|
1213
1558
|
resolve(jsonData);
|
|
1214
1559
|
} catch (error) {
|
|
1215
1560
|
reject("Error parsing file");
|
|
@@ -1230,13 +1575,13 @@ function useAreaController() {
|
|
|
1230
1575
|
updateArea: _updateArea,
|
|
1231
1576
|
deleteArea: _deleteById
|
|
1232
1577
|
} = useAreaRepo();
|
|
1233
|
-
const { importArea: _importArea } = useAreaService();
|
|
1578
|
+
const { importArea: _importArea, exportAreas: _exportAreas } = useAreaService();
|
|
1234
1579
|
async function createArea(req, res, next) {
|
|
1235
1580
|
const payload = { ...req.body, ...req.params };
|
|
1236
1581
|
const { error } = areaSchema.validate(payload);
|
|
1237
1582
|
if (error) {
|
|
1238
|
-
|
|
1239
|
-
next(new
|
|
1583
|
+
import_node_server_utils9.logger.log({ level: "error", message: error.message });
|
|
1584
|
+
next(new import_node_server_utils9.BadRequestError(error.message));
|
|
1240
1585
|
return;
|
|
1241
1586
|
}
|
|
1242
1587
|
try {
|
|
@@ -1244,24 +1589,24 @@ function useAreaController() {
|
|
|
1244
1589
|
res.status(201).json({ message: "Area created successfully.", id });
|
|
1245
1590
|
return;
|
|
1246
1591
|
} catch (error2) {
|
|
1247
|
-
|
|
1592
|
+
import_node_server_utils9.logger.log({ level: "error", message: error2.message });
|
|
1248
1593
|
next(error2);
|
|
1249
1594
|
return;
|
|
1250
1595
|
}
|
|
1251
1596
|
}
|
|
1252
1597
|
async function getAreas(req, res, next) {
|
|
1253
1598
|
const query = { ...req.query, ...req.params };
|
|
1254
|
-
const validation =
|
|
1255
|
-
page:
|
|
1256
|
-
limit:
|
|
1257
|
-
search:
|
|
1258
|
-
type:
|
|
1259
|
-
site:
|
|
1599
|
+
const validation = import_joi4.default.object({
|
|
1600
|
+
page: import_joi4.default.number().min(1).optional().allow("", null),
|
|
1601
|
+
limit: import_joi4.default.number().min(1).optional().allow("", null),
|
|
1602
|
+
search: import_joi4.default.string().optional().allow("", null),
|
|
1603
|
+
type: import_joi4.default.string().valid("all", ...allowedTypes).optional().allow("", null),
|
|
1604
|
+
site: import_joi4.default.string().hex().required()
|
|
1260
1605
|
});
|
|
1261
1606
|
const { error } = validation.validate(query);
|
|
1262
1607
|
if (error) {
|
|
1263
|
-
|
|
1264
|
-
next(new
|
|
1608
|
+
import_node_server_utils9.logger.log({ level: "error", message: error.message });
|
|
1609
|
+
next(new import_node_server_utils9.BadRequestError(error.message));
|
|
1265
1610
|
return;
|
|
1266
1611
|
}
|
|
1267
1612
|
const page = parseInt(req.query.page) ?? 1;
|
|
@@ -1285,12 +1630,12 @@ function useAreaController() {
|
|
|
1285
1630
|
}
|
|
1286
1631
|
}
|
|
1287
1632
|
async function getAreaById(req, res, next) {
|
|
1288
|
-
const validation =
|
|
1633
|
+
const validation = import_joi4.default.string().hex().required();
|
|
1289
1634
|
const _id = req.params.id;
|
|
1290
1635
|
const { error, value } = validation.validate(_id);
|
|
1291
1636
|
if (error) {
|
|
1292
|
-
|
|
1293
|
-
next(new
|
|
1637
|
+
import_node_server_utils9.logger.log({ level: "error", message: error.message });
|
|
1638
|
+
next(new import_node_server_utils9.BadRequestError(error.message));
|
|
1294
1639
|
return;
|
|
1295
1640
|
}
|
|
1296
1641
|
try {
|
|
@@ -1298,22 +1643,22 @@ function useAreaController() {
|
|
|
1298
1643
|
res.json(data);
|
|
1299
1644
|
return;
|
|
1300
1645
|
} catch (error2) {
|
|
1301
|
-
|
|
1646
|
+
import_node_server_utils9.logger.log({ level: "error", message: error2.message });
|
|
1302
1647
|
next(error2);
|
|
1303
1648
|
return;
|
|
1304
1649
|
}
|
|
1305
1650
|
}
|
|
1306
1651
|
async function updateArea(req, res, next) {
|
|
1307
1652
|
const payload = { id: req.params.id, ...req.body };
|
|
1308
|
-
const schema =
|
|
1309
|
-
id:
|
|
1310
|
-
name:
|
|
1311
|
-
type:
|
|
1312
|
-
set:
|
|
1313
|
-
units:
|
|
1314
|
-
|
|
1315
|
-
unit:
|
|
1316
|
-
name:
|
|
1653
|
+
const schema = import_joi4.default.object({
|
|
1654
|
+
id: import_joi4.default.string().hex().required(),
|
|
1655
|
+
name: import_joi4.default.string().optional().allow("", null),
|
|
1656
|
+
type: import_joi4.default.string().optional().allow("", null, ...allowedTypes),
|
|
1657
|
+
set: import_joi4.default.number().min(0).optional(),
|
|
1658
|
+
units: import_joi4.default.array().items(
|
|
1659
|
+
import_joi4.default.object({
|
|
1660
|
+
unit: import_joi4.default.string().hex().required(),
|
|
1661
|
+
name: import_joi4.default.string().required()
|
|
1317
1662
|
}).required()
|
|
1318
1663
|
).min(1).unique("unit", { ignoreUndefined: true }).optional().messages({
|
|
1319
1664
|
"array.unique": "Duplicate area units are not allowed"
|
|
@@ -1321,8 +1666,8 @@ function useAreaController() {
|
|
|
1321
1666
|
});
|
|
1322
1667
|
const { error } = schema.validate(payload);
|
|
1323
1668
|
if (error) {
|
|
1324
|
-
|
|
1325
|
-
next(new
|
|
1669
|
+
import_node_server_utils9.logger.log({ level: "error", message: error.message });
|
|
1670
|
+
next(new import_node_server_utils9.BadRequestError(error.message));
|
|
1326
1671
|
return;
|
|
1327
1672
|
}
|
|
1328
1673
|
try {
|
|
@@ -1331,286 +1676,135 @@ function useAreaController() {
|
|
|
1331
1676
|
res.json({ message: "Area updated successfully." });
|
|
1332
1677
|
return;
|
|
1333
1678
|
} catch (error2) {
|
|
1334
|
-
|
|
1679
|
+
import_node_server_utils9.logger.log({ level: "error", message: error2.message });
|
|
1335
1680
|
next(error2);
|
|
1336
1681
|
return;
|
|
1337
1682
|
}
|
|
1338
1683
|
}
|
|
1339
|
-
async function deleteArea(req, res, next) {
|
|
1340
|
-
const id = req.params.id;
|
|
1341
|
-
const validation =
|
|
1342
|
-
const { error, value } = validation.validate(id);
|
|
1343
|
-
if (error) {
|
|
1344
|
-
|
|
1345
|
-
next(new
|
|
1346
|
-
return;
|
|
1347
|
-
}
|
|
1348
|
-
try {
|
|
1349
|
-
await _deleteById(value);
|
|
1350
|
-
res.json({ message: "Area deleted successfully." });
|
|
1351
|
-
return;
|
|
1352
|
-
} catch (error2) {
|
|
1353
|
-
import_node_server_utils6.logger.log({ level: "error", message: error2.message });
|
|
1354
|
-
next(error2);
|
|
1355
|
-
return;
|
|
1356
|
-
}
|
|
1357
|
-
}
|
|
1358
|
-
async function importArea(req, res, next) {
|
|
1359
|
-
if (!req.file) {
|
|
1360
|
-
next(new import_node_server_utils6.BadRequestError("File is required!"));
|
|
1361
|
-
return;
|
|
1362
|
-
}
|
|
1363
|
-
const { site } = req.params;
|
|
1364
|
-
const schema = import_joi3.default.string().hex().required();
|
|
1365
|
-
const { error, value } = schema.validate(site);
|
|
1366
|
-
if (error) {
|
|
1367
|
-
import_node_server_utils6.logger.log({ level: "error", message: error.message });
|
|
1368
|
-
next(new import_node_server_utils6.BadRequestError(error.message));
|
|
1369
|
-
return;
|
|
1370
|
-
}
|
|
1371
|
-
try {
|
|
1372
|
-
const xlsData = await convertBufferFile(req.file.buffer);
|
|
1373
|
-
const dataJson = JSON.stringify(xlsData);
|
|
1374
|
-
const result = await _importArea({ dataJson, site: value });
|
|
1375
|
-
return res.status(201).json(result);
|
|
1376
|
-
} catch (error2) {
|
|
1377
|
-
import_node_server_utils6.logger.log({ level: "error", message: error2.message });
|
|
1378
|
-
next(error2);
|
|
1379
|
-
return;
|
|
1380
|
-
}
|
|
1381
|
-
}
|
|
1382
|
-
return {
|
|
1383
|
-
createArea,
|
|
1384
|
-
getAreas,
|
|
1385
|
-
getAreaById,
|
|
1386
|
-
updateArea,
|
|
1387
|
-
deleteArea,
|
|
1388
|
-
importArea
|
|
1389
|
-
};
|
|
1390
|
-
}
|
|
1391
|
-
|
|
1392
|
-
// src/models/hygiene-unit.model.ts
|
|
1393
|
-
var import_joi4 = __toESM(require("joi"));
|
|
1394
|
-
var import_mongodb4 = require("mongodb");
|
|
1395
|
-
var import_node_server_utils7 = require("@7365admin1/node-server-utils");
|
|
1396
|
-
var unitSchema = import_joi4.default.object({
|
|
1397
|
-
site: import_joi4.default.string().hex().required(),
|
|
1398
|
-
name: import_joi4.default.string().required()
|
|
1399
|
-
});
|
|
1400
|
-
function MUnit(value) {
|
|
1401
|
-
const { error } = unitSchema.validate(value);
|
|
1402
|
-
if (error) {
|
|
1403
|
-
import_node_server_utils7.logger.info(`Hygiene Unit Model: ${error.message}`);
|
|
1404
|
-
throw new import_node_server_utils7.BadRequestError(error.message);
|
|
1405
|
-
}
|
|
1406
|
-
if (value.site) {
|
|
1407
|
-
try {
|
|
1408
|
-
value.site = new import_mongodb4.ObjectId(value.site);
|
|
1409
|
-
} catch (error2) {
|
|
1410
|
-
throw new import_node_server_utils7.BadRequestError("Invalid site ID format.");
|
|
1411
|
-
}
|
|
1412
|
-
}
|
|
1413
|
-
return {
|
|
1414
|
-
site: value.site,
|
|
1415
|
-
name: value.name,
|
|
1416
|
-
status: "active",
|
|
1417
|
-
createdAt: /* @__PURE__ */ new Date(),
|
|
1418
|
-
updatedAt: "",
|
|
1419
|
-
deletedAt: ""
|
|
1420
|
-
};
|
|
1421
|
-
}
|
|
1422
|
-
|
|
1423
|
-
// src/services/hygiene-unit.service.ts
|
|
1424
|
-
var import_node_server_utils9 = require("@7365admin1/node-server-utils");
|
|
1425
|
-
|
|
1426
|
-
// src/repositories/hygiene-unit.repository.ts
|
|
1427
|
-
var import_mongodb5 = require("mongodb");
|
|
1428
|
-
var import_node_server_utils8 = require("@7365admin1/node-server-utils");
|
|
1429
|
-
function useUnitRepository() {
|
|
1430
|
-
const db = import_node_server_utils8.useAtlas.getDb();
|
|
1431
|
-
if (!db) {
|
|
1432
|
-
throw new import_node_server_utils8.InternalServerError("Unable to connect to server.");
|
|
1433
|
-
}
|
|
1434
|
-
const namespace_collection = "site.cleaning.area.unit";
|
|
1435
|
-
const collection = db.collection(namespace_collection);
|
|
1436
|
-
const { delNamespace, setCache, getCache } = (0, import_node_server_utils8.useCache)(namespace_collection);
|
|
1437
|
-
async function createIndex() {
|
|
1438
|
-
try {
|
|
1439
|
-
await collection.createIndexes([
|
|
1440
|
-
{ key: { site: 1 } },
|
|
1441
|
-
{ key: { status: 1 } }
|
|
1442
|
-
]);
|
|
1443
|
-
} catch (error) {
|
|
1444
|
-
throw new import_node_server_utils8.InternalServerError("Failed to create index on hygiene unit.");
|
|
1445
|
-
}
|
|
1446
|
-
}
|
|
1447
|
-
async function createTextIndex() {
|
|
1448
|
-
try {
|
|
1449
|
-
await collection.createIndex({ name: "text" });
|
|
1450
|
-
} catch (error) {
|
|
1451
|
-
throw new import_node_server_utils8.InternalServerError(
|
|
1452
|
-
"Failed to create text index on hygiene unit."
|
|
1453
|
-
);
|
|
1454
|
-
}
|
|
1455
|
-
}
|
|
1456
|
-
async function createUniqueIndex() {
|
|
1457
|
-
try {
|
|
1458
|
-
await collection.createIndex(
|
|
1459
|
-
{ site: 1, name: 1, deletedAt: 1 },
|
|
1460
|
-
{ unique: true }
|
|
1461
|
-
);
|
|
1462
|
-
} catch (error) {
|
|
1463
|
-
throw new import_node_server_utils8.InternalServerError(
|
|
1464
|
-
"Failed to create unique index on hygiene unit."
|
|
1465
|
-
);
|
|
1466
|
-
}
|
|
1467
|
-
}
|
|
1468
|
-
async function createUnit(value, session) {
|
|
1469
|
-
try {
|
|
1470
|
-
value = MUnit(value);
|
|
1471
|
-
const res = await collection.insertOne(value, { session });
|
|
1472
|
-
delNamespace().then(() => {
|
|
1473
|
-
import_node_server_utils8.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
1474
|
-
}).catch((err) => {
|
|
1475
|
-
import_node_server_utils8.logger.error(
|
|
1476
|
-
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
1477
|
-
err
|
|
1478
|
-
);
|
|
1479
|
-
});
|
|
1480
|
-
return res.insertedId;
|
|
1481
|
-
} catch (error) {
|
|
1482
|
-
const isDuplicated = error.message.includes("duplicate");
|
|
1483
|
-
if (isDuplicated) {
|
|
1484
|
-
throw new import_node_server_utils8.BadRequestError("Unit already exists.");
|
|
1485
|
-
}
|
|
1486
|
-
throw error;
|
|
1487
|
-
}
|
|
1488
|
-
}
|
|
1489
|
-
async function getUnits({
|
|
1490
|
-
page = 1,
|
|
1491
|
-
limit = 10,
|
|
1492
|
-
search = "",
|
|
1493
|
-
site
|
|
1494
|
-
}) {
|
|
1495
|
-
page = page > 0 ? page - 1 : 0;
|
|
1496
|
-
const query = {
|
|
1497
|
-
status: { $ne: "deleted" }
|
|
1498
|
-
};
|
|
1499
|
-
const cacheOptions = {
|
|
1500
|
-
page,
|
|
1501
|
-
limit
|
|
1502
|
-
};
|
|
1503
|
-
try {
|
|
1504
|
-
site = new import_mongodb5.ObjectId(site);
|
|
1505
|
-
query.site = site;
|
|
1506
|
-
cacheOptions.site = site.toString();
|
|
1507
|
-
} catch (error) {
|
|
1508
|
-
throw new import_node_server_utils8.BadRequestError("Invalid site ID format.");
|
|
1509
|
-
}
|
|
1510
|
-
if (search) {
|
|
1511
|
-
query.$or = [{ name: { $regex: search, $options: "i" } }];
|
|
1512
|
-
cacheOptions.search = search;
|
|
1513
|
-
}
|
|
1514
|
-
const cacheKey = (0, import_node_server_utils8.makeCacheKey)(namespace_collection, cacheOptions);
|
|
1515
|
-
const cachedData = await getCache(cacheKey);
|
|
1516
|
-
if (cachedData) {
|
|
1517
|
-
import_node_server_utils8.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
1518
|
-
return cachedData;
|
|
1684
|
+
async function deleteArea(req, res, next) {
|
|
1685
|
+
const id = req.params.id;
|
|
1686
|
+
const validation = import_joi4.default.string().hex().required();
|
|
1687
|
+
const { error, value } = validation.validate(id);
|
|
1688
|
+
if (error) {
|
|
1689
|
+
import_node_server_utils9.logger.log({ level: "error", message: error.message });
|
|
1690
|
+
next(new import_node_server_utils9.BadRequestError(error.message));
|
|
1691
|
+
return;
|
|
1519
1692
|
}
|
|
1520
1693
|
try {
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
const length = await collection.countDocuments(query);
|
|
1529
|
-
const data = (0, import_node_server_utils8.paginate)(items, page, limit, length);
|
|
1530
|
-
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
1531
|
-
import_node_server_utils8.logger.info(`Cache set for key: ${cacheKey}`);
|
|
1532
|
-
}).catch((err) => {
|
|
1533
|
-
import_node_server_utils8.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
1534
|
-
});
|
|
1535
|
-
return data;
|
|
1536
|
-
} catch (error) {
|
|
1537
|
-
throw error;
|
|
1694
|
+
await _deleteById(value);
|
|
1695
|
+
res.json({ message: "Area deleted successfully." });
|
|
1696
|
+
return;
|
|
1697
|
+
} catch (error2) {
|
|
1698
|
+
import_node_server_utils9.logger.log({ level: "error", message: error2.message });
|
|
1699
|
+
next(error2);
|
|
1700
|
+
return;
|
|
1538
1701
|
}
|
|
1539
1702
|
}
|
|
1540
|
-
async function
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1703
|
+
async function importArea(req, res, next) {
|
|
1704
|
+
if (!req.file) {
|
|
1705
|
+
next(new import_node_server_utils9.BadRequestError("File is required!"));
|
|
1706
|
+
return;
|
|
1707
|
+
}
|
|
1708
|
+
const { site } = req.params;
|
|
1709
|
+
const schema = import_joi4.default.string().hex().required();
|
|
1710
|
+
const { error, value } = schema.validate(site);
|
|
1711
|
+
if (error) {
|
|
1712
|
+
import_node_server_utils9.logger.log({ level: "error", message: error.message });
|
|
1713
|
+
next(new import_node_server_utils9.BadRequestError(error.message));
|
|
1714
|
+
return;
|
|
1545
1715
|
}
|
|
1546
1716
|
try {
|
|
1547
|
-
const
|
|
1548
|
-
const
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
);
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
}
|
|
1556
|
-
delNamespace().then(() => {
|
|
1557
|
-
import_node_server_utils8.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
1558
|
-
}).catch((err) => {
|
|
1559
|
-
import_node_server_utils8.logger.error(
|
|
1560
|
-
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
1561
|
-
err
|
|
1562
|
-
);
|
|
1563
|
-
});
|
|
1564
|
-
return res.modifiedCount;
|
|
1565
|
-
} catch (error) {
|
|
1566
|
-
const isDuplicated = error.message.includes("duplicate");
|
|
1567
|
-
if (isDuplicated) {
|
|
1568
|
-
throw new import_node_server_utils8.BadRequestError("Area already exists.");
|
|
1569
|
-
}
|
|
1570
|
-
throw error;
|
|
1717
|
+
const xlsData = await convertBufferFile(req.file.buffer);
|
|
1718
|
+
const dataJson = JSON.stringify(xlsData);
|
|
1719
|
+
const result = await _importArea({ dataJson, site: value });
|
|
1720
|
+
return res.status(201).json(result);
|
|
1721
|
+
} catch (error2) {
|
|
1722
|
+
import_node_server_utils9.logger.log({ level: "error", message: error2.message });
|
|
1723
|
+
next(error2);
|
|
1724
|
+
return;
|
|
1571
1725
|
}
|
|
1572
1726
|
}
|
|
1573
|
-
async function
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
}
|
|
1577
|
-
|
|
1727
|
+
async function exportAreas(req, res, next) {
|
|
1728
|
+
const { site } = req.params;
|
|
1729
|
+
const validation = import_joi4.default.string().hex().required();
|
|
1730
|
+
const { error, value } = validation.validate(site);
|
|
1731
|
+
if (error) {
|
|
1732
|
+
import_node_server_utils9.logger.log({ level: "error", message: error.message });
|
|
1733
|
+
next(new import_node_server_utils9.BadRequestError(error.message));
|
|
1734
|
+
return;
|
|
1578
1735
|
}
|
|
1579
1736
|
try {
|
|
1580
|
-
const
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1737
|
+
const excelBuffer = await _exportAreas(value);
|
|
1738
|
+
const date = /* @__PURE__ */ new Date();
|
|
1739
|
+
const formattedDate = `${String(date.getMonth() + 1).padStart(
|
|
1740
|
+
2,
|
|
1741
|
+
"0"
|
|
1742
|
+
)}-${String(date.getDate()).padStart(2, "0")}-${date.getFullYear()}`;
|
|
1743
|
+
res.setHeader(
|
|
1744
|
+
"Content-Type",
|
|
1745
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
1589
1746
|
);
|
|
1590
|
-
|
|
1591
|
-
|
|
1747
|
+
res.setHeader(
|
|
1748
|
+
"Content-Disposition",
|
|
1749
|
+
`attachment; filename="areas-${formattedDate}.xlsx"`
|
|
1750
|
+
);
|
|
1751
|
+
res.setHeader("Content-Length", excelBuffer.length);
|
|
1752
|
+
res.end(excelBuffer);
|
|
1753
|
+
return;
|
|
1754
|
+
} catch (error2) {
|
|
1755
|
+
import_node_server_utils9.logger.log({ level: "error", message: error2.message });
|
|
1756
|
+
next(error2);
|
|
1757
|
+
return;
|
|
1758
|
+
}
|
|
1759
|
+
}
|
|
1760
|
+
return {
|
|
1761
|
+
createArea,
|
|
1762
|
+
getAreas,
|
|
1763
|
+
getAreaById,
|
|
1764
|
+
updateArea,
|
|
1765
|
+
deleteArea,
|
|
1766
|
+
importArea,
|
|
1767
|
+
exportAreas
|
|
1768
|
+
};
|
|
1769
|
+
}
|
|
1770
|
+
|
|
1771
|
+
// src/services/hygiene-unit.service.ts
|
|
1772
|
+
var import_node_server_utils11 = require("@7365admin1/node-server-utils");
|
|
1773
|
+
|
|
1774
|
+
// src/services/hygiene-unit-export.service.ts
|
|
1775
|
+
var import_node_server_utils10 = require("@7365admin1/node-server-utils");
|
|
1776
|
+
var xlsx3 = __toESM(require("xlsx"));
|
|
1777
|
+
function useUnitExportService() {
|
|
1778
|
+
async function generateUnitExcel(units) {
|
|
1779
|
+
try {
|
|
1780
|
+
const rows = [];
|
|
1781
|
+
rows.push(["UNIT"]);
|
|
1782
|
+
for (const unit of units) {
|
|
1783
|
+
const unitName = unit.name || "";
|
|
1784
|
+
rows.push([unitName]);
|
|
1592
1785
|
}
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1786
|
+
const workbook = xlsx3.utils.book_new();
|
|
1787
|
+
const worksheet = xlsx3.utils.aoa_to_sheet(rows);
|
|
1788
|
+
worksheet["!cols"] = [
|
|
1789
|
+
{ width: 25 }
|
|
1790
|
+
// UNIT
|
|
1791
|
+
];
|
|
1792
|
+
xlsx3.utils.book_append_sheet(workbook, worksheet, "Units");
|
|
1793
|
+
const excelBuffer = xlsx3.write(workbook, {
|
|
1794
|
+
type: "buffer",
|
|
1795
|
+
bookType: "xlsx"
|
|
1600
1796
|
});
|
|
1601
|
-
return
|
|
1797
|
+
return excelBuffer;
|
|
1602
1798
|
} catch (error) {
|
|
1799
|
+
import_node_server_utils10.logger.log({
|
|
1800
|
+
level: "error",
|
|
1801
|
+
message: `Failed to generate unit Excel: ${error.message}`
|
|
1802
|
+
});
|
|
1603
1803
|
throw error;
|
|
1604
1804
|
}
|
|
1605
1805
|
}
|
|
1606
1806
|
return {
|
|
1607
|
-
|
|
1608
|
-
createTextIndex,
|
|
1609
|
-
createUniqueIndex,
|
|
1610
|
-
createUnit,
|
|
1611
|
-
getUnits,
|
|
1612
|
-
updateUnit,
|
|
1613
|
-
deleteUnit
|
|
1807
|
+
generateUnitExcel
|
|
1614
1808
|
};
|
|
1615
1809
|
}
|
|
1616
1810
|
|
|
@@ -1630,10 +1824,10 @@ function useUnitService() {
|
|
|
1630
1824
|
try {
|
|
1631
1825
|
dataArray = JSON.parse(dataJson);
|
|
1632
1826
|
} catch (error) {
|
|
1633
|
-
throw new
|
|
1827
|
+
throw new import_node_server_utils11.BadRequestError("Invalid JSON format for data in excel");
|
|
1634
1828
|
}
|
|
1635
1829
|
if (!dataArray || dataArray.length === 0) {
|
|
1636
|
-
throw new
|
|
1830
|
+
throw new import_node_server_utils11.NotFoundError("No data found in the uploaded file");
|
|
1637
1831
|
}
|
|
1638
1832
|
const insertedUnitIds = [];
|
|
1639
1833
|
const duplicateUnits = [];
|
|
@@ -1643,13 +1837,18 @@ function useUnitService() {
|
|
|
1643
1837
|
for (let i = 0; i < dataArray.length; i++) {
|
|
1644
1838
|
const row = dataArray[i];
|
|
1645
1839
|
if (!row?.UNIT) {
|
|
1646
|
-
|
|
1840
|
+
import_node_server_utils11.logger.warn(`Skipping row ${i + 1} with missing UNIT:`, row);
|
|
1647
1841
|
skippedRows.push(i + 1);
|
|
1648
1842
|
continue;
|
|
1649
1843
|
}
|
|
1650
1844
|
const unitName = String(row.UNIT).trim();
|
|
1651
1845
|
if (!unitName) {
|
|
1652
|
-
|
|
1846
|
+
import_node_server_utils11.logger.warn(`Skipping row ${i + 1} with empty unit name`);
|
|
1847
|
+
skippedRows.push(i + 1);
|
|
1848
|
+
continue;
|
|
1849
|
+
}
|
|
1850
|
+
if (unitName.startsWith("Sample:")) {
|
|
1851
|
+
import_node_server_utils11.logger.warn(`Skipping row ${i + 1} with sample unit: ${unitName}`);
|
|
1653
1852
|
skippedRows.push(i + 1);
|
|
1654
1853
|
continue;
|
|
1655
1854
|
}
|
|
@@ -1659,9 +1858,9 @@ function useUnitService() {
|
|
|
1659
1858
|
site
|
|
1660
1859
|
});
|
|
1661
1860
|
insertedUnitIds.push(insertedId);
|
|
1662
|
-
|
|
1861
|
+
import_node_server_utils11.logger.info(`Successfully created unit: ${unitName}`);
|
|
1663
1862
|
} catch (error) {
|
|
1664
|
-
|
|
1863
|
+
import_node_server_utils11.logger.error(`Error creating unit "${unitName}": ${error.message}`);
|
|
1665
1864
|
if (error.message.includes("Unit already exists")) {
|
|
1666
1865
|
duplicateUnits.push(unitName);
|
|
1667
1866
|
} else {
|
|
@@ -1679,44 +1878,44 @@ function useUnitService() {
|
|
|
1679
1878
|
if (skippedRows.length > 0) {
|
|
1680
1879
|
message += `, ${skippedRows.length} rows skipped (invalid data)`;
|
|
1681
1880
|
}
|
|
1682
|
-
|
|
1881
|
+
import_node_server_utils11.logger.info(message);
|
|
1683
1882
|
if (insertedUnitIds.length === 0) {
|
|
1684
1883
|
if (duplicateUnits.length > 0 && failedUnits.length === 0) {
|
|
1685
|
-
throw new
|
|
1884
|
+
throw new import_node_server_utils11.BadRequestError(
|
|
1686
1885
|
`No new units were created. All ${duplicateUnits.length} units already exist in the system: ${duplicateUnits.join(", ")}`
|
|
1687
1886
|
);
|
|
1688
1887
|
} else if (failedUnits.length > 0) {
|
|
1689
|
-
throw new
|
|
1888
|
+
throw new import_node_server_utils11.BadRequestError(
|
|
1690
1889
|
`No units were created. Please check your data format and ensure unit names are valid.`
|
|
1691
1890
|
);
|
|
1692
1891
|
} else if (skippedRows.length > 0) {
|
|
1693
|
-
throw new
|
|
1892
|
+
throw new import_node_server_utils11.BadRequestError(
|
|
1694
1893
|
`No units were created. All rows contained invalid or missing unit names.`
|
|
1695
1894
|
);
|
|
1696
1895
|
}
|
|
1697
1896
|
}
|
|
1698
1897
|
return { message };
|
|
1699
1898
|
} catch (error) {
|
|
1700
|
-
|
|
1701
|
-
if (error instanceof
|
|
1899
|
+
import_node_server_utils11.logger.error("Error while uploading unit information", error);
|
|
1900
|
+
if (error instanceof import_node_server_utils11.BadRequestError) {
|
|
1702
1901
|
throw error;
|
|
1703
1902
|
} else if (error.message.includes("duplicate")) {
|
|
1704
|
-
throw new
|
|
1903
|
+
throw new import_node_server_utils11.BadRequestError(
|
|
1705
1904
|
"Upload failed due to duplicate unit names. Please ensure all unit names are unique."
|
|
1706
1905
|
);
|
|
1707
1906
|
} else if (error.message.includes("validation")) {
|
|
1708
|
-
throw new
|
|
1907
|
+
throw new import_node_server_utils11.BadRequestError(
|
|
1709
1908
|
"Upload failed due to invalid data format. Please check that all required fields are properly filled."
|
|
1710
1909
|
);
|
|
1711
1910
|
} else {
|
|
1712
|
-
throw new
|
|
1911
|
+
throw new import_node_server_utils11.BadRequestError(
|
|
1713
1912
|
`Upload failed: ${error.message || "Please check your data format and try again."}`
|
|
1714
1913
|
);
|
|
1715
1914
|
}
|
|
1716
1915
|
}
|
|
1717
1916
|
}
|
|
1718
1917
|
async function updateUnit(_id, value) {
|
|
1719
|
-
const session =
|
|
1918
|
+
const session = import_node_server_utils11.useAtlas.getClient()?.startSession();
|
|
1720
1919
|
try {
|
|
1721
1920
|
session?.startTransaction();
|
|
1722
1921
|
const result = await _updateUnit(_id, value, session);
|
|
@@ -1727,7 +1926,7 @@ function useUnitService() {
|
|
|
1727
1926
|
await session?.commitTransaction();
|
|
1728
1927
|
return result;
|
|
1729
1928
|
} catch (error) {
|
|
1730
|
-
|
|
1929
|
+
import_node_server_utils11.logger.error(`Error updating unit and associated areas:`, error);
|
|
1731
1930
|
if (session?.inTransaction()) {
|
|
1732
1931
|
await session?.abortTransaction();
|
|
1733
1932
|
}
|
|
@@ -1737,18 +1936,18 @@ function useUnitService() {
|
|
|
1737
1936
|
}
|
|
1738
1937
|
}
|
|
1739
1938
|
async function deleteUnit(_id) {
|
|
1740
|
-
const session =
|
|
1939
|
+
const session = import_node_server_utils11.useAtlas.getClient()?.startSession();
|
|
1741
1940
|
try {
|
|
1742
1941
|
session?.startTransaction();
|
|
1743
1942
|
const isExistingArea = await verifyAreaByUnitId(_id);
|
|
1744
1943
|
if (isExistingArea) {
|
|
1745
|
-
throw new
|
|
1944
|
+
throw new import_node_server_utils11.BadRequestError("Failed to delete unit, unit is in use.");
|
|
1746
1945
|
}
|
|
1747
1946
|
const result = await _deleteUnit(_id, session);
|
|
1748
1947
|
await session?.commitTransaction();
|
|
1749
1948
|
return result;
|
|
1750
1949
|
} catch (error) {
|
|
1751
|
-
|
|
1950
|
+
import_node_server_utils11.logger.error(`Error deleting unit:`, error);
|
|
1752
1951
|
if (session?.inTransaction()) {
|
|
1753
1952
|
await session?.abortTransaction();
|
|
1754
1953
|
}
|
|
@@ -1757,25 +1956,49 @@ function useUnitService() {
|
|
|
1757
1956
|
session?.endSession();
|
|
1758
1957
|
}
|
|
1759
1958
|
}
|
|
1760
|
-
|
|
1959
|
+
async function exportUnits(site) {
|
|
1960
|
+
const { generateUnitExcel: _generateUnitExcel } = useUnitExportService();
|
|
1961
|
+
const { getUnits: _getUnits } = useUnitRepository();
|
|
1962
|
+
try {
|
|
1963
|
+
const data = await _getUnits({
|
|
1964
|
+
page: 1,
|
|
1965
|
+
limit: 999999,
|
|
1966
|
+
search: "",
|
|
1967
|
+
site
|
|
1968
|
+
});
|
|
1969
|
+
if (!data || !data.items || data.items.length === 0) {
|
|
1970
|
+
throw new import_node_server_utils11.BadRequestError("No data found to export");
|
|
1971
|
+
}
|
|
1972
|
+
const excelBuffer = await _generateUnitExcel(data.items);
|
|
1973
|
+
if (!excelBuffer || excelBuffer.length === 0) {
|
|
1974
|
+
throw new Error("Generated Excel file is empty or invalid.");
|
|
1975
|
+
}
|
|
1976
|
+
return excelBuffer;
|
|
1977
|
+
} catch (error) {
|
|
1978
|
+
import_node_server_utils11.logger.error(`Error downloading units: ${error.message}`);
|
|
1979
|
+
throw error;
|
|
1980
|
+
}
|
|
1981
|
+
}
|
|
1982
|
+
return { importUnit, updateUnit, deleteUnit, exportUnits };
|
|
1761
1983
|
}
|
|
1762
1984
|
|
|
1763
1985
|
// src/controllers/hygiene-unit.controller.ts
|
|
1764
1986
|
var import_joi5 = __toESM(require("joi"));
|
|
1765
|
-
var
|
|
1987
|
+
var import_node_server_utils12 = require("@7365admin1/node-server-utils");
|
|
1766
1988
|
function useUnitController() {
|
|
1767
1989
|
const { createUnit: _createUnit, getUnits: _getUnits } = useUnitRepository();
|
|
1768
1990
|
const {
|
|
1769
1991
|
updateUnit: _updateUnit,
|
|
1770
1992
|
deleteUnit: _deleteUnit,
|
|
1771
|
-
importUnit: _importUnit
|
|
1993
|
+
importUnit: _importUnit,
|
|
1994
|
+
exportUnits: _exportUnits
|
|
1772
1995
|
} = useUnitService();
|
|
1773
1996
|
async function createUnit(req, res, next) {
|
|
1774
1997
|
const payload = { ...req.body, ...req.params };
|
|
1775
1998
|
const { error } = unitSchema.validate(payload);
|
|
1776
1999
|
if (error) {
|
|
1777
|
-
|
|
1778
|
-
next(new
|
|
2000
|
+
import_node_server_utils12.logger.log({ level: "error", message: error.message });
|
|
2001
|
+
next(new import_node_server_utils12.BadRequestError(error.message));
|
|
1779
2002
|
return;
|
|
1780
2003
|
}
|
|
1781
2004
|
try {
|
|
@@ -1783,7 +2006,7 @@ function useUnitController() {
|
|
|
1783
2006
|
res.status(201).json({ message: "Unit created successfully.", id });
|
|
1784
2007
|
return;
|
|
1785
2008
|
} catch (error2) {
|
|
1786
|
-
|
|
2009
|
+
import_node_server_utils12.logger.log({ level: "error", message: error2.message });
|
|
1787
2010
|
next(error2);
|
|
1788
2011
|
return;
|
|
1789
2012
|
}
|
|
@@ -1798,8 +2021,8 @@ function useUnitController() {
|
|
|
1798
2021
|
});
|
|
1799
2022
|
const { error } = validation.validate(query);
|
|
1800
2023
|
if (error) {
|
|
1801
|
-
|
|
1802
|
-
next(new
|
|
2024
|
+
import_node_server_utils12.logger.log({ level: "error", message: error.message });
|
|
2025
|
+
next(new import_node_server_utils12.BadRequestError(error.message));
|
|
1803
2026
|
return;
|
|
1804
2027
|
}
|
|
1805
2028
|
const page = parseInt(req.query.page) ?? 1;
|
|
@@ -1816,7 +2039,7 @@ function useUnitController() {
|
|
|
1816
2039
|
res.json(data);
|
|
1817
2040
|
return;
|
|
1818
2041
|
} catch (error2) {
|
|
1819
|
-
|
|
2042
|
+
import_node_server_utils12.logger.log({ level: "error", message: error2.message });
|
|
1820
2043
|
next(error2);
|
|
1821
2044
|
return;
|
|
1822
2045
|
}
|
|
@@ -1829,8 +2052,8 @@ function useUnitController() {
|
|
|
1829
2052
|
});
|
|
1830
2053
|
const { error } = validation.validate(payload);
|
|
1831
2054
|
if (error) {
|
|
1832
|
-
|
|
1833
|
-
next(new
|
|
2055
|
+
import_node_server_utils12.logger.log({ level: "error", message: error.message });
|
|
2056
|
+
next(new import_node_server_utils12.BadRequestError(error.message));
|
|
1834
2057
|
return;
|
|
1835
2058
|
}
|
|
1836
2059
|
try {
|
|
@@ -1839,7 +2062,7 @@ function useUnitController() {
|
|
|
1839
2062
|
res.json({ message: "Unit updated successfully." });
|
|
1840
2063
|
return;
|
|
1841
2064
|
} catch (error2) {
|
|
1842
|
-
|
|
2065
|
+
import_node_server_utils12.logger.log({ level: "error", message: error2.message });
|
|
1843
2066
|
next(error2);
|
|
1844
2067
|
return;
|
|
1845
2068
|
}
|
|
@@ -1851,8 +2074,8 @@ function useUnitController() {
|
|
|
1851
2074
|
});
|
|
1852
2075
|
const { error, value } = validation.validate({ id });
|
|
1853
2076
|
if (error) {
|
|
1854
|
-
|
|
1855
|
-
next(new
|
|
2077
|
+
import_node_server_utils12.logger.log({ level: "error", message: error.message });
|
|
2078
|
+
next(new import_node_server_utils12.BadRequestError(error.message));
|
|
1856
2079
|
return;
|
|
1857
2080
|
}
|
|
1858
2081
|
try {
|
|
@@ -1860,22 +2083,22 @@ function useUnitController() {
|
|
|
1860
2083
|
res.json({ message: "Unit deleted successfully." });
|
|
1861
2084
|
return;
|
|
1862
2085
|
} catch (error2) {
|
|
1863
|
-
|
|
2086
|
+
import_node_server_utils12.logger.log({ level: "error", message: error2.message });
|
|
1864
2087
|
next(error2);
|
|
1865
2088
|
return;
|
|
1866
2089
|
}
|
|
1867
2090
|
}
|
|
1868
2091
|
async function importUnit(req, res, next) {
|
|
1869
2092
|
if (!req.file) {
|
|
1870
|
-
next(new
|
|
2093
|
+
next(new import_node_server_utils12.BadRequestError("File is required!"));
|
|
1871
2094
|
return;
|
|
1872
2095
|
}
|
|
1873
2096
|
const { site } = req.params;
|
|
1874
2097
|
const validation = import_joi5.default.string().hex().required();
|
|
1875
2098
|
const { error, value } = validation.validate(site);
|
|
1876
2099
|
if (error) {
|
|
1877
|
-
|
|
1878
|
-
next(new
|
|
2100
|
+
import_node_server_utils12.logger.log({ level: "error", message: error.message });
|
|
2101
|
+
next(new import_node_server_utils12.BadRequestError(error.message));
|
|
1879
2102
|
return;
|
|
1880
2103
|
}
|
|
1881
2104
|
try {
|
|
@@ -1884,7 +2107,40 @@ function useUnitController() {
|
|
|
1884
2107
|
const result = await _importUnit({ dataJson, site: value });
|
|
1885
2108
|
return res.status(201).json(result);
|
|
1886
2109
|
} catch (error2) {
|
|
1887
|
-
|
|
2110
|
+
import_node_server_utils12.logger.log({ level: "error", message: error2.message });
|
|
2111
|
+
next(error2);
|
|
2112
|
+
return;
|
|
2113
|
+
}
|
|
2114
|
+
}
|
|
2115
|
+
async function exportUnits(req, res, next) {
|
|
2116
|
+
const { site } = req.params;
|
|
2117
|
+
const validation = import_joi5.default.string().hex().required();
|
|
2118
|
+
const { error, value } = validation.validate(site);
|
|
2119
|
+
if (error) {
|
|
2120
|
+
import_node_server_utils12.logger.log({ level: "error", message: error.message });
|
|
2121
|
+
next(new import_node_server_utils12.BadRequestError(error.message));
|
|
2122
|
+
return;
|
|
2123
|
+
}
|
|
2124
|
+
try {
|
|
2125
|
+
const excelBuffer = await _exportUnits(value);
|
|
2126
|
+
const date = /* @__PURE__ */ new Date();
|
|
2127
|
+
const formattedDate = `${String(date.getMonth() + 1).padStart(
|
|
2128
|
+
2,
|
|
2129
|
+
"0"
|
|
2130
|
+
)}-${String(date.getDate()).padStart(2, "0")}-${date.getFullYear()}`;
|
|
2131
|
+
res.setHeader(
|
|
2132
|
+
"Content-Type",
|
|
2133
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
2134
|
+
);
|
|
2135
|
+
res.setHeader(
|
|
2136
|
+
"Content-Disposition",
|
|
2137
|
+
`attachment; filename="units-${formattedDate}.xlsx"`
|
|
2138
|
+
);
|
|
2139
|
+
res.setHeader("Content-Length", excelBuffer.length);
|
|
2140
|
+
res.end(excelBuffer);
|
|
2141
|
+
return;
|
|
2142
|
+
} catch (error2) {
|
|
2143
|
+
import_node_server_utils12.logger.log({ level: "error", message: error2.message });
|
|
1888
2144
|
next(error2);
|
|
1889
2145
|
return;
|
|
1890
2146
|
}
|
|
@@ -1894,14 +2150,15 @@ function useUnitController() {
|
|
|
1894
2150
|
getUnits,
|
|
1895
2151
|
updateUnit,
|
|
1896
2152
|
deleteUnit,
|
|
1897
|
-
importUnit
|
|
2153
|
+
importUnit,
|
|
2154
|
+
exportUnits
|
|
1898
2155
|
};
|
|
1899
2156
|
}
|
|
1900
2157
|
|
|
1901
2158
|
// src/models/hygiene-parent-checklist.model.ts
|
|
1902
2159
|
var import_joi6 = __toESM(require("joi"));
|
|
1903
2160
|
var import_mongodb6 = require("mongodb");
|
|
1904
|
-
var
|
|
2161
|
+
var import_node_server_utils13 = require("@7365admin1/node-server-utils");
|
|
1905
2162
|
var parentChecklistSchema = import_joi6.default.object({
|
|
1906
2163
|
createdAt: import_joi6.default.alternatives().try(import_joi6.default.date(), import_joi6.default.string()).optional().allow("", null),
|
|
1907
2164
|
site: import_joi6.default.string().hex().required()
|
|
@@ -1909,14 +2166,14 @@ var parentChecklistSchema = import_joi6.default.object({
|
|
|
1909
2166
|
function MParentChecklist(value) {
|
|
1910
2167
|
const { error } = parentChecklistSchema.validate(value);
|
|
1911
2168
|
if (error) {
|
|
1912
|
-
|
|
1913
|
-
throw new
|
|
2169
|
+
import_node_server_utils13.logger.info(`Hygiene Parent Checklist Model: ${error.message}`);
|
|
2170
|
+
throw new import_node_server_utils13.BadRequestError(error.message);
|
|
1914
2171
|
}
|
|
1915
2172
|
if (value.site) {
|
|
1916
2173
|
try {
|
|
1917
2174
|
value.site = new import_mongodb6.ObjectId(value.site);
|
|
1918
2175
|
} catch (error2) {
|
|
1919
|
-
throw new
|
|
2176
|
+
throw new import_node_server_utils13.BadRequestError(`Invalid site ID format: ${value.site}`);
|
|
1920
2177
|
}
|
|
1921
2178
|
}
|
|
1922
2179
|
return {
|
|
@@ -1929,17 +2186,17 @@ function MParentChecklist(value) {
|
|
|
1929
2186
|
|
|
1930
2187
|
// src/repositories/hygiene-parent-checklist.repository.ts
|
|
1931
2188
|
var import_mongodb7 = require("mongodb");
|
|
1932
|
-
var
|
|
2189
|
+
var import_node_server_utils14 = require("@7365admin1/node-server-utils");
|
|
1933
2190
|
function useParentChecklistRepo() {
|
|
1934
|
-
const db =
|
|
2191
|
+
const db = import_node_server_utils14.useAtlas.getDb();
|
|
1935
2192
|
if (!db) {
|
|
1936
|
-
throw new
|
|
2193
|
+
throw new import_node_server_utils14.InternalServerError("Unable to connect to server.");
|
|
1937
2194
|
}
|
|
1938
2195
|
const namespace_collection = "site.cleaning.schedules";
|
|
1939
2196
|
const site_collection = "sites";
|
|
1940
2197
|
const collection = db.collection(namespace_collection);
|
|
1941
2198
|
const siteCollection = db.collection(site_collection);
|
|
1942
|
-
const { delNamespace, setCache, getCache } = (0,
|
|
2199
|
+
const { delNamespace, setCache, getCache } = (0, import_node_server_utils14.useCache)(namespace_collection);
|
|
1943
2200
|
async function createIndex() {
|
|
1944
2201
|
try {
|
|
1945
2202
|
await collection.createIndexes([
|
|
@@ -1948,7 +2205,7 @@ function useParentChecklistRepo() {
|
|
|
1948
2205
|
{ key: { status: 1 } }
|
|
1949
2206
|
]);
|
|
1950
2207
|
} catch (error) {
|
|
1951
|
-
throw new
|
|
2208
|
+
throw new import_node_server_utils14.InternalServerError(
|
|
1952
2209
|
"Failed to create index on hygiene parent checklist."
|
|
1953
2210
|
);
|
|
1954
2211
|
}
|
|
@@ -1969,16 +2226,16 @@ function useParentChecklistRepo() {
|
|
|
1969
2226
|
if (value.site) {
|
|
1970
2227
|
try {
|
|
1971
2228
|
existingQuery.site = new import_mongodb7.ObjectId(value.site);
|
|
1972
|
-
|
|
2229
|
+
import_node_server_utils14.logger.info(
|
|
1973
2230
|
`createParentChecklist: Looking for existing checklist with query: ${JSON.stringify(
|
|
1974
2231
|
{ ...existingQuery, site: value.site }
|
|
1975
2232
|
)}`
|
|
1976
2233
|
);
|
|
1977
2234
|
} catch (error) {
|
|
1978
|
-
throw new
|
|
2235
|
+
throw new import_node_server_utils14.BadRequestError("Invalid site ID format.");
|
|
1979
2236
|
}
|
|
1980
2237
|
} else {
|
|
1981
|
-
|
|
2238
|
+
import_node_server_utils14.logger.info(
|
|
1982
2239
|
`createParentChecklist: Looking for existing checklist with query (no site filter): ${JSON.stringify(
|
|
1983
2240
|
existingQuery
|
|
1984
2241
|
)}`
|
|
@@ -1987,7 +2244,7 @@ function useParentChecklistRepo() {
|
|
|
1987
2244
|
const existingChecklist = await collection.findOne(existingQuery);
|
|
1988
2245
|
if (existingChecklist) {
|
|
1989
2246
|
const dateStr2 = currentDate.toISOString().split("T")[0];
|
|
1990
|
-
|
|
2247
|
+
import_node_server_utils14.logger.info(
|
|
1991
2248
|
`Parent checklist already exists for ${value.site ? `site ${value.site} on` : ""} today: ${dateStr2}. Found checklist: ${JSON.stringify({
|
|
1992
2249
|
_id: existingChecklist._id,
|
|
1993
2250
|
site: existingChecklist.site
|
|
@@ -2002,27 +2259,27 @@ function useParentChecklistRepo() {
|
|
|
2002
2259
|
});
|
|
2003
2260
|
const result2 = await collection.insertOne(checklistDoc, { session });
|
|
2004
2261
|
delNamespace().then(() => {
|
|
2005
|
-
|
|
2262
|
+
import_node_server_utils14.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
2006
2263
|
}).catch((err) => {
|
|
2007
|
-
|
|
2264
|
+
import_node_server_utils14.logger.error(
|
|
2008
2265
|
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
2009
2266
|
err
|
|
2010
2267
|
);
|
|
2011
2268
|
});
|
|
2012
2269
|
const dateStr2 = currentDate.toISOString().split("T")[0];
|
|
2013
|
-
|
|
2270
|
+
import_node_server_utils14.logger.info(
|
|
2014
2271
|
`Created parent checklist for site ${value.site} for today: ${dateStr2}`
|
|
2015
2272
|
);
|
|
2016
2273
|
return result2.insertedId;
|
|
2017
2274
|
}
|
|
2018
2275
|
const siteIds = await getHygieneSiteIds();
|
|
2019
2276
|
if (!Array.isArray(siteIds)) {
|
|
2020
|
-
|
|
2021
|
-
throw new
|
|
2277
|
+
import_node_server_utils14.logger.error("getHygieneSiteIds returned non-array value:", siteIds);
|
|
2278
|
+
throw new import_node_server_utils14.InternalServerError("Failed to retrieve site IDs");
|
|
2022
2279
|
}
|
|
2023
2280
|
if (siteIds.length === 0) {
|
|
2024
|
-
|
|
2025
|
-
throw new
|
|
2281
|
+
import_node_server_utils14.logger.warn("No sites found for creating parent checklist");
|
|
2282
|
+
throw new import_node_server_utils14.BadRequestError("No sites available for checklist creation");
|
|
2026
2283
|
}
|
|
2027
2284
|
const checklistDocs = [];
|
|
2028
2285
|
for (const site of siteIds) {
|
|
@@ -2035,20 +2292,20 @@ function useParentChecklistRepo() {
|
|
|
2035
2292
|
}
|
|
2036
2293
|
const result = await collection.insertMany(checklistDocs, { session });
|
|
2037
2294
|
delNamespace().then(() => {
|
|
2038
|
-
|
|
2295
|
+
import_node_server_utils14.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
2039
2296
|
}).catch((err) => {
|
|
2040
|
-
|
|
2297
|
+
import_node_server_utils14.logger.error(
|
|
2041
2298
|
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
2042
2299
|
err
|
|
2043
2300
|
);
|
|
2044
2301
|
});
|
|
2045
2302
|
const dateStr = currentDate.toISOString().split("T")[0];
|
|
2046
|
-
|
|
2303
|
+
import_node_server_utils14.logger.info(
|
|
2047
2304
|
`Created ${Object.keys(result.insertedIds).length} parent checklists for today: ${dateStr}`
|
|
2048
2305
|
);
|
|
2049
2306
|
return Object.values(result.insertedIds);
|
|
2050
2307
|
} catch (error) {
|
|
2051
|
-
|
|
2308
|
+
import_node_server_utils14.logger.error("Failed to create daily parent checklist", error);
|
|
2052
2309
|
throw error;
|
|
2053
2310
|
}
|
|
2054
2311
|
}
|
|
@@ -2072,7 +2329,7 @@ function useParentChecklistRepo() {
|
|
|
2072
2329
|
query.site = site;
|
|
2073
2330
|
cacheOptions.site = site.toString();
|
|
2074
2331
|
} catch (error) {
|
|
2075
|
-
throw new
|
|
2332
|
+
throw new import_node_server_utils14.BadRequestError("Invalid site ID format.");
|
|
2076
2333
|
}
|
|
2077
2334
|
if (search) {
|
|
2078
2335
|
query.$text = { $search: search };
|
|
@@ -2096,10 +2353,10 @@ function useParentChecklistRepo() {
|
|
|
2096
2353
|
query.status = status;
|
|
2097
2354
|
cacheOptions.status = status;
|
|
2098
2355
|
}
|
|
2099
|
-
const cacheKey = (0,
|
|
2356
|
+
const cacheKey = (0, import_node_server_utils14.makeCacheKey)(namespace_collection, cacheOptions);
|
|
2100
2357
|
const cachedData = await getCache(cacheKey);
|
|
2101
2358
|
if (cachedData) {
|
|
2102
|
-
|
|
2359
|
+
import_node_server_utils14.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
2103
2360
|
return cachedData;
|
|
2104
2361
|
}
|
|
2105
2362
|
try {
|
|
@@ -2132,11 +2389,11 @@ function useParentChecklistRepo() {
|
|
|
2132
2389
|
);
|
|
2133
2390
|
const items = await collection.aggregate(pipeline).toArray();
|
|
2134
2391
|
const length = await collection.countDocuments(query);
|
|
2135
|
-
const data = (0,
|
|
2392
|
+
const data = (0, import_node_server_utils14.paginate)(items, page, limit, length);
|
|
2136
2393
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
2137
|
-
|
|
2394
|
+
import_node_server_utils14.logger.info(`Cache set for key: ${cacheKey}`);
|
|
2138
2395
|
}).catch((err) => {
|
|
2139
|
-
|
|
2396
|
+
import_node_server_utils14.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
2140
2397
|
});
|
|
2141
2398
|
return data;
|
|
2142
2399
|
} catch (error) {
|
|
@@ -2147,7 +2404,7 @@ function useParentChecklistRepo() {
|
|
|
2147
2404
|
try {
|
|
2148
2405
|
_id = new import_mongodb7.ObjectId(_id);
|
|
2149
2406
|
} catch (error) {
|
|
2150
|
-
throw new
|
|
2407
|
+
throw new import_node_server_utils14.BadRequestError("Invalid parent checklist ID format.");
|
|
2151
2408
|
}
|
|
2152
2409
|
try {
|
|
2153
2410
|
const updateValue = {
|
|
@@ -2163,14 +2420,14 @@ function useParentChecklistRepo() {
|
|
|
2163
2420
|
{ session }
|
|
2164
2421
|
);
|
|
2165
2422
|
if (res.modifiedCount === 0) {
|
|
2166
|
-
throw new
|
|
2423
|
+
throw new import_node_server_utils14.InternalServerError(
|
|
2167
2424
|
"Unable to update parent checklist status."
|
|
2168
2425
|
);
|
|
2169
2426
|
}
|
|
2170
2427
|
delNamespace().then(() => {
|
|
2171
|
-
|
|
2428
|
+
import_node_server_utils14.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
2172
2429
|
}).catch((err) => {
|
|
2173
|
-
|
|
2430
|
+
import_node_server_utils14.logger.error(
|
|
2174
2431
|
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
2175
2432
|
err
|
|
2176
2433
|
);
|
|
@@ -2184,10 +2441,10 @@ function useParentChecklistRepo() {
|
|
|
2184
2441
|
const query = {
|
|
2185
2442
|
status: { $ne: "deleted" }
|
|
2186
2443
|
};
|
|
2187
|
-
const cacheKey = (0,
|
|
2444
|
+
const cacheKey = (0, import_node_server_utils14.makeCacheKey)(site_collection, { tag: "site-ids" });
|
|
2188
2445
|
const cachedData = await getCache(cacheKey);
|
|
2189
2446
|
if (cachedData && Array.isArray(cachedData)) {
|
|
2190
|
-
|
|
2447
|
+
import_node_server_utils14.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
2191
2448
|
return cachedData;
|
|
2192
2449
|
}
|
|
2193
2450
|
try {
|
|
@@ -2199,14 +2456,14 @@ function useParentChecklistRepo() {
|
|
|
2199
2456
|
const siteIds = items.map((item) => item._id.toString());
|
|
2200
2457
|
if (siteIds.length > 0) {
|
|
2201
2458
|
setCache(cacheKey, siteIds, 15 * 60).then(() => {
|
|
2202
|
-
|
|
2459
|
+
import_node_server_utils14.logger.info(`Cache set for key: ${cacheKey}`);
|
|
2203
2460
|
}).catch((err) => {
|
|
2204
|
-
|
|
2461
|
+
import_node_server_utils14.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
2205
2462
|
});
|
|
2206
2463
|
}
|
|
2207
2464
|
return siteIds;
|
|
2208
2465
|
} catch (error) {
|
|
2209
|
-
|
|
2466
|
+
import_node_server_utils14.logger.error("Failed to get hygiene site IDs", error);
|
|
2210
2467
|
throw error;
|
|
2211
2468
|
}
|
|
2212
2469
|
}
|
|
@@ -2220,7 +2477,7 @@ function useParentChecklistRepo() {
|
|
|
2220
2477
|
|
|
2221
2478
|
// src/controllers/hygiene-parent-checklist.controller.ts
|
|
2222
2479
|
var import_joi7 = __toESM(require("joi"));
|
|
2223
|
-
var
|
|
2480
|
+
var import_node_server_utils15 = require("@7365admin1/node-server-utils");
|
|
2224
2481
|
function useParentChecklistController() {
|
|
2225
2482
|
const {
|
|
2226
2483
|
createParentChecklist: _createParentChecklist,
|
|
@@ -2230,8 +2487,8 @@ function useParentChecklistController() {
|
|
|
2230
2487
|
const payload = req.body;
|
|
2231
2488
|
const { error } = parentChecklistSchema.validate(payload);
|
|
2232
2489
|
if (error) {
|
|
2233
|
-
|
|
2234
|
-
next(new
|
|
2490
|
+
import_node_server_utils15.logger.log({ level: "error", message: error.message });
|
|
2491
|
+
next(new import_node_server_utils15.BadRequestError(error.message));
|
|
2235
2492
|
return;
|
|
2236
2493
|
}
|
|
2237
2494
|
try {
|
|
@@ -2239,7 +2496,7 @@ function useParentChecklistController() {
|
|
|
2239
2496
|
res.status(201).json({ message: "Parent checklist created successfully.", id });
|
|
2240
2497
|
return;
|
|
2241
2498
|
} catch (error2) {
|
|
2242
|
-
|
|
2499
|
+
import_node_server_utils15.logger.log({ level: "error", message: error2.message });
|
|
2243
2500
|
next(error2);
|
|
2244
2501
|
return;
|
|
2245
2502
|
}
|
|
@@ -2257,8 +2514,8 @@ function useParentChecklistController() {
|
|
|
2257
2514
|
});
|
|
2258
2515
|
const { error } = validation.validate(query);
|
|
2259
2516
|
if (error) {
|
|
2260
|
-
|
|
2261
|
-
next(new
|
|
2517
|
+
import_node_server_utils15.logger.log({ level: "error", message: error.message });
|
|
2518
|
+
next(new import_node_server_utils15.BadRequestError(error.message));
|
|
2262
2519
|
return;
|
|
2263
2520
|
}
|
|
2264
2521
|
const page = parseInt(req.query.page) ?? 1;
|
|
@@ -2281,7 +2538,7 @@ function useParentChecklistController() {
|
|
|
2281
2538
|
res.json(data);
|
|
2282
2539
|
return;
|
|
2283
2540
|
} catch (error2) {
|
|
2284
|
-
|
|
2541
|
+
import_node_server_utils15.logger.log({ level: "error", message: error2.message });
|
|
2285
2542
|
next(error2);
|
|
2286
2543
|
return;
|
|
2287
2544
|
}
|
|
@@ -2295,7 +2552,7 @@ function useParentChecklistController() {
|
|
|
2295
2552
|
// src/models/hygiene-area-checklist.model.ts
|
|
2296
2553
|
var import_joi8 = __toESM(require("joi"));
|
|
2297
2554
|
var import_mongodb8 = require("mongodb");
|
|
2298
|
-
var
|
|
2555
|
+
var import_node_server_utils16 = require("@7365admin1/node-server-utils");
|
|
2299
2556
|
var allowedChecklistStatus = ["ready", "completed"];
|
|
2300
2557
|
var areaChecklistSchema = import_joi8.default.object({
|
|
2301
2558
|
schedule: import_joi8.default.string().hex().required(),
|
|
@@ -2318,21 +2575,21 @@ var areaChecklistSchema = import_joi8.default.object({
|
|
|
2318
2575
|
function MAreaChecklist(value) {
|
|
2319
2576
|
const { error } = areaChecklistSchema.validate(value);
|
|
2320
2577
|
if (error) {
|
|
2321
|
-
|
|
2322
|
-
throw new
|
|
2578
|
+
import_node_server_utils16.logger.info(`Hygiene Checklist Area Model: ${error.message}`);
|
|
2579
|
+
throw new import_node_server_utils16.BadRequestError(error.message);
|
|
2323
2580
|
}
|
|
2324
2581
|
if (value.schedule) {
|
|
2325
2582
|
try {
|
|
2326
2583
|
value.schedule = new import_mongodb8.ObjectId(value.schedule);
|
|
2327
2584
|
} catch (error2) {
|
|
2328
|
-
throw new
|
|
2585
|
+
throw new import_node_server_utils16.BadRequestError("Invalid schedule ID format.");
|
|
2329
2586
|
}
|
|
2330
2587
|
}
|
|
2331
2588
|
if (value.area) {
|
|
2332
2589
|
try {
|
|
2333
2590
|
value.area = new import_mongodb8.ObjectId(value.area);
|
|
2334
2591
|
} catch (error2) {
|
|
2335
|
-
throw new
|
|
2592
|
+
throw new import_node_server_utils16.BadRequestError("Invalid area ID format.");
|
|
2336
2593
|
}
|
|
2337
2594
|
}
|
|
2338
2595
|
if (value.checklist && Array.isArray(value.checklist)) {
|
|
@@ -2354,7 +2611,7 @@ function MAreaChecklist(value) {
|
|
|
2354
2611
|
try {
|
|
2355
2612
|
value.createdBy = new import_mongodb8.ObjectId(value.createdBy);
|
|
2356
2613
|
} catch (error2) {
|
|
2357
|
-
throw new
|
|
2614
|
+
throw new import_node_server_utils16.BadRequestError("Invalid createdBy ID format.");
|
|
2358
2615
|
}
|
|
2359
2616
|
}
|
|
2360
2617
|
return {
|
|
@@ -2372,19 +2629,19 @@ function MAreaChecklist(value) {
|
|
|
2372
2629
|
}
|
|
2373
2630
|
|
|
2374
2631
|
// src/services/hygiene-area-checklist.service.ts
|
|
2375
|
-
var
|
|
2632
|
+
var import_node_server_utils18 = require("@7365admin1/node-server-utils");
|
|
2376
2633
|
|
|
2377
2634
|
// src/repositories/hygiene-area-checklist.repository.ts
|
|
2378
2635
|
var import_mongodb9 = require("mongodb");
|
|
2379
|
-
var
|
|
2636
|
+
var import_node_server_utils17 = require("@7365admin1/node-server-utils");
|
|
2380
2637
|
function useAreaChecklistRepo() {
|
|
2381
|
-
const db =
|
|
2638
|
+
const db = import_node_server_utils17.useAtlas.getDb();
|
|
2382
2639
|
if (!db) {
|
|
2383
|
-
throw new
|
|
2640
|
+
throw new import_node_server_utils17.InternalServerError("Unable to connect to server.");
|
|
2384
2641
|
}
|
|
2385
2642
|
const namespace_collection = "site.cleaning.schedule.areas";
|
|
2386
2643
|
const collection = db.collection(namespace_collection);
|
|
2387
|
-
const { delNamespace, setCache, getCache } = (0,
|
|
2644
|
+
const { delNamespace, setCache, getCache } = (0, import_node_server_utils17.useCache)(namespace_collection);
|
|
2388
2645
|
async function createIndex() {
|
|
2389
2646
|
try {
|
|
2390
2647
|
await collection.createIndexes([
|
|
@@ -2396,7 +2653,7 @@ function useAreaChecklistRepo() {
|
|
|
2396
2653
|
{ key: { "checklist.units.status": 1 } }
|
|
2397
2654
|
]);
|
|
2398
2655
|
} catch (error) {
|
|
2399
|
-
throw new
|
|
2656
|
+
throw new import_node_server_utils17.InternalServerError(
|
|
2400
2657
|
"Failed to create index on hygiene checklist area."
|
|
2401
2658
|
);
|
|
2402
2659
|
}
|
|
@@ -2409,7 +2666,7 @@ function useAreaChecklistRepo() {
|
|
|
2409
2666
|
"checklist.units.remarks": "text"
|
|
2410
2667
|
});
|
|
2411
2668
|
} catch (error) {
|
|
2412
|
-
throw new
|
|
2669
|
+
throw new import_node_server_utils17.InternalServerError(
|
|
2413
2670
|
"Failed to create text index on hygiene checklist area."
|
|
2414
2671
|
);
|
|
2415
2672
|
}
|
|
@@ -2432,7 +2689,7 @@ function useAreaChecklistRepo() {
|
|
|
2432
2689
|
}
|
|
2433
2690
|
});
|
|
2434
2691
|
if (existingChecklist) {
|
|
2435
|
-
|
|
2692
|
+
import_node_server_utils17.logger.info(
|
|
2436
2693
|
`Area checklist already exists for area ${value.name} on ${currentDate.toISOString().split("T")[0]}`
|
|
2437
2694
|
);
|
|
2438
2695
|
return existingChecklist._id;
|
|
@@ -2440,9 +2697,9 @@ function useAreaChecklistRepo() {
|
|
|
2440
2697
|
const processedValue = MAreaChecklist(value);
|
|
2441
2698
|
const result = await collection.insertOne(processedValue, { session });
|
|
2442
2699
|
delNamespace().then(() => {
|
|
2443
|
-
|
|
2700
|
+
import_node_server_utils17.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
2444
2701
|
}).catch((err) => {
|
|
2445
|
-
|
|
2702
|
+
import_node_server_utils17.logger.error(
|
|
2446
2703
|
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
2447
2704
|
err
|
|
2448
2705
|
);
|
|
@@ -2470,7 +2727,7 @@ function useAreaChecklistRepo() {
|
|
|
2470
2727
|
query.schedule = new import_mongodb9.ObjectId(schedule);
|
|
2471
2728
|
cacheOptions.schedule = schedule.toString();
|
|
2472
2729
|
} catch (error) {
|
|
2473
|
-
throw new
|
|
2730
|
+
throw new import_node_server_utils17.BadRequestError("Invalid parent checklist ID format.");
|
|
2474
2731
|
}
|
|
2475
2732
|
if (type && type !== "all") {
|
|
2476
2733
|
query.type = type;
|
|
@@ -2484,11 +2741,11 @@ function useAreaChecklistRepo() {
|
|
|
2484
2741
|
query.$text = { $search: search };
|
|
2485
2742
|
cacheOptions.search = search;
|
|
2486
2743
|
}
|
|
2487
|
-
const cacheKey = (0,
|
|
2744
|
+
const cacheKey = (0, import_node_server_utils17.makeCacheKey)(namespace_collection, cacheOptions);
|
|
2488
2745
|
if (!session) {
|
|
2489
2746
|
const cachedData = await getCache(cacheKey);
|
|
2490
2747
|
if (cachedData) {
|
|
2491
|
-
|
|
2748
|
+
import_node_server_utils17.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
2492
2749
|
return cachedData;
|
|
2493
2750
|
}
|
|
2494
2751
|
}
|
|
@@ -2562,11 +2819,11 @@ function useAreaChecklistRepo() {
|
|
|
2562
2819
|
];
|
|
2563
2820
|
const items = await collection.aggregate(pipeline, { session }).toArray();
|
|
2564
2821
|
const length = await collection.countDocuments(query, { session });
|
|
2565
|
-
const data = (0,
|
|
2822
|
+
const data = (0, import_node_server_utils17.paginate)(items, page, limit, length);
|
|
2566
2823
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
2567
|
-
|
|
2824
|
+
import_node_server_utils17.logger.info(`Cache set for key: ${cacheKey}`);
|
|
2568
2825
|
}).catch((err) => {
|
|
2569
|
-
|
|
2826
|
+
import_node_server_utils17.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
2570
2827
|
});
|
|
2571
2828
|
return data;
|
|
2572
2829
|
} catch (error) {
|
|
@@ -2592,7 +2849,7 @@ function useAreaChecklistRepo() {
|
|
|
2592
2849
|
query.schedule = new import_mongodb9.ObjectId(schedule);
|
|
2593
2850
|
cacheOptions.schedule = schedule.toString();
|
|
2594
2851
|
} catch (error) {
|
|
2595
|
-
throw new
|
|
2852
|
+
throw new import_node_server_utils17.BadRequestError("Invalid parent checklist ID format.");
|
|
2596
2853
|
}
|
|
2597
2854
|
if (type) {
|
|
2598
2855
|
query.type = type;
|
|
@@ -2615,10 +2872,10 @@ function useAreaChecklistRepo() {
|
|
|
2615
2872
|
} else {
|
|
2616
2873
|
query.status = { $in: ["ongoing", "completed"] };
|
|
2617
2874
|
}
|
|
2618
|
-
const cacheKey = (0,
|
|
2875
|
+
const cacheKey = (0, import_node_server_utils17.makeCacheKey)(namespace_collection, cacheOptions);
|
|
2619
2876
|
const cachedData = await getCache(cacheKey);
|
|
2620
2877
|
if (cachedData) {
|
|
2621
|
-
|
|
2878
|
+
import_node_server_utils17.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
2622
2879
|
return cachedData;
|
|
2623
2880
|
}
|
|
2624
2881
|
try {
|
|
@@ -2666,11 +2923,11 @@ function useAreaChecklistRepo() {
|
|
|
2666
2923
|
];
|
|
2667
2924
|
const items = await collection.aggregate(pipeline).toArray();
|
|
2668
2925
|
const length = await collection.countDocuments(query);
|
|
2669
|
-
const data = (0,
|
|
2926
|
+
const data = (0, import_node_server_utils17.paginate)(items, page, limit, length);
|
|
2670
2927
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
2671
|
-
|
|
2928
|
+
import_node_server_utils17.logger.info(`Cache set for key: ${cacheKey}`);
|
|
2672
2929
|
}).catch((err) => {
|
|
2673
|
-
|
|
2930
|
+
import_node_server_utils17.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
2674
2931
|
});
|
|
2675
2932
|
return data;
|
|
2676
2933
|
} catch (error) {
|
|
@@ -2681,14 +2938,14 @@ function useAreaChecklistRepo() {
|
|
|
2681
2938
|
try {
|
|
2682
2939
|
_id = new import_mongodb9.ObjectId(_id);
|
|
2683
2940
|
} catch (error) {
|
|
2684
|
-
throw new
|
|
2941
|
+
throw new import_node_server_utils17.BadRequestError("Invalid area checklist ID format.");
|
|
2685
2942
|
}
|
|
2686
|
-
const cacheKey = (0,
|
|
2943
|
+
const cacheKey = (0, import_node_server_utils17.makeCacheKey)(namespace_collection, {
|
|
2687
2944
|
_id: _id.toString()
|
|
2688
2945
|
});
|
|
2689
2946
|
const cachedData = await getCache(cacheKey);
|
|
2690
2947
|
if (cachedData) {
|
|
2691
|
-
|
|
2948
|
+
import_node_server_utils17.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
2692
2949
|
return cachedData;
|
|
2693
2950
|
}
|
|
2694
2951
|
try {
|
|
@@ -2811,16 +3068,16 @@ function useAreaChecklistRepo() {
|
|
|
2811
3068
|
collection.aggregate(unitPipeline).toArray()
|
|
2812
3069
|
]);
|
|
2813
3070
|
if (!area.length) {
|
|
2814
|
-
throw new
|
|
3071
|
+
throw new import_node_server_utils17.BadRequestError("Area checklist not found.");
|
|
2815
3072
|
}
|
|
2816
3073
|
const items = {
|
|
2817
3074
|
area: area[0],
|
|
2818
3075
|
units
|
|
2819
3076
|
};
|
|
2820
3077
|
setCache(cacheKey, items, 15 * 60).then(() => {
|
|
2821
|
-
|
|
3078
|
+
import_node_server_utils17.logger.info(`Cache set for key: ${cacheKey}`);
|
|
2822
3079
|
}).catch((err) => {
|
|
2823
|
-
|
|
3080
|
+
import_node_server_utils17.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
2824
3081
|
});
|
|
2825
3082
|
return items;
|
|
2826
3083
|
} catch (error) {
|
|
@@ -2843,17 +3100,17 @@ function useAreaChecklistRepo() {
|
|
|
2843
3100
|
query._id = new import_mongodb9.ObjectId(_id);
|
|
2844
3101
|
cacheOptions._id = _id.toString();
|
|
2845
3102
|
} catch (error) {
|
|
2846
|
-
throw new
|
|
3103
|
+
throw new import_node_server_utils17.BadRequestError("Invalid area checklist ID format.");
|
|
2847
3104
|
}
|
|
2848
3105
|
if (search) {
|
|
2849
3106
|
query.$text = { $search: search };
|
|
2850
3107
|
cacheOptions.search = search;
|
|
2851
3108
|
}
|
|
2852
|
-
const cacheKey = (0,
|
|
3109
|
+
const cacheKey = (0, import_node_server_utils17.makeCacheKey)(namespace_collection, cacheOptions);
|
|
2853
3110
|
if (!session) {
|
|
2854
3111
|
const cachedData = await getCache(cacheKey);
|
|
2855
3112
|
if (cachedData) {
|
|
2856
|
-
|
|
3113
|
+
import_node_server_utils17.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
2857
3114
|
return cachedData;
|
|
2858
3115
|
}
|
|
2859
3116
|
}
|
|
@@ -2941,11 +3198,11 @@ function useAreaChecklistRepo() {
|
|
|
2941
3198
|
collection.aggregate(countPipeline, { session }).toArray()
|
|
2942
3199
|
]);
|
|
2943
3200
|
const length = countResult.length > 0 ? countResult[0].total : 0;
|
|
2944
|
-
const data = (0,
|
|
3201
|
+
const data = (0, import_node_server_utils17.paginate)(items, page, limit, length);
|
|
2945
3202
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
2946
|
-
|
|
3203
|
+
import_node_server_utils17.logger.info(`Cache set for key: ${cacheKey}`);
|
|
2947
3204
|
}).catch((err) => {
|
|
2948
|
-
|
|
3205
|
+
import_node_server_utils17.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
2949
3206
|
});
|
|
2950
3207
|
return data;
|
|
2951
3208
|
} catch (error) {
|
|
@@ -2956,7 +3213,7 @@ function useAreaChecklistRepo() {
|
|
|
2956
3213
|
try {
|
|
2957
3214
|
_id = new import_mongodb9.ObjectId(_id);
|
|
2958
3215
|
} catch (error) {
|
|
2959
|
-
throw new
|
|
3216
|
+
throw new import_node_server_utils17.BadRequestError("Invalid area checklist ID format.");
|
|
2960
3217
|
}
|
|
2961
3218
|
try {
|
|
2962
3219
|
const area = await collection.findOne(
|
|
@@ -2964,7 +3221,7 @@ function useAreaChecklistRepo() {
|
|
|
2964
3221
|
{ projection: { schedule: 1, name: 1, type: 1, status: 1 }, session }
|
|
2965
3222
|
);
|
|
2966
3223
|
if (!area) {
|
|
2967
|
-
throw new
|
|
3224
|
+
throw new import_node_server_utils17.BadRequestError("Area checklist not found.");
|
|
2968
3225
|
}
|
|
2969
3226
|
return area;
|
|
2970
3227
|
} catch (error) {
|
|
@@ -2976,12 +3233,12 @@ function useAreaChecklistRepo() {
|
|
|
2976
3233
|
schedule = new import_mongodb9.ObjectId(schedule);
|
|
2977
3234
|
area = new import_mongodb9.ObjectId(area);
|
|
2978
3235
|
} catch (error) {
|
|
2979
|
-
throw new
|
|
3236
|
+
throw new import_node_server_utils17.BadRequestError("Invalid area checklist ID format.");
|
|
2980
3237
|
}
|
|
2981
3238
|
try {
|
|
2982
3239
|
const data = await collection.findOne({ schedule, area }, { session });
|
|
2983
3240
|
if (!data) {
|
|
2984
|
-
throw new
|
|
3241
|
+
throw new import_node_server_utils17.BadRequestError("Area checklist not found.");
|
|
2985
3242
|
}
|
|
2986
3243
|
return data;
|
|
2987
3244
|
} catch (error) {
|
|
@@ -2992,12 +3249,12 @@ function useAreaChecklistRepo() {
|
|
|
2992
3249
|
try {
|
|
2993
3250
|
_id = new import_mongodb9.ObjectId(_id);
|
|
2994
3251
|
} catch (error) {
|
|
2995
|
-
throw new
|
|
3252
|
+
throw new import_node_server_utils17.BadRequestError("Invalid area checklist ID format.");
|
|
2996
3253
|
}
|
|
2997
3254
|
try {
|
|
2998
3255
|
unitId = new import_mongodb9.ObjectId(unitId);
|
|
2999
3256
|
} catch (error) {
|
|
3000
|
-
throw new
|
|
3257
|
+
throw new import_node_server_utils17.BadRequestError("Invalid unit checklist ID format.");
|
|
3001
3258
|
}
|
|
3002
3259
|
try {
|
|
3003
3260
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -3022,19 +3279,19 @@ function useAreaChecklistRepo() {
|
|
|
3022
3279
|
{ arrayFilters, session }
|
|
3023
3280
|
);
|
|
3024
3281
|
if (res.modifiedCount === 0) {
|
|
3025
|
-
throw new
|
|
3282
|
+
throw new import_node_server_utils17.InternalServerError("Unable to update area checklist unit.");
|
|
3026
3283
|
}
|
|
3027
3284
|
delNamespace().then(() => {
|
|
3028
|
-
|
|
3285
|
+
import_node_server_utils17.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
3029
3286
|
}).catch((err) => {
|
|
3030
|
-
|
|
3287
|
+
import_node_server_utils17.logger.error(
|
|
3031
3288
|
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
3032
3289
|
err
|
|
3033
3290
|
);
|
|
3034
3291
|
});
|
|
3035
3292
|
return res.modifiedCount;
|
|
3036
3293
|
} catch (error) {
|
|
3037
|
-
|
|
3294
|
+
import_node_server_utils17.logger.error("Error updating area checklist unit:", error.message);
|
|
3038
3295
|
throw error;
|
|
3039
3296
|
}
|
|
3040
3297
|
}
|
|
@@ -3042,7 +3299,7 @@ function useAreaChecklistRepo() {
|
|
|
3042
3299
|
try {
|
|
3043
3300
|
_id = new import_mongodb9.ObjectId(_id);
|
|
3044
3301
|
} catch (error) {
|
|
3045
|
-
throw new
|
|
3302
|
+
throw new import_node_server_utils17.BadRequestError("Invalid area checklist ID format.");
|
|
3046
3303
|
}
|
|
3047
3304
|
try {
|
|
3048
3305
|
const updateValue = {
|
|
@@ -3055,12 +3312,12 @@ function useAreaChecklistRepo() {
|
|
|
3055
3312
|
{ session }
|
|
3056
3313
|
);
|
|
3057
3314
|
if (res.modifiedCount === 0) {
|
|
3058
|
-
throw new
|
|
3315
|
+
throw new import_node_server_utils17.InternalServerError("Unable to update area checklist.");
|
|
3059
3316
|
}
|
|
3060
3317
|
delNamespace().then(() => {
|
|
3061
|
-
|
|
3318
|
+
import_node_server_utils17.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
3062
3319
|
}).catch((err) => {
|
|
3063
|
-
|
|
3320
|
+
import_node_server_utils17.logger.error(
|
|
3064
3321
|
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
3065
3322
|
err
|
|
3066
3323
|
);
|
|
@@ -3074,7 +3331,7 @@ function useAreaChecklistRepo() {
|
|
|
3074
3331
|
try {
|
|
3075
3332
|
_id = new import_mongodb9.ObjectId(_id);
|
|
3076
3333
|
} catch (error) {
|
|
3077
|
-
throw new
|
|
3334
|
+
throw new import_node_server_utils17.BadRequestError("Invalid area checklist ID format.");
|
|
3078
3335
|
}
|
|
3079
3336
|
try {
|
|
3080
3337
|
const updateValue = {
|
|
@@ -3090,14 +3347,14 @@ function useAreaChecklistRepo() {
|
|
|
3090
3347
|
{ session }
|
|
3091
3348
|
);
|
|
3092
3349
|
if (res.modifiedCount === 0) {
|
|
3093
|
-
throw new
|
|
3350
|
+
throw new import_node_server_utils17.InternalServerError(
|
|
3094
3351
|
"Unable to update area checklist status."
|
|
3095
3352
|
);
|
|
3096
3353
|
}
|
|
3097
3354
|
delNamespace().then(() => {
|
|
3098
|
-
|
|
3355
|
+
import_node_server_utils17.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
3099
3356
|
}).catch((err) => {
|
|
3100
|
-
|
|
3357
|
+
import_node_server_utils17.logger.error(
|
|
3101
3358
|
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
3102
3359
|
err
|
|
3103
3360
|
);
|
|
@@ -3120,7 +3377,7 @@ function useAreaChecklistRepo() {
|
|
|
3120
3377
|
).toArray();
|
|
3121
3378
|
return result.length > 0 && result[0].maxSet ? result[0].maxSet : 0;
|
|
3122
3379
|
} catch (error) {
|
|
3123
|
-
|
|
3380
|
+
import_node_server_utils17.logger.error(`Error getting max set number for area ${areaId}:`, error);
|
|
3124
3381
|
return 0;
|
|
3125
3382
|
}
|
|
3126
3383
|
}
|
|
@@ -3155,7 +3412,7 @@ function useAreaChecklistService() {
|
|
|
3155
3412
|
} = useAreaChecklistRepo();
|
|
3156
3413
|
const { updateParentChecklistStatuses } = useParentChecklistRepo();
|
|
3157
3414
|
async function createAreaChecklist(value) {
|
|
3158
|
-
const session =
|
|
3415
|
+
const session = import_node_server_utils18.useAtlas.getClient()?.startSession();
|
|
3159
3416
|
try {
|
|
3160
3417
|
session?.startTransaction();
|
|
3161
3418
|
const results = [];
|
|
@@ -3168,7 +3425,7 @@ function useAreaChecklistService() {
|
|
|
3168
3425
|
const batch = areas.slice(i, i + BATCH_SIZE);
|
|
3169
3426
|
const batchPromises = batch.map(async (area) => {
|
|
3170
3427
|
if (!area.units || area.units.length === 0) {
|
|
3171
|
-
|
|
3428
|
+
import_node_server_utils18.logger.warn(
|
|
3172
3429
|
`Skipping area ${area.name} (${area._id}): No units defined`
|
|
3173
3430
|
);
|
|
3174
3431
|
return null;
|
|
@@ -3199,19 +3456,19 @@ function useAreaChecklistService() {
|
|
|
3199
3456
|
const batchResults = await Promise.all(batchPromises);
|
|
3200
3457
|
results.push(...batchResults.filter((id) => id !== null));
|
|
3201
3458
|
}
|
|
3202
|
-
|
|
3459
|
+
import_node_server_utils18.logger.info(
|
|
3203
3460
|
`Created ${totalChecklistsCreated} area checklists out of ${areas.length} areas for site: ${value.site}`
|
|
3204
3461
|
);
|
|
3205
3462
|
} else {
|
|
3206
|
-
|
|
3463
|
+
import_node_server_utils18.logger.warn(`No common areas found for site: ${value.site}`);
|
|
3207
3464
|
}
|
|
3208
3465
|
await session?.commitTransaction();
|
|
3209
|
-
|
|
3466
|
+
import_node_server_utils18.logger.info(
|
|
3210
3467
|
`Successfully created ${totalChecklistsCreated} area checklists for site: ${value.site}`
|
|
3211
3468
|
);
|
|
3212
3469
|
return results;
|
|
3213
3470
|
} catch (error) {
|
|
3214
|
-
|
|
3471
|
+
import_node_server_utils18.logger.error(`Error generating area checklists:`, error);
|
|
3215
3472
|
if (session?.inTransaction()) {
|
|
3216
3473
|
await session?.abortTransaction();
|
|
3217
3474
|
}
|
|
@@ -3221,7 +3478,7 @@ function useAreaChecklistService() {
|
|
|
3221
3478
|
}
|
|
3222
3479
|
}
|
|
3223
3480
|
async function completeAreaChecklistUnits(_id, set, unitId, value) {
|
|
3224
|
-
const session =
|
|
3481
|
+
const session = import_node_server_utils18.useAtlas.getClient()?.startSession();
|
|
3225
3482
|
try {
|
|
3226
3483
|
session?.startTransaction();
|
|
3227
3484
|
await _completeAreaChecklistUnits(_id, set, unitId, value, session);
|
|
@@ -3287,7 +3544,7 @@ function useAreaChecklistService() {
|
|
|
3287
3544
|
session
|
|
3288
3545
|
);
|
|
3289
3546
|
} else {
|
|
3290
|
-
|
|
3547
|
+
import_node_server_utils18.logger.info(
|
|
3291
3548
|
"No area checklists found, keeping parent status as ready"
|
|
3292
3549
|
);
|
|
3293
3550
|
}
|
|
@@ -3295,7 +3552,7 @@ function useAreaChecklistService() {
|
|
|
3295
3552
|
await session?.commitTransaction();
|
|
3296
3553
|
return;
|
|
3297
3554
|
} catch (error) {
|
|
3298
|
-
|
|
3555
|
+
import_node_server_utils18.logger.error(`Error updating area checklist unit and statuses:`, error);
|
|
3299
3556
|
if (session?.inTransaction()) {
|
|
3300
3557
|
await session?.abortTransaction();
|
|
3301
3558
|
}
|
|
@@ -3309,7 +3566,7 @@ function useAreaChecklistService() {
|
|
|
3309
3566
|
|
|
3310
3567
|
// src/controllers/hygiene-area-checklist.controller.ts
|
|
3311
3568
|
var import_joi9 = __toESM(require("joi"));
|
|
3312
|
-
var
|
|
3569
|
+
var import_node_server_utils19 = require("@7365admin1/node-server-utils");
|
|
3313
3570
|
function useAreaChecklistController() {
|
|
3314
3571
|
const {
|
|
3315
3572
|
getAllAreaChecklist: _getAllAreaChecklist,
|
|
@@ -3339,8 +3596,8 @@ function useAreaChecklistController() {
|
|
|
3339
3596
|
});
|
|
3340
3597
|
const { error, value } = validation.validate(payload);
|
|
3341
3598
|
if (error) {
|
|
3342
|
-
|
|
3343
|
-
next(new
|
|
3599
|
+
import_node_server_utils19.logger.log({ level: "error", message: error.message });
|
|
3600
|
+
next(new import_node_server_utils19.BadRequestError(error.message));
|
|
3344
3601
|
return;
|
|
3345
3602
|
}
|
|
3346
3603
|
try {
|
|
@@ -3348,7 +3605,7 @@ function useAreaChecklistController() {
|
|
|
3348
3605
|
res.status(201).json({ message: "Area checklist generated successfully." });
|
|
3349
3606
|
return;
|
|
3350
3607
|
} catch (error2) {
|
|
3351
|
-
|
|
3608
|
+
import_node_server_utils19.logger.log({ level: "error", message: error2.message });
|
|
3352
3609
|
next(error2);
|
|
3353
3610
|
return;
|
|
3354
3611
|
}
|
|
@@ -3365,8 +3622,8 @@ function useAreaChecklistController() {
|
|
|
3365
3622
|
});
|
|
3366
3623
|
const { error } = validation.validate(query);
|
|
3367
3624
|
if (error) {
|
|
3368
|
-
|
|
3369
|
-
next(new
|
|
3625
|
+
import_node_server_utils19.logger.log({ level: "error", message: error.message });
|
|
3626
|
+
next(new import_node_server_utils19.BadRequestError(error.message));
|
|
3370
3627
|
return;
|
|
3371
3628
|
}
|
|
3372
3629
|
const page = parseInt(req.query.page) ?? 1;
|
|
@@ -3387,7 +3644,7 @@ function useAreaChecklistController() {
|
|
|
3387
3644
|
res.json(data);
|
|
3388
3645
|
return;
|
|
3389
3646
|
} catch (error2) {
|
|
3390
|
-
|
|
3647
|
+
import_node_server_utils19.logger.log({ level: "error", message: error2.message });
|
|
3391
3648
|
next(error2);
|
|
3392
3649
|
return;
|
|
3393
3650
|
}
|
|
@@ -3405,8 +3662,8 @@ function useAreaChecklistController() {
|
|
|
3405
3662
|
});
|
|
3406
3663
|
const { error } = validation.validate(query);
|
|
3407
3664
|
if (error) {
|
|
3408
|
-
|
|
3409
|
-
next(new
|
|
3665
|
+
import_node_server_utils19.logger.log({ level: "error", message: error.message });
|
|
3666
|
+
next(new import_node_server_utils19.BadRequestError(error.message));
|
|
3410
3667
|
return;
|
|
3411
3668
|
}
|
|
3412
3669
|
const page = parseInt(req.query.page) ?? 1;
|
|
@@ -3429,7 +3686,7 @@ function useAreaChecklistController() {
|
|
|
3429
3686
|
res.json(data);
|
|
3430
3687
|
return;
|
|
3431
3688
|
} catch (error2) {
|
|
3432
|
-
|
|
3689
|
+
import_node_server_utils19.logger.log({ level: "error", message: error2.message });
|
|
3433
3690
|
next(error2);
|
|
3434
3691
|
return;
|
|
3435
3692
|
}
|
|
@@ -3439,8 +3696,8 @@ function useAreaChecklistController() {
|
|
|
3439
3696
|
const _id = req.params.id;
|
|
3440
3697
|
const { error, value } = validation.validate(_id);
|
|
3441
3698
|
if (error) {
|
|
3442
|
-
|
|
3443
|
-
next(new
|
|
3699
|
+
import_node_server_utils19.logger.log({ level: "error", message: error.message });
|
|
3700
|
+
next(new import_node_server_utils19.BadRequestError(error.message));
|
|
3444
3701
|
return;
|
|
3445
3702
|
}
|
|
3446
3703
|
try {
|
|
@@ -3448,7 +3705,7 @@ function useAreaChecklistController() {
|
|
|
3448
3705
|
res.json(data);
|
|
3449
3706
|
return;
|
|
3450
3707
|
} catch (error2) {
|
|
3451
|
-
|
|
3708
|
+
import_node_server_utils19.logger.log({ level: "error", message: error2.message });
|
|
3452
3709
|
next(error2);
|
|
3453
3710
|
return;
|
|
3454
3711
|
}
|
|
@@ -3463,8 +3720,8 @@ function useAreaChecklistController() {
|
|
|
3463
3720
|
});
|
|
3464
3721
|
const { error } = validation.validate(query);
|
|
3465
3722
|
if (error) {
|
|
3466
|
-
|
|
3467
|
-
next(new
|
|
3723
|
+
import_node_server_utils19.logger.log({ level: "error", message: error.message });
|
|
3724
|
+
next(new import_node_server_utils19.BadRequestError(error.message));
|
|
3468
3725
|
return;
|
|
3469
3726
|
}
|
|
3470
3727
|
const page = parseInt(req.query.page) ?? 1;
|
|
@@ -3481,7 +3738,7 @@ function useAreaChecklistController() {
|
|
|
3481
3738
|
res.json(data);
|
|
3482
3739
|
return;
|
|
3483
3740
|
} catch (error2) {
|
|
3484
|
-
|
|
3741
|
+
import_node_server_utils19.logger.log({ level: "error", message: error2.message });
|
|
3485
3742
|
next(error2);
|
|
3486
3743
|
return;
|
|
3487
3744
|
}
|
|
@@ -3506,8 +3763,8 @@ function useAreaChecklistController() {
|
|
|
3506
3763
|
});
|
|
3507
3764
|
const { error } = validation.validate(payload);
|
|
3508
3765
|
if (error) {
|
|
3509
|
-
|
|
3510
|
-
next(new
|
|
3766
|
+
import_node_server_utils19.logger.log({ level: "error", message: error.message });
|
|
3767
|
+
next(new import_node_server_utils19.BadRequestError(error.message));
|
|
3511
3768
|
return;
|
|
3512
3769
|
}
|
|
3513
3770
|
try {
|
|
@@ -3521,7 +3778,7 @@ function useAreaChecklistController() {
|
|
|
3521
3778
|
res.json({ message: "Area checklist updated successfully." });
|
|
3522
3779
|
return;
|
|
3523
3780
|
} catch (error2) {
|
|
3524
|
-
|
|
3781
|
+
import_node_server_utils19.logger.log({ level: "error", message: error2.message });
|
|
3525
3782
|
next(error2);
|
|
3526
3783
|
return;
|
|
3527
3784
|
}
|
|
@@ -3539,7 +3796,7 @@ function useAreaChecklistController() {
|
|
|
3539
3796
|
// src/models/hygiene-supply.model.ts
|
|
3540
3797
|
var import_joi10 = __toESM(require("joi"));
|
|
3541
3798
|
var import_mongodb10 = require("mongodb");
|
|
3542
|
-
var
|
|
3799
|
+
var import_node_server_utils20 = require("@7365admin1/node-server-utils");
|
|
3543
3800
|
var supplySchema = import_joi10.default.object({
|
|
3544
3801
|
site: import_joi10.default.string().hex().required(),
|
|
3545
3802
|
name: import_joi10.default.string().required(),
|
|
@@ -3548,14 +3805,14 @@ var supplySchema = import_joi10.default.object({
|
|
|
3548
3805
|
function MSupply(value) {
|
|
3549
3806
|
const { error } = supplySchema.validate(value);
|
|
3550
3807
|
if (error) {
|
|
3551
|
-
|
|
3552
|
-
throw new
|
|
3808
|
+
import_node_server_utils20.logger.info(`Hygiene Supply Model: ${error.message}`);
|
|
3809
|
+
throw new import_node_server_utils20.BadRequestError(error.message);
|
|
3553
3810
|
}
|
|
3554
3811
|
if (value.site) {
|
|
3555
3812
|
try {
|
|
3556
3813
|
value.site = new import_mongodb10.ObjectId(value.site);
|
|
3557
3814
|
} catch (error2) {
|
|
3558
|
-
throw new
|
|
3815
|
+
throw new import_node_server_utils20.BadRequestError("Invalid site ID format.");
|
|
3559
3816
|
}
|
|
3560
3817
|
}
|
|
3561
3818
|
return {
|
|
@@ -3572,20 +3829,20 @@ function MSupply(value) {
|
|
|
3572
3829
|
|
|
3573
3830
|
// src/repositories/hygiene-supply.repository.ts
|
|
3574
3831
|
var import_mongodb11 = require("mongodb");
|
|
3575
|
-
var
|
|
3832
|
+
var import_node_server_utils21 = require("@7365admin1/node-server-utils");
|
|
3576
3833
|
function useSupplyRepository() {
|
|
3577
|
-
const db =
|
|
3834
|
+
const db = import_node_server_utils21.useAtlas.getDb();
|
|
3578
3835
|
if (!db) {
|
|
3579
|
-
throw new
|
|
3836
|
+
throw new import_node_server_utils21.InternalServerError("Unable to connect to server.");
|
|
3580
3837
|
}
|
|
3581
3838
|
const namespace_collection = "site.supplies";
|
|
3582
3839
|
const collection = db.collection(namespace_collection);
|
|
3583
|
-
const { delNamespace, setCache, getCache } = (0,
|
|
3840
|
+
const { delNamespace, setCache, getCache } = (0, import_node_server_utils21.useCache)(namespace_collection);
|
|
3584
3841
|
async function createIndex() {
|
|
3585
3842
|
try {
|
|
3586
3843
|
await collection.createIndexes([{ key: { site: 1 } }]);
|
|
3587
3844
|
} catch (error) {
|
|
3588
|
-
throw new
|
|
3845
|
+
throw new import_node_server_utils21.InternalServerError(
|
|
3589
3846
|
"Failed to create index on hygiene supply."
|
|
3590
3847
|
);
|
|
3591
3848
|
}
|
|
@@ -3594,7 +3851,7 @@ function useSupplyRepository() {
|
|
|
3594
3851
|
try {
|
|
3595
3852
|
await collection.createIndex({ name: "text" });
|
|
3596
3853
|
} catch (error) {
|
|
3597
|
-
throw new
|
|
3854
|
+
throw new import_node_server_utils21.InternalServerError(
|
|
3598
3855
|
"Failed to create text index on hygiene supply."
|
|
3599
3856
|
);
|
|
3600
3857
|
}
|
|
@@ -3606,7 +3863,7 @@ function useSupplyRepository() {
|
|
|
3606
3863
|
{ unique: true }
|
|
3607
3864
|
);
|
|
3608
3865
|
} catch (error) {
|
|
3609
|
-
throw new
|
|
3866
|
+
throw new import_node_server_utils21.InternalServerError(
|
|
3610
3867
|
"Failed to create unique index on hygiene supply."
|
|
3611
3868
|
);
|
|
3612
3869
|
}
|
|
@@ -3616,9 +3873,9 @@ function useSupplyRepository() {
|
|
|
3616
3873
|
value = MSupply(value);
|
|
3617
3874
|
const res = await collection.insertOne(value, { session });
|
|
3618
3875
|
delNamespace().then(() => {
|
|
3619
|
-
|
|
3876
|
+
import_node_server_utils21.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
3620
3877
|
}).catch((err) => {
|
|
3621
|
-
|
|
3878
|
+
import_node_server_utils21.logger.error(
|
|
3622
3879
|
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
3623
3880
|
err
|
|
3624
3881
|
);
|
|
@@ -3627,7 +3884,7 @@ function useSupplyRepository() {
|
|
|
3627
3884
|
} catch (error) {
|
|
3628
3885
|
const isDuplicated = error.message.includes("duplicate");
|
|
3629
3886
|
if (isDuplicated) {
|
|
3630
|
-
throw new
|
|
3887
|
+
throw new import_node_server_utils21.BadRequestError("Supply already exists.");
|
|
3631
3888
|
}
|
|
3632
3889
|
throw error;
|
|
3633
3890
|
}
|
|
@@ -3651,16 +3908,16 @@ function useSupplyRepository() {
|
|
|
3651
3908
|
query.site = site;
|
|
3652
3909
|
cacheOptions.site = site.toString();
|
|
3653
3910
|
} catch (error) {
|
|
3654
|
-
throw new
|
|
3911
|
+
throw new import_node_server_utils21.BadRequestError("Invalid site ID format.");
|
|
3655
3912
|
}
|
|
3656
3913
|
if (search) {
|
|
3657
3914
|
query.$text = { $search: search };
|
|
3658
3915
|
cacheOptions.search = search;
|
|
3659
3916
|
}
|
|
3660
|
-
const cacheKey = (0,
|
|
3917
|
+
const cacheKey = (0, import_node_server_utils21.makeCacheKey)(namespace_collection, cacheOptions);
|
|
3661
3918
|
const cachedData = await getCache(cacheKey);
|
|
3662
3919
|
if (cachedData) {
|
|
3663
|
-
|
|
3920
|
+
import_node_server_utils21.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
3664
3921
|
return cachedData;
|
|
3665
3922
|
}
|
|
3666
3923
|
try {
|
|
@@ -3678,11 +3935,11 @@ function useSupplyRepository() {
|
|
|
3678
3935
|
{ $limit: limit }
|
|
3679
3936
|
]).toArray();
|
|
3680
3937
|
const length = await collection.countDocuments(query);
|
|
3681
|
-
const data = (0,
|
|
3938
|
+
const data = (0, import_node_server_utils21.paginate)(items, page, limit, length);
|
|
3682
3939
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
3683
|
-
|
|
3940
|
+
import_node_server_utils21.logger.info(`Cache set for key: ${cacheKey}`);
|
|
3684
3941
|
}).catch((err) => {
|
|
3685
|
-
|
|
3942
|
+
import_node_server_utils21.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
3686
3943
|
});
|
|
3687
3944
|
return data;
|
|
3688
3945
|
} catch (error) {
|
|
@@ -3693,23 +3950,23 @@ function useSupplyRepository() {
|
|
|
3693
3950
|
try {
|
|
3694
3951
|
_id = new import_mongodb11.ObjectId(_id);
|
|
3695
3952
|
} catch (error) {
|
|
3696
|
-
throw new
|
|
3953
|
+
throw new import_node_server_utils21.BadRequestError("Invalid supply ID format.");
|
|
3697
3954
|
}
|
|
3698
3955
|
const query = {
|
|
3699
3956
|
_id,
|
|
3700
3957
|
status: { $ne: "deleted" }
|
|
3701
3958
|
};
|
|
3702
|
-
const cacheKey = (0,
|
|
3959
|
+
const cacheKey = (0, import_node_server_utils21.makeCacheKey)(namespace_collection, {
|
|
3703
3960
|
_id: _id.toString()
|
|
3704
3961
|
});
|
|
3705
3962
|
if (!session) {
|
|
3706
3963
|
const cachedData = await getCache(cacheKey);
|
|
3707
3964
|
if (cachedData) {
|
|
3708
|
-
|
|
3965
|
+
import_node_server_utils21.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
3709
3966
|
return cachedData;
|
|
3710
3967
|
}
|
|
3711
3968
|
} else {
|
|
3712
|
-
|
|
3969
|
+
import_node_server_utils21.logger.info(`Skipping cache during transaction for key: ${cacheKey}`);
|
|
3713
3970
|
}
|
|
3714
3971
|
try {
|
|
3715
3972
|
const data = await collection.aggregate([
|
|
@@ -3723,12 +3980,12 @@ function useSupplyRepository() {
|
|
|
3723
3980
|
}
|
|
3724
3981
|
]).toArray();
|
|
3725
3982
|
if (!data || data.length === 0) {
|
|
3726
|
-
throw new
|
|
3983
|
+
throw new import_node_server_utils21.NotFoundError("Supply not found.");
|
|
3727
3984
|
}
|
|
3728
3985
|
setCache(cacheKey, data[0], 15 * 60).then(() => {
|
|
3729
|
-
|
|
3986
|
+
import_node_server_utils21.logger.info(`Cache set for key: ${cacheKey}`);
|
|
3730
3987
|
}).catch((err) => {
|
|
3731
|
-
|
|
3988
|
+
import_node_server_utils21.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
3732
3989
|
});
|
|
3733
3990
|
return data[0];
|
|
3734
3991
|
} catch (error) {
|
|
@@ -3739,7 +3996,7 @@ function useSupplyRepository() {
|
|
|
3739
3996
|
try {
|
|
3740
3997
|
_id = new import_mongodb11.ObjectId(_id);
|
|
3741
3998
|
} catch (error) {
|
|
3742
|
-
throw new
|
|
3999
|
+
throw new import_node_server_utils21.BadRequestError("Invalid supply ID format.");
|
|
3743
4000
|
}
|
|
3744
4001
|
try {
|
|
3745
4002
|
const updateValue = { ...value, updatedAt: /* @__PURE__ */ new Date() };
|
|
@@ -3749,12 +4006,12 @@ function useSupplyRepository() {
|
|
|
3749
4006
|
{ session }
|
|
3750
4007
|
);
|
|
3751
4008
|
if (res.modifiedCount === 0) {
|
|
3752
|
-
throw new
|
|
4009
|
+
throw new import_node_server_utils21.InternalServerError("Unable to update cleaning supply.");
|
|
3753
4010
|
}
|
|
3754
4011
|
delNamespace().then(() => {
|
|
3755
|
-
|
|
4012
|
+
import_node_server_utils21.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
3756
4013
|
}).catch((err) => {
|
|
3757
|
-
|
|
4014
|
+
import_node_server_utils21.logger.error(
|
|
3758
4015
|
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
3759
4016
|
err
|
|
3760
4017
|
);
|
|
@@ -3763,7 +4020,7 @@ function useSupplyRepository() {
|
|
|
3763
4020
|
} catch (error) {
|
|
3764
4021
|
const isDuplicated = error.message.includes("duplicate");
|
|
3765
4022
|
if (isDuplicated) {
|
|
3766
|
-
throw new
|
|
4023
|
+
throw new import_node_server_utils21.BadRequestError("Supply already exists.");
|
|
3767
4024
|
}
|
|
3768
4025
|
throw error;
|
|
3769
4026
|
}
|
|
@@ -3772,7 +4029,7 @@ function useSupplyRepository() {
|
|
|
3772
4029
|
try {
|
|
3773
4030
|
_id = new import_mongodb11.ObjectId(_id);
|
|
3774
4031
|
} catch (error) {
|
|
3775
|
-
throw new
|
|
4032
|
+
throw new import_node_server_utils21.BadRequestError("Invalid supply ID format.");
|
|
3776
4033
|
}
|
|
3777
4034
|
try {
|
|
3778
4035
|
const updateValue = {
|
|
@@ -3786,12 +4043,12 @@ function useSupplyRepository() {
|
|
|
3786
4043
|
{ session }
|
|
3787
4044
|
);
|
|
3788
4045
|
if (res.modifiedCount === 0) {
|
|
3789
|
-
throw new
|
|
4046
|
+
throw new import_node_server_utils21.InternalServerError("Unable to delete supply.");
|
|
3790
4047
|
}
|
|
3791
4048
|
delNamespace().then(() => {
|
|
3792
|
-
|
|
4049
|
+
import_node_server_utils21.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
3793
4050
|
}).catch((err) => {
|
|
3794
|
-
|
|
4051
|
+
import_node_server_utils21.logger.error(
|
|
3795
4052
|
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
3796
4053
|
err
|
|
3797
4054
|
);
|
|
@@ -3815,7 +4072,7 @@ function useSupplyRepository() {
|
|
|
3815
4072
|
|
|
3816
4073
|
// src/controllers/hygiene-supply.controller.ts
|
|
3817
4074
|
var import_joi11 = __toESM(require("joi"));
|
|
3818
|
-
var
|
|
4075
|
+
var import_node_server_utils22 = require("@7365admin1/node-server-utils");
|
|
3819
4076
|
function useSupplyController() {
|
|
3820
4077
|
const {
|
|
3821
4078
|
createSupply: _createSupply,
|
|
@@ -3828,8 +4085,8 @@ function useSupplyController() {
|
|
|
3828
4085
|
const payload = { ...req.body, ...req.params };
|
|
3829
4086
|
const { error } = supplySchema.validate(payload);
|
|
3830
4087
|
if (error) {
|
|
3831
|
-
|
|
3832
|
-
next(new
|
|
4088
|
+
import_node_server_utils22.logger.log({ level: "error", message: error.message });
|
|
4089
|
+
next(new import_node_server_utils22.BadRequestError(error.message));
|
|
3833
4090
|
return;
|
|
3834
4091
|
}
|
|
3835
4092
|
try {
|
|
@@ -3837,7 +4094,7 @@ function useSupplyController() {
|
|
|
3837
4094
|
res.status(201).json({ message: "Supply created successfully.", id });
|
|
3838
4095
|
return;
|
|
3839
4096
|
} catch (error2) {
|
|
3840
|
-
|
|
4097
|
+
import_node_server_utils22.logger.log({ level: "error", message: error2.message });
|
|
3841
4098
|
next(error2);
|
|
3842
4099
|
return;
|
|
3843
4100
|
}
|
|
@@ -3852,8 +4109,8 @@ function useSupplyController() {
|
|
|
3852
4109
|
});
|
|
3853
4110
|
const { error } = validation.validate(query);
|
|
3854
4111
|
if (error) {
|
|
3855
|
-
|
|
3856
|
-
next(new
|
|
4112
|
+
import_node_server_utils22.logger.log({ level: "error", message: error.message });
|
|
4113
|
+
next(new import_node_server_utils22.BadRequestError(error.message));
|
|
3857
4114
|
return;
|
|
3858
4115
|
}
|
|
3859
4116
|
const page = parseInt(req.query.page) ?? 1;
|
|
@@ -3870,7 +4127,7 @@ function useSupplyController() {
|
|
|
3870
4127
|
res.json(data);
|
|
3871
4128
|
return;
|
|
3872
4129
|
} catch (error2) {
|
|
3873
|
-
|
|
4130
|
+
import_node_server_utils22.logger.log({ level: "error", message: error2.message });
|
|
3874
4131
|
next(error2);
|
|
3875
4132
|
return;
|
|
3876
4133
|
}
|
|
@@ -3880,8 +4137,8 @@ function useSupplyController() {
|
|
|
3880
4137
|
const _id = req.params.id;
|
|
3881
4138
|
const { error, value } = validation.validate(_id);
|
|
3882
4139
|
if (error) {
|
|
3883
|
-
|
|
3884
|
-
next(new
|
|
4140
|
+
import_node_server_utils22.logger.log({ level: "error", message: error.message });
|
|
4141
|
+
next(new import_node_server_utils22.BadRequestError(error.message));
|
|
3885
4142
|
return;
|
|
3886
4143
|
}
|
|
3887
4144
|
try {
|
|
@@ -3889,7 +4146,7 @@ function useSupplyController() {
|
|
|
3889
4146
|
res.json(data);
|
|
3890
4147
|
return;
|
|
3891
4148
|
} catch (error2) {
|
|
3892
|
-
|
|
4149
|
+
import_node_server_utils22.logger.log({ level: "error", message: error2.message });
|
|
3893
4150
|
next(error2);
|
|
3894
4151
|
return;
|
|
3895
4152
|
}
|
|
@@ -3904,8 +4161,8 @@ function useSupplyController() {
|
|
|
3904
4161
|
});
|
|
3905
4162
|
const { error } = validation.validate(payload);
|
|
3906
4163
|
if (error) {
|
|
3907
|
-
|
|
3908
|
-
next(new
|
|
4164
|
+
import_node_server_utils22.logger.log({ level: "error", message: error.message });
|
|
4165
|
+
next(new import_node_server_utils22.BadRequestError(error.message));
|
|
3909
4166
|
return;
|
|
3910
4167
|
}
|
|
3911
4168
|
try {
|
|
@@ -3914,7 +4171,7 @@ function useSupplyController() {
|
|
|
3914
4171
|
res.json({ message: "Supply updated successfully." });
|
|
3915
4172
|
return;
|
|
3916
4173
|
} catch (error2) {
|
|
3917
|
-
|
|
4174
|
+
import_node_server_utils22.logger.log({ level: "error", message: error2.message });
|
|
3918
4175
|
next(error2);
|
|
3919
4176
|
return;
|
|
3920
4177
|
}
|
|
@@ -3926,8 +4183,8 @@ function useSupplyController() {
|
|
|
3926
4183
|
});
|
|
3927
4184
|
const { error, value } = validation.validate({ id });
|
|
3928
4185
|
if (error) {
|
|
3929
|
-
|
|
3930
|
-
next(new
|
|
4186
|
+
import_node_server_utils22.logger.log({ level: "error", message: error.message });
|
|
4187
|
+
next(new import_node_server_utils22.BadRequestError(error.message));
|
|
3931
4188
|
return;
|
|
3932
4189
|
}
|
|
3933
4190
|
try {
|
|
@@ -3935,7 +4192,7 @@ function useSupplyController() {
|
|
|
3935
4192
|
res.json({ message: "Supply deleted successfully." });
|
|
3936
4193
|
return;
|
|
3937
4194
|
} catch (error2) {
|
|
3938
|
-
|
|
4195
|
+
import_node_server_utils22.logger.log({ level: "error", message: error2.message });
|
|
3939
4196
|
next(error2);
|
|
3940
4197
|
return;
|
|
3941
4198
|
}
|
|
@@ -3952,7 +4209,7 @@ function useSupplyController() {
|
|
|
3952
4209
|
// src/models/hygiene-stock.model.ts
|
|
3953
4210
|
var import_joi12 = __toESM(require("joi"));
|
|
3954
4211
|
var import_mongodb12 = require("mongodb");
|
|
3955
|
-
var
|
|
4212
|
+
var import_node_server_utils23 = require("@7365admin1/node-server-utils");
|
|
3956
4213
|
var stockSchema = import_joi12.default.object({
|
|
3957
4214
|
site: import_joi12.default.string().hex().required(),
|
|
3958
4215
|
supply: import_joi12.default.string().hex().required(),
|
|
@@ -3964,21 +4221,21 @@ var stockSchema = import_joi12.default.object({
|
|
|
3964
4221
|
function MStock(value) {
|
|
3965
4222
|
const { error } = stockSchema.validate(value);
|
|
3966
4223
|
if (error) {
|
|
3967
|
-
|
|
3968
|
-
throw new
|
|
4224
|
+
import_node_server_utils23.logger.info(`Hygiene Stock Model: ${error.message}`);
|
|
4225
|
+
throw new import_node_server_utils23.BadRequestError(error.message);
|
|
3969
4226
|
}
|
|
3970
4227
|
if (value.site) {
|
|
3971
4228
|
try {
|
|
3972
4229
|
value.site = new import_mongodb12.ObjectId(value.site);
|
|
3973
4230
|
} catch (error2) {
|
|
3974
|
-
throw new
|
|
4231
|
+
throw new import_node_server_utils23.BadRequestError("Invalid site ID format.");
|
|
3975
4232
|
}
|
|
3976
4233
|
}
|
|
3977
4234
|
if (value.supply) {
|
|
3978
4235
|
try {
|
|
3979
4236
|
value.supply = new import_mongodb12.ObjectId(value.supply);
|
|
3980
4237
|
} catch (error2) {
|
|
3981
|
-
throw new
|
|
4238
|
+
throw new import_node_server_utils23.BadRequestError("Invalid supply ID format.");
|
|
3982
4239
|
}
|
|
3983
4240
|
}
|
|
3984
4241
|
return {
|
|
@@ -3997,17 +4254,17 @@ function MStock(value) {
|
|
|
3997
4254
|
|
|
3998
4255
|
// src/repositories/hygiene-stock.repository.ts
|
|
3999
4256
|
var import_mongodb13 = require("mongodb");
|
|
4000
|
-
var
|
|
4257
|
+
var import_node_server_utils24 = require("@7365admin1/node-server-utils");
|
|
4001
4258
|
function useStockRepository() {
|
|
4002
|
-
const db =
|
|
4259
|
+
const db = import_node_server_utils24.useAtlas.getDb();
|
|
4003
4260
|
if (!db) {
|
|
4004
|
-
throw new
|
|
4261
|
+
throw new import_node_server_utils24.InternalServerError("Unable to connect to server.");
|
|
4005
4262
|
}
|
|
4006
4263
|
const namespace_collection = "site.supply.stocks";
|
|
4007
4264
|
const supply_collection = "site.supplies";
|
|
4008
4265
|
const collection = db.collection(namespace_collection);
|
|
4009
|
-
const { delNamespace, setCache, getCache } = (0,
|
|
4010
|
-
const { delNamespace: delSupplyNamespace } = (0,
|
|
4266
|
+
const { delNamespace, setCache, getCache } = (0, import_node_server_utils24.useCache)(namespace_collection);
|
|
4267
|
+
const { delNamespace: delSupplyNamespace } = (0, import_node_server_utils24.useCache)(supply_collection);
|
|
4011
4268
|
async function createIndex() {
|
|
4012
4269
|
try {
|
|
4013
4270
|
await collection.createIndexes([
|
|
@@ -4017,7 +4274,7 @@ function useStockRepository() {
|
|
|
4017
4274
|
{ key: { status: 1 } }
|
|
4018
4275
|
]);
|
|
4019
4276
|
} catch (error) {
|
|
4020
|
-
throw new
|
|
4277
|
+
throw new import_node_server_utils24.InternalServerError("Failed to create index on hygiene stock.");
|
|
4021
4278
|
}
|
|
4022
4279
|
}
|
|
4023
4280
|
async function createStock(value, session) {
|
|
@@ -4025,17 +4282,17 @@ function useStockRepository() {
|
|
|
4025
4282
|
value = MStock(value);
|
|
4026
4283
|
const res = await collection.insertOne(value, { session });
|
|
4027
4284
|
delNamespace().then(() => {
|
|
4028
|
-
|
|
4285
|
+
import_node_server_utils24.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
4029
4286
|
}).catch((err) => {
|
|
4030
|
-
|
|
4287
|
+
import_node_server_utils24.logger.error(
|
|
4031
4288
|
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
4032
4289
|
err
|
|
4033
4290
|
);
|
|
4034
4291
|
});
|
|
4035
4292
|
delSupplyNamespace().then(() => {
|
|
4036
|
-
|
|
4293
|
+
import_node_server_utils24.logger.info(`Cache cleared for namespace: ${supply_collection}`);
|
|
4037
4294
|
}).catch((err) => {
|
|
4038
|
-
|
|
4295
|
+
import_node_server_utils24.logger.error(
|
|
4039
4296
|
`Failed to clear cache for namespace: ${supply_collection}`,
|
|
4040
4297
|
err
|
|
4041
4298
|
);
|
|
@@ -4065,23 +4322,23 @@ function useStockRepository() {
|
|
|
4065
4322
|
query.site = site;
|
|
4066
4323
|
cacheOptions.site = site.toString();
|
|
4067
4324
|
} catch (error) {
|
|
4068
|
-
throw new
|
|
4325
|
+
throw new import_node_server_utils24.BadRequestError("Invalid site ID format.");
|
|
4069
4326
|
}
|
|
4070
4327
|
try {
|
|
4071
4328
|
supply = new import_mongodb13.ObjectId(supply);
|
|
4072
4329
|
query.supply = supply;
|
|
4073
4330
|
cacheOptions.supply = supply.toString();
|
|
4074
4331
|
} catch (error) {
|
|
4075
|
-
throw new
|
|
4332
|
+
throw new import_node_server_utils24.BadRequestError("Invalid supply ID format.");
|
|
4076
4333
|
}
|
|
4077
4334
|
if (search) {
|
|
4078
4335
|
query.$text = { $search: search };
|
|
4079
4336
|
cacheOptions.search = search;
|
|
4080
4337
|
}
|
|
4081
|
-
const cacheKey = (0,
|
|
4338
|
+
const cacheKey = (0, import_node_server_utils24.makeCacheKey)(namespace_collection, cacheOptions);
|
|
4082
4339
|
const cachedData = await getCache(cacheKey);
|
|
4083
4340
|
if (cachedData) {
|
|
4084
|
-
|
|
4341
|
+
import_node_server_utils24.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
4085
4342
|
return cachedData;
|
|
4086
4343
|
}
|
|
4087
4344
|
try {
|
|
@@ -4100,11 +4357,11 @@ function useStockRepository() {
|
|
|
4100
4357
|
{ $limit: limit }
|
|
4101
4358
|
]).toArray();
|
|
4102
4359
|
const length = await collection.countDocuments(query);
|
|
4103
|
-
const data = (0,
|
|
4360
|
+
const data = (0, import_node_server_utils24.paginate)(items, page, limit, length);
|
|
4104
4361
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
4105
|
-
|
|
4362
|
+
import_node_server_utils24.logger.info(`Cache set for key: ${cacheKey}`);
|
|
4106
4363
|
}).catch((err) => {
|
|
4107
|
-
|
|
4364
|
+
import_node_server_utils24.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
4108
4365
|
});
|
|
4109
4366
|
return data;
|
|
4110
4367
|
} catch (error) {
|
|
@@ -4119,14 +4376,14 @@ function useStockRepository() {
|
|
|
4119
4376
|
}
|
|
4120
4377
|
|
|
4121
4378
|
// src/services/hygiene-stock.service.ts
|
|
4122
|
-
var
|
|
4379
|
+
var import_node_server_utils25 = require("@7365admin1/node-server-utils");
|
|
4123
4380
|
function useStockService() {
|
|
4124
4381
|
const { createStock: _createStock } = useStockRepository();
|
|
4125
4382
|
const { getSupplyById, updateSupply } = useSupplyRepository();
|
|
4126
4383
|
async function createStock(value, out = false, session) {
|
|
4127
4384
|
let ownSession = false;
|
|
4128
4385
|
if (!session) {
|
|
4129
|
-
session =
|
|
4386
|
+
session = import_node_server_utils25.useAtlas.getClient()?.startSession();
|
|
4130
4387
|
ownSession = true;
|
|
4131
4388
|
}
|
|
4132
4389
|
try {
|
|
@@ -4135,11 +4392,11 @@ function useStockService() {
|
|
|
4135
4392
|
const { qty, ...stockData } = value;
|
|
4136
4393
|
const supply = await getSupplyById(value.supply, session);
|
|
4137
4394
|
if (!supply || supply.qty === void 0) {
|
|
4138
|
-
throw new
|
|
4395
|
+
throw new import_node_server_utils25.NotFoundError("Supply not found.");
|
|
4139
4396
|
}
|
|
4140
4397
|
const newSupplyQty = out ? supply.qty - qty : supply.qty + qty;
|
|
4141
4398
|
if (out && newSupplyQty < 0) {
|
|
4142
|
-
throw new
|
|
4399
|
+
throw new import_node_server_utils25.BadRequestError(
|
|
4143
4400
|
`Insufficient stock. Available: ${supply.qty}, Requested: ${qty}`
|
|
4144
4401
|
);
|
|
4145
4402
|
}
|
|
@@ -4170,7 +4427,7 @@ function useStockService() {
|
|
|
4170
4427
|
|
|
4171
4428
|
// src/controllers/hygiene-stock.controller.ts
|
|
4172
4429
|
var import_joi13 = __toESM(require("joi"));
|
|
4173
|
-
var
|
|
4430
|
+
var import_node_server_utils26 = require("@7365admin1/node-server-utils");
|
|
4174
4431
|
function useStockController() {
|
|
4175
4432
|
const { getStocksBySupplyId: _getStocksBySupplyId } = useStockRepository();
|
|
4176
4433
|
const { createStock: _createStock } = useStockService();
|
|
@@ -4184,8 +4441,8 @@ function useStockController() {
|
|
|
4184
4441
|
});
|
|
4185
4442
|
const { error } = validation.validate(payload);
|
|
4186
4443
|
if (error) {
|
|
4187
|
-
|
|
4188
|
-
next(new
|
|
4444
|
+
import_node_server_utils26.logger.log({ level: "error", message: error.message });
|
|
4445
|
+
next(new import_node_server_utils26.BadRequestError(error.message));
|
|
4189
4446
|
return;
|
|
4190
4447
|
}
|
|
4191
4448
|
try {
|
|
@@ -4193,7 +4450,7 @@ function useStockController() {
|
|
|
4193
4450
|
res.status(201).json({ message: "Stock created successfully.", id });
|
|
4194
4451
|
return;
|
|
4195
4452
|
} catch (error2) {
|
|
4196
|
-
|
|
4453
|
+
import_node_server_utils26.logger.log({ level: "error", message: error2.message });
|
|
4197
4454
|
next(error2);
|
|
4198
4455
|
return;
|
|
4199
4456
|
}
|
|
@@ -4209,8 +4466,8 @@ function useStockController() {
|
|
|
4209
4466
|
});
|
|
4210
4467
|
const { error } = validation.validate(query);
|
|
4211
4468
|
if (error) {
|
|
4212
|
-
|
|
4213
|
-
next(new
|
|
4469
|
+
import_node_server_utils26.logger.log({ level: "error", message: error.message });
|
|
4470
|
+
next(new import_node_server_utils26.BadRequestError(error.message));
|
|
4214
4471
|
return;
|
|
4215
4472
|
}
|
|
4216
4473
|
const page = parseInt(req.query.page) ?? 1;
|
|
@@ -4229,7 +4486,7 @@ function useStockController() {
|
|
|
4229
4486
|
res.json(data);
|
|
4230
4487
|
return;
|
|
4231
4488
|
} catch (error2) {
|
|
4232
|
-
|
|
4489
|
+
import_node_server_utils26.logger.log({ level: "error", message: error2.message });
|
|
4233
4490
|
next(error2);
|
|
4234
4491
|
return;
|
|
4235
4492
|
}
|
|
@@ -4243,7 +4500,7 @@ function useStockController() {
|
|
|
4243
4500
|
// src/models/hygiene-checkout-item.model.ts
|
|
4244
4501
|
var import_joi14 = __toESM(require("joi"));
|
|
4245
4502
|
var import_mongodb14 = require("mongodb");
|
|
4246
|
-
var
|
|
4503
|
+
var import_node_server_utils27 = require("@7365admin1/node-server-utils");
|
|
4247
4504
|
var allowedCheckOutItemStatus = ["pending", "completed"];
|
|
4248
4505
|
var checkOutItemSchema = import_joi14.default.object({
|
|
4249
4506
|
site: import_joi14.default.string().hex().required(),
|
|
@@ -4257,21 +4514,21 @@ var checkOutItemSchema = import_joi14.default.object({
|
|
|
4257
4514
|
function MCheckOutItem(value) {
|
|
4258
4515
|
const { error } = checkOutItemSchema.validate(value);
|
|
4259
4516
|
if (error) {
|
|
4260
|
-
|
|
4261
|
-
throw new
|
|
4517
|
+
import_node_server_utils27.logger.info(`Hygiene Check Out Item Model: ${error.message}`);
|
|
4518
|
+
throw new import_node_server_utils27.BadRequestError(error.message);
|
|
4262
4519
|
}
|
|
4263
4520
|
if (value.site) {
|
|
4264
4521
|
try {
|
|
4265
4522
|
value.site = new import_mongodb14.ObjectId(value.site);
|
|
4266
4523
|
} catch (error2) {
|
|
4267
|
-
throw new
|
|
4524
|
+
throw new import_node_server_utils27.BadRequestError("Invalid site ID format.");
|
|
4268
4525
|
}
|
|
4269
4526
|
}
|
|
4270
4527
|
if (value.supply) {
|
|
4271
4528
|
try {
|
|
4272
4529
|
value.supply = new import_mongodb14.ObjectId(value.supply);
|
|
4273
4530
|
} catch (error2) {
|
|
4274
|
-
throw new
|
|
4531
|
+
throw new import_node_server_utils27.BadRequestError("Invalid supply ID format.");
|
|
4275
4532
|
}
|
|
4276
4533
|
}
|
|
4277
4534
|
return {
|
|
@@ -4291,15 +4548,15 @@ function MCheckOutItem(value) {
|
|
|
4291
4548
|
|
|
4292
4549
|
// src/repositories/hygiene-checkout-item.repository.ts
|
|
4293
4550
|
var import_mongodb15 = require("mongodb");
|
|
4294
|
-
var
|
|
4551
|
+
var import_node_server_utils28 = require("@7365admin1/node-server-utils");
|
|
4295
4552
|
function useCheckOutItemRepository() {
|
|
4296
|
-
const db =
|
|
4553
|
+
const db = import_node_server_utils28.useAtlas.getDb();
|
|
4297
4554
|
if (!db) {
|
|
4298
|
-
throw new
|
|
4555
|
+
throw new import_node_server_utils28.InternalServerError("Unable to connect to server.");
|
|
4299
4556
|
}
|
|
4300
4557
|
const namespace_collection = "site.supply.checkouts";
|
|
4301
4558
|
const collection = db.collection(namespace_collection);
|
|
4302
|
-
const { delNamespace, setCache, getCache } = (0,
|
|
4559
|
+
const { delNamespace, setCache, getCache } = (0, import_node_server_utils28.useCache)(namespace_collection);
|
|
4303
4560
|
async function createIndex() {
|
|
4304
4561
|
try {
|
|
4305
4562
|
await collection.createIndexes([
|
|
@@ -4308,7 +4565,7 @@ function useCheckOutItemRepository() {
|
|
|
4308
4565
|
{ key: { status: 1 } }
|
|
4309
4566
|
]);
|
|
4310
4567
|
} catch (error) {
|
|
4311
|
-
throw new
|
|
4568
|
+
throw new import_node_server_utils28.InternalServerError(
|
|
4312
4569
|
"Failed to create index on hygiene check out item."
|
|
4313
4570
|
);
|
|
4314
4571
|
}
|
|
@@ -4317,7 +4574,7 @@ function useCheckOutItemRepository() {
|
|
|
4317
4574
|
try {
|
|
4318
4575
|
await collection.createIndex({ supplyName: "text" });
|
|
4319
4576
|
} catch (error) {
|
|
4320
|
-
throw new
|
|
4577
|
+
throw new import_node_server_utils28.InternalServerError(
|
|
4321
4578
|
"Failed to create text index on hygiene supply."
|
|
4322
4579
|
);
|
|
4323
4580
|
}
|
|
@@ -4327,9 +4584,9 @@ function useCheckOutItemRepository() {
|
|
|
4327
4584
|
value = MCheckOutItem(value);
|
|
4328
4585
|
const res = await collection.insertOne(value, { session });
|
|
4329
4586
|
delNamespace().then(() => {
|
|
4330
|
-
|
|
4587
|
+
import_node_server_utils28.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
4331
4588
|
}).catch((err) => {
|
|
4332
|
-
|
|
4589
|
+
import_node_server_utils28.logger.error(
|
|
4333
4590
|
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
4334
4591
|
err
|
|
4335
4592
|
);
|
|
@@ -4358,16 +4615,16 @@ function useCheckOutItemRepository() {
|
|
|
4358
4615
|
query.site = site;
|
|
4359
4616
|
cacheOptions.site = site.toString();
|
|
4360
4617
|
} catch (error) {
|
|
4361
|
-
throw new
|
|
4618
|
+
throw new import_node_server_utils28.BadRequestError("Invalid site ID format.");
|
|
4362
4619
|
}
|
|
4363
4620
|
if (search) {
|
|
4364
4621
|
query.$text = { $search: search };
|
|
4365
4622
|
cacheOptions.search = search;
|
|
4366
4623
|
}
|
|
4367
|
-
const cacheKey = (0,
|
|
4624
|
+
const cacheKey = (0, import_node_server_utils28.makeCacheKey)(namespace_collection, cacheOptions);
|
|
4368
4625
|
const cachedData = await getCache(cacheKey);
|
|
4369
4626
|
if (cachedData) {
|
|
4370
|
-
|
|
4627
|
+
import_node_server_utils28.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
4371
4628
|
return cachedData;
|
|
4372
4629
|
}
|
|
4373
4630
|
try {
|
|
@@ -4414,11 +4671,11 @@ function useCheckOutItemRepository() {
|
|
|
4414
4671
|
{ $limit: limit }
|
|
4415
4672
|
]).toArray();
|
|
4416
4673
|
const length = await collection.countDocuments(query);
|
|
4417
|
-
const data = (0,
|
|
4674
|
+
const data = (0, import_node_server_utils28.paginate)(items, page, limit, length);
|
|
4418
4675
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
4419
|
-
|
|
4676
|
+
import_node_server_utils28.logger.info(`Cache set for key: ${cacheKey}`);
|
|
4420
4677
|
}).catch((err) => {
|
|
4421
|
-
|
|
4678
|
+
import_node_server_utils28.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
4422
4679
|
});
|
|
4423
4680
|
return data;
|
|
4424
4681
|
} catch (error) {
|
|
@@ -4429,20 +4686,20 @@ function useCheckOutItemRepository() {
|
|
|
4429
4686
|
try {
|
|
4430
4687
|
_id = new import_mongodb15.ObjectId(_id);
|
|
4431
4688
|
} catch (error) {
|
|
4432
|
-
throw new
|
|
4689
|
+
throw new import_node_server_utils28.BadRequestError("Invalid check out item ID format.");
|
|
4433
4690
|
}
|
|
4434
4691
|
const query = { _id };
|
|
4435
|
-
const cacheKey = (0,
|
|
4692
|
+
const cacheKey = (0, import_node_server_utils28.makeCacheKey)(namespace_collection, {
|
|
4436
4693
|
_id: _id.toString()
|
|
4437
4694
|
});
|
|
4438
4695
|
if (!session) {
|
|
4439
4696
|
const cachedData = await getCache(cacheKey);
|
|
4440
4697
|
if (cachedData) {
|
|
4441
|
-
|
|
4698
|
+
import_node_server_utils28.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
4442
4699
|
return cachedData;
|
|
4443
4700
|
}
|
|
4444
4701
|
} else {
|
|
4445
|
-
|
|
4702
|
+
import_node_server_utils28.logger.info(`Skipping cache during transaction for key: ${cacheKey}`);
|
|
4446
4703
|
}
|
|
4447
4704
|
try {
|
|
4448
4705
|
const data = await collection.aggregate(
|
|
@@ -4477,12 +4734,12 @@ function useCheckOutItemRepository() {
|
|
|
4477
4734
|
session ? { session } : void 0
|
|
4478
4735
|
).toArray();
|
|
4479
4736
|
if (!data || data.length === 0) {
|
|
4480
|
-
throw new
|
|
4737
|
+
throw new import_node_server_utils28.NotFoundError("Check out item not found.");
|
|
4481
4738
|
}
|
|
4482
4739
|
setCache(cacheKey, data[0], 15 * 60).then(() => {
|
|
4483
|
-
|
|
4740
|
+
import_node_server_utils28.logger.info(`Cache set for key: ${cacheKey}`);
|
|
4484
4741
|
}).catch((err) => {
|
|
4485
|
-
|
|
4742
|
+
import_node_server_utils28.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
4486
4743
|
});
|
|
4487
4744
|
return data[0];
|
|
4488
4745
|
} catch (error) {
|
|
@@ -4493,7 +4750,7 @@ function useCheckOutItemRepository() {
|
|
|
4493
4750
|
try {
|
|
4494
4751
|
_id = new import_mongodb15.ObjectId(_id);
|
|
4495
4752
|
} catch (error) {
|
|
4496
|
-
throw new
|
|
4753
|
+
throw new import_node_server_utils28.BadRequestError("Invalid check out item ID format.");
|
|
4497
4754
|
}
|
|
4498
4755
|
try {
|
|
4499
4756
|
const updateValue = {
|
|
@@ -4506,12 +4763,12 @@ function useCheckOutItemRepository() {
|
|
|
4506
4763
|
{ session }
|
|
4507
4764
|
);
|
|
4508
4765
|
if (res.modifiedCount === 0) {
|
|
4509
|
-
throw new
|
|
4766
|
+
throw new import_node_server_utils28.InternalServerError("Unable to complete check out item.");
|
|
4510
4767
|
}
|
|
4511
4768
|
delNamespace().then(() => {
|
|
4512
|
-
|
|
4769
|
+
import_node_server_utils28.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
4513
4770
|
}).catch((err) => {
|
|
4514
|
-
|
|
4771
|
+
import_node_server_utils28.logger.error(
|
|
4515
4772
|
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
4516
4773
|
err
|
|
4517
4774
|
);
|
|
@@ -4533,7 +4790,7 @@ function useCheckOutItemRepository() {
|
|
|
4533
4790
|
|
|
4534
4791
|
// src/services/hygiene-checkout-item.service.ts
|
|
4535
4792
|
var import_core = require("@7365admin1/core");
|
|
4536
|
-
var
|
|
4793
|
+
var import_node_server_utils29 = require("@7365admin1/node-server-utils");
|
|
4537
4794
|
function useCheckOutItemService() {
|
|
4538
4795
|
const {
|
|
4539
4796
|
createCheckOutItem: _createCheckOutItem,
|
|
@@ -4544,7 +4801,7 @@ function useCheckOutItemService() {
|
|
|
4544
4801
|
const { getUserById } = (0, import_core.useUserRepo)();
|
|
4545
4802
|
const { createStock } = useStockService();
|
|
4546
4803
|
async function createCheckOutItem(value) {
|
|
4547
|
-
const session =
|
|
4804
|
+
const session = import_node_server_utils29.useAtlas.getClient()?.startSession();
|
|
4548
4805
|
try {
|
|
4549
4806
|
session?.startTransaction();
|
|
4550
4807
|
const supplyData = await getSupplyById(value.supply);
|
|
@@ -4562,7 +4819,7 @@ function useCheckOutItemService() {
|
|
|
4562
4819
|
session
|
|
4563
4820
|
);
|
|
4564
4821
|
if (!checkOutItem) {
|
|
4565
|
-
throw new
|
|
4822
|
+
throw new import_node_server_utils29.BadRequestError("Failed to create check out item.");
|
|
4566
4823
|
}
|
|
4567
4824
|
const createdStocks = await createStock(
|
|
4568
4825
|
{
|
|
@@ -4584,7 +4841,7 @@ function useCheckOutItemService() {
|
|
|
4584
4841
|
}
|
|
4585
4842
|
}
|
|
4586
4843
|
async function createCheckOutItemByBatch(value) {
|
|
4587
|
-
const session =
|
|
4844
|
+
const session = import_node_server_utils29.useAtlas.getClient()?.startSession();
|
|
4588
4845
|
try {
|
|
4589
4846
|
session?.startTransaction();
|
|
4590
4847
|
const { site, attachment, createdBy, items } = value;
|
|
@@ -4632,7 +4889,7 @@ function useCheckOutItemService() {
|
|
|
4632
4889
|
|
|
4633
4890
|
// src/controllers/hygiene-checkout-item.controller.ts
|
|
4634
4891
|
var import_joi15 = __toESM(require("joi"));
|
|
4635
|
-
var
|
|
4892
|
+
var import_node_server_utils30 = require("@7365admin1/node-server-utils");
|
|
4636
4893
|
function useCheckOutItemController() {
|
|
4637
4894
|
const {
|
|
4638
4895
|
getCheckOutItems: _getCheckOutItems,
|
|
@@ -4662,8 +4919,8 @@ function useCheckOutItemController() {
|
|
|
4662
4919
|
});
|
|
4663
4920
|
const { error } = validation.validate(payload);
|
|
4664
4921
|
if (error) {
|
|
4665
|
-
|
|
4666
|
-
next(new
|
|
4922
|
+
import_node_server_utils30.logger.log({ level: "error", message: error.message });
|
|
4923
|
+
next(new import_node_server_utils30.BadRequestError(error.message));
|
|
4667
4924
|
return;
|
|
4668
4925
|
}
|
|
4669
4926
|
try {
|
|
@@ -4671,7 +4928,7 @@ function useCheckOutItemController() {
|
|
|
4671
4928
|
res.status(201).json({ message: "Check out item created successfully.", id });
|
|
4672
4929
|
return;
|
|
4673
4930
|
} catch (error2) {
|
|
4674
|
-
|
|
4931
|
+
import_node_server_utils30.logger.log({ level: "error", message: error2.message });
|
|
4675
4932
|
next(error2);
|
|
4676
4933
|
return;
|
|
4677
4934
|
}
|
|
@@ -4700,8 +4957,8 @@ function useCheckOutItemController() {
|
|
|
4700
4957
|
});
|
|
4701
4958
|
const { error } = validation.validate(payload);
|
|
4702
4959
|
if (error) {
|
|
4703
|
-
|
|
4704
|
-
next(new
|
|
4960
|
+
import_node_server_utils30.logger.log({ level: "error", message: error.message });
|
|
4961
|
+
next(new import_node_server_utils30.BadRequestError(error.message));
|
|
4705
4962
|
return;
|
|
4706
4963
|
}
|
|
4707
4964
|
try {
|
|
@@ -4709,7 +4966,7 @@ function useCheckOutItemController() {
|
|
|
4709
4966
|
res.status(201).json({ message: "Check out items created successfully." });
|
|
4710
4967
|
return;
|
|
4711
4968
|
} catch (error2) {
|
|
4712
|
-
|
|
4969
|
+
import_node_server_utils30.logger.log({ level: "error", message: error2.message });
|
|
4713
4970
|
next(error2);
|
|
4714
4971
|
return;
|
|
4715
4972
|
}
|
|
@@ -4724,8 +4981,8 @@ function useCheckOutItemController() {
|
|
|
4724
4981
|
});
|
|
4725
4982
|
const { error } = validation.validate(query);
|
|
4726
4983
|
if (error) {
|
|
4727
|
-
|
|
4728
|
-
next(new
|
|
4984
|
+
import_node_server_utils30.logger.log({ level: "error", message: error.message });
|
|
4985
|
+
next(new import_node_server_utils30.BadRequestError(error.message));
|
|
4729
4986
|
return;
|
|
4730
4987
|
}
|
|
4731
4988
|
const page = parseInt(req.query.page) ?? 1;
|
|
@@ -4742,7 +4999,7 @@ function useCheckOutItemController() {
|
|
|
4742
4999
|
res.json(data);
|
|
4743
5000
|
return;
|
|
4744
5001
|
} catch (error2) {
|
|
4745
|
-
|
|
5002
|
+
import_node_server_utils30.logger.log({ level: "error", message: error2.message });
|
|
4746
5003
|
next(error2);
|
|
4747
5004
|
return;
|
|
4748
5005
|
}
|
|
@@ -4752,8 +5009,8 @@ function useCheckOutItemController() {
|
|
|
4752
5009
|
const _id = req.params.id;
|
|
4753
5010
|
const { error, value } = validation.validate(_id);
|
|
4754
5011
|
if (error) {
|
|
4755
|
-
|
|
4756
|
-
next(new
|
|
5012
|
+
import_node_server_utils30.logger.log({ level: "error", message: error.message });
|
|
5013
|
+
next(new import_node_server_utils30.BadRequestError(error.message));
|
|
4757
5014
|
return;
|
|
4758
5015
|
}
|
|
4759
5016
|
try {
|
|
@@ -4761,7 +5018,7 @@ function useCheckOutItemController() {
|
|
|
4761
5018
|
res.json(data);
|
|
4762
5019
|
return;
|
|
4763
5020
|
} catch (error2) {
|
|
4764
|
-
|
|
5021
|
+
import_node_server_utils30.logger.log({ level: "error", message: error2.message });
|
|
4765
5022
|
next(error2);
|
|
4766
5023
|
return;
|
|
4767
5024
|
}
|
|
@@ -4775,7 +5032,7 @@ function useCheckOutItemController() {
|
|
|
4775
5032
|
}
|
|
4776
5033
|
|
|
4777
5034
|
// src/models/hygiene-schedule-task.model.ts
|
|
4778
|
-
var
|
|
5035
|
+
var import_node_server_utils31 = require("@7365admin1/node-server-utils");
|
|
4779
5036
|
var import_joi16 = __toESM(require("joi"));
|
|
4780
5037
|
var import_mongodb16 = require("mongodb");
|
|
4781
5038
|
var scheduleTaskSchema = import_joi16.default.object({
|
|
@@ -4796,14 +5053,14 @@ var scheduleTaskSchema = import_joi16.default.object({
|
|
|
4796
5053
|
function MScheduleTask(value) {
|
|
4797
5054
|
const { error } = scheduleTaskSchema.validate(value);
|
|
4798
5055
|
if (error) {
|
|
4799
|
-
|
|
4800
|
-
throw new
|
|
5056
|
+
import_node_server_utils31.logger.info(`Hygiene Schedule Task Model: ${error.message}`);
|
|
5057
|
+
throw new import_node_server_utils31.BadRequestError(error.message);
|
|
4801
5058
|
}
|
|
4802
5059
|
if (value.site) {
|
|
4803
5060
|
try {
|
|
4804
5061
|
value.site = new import_mongodb16.ObjectId(value.site);
|
|
4805
5062
|
} catch (error2) {
|
|
4806
|
-
throw new
|
|
5063
|
+
throw new import_node_server_utils31.BadRequestError("Invalid site ID format.");
|
|
4807
5064
|
}
|
|
4808
5065
|
}
|
|
4809
5066
|
if (value.areas && Array.isArray(value.areas)) {
|
|
@@ -4814,7 +5071,7 @@ function MScheduleTask(value) {
|
|
|
4814
5071
|
value: new import_mongodb16.ObjectId(area.value.toString())
|
|
4815
5072
|
};
|
|
4816
5073
|
} catch (error2) {
|
|
4817
|
-
throw new
|
|
5074
|
+
throw new import_node_server_utils31.BadRequestError(`Invalid area value format: ${area.name}`);
|
|
4818
5075
|
}
|
|
4819
5076
|
});
|
|
4820
5077
|
}
|
|
@@ -4822,7 +5079,7 @@ function MScheduleTask(value) {
|
|
|
4822
5079
|
try {
|
|
4823
5080
|
value.createdBy = new import_mongodb16.ObjectId(value.createdBy);
|
|
4824
5081
|
} catch (error2) {
|
|
4825
|
-
throw new
|
|
5082
|
+
throw new import_node_server_utils31.BadRequestError("Invalid createdBy ID format.");
|
|
4826
5083
|
}
|
|
4827
5084
|
}
|
|
4828
5085
|
return {
|
|
@@ -4843,15 +5100,15 @@ function MScheduleTask(value) {
|
|
|
4843
5100
|
|
|
4844
5101
|
// src/repositories/hygiene-schedule-task.repository.ts
|
|
4845
5102
|
var import_mongodb17 = require("mongodb");
|
|
4846
|
-
var
|
|
5103
|
+
var import_node_server_utils32 = require("@7365admin1/node-server-utils");
|
|
4847
5104
|
function useScheduleTaskRepository() {
|
|
4848
|
-
const db =
|
|
5105
|
+
const db = import_node_server_utils32.useAtlas.getDb();
|
|
4849
5106
|
if (!db) {
|
|
4850
|
-
throw new
|
|
5107
|
+
throw new import_node_server_utils32.InternalServerError("Unable to connect to server.");
|
|
4851
5108
|
}
|
|
4852
5109
|
const namespace_collection = "site.schedule-tasks";
|
|
4853
5110
|
const collection = db.collection(namespace_collection);
|
|
4854
|
-
const { delNamespace, setCache, getCache } = (0,
|
|
5111
|
+
const { delNamespace, setCache, getCache } = (0, import_node_server_utils32.useCache)(namespace_collection);
|
|
4855
5112
|
async function createIndex() {
|
|
4856
5113
|
try {
|
|
4857
5114
|
await collection.createIndexes([
|
|
@@ -4859,7 +5116,7 @@ function useScheduleTaskRepository() {
|
|
|
4859
5116
|
{ key: { status: 1 } }
|
|
4860
5117
|
]);
|
|
4861
5118
|
} catch (error) {
|
|
4862
|
-
throw new
|
|
5119
|
+
throw new import_node_server_utils32.InternalServerError(
|
|
4863
5120
|
"Failed to create index on hygiene schedule task."
|
|
4864
5121
|
);
|
|
4865
5122
|
}
|
|
@@ -4868,7 +5125,7 @@ function useScheduleTaskRepository() {
|
|
|
4868
5125
|
try {
|
|
4869
5126
|
await collection.createIndex({ title: "text", description: "text" });
|
|
4870
5127
|
} catch (error) {
|
|
4871
|
-
throw new
|
|
5128
|
+
throw new import_node_server_utils32.InternalServerError(
|
|
4872
5129
|
"Failed to create text index on hygiene schedule task."
|
|
4873
5130
|
);
|
|
4874
5131
|
}
|
|
@@ -4878,9 +5135,9 @@ function useScheduleTaskRepository() {
|
|
|
4878
5135
|
value = MScheduleTask(value);
|
|
4879
5136
|
const res = await collection.insertOne(value, { session });
|
|
4880
5137
|
delNamespace().then(() => {
|
|
4881
|
-
|
|
5138
|
+
import_node_server_utils32.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
4882
5139
|
}).catch((err) => {
|
|
4883
|
-
|
|
5140
|
+
import_node_server_utils32.logger.error(
|
|
4884
5141
|
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
4885
5142
|
err
|
|
4886
5143
|
);
|
|
@@ -4909,16 +5166,16 @@ function useScheduleTaskRepository() {
|
|
|
4909
5166
|
query.site = site;
|
|
4910
5167
|
cacheOptions.site = site.toString();
|
|
4911
5168
|
} catch (error) {
|
|
4912
|
-
throw new
|
|
5169
|
+
throw new import_node_server_utils32.BadRequestError("Invalid site ID format.");
|
|
4913
5170
|
}
|
|
4914
5171
|
if (search) {
|
|
4915
5172
|
query.$or = [{ name: { $regex: search, $options: "i" } }];
|
|
4916
5173
|
cacheOptions.search = search;
|
|
4917
5174
|
}
|
|
4918
|
-
const cacheKey = (0,
|
|
5175
|
+
const cacheKey = (0, import_node_server_utils32.makeCacheKey)(namespace_collection, cacheOptions);
|
|
4919
5176
|
const cachedData = await getCache(cacheKey);
|
|
4920
5177
|
if (cachedData) {
|
|
4921
|
-
|
|
5178
|
+
import_node_server_utils32.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
4922
5179
|
return cachedData;
|
|
4923
5180
|
}
|
|
4924
5181
|
try {
|
|
@@ -4936,11 +5193,11 @@ function useScheduleTaskRepository() {
|
|
|
4936
5193
|
{ $limit: limit }
|
|
4937
5194
|
]).toArray();
|
|
4938
5195
|
const length = await collection.countDocuments(query);
|
|
4939
|
-
const data = (0,
|
|
5196
|
+
const data = (0, import_node_server_utils32.paginate)(items, page, limit, length);
|
|
4940
5197
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
4941
|
-
|
|
5198
|
+
import_node_server_utils32.logger.info(`Cache set for key: ${cacheKey}`);
|
|
4942
5199
|
}).catch((err) => {
|
|
4943
|
-
|
|
5200
|
+
import_node_server_utils32.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
4944
5201
|
});
|
|
4945
5202
|
return data;
|
|
4946
5203
|
} catch (error) {
|
|
@@ -4977,16 +5234,16 @@ function useScheduleTaskRepository() {
|
|
|
4977
5234
|
query.site = site;
|
|
4978
5235
|
cacheOptions.site = site.toString();
|
|
4979
5236
|
} catch (error) {
|
|
4980
|
-
throw new
|
|
5237
|
+
throw new import_node_server_utils32.BadRequestError("Invalid site ID format.");
|
|
4981
5238
|
}
|
|
4982
5239
|
if (search) {
|
|
4983
5240
|
query.$or = [{ name: { $regex: search, $options: "i" } }];
|
|
4984
5241
|
cacheOptions.search = search;
|
|
4985
5242
|
}
|
|
4986
|
-
const cacheKey = (0,
|
|
5243
|
+
const cacheKey = (0, import_node_server_utils32.makeCacheKey)(namespace_collection, cacheOptions);
|
|
4987
5244
|
const cachedData = await getCache(cacheKey);
|
|
4988
5245
|
if (cachedData) {
|
|
4989
|
-
|
|
5246
|
+
import_node_server_utils32.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
4990
5247
|
return cachedData;
|
|
4991
5248
|
}
|
|
4992
5249
|
try {
|
|
@@ -5003,11 +5260,11 @@ function useScheduleTaskRepository() {
|
|
|
5003
5260
|
{ $limit: limit }
|
|
5004
5261
|
]).toArray();
|
|
5005
5262
|
const length = await collection.countDocuments(query);
|
|
5006
|
-
const data = (0,
|
|
5263
|
+
const data = (0, import_node_server_utils32.paginate)(items, page, limit, length);
|
|
5007
5264
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
5008
|
-
|
|
5265
|
+
import_node_server_utils32.logger.info(`Cache set for key: ${cacheKey}`);
|
|
5009
5266
|
}).catch((err) => {
|
|
5010
|
-
|
|
5267
|
+
import_node_server_utils32.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
5011
5268
|
});
|
|
5012
5269
|
return data;
|
|
5013
5270
|
} catch (error) {
|
|
@@ -5018,23 +5275,23 @@ function useScheduleTaskRepository() {
|
|
|
5018
5275
|
try {
|
|
5019
5276
|
_id = new import_mongodb17.ObjectId(_id);
|
|
5020
5277
|
} catch (error) {
|
|
5021
|
-
throw new
|
|
5278
|
+
throw new import_node_server_utils32.BadRequestError("Invalid schedule task ID format.");
|
|
5022
5279
|
}
|
|
5023
5280
|
const query = {
|
|
5024
5281
|
_id,
|
|
5025
5282
|
status: { $ne: "deleted" }
|
|
5026
5283
|
};
|
|
5027
|
-
const cacheKey = (0,
|
|
5284
|
+
const cacheKey = (0, import_node_server_utils32.makeCacheKey)(namespace_collection, {
|
|
5028
5285
|
_id: _id.toString()
|
|
5029
5286
|
});
|
|
5030
5287
|
if (!session) {
|
|
5031
5288
|
const cachedData = await getCache(cacheKey);
|
|
5032
5289
|
if (cachedData) {
|
|
5033
|
-
|
|
5290
|
+
import_node_server_utils32.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
5034
5291
|
return cachedData;
|
|
5035
5292
|
}
|
|
5036
5293
|
} else {
|
|
5037
|
-
|
|
5294
|
+
import_node_server_utils32.logger.info(`Skipping cache during transaction for key: ${cacheKey}`);
|
|
5038
5295
|
}
|
|
5039
5296
|
try {
|
|
5040
5297
|
const data = await collection.aggregate([
|
|
@@ -5053,12 +5310,12 @@ function useScheduleTaskRepository() {
|
|
|
5053
5310
|
}
|
|
5054
5311
|
]).toArray();
|
|
5055
5312
|
if (!data || data.length === 0) {
|
|
5056
|
-
throw new
|
|
5313
|
+
throw new import_node_server_utils32.NotFoundError("Schedule task not found.");
|
|
5057
5314
|
}
|
|
5058
5315
|
setCache(cacheKey, data[0], 15 * 60).then(() => {
|
|
5059
|
-
|
|
5316
|
+
import_node_server_utils32.logger.info(`Cache set for key: ${cacheKey}`);
|
|
5060
5317
|
}).catch((err) => {
|
|
5061
|
-
|
|
5318
|
+
import_node_server_utils32.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
5062
5319
|
});
|
|
5063
5320
|
return data[0];
|
|
5064
5321
|
} catch (error) {
|
|
@@ -5069,7 +5326,7 @@ function useScheduleTaskRepository() {
|
|
|
5069
5326
|
try {
|
|
5070
5327
|
_id = new import_mongodb17.ObjectId(_id);
|
|
5071
5328
|
} catch (error) {
|
|
5072
|
-
throw new
|
|
5329
|
+
throw new import_node_server_utils32.BadRequestError("Invalid schedule task ID format.");
|
|
5073
5330
|
}
|
|
5074
5331
|
if (value.areas && Array.isArray(value.areas)) {
|
|
5075
5332
|
value.areas = value.areas.map((area) => {
|
|
@@ -5079,7 +5336,7 @@ function useScheduleTaskRepository() {
|
|
|
5079
5336
|
value: new import_mongodb17.ObjectId(area.value.toString())
|
|
5080
5337
|
};
|
|
5081
5338
|
} catch (error) {
|
|
5082
|
-
throw new
|
|
5339
|
+
throw new import_node_server_utils32.BadRequestError(`Invalid area value format: ${area.name}`);
|
|
5083
5340
|
}
|
|
5084
5341
|
});
|
|
5085
5342
|
}
|
|
@@ -5091,14 +5348,14 @@ function useScheduleTaskRepository() {
|
|
|
5091
5348
|
{ session }
|
|
5092
5349
|
);
|
|
5093
5350
|
if (res.modifiedCount === 0) {
|
|
5094
|
-
throw new
|
|
5351
|
+
throw new import_node_server_utils32.InternalServerError(
|
|
5095
5352
|
"Unable to update hygiene schedule task."
|
|
5096
5353
|
);
|
|
5097
5354
|
}
|
|
5098
5355
|
delNamespace().then(() => {
|
|
5099
|
-
|
|
5356
|
+
import_node_server_utils32.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
5100
5357
|
}).catch((err) => {
|
|
5101
|
-
|
|
5358
|
+
import_node_server_utils32.logger.error(
|
|
5102
5359
|
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
5103
5360
|
err
|
|
5104
5361
|
);
|
|
@@ -5121,7 +5378,7 @@ function useScheduleTaskRepository() {
|
|
|
5121
5378
|
}
|
|
5122
5379
|
|
|
5123
5380
|
// src/services/hygiene-schedule-task.service.ts
|
|
5124
|
-
var
|
|
5381
|
+
var import_node_server_utils33 = require("@7365admin1/node-server-utils");
|
|
5125
5382
|
function useScheduleTaskService() {
|
|
5126
5383
|
const { createParentChecklist } = useParentChecklistRepo();
|
|
5127
5384
|
const { getAllScheduleTask } = useScheduleTaskRepository();
|
|
@@ -5144,13 +5401,13 @@ function useScheduleTaskService() {
|
|
|
5144
5401
|
const currentDateString = now.toLocaleDateString("en-US", {
|
|
5145
5402
|
timeZone: "Asia/Singapore"
|
|
5146
5403
|
});
|
|
5147
|
-
|
|
5404
|
+
import_node_server_utils33.logger.info(
|
|
5148
5405
|
`Checking schedule ${schedule._id}: Current time ${currentHour}:${currentMinute}, Current date ${currentDateString}, Schedule time ${schedule.time}, Start date ${schedule.startDate}, End date ${schedule.endDate}`
|
|
5149
5406
|
);
|
|
5150
5407
|
const startDate = /* @__PURE__ */ new Date(schedule.startDate + "T00:00:00");
|
|
5151
5408
|
const currentDateOnly = /* @__PURE__ */ new Date(currentDateString + "T00:00:00");
|
|
5152
5409
|
if (currentDateOnly < startDate) {
|
|
5153
|
-
|
|
5410
|
+
import_node_server_utils33.logger.info(
|
|
5154
5411
|
`Schedule ${schedule._id}: Current date ${currentDateString} is before start date ${schedule.startDate}`
|
|
5155
5412
|
);
|
|
5156
5413
|
return false;
|
|
@@ -5158,7 +5415,7 @@ function useScheduleTaskService() {
|
|
|
5158
5415
|
if (schedule.endDate) {
|
|
5159
5416
|
const endDate = /* @__PURE__ */ new Date(schedule.endDate + "T00:00:00");
|
|
5160
5417
|
if (currentDateOnly > endDate) {
|
|
5161
|
-
|
|
5418
|
+
import_node_server_utils33.logger.info(
|
|
5162
5419
|
`Schedule ${schedule._id}: Current date ${currentDateString} is after end date ${schedule.endDate}`
|
|
5163
5420
|
);
|
|
5164
5421
|
return false;
|
|
@@ -5167,17 +5424,17 @@ function useScheduleTaskService() {
|
|
|
5167
5424
|
const [scheduleHour, scheduleMinute] = schedule.time.split(":").map(Number);
|
|
5168
5425
|
const timeMatches = currentHour === scheduleHour && currentMinute === scheduleMinute;
|
|
5169
5426
|
if (!timeMatches) {
|
|
5170
|
-
|
|
5427
|
+
import_node_server_utils33.logger.info(
|
|
5171
5428
|
`Schedule ${schedule._id}: Time does not match. Current: ${currentHour}:${currentMinute}, Expected: ${scheduleHour}:${scheduleMinute}`
|
|
5172
5429
|
);
|
|
5173
5430
|
return false;
|
|
5174
5431
|
}
|
|
5175
|
-
|
|
5432
|
+
import_node_server_utils33.logger.info(
|
|
5176
5433
|
`Schedule ${schedule._id}: All conditions matched - Date is within range and time matches`
|
|
5177
5434
|
);
|
|
5178
5435
|
return true;
|
|
5179
5436
|
} catch (error) {
|
|
5180
|
-
|
|
5437
|
+
import_node_server_utils33.logger.error(
|
|
5181
5438
|
`Error checking schedule conditions for ${schedule._id}:`,
|
|
5182
5439
|
error
|
|
5183
5440
|
);
|
|
@@ -5186,40 +5443,40 @@ function useScheduleTaskService() {
|
|
|
5186
5443
|
}
|
|
5187
5444
|
async function processScheduledTasks(currentDate) {
|
|
5188
5445
|
try {
|
|
5189
|
-
|
|
5446
|
+
import_node_server_utils33.logger.info("Starting scheduled task processing...");
|
|
5190
5447
|
const scheduleTasks = await getAllScheduleTask();
|
|
5191
5448
|
if (!scheduleTasks || scheduleTasks.length === 0) {
|
|
5192
|
-
|
|
5449
|
+
import_node_server_utils33.logger.info("No schedule tasks found to process");
|
|
5193
5450
|
return { processed: 0, validated: 0 };
|
|
5194
5451
|
}
|
|
5195
|
-
|
|
5452
|
+
import_node_server_utils33.logger.info(`Found ${scheduleTasks.length} schedule tasks to check`);
|
|
5196
5453
|
let processedCount = 0;
|
|
5197
5454
|
let validatedCount = 0;
|
|
5198
5455
|
const validatedTasks = [];
|
|
5199
5456
|
for (const scheduleTask of scheduleTasks) {
|
|
5200
5457
|
try {
|
|
5201
|
-
|
|
5458
|
+
import_node_server_utils33.logger.info(
|
|
5202
5459
|
`Checking schedule ${scheduleTask._id} - ${scheduleTask.title}: time=${scheduleTask.time}, startDate=${scheduleTask.startDate}, endDate=${scheduleTask.endDate}`
|
|
5203
5460
|
);
|
|
5204
5461
|
const shouldRun = checkScheduleConditions(scheduleTask, currentDate);
|
|
5205
5462
|
if (!shouldRun) {
|
|
5206
|
-
|
|
5463
|
+
import_node_server_utils33.logger.info(
|
|
5207
5464
|
`Schedule ${scheduleTask._id} conditions not met, skipping`
|
|
5208
5465
|
);
|
|
5209
5466
|
continue;
|
|
5210
5467
|
}
|
|
5211
|
-
|
|
5468
|
+
import_node_server_utils33.logger.info(
|
|
5212
5469
|
`Schedule ${scheduleTask._id} conditions validated, creating area checklists`
|
|
5213
5470
|
);
|
|
5214
5471
|
if (!scheduleTask._id) {
|
|
5215
|
-
|
|
5472
|
+
import_node_server_utils33.logger.warn(`Schedule ${scheduleTask.title} has no _id, skipping`);
|
|
5216
5473
|
continue;
|
|
5217
5474
|
}
|
|
5218
5475
|
if (!scheduleTask.site) {
|
|
5219
|
-
|
|
5476
|
+
import_node_server_utils33.logger.warn(`Schedule ${scheduleTask._id} has no site, skipping`);
|
|
5220
5477
|
continue;
|
|
5221
5478
|
}
|
|
5222
|
-
|
|
5479
|
+
import_node_server_utils33.logger.info(
|
|
5223
5480
|
`Getting or creating parent checklist for schedule ${scheduleTask._id} in site ${scheduleTask.site}`
|
|
5224
5481
|
);
|
|
5225
5482
|
const parentChecklistIds = await createParentChecklist({
|
|
@@ -5227,7 +5484,7 @@ function useScheduleTaskService() {
|
|
|
5227
5484
|
createdAt: /* @__PURE__ */ new Date()
|
|
5228
5485
|
});
|
|
5229
5486
|
const parentChecklistId = Array.isArray(parentChecklistIds) ? parentChecklistIds[0] : parentChecklistIds;
|
|
5230
|
-
|
|
5487
|
+
import_node_server_utils33.logger.info(
|
|
5231
5488
|
`Using parent checklist ${parentChecklistId}, now creating/updating area checklists`
|
|
5232
5489
|
);
|
|
5233
5490
|
for (const area of scheduleTask.areas) {
|
|
@@ -5240,14 +5497,14 @@ function useScheduleTaskService() {
|
|
|
5240
5497
|
unit: unit.unit.toString(),
|
|
5241
5498
|
name: unit.name
|
|
5242
5499
|
}));
|
|
5243
|
-
|
|
5500
|
+
import_node_server_utils33.logger.info(
|
|
5244
5501
|
`Area ${area.name} (${areaId}): Using units from area details: ${JSON.stringify(
|
|
5245
5502
|
units
|
|
5246
5503
|
)}`
|
|
5247
5504
|
);
|
|
5248
5505
|
}
|
|
5249
5506
|
if (units.length === 0) {
|
|
5250
|
-
|
|
5507
|
+
import_node_server_utils33.logger.warn(
|
|
5251
5508
|
`Area ${area.name} (${areaId}): No units found, skipping area.`
|
|
5252
5509
|
);
|
|
5253
5510
|
continue;
|
|
@@ -5258,11 +5515,11 @@ function useScheduleTaskService() {
|
|
|
5258
5515
|
parentChecklistId.toString(),
|
|
5259
5516
|
areaId
|
|
5260
5517
|
);
|
|
5261
|
-
|
|
5518
|
+
import_node_server_utils33.logger.info(
|
|
5262
5519
|
`Area ${area.name} (${areaId}): Existing area checklist found: ${existingAreaChecklist ? "Yes" : "No"}`
|
|
5263
5520
|
);
|
|
5264
5521
|
if (existingAreaChecklist) {
|
|
5265
|
-
|
|
5522
|
+
import_node_server_utils33.logger.info(
|
|
5266
5523
|
`Area ${area.name} (${areaId}): Existing checklist content: ${JSON.stringify(
|
|
5267
5524
|
existingAreaChecklist.checklist
|
|
5268
5525
|
)}`
|
|
@@ -5270,7 +5527,7 @@ function useScheduleTaskService() {
|
|
|
5270
5527
|
}
|
|
5271
5528
|
} catch (error) {
|
|
5272
5529
|
existingAreaChecklist = null;
|
|
5273
|
-
|
|
5530
|
+
import_node_server_utils33.logger.info(
|
|
5274
5531
|
`Area ${area.name} (${areaId}): No existing area checklist found (exception).`
|
|
5275
5532
|
);
|
|
5276
5533
|
}
|
|
@@ -5284,7 +5541,7 @@ function useScheduleTaskService() {
|
|
|
5284
5541
|
...existingAreaChecklist.checklist || [],
|
|
5285
5542
|
newSet
|
|
5286
5543
|
];
|
|
5287
|
-
|
|
5544
|
+
import_node_server_utils33.logger.info(
|
|
5288
5545
|
`Area ${area.name} (${areaId}): Appending new set ${newSet.set} to checklist. Updated checklist: ${JSON.stringify(
|
|
5289
5546
|
updatedChecklist
|
|
5290
5547
|
)}`
|
|
@@ -5292,7 +5549,7 @@ function useScheduleTaskService() {
|
|
|
5292
5549
|
await updateAreaChecklist(existingAreaChecklist._id, {
|
|
5293
5550
|
checklist: updatedChecklist
|
|
5294
5551
|
});
|
|
5295
|
-
|
|
5552
|
+
import_node_server_utils33.logger.info(
|
|
5296
5553
|
`Appended set ${newSet.set} to area checklist for area ${area.name}`
|
|
5297
5554
|
);
|
|
5298
5555
|
try {
|
|
@@ -5300,13 +5557,13 @@ function useScheduleTaskService() {
|
|
|
5300
5557
|
parentChecklistId.toString(),
|
|
5301
5558
|
areaId
|
|
5302
5559
|
);
|
|
5303
|
-
|
|
5560
|
+
import_node_server_utils33.logger.info(
|
|
5304
5561
|
`Area ${area.name} (${areaId}): Checklist after update: ${JSON.stringify(
|
|
5305
5562
|
verifyChecklist.checklist
|
|
5306
5563
|
)}`
|
|
5307
5564
|
);
|
|
5308
5565
|
} catch (verifyError) {
|
|
5309
|
-
|
|
5566
|
+
import_node_server_utils33.logger.warn(
|
|
5310
5567
|
`Area ${area.name} (${areaId}): Error verifying checklist after update:`,
|
|
5311
5568
|
verifyError
|
|
5312
5569
|
);
|
|
@@ -5325,50 +5582,50 @@ function useScheduleTaskService() {
|
|
|
5325
5582
|
],
|
|
5326
5583
|
createdBy: scheduleTask.createdBy
|
|
5327
5584
|
};
|
|
5328
|
-
|
|
5585
|
+
import_node_server_utils33.logger.info(
|
|
5329
5586
|
`Area ${area.name} (${areaId}): Creating new area checklist with data: ${JSON.stringify(
|
|
5330
5587
|
checklistData
|
|
5331
5588
|
)}`
|
|
5332
5589
|
);
|
|
5333
5590
|
await createAreaChecklist(checklistData);
|
|
5334
|
-
|
|
5591
|
+
import_node_server_utils33.logger.info(`Created new area checklist for area ${area.name}`);
|
|
5335
5592
|
try {
|
|
5336
5593
|
const verifyChecklist = await getAreaChecklistByAreaAndSchedule(
|
|
5337
5594
|
parentChecklistId.toString(),
|
|
5338
5595
|
areaId
|
|
5339
5596
|
);
|
|
5340
|
-
|
|
5597
|
+
import_node_server_utils33.logger.info(
|
|
5341
5598
|
`Area ${area.name} (${areaId}): Checklist after creation: ${JSON.stringify(
|
|
5342
5599
|
verifyChecklist.checklist
|
|
5343
5600
|
)}`
|
|
5344
5601
|
);
|
|
5345
5602
|
} catch (verifyError) {
|
|
5346
|
-
|
|
5603
|
+
import_node_server_utils33.logger.warn(
|
|
5347
5604
|
`Area ${area.name} (${areaId}): Error verifying checklist after creation:`,
|
|
5348
5605
|
verifyError
|
|
5349
5606
|
);
|
|
5350
5607
|
}
|
|
5351
5608
|
}
|
|
5352
5609
|
} catch (error) {
|
|
5353
|
-
|
|
5610
|
+
import_node_server_utils33.logger.error(`Error processing area ${area.name}:`, error);
|
|
5354
5611
|
continue;
|
|
5355
5612
|
}
|
|
5356
5613
|
}
|
|
5357
5614
|
processedCount++;
|
|
5358
5615
|
validatedCount++;
|
|
5359
5616
|
validatedTasks.push(scheduleTask);
|
|
5360
|
-
|
|
5617
|
+
import_node_server_utils33.logger.info(
|
|
5361
5618
|
`Successfully processed schedule ${scheduleTask._id}, created/updated area checklists for all areas.`
|
|
5362
5619
|
);
|
|
5363
5620
|
} catch (error) {
|
|
5364
|
-
|
|
5621
|
+
import_node_server_utils33.logger.error(
|
|
5365
5622
|
`Error processing schedule task ${scheduleTask._id}:`,
|
|
5366
5623
|
error
|
|
5367
5624
|
);
|
|
5368
5625
|
continue;
|
|
5369
5626
|
}
|
|
5370
5627
|
}
|
|
5371
|
-
|
|
5628
|
+
import_node_server_utils33.logger.info(
|
|
5372
5629
|
`Scheduled task processing completed. Processed: ${processedCount}, Validated: ${validatedCount} tasks`
|
|
5373
5630
|
);
|
|
5374
5631
|
return {
|
|
@@ -5377,7 +5634,7 @@ function useScheduleTaskService() {
|
|
|
5377
5634
|
tasks: validatedTasks
|
|
5378
5635
|
};
|
|
5379
5636
|
} catch (error) {
|
|
5380
|
-
|
|
5637
|
+
import_node_server_utils33.logger.error("Error processing scheduled tasks:", error);
|
|
5381
5638
|
throw error;
|
|
5382
5639
|
}
|
|
5383
5640
|
}
|
|
@@ -5386,7 +5643,7 @@ function useScheduleTaskService() {
|
|
|
5386
5643
|
|
|
5387
5644
|
// src/controllers/hygiene-schedule-task.controller.ts
|
|
5388
5645
|
var import_joi17 = __toESM(require("joi"));
|
|
5389
|
-
var
|
|
5646
|
+
var import_node_server_utils34 = require("@7365admin1/node-server-utils");
|
|
5390
5647
|
function useScheduleTaskController() {
|
|
5391
5648
|
const {
|
|
5392
5649
|
createScheduleTask: _createScheduleTask,
|
|
@@ -5404,8 +5661,8 @@ function useScheduleTaskController() {
|
|
|
5404
5661
|
const payload = { ...req.body, ...req.params, createdBy };
|
|
5405
5662
|
const { error } = scheduleTaskSchema.validate(payload);
|
|
5406
5663
|
if (error) {
|
|
5407
|
-
|
|
5408
|
-
next(new
|
|
5664
|
+
import_node_server_utils34.logger.log({ level: "error", message: error.message });
|
|
5665
|
+
next(new import_node_server_utils34.BadRequestError(error.message));
|
|
5409
5666
|
return;
|
|
5410
5667
|
}
|
|
5411
5668
|
try {
|
|
@@ -5413,7 +5670,7 @@ function useScheduleTaskController() {
|
|
|
5413
5670
|
res.status(201).json({ message: "Schedule task created successfully.", id });
|
|
5414
5671
|
return;
|
|
5415
5672
|
} catch (error2) {
|
|
5416
|
-
|
|
5673
|
+
import_node_server_utils34.logger.log({ level: "error", message: error2.message });
|
|
5417
5674
|
next(error2);
|
|
5418
5675
|
return;
|
|
5419
5676
|
}
|
|
@@ -5428,8 +5685,8 @@ function useScheduleTaskController() {
|
|
|
5428
5685
|
});
|
|
5429
5686
|
const { error } = validation.validate(query);
|
|
5430
5687
|
if (error) {
|
|
5431
|
-
|
|
5432
|
-
next(new
|
|
5688
|
+
import_node_server_utils34.logger.log({ level: "error", message: error.message });
|
|
5689
|
+
next(new import_node_server_utils34.BadRequestError(error.message));
|
|
5433
5690
|
return;
|
|
5434
5691
|
}
|
|
5435
5692
|
const page = parseInt(req.query.page) ?? 1;
|
|
@@ -5446,7 +5703,7 @@ function useScheduleTaskController() {
|
|
|
5446
5703
|
res.json(data);
|
|
5447
5704
|
return;
|
|
5448
5705
|
} catch (error2) {
|
|
5449
|
-
|
|
5706
|
+
import_node_server_utils34.logger.log({ level: "error", message: error2.message });
|
|
5450
5707
|
next(error2);
|
|
5451
5708
|
return;
|
|
5452
5709
|
}
|
|
@@ -5461,8 +5718,8 @@ function useScheduleTaskController() {
|
|
|
5461
5718
|
});
|
|
5462
5719
|
const { error } = validation.validate(query);
|
|
5463
5720
|
if (error) {
|
|
5464
|
-
|
|
5465
|
-
next(new
|
|
5721
|
+
import_node_server_utils34.logger.log({ level: "error", message: error.message });
|
|
5722
|
+
next(new import_node_server_utils34.BadRequestError(error.message));
|
|
5466
5723
|
return;
|
|
5467
5724
|
}
|
|
5468
5725
|
const page = parseInt(req.query.page) ?? 1;
|
|
@@ -5479,7 +5736,7 @@ function useScheduleTaskController() {
|
|
|
5479
5736
|
res.json(data);
|
|
5480
5737
|
return;
|
|
5481
5738
|
} catch (error2) {
|
|
5482
|
-
|
|
5739
|
+
import_node_server_utils34.logger.log({ level: "error", message: error2.message });
|
|
5483
5740
|
next(error2);
|
|
5484
5741
|
return;
|
|
5485
5742
|
}
|
|
@@ -5489,8 +5746,8 @@ function useScheduleTaskController() {
|
|
|
5489
5746
|
const _id = req.params.id;
|
|
5490
5747
|
const { error, value } = validation.validate(_id);
|
|
5491
5748
|
if (error) {
|
|
5492
|
-
|
|
5493
|
-
next(new
|
|
5749
|
+
import_node_server_utils34.logger.log({ level: "error", message: error.message });
|
|
5750
|
+
next(new import_node_server_utils34.BadRequestError(error.message));
|
|
5494
5751
|
return;
|
|
5495
5752
|
}
|
|
5496
5753
|
try {
|
|
@@ -5498,7 +5755,7 @@ function useScheduleTaskController() {
|
|
|
5498
5755
|
res.json(data);
|
|
5499
5756
|
return;
|
|
5500
5757
|
} catch (error2) {
|
|
5501
|
-
|
|
5758
|
+
import_node_server_utils34.logger.log({ level: "error", message: error2.message });
|
|
5502
5759
|
next(error2);
|
|
5503
5760
|
return;
|
|
5504
5761
|
}
|
|
@@ -5521,8 +5778,8 @@ function useScheduleTaskController() {
|
|
|
5521
5778
|
});
|
|
5522
5779
|
const { error } = validation.validate(payload);
|
|
5523
5780
|
if (error) {
|
|
5524
|
-
|
|
5525
|
-
next(new
|
|
5781
|
+
import_node_server_utils34.logger.log({ level: "error", message: error.message });
|
|
5782
|
+
next(new import_node_server_utils34.BadRequestError(error.message));
|
|
5526
5783
|
return;
|
|
5527
5784
|
}
|
|
5528
5785
|
try {
|
|
@@ -5531,7 +5788,7 @@ function useScheduleTaskController() {
|
|
|
5531
5788
|
res.json({ message: "Schedule task updated successfully." });
|
|
5532
5789
|
return;
|
|
5533
5790
|
} catch (error2) {
|
|
5534
|
-
|
|
5791
|
+
import_node_server_utils34.logger.log({ level: "error", message: error2.message });
|
|
5535
5792
|
next(error2);
|
|
5536
5793
|
return;
|
|
5537
5794
|
}
|
|
@@ -5544,6 +5801,275 @@ function useScheduleTaskController() {
|
|
|
5544
5801
|
updateScheduleTask
|
|
5545
5802
|
};
|
|
5546
5803
|
}
|
|
5804
|
+
|
|
5805
|
+
// src/services/hygiene-qr.service.ts
|
|
5806
|
+
var import_node_server_utils35 = require("@7365admin1/node-server-utils");
|
|
5807
|
+
var import_puppeteer = require("puppeteer");
|
|
5808
|
+
var import_qrcode = __toESM(require("qrcode"));
|
|
5809
|
+
function useQRService() {
|
|
5810
|
+
async function generateQRDataUrl(qrUrl) {
|
|
5811
|
+
return import_qrcode.default.toDataURL(qrUrl, {
|
|
5812
|
+
width: 350,
|
|
5813
|
+
margin: 2,
|
|
5814
|
+
errorCorrectionLevel: "M",
|
|
5815
|
+
color: {
|
|
5816
|
+
dark: "#000000",
|
|
5817
|
+
light: "#FFFFFF"
|
|
5818
|
+
}
|
|
5819
|
+
});
|
|
5820
|
+
}
|
|
5821
|
+
async function generateQRImage(qrUrl) {
|
|
5822
|
+
try {
|
|
5823
|
+
const qrDataUrl = await generateQRDataUrl(qrUrl);
|
|
5824
|
+
const browser = await (0, import_puppeteer.launch)({
|
|
5825
|
+
headless: true,
|
|
5826
|
+
executablePath: process.env.CHROME_BINARY,
|
|
5827
|
+
args: [`--no-sandbox`, `--disable-gpu`, `--disable-dev-shm-usage`]
|
|
5828
|
+
});
|
|
5829
|
+
const page = await browser.newPage();
|
|
5830
|
+
await page.setViewport({
|
|
5831
|
+
width: 400,
|
|
5832
|
+
height: 400
|
|
5833
|
+
});
|
|
5834
|
+
const html = `
|
|
5835
|
+
<!DOCTYPE html>
|
|
5836
|
+
<html>
|
|
5837
|
+
<head>
|
|
5838
|
+
<meta charset="UTF-8">
|
|
5839
|
+
<style>
|
|
5840
|
+
body {
|
|
5841
|
+
margin: 0;
|
|
5842
|
+
padding: 20px;
|
|
5843
|
+
display: flex;
|
|
5844
|
+
justify-content: center;
|
|
5845
|
+
align-items: center;
|
|
5846
|
+
background: white;
|
|
5847
|
+
min-height: 100vh;
|
|
5848
|
+
}
|
|
5849
|
+
#qr-image {
|
|
5850
|
+
display: block;
|
|
5851
|
+
width: 350px;
|
|
5852
|
+
height: 350px;
|
|
5853
|
+
}
|
|
5854
|
+
</style>
|
|
5855
|
+
</head>
|
|
5856
|
+
<body>
|
|
5857
|
+
<img id="qr-image" src="${qrDataUrl}" alt="QR Code" />
|
|
5858
|
+
</body>
|
|
5859
|
+
</html>
|
|
5860
|
+
`;
|
|
5861
|
+
await page.setContent(html, {
|
|
5862
|
+
waitUntil: ["load", "networkidle0"]
|
|
5863
|
+
});
|
|
5864
|
+
await page.waitForSelector("#qr-image", { timeout: 1e4 });
|
|
5865
|
+
const imageBuffer = await page.screenshot({
|
|
5866
|
+
type: "png",
|
|
5867
|
+
clip: {
|
|
5868
|
+
x: 0,
|
|
5869
|
+
y: 0,
|
|
5870
|
+
width: 400,
|
|
5871
|
+
height: 400
|
|
5872
|
+
}
|
|
5873
|
+
});
|
|
5874
|
+
await browser.close();
|
|
5875
|
+
return imageBuffer;
|
|
5876
|
+
} catch (error) {
|
|
5877
|
+
import_node_server_utils35.logger.log({
|
|
5878
|
+
level: "error",
|
|
5879
|
+
message: `Failed to generate QR image: ${error.message}`
|
|
5880
|
+
});
|
|
5881
|
+
throw error;
|
|
5882
|
+
}
|
|
5883
|
+
}
|
|
5884
|
+
async function generateQRPDF(qrUrl, title) {
|
|
5885
|
+
try {
|
|
5886
|
+
const qrDataUrl = await generateQRDataUrl(qrUrl);
|
|
5887
|
+
const browser = await (0, import_puppeteer.launch)({
|
|
5888
|
+
headless: true,
|
|
5889
|
+
executablePath: process.env.CHROME_BINARY,
|
|
5890
|
+
args: [`--no-sandbox`, `--disable-gpu`, `--disable-dev-shm-usage`]
|
|
5891
|
+
});
|
|
5892
|
+
const page = await browser.newPage();
|
|
5893
|
+
await page.setViewport({
|
|
5894
|
+
width: 800,
|
|
5895
|
+
height: 1100
|
|
5896
|
+
});
|
|
5897
|
+
const escapedTitle = (title || "Cleaning Schedule QR Code").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
5898
|
+
const html = `
|
|
5899
|
+
<!DOCTYPE html>
|
|
5900
|
+
<html>
|
|
5901
|
+
<head>
|
|
5902
|
+
<meta charset="UTF-8">
|
|
5903
|
+
<style>
|
|
5904
|
+
* {
|
|
5905
|
+
margin: 0;
|
|
5906
|
+
padding: 0;
|
|
5907
|
+
box-sizing: border-box;
|
|
5908
|
+
}
|
|
5909
|
+
body {
|
|
5910
|
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
5911
|
+
background: white;
|
|
5912
|
+
padding: 60px 40px;
|
|
5913
|
+
display: flex;
|
|
5914
|
+
flex-direction: column;
|
|
5915
|
+
align-items: center;
|
|
5916
|
+
justify-content: center;
|
|
5917
|
+
min-height: 100vh;
|
|
5918
|
+
}
|
|
5919
|
+
.qr-container {
|
|
5920
|
+
text-align: center;
|
|
5921
|
+
background: transparent;
|
|
5922
|
+
padding: 0;
|
|
5923
|
+
}
|
|
5924
|
+
h1 {
|
|
5925
|
+
font-size: 28px;
|
|
5926
|
+
color: #333;
|
|
5927
|
+
margin-bottom: 20px;
|
|
5928
|
+
font-weight: 600;
|
|
5929
|
+
}
|
|
5930
|
+
.qr-wrapper {
|
|
5931
|
+
display: inline-block;
|
|
5932
|
+
padding: 0;
|
|
5933
|
+
background: transparent;
|
|
5934
|
+
border: none;
|
|
5935
|
+
border-radius: 0;
|
|
5936
|
+
margin: 20px 0;
|
|
5937
|
+
}
|
|
5938
|
+
#qr-image {
|
|
5939
|
+
display: block;
|
|
5940
|
+
width: 350px;
|
|
5941
|
+
height: 350px;
|
|
5942
|
+
}
|
|
5943
|
+
.instructions {
|
|
5944
|
+
margin-top: 30px;
|
|
5945
|
+
font-size: 16px;
|
|
5946
|
+
color: #666;
|
|
5947
|
+
line-height: 1.6;
|
|
5948
|
+
}
|
|
5949
|
+
.url-info {
|
|
5950
|
+
margin-top: 20px;
|
|
5951
|
+
padding: 15px;
|
|
5952
|
+
background: #f5f5f5;
|
|
5953
|
+
border-radius: 6px;
|
|
5954
|
+
font-size: 12px;
|
|
5955
|
+
color: #888;
|
|
5956
|
+
word-break: break-all;
|
|
5957
|
+
}
|
|
5958
|
+
</style>
|
|
5959
|
+
</head>
|
|
5960
|
+
<body>
|
|
5961
|
+
<div class="qr-container">
|
|
5962
|
+
<h1>${escapedTitle}</h1>
|
|
5963
|
+
<div class="qr-wrapper">
|
|
5964
|
+
<img id="qr-image" src="${qrDataUrl}" alt="QR Code" />
|
|
5965
|
+
</div>
|
|
5966
|
+
<div class="instructions">
|
|
5967
|
+
<p>Scan this QR code to access the cleaning schedule.</p>
|
|
5968
|
+
</div>
|
|
5969
|
+
<div class="url-info">
|
|
5970
|
+
${qrUrl}
|
|
5971
|
+
</div>
|
|
5972
|
+
</div>
|
|
5973
|
+
</body>
|
|
5974
|
+
</html>
|
|
5975
|
+
`;
|
|
5976
|
+
await page.setContent(html, {
|
|
5977
|
+
waitUntil: ["load", "networkidle0"]
|
|
5978
|
+
});
|
|
5979
|
+
await page.waitForSelector("#qr-image", { timeout: 1e4 });
|
|
5980
|
+
await page.waitForFunction(
|
|
5981
|
+
() => {
|
|
5982
|
+
const img = document.getElementById("qr-image");
|
|
5983
|
+
return img && img.complete && img.naturalWidth > 0;
|
|
5984
|
+
},
|
|
5985
|
+
{ timeout: 1e4 }
|
|
5986
|
+
);
|
|
5987
|
+
const pdfBuffer = await page.pdf({
|
|
5988
|
+
format: "A4",
|
|
5989
|
+
printBackground: true,
|
|
5990
|
+
margin: {
|
|
5991
|
+
top: "20mm",
|
|
5992
|
+
right: "20mm",
|
|
5993
|
+
bottom: "20mm",
|
|
5994
|
+
left: "20mm"
|
|
5995
|
+
}
|
|
5996
|
+
});
|
|
5997
|
+
await browser.close();
|
|
5998
|
+
return pdfBuffer;
|
|
5999
|
+
} catch (error) {
|
|
6000
|
+
import_node_server_utils35.logger.log({
|
|
6001
|
+
level: "error",
|
|
6002
|
+
message: `Failed to generate QR PDF: ${error.message}`
|
|
6003
|
+
});
|
|
6004
|
+
throw error;
|
|
6005
|
+
}
|
|
6006
|
+
}
|
|
6007
|
+
return {
|
|
6008
|
+
generateQRImage,
|
|
6009
|
+
generateQRPDF
|
|
6010
|
+
};
|
|
6011
|
+
}
|
|
6012
|
+
|
|
6013
|
+
// src/controllers/hygiene-qr.controller.ts
|
|
6014
|
+
var import_joi18 = __toESM(require("joi"));
|
|
6015
|
+
var import_node_server_utils36 = require("@7365admin1/node-server-utils");
|
|
6016
|
+
function useQRController() {
|
|
6017
|
+
const { generateQRImage: _generateQRImage, generateQRPDF: _generateQRPDF } = useQRService();
|
|
6018
|
+
async function generateQR(req, res, next) {
|
|
6019
|
+
const validation = import_joi18.default.object({
|
|
6020
|
+
url: import_joi18.default.string().uri().required(),
|
|
6021
|
+
filename: import_joi18.default.string().optional().allow("", null),
|
|
6022
|
+
title: import_joi18.default.string().optional().allow("", null),
|
|
6023
|
+
download: import_joi18.default.boolean().optional().default(false)
|
|
6024
|
+
});
|
|
6025
|
+
const query = { ...req.query };
|
|
6026
|
+
const { error, value } = validation.validate(query);
|
|
6027
|
+
if (error) {
|
|
6028
|
+
import_node_server_utils36.logger.log({ level: "error", message: error.message });
|
|
6029
|
+
next(new import_node_server_utils36.BadRequestError(error.message));
|
|
6030
|
+
return;
|
|
6031
|
+
}
|
|
6032
|
+
try {
|
|
6033
|
+
const { url, filename, title, download } = value;
|
|
6034
|
+
if (download) {
|
|
6035
|
+
const pdfBuffer = await _generateQRPDF(url, title);
|
|
6036
|
+
if (!pdfBuffer || pdfBuffer.length === 0) {
|
|
6037
|
+
throw new Error("Generated QR PDF is empty or invalid.");
|
|
6038
|
+
}
|
|
6039
|
+
const sanitizedFilename = (filename || "qrcode").replace(/['"]/g, "").replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
6040
|
+
const date = /* @__PURE__ */ new Date();
|
|
6041
|
+
const formattedDate = `${String(date.getMonth() + 1).padStart(
|
|
6042
|
+
2,
|
|
6043
|
+
"0"
|
|
6044
|
+
)}-${String(date.getDate()).padStart(2, "0")}-${date.getFullYear()}`;
|
|
6045
|
+
res.setHeader("Content-Type", "application/pdf");
|
|
6046
|
+
res.setHeader(
|
|
6047
|
+
"Content-Disposition",
|
|
6048
|
+
`attachment; filename="${sanitizedFilename}-${formattedDate}.pdf"`
|
|
6049
|
+
);
|
|
6050
|
+
res.setHeader("Content-Length", pdfBuffer.length);
|
|
6051
|
+
res.end(pdfBuffer);
|
|
6052
|
+
} else {
|
|
6053
|
+
const imageBuffer = await _generateQRImage(url);
|
|
6054
|
+
if (!imageBuffer || imageBuffer.length === 0) {
|
|
6055
|
+
throw new Error("Generated QR image is empty or invalid.");
|
|
6056
|
+
}
|
|
6057
|
+
res.setHeader("Content-Type", "image/png");
|
|
6058
|
+
res.setHeader("Cache-Control", "public, max-age=3600");
|
|
6059
|
+
res.setHeader("Content-Length", imageBuffer.length);
|
|
6060
|
+
res.end(imageBuffer);
|
|
6061
|
+
}
|
|
6062
|
+
return;
|
|
6063
|
+
} catch (error2) {
|
|
6064
|
+
import_node_server_utils36.logger.log({ level: "error", message: error2.message });
|
|
6065
|
+
next(error2);
|
|
6066
|
+
return;
|
|
6067
|
+
}
|
|
6068
|
+
}
|
|
6069
|
+
return {
|
|
6070
|
+
generateQR
|
|
6071
|
+
};
|
|
6072
|
+
}
|
|
5547
6073
|
// Annotate the CommonJS export names for ESM import in node:
|
|
5548
6074
|
0 && (module.exports = {
|
|
5549
6075
|
MArea,
|
|
@@ -5571,6 +6097,7 @@ function useScheduleTaskController() {
|
|
|
5571
6097
|
useAreaChecklistRepo,
|
|
5572
6098
|
useAreaChecklistService,
|
|
5573
6099
|
useAreaController,
|
|
6100
|
+
useAreaExportService,
|
|
5574
6101
|
useAreaRepo,
|
|
5575
6102
|
useAreaService,
|
|
5576
6103
|
useCheckOutItemController,
|
|
@@ -5580,6 +6107,8 @@ function useScheduleTaskController() {
|
|
|
5580
6107
|
useHygieneDashboardRepository,
|
|
5581
6108
|
useParentChecklistController,
|
|
5582
6109
|
useParentChecklistRepo,
|
|
6110
|
+
useQRController,
|
|
6111
|
+
useQRService,
|
|
5583
6112
|
useScheduleTaskController,
|
|
5584
6113
|
useScheduleTaskRepository,
|
|
5585
6114
|
useScheduleTaskService,
|
|
@@ -5589,6 +6118,7 @@ function useScheduleTaskController() {
|
|
|
5589
6118
|
useSupplyController,
|
|
5590
6119
|
useSupplyRepository,
|
|
5591
6120
|
useUnitController,
|
|
6121
|
+
useUnitExportService,
|
|
5592
6122
|
useUnitRepository,
|
|
5593
6123
|
useUnitService
|
|
5594
6124
|
});
|