@eeplatform/basic-edu 1.10.0 → 1.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/index.d.ts +36 -8
- package/dist/index.js +2169 -1922
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2010 -1763
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2878,8 +2878,7 @@ var schemaUpdateStatus = Joi5.object({
|
|
|
2878
2878
|
status: Joi5.string().valid("pending", "accepted", "rejected", "cancelled").required()
|
|
2879
2879
|
});
|
|
2880
2880
|
var gradeLevels = [
|
|
2881
|
-
"
|
|
2882
|
-
"K2",
|
|
2881
|
+
"kindergarten",
|
|
2883
2882
|
"grade-1",
|
|
2884
2883
|
"grade-2",
|
|
2885
2884
|
"grade-3",
|
|
@@ -38854,7 +38853,6 @@ var schemaSectionPreset = Joi29.object({
|
|
|
38854
38853
|
description: Joi29.string().max(500).optional().allow(null, ""),
|
|
38855
38854
|
set: Joi29.array().items(Joi29.string()).required(),
|
|
38856
38855
|
school: Joi29.string().hex().required(),
|
|
38857
|
-
createdBy: Joi29.string().hex().required(),
|
|
38858
38856
|
createdAt: Joi29.string().isoDate().optional(),
|
|
38859
38857
|
updatedAt: Joi29.string().isoDate().optional(),
|
|
38860
38858
|
deletedAt: Joi29.string().isoDate().optional().allow(null, "")
|
|
@@ -38871,13 +38869,6 @@ function modelSectionPreset(value) {
|
|
|
38871
38869
|
throw new Error("Invalid _id.");
|
|
38872
38870
|
}
|
|
38873
38871
|
}
|
|
38874
|
-
if (value.createdBy && typeof value.createdBy === "string") {
|
|
38875
|
-
try {
|
|
38876
|
-
value.createdBy = new ObjectId27(value.createdBy);
|
|
38877
|
-
} catch (error2) {
|
|
38878
|
-
throw new Error("Invalid createdBy.");
|
|
38879
|
-
}
|
|
38880
|
-
}
|
|
38881
38872
|
if (value.school && typeof value.school === "string") {
|
|
38882
38873
|
try {
|
|
38883
38874
|
value.school = new ObjectId27(value.school);
|
|
@@ -38892,7 +38883,6 @@ function modelSectionPreset(value) {
|
|
|
38892
38883
|
set: value.set,
|
|
38893
38884
|
status: value.status ?? "active",
|
|
38894
38885
|
school: value.school,
|
|
38895
|
-
createdBy: value.createdBy,
|
|
38896
38886
|
createdAt: value.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
38897
38887
|
updatedAt: value.updatedAt ?? "",
|
|
38898
38888
|
deletedAt: value.deletedAt ?? ""
|
|
@@ -38922,12 +38912,13 @@ function useSectionPresetRepo() {
|
|
|
38922
38912
|
async function createIndexes() {
|
|
38923
38913
|
try {
|
|
38924
38914
|
await collection.createIndexes([
|
|
38915
|
+
{ key: { school: 1 } },
|
|
38925
38916
|
{ key: { name: 1 } },
|
|
38926
38917
|
{ key: { createdAt: 1 } },
|
|
38927
38918
|
{ key: { createdBy: 1 } },
|
|
38928
38919
|
{ key: { name: "text", description: "text" } },
|
|
38929
38920
|
{
|
|
38930
|
-
key: { name: 1, status: 1 },
|
|
38921
|
+
key: { school: 1, name: 1, status: 1 },
|
|
38931
38922
|
unique: true,
|
|
38932
38923
|
name: "unique_section_preset"
|
|
38933
38924
|
}
|
|
@@ -39361,6 +39352,7 @@ var schemaSection = Joi31.object({
|
|
|
39361
39352
|
_id: Joi31.string().hex().optional().allow(null, ""),
|
|
39362
39353
|
school: Joi31.string().hex().required(),
|
|
39363
39354
|
name: Joi31.string().min(1).max(100).required(),
|
|
39355
|
+
label: Joi31.string().max(100).optional().allow(null, ""),
|
|
39364
39356
|
schoolYear: Joi31.string().required(),
|
|
39365
39357
|
gradeLevel: Joi31.string().required(),
|
|
39366
39358
|
students: Joi31.number().integer().min(0).optional(),
|
|
@@ -39377,8 +39369,7 @@ var schemaGenerateSections = Joi31.object({
|
|
|
39377
39369
|
gradeLevel: Joi31.string().required(),
|
|
39378
39370
|
minStudents: Joi31.number().integer().min(1).required(),
|
|
39379
39371
|
maxStudents: Joi31.number().integer().min(Joi31.ref("minStudents")).required(),
|
|
39380
|
-
specialProgram: Joi31.string().hex().optional().allow(null, "")
|
|
39381
|
-
set: Joi31.array().items(Joi31.string().min(1).max(100)).required()
|
|
39372
|
+
specialProgram: Joi31.string().hex().optional().allow(null, "")
|
|
39382
39373
|
});
|
|
39383
39374
|
function modelSection(value) {
|
|
39384
39375
|
const { error } = schemaSection.validate(value);
|
|
@@ -39410,6 +39401,7 @@ function modelSection(value) {
|
|
|
39410
39401
|
_id: value._id,
|
|
39411
39402
|
school: value.school,
|
|
39412
39403
|
name: value.name,
|
|
39404
|
+
label: value.label ?? "",
|
|
39413
39405
|
schoolYear: value.schoolYear,
|
|
39414
39406
|
gradeLevel: value.gradeLevel,
|
|
39415
39407
|
adviser: value.adviser,
|
|
@@ -39453,7 +39445,7 @@ function useSectionRepo() {
|
|
|
39453
39445
|
{ key: { createdAt: 1 } },
|
|
39454
39446
|
{ key: { name: "text", schoolYear: "text", gradeLevel: "text" } },
|
|
39455
39447
|
{
|
|
39456
|
-
key: { school: 1,
|
|
39448
|
+
key: { school: 1, teacher: 1, schoolYear: 1, status: 1 },
|
|
39457
39449
|
unique: true,
|
|
39458
39450
|
name: "unique_section"
|
|
39459
39451
|
}
|
|
@@ -39480,7 +39472,7 @@ function useSectionRepo() {
|
|
|
39480
39472
|
value = modelSection(value);
|
|
39481
39473
|
const res = await collection.insertOne(value, { session });
|
|
39482
39474
|
delCachedData();
|
|
39483
|
-
return res.insertedId;
|
|
39475
|
+
return res.insertedId.toString();
|
|
39484
39476
|
} catch (error) {
|
|
39485
39477
|
logger27.log({
|
|
39486
39478
|
level: "error",
|
|
@@ -39621,6 +39613,54 @@ function useSectionRepo() {
|
|
|
39621
39613
|
}
|
|
39622
39614
|
}
|
|
39623
39615
|
}
|
|
39616
|
+
async function getSection(options) {
|
|
39617
|
+
const query = {};
|
|
39618
|
+
const cacheKeyOptions = { tag: "getSection" };
|
|
39619
|
+
try {
|
|
39620
|
+
query.school = new ObjectId30(options.school);
|
|
39621
|
+
cacheKeyOptions.school = String(options.school);
|
|
39622
|
+
} catch (error) {
|
|
39623
|
+
throw new BadRequestError49("Invalid school ID.");
|
|
39624
|
+
}
|
|
39625
|
+
query.gradeLevel = options.gradeLevel;
|
|
39626
|
+
cacheKeyOptions.gradeLevel = options.gradeLevel;
|
|
39627
|
+
query.name = options.name;
|
|
39628
|
+
cacheKeyOptions.name = options.name;
|
|
39629
|
+
if (options.schoolYear) {
|
|
39630
|
+
query.schoolYear = options.schoolYear;
|
|
39631
|
+
cacheKeyOptions.schoolYear = options.schoolYear;
|
|
39632
|
+
}
|
|
39633
|
+
const cacheKey = makeCacheKey16(namespace_collection, cacheKeyOptions);
|
|
39634
|
+
try {
|
|
39635
|
+
const cached = await getCache(cacheKey);
|
|
39636
|
+
if (cached) {
|
|
39637
|
+
logger27.log({
|
|
39638
|
+
level: "info",
|
|
39639
|
+
message: `Cache hit for getSection: ${cacheKey}`
|
|
39640
|
+
});
|
|
39641
|
+
return cached;
|
|
39642
|
+
}
|
|
39643
|
+
const result = await collection.findOne(query);
|
|
39644
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
39645
|
+
logger27.log({
|
|
39646
|
+
level: "info",
|
|
39647
|
+
message: `Cache set for section: ${cacheKey}`
|
|
39648
|
+
});
|
|
39649
|
+
}).catch((err) => {
|
|
39650
|
+
logger27.log({
|
|
39651
|
+
level: "error",
|
|
39652
|
+
message: `Failed to set cache for section: ${err.message}`
|
|
39653
|
+
});
|
|
39654
|
+
});
|
|
39655
|
+
return result;
|
|
39656
|
+
} catch (error) {
|
|
39657
|
+
if (error instanceof AppError17) {
|
|
39658
|
+
throw error;
|
|
39659
|
+
} else {
|
|
39660
|
+
throw new InternalServerError14("Failed to get section.");
|
|
39661
|
+
}
|
|
39662
|
+
}
|
|
39663
|
+
}
|
|
39624
39664
|
async function getByName(name) {
|
|
39625
39665
|
const cacheKey = makeCacheKey16(namespace_collection, { name });
|
|
39626
39666
|
try {
|
|
@@ -39804,6 +39844,7 @@ function useSectionRepo() {
|
|
|
39804
39844
|
add,
|
|
39805
39845
|
getAll,
|
|
39806
39846
|
getById,
|
|
39847
|
+
getSection,
|
|
39807
39848
|
getByName,
|
|
39808
39849
|
getBySchool,
|
|
39809
39850
|
updateFieldById,
|
|
@@ -39814,15 +39855,15 @@ function useSectionRepo() {
|
|
|
39814
39855
|
}
|
|
39815
39856
|
|
|
39816
39857
|
// src/resources/section/section.controller.ts
|
|
39817
|
-
import { BadRequestError as
|
|
39818
|
-
import
|
|
39858
|
+
import { BadRequestError as BadRequestError65 } from "@eeplatform/nodejs-utils";
|
|
39859
|
+
import Joi43 from "joi";
|
|
39819
39860
|
|
|
39820
39861
|
// src/resources/section/section.service.ts
|
|
39821
39862
|
import {
|
|
39822
|
-
AppError as
|
|
39823
|
-
BadRequestError as
|
|
39824
|
-
InternalServerError as
|
|
39825
|
-
useAtlas as
|
|
39863
|
+
AppError as AppError25,
|
|
39864
|
+
BadRequestError as BadRequestError64,
|
|
39865
|
+
InternalServerError as InternalServerError21,
|
|
39866
|
+
useAtlas as useAtlas30
|
|
39826
39867
|
} from "@eeplatform/nodejs-utils";
|
|
39827
39868
|
|
|
39828
39869
|
// src/resources/section-student/section.student.repository.ts
|
|
@@ -40062,11 +40103,73 @@ function useSectionStudentRepo() {
|
|
|
40062
40103
|
});
|
|
40063
40104
|
return data;
|
|
40064
40105
|
}
|
|
40106
|
+
async function getStudent(options) {
|
|
40107
|
+
const query = {};
|
|
40108
|
+
const cacheKeyOptions = { tag: "getStudent" };
|
|
40109
|
+
if (options.learner) {
|
|
40110
|
+
try {
|
|
40111
|
+
query.learner = new ObjectId32(options.learner);
|
|
40112
|
+
cacheKeyOptions.learner = String(options.learner);
|
|
40113
|
+
} catch (error) {
|
|
40114
|
+
throw new BadRequestError51("Invalid learner ID.");
|
|
40115
|
+
}
|
|
40116
|
+
}
|
|
40117
|
+
if (options.schoolYear) {
|
|
40118
|
+
query.schoolYear = options.schoolYear;
|
|
40119
|
+
cacheKeyOptions.schoolYear = options.schoolYear;
|
|
40120
|
+
}
|
|
40121
|
+
if (options.section) {
|
|
40122
|
+
try {
|
|
40123
|
+
query.section = new ObjectId32(options.section);
|
|
40124
|
+
cacheKeyOptions.section = String(options.section);
|
|
40125
|
+
} catch (error) {
|
|
40126
|
+
throw new BadRequestError51("Invalid section ID.");
|
|
40127
|
+
}
|
|
40128
|
+
}
|
|
40129
|
+
if (options.gradeLevel) {
|
|
40130
|
+
query.gradeLevel = options.gradeLevel;
|
|
40131
|
+
cacheKeyOptions.gradeLevel = options.gradeLevel;
|
|
40132
|
+
}
|
|
40133
|
+
try {
|
|
40134
|
+
query.student = new ObjectId32(options.student);
|
|
40135
|
+
cacheKeyOptions.student = String(options.student);
|
|
40136
|
+
} catch (error) {
|
|
40137
|
+
throw new BadRequestError51("Invalid student ID.");
|
|
40138
|
+
}
|
|
40139
|
+
const cacheKey = makeCacheKey17(namespace_collection, cacheKeyOptions);
|
|
40140
|
+
try {
|
|
40141
|
+
const cached = await getCache(cacheKey);
|
|
40142
|
+
if (cached) {
|
|
40143
|
+
logger28.log({
|
|
40144
|
+
level: "info",
|
|
40145
|
+
message: `Cache hit for getStudent section student: ${cacheKey}`
|
|
40146
|
+
});
|
|
40147
|
+
return cached;
|
|
40148
|
+
}
|
|
40149
|
+
const item = await collection.findOne(query);
|
|
40150
|
+
setCache(cacheKey, item, 600).then(() => {
|
|
40151
|
+
logger28.log({
|
|
40152
|
+
level: "info",
|
|
40153
|
+
message: `Cache set for getStudent section student: ${cacheKey}`
|
|
40154
|
+
});
|
|
40155
|
+
}).catch((err) => {
|
|
40156
|
+
logger28.log({
|
|
40157
|
+
level: "error",
|
|
40158
|
+
message: `Failed to set cache for getStudent section student: ${err.message}`
|
|
40159
|
+
});
|
|
40160
|
+
});
|
|
40161
|
+
return item;
|
|
40162
|
+
} catch (error) {
|
|
40163
|
+
logger28.log({ level: "error", message: `${error}` });
|
|
40164
|
+
throw error;
|
|
40165
|
+
}
|
|
40166
|
+
}
|
|
40065
40167
|
return {
|
|
40066
40168
|
createIndexes,
|
|
40067
40169
|
delCachedData,
|
|
40068
40170
|
add,
|
|
40069
|
-
getAll
|
|
40171
|
+
getAll,
|
|
40172
|
+
getStudent
|
|
40070
40173
|
};
|
|
40071
40174
|
}
|
|
40072
40175
|
|
|
@@ -40412,6 +40515,63 @@ function useSectionSubjectRepo() {
|
|
|
40412
40515
|
}
|
|
40413
40516
|
}
|
|
40414
40517
|
}
|
|
40518
|
+
async function getSectionSubject(options) {
|
|
40519
|
+
const query = {};
|
|
40520
|
+
const cacheKeyOptions = { tag: "getSectionSubject" };
|
|
40521
|
+
if (options.gradeLevel) {
|
|
40522
|
+
query.gradeLevel = options.gradeLevel;
|
|
40523
|
+
cacheKeyOptions.gradeLevel = options.gradeLevel;
|
|
40524
|
+
}
|
|
40525
|
+
if (options.schoolYear) {
|
|
40526
|
+
query.schoolYear = options.schoolYear;
|
|
40527
|
+
cacheKeyOptions.schoolYear = options.schoolYear;
|
|
40528
|
+
}
|
|
40529
|
+
if (options.subjectCode) {
|
|
40530
|
+
query.subjectCode = options.subjectCode;
|
|
40531
|
+
cacheKeyOptions.subjectCode = options.subjectCode;
|
|
40532
|
+
}
|
|
40533
|
+
try {
|
|
40534
|
+
query.section = new ObjectId34(options.section);
|
|
40535
|
+
cacheKeyOptions.section = String(options.section);
|
|
40536
|
+
} catch (error) {
|
|
40537
|
+
throw new BadRequestError53("Invalid section ID.");
|
|
40538
|
+
}
|
|
40539
|
+
const cacheKey = makeCacheKey18(namespace_collection, cacheKeyOptions);
|
|
40540
|
+
try {
|
|
40541
|
+
const cached = await getCache(cacheKey);
|
|
40542
|
+
if (cached) {
|
|
40543
|
+
logger29.log({
|
|
40544
|
+
level: "info",
|
|
40545
|
+
message: `Cache hit for getSectionSubject section subjects: ${cacheKey}`
|
|
40546
|
+
});
|
|
40547
|
+
return cached;
|
|
40548
|
+
}
|
|
40549
|
+
const result = await collection.find({
|
|
40550
|
+
...query,
|
|
40551
|
+
deletedAt: { $in: ["", null] }
|
|
40552
|
+
}).toArray();
|
|
40553
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
40554
|
+
logger29.log({
|
|
40555
|
+
level: "info",
|
|
40556
|
+
message: `Cache set for section subjects by getSectionSubject: ${cacheKey}`
|
|
40557
|
+
});
|
|
40558
|
+
}).catch((err) => {
|
|
40559
|
+
logger29.log({
|
|
40560
|
+
level: "error",
|
|
40561
|
+
message: `Failed to set cache for section subjects by getSectionSubject: ${err.message}`
|
|
40562
|
+
});
|
|
40563
|
+
});
|
|
40564
|
+
return result;
|
|
40565
|
+
} catch (error) {
|
|
40566
|
+
if (error instanceof AppError19) {
|
|
40567
|
+
throw error;
|
|
40568
|
+
} else {
|
|
40569
|
+
throw new InternalServerError16(
|
|
40570
|
+
"Failed to get section subjects by getSectionSubject."
|
|
40571
|
+
);
|
|
40572
|
+
}
|
|
40573
|
+
}
|
|
40574
|
+
}
|
|
40415
40575
|
async function getBySection(section) {
|
|
40416
40576
|
try {
|
|
40417
40577
|
section = new ObjectId34(section);
|
|
@@ -40644,6 +40804,7 @@ function useSectionSubjectRepo() {
|
|
|
40644
40804
|
add,
|
|
40645
40805
|
getAll,
|
|
40646
40806
|
getById,
|
|
40807
|
+
getSectionSubject,
|
|
40647
40808
|
getBySection,
|
|
40648
40809
|
getByTeacher,
|
|
40649
40810
|
getBySchool,
|
|
@@ -41033,7 +41194,13 @@ function useTeachingLoadRepo() {
|
|
|
41033
41194
|
{ key: { status: 1 } },
|
|
41034
41195
|
{ key: { school: 1 } },
|
|
41035
41196
|
{ key: { teacher: 1 } },
|
|
41036
|
-
{ key: {
|
|
41197
|
+
{ key: { gradeLevel: 1 } },
|
|
41198
|
+
{ key: { schoolYear: 1 } },
|
|
41199
|
+
{
|
|
41200
|
+
key: { school: 1, teacher: 1, schoolYear: 1, gradeLevel: 1 },
|
|
41201
|
+
unique: true,
|
|
41202
|
+
name: "unique_teaching_load_index"
|
|
41203
|
+
}
|
|
41037
41204
|
]);
|
|
41038
41205
|
} catch (error) {
|
|
41039
41206
|
throw new Error("Failed to create index on teaching load.");
|
|
@@ -41053,7 +41220,11 @@ function useTeachingLoadRepo() {
|
|
|
41053
41220
|
if (error instanceof AppError21) {
|
|
41054
41221
|
throw error;
|
|
41055
41222
|
} else {
|
|
41056
|
-
|
|
41223
|
+
const isDuplicated = error.message.includes("duplicate");
|
|
41224
|
+
if (isDuplicated) {
|
|
41225
|
+
throw new BadRequestError56("Teaching load already exist.");
|
|
41226
|
+
}
|
|
41227
|
+
throw new InternalServerError18("Failed to create teaching load.");
|
|
41057
41228
|
}
|
|
41058
41229
|
}
|
|
41059
41230
|
}
|
|
@@ -41258,23 +41429,32 @@ function useTeachingLoadRepo() {
|
|
|
41258
41429
|
}
|
|
41259
41430
|
}
|
|
41260
41431
|
}
|
|
41261
|
-
async function getByTeacher(
|
|
41432
|
+
async function getByTeacher(options) {
|
|
41433
|
+
const query = {};
|
|
41434
|
+
const cacheKeyOptions = { tag: "getByTeacher" };
|
|
41435
|
+
if (options.status) {
|
|
41436
|
+
query.status = options.status;
|
|
41437
|
+
cacheKeyOptions.status = options.status;
|
|
41438
|
+
}
|
|
41262
41439
|
try {
|
|
41263
|
-
teacher = new ObjectId36(teacher);
|
|
41440
|
+
query.teacher = new ObjectId36(options.teacher);
|
|
41264
41441
|
} catch (error) {
|
|
41265
41442
|
throw new BadRequestError56("Invalid teacher ID.");
|
|
41266
41443
|
}
|
|
41267
|
-
|
|
41268
|
-
|
|
41269
|
-
|
|
41270
|
-
|
|
41271
|
-
if (schoolYear) {
|
|
41272
|
-
query.schoolYear = schoolYear;
|
|
41444
|
+
cacheKeyOptions.teacher = String(options.teacher);
|
|
41445
|
+
if (options.schoolYear) {
|
|
41446
|
+
query.schoolYear = options.schoolYear;
|
|
41447
|
+
cacheKeyOptions.schoolYear = options.schoolYear;
|
|
41273
41448
|
}
|
|
41274
|
-
|
|
41275
|
-
|
|
41276
|
-
|
|
41277
|
-
|
|
41449
|
+
if (options.school) {
|
|
41450
|
+
try {
|
|
41451
|
+
query.school = new ObjectId36(options.school);
|
|
41452
|
+
} catch (error) {
|
|
41453
|
+
throw new BadRequestError56("Invalid school ID.");
|
|
41454
|
+
}
|
|
41455
|
+
cacheKeyOptions.school = String(options.school);
|
|
41456
|
+
}
|
|
41457
|
+
const cacheKey = makeCacheKey19(namespace_collection, cacheKeyOptions);
|
|
41278
41458
|
try {
|
|
41279
41459
|
const cached = await getCache(cacheKey);
|
|
41280
41460
|
if (cached) {
|
|
@@ -41528,7 +41708,7 @@ function useTeachingLoadController() {
|
|
|
41528
41708
|
return;
|
|
41529
41709
|
}
|
|
41530
41710
|
try {
|
|
41531
|
-
const result = await _getByTeacher(teacher, schoolYear);
|
|
41711
|
+
const result = await _getByTeacher({ teacher, schoolYear });
|
|
41532
41712
|
res.json(result);
|
|
41533
41713
|
return;
|
|
41534
41714
|
} catch (error2) {
|
|
@@ -41574,7 +41754,7 @@ function modelTeachingLoadSlot(value) {
|
|
|
41574
41754
|
const { error } = schemaTeachingLoadSlot.validate(value);
|
|
41575
41755
|
if (error) {
|
|
41576
41756
|
logger33.info(`Teaching Load Slot Model: ${error.message}`);
|
|
41577
|
-
throw new BadRequestError58(error.message);
|
|
41757
|
+
throw new BadRequestError58(`${error.message} - model`);
|
|
41578
41758
|
}
|
|
41579
41759
|
if (value._id && typeof value._id === "string") {
|
|
41580
41760
|
try {
|
|
@@ -41990,9 +42170,11 @@ function useTeachingLoadSlotController() {
|
|
|
41990
42170
|
gradeLevel: Joi40.string().required(),
|
|
41991
42171
|
startTime: Joi40.string().required(),
|
|
41992
42172
|
endTime: Joi40.string().required(),
|
|
41993
|
-
subject: Joi40.string().hex().
|
|
42173
|
+
subject: Joi40.string().hex().optional().allow("", null),
|
|
41994
42174
|
subjectName: Joi40.string().optional().allow("", null),
|
|
41995
42175
|
subjectCode: Joi40.string().optional().allow("", null),
|
|
42176
|
+
routine: Joi40.string().hex().optional().allow("", null),
|
|
42177
|
+
routineName: Joi40.string().optional().allow("", null),
|
|
41996
42178
|
section: Joi40.string().hex().required(),
|
|
41997
42179
|
sectionName: Joi40.string().optional().allow("", null),
|
|
41998
42180
|
duration: Joi40.number().min(0).required(),
|
|
@@ -42389,7 +42571,9 @@ function usePersonnelRepo() {
|
|
|
42389
42571
|
page = 1,
|
|
42390
42572
|
limit = 10,
|
|
42391
42573
|
sort = {},
|
|
42392
|
-
status = "active"
|
|
42574
|
+
status = "active",
|
|
42575
|
+
gradeLevel = "",
|
|
42576
|
+
classification = ""
|
|
42393
42577
|
} = {}) {
|
|
42394
42578
|
page = page > 0 ? page - 1 : 0;
|
|
42395
42579
|
const query = {
|
|
@@ -42413,6 +42597,14 @@ function usePersonnelRepo() {
|
|
|
42413
42597
|
}
|
|
42414
42598
|
cacheParams.school = school;
|
|
42415
42599
|
}
|
|
42600
|
+
if (gradeLevel) {
|
|
42601
|
+
query.gradeLevels = gradeLevel;
|
|
42602
|
+
cacheParams.gradeLevel = gradeLevel;
|
|
42603
|
+
}
|
|
42604
|
+
if (classification) {
|
|
42605
|
+
query.classification = classification;
|
|
42606
|
+
cacheParams.classification = classification;
|
|
42607
|
+
}
|
|
42416
42608
|
const cacheKey = makeCacheKey21(namespace_collection, cacheParams);
|
|
42417
42609
|
logger37.log({
|
|
42418
42610
|
level: "info",
|
|
@@ -42797,531 +42989,436 @@ function usePersonnelController() {
|
|
|
42797
42989
|
};
|
|
42798
42990
|
}
|
|
42799
42991
|
|
|
42800
|
-
// src/resources/
|
|
42801
|
-
|
|
42802
|
-
|
|
42803
|
-
|
|
42804
|
-
|
|
42805
|
-
|
|
42806
|
-
|
|
42807
|
-
|
|
42808
|
-
|
|
42809
|
-
|
|
42810
|
-
|
|
42811
|
-
|
|
42812
|
-
|
|
42813
|
-
|
|
42814
|
-
|
|
42815
|
-
|
|
42816
|
-
|
|
42817
|
-
|
|
42818
|
-
|
|
42819
|
-
|
|
42820
|
-
|
|
42821
|
-
|
|
42822
|
-
|
|
42823
|
-
|
|
42824
|
-
|
|
42825
|
-
|
|
42826
|
-
|
|
42827
|
-
|
|
42828
|
-
|
|
42829
|
-
|
|
42830
|
-
|
|
42831
|
-
|
|
42832
|
-
|
|
42833
|
-
|
|
42834
|
-
|
|
42835
|
-
|
|
42836
|
-
|
|
42837
|
-
|
|
42838
|
-
|
|
42839
|
-
|
|
42840
|
-
|
|
42841
|
-
|
|
42842
|
-
|
|
42843
|
-
).optional(),
|
|
42844
|
-
durationMinutes: Joi43.number().optional().allow(null, 0)
|
|
42845
|
-
});
|
|
42846
|
-
function modelKindergartenRoutine(value) {
|
|
42847
|
-
const { error } = schemaKindergartenRoutine.validate(value);
|
|
42848
|
-
if (error) {
|
|
42849
|
-
throw new BadRequestError64(`Invalid kinder schedule data: ${error.message}`);
|
|
42992
|
+
// src/resources/section/section.service.ts
|
|
42993
|
+
function useSectionService() {
|
|
42994
|
+
const { getCountByGradeLevel, getByGradeLevel: getLeanerByGradeLevel } = useLearnerRepo();
|
|
42995
|
+
const { getByGradeLevel } = useGradeLevelRepo();
|
|
42996
|
+
const { add: createSection, getSection } = useSectionRepo();
|
|
42997
|
+
const { add: assignStudent, getStudent } = useSectionStudentRepo();
|
|
42998
|
+
const { getAll: getAllCurriculumSubjects } = useSubjectRepo();
|
|
42999
|
+
const { add: addSectionSubject, getSectionSubject } = useSectionSubjectRepo();
|
|
43000
|
+
const { getById: getSchoolById } = useSchoolRepo();
|
|
43001
|
+
const { getAll: getAllPersonnel } = usePersonnelRepo();
|
|
43002
|
+
const { add: addTeachingLoad, getByTeacher } = useTeachingLoadRepo();
|
|
43003
|
+
function distributeStudents(total, minPer, maxPer) {
|
|
43004
|
+
if (total <= 0)
|
|
43005
|
+
return [];
|
|
43006
|
+
if (minPer <= 0 || maxPer <= 0)
|
|
43007
|
+
return [];
|
|
43008
|
+
if (minPer > maxPer) {
|
|
43009
|
+
throw new BadRequestError64(
|
|
43010
|
+
"Minimum students per section cannot be greater than maximum."
|
|
43011
|
+
);
|
|
43012
|
+
}
|
|
43013
|
+
const minSections = Math.ceil(total / maxPer);
|
|
43014
|
+
const maxSections = Math.floor(total / minPer);
|
|
43015
|
+
let sectionCount;
|
|
43016
|
+
if (minSections <= maxSections) {
|
|
43017
|
+
sectionCount = minSections;
|
|
43018
|
+
} else {
|
|
43019
|
+
sectionCount = minSections;
|
|
43020
|
+
}
|
|
43021
|
+
const base = Math.floor(total / sectionCount);
|
|
43022
|
+
const extra = total % sectionCount;
|
|
43023
|
+
const sizes = new Array(sectionCount).fill(base);
|
|
43024
|
+
for (let i = 0; i < extra; i++) {
|
|
43025
|
+
sizes[i] += 1;
|
|
43026
|
+
}
|
|
43027
|
+
for (const size of sizes) {
|
|
43028
|
+
if (size > maxPer) {
|
|
43029
|
+
throw new BadRequestError64(
|
|
43030
|
+
`Generated section exceeds max limit of ${maxPer}.`
|
|
43031
|
+
);
|
|
43032
|
+
}
|
|
43033
|
+
}
|
|
43034
|
+
return sizes;
|
|
42850
43035
|
}
|
|
42851
|
-
|
|
43036
|
+
async function generateSections(value) {
|
|
43037
|
+
const { error } = schemaGenerateSections.validate(value);
|
|
43038
|
+
if (error) {
|
|
43039
|
+
throw new BadRequestError64(
|
|
43040
|
+
`Invalid section generation data: ${error.message}`
|
|
43041
|
+
);
|
|
43042
|
+
}
|
|
43043
|
+
const session = useAtlas30.getClient()?.startSession();
|
|
43044
|
+
if (!session) {
|
|
43045
|
+
throw new Error("Unable to start database session.");
|
|
43046
|
+
}
|
|
42852
43047
|
try {
|
|
42853
|
-
|
|
43048
|
+
await session.startTransaction();
|
|
43049
|
+
const studentCount = await getCountByGradeLevel(
|
|
43050
|
+
{
|
|
43051
|
+
school: value.school,
|
|
43052
|
+
schoolYear: value.schoolYear,
|
|
43053
|
+
gradeLevel: value.gradeLevel,
|
|
43054
|
+
specialProgram: value.specialProgram
|
|
43055
|
+
},
|
|
43056
|
+
session
|
|
43057
|
+
);
|
|
43058
|
+
if (studentCount === 0) {
|
|
43059
|
+
throw new BadRequestError64("No learners found for this grade level.");
|
|
43060
|
+
}
|
|
43061
|
+
const gradeLevelData = await getByGradeLevel(
|
|
43062
|
+
{
|
|
43063
|
+
school: value.school,
|
|
43064
|
+
gradeLevel: value.gradeLevel
|
|
43065
|
+
},
|
|
43066
|
+
session
|
|
43067
|
+
);
|
|
43068
|
+
if (!gradeLevelData) {
|
|
43069
|
+
throw new BadRequestError64("Grade level not found.");
|
|
43070
|
+
}
|
|
43071
|
+
const minPerSection = value.minStudents ?? gradeLevelData.minNumberOfLearners;
|
|
43072
|
+
const maxPerSection = value.maxStudents ?? gradeLevelData.maxNumberOfLearners;
|
|
43073
|
+
const sectionSizes = distributeStudents(
|
|
43074
|
+
studentCount,
|
|
43075
|
+
minPerSection,
|
|
43076
|
+
maxPerSection
|
|
43077
|
+
);
|
|
43078
|
+
if (sectionSizes.length === 0) {
|
|
43079
|
+
throw new BadRequestError64("Unable to compute section sizes.");
|
|
43080
|
+
}
|
|
43081
|
+
const schoolData = await getSchoolById(value.school);
|
|
43082
|
+
if (!schoolData) {
|
|
43083
|
+
throw new BadRequestError64("School not found.");
|
|
43084
|
+
}
|
|
43085
|
+
let totalStudentsProcessed = 0;
|
|
43086
|
+
let sectionsGenerated = 0;
|
|
43087
|
+
let sectionsSkipped = 0;
|
|
43088
|
+
let teachingLoadsCreated = 0;
|
|
43089
|
+
let teachingLoadsSkipped = 0;
|
|
43090
|
+
let studentCreated = 0;
|
|
43091
|
+
let studentSkipped = 0;
|
|
43092
|
+
let subjectsAssigned = 0;
|
|
43093
|
+
let subjectsSkipped = 0;
|
|
43094
|
+
for (let i = 0; i < sectionSizes.length; i++) {
|
|
43095
|
+
const size = sectionSizes[i];
|
|
43096
|
+
const sectionName = String(i + 1);
|
|
43097
|
+
const existingSection = await getSection({
|
|
43098
|
+
gradeLevel: value.gradeLevel,
|
|
43099
|
+
schoolYear: value.schoolYear,
|
|
43100
|
+
name: sectionName,
|
|
43101
|
+
school: value.school
|
|
43102
|
+
});
|
|
43103
|
+
let sectionId = "";
|
|
43104
|
+
if (existingSection) {
|
|
43105
|
+
sectionId = existingSection._id?.toString() || "";
|
|
43106
|
+
sectionsSkipped++;
|
|
43107
|
+
continue;
|
|
43108
|
+
}
|
|
43109
|
+
sectionId = await createSection(
|
|
43110
|
+
{
|
|
43111
|
+
school: value.school,
|
|
43112
|
+
schoolYear: value.schoolYear,
|
|
43113
|
+
gradeLevel: value.gradeLevel,
|
|
43114
|
+
name: sectionName,
|
|
43115
|
+
students: size
|
|
43116
|
+
},
|
|
43117
|
+
session
|
|
43118
|
+
);
|
|
43119
|
+
if (!sectionId) {
|
|
43120
|
+
throw new InternalServerError21("Required section ID is missing.");
|
|
43121
|
+
}
|
|
43122
|
+
sectionsGenerated++;
|
|
43123
|
+
const skip = totalStudentsProcessed;
|
|
43124
|
+
const learners = await getLeanerByGradeLevel(
|
|
43125
|
+
{
|
|
43126
|
+
school: value.school,
|
|
43127
|
+
gradeLevel: value.gradeLevel,
|
|
43128
|
+
skip,
|
|
43129
|
+
limit: size
|
|
43130
|
+
},
|
|
43131
|
+
session
|
|
43132
|
+
);
|
|
43133
|
+
if (!learners.length) {
|
|
43134
|
+
throw new BadRequestError64(`No learners found for section #${i + 1}.`);
|
|
43135
|
+
}
|
|
43136
|
+
totalStudentsProcessed += learners.length;
|
|
43137
|
+
for (const student of learners) {
|
|
43138
|
+
if (!student._id) {
|
|
43139
|
+
throw new BadRequestError64("Learner ID is missing.");
|
|
43140
|
+
}
|
|
43141
|
+
if (!student.learnerInfo.lrn) {
|
|
43142
|
+
throw new BadRequestError64("Learner LRN is missing.");
|
|
43143
|
+
}
|
|
43144
|
+
const existingStudent = await getStudent({
|
|
43145
|
+
student: student._id.toString(),
|
|
43146
|
+
schoolYear: value.schoolYear,
|
|
43147
|
+
section: sectionId,
|
|
43148
|
+
gradeLevel: value.gradeLevel
|
|
43149
|
+
});
|
|
43150
|
+
if (existingStudent) {
|
|
43151
|
+
studentSkipped++;
|
|
43152
|
+
continue;
|
|
43153
|
+
}
|
|
43154
|
+
await assignStudent(
|
|
43155
|
+
{
|
|
43156
|
+
section: sectionId,
|
|
43157
|
+
lrn: student.learnerInfo.lrn,
|
|
43158
|
+
student: student._id?.toString(),
|
|
43159
|
+
studentName: `${student.learnerInfo.firstName} ${student.learnerInfo.lastName}`,
|
|
43160
|
+
school: value.school,
|
|
43161
|
+
schoolName: schoolData.name,
|
|
43162
|
+
gradeLevel: value.gradeLevel,
|
|
43163
|
+
educationLevel: gradeLevelData.educationLevel,
|
|
43164
|
+
schoolYear: value.schoolYear,
|
|
43165
|
+
status: "active"
|
|
43166
|
+
},
|
|
43167
|
+
session
|
|
43168
|
+
);
|
|
43169
|
+
studentCreated++;
|
|
43170
|
+
}
|
|
43171
|
+
if (value.gradeLevel !== "kindergarten") {
|
|
43172
|
+
const curriculumSubjects = await getAllCurriculumSubjects({
|
|
43173
|
+
schoolYear: Number(value.schoolYear),
|
|
43174
|
+
gradeLevel: value.gradeLevel,
|
|
43175
|
+
limit: 20
|
|
43176
|
+
});
|
|
43177
|
+
for (const curriculumSubject of curriculumSubjects.items) {
|
|
43178
|
+
const existingSectionSubject = await getSectionSubject({
|
|
43179
|
+
section: sectionId,
|
|
43180
|
+
subjectCode: curriculumSubject.subjectCode,
|
|
43181
|
+
schoolYear: value.schoolYear
|
|
43182
|
+
});
|
|
43183
|
+
if (existingSectionSubject) {
|
|
43184
|
+
subjectsSkipped++;
|
|
43185
|
+
continue;
|
|
43186
|
+
}
|
|
43187
|
+
await addSectionSubject(
|
|
43188
|
+
{
|
|
43189
|
+
curriculum: curriculumSubject.curriculum.toString(),
|
|
43190
|
+
school: value.school,
|
|
43191
|
+
schoolName: schoolData.name,
|
|
43192
|
+
gradeLevel: value.gradeLevel,
|
|
43193
|
+
educationLevel: gradeLevelData.educationLevel,
|
|
43194
|
+
schoolYear: value.schoolYear,
|
|
43195
|
+
section: sectionId,
|
|
43196
|
+
sectionName,
|
|
43197
|
+
subjectCode: curriculumSubject.subjectCode,
|
|
43198
|
+
subjectName: curriculumSubject.subjectName,
|
|
43199
|
+
teacher: "",
|
|
43200
|
+
teacherName: "",
|
|
43201
|
+
schedule: "",
|
|
43202
|
+
daysOfWeek: [],
|
|
43203
|
+
classroom: "",
|
|
43204
|
+
classroomName: "",
|
|
43205
|
+
sessionDuration: curriculumSubject.sessionDuration,
|
|
43206
|
+
sessionFrequency: curriculumSubject.sessionFrequency,
|
|
43207
|
+
status: "draft"
|
|
43208
|
+
},
|
|
43209
|
+
session
|
|
43210
|
+
);
|
|
43211
|
+
subjectsAssigned++;
|
|
43212
|
+
}
|
|
43213
|
+
}
|
|
43214
|
+
}
|
|
43215
|
+
let pageTeacher = 1;
|
|
43216
|
+
let pagesTeachers = 1;
|
|
43217
|
+
let teachers = [];
|
|
43218
|
+
do {
|
|
43219
|
+
const teachersData = await getAllPersonnel({
|
|
43220
|
+
school: value.school,
|
|
43221
|
+
limit: 100,
|
|
43222
|
+
gradeLevel: value.gradeLevel,
|
|
43223
|
+
classification: "teaching"
|
|
43224
|
+
});
|
|
43225
|
+
pagesTeachers = teachersData.pages;
|
|
43226
|
+
teachers.push(...teachersData.items);
|
|
43227
|
+
pageTeacher++;
|
|
43228
|
+
} while (pageTeacher < pagesTeachers);
|
|
43229
|
+
if (!teachers.length) {
|
|
43230
|
+
throw new BadRequestError64(
|
|
43231
|
+
"Could not proceed, no teaching personnel found."
|
|
43232
|
+
);
|
|
43233
|
+
}
|
|
43234
|
+
if (teachers.length) {
|
|
43235
|
+
for (const teacher of teachers) {
|
|
43236
|
+
if (!teacher._id) {
|
|
43237
|
+
throw new BadRequestError64("Teacher ID is missing.");
|
|
43238
|
+
}
|
|
43239
|
+
const existingLoad = await getByTeacher({
|
|
43240
|
+
teacher: teacher._id.toString(),
|
|
43241
|
+
school: value.school,
|
|
43242
|
+
schoolYear: value.schoolYear
|
|
43243
|
+
});
|
|
43244
|
+
if (existingLoad) {
|
|
43245
|
+
teachingLoadsSkipped++;
|
|
43246
|
+
continue;
|
|
43247
|
+
}
|
|
43248
|
+
await addTeachingLoad(
|
|
43249
|
+
{
|
|
43250
|
+
school: value.school,
|
|
43251
|
+
schoolName: schoolData.name,
|
|
43252
|
+
schoolYear: value.schoolYear,
|
|
43253
|
+
teacher: teacher._id.toString(),
|
|
43254
|
+
teacherName: `${teacher.firstName} ${teacher.lastName}`,
|
|
43255
|
+
status: "draft"
|
|
43256
|
+
},
|
|
43257
|
+
session
|
|
43258
|
+
);
|
|
43259
|
+
teachingLoadsCreated++;
|
|
43260
|
+
}
|
|
43261
|
+
}
|
|
43262
|
+
await session.commitTransaction();
|
|
43263
|
+
return {
|
|
43264
|
+
message: "Sections generated successfully.",
|
|
43265
|
+
summary: {
|
|
43266
|
+
sectionsGenerated,
|
|
43267
|
+
sectionsSkipped,
|
|
43268
|
+
totalSections: sectionsGenerated + sectionsSkipped,
|
|
43269
|
+
studentsProcessed: totalStudentsProcessed,
|
|
43270
|
+
studentCreated,
|
|
43271
|
+
studentSkipped,
|
|
43272
|
+
subjectsAssigned,
|
|
43273
|
+
subjectsSkipped,
|
|
43274
|
+
teachingLoadsCreated,
|
|
43275
|
+
teachingLoadsSkipped,
|
|
43276
|
+
totalStudents: studentCount
|
|
43277
|
+
}
|
|
43278
|
+
};
|
|
42854
43279
|
} catch (error2) {
|
|
42855
|
-
|
|
43280
|
+
await session.abortTransaction();
|
|
43281
|
+
if (error2 instanceof AppError25) {
|
|
43282
|
+
throw error2;
|
|
43283
|
+
} else {
|
|
43284
|
+
throw new InternalServerError21("Failed to generate sections.");
|
|
43285
|
+
}
|
|
43286
|
+
} finally {
|
|
43287
|
+
await session?.endSession();
|
|
42856
43288
|
}
|
|
42857
43289
|
}
|
|
42858
|
-
|
|
43290
|
+
async function generateSectionPreview(value) {
|
|
43291
|
+
const { error } = schemaGenerateSections.validate(value);
|
|
43292
|
+
if (error) {
|
|
43293
|
+
throw new BadRequestError64(
|
|
43294
|
+
`Invalid section generation data: ${error.message}`
|
|
43295
|
+
);
|
|
43296
|
+
}
|
|
42859
43297
|
try {
|
|
42860
|
-
|
|
43298
|
+
const studentCount = await getCountByGradeLevel({
|
|
43299
|
+
school: value.school,
|
|
43300
|
+
schoolYear: value.schoolYear,
|
|
43301
|
+
gradeLevel: value.gradeLevel,
|
|
43302
|
+
specialProgram: value.specialProgram
|
|
43303
|
+
});
|
|
43304
|
+
if (studentCount === 0) {
|
|
43305
|
+
throw new BadRequestError64("No learners found for this grade level.");
|
|
43306
|
+
}
|
|
43307
|
+
const gradeLevelData = await getByGradeLevel({
|
|
43308
|
+
school: value.school,
|
|
43309
|
+
gradeLevel: value.gradeLevel
|
|
43310
|
+
});
|
|
43311
|
+
if (!gradeLevelData) {
|
|
43312
|
+
throw new BadRequestError64("Grade level not found.");
|
|
43313
|
+
}
|
|
43314
|
+
const minPerSection = value.minStudents ?? gradeLevelData.minNumberOfLearners;
|
|
43315
|
+
const maxPerSection = value.maxStudents ?? gradeLevelData.maxNumberOfLearners;
|
|
43316
|
+
const sectionSizes = distributeStudents(
|
|
43317
|
+
studentCount,
|
|
43318
|
+
minPerSection,
|
|
43319
|
+
maxPerSection
|
|
43320
|
+
);
|
|
43321
|
+
if (sectionSizes.length === 0) {
|
|
43322
|
+
throw new BadRequestError64("Unable to compute section sizes.");
|
|
43323
|
+
}
|
|
43324
|
+
const sections = sectionSizes.map((size, index) => ({
|
|
43325
|
+
name: `${index + 1}`,
|
|
43326
|
+
value: size
|
|
43327
|
+
}));
|
|
43328
|
+
return {
|
|
43329
|
+
totalSectionsGenerated: sectionSizes.length,
|
|
43330
|
+
totalStudentsAssigned: studentCount,
|
|
43331
|
+
sections
|
|
43332
|
+
};
|
|
42861
43333
|
} catch (error2) {
|
|
42862
|
-
|
|
43334
|
+
if (error2 instanceof AppError25) {
|
|
43335
|
+
throw error2;
|
|
43336
|
+
} else {
|
|
43337
|
+
throw new InternalServerError21("Failed to generate section preview.");
|
|
43338
|
+
}
|
|
42863
43339
|
}
|
|
42864
43340
|
}
|
|
42865
|
-
|
|
43341
|
+
return { generateSections, generateSectionPreview };
|
|
43342
|
+
}
|
|
43343
|
+
|
|
43344
|
+
// src/resources/section/section.controller.ts
|
|
43345
|
+
function useSectionController() {
|
|
43346
|
+
const {
|
|
43347
|
+
add: _add,
|
|
43348
|
+
getAll: _getAll,
|
|
43349
|
+
getById: _getById,
|
|
43350
|
+
getByName: _getByName,
|
|
43351
|
+
getBySchool: _getBySchool,
|
|
43352
|
+
updateFieldById: _updateFieldById,
|
|
43353
|
+
addStudentToSection: _addStudentToSection,
|
|
43354
|
+
removeStudentFromSection: _removeStudentFromSection,
|
|
43355
|
+
deleteById: _deleteById
|
|
43356
|
+
} = useSectionRepo();
|
|
43357
|
+
const {
|
|
43358
|
+
generateSections: _generateSections,
|
|
43359
|
+
generateSectionPreview: _generateSectionPreview
|
|
43360
|
+
} = useSectionService();
|
|
43361
|
+
async function add(req, res, next) {
|
|
43362
|
+
const value = req.body;
|
|
43363
|
+
const { error } = schemaSection.validate(value);
|
|
43364
|
+
if (error) {
|
|
43365
|
+
next(new BadRequestError65(error.message));
|
|
43366
|
+
return;
|
|
43367
|
+
}
|
|
42866
43368
|
try {
|
|
42867
|
-
|
|
43369
|
+
const data = await _add(value);
|
|
43370
|
+
res.json({
|
|
43371
|
+
message: "Successfully created section.",
|
|
43372
|
+
data
|
|
43373
|
+
});
|
|
43374
|
+
return;
|
|
42868
43375
|
} catch (error2) {
|
|
42869
|
-
|
|
43376
|
+
next(error2);
|
|
42870
43377
|
}
|
|
42871
43378
|
}
|
|
42872
|
-
|
|
43379
|
+
async function generateSections(req, res, next) {
|
|
43380
|
+
const value = req.body;
|
|
43381
|
+
const { error } = schemaGenerateSections.validate(value);
|
|
43382
|
+
if (error) {
|
|
43383
|
+
next(new BadRequestError65(error.message));
|
|
43384
|
+
return;
|
|
43385
|
+
}
|
|
42873
43386
|
try {
|
|
42874
|
-
|
|
43387
|
+
const data = await _generateSections(value);
|
|
43388
|
+
res.json({
|
|
43389
|
+
message: "Successfully created section.",
|
|
43390
|
+
data
|
|
43391
|
+
});
|
|
43392
|
+
return;
|
|
42875
43393
|
} catch (error2) {
|
|
42876
|
-
|
|
43394
|
+
next(error2);
|
|
42877
43395
|
}
|
|
42878
43396
|
}
|
|
42879
|
-
|
|
42880
|
-
|
|
42881
|
-
|
|
42882
|
-
|
|
42883
|
-
|
|
42884
|
-
|
|
42885
|
-
|
|
42886
|
-
schedule: value.schedule,
|
|
42887
|
-
blockTimes: value.blockTimes,
|
|
42888
|
-
type: value.type,
|
|
42889
|
-
durationMinutes: value.durationMinutes ?? 0,
|
|
42890
|
-
status: value.status ?? "active",
|
|
42891
|
-
school: value.school,
|
|
42892
|
-
createdAt: value.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
42893
|
-
updatedAt: value.updatedAt ?? "",
|
|
42894
|
-
deletedAt: value.deletedAt ?? ""
|
|
42895
|
-
};
|
|
42896
|
-
}
|
|
42897
|
-
|
|
42898
|
-
// src/resources/kindergarten-routine/kindergarten.routine.repository.ts
|
|
42899
|
-
import {
|
|
42900
|
-
AppError as AppError25,
|
|
42901
|
-
BadRequestError as BadRequestError65,
|
|
42902
|
-
InternalServerError as InternalServerError21,
|
|
42903
|
-
logger as logger39,
|
|
42904
|
-
makeCacheKey as makeCacheKey22,
|
|
42905
|
-
paginate as paginate21,
|
|
42906
|
-
useAtlas as useAtlas30,
|
|
42907
|
-
useCache as useCache22
|
|
42908
|
-
} from "@eeplatform/nodejs-utils";
|
|
42909
|
-
import { ObjectId as ObjectId42 } from "mongodb";
|
|
42910
|
-
function useKindergartenRoutineRepo() {
|
|
42911
|
-
const db = useAtlas30.getDb();
|
|
42912
|
-
if (!db) {
|
|
42913
|
-
throw new Error("Unable to connect to server.");
|
|
42914
|
-
}
|
|
42915
|
-
const namespace_collection = "deped.kindergarten.routines";
|
|
42916
|
-
const collection = db.collection(namespace_collection);
|
|
42917
|
-
const { getCache, setCache, delNamespace } = useCache22(namespace_collection);
|
|
42918
|
-
async function createIndexes() {
|
|
43397
|
+
async function generateSectionPreview(req, res, next) {
|
|
43398
|
+
const value = req.body;
|
|
43399
|
+
const { error } = schemaGenerateSections.validate(value);
|
|
43400
|
+
if (error) {
|
|
43401
|
+
next(new BadRequestError65(error.message));
|
|
43402
|
+
return;
|
|
43403
|
+
}
|
|
42919
43404
|
try {
|
|
42920
|
-
await
|
|
42921
|
-
|
|
42922
|
-
|
|
42923
|
-
|
|
42924
|
-
|
|
42925
|
-
{ key: { createdAt: 1 } },
|
|
42926
|
-
{ key: { createdBy: 1 } },
|
|
42927
|
-
{ key: { sectionName: "text", classroomName: "text" } },
|
|
42928
|
-
{
|
|
42929
|
-
key: { title: 1, school: 1, type: 1, status: 1 },
|
|
42930
|
-
unique: true,
|
|
42931
|
-
name: "unique_kindergarten_routine"
|
|
42932
|
-
}
|
|
42933
|
-
]);
|
|
42934
|
-
} catch (error) {
|
|
42935
|
-
throw new Error("Failed to create index on kindergarten routines.");
|
|
42936
|
-
}
|
|
42937
|
-
}
|
|
42938
|
-
function delCachedData() {
|
|
42939
|
-
delNamespace().then(() => {
|
|
42940
|
-
logger39.log({
|
|
42941
|
-
level: "info",
|
|
42942
|
-
message: `Cache namespace cleared for ${namespace_collection}`
|
|
42943
|
-
});
|
|
42944
|
-
}).catch((err) => {
|
|
42945
|
-
logger39.log({
|
|
42946
|
-
level: "error",
|
|
42947
|
-
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
42948
|
-
});
|
|
42949
|
-
});
|
|
42950
|
-
}
|
|
42951
|
-
async function add(value, session) {
|
|
42952
|
-
try {
|
|
42953
|
-
value = modelKindergartenRoutine(value);
|
|
42954
|
-
const res = await collection.insertOne(value, { session });
|
|
42955
|
-
delCachedData();
|
|
42956
|
-
return res.insertedId;
|
|
42957
|
-
} catch (error) {
|
|
42958
|
-
logger39.log({
|
|
42959
|
-
level: "error",
|
|
42960
|
-
message: error.message
|
|
42961
|
-
});
|
|
42962
|
-
if (error instanceof AppError25) {
|
|
42963
|
-
throw error;
|
|
42964
|
-
} else {
|
|
42965
|
-
const isDuplicated = error.message.includes("duplicate");
|
|
42966
|
-
if (isDuplicated) {
|
|
42967
|
-
throw new BadRequestError65("Kinder schedule already exists.");
|
|
42968
|
-
}
|
|
42969
|
-
throw new Error("Failed to create kindergarten routine.");
|
|
42970
|
-
}
|
|
42971
|
-
}
|
|
42972
|
-
}
|
|
42973
|
-
async function getAll({
|
|
42974
|
-
search = "",
|
|
42975
|
-
page = 1,
|
|
42976
|
-
limit = 10,
|
|
42977
|
-
sort = {},
|
|
42978
|
-
status = "active",
|
|
42979
|
-
createdBy,
|
|
42980
|
-
school = "",
|
|
42981
|
-
section = "",
|
|
42982
|
-
classroom = "",
|
|
42983
|
-
type = ""
|
|
42984
|
-
} = {}) {
|
|
42985
|
-
page = page > 0 ? page - 1 : 0;
|
|
42986
|
-
const query = {
|
|
42987
|
-
deletedAt: { $in: ["", null] },
|
|
42988
|
-
status
|
|
42989
|
-
};
|
|
42990
|
-
sort = Object.keys(sort).length > 0 ? sort : { _id: 1 };
|
|
42991
|
-
const cacheKeyOptions = {
|
|
42992
|
-
status,
|
|
42993
|
-
page,
|
|
42994
|
-
limit,
|
|
42995
|
-
sort: JSON.stringify(sort)
|
|
42996
|
-
};
|
|
42997
|
-
if (createdBy) {
|
|
42998
|
-
try {
|
|
42999
|
-
query.createdBy = new ObjectId42(createdBy);
|
|
43000
|
-
} catch (error) {
|
|
43001
|
-
throw new BadRequestError65("Invalid createdBy ID.");
|
|
43002
|
-
}
|
|
43003
|
-
cacheKeyOptions.createdBy = createdBy;
|
|
43004
|
-
}
|
|
43005
|
-
if (search) {
|
|
43006
|
-
query.$text = { $search: search };
|
|
43007
|
-
cacheKeyOptions.search = search;
|
|
43008
|
-
}
|
|
43009
|
-
if (school) {
|
|
43010
|
-
try {
|
|
43011
|
-
query.school = new ObjectId42(school);
|
|
43012
|
-
} catch (error) {
|
|
43013
|
-
throw new BadRequestError65("Invalid school ID.");
|
|
43014
|
-
}
|
|
43015
|
-
cacheKeyOptions.school = school;
|
|
43016
|
-
}
|
|
43017
|
-
if (section) {
|
|
43018
|
-
try {
|
|
43019
|
-
query.section = new ObjectId42(section);
|
|
43020
|
-
} catch (error) {
|
|
43021
|
-
throw new BadRequestError65("Invalid section ID.");
|
|
43022
|
-
}
|
|
43023
|
-
cacheKeyOptions.section = section;
|
|
43024
|
-
}
|
|
43025
|
-
if (classroom) {
|
|
43026
|
-
try {
|
|
43027
|
-
query.classroom = new ObjectId42(classroom);
|
|
43028
|
-
} catch (error) {
|
|
43029
|
-
throw new BadRequestError65("Invalid classroom ID.");
|
|
43030
|
-
}
|
|
43031
|
-
cacheKeyOptions.classroom = classroom;
|
|
43032
|
-
}
|
|
43033
|
-
if (type) {
|
|
43034
|
-
query.type = type;
|
|
43035
|
-
cacheKeyOptions.type = type;
|
|
43036
|
-
}
|
|
43037
|
-
const cacheKey = makeCacheKey22(namespace_collection, cacheKeyOptions);
|
|
43038
|
-
logger39.log({
|
|
43039
|
-
level: "info",
|
|
43040
|
-
message: `Cache key for getAll kindergarten routines: ${cacheKey}`
|
|
43041
|
-
});
|
|
43042
|
-
try {
|
|
43043
|
-
const cached = await getCache(cacheKey);
|
|
43044
|
-
if (cached) {
|
|
43045
|
-
logger39.log({
|
|
43046
|
-
level: "info",
|
|
43047
|
-
message: `Cache hit for getAll kindergarten routines: ${cacheKey}`
|
|
43048
|
-
});
|
|
43049
|
-
return cached;
|
|
43050
|
-
}
|
|
43051
|
-
const items = await collection.aggregate([
|
|
43052
|
-
{ $match: query },
|
|
43053
|
-
{ $sort: sort },
|
|
43054
|
-
{ $skip: page * limit },
|
|
43055
|
-
{ $limit: limit }
|
|
43056
|
-
]).toArray();
|
|
43057
|
-
const length = await collection.countDocuments(query);
|
|
43058
|
-
const data = paginate21(items, page, limit, length);
|
|
43059
|
-
setCache(cacheKey, data, 600).then(() => {
|
|
43060
|
-
logger39.log({
|
|
43061
|
-
level: "info",
|
|
43062
|
-
message: `Cache set for getAll kindergarten routines: ${cacheKey}`
|
|
43063
|
-
});
|
|
43064
|
-
}).catch((err) => {
|
|
43065
|
-
logger39.log({
|
|
43066
|
-
level: "error",
|
|
43067
|
-
message: `Failed to set cache for getAll kindergarten routines: ${err.message}`
|
|
43068
|
-
});
|
|
43069
|
-
});
|
|
43070
|
-
return data;
|
|
43071
|
-
} catch (error) {
|
|
43072
|
-
logger39.log({ level: "error", message: `${error}` });
|
|
43073
|
-
throw error;
|
|
43074
|
-
}
|
|
43075
|
-
}
|
|
43076
|
-
async function getById(_id) {
|
|
43077
|
-
try {
|
|
43078
|
-
_id = new ObjectId42(_id);
|
|
43079
|
-
} catch (error) {
|
|
43080
|
-
throw new BadRequestError65(namespace_collection + " Invalid ID.");
|
|
43081
|
-
}
|
|
43082
|
-
const cacheKey = makeCacheKey22(namespace_collection, { _id: String(_id) });
|
|
43083
|
-
try {
|
|
43084
|
-
const cached = await getCache(cacheKey);
|
|
43085
|
-
if (cached) {
|
|
43086
|
-
logger39.log({
|
|
43087
|
-
level: "info",
|
|
43088
|
-
message: `Cache hit for getById kindergarten routine: ${cacheKey}`
|
|
43089
|
-
});
|
|
43090
|
-
return cached;
|
|
43091
|
-
}
|
|
43092
|
-
const result = await collection.findOne({
|
|
43093
|
-
_id,
|
|
43094
|
-
deletedAt: { $in: ["", null] }
|
|
43095
|
-
});
|
|
43096
|
-
setCache(cacheKey, result, 300).then(() => {
|
|
43097
|
-
logger39.log({
|
|
43098
|
-
level: "info",
|
|
43099
|
-
message: `Cache set for kindergarten routine by id: ${cacheKey}`
|
|
43100
|
-
});
|
|
43101
|
-
}).catch((err) => {
|
|
43102
|
-
logger39.log({
|
|
43103
|
-
level: "error",
|
|
43104
|
-
message: `Failed to set cache for kindergarten routine by id: ${err.message}`
|
|
43105
|
-
});
|
|
43106
|
-
});
|
|
43107
|
-
return result;
|
|
43108
|
-
} catch (error) {
|
|
43109
|
-
if (error instanceof AppError25) {
|
|
43110
|
-
throw error;
|
|
43111
|
-
} else {
|
|
43112
|
-
throw new InternalServerError21("Failed to get kindergarten routine.");
|
|
43113
|
-
}
|
|
43114
|
-
}
|
|
43115
|
-
}
|
|
43116
|
-
async function countByDomain(domain) {
|
|
43117
|
-
const cacheKey = makeCacheKey22(namespace_collection, {
|
|
43118
|
-
domain,
|
|
43119
|
-
tag: "getByDomain"
|
|
43120
|
-
});
|
|
43121
|
-
try {
|
|
43122
|
-
const cached = await getCache(cacheKey);
|
|
43123
|
-
if (cached) {
|
|
43124
|
-
logger39.log({
|
|
43125
|
-
level: "info",
|
|
43126
|
-
message: `Cache hit for getById kindergarten routine: ${cacheKey}`
|
|
43127
|
-
});
|
|
43128
|
-
return cached;
|
|
43129
|
-
}
|
|
43130
|
-
const result = await collection.countDocuments({
|
|
43131
|
-
domain,
|
|
43132
|
-
status: "active"
|
|
43133
|
-
});
|
|
43134
|
-
setCache(cacheKey, result, 300).then(() => {
|
|
43135
|
-
logger39.log({
|
|
43136
|
-
level: "info",
|
|
43137
|
-
message: `Cache set for kindergarten routine by id: ${cacheKey}`
|
|
43138
|
-
});
|
|
43139
|
-
}).catch((err) => {
|
|
43140
|
-
logger39.log({
|
|
43141
|
-
level: "error",
|
|
43142
|
-
message: `Failed to set cache for kindergarten routine by id: ${err.message}`
|
|
43143
|
-
});
|
|
43144
|
-
});
|
|
43145
|
-
return result;
|
|
43146
|
-
} catch (error) {
|
|
43147
|
-
if (error instanceof AppError25) {
|
|
43148
|
-
throw error;
|
|
43149
|
-
} else {
|
|
43150
|
-
throw new InternalServerError21("Failed to get kindergarten routine.");
|
|
43151
|
-
}
|
|
43152
|
-
}
|
|
43153
|
-
}
|
|
43154
|
-
async function getBySection(section) {
|
|
43155
|
-
try {
|
|
43156
|
-
section = new ObjectId42(section);
|
|
43157
|
-
} catch (error) {
|
|
43158
|
-
throw new BadRequestError65("Invalid section ID.");
|
|
43159
|
-
}
|
|
43160
|
-
const cacheKey = makeCacheKey22(namespace_collection, {
|
|
43161
|
-
section: String(section)
|
|
43162
|
-
});
|
|
43163
|
-
try {
|
|
43164
|
-
const cached = await getCache(cacheKey);
|
|
43165
|
-
if (cached) {
|
|
43166
|
-
logger39.log({
|
|
43167
|
-
level: "info",
|
|
43168
|
-
message: `Cache hit for getBySection kindergarten routine: ${cacheKey}`
|
|
43169
|
-
});
|
|
43170
|
-
return cached;
|
|
43171
|
-
}
|
|
43172
|
-
const result = await collection.find({
|
|
43173
|
-
section,
|
|
43174
|
-
deletedAt: { $in: ["", null] }
|
|
43175
|
-
}).toArray();
|
|
43176
|
-
setCache(cacheKey, result, 300).then(() => {
|
|
43177
|
-
logger39.log({
|
|
43178
|
-
level: "info",
|
|
43179
|
-
message: `Cache set for kindergarten routine by section: ${cacheKey}`
|
|
43180
|
-
});
|
|
43181
|
-
}).catch((err) => {
|
|
43182
|
-
logger39.log({
|
|
43183
|
-
level: "error",
|
|
43184
|
-
message: `Failed to set cache for kindergarten routine by section: ${err.message}`
|
|
43185
|
-
});
|
|
43186
|
-
});
|
|
43187
|
-
return result;
|
|
43188
|
-
} catch (error) {
|
|
43189
|
-
if (error instanceof AppError25) {
|
|
43190
|
-
throw error;
|
|
43191
|
-
} else {
|
|
43192
|
-
throw new InternalServerError21("Failed to get kindergarten routine.");
|
|
43193
|
-
}
|
|
43194
|
-
}
|
|
43195
|
-
}
|
|
43196
|
-
async function updateFieldById({ _id, field, value } = {}, session) {
|
|
43197
|
-
const allowedFields = [
|
|
43198
|
-
"sectionName",
|
|
43199
|
-
"classroomName",
|
|
43200
|
-
"schedule",
|
|
43201
|
-
"blockTimes",
|
|
43202
|
-
"type"
|
|
43203
|
-
];
|
|
43204
|
-
if (!allowedFields.includes(field)) {
|
|
43205
|
-
throw new BadRequestError65(
|
|
43206
|
-
`Field "${field}" is not allowed to be updated.`
|
|
43207
|
-
);
|
|
43208
|
-
}
|
|
43209
|
-
try {
|
|
43210
|
-
_id = new ObjectId42(_id);
|
|
43211
|
-
} catch (error) {
|
|
43212
|
-
throw new BadRequestError65(namespace_collection + " Invalid ID.");
|
|
43213
|
-
}
|
|
43214
|
-
try {
|
|
43215
|
-
await collection.updateOne(
|
|
43216
|
-
{ _id, deletedAt: { $in: ["", null] } },
|
|
43217
|
-
{ $set: { [field]: value, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
|
|
43218
|
-
{ session }
|
|
43219
|
-
);
|
|
43220
|
-
delCachedData();
|
|
43221
|
-
return `Successfully updated kindergarten routine ${field}.`;
|
|
43222
|
-
} catch (error) {
|
|
43223
|
-
throw new InternalServerError21(
|
|
43224
|
-
`Failed to update kindergarten routine ${field}.`
|
|
43225
|
-
);
|
|
43226
|
-
}
|
|
43227
|
-
}
|
|
43228
|
-
async function updateById(_id, value, session) {
|
|
43229
|
-
const { error } = schemaKindergartenRoutineUpdate.validate(value);
|
|
43230
|
-
if (error) {
|
|
43231
|
-
throw new BadRequestError65(
|
|
43232
|
-
`Invalid kindergarten routine data: ${error.message}`
|
|
43233
|
-
);
|
|
43234
|
-
}
|
|
43235
|
-
try {
|
|
43236
|
-
_id = new ObjectId42(_id);
|
|
43237
|
-
} catch (error2) {
|
|
43238
|
-
throw new BadRequestError65(namespace_collection + " Invalid ID.");
|
|
43239
|
-
}
|
|
43240
|
-
try {
|
|
43241
|
-
await collection.updateOne(
|
|
43242
|
-
{ _id },
|
|
43243
|
-
{ $set: { ...value, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
|
|
43244
|
-
{ session }
|
|
43245
|
-
);
|
|
43246
|
-
delCachedData();
|
|
43247
|
-
return `Successfully updated kindergarten routine.`;
|
|
43248
|
-
} catch (error2) {
|
|
43249
|
-
throw new InternalServerError21("Failed to update kindergarten routine.");
|
|
43250
|
-
}
|
|
43251
|
-
}
|
|
43252
|
-
async function deleteById(_id) {
|
|
43253
|
-
try {
|
|
43254
|
-
_id = new ObjectId42(_id);
|
|
43255
|
-
} catch (error) {
|
|
43256
|
-
throw new BadRequestError65(namespace_collection + " Invalid ID.");
|
|
43257
|
-
}
|
|
43258
|
-
try {
|
|
43259
|
-
await collection.updateOne(
|
|
43260
|
-
{ _id },
|
|
43261
|
-
{ $set: { status: "deleted", deletedAt: (/* @__PURE__ */ new Date()).toISOString() } }
|
|
43262
|
-
);
|
|
43263
|
-
delCachedData();
|
|
43264
|
-
return "Successfully deleted kindergarten routine.";
|
|
43265
|
-
} catch (error) {
|
|
43266
|
-
throw new InternalServerError21("Failed to delete kindergarten routine.");
|
|
43267
|
-
}
|
|
43268
|
-
}
|
|
43269
|
-
return {
|
|
43270
|
-
createIndexes,
|
|
43271
|
-
add,
|
|
43272
|
-
getAll,
|
|
43273
|
-
getById,
|
|
43274
|
-
countByDomain,
|
|
43275
|
-
getBySection,
|
|
43276
|
-
updateFieldById,
|
|
43277
|
-
updateById,
|
|
43278
|
-
deleteById
|
|
43279
|
-
};
|
|
43280
|
-
}
|
|
43281
|
-
|
|
43282
|
-
// src/resources/kindergarten-routine/kindergarten.routine.controller.ts
|
|
43283
|
-
import { BadRequestError as BadRequestError66 } from "@eeplatform/nodejs-utils";
|
|
43284
|
-
import Joi44 from "joi";
|
|
43285
|
-
function useKindergartenRoutineController() {
|
|
43286
|
-
const {
|
|
43287
|
-
add: _add,
|
|
43288
|
-
getAll: _getAll,
|
|
43289
|
-
getById: _getById,
|
|
43290
|
-
getBySection: _getBySection,
|
|
43291
|
-
updateFieldById: _updateFieldById,
|
|
43292
|
-
deleteById: _deleteById,
|
|
43293
|
-
updateById: _updateById
|
|
43294
|
-
} = useKindergartenRoutineRepo();
|
|
43295
|
-
async function add(req, res, next) {
|
|
43296
|
-
const value = req.body;
|
|
43297
|
-
const { error } = schemaKindergartenRoutine.validate(value);
|
|
43298
|
-
if (error) {
|
|
43299
|
-
next(new BadRequestError66(error.message));
|
|
43300
|
-
return;
|
|
43301
|
-
}
|
|
43302
|
-
try {
|
|
43303
|
-
const data = await _add(value);
|
|
43304
|
-
res.json({
|
|
43305
|
-
message: "Successfully created kinder schedule.",
|
|
43306
|
-
data
|
|
43307
|
-
});
|
|
43308
|
-
return;
|
|
43309
|
-
} catch (error2) {
|
|
43310
|
-
next(error2);
|
|
43405
|
+
const data = await _generateSectionPreview(value);
|
|
43406
|
+
res.json(data);
|
|
43407
|
+
return;
|
|
43408
|
+
} catch (error2) {
|
|
43409
|
+
next(error2);
|
|
43311
43410
|
}
|
|
43312
43411
|
}
|
|
43313
43412
|
async function getAll(req, res, next) {
|
|
43314
43413
|
const query = req.query;
|
|
43315
|
-
const validation =
|
|
43316
|
-
page:
|
|
43317
|
-
limit:
|
|
43318
|
-
search:
|
|
43319
|
-
status:
|
|
43320
|
-
school:
|
|
43321
|
-
|
|
43322
|
-
|
|
43323
|
-
type: Joi44.string().optional().allow("", null),
|
|
43324
|
-
createdBy: Joi44.string().hex().optional().allow("", null)
|
|
43414
|
+
const validation = Joi43.object({
|
|
43415
|
+
page: Joi43.number().min(1).optional().allow("", null),
|
|
43416
|
+
limit: Joi43.number().min(1).optional().allow("", null),
|
|
43417
|
+
search: Joi43.string().optional().allow("", null),
|
|
43418
|
+
status: Joi43.string().optional().allow("", null),
|
|
43419
|
+
school: Joi43.string().hex().optional().allow("", null),
|
|
43420
|
+
schoolYear: Joi43.string().optional().allow("", null),
|
|
43421
|
+
gradeLevel: Joi43.string().optional().allow("", null)
|
|
43325
43422
|
});
|
|
43326
43423
|
const { error } = validation.validate(query);
|
|
43327
43424
|
const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
|
|
@@ -43329,22 +43426,20 @@ function useKindergartenRoutineController() {
|
|
|
43329
43426
|
const search = req.query.search ?? "";
|
|
43330
43427
|
const status = req.query.status ?? "active";
|
|
43331
43428
|
const school = req.query.school ?? "";
|
|
43332
|
-
const
|
|
43333
|
-
const
|
|
43334
|
-
const type = req.query.type ?? "";
|
|
43335
|
-
const createdBy = req.query.createdBy ?? "";
|
|
43429
|
+
const schoolYear = req.query.schoolYear ?? "";
|
|
43430
|
+
const gradeLevel = req.query.gradeLevel ?? "";
|
|
43336
43431
|
const isPageNumber = isFinite(page);
|
|
43337
43432
|
if (!isPageNumber) {
|
|
43338
|
-
next(new
|
|
43433
|
+
next(new BadRequestError65("Invalid page number."));
|
|
43339
43434
|
return;
|
|
43340
43435
|
}
|
|
43341
43436
|
const isLimitNumber = isFinite(limit);
|
|
43342
43437
|
if (!isLimitNumber) {
|
|
43343
|
-
next(new
|
|
43438
|
+
next(new BadRequestError65("Invalid limit number."));
|
|
43344
43439
|
return;
|
|
43345
43440
|
}
|
|
43346
43441
|
if (error) {
|
|
43347
|
-
next(new
|
|
43442
|
+
next(new BadRequestError65(error.message));
|
|
43348
43443
|
return;
|
|
43349
43444
|
}
|
|
43350
43445
|
try {
|
|
@@ -43354,10 +43449,8 @@ function useKindergartenRoutineController() {
|
|
|
43354
43449
|
search,
|
|
43355
43450
|
status,
|
|
43356
43451
|
school,
|
|
43357
|
-
|
|
43358
|
-
|
|
43359
|
-
type,
|
|
43360
|
-
createdBy: createdBy || void 0
|
|
43452
|
+
schoolYear,
|
|
43453
|
+
gradeLevel
|
|
43361
43454
|
});
|
|
43362
43455
|
res.json(data);
|
|
43363
43456
|
return;
|
|
@@ -43367,18 +43460,36 @@ function useKindergartenRoutineController() {
|
|
|
43367
43460
|
}
|
|
43368
43461
|
async function getById(req, res, next) {
|
|
43369
43462
|
const id = req.params.id;
|
|
43370
|
-
const validation =
|
|
43371
|
-
id:
|
|
43463
|
+
const validation = Joi43.object({
|
|
43464
|
+
id: Joi43.string().hex().required()
|
|
43372
43465
|
});
|
|
43373
43466
|
const { error } = validation.validate({ id });
|
|
43374
43467
|
if (error) {
|
|
43375
|
-
next(new
|
|
43468
|
+
next(new BadRequestError65(error.message));
|
|
43376
43469
|
return;
|
|
43377
43470
|
}
|
|
43378
43471
|
try {
|
|
43379
43472
|
const data = await _getById(id);
|
|
43473
|
+
res.json(data);
|
|
43474
|
+
return;
|
|
43475
|
+
} catch (error2) {
|
|
43476
|
+
next(error2);
|
|
43477
|
+
}
|
|
43478
|
+
}
|
|
43479
|
+
async function getByName(req, res, next) {
|
|
43480
|
+
const name = req.params.name;
|
|
43481
|
+
const validation = Joi43.object({
|
|
43482
|
+
name: Joi43.string().required()
|
|
43483
|
+
});
|
|
43484
|
+
const { error } = validation.validate({ name });
|
|
43485
|
+
if (error) {
|
|
43486
|
+
next(new BadRequestError65(error.message));
|
|
43487
|
+
return;
|
|
43488
|
+
}
|
|
43489
|
+
try {
|
|
43490
|
+
const data = await _getByName(name);
|
|
43380
43491
|
res.json({
|
|
43381
|
-
message: "Successfully retrieved
|
|
43492
|
+
message: "Successfully retrieved section.",
|
|
43382
43493
|
data
|
|
43383
43494
|
});
|
|
43384
43495
|
return;
|
|
@@ -43386,20 +43497,20 @@ function useKindergartenRoutineController() {
|
|
|
43386
43497
|
next(error2);
|
|
43387
43498
|
}
|
|
43388
43499
|
}
|
|
43389
|
-
async function
|
|
43390
|
-
const
|
|
43391
|
-
const validation =
|
|
43392
|
-
|
|
43500
|
+
async function getBySchool(req, res, next) {
|
|
43501
|
+
const school = req.params.school;
|
|
43502
|
+
const validation = Joi43.object({
|
|
43503
|
+
school: Joi43.string().hex().required()
|
|
43393
43504
|
});
|
|
43394
|
-
const { error } = validation.validate({
|
|
43505
|
+
const { error } = validation.validate({ school });
|
|
43395
43506
|
if (error) {
|
|
43396
|
-
next(new
|
|
43507
|
+
next(new BadRequestError65(error.message));
|
|
43397
43508
|
return;
|
|
43398
43509
|
}
|
|
43399
43510
|
try {
|
|
43400
|
-
const data = await
|
|
43511
|
+
const data = await _getBySchool(school);
|
|
43401
43512
|
res.json({
|
|
43402
|
-
message: "Successfully retrieved
|
|
43513
|
+
message: "Successfully retrieved sections.",
|
|
43403
43514
|
data
|
|
43404
43515
|
});
|
|
43405
43516
|
return;
|
|
@@ -43410,14 +43521,14 @@ function useKindergartenRoutineController() {
|
|
|
43410
43521
|
async function updateField(req, res, next) {
|
|
43411
43522
|
const _id = req.params.id;
|
|
43412
43523
|
const { field, value } = req.body;
|
|
43413
|
-
const validation =
|
|
43414
|
-
_id:
|
|
43415
|
-
field:
|
|
43416
|
-
value:
|
|
43524
|
+
const validation = Joi43.object({
|
|
43525
|
+
_id: Joi43.string().hex().required(),
|
|
43526
|
+
field: Joi43.string().valid("name", "schoolYear", "gradeLevel", "adviser", "adviserName").required(),
|
|
43527
|
+
value: Joi43.string().required()
|
|
43417
43528
|
});
|
|
43418
43529
|
const { error } = validation.validate({ _id, field, value });
|
|
43419
43530
|
if (error) {
|
|
43420
|
-
next(new
|
|
43531
|
+
next(new BadRequestError65(error.message));
|
|
43421
43532
|
return;
|
|
43422
43533
|
}
|
|
43423
43534
|
try {
|
|
@@ -43428,21 +43539,40 @@ function useKindergartenRoutineController() {
|
|
|
43428
43539
|
next(error2);
|
|
43429
43540
|
}
|
|
43430
43541
|
}
|
|
43431
|
-
async function
|
|
43542
|
+
async function addStudent(req, res, next) {
|
|
43432
43543
|
const _id = req.params.id;
|
|
43433
|
-
const
|
|
43434
|
-
const
|
|
43435
|
-
|
|
43436
|
-
|
|
43544
|
+
const { studentId } = req.body;
|
|
43545
|
+
const validation = Joi43.object({
|
|
43546
|
+
_id: Joi43.string().hex().required(),
|
|
43547
|
+
studentId: Joi43.string().required()
|
|
43548
|
+
});
|
|
43549
|
+
const { error } = validation.validate({ _id, studentId });
|
|
43550
|
+
if (error) {
|
|
43551
|
+
next(new BadRequestError65(error.message));
|
|
43437
43552
|
return;
|
|
43438
43553
|
}
|
|
43439
|
-
|
|
43554
|
+
try {
|
|
43555
|
+
const message = await _addStudentToSection(_id, studentId);
|
|
43556
|
+
res.json({ message });
|
|
43557
|
+
return;
|
|
43558
|
+
} catch (error2) {
|
|
43559
|
+
next(error2);
|
|
43560
|
+
}
|
|
43561
|
+
}
|
|
43562
|
+
async function removeStudent(req, res, next) {
|
|
43563
|
+
const _id = req.params.id;
|
|
43564
|
+
const { studentId } = req.body;
|
|
43565
|
+
const validation = Joi43.object({
|
|
43566
|
+
_id: Joi43.string().hex().required(),
|
|
43567
|
+
studentId: Joi43.string().required()
|
|
43568
|
+
});
|
|
43569
|
+
const { error } = validation.validate({ _id, studentId });
|
|
43440
43570
|
if (error) {
|
|
43441
|
-
next(new
|
|
43571
|
+
next(new BadRequestError65(error.message));
|
|
43442
43572
|
return;
|
|
43443
43573
|
}
|
|
43444
43574
|
try {
|
|
43445
|
-
const message = await
|
|
43575
|
+
const message = await _removeStudentFromSection(_id, studentId);
|
|
43446
43576
|
res.json({ message });
|
|
43447
43577
|
return;
|
|
43448
43578
|
} catch (error2) {
|
|
@@ -43451,12 +43581,12 @@ function useKindergartenRoutineController() {
|
|
|
43451
43581
|
}
|
|
43452
43582
|
async function deleteById(req, res, next) {
|
|
43453
43583
|
const _id = req.params.id;
|
|
43454
|
-
const validation =
|
|
43455
|
-
_id:
|
|
43584
|
+
const validation = Joi43.object({
|
|
43585
|
+
_id: Joi43.string().hex().required()
|
|
43456
43586
|
});
|
|
43457
43587
|
const { error } = validation.validate({ _id });
|
|
43458
43588
|
if (error) {
|
|
43459
|
-
next(new
|
|
43589
|
+
next(new BadRequestError65(error.message));
|
|
43460
43590
|
return;
|
|
43461
43591
|
}
|
|
43462
43592
|
try {
|
|
@@ -43469,651 +43599,76 @@ function useKindergartenRoutineController() {
|
|
|
43469
43599
|
}
|
|
43470
43600
|
return {
|
|
43471
43601
|
add,
|
|
43602
|
+
generateSections,
|
|
43603
|
+
generateSectionPreview,
|
|
43472
43604
|
getAll,
|
|
43473
43605
|
getById,
|
|
43474
|
-
|
|
43606
|
+
getByName,
|
|
43607
|
+
getBySchool,
|
|
43475
43608
|
updateField,
|
|
43476
|
-
|
|
43609
|
+
addStudent,
|
|
43610
|
+
removeStudent,
|
|
43477
43611
|
deleteById
|
|
43478
43612
|
};
|
|
43479
43613
|
}
|
|
43480
43614
|
|
|
43481
|
-
// src/resources/section/section.
|
|
43482
|
-
|
|
43483
|
-
|
|
43484
|
-
|
|
43485
|
-
const { add:
|
|
43486
|
-
|
|
43487
|
-
|
|
43488
|
-
|
|
43489
|
-
|
|
43490
|
-
|
|
43491
|
-
|
|
43492
|
-
const { getById: getKindergartenRoutineById, add: addKindergartenRoutine } = useKindergartenRoutineRepo();
|
|
43493
|
-
function distributeStudents(total, minPer, maxPer) {
|
|
43494
|
-
if (total <= 0)
|
|
43495
|
-
return [];
|
|
43496
|
-
if (minPer <= 0 || maxPer <= 0)
|
|
43497
|
-
return [];
|
|
43498
|
-
if (minPer > maxPer) {
|
|
43499
|
-
throw new BadRequestError67(
|
|
43500
|
-
"Minimum students per section cannot be greater than maximum."
|
|
43501
|
-
);
|
|
43615
|
+
// src/resources/section-student/section.student.controller.ts
|
|
43616
|
+
import { BadRequestError as BadRequestError66 } from "@eeplatform/nodejs-utils";
|
|
43617
|
+
import Joi44 from "joi";
|
|
43618
|
+
function useSectionStudentController() {
|
|
43619
|
+
const { add: _add, getAll: _getAll } = useSectionStudentRepo();
|
|
43620
|
+
async function add(req, res, next) {
|
|
43621
|
+
const value = req.body;
|
|
43622
|
+
const { error } = schemaSectionStudent.validate(value);
|
|
43623
|
+
if (error) {
|
|
43624
|
+
next(new BadRequestError66(error.message));
|
|
43625
|
+
return;
|
|
43502
43626
|
}
|
|
43503
|
-
|
|
43504
|
-
|
|
43505
|
-
|
|
43506
|
-
|
|
43507
|
-
|
|
43508
|
-
|
|
43509
|
-
|
|
43627
|
+
try {
|
|
43628
|
+
const data = await _add(value);
|
|
43629
|
+
res.json({
|
|
43630
|
+
message: "Successfully created section student.",
|
|
43631
|
+
data
|
|
43632
|
+
});
|
|
43633
|
+
return;
|
|
43634
|
+
} catch (error2) {
|
|
43635
|
+
next(error2);
|
|
43510
43636
|
}
|
|
43511
|
-
|
|
43512
|
-
|
|
43513
|
-
const
|
|
43514
|
-
|
|
43515
|
-
|
|
43637
|
+
}
|
|
43638
|
+
async function getAll(req, res, next) {
|
|
43639
|
+
const query = req.query;
|
|
43640
|
+
const validation = Joi44.object({
|
|
43641
|
+
page: Joi44.number().min(1).optional().allow("", null),
|
|
43642
|
+
limit: Joi44.number().min(1).optional().allow("", null),
|
|
43643
|
+
search: Joi44.string().optional().allow("", null),
|
|
43644
|
+
status: Joi44.string().optional().allow("", null),
|
|
43645
|
+
school: Joi44.string().optional().allow("", null),
|
|
43646
|
+
gradeLevel: Joi44.string().optional().allow("", null),
|
|
43647
|
+
section: Joi44.string().optional().allow("", null),
|
|
43648
|
+
schoolYear: Joi44.string().optional().allow("", null)
|
|
43649
|
+
});
|
|
43650
|
+
const { error } = validation.validate(query);
|
|
43651
|
+
const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
|
|
43652
|
+
const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
|
|
43653
|
+
const search = req.query.search ?? "";
|
|
43654
|
+
const status = req.query.status ?? "active";
|
|
43655
|
+
const school = req.query.school ?? "";
|
|
43656
|
+
const gradeLevel = req.query.gradeLevel ?? "";
|
|
43657
|
+
const section = req.query.section ?? "";
|
|
43658
|
+
const schoolYear = req.query.schoolYear ?? "";
|
|
43659
|
+
const isPageNumber = isFinite(page);
|
|
43660
|
+
if (!isPageNumber) {
|
|
43661
|
+
next(new BadRequestError66("Invalid page number."));
|
|
43662
|
+
return;
|
|
43516
43663
|
}
|
|
43517
|
-
|
|
43518
|
-
|
|
43519
|
-
|
|
43520
|
-
|
|
43521
|
-
);
|
|
43522
|
-
}
|
|
43664
|
+
const isLimitNumber = isFinite(limit);
|
|
43665
|
+
if (!isLimitNumber) {
|
|
43666
|
+
next(new BadRequestError66("Invalid limit number."));
|
|
43667
|
+
return;
|
|
43523
43668
|
}
|
|
43524
|
-
return sizes;
|
|
43525
|
-
}
|
|
43526
|
-
async function generateSections(value) {
|
|
43527
|
-
const { error } = schemaGenerateSections.validate(value);
|
|
43528
43669
|
if (error) {
|
|
43529
|
-
|
|
43530
|
-
|
|
43531
|
-
);
|
|
43532
|
-
}
|
|
43533
|
-
const session = useAtlas31.getClient()?.startSession();
|
|
43534
|
-
if (!session) {
|
|
43535
|
-
throw new Error("Unable to start database session.");
|
|
43536
|
-
}
|
|
43537
|
-
try {
|
|
43538
|
-
await session.startTransaction();
|
|
43539
|
-
const isKindergarten = value.gradeLevel.toLowerCase() === "kindergarten";
|
|
43540
|
-
let kindergartenRoutine = null;
|
|
43541
|
-
if (isKindergarten) {
|
|
43542
|
-
kindergartenRoutine = await getKindergartenRoutineById(
|
|
43543
|
-
value.routine ?? ""
|
|
43544
|
-
);
|
|
43545
|
-
if (!kindergartenRoutine) {
|
|
43546
|
-
throw new BadRequestError67("Kindergarten routine not found.");
|
|
43547
|
-
}
|
|
43548
|
-
}
|
|
43549
|
-
const studentCount = await getCountByGradeLevel(
|
|
43550
|
-
{
|
|
43551
|
-
school: value.school,
|
|
43552
|
-
schoolYear: value.schoolYear,
|
|
43553
|
-
gradeLevel: value.gradeLevel,
|
|
43554
|
-
specialProgram: value.specialProgram
|
|
43555
|
-
},
|
|
43556
|
-
session
|
|
43557
|
-
);
|
|
43558
|
-
if (studentCount === 0) {
|
|
43559
|
-
throw new BadRequestError67("No learners found for this grade level.");
|
|
43560
|
-
}
|
|
43561
|
-
const gradeLevelData = await getByGradeLevel(
|
|
43562
|
-
{
|
|
43563
|
-
school: value.school,
|
|
43564
|
-
gradeLevel: value.gradeLevel
|
|
43565
|
-
},
|
|
43566
|
-
session
|
|
43567
|
-
);
|
|
43568
|
-
if (!gradeLevelData) {
|
|
43569
|
-
throw new BadRequestError67("Grade level not found.");
|
|
43570
|
-
}
|
|
43571
|
-
const minPerSection = value.minStudents ?? gradeLevelData.minNumberOfLearners;
|
|
43572
|
-
const maxPerSection = value.maxStudents ?? gradeLevelData.maxNumberOfLearners;
|
|
43573
|
-
const sectionsNeeded = Math.ceil(studentCount / minPerSection);
|
|
43574
|
-
if (sectionsNeeded > value.set.length) {
|
|
43575
|
-
throw new BadRequestError67(
|
|
43576
|
-
"Insufficient number of section names in set[]."
|
|
43577
|
-
);
|
|
43578
|
-
}
|
|
43579
|
-
const sectionSizes = distributeStudents(
|
|
43580
|
-
studentCount,
|
|
43581
|
-
minPerSection,
|
|
43582
|
-
maxPerSection
|
|
43583
|
-
);
|
|
43584
|
-
if (sectionSizes.length === 0) {
|
|
43585
|
-
throw new BadRequestError67("Unable to compute section sizes.");
|
|
43586
|
-
}
|
|
43587
|
-
const schoolData = await getSchoolById(value.school);
|
|
43588
|
-
if (!schoolData) {
|
|
43589
|
-
throw new BadRequestError67("School not found.");
|
|
43590
|
-
}
|
|
43591
|
-
let totalStudentsProcessed = 0;
|
|
43592
|
-
for (let i = 0; i < sectionSizes.length; i++) {
|
|
43593
|
-
const size = sectionSizes[i];
|
|
43594
|
-
const sectionName = value.set[i];
|
|
43595
|
-
const section = await createSection(
|
|
43596
|
-
{
|
|
43597
|
-
school: value.school,
|
|
43598
|
-
schoolYear: value.schoolYear,
|
|
43599
|
-
gradeLevel: value.gradeLevel,
|
|
43600
|
-
name: sectionName,
|
|
43601
|
-
students: size
|
|
43602
|
-
},
|
|
43603
|
-
session
|
|
43604
|
-
);
|
|
43605
|
-
const skip = totalStudentsProcessed;
|
|
43606
|
-
const learners = await getLeanerByGradeLevel(
|
|
43607
|
-
{
|
|
43608
|
-
school: value.school,
|
|
43609
|
-
gradeLevel: value.gradeLevel,
|
|
43610
|
-
skip,
|
|
43611
|
-
limit: size
|
|
43612
|
-
},
|
|
43613
|
-
session
|
|
43614
|
-
);
|
|
43615
|
-
if (!learners.length) {
|
|
43616
|
-
throw new BadRequestError67(`No learners found for section #${i + 1}.`);
|
|
43617
|
-
}
|
|
43618
|
-
totalStudentsProcessed += learners.length;
|
|
43619
|
-
for (const student of learners) {
|
|
43620
|
-
if (!student._id) {
|
|
43621
|
-
throw new BadRequestError67("Learner ID is missing.");
|
|
43622
|
-
}
|
|
43623
|
-
if (!student.learnerInfo.lrn) {
|
|
43624
|
-
throw new BadRequestError67("Learner LRN is missing.");
|
|
43625
|
-
}
|
|
43626
|
-
await assignStudent(
|
|
43627
|
-
{
|
|
43628
|
-
section: section.toString(),
|
|
43629
|
-
lrn: student.learnerInfo.lrn,
|
|
43630
|
-
student: student._id?.toString(),
|
|
43631
|
-
studentName: `${student.learnerInfo.firstName} ${student.learnerInfo.lastName}`,
|
|
43632
|
-
school: value.school,
|
|
43633
|
-
schoolName: schoolData.name,
|
|
43634
|
-
gradeLevel: value.gradeLevel,
|
|
43635
|
-
educationLevel: gradeLevelData.educationLevel,
|
|
43636
|
-
schoolYear: value.schoolYear,
|
|
43637
|
-
status: "active"
|
|
43638
|
-
},
|
|
43639
|
-
session
|
|
43640
|
-
);
|
|
43641
|
-
}
|
|
43642
|
-
const curriculumSubjects = await getAllCurriculumSubjects({
|
|
43643
|
-
schoolYear: Number(value.schoolYear),
|
|
43644
|
-
gradeLevel: value.gradeLevel,
|
|
43645
|
-
limit: 20
|
|
43646
|
-
});
|
|
43647
|
-
for (const curriculumSubject of curriculumSubjects.items) {
|
|
43648
|
-
await addSectionSubject(
|
|
43649
|
-
{
|
|
43650
|
-
curriculum: curriculumSubject.curriculum.toString(),
|
|
43651
|
-
school: value.school,
|
|
43652
|
-
schoolName: schoolData.name,
|
|
43653
|
-
gradeLevel: value.gradeLevel,
|
|
43654
|
-
educationLevel: gradeLevelData.educationLevel,
|
|
43655
|
-
schoolYear: value.schoolYear,
|
|
43656
|
-
section: section.toString(),
|
|
43657
|
-
sectionName,
|
|
43658
|
-
subjectCode: curriculumSubject.subjectCode,
|
|
43659
|
-
subjectName: curriculumSubject.subjectName,
|
|
43660
|
-
teacher: "",
|
|
43661
|
-
teacherName: "",
|
|
43662
|
-
schedule: "",
|
|
43663
|
-
daysOfWeek: [],
|
|
43664
|
-
classroom: "",
|
|
43665
|
-
classroomName: "",
|
|
43666
|
-
sessionDuration: curriculumSubject.sessionDuration,
|
|
43667
|
-
sessionFrequency: curriculumSubject.sessionFrequency,
|
|
43668
|
-
status: "draft"
|
|
43669
|
-
},
|
|
43670
|
-
session
|
|
43671
|
-
);
|
|
43672
|
-
}
|
|
43673
|
-
if (isKindergarten && kindergartenRoutine) {
|
|
43674
|
-
kindergartenRoutine.section = section;
|
|
43675
|
-
kindergartenRoutine.sectionName = sectionName;
|
|
43676
|
-
kindergartenRoutine.type = "actual";
|
|
43677
|
-
await addKindergartenRoutine(kindergartenRoutine, session);
|
|
43678
|
-
}
|
|
43679
|
-
}
|
|
43680
|
-
let pageTeacher = 1;
|
|
43681
|
-
let pagesTeachers = 1;
|
|
43682
|
-
let teachers = [];
|
|
43683
|
-
do {
|
|
43684
|
-
const teachersData = await getAllPersonnel({
|
|
43685
|
-
school: value.school,
|
|
43686
|
-
limit: 100
|
|
43687
|
-
});
|
|
43688
|
-
pagesTeachers = teachersData.pages;
|
|
43689
|
-
teachers.push(...teachersData.items);
|
|
43690
|
-
pageTeacher++;
|
|
43691
|
-
} while (pageTeacher < pagesTeachers);
|
|
43692
|
-
if (!teachers.length) {
|
|
43693
|
-
throw new BadRequestError67(
|
|
43694
|
-
"Could not proceed, no teaching personnel found."
|
|
43695
|
-
);
|
|
43696
|
-
}
|
|
43697
|
-
if (teachers.length) {
|
|
43698
|
-
for (let index = 0; index < teachers.length; index++) {
|
|
43699
|
-
const teacher = teachers[index];
|
|
43700
|
-
if (!teacher._id) {
|
|
43701
|
-
throw new BadRequestError67("Teacher ID is missing.");
|
|
43702
|
-
}
|
|
43703
|
-
await addTeachingLoad(
|
|
43704
|
-
{
|
|
43705
|
-
school: value.school,
|
|
43706
|
-
schoolName: schoolData.name,
|
|
43707
|
-
schoolYear: value.schoolYear,
|
|
43708
|
-
teacher: teacher._id.toString(),
|
|
43709
|
-
teacherName: `${teacher.firstName} ${teacher.lastName}`,
|
|
43710
|
-
status: "draft"
|
|
43711
|
-
},
|
|
43712
|
-
session
|
|
43713
|
-
);
|
|
43714
|
-
}
|
|
43715
|
-
}
|
|
43716
|
-
await session.commitTransaction();
|
|
43717
|
-
return "Sections generated successfully.";
|
|
43718
|
-
} catch (error2) {
|
|
43719
|
-
await session.abortTransaction();
|
|
43720
|
-
if (error2 instanceof AppError26) {
|
|
43721
|
-
throw error2;
|
|
43722
|
-
} else {
|
|
43723
|
-
throw new InternalServerError22("Failed to generate sections.");
|
|
43724
|
-
}
|
|
43725
|
-
} finally {
|
|
43726
|
-
await session?.endSession();
|
|
43727
|
-
}
|
|
43728
|
-
}
|
|
43729
|
-
async function generateSectionPreview(value) {
|
|
43730
|
-
const { error } = schemaGenerateSections.validate(value);
|
|
43731
|
-
if (error) {
|
|
43732
|
-
throw new BadRequestError67(
|
|
43733
|
-
`Invalid section generation data: ${error.message}`
|
|
43734
|
-
);
|
|
43735
|
-
}
|
|
43736
|
-
try {
|
|
43737
|
-
const studentCount = await getCountByGradeLevel({
|
|
43738
|
-
school: value.school,
|
|
43739
|
-
schoolYear: value.schoolYear,
|
|
43740
|
-
gradeLevel: value.gradeLevel,
|
|
43741
|
-
specialProgram: value.specialProgram
|
|
43742
|
-
});
|
|
43743
|
-
if (studentCount === 0) {
|
|
43744
|
-
throw new BadRequestError67("No learners found for this grade level.");
|
|
43745
|
-
}
|
|
43746
|
-
const gradeLevelData = await getByGradeLevel({
|
|
43747
|
-
school: value.school,
|
|
43748
|
-
gradeLevel: value.gradeLevel
|
|
43749
|
-
});
|
|
43750
|
-
if (!gradeLevelData) {
|
|
43751
|
-
throw new BadRequestError67("Grade level not found.");
|
|
43752
|
-
}
|
|
43753
|
-
const minPerSection = value.minStudents ?? gradeLevelData.minNumberOfLearners;
|
|
43754
|
-
const maxPerSection = value.maxStudents ?? gradeLevelData.maxNumberOfLearners;
|
|
43755
|
-
const sectionsNeeded = Math.ceil(studentCount / minPerSection);
|
|
43756
|
-
if (sectionsNeeded > value.set.length) {
|
|
43757
|
-
throw new BadRequestError67(
|
|
43758
|
-
"Insufficient number of section names in set[]."
|
|
43759
|
-
);
|
|
43760
|
-
}
|
|
43761
|
-
const sectionSizes = distributeStudents(
|
|
43762
|
-
studentCount,
|
|
43763
|
-
minPerSection,
|
|
43764
|
-
maxPerSection
|
|
43765
|
-
);
|
|
43766
|
-
if (sectionSizes.length === 0) {
|
|
43767
|
-
throw new BadRequestError67("Unable to compute section sizes.");
|
|
43768
|
-
}
|
|
43769
|
-
const sections = sectionSizes.map((size, index) => ({
|
|
43770
|
-
name: value.set[index],
|
|
43771
|
-
value: size
|
|
43772
|
-
}));
|
|
43773
|
-
return {
|
|
43774
|
-
totalSectionsGenerated: sectionSizes.length,
|
|
43775
|
-
totalStudentsAssigned: studentCount,
|
|
43776
|
-
sections
|
|
43777
|
-
};
|
|
43778
|
-
} catch (error2) {
|
|
43779
|
-
if (error2 instanceof AppError26) {
|
|
43780
|
-
throw error2;
|
|
43781
|
-
} else {
|
|
43782
|
-
throw new InternalServerError22("Failed to generate section preview.");
|
|
43783
|
-
}
|
|
43784
|
-
}
|
|
43785
|
-
}
|
|
43786
|
-
return { generateSections, generateSectionPreview };
|
|
43787
|
-
}
|
|
43788
|
-
|
|
43789
|
-
// src/resources/section/section.controller.ts
|
|
43790
|
-
function useSectionController() {
|
|
43791
|
-
const {
|
|
43792
|
-
add: _add,
|
|
43793
|
-
getAll: _getAll,
|
|
43794
|
-
getById: _getById,
|
|
43795
|
-
getByName: _getByName,
|
|
43796
|
-
getBySchool: _getBySchool,
|
|
43797
|
-
updateFieldById: _updateFieldById,
|
|
43798
|
-
addStudentToSection: _addStudentToSection,
|
|
43799
|
-
removeStudentFromSection: _removeStudentFromSection,
|
|
43800
|
-
deleteById: _deleteById
|
|
43801
|
-
} = useSectionRepo();
|
|
43802
|
-
const {
|
|
43803
|
-
generateSections: _generateSections,
|
|
43804
|
-
generateSectionPreview: _generateSectionPreview
|
|
43805
|
-
} = useSectionService();
|
|
43806
|
-
async function add(req, res, next) {
|
|
43807
|
-
const value = req.body;
|
|
43808
|
-
const { error } = schemaSection.validate(value);
|
|
43809
|
-
if (error) {
|
|
43810
|
-
next(new BadRequestError68(error.message));
|
|
43811
|
-
return;
|
|
43812
|
-
}
|
|
43813
|
-
try {
|
|
43814
|
-
const data = await _add(value);
|
|
43815
|
-
res.json({
|
|
43816
|
-
message: "Successfully created section.",
|
|
43817
|
-
data
|
|
43818
|
-
});
|
|
43819
|
-
return;
|
|
43820
|
-
} catch (error2) {
|
|
43821
|
-
next(error2);
|
|
43822
|
-
}
|
|
43823
|
-
}
|
|
43824
|
-
async function generateSections(req, res, next) {
|
|
43825
|
-
const value = req.body;
|
|
43826
|
-
const { error } = schemaGenerateSections.validate(value);
|
|
43827
|
-
if (error) {
|
|
43828
|
-
next(new BadRequestError68(error.message));
|
|
43829
|
-
return;
|
|
43830
|
-
}
|
|
43831
|
-
try {
|
|
43832
|
-
const data = await _generateSections(value);
|
|
43833
|
-
res.json({
|
|
43834
|
-
message: "Successfully created section.",
|
|
43835
|
-
data
|
|
43836
|
-
});
|
|
43837
|
-
return;
|
|
43838
|
-
} catch (error2) {
|
|
43839
|
-
next(error2);
|
|
43840
|
-
}
|
|
43841
|
-
}
|
|
43842
|
-
async function generateSectionPreview(req, res, next) {
|
|
43843
|
-
const value = req.body;
|
|
43844
|
-
const { error } = schemaGenerateSections.validate(value);
|
|
43845
|
-
if (error) {
|
|
43846
|
-
next(new BadRequestError68(error.message));
|
|
43847
|
-
return;
|
|
43848
|
-
}
|
|
43849
|
-
try {
|
|
43850
|
-
const data = await _generateSectionPreview(value);
|
|
43851
|
-
res.json(data);
|
|
43852
|
-
return;
|
|
43853
|
-
} catch (error2) {
|
|
43854
|
-
next(error2);
|
|
43855
|
-
}
|
|
43856
|
-
}
|
|
43857
|
-
async function getAll(req, res, next) {
|
|
43858
|
-
const query = req.query;
|
|
43859
|
-
const validation = Joi45.object({
|
|
43860
|
-
page: Joi45.number().min(1).optional().allow("", null),
|
|
43861
|
-
limit: Joi45.number().min(1).optional().allow("", null),
|
|
43862
|
-
search: Joi45.string().optional().allow("", null),
|
|
43863
|
-
status: Joi45.string().optional().allow("", null),
|
|
43864
|
-
school: Joi45.string().hex().optional().allow("", null),
|
|
43865
|
-
schoolYear: Joi45.string().optional().allow("", null),
|
|
43866
|
-
gradeLevel: Joi45.string().optional().allow("", null)
|
|
43867
|
-
});
|
|
43868
|
-
const { error } = validation.validate(query);
|
|
43869
|
-
const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
|
|
43870
|
-
const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
|
|
43871
|
-
const search = req.query.search ?? "";
|
|
43872
|
-
const status = req.query.status ?? "active";
|
|
43873
|
-
const school = req.query.school ?? "";
|
|
43874
|
-
const schoolYear = req.query.schoolYear ?? "";
|
|
43875
|
-
const gradeLevel = req.query.gradeLevel ?? "";
|
|
43876
|
-
const isPageNumber = isFinite(page);
|
|
43877
|
-
if (!isPageNumber) {
|
|
43878
|
-
next(new BadRequestError68("Invalid page number."));
|
|
43879
|
-
return;
|
|
43880
|
-
}
|
|
43881
|
-
const isLimitNumber = isFinite(limit);
|
|
43882
|
-
if (!isLimitNumber) {
|
|
43883
|
-
next(new BadRequestError68("Invalid limit number."));
|
|
43884
|
-
return;
|
|
43885
|
-
}
|
|
43886
|
-
if (error) {
|
|
43887
|
-
next(new BadRequestError68(error.message));
|
|
43888
|
-
return;
|
|
43889
|
-
}
|
|
43890
|
-
try {
|
|
43891
|
-
const data = await _getAll({
|
|
43892
|
-
page,
|
|
43893
|
-
limit,
|
|
43894
|
-
search,
|
|
43895
|
-
status,
|
|
43896
|
-
school,
|
|
43897
|
-
schoolYear,
|
|
43898
|
-
gradeLevel
|
|
43899
|
-
});
|
|
43900
|
-
res.json(data);
|
|
43901
|
-
return;
|
|
43902
|
-
} catch (error2) {
|
|
43903
|
-
next(error2);
|
|
43904
|
-
}
|
|
43905
|
-
}
|
|
43906
|
-
async function getById(req, res, next) {
|
|
43907
|
-
const id = req.params.id;
|
|
43908
|
-
const validation = Joi45.object({
|
|
43909
|
-
id: Joi45.string().hex().required()
|
|
43910
|
-
});
|
|
43911
|
-
const { error } = validation.validate({ id });
|
|
43912
|
-
if (error) {
|
|
43913
|
-
next(new BadRequestError68(error.message));
|
|
43914
|
-
return;
|
|
43915
|
-
}
|
|
43916
|
-
try {
|
|
43917
|
-
const data = await _getById(id);
|
|
43918
|
-
res.json(data);
|
|
43919
|
-
return;
|
|
43920
|
-
} catch (error2) {
|
|
43921
|
-
next(error2);
|
|
43922
|
-
}
|
|
43923
|
-
}
|
|
43924
|
-
async function getByName(req, res, next) {
|
|
43925
|
-
const name = req.params.name;
|
|
43926
|
-
const validation = Joi45.object({
|
|
43927
|
-
name: Joi45.string().required()
|
|
43928
|
-
});
|
|
43929
|
-
const { error } = validation.validate({ name });
|
|
43930
|
-
if (error) {
|
|
43931
|
-
next(new BadRequestError68(error.message));
|
|
43932
|
-
return;
|
|
43933
|
-
}
|
|
43934
|
-
try {
|
|
43935
|
-
const data = await _getByName(name);
|
|
43936
|
-
res.json({
|
|
43937
|
-
message: "Successfully retrieved section.",
|
|
43938
|
-
data
|
|
43939
|
-
});
|
|
43940
|
-
return;
|
|
43941
|
-
} catch (error2) {
|
|
43942
|
-
next(error2);
|
|
43943
|
-
}
|
|
43944
|
-
}
|
|
43945
|
-
async function getBySchool(req, res, next) {
|
|
43946
|
-
const school = req.params.school;
|
|
43947
|
-
const validation = Joi45.object({
|
|
43948
|
-
school: Joi45.string().hex().required()
|
|
43949
|
-
});
|
|
43950
|
-
const { error } = validation.validate({ school });
|
|
43951
|
-
if (error) {
|
|
43952
|
-
next(new BadRequestError68(error.message));
|
|
43953
|
-
return;
|
|
43954
|
-
}
|
|
43955
|
-
try {
|
|
43956
|
-
const data = await _getBySchool(school);
|
|
43957
|
-
res.json({
|
|
43958
|
-
message: "Successfully retrieved sections.",
|
|
43959
|
-
data
|
|
43960
|
-
});
|
|
43961
|
-
return;
|
|
43962
|
-
} catch (error2) {
|
|
43963
|
-
next(error2);
|
|
43964
|
-
}
|
|
43965
|
-
}
|
|
43966
|
-
async function updateField(req, res, next) {
|
|
43967
|
-
const _id = req.params.id;
|
|
43968
|
-
const { field, value } = req.body;
|
|
43969
|
-
const validation = Joi45.object({
|
|
43970
|
-
_id: Joi45.string().hex().required(),
|
|
43971
|
-
field: Joi45.string().valid("name", "schoolYear", "gradeLevel", "adviser", "adviserName").required(),
|
|
43972
|
-
value: Joi45.string().required()
|
|
43973
|
-
});
|
|
43974
|
-
const { error } = validation.validate({ _id, field, value });
|
|
43975
|
-
if (error) {
|
|
43976
|
-
next(new BadRequestError68(error.message));
|
|
43977
|
-
return;
|
|
43978
|
-
}
|
|
43979
|
-
try {
|
|
43980
|
-
const message = await _updateFieldById({ _id, field, value });
|
|
43981
|
-
res.json({ message });
|
|
43982
|
-
return;
|
|
43983
|
-
} catch (error2) {
|
|
43984
|
-
next(error2);
|
|
43985
|
-
}
|
|
43986
|
-
}
|
|
43987
|
-
async function addStudent(req, res, next) {
|
|
43988
|
-
const _id = req.params.id;
|
|
43989
|
-
const { studentId } = req.body;
|
|
43990
|
-
const validation = Joi45.object({
|
|
43991
|
-
_id: Joi45.string().hex().required(),
|
|
43992
|
-
studentId: Joi45.string().required()
|
|
43993
|
-
});
|
|
43994
|
-
const { error } = validation.validate({ _id, studentId });
|
|
43995
|
-
if (error) {
|
|
43996
|
-
next(new BadRequestError68(error.message));
|
|
43997
|
-
return;
|
|
43998
|
-
}
|
|
43999
|
-
try {
|
|
44000
|
-
const message = await _addStudentToSection(_id, studentId);
|
|
44001
|
-
res.json({ message });
|
|
44002
|
-
return;
|
|
44003
|
-
} catch (error2) {
|
|
44004
|
-
next(error2);
|
|
44005
|
-
}
|
|
44006
|
-
}
|
|
44007
|
-
async function removeStudent(req, res, next) {
|
|
44008
|
-
const _id = req.params.id;
|
|
44009
|
-
const { studentId } = req.body;
|
|
44010
|
-
const validation = Joi45.object({
|
|
44011
|
-
_id: Joi45.string().hex().required(),
|
|
44012
|
-
studentId: Joi45.string().required()
|
|
44013
|
-
});
|
|
44014
|
-
const { error } = validation.validate({ _id, studentId });
|
|
44015
|
-
if (error) {
|
|
44016
|
-
next(new BadRequestError68(error.message));
|
|
44017
|
-
return;
|
|
44018
|
-
}
|
|
44019
|
-
try {
|
|
44020
|
-
const message = await _removeStudentFromSection(_id, studentId);
|
|
44021
|
-
res.json({ message });
|
|
44022
|
-
return;
|
|
44023
|
-
} catch (error2) {
|
|
44024
|
-
next(error2);
|
|
44025
|
-
}
|
|
44026
|
-
}
|
|
44027
|
-
async function deleteById(req, res, next) {
|
|
44028
|
-
const _id = req.params.id;
|
|
44029
|
-
const validation = Joi45.object({
|
|
44030
|
-
_id: Joi45.string().hex().required()
|
|
44031
|
-
});
|
|
44032
|
-
const { error } = validation.validate({ _id });
|
|
44033
|
-
if (error) {
|
|
44034
|
-
next(new BadRequestError68(error.message));
|
|
44035
|
-
return;
|
|
44036
|
-
}
|
|
44037
|
-
try {
|
|
44038
|
-
const message = await _deleteById(_id);
|
|
44039
|
-
res.json({ message });
|
|
44040
|
-
return;
|
|
44041
|
-
} catch (error2) {
|
|
44042
|
-
next(error2);
|
|
44043
|
-
}
|
|
44044
|
-
}
|
|
44045
|
-
return {
|
|
44046
|
-
add,
|
|
44047
|
-
generateSections,
|
|
44048
|
-
generateSectionPreview,
|
|
44049
|
-
getAll,
|
|
44050
|
-
getById,
|
|
44051
|
-
getByName,
|
|
44052
|
-
getBySchool,
|
|
44053
|
-
updateField,
|
|
44054
|
-
addStudent,
|
|
44055
|
-
removeStudent,
|
|
44056
|
-
deleteById
|
|
44057
|
-
};
|
|
44058
|
-
}
|
|
44059
|
-
|
|
44060
|
-
// src/resources/section-student/section.student.controller.ts
|
|
44061
|
-
import { BadRequestError as BadRequestError69 } from "@eeplatform/nodejs-utils";
|
|
44062
|
-
import Joi46 from "joi";
|
|
44063
|
-
function useSectionStudentController() {
|
|
44064
|
-
const { add: _add, getAll: _getAll } = useSectionStudentRepo();
|
|
44065
|
-
async function add(req, res, next) {
|
|
44066
|
-
const value = req.body;
|
|
44067
|
-
const { error } = schemaSectionStudent.validate(value);
|
|
44068
|
-
if (error) {
|
|
44069
|
-
next(new BadRequestError69(error.message));
|
|
44070
|
-
return;
|
|
44071
|
-
}
|
|
44072
|
-
try {
|
|
44073
|
-
const data = await _add(value);
|
|
44074
|
-
res.json({
|
|
44075
|
-
message: "Successfully created section student.",
|
|
44076
|
-
data
|
|
44077
|
-
});
|
|
44078
|
-
return;
|
|
44079
|
-
} catch (error2) {
|
|
44080
|
-
next(error2);
|
|
44081
|
-
}
|
|
44082
|
-
}
|
|
44083
|
-
async function getAll(req, res, next) {
|
|
44084
|
-
const query = req.query;
|
|
44085
|
-
const validation = Joi46.object({
|
|
44086
|
-
page: Joi46.number().min(1).optional().allow("", null),
|
|
44087
|
-
limit: Joi46.number().min(1).optional().allow("", null),
|
|
44088
|
-
search: Joi46.string().optional().allow("", null),
|
|
44089
|
-
status: Joi46.string().optional().allow("", null),
|
|
44090
|
-
school: Joi46.string().optional().allow("", null),
|
|
44091
|
-
gradeLevel: Joi46.string().optional().allow("", null),
|
|
44092
|
-
section: Joi46.string().optional().allow("", null),
|
|
44093
|
-
schoolYear: Joi46.string().optional().allow("", null)
|
|
44094
|
-
});
|
|
44095
|
-
const { error } = validation.validate(query);
|
|
44096
|
-
const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
|
|
44097
|
-
const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
|
|
44098
|
-
const search = req.query.search ?? "";
|
|
44099
|
-
const status = req.query.status ?? "active";
|
|
44100
|
-
const school = req.query.school ?? "";
|
|
44101
|
-
const gradeLevel = req.query.gradeLevel ?? "";
|
|
44102
|
-
const section = req.query.section ?? "";
|
|
44103
|
-
const schoolYear = req.query.schoolYear ?? "";
|
|
44104
|
-
const isPageNumber = isFinite(page);
|
|
44105
|
-
if (!isPageNumber) {
|
|
44106
|
-
next(new BadRequestError69("Invalid page number."));
|
|
44107
|
-
return;
|
|
44108
|
-
}
|
|
44109
|
-
const isLimitNumber = isFinite(limit);
|
|
44110
|
-
if (!isLimitNumber) {
|
|
44111
|
-
next(new BadRequestError69("Invalid limit number."));
|
|
44112
|
-
return;
|
|
44113
|
-
}
|
|
44114
|
-
if (error) {
|
|
44115
|
-
next(new BadRequestError69(error.message));
|
|
44116
|
-
return;
|
|
43670
|
+
next(new BadRequestError66(error.message));
|
|
43671
|
+
return;
|
|
44117
43672
|
}
|
|
44118
43673
|
try {
|
|
44119
43674
|
const data = await _getAll({
|
|
@@ -44139,64 +43694,64 @@ function useSectionStudentController() {
|
|
|
44139
43694
|
}
|
|
44140
43695
|
|
|
44141
43696
|
// src/resources/building/building.model.ts
|
|
44142
|
-
import { BadRequestError as
|
|
44143
|
-
import
|
|
44144
|
-
import { ObjectId as
|
|
44145
|
-
var schemaBuilding =
|
|
44146
|
-
_id:
|
|
44147
|
-
school:
|
|
44148
|
-
serial:
|
|
44149
|
-
name:
|
|
44150
|
-
levels:
|
|
44151
|
-
createdAt:
|
|
44152
|
-
updatedAt:
|
|
44153
|
-
deletedAt:
|
|
44154
|
-
status:
|
|
43697
|
+
import { BadRequestError as BadRequestError67, logger as logger39 } from "@eeplatform/nodejs-utils";
|
|
43698
|
+
import Joi45 from "joi";
|
|
43699
|
+
import { ObjectId as ObjectId41 } from "mongodb";
|
|
43700
|
+
var schemaBuilding = Joi45.object({
|
|
43701
|
+
_id: Joi45.string().hex().optional(),
|
|
43702
|
+
school: Joi45.string().hex().required(),
|
|
43703
|
+
serial: Joi45.string().optional().allow("", null),
|
|
43704
|
+
name: Joi45.string().required(),
|
|
43705
|
+
levels: Joi45.number().integer().min(1).required(),
|
|
43706
|
+
createdAt: Joi45.date().optional().allow("", null),
|
|
43707
|
+
updatedAt: Joi45.date().optional().allow("", null),
|
|
43708
|
+
deletedAt: Joi45.date().optional().allow("", null),
|
|
43709
|
+
status: Joi45.string().optional().allow("", null)
|
|
44155
43710
|
});
|
|
44156
|
-
var schemaBuildingUnit =
|
|
44157
|
-
_id:
|
|
44158
|
-
school:
|
|
44159
|
-
name:
|
|
44160
|
-
building:
|
|
44161
|
-
buildingName:
|
|
44162
|
-
level:
|
|
44163
|
-
category:
|
|
44164
|
-
type:
|
|
44165
|
-
seating_capacity:
|
|
44166
|
-
standing_capacity:
|
|
44167
|
-
description:
|
|
44168
|
-
unit_of_measurement:
|
|
44169
|
-
area:
|
|
44170
|
-
status:
|
|
43711
|
+
var schemaBuildingUnit = Joi45.object({
|
|
43712
|
+
_id: Joi45.string().hex().optional(),
|
|
43713
|
+
school: Joi45.string().hex().required(),
|
|
43714
|
+
name: Joi45.string().optional().allow("", null),
|
|
43715
|
+
building: Joi45.string().hex().required(),
|
|
43716
|
+
buildingName: Joi45.string().optional().allow("", null),
|
|
43717
|
+
level: Joi45.number().integer().min(1).required(),
|
|
43718
|
+
category: Joi45.string().required(),
|
|
43719
|
+
type: Joi45.string().required(),
|
|
43720
|
+
seating_capacity: Joi45.number().integer().min(0).required(),
|
|
43721
|
+
standing_capacity: Joi45.number().integer().min(0).required(),
|
|
43722
|
+
description: Joi45.string().optional().allow("", null),
|
|
43723
|
+
unit_of_measurement: Joi45.string().valid("sqm").required(),
|
|
43724
|
+
area: Joi45.number().positive().required(),
|
|
43725
|
+
status: Joi45.string().optional().allow("", null)
|
|
44171
43726
|
});
|
|
44172
|
-
var schemaUpdateOptions =
|
|
44173
|
-
name:
|
|
44174
|
-
building:
|
|
44175
|
-
buildingName:
|
|
44176
|
-
level:
|
|
44177
|
-
category:
|
|
44178
|
-
type:
|
|
44179
|
-
seating_capacity:
|
|
44180
|
-
standing_capacity:
|
|
44181
|
-
area:
|
|
43727
|
+
var schemaUpdateOptions = Joi45.object({
|
|
43728
|
+
name: Joi45.string().optional().allow("", null),
|
|
43729
|
+
building: Joi45.string().hex().optional().allow("", null),
|
|
43730
|
+
buildingName: Joi45.string().optional().allow("", null),
|
|
43731
|
+
level: Joi45.number().integer().min(1).optional().allow("", null),
|
|
43732
|
+
category: Joi45.string().optional().allow("", null),
|
|
43733
|
+
type: Joi45.string().optional().allow("", null),
|
|
43734
|
+
seating_capacity: Joi45.number().integer().min(0).optional().allow("", null),
|
|
43735
|
+
standing_capacity: Joi45.number().integer().min(0).optional().allow("", null),
|
|
43736
|
+
area: Joi45.number().positive().optional().allow("", null)
|
|
44182
43737
|
});
|
|
44183
43738
|
function MBuilding(value) {
|
|
44184
43739
|
const { error } = schemaBuilding.validate(value);
|
|
44185
43740
|
if (error) {
|
|
44186
|
-
|
|
44187
|
-
throw new
|
|
43741
|
+
logger39.info(`Building Model: ${error.message}`);
|
|
43742
|
+
throw new BadRequestError67(error.message);
|
|
44188
43743
|
}
|
|
44189
43744
|
if (value._id && typeof value._id === "string") {
|
|
44190
43745
|
try {
|
|
44191
|
-
value._id = new
|
|
43746
|
+
value._id = new ObjectId41(value._id);
|
|
44192
43747
|
} catch (error2) {
|
|
44193
|
-
throw new
|
|
43748
|
+
throw new BadRequestError67("Invalid _id format");
|
|
44194
43749
|
}
|
|
44195
43750
|
}
|
|
44196
43751
|
try {
|
|
44197
|
-
value.school = new
|
|
43752
|
+
value.school = new ObjectId41(value.school);
|
|
44198
43753
|
} catch (error2) {
|
|
44199
|
-
throw new
|
|
43754
|
+
throw new BadRequestError67("Invalid school format");
|
|
44200
43755
|
}
|
|
44201
43756
|
return {
|
|
44202
43757
|
_id: value._id ?? void 0,
|
|
@@ -44213,25 +43768,25 @@ function MBuilding(value) {
|
|
|
44213
43768
|
function MBuildingUnit(value) {
|
|
44214
43769
|
const { error } = schemaBuildingUnit.validate(value);
|
|
44215
43770
|
if (error) {
|
|
44216
|
-
|
|
44217
|
-
throw new
|
|
43771
|
+
logger39.info(`Building Unit Model: ${error.message}`);
|
|
43772
|
+
throw new BadRequestError67(error.message);
|
|
44218
43773
|
}
|
|
44219
43774
|
if (value._id && typeof value._id === "string") {
|
|
44220
43775
|
try {
|
|
44221
|
-
value._id = new
|
|
43776
|
+
value._id = new ObjectId41(value._id);
|
|
44222
43777
|
} catch (error2) {
|
|
44223
|
-
throw new
|
|
43778
|
+
throw new BadRequestError67("Invalid ID");
|
|
44224
43779
|
}
|
|
44225
43780
|
}
|
|
44226
43781
|
try {
|
|
44227
|
-
value.school = new
|
|
43782
|
+
value.school = new ObjectId41(value.school);
|
|
44228
43783
|
} catch (error2) {
|
|
44229
|
-
throw new
|
|
43784
|
+
throw new BadRequestError67("Invalid school ID");
|
|
44230
43785
|
}
|
|
44231
43786
|
try {
|
|
44232
|
-
value.building = new
|
|
43787
|
+
value.building = new ObjectId41(value.building);
|
|
44233
43788
|
} catch (error2) {
|
|
44234
|
-
throw new
|
|
43789
|
+
throw new BadRequestError67("Invalid building ID");
|
|
44235
43790
|
}
|
|
44236
43791
|
return {
|
|
44237
43792
|
_id: value._id ?? void 0,
|
|
@@ -44256,24 +43811,24 @@ function MBuildingUnit(value) {
|
|
|
44256
43811
|
|
|
44257
43812
|
// src/resources/building/building.repository.ts
|
|
44258
43813
|
import {
|
|
44259
|
-
AppError as
|
|
44260
|
-
BadRequestError as
|
|
44261
|
-
InternalServerError as
|
|
44262
|
-
logger as
|
|
44263
|
-
makeCacheKey as
|
|
44264
|
-
paginate as
|
|
44265
|
-
useAtlas as
|
|
44266
|
-
useCache as
|
|
43814
|
+
AppError as AppError26,
|
|
43815
|
+
BadRequestError as BadRequestError68,
|
|
43816
|
+
InternalServerError as InternalServerError22,
|
|
43817
|
+
logger as logger40,
|
|
43818
|
+
makeCacheKey as makeCacheKey22,
|
|
43819
|
+
paginate as paginate21,
|
|
43820
|
+
useAtlas as useAtlas31,
|
|
43821
|
+
useCache as useCache22
|
|
44267
43822
|
} from "@eeplatform/nodejs-utils";
|
|
44268
|
-
import { ObjectId as
|
|
43823
|
+
import { ObjectId as ObjectId42 } from "mongodb";
|
|
44269
43824
|
function useBuildingRepo() {
|
|
44270
|
-
const db =
|
|
43825
|
+
const db = useAtlas31.getDb();
|
|
44271
43826
|
if (!db) {
|
|
44272
43827
|
throw new Error("Unable to connect to server.");
|
|
44273
43828
|
}
|
|
44274
43829
|
const namespace_collection = "deped.buildings";
|
|
44275
43830
|
const collection = db.collection(namespace_collection);
|
|
44276
|
-
const { getCache, setCache, delNamespace } =
|
|
43831
|
+
const { getCache, setCache, delNamespace } = useCache22(namespace_collection);
|
|
44277
43832
|
async function createIndexes() {
|
|
44278
43833
|
try {
|
|
44279
43834
|
await collection.createIndexes([
|
|
@@ -44292,16 +43847,16 @@ function useBuildingRepo() {
|
|
|
44292
43847
|
delCachedData();
|
|
44293
43848
|
return res.insertedId;
|
|
44294
43849
|
} catch (error) {
|
|
44295
|
-
|
|
43850
|
+
logger40.log({
|
|
44296
43851
|
level: "error",
|
|
44297
43852
|
message: error.message
|
|
44298
43853
|
});
|
|
44299
|
-
if (error instanceof
|
|
43854
|
+
if (error instanceof AppError26) {
|
|
44300
43855
|
throw error;
|
|
44301
43856
|
} else {
|
|
44302
43857
|
const isDuplicated = error.message.includes("duplicate");
|
|
44303
43858
|
if (isDuplicated) {
|
|
44304
|
-
throw new
|
|
43859
|
+
throw new BadRequestError68("Building already exists.");
|
|
44305
43860
|
}
|
|
44306
43861
|
throw new Error("Failed to create building.");
|
|
44307
43862
|
}
|
|
@@ -44309,9 +43864,9 @@ function useBuildingRepo() {
|
|
|
44309
43864
|
}
|
|
44310
43865
|
async function updateById(_id, value, session) {
|
|
44311
43866
|
try {
|
|
44312
|
-
_id = new
|
|
43867
|
+
_id = new ObjectId42(_id);
|
|
44313
43868
|
} catch (error) {
|
|
44314
|
-
throw new
|
|
43869
|
+
throw new BadRequestError68(namespace_collection + " Invalid ID.");
|
|
44315
43870
|
}
|
|
44316
43871
|
try {
|
|
44317
43872
|
const res = await collection.updateOne(
|
|
@@ -44322,11 +43877,11 @@ function useBuildingRepo() {
|
|
|
44322
43877
|
delCachedData();
|
|
44323
43878
|
return res;
|
|
44324
43879
|
} catch (error) {
|
|
44325
|
-
|
|
43880
|
+
logger40.log({
|
|
44326
43881
|
level: "error",
|
|
44327
43882
|
message: error.message
|
|
44328
43883
|
});
|
|
44329
|
-
if (error instanceof
|
|
43884
|
+
if (error instanceof AppError26) {
|
|
44330
43885
|
throw error;
|
|
44331
43886
|
} else {
|
|
44332
43887
|
throw new Error("Failed to update building.");
|
|
@@ -44351,9 +43906,9 @@ function useBuildingRepo() {
|
|
|
44351
43906
|
}
|
|
44352
43907
|
if (school) {
|
|
44353
43908
|
try {
|
|
44354
|
-
query.school = new
|
|
43909
|
+
query.school = new ObjectId42(school);
|
|
44355
43910
|
} catch (error) {
|
|
44356
|
-
throw new
|
|
43911
|
+
throw new BadRequestError68("Invalid school ID.");
|
|
44357
43912
|
}
|
|
44358
43913
|
}
|
|
44359
43914
|
const cacheParams = {
|
|
@@ -44367,15 +43922,15 @@ function useBuildingRepo() {
|
|
|
44367
43922
|
cacheParams.school = school;
|
|
44368
43923
|
if (status !== "active")
|
|
44369
43924
|
cacheParams.status = status;
|
|
44370
|
-
const cacheKey =
|
|
44371
|
-
|
|
43925
|
+
const cacheKey = makeCacheKey22(namespace_collection, cacheParams);
|
|
43926
|
+
logger40.log({
|
|
44372
43927
|
level: "info",
|
|
44373
43928
|
message: `Cache key for getAll buildings: ${cacheKey}`
|
|
44374
43929
|
});
|
|
44375
43930
|
try {
|
|
44376
43931
|
const cached = await getCache(cacheKey);
|
|
44377
43932
|
if (cached) {
|
|
44378
|
-
|
|
43933
|
+
logger40.log({
|
|
44379
43934
|
level: "info",
|
|
44380
43935
|
message: `Cache hit for getAll buildings: ${cacheKey}`
|
|
44381
43936
|
});
|
|
@@ -44388,35 +43943,35 @@ function useBuildingRepo() {
|
|
|
44388
43943
|
{ $limit: limit }
|
|
44389
43944
|
]).toArray();
|
|
44390
43945
|
const length = await collection.countDocuments(query);
|
|
44391
|
-
const data =
|
|
43946
|
+
const data = paginate21(items, page, limit, length);
|
|
44392
43947
|
setCache(cacheKey, data, 600).then(() => {
|
|
44393
|
-
|
|
43948
|
+
logger40.log({
|
|
44394
43949
|
level: "info",
|
|
44395
43950
|
message: `Cache set for getAll buildings: ${cacheKey}`
|
|
44396
43951
|
});
|
|
44397
43952
|
}).catch((err) => {
|
|
44398
|
-
|
|
43953
|
+
logger40.log({
|
|
44399
43954
|
level: "error",
|
|
44400
43955
|
message: `Failed to set cache for getAll buildings: ${err.message}`
|
|
44401
43956
|
});
|
|
44402
43957
|
});
|
|
44403
43958
|
return data;
|
|
44404
43959
|
} catch (error) {
|
|
44405
|
-
|
|
43960
|
+
logger40.log({ level: "error", message: `${error}` });
|
|
44406
43961
|
throw error;
|
|
44407
43962
|
}
|
|
44408
43963
|
}
|
|
44409
43964
|
async function getById(_id) {
|
|
44410
43965
|
try {
|
|
44411
|
-
_id = new
|
|
43966
|
+
_id = new ObjectId42(_id);
|
|
44412
43967
|
} catch (error) {
|
|
44413
|
-
throw new
|
|
43968
|
+
throw new BadRequestError68(namespace_collection + " Invalid ID.");
|
|
44414
43969
|
}
|
|
44415
|
-
const cacheKey =
|
|
43970
|
+
const cacheKey = makeCacheKey22(namespace_collection, { _id: String(_id) });
|
|
44416
43971
|
try {
|
|
44417
43972
|
const cached = await getCache(cacheKey);
|
|
44418
43973
|
if (cached) {
|
|
44419
|
-
|
|
43974
|
+
logger40.log({
|
|
44420
43975
|
level: "info",
|
|
44421
43976
|
message: `Cache hit for getById building: ${cacheKey}`
|
|
44422
43977
|
});
|
|
@@ -44426,30 +43981,30 @@ function useBuildingRepo() {
|
|
|
44426
43981
|
_id
|
|
44427
43982
|
});
|
|
44428
43983
|
setCache(cacheKey, result, 300).then(() => {
|
|
44429
|
-
|
|
43984
|
+
logger40.log({
|
|
44430
43985
|
level: "info",
|
|
44431
43986
|
message: `Cache set for building by id: ${cacheKey}`
|
|
44432
43987
|
});
|
|
44433
43988
|
}).catch((err) => {
|
|
44434
|
-
|
|
43989
|
+
logger40.log({
|
|
44435
43990
|
level: "error",
|
|
44436
43991
|
message: `Failed to set cache for building by id: ${err.message}`
|
|
44437
43992
|
});
|
|
44438
43993
|
});
|
|
44439
43994
|
return result;
|
|
44440
43995
|
} catch (error) {
|
|
44441
|
-
if (error instanceof
|
|
43996
|
+
if (error instanceof AppError26) {
|
|
44442
43997
|
throw error;
|
|
44443
43998
|
} else {
|
|
44444
|
-
throw new
|
|
43999
|
+
throw new InternalServerError22("Failed to get building.");
|
|
44445
44000
|
}
|
|
44446
44001
|
}
|
|
44447
44002
|
}
|
|
44448
44003
|
async function deleteById(_id, session) {
|
|
44449
44004
|
try {
|
|
44450
|
-
_id = new
|
|
44005
|
+
_id = new ObjectId42(_id);
|
|
44451
44006
|
} catch (error) {
|
|
44452
|
-
throw new
|
|
44007
|
+
throw new BadRequestError68(namespace_collection + " Invalid ID.");
|
|
44453
44008
|
}
|
|
44454
44009
|
try {
|
|
44455
44010
|
const res = await collection.updateOne(
|
|
@@ -44459,25 +44014,25 @@ function useBuildingRepo() {
|
|
|
44459
44014
|
delCachedData();
|
|
44460
44015
|
return res;
|
|
44461
44016
|
} catch (error) {
|
|
44462
|
-
|
|
44017
|
+
logger40.log({
|
|
44463
44018
|
level: "error",
|
|
44464
44019
|
message: error.message
|
|
44465
44020
|
});
|
|
44466
|
-
if (error instanceof
|
|
44021
|
+
if (error instanceof AppError26) {
|
|
44467
44022
|
throw error;
|
|
44468
44023
|
} else {
|
|
44469
|
-
throw new
|
|
44024
|
+
throw new InternalServerError22("Failed to delete building.");
|
|
44470
44025
|
}
|
|
44471
44026
|
}
|
|
44472
44027
|
}
|
|
44473
44028
|
function delCachedData() {
|
|
44474
44029
|
delNamespace().then(() => {
|
|
44475
|
-
|
|
44030
|
+
logger40.log({
|
|
44476
44031
|
level: "info",
|
|
44477
44032
|
message: `Cache namespace cleared for ${namespace_collection}`
|
|
44478
44033
|
});
|
|
44479
44034
|
}).catch((err) => {
|
|
44480
|
-
|
|
44035
|
+
logger40.log({
|
|
44481
44036
|
level: "error",
|
|
44482
44037
|
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
44483
44038
|
});
|
|
@@ -44495,31 +44050,31 @@ function useBuildingRepo() {
|
|
|
44495
44050
|
|
|
44496
44051
|
// src/resources/building/building.service.ts
|
|
44497
44052
|
import {
|
|
44498
|
-
BadRequestError as
|
|
44053
|
+
BadRequestError as BadRequestError70,
|
|
44499
44054
|
NotFoundError as NotFoundError3,
|
|
44500
|
-
useAtlas as
|
|
44055
|
+
useAtlas as useAtlas33
|
|
44501
44056
|
} from "@eeplatform/nodejs-utils";
|
|
44502
44057
|
|
|
44503
44058
|
// src/resources/building/building-unit.repository.ts
|
|
44504
44059
|
import {
|
|
44505
|
-
AppError as
|
|
44506
|
-
BadRequestError as
|
|
44507
|
-
InternalServerError as
|
|
44508
|
-
logger as
|
|
44509
|
-
makeCacheKey as
|
|
44510
|
-
paginate as
|
|
44511
|
-
useAtlas as
|
|
44512
|
-
useCache as
|
|
44060
|
+
AppError as AppError27,
|
|
44061
|
+
BadRequestError as BadRequestError69,
|
|
44062
|
+
InternalServerError as InternalServerError23,
|
|
44063
|
+
logger as logger41,
|
|
44064
|
+
makeCacheKey as makeCacheKey23,
|
|
44065
|
+
paginate as paginate22,
|
|
44066
|
+
useAtlas as useAtlas32,
|
|
44067
|
+
useCache as useCache23
|
|
44513
44068
|
} from "@eeplatform/nodejs-utils";
|
|
44514
|
-
import { ObjectId as
|
|
44069
|
+
import { ObjectId as ObjectId43 } from "mongodb";
|
|
44515
44070
|
function useBuildingUnitRepo() {
|
|
44516
|
-
const db =
|
|
44071
|
+
const db = useAtlas32.getDb();
|
|
44517
44072
|
if (!db) {
|
|
44518
44073
|
throw new Error("Unable to connect to server.");
|
|
44519
44074
|
}
|
|
44520
44075
|
const namespace_collection = "deped.building.units";
|
|
44521
44076
|
const collection = db.collection(namespace_collection);
|
|
44522
|
-
const { getCache, setCache, delNamespace } =
|
|
44077
|
+
const { getCache, setCache, delNamespace } = useCache23(namespace_collection);
|
|
44523
44078
|
async function createIndexes() {
|
|
44524
44079
|
try {
|
|
44525
44080
|
await collection.createIndexes([
|
|
@@ -44547,12 +44102,12 @@ function useBuildingUnitRepo() {
|
|
|
44547
44102
|
}
|
|
44548
44103
|
function delCachedData() {
|
|
44549
44104
|
delNamespace().then(() => {
|
|
44550
|
-
|
|
44105
|
+
logger41.log({
|
|
44551
44106
|
level: "info",
|
|
44552
44107
|
message: `Cache namespace cleared for ${namespace_collection}`
|
|
44553
44108
|
});
|
|
44554
44109
|
}).catch((err) => {
|
|
44555
|
-
|
|
44110
|
+
logger41.log({
|
|
44556
44111
|
level: "error",
|
|
44557
44112
|
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
44558
44113
|
});
|
|
@@ -44565,11 +44120,11 @@ function useBuildingUnitRepo() {
|
|
|
44565
44120
|
delCachedData();
|
|
44566
44121
|
return res.insertedId;
|
|
44567
44122
|
} catch (error) {
|
|
44568
|
-
|
|
44123
|
+
logger41.log({
|
|
44569
44124
|
level: "error",
|
|
44570
44125
|
message: error.message
|
|
44571
44126
|
});
|
|
44572
|
-
if (error instanceof
|
|
44127
|
+
if (error instanceof AppError27) {
|
|
44573
44128
|
throw error;
|
|
44574
44129
|
} else {
|
|
44575
44130
|
throw new Error("Failed to create building unit.");
|
|
@@ -44579,12 +44134,12 @@ function useBuildingUnitRepo() {
|
|
|
44579
44134
|
async function updateById(_id, value, session) {
|
|
44580
44135
|
const { error } = schemaUpdateOptions.validate(value);
|
|
44581
44136
|
if (error) {
|
|
44582
|
-
throw new
|
|
44137
|
+
throw new BadRequestError69(error.message);
|
|
44583
44138
|
}
|
|
44584
44139
|
try {
|
|
44585
|
-
_id = new
|
|
44140
|
+
_id = new ObjectId43(_id);
|
|
44586
44141
|
} catch (error2) {
|
|
44587
|
-
throw new
|
|
44142
|
+
throw new BadRequestError69(namespace_collection + " Invalid ID.");
|
|
44588
44143
|
}
|
|
44589
44144
|
try {
|
|
44590
44145
|
const res = await collection.updateOne(
|
|
@@ -44595,11 +44150,11 @@ function useBuildingUnitRepo() {
|
|
|
44595
44150
|
delCachedData();
|
|
44596
44151
|
return res;
|
|
44597
44152
|
} catch (error2) {
|
|
44598
|
-
|
|
44153
|
+
logger41.log({
|
|
44599
44154
|
level: "error",
|
|
44600
44155
|
message: error2.message
|
|
44601
44156
|
});
|
|
44602
|
-
if (error2 instanceof
|
|
44157
|
+
if (error2 instanceof AppError27) {
|
|
44603
44158
|
throw error2;
|
|
44604
44159
|
} else {
|
|
44605
44160
|
throw new Error("Failed to create building unit.");
|
|
@@ -44609,12 +44164,12 @@ function useBuildingUnitRepo() {
|
|
|
44609
44164
|
async function updateByBuildingId(building, value, session) {
|
|
44610
44165
|
const { error } = schemaUpdateOptions.validate(value);
|
|
44611
44166
|
if (error) {
|
|
44612
|
-
throw new
|
|
44167
|
+
throw new BadRequestError69(error.message);
|
|
44613
44168
|
}
|
|
44614
44169
|
try {
|
|
44615
|
-
building = new
|
|
44170
|
+
building = new ObjectId43(building);
|
|
44616
44171
|
} catch (error2) {
|
|
44617
|
-
throw new
|
|
44172
|
+
throw new BadRequestError69("Invalid building ID.");
|
|
44618
44173
|
}
|
|
44619
44174
|
try {
|
|
44620
44175
|
const res = await collection.updateMany(
|
|
@@ -44625,11 +44180,11 @@ function useBuildingUnitRepo() {
|
|
|
44625
44180
|
delCachedData();
|
|
44626
44181
|
return res;
|
|
44627
44182
|
} catch (error2) {
|
|
44628
|
-
|
|
44183
|
+
logger41.log({
|
|
44629
44184
|
level: "error",
|
|
44630
44185
|
message: error2.message
|
|
44631
44186
|
});
|
|
44632
|
-
if (error2 instanceof
|
|
44187
|
+
if (error2 instanceof AppError27) {
|
|
44633
44188
|
throw error2;
|
|
44634
44189
|
} else {
|
|
44635
44190
|
throw new Error("Failed to update building unit.");
|
|
@@ -44661,37 +44216,941 @@ function useBuildingUnitRepo() {
|
|
|
44661
44216
|
query.$text = { $search: search };
|
|
44662
44217
|
cacheParams.search = search;
|
|
44663
44218
|
}
|
|
44664
|
-
if (school) {
|
|
44219
|
+
if (school) {
|
|
44220
|
+
try {
|
|
44221
|
+
query.school = new ObjectId43(school);
|
|
44222
|
+
} catch (error) {
|
|
44223
|
+
throw new BadRequestError69("Invalid school ID.");
|
|
44224
|
+
}
|
|
44225
|
+
cacheParams.school = school;
|
|
44226
|
+
}
|
|
44227
|
+
if (building) {
|
|
44228
|
+
try {
|
|
44229
|
+
query.building = new ObjectId43(building);
|
|
44230
|
+
} catch (error) {
|
|
44231
|
+
throw new BadRequestError69("Invalid building ID.");
|
|
44232
|
+
}
|
|
44233
|
+
cacheParams.building = building;
|
|
44234
|
+
}
|
|
44235
|
+
if (type) {
|
|
44236
|
+
query.type = type;
|
|
44237
|
+
cacheParams.type = type;
|
|
44238
|
+
}
|
|
44239
|
+
const cacheKey = makeCacheKey23(namespace_collection, cacheParams);
|
|
44240
|
+
logger41.log({
|
|
44241
|
+
level: "info",
|
|
44242
|
+
message: `Cache key for getAll building units: ${cacheKey}`
|
|
44243
|
+
});
|
|
44244
|
+
try {
|
|
44245
|
+
const cached = await getCache(cacheKey);
|
|
44246
|
+
if (cached) {
|
|
44247
|
+
logger41.log({
|
|
44248
|
+
level: "info",
|
|
44249
|
+
message: `Cache hit for getAll building units: ${cacheKey}`
|
|
44250
|
+
});
|
|
44251
|
+
return cached;
|
|
44252
|
+
}
|
|
44253
|
+
const items = await collection.aggregate([
|
|
44254
|
+
{ $match: query },
|
|
44255
|
+
{ $sort: sort },
|
|
44256
|
+
{ $skip: page * limit },
|
|
44257
|
+
{ $limit: limit }
|
|
44258
|
+
]).toArray();
|
|
44259
|
+
const length = await collection.countDocuments(query);
|
|
44260
|
+
const data = paginate22(items, page, limit, length);
|
|
44261
|
+
setCache(cacheKey, data, 600).then(() => {
|
|
44262
|
+
logger41.log({
|
|
44263
|
+
level: "info",
|
|
44264
|
+
message: `Cache set for getAll building units: ${cacheKey}`
|
|
44265
|
+
});
|
|
44266
|
+
}).catch((err) => {
|
|
44267
|
+
logger41.log({
|
|
44268
|
+
level: "error",
|
|
44269
|
+
message: `Failed to set cache for getAll building units: ${err.message}`
|
|
44270
|
+
});
|
|
44271
|
+
});
|
|
44272
|
+
return data;
|
|
44273
|
+
} catch (error) {
|
|
44274
|
+
logger41.log({ level: "error", message: `${error}` });
|
|
44275
|
+
throw error;
|
|
44276
|
+
}
|
|
44277
|
+
}
|
|
44278
|
+
async function countByBuilding(building, level) {
|
|
44279
|
+
const query = {
|
|
44280
|
+
status: "active"
|
|
44281
|
+
};
|
|
44282
|
+
const cacheKeyOptions = {
|
|
44283
|
+
...query,
|
|
44284
|
+
tag: "countByBuilding"
|
|
44285
|
+
};
|
|
44286
|
+
try {
|
|
44287
|
+
query.building = new ObjectId43(building);
|
|
44288
|
+
cacheKeyOptions.building = String(building);
|
|
44289
|
+
} catch (error) {
|
|
44290
|
+
throw new BadRequestError69("Invalid building ID.");
|
|
44291
|
+
}
|
|
44292
|
+
if (level) {
|
|
44293
|
+
query.level = level;
|
|
44294
|
+
cacheKeyOptions.level = level;
|
|
44295
|
+
}
|
|
44296
|
+
try {
|
|
44297
|
+
return await collection.countDocuments(query);
|
|
44298
|
+
} catch (error) {
|
|
44299
|
+
logger41.log({ level: "error", message: `${error}` });
|
|
44300
|
+
throw new InternalServerError23("Failed to count building units.");
|
|
44301
|
+
}
|
|
44302
|
+
}
|
|
44303
|
+
async function getById(_id) {
|
|
44304
|
+
try {
|
|
44305
|
+
_id = new ObjectId43(_id);
|
|
44306
|
+
} catch (error) {
|
|
44307
|
+
throw new BadRequestError69(namespace_collection + " Invalid ID.");
|
|
44308
|
+
}
|
|
44309
|
+
const cacheKey = makeCacheKey23(namespace_collection, { _id: String(_id) });
|
|
44310
|
+
try {
|
|
44311
|
+
const cached = await getCache(cacheKey);
|
|
44312
|
+
if (cached) {
|
|
44313
|
+
logger41.log({
|
|
44314
|
+
level: "info",
|
|
44315
|
+
message: `Cache hit for getById building unit: ${cacheKey}`
|
|
44316
|
+
});
|
|
44317
|
+
return cached;
|
|
44318
|
+
}
|
|
44319
|
+
const result = await collection.findOne({
|
|
44320
|
+
_id,
|
|
44321
|
+
deletedAt: { $in: ["", null] }
|
|
44322
|
+
});
|
|
44323
|
+
if (!result) {
|
|
44324
|
+
throw new BadRequestError69("Building unit not found.");
|
|
44325
|
+
}
|
|
44326
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
44327
|
+
logger41.log({
|
|
44328
|
+
level: "info",
|
|
44329
|
+
message: `Cache set for building unit by id: ${cacheKey}`
|
|
44330
|
+
});
|
|
44331
|
+
}).catch((err) => {
|
|
44332
|
+
logger41.log({
|
|
44333
|
+
level: "error",
|
|
44334
|
+
message: `Failed to set cache for building unit by id: ${err.message}`
|
|
44335
|
+
});
|
|
44336
|
+
});
|
|
44337
|
+
return result;
|
|
44338
|
+
} catch (error) {
|
|
44339
|
+
if (error instanceof AppError27) {
|
|
44340
|
+
throw error;
|
|
44341
|
+
} else {
|
|
44342
|
+
throw new InternalServerError23("Failed to get building unit.");
|
|
44343
|
+
}
|
|
44344
|
+
}
|
|
44345
|
+
}
|
|
44346
|
+
async function getByBuildingLevel(building, level) {
|
|
44347
|
+
try {
|
|
44348
|
+
building = new ObjectId43(building);
|
|
44349
|
+
} catch (error) {
|
|
44350
|
+
throw new BadRequestError69("Invalid building ID.");
|
|
44351
|
+
}
|
|
44352
|
+
const cacheKey = makeCacheKey23(namespace_collection, {
|
|
44353
|
+
building: String(building),
|
|
44354
|
+
level
|
|
44355
|
+
});
|
|
44356
|
+
try {
|
|
44357
|
+
const cached = await getCache(cacheKey);
|
|
44358
|
+
if (cached) {
|
|
44359
|
+
logger41.log({
|
|
44360
|
+
level: "info",
|
|
44361
|
+
message: `Cache hit for getById building unit: ${cacheKey}`
|
|
44362
|
+
});
|
|
44363
|
+
return cached;
|
|
44364
|
+
}
|
|
44365
|
+
const result = await collection.findOne({
|
|
44366
|
+
building,
|
|
44367
|
+
level,
|
|
44368
|
+
status: "active"
|
|
44369
|
+
});
|
|
44370
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
44371
|
+
logger41.log({
|
|
44372
|
+
level: "info",
|
|
44373
|
+
message: `Cache set for building unit by id: ${cacheKey}`
|
|
44374
|
+
});
|
|
44375
|
+
}).catch((err) => {
|
|
44376
|
+
logger41.log({
|
|
44377
|
+
level: "error",
|
|
44378
|
+
message: `Failed to set cache for building unit by id: ${err.message}`
|
|
44379
|
+
});
|
|
44380
|
+
});
|
|
44381
|
+
return result;
|
|
44382
|
+
} catch (error) {
|
|
44383
|
+
if (error instanceof AppError27) {
|
|
44384
|
+
throw error;
|
|
44385
|
+
} else {
|
|
44386
|
+
throw new InternalServerError23("Failed to get building unit.");
|
|
44387
|
+
}
|
|
44388
|
+
}
|
|
44389
|
+
}
|
|
44390
|
+
async function getByBuilding(building) {
|
|
44391
|
+
try {
|
|
44392
|
+
building = new ObjectId43(building);
|
|
44393
|
+
} catch (error) {
|
|
44394
|
+
throw new BadRequestError69("Invalid building ID.");
|
|
44395
|
+
}
|
|
44396
|
+
const cacheKey = makeCacheKey23(namespace_collection, {
|
|
44397
|
+
building: String(building)
|
|
44398
|
+
});
|
|
44399
|
+
try {
|
|
44400
|
+
const cached = await getCache(cacheKey);
|
|
44401
|
+
if (cached) {
|
|
44402
|
+
logger41.log({
|
|
44403
|
+
level: "info",
|
|
44404
|
+
message: `Cache hit for getById building unit: ${cacheKey}`
|
|
44405
|
+
});
|
|
44406
|
+
return cached;
|
|
44407
|
+
}
|
|
44408
|
+
const result = await collection.findOne({
|
|
44409
|
+
building,
|
|
44410
|
+
status: "active"
|
|
44411
|
+
});
|
|
44412
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
44413
|
+
logger41.log({
|
|
44414
|
+
level: "info",
|
|
44415
|
+
message: `Cache set for building unit by id: ${cacheKey}`
|
|
44416
|
+
});
|
|
44417
|
+
}).catch((err) => {
|
|
44418
|
+
logger41.log({
|
|
44419
|
+
level: "error",
|
|
44420
|
+
message: `Failed to set cache for building unit by id: ${err.message}`
|
|
44421
|
+
});
|
|
44422
|
+
});
|
|
44423
|
+
return result;
|
|
44424
|
+
} catch (error) {
|
|
44425
|
+
if (error instanceof AppError27) {
|
|
44426
|
+
throw error;
|
|
44427
|
+
} else {
|
|
44428
|
+
throw new InternalServerError23("Failed to get building unit.");
|
|
44429
|
+
}
|
|
44430
|
+
}
|
|
44431
|
+
}
|
|
44432
|
+
async function deleteById(_id, session) {
|
|
44433
|
+
try {
|
|
44434
|
+
_id = new ObjectId43(_id);
|
|
44435
|
+
} catch (error) {
|
|
44436
|
+
throw new BadRequestError69(namespace_collection + " Invalid ID.");
|
|
44437
|
+
}
|
|
44438
|
+
try {
|
|
44439
|
+
const res = await collection.updateOne(
|
|
44440
|
+
{ _id },
|
|
44441
|
+
{ $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } },
|
|
44442
|
+
{ session }
|
|
44443
|
+
);
|
|
44444
|
+
delCachedData();
|
|
44445
|
+
return "Room/Facility deleted successfully.";
|
|
44446
|
+
} catch (error) {
|
|
44447
|
+
logger41.log({
|
|
44448
|
+
level: "error",
|
|
44449
|
+
message: error.message
|
|
44450
|
+
});
|
|
44451
|
+
if (error instanceof AppError27) {
|
|
44452
|
+
throw error;
|
|
44453
|
+
} else {
|
|
44454
|
+
throw new Error("Failed to deleted room/facility.");
|
|
44455
|
+
}
|
|
44456
|
+
}
|
|
44457
|
+
}
|
|
44458
|
+
return {
|
|
44459
|
+
createIndexes,
|
|
44460
|
+
add,
|
|
44461
|
+
getAll,
|
|
44462
|
+
getById,
|
|
44463
|
+
getByBuildingLevel,
|
|
44464
|
+
updateById,
|
|
44465
|
+
getByBuilding,
|
|
44466
|
+
deleteById,
|
|
44467
|
+
updateByBuildingId,
|
|
44468
|
+
countByBuilding
|
|
44469
|
+
};
|
|
44470
|
+
}
|
|
44471
|
+
|
|
44472
|
+
// src/resources/building/building.service.ts
|
|
44473
|
+
function useBuildingService() {
|
|
44474
|
+
const {
|
|
44475
|
+
updateById: _updateById,
|
|
44476
|
+
getById: _getById,
|
|
44477
|
+
deleteById: _deleteById
|
|
44478
|
+
} = useBuildingRepo();
|
|
44479
|
+
const { getByBuildingLevel, getByBuilding, updateByBuildingId } = useBuildingUnitRepo();
|
|
44480
|
+
async function updateById(id, data) {
|
|
44481
|
+
data.levels = Number(data.levels);
|
|
44482
|
+
const session = useAtlas33.getClient()?.startSession();
|
|
44483
|
+
try {
|
|
44484
|
+
const building = await _getById(id);
|
|
44485
|
+
if (!building) {
|
|
44486
|
+
throw new NotFoundError3("Building not found.");
|
|
44487
|
+
}
|
|
44488
|
+
if (data.levels < building.levels) {
|
|
44489
|
+
const unit = await getByBuildingLevel(id, building.levels);
|
|
44490
|
+
if (unit) {
|
|
44491
|
+
throw new BadRequestError70(
|
|
44492
|
+
"Cannot reduce floors, there are existing building units at higher floors."
|
|
44493
|
+
);
|
|
44494
|
+
}
|
|
44495
|
+
}
|
|
44496
|
+
session?.startTransaction();
|
|
44497
|
+
if (building.name !== data.name) {
|
|
44498
|
+
await updateByBuildingId(id, { buildingName: data.name }, session);
|
|
44499
|
+
}
|
|
44500
|
+
const result = await _updateById(id, data, session);
|
|
44501
|
+
await session?.commitTransaction();
|
|
44502
|
+
return result;
|
|
44503
|
+
} catch (error) {
|
|
44504
|
+
await session?.abortTransaction();
|
|
44505
|
+
throw error;
|
|
44506
|
+
} finally {
|
|
44507
|
+
session?.endSession();
|
|
44508
|
+
}
|
|
44509
|
+
}
|
|
44510
|
+
async function deleteById(id) {
|
|
44511
|
+
const building = await getByBuilding(id);
|
|
44512
|
+
if (building) {
|
|
44513
|
+
throw new BadRequestError70(
|
|
44514
|
+
"Cannot delete building with existing room/facility. Please delete room/facility first."
|
|
44515
|
+
);
|
|
44516
|
+
}
|
|
44517
|
+
try {
|
|
44518
|
+
await _deleteById(id);
|
|
44519
|
+
return "Building deleted successfully.";
|
|
44520
|
+
} catch (error) {
|
|
44521
|
+
throw error;
|
|
44522
|
+
}
|
|
44523
|
+
}
|
|
44524
|
+
return {
|
|
44525
|
+
updateById,
|
|
44526
|
+
deleteById
|
|
44527
|
+
};
|
|
44528
|
+
}
|
|
44529
|
+
|
|
44530
|
+
// src/resources/building/building.controller.ts
|
|
44531
|
+
import { BadRequestError as BadRequestError71, logger as logger42 } from "@eeplatform/nodejs-utils";
|
|
44532
|
+
import Joi46 from "joi";
|
|
44533
|
+
function useBuildingController() {
|
|
44534
|
+
const { getAll: _getAll, getById: _getById, add: _add } = useBuildingRepo();
|
|
44535
|
+
const { updateById: _updateById, deleteById: _deleteById } = useBuildingService();
|
|
44536
|
+
async function createBuilding(req, res, next) {
|
|
44537
|
+
const value = req.body;
|
|
44538
|
+
const validation = Joi46.object({
|
|
44539
|
+
name: Joi46.string().required(),
|
|
44540
|
+
school: Joi46.string().hex().required(),
|
|
44541
|
+
levels: Joi46.number().integer().min(1).required(),
|
|
44542
|
+
serial: Joi46.string().optional().allow("", null),
|
|
44543
|
+
status: Joi46.string().optional().allow("", null)
|
|
44544
|
+
});
|
|
44545
|
+
const { error } = validation.validate(value);
|
|
44546
|
+
if (error) {
|
|
44547
|
+
next(new BadRequestError71(error.message));
|
|
44548
|
+
logger42.info(`Controller: ${error.message}`);
|
|
44549
|
+
return;
|
|
44550
|
+
}
|
|
44551
|
+
try {
|
|
44552
|
+
const result = await _add(value);
|
|
44553
|
+
res.json(result);
|
|
44554
|
+
return;
|
|
44555
|
+
} catch (error2) {
|
|
44556
|
+
next(error2);
|
|
44557
|
+
}
|
|
44558
|
+
}
|
|
44559
|
+
async function updateById(req, res, next) {
|
|
44560
|
+
const value = req.body;
|
|
44561
|
+
const id = req.params.id ?? "";
|
|
44562
|
+
const validation = Joi46.object({
|
|
44563
|
+
id: Joi46.string().hex().required(),
|
|
44564
|
+
value: Joi46.object({
|
|
44565
|
+
name: Joi46.string().required(),
|
|
44566
|
+
serial: Joi46.string().optional().allow("", null),
|
|
44567
|
+
levels: Joi46.number().integer().min(1).required()
|
|
44568
|
+
})
|
|
44569
|
+
});
|
|
44570
|
+
const { error } = validation.validate({ id, value });
|
|
44571
|
+
if (error) {
|
|
44572
|
+
next(new BadRequestError71(error.message));
|
|
44573
|
+
logger42.info(`Controller: ${error.message}`);
|
|
44574
|
+
return;
|
|
44575
|
+
}
|
|
44576
|
+
try {
|
|
44577
|
+
const result = await _updateById(id, value);
|
|
44578
|
+
res.json(result);
|
|
44579
|
+
return;
|
|
44580
|
+
} catch (error2) {
|
|
44581
|
+
next(error2);
|
|
44582
|
+
}
|
|
44583
|
+
}
|
|
44584
|
+
async function getAll(req, res, next) {
|
|
44585
|
+
const query = req.query;
|
|
44586
|
+
const validation = Joi46.object({
|
|
44587
|
+
page: Joi46.number().min(1).optional().allow("", null),
|
|
44588
|
+
limit: Joi46.number().min(1).optional().allow("", null),
|
|
44589
|
+
search: Joi46.string().optional().allow("", null),
|
|
44590
|
+
school: Joi46.string().hex().optional().allow("", null),
|
|
44591
|
+
status: Joi46.string().optional().allow("", null)
|
|
44592
|
+
});
|
|
44593
|
+
const { error } = validation.validate(query);
|
|
44594
|
+
if (error) {
|
|
44595
|
+
next(new BadRequestError71(error.message));
|
|
44596
|
+
return;
|
|
44597
|
+
}
|
|
44598
|
+
const page = parseInt(req.query.page) ?? 1;
|
|
44599
|
+
let limit = parseInt(req.query.limit) ?? 20;
|
|
44600
|
+
limit = isNaN(limit) ? 20 : limit;
|
|
44601
|
+
const sort = req.query.sort ? String(req.query.sort).split(",") : "";
|
|
44602
|
+
const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
|
|
44603
|
+
const sortObj = {};
|
|
44604
|
+
if (sort && Array.isArray(sort) && sort.length && sortOrder && Array.isArray(sortOrder) && sortOrder.length) {
|
|
44605
|
+
sort.forEach((field, index) => {
|
|
44606
|
+
sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
|
|
44607
|
+
});
|
|
44608
|
+
}
|
|
44609
|
+
const status = req.query.status ?? "active";
|
|
44610
|
+
const school = req.query.school ?? "";
|
|
44611
|
+
const search = req.query.search ?? "";
|
|
44612
|
+
try {
|
|
44613
|
+
const buildings = await _getAll({
|
|
44614
|
+
page,
|
|
44615
|
+
limit,
|
|
44616
|
+
sort: sortObj,
|
|
44617
|
+
status,
|
|
44618
|
+
school,
|
|
44619
|
+
search
|
|
44620
|
+
});
|
|
44621
|
+
res.json(buildings);
|
|
44622
|
+
return;
|
|
44623
|
+
} catch (error2) {
|
|
44624
|
+
next(error2);
|
|
44625
|
+
}
|
|
44626
|
+
}
|
|
44627
|
+
async function getById(req, res, next) {
|
|
44628
|
+
const id = req.params.id;
|
|
44629
|
+
const validation = Joi46.object({
|
|
44630
|
+
id: Joi46.string().hex().required()
|
|
44631
|
+
});
|
|
44632
|
+
const { error } = validation.validate({ id });
|
|
44633
|
+
if (error) {
|
|
44634
|
+
next(new BadRequestError71(error.message));
|
|
44635
|
+
return;
|
|
44636
|
+
}
|
|
44637
|
+
try {
|
|
44638
|
+
const building = await _getById(id);
|
|
44639
|
+
res.json({
|
|
44640
|
+
message: "Successfully retrieved building.",
|
|
44641
|
+
data: { building }
|
|
44642
|
+
});
|
|
44643
|
+
return;
|
|
44644
|
+
} catch (error2) {
|
|
44645
|
+
next(error2);
|
|
44646
|
+
}
|
|
44647
|
+
}
|
|
44648
|
+
async function deleteById(req, res, next) {
|
|
44649
|
+
const id = req.params.id;
|
|
44650
|
+
const validation = Joi46.object({
|
|
44651
|
+
id: Joi46.string().hex().required()
|
|
44652
|
+
});
|
|
44653
|
+
const { error } = validation.validate({ id });
|
|
44654
|
+
if (error) {
|
|
44655
|
+
next(new BadRequestError71(error.message));
|
|
44656
|
+
return;
|
|
44657
|
+
}
|
|
44658
|
+
try {
|
|
44659
|
+
const message = await _deleteById(id);
|
|
44660
|
+
res.json(message);
|
|
44661
|
+
return;
|
|
44662
|
+
} catch (error2) {
|
|
44663
|
+
next(error2);
|
|
44664
|
+
}
|
|
44665
|
+
}
|
|
44666
|
+
return {
|
|
44667
|
+
createBuilding,
|
|
44668
|
+
getAll,
|
|
44669
|
+
getById,
|
|
44670
|
+
updateById,
|
|
44671
|
+
deleteById
|
|
44672
|
+
};
|
|
44673
|
+
}
|
|
44674
|
+
|
|
44675
|
+
// src/resources/building/building-unit.service.ts
|
|
44676
|
+
import { useAtlas as useAtlas34 } from "@eeplatform/nodejs-utils";
|
|
44677
|
+
function useBuildingUnitService() {
|
|
44678
|
+
const {
|
|
44679
|
+
add: _add,
|
|
44680
|
+
countByBuilding,
|
|
44681
|
+
deleteById: _deleteById
|
|
44682
|
+
} = useBuildingUnitRepo();
|
|
44683
|
+
async function add(value) {
|
|
44684
|
+
const session = useAtlas34.getClient()?.startSession();
|
|
44685
|
+
if (!session) {
|
|
44686
|
+
throw new Error("Unable to start session for building unit service.");
|
|
44687
|
+
}
|
|
44688
|
+
try {
|
|
44689
|
+
await session.startTransaction();
|
|
44690
|
+
const existingCount = await countByBuilding(
|
|
44691
|
+
value.building.building,
|
|
44692
|
+
value.building.level
|
|
44693
|
+
);
|
|
44694
|
+
for (let index = 0; index < value.qty; index++) {
|
|
44695
|
+
const unitNumber = existingCount ? existingCount + index + 1 : index + 1;
|
|
44696
|
+
await _add(
|
|
44697
|
+
{ ...value.building, name: `${value.building.name} R${unitNumber}` },
|
|
44698
|
+
session
|
|
44699
|
+
);
|
|
44700
|
+
}
|
|
44701
|
+
await session.commitTransaction();
|
|
44702
|
+
return "Building unit added successfully.";
|
|
44703
|
+
} catch (error) {
|
|
44704
|
+
await session.abortTransaction();
|
|
44705
|
+
throw error;
|
|
44706
|
+
} finally {
|
|
44707
|
+
session.endSession();
|
|
44708
|
+
}
|
|
44709
|
+
}
|
|
44710
|
+
const { getById: getSectionSubjectByClassroom } = useSectionSubjectRepo();
|
|
44711
|
+
async function deleteById(id) {
|
|
44712
|
+
if (!id) {
|
|
44713
|
+
throw new Error("Invalid building unit ID.");
|
|
44714
|
+
}
|
|
44715
|
+
const sectionSubject = await getSectionSubjectByClassroom(id);
|
|
44716
|
+
if (sectionSubject) {
|
|
44717
|
+
throw new Error(
|
|
44718
|
+
"Cannot delete building unit as it is assigned to a section subject."
|
|
44719
|
+
);
|
|
44720
|
+
}
|
|
44721
|
+
try {
|
|
44722
|
+
await _deleteById(id);
|
|
44723
|
+
return "Building unit deleted successfully.";
|
|
44724
|
+
} catch (error) {
|
|
44725
|
+
throw new Error("Failed to delete building unit.");
|
|
44726
|
+
}
|
|
44727
|
+
}
|
|
44728
|
+
return {
|
|
44729
|
+
add,
|
|
44730
|
+
deleteById
|
|
44731
|
+
};
|
|
44732
|
+
}
|
|
44733
|
+
|
|
44734
|
+
// src/resources/building/building-unit.controller.ts
|
|
44735
|
+
import { BadRequestError as BadRequestError72 } from "@eeplatform/nodejs-utils";
|
|
44736
|
+
import Joi47 from "joi";
|
|
44737
|
+
function useBuildingUnitController() {
|
|
44738
|
+
const {
|
|
44739
|
+
getAll: _getAll,
|
|
44740
|
+
getById: _getById,
|
|
44741
|
+
updateById: _updateById
|
|
44742
|
+
} = useBuildingUnitRepo();
|
|
44743
|
+
const { add: _add, deleteById: _deleteById } = useBuildingUnitService();
|
|
44744
|
+
async function add(req, res, next) {
|
|
44745
|
+
const data = req.body;
|
|
44746
|
+
const validation = Joi47.object({
|
|
44747
|
+
building: Joi47.object({
|
|
44748
|
+
school: Joi47.string().hex().required(),
|
|
44749
|
+
name: Joi47.string().optional().allow("", null),
|
|
44750
|
+
building: Joi47.string().hex().required(),
|
|
44751
|
+
buildingName: Joi47.string().optional().allow("", null),
|
|
44752
|
+
level: Joi47.number().integer().min(1).required(),
|
|
44753
|
+
category: Joi47.string().required(),
|
|
44754
|
+
type: Joi47.string().required(),
|
|
44755
|
+
seating_capacity: Joi47.number().integer().min(0).required(),
|
|
44756
|
+
standing_capacity: Joi47.number().integer().min(0).required(),
|
|
44757
|
+
description: Joi47.string().optional().allow("", null),
|
|
44758
|
+
unit_of_measurement: Joi47.string().valid("sqm").required(),
|
|
44759
|
+
area: Joi47.number().positive().required(),
|
|
44760
|
+
status: Joi47.string().optional().allow("", null)
|
|
44761
|
+
}),
|
|
44762
|
+
qty: Joi47.number().integer().min(1).max(20).optional().default(1)
|
|
44763
|
+
});
|
|
44764
|
+
const { error } = validation.validate(data);
|
|
44765
|
+
if (error) {
|
|
44766
|
+
next(new BadRequestError72(error.message));
|
|
44767
|
+
return;
|
|
44768
|
+
}
|
|
44769
|
+
try {
|
|
44770
|
+
const buildingUnit = await _add(data);
|
|
44771
|
+
res.json({
|
|
44772
|
+
message: "Building unit added successfully.",
|
|
44773
|
+
data: { buildingUnit }
|
|
44774
|
+
});
|
|
44775
|
+
} catch (error2) {
|
|
44776
|
+
next(error2);
|
|
44777
|
+
}
|
|
44778
|
+
}
|
|
44779
|
+
async function updateById(req, res, next) {
|
|
44780
|
+
const data = req.body;
|
|
44781
|
+
const id = req.params.id ?? "";
|
|
44782
|
+
const validation = Joi47.object({
|
|
44783
|
+
id: Joi47.string().hex().required(),
|
|
44784
|
+
value: schemaUpdateOptions
|
|
44785
|
+
});
|
|
44786
|
+
const { error } = validation.validate({ id, value: data });
|
|
44787
|
+
if (error) {
|
|
44788
|
+
next(new BadRequestError72(error.message));
|
|
44789
|
+
return;
|
|
44790
|
+
}
|
|
44791
|
+
try {
|
|
44792
|
+
const buildingUnit = await _updateById(id, data);
|
|
44793
|
+
res.json({
|
|
44794
|
+
message: "Building unit updated successfully.",
|
|
44795
|
+
data: { buildingUnit }
|
|
44796
|
+
});
|
|
44797
|
+
} catch (error2) {
|
|
44798
|
+
next(error2);
|
|
44799
|
+
}
|
|
44800
|
+
}
|
|
44801
|
+
async function getAll(req, res, next) {
|
|
44802
|
+
const query = req.query;
|
|
44803
|
+
const validation = Joi47.object({
|
|
44804
|
+
page: Joi47.number().min(1).optional().allow("", null),
|
|
44805
|
+
limit: Joi47.number().min(1).optional().allow("", null),
|
|
44806
|
+
search: Joi47.string().optional().allow("", null),
|
|
44807
|
+
school: Joi47.string().hex().optional().allow("", null),
|
|
44808
|
+
building: Joi47.string().hex().optional().allow("", null),
|
|
44809
|
+
status: Joi47.string().optional().allow("", null),
|
|
44810
|
+
type: Joi47.string().optional().allow("", null)
|
|
44811
|
+
});
|
|
44812
|
+
const { error } = validation.validate(query);
|
|
44813
|
+
if (error) {
|
|
44814
|
+
next(new BadRequestError72(error.message));
|
|
44815
|
+
return;
|
|
44816
|
+
}
|
|
44817
|
+
const page = parseInt(req.query.page) ?? 1;
|
|
44818
|
+
let limit = parseInt(req.query.limit) ?? 20;
|
|
44819
|
+
limit = isNaN(limit) ? 20 : limit;
|
|
44820
|
+
const sort = req.query.sort ? String(req.query.sort).split(",") : "";
|
|
44821
|
+
const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
|
|
44822
|
+
const sortObj = {};
|
|
44823
|
+
if (sort && Array.isArray(sort) && sort.length && sortOrder && Array.isArray(sortOrder) && sortOrder.length) {
|
|
44824
|
+
sort.forEach((field, index) => {
|
|
44825
|
+
sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
|
|
44826
|
+
});
|
|
44827
|
+
}
|
|
44828
|
+
const status = req.query.status ?? "active";
|
|
44829
|
+
const school = req.query.school ?? "";
|
|
44830
|
+
const building = req.query.building ?? "";
|
|
44831
|
+
const search = req.query.search ?? "";
|
|
44832
|
+
const type = req.query.type ?? "";
|
|
44833
|
+
try {
|
|
44834
|
+
const buildings = await _getAll({
|
|
44835
|
+
page,
|
|
44836
|
+
limit,
|
|
44837
|
+
sort: sortObj,
|
|
44838
|
+
status,
|
|
44839
|
+
school,
|
|
44840
|
+
search,
|
|
44841
|
+
building,
|
|
44842
|
+
type
|
|
44843
|
+
});
|
|
44844
|
+
res.json(buildings);
|
|
44845
|
+
return;
|
|
44846
|
+
} catch (error2) {
|
|
44847
|
+
next(error2);
|
|
44848
|
+
}
|
|
44849
|
+
}
|
|
44850
|
+
async function getById(req, res, next) {
|
|
44851
|
+
const id = req.params.id;
|
|
44852
|
+
const validation = Joi47.object({
|
|
44853
|
+
id: Joi47.string().hex().required()
|
|
44854
|
+
});
|
|
44855
|
+
const { error } = validation.validate({ id });
|
|
44856
|
+
if (error) {
|
|
44857
|
+
next(new BadRequestError72(error.message));
|
|
44858
|
+
return;
|
|
44859
|
+
}
|
|
44860
|
+
try {
|
|
44861
|
+
const buildingUnit = await _getById(id);
|
|
44862
|
+
res.json({
|
|
44863
|
+
message: "Successfully retrieved building unit.",
|
|
44864
|
+
data: { buildingUnit }
|
|
44865
|
+
});
|
|
44866
|
+
return;
|
|
44867
|
+
} catch (error2) {
|
|
44868
|
+
next(error2);
|
|
44869
|
+
}
|
|
44870
|
+
}
|
|
44871
|
+
async function deleteById(req, res, next) {
|
|
44872
|
+
const id = req.params.id;
|
|
44873
|
+
const validation = Joi47.object({
|
|
44874
|
+
id: Joi47.string().hex().required()
|
|
44875
|
+
});
|
|
44876
|
+
const { error } = validation.validate({ id });
|
|
44877
|
+
if (error) {
|
|
44878
|
+
next(new BadRequestError72(error.message));
|
|
44879
|
+
return;
|
|
44880
|
+
}
|
|
44881
|
+
try {
|
|
44882
|
+
const message = await _deleteById(id);
|
|
44883
|
+
res.json({ message });
|
|
44884
|
+
return;
|
|
44885
|
+
} catch (error2) {
|
|
44886
|
+
next(error2);
|
|
44887
|
+
}
|
|
44888
|
+
}
|
|
44889
|
+
return {
|
|
44890
|
+
add,
|
|
44891
|
+
getAll,
|
|
44892
|
+
getById,
|
|
44893
|
+
updateById,
|
|
44894
|
+
deleteById
|
|
44895
|
+
};
|
|
44896
|
+
}
|
|
44897
|
+
|
|
44898
|
+
// src/resources/kindergarten-routine/kindergarten.routine.model.ts
|
|
44899
|
+
import { BadRequestError as BadRequestError73 } from "@eeplatform/nodejs-utils";
|
|
44900
|
+
import Joi48 from "joi";
|
|
44901
|
+
import { ObjectId as ObjectId44 } from "mongodb";
|
|
44902
|
+
var schemaKindergartenRoutine = Joi48.object({
|
|
44903
|
+
_id: Joi48.string().hex().optional().allow(null, ""),
|
|
44904
|
+
title: Joi48.string().max(100).required(),
|
|
44905
|
+
section: Joi48.string().hex().optional().allow(null, ""),
|
|
44906
|
+
sectionName: Joi48.string().max(100).optional().allow(null, ""),
|
|
44907
|
+
classroom: Joi48.string().hex().optional().allow(null, ""),
|
|
44908
|
+
classroomName: Joi48.string().max(100).optional().allow(null, ""),
|
|
44909
|
+
blockTimes: Joi48.array().items(
|
|
44910
|
+
Joi48.object({
|
|
44911
|
+
id: Joi48.number().required(),
|
|
44912
|
+
title: Joi48.string().required(),
|
|
44913
|
+
startTime: Joi48.string().required(),
|
|
44914
|
+
endTime: Joi48.string().required(),
|
|
44915
|
+
durationMinutes: Joi48.number().required(),
|
|
44916
|
+
domains: Joi48.array().items(Joi48.string()).optional()
|
|
44917
|
+
})
|
|
44918
|
+
).required(),
|
|
44919
|
+
type: Joi48.string().required(),
|
|
44920
|
+
durationMinutes: Joi48.number().optional().allow(null, 0),
|
|
44921
|
+
school: Joi48.string().hex().required(),
|
|
44922
|
+
schoolYear: Joi48.string().optional().allow(null, ""),
|
|
44923
|
+
createdAt: Joi48.string().isoDate().optional().allow(null, ""),
|
|
44924
|
+
updatedAt: Joi48.string().isoDate().optional().allow(null, ""),
|
|
44925
|
+
deletedAt: Joi48.string().isoDate().optional().allow(null, "")
|
|
44926
|
+
});
|
|
44927
|
+
var schemaKindergartenRoutineUpdate = Joi48.object({
|
|
44928
|
+
title: Joi48.string().max(100).optional().allow(null, ""),
|
|
44929
|
+
section: Joi48.string().hex().optional().allow(null, ""),
|
|
44930
|
+
sectionName: Joi48.string().max(100).optional().allow(null, ""),
|
|
44931
|
+
classroom: Joi48.string().hex().optional().allow(null, ""),
|
|
44932
|
+
classroomName: Joi48.string().max(100).optional().allow(null, ""),
|
|
44933
|
+
blockTimes: Joi48.array().items(
|
|
44934
|
+
Joi48.object({
|
|
44935
|
+
id: Joi48.number().required(),
|
|
44936
|
+
title: Joi48.string().required(),
|
|
44937
|
+
startTime: Joi48.string().required(),
|
|
44938
|
+
endTime: Joi48.string().required(),
|
|
44939
|
+
durationMinutes: Joi48.number().required(),
|
|
44940
|
+
domains: Joi48.array().items(Joi48.string()).optional()
|
|
44941
|
+
})
|
|
44942
|
+
).optional(),
|
|
44943
|
+
durationMinutes: Joi48.number().optional().allow(null, 0)
|
|
44944
|
+
});
|
|
44945
|
+
function modelKindergartenRoutine(value) {
|
|
44946
|
+
const { error } = schemaKindergartenRoutine.validate(value);
|
|
44947
|
+
if (error) {
|
|
44948
|
+
throw new BadRequestError73(
|
|
44949
|
+
`Invalid kindergarten routine data: ${error.message}`
|
|
44950
|
+
);
|
|
44951
|
+
}
|
|
44952
|
+
if (value._id && typeof value._id === "string") {
|
|
44953
|
+
try {
|
|
44954
|
+
value._id = new ObjectId44(value._id);
|
|
44955
|
+
} catch (error2) {
|
|
44956
|
+
throw new Error("Invalid _id.");
|
|
44957
|
+
}
|
|
44958
|
+
}
|
|
44959
|
+
if (value.school && typeof value.school === "string") {
|
|
44960
|
+
try {
|
|
44961
|
+
value.school = new ObjectId44(value.school);
|
|
44962
|
+
} catch (error2) {
|
|
44963
|
+
throw new Error("Invalid school.");
|
|
44964
|
+
}
|
|
44965
|
+
}
|
|
44966
|
+
if (value.section && typeof value.section === "string") {
|
|
44967
|
+
try {
|
|
44968
|
+
value.section = new ObjectId44(value.section);
|
|
44969
|
+
} catch (error2) {
|
|
44970
|
+
throw new Error("Invalid section.");
|
|
44971
|
+
}
|
|
44972
|
+
}
|
|
44973
|
+
if (value.classroom && typeof value.classroom === "string") {
|
|
44974
|
+
try {
|
|
44975
|
+
value.classroom = new ObjectId44(value.classroom);
|
|
44976
|
+
} catch (error2) {
|
|
44977
|
+
throw new Error("Invalid classroom.");
|
|
44978
|
+
}
|
|
44979
|
+
}
|
|
44980
|
+
return {
|
|
44981
|
+
_id: value._id,
|
|
44982
|
+
title: value.title,
|
|
44983
|
+
section: value.section,
|
|
44984
|
+
sectionName: value.sectionName ?? "",
|
|
44985
|
+
classroom: value.classroom,
|
|
44986
|
+
classroomName: value.classroomName ?? "",
|
|
44987
|
+
blockTimes: value.blockTimes,
|
|
44988
|
+
type: value.type,
|
|
44989
|
+
durationMinutes: value.durationMinutes ?? 0,
|
|
44990
|
+
status: value.status ?? "active",
|
|
44991
|
+
school: value.school,
|
|
44992
|
+
schoolYear: value.schoolYear ?? "",
|
|
44993
|
+
createdAt: value.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
44994
|
+
updatedAt: value.updatedAt ?? "",
|
|
44995
|
+
deletedAt: value.deletedAt ?? ""
|
|
44996
|
+
};
|
|
44997
|
+
}
|
|
44998
|
+
|
|
44999
|
+
// src/resources/kindergarten-routine/kindergarten.routine.repository.ts
|
|
45000
|
+
import {
|
|
45001
|
+
AppError as AppError28,
|
|
45002
|
+
BadRequestError as BadRequestError74,
|
|
45003
|
+
InternalServerError as InternalServerError24,
|
|
45004
|
+
logger as logger43,
|
|
45005
|
+
makeCacheKey as makeCacheKey24,
|
|
45006
|
+
paginate as paginate23,
|
|
45007
|
+
useAtlas as useAtlas35,
|
|
45008
|
+
useCache as useCache24
|
|
45009
|
+
} from "@eeplatform/nodejs-utils";
|
|
45010
|
+
import { ObjectId as ObjectId45 } from "mongodb";
|
|
45011
|
+
function useKindergartenRoutineRepo() {
|
|
45012
|
+
const db = useAtlas35.getDb();
|
|
45013
|
+
if (!db) {
|
|
45014
|
+
throw new Error("Unable to connect to server.");
|
|
45015
|
+
}
|
|
45016
|
+
const namespace_collection = "deped.kindergarten.routines";
|
|
45017
|
+
const collection = db.collection(namespace_collection);
|
|
45018
|
+
const { getCache, setCache, delNamespace } = useCache24(namespace_collection);
|
|
45019
|
+
async function createIndexes() {
|
|
45020
|
+
try {
|
|
45021
|
+
await collection.createIndexes([
|
|
45022
|
+
{ key: { section: 1 } },
|
|
45023
|
+
{ key: { classroom: 1 } },
|
|
45024
|
+
{ key: { schedule: 1 } },
|
|
45025
|
+
{ key: { type: 1 } },
|
|
45026
|
+
{ key: { createdAt: 1 } },
|
|
45027
|
+
{ key: { createdBy: 1 } },
|
|
45028
|
+
{ key: { sectionName: "text", classroomName: "text" } },
|
|
45029
|
+
{
|
|
45030
|
+
key: { title: 1, school: 1, type: 1, section: 1, status: 1 },
|
|
45031
|
+
unique: true,
|
|
45032
|
+
name: "unique_kindergarten_routine"
|
|
45033
|
+
}
|
|
45034
|
+
]);
|
|
45035
|
+
} catch (error) {
|
|
45036
|
+
throw new Error("Failed to create index on kindergarten routines.");
|
|
45037
|
+
}
|
|
45038
|
+
}
|
|
45039
|
+
function delCachedData() {
|
|
45040
|
+
delNamespace().then(() => {
|
|
45041
|
+
logger43.log({
|
|
45042
|
+
level: "info",
|
|
45043
|
+
message: `Cache namespace cleared for ${namespace_collection}`
|
|
45044
|
+
});
|
|
45045
|
+
}).catch((err) => {
|
|
45046
|
+
logger43.log({
|
|
45047
|
+
level: "error",
|
|
45048
|
+
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
45049
|
+
});
|
|
45050
|
+
});
|
|
45051
|
+
}
|
|
45052
|
+
async function add(value, session) {
|
|
45053
|
+
try {
|
|
45054
|
+
value = modelKindergartenRoutine(value);
|
|
45055
|
+
const res = await collection.insertOne(value, { session });
|
|
45056
|
+
delCachedData();
|
|
45057
|
+
return res.insertedId;
|
|
45058
|
+
} catch (error) {
|
|
45059
|
+
logger43.log({
|
|
45060
|
+
level: "error",
|
|
45061
|
+
message: error.message
|
|
45062
|
+
});
|
|
45063
|
+
if (error instanceof AppError28) {
|
|
45064
|
+
throw error;
|
|
45065
|
+
} else {
|
|
45066
|
+
const isDuplicated = error.message.includes("duplicate");
|
|
45067
|
+
if (isDuplicated) {
|
|
45068
|
+
throw new BadRequestError74("Kinder schedule already exists.");
|
|
45069
|
+
}
|
|
45070
|
+
throw new Error("Failed to create kindergarten routine.");
|
|
45071
|
+
}
|
|
45072
|
+
}
|
|
45073
|
+
}
|
|
45074
|
+
async function getAll({
|
|
45075
|
+
search = "",
|
|
45076
|
+
page = 1,
|
|
45077
|
+
limit = 10,
|
|
45078
|
+
sort = {},
|
|
45079
|
+
status = "active",
|
|
45080
|
+
createdBy,
|
|
45081
|
+
school = "",
|
|
45082
|
+
section = "",
|
|
45083
|
+
classroom = "",
|
|
45084
|
+
type = "",
|
|
45085
|
+
schoolYear = ""
|
|
45086
|
+
} = {}) {
|
|
45087
|
+
page = page > 0 ? page - 1 : 0;
|
|
45088
|
+
const query = {
|
|
45089
|
+
deletedAt: { $in: ["", null] },
|
|
45090
|
+
status
|
|
45091
|
+
};
|
|
45092
|
+
sort = Object.keys(sort).length > 0 ? sort : { _id: 1 };
|
|
45093
|
+
const cacheKeyOptions = {
|
|
45094
|
+
status,
|
|
45095
|
+
page,
|
|
45096
|
+
limit,
|
|
45097
|
+
sort: JSON.stringify(sort)
|
|
45098
|
+
};
|
|
45099
|
+
if (createdBy) {
|
|
45100
|
+
try {
|
|
45101
|
+
query.createdBy = new ObjectId45(createdBy);
|
|
45102
|
+
} catch (error) {
|
|
45103
|
+
throw new BadRequestError74("Invalid createdBy ID.");
|
|
45104
|
+
}
|
|
45105
|
+
cacheKeyOptions.createdBy = createdBy;
|
|
45106
|
+
}
|
|
45107
|
+
if (search) {
|
|
45108
|
+
query.$text = { $search: search };
|
|
45109
|
+
cacheKeyOptions.search = search;
|
|
45110
|
+
}
|
|
45111
|
+
if (school) {
|
|
45112
|
+
try {
|
|
45113
|
+
query.school = new ObjectId45(school);
|
|
45114
|
+
} catch (error) {
|
|
45115
|
+
throw new BadRequestError74("Invalid school ID.");
|
|
45116
|
+
}
|
|
45117
|
+
cacheKeyOptions.school = school;
|
|
45118
|
+
}
|
|
45119
|
+
if (section) {
|
|
44665
45120
|
try {
|
|
44666
|
-
query.
|
|
45121
|
+
query.section = new ObjectId45(section);
|
|
44667
45122
|
} catch (error) {
|
|
44668
|
-
throw new
|
|
45123
|
+
throw new BadRequestError74("Invalid section ID.");
|
|
44669
45124
|
}
|
|
44670
|
-
|
|
45125
|
+
cacheKeyOptions.section = section;
|
|
44671
45126
|
}
|
|
44672
|
-
if (
|
|
45127
|
+
if (classroom) {
|
|
44673
45128
|
try {
|
|
44674
|
-
query.
|
|
45129
|
+
query.classroom = new ObjectId45(classroom);
|
|
44675
45130
|
} catch (error) {
|
|
44676
|
-
throw new
|
|
45131
|
+
throw new BadRequestError74("Invalid classroom ID.");
|
|
44677
45132
|
}
|
|
44678
|
-
|
|
45133
|
+
cacheKeyOptions.classroom = classroom;
|
|
44679
45134
|
}
|
|
44680
45135
|
if (type) {
|
|
44681
45136
|
query.type = type;
|
|
44682
|
-
|
|
45137
|
+
cacheKeyOptions.type = type;
|
|
45138
|
+
}
|
|
45139
|
+
if (schoolYear) {
|
|
45140
|
+
query.schoolYear = schoolYear;
|
|
45141
|
+
cacheKeyOptions.schoolYear = schoolYear;
|
|
44683
45142
|
}
|
|
44684
|
-
const cacheKey = makeCacheKey24(namespace_collection,
|
|
44685
|
-
|
|
45143
|
+
const cacheKey = makeCacheKey24(namespace_collection, cacheKeyOptions);
|
|
45144
|
+
logger43.log({
|
|
44686
45145
|
level: "info",
|
|
44687
|
-
message: `Cache key for getAll
|
|
45146
|
+
message: `Cache key for getAll kindergarten routines: ${cacheKey}`
|
|
44688
45147
|
});
|
|
44689
45148
|
try {
|
|
44690
45149
|
const cached = await getCache(cacheKey);
|
|
44691
45150
|
if (cached) {
|
|
44692
|
-
|
|
45151
|
+
logger43.log({
|
|
44693
45152
|
level: "info",
|
|
44694
|
-
message: `Cache hit for getAll
|
|
45153
|
+
message: `Cache hit for getAll kindergarten routines: ${cacheKey}`
|
|
44695
45154
|
});
|
|
44696
45155
|
return cached;
|
|
44697
45156
|
}
|
|
@@ -44704,60 +45163,35 @@ function useBuildingUnitRepo() {
|
|
|
44704
45163
|
const length = await collection.countDocuments(query);
|
|
44705
45164
|
const data = paginate23(items, page, limit, length);
|
|
44706
45165
|
setCache(cacheKey, data, 600).then(() => {
|
|
44707
|
-
|
|
45166
|
+
logger43.log({
|
|
44708
45167
|
level: "info",
|
|
44709
|
-
message: `Cache set for getAll
|
|
45168
|
+
message: `Cache set for getAll kindergarten routines: ${cacheKey}`
|
|
44710
45169
|
});
|
|
44711
45170
|
}).catch((err) => {
|
|
44712
|
-
|
|
45171
|
+
logger43.log({
|
|
44713
45172
|
level: "error",
|
|
44714
|
-
message: `Failed to set cache for getAll
|
|
45173
|
+
message: `Failed to set cache for getAll kindergarten routines: ${err.message}`
|
|
44715
45174
|
});
|
|
44716
45175
|
});
|
|
44717
45176
|
return data;
|
|
44718
45177
|
} catch (error) {
|
|
44719
|
-
|
|
45178
|
+
logger43.log({ level: "error", message: `${error}` });
|
|
44720
45179
|
throw error;
|
|
44721
45180
|
}
|
|
44722
45181
|
}
|
|
44723
|
-
async function countByBuilding(building, level) {
|
|
44724
|
-
const query = {
|
|
44725
|
-
status: "active"
|
|
44726
|
-
};
|
|
44727
|
-
const cacheKeyOptions = {
|
|
44728
|
-
...query,
|
|
44729
|
-
tag: "countByBuilding"
|
|
44730
|
-
};
|
|
44731
|
-
try {
|
|
44732
|
-
query.building = new ObjectId45(building);
|
|
44733
|
-
cacheKeyOptions.building = String(building);
|
|
44734
|
-
} catch (error) {
|
|
44735
|
-
throw new BadRequestError72("Invalid building ID.");
|
|
44736
|
-
}
|
|
44737
|
-
if (level) {
|
|
44738
|
-
query.level = level;
|
|
44739
|
-
cacheKeyOptions.level = level;
|
|
44740
|
-
}
|
|
44741
|
-
try {
|
|
44742
|
-
return await collection.countDocuments(query);
|
|
44743
|
-
} catch (error) {
|
|
44744
|
-
logger42.log({ level: "error", message: `${error}` });
|
|
44745
|
-
throw new InternalServerError24("Failed to count building units.");
|
|
44746
|
-
}
|
|
44747
|
-
}
|
|
44748
45182
|
async function getById(_id) {
|
|
44749
45183
|
try {
|
|
44750
45184
|
_id = new ObjectId45(_id);
|
|
44751
45185
|
} catch (error) {
|
|
44752
|
-
throw new
|
|
45186
|
+
throw new BadRequestError74(namespace_collection + " Invalid ID.");
|
|
44753
45187
|
}
|
|
44754
45188
|
const cacheKey = makeCacheKey24(namespace_collection, { _id: String(_id) });
|
|
44755
45189
|
try {
|
|
44756
45190
|
const cached = await getCache(cacheKey);
|
|
44757
45191
|
if (cached) {
|
|
44758
|
-
|
|
45192
|
+
logger43.log({
|
|
44759
45193
|
level: "info",
|
|
44760
|
-
message: `Cache hit for getById
|
|
45194
|
+
message: `Cache hit for getById kindergarten routine: ${cacheKey}`
|
|
44761
45195
|
});
|
|
44762
45196
|
return cached;
|
|
44763
45197
|
}
|
|
@@ -44765,18 +45199,15 @@ function useBuildingUnitRepo() {
|
|
|
44765
45199
|
_id,
|
|
44766
45200
|
deletedAt: { $in: ["", null] }
|
|
44767
45201
|
});
|
|
44768
|
-
if (!result) {
|
|
44769
|
-
throw new BadRequestError72("Building unit not found.");
|
|
44770
|
-
}
|
|
44771
45202
|
setCache(cacheKey, result, 300).then(() => {
|
|
44772
|
-
|
|
45203
|
+
logger43.log({
|
|
44773
45204
|
level: "info",
|
|
44774
|
-
message: `Cache set for
|
|
45205
|
+
message: `Cache set for kindergarten routine by id: ${cacheKey}`
|
|
44775
45206
|
});
|
|
44776
45207
|
}).catch((err) => {
|
|
44777
|
-
|
|
45208
|
+
logger43.log({
|
|
44778
45209
|
level: "error",
|
|
44779
|
-
message: `Failed to set cache for
|
|
45210
|
+
message: `Failed to set cache for kindergarten routine by id: ${err.message}`
|
|
44780
45211
|
});
|
|
44781
45212
|
});
|
|
44782
45213
|
return result;
|
|
@@ -44784,43 +45215,37 @@ function useBuildingUnitRepo() {
|
|
|
44784
45215
|
if (error instanceof AppError28) {
|
|
44785
45216
|
throw error;
|
|
44786
45217
|
} else {
|
|
44787
|
-
throw new InternalServerError24("Failed to get
|
|
45218
|
+
throw new InternalServerError24("Failed to get kindergarten routine.");
|
|
44788
45219
|
}
|
|
44789
45220
|
}
|
|
44790
45221
|
}
|
|
44791
|
-
async function
|
|
44792
|
-
try {
|
|
44793
|
-
building = new ObjectId45(building);
|
|
44794
|
-
} catch (error) {
|
|
44795
|
-
throw new BadRequestError72("Invalid building ID.");
|
|
44796
|
-
}
|
|
45222
|
+
async function countByDomain(domain) {
|
|
44797
45223
|
const cacheKey = makeCacheKey24(namespace_collection, {
|
|
44798
|
-
|
|
44799
|
-
|
|
45224
|
+
domain,
|
|
45225
|
+
tag: "getByDomain"
|
|
44800
45226
|
});
|
|
44801
45227
|
try {
|
|
44802
45228
|
const cached = await getCache(cacheKey);
|
|
44803
45229
|
if (cached) {
|
|
44804
|
-
|
|
45230
|
+
logger43.log({
|
|
44805
45231
|
level: "info",
|
|
44806
|
-
message: `Cache hit for getById
|
|
45232
|
+
message: `Cache hit for getById kindergarten routine: ${cacheKey}`
|
|
44807
45233
|
});
|
|
44808
45234
|
return cached;
|
|
44809
45235
|
}
|
|
44810
|
-
const result = await collection.
|
|
44811
|
-
|
|
44812
|
-
level,
|
|
45236
|
+
const result = await collection.countDocuments({
|
|
45237
|
+
domain,
|
|
44813
45238
|
status: "active"
|
|
44814
45239
|
});
|
|
44815
45240
|
setCache(cacheKey, result, 300).then(() => {
|
|
44816
|
-
|
|
45241
|
+
logger43.log({
|
|
44817
45242
|
level: "info",
|
|
44818
|
-
message: `Cache set for
|
|
45243
|
+
message: `Cache set for kindergarten routine by id: ${cacheKey}`
|
|
44819
45244
|
});
|
|
44820
45245
|
}).catch((err) => {
|
|
44821
|
-
|
|
45246
|
+
logger43.log({
|
|
44822
45247
|
level: "error",
|
|
44823
|
-
message: `Failed to set cache for
|
|
45248
|
+
message: `Failed to set cache for kindergarten routine by id: ${err.message}`
|
|
44824
45249
|
});
|
|
44825
45250
|
});
|
|
44826
45251
|
return result;
|
|
@@ -44828,41 +45253,41 @@ function useBuildingUnitRepo() {
|
|
|
44828
45253
|
if (error instanceof AppError28) {
|
|
44829
45254
|
throw error;
|
|
44830
45255
|
} else {
|
|
44831
|
-
throw new InternalServerError24("Failed to get
|
|
45256
|
+
throw new InternalServerError24("Failed to get kindergarten routine.");
|
|
44832
45257
|
}
|
|
44833
45258
|
}
|
|
44834
45259
|
}
|
|
44835
|
-
async function
|
|
45260
|
+
async function getBySection(section) {
|
|
44836
45261
|
try {
|
|
44837
|
-
|
|
45262
|
+
section = new ObjectId45(section);
|
|
44838
45263
|
} catch (error) {
|
|
44839
|
-
throw new
|
|
45264
|
+
throw new BadRequestError74("Invalid section ID.");
|
|
44840
45265
|
}
|
|
44841
45266
|
const cacheKey = makeCacheKey24(namespace_collection, {
|
|
44842
|
-
|
|
45267
|
+
section: String(section)
|
|
44843
45268
|
});
|
|
44844
45269
|
try {
|
|
44845
45270
|
const cached = await getCache(cacheKey);
|
|
44846
45271
|
if (cached) {
|
|
44847
|
-
|
|
45272
|
+
logger43.log({
|
|
44848
45273
|
level: "info",
|
|
44849
|
-
message: `Cache hit for
|
|
45274
|
+
message: `Cache hit for getBySection kindergarten routine: ${cacheKey}`
|
|
44850
45275
|
});
|
|
44851
45276
|
return cached;
|
|
44852
45277
|
}
|
|
44853
|
-
const result = await collection.
|
|
44854
|
-
|
|
44855
|
-
|
|
44856
|
-
});
|
|
45278
|
+
const result = await collection.find({
|
|
45279
|
+
section,
|
|
45280
|
+
deletedAt: { $in: ["", null] }
|
|
45281
|
+
}).toArray();
|
|
44857
45282
|
setCache(cacheKey, result, 300).then(() => {
|
|
44858
|
-
|
|
45283
|
+
logger43.log({
|
|
44859
45284
|
level: "info",
|
|
44860
|
-
message: `Cache set for
|
|
45285
|
+
message: `Cache set for kindergarten routine by section: ${cacheKey}`
|
|
44861
45286
|
});
|
|
44862
45287
|
}).catch((err) => {
|
|
44863
|
-
|
|
45288
|
+
logger43.log({
|
|
44864
45289
|
level: "error",
|
|
44865
|
-
message: `Failed to set cache for
|
|
45290
|
+
message: `Failed to set cache for kindergarten routine by section: ${err.message}`
|
|
44866
45291
|
});
|
|
44867
45292
|
});
|
|
44868
45293
|
return result;
|
|
@@ -44870,200 +45295,180 @@ function useBuildingUnitRepo() {
|
|
|
44870
45295
|
if (error instanceof AppError28) {
|
|
44871
45296
|
throw error;
|
|
44872
45297
|
} else {
|
|
44873
|
-
throw new InternalServerError24("Failed to get
|
|
45298
|
+
throw new InternalServerError24("Failed to get kindergarten routine.");
|
|
44874
45299
|
}
|
|
44875
45300
|
}
|
|
44876
45301
|
}
|
|
44877
|
-
async function
|
|
45302
|
+
async function updateFieldById({ _id, field, value } = {}, session) {
|
|
45303
|
+
const allowedFields = [
|
|
45304
|
+
"sectionName",
|
|
45305
|
+
"classroomName",
|
|
45306
|
+
"schedule",
|
|
45307
|
+
"blockTimes",
|
|
45308
|
+
"type"
|
|
45309
|
+
];
|
|
45310
|
+
if (!allowedFields.includes(field)) {
|
|
45311
|
+
throw new BadRequestError74(
|
|
45312
|
+
`Field "${field}" is not allowed to be updated.`
|
|
45313
|
+
);
|
|
45314
|
+
}
|
|
44878
45315
|
try {
|
|
44879
45316
|
_id = new ObjectId45(_id);
|
|
44880
45317
|
} catch (error) {
|
|
44881
|
-
throw new
|
|
45318
|
+
throw new BadRequestError74(namespace_collection + " Invalid ID.");
|
|
44882
45319
|
}
|
|
44883
45320
|
try {
|
|
44884
|
-
|
|
44885
|
-
{ _id },
|
|
44886
|
-
{ $set: {
|
|
45321
|
+
await collection.updateOne(
|
|
45322
|
+
{ _id, deletedAt: { $in: ["", null] } },
|
|
45323
|
+
{ $set: { [field]: value, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
|
|
44887
45324
|
{ session }
|
|
44888
45325
|
);
|
|
44889
45326
|
delCachedData();
|
|
44890
|
-
return
|
|
45327
|
+
return `Successfully updated kindergarten routine ${field}.`;
|
|
44891
45328
|
} catch (error) {
|
|
44892
|
-
|
|
44893
|
-
|
|
44894
|
-
|
|
44895
|
-
});
|
|
44896
|
-
if (error instanceof AppError28) {
|
|
44897
|
-
throw error;
|
|
44898
|
-
} else {
|
|
44899
|
-
throw new Error("Failed to deleted room/facility.");
|
|
44900
|
-
}
|
|
45329
|
+
throw new InternalServerError24(
|
|
45330
|
+
`Failed to update kindergarten routine ${field}.`
|
|
45331
|
+
);
|
|
44901
45332
|
}
|
|
44902
45333
|
}
|
|
44903
|
-
|
|
44904
|
-
|
|
44905
|
-
|
|
44906
|
-
|
|
44907
|
-
|
|
44908
|
-
|
|
44909
|
-
|
|
44910
|
-
getByBuilding,
|
|
44911
|
-
deleteById,
|
|
44912
|
-
updateByBuildingId,
|
|
44913
|
-
countByBuilding
|
|
44914
|
-
};
|
|
44915
|
-
}
|
|
44916
|
-
|
|
44917
|
-
// src/resources/building/building.service.ts
|
|
44918
|
-
function useBuildingService() {
|
|
44919
|
-
const {
|
|
44920
|
-
updateById: _updateById,
|
|
44921
|
-
getById: _getById,
|
|
44922
|
-
deleteById: _deleteById
|
|
44923
|
-
} = useBuildingRepo();
|
|
44924
|
-
const { getByBuildingLevel, getByBuilding, updateByBuildingId } = useBuildingUnitRepo();
|
|
44925
|
-
async function updateById(id, data) {
|
|
44926
|
-
data.levels = Number(data.levels);
|
|
44927
|
-
const session = useAtlas34.getClient()?.startSession();
|
|
45334
|
+
async function updateById(_id, value, session) {
|
|
45335
|
+
const { error } = schemaKindergartenRoutineUpdate.validate(value);
|
|
45336
|
+
if (error) {
|
|
45337
|
+
throw new BadRequestError74(
|
|
45338
|
+
`Invalid kindergarten routine data: ${error.message}`
|
|
45339
|
+
);
|
|
45340
|
+
}
|
|
44928
45341
|
try {
|
|
44929
|
-
|
|
44930
|
-
|
|
44931
|
-
|
|
44932
|
-
}
|
|
44933
|
-
if (data.levels < building.levels) {
|
|
44934
|
-
const unit = await getByBuildingLevel(id, building.levels);
|
|
44935
|
-
if (unit) {
|
|
44936
|
-
throw new BadRequestError73(
|
|
44937
|
-
"Cannot reduce floors, there are existing building units at higher floors."
|
|
44938
|
-
);
|
|
44939
|
-
}
|
|
44940
|
-
}
|
|
44941
|
-
session?.startTransaction();
|
|
44942
|
-
if (building.name !== data.name) {
|
|
44943
|
-
await updateByBuildingId(id, { buildingName: data.name }, session);
|
|
44944
|
-
}
|
|
44945
|
-
const result = await _updateById(id, data, session);
|
|
44946
|
-
await session?.commitTransaction();
|
|
44947
|
-
return result;
|
|
44948
|
-
} catch (error) {
|
|
44949
|
-
await session?.abortTransaction();
|
|
44950
|
-
throw error;
|
|
44951
|
-
} finally {
|
|
44952
|
-
session?.endSession();
|
|
45342
|
+
_id = new ObjectId45(_id);
|
|
45343
|
+
} catch (error2) {
|
|
45344
|
+
throw new BadRequestError74(namespace_collection + " Invalid ID.");
|
|
44953
45345
|
}
|
|
44954
|
-
|
|
44955
|
-
|
|
44956
|
-
|
|
44957
|
-
|
|
44958
|
-
|
|
44959
|
-
"Cannot delete building with existing room/facility. Please delete room/facility first."
|
|
45346
|
+
try {
|
|
45347
|
+
await collection.updateOne(
|
|
45348
|
+
{ _id },
|
|
45349
|
+
{ $set: { ...value, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
|
|
45350
|
+
{ session }
|
|
44960
45351
|
);
|
|
45352
|
+
delCachedData();
|
|
45353
|
+
return `Successfully updated kindergarten routine.`;
|
|
45354
|
+
} catch (error2) {
|
|
45355
|
+
throw new InternalServerError24("Failed to update kindergarten routine.");
|
|
45356
|
+
}
|
|
45357
|
+
}
|
|
45358
|
+
async function deleteById(_id) {
|
|
45359
|
+
try {
|
|
45360
|
+
_id = new ObjectId45(_id);
|
|
45361
|
+
} catch (error) {
|
|
45362
|
+
throw new BadRequestError74(namespace_collection + " Invalid ID.");
|
|
44961
45363
|
}
|
|
44962
45364
|
try {
|
|
44963
|
-
await
|
|
44964
|
-
|
|
45365
|
+
await collection.updateOne(
|
|
45366
|
+
{ _id },
|
|
45367
|
+
{ $set: { status: "deleted", deletedAt: (/* @__PURE__ */ new Date()).toISOString() } }
|
|
45368
|
+
);
|
|
45369
|
+
delCachedData();
|
|
45370
|
+
return "Successfully deleted kindergarten routine.";
|
|
44965
45371
|
} catch (error) {
|
|
44966
|
-
throw
|
|
45372
|
+
throw new InternalServerError24("Failed to delete kindergarten routine.");
|
|
44967
45373
|
}
|
|
44968
45374
|
}
|
|
44969
45375
|
return {
|
|
45376
|
+
createIndexes,
|
|
45377
|
+
add,
|
|
45378
|
+
getAll,
|
|
45379
|
+
getById,
|
|
45380
|
+
countByDomain,
|
|
45381
|
+
getBySection,
|
|
45382
|
+
updateFieldById,
|
|
44970
45383
|
updateById,
|
|
44971
45384
|
deleteById
|
|
44972
45385
|
};
|
|
44973
45386
|
}
|
|
44974
45387
|
|
|
44975
|
-
// src/resources/
|
|
44976
|
-
import { BadRequestError as
|
|
44977
|
-
import
|
|
44978
|
-
function
|
|
44979
|
-
const {
|
|
44980
|
-
|
|
44981
|
-
|
|
45388
|
+
// src/resources/kindergarten-routine/kindergarten.routine.controller.ts
|
|
45389
|
+
import { BadRequestError as BadRequestError75 } from "@eeplatform/nodejs-utils";
|
|
45390
|
+
import Joi49 from "joi";
|
|
45391
|
+
function useKindergartenRoutineController() {
|
|
45392
|
+
const {
|
|
45393
|
+
add: _add,
|
|
45394
|
+
getAll: _getAll,
|
|
45395
|
+
getById: _getById,
|
|
45396
|
+
getBySection: _getBySection,
|
|
45397
|
+
updateFieldById: _updateFieldById,
|
|
45398
|
+
deleteById: _deleteById,
|
|
45399
|
+
updateById: _updateById
|
|
45400
|
+
} = useKindergartenRoutineRepo();
|
|
45401
|
+
async function add(req, res, next) {
|
|
44982
45402
|
const value = req.body;
|
|
44983
|
-
const
|
|
44984
|
-
name: Joi48.string().required(),
|
|
44985
|
-
school: Joi48.string().hex().required(),
|
|
44986
|
-
levels: Joi48.number().integer().min(1).required(),
|
|
44987
|
-
serial: Joi48.string().optional().allow("", null),
|
|
44988
|
-
status: Joi48.string().optional().allow("", null)
|
|
44989
|
-
});
|
|
44990
|
-
const { error } = validation.validate(value);
|
|
45403
|
+
const { error } = schemaKindergartenRoutine.validate(value);
|
|
44991
45404
|
if (error) {
|
|
44992
|
-
next(new
|
|
44993
|
-
logger43.info(`Controller: ${error.message}`);
|
|
45405
|
+
next(new BadRequestError75(error.message));
|
|
44994
45406
|
return;
|
|
44995
45407
|
}
|
|
44996
45408
|
try {
|
|
44997
|
-
const
|
|
44998
|
-
res.json(
|
|
45409
|
+
const data = await _add(value);
|
|
45410
|
+
res.json({
|
|
45411
|
+
message: "Successfully created kinder schedule.",
|
|
45412
|
+
data
|
|
45413
|
+
});
|
|
44999
45414
|
return;
|
|
45000
45415
|
} catch (error2) {
|
|
45001
45416
|
next(error2);
|
|
45002
45417
|
}
|
|
45003
45418
|
}
|
|
45004
|
-
async function
|
|
45005
|
-
const
|
|
45006
|
-
const
|
|
45007
|
-
|
|
45008
|
-
|
|
45009
|
-
|
|
45010
|
-
|
|
45011
|
-
|
|
45012
|
-
|
|
45013
|
-
|
|
45419
|
+
async function getAll(req, res, next) {
|
|
45420
|
+
const query = req.query;
|
|
45421
|
+
const validation = Joi49.object({
|
|
45422
|
+
page: Joi49.number().min(1).optional().allow("", null),
|
|
45423
|
+
limit: Joi49.number().min(1).optional().allow("", null),
|
|
45424
|
+
search: Joi49.string().optional().allow("", null),
|
|
45425
|
+
status: Joi49.string().optional().allow("", null),
|
|
45426
|
+
school: Joi49.string().hex().optional().allow("", null),
|
|
45427
|
+
section: Joi49.string().hex().optional().allow("", null),
|
|
45428
|
+
classroom: Joi49.string().hex().optional().allow("", null),
|
|
45429
|
+
type: Joi49.string().optional().allow("", null),
|
|
45430
|
+
createdBy: Joi49.string().hex().optional().allow("", null),
|
|
45431
|
+
schoolYear: Joi49.string().optional().allow("", null)
|
|
45014
45432
|
});
|
|
45015
|
-
const { error } = validation.validate(
|
|
45016
|
-
|
|
45017
|
-
|
|
45018
|
-
|
|
45433
|
+
const { error } = validation.validate(query);
|
|
45434
|
+
const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
|
|
45435
|
+
const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
|
|
45436
|
+
const search = req.query.search ?? "";
|
|
45437
|
+
const status = req.query.status ?? "active";
|
|
45438
|
+
const school = req.query.school ?? "";
|
|
45439
|
+
const section = req.query.section ?? "";
|
|
45440
|
+
const classroom = req.query.classroom ?? "";
|
|
45441
|
+
const type = req.query.type ?? "";
|
|
45442
|
+
const createdBy = req.query.createdBy ?? "";
|
|
45443
|
+
const schoolYear = req.query.schoolYear ?? "";
|
|
45444
|
+
const isPageNumber = isFinite(page);
|
|
45445
|
+
if (!isPageNumber) {
|
|
45446
|
+
next(new BadRequestError75("Invalid page number."));
|
|
45019
45447
|
return;
|
|
45020
45448
|
}
|
|
45021
|
-
|
|
45022
|
-
|
|
45023
|
-
|
|
45449
|
+
const isLimitNumber = isFinite(limit);
|
|
45450
|
+
if (!isLimitNumber) {
|
|
45451
|
+
next(new BadRequestError75("Invalid limit number."));
|
|
45024
45452
|
return;
|
|
45025
|
-
} catch (error2) {
|
|
45026
|
-
next(error2);
|
|
45027
45453
|
}
|
|
45028
|
-
}
|
|
45029
|
-
async function getAll(req, res, next) {
|
|
45030
|
-
const query = req.query;
|
|
45031
|
-
const validation = Joi48.object({
|
|
45032
|
-
page: Joi48.number().min(1).optional().allow("", null),
|
|
45033
|
-
limit: Joi48.number().min(1).optional().allow("", null),
|
|
45034
|
-
search: Joi48.string().optional().allow("", null),
|
|
45035
|
-
school: Joi48.string().hex().optional().allow("", null),
|
|
45036
|
-
status: Joi48.string().optional().allow("", null)
|
|
45037
|
-
});
|
|
45038
|
-
const { error } = validation.validate(query);
|
|
45039
45454
|
if (error) {
|
|
45040
|
-
next(new
|
|
45455
|
+
next(new BadRequestError75(error.message));
|
|
45041
45456
|
return;
|
|
45042
45457
|
}
|
|
45043
|
-
const page = parseInt(req.query.page) ?? 1;
|
|
45044
|
-
let limit = parseInt(req.query.limit) ?? 20;
|
|
45045
|
-
limit = isNaN(limit) ? 20 : limit;
|
|
45046
|
-
const sort = req.query.sort ? String(req.query.sort).split(",") : "";
|
|
45047
|
-
const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
|
|
45048
|
-
const sortObj = {};
|
|
45049
|
-
if (sort && Array.isArray(sort) && sort.length && sortOrder && Array.isArray(sortOrder) && sortOrder.length) {
|
|
45050
|
-
sort.forEach((field, index) => {
|
|
45051
|
-
sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
|
|
45052
|
-
});
|
|
45053
|
-
}
|
|
45054
|
-
const status = req.query.status ?? "active";
|
|
45055
|
-
const school = req.query.school ?? "";
|
|
45056
|
-
const search = req.query.search ?? "";
|
|
45057
45458
|
try {
|
|
45058
|
-
const
|
|
45459
|
+
const data = await _getAll({
|
|
45059
45460
|
page,
|
|
45060
45461
|
limit,
|
|
45061
|
-
|
|
45462
|
+
search,
|
|
45062
45463
|
status,
|
|
45063
45464
|
school,
|
|
45064
|
-
|
|
45465
|
+
section,
|
|
45466
|
+
classroom,
|
|
45467
|
+
type,
|
|
45468
|
+
createdBy: createdBy || void 0,
|
|
45469
|
+
schoolYear
|
|
45065
45470
|
});
|
|
45066
|
-
res.json(
|
|
45471
|
+
res.json(data);
|
|
45067
45472
|
return;
|
|
45068
45473
|
} catch (error2) {
|
|
45069
45474
|
next(error2);
|
|
@@ -45071,260 +45476,100 @@ function useBuildingController() {
|
|
|
45071
45476
|
}
|
|
45072
45477
|
async function getById(req, res, next) {
|
|
45073
45478
|
const id = req.params.id;
|
|
45074
|
-
const validation =
|
|
45075
|
-
id:
|
|
45479
|
+
const validation = Joi49.object({
|
|
45480
|
+
id: Joi49.string().hex().required()
|
|
45076
45481
|
});
|
|
45077
45482
|
const { error } = validation.validate({ id });
|
|
45078
45483
|
if (error) {
|
|
45079
|
-
next(new
|
|
45484
|
+
next(new BadRequestError75(error.message));
|
|
45080
45485
|
return;
|
|
45081
45486
|
}
|
|
45082
45487
|
try {
|
|
45083
|
-
const
|
|
45488
|
+
const data = await _getById(id);
|
|
45084
45489
|
res.json({
|
|
45085
|
-
message: "Successfully retrieved
|
|
45086
|
-
data
|
|
45490
|
+
message: "Successfully retrieved kinder schedule.",
|
|
45491
|
+
data
|
|
45087
45492
|
});
|
|
45088
45493
|
return;
|
|
45089
45494
|
} catch (error2) {
|
|
45090
45495
|
next(error2);
|
|
45091
45496
|
}
|
|
45092
45497
|
}
|
|
45093
|
-
async function
|
|
45094
|
-
const
|
|
45095
|
-
const validation = Joi48.object({
|
|
45096
|
-
id: Joi48.string().hex().required()
|
|
45097
|
-
});
|
|
45098
|
-
const { error } = validation.validate({ id });
|
|
45099
|
-
if (error) {
|
|
45100
|
-
next(new BadRequestError74(error.message));
|
|
45101
|
-
return;
|
|
45102
|
-
}
|
|
45103
|
-
try {
|
|
45104
|
-
const message = await _deleteById(id);
|
|
45105
|
-
res.json(message);
|
|
45106
|
-
return;
|
|
45107
|
-
} catch (error2) {
|
|
45108
|
-
next(error2);
|
|
45109
|
-
}
|
|
45110
|
-
}
|
|
45111
|
-
return {
|
|
45112
|
-
createBuilding,
|
|
45113
|
-
getAll,
|
|
45114
|
-
getById,
|
|
45115
|
-
updateById,
|
|
45116
|
-
deleteById
|
|
45117
|
-
};
|
|
45118
|
-
}
|
|
45119
|
-
|
|
45120
|
-
// src/resources/building/building-unit.service.ts
|
|
45121
|
-
import { useAtlas as useAtlas35 } from "@eeplatform/nodejs-utils";
|
|
45122
|
-
function useBuildingUnitService() {
|
|
45123
|
-
const {
|
|
45124
|
-
add: _add,
|
|
45125
|
-
countByBuilding,
|
|
45126
|
-
deleteById: _deleteById
|
|
45127
|
-
} = useBuildingUnitRepo();
|
|
45128
|
-
async function add(value) {
|
|
45129
|
-
const session = useAtlas35.getClient()?.startSession();
|
|
45130
|
-
if (!session) {
|
|
45131
|
-
throw new Error("Unable to start session for building unit service.");
|
|
45132
|
-
}
|
|
45133
|
-
try {
|
|
45134
|
-
await session.startTransaction();
|
|
45135
|
-
const existingCount = await countByBuilding(
|
|
45136
|
-
value.building.building,
|
|
45137
|
-
value.building.level
|
|
45138
|
-
);
|
|
45139
|
-
for (let index = 0; index < value.qty; index++) {
|
|
45140
|
-
const unitNumber = existingCount ? existingCount + index + 1 : index + 1;
|
|
45141
|
-
await _add(
|
|
45142
|
-
{ ...value.building, name: `${value.building.name} R${unitNumber}` },
|
|
45143
|
-
session
|
|
45144
|
-
);
|
|
45145
|
-
}
|
|
45146
|
-
await session.commitTransaction();
|
|
45147
|
-
return "Building unit added successfully.";
|
|
45148
|
-
} catch (error) {
|
|
45149
|
-
await session.abortTransaction();
|
|
45150
|
-
throw error;
|
|
45151
|
-
} finally {
|
|
45152
|
-
session.endSession();
|
|
45153
|
-
}
|
|
45154
|
-
}
|
|
45155
|
-
const { getById: getSectionSubjectByClassroom } = useSectionSubjectRepo();
|
|
45156
|
-
async function deleteById(id) {
|
|
45157
|
-
if (!id) {
|
|
45158
|
-
throw new Error("Invalid building unit ID.");
|
|
45159
|
-
}
|
|
45160
|
-
const sectionSubject = await getSectionSubjectByClassroom(id);
|
|
45161
|
-
if (sectionSubject) {
|
|
45162
|
-
throw new Error(
|
|
45163
|
-
"Cannot delete building unit as it is assigned to a section subject."
|
|
45164
|
-
);
|
|
45165
|
-
}
|
|
45166
|
-
try {
|
|
45167
|
-
await _deleteById(id);
|
|
45168
|
-
return "Building unit deleted successfully.";
|
|
45169
|
-
} catch (error) {
|
|
45170
|
-
throw new Error("Failed to delete building unit.");
|
|
45171
|
-
}
|
|
45172
|
-
}
|
|
45173
|
-
return {
|
|
45174
|
-
add,
|
|
45175
|
-
deleteById
|
|
45176
|
-
};
|
|
45177
|
-
}
|
|
45178
|
-
|
|
45179
|
-
// src/resources/building/building-unit.controller.ts
|
|
45180
|
-
import { BadRequestError as BadRequestError75 } from "@eeplatform/nodejs-utils";
|
|
45181
|
-
import Joi49 from "joi";
|
|
45182
|
-
function useBuildingUnitController() {
|
|
45183
|
-
const {
|
|
45184
|
-
getAll: _getAll,
|
|
45185
|
-
getById: _getById,
|
|
45186
|
-
updateById: _updateById
|
|
45187
|
-
} = useBuildingUnitRepo();
|
|
45188
|
-
const { add: _add, deleteById: _deleteById } = useBuildingUnitService();
|
|
45189
|
-
async function add(req, res, next) {
|
|
45190
|
-
const data = req.body;
|
|
45498
|
+
async function getBySection(req, res, next) {
|
|
45499
|
+
const section = req.params.section;
|
|
45191
45500
|
const validation = Joi49.object({
|
|
45192
|
-
|
|
45193
|
-
school: Joi49.string().hex().required(),
|
|
45194
|
-
name: Joi49.string().optional().allow("", null),
|
|
45195
|
-
building: Joi49.string().hex().required(),
|
|
45196
|
-
buildingName: Joi49.string().optional().allow("", null),
|
|
45197
|
-
level: Joi49.number().integer().min(1).required(),
|
|
45198
|
-
category: Joi49.string().required(),
|
|
45199
|
-
type: Joi49.string().required(),
|
|
45200
|
-
seating_capacity: Joi49.number().integer().min(0).required(),
|
|
45201
|
-
standing_capacity: Joi49.number().integer().min(0).required(),
|
|
45202
|
-
description: Joi49.string().optional().allow("", null),
|
|
45203
|
-
unit_of_measurement: Joi49.string().valid("sqm").required(),
|
|
45204
|
-
area: Joi49.number().positive().required(),
|
|
45205
|
-
status: Joi49.string().optional().allow("", null)
|
|
45206
|
-
}),
|
|
45207
|
-
qty: Joi49.number().integer().min(1).max(20).optional().default(1)
|
|
45501
|
+
section: Joi49.string().hex().required()
|
|
45208
45502
|
});
|
|
45209
|
-
const { error } = validation.validate(
|
|
45503
|
+
const { error } = validation.validate({ section });
|
|
45210
45504
|
if (error) {
|
|
45211
45505
|
next(new BadRequestError75(error.message));
|
|
45212
45506
|
return;
|
|
45213
45507
|
}
|
|
45214
45508
|
try {
|
|
45215
|
-
const
|
|
45509
|
+
const data = await _getBySection(section);
|
|
45216
45510
|
res.json({
|
|
45217
|
-
message: "
|
|
45218
|
-
data
|
|
45511
|
+
message: "Successfully retrieved kinder schedules.",
|
|
45512
|
+
data
|
|
45219
45513
|
});
|
|
45220
|
-
} catch (error2) {
|
|
45221
|
-
next(error2);
|
|
45222
|
-
}
|
|
45223
|
-
}
|
|
45224
|
-
async function updateById(req, res, next) {
|
|
45225
|
-
const data = req.body;
|
|
45226
|
-
const id = req.params.id ?? "";
|
|
45227
|
-
const validation = Joi49.object({
|
|
45228
|
-
id: Joi49.string().hex().required(),
|
|
45229
|
-
value: schemaUpdateOptions
|
|
45230
|
-
});
|
|
45231
|
-
const { error } = validation.validate({ id, value: data });
|
|
45232
|
-
if (error) {
|
|
45233
|
-
next(new BadRequestError75(error.message));
|
|
45234
45514
|
return;
|
|
45235
|
-
}
|
|
45236
|
-
try {
|
|
45237
|
-
const buildingUnit = await _updateById(id, data);
|
|
45238
|
-
res.json({
|
|
45239
|
-
message: "Building unit updated successfully.",
|
|
45240
|
-
data: { buildingUnit }
|
|
45241
|
-
});
|
|
45242
45515
|
} catch (error2) {
|
|
45243
45516
|
next(error2);
|
|
45244
45517
|
}
|
|
45245
45518
|
}
|
|
45246
|
-
async function
|
|
45247
|
-
const
|
|
45519
|
+
async function updateField(req, res, next) {
|
|
45520
|
+
const _id = req.params.id;
|
|
45521
|
+
const { field, value } = req.body;
|
|
45248
45522
|
const validation = Joi49.object({
|
|
45249
|
-
|
|
45250
|
-
|
|
45251
|
-
|
|
45252
|
-
school: Joi49.string().hex().optional().allow("", null),
|
|
45253
|
-
building: Joi49.string().hex().optional().allow("", null),
|
|
45254
|
-
status: Joi49.string().optional().allow("", null),
|
|
45255
|
-
type: Joi49.string().optional().allow("", null)
|
|
45523
|
+
_id: Joi49.string().hex().required(),
|
|
45524
|
+
field: Joi49.string().valid("sectionName", "classroomName", "schedule", "blockTimes", "type").required(),
|
|
45525
|
+
value: Joi49.alternatives().try(Joi49.string(), Joi49.array(), Joi49.object()).required()
|
|
45256
45526
|
});
|
|
45257
|
-
const { error } = validation.validate(
|
|
45527
|
+
const { error } = validation.validate({ _id, field, value });
|
|
45258
45528
|
if (error) {
|
|
45259
45529
|
next(new BadRequestError75(error.message));
|
|
45260
45530
|
return;
|
|
45261
45531
|
}
|
|
45262
|
-
const page = parseInt(req.query.page) ?? 1;
|
|
45263
|
-
let limit = parseInt(req.query.limit) ?? 20;
|
|
45264
|
-
limit = isNaN(limit) ? 20 : limit;
|
|
45265
|
-
const sort = req.query.sort ? String(req.query.sort).split(",") : "";
|
|
45266
|
-
const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
|
|
45267
|
-
const sortObj = {};
|
|
45268
|
-
if (sort && Array.isArray(sort) && sort.length && sortOrder && Array.isArray(sortOrder) && sortOrder.length) {
|
|
45269
|
-
sort.forEach((field, index) => {
|
|
45270
|
-
sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
|
|
45271
|
-
});
|
|
45272
|
-
}
|
|
45273
|
-
const status = req.query.status ?? "active";
|
|
45274
|
-
const school = req.query.school ?? "";
|
|
45275
|
-
const building = req.query.building ?? "";
|
|
45276
|
-
const search = req.query.search ?? "";
|
|
45277
|
-
const type = req.query.type ?? "";
|
|
45278
45532
|
try {
|
|
45279
|
-
const
|
|
45280
|
-
|
|
45281
|
-
limit,
|
|
45282
|
-
sort: sortObj,
|
|
45283
|
-
status,
|
|
45284
|
-
school,
|
|
45285
|
-
search,
|
|
45286
|
-
building,
|
|
45287
|
-
type
|
|
45288
|
-
});
|
|
45289
|
-
res.json(buildings);
|
|
45533
|
+
const message = await _updateFieldById({ _id, field, value });
|
|
45534
|
+
res.json({ message });
|
|
45290
45535
|
return;
|
|
45291
45536
|
} catch (error2) {
|
|
45292
45537
|
next(error2);
|
|
45293
45538
|
}
|
|
45294
45539
|
}
|
|
45295
|
-
async function
|
|
45296
|
-
const
|
|
45297
|
-
const
|
|
45298
|
-
|
|
45299
|
-
|
|
45300
|
-
|
|
45540
|
+
async function updateById(req, res, next) {
|
|
45541
|
+
const _id = req.params.id;
|
|
45542
|
+
const payload = req.body;
|
|
45543
|
+
const { error: errorId } = Joi49.string().hex().required().validate(_id);
|
|
45544
|
+
if (errorId) {
|
|
45545
|
+
next(new BadRequestError75(errorId.message));
|
|
45546
|
+
return;
|
|
45547
|
+
}
|
|
45548
|
+
const { error } = schemaKindergartenRoutineUpdate.validate(payload);
|
|
45301
45549
|
if (error) {
|
|
45302
45550
|
next(new BadRequestError75(error.message));
|
|
45303
45551
|
return;
|
|
45304
45552
|
}
|
|
45305
45553
|
try {
|
|
45306
|
-
const
|
|
45307
|
-
res.json({
|
|
45308
|
-
message: "Successfully retrieved building unit.",
|
|
45309
|
-
data: { buildingUnit }
|
|
45310
|
-
});
|
|
45554
|
+
const message = await _updateById(_id, payload);
|
|
45555
|
+
res.json({ message });
|
|
45311
45556
|
return;
|
|
45312
45557
|
} catch (error2) {
|
|
45313
45558
|
next(error2);
|
|
45314
45559
|
}
|
|
45315
45560
|
}
|
|
45316
45561
|
async function deleteById(req, res, next) {
|
|
45317
|
-
const
|
|
45562
|
+
const _id = req.params.id;
|
|
45318
45563
|
const validation = Joi49.object({
|
|
45319
|
-
|
|
45564
|
+
_id: Joi49.string().hex().required()
|
|
45320
45565
|
});
|
|
45321
|
-
const { error } = validation.validate({
|
|
45566
|
+
const { error } = validation.validate({ _id });
|
|
45322
45567
|
if (error) {
|
|
45323
45568
|
next(new BadRequestError75(error.message));
|
|
45324
45569
|
return;
|
|
45325
45570
|
}
|
|
45326
45571
|
try {
|
|
45327
|
-
const message = await _deleteById(
|
|
45572
|
+
const message = await _deleteById(_id);
|
|
45328
45573
|
res.json({ message });
|
|
45329
45574
|
return;
|
|
45330
45575
|
} catch (error2) {
|
|
@@ -45335,6 +45580,8 @@ function useBuildingUnitController() {
|
|
|
45335
45580
|
add,
|
|
45336
45581
|
getAll,
|
|
45337
45582
|
getById,
|
|
45583
|
+
getBySection,
|
|
45584
|
+
updateField,
|
|
45338
45585
|
updateById,
|
|
45339
45586
|
deleteById
|
|
45340
45587
|
};
|