@eeplatform/core 1.2.1 → 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/CHANGELOG.md +12 -0
- package/dist/index.d.ts +111 -1
- package/dist/index.js +1124 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1141 -7
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -11342,6 +11342,7 @@ __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,
|
|
@@ -11357,6 +11358,7 @@ __export(src_exports, {
|
|
|
11357
11358
|
MRegion: () => MRegion,
|
|
11358
11359
|
MRole: () => MRole,
|
|
11359
11360
|
MSchool: () => MSchool,
|
|
11361
|
+
MStockCard: () => MStockCard,
|
|
11360
11362
|
MSubscription: () => MSubscription,
|
|
11361
11363
|
MToken: () => MToken,
|
|
11362
11364
|
MUser: () => MUser,
|
|
@@ -11384,14 +11386,19 @@ __export(src_exports, {
|
|
|
11384
11386
|
addressSchema: () => addressSchema,
|
|
11385
11387
|
isDev: () => isDev,
|
|
11386
11388
|
schema: () => schema,
|
|
11389
|
+
schemaAsset: () => schemaAsset,
|
|
11390
|
+
schemaAssetUpdateOption: () => schemaAssetUpdateOption,
|
|
11387
11391
|
schemaBuilding: () => schemaBuilding,
|
|
11388
11392
|
schemaBuildingUnit: () => schemaBuildingUnit,
|
|
11389
11393
|
schemaDivision: () => schemaDivision,
|
|
11390
11394
|
schemaRegion: () => schemaRegion,
|
|
11391
11395
|
schemaSchool: () => schemaSchool,
|
|
11396
|
+
schemaStockCard: () => schemaStockCard,
|
|
11392
11397
|
schemaUpdateOptions: () => schemaUpdateOptions,
|
|
11393
11398
|
useAddressController: () => useAddressController,
|
|
11394
11399
|
useAddressRepo: () => useAddressRepo,
|
|
11400
|
+
useAssetController: () => useAssetController,
|
|
11401
|
+
useAssetRepo: () => useAssetRepo,
|
|
11395
11402
|
useAuthController: () => useAuthController,
|
|
11396
11403
|
useAuthService: () => useAuthService,
|
|
11397
11404
|
useBuildingController: () => useBuildingController,
|
|
@@ -11439,6 +11446,8 @@ __export(src_exports, {
|
|
|
11439
11446
|
useSchoolController: () => useSchoolController,
|
|
11440
11447
|
useSchoolRepo: () => useSchoolRepo,
|
|
11441
11448
|
useSchoolService: () => useSchoolService,
|
|
11449
|
+
useStockCardController: () => useStockCardController,
|
|
11450
|
+
useStockCardRepository: () => useStockCardRepository,
|
|
11442
11451
|
useSubscriptionController: () => useSubscriptionController,
|
|
11443
11452
|
useSubscriptionRepo: () => useSubscriptionRepo,
|
|
11444
11453
|
useSubscriptionService: () => useSubscriptionService,
|
|
@@ -26991,6 +27000,7 @@ var schemaBuildingUnit = import_joi33.default.object({
|
|
|
26991
27000
|
var schemaUpdateOptions = import_joi33.default.object({
|
|
26992
27001
|
name: import_joi33.default.string().optional().allow("", null),
|
|
26993
27002
|
building: import_joi33.default.string().hex().optional().allow("", null),
|
|
27003
|
+
buildingName: import_joi33.default.string().optional().allow("", null),
|
|
26994
27004
|
level: import_joi33.default.number().integer().min(1).optional().allow("", null),
|
|
26995
27005
|
category: import_joi33.default.string().optional().allow("", null),
|
|
26996
27006
|
type: import_joi33.default.string().optional().allow("", null),
|
|
@@ -27399,6 +27409,36 @@ function useBuildingUnitRepo() {
|
|
|
27399
27409
|
}
|
|
27400
27410
|
}
|
|
27401
27411
|
}
|
|
27412
|
+
async function updateByBuildingId(building, value, session) {
|
|
27413
|
+
const { error } = schemaUpdateOptions.validate(value);
|
|
27414
|
+
if (error) {
|
|
27415
|
+
throw new import_nodejs_utils68.BadRequestError(error.message);
|
|
27416
|
+
}
|
|
27417
|
+
try {
|
|
27418
|
+
building = new import_mongodb41.ObjectId(building);
|
|
27419
|
+
} catch (error2) {
|
|
27420
|
+
throw new import_nodejs_utils68.BadRequestError("Invalid building ID.");
|
|
27421
|
+
}
|
|
27422
|
+
try {
|
|
27423
|
+
const res = await collection.updateMany(
|
|
27424
|
+
{ building },
|
|
27425
|
+
{ $set: value },
|
|
27426
|
+
{ session }
|
|
27427
|
+
);
|
|
27428
|
+
delCachedData();
|
|
27429
|
+
return res;
|
|
27430
|
+
} catch (error2) {
|
|
27431
|
+
import_nodejs_utils68.logger.log({
|
|
27432
|
+
level: "error",
|
|
27433
|
+
message: error2.message
|
|
27434
|
+
});
|
|
27435
|
+
if (error2 instanceof import_nodejs_utils68.AppError) {
|
|
27436
|
+
throw error2;
|
|
27437
|
+
} else {
|
|
27438
|
+
throw new Error("Failed to update building unit.");
|
|
27439
|
+
}
|
|
27440
|
+
}
|
|
27441
|
+
}
|
|
27402
27442
|
async function getAll({
|
|
27403
27443
|
search = "",
|
|
27404
27444
|
page = 1,
|
|
@@ -27646,7 +27686,8 @@ function useBuildingUnitRepo() {
|
|
|
27646
27686
|
getByBuildingLevel,
|
|
27647
27687
|
updateById,
|
|
27648
27688
|
getByBuilding,
|
|
27649
|
-
deleteById
|
|
27689
|
+
deleteById,
|
|
27690
|
+
updateByBuildingId
|
|
27650
27691
|
};
|
|
27651
27692
|
}
|
|
27652
27693
|
|
|
@@ -27662,9 +27703,10 @@ function useBuildingService() {
|
|
|
27662
27703
|
getById: _getById,
|
|
27663
27704
|
deleteById: _deleteById
|
|
27664
27705
|
} = useBuildingRepo();
|
|
27665
|
-
const { getByBuildingLevel, getByBuilding } = useBuildingUnitRepo();
|
|
27706
|
+
const { getByBuildingLevel, getByBuilding, updateByBuildingId } = useBuildingUnitRepo();
|
|
27666
27707
|
async function updateById(id, data) {
|
|
27667
27708
|
data.levels = Number(data.levels);
|
|
27709
|
+
const session = import_nodejs_utils69.useAtlas.getClient()?.startSession();
|
|
27668
27710
|
try {
|
|
27669
27711
|
const building = await _getById(id);
|
|
27670
27712
|
if (!building) {
|
|
@@ -27678,10 +27720,18 @@ function useBuildingService() {
|
|
|
27678
27720
|
);
|
|
27679
27721
|
}
|
|
27680
27722
|
}
|
|
27681
|
-
|
|
27723
|
+
session?.startTransaction();
|
|
27724
|
+
if (building.name !== data.name) {
|
|
27725
|
+
await updateByBuildingId(id, { buildingName: data.name }, session);
|
|
27726
|
+
}
|
|
27727
|
+
const result = await _updateById(id, data, session);
|
|
27728
|
+
await session?.commitTransaction();
|
|
27682
27729
|
return result;
|
|
27683
27730
|
} catch (error) {
|
|
27731
|
+
await session?.abortTransaction();
|
|
27684
27732
|
throw error;
|
|
27733
|
+
} finally {
|
|
27734
|
+
session?.endSession();
|
|
27685
27735
|
}
|
|
27686
27736
|
}
|
|
27687
27737
|
async function deleteById(id) {
|
|
@@ -28038,6 +28088,1068 @@ function useBuildingUnitController() {
|
|
|
28038
28088
|
deleteById
|
|
28039
28089
|
};
|
|
28040
28090
|
}
|
|
28091
|
+
|
|
28092
|
+
// src/models/asset.model.ts
|
|
28093
|
+
var import_nodejs_utils73 = require("@eeplatform/nodejs-utils");
|
|
28094
|
+
var import_joi36 = __toESM(require("joi"));
|
|
28095
|
+
var import_mongodb42 = require("mongodb");
|
|
28096
|
+
var schemaAsset = import_joi36.default.object({
|
|
28097
|
+
_id: import_joi36.default.string().hex().optional(),
|
|
28098
|
+
school: import_joi36.default.string().hex().required(),
|
|
28099
|
+
asset_type: import_joi36.default.string().required().allow("supply", "furniture-equipment", "fixed-asset"),
|
|
28100
|
+
name: import_joi36.default.string().required(),
|
|
28101
|
+
category: import_joi36.default.string().optional().allow("", null),
|
|
28102
|
+
type: import_joi36.default.string().optional().allow("", null),
|
|
28103
|
+
brand: import_joi36.default.string().optional().allow("", null),
|
|
28104
|
+
unit: import_joi36.default.string().required(),
|
|
28105
|
+
status: import_joi36.default.string().optional().allow("", null),
|
|
28106
|
+
createdAt: import_joi36.default.date().optional().allow("", null),
|
|
28107
|
+
updatedAt: import_joi36.default.date().optional().allow("", null),
|
|
28108
|
+
deletedAt: import_joi36.default.date().optional().allow("", null),
|
|
28109
|
+
metadata: import_joi36.default.object({
|
|
28110
|
+
title: import_joi36.default.string().optional().allow("", null),
|
|
28111
|
+
isbn: import_joi36.default.string().optional().allow("", null),
|
|
28112
|
+
author: import_joi36.default.string().optional().allow("", null),
|
|
28113
|
+
edition: import_joi36.default.string().optional().allow("", null),
|
|
28114
|
+
subject: import_joi36.default.string().optional().allow("", null),
|
|
28115
|
+
grade_level: import_joi36.default.number().integer().min(0).optional().allow("", null),
|
|
28116
|
+
publisher: import_joi36.default.string().optional().allow("", null),
|
|
28117
|
+
language: import_joi36.default.string().optional().allow("", null)
|
|
28118
|
+
}).optional().allow(null)
|
|
28119
|
+
});
|
|
28120
|
+
var schemaAssetUpdateOption = import_joi36.default.object({
|
|
28121
|
+
name: import_joi36.default.string().optional().allow("", null),
|
|
28122
|
+
category: import_joi36.default.string().optional().allow("", null),
|
|
28123
|
+
type: import_joi36.default.string().optional().allow("", null),
|
|
28124
|
+
brand: import_joi36.default.string().optional().allow("", null),
|
|
28125
|
+
qty: import_joi36.default.number().integer().min(0).optional().allow("", null),
|
|
28126
|
+
unit: import_joi36.default.string().optional().allow("", null),
|
|
28127
|
+
metadata: import_joi36.default.object({
|
|
28128
|
+
title: import_joi36.default.string().optional().allow("", null),
|
|
28129
|
+
isbn: import_joi36.default.string().optional().allow("", null),
|
|
28130
|
+
author: import_joi36.default.string().optional().allow("", null),
|
|
28131
|
+
edition: import_joi36.default.string().optional().allow("", null),
|
|
28132
|
+
subject: import_joi36.default.string().optional().allow("", null),
|
|
28133
|
+
grade_level: import_joi36.default.number().integer().min(0).optional().allow("", null),
|
|
28134
|
+
publisher: import_joi36.default.string().optional().allow("", null),
|
|
28135
|
+
language: import_joi36.default.string().optional().allow("", null)
|
|
28136
|
+
}).optional().allow(null)
|
|
28137
|
+
});
|
|
28138
|
+
function MAsset(value) {
|
|
28139
|
+
const { error } = schemaAsset.validate(value);
|
|
28140
|
+
if (error) {
|
|
28141
|
+
throw new import_nodejs_utils73.BadRequestError(error.message);
|
|
28142
|
+
}
|
|
28143
|
+
if (value._id && typeof value._id === "string") {
|
|
28144
|
+
try {
|
|
28145
|
+
value._id = new import_mongodb42.ObjectId();
|
|
28146
|
+
} catch (error2) {
|
|
28147
|
+
throw new import_nodejs_utils73.BadRequestError("Invalid ID.");
|
|
28148
|
+
}
|
|
28149
|
+
}
|
|
28150
|
+
try {
|
|
28151
|
+
value.school = new import_mongodb42.ObjectId(value.school);
|
|
28152
|
+
} catch (error2) {
|
|
28153
|
+
throw new import_nodejs_utils73.BadRequestError("Invalid school ID.");
|
|
28154
|
+
}
|
|
28155
|
+
value.createdAt = value.createdAt ? new Date(value.createdAt) : /* @__PURE__ */ new Date();
|
|
28156
|
+
value.updatedAt = value.updatedAt ? new Date(value.updatedAt) : "";
|
|
28157
|
+
value.deletedAt = value.deletedAt ? new Date(value.deletedAt) : "";
|
|
28158
|
+
return {
|
|
28159
|
+
_id: value._id ?? new import_mongodb42.ObjectId(),
|
|
28160
|
+
school: value.school,
|
|
28161
|
+
asset_type: value.asset_type ?? "supply",
|
|
28162
|
+
name: value.name,
|
|
28163
|
+
category: value.category ?? "",
|
|
28164
|
+
type: value.type ?? "",
|
|
28165
|
+
brand: value.brand ?? "",
|
|
28166
|
+
qty: value.qty ?? 0,
|
|
28167
|
+
condition: value.condition ?? {
|
|
28168
|
+
good: 0,
|
|
28169
|
+
disposal: 0,
|
|
28170
|
+
lost: 0,
|
|
28171
|
+
damaged: 0
|
|
28172
|
+
},
|
|
28173
|
+
unit: value.unit ?? "",
|
|
28174
|
+
status: value.status ?? "active",
|
|
28175
|
+
createdAt: value.createdAt,
|
|
28176
|
+
updatedAt: value.updatedAt,
|
|
28177
|
+
deletedAt: value.deletedAt,
|
|
28178
|
+
metadata: value.metadata ?? {}
|
|
28179
|
+
};
|
|
28180
|
+
}
|
|
28181
|
+
|
|
28182
|
+
// src/repositories/asset.repository.ts
|
|
28183
|
+
var import_nodejs_utils74 = require("@eeplatform/nodejs-utils");
|
|
28184
|
+
var import_mongodb43 = require("mongodb");
|
|
28185
|
+
function useAssetRepo() {
|
|
28186
|
+
const db = import_nodejs_utils74.useAtlas.getDb();
|
|
28187
|
+
if (!db) {
|
|
28188
|
+
throw new import_nodejs_utils74.BadRequestError("Unable to connect to server.");
|
|
28189
|
+
}
|
|
28190
|
+
const namespace_collection = "school.assets";
|
|
28191
|
+
const collection = db.collection(namespace_collection);
|
|
28192
|
+
const { getCache, setCache, delNamespace } = (0, import_nodejs_utils74.useCache)(namespace_collection);
|
|
28193
|
+
function delCachedData() {
|
|
28194
|
+
delNamespace().then(() => {
|
|
28195
|
+
import_nodejs_utils74.logger.log({
|
|
28196
|
+
level: "info",
|
|
28197
|
+
message: `Cache namespace cleared for ${namespace_collection}`
|
|
28198
|
+
});
|
|
28199
|
+
}).catch((err) => {
|
|
28200
|
+
import_nodejs_utils74.logger.log({
|
|
28201
|
+
level: "error",
|
|
28202
|
+
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
28203
|
+
});
|
|
28204
|
+
});
|
|
28205
|
+
}
|
|
28206
|
+
async function createIndex() {
|
|
28207
|
+
try {
|
|
28208
|
+
await collection.createIndexes([
|
|
28209
|
+
{ key: { school: 1 } },
|
|
28210
|
+
{ key: { name: 1 } },
|
|
28211
|
+
{ key: { name: "text" } }
|
|
28212
|
+
]);
|
|
28213
|
+
} catch (error) {
|
|
28214
|
+
throw new import_nodejs_utils74.BadRequestError("Failed to create index on asset.");
|
|
28215
|
+
}
|
|
28216
|
+
}
|
|
28217
|
+
async function add(value) {
|
|
28218
|
+
try {
|
|
28219
|
+
value = MAsset(value);
|
|
28220
|
+
const res = await collection.insertOne(value);
|
|
28221
|
+
delCachedData();
|
|
28222
|
+
return res.insertedId;
|
|
28223
|
+
} catch (error) {
|
|
28224
|
+
throw new import_nodejs_utils74.BadRequestError("Failed to create asset item.");
|
|
28225
|
+
}
|
|
28226
|
+
}
|
|
28227
|
+
async function updateById(_id, value, session) {
|
|
28228
|
+
const { error } = schemaAssetUpdateOption.validate(value);
|
|
28229
|
+
if (error) {
|
|
28230
|
+
throw new import_nodejs_utils74.BadRequestError(error.message);
|
|
28231
|
+
}
|
|
28232
|
+
try {
|
|
28233
|
+
_id = new import_mongodb43.ObjectId(_id);
|
|
28234
|
+
} catch (error2) {
|
|
28235
|
+
throw new import_nodejs_utils74.BadRequestError("Invalid ID.");
|
|
28236
|
+
}
|
|
28237
|
+
try {
|
|
28238
|
+
const res = await collection.updateOne(
|
|
28239
|
+
{ _id },
|
|
28240
|
+
{ $set: value },
|
|
28241
|
+
{ session }
|
|
28242
|
+
);
|
|
28243
|
+
if (res.modifiedCount) {
|
|
28244
|
+
delCachedData();
|
|
28245
|
+
}
|
|
28246
|
+
return "Successfully updated asset item.";
|
|
28247
|
+
} catch (error2) {
|
|
28248
|
+
throw new import_nodejs_utils74.BadRequestError("Failed to update asset item.");
|
|
28249
|
+
}
|
|
28250
|
+
}
|
|
28251
|
+
async function deleteById(_id) {
|
|
28252
|
+
try {
|
|
28253
|
+
_id = new import_mongodb43.ObjectId(_id);
|
|
28254
|
+
} catch (error) {
|
|
28255
|
+
throw new import_nodejs_utils74.BadRequestError("Invalid ID.");
|
|
28256
|
+
}
|
|
28257
|
+
try {
|
|
28258
|
+
const res = await collection.deleteOne({ _id });
|
|
28259
|
+
if (res.deletedCount) {
|
|
28260
|
+
delCachedData();
|
|
28261
|
+
return "Successfully deleted asset item.";
|
|
28262
|
+
}
|
|
28263
|
+
return "Successfully deleted asset item.";
|
|
28264
|
+
} catch (error) {
|
|
28265
|
+
throw new import_nodejs_utils74.BadRequestError("Failed to delete asset item.");
|
|
28266
|
+
}
|
|
28267
|
+
}
|
|
28268
|
+
async function getById(_id) {
|
|
28269
|
+
try {
|
|
28270
|
+
_id = new import_mongodb43.ObjectId(_id);
|
|
28271
|
+
} catch (error) {
|
|
28272
|
+
throw new import_nodejs_utils74.BadRequestError("Invalid ID.");
|
|
28273
|
+
}
|
|
28274
|
+
const cacheKey = (0, import_nodejs_utils74.makeCacheKey)(namespace_collection, { _id: String(_id) });
|
|
28275
|
+
const cachedData = await getCache(cacheKey);
|
|
28276
|
+
if (cachedData) {
|
|
28277
|
+
return cachedData;
|
|
28278
|
+
}
|
|
28279
|
+
try {
|
|
28280
|
+
const res = await collection.findOne({ _id });
|
|
28281
|
+
if (!res) {
|
|
28282
|
+
throw new import_nodejs_utils74.BadRequestError("Asset item not found.");
|
|
28283
|
+
}
|
|
28284
|
+
setCache(cacheKey, res).then(() => {
|
|
28285
|
+
import_nodejs_utils74.logger.log({
|
|
28286
|
+
level: "info",
|
|
28287
|
+
message: `Cache set for asset item by ID: ${cacheKey}`
|
|
28288
|
+
});
|
|
28289
|
+
}).catch((err) => {
|
|
28290
|
+
import_nodejs_utils74.logger.log({
|
|
28291
|
+
level: "error",
|
|
28292
|
+
message: `Failed to set cache for asset item by ID: ${cacheKey} - ${err.message}`
|
|
28293
|
+
});
|
|
28294
|
+
});
|
|
28295
|
+
return res;
|
|
28296
|
+
} catch (error) {
|
|
28297
|
+
if (error instanceof import_nodejs_utils74.BadRequestError) {
|
|
28298
|
+
throw error;
|
|
28299
|
+
}
|
|
28300
|
+
throw new import_nodejs_utils74.BadRequestError("Failed to retrieve asset item.");
|
|
28301
|
+
}
|
|
28302
|
+
}
|
|
28303
|
+
async function getAll({
|
|
28304
|
+
page = 1,
|
|
28305
|
+
search = "",
|
|
28306
|
+
limit = 20,
|
|
28307
|
+
status = "active",
|
|
28308
|
+
school = "",
|
|
28309
|
+
sort = { _id: -1 },
|
|
28310
|
+
asset_type = "supply"
|
|
28311
|
+
} = {}) {
|
|
28312
|
+
page = page ? page - 1 : 0;
|
|
28313
|
+
try {
|
|
28314
|
+
school = new import_mongodb43.ObjectId(school);
|
|
28315
|
+
} catch (error) {
|
|
28316
|
+
throw new import_nodejs_utils74.BadRequestError("Invalid school ID.");
|
|
28317
|
+
}
|
|
28318
|
+
const query = {
|
|
28319
|
+
school,
|
|
28320
|
+
status,
|
|
28321
|
+
asset_type
|
|
28322
|
+
};
|
|
28323
|
+
const cacheKeyOptions = {
|
|
28324
|
+
page,
|
|
28325
|
+
limit,
|
|
28326
|
+
status,
|
|
28327
|
+
school: String(school),
|
|
28328
|
+
sort: JSON.stringify(sort),
|
|
28329
|
+
asset_type
|
|
28330
|
+
};
|
|
28331
|
+
if (search) {
|
|
28332
|
+
query.$text = { $search: search };
|
|
28333
|
+
cacheKeyOptions.search = search;
|
|
28334
|
+
}
|
|
28335
|
+
try {
|
|
28336
|
+
const cacheKey = (0, import_nodejs_utils74.makeCacheKey)(namespace_collection, cacheKeyOptions);
|
|
28337
|
+
const cached = await getCache(cacheKey);
|
|
28338
|
+
if (cached) {
|
|
28339
|
+
import_nodejs_utils74.logger.log({
|
|
28340
|
+
level: "info",
|
|
28341
|
+
message: `Cache hit for getAll asset items: ${cacheKey}`
|
|
28342
|
+
});
|
|
28343
|
+
return cached;
|
|
28344
|
+
}
|
|
28345
|
+
const items = await collection.aggregate([
|
|
28346
|
+
{ $match: query },
|
|
28347
|
+
{
|
|
28348
|
+
$sort: sort
|
|
28349
|
+
},
|
|
28350
|
+
{
|
|
28351
|
+
$skip: page * limit
|
|
28352
|
+
},
|
|
28353
|
+
{
|
|
28354
|
+
$limit: limit
|
|
28355
|
+
}
|
|
28356
|
+
]).toArray();
|
|
28357
|
+
const length = await collection.countDocuments(query);
|
|
28358
|
+
const data = (0, import_nodejs_utils74.paginate)(items, page, limit, length);
|
|
28359
|
+
setCache(cacheKey, data, 500).then(() => {
|
|
28360
|
+
import_nodejs_utils74.logger.log({
|
|
28361
|
+
level: "info",
|
|
28362
|
+
message: `Cache set for getAll asset items: ${cacheKey}`
|
|
28363
|
+
});
|
|
28364
|
+
}).catch((err) => {
|
|
28365
|
+
import_nodejs_utils74.logger.log({
|
|
28366
|
+
level: "error",
|
|
28367
|
+
message: `Failed to set cache for getAll asset items: ${err.message}`
|
|
28368
|
+
});
|
|
28369
|
+
});
|
|
28370
|
+
return data;
|
|
28371
|
+
} catch (error) {
|
|
28372
|
+
console.log("Error in getAll:", error);
|
|
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
|
+
);
|
|
28550
|
+
}
|
|
28551
|
+
}
|
|
28552
|
+
return {
|
|
28553
|
+
createIndex,
|
|
28554
|
+
add,
|
|
28555
|
+
updateById,
|
|
28556
|
+
deleteById,
|
|
28557
|
+
getById,
|
|
28558
|
+
getAll,
|
|
28559
|
+
getCategories,
|
|
28560
|
+
getTypes,
|
|
28561
|
+
getUnitsBySchool
|
|
28562
|
+
};
|
|
28563
|
+
}
|
|
28564
|
+
|
|
28565
|
+
// src/controllers/asset.controller.ts
|
|
28566
|
+
var import_nodejs_utils75 = require("@eeplatform/nodejs-utils");
|
|
28567
|
+
var import_joi37 = __toESM(require("joi"));
|
|
28568
|
+
function useAssetController() {
|
|
28569
|
+
const {
|
|
28570
|
+
add: _add,
|
|
28571
|
+
getAll: _getAll,
|
|
28572
|
+
deleteById: _deleteById,
|
|
28573
|
+
updateById: _updateById,
|
|
28574
|
+
getById: _getById,
|
|
28575
|
+
getCategories: _getCategories,
|
|
28576
|
+
getTypes: _getTypes,
|
|
28577
|
+
getUnitsBySchool: _getUnitsBySchool
|
|
28578
|
+
} = useAssetRepo();
|
|
28579
|
+
async function add(req, res, next) {
|
|
28580
|
+
const value = req.body;
|
|
28581
|
+
const { error } = schemaAsset.validate(value);
|
|
28582
|
+
if (error) {
|
|
28583
|
+
next(new import_nodejs_utils75.BadRequestError(error.message));
|
|
28584
|
+
return;
|
|
28585
|
+
}
|
|
28586
|
+
try {
|
|
28587
|
+
const id = await _add(value);
|
|
28588
|
+
res.json({ message: "Successfully added asset item.", id });
|
|
28589
|
+
} catch (error2) {
|
|
28590
|
+
next(error2);
|
|
28591
|
+
}
|
|
28592
|
+
}
|
|
28593
|
+
async function getAll(req, res, next) {
|
|
28594
|
+
const query = req.query;
|
|
28595
|
+
const validation = import_joi37.default.object({
|
|
28596
|
+
page: import_joi37.default.number().min(1).optional().allow("", null),
|
|
28597
|
+
limit: import_joi37.default.number().min(1).optional().allow("", null),
|
|
28598
|
+
search: import_joi37.default.string().optional().allow("", null),
|
|
28599
|
+
status: import_joi37.default.string().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")
|
|
28602
|
+
});
|
|
28603
|
+
const { error } = validation.validate(query);
|
|
28604
|
+
const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
|
|
28605
|
+
const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
|
|
28606
|
+
const search = req.query.search ?? "";
|
|
28607
|
+
const status = req.query.status ?? "active";
|
|
28608
|
+
const school = req.query.school ?? "";
|
|
28609
|
+
const asset_type = req.query.asset_type ?? "supply";
|
|
28610
|
+
const isPageNumber = isFinite(page);
|
|
28611
|
+
if (!isPageNumber) {
|
|
28612
|
+
next(new import_nodejs_utils75.BadRequestError("Invalid page number."));
|
|
28613
|
+
return;
|
|
28614
|
+
}
|
|
28615
|
+
const isLimitNumber = isFinite(limit);
|
|
28616
|
+
if (!isLimitNumber) {
|
|
28617
|
+
next(new import_nodejs_utils75.BadRequestError("Invalid limit number."));
|
|
28618
|
+
return;
|
|
28619
|
+
}
|
|
28620
|
+
if (error) {
|
|
28621
|
+
next(new import_nodejs_utils75.BadRequestError(error.message));
|
|
28622
|
+
return;
|
|
28623
|
+
}
|
|
28624
|
+
try {
|
|
28625
|
+
const regions = await _getAll({
|
|
28626
|
+
page,
|
|
28627
|
+
limit,
|
|
28628
|
+
search,
|
|
28629
|
+
status,
|
|
28630
|
+
school,
|
|
28631
|
+
asset_type
|
|
28632
|
+
});
|
|
28633
|
+
res.json(regions);
|
|
28634
|
+
return;
|
|
28635
|
+
} catch (error2) {
|
|
28636
|
+
next(error2);
|
|
28637
|
+
}
|
|
28638
|
+
}
|
|
28639
|
+
async function deleteById(req, res, next) {
|
|
28640
|
+
const id = req.params.id;
|
|
28641
|
+
const validation = import_joi37.default.string().hex().required();
|
|
28642
|
+
const { error } = validation.validate(id);
|
|
28643
|
+
if (error) {
|
|
28644
|
+
next(new import_nodejs_utils75.BadRequestError(error.message));
|
|
28645
|
+
return;
|
|
28646
|
+
}
|
|
28647
|
+
try {
|
|
28648
|
+
await _deleteById(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);
|
|
28665
|
+
} catch (error2) {
|
|
28666
|
+
next(error2);
|
|
28667
|
+
}
|
|
28668
|
+
}
|
|
28669
|
+
async function updateById(req, res, next) {
|
|
28670
|
+
const id = req.params.id;
|
|
28671
|
+
const value = req.body;
|
|
28672
|
+
const { error } = schemaAssetUpdateOption.validate(value);
|
|
28673
|
+
if (error) {
|
|
28674
|
+
next(new import_nodejs_utils75.BadRequestError(error.message));
|
|
28675
|
+
return;
|
|
28676
|
+
}
|
|
28677
|
+
try {
|
|
28678
|
+
await _updateById(id, value);
|
|
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);
|
|
28727
|
+
} catch (error2) {
|
|
28728
|
+
next(error2);
|
|
28729
|
+
}
|
|
28730
|
+
}
|
|
28731
|
+
return {
|
|
28732
|
+
add,
|
|
28733
|
+
getAll,
|
|
28734
|
+
deleteById,
|
|
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
|
|
29151
|
+
};
|
|
29152
|
+
}
|
|
28041
29153
|
// Annotate the CommonJS export names for ESM import in node:
|
|
28042
29154
|
0 && (module.exports = {
|
|
28043
29155
|
ACCESS_TOKEN_EXPIRY,
|
|
@@ -28057,6 +29169,7 @@ function useBuildingUnitController() {
|
|
|
28057
29169
|
MAILER_TRANSPORT_PORT,
|
|
28058
29170
|
MAILER_TRANSPORT_SECURE,
|
|
28059
29171
|
MAddress,
|
|
29172
|
+
MAsset,
|
|
28060
29173
|
MBuilding,
|
|
28061
29174
|
MBuildingUnit,
|
|
28062
29175
|
MDivision,
|
|
@@ -28072,6 +29185,7 @@ function useBuildingUnitController() {
|
|
|
28072
29185
|
MRegion,
|
|
28073
29186
|
MRole,
|
|
28074
29187
|
MSchool,
|
|
29188
|
+
MStockCard,
|
|
28075
29189
|
MSubscription,
|
|
28076
29190
|
MToken,
|
|
28077
29191
|
MUser,
|
|
@@ -28099,14 +29213,19 @@ function useBuildingUnitController() {
|
|
|
28099
29213
|
addressSchema,
|
|
28100
29214
|
isDev,
|
|
28101
29215
|
schema,
|
|
29216
|
+
schemaAsset,
|
|
29217
|
+
schemaAssetUpdateOption,
|
|
28102
29218
|
schemaBuilding,
|
|
28103
29219
|
schemaBuildingUnit,
|
|
28104
29220
|
schemaDivision,
|
|
28105
29221
|
schemaRegion,
|
|
28106
29222
|
schemaSchool,
|
|
29223
|
+
schemaStockCard,
|
|
28107
29224
|
schemaUpdateOptions,
|
|
28108
29225
|
useAddressController,
|
|
28109
29226
|
useAddressRepo,
|
|
29227
|
+
useAssetController,
|
|
29228
|
+
useAssetRepo,
|
|
28110
29229
|
useAuthController,
|
|
28111
29230
|
useAuthService,
|
|
28112
29231
|
useBuildingController,
|
|
@@ -28154,6 +29273,8 @@ function useBuildingUnitController() {
|
|
|
28154
29273
|
useSchoolController,
|
|
28155
29274
|
useSchoolRepo,
|
|
28156
29275
|
useSchoolService,
|
|
29276
|
+
useStockCardController,
|
|
29277
|
+
useStockCardRepository,
|
|
28157
29278
|
useSubscriptionController,
|
|
28158
29279
|
useSubscriptionRepo,
|
|
28159
29280
|
useSubscriptionService,
|