@7365admin1/module-hygiene 4.0.0 → 4.2.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/dist/index.mjs CHANGED
@@ -2273,7 +2273,8 @@ var areaChecklistSchema = Joi8.object({
2273
2273
  }).required()
2274
2274
  ).min(1).required()
2275
2275
  }).required()
2276
- ).optional().default([])
2276
+ ).optional().default([]),
2277
+ createdBy: Joi8.string().hex().required()
2277
2278
  });
2278
2279
  function MAreaChecklist(value) {
2279
2280
  const { error } = areaChecklistSchema.validate(value);
@@ -2310,6 +2311,13 @@ function MAreaChecklist(value) {
2310
2311
  };
2311
2312
  });
2312
2313
  }
2314
+ if (value.createdBy) {
2315
+ try {
2316
+ value.createdBy = new ObjectId8(value.createdBy);
2317
+ } catch (error2) {
2318
+ throw new BadRequestError14("Invalid createdBy ID format.");
2319
+ }
2320
+ }
2313
2321
  return {
2314
2322
  schedule: value.schedule,
2315
2323
  area: value.area,
@@ -2317,6 +2325,7 @@ function MAreaChecklist(value) {
2317
2325
  type: value.type,
2318
2326
  checklist: value.checklist || [],
2319
2327
  status: "ready",
2328
+ createdBy: value.createdBy,
2320
2329
  createdAt: /* @__PURE__ */ new Date(),
2321
2330
  completedAt: "",
2322
2331
  updatedAt: ""
@@ -2455,6 +2464,32 @@ function useAreaChecklistRepo() {
2455
2464
  try {
2456
2465
  const pipeline = [
2457
2466
  { $match: query },
2467
+ {
2468
+ $lookup: {
2469
+ from: "users",
2470
+ let: { createdById: "$createdBy" },
2471
+ pipeline: [
2472
+ {
2473
+ $match: {
2474
+ $expr: {
2475
+ $and: [
2476
+ { $ne: ["$$createdById", ""] },
2477
+ { $eq: ["$_id", "$$createdById"] }
2478
+ ]
2479
+ }
2480
+ }
2481
+ },
2482
+ { $project: { name: 1 } }
2483
+ ],
2484
+ as: "createdByDoc"
2485
+ }
2486
+ },
2487
+ {
2488
+ $unwind: {
2489
+ path: "$createdByDoc",
2490
+ preserveNullAndEmptyArrays: true
2491
+ }
2492
+ },
2458
2493
  {
2459
2494
  $project: {
2460
2495
  name: 1,
@@ -2486,7 +2521,8 @@ function useAreaChecklistRepo() {
2486
2521
  },
2487
2522
  else: 0
2488
2523
  }
2489
- }
2524
+ },
2525
+ createdByName: "$createdByDoc.name"
2490
2526
  }
2491
2527
  },
2492
2528
  { $sort: { _id: -1 } },
@@ -3119,7 +3155,8 @@ function useAreaChecklistService() {
3119
3155
  unit: unit.unit.toString(),
3120
3156
  name: unit.name
3121
3157
  }))
3122
- }))
3158
+ })),
3159
+ createdBy: value.createdBy
3123
3160
  };
