@iservice365/module-hygiene 1.0.3 → 1.3.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.js CHANGED
@@ -33,15 +33,25 @@ __export(src_exports, {
33
33
  MArea: () => MArea,
34
34
  MAreaChecklist: () => MAreaChecklist,
35
35
  MParentChecklist: () => MParentChecklist,
36
+ MRequestItem: () => MRequestItem,
37
+ MScheduleTask: () => MScheduleTask,
36
38
  MStock: () => MStock,
37
39
  MSupply: () => MSupply,
38
40
  MUnit: () => MUnit,
39
41
  allowedChecklistStatus: () => allowedChecklistStatus,
42
+ allowedDays: () => allowedDays,
43
+ allowedFrequency: () => allowedFrequency,
44
+ allowedMonths: () => allowedMonths,
45
+ allowedQuarter: () => allowedQuarter,
46
+ allowedRequestItemStatus: () => allowedRequestItemStatus,
40
47
  allowedStatus: () => allowedStatus,
41
48
  allowedTypes: () => allowedTypes,
49
+ allowedWeekOfMonth: () => allowedWeekOfMonth,
42
50
  areaChecklistSchema: () => areaChecklistSchema,
43
51
  areaSchema: () => areaSchema,
44
52
  parentChecklistSchema: () => parentChecklistSchema,
53
+ requestItemSchema: () => requestItemSchema,
54
+ scheduleTaskSchema: () => scheduleTaskSchema,
45
55
  stockSchema: () => stockSchema,
46
56
  supplySchema: () => supplySchema,
47
57
  unitSchema: () => unitSchema,
@@ -53,12 +63,16 @@ __export(src_exports, {
53
63
  useAreaService: () => useAreaService,
54
64
  useParentChecklistController: () => useParentChecklistController,
55
65
  useParentChecklistRepo: () => useParentChecklistRepo,
66
+ useRequestItemController: () => useRequestItemController,
67
+ useRequestItemRepository: () => useRequestItemRepository,
68
+ useRequestItemService: () => useRequestItemService,
69
+ useScheduleTaskController: () => useScheduleTaskController,
70
+ useScheduleTaskRepository: () => useScheduleTaskRepository,
56
71
  useStockController: () => useStockController,
57
72
  useStockRepository: () => useStockRepository,
58
73
  useStockService: () => useStockService,
59
74
  useSupplyController: () => useSupplyController,
60
75
  useSupplyRepository: () => useSupplyRepository,
61
- useSupplyService: () => useSupplyService,
62
76
  useUnitController: () => useUnitController,
63
77
  useUnitRepository: () => useUnitRepository,
64
78
  useUnitService: () => useUnitService
@@ -698,7 +712,7 @@ function useAreaController() {
698
712
  return;
699
713
  }
700
714
  const page = parseInt(req.query.page) ?? 1;
701
- const limit = parseInt(req.query.limit) ?? 20;
715
+ const limit = parseInt(req.query.limit) ?? 10;
702
716
  const search = req.query.search ?? "";
703
717
  const site = req.params.site ?? "";
704
718
  try {
@@ -844,8 +858,8 @@ function MUnit(value) {
844
858
  return {
845
859
  site: value.site,
846
860
  name: value.name,
847
- createdAt: /* @__PURE__ */ new Date(),
848
861
  status: "active",
862
+ createdAt: /* @__PURE__ */ new Date(),
849
863
  updatedAt: "",
850
864
  deletedAt: ""
851
865
  };
@@ -1234,7 +1248,7 @@ function useUnitController() {
1234
1248
  return;
1235
1249
  }
1236
1250
  const page = parseInt(req.query.page) ?? 1;
1237
- const limit = parseInt(req.query.limit) ?? 20;
1251
+ const limit = parseInt(req.query.limit) ?? 10;
1238
1252
  const search = req.query.search ?? "";
1239
1253
  const site = req.params.site ?? "";
1240
1254
  try {
@@ -1536,6 +1550,9 @@ function useParentChecklistRepo() {
1536
1550
  status,
1537
1551
  updatedAt: /* @__PURE__ */ new Date()
1538
1552
  };
1553
+ if (status === "completed") {
1554
+ updateValue.completedAt = /* @__PURE__ */ new Date();
1555
+ }
1539
1556
  const res = await collection.updateOne(
1540
1557
  { _id },
1541
1558
  { $set: updateValue },
@@ -1640,7 +1657,7 @@ function useParentChecklistController() {
1640
1657
  return;
1641
1658
  }
1642
1659
  const page = parseInt(req.query.page) ?? 1;
1643
- const limit = parseInt(req.query.limit) ?? 20;
1660
+ const limit = parseInt(req.query.limit) ?? 10;
1644
1661
  const search = req.query.search ?? "";
1645
1662
  const site = req.params.site ?? "";
1646
1663
  const startDate = req.query.startDate ?? "";
@@ -2651,7 +2668,7 @@ function useAreaChecklistController() {
2651
2668
  return;
2652
2669
  }
2653
2670
  const page = parseInt(req.query.page) ?? 1;
2654
- const limit = parseInt(req.query.limit) ?? 20;
2671
+ const limit = parseInt(req.query.limit) ?? 10;
2655
2672
  const search = req.query.search ?? "";
2656
2673
  const type = req.query.type ?? "";
2657
2674
  const schedule = req.params.schedule ?? "";
@@ -2689,7 +2706,7 @@ function useAreaChecklistController() {
2689
2706
  return;
2690
2707
  }
2691
2708
  const page = parseInt(req.query.page) ?? 1;
2692
- const limit = parseInt(req.query.limit) ?? 20;
2709
+ const limit = parseInt(req.query.limit) ?? 10;
2693
2710
  const search = req.query.search ?? "";
2694
2711
  const type = req.query.type ?? "";
2695
2712
  const schedule = req.params.schedule ?? "";
@@ -2747,7 +2764,7 @@ function useAreaChecklistController() {
2747
2764
  return;
2748
2765
  }
2749
2766
  const page = parseInt(req.query.page) ?? 1;
2750
- const limit = parseInt(req.query.limit) ?? 20;
2767
+ const limit = parseInt(req.query.limit) ?? 10;
2751
2768
  const search = req.query.search ?? "";
2752
2769
  const _id = req.params.id ?? "";
2753
2770
  try {
@@ -2822,8 +2839,7 @@ var import_mongodb9 = require("mongodb");
2822
2839
  var supplySchema = import_joi9.default.object({
2823
2840
  site: import_joi9.default.string().hex().required(),
2824
2841
  name: import_joi9.default.string().required(),
2825
- unitOfMeasurement: import_joi9.default.string().required(),
2826
- qty: import_joi9.default.number().min(0).required()
2842
+ unitOfMeasurement: import_joi9.default.string().required()
2827
2843
  });
2828
2844
  function MSupply(value) {
2829
2845
  const { error } = supplySchema.validate(value);
@@ -2842,7 +2858,7 @@ function MSupply(value) {
2842
2858
  site: value.site,
2843
2859
  name: value.name,
2844
2860
  unitOfMeasurement: value.unitOfMeasurement,
2845
- qty: value.qty,
2861
+ qty: 0,
2846
2862
  status: "active",
2847
2863
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
2848
2864
  updatedAt: "",
@@ -2949,7 +2965,8 @@ function useSupplyRepository() {
2949
2965
  {
2950
2966
  $project: {
2951
2967
  name: 1,
2952
- qty: 1
2968
+ qty: 1,
2969
+ status: 1
2953
2970
  }
2954
2971
  },
2955
2972
  { $sort: { _id: -1 } },
@@ -2968,7 +2985,7 @@ function useSupplyRepository() {
2968
2985
  throw error;
2969
2986
  }
2970
2987
  }
2971
- async function getSupplyById(_id) {
2988
+ async function getSupplyById(_id, session) {
2972
2989
  try {
2973
2990
  _id = new import_mongodb10.ObjectId(_id);
2974
2991
  } catch (error) {
@@ -2981,10 +2998,14 @@ function useSupplyRepository() {
2981
2998
  const cacheKey = (0, import_node_server_utils17.makeCacheKey)(namespace_collection, {
2982
2999
  _id: _id.toString()
2983
3000
  });
2984
- const cachedData = await getCache(cacheKey);
2985
- if (cachedData) {
2986
- import_node_server_utils17.logger.info(`Cache hit for key: ${cacheKey}`);
2987
- return cachedData;
3001
+ if (!session) {
3002
+ const cachedData = await getCache(cacheKey);
3003
+ if (cachedData) {
3004
+ import_node_server_utils17.logger.info(`Cache hit for key: ${cacheKey}`);
3005
+ return cachedData;
3006
+ }
3007
+ } else {
3008
+ import_node_server_utils17.logger.info(`Skipping cache during transaction for key: ${cacheKey}`);
2988
3009
  }
2989
3010
  try {
2990
3011
  const data = await collection.aggregate([
@@ -3038,7 +3059,7 @@ function useSupplyRepository() {
3038
3059
  } catch (error) {
3039
3060
  const isDuplicated = error.message.includes("duplicate");
3040
3061
  if (isDuplicated) {
3041
- throw new import_node_server_utils17.BadRequestError("Area already exists.");
3062
+ throw new import_node_server_utils17.BadRequestError("Supply already exists.");
3042
3063
  }
3043
3064
  throw error;
3044
3065
  }
@@ -3088,152 +3109,23 @@ function useSupplyRepository() {
3088
3109
  };
3089
3110
  }
3090
3111
 
3091
- // src/services/hygiene-supply.service.ts
3092
- var import_node_server_utils20 = require("@iservice365/node-server-utils");
3093
-
3094
- // src/models/hygiene-stock.model.ts
3112
+ // src/controllers/hygiene-supply.controller.ts
3095
3113
  var import_node_server_utils18 = require("@iservice365/node-server-utils");
3096
3114
  var import_joi10 = __toESM(require("joi"));
3097
- var import_mongodb11 = require("mongodb");
3098
- var stockSchema = import_joi10.default.object({
3099
- site: import_joi10.default.string().hex().required(),
3100
- supply: import_joi10.default.string().hex().required(),
3101
- in: import_joi10.default.number().min(0).optional(),
3102
- out: import_joi10.default.number().min(0).optional(),
3103
- balance: import_joi10.default.number().min(0).required(),
3104
- remarks: import_joi10.default.string().optional().allow("", null)
3105
- });
3106
- function MStock(value) {
3107
- const { error } = stockSchema.validate(value);
3108
- if (error) {
3109
- import_node_server_utils18.logger.info(`Hygiene Stock Model: ${error.message}`);
3110
- throw new import_node_server_utils18.BadRequestError(error.message);
3111
- }
3112
- if (value.site) {
3113
- try {
3114
- value.site = new import_mongodb11.ObjectId(value.site);
3115
- } catch (error2) {
3116
- throw new import_node_server_utils18.BadRequestError("Invalid site ID format.");
3117
- }
3118
- }
3119
- if (value.supply) {
3120
- try {
3121
- value.supply = new import_mongodb11.ObjectId(value.supply);
3122
- } catch (error2) {
3123
- throw new import_node_server_utils18.BadRequestError("Invalid supply ID format.");
3124
- }
3125
- }
3126
- return {
3127
- site: value.site,
3128
- supply: value.supply,
3129
- in: value.in ?? 0,
3130
- out: value.out ?? 0,
3131
- balance: value.balance,
3132
- remarks: value.remarks ?? "",
3133
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
3134
- status: "active",
3135
- updatedAt: "",
3136
- deletedAt: ""
3137
- };
3138
- }
3139
-
3140
- // src/repositories/hygiene-stock.repository.ts
3141
- var import_node_server_utils19 = require("@iservice365/node-server-utils");
3142
- function useStockRepository() {
3143
- const db = import_node_server_utils19.useAtlas.getDb();
3144
- if (!db) {
3145
- throw new import_node_server_utils19.InternalServerError("Unable to connect to server.");
3146
- }
3147
- const namespace_collection = "site.supply.stocks";
3148
- const collection = db.collection(namespace_collection);
3149
- const { delNamespace } = (0, import_node_server_utils19.useCache)(namespace_collection);
3150
- async function createIndex() {
3151
- try {
3152
- await collection.createIndexes([
3153
- { key: { site: 1 } },
3154
- { key: { supply: 1 } },
3155
- { key: { balance: 1 } },
3156
- { key: { status: 1 } }
3157
- ]);
3158
- } catch (error) {
3159
- throw new import_node_server_utils19.InternalServerError("Failed to create index on hygiene stock.");
3160
- }
3161
- }
3162
- async function createStock(value, session) {
3163
- try {
3164
- value = MStock(value);
3165
- const res = await collection.insertOne(value, { session });
3166
- delNamespace().then(() => {
3167
- import_node_server_utils19.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
3168
- }).catch((err) => {
3169
- import_node_server_utils19.logger.error(
3170
- `Failed to clear cache for namespace: ${namespace_collection}`,
3171
- err
3172
- );
3173
- });
3174
- return res.insertedId;
3175
- } catch (error) {
3176
- const isDuplicated = error.message.includes("duplicate");
3177
- if (isDuplicated) {
3178
- throw new import_node_server_utils19.BadRequestError("Stock already exists.");
3179
- }
3180
- throw error;
3181
- }
3182
- }
3183
- return {
3184
- createIndex,
3185
- createStock
3186
- };
3187
- }
3188
-
3189
- // src/services/hygiene-supply.service.ts
3190
- function useSupplyService() {
3191
- const { createSupply: _createSupply } = useSupplyRepository();
3192
- const { createStock } = useStockRepository();
3193
- async function createSupply(value) {
3194
- const session = import_node_server_utils20.useAtlas.getClient()?.startSession();
3195
- try {
3196
- session?.startTransaction();
3197
- const { qty, site } = value;
3198
- const supply = await _createSupply(value, session);
3199
- const createdSupply = await createStock(
3200
- {
3201
- site,
3202
- supply: supply.toString(),
3203
- in: qty,
3204
- balance: qty
3205
- },
3206
- session
3207
- );
3208
- await session?.commitTransaction();
3209
- return createdSupply;
3210
- } catch (error) {
3211
- await session?.abortTransaction();
3212
- throw error;
3213
- } finally {
3214
- await session?.endSession();
3215
- }
3216
- }
3217
- return { createSupply };
3218
- }
3219
-
3220
- // src/controllers/hygiene-supply.controller.ts
3221
- var import_node_server_utils21 = require("@iservice365/node-server-utils");
3222
- var import_joi11 = __toESM(require("joi"));
3223
3115
  function useSupplyController() {
3224
3116
  const {
3117
+ createSupply: _createSupply,
3225
3118
  getSupplies: _getSupplies,
3226
3119
  getSupplyById: _getSupplyById,
3227
3120
  updateSupply: _updateSupply,
3228
3121
  deleteSupply: _deleteSupply
3229
3122
  } = useSupplyRepository();
3230
- const { createSupply: _createSupply } = useSupplyService();
3231
3123
  async function createSupply(req, res, next) {
3232
3124
  const payload = { ...req.body, ...req.params };
3233
3125
  const { error } = supplySchema.validate(payload);
3234
3126
  if (error) {
3235
- import_node_server_utils21.logger.log({ level: "error", message: error.message });
3236
- next(new import_node_server_utils21.BadRequestError(error.message));
3127
+ import_node_server_utils18.logger.log({ level: "error", message: error.message });
3128
+ next(new import_node_server_utils18.BadRequestError(error.message));
3237
3129
  return;
3238
3130
  }
3239
3131
  try {
@@ -3241,27 +3133,27 @@ function useSupplyController() {
3241
3133
  res.status(201).json({ message: "Supply created successfully.", id });
3242
3134
  return;
3243
3135
  } catch (error2) {
3244
- import_node_server_utils21.logger.log({ level: "error", message: error2.message });
3136
+ import_node_server_utils18.logger.log({ level: "error", message: error2.message });
3245
3137
  next(error2);
3246
3138
  return;
3247
3139
  }
3248
3140
  }
3249
3141
  async function getSupplies(req, res, next) {
3250
3142
  const query = { ...req.query, ...req.params };
3251
- const validation = import_joi11.default.object({
3252
- page: import_joi11.default.number().min(1).optional().allow("", null),
3253
- limit: import_joi11.default.number().min(1).optional().allow("", null),
3254
- search: import_joi11.default.string().optional().allow("", null),
3255
- site: import_joi11.default.string().hex().required()
3143
+ const validation = import_joi10.default.object({
3144
+ page: import_joi10.default.number().min(1).optional().allow("", null),
3145
+ limit: import_joi10.default.number().min(1).optional().allow("", null),
3146
+ search: import_joi10.default.string().optional().allow("", null),
3147
+ site: import_joi10.default.string().hex().required()
3256
3148
  });
3257
3149
  const { error } = validation.validate(query);
3258
3150
  if (error) {
3259
- import_node_server_utils21.logger.log({ level: "error", message: error.message });
3260
- next(new import_node_server_utils21.BadRequestError(error.message));
3151
+ import_node_server_utils18.logger.log({ level: "error", message: error.message });
3152
+ next(new import_node_server_utils18.BadRequestError(error.message));
3261
3153
  return;
3262
3154
  }
3263
3155
  const page = parseInt(req.query.page) ?? 1;
3264
- const limit = parseInt(req.query.limit) ?? 20;
3156
+ const limit = parseInt(req.query.limit) ?? 10;
3265
3157
  const search = req.query.search ?? "";
3266
3158
  const site = req.params.site ?? "";
3267
3159
  try {
@@ -3274,18 +3166,18 @@ function useSupplyController() {
3274
3166
  res.json(data);
3275
3167
  return;
3276
3168
  } catch (error2) {
3277
- import_node_server_utils21.logger.log({ level: "error", message: error2.message });
3169
+ import_node_server_utils18.logger.log({ level: "error", message: error2.message });
3278
3170
  next(error2);
3279
3171
  return;
3280
3172
  }
3281
3173
  }
3282
3174
  async function getSupplyById(req, res, next) {
3283
- const validation = import_joi11.default.string().hex().required();
3175
+ const validation = import_joi10.default.string().hex().required();
3284
3176
  const _id = req.params.id;
3285
3177
  const { error } = validation.validate(_id);
3286
3178
  if (error) {
3287
- import_node_server_utils21.logger.log({ level: "error", message: error.message });
3288
- next(new import_node_server_utils21.BadRequestError(error.message));
3179
+ import_node_server_utils18.logger.log({ level: "error", message: error.message });
3180
+ next(new import_node_server_utils18.BadRequestError(error.message));
3289
3181
  return;
3290
3182
  }
3291
3183
  try {
@@ -3293,23 +3185,23 @@ function useSupplyController() {
3293
3185
  res.json(data);
3294
3186
  return;
3295
3187
  } catch (error2) {
3296
- import_node_server_utils21.logger.log({ level: "error", message: error2.message });
3188
+ import_node_server_utils18.logger.log({ level: "error", message: error2.message });
3297
3189
  next(error2);
3298
3190
  return;
3299
3191
  }
3300
3192
  }
3301
3193
  async function updateSupply(req, res, next) {
3302
3194
  const payload = { id: req.params.id, ...req.body };
3303
- const validation = import_joi11.default.object({
3304
- id: import_joi11.default.string().hex().required(),
3305
- name: import_joi11.default.string().optional().allow("", null),
3306
- unitOfMeasurement: import_joi11.default.string().optional().allow("", null),
3307
- qty: import_joi11.default.number().min(0).optional().allow("", null)
3195
+ const validation = import_joi10.default.object({
3196
+ id: import_joi10.default.string().hex().required(),
3197
+ name: import_joi10.default.string().optional().allow("", null),
3198
+ unitOfMeasurement: import_joi10.default.string().optional().allow("", null),
3199
+ qty: import_joi10.default.number().min(0).optional().allow("", null)
3308
3200
  });
3309
3201
  const { error } = validation.validate(payload);
3310
3202
  if (error) {
3311
- import_node_server_utils21.logger.log({ level: "error", message: error.message });
3312
- next(new import_node_server_utils21.BadRequestError(error.message));
3203
+ import_node_server_utils18.logger.log({ level: "error", message: error.message });
3204
+ next(new import_node_server_utils18.BadRequestError(error.message));
3313
3205
  return;
3314
3206
  }
3315
3207
  try {
@@ -3318,20 +3210,20 @@ function useSupplyController() {
3318
3210
  res.json({ message: "Supply updated successfully." });
3319
3211
  return;
3320
3212
  } catch (error2) {
3321
- import_node_server_utils21.logger.log({ level: "error", message: error2.message });
3213
+ import_node_server_utils18.logger.log({ level: "error", message: error2.message });
3322
3214
  next(error2);
3323
3215
  return;
3324
3216
  }
3325
3217
  }
3326
3218
  async function deleteSupply(req, res, next) {
3327
3219
  const id = req.params.id;
3328
- const validation = import_joi11.default.object({
3329
- id: import_joi11.default.string().hex().required()
3220
+ const validation = import_joi10.default.object({
3221
+ id: import_joi10.default.string().hex().required()
3330
3222
  });
3331
3223
  const { error } = validation.validate({ id });
3332
3224
  if (error) {
3333
- import_node_server_utils21.logger.log({ level: "error", message: error.message });
3334
- next(new import_node_server_utils21.BadRequestError(error.message));
3225
+ import_node_server_utils18.logger.log({ level: "error", message: error.message });
3226
+ next(new import_node_server_utils18.BadRequestError(error.message));
3335
3227
  return;
3336
3228
  }
3337
3229
  try {
@@ -3339,7 +3231,7 @@ function useSupplyController() {
3339
3231
  res.json({ message: "Supply deleted successfully." });
3340
3232
  return;
3341
3233
  } catch (error2) {
3342
- import_node_server_utils21.logger.log({ level: "error", message: error2.message });
3234
+ import_node_server_utils18.logger.log({ level: "error", message: error2.message });
3343
3235
  next(error2);
3344
3236
  return;
3345
3237
  }
@@ -3353,24 +3245,203 @@ function useSupplyController() {
3353
3245
  };
3354
3246
  }
3355
3247
 
3248
+ // src/models/hygiene-stock.model.ts
3249
+ var import_node_server_utils19 = require("@iservice365/node-server-utils");
3250
+ var import_joi11 = __toESM(require("joi"));
3251
+ var import_mongodb11 = require("mongodb");
3252
+ var stockSchema = import_joi11.default.object({
3253
+ site: import_joi11.default.string().hex().required(),
3254
+ supply: import_joi11.default.string().hex().required(),
3255
+ in: import_joi11.default.number().min(0).optional(),
3256
+ out: import_joi11.default.number().min(0).optional(),
3257
+ balance: import_joi11.default.number().min(0).required(),
3258
+ remarks: import_joi11.default.string().optional().allow("", null)
3259
+ });
3260
+ function MStock(value) {
3261
+ const { error } = stockSchema.validate(value);
3262
+ if (error) {
3263
+ import_node_server_utils19.logger.info(`Hygiene Stock Model: ${error.message}`);
3264
+ throw new import_node_server_utils19.BadRequestError(error.message);
3265
+ }
3266
+ if (value.site) {
3267
+ try {
3268
+ value.site = new import_mongodb11.ObjectId(value.site);
3269
+ } catch (error2) {
3270
+ throw new import_node_server_utils19.BadRequestError("Invalid site ID format.");
3271
+ }
3272
+ }
3273
+ if (value.supply) {
3274
+ try {
3275
+ value.supply = new import_mongodb11.ObjectId(value.supply);
3276
+ } catch (error2) {
3277
+ throw new import_node_server_utils19.BadRequestError("Invalid supply ID format.");
3278
+ }
3279
+ }
3280
+ return {
3281
+ site: value.site,
3282
+ supply: value.supply,
3283
+ in: value.in ?? 0,
3284
+ out: value.out ?? 0,
3285
+ balance: value.balance,
3286
+ remarks: value.remarks ?? "",
3287
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
3288
+ status: "active",
3289
+ updatedAt: "",
3290
+ deletedAt: ""
3291
+ };
3292
+ }
3293
+
3294
+ // src/repositories/hygiene-stock.repository.ts
3295
+ var import_mongodb12 = require("mongodb");
3296
+ var import_node_server_utils20 = require("@iservice365/node-server-utils");
3297
+ function useStockRepository() {
3298
+ const db = import_node_server_utils20.useAtlas.getDb();
3299
+ if (!db) {
3300
+ throw new import_node_server_utils20.InternalServerError("Unable to connect to server.");
3301
+ }
3302
+ const namespace_collection = "site.supply.stocks";
3303
+ const supply_collection = "site.supplies";
3304
+ const collection = db.collection(namespace_collection);
3305
+ const { delNamespace, setCache, getCache } = (0, import_node_server_utils20.useCache)(namespace_collection);
3306
+ const { delNamespace: delSupplyNamespace } = (0, import_node_server_utils20.useCache)(supply_collection);
3307
+ async function createIndex() {
3308
+ try {
3309
+ await collection.createIndexes([
3310
+ { key: { site: 1 } },
3311
+ { key: { supply: 1 } },
3312
+ { key: { balance: 1 } },
3313
+ { key: { status: 1 } }
3314
+ ]);
3315
+ } catch (error) {
3316
+ throw new import_node_server_utils20.InternalServerError("Failed to create index on hygiene stock.");
3317
+ }
3318
+ }
3319
+ async function createStock(value, session) {
3320
+ try {
3321
+ value = MStock(value);
3322
+ const res = await collection.insertOne(value, { session });
3323
+ delNamespace().then(() => {
3324
+ import_node_server_utils20.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
3325
+ }).catch((err) => {
3326
+ import_node_server_utils20.logger.error(
3327
+ `Failed to clear cache for namespace: ${namespace_collection}`,
3328
+ err
3329
+ );
3330
+ });
3331
+ delSupplyNamespace().then(() => {
3332
+ import_node_server_utils20.logger.info(`Cache cleared for namespace: ${supply_collection}`);
3333
+ }).catch((err) => {
3334
+ import_node_server_utils20.logger.error(
3335
+ `Failed to clear cache for namespace: ${supply_collection}`,
3336
+ err
3337
+ );
3338
+ });
3339
+ return res.insertedId;
3340
+ } catch (error) {
3341
+ throw error;
3342
+ }
3343
+ }
3344
+ async function getStocksBySupplyId({
3345
+ page = 1,
3346
+ limit = 10,
3347
+ search = "",
3348
+ site,
3349
+ supply
3350
+ }) {
3351
+ page = page > 0 ? page - 1 : 0;
3352
+ const query = {
3353
+ status: { $ne: "deleted" }
3354
+ };
3355
+ const cacheOptions = {
3356
+ page,
3357
+ limit
3358
+ };
3359
+ try {
3360
+ site = new import_mongodb12.ObjectId(site);
3361
+ query.site = site;
3362
+ cacheOptions.site = site.toString();
3363
+ } catch (error) {
3364
+ throw new import_node_server_utils20.BadRequestError("Invalid site ID format.");
3365
+ }
3366
+ try {
3367
+ supply = new import_mongodb12.ObjectId(supply);
3368
+ query.supply = supply;
3369
+ cacheOptions.supply = supply.toString();
3370
+ } catch (error) {
3371
+ throw new import_node_server_utils20.BadRequestError("Invalid supply ID format.");
3372
+ }
3373
+ if (search) {
3374
+ query.$text = { $search: search };
3375
+ cacheOptions.search = search;
3376
+ }
3377
+ const cacheKey = (0, import_node_server_utils20.makeCacheKey)(namespace_collection, cacheOptions);
3378
+ const cachedData = await getCache(cacheKey);
3379
+ if (cachedData) {
3380
+ import_node_server_utils20.logger.info(`Cache hit for key: ${cacheKey}`);
3381
+ return cachedData;
3382
+ }
3383
+ try {
3384
+ const items = await collection.aggregate([
3385
+ { $match: query },
3386
+ {
3387
+ $project: {
3388
+ createdAt: 1,
3389
+ in: 1,
3390
+ out: 1,
3391
+ balance: 1
3392
+ }
3393
+ },
3394
+ { $sort: { _id: 1 } },
3395
+ { $skip: page * limit },
3396
+ { $limit: limit }
3397
+ ]).toArray();
3398
+ const length = await collection.countDocuments(query);
3399
+ const data = (0, import_node_server_utils20.paginate)(items, page, limit, length);
3400
+ setCache(cacheKey, data, 15 * 60).then(() => {
3401
+ import_node_server_utils20.logger.info(`Cache set for key: ${cacheKey}`);
3402
+ }).catch((err) => {
3403
+ import_node_server_utils20.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
3404
+ });
3405
+ return data;
3406
+ } catch (error) {
3407
+ throw error;
3408
+ }
3409
+ }
3410
+ return {
3411
+ createIndex,
3412
+ createStock,
3413
+ getStocksBySupplyId
3414
+ };
3415
+ }
3416
+
3356
3417
  // src/services/hygiene-stock.service.ts
3357
- var import_node_server_utils22 = require("@iservice365/node-server-utils");
3418
+ var import_node_server_utils21 = require("@iservice365/node-server-utils");
3358
3419
  function useStockService() {
3359
3420
  const { createStock: _createStock } = useStockRepository();
3360
3421
  const { getSupplyById, updateSupply } = useSupplyRepository();
3361
- async function createStock(value) {
3362
- const session = import_node_server_utils22.useAtlas.getClient()?.startSession();
3422
+ async function createStock(value, out = false) {
3423
+ const session = import_node_server_utils21.useAtlas.getClient()?.startSession();
3363
3424
  try {
3364
3425
  session?.startTransaction();
3365
3426
  const { qty, ...stockData } = value;
3366
- const supply = await getSupplyById(value.supply);
3427
+ const supply = await getSupplyById(value.supply, session);
3367
3428
  if (!supply || supply.qty === void 0) {
3368
- throw new import_node_server_utils22.NotFoundError("Supply not found.");
3429
+ throw new import_node_server_utils21.NotFoundError("Supply not found.");
3430
+ }
3431
+ const newSupplyQty = out ? supply.qty - qty : supply.qty + qty;
3432
+ if (out && newSupplyQty < 0) {
3433
+ throw new import_node_server_utils21.BadRequestError(
3434
+ `Insufficient stock. Available: ${supply.qty}, Requested: ${qty}`
3435
+ );
3369
3436
  }
3370
- const newSupplyQty = supply.qty + qty;
3371
3437
  await updateSupply(value.supply, { qty: newSupplyQty }, session);
3372
3438
  const createdStock = await _createStock(
3373
- { ...stockData, in: qty, balance: newSupplyQty },
3439
+ {
3440
+ ...stockData,
3441
+ in: out ? 0 : qty,
3442
+ out: out ? qty : 0,
3443
+ balance: newSupplyQty
3444
+ },
3374
3445
  session
3375
3446
  );
3376
3447
  await session?.commitTransaction();
@@ -3386,22 +3457,23 @@ function useStockService() {
3386
3457
  }
3387
3458
 
3388
3459
  // src/controllers/hygiene-stock.controller.ts
3389
- var import_node_server_utils23 = require("@iservice365/node-server-utils");
3460
+ var import_node_server_utils22 = require("@iservice365/node-server-utils");
3390
3461
  var import_joi12 = __toESM(require("joi"));
3391
3462
  function useStockController() {
3463
+ const { getStocksBySupplyId: _getStocksBySupplyId } = useStockRepository();
3392
3464
  const { createStock: _createStock } = useStockService();
3393
3465
  async function createStock(req, res, next) {
3394
3466
  const payload = { ...req.body, ...req.params };
3395
3467
  const validation = import_joi12.default.object({
3396
3468
  site: import_joi12.default.string().hex().required(),
3397
3469
  supply: import_joi12.default.string().hex().required(),
3398
- qty: import_joi12.default.number().min(0).optional(),
3470
+ qty: import_joi12.default.number().min(0).required(),
3399
3471
  remarks: import_joi12.default.string().optional().allow("", null)
3400
3472
  });
3401
3473
  const { error } = validation.validate(payload);
3402
3474
  if (error) {
3403
- import_node_server_utils23.logger.log({ level: "error", message: error.message });
3404
- next(new import_node_server_utils23.BadRequestError(error.message));
3475
+ import_node_server_utils22.logger.log({ level: "error", message: error.message });
3476
+ next(new import_node_server_utils22.BadRequestError(error.message));
3405
3477
  return;
3406
3478
  }
3407
3479
  try {
@@ -3409,13 +3481,1092 @@ function useStockController() {
3409
3481
  res.status(201).json({ message: "Stock created successfully.", id });
3410
3482
  return;
3411
3483
  } catch (error2) {
3412
- import_node_server_utils23.logger.log({ level: "error", message: error2.message });
3484
+ import_node_server_utils22.logger.log({ level: "error", message: error2.message });
3485
+ next(error2);
3486
+ return;
3487
+ }
3488
+ }
3489
+ async function getStocksBySupplyId(req, res, next) {
3490
+ const query = { ...req.query, ...req.params };
3491
+ const validation = import_joi12.default.object({
3492
+ page: import_joi12.default.number().min(1).optional().allow("", null),
3493
+ limit: import_joi12.default.number().min(1).optional().allow("", null),
3494
+ search: import_joi12.default.string().optional().allow("", null),
3495
+ site: import_joi12.default.string().hex().required(),
3496
+ supply: import_joi12.default.string().hex().required()
3497
+ });
3498
+ const { error } = validation.validate(query);
3499
+ if (error) {
3500
+ import_node_server_utils22.logger.log({ level: "error", message: error.message });
3501
+ next(new import_node_server_utils22.BadRequestError(error.message));
3502
+ return;
3503
+ }
3504
+ const page = parseInt(req.query.page) ?? 1;
3505
+ const limit = parseInt(req.query.limit) ?? 10;
3506
+ const search = req.query.search ?? "";
3507
+ const site = req.params.site ?? "";
3508
+ const supply = req.params.supply ?? "";
3509
+ try {
3510
+ const data = await _getStocksBySupplyId({
3511
+ page,
3512
+ limit,
3513
+ search,
3514
+ site,
3515
+ supply
3516
+ });
3517
+ res.json(data);
3518
+ return;
3519
+ } catch (error2) {
3520
+ import_node_server_utils22.logger.log({ level: "error", message: error2.message });
3521
+ next(error2);
3522
+ return;
3523
+ }
3524
+ }
3525
+ return {
3526
+ createStock,
3527
+ getStocksBySupplyId
3528
+ };
3529
+ }
3530
+
3531
+ // src/models/hygiene-request-item.model.ts
3532
+ var import_node_server_utils23 = require("@iservice365/node-server-utils");
3533
+ var import_joi13 = __toESM(require("joi"));
3534
+ var import_mongodb13 = require("mongodb");
3535
+ var allowedRequestItemStatus = [
3536
+ "pending",
3537
+ "approved",
3538
+ "disapproved"
3539
+ ];
3540
+ var requestItemSchema = import_joi13.default.object({
3541
+ site: import_joi13.default.string().hex().required(),
3542
+ supply: import_joi13.default.string().hex().required(),
3543
+ supplyName: import_joi13.default.string().required(),
3544
+ qty: import_joi13.default.number().min(0).required(),
3545
+ createdBy: import_joi13.default.string().hex().required(),
3546
+ createdByName: import_joi13.default.string().required()
3547
+ });
3548
+ function MRequestItem(value) {
3549
+ const { error } = requestItemSchema.validate(value);
3550
+ if (error) {
3551
+ import_node_server_utils23.logger.info(`Hygiene Request Item Model: ${error.message}`);
3552
+ throw new import_node_server_utils23.BadRequestError(error.message);
3553
+ }
3554
+ if (value.site) {
3555
+ try {
3556
+ value.site = new import_mongodb13.ObjectId(value.site);
3557
+ } catch (error2) {
3558
+ throw new import_node_server_utils23.BadRequestError("Invalid site ID format.");
3559
+ }
3560
+ }
3561
+ if (value.supply) {
3562
+ try {
3563
+ value.supply = new import_mongodb13.ObjectId(value.supply);
3564
+ } catch (error2) {
3565
+ throw new import_node_server_utils23.BadRequestError("Invalid supply ID format.");
3566
+ }
3567
+ }
3568
+ return {
3569
+ site: value.site,
3570
+ supply: value.supply,
3571
+ supplyName: value.supplyName,
3572
+ qty: value.qty,
3573
+ remarks: "",
3574
+ createdBy: value.createdBy,
3575
+ createdByName: value.createdByName,
3576
+ status: "pending",
3577
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
3578
+ updatedAt: "",
3579
+ deletedAt: ""
3580
+ };
3581
+ }
3582
+
3583
+ // src/repositories/hygiene-request-item.repository.ts
3584
+ var import_mongodb14 = require("mongodb");
3585
+ var import_node_server_utils24 = require("@iservice365/node-server-utils");
3586
+ function useRequestItemRepository() {
3587
+ const db = import_node_server_utils24.useAtlas.getDb();
3588
+ if (!db) {
3589
+ throw new import_node_server_utils24.InternalServerError("Unable to connect to server.");
3590
+ }
3591
+ const namespace_collection = "site.supply.requests";
3592
+ const collection = db.collection(namespace_collection);
3593
+ const { delNamespace, setCache, getCache } = (0, import_node_server_utils24.useCache)(namespace_collection);
3594
+ async function createIndex() {
3595
+ try {
3596
+ await collection.createIndexes([
3597
+ { key: { site: 1 } },
3598
+ { key: { supply: 1 } },
3599
+ { key: { status: 1 } }
3600
+ ]);
3601
+ } catch (error) {
3602
+ throw new import_node_server_utils24.InternalServerError(
3603
+ "Failed to create index on hygiene request item."
3604
+ );
3605
+ }
3606
+ }
3607
+ async function createTextIndex() {
3608
+ try {
3609
+ await collection.createIndex({ supplyName: "text" });
3610
+ } catch (error) {
3611
+ throw new import_node_server_utils24.InternalServerError(
3612
+ "Failed to create text index on hygiene supply."
3613
+ );
3614
+ }
3615
+ }
3616
+ async function createRequestItem(value, session) {
3617
+ try {
3618
+ value = MRequestItem(value);
3619
+ const res = await collection.insertOne(value, { session });
3620
+ delNamespace().then(() => {
3621
+ import_node_server_utils24.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
3622
+ }).catch((err) => {
3623
+ import_node_server_utils24.logger.error(
3624
+ `Failed to clear cache for namespace: ${namespace_collection}`,
3625
+ err
3626
+ );
3627
+ });
3628
+ return res.insertedId;
3629
+ } catch (error) {
3630
+ throw error;
3631
+ }
3632
+ }
3633
+ async function getRequestItems({
3634
+ page = 1,
3635
+ limit = 10,
3636
+ search = "",
3637
+ site
3638
+ }) {
3639
+ page = page > 0 ? page - 1 : 0;
3640
+ const query = {
3641
+ status: { $ne: "deleted" }
3642
+ };
3643
+ const cacheOptions = {
3644
+ page,
3645
+ limit
3646
+ };
3647
+ try {
3648
+ site = new import_mongodb14.ObjectId(site);
3649
+ query.site = site;
3650
+ cacheOptions.site = site.toString();
3651
+ } catch (error) {
3652
+ throw new import_node_server_utils24.BadRequestError("Invalid site ID format.");
3653
+ }
3654
+ if (search) {
3655
+ query.$text = { $search: search };
3656
+ cacheOptions.search = search;
3657
+ }
3658
+ const cacheKey = (0, import_node_server_utils24.makeCacheKey)(namespace_collection, cacheOptions);
3659
+ const cachedData = await getCache(cacheKey);
3660
+ if (cachedData) {
3661
+ import_node_server_utils24.logger.info(`Cache hit for key: ${cacheKey}`);
3662
+ return cachedData;
3663
+ }
3664
+ try {
3665
+ const items = await collection.aggregate([
3666
+ { $match: query },
3667
+ {
3668
+ $project: {
3669
+ createdAt: 1,
3670
+ status: 1
3671
+ }
3672
+ },
3673
+ { $sort: { _id: -1 } },
3674
+ { $skip: page * limit },
3675
+ { $limit: limit }
3676
+ ]).toArray();
3677
+ const length = await collection.countDocuments(query);
3678
+ const data = (0, import_node_server_utils24.paginate)(items, page, limit, length);
3679
+ setCache(cacheKey, data, 15 * 60).then(() => {
3680
+ import_node_server_utils24.logger.info(`Cache set for key: ${cacheKey}`);
3681
+ }).catch((err) => {
3682
+ import_node_server_utils24.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
3683
+ });
3684
+ return data;
3685
+ } catch (error) {
3686
+ throw error;
3687
+ }
3688
+ }
3689
+ async function getRequestItemById(_id, session) {
3690
+ try {
3691
+ _id = new import_mongodb14.ObjectId(_id);
3692
+ } catch (error) {
3693
+ throw new import_node_server_utils24.BadRequestError("Invalid request item ID format.");
3694
+ }
3695
+ const query = { _id };
3696
+ const cacheKey = (0, import_node_server_utils24.makeCacheKey)(namespace_collection, {
3697
+ _id: _id.toString()
3698
+ });
3699
+ if (!session) {
3700
+ const cachedData = await getCache(cacheKey);
3701
+ if (cachedData) {
3702
+ import_node_server_utils24.logger.info(`Cache hit for key: ${cacheKey}`);
3703
+ return cachedData;
3704
+ }
3705
+ } else {
3706
+ import_node_server_utils24.logger.info(`Skipping cache during transaction for key: ${cacheKey}`);
3707
+ }
3708
+ try {
3709
+ const data = await collection.aggregate([
3710
+ { $match: query },
3711
+ {
3712
+ $lookup: {
3713
+ from: "site.supply.items",
3714
+ localField: "supply",
3715
+ foreignField: "_id",
3716
+ as: "supplyDetails"
3717
+ }
3718
+ },
3719
+ {
3720
+ $unwind: {
3721
+ path: "$supplyDetails",
3722
+ preserveNullAndEmptyArrays: true
3723
+ }
3724
+ },
3725
+ {
3726
+ $project: {
3727
+ site: 1,
3728
+ supply: 1,
3729
+ supplyName: 1,
3730
+ qty: 1,
3731
+ status: 1,
3732
+ unitOfMeasurement: "$supplyDetails.unitOfMeasurement"
3733
+ }
3734
+ }
3735
+ ]).toArray();
3736
+ if (!data || data.length === 0) {
3737
+ throw new import_node_server_utils24.NotFoundError("Request item not found.");
3738
+ }
3739
+ setCache(cacheKey, data[0], 15 * 60).then(() => {
3740
+ import_node_server_utils24.logger.info(`Cache set for key: ${cacheKey}`);
3741
+ }).catch((err) => {
3742
+ import_node_server_utils24.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
3743
+ });
3744
+ return data[0];
3745
+ } catch (error) {
3746
+ throw error;
3747
+ }
3748
+ }
3749
+ async function approveRequestItem(_id, remarks, session) {
3750
+ try {
3751
+ _id = new import_mongodb14.ObjectId(_id);
3752
+ } catch (error) {
3753
+ throw new import_node_server_utils24.BadRequestError("Invalid request item ID format.");
3754
+ }
3755
+ try {
3756
+ const updateValue = {
3757
+ status: "approved",
3758
+ remarks: remarks || "",
3759
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
3760
+ };
3761
+ const res = await collection.updateOne(
3762
+ { _id },
3763
+ { $set: updateValue },
3764
+ { session }
3765
+ );
3766
+ if (res.modifiedCount === 0) {
3767
+ throw new import_node_server_utils24.InternalServerError("Unable to approve request item.");
3768
+ }
3769
+ delNamespace().then(() => {
3770
+ import_node_server_utils24.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
3771
+ }).catch((err) => {
3772
+ import_node_server_utils24.logger.error(
3773
+ `Failed to clear cache for namespace: ${namespace_collection}`,
3774
+ err
3775
+ );
3776
+ });
3777
+ return res.modifiedCount;
3778
+ } catch (error) {
3779
+ throw error;
3780
+ }
3781
+ }
3782
+ async function disapproveRequestItem(_id, remarks, session) {
3783
+ try {
3784
+ _id = new import_mongodb14.ObjectId(_id);
3785
+ } catch (error) {
3786
+ throw new import_node_server_utils24.BadRequestError("Invalid request item ID format.");
3787
+ }
3788
+ try {
3789
+ const updateValue = {
3790
+ status: "disapproved",
3791
+ remarks: remarks || "",
3792
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
3793
+ };
3794
+ const res = await collection.updateOne(
3795
+ { _id },
3796
+ { $set: updateValue },
3797
+ { session }
3798
+ );
3799
+ if (res.modifiedCount === 0) {
3800
+ throw new import_node_server_utils24.InternalServerError("Unable to disapprove request item.");
3801
+ }
3802
+ delNamespace().then(() => {
3803
+ import_node_server_utils24.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
3804
+ }).catch((err) => {
3805
+ import_node_server_utils24.logger.error(
3806
+ `Failed to clear cache for namespace: ${namespace_collection}`,
3807
+ err
3808
+ );
3809
+ });
3810
+ return res.modifiedCount;
3811
+ } catch (error) {
3812
+ throw error;
3813
+ }
3814
+ }
3815
+ return {
3816
+ createIndex,
3817
+ createTextIndex,
3818
+ createRequestItem,
3819
+ getRequestItems,
3820
+ getRequestItemById,
3821
+ approveRequestItem,
3822
+ disapproveRequestItem
3823
+ };
3824
+ }
3825
+
3826
+ // src/services/hygiene-request-item.service.ts
3827
+ var import_node_server_utils25 = require("@iservice365/node-server-utils");
3828
+ var import_core = require("@iservice365/core");
3829
+ function useRequestItemService() {
3830
+ const {
3831
+ createRequestItem: _createRequestItem,
3832
+ getRequestItemById: _getRequestItemById,
3833
+ approveRequestItem: _approveRequestItem,
3834
+ disapproveRequestItem: _disapproveRequestItem
3835
+ } = useRequestItemRepository();
3836
+ const { getSupplyById } = useSupplyRepository();
3837
+ const { getUserById } = (0, import_core.useUserRepo)();
3838
+ const { createStock } = useStockService();
3839
+ async function createRequestItem(value) {
3840
+ try {
3841
+ const { supply, createdBy } = value;
3842
+ const supplyData = await getSupplyById(supply);
3843
+ const createdByData = await getUserById(createdBy);
3844
+ const createdRequestItem = await _createRequestItem({
3845
+ ...value,
3846
+ supplyName: supplyData?.name || "",
3847
+ createdByName: createdByData?.name || ""
3848
+ });
3849
+ return createdRequestItem;
3850
+ } catch (error) {
3851
+ throw error;
3852
+ }
3853
+ }
3854
+ async function createRequestItemByBatch(value) {
3855
+ const session = import_node_server_utils25.useAtlas.getClient()?.startSession();
3856
+ try {
3857
+ session?.startTransaction();
3858
+ const { site, createdBy, items } = value;
3859
+ const createdByData = await getUserById(createdBy);
3860
+ const createdRequestItemIds = [];
3861
+ for (const item of items) {
3862
+ const supplyData = await getSupplyById(item.supply, session);
3863
+ const createdId = await _createRequestItem(
3864
+ {
3865
+ site,
3866
+ supply: item.supply,
3867
+ qty: item.qty,
3868
+ supplyName: supplyData?.name || "",
3869
+ createdBy,
3870
+ createdByName: createdByData?.name || ""
3871
+ },
3872
+ session
3873
+ );
3874
+ createdRequestItemIds.push(createdId);
3875
+ }
3876
+ await session?.commitTransaction();
3877
+ return createdRequestItemIds;
3878
+ } catch (error) {
3879
+ await session?.abortTransaction();
3880
+ throw error;
3881
+ } finally {
3882
+ await session?.endSession();
3883
+ }
3884
+ }
3885
+ async function approveRequestItem(id, remarks) {
3886
+ const session = import_node_server_utils25.useAtlas.getClient()?.startSession();
3887
+ try {
3888
+ session?.startTransaction();
3889
+ await _approveRequestItem(id, remarks, session);
3890
+ const requestItem = await _getRequestItemById(id, session);
3891
+ if (requestItem.status !== "pending") {
3892
+ throw new import_node_server_utils25.BadRequestError(
3893
+ "Only 'pending' request items can be approved."
3894
+ );
3895
+ }
3896
+ const createdStocks = await createStock(
3897
+ {
3898
+ site: requestItem.site.toString(),
3899
+ supply: requestItem.supply.toString(),
3900
+ qty: requestItem.qty,
3901
+ remarks
3902
+ },
3903
+ true
3904
+ );
3905
+ await session?.commitTransaction();
3906
+ return createdStocks;
3907
+ } catch (error) {
3908
+ await session?.abortTransaction();
3909
+ throw error;
3910
+ } finally {
3911
+ await session?.endSession();
3912
+ }
3913
+ }
3914
+ async function disapproveRequestItem(id, remarks) {
3915
+ const session = import_node_server_utils25.useAtlas.getClient()?.startSession();
3916
+ try {
3917
+ session?.startTransaction();
3918
+ const result = await _disapproveRequestItem(id, remarks, session);
3919
+ const requestItem = await _getRequestItemById(id, session);
3920
+ if (requestItem.status !== "pending") {
3921
+ throw new import_node_server_utils25.BadRequestError(
3922
+ "Only 'pending' request items can be disapproved."
3923
+ );
3924
+ }
3925
+ await session?.commitTransaction();
3926
+ return result;
3927
+ } catch (error) {
3928
+ await session?.abortTransaction();
3929
+ throw error;
3930
+ } finally {
3931
+ await session?.endSession();
3932
+ }
3933
+ }
3934
+ return {
3935
+ createRequestItem,
3936
+ createRequestItemByBatch,
3937
+ approveRequestItem,
3938
+ disapproveRequestItem
3939
+ };
3940
+ }
3941
+
3942
+ // src/controllers/hygiene-request-item.controller.ts
3943
+ var import_node_server_utils26 = require("@iservice365/node-server-utils");
3944
+ var import_joi14 = __toESM(require("joi"));
3945
+ function useRequestItemController() {
3946
+ const {
3947
+ getRequestItems: _getRequestItems,
3948
+ getRequestItemById: _getRequestItemById
3949
+ } = useRequestItemRepository();
3950
+ const {
3951
+ createRequestItem: _createRequestItem,
3952
+ createRequestItemByBatch: _createRequestItemByBatch,
3953
+ approveRequestItem: _approveRequestItem,
3954
+ disapproveRequestItem: _disapproveRequestItem
3955
+ } = useRequestItemService();
3956
+ async function createRequestItem(req, res, next) {
3957
+ const cookies = req.headers.cookie ? req.headers.cookie.split(";").map((cookie) => cookie.trim().split("=")).reduce(
3958
+ (acc, [key, value]) => ({ ...acc, [key]: value }),
3959
+ {}
3960
+ ) : {};
3961
+ const createdBy = cookies["user"] || "";
3962
+ const payload = {
3963
+ ...req.body,
3964
+ ...req.params,
3965
+ createdBy
3966
+ };
3967
+ const validation = import_joi14.default.object({
3968
+ site: import_joi14.default.string().hex().required(),
3969
+ supply: import_joi14.default.string().hex().required(),
3970
+ qty: import_joi14.default.number().min(0).required(),
3971
+ createdBy: import_joi14.default.string().hex().required()
3972
+ });
3973
+ const { error } = validation.validate(payload);
3974
+ if (error) {
3975
+ import_node_server_utils26.logger.log({ level: "error", message: error.message });
3976
+ next(new import_node_server_utils26.BadRequestError(error.message));
3977
+ return;
3978
+ }
3979
+ try {
3980
+ const id = await _createRequestItem(payload);
3981
+ res.status(201).json({ message: "Request item created successfully.", id });
3982
+ return;
3983
+ } catch (error2) {
3984
+ import_node_server_utils26.logger.log({ level: "error", message: error2.message });
3985
+ next(error2);
3986
+ return;
3987
+ }
3988
+ }
3989
+ async function createRequestItemByBatch(req, res, next) {
3990
+ const cookies = req.headers.cookie ? req.headers.cookie.split(";").map((cookie) => cookie.trim().split("=")).reduce(
3991
+ (acc, [key, value]) => ({ ...acc, [key]: value }),
3992
+ {}
3993
+ ) : {};
3994
+ const createdBy = cookies["user"] || "";
3995
+ const payload = {
3996
+ ...req.body,
3997
+ ...req.params,
3998
+ createdBy
3999
+ };
4000
+ const validation = import_joi14.default.object({
4001
+ site: import_joi14.default.string().hex().required(),
4002
+ createdBy: import_joi14.default.string().hex().required(),
4003
+ items: import_joi14.default.array().items(
4004
+ import_joi14.default.object({
4005
+ supply: import_joi14.default.string().hex().required(),
4006
+ qty: import_joi14.default.number().min(0).required()
4007
+ })
4008
+ ).min(1).required()
4009
+ });
4010
+ const { error } = validation.validate(payload);
4011
+ if (error) {
4012
+ import_node_server_utils26.logger.log({ level: "error", message: error.message });
4013
+ next(new import_node_server_utils26.BadRequestError(error.message));
4014
+ return;
4015
+ }
4016
+ try {
4017
+ await _createRequestItemByBatch(payload);
4018
+ res.status(201).json({ message: "Request items created successfully." });
4019
+ return;
4020
+ } catch (error2) {
4021
+ import_node_server_utils26.logger.log({ level: "error", message: error2.message });
4022
+ next(error2);
4023
+ return;
4024
+ }
4025
+ }
4026
+ async function getRequestItems(req, res, next) {
4027
+ const query = { ...req.query, ...req.params };
4028
+ const validation = import_joi14.default.object({
4029
+ page: import_joi14.default.number().min(1).optional().allow("", null),
4030
+ limit: import_joi14.default.number().min(1).optional().allow("", null),
4031
+ search: import_joi14.default.string().optional().allow("", null),
4032
+ site: import_joi14.default.string().hex().required()
4033
+ });
4034
+ const { error } = validation.validate(query);
4035
+ if (error) {
4036
+ import_node_server_utils26.logger.log({ level: "error", message: error.message });
4037
+ next(new import_node_server_utils26.BadRequestError(error.message));
4038
+ return;
4039
+ }
4040
+ const page = parseInt(req.query.page) ?? 1;
4041
+ const limit = parseInt(req.query.limit) ?? 10;
4042
+ const search = req.query.search ?? "";
4043
+ const site = req.params.site ?? "";
4044
+ try {
4045
+ const data = await _getRequestItems({
4046
+ page,
4047
+ limit,
4048
+ search,
4049
+ site
4050
+ });
4051
+ res.json(data);
4052
+ return;
4053
+ } catch (error2) {
4054
+ import_node_server_utils26.logger.log({ level: "error", message: error2.message });
4055
+ next(error2);
4056
+ return;
4057
+ }
4058
+ }
4059
+ async function getRequestItemById(req, res, next) {
4060
+ const validation = import_joi14.default.string().hex().required();
4061
+ const _id = req.params.id;
4062
+ const { error } = validation.validate(_id);
4063
+ if (error) {
4064
+ import_node_server_utils26.logger.log({ level: "error", message: error.message });
4065
+ next(new import_node_server_utils26.BadRequestError(error.message));
4066
+ return;
4067
+ }
4068
+ try {
4069
+ const data = await _getRequestItemById(_id);
4070
+ res.json(data);
4071
+ return;
4072
+ } catch (error2) {
4073
+ import_node_server_utils26.logger.log({ level: "error", message: error2.message });
4074
+ next(error2);
4075
+ return;
4076
+ }
4077
+ }
4078
+ async function approveRequestItem(req, res, next) {
4079
+ const payload = { ...req.params, ...req.body };
4080
+ const validation = import_joi14.default.object({
4081
+ id: import_joi14.default.string().hex().required(),
4082
+ remarks: import_joi14.default.string().optional().allow("", null)
4083
+ });
4084
+ const { error } = validation.validate(payload);
4085
+ if (error) {
4086
+ import_node_server_utils26.logger.log({ level: "error", message: error.message });
4087
+ next(new import_node_server_utils26.BadRequestError(error.message));
4088
+ return;
4089
+ }
4090
+ try {
4091
+ await _approveRequestItem(payload.id, payload.remarks);
4092
+ res.json({ message: "Request item approved successfully." });
4093
+ return;
4094
+ } catch (error2) {
4095
+ import_node_server_utils26.logger.log({ level: "error", message: error2.message });
4096
+ next(error2);
4097
+ return;
4098
+ }
4099
+ }
4100
+ async function disapproveRequestItem(req, res, next) {
4101
+ const payload = { ...req.params, ...req.body };
4102
+ const validation = import_joi14.default.object({
4103
+ id: import_joi14.default.string().hex().required(),
4104
+ remarks: import_joi14.default.string().optional().allow("", null)
4105
+ });
4106
+ const { error } = validation.validate(payload);
4107
+ if (error) {
4108
+ import_node_server_utils26.logger.log({ level: "error", message: error.message });
4109
+ next(new import_node_server_utils26.BadRequestError(error.message));
4110
+ return;
4111
+ }
4112
+ try {
4113
+ await _disapproveRequestItem(payload.id, payload.remarks);
4114
+ res.json({ message: "Request item disapproved successfully." });
4115
+ return;
4116
+ } catch (error2) {
4117
+ import_node_server_utils26.logger.log({ level: "error", message: error2.message });
4118
+ next(error2);
4119
+ return;
4120
+ }
4121
+ }
4122
+ return {
4123
+ createRequestItem,
4124
+ createRequestItemByBatch,
4125
+ getRequestItems,
4126
+ getRequestItemById,
4127
+ approveRequestItem,
4128
+ disapproveRequestItem
4129
+ };
4130
+ }
4131
+
4132
+ // src/models/hygiene-schedule-task.model.ts
4133
+ var import_node_server_utils27 = require("@iservice365/node-server-utils");
4134
+ var import_joi15 = __toESM(require("joi"));
4135
+ var import_mongodb15 = require("mongodb");
4136
+ var allowedFrequency = ["week", "month", "quarter", "year"];
4137
+ var allowedDays = [
4138
+ "Mon",
4139
+ "Tue",
4140
+ "Wed",
4141
+ "Thu",
4142
+ "Fri",
4143
+ "Sat",
4144
+ "Sun"
4145
+ ];
4146
+ var allowedQuarter = ["1st", "2nd", "3rd", "4th"];
4147
+ var allowedWeekOfMonth = [
4148
+ "1st",
4149
+ "2nd",
4150
+ "3rd",
4151
+ "4th",
4152
+ "last"
4153
+ ];
4154
+ var allowedMonths = [
4155
+ "January",
4156
+ "February",
4157
+ "March",
4158
+ "April",
4159
+ "May",
4160
+ "June",
4161
+ "July",
4162
+ "August",
4163
+ "September",
4164
+ "October",
4165
+ "November",
4166
+ "December"
4167
+ ];
4168
+ var scheduleTaskSchema = import_joi15.default.object({
4169
+ site: import_joi15.default.string().hex().required(),
4170
+ title: import_joi15.default.string().required(),
4171
+ frequency: import_joi15.default.string().valid(...allowedFrequency).required(),
4172
+ day: import_joi15.default.string().valid(...allowedDays).required(),
4173
+ weekOfMonth: import_joi15.default.string().valid(...allowedWeekOfMonth).when("frequency", {
4174
+ is: import_joi15.default.string().valid("month", "quarter", "year"),
4175
+ then: import_joi15.default.required(),
4176
+ otherwise: import_joi15.default.optional().allow("", null)
4177
+ }),
4178
+ quarter: import_joi15.default.string().valid(...allowedQuarter).when("frequency", {
4179
+ is: "quarter",
4180
+ then: import_joi15.default.required(),
4181
+ otherwise: import_joi15.default.optional().allow("", null)
4182
+ }),
4183
+ month: import_joi15.default.string().valid(...allowedMonths).when("frequency", {
4184
+ is: import_joi15.default.string().valid("quarter", "year"),
4185
+ then: import_joi15.default.required(),
4186
+ otherwise: import_joi15.default.optional().allow("", null)
4187
+ }),
4188
+ description: import_joi15.default.string().optional().allow("", null),
4189
+ areas: import_joi15.default.array().min(1).items(
4190
+ import_joi15.default.object({
4191
+ name: import_joi15.default.string().required(),
4192
+ value: import_joi15.default.any().required()
4193
+ })
4194
+ ).required()
4195
+ });
4196
+ function MScheduleTask(value) {
4197
+ const { error } = scheduleTaskSchema.validate(value);
4198
+ if (error) {
4199
+ import_node_server_utils27.logger.info(`Hygiene Schedule Task Model: ${error.message}`);
4200
+ throw new import_node_server_utils27.BadRequestError(error.message);
4201
+ }
4202
+ if (value.site) {
4203
+ try {
4204
+ value.site = new import_mongodb15.ObjectId(value.site);
4205
+ } catch (error2) {
4206
+ throw new import_node_server_utils27.BadRequestError("Invalid site ID format.");
4207
+ }
4208
+ }
4209
+ if (value.areas && Array.isArray(value.areas)) {
4210
+ value.areas = value.areas.map((area) => {
4211
+ try {
4212
+ return {
4213
+ name: area.name,
4214
+ value: new import_mongodb15.ObjectId(area.value.toString())
4215
+ };
4216
+ } catch (error2) {
4217
+ throw new import_node_server_utils27.BadRequestError(`Invalid area value format: ${area.name}`);
4218
+ }
4219
+ });
4220
+ }
4221
+ return {
4222
+ site: value.site,
4223
+ title: value.title,
4224
+ frequency: value.frequency,
4225
+ day: value.day,
4226
+ weekOfMonth: value.weekOfMonth,
4227
+ quarter: value.quarter,
4228
+ month: value.month,
4229
+ description: value.description,
4230
+ areas: value.areas,
4231
+ status: "active",
4232
+ createdAt: /* @__PURE__ */ new Date(),
4233
+ updatedAt: "",
4234
+ deletedAt: ""
4235
+ };
4236
+ }
4237
+
4238
+ // src/repositories/hygiene-schedule-task.repository.ts
4239
+ var import_mongodb16 = require("mongodb");
4240
+ var import_node_server_utils28 = require("@iservice365/node-server-utils");
4241
+ function useScheduleTaskRepository() {
4242
+ const db = import_node_server_utils28.useAtlas.getDb();
4243
+ if (!db) {
4244
+ throw new import_node_server_utils28.InternalServerError("Unable to connect to server.");
4245
+ }
4246
+ const namespace_collection = "site.schedule-tasks";
4247
+ const collection = db.collection(namespace_collection);
4248
+ const { delNamespace, setCache, getCache } = (0, import_node_server_utils28.useCache)(namespace_collection);
4249
+ async function createIndex() {
4250
+ try {
4251
+ await collection.createIndexes([
4252
+ { key: { site: 1 } },
4253
+ { key: { status: 1 } }
4254
+ ]);
4255
+ } catch (error) {
4256
+ throw new import_node_server_utils28.InternalServerError(
4257
+ "Failed to create index on hygiene schedule task."
4258
+ );
4259
+ }
4260
+ }
4261
+ async function createTextIndex() {
4262
+ try {
4263
+ await collection.createIndex({ title: "text", description: "text" });
4264
+ } catch (error) {
4265
+ throw new import_node_server_utils28.InternalServerError(
4266
+ "Failed to create text index on hygiene schedule task."
4267
+ );
4268
+ }
4269
+ }
4270
+ async function createScheduleTask(value, session) {
4271
+ try {
4272
+ value = MScheduleTask(value);
4273
+ const res = await collection.insertOne(value, { session });
4274
+ delNamespace().then(() => {
4275
+ import_node_server_utils28.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
4276
+ }).catch((err) => {
4277
+ import_node_server_utils28.logger.error(
4278
+ `Failed to clear cache for namespace: ${namespace_collection}`,
4279
+ err
4280
+ );
4281
+ });
4282
+ return res.insertedId;
4283
+ } catch (error) {
4284
+ throw error;
4285
+ }
4286
+ }
4287
+ async function getScheduleTasks({
4288
+ page = 1,
4289
+ limit = 10,
4290
+ search = "",
4291
+ site
4292
+ }) {
4293
+ page = page > 0 ? page - 1 : 0;
4294
+ const query = {
4295
+ status: { $ne: "deleted" }
4296
+ };
4297
+ const cacheOptions = {
4298
+ page,
4299
+ limit
4300
+ };
4301
+ try {
4302
+ site = new import_mongodb16.ObjectId(site);
4303
+ query.site = site;
4304
+ cacheOptions.site = site.toString();
4305
+ } catch (error) {
4306
+ throw new import_node_server_utils28.BadRequestError("Invalid site ID format.");
4307
+ }
4308
+ if (search) {
4309
+ query.$or = [{ name: { $regex: search, $options: "i" } }];
4310
+ cacheOptions.search = search;
4311
+ }
4312
+ const cacheKey = (0, import_node_server_utils28.makeCacheKey)(namespace_collection, cacheOptions);
4313
+ const cachedData = await getCache(cacheKey);
4314
+ if (cachedData) {
4315
+ import_node_server_utils28.logger.info(`Cache hit for key: ${cacheKey}`);
4316
+ return cachedData;
4317
+ }
4318
+ try {
4319
+ const items = await collection.aggregate([
4320
+ { $match: query },
4321
+ {
4322
+ $project: {
4323
+ title: 1,
4324
+ areas: 1,
4325
+ status: 1
4326
+ }
4327
+ },
4328
+ { $sort: { _id: -1 } },
4329
+ { $skip: page * limit },
4330
+ { $limit: limit }
4331
+ ]).toArray();
4332
+ const length = await collection.countDocuments(query);
4333
+ const data = (0, import_node_server_utils28.paginate)(items, page, limit, length);
4334
+ setCache(cacheKey, data, 15 * 60).then(() => {
4335
+ import_node_server_utils28.logger.info(`Cache set for key: ${cacheKey}`);
4336
+ }).catch((err) => {
4337
+ import_node_server_utils28.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
4338
+ });
4339
+ return data;
4340
+ } catch (error) {
4341
+ throw error;
4342
+ }
4343
+ }
4344
+ async function getScheduleTaskById(_id, session) {
4345
+ try {
4346
+ _id = new import_mongodb16.ObjectId(_id);
4347
+ } catch (error) {
4348
+ throw new import_node_server_utils28.BadRequestError("Invalid schedule task ID format.");
4349
+ }
4350
+ const query = {
4351
+ _id,
4352
+ status: { $ne: "deleted" }
4353
+ };
4354
+ const cacheKey = (0, import_node_server_utils28.makeCacheKey)(namespace_collection, {
4355
+ _id: _id.toString()
4356
+ });
4357
+ if (!session) {
4358
+ const cachedData = await getCache(cacheKey);
4359
+ if (cachedData) {
4360
+ import_node_server_utils28.logger.info(`Cache hit for key: ${cacheKey}`);
4361
+ return cachedData;
4362
+ }
4363
+ } else {
4364
+ import_node_server_utils28.logger.info(`Skipping cache during transaction for key: ${cacheKey}`);
4365
+ }
4366
+ try {
4367
+ const data = await collection.aggregate([
4368
+ { $match: query },
4369
+ {
4370
+ $project: {
4371
+ title: 1,
4372
+ frequency: 1,
4373
+ day: 1,
4374
+ weekOfMonth: 1,
4375
+ quarter: 1,
4376
+ month: 1,
4377
+ description: 1,
4378
+ areas: 1,
4379
+ status: 1,
4380
+ createdAt: 1
4381
+ }
4382
+ }
4383
+ ]).toArray();
4384
+ if (!data || data.length === 0) {
4385
+ throw new import_node_server_utils28.NotFoundError("Schedule task not found.");
4386
+ }
4387
+ setCache(cacheKey, data[0], 15 * 60).then(() => {
4388
+ import_node_server_utils28.logger.info(`Cache set for key: ${cacheKey}`);
4389
+ }).catch((err) => {
4390
+ import_node_server_utils28.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
4391
+ });
4392
+ return data[0];
4393
+ } catch (error) {
4394
+ throw error;
4395
+ }
4396
+ }
4397
+ async function updateScheduleTask(_id, value, session) {
4398
+ try {
4399
+ _id = new import_mongodb16.ObjectId(_id);
4400
+ } catch (error) {
4401
+ throw new import_node_server_utils28.BadRequestError("Invalid schedule task ID format.");
4402
+ }
4403
+ if (value.areas && Array.isArray(value.areas)) {
4404
+ value.areas = value.areas.map((area) => {
4405
+ try {
4406
+ return {
4407
+ name: area.name,
4408
+ value: new import_mongodb16.ObjectId(area.value.toString())
4409
+ };
4410
+ } catch (error) {
4411
+ throw new import_node_server_utils28.BadRequestError(`Invalid area value format: ${area.name}`);
4412
+ }
4413
+ });
4414
+ }
4415
+ try {
4416
+ const updateValue = { ...value, updatedAt: /* @__PURE__ */ new Date() };
4417
+ const res = await collection.updateOne(
4418
+ { _id },
4419
+ { $set: updateValue },
4420
+ { session }
4421
+ );
4422
+ if (res.modifiedCount === 0) {
4423
+ throw new import_node_server_utils28.InternalServerError(
4424
+ "Unable to update hygiene schedule task."
4425
+ );
4426
+ }
4427
+ delNamespace().then(() => {
4428
+ import_node_server_utils28.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
4429
+ }).catch((err) => {
4430
+ import_node_server_utils28.logger.error(
4431
+ `Failed to clear cache for namespace: ${namespace_collection}`,
4432
+ err
4433
+ );
4434
+ });
4435
+ return res.modifiedCount;
4436
+ } catch (error) {
4437
+ throw error;
4438
+ }
4439
+ }
4440
+ return {
4441
+ createIndex,
4442
+ createTextIndex,
4443
+ createScheduleTask,
4444
+ getScheduleTasks,
4445
+ getScheduleTaskById,
4446
+ updateScheduleTask
4447
+ };
4448
+ }
4449
+
4450
+ // src/controllers/hygiene-schedule-task.controller.ts
4451
+ var import_node_server_utils29 = require("@iservice365/node-server-utils");
4452
+ var import_joi16 = __toESM(require("joi"));
4453
+ function useScheduleTaskController() {
4454
+ const {
4455
+ createScheduleTask: _createScheduleTask,
4456
+ getScheduleTasks: _getScheduleTasks,
4457
+ getScheduleTaskById: _getScheduleTaskById,
4458
+ updateScheduleTask: _updateScheduleTask
4459
+ } = useScheduleTaskRepository();
4460
+ async function createScheduleTask(req, res, next) {
4461
+ const payload = { ...req.body, ...req.params };
4462
+ const { error } = scheduleTaskSchema.validate(payload);
4463
+ if (error) {
4464
+ import_node_server_utils29.logger.log({ level: "error", message: error.message });
4465
+ next(new import_node_server_utils29.BadRequestError(error.message));
4466
+ return;
4467
+ }
4468
+ try {
4469
+ const id = await _createScheduleTask(payload);
4470
+ res.status(201).json({ message: "Schedule task created successfully.", id });
4471
+ return;
4472
+ } catch (error2) {
4473
+ import_node_server_utils29.logger.log({ level: "error", message: error2.message });
4474
+ next(error2);
4475
+ return;
4476
+ }
4477
+ }
4478
+ async function getScheduleTasks(req, res, next) {
4479
+ const query = { ...req.query, ...req.params };
4480
+ const validation = import_joi16.default.object({
4481
+ page: import_joi16.default.number().min(1).optional().allow("", null),
4482
+ limit: import_joi16.default.number().min(1).optional().allow("", null),
4483
+ search: import_joi16.default.string().optional().allow("", null),
4484
+ site: import_joi16.default.string().hex().required()
4485
+ });
4486
+ const { error } = validation.validate(query);
4487
+ if (error) {
4488
+ import_node_server_utils29.logger.log({ level: "error", message: error.message });
4489
+ next(new import_node_server_utils29.BadRequestError(error.message));
4490
+ return;
4491
+ }
4492
+ const page = parseInt(req.query.page) ?? 1;
4493
+ const limit = parseInt(req.query.limit) ?? 10;
4494
+ const search = req.query.search ?? "";
4495
+ const site = req.params.site ?? "";
4496
+ try {
4497
+ const data = await _getScheduleTasks({
4498
+ page,
4499
+ limit,
4500
+ search,
4501
+ site
4502
+ });
4503
+ res.json(data);
4504
+ return;
4505
+ } catch (error2) {
4506
+ import_node_server_utils29.logger.log({ level: "error", message: error2.message });
4507
+ next(error2);
4508
+ return;
4509
+ }
4510
+ }
4511
+ async function getScheduleTaskById(req, res, next) {
4512
+ const validation = import_joi16.default.string().hex().required();
4513
+ const _id = req.params.id;
4514
+ const { error } = validation.validate(_id);
4515
+ if (error) {
4516
+ import_node_server_utils29.logger.log({ level: "error", message: error.message });
4517
+ next(new import_node_server_utils29.BadRequestError(error.message));
4518
+ return;
4519
+ }
4520
+ try {
4521
+ const data = await _getScheduleTaskById(_id);
4522
+ res.json(data);
4523
+ return;
4524
+ } catch (error2) {
4525
+ import_node_server_utils29.logger.log({ level: "error", message: error2.message });
4526
+ next(error2);
4527
+ return;
4528
+ }
4529
+ }
4530
+ async function updateScheduleTask(req, res, next) {
4531
+ const payload = { id: req.params.id, ...req.body };
4532
+ const validation = import_joi16.default.object({
4533
+ id: import_joi16.default.string().hex().required(),
4534
+ title: import_joi16.default.string().optional().allow("", null),
4535
+ frequency: import_joi16.default.string().valid(...allowedFrequency).optional().allow("", null),
4536
+ day: import_joi16.default.string().valid(...allowedDays).optional().allow("", null),
4537
+ weekOfMonth: import_joi16.default.string().valid(...allowedWeekOfMonth).optional().allow("", null),
4538
+ quarter: import_joi16.default.string().valid(...allowedQuarter).optional().allow("", null),
4539
+ month: import_joi16.default.string().valid(...allowedMonths).optional().allow("", null),
4540
+ description: import_joi16.default.string().optional().allow("", null),
4541
+ areas: import_joi16.default.array().min(1).items(
4542
+ import_joi16.default.object({
4543
+ name: import_joi16.default.string().required(),
4544
+ value: import_joi16.default.any().required()
4545
+ })
4546
+ ).optional()
4547
+ });
4548
+ const { error } = validation.validate(payload);
4549
+ if (error) {
4550
+ import_node_server_utils29.logger.log({ level: "error", message: error.message });
4551
+ next(new import_node_server_utils29.BadRequestError(error.message));
4552
+ return;
4553
+ }
4554
+ try {
4555
+ const { id, ...value } = payload;
4556
+ await _updateScheduleTask(id, value);
4557
+ res.json({ message: "Schedule task updated successfully." });
4558
+ return;
4559
+ } catch (error2) {
4560
+ import_node_server_utils29.logger.log({ level: "error", message: error2.message });
3413
4561
  next(error2);
3414
4562
  return;
3415
4563
  }
3416
4564
  }
3417
4565
  return {
3418
- createStock
4566
+ createScheduleTask,
4567
+ getScheduleTasks,
4568
+ getScheduleTaskById,
4569
+ updateScheduleTask
3419
4570
  };
3420
4571
  }
3421
4572
  // Annotate the CommonJS export names for ESM import in node:
@@ -3423,15 +4574,25 @@ function useStockController() {
3423
4574
  MArea,
3424
4575
  MAreaChecklist,
3425
4576
  MParentChecklist,
4577
+ MRequestItem,
4578
+ MScheduleTask,
3426
4579
  MStock,
3427
4580
  MSupply,
3428
4581
  MUnit,
3429
4582
  allowedChecklistStatus,
4583
+ allowedDays,
4584
+ allowedFrequency,
4585
+ allowedMonths,
4586
+ allowedQuarter,
4587
+ allowedRequestItemStatus,
3430
4588
  allowedStatus,
3431
4589
  allowedTypes,
4590
+ allowedWeekOfMonth,
3432
4591
  areaChecklistSchema,
3433
4592
  areaSchema,
3434
4593
  parentChecklistSchema,
4594
+ requestItemSchema,
4595
+ scheduleTaskSchema,
3435
4596
  stockSchema,
3436
4597
  supplySchema,
3437
4598
  unitSchema,
@@ -3443,12 +4604,16 @@ function useStockController() {
3443
4604
  useAreaService,
3444
4605
  useParentChecklistController,
3445
4606
  useParentChecklistRepo,
4607
+ useRequestItemController,
4608
+ useRequestItemRepository,
4609
+ useRequestItemService,
4610
+ useScheduleTaskController,
4611
+ useScheduleTaskRepository,
3446
4612
  useStockController,
3447
4613
  useStockRepository,
3448
4614
  useStockService,
3449
4615
  useSupplyController,
3450
4616
  useSupplyRepository,
3451
- useSupplyService,
3452
4617
  useUnitController,
3453
4618
  useUnitRepository,
3454
4619
  useUnitService