@goweekdays/core 2.15.9 → 2.15.10

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
@@ -22572,19 +22572,36 @@ var schemaAssetItemCreate = Joi96.object({
22572
22572
  }, "subcategory-requires-category");
22573
22573
  var schemaAssetItemUpdate = Joi96.object({
22574
22574
  name: Joi96.string().optional(),
22575
+ sku: Joi96.string().optional().allow("", null),
22576
+ price: Joi96.number().min(0).optional().allow("", null),
22577
+ unit: Joi96.string().optional(),
22575
22578
  description: Joi96.string().optional().allow("", null),
22576
22579
  assetCategory: Joi96.string().valid(...assetItemCategories).optional(),
22577
- assetClass: Joi96.string().valid(...assetItemClasses).optional(),
22580
+ assetClass: Joi96.string().valid(...assetItemClasses).optional().allow("", null),
22581
+ trackingType: Joi96.string().valid(...assetItemTrackingTypes).optional(),
22582
+ departmentId: Joi96.string().hex().length(24).optional(),
22583
+ departmentName: Joi96.string().optional(),
22584
+ categoryId: Joi96.string().hex().length(24).optional().allow("", null),
22585
+ categoryName: Joi96.string().optional().allow("", null),
22586
+ subcategoryId: Joi96.string().hex().length(24).optional().allow("", null),
22587
+ subcategoryName: Joi96.string().optional().allow("", null),
22588
+ categoryPath: Joi96.string().optional().allow("", null),
22578
22589
  brand: Joi96.string().optional().allow("", null),
22579
- sku: Joi96.string().optional().allow("", null),
22580
- price: Joi96.number().min(0).optional().allow("", null),
22581
22590
  tags: Joi96.array().items(
22582
22591
  Joi96.object({
22583
22592
  id: Joi96.string().required(),
22584
22593
  name: Joi96.string().required()
22585
22594
  })
22586
22595
  ).optional(),
22587
- quantityOnHand: Joi96.number().min(0).optional()
22596
+ isPublic: Joi96.boolean().optional(),
22597
+ updatedAt: Joi96.date().optional()
22598
+ }).custom((value, helpers) => {
22599
+ if (value.subcategoryId && !value.categoryId) {
22600
+ return helpers.error("any.custom", {
22601
+ message: "categoryId is required when subcategoryId is provided."
22602
+ });
22603
+ }
22604
+ return value;
22588
22605
  });
