@7365admin1/module-hygiene 4.10.0 → 4.12.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 +11 -0
- package/dist/index.js +455 -132
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +460 -133
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -2529,12 +2529,30 @@ function useParentChecklistRepo() {
|
|
|
2529
2529
|
throw error;
|
|
2530
2530
|
}
|
|
2531
2531
|
}
|
|
2532
|
+
async function getTodayParentChecklists() {
|
|
2533
|
+
const now = /* @__PURE__ */ new Date();
|
|
2534
|
+
const start = new Date(now);
|
|
2535
|
+
start.setUTCHours(0, 0, 0, 0);
|
|
2536
|
+
const end = new Date(now);
|
|
2537
|
+
end.setUTCHours(23, 59, 59, 999);
|
|
2538
|
+
try {
|
|
2539
|
+
const items = await collection.find(
|
|
2540
|
+
{ createdAt: { $gte: start, $lte: end } },
|
|
2541
|
+
{ projection: { _id: 1, site: 1 } }
|
|
2542
|
+
).toArray();
|
|
2543
|
+
return items;
|
|
2544
|
+
} catch (error) {
|
|
2545
|
+
import_node_server_utils14.logger.error("Failed to get today's parent checklists", error);
|
|
2546
|
+
throw error;
|
|
2547
|
+
}
|
|
2548
|
+
}
|
|
2532
2549
|
return {
|
|
2533
2550
|
createIndex,
|
|
2534
2551
|
createParentChecklist,
|
|
2535
2552
|
getAllParentChecklist,
|
|
2536
2553
|
updateParentChecklistStatuses,
|
|
2537
|
-
closeExpiredParentChecklists
|
|
2554
|
+
closeExpiredParentChecklists,
|
|
2555
|
+
getTodayParentChecklists
|
|
2538
2556
|
};
|
|
2539
2557
|
}
|
|
2540
2558
|
|
|
@@ -2630,7 +2648,9 @@ var areaChecklistSchema = import_joi8.default.object({
|
|
|
2630
2648
|
unit: import_joi8.default.string().hex().required(),
|
|
2631
2649
|
name: import_joi8.default.string().required()
|
|
2632
2650
|
}).required()
|
|
2633
|
-
).min(1).required()
|
|
2651
|
+
).min(1).required(),
|
|
2652
|
+
isScheduleTask: import_joi8.default.boolean().optional().default(false),
|
|
2653
|
+
scheduleTaskId: import_joi8.default.string().hex().optional().allow(null)
|
|
2634
2654
|
}).required()
|
|
2635
2655
|
).optional().default([]),
|
|
2636
2656
|
createdBy: import_joi8.default.string().hex().required()
|
|
@@ -2659,6 +2679,8 @@ function MAreaChecklist(value) {
|
|
|
2659
2679
|
value.checklist = value.checklist.map((checklistItem) => {
|
|
2660
2680
|
return {
|
|
2661
2681
|
set: checklistItem.set,
|
|
2682
|
+
isScheduleTask: checklistItem.isScheduleTask ?? false,
|
|
2683
|
+
scheduleTaskId: checklistItem.scheduleTaskId ?? void 0,
|
|
2662
2684
|
units: checklistItem.units.map((unit) => ({
|
|
2663
2685
|
unit: new import_mongodb8.ObjectId(unit.unit),
|
|
2664
2686
|
name: unit.name,
|
|
@@ -2694,7 +2716,9 @@ function MAreaChecklist(value) {
|
|
|
2694
2716
|
}
|
|
2695
2717
|
|
|
2696
2718
|
// src/services/hygiene-area-checklist.service.ts
|
|
2719
|
+
var import_mongodb10 = require("mongodb");
|
|
2697
2720
|
var import_node_server_utils18 = require("@7365admin1/node-server-utils");
|
|
2721
|
+
var import_core = require("@7365admin1/core");
|
|
2698
2722
|
|
|
2699
2723
|
// src/repositories/hygiene-area-checklist.repository.ts
|
|
2700
2724
|
var import_mongodb9 = require("mongodb");
|
|
@@ -2736,26 +2760,26 @@ function useAreaChecklistRepo() {
|
|
|
2736
2760
|
);
|
|
2737
2761
|
}
|
|
2738
2762
|
}
|
|
2763
|
+
async function createUniqueIndex() {
|
|
2764
|
+
try {
|
|
2765
|
+
await collection.createIndex({ schedule: 1, area: 1 }, { unique: true });
|
|
2766
|
+
} catch (error) {
|
|
2767
|
+
throw new import_node_server_utils17.InternalServerError(
|
|
2768
|
+
"Failed to create unique index on hygiene checklist area."
|
|
2769
|
+
);
|
|
2770
|
+
}
|
|
2771
|
+
}
|
|
2739
2772
|
async function createAreaChecklist(value, session) {
|
|
2740
2773
|
try {
|
|
2741
2774
|
const parentChecklistId = new import_mongodb9.ObjectId(value.schedule);
|
|
2742
|
-
const
|
|
2743
|
-
const
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
const existingChecklist = await collection.findOne({
|
|
2748
|
-
type: value.type,
|
|
2749
|
-
schedule: parentChecklistId,
|
|
2750
|
-
name: value.name,
|
|
2751
|
-
createdAt: {
|
|
2752
|
-
$gte: startOfDay,
|
|
2753
|
-
$lte: endOfDay
|
|
2754
|
-
}
|
|
2755
|
-
});
|
|
2775
|
+
const areaId = new import_mongodb9.ObjectId(value.area);
|
|
2776
|
+
const existingChecklist = await collection.findOne(
|
|
2777
|
+
{ schedule: parentChecklistId, area: areaId },
|
|
2778
|
+
{ session }
|
|
2779
|
+
);
|
|
2756
2780
|
if (existingChecklist) {
|
|
2757
2781
|
import_node_server_utils17.logger.info(
|
|
2758
|
-
`Area checklist already exists for area ${value.name}
|
|
2782
|
+
`Area checklist already exists for area ${value.name} (schedule: ${parentChecklistId}, area: ${areaId})`
|
|
2759
2783
|
);
|
|
2760
2784
|
return existingChecklist._id;
|
|
2761
2785
|
}
|
|
@@ -2771,6 +2795,14 @@ function useAreaChecklistRepo() {
|
|
|
2771
2795
|
});
|
|
2772
2796
|
return result.insertedId;
|
|
2773
2797
|
} catch (error) {
|
|
2798
|
+
if (error?.code === 11e3) {
|
|
2799
|
+
import_node_server_utils17.logger.info(`Duplicate area checklist skipped for area ${value.name}`);
|
|
2800
|
+
const existing = await collection.findOne({
|
|
2801
|
+
schedule: new import_mongodb9.ObjectId(value.schedule),
|
|
2802
|
+
area: new import_mongodb9.ObjectId(value.area)
|
|
2803
|
+
});
|
|
2804
|
+
return existing._id;
|
|
2805
|
+
}
|
|
2774
2806
|
throw error;
|
|
2775
2807
|
}
|
|
2776
2808
|
}
|
|
@@ -3108,6 +3140,9 @@ function useAreaChecklistRepo() {
|
|
|
3108
3140
|
$project: {
|
|
3109
3141
|
_id: 0,
|
|
3110
3142
|
set: "$checklist.set",
|
|
3143
|
+
isScheduleTask: {
|
|
3144
|
+
$ifNull: ["$checklist.isScheduleTask", false]
|
|
3145
|
+
},
|
|
3111
3146
|
unit: "$checklist.units.unit",
|
|
3112
3147
|
name: "$checklist.units.name",
|
|
3113
3148
|
remarks: "$checklist.units.remarks",
|
|
@@ -3138,6 +3173,7 @@ function useAreaChecklistRepo() {
|
|
|
3138
3173
|
{
|
|
3139
3174
|
$group: {
|
|
3140
3175
|
_id: "$set",
|
|
3176
|
+
isScheduleTask: { $first: "$isScheduleTask" },
|
|
3141
3177
|
units: {
|
|
3142
3178
|
$push: {
|
|
3143
3179
|
unit: "$unit",
|
|
@@ -3154,6 +3190,7 @@ function useAreaChecklistRepo() {
|
|
|
3154
3190
|
$project: {
|
|
3155
3191
|
_id: 0,
|
|
3156
3192
|
set: "$_id",
|
|
3193
|
+
isScheduleTask: 1,
|
|
3157
3194
|
units: 1
|
|
3158
3195
|
}
|
|
3159
3196
|
},
|
|
@@ -3227,7 +3264,19 @@ function useAreaChecklistRepo() {
|
|
|
3227
3264
|
},
|
|
3228
3265
|
{
|
|
3229
3266
|
$addFields: {
|
|
3230
|
-
isCompleted: { $ne: ["$checklist.units.completedBy", ""] }
|
|
3267
|
+
isCompleted: { $ne: ["$checklist.units.completedBy", ""] },
|
|
3268
|
+
isActioned: {
|
|
3269
|
+
$cond: {
|
|
3270
|
+
if: {
|
|
3271
|
+
$or: [
|
|
3272
|
+
{ $eq: ["$checklist.units.approve", true] },
|
|
3273
|
+
{ $eq: ["$checklist.units.reject", true] }
|
|
3274
|
+
]
|
|
3275
|
+
},
|
|
3276
|
+
then: 1,
|
|
3277
|
+
else: 0
|
|
3278
|
+
}
|
|
3279
|
+
}
|
|
3231
3280
|
}
|
|
3232
3281
|
},
|
|
3233
3282
|
{
|
|
@@ -3256,11 +3305,24 @@ function useAreaChecklistRepo() {
|
|
|
3256
3305
|
preserveNullAndEmptyArrays: true
|
|
3257
3306
|
}
|
|
3258
3307
|
},
|
|
3259
|
-
{
|
|
3308
|
+
{
|
|
3309
|
+
$sort: {
|
|
3310
|
+
"checklist.set": 1,
|
|
3311
|
+
isActioned: 1,
|
|
3312
|
+
"checklist.units.timestamp": 1,
|
|
3313
|
+
isCompleted: -1
|
|
3314
|
+
}
|
|
3315
|
+
},
|
|
3260
3316
|
{
|
|
3261
3317
|
$project: {
|
|
3262
3318
|
_id: 0,
|
|
3263
3319
|
set: "$checklist.set",
|
|
3320
|
+
isScheduleTask: {
|
|
3321
|
+
$ifNull: ["$checklist.isScheduleTask", false]
|
|
3322
|
+
},
|
|
3323
|
+
scheduleTaskId: {
|
|
3324
|
+
$ifNull: ["$checklist.scheduleTaskId", null]
|
|
3325
|
+
},
|
|
3264
3326
|
remarks: "$checklist.remarks",
|
|
3265
3327
|
attachment: "$checklist.attachment",
|
|
3266
3328
|
unit: "$checklist.units.unit",
|
|
@@ -3293,6 +3355,8 @@ function useAreaChecklistRepo() {
|
|
|
3293
3355
|
{
|
|
3294
3356
|
$group: {
|
|
3295
3357
|
_id: "$set",
|
|
3358
|
+
isScheduleTask: { $first: "$isScheduleTask" },
|
|
3359
|
+
scheduleTaskId: { $first: "$scheduleTaskId" },
|
|
3296
3360
|
remarks: { $first: "$remarks" },
|
|
3297
3361
|
attachment: { $first: "$attachment" },
|
|
3298
3362
|
completedByName: { $first: "$completedByName" },
|
|
@@ -3314,13 +3378,33 @@ function useAreaChecklistRepo() {
|
|
|
3314
3378
|
$project: {
|
|
3315
3379
|
_id: 0,
|
|
3316
3380
|
set: "$_id",
|
|
3381
|
+
isScheduleTask: 1,
|
|
3382
|
+
scheduleTaskId: 1,
|
|
3317
3383
|
remarks: "$remarks",
|
|
3318
3384
|
attachment: "$attachment",
|
|
3319
3385
|
completedByName: 1,
|
|
3320
3386
|
units: 1
|
|
3321
3387
|
}
|
|
3322
3388
|
},
|
|
3323
|
-
{
|
|
3389
|
+
{
|
|
3390
|
+
$addFields: {
|
|
3391
|
+
isFullyActioned: {
|
|
3392
|
+
$allElementsTrue: {
|
|
3393
|
+
$map: {
|
|
3394
|
+
input: "$units",
|
|
3395
|
+
as: "u",
|
|
3396
|
+
in: {
|
|
3397
|
+
$or: [
|
|
3398
|
+
{ $eq: ["$$u.approve", true] },
|
|
3399
|
+
{ $eq: ["$$u.reject", true] }
|
|
3400
|
+
]
|
|
3401
|
+
}
|
|
3402
|
+
}
|
|
3403
|
+
}
|
|
3404
|
+
}
|
|
3405
|
+
}
|
|
3406
|
+
},
|
|
3407
|
+
{ $sort: { isFullyActioned: 1, set: 1 } },
|
|
3324
3408
|
{ $skip: page * limit },
|
|
3325
3409
|
{ $limit: limit }
|
|
3326
3410
|
];
|
|
@@ -3524,12 +3608,26 @@ function useAreaChecklistRepo() {
|
|
|
3524
3608
|
throw error;
|
|
3525
3609
|
}
|
|
3526
3610
|
}
|
|
3611
|
+
async function getAreaChecklistSetOwner(_id, set, session) {
|
|
3612
|
+
try {
|
|
3613
|
+
_id = new import_mongodb9.ObjectId(_id);
|
|
3614
|
+
} catch (error) {
|
|
3615
|
+
throw new import_node_server_utils17.BadRequestError("Invalid area checklist ID format.");
|
|
3616
|
+
}
|
|
3617
|
+
const existing = await collection.findOne(
|
|
3618
|
+
{ _id, "checklist.set": set },
|
|
3619
|
+
{ projection: { "checklist.$": 1 }, session }
|
|
3620
|
+
);
|
|
3621
|
+
if (!existing?.checklist?.length)
|
|
3622
|
+
return null;
|
|
3623
|
+
return existing.checklist[0].units.map((u) => u.completedBy).find((cb) => cb && cb.toString() !== "") ?? null;
|
|
3624
|
+
}
|
|
3527
3625
|
async function getMaxSetNumberForArea(areaId, session) {
|
|
3528
3626
|
try {
|
|
3529
3627
|
const _id = new import_mongodb9.ObjectId(areaId);
|
|
3530
3628
|
const result = await collection.aggregate(
|
|
3531
3629
|
[
|
|
3532
|
-
{ $match: { area: _id
|
|
3630
|
+
{ $match: { area: _id } },
|
|
3533
3631
|
{ $unwind: "$checklist" },
|
|
3534
3632
|
{ $group: { _id: null, maxSet: { $max: "$checklist.set" } } }
|
|
3535
3633
|
],
|
|
@@ -3577,9 +3675,155 @@ function useAreaChecklistRepo() {
|
|
|
3577
3675
|
throw error;
|
|
3578
3676
|
}
|
|
3579
3677
|
}
|
|
3678
|
+
async function pushScheduleTaskSets(scheduleId, areaId, scheduleTaskId, newSets) {
|
|
3679
|
+
try {
|
|
3680
|
+
const schedule = new import_mongodb9.ObjectId(scheduleId);
|
|
3681
|
+
const area = new import_mongodb9.ObjectId(areaId);
|
|
3682
|
+
const taskId = new import_mongodb9.ObjectId(scheduleTaskId);
|
|
3683
|
+
const result = await collection.updateOne(
|
|
3684
|
+
{
|
|
3685
|
+
schedule,
|
|
3686
|
+
area,
|
|
3687
|
+
checklist: { $not: { $elemMatch: { scheduleTaskId: taskId } } }
|
|
3688
|
+
},
|
|
3689
|
+
{
|
|
3690
|
+
$push: { checklist: { $each: newSets } },
|
|
3691
|
+
$set: { updatedAt: /* @__PURE__ */ new Date() }
|
|
3692
|
+
}
|
|
3693
|
+
);
|
|
3694
|
+
if (result.modifiedCount > 0) {
|
|
3695
|
+
delNamespace().catch((err) => {
|
|
3696
|
+
import_node_server_utils17.logger.error(
|
|
3697
|
+
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
3698
|
+
err
|
|
3699
|
+
);
|
|
3700
|
+
});
|
|
3701
|
+
}
|
|
3702
|
+
return result.modifiedCount;
|
|
3703
|
+
} catch (error) {
|
|
3704
|
+
import_node_server_utils17.logger.error("Error in pushScheduleTaskSets:", error);
|
|
3705
|
+
throw error;
|
|
3706
|
+
}
|
|
3707
|
+
}
|
|
3708
|
+
async function insertAutoGenSets(scheduleId, areaId, newSets) {
|
|
3709
|
+
try {
|
|
3710
|
+
const schedule = new import_mongodb9.ObjectId(scheduleId);
|
|
3711
|
+
const area = new import_mongodb9.ObjectId(areaId);
|
|
3712
|
+
const result = await collection.updateOne(
|
|
3713
|
+
{
|
|
3714
|
+
schedule,
|
|
3715
|
+
area,
|
|
3716
|
+
checklist: {
|
|
3717
|
+
$not: { $elemMatch: { isScheduleTask: { $ne: true } } }
|
|
3718
|
+
}
|
|
3719
|
+
},
|
|
3720
|
+
{
|
|
3721
|
+
$push: { checklist: { $each: newSets } },
|
|
3722
|
+
$set: { updatedAt: /* @__PURE__ */ new Date() }
|
|
3723
|
+
}
|
|
3724
|
+
);
|
|
3725
|
+
if (result.modifiedCount > 0) {
|
|
3726
|
+
delNamespace().catch((err) => {
|
|
3727
|
+
import_node_server_utils17.logger.error(
|
|
3728
|
+
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
3729
|
+
err
|
|
3730
|
+
);
|
|
3731
|
+
});
|
|
3732
|
+
}
|
|
3733
|
+
return result.modifiedCount;
|
|
3734
|
+
} catch (error) {
|
|
3735
|
+
import_node_server_utils17.logger.error("Error in insertAutoGenSets:", error);
|
|
3736
|
+
throw error;
|
|
3737
|
+
}
|
|
3738
|
+
}
|
|
3739
|
+
async function trimOverflowSets() {
|
|
3740
|
+
try {
|
|
3741
|
+
const db2 = import_node_server_utils17.useAtlas.getDb();
|
|
3742
|
+
if (!db2)
|
|
3743
|
+
return 0;
|
|
3744
|
+
const bloated = await collection.aggregate([
|
|
3745
|
+
{
|
|
3746
|
+
$lookup: {
|
|
3747
|
+
from: "site.cleaning.areas",
|
|
3748
|
+
localField: "area",
|
|
3749
|
+
foreignField: "_id",
|
|
3750
|
+
as: "areaDoc"
|
|
3751
|
+
}
|
|
3752
|
+
},
|
|
3753
|
+
{
|
|
3754
|
+
$unwind: { path: "$areaDoc", preserveNullAndEmptyArrays: false }
|
|
3755
|
+
},
|
|
3756
|
+
{
|
|
3757
|
+
$addFields: {
|
|
3758
|
+
configuredSet: { $max: [1, { $ifNull: ["$areaDoc.set", 1] }] },
|
|
3759
|
+
autoGenSets: {
|
|
3760
|
+
$filter: {
|
|
3761
|
+
input: { $ifNull: ["$checklist", []] },
|
|
3762
|
+
as: "item",
|
|
3763
|
+
cond: { $ne: ["$$item.isScheduleTask", true] }
|
|
3764
|
+
}
|
|
3765
|
+
},
|
|
3766
|
+
scheduledSets: {
|
|
3767
|
+
$filter: {
|
|
3768
|
+
input: { $ifNull: ["$checklist", []] },
|
|
3769
|
+
as: "item",
|
|
3770
|
+
cond: { $eq: ["$$item.isScheduleTask", true] }
|
|
3771
|
+
}
|
|
3772
|
+
}
|
|
3773
|
+
}
|
|
3774
|
+
},
|
|
3775
|
+
{
|
|
3776
|
+
$match: {
|
|
3777
|
+
$expr: {
|
|
3778
|
+
$gt: [{ $size: "$autoGenSets" }, "$configuredSet"]
|
|
3779
|
+
}
|
|
3780
|
+
}
|
|
3781
|
+
},
|
|
3782
|
+
{
|
|
3783
|
+
$project: {
|
|
3784
|
+
_id: 1,
|
|
3785
|
+
checklist: 1,
|
|
3786
|
+
configuredSet: 1,
|
|
3787
|
+
autoGenSets: 1,
|
|
3788
|
+
scheduledSets: 1
|
|
3789
|
+
}
|
|
3790
|
+
}
|
|
3791
|
+
]).toArray();
|
|
3792
|
+
if (bloated.length === 0) {
|
|
3793
|
+
import_node_server_utils17.logger.info(
|
|
3794
|
+
"trimOverflowSets: no bloated area-checklist documents found"
|
|
3795
|
+
);
|
|
3796
|
+
return 0;
|
|
3797
|
+
}
|
|
3798
|
+
let trimmed = 0;
|
|
3799
|
+
for (const doc of bloated) {
|
|
3800
|
+
const limit = Number(doc.configuredSet) || 1;
|
|
3801
|
+
const trimmedAutoGen = [...doc.autoGenSets ?? []].sort((a, b) => (a.set ?? 0) - (b.set ?? 0)).slice(0, limit);
|
|
3802
|
+
const keep = [...trimmedAutoGen, ...doc.scheduledSets ?? []];
|
|
3803
|
+
const res = await collection.updateOne(
|
|
3804
|
+
{ _id: doc._id },
|
|
3805
|
+
{ $set: { checklist: keep, updatedAt: /* @__PURE__ */ new Date() } }
|
|
3806
|
+
);
|
|
3807
|
+
if (res.modifiedCount > 0) {
|
|
3808
|
+
trimmed++;
|
|
3809
|
+
import_node_server_utils17.logger.info(
|
|
3810
|
+
`trimOverflowSets: trimmed doc ${doc._id} \u2014 kept ${keep.length} sets (${trimmedAutoGen.length} auto-gen, ${(doc.scheduledSets ?? []).length} scheduled), removed ${doc.checklist.length - keep.length} excess auto-gen`
|
|
3811
|
+
);
|
|
3812
|
+
}
|
|
3813
|
+
}
|
|
3814
|
+
delNamespace().catch(() => {
|
|
3815
|
+
});
|
|
3816
|
+
import_node_server_utils17.logger.info(`trimOverflowSets: trimmed ${trimmed} document(s)`);
|
|
3817
|
+
return trimmed;
|
|
3818
|
+
} catch (error) {
|
|
3819
|
+
import_node_server_utils17.logger.error("Error in trimOverflowSets:", error);
|
|
3820
|
+
return 0;
|
|
3821
|
+
}
|
|
3822
|
+
}
|
|
3580
3823
|
return {
|
|
3581
3824
|
createIndex,
|
|
3582
3825
|
createTextIndex,
|
|
3826
|
+
createUniqueIndex,
|
|
3583
3827
|
createAreaChecklist,
|
|
3584
3828
|
getAllAreaChecklist,
|
|
3585
3829
|
getAreaChecklistHistory,
|
|
@@ -3587,11 +3831,15 @@ function useAreaChecklistRepo() {
|
|
|
3587
3831
|
getAreaChecklistUnits,
|
|
3588
3832
|
getAreaChecklistById,
|
|
3589
3833
|
getAreaChecklistByAreaAndSchedule,
|
|
3834
|
+
getAreaChecklistSetOwner,
|
|
3590
3835
|
updateAreaChecklist,
|
|
3591
3836
|
updateAreaChecklistStatus,
|
|
3592
3837
|
updateAreaChecklistUnits,
|
|
3593
3838
|
getMaxSetNumberForArea,
|
|
3594
|
-
closeExpiredAreaChecklists
|
|
3839
|
+
closeExpiredAreaChecklists,
|
|
3840
|
+
pushScheduleTaskSets,
|
|
3841
|
+
insertAutoGenSets,
|
|
3842
|
+
trimOverflowSets
|
|
3595
3843
|
};
|
|
3596
3844
|
}
|
|
3597
3845
|
|
|
@@ -3603,17 +3851,18 @@ function useAreaChecklistService() {
|
|
|
3603
3851
|
getAllAreaChecklist,
|
|
3604
3852
|
getAreaChecklistUnits,
|
|
3605
3853
|
getAreaChecklistById,
|
|
3854
|
+
getAreaChecklistByAreaAndSchedule,
|
|
3855
|
+
getAreaChecklistSetOwner,
|
|
3606
3856
|
updateAreaChecklistUnits: _updateAreaChecklistUnits,
|
|
3607
3857
|
updateAreaChecklistStatus,
|
|
3608
|
-
|
|
3858
|
+
insertAutoGenSets
|
|
3609
3859
|
} = useAreaChecklistRepo();
|
|
3610
3860
|
const { updateParentChecklistStatuses } = useParentChecklistRepo();
|
|
3861
|
+
const { getUserById } = (0, import_core.useUserRepo)();
|
|
3611
3862
|
async function createAreaChecklist(value) {
|
|
3612
|
-
const
|
|
3863
|
+
const results = [];
|
|
3864
|
+
let totalChecklistsCreated = 0;
|
|
3613
3865
|
try {
|
|
3614
|
-
session?.startTransaction();
|
|
3615
|
-
const results = [];
|
|
3616
|
-
let totalChecklistsCreated = 0;
|
|
3617
3866
|
const BATCH_SIZE = 10;
|
|
3618
3867
|
const areasResult = await getAreasForChecklist(value.site);
|
|
3619
3868
|
const areas = areasResult || [];
|
|
@@ -3627,15 +3876,72 @@ function useAreaChecklistService() {
|
|
|
3627
3876
|
);
|
|
3628
3877
|
return null;
|
|
3629
3878
|
}
|
|
3630
|
-
|
|
3631
|
-
|
|
3879
|
+
let existing = null;
|
|
3880
|
+
try {
|
|
3881
|
+
existing = await getAreaChecklistByAreaAndSchedule(
|
|
3882
|
+
value.schedule.toString(),
|
|
3883
|
+
area._id.toString()
|
|
3884
|
+
);
|
|
3885
|
+
} catch (_) {
|
|
3886
|
+
}
|
|
3887
|
+
if (existing) {
|
|
3888
|
+
const hasAutoGenSets = existing.checklist?.some(
|
|
3889
|
+
(c) => c.isScheduleTask !== true
|
|
3890
|
+
);
|
|
3891
|
+
if (hasAutoGenSets) {
|
|
3892
|
+
import_node_server_utils18.logger.info(
|
|
3893
|
+
`Area checklist already exists with auto-gen sets for area ${area.name}, skipping`
|
|
3894
|
+
);
|
|
3895
|
+
return existing._id;
|
|
3896
|
+
}
|
|
3897
|
+
import_node_server_utils18.logger.info(
|
|
3898
|
+
`Area checklist for area ${area.name} exists but has no auto-gen sets. Inserting auto-gen sets.`
|
|
3899
|
+
);
|
|
3900
|
+
const setCount2 = Number(area.set) || 1;
|
|
3901
|
+
const totalExistingSets = existing.checklist?.length ?? 0;
|
|
3902
|
+
if (totalExistingSets >= setCount2) {
|
|
3903
|
+
import_node_server_utils18.logger.info(
|
|
3904
|
+
`Area checklist for area ${area.name} already has ${totalExistingSets} set(s) (configured: ${setCount2}). Skipping auto-gen sets.`
|
|
3905
|
+
);
|
|
3906
|
+
return existing._id;
|
|
3907
|
+
}
|
|
3908
|
+
const maxExistingSet = existing.checklist?.reduce(
|
|
3909
|
+
(max, c) => Math.max(max, c.set ?? 0),
|
|
3910
|
+
0
|
|
3911
|
+
) ?? 0;
|
|
3912
|
+
const setsToAdd = setCount2 - totalExistingSets;
|
|
3913
|
+
const autoGenSets = Array.from(
|
|
3914
|
+
{ length: setsToAdd },
|
|
3915
|
+
(_, index) => ({
|
|
3916
|
+
set: maxExistingSet + index + 1,
|
|
3917
|
+
isScheduleTask: false,
|
|
3918
|
+
units: area.units.map((unit) => ({
|
|
3919
|
+
unit: new import_mongodb10.ObjectId(unit.unit),
|
|
3920
|
+
name: unit.name,
|
|
3921
|
+
approve: false,
|
|
3922
|
+
reject: false,
|
|
3923
|
+
status: "open",
|
|
3924
|
+
remarks: "",
|
|
3925
|
+
completedBy: "",
|
|
3926
|
+
timestamp: ""
|
|
3927
|
+
}))
|
|
3928
|
+
})
|
|
3929
|
+
);
|
|
3930
|
+
await insertAutoGenSets(
|
|
3931
|
+
value.schedule.toString(),
|
|
3932
|
+
area._id.toString(),
|
|
3933
|
+
autoGenSets
|
|
3934
|
+
);
|
|
3935
|
+
return existing._id;
|
|
3936
|
+
}
|
|
3937
|
+
const setCount = Number(area.set) || 1;
|
|
3632
3938
|
const checklistData = {
|
|
3633
3939
|
schedule: value.schedule,
|
|
3634
3940
|
area: area._id.toString(),
|
|
3635
3941
|
name: area.name,
|
|
3636
3942
|
type: area.type,
|
|
3637
3943
|
checklist: Array.from({ length: setCount }, (_, index) => ({
|
|
3638
|
-
set:
|
|
3944
|
+
set: index + 1,
|
|
3639
3945
|
units: area.units.map((unit) => ({
|
|
3640
3946
|
unit: unit.unit.toString(),
|
|
3641
3947
|
name: unit.name
|
|
@@ -3643,10 +3949,7 @@ function useAreaChecklistService() {
|
|
|
3643
3949
|
})),
|
|
3644
3950
|
createdBy: value.createdBy
|
|
3645
3951
|
};
|
|
3646
|
-
const insertedId = await _createAreaChecklist(
|
|
3647
|
-
checklistData,
|
|
3648
|
-
session
|
|
3649
|
-
);
|
|
3952
|
+
const insertedId = await _createAreaChecklist(checklistData);
|
|
3650
3953
|
totalChecklistsCreated++;
|
|
3651
3954
|
return insertedId;
|
|
3652
3955
|
});
|
|
@@ -3659,25 +3962,26 @@ function useAreaChecklistService() {
|
|
|
3659
3962
|
} else {
|
|
3660
3963
|
import_node_server_utils18.logger.warn(`No common areas found for site: ${value.site}`);
|
|
3661
3964
|
}
|
|
3662
|
-
await session?.commitTransaction();
|
|
3663
3965
|
import_node_server_utils18.logger.info(
|
|
3664
3966
|
`Successfully created ${totalChecklistsCreated} area checklists for site: ${value.site}`
|
|
3665
3967
|
);
|
|
3666
3968
|
return results;
|
|
3667
3969
|
} catch (error) {
|
|
3668
3970
|
import_node_server_utils18.logger.error(`Error generating area checklists:`, error);
|
|
3669
|
-
if (session?.inTransaction()) {
|
|
3670
|
-
await session?.abortTransaction();
|
|
3671
|
-
}
|
|
3672
3971
|
throw error;
|
|
3673
|
-
} finally {
|
|
3674
|
-
session?.endSession();
|
|
3675
3972
|
}
|
|
3676
3973
|
}
|
|
3677
3974
|
async function updateAreaChecklistUnits(_id, set, unitId, value) {
|
|
3678
3975
|
const session = import_node_server_utils18.useAtlas.getClient()?.startSession();
|
|
3679
3976
|
try {
|
|
3680
3977
|
session?.startTransaction();
|
|
3978
|
+
const setOwner = await getAreaChecklistSetOwner(_id, set, session);
|
|
3979
|
+
if (setOwner && value.completedBy && setOwner.toString() !== value.completedBy.toString()) {
|
|
3980
|
+
const acceptedBy = await getUserById(setOwner.toString());
|
|
3981
|
+
throw new import_node_server_utils18.UnauthorizedError(
|
|
3982
|
+
`${acceptedBy.name} has already taken this set.`
|
|
3983
|
+
);
|
|
3984
|
+
}
|
|
3681
3985
|
await _updateAreaChecklistUnits(_id, set, unitId, value, session);
|
|
3682
3986
|
const allUnitsResult = await getAreaChecklistUnits(
|
|
3683
3987
|
{
|
|
@@ -3768,7 +4072,7 @@ var import_node_server_utils20 = require("@7365admin1/node-server-utils");
|
|
|
3768
4072
|
// src/services/hygiene-checklist-pdf.service.ts
|
|
3769
4073
|
var import_puppeteer = require("puppeteer");
|
|
3770
4074
|
var import_node_server_utils19 = require("@7365admin1/node-server-utils");
|
|
3771
|
-
var
|
|
4075
|
+
var import_mongodb11 = require("mongodb");
|
|
3772
4076
|
function escapeHtml(text) {
|
|
3773
4077
|
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
3774
4078
|
}
|
|
@@ -3942,7 +4246,7 @@ function useChecklistPdfService() {
|
|
|
3942
4246
|
const collection = db.collection("site.cleaning.schedule.areas");
|
|
3943
4247
|
let scheduleObjectId;
|
|
3944
4248
|
try {
|
|
3945
|
-
scheduleObjectId = new
|
|
4249
|
+
scheduleObjectId = new import_mongodb11.ObjectId(scheduleId);
|
|
3946
4250
|
} catch {
|
|
3947
4251
|
throw new import_node_server_utils19.InternalServerError("Invalid schedule ID format.");
|
|
3948
4252
|
}
|
|
@@ -4251,7 +4555,7 @@ function useAreaChecklistController() {
|
|
|
4251
4555
|
|
|
4252
4556
|
// src/models/hygiene-supply.model.ts
|
|
4253
4557
|
var import_joi10 = __toESM(require("joi"));
|
|
4254
|
-
var
|
|
4558
|
+
var import_mongodb12 = require("mongodb");
|
|
4255
4559
|
var import_node_server_utils21 = require("@7365admin1/node-server-utils");
|
|
4256
4560
|
var supplySchema = import_joi10.default.object({
|
|
4257
4561
|
site: import_joi10.default.string().hex().required(),
|
|
@@ -4266,7 +4570,7 @@ function MSupply(value) {
|
|
|
4266
4570
|
}
|
|
4267
4571
|
if (value.site) {
|
|
4268
4572
|
try {
|
|
4269
|
-
value.site = new
|
|
4573
|
+
value.site = new import_mongodb12.ObjectId(value.site);
|
|
4270
4574
|
} catch (error2) {
|
|
4271
4575
|
throw new import_node_server_utils21.BadRequestError("Invalid site ID format.");
|
|
4272
4576
|
}
|
|
@@ -4284,7 +4588,7 @@ function MSupply(value) {
|
|
|
4284
4588
|
}
|
|
4285
4589
|
|
|
4286
4590
|
// src/repositories/hygiene-supply.repository.ts
|
|
4287
|
-
var
|
|
4591
|
+
var import_mongodb13 = require("mongodb");
|
|
4288
4592
|
var import_node_server_utils22 = require("@7365admin1/node-server-utils");
|
|
4289
4593
|
function useSupplyRepository() {
|
|
4290
4594
|
const db = import_node_server_utils22.useAtlas.getDb();
|
|
@@ -4360,7 +4664,7 @@ function useSupplyRepository() {
|
|
|
4360
4664
|
limit
|
|
4361
4665
|
};
|
|
4362
4666
|
try {
|
|
4363
|
-
site = new
|
|
4667
|
+
site = new import_mongodb13.ObjectId(site);
|
|
4364
4668
|
query.site = site;
|
|
4365
4669
|
cacheOptions.site = site.toString();
|
|
4366
4670
|
} catch (error) {
|
|
@@ -4404,7 +4708,7 @@ function useSupplyRepository() {
|
|
|
4404
4708
|
}
|
|
4405
4709
|
async function getSupplyById(_id, session) {
|
|
4406
4710
|
try {
|
|
4407
|
-
_id = new
|
|
4711
|
+
_id = new import_mongodb13.ObjectId(_id);
|
|
4408
4712
|
} catch (error) {
|
|
4409
4713
|
throw new import_node_server_utils22.BadRequestError("Invalid supply ID format.");
|
|
4410
4714
|
}
|
|
@@ -4450,7 +4754,7 @@ function useSupplyRepository() {
|
|
|
4450
4754
|
}
|
|
4451
4755
|
async function updateSupply(_id, value, session) {
|
|
4452
4756
|
try {
|
|
4453
|
-
_id = new
|
|
4757
|
+
_id = new import_mongodb13.ObjectId(_id);
|
|
4454
4758
|
} catch (error) {
|
|
4455
4759
|
throw new import_node_server_utils22.BadRequestError("Invalid supply ID format.");
|
|
4456
4760
|
}
|
|
@@ -4483,7 +4787,7 @@ function useSupplyRepository() {
|
|
|
4483
4787
|
}
|
|
4484
4788
|
async function deleteSupply(_id, session) {
|
|
4485
4789
|
try {
|
|
4486
|
-
_id = new
|
|
4790
|
+
_id = new import_mongodb13.ObjectId(_id);
|
|
4487
4791
|
} catch (error) {
|
|
4488
4792
|
throw new import_node_server_utils22.BadRequestError("Invalid supply ID format.");
|
|
4489
4793
|
}
|
|
@@ -4664,7 +4968,7 @@ function useSupplyController() {
|
|
|
4664
4968
|
|
|
4665
4969
|
// src/models/hygiene-stock.model.ts
|
|
4666
4970
|
var import_joi12 = __toESM(require("joi"));
|
|
4667
|
-
var
|
|
4971
|
+
var import_mongodb14 = require("mongodb");
|
|
4668
4972
|
var import_node_server_utils24 = require("@7365admin1/node-server-utils");
|
|
4669
4973
|
var stockSchema = import_joi12.default.object({
|
|
4670
4974
|
site: import_joi12.default.string().hex().required(),
|
|
@@ -4682,14 +4986,14 @@ function MStock(value) {
|
|
|
4682
4986
|
}
|
|
4683
4987
|
if (value.site) {
|
|
4684
4988
|
try {
|
|
4685
|
-
value.site = new
|
|
4989
|
+
value.site = new import_mongodb14.ObjectId(value.site);
|
|
4686
4990
|
} catch (error2) {
|
|
4687
4991
|
throw new import_node_server_utils24.BadRequestError("Invalid site ID format.");
|
|
4688
4992
|
}
|
|
4689
4993
|
}
|
|
4690
4994
|
if (value.supply) {
|
|
4691
4995
|
try {
|
|
4692
|
-
value.supply = new
|
|
4996
|
+
value.supply = new import_mongodb14.ObjectId(value.supply);
|
|
4693
4997
|
} catch (error2) {
|
|
4694
4998
|
throw new import_node_server_utils24.BadRequestError("Invalid supply ID format.");
|
|
4695
4999
|
}
|
|
@@ -4709,7 +5013,7 @@ function MStock(value) {
|
|
|
4709
5013
|
}
|
|
4710
5014
|
|
|
4711
5015
|
// src/repositories/hygiene-stock.repository.ts
|
|
4712
|
-
var
|
|
5016
|
+
var import_mongodb15 = require("mongodb");
|
|
4713
5017
|
var import_node_server_utils25 = require("@7365admin1/node-server-utils");
|
|
4714
5018
|
function useStockRepository() {
|
|
4715
5019
|
const db = import_node_server_utils25.useAtlas.getDb();
|
|
@@ -4774,14 +5078,14 @@ function useStockRepository() {
|
|
|
4774
5078
|
limit
|
|
4775
5079
|
};
|
|
4776
5080
|
try {
|
|
4777
|
-
site = new
|
|
5081
|
+
site = new import_mongodb15.ObjectId(site);
|
|
4778
5082
|
query.site = site;
|
|
4779
5083
|
cacheOptions.site = site.toString();
|
|
4780
5084
|
} catch (error) {
|
|
4781
5085
|
throw new import_node_server_utils25.BadRequestError("Invalid site ID format.");
|
|
4782
5086
|
}
|
|
4783
5087
|
try {
|
|
4784
|
-
supply = new
|
|
5088
|
+
supply = new import_mongodb15.ObjectId(supply);
|
|
4785
5089
|
query.supply = supply;
|
|
4786
5090
|
cacheOptions.supply = supply.toString();
|
|
4787
5091
|
} catch (error) {
|
|
@@ -4955,7 +5259,7 @@ function useStockController() {
|
|
|
4955
5259
|
|
|
4956
5260
|
// src/models/hygiene-checkout-item.model.ts
|
|
4957
5261
|
var import_joi14 = __toESM(require("joi"));
|
|
4958
|
-
var
|
|
5262
|
+
var import_mongodb16 = require("mongodb");
|
|
4959
5263
|
var import_node_server_utils28 = require("@7365admin1/node-server-utils");
|
|
4960
5264
|
var allowedCheckOutItemStatus = ["pending", "completed"];
|
|
4961
5265
|
var checkOutItemSchema = import_joi14.default.object({
|
|
@@ -4975,14 +5279,14 @@ function MCheckOutItem(value) {
|
|
|
4975
5279
|
}
|
|
4976
5280
|
if (value.site) {
|
|
4977
5281
|
try {
|
|
4978
|
-
value.site = new
|
|
5282
|
+
value.site = new import_mongodb16.ObjectId(value.site);
|
|
4979
5283
|
} catch (error2) {
|
|
4980
5284
|
throw new import_node_server_utils28.BadRequestError("Invalid site ID format.");
|
|
4981
5285
|
}
|
|
4982
5286
|
}
|
|
4983
5287
|
if (value.supply) {
|
|
4984
5288
|
try {
|
|
4985
|
-
value.supply = new
|
|
5289
|
+
value.supply = new import_mongodb16.ObjectId(value.supply);
|
|
4986
5290
|
} catch (error2) {
|
|
4987
5291
|
throw new import_node_server_utils28.BadRequestError("Invalid supply ID format.");
|
|
4988
5292
|
}
|
|
@@ -5003,7 +5307,7 @@ function MCheckOutItem(value) {
|
|
|
5003
5307
|
}
|
|
5004
5308
|
|
|
5005
5309
|
// src/repositories/hygiene-checkout-item.repository.ts
|
|
5006
|
-
var
|
|
5310
|
+
var import_mongodb17 = require("mongodb");
|
|
5007
5311
|
var import_node_server_utils29 = require("@7365admin1/node-server-utils");
|
|
5008
5312
|
function useCheckOutItemRepository() {
|
|
5009
5313
|
const db = import_node_server_utils29.useAtlas.getDb();
|
|
@@ -5067,7 +5371,7 @@ function useCheckOutItemRepository() {
|
|
|
5067
5371
|
limit
|
|
5068
5372
|
};
|
|
5069
5373
|
try {
|
|
5070
|
-
site = new
|
|
5374
|
+
site = new import_mongodb17.ObjectId(site);
|
|
5071
5375
|
query.site = site;
|
|
5072
5376
|
cacheOptions.site = site.toString();
|
|
5073
5377
|
} catch (error) {
|
|
@@ -5140,7 +5444,7 @@ function useCheckOutItemRepository() {
|
|
|
5140
5444
|
}
|
|
5141
5445
|
async function getCheckOutItemById(_id, session) {
|
|
5142
5446
|
try {
|
|
5143
|
-
_id = new
|
|
5447
|
+
_id = new import_mongodb17.ObjectId(_id);
|
|
5144
5448
|
} catch (error) {
|
|
5145
5449
|
throw new import_node_server_utils29.BadRequestError("Invalid check out item ID format.");
|
|
5146
5450
|
}
|
|
@@ -5204,7 +5508,7 @@ function useCheckOutItemRepository() {
|
|
|
5204
5508
|
}
|
|
5205
5509
|
async function completeCheckOutItem(_id, session) {
|
|
5206
5510
|
try {
|
|
5207
|
-
_id = new
|
|
5511
|
+
_id = new import_mongodb17.ObjectId(_id);
|
|
5208
5512
|
} catch (error) {
|
|
5209
5513
|
throw new import_node_server_utils29.BadRequestError("Invalid check out item ID format.");
|
|
5210
5514
|
}
|
|
@@ -5245,7 +5549,7 @@ function useCheckOutItemRepository() {
|
|
|
5245
5549
|
}
|
|
5246
5550
|
|
|
5247
5551
|
// src/services/hygiene-checkout-item.service.ts
|
|
5248
|
-
var
|
|
5552
|
+
var import_core2 = require("@7365admin1/core");
|
|
5249
5553
|
var import_node_server_utils30 = require("@7365admin1/node-server-utils");
|
|
5250
5554
|
function useCheckOutItemService() {
|
|
5251
5555
|
const {
|
|
@@ -5254,7 +5558,7 @@ function useCheckOutItemService() {
|
|
|
5254
5558
|
completeCheckOutItem
|
|
5255
5559
|
} = useCheckOutItemRepository();
|
|
5256
5560
|
const { getSupplyById } = useSupplyRepository();
|
|
5257
|
-
const { getUserById } = (0,
|
|
5561
|
+
const { getUserById } = (0, import_core2.useUserRepo)();
|
|
5258
5562
|
const { createStock } = useStockService();
|
|
5259
5563
|
async function createCheckOutItem(value) {
|
|
5260
5564
|
const session = import_node_server_utils30.useAtlas.getClient()?.startSession();
|
|
@@ -5490,7 +5794,7 @@ function useCheckOutItemController() {
|
|
|
5490
5794
|
// src/models/hygiene-schedule-task.model.ts
|
|
5491
5795
|
var import_node_server_utils32 = require("@7365admin1/node-server-utils");
|
|
5492
5796
|
var import_joi16 = __toESM(require("joi"));
|
|
5493
|
-
var
|
|
5797
|
+
var import_mongodb18 = require("mongodb");
|
|
5494
5798
|
var scheduleTaskSchema = import_joi16.default.object({
|
|
5495
5799
|
site: import_joi16.default.string().hex().required(),
|
|
5496
5800
|
title: import_joi16.default.string().required(),
|
|
@@ -5515,7 +5819,7 @@ function MScheduleTask(value) {
|
|
|
5515
5819
|
}
|
|
5516
5820
|
if (value.site) {
|
|
5517
5821
|
try {
|
|
5518
|
-
value.site = new
|
|
5822
|
+
value.site = new import_mongodb18.ObjectId(value.site);
|
|
5519
5823
|
} catch (error2) {
|
|
5520
5824
|
throw new import_node_server_utils32.BadRequestError("Invalid site ID format.");
|
|
5521
5825
|
}
|
|
@@ -5525,7 +5829,7 @@ function MScheduleTask(value) {
|
|
|
5525
5829
|
try {
|
|
5526
5830
|
return {
|
|
5527
5831
|
name: area.name,
|
|
5528
|
-
value: new
|
|
5832
|
+
value: new import_mongodb18.ObjectId(area.value.toString())
|
|
5529
5833
|
};
|
|
5530
5834
|
} catch (error2) {
|
|
5531
5835
|
throw new import_node_server_utils32.BadRequestError(`Invalid area value format: ${area.name}`);
|
|
@@ -5534,7 +5838,7 @@ function MScheduleTask(value) {
|
|
|
5534
5838
|
}
|
|
5535
5839
|
if (value.createdBy) {
|
|
5536
5840
|
try {
|
|
5537
|
-
value.createdBy = new
|
|
5841
|
+
value.createdBy = new import_mongodb18.ObjectId(value.createdBy);
|
|
5538
5842
|
} catch (error2) {
|
|
5539
5843
|
throw new import_node_server_utils32.BadRequestError("Invalid createdBy ID format.");
|
|
5540
5844
|
}
|
|
@@ -5555,7 +5859,7 @@ function MScheduleTask(value) {
|
|
|
5555
5859
|
}
|
|
5556
5860
|
|
|
5557
5861
|
// src/repositories/hygiene-schedule-task.repository.ts
|
|
5558
|
-
var
|
|
5862
|
+
var import_mongodb19 = require("mongodb");
|
|
5559
5863
|
var import_node_server_utils33 = require("@7365admin1/node-server-utils");
|
|
5560
5864
|
function useScheduleTaskRepository() {
|
|
5561
5865
|
const db = import_node_server_utils33.useAtlas.getDb();
|
|
@@ -5618,7 +5922,7 @@ function useScheduleTaskRepository() {
|
|
|
5618
5922
|
limit
|
|
5619
5923
|
};
|
|
5620
5924
|
try {
|
|
5621
|
-
site = new
|
|
5925
|
+
site = new import_mongodb19.ObjectId(site);
|
|
5622
5926
|
query.site = site;
|
|
5623
5927
|
cacheOptions.site = site.toString();
|
|
5624
5928
|
} catch (error) {
|
|
@@ -5686,7 +5990,7 @@ function useScheduleTaskRepository() {
|
|
|
5686
5990
|
limit
|
|
5687
5991
|
};
|
|
5688
5992
|
try {
|
|
5689
|
-
site = new
|
|
5993
|
+
site = new import_mongodb19.ObjectId(site);
|
|
5690
5994
|
query.site = site;
|
|
5691
5995
|
cacheOptions.site = site.toString();
|
|
5692
5996
|
} catch (error) {
|
|
@@ -5729,7 +6033,7 @@ function useScheduleTaskRepository() {
|
|
|
5729
6033
|
}
|
|
5730
6034
|
async function getScheduleTaskById(_id, session) {
|
|
5731
6035
|
try {
|
|
5732
|
-
_id = new
|
|
6036
|
+
_id = new import_mongodb19.ObjectId(_id);
|
|
5733
6037
|
} catch (error) {
|
|
5734
6038
|
throw new import_node_server_utils33.BadRequestError("Invalid schedule task ID format.");
|
|
5735
6039
|
}
|
|
@@ -5779,7 +6083,7 @@ function useScheduleTaskRepository() {
|
|
|
5779
6083
|
}
|
|
5780
6084
|
async function updateScheduleTask(_id, value, session) {
|
|
5781
6085
|
try {
|
|
5782
|
-
_id = new
|
|
6086
|
+
_id = new import_mongodb19.ObjectId(_id);
|
|
5783
6087
|
} catch (error) {
|
|
5784
6088
|
throw new import_node_server_utils33.BadRequestError("Invalid schedule task ID format.");
|
|
5785
6089
|
}
|
|
@@ -5788,7 +6092,7 @@ function useScheduleTaskRepository() {
|
|
|
5788
6092
|
try {
|
|
5789
6093
|
return {
|
|
5790
6094
|
name: area.name,
|
|
5791
|
-
value: new
|
|
6095
|
+
value: new import_mongodb19.ObjectId(area.value.toString())
|
|
5792
6096
|
};
|
|
5793
6097
|
} catch (error) {
|
|
5794
6098
|
throw new import_node_server_utils33.BadRequestError(`Invalid area value format: ${area.name}`);
|
|
@@ -5833,6 +6137,7 @@ function useScheduleTaskRepository() {
|
|
|
5833
6137
|
}
|
|
5834
6138
|
|
|
5835
6139
|
// src/services/hygiene-schedule-task.service.ts
|
|
6140
|
+
var import_mongodb20 = require("mongodb");
|
|
5836
6141
|
var import_node_server_utils34 = require("@7365admin1/node-server-utils");
|
|
5837
6142
|
function useScheduleTaskService() {
|
|
5838
6143
|
const { createParentChecklist } = useParentChecklistRepo();
|
|
@@ -5840,7 +6145,7 @@ function useScheduleTaskService() {
|
|
|
5840
6145
|
const {
|
|
5841
6146
|
createAreaChecklist,
|
|
5842
6147
|
getAreaChecklistByAreaAndSchedule,
|
|
5843
|
-
|
|
6148
|
+
pushScheduleTaskSets
|
|
5844
6149
|
} = useAreaChecklistRepo();
|
|
5845
6150
|
const { getAreaById } = useAreaRepo();
|
|
5846
6151
|
function checkScheduleConditions(schedule, currentDate = /* @__PURE__ */ new Date()) {
|
|
@@ -5879,6 +6184,35 @@ function useScheduleTaskService() {
|
|
|
5879
6184
|
);
|
|
5880
6185
|
return false;
|
|
5881
6186
|
}
|
|
6187
|
+
const relevantTimestamp = schedule.updatedAt || schedule.createdAt;
|
|
6188
|
+
if (relevantTimestamp) {
|
|
6189
|
+
const savedAt = new Date(relevantTimestamp);
|
|
6190
|
+
const savedHour = parseInt(
|
|
6191
|
+
savedAt.toLocaleTimeString("en-US", {
|
|
6192
|
+
hour: "2-digit",
|
|
6193
|
+
hour12: false,
|
|
6194
|
+
timeZone: "Asia/Singapore"
|
|
6195
|
+
}),
|
|
6196
|
+
10
|
|
6197
|
+
);
|
|
6198
|
+
const savedMinute = savedAt.toLocaleString("en-US", {
|
|
6199
|
+
minute: "2-digit",
|
|
6200
|
+
timeZone: "Asia/Singapore"
|
|
6201
|
+
});
|
|
6202
|
+
const savedDateFormatted = savedAt.toLocaleDateString("en-CA", {
|
|
6203
|
+
timeZone: "Asia/Singapore"
|
|
6204
|
+
});
|
|
6205
|
+
const savedMinNum = parseInt(savedMinute, 10);
|
|
6206
|
+
const wasSavedThisMinute = savedDateFormatted === currentDateFormatted && savedHour === currentHour && savedMinNum === currentMinute;
|
|
6207
|
+
if (wasSavedThisMinute) {
|
|
6208
|
+
import_node_server_utils34.logger.info(
|
|
6209
|
+
`Schedule ${schedule._id}: Skipping \u2014 task was saved this minute (${savedHour}:${String(
|
|
6210
|
+
savedMinNum
|
|
6211
|
+
).padStart(2, "0")}). Will fire on next occurrence.`
|
|
6212
|
+
);
|
|
6213
|
+
return false;
|
|
6214
|
+
}
|
|
6215
|
+
}
|
|
5882
6216
|
import_node_server_utils34.logger.info(
|
|
5883
6217
|
`Schedule ${schedule._id}: All conditions matched - Date is within range and time matches`
|
|
5884
6218
|
);
|
|
@@ -5946,8 +6280,14 @@ function useScheduleTaskService() {
|
|
|
5946
6280
|
let units = [];
|
|
5947
6281
|
if (areaDetails.units && areaDetails.units.length > 0) {
|
|
5948
6282
|
units = areaDetails.units.map((unit) => ({
|
|
5949
|
-
unit: unit.unit
|
|
5950
|
-
name: unit.name
|
|
6283
|
+
unit: new import_mongodb20.ObjectId(unit.unit),
|
|
6284
|
+
name: unit.name,
|
|
6285
|
+
approve: false,
|
|
6286
|
+
reject: false,
|
|
6287
|
+
status: "open",
|
|
6288
|
+
remarks: "",
|
|
6289
|
+
completedBy: "",
|
|
6290
|
+
timestamp: ""
|
|
5951
6291
|
}));
|
|
5952
6292
|
import_node_server_utils34.logger.info(
|
|
5953
6293
|
`Area ${area.name} (${areaId}): Using units from area details: ${JSON.stringify(
|
|
@@ -5984,79 +6324,62 @@ function useScheduleTaskService() {
|
|
|
5984
6324
|
);
|
|
5985
6325
|
}
|
|
5986
6326
|
if (existingAreaChecklist) {
|
|
5987
|
-
const
|
|
5988
|
-
const
|
|
5989
|
-
|
|
5990
|
-
|
|
5991
|
-
|
|
5992
|
-
|
|
5993
|
-
|
|
5994
|
-
|
|
5995
|
-
|
|
5996
|
-
|
|
5997
|
-
|
|
5998
|
-
|
|
5999
|
-
|
|
6327
|
+
const areaSetConfig = Number(areaDetails.set) || 1;
|
|
6328
|
+
const maxSetInChecklist = existingAreaChecklist.checklist?.length ? Math.max(
|
|
6329
|
+
...existingAreaChecklist.checklist.map(
|
|
6330
|
+
(c) => c.set
|
|
6331
|
+
)
|
|
6332
|
+
) : 0;
|
|
6333
|
+
const startSetNumber = maxSetInChecklist + 1;
|
|
6334
|
+
const newSets = Array.from(
|
|
6335
|
+
{ length: areaSetConfig },
|
|
6336
|
+
(_, index) => ({
|
|
6337
|
+
set: startSetNumber + index,
|
|
6338
|
+
units,
|
|
6339
|
+
isScheduleTask: true,
|
|
6340
|
+
scheduleTaskId: scheduleTask._id
|
|
6341
|
+
})
|
|
6000
6342
|
);
|
|
6001
|
-
await
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6005
|
-
|
|
6343
|
+
const modified = await pushScheduleTaskSets(
|
|
6344
|
+
parentChecklistId.toString(),
|
|
6345
|
+
areaId,
|
|
6346
|
+
scheduleTask._id.toString(),
|
|
6347
|
+
newSets
|
|
6006
6348
|
);
|
|
6007
|
-
|
|
6008
|
-
const verifyChecklist = await getAreaChecklistByAreaAndSchedule(
|
|
6009
|
-
parentChecklistId.toString(),
|
|
6010
|
-
areaId
|
|
6011
|
-
);
|
|
6349
|
+
if (modified > 0) {
|
|
6012
6350
|
import_node_server_utils34.logger.info(
|
|
6013
|
-
`
|
|
6014
|
-
verifyChecklist.checklist
|
|
6015
|
-
)}`
|
|
6351
|
+
`Appended ${areaSetConfig} set(s) starting from ${startSetNumber} to area checklist for area ${area.name}`
|
|
6016
6352
|
);
|
|
6017
|
-
}
|
|
6018
|
-
import_node_server_utils34.logger.
|
|
6019
|
-
`Area ${area.name} (${areaId}):
|
|
6020
|
-
verifyError
|
|
6353
|
+
} else {
|
|
6354
|
+
import_node_server_utils34.logger.info(
|
|
6355
|
+
`Area ${area.name} (${areaId}): Schedule task ${scheduleTask._id} already processed (atomic check), skipping.`
|
|
6021
6356
|
);
|
|
6022
6357
|
}
|
|
6023
6358
|
} else {
|
|
6359
|
+
const areaSetConfig = Number(areaDetails.set) || 1;
|
|
6360
|
+
const schedTaskId = scheduleTask._id;
|
|
6361
|
+
const schedTaskSets = Array.from(
|
|
6362
|
+
{ length: areaSetConfig },
|
|
6363
|
+
(_, index) => ({
|
|
6364
|
+
set: index + 1,
|
|
6365
|
+
units,
|
|
6366
|
+
isScheduleTask: true,
|
|
6367
|
+
scheduleTaskId: schedTaskId
|
|
6368
|
+
})
|
|
6369
|
+
);
|
|
6024
6370
|
const checklistData = {
|
|
6025
6371
|
schedule: parentChecklistId.toString(),
|
|
6026
6372
|
area: areaId,
|
|
6027
6373
|
name: area.name,
|
|
6028
6374
|
type: areaDetails.type || "common",
|
|
6029
|
-
checklist:
|
|
6030
|
-
{
|
|
6031
|
-
set: 1,
|
|
6032
|
-
units
|
|
6033
|
-
}
|
|
6034
|
-
],
|
|
6375
|
+
checklist: schedTaskSets,
|
|
6035
6376
|
createdBy: scheduleTask.createdBy
|
|
6036
6377
|
};
|
|
6037
6378
|
import_node_server_utils34.logger.info(
|
|
6038
|
-
`Area ${area.name} (${areaId}): Creating new area checklist with
|
|
6039
|
-
checklistData
|
|
6040
|
-
)}`
|
|
6379
|
+
`Area ${area.name} (${areaId}): Creating new area checklist with schedule-task sets only`
|
|
6041
6380
|
);
|
|
6042
6381
|
await createAreaChecklist(checklistData);
|
|
6043
6382
|
import_node_server_utils34.logger.info(`Created new area checklist for area ${area.name}`);
|
|
6044
|
-
try {
|
|
6045
|
-
const verifyChecklist = await getAreaChecklistByAreaAndSchedule(
|
|
6046
|
-
parentChecklistId.toString(),
|
|
6047
|
-
areaId
|
|
6048
|
-
);
|
|
6049
|
-
import_node_server_utils34.logger.info(
|
|
6050
|
-
`Area ${area.name} (${areaId}): Checklist after creation: ${JSON.stringify(
|
|
6051
|
-
verifyChecklist.checklist
|
|
6052
|
-
)}`
|
|
6053
|
-
);
|
|
6054
|
-
} catch (verifyError) {
|
|
6055
|
-
import_node_server_utils34.logger.warn(
|
|
6056
|
-
`Area ${area.name} (${areaId}): Error verifying checklist after creation:`,
|
|
6057
|
-
verifyError
|
|
6058
|
-
);
|
|
6059
|
-
}
|
|
6060
6383
|
}
|
|
6061
6384
|
} catch (error) {
|
|
6062
6385
|
import_node_server_utils34.logger.error(`Error processing area ${area.name}:`, error);
|