@7365admin1/module-hygiene 4.28.1 → 4.28.2-staging.10
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/.changeset/hygiene-checkout-approval.md +5 -0
- package/dist/index.d.ts +43 -2
- package/dist/index.js +132 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +128 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/test/hygiene-checkout-decision.util.test.mjs +64 -0
package/dist/index.d.ts
CHANGED
|
@@ -512,6 +512,36 @@ declare function useStockController(): {
|
|
|
512
512
|
getStocksBySupplyId: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
513
513
|
};
|
|
514
514
|
|
|
515
|
+
/**
|
|
516
|
+
* The approval decision on a hygiene check out item, as data.
|
|
517
|
+
*
|
|
518
|
+
* Kept out of the repository so it can be tested without a database, the same
|
|
519
|
+
* way `hygiene-dashboard-metrics.util.ts` is. The repository wraps the ids in
|
|
520
|
+
* `ObjectId` and hands the rest of this straight to `$set`.
|
|
521
|
+
*
|
|
522
|
+
* Shape follows `hygiene-area-checklist`: an approve/reject pair plus a
|
|
523
|
+
* terminal `status: "completed"`, so the `allowedCheckOutItemStatus`
|
|
524
|
+
* vocabulary (`pending` | `completed`) gains no new value. Rows written before
|
|
525
|
+
* this feature carry no `approve`/`reject` at all, which reads as "not
|
|
526
|
+
* decided" — nothing is backfilled.
|
|
527
|
+
*/
|
|
528
|
+
declare const CHECKOUT_DECISIONS: readonly ["approve", "disapprove"];
|
|
529
|
+
type TCheckOutDecision = (typeof CHECKOUT_DECISIONS)[number];
|
|
530
|
+
declare function isCheckOutDecision(value: string): value is TCheckOutDecision;
|
|
531
|
+
/**
|
|
532
|
+
* Only a `pending` row may be decided. Returning the status the update must
|
|
533
|
+
* match — rather than matching on `_id` alone — is what makes a second
|
|
534
|
+
* approval a refusal instead of a silent overwrite of the first one.
|
|
535
|
+
*/
|
|
536
|
+
declare const CHECKOUT_DECIDABLE_STATUS = "pending";
|
|
537
|
+
declare function buildCheckOutDecision(decision: TCheckOutDecision, remarks?: string | null, now?: string): {
|
|
538
|
+
approve: boolean;
|
|
539
|
+
reject: boolean;
|
|
540
|
+
status: string;
|
|
541
|
+
remarks: string;
|
|
542
|
+
updatedAt: string;
|
|
543
|
+
};
|
|
544
|
+
|
|
515
545
|
declare const allowedCheckOutItemStatus: string[];
|
|
516
546
|
type TCheckOutItem = {
|
|
517
547
|
_id?: ObjectId;
|
|
@@ -525,6 +555,10 @@ type TCheckOutItem = {
|
|
|
525
555
|
createdBy: string | ObjectId;
|
|
526
556
|
createdByName: string;
|
|
527
557
|
status?: (typeof allowedCheckOutItemStatus)[number];
|
|
558
|
+
approve?: boolean;
|
|
559
|
+
reject?: boolean;
|
|
560
|
+
remarks?: string;
|
|
561
|
+
completedBy?: string | ObjectId;
|
|
528
562
|
createdAt?: string;
|
|
529
563
|
updatedAt?: string;
|
|
530
564
|
deletedAt?: string;
|
|
@@ -534,12 +568,13 @@ type TCheckOutItemCreateService = Pick<TCheckOutItem, "site" | "serviceType" | "
|
|
|
534
568
|
type TCheckOutItemCreateByBatchService = Pick<TCheckOutItem, "site" | "serviceType" | "createdBy"> & {
|
|
535
569
|
items: Pick<TCheckOutItem, "supply" | "qty" | "attachment">[];
|
|
536
570
|
};
|
|
571
|
+
type TCheckOutItemDecision = Pick<TCheckOutItem, "approve" | "reject" | "remarks" | "completedBy">;
|
|
537
572
|
type TCheckOutItemGetQuery = {
|
|
538
573
|
page?: number;
|
|
539
574
|
limit?: number;
|
|
540
575
|
search?: string;
|
|
541
576
|
} & Pick<TCheckOutItem, "site" | "serviceType">;
|
|
542
|
-
type TCheckOutItemGetById = Pick<TCheckOutItem, "_id" | "site" | "serviceType" | "supply" | "supplyName" | "supplyQty" | "qty" | "status"> & {
|
|
577
|
+
type TCheckOutItemGetById = Pick<TCheckOutItem, "_id" | "site" | "serviceType" | "supply" | "supplyName" | "supplyQty" | "qty" | "status" | "approve" | "reject" | "remarks"> & {
|
|
543
578
|
unitOfMeasurement?: string;
|
|
544
579
|
};
|
|
545
580
|
declare const checkOutItemSchema: Joi.ObjectSchema<any>;
|
|
@@ -554,6 +589,10 @@ declare function MCheckOutItem(value: TCheckOutItemCreate): {
|
|
|
554
589
|
createdBy: string | ObjectId;
|
|
555
590
|
createdByName: string;
|
|
556
591
|
status: string;
|
|
592
|
+
approve: boolean;
|
|
593
|
+
reject: boolean;
|
|
594
|
+
remarks: string;
|
|
595
|
+
completedBy: string;
|
|
557
596
|
createdAt: string;
|
|
558
597
|
updatedAt: string;
|
|
559
598
|
deletedAt: string;
|
|
@@ -566,6 +605,7 @@ declare function useCheckOutItemRepository(): {
|
|
|
566
605
|
getCheckOutItems: ({ page, limit, search, site, serviceType, }: TCheckOutItemGetQuery) => Promise<{}>;
|
|
567
606
|
getCheckOutItemById: (_id: string | ObjectId, session?: ClientSession) => Promise<TCheckOutItemGetById>;
|
|
568
607
|
completeCheckOutItem: (_id: string | ObjectId, session?: ClientSession) => Promise<number>;
|
|
608
|
+
decideCheckOutItem: (_id: string | ObjectId, value: TCheckOutItemDecision, session?: ClientSession) => Promise<number>;
|
|
569
609
|
};
|
|
570
610
|
|
|
571
611
|
declare function useCheckOutItemService(): {
|
|
@@ -578,6 +618,7 @@ declare function useCheckOutItemController(): {
|
|
|
578
618
|
createCheckOutItemByBatch: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
579
619
|
getCheckOutItems: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
580
620
|
getCheckOutItemById: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
621
|
+
decideCheckOutItem: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
581
622
|
};
|
|
582
623
|
|
|
583
624
|
type TScheduleTask = {
|
|
@@ -664,4 +705,4 @@ declare function useQRController(): {
|
|
|
664
705
|
generateQR: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
665
706
|
};
|
|
666
707
|
|
|
667
|
-
export { MArea, MAreaChecklist, MCheckOutItem, MParentChecklist, MScheduleTask, MStock, MSupply, MUnit, TArea, TAreaChecklist, TAreaChecklistBatchCreate, TAreaChecklistCreate, TAreaChecklistUnits, TAreaChecklistUnitsUpdate, TAreaChecklistUpdate, TAreaCreate, TAreaGetQuery, TAreaUnits, TAreaUpdate, TAreaUpdateChecklist, TCheckOutItem, TCheckOutItemCreate, TCheckOutItemCreateByBatchService, TCheckOutItemCreateService, TCheckOutItemGetById, TCheckOutItemGetQuery, TCleaningScheduleArea, TCleaningScheduleAreaGetQuery, TGetStocksQuery, TParentChecklist, TParentChecklistCreate, TParentChecklistGetQuery, TScheduleTask, TScheduleTaskCreate, TScheduleTaskGetById, TScheduleTaskGetQuery, TScheduleTaskUpdate, TStock, TStockCreate, TStockCreateService, TSupply, TSupplyCreate, TSupplyGetById, TSupplyGetQuery, TSupplyUpdate, TUnit, TUnitCreate, TUnitGetQuery, TUnitUpdate, allowedCheckOutItemStatus, allowedChecklistStatus, allowedPeriods, allowedStatus, allowedTypes, areaChecklistSchema, areaSchema, checkOutItemSchema, parentChecklistSchema, scheduleTaskSchema, stockSchema, supplySchema, unitSchema, useAreaChecklistController, useAreaChecklistRepo, useAreaChecklistService, useAreaController, useAreaExportService, useAreaRepo, useAreaService, useCheckOutItemController, useCheckOutItemRepository, useCheckOutItemService, useHygieneDashboardController, useHygieneDashboardRepository, useParentChecklistController, useParentChecklistRepo, useQRController, useQRService, useScheduleTaskController, useScheduleTaskRepository, useScheduleTaskService, useStockController, useStockRepository, useStockService, useSupplyController, useSupplyRepository, useUnitController, useUnitExportService, useUnitRepository, useUnitService };
|
|
708
|
+
export { CHECKOUT_DECIDABLE_STATUS, CHECKOUT_DECISIONS, MArea, MAreaChecklist, MCheckOutItem, MParentChecklist, MScheduleTask, MStock, MSupply, MUnit, TArea, TAreaChecklist, TAreaChecklistBatchCreate, TAreaChecklistCreate, TAreaChecklistUnits, TAreaChecklistUnitsUpdate, TAreaChecklistUpdate, TAreaCreate, TAreaGetQuery, TAreaUnits, TAreaUpdate, TAreaUpdateChecklist, TCheckOutDecision, TCheckOutItem, TCheckOutItemCreate, TCheckOutItemCreateByBatchService, TCheckOutItemCreateService, TCheckOutItemDecision, TCheckOutItemGetById, TCheckOutItemGetQuery, TCleaningScheduleArea, TCleaningScheduleAreaGetQuery, TGetStocksQuery, TParentChecklist, TParentChecklistCreate, TParentChecklistGetQuery, TScheduleTask, TScheduleTaskCreate, TScheduleTaskGetById, TScheduleTaskGetQuery, TScheduleTaskUpdate, TStock, TStockCreate, TStockCreateService, TSupply, TSupplyCreate, TSupplyGetById, TSupplyGetQuery, TSupplyUpdate, TUnit, TUnitCreate, TUnitGetQuery, TUnitUpdate, allowedCheckOutItemStatus, allowedChecklistStatus, allowedPeriods, allowedStatus, allowedTypes, areaChecklistSchema, areaSchema, buildCheckOutDecision, checkOutItemSchema, isCheckOutDecision, parentChecklistSchema, scheduleTaskSchema, stockSchema, supplySchema, unitSchema, useAreaChecklistController, useAreaChecklistRepo, useAreaChecklistService, useAreaController, useAreaExportService, useAreaRepo, useAreaService, useCheckOutItemController, useCheckOutItemRepository, useCheckOutItemService, useHygieneDashboardController, useHygieneDashboardRepository, useParentChecklistController, useParentChecklistRepo, useQRController, useQRService, useScheduleTaskController, useScheduleTaskRepository, useScheduleTaskService, useStockController, useStockRepository, useStockService, useSupplyController, useSupplyRepository, useUnitController, useUnitExportService, useUnitRepository, useUnitService };
|
package/dist/index.js
CHANGED
|
@@ -30,6 +30,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var src_exports = {};
|
|
32
32
|
__export(src_exports, {
|
|
33
|
+
CHECKOUT_DECIDABLE_STATUS: () => CHECKOUT_DECIDABLE_STATUS,
|
|
34
|
+
CHECKOUT_DECISIONS: () => CHECKOUT_DECISIONS,
|
|
33
35
|
MArea: () => MArea,
|
|
34
36
|
MAreaChecklist: () => MAreaChecklist,
|
|
35
37
|
MCheckOutItem: () => MCheckOutItem,
|
|
@@ -45,7 +47,9 @@ __export(src_exports, {
|
|
|
45
47
|
allowedTypes: () => allowedTypes,
|
|
46
48
|
areaChecklistSchema: () => areaChecklistSchema,
|
|
47
49
|
areaSchema: () => areaSchema,
|
|
50
|
+
buildCheckOutDecision: () => buildCheckOutDecision,
|
|
48
51
|
checkOutItemSchema: () => checkOutItemSchema,
|
|
52
|
+
isCheckOutDecision: () => isCheckOutDecision,
|
|
49
53
|
parentChecklistSchema: () => parentChecklistSchema,
|
|
50
54
|
scheduleTaskSchema: () => scheduleTaskSchema,
|
|
51
55
|
stockSchema: () => stockSchema,
|
|
@@ -5876,6 +5880,23 @@ function useStockController() {
|
|
|
5876
5880
|
};
|
|
5877
5881
|
}
|
|
5878
5882
|
|
|
5883
|
+
// src/utils/hygiene-checkout-decision.util.ts
|
|
5884
|
+
var CHECKOUT_DECISIONS = ["approve", "disapprove"];
|
|
5885
|
+
function isCheckOutDecision(value) {
|
|
5886
|
+
return CHECKOUT_DECISIONS.includes(value);
|
|
5887
|
+
}
|
|
5888
|
+
var CHECKOUT_DECIDABLE_STATUS = "pending";
|
|
5889
|
+
function buildCheckOutDecision(decision, remarks, now = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
5890
|
+
const approve = decision === "approve";
|
|
5891
|
+
return {
|
|
5892
|
+
approve,
|
|
5893
|
+
reject: !approve,
|
|
5894
|
+
status: "completed",
|
|
5895
|
+
remarks: remarks ?? "",
|
|
5896
|
+
updatedAt: now
|
|
5897
|
+
};
|
|
5898
|
+
}
|
|
5899
|
+
|
|
5879
5900
|
// src/models/hygiene-checkout-item.model.ts
|
|
5880
5901
|
var import_joi14 = __toESM(require("joi"));
|
|
5881
5902
|
var import_mongodb16 = require("mongodb");
|
|
@@ -5924,6 +5945,10 @@ function MCheckOutItem(value) {
|
|
|
5924
5945
|
createdBy: value.createdBy,
|
|
5925
5946
|
createdByName: value.createdByName,
|
|
5926
5947
|
status: "pending",
|
|
5948
|
+
approve: false,
|
|
5949
|
+
reject: false,
|
|
5950
|
+
remarks: "",
|
|
5951
|
+
completedBy: "",
|
|
5927
5952
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5928
5953
|
updatedAt: "",
|
|
5929
5954
|
deletedAt: ""
|
|
@@ -6054,7 +6079,10 @@ function useCheckOutItemRepository() {
|
|
|
6054
6079
|
profile: "$createdByDoc.profile",
|
|
6055
6080
|
checkOutQty: "$qty",
|
|
6056
6081
|
createdAt: 1,
|
|
6057
|
-
status: 1
|
|
6082
|
+
status: 1,
|
|
6083
|
+
approve: 1,
|
|
6084
|
+
reject: 1,
|
|
6085
|
+
remarks: 1
|
|
6058
6086
|
}
|
|
6059
6087
|
},
|
|
6060
6088
|
{ $sort: { _id: -1 } },
|
|
@@ -6120,7 +6148,10 @@ function useCheckOutItemRepository() {
|
|
|
6120
6148
|
status: 1,
|
|
6121
6149
|
unitOfMeasurement: "$supplyDetails.unitOfMeasurement",
|
|
6122
6150
|
stockQty: "$supplyQty",
|
|
6123
|
-
attachment: 1
|
|
6151
|
+
attachment: 1,
|
|
6152
|
+
approve: 1,
|
|
6153
|
+
reject: 1,
|
|
6154
|
+
remarks: 1
|
|
6124
6155
|
}
|
|
6125
6156
|
}
|
|
6126
6157
|
],
|
|
@@ -6171,13 +6202,55 @@ function useCheckOutItemRepository() {
|
|
|
6171
6202
|
throw error;
|
|
6172
6203
|
}
|
|
6173
6204
|
}
|
|
6205
|
+
async function decideCheckOutItem(_id, value, session) {
|
|
6206
|
+
try {
|
|
6207
|
+
_id = new import_mongodb17.ObjectId(_id);
|
|
6208
|
+
} catch (error) {
|
|
6209
|
+
throw new import_node_server_utils29.BadRequestError("Invalid check out item ID format.");
|
|
6210
|
+
}
|
|
6211
|
+
const updateValue = buildCheckOutDecision(
|
|
6212
|
+
value.approve === true ? "approve" : "disapprove",
|
|
6213
|
+
value.remarks
|
|
6214
|
+
);
|
|
6215
|
+
if (value.completedBy) {
|
|
6216
|
+
try {
|
|
6217
|
+
updateValue.completedBy = new import_mongodb17.ObjectId(value.completedBy);
|
|
6218
|
+
} catch (error) {
|
|
6219
|
+
throw new import_node_server_utils29.BadRequestError("Invalid user ID format.");
|
|
6220
|
+
}
|
|
6221
|
+
}
|
|
6222
|
+
try {
|
|
6223
|
+
const res = await collection.updateOne(
|
|
6224
|
+
{ _id, status: CHECKOUT_DECIDABLE_STATUS },
|
|
6225
|
+
{ $set: updateValue },
|
|
6226
|
+
{ session }
|
|
6227
|
+
);
|
|
6228
|
+
if (res.matchedCount === 0) {
|
|
6229
|
+
throw new import_node_server_utils29.NotFoundError(
|
|
6230
|
+
"Check out item not found or is no longer pending approval."
|
|
6231
|
+
);
|
|
6232
|
+
}
|
|
6233
|
+
delNamespace().then(() => {
|
|
6234
|
+
import_node_server_utils29.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
6235
|
+
}).catch((err) => {
|
|
6236
|
+
import_node_server_utils29.logger.error(
|
|
6237
|
+
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
6238
|
+
err
|
|
6239
|
+
);
|
|
6240
|
+
});
|
|
6241
|
+
return res.modifiedCount;
|
|
6242
|
+
} catch (error) {
|
|
6243
|
+
throw error;
|
|
6244
|
+
}
|
|
6245
|
+
}
|
|
6174
6246
|
return {
|
|
6175
6247
|
createIndex,
|
|
6176
6248
|
createTextIndex,
|
|
6177
6249
|
createCheckOutItem,
|
|
6178
6250
|
getCheckOutItems,
|
|
6179
6251
|
getCheckOutItemById,
|
|
6180
|
-
completeCheckOutItem
|
|
6252
|
+
completeCheckOutItem,
|
|
6253
|
+
decideCheckOutItem
|
|
6181
6254
|
};
|
|
6182
6255
|
}
|
|
6183
6256
|
|
|
@@ -6292,7 +6365,8 @@ var import_core18 = require("@7365admin1/core");
|
|
|
6292
6365
|
function useCheckOutItemController() {
|
|
6293
6366
|
const {
|
|
6294
6367
|
getCheckOutItems: _getCheckOutItems,
|
|
6295
|
-
getCheckOutItemById: _getCheckOutItemById
|
|
6368
|
+
getCheckOutItemById: _getCheckOutItemById,
|
|
6369
|
+
decideCheckOutItem: _decideCheckOutItem
|
|
6296
6370
|
} = useCheckOutItemRepository();
|
|
6297
6371
|
const {
|
|
6298
6372
|
createCheckOutItem: _createCheckOutItem,
|
|
@@ -6427,11 +6501,60 @@ function useCheckOutItemController() {
|
|
|
6427
6501
|
return;
|
|
6428
6502
|
}
|
|
6429
6503
|
}
|
|
6504
|
+
async function decideCheckOutItem(req, res, next) {
|
|
6505
|
+
const cookies = req.headers.cookie ? req.headers.cookie.split(";").map((cookie) => cookie.trim().split("=")).reduce(
|
|
6506
|
+
(acc, [key, value]) => ({ ...acc, [key]: value }),
|
|
6507
|
+
{}
|
|
6508
|
+
) : {};
|
|
6509
|
+
const completedBy = cookies["user"] || "";
|
|
6510
|
+
const decisionMap = {
|
|
6511
|
+
approve: { approve: true, reject: false },
|
|
6512
|
+
disapprove: { approve: false, reject: true }
|
|
6513
|
+
};
|
|
6514
|
+
const decision = req.params.decision;
|
|
6515
|
+
const decisionValues = decisionMap[decision] || {
|
|
6516
|
+
approve: void 0,
|
|
6517
|
+
reject: void 0
|
|
6518
|
+
};
|
|
6519
|
+
const payload = {
|
|
6520
|
+
...req.params,
|
|
6521
|
+
...req.body,
|
|
6522
|
+
...decisionValues,
|
|
6523
|
+
completedBy
|
|
6524
|
+
};
|
|
6525
|
+
const validation = import_joi15.default.object({
|
|
6526
|
+
id: import_joi15.default.string().hex().required(),
|
|
6527
|
+
decision: import_joi15.default.string().valid("approve", "disapprove").required(),
|
|
6528
|
+
approve: import_joi15.default.boolean().required(),
|
|
6529
|
+
reject: import_joi15.default.boolean().required(),
|
|
6530
|
+
remarks: import_joi15.default.string().optional().allow("", null),
|
|
6531
|
+
completedBy: import_joi15.default.string().hex().required()
|
|
6532
|
+
});
|
|
6533
|
+
const { error } = validation.validate(payload);
|
|
6534
|
+
if (error) {
|
|
6535
|
+
import_node_server_utils31.logger.log({ level: "error", message: error.message });
|
|
6536
|
+
next(new import_node_server_utils31.BadRequestError(error.message));
|
|
6537
|
+
return;
|
|
6538
|
+
}
|
|
6539
|
+
try {
|
|
6540
|
+
const { id, decision: _d, ...value } = payload;
|
|
6541
|
+
await _decideCheckOutItem(id, value);
|
|
6542
|
+
res.json({
|
|
6543
|
+
message: `Check out item ${decision === "approve" ? "approved" : "disapproved"} successfully.`
|
|
6544
|
+
});
|
|
6545
|
+
return;
|
|
6546
|
+
} catch (error2) {
|
|
6547
|
+
import_node_server_utils31.logger.log({ level: "error", message: error2.message });
|
|
6548
|
+
next(error2);
|
|
6549
|
+
return;
|
|
6550
|
+
}
|
|
6551
|
+
}
|
|
6430
6552
|
return {
|
|
6431
6553
|
createCheckOutItem,
|
|
6432
6554
|
createCheckOutItemByBatch,
|
|
6433
6555
|
getCheckOutItems,
|
|
6434
|
-
getCheckOutItemById
|
|
6556
|
+
getCheckOutItemById,
|
|
6557
|
+
decideCheckOutItem
|
|
6435
6558
|
};
|
|
6436
6559
|
}
|
|
6437
6560
|
|
|
@@ -7472,6 +7595,8 @@ function useQRController() {
|
|
|
7472
7595
|
}
|
|
7473
7596
|
// Annotate the CommonJS export names for ESM import in node:
|
|
7474
7597
|
0 && (module.exports = {
|
|
7598
|
+
CHECKOUT_DECIDABLE_STATUS,
|
|
7599
|
+
CHECKOUT_DECISIONS,
|
|
7475
7600
|
MArea,
|
|
7476
7601
|
MAreaChecklist,
|
|
7477
7602
|
MCheckOutItem,
|
|
@@ -7487,7 +7612,9 @@ function useQRController() {
|
|
|
7487
7612
|
allowedTypes,
|
|
7488
7613
|
areaChecklistSchema,
|
|
7489
7614
|
areaSchema,
|
|
7615
|
+
buildCheckOutDecision,
|
|
7490
7616
|
checkOutItemSchema,
|
|
7617
|
+
isCheckOutDecision,
|
|
7491
7618
|
parentChecklistSchema,
|
|
7492
7619
|
scheduleTaskSchema,
|
|
7493
7620
|
stockSchema,
|