@iservice365/module-hygiene 1.3.0 → 1.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 +31 -12
- package/dist/index.js +381 -107
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +376 -102
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -42,7 +42,6 @@ __export(src_exports, {
|
|
|
42
42
|
allowedDays: () => allowedDays,
|
|
43
43
|
allowedFrequency: () => allowedFrequency,
|
|
44
44
|
allowedMonths: () => allowedMonths,
|
|
45
|
-
allowedQuarter: () => allowedQuarter,
|
|
46
45
|
allowedRequestItemStatus: () => allowedRequestItemStatus,
|
|
47
46
|
allowedStatus: () => allowedStatus,
|
|
48
47
|
allowedTypes: () => allowedTypes,
|
|
@@ -68,6 +67,7 @@ __export(src_exports, {
|
|
|
68
67
|
useRequestItemService: () => useRequestItemService,
|
|
69
68
|
useScheduleTaskController: () => useScheduleTaskController,
|
|
70
69
|
useScheduleTaskRepository: () => useScheduleTaskRepository,
|
|
70
|
+
useScheduleTaskService: () => useScheduleTaskService,
|
|
71
71
|
useStockController: () => useStockController,
|
|
72
72
|
useStockRepository: () => useStockRepository,
|
|
73
73
|
useStockService: () => useStockService,
|
|
@@ -272,12 +272,9 @@ function useAreaRepo() {
|
|
|
272
272
|
throw error;
|
|
273
273
|
}
|
|
274
274
|
}
|
|
275
|
-
async function getAreasForChecklist({
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
}) {
|
|
279
|
-
const query = { type, status: { $ne: "deleted" } };
|
|
280
|
-
const cacheOptions = { type };
|
|
275
|
+
async function getAreasForChecklist(site) {
|
|
276
|
+
const query = { status: { $ne: "deleted" } };
|
|
277
|
+
const cacheOptions = {};
|
|
281
278
|
try {
|
|
282
279
|
site = new import_mongodb2.ObjectId(site);
|
|
283
280
|
query.site = site;
|
|
@@ -297,6 +294,7 @@ function useAreaRepo() {
|
|
|
297
294
|
{
|
|
298
295
|
$project: {
|
|
299
296
|
name: 1,
|
|
297
|
+
type: 1,
|
|
300
298
|
set: 1,
|
|
301
299
|
units: 1
|
|
302
300
|
}
|
|
@@ -356,6 +354,28 @@ function useAreaRepo() {
|
|
|
356
354
|
throw error;
|
|
357
355
|
}
|
|
358
356
|
}
|
|
357
|
+
async function getAreaByMultipleId(_id) {
|
|
358
|
+
for (let i = 0; i < _id.length; i++) {
|
|
359
|
+
try {
|
|
360
|
+
_id[i] = new import_mongodb2.ObjectId(_id[i]);
|
|
361
|
+
} catch (error) {
|
|
362
|
+
throw new import_node_server_utils2.BadRequestError("Invalid area ID format.");
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
const query = {
|
|
366
|
+
_id: { $in: _id },
|
|
367
|
+
status: { $ne: "deleted" }
|
|
368
|
+
};
|
|
369
|
+
try {
|
|
370
|
+
const data = await collection.aggregate([{ $match: query }]).toArray();
|
|
371
|
+
if (!data || data.length === 0) {
|
|
372
|
+
throw new import_node_server_utils2.NotFoundError("Area not found.");
|
|
373
|
+
}
|
|
374
|
+
return data;
|
|
375
|
+
} catch (error) {
|
|
376
|
+
throw error;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
359
379
|
async function verifyAreaByUnitId(unitId) {
|
|
360
380
|
try {
|
|
361
381
|
unitId = new import_mongodb2.ObjectId(unitId);
|
|
@@ -517,6 +537,7 @@ function useAreaRepo() {
|
|
|
517
537
|
getAreas,
|
|
518
538
|
getAreasForChecklist,
|
|
519
539
|
getAreaById,
|
|
540
|
+
getAreaByMultipleId,
|
|
520
541
|
verifyAreaByUnitId,
|
|
521
542
|
updateArea,
|
|
522
543
|
updateAreaChecklist,
|
|
@@ -1692,6 +1713,7 @@ var import_mongodb7 = require("mongodb");
|
|
|
1692
1713
|
var allowedChecklistStatus = ["ready", "completed"];
|
|
1693
1714
|
var areaChecklistSchema = import_joi7.default.object({
|
|
1694
1715
|
schedule: import_joi7.default.string().hex().required(),
|
|
1716
|
+
area: import_joi7.default.string().hex().required(),
|
|
1695
1717
|
name: import_joi7.default.string().required(),
|
|
1696
1718
|
type: import_joi7.default.string().valid(...allowedTypes).required(),
|
|
1697
1719
|
checklist: import_joi7.default.array().items(
|
|
@@ -1719,6 +1741,13 @@ function MAreaChecklist(value) {
|
|
|
1719
1741
|
throw new import_node_server_utils12.BadRequestError("Invalid schedule ID format.");
|
|
1720
1742
|
}
|
|
1721
1743
|
}
|
|
1744
|
+
if (value.area) {
|
|
1745
|
+
try {
|
|
1746
|
+
value.area = new import_mongodb7.ObjectId(value.area);
|
|
1747
|
+
} catch (error2) {
|
|
1748
|
+
throw new import_node_server_utils12.BadRequestError("Invalid area ID format.");
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1722
1751
|
if (value.checklist && Array.isArray(value.checklist)) {
|
|
1723
1752
|
value.checklist = value.checklist.map((checklistItem) => {
|
|
1724
1753
|
return {
|
|
@@ -1736,6 +1765,7 @@ function MAreaChecklist(value) {
|
|
|
1736
1765
|
}
|
|
1737
1766
|
return {
|
|
1738
1767
|
schedule: value.schedule,
|
|
1768
|
+
area: value.area,
|
|
1739
1769
|
name: value.name,
|
|
1740
1770
|
type: value.type,
|
|
1741
1771
|
checklist: value.checklist || [],
|
|
@@ -2434,19 +2464,17 @@ function useAreaChecklistService() {
|
|
|
2434
2464
|
const results = [];
|
|
2435
2465
|
let totalChecklistsCreated = 0;
|
|
2436
2466
|
const BATCH_SIZE = 10;
|
|
2437
|
-
const
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
if (commonAreas.length > 0) {
|
|
2443
|
-
for (let i = 0; i < commonAreas.length; i += BATCH_SIZE) {
|
|
2444
|
-
const batch = commonAreas.slice(i, i + BATCH_SIZE);
|
|
2467
|
+
const areasResult = await getAreasForChecklist(value.site);
|
|
2468
|
+
const areas = areasResult || [];
|
|
2469
|
+
if (areas.length > 0) {
|
|
2470
|
+
for (let i = 0; i < areas.length; i += BATCH_SIZE) {
|
|
2471
|
+
const batch = areas.slice(i, i + BATCH_SIZE);
|
|
2445
2472
|
const batchPromises = batch.map(async (area) => {
|
|
2446
2473
|
const checklistData = {
|
|
2447
2474
|
schedule: value.schedule,
|
|
2475
|
+
area: area._id.toString(),
|
|
2448
2476
|
name: area.name,
|
|
2449
|
-
type:
|
|
2477
|
+
type: area.type,
|
|
2450
2478
|
checklist: area.units && area.units.length > 0 ? Array.from({ length: area.set || 1 }, (_, index) => ({
|
|
2451
2479
|
set: index + 1,
|
|
2452
2480
|
units: area.units.map((unit) => ({
|
|
@@ -2466,51 +2494,11 @@ function useAreaChecklistService() {
|
|
|
2466
2494
|
results.push(...batchResults);
|
|
2467
2495
|
}
|
|
2468
2496
|
import_node_server_utils14.logger.info(
|
|
2469
|
-
`Created ${
|
|
2497
|
+
`Created ${areas.length} common area checklists for site: ${value.site}`
|
|
2470
2498
|
);
|
|
2471
2499
|
} else {
|
|
2472
2500
|
import_node_server_utils14.logger.warn(`No common areas found for site: ${value.site}`);
|
|
2473
2501
|
}
|
|
2474
|
-
const toiletAreasResult = await getAreasForChecklist({
|
|
2475
|
-
site: value.site,
|
|
2476
|
-
type: "toilet"
|
|
2477
|
-
});
|
|
2478
|
-
const toiletAreas = toiletAreasResult || [];
|
|
2479
|
-
if (toiletAreas.length > 0) {
|
|
2480
|
-
for (let i = 0; i < toiletAreas.length; i += BATCH_SIZE) {
|
|
2481
|
-
const batch = toiletAreas.slice(i, i + BATCH_SIZE);
|
|
2482
|
-
const batchPromises = batch.map(async (toiletLocation) => {
|
|
2483
|
-
const checklistData = {
|
|
2484
|
-
schedule: value.schedule,
|
|
2485
|
-
name: toiletLocation.name,
|
|
2486
|
-
type: "toilet",
|
|
2487
|
-
checklist: toiletLocation.units && toiletLocation.units.length > 0 ? Array.from(
|
|
2488
|
-
{ length: toiletLocation.set || 1 },
|
|
2489
|
-
(_, index) => ({
|
|
2490
|
-
set: index + 1,
|
|
2491
|
-
units: toiletLocation.units.map((unit) => ({
|
|
2492
|
-
unit: unit.unit.toString(),
|
|
2493
|
-
name: unit.name
|
|
2494
|
-
}))
|
|
2495
|
-
})
|
|
2496
|
-
) : []
|
|
2497
|
-
};
|
|
2498
|
-
const insertedId = await _createAreaChecklist(
|
|
2499
|
-
checklistData,
|
|
2500
|
-
session
|
|
2501
|
-
);
|
|
2502
|
-
totalChecklistsCreated++;
|
|
2503
|
-
return insertedId;
|
|
2504
|
-
});
|
|
2505
|
-
const batchResults = await Promise.all(batchPromises);
|
|
2506
|
-
results.push(...batchResults);
|
|
2507
|
-
}
|
|
2508
|
-
import_node_server_utils14.logger.info(
|
|
2509
|
-
`Created ${toiletAreas.length} toilet area checklists for site: ${value.site}`
|
|
2510
|
-
);
|
|
2511
|
-
} else {
|
|
2512
|
-
import_node_server_utils14.logger.warn(`No toilet locations found for site: ${value.site}`);
|
|
2513
|
-
}
|
|
2514
2502
|
await session?.commitTransaction();
|
|
2515
2503
|
import_node_server_utils14.logger.info(
|
|
2516
2504
|
`Successfully created ${totalChecklistsCreated} area checklists for site: ${value.site}`
|
|
@@ -4133,24 +4121,22 @@ function useRequestItemController() {
|
|
|
4133
4121
|
var import_node_server_utils27 = require("@iservice365/node-server-utils");
|
|
4134
4122
|
var import_joi15 = __toESM(require("joi"));
|
|
4135
4123
|
var import_mongodb15 = require("mongodb");
|
|
4136
|
-
var allowedFrequency = [
|
|
4137
|
-
|
|
4138
|
-
"
|
|
4139
|
-
"
|
|
4140
|
-
"
|
|
4141
|
-
"Thu",
|
|
4142
|
-
"Fri",
|
|
4143
|
-
"Sat",
|
|
4144
|
-
"Sun"
|
|
4124
|
+
var allowedFrequency = [
|
|
4125
|
+
"daily",
|
|
4126
|
+
"weekly",
|
|
4127
|
+
"monthly",
|
|
4128
|
+
"annually"
|
|
4145
4129
|
];
|
|
4146
|
-
var
|
|
4147
|
-
|
|
4148
|
-
"
|
|
4149
|
-
"
|
|
4150
|
-
"
|
|
4151
|
-
"
|
|
4152
|
-
"
|
|
4130
|
+
var allowedDays = [
|
|
4131
|
+
"Monday",
|
|
4132
|
+
"Tuesday",
|
|
4133
|
+
"Wednesday",
|
|
4134
|
+
"Thursday",
|
|
4135
|
+
"Friday",
|
|
4136
|
+
"Saturday",
|
|
4137
|
+
"Sunday"
|
|
4153
4138
|
];
|
|
4139
|
+
var allowedWeekOfMonth = ["start", "end"];
|
|
4154
4140
|
var allowedMonths = [
|
|
4155
4141
|
"January",
|
|
4156
4142
|
"February",
|
|
@@ -4169,22 +4155,11 @@ var scheduleTaskSchema = import_joi15.default.object({
|
|
|
4169
4155
|
site: import_joi15.default.string().hex().required(),
|
|
4170
4156
|
title: import_joi15.default.string().required(),
|
|
4171
4157
|
frequency: import_joi15.default.string().valid(...allowedFrequency).required(),
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
}),
|
|
4178
|
-
quarter: import_joi15.default.string().valid(...allowedQuarter).when("frequency", {
|
|
4179
|
-
is: "quarter",
|
|
4180
|
-
then: import_joi15.default.required(),
|
|
4181
|
-
otherwise: import_joi15.default.optional().allow("", null)
|
|
4182
|
-
}),
|
|
4183
|
-
month: import_joi15.default.string().valid(...allowedMonths).when("frequency", {
|
|
4184
|
-
is: import_joi15.default.string().valid("quarter", "year"),
|
|
4185
|
-
then: import_joi15.default.required(),
|
|
4186
|
-
otherwise: import_joi15.default.optional().allow("", null)
|
|
4187
|
-
}),
|
|
4158
|
+
time: import_joi15.default.string().pattern(/^([0-1]\d|2[0-3]):([0-5]\d)$/).required(),
|
|
4159
|
+
day: import_joi15.default.array().items(import_joi15.default.string().valid(...allowedDays)).optional().allow(null),
|
|
4160
|
+
weekOfMonth: import_joi15.default.string().valid(...allowedWeekOfMonth).optional().allow("", null),
|
|
4161
|
+
month: import_joi15.default.string().valid(...allowedMonths).optional().allow("", null),
|
|
4162
|
+
date: import_joi15.default.number().min(1).max(31).optional().allow(null),
|
|
4188
4163
|
description: import_joi15.default.string().optional().allow("", null),
|
|
4189
4164
|
areas: import_joi15.default.array().min(1).items(
|
|
4190
4165
|
import_joi15.default.object({
|
|
@@ -4222,10 +4197,11 @@ function MScheduleTask(value) {
|
|
|
4222
4197
|
site: value.site,
|
|
4223
4198
|
title: value.title,
|
|
4224
4199
|
frequency: value.frequency,
|
|
4200
|
+
time: value.time,
|
|
4225
4201
|
day: value.day,
|
|
4226
4202
|
weekOfMonth: value.weekOfMonth,
|
|
4227
|
-
quarter: value.quarter,
|
|
4228
4203
|
month: value.month,
|
|
4204
|
+
date: value.date,
|
|
4229
4205
|
description: value.description,
|
|
4230
4206
|
areas: value.areas,
|
|
4231
4207
|
status: "active",
|
|
@@ -4341,6 +4317,73 @@ function useScheduleTaskRepository() {
|
|
|
4341
4317
|
throw error;
|
|
4342
4318
|
}
|
|
4343
4319
|
}
|
|
4320
|
+
async function getAllScheduleTask() {
|
|
4321
|
+
const query = {
|
|
4322
|
+
status: { $ne: "deleted" }
|
|
4323
|
+
};
|
|
4324
|
+
try {
|
|
4325
|
+
const items = await collection.aggregate([{ $match: query }, { $sort: { _id: -1 } }]).toArray();
|
|
4326
|
+
return items;
|
|
4327
|
+
} catch (error) {
|
|
4328
|
+
throw error;
|
|
4329
|
+
}
|
|
4330
|
+
}
|
|
4331
|
+
async function getTasksForScheduleTask({
|
|
4332
|
+
page = 1,
|
|
4333
|
+
limit = 10,
|
|
4334
|
+
search = "",
|
|
4335
|
+
site
|
|
4336
|
+
}) {
|
|
4337
|
+
page = page > 0 ? page - 1 : 0;
|
|
4338
|
+
const query = {
|
|
4339
|
+
status: { $ne: "deleted" }
|
|
4340
|
+
};
|
|
4341
|
+
const cacheOptions = {
|
|
4342
|
+
page,
|
|
4343
|
+
limit
|
|
4344
|
+
};
|
|
4345
|
+
try {
|
|
4346
|
+
site = new import_mongodb16.ObjectId(site);
|
|
4347
|
+
query.site = site;
|
|
4348
|
+
cacheOptions.site = site.toString();
|
|
4349
|
+
} catch (error) {
|
|
4350
|
+
throw new import_node_server_utils28.BadRequestError("Invalid site ID format.");
|
|
4351
|
+
}
|
|
4352
|
+
if (search) {
|
|
4353
|
+
query.$or = [{ name: { $regex: search, $options: "i" } }];
|
|
4354
|
+
cacheOptions.search = search;
|
|
4355
|
+
}
|
|
4356
|
+
const cacheKey = (0, import_node_server_utils28.makeCacheKey)(namespace_collection, cacheOptions);
|
|
4357
|
+
const cachedData = await getCache(cacheKey);
|
|
4358
|
+
if (cachedData) {
|
|
4359
|
+
import_node_server_utils28.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
4360
|
+
return cachedData;
|
|
4361
|
+
}
|
|
4362
|
+
try {
|
|
4363
|
+
const items = await collection.aggregate([
|
|
4364
|
+
{ $match: query },
|
|
4365
|
+
{
|
|
4366
|
+
$project: {
|
|
4367
|
+
createdAt: 1,
|
|
4368
|
+
title: 1
|
|
4369
|
+
}
|
|
4370
|
+
},
|
|
4371
|
+
{ $sort: { _id: -1 } },
|
|
4372
|
+
{ $skip: page * limit },
|
|
4373
|
+
{ $limit: limit }
|
|
4374
|
+
]).toArray();
|
|
4375
|
+
const length = await collection.countDocuments(query);
|
|
4376
|
+
const data = (0, import_node_server_utils28.paginate)(items, page, limit, length);
|
|
4377
|
+
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
4378
|
+
import_node_server_utils28.logger.info(`Cache set for key: ${cacheKey}`);
|
|
4379
|
+
}).catch((err) => {
|
|
4380
|
+
import_node_server_utils28.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
4381
|
+
});
|
|
4382
|
+
return data;
|
|
4383
|
+
} catch (error) {
|
|
4384
|
+
throw error;
|
|
4385
|
+
}
|
|
4386
|
+
}
|
|
4344
4387
|
async function getScheduleTaskById(_id, session) {
|
|
4345
4388
|
try {
|
|
4346
4389
|
_id = new import_mongodb16.ObjectId(_id);
|
|
@@ -4370,10 +4413,11 @@ function useScheduleTaskRepository() {
|
|
|
4370
4413
|
$project: {
|
|
4371
4414
|
title: 1,
|
|
4372
4415
|
frequency: 1,
|
|
4416
|
+
time: 1,
|
|
4373
4417
|
day: 1,
|
|
4374
4418
|
weekOfMonth: 1,
|
|
4375
|
-
quarter: 1,
|
|
4376
4419
|
month: 1,
|
|
4420
|
+
date: 1,
|
|
4377
4421
|
description: 1,
|
|
4378
4422
|
areas: 1,
|
|
4379
4423
|
status: 1,
|
|
@@ -4442,18 +4486,213 @@ function useScheduleTaskRepository() {
|
|
|
4442
4486
|
createTextIndex,
|
|
4443
4487
|
createScheduleTask,
|
|
4444
4488
|
getScheduleTasks,
|
|
4489
|
+
getAllScheduleTask,
|
|
4490
|
+
getTasksForScheduleTask,
|
|
4445
4491
|
getScheduleTaskById,
|
|
4446
4492
|
updateScheduleTask
|
|
4447
4493
|
};
|
|
4448
4494
|
}
|
|
4449
4495
|
|
|
4450
|
-
// src/
|
|
4496
|
+
// src/services/hygiene-schedule-task.service.ts
|
|
4451
4497
|
var import_node_server_utils29 = require("@iservice365/node-server-utils");
|
|
4498
|
+
function useScheduleTaskService() {
|
|
4499
|
+
const { getAllScheduleTask } = useScheduleTaskRepository();
|
|
4500
|
+
const { createAreaChecklist } = useAreaChecklistService();
|
|
4501
|
+
const { createParentChecklist } = useParentChecklistRepo();
|
|
4502
|
+
function checkScheduleConditions(schedule, currentDate = /* @__PURE__ */ new Date()) {
|
|
4503
|
+
try {
|
|
4504
|
+
const now = currentDate;
|
|
4505
|
+
const currentDay = now.toLocaleDateString("en-US", {
|
|
4506
|
+
weekday: "long",
|
|
4507
|
+
timeZone: "Asia/Singapore"
|
|
4508
|
+
});
|
|
4509
|
+
const currentMonth = now.toLocaleDateString("en-US", {
|
|
4510
|
+
month: "long",
|
|
4511
|
+
timeZone: "Asia/Singapore"
|
|
4512
|
+
});
|
|
4513
|
+
const currentDate_num = Number(
|
|
4514
|
+
now.toLocaleDateString("en-US", {
|
|
4515
|
+
day: "numeric",
|
|
4516
|
+
timeZone: "Asia/Singapore"
|
|
4517
|
+
})
|
|
4518
|
+
);
|
|
4519
|
+
const timeString = now.toLocaleTimeString("en-US", {
|
|
4520
|
+
hour: "2-digit",
|
|
4521
|
+
minute: "2-digit",
|
|
4522
|
+
hour12: false,
|
|
4523
|
+
timeZone: "Asia/Singapore"
|
|
4524
|
+
});
|
|
4525
|
+
const [currentHour, currentMinute] = timeString.split(":").map(Number);
|
|
4526
|
+
import_node_server_utils29.logger.info(
|
|
4527
|
+
`Checking schedule ${schedule._id}: Current time ${currentHour}:${currentMinute}, Schedule time ${schedule.time}, Frequency ${schedule.frequency}`
|
|
4528
|
+
);
|
|
4529
|
+
const [scheduleHour, scheduleMinute] = schedule.time.split(":").map(Number);
|
|
4530
|
+
const timeMatches = currentHour === scheduleHour && currentMinute === scheduleMinute;
|
|
4531
|
+
if (!timeMatches) {
|
|
4532
|
+
import_node_server_utils29.logger.info(
|
|
4533
|
+
`Schedule ${schedule._id}: Time does not match. Current: ${currentHour}:${currentMinute}, Expected: ${scheduleHour}:${scheduleMinute}`
|
|
4534
|
+
);
|
|
4535
|
+
return false;
|
|
4536
|
+
}
|
|
4537
|
+
import_node_server_utils29.logger.info(
|
|
4538
|
+
`Schedule ${schedule._id}: Time matches, checking frequency...`
|
|
4539
|
+
);
|
|
4540
|
+
switch (schedule.frequency) {
|
|
4541
|
+
case "daily":
|
|
4542
|
+
import_node_server_utils29.logger.info(`Schedule ${schedule._id}: Daily frequency matched`);
|
|
4543
|
+
return true;
|
|
4544
|
+
case "weekly":
|
|
4545
|
+
if (!schedule.day || schedule.day.length === 0) {
|
|
4546
|
+
import_node_server_utils29.logger.warn(
|
|
4547
|
+
`Schedule ${schedule._id} is weekly but has no days specified`
|
|
4548
|
+
);
|
|
4549
|
+
return false;
|
|
4550
|
+
}
|
|
4551
|
+
const dayMatches = schedule.day.includes(currentDay);
|
|
4552
|
+
import_node_server_utils29.logger.info(
|
|
4553
|
+
`Schedule ${schedule._id}: Weekly - Current day: ${currentDay}, Schedule days: ${schedule.day.join(
|
|
4554
|
+
", "
|
|
4555
|
+
)}, Match: ${dayMatches}`
|
|
4556
|
+
);
|
|
4557
|
+
return dayMatches;
|
|
4558
|
+
case "monthly":
|
|
4559
|
+
if (!schedule.weekOfMonth) {
|
|
4560
|
+
import_node_server_utils29.logger.warn(
|
|
4561
|
+
`Schedule ${schedule._id} is monthly but has no weekOfMonth specified`
|
|
4562
|
+
);
|
|
4563
|
+
return false;
|
|
4564
|
+
}
|
|
4565
|
+
if (schedule.weekOfMonth === "start") {
|
|
4566
|
+
const matches2 = currentDate_num >= 1 && currentDate_num <= 7;
|
|
4567
|
+
import_node_server_utils29.logger.info(
|
|
4568
|
+
`Schedule ${schedule._id}: Monthly start - Current date: ${currentDate_num}, Match: ${matches2}`
|
|
4569
|
+
);
|
|
4570
|
+
return matches2;
|
|
4571
|
+
} else if (schedule.weekOfMonth === "end") {
|
|
4572
|
+
const lastDayOfMonth = new Date(
|
|
4573
|
+
now.getFullYear(),
|
|
4574
|
+
now.getMonth() + 1,
|
|
4575
|
+
0
|
|
4576
|
+
).getDate();
|
|
4577
|
+
const matches2 = currentDate_num > lastDayOfMonth - 7;
|
|
4578
|
+
import_node_server_utils29.logger.info(
|
|
4579
|
+
`Schedule ${schedule._id}: Monthly end - Current date: ${currentDate_num}, Last day: ${lastDayOfMonth}, Match: ${matches2}`
|
|
4580
|
+
);
|
|
4581
|
+
return matches2;
|
|
4582
|
+
}
|
|
4583
|
+
return false;
|
|
4584
|
+
case "annually":
|
|
4585
|
+
if (!schedule.month || !schedule.date) {
|
|
4586
|
+
import_node_server_utils29.logger.warn(
|
|
4587
|
+
`Schedule ${schedule._id} is annually but has no month or date specified`
|
|
4588
|
+
);
|
|
4589
|
+
return false;
|
|
4590
|
+
}
|
|
4591
|
+
const matches = currentMonth === schedule.month && currentDate_num === schedule.date;
|
|
4592
|
+
import_node_server_utils29.logger.info(
|
|
4593
|
+
`Schedule ${schedule._id}: Annually - Current: ${currentMonth} ${currentDate_num}, Expected: ${schedule.month} ${schedule.date}, Match: ${matches}`
|
|
4594
|
+
);
|
|
4595
|
+
return matches;
|
|
4596
|
+
default:
|
|
4597
|
+
import_node_server_utils29.logger.warn(`Unknown frequency type: ${schedule.frequency}`);
|
|
4598
|
+
return false;
|
|
4599
|
+
}
|
|
4600
|
+
} catch (error) {
|
|
4601
|
+
import_node_server_utils29.logger.error(
|
|
4602
|
+
`Error checking schedule conditions for ${schedule._id}:`,
|
|
4603
|
+
error
|
|
4604
|
+
);
|
|
4605
|
+
return false;
|
|
4606
|
+
}
|
|
4607
|
+
}
|
|
4608
|
+
async function processScheduledTasks(currentDate) {
|
|
4609
|
+
try {
|
|
4610
|
+
import_node_server_utils29.logger.info("Starting scheduled task processing...");
|
|
4611
|
+
const scheduleTasks = await getAllScheduleTask();
|
|
4612
|
+
if (!scheduleTasks || scheduleTasks.length === 0) {
|
|
4613
|
+
import_node_server_utils29.logger.info("No schedule tasks found to process");
|
|
4614
|
+
return { processed: 0, validated: 0 };
|
|
4615
|
+
}
|
|
4616
|
+
import_node_server_utils29.logger.info(`Found ${scheduleTasks.length} schedule tasks to check`);
|
|
4617
|
+
let processedCount = 0;
|
|
4618
|
+
let validatedCount = 0;
|
|
4619
|
+
const validatedTasks = [];
|
|
4620
|
+
for (const scheduleTask of scheduleTasks) {
|
|
4621
|
+
try {
|
|
4622
|
+
import_node_server_utils29.logger.info(
|
|
4623
|
+
`Checking schedule ${scheduleTask._id} - ${scheduleTask.title}: time=${scheduleTask.time}, frequency=${scheduleTask.frequency}`
|
|
4624
|
+
);
|
|
4625
|
+
const shouldRun = checkScheduleConditions(scheduleTask, currentDate);
|
|
4626
|
+
if (!shouldRun) {
|
|
4627
|
+
import_node_server_utils29.logger.info(
|
|
4628
|
+
`Schedule ${scheduleTask._id} conditions not met, skipping`
|
|
4629
|
+
);
|
|
4630
|
+
continue;
|
|
4631
|
+
}
|
|
4632
|
+
import_node_server_utils29.logger.info(
|
|
4633
|
+
`Schedule ${scheduleTask._id} conditions validated, creating area checklists`
|
|
4634
|
+
);
|
|
4635
|
+
if (!scheduleTask._id) {
|
|
4636
|
+
import_node_server_utils29.logger.warn(`Schedule ${scheduleTask.title} has no _id, skipping`);
|
|
4637
|
+
continue;
|
|
4638
|
+
}
|
|
4639
|
+
if (!scheduleTask.site) {
|
|
4640
|
+
import_node_server_utils29.logger.warn(`Schedule ${scheduleTask._id} has no site, skipping`);
|
|
4641
|
+
continue;
|
|
4642
|
+
}
|
|
4643
|
+
import_node_server_utils29.logger.info(
|
|
4644
|
+
`Getting or creating parent checklist for schedule ${scheduleTask._id} in site ${scheduleTask.site}`
|
|
4645
|
+
);
|
|
4646
|
+
const parentChecklistIds = await createParentChecklist({
|
|
4647
|
+
site: scheduleTask.site.toString(),
|
|
4648
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
4649
|
+
});
|
|
4650
|
+
const parentChecklistId = Array.isArray(parentChecklistIds) ? parentChecklistIds[0] : parentChecklistIds;
|
|
4651
|
+
import_node_server_utils29.logger.info(
|
|
4652
|
+
`Using parent checklist ${parentChecklistId}, now creating area checklists`
|
|
4653
|
+
);
|
|
4654
|
+
const createdChecklistIds = await createAreaChecklist({
|
|
4655
|
+
schedule: parentChecklistId.toString(),
|
|
4656
|
+
site: scheduleTask.site.toString()
|
|
4657
|
+
});
|
|
4658
|
+
processedCount++;
|
|
4659
|
+
validatedCount++;
|
|
4660
|
+
validatedTasks.push(scheduleTask);
|
|
4661
|
+
import_node_server_utils29.logger.info(
|
|
4662
|
+
`Successfully processed schedule ${scheduleTask._id}, created parent checklist ${parentChecklistId} and ${createdChecklistIds.length} area checklists`
|
|
4663
|
+
);
|
|
4664
|
+
} catch (error) {
|
|
4665
|
+
import_node_server_utils29.logger.error(
|
|
4666
|
+
`Error processing schedule task ${scheduleTask._id}:`,
|
|
4667
|
+
error
|
|
4668
|
+
);
|
|
4669
|
+
continue;
|
|
4670
|
+
}
|
|
4671
|
+
}
|
|
4672
|
+
import_node_server_utils29.logger.info(
|
|
4673
|
+
`Scheduled task processing completed. Processed: ${processedCount}, Validated: ${validatedCount} tasks`
|
|
4674
|
+
);
|
|
4675
|
+
return {
|
|
4676
|
+
processed: processedCount,
|
|
4677
|
+
validated: validatedCount,
|
|
4678
|
+
tasks: validatedTasks
|
|
4679
|
+
};
|
|
4680
|
+
} catch (error) {
|
|
4681
|
+
import_node_server_utils29.logger.error("Error processing scheduled tasks:", error);
|
|
4682
|
+
throw error;
|
|
4683
|
+
}
|
|
4684
|
+
}
|
|
4685
|
+
return { checkScheduleConditions, processScheduledTasks };
|
|
4686
|
+
}
|
|
4687
|
+
|
|
4688
|
+
// src/controllers/hygiene-schedule-task.controller.ts
|
|
4689
|
+
var import_node_server_utils30 = require("@iservice365/node-server-utils");
|
|
4452
4690
|
var import_joi16 = __toESM(require("joi"));
|
|
4453
4691
|
function useScheduleTaskController() {
|
|
4454
4692
|
const {
|
|
4455
4693
|
createScheduleTask: _createScheduleTask,
|
|
4456
4694
|
getScheduleTasks: _getScheduleTasks,
|
|
4695
|
+
getTasksForScheduleTask: _getTasksForScheduleTask,
|
|
4457
4696
|
getScheduleTaskById: _getScheduleTaskById,
|
|
4458
4697
|
updateScheduleTask: _updateScheduleTask
|
|
4459
4698
|
} = useScheduleTaskRepository();
|
|
@@ -4461,8 +4700,8 @@ function useScheduleTaskController() {
|
|
|
4461
4700
|
const payload = { ...req.body, ...req.params };
|
|
4462
4701
|
const { error } = scheduleTaskSchema.validate(payload);
|
|
4463
4702
|
if (error) {
|
|
4464
|
-
|
|
4465
|
-
next(new
|
|
4703
|
+
import_node_server_utils30.logger.log({ level: "error", message: error.message });
|
|
4704
|
+
next(new import_node_server_utils30.BadRequestError(error.message));
|
|
4466
4705
|
return;
|
|
4467
4706
|
}
|
|
4468
4707
|
try {
|
|
@@ -4470,7 +4709,7 @@ function useScheduleTaskController() {
|
|
|
4470
4709
|
res.status(201).json({ message: "Schedule task created successfully.", id });
|
|
4471
4710
|
return;
|
|
4472
4711
|
} catch (error2) {
|
|
4473
|
-
|
|
4712
|
+
import_node_server_utils30.logger.log({ level: "error", message: error2.message });
|
|
4474
4713
|
next(error2);
|
|
4475
4714
|
return;
|
|
4476
4715
|
}
|
|
@@ -4485,8 +4724,8 @@ function useScheduleTaskController() {
|
|
|
4485
4724
|
});
|
|
4486
4725
|
const { error } = validation.validate(query);
|
|
4487
4726
|
if (error) {
|
|
4488
|
-
|
|
4489
|
-
next(new
|
|
4727
|
+
import_node_server_utils30.logger.log({ level: "error", message: error.message });
|
|
4728
|
+
next(new import_node_server_utils30.BadRequestError(error.message));
|
|
4490
4729
|
return;
|
|
4491
4730
|
}
|
|
4492
4731
|
const page = parseInt(req.query.page) ?? 1;
|
|
@@ -4503,7 +4742,40 @@ function useScheduleTaskController() {
|
|
|
4503
4742
|
res.json(data);
|
|
4504
4743
|
return;
|
|
4505
4744
|
} catch (error2) {
|
|
4506
|
-
|
|
4745
|
+
import_node_server_utils30.logger.log({ level: "error", message: error2.message });
|
|
4746
|
+
next(error2);
|
|
4747
|
+
return;
|
|
4748
|
+
}
|
|
4749
|
+
}
|
|
4750
|
+
async function getTasksForScheduleTask(req, res, next) {
|
|
4751
|
+
const query = { ...req.query, ...req.params };
|
|
4752
|
+
const validation = import_joi16.default.object({
|
|
4753
|
+
page: import_joi16.default.number().min(1).optional().allow("", null),
|
|
4754
|
+
limit: import_joi16.default.number().min(1).optional().allow("", null),
|
|
4755
|
+
search: import_joi16.default.string().optional().allow("", null),
|
|
4756
|
+
site: import_joi16.default.string().hex().required()
|
|
4757
|
+
});
|
|
4758
|
+
const { error } = validation.validate(query);
|
|
4759
|
+
if (error) {
|
|
4760
|
+
import_node_server_utils30.logger.log({ level: "error", message: error.message });
|
|
4761
|
+
next(new import_node_server_utils30.BadRequestError(error.message));
|
|
4762
|
+
return;
|
|
4763
|
+
}
|
|
4764
|
+
const page = parseInt(req.query.page) ?? 1;
|
|
4765
|
+
const limit = parseInt(req.query.limit) ?? 10;
|
|
4766
|
+
const search = req.query.search ?? "";
|
|
4767
|
+
const site = req.params.site ?? "";
|
|
4768
|
+
try {
|
|
4769
|
+
const data = await _getTasksForScheduleTask({
|
|
4770
|
+
page,
|
|
4771
|
+
limit,
|
|
4772
|
+
search,
|
|
4773
|
+
site
|
|
4774
|
+
});
|
|
4775
|
+
res.json(data);
|
|
4776
|
+
return;
|
|
4777
|
+
} catch (error2) {
|
|
4778
|
+
import_node_server_utils30.logger.log({ level: "error", message: error2.message });
|
|
4507
4779
|
next(error2);
|
|
4508
4780
|
return;
|
|
4509
4781
|
}
|
|
@@ -4513,8 +4785,8 @@ function useScheduleTaskController() {
|
|
|
4513
4785
|
const _id = req.params.id;
|
|
4514
4786
|
const { error } = validation.validate(_id);
|
|
4515
4787
|
if (error) {
|
|
4516
|
-
|
|
4517
|
-
next(new
|
|
4788
|
+
import_node_server_utils30.logger.log({ level: "error", message: error.message });
|
|
4789
|
+
next(new import_node_server_utils30.BadRequestError(error.message));
|
|
4518
4790
|
return;
|
|
4519
4791
|
}
|
|
4520
4792
|
try {
|
|
@@ -4522,7 +4794,7 @@ function useScheduleTaskController() {
|
|
|
4522
4794
|
res.json(data);
|
|
4523
4795
|
return;
|
|
4524
4796
|
} catch (error2) {
|
|
4525
|
-
|
|
4797
|
+
import_node_server_utils30.logger.log({ level: "error", message: error2.message });
|
|
4526
4798
|
next(error2);
|
|
4527
4799
|
return;
|
|
4528
4800
|
}
|
|
@@ -4533,10 +4805,11 @@ function useScheduleTaskController() {
|
|
|
4533
4805
|
id: import_joi16.default.string().hex().required(),
|
|
4534
4806
|
title: import_joi16.default.string().optional().allow("", null),
|
|
4535
4807
|
frequency: import_joi16.default.string().valid(...allowedFrequency).optional().allow("", null),
|
|
4536
|
-
|
|
4808
|
+
time: import_joi16.default.string().pattern(/^([0-1]\d|2[0-3]):([0-5]\d)$/).optional().allow("", null),
|
|
4809
|
+
day: import_joi16.default.array().items(import_joi16.default.string().valid(...allowedDays)).optional().allow(null),
|
|
4537
4810
|
weekOfMonth: import_joi16.default.string().valid(...allowedWeekOfMonth).optional().allow("", null),
|
|
4538
|
-
quarter: import_joi16.default.string().valid(...allowedQuarter).optional().allow("", null),
|
|
4539
4811
|
month: import_joi16.default.string().valid(...allowedMonths).optional().allow("", null),
|
|
4812
|
+
date: import_joi16.default.number().min(1).max(31).optional().allow(null),
|
|
4540
4813
|
description: import_joi16.default.string().optional().allow("", null),
|
|
4541
4814
|
areas: import_joi16.default.array().min(1).items(
|
|
4542
4815
|
import_joi16.default.object({
|
|
@@ -4547,8 +4820,8 @@ function useScheduleTaskController() {
|
|
|
4547
4820
|
});
|
|
4548
4821
|
const { error } = validation.validate(payload);
|
|
4549
4822
|
if (error) {
|
|
4550
|
-
|
|
4551
|
-
next(new
|
|
4823
|
+
import_node_server_utils30.logger.log({ level: "error", message: error.message });
|
|
4824
|
+
next(new import_node_server_utils30.BadRequestError(error.message));
|
|
4552
4825
|
return;
|
|
4553
4826
|
}
|
|
4554
4827
|
try {
|
|
@@ -4557,7 +4830,7 @@ function useScheduleTaskController() {
|
|
|
4557
4830
|
res.json({ message: "Schedule task updated successfully." });
|
|
4558
4831
|
return;
|
|
4559
4832
|
} catch (error2) {
|
|
4560
|
-
|
|
4833
|
+
import_node_server_utils30.logger.log({ level: "error", message: error2.message });
|
|
4561
4834
|
next(error2);
|
|
4562
4835
|
return;
|
|
4563
4836
|
}
|
|
@@ -4565,6 +4838,7 @@ function useScheduleTaskController() {
|
|
|
4565
4838
|
return {
|
|
4566
4839
|
createScheduleTask,
|
|
4567
4840
|
getScheduleTasks,
|
|
4841
|
+
getTasksForScheduleTask,
|
|
4568
4842
|
getScheduleTaskById,
|
|
4569
4843
|
updateScheduleTask
|
|
4570
4844
|
};
|
|
@@ -4583,7 +4857,6 @@ function useScheduleTaskController() {
|
|
|
4583
4857
|
allowedDays,
|
|
4584
4858
|
allowedFrequency,
|
|
4585
4859
|
allowedMonths,
|
|
4586
|
-
allowedQuarter,
|
|
4587
4860
|
allowedRequestItemStatus,
|
|
4588
4861
|
allowedStatus,
|
|
4589
4862
|
allowedTypes,
|
|
@@ -4609,6 +4882,7 @@ function useScheduleTaskController() {
|
|
|
4609
4882
|
useRequestItemService,
|
|
4610
4883
|
useScheduleTaskController,
|
|
4611
4884
|
useScheduleTaskRepository,
|
|
4885
|
+
useScheduleTaskService,
|
|
4612
4886
|
useStockController,
|
|
4613
4887
|
useStockRepository,
|
|
4614
4888
|
useStockService,
|