@eeplatform/core 1.4.5 → 1.5.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 +6 -0
- package/dist/index.d.ts +138 -3
- package/dist/index.js +1167 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1176 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -10384,7 +10384,7 @@ var require_ms = __commonJS({
|
|
|
10384
10384
|
options = options || {};
|
|
10385
10385
|
var type = typeof val;
|
|
10386
10386
|
if (type === "string" && val.length > 0) {
|
|
10387
|
-
return
|
|
10387
|
+
return parse4(val);
|
|
10388
10388
|
} else if (type === "number" && isNaN(val) === false) {
|
|
10389
10389
|
return options.long ? fmtLong(val) : fmtShort(val);
|
|
10390
10390
|
}
|
|
@@ -10392,7 +10392,7 @@ var require_ms = __commonJS({
|
|
|
10392
10392
|
"val is not a non-empty string or a valid number. val=" + JSON.stringify(val)
|
|
10393
10393
|
);
|
|
10394
10394
|
};
|
|
10395
|
-
function
|
|
10395
|
+
function parse4(str) {
|
|
10396
10396
|
str = String(str);
|
|
10397
10397
|
if (str.length > 100) {
|
|
10398
10398
|
return;
|
|
@@ -11345,12 +11345,14 @@ __export(src_exports, {
|
|
|
11345
11345
|
MAsset: () => MAsset,
|
|
11346
11346
|
MBuilding: () => MBuilding,
|
|
11347
11347
|
MBuildingUnit: () => MBuildingUnit,
|
|
11348
|
+
MCurriculum: () => MCurriculum,
|
|
11348
11349
|
MDivision: () => MDivision,
|
|
11349
11350
|
MEntity: () => MEntity,
|
|
11350
11351
|
MFile: () => MFile,
|
|
11351
11352
|
MMember: () => MMember,
|
|
11352
11353
|
MONGO_DB: () => MONGO_DB,
|
|
11353
11354
|
MONGO_URI: () => MONGO_URI,
|
|
11355
|
+
MOffice: () => MOffice,
|
|
11354
11356
|
MOrder: () => MOrder,
|
|
11355
11357
|
MOrg: () => MOrg,
|
|
11356
11358
|
MPaymentMethod: () => MPaymentMethod,
|
|
@@ -11391,7 +11393,9 @@ __export(src_exports, {
|
|
|
11391
11393
|
schemaAssetUpdateOption: () => schemaAssetUpdateOption,
|
|
11392
11394
|
schemaBuilding: () => schemaBuilding,
|
|
11393
11395
|
schemaBuildingUnit: () => schemaBuildingUnit,
|
|
11396
|
+
schemaCurriculum: () => schemaCurriculum,
|
|
11394
11397
|
schemaDivision: () => schemaDivision,
|
|
11398
|
+
schemaOffice: () => schemaOffice,
|
|
11395
11399
|
schemaPlantilla: () => schemaPlantilla,
|
|
11396
11400
|
schemaRegion: () => schemaRegion,
|
|
11397
11401
|
schemaSchool: () => schemaSchool,
|
|
@@ -11409,6 +11413,8 @@ __export(src_exports, {
|
|
|
11409
11413
|
useBuildingUnitRepo: () => useBuildingUnitRepo,
|
|
11410
11414
|
useCounterModel: () => useCounterModel,
|
|
11411
11415
|
useCounterRepo: () => useCounterRepo,
|
|
11416
|
+
useCurriculumController: () => useCurriculumController,
|
|
11417
|
+
useCurriculumRepo: () => useCurriculumRepo,
|
|
11412
11418
|
useDivisionController: () => useDivisionController,
|
|
11413
11419
|
useDivisionRepo: () => useDivisionRepo,
|
|
11414
11420
|
useDivisionService: () => useDivisionService,
|
|
@@ -11424,6 +11430,9 @@ __export(src_exports, {
|
|
|
11424
11430
|
useInvoiceService: () => useInvoiceService,
|
|
11425
11431
|
useMemberController: () => useMemberController,
|
|
11426
11432
|
useMemberRepo: () => useMemberRepo,
|
|
11433
|
+
useOfficeController: () => useOfficeController,
|
|
11434
|
+
useOfficeRepo: () => useOfficeRepo,
|
|
11435
|
+
useOfficeService: () => useOfficeService,
|
|
11427
11436
|
useOrderController: () => useOrderController,
|
|
11428
11437
|
useOrderRepo: () => useOrderRepo,
|
|
11429
11438
|
useOrgController: () => useOrgController,
|
|
@@ -28328,7 +28337,10 @@ function useBuildingUnitService() {
|
|
|
28328
28337
|
try {
|
|
28329
28338
|
await session.startTransaction();
|
|
28330
28339
|
for (let index = 0; index < value.qty; index++) {
|
|
28331
|
-
await _add(
|
|
28340
|
+
await _add(
|
|
28341
|
+
{ ...value.building, name: `${value.building.name} ${index + 1}` },
|
|
28342
|
+
session
|
|
28343
|
+
);
|
|
28332
28344
|
}
|
|
28333
28345
|
await session.commitTransaction();
|
|
28334
28346
|
return "Building unit added successfully.";
|
|
@@ -29820,6 +29832,10 @@ var import_joi41 = __toESM(require("joi"));
|
|
|
29820
29832
|
var import_mongodb46 = require("mongodb");
|
|
29821
29833
|
var schemaPlantilla = import_joi41.default.object({
|
|
29822
29834
|
_id: import_joi41.default.string().hex().optional().allow(null, ""),
|
|
29835
|
+
org: import_joi41.default.string().hex().required(),
|
|
29836
|
+
orgUnitCode: import_joi41.default.string().optional().allow(null, ""),
|
|
29837
|
+
employmentType: import_joi41.default.string().optional().allow(null, ""),
|
|
29838
|
+
personnelType: import_joi41.default.string().required(),
|
|
29823
29839
|
itemNumber: import_joi41.default.string().required(),
|
|
29824
29840
|
positionTitle: import_joi41.default.string().required(),
|
|
29825
29841
|
positionCategory: import_joi41.default.string().required(),
|
|
@@ -29828,8 +29844,7 @@ var schemaPlantilla = import_joi41.default.object({
|
|
|
29828
29844
|
division: import_joi41.default.string().hex().optional().allow(null, ""),
|
|
29829
29845
|
divisionName: import_joi41.default.string().optional().allow(null, ""),
|
|
29830
29846
|
salaryGrade: import_joi41.default.number().required(),
|
|
29831
|
-
|
|
29832
|
-
incumbent: import_joi41.default.string().optional().allow(null, ""),
|
|
29847
|
+
employeeName: import_joi41.default.string().optional().allow(null, ""),
|
|
29833
29848
|
annualSalary: import_joi41.default.number().optional().allow(null, 0),
|
|
29834
29849
|
monthlySalary: import_joi41.default.number().optional().allow(null, 0),
|
|
29835
29850
|
status: import_joi41.default.string().required(),
|
|
@@ -29857,14 +29872,18 @@ function MPlantilla(data) {
|
|
|
29857
29872
|
positionCategory: data.positionCategory ?? "",
|
|
29858
29873
|
status: data.status ?? "active",
|
|
29859
29874
|
salaryGrade: data.salaryGrade ?? 0,
|
|
29860
|
-
step: data.step ?? 0,
|
|
29861
29875
|
monthlySalary: data.monthlySalary ?? 0,
|
|
29862
29876
|
annualSalary: data.annualSalary ?? 0,
|
|
29863
29877
|
region: data.region ?? "",
|
|
29864
29878
|
regionName: data.regionName ?? "",
|
|
29865
29879
|
division: data.division ?? "",
|
|
29866
29880
|
divisionName: data.divisionName ?? "",
|
|
29867
|
-
|
|
29881
|
+
org: data.org ?? "",
|
|
29882
|
+
orgUnitCode: data.orgUnitCode ?? "",
|
|
29883
|
+
employmentType: data.employmentType ?? "",
|
|
29884
|
+
personnelType: data.personnelType ?? "",
|
|
29885
|
+
employee: data.employee ?? "",
|
|
29886
|
+
employeeName: data.employeeName ?? "",
|
|
29868
29887
|
createdAt: data.createdAt ? new Date(data.createdAt) : /* @__PURE__ */ new Date(),
|
|
29869
29888
|
updatedAt: data.updatedAt ? new Date(data.updatedAt) : "",
|
|
29870
29889
|
deletedAt: data.deletedAt ? new Date(data.deletedAt) : ""
|
|
@@ -30205,7 +30224,8 @@ function usePlantillaService() {
|
|
|
30205
30224
|
salaryGrade: parseInt(
|
|
30206
30225
|
plantillaData.salarygrade || plantillaData.salary_grade || "1"
|
|
30207
30226
|
) || 1,
|
|
30208
|
-
|
|
30227
|
+
org: "",
|
|
30228
|
+
personnelType: "",
|
|
30209
30229
|
status: status.trim() || "active"
|
|
30210
30230
|
};
|
|
30211
30231
|
if (region)
|
|
@@ -30218,9 +30238,6 @@ function usePlantillaService() {
|
|
|
30218
30238
|
if (plantillaData.divisionname || plantillaData.division_name) {
|
|
30219
30239
|
plantilla.divisionName = plantillaData.divisionname || plantillaData.division_name;
|
|
30220
30240
|
}
|
|
30221
|
-
if (plantillaData.incumbent) {
|
|
30222
|
-
plantilla.incumbent = plantillaData.incumbent;
|
|
30223
|
-
}
|
|
30224
30241
|
if (plantillaData.employee) {
|
|
30225
30242
|
plantilla.employee = plantillaData.employee;
|
|
30226
30243
|
}
|
|
@@ -30501,6 +30518,1136 @@ function usePlantillaController() {
|
|
|
30501
30518
|
bulkAddPlantillas
|
|
30502
30519
|
};
|
|
30503
30520
|
}
|
|
30521
|
+
|
|
30522
|
+
// src/models/office.model.ts
|
|
30523
|
+
var import_nodejs_utils86 = require("@eeplatform/nodejs-utils");
|
|
30524
|
+
var import_joi43 = __toESM(require("joi"));
|
|
30525
|
+
var import_mongodb48 = require("mongodb");
|
|
30526
|
+
var schemaOffice = import_joi43.default.object({
|
|
30527
|
+
_id: import_joi43.default.string().hex().optional().allow(null, ""),
|
|
30528
|
+
name: import_joi43.default.string().required(),
|
|
30529
|
+
code: import_joi43.default.string().required(),
|
|
30530
|
+
type: import_joi43.default.string().required(),
|
|
30531
|
+
parent: import_joi43.default.string().hex().optional().allow(null, ""),
|
|
30532
|
+
path: import_joi43.default.string().required(),
|
|
30533
|
+
status: import_joi43.default.string().required(),
|
|
30534
|
+
createdAt: import_joi43.default.date().iso().optional().allow(null, ""),
|
|
30535
|
+
updatedAt: import_joi43.default.date().iso().optional().allow(null, ""),
|
|
30536
|
+
deletedAt: import_joi43.default.date().iso().optional().allow(null, "")
|
|
30537
|
+
});
|
|
30538
|
+
function MOffice(data) {
|
|
30539
|
+
const { error } = schemaOffice.validate(data);
|
|
30540
|
+
if (error) {
|
|
30541
|
+
throw new import_nodejs_utils86.BadRequestError(error.message);
|
|
30542
|
+
}
|
|
30543
|
+
if (data._id && typeof data._id === "string") {
|
|
30544
|
+
try {
|
|
30545
|
+
data._id = new import_mongodb48.ObjectId(data._id);
|
|
30546
|
+
} catch (error2) {
|
|
30547
|
+
throw new import_nodejs_utils86.BadRequestError("Invalid _id.");
|
|
30548
|
+
}
|
|
30549
|
+
}
|
|
30550
|
+
if (data.parent && typeof data.parent === "string") {
|
|
30551
|
+
try {
|
|
30552
|
+
data.parent = new import_mongodb48.ObjectId(data.parent);
|
|
30553
|
+
} catch (error2) {
|
|
30554
|
+
throw new import_nodejs_utils86.BadRequestError("Invalid parent.");
|
|
30555
|
+
}
|
|
30556
|
+
}
|
|
30557
|
+
return {
|
|
30558
|
+
_id: data._id,
|
|
30559
|
+
name: data.name ?? "",
|
|
30560
|
+
code: data.code ?? "",
|
|
30561
|
+
type: data.type ?? "",
|
|
30562
|
+
parent: data.parent ?? "",
|
|
30563
|
+
path: data.path ?? "",
|
|
30564
|
+
status: data.status ?? "active",
|
|
30565
|
+
createdAt: data.createdAt ? new Date(data.createdAt) : /* @__PURE__ */ new Date(),
|
|
30566
|
+
updatedAt: data.updatedAt ? new Date(data.updatedAt) : "",
|
|
30567
|
+
deletedAt: data.deletedAt ? new Date(data.deletedAt) : ""
|
|
30568
|
+
};
|
|
30569
|
+
}
|
|
30570
|
+
|
|
30571
|
+
// src/repositories/office.repository.ts
|
|
30572
|
+
var import_nodejs_utils87 = require("@eeplatform/nodejs-utils");
|
|
30573
|
+
var import_mongodb49 = require("mongodb");
|
|
30574
|
+
function useOfficeRepo() {
|
|
30575
|
+
const db = import_nodejs_utils87.useAtlas.getDb();
|
|
30576
|
+
if (!db) {
|
|
30577
|
+
throw new Error("Unable to connect to server.");
|
|
30578
|
+
}
|
|
30579
|
+
const namespace_collection = "offices";
|
|
30580
|
+
const collection = db.collection(namespace_collection);
|
|
30581
|
+
const { getCache, setCache, delNamespace } = (0, import_nodejs_utils87.useCache)(namespace_collection);
|
|
30582
|
+
async function createIndexes() {
|
|
30583
|
+
try {
|
|
30584
|
+
await collection.createIndexes([
|
|
30585
|
+
{
|
|
30586
|
+
key: { name: 1, code: 1 },
|
|
30587
|
+
unique: true,
|
|
30588
|
+
name: "unique_name_code_index"
|
|
30589
|
+
},
|
|
30590
|
+
{ key: { type: 1 } },
|
|
30591
|
+
{ key: { parent: 1 } },
|
|
30592
|
+
{ key: { status: 1 } }
|
|
30593
|
+
]);
|
|
30594
|
+
} catch (error) {
|
|
30595
|
+
throw new Error("Failed to create index on offices.");
|
|
30596
|
+
}
|
|
30597
|
+
}
|
|
30598
|
+
async function add(value, session, clearCache = true) {
|
|
30599
|
+
try {
|
|
30600
|
+
value = MOffice(value);
|
|
30601
|
+
const res = await collection.insertOne(value, { session });
|
|
30602
|
+
if (clearCache) {
|
|
30603
|
+
delCachedData();
|
|
30604
|
+
}
|
|
30605
|
+
return res.insertedId;
|
|
30606
|
+
} catch (error) {
|
|
30607
|
+
import_nodejs_utils87.logger.log({
|
|
30608
|
+
level: "error",
|
|
30609
|
+
message: error.message
|
|
30610
|
+
});
|
|
30611
|
+
if (error instanceof import_nodejs_utils87.AppError) {
|
|
30612
|
+
throw error;
|
|
30613
|
+
} else {
|
|
30614
|
+
const isDuplicated = error.message.includes("duplicate");
|
|
30615
|
+
if (isDuplicated) {
|
|
30616
|
+
throw new import_nodejs_utils87.BadRequestError("Office already exists.");
|
|
30617
|
+
}
|
|
30618
|
+
throw new Error("Failed to create office.");
|
|
30619
|
+
}
|
|
30620
|
+
}
|
|
30621
|
+
}
|
|
30622
|
+
async function updateById(_id, value, session) {
|
|
30623
|
+
try {
|
|
30624
|
+
_id = new import_mongodb49.ObjectId(_id);
|
|
30625
|
+
} catch (error) {
|
|
30626
|
+
throw new import_nodejs_utils87.BadRequestError("Invalid ID.");
|
|
30627
|
+
}
|
|
30628
|
+
value.updatedAt = /* @__PURE__ */ new Date();
|
|
30629
|
+
try {
|
|
30630
|
+
const res = await collection.updateOne(
|
|
30631
|
+
{ _id },
|
|
30632
|
+
{ $set: value },
|
|
30633
|
+
{ session }
|
|
30634
|
+
);
|
|
30635
|
+
delCachedData();
|
|
30636
|
+
return res;
|
|
30637
|
+
} catch (error) {
|
|
30638
|
+
import_nodejs_utils87.logger.log({
|
|
30639
|
+
level: "error",
|
|
30640
|
+
message: error.message
|
|
30641
|
+
});
|
|
30642
|
+
if (error instanceof import_nodejs_utils87.AppError) {
|
|
30643
|
+
throw error;
|
|
30644
|
+
} else {
|
|
30645
|
+
throw new Error("Failed to update office.");
|
|
30646
|
+
}
|
|
30647
|
+
}
|
|
30648
|
+
}
|
|
30649
|
+
async function getAll({
|
|
30650
|
+
search = "",
|
|
30651
|
+
page = 1,
|
|
30652
|
+
limit = 10,
|
|
30653
|
+
sort = {},
|
|
30654
|
+
type = "",
|
|
30655
|
+
parent = "",
|
|
30656
|
+
status = "active"
|
|
30657
|
+
} = {}) {
|
|
30658
|
+
page = page > 0 ? page - 1 : 0;
|
|
30659
|
+
const query = {
|
|
30660
|
+
status
|
|
30661
|
+
};
|
|
30662
|
+
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
30663
|
+
if (search) {
|
|
30664
|
+
query.$text = { $search: search };
|
|
30665
|
+
}
|
|
30666
|
+
if (type) {
|
|
30667
|
+
query.type = type;
|
|
30668
|
+
}
|
|
30669
|
+
if (parent) {
|
|
30670
|
+
try {
|
|
30671
|
+
query.parent = new import_mongodb49.ObjectId(parent);
|
|
30672
|
+
} catch (error) {
|
|
30673
|
+
throw new import_nodejs_utils87.BadRequestError("Invalid parent ID.");
|
|
30674
|
+
}
|
|
30675
|
+
}
|
|
30676
|
+
const cacheParams = {
|
|
30677
|
+
page,
|
|
30678
|
+
limit,
|
|
30679
|
+
sort: JSON.stringify(sort)
|
|
30680
|
+
};
|
|
30681
|
+
if (search)
|
|
30682
|
+
cacheParams.search = search;
|
|
30683
|
+
if (type)
|
|
30684
|
+
cacheParams.type = type;
|
|
30685
|
+
if (parent)
|
|
30686
|
+
cacheParams.parent = parent;
|
|
30687
|
+
if (status !== "active")
|
|
30688
|
+
cacheParams.status = status;
|
|
30689
|
+
const cacheKey = (0, import_nodejs_utils87.makeCacheKey)(namespace_collection, cacheParams);
|
|
30690
|
+
import_nodejs_utils87.logger.log({
|
|
30691
|
+
level: "info",
|
|
30692
|
+
message: `Cache key for getAll offices: ${cacheKey}`
|
|
30693
|
+
});
|
|
30694
|
+
try {
|
|
30695
|
+
const cached = await getCache(cacheKey);
|
|
30696
|
+
if (cached) {
|
|
30697
|
+
import_nodejs_utils87.logger.log({
|
|
30698
|
+
level: "info",
|
|
30699
|
+
message: `Cache hit for getAll offices: ${cacheKey}`
|
|
30700
|
+
});
|
|
30701
|
+
return cached;
|
|
30702
|
+
}
|
|
30703
|
+
const items = await collection.aggregate([
|
|
30704
|
+
{ $match: query },
|
|
30705
|
+
{ $sort: sort },
|
|
30706
|
+
{ $skip: page * limit },
|
|
30707
|
+
{ $limit: limit }
|
|
30708
|
+
]).toArray();
|
|
30709
|
+
const length = await collection.countDocuments(query);
|
|
30710
|
+
const data = (0, import_nodejs_utils87.paginate)(items, page, limit, length);
|
|
30711
|
+
setCache(cacheKey, data, 600).then(() => {
|
|
30712
|
+
import_nodejs_utils87.logger.log({
|
|
30713
|
+
level: "info",
|
|
30714
|
+
message: `Cache set for getAll offices: ${cacheKey}`
|
|
30715
|
+
});
|
|
30716
|
+
}).catch((err) => {
|
|
30717
|
+
import_nodejs_utils87.logger.log({
|
|
30718
|
+
level: "error",
|
|
30719
|
+
message: `Failed to set cache for getAll offices: ${err.message}`
|
|
30720
|
+
});
|
|
30721
|
+
});
|
|
30722
|
+
return data;
|
|
30723
|
+
} catch (error) {
|
|
30724
|
+
import_nodejs_utils87.logger.log({ level: "error", message: `${error}` });
|
|
30725
|
+
throw error;
|
|
30726
|
+
}
|
|
30727
|
+
}
|
|
30728
|
+
async function getById(_id) {
|
|
30729
|
+
try {
|
|
30730
|
+
_id = new import_mongodb49.ObjectId(_id);
|
|
30731
|
+
} catch (error) {
|
|
30732
|
+
throw new import_nodejs_utils87.BadRequestError("Invalid ID.");
|
|
30733
|
+
}
|
|
30734
|
+
const cacheKey = (0, import_nodejs_utils87.makeCacheKey)(namespace_collection, { _id: String(_id) });
|
|
30735
|
+
try {
|
|
30736
|
+
const cached = await getCache(cacheKey);
|
|
30737
|
+
if (cached) {
|
|
30738
|
+
import_nodejs_utils87.logger.log({
|
|
30739
|
+
level: "info",
|
|
30740
|
+
message: `Cache hit for getById office: ${cacheKey}`
|
|
30741
|
+
});
|
|
30742
|
+
return cached;
|
|
30743
|
+
}
|
|
30744
|
+
const result = await collection.findOne({
|
|
30745
|
+
_id
|
|
30746
|
+
});
|
|
30747
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
30748
|
+
import_nodejs_utils87.logger.log({
|
|
30749
|
+
level: "info",
|
|
30750
|
+
message: `Cache set for office by id: ${cacheKey}`
|
|
30751
|
+
});
|
|
30752
|
+
}).catch((err) => {
|
|
30753
|
+
import_nodejs_utils87.logger.log({
|
|
30754
|
+
level: "error",
|
|
30755
|
+
message: `Failed to set cache for office by id: ${err.message}`
|
|
30756
|
+
});
|
|
30757
|
+
});
|
|
30758
|
+
return result;
|
|
30759
|
+
} catch (error) {
|
|
30760
|
+
if (error instanceof import_nodejs_utils87.AppError) {
|
|
30761
|
+
throw error;
|
|
30762
|
+
} else {
|
|
30763
|
+
throw new import_nodejs_utils87.InternalServerError("Failed to get office.");
|
|
30764
|
+
}
|
|
30765
|
+
}
|
|
30766
|
+
}
|
|
30767
|
+
async function deleteById(_id, session) {
|
|
30768
|
+
try {
|
|
30769
|
+
_id = new import_mongodb49.ObjectId(_id);
|
|
30770
|
+
} catch (error) {
|
|
30771
|
+
throw new import_nodejs_utils87.BadRequestError("Invalid ID.");
|
|
30772
|
+
}
|
|
30773
|
+
try {
|
|
30774
|
+
const res = await collection.updateOne(
|
|
30775
|
+
{ _id },
|
|
30776
|
+
{ $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } }
|
|
30777
|
+
);
|
|
30778
|
+
delCachedData();
|
|
30779
|
+
return res;
|
|
30780
|
+
} catch (error) {
|
|
30781
|
+
import_nodejs_utils87.logger.log({
|
|
30782
|
+
level: "error",
|
|
30783
|
+
message: error.message
|
|
30784
|
+
});
|
|
30785
|
+
if (error instanceof import_nodejs_utils87.AppError) {
|
|
30786
|
+
throw error;
|
|
30787
|
+
} else {
|
|
30788
|
+
throw new import_nodejs_utils87.InternalServerError("Failed to delete office.");
|
|
30789
|
+
}
|
|
30790
|
+
}
|
|
30791
|
+
}
|
|
30792
|
+
function delCachedData() {
|
|
30793
|
+
delNamespace().then(() => {
|
|
30794
|
+
import_nodejs_utils87.logger.log({
|
|
30795
|
+
level: "info",
|
|
30796
|
+
message: `Cache namespace cleared for ${namespace_collection}`
|
|
30797
|
+
});
|
|
30798
|
+
}).catch((err) => {
|
|
30799
|
+
import_nodejs_utils87.logger.log({
|
|
30800
|
+
level: "error",
|
|
30801
|
+
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
30802
|
+
});
|
|
30803
|
+
});
|
|
30804
|
+
}
|
|
30805
|
+
return {
|
|
30806
|
+
createIndexes,
|
|
30807
|
+
add,
|
|
30808
|
+
getAll,
|
|
30809
|
+
getById,
|
|
30810
|
+
updateById,
|
|
30811
|
+
deleteById,
|
|
30812
|
+
delCachedData
|
|
30813
|
+
};
|
|
30814
|
+
}
|
|
30815
|
+
|
|
30816
|
+
// src/services/office.service.ts
|
|
30817
|
+
var import_nodejs_utils88 = require("@eeplatform/nodejs-utils");
|
|
30818
|
+
var XLSX3 = __toESM(require("xlsx"));
|
|
30819
|
+
var Papa3 = __toESM(require("papaparse"));
|
|
30820
|
+
function useOfficeService() {
|
|
30821
|
+
const { add: addOffice, delCachedData } = useOfficeRepo();
|
|
30822
|
+
async function addBulk(file) {
|
|
30823
|
+
import_nodejs_utils88.logger.log({
|
|
30824
|
+
level: "info",
|
|
30825
|
+
message: `Starting office bulk upload. File: ${file.originalname}, Size: ${file.size} bytes`
|
|
30826
|
+
});
|
|
30827
|
+
const MAX_SIZE = 16 * 1024 * 1024;
|
|
30828
|
+
let offices = [];
|
|
30829
|
+
let totalSize = 0;
|
|
30830
|
+
let validatedOffices = [];
|
|
30831
|
+
if (!file.buffer) {
|
|
30832
|
+
throw new import_nodejs_utils88.BadRequestError("File buffer is empty or corrupted");
|
|
30833
|
+
}
|
|
30834
|
+
try {
|
|
30835
|
+
const fileExtension = file.originalname.split(".").pop()?.toLowerCase();
|
|
30836
|
+
if (fileExtension === "csv") {
|
|
30837
|
+
const csvData = file.buffer.toString("utf-8");
|
|
30838
|
+
totalSize = Buffer.byteLength(csvData, "utf8");
|
|
30839
|
+
if (totalSize > MAX_SIZE) {
|
|
30840
|
+
throw new import_nodejs_utils88.BadRequestError(
|
|
30841
|
+
`File size exceeds limit. Maximum allowed: ${MAX_SIZE / 1024 / 1024}MB, Received: ${(totalSize / 1024 / 1024).toFixed(2)}MB`
|
|
30842
|
+
);
|
|
30843
|
+
}
|
|
30844
|
+
const parseResult = Papa3.parse(csvData, {
|
|
30845
|
+
header: true,
|
|
30846
|
+
skipEmptyLines: true,
|
|
30847
|
+
transformHeader: (header) => {
|
|
30848
|
+
return header.toLowerCase().replace(/\s+/g, "").replace(/[^\w]/g, "");
|
|
30849
|
+
}
|
|
30850
|
+
});
|
|
30851
|
+
if (parseResult.errors.length > 0) {
|
|
30852
|
+
throw new import_nodejs_utils88.BadRequestError(
|
|
30853
|
+
`CSV parsing errors: ${parseResult.errors.map((e) => e.message).join(", ")}`
|
|
30854
|
+
);
|
|
30855
|
+
}
|
|
30856
|
+
offices = parseResult.data || [];
|
|
30857
|
+
} else if (["xlsx", "xls"].includes(fileExtension || "")) {
|
|
30858
|
+
totalSize = file.buffer.length;
|
|
30859
|
+
if (totalSize > MAX_SIZE) {
|
|
30860
|
+
throw new import_nodejs_utils88.BadRequestError(
|
|
30861
|
+
`File size exceeds limit. Maximum allowed: ${MAX_SIZE / 1024 / 1024}MB, Received: ${(totalSize / 1024 / 1024).toFixed(2)}MB`
|
|
30862
|
+
);
|
|
30863
|
+
}
|
|
30864
|
+
const workbook = XLSX3.read(file.buffer, { type: "buffer" });
|
|
30865
|
+
const sheetName = workbook.SheetNames[0];
|
|
30866
|
+
if (!sheetName) {
|
|
30867
|
+
throw new import_nodejs_utils88.BadRequestError("Excel file contains no sheets");
|
|
30868
|
+
}
|
|
30869
|
+
const worksheet = workbook.Sheets[sheetName];
|
|
30870
|
+
offices = XLSX3.utils.sheet_to_json(worksheet, {
|
|
30871
|
+
header: 1,
|
|
30872
|
+
defval: ""
|
|
30873
|
+
});
|
|
30874
|
+
if (offices.length > 0) {
|
|
30875
|
+
const headers = offices[0];
|
|
30876
|
+
offices = offices.slice(1).map((row) => {
|
|
30877
|
+
const obj = {};
|
|
30878
|
+
headers.forEach((header, index) => {
|
|
30879
|
+
obj[header.trim()] = row[index] || "";
|
|
30880
|
+
});
|
|
30881
|
+
return obj;
|
|
30882
|
+
});
|
|
30883
|
+
}
|
|
30884
|
+
} else {
|
|
30885
|
+
throw new import_nodejs_utils88.BadRequestError(
|
|
30886
|
+
"Unsupported file format. Please upload CSV, XLS, or XLSX files."
|
|
30887
|
+
);
|
|
30888
|
+
}
|
|
30889
|
+
if (!offices || offices.length === 0) {
|
|
30890
|
+
throw new import_nodejs_utils88.BadRequestError("File is empty or contains no valid data");
|
|
30891
|
+
}
|
|
30892
|
+
const results = {
|
|
30893
|
+
total: offices.length,
|
|
30894
|
+
successful: 0,
|
|
30895
|
+
failed: 0,
|
|
30896
|
+
errors: []
|
|
30897
|
+
};
|
|
30898
|
+
import_nodejs_utils88.logger.log({
|
|
30899
|
+
level: "info",
|
|
30900
|
+
message: `Processing ${offices.length} offices from file`
|
|
30901
|
+
});
|
|
30902
|
+
for (let i = 0; i < offices.length; i++) {
|
|
30903
|
+
const officeData = offices[i];
|
|
30904
|
+
try {
|
|
30905
|
+
const cleanOffice = {
|
|
30906
|
+
name: String(officeData.name || "").trim(),
|
|
30907
|
+
code: String(officeData.code || "").trim(),
|
|
30908
|
+
type: String(officeData.type || "").trim(),
|
|
30909
|
+
path: String(officeData.path || "").trim(),
|
|
30910
|
+
status: String(officeData.status || "active").trim()
|
|
30911
|
+
};
|
|
30912
|
+
if (officeData.parent && String(officeData.parent).trim()) {
|
|
30913
|
+
cleanOffice.parent = String(officeData.parent).trim();
|
|
30914
|
+
}
|
|
30915
|
+
const { error } = schemaOffice.validate(cleanOffice);
|
|
30916
|
+
if (error) {
|
|
30917
|
+
results.errors.push(`Row ${i + 1}: ${error.message}`);
|
|
30918
|
+
results.failed++;
|
|
30919
|
+
continue;
|
|
30920
|
+
}
|
|
30921
|
+
validatedOffices.push(cleanOffice);
|
|
30922
|
+
} catch (error) {
|
|
30923
|
+
results.errors.push(`Row ${i + 1}: ${error.message}`);
|
|
30924
|
+
results.failed++;
|
|
30925
|
+
}
|
|
30926
|
+
}
|
|
30927
|
+
if (validatedOffices.length === 0) {
|
|
30928
|
+
throw new import_nodejs_utils88.BadRequestError(
|
|
30929
|
+
"No valid offices found in file. Please check the format and data."
|
|
30930
|
+
);
|
|
30931
|
+
}
|
|
30932
|
+
const db = import_nodejs_utils88.useAtlas.getDb();
|
|
30933
|
+
if (!db) {
|
|
30934
|
+
throw new Error("Database connection not available");
|
|
30935
|
+
}
|
|
30936
|
+
const session = db.client.startSession();
|
|
30937
|
+
try {
|
|
30938
|
+
await session.withTransaction(async () => {
|
|
30939
|
+
const batchSize = 100;
|
|
30940
|
+
for (let i = 0; i < validatedOffices.length; i += batchSize) {
|
|
30941
|
+
const batch = validatedOffices.slice(i, i + batchSize);
|
|
30942
|
+
for (const office of batch) {
|
|
30943
|
+
try {
|
|
30944
|
+
await addOffice(office, session, false);
|
|
30945
|
+
results.successful++;
|
|
30946
|
+
} catch (error) {
|
|
30947
|
+
results.failed++;
|
|
30948
|
+
results.errors.push(
|
|
30949
|
+
`Failed to insert office "${office.name}": ${error.message}`
|
|
30950
|
+
);
|
|
30951
|
+
import_nodejs_utils88.logger.log({
|
|
30952
|
+
level: "error",
|
|
30953
|
+
message: `Failed to insert office: ${error.message}`
|
|
30954
|
+
});
|
|
30955
|
+
}
|
|
30956
|
+
}
|
|
30957
|
+
}
|
|
30958
|
+
});
|
|
30959
|
+
delCachedData();
|
|
30960
|
+
import_nodejs_utils88.logger.log({
|
|
30961
|
+
level: "info",
|
|
30962
|
+
message: `Bulk upload completed. Successful: ${results.successful}, Failed: ${results.failed}`
|
|
30963
|
+
});
|
|
30964
|
+
return results;
|
|
30965
|
+
} catch (error) {
|
|
30966
|
+
import_nodejs_utils88.logger.log({
|
|
30967
|
+
level: "error",
|
|
30968
|
+
message: `Transaction failed: ${error.message}`
|
|
30969
|
+
});
|
|
30970
|
+
throw new import_nodejs_utils88.BadRequestError(`Bulk upload failed: ${error.message}`);
|
|
30971
|
+
} finally {
|
|
30972
|
+
await session.endSession();
|
|
30973
|
+
}
|
|
30974
|
+
} catch (error) {
|
|
30975
|
+
import_nodejs_utils88.logger.log({
|
|
30976
|
+
level: "error",
|
|
30977
|
+
message: `Bulk office upload failed: ${error.message}`
|
|
30978
|
+
});
|
|
30979
|
+
if (error instanceof import_nodejs_utils88.BadRequestError) {
|
|
30980
|
+
throw error;
|
|
30981
|
+
}
|
|
30982
|
+
throw new import_nodejs_utils88.BadRequestError(`File processing failed: ${error.message}`);
|
|
30983
|
+
}
|
|
30984
|
+
}
|
|
30985
|
+
return {
|
|
30986
|
+
addBulk
|
|
30987
|
+
};
|
|
30988
|
+
}
|
|
30989
|
+
|
|
30990
|
+
// src/controllers/office.controller.ts
|
|
30991
|
+
var import_nodejs_utils89 = require("@eeplatform/nodejs-utils");
|
|
30992
|
+
var import_joi44 = __toESM(require("joi"));
|
|
30993
|
+
function useOfficeController() {
|
|
30994
|
+
const {
|
|
30995
|
+
add: _add,
|
|
30996
|
+
getAll: _getAll,
|
|
30997
|
+
getById: _getById,
|
|
30998
|
+
updateById: _updateByIdById,
|
|
30999
|
+
deleteById: _deleteByIdById
|
|
31000
|
+
} = useOfficeRepo();
|
|
31001
|
+
const { addBulk: _addBulk } = useOfficeService();
|
|
31002
|
+
async function add(req, res, next) {
|
|
31003
|
+
const value = req.body;
|
|
31004
|
+
const validation = import_joi44.default.object({
|
|
31005
|
+
name: import_joi44.default.string().required(),
|
|
31006
|
+
code: import_joi44.default.string().required(),
|
|
31007
|
+
type: import_joi44.default.string().required(),
|
|
31008
|
+
path: import_joi44.default.string().required(),
|
|
31009
|
+
parent: import_joi44.default.string().hex().optional().allow(null, ""),
|
|
31010
|
+
status: import_joi44.default.string().optional().allow(null, "")
|
|
31011
|
+
});
|
|
31012
|
+
const { error } = validation.validate(value);
|
|
31013
|
+
if (error) {
|
|
31014
|
+
next(new import_nodejs_utils89.BadRequestError(error.message));
|
|
31015
|
+
return;
|
|
31016
|
+
}
|
|
31017
|
+
try {
|
|
31018
|
+
const id = await _add(value);
|
|
31019
|
+
res.json({ message: "Office created successfully", id });
|
|
31020
|
+
return;
|
|
31021
|
+
} catch (error2) {
|
|
31022
|
+
next(error2);
|
|
31023
|
+
}
|
|
31024
|
+
}
|
|
31025
|
+
async function getAll(req, res, next) {
|
|
31026
|
+
const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
|
|
31027
|
+
const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
|
|
31028
|
+
const search = req.query.search ?? "";
|
|
31029
|
+
const type = req.query.type ?? "";
|
|
31030
|
+
const parent = req.query.parent ?? "";
|
|
31031
|
+
const status = req.query.status ?? "active";
|
|
31032
|
+
const isPageNumber = isFinite(page);
|
|
31033
|
+
if (!isPageNumber) {
|
|
31034
|
+
next(new import_nodejs_utils89.BadRequestError("Invalid page number."));
|
|
31035
|
+
return;
|
|
31036
|
+
}
|
|
31037
|
+
const isLimitNumber = isFinite(limit);
|
|
31038
|
+
if (!isLimitNumber) {
|
|
31039
|
+
next(new import_nodejs_utils89.BadRequestError("Invalid limit number."));
|
|
31040
|
+
return;
|
|
31041
|
+
}
|
|
31042
|
+
const validation = import_joi44.default.object({
|
|
31043
|
+
page: import_joi44.default.number().min(1).optional().allow("", null),
|
|
31044
|
+
limit: import_joi44.default.number().min(1).optional().allow("", null),
|
|
31045
|
+
search: import_joi44.default.string().optional().allow("", null),
|
|
31046
|
+
type: import_joi44.default.string().optional().allow("", null),
|
|
31047
|
+
parent: import_joi44.default.string().optional().allow("", null),
|
|
31048
|
+
status: import_joi44.default.string().optional().allow("", null)
|
|
31049
|
+
});
|
|
31050
|
+
const { error } = validation.validate({
|
|
31051
|
+
page,
|
|
31052
|
+
limit,
|
|
31053
|
+
search,
|
|
31054
|
+
type,
|
|
31055
|
+
parent,
|
|
31056
|
+
status
|
|
31057
|
+
});
|
|
31058
|
+
if (error) {
|
|
31059
|
+
next(new import_nodejs_utils89.BadRequestError(error.message));
|
|
31060
|
+
return;
|
|
31061
|
+
}
|
|
31062
|
+
try {
|
|
31063
|
+
const offices = await _getAll({
|
|
31064
|
+
search,
|
|
31065
|
+
page,
|
|
31066
|
+
limit,
|
|
31067
|
+
type,
|
|
31068
|
+
parent,
|
|
31069
|
+
status
|
|
31070
|
+
});
|
|
31071
|
+
res.json(offices);
|
|
31072
|
+
return;
|
|
31073
|
+
} catch (error2) {
|
|
31074
|
+
next(error2);
|
|
31075
|
+
}
|
|
31076
|
+
}
|
|
31077
|
+
async function getById(req, res, next) {
|
|
31078
|
+
const id = req.params.id;
|
|
31079
|
+
const validation = import_joi44.default.object({
|
|
31080
|
+
id: import_joi44.default.string().hex().required()
|
|
31081
|
+
});
|
|
31082
|
+
const { error } = validation.validate({ id });
|
|
31083
|
+
if (error) {
|
|
31084
|
+
next(new import_nodejs_utils89.BadRequestError(error.message));
|
|
31085
|
+
return;
|
|
31086
|
+
}
|
|
31087
|
+
try {
|
|
31088
|
+
const office = await _getById(id);
|
|
31089
|
+
if (!office) {
|
|
31090
|
+
next(new import_nodejs_utils89.BadRequestError("Office not found."));
|
|
31091
|
+
return;
|
|
31092
|
+
}
|
|
31093
|
+
res.json(office);
|
|
31094
|
+
return;
|
|
31095
|
+
} catch (error2) {
|
|
31096
|
+
next(error2);
|
|
31097
|
+
}
|
|
31098
|
+
}
|
|
31099
|
+
async function updateById(req, res, next) {
|
|
31100
|
+
const id = req.params.id;
|
|
31101
|
+
const value = req.body;
|
|
31102
|
+
const validation = import_joi44.default.object({
|
|
31103
|
+
id: import_joi44.default.string().hex().required(),
|
|
31104
|
+
name: import_joi44.default.string().optional(),
|
|
31105
|
+
code: import_joi44.default.string().optional(),
|
|
31106
|
+
type: import_joi44.default.string().optional(),
|
|
31107
|
+
parent: import_joi44.default.string().hex().optional().allow(null, ""),
|
|
31108
|
+
path: import_joi44.default.string().optional(),
|
|
31109
|
+
status: import_joi44.default.string().optional()
|
|
31110
|
+
});
|
|
31111
|
+
const { error } = validation.validate({ id, ...value });
|
|
31112
|
+
if (error) {
|
|
31113
|
+
next(new import_nodejs_utils89.BadRequestError(error.message));
|
|
31114
|
+
return;
|
|
31115
|
+
}
|
|
31116
|
+
try {
|
|
31117
|
+
const result = await _updateByIdById(id, value);
|
|
31118
|
+
if (result.matchedCount === 0) {
|
|
31119
|
+
next(new import_nodejs_utils89.BadRequestError("Office not found."));
|
|
31120
|
+
return;
|
|
31121
|
+
}
|
|
31122
|
+
res.json({ message: "Office updated successfully" });
|
|
31123
|
+
return;
|
|
31124
|
+
} catch (error2) {
|
|
31125
|
+
next(error2);
|
|
31126
|
+
}
|
|
31127
|
+
}
|
|
31128
|
+
async function deleteById(req, res, next) {
|
|
31129
|
+
const id = req.params.id;
|
|
31130
|
+
const validation = import_joi44.default.object({
|
|
31131
|
+
id: import_joi44.default.string().hex().required()
|
|
31132
|
+
});
|
|
31133
|
+
const { error } = validation.validate({ id });
|
|
31134
|
+
if (error) {
|
|
31135
|
+
next(new import_nodejs_utils89.BadRequestError(error.message));
|
|
31136
|
+
return;
|
|
31137
|
+
}
|
|
31138
|
+
try {
|
|
31139
|
+
const result = await _deleteByIdById(id);
|
|
31140
|
+
if (result.matchedCount === 0) {
|
|
31141
|
+
next(new import_nodejs_utils89.BadRequestError("Office not found."));
|
|
31142
|
+
return;
|
|
31143
|
+
}
|
|
31144
|
+
res.json({ message: "Office deleted successfully" });
|
|
31145
|
+
return;
|
|
31146
|
+
} catch (error2) {
|
|
31147
|
+
next(error2);
|
|
31148
|
+
}
|
|
31149
|
+
}
|
|
31150
|
+
async function bulkAddOffices(req, res, next) {
|
|
31151
|
+
if (!req.file) {
|
|
31152
|
+
res.status(400).send("File is required!");
|
|
31153
|
+
return;
|
|
31154
|
+
}
|
|
31155
|
+
try {
|
|
31156
|
+
const result = await _addBulk(req.file);
|
|
31157
|
+
res.status(201).json(result);
|
|
31158
|
+
return;
|
|
31159
|
+
} catch (error) {
|
|
31160
|
+
next(error);
|
|
31161
|
+
return;
|
|
31162
|
+
}
|
|
31163
|
+
}
|
|
31164
|
+
return {
|
|
31165
|
+
add,
|
|
31166
|
+
getAll,
|
|
31167
|
+
getById,
|
|
31168
|
+
updateById,
|
|
31169
|
+
deleteById,
|
|
31170
|
+
bulkAddOffices
|
|
31171
|
+
};
|
|
31172
|
+
}
|
|
31173
|
+
|
|
31174
|
+
// src/models/curriculum.model.ts
|
|
31175
|
+
var import_nodejs_utils90 = require("@eeplatform/nodejs-utils");
|
|
31176
|
+
var import_joi45 = __toESM(require("joi"));
|
|
31177
|
+
var import_mongodb50 = require("mongodb");
|
|
31178
|
+
var schemaCurriculum = import_joi45.default.object({
|
|
31179
|
+
_id: import_joi45.default.string().hex().optional(),
|
|
31180
|
+
school: import_joi45.default.string().hex().required(),
|
|
31181
|
+
code: import_joi45.default.string().required(),
|
|
31182
|
+
educationLevel: import_joi45.default.string().required(),
|
|
31183
|
+
gradeLevel: import_joi45.default.string().required(),
|
|
31184
|
+
subjectCode: import_joi45.default.string().required(),
|
|
31185
|
+
subjectName: import_joi45.default.string().required(),
|
|
31186
|
+
subjectType: import_joi45.default.string().required(),
|
|
31187
|
+
sessionFrequency: import_joi45.default.number().integer().min(0).required(),
|
|
31188
|
+
sessionDuration: import_joi45.default.number().integer().min(0).required(),
|
|
31189
|
+
totalMinutesPerWeek: import_joi45.default.number().integer().min(0).required(),
|
|
31190
|
+
curriculumMemoRef: import_joi45.default.string().optional().allow("", null),
|
|
31191
|
+
status: import_joi45.default.string().optional().allow("", null),
|
|
31192
|
+
createdAt: import_joi45.default.date().optional().allow("", null),
|
|
31193
|
+
updatedAt: import_joi45.default.date().optional().allow("", null),
|
|
31194
|
+
deletedAt: import_joi45.default.date().optional().allow("", null),
|
|
31195
|
+
createdBy: import_joi45.default.string().optional().allow("", null),
|
|
31196
|
+
updatedBy: import_joi45.default.string().optional().allow("", null),
|
|
31197
|
+
deletedBy: import_joi45.default.string().optional().allow("", null)
|
|
31198
|
+
});
|
|
31199
|
+
function MCurriculum(value) {
|
|
31200
|
+
const { error } = schemaCurriculum.validate(value);
|
|
31201
|
+
if (error) {
|
|
31202
|
+
import_nodejs_utils90.logger.info(`Curriculum Model: ${error.message}`);
|
|
31203
|
+
throw new import_nodejs_utils90.BadRequestError(error.message);
|
|
31204
|
+
}
|
|
31205
|
+
if (value._id && typeof value._id === "string") {
|
|
31206
|
+
try {
|
|
31207
|
+
value._id = new import_mongodb50.ObjectId(value._id);
|
|
31208
|
+
} catch (error2) {
|
|
31209
|
+
throw new import_nodejs_utils90.BadRequestError("Invalid _id format");
|
|
31210
|
+
}
|
|
31211
|
+
}
|
|
31212
|
+
return {
|
|
31213
|
+
_id: value._id ?? void 0,
|
|
31214
|
+
school: value.school ?? "",
|
|
31215
|
+
code: value.code ?? "",
|
|
31216
|
+
educationLevel: value.educationLevel ?? "",
|
|
31217
|
+
gradeLevel: value.gradeLevel ?? "",
|
|
31218
|
+
subjectCode: value.subjectCode ?? "",
|
|
31219
|
+
subjectName: value.subjectName ?? "",
|
|
31220
|
+
subjectType: value.subjectType ?? "",
|
|
31221
|
+
sessionFrequency: value.sessionFrequency ?? 0,
|
|
31222
|
+
sessionDuration: value.sessionDuration ?? 0,
|
|
31223
|
+
totalMinutesPerWeek: value.totalMinutesPerWeek ?? 0,
|
|
31224
|
+
curriculumMemoRef: value.curriculumMemoRef ?? "",
|
|
31225
|
+
status: value.status ?? "active",
|
|
31226
|
+
createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
|
|
31227
|
+
updatedAt: value.updatedAt ?? "",
|
|
31228
|
+
deletedAt: value.deletedAt ?? "",
|
|
31229
|
+
createdBy: value.createdBy ?? "",
|
|
31230
|
+
updatedBy: value.updatedBy ?? "",
|
|
31231
|
+
deletedBy: value.deletedBy ?? ""
|
|
31232
|
+
};
|
|
31233
|
+
}
|
|
31234
|
+
|
|
31235
|
+
// src/repositories/curriculum.repository.ts
|
|
31236
|
+
var import_nodejs_utils91 = require("@eeplatform/nodejs-utils");
|
|
31237
|
+
var import_mongodb51 = require("mongodb");
|
|
31238
|
+
function useCurriculumRepo() {
|
|
31239
|
+
const db = import_nodejs_utils91.useAtlas.getDb();
|
|
31240
|
+
if (!db) {
|
|
31241
|
+
throw new Error("Unable to connect to server.");
|
|
31242
|
+
}
|
|
31243
|
+
const namespace_collection = "school.curriculums";
|
|
31244
|
+
const collection = db.collection(namespace_collection);
|
|
31245
|
+
const { getCache, setCache, delNamespace } = (0, import_nodejs_utils91.useCache)(namespace_collection);
|
|
31246
|
+
async function createIndexes() {
|
|
31247
|
+
try {
|
|
31248
|
+
await collection.createIndexes([
|
|
31249
|
+
{ key: { code: 1 }, unique: true, name: "unique_code_index" },
|
|
31250
|
+
{ key: { educationLevel: 1 } },
|
|
31251
|
+
{ key: { gradeLevel: 1 } },
|
|
31252
|
+
{ key: { subjectCode: 1 } },
|
|
31253
|
+
{ key: { status: 1 } }
|
|
31254
|
+
]);
|
|
31255
|
+
} catch (error) {
|
|
31256
|
+
throw new Error("Failed to create index on curriculums.");
|
|
31257
|
+
}
|
|
31258
|
+
}
|
|
31259
|
+
async function add(value, session) {
|
|
31260
|
+
try {
|
|
31261
|
+
value = MCurriculum(value);
|
|
31262
|
+
const res = await collection.insertOne(value, { session });
|
|
31263
|
+
delCachedData();
|
|
31264
|
+
return res.insertedId;
|
|
31265
|
+
} catch (error) {
|
|
31266
|
+
import_nodejs_utils91.logger.log({
|
|
31267
|
+
level: "error",
|
|
31268
|
+
message: error.message
|
|
31269
|
+
});
|
|
31270
|
+
if (error instanceof import_nodejs_utils91.AppError) {
|
|
31271
|
+
throw error;
|
|
31272
|
+
} else {
|
|
31273
|
+
const isDuplicated = error.message.includes("duplicate");
|
|
31274
|
+
if (isDuplicated) {
|
|
31275
|
+
throw new import_nodejs_utils91.BadRequestError("Curriculum already exists.");
|
|
31276
|
+
}
|
|
31277
|
+
throw new Error("Failed to create curriculum.");
|
|
31278
|
+
}
|
|
31279
|
+
}
|
|
31280
|
+
}
|
|
31281
|
+
async function updateById(_id, value, session) {
|
|
31282
|
+
try {
|
|
31283
|
+
_id = new import_mongodb51.ObjectId(_id);
|
|
31284
|
+
} catch (error) {
|
|
31285
|
+
throw new import_nodejs_utils91.BadRequestError("Invalid ID.");
|
|
31286
|
+
}
|
|
31287
|
+
try {
|
|
31288
|
+
const res = await collection.updateOne(
|
|
31289
|
+
{ _id },
|
|
31290
|
+
{ $set: { ...value, updatedAt: /* @__PURE__ */ new Date() } },
|
|
31291
|
+
{ session }
|
|
31292
|
+
);
|
|
31293
|
+
delCachedData();
|
|
31294
|
+
return res;
|
|
31295
|
+
} catch (error) {
|
|
31296
|
+
import_nodejs_utils91.logger.log({
|
|
31297
|
+
level: "error",
|
|
31298
|
+
message: error.message
|
|
31299
|
+
});
|
|
31300
|
+
if (error instanceof import_nodejs_utils91.AppError) {
|
|
31301
|
+
throw error;
|
|
31302
|
+
} else {
|
|
31303
|
+
throw new Error("Failed to update curriculum.");
|
|
31304
|
+
}
|
|
31305
|
+
}
|
|
31306
|
+
}
|
|
31307
|
+
async function getAll({
|
|
31308
|
+
search = "",
|
|
31309
|
+
page = 1,
|
|
31310
|
+
limit = 10,
|
|
31311
|
+
sort = {},
|
|
31312
|
+
educationLevel = "",
|
|
31313
|
+
gradeLevel = "",
|
|
31314
|
+
subjectCode = "",
|
|
31315
|
+
status = "active"
|
|
31316
|
+
} = {}) {
|
|
31317
|
+
page = page > 0 ? page - 1 : 0;
|
|
31318
|
+
const query = {
|
|
31319
|
+
status
|
|
31320
|
+
};
|
|
31321
|
+
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
31322
|
+
if (search) {
|
|
31323
|
+
query.$or = [
|
|
31324
|
+
{ code: { $regex: search, $options: "i" } },
|
|
31325
|
+
{ subjectName: { $regex: search, $options: "i" } },
|
|
31326
|
+
{ subjectCode: { $regex: search, $options: "i" } }
|
|
31327
|
+
];
|
|
31328
|
+
}
|
|
31329
|
+
if (educationLevel) {
|
|
31330
|
+
query.educationLevel = educationLevel;
|
|
31331
|
+
}
|
|
31332
|
+
if (gradeLevel) {
|
|
31333
|
+
query.gradeLevel = gradeLevel;
|
|
31334
|
+
}
|
|
31335
|
+
if (subjectCode) {
|
|
31336
|
+
query.subjectCode = subjectCode;
|
|
31337
|
+
}
|
|
31338
|
+
const cacheParams = {
|
|
31339
|
+
page,
|
|
31340
|
+
limit,
|
|
31341
|
+
sort: JSON.stringify(sort)
|
|
31342
|
+
};
|
|
31343
|
+
if (search)
|
|
31344
|
+
cacheParams.search = search;
|
|
31345
|
+
if (educationLevel)
|
|
31346
|
+
cacheParams.educationLevel = educationLevel;
|
|
31347
|
+
if (gradeLevel)
|
|
31348
|
+
cacheParams.gradeLevel = gradeLevel;
|
|
31349
|
+
if (subjectCode)
|
|
31350
|
+
cacheParams.subjectCode = subjectCode;
|
|
31351
|
+
if (status !== "active")
|
|
31352
|
+
cacheParams.status = status;
|
|
31353
|
+
const cacheKey = (0, import_nodejs_utils91.makeCacheKey)(namespace_collection, cacheParams);
|
|
31354
|
+
import_nodejs_utils91.logger.log({
|
|
31355
|
+
level: "info",
|
|
31356
|
+
message: `Cache key for getAll curriculums: ${cacheKey}`
|
|
31357
|
+
});
|
|
31358
|
+
try {
|
|
31359
|
+
const cached = await getCache(cacheKey);
|
|
31360
|
+
if (cached) {
|
|
31361
|
+
import_nodejs_utils91.logger.log({
|
|
31362
|
+
level: "info",
|
|
31363
|
+
message: `Cache hit for getAll curriculums: ${cacheKey}`
|
|
31364
|
+
});
|
|
31365
|
+
return cached;
|
|
31366
|
+
}
|
|
31367
|
+
const items = await collection.aggregate([
|
|
31368
|
+
{ $match: query },
|
|
31369
|
+
{ $sort: sort },
|
|
31370
|
+
{ $skip: page * limit },
|
|
31371
|
+
{ $limit: limit }
|
|
31372
|
+
]).toArray();
|
|
31373
|
+
const length = await collection.countDocuments(query);
|
|
31374
|
+
const data = (0, import_nodejs_utils91.paginate)(items, page, limit, length);
|
|
31375
|
+
setCache(cacheKey, data, 600).then(() => {
|
|
31376
|
+
import_nodejs_utils91.logger.log({
|
|
31377
|
+
level: "info",
|
|
31378
|
+
message: `Cache set for getAll curriculums: ${cacheKey}`
|
|
31379
|
+
});
|
|
31380
|
+
}).catch((err) => {
|
|
31381
|
+
import_nodejs_utils91.logger.log({
|
|
31382
|
+
level: "error",
|
|
31383
|
+
message: `Failed to set cache for getAll curriculums: ${err.message}`
|
|
31384
|
+
});
|
|
31385
|
+
});
|
|
31386
|
+
return data;
|
|
31387
|
+
} catch (error) {
|
|
31388
|
+
import_nodejs_utils91.logger.log({ level: "error", message: `${error}` });
|
|
31389
|
+
throw error;
|
|
31390
|
+
}
|
|
31391
|
+
}
|
|
31392
|
+
async function getById(_id) {
|
|
31393
|
+
try {
|
|
31394
|
+
_id = new import_mongodb51.ObjectId(_id);
|
|
31395
|
+
} catch (error) {
|
|
31396
|
+
throw new import_nodejs_utils91.BadRequestError("Invalid ID.");
|
|
31397
|
+
}
|
|
31398
|
+
const cacheKey = (0, import_nodejs_utils91.makeCacheKey)(namespace_collection, { _id: String(_id) });
|
|
31399
|
+
try {
|
|
31400
|
+
const cached = await getCache(cacheKey);
|
|
31401
|
+
if (cached) {
|
|
31402
|
+
import_nodejs_utils91.logger.log({
|
|
31403
|
+
level: "info",
|
|
31404
|
+
message: `Cache hit for getById curriculum: ${cacheKey}`
|
|
31405
|
+
});
|
|
31406
|
+
return cached;
|
|
31407
|
+
}
|
|
31408
|
+
const result = await collection.findOne({
|
|
31409
|
+
_id
|
|
31410
|
+
});
|
|
31411
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
31412
|
+
import_nodejs_utils91.logger.log({
|
|
31413
|
+
level: "info",
|
|
31414
|
+
message: `Cache set for curriculum by id: ${cacheKey}`
|
|
31415
|
+
});
|
|
31416
|
+
}).catch((err) => {
|
|
31417
|
+
import_nodejs_utils91.logger.log({
|
|
31418
|
+
level: "error",
|
|
31419
|
+
message: `Failed to set cache for curriculum by id: ${err.message}`
|
|
31420
|
+
});
|
|
31421
|
+
});
|
|
31422
|
+
return result;
|
|
31423
|
+
} catch (error) {
|
|
31424
|
+
if (error instanceof import_nodejs_utils91.AppError) {
|
|
31425
|
+
throw error;
|
|
31426
|
+
} else {
|
|
31427
|
+
throw new import_nodejs_utils91.InternalServerError("Failed to get curriculum.");
|
|
31428
|
+
}
|
|
31429
|
+
}
|
|
31430
|
+
}
|
|
31431
|
+
async function deleteById(_id, session) {
|
|
31432
|
+
try {
|
|
31433
|
+
_id = new import_mongodb51.ObjectId(_id);
|
|
31434
|
+
} catch (error) {
|
|
31435
|
+
throw new import_nodejs_utils91.BadRequestError("Invalid ID.");
|
|
31436
|
+
}
|
|
31437
|
+
try {
|
|
31438
|
+
const res = await collection.updateOne(
|
|
31439
|
+
{ _id },
|
|
31440
|
+
{ $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } }
|
|
31441
|
+
);
|
|
31442
|
+
delCachedData();
|
|
31443
|
+
return res;
|
|
31444
|
+
} catch (error) {
|
|
31445
|
+
import_nodejs_utils91.logger.log({
|
|
31446
|
+
level: "error",
|
|
31447
|
+
message: error.message
|
|
31448
|
+
});
|
|
31449
|
+
if (error instanceof import_nodejs_utils91.AppError) {
|
|
31450
|
+
throw error;
|
|
31451
|
+
} else {
|
|
31452
|
+
throw new import_nodejs_utils91.InternalServerError("Failed to delete curriculum.");
|
|
31453
|
+
}
|
|
31454
|
+
}
|
|
31455
|
+
}
|
|
31456
|
+
function delCachedData() {
|
|
31457
|
+
delNamespace().then(() => {
|
|
31458
|
+
import_nodejs_utils91.logger.log({
|
|
31459
|
+
level: "info",
|
|
31460
|
+
message: `Cache namespace cleared for ${namespace_collection}`
|
|
31461
|
+
});
|
|
31462
|
+
}).catch((err) => {
|
|
31463
|
+
import_nodejs_utils91.logger.log({
|
|
31464
|
+
level: "error",
|
|
31465
|
+
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
31466
|
+
});
|
|
31467
|
+
});
|
|
31468
|
+
}
|
|
31469
|
+
return {
|
|
31470
|
+
createIndexes,
|
|
31471
|
+
add,
|
|
31472
|
+
getAll,
|
|
31473
|
+
getById,
|
|
31474
|
+
updateById,
|
|
31475
|
+
deleteById
|
|
31476
|
+
};
|
|
31477
|
+
}
|
|
31478
|
+
|
|
31479
|
+
// src/controllers/curriculum.controller.ts
|
|
31480
|
+
var import_nodejs_utils92 = require("@eeplatform/nodejs-utils");
|
|
31481
|
+
var import_joi46 = __toESM(require("joi"));
|
|
31482
|
+
function useCurriculumController() {
|
|
31483
|
+
const {
|
|
31484
|
+
getAll: _getAll,
|
|
31485
|
+
getById: _getById,
|
|
31486
|
+
add: _add,
|
|
31487
|
+
updateById: _updateById,
|
|
31488
|
+
deleteById: _deleteById
|
|
31489
|
+
} = useCurriculumRepo();
|
|
31490
|
+
async function add(req, res, next) {
|
|
31491
|
+
const value = req.body;
|
|
31492
|
+
const validation = import_joi46.default.object({
|
|
31493
|
+
code: import_joi46.default.string().required(),
|
|
31494
|
+
school: import_joi46.default.string().hex().required(),
|
|
31495
|
+
educationLevel: import_joi46.default.string().required(),
|
|
31496
|
+
gradeLevel: import_joi46.default.string().required(),
|
|
31497
|
+
subjectCode: import_joi46.default.string().required(),
|
|
31498
|
+
subjectName: import_joi46.default.string().required(),
|
|
31499
|
+
subjectType: import_joi46.default.string().required(),
|
|
31500
|
+
sessionFrequency: import_joi46.default.number().integer().min(0).required(),
|
|
31501
|
+
sessionDuration: import_joi46.default.number().integer().min(0).required(),
|
|
31502
|
+
totalMinutesPerWeek: import_joi46.default.number().integer().min(0).required(),
|
|
31503
|
+
curriculumMemoRef: import_joi46.default.string().optional().allow("", null),
|
|
31504
|
+
status: import_joi46.default.string().optional().allow("", null)
|
|
31505
|
+
});
|
|
31506
|
+
const { error } = validation.validate(value);
|
|
31507
|
+
if (error) {
|
|
31508
|
+
next(new import_nodejs_utils92.BadRequestError(error.message));
|
|
31509
|
+
import_nodejs_utils92.logger.info(`Controller: ${error.message}`);
|
|
31510
|
+
return;
|
|
31511
|
+
}
|
|
31512
|
+
try {
|
|
31513
|
+
const result = await _add(value);
|
|
31514
|
+
res.json(result);
|
|
31515
|
+
return;
|
|
31516
|
+
} catch (error2) {
|
|
31517
|
+
next(error2);
|
|
31518
|
+
}
|
|
31519
|
+
}
|
|
31520
|
+
async function updateById(req, res, next) {
|
|
31521
|
+
const value = req.body;
|
|
31522
|
+
const id = req.params.id ?? "";
|
|
31523
|
+
const validation = import_joi46.default.object({
|
|
31524
|
+
id: import_joi46.default.string().hex().required(),
|
|
31525
|
+
value: import_joi46.default.object({
|
|
31526
|
+
code: import_joi46.default.string().optional(),
|
|
31527
|
+
educationLevel: import_joi46.default.string().optional(),
|
|
31528
|
+
gradeLevel: import_joi46.default.string().optional(),
|
|
31529
|
+
subjectCode: import_joi46.default.string().optional(),
|
|
31530
|
+
subjectName: import_joi46.default.string().optional(),
|
|
31531
|
+
subjectType: import_joi46.default.string().optional(),
|
|
31532
|
+
sessionFrequency: import_joi46.default.number().integer().min(0).optional(),
|
|
31533
|
+
sessionDuration: import_joi46.default.number().integer().min(0).optional(),
|
|
31534
|
+
totalMinutesPerWeek: import_joi46.default.number().integer().min(0).optional(),
|
|
31535
|
+
curriculumMemoRef: import_joi46.default.string().optional().allow("", null)
|
|
31536
|
+
}).min(1)
|
|
31537
|
+
});
|
|
31538
|
+
const { error } = validation.validate({ id, value });
|
|
31539
|
+
if (error) {
|
|
31540
|
+
next(new import_nodejs_utils92.BadRequestError(error.message));
|
|
31541
|
+
import_nodejs_utils92.logger.info(`Controller: ${error.message}`);
|
|
31542
|
+
return;
|
|
31543
|
+
}
|
|
31544
|
+
try {
|
|
31545
|
+
const result = await _updateById(id, value);
|
|
31546
|
+
res.json(result);
|
|
31547
|
+
return;
|
|
31548
|
+
} catch (error2) {
|
|
31549
|
+
next(error2);
|
|
31550
|
+
}
|
|
31551
|
+
}
|
|
31552
|
+
async function getAll(req, res, next) {
|
|
31553
|
+
const query = req.query;
|
|
31554
|
+
const validation = import_joi46.default.object({
|
|
31555
|
+
page: import_joi46.default.number().min(1).optional().allow("", null),
|
|
31556
|
+
limit: import_joi46.default.number().min(1).optional().allow("", null),
|
|
31557
|
+
search: import_joi46.default.string().optional().allow("", null),
|
|
31558
|
+
educationLevel: import_joi46.default.string().optional().allow("", null),
|
|
31559
|
+
gradeLevel: import_joi46.default.string().optional().allow("", null),
|
|
31560
|
+
subjectCode: import_joi46.default.string().optional().allow("", null),
|
|
31561
|
+
status: import_joi46.default.string().optional().allow("", null)
|
|
31562
|
+
});
|
|
31563
|
+
const { error } = validation.validate(query);
|
|
31564
|
+
if (error) {
|
|
31565
|
+
next(new import_nodejs_utils92.BadRequestError(error.message));
|
|
31566
|
+
return;
|
|
31567
|
+
}
|
|
31568
|
+
const page = parseInt(req.query.page) ?? 1;
|
|
31569
|
+
let limit = parseInt(req.query.limit) ?? 20;
|
|
31570
|
+
limit = isNaN(limit) ? 20 : limit;
|
|
31571
|
+
const sort = req.query.sort ? String(req.query.sort).split(",") : "";
|
|
31572
|
+
const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
|
|
31573
|
+
const sortObj = {};
|
|
31574
|
+
if (sort && Array.isArray(sort) && sort.length && sortOrder && Array.isArray(sortOrder) && sortOrder.length) {
|
|
31575
|
+
sort.forEach((field, index) => {
|
|
31576
|
+
sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
|
|
31577
|
+
});
|
|
31578
|
+
}
|
|
31579
|
+
const status = req.query.status ?? "active";
|
|
31580
|
+
const educationLevel = req.query.educationLevel ?? "";
|
|
31581
|
+
const gradeLevel = req.query.gradeLevel ?? "";
|
|
31582
|
+
const subjectCode = req.query.subjectCode ?? "";
|
|
31583
|
+
const search = req.query.search ?? "";
|
|
31584
|
+
try {
|
|
31585
|
+
const curriculums = await _getAll({
|
|
31586
|
+
page,
|
|
31587
|
+
limit,
|
|
31588
|
+
sort: sortObj,
|
|
31589
|
+
status,
|
|
31590
|
+
educationLevel,
|
|
31591
|
+
gradeLevel,
|
|
31592
|
+
subjectCode,
|
|
31593
|
+
search
|
|
31594
|
+
});
|
|
31595
|
+
res.json(curriculums);
|
|
31596
|
+
return;
|
|
31597
|
+
} catch (error2) {
|
|
31598
|
+
next(error2);
|
|
31599
|
+
}
|
|
31600
|
+
}
|
|
31601
|
+
async function getById(req, res, next) {
|
|
31602
|
+
const id = req.params.id;
|
|
31603
|
+
const validation = import_joi46.default.object({
|
|
31604
|
+
id: import_joi46.default.string().hex().required()
|
|
31605
|
+
});
|
|
31606
|
+
const { error } = validation.validate({ id });
|
|
31607
|
+
if (error) {
|
|
31608
|
+
next(new import_nodejs_utils92.BadRequestError(error.message));
|
|
31609
|
+
return;
|
|
31610
|
+
}
|
|
31611
|
+
try {
|
|
31612
|
+
const curriculum = await _getById(id);
|
|
31613
|
+
res.json({
|
|
31614
|
+
message: "Successfully retrieved curriculum.",
|
|
31615
|
+
data: { curriculum }
|
|
31616
|
+
});
|
|
31617
|
+
return;
|
|
31618
|
+
} catch (error2) {
|
|
31619
|
+
next(error2);
|
|
31620
|
+
}
|
|
31621
|
+
}
|
|
31622
|
+
async function deleteById(req, res, next) {
|
|
31623
|
+
const id = req.params.id;
|
|
31624
|
+
const validation = import_joi46.default.object({
|
|
31625
|
+
id: import_joi46.default.string().hex().required()
|
|
31626
|
+
});
|
|
31627
|
+
const { error } = validation.validate({ id });
|
|
31628
|
+
if (error) {
|
|
31629
|
+
next(new import_nodejs_utils92.BadRequestError(error.message));
|
|
31630
|
+
return;
|
|
31631
|
+
}
|
|
31632
|
+
try {
|
|
31633
|
+
const result = await _deleteById(id);
|
|
31634
|
+
res.json({
|
|
31635
|
+
message: "Successfully deleted curriculum.",
|
|
31636
|
+
data: result
|
|
31637
|
+
});
|
|
31638
|
+
return;
|
|
31639
|
+
} catch (error2) {
|
|
31640
|
+
next(error2);
|
|
31641
|
+
}
|
|
31642
|
+
}
|
|
31643
|
+
return {
|
|
31644
|
+
add,
|
|
31645
|
+
getAll,
|
|
31646
|
+
getById,
|
|
31647
|
+
updateById,
|
|
31648
|
+
deleteById
|
|
31649
|
+
};
|
|
31650
|
+
}
|
|
30504
31651
|
// Annotate the CommonJS export names for ESM import in node:
|
|
30505
31652
|
0 && (module.exports = {
|
|
30506
31653
|
ACCESS_TOKEN_EXPIRY,
|
|
@@ -30523,12 +31670,14 @@ function usePlantillaController() {
|
|
|
30523
31670
|
MAsset,
|
|
30524
31671
|
MBuilding,
|
|
30525
31672
|
MBuildingUnit,
|
|
31673
|
+
MCurriculum,
|
|
30526
31674
|
MDivision,
|
|
30527
31675
|
MEntity,
|
|
30528
31676
|
MFile,
|
|
30529
31677
|
MMember,
|
|
30530
31678
|
MONGO_DB,
|
|
30531
31679
|
MONGO_URI,
|
|
31680
|
+
MOffice,
|
|
30532
31681
|
MOrder,
|
|
30533
31682
|
MOrg,
|
|
30534
31683
|
MPaymentMethod,
|
|
@@ -30569,7 +31718,9 @@ function usePlantillaController() {
|
|
|
30569
31718
|
schemaAssetUpdateOption,
|
|
30570
31719
|
schemaBuilding,
|
|
30571
31720
|
schemaBuildingUnit,
|
|
31721
|
+
schemaCurriculum,
|
|
30572
31722
|
schemaDivision,
|
|
31723
|
+
schemaOffice,
|
|
30573
31724
|
schemaPlantilla,
|
|
30574
31725
|
schemaRegion,
|
|
30575
31726
|
schemaSchool,
|
|
@@ -30587,6 +31738,8 @@ function usePlantillaController() {
|
|
|
30587
31738
|
useBuildingUnitRepo,
|
|
30588
31739
|
useCounterModel,
|
|
30589
31740
|
useCounterRepo,
|
|
31741
|
+
useCurriculumController,
|
|
31742
|
+
useCurriculumRepo,
|
|
30590
31743
|
useDivisionController,
|
|
30591
31744
|
useDivisionRepo,
|
|
30592
31745
|
useDivisionService,
|
|
@@ -30602,6 +31755,9 @@ function usePlantillaController() {
|
|
|
30602
31755
|
useInvoiceService,
|
|
30603
31756
|
useMemberController,
|
|
30604
31757
|
useMemberRepo,
|
|
31758
|
+
useOfficeController,
|
|
31759
|
+
useOfficeRepo,
|
|
31760
|
+
useOfficeService,
|
|
30605
31761
|
useOrderController,
|
|
30606
31762
|
useOrderRepo,
|
|
30607
31763
|
useOrgController,
|