@eeplatform/basic-edu 1.5.2 → 1.6.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 +302 -1
- package/dist/index.js +2782 -200
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2804 -203
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1344,10 +1344,13 @@ var require_papaparse = __commonJS({
|
|
|
1344
1344
|
var src_exports = {};
|
|
1345
1345
|
__export(src_exports, {
|
|
1346
1346
|
MAsset: () => MAsset,
|
|
1347
|
+
MBuilding: () => MBuilding,
|
|
1348
|
+
MBuildingUnit: () => MBuildingUnit,
|
|
1347
1349
|
MCurriculum: () => MCurriculum,
|
|
1348
1350
|
MCurriculumSubject: () => MCurriculumSubject,
|
|
1349
1351
|
MGradeLevel: () => MGradeLevel,
|
|
1350
1352
|
MLearner: () => MLearner,
|
|
1353
|
+
MPersonnel: () => MPersonnel,
|
|
1351
1354
|
MPlantilla: () => MPlantilla,
|
|
1352
1355
|
MStockCard: () => MStockCard,
|
|
1353
1356
|
allowedSectionStudentStatuses: () => allowedSectionStudentStatuses,
|
|
@@ -1358,9 +1361,12 @@ __export(src_exports, {
|
|
|
1358
1361
|
modelSection: () => modelSection,
|
|
1359
1362
|
modelSectionPreset: () => modelSectionPreset,
|
|
1360
1363
|
modelSectionStudent: () => modelSectionStudent,
|
|
1364
|
+
modelSectionSubject: () => modelSectionSubject,
|
|
1361
1365
|
schemaAsset: () => schemaAsset,
|
|
1362
1366
|
schemaAssetUpdateOption: () => schemaAssetUpdateOption,
|
|
1363
1367
|
schemaBasicEduCount: () => schemaBasicEduCount,
|
|
1368
|
+
schemaBuilding: () => schemaBuilding,
|
|
1369
|
+
schemaBuildingUnit: () => schemaBuildingUnit,
|
|
1364
1370
|
schemaCurriculum: () => schemaCurriculum,
|
|
1365
1371
|
schemaCurriculumSubject: () => schemaCurriculumSubject,
|
|
1366
1372
|
schemaCurriculumSubjectAdd: () => schemaCurriculumSubjectAdd,
|
|
@@ -1369,6 +1375,7 @@ __export(src_exports, {
|
|
|
1369
1375
|
schemaEnrollment: () => schemaEnrollment,
|
|
1370
1376
|
schemaGenerateSections: () => schemaGenerateSections,
|
|
1371
1377
|
schemaGradeLevel: () => schemaGradeLevel,
|
|
1378
|
+
schemaPersonnel: () => schemaPersonnel,
|
|
1372
1379
|
schemaPlantilla: () => schemaPlantilla,
|
|
1373
1380
|
schemaRegion: () => schemaRegion,
|
|
1374
1381
|
schemaSchool: () => schemaSchool,
|
|
@@ -1376,11 +1383,20 @@ __export(src_exports, {
|
|
|
1376
1383
|
schemaSection: () => schemaSection,
|
|
1377
1384
|
schemaSectionPreset: () => schemaSectionPreset,
|
|
1378
1385
|
schemaSectionStudent: () => schemaSectionStudent,
|
|
1386
|
+
schemaSectionSubject: () => schemaSectionSubject,
|
|
1387
|
+
schemaSectionSubjectSetup: () => schemaSectionSubjectSetup,
|
|
1379
1388
|
schemaStockCard: () => schemaStockCard,
|
|
1389
|
+
schemaUpdateOptions: () => schemaUpdateOptions,
|
|
1380
1390
|
schemaUpdateStatus: () => schemaUpdateStatus,
|
|
1381
1391
|
useAssetController: () => useAssetController,
|
|
1382
1392
|
useAssetRepo: () => useAssetRepo,
|
|
1383
1393
|
useBasicEduCountRepo: () => useBasicEduCountRepo,
|
|
1394
|
+
useBuildingController: () => useBuildingController,
|
|
1395
|
+
useBuildingRepo: () => useBuildingRepo,
|
|
1396
|
+
useBuildingService: () => useBuildingService,
|
|
1397
|
+
useBuildingUnitController: () => useBuildingUnitController,
|
|
1398
|
+
useBuildingUnitRepo: () => useBuildingUnitRepo,
|
|
1399
|
+
useBuildingUnitService: () => useBuildingUnitService,
|
|
1384
1400
|
useCurriculumController: () => useCurriculumController,
|
|
1385
1401
|
useCurriculumRepo: () => useCurriculumRepo,
|
|
1386
1402
|
useCurriculumSubjectController: () => useCurriculumSubjectController,
|
|
@@ -1396,6 +1412,8 @@ __export(src_exports, {
|
|
|
1396
1412
|
useGradeLevelRepo: () => useGradeLevelRepo,
|
|
1397
1413
|
useLearnerController: () => useLearnerController,
|
|
1398
1414
|
useLearnerRepo: () => useLearnerRepo,
|
|
1415
|
+
usePersonnelController: () => usePersonnelController,
|
|
1416
|
+
usePersonnelRepo: () => usePersonnelRepo,
|
|
1399
1417
|
usePlantillaController: () => usePlantillaController,
|
|
1400
1418
|
usePlantillaRepo: () => usePlantillaRepo,
|
|
1401
1419
|
usePlantillaService: () => usePlantillaService,
|
|
@@ -1409,6 +1427,9 @@ __export(src_exports, {
|
|
|
1409
1427
|
useSectionPresetRepo: () => useSectionPresetRepo,
|
|
1410
1428
|
useSectionRepo: () => useSectionRepo,
|
|
1411
1429
|
useSectionStudentRepo: () => useSectionStudentRepo,
|
|
1430
|
+
useSectionSubjectController: () => useSectionSubjectController,
|
|
1431
|
+
useSectionSubjectRepo: () => useSectionSubjectRepo,
|
|
1432
|
+
useSectionSubjectService: () => useSectionSubjectService,
|
|
1412
1433
|
useStockCardController: () => useStockCardController,
|
|
1413
1434
|
useStockCardRepository: () => useStockCardRepository,
|
|
1414
1435
|
useStockCardService: () => useStockCardService
|
|
@@ -3587,8 +3608,11 @@ function useLearnerRepo() {
|
|
|
3587
3608
|
}
|
|
3588
3609
|
}
|
|
3589
3610
|
async function getByGradeLevel(value, session) {
|
|
3611
|
+
value.limit = value.limit && value.limit > 0 ? value.limit : 50;
|
|
3612
|
+
value.skip = value.skip && value.skip > 0 ? value.skip - 1 : 0;
|
|
3590
3613
|
const validation = import_joi7.default.object({
|
|
3591
3614
|
school: import_joi7.default.string().hex().required(),
|
|
3615
|
+
schoolYear: import_joi7.default.string().optional(),
|
|
3592
3616
|
gradeLevel: import_joi7.default.string().required(),
|
|
3593
3617
|
status: import_joi7.default.string().optional().allow("", null),
|
|
3594
3618
|
limit: import_joi7.default.number().integer().required(),
|
|
@@ -3605,8 +3629,14 @@ function useLearnerRepo() {
|
|
|
3605
3629
|
};
|
|
3606
3630
|
const cacheKeyOptions = {
|
|
3607
3631
|
...query,
|
|
3608
|
-
tag: "byGradeLevel"
|
|
3632
|
+
tag: "byGradeLevel",
|
|
3633
|
+
limit: value.limit,
|
|
3634
|
+
skip: value.skip
|
|
3609
3635
|
};
|
|
3636
|
+
if (value.schoolYear) {
|
|
3637
|
+
query.schoolYear = value.schoolYear;
|
|
3638
|
+
cacheKeyOptions.schoolYear = value.schoolYear;
|
|
3639
|
+
}
|
|
3610
3640
|
if (value.school && typeof value.school === "string") {
|
|
3611
3641
|
try {
|
|
3612
3642
|
query.school = new import_mongodb7.ObjectId(value.school);
|
|
@@ -3626,11 +3656,7 @@ function useLearnerRepo() {
|
|
|
3626
3656
|
}
|
|
3627
3657
|
try {
|
|
3628
3658
|
const data = await collection.aggregate(
|
|
3629
|
-
[
|
|
3630
|
-
{ $match: query },
|
|
3631
|
-
{ $skip: value.skip ?? 0 },
|
|
3632
|
-
{ $limit: value.limit ?? 100 }
|
|
3633
|
-
],
|
|
3659
|
+
[{ $match: query }, { $skip: value.skip }, { $limit: value.limit }],
|
|
3634
3660
|
{ session }
|
|
3635
3661
|
).toArray();
|
|
3636
3662
|
setCache(cacheKey, data, 600).then(() => {
|
|
@@ -37820,11 +37846,11 @@ function useSectionRepo() {
|
|
|
37820
37846
|
}
|
|
37821
37847
|
|
|
37822
37848
|
// src/resources/section/section.controller.ts
|
|
37823
|
-
var
|
|
37824
|
-
var
|
|
37849
|
+
var import_nodejs_utils53 = require("@eeplatform/nodejs-utils");
|
|
37850
|
+
var import_joi31 = __toESM(require("joi"));
|
|
37825
37851
|
|
|
37826
37852
|
// src/resources/section/section.service.ts
|
|
37827
|
-
var
|
|
37853
|
+
var import_nodejs_utils52 = require("@eeplatform/nodejs-utils");
|
|
37828
37854
|
|
|
37829
37855
|
// src/resources/section-student/section.student.repository.ts
|
|
37830
37856
|
var import_nodejs_utils47 = require("@eeplatform/nodejs-utils");
|
|
@@ -37949,196 +37975,614 @@ function useSectionStudentRepo() {
|
|
|
37949
37975
|
};
|
|
37950
37976
|
}
|
|
37951
37977
|
|
|
37952
|
-
// src/resources/section/section.
|
|
37953
|
-
|
|
37954
|
-
|
|
37955
|
-
|
|
37956
|
-
|
|
37957
|
-
|
|
37958
|
-
|
|
37959
|
-
|
|
37960
|
-
|
|
37961
|
-
|
|
37962
|
-
|
|
37963
|
-
|
|
37964
|
-
|
|
37965
|
-
|
|
37966
|
-
|
|
37978
|
+
// src/resources/section-subject/section.subject.model.ts
|
|
37979
|
+
var import_nodejs_utils48 = require("@eeplatform/nodejs-utils");
|
|
37980
|
+
var import_joi29 = __toESM(require("joi"));
|
|
37981
|
+
var import_mongodb28 = require("mongodb");
|
|
37982
|
+
var schemaSectionSubject = import_joi29.default.object({
|
|
37983
|
+
_id: import_joi29.default.string().hex().optional().allow(null, ""),
|
|
37984
|
+
school: import_joi29.default.string().hex().required(),
|
|
37985
|
+
schoolName: import_joi29.default.string().optional().allow(null, ""),
|
|
37986
|
+
section: import_joi29.default.string().hex().required(),
|
|
37987
|
+
sectionName: import_joi29.default.string().required(),
|
|
37988
|
+
gradeLevel: import_joi29.default.string().required(),
|
|
37989
|
+
educationLevel: import_joi29.default.string().required(),
|
|
37990
|
+
schoolYear: import_joi29.default.string().required(),
|
|
37991
|
+
subjectCode: import_joi29.default.string().required(),
|
|
37992
|
+
subjectName: import_joi29.default.string().required(),
|
|
37993
|
+
teacher: import_joi29.default.string().hex().optional().allow(null, ""),
|
|
37994
|
+
teacherName: import_joi29.default.string().optional().allow(null, ""),
|
|
37995
|
+
classroom: import_joi29.default.string().optional().allow(null, ""),
|
|
37996
|
+
classroomName: import_joi29.default.string().optional().allow(null, ""),
|
|
37997
|
+
daysOfWeek: import_joi29.default.array().items(import_joi29.default.string()).optional().allow(null),
|
|
37998
|
+
schedule: import_joi29.default.string().optional().allow(null, ""),
|
|
37999
|
+
sessionDuration: import_joi29.default.number().optional().allow(null, 0),
|
|
38000
|
+
sessionFrequency: import_joi29.default.number().optional().allow(null, 0),
|
|
38001
|
+
status: import_joi29.default.string().valid("active", "draft").optional(),
|
|
38002
|
+
createdAt: import_joi29.default.string().isoDate().optional().allow(null, ""),
|
|
38003
|
+
updatedAt: import_joi29.default.string().isoDate().optional().allow(null, ""),
|
|
38004
|
+
deletedAt: import_joi29.default.string().isoDate().optional().allow(null, "")
|
|
38005
|
+
});
|
|
38006
|
+
var schemaSectionSubjectSetup = import_joi29.default.object({
|
|
38007
|
+
teacher: import_joi29.default.string().hex().optional().allow(null, ""),
|
|
38008
|
+
teacherName: import_joi29.default.string().optional().allow(null, ""),
|
|
38009
|
+
classroom: import_joi29.default.string().optional().allow(null, ""),
|
|
38010
|
+
classroomName: import_joi29.default.string().optional().allow(null, ""),
|
|
38011
|
+
daysOfWeek: import_joi29.default.array().items(import_joi29.default.string()).optional().allow(null),
|
|
38012
|
+
schedule: import_joi29.default.string().optional().allow(null, "")
|
|
38013
|
+
});
|
|
38014
|
+
function modelSectionSubject(value) {
|
|
38015
|
+
const { error } = schemaSectionSubject.validate(value);
|
|
38016
|
+
if (error) {
|
|
38017
|
+
throw new import_nodejs_utils48.BadRequestError(`Invalid section subject data: ${error.message}`);
|
|
38018
|
+
}
|
|
38019
|
+
if (value._id && typeof value._id === "string") {
|
|
38020
|
+
try {
|
|
38021
|
+
value._id = new import_mongodb28.ObjectId(value._id);
|
|
38022
|
+
} catch (error2) {
|
|
38023
|
+
throw new Error("Invalid _id.");
|
|
37967
38024
|
}
|
|
37968
|
-
|
|
37969
|
-
|
|
37970
|
-
|
|
37971
|
-
|
|
37972
|
-
|
|
37973
|
-
|
|
37974
|
-
sectionCount = minSections;
|
|
38025
|
+
}
|
|
38026
|
+
if (value.school && typeof value.school === "string") {
|
|
38027
|
+
try {
|
|
38028
|
+
value.school = new import_mongodb28.ObjectId(value.school);
|
|
38029
|
+
} catch (error2) {
|
|
38030
|
+
throw new Error("Invalid school ID.");
|
|
37975
38031
|
}
|
|
37976
|
-
|
|
37977
|
-
|
|
37978
|
-
|
|
37979
|
-
|
|
37980
|
-
|
|
38032
|
+
}
|
|
38033
|
+
if (value.section && typeof value.section === "string") {
|
|
38034
|
+
try {
|
|
38035
|
+
value.section = new import_mongodb28.ObjectId(value.section);
|
|
38036
|
+
} catch (error2) {
|
|
38037
|
+
throw new Error("Invalid section ID.");
|
|
37981
38038
|
}
|
|
37982
|
-
|
|
37983
|
-
|
|
37984
|
-
|
|
37985
|
-
|
|
37986
|
-
|
|
38039
|
+
}
|
|
38040
|
+
if (value.teacher && typeof value.teacher === "string") {
|
|
38041
|
+
try {
|
|
38042
|
+
value.teacher = new import_mongodb28.ObjectId(value.teacher);
|
|
38043
|
+
} catch (error2) {
|
|
38044
|
+
throw new Error("Invalid teacher ID.");
|
|
38045
|
+
}
|
|
38046
|
+
}
|
|
38047
|
+
return {
|
|
38048
|
+
_id: value._id,
|
|
38049
|
+
school: value.school,
|
|
38050
|
+
schoolName: value.schoolName,
|
|
38051
|
+
section: value.section,
|
|
38052
|
+
sectionName: value.sectionName,
|
|
38053
|
+
gradeLevel: value.gradeLevel,
|
|
38054
|
+
educationLevel: value.educationLevel,
|
|
38055
|
+
schoolYear: value.schoolYear,
|
|
38056
|
+
subjectCode: value.subjectCode,
|
|
38057
|
+
subjectName: value.subjectName,
|
|
38058
|
+
teacher: value.teacher,
|
|
38059
|
+
teacherName: value.teacherName,
|
|
38060
|
+
classroom: value.classroom ?? "",
|
|
38061
|
+
classroomName: value.classroomName ?? "",
|
|
38062
|
+
daysOfWeek: value.daysOfWeek ?? [],
|
|
38063
|
+
schedule: value.schedule ?? "",
|
|
38064
|
+
sessionDuration: value.sessionDuration ?? 0,
|
|
38065
|
+
sessionFrequency: value.sessionFrequency ?? 0,
|
|
38066
|
+
status: value.status ?? "draft",
|
|
38067
|
+
createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
|
|
38068
|
+
updatedAt: value.updatedAt ?? "",
|
|
38069
|
+
deletedAt: value.deletedAt ?? ""
|
|
38070
|
+
};
|
|
38071
|
+
}
|
|
38072
|
+
|
|
38073
|
+
// src/resources/section-subject/section.subject.repository.ts
|
|
38074
|
+
var import_nodejs_utils49 = require("@eeplatform/nodejs-utils");
|
|
38075
|
+
var import_mongodb29 = require("mongodb");
|
|
38076
|
+
function useSectionSubjectRepo() {
|
|
38077
|
+
const db = import_nodejs_utils49.useAtlas.getDb();
|
|
38078
|
+
if (!db) {
|
|
38079
|
+
throw new Error("Unable to connect to server.");
|
|
38080
|
+
}
|
|
38081
|
+
const namespace_collection = "deped.section.subjects";
|
|
38082
|
+
const collection = db.collection(namespace_collection);
|
|
38083
|
+
const { getCache, setCache, delNamespace } = (0, import_nodejs_utils49.useCache)(namespace_collection);
|
|
38084
|
+
async function createIndexes() {
|
|
38085
|
+
try {
|
|
38086
|
+
await collection.createIndexes([
|
|
38087
|
+
{ key: { school: 1 } },
|
|
38088
|
+
{ key: { section: 1 } },
|
|
38089
|
+
{ key: { teacher: 1 } },
|
|
38090
|
+
{ key: { subjectCode: 1 } },
|
|
38091
|
+
{ key: { schoolYear: 1 } },
|
|
38092
|
+
{ key: { gradeLevel: 1 } },
|
|
38093
|
+
{ key: { createdAt: 1 } },
|
|
38094
|
+
{
|
|
38095
|
+
key: {
|
|
38096
|
+
subjectName: "text",
|
|
38097
|
+
subjectCode: "text",
|
|
38098
|
+
teacherName: "text"
|
|
38099
|
+
}
|
|
38100
|
+
},
|
|
38101
|
+
{
|
|
38102
|
+
key: {
|
|
38103
|
+
school: 1,
|
|
38104
|
+
section: 1,
|
|
38105
|
+
subjectCode: 1,
|
|
38106
|
+
schoolYear: 1,
|
|
38107
|
+
status: 1
|
|
38108
|
+
},
|
|
38109
|
+
unique: true,
|
|
38110
|
+
name: "unique_section_subject"
|
|
38111
|
+
}
|
|
38112
|
+
]);
|
|
38113
|
+
} catch (error) {
|
|
38114
|
+
throw new Error("Failed to create index on section subjects.");
|
|
38115
|
+
}
|
|
38116
|
+
}
|
|
38117
|
+
function delCachedData() {
|
|
38118
|
+
delNamespace().then(() => {
|
|
38119
|
+
import_nodejs_utils49.logger.log({
|
|
38120
|
+
level: "info",
|
|
38121
|
+
message: `Cache namespace cleared for ${namespace_collection}`
|
|
38122
|
+
});
|
|
38123
|
+
}).catch((err) => {
|
|
38124
|
+
import_nodejs_utils49.logger.log({
|
|
38125
|
+
level: "error",
|
|
38126
|
+
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
38127
|
+
});
|
|
38128
|
+
});
|
|
38129
|
+
}
|
|
38130
|
+
async function add(value, session) {
|
|
38131
|
+
try {
|
|
38132
|
+
value = modelSectionSubject(value);
|
|
38133
|
+
const res = await collection.insertOne(value, { session });
|
|
38134
|
+
delCachedData();
|
|
38135
|
+
return res.insertedId;
|
|
38136
|
+
} catch (error) {
|
|
38137
|
+
import_nodejs_utils49.logger.log({
|
|
38138
|
+
level: "error",
|
|
38139
|
+
message: error.message
|
|
38140
|
+
});
|
|
38141
|
+
if (error instanceof import_nodejs_utils49.AppError) {
|
|
38142
|
+
throw error;
|
|
38143
|
+
} else {
|
|
38144
|
+
const isDuplicated = error.message.includes("duplicate");
|
|
38145
|
+
if (isDuplicated) {
|
|
38146
|
+
throw new import_nodejs_utils49.BadRequestError("Section subject already exists.");
|
|
38147
|
+
}
|
|
38148
|
+
throw new Error("Failed to create section subject.");
|
|
37987
38149
|
}
|
|
37988
38150
|
}
|
|
37989
|
-
return sizes;
|
|
37990
38151
|
}
|
|
37991
|
-
async function
|
|
37992
|
-
|
|
37993
|
-
|
|
37994
|
-
|
|
37995
|
-
|
|
37996
|
-
|
|
38152
|
+
async function getAll({
|
|
38153
|
+
search = "",
|
|
38154
|
+
page = 1,
|
|
38155
|
+
limit = 10,
|
|
38156
|
+
sort = {},
|
|
38157
|
+
status = "active",
|
|
38158
|
+
school = "",
|
|
38159
|
+
section = "",
|
|
38160
|
+
teacher = "",
|
|
38161
|
+
schoolYear = "",
|
|
38162
|
+
gradeLevel = "",
|
|
38163
|
+
subjectCode = ""
|
|
38164
|
+
} = {}) {
|
|
38165
|
+
page = page > 0 ? page - 1 : 0;
|
|
38166
|
+
const query = { status: { $ne: "deleted" } };
|
|
38167
|
+
const cacheKeyOptions = {
|
|
38168
|
+
page,
|
|
38169
|
+
limit,
|
|
38170
|
+
sort: JSON.stringify(sort)
|
|
38171
|
+
};
|
|
38172
|
+
if (status) {
|
|
38173
|
+
query.status = status;
|
|
38174
|
+
cacheKeyOptions.status = status;
|
|
37997
38175
|
}
|
|
37998
|
-
|
|
37999
|
-
|
|
38000
|
-
|
|
38176
|
+
if (school) {
|
|
38177
|
+
try {
|
|
38178
|
+
query.school = new import_mongodb29.ObjectId(school);
|
|
38179
|
+
} catch (error) {
|
|
38180
|
+
throw new import_nodejs_utils49.BadRequestError("Invalid school ID.");
|
|
38181
|
+
}
|
|
38182
|
+
cacheKeyOptions.school = school;
|
|
38183
|
+
}
|
|
38184
|
+
if (section) {
|
|
38185
|
+
try {
|
|
38186
|
+
query.section = new import_mongodb29.ObjectId(section);
|
|
38187
|
+
} catch (error) {
|
|
38188
|
+
throw new import_nodejs_utils49.BadRequestError("Invalid section ID.");
|
|
38189
|
+
}
|
|
38190
|
+
cacheKeyOptions.section = section;
|
|
38191
|
+
}
|
|
38192
|
+
if (teacher) {
|
|
38193
|
+
try {
|
|
38194
|
+
query.teacher = new import_mongodb29.ObjectId(teacher);
|
|
38195
|
+
} catch (error) {
|
|
38196
|
+
throw new import_nodejs_utils49.BadRequestError("Invalid teacher ID.");
|
|
38197
|
+
}
|
|
38198
|
+
cacheKeyOptions.teacher = teacher;
|
|
38199
|
+
}
|
|
38200
|
+
if (schoolYear) {
|
|
38201
|
+
query.schoolYear = schoolYear;
|
|
38202
|
+
cacheKeyOptions.schoolYear = schoolYear;
|
|
38001
38203
|
}
|
|
38204
|
+
if (gradeLevel) {
|
|
38205
|
+
query.gradeLevel = gradeLevel;
|
|
38206
|
+
cacheKeyOptions.gradeLevel = gradeLevel;
|
|
38207
|
+
}
|
|
38208
|
+
if (subjectCode) {
|
|
38209
|
+
query.subjectCode = subjectCode;
|
|
38210
|
+
cacheKeyOptions.subjectCode = subjectCode;
|
|
38211
|
+
}
|
|
38212
|
+
sort = Object.keys(sort).length > 0 ? sort : { _id: 1 };
|
|
38213
|
+
if (search) {
|
|
38214
|
+
query.$text = { $search: search };
|
|
38215
|
+
cacheKeyOptions.search = search;
|
|
38216
|
+
}
|
|
38217
|
+
const cacheKey = (0, import_nodejs_utils49.makeCacheKey)(namespace_collection, cacheKeyOptions);
|
|
38218
|
+
import_nodejs_utils49.logger.log({
|
|
38219
|
+
level: "info",
|
|
38220
|
+
message: `Cache key for getAll section subjects: ${cacheKey}`
|
|
38221
|
+
});
|
|
38002
38222
|
try {
|
|
38003
|
-
await
|
|
38004
|
-
|
|
38005
|
-
{
|
|
38006
|
-
|
|
38007
|
-
|
|
38008
|
-
|
|
38009
|
-
|
|
38010
|
-
session
|
|
38011
|
-
);
|
|
38012
|
-
if (studentCount === 0) {
|
|
38013
|
-
throw new import_nodejs_utils48.BadRequestError("No learners found for this grade level.");
|
|
38223
|
+
const cached = await getCache(cacheKey);
|
|
38224
|
+
if (cached) {
|
|
38225
|
+
import_nodejs_utils49.logger.log({
|
|
38226
|
+
level: "info",
|
|
38227
|
+
message: `Cache hit for getAll section subjects: ${cacheKey}`
|
|
38228
|
+
});
|
|
38229
|
+
return cached;
|
|
38014
38230
|
}
|
|
38015
|
-
const
|
|
38016
|
-
{
|
|
38017
|
-
|
|
38018
|
-
|
|
38019
|
-
}
|
|
38020
|
-
|
|
38021
|
-
);
|
|
38022
|
-
|
|
38023
|
-
|
|
38231
|
+
const items = await collection.aggregate([
|
|
38232
|
+
{ $match: query },
|
|
38233
|
+
{ $sort: sort },
|
|
38234
|
+
{ $skip: page * limit },
|
|
38235
|
+
{ $limit: limit }
|
|
38236
|
+
]).toArray();
|
|
38237
|
+
const length = await collection.countDocuments(query);
|
|
38238
|
+
const data = (0, import_nodejs_utils49.paginate)(items, page, limit, length);
|
|
38239
|
+
setCache(cacheKey, data, 600).then(() => {
|
|
38240
|
+
import_nodejs_utils49.logger.log({
|
|
38241
|
+
level: "info",
|
|
38242
|
+
message: `Cache set for getAll section subjects: ${cacheKey}`
|
|
38243
|
+
});
|
|
38244
|
+
}).catch((err) => {
|
|
38245
|
+
import_nodejs_utils49.logger.log({
|
|
38246
|
+
level: "error",
|
|
38247
|
+
message: `Failed to set cache for getAll section subjects: ${err.message}`
|
|
38248
|
+
});
|
|
38249
|
+
});
|
|
38250
|
+
return data;
|
|
38251
|
+
} catch (error) {
|
|
38252
|
+
import_nodejs_utils49.logger.log({ level: "error", message: `${error}` });
|
|
38253
|
+
throw error;
|
|
38254
|
+
}
|
|
38255
|
+
}
|
|
38256
|
+
async function getById(_id) {
|
|
38257
|
+
try {
|
|
38258
|
+
_id = new import_mongodb29.ObjectId(_id);
|
|
38259
|
+
} catch (error) {
|
|
38260
|
+
throw new import_nodejs_utils49.BadRequestError("Invalid ID.");
|
|
38261
|
+
}
|
|
38262
|
+
const cacheKey = (0, import_nodejs_utils49.makeCacheKey)(namespace_collection, { _id: String(_id) });
|
|
38263
|
+
try {
|
|
38264
|
+
const cached = await getCache(cacheKey);
|
|
38265
|
+
if (cached) {
|
|
38266
|
+
import_nodejs_utils49.logger.log({
|
|
38267
|
+
level: "info",
|
|
38268
|
+
message: `Cache hit for getById section subject: ${cacheKey}`
|
|
38269
|
+
});
|
|
38270
|
+
return cached;
|
|
38024
38271
|
}
|
|
38025
|
-
const
|
|
38026
|
-
|
|
38027
|
-
|
|
38028
|
-
|
|
38029
|
-
|
|
38030
|
-
|
|
38272
|
+
const result = await collection.findOne({
|
|
38273
|
+
_id,
|
|
38274
|
+
deletedAt: { $in: ["", null] }
|
|
38275
|
+
});
|
|
38276
|
+
if (!result) {
|
|
38277
|
+
throw new import_nodejs_utils49.BadRequestError("Section subject not found.");
|
|
38278
|
+
}
|
|
38279
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
38280
|
+
import_nodejs_utils49.logger.log({
|
|
38281
|
+
level: "info",
|
|
38282
|
+
message: `Cache set for section subject by id: ${cacheKey}`
|
|
38283
|
+
});
|
|
38284
|
+
}).catch((err) => {
|
|
38285
|
+
import_nodejs_utils49.logger.log({
|
|
38286
|
+
level: "error",
|
|
38287
|
+
message: `Failed to set cache for section subject by id: ${err.message}`
|
|
38288
|
+
});
|
|
38289
|
+
});
|
|
38290
|
+
return result;
|
|
38291
|
+
} catch (error) {
|
|
38292
|
+
if (error instanceof import_nodejs_utils49.AppError) {
|
|
38293
|
+
throw error;
|
|
38294
|
+
} else {
|
|
38295
|
+
throw new import_nodejs_utils49.InternalServerError("Failed to get section subject.");
|
|
38296
|
+
}
|
|
38297
|
+
}
|
|
38298
|
+
}
|
|
38299
|
+
async function getBySection(section) {
|
|
38300
|
+
try {
|
|
38301
|
+
section = new import_mongodb29.ObjectId(section);
|
|
38302
|
+
} catch (error) {
|
|
38303
|
+
throw new import_nodejs_utils49.BadRequestError("Invalid section ID.");
|
|
38304
|
+
}
|
|
38305
|
+
const cacheKey = (0, import_nodejs_utils49.makeCacheKey)(namespace_collection, {
|
|
38306
|
+
section: String(section)
|
|
38307
|
+
});
|
|
38308
|
+
try {
|
|
38309
|
+
const cached = await getCache(cacheKey);
|
|
38310
|
+
if (cached) {
|
|
38311
|
+
import_nodejs_utils49.logger.log({
|
|
38312
|
+
level: "info",
|
|
38313
|
+
message: `Cache hit for getBySection section subjects: ${cacheKey}`
|
|
38314
|
+
});
|
|
38315
|
+
return cached;
|
|
38316
|
+
}
|
|
38317
|
+
const result = await collection.find({
|
|
38318
|
+
section,
|
|
38319
|
+
deletedAt: { $in: ["", null] }
|
|
38320
|
+
}).toArray();
|
|
38321
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
38322
|
+
import_nodejs_utils49.logger.log({
|
|
38323
|
+
level: "info",
|
|
38324
|
+
message: `Cache set for section subjects by section: ${cacheKey}`
|
|
38325
|
+
});
|
|
38326
|
+
}).catch((err) => {
|
|
38327
|
+
import_nodejs_utils49.logger.log({
|
|
38328
|
+
level: "error",
|
|
38329
|
+
message: `Failed to set cache for section subjects by section: ${err.message}`
|
|
38330
|
+
});
|
|
38331
|
+
});
|
|
38332
|
+
return result;
|
|
38333
|
+
} catch (error) {
|
|
38334
|
+
if (error instanceof import_nodejs_utils49.AppError) {
|
|
38335
|
+
throw error;
|
|
38336
|
+
} else {
|
|
38337
|
+
throw new import_nodejs_utils49.InternalServerError(
|
|
38338
|
+
"Failed to get section subjects by section."
|
|
38031
38339
|
);
|
|
38032
38340
|
}
|
|
38033
|
-
|
|
38034
|
-
|
|
38035
|
-
|
|
38036
|
-
|
|
38037
|
-
);
|
|
38038
|
-
|
|
38039
|
-
|
|
38341
|
+
}
|
|
38342
|
+
}
|
|
38343
|
+
async function getByTeacher(teacher) {
|
|
38344
|
+
try {
|
|
38345
|
+
teacher = new import_mongodb29.ObjectId(teacher);
|
|
38346
|
+
} catch (error) {
|
|
38347
|
+
throw new import_nodejs_utils49.BadRequestError("Invalid teacher ID.");
|
|
38348
|
+
}
|
|
38349
|
+
const cacheKey = (0, import_nodejs_utils49.makeCacheKey)(namespace_collection, {
|
|
38350
|
+
teacher: String(teacher)
|
|
38351
|
+
});
|
|
38352
|
+
try {
|
|
38353
|
+
const cached = await getCache(cacheKey);
|
|
38354
|
+
if (cached) {
|
|
38355
|
+
import_nodejs_utils49.logger.log({
|
|
38356
|
+
level: "info",
|
|
38357
|
+
message: `Cache hit for getByTeacher section subjects: ${cacheKey}`
|
|
38358
|
+
});
|
|
38359
|
+
return cached;
|
|
38040
38360
|
}
|
|
38041
|
-
|
|
38042
|
-
|
|
38043
|
-
|
|
38044
|
-
|
|
38045
|
-
|
|
38046
|
-
|
|
38047
|
-
|
|
38048
|
-
|
|
38049
|
-
|
|
38050
|
-
|
|
38051
|
-
|
|
38052
|
-
|
|
38053
|
-
|
|
38361
|
+
const result = await collection.find({
|
|
38362
|
+
teacher,
|
|
38363
|
+
deletedAt: { $in: ["", null] }
|
|
38364
|
+
}).toArray();
|
|
38365
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
38366
|
+
import_nodejs_utils49.logger.log({
|
|
38367
|
+
level: "info",
|
|
38368
|
+
message: `Cache set for section subjects by teacher: ${cacheKey}`
|
|
38369
|
+
});
|
|
38370
|
+
}).catch((err) => {
|
|
38371
|
+
import_nodejs_utils49.logger.log({
|
|
38372
|
+
level: "error",
|
|
38373
|
+
message: `Failed to set cache for section subjects by teacher: ${err.message}`
|
|
38374
|
+
});
|
|
38375
|
+
});
|
|
38376
|
+
return result;
|
|
38377
|
+
} catch (error) {
|
|
38378
|
+
if (error instanceof import_nodejs_utils49.AppError) {
|
|
38379
|
+
throw error;
|
|
38380
|
+
} else {
|
|
38381
|
+
throw new import_nodejs_utils49.InternalServerError(
|
|
38382
|
+
"Failed to get section subjects by teacher."
|
|
38054
38383
|
);
|
|
38055
|
-
|
|
38056
|
-
|
|
38057
|
-
|
|
38058
|
-
|
|
38059
|
-
|
|
38060
|
-
|
|
38061
|
-
|
|
38062
|
-
|
|
38384
|
+
}
|
|
38385
|
+
}
|
|
38386
|
+
}
|
|
38387
|
+
async function getBySchool(school) {
|
|
38388
|
+
try {
|
|
38389
|
+
school = new import_mongodb29.ObjectId(school);
|
|
38390
|
+
} catch (error) {
|
|
38391
|
+
throw new import_nodejs_utils49.BadRequestError("Invalid school ID.");
|
|
38392
|
+
}
|
|
38393
|
+
const cacheKey = (0, import_nodejs_utils49.makeCacheKey)(namespace_collection, {
|
|
38394
|
+
school: String(school)
|
|
38395
|
+
});
|
|
38396
|
+
try {
|
|
38397
|
+
const cached = await getCache(cacheKey);
|
|
38398
|
+
if (cached) {
|
|
38399
|
+
import_nodejs_utils49.logger.log({
|
|
38400
|
+
level: "info",
|
|
38401
|
+
message: `Cache hit for getBySchool section subjects: ${cacheKey}`
|
|
38402
|
+
});
|
|
38403
|
+
return cached;
|
|
38404
|
+
}
|
|
38405
|
+
const result = await collection.find({
|
|
38406
|
+
school,
|
|
38407
|
+
deletedAt: { $in: ["", null] }
|
|
38408
|
+
}).toArray();
|
|
38409
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
38410
|
+
import_nodejs_utils49.logger.log({
|
|
38411
|
+
level: "info",
|
|
38412
|
+
message: `Cache set for section subjects by school: ${cacheKey}`
|
|
38413
|
+
});
|
|
38414
|
+
}).catch((err) => {
|
|
38415
|
+
import_nodejs_utils49.logger.log({
|
|
38416
|
+
level: "error",
|
|
38417
|
+
message: `Failed to set cache for section subjects by school: ${err.message}`
|
|
38418
|
+
});
|
|
38419
|
+
});
|
|
38420
|
+
return result;
|
|
38421
|
+
} catch (error) {
|
|
38422
|
+
if (error instanceof import_nodejs_utils49.AppError) {
|
|
38423
|
+
throw error;
|
|
38424
|
+
} else {
|
|
38425
|
+
throw new import_nodejs_utils49.InternalServerError(
|
|
38426
|
+
"Failed to get section subjects by school."
|
|
38063
38427
|
);
|
|
38064
|
-
if (!learners.length) {
|
|
38065
|
-
throw new import_nodejs_utils48.BadRequestError(`No learners found for section #${i + 1}.`);
|
|
38066
|
-
}
|
|
38067
|
-
pointer += size;
|
|
38068
|
-
for (const student of learners) {
|
|
38069
|
-
if (!student._id) {
|
|
38070
|
-
throw new import_nodejs_utils48.BadRequestError("Learner ID is missing.");
|
|
38071
|
-
}
|
|
38072
|
-
await assignStudent(
|
|
38073
|
-
{
|
|
38074
|
-
section: section.toString(),
|
|
38075
|
-
student: student._id?.toString(),
|
|
38076
|
-
studentName: `${student.learnerInfo.firstName} ${student.learnerInfo.lastName}`,
|
|
38077
|
-
status: "active"
|
|
38078
|
-
},
|
|
38079
|
-
session
|
|
38080
|
-
);
|
|
38081
|
-
}
|
|
38082
38428
|
}
|
|
38083
|
-
|
|
38084
|
-
|
|
38429
|
+
}
|
|
38430
|
+
}
|
|
38431
|
+
async function updateFieldById({ _id, field, value } = {}, session) {
|
|
38432
|
+
const allowedFields = [
|
|
38433
|
+
"teacher",
|
|
38434
|
+
"teacherName",
|
|
38435
|
+
"classroom",
|
|
38436
|
+
"schedule",
|
|
38437
|
+
"daysOfWeek"
|
|
38438
|
+
];
|
|
38439
|
+
if (!allowedFields.includes(field)) {
|
|
38440
|
+
throw new import_nodejs_utils49.BadRequestError(
|
|
38441
|
+
`Field "${field}" is not allowed to be updated.`
|
|
38442
|
+
);
|
|
38443
|
+
}
|
|
38444
|
+
try {
|
|
38445
|
+
_id = new import_mongodb29.ObjectId(_id);
|
|
38446
|
+
} catch (error) {
|
|
38447
|
+
throw new import_nodejs_utils49.BadRequestError("Invalid ID.");
|
|
38448
|
+
}
|
|
38449
|
+
if (field === "teacher" && value) {
|
|
38450
|
+
try {
|
|
38451
|
+
value = new import_mongodb29.ObjectId(value).toString();
|
|
38452
|
+
} catch (error) {
|
|
38453
|
+
throw new import_nodejs_utils49.BadRequestError("Invalid teacher ID.");
|
|
38454
|
+
}
|
|
38455
|
+
}
|
|
38456
|
+
try {
|
|
38457
|
+
const updateValue = field === "teacher" ? new import_mongodb29.ObjectId(value) : value;
|
|
38458
|
+
await collection.updateOne(
|
|
38459
|
+
{ _id, deletedAt: { $in: ["", null] } },
|
|
38460
|
+
{ $set: { [field]: updateValue, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
|
|
38461
|
+
{ session }
|
|
38462
|
+
);
|
|
38463
|
+
delCachedData();
|
|
38464
|
+
return `Successfully updated section subject ${field}.`;
|
|
38465
|
+
} catch (error) {
|
|
38466
|
+
throw new import_nodejs_utils49.InternalServerError(
|
|
38467
|
+
`Failed to update section subject ${field}.`
|
|
38468
|
+
);
|
|
38469
|
+
}
|
|
38470
|
+
}
|
|
38471
|
+
async function setupById(_id, value, session) {
|
|
38472
|
+
const { error } = schemaSectionSubjectSetup.validate(value);
|
|
38473
|
+
if (error) {
|
|
38474
|
+
throw new import_nodejs_utils49.BadRequestError(
|
|
38475
|
+
`Invalid section subject data: ${error.message}`
|
|
38476
|
+
);
|
|
38477
|
+
}
|
|
38478
|
+
try {
|
|
38479
|
+
_id = new import_mongodb29.ObjectId(_id);
|
|
38085
38480
|
} catch (error2) {
|
|
38086
|
-
|
|
38087
|
-
|
|
38481
|
+
throw new import_nodejs_utils49.BadRequestError("Invalid ID.");
|
|
38482
|
+
}
|
|
38483
|
+
try {
|
|
38484
|
+
await collection.updateOne(
|
|
38485
|
+
{ _id, deletedAt: { $in: ["", null] } },
|
|
38486
|
+
{ $set: { ...value, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
|
|
38487
|
+
{ session }
|
|
38488
|
+
);
|
|
38489
|
+
delCachedData();
|
|
38490
|
+
return `Successfully updated section subject.`;
|
|
38491
|
+
} catch (error2) {
|
|
38492
|
+
throw new import_nodejs_utils49.InternalServerError(`Failed to update section subject.`);
|
|
38493
|
+
}
|
|
38494
|
+
}
|
|
38495
|
+
async function deleteById(_id) {
|
|
38496
|
+
try {
|
|
38497
|
+
_id = new import_mongodb29.ObjectId(_id);
|
|
38498
|
+
} catch (error) {
|
|
38499
|
+
throw new import_nodejs_utils49.BadRequestError("Invalid ID.");
|
|
38500
|
+
}
|
|
38501
|
+
try {
|
|
38502
|
+
await collection.updateOne(
|
|
38503
|
+
{ _id },
|
|
38504
|
+
{ $set: { status: "deleted", deletedAt: (/* @__PURE__ */ new Date()).toISOString() } }
|
|
38505
|
+
);
|
|
38506
|
+
delCachedData();
|
|
38507
|
+
return "Successfully deleted section subject.";
|
|
38508
|
+
} catch (error) {
|
|
38509
|
+
throw new import_nodejs_utils49.InternalServerError("Failed to delete section subject.");
|
|
38510
|
+
}
|
|
38511
|
+
}
|
|
38512
|
+
return {
|
|
38513
|
+
createIndexes,
|
|
38514
|
+
add,
|
|
38515
|
+
getAll,
|
|
38516
|
+
getById,
|
|
38517
|
+
getBySection,
|
|
38518
|
+
getByTeacher,
|
|
38519
|
+
getBySchool,
|
|
38520
|
+
updateFieldById,
|
|
38521
|
+
setupById,
|
|
38522
|
+
deleteById
|
|
38523
|
+
};
|
|
38524
|
+
}
|
|
38525
|
+
|
|
38526
|
+
// src/resources/section-subject/section.subject.service.ts
|
|
38527
|
+
var import_nodejs_utils50 = require("@eeplatform/nodejs-utils");
|
|
38528
|
+
function useSectionSubjectService() {
|
|
38529
|
+
const { getById: getSchoolById } = useSchoolRepo();
|
|
38530
|
+
const { add: _add } = useSectionSubjectRepo();
|
|
38531
|
+
async function add(value) {
|
|
38532
|
+
const { error } = schemaSectionSubject.validate(value);
|
|
38533
|
+
if (error) {
|
|
38534
|
+
throw new Error(`Invalid section subject data: ${error.message}`);
|
|
38535
|
+
}
|
|
38536
|
+
try {
|
|
38537
|
+
const school = await getSchoolById(value.school);
|
|
38538
|
+
if (!school) {
|
|
38539
|
+
throw new Error("School not found.");
|
|
38540
|
+
}
|
|
38541
|
+
if (!school.name) {
|
|
38542
|
+
throw new Error("School name is missing.");
|
|
38543
|
+
}
|
|
38544
|
+
value.schoolName = school.name;
|
|
38545
|
+
await _add(value);
|
|
38546
|
+
return "Successfully created section subject.";
|
|
38547
|
+
} catch (error2) {
|
|
38548
|
+
if (error2 instanceof import_nodejs_utils50.AppError) {
|
|
38088
38549
|
throw error2;
|
|
38089
38550
|
} else {
|
|
38090
|
-
throw new
|
|
38551
|
+
throw new import_nodejs_utils50.InternalServerError("Failed to create section subject.");
|
|
38091
38552
|
}
|
|
38092
|
-
} finally {
|
|
38093
|
-
await session?.endSession();
|
|
38094
38553
|
}
|
|
38095
38554
|
}
|
|
38096
|
-
return {
|
|
38555
|
+
return {
|
|
38556
|
+
add
|
|
38557
|
+
};
|
|
38097
38558
|
}
|
|
38098
38559
|
|
|
38099
|
-
// src/resources/section/section.controller.ts
|
|
38100
|
-
|
|
38560
|
+
// src/resources/section-subject/section.subject.controller.ts
|
|
38561
|
+
var import_nodejs_utils51 = require("@eeplatform/nodejs-utils");
|
|
38562
|
+
var import_joi30 = __toESM(require("joi"));
|
|
38563
|
+
function useSectionSubjectController() {
|
|
38101
38564
|
const {
|
|
38102
|
-
add: _add,
|
|
38103
38565
|
getAll: _getAll,
|
|
38104
38566
|
getById: _getById,
|
|
38105
|
-
|
|
38567
|
+
getBySection: _getBySection,
|
|
38568
|
+
getByTeacher: _getByTeacher,
|
|
38106
38569
|
getBySchool: _getBySchool,
|
|
38107
38570
|
updateFieldById: _updateFieldById,
|
|
38108
|
-
|
|
38109
|
-
|
|
38110
|
-
|
|
38111
|
-
} =
|
|
38112
|
-
const { generateSections: _generateSections } = useSectionService();
|
|
38571
|
+
deleteById: _deleteById,
|
|
38572
|
+
setupById: _setupById
|
|
38573
|
+
} = useSectionSubjectRepo();
|
|
38574
|
+
const { add: _add } = useSectionSubjectService();
|
|
38113
38575
|
async function add(req, res, next) {
|
|
38114
38576
|
const value = req.body;
|
|
38115
|
-
const { error } =
|
|
38577
|
+
const { error } = schemaSectionSubject.validate(value);
|
|
38116
38578
|
if (error) {
|
|
38117
|
-
next(new
|
|
38579
|
+
next(new import_nodejs_utils51.BadRequestError(error.message));
|
|
38118
38580
|
return;
|
|
38119
38581
|
}
|
|
38120
38582
|
try {
|
|
38121
38583
|
const data = await _add(value);
|
|
38122
38584
|
res.json({
|
|
38123
|
-
message: "Successfully created section.",
|
|
38124
|
-
data
|
|
38125
|
-
});
|
|
38126
|
-
return;
|
|
38127
|
-
} catch (error2) {
|
|
38128
|
-
next(error2);
|
|
38129
|
-
}
|
|
38130
|
-
}
|
|
38131
|
-
async function generateSections(req, res, next) {
|
|
38132
|
-
const value = req.body;
|
|
38133
|
-
const { error } = schemaGenerateSections.validate(value);
|
|
38134
|
-
if (error) {
|
|
38135
|
-
next(new import_nodejs_utils49.BadRequestError(error.message));
|
|
38136
|
-
return;
|
|
38137
|
-
}
|
|
38138
|
-
try {
|
|
38139
|
-
const data = await _generateSections(value);
|
|
38140
|
-
res.json({
|
|
38141
|
-
message: "Successfully created section.",
|
|
38585
|
+
message: "Successfully created section subject.",
|
|
38142
38586
|
data
|
|
38143
38587
|
});
|
|
38144
38588
|
return;
|
|
@@ -38148,35 +38592,41 @@ function useSectionController() {
|
|
|
38148
38592
|
}
|
|
38149
38593
|
async function getAll(req, res, next) {
|
|
38150
38594
|
const query = req.query;
|
|
38151
|
-
const validation =
|
|
38152
|
-
page:
|
|
38153
|
-
limit:
|
|
38154
|
-
search:
|
|
38155
|
-
status:
|
|
38156
|
-
school:
|
|
38157
|
-
|
|
38158
|
-
|
|
38595
|
+
const validation = import_joi30.default.object({
|
|
38596
|
+
page: import_joi30.default.number().min(1).optional().allow("", null),
|
|
38597
|
+
limit: import_joi30.default.number().min(1).optional().allow("", null),
|
|
38598
|
+
search: import_joi30.default.string().optional().allow("", null),
|
|
38599
|
+
status: import_joi30.default.string().optional().allow("", null),
|
|
38600
|
+
school: import_joi30.default.string().hex().optional().allow("", null),
|
|
38601
|
+
section: import_joi30.default.string().hex().optional().allow("", null),
|
|
38602
|
+
teacher: import_joi30.default.string().hex().optional().allow("", null),
|
|
38603
|
+
schoolYear: import_joi30.default.string().optional().allow("", null),
|
|
38604
|
+
gradeLevel: import_joi30.default.string().optional().allow("", null),
|
|
38605
|
+
subjectCode: import_joi30.default.string().optional().allow("", null)
|
|
38159
38606
|
});
|
|
38160
38607
|
const { error } = validation.validate(query);
|
|
38161
38608
|
const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
|
|
38162
38609
|
const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
|
|
38163
38610
|
const search = req.query.search ?? "";
|
|
38164
|
-
const status = req.query.status ?? "
|
|
38611
|
+
const status = req.query.status ?? "";
|
|
38165
38612
|
const school = req.query.school ?? "";
|
|
38613
|
+
const section = req.query.section ?? "";
|
|
38614
|
+
const teacher = req.query.teacher ?? "";
|
|
38166
38615
|
const schoolYear = req.query.schoolYear ?? "";
|
|
38167
38616
|
const gradeLevel = req.query.gradeLevel ?? "";
|
|
38617
|
+
const subjectCode = req.query.subjectCode ?? "";
|
|
38168
38618
|
const isPageNumber = isFinite(page);
|
|
38169
38619
|
if (!isPageNumber) {
|
|
38170
|
-
next(new
|
|
38620
|
+
next(new import_nodejs_utils51.BadRequestError("Invalid page number."));
|
|
38171
38621
|
return;
|
|
38172
38622
|
}
|
|
38173
38623
|
const isLimitNumber = isFinite(limit);
|
|
38174
38624
|
if (!isLimitNumber) {
|
|
38175
|
-
next(new
|
|
38625
|
+
next(new import_nodejs_utils51.BadRequestError("Invalid limit number."));
|
|
38176
38626
|
return;
|
|
38177
38627
|
}
|
|
38178
38628
|
if (error) {
|
|
38179
|
-
next(new
|
|
38629
|
+
next(new import_nodejs_utils51.BadRequestError(error.message));
|
|
38180
38630
|
return;
|
|
38181
38631
|
}
|
|
38182
38632
|
try {
|
|
@@ -38186,8 +38636,11 @@ function useSectionController() {
|
|
|
38186
38636
|
search,
|
|
38187
38637
|
status,
|
|
38188
38638
|
school,
|
|
38639
|
+
section,
|
|
38640
|
+
teacher,
|
|
38189
38641
|
schoolYear,
|
|
38190
|
-
gradeLevel
|
|
38642
|
+
gradeLevel,
|
|
38643
|
+
subjectCode
|
|
38191
38644
|
});
|
|
38192
38645
|
res.json(data);
|
|
38193
38646
|
return;
|
|
@@ -38197,18 +38650,386 @@ function useSectionController() {
|
|
|
38197
38650
|
}
|
|
38198
38651
|
async function getById(req, res, next) {
|
|
38199
38652
|
const id = req.params.id;
|
|
38200
|
-
const validation =
|
|
38201
|
-
id:
|
|
38653
|
+
const validation = import_joi30.default.object({
|
|
38654
|
+
id: import_joi30.default.string().hex().required()
|
|
38202
38655
|
});
|
|
38203
38656
|
const { error } = validation.validate({ id });
|
|
38204
38657
|
if (error) {
|
|
38205
|
-
next(new
|
|
38658
|
+
next(new import_nodejs_utils51.BadRequestError(error.message));
|
|
38206
38659
|
return;
|
|
38207
38660
|
}
|
|
38208
38661
|
try {
|
|
38209
38662
|
const data = await _getById(id);
|
|
38210
38663
|
res.json({
|
|
38211
|
-
message: "Successfully retrieved section.",
|
|
38664
|
+
message: "Successfully retrieved section subject.",
|
|
38665
|
+
data
|
|
38666
|
+
});
|
|
38667
|
+
return;
|
|
38668
|
+
} catch (error2) {
|
|
38669
|
+
next(error2);
|
|
38670
|
+
}
|
|
38671
|
+
}
|
|
38672
|
+
async function getBySection(req, res, next) {
|
|
38673
|
+
const section = req.params.section;
|
|
38674
|
+
const validation = import_joi30.default.object({
|
|
38675
|
+
section: import_joi30.default.string().hex().required()
|
|
38676
|
+
});
|
|
38677
|
+
const { error } = validation.validate({ section });
|
|
38678
|
+
if (error) {
|
|
38679
|
+
next(new import_nodejs_utils51.BadRequestError(error.message));
|
|
38680
|
+
return;
|
|
38681
|
+
}
|
|
38682
|
+
try {
|
|
38683
|
+
const data = await _getBySection(section);
|
|
38684
|
+
res.json({
|
|
38685
|
+
message: "Successfully retrieved section subjects.",
|
|
38686
|
+
data
|
|
38687
|
+
});
|
|
38688
|
+
return;
|
|
38689
|
+
} catch (error2) {
|
|
38690
|
+
next(error2);
|
|
38691
|
+
}
|
|
38692
|
+
}
|
|
38693
|
+
async function getByTeacher(req, res, next) {
|
|
38694
|
+
const teacher = req.params.teacher;
|
|
38695
|
+
const validation = import_joi30.default.object({
|
|
38696
|
+
teacher: import_joi30.default.string().hex().required()
|
|
38697
|
+
});
|
|
38698
|
+
const { error } = validation.validate({ teacher });
|
|
38699
|
+
if (error) {
|
|
38700
|
+
next(new import_nodejs_utils51.BadRequestError(error.message));
|
|
38701
|
+
return;
|
|
38702
|
+
}
|
|
38703
|
+
try {
|
|
38704
|
+
const data = await _getByTeacher(teacher);
|
|
38705
|
+
res.json({
|
|
38706
|
+
message: "Successfully retrieved section subjects.",
|
|
38707
|
+
data
|
|
38708
|
+
});
|
|
38709
|
+
return;
|
|
38710
|
+
} catch (error2) {
|
|
38711
|
+
next(error2);
|
|
38712
|
+
}
|
|
38713
|
+
}
|
|
38714
|
+
async function getBySchool(req, res, next) {
|
|
38715
|
+
const school = req.params.school;
|
|
38716
|
+
const validation = import_joi30.default.object({
|
|
38717
|
+
school: import_joi30.default.string().hex().required()
|
|
38718
|
+
});
|
|
38719
|
+
const { error } = validation.validate({ school });
|
|
38720
|
+
if (error) {
|
|
38721
|
+
next(new import_nodejs_utils51.BadRequestError(error.message));
|
|
38722
|
+
return;
|
|
38723
|
+
}
|
|
38724
|
+
try {
|
|
38725
|
+
const data = await _getBySchool(school);
|
|
38726
|
+
res.json({
|
|
38727
|
+
message: "Successfully retrieved section subjects.",
|
|
38728
|
+
data
|
|
38729
|
+
});
|
|
38730
|
+
return;
|
|
38731
|
+
} catch (error2) {
|
|
38732
|
+
next(error2);
|
|
38733
|
+
}
|
|
38734
|
+
}
|
|
38735
|
+
async function updateField(req, res, next) {
|
|
38736
|
+
const _id = req.params.id;
|
|
38737
|
+
const { field, value } = req.body;
|
|
38738
|
+
const validation = import_joi30.default.object({
|
|
38739
|
+
_id: import_joi30.default.string().hex().required(),
|
|
38740
|
+
field: import_joi30.default.string().valid(
|
|
38741
|
+
"subjectCode",
|
|
38742
|
+
"subjectName",
|
|
38743
|
+
"teacher",
|
|
38744
|
+
"teacherName",
|
|
38745
|
+
"classroom",
|
|
38746
|
+
"schedule"
|
|
38747
|
+
).required(),
|
|
38748
|
+
value: import_joi30.default.string().required()
|
|
38749
|
+
});
|
|
38750
|
+
const { error } = validation.validate({ _id, field, value });
|
|
38751
|
+
if (error) {
|
|
38752
|
+
next(new import_nodejs_utils51.BadRequestError(error.message));
|
|
38753
|
+
return;
|
|
38754
|
+
}
|
|
38755
|
+
try {
|
|
38756
|
+
const message = await _updateFieldById({ _id, field, value });
|
|
38757
|
+
res.json({ message });
|
|
38758
|
+
return;
|
|
38759
|
+
} catch (error2) {
|
|
38760
|
+
next(error2);
|
|
38761
|
+
}
|
|
38762
|
+
}
|
|
38763
|
+
async function setupById(req, res, next) {
|
|
38764
|
+
const _id = req.params.id;
|
|
38765
|
+
const data = req.body;
|
|
38766
|
+
const { error } = schemaSectionSubjectSetup.validate(data);
|
|
38767
|
+
if (error) {
|
|
38768
|
+
next(new import_nodejs_utils51.BadRequestError(error.message));
|
|
38769
|
+
return;
|
|
38770
|
+
}
|
|
38771
|
+
try {
|
|
38772
|
+
const message = await _setupById(_id, data);
|
|
38773
|
+
res.json({ message });
|
|
38774
|
+
return;
|
|
38775
|
+
} catch (error2) {
|
|
38776
|
+
next(error2);
|
|
38777
|
+
}
|
|
38778
|
+
}
|
|
38779
|
+
async function deleteById(req, res, next) {
|
|
38780
|
+
const _id = req.params.id;
|
|
38781
|
+
const validation = import_joi30.default.object({
|
|
38782
|
+
_id: import_joi30.default.string().hex().required()
|
|
38783
|
+
});
|
|
38784
|
+
const { error } = validation.validate({ _id });
|
|
38785
|
+
if (error) {
|
|
38786
|
+
next(new import_nodejs_utils51.BadRequestError(error.message));
|
|
38787
|
+
return;
|
|
38788
|
+
}
|
|
38789
|
+
try {
|
|
38790
|
+
const message = await _deleteById(_id);
|
|
38791
|
+
res.json({ message });
|
|
38792
|
+
return;
|
|
38793
|
+
} catch (error2) {
|
|
38794
|
+
next(error2);
|
|
38795
|
+
}
|
|
38796
|
+
}
|
|
38797
|
+
return {
|
|
38798
|
+
add,
|
|
38799
|
+
getAll,
|
|
38800
|
+
getById,
|
|
38801
|
+
getBySection,
|
|
38802
|
+
getByTeacher,
|
|
38803
|
+
getBySchool,
|
|
38804
|
+
updateField,
|
|
38805
|
+
setupById,
|
|
38806
|
+
deleteById
|
|
38807
|
+
};
|
|
38808
|
+
}
|
|
38809
|
+
|
|
38810
|
+
// src/resources/section/section.service.ts
|
|
38811
|
+
function useSectionService() {
|
|
38812
|
+
const { getCountByGradeLevel, getByGradeLevel: getLeanerByGradeLevel } = useLearnerRepo();
|
|
38813
|
+
const { getByGradeLevel } = useGradeLevelRepo();
|
|
38814
|
+
const { add: createSection } = useSectionRepo();
|
|
38815
|
+
const { add: assignStudent } = useSectionStudentRepo();
|
|
38816
|
+
const { getAll: getAllCurriculumSubjects } = useCurriculumSubjectRepo();
|
|
38817
|
+
const { add: addSectionSubject } = useSectionSubjectRepo();
|
|
38818
|
+
function distributeStudents(total, minPer, maxPer) {
|
|
38819
|
+
if (total <= 0)
|
|
38820
|
+
return [];
|
|
38821
|
+
if (minPer <= 0 || maxPer <= 0)
|
|
38822
|
+
return [];
|
|
38823
|
+
if (minPer > maxPer) {
|
|
38824
|
+
throw new import_nodejs_utils52.BadRequestError(
|
|
38825
|
+
"Minimum students per section cannot be greater than maximum."
|
|
38826
|
+
);
|
|
38827
|
+
}
|
|
38828
|
+
const minSections = Math.ceil(total / maxPer);
|
|
38829
|
+
const maxSections = Math.floor(total / minPer);
|
|
38830
|
+
let sectionCount;
|
|
38831
|
+
if (minSections <= maxSections) {
|
|
38832
|
+
sectionCount = minSections;
|
|
38833
|
+
} else {
|
|
38834
|
+
sectionCount = minSections;
|
|
38835
|
+
}
|
|
38836
|
+
const base = Math.floor(total / sectionCount);
|
|
38837
|
+
const extra = total % sectionCount;
|
|
38838
|
+
const sizes = new Array(sectionCount).fill(base);
|
|
38839
|
+
for (let i = 0; i < extra; i++) {
|
|
38840
|
+
sizes[i] += 1;
|
|
38841
|
+
}
|
|
38842
|
+
for (const size of sizes) {
|
|
38843
|
+
if (size > maxPer) {
|
|
38844
|
+
throw new import_nodejs_utils52.BadRequestError(
|
|
38845
|
+
`Generated section exceeds max limit of ${maxPer}.`
|
|
38846
|
+
);
|
|
38847
|
+
}
|
|
38848
|
+
}
|
|
38849
|
+
return sizes;
|
|
38850
|
+
}
|
|
38851
|
+
async function generateSections(value) {
|
|
38852
|
+
const { error } = schemaGenerateSections.validate(value);
|
|
38853
|
+
if (error) {
|
|
38854
|
+
throw new import_nodejs_utils52.BadRequestError(
|
|
38855
|
+
`Invalid section generation data: ${error.message}`
|
|
38856
|
+
);
|
|
38857
|
+
}
|
|
38858
|
+
const session = import_nodejs_utils52.useAtlas.getClient()?.startSession();
|
|
38859
|
+
if (!session) {
|
|
38860
|
+
throw new Error("Unable to start database session.");
|
|
38861
|
+
}
|
|
38862
|
+
try {
|
|
38863
|
+
await session.startTransaction();
|
|
38864
|
+
const studentCount = await getCountByGradeLevel(
|
|
38865
|
+
{
|
|
38866
|
+
school: value.school,
|
|
38867
|
+
schoolYear: value.schoolYear,
|
|
38868
|
+
gradeLevel: value.gradeLevel
|
|
38869
|
+
},
|
|
38870
|
+
session
|
|
38871
|
+
);
|
|
38872
|
+
if (studentCount === 0) {
|
|
38873
|
+
throw new import_nodejs_utils52.BadRequestError("No learners found for this grade level.");
|
|
38874
|
+
}
|
|
38875
|
+
const gradeLevelData = await getByGradeLevel(
|
|
38876
|
+
{
|
|
38877
|
+
school: value.school,
|
|
38878
|
+
gradeLevel: value.gradeLevel
|
|
38879
|
+
},
|
|
38880
|
+
session
|
|
38881
|
+
);
|
|
38882
|
+
if (!gradeLevelData) {
|
|
38883
|
+
throw new import_nodejs_utils52.BadRequestError("Grade level not found.");
|
|
38884
|
+
}
|
|
38885
|
+
const minPerSection = gradeLevelData.minNumberOfLearners;
|
|
38886
|
+
const maxPerSection = gradeLevelData.maxNumberOfLearners;
|
|
38887
|
+
const sectionsNeeded = Math.ceil(studentCount / minPerSection);
|
|
38888
|
+
if (sectionsNeeded > value.set.length) {
|
|
38889
|
+
throw new import_nodejs_utils52.BadRequestError(
|
|
38890
|
+
"Insufficient number of section names in set[]."
|
|
38891
|
+
);
|
|
38892
|
+
}
|
|
38893
|
+
const sectionSizes = distributeStudents(
|
|
38894
|
+
studentCount,
|
|
38895
|
+
minPerSection,
|
|
38896
|
+
maxPerSection
|
|
38897
|
+
);
|
|
38898
|
+
if (sectionSizes.length === 0) {
|
|
38899
|
+
throw new import_nodejs_utils52.BadRequestError("Unable to compute section sizes.");
|
|
38900
|
+
}
|
|
38901
|
+
let totalStudentsProcessed = 0;
|
|
38902
|
+
for (let i = 0; i < sectionSizes.length; i++) {
|
|
38903
|
+
const size = sectionSizes[i];
|
|
38904
|
+
const sectionName = value.set[i];
|
|
38905
|
+
const section = await createSection(
|
|
38906
|
+
{
|
|
38907
|
+
school: value.school,
|
|
38908
|
+
schoolYear: value.schoolYear,
|
|
38909
|
+
gradeLevel: value.gradeLevel,
|
|
38910
|
+
name: sectionName,
|
|
38911
|
+
students: size
|
|
38912
|
+
},
|
|
38913
|
+
session
|
|
38914
|
+
);
|
|
38915
|
+
const skip = totalStudentsProcessed;
|
|
38916
|
+
const learners = await getLeanerByGradeLevel(
|
|
38917
|
+
{
|
|
38918
|
+
school: value.school,
|
|
38919
|
+
gradeLevel: value.gradeLevel,
|
|
38920
|
+
skip,
|
|
38921
|
+
limit: size
|
|
38922
|
+
},
|
|
38923
|
+
session
|
|
38924
|
+
);
|
|
38925
|
+
if (!learners.length) {
|
|
38926
|
+
throw new import_nodejs_utils52.BadRequestError(`No learners found for section #${i + 1}.`);
|
|
38927
|
+
}
|
|
38928
|
+
totalStudentsProcessed += learners.length;
|
|
38929
|
+
for (const student of learners) {
|
|
38930
|
+
if (!student._id) {
|
|
38931
|
+
throw new import_nodejs_utils52.BadRequestError("Learner ID is missing.");
|
|
38932
|
+
}
|
|
38933
|
+
await assignStudent(
|
|
38934
|
+
{
|
|
38935
|
+
section: section.toString(),
|
|
38936
|
+
student: student._id?.toString(),
|
|
38937
|
+
studentName: `${student.learnerInfo.firstName} ${student.learnerInfo.lastName}`,
|
|
38938
|
+
status: "active"
|
|
38939
|
+
},
|
|
38940
|
+
session
|
|
38941
|
+
);
|
|
38942
|
+
}
|
|
38943
|
+
const curriculumSubjects = await getAllCurriculumSubjects({
|
|
38944
|
+
schoolYear: Number(value.schoolYear),
|
|
38945
|
+
gradeLevel: value.gradeLevel,
|
|
38946
|
+
limit: 20
|
|
38947
|
+
});
|
|
38948
|
+
for (const curriculumSubject of curriculumSubjects.items) {
|
|
38949
|
+
await addSectionSubject(
|
|
38950
|
+
{
|
|
38951
|
+
school: value.school,
|
|
38952
|
+
schoolName: "",
|
|
38953
|
+
gradeLevel: value.gradeLevel,
|
|
38954
|
+
educationLevel: gradeLevelData.educationLevel,
|
|
38955
|
+
schoolYear: value.schoolYear,
|
|
38956
|
+
section: section.toString(),
|
|
38957
|
+
sectionName,
|
|
38958
|
+
subjectCode: curriculumSubject.subjectCode,
|
|
38959
|
+
subjectName: curriculumSubject.subjectName,
|
|
38960
|
+
teacher: "",
|
|
38961
|
+
teacherName: "",
|
|
38962
|
+
schedule: "",
|
|
38963
|
+
daysOfWeek: [],
|
|
38964
|
+
classroom: "",
|
|
38965
|
+
classroomName: "",
|
|
38966
|
+
sessionDuration: curriculumSubject.sessionDuration,
|
|
38967
|
+
sessionFrequency: curriculumSubject.sessionFrequency,
|
|
38968
|
+
status: "draft"
|
|
38969
|
+
},
|
|
38970
|
+
session
|
|
38971
|
+
);
|
|
38972
|
+
}
|
|
38973
|
+
}
|
|
38974
|
+
await session.commitTransaction();
|
|
38975
|
+
return "Sections generated successfully.";
|
|
38976
|
+
} catch (error2) {
|
|
38977
|
+
await session.abortTransaction();
|
|
38978
|
+
if (error2 instanceof import_nodejs_utils52.AppError) {
|
|
38979
|
+
throw error2;
|
|
38980
|
+
} else {
|
|
38981
|
+
throw new import_nodejs_utils52.InternalServerError("Failed to generate sections.");
|
|
38982
|
+
}
|
|
38983
|
+
} finally {
|
|
38984
|
+
await session?.endSession();
|
|
38985
|
+
}
|
|
38986
|
+
}
|
|
38987
|
+
return { generateSections };
|
|
38988
|
+
}
|
|
38989
|
+
|
|
38990
|
+
// src/resources/section/section.controller.ts
|
|
38991
|
+
function useSectionController() {
|
|
38992
|
+
const {
|
|
38993
|
+
add: _add,
|
|
38994
|
+
getAll: _getAll,
|
|
38995
|
+
getById: _getById,
|
|
38996
|
+
getByName: _getByName,
|
|
38997
|
+
getBySchool: _getBySchool,
|
|
38998
|
+
updateFieldById: _updateFieldById,
|
|
38999
|
+
addStudentToSection: _addStudentToSection,
|
|
39000
|
+
removeStudentFromSection: _removeStudentFromSection,
|
|
39001
|
+
deleteById: _deleteById
|
|
39002
|
+
} = useSectionRepo();
|
|
39003
|
+
const { generateSections: _generateSections } = useSectionService();
|
|
39004
|
+
async function add(req, res, next) {
|
|
39005
|
+
const value = req.body;
|
|
39006
|
+
const { error } = schemaSection.validate(value);
|
|
39007
|
+
if (error) {
|
|
39008
|
+
next(new import_nodejs_utils53.BadRequestError(error.message));
|
|
39009
|
+
return;
|
|
39010
|
+
}
|
|
39011
|
+
try {
|
|
39012
|
+
const data = await _add(value);
|
|
39013
|
+
res.json({
|
|
39014
|
+
message: "Successfully created section.",
|
|
39015
|
+
data
|
|
39016
|
+
});
|
|
39017
|
+
return;
|
|
39018
|
+
} catch (error2) {
|
|
39019
|
+
next(error2);
|
|
39020
|
+
}
|
|
39021
|
+
}
|
|
39022
|
+
async function generateSections(req, res, next) {
|
|
39023
|
+
const value = req.body;
|
|
39024
|
+
const { error } = schemaGenerateSections.validate(value);
|
|
39025
|
+
if (error) {
|
|
39026
|
+
next(new import_nodejs_utils53.BadRequestError(error.message));
|
|
39027
|
+
return;
|
|
39028
|
+
}
|
|
39029
|
+
try {
|
|
39030
|
+
const data = await _generateSections(value);
|
|
39031
|
+
res.json({
|
|
39032
|
+
message: "Successfully created section.",
|
|
38212
39033
|
data
|
|
38213
39034
|
});
|
|
38214
39035
|
return;
|
|
@@ -38216,14 +39037,81 @@ function useSectionController() {
|
|
|
38216
39037
|
next(error2);
|
|
38217
39038
|
}
|
|
38218
39039
|
}
|
|
39040
|
+
async function getAll(req, res, next) {
|
|
39041
|
+
const query = req.query;
|
|
39042
|
+
const validation = import_joi31.default.object({
|
|
39043
|
+
page: import_joi31.default.number().min(1).optional().allow("", null),
|
|
39044
|
+
limit: import_joi31.default.number().min(1).optional().allow("", null),
|
|
39045
|
+
search: import_joi31.default.string().optional().allow("", null),
|
|
39046
|
+
status: import_joi31.default.string().optional().allow("", null),
|
|
39047
|
+
school: import_joi31.default.string().hex().optional().allow("", null),
|
|
39048
|
+
schoolYear: import_joi31.default.string().optional().allow("", null),
|
|
39049
|
+
gradeLevel: import_joi31.default.string().optional().allow("", null)
|
|
39050
|
+
});
|
|
39051
|
+
const { error } = validation.validate(query);
|
|
39052
|
+
const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
|
|
39053
|
+
const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
|
|
39054
|
+
const search = req.query.search ?? "";
|
|
39055
|
+
const status = req.query.status ?? "active";
|
|
39056
|
+
const school = req.query.school ?? "";
|
|
39057
|
+
const schoolYear = req.query.schoolYear ?? "";
|
|
39058
|
+
const gradeLevel = req.query.gradeLevel ?? "";
|
|
39059
|
+
const isPageNumber = isFinite(page);
|
|
39060
|
+
if (!isPageNumber) {
|
|
39061
|
+
next(new import_nodejs_utils53.BadRequestError("Invalid page number."));
|
|
39062
|
+
return;
|
|
39063
|
+
}
|
|
39064
|
+
const isLimitNumber = isFinite(limit);
|
|
39065
|
+
if (!isLimitNumber) {
|
|
39066
|
+
next(new import_nodejs_utils53.BadRequestError("Invalid limit number."));
|
|
39067
|
+
return;
|
|
39068
|
+
}
|
|
39069
|
+
if (error) {
|
|
39070
|
+
next(new import_nodejs_utils53.BadRequestError(error.message));
|
|
39071
|
+
return;
|
|
39072
|
+
}
|
|
39073
|
+
try {
|
|
39074
|
+
const data = await _getAll({
|
|
39075
|
+
page,
|
|
39076
|
+
limit,
|
|
39077
|
+
search,
|
|
39078
|
+
status,
|
|
39079
|
+
school,
|
|
39080
|
+
schoolYear,
|
|
39081
|
+
gradeLevel
|
|
39082
|
+
});
|
|
39083
|
+
res.json(data);
|
|
39084
|
+
return;
|
|
39085
|
+
} catch (error2) {
|
|
39086
|
+
next(error2);
|
|
39087
|
+
}
|
|
39088
|
+
}
|
|
39089
|
+
async function getById(req, res, next) {
|
|
39090
|
+
const id = req.params.id;
|
|
39091
|
+
const validation = import_joi31.default.object({
|
|
39092
|
+
id: import_joi31.default.string().hex().required()
|
|
39093
|
+
});
|
|
39094
|
+
const { error } = validation.validate({ id });
|
|
39095
|
+
if (error) {
|
|
39096
|
+
next(new import_nodejs_utils53.BadRequestError(error.message));
|
|
39097
|
+
return;
|
|
39098
|
+
}
|
|
39099
|
+
try {
|
|
39100
|
+
const data = await _getById(id);
|
|
39101
|
+
res.json(data);
|
|
39102
|
+
return;
|
|
39103
|
+
} catch (error2) {
|
|
39104
|
+
next(error2);
|
|
39105
|
+
}
|
|
39106
|
+
}
|
|
38219
39107
|
async function getByName(req, res, next) {
|
|
38220
39108
|
const name = req.params.name;
|
|
38221
|
-
const validation =
|
|
38222
|
-
name:
|
|
39109
|
+
const validation = import_joi31.default.object({
|
|
39110
|
+
name: import_joi31.default.string().required()
|
|
38223
39111
|
});
|
|
38224
39112
|
const { error } = validation.validate({ name });
|
|
38225
39113
|
if (error) {
|
|
38226
|
-
next(new
|
|
39114
|
+
next(new import_nodejs_utils53.BadRequestError(error.message));
|
|
38227
39115
|
return;
|
|
38228
39116
|
}
|
|
38229
39117
|
try {
|
|
@@ -38239,12 +39127,12 @@ function useSectionController() {
|
|
|
38239
39127
|
}
|
|
38240
39128
|
async function getBySchool(req, res, next) {
|
|
38241
39129
|
const school = req.params.school;
|
|
38242
|
-
const validation =
|
|
38243
|
-
school:
|
|
39130
|
+
const validation = import_joi31.default.object({
|
|
39131
|
+
school: import_joi31.default.string().hex().required()
|
|
38244
39132
|
});
|
|
38245
39133
|
const { error } = validation.validate({ school });
|
|
38246
39134
|
if (error) {
|
|
38247
|
-
next(new
|
|
39135
|
+
next(new import_nodejs_utils53.BadRequestError(error.message));
|
|
38248
39136
|
return;
|
|
38249
39137
|
}
|
|
38250
39138
|
try {
|
|
@@ -38261,14 +39149,14 @@ function useSectionController() {
|
|
|
38261
39149
|
async function updateField(req, res, next) {
|
|
38262
39150
|
const _id = req.params.id;
|
|
38263
39151
|
const { field, value } = req.body;
|
|
38264
|
-
const validation =
|
|
38265
|
-
_id:
|
|
38266
|
-
field:
|
|
38267
|
-
value:
|
|
39152
|
+
const validation = import_joi31.default.object({
|
|
39153
|
+
_id: import_joi31.default.string().hex().required(),
|
|
39154
|
+
field: import_joi31.default.string().valid("name", "schoolYear", "gradeLevel", "adviser", "adviserName").required(),
|
|
39155
|
+
value: import_joi31.default.string().required()
|
|
38268
39156
|
});
|
|
38269
39157
|
const { error } = validation.validate({ _id, field, value });
|
|
38270
39158
|
if (error) {
|
|
38271
|
-
next(new
|
|
39159
|
+
next(new import_nodejs_utils53.BadRequestError(error.message));
|
|
38272
39160
|
return;
|
|
38273
39161
|
}
|
|
38274
39162
|
try {
|
|
@@ -38282,13 +39170,13 @@ function useSectionController() {
|
|
|
38282
39170
|
async function addStudent(req, res, next) {
|
|
38283
39171
|
const _id = req.params.id;
|
|
38284
39172
|
const { studentId } = req.body;
|
|
38285
|
-
const validation =
|
|
38286
|
-
_id:
|
|
38287
|
-
studentId:
|
|
39173
|
+
const validation = import_joi31.default.object({
|
|
39174
|
+
_id: import_joi31.default.string().hex().required(),
|
|
39175
|
+
studentId: import_joi31.default.string().required()
|
|
38288
39176
|
});
|
|
38289
39177
|
const { error } = validation.validate({ _id, studentId });
|
|
38290
39178
|
if (error) {
|
|
38291
|
-
next(new
|
|
39179
|
+
next(new import_nodejs_utils53.BadRequestError(error.message));
|
|
38292
39180
|
return;
|
|
38293
39181
|
}
|
|
38294
39182
|
try {
|
|
@@ -38302,13 +39190,13 @@ function useSectionController() {
|
|
|
38302
39190
|
async function removeStudent(req, res, next) {
|
|
38303
39191
|
const _id = req.params.id;
|
|
38304
39192
|
const { studentId } = req.body;
|
|
38305
|
-
const validation =
|
|
38306
|
-
_id:
|
|
38307
|
-
studentId:
|
|
39193
|
+
const validation = import_joi31.default.object({
|
|
39194
|
+
_id: import_joi31.default.string().hex().required(),
|
|
39195
|
+
studentId: import_joi31.default.string().required()
|
|
38308
39196
|
});
|
|
38309
39197
|
const { error } = validation.validate({ _id, studentId });
|
|
38310
39198
|
if (error) {
|
|
38311
|
-
next(new
|
|
39199
|
+
next(new import_nodejs_utils53.BadRequestError(error.message));
|
|
38312
39200
|
return;
|
|
38313
39201
|
}
|
|
38314
39202
|
try {
|
|
@@ -38321,12 +39209,12 @@ function useSectionController() {
|
|
|
38321
39209
|
}
|
|
38322
39210
|
async function deleteById(req, res, next) {
|
|
38323
39211
|
const _id = req.params.id;
|
|
38324
|
-
const validation =
|
|
38325
|
-
_id:
|
|
39212
|
+
const validation = import_joi31.default.object({
|
|
39213
|
+
_id: import_joi31.default.string().hex().required()
|
|
38326
39214
|
});
|
|
38327
39215
|
const { error } = validation.validate({ _id });
|
|
38328
39216
|
if (error) {
|
|
38329
|
-
next(new
|
|
39217
|
+
next(new import_nodejs_utils53.BadRequestError(error.message));
|
|
38330
39218
|
return;
|
|
38331
39219
|
}
|
|
38332
39220
|
try {
|
|
@@ -38351,16 +39239,1692 @@ function useSectionController() {
|
|
|
38351
39239
|
};
|
|
38352
39240
|
}
|
|
38353
39241
|
|
|
39242
|
+
// src/resources/building/building.model.ts
|
|
39243
|
+
var import_nodejs_utils54 = require("@eeplatform/nodejs-utils");
|
|
39244
|
+
var import_joi32 = __toESM(require("joi"));
|
|
39245
|
+
var import_mongodb30 = require("mongodb");
|
|
39246
|
+
var schemaBuilding = import_joi32.default.object({
|
|
39247
|
+
_id: import_joi32.default.string().hex().optional(),
|
|
39248
|
+
school: import_joi32.default.string().hex().required(),
|
|
39249
|
+
serial: import_joi32.default.string().optional().allow("", null),
|
|
39250
|
+
name: import_joi32.default.string().required(),
|
|
39251
|
+
levels: import_joi32.default.number().integer().min(1).required(),
|
|
39252
|
+
createdAt: import_joi32.default.date().optional().allow("", null),
|
|
39253
|
+
updatedAt: import_joi32.default.date().optional().allow("", null),
|
|
39254
|
+
deletedAt: import_joi32.default.date().optional().allow("", null),
|
|
39255
|
+
status: import_joi32.default.string().optional().allow("", null)
|
|
39256
|
+
});
|
|
39257
|
+
var schemaBuildingUnit = import_joi32.default.object({
|
|
39258
|
+
_id: import_joi32.default.string().hex().optional(),
|
|
39259
|
+
school: import_joi32.default.string().hex().required(),
|
|
39260
|
+
name: import_joi32.default.string().optional().allow("", null),
|
|
39261
|
+
building: import_joi32.default.string().hex().required(),
|
|
39262
|
+
buildingName: import_joi32.default.string().optional().allow("", null),
|
|
39263
|
+
level: import_joi32.default.number().integer().min(1).required(),
|
|
39264
|
+
category: import_joi32.default.string().required(),
|
|
39265
|
+
type: import_joi32.default.string().required(),
|
|
39266
|
+
seating_capacity: import_joi32.default.number().integer().min(0).required(),
|
|
39267
|
+
standing_capacity: import_joi32.default.number().integer().min(0).required(),
|
|
39268
|
+
description: import_joi32.default.string().optional().allow("", null),
|
|
39269
|
+
unit_of_measurement: import_joi32.default.string().valid("sqm").required(),
|
|
39270
|
+
area: import_joi32.default.number().positive().required(),
|
|
39271
|
+
status: import_joi32.default.string().optional().allow("", null)
|
|
39272
|
+
});
|
|
39273
|
+
var schemaUpdateOptions = import_joi32.default.object({
|
|
39274
|
+
name: import_joi32.default.string().optional().allow("", null),
|
|
39275
|
+
building: import_joi32.default.string().hex().optional().allow("", null),
|
|
39276
|
+
buildingName: import_joi32.default.string().optional().allow("", null),
|
|
39277
|
+
level: import_joi32.default.number().integer().min(1).optional().allow("", null),
|
|
39278
|
+
category: import_joi32.default.string().optional().allow("", null),
|
|
39279
|
+
type: import_joi32.default.string().optional().allow("", null),
|
|
39280
|
+
seating_capacity: import_joi32.default.number().integer().min(0).optional().allow("", null),
|
|
39281
|
+
standing_capacity: import_joi32.default.number().integer().min(0).optional().allow("", null),
|
|
39282
|
+
area: import_joi32.default.number().positive().optional().allow("", null)
|
|
39283
|
+
});
|
|
39284
|
+
function MBuilding(value) {
|
|
39285
|
+
const { error } = schemaBuilding.validate(value);
|
|
39286
|
+
if (error) {
|
|
39287
|
+
import_nodejs_utils54.logger.info(`Building Model: ${error.message}`);
|
|
39288
|
+
throw new import_nodejs_utils54.BadRequestError(error.message);
|
|
39289
|
+
}
|
|
39290
|
+
if (value._id && typeof value._id === "string") {
|
|
39291
|
+
try {
|
|
39292
|
+
value._id = new import_mongodb30.ObjectId(value._id);
|
|
39293
|
+
} catch (error2) {
|
|
39294
|
+
throw new import_nodejs_utils54.BadRequestError("Invalid _id format");
|
|
39295
|
+
}
|
|
39296
|
+
}
|
|
39297
|
+
try {
|
|
39298
|
+
value.school = new import_mongodb30.ObjectId(value.school);
|
|
39299
|
+
} catch (error2) {
|
|
39300
|
+
throw new import_nodejs_utils54.BadRequestError("Invalid school format");
|
|
39301
|
+
}
|
|
39302
|
+
return {
|
|
39303
|
+
_id: value._id ?? void 0,
|
|
39304
|
+
school: value.school,
|
|
39305
|
+
serial: value.serial ?? "",
|
|
39306
|
+
name: value.name ?? "",
|
|
39307
|
+
levels: value.levels ?? 0,
|
|
39308
|
+
status: value.status ?? "active",
|
|
39309
|
+
createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
|
|
39310
|
+
updatedAt: value.updatedAt ?? "",
|
|
39311
|
+
deletedAt: value.deletedAt ?? ""
|
|
39312
|
+
};
|
|
39313
|
+
}
|
|
39314
|
+
function MBuildingUnit(value) {
|
|
39315
|
+
const { error } = schemaBuildingUnit.validate(value);
|
|
39316
|
+
if (error) {
|
|
39317
|
+
import_nodejs_utils54.logger.info(`Building Unit Model: ${error.message}`);
|
|
39318
|
+
throw new import_nodejs_utils54.BadRequestError(error.message);
|
|
39319
|
+
}
|
|
39320
|
+
if (value._id && typeof value._id === "string") {
|
|
39321
|
+
try {
|
|
39322
|
+
value._id = new import_mongodb30.ObjectId(value._id);
|
|
39323
|
+
} catch (error2) {
|
|
39324
|
+
throw new import_nodejs_utils54.BadRequestError("Invalid ID");
|
|
39325
|
+
}
|
|
39326
|
+
}
|
|
39327
|
+
try {
|
|
39328
|
+
value.school = new import_mongodb30.ObjectId(value.school);
|
|
39329
|
+
} catch (error2) {
|
|
39330
|
+
throw new import_nodejs_utils54.BadRequestError("Invalid school ID");
|
|
39331
|
+
}
|
|
39332
|
+
try {
|
|
39333
|
+
value.building = new import_mongodb30.ObjectId(value.building);
|
|
39334
|
+
} catch (error2) {
|
|
39335
|
+
throw new import_nodejs_utils54.BadRequestError("Invalid building ID");
|
|
39336
|
+
}
|
|
39337
|
+
return {
|
|
39338
|
+
_id: value._id ?? void 0,
|
|
39339
|
+
school: value.school,
|
|
39340
|
+
name: value.name ?? "",
|
|
39341
|
+
building: value.building,
|
|
39342
|
+
buildingName: value.buildingName ?? "",
|
|
39343
|
+
level: value.level ?? 0,
|
|
39344
|
+
category: value.category ?? "",
|
|
39345
|
+
type: value.type ?? "",
|
|
39346
|
+
seating_capacity: value.seating_capacity ?? 0,
|
|
39347
|
+
standing_capacity: value.standing_capacity ?? 0,
|
|
39348
|
+
description: value.description ?? "",
|
|
39349
|
+
unit_of_measurement: value.unit_of_measurement ?? "sqm",
|
|
39350
|
+
area: value.area ?? 0,
|
|
39351
|
+
status: value.status ?? "active",
|
|
39352
|
+
createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
|
|
39353
|
+
updatedAt: value.updatedAt ?? "",
|
|
39354
|
+
deletedAt: value.deletedAt ?? ""
|
|
39355
|
+
};
|
|
39356
|
+
}
|
|
39357
|
+
|
|
39358
|
+
// src/resources/building/building.repository.ts
|
|
39359
|
+
var import_nodejs_utils55 = require("@eeplatform/nodejs-utils");
|
|
39360
|
+
var import_mongodb31 = require("mongodb");
|
|
39361
|
+
function useBuildingRepo() {
|
|
39362
|
+
const db = import_nodejs_utils55.useAtlas.getDb();
|
|
39363
|
+
if (!db) {
|
|
39364
|
+
throw new Error("Unable to connect to server.");
|
|
39365
|
+
}
|
|
39366
|
+
const namespace_collection = "school.buildings";
|
|
39367
|
+
const collection = db.collection(namespace_collection);
|
|
39368
|
+
const { getCache, setCache, delNamespace } = (0, import_nodejs_utils55.useCache)(namespace_collection);
|
|
39369
|
+
async function createIndexes() {
|
|
39370
|
+
try {
|
|
39371
|
+
await collection.createIndexes([
|
|
39372
|
+
{ key: { name: 1 }, unique: true, name: "unique_name_index" },
|
|
39373
|
+
{ key: { school: 1 } },
|
|
39374
|
+
{ key: { status: 1 } }
|
|
39375
|
+
]);
|
|
39376
|
+
} catch (error) {
|
|
39377
|
+
throw new Error("Failed to create index on buildings.");
|
|
39378
|
+
}
|
|
39379
|
+
}
|
|
39380
|
+
async function add(value, session) {
|
|
39381
|
+
try {
|
|
39382
|
+
value = MBuilding(value);
|
|
39383
|
+
const res = await collection.insertOne(value, { session });
|
|
39384
|
+
delCachedData();
|
|
39385
|
+
return res.insertedId;
|
|
39386
|
+
} catch (error) {
|
|
39387
|
+
import_nodejs_utils55.logger.log({
|
|
39388
|
+
level: "error",
|
|
39389
|
+
message: error.message
|
|
39390
|
+
});
|
|
39391
|
+
if (error instanceof import_nodejs_utils55.AppError) {
|
|
39392
|
+
throw error;
|
|
39393
|
+
} else {
|
|
39394
|
+
const isDuplicated = error.message.includes("duplicate");
|
|
39395
|
+
if (isDuplicated) {
|
|
39396
|
+
throw new import_nodejs_utils55.BadRequestError("Building already exists.");
|
|
39397
|
+
}
|
|
39398
|
+
throw new Error("Failed to create building.");
|
|
39399
|
+
}
|
|
39400
|
+
}
|
|
39401
|
+
}
|
|
39402
|
+
async function updateById(_id, value, session) {
|
|
39403
|
+
try {
|
|
39404
|
+
_id = new import_mongodb31.ObjectId(_id);
|
|
39405
|
+
} catch (error) {
|
|
39406
|
+
throw new import_nodejs_utils55.BadRequestError("Invalid ID.");
|
|
39407
|
+
}
|
|
39408
|
+
try {
|
|
39409
|
+
const res = await collection.updateOne(
|
|
39410
|
+
{ _id },
|
|
39411
|
+
{ $set: value },
|
|
39412
|
+
{ session }
|
|
39413
|
+
);
|
|
39414
|
+
delCachedData();
|
|
39415
|
+
return res;
|
|
39416
|
+
} catch (error) {
|
|
39417
|
+
import_nodejs_utils55.logger.log({
|
|
39418
|
+
level: "error",
|
|
39419
|
+
message: error.message
|
|
39420
|
+
});
|
|
39421
|
+
if (error instanceof import_nodejs_utils55.AppError) {
|
|
39422
|
+
throw error;
|
|
39423
|
+
} else {
|
|
39424
|
+
throw new Error("Failed to update building.");
|
|
39425
|
+
}
|
|
39426
|
+
}
|
|
39427
|
+
}
|
|
39428
|
+
async function getAll({
|
|
39429
|
+
search = "",
|
|
39430
|
+
page = 1,
|
|
39431
|
+
limit = 10,
|
|
39432
|
+
sort = {},
|
|
39433
|
+
school = "",
|
|
39434
|
+
status = "active"
|
|
39435
|
+
} = {}) {
|
|
39436
|
+
page = page > 0 ? page - 1 : 0;
|
|
39437
|
+
const query = {
|
|
39438
|
+
status
|
|
39439
|
+
};
|
|
39440
|
+
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
39441
|
+
if (search) {
|
|
39442
|
+
query.$text = { $search: search };
|
|
39443
|
+
}
|
|
39444
|
+
if (school) {
|
|
39445
|
+
try {
|
|
39446
|
+
query.school = new import_mongodb31.ObjectId(school);
|
|
39447
|
+
} catch (error) {
|
|
39448
|
+
throw new import_nodejs_utils55.BadRequestError("Invalid school ID.");
|
|
39449
|
+
}
|
|
39450
|
+
}
|
|
39451
|
+
const cacheParams = {
|
|
39452
|
+
page,
|
|
39453
|
+
limit,
|
|
39454
|
+
sort: JSON.stringify(sort)
|
|
39455
|
+
};
|
|
39456
|
+
if (search)
|
|
39457
|
+
cacheParams.search = search;
|
|
39458
|
+
if (school)
|
|
39459
|
+
cacheParams.school = school;
|
|
39460
|
+
if (status !== "active")
|
|
39461
|
+
cacheParams.status = status;
|
|
39462
|
+
const cacheKey = (0, import_nodejs_utils55.makeCacheKey)(namespace_collection, cacheParams);
|
|
39463
|
+
import_nodejs_utils55.logger.log({
|
|
39464
|
+
level: "info",
|
|
39465
|
+
message: `Cache key for getAll buildings: ${cacheKey}`
|
|
39466
|
+
});
|
|
39467
|
+
try {
|
|
39468
|
+
const cached = await getCache(cacheKey);
|
|
39469
|
+
if (cached) {
|
|
39470
|
+
import_nodejs_utils55.logger.log({
|
|
39471
|
+
level: "info",
|
|
39472
|
+
message: `Cache hit for getAll buildings: ${cacheKey}`
|
|
39473
|
+
});
|
|
39474
|
+
return cached;
|
|
39475
|
+
}
|
|
39476
|
+
const items = await collection.aggregate([
|
|
39477
|
+
{ $match: query },
|
|
39478
|
+
{ $sort: sort },
|
|
39479
|
+
{ $skip: page * limit },
|
|
39480
|
+
{ $limit: limit }
|
|
39481
|
+
]).toArray();
|
|
39482
|
+
const length = await collection.countDocuments(query);
|
|
39483
|
+
const data = (0, import_nodejs_utils55.paginate)(items, page, limit, length);
|
|
39484
|
+
setCache(cacheKey, data, 600).then(() => {
|
|
39485
|
+
import_nodejs_utils55.logger.log({
|
|
39486
|
+
level: "info",
|
|
39487
|
+
message: `Cache set for getAll buildings: ${cacheKey}`
|
|
39488
|
+
});
|
|
39489
|
+
}).catch((err) => {
|
|
39490
|
+
import_nodejs_utils55.logger.log({
|
|
39491
|
+
level: "error",
|
|
39492
|
+
message: `Failed to set cache for getAll buildings: ${err.message}`
|
|
39493
|
+
});
|
|
39494
|
+
});
|
|
39495
|
+
return data;
|
|
39496
|
+
} catch (error) {
|
|
39497
|
+
import_nodejs_utils55.logger.log({ level: "error", message: `${error}` });
|
|
39498
|
+
throw error;
|
|
39499
|
+
}
|
|
39500
|
+
}
|
|
39501
|
+
async function getById(_id) {
|
|
39502
|
+
try {
|
|
39503
|
+
_id = new import_mongodb31.ObjectId(_id);
|
|
39504
|
+
} catch (error) {
|
|
39505
|
+
throw new import_nodejs_utils55.BadRequestError("Invalid ID.");
|
|
39506
|
+
}
|
|
39507
|
+
const cacheKey = (0, import_nodejs_utils55.makeCacheKey)(namespace_collection, { _id: String(_id) });
|
|
39508
|
+
try {
|
|
39509
|
+
const cached = await getCache(cacheKey);
|
|
39510
|
+
if (cached) {
|
|
39511
|
+
import_nodejs_utils55.logger.log({
|
|
39512
|
+
level: "info",
|
|
39513
|
+
message: `Cache hit for getById building: ${cacheKey}`
|
|
39514
|
+
});
|
|
39515
|
+
return cached;
|
|
39516
|
+
}
|
|
39517
|
+
const result = await collection.findOne({
|
|
39518
|
+
_id
|
|
39519
|
+
});
|
|
39520
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
39521
|
+
import_nodejs_utils55.logger.log({
|
|
39522
|
+
level: "info",
|
|
39523
|
+
message: `Cache set for building by id: ${cacheKey}`
|
|
39524
|
+
});
|
|
39525
|
+
}).catch((err) => {
|
|
39526
|
+
import_nodejs_utils55.logger.log({
|
|
39527
|
+
level: "error",
|
|
39528
|
+
message: `Failed to set cache for building by id: ${err.message}`
|
|
39529
|
+
});
|
|
39530
|
+
});
|
|
39531
|
+
return result;
|
|
39532
|
+
} catch (error) {
|
|
39533
|
+
if (error instanceof import_nodejs_utils55.AppError) {
|
|
39534
|
+
throw error;
|
|
39535
|
+
} else {
|
|
39536
|
+
throw new import_nodejs_utils55.InternalServerError("Failed to get building.");
|
|
39537
|
+
}
|
|
39538
|
+
}
|
|
39539
|
+
}
|
|
39540
|
+
async function deleteById(_id, session) {
|
|
39541
|
+
try {
|
|
39542
|
+
_id = new import_mongodb31.ObjectId(_id);
|
|
39543
|
+
} catch (error) {
|
|
39544
|
+
throw new import_nodejs_utils55.BadRequestError("Invalid ID.");
|
|
39545
|
+
}
|
|
39546
|
+
try {
|
|
39547
|
+
const res = await collection.updateOne(
|
|
39548
|
+
{ _id },
|
|
39549
|
+
{ $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } }
|
|
39550
|
+
);
|
|
39551
|
+
delCachedData();
|
|
39552
|
+
return res;
|
|
39553
|
+
} catch (error) {
|
|
39554
|
+
import_nodejs_utils55.logger.log({
|
|
39555
|
+
level: "error",
|
|
39556
|
+
message: error.message
|
|
39557
|
+
});
|
|
39558
|
+
if (error instanceof import_nodejs_utils55.AppError) {
|
|
39559
|
+
throw error;
|
|
39560
|
+
} else {
|
|
39561
|
+
throw new import_nodejs_utils55.InternalServerError("Failed to delete building.");
|
|
39562
|
+
}
|
|
39563
|
+
}
|
|
39564
|
+
}
|
|
39565
|
+
function delCachedData() {
|
|
39566
|
+
delNamespace().then(() => {
|
|
39567
|
+
import_nodejs_utils55.logger.log({
|
|
39568
|
+
level: "info",
|
|
39569
|
+
message: `Cache namespace cleared for ${namespace_collection}`
|
|
39570
|
+
});
|
|
39571
|
+
}).catch((err) => {
|
|
39572
|
+
import_nodejs_utils55.logger.log({
|
|
39573
|
+
level: "error",
|
|
39574
|
+
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
39575
|
+
});
|
|
39576
|
+
});
|
|
39577
|
+
}
|
|
39578
|
+
return {
|
|
39579
|
+
createIndexes,
|
|
39580
|
+
add,
|
|
39581
|
+
getAll,
|
|
39582
|
+
getById,
|
|
39583
|
+
updateById,
|
|
39584
|
+
deleteById
|
|
39585
|
+
};
|
|
39586
|
+
}
|
|
39587
|
+
|
|
39588
|
+
// src/resources/building/building.service.ts
|
|
39589
|
+
var import_nodejs_utils57 = require("@eeplatform/nodejs-utils");
|
|
39590
|
+
|
|
39591
|
+
// src/resources/building/building-unit.repository.ts
|
|
39592
|
+
var import_nodejs_utils56 = require("@eeplatform/nodejs-utils");
|
|
39593
|
+
var import_mongodb32 = require("mongodb");
|
|
39594
|
+
function useBuildingUnitRepo() {
|
|
39595
|
+
const db = import_nodejs_utils56.useAtlas.getDb();
|
|
39596
|
+
if (!db) {
|
|
39597
|
+
throw new Error("Unable to connect to server.");
|
|
39598
|
+
}
|
|
39599
|
+
const namespace_collection = "school.building-units";
|
|
39600
|
+
const collection = db.collection(namespace_collection);
|
|
39601
|
+
const { getCache, setCache, delNamespace } = (0, import_nodejs_utils56.useCache)(namespace_collection);
|
|
39602
|
+
async function createIndexes() {
|
|
39603
|
+
try {
|
|
39604
|
+
await collection.createIndexes([
|
|
39605
|
+
{
|
|
39606
|
+
key: { name: 1, building: 1, level: 1 },
|
|
39607
|
+
unique: true,
|
|
39608
|
+
name: "unique_name_index"
|
|
39609
|
+
},
|
|
39610
|
+
{ key: { school: 1 } },
|
|
39611
|
+
{ key: { building: 1 } },
|
|
39612
|
+
{ key: { status: 1 } },
|
|
39613
|
+
{ key: { createdAt: 1 } },
|
|
39614
|
+
{
|
|
39615
|
+
key: {
|
|
39616
|
+
name: "text",
|
|
39617
|
+
buildingName: "text",
|
|
39618
|
+
category: "text",
|
|
39619
|
+
type: "text"
|
|
39620
|
+
}
|
|
39621
|
+
}
|
|
39622
|
+
]);
|
|
39623
|
+
} catch (error) {
|
|
39624
|
+
throw new Error("Failed to create index on building units.");
|
|
39625
|
+
}
|
|
39626
|
+
}
|
|
39627
|
+
function delCachedData() {
|
|
39628
|
+
delNamespace().then(() => {
|
|
39629
|
+
import_nodejs_utils56.logger.log({
|
|
39630
|
+
level: "info",
|
|
39631
|
+
message: `Cache namespace cleared for ${namespace_collection}`
|
|
39632
|
+
});
|
|
39633
|
+
}).catch((err) => {
|
|
39634
|
+
import_nodejs_utils56.logger.log({
|
|
39635
|
+
level: "error",
|
|
39636
|
+
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
39637
|
+
});
|
|
39638
|
+
});
|
|
39639
|
+
}
|
|
39640
|
+
async function add(value, session) {
|
|
39641
|
+
try {
|
|
39642
|
+
value = MBuildingUnit(value);
|
|
39643
|
+
const res = await collection.insertOne(value, { session });
|
|
39644
|
+
delCachedData();
|
|
39645
|
+
return res.insertedId;
|
|
39646
|
+
} catch (error) {
|
|
39647
|
+
import_nodejs_utils56.logger.log({
|
|
39648
|
+
level: "error",
|
|
39649
|
+
message: error.message
|
|
39650
|
+
});
|
|
39651
|
+
if (error instanceof import_nodejs_utils56.AppError) {
|
|
39652
|
+
throw error;
|
|
39653
|
+
} else {
|
|
39654
|
+
throw new Error("Failed to create building unit.");
|
|
39655
|
+
}
|
|
39656
|
+
}
|
|
39657
|
+
}
|
|
39658
|
+
async function updateById(_id, value, session) {
|
|
39659
|
+
const { error } = schemaUpdateOptions.validate(value);
|
|
39660
|
+
if (error) {
|
|
39661
|
+
throw new import_nodejs_utils56.BadRequestError(error.message);
|
|
39662
|
+
}
|
|
39663
|
+
try {
|
|
39664
|
+
_id = new import_mongodb32.ObjectId(_id);
|
|
39665
|
+
} catch (error2) {
|
|
39666
|
+
throw new import_nodejs_utils56.BadRequestError("Invalid ID.");
|
|
39667
|
+
}
|
|
39668
|
+
try {
|
|
39669
|
+
const res = await collection.updateOne(
|
|
39670
|
+
{ _id },
|
|
39671
|
+
{ $set: value },
|
|
39672
|
+
{ session }
|
|
39673
|
+
);
|
|
39674
|
+
delCachedData();
|
|
39675
|
+
return res;
|
|
39676
|
+
} catch (error2) {
|
|
39677
|
+
import_nodejs_utils56.logger.log({
|
|
39678
|
+
level: "error",
|
|
39679
|
+
message: error2.message
|
|
39680
|
+
});
|
|
39681
|
+
if (error2 instanceof import_nodejs_utils56.AppError) {
|
|
39682
|
+
throw error2;
|
|
39683
|
+
} else {
|
|
39684
|
+
throw new Error("Failed to create building unit.");
|
|
39685
|
+
}
|
|
39686
|
+
}
|
|
39687
|
+
}
|
|
39688
|
+
async function updateByBuildingId(building, value, session) {
|
|
39689
|
+
const { error } = schemaUpdateOptions.validate(value);
|
|
39690
|
+
if (error) {
|
|
39691
|
+
throw new import_nodejs_utils56.BadRequestError(error.message);
|
|
39692
|
+
}
|
|
39693
|
+
try {
|
|
39694
|
+
building = new import_mongodb32.ObjectId(building);
|
|
39695
|
+
} catch (error2) {
|
|
39696
|
+
throw new import_nodejs_utils56.BadRequestError("Invalid building ID.");
|
|
39697
|
+
}
|
|
39698
|
+
try {
|
|
39699
|
+
const res = await collection.updateMany(
|
|
39700
|
+
{ building },
|
|
39701
|
+
{ $set: value },
|
|
39702
|
+
{ session }
|
|
39703
|
+
);
|
|
39704
|
+
delCachedData();
|
|
39705
|
+
return res;
|
|
39706
|
+
} catch (error2) {
|
|
39707
|
+
import_nodejs_utils56.logger.log({
|
|
39708
|
+
level: "error",
|
|
39709
|
+
message: error2.message
|
|
39710
|
+
});
|
|
39711
|
+
if (error2 instanceof import_nodejs_utils56.AppError) {
|
|
39712
|
+
throw error2;
|
|
39713
|
+
} else {
|
|
39714
|
+
throw new Error("Failed to update building unit.");
|
|
39715
|
+
}
|
|
39716
|
+
}
|
|
39717
|
+
}
|
|
39718
|
+
async function getAll({
|
|
39719
|
+
search = "",
|
|
39720
|
+
page = 1,
|
|
39721
|
+
limit = 10,
|
|
39722
|
+
sort = {},
|
|
39723
|
+
school = "",
|
|
39724
|
+
building = "",
|
|
39725
|
+
status = "active"
|
|
39726
|
+
} = {}) {
|
|
39727
|
+
page = page > 0 ? page - 1 : 0;
|
|
39728
|
+
const query = {
|
|
39729
|
+
deletedAt: { $in: ["", null] },
|
|
39730
|
+
status: { $in: [status, "", null] }
|
|
39731
|
+
};
|
|
39732
|
+
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
39733
|
+
if (search) {
|
|
39734
|
+
query.$text = { $search: search };
|
|
39735
|
+
}
|
|
39736
|
+
if (school) {
|
|
39737
|
+
try {
|
|
39738
|
+
query.school = new import_mongodb32.ObjectId(school);
|
|
39739
|
+
} catch (error) {
|
|
39740
|
+
throw new import_nodejs_utils56.BadRequestError("Invalid school ID.");
|
|
39741
|
+
}
|
|
39742
|
+
}
|
|
39743
|
+
if (building) {
|
|
39744
|
+
try {
|
|
39745
|
+
query.building = new import_mongodb32.ObjectId(building);
|
|
39746
|
+
} catch (error) {
|
|
39747
|
+
throw new import_nodejs_utils56.BadRequestError("Invalid building ID.");
|
|
39748
|
+
}
|
|
39749
|
+
}
|
|
39750
|
+
const cacheParams = {
|
|
39751
|
+
page,
|
|
39752
|
+
limit,
|
|
39753
|
+
sort: JSON.stringify(sort)
|
|
39754
|
+
};
|
|
39755
|
+
if (search)
|
|
39756
|
+
cacheParams.search = search;
|
|
39757
|
+
if (school)
|
|
39758
|
+
cacheParams.school = school;
|
|
39759
|
+
if (building)
|
|
39760
|
+
cacheParams.building = building;
|
|
39761
|
+
if (status !== "active")
|
|
39762
|
+
cacheParams.status = status;
|
|
39763
|
+
const cacheKey = (0, import_nodejs_utils56.makeCacheKey)(namespace_collection, cacheParams);
|
|
39764
|
+
import_nodejs_utils56.logger.log({
|
|
39765
|
+
level: "info",
|
|
39766
|
+
message: `Cache key for getAll building units: ${cacheKey}`
|
|
39767
|
+
});
|
|
39768
|
+
try {
|
|
39769
|
+
const cached = await getCache(cacheKey);
|
|
39770
|
+
if (cached) {
|
|
39771
|
+
import_nodejs_utils56.logger.log({
|
|
39772
|
+
level: "info",
|
|
39773
|
+
message: `Cache hit for getAll building units: ${cacheKey}`
|
|
39774
|
+
});
|
|
39775
|
+
return cached;
|
|
39776
|
+
}
|
|
39777
|
+
const items = await collection.aggregate([
|
|
39778
|
+
{ $match: query },
|
|
39779
|
+
{ $sort: sort },
|
|
39780
|
+
{ $skip: page * limit },
|
|
39781
|
+
{ $limit: limit }
|
|
39782
|
+
]).toArray();
|
|
39783
|
+
const length = await collection.countDocuments(query);
|
|
39784
|
+
const data = (0, import_nodejs_utils56.paginate)(items, page, limit, length);
|
|
39785
|
+
setCache(cacheKey, data, 600).then(() => {
|
|
39786
|
+
import_nodejs_utils56.logger.log({
|
|
39787
|
+
level: "info",
|
|
39788
|
+
message: `Cache set for getAll building units: ${cacheKey}`
|
|
39789
|
+
});
|
|
39790
|
+
}).catch((err) => {
|
|
39791
|
+
import_nodejs_utils56.logger.log({
|
|
39792
|
+
level: "error",
|
|
39793
|
+
message: `Failed to set cache for getAll building units: ${err.message}`
|
|
39794
|
+
});
|
|
39795
|
+
});
|
|
39796
|
+
return data;
|
|
39797
|
+
} catch (error) {
|
|
39798
|
+
import_nodejs_utils56.logger.log({ level: "error", message: `${error}` });
|
|
39799
|
+
throw error;
|
|
39800
|
+
}
|
|
39801
|
+
}
|
|
39802
|
+
async function getById(_id) {
|
|
39803
|
+
try {
|
|
39804
|
+
_id = new import_mongodb32.ObjectId(_id);
|
|
39805
|
+
} catch (error) {
|
|
39806
|
+
throw new import_nodejs_utils56.BadRequestError("Invalid ID.");
|
|
39807
|
+
}
|
|
39808
|
+
const cacheKey = (0, import_nodejs_utils56.makeCacheKey)(namespace_collection, { _id: String(_id) });
|
|
39809
|
+
try {
|
|
39810
|
+
const cached = await getCache(cacheKey);
|
|
39811
|
+
if (cached) {
|
|
39812
|
+
import_nodejs_utils56.logger.log({
|
|
39813
|
+
level: "info",
|
|
39814
|
+
message: `Cache hit for getById building unit: ${cacheKey}`
|
|
39815
|
+
});
|
|
39816
|
+
return cached;
|
|
39817
|
+
}
|
|
39818
|
+
const result = await collection.findOne({
|
|
39819
|
+
_id,
|
|
39820
|
+
deletedAt: { $in: ["", null] }
|
|
39821
|
+
});
|
|
39822
|
+
if (!result) {
|
|
39823
|
+
throw new import_nodejs_utils56.BadRequestError("Building unit not found.");
|
|
39824
|
+
}
|
|
39825
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
39826
|
+
import_nodejs_utils56.logger.log({
|
|
39827
|
+
level: "info",
|
|
39828
|
+
message: `Cache set for building unit by id: ${cacheKey}`
|
|
39829
|
+
});
|
|
39830
|
+
}).catch((err) => {
|
|
39831
|
+
import_nodejs_utils56.logger.log({
|
|
39832
|
+
level: "error",
|
|
39833
|
+
message: `Failed to set cache for building unit by id: ${err.message}`
|
|
39834
|
+
});
|
|
39835
|
+
});
|
|
39836
|
+
return result;
|
|
39837
|
+
} catch (error) {
|
|
39838
|
+
if (error instanceof import_nodejs_utils56.AppError) {
|
|
39839
|
+
throw error;
|
|
39840
|
+
} else {
|
|
39841
|
+
throw new import_nodejs_utils56.InternalServerError("Failed to get building unit.");
|
|
39842
|
+
}
|
|
39843
|
+
}
|
|
39844
|
+
}
|
|
39845
|
+
async function getByBuildingLevel(building, level) {
|
|
39846
|
+
try {
|
|
39847
|
+
building = new import_mongodb32.ObjectId(building);
|
|
39848
|
+
} catch (error) {
|
|
39849
|
+
throw new import_nodejs_utils56.BadRequestError("Invalid building ID.");
|
|
39850
|
+
}
|
|
39851
|
+
const cacheKey = (0, import_nodejs_utils56.makeCacheKey)(namespace_collection, {
|
|
39852
|
+
building: String(building),
|
|
39853
|
+
level
|
|
39854
|
+
});
|
|
39855
|
+
try {
|
|
39856
|
+
const cached = await getCache(cacheKey);
|
|
39857
|
+
if (cached) {
|
|
39858
|
+
import_nodejs_utils56.logger.log({
|
|
39859
|
+
level: "info",
|
|
39860
|
+
message: `Cache hit for getById building unit: ${cacheKey}`
|
|
39861
|
+
});
|
|
39862
|
+
return cached;
|
|
39863
|
+
}
|
|
39864
|
+
const result = await collection.findOne({
|
|
39865
|
+
building,
|
|
39866
|
+
level,
|
|
39867
|
+
status: "active"
|
|
39868
|
+
});
|
|
39869
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
39870
|
+
import_nodejs_utils56.logger.log({
|
|
39871
|
+
level: "info",
|
|
39872
|
+
message: `Cache set for building unit by id: ${cacheKey}`
|
|
39873
|
+
});
|
|
39874
|
+
}).catch((err) => {
|
|
39875
|
+
import_nodejs_utils56.logger.log({
|
|
39876
|
+
level: "error",
|
|
39877
|
+
message: `Failed to set cache for building unit by id: ${err.message}`
|
|
39878
|
+
});
|
|
39879
|
+
});
|
|
39880
|
+
return result;
|
|
39881
|
+
} catch (error) {
|
|
39882
|
+
if (error instanceof import_nodejs_utils56.AppError) {
|
|
39883
|
+
throw error;
|
|
39884
|
+
} else {
|
|
39885
|
+
throw new import_nodejs_utils56.InternalServerError("Failed to get building unit.");
|
|
39886
|
+
}
|
|
39887
|
+
}
|
|
39888
|
+
}
|
|
39889
|
+
async function getByBuilding(building) {
|
|
39890
|
+
try {
|
|
39891
|
+
building = new import_mongodb32.ObjectId(building);
|
|
39892
|
+
} catch (error) {
|
|
39893
|
+
throw new import_nodejs_utils56.BadRequestError("Invalid building ID.");
|
|
39894
|
+
}
|
|
39895
|
+
const cacheKey = (0, import_nodejs_utils56.makeCacheKey)(namespace_collection, {
|
|
39896
|
+
building: String(building)
|
|
39897
|
+
});
|
|
39898
|
+
try {
|
|
39899
|
+
const cached = await getCache(cacheKey);
|
|
39900
|
+
if (cached) {
|
|
39901
|
+
import_nodejs_utils56.logger.log({
|
|
39902
|
+
level: "info",
|
|
39903
|
+
message: `Cache hit for getById building unit: ${cacheKey}`
|
|
39904
|
+
});
|
|
39905
|
+
return cached;
|
|
39906
|
+
}
|
|
39907
|
+
const result = await collection.findOne({
|
|
39908
|
+
building,
|
|
39909
|
+
status: "active"
|
|
39910
|
+
});
|
|
39911
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
39912
|
+
import_nodejs_utils56.logger.log({
|
|
39913
|
+
level: "info",
|
|
39914
|
+
message: `Cache set for building unit by id: ${cacheKey}`
|
|
39915
|
+
});
|
|
39916
|
+
}).catch((err) => {
|
|
39917
|
+
import_nodejs_utils56.logger.log({
|
|
39918
|
+
level: "error",
|
|
39919
|
+
message: `Failed to set cache for building unit by id: ${err.message}`
|
|
39920
|
+
});
|
|
39921
|
+
});
|
|
39922
|
+
return result;
|
|
39923
|
+
} catch (error) {
|
|
39924
|
+
if (error instanceof import_nodejs_utils56.AppError) {
|
|
39925
|
+
throw error;
|
|
39926
|
+
} else {
|
|
39927
|
+
throw new import_nodejs_utils56.InternalServerError("Failed to get building unit.");
|
|
39928
|
+
}
|
|
39929
|
+
}
|
|
39930
|
+
}
|
|
39931
|
+
async function deleteById(_id, session) {
|
|
39932
|
+
try {
|
|
39933
|
+
_id = new import_mongodb32.ObjectId(_id);
|
|
39934
|
+
} catch (error) {
|
|
39935
|
+
throw new import_nodejs_utils56.BadRequestError("Invalid ID.");
|
|
39936
|
+
}
|
|
39937
|
+
try {
|
|
39938
|
+
const res = await collection.updateOne(
|
|
39939
|
+
{ _id },
|
|
39940
|
+
{ $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } },
|
|
39941
|
+
{ session }
|
|
39942
|
+
);
|
|
39943
|
+
delCachedData();
|
|
39944
|
+
return "Room/Facility deleted successfully.";
|
|
39945
|
+
} catch (error) {
|
|
39946
|
+
import_nodejs_utils56.logger.log({
|
|
39947
|
+
level: "error",
|
|
39948
|
+
message: error.message
|
|
39949
|
+
});
|
|
39950
|
+
if (error instanceof import_nodejs_utils56.AppError) {
|
|
39951
|
+
throw error;
|
|
39952
|
+
} else {
|
|
39953
|
+
throw new Error("Failed to deleted room/facility.");
|
|
39954
|
+
}
|
|
39955
|
+
}
|
|
39956
|
+
}
|
|
39957
|
+
return {
|
|
39958
|
+
createIndexes,
|
|
39959
|
+
add,
|
|
39960
|
+
getAll,
|
|
39961
|
+
getById,
|
|
39962
|
+
getByBuildingLevel,
|
|
39963
|
+
updateById,
|
|
39964
|
+
getByBuilding,
|
|
39965
|
+
deleteById,
|
|
39966
|
+
updateByBuildingId
|
|
39967
|
+
};
|
|
39968
|
+
}
|
|
39969
|
+
|
|
39970
|
+
// src/resources/building/building.service.ts
|
|
39971
|
+
function useBuildingService() {
|
|
39972
|
+
const {
|
|
39973
|
+
updateById: _updateById,
|
|
39974
|
+
getById: _getById,
|
|
39975
|
+
deleteById: _deleteById
|
|
39976
|
+
} = useBuildingRepo();
|
|
39977
|
+
const { getByBuildingLevel, getByBuilding, updateByBuildingId } = useBuildingUnitRepo();
|
|
39978
|
+
async function updateById(id, data) {
|
|
39979
|
+
data.levels = Number(data.levels);
|
|
39980
|
+
const session = import_nodejs_utils57.useAtlas.getClient()?.startSession();
|
|
39981
|
+
try {
|
|
39982
|
+
const building = await _getById(id);
|
|
39983
|
+
if (!building) {
|
|
39984
|
+
throw new import_nodejs_utils57.NotFoundError("Building not found.");
|
|
39985
|
+
}
|
|
39986
|
+
if (data.levels < building.levels) {
|
|
39987
|
+
const unit = await getByBuildingLevel(id, building.levels);
|
|
39988
|
+
if (unit) {
|
|
39989
|
+
throw new import_nodejs_utils57.BadRequestError(
|
|
39990
|
+
"Cannot reduce floors, there are existing building units at higher floors."
|
|
39991
|
+
);
|
|
39992
|
+
}
|
|
39993
|
+
}
|
|
39994
|
+
session?.startTransaction();
|
|
39995
|
+
if (building.name !== data.name) {
|
|
39996
|
+
await updateByBuildingId(id, { buildingName: data.name }, session);
|
|
39997
|
+
}
|
|
39998
|
+
const result = await _updateById(id, data, session);
|
|
39999
|
+
await session?.commitTransaction();
|
|
40000
|
+
return result;
|
|
40001
|
+
} catch (error) {
|
|
40002
|
+
await session?.abortTransaction();
|
|
40003
|
+
throw error;
|
|
40004
|
+
} finally {
|
|
40005
|
+
session?.endSession();
|
|
40006
|
+
}
|
|
40007
|
+
}
|
|
40008
|
+
async function deleteById(id) {
|
|
40009
|
+
const building = await getByBuilding(id);
|
|
40010
|
+
if (building) {
|
|
40011
|
+
throw new import_nodejs_utils57.BadRequestError(
|
|
40012
|
+
"Cannot delete building with existing room/facility. Please delete room/facility first."
|
|
40013
|
+
);
|
|
40014
|
+
}
|
|
40015
|
+
try {
|
|
40016
|
+
await _deleteById(id);
|
|
40017
|
+
return "Building deleted successfully.";
|
|
40018
|
+
} catch (error) {
|
|
40019
|
+
throw error;
|
|
40020
|
+
}
|
|
40021
|
+
}
|
|
40022
|
+
return {
|
|
40023
|
+
updateById,
|
|
40024
|
+
deleteById
|
|
40025
|
+
};
|
|
40026
|
+
}
|
|
40027
|
+
|
|
40028
|
+
// src/resources/building/building.controller.ts
|
|
40029
|
+
var import_nodejs_utils58 = require("@eeplatform/nodejs-utils");
|
|
40030
|
+
var import_joi33 = __toESM(require("joi"));
|
|
40031
|
+
function useBuildingController() {
|
|
40032
|
+
const { getAll: _getAll, getById: _getById, add: _add } = useBuildingRepo();
|
|
40033
|
+
const { updateById: _updateById, deleteById: _deleteById } = useBuildingService();
|
|
40034
|
+
async function createBuilding(req, res, next) {
|
|
40035
|
+
const value = req.body;
|
|
40036
|
+
const validation = import_joi33.default.object({
|
|
40037
|
+
name: import_joi33.default.string().required(),
|
|
40038
|
+
school: import_joi33.default.string().hex().required(),
|
|
40039
|
+
levels: import_joi33.default.number().integer().min(1).required(),
|
|
40040
|
+
serial: import_joi33.default.string().optional().allow("", null),
|
|
40041
|
+
status: import_joi33.default.string().optional().allow("", null)
|
|
40042
|
+
});
|
|
40043
|
+
const { error } = validation.validate(value);
|
|
40044
|
+
if (error) {
|
|
40045
|
+
next(new import_nodejs_utils58.BadRequestError(error.message));
|
|
40046
|
+
import_nodejs_utils58.logger.info(`Controller: ${error.message}`);
|
|
40047
|
+
return;
|
|
40048
|
+
}
|
|
40049
|
+
try {
|
|
40050
|
+
const result = await _add(value);
|
|
40051
|
+
res.json(result);
|
|
40052
|
+
return;
|
|
40053
|
+
} catch (error2) {
|
|
40054
|
+
next(error2);
|
|
40055
|
+
}
|
|
40056
|
+
}
|
|
40057
|
+
async function updateById(req, res, next) {
|
|
40058
|
+
const value = req.body;
|
|
40059
|
+
const id = req.params.id ?? "";
|
|
40060
|
+
const validation = import_joi33.default.object({
|
|
40061
|
+
id: import_joi33.default.string().hex().required(),
|
|
40062
|
+
value: import_joi33.default.object({
|
|
40063
|
+
name: import_joi33.default.string().required(),
|
|
40064
|
+
serial: import_joi33.default.string().optional().allow("", null),
|
|
40065
|
+
levels: import_joi33.default.number().integer().min(1).required()
|
|
40066
|
+
})
|
|
40067
|
+
});
|
|
40068
|
+
const { error } = validation.validate({ id, value });
|
|
40069
|
+
if (error) {
|
|
40070
|
+
next(new import_nodejs_utils58.BadRequestError(error.message));
|
|
40071
|
+
import_nodejs_utils58.logger.info(`Controller: ${error.message}`);
|
|
40072
|
+
return;
|
|
40073
|
+
}
|
|
40074
|
+
try {
|
|
40075
|
+
const result = await _updateById(id, value);
|
|
40076
|
+
res.json(result);
|
|
40077
|
+
return;
|
|
40078
|
+
} catch (error2) {
|
|
40079
|
+
next(error2);
|
|
40080
|
+
}
|
|
40081
|
+
}
|
|
40082
|
+
async function getAll(req, res, next) {
|
|
40083
|
+
const query = req.query;
|
|
40084
|
+
const validation = import_joi33.default.object({
|
|
40085
|
+
page: import_joi33.default.number().min(1).optional().allow("", null),
|
|
40086
|
+
limit: import_joi33.default.number().min(1).optional().allow("", null),
|
|
40087
|
+
search: import_joi33.default.string().optional().allow("", null),
|
|
40088
|
+
school: import_joi33.default.string().hex().optional().allow("", null),
|
|
40089
|
+
status: import_joi33.default.string().optional().allow("", null)
|
|
40090
|
+
});
|
|
40091
|
+
const { error } = validation.validate(query);
|
|
40092
|
+
if (error) {
|
|
40093
|
+
next(new import_nodejs_utils58.BadRequestError(error.message));
|
|
40094
|
+
return;
|
|
40095
|
+
}
|
|
40096
|
+
const page = parseInt(req.query.page) ?? 1;
|
|
40097
|
+
let limit = parseInt(req.query.limit) ?? 20;
|
|
40098
|
+
limit = isNaN(limit) ? 20 : limit;
|
|
40099
|
+
const sort = req.query.sort ? String(req.query.sort).split(",") : "";
|
|
40100
|
+
const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
|
|
40101
|
+
const sortObj = {};
|
|
40102
|
+
if (sort && Array.isArray(sort) && sort.length && sortOrder && Array.isArray(sortOrder) && sortOrder.length) {
|
|
40103
|
+
sort.forEach((field, index) => {
|
|
40104
|
+
sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
|
|
40105
|
+
});
|
|
40106
|
+
}
|
|
40107
|
+
const status = req.query.status ?? "active";
|
|
40108
|
+
const school = req.query.school ?? "";
|
|
40109
|
+
const search = req.query.search ?? "";
|
|
40110
|
+
try {
|
|
40111
|
+
const buildings = await _getAll({
|
|
40112
|
+
page,
|
|
40113
|
+
limit,
|
|
40114
|
+
sort: sortObj,
|
|
40115
|
+
status,
|
|
40116
|
+
school,
|
|
40117
|
+
search
|
|
40118
|
+
});
|
|
40119
|
+
res.json(buildings);
|
|
40120
|
+
return;
|
|
40121
|
+
} catch (error2) {
|
|
40122
|
+
next(error2);
|
|
40123
|
+
}
|
|
40124
|
+
}
|
|
40125
|
+
async function getById(req, res, next) {
|
|
40126
|
+
const id = req.params.id;
|
|
40127
|
+
const validation = import_joi33.default.object({
|
|
40128
|
+
id: import_joi33.default.string().hex().required()
|
|
40129
|
+
});
|
|
40130
|
+
const { error } = validation.validate({ id });
|
|
40131
|
+
if (error) {
|
|
40132
|
+
next(new import_nodejs_utils58.BadRequestError(error.message));
|
|
40133
|
+
return;
|
|
40134
|
+
}
|
|
40135
|
+
try {
|
|
40136
|
+
const building = await _getById(id);
|
|
40137
|
+
res.json({
|
|
40138
|
+
message: "Successfully retrieved building.",
|
|
40139
|
+
data: { building }
|
|
40140
|
+
});
|
|
40141
|
+
return;
|
|
40142
|
+
} catch (error2) {
|
|
40143
|
+
next(error2);
|
|
40144
|
+
}
|
|
40145
|
+
}
|
|
40146
|
+
async function deleteById(req, res, next) {
|
|
40147
|
+
const id = req.params.id;
|
|
40148
|
+
const validation = import_joi33.default.object({
|
|
40149
|
+
id: import_joi33.default.string().hex().required()
|
|
40150
|
+
});
|
|
40151
|
+
const { error } = validation.validate({ id });
|
|
40152
|
+
if (error) {
|
|
40153
|
+
next(new import_nodejs_utils58.BadRequestError(error.message));
|
|
40154
|
+
return;
|
|
40155
|
+
}
|
|
40156
|
+
try {
|
|
40157
|
+
const message = await _deleteById(id);
|
|
40158
|
+
res.json(message);
|
|
40159
|
+
return;
|
|
40160
|
+
} catch (error2) {
|
|
40161
|
+
next(error2);
|
|
40162
|
+
}
|
|
40163
|
+
}
|
|
40164
|
+
return {
|
|
40165
|
+
createBuilding,
|
|
40166
|
+
getAll,
|
|
40167
|
+
getById,
|
|
40168
|
+
updateById,
|
|
40169
|
+
deleteById
|
|
40170
|
+
};
|
|
40171
|
+
}
|
|
40172
|
+
|
|
40173
|
+
// src/resources/building/building-unit.service.ts
|
|
40174
|
+
var import_nodejs_utils59 = require("@eeplatform/nodejs-utils");
|
|
40175
|
+
function useBuildingUnitService() {
|
|
40176
|
+
const { add: _add } = useBuildingUnitRepo();
|
|
40177
|
+
async function add(value) {
|
|
40178
|
+
const session = import_nodejs_utils59.useAtlas.getClient()?.startSession();
|
|
40179
|
+
if (!session) {
|
|
40180
|
+
throw new Error("Unable to start session for building unit service.");
|
|
40181
|
+
}
|
|
40182
|
+
try {
|
|
40183
|
+
await session.startTransaction();
|
|
40184
|
+
for (let index = 0; index < value.qty; index++) {
|
|
40185
|
+
await _add(
|
|
40186
|
+
{ ...value.building, name: `${value.building.name} ${index + 1}` },
|
|
40187
|
+
session
|
|
40188
|
+
);
|
|
40189
|
+
}
|
|
40190
|
+
await session.commitTransaction();
|
|
40191
|
+
return "Building unit added successfully.";
|
|
40192
|
+
} catch (error) {
|
|
40193
|
+
await session.abortTransaction();
|
|
40194
|
+
throw error;
|
|
40195
|
+
} finally {
|
|
40196
|
+
session.endSession();
|
|
40197
|
+
}
|
|
40198
|
+
}
|
|
40199
|
+
return {
|
|
40200
|
+
add
|
|
40201
|
+
};
|
|
40202
|
+
}
|
|
40203
|
+
|
|
40204
|
+
// src/resources/building/building-unit.controller.ts
|
|
40205
|
+
var import_nodejs_utils60 = require("@eeplatform/nodejs-utils");
|
|
40206
|
+
var import_joi34 = __toESM(require("joi"));
|
|
40207
|
+
function useBuildingUnitController() {
|
|
40208
|
+
const {
|
|
40209
|
+
getAll: _getAll,
|
|
40210
|
+
getById: _getById,
|
|
40211
|
+
updateById: _updateById,
|
|
40212
|
+
deleteById: _deleteById
|
|
40213
|
+
} = useBuildingUnitRepo();
|
|
40214
|
+
const { add: _add } = useBuildingUnitService();
|
|
40215
|
+
async function add(req, res, next) {
|
|
40216
|
+
const data = req.body;
|
|
40217
|
+
const validation = import_joi34.default.object({
|
|
40218
|
+
building: import_joi34.default.object({
|
|
40219
|
+
school: import_joi34.default.string().hex().required(),
|
|
40220
|
+
name: import_joi34.default.string().optional().allow("", null),
|
|
40221
|
+
building: import_joi34.default.string().hex().required(),
|
|
40222
|
+
buildingName: import_joi34.default.string().optional().allow("", null),
|
|
40223
|
+
level: import_joi34.default.number().integer().min(1).required(),
|
|
40224
|
+
category: import_joi34.default.string().required(),
|
|
40225
|
+
type: import_joi34.default.string().required(),
|
|
40226
|
+
seating_capacity: import_joi34.default.number().integer().min(0).required(),
|
|
40227
|
+
standing_capacity: import_joi34.default.number().integer().min(0).required(),
|
|
40228
|
+
description: import_joi34.default.string().optional().allow("", null),
|
|
40229
|
+
unit_of_measurement: import_joi34.default.string().valid("sqm").required(),
|
|
40230
|
+
area: import_joi34.default.number().positive().required(),
|
|
40231
|
+
status: import_joi34.default.string().optional().allow("", null)
|
|
40232
|
+
}),
|
|
40233
|
+
qty: import_joi34.default.number().integer().min(1).max(20).optional().default(1)
|
|
40234
|
+
});
|
|
40235
|
+
const { error } = validation.validate(data);
|
|
40236
|
+
if (error) {
|
|
40237
|
+
next(new import_nodejs_utils60.BadRequestError(error.message));
|
|
40238
|
+
return;
|
|
40239
|
+
}
|
|
40240
|
+
try {
|
|
40241
|
+
const buildingUnit = await _add(data);
|
|
40242
|
+
res.json({
|
|
40243
|
+
message: "Building unit added successfully.",
|
|
40244
|
+
data: { buildingUnit }
|
|
40245
|
+
});
|
|
40246
|
+
} catch (error2) {
|
|
40247
|
+
next(error2);
|
|
40248
|
+
}
|
|
40249
|
+
}
|
|
40250
|
+
async function updateById(req, res, next) {
|
|
40251
|
+
const data = req.body;
|
|
40252
|
+
const id = req.params.id ?? "";
|
|
40253
|
+
const validation = import_joi34.default.object({
|
|
40254
|
+
id: import_joi34.default.string().hex().required(),
|
|
40255
|
+
value: schemaUpdateOptions
|
|
40256
|
+
});
|
|
40257
|
+
const { error } = validation.validate({ id, value: data });
|
|
40258
|
+
if (error) {
|
|
40259
|
+
next(new import_nodejs_utils60.BadRequestError(error.message));
|
|
40260
|
+
return;
|
|
40261
|
+
}
|
|
40262
|
+
try {
|
|
40263
|
+
const buildingUnit = await _updateById(id, data);
|
|
40264
|
+
res.json({
|
|
40265
|
+
message: "Building unit updated successfully.",
|
|
40266
|
+
data: { buildingUnit }
|
|
40267
|
+
});
|
|
40268
|
+
} catch (error2) {
|
|
40269
|
+
next(error2);
|
|
40270
|
+
}
|
|
40271
|
+
}
|
|
40272
|
+
async function getAll(req, res, next) {
|
|
40273
|
+
const query = req.query;
|
|
40274
|
+
const validation = import_joi34.default.object({
|
|
40275
|
+
page: import_joi34.default.number().min(1).optional().allow("", null),
|
|
40276
|
+
limit: import_joi34.default.number().min(1).optional().allow("", null),
|
|
40277
|
+
search: import_joi34.default.string().optional().allow("", null),
|
|
40278
|
+
school: import_joi34.default.string().hex().optional().allow("", null),
|
|
40279
|
+
building: import_joi34.default.string().hex().optional().allow("", null),
|
|
40280
|
+
status: import_joi34.default.string().optional().allow("", null)
|
|
40281
|
+
});
|
|
40282
|
+
const { error } = validation.validate(query);
|
|
40283
|
+
if (error) {
|
|
40284
|
+
next(new import_nodejs_utils60.BadRequestError(error.message));
|
|
40285
|
+
return;
|
|
40286
|
+
}
|
|
40287
|
+
const page = parseInt(req.query.page) ?? 1;
|
|
40288
|
+
let limit = parseInt(req.query.limit) ?? 20;
|
|
40289
|
+
limit = isNaN(limit) ? 20 : limit;
|
|
40290
|
+
const sort = req.query.sort ? String(req.query.sort).split(",") : "";
|
|
40291
|
+
const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
|
|
40292
|
+
const sortObj = {};
|
|
40293
|
+
if (sort && Array.isArray(sort) && sort.length && sortOrder && Array.isArray(sortOrder) && sortOrder.length) {
|
|
40294
|
+
sort.forEach((field, index) => {
|
|
40295
|
+
sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
|
|
40296
|
+
});
|
|
40297
|
+
}
|
|
40298
|
+
const status = req.query.status ?? "active";
|
|
40299
|
+
const school = req.query.school ?? "";
|
|
40300
|
+
const building = req.query.building ?? "";
|
|
40301
|
+
const search = req.query.search ?? "";
|
|
40302
|
+
try {
|
|
40303
|
+
const buildings = await _getAll({
|
|
40304
|
+
page,
|
|
40305
|
+
limit,
|
|
40306
|
+
sort: sortObj,
|
|
40307
|
+
status,
|
|
40308
|
+
school,
|
|
40309
|
+
search,
|
|
40310
|
+
building
|
|
40311
|
+
});
|
|
40312
|
+
res.json(buildings);
|
|
40313
|
+
return;
|
|
40314
|
+
} catch (error2) {
|
|
40315
|
+
next(error2);
|
|
40316
|
+
}
|
|
40317
|
+
}
|
|
40318
|
+
async function getById(req, res, next) {
|
|
40319
|
+
const id = req.params.id;
|
|
40320
|
+
const validation = import_joi34.default.object({
|
|
40321
|
+
id: import_joi34.default.string().hex().required()
|
|
40322
|
+
});
|
|
40323
|
+
const { error } = validation.validate({ id });
|
|
40324
|
+
if (error) {
|
|
40325
|
+
next(new import_nodejs_utils60.BadRequestError(error.message));
|
|
40326
|
+
return;
|
|
40327
|
+
}
|
|
40328
|
+
try {
|
|
40329
|
+
const buildingUnit = await _getById(id);
|
|
40330
|
+
res.json({
|
|
40331
|
+
message: "Successfully retrieved building unit.",
|
|
40332
|
+
data: { buildingUnit }
|
|
40333
|
+
});
|
|
40334
|
+
return;
|
|
40335
|
+
} catch (error2) {
|
|
40336
|
+
next(error2);
|
|
40337
|
+
}
|
|
40338
|
+
}
|
|
40339
|
+
async function deleteById(req, res, next) {
|
|
40340
|
+
const id = req.params.id;
|
|
40341
|
+
const validation = import_joi34.default.object({
|
|
40342
|
+
id: import_joi34.default.string().hex().required()
|
|
40343
|
+
});
|
|
40344
|
+
const { error } = validation.validate({ id });
|
|
40345
|
+
if (error) {
|
|
40346
|
+
next(new import_nodejs_utils60.BadRequestError(error.message));
|
|
40347
|
+
return;
|
|
40348
|
+
}
|
|
40349
|
+
try {
|
|
40350
|
+
const message = await _deleteById(id);
|
|
40351
|
+
res.json({ message });
|
|
40352
|
+
return;
|
|
40353
|
+
} catch (error2) {
|
|
40354
|
+
next(error2);
|
|
40355
|
+
}
|
|
40356
|
+
}
|
|
40357
|
+
return {
|
|
40358
|
+
add,
|
|
40359
|
+
getAll,
|
|
40360
|
+
getById,
|
|
40361
|
+
updateById,
|
|
40362
|
+
deleteById
|
|
40363
|
+
};
|
|
40364
|
+
}
|
|
40365
|
+
|
|
40366
|
+
// src/resources/personnel/personnel.model.ts
|
|
40367
|
+
var import_nodejs_utils61 = require("@eeplatform/nodejs-utils");
|
|
40368
|
+
var import_joi35 = __toESM(require("joi"));
|
|
40369
|
+
var import_mongodb33 = require("mongodb");
|
|
40370
|
+
var schemaPersonnel = import_joi35.default.object({
|
|
40371
|
+
_id: import_joi35.default.string().hex().optional().allow("", null),
|
|
40372
|
+
school: import_joi35.default.string().hex().required(),
|
|
40373
|
+
schoolName: import_joi35.default.string().optional().allow("", null),
|
|
40374
|
+
firstName: import_joi35.default.string().required(),
|
|
40375
|
+
lastName: import_joi35.default.string().required(),
|
|
40376
|
+
middleName: import_joi35.default.string().optional().allow("", null),
|
|
40377
|
+
suffix: import_joi35.default.string().optional().allow("", null),
|
|
40378
|
+
title: import_joi35.default.string().optional().allow("", null),
|
|
40379
|
+
classification: import_joi35.default.string().required(),
|
|
40380
|
+
status: import_joi35.default.string().optional().allow("", null),
|
|
40381
|
+
createdAt: import_joi35.default.date().optional().allow("", null),
|
|
40382
|
+
updatedAt: import_joi35.default.date().optional().allow("", null),
|
|
40383
|
+
deletedAt: import_joi35.default.date().optional().allow("", null)
|
|
40384
|
+
});
|
|
40385
|
+
function MPersonnel(value) {
|
|
40386
|
+
const { error } = schemaPersonnel.validate(value);
|
|
40387
|
+
if (error) {
|
|
40388
|
+
import_nodejs_utils61.logger.info(`Personnel Model: ${error.message}`);
|
|
40389
|
+
throw new import_nodejs_utils61.BadRequestError(error.message);
|
|
40390
|
+
}
|
|
40391
|
+
if (value._id && typeof value._id === "string") {
|
|
40392
|
+
try {
|
|
40393
|
+
value._id = new import_mongodb33.ObjectId(value._id);
|
|
40394
|
+
} catch (error2) {
|
|
40395
|
+
throw new import_nodejs_utils61.BadRequestError("Invalid _id format");
|
|
40396
|
+
}
|
|
40397
|
+
}
|
|
40398
|
+
if (value.school && typeof value.school === "string") {
|
|
40399
|
+
try {
|
|
40400
|
+
value.school = new import_mongodb33.ObjectId(value.school);
|
|
40401
|
+
} catch (error2) {
|
|
40402
|
+
throw new import_nodejs_utils61.BadRequestError("Invalid school format");
|
|
40403
|
+
}
|
|
40404
|
+
}
|
|
40405
|
+
if (!value.status) {
|
|
40406
|
+
value.status = "active";
|
|
40407
|
+
}
|
|
40408
|
+
return {
|
|
40409
|
+
_id: value._id,
|
|
40410
|
+
school: value.school,
|
|
40411
|
+
schoolName: value.schoolName ?? "",
|
|
40412
|
+
firstName: value.firstName ?? "",
|
|
40413
|
+
lastName: value.lastName ?? "",
|
|
40414
|
+
middleName: value.middleName ?? "",
|
|
40415
|
+
suffix: value.suffix ?? "",
|
|
40416
|
+
title: value.title ?? "",
|
|
40417
|
+
classification: value.classification ?? "",
|
|
40418
|
+
status: value.status,
|
|
40419
|
+
createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
|
|
40420
|
+
updatedAt: value.updatedAt ?? "",
|
|
40421
|
+
deletedAt: value.deletedAt ?? ""
|
|
40422
|
+
};
|
|
40423
|
+
}
|
|
40424
|
+
|
|
40425
|
+
// src/resources/personnel/personnel.repository.ts
|
|
40426
|
+
var import_nodejs_utils62 = require("@eeplatform/nodejs-utils");
|
|
40427
|
+
var import_mongodb34 = require("mongodb");
|
|
40428
|
+
function usePersonnelRepo() {
|
|
40429
|
+
const db = import_nodejs_utils62.useAtlas.getDb();
|
|
40430
|
+
if (!db) {
|
|
40431
|
+
throw new Error("Unable to connect to server.");
|
|
40432
|
+
}
|
|
40433
|
+
const namespace_collection = "deped.school.personnel";
|
|
40434
|
+
const collection = db.collection(namespace_collection);
|
|
40435
|
+
const { getCache, setCache, delNamespace } = (0, import_nodejs_utils62.useCache)(namespace_collection);
|
|
40436
|
+
async function createIndexes() {
|
|
40437
|
+
try {
|
|
40438
|
+
await collection.createIndexes([
|
|
40439
|
+
{
|
|
40440
|
+
key: {
|
|
40441
|
+
firstName: 1,
|
|
40442
|
+
lastName: 1,
|
|
40443
|
+
classification: 1,
|
|
40444
|
+
status: 1
|
|
40445
|
+
},
|
|
40446
|
+
name: "personnel_search_index"
|
|
40447
|
+
},
|
|
40448
|
+
{ key: { status: 1 } },
|
|
40449
|
+
{ key: { classification: 1 } },
|
|
40450
|
+
{ key: { firstName: "text", lastName: "text", middleName: "text" } }
|
|
40451
|
+
]);
|
|
40452
|
+
} catch (error) {
|
|
40453
|
+
throw new Error("Failed to create index on personnel.");
|
|
40454
|
+
}
|
|
40455
|
+
}
|
|
40456
|
+
async function add(value, session) {
|
|
40457
|
+
try {
|
|
40458
|
+
value = MPersonnel(value);
|
|
40459
|
+
await collection.insertOne(value, { session });
|
|
40460
|
+
delCachedData();
|
|
40461
|
+
return "Successfully added personnel.";
|
|
40462
|
+
} catch (error) {
|
|
40463
|
+
import_nodejs_utils62.logger.log({
|
|
40464
|
+
level: "error",
|
|
40465
|
+
message: error.message
|
|
40466
|
+
});
|
|
40467
|
+
if (error instanceof import_nodejs_utils62.AppError) {
|
|
40468
|
+
throw error;
|
|
40469
|
+
} else {
|
|
40470
|
+
throw new Error("Failed to create personnel.");
|
|
40471
|
+
}
|
|
40472
|
+
}
|
|
40473
|
+
}
|
|
40474
|
+
async function updateById(_id, value, session) {
|
|
40475
|
+
try {
|
|
40476
|
+
_id = new import_mongodb34.ObjectId(_id);
|
|
40477
|
+
} catch (error) {
|
|
40478
|
+
throw new import_nodejs_utils62.BadRequestError("Invalid ID.");
|
|
40479
|
+
}
|
|
40480
|
+
try {
|
|
40481
|
+
const res = await collection.updateOne(
|
|
40482
|
+
{ _id },
|
|
40483
|
+
{ $set: { ...value, updatedAt: /* @__PURE__ */ new Date() } },
|
|
40484
|
+
{ session }
|
|
40485
|
+
);
|
|
40486
|
+
delCachedData();
|
|
40487
|
+
return res;
|
|
40488
|
+
} catch (error) {
|
|
40489
|
+
import_nodejs_utils62.logger.log({
|
|
40490
|
+
level: "error",
|
|
40491
|
+
message: error.message
|
|
40492
|
+
});
|
|
40493
|
+
if (error instanceof import_nodejs_utils62.AppError) {
|
|
40494
|
+
throw error;
|
|
40495
|
+
} else {
|
|
40496
|
+
throw new Error("Failed to update personnel.");
|
|
40497
|
+
}
|
|
40498
|
+
}
|
|
40499
|
+
}
|
|
40500
|
+
async function getAll({
|
|
40501
|
+
school = "",
|
|
40502
|
+
search = "",
|
|
40503
|
+
page = 1,
|
|
40504
|
+
limit = 10,
|
|
40505
|
+
sort = {},
|
|
40506
|
+
status = "active"
|
|
40507
|
+
} = {}) {
|
|
40508
|
+
page = page > 0 ? page - 1 : 0;
|
|
40509
|
+
const query = {
|
|
40510
|
+
status
|
|
40511
|
+
};
|
|
40512
|
+
const cacheParams = {
|
|
40513
|
+
page,
|
|
40514
|
+
limit,
|
|
40515
|
+
sort: JSON.stringify(sort)
|
|
40516
|
+
};
|
|
40517
|
+
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
40518
|
+
if (search) {
|
|
40519
|
+
query.$text = { $search: search };
|
|
40520
|
+
cacheParams.search = search;
|
|
40521
|
+
}
|
|
40522
|
+
if (school) {
|
|
40523
|
+
try {
|
|
40524
|
+
query.school = new import_mongodb34.ObjectId(school);
|
|
40525
|
+
} catch (error) {
|
|
40526
|
+
throw new import_nodejs_utils62.BadRequestError("Invalid school ID.");
|
|
40527
|
+
}
|
|
40528
|
+
cacheParams.school = school;
|
|
40529
|
+
}
|
|
40530
|
+
const cacheKey = (0, import_nodejs_utils62.makeCacheKey)(namespace_collection, cacheParams);
|
|
40531
|
+
import_nodejs_utils62.logger.log({
|
|
40532
|
+
level: "info",
|
|
40533
|
+
message: `Cache key for getAll personnel: ${cacheKey}`
|
|
40534
|
+
});
|
|
40535
|
+
try {
|
|
40536
|
+
const cached = await getCache(cacheKey);
|
|
40537
|
+
if (cached) {
|
|
40538
|
+
import_nodejs_utils62.logger.log({
|
|
40539
|
+
level: "info",
|
|
40540
|
+
message: `Cache hit for getAll personnel: ${cacheKey}`
|
|
40541
|
+
});
|
|
40542
|
+
return cached;
|
|
40543
|
+
}
|
|
40544
|
+
const items = await collection.aggregate([
|
|
40545
|
+
{ $match: query },
|
|
40546
|
+
{ $sort: sort },
|
|
40547
|
+
{ $skip: page * limit },
|
|
40548
|
+
{ $limit: limit }
|
|
40549
|
+
]).toArray();
|
|
40550
|
+
const length = await collection.countDocuments(query);
|
|
40551
|
+
const data = (0, import_nodejs_utils62.paginate)(items, page, limit, length);
|
|
40552
|
+
setCache(cacheKey, data, 600).then(() => {
|
|
40553
|
+
import_nodejs_utils62.logger.log({
|
|
40554
|
+
level: "info",
|
|
40555
|
+
message: `Cache set for getAll personnel: ${cacheKey}`
|
|
40556
|
+
});
|
|
40557
|
+
}).catch((err) => {
|
|
40558
|
+
import_nodejs_utils62.logger.log({
|
|
40559
|
+
level: "error",
|
|
40560
|
+
message: `Failed to set cache for getAll personnel: ${err.message}`
|
|
40561
|
+
});
|
|
40562
|
+
});
|
|
40563
|
+
return data;
|
|
40564
|
+
} catch (error) {
|
|
40565
|
+
import_nodejs_utils62.logger.log({ level: "error", message: `${error}` });
|
|
40566
|
+
throw error;
|
|
40567
|
+
}
|
|
40568
|
+
}
|
|
40569
|
+
async function getById(_id) {
|
|
40570
|
+
try {
|
|
40571
|
+
_id = new import_mongodb34.ObjectId(_id);
|
|
40572
|
+
} catch (error) {
|
|
40573
|
+
throw new import_nodejs_utils62.BadRequestError("Invalid ID.");
|
|
40574
|
+
}
|
|
40575
|
+
const cacheKey = (0, import_nodejs_utils62.makeCacheKey)(namespace_collection, { _id: String(_id) });
|
|
40576
|
+
try {
|
|
40577
|
+
const cached = await getCache(cacheKey);
|
|
40578
|
+
if (cached) {
|
|
40579
|
+
import_nodejs_utils62.logger.log({
|
|
40580
|
+
level: "info",
|
|
40581
|
+
message: `Cache hit for getById personnel: ${cacheKey}`
|
|
40582
|
+
});
|
|
40583
|
+
return cached;
|
|
40584
|
+
}
|
|
40585
|
+
const result = await collection.findOne({
|
|
40586
|
+
_id
|
|
40587
|
+
});
|
|
40588
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
40589
|
+
import_nodejs_utils62.logger.log({
|
|
40590
|
+
level: "info",
|
|
40591
|
+
message: `Cache set for personnel by id: ${cacheKey}`
|
|
40592
|
+
});
|
|
40593
|
+
}).catch((err) => {
|
|
40594
|
+
import_nodejs_utils62.logger.log({
|
|
40595
|
+
level: "error",
|
|
40596
|
+
message: `Failed to set cache for personnel by id: ${err.message}`
|
|
40597
|
+
});
|
|
40598
|
+
});
|
|
40599
|
+
return result;
|
|
40600
|
+
} catch (error) {
|
|
40601
|
+
if (error instanceof import_nodejs_utils62.AppError) {
|
|
40602
|
+
throw error;
|
|
40603
|
+
} else {
|
|
40604
|
+
throw new import_nodejs_utils62.InternalServerError("Failed to get personnel.");
|
|
40605
|
+
}
|
|
40606
|
+
}
|
|
40607
|
+
}
|
|
40608
|
+
async function deleteById(_id, session) {
|
|
40609
|
+
try {
|
|
40610
|
+
_id = new import_mongodb34.ObjectId(_id);
|
|
40611
|
+
} catch (error) {
|
|
40612
|
+
throw new import_nodejs_utils62.BadRequestError("Invalid ID.");
|
|
40613
|
+
}
|
|
40614
|
+
try {
|
|
40615
|
+
const res = await collection.updateOne(
|
|
40616
|
+
{ _id },
|
|
40617
|
+
{ $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } }
|
|
40618
|
+
);
|
|
40619
|
+
delCachedData();
|
|
40620
|
+
return res;
|
|
40621
|
+
} catch (error) {
|
|
40622
|
+
import_nodejs_utils62.logger.log({
|
|
40623
|
+
level: "error",
|
|
40624
|
+
message: error.message
|
|
40625
|
+
});
|
|
40626
|
+
if (error instanceof import_nodejs_utils62.AppError) {
|
|
40627
|
+
throw error;
|
|
40628
|
+
} else {
|
|
40629
|
+
throw new import_nodejs_utils62.InternalServerError("Failed to delete personnel.");
|
|
40630
|
+
}
|
|
40631
|
+
}
|
|
40632
|
+
}
|
|
40633
|
+
async function getByClassification(classification) {
|
|
40634
|
+
const query = {
|
|
40635
|
+
classification,
|
|
40636
|
+
status: "active"
|
|
40637
|
+
};
|
|
40638
|
+
const cacheKey = (0, import_nodejs_utils62.makeCacheKey)(namespace_collection, { classification });
|
|
40639
|
+
try {
|
|
40640
|
+
const cached = await getCache(cacheKey);
|
|
40641
|
+
if (cached) {
|
|
40642
|
+
import_nodejs_utils62.logger.log({
|
|
40643
|
+
level: "info",
|
|
40644
|
+
message: `Cache hit for getByClassification personnel: ${cacheKey}`
|
|
40645
|
+
});
|
|
40646
|
+
return cached;
|
|
40647
|
+
}
|
|
40648
|
+
const result = await collection.find(query).toArray();
|
|
40649
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
40650
|
+
import_nodejs_utils62.logger.log({
|
|
40651
|
+
level: "info",
|
|
40652
|
+
message: `Cache set for personnel by classification: ${cacheKey}`
|
|
40653
|
+
});
|
|
40654
|
+
}).catch((err) => {
|
|
40655
|
+
import_nodejs_utils62.logger.log({
|
|
40656
|
+
level: "error",
|
|
40657
|
+
message: `Failed to set cache for personnel by classification: ${err.message}`
|
|
40658
|
+
});
|
|
40659
|
+
});
|
|
40660
|
+
return result;
|
|
40661
|
+
} catch (error) {
|
|
40662
|
+
if (error instanceof import_nodejs_utils62.AppError) {
|
|
40663
|
+
throw error;
|
|
40664
|
+
} else {
|
|
40665
|
+
throw new import_nodejs_utils62.InternalServerError(
|
|
40666
|
+
"Failed to get personnel by classification."
|
|
40667
|
+
);
|
|
40668
|
+
}
|
|
40669
|
+
}
|
|
40670
|
+
}
|
|
40671
|
+
function delCachedData() {
|
|
40672
|
+
delNamespace().then(() => {
|
|
40673
|
+
import_nodejs_utils62.logger.log({
|
|
40674
|
+
level: "info",
|
|
40675
|
+
message: `Cache cleared for namespace: ${namespace_collection}`
|
|
40676
|
+
});
|
|
40677
|
+
}).catch((err) => {
|
|
40678
|
+
import_nodejs_utils62.logger.log({
|
|
40679
|
+
level: "error",
|
|
40680
|
+
message: `Failed to clear cache for namespace: ${namespace_collection}: ${err.message}`
|
|
40681
|
+
});
|
|
40682
|
+
});
|
|
40683
|
+
}
|
|
40684
|
+
return {
|
|
40685
|
+
createIndexes,
|
|
40686
|
+
add,
|
|
40687
|
+
updateById,
|
|
40688
|
+
getAll,
|
|
40689
|
+
getById,
|
|
40690
|
+
deleteById,
|
|
40691
|
+
getByClassification,
|
|
40692
|
+
delCachedData
|
|
40693
|
+
};
|
|
40694
|
+
}
|
|
40695
|
+
|
|
40696
|
+
// src/resources/personnel/personnel.controller.ts
|
|
40697
|
+
var import_nodejs_utils63 = require("@eeplatform/nodejs-utils");
|
|
40698
|
+
var import_joi36 = __toESM(require("joi"));
|
|
40699
|
+
function usePersonnelController() {
|
|
40700
|
+
const {
|
|
40701
|
+
getAll: _getAll,
|
|
40702
|
+
getById: _getById,
|
|
40703
|
+
add: _add,
|
|
40704
|
+
updateById: _updateById,
|
|
40705
|
+
deleteById: _deleteById,
|
|
40706
|
+
getByClassification: _getByClassification
|
|
40707
|
+
} = usePersonnelRepo();
|
|
40708
|
+
async function add(req, res, next) {
|
|
40709
|
+
const value = req.body;
|
|
40710
|
+
const { error } = schemaPersonnel.validate(value);
|
|
40711
|
+
if (error) {
|
|
40712
|
+
next(new import_nodejs_utils63.BadRequestError(error.message));
|
|
40713
|
+
import_nodejs_utils63.logger.info(`Controller: ${error.message}`);
|
|
40714
|
+
return;
|
|
40715
|
+
}
|
|
40716
|
+
try {
|
|
40717
|
+
const result = await _add(value);
|
|
40718
|
+
res.json(result);
|
|
40719
|
+
return;
|
|
40720
|
+
} catch (error2) {
|
|
40721
|
+
next(error2);
|
|
40722
|
+
}
|
|
40723
|
+
}
|
|
40724
|
+
async function updateById(req, res, next) {
|
|
40725
|
+
const value = req.body;
|
|
40726
|
+
const id = req.params.id ?? "";
|
|
40727
|
+
const validation = import_joi36.default.object({
|
|
40728
|
+
id: import_joi36.default.string().hex().required(),
|
|
40729
|
+
value: import_joi36.default.object({
|
|
40730
|
+
firstName: import_joi36.default.string().optional(),
|
|
40731
|
+
lastName: import_joi36.default.string().optional(),
|
|
40732
|
+
middleName: import_joi36.default.string().optional().allow("", null),
|
|
40733
|
+
classification: import_joi36.default.string().optional(),
|
|
40734
|
+
status: import_joi36.default.string().optional()
|
|
40735
|
+
}).min(1)
|
|
40736
|
+
});
|
|
40737
|
+
const { error } = validation.validate({ id, value });
|
|
40738
|
+
if (error) {
|
|
40739
|
+
next(new import_nodejs_utils63.BadRequestError(error.message));
|
|
40740
|
+
import_nodejs_utils63.logger.info(`Controller: ${error.message}`);
|
|
40741
|
+
return;
|
|
40742
|
+
}
|
|
40743
|
+
try {
|
|
40744
|
+
const result = await _updateById(id, value);
|
|
40745
|
+
res.json(result);
|
|
40746
|
+
return;
|
|
40747
|
+
} catch (error2) {
|
|
40748
|
+
next(error2);
|
|
40749
|
+
}
|
|
40750
|
+
}
|
|
40751
|
+
async function getAll(req, res, next) {
|
|
40752
|
+
const query = req.query;
|
|
40753
|
+
const validation = import_joi36.default.object({
|
|
40754
|
+
page: import_joi36.default.number().min(1).optional().allow("", null),
|
|
40755
|
+
limit: import_joi36.default.number().min(1).optional().allow("", null),
|
|
40756
|
+
search: import_joi36.default.string().optional().allow("", null),
|
|
40757
|
+
status: import_joi36.default.string().optional().allow("", null),
|
|
40758
|
+
classification: import_joi36.default.string().optional().allow("", null)
|
|
40759
|
+
});
|
|
40760
|
+
const { error } = validation.validate(query);
|
|
40761
|
+
if (error) {
|
|
40762
|
+
next(new import_nodejs_utils63.BadRequestError(error.message));
|
|
40763
|
+
return;
|
|
40764
|
+
}
|
|
40765
|
+
const page = parseInt(req.query.page) ?? 1;
|
|
40766
|
+
let limit = parseInt(req.query.limit) ?? 20;
|
|
40767
|
+
limit = isNaN(limit) ? 20 : limit;
|
|
40768
|
+
const sort = req.query.sort ? String(req.query.sort).split(",") : "";
|
|
40769
|
+
const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
|
|
40770
|
+
const sortObj = {};
|
|
40771
|
+
if (sort && Array.isArray(sort) && sort.length && sortOrder && Array.isArray(sortOrder) && sortOrder.length) {
|
|
40772
|
+
sort.forEach((field, index) => {
|
|
40773
|
+
sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
|
|
40774
|
+
});
|
|
40775
|
+
}
|
|
40776
|
+
const status = req.query.status ?? "active";
|
|
40777
|
+
const search = req.query.search ?? "";
|
|
40778
|
+
try {
|
|
40779
|
+
const personnel = await _getAll({
|
|
40780
|
+
page,
|
|
40781
|
+
limit,
|
|
40782
|
+
sort: sortObj,
|
|
40783
|
+
status,
|
|
40784
|
+
search
|
|
40785
|
+
});
|
|
40786
|
+
res.json(personnel);
|
|
40787
|
+
return;
|
|
40788
|
+
} catch (error2) {
|
|
40789
|
+
next(error2);
|
|
40790
|
+
}
|
|
40791
|
+
}
|
|
40792
|
+
async function getAllBySchool(req, res, next) {
|
|
40793
|
+
const school = req.params.school;
|
|
40794
|
+
const schoolValidation = import_joi36.default.string().hex().required();
|
|
40795
|
+
const { error: schoolError } = schoolValidation.validate(school);
|
|
40796
|
+
if (schoolError) {
|
|
40797
|
+
next(new import_nodejs_utils63.BadRequestError(schoolError.message));
|
|
40798
|
+
return;
|
|
40799
|
+
}
|
|
40800
|
+
const query = req.query;
|
|
40801
|
+
const validation = import_joi36.default.object({
|
|
40802
|
+
page: import_joi36.default.number().min(1).optional().allow("", null),
|
|
40803
|
+
limit: import_joi36.default.number().min(1).optional().allow("", null),
|
|
40804
|
+
search: import_joi36.default.string().optional().allow("", null),
|
|
40805
|
+
status: import_joi36.default.string().optional().allow("", null),
|
|
40806
|
+
classification: import_joi36.default.string().optional().allow("", null)
|
|
40807
|
+
});
|
|
40808
|
+
const { error } = validation.validate(query);
|
|
40809
|
+
if (error) {
|
|
40810
|
+
next(new import_nodejs_utils63.BadRequestError(error.message));
|
|
40811
|
+
return;
|
|
40812
|
+
}
|
|
40813
|
+
const page = parseInt(req.query.page) ?? 1;
|
|
40814
|
+
let limit = parseInt(req.query.limit) ?? 20;
|
|
40815
|
+
limit = isNaN(limit) ? 20 : limit;
|
|
40816
|
+
const sort = req.query.sort ? String(req.query.sort).split(",") : "";
|
|
40817
|
+
const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
|
|
40818
|
+
const sortObj = {};
|
|
40819
|
+
if (sort && Array.isArray(sort) && sort.length && sortOrder && Array.isArray(sortOrder) && sortOrder.length) {
|
|
40820
|
+
sort.forEach((field, index) => {
|
|
40821
|
+
sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
|
|
40822
|
+
});
|
|
40823
|
+
}
|
|
40824
|
+
const status = req.query.status ?? "active";
|
|
40825
|
+
const search = req.query.search ?? "";
|
|
40826
|
+
try {
|
|
40827
|
+
const personnel = await _getAll({
|
|
40828
|
+
school,
|
|
40829
|
+
page,
|
|
40830
|
+
limit,
|
|
40831
|
+
sort: sortObj,
|
|
40832
|
+
status,
|
|
40833
|
+
search
|
|
40834
|
+
});
|
|
40835
|
+
res.json(personnel);
|
|
40836
|
+
return;
|
|
40837
|
+
} catch (error2) {
|
|
40838
|
+
next(error2);
|
|
40839
|
+
}
|
|
40840
|
+
}
|
|
40841
|
+
async function getById(req, res, next) {
|
|
40842
|
+
const id = req.params.id;
|
|
40843
|
+
const validation = import_joi36.default.object({
|
|
40844
|
+
id: import_joi36.default.string().hex().required()
|
|
40845
|
+
});
|
|
40846
|
+
const { error } = validation.validate({ id });
|
|
40847
|
+
if (error) {
|
|
40848
|
+
next(new import_nodejs_utils63.BadRequestError(error.message));
|
|
40849
|
+
return;
|
|
40850
|
+
}
|
|
40851
|
+
try {
|
|
40852
|
+
const personnel = await _getById(id);
|
|
40853
|
+
res.json({
|
|
40854
|
+
message: "Successfully retrieved personnel.",
|
|
40855
|
+
data: personnel
|
|
40856
|
+
});
|
|
40857
|
+
return;
|
|
40858
|
+
} catch (error2) {
|
|
40859
|
+
next(error2);
|
|
40860
|
+
}
|
|
40861
|
+
}
|
|
40862
|
+
async function deleteById(req, res, next) {
|
|
40863
|
+
const id = req.params.id;
|
|
40864
|
+
const validation = import_joi36.default.object({
|
|
40865
|
+
id: import_joi36.default.string().hex().required()
|
|
40866
|
+
});
|
|
40867
|
+
const { error } = validation.validate({ id });
|
|
40868
|
+
if (error) {
|
|
40869
|
+
next(new import_nodejs_utils63.BadRequestError(error.message));
|
|
40870
|
+
return;
|
|
40871
|
+
}
|
|
40872
|
+
try {
|
|
40873
|
+
const result = await _deleteById(id);
|
|
40874
|
+
res.json({
|
|
40875
|
+
message: "Successfully deleted personnel.",
|
|
40876
|
+
data: result
|
|
40877
|
+
});
|
|
40878
|
+
return;
|
|
40879
|
+
} catch (error2) {
|
|
40880
|
+
next(error2);
|
|
40881
|
+
}
|
|
40882
|
+
}
|
|
40883
|
+
async function getByClassification(req, res, next) {
|
|
40884
|
+
const classification = req.params.classification;
|
|
40885
|
+
const validation = import_joi36.default.object({
|
|
40886
|
+
classification: import_joi36.default.string().required()
|
|
40887
|
+
});
|
|
40888
|
+
const { error } = validation.validate({ classification });
|
|
40889
|
+
if (error) {
|
|
40890
|
+
next(new import_nodejs_utils63.BadRequestError(error.message));
|
|
40891
|
+
return;
|
|
40892
|
+
}
|
|
40893
|
+
try {
|
|
40894
|
+
const personnel = await _getByClassification(classification);
|
|
40895
|
+
res.json({
|
|
40896
|
+
message: "Successfully retrieved personnel by classification.",
|
|
40897
|
+
data: personnel
|
|
40898
|
+
});
|
|
40899
|
+
return;
|
|
40900
|
+
} catch (error2) {
|
|
40901
|
+
next(error2);
|
|
40902
|
+
}
|
|
40903
|
+
}
|
|
40904
|
+
return {
|
|
40905
|
+
add,
|
|
40906
|
+
updateById,
|
|
40907
|
+
getAll,
|
|
40908
|
+
getAllBySchool,
|
|
40909
|
+
getById,
|
|
40910
|
+
deleteById,
|
|
40911
|
+
getByClassification
|
|
40912
|
+
};
|
|
40913
|
+
}
|
|
40914
|
+
|
|
38354
40915
|
// src/config.ts
|
|
38355
40916
|
var dotenv = __toESM(require("dotenv"));
|
|
38356
40917
|
dotenv.config();
|
|
38357
40918
|
// Annotate the CommonJS export names for ESM import in node:
|
|
38358
40919
|
0 && (module.exports = {
|
|
38359
40920
|
MAsset,
|
|
40921
|
+
MBuilding,
|
|
40922
|
+
MBuildingUnit,
|
|
38360
40923
|
MCurriculum,
|
|
38361
40924
|
MCurriculumSubject,
|
|
38362
40925
|
MGradeLevel,
|
|
38363
40926
|
MLearner,
|
|
40927
|
+
MPersonnel,
|
|
38364
40928
|
MPlantilla,
|
|
38365
40929
|
MStockCard,
|
|
38366
40930
|
allowedSectionStudentStatuses,
|
|
@@ -38371,9 +40935,12 @@ dotenv.config();
|
|
|
38371
40935
|
modelSection,
|
|
38372
40936
|
modelSectionPreset,
|
|
38373
40937
|
modelSectionStudent,
|
|
40938
|
+
modelSectionSubject,
|
|
38374
40939
|
schemaAsset,
|
|
38375
40940
|
schemaAssetUpdateOption,
|
|
38376
40941
|
schemaBasicEduCount,
|
|
40942
|
+
schemaBuilding,
|
|
40943
|
+
schemaBuildingUnit,
|
|
38377
40944
|
schemaCurriculum,
|
|
38378
40945
|
schemaCurriculumSubject,
|
|
38379
40946
|
schemaCurriculumSubjectAdd,
|
|
@@ -38382,6 +40949,7 @@ dotenv.config();
|
|
|
38382
40949
|
schemaEnrollment,
|
|
38383
40950
|
schemaGenerateSections,
|
|
38384
40951
|
schemaGradeLevel,
|
|
40952
|
+
schemaPersonnel,
|
|
38385
40953
|
schemaPlantilla,
|
|
38386
40954
|
schemaRegion,
|
|
38387
40955
|
schemaSchool,
|
|
@@ -38389,11 +40957,20 @@ dotenv.config();
|
|
|
38389
40957
|
schemaSection,
|
|
38390
40958
|
schemaSectionPreset,
|
|
38391
40959
|
schemaSectionStudent,
|
|
40960
|
+
schemaSectionSubject,
|
|
40961
|
+
schemaSectionSubjectSetup,
|
|
38392
40962
|
schemaStockCard,
|
|
40963
|
+
schemaUpdateOptions,
|
|
38393
40964
|
schemaUpdateStatus,
|
|
38394
40965
|
useAssetController,
|
|
38395
40966
|
useAssetRepo,
|
|
38396
40967
|
useBasicEduCountRepo,
|
|
40968
|
+
useBuildingController,
|
|
40969
|
+
useBuildingRepo,
|
|
40970
|
+
useBuildingService,
|
|
40971
|
+
useBuildingUnitController,
|
|
40972
|
+
useBuildingUnitRepo,
|
|
40973
|
+
useBuildingUnitService,
|
|
38397
40974
|
useCurriculumController,
|
|
38398
40975
|
useCurriculumRepo,
|
|
38399
40976
|
useCurriculumSubjectController,
|
|
@@ -38409,6 +40986,8 @@ dotenv.config();
|
|
|
38409
40986
|
useGradeLevelRepo,
|
|
38410
40987
|
useLearnerController,
|
|
38411
40988
|
useLearnerRepo,
|
|
40989
|
+
usePersonnelController,
|
|
40990
|
+
usePersonnelRepo,
|
|
38412
40991
|
usePlantillaController,
|
|
38413
40992
|
usePlantillaRepo,
|
|
38414
40993
|
usePlantillaService,
|
|
@@ -38422,6 +41001,9 @@ dotenv.config();
|
|
|
38422
41001
|
useSectionPresetRepo,
|
|
38423
41002
|
useSectionRepo,
|
|
38424
41003
|
useSectionStudentRepo,
|
|
41004
|
+
useSectionSubjectController,
|
|
41005
|
+
useSectionSubjectRepo,
|
|
41006
|
+
useSectionSubjectService,
|
|
38425
41007
|
useStockCardController,
|
|
38426
41008
|
useStockCardRepository,
|
|
38427
41009
|
useStockCardService
|