@iservice365/module-hygiene 1.0.1 → 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
  };
@@ -2834,7 +2834,8 @@ import {
2834
2834
  BadRequestError as BadRequestError16,
2835
2835
  useCache as useCache5,
2836
2836
  logger as logger17,
2837
- makeCacheKey as makeCacheKey5
2837
+ makeCacheKey as makeCacheKey5,
2838
+ NotFoundError as NotFoundError4
2838
2839
  } from "@iservice365/node-server-utils";
2839
2840
  function useSupplyRepository() {
2840
2841
  const db = useAtlas7.getDb();
@@ -2951,6 +2952,48 @@ function useSupplyRepository() {
2951
2952
  throw error;
2952
2953
  }
2953
2954
  }
2955
+ async function getSupplyById(_id) {
2956
+ try {
2957
+ _id = new ObjectId10(_id);
2958
+ } catch (error) {
2959
+ throw new BadRequestError16("Invalid supply ID format.");
2960
+ }
2961
+ const query = {
2962
+ _id,
2963
+ status: { $ne: "deleted" }
2964
+ };
2965
+ const cacheKey = makeCacheKey5(namespace_collection, {
2966
+ _id: _id.toString()
2967
+ });
2968
+ const cachedData = await getCache(cacheKey);
2969
+ if (cachedData) {
2970
+ logger17.info(`Cache hit for key: ${cacheKey}`);
2971
+ return cachedData;
2972
+ }
2973
+ try {
2974
+ const data = await collection.aggregate([
2975
+ { $match: query },
2976
+ {
2977
+ $project: {
2978
+ name: 1,
2979
+ unitOfMeasurement: 1,
2980
+ qty: 1
2981
+ }
2982
+ }
2983
+ ]).toArray();
2984
+ if (!data || data.length === 0) {
2985
+ throw new NotFoundError4("Supply not found.");
2986
+ }
2987
+ setCache(cacheKey, data[0], 15 * 60).then(() => {
2988
+ logger17.info(`Cache set for key: ${cacheKey}`);
2989
+ }).catch((err) => {
2990
+ logger17.error(`Failed to set cache for key: ${cacheKey}`, err);
2991
+ });
2992
+ return data[0];
2993
+ } catch (error) {
2994
+ throw error;
2995
+ }
2996
+ }
2954
2997
  async function updateSupply(_id, value, session) {
2955
2998
  try {
2956
2999
  _id = new ObjectId10(_id);
@@ -3023,27 +3066,164 @@ function useSupplyRepository() {
3023
3066
  createUniqueIndex,
3024
3067
  createSupply,
3025
3068
  getSupplies,
3069
+ getSupplyById,
3026
3070
  updateSupply,
3027
3071
  deleteSupply
3028
3072
  };
3029
3073
  }
3030
3074
 
3031
- // 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
3032
3079
  import { BadRequestError as BadRequestError17, logger as logger18 } from "@iservice365/node-server-utils";
3033
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";
3034
3213
  function useSupplyController() {
3035
3214
  const {
3036
- createSupply: _createSupply,
3037
3215
  getSupplies: _getSupplies,
3216
+ getSupplyById: _getSupplyById,
3038
3217
  updateSupply: _updateSupply,
3039
3218
  deleteSupply: _deleteSupply
3040
3219
  } = useSupplyRepository();
3220
+ const { createSupply: _createSupply } = useSupplyService();
3041
3221
  async function createSupply(req, res, next) {
3042
3222
  const payload = { ...req.body, ...req.params };
3043
3223
  const { error } = supplySchema.validate(payload);
3044
3224
  if (error) {
3045
- logger18.log({ level: "error", message: error.message });
3046
- next(new BadRequestError17(error.message));
3225
+ logger20.log({ level: "error", message: error.message });
3226
+ next(new BadRequestError19(error.message));
3047
3227
  return;
3048
3228
  }
3049
3229
  try {
@@ -3051,23 +3231,23 @@ function useSupplyController() {
3051
3231
  res.status(201).json({ message: "Supply created successfully.", id });
3052
3232
  return;
3053
3233
  } catch (error2) {
3054
- logger18.log({ level: "error", message: error2.message });
3234
+ logger20.log({ level: "error", message: error2.message });
3055
3235
  next(error2);
3056
3236
  return;
3057
3237
  }
3058
3238
  }
3059
3239
  async function getSupplies(req, res, next) {
3060
3240
  const query = { ...req.query, ...req.params };
3061
- const validation = Joi10.object({
3062
- page: Joi10.number().min(1).optional().allow("", null),
3063
- limit: Joi10.number().min(1).optional().allow("", null),
3064
- search: Joi10.string().optional().allow("", null),
3065
- 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()
3066
3246
  });
3067
3247
  const { error } = validation.validate(query);
3068
3248
  if (error) {
3069
- logger18.log({ level: "error", message: error.message });
3070
- next(new BadRequestError17(error.message));
3249
+ logger20.log({ level: "error", message: error.message });
3250
+ next(new BadRequestError19(error.message));
3071
3251
  return;
3072
3252
  }
3073
3253
  const page = parseInt(req.query.page) ?? 1;
@@ -3084,23 +3264,42 @@ function useSupplyController() {
3084
3264
  res.json(data);
3085
3265
  return;
3086
3266
  } catch (error2) {
3087
- logger18.log({ level: "error", message: error2.message });
3267
+ logger20.log({ level: "error", message: error2.message });
3268
+ next(error2);
3269
+ return;
3270
+ }
3271
+ }
3272
+ async function getSupplyById(req, res, next) {
3273
+ const validation = Joi11.string().hex().required();
3274
+ const _id = req.params.id;
3275
+ const { error } = validation.validate(_id);
3276
+ if (error) {
3277
+ logger20.log({ level: "error", message: error.message });
3278
+ next(new BadRequestError19(error.message));
3279
+ return;
3280
+ }
3281
+ try {
3282
+ const data = await _getSupplyById(_id);
3283
+ res.json(data);
3284
+ return;
3285
+ } catch (error2) {
3286
+ logger20.log({ level: "error", message: error2.message });
3088
3287
  next(error2);
3089
3288
  return;
3090
3289
  }
3091
3290
  }
3092
3291
  async function updateSupply(req, res, next) {
3093
3292
  const payload = { id: req.params.id, ...req.body };
3094
- const validation = Joi10.object({
3095
- id: Joi10.string().hex().required(),
3096
- name: Joi10.string().optional().allow("", null),
3097
- unitOfMeasurement: Joi10.string().optional().allow("", null),
3098
- 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)
3099
3298
  });
3100
3299
  const { error } = validation.validate(payload);
3101
3300
  if (error) {
3102
- logger18.log({ level: "error", message: error.message });
3103
- next(new BadRequestError17(error.message));
3301
+ logger20.log({ level: "error", message: error.message });
3302
+ next(new BadRequestError19(error.message));
3104
3303
  return;
3105
3304
  }
3106
3305
  try {
@@ -3109,20 +3308,20 @@ function useSupplyController() {
3109
3308
  res.json({ message: "Supply updated successfully." });
3110
3309
  return;
3111
3310
  } catch (error2) {
3112
- logger18.log({ level: "error", message: error2.message });
3311
+ logger20.log({ level: "error", message: error2.message });
3113
3312
  next(error2);
3114
3313
  return;
3115
3314
  }
3116
3315
  }
3117
3316
  async function deleteSupply(req, res, next) {
3118
3317
  const id = req.params.id;
3119
- const validation = Joi10.object({
3120
- id: Joi10.string().hex().required()
3318
+ const validation = Joi11.object({
3319
+ id: Joi11.string().hex().required()
3121
3320
  });
3122
3321
  const { error } = validation.validate({ id });
3123
3322
  if (error) {
3124
- logger18.log({ level: "error", message: error.message });
3125
- next(new BadRequestError17(error.message));
3323
+ logger20.log({ level: "error", message: error.message });
3324
+ next(new BadRequestError19(error.message));
3126
3325
  return;
3127
3326
  }
3128
3327
  try {
@@ -3130,7 +3329,7 @@ function useSupplyController() {
3130
3329
  res.json({ message: "Supply deleted successfully." });
3131
3330
  return;
3132
3331
  } catch (error2) {
3133
- logger18.log({ level: "error", message: error2.message });
3332
+ logger20.log({ level: "error", message: error2.message });
3134
3333
  next(error2);
3135
3334
  return;
3136
3335
  }
@@ -3138,14 +3337,82 @@ function useSupplyController() {
3138
3337
  return {
3139
3338
  createSupply,
3140
3339
  getSupplies,
3340
+ getSupplyById,
3141
3341
  updateSupply,
3142
3342
  deleteSupply
3143
3343
  };
3144
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
+ }
3145
3411
  export {
3146
3412
  MArea,
3147
3413
  MAreaChecklist,
3148
3414
  MParentChecklist,
3415
+ MStock,
3149
3416
  MSupply,
3150
3417
  MUnit,
3151
3418
  allowedChecklistStatus,
@@ -3154,6 +3421,7 @@ export {
3154
3421
  areaChecklistSchema,
3155
3422
  areaSchema,
3156
3423
  parentChecklistSchema,
3424
+ stockSchema,
3157
3425
  supplySchema,
3158
3426
  unitSchema,
3159
3427
  useAreaChecklistController,
@@ -3164,8 +3432,12 @@ export {
3164
3432
  useAreaService,
3165
3433
  useParentChecklistController,
3166
3434
  useParentChecklistRepo,
3435
+ useStockController,
3436
+ useStockRepository,
3437
+ useStockService,
3167
3438
  useSupplyController,
3168
3439
  useSupplyRepository,
3440
+ useSupplyService,
3169
3441
  useUnitController,
3170
3442
  useUnitRepository,
3171
3443
  useUnitService