@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.mjs CHANGED
@@ -644,7 +644,7 @@ function useAreaController() {
644
644
  return;
645
645
  }
646
646
  const page = parseInt(req.query.page) ?? 1;
647
- const limit = parseInt(req.query.limit) ?? 20;
647
+ const limit = parseInt(req.query.limit) ?? 10;
648
648
  const search = req.query.search ?? "";
649
649
  const site = req.params.site ?? "";
650
650
  try {
@@ -1193,7 +1193,7 @@ function useUnitController() {
1193
1193
  return;
1194
1194
  }
1195
1195
  const page = parseInt(req.query.page) ?? 1;
1196
- const limit = parseInt(req.query.limit) ?? 20;
1196
+ const limit = parseInt(req.query.limit) ?? 10;
1197
1197
  const search = req.query.search ?? "";
1198
1198
  const site = req.params.site ?? "";
1199
1199
  try {
@@ -1607,7 +1607,7 @@ function useParentChecklistController() {
1607
1607
  return;
1608
1608
  }
1609
1609
  const page = parseInt(req.query.page) ?? 1;
1610
- const limit = parseInt(req.query.limit) ?? 20;
1610
+ const limit = parseInt(req.query.limit) ?? 10;
1611
1611
  const search = req.query.search ?? "";
1612
1612
  const site = req.params.site ?? "";
1613
1613
  const startDate = req.query.startDate ?? "";
@@ -2626,7 +2626,7 @@ function useAreaChecklistController() {
2626
2626
  return;
2627
2627
  }
2628
2628
  const page = parseInt(req.query.page) ?? 1;
2629
- const limit = parseInt(req.query.limit) ?? 20;
2629
+ const limit = parseInt(req.query.limit) ?? 10;
2630
2630
  const search = req.query.search ?? "";
2631
2631
  const type = req.query.type ?? "";
2632
2632
  const schedule = req.params.schedule ?? "";
@@ -2664,7 +2664,7 @@ function useAreaChecklistController() {
2664
2664
  return;
2665
2665
  }
2666
2666
  const page = parseInt(req.query.page) ?? 1;
2667
- const limit = parseInt(req.query.limit) ?? 20;
2667
+ const limit = parseInt(req.query.limit) ?? 10;
2668
2668
  const search = req.query.search ?? "";
2669
2669
  const type = req.query.type ?? "";
2670
2670
  const schedule = req.params.schedule ?? "";
@@ -2722,7 +2722,7 @@ function useAreaChecklistController() {
2722
2722
  return;
2723
2723
  }
2724
2724
  const page = parseInt(req.query.page) ?? 1;
2725
- const limit = parseInt(req.query.limit) ?? 20;
2725
+ const limit = parseInt(req.query.limit) ?? 10;
2726
2726
  const search = req.query.search ?? "";
2727
2727
  const _id = req.params.id ?? "";
2728
2728
  try {
@@ -2797,8 +2797,7 @@ import { ObjectId as ObjectId9 } from "mongodb";
2797
2797
  var supplySchema = Joi9.object({
2798
2798
  site: Joi9.string().hex().required(),
2799
2799
  name: Joi9.string().required(),
2800
- unitOfMeasurement: Joi9.string().required(),
2801
- qty: Joi9.number().min(0).required()
2800
+ unitOfMeasurement: Joi9.string().required()
2802
2801
  });
2803
2802
  function MSupply(value) {
2804
2803
  const { error } = supplySchema.validate(value);
@@ -2817,9 +2816,9 @@ function MSupply(value) {
2817
2816
  site: value.site,
2818
2817
  name: value.name,
2819
2818
  unitOfMeasurement: value.unitOfMeasurement,
2820
- qty: value.qty,
2821
- createdAt: /* @__PURE__ */ new Date(),
2819
+ qty: 0,
2822
2820
  status: "active",
2821
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
2823
2822
  updatedAt: "",
2824
2823
  deletedAt: ""
2825
2824
  };
@@ -2952,7 +2951,7 @@ function useSupplyRepository() {
2952
2951
  throw error;
2953
2952
  }
2954
2953
  }
2955
- async function getSupplyById(_id) {
2954
+ async function getSupplyById(_id, session) {
2956
2955
  try {
2957
2956
  _id = new ObjectId10(_id);
2958
2957
  } catch (error) {
@@ -2965,10 +2964,14 @@ function useSupplyRepository() {
2965
2964
  const cacheKey = makeCacheKey5(namespace_collection, {
2966
2965
  _id: _id.toString()
2967
2966
  });
2968
- const cachedData = await getCache(cacheKey);
2969
- if (cachedData) {
2970
- logger17.info(`Cache hit for key: ${cacheKey}`);
2971
- return cachedData;
2967
+ if (!session) {
2968
+ const cachedData = await getCache(cacheKey);
2969
+ if (cachedData) {
2970
+ logger17.info(`Cache hit for key: ${cacheKey}`);
2971
+ return cachedData;
2972
+ }
2973
+ } else {
2974
+ logger17.info(`Skipping cache during transaction for key: ${cacheKey}`);
2972
2975
  }
2973
2976
  try {
2974
2977
  const data = await collection.aggregate([
@@ -3116,7 +3119,7 @@ function useSupplyController() {
3116
3119
  return;
3117
3120
  }
3118
3121
  const page = parseInt(req.query.page) ?? 1;
3119
- const limit = parseInt(req.query.limit) ?? 20;
3122
+ const limit = parseInt(req.query.limit) ?? 10;
3120
3123
  const search = req.query.search ?? "";
3121
3124
  const site = req.params.site ?? "";
3122
3125
  try {
@@ -3207,18 +3210,667 @@ function useSupplyController() {
3207
3210
  deleteSupply
3208
3211
  };
3209
3212
  }
3213
+
3214
+ // src/models/hygiene-stock.model.ts
3215
+ import { BadRequestError as BadRequestError18, logger as logger19 } from "@iservice365/node-server-utils";
3216
+ import Joi11 from "joi";
3217
+ import { ObjectId as ObjectId11 } from "mongodb";
3218
+ var stockSchema = Joi11.object({
3219
+ site: Joi11.string().hex().required(),
3220
+ supply: Joi11.string().hex().required(),
3221
+ in: Joi11.number().min(0).optional(),
3222
+ out: Joi11.number().min(0).optional(),
3223
+ balance: Joi11.number().min(0).required(),
3224
+ remarks: Joi11.string().optional().allow("", null)
3225
+ });
3226
+ function MStock(value) {
3227
+ const { error } = stockSchema.validate(value);
3228
+ if (error) {
3229
+ logger19.info(`Hygiene Stock Model: ${error.message}`);
3230
+ throw new BadRequestError18(error.message);
3231
+ }
3232
+ if (value.site) {
3233
+ try {
3234
+ value.site = new ObjectId11(value.site);
3235
+ } catch (error2) {
3236
+ throw new BadRequestError18("Invalid site ID format.");
3237
+ }
3238
+ }
3239
+ if (value.supply) {
3240
+ try {
3241
+ value.supply = new ObjectId11(value.supply);
3242
+ } catch (error2) {
3243
+ throw new BadRequestError18("Invalid supply ID format.");
3244
+ }
3245
+ }
3246
+ return {
3247
+ site: value.site,
3248
+ supply: value.supply,
3249
+ in: value.in ?? 0,
3250
+ out: value.out ?? 0,
3251
+ balance: value.balance,
3252
+ remarks: value.remarks ?? "",
3253
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
3254
+ status: "active",
3255
+ updatedAt: "",
3256
+ deletedAt: ""
3257
+ };
3258
+ }
3259
+
3260
+ // src/repositories/hygiene-stock.repository.ts
3261
+ import { ObjectId as ObjectId12 } from "mongodb";
3262
+ import {
3263
+ useAtlas as useAtlas8,
3264
+ InternalServerError as InternalServerError6,
3265
+ BadRequestError as BadRequestError19,
3266
+ useCache as useCache6,
3267
+ logger as logger20,
3268
+ makeCacheKey as makeCacheKey6,
3269
+ paginate as paginate6
3270
+ } from "@iservice365/node-server-utils";
3271
+ function useStockRepository() {
3272
+ const db = useAtlas8.getDb();
3273
+ if (!db) {
3274
+ throw new InternalServerError6("Unable to connect to server.");
3275
+ }
3276
+ const namespace_collection = "site.supply.stocks";
3277
+ const supply_collection = "site.supplies";
3278
+ const collection = db.collection(namespace_collection);
3279
+ const { delNamespace, setCache, getCache } = useCache6(namespace_collection);
3280
+ const { delNamespace: delSupplyNamespace } = useCache6(supply_collection);
3281
+ async function createIndex() {
3282
+ try {
3283
+ await collection.createIndexes([
3284
+ { key: { site: 1 } },
3285
+ { key: { supply: 1 } },
3286
+ { key: { balance: 1 } },
3287
+ { key: { status: 1 } }
3288
+ ]);
3289
+ } catch (error) {
3290
+ throw new InternalServerError6("Failed to create index on hygiene stock.");
3291
+ }
3292
+ }
3293
+ async function createStock(value, session) {
3294
+ try {
3295
+ value = MStock(value);
3296
+ const res = await collection.insertOne(value, { session });
3297
+ delNamespace().then(() => {
3298
+ logger20.info(`Cache cleared for namespace: ${namespace_collection}`);
3299
+ }).catch((err) => {
3300
+ logger20.error(
3301
+ `Failed to clear cache for namespace: ${namespace_collection}`,
3302
+ err
3303
+ );
3304
+ });
3305
+ delSupplyNamespace().then(() => {
3306
+ logger20.info(`Cache cleared for namespace: ${supply_collection}`);
3307
+ }).catch((err) => {
3308
+ logger20.error(
3309
+ `Failed to clear cache for namespace: ${supply_collection}`,
3310
+ err
3311
+ );
3312
+ });
3313
+ return res.insertedId;
3314
+ } catch (error) {
3315
+ throw error;
3316
+ }
3317
+ }
3318
+ async function getStocksBySupplyId({
3319
+ page = 1,
3320
+ limit = 10,
3321
+ search = "",
3322
+ site,
3323
+ supply
3324
+ }) {
3325
+ page = page > 0 ? page - 1 : 0;
3326
+ const query = {
3327
+ status: { $ne: "deleted" }
3328
+ };
3329
+ const cacheOptions = {
3330
+ page,
3331
+ limit
3332
+ };
3333
+ try {
3334
+ site = new ObjectId12(site);
3335
+ query.site = site;
3336
+ cacheOptions.site = site.toString();
3337
+ } catch (error) {
3338
+ throw new BadRequestError19("Invalid site ID format.");
3339
+ }
3340
+ try {
3341
+ supply = new ObjectId12(supply);
3342
+ query.supply = supply;
3343
+ cacheOptions.supply = supply.toString();
3344
+ } catch (error) {
3345
+ throw new BadRequestError19("Invalid supply ID format.");
3346
+ }
3347
+ if (search) {
3348
+ query.$text = { $search: search };
3349
+ cacheOptions.search = search;
3350
+ }
3351
+ const cacheKey = makeCacheKey6(namespace_collection, cacheOptions);
3352
+ const cachedData = await getCache(cacheKey);
3353
+ if (cachedData) {
3354
+ logger20.info(`Cache hit for key: ${cacheKey}`);
3355
+ return cachedData;
3356
+ }
3357
+ try {
3358
+ const items = await collection.aggregate([
3359
+ { $match: query },
3360
+ {
3361
+ $project: {
3362
+ createdAt: 1,
3363
+ in: 1,
3364
+ out: 1,
3365
+ balance: 1
3366
+ }
3367
+ },
3368
+ { $sort: { _id: 1 } },
3369
+ { $skip: page * limit },
3370
+ { $limit: limit }
3371
+ ]).toArray();
3372
+ const length = await collection.countDocuments(query);
3373
+ const data = paginate6(items, page, limit, length);
3374
+ setCache(cacheKey, data, 15 * 60).then(() => {
3375
+ logger20.info(`Cache set for key: ${cacheKey}`);
3376
+ }).catch((err) => {
3377
+ logger20.error(`Failed to set cache for key: ${cacheKey}`, err);
3378
+ });
3379
+ return data;
3380
+ } catch (error) {
3381
+ throw error;
3382
+ }
3383
+ }
3384
+ return {
3385
+ createIndex,
3386
+ createStock,
3387
+ getStocksBySupplyId
3388
+ };
3389
+ }
3390
+
3391
+ // src/services/hygiene-stock.service.ts
3392
+ import {
3393
+ NotFoundError as NotFoundError5,
3394
+ useAtlas as useAtlas9,
3395
+ BadRequestError as BadRequestError20
3396
+ } from "@iservice365/node-server-utils";
3397
+ function useStockService() {
3398
+ const { createStock: _createStock } = useStockRepository();
3399
+ const { getSupplyById, updateSupply } = useSupplyRepository();
3400
+ async function createStock(value, out = false) {
3401
+ const session = useAtlas9.getClient()?.startSession();
3402
+ try {
3403
+ session?.startTransaction();
3404
+ const { qty, ...stockData } = value;
3405
+ const supply = await getSupplyById(value.supply, session);
3406
+ if (!supply || supply.qty === void 0) {
3407
+ throw new NotFoundError5("Supply not found.");
3408
+ }
3409
+ const newSupplyQty = out ? supply.qty - qty : supply.qty + qty;
3410
+ if (out && newSupplyQty < 0) {
3411
+ throw new BadRequestError20(
3412
+ `Insufficient stock. Available: ${supply.qty}, Requested: ${qty}`
3413
+ );
3414
+ }
3415
+ await updateSupply(value.supply, { qty: newSupplyQty }, session);
3416
+ const createdStock = await _createStock(
3417
+ {
3418
+ ...stockData,
3419
+ in: out ? 0 : qty,
3420
+ out: out ? qty : 0,
3421
+ balance: newSupplyQty
3422
+ },
3423
+ session
3424
+ );
3425
+ await session?.commitTransaction();
3426
+ return createdStock;
3427
+ } catch (error) {
3428
+ await session?.abortTransaction();
3429
+ throw error;
3430
+ } finally {
3431
+ await session?.endSession();
3432
+ }
3433
+ }
3434
+ return { createStock };
3435
+ }
3436
+
3437
+ // src/controllers/hygiene-stock.controller.ts
3438
+ import { BadRequestError as BadRequestError21, logger as logger21 } from "@iservice365/node-server-utils";
3439
+ import Joi12 from "joi";
3440
+ function useStockController() {
3441
+ const { getStocksBySupplyId: _getStocksBySupplyId } = useStockRepository();
3442
+ const { createStock: _createStock } = useStockService();
3443
+ async function createStock(req, res, next) {
3444
+ const payload = { ...req.body, ...req.params };
3445
+ const validation = Joi12.object({
3446
+ site: Joi12.string().hex().required(),
3447
+ supply: Joi12.string().hex().required(),
3448
+ qty: Joi12.number().min(0).required(),
3449
+ remarks: Joi12.string().optional().allow("", null)
3450
+ });
3451
+ const { error } = validation.validate(payload);
3452
+ if (error) {
3453
+ logger21.log({ level: "error", message: error.message });
3454
+ next(new BadRequestError21(error.message));
3455
+ return;
3456
+ }
3457
+ try {
3458
+ const id = await _createStock(payload);
3459
+ res.status(201).json({ message: "Stock created successfully.", id });
3460
+ return;
3461
+ } catch (error2) {
3462
+ logger21.log({ level: "error", message: error2.message });
3463
+ next(error2);
3464
+ return;
3465
+ }
3466
+ }
3467
+ async function getStocksBySupplyId(req, res, next) {
3468
+ const query = { ...req.query, ...req.params };
3469
+ const validation = Joi12.object({
3470
+ page: Joi12.number().min(1).optional().allow("", null),
3471
+ limit: Joi12.number().min(1).optional().allow("", null),
3472
+ search: Joi12.string().optional().allow("", null),
3473
+ site: Joi12.string().hex().required(),
3474
+ supply: Joi12.string().hex().required()
3475
+ });
3476
+ const { error } = validation.validate(query);
3477
+ if (error) {
3478
+ logger21.log({ level: "error", message: error.message });
3479
+ next(new BadRequestError21(error.message));
3480
+ return;
3481
+ }
3482
+ const page = parseInt(req.query.page) ?? 1;
3483
+ const limit = parseInt(req.query.limit) ?? 10;
3484
+ const search = req.query.search ?? "";
3485
+ const site = req.params.site ?? "";
3486
+ const supply = req.params.supply ?? "";
3487
+ try {
3488
+ const data = await _getStocksBySupplyId({
3489
+ page,
3490
+ limit,
3491
+ search,
3492
+ site,
3493
+ supply
3494
+ });
3495
+ res.json(data);
3496
+ return;
3497
+ } catch (error2) {
3498
+ logger21.log({ level: "error", message: error2.message });
3499
+ next(error2);
3500
+ return;
3501
+ }
3502
+ }
3503
+ return {
3504
+ createStock,
3505
+ getStocksBySupplyId
3506
+ };
3507
+ }
3508
+
3509
+ // src/models/hygiene-request-item.model.ts
3510
+ import { BadRequestError as BadRequestError22, logger as logger22 } from "@iservice365/node-server-utils";
3511
+ import Joi13 from "joi";
3512
+ import { ObjectId as ObjectId13 } from "mongodb";
3513
+ var allowedRequestItemStatus = [
3514
+ "pending",
3515
+ "approved",
3516
+ "disapproved"
3517
+ ];
3518
+ var requestItemSchema = Joi13.object({
3519
+ site: Joi13.string().hex().required(),
3520
+ supply: Joi13.string().hex().required(),
3521
+ supplyName: Joi13.string().required(),
3522
+ qty: Joi13.number().min(0).required(),
3523
+ createdBy: Joi13.string().hex().required(),
3524
+ createdByName: Joi13.string().required()
3525
+ });
3526
+ function MRequestItem(value) {
3527
+ const { error } = requestItemSchema.validate(value);
3528
+ if (error) {
3529
+ logger22.info(`Hygiene Request Item Model: ${error.message}`);
3530
+ throw new BadRequestError22(error.message);
3531
+ }
3532
+ if (value.site) {
3533
+ try {
3534
+ value.site = new ObjectId13(value.site);
3535
+ } catch (error2) {
3536
+ throw new BadRequestError22("Invalid site ID format.");
3537
+ }
3538
+ }
3539
+ if (value.supply) {
3540
+ try {
3541
+ value.supply = new ObjectId13(value.supply);
3542
+ } catch (error2) {
3543
+ throw new BadRequestError22("Invalid supply ID format.");
3544
+ }
3545
+ }
3546
+ return {
3547
+ site: value.site,
3548
+ supply: value.supply,
3549
+ supplyName: value.supplyName,
3550
+ qty: value.qty,
3551
+ remarks: "",
3552
+ createdBy: value.createdBy,
3553
+ createdByName: value.createdByName,
3554
+ status: "pending",
3555
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
3556
+ updatedAt: "",
3557
+ deletedAt: ""
3558
+ };
3559
+ }
3560
+
3561
+ // src/repositories/hygiene-request-item.repository.ts
3562
+ import { ObjectId as ObjectId14 } from "mongodb";
3563
+ import {
3564
+ useAtlas as useAtlas10,
3565
+ InternalServerError as InternalServerError7,
3566
+ useCache as useCache7,
3567
+ logger as logger23,
3568
+ makeCacheKey as makeCacheKey7,
3569
+ paginate as paginate7,
3570
+ BadRequestError as BadRequestError23
3571
+ } from "@iservice365/node-server-utils";
3572
+ function useRequestItemRepository() {
3573
+ const db = useAtlas10.getDb();
3574
+ if (!db) {
3575
+ throw new InternalServerError7("Unable to connect to server.");
3576
+ }
3577
+ const namespace_collection = "site.supply.requests";
3578
+ const collection = db.collection(namespace_collection);
3579
+ const { delNamespace, setCache, getCache } = useCache7(namespace_collection);
3580
+ async function createIndex() {
3581
+ try {
3582
+ await collection.createIndexes([
3583
+ { key: { site: 1 } },
3584
+ { key: { supply: 1 } },
3585
+ { key: { status: 1 } }
3586
+ ]);
3587
+ } catch (error) {
3588
+ throw new InternalServerError7(
3589
+ "Failed to create index on hygiene request item."
3590
+ );
3591
+ }
3592
+ }
3593
+ async function createTextIndex() {
3594
+ try {
3595
+ await collection.createIndex({ supplyName: "text" });
3596
+ } catch (error) {
3597
+ throw new InternalServerError7(
3598
+ "Failed to create text index on hygiene supply."
3599
+ );
3600
+ }
3601
+ }
3602
+ async function createRequestItem(value, session) {
3603
+ try {
3604
+ value = MRequestItem(value);
3605
+ const res = await collection.insertOne(value, { session });
3606
+ delNamespace().then(() => {
3607
+ logger23.info(`Cache cleared for namespace: ${namespace_collection}`);
3608
+ }).catch((err) => {
3609
+ logger23.error(
3610
+ `Failed to clear cache for namespace: ${namespace_collection}`,
3611
+ err
3612
+ );
3613
+ });
3614
+ return res.insertedId;
3615
+ } catch (error) {
3616
+ throw error;
3617
+ }
3618
+ }
3619
+ async function getRequestItems({
3620
+ page = 1,
3621
+ limit = 10,
3622
+ search = "",
3623
+ site
3624
+ }) {
3625
+ page = page > 0 ? page - 1 : 0;
3626
+ const query = {
3627
+ status: { $ne: "deleted" }
3628
+ };
3629
+ const cacheOptions = {
3630
+ page,
3631
+ limit
3632
+ };
3633
+ try {
3634
+ site = new ObjectId14(site);
3635
+ query.site = site;
3636
+ cacheOptions.site = site.toString();
3637
+ } catch (error) {
3638
+ throw new BadRequestError23("Invalid site ID format.");
3639
+ }
3640
+ if (search) {
3641
+ query.$text = { $search: search };
3642
+ cacheOptions.search = search;
3643
+ }
3644
+ const cacheKey = makeCacheKey7(namespace_collection, cacheOptions);
3645
+ const cachedData = await getCache(cacheKey);
3646
+ if (cachedData) {
3647
+ logger23.info(`Cache hit for key: ${cacheKey}`);
3648
+ return cachedData;
3649
+ }
3650
+ try {
3651
+ const items = await collection.aggregate([
3652
+ { $match: query },
3653
+ {
3654
+ $project: {
3655
+ createdAt: 1,
3656
+ status: 1
3657
+ }
3658
+ },
3659
+ { $sort: { _id: 1 } },
3660
+ { $skip: page * limit },
3661
+ { $limit: limit }
3662
+ ]).toArray();
3663
+ const length = await collection.countDocuments(query);
3664
+ const data = paginate7(items, page, limit, length);
3665
+ setCache(cacheKey, data, 15 * 60).then(() => {
3666
+ logger23.info(`Cache set for key: ${cacheKey}`);
3667
+ }).catch((err) => {
3668
+ logger23.error(`Failed to set cache for key: ${cacheKey}`, err);
3669
+ });
3670
+ return data;
3671
+ } catch (error) {
3672
+ throw error;
3673
+ }
3674
+ }
3675
+ return {
3676
+ createIndex,
3677
+ createTextIndex,
3678
+ createRequestItem,
3679
+ getRequestItems
3680
+ };
3681
+ }
3682
+
3683
+ // src/services/hygiene-request-item.service.ts
3684
+ import { useAtlas as useAtlas11 } from "@iservice365/node-server-utils";
3685
+ import { useUserRepo } from "@iservice365/core";
3686
+ function useRequestItemService() {
3687
+ const { createRequestItem: _createRequestItem } = useRequestItemRepository();
3688
+ const { getSupplyById } = useSupplyRepository();
3689
+ const { getUserById } = useUserRepo();
3690
+ async function createRequestItem(value) {
3691
+ try {
3692
+ const { supply, createdBy } = value;
3693
+ const supplyData = await getSupplyById(supply);
3694
+ const createdByData = await getUserById(createdBy);
3695
+ const createdRequestItem = await _createRequestItem({
3696
+ ...value,
3697
+ supplyName: supplyData?.name || "",
3698
+ createdByName: createdByData?.name || ""
3699
+ });
3700
+ return createdRequestItem;
3701
+ } catch (error) {
3702
+ throw error;
3703
+ }
3704
+ }
3705
+ async function createRequestItemByBatch(value) {
3706
+ const session = useAtlas11.getClient()?.startSession();
3707
+ try {
3708
+ session?.startTransaction();
3709
+ const { site, createdBy, items } = value;
3710
+ const createdByData = await getUserById(createdBy);
3711
+ const createdRequestItemIds = [];
3712
+ for (const item of items) {
3713
+ const supplyData = await getSupplyById(item.supply, session);
3714
+ const createdId = await _createRequestItem(
3715
+ {
3716
+ site,
3717
+ supply: item.supply,
3718
+ qty: item.qty,
3719
+ supplyName: supplyData?.name || "",
3720
+ createdBy,
3721
+ createdByName: createdByData?.name || ""
3722
+ },
3723
+ session
3724
+ );
3725
+ createdRequestItemIds.push(createdId);
3726
+ }
3727
+ await session?.commitTransaction();
3728
+ return createdRequestItemIds;
3729
+ } catch (error) {
3730
+ await session?.abortTransaction();
3731
+ throw error;
3732
+ } finally {
3733
+ await session?.endSession();
3734
+ }
3735
+ }
3736
+ return { createRequestItem, createRequestItemByBatch };
3737
+ }
3738
+
3739
+ // src/controllers/hygiene-request-item.controller.ts
3740
+ import { BadRequestError as BadRequestError24, logger as logger24 } from "@iservice365/node-server-utils";
3741
+ import Joi14 from "joi";
3742
+ function useRequestItemController() {
3743
+ const { getRequestItems: _getRequestItems } = useRequestItemRepository();
3744
+ const {
3745
+ createRequestItem: _createRequestItem,
3746
+ createRequestItemByBatch: _createRequestItemByBatch
3747
+ } = useRequestItemService();
3748
+ async function createRequestItem(req, res, next) {
3749
+ const cookies = req.headers.cookie ? req.headers.cookie.split(";").map((cookie) => cookie.trim().split("=")).reduce(
3750
+ (acc, [key, value]) => ({ ...acc, [key]: value }),
3751
+ {}
3752
+ ) : {};
3753
+ const createdBy = cookies["user"] || "";
3754
+ const payload = {
3755
+ ...req.body,
3756
+ ...req.params,
3757
+ createdBy
3758
+ };
3759
+ const validation = Joi14.object({
3760
+ site: Joi14.string().hex().required(),
3761
+ supply: Joi14.string().hex().required(),
3762
+ qty: Joi14.number().min(0).required(),
3763
+ createdBy: Joi14.string().hex().required()
3764
+ });
3765
+ const { error } = validation.validate(payload);
3766
+ if (error) {
3767
+ logger24.log({ level: "error", message: error.message });
3768
+ next(new BadRequestError24(error.message));
3769
+ return;
3770
+ }
3771
+ try {
3772
+ const id = await _createRequestItem(payload);
3773
+ res.status(201).json({ message: "Request item created successfully.", id });
3774
+ return;
3775
+ } catch (error2) {
3776
+ logger24.log({ level: "error", message: error2.message });
3777
+ next(error2);
3778
+ return;
3779
+ }
3780
+ }
3781
+ async function createRequestItemByBatch(req, res, next) {
3782
+ const cookies = req.headers.cookie ? req.headers.cookie.split(";").map((cookie) => cookie.trim().split("=")).reduce(
3783
+ (acc, [key, value]) => ({ ...acc, [key]: value }),
3784
+ {}
3785
+ ) : {};
3786
+ const createdBy = cookies["user"] || "";
3787
+ const payload = {
3788
+ ...req.body,
3789
+ ...req.params,
3790
+ createdBy
3791
+ };
3792
+ const validation = Joi14.object({
3793
+ site: Joi14.string().hex().required(),
3794
+ createdBy: Joi14.string().hex().required(),
3795
+ items: Joi14.array().items(
3796
+ Joi14.object({
3797
+ supply: Joi14.string().hex().required(),
3798
+ qty: Joi14.number().min(0).required()
3799
+ })
3800
+ ).min(1).required()
3801
+ });
3802
+ const { error } = validation.validate(payload);
3803
+ if (error) {
3804
+ logger24.log({ level: "error", message: error.message });
3805
+ next(new BadRequestError24(error.message));
3806
+ return;
3807
+ }
3808
+ try {
3809
+ await _createRequestItemByBatch(payload);
3810
+ res.status(201).json({ message: "Request items created successfully." });
3811
+ return;
3812
+ } catch (error2) {
3813
+ logger24.log({ level: "error", message: error2.message });
3814
+ next(error2);
3815
+ return;
3816
+ }
3817
+ }
3818
+ async function getRequestItems(req, res, next) {
3819
+ const query = { ...req.query, ...req.params };
3820
+ const validation = Joi14.object({
3821
+ page: Joi14.number().min(1).optional().allow("", null),
3822
+ limit: Joi14.number().min(1).optional().allow("", null),
3823
+ search: Joi14.string().optional().allow("", null),
3824
+ site: Joi14.string().hex().required()
3825
+ });
3826
+ const { error } = validation.validate(query);
3827
+ if (error) {
3828
+ logger24.log({ level: "error", message: error.message });
3829
+ next(new BadRequestError24(error.message));
3830
+ return;
3831
+ }
3832
+ const page = parseInt(req.query.page) ?? 1;
3833
+ const limit = parseInt(req.query.limit) ?? 10;
3834
+ const search = req.query.search ?? "";
3835
+ const site = req.params.site ?? "";
3836
+ try {
3837
+ const data = await _getRequestItems({
3838
+ page,
3839
+ limit,
3840
+ search,
3841
+ site
3842
+ });
3843
+ res.json(data);
3844
+ return;
3845
+ } catch (error2) {
3846
+ logger24.log({ level: "error", message: error2.message });
3847
+ next(error2);
3848
+ return;
3849
+ }
3850
+ }
3851
+ return {
3852
+ createRequestItem,
3853
+ createRequestItemByBatch,
3854
+ getRequestItems
3855
+ };
3856
+ }
3210
3857
  export {
3211
3858
  MArea,
3212
3859
  MAreaChecklist,
3213
3860
  MParentChecklist,
3861
+ MRequestItem,
3862
+ MStock,
3214
3863
  MSupply,
3215
3864
  MUnit,
3216
3865
  allowedChecklistStatus,
3866
+ allowedRequestItemStatus,
3217
3867
  allowedStatus,
3218
3868
  allowedTypes,
3219
3869
  areaChecklistSchema,
3220
3870
  areaSchema,
3221
3871
  parentChecklistSchema,
3872
+ requestItemSchema,
3873
+ stockSchema,
3222
3874
  supplySchema,
3223
3875
  unitSchema,
3224
3876
  useAreaChecklistController,
@@ -3229,6 +3881,12 @@ export {
3229
3881
  useAreaService,
3230
3882
  useParentChecklistController,
3231
3883
  useParentChecklistRepo,
3884
+ useRequestItemController,
3885
+ useRequestItemRepository,
3886
+ useRequestItemService,
3887
+ useStockController,
3888
+ useStockRepository,
3889
+ useStockService,
3232
3890
  useSupplyController,
3233
3891
  useSupplyRepository,
3234
3892
  useUnitController,