@eeplatform/core 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -11342,12 +11342,12 @@ __export(src_exports, {
11342
11342
  MAILER_TRANSPORT_PORT: () => MAILER_TRANSPORT_PORT,
11343
11343
  MAILER_TRANSPORT_SECURE: () => MAILER_TRANSPORT_SECURE,
11344
11344
  MAddress: () => MAddress,
11345
+ MAsset: () => MAsset,
11345
11346
  MBuilding: () => MBuilding,
11346
11347
  MBuildingUnit: () => MBuildingUnit,
11347
11348
  MDivision: () => MDivision,
11348
11349
  MEntity: () => MEntity,
11349
11350
  MFile: () => MFile,
11350
- MInventory: () => MInventory,
11351
11351
  MMember: () => MMember,
11352
11352
  MONGO_DB: () => MONGO_DB,
11353
11353
  MONGO_URI: () => MONGO_URI,
@@ -11358,6 +11358,7 @@ __export(src_exports, {
11358
11358
  MRegion: () => MRegion,
11359
11359
  MRole: () => MRole,
11360
11360
  MSchool: () => MSchool,
11361
+ MStockCard: () => MStockCard,
11361
11362
  MSubscription: () => MSubscription,
11362
11363
  MToken: () => MToken,
11363
11364
  MUser: () => MUser,
@@ -11385,16 +11386,19 @@ __export(src_exports, {
11385
11386
  addressSchema: () => addressSchema,
11386
11387
  isDev: () => isDev,
11387
11388
  schema: () => schema,
11389
+ schemaAsset: () => schemaAsset,
11390
+ schemaAssetUpdateOption: () => schemaAssetUpdateOption,
11388
11391
  schemaBuilding: () => schemaBuilding,
11389
11392
  schemaBuildingUnit: () => schemaBuildingUnit,
11390
11393
  schemaDivision: () => schemaDivision,
11391
- schemaInventory: () => schemaInventory,
11392
- schemaInventoryUpdateOption: () => schemaInventoryUpdateOption,
11393
11394
  schemaRegion: () => schemaRegion,
11394
11395
  schemaSchool: () => schemaSchool,
11396
+ schemaStockCard: () => schemaStockCard,
11395
11397
  schemaUpdateOptions: () => schemaUpdateOptions,
11396
11398
  useAddressController: () => useAddressController,
11397
11399
  useAddressRepo: () => useAddressRepo,
11400
+ useAssetController: () => useAssetController,
11401
+ useAssetRepo: () => useAssetRepo,
11398
11402
  useAuthController: () => useAuthController,
11399
11403
  useAuthService: () => useAuthService,
11400
11404
  useBuildingController: () => useBuildingController,
@@ -11411,8 +11415,6 @@ __export(src_exports, {
11411
11415
  useFileController: () => useFileController,
11412
11416
  useFileRepo: () => useFileRepo,
11413
11417
  useFileService: () => useFileService,
11414
- useInventoryController: () => useInventoryController,
11415
- useInventoryRepo: () => useInventoryRepo,
11416
11418
  useInvoiceController: () => useInvoiceController,
11417
11419
  useInvoiceModel: () => useInvoiceModel,
11418
11420
  useInvoiceRepo: () => useInvoiceRepo,
@@ -11444,6 +11446,8 @@ __export(src_exports, {
11444
11446
  useSchoolController: () => useSchoolController,
11445
11447
  useSchoolRepo: () => useSchoolRepo,
11446
11448
  useSchoolService: () => useSchoolService,
11449
+ useStockCardController: () => useStockCardController,
11450
+ useStockCardRepository: () => useStockCardRepository,
11447
11451
  useSubscriptionController: () => useSubscriptionController,
11448
11452
  useSubscriptionRepo: () => useSubscriptionRepo,
11449
11453
  useSubscriptionService: () => useSubscriptionService,
@@ -28085,19 +28089,19 @@ function useBuildingUnitController() {
28085
28089
  };
28086
28090
  }
28087
28091
 
28088
- // src/models/inventory.model.ts
28092
+ // src/models/asset.model.ts
28089
28093
  var import_nodejs_utils73 = require("@eeplatform/nodejs-utils");
28090
28094
  var import_joi36 = __toESM(require("joi"));
28091
28095
  var import_mongodb42 = require("mongodb");
28092
- var schemaInventory = import_joi36.default.object({
28096
+ var schemaAsset = import_joi36.default.object({
28093
28097
  _id: import_joi36.default.string().hex().optional(),
28094
28098
  school: import_joi36.default.string().hex().required(),
28099
+ asset_type: import_joi36.default.string().required().allow("supply", "furniture-equipment", "fixed-asset"),
28095
28100
  name: import_joi36.default.string().required(),
28096
28101
  category: import_joi36.default.string().optional().allow("", null),
28097
28102
  type: import_joi36.default.string().optional().allow("", null),
28098
28103
  brand: import_joi36.default.string().optional().allow("", null),
28099
- unit_of_measurement_category: import_joi36.default.string().required(),
28100
- unit_of_measurement_type: import_joi36.default.string().required(),
28104
+ unit: import_joi36.default.string().required(),
28101
28105
  status: import_joi36.default.string().optional().allow("", null),
28102
28106
  createdAt: import_joi36.default.date().optional().allow("", null),
28103
28107
  updatedAt: import_joi36.default.date().optional().allow("", null),
@@ -28113,14 +28117,13 @@ var schemaInventory = import_joi36.default.object({
28113
28117
  language: import_joi36.default.string().optional().allow("", null)
28114
28118
  }).optional().allow(null)
28115
28119
  });
28116
- var schemaInventoryUpdateOption = import_joi36.default.object({
28120
+ var schemaAssetUpdateOption = import_joi36.default.object({
28117
28121
  name: import_joi36.default.string().optional().allow("", null),
28118
28122
  category: import_joi36.default.string().optional().allow("", null),
28119
28123
  type: import_joi36.default.string().optional().allow("", null),
28120
28124
  brand: import_joi36.default.string().optional().allow("", null),
28121
28125
  qty: import_joi36.default.number().integer().min(0).optional().allow("", null),
28122
- unit_of_measurement_category: import_joi36.default.string().optional().allow("", null),
28123
- unit_of_measurement_type: import_joi36.default.string().optional().allow("", null),
28126
+ unit: import_joi36.default.string().optional().allow("", null),
28124
28127
  metadata: import_joi36.default.object({
28125
28128
  title: import_joi36.default.string().optional().allow("", null),
28126
28129
  isbn: import_joi36.default.string().optional().allow("", null),
@@ -28132,8 +28135,8 @@ var schemaInventoryUpdateOption = import_joi36.default.object({
28132
28135
  language: import_joi36.default.string().optional().allow("", null)
28133
28136
  }).optional().allow(null)
28134
28137
  });
28135
- function MInventory(value) {
28136
- const { error } = schemaInventory.validate(value);
28138
+ function MAsset(value) {
28139
+ const { error } = schemaAsset.validate(value);
28137
28140
  if (error) {
28138
28141
  throw new import_nodejs_utils73.BadRequestError(error.message);
28139
28142
  }
@@ -28155,6 +28158,7 @@ function MInventory(value) {
28155
28158
  return {
28156
28159
  _id: value._id ?? new import_mongodb42.ObjectId(),
28157
28160
  school: value.school,
28161
+ asset_type: value.asset_type ?? "supply",
28158
28162
  name: value.name,
28159
28163
  category: value.category ?? "",
28160
28164
  type: value.type ?? "",
@@ -28166,8 +28170,7 @@ function MInventory(value) {
28166
28170
  lost: 0,
28167
28171
  damaged: 0
28168
28172
  },
28169
- unit_of_measurement_category: value.unit_of_measurement_category ?? "",
28170
- unit_of_measurement_type: value.unit_of_measurement_type ?? "",
28173
+ unit: value.unit ?? "",
28171
28174
  status: value.status ?? "active",
28172
28175
  createdAt: value.createdAt,
28173
28176
  updatedAt: value.updatedAt,
@@ -28176,15 +28179,15 @@ function MInventory(value) {
28176
28179
  };
28177
28180
  }
28178
28181
 
28179
- // src/repositories/inventory.repository.ts
28182
+ // src/repositories/asset.repository.ts
28180
28183
  var import_nodejs_utils74 = require("@eeplatform/nodejs-utils");
28181
28184
  var import_mongodb43 = require("mongodb");
28182
- function useInventoryRepo() {
28185
+ function useAssetRepo() {
28183
28186
  const db = import_nodejs_utils74.useAtlas.getDb();
28184
28187
  if (!db) {
28185
28188
  throw new import_nodejs_utils74.BadRequestError("Unable to connect to server.");
28186
28189
  }
28187
- const namespace_collection = "school.inventories";
28190
+ const namespace_collection = "school.assets";
28188
28191
  const collection = db.collection(namespace_collection);
28189
28192
  const { getCache, setCache, delNamespace } = (0, import_nodejs_utils74.useCache)(namespace_collection);
28190
28193
  function delCachedData() {
@@ -28208,21 +28211,21 @@ function useInventoryRepo() {
28208
28211
  { key: { name: "text" } }
28209
28212
  ]);
28210
28213
  } catch (error) {
28211
- throw new import_nodejs_utils74.BadRequestError("Failed to create index on inventory.");
28214
+ throw new import_nodejs_utils74.BadRequestError("Failed to create index on asset.");
28212
28215
  }
28213
28216
  }
28214
28217
  async function add(value) {
28215
28218
  try {
28216
- value = MInventory(value);
28219
+ value = MAsset(value);
28217
28220
  const res = await collection.insertOne(value);
28218
28221
  delCachedData();
28219
28222
  return res.insertedId;
28220
28223
  } catch (error) {
28221
- throw new import_nodejs_utils74.BadRequestError("Failed to create inventory item.");
28224
+ throw new import_nodejs_utils74.BadRequestError("Failed to create asset item.");
28222
28225
  }
28223
28226
  }
28224
- async function updateById(_id, value) {
28225
- const { error } = schemaInventoryUpdateOption.validate(value);
28227
+ async function updateById(_id, value, session) {
28228
+ const { error } = schemaAssetUpdateOption.validate(value);
28226
28229
  if (error) {
28227
28230
  throw new import_nodejs_utils74.BadRequestError(error.message);
28228
28231
  }
@@ -28232,13 +28235,17 @@ function useInventoryRepo() {
28232
28235
  throw new import_nodejs_utils74.BadRequestError("Invalid ID.");
28233
28236
  }
28234
28237
  try {
28235
- const res = await collection.updateOne({ _id }, { $set: value });
28238
+ const res = await collection.updateOne(
28239
+ { _id },
28240
+ { $set: value },
28241
+ { session }
28242
+ );
28236
28243
  if (res.modifiedCount) {
28237
28244
  delCachedData();
28238
28245
  }
28239
- return "Successfully updated inventory item.";
28246
+ return "Successfully updated asset item.";
28240
28247
  } catch (error2) {
28241
- throw new import_nodejs_utils74.BadRequestError("Failed to update inventory item.");
28248
+ throw new import_nodejs_utils74.BadRequestError("Failed to update asset item.");
28242
28249
  }
28243
28250
  }
28244
28251
  async function deleteById(_id) {
@@ -28251,11 +28258,11 @@ function useInventoryRepo() {
28251
28258
  const res = await collection.deleteOne({ _id });
28252
28259
  if (res.deletedCount) {
28253
28260
  delCachedData();
28254
- return "Successfully deleted inventory item.";
28261
+ return "Successfully deleted asset item.";
28255
28262
  }
28256
- return "Successfully deleted inventory item.";
28263
+ return "Successfully deleted asset item.";
28257
28264
  } catch (error) {
28258
- throw new import_nodejs_utils74.BadRequestError("Failed to delete inventory item.");
28265
+ throw new import_nodejs_utils74.BadRequestError("Failed to delete asset item.");
28259
28266
  }
28260
28267
  }
28261
28268
  async function getById(_id) {
@@ -28272,17 +28279,17 @@ function useInventoryRepo() {
28272
28279
  try {
28273
28280
  const res = await collection.findOne({ _id });
28274
28281
  if (!res) {
28275
- throw new import_nodejs_utils74.BadRequestError("Inventory item not found.");
28282
+ throw new import_nodejs_utils74.BadRequestError("Asset item not found.");
28276
28283
  }
28277
28284
  setCache(cacheKey, res).then(() => {
28278
28285
  import_nodejs_utils74.logger.log({
28279
28286
  level: "info",
28280
- message: `Cache set for inventory item by ID: ${cacheKey}`
28287
+ message: `Cache set for asset item by ID: ${cacheKey}`
28281
28288
  });
28282
28289
  }).catch((err) => {
28283
28290
  import_nodejs_utils74.logger.log({
28284
28291
  level: "error",
28285
- message: `Failed to set cache for inventory item by ID: ${cacheKey} - ${err.message}`
28292
+ message: `Failed to set cache for asset item by ID: ${cacheKey} - ${err.message}`
28286
28293
  });
28287
28294
  });
28288
28295
  return res;
@@ -28290,7 +28297,7 @@ function useInventoryRepo() {
28290
28297
  if (error instanceof import_nodejs_utils74.BadRequestError) {
28291
28298
  throw error;
28292
28299
  }
28293
- throw new import_nodejs_utils74.BadRequestError("Failed to retrieve inventory item.");
28300
+ throw new import_nodejs_utils74.BadRequestError("Failed to retrieve asset item.");
28294
28301
  }
28295
28302
  }
28296
28303
  async function getAll({
@@ -28299,7 +28306,8 @@ function useInventoryRepo() {
28299
28306
  limit = 20,
28300
28307
  status = "active",
28301
28308
  school = "",
28302
- sort = { _id: -1 }
28309
+ sort = { _id: -1 },
28310
+ asset_type = "supply"
28303
28311
  } = {}) {
28304
28312
  page = page ? page - 1 : 0;
28305
28313
  try {
@@ -28309,14 +28317,16 @@ function useInventoryRepo() {
28309
28317
  }
28310
28318
  const query = {
28311
28319
  school,
28312
- status
28320
+ status,
28321
+ asset_type
28313
28322
  };
28314
28323
  const cacheKeyOptions = {
28315
28324
  page,
28316
28325
  limit,
28317
28326
  status,
28318
28327
  school: String(school),
28319
- sort: JSON.stringify(sort)
28328
+ sort: JSON.stringify(sort),
28329
+ asset_type
28320
28330
  };
28321
28331
  if (search) {
28322
28332
  query.$text = { $search: search };
@@ -28328,7 +28338,7 @@ function useInventoryRepo() {
28328
28338
  if (cached) {
28329
28339
  import_nodejs_utils74.logger.log({
28330
28340
  level: "info",
28331
- message: `Cache hit for getAll inventory items: ${cacheKey}`
28341
+ message: `Cache hit for getAll asset items: ${cacheKey}`
28332
28342
  });
28333
28343
  return cached;
28334
28344
  }
@@ -28349,18 +28359,194 @@ function useInventoryRepo() {
28349
28359
  setCache(cacheKey, data, 500).then(() => {
28350
28360
  import_nodejs_utils74.logger.log({
28351
28361
  level: "info",
28352
- message: `Cache set for getAll inventory items: ${cacheKey}`
28362
+ message: `Cache set for getAll asset items: ${cacheKey}`
28353
28363
  });
28354
28364
  }).catch((err) => {
28355
28365
  import_nodejs_utils74.logger.log({
28356
28366
  level: "error",
28357
- message: `Failed to set cache for getAll inventory items: ${err.message}`
28367
+ message: `Failed to set cache for getAll asset items: ${err.message}`
28358
28368
  });
28359
28369
  });
28360
28370
  return data;
28361
28371
  } catch (error) {
28362
28372
  console.log("Error in getAll:", error);
28363
- throw new import_nodejs_utils74.BadRequestError("Failed to retrieve inventory items.");
28373
+ throw new import_nodejs_utils74.BadRequestError("Failed to retrieve asset items.");
28374
+ }
28375
+ }
28376
+ async function getCategories(school, asset_type) {
28377
+ try {
28378
+ school = new import_mongodb43.ObjectId(school);
28379
+ } catch (error) {
28380
+ throw new import_nodejs_utils74.BadRequestError("Invalid school ID.");
28381
+ }
28382
+ const cacheKey = (0, import_nodejs_utils74.makeCacheKey)(namespace_collection, {
28383
+ school,
28384
+ asset_type,
28385
+ type: "category-as-options"
28386
+ });
28387
+ const cachedData = await getCache(cacheKey);
28388
+ if (cachedData) {
28389
+ return cachedData;
28390
+ }
28391
+ try {
28392
+ const categories = await collection.aggregate([
28393
+ {
28394
+ $match: { school, asset_type }
28395
+ },
28396
+ {
28397
+ $group: {
28398
+ _id: "$category",
28399
+ value: { $first: "$category" },
28400
+ title: {
28401
+ $first: "$category"
28402
+ }
28403
+ }
28404
+ },
28405
+ {
28406
+ $project: {
28407
+ _id: 0,
28408
+ title: 1,
28409
+ value: 1
28410
+ }
28411
+ },
28412
+ { $sort: { title: 1 } }
28413
+ ]).toArray();
28414
+ setCache(cacheKey, categories).then(() => {
28415
+ import_nodejs_utils74.logger.log({
28416
+ level: "info",
28417
+ message: `Cache set for getCategoriesBySchool: ${cacheKey}`
28418
+ });
28419
+ }).catch((err) => {
28420
+ import_nodejs_utils74.logger.log({
28421
+ level: "error",
28422
+ message: `Failed to set cache for getCategoriesBySchool: ${err.message}`
28423
+ });
28424
+ });
28425
+ return categories;
28426
+ } catch (error) {
28427
+ if (error instanceof import_nodejs_utils74.BadRequestError) {
28428
+ throw error;
28429
+ }
28430
+ throw new import_nodejs_utils74.BadRequestError("Failed to retrieve asset categories.");
28431
+ }
28432
+ }
28433
+ async function getTypes(school, asset_type) {
28434
+ try {
28435
+ school = new import_mongodb43.ObjectId(school);
28436
+ } catch (error) {
28437
+ throw new import_nodejs_utils74.BadRequestError("Invalid school ID.");
28438
+ }
28439
+ const cacheKey = (0, import_nodejs_utils74.makeCacheKey)(namespace_collection, {
28440
+ school,
28441
+ asset_type,
28442
+ type: "types-as-options"
28443
+ });
28444
+ const cachedData = await getCache(cacheKey);
28445
+ if (cachedData) {
28446
+ return cachedData;
28447
+ }
28448
+ try {
28449
+ const categories = await collection.aggregate([
28450
+ {
28451
+ $match: { school, asset_type }
28452
+ },
28453
+ {
28454
+ $group: {
28455
+ _id: "$type",
28456
+ value: { $first: "$type" },
28457
+ category: { $first: "$category" },
28458
+ title: { $first: "$name" },
28459
+ subtitle: { $first: "" }
28460
+ // keep empty for now, can be filled later
28461
+ }
28462
+ },
28463
+ {
28464
+ $project: {
28465
+ _id: 0,
28466
+ title: 1,
28467
+ value: 1,
28468
+ category: 1,
28469
+ subtitle: 1
28470
+ }
28471
+ },
28472
+ { $sort: { title: 1 } }
28473
+ ]).toArray();
28474
+ setCache(cacheKey, categories).then(() => {
28475
+ import_nodejs_utils74.logger.log({
28476
+ level: "info",
28477
+ message: `Cache set for getCategoriesBySchool: ${cacheKey}`
28478
+ });
28479
+ }).catch((err) => {
28480
+ import_nodejs_utils74.logger.log({
28481
+ level: "error",
28482
+ message: `Failed to set cache for getCategoriesBySchool: ${err.message}`
28483
+ });
28484
+ });
28485
+ return categories;
28486
+ } catch (error) {
28487
+ if (error instanceof import_nodejs_utils74.BadRequestError) {
28488
+ throw error;
28489
+ }
28490
+ throw new import_nodejs_utils74.BadRequestError("Failed to retrieve asset categories.");
28491
+ }
28492
+ }
28493
+ async function getUnitsBySchool(school) {
28494
+ try {
28495
+ school = new import_mongodb43.ObjectId(school);
28496
+ } catch (error) {
28497
+ throw new import_nodejs_utils74.BadRequestError("Invalid school ID.");
28498
+ }
28499
+ const cacheKey = (0, import_nodejs_utils74.makeCacheKey)(namespace_collection, {
28500
+ school,
28501
+ type: "unit-as-options"
28502
+ });
28503
+ const cachedData = await getCache(cacheKey);
28504
+ if (cachedData) {
28505
+ return cachedData;
28506
+ }
28507
+ try {
28508
+ const categories = await collection.aggregate([
28509
+ {
28510
+ $match: { school }
28511
+ },
28512
+ {
28513
+ $group: {
28514
+ _id: "$unit",
28515
+ value: { $first: "$unit" },
28516
+ title: {
28517
+ $first: "$unit"
28518
+ }
28519
+ }
28520
+ },
28521
+ {
28522
+ $project: {
28523
+ _id: 0,
28524
+ title: 1,
28525
+ value: 1
28526
+ }
28527
+ },
28528
+ { $sort: { title: 1 } }
28529
+ ]).toArray();
28530
+ setCache(cacheKey, categories).then(() => {
28531
+ import_nodejs_utils74.logger.log({
28532
+ level: "info",
28533
+ message: `Cache set for getUnitBy: ${cacheKey}`
28534
+ });
28535
+ }).catch((err) => {
28536
+ import_nodejs_utils74.logger.log({
28537
+ level: "error",
28538
+ message: `Failed to set cache for getUnitBy: ${err.message}`
28539
+ });
28540
+ });
28541
+ return categories;
28542
+ } catch (error) {
28543
+ console.log(error);
28544
+ if (error instanceof import_nodejs_utils74.BadRequestError) {
28545
+ throw error;
28546
+ }
28547
+ throw new import_nodejs_utils74.BadRequestError(
28548
+ "Failed to retrieve asset unit of measurements."
28549
+ );
28364
28550
  }
28365
28551
  }
28366
28552
  return {
@@ -28369,30 +28555,37 @@ function useInventoryRepo() {
28369
28555
  updateById,
28370
28556
  deleteById,
28371
28557
  getById,
28372
- getAll
28558
+ getAll,
28559
+ getCategories,
28560
+ getTypes,
28561
+ getUnitsBySchool
28373
28562
  };
28374
28563
  }
28375
28564
 
28376
- // src/controllers/inventory.controller.ts
28565
+ // src/controllers/asset.controller.ts
28377
28566
  var import_nodejs_utils75 = require("@eeplatform/nodejs-utils");
28378
28567
  var import_joi37 = __toESM(require("joi"));
28379
- function useInventoryController() {
28568
+ function useAssetController() {
28380
28569
  const {
28381
28570
  add: _add,
28382
28571
  getAll: _getAll,
28383
28572
  deleteById: _deleteById,
28384
- updateById: _updateById
28385
- } = useInventoryRepo();
28573
+ updateById: _updateById,
28574
+ getById: _getById,
28575
+ getCategories: _getCategories,
28576
+ getTypes: _getTypes,
28577
+ getUnitsBySchool: _getUnitsBySchool
28578
+ } = useAssetRepo();
28386
28579
  async function add(req, res, next) {
28387
28580
  const value = req.body;
28388
- const { error } = schemaInventory.validate(value);
28581
+ const { error } = schemaAsset.validate(value);
28389
28582
  if (error) {
28390
28583
  next(new import_nodejs_utils75.BadRequestError(error.message));
28391
28584
  return;
28392
28585
  }
28393
28586
  try {
28394
28587
  const id = await _add(value);
28395
- res.json({ message: "Successfully added inventory item.", id });
28588
+ res.json({ message: "Successfully added asset item.", id });
28396
28589
  } catch (error2) {
28397
28590
  next(error2);
28398
28591
  }
@@ -28404,7 +28597,8 @@ function useInventoryController() {
28404
28597
  limit: import_joi37.default.number().min(1).optional().allow("", null),
28405
28598
  search: import_joi37.default.string().optional().allow("", null),
28406
28599
  status: import_joi37.default.string().optional().allow("", null),
28407
- school: import_joi37.default.string().hex().optional().allow("", null)
28600
+ school: import_joi37.default.string().hex().optional().allow("", null),
28601
+ asset_type: import_joi37.default.string().required().allow("supply", "furniture-equipment", "fixed-asset")
28408
28602
  });
28409
28603
  const { error } = validation.validate(query);
28410
28604
  const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
@@ -28412,6 +28606,7 @@ function useInventoryController() {
28412
28606
  const search = req.query.search ?? "";
28413
28607
  const status = req.query.status ?? "active";
28414
28608
  const school = req.query.school ?? "";
28609
+ const asset_type = req.query.asset_type ?? "supply";
28415
28610
  const isPageNumber = isFinite(page);
28416
28611
  if (!isPageNumber) {
28417
28612
  next(new import_nodejs_utils75.BadRequestError("Invalid page number."));
@@ -28427,7 +28622,14 @@ function useInventoryController() {
28427
28622
  return;
28428
28623
  }
28429
28624
  try {
28430
- const regions = await _getAll({ page, limit, search, status, school });
28625
+ const regions = await _getAll({
28626
+ page,
28627
+ limit,
28628
+ search,
28629
+ status,
28630
+ school,
28631
+ asset_type
28632
+ });
28431
28633
  res.json(regions);
28432
28634
  return;
28433
28635
  } catch (error2) {
@@ -28444,7 +28646,22 @@ function useInventoryController() {
28444
28646
  }
28445
28647
  try {
28446
28648
  await _deleteById(id);
28447
- res.json({ message: "Successfully deleted inventory item.", id });
28649
+ res.json({ message: "Successfully deleted asset item.", id });
28650
+ } catch (error2) {
28651
+ next(error2);
28652
+ }
28653
+ }
28654
+ async function getById(req, res, next) {
28655
+ const id = req.params.id;
28656
+ const validation = import_joi37.default.string().hex().required();
28657
+ const { error } = validation.validate(id);
28658
+ if (error) {
28659
+ next(new import_nodejs_utils75.BadRequestError(error.message));
28660
+ return;
28661
+ }
28662
+ try {
28663
+ const data = await _getById(id);
28664
+ res.json(data);
28448
28665
  } catch (error2) {
28449
28666
  next(error2);
28450
28667
  }
@@ -28452,14 +28669,61 @@ function useInventoryController() {
28452
28669
  async function updateById(req, res, next) {
28453
28670
  const id = req.params.id;
28454
28671
  const value = req.body;
28455
- const { error } = schemaInventoryUpdateOption.validate(value);
28672
+ const { error } = schemaAssetUpdateOption.validate(value);
28456
28673
  if (error) {
28457
28674
  next(new import_nodejs_utils75.BadRequestError(error.message));
28458
28675
  return;
28459
28676
  }
28460
28677
  try {
28461
28678
  await _updateById(id, value);
28462
- res.json({ message: "Successfully updated inventory item.", id });
28679
+ res.json({ message: "Successfully updated asset item.", id });
28680
+ } catch (error2) {
28681
+ next(error2);
28682
+ }
28683
+ }
28684
+ async function getCategories(req, res, next) {
28685
+ const school = req.params.school;
28686
+ const asset_type = req.params.asset_type;
28687
+ const validation = import_joi37.default.string().hex().required();
28688
+ const { error } = validation.validate(school);
28689
+ if (error) {
28690
+ next(new import_nodejs_utils75.BadRequestError(error.message));
28691
+ return;
28692
+ }
28693
+ try {
28694
+ const data = await _getCategories(school, asset_type);
28695
+ res.json(data);
28696
+ } catch (error2) {
28697
+ next(error2);
28698
+ }
28699
+ }
28700
+ async function getTypes(req, res, next) {
28701
+ const school = req.params.school;
28702
+ const asset_type = req.params.asset_type;
28703
+ const validation = import_joi37.default.string().hex().required();
28704
+ const { error } = validation.validate(school);
28705
+ if (error) {
28706
+ next(new import_nodejs_utils75.BadRequestError(error.message));
28707
+ return;
28708
+ }
28709
+ try {
28710
+ const data = await _getTypes(school, asset_type);
28711
+ res.json(data);
28712
+ } catch (error2) {
28713
+ next(error2);
28714
+ }
28715
+ }
28716
+ async function getUnitsBySchool(req, res, next) {
28717
+ const school = req.params.school;
28718
+ const validation = import_joi37.default.string().hex().required();
28719
+ const { error } = validation.validate(school);
28720
+ if (error) {
28721
+ next(new import_nodejs_utils75.BadRequestError(error.message));
28722
+ return;
28723
+ }
28724
+ try {
28725
+ const data = await _getUnitsBySchool(school);
28726
+ res.json(data);
28463
28727
  } catch (error2) {
28464
28728
  next(error2);
28465
28729
  }
@@ -28468,7 +28732,422 @@ function useInventoryController() {
28468
28732
  add,
28469
28733
  getAll,
28470
28734
  deleteById,
28471
- updateById
28735
+ updateById,
28736
+ getById,
28737
+ getCategories,
28738
+ getTypes,
28739
+ getUnitsBySchool
28740
+ };
28741
+ }
28742
+
28743
+ // src/models/stock-card.model.ts
28744
+ var import_nodejs_utils76 = require("@eeplatform/nodejs-utils");
28745
+ var import_joi38 = __toESM(require("joi"));
28746
+ var import_mongodb44 = require("mongodb");
28747
+ var schemaStockCard = import_joi38.default.object({
28748
+ _id: import_joi38.default.string().hex().optional().allow("", null),
28749
+ school: import_joi38.default.string().hex().required(),
28750
+ item: import_joi38.default.string().hex().required(),
28751
+ balance: import_joi38.default.number().optional().allow(null, 0),
28752
+ qty: import_joi38.default.number().required(),
28753
+ unitCost: import_joi38.default.number().optional().allow(null, 0),
28754
+ totalCost: import_joi38.default.number().optional().allow(null, 0),
28755
+ status: import_joi38.default.string().required(),
28756
+ condition: import_joi38.default.string().required(),
28757
+ supplier: import_joi38.default.string().optional().allow("", null),
28758
+ location: import_joi38.default.string().optional().allow("", null),
28759
+ locationName: import_joi38.default.string().optional().allow("", null),
28760
+ reason: import_joi38.default.string().optional().allow("", null),
28761
+ remarks: import_joi38.default.string().optional().allow("", null),
28762
+ createdAt: import_joi38.default.date().optional().allow("", null),
28763
+ updatedAt: import_joi38.default.date().optional().allow("", null),
28764
+ deletedAt: import_joi38.default.date().optional().allow("", null)
28765
+ });
28766
+ function MStockCard(value) {
28767
+ const { error } = schemaStockCard.validate(value);
28768
+ if (error) {
28769
+ throw new import_nodejs_utils76.BadRequestError(`Invalid stock card data: ${error.message}`);
28770
+ }
28771
+ if (value._id && typeof value._id === "string") {
28772
+ try {
28773
+ value._id = new import_mongodb44.ObjectId(value._id);
28774
+ } catch (err) {
28775
+ throw new import_nodejs_utils76.BadRequestError("Invalid stock card ID.");
28776
+ }
28777
+ }
28778
+ try {
28779
+ value.item = new import_mongodb44.ObjectId(value.item);
28780
+ } catch (err) {
28781
+ throw new import_nodejs_utils76.BadRequestError("Invalid item ID.");
28782
+ }
28783
+ try {
28784
+ value.school = new import_mongodb44.ObjectId(value.school);
28785
+ } catch (err) {
28786
+ throw new import_nodejs_utils76.BadRequestError("Invalid school ID.");
28787
+ }
28788
+ return {
28789
+ _id: value._id ?? void 0,
28790
+ school: value.school,
28791
+ item: value.item,
28792
+ balance: value.balance,
28793
+ qty: value.qty,
28794
+ unitCost: value.unitCost,
28795
+ totalCost: value.totalCost,
28796
+ status: value.status,
28797
+ condition: value.condition,
28798
+ supplier: value.supplier ?? "",
28799
+ location: value.location ?? void 0,
28800
+ locationName: value.locationName ?? "",
28801
+ reason: value.reason ?? "",
28802
+ remarks: value.remarks ?? "",
28803
+ createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
28804
+ updatedAt: value.updatedAt ?? "",
28805
+ deletedAt: value.deletedAt ?? ""
28806
+ };
28807
+ }
28808
+
28809
+ // src/repositories/stock-card.repository.ts
28810
+ var import_nodejs_utils77 = require("@eeplatform/nodejs-utils");
28811
+ var import_mongodb45 = require("mongodb");
28812
+ function useStockCardRepository() {
28813
+ const db = import_nodejs_utils77.useAtlas.getDb();
28814
+ if (!db) {
28815
+ throw new import_nodejs_utils77.BadRequestError("Unable to connect to server.");
28816
+ }
28817
+ const namespace_collection = "school.assets.stock-cards";
28818
+ const collection = db.collection(namespace_collection);
28819
+ const { getCache, setCache, delNamespace } = (0, import_nodejs_utils77.useCache)(namespace_collection);
28820
+ function delCachedData() {
28821
+ delNamespace().then(() => {
28822
+ import_nodejs_utils77.logger.log({
28823
+ level: "info",
28824
+ message: `Cache namespace cleared for ${namespace_collection}`
28825
+ });
28826
+ }).catch((err) => {
28827
+ import_nodejs_utils77.logger.log({
28828
+ level: "error",
28829
+ message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
28830
+ });
28831
+ });
28832
+ }
28833
+ async function createIndex() {
28834
+ try {
28835
+ await collection.createIndexes([
28836
+ { key: { school: 1 } },
28837
+ { key: { item: 1 } }
28838
+ ]);
28839
+ } catch (error) {
28840
+ throw new import_nodejs_utils77.BadRequestError("Failed to create index on stock card.");
28841
+ }
28842
+ }
28843
+ async function add(value, session) {
28844
+ try {
28845
+ value = MStockCard(value);
28846
+ const res = await collection.insertOne(value, { session });
28847
+ delCachedData();
28848
+ return res.insertedId;
28849
+ } catch (error) {
28850
+ throw new import_nodejs_utils77.BadRequestError("Failed to create stock card.");
28851
+ }
28852
+ }
28853
+ async function getById(_id) {
28854
+ try {
28855
+ _id = new import_mongodb45.ObjectId(_id);
28856
+ } catch (error) {
28857
+ throw new import_nodejs_utils77.BadRequestError("Invalid ID.");
28858
+ }
28859
+ const cacheKey = (0, import_nodejs_utils77.makeCacheKey)(namespace_collection, { _id: String(_id) });
28860
+ const cachedData = await getCache(cacheKey);
28861
+ if (cachedData) {
28862
+ return cachedData;
28863
+ }
28864
+ try {
28865
+ const res = await collection.findOne({ _id });
28866
+ if (!res) {
28867
+ throw new import_nodejs_utils77.BadRequestError("Asset item not found.");
28868
+ }
28869
+ setCache(cacheKey, res).then(() => {
28870
+ import_nodejs_utils77.logger.log({
28871
+ level: "info",
28872
+ message: `Cache set for stock card by ID: ${cacheKey}`
28873
+ });
28874
+ }).catch((err) => {
28875
+ import_nodejs_utils77.logger.log({
28876
+ level: "error",
28877
+ message: `Failed to set cache for stock card by ID: ${cacheKey} - ${err.message}`
28878
+ });
28879
+ });
28880
+ return res;
28881
+ } catch (error) {
28882
+ if (error instanceof import_nodejs_utils77.BadRequestError) {
28883
+ throw error;
28884
+ }
28885
+ throw new import_nodejs_utils77.BadRequestError("Failed to retrieve stock card.");
28886
+ }
28887
+ }
28888
+ async function getAll({ page = 1, limit = 20, school = "", sort = { _id: 1 }, id = "" } = {}) {
28889
+ page = page ? page - 1 : 0;
28890
+ try {
28891
+ school = new import_mongodb45.ObjectId(school);
28892
+ } catch (error) {
28893
+ throw new import_nodejs_utils77.BadRequestError("Invalid school ID.");
28894
+ }
28895
+ try {
28896
+ id = new import_mongodb45.ObjectId(id);
28897
+ } catch (error) {
28898
+ throw new import_nodejs_utils77.BadRequestError("Invalid ID.");
28899
+ }
28900
+ const query = {
28901
+ school,
28902
+ item: id
28903
+ };
28904
+ const cacheKeyOptions = {
28905
+ page,
28906
+ limit,
28907
+ school: String(school),
28908
+ sort: JSON.stringify(sort),
28909
+ item: id
28910
+ };
28911
+ try {
28912
+ const cacheKey = (0, import_nodejs_utils77.makeCacheKey)(namespace_collection, cacheKeyOptions);
28913
+ const cached = await getCache(cacheKey);
28914
+ if (cached) {
28915
+ import_nodejs_utils77.logger.log({
28916
+ level: "info",
28917
+ message: `Cache hit for getAll stock cards: ${cacheKey}`
28918
+ });
28919
+ return cached;
28920
+ }
28921
+ const items = await collection.aggregate([
28922
+ { $match: query },
28923
+ {
28924
+ $sort: sort
28925
+ },
28926
+ {
28927
+ $skip: page * limit
28928
+ },
28929
+ {
28930
+ $limit: limit
28931
+ }
28932
+ ]).toArray();
28933
+ const length = await collection.countDocuments(query);
28934
+ const data = (0, import_nodejs_utils77.paginate)(items, page, limit, length);
28935
+ setCache(cacheKey, data, 500).then(() => {
28936
+ import_nodejs_utils77.logger.log({
28937
+ level: "info",
28938
+ message: `Cache set for getAll stock cards: ${cacheKey}`
28939
+ });
28940
+ }).catch((err) => {
28941
+ import_nodejs_utils77.logger.log({
28942
+ level: "error",
28943
+ message: `Failed to set cache for getAll stock cards: ${err.message}`
28944
+ });
28945
+ });
28946
+ return data;
28947
+ } catch (error) {
28948
+ console.log("Error in getAll:", error);
28949
+ throw new import_nodejs_utils77.BadRequestError("Failed to retrieve stock cards.");
28950
+ }
28951
+ }
28952
+ async function getSuppliers(school) {
28953
+ try {
28954
+ school = new import_mongodb45.ObjectId(school);
28955
+ } catch (error) {
28956
+ throw new import_nodejs_utils77.BadRequestError("Invalid school ID.");
28957
+ }
28958
+ const cacheKey = (0, import_nodejs_utils77.makeCacheKey)(namespace_collection, {
28959
+ school,
28960
+ type: "supplier-as-options"
28961
+ });
28962
+ const cachedData = await getCache(cacheKey);
28963
+ if (cachedData) {
28964
+ return cachedData;
28965
+ }
28966
+ try {
28967
+ const suppliers = await collection.aggregate([
28968
+ {
28969
+ $match: { school }
28970
+ },
28971
+ {
28972
+ $group: {
28973
+ _id: "$supplier",
28974
+ value: { $first: "$supplier" },
28975
+ title: {
28976
+ $first: "$supplier"
28977
+ }
28978
+ }
28979
+ },
28980
+ {
28981
+ $project: {
28982
+ _id: 0,
28983
+ title: 1,
28984
+ value: 1
28985
+ }
28986
+ },
28987
+ { $sort: { title: 1 } }
28988
+ ]).toArray();
28989
+ setCache(cacheKey, suppliers).then(() => {
28990
+ import_nodejs_utils77.logger.log({
28991
+ level: "info",
28992
+ message: `Cache set for getSuppliersBySchool: ${cacheKey}`
28993
+ });
28994
+ }).catch((err) => {
28995
+ import_nodejs_utils77.logger.log({
28996
+ level: "error",
28997
+ message: `Failed to set cache for getSuppliersBySchool: ${err.message}`
28998
+ });
28999
+ });
29000
+ return suppliers;
29001
+ } catch (error) {
29002
+ if (error instanceof import_nodejs_utils77.BadRequestError) {
29003
+ throw error;
29004
+ }
29005
+ throw new import_nodejs_utils77.BadRequestError("Failed to retrieve asset suppliers.");
29006
+ }
29007
+ }
29008
+ return {
29009
+ createIndex,
29010
+ add,
29011
+ getById,
29012
+ getAll,
29013
+ getSuppliers
29014
+ };
29015
+ }
29016
+
29017
+ // src/controllers/stock-card.controller.ts
29018
+ var import_nodejs_utils79 = require("@eeplatform/nodejs-utils");
29019
+ var import_joi39 = __toESM(require("joi"));
29020
+
29021
+ // src/services/stock-card.service.ts
29022
+ var import_nodejs_utils78 = require("@eeplatform/nodejs-utils");
29023
+ function useStockCardService() {
29024
+ const { add: _add, getById: _getById } = useStockCardRepository();
29025
+ const { getById: _getAssetById, updateById: updateAssetById } = useAssetRepo();
29026
+ async function add(data) {
29027
+ const session = import_nodejs_utils78.useAtlas.getClient()?.startSession();
29028
+ if (!session) {
29029
+ throw new import_nodejs_utils78.BadRequestError("Unable to start database session.");
29030
+ }
29031
+ session.startTransaction();
29032
+ try {
29033
+ const asset = await _getAssetById(data.item);
29034
+ if (!asset) {
29035
+ throw new import_nodejs_utils78.NotFoundError("Asset not found.");
29036
+ }
29037
+ data.balance = (asset.qty ?? 0) + data.qty;
29038
+ await _add(data, session);
29039
+ await updateAssetById(data.item, { qty: data.balance }, session);
29040
+ await session.commitTransaction();
29041
+ return "Successfully added stock card.";
29042
+ } catch (error) {
29043
+ await session.abortTransaction();
29044
+ throw new import_nodejs_utils78.BadRequestError("Failed to add stock card.");
29045
+ } finally {
29046
+ session.endSession();
29047
+ }
29048
+ }
29049
+ return {
29050
+ add
29051
+ };
29052
+ }
29053
+
29054
+ // src/controllers/stock-card.controller.ts
29055
+ function useStockCardController() {
29056
+ const {
29057
+ getAll: _getAll,
29058
+ getById: _getById,
29059
+ getSuppliers: _getSuppliers
29060
+ } = useStockCardRepository();
29061
+ const { add: _add } = useStockCardService();
29062
+ async function add(req, res, next) {
29063
+ const value = req.body;
29064
+ const { error } = schemaStockCard.validate(value);
29065
+ if (error) {
29066
+ next(new import_nodejs_utils79.BadRequestError(error.message));
29067
+ return;
29068
+ }
29069
+ try {
29070
+ const id = await _add(value);
29071
+ res.json({ message: "Successfully added asset item.", id });
29072
+ } catch (error2) {
29073
+ next(error2);
29074
+ }
29075
+ }
29076
+ async function getAll(req, res, next) {
29077
+ const query = req.query;
29078
+ const validation = import_joi39.default.object({
29079
+ page: import_joi39.default.number().min(1).optional().allow("", null),
29080
+ limit: import_joi39.default.number().min(1).optional().allow("", null),
29081
+ school: import_joi39.default.string().hex().optional().allow("", null),
29082
+ id: import_joi39.default.string().hex().required()
29083
+ });
29084
+ const { error } = validation.validate(query);
29085
+ const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
29086
+ const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
29087
+ const school = req.query.school ?? "";
29088
+ const id = req.query.id ?? "supply";
29089
+ const isPageNumber = isFinite(page);
29090
+ if (!isPageNumber) {
29091
+ next(new import_nodejs_utils79.BadRequestError("Invalid page number."));
29092
+ return;
29093
+ }
29094
+ const isLimitNumber = isFinite(limit);
29095
+ if (!isLimitNumber) {
29096
+ next(new import_nodejs_utils79.BadRequestError("Invalid limit number."));
29097
+ return;
29098
+ }
29099
+ if (error) {
29100
+ next(new import_nodejs_utils79.BadRequestError(error.message));
29101
+ return;
29102
+ }
29103
+ try {
29104
+ const regions = await _getAll({
29105
+ page,
29106
+ limit,
29107
+ id,
29108
+ school
29109
+ });
29110
+ res.json(regions);
29111
+ return;
29112
+ } catch (error2) {
29113
+ next(error2);
29114
+ }
29115
+ }
29116
+ async function getById(req, res, next) {
29117
+ const id = req.params.id;
29118
+ const validation = import_joi39.default.string().hex().required();
29119
+ const { error } = validation.validate(id);
29120
+ if (error) {
29121
+ next(new import_nodejs_utils79.BadRequestError(error.message));
29122
+ return;
29123
+ }
29124
+ try {
29125
+ const data = await _getById(id);
29126
+ res.json(data);
29127
+ } catch (error2) {
29128
+ next(error2);
29129
+ }
29130
+ }
29131
+ async function getSuppliers(req, res, next) {
29132
+ const school = req.params.school;
29133
+ const validation = import_joi39.default.string().hex().required();
29134
+ const { error } = validation.validate(school);
29135
+ if (error) {
29136
+ next(new import_nodejs_utils79.BadRequestError(error.message));
29137
+ return;
29138
+ }
29139
+ try {
29140
+ const data = await _getSuppliers(school);
29141
+ res.json(data);
29142
+ } catch (error2) {
29143
+ next(error2);
29144
+ }
29145
+ }
29146
+ return {
29147
+ add,
29148
+ getAll,
29149
+ getById,
29150
+ getSuppliers
28472
29151
  };
28473
29152
  }
28474
29153
  // Annotate the CommonJS export names for ESM import in node:
@@ -28490,12 +29169,12 @@ function useInventoryController() {
28490
29169
  MAILER_TRANSPORT_PORT,
28491
29170
  MAILER_TRANSPORT_SECURE,
28492
29171
  MAddress,
29172
+ MAsset,
28493
29173
  MBuilding,
28494
29174
  MBuildingUnit,
28495
29175
  MDivision,
28496
29176
  MEntity,
28497
29177
  MFile,
28498
- MInventory,
28499
29178
  MMember,
28500
29179
  MONGO_DB,
28501
29180
  MONGO_URI,
@@ -28506,6 +29185,7 @@ function useInventoryController() {
28506
29185
  MRegion,
28507
29186
  MRole,
28508
29187
  MSchool,
29188
+ MStockCard,
28509
29189
  MSubscription,
28510
29190
  MToken,
28511
29191
  MUser,
@@ -28533,16 +29213,19 @@ function useInventoryController() {
28533
29213
  addressSchema,
28534
29214
  isDev,
28535
29215
  schema,
29216
+ schemaAsset,
29217
+ schemaAssetUpdateOption,
28536
29218
  schemaBuilding,
28537
29219
  schemaBuildingUnit,
28538
29220
  schemaDivision,
28539
- schemaInventory,
28540
- schemaInventoryUpdateOption,
28541
29221
  schemaRegion,
28542
29222
  schemaSchool,
29223
+ schemaStockCard,
28543
29224
  schemaUpdateOptions,
28544
29225
  useAddressController,
28545
29226
  useAddressRepo,
29227
+ useAssetController,
29228
+ useAssetRepo,
28546
29229
  useAuthController,
28547
29230
  useAuthService,
28548
29231
  useBuildingController,
@@ -28559,8 +29242,6 @@ function useInventoryController() {
28559
29242
  useFileController,
28560
29243
  useFileRepo,
28561
29244
  useFileService,
28562
- useInventoryController,
28563
- useInventoryRepo,
28564
29245
  useInvoiceController,
28565
29246
  useInvoiceModel,
28566
29247
  useInvoiceRepo,
@@ -28592,6 +29273,8 @@ function useInventoryController() {
28592
29273
  useSchoolController,
28593
29274
  useSchoolRepo,
28594
29275
  useSchoolService,
29276
+ useStockCardController,
29277
+ useStockCardRepository,
28595
29278
  useSubscriptionController,
28596
29279
  useSubscriptionRepo,
28597
29280
  useSubscriptionService,