@iservice365/module-hygiene 1.0.2 → 1.0.3

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
@@ -2818,8 +2818,8 @@ function MSupply(value) {
2818
2818
  name: value.name,
2819
2819
  unitOfMeasurement: value.unitOfMeasurement,
2820
2820
  qty: value.qty,
2821
- createdAt: /* @__PURE__ */ new Date(),
2822
2821
  status: "active",
2822
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
2823
2823
  updatedAt: "",
2824
2824
  deletedAt: ""
2825
2825
  };
@@ -3072,23 +3072,158 @@ function useSupplyRepository() {
3072
3072
  };
3073
3073
  }
3074
3074
 
3075
- // src/controllers/hygiene-supply.controller.ts
3075
+ // src/services/hygiene-supply.service.ts
3076
+ import { useAtlas as useAtlas9 } from "@iservice365/node-server-utils";
3077
+
3078
+ // src/models/hygiene-stock.model.ts
3076
3079
  import { BadRequestError as BadRequestError17, logger as logger18 } from "@iservice365/node-server-utils";
3077
3080
  import Joi10 from "joi";
3081
+ import { ObjectId as ObjectId11 } from "mongodb";
3082
+ var stockSchema = Joi10.object({
3083
+ site: Joi10.string().hex().required(),
3084
+ supply: Joi10.string().hex().required(),
3085
+ in: Joi10.number().min(0).optional(),
3086
+ out: Joi10.number().min(0).optional(),
3087
+ balance: Joi10.number().min(0).required(),
3088
+ remarks: Joi10.string().optional().allow("", null)
3089
+ });
3090
+ function MStock(value) {
3091
+ const { error } = stockSchema.validate(value);
3092
+ if (error) {
3093
+ logger18.info(`Hygiene Stock Model: ${error.message}`);
3094
+ throw new BadRequestError17(error.message);
3095
+ }
3096
+ if (value.site) {
3097
+ try {
3098
+ value.site = new ObjectId11(value.site);
3099
+ } catch (error2) {
3100
+ throw new BadRequestError17("Invalid site ID format.");
3101
+ }
3102
+ }
3103
+ if (value.supply) {
3104
+ try {
3105
+ value.supply = new ObjectId11(value.supply);
3106
+ } catch (error2) {
3107
+ throw new BadRequestError17("Invalid supply ID format.");
3108
+ }
3109
+ }
3110
+ return {
3111
+ site: value.site,
3112
+ supply: value.supply,
3113
+ in: value.in ?? 0,
3114
+ out: value.out ?? 0,
3115
+ balance: value.balance,
3116
+ remarks: value.remarks ?? "",
3117
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
3118
+ status: "active",
3119
+ updatedAt: "",
3120
+ deletedAt: ""
3121
+ };
3122
+ }
3123
+
3124
+ // src/repositories/hygiene-stock.repository.ts
3125
+ import {
3126
+ useAtlas as useAtlas8,
3127
+ InternalServerError as InternalServerError6,
3128
+ BadRequestError as BadRequestError18,
3129
+ useCache as useCache6,
3130
+ logger as logger19
3131
+ } from "@iservice365/node-server-utils";
3132
+ function useStockRepository() {
3133
+ const db = useAtlas8.getDb();
3134
+ if (!db) {
3135
+ throw new InternalServerError6("Unable to connect to server.");
3136
+ }
3137
+ const namespace_collection = "site.supply.stocks";
3138
+ const collection = db.collection(namespace_collection);
3139
+ const { delNamespace } = useCache6(namespace_collection);
3140
+ async function createIndex() {
3141
+ try {
3142
+ await collection.createIndexes([
3143
+ { key: { site: 1 } },
3144
+ { key: { supply: 1 } },
3145
+ { key: { balance: 1 } },
3146
+ { key: { status: 1 } }
3147
+ ]);
3148
+ } catch (error) {
3149
+ throw new InternalServerError6("Failed to create index on hygiene stock.");
3150
+ }
3151
+ }
3152
+ async function createStock(value, session) {
3153
+ try {
3154
+ value = MStock(value);
3155
+ const res = await collection.insertOne(value, { session });
3156
+ delNamespace().then(() => {
3157
+ logger19.info(`Cache cleared for namespace: ${namespace_collection}`);
3158
+ }).catch((err) => {
3159
+ logger19.error(
3160
+ `Failed to clear cache for namespace: ${namespace_collection}`,
3161
+ err
3162
+ );
3163
+ });
3164
+ return res.insertedId;
3165
+ } catch (error) {
3166
+ const isDuplicated = error.message.includes("duplicate");
3167
+ if (isDuplicated) {
3168
+ throw new BadRequestError18("Stock already exists.");
3169
+ }
3170
+ throw error;
3171
+ }
3172
+ }
3173
+ return {
3174
+ createIndex,
3175
+ createStock
3176
+ };
3177
+ }
3178
+
3179
+ // src/services/hygiene-supply.service.ts
3180
+ function useSupplyService() {
3181
+ const { createSupply: _createSupply } = useSupplyRepository();
3182
+ const { createStock } = useStockRepository();
3183
+ async function createSupply(value) {
3184
+ const session = useAtlas9.getClient()?.startSession();
3185
+ try {
3186
+ session?.startTransaction();
3187
+ const { qty, site } = value;
3188
+ const supply = await _createSupply(value, session);
3189
+ const createdSupply = await createStock(
3190
+ {
3191
+ site,
3192
+ supply: supply.toString(),
3193
+ in: qty,
3194
+ balance: qty
3195
+ },
3196
+ session
3197
+ );
3198
+ await session?.commitTransaction();
3199
+ return createdSupply;
3200
+ } catch (error) {
3201
+ await session?.abortTransaction();
3202
+ throw error;
3203
+ } finally {
3204
+ await session?.endSession();
3205
+ }
3206
+ }
3207
+ return { createSupply };
3208
+ }
3209
+
3210
+ // src/controllers/hygiene-supply.controller.ts
3211
+ import { BadRequestError as BadRequestError19, logger as logger20 } from "@iservice365/node-server-utils";
3212
+ import Joi11 from "joi";
3078
3213
  function useSupplyController() {
3079
3214
  const {
3080
- createSupply: _createSupply,
3081
3215
  getSupplies: _getSupplies,
3082
3216
  getSupplyById: _getSupplyById,
3083
3217
  updateSupply: _updateSupply,
3084
3218
  deleteSupply: _deleteSupply
3085
3219
  } = useSupplyRepository();
3220
+ const { createSupply: _createSupply } = useSupplyService();
3086
3221
  async function createSupply(req, res, next) {
3087
3222
  const payload = { ...req.body, ...req.params };
3088
3223
  const { error } = supplySchema.validate(payload);
3089
3224
  if (error) {
3090
- logger18.log({ level: "error", message: error.message });
3091
- next(new BadRequestError17(error.message));
3225
+ logger20.log({ level: "error", message: error.message });
3226
+ next(new BadRequestError19(error.message));
3092
3227
  return;
3093
3228
  }
3094
3229
  try {
@@ -3096,23 +3231,23 @@ function useSupplyController() {
3096
3231
  res.status(201).json({ message: "Supply created successfully.", id });
3097
3232
  return;
3098
3233
  } catch (error2) {
3099
- logger18.log({ level: "error", message: error2.message });
3234
+ logger20.log({ level: "error", message: error2.message });
3100
3235
  next(error2);
3101
3236
  return;
3102
3237
  }
3103
3238
  }
3104
3239
  async function getSupplies(req, res, next) {
3105
3240
  const query = { ...req.query, ...req.params };
3106
- const validation = Joi10.object({
3107
- page: Joi10.number().min(1).optional().allow("", null),
3108
- limit: Joi10.number().min(1).optional().allow("", null),
3109
- search: Joi10.string().optional().allow("", null),
3110
- site: Joi10.string().hex().required()
3241
+ const validation = Joi11.object({
3242
+ page: Joi11.number().min(1).optional().allow("", null),
3243
+ limit: Joi11.number().min(1).optional().allow("", null),
3244
+ search: Joi11.string().optional().allow("", null),
3245
+ site: Joi11.string().hex().required()
3111
3246
  });
3112
3247
  const { error } = validation.validate(query);
3113
3248
  if (error) {
3114
- logger18.log({ level: "error", message: error.message });
3115
- next(new BadRequestError17(error.message));
3249
+ logger20.log({ level: "error", message: error.message });
3250
+ next(new BadRequestError19(error.message));
3116
3251
  return;
3117
3252
  }
3118
3253
  const page = parseInt(req.query.page) ?? 1;
@@ -3129,18 +3264,18 @@ function useSupplyController() {
3129
3264
  res.json(data);
3130
3265
  return;
3131
3266
  } catch (error2) {
3132
- logger18.log({ level: "error", message: error2.message });
3267
+ logger20.log({ level: "error", message: error2.message });
3133
3268
  next(error2);
3134
3269
  return;
3135
3270
  }
3136
3271
  }
3137
3272
  async function getSupplyById(req, res, next) {
3138
- const validation = Joi10.string().hex().required();
3273
+ const validation = Joi11.string().hex().required();
3139
3274
  const _id = req.params.id;
3140
3275
  const { error } = validation.validate(_id);
3141
3276
  if (error) {
3142
- logger18.log({ level: "error", message: error.message });
3143
- next(new BadRequestError17(error.message));
3277
+ logger20.log({ level: "error", message: error.message });
3278
+ next(new BadRequestError19(error.message));
3144
3279
  return;
3145
3280
  }
3146
3281
  try {
@@ -3148,23 +3283,23 @@ function useSupplyController() {
3148
3283
  res.json(data);
3149
3284
  return;
3150
3285
  } catch (error2) {
3151
- logger18.log({ level: "error", message: error2.message });
3286
+ logger20.log({ level: "error", message: error2.message });
3152
3287
  next(error2);
3153
3288
  return;
3154
3289
  }
3155
3290
  }
3156
3291
  async function updateSupply(req, res, next) {
3157
3292
  const payload = { id: req.params.id, ...req.body };
3158
- const validation = Joi10.object({
3159
- id: Joi10.string().hex().required(),
3160
- name: Joi10.string().optional().allow("", null),
3161
- unitOfMeasurement: Joi10.string().optional().allow("", null),
3162
- qty: Joi10.number().min(0).optional().allow("", null)
3293
+ const validation = Joi11.object({
3294
+ id: Joi11.string().hex().required(),
3295
+ name: Joi11.string().optional().allow("", null),
3296
+ unitOfMeasurement: Joi11.string().optional().allow("", null),
3297
+ qty: Joi11.number().min(0).optional().allow("", null)
3163
3298
  });
3164
3299
  const { error } = validation.validate(payload);
3165
3300
  if (error) {
3166
- logger18.log({ level: "error", message: error.message });
3167
- next(new BadRequestError17(error.message));
3301
+ logger20.log({ level: "error", message: error.message });
3302
+ next(new BadRequestError19(error.message));
3168
3303
  return;
3169
3304
  }
3170
3305
  try {
@@ -3173,20 +3308,20 @@ function useSupplyController() {
3173
3308
  res.json({ message: "Supply updated successfully." });
3174
3309
  return;
3175
3310
  } catch (error2) {
3176
- logger18.log({ level: "error", message: error2.message });
3311
+ logger20.log({ level: "error", message: error2.message });
3177
3312
  next(error2);
3178
3313
  return;
3179
3314
  }
3180
3315
  }
3181
3316
  async function deleteSupply(req, res, next) {
3182
3317
  const id = req.params.id;
3183
- const validation = Joi10.object({
3184
- id: Joi10.string().hex().required()
3318
+ const validation = Joi11.object({
3319
+ id: Joi11.string().hex().required()
3185
3320
  });
3186
3321
  const { error } = validation.validate({ id });
3187
3322
  if (error) {
3188
- logger18.log({ level: "error", message: error.message });
3189
- next(new BadRequestError17(error.message));
3323
+ logger20.log({ level: "error", message: error.message });
3324
+ next(new BadRequestError19(error.message));
3190
3325
  return;
3191
3326
  }
3192
3327
  try {
@@ -3194,7 +3329,7 @@ function useSupplyController() {
3194
3329
  res.json({ message: "Supply deleted successfully." });
3195
3330
  return;
3196
3331
  } catch (error2) {
3197
- logger18.log({ level: "error", message: error2.message });
3332
+ logger20.log({ level: "error", message: error2.message });
3198
3333
  next(error2);
3199
3334
  return;
3200
3335
  }
@@ -3207,10 +3342,77 @@ function useSupplyController() {
3207
3342
  deleteSupply
3208
3343
  };
3209
3344
  }
3345
+
3346
+ // src/services/hygiene-stock.service.ts
3347
+ import { NotFoundError as NotFoundError5, useAtlas as useAtlas10 } from "@iservice365/node-server-utils";
3348
+ function useStockService() {
3349
+ const { createStock: _createStock } = useStockRepository();
3350
+ const { getSupplyById, updateSupply } = useSupplyRepository();
3351
+ async function createStock(value) {
3352
+ const session = useAtlas10.getClient()?.startSession();
3353
+ try {
3354
+ session?.startTransaction();
3355
+ const { qty, ...stockData } = value;
3356
+ const supply = await getSupplyById(value.supply);
3357
+ if (!supply || supply.qty === void 0) {
3358
+ throw new NotFoundError5("Supply not found.");
3359
+ }
3360
+ const newSupplyQty = supply.qty + qty;
3361
+ await updateSupply(value.supply, { qty: newSupplyQty }, session);
3362
+ const createdStock = await _createStock(
3363
+ { ...stockData, in: qty, balance: newSupplyQty },
3364
+ session
3365
+ );
3366
+ await session?.commitTransaction();
3367
+ return createdStock;
3368
+ } catch (error) {
3369
+ await session?.abortTransaction();
3370
+ throw error;
3371
+ } finally {
3372
+ await session?.endSession();
3373
+ }
3374
+ }
3375
+ return { createStock };
3376
+ }
3377
+
3378
+ // src/controllers/hygiene-stock.controller.ts
3379
+ import { BadRequestError as BadRequestError20, logger as logger21 } from "@iservice365/node-server-utils";
3380
+ import Joi12 from "joi";
3381
+ function useStockController() {
3382
+ const { createStock: _createStock } = useStockService();
3383
+ async function createStock(req, res, next) {
3384
+ const payload = { ...req.body, ...req.params };
3385
+ const validation = Joi12.object({
3386
+ site: Joi12.string().hex().required(),
3387
+ supply: Joi12.string().hex().required(),
3388
+ qty: Joi12.number().min(0).optional(),
3389
+ remarks: Joi12.string().optional().allow("", null)
3390
+ });
3391
+ const { error } = validation.validate(payload);
3392
+ if (error) {
3393
+ logger21.log({ level: "error", message: error.message });
3394
+ next(new BadRequestError20(error.message));
3395
+ return;
3396
+ }
3397
+ try {
3398
+ const id = await _createStock(payload);
3399
+ res.status(201).json({ message: "Stock created successfully.", id });
3400
+ return;
3401
+ } catch (error2) {
3402
+ logger21.log({ level: "error", message: error2.message });
3403
+ next(error2);
3404
+ return;
3405
+ }
3406
+ }
3407
+ return {
3408
+ createStock
3409
+ };
3410
+ }
3210
3411
  export {
3211
3412
  MArea,
3212
3413
  MAreaChecklist,
3213
3414
  MParentChecklist,
3415
+ MStock,
3214
3416
  MSupply,
3215
3417
  MUnit,
3216
3418
  allowedChecklistStatus,
@@ -3219,6 +3421,7 @@ export {
3219
3421
  areaChecklistSchema,
3220
3422
  areaSchema,
3221
3423
  parentChecklistSchema,
3424
+ stockSchema,
3222
3425
  supplySchema,
3223
3426
  unitSchema,
3224
3427
  useAreaChecklistController,
@@ -3229,8 +3432,12 @@ export {
3229
3432
  useAreaService,
3230
3433
  useParentChecklistController,
3231
3434
  useParentChecklistRepo,
3435
+ useStockController,
3436
+ useStockRepository,
3437
+ useStockService,
3232
3438
  useSupplyController,
3233
3439
  useSupplyRepository,
3440
+ useSupplyService,
3234
3441
  useUnitController,
3235
3442
  useUnitRepository,
3236
3443
  useUnitService