@iservice365/module-hygiene 1.0.2 → 1.1.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,14 +33,19 @@ __export(src_exports, {
33
33
  MArea: () => MArea,
34
34
  MAreaChecklist: () => MAreaChecklist,
35
35
  MParentChecklist: () => MParentChecklist,
36
+ MRequestItem: () => MRequestItem,
37
+ MStock: () => MStock,
36
38
  MSupply: () => MSupply,
37
39
  MUnit: () => MUnit,
38
40
  allowedChecklistStatus: () => allowedChecklistStatus,
41
+ allowedRequestItemStatus: () => allowedRequestItemStatus,
39
42
  allowedStatus: () => allowedStatus,
40
43
  allowedTypes: () => allowedTypes,
41
44
  areaChecklistSchema: () => areaChecklistSchema,
42
45
  areaSchema: () => areaSchema,
43
46
  parentChecklistSchema: () => parentChecklistSchema,
47
+ requestItemSchema: () => requestItemSchema,
48
+ stockSchema: () => stockSchema,
44
49
  supplySchema: () => supplySchema,
45
50
  unitSchema: () => unitSchema,
46
51
  useAreaChecklistController: () => useAreaChecklistController,
@@ -51,6 +56,12 @@ __export(src_exports, {
51
56
  useAreaService: () => useAreaService,
52
57
  useParentChecklistController: () => useParentChecklistController,
53
58
  useParentChecklistRepo: () => useParentChecklistRepo,
59
+ useRequestItemController: () => useRequestItemController,
60
+ useRequestItemRepository: () => useRequestItemRepository,
61
+ useRequestItemService: () => useRequestItemService,
62
+ useStockController: () => useStockController,
63
+ useStockRepository: () => useStockRepository,
64
+ useStockService: () => useStockService,
54
65
  useSupplyController: () => useSupplyController,
55
66
  useSupplyRepository: () => useSupplyRepository,
56
67
  useUnitController: () => useUnitController,
@@ -692,7 +703,7 @@ function useAreaController() {
692
703
  return;
693
704
  }
694
705
  const page = parseInt(req.query.page) ?? 1;
695
- const limit = parseInt(req.query.limit) ?? 20;
706
+ const limit = parseInt(req.query.limit) ?? 10;
696
707
  const search = req.query.search ?? "";
697
708
  const site = req.params.site ?? "";
698
709
  try {
@@ -1228,7 +1239,7 @@ function useUnitController() {
1228
1239
  return;
1229
1240
  }
1230
1241
  const page = parseInt(req.query.page) ?? 1;
1231
- const limit = parseInt(req.query.limit) ?? 20;
1242
+ const limit = parseInt(req.query.limit) ?? 10;
1232
1243
  const search = req.query.search ?? "";
1233
1244
  const site = req.params.site ?? "";
1234
1245
  try {
@@ -1634,7 +1645,7 @@ function useParentChecklistController() {
1634
1645
  return;
1635
1646
  }
1636
1647
  const page = parseInt(req.query.page) ?? 1;
1637
- const limit = parseInt(req.query.limit) ?? 20;
1648
+ const limit = parseInt(req.query.limit) ?? 10;
1638
1649
  const search = req.query.search ?? "";
1639
1650
  const site = req.params.site ?? "";
1640
1651
  const startDate = req.query.startDate ?? "";
@@ -2645,7 +2656,7 @@ function useAreaChecklistController() {
2645
2656
  return;
2646
2657
  }
2647
2658
  const page = parseInt(req.query.page) ?? 1;
2648
- const limit = parseInt(req.query.limit) ?? 20;
2659
+ const limit = parseInt(req.query.limit) ?? 10;
2649
2660
  const search = req.query.search ?? "";
2650
2661
  const type = req.query.type ?? "";
2651
2662
  const schedule = req.params.schedule ?? "";
@@ -2683,7 +2694,7 @@ function useAreaChecklistController() {
2683
2694
  return;
2684
2695
  }
2685
2696
  const page = parseInt(req.query.page) ?? 1;
2686
- const limit = parseInt(req.query.limit) ?? 20;
2697
+ const limit = parseInt(req.query.limit) ?? 10;
2687
2698
  const search = req.query.search ?? "";
2688
2699
  const type = req.query.type ?? "";
2689
2700
  const schedule = req.params.schedule ?? "";
@@ -2741,7 +2752,7 @@ function useAreaChecklistController() {
2741
2752
  return;
2742
2753
  }
2743
2754
  const page = parseInt(req.query.page) ?? 1;
2744
- const limit = parseInt(req.query.limit) ?? 20;
2755
+ const limit = parseInt(req.query.limit) ?? 10;
2745
2756
  const search = req.query.search ?? "";
2746
2757
  const _id = req.params.id ?? "";
2747
2758
  try {
@@ -2816,8 +2827,7 @@ var import_mongodb9 = require("mongodb");
2816
2827
  var supplySchema = import_joi9.default.object({
2817
2828
  site: import_joi9.default.string().hex().required(),
2818
2829
  name: import_joi9.default.string().required(),
2819
- unitOfMeasurement: import_joi9.default.string().required(),
2820
- qty: import_joi9.default.number().min(0).required()
2830
+ unitOfMeasurement: import_joi9.default.string().required()
2821
2831
  });
2822
2832
  function MSupply(value) {
2823
2833
  const { error } = supplySchema.validate(value);
@@ -2836,9 +2846,9 @@ function MSupply(value) {
2836
2846
  site: value.site,
2837
2847
  name: value.name,
2838
2848
  unitOfMeasurement: value.unitOfMeasurement,
2839
- qty: value.qty,
2840
- createdAt: /* @__PURE__ */ new Date(),
2849
+ qty: 0,
2841
2850
  status: "active",
2851
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
2842
2852
  updatedAt: "",
2843
2853
  deletedAt: ""
2844
2854
  };
@@ -2962,7 +2972,7 @@ function useSupplyRepository() {
2962
2972
  throw error;
2963
2973
  }
2964
2974
  }
2965
- async function getSupplyById(_id) {
2975
+ async function getSupplyById(_id, session) {
2966
2976
  try {
2967
2977
  _id = new import_mongodb10.ObjectId(_id);
2968
2978
  } catch (error) {
@@ -2975,10 +2985,14 @@ function useSupplyRepository() {
2975
2985
  const cacheKey = (0, import_node_server_utils17.makeCacheKey)(namespace_collection, {
2976
2986
  _id: _id.toString()
2977
2987
  });
2978
- const cachedData = await getCache(cacheKey);
2979
- if (cachedData) {
2980
- import_node_server_utils17.logger.info(`Cache hit for key: ${cacheKey}`);
2981
- return cachedData;
2988
+ if (!session) {
2989
+ const cachedData = await getCache(cacheKey);
2990
+ if (cachedData) {
2991
+ import_node_server_utils17.logger.info(`Cache hit for key: ${cacheKey}`);
2992
+ return cachedData;
2993
+ }
2994
+ } else {
2995
+ import_node_server_utils17.logger.info(`Skipping cache during transaction for key: ${cacheKey}`);
2982
2996
  }
2983
2997
  try {
2984
2998
  const data = await collection.aggregate([
@@ -3126,7 +3140,7 @@ function useSupplyController() {
3126
3140
  return;
3127
3141
  }
3128
3142
  const page = parseInt(req.query.page) ?? 1;
3129
- const limit = parseInt(req.query.limit) ?? 20;
3143
+ const limit = parseInt(req.query.limit) ?? 10;
3130
3144
  const search = req.query.search ?? "";
3131
3145
  const site = req.params.site ?? "";
3132
3146
  try {
@@ -3217,19 +3231,648 @@ function useSupplyController() {
3217
3231
  deleteSupply
3218
3232
  };
3219
3233
  }
3234
+
3235
+ // src/models/hygiene-stock.model.ts
3236
+ var import_node_server_utils19 = require("@iservice365/node-server-utils");
3237
+ var import_joi11 = __toESM(require("joi"));
3238
+ var import_mongodb11 = require("mongodb");
3239
+ var stockSchema = import_joi11.default.object({
3240
+ site: import_joi11.default.string().hex().required(),
3241
+ supply: import_joi11.default.string().hex().required(),
3242
+ in: import_joi11.default.number().min(0).optional(),
3243
+ out: import_joi11.default.number().min(0).optional(),
3244
+ balance: import_joi11.default.number().min(0).required(),
3245
+ remarks: import_joi11.default.string().optional().allow("", null)
3246
+ });
3247
+ function MStock(value) {
3248
+ const { error } = stockSchema.validate(value);
3249
+ if (error) {
3250
+ import_node_server_utils19.logger.info(`Hygiene Stock Model: ${error.message}`);
3251
+ throw new import_node_server_utils19.BadRequestError(error.message);
3252
+ }
3253
+ if (value.site) {
3254
+ try {
3255
+ value.site = new import_mongodb11.ObjectId(value.site);
3256
+ } catch (error2) {
3257
+ throw new import_node_server_utils19.BadRequestError("Invalid site ID format.");
3258
+ }
3259
+ }
3260
+ if (value.supply) {
3261
+ try {
3262
+ value.supply = new import_mongodb11.ObjectId(value.supply);
3263
+ } catch (error2) {
3264
+ throw new import_node_server_utils19.BadRequestError("Invalid supply ID format.");
3265
+ }
3266
+ }
3267
+ return {
3268
+ site: value.site,
3269
+ supply: value.supply,
3270
+ in: value.in ?? 0,
3271
+ out: value.out ?? 0,
3272
+ balance: value.balance,
3273
+ remarks: value.remarks ?? "",
3274
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
3275
+ status: "active",
3276
+ updatedAt: "",
3277
+ deletedAt: ""
3278
+ };
3279
+ }
3280
+
3281
+ // src/repositories/hygiene-stock.repository.ts
3282
+ var import_mongodb12 = require("mongodb");
3283
+ var import_node_server_utils20 = require("@iservice365/node-server-utils");
3284
+ function useStockRepository() {
3285
+ const db = import_node_server_utils20.useAtlas.getDb();
3286
+ if (!db) {
3287
+ throw new import_node_server_utils20.InternalServerError("Unable to connect to server.");
3288
+ }
3289
+ const namespace_collection = "site.supply.stocks";
3290
+ const supply_collection = "site.supplies";
3291
+ const collection = db.collection(namespace_collection);
3292
+ const { delNamespace, setCache, getCache } = (0, import_node_server_utils20.useCache)(namespace_collection);
3293
+ const { delNamespace: delSupplyNamespace } = (0, import_node_server_utils20.useCache)(supply_collection);
3294
+ async function createIndex() {
3295
+ try {
3296
+ await collection.createIndexes([
3297
+ { key: { site: 1 } },
3298
+ { key: { supply: 1 } },
3299
+ { key: { balance: 1 } },
3300
+ { key: { status: 1 } }
3301
+ ]);
3302
+ } catch (error) {
3303
+ throw new import_node_server_utils20.InternalServerError("Failed to create index on hygiene stock.");
3304
+ }
3305
+ }
3306
+ async function createStock(value, session) {
3307
+ try {
3308
+ value = MStock(value);
3309
+ const res = await collection.insertOne(value, { session });
3310
+ delNamespace().then(() => {
3311
+ import_node_server_utils20.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
3312
+ }).catch((err) => {
3313
+ import_node_server_utils20.logger.error(
3314
+ `Failed to clear cache for namespace: ${namespace_collection}`,
3315
+ err
3316
+ );
3317
+ });
3318
+ delSupplyNamespace().then(() => {
3319
+ import_node_server_utils20.logger.info(`Cache cleared for namespace: ${supply_collection}`);
3320
+ }).catch((err) => {
3321
+ import_node_server_utils20.logger.error(
3322
+ `Failed to clear cache for namespace: ${supply_collection}`,
3323
+ err
3324
+ );
3325
+ });
3326
+ return res.insertedId;
3327
+ } catch (error) {
3328
+ throw error;
3329
+ }
3330
+ }
3331
+ async function getStocksBySupplyId({
3332
+ page = 1,
3333
+ limit = 10,
3334
+ search = "",
3335
+ site,
3336
+ supply
3337
+ }) {
3338
+ page = page > 0 ? page - 1 : 0;
3339
+ const query = {
3340
+ status: { $ne: "deleted" }
3341
+ };
3342
+ const cacheOptions = {
3343
+ page,
3344
+ limit
3345
+ };
3346
+ try {
3347
+ site = new import_mongodb12.ObjectId(site);
3348
+ query.site = site;
3349
+ cacheOptions.site = site.toString();
3350
+ } catch (error) {
3351
+ throw new import_node_server_utils20.BadRequestError("Invalid site ID format.");
3352
+ }
3353
+ try {
3354
+ supply = new import_mongodb12.ObjectId(supply);
3355
+ query.supply = supply;
3356
+ cacheOptions.supply = supply.toString();
3357
+ } catch (error) {
3358
+ throw new import_node_server_utils20.BadRequestError("Invalid supply ID format.");
3359
+ }
3360
+ if (search) {
3361
+ query.$text = { $search: search };
3362
+ cacheOptions.search = search;
3363
+ }
3364
+ const cacheKey = (0, import_node_server_utils20.makeCacheKey)(namespace_collection, cacheOptions);
3365
+ const cachedData = await getCache(cacheKey);
3366
+ if (cachedData) {
3367
+ import_node_server_utils20.logger.info(`Cache hit for key: ${cacheKey}`);
3368
+ return cachedData;
3369
+ }
3370
+ try {
3371
+ const items = await collection.aggregate([
3372
+ { $match: query },
3373
+ {
3374
+ $project: {
3375
+ createdAt: 1,
3376
+ in: 1,
3377
+ out: 1,
3378
+ balance: 1
3379
+ }
3380
+ },
3381
+ { $sort: { _id: 1 } },
3382
+ { $skip: page * limit },
3383
+ { $limit: limit }
3384
+ ]).toArray();
3385
+ const length = await collection.countDocuments(query);
3386
+ const data = (0, import_node_server_utils20.paginate)(items, page, limit, length);
3387
+ setCache(cacheKey, data, 15 * 60).then(() => {
3388
+ import_node_server_utils20.logger.info(`Cache set for key: ${cacheKey}`);
3389
+ }).catch((err) => {
3390
+ import_node_server_utils20.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
3391
+ });
3392
+ return data;
3393
+ } catch (error) {
3394
+ throw error;
3395
+ }
3396
+ }
3397
+ return {
3398
+ createIndex,
3399
+ createStock,
3400
+ getStocksBySupplyId
3401
+ };
3402
+ }
3403
+
3404
+ // src/services/hygiene-stock.service.ts
3405
+ var import_node_server_utils21 = require("@iservice365/node-server-utils");
3406
+ function useStockService() {
3407
+ const { createStock: _createStock } = useStockRepository();
3408
+ const { getSupplyById, updateSupply } = useSupplyRepository();
3409
+ async function createStock(value, out = false) {
3410
+ const session = import_node_server_utils21.useAtlas.getClient()?.startSession();
3411
+ try {
3412
+ session?.startTransaction();
3413
+ const { qty, ...stockData } = value;
3414
+ const supply = await getSupplyById(value.supply, session);
3415
+ if (!supply || supply.qty === void 0) {
3416
+ throw new import_node_server_utils21.NotFoundError("Supply not found.");
3417
+ }
3418
+ const newSupplyQty = out ? supply.qty - qty : supply.qty + qty;
3419
+ if (out && newSupplyQty < 0) {
3420
+ throw new import_node_server_utils21.BadRequestError(
3421
+ `Insufficient stock. Available: ${supply.qty}, Requested: ${qty}`
3422
+ );
3423
+ }
3424
+ await updateSupply(value.supply, { qty: newSupplyQty }, session);
3425
+ const createdStock = await _createStock(
3426
+ {
3427
+ ...stockData,
3428
+ in: out ? 0 : qty,
3429
+ out: out ? qty : 0,
3430
+ balance: newSupplyQty
3431
+ },
3432
+ session
3433
+ );
3434
+ await session?.commitTransaction();
3435
+ return createdStock;
3436
+ } catch (error) {
3437
+ await session?.abortTransaction();
3438
+ throw error;
3439
+ } finally {
3440
+ await session?.endSession();
3441
+ }
3442
+ }
3443
+ return { createStock };
3444
+ }
3445
+
3446
+ // src/controllers/hygiene-stock.controller.ts
3447
+ var import_node_server_utils22 = require("@iservice365/node-server-utils");
3448
+ var import_joi12 = __toESM(require("joi"));
3449
+ function useStockController() {
3450
+ const { getStocksBySupplyId: _getStocksBySupplyId } = useStockRepository();
3451
+ const { createStock: _createStock } = useStockService();
3452
+ async function createStock(req, res, next) {
3453
+ const payload = { ...req.body, ...req.params };
3454
+ const validation = import_joi12.default.object({
3455
+ site: import_joi12.default.string().hex().required(),
3456
+ supply: import_joi12.default.string().hex().required(),
3457
+ qty: import_joi12.default.number().min(0).required(),
3458
+ remarks: import_joi12.default.string().optional().allow("", null)
3459
+ });
3460
+ const { error } = validation.validate(payload);
3461
+ if (error) {
3462
+ import_node_server_utils22.logger.log({ level: "error", message: error.message });
3463
+ next(new import_node_server_utils22.BadRequestError(error.message));
3464
+ return;
3465
+ }
3466
+ try {
3467
+ const id = await _createStock(payload);
3468
+ res.status(201).json({ message: "Stock created successfully.", id });
3469
+ return;
3470
+ } catch (error2) {
3471
+ import_node_server_utils22.logger.log({ level: "error", message: error2.message });
3472
+ next(error2);
3473
+ return;
3474
+ }
3475
+ }
3476
+ async function getStocksBySupplyId(req, res, next) {
3477
+ const query = { ...req.query, ...req.params };
3478
+ const validation = import_joi12.default.object({
3479
+ page: import_joi12.default.number().min(1).optional().allow("", null),
3480
+ limit: import_joi12.default.number().min(1).optional().allow("", null),
3481
+ search: import_joi12.default.string().optional().allow("", null),
3482
+ site: import_joi12.default.string().hex().required(),
3483
+ supply: import_joi12.default.string().hex().required()
3484
+ });
3485
+ const { error } = validation.validate(query);
3486
+ if (error) {
3487
+ import_node_server_utils22.logger.log({ level: "error", message: error.message });
3488
+ next(new import_node_server_utils22.BadRequestError(error.message));
3489
+ return;
3490
+ }
3491
+ const page = parseInt(req.query.page) ?? 1;
3492
+ const limit = parseInt(req.query.limit) ?? 10;
3493
+ const search = req.query.search ?? "";
3494
+ const site = req.params.site ?? "";
3495
+ const supply = req.params.supply ?? "";
3496
+ try {
3497
+ const data = await _getStocksBySupplyId({
3498
+ page,
3499
+ limit,
3500
+ search,
3501
+ site,
3502
+ supply
3503
+ });
3504
+ res.json(data);
3505
+ return;
3506
+ } catch (error2) {
3507
+ import_node_server_utils22.logger.log({ level: "error", message: error2.message });
3508
+ next(error2);
3509
+ return;
3510
+ }
3511
+ }
3512
+ return {
3513
+ createStock,
3514
+ getStocksBySupplyId
3515
+ };
3516
+ }
3517
+
3518
+ // src/models/hygiene-request-item.model.ts
3519
+ var import_node_server_utils23 = require("@iservice365/node-server-utils");
3520
+ var import_joi13 = __toESM(require("joi"));
3521
+ var import_mongodb13 = require("mongodb");
3522
+ var allowedRequestItemStatus = [
3523
+ "pending",
3524
+ "approved",
3525
+ "disapproved"
3526
+ ];
3527
+ var requestItemSchema = import_joi13.default.object({
3528
+ site: import_joi13.default.string().hex().required(),
3529
+ supply: import_joi13.default.string().hex().required(),
3530
+ supplyName: import_joi13.default.string().required(),
3531
+ qty: import_joi13.default.number().min(0).required(),
3532
+ createdBy: import_joi13.default.string().hex().required(),
3533
+ createdByName: import_joi13.default.string().required()
3534
+ });
3535
+ function MRequestItem(value) {
3536
+ const { error } = requestItemSchema.validate(value);
3537
+ if (error) {
3538
+ import_node_server_utils23.logger.info(`Hygiene Request Item Model: ${error.message}`);
3539
+ throw new import_node_server_utils23.BadRequestError(error.message);
3540
+ }
3541
+ if (value.site) {
3542
+ try {
3543
+ value.site = new import_mongodb13.ObjectId(value.site);
3544
+ } catch (error2) {
3545
+ throw new import_node_server_utils23.BadRequestError("Invalid site ID format.");
3546
+ }
3547
+ }
3548
+ if (value.supply) {
3549
+ try {
3550
+ value.supply = new import_mongodb13.ObjectId(value.supply);
3551
+ } catch (error2) {
3552
+ throw new import_node_server_utils23.BadRequestError("Invalid supply ID format.");
3553
+ }
3554
+ }
3555
+ return {
3556
+ site: value.site,
3557
+ supply: value.supply,
3558
+ supplyName: value.supplyName,
3559
+ qty: value.qty,
3560
+ remarks: "",
3561
+ createdBy: value.createdBy,
3562
+ createdByName: value.createdByName,
3563
+ status: "pending",
3564
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
3565
+ updatedAt: "",
3566
+ deletedAt: ""
3567
+ };
3568
+ }
3569
+
3570
+ // src/repositories/hygiene-request-item.repository.ts
3571
+ var import_mongodb14 = require("mongodb");
3572
+ var import_node_server_utils24 = require("@iservice365/node-server-utils");
3573
+ function useRequestItemRepository() {
3574
+ const db = import_node_server_utils24.useAtlas.getDb();
3575
+ if (!db) {
3576
+ throw new import_node_server_utils24.InternalServerError("Unable to connect to server.");
3577
+ }
3578
+ const namespace_collection = "site.supply.requests";
3579
+ const collection = db.collection(namespace_collection);
3580
+ const { delNamespace, setCache, getCache } = (0, import_node_server_utils24.useCache)(namespace_collection);
3581
+ async function createIndex() {
3582
+ try {
3583
+ await collection.createIndexes([
3584
+ { key: { site: 1 } },
3585
+ { key: { supply: 1 } },
3586
+ { key: { status: 1 } }
3587
+ ]);
3588
+ } catch (error) {
3589
+ throw new import_node_server_utils24.InternalServerError(
3590
+ "Failed to create index on hygiene request item."
3591
+ );
3592
+ }
3593
+ }
3594
+ async function createTextIndex() {
3595
+ try {
3596
+ await collection.createIndex({ supplyName: "text" });
3597
+ } catch (error) {
3598
+ throw new import_node_server_utils24.InternalServerError(
3599
+ "Failed to create text index on hygiene supply."
3600
+ );
3601
+ }
3602
+ }
3603
+ async function createRequestItem(value, session) {
3604
+ try {
3605
+ value = MRequestItem(value);
3606
+ const res = await collection.insertOne(value, { session });
3607
+ delNamespace().then(() => {
3608
+ import_node_server_utils24.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
3609
+ }).catch((err) => {
3610
+ import_node_server_utils24.logger.error(
3611
+ `Failed to clear cache for namespace: ${namespace_collection}`,
3612
+ err
3613
+ );
3614
+ });
3615
+ return res.insertedId;
3616
+ } catch (error) {
3617
+ throw error;
3618
+ }
3619
+ }
3620
+ async function getRequestItems({
3621
+ page = 1,
3622
+ limit = 10,
3623
+ search = "",
3624
+ site
3625
+ }) {
3626
+ page = page > 0 ? page - 1 : 0;
3627
+ const query = {
3628
+ status: { $ne: "deleted" }
3629
+ };
3630
+ const cacheOptions = {
3631
+ page,
3632
+ limit
3633
+ };
3634
+ try {
3635
+ site = new import_mongodb14.ObjectId(site);
3636
+ query.site = site;
3637
+ cacheOptions.site = site.toString();
3638
+ } catch (error) {
3639
+ throw new import_node_server_utils24.BadRequestError("Invalid site ID format.");
3640
+ }
3641
+ if (search) {
3642
+ query.$text = { $search: search };
3643
+ cacheOptions.search = search;
3644
+ }
3645
+ const cacheKey = (0, import_node_server_utils24.makeCacheKey)(namespace_collection, cacheOptions);
3646
+ const cachedData = await getCache(cacheKey);
3647
+ if (cachedData) {
3648
+ import_node_server_utils24.logger.info(`Cache hit for key: ${cacheKey}`);
3649
+ return cachedData;
3650
+ }
3651
+ try {
3652
+ const items = await collection.aggregate([
3653
+ { $match: query },
3654
+ {
3655
+ $project: {
3656
+ createdAt: 1,
3657
+ status: 1
3658
+ }
3659
+ },
3660
+ { $sort: { _id: 1 } },
3661
+ { $skip: page * limit },
3662
+ { $limit: limit }
3663
+ ]).toArray();
3664
+ const length = await collection.countDocuments(query);
3665
+ const data = (0, import_node_server_utils24.paginate)(items, page, limit, length);
3666
+ setCache(cacheKey, data, 15 * 60).then(() => {
3667
+ import_node_server_utils24.logger.info(`Cache set for key: ${cacheKey}`);
3668
+ }).catch((err) => {
3669
+ import_node_server_utils24.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
3670
+ });
3671
+ return data;
3672
+ } catch (error) {
3673
+ throw error;
3674
+ }
3675
+ }
3676
+ return {
3677
+ createIndex,
3678
+ createTextIndex,
3679
+ createRequestItem,
3680
+ getRequestItems
3681
+ };
3682
+ }
3683
+
3684
+ // src/services/hygiene-request-item.service.ts
3685
+ var import_node_server_utils25 = require("@iservice365/node-server-utils");
3686
+ var import_core = require("@iservice365/core");
3687
+ function useRequestItemService() {
3688
+ const { createRequestItem: _createRequestItem } = useRequestItemRepository();
3689
+ const { getSupplyById } = useSupplyRepository();
3690
+ const { getUserById } = (0, import_core.useUserRepo)();
3691
+ async function createRequestItem(value) {
3692
+ try {
3693
+ const { supply, createdBy } = value;
3694
+ const supplyData = await getSupplyById(supply);
3695
+ const createdByData = await getUserById(createdBy);
3696
+ const createdRequestItem = await _createRequestItem({
3697
+ ...value,
3698
+ supplyName: supplyData?.name || "",
3699
+ createdByName: createdByData?.name || ""
3700
+ });
3701
+ return createdRequestItem;
3702
+ } catch (error) {
3703
+ throw error;
3704
+ }
3705
+ }
3706
+ async function createRequestItemByBatch(value) {
3707
+ const session = import_node_server_utils25.useAtlas.getClient()?.startSession();
3708
+ try {
3709
+ session?.startTransaction();
3710
+ const { site, createdBy, items } = value;
3711
+ const createdByData = await getUserById(createdBy);
3712
+ const createdRequestItemIds = [];
3713
+ for (const item of items) {
3714
+ const supplyData = await getSupplyById(item.supply, session);
3715
+ const createdId = await _createRequestItem(
3716
+ {
3717
+ site,
3718
+ supply: item.supply,
3719
+ qty: item.qty,
3720
+ supplyName: supplyData?.name || "",
3721
+ createdBy,
3722
+ createdByName: createdByData?.name || ""
3723
+ },
3724
+ session
3725
+ );
3726
+ createdRequestItemIds.push(createdId);
3727
+ }
3728
+ await session?.commitTransaction();
3729
+ return createdRequestItemIds;
3730
+ } catch (error) {
3731
+ await session?.abortTransaction();
3732
+ throw error;
3733
+ } finally {
3734
+ await session?.endSession();
3735
+ }
3736
+ }
3737
+ return { createRequestItem, createRequestItemByBatch };
3738
+ }
3739
+
3740
+ // src/controllers/hygiene-request-item.controller.ts
3741
+ var import_node_server_utils26 = require("@iservice365/node-server-utils");
3742
+ var import_joi14 = __toESM(require("joi"));
3743
+ function useRequestItemController() {
3744
+ const { getRequestItems: _getRequestItems } = useRequestItemRepository();
3745
+ const {
3746
+ createRequestItem: _createRequestItem,
3747
+ createRequestItemByBatch: _createRequestItemByBatch
3748
+ } = useRequestItemService();
3749
+ async function createRequestItem(req, res, next) {
3750
+ const cookies = req.headers.cookie ? req.headers.cookie.split(";").map((cookie) => cookie.trim().split("=")).reduce(
3751
+ (acc, [key, value]) => ({ ...acc, [key]: value }),
3752
+ {}
3753
+ ) : {};
3754
+ const createdBy = cookies["user"] || "";
3755
+ const payload = {
3756
+ ...req.body,
3757
+ ...req.params,
3758
+ createdBy
3759
+ };
3760
+ const validation = import_joi14.default.object({
3761
+ site: import_joi14.default.string().hex().required(),
3762
+ supply: import_joi14.default.string().hex().required(),
3763
+ qty: import_joi14.default.number().min(0).required(),
3764
+ createdBy: import_joi14.default.string().hex().required()
3765
+ });
3766
+ const { error } = validation.validate(payload);
3767
+ if (error) {
3768
+ import_node_server_utils26.logger.log({ level: "error", message: error.message });
3769
+ next(new import_node_server_utils26.BadRequestError(error.message));
3770
+ return;
3771
+ }
3772
+ try {
3773
+ const id = await _createRequestItem(payload);
3774
+ res.status(201).json({ message: "Request item created successfully.", id });
3775
+ return;
3776
+ } catch (error2) {
3777
+ import_node_server_utils26.logger.log({ level: "error", message: error2.message });
3778
+ next(error2);
3779
+ return;
3780
+ }
3781
+ }
3782
+ async function createRequestItemByBatch(req, res, next) {
3783
+ const cookies = req.headers.cookie ? req.headers.cookie.split(";").map((cookie) => cookie.trim().split("=")).reduce(
3784
+ (acc, [key, value]) => ({ ...acc, [key]: value }),
3785
+ {}
3786
+ ) : {};
3787
+ const createdBy = cookies["user"] || "";
3788
+ const payload = {
3789
+ ...req.body,
3790
+ ...req.params,
3791
+ createdBy
3792
+ };
3793
+ const validation = import_joi14.default.object({
3794
+ site: import_joi14.default.string().hex().required(),
3795
+ createdBy: import_joi14.default.string().hex().required(),
3796
+ items: import_joi14.default.array().items(
3797
+ import_joi14.default.object({
3798
+ supply: import_joi14.default.string().hex().required(),
3799
+ qty: import_joi14.default.number().min(0).required()
3800
+ })
3801
+ ).min(1).required()
3802
+ });
3803
+ const { error } = validation.validate(payload);
3804
+ if (error) {
3805
+ import_node_server_utils26.logger.log({ level: "error", message: error.message });
3806
+ next(new import_node_server_utils26.BadRequestError(error.message));
3807
+ return;
3808
+ }
3809
+ try {
3810
+ await _createRequestItemByBatch(payload);
3811
+ res.status(201).json({ message: "Request items created successfully." });
3812
+ return;
3813
+ } catch (error2) {
3814
+ import_node_server_utils26.logger.log({ level: "error", message: error2.message });
3815
+ next(error2);
3816
+ return;
3817
+ }
3818
+ }
3819
+ async function getRequestItems(req, res, next) {
3820
+ const query = { ...req.query, ...req.params };
3821
+ const validation = import_joi14.default.object({
3822
+ page: import_joi14.default.number().min(1).optional().allow("", null),
3823
+ limit: import_joi14.default.number().min(1).optional().allow("", null),
3824
+ search: import_joi14.default.string().optional().allow("", null),
3825
+ site: import_joi14.default.string().hex().required()
3826
+ });
3827
+ const { error } = validation.validate(query);
3828
+ if (error) {
3829
+ import_node_server_utils26.logger.log({ level: "error", message: error.message });
3830
+ next(new import_node_server_utils26.BadRequestError(error.message));
3831
+ return;
3832
+ }
3833
+ const page = parseInt(req.query.page) ?? 1;
3834
+ const limit = parseInt(req.query.limit) ?? 10;
3835
+ const search = req.query.search ?? "";
3836
+ const site = req.params.site ?? "";
3837
+ try {
3838
+ const data = await _getRequestItems({
3839
+ page,
3840
+ limit,
3841
+ search,
3842
+ site
3843
+ });
3844
+ res.json(data);
3845
+ return;
3846
+ } catch (error2) {
3847
+ import_node_server_utils26.logger.log({ level: "error", message: error2.message });
3848
+ next(error2);
3849
+ return;
3850
+ }
3851
+ }
3852
+ return {
3853
+ createRequestItem,
3854
+ createRequestItemByBatch,
3855
+ getRequestItems
3856
+ };
3857
+ }
3220
3858
  // Annotate the CommonJS export names for ESM import in node:
3221
3859
  0 && (module.exports = {
3222
3860
  MArea,
3223
3861
  MAreaChecklist,
3224
3862
  MParentChecklist,
3863
+ MRequestItem,
3864
+ MStock,
3225
3865
  MSupply,
3226
3866
  MUnit,
3227
3867
  allowedChecklistStatus,
3868
+ allowedRequestItemStatus,
3228
3869
  allowedStatus,
3229
3870
  allowedTypes,
3230
3871
  areaChecklistSchema,
3231
3872
  areaSchema,
3232
3873
  parentChecklistSchema,
3874
+ requestItemSchema,
3875
+ stockSchema,
3233
3876
  supplySchema,
3234
3877
  unitSchema,
3235
3878
  useAreaChecklistController,
@@ -3240,6 +3883,12 @@ function useSupplyController() {
3240
3883
  useAreaService,
3241
3884
  useParentChecklistController,
3242
3885
  useParentChecklistRepo,
3886
+ useRequestItemController,
3887
+ useRequestItemRepository,
3888
+ useRequestItemService,
3889
+ useStockController,
3890
+ useStockRepository,
3891
+ useStockService,
3243
3892
  useSupplyController,
3244
3893
  useSupplyRepository,
3245
3894
  useUnitController,