22589
22606
  function modelAssetItem(data) {
22590
22607
  const { error } = schemaAssetItem.validate(data);
@@ -22695,6 +22712,7 @@ function useAssetItemRepo() {
22695
22712
  { key: { trackingType: 1 } },
22696
22713
  { key: { status: 1 } },
22697
22714
  { key: { name: "text" } },
22715
+ { key: { public: 1 } },
22698
22716
  {
22699
22717
  key: {
22700
22718
  orgId: 1,
@@ -22739,10 +22757,14 @@ function useAssetItemRepo() {
22739
22757
  categoryId = "",
22740
22758
  subcategoryId = "",
22741
22759
  brand = "",
22742
- tags = []
22760
+ tags = [],
22761
+ isPublic = false
22743
22762
  } = {}) {
22744
22763
  page = page > 0 ? page - 1 : 0;
22745
22764
  const query = { status: status2 };
22765
+ if (isPublic) {
22766
+ query.isPublic = true;
22767
+ }
22746
22768
  if (search) {
22747
22769
  query.$text = { $search: search };
22748
22770
  }
@@ -22783,7 +22805,8 @@ function useAssetItemRepo() {
22783
22805
  subcategoryId,
22784
22806
  brand,
22785
22807
  tags: tags.join(","),
22786
- tag: "getAll"
22808
+ tag: "getAll",
22809
+ public: isPublic ? "true" : "false"
22787
22810
  });
22788
22811
  try {
22789
22812
  const cached = await repo.getCache(cacheKey);
@@ -22828,10 +22851,16 @@ function useAssetItemRepo() {
22828
22851
  }
22829
22852
  }
22830
22853
  async function updateById(id, value) {
22854
+ const { error, value: validatedValue } = schemaAssetItemUpdate.validate(value);
22855
+ if (error) {
22856
+ throw new BadRequestError109(
22857
+ `Invalid asset item update data: ${error.message}`
22858
+ );
22859
+ }
22831
22860
  try {
22832
22861
  const result = await repo.collection.findOneAndUpdate(
22833
22862
  { _id: new ObjectId59(id) },
22834
- { $set: { ...value, updatedAt: /* @__PURE__ */ new Date() } },
22863
+ { $set: { ...validatedValue, updatedAt: /* @__PURE__ */ new Date() } },
22835
22864
  { returnDocument: "after" }
22836
22865
  );
22837
22866
  if (!result) {
@@ -22839,9 +22868,9 @@ function useAssetItemRepo() {
22839
22868
  }
22840
22869
  repo.delCachedData();
22841
22870
  return result;
22842
- } catch (error) {
22843
- if (error instanceof AppError51)
22844
- throw error;
22871
+ } catch (error2) {
22872
+ if (error2 instanceof AppError51)
22873
+ throw error2;
22845
22874
  throw new InternalServerError47("Failed to update asset item.");
22846
22875
  }
22847
22876
  }
@@ -22897,9 +22926,10 @@ function useAssetItemRepo() {
22897
22926
 
22898
22927
  // src/resources/asset-item/asset.item.service.ts
22899
22928
  import {
22900
- AppError as AppError54,
22901
- InternalServerError as InternalServerError50,
22902
- useAtlas as useAtlas17
22929
+ AppError as AppError56,
22930
+ BadRequestError as BadRequestError118,
22931
+ InternalServerError as InternalServerError52,
22932
+ useAtlas as useAtlas18
22903
22933
  } from "@goweekdays/utils";
22904
22934
 
22905
22935
  // src/resources/tag/tag.repository.ts
@@ -23576,246 +23606,203 @@ function useCategoryRepo() {
23576
23606
  };
23577
23607
  }
23578
23608
 
23579
- // src/resources/asset-item/asset.item.service.ts
23580
- function normalizeTagName(name) {
23581
- return name.trim().toLowerCase().replace(/\s+/g, "-");
23582
- }
23583
- function useAssetItemService() {
23584
- const assetItemRepo = useAssetItemRepo();
23585
- const tagRepo = useTagRepo();
23586
- const categoryRepo = useCategoryRepo();
23587
- async function resolveTags(tagNames, orgId, categoryPath, session) {
23588
- const resolvedTags = [];
23589
- for (const tag of tagNames) {
23590
- const normalizedName = normalizeTagName(tag.name);
23591
- const existing = await tagRepo.findByNormalizedNameAndOrg(
23592
- normalizedName,
23593
- orgId
23594
- );
23595
- if (existing && existing._id) {
23596
- await tagRepo.incrementUsageCount(existing._id, 1, session);
23597
- resolvedTags.push({
23598
- id: String(existing._id),
23599
- name: existing.name
23600
- });
23601
- } else {
23602
- const tagData = {
23603
- name: tag.name.trim(),
23604
- normalizedName,
23605
- type: "private",
23606
- orgId,
23607
- categoryPath,
23608
- status: "active",
23609
- usageCount: 1
23610
- };
23611
- const tagId = await tagRepo.add(tagData, session);
23612
- resolvedTags.push({
23613
- id: String(tagId),
23614
- name: tag.name.trim()
23615
- });
23616
- }
23617
- }
23618
- return resolvedTags;
23609
+ // src/resources/asset-item-movement/stock.movement.model.ts
23610
+ import Joi100 from "joi";
23611
+ import { ObjectId as ObjectId64 } from "mongodb";
23612
+ var stockMovementTypes = [
23613
+ "in",
23614
+ "out",
23615
+ "transfer",
23616
+ "adjustment",
23617
+ "conversion"
23618
+ ];
23619
+ var stockMovementReferenceTypes = [
23620
+ "purchase",
23621
+ "sale",
23622
+ "transfer",
23623
+ "manual",
23624
+ "conversion"
23625
+ ];
23626
+ var schemaStockMovement = Joi100.object({
23627
+ itemId: Joi100.string().hex().length(24).required(),
23628
+ type: Joi100.string().valid(...stockMovementTypes).required(),
23629
+ quantity: Joi100.number().positive().required(),
23630
+ unitCost: Joi100.number().min(0).optional().allow(null),
23631
+ totalCost: Joi100.number().min(0).optional().allow(null),
23632
+ reference: Joi100.object({
23633
+ type: Joi100.string().valid(...stockMovementReferenceTypes).required(),
23634
+ id: Joi100.string().optional().allow("", null)
23635
+ }).optional().allow(null),
23636
+ fromLocationId: Joi100.string().optional().allow("", null),
23637
+ toLocationId: Joi100.string().optional().allow("", null),
23638
+ fromItemId: Joi100.string().hex().length(24).optional().allow("", null),
23639
+ toItemId: Joi100.string().hex().length(24).optional().allow("", null),
23640
+ reason: Joi100.string().optional().allow("", null)
23641
+ });
23642
+ function modelStockMovement(data) {
23643
+ const { error } = schemaStockMovement.validate(data);
23644
+ if (error) {
23645
+ throw new Error(`Invalid stock movement data: ${error.message}`);
23619
23646
  }
23620
- async function add(value) {
23621
- const session = useAtlas17.getClient()?.startSession();
23622
- if (!session) {
23623
- throw new InternalServerError50(
23624
- "Unable to start session for asset item service."
23625
- );
23626
- }
23647
+ if (data.itemId && typeof data.itemId === "string") {
23627
23648
  try {
23628
- await session.startTransaction();
23629
- const department = await categoryRepo.getById(value.departmentId);
23630
- value.departmentName = department.displayName;
23631
- if (value.categoryId) {
23632
- const category = await categoryRepo.getById(value.categoryId);
23633
- value.categoryName = category.displayName;
23634
- }
23635
- if (value.subcategoryId) {
23636
- const subcategory = await categoryRepo.getById(value.subcategoryId);
23637
- value.subcategoryName = subcategory.displayName;
23638
- }
23639
- const categoryPath = buildCategoryPath(
23640
- value.departmentName,
23641
- value.categoryName ?? "",
23642
- value.subcategoryName ?? ""
23643
- );
23644
- value.categoryPath = categoryPath;
23645
- const resolvedTags = value.tags.length ? await resolveTags(
23646
- value.tags,
23647
- value.orgId,
23648
- value.categoryPath,
23649
- session
23650
- ) : [];
23651
- const assetItem = {
23652
- ...value,
23653
- tags: resolvedTags
23654
- };
23655
- const assetItemId = await assetItemRepo.add(assetItem, session);
23656
- await session.commitTransaction();
23657
- return assetItemId;
23658
- } catch (error) {
23659
- await session.abortTransaction();
23660
- if (error instanceof AppError54)
23661
- throw error;
23662
- throw new InternalServerError50("Failed to create asset item.");
23663
- } finally {
23664
- session.endSession();
23649
+ data.itemId = new ObjectId64(data.itemId);
23650
+ } catch {
23651
+ throw new Error(`Invalid itemId format: ${data.itemId}`);
23665
23652
  }
23666
23653
  }
23667
23654
  return {
23668
- add
23655
+ _id: data._id,
23656
+ itemId: data.itemId,
23657
+ type: data.type,
23658
+ quantity: data.quantity,
23659
+ unitCost: data.unitCost ?? 0,
23660
+ totalCost: data.totalCost ?? 0,
23661
+ reference: data.reference ?? void 0,
23662
+ fromLocationId: data.fromLocationId ?? "",
23663
+ toLocationId: data.toLocationId ?? "",
23664
+ fromItemId: data.fromItemId ?? "",
23665
+ toItemId: data.toItemId ?? "",
23666
+ reason: data.reason ?? "",
23667
+ createdAt: data.createdAt ?? /* @__PURE__ */ new Date()
23669
23668
  };
23670
23669
  }
23671
23670
 
23672
- // src/resources/asset-item/asset.item.controller.ts
23673
- import Joi100 from "joi";
23674
- import { BadRequestError as BadRequestError114 } from "@goweekdays/utils";
23675
- var paginationSchema3 = Joi100.object({
23676
- page: Joi100.number().min(1).optional().allow("", null),
23677
- limit: Joi100.number().min(1).optional().allow("", null),
23678
- search: Joi100.string().optional().allow("", null),
23679
- status: Joi100.string().valid(...assetItemStatuses).optional().allow("", null),
23680
- assetCategory: Joi100.string().valid(...assetItemCategories).optional().allow("", null),
23681
- trackingType: Joi100.string().valid(...assetItemTrackingTypes).optional().allow("", null),
23682
- purpose: Joi100.string().valid(...assetItemPurposes).optional().allow("", null),
23683
- departmentId: Joi100.string().optional().allow("", null),
23684
- categoryId: Joi100.string().optional().allow("", null),
23685
- subcategoryId: Joi100.string().optional().allow("", null),
23686
- brand: Joi100.string().optional().allow("", null),
23687
- tags: Joi100.string().optional().allow("", null)
23688
- });
23689
- var idParamSchema2 = Joi100.object({
23690
- id: Joi100.string().hex().length(24).required()
23691
- });
23692
- function useAssetItemController() {
23693
- const repo = useAssetItemRepo();
23694
- const service = useAssetItemService();
23695
- async function add(req, res, next) {
23671
+ // src/resources/asset-item-movement/stock.movement.repository.ts
23672
+ import {
23673
+ AppError as AppError54,
23674
+ BadRequestError as BadRequestError113,
23675
+ InternalServerError as InternalServerError50,
23676
+ logger as logger57,
23677
+ makeCacheKey as makeCacheKey36,
23678
+ paginate as paginate32,
23679
+ useRepo as useRepo35
23680
+ } from "@goweekdays/utils";
23681
+ import { ObjectId as ObjectId65 } from "mongodb";
23682
+ function useStockMovementRepo() {
23683
+ const namespace_collection = "stock.movements";
23684
+ const repo = useRepo35(namespace_collection);
23685
+ async function createIndexes() {
23696
23686
  try {
23697
- const { error, value } = schemaAssetItemCreate.validate(req.body);
23698
- if (error) {
23699
- next(new BadRequestError114(error.message));
23700
- return;
23701
- }
23702
- const assetItemId = await service.add(value);
23703
- res.status(201).json({
23704
- message: "Asset item created successfully.",
23705
- assetItemId
23706
- });
23687
+ await repo.collection.createIndexes([
23688
+ { key: { itemId: 1 } },
23689
+ { key: { createdAt: -1 } },
23690
+ { key: { itemId: 1, createdAt: -1 } },
23691
+ { key: { type: 1 } }
23692
+ ]);
23707
23693
  } catch (error) {
23708
- next(error);
23694
+ throw new BadRequestError113("Failed to create stock movement indexes.");
23709
23695
  }
23710
23696
  }
23711
- async function getAll(req, res, next) {
23712
- const { error } = paginationSchema3.validate(req.query);
23713
- if (error) {
23714
- next(new BadRequestError114(error.message));
23715
- return;
23716
- }
23717
- const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
23718
- const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
23719
- const search = req.query.search ?? "";
23720
- const status2 = req.query.status ?? "active";
23721
- const assetCategory = req.query.assetCategory ?? "";
23722
- const trackingType = req.query.trackingType ?? "";
23723
- const purpose = req.query.purpose ?? "";
23724
- const departmentId = req.query.departmentId ?? "";
23725
- const categoryId = req.query.categoryId ?? "";
23726
- const subcategoryId = req.query.subcategoryId ?? "";
23727
- const brand = req.query.brand ?? "";
23728
- const tagsParam = req.query.tags ?? "";
23729
- const tags = tagsParam ? tagsParam.split(",").filter(Boolean) : [];
23730
- if (!isFinite(page)) {
23731
- next(new BadRequestError114("Invalid page number."));
23732
- return;
23733
- }
23734
- if (!isFinite(limit)) {
23735
- next(new BadRequestError114("Invalid limit number."));
23736
- return;
23737
- }
23697
+ async function add(value, session) {
23738
23698
  try {
23739
- const results = await repo.getAll({
23740
- page,
23741
- limit,
23742
- search,
23743
- status: status2,
23744
- assetCategory,
23745
- trackingType,
23746
- purpose,
23747
- departmentId,
23748
- categoryId,
23749
- subcategoryId,
23750
- brand,
23751
- tags
23752
- });
23753
- res.json(results);
23754
- } catch (error2) {
23755
- next(error2);
23699
+ value = modelStockMovement(value);
23700
+ const res = await repo.collection.insertOne(value, { session });
23701
+ repo.delCachedData();
23702
+ return res.insertedId;
23703
+ } catch (error) {
23704
+ logger57.log({ level: "error", message: error.message });
23705
+ throw new InternalServerError50("Failed to create stock movement.");
23756
23706
  }
23757
23707
  }
23758
- async function getById(req, res, next) {
23759
- const { error } = idParamSchema2.validate(req.params);
23760
- if (error) {
23761
- next(new BadRequestError114(error.message));
23762
- return;
23708
+ async function getByItemId({
23709
+ itemId,
23710
+ type = "",
23711
+ page = 1,
23712
+ limit = 10
23713
+ }) {
23714
+ page = page > 0 ? page - 1 : 0;
23715
+ const query = {
23716
+ itemId: new ObjectId65(itemId)
23717
+ };
23718
+ if (type) {
23719
+ query.type = type;
23763
23720
  }
23721
+ const cacheKey = makeCacheKey36(namespace_collection, {
23722
+ itemId,
23723
+ type,
23724
+ page,
23725
+ limit,
23726
+ tag: "byItemId"
23727
+ });
23764
23728
  try {
23765
- const assetItem = await repo.getById(req.params.id);
23766
- res.json(assetItem);
23767
- } catch (error2) {
23768
- next(error2);
23729
+ const cached = await repo.getCache(cacheKey);
23730
+ if (cached)
23731
+ return cached;
23732
+ const items = await repo.collection.aggregate([
23733
+ { $match: query },
23734
+ { $sort: { createdAt: -1 } },
23735
+ { $skip: page * limit },
23736
+ { $limit: limit }
23737
+ ]).toArray();
23738
+ const length = await repo.collection.countDocuments(query);
23739
+ const data = paginate32(items, page, limit, length);
23740
+ repo.setCache(cacheKey, data, 600);
23741
+ return data;
23742
+ } catch (error) {
23743
+ logger57.log({ level: "error", message: `${error}` });
23744
+ throw error;
23769
23745
  }
23770
23746
  }
23771
- async function updateById(req, res, next) {
23772
- const { error: paramError } = idParamSchema2.validate(req.params);
23773
- if (paramError) {
23774
- next(new BadRequestError114(paramError.message));
23775
- return;
23776
- }
23777
- const { error: bodyError } = schemaAssetItemUpdate.validate(req.body);
23778
- if (bodyError) {
23779
- next(new BadRequestError114(bodyError.message));
23780
- return;
23781
- }
23747
+ async function getById(id) {
23748
+ const cacheKey = makeCacheKey36(namespace_collection, {
23749
+ id,
23750
+ tag: "by-id"
23751
+ });
23782
23752
  try {
23783
- const updatedAssetItem = await repo.updateById(req.params.id, req.body);
23784
- res.json({
23785
- message: "Asset item updated successfully.",
23786
- assetItem: updatedAssetItem
23753
+ const cached = await repo.getCache(cacheKey);
23754
+ if (cached)
23755
+ return cached;
23756
+ const result = await repo.collection.findOne({
23757
+ _id: new ObjectId65(id)
23787
23758
  });
23759
+ if (!result) {
23760
+ throw new BadRequestError113("Stock movement not found.");
23761
+ }
23762
+ repo.setCache(cacheKey, result, 300);
23763
+ return result;
23788
23764
  } catch (error) {
23789
- next(error);
23765
+ if (error instanceof AppError54)
23766
+ throw error;
23767
+ throw new InternalServerError50("Failed to get stock movement.");
23790
23768
  }
23791
23769
  }
23792
- async function deleteById(req, res, next) {
23793
- const { error } = idParamSchema2.validate(req.params);
23794
- if (error) {
23795
- next(new BadRequestError114(error.message));
23796
- return;
23797
- }
23770
+ async function countByItemId(itemId) {
23798
23771
  try {
23799
- await repo.deleteById(req.params.id);
23800
- res.json({
23801
- message: "Asset item deleted successfully."
23772
+ return await repo.collection.countDocuments({
23773
+ itemId: new ObjectId65(itemId)
23802
23774
  });
23803
- } catch (error2) {
23804
- next(error2);
23775
+ } catch (error) {
23776
+ throw new InternalServerError50("Failed to count stock movements.");
23805
23777
  }
23806
23778
  }
23807
23779
  return {
23780
+ createIndexes,
23808
23781
  add,
23809
- getAll,
23782
+ getByItemId,
23810
23783
  getById,
23811
- updateById,
23812
- deleteById
23784
+ countByItemId
23813
23785
  };
23814
23786
  }
23815
23787
 
23788
+ // src/resources/asset-item-movement/stock.movement.service.ts
23789
+ import { BadRequestError as BadRequestError115 } from "@goweekdays/utils";
23790
+ import { useAtlas as useAtlas17 } from "@goweekdays/utils";
23791
+
23792
+ // src/resources/asset-item-unit/asset.unit.repository.ts
23793
+ import {
23794
+ AppError as AppError55,
23795
+ BadRequestError as BadRequestError114,
23796
+ InternalServerError as InternalServerError51,
23797
+ logger as logger58,
23798
+ makeCacheKey as makeCacheKey37,
23799
+ paginate as paginate33,
23800
+ useRepo as useRepo36
23801
+ } from "@goweekdays/utils";
23802
+
23816
23803
  // src/resources/asset-item-unit/asset.unit.model.ts
23817
23804
  import Joi101 from "joi";
23818
- import { ObjectId as ObjectId64 } from "mongodb";
23805
+ import { ObjectId as ObjectId66 } from "mongodb";
23819
23806
  var assetUnitStatuses = [
23820
23807
  "available",
23821
23808
  "assigned",
@@ -23845,7 +23832,7 @@ function modelAssetUnit(data) {
23845
23832
  }
23846
23833
  if (data.itemId && typeof data.itemId === "string") {
23847
23834
  try {
23848
- data.itemId = new ObjectId64(data.itemId);
23835
+ data.itemId = new ObjectId66(data.itemId);
23849
23836
  } catch {
23850
23837
  throw new Error(`Invalid itemId format: ${data.itemId}`);
23851
23838
  }
@@ -23864,19 +23851,10 @@ function modelAssetUnit(data) {
23864
23851
  }
23865
23852
 
23866
23853
  // src/resources/asset-item-unit/asset.unit.repository.ts
23867
- import {
23868
- AppError as AppError55,
23869
- BadRequestError as BadRequestError115,
23870
- InternalServerError as InternalServerError51,
23871
- logger as logger57,
23872
- makeCacheKey as makeCacheKey36,
23873
- paginate as paginate32,
23874
- useRepo as useRepo35
23875
- } from "@goweekdays/utils";
23876
- import { ObjectId as ObjectId65 } from "mongodb";
23854
+ import { ObjectId as ObjectId67 } from "mongodb";
23877
23855
  function useAssetUnitRepo() {
23878
23856
  const namespace_collection = "asset.units";
23879
- const repo = useRepo35(namespace_collection);
23857
+ const repo = useRepo36(namespace_collection);
23880
23858
  async function createIndexes() {
23881
23859
  try {
23882
23860
  await repo.collection.createIndexes([
@@ -23886,7 +23864,7 @@ function useAssetUnitRepo() {
23886
23864
  { key: { itemId: 1, status: 1 } }
23887
23865
  ]);
23888
23866
  } catch (error) {
23889
- throw new BadRequestError115("Failed to create asset unit indexes.");
23867
+ throw new BadRequestError114("Failed to create asset unit indexes.");
23890
23868
  }
23891
23869
  }
23892
23870
  async function add(value, session) {
@@ -23896,7 +23874,7 @@ function useAssetUnitRepo() {
23896
23874
  repo.delCachedData();
23897
23875
  return res.insertedId;
23898
23876
  } catch (error) {
23899
- logger57.log({ level: "error", message: error.message });
23877
+ logger58.log({ level: "error", message: error.message });
23900
23878
  throw new InternalServerError51("Failed to create asset unit.");
23901
23879
  }
23902
23880
  }
@@ -23908,12 +23886,12 @@ function useAssetUnitRepo() {
23908
23886
  }) {
23909
23887
  page = page > 0 ? page - 1 : 0;
23910
23888
  const query = {
23911
- itemId: new ObjectId65(itemId)
23889
+ itemId: new ObjectId67(itemId)
23912
23890
  };
23913
23891
  if (status2) {
23914
23892
  query.status = status2;
23915
23893
  }
23916
- const cacheKey = makeCacheKey36(namespace_collection, {
23894
+ const cacheKey = makeCacheKey37(namespace_collection, {
23917
23895
  itemId,
23918
23896
  status: status2,
23919
23897
  page,
@@ -23931,16 +23909,16 @@ function useAssetUnitRepo() {
23931
23909
  { $limit: limit }
23932
23910
  ]).toArray();
23933
23911
  const length = await repo.collection.countDocuments(query);
23934
- const data = paginate32(items, page, limit, length);
23912
+ const data = paginate33(items, page, limit, length);
23935
23913
  repo.setCache(cacheKey, data, 600);
23936
23914
  return data;
23937
23915
  } catch (error) {
23938
- logger57.log({ level: "error", message: `${error}` });
23916
+ logger58.log({ level: "error", message: `${error}` });
23939
23917
  throw error;
23940
23918
  }
23941
23919
  }
23942
23920
  async function getById(id) {
23943
- const cacheKey = makeCacheKey36(namespace_collection, {
23921
+ const cacheKey = makeCacheKey37(namespace_collection, {
23944
23922
  id,
23945
23923
  tag: "by-id"
23946
23924
  });
@@ -23949,10 +23927,10 @@ function useAssetUnitRepo() {
23949
23927
  if (cached)
23950
23928
  return cached;
23951
23929
  const result = await repo.collection.findOne({
23952
- _id: new ObjectId65(id)
23930
+ _id: new ObjectId67(id)
23953
23931
  });
23954
23932
  if (!result) {
23955
- throw new BadRequestError115("Asset unit not found.");
23933
+ throw new BadRequestError114("Asset unit not found.");
23956
23934
  }
23957
23935
  repo.setCache(cacheKey, result, 300);
23958
23936
  return result;
@@ -23965,12 +23943,12 @@ function useAssetUnitRepo() {
23965
23943
  async function updateById(id, value, session) {
23966
23944
  try {
23967
23945
  const result = await repo.collection.findOneAndUpdate(
23968
- { _id: new ObjectId65(id) },
23946
+ { _id: new ObjectId67(id) },
23969
23947
  { $set: { ...value, updatedAt: /* @__PURE__ */ new Date() } },
23970
23948
  { returnDocument: "after", session }
23971
23949
  );
23972
23950
  if (!result) {
23973
- throw new BadRequestError115("Asset unit not found.");
23951
+ throw new BadRequestError114("Asset unit not found.");
23974
23952
  }
23975
23953
  repo.delCachedData();
23976
23954
  return result;
@@ -23980,10 +23958,19 @@ function useAssetUnitRepo() {
23980
23958
  throw new InternalServerError51("Failed to update asset unit.");
23981
23959
  }
23982
23960
  }
23961
+ async function countByItemId(itemId) {
23962
+ try {
23963
+ return await repo.collection.countDocuments({
23964
+ itemId: new ObjectId67(itemId)
23965
+ });
23966
+ } catch (error) {
23967
+ throw new InternalServerError51("Failed to count asset units.");
23968
+ }
23969
+ }
23983
23970
  async function countByItemIdAndStatus(itemId, status2) {
23984
23971
  try {
23985
23972
  return await repo.collection.countDocuments({
23986
- itemId: new ObjectId65(itemId),
23973
+ itemId: new ObjectId67(itemId),
23987
23974
  status: status2
23988
23975
  });
23989
23976
  } catch (error) {
@@ -23996,357 +23983,98 @@ function useAssetUnitRepo() {
23996
23983
  getByItemId,
23997
23984
  getById,
23998
23985
  updateById,
23986
+ countByItemId,
23999
23987
  countByItemIdAndStatus
24000
23988
  };
24001
23989
  }
24002
23990
 
24003
- // src/resources/asset-item-unit/asset.unit.controller.ts
24004
- import Joi102 from "joi";
24005
- import { BadRequestError as BadRequestError116 } from "@goweekdays/utils";
24006
- var querySchema = Joi102.object({
24007
- itemId: Joi102.string().hex().length(24).required(),
24008
- status: Joi102.string().valid(...assetUnitStatuses).optional().allow("", null),
24009
- page: Joi102.number().min(1).optional().allow("", null),
24010
- limit: Joi102.number().min(1).optional().allow("", null)
24011
- });
24012
- var idParamSchema3 = Joi102.object({
24013
- id: Joi102.string().hex().length(24).required()
24014
- });
24015
- function useAssetUnitController() {
24016
- const repo = useAssetUnitRepo();
24017
- async function add(req, res, next) {
23991
+ // src/resources/asset-item-movement/stock.movement.service.ts
23992
+ function useStockMovementService() {
23993
+ const movementRepo = useStockMovementRepo();
23994
+ const assetItemRepo = useAssetItemRepo();
23995
+ const assetUnitRepo = useAssetUnitRepo();
23996
+ async function stockIn(value, units) {
23997
+ const item = await assetItemRepo.getById(String(value.itemId));
23998
+ const session = useAtlas17.getClient()?.startSession();
23999
+ if (!session)
24000
+ throw new BadRequestError115("Failed to start session.");
24018
24001
  try {
24019
- const { error } = schemaAssetUnit.validate(req.body);
24020
- if (error) {
24021
- next(new BadRequestError116(error.message));
24022
- return;
24002
+ session.startTransaction();
24003
+ value.type = "in";
24004
+ const movementId = await movementRepo.add(value, session);
24005
+ if (item.trackingType === "individual" && units && units.length > 0) {
24006
+ for (const unit of units) {
24007
+ await assetUnitRepo.add(
24008
+ {
24009
+ itemId: value.itemId,
24010
+ serialNumber: unit.serialNumber,
24011
+ plateNumber: unit.plateNumber,
24012
+ status: "available",
24013
+ locationId: value.toLocationId
24014
+ },
24015
+ session
24016
+ );
24017
+ }
24023
24018
  }
24024
- const unitId = await repo.add(req.body);
24025
- res.status(201).json({
24026
- message: "Asset unit created successfully.",
24027
- unitId
24028
- });
24019
+ await assetItemRepo.incrementQuantity(
24020
+ String(value.itemId),
24021
+ value.quantity,
24022
+ session
24023
+ );
24024
+ await session.commitTransaction();
24025
+ return movementId;
24029
24026
  } catch (error) {
24030
- next(error);
24031
- }
24032
- }
24033
- async function getByItemId(req, res, next) {
24034
- const { error } = querySchema.validate(req.query);
24035
- if (error) {
24036
- next(new BadRequestError116(error.message));
24037
- return;
24038
- }
24039
- const itemId = req.query.itemId;
24040
- const status2 = req.query.status ?? "";
24041
- const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
24042
- const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
24043
- try {
24044
- const results = await repo.getByItemId({ itemId, status: status2, page, limit });
24045
- res.json(results);
24046
- } catch (error2) {
24047
- next(error2);
24027
+ await session.abortTransaction();
24028
+ throw error;
24029
+ } finally {
24030
+ await session.endSession();
24048
24031
  }
24049
24032
  }
24050
- async function getById(req, res, next) {
24051
- const { error } = idParamSchema3.validate(req.params);
24052
- if (error) {
24053
- next(new BadRequestError116(error.message));
24054
- return;
24033
+ async function stockOut(value, unitIds) {
24034
+ const item = await assetItemRepo.getById(String(value.itemId));
24035
+ if (item.trackingType === "quantity" && (item.quantityOnHand ?? 0) < value.quantity) {
24036
+ throw new BadRequestError115("Insufficient stock.");
24055
24037
  }
24038
+ const session = useAtlas17.getClient()?.startSession();
24039
+ if (!session)
24040
+ throw new BadRequestError115("Failed to start session.");
24056
24041
  try {
24057
- const unit = await repo.getById(req.params.id);
24058
- res.json(unit);
24059
- } catch (error2) {
24060
- next(error2);
24042
+ session.startTransaction();
24043
+ value.type = "out";
24044
+ const movementId = await movementRepo.add(value, session);
24045
+ if (item.trackingType === "individual" && unitIds && unitIds.length > 0) {
24046
+ for (const unitId of unitIds) {
24047
+ await assetUnitRepo.updateById(
24048
+ unitId,
24049
+ { status: "assigned", assignedTo: value.reference?.id },
24050
+ session
24051
+ );
24052
+ }
24053
+ }
24054
+ await assetItemRepo.incrementQuantity(
24055
+ String(value.itemId),
24056
+ -value.quantity,
24057
+ session
24058
+ );
24059
+ await session.commitTransaction();
24060
+ return movementId;
24061
+ } catch (error) {
24062
+ await session.abortTransaction();
24063
+ throw error;
24064
+ } finally {
24065
+ await session.endSession();
24061
24066
  }
24062
24067
  }
24063
- async function updateById(req, res, next) {
24064
- const { error: paramError } = idParamSchema3.validate(req.params);
24065
- if (paramError) {
24066
- next(new BadRequestError116(paramError.message));
24067
- return;
24068
- }
24069
- const { error: bodyError } = schemaAssetUnitUpdate.validate(req.body);
24070
- if (bodyError) {
24071
- next(new BadRequestError116(bodyError.message));
24072
- return;
24068
+ async function transfer(value, unitIds) {
24069
+ if (!value.fromLocationId || !value.toLocationId) {
24070
+ throw new BadRequestError115(
24071
+ "Transfer requires both fromLocationId and toLocationId."
24072
+ );
24073
24073
  }
24074
- try {
24075
- const updatedUnit = await repo.updateById(req.params.id, req.body);
24076
- res.json({
24077
- message: "Asset unit updated successfully.",
24078
- unit: updatedUnit
24079
- });
24080
- } catch (error) {
24081
- next(error);
24082
- }
24083
- }
24084
- return {
24085
- add,
24086
- getByItemId,
24087
- getById,
24088
- updateById
24089
- };
24090
- }
24091
-
24092
- // src/resources/asset-item-movement/stock.movement.model.ts
24093
- import Joi103 from "joi";
24094
- import { ObjectId as ObjectId66 } from "mongodb";
24095
- var stockMovementTypes = [
24096
- "in",
24097
- "out",
24098
- "transfer",
24099
- "adjustment",
24100
- "conversion"
24101
- ];
24102
- var stockMovementReferenceTypes = [
24103
- "purchase",
24104
- "sale",
24105
- "transfer",
24106
- "manual",
24107
- "conversion"
24108
- ];
24109
- var schemaStockMovement = Joi103.object({
24110
- itemId: Joi103.string().hex().length(24).required(),
24111
- type: Joi103.string().valid(...stockMovementTypes).required(),
24112
- quantity: Joi103.number().positive().required(),
24113
- unitCost: Joi103.number().min(0).optional().allow(null),
24114
- totalCost: Joi103.number().min(0).optional().allow(null),
24115
- reference: Joi103.object({
24116
- type: Joi103.string().valid(...stockMovementReferenceTypes).required(),
24117
- id: Joi103.string().optional().allow("", null)
24118
- }).optional().allow(null),
24119
- fromLocationId: Joi103.string().optional().allow("", null),
24120
- toLocationId: Joi103.string().optional().allow("", null),
24121
- fromItemId: Joi103.string().hex().length(24).optional().allow("", null),
24122
- toItemId: Joi103.string().hex().length(24).optional().allow("", null),
24123
- reason: Joi103.string().optional().allow("", null)
24124
- });
24125
- function modelStockMovement(data) {
24126
- const { error } = schemaStockMovement.validate(data);
24127
- if (error) {
24128
- throw new Error(`Invalid stock movement data: ${error.message}`);
24129
- }
24130
- if (data.itemId && typeof data.itemId === "string") {
24131
- try {
24132
- data.itemId = new ObjectId66(data.itemId);
24133
- } catch {
24134
- throw new Error(`Invalid itemId format: ${data.itemId}`);
24135
- }
24136
- }
24137
- return {
24138
- _id: data._id,
24139
- itemId: data.itemId,
24140
- type: data.type,
24141
- quantity: data.quantity,
24142
- unitCost: data.unitCost ?? 0,
24143
- totalCost: data.totalCost ?? 0,
24144
- reference: data.reference ?? void 0,
24145
- fromLocationId: data.fromLocationId ?? "",
24146
- toLocationId: data.toLocationId ?? "",
24147
- fromItemId: data.fromItemId ?? "",
24148
- toItemId: data.toItemId ?? "",
24149
- reason: data.reason ?? "",
24150
- createdAt: data.createdAt ?? /* @__PURE__ */ new Date()
24151
- };
24152
- }
24153
-
24154
- // src/resources/asset-item-movement/stock.movement.repository.ts
24155
- import {
24156
- AppError as AppError56,
24157
- BadRequestError as BadRequestError117,
24158
- InternalServerError as InternalServerError52,
24159
- logger as logger58,
24160
- makeCacheKey as makeCacheKey37,
24161
- paginate as paginate33,
24162
- useRepo as useRepo36
24163
- } from "@goweekdays/utils";
24164
- import { ObjectId as ObjectId67 } from "mongodb";
24165
- function useStockMovementRepo() {
24166
- const namespace_collection = "stock.movements";
24167
- const repo = useRepo36(namespace_collection);
24168
- async function createIndexes() {
24169
- try {
24170
- await repo.collection.createIndexes([
24171
- { key: { itemId: 1 } },
24172
- { key: { createdAt: -1 } },
24173
- { key: { itemId: 1, createdAt: -1 } },
24174
- { key: { type: 1 } }
24175
- ]);
24176
- } catch (error) {
24177
- throw new BadRequestError117("Failed to create stock movement indexes.");
24178
- }
24179
- }
24180
- async function add(value, session) {
24181
- try {
24182
- value = modelStockMovement(value);
24183
- const res = await repo.collection.insertOne(value, { session });
24184
- repo.delCachedData();
24185
- return res.insertedId;
24186
- } catch (error) {
24187
- logger58.log({ level: "error", message: error.message });
24188
- throw new InternalServerError52("Failed to create stock movement.");
24189
- }
24190
- }
24191
- async function getByItemId({
24192
- itemId,
24193
- type = "",
24194
- page = 1,
24195
- limit = 10
24196
- }) {
24197
- page = page > 0 ? page - 1 : 0;
24198
- const query = {
24199
- itemId: new ObjectId67(itemId)
24200
- };
24201
- if (type) {
24202
- query.type = type;
24203
- }
24204
- const cacheKey = makeCacheKey37(namespace_collection, {
24205
- itemId,
24206
- type,
24207
- page,
24208
- limit,
24209
- tag: "byItemId"
24210
- });
24211
- try {
24212
- const cached = await repo.getCache(cacheKey);
24213
- if (cached)
24214
- return cached;
24215
- const items = await repo.collection.aggregate([
24216
- { $match: query },
24217
- { $sort: { createdAt: -1 } },
24218
- { $skip: page * limit },
24219
- { $limit: limit }
24220
- ]).toArray();
24221
- const length = await repo.collection.countDocuments(query);
24222
- const data = paginate33(items, page, limit, length);
24223
- repo.setCache(cacheKey, data, 600);
24224
- return data;
24225
- } catch (error) {
24226
- logger58.log({ level: "error", message: `${error}` });
24227
- throw error;
24228
- }
24229
- }
24230
- async function getById(id) {
24231
- const cacheKey = makeCacheKey37(namespace_collection, {
24232
- id,
24233
- tag: "by-id"
24234
- });
24235
- try {
24236
- const cached = await repo.getCache(cacheKey);
24237
- if (cached)
24238
- return cached;
24239
- const result = await repo.collection.findOne({
24240
- _id: new ObjectId67(id)
24241
- });
24242
- if (!result) {
24243
- throw new BadRequestError117("Stock movement not found.");
24244
- }
24245
- repo.setCache(cacheKey, result, 300);
24246
- return result;
24247
- } catch (error) {
24248
- if (error instanceof AppError56)
24249
- throw error;
24250
- throw new InternalServerError52("Failed to get stock movement.");
24251
- }
24252
- }
24253
- return {
24254
- createIndexes,
24255
- add,
24256
- getByItemId,
24257
- getById
24258
- };
24259
- }
24260
-
24261
- // src/resources/asset-item-movement/stock.movement.service.ts
24262
- import { BadRequestError as BadRequestError118 } from "@goweekdays/utils";
24263
- import { useAtlas as useAtlas18 } from "@goweekdays/utils";
24264
- function useStockMovementService() {
24265
- const movementRepo = useStockMovementRepo();
24266
- const assetItemRepo = useAssetItemRepo();
24267
- const assetUnitRepo = useAssetUnitRepo();
24268
- async function stockIn(value, units) {
24269
- const item = await assetItemRepo.getById(String(value.itemId));
24270
- const session = useAtlas18.getClient()?.startSession();
24271
- if (!session)
24272
- throw new BadRequestError118("Failed to start session.");
24273
- try {
24274
- session.startTransaction();
24275
- value.type = "in";
24276
- const movementId = await movementRepo.add(value, session);
24277
- if (item.trackingType === "individual" && units && units.length > 0) {
24278
- for (const unit of units) {
24279
- await assetUnitRepo.add(
24280
- {
24281
- itemId: value.itemId,
24282
- serialNumber: unit.serialNumber,
24283
- plateNumber: unit.plateNumber,
24284
- status: "available",
24285
- locationId: value.toLocationId
24286
- },
24287
- session
24288
- );
24289
- }
24290
- }
24291
- await assetItemRepo.incrementQuantity(
24292
- String(value.itemId),
24293
- value.quantity,
24294
- session
24295
- );
24296
- await session.commitTransaction();
24297
- return movementId;
24298
- } catch (error) {
24299
- await session.abortTransaction();
24300
- throw error;
24301
- } finally {
24302
- await session.endSession();
24303
- }
24304
- }
24305
- async function stockOut(value, unitIds) {
24306
- const item = await assetItemRepo.getById(String(value.itemId));
24307
- if (item.trackingType === "quantity" && (item.quantityOnHand ?? 0) < value.quantity) {
24308
- throw new BadRequestError118("Insufficient stock.");
24309
- }
24310
- const session = useAtlas18.getClient()?.startSession();
24311
- if (!session)
24312
- throw new BadRequestError118("Failed to start session.");
24313
- try {
24314
- session.startTransaction();
24315
- value.type = "out";
24316
- const movementId = await movementRepo.add(value, session);
24317
- if (item.trackingType === "individual" && unitIds && unitIds.length > 0) {
24318
- for (const unitId of unitIds) {
24319
- await assetUnitRepo.updateById(
24320
- unitId,
24321
- { status: "assigned", assignedTo: value.reference?.id },
24322
- session
24323
- );
24324
- }
24325
- }
24326
- await assetItemRepo.incrementQuantity(
24327
- String(value.itemId),
24328
- -value.quantity,
24329
- session
24330
- );
24331
- await session.commitTransaction();
24332
- return movementId;
24333
- } catch (error) {
24334
- await session.abortTransaction();
24335
- throw error;
24336
- } finally {
24337
- await session.endSession();
24338
- }
24339
- }
24340
- async function transfer(value, unitIds) {
24341
- if (!value.fromLocationId || !value.toLocationId) {
24342
- throw new BadRequestError118(
24343
- "Transfer requires both fromLocationId and toLocationId."
24344
- );
24345
- }
24346
- const item = await assetItemRepo.getById(String(value.itemId));
24347
- const session = useAtlas18.getClient()?.startSession();
24348
- if (!session)
24349
- throw new BadRequestError118("Failed to start session.");
24074
+ const item = await assetItemRepo.getById(String(value.itemId));
24075
+ const session = useAtlas17.getClient()?.startSession();
24076
+ if (!session)
24077
+ throw new BadRequestError115("Failed to start session.");
24350
24078
  try {
24351
24079
  session.startTransaction();
24352
24080
  value.type = "transfer";
@@ -24371,11 +24099,11 @@ function useStockMovementService() {
24371
24099
  }
24372
24100
  async function adjustment(value) {
24373
24101
  if (!value.reason) {
24374
- throw new BadRequestError118("Adjustment requires a reason.");
24102
+ throw new BadRequestError115("Adjustment requires a reason.");
24375
24103
  }
24376
- const session = useAtlas18.getClient()?.startSession();
24104
+ const session = useAtlas17.getClient()?.startSession();
24377
24105
  if (!session)
24378
- throw new BadRequestError118("Failed to start session.");
24106
+ throw new BadRequestError115("Failed to start session.");
24379
24107
  try {
24380
24108
  session.startTransaction();
24381
24109
  value.type = "adjustment";
@@ -24397,14 +24125,14 @@ function useStockMovementService() {
24397
24125
  async function conversion(newItem, quantity, unitIds) {
24398
24126
  const sourceItem = await assetItemRepo.getById(String(newItem.itemRefId));
24399
24127
  if (!newItem.itemRefId) {
24400
- throw new BadRequestError118("Conversion requires itemRefId.");
24128
+ throw new BadRequestError115("Conversion requires itemRefId.");
24401
24129
  }
24402
24130
  if (sourceItem.trackingType === "quantity" && (sourceItem.quantityOnHand ?? 0) < quantity) {
24403
- throw new BadRequestError118("Insufficient stock on source item.");
24131
+ throw new BadRequestError115("Insufficient stock on source item.");
24404
24132
  }
24405
- const session = useAtlas18.getClient()?.startSession();
24133
+ const session = useAtlas17.getClient()?.startSession();
24406
24134
  if (!session)
24407
- throw new BadRequestError118("Failed to start session.");
24135
+ throw new BadRequestError115("Failed to start session.");
24408
24136
  try {
24409
24137
  session.startTransaction();
24410
24138
  const newItemId = await assetItemRepo.add(newItem, session);
@@ -24455,93 +24183,93 @@ function useStockMovementService() {
24455
24183
  }
24456
24184
 
24457
24185
  // src/resources/asset-item-movement/stock.movement.controller.ts
24458
- import Joi104 from "joi";
24459
- import { BadRequestError as BadRequestError119 } from "@goweekdays/utils";
24460
- var querySchema2 = Joi104.object({
24461
- itemId: Joi104.string().hex().length(24).required(),
24462
- type: Joi104.string().valid(...stockMovementTypes).optional().allow("", null),
24463
- page: Joi104.number().min(1).optional().allow("", null),
24464
- limit: Joi104.number().min(1).optional().allow("", null)
24465
- });
24466
- var idParamSchema4 = Joi104.object({
24467
- id: Joi104.string().hex().length(24).required()
24186
+ import Joi102 from "joi";
24187
+ import { BadRequestError as BadRequestError116 } from "@goweekdays/utils";
24188
+ var querySchema = Joi102.object({
24189
+ itemId: Joi102.string().hex().length(24).required(),
24190
+ type: Joi102.string().valid(...stockMovementTypes).optional().allow("", null),
24191
+ page: Joi102.number().min(1).optional().allow("", null),
24192
+ limit: Joi102.number().min(1).optional().allow("", null)
24468
24193
  });
24469
- var stockInSchema = Joi104.object({
24470
- itemId: Joi104.string().hex().length(24).required(),
24471
- quantity: Joi104.number().positive().required(),
24472
- unitCost: Joi104.number().min(0).optional().allow(null),
24473
- totalCost: Joi104.number().min(0).optional().allow(null),
24474
- reference: Joi104.object({
24475
- type: Joi104.string().valid("purchase", "sale", "transfer", "manual", "conversion").required(),
24476
- id: Joi104.string().optional().allow("", null)
24194
+ var idParamSchema2 = Joi102.object({
24195
+ id: Joi102.string().hex().length(24).required()
24196
+ });
24197
+ var stockInSchema = Joi102.object({
24198
+ itemId: Joi102.string().hex().length(24).required(),
24199
+ quantity: Joi102.number().positive().required(),
24200
+ unitCost: Joi102.number().min(0).optional().allow(null),
24201
+ totalCost: Joi102.number().min(0).optional().allow(null),
24202
+ reference: Joi102.object({
24203
+ type: Joi102.string().valid("purchase", "sale", "transfer", "manual", "conversion").required(),
24204
+ id: Joi102.string().optional().allow("", null)
24477
24205
  }).optional().allow(null),
24478
- toLocationId: Joi104.string().optional().allow("", null),
24479
- units: Joi104.array().items(
24480
- Joi104.object({
24481
- serialNumber: Joi104.string().optional().allow("", null),
24482
- plateNumber: Joi104.string().optional().allow("", null)
24206
+ toLocationId: Joi102.string().optional().allow("", null),
24207
+ units: Joi102.array().items(
24208
+ Joi102.object({
24209
+ serialNumber: Joi102.string().optional().allow("", null),
24210
+ plateNumber: Joi102.string().optional().allow("", null)
24483
24211
  })
24484
24212
  ).optional()
24485
24213
  });
24486
- var stockOutSchema = Joi104.object({
24487
- itemId: Joi104.string().hex().length(24).required(),
24488
- quantity: Joi104.number().positive().required(),
24489
- unitCost: Joi104.number().min(0).optional().allow(null),
24490
- totalCost: Joi104.number().min(0).optional().allow(null),
24491
- reference: Joi104.object({
24492
- type: Joi104.string().valid("purchase", "sale", "transfer", "manual", "conversion").required(),
24493
- id: Joi104.string().optional().allow("", null)
24214
+ var stockOutSchema = Joi102.object({
24215
+ itemId: Joi102.string().hex().length(24).required(),
24216
+ quantity: Joi102.number().positive().required(),
24217
+ unitCost: Joi102.number().min(0).optional().allow(null),
24218
+ totalCost: Joi102.number().min(0).optional().allow(null),
24219
+ reference: Joi102.object({
24220
+ type: Joi102.string().valid("purchase", "sale", "transfer", "manual", "conversion").required(),
24221
+ id: Joi102.string().optional().allow("", null)
24494
24222
  }).optional().allow(null),
24495
- fromLocationId: Joi104.string().optional().allow("", null),
24496
- unitIds: Joi104.array().items(Joi104.string().hex().length(24)).optional()
24223
+ fromLocationId: Joi102.string().optional().allow("", null),
24224
+ unitIds: Joi102.array().items(Joi102.string().hex().length(24)).optional()
24497
24225
  });
24498
- var transferSchema = Joi104.object({
24499
- itemId: Joi104.string().hex().length(24).required(),
24500
- quantity: Joi104.number().positive().required(),
24501
- fromLocationId: Joi104.string().required(),
24502
- toLocationId: Joi104.string().required(),
24503
- reference: Joi104.object({
24504
- type: Joi104.string().valid("purchase", "sale", "transfer", "manual", "conversion").required(),
24505
- id: Joi104.string().optional().allow("", null)
24226
+ var transferSchema = Joi102.object({
24227
+ itemId: Joi102.string().hex().length(24).required(),
24228
+ quantity: Joi102.number().positive().required(),
24229
+ fromLocationId: Joi102.string().required(),
24230
+ toLocationId: Joi102.string().required(),
24231
+ reference: Joi102.object({
24232
+ type: Joi102.string().valid("purchase", "sale", "transfer", "manual", "conversion").required(),
24233
+ id: Joi102.string().optional().allow("", null)
24506
24234
  }).optional().allow(null),
24507
- unitIds: Joi104.array().items(Joi104.string().hex().length(24)).optional()
24235
+ unitIds: Joi102.array().items(Joi102.string().hex().length(24)).optional()
24508
24236
  });
24509
- var adjustmentSchema = Joi104.object({
24510
- itemId: Joi104.string().hex().length(24).required(),
24511
- quantity: Joi104.number().required(),
24512
- reason: Joi104.string().required(),
24513
- reference: Joi104.object({
24514
- type: Joi104.string().valid("purchase", "sale", "transfer", "manual", "conversion").required(),
24515
- id: Joi104.string().optional().allow("", null)
24237
+ var adjustmentSchema = Joi102.object({
24238
+ itemId: Joi102.string().hex().length(24).required(),
24239
+ quantity: Joi102.number().required(),
24240
+ reason: Joi102.string().required(),
24241
+ reference: Joi102.object({
24242
+ type: Joi102.string().valid("purchase", "sale", "transfer", "manual", "conversion").required(),
24243
+ id: Joi102.string().optional().allow("", null)
24516
24244
  }).optional().allow(null)
24517
24245
  });
24518
- var conversionSchema = Joi104.object({
24519
- quantity: Joi104.number().positive().required(),
24520
- newItem: Joi104.object({
24521
- name: Joi104.string().required(),
24522
- description: Joi104.string().optional().allow("", null),
24523
- assetCategory: Joi104.string().valid(...assetItemCategories).required(),
24524
- assetClass: Joi104.string().valid(...assetItemClasses).required(),
24525
- trackingType: Joi104.string().valid(...assetItemTrackingTypes).required(),
24526
- purpose: Joi104.string().valid(...assetItemPurposes).required(),
24527
- itemRefId: Joi104.string().hex().length(24).required(),
24528
- remarks: Joi104.string().optional().allow("", null),
24529
- departmentId: Joi104.string().required(),
24530
- departmentName: Joi104.string().required(),
24531
- categoryId: Joi104.string().required(),
24532
- categoryName: Joi104.string().required(),
24533
- subcategoryId: Joi104.string().required(),
24534
- subcategoryName: Joi104.string().required(),
24535
- categoryPath: Joi104.string().required(),
24536
- brand: Joi104.string().optional().allow("", null),
24537
- tags: Joi104.array().items(
24538
- Joi104.object({
24539
- id: Joi104.string().required(),
24540
- name: Joi104.string().required()
24246
+ var conversionSchema = Joi102.object({
24247
+ quantity: Joi102.number().positive().required(),
24248
+ newItem: Joi102.object({
24249
+ name: Joi102.string().required(),
24250
+ description: Joi102.string().optional().allow("", null),
24251
+ assetCategory: Joi102.string().valid(...assetItemCategories).required(),
24252
+ assetClass: Joi102.string().valid(...assetItemClasses).required(),
24253
+ trackingType: Joi102.string().valid(...assetItemTrackingTypes).required(),
24254
+ purpose: Joi102.string().valid(...assetItemPurposes).required(),
24255
+ itemRefId: Joi102.string().hex().length(24).required(),
24256
+ remarks: Joi102.string().optional().allow("", null),
24257
+ departmentId: Joi102.string().required(),
24258
+ departmentName: Joi102.string().required(),
24259
+ categoryId: Joi102.string().required(),
24260
+ categoryName: Joi102.string().required(),
24261
+ subcategoryId: Joi102.string().required(),
24262
+ subcategoryName: Joi102.string().required(),
24263
+ categoryPath: Joi102.string().required(),
24264
+ brand: Joi102.string().optional().allow("", null),
24265
+ tags: Joi102.array().items(
24266
+ Joi102.object({
24267
+ id: Joi102.string().required(),
24268
+ name: Joi102.string().required()
24541
24269
  })
24542
24270
  ).optional().default([])
24543
24271
  }).required(),
24544
- unitIds: Joi104.array().items(Joi104.string().hex().length(24)).optional()
24272
+ unitIds: Joi102.array().items(Joi102.string().hex().length(24)).optional()
24545
24273
  });
24546
24274
  function useStockMovementController() {
24547
24275
  const repo = useStockMovementRepo();
@@ -24550,7 +24278,7 @@ function useStockMovementController() {
24550
24278
  try {
24551
24279
  const { error } = stockInSchema.validate(req.body);
24552
24280
  if (error) {
24553
- next(new BadRequestError119(error.message));
24281
+ next(new BadRequestError116(error.message));
24554
24282
  return;
24555
24283
  }
24556
24284
  const { units, ...movement } = req.body;
@@ -24567,7 +24295,7 @@ function useStockMovementController() {
24567
24295
  try {
24568
24296
  const { error } = stockOutSchema.validate(req.body);
24569
24297
  if (error) {
24570
- next(new BadRequestError119(error.message));
24298
+ next(new BadRequestError116(error.message));
24571
24299
  return;
24572
24300
  }
24573
24301
  const { unitIds, ...movement } = req.body;
@@ -24584,7 +24312,7 @@ function useStockMovementController() {
24584
24312
  try {
24585
24313
  const { error } = transferSchema.validate(req.body);
24586
24314
  if (error) {
24587
- next(new BadRequestError119(error.message));
24315
+ next(new BadRequestError116(error.message));
24588
24316
  return;
24589
24317
  }
24590
24318
  const { unitIds, ...movement } = req.body;
@@ -24601,7 +24329,7 @@ function useStockMovementController() {
24601
24329
  try {
24602
24330
  const { error } = adjustmentSchema.validate(req.body);
24603
24331
  if (error) {
24604
- next(new BadRequestError119(error.message));
24332
+ next(new BadRequestError116(error.message));
24605
24333
  return;
24606
24334
  }
24607
24335
  const movementId = await service.adjustment(req.body);
@@ -24614,9 +24342,9 @@ function useStockMovementController() {
24614
24342
  }
24615
24343
  }
24616
24344
  async function getByItemId(req, res, next) {
24617
- const { error } = querySchema2.validate(req.query);
24345
+ const { error } = querySchema.validate(req.query);
24618
24346
  if (error) {
24619
- next(new BadRequestError119(error.message));
24347
+ next(new BadRequestError116(error.message));
24620
24348
  return;
24621
24349
  }
24622
24350
  const itemId = req.query.itemId;
@@ -24631,9 +24359,9 @@ function useStockMovementController() {
24631
24359
  }
24632
24360
  }
24633
24361
  async function getById(req, res, next) {
24634
- const { error } = idParamSchema4.validate(req.params);
24362
+ const { error } = idParamSchema2.validate(req.params);
24635
24363
  if (error) {
24636
- next(new BadRequestError119(error.message));
24364
+ next(new BadRequestError116(error.message));
24637
24365
  return;
24638
24366
  }
24639
24367
  try {
@@ -24647,7 +24375,7 @@ function useStockMovementController() {
24647
24375
  try {
24648
24376
  const { error } = conversionSchema.validate(req.body);
24649
24377
  if (error) {
24650
- next(new BadRequestError119(error.message));
24378
+ next(new BadRequestError116(error.message));
24651
24379
  return;
24652
24380
  }
24653
24381
  const { quantity, newItem, unitIds } = req.body;
@@ -24672,6 +24400,406 @@ function useStockMovementController() {
24672
24400
  };
24673
24401
  }
24674
24402
 
24403
+ // src/resources/asset-item-unit/asset.unit.controller.ts
24404
+ import Joi103 from "joi";
24405
+ import { BadRequestError as BadRequestError117 } from "@goweekdays/utils";
24406
+ var querySchema2 = Joi103.object({
24407
+ itemId: Joi103.string().hex().length(24).required(),
24408
+ status: Joi103.string().valid(...assetUnitStatuses).optional().allow("", null),
24409
+ page: Joi103.number().min(1).optional().allow("", null),
24410
+ limit: Joi103.number().min(1).optional().allow("", null)
24411
+ });
24412
+ var idParamSchema3 = Joi103.object({
24413
+ id: Joi103.string().hex().length(24).required()
24414
+ });
24415
+ function useAssetUnitController() {
24416
+ const repo = useAssetUnitRepo();
24417
+ async function add(req, res, next) {
24418
+ try {
24419
+ const { error } = schemaAssetUnit.validate(req.body);
24420
+ if (error) {
24421
+ next(new BadRequestError117(error.message));
24422
+ return;
24423
+ }
24424
+ const unitId = await repo.add(req.body);
24425
+ res.status(201).json({
24426
+ message: "Asset unit created successfully.",
24427
+ unitId
24428
+ });
24429
+ } catch (error) {
24430
+ next(error);
24431
+ }
24432
+ }
24433
+ async function getByItemId(req, res, next) {
24434
+ const { error } = querySchema2.validate(req.query);
24435
+ if (error) {
24436
+ next(new BadRequestError117(error.message));
24437
+ return;
24438
+ }
24439
+ const itemId = req.query.itemId;
24440
+ const status2 = req.query.status ?? "";
24441
+ const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
24442
+ const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
24443
+ try {
24444
+ const results = await repo.getByItemId({ itemId, status: status2, page, limit });
24445
+ res.json(results);
24446
+ } catch (error2) {
24447
+ next(error2);
24448
+ }
24449
+ }
24450
+ async function getById(req, res, next) {
24451
+ const { error } = idParamSchema3.validate(req.params);
24452
+ if (error) {
24453
+ next(new BadRequestError117(error.message));
24454
+ return;
24455
+ }
24456
+ try {
24457
+ const unit = await repo.getById(req.params.id);
24458
+ res.json(unit);
24459
+ } catch (error2) {
24460
+ next(error2);
24461
+ }
24462
+ }
24463
+ async function updateById(req, res, next) {
24464
+ const { error: paramError } = idParamSchema3.validate(req.params);
24465
+ if (paramError) {
24466
+ next(new BadRequestError117(paramError.message));
24467
+ return;
24468
+ }
24469
+ const { error: bodyError } = schemaAssetUnitUpdate.validate(req.body);
24470
+ if (bodyError) {
24471
+ next(new BadRequestError117(bodyError.message));
24472
+ return;
24473
+ }
24474
+ try {
24475
+ const updatedUnit = await repo.updateById(req.params.id, req.body);
24476
+ res.json({
24477
+ message: "Asset unit updated successfully.",
24478
+ unit: updatedUnit
24479
+ });
24480
+ } catch (error) {
24481
+ next(error);
24482
+ }
24483
+ }
24484
+ return {
24485
+ add,
24486
+ getByItemId,
24487
+ getById,
24488
+ updateById
24489
+ };
24490
+ }
24491
+
24492
+ // src/resources/asset-item/asset.item.service.ts
24493
+ function normalizeTagName(name) {
24494
+ return name.trim().toLowerCase().replace(/\s+/g, "-");
24495
+ }
24496
+ function useAssetItemService() {
24497
+ const assetItemRepo = useAssetItemRepo();
24498
+ const tagRepo = useTagRepo();
24499
+ const categoryRepo = useCategoryRepo();
24500
+ const stockMovementRepo = useStockMovementRepo();
24501
+ const assetUnitRepo = useAssetUnitRepo();
24502
+ async function resolveTags(tagNames, orgId, categoryPath, session) {
24503
+ const resolvedTags = [];
24504
+ for (const tag of tagNames) {
24505
+ const normalizedName = normalizeTagName(tag.name);
24506
+ const existing = await tagRepo.findByNormalizedNameAndOrg(
24507
+ normalizedName,
24508
+ orgId
24509
+ );
24510
+ if (existing && existing._id) {
24511
+ await tagRepo.incrementUsageCount(existing._id, 1, session);
24512
+ resolvedTags.push({
24513
+ id: String(existing._id),
24514
+ name: existing.name
24515
+ });
24516
+ } else {
24517
+ const tagData = {
24518
+ name: tag.name.trim(),
24519
+ normalizedName,
24520
+ type: "private",
24521
+ orgId,
24522
+ categoryPath,
24523
+ status: "active",
24524
+ usageCount: 1
24525
+ };
24526
+ const tagId = await tagRepo.add(tagData, session);
24527
+ resolvedTags.push({
24528
+ id: String(tagId),
24529
+ name: tag.name.trim()
24530
+ });
24531
+ }
24532
+ }
24533
+ return resolvedTags;
24534
+ }
24535
+ async function add(value) {
24536
+ const session = useAtlas18.getClient()?.startSession();
24537
+ if (!session) {
24538
+ throw new InternalServerError52(
24539
+ "Unable to start session for asset item service."
24540
+ );
24541
+ }
24542
+ try {
24543
+ await session.startTransaction();
24544
+ const department = await categoryRepo.getById(value.departmentId);
24545
+ value.departmentName = department.displayName;
24546
+ if (value.categoryId) {
24547
+ const category = await categoryRepo.getById(value.categoryId);
24548
+ value.categoryName = category.displayName;
24549
+ }
24550
+ if (value.subcategoryId) {
24551
+ const subcategory = await categoryRepo.getById(value.subcategoryId);
24552
+ value.subcategoryName = subcategory.displayName;
24553
+ }
24554
+ const categoryPath = buildCategoryPath(
24555
+ value.departmentName,
24556
+ value.categoryName ?? "",
24557
+ value.subcategoryName ?? ""
24558
+ );
24559
+ value.categoryPath = categoryPath;
24560
+ const resolvedTags = value.tags.length ? await resolveTags(
24561
+ value.tags,
24562
+ value.orgId,
24563
+ value.categoryPath,
24564
+ session
24565
+ ) : [];
24566
+ const assetItem = {
24567
+ ...value,
24568
+ tags: resolvedTags
24569
+ };
24570
+ const assetItemId = await assetItemRepo.add(assetItem, session);
24571
+ await session.commitTransaction();
24572
+ return assetItemId;
24573
+ } catch (error) {
24574
+ await session.abortTransaction();
24575
+ if (error instanceof AppError56)
24576
+ throw error;
24577
+ throw new InternalServerError52("Failed to create asset item.");
24578
+ } finally {
24579
+ session.endSession();
24580
+ }
24581
+ }
24582
+ async function makePublic(id, value) {
24583
+ try {
24584
+ await assetItemRepo.updateById(id, {
24585
+ isPublic: value,
24586
+ updatedAt: /* @__PURE__ */ new Date()
24587
+ });
24588
+ return "Asset item visibility updated successfully.";
24589
+ } catch (error) {
24590
+ if (error instanceof AppError56)
24591
+ throw error;
24592
+ throw new InternalServerError52("Failed to update asset item visibility.");
24593
+ }
24594
+ }
24595
+ async function deleteById(id) {
24596
+ const [movementCount, unitCount] = await Promise.all([
24597
+ stockMovementRepo.countByItemId(id),
24598
+ assetUnitRepo.countByItemId(id)
24599
+ ]);
24600
+ if (movementCount > 0 || unitCount > 0) {
24601
+ throw new BadRequestError118(
24602
+ "Cannot delete asset item because it has associated movement or unit records."
24603
+ );
24604
+ }
24605
+ try {
24606
+ await assetItemRepo.deleteById(id);
24607
+ return "Asset item deleted successfully.";
24608
+ } catch (error) {
24609
+ if (error instanceof AppError56)
24610
+ throw error;
24611
+ throw new InternalServerError52("Failed to delete asset item.");
24612
+ }
24613
+ }
24614
+ return {
24615
+ add,
24616
+ makePublic,
24617
+ deleteById
24618
+ };
24619
+ }
24620
+
24621
+ // src/resources/asset-item/asset.item.controller.ts
24622
+ import Joi104 from "joi";
24623
+ import {
24624
+ AppError as AppError57,
24625
+ BadRequestError as BadRequestError119,
24626
+ InternalServerError as InternalServerError53
24627
+ } from "@goweekdays/utils";
24628
+ var paginationSchema3 = Joi104.object({
24629
+ page: Joi104.number().min(1).optional().allow("", null),
24630
+ limit: Joi104.number().min(1).optional().allow("", null),
24631
+ search: Joi104.string().optional().allow("", null),
24632
+ status: Joi104.string().valid(...assetItemStatuses).optional().allow("", null),
24633
+ assetCategory: Joi104.string().valid(...assetItemCategories).optional().allow("", null),
24634
+ trackingType: Joi104.string().valid(...assetItemTrackingTypes).optional().allow("", null),
24635
+ purpose: Joi104.string().valid(...assetItemPurposes).optional().allow("", null),
24636
+ departmentId: Joi104.string().optional().allow("", null),
24637
+ categoryId: Joi104.string().optional().allow("", null),
24638
+ subcategoryId: Joi104.string().optional().allow("", null),
24639
+ brand: Joi104.string().optional().allow("", null),
24640
+ tags: Joi104.string().optional().allow("", null),
24641
+ public: Joi104.boolean().optional().allow("", null)
24642
+ });
24643
+ var idParamSchema4 = Joi104.object({
24644
+ id: Joi104.string().hex().length(24).required()
24645
+ });
24646
+ function useAssetItemController() {
24647
+ const repo = useAssetItemRepo();
24648
+ const service = useAssetItemService();
24649
+ async function add(req, res, next) {
24650
+ try {
24651
+ const { error, value } = schemaAssetItemCreate.validate(req.body);
24652
+ if (error) {
24653
+ next(new BadRequestError119(error.message));
24654
+ return;
24655
+ }
24656
+ const assetItemId = await service.add(value);
24657
+ res.status(201).json({
24658
+ message: "Asset item created successfully.",
24659
+ assetItemId
24660
+ });
24661
+ } catch (error) {
24662
+ next(error);
24663
+ }
24664
+ }
24665
+ async function getAll(req, res, next) {
24666
+ const { error } = paginationSchema3.validate(req.query);
24667
+ if (error) {
24668
+ next(new BadRequestError119(error.message));
24669
+ return;
24670
+ }
24671
+ const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
24672
+ const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
24673
+ const search = req.query.search ?? "";
24674
+ const status2 = req.query.status ?? "active";
24675
+ const assetCategory = req.query.assetCategory ?? "";
24676
+ const trackingType = req.query.trackingType ?? "";
24677
+ const purpose = req.query.purpose ?? "";
24678
+ const departmentId = req.query.departmentId ?? "";
24679
+ const categoryId = req.query.categoryId ?? "";
24680
+ const subcategoryId = req.query.subcategoryId ?? "";
24681
+ const brand = req.query.brand ?? "";
24682
+ const tagsParam = req.query.tags ?? "";
24683
+ const tags = tagsParam ? tagsParam.split(",").filter(Boolean) : [];
24684
+ const isPublic = req.query.public === "true";
24685
+ if (!isFinite(page)) {
24686
+ next(new BadRequestError119("Invalid page number."));
24687
+ return;
24688
+ }
24689
+ if (!isFinite(limit)) {
24690
+ next(new BadRequestError119("Invalid limit number."));
24691
+ return;
24692
+ }
24693
+ try {
24694
+ const results = await repo.getAll({
24695
+ page,
24696
+ limit,
24697
+ search,
24698
+ status: status2,
24699
+ assetCategory,
24700
+ trackingType,
24701
+ purpose,
24702
+ departmentId,
24703
+ categoryId,
24704
+ subcategoryId,
24705
+ brand,
24706
+ tags,
24707
+ isPublic
24708
+ });
24709
+ res.json(results);
24710
+ } catch (error2) {
24711
+ next(error2);
24712
+ }
24713
+ }
24714
+ async function getById(req, res, next) {
24715
+ const { error } = idParamSchema4.validate(req.params);
24716
+ if (error) {
24717
+ next(new BadRequestError119(error.message));
24718
+ return;
24719
+ }
24720
+ try {
24721
+ const assetItem = await repo.getById(req.params.id);
24722
+ res.json(assetItem);
24723
+ } catch (error2) {
24724
+ next(error2);
24725
+ }
24726
+ }
24727
+ async function updateById(req, res, next) {
24728
+ const { error: paramError } = Joi104.object({
24729
+ id: Joi104.string().hex().length(24).required(),
24730
+ orgId: Joi104.string().hex().required()
24731
+ }).validate(req.params);
24732
+ if (paramError) {
24733
+ next(new BadRequestError119(paramError.message));
24734
+ return;
24735
+ }
24736
+ const { error: bodyError } = schemaAssetItemUpdate.validate(req.body);
24737
+ if (bodyError) {
24738
+ next(new BadRequestError119(bodyError.message));
24739
+ return;
24740
+ }
24741
+ try {
24742
+ const updatedAssetItem = await repo.updateById(req.params.id, req.body);
24743
+ res.json({
24744
+ message: "Asset item updated successfully.",
24745
+ assetItem: updatedAssetItem
24746
+ });
24747
+ } catch (error) {
24748
+ next(error);
24749
+ }
24750
+ }
24751
+ async function makePublic(req, res, next) {
24752
+ const { error, value } = Joi104.object({
24753
+ orgId: Joi104.string().hex().required(),
24754
+ id: Joi104.string().hex().length(24).required(),
24755
+ isPublic: Joi104.boolean().required()
24756
+ }).validate({ ...req.params, ...req.body });
24757
+ if (error) {
24758
+ next(new BadRequestError119(error.message));
24759
+ return;
24760
+ }
24761
+ try {
24762
+ const message = await service.makePublic(value.id, value.isPublic);
24763
+ res.json({
24764
+ message
24765
+ });
24766
+ return;
24767
+ } catch (error2) {
24768
+ if (error2 instanceof AppError57) {
24769
+ next(error2);
24770
+ return;
24771
+ }
24772
+ next(new InternalServerError53("Failed to update asset item visibility."));
24773
+ }
24774
+ }
24775
+ async function deleteById(req, res, next) {
24776
+ const { error } = Joi104.object({
24777
+ id: Joi104.string().hex().length(24).required(),
24778
+ orgId: Joi104.string().hex().required()
24779
+ }).validate(req.params);
24780
+ if (error) {
24781
+ next(new BadRequestError119(error.message));
24782
+ return;
24783
+ }
24784
+ try {
24785
+ await service.deleteById(req.params.id);
24786
+ res.json({
24787
+ message: "Asset item deleted successfully."
24788
+ });
24789
+ } catch (error2) {
24790
+ next(error2);
24791
+ }
24792
+ }
24793
+ return {
24794
+ add,
24795
+ getAll,
24796
+ getById,
24797
+ updateById,
24798
+ makePublic,
24799
+ deleteById
24800
+ };
24801
+ }
24802
+
24675
24803
  // src/resources/asset-item-category/category.service.ts
24676
24804
  import { BadRequestError as BadRequestError120 } from "@goweekdays/utils";
24677
24805
  function useCategoryService() {
@@ -24862,7 +24990,7 @@ function useCategoryController() {
24862
24990
  }
24863
24991
 
24864
24992
  // src/resources/tag/tag.service.ts
24865
- import { AppError as AppError57, BadRequestError as BadRequestError122 } from "@goweekdays/utils";
24993
+ import { AppError as AppError58, BadRequestError as BadRequestError122 } from "@goweekdays/utils";
24866
24994
  import Joi106 from "joi";
24867
24995
  function normalizeTagName2(name) {
24868
24996
  return name.trim().toLowerCase().replace(/\s+/g, "-");
@@ -24893,7 +25021,7 @@ function useTagService() {
24893
25021
  const id = await _add(data);
24894
25022
  return id;
24895
25023
  } catch (error2) {
24896
- if (error2 instanceof AppError57)
25024
+ if (error2 instanceof AppError58)
24897
25025
  throw error2;
24898
25026
  throw new BadRequestError122("Failed to add tag.");
24899
25027
  }