3124
3161
  const insertedId = await _createAreaChecklist(
3125
3162
  checklistData,
@@ -3254,13 +3291,20 @@ function useAreaChecklistController() {
3254
3291
  completeAreaChecklistUnits: _completeAreaChecklistUnits
3255
3292
  } = useAreaChecklistService();
3256
3293
  async function createAreaChecklist(req, res, next) {
3294
+ const cookies = req.headers.cookie ? req.headers.cookie.split(";").map((cookie) => cookie.trim().split("=")).reduce(
3295
+ (acc, [key, value2]) => ({ ...acc, [key]: value2 }),
3296
+ {}
3297
+ ) : {};
3298
+ const createdBy = cookies["user"] || "";
3257
3299
  const payload = {
3258
3300
  site: req.params.site,
3259
- schedule: req.params.schedule
3301
+ schedule: req.params.schedule,
3302
+ createdBy
3260
3303
  };
3261
3304
  const validation = Joi9.object({
3262
3305
  site: Joi9.string().hex().required(),
3263
- schedule: Joi9.string().hex().required()
3306
+ schedule: Joi9.string().hex().required(),
3307
+ createdBy: Joi9.string().hex().required()
3264
3308
  });
3265
3309
  const { error, value } = validation.validate(payload);
3266
3310
  if (error) {
@@ -4069,10 +4113,15 @@ import {
4069
4113
  function useStockService() {
4070
4114
  const { createStock: _createStock } = useStockRepository();
4071
4115
  const { getSupplyById, updateSupply } = useSupplyRepository();
4072
- async function createStock(value, out = false) {
4073
- const session = useAtlas10.getClient()?.startSession();
4116
+ async function createStock(value, out = false, session) {
4117
+ let ownSession = false;
4118
+ if (!session) {
4119
+ session = useAtlas10.getClient()?.startSession();
4120
+ ownSession = true;
4121
+ }
4074
4122
  try {
4075
- session?.startTransaction();
4123
+ if (ownSession)
4124
+ session?.startTransaction();
4076
4125
  const { qty, ...stockData } = value;
4077
4126
  const supply = await getSupplyById(value.supply, session);
4078
4127
  if (!supply || supply.qty === void 0) {
@@ -4094,13 +4143,16 @@ function useStockService() {
4094
4143
  },
4095
4144
  session
4096
4145
  );
4097
- await session?.commitTransaction();
4146
+ if (ownSession)
4147
+ await session?.commitTransaction();
4098
4148
  return createdStock;
4099
4149
  } catch (error) {
4100
- await session?.abortTransaction();
4150
+ if (ownSession)
4151
+ await session?.abortTransaction();
4101
4152
  throw error;
4102
4153
  } finally {
4103
- await session?.endSession();
4154
+ if (ownSession)
4155
+ await session?.endSession();
4104
4156
  }
4105
4157
  }
4106
4158
  return { createStock };
@@ -4789,28 +4841,24 @@ function useRequestItemController() {
4789
4841
  };
4790
4842
  }
4791
4843
 
4792
- // src/models/hygiene-schedule-task.model.ts
4793
- import { BadRequestError as BadRequestError28, logger as logger27 } from "@7365admin1/node-server-utils";
4844
+ // src/models/hygiene-checkout-item.model.ts
4794
4845
  import Joi16 from "joi";
4795
4846
  import { ObjectId as ObjectId16 } from "mongodb";
4796
- var scheduleTaskSchema = Joi16.object({
4847
+ import { BadRequestError as BadRequestError28, logger as logger27 } from "@7365admin1/node-server-utils";
4848
+ var allowedCheckOutItemStatus = ["pending", "completed"];
4849
+ var checkOutItemSchema = Joi16.object({
4797
4850
  site: Joi16.string().hex().required(),
4798
- title: Joi16.string().required(),
4799
- time: Joi16.string().pattern(/^([0-1]\d|2[0-3]):([0-5]\d)$/).required(),
4800
- startDate: Joi16.string().pattern(/^\d{4}-\d{2}-\d{2}$/).required(),
4801
- endDate: Joi16.string().pattern(/^\d{4}-\d{2}-\d{2}$/).optional().allow("", null),
4802
- description: Joi16.string().optional().allow("", null),
4803
- areas: Joi16.array().min(1).items(
4804
- Joi16.object({
4805
- name: Joi16.string().required(),
4806
- value: Joi16.any().required()
4807
- })
4808
- ).required()
4851
+ supply: Joi16.string().hex().required(),
4852
+ supplyName: Joi16.string().required(),
4853
+ qty: Joi16.number().min(0).required(),
4854
+ attachment: Joi16.string().optional().allow("", null),
4855
+ createdBy: Joi16.string().hex().required(),
4856
+ createdByName: Joi16.string().required()
4809
4857
  });
4810
- function MScheduleTask(value) {
4811
- const { error } = scheduleTaskSchema.validate(value);
4858
+ function MCheckOutItem(value) {
4859
+ const { error } = checkOutItemSchema.validate(value);
4812
4860
  if (error) {
4813
- logger27.info(`Hygiene Schedule Task Model: ${error.message}`);
4861
+ logger27.info(`Hygiene Check Out Item Model: ${error.message}`);
4814
4862
  throw new BadRequestError28(error.message);
4815
4863
  }
4816
4864
  if (value.site) {
@@ -4820,18 +4868,557 @@ function MScheduleTask(value) {
4820
4868
  throw new BadRequestError28("Invalid site ID format.");
4821
4869
  }
4822
4870
  }
4871
+ if (value.supply) {
4872
+ try {
4873
+ value.supply = new ObjectId16(value.supply);
4874
+ } catch (error2) {
4875
+ throw new BadRequestError28("Invalid supply ID format.");
4876
+ }
4877
+ }
4878
+ return {
4879
+ site: value.site,
4880
+ supply: value.supply,
4881
+ supplyName: value.supplyName,
4882
+ qty: value.qty,
4883
+ attachment: "",
4884
+ createdBy: value.createdBy,
4885
+ createdByName: value.createdByName,
4886
+ status: "pending",
4887
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
4888
+ updatedAt: "",
4889
+ deletedAt: ""
4890
+ };
4891
+ }
4892
+
4893
+ // src/repositories/hygiene-checkout-item.repository.ts
4894
+ import { ObjectId as ObjectId17 } from "mongodb";
4895
+ import {
4896
+ useAtlas as useAtlas13,
4897
+ InternalServerError as InternalServerError9,
4898
+ useCache as useCache9,
4899
+ logger as logger28,
4900
+ makeCacheKey as makeCacheKey9,
4901
+ paginate as paginate8,
4902
+ BadRequestError as BadRequestError29,
4903
+ NotFoundError as NotFoundError7
4904
+ } from "@7365admin1/node-server-utils";
4905
+ function useCheckOutItemRepository() {
4906
+ const db = useAtlas13.getDb();
4907
+ if (!db) {
4908
+ throw new InternalServerError9("Unable to connect to server.");
4909
+ }
4910
+ const namespace_collection = "site.supply.checkouts";
4911
+ const collection = db.collection(namespace_collection);
4912
+ const { delNamespace, setCache, getCache } = useCache9(namespace_collection);
4913
+ async function createIndex() {
4914
+ try {
4915
+ await collection.createIndexes([
4916
+ { key: { site: 1 } },
4917
+ { key: { supply: 1 } },
4918
+ { key: { status: 1 } }
4919
+ ]);
4920
+ } catch (error) {
4921
+ throw new InternalServerError9(
4922
+ "Failed to create index on hygiene check out item."
4923
+ );
4924
+ }
4925
+ }
4926
+ async function createTextIndex() {
4927
+ try {
4928
+ await collection.createIndex({ supplyName: "text" });
4929
+ } catch (error) {
4930
+ throw new InternalServerError9(
4931
+ "Failed to create text index on hygiene supply."
4932
+ );
4933
+ }
4934
+ }
4935
+ async function createCheckOutItem(value, session) {
4936
+ try {
4937
+ value = MCheckOutItem(value);
4938
+ const res = await collection.insertOne(value, { session });
4939
+ delNamespace().then(() => {
4940
+ logger28.info(`Cache cleared for namespace: ${namespace_collection}`);
4941
+ }).catch((err) => {
4942
+ logger28.error(
4943
+ `Failed to clear cache for namespace: ${namespace_collection}`,
4944
+ err
4945
+ );
4946
+ });
4947
+ return res.insertedId;
4948
+ } catch (error) {
4949
+ throw error;
4950
+ }
4951
+ }
4952
+ async function getCheckOutItems({
4953
+ page = 1,
4954
+ limit = 10,
4955
+ search = "",
4956
+ site
4957
+ }) {
4958
+ page = page > 0 ? page - 1 : 0;
4959
+ const query = {
4960
+ status: { $ne: "deleted" }
4961
+ };
4962
+ const cacheOptions = {
4963
+ page,
4964
+ limit
4965
+ };
4966
+ try {
4967
+ site = new ObjectId17(site);
4968
+ query.site = site;
4969
+ cacheOptions.site = site.toString();
4970
+ } catch (error) {
4971
+ throw new BadRequestError29("Invalid site ID format.");
4972
+ }
4973
+ if (search) {
4974
+ query.$text = { $search: search };
4975
+ cacheOptions.search = search;
4976
+ }
4977
+ const cacheKey = makeCacheKey9(namespace_collection, cacheOptions);
4978
+ const cachedData = await getCache(cacheKey);
4979
+ if (cachedData) {
4980
+ logger28.info(`Cache hit for key: ${cacheKey}`);
4981
+ return cachedData;
4982
+ }
4983
+ try {
4984
+ const items = await collection.aggregate([
4985
+ { $match: query },
4986
+ {
4987
+ $lookup: {
4988
+ from: "site.supplies",
4989
+ let: { supplyId: "$supply" },
4990
+ pipeline: [
4991
+ {
4992
+ $match: {
4993
+ $expr: {
4994
+ $and: [
4995
+ { $ne: ["$$supplyId", ""] },
4996
+ { $eq: ["$_id", "$$supplyId"] }
4997
+ ]
4998
+ }
4999
+ }
5000
+ },
5001
+ { $project: { qty: 1 } }
5002
+ ],
5003
+ as: "supplyDoc"
5004
+ }
5005
+ },
5006
+ {
5007
+ $unwind: {
5008
+ path: "$supplyDoc",
5009
+ preserveNullAndEmptyArrays: true
5010
+ }
5011
+ },
5012
+ {
5013
+ $lookup: {
5014
+ from: "users",
5015
+ let: { createdById: "$createdBy" },
5016
+ pipeline: [
5017
+ {
5018
+ $match: {
5019
+ $expr: {
5020
+ $and: [
5021
+ { $ne: ["$$createdById", ""] },
5022
+ { $eq: ["$_id", "$$createdById"] }
5023
+ ]
5024
+ }
5025
+ }
5026
+ },
5027
+ { $project: { name: 1 } }
5028
+ ],
5029
+ as: "createdByDoc"
5030
+ }
5031
+ },
5032
+ {
5033
+ $unwind: {
5034
+ path: "$createdByDoc",
5035
+ preserveNullAndEmptyArrays: true
5036
+ }
5037
+ },
5038
+ {
5039
+ $project: {
5040
+ supplyName: 1,
5041
+ supplyQty: "$supplyDoc.qty",
5042
+ checkOutByName: "$createdByDoc.name",
5043
+ checkOutQty: "$qty",
5044
+ createdAt: 1,
5045
+ status: 1
5046
+ }
5047
+ },
5048
+ { $sort: { _id: -1 } },
5049
+ { $skip: page * limit },
5050
+ { $limit: limit }
5051
+ ]).toArray();
5052
+ const length = await collection.countDocuments(query);
5053
+ const data = paginate8(items, page, limit, length);
5054
+ setCache(cacheKey, data, 15 * 60).then(() => {
5055
+ logger28.info(`Cache set for key: ${cacheKey}`);
5056
+ }).catch((err) => {
5057
+ logger28.error(`Failed to set cache for key: ${cacheKey}`, err);
5058
+ });
5059
+ return data;
5060
+ } catch (error) {
5061
+ throw error;
5062
+ }
5063
+ }
5064
+ async function getCheckOutItemById(_id, session) {
5065
+ try {
5066
+ _id = new ObjectId17(_id);
5067
+ } catch (error) {
5068
+ throw new BadRequestError29("Invalid check out item ID format.");
5069
+ }
5070
+ const query = { _id };
5071
+ const cacheKey = makeCacheKey9(namespace_collection, {
5072
+ _id: _id.toString()
5073
+ });
5074
+ if (!session) {
5075
+ const cachedData = await getCache(cacheKey);
5076
+ if (cachedData) {
5077
+ logger28.info(`Cache hit for key: ${cacheKey}`);
5078
+ return cachedData;
5079
+ }
5080
+ } else {
5081
+ logger28.info(`Skipping cache during transaction for key: ${cacheKey}`);
5082
+ }
5083
+ try {
5084
+ const data = await collection.aggregate([
5085
+ { $match: query },
5086
+ {
5087
+ $lookup: {
5088
+ from: "site.supply.items",
5089
+ localField: "supply",
5090
+ foreignField: "_id",
5091
+ as: "supplyDetails"
5092
+ }
5093
+ },
5094
+ {
5095
+ $unwind: {
5096
+ path: "$supplyDetails",
5097
+ preserveNullAndEmptyArrays: true
5098
+ }
5099
+ },
5100
+ {
5101
+ $project: {
5102
+ site: 1,
5103
+ supply: 1,
5104
+ supplyName: 1,
5105
+ qty: 1,
5106
+ status: 1,
5107
+ unitOfMeasurement: "$supplyDetails.unitOfMeasurement"
5108
+ }
5109
+ }
5110
+ ]).toArray();
5111
+ if (!data || data.length === 0) {
5112
+ throw new NotFoundError7("Check out item not found.");
5113
+ }
5114
+ setCache(cacheKey, data[0], 15 * 60).then(() => {
5115
+ logger28.info(`Cache set for key: ${cacheKey}`);
5116
+ }).catch((err) => {
5117
+ logger28.error(`Failed to set cache for key: ${cacheKey}`, err);
5118
+ });
5119
+ return data[0];
5120
+ } catch (error) {
5121
+ throw error;
5122
+ }
5123
+ }
5124
+ return {
5125
+ createIndex,
5126
+ createTextIndex,
5127
+ createCheckOutItem,
5128
+ getCheckOutItems,
5129
+ getCheckOutItemById
5130
+ };
5131
+ }
5132
+
5133
+ // src/services/hygiene-checkout-item.service.ts
5134
+ import { useUserRepo as useUserRepo2 } from "@7365admin1/core";
5135
+ import { BadRequestError as BadRequestError30, useAtlas as useAtlas14 } from "@7365admin1/node-server-utils";
5136
+ function useCheckOutItemService() {
5137
+ const {
5138
+ createCheckOutItem: _createCheckOutItem,
5139
+ getCheckOutItemById: _getCheckOutItemById
5140
+ } = useCheckOutItemRepository();
5141
+ const { getSupplyById } = useSupplyRepository();
5142
+ const { getUserById } = useUserRepo2();
5143
+ const { createStock } = useStockService();
5144
+ async function createCheckOutItem(value) {
5145
+ const session = useAtlas14.getClient()?.startSession();
5146
+ try {
5147
+ session?.startTransaction();
5148
+ const supplyData = await getSupplyById(value.supply);
5149
+ const createdByData = await getUserById(value.createdBy);
5150
+ const checkOutItemId = await _createCheckOutItem(
5151
+ {
5152
+ ...value,
5153
+ supplyName: supplyData?.name || "",
5154
+ createdByName: createdByData?.name || ""
5155
+ },
5156
+ session
5157
+ );
5158
+ const checkOutItem = await _getCheckOutItemById(checkOutItemId, session);
5159
+ if (!checkOutItem) {
5160
+ throw new BadRequestError30("Failed to create check out item.");
5161
+ }
5162
+ const createdStocks = await createStock(
5163
+ {
5164
+ site: checkOutItem.site.toString(),
5165
+ supply: checkOutItem.supply.toString(),
5166
+ qty: checkOutItem.qty
5167
+ },
5168
+ true,
5169
+ session
5170
+ );
5171
+ await session?.commitTransaction();
5172
+ return createdStocks;
5173
+ } catch (error) {
5174
+ await session?.abortTransaction();
5175
+ throw error;
5176
+ } finally {
5177
+ await session?.endSession();
5178
+ }
5179
+ }
5180
+ async function createCheckOutItemByBatch(value) {
5181
+ const session = useAtlas14.getClient()?.startSession();
5182
+ try {
5183
+ session?.startTransaction();
5184
+ const { site, createdBy, items } = value;
5185
+ const createdByData = await getUserById(createdBy);
5186
+ const createdCheckOutItemIds = [];
5187
+ for (const item of items) {
5188
+ const supplyData = await getSupplyById(item.supply, session);
5189
+ const createdId = await _createCheckOutItem(
5190
+ {
5191
+ site,
5192
+ supply: item.supply,
5193
+ supplyName: supplyData?.name || "",
5194
+ qty: item.qty,
5195
+ attachment: item.attachment || "",
5196
+ createdBy,
5197
+ createdByName: createdByData?.name || ""
5198
+ },
5199
+ session
5200
+ );
5201
+ await createStock(
5202
+ {
5203
+ site,
5204
+ supply: item.supply,
5205
+ qty: item.qty
5206
+ },
5207
+ true,
5208
+ session
5209
+ );
5210
+ createdCheckOutItemIds.push(createdId);
5211
+ }
5212
+ await session?.commitTransaction();
5213
+ return createdCheckOutItemIds;
5214
+ } catch (error) {
5215
+ await session?.abortTransaction();
5216
+ throw error;
5217
+ } finally {
5218
+ await session?.endSession();
5219
+ }
5220
+ }
5221
+ return {
5222
+ createCheckOutItem,
5223
+ createCheckOutItemByBatch
5224
+ };
5225
+ }
5226
+
5227
+ // src/controllers/hygiene-checkout-item.controller.ts
5228
+ import Joi17 from "joi";
5229
+ import { BadRequestError as BadRequestError31, logger as logger29 } from "@7365admin1/node-server-utils";
5230
+ function useCheckOutItemController() {
5231
+ const {
5232
+ getCheckOutItems: _getCheckOutItems,
5233
+ getCheckOutItemById: _getCheckOutItemById
5234
+ } = useCheckOutItemRepository();
5235
+ const {
5236
+ createCheckOutItem: _createCheckOutItem,
5237
+ createCheckOutItemByBatch: _createCheckOutItemByBatch
5238
+ } = useCheckOutItemService();
5239
+ async function createCheckOutItem(req, res, next) {
5240
+ const cookies = req.headers.cookie ? req.headers.cookie.split(";").map((cookie) => cookie.trim().split("=")).reduce(
5241
+ (acc, [key, value]) => ({ ...acc, [key]: value }),
5242
+ {}
5243
+ ) : {};
5244
+ const createdBy = cookies["user"] || "";
5245
+ const payload = {
5246
+ ...req.body,
5247
+ ...req.params,
5248
+ createdBy
5249
+ };
5250
+ const validation = Joi17.object({
5251
+ site: Joi17.string().hex().required(),
5252
+ supply: Joi17.string().hex().required(),
5253
+ qty: Joi17.number().min(0).required(),
5254
+ attachment: Joi17.string().optional().allow("", null),
5255
+ createdBy: Joi17.string().hex().required()
5256
+ });
5257
+ const { error } = validation.validate(payload);
5258
+ if (error) {
5259
+ logger29.log({ level: "error", message: error.message });
5260
+ next(new BadRequestError31(error.message));
5261
+ return;
5262
+ }
5263
+ try {
5264
+ const id = await _createCheckOutItem(payload);
5265
+ res.status(201).json({ message: "Check out item created successfully.", id });
5266
+ return;
5267
+ } catch (error2) {
5268
+ logger29.log({ level: "error", message: error2.message });
5269
+ next(error2);
5270
+ return;
5271
+ }
5272
+ }
5273
+ async function createCheckOutItemByBatch(req, res, next) {
5274
+ const cookies = req.headers.cookie ? req.headers.cookie.split(";").map((cookie) => cookie.trim().split("=")).reduce(
5275
+ (acc, [key, value]) => ({ ...acc, [key]: value }),
5276
+ {}
5277
+ ) : {};
5278
+ const createdBy = cookies["user"] || "";
5279
+ const payload = {
5280
+ ...req.body,
5281
+ ...req.params,
5282
+ createdBy
5283
+ };
5284
+ const validation = Joi17.object({
5285
+ site: Joi17.string().hex().required(),
5286
+ createdBy: Joi17.string().hex().required(),
5287
+ items: Joi17.array().items(
5288
+ Joi17.object({
5289
+ supply: Joi17.string().hex().required(),
5290
+ qty: Joi17.number().min(0).required(),
5291
+ attachment: Joi17.string().optional().allow("", null)
5292
+ })
5293
+ ).min(1).required()
5294
+ });
5295
+ const { error } = validation.validate(payload);
5296
+ if (error) {
5297
+ logger29.log({ level: "error", message: error.message });
5298
+ next(new BadRequestError31(error.message));
5299
+ return;
5300
+ }
5301
+ try {
5302
+ await _createCheckOutItemByBatch(payload);
5303
+ res.status(201).json({ message: "Check out items created successfully." });
5304
+ return;
5305
+ } catch (error2) {
5306
+ logger29.log({ level: "error", message: error2.message });
5307
+ next(error2);
5308
+ return;
5309
+ }
5310
+ }
5311
+ async function getCheckOutItems(req, res, next) {
5312
+ const query = { ...req.query, ...req.params };
5313
+ const validation = Joi17.object({
5314
+ page: Joi17.number().min(1).optional().allow("", null),
5315
+ limit: Joi17.number().min(1).optional().allow("", null),
5316
+ search: Joi17.string().optional().allow("", null),
5317
+ site: Joi17.string().hex().required()
5318
+ });
5319
+ const { error } = validation.validate(query);
5320
+ if (error) {
5321
+ logger29.log({ level: "error", message: error.message });
5322
+ next(new BadRequestError31(error.message));
5323
+ return;
5324
+ }
5325
+ const page = parseInt(req.query.page) ?? 1;
5326
+ const limit = parseInt(req.query.limit) ?? 10;
5327
+ const search = req.query.search ?? "";
5328
+ const site = req.params.site ?? "";
5329
+ try {
5330
+ const data = await _getCheckOutItems({
5331
+ page,
5332
+ limit,
5333
+ search,
5334
+ site
5335
+ });
5336
+ res.json(data);
5337
+ return;
5338
+ } catch (error2) {
5339
+ logger29.log({ level: "error", message: error2.message });
5340
+ next(error2);
5341
+ return;
5342
+ }
5343
+ }
5344
+ async function getCheckOutItemById(req, res, next) {
5345
+ const validation = Joi17.string().hex().required();
5346
+ const _id = req.params.id;
5347
+ const { error, value } = validation.validate(_id);
5348
+ if (error) {
5349
+ logger29.log({ level: "error", message: error.message });
5350
+ next(new BadRequestError31(error.message));
5351
+ return;
5352
+ }
5353
+ try {
5354
+ const data = await _getCheckOutItemById(value);
5355
+ res.json(data);
5356
+ return;
5357
+ } catch (error2) {
5358
+ logger29.log({ level: "error", message: error2.message });
5359
+ next(error2);
5360
+ return;
5361
+ }
5362
+ }
5363
+ return {
5364
+ createCheckOutItem,
5365
+ createCheckOutItemByBatch,
5366
+ getCheckOutItems,
5367
+ getCheckOutItemById
5368
+ };
5369
+ }
5370
+
5371
+ // src/models/hygiene-schedule-task.model.ts
5372
+ import { BadRequestError as BadRequestError32, logger as logger30 } from "@7365admin1/node-server-utils";
5373
+ import Joi18 from "joi";
5374
+ import { ObjectId as ObjectId18 } from "mongodb";
5375
+ var scheduleTaskSchema = Joi18.object({
5376
+ site: Joi18.string().hex().required(),
5377
+ title: Joi18.string().required(),
5378
+ time: Joi18.string().pattern(/^([0-1]\d|2[0-3]):([0-5]\d)$/).required(),
5379
+ startDate: Joi18.string().pattern(/^\d{4}-\d{2}-\d{2}$/).required(),
5380
+ endDate: Joi18.string().pattern(/^\d{4}-\d{2}-\d{2}$/).optional().allow("", null),
5381
+ description: Joi18.string().optional().allow("", null),
5382
+ areas: Joi18.array().min(1).items(
5383
+ Joi18.object({
5384
+ name: Joi18.string().required(),
5385
+ value: Joi18.any().required()
5386
+ })
5387
+ ).required(),
5388
+ createdBy: Joi18.string().hex().required()
5389
+ });
5390
+ function MScheduleTask(value) {
5391
+ const { error } = scheduleTaskSchema.validate(value);
5392
+ if (error) {
5393
+ logger30.info(`Hygiene Schedule Task Model: ${error.message}`);
5394
+ throw new BadRequestError32(error.message);
5395
+ }
5396
+ if (value.site) {
5397
+ try {
5398
+ value.site = new ObjectId18(value.site);
5399
+ } catch (error2) {
5400
+ throw new BadRequestError32("Invalid site ID format.");
5401
+ }
5402
+ }
4823
5403
  if (value.areas && Array.isArray(value.areas)) {
4824
5404
  value.areas = value.areas.map((area) => {
4825
5405
  try {
4826
5406
  return {
4827
5407
  name: area.name,
4828
- value: new ObjectId16(area.value.toString())
5408
+ value: new ObjectId18(area.value.toString())
4829
5409
  };
4830
5410
  } catch (error2) {
4831
- throw new BadRequestError28(`Invalid area value format: ${area.name}`);
5411
+ throw new BadRequestError32(`Invalid area value format: ${area.name}`);
4832
5412
  }
4833
5413
  });
4834
5414
  }
5415
+ if (value.createdBy) {
5416
+ try {
5417
+ value.createdBy = new ObjectId18(value.createdBy);
5418
+ } catch (error2) {
5419
+ throw new BadRequestError32("Invalid createdBy ID format.");
5420
+ }
5421
+ }
4835
5422
  return {
4836
5423
  site: value.site,
4837
5424
  title: value.title,
@@ -4841,6 +5428,7 @@ function MScheduleTask(value) {
4841
5428
  description: value.description,
4842
5429
  areas: value.areas,
4843
5430
  status: "active",
5431
+ createdBy: value.createdBy,
4844
5432
  createdAt: /* @__PURE__ */ new Date(),
4845
5433
  updatedAt: "",
4846
5434
  deletedAt: ""
@@ -4848,25 +5436,25 @@ function MScheduleTask(value) {
4848
5436
  }
4849
5437
 
4850
5438
  // src/repositories/hygiene-schedule-task.repository.ts
4851
- import { ObjectId as ObjectId17 } from "mongodb";
5439
+ import { ObjectId as ObjectId19 } from "mongodb";
4852
5440
  import {
4853
- useAtlas as useAtlas13,
4854
- InternalServerError as InternalServerError9,
4855
- paginate as paginate8,
4856
- BadRequestError as BadRequestError29,
4857
- useCache as useCache9,
4858
- logger as logger28,
4859
- makeCacheKey as makeCacheKey9,
4860
- NotFoundError as NotFoundError7
5441
+ useAtlas as useAtlas15,
5442
+ InternalServerError as InternalServerError10,
5443
+ paginate as paginate9,
5444
+ BadRequestError as BadRequestError33,
5445
+ useCache as useCache10,
5446
+ logger as logger31,
5447
+ makeCacheKey as makeCacheKey10,
5448
+ NotFoundError as NotFoundError8
4861
5449
  } from "@7365admin1/node-server-utils";
4862
5450
  function useScheduleTaskRepository() {
4863
- const db = useAtlas13.getDb();
5451
+ const db = useAtlas15.getDb();
4864
5452
  if (!db) {
4865
- throw new InternalServerError9("Unable to connect to server.");
5453
+ throw new InternalServerError10("Unable to connect to server.");
4866
5454
  }
4867
5455
  const namespace_collection = "site.schedule-tasks";
4868
5456
  const collection = db.collection(namespace_collection);
4869
- const { delNamespace, setCache, getCache } = useCache9(namespace_collection);
5457
+ const { delNamespace, setCache, getCache } = useCache10(namespace_collection);
4870
5458
  async function createIndex() {
4871
5459
  try {
4872
5460
  await collection.createIndexes([
@@ -4874,7 +5462,7 @@ function useScheduleTaskRepository() {
4874
5462
  { key: { status: 1 } }
4875
5463
  ]);
4876
5464
  } catch (error) {
4877
- throw new InternalServerError9(
5465
+ throw new InternalServerError10(
4878
5466
  "Failed to create index on hygiene schedule task."
4879
5467
  );
4880
5468
  }
@@ -4883,7 +5471,7 @@ function useScheduleTaskRepository() {
4883
5471
  try {
4884
5472
  await collection.createIndex({ title: "text", description: "text" });
4885
5473
  } catch (error) {
4886
- throw new InternalServerError9(
5474
+ throw new InternalServerError10(
4887
5475
  "Failed to create text index on hygiene schedule task."
4888
5476
  );
4889
5477
  }
@@ -4893,9 +5481,9 @@ function useScheduleTaskRepository() {
4893
5481
  value = MScheduleTask(value);
4894
5482
  const res = await collection.insertOne(value, { session });
4895
5483
  delNamespace().then(() => {
4896
- logger28.info(`Cache cleared for namespace: ${namespace_collection}`);
5484
+ logger31.info(`Cache cleared for namespace: ${namespace_collection}`);
4897
5485
  }).catch((err) => {
4898
- logger28.error(
5486
+ logger31.error(
4899
5487
  `Failed to clear cache for namespace: ${namespace_collection}`,
4900
5488
  err
4901
5489
  );
@@ -4920,20 +5508,20 @@ function useScheduleTaskRepository() {
4920
5508
  limit
4921
5509
  };
4922
5510
  try {
4923
- site = new ObjectId17(site);
5511
+ site = new ObjectId19(site);
4924
5512
  query.site = site;
4925
5513
  cacheOptions.site = site.toString();
4926
5514
  } catch (error) {
4927
- throw new BadRequestError29("Invalid site ID format.");
5515
+ throw new BadRequestError33("Invalid site ID format.");
4928
5516
  }
4929
5517
  if (search) {
4930
5518
  query.$or = [{ name: { $regex: search, $options: "i" } }];
4931
5519
  cacheOptions.search = search;
4932
5520
  }
4933
- const cacheKey = makeCacheKey9(namespace_collection, cacheOptions);
5521
+ const cacheKey = makeCacheKey10(namespace_collection, cacheOptions);
4934
5522
  const cachedData = await getCache(cacheKey);
4935
5523
  if (cachedData) {
4936
- logger28.info(`Cache hit for key: ${cacheKey}`);
5524
+ logger31.info(`Cache hit for key: ${cacheKey}`);
4937
5525
  return cachedData;
4938
5526
  }
4939
5527
  try {
@@ -4951,11 +5539,11 @@ function useScheduleTaskRepository() {
4951
5539
  { $limit: limit }
4952
5540
  ]).toArray();
4953
5541
  const length = await collection.countDocuments(query);
4954
- const data = paginate8(items, page, limit, length);
5542
+ const data = paginate9(items, page, limit, length);
4955
5543
  setCache(cacheKey, data, 15 * 60).then(() => {
4956
- logger28.info(`Cache set for key: ${cacheKey}`);
5544
+ logger31.info(`Cache set for key: ${cacheKey}`);
4957
5545
  }).catch((err) => {
4958
- logger28.error(`Failed to set cache for key: ${cacheKey}`, err);
5546
+ logger31.error(`Failed to set cache for key: ${cacheKey}`, err);
4959
5547
  });
4960
5548
  return data;
4961
5549
  } catch (error) {
@@ -4988,20 +5576,20 @@ function useScheduleTaskRepository() {
4988
5576
  limit
4989
5577
  };
4990
5578
  try {
4991
- site = new ObjectId17(site);
5579
+ site = new ObjectId19(site);
4992
5580
  query.site = site;
4993
5581
  cacheOptions.site = site.toString();
4994
5582
  } catch (error) {
4995
- throw new BadRequestError29("Invalid site ID format.");
5583
+ throw new BadRequestError33("Invalid site ID format.");
4996
5584
  }
4997
5585
  if (search) {
4998
5586
  query.$or = [{ name: { $regex: search, $options: "i" } }];
4999
5587
  cacheOptions.search = search;
5000
5588
  }
5001
- const cacheKey = makeCacheKey9(namespace_collection, cacheOptions);
5589
+ const cacheKey = makeCacheKey10(namespace_collection, cacheOptions);
5002
5590
  const cachedData = await getCache(cacheKey);
5003
5591
  if (cachedData) {
5004
- logger28.info(`Cache hit for key: ${cacheKey}`);
5592
+ logger31.info(`Cache hit for key: ${cacheKey}`);
5005
5593
  return cachedData;
5006
5594
  }
5007
5595
  try {
@@ -5018,11 +5606,11 @@ function useScheduleTaskRepository() {
5018
5606
  { $limit: limit }
5019
5607
  ]).toArray();
5020
5608
  const length = await collection.countDocuments(query);
5021
- const data = paginate8(items, page, limit, length);
5609
+ const data = paginate9(items, page, limit, length);
5022
5610
  setCache(cacheKey, data, 15 * 60).then(() => {
5023
- logger28.info(`Cache set for key: ${cacheKey}`);
5611
+ logger31.info(`Cache set for key: ${cacheKey}`);
5024
5612
  }).catch((err) => {
5025
- logger28.error(`Failed to set cache for key: ${cacheKey}`, err);
5613
+ logger31.error(`Failed to set cache for key: ${cacheKey}`, err);
5026
5614
  });
5027
5615
  return data;
5028
5616
  } catch (error) {
@@ -5031,25 +5619,25 @@ function useScheduleTaskRepository() {
5031
5619
  }
5032
5620
  async function getScheduleTaskById(_id, session) {
5033
5621
  try {
5034
- _id = new ObjectId17(_id);
5622
+ _id = new ObjectId19(_id);
5035
5623
  } catch (error) {
5036
- throw new BadRequestError29("Invalid schedule task ID format.");
5624
+ throw new BadRequestError33("Invalid schedule task ID format.");
5037
5625
  }
5038
5626
  const query = {
5039
5627
  _id,
5040
5628
  status: { $ne: "deleted" }
5041
5629
  };
5042
- const cacheKey = makeCacheKey9(namespace_collection, {
5630
+ const cacheKey = makeCacheKey10(namespace_collection, {
5043
5631
  _id: _id.toString()
5044
5632
  });
5045
5633
  if (!session) {
5046
5634
  const cachedData = await getCache(cacheKey);
5047
5635
  if (cachedData) {
5048
- logger28.info(`Cache hit for key: ${cacheKey}`);
5636
+ logger31.info(`Cache hit for key: ${cacheKey}`);
5049
5637
  return cachedData;
5050
5638
  }
5051
5639
  } else {
5052
- logger28.info(`Skipping cache during transaction for key: ${cacheKey}`);
5640
+ logger31.info(`Skipping cache during transaction for key: ${cacheKey}`);
5053
5641
  }
5054
5642
  try {
5055
5643
  const data = await collection.aggregate([
@@ -5068,12 +5656,12 @@ function useScheduleTaskRepository() {
5068
5656
  }
5069
5657
  ]).toArray();
5070
5658
  if (!data || data.length === 0) {
5071
- throw new NotFoundError7("Schedule task not found.");
5659
+ throw new NotFoundError8("Schedule task not found.");
5072
5660
  }
5073
5661
  setCache(cacheKey, data[0], 15 * 60).then(() => {
5074
- logger28.info(`Cache set for key: ${cacheKey}`);
5662
+ logger31.info(`Cache set for key: ${cacheKey}`);
5075
5663
  }).catch((err) => {
5076
- logger28.error(`Failed to set cache for key: ${cacheKey}`, err);
5664
+ logger31.error(`Failed to set cache for key: ${cacheKey}`, err);
5077
5665
  });
5078
5666
  return data[0];
5079
5667
  } catch (error) {
@@ -5082,19 +5670,19 @@ function useScheduleTaskRepository() {
5082
5670
  }
5083
5671
  async function updateScheduleTask(_id, value, session) {
5084
5672
  try {
5085
- _id = new ObjectId17(_id);
5673
+ _id = new ObjectId19(_id);
5086
5674
  } catch (error) {
5087
- throw new BadRequestError29("Invalid schedule task ID format.");
5675
+ throw new BadRequestError33("Invalid schedule task ID format.");
5088
5676
  }
5089
5677
  if (value.areas && Array.isArray(value.areas)) {
5090
5678
  value.areas = value.areas.map((area) => {
5091
5679
  try {
5092
5680
  return {
5093
5681
  name: area.name,
5094
- value: new ObjectId17(area.value.toString())
5682
+ value: new ObjectId19(area.value.toString())
5095
5683
  };
5096
5684
  } catch (error) {
5097
- throw new BadRequestError29(`Invalid area value format: ${area.name}`);
5685
+ throw new BadRequestError33(`Invalid area value format: ${area.name}`);
5098
5686
  }
5099
5687
  });
5100
5688
  }
@@ -5106,14 +5694,14 @@ function useScheduleTaskRepository() {
5106
5694
  { session }
5107
5695
  );
5108
5696
  if (res.modifiedCount === 0) {
5109
- throw new InternalServerError9(
5697
+ throw new InternalServerError10(
5110
5698
  "Unable to update hygiene schedule task."
5111
5699
  );
5112
5700
  }
5113
5701
  delNamespace().then(() => {
5114
- logger28.info(`Cache cleared for namespace: ${namespace_collection}`);
5702
+ logger31.info(`Cache cleared for namespace: ${namespace_collection}`);
5115
5703
  }).catch((err) => {
5116
- logger28.error(
5704
+ logger31.error(
5117
5705
  `Failed to clear cache for namespace: ${namespace_collection}`,
5118
5706
  err
5119
5707
  );
@@ -5136,10 +5724,10 @@ function useScheduleTaskRepository() {
5136
5724
  }
5137
5725
 
5138
5726
  // src/services/hygiene-schedule-task.service.ts
5139
- import { logger as logger29 } from "@7365admin1/node-server-utils";
5727
+ import { logger as logger32 } from "@7365admin1/node-server-utils";
5140
5728
  function useScheduleTaskService() {
5141
5729
  const { createParentChecklist } = useParentChecklistRepo();
5142
- const { getAllScheduleTask, getScheduleTaskById } = useScheduleTaskRepository();
5730
+ const { getAllScheduleTask } = useScheduleTaskRepository();
5143
5731
  const {
5144
5732
  createAreaChecklist,
5145
5733
  getAreaChecklistByAreaAndSchedule,
@@ -5159,13 +5747,13 @@ function useScheduleTaskService() {
5159
5747
  const currentDateString = now.toLocaleDateString("en-US", {
5160
5748
  timeZone: "Asia/Singapore"
5161
5749
  });
5162
- logger29.info(
5750
+ logger32.info(
5163
5751
  `Checking schedule ${schedule._id}: Current time ${currentHour}:${currentMinute}, Current date ${currentDateString}, Schedule time ${schedule.time}, Start date ${schedule.startDate}, End date ${schedule.endDate}`
5164
5752
  );
5165
5753
  const startDate = /* @__PURE__ */ new Date(schedule.startDate + "T00:00:00");
5166
5754
  const currentDateOnly = /* @__PURE__ */ new Date(currentDateString + "T00:00:00");
5167
5755
  if (currentDateOnly < startDate) {
5168
- logger29.info(
5756
+ logger32.info(
5169
5757
  `Schedule ${schedule._id}: Current date ${currentDateString} is before start date ${schedule.startDate}`
5170
5758
  );
5171
5759
  return false;
@@ -5173,7 +5761,7 @@ function useScheduleTaskService() {
5173
5761
  if (schedule.endDate) {
5174
5762
  const endDate = /* @__PURE__ */ new Date(schedule.endDate + "T00:00:00");
5175
5763
  if (currentDateOnly > endDate) {
5176
- logger29.info(
5764
+ logger32.info(
5177
5765
  `Schedule ${schedule._id}: Current date ${currentDateString} is after end date ${schedule.endDate}`
5178
5766
  );
5179
5767
  return false;
@@ -5182,17 +5770,17 @@ function useScheduleTaskService() {
5182
5770
  const [scheduleHour, scheduleMinute] = schedule.time.split(":").map(Number);
5183
5771
  const timeMatches = currentHour === scheduleHour && currentMinute === scheduleMinute;
5184
5772
  if (!timeMatches) {
5185
- logger29.info(
5773
+ logger32.info(
5186
5774
  `Schedule ${schedule._id}: Time does not match. Current: ${currentHour}:${currentMinute}, Expected: ${scheduleHour}:${scheduleMinute}`
5187
5775
  );
5188
5776
  return false;
5189
5777
  }
5190
- logger29.info(
5778
+ logger32.info(
5191
5779
  `Schedule ${schedule._id}: All conditions matched - Date is within range and time matches`
5192
5780
  );
5193
5781
  return true;
5194
5782
  } catch (error) {
5195
- logger29.error(
5783
+ logger32.error(
5196
5784
  `Error checking schedule conditions for ${schedule._id}:`,
5197
5785
  error
5198
5786
  );
@@ -5201,40 +5789,40 @@ function useScheduleTaskService() {
5201
5789
  }
5202
5790
  async function processScheduledTasks(currentDate) {
5203
5791
  try {
5204
- logger29.info("Starting scheduled task processing...");
5792
+ logger32.info("Starting scheduled task processing...");
5205
5793
  const scheduleTasks = await getAllScheduleTask();
5206
5794
  if (!scheduleTasks || scheduleTasks.length === 0) {
5207
- logger29.info("No schedule tasks found to process");
5795
+ logger32.info("No schedule tasks found to process");
5208
5796
  return { processed: 0, validated: 0 };
5209
5797
  }
5210
- logger29.info(`Found ${scheduleTasks.length} schedule tasks to check`);
5798
+ logger32.info(`Found ${scheduleTasks.length} schedule tasks to check`);
5211
5799
  let processedCount = 0;
5212
5800
  let validatedCount = 0;
5213
5801
  const validatedTasks = [];
5214
5802
  for (const scheduleTask of scheduleTasks) {
5215
5803
  try {
5216
- logger29.info(
5804
+ logger32.info(
5217
5805
  `Checking schedule ${scheduleTask._id} - ${scheduleTask.title}: time=${scheduleTask.time}, startDate=${scheduleTask.startDate}, endDate=${scheduleTask.endDate}`
5218
5806
  );
5219
5807
  const shouldRun = checkScheduleConditions(scheduleTask, currentDate);
5220
5808
  if (!shouldRun) {
5221
- logger29.info(
5809
+ logger32.info(
5222
5810
  `Schedule ${scheduleTask._id} conditions not met, skipping`
5223
5811
  );
5224
5812
  continue;
5225
5813
  }
5226
- logger29.info(
5814
+ logger32.info(
5227
5815
  `Schedule ${scheduleTask._id} conditions validated, creating area checklists`
5228
5816
  );
5229
5817
  if (!scheduleTask._id) {
5230
- logger29.warn(`Schedule ${scheduleTask.title} has no _id, skipping`);
5818
+ logger32.warn(`Schedule ${scheduleTask.title} has no _id, skipping`);
5231
5819
  continue;
5232
5820
  }
5233
5821
  if (!scheduleTask.site) {
5234
- logger29.warn(`Schedule ${scheduleTask._id} has no site, skipping`);
5822
+ logger32.warn(`Schedule ${scheduleTask._id} has no site, skipping`);
5235
5823
  continue;
5236
5824
  }
5237
- logger29.info(
5825
+ logger32.info(
5238
5826
  `Getting or creating parent checklist for schedule ${scheduleTask._id} in site ${scheduleTask.site}`
5239
5827
  );
5240
5828
  const parentChecklistIds = await createParentChecklist({
@@ -5242,7 +5830,7 @@ function useScheduleTaskService() {
5242
5830
  createdAt: /* @__PURE__ */ new Date()
5243
5831
  });
5244
5832
  const parentChecklistId = Array.isArray(parentChecklistIds) ? parentChecklistIds[0] : parentChecklistIds;
5245
- logger29.info(
5833
+ logger32.info(
5246
5834
  `Using parent checklist ${parentChecklistId}, now creating/updating area checklists`
5247
5835
  );
5248
5836
  for (const area of scheduleTask.areas) {
@@ -5255,14 +5843,14 @@ function useScheduleTaskService() {
5255
5843
  unit: unit.unit.toString(),
5256
5844
  name: unit.name
5257
5845
  }));
5258
- logger29.info(
5846
+ logger32.info(
5259
5847
  `Area ${area.name} (${areaId}): Using units from area details: ${JSON.stringify(
5260
5848
  units
5261
5849
  )}`
5262
5850
  );
5263
5851
  }
5264
5852
  if (units.length === 0) {
5265
- logger29.warn(
5853
+ logger32.warn(
5266
5854
  `Area ${area.name} (${areaId}): No units found, skipping area.`
5267
5855
  );
5268
5856
  continue;
@@ -5273,11 +5861,11 @@ function useScheduleTaskService() {
5273
5861
  parentChecklistId.toString(),
5274
5862
  areaId
5275
5863
  );
5276
- logger29.info(
5864
+ logger32.info(
5277
5865
  `Area ${area.name} (${areaId}): Existing area checklist found: ${existingAreaChecklist ? "Yes" : "No"}`
5278
5866
  );
5279
5867
  if (existingAreaChecklist) {
5280
- logger29.info(
5868
+ logger32.info(
5281
5869
  `Area ${area.name} (${areaId}): Existing checklist content: ${JSON.stringify(
5282
5870
  existingAreaChecklist.checklist
5283
5871
  )}`
@@ -5285,7 +5873,7 @@ function useScheduleTaskService() {
5285
5873
  }
5286
5874
  } catch (error) {
5287
5875
  existingAreaChecklist = null;
5288
- logger29.info(
5876
+ logger32.info(
5289
5877
  `Area ${area.name} (${areaId}): No existing area checklist found (exception).`
5290
5878
  );
5291
5879
  }
@@ -5299,7 +5887,7 @@ function useScheduleTaskService() {
5299
5887
  ...existingAreaChecklist.checklist || [],
5300
5888
  newSet
5301
5889
  ];
5302
- logger29.info(
5890
+ logger32.info(
5303
5891
  `Area ${area.name} (${areaId}): Appending new set ${newSet.set} to checklist. Updated checklist: ${JSON.stringify(
5304
5892
  updatedChecklist
5305
5893
  )}`
@@ -5307,7 +5895,7 @@ function useScheduleTaskService() {
5307
5895
  await updateAreaChecklist(existingAreaChecklist._id, {
5308
5896
  checklist: updatedChecklist
5309
5897
  });
5310
- logger29.info(
5898
+ logger32.info(
5311
5899
  `Appended set ${newSet.set} to area checklist for area ${area.name}`
5312
5900
  );
5313
5901
  try {
@@ -5315,13 +5903,13 @@ function useScheduleTaskService() {
5315
5903
  parentChecklistId.toString(),
5316
5904
  areaId
5317
5905
  );
5318
- logger29.info(
5906
+ logger32.info(
5319
5907
  `Area ${area.name} (${areaId}): Checklist after update: ${JSON.stringify(
5320
5908
  verifyChecklist.checklist
5321
5909
  )}`
5322
5910
  );
5323
5911
  } catch (verifyError) {
5324
- logger29.warn(
5912
+ logger32.warn(
5325
5913
  `Area ${area.name} (${areaId}): Error verifying checklist after update:`,
5326
5914
  verifyError
5327
5915
  );
@@ -5337,52 +5925,53 @@ function useScheduleTaskService() {
5337
5925
  set: 1,
5338
5926
  units
5339
5927
  }
5340
- ]
5928
+ ],
5929
+ createdBy: scheduleTask.createdBy
5341
5930
  };
5342
- logger29.info(
5931
+ logger32.info(
5343
5932
  `Area ${area.name} (${areaId}): Creating new area checklist with data: ${JSON.stringify(
5344
5933
  checklistData
5345
5934
  )}`
5346
5935
  );
5347
5936
  await createAreaChecklist(checklistData);
5348
- logger29.info(`Created new area checklist for area ${area.name}`);
5937
+ logger32.info(`Created new area checklist for area ${area.name}`);
5349
5938
  try {
5350
5939
  const verifyChecklist = await getAreaChecklistByAreaAndSchedule(
5351
5940
  parentChecklistId.toString(),
5352
5941
  areaId
5353
5942
  );
5354
- logger29.info(
5943
+ logger32.info(
5355
5944
  `Area ${area.name} (${areaId}): Checklist after creation: ${JSON.stringify(
5356
5945
  verifyChecklist.checklist
5357
5946
  )}`
5358
5947
  );
5359
5948
  } catch (verifyError) {
5360
- logger29.warn(
5949
+ logger32.warn(
5361
5950
  `Area ${area.name} (${areaId}): Error verifying checklist after creation:`,
5362
5951
  verifyError
5363
5952
  );
5364
5953
  }
5365
5954
  }
5366
5955
  } catch (error) {
5367
- logger29.error(`Error processing area ${area.name}:`, error);
5956
+ logger32.error(`Error processing area ${area.name}:`, error);
5368
5957
  continue;
5369
5958
  }
5370
5959
  }
5371
5960
  processedCount++;
5372
5961
  validatedCount++;
5373
5962
  validatedTasks.push(scheduleTask);
5374
- logger29.info(
5963
+ logger32.info(
5375
5964
  `Successfully processed schedule ${scheduleTask._id}, created/updated area checklists for all areas.`
5376
5965
  );
5377
5966
  } catch (error) {
5378
- logger29.error(
5967
+ logger32.error(
5379
5968
  `Error processing schedule task ${scheduleTask._id}:`,
5380
5969
  error
5381
5970
  );
5382
5971
  continue;
5383
5972
  }
5384
5973
  }
5385
- logger29.info(
5974
+ logger32.info(
5386
5975
  `Scheduled task processing completed. Processed: ${processedCount}, Validated: ${validatedCount} tasks`
5387
5976
  );
5388
5977
  return {
@@ -5391,7 +5980,7 @@ function useScheduleTaskService() {
5391
5980
  tasks: validatedTasks
5392
5981
  };
5393
5982
  } catch (error) {
5394
- logger29.error("Error processing scheduled tasks:", error);
5983
+ logger32.error("Error processing scheduled tasks:", error);
5395
5984
  throw error;
5396
5985
  }
5397
5986
  }
@@ -5399,8 +5988,8 @@ function useScheduleTaskService() {
5399
5988
  }
5400
5989
 
5401
5990
  // src/controllers/hygiene-schedule-task.controller.ts
5402
- import Joi17 from "joi";
5403
- import { BadRequestError as BadRequestError30, logger as logger30 } from "@7365admin1/node-server-utils";
5991
+ import Joi19 from "joi";
5992
+ import { BadRequestError as BadRequestError34, logger as logger33 } from "@7365admin1/node-server-utils";
5404
5993
  function useScheduleTaskController() {
5405
5994
  const {
5406
5995
  createScheduleTask: _createScheduleTask,
@@ -5410,11 +5999,16 @@ function useScheduleTaskController() {
5410
5999
  updateScheduleTask: _updateScheduleTask
5411
6000
  } = useScheduleTaskRepository();
5412
6001
  async function createScheduleTask(req, res, next) {
5413
- const payload = { ...req.body, ...req.params };
6002
+ const cookies = req.headers.cookie ? req.headers.cookie.split(";").map((cookie) => cookie.trim().split("=")).reduce(
6003
+ (acc, [key, value]) => ({ ...acc, [key]: value }),
6004
+ {}
6005
+ ) : {};
6006
+ const createdBy = cookies["user"] || "";
6007
+ const payload = { ...req.body, ...req.params, createdBy };
5414
6008
  const { error } = scheduleTaskSchema.validate(payload);
5415
6009
  if (error) {
5416
- logger30.log({ level: "error", message: error.message });
5417
- next(new BadRequestError30(error.message));
6010
+ logger33.log({ level: "error", message: error.message });
6011
+ next(new BadRequestError34(error.message));
5418
6012
  return;
5419
6013
  }
5420
6014
  try {
@@ -5422,23 +6016,23 @@ function useScheduleTaskController() {
5422
6016
  res.status(201).json({ message: "Schedule task created successfully.", id });
5423
6017
  return;
5424
6018
  } catch (error2) {
5425
- logger30.log({ level: "error", message: error2.message });
6019
+ logger33.log({ level: "error", message: error2.message });
5426
6020
  next(error2);
5427
6021
  return;
5428
6022
  }
5429
6023
  }
5430
6024
  async function getScheduleTasks(req, res, next) {
5431
6025
  const query = { ...req.query, ...req.params };
5432
- const validation = Joi17.object({
5433
- page: Joi17.number().min(1).optional().allow("", null),
5434
- limit: Joi17.number().min(1).optional().allow("", null),
5435
- search: Joi17.string().optional().allow("", null),
5436
- site: Joi17.string().hex().required()
6026
+ const validation = Joi19.object({
6027
+ page: Joi19.number().min(1).optional().allow("", null),
6028
+ limit: Joi19.number().min(1).optional().allow("", null),
6029
+ search: Joi19.string().optional().allow("", null),
6030
+ site: Joi19.string().hex().required()
5437
6031
  });
5438
6032
  const { error } = validation.validate(query);
5439
6033
  if (error) {
5440
- logger30.log({ level: "error", message: error.message });
5441
- next(new BadRequestError30(error.message));
6034
+ logger33.log({ level: "error", message: error.message });
6035
+ next(new BadRequestError34(error.message));
5442
6036
  return;
5443
6037
  }
5444
6038
  const page = parseInt(req.query.page) ?? 1;
@@ -5455,23 +6049,23 @@ function useScheduleTaskController() {
5455
6049
  res.json(data);
5456
6050
  return;
5457
6051
  } catch (error2) {
5458
- logger30.log({ level: "error", message: error2.message });
6052
+ logger33.log({ level: "error", message: error2.message });
5459
6053
  next(error2);
5460
6054
  return;
5461
6055
  }
5462
6056
  }
5463
6057
  async function getTasksForScheduleTask(req, res, next) {
5464
6058
  const query = { ...req.query, ...req.params };
5465
- const validation = Joi17.object({
5466
- page: Joi17.number().min(1).optional().allow("", null),
5467
- limit: Joi17.number().min(1).optional().allow("", null),
5468
- search: Joi17.string().optional().allow("", null),
5469
- site: Joi17.string().hex().required()
6059
+ const validation = Joi19.object({
6060
+ page: Joi19.number().min(1).optional().allow("", null),
6061
+ limit: Joi19.number().min(1).optional().allow("", null),
6062
+ search: Joi19.string().optional().allow("", null),
6063
+ site: Joi19.string().hex().required()
5470
6064
  });
5471
6065
  const { error } = validation.validate(query);
5472
6066
  if (error) {
5473
- logger30.log({ level: "error", message: error.message });
5474
- next(new BadRequestError30(error.message));
6067
+ logger33.log({ level: "error", message: error.message });
6068
+ next(new BadRequestError34(error.message));
5475
6069
  return;
5476
6070
  }
5477
6071
  const page = parseInt(req.query.page) ?? 1;
@@ -5488,18 +6082,18 @@ function useScheduleTaskController() {
5488
6082
  res.json(data);
5489
6083
  return;
5490
6084
  } catch (error2) {
5491
- logger30.log({ level: "error", message: error2.message });
6085
+ logger33.log({ level: "error", message: error2.message });
5492
6086
  next(error2);
5493
6087
  return;
5494
6088
  }
5495
6089
  }
5496
6090
  async function getScheduleTaskById(req, res, next) {
5497
- const validation = Joi17.string().hex().required();
6091
+ const validation = Joi19.string().hex().required();
5498
6092
  const _id = req.params.id;
5499
6093
  const { error, value } = validation.validate(_id);
5500
6094
  if (error) {
5501
- logger30.log({ level: "error", message: error.message });
5502
- next(new BadRequestError30(error.message));
6095
+ logger33.log({ level: "error", message: error.message });
6096
+ next(new BadRequestError34(error.message));
5503
6097
  return;
5504
6098
  }
5505
6099
  try {
@@ -5507,31 +6101,31 @@ function useScheduleTaskController() {
5507
6101
  res.json(data);
5508
6102
  return;
5509
6103
  } catch (error2) {
5510
- logger30.log({ level: "error", message: error2.message });
6104
+ logger33.log({ level: "error", message: error2.message });
5511
6105
  next(error2);
5512
6106
  return;
5513
6107
  }
5514
6108
  }
5515
6109
  async function updateScheduleTask(req, res, next) {
5516
6110
  const payload = { id: req.params.id, ...req.body };
5517
- const validation = Joi17.object({
5518
- id: Joi17.string().hex().required(),
5519
- title: Joi17.string().optional().allow("", null),
5520
- time: Joi17.string().pattern(/^([0-1]\d|2[0-3]):([0-5]\d)$/).optional().allow("", null),
5521
- startDate: Joi17.string().pattern(/^\d{4}-\d{2}-\d{2}$/).optional().allow("", null),
5522
- endDate: Joi17.string().pattern(/^\d{4}-\d{2}-\d{2}$/).optional().allow("", null),
5523
- description: Joi17.string().optional().allow("", null),
5524
- areas: Joi17.array().min(1).items(
5525
- Joi17.object({
5526
- name: Joi17.string().required(),
5527
- value: Joi17.any().required()
6111
+ const validation = Joi19.object({
6112
+ id: Joi19.string().hex().required(),
6113
+ title: Joi19.string().optional().allow("", null),
6114
+ time: Joi19.string().pattern(/^([0-1]\d|2[0-3]):([0-5]\d)$/).optional().allow("", null),
6115
+ startDate: Joi19.string().pattern(/^\d{4}-\d{2}-\d{2}$/).optional().allow("", null),
6116
+ endDate: Joi19.string().pattern(/^\d{4}-\d{2}-\d{2}$/).optional().allow("", null),
6117
+ description: Joi19.string().optional().allow("", null),
6118
+ areas: Joi19.array().min(1).items(
6119
+ Joi19.object({
6120
+ name: Joi19.string().required(),
6121
+ value: Joi19.any().required()
5528
6122
  })
5529
6123
  ).optional()
5530
6124
  });
5531
6125
  const { error } = validation.validate(payload);
5532
6126
  if (error) {
5533
- logger30.log({ level: "error", message: error.message });
5534
- next(new BadRequestError30(error.message));
6127
+ logger33.log({ level: "error", message: error.message });
6128
+ next(new BadRequestError34(error.message));
5535
6129
  return;
5536
6130
  }
5537
6131
  try {
@@ -5540,7 +6134,7 @@ function useScheduleTaskController() {
5540
6134
  res.json({ message: "Schedule task updated successfully." });
5541
6135
  return;
5542
6136
  } catch (error2) {
5543
- logger30.log({ level: "error", message: error2.message });
6137
+ logger33.log({ level: "error", message: error2.message });
5544
6138
  next(error2);
5545
6139
  return;
5546
6140
  }
@@ -5556,12 +6150,14 @@ function useScheduleTaskController() {
5556
6150
  export {
5557
6151
  MArea,
5558
6152
  MAreaChecklist,
6153
+ MCheckOutItem,
5559
6154
  MParentChecklist,
5560
6155
  MRequestItem,
5561
6156
  MScheduleTask,
5562
6157
  MStock,
5563
6158
  MSupply,
5564
6159
  MUnit,
6160
+ allowedCheckOutItemStatus,
5565
6161
  allowedChecklistStatus,
5566
6162
  allowedPeriods,
5567
6163
  allowedRequestItemStatus,
@@ -5569,6 +6165,7 @@ export {
5569
6165
  allowedTypes,
5570
6166
  areaChecklistSchema,
5571
6167
  areaSchema,
6168
+ checkOutItemSchema,
5572
6169
  parentChecklistSchema,
5573
6170
  requestItemSchema,
5574
6171
  scheduleTaskSchema,
@@ -5581,6 +6178,9 @@ export {
5581
6178
  useAreaController,
5582
6179
  useAreaRepo,
5583
6180
  useAreaService,
6181
+ useCheckOutItemController,
6182
+ useCheckOutItemRepository,
6183
+ useCheckOutItemService,
5584
6184
  useHygieneDashboardController,
5585
6185
  useHygieneDashboardRepository,
5586
6186
  useParentChecklistController,