@eeplatform/basic-edu 1.10.0 → 1.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/index.d.ts +6 -5
- package/dist/index.js +1860 -1873
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1901 -1914
- 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
|
}
|
|
@@ -39814,15 +39805,15 @@ function useSectionRepo() {
|
|
|
39814
39805
|
}
|
|
39815
39806
|
|
|
39816
39807
|
// src/resources/section/section.controller.ts
|
|
39817
|
-
import { BadRequestError as
|
|
39818
|
-
import
|
|
39808
|
+
import { BadRequestError as BadRequestError65 } from "@eeplatform/nodejs-utils";
|
|
39809
|
+
import Joi43 from "joi";
|
|
39819
39810
|
|
|
39820
39811
|
// src/resources/section/section.service.ts
|
|
39821
39812
|
import {
|
|
39822
|
-
AppError as
|
|
39823
|
-
BadRequestError as
|
|
39824
|
-
InternalServerError as
|
|
39825
|
-
useAtlas as
|
|
39813
|
+
AppError as AppError25,
|
|
39814
|
+
BadRequestError as BadRequestError64,
|
|
39815
|
+
InternalServerError as InternalServerError21,
|
|
39816
|
+
useAtlas as useAtlas30
|
|
39826
39817
|
} from "@eeplatform/nodejs-utils";
|
|
39827
39818
|
|
|
39828
39819
|
// src/resources/section-student/section.student.repository.ts
|
|
@@ -41574,7 +41565,7 @@ function modelTeachingLoadSlot(value) {
|
|
|
41574
41565
|
const { error } = schemaTeachingLoadSlot.validate(value);
|
|
41575
41566
|
if (error) {
|
|
41576
41567
|
logger33.info(`Teaching Load Slot Model: ${error.message}`);
|
|
41577
|
-
throw new BadRequestError58(error.message);
|
|
41568
|
+
throw new BadRequestError58(`${error.message} - model`);
|
|
41578
41569
|
}
|
|
41579
41570
|
if (value._id && typeof value._id === "string") {
|
|
41580
41571
|
try {
|
|
@@ -41990,9 +41981,11 @@ function useTeachingLoadSlotController() {
|
|
|
41990
41981
|
gradeLevel: Joi40.string().required(),
|
|
41991
41982
|
startTime: Joi40.string().required(),
|
|
41992
41983
|
endTime: Joi40.string().required(),
|
|
41993
|
-
subject: Joi40.string().hex().
|
|
41984
|
+
subject: Joi40.string().hex().optional().allow("", null),
|
|
41994
41985
|
subjectName: Joi40.string().optional().allow("", null),
|
|
41995
41986
|
subjectCode: Joi40.string().optional().allow("", null),
|
|
41987
|
+
routine: Joi40.string().hex().optional().allow("", null),
|
|
41988
|
+
routineName: Joi40.string().optional().allow("", null),
|
|
41996
41989
|
section: Joi40.string().hex().required(),
|
|
41997
41990
|
sectionName: Joi40.string().optional().allow("", null),
|
|
41998
41991
|
duration: Joi40.number().min(0).required(),
|
|
@@ -42797,504 +42790,576 @@ function usePersonnelController() {
|
|
|
42797
42790
|
};
|
|
42798
42791
|
}
|
|
42799
42792
|
|
|
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}`);
|
|
42793
|
+
// src/resources/section/section.service.ts
|
|
42794
|
+
function useSectionService() {
|
|
42795
|
+
const { getCountByGradeLevel, getByGradeLevel: getLeanerByGradeLevel } = useLearnerRepo();
|
|
42796
|
+
const { getByGradeLevel } = useGradeLevelRepo();
|
|
42797
|
+
const { add: createSection } = useSectionRepo();
|
|
42798
|
+
const { add: assignStudent } = useSectionStudentRepo();
|
|
42799
|
+
const { getAll: getAllCurriculumSubjects } = useSubjectRepo();
|
|
42800
|
+
const { add: addSectionSubject } = useSectionSubjectRepo();
|
|
42801
|
+
const { getById: getSchoolById } = useSchoolRepo();
|
|
42802
|
+
const { getAll: getAllPersonnel } = usePersonnelRepo();
|
|
42803
|
+
const { add: addTeachingLoad } = useTeachingLoadRepo();
|
|
42804
|
+
function distributeStudents(total, minPer, maxPer) {
|
|
42805
|
+
if (total <= 0)
|
|
42806
|
+
return [];
|
|
42807
|
+
if (minPer <= 0 || maxPer <= 0)
|
|
42808
|
+
return [];
|
|
42809
|
+
if (minPer > maxPer) {
|
|
42810
|
+
throw new BadRequestError64(
|
|
42811
|
+
"Minimum students per section cannot be greater than maximum."
|
|
42812
|
+
);
|
|
42813
|
+
}
|
|
42814
|
+
const minSections = Math.ceil(total / maxPer);
|
|
42815
|
+
const maxSections = Math.floor(total / minPer);
|
|
42816
|
+
let sectionCount;
|
|
42817
|
+
if (minSections <= maxSections) {
|
|
42818
|
+
sectionCount = minSections;
|
|
42819
|
+
} else {
|
|
42820
|
+
sectionCount = minSections;
|
|
42821
|
+
}
|
|
42822
|
+
const base = Math.floor(total / sectionCount);
|
|
42823
|
+
const extra = total % sectionCount;
|
|
42824
|
+
const sizes = new Array(sectionCount).fill(base);
|
|
42825
|
+
for (let i = 0; i < extra; i++) {
|
|
42826
|
+
sizes[i] += 1;
|
|
42827
|
+
}
|
|
42828
|
+
for (const size of sizes) {
|
|
42829
|
+
if (size > maxPer) {
|
|
42830
|
+
throw new BadRequestError64(
|
|
42831
|
+
`Generated section exceeds max limit of ${maxPer}.`
|
|
42832
|
+
);
|
|
42833
|
+
}
|
|
42834
|
+
}
|
|
42835
|
+
return sizes;
|
|
42850
42836
|
}
|
|
42851
|
-
|
|
42837
|
+
async function generateSections(value) {
|
|
42838
|
+
const { error } = schemaGenerateSections.validate(value);
|
|
42839
|
+
if (error) {
|
|
42840
|
+
throw new BadRequestError64(
|
|
42841
|
+
`Invalid section generation data: ${error.message}`
|
|
42842
|
+
);
|
|
42843
|
+
}
|
|
42844
|
+
const session = useAtlas30.getClient()?.startSession();
|
|
42845
|
+
if (!session) {
|
|
42846
|
+
throw new Error("Unable to start database session.");
|
|
42847
|
+
}
|
|
42852
42848
|
try {
|
|
42853
|
-
|
|
42849
|
+
await session.startTransaction();
|
|
42850
|
+
const studentCount = await getCountByGradeLevel(
|
|
42851
|
+
{
|
|
42852
|
+
school: value.school,
|
|
42853
|
+
schoolYear: value.schoolYear,
|
|
42854
|
+
gradeLevel: value.gradeLevel,
|
|
42855
|
+
specialProgram: value.specialProgram
|
|
42856
|
+
},
|
|
42857
|
+
session
|
|
42858
|
+
);
|
|
42859
|
+
if (studentCount === 0) {
|
|
42860
|
+
throw new BadRequestError64("No learners found for this grade level.");
|
|
42861
|
+
}
|
|
42862
|
+
const gradeLevelData = await getByGradeLevel(
|
|
42863
|
+
{
|
|
42864
|
+
school: value.school,
|
|
42865
|
+
gradeLevel: value.gradeLevel
|
|
42866
|
+
},
|
|
42867
|
+
session
|
|
42868
|
+
);
|
|
42869
|
+
if (!gradeLevelData) {
|
|
42870
|
+
throw new BadRequestError64("Grade level not found.");
|
|
42871
|
+
}
|
|
42872
|
+
const minPerSection = value.minStudents ?? gradeLevelData.minNumberOfLearners;
|
|
42873
|
+
const maxPerSection = value.maxStudents ?? gradeLevelData.maxNumberOfLearners;
|
|
42874
|
+
const sectionsNeeded = Math.ceil(studentCount / minPerSection);
|
|
42875
|
+
if (sectionsNeeded > value.set.length) {
|
|
42876
|
+
throw new BadRequestError64(
|
|
42877
|
+
"Insufficient number of section names in set[]."
|
|
42878
|
+
);
|
|
42879
|
+
}
|
|
42880
|
+
const sectionSizes = distributeStudents(
|
|
42881
|
+
studentCount,
|
|
42882
|
+
minPerSection,
|
|
42883
|
+
maxPerSection
|
|
42884
|
+
);
|
|
42885
|
+
if (sectionSizes.length === 0) {
|
|
42886
|
+
throw new BadRequestError64("Unable to compute section sizes.");
|
|
42887
|
+
}
|
|
42888
|
+
const schoolData = await getSchoolById(value.school);
|
|
42889
|
+
if (!schoolData) {
|
|
42890
|
+
throw new BadRequestError64("School not found.");
|
|
42891
|
+
}
|
|
42892
|
+
let totalStudentsProcessed = 0;
|
|
42893
|
+
for (let i = 0; i < sectionSizes.length; i++) {
|
|
42894
|
+
const size = sectionSizes[i];
|
|
42895
|
+
const sectionName = value.set[i];
|
|
42896
|
+
const section = await createSection(
|
|
42897
|
+
{
|
|
42898
|
+
school: value.school,
|
|
42899
|
+
schoolYear: value.schoolYear,
|
|
42900
|
+
gradeLevel: value.gradeLevel,
|
|
42901
|
+
name: sectionName,
|
|
42902
|
+
students: size
|
|
42903
|
+
},
|
|
42904
|
+
session
|
|
42905
|
+
);
|
|
42906
|
+
const skip = totalStudentsProcessed;
|
|
42907
|
+
const learners = await getLeanerByGradeLevel(
|
|
42908
|
+
{
|
|
42909
|
+
school: value.school,
|
|
42910
|
+
gradeLevel: value.gradeLevel,
|
|
42911
|
+
skip,
|
|
42912
|
+
limit: size
|
|
42913
|
+
},
|
|
42914
|
+
session
|
|
42915
|
+
);
|
|
42916
|
+
if (!learners.length) {
|
|
42917
|
+
throw new BadRequestError64(`No learners found for section #${i + 1}.`);
|
|
42918
|
+
}
|
|
42919
|
+
totalStudentsProcessed += learners.length;
|
|
42920
|
+
for (const student of learners) {
|
|
42921
|
+
if (!student._id) {
|
|
42922
|
+
throw new BadRequestError64("Learner ID is missing.");
|
|
42923
|
+
}
|
|
42924
|
+
if (!student.learnerInfo.lrn) {
|
|
42925
|
+
throw new BadRequestError64("Learner LRN is missing.");
|
|
42926
|
+
}
|
|
42927
|
+
await assignStudent(
|
|
42928
|
+
{
|
|
42929
|
+
section: section.toString(),
|
|
42930
|
+
lrn: student.learnerInfo.lrn,
|
|
42931
|
+
student: student._id?.toString(),
|
|
42932
|
+
studentName: `${student.learnerInfo.firstName} ${student.learnerInfo.lastName}`,
|
|
42933
|
+
school: value.school,
|
|
42934
|
+
schoolName: schoolData.name,
|
|
42935
|
+
gradeLevel: value.gradeLevel,
|
|
42936
|
+
educationLevel: gradeLevelData.educationLevel,
|
|
42937
|
+
schoolYear: value.schoolYear,
|
|
42938
|
+
status: "active"
|
|
42939
|
+
},
|
|
42940
|
+
session
|
|
42941
|
+
);
|
|
42942
|
+
}
|
|
42943
|
+
const curriculumSubjects = await getAllCurriculumSubjects({
|
|
42944
|
+
schoolYear: Number(value.schoolYear),
|
|
42945
|
+
gradeLevel: value.gradeLevel,
|
|
42946
|
+
limit: 20
|
|
42947
|
+
});
|
|
42948
|
+
for (const curriculumSubject of curriculumSubjects.items) {
|
|
42949
|
+
await addSectionSubject(
|
|
42950
|
+
{
|
|
42951
|
+
curriculum: curriculumSubject.curriculum.toString(),
|
|
42952
|
+
school: value.school,
|
|
42953
|
+
schoolName: schoolData.name,
|
|
42954
|
+
gradeLevel: value.gradeLevel,
|
|
42955
|
+
educationLevel: gradeLevelData.educationLevel,
|
|
42956
|
+
schoolYear: value.schoolYear,
|
|
42957
|
+
section: section.toString(),
|
|
42958
|
+
sectionName,
|
|
42959
|
+
subjectCode: curriculumSubject.subjectCode,
|
|
42960
|
+
subjectName: curriculumSubject.subjectName,
|
|
42961
|
+
teacher: "",
|
|
42962
|
+
teacherName: "",
|
|
42963
|
+
schedule: "",
|
|
42964
|
+
daysOfWeek: [],
|
|
42965
|
+
classroom: "",
|
|
42966
|
+
classroomName: "",
|
|
42967
|
+
sessionDuration: curriculumSubject.sessionDuration,
|
|
42968
|
+
sessionFrequency: curriculumSubject.sessionFrequency,
|
|
42969
|
+
status: "draft"
|
|
42970
|
+
},
|
|
42971
|
+
session
|
|
42972
|
+
);
|
|
42973
|
+
}
|
|
42974
|
+
}
|
|
42975
|
+
let pageTeacher = 1;
|
|
42976
|
+
let pagesTeachers = 1;
|
|
42977
|
+
let teachers = [];
|
|
42978
|
+
do {
|
|
42979
|
+
const teachersData = await getAllPersonnel({
|
|
42980
|
+
school: value.school,
|
|
42981
|
+
limit: 100
|
|
42982
|
+
});
|
|
42983
|
+
pagesTeachers = teachersData.pages;
|
|
42984
|
+
teachers.push(...teachersData.items);
|
|
42985
|
+
pageTeacher++;
|
|
42986
|
+
} while (pageTeacher < pagesTeachers);
|
|
42987
|
+
if (!teachers.length) {
|
|
42988
|
+
throw new BadRequestError64(
|
|
42989
|
+
"Could not proceed, no teaching personnel found."
|
|
42990
|
+
);
|
|
42991
|
+
}
|
|
42992
|
+
if (teachers.length) {
|
|
42993
|
+
for (let index = 0; index < teachers.length; index++) {
|
|
42994
|
+
const teacher = teachers[index];
|
|
42995
|
+
if (!teacher._id) {
|
|
42996
|
+
throw new BadRequestError64("Teacher ID is missing.");
|
|
42997
|
+
}
|
|
42998
|
+
await addTeachingLoad(
|
|
42999
|
+
{
|
|
43000
|
+
school: value.school,
|
|
43001
|
+
schoolName: schoolData.name,
|
|
43002
|
+
schoolYear: value.schoolYear,
|
|
43003
|
+
teacher: teacher._id.toString(),
|
|
43004
|
+
teacherName: `${teacher.firstName} ${teacher.lastName}`,
|
|
43005
|
+
status: "draft"
|
|
43006
|
+
},
|
|
43007
|
+
session
|
|
43008
|
+
);
|
|
43009
|
+
}
|
|
43010
|
+
}
|
|
43011
|
+
await session.commitTransaction();
|
|
43012
|
+
return "Sections generated successfully.";
|
|
42854
43013
|
} catch (error2) {
|
|
42855
|
-
|
|
43014
|
+
await session.abortTransaction();
|
|
43015
|
+
if (error2 instanceof AppError25) {
|
|
43016
|
+
throw error2;
|
|
43017
|
+
} else {
|
|
43018
|
+
throw new InternalServerError21("Failed to generate sections.");
|
|
43019
|
+
}
|
|
43020
|
+
} finally {
|
|
43021
|
+
await session?.endSession();
|
|
42856
43022
|
}
|
|
42857
43023
|
}
|
|
42858
|
-
|
|
43024
|
+
async function generateSectionPreview(value) {
|
|
43025
|
+
const { error } = schemaGenerateSections.validate(value);
|
|
43026
|
+
if (error) {
|
|
43027
|
+
throw new BadRequestError64(
|
|
43028
|
+
`Invalid section generation data: ${error.message}`
|
|
43029
|
+
);
|
|
43030
|
+
}
|
|
42859
43031
|
try {
|
|
42860
|
-
|
|
43032
|
+
const studentCount = await getCountByGradeLevel({
|
|
43033
|
+
school: value.school,
|
|
43034
|
+
schoolYear: value.schoolYear,
|
|
43035
|
+
gradeLevel: value.gradeLevel,
|
|
43036
|
+
specialProgram: value.specialProgram
|
|
43037
|
+
});
|
|
43038
|
+
if (studentCount === 0) {
|
|
43039
|
+
throw new BadRequestError64("No learners found for this grade level.");
|
|
43040
|
+
}
|
|
43041
|
+
const gradeLevelData = await getByGradeLevel({
|
|
43042
|
+
school: value.school,
|
|
43043
|
+
gradeLevel: value.gradeLevel
|
|
43044
|
+
});
|
|
43045
|
+
if (!gradeLevelData) {
|
|
43046
|
+
throw new BadRequestError64("Grade level not found.");
|
|
43047
|
+
}
|
|
43048
|
+
const minPerSection = value.minStudents ?? gradeLevelData.minNumberOfLearners;
|
|
43049
|
+
const maxPerSection = value.maxStudents ?? gradeLevelData.maxNumberOfLearners;
|
|
43050
|
+
const sectionsNeeded = Math.ceil(studentCount / minPerSection);
|
|
43051
|
+
if (sectionsNeeded > value.set.length) {
|
|
43052
|
+
throw new BadRequestError64(
|
|
43053
|
+
"Insufficient number of section names in set[]."
|
|
43054
|
+
);
|
|
43055
|
+
}
|
|
43056
|
+
const sectionSizes = distributeStudents(
|
|
43057
|
+
studentCount,
|
|
43058
|
+
minPerSection,
|
|
43059
|
+
maxPerSection
|
|
43060
|
+
);
|
|
43061
|
+
if (sectionSizes.length === 0) {
|
|
43062
|
+
throw new BadRequestError64("Unable to compute section sizes.");
|
|
43063
|
+
}
|
|
43064
|
+
const sections = sectionSizes.map((size, index) => ({
|
|
43065
|
+
name: value.set[index],
|
|
43066
|
+
value: size
|
|
43067
|
+
}));
|
|
43068
|
+
return {
|
|
43069
|
+
totalSectionsGenerated: sectionSizes.length,
|
|
43070
|
+
totalStudentsAssigned: studentCount,
|
|
43071
|
+
sections
|
|
43072
|
+
};
|
|
42861
43073
|
} catch (error2) {
|
|
42862
|
-
|
|
43074
|
+
if (error2 instanceof AppError25) {
|
|
43075
|
+
throw error2;
|
|
43076
|
+
} else {
|
|
43077
|
+
throw new InternalServerError21("Failed to generate section preview.");
|
|
43078
|
+
}
|
|
42863
43079
|
}
|
|
42864
43080
|
}
|
|
42865
|
-
|
|
43081
|
+
return { generateSections, generateSectionPreview };
|
|
43082
|
+
}
|
|
43083
|
+
|
|
43084
|
+
// src/resources/section/section.controller.ts
|
|
43085
|
+
function useSectionController() {
|
|
43086
|
+
const {
|
|
43087
|
+
add: _add,
|
|
43088
|
+
getAll: _getAll,
|
|
43089
|
+
getById: _getById,
|
|
43090
|
+
getByName: _getByName,
|
|
43091
|
+
getBySchool: _getBySchool,
|
|
43092
|
+
updateFieldById: _updateFieldById,
|
|
43093
|
+
addStudentToSection: _addStudentToSection,
|
|
43094
|
+
removeStudentFromSection: _removeStudentFromSection,
|
|
43095
|
+
deleteById: _deleteById
|
|
43096
|
+
} = useSectionRepo();
|
|
43097
|
+
const {
|
|
43098
|
+
generateSections: _generateSections,
|
|
43099
|
+
generateSectionPreview: _generateSectionPreview
|
|
43100
|
+
} = useSectionService();
|
|
43101
|
+
async function add(req, res, next) {
|
|
43102
|
+
const value = req.body;
|
|
43103
|
+
const { error } = schemaSection.validate(value);
|
|
43104
|
+
if (error) {
|
|
43105
|
+
next(new BadRequestError65(error.message));
|
|
43106
|
+
return;
|
|
43107
|
+
}
|
|
42866
43108
|
try {
|
|
42867
|
-
|
|
43109
|
+
const data = await _add(value);
|
|
43110
|
+
res.json({
|
|
43111
|
+
message: "Successfully created section.",
|
|
43112
|
+
data
|
|
43113
|
+
});
|
|
43114
|
+
return;
|
|
42868
43115
|
} catch (error2) {
|
|
42869
|
-
|
|
43116
|
+
next(error2);
|
|
42870
43117
|
}
|
|
42871
43118
|
}
|
|
42872
|
-
|
|
43119
|
+
async function generateSections(req, res, next) {
|
|
43120
|
+
const value = req.body;
|
|
43121
|
+
const { error } = schemaGenerateSections.validate(value);
|
|
43122
|
+
if (error) {
|
|
43123
|
+
next(new BadRequestError65(error.message));
|
|
43124
|
+
return;
|
|
43125
|
+
}
|
|
42873
43126
|
try {
|
|
42874
|
-
|
|
43127
|
+
const data = await _generateSections(value);
|
|
43128
|
+
res.json({
|
|
43129
|
+
message: "Successfully created section.",
|
|
43130
|
+
data
|
|
43131
|
+
});
|
|
43132
|
+
return;
|
|
42875
43133
|
} catch (error2) {
|
|
42876
|
-
|
|
43134
|
+
next(error2);
|
|
42877
43135
|
}
|
|
42878
43136
|
}
|
|
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() {
|
|
43137
|
+
async function generateSectionPreview(req, res, next) {
|
|
43138
|
+
const value = req.body;
|
|
43139
|
+
const { error } = schemaGenerateSections.validate(value);
|
|
43140
|
+
if (error) {
|
|
43141
|
+
next(new BadRequestError65(error.message));
|
|
43142
|
+
return;
|
|
43143
|
+
}
|
|
42919
43144
|
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.");
|
|
43145
|
+
const data = await _generateSectionPreview(value);
|
|
43146
|
+
res.json(data);
|
|
43147
|
+
return;
|
|
43148
|
+
} catch (error2) {
|
|
43149
|
+
next(error2);
|
|
42936
43150
|
}
|
|
42937
43151
|
}
|
|
42938
|
-
function
|
|
42939
|
-
|
|
42940
|
-
|
|
42941
|
-
|
|
42942
|
-
|
|
42943
|
-
|
|
42944
|
-
|
|
42945
|
-
|
|
42946
|
-
|
|
42947
|
-
|
|
42948
|
-
});
|
|
43152
|
+
async function getAll(req, res, next) {
|
|
43153
|
+
const query = req.query;
|
|
43154
|
+
const validation = Joi43.object({
|
|
43155
|
+
page: Joi43.number().min(1).optional().allow("", null),
|
|
43156
|
+
limit: Joi43.number().min(1).optional().allow("", null),
|
|
43157
|
+
search: Joi43.string().optional().allow("", null),
|
|
43158
|
+
status: Joi43.string().optional().allow("", null),
|
|
43159
|
+
school: Joi43.string().hex().optional().allow("", null),
|
|
43160
|
+
schoolYear: Joi43.string().optional().allow("", null),
|
|
43161
|
+
gradeLevel: Joi43.string().optional().allow("", null)
|
|
42949
43162
|
});
|
|
42950
|
-
|
|
42951
|
-
|
|
43163
|
+
const { error } = validation.validate(query);
|
|
43164
|
+
const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
|
|
43165
|
+
const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
|
|
43166
|
+
const search = req.query.search ?? "";
|
|
43167
|
+
const status = req.query.status ?? "active";
|
|
43168
|
+
const school = req.query.school ?? "";
|
|
43169
|
+
const schoolYear = req.query.schoolYear ?? "";
|
|
43170
|
+
const gradeLevel = req.query.gradeLevel ?? "";
|
|
43171
|
+
const isPageNumber = isFinite(page);
|
|
43172
|
+
if (!isPageNumber) {
|
|
43173
|
+
next(new BadRequestError65("Invalid page number."));
|
|
43174
|
+
return;
|
|
43175
|
+
}
|
|
43176
|
+
const isLimitNumber = isFinite(limit);
|
|
43177
|
+
if (!isLimitNumber) {
|
|
43178
|
+
next(new BadRequestError65("Invalid limit number."));
|
|
43179
|
+
return;
|
|
43180
|
+
}
|
|
43181
|
+
if (error) {
|
|
43182
|
+
next(new BadRequestError65(error.message));
|
|
43183
|
+
return;
|
|
43184
|
+
}
|
|
42952
43185
|
try {
|
|
42953
|
-
|
|
42954
|
-
|
|
42955
|
-
|
|
42956
|
-
|
|
42957
|
-
|
|
42958
|
-
|
|
42959
|
-
|
|
42960
|
-
|
|
43186
|
+
const data = await _getAll({
|
|
43187
|
+
page,
|
|
43188
|
+
limit,
|
|
43189
|
+
search,
|
|
43190
|
+
status,
|
|
43191
|
+
school,
|
|
43192
|
+
schoolYear,
|
|
43193
|
+
gradeLevel
|
|
42961
43194
|
});
|
|
42962
|
-
|
|
42963
|
-
|
|
42964
|
-
|
|
42965
|
-
|
|
42966
|
-
if (isDuplicated) {
|
|
42967
|
-
throw new BadRequestError65("Kinder schedule already exists.");
|
|
42968
|
-
}
|
|
42969
|
-
throw new Error("Failed to create kindergarten routine.");
|
|
42970
|
-
}
|
|
43195
|
+
res.json(data);
|
|
43196
|
+
return;
|
|
43197
|
+
} catch (error2) {
|
|
43198
|
+
next(error2);
|
|
42971
43199
|
}
|
|
42972
43200
|
}
|
|
42973
|
-
async function
|
|
42974
|
-
|
|
42975
|
-
|
|
42976
|
-
|
|
42977
|
-
|
|
42978
|
-
|
|
42979
|
-
|
|
42980
|
-
|
|
42981
|
-
|
|
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;
|
|
43201
|
+
async function getById(req, res, next) {
|
|
43202
|
+
const id = req.params.id;
|
|
43203
|
+
const validation = Joi43.object({
|
|
43204
|
+
id: Joi43.string().hex().required()
|
|
43205
|
+
});
|
|
43206
|
+
const { error } = validation.validate({ id });
|
|
43207
|
+
if (error) {
|
|
43208
|
+
next(new BadRequestError65(error.message));
|
|
43209
|
+
return;
|
|
43004
43210
|
}
|
|
43005
|
-
|
|
43006
|
-
|
|
43007
|
-
|
|
43211
|
+
try {
|
|
43212
|
+
const data = await _getById(id);
|
|
43213
|
+
res.json(data);
|
|
43214
|
+
return;
|
|
43215
|
+
} catch (error2) {
|
|
43216
|
+
next(error2);
|
|
43008
43217
|
}
|
|
43009
|
-
|
|
43010
|
-
|
|
43011
|
-
|
|
43012
|
-
|
|
43013
|
-
|
|
43014
|
-
|
|
43015
|
-
|
|
43218
|
+
}
|
|
43219
|
+
async function getByName(req, res, next) {
|
|
43220
|
+
const name = req.params.name;
|
|
43221
|
+
const validation = Joi43.object({
|
|
43222
|
+
name: Joi43.string().required()
|
|
43223
|
+
});
|
|
43224
|
+
const { error } = validation.validate({ name });
|
|
43225
|
+
if (error) {
|
|
43226
|
+
next(new BadRequestError65(error.message));
|
|
43227
|
+
return;
|
|
43016
43228
|
}
|
|
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
43229
|
try {
|
|
43043
|
-
const
|
|
43044
|
-
|
|
43045
|
-
|
|
43046
|
-
|
|
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
|
-
});
|
|
43230
|
+
const data = await _getByName(name);
|
|
43231
|
+
res.json({
|
|
43232
|
+
message: "Successfully retrieved section.",
|
|
43233
|
+
data
|
|
43069
43234
|
});
|
|
43070
|
-
return
|
|
43071
|
-
} catch (
|
|
43072
|
-
|
|
43073
|
-
throw error;
|
|
43235
|
+
return;
|
|
43236
|
+
} catch (error2) {
|
|
43237
|
+
next(error2);
|
|
43074
43238
|
}
|
|
43075
43239
|
}
|
|
43076
|
-
async function
|
|
43077
|
-
|
|
43078
|
-
|
|
43079
|
-
|
|
43080
|
-
|
|
43240
|
+
async function getBySchool(req, res, next) {
|
|
43241
|
+
const school = req.params.school;
|
|
43242
|
+
const validation = Joi43.object({
|
|
43243
|
+
school: Joi43.string().hex().required()
|
|
43244
|
+
});
|
|
43245
|
+
const { error } = validation.validate({ school });
|
|
43246
|
+
if (error) {
|
|
43247
|
+
next(new BadRequestError65(error.message));
|
|
43248
|
+
return;
|
|
43081
43249
|
}
|
|
43082
|
-
const cacheKey = makeCacheKey22(namespace_collection, { _id: String(_id) });
|
|
43083
43250
|
try {
|
|
43084
|
-
const
|
|
43085
|
-
|
|
43086
|
-
|
|
43087
|
-
|
|
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
|
-
});
|
|
43251
|
+
const data = await _getBySchool(school);
|
|
43252
|
+
res.json({
|
|
43253
|
+
message: "Successfully retrieved sections.",
|
|
43254
|
+
data
|
|
43106
43255
|
});
|
|
43107
|
-
return
|
|
43108
|
-
} catch (
|
|
43109
|
-
|
|
43110
|
-
throw error;
|
|
43111
|
-
} else {
|
|
43112
|
-
throw new InternalServerError21("Failed to get kindergarten routine.");
|
|
43113
|
-
}
|
|
43256
|
+
return;
|
|
43257
|
+
} catch (error2) {
|
|
43258
|
+
next(error2);
|
|
43114
43259
|
}
|
|
43115
43260
|
}
|
|
43116
|
-
async function
|
|
43117
|
-
const
|
|
43118
|
-
|
|
43119
|
-
|
|
43261
|
+
async function updateField(req, res, next) {
|
|
43262
|
+
const _id = req.params.id;
|
|
43263
|
+
const { field, value } = req.body;
|
|
43264
|
+
const validation = Joi43.object({
|
|
43265
|
+
_id: Joi43.string().hex().required(),
|
|
43266
|
+
field: Joi43.string().valid("name", "schoolYear", "gradeLevel", "adviser", "adviserName").required(),
|
|
43267
|
+
value: Joi43.string().required()
|
|
43120
43268
|
});
|
|
43121
|
-
|
|
43122
|
-
|
|
43123
|
-
|
|
43124
|
-
|
|
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.");
|
|
43269
|
+
const { error } = validation.validate({ _id, field, value });
|
|
43270
|
+
if (error) {
|
|
43271
|
+
next(new BadRequestError65(error.message));
|
|
43272
|
+
return;
|
|
43159
43273
|
}
|
|
43160
|
-
const cacheKey = makeCacheKey22(namespace_collection, {
|
|
43161
|
-
section: String(section)
|
|
43162
|
-
});
|
|
43163
43274
|
try {
|
|
43164
|
-
const
|
|
43165
|
-
|
|
43166
|
-
|
|
43167
|
-
|
|
43168
|
-
|
|
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
|
-
}
|
|
43275
|
+
const message = await _updateFieldById({ _id, field, value });
|
|
43276
|
+
res.json({ message });
|
|
43277
|
+
return;
|
|
43278
|
+
} catch (error2) {
|
|
43279
|
+
next(error2);
|
|
43194
43280
|
}
|
|
43195
43281
|
}
|
|
43196
|
-
async function
|
|
43197
|
-
const
|
|
43198
|
-
|
|
43199
|
-
|
|
43200
|
-
|
|
43201
|
-
|
|
43202
|
-
|
|
43203
|
-
|
|
43204
|
-
if (
|
|
43205
|
-
|
|
43206
|
-
|
|
43207
|
-
);
|
|
43208
|
-
}
|
|
43209
|
-
try {
|
|
43210
|
-
_id = new ObjectId42(_id);
|
|
43211
|
-
} catch (error) {
|
|
43212
|
-
throw new BadRequestError65(namespace_collection + " Invalid ID.");
|
|
43282
|
+
async function addStudent(req, res, next) {
|
|
43283
|
+
const _id = req.params.id;
|
|
43284
|
+
const { studentId } = req.body;
|
|
43285
|
+
const validation = Joi43.object({
|
|
43286
|
+
_id: Joi43.string().hex().required(),
|
|
43287
|
+
studentId: Joi43.string().required()
|
|
43288
|
+
});
|
|
43289
|
+
const { error } = validation.validate({ _id, studentId });
|
|
43290
|
+
if (error) {
|
|
43291
|
+
next(new BadRequestError65(error.message));
|
|
43292
|
+
return;
|
|
43213
43293
|
}
|
|
43214
43294
|
try {
|
|
43215
|
-
await
|
|
43216
|
-
|
|
43217
|
-
|
|
43218
|
-
|
|
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
|
-
);
|
|
43295
|
+
const message = await _addStudentToSection(_id, studentId);
|
|
43296
|
+
res.json({ message });
|
|
43297
|
+
return;
|
|
43298
|
+
} catch (error2) {
|
|
43299
|
+
next(error2);
|
|
43226
43300
|
}
|
|
43227
43301
|
}
|
|
43228
|
-
async function
|
|
43229
|
-
const
|
|
43302
|
+
async function removeStudent(req, res, next) {
|
|
43303
|
+
const _id = req.params.id;
|
|
43304
|
+
const { studentId } = req.body;
|
|
43305
|
+
const validation = Joi43.object({
|
|
43306
|
+
_id: Joi43.string().hex().required(),
|
|
43307
|
+
studentId: Joi43.string().required()
|
|
43308
|
+
});
|
|
43309
|
+
const { error } = validation.validate({ _id, studentId });
|
|
43230
43310
|
if (error) {
|
|
43231
|
-
|
|
43232
|
-
|
|
43233
|
-
);
|
|
43234
|
-
}
|
|
43235
|
-
try {
|
|
43236
|
-
_id = new ObjectId42(_id);
|
|
43237
|
-
} catch (error2) {
|
|
43238
|
-
throw new BadRequestError65(namespace_collection + " Invalid ID.");
|
|
43311
|
+
next(new BadRequestError65(error.message));
|
|
43312
|
+
return;
|
|
43239
43313
|
}
|
|
43240
43314
|
try {
|
|
43241
|
-
await
|
|
43242
|
-
|
|
43243
|
-
|
|
43244
|
-
{ session }
|
|
43245
|
-
);
|
|
43246
|
-
delCachedData();
|
|
43247
|
-
return `Successfully updated kindergarten routine.`;
|
|
43315
|
+
const message = await _removeStudentFromSection(_id, studentId);
|
|
43316
|
+
res.json({ message });
|
|
43317
|
+
return;
|
|
43248
43318
|
} catch (error2) {
|
|
43249
|
-
|
|
43319
|
+
next(error2);
|
|
43250
43320
|
}
|
|
43251
43321
|
}
|
|
43252
|
-
async function deleteById(
|
|
43253
|
-
|
|
43254
|
-
|
|
43255
|
-
|
|
43256
|
-
|
|
43322
|
+
async function deleteById(req, res, next) {
|
|
43323
|
+
const _id = req.params.id;
|
|
43324
|
+
const validation = Joi43.object({
|
|
43325
|
+
_id: Joi43.string().hex().required()
|
|
43326
|
+
});
|
|
43327
|
+
const { error } = validation.validate({ _id });
|
|
43328
|
+
if (error) {
|
|
43329
|
+
next(new BadRequestError65(error.message));
|
|
43330
|
+
return;
|
|
43257
43331
|
}
|
|
43258
43332
|
try {
|
|
43259
|
-
await
|
|
43260
|
-
|
|
43261
|
-
|
|
43262
|
-
|
|
43263
|
-
|
|
43264
|
-
return "Successfully deleted kindergarten routine.";
|
|
43265
|
-
} catch (error) {
|
|
43266
|
-
throw new InternalServerError21("Failed to delete kindergarten routine.");
|
|
43333
|
+
const message = await _deleteById(_id);
|
|
43334
|
+
res.json({ message });
|
|
43335
|
+
return;
|
|
43336
|
+
} catch (error2) {
|
|
43337
|
+
next(error2);
|
|
43267
43338
|
}
|
|
43268
43339
|
}
|
|
43269
43340
|
return {
|
|
43270
|
-
createIndexes,
|
|
43271
43341
|
add,
|
|
43342
|
+
generateSections,
|
|
43343
|
+
generateSectionPreview,
|
|
43272
43344
|
getAll,
|
|
43273
43345
|
getById,
|
|
43274
|
-
|
|
43275
|
-
|
|
43276
|
-
|
|
43277
|
-
|
|
43346
|
+
getByName,
|
|
43347
|
+
getBySchool,
|
|
43348
|
+
updateField,
|
|
43349
|
+
addStudent,
|
|
43350
|
+
removeStudent,
|
|
43278
43351
|
deleteById
|
|
43279
43352
|
};
|
|
43280
43353
|
}
|
|
43281
43354
|
|
|
43282
|
-
// src/resources/
|
|
43355
|
+
// src/resources/section-student/section.student.controller.ts
|
|
43283
43356
|
import { BadRequestError as BadRequestError66 } from "@eeplatform/nodejs-utils";
|
|
43284
43357
|
import Joi44 from "joi";
|
|
43285
|
-
function
|
|
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();
|
|
43358
|
+
function useSectionStudentController() {
|
|
43359
|
+
const { add: _add, getAll: _getAll } = useSectionStudentRepo();
|
|
43295
43360
|
async function add(req, res, next) {
|
|
43296
43361
|
const value = req.body;
|
|
43297
|
-
const { error } =
|
|
43362
|
+
const { error } = schemaSectionStudent.validate(value);
|
|
43298
43363
|
if (error) {
|
|
43299
43364
|
next(new BadRequestError66(error.message));
|
|
43300
43365
|
return;
|
|
@@ -43302,7 +43367,7 @@ function useKindergartenRoutineController() {
|
|
|
43302
43367
|
try {
|
|
43303
43368
|
const data = await _add(value);
|
|
43304
43369
|
res.json({
|
|
43305
|
-
message: "Successfully created
|
|
43370
|
+
message: "Successfully created section student.",
|
|
43306
43371
|
data
|
|
43307
43372
|
});
|
|
43308
43373
|
return;
|
|
@@ -43317,11 +43382,10 @@ function useKindergartenRoutineController() {
|
|
|
43317
43382
|
limit: Joi44.number().min(1).optional().allow("", null),
|
|
43318
43383
|
search: Joi44.string().optional().allow("", null),
|
|
43319
43384
|
status: Joi44.string().optional().allow("", null),
|
|
43320
|
-
school: Joi44.string().
|
|
43321
|
-
|
|
43322
|
-
|
|
43323
|
-
|
|
43324
|
-
createdBy: Joi44.string().hex().optional().allow("", null)
|
|
43385
|
+
school: Joi44.string().optional().allow("", null),
|
|
43386
|
+
gradeLevel: Joi44.string().optional().allow("", null),
|
|
43387
|
+
section: Joi44.string().optional().allow("", null),
|
|
43388
|
+
schoolYear: Joi44.string().optional().allow("", null)
|
|
43325
43389
|
});
|
|
43326
43390
|
const { error } = validation.validate(query);
|
|
43327
43391
|
const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
|
|
@@ -43329,10 +43393,9 @@ function useKindergartenRoutineController() {
|
|
|
43329
43393
|
const search = req.query.search ?? "";
|
|
43330
43394
|
const status = req.query.status ?? "active";
|
|
43331
43395
|
const school = req.query.school ?? "";
|
|
43396
|
+
const gradeLevel = req.query.gradeLevel ?? "";
|
|
43332
43397
|
const section = req.query.section ?? "";
|
|
43333
|
-
const
|
|
43334
|
-
const type = req.query.type ?? "";
|
|
43335
|
-
const createdBy = req.query.createdBy ?? "";
|
|
43398
|
+
const schoolYear = req.query.schoolYear ?? "";
|
|
43336
43399
|
const isPageNumber = isFinite(page);
|
|
43337
43400
|
if (!isPageNumber) {
|
|
43338
43401
|
next(new BadRequestError66("Invalid page number."));
|
|
@@ -43354,10 +43417,9 @@ function useKindergartenRoutineController() {
|
|
|
43354
43417
|
search,
|
|
43355
43418
|
status,
|
|
43356
43419
|
school,
|
|
43420
|
+
gradeLevel,
|
|
43357
43421
|
section,
|
|
43358
|
-
|
|
43359
|
-
type,
|
|
43360
|
-
createdBy: createdBy || void 0
|
|
43422
|
+
schoolYear
|
|
43361
43423
|
});
|
|
43362
43424
|
res.json(data);
|
|
43363
43425
|
return;
|
|
@@ -43365,490 +43427,895 @@ function useKindergartenRoutineController() {
|
|
|
43365
43427
|
next(error2);
|
|
43366
43428
|
}
|
|
43367
43429
|
}
|
|
43368
|
-
|
|
43369
|
-
|
|
43370
|
-
|
|
43371
|
-
|
|
43372
|
-
|
|
43373
|
-
|
|
43374
|
-
|
|
43375
|
-
|
|
43376
|
-
|
|
43377
|
-
|
|
43430
|
+
return {
|
|
43431
|
+
add,
|
|
43432
|
+
getAll
|
|
43433
|
+
};
|
|
43434
|
+
}
|
|
43435
|
+
|
|
43436
|
+
// src/resources/building/building.model.ts
|
|
43437
|
+
import { BadRequestError as BadRequestError67, logger as logger39 } from "@eeplatform/nodejs-utils";
|
|
43438
|
+
import Joi45 from "joi";
|
|
43439
|
+
import { ObjectId as ObjectId41 } from "mongodb";
|
|
43440
|
+
var schemaBuilding = Joi45.object({
|
|
43441
|
+
_id: Joi45.string().hex().optional(),
|
|
43442
|
+
school: Joi45.string().hex().required(),
|
|
43443
|
+
serial: Joi45.string().optional().allow("", null),
|
|
43444
|
+
name: Joi45.string().required(),
|
|
43445
|
+
levels: Joi45.number().integer().min(1).required(),
|
|
43446
|
+
createdAt: Joi45.date().optional().allow("", null),
|
|
43447
|
+
updatedAt: Joi45.date().optional().allow("", null),
|
|
43448
|
+
deletedAt: Joi45.date().optional().allow("", null),
|
|
43449
|
+
status: Joi45.string().optional().allow("", null)
|
|
43450
|
+
});
|
|
43451
|
+
var schemaBuildingUnit = Joi45.object({
|
|
43452
|
+
_id: Joi45.string().hex().optional(),
|
|
43453
|
+
school: Joi45.string().hex().required(),
|
|
43454
|
+
name: Joi45.string().optional().allow("", null),
|
|
43455
|
+
building: Joi45.string().hex().required(),
|
|
43456
|
+
buildingName: Joi45.string().optional().allow("", null),
|
|
43457
|
+
level: Joi45.number().integer().min(1).required(),
|
|
43458
|
+
category: Joi45.string().required(),
|
|
43459
|
+
type: Joi45.string().required(),
|
|
43460
|
+
seating_capacity: Joi45.number().integer().min(0).required(),
|
|
43461
|
+
standing_capacity: Joi45.number().integer().min(0).required(),
|
|
43462
|
+
description: Joi45.string().optional().allow("", null),
|
|
43463
|
+
unit_of_measurement: Joi45.string().valid("sqm").required(),
|
|
43464
|
+
area: Joi45.number().positive().required(),
|
|
43465
|
+
status: Joi45.string().optional().allow("", null)
|
|
43466
|
+
});
|
|
43467
|
+
var schemaUpdateOptions = Joi45.object({
|
|
43468
|
+
name: Joi45.string().optional().allow("", null),
|
|
43469
|
+
building: Joi45.string().hex().optional().allow("", null),
|
|
43470
|
+
buildingName: Joi45.string().optional().allow("", null),
|
|
43471
|
+
level: Joi45.number().integer().min(1).optional().allow("", null),
|
|
43472
|
+
category: Joi45.string().optional().allow("", null),
|
|
43473
|
+
type: Joi45.string().optional().allow("", null),
|
|
43474
|
+
seating_capacity: Joi45.number().integer().min(0).optional().allow("", null),
|
|
43475
|
+
standing_capacity: Joi45.number().integer().min(0).optional().allow("", null),
|
|
43476
|
+
area: Joi45.number().positive().optional().allow("", null)
|
|
43477
|
+
});
|
|
43478
|
+
function MBuilding(value) {
|
|
43479
|
+
const { error } = schemaBuilding.validate(value);
|
|
43480
|
+
if (error) {
|
|
43481
|
+
logger39.info(`Building Model: ${error.message}`);
|
|
43482
|
+
throw new BadRequestError67(error.message);
|
|
43483
|
+
}
|
|
43484
|
+
if (value._id && typeof value._id === "string") {
|
|
43378
43485
|
try {
|
|
43379
|
-
|
|
43380
|
-
res.json({
|
|
43381
|
-
message: "Successfully retrieved kinder schedule.",
|
|
43382
|
-
data
|
|
43383
|
-
});
|
|
43384
|
-
return;
|
|
43486
|
+
value._id = new ObjectId41(value._id);
|
|
43385
43487
|
} catch (error2) {
|
|
43386
|
-
|
|
43488
|
+
throw new BadRequestError67("Invalid _id format");
|
|
43387
43489
|
}
|
|
43388
43490
|
}
|
|
43389
|
-
|
|
43390
|
-
|
|
43391
|
-
|
|
43392
|
-
|
|
43393
|
-
|
|
43394
|
-
|
|
43395
|
-
|
|
43396
|
-
|
|
43397
|
-
|
|
43398
|
-
|
|
43491
|
+
try {
|
|
43492
|
+
value.school = new ObjectId41(value.school);
|
|
43493
|
+
} catch (error2) {
|
|
43494
|
+
throw new BadRequestError67("Invalid school format");
|
|
43495
|
+
}
|
|
43496
|
+
return {
|
|
43497
|
+
_id: value._id ?? void 0,
|
|
43498
|
+
school: value.school,
|
|
43499
|
+
serial: value.serial ?? "",
|
|
43500
|
+
name: value.name ?? "",
|
|
43501
|
+
levels: value.levels ?? 0,
|
|
43502
|
+
status: value.status ?? "active",
|
|
43503
|
+
createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
|
|
43504
|
+
updatedAt: value.updatedAt ?? "",
|
|
43505
|
+
deletedAt: value.deletedAt ?? ""
|
|
43506
|
+
};
|
|
43507
|
+
}
|
|
43508
|
+
function MBuildingUnit(value) {
|
|
43509
|
+
const { error } = schemaBuildingUnit.validate(value);
|
|
43510
|
+
if (error) {
|
|
43511
|
+
logger39.info(`Building Unit Model: ${error.message}`);
|
|
43512
|
+
throw new BadRequestError67(error.message);
|
|
43513
|
+
}
|
|
43514
|
+
if (value._id && typeof value._id === "string") {
|
|
43399
43515
|
try {
|
|
43400
|
-
|
|
43401
|
-
res.json({
|
|
43402
|
-
message: "Successfully retrieved kinder schedules.",
|
|
43403
|
-
data
|
|
43404
|
-
});
|
|
43405
|
-
return;
|
|
43516
|
+
value._id = new ObjectId41(value._id);
|
|
43406
43517
|
} catch (error2) {
|
|
43407
|
-
|
|
43518
|
+
throw new BadRequestError67("Invalid ID");
|
|
43408
43519
|
}
|
|
43409
43520
|
}
|
|
43410
|
-
|
|
43411
|
-
|
|
43412
|
-
|
|
43413
|
-
|
|
43414
|
-
|
|
43415
|
-
|
|
43416
|
-
|
|
43417
|
-
|
|
43418
|
-
|
|
43419
|
-
|
|
43420
|
-
|
|
43421
|
-
|
|
43422
|
-
|
|
43521
|
+
try {
|
|
43522
|
+
value.school = new ObjectId41(value.school);
|
|
43523
|
+
} catch (error2) {
|
|
43524
|
+
throw new BadRequestError67("Invalid school ID");
|
|
43525
|
+
}
|
|
43526
|
+
try {
|
|
43527
|
+
value.building = new ObjectId41(value.building);
|
|
43528
|
+
} catch (error2) {
|
|
43529
|
+
throw new BadRequestError67("Invalid building ID");
|
|
43530
|
+
}
|
|
43531
|
+
return {
|
|
43532
|
+
_id: value._id ?? void 0,
|
|
43533
|
+
school: value.school,
|
|
43534
|
+
name: value.name ?? "",
|
|
43535
|
+
building: value.building,
|
|
43536
|
+
buildingName: value.buildingName ?? "",
|
|
43537
|
+
level: value.level ?? 0,
|
|
43538
|
+
category: value.category ?? "",
|
|
43539
|
+
type: value.type ?? "",
|
|
43540
|
+
seating_capacity: value.seating_capacity ?? 0,
|
|
43541
|
+
standing_capacity: value.standing_capacity ?? 0,
|
|
43542
|
+
description: value.description ?? "",
|
|
43543
|
+
unit_of_measurement: value.unit_of_measurement ?? "sqm",
|
|
43544
|
+
area: value.area ?? 0,
|
|
43545
|
+
status: value.status ?? "active",
|
|
43546
|
+
createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
|
|
43547
|
+
updatedAt: value.updatedAt ?? "",
|
|
43548
|
+
deletedAt: value.deletedAt ?? ""
|
|
43549
|
+
};
|
|
43550
|
+
}
|
|
43551
|
+
|
|
43552
|
+
// src/resources/building/building.repository.ts
|
|
43553
|
+
import {
|
|
43554
|
+
AppError as AppError26,
|
|
43555
|
+
BadRequestError as BadRequestError68,
|
|
43556
|
+
InternalServerError as InternalServerError22,
|
|
43557
|
+
logger as logger40,
|
|
43558
|
+
makeCacheKey as makeCacheKey22,
|
|
43559
|
+
paginate as paginate21,
|
|
43560
|
+
useAtlas as useAtlas31,
|
|
43561
|
+
useCache as useCache22
|
|
43562
|
+
} from "@eeplatform/nodejs-utils";
|
|
43563
|
+
import { ObjectId as ObjectId42 } from "mongodb";
|
|
43564
|
+
function useBuildingRepo() {
|
|
43565
|
+
const db = useAtlas31.getDb();
|
|
43566
|
+
if (!db) {
|
|
43567
|
+
throw new Error("Unable to connect to server.");
|
|
43568
|
+
}
|
|
43569
|
+
const namespace_collection = "deped.buildings";
|
|
43570
|
+
const collection = db.collection(namespace_collection);
|
|
43571
|
+
const { getCache, setCache, delNamespace } = useCache22(namespace_collection);
|
|
43572
|
+
async function createIndexes() {
|
|
43423
43573
|
try {
|
|
43424
|
-
|
|
43425
|
-
|
|
43426
|
-
|
|
43427
|
-
|
|
43428
|
-
|
|
43574
|
+
await collection.createIndexes([
|
|
43575
|
+
{ key: { name: 1 }, unique: true, name: "unique_name_index" },
|
|
43576
|
+
{ key: { school: 1 } },
|
|
43577
|
+
{ key: { status: 1 } }
|
|
43578
|
+
]);
|
|
43579
|
+
} catch (error) {
|
|
43580
|
+
throw new Error("Failed to create index on buildings.");
|
|
43429
43581
|
}
|
|
43430
43582
|
}
|
|
43431
|
-
async function
|
|
43432
|
-
const _id = req.params.id;
|
|
43433
|
-
const payload = req.body;
|
|
43434
|
-
const { error: errorId } = Joi44.string().hex().required().validate(_id);
|
|
43435
|
-
if (errorId) {
|
|
43436
|
-
next(new BadRequestError66(errorId.message));
|
|
43437
|
-
return;
|
|
43438
|
-
}
|
|
43439
|
-
const { error } = schemaKindergartenRoutineUpdate.validate(payload);
|
|
43440
|
-
if (error) {
|
|
43441
|
-
next(new BadRequestError66(error.message));
|
|
43442
|
-
return;
|
|
43443
|
-
}
|
|
43583
|
+
async function add(value, session) {
|
|
43444
43584
|
try {
|
|
43445
|
-
|
|
43446
|
-
res.
|
|
43447
|
-
|
|
43448
|
-
|
|
43449
|
-
|
|
43585
|
+
value = MBuilding(value);
|
|
43586
|
+
const res = await collection.insertOne(value, { session });
|
|
43587
|
+
delCachedData();
|
|
43588
|
+
return res.insertedId;
|
|
43589
|
+
} catch (error) {
|
|
43590
|
+
logger40.log({
|
|
43591
|
+
level: "error",
|
|
43592
|
+
message: error.message
|
|
43593
|
+
});
|
|
43594
|
+
if (error instanceof AppError26) {
|
|
43595
|
+
throw error;
|
|
43596
|
+
} else {
|
|
43597
|
+
const isDuplicated = error.message.includes("duplicate");
|
|
43598
|
+
if (isDuplicated) {
|
|
43599
|
+
throw new BadRequestError68("Building already exists.");
|
|
43600
|
+
}
|
|
43601
|
+
throw new Error("Failed to create building.");
|
|
43602
|
+
}
|
|
43450
43603
|
}
|
|
43451
43604
|
}
|
|
43452
|
-
async function
|
|
43453
|
-
|
|
43454
|
-
|
|
43455
|
-
|
|
43456
|
-
|
|
43457
|
-
const { error } = validation.validate({ _id });
|
|
43458
|
-
if (error) {
|
|
43459
|
-
next(new BadRequestError66(error.message));
|
|
43460
|
-
return;
|
|
43605
|
+
async function updateById(_id, value, session) {
|
|
43606
|
+
try {
|
|
43607
|
+
_id = new ObjectId42(_id);
|
|
43608
|
+
} catch (error) {
|
|
43609
|
+
throw new BadRequestError68(namespace_collection + " Invalid ID.");
|
|
43461
43610
|
}
|
|
43462
43611
|
try {
|
|
43463
|
-
const
|
|
43464
|
-
|
|
43465
|
-
|
|
43466
|
-
|
|
43467
|
-
|
|
43612
|
+
const res = await collection.updateOne(
|
|
43613
|
+
{ _id },
|
|
43614
|
+
{ $set: value },
|
|
43615
|
+
{ session }
|
|
43616
|
+
);
|
|
43617
|
+
delCachedData();
|
|
43618
|
+
return res;
|
|
43619
|
+
} catch (error) {
|
|
43620
|
+
logger40.log({
|
|
43621
|
+
level: "error",
|
|
43622
|
+
message: error.message
|
|
43623
|
+
});
|
|
43624
|
+
if (error instanceof AppError26) {
|
|
43625
|
+
throw error;
|
|
43626
|
+
} else {
|
|
43627
|
+
throw new Error("Failed to update building.");
|
|
43628
|
+
}
|
|
43468
43629
|
}
|
|
43469
43630
|
}
|
|
43470
|
-
|
|
43471
|
-
|
|
43472
|
-
|
|
43473
|
-
|
|
43474
|
-
|
|
43475
|
-
|
|
43476
|
-
|
|
43477
|
-
|
|
43478
|
-
|
|
43479
|
-
|
|
43480
|
-
|
|
43481
|
-
|
|
43482
|
-
|
|
43483
|
-
|
|
43484
|
-
|
|
43485
|
-
const { add: createSection } = useSectionRepo();
|
|
43486
|
-
const { add: assignStudent } = useSectionStudentRepo();
|
|
43487
|
-
const { getAll: getAllCurriculumSubjects } = useSubjectRepo();
|
|
43488
|
-
const { add: addSectionSubject } = useSectionSubjectRepo();
|
|
43489
|
-
const { getById: getSchoolById } = useSchoolRepo();
|
|
43490
|
-
const { getAll: getAllPersonnel } = usePersonnelRepo();
|
|
43491
|
-
const { add: addTeachingLoad } = useTeachingLoadRepo();
|
|
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
|
-
);
|
|
43502
|
-
}
|
|
43503
|
-
const minSections = Math.ceil(total / maxPer);
|
|
43504
|
-
const maxSections = Math.floor(total / minPer);
|
|
43505
|
-
let sectionCount;
|
|
43506
|
-
if (minSections <= maxSections) {
|
|
43507
|
-
sectionCount = minSections;
|
|
43508
|
-
} else {
|
|
43509
|
-
sectionCount = minSections;
|
|
43631
|
+
async function getAll({
|
|
43632
|
+
search = "",
|
|
43633
|
+
page = 1,
|
|
43634
|
+
limit = 10,
|
|
43635
|
+
sort = {},
|
|
43636
|
+
school = "",
|
|
43637
|
+
status = "active"
|
|
43638
|
+
} = {}) {
|
|
43639
|
+
page = page > 0 ? page - 1 : 0;
|
|
43640
|
+
const query = {
|
|
43641
|
+
status
|
|
43642
|
+
};
|
|
43643
|
+
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
43644
|
+
if (search) {
|
|
43645
|
+
query.$text = { $search: search };
|
|
43510
43646
|
}
|
|
43511
|
-
|
|
43512
|
-
|
|
43513
|
-
|
|
43514
|
-
|
|
43515
|
-
|
|
43647
|
+
if (school) {
|
|
43648
|
+
try {
|
|
43649
|
+
query.school = new ObjectId42(school);
|
|
43650
|
+
} catch (error) {
|
|
43651
|
+
throw new BadRequestError68("Invalid school ID.");
|
|
43652
|
+
}
|
|
43516
43653
|
}
|
|
43517
|
-
|
|
43518
|
-
|
|
43519
|
-
|
|
43520
|
-
|
|
43521
|
-
|
|
43654
|
+
const cacheParams = {
|
|
43655
|
+
page,
|
|
43656
|
+
limit,
|
|
43657
|
+
sort: JSON.stringify(sort)
|
|
43658
|
+
};
|
|
43659
|
+
if (search)
|
|
43660
|
+
cacheParams.search = search;
|
|
43661
|
+
if (school)
|
|
43662
|
+
cacheParams.school = school;
|
|
43663
|
+
if (status !== "active")
|
|
43664
|
+
cacheParams.status = status;
|
|
43665
|
+
const cacheKey = makeCacheKey22(namespace_collection, cacheParams);
|
|
43666
|
+
logger40.log({
|
|
43667
|
+
level: "info",
|
|
43668
|
+
message: `Cache key for getAll buildings: ${cacheKey}`
|
|
43669
|
+
});
|
|
43670
|
+
try {
|
|
43671
|
+
const cached = await getCache(cacheKey);
|
|
43672
|
+
if (cached) {
|
|
43673
|
+
logger40.log({
|
|
43674
|
+
level: "info",
|
|
43675
|
+
message: `Cache hit for getAll buildings: ${cacheKey}`
|
|
43676
|
+
});
|
|
43677
|
+
return cached;
|
|
43522
43678
|
}
|
|
43679
|
+
const items = await collection.aggregate([
|
|
43680
|
+
{ $match: query },
|
|
43681
|
+
{ $sort: sort },
|
|
43682
|
+
{ $skip: page * limit },
|
|
43683
|
+
{ $limit: limit }
|
|
43684
|
+
]).toArray();
|
|
43685
|
+
const length = await collection.countDocuments(query);
|
|
43686
|
+
const data = paginate21(items, page, limit, length);
|
|
43687
|
+
setCache(cacheKey, data, 600).then(() => {
|
|
43688
|
+
logger40.log({
|
|
43689
|
+
level: "info",
|
|
43690
|
+
message: `Cache set for getAll buildings: ${cacheKey}`
|
|
43691
|
+
});
|
|
43692
|
+
}).catch((err) => {
|
|
43693
|
+
logger40.log({
|
|
43694
|
+
level: "error",
|
|
43695
|
+
message: `Failed to set cache for getAll buildings: ${err.message}`
|
|
43696
|
+
});
|
|
43697
|
+
});
|
|
43698
|
+
return data;
|
|
43699
|
+
} catch (error) {
|
|
43700
|
+
logger40.log({ level: "error", message: `${error}` });
|
|
43701
|
+
throw error;
|
|
43523
43702
|
}
|
|
43524
|
-
return sizes;
|
|
43525
43703
|
}
|
|
43526
|
-
async function
|
|
43527
|
-
|
|
43528
|
-
|
|
43529
|
-
|
|
43530
|
-
|
|
43531
|
-
);
|
|
43532
|
-
}
|
|
43533
|
-
const session = useAtlas31.getClient()?.startSession();
|
|
43534
|
-
if (!session) {
|
|
43535
|
-
throw new Error("Unable to start database session.");
|
|
43704
|
+
async function getById(_id) {
|
|
43705
|
+
try {
|
|
43706
|
+
_id = new ObjectId42(_id);
|
|
43707
|
+
} catch (error) {
|
|
43708
|
+
throw new BadRequestError68(namespace_collection + " Invalid ID.");
|
|
43536
43709
|
}
|
|
43710
|
+
const cacheKey = makeCacheKey22(namespace_collection, { _id: String(_id) });
|
|
43537
43711
|
try {
|
|
43538
|
-
await
|
|
43539
|
-
|
|
43540
|
-
|
|
43541
|
-
|
|
43542
|
-
|
|
43543
|
-
|
|
43544
|
-
|
|
43545
|
-
if (!kindergartenRoutine) {
|
|
43546
|
-
throw new BadRequestError67("Kindergarten routine not found.");
|
|
43547
|
-
}
|
|
43712
|
+
const cached = await getCache(cacheKey);
|
|
43713
|
+
if (cached) {
|
|
43714
|
+
logger40.log({
|
|
43715
|
+
level: "info",
|
|
43716
|
+
message: `Cache hit for getById building: ${cacheKey}`
|
|
43717
|
+
});
|
|
43718
|
+
return cached;
|
|
43548
43719
|
}
|
|
43549
|
-
const
|
|
43550
|
-
|
|
43551
|
-
|
|
43552
|
-
|
|
43553
|
-
|
|
43554
|
-
|
|
43555
|
-
|
|
43556
|
-
|
|
43720
|
+
const result = await collection.findOne({
|
|
43721
|
+
_id
|
|
43722
|
+
});
|
|
43723
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
43724
|
+
logger40.log({
|
|
43725
|
+
level: "info",
|
|
43726
|
+
message: `Cache set for building by id: ${cacheKey}`
|
|
43727
|
+
});
|
|
43728
|
+
}).catch((err) => {
|
|
43729
|
+
logger40.log({
|
|
43730
|
+
level: "error",
|
|
43731
|
+
message: `Failed to set cache for building by id: ${err.message}`
|
|
43732
|
+
});
|
|
43733
|
+
});
|
|
43734
|
+
return result;
|
|
43735
|
+
} catch (error) {
|
|
43736
|
+
if (error instanceof AppError26) {
|
|
43737
|
+
throw error;
|
|
43738
|
+
} else {
|
|
43739
|
+
throw new InternalServerError22("Failed to get building.");
|
|
43740
|
+
}
|
|
43741
|
+
}
|
|
43742
|
+
}
|
|
43743
|
+
async function deleteById(_id, session) {
|
|
43744
|
+
try {
|
|
43745
|
+
_id = new ObjectId42(_id);
|
|
43746
|
+
} catch (error) {
|
|
43747
|
+
throw new BadRequestError68(namespace_collection + " Invalid ID.");
|
|
43748
|
+
}
|
|
43749
|
+
try {
|
|
43750
|
+
const res = await collection.updateOne(
|
|
43751
|
+
{ _id },
|
|
43752
|
+
{ $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } }
|
|
43557
43753
|
);
|
|
43558
|
-
|
|
43559
|
-
|
|
43754
|
+
delCachedData();
|
|
43755
|
+
return res;
|
|
43756
|
+
} catch (error) {
|
|
43757
|
+
logger40.log({
|
|
43758
|
+
level: "error",
|
|
43759
|
+
message: error.message
|
|
43760
|
+
});
|
|
43761
|
+
if (error instanceof AppError26) {
|
|
43762
|
+
throw error;
|
|
43763
|
+
} else {
|
|
43764
|
+
throw new InternalServerError22("Failed to delete building.");
|
|
43560
43765
|
}
|
|
43561
|
-
|
|
43766
|
+
}
|
|
43767
|
+
}
|
|
43768
|
+
function delCachedData() {
|
|
43769
|
+
delNamespace().then(() => {
|
|
43770
|
+
logger40.log({
|
|
43771
|
+
level: "info",
|
|
43772
|
+
message: `Cache namespace cleared for ${namespace_collection}`
|
|
43773
|
+
});
|
|
43774
|
+
}).catch((err) => {
|
|
43775
|
+
logger40.log({
|
|
43776
|
+
level: "error",
|
|
43777
|
+
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
43778
|
+
});
|
|
43779
|
+
});
|
|
43780
|
+
}
|
|
43781
|
+
return {
|
|
43782
|
+
createIndexes,
|
|
43783
|
+
add,
|
|
43784
|
+
getAll,
|
|
43785
|
+
getById,
|
|
43786
|
+
updateById,
|
|
43787
|
+
deleteById
|
|
43788
|
+
};
|
|
43789
|
+
}
|
|
43790
|
+
|
|
43791
|
+
// src/resources/building/building.service.ts
|
|
43792
|
+
import {
|
|
43793
|
+
BadRequestError as BadRequestError70,
|
|
43794
|
+
NotFoundError as NotFoundError3,
|
|
43795
|
+
useAtlas as useAtlas33
|
|
43796
|
+
} from "@eeplatform/nodejs-utils";
|
|
43797
|
+
|
|
43798
|
+
// src/resources/building/building-unit.repository.ts
|
|
43799
|
+
import {
|
|
43800
|
+
AppError as AppError27,
|
|
43801
|
+
BadRequestError as BadRequestError69,
|
|
43802
|
+
InternalServerError as InternalServerError23,
|
|
43803
|
+
logger as logger41,
|
|
43804
|
+
makeCacheKey as makeCacheKey23,
|
|
43805
|
+
paginate as paginate22,
|
|
43806
|
+
useAtlas as useAtlas32,
|
|
43807
|
+
useCache as useCache23
|
|
43808
|
+
} from "@eeplatform/nodejs-utils";
|
|
43809
|
+
import { ObjectId as ObjectId43 } from "mongodb";
|
|
43810
|
+
function useBuildingUnitRepo() {
|
|
43811
|
+
const db = useAtlas32.getDb();
|
|
43812
|
+
if (!db) {
|
|
43813
|
+
throw new Error("Unable to connect to server.");
|
|
43814
|
+
}
|
|
43815
|
+
const namespace_collection = "deped.building.units";
|
|
43816
|
+
const collection = db.collection(namespace_collection);
|
|
43817
|
+
const { getCache, setCache, delNamespace } = useCache23(namespace_collection);
|
|
43818
|
+
async function createIndexes() {
|
|
43819
|
+
try {
|
|
43820
|
+
await collection.createIndexes([
|
|
43562
43821
|
{
|
|
43563
|
-
|
|
43564
|
-
|
|
43822
|
+
key: { name: 1, building: 1, level: 1 },
|
|
43823
|
+
unique: true,
|
|
43824
|
+
name: "unique_name_index"
|
|
43565
43825
|
},
|
|
43566
|
-
|
|
43567
|
-
|
|
43568
|
-
|
|
43569
|
-
|
|
43826
|
+
{ key: { school: 1 } },
|
|
43827
|
+
{ key: { building: 1 } },
|
|
43828
|
+
{ key: { status: 1 } },
|
|
43829
|
+
{ key: { createdAt: 1 } },
|
|
43830
|
+
{
|
|
43831
|
+
key: {
|
|
43832
|
+
name: "text",
|
|
43833
|
+
buildingName: "text",
|
|
43834
|
+
category: "text",
|
|
43835
|
+
type: "text"
|
|
43836
|
+
}
|
|
43837
|
+
}
|
|
43838
|
+
]);
|
|
43839
|
+
} catch (error) {
|
|
43840
|
+
throw new Error("Failed to create index on building units.");
|
|
43841
|
+
}
|
|
43842
|
+
}
|
|
43843
|
+
function delCachedData() {
|
|
43844
|
+
delNamespace().then(() => {
|
|
43845
|
+
logger41.log({
|
|
43846
|
+
level: "info",
|
|
43847
|
+
message: `Cache namespace cleared for ${namespace_collection}`
|
|
43848
|
+
});
|
|
43849
|
+
}).catch((err) => {
|
|
43850
|
+
logger41.log({
|
|
43851
|
+
level: "error",
|
|
43852
|
+
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
43853
|
+
});
|
|
43854
|
+
});
|
|
43855
|
+
}
|
|
43856
|
+
async function add(value, session) {
|
|
43857
|
+
try {
|
|
43858
|
+
value = MBuildingUnit(value);
|
|
43859
|
+
const res = await collection.insertOne(value, { session });
|
|
43860
|
+
delCachedData();
|
|
43861
|
+
return res.insertedId;
|
|
43862
|
+
} catch (error) {
|
|
43863
|
+
logger41.log({
|
|
43864
|
+
level: "error",
|
|
43865
|
+
message: error.message
|
|
43866
|
+
});
|
|
43867
|
+
if (error instanceof AppError27) {
|
|
43868
|
+
throw error;
|
|
43869
|
+
} else {
|
|
43870
|
+
throw new Error("Failed to create building unit.");
|
|
43570
43871
|
}
|
|
43571
|
-
|
|
43572
|
-
|
|
43573
|
-
|
|
43574
|
-
|
|
43575
|
-
|
|
43576
|
-
|
|
43577
|
-
|
|
43872
|
+
}
|
|
43873
|
+
}
|
|
43874
|
+
async function updateById(_id, value, session) {
|
|
43875
|
+
const { error } = schemaUpdateOptions.validate(value);
|
|
43876
|
+
if (error) {
|
|
43877
|
+
throw new BadRequestError69(error.message);
|
|
43878
|
+
}
|
|
43879
|
+
try {
|
|
43880
|
+
_id = new ObjectId43(_id);
|
|
43881
|
+
} catch (error2) {
|
|
43882
|
+
throw new BadRequestError69(namespace_collection + " Invalid ID.");
|
|
43883
|
+
}
|
|
43884
|
+
try {
|
|
43885
|
+
const res = await collection.updateOne(
|
|
43886
|
+
{ _id },
|
|
43887
|
+
{ $set: value },
|
|
43888
|
+
{ session }
|
|
43889
|
+
);
|
|
43890
|
+
delCachedData();
|
|
43891
|
+
return res;
|
|
43892
|
+
} catch (error2) {
|
|
43893
|
+
logger41.log({
|
|
43894
|
+
level: "error",
|
|
43895
|
+
message: error2.message
|
|
43896
|
+
});
|
|
43897
|
+
if (error2 instanceof AppError27) {
|
|
43898
|
+
throw error2;
|
|
43899
|
+
} else {
|
|
43900
|
+
throw new Error("Failed to create building unit.");
|
|
43578
43901
|
}
|
|
43579
|
-
|
|
43580
|
-
|
|
43581
|
-
|
|
43582
|
-
|
|
43902
|
+
}
|
|
43903
|
+
}
|
|
43904
|
+
async function updateByBuildingId(building, value, session) {
|
|
43905
|
+
const { error } = schemaUpdateOptions.validate(value);
|
|
43906
|
+
if (error) {
|
|
43907
|
+
throw new BadRequestError69(error.message);
|
|
43908
|
+
}
|
|
43909
|
+
try {
|
|
43910
|
+
building = new ObjectId43(building);
|
|
43911
|
+
} catch (error2) {
|
|
43912
|
+
throw new BadRequestError69("Invalid building ID.");
|
|
43913
|
+
}
|
|
43914
|
+
try {
|
|
43915
|
+
const res = await collection.updateMany(
|
|
43916
|
+
{ building },
|
|
43917
|
+
{ $set: value },
|
|
43918
|
+
{ session }
|
|
43583
43919
|
);
|
|
43584
|
-
|
|
43585
|
-
|
|
43920
|
+
delCachedData();
|
|
43921
|
+
return res;
|
|
43922
|
+
} catch (error2) {
|
|
43923
|
+
logger41.log({
|
|
43924
|
+
level: "error",
|
|
43925
|
+
message: error2.message
|
|
43926
|
+
});
|
|
43927
|
+
if (error2 instanceof AppError27) {
|
|
43928
|
+
throw error2;
|
|
43929
|
+
} else {
|
|
43930
|
+
throw new Error("Failed to update building unit.");
|
|
43586
43931
|
}
|
|
43587
|
-
|
|
43588
|
-
|
|
43589
|
-
|
|
43932
|
+
}
|
|
43933
|
+
}
|
|
43934
|
+
async function getAll({
|
|
43935
|
+
search = "",
|
|
43936
|
+
page = 1,
|
|
43937
|
+
limit = 10,
|
|
43938
|
+
sort = {},
|
|
43939
|
+
school = "",
|
|
43940
|
+
building = "",
|
|
43941
|
+
type = "",
|
|
43942
|
+
status = "active"
|
|
43943
|
+
} = {}) {
|
|
43944
|
+
page = page > 0 ? page - 1 : 0;
|
|
43945
|
+
const query = {
|
|
43946
|
+
deletedAt: { $in: ["", null] },
|
|
43947
|
+
status: { $in: [status, "", null] }
|
|
43948
|
+
};
|
|
43949
|
+
const cacheParams = {
|
|
43950
|
+
page,
|
|
43951
|
+
limit,
|
|
43952
|
+
sort: JSON.stringify(sort)
|
|
43953
|
+
};
|
|
43954
|
+
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
43955
|
+
if (search) {
|
|
43956
|
+
query.$text = { $search: search };
|
|
43957
|
+
cacheParams.search = search;
|
|
43958
|
+
}
|
|
43959
|
+
if (school) {
|
|
43960
|
+
try {
|
|
43961
|
+
query.school = new ObjectId43(school);
|
|
43962
|
+
} catch (error) {
|
|
43963
|
+
throw new BadRequestError69("Invalid school ID.");
|
|
43590
43964
|
}
|
|
43591
|
-
|
|
43592
|
-
|
|
43593
|
-
|
|
43594
|
-
|
|
43595
|
-
|
|
43596
|
-
|
|
43597
|
-
|
|
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
|
-
}
|
|
43965
|
+
cacheParams.school = school;
|
|
43966
|
+
}
|
|
43967
|
+
if (building) {
|
|
43968
|
+
try {
|
|
43969
|
+
query.building = new ObjectId43(building);
|
|
43970
|
+
} catch (error) {
|
|
43971
|
+
throw new BadRequestError69("Invalid building ID.");
|
|
43679
43972
|
}
|
|
43680
|
-
|
|
43681
|
-
|
|
43682
|
-
|
|
43683
|
-
|
|
43684
|
-
|
|
43685
|
-
|
|
43686
|
-
|
|
43973
|
+
cacheParams.building = building;
|
|
43974
|
+
}
|
|
43975
|
+
if (type) {
|
|
43976
|
+
query.type = type;
|
|
43977
|
+
cacheParams.type = type;
|
|
43978
|
+
}
|
|
43979
|
+
const cacheKey = makeCacheKey23(namespace_collection, cacheParams);
|
|
43980
|
+
logger41.log({
|
|
43981
|
+
level: "info",
|
|
43982
|
+
message: `Cache key for getAll building units: ${cacheKey}`
|
|
43983
|
+
});
|
|
43984
|
+
try {
|
|
43985
|
+
const cached = await getCache(cacheKey);
|
|
43986
|
+
if (cached) {
|
|
43987
|
+
logger41.log({
|
|
43988
|
+
level: "info",
|
|
43989
|
+
message: `Cache hit for getAll building units: ${cacheKey}`
|
|
43687
43990
|
});
|
|
43688
|
-
|
|
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
|
-
);
|
|
43991
|
+
return cached;
|
|
43696
43992
|
}
|
|
43697
|
-
|
|
43698
|
-
|
|
43699
|
-
|
|
43700
|
-
|
|
43701
|
-
|
|
43702
|
-
|
|
43703
|
-
|
|
43704
|
-
|
|
43705
|
-
|
|
43706
|
-
|
|
43707
|
-
|
|
43708
|
-
|
|
43709
|
-
|
|
43710
|
-
|
|
43711
|
-
|
|
43712
|
-
|
|
43713
|
-
|
|
43714
|
-
}
|
|
43993
|
+
const items = await collection.aggregate([
|
|
43994
|
+
{ $match: query },
|
|
43995
|
+
{ $sort: sort },
|
|
43996
|
+
{ $skip: page * limit },
|
|
43997
|
+
{ $limit: limit }
|
|
43998
|
+
]).toArray();
|
|
43999
|
+
const length = await collection.countDocuments(query);
|
|
44000
|
+
const data = paginate22(items, page, limit, length);
|
|
44001
|
+
setCache(cacheKey, data, 600).then(() => {
|
|
44002
|
+
logger41.log({
|
|
44003
|
+
level: "info",
|
|
44004
|
+
message: `Cache set for getAll building units: ${cacheKey}`
|
|
44005
|
+
});
|
|
44006
|
+
}).catch((err) => {
|
|
44007
|
+
logger41.log({
|
|
44008
|
+
level: "error",
|
|
44009
|
+
message: `Failed to set cache for getAll building units: ${err.message}`
|
|
44010
|
+
});
|
|
44011
|
+
});
|
|
44012
|
+
return data;
|
|
44013
|
+
} catch (error) {
|
|
44014
|
+
logger41.log({ level: "error", message: `${error}` });
|
|
44015
|
+
throw error;
|
|
44016
|
+
}
|
|
44017
|
+
}
|
|
44018
|
+
async function countByBuilding(building, level) {
|
|
44019
|
+
const query = {
|
|
44020
|
+
status: "active"
|
|
44021
|
+
};
|
|
44022
|
+
const cacheKeyOptions = {
|
|
44023
|
+
...query,
|
|
44024
|
+
tag: "countByBuilding"
|
|
44025
|
+
};
|
|
44026
|
+
try {
|
|
44027
|
+
query.building = new ObjectId43(building);
|
|
44028
|
+
cacheKeyOptions.building = String(building);
|
|
44029
|
+
} catch (error) {
|
|
44030
|
+
throw new BadRequestError69("Invalid building ID.");
|
|
44031
|
+
}
|
|
44032
|
+
if (level) {
|
|
44033
|
+
query.level = level;
|
|
44034
|
+
cacheKeyOptions.level = level;
|
|
44035
|
+
}
|
|
44036
|
+
try {
|
|
44037
|
+
return await collection.countDocuments(query);
|
|
44038
|
+
} catch (error) {
|
|
44039
|
+
logger41.log({ level: "error", message: `${error}` });
|
|
44040
|
+
throw new InternalServerError23("Failed to count building units.");
|
|
44041
|
+
}
|
|
44042
|
+
}
|
|
44043
|
+
async function getById(_id) {
|
|
44044
|
+
try {
|
|
44045
|
+
_id = new ObjectId43(_id);
|
|
44046
|
+
} catch (error) {
|
|
44047
|
+
throw new BadRequestError69(namespace_collection + " Invalid ID.");
|
|
44048
|
+
}
|
|
44049
|
+
const cacheKey = makeCacheKey23(namespace_collection, { _id: String(_id) });
|
|
44050
|
+
try {
|
|
44051
|
+
const cached = await getCache(cacheKey);
|
|
44052
|
+
if (cached) {
|
|
44053
|
+
logger41.log({
|
|
44054
|
+
level: "info",
|
|
44055
|
+
message: `Cache hit for getById building unit: ${cacheKey}`
|
|
44056
|
+
});
|
|
44057
|
+
return cached;
|
|
43715
44058
|
}
|
|
43716
|
-
await
|
|
43717
|
-
|
|
43718
|
-
|
|
43719
|
-
|
|
43720
|
-
if (
|
|
43721
|
-
throw
|
|
44059
|
+
const result = await collection.findOne({
|
|
44060
|
+
_id,
|
|
44061
|
+
deletedAt: { $in: ["", null] }
|
|
44062
|
+
});
|
|
44063
|
+
if (!result) {
|
|
44064
|
+
throw new BadRequestError69("Building unit not found.");
|
|
44065
|
+
}
|
|
44066
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
44067
|
+
logger41.log({
|
|
44068
|
+
level: "info",
|
|
44069
|
+
message: `Cache set for building unit by id: ${cacheKey}`
|
|
44070
|
+
});
|
|
44071
|
+
}).catch((err) => {
|
|
44072
|
+
logger41.log({
|
|
44073
|
+
level: "error",
|
|
44074
|
+
message: `Failed to set cache for building unit by id: ${err.message}`
|
|
44075
|
+
});
|
|
44076
|
+
});
|
|
44077
|
+
return result;
|
|
44078
|
+
} catch (error) {
|
|
44079
|
+
if (error instanceof AppError27) {
|
|
44080
|
+
throw error;
|
|
43722
44081
|
} else {
|
|
43723
|
-
throw new
|
|
44082
|
+
throw new InternalServerError23("Failed to get building unit.");
|
|
43724
44083
|
}
|
|
43725
|
-
} finally {
|
|
43726
|
-
await session?.endSession();
|
|
43727
44084
|
}
|
|
43728
44085
|
}
|
|
43729
|
-
async function
|
|
43730
|
-
|
|
43731
|
-
|
|
43732
|
-
|
|
43733
|
-
|
|
43734
|
-
);
|
|
44086
|
+
async function getByBuildingLevel(building, level) {
|
|
44087
|
+
try {
|
|
44088
|
+
building = new ObjectId43(building);
|
|
44089
|
+
} catch (error) {
|
|
44090
|
+
throw new BadRequestError69("Invalid building ID.");
|
|
43735
44091
|
}
|
|
44092
|
+
const cacheKey = makeCacheKey23(namespace_collection, {
|
|
44093
|
+
building: String(building),
|
|
44094
|
+
level
|
|
44095
|
+
});
|
|
43736
44096
|
try {
|
|
43737
|
-
const
|
|
43738
|
-
|
|
43739
|
-
|
|
43740
|
-
|
|
43741
|
-
|
|
43742
|
-
|
|
43743
|
-
|
|
43744
|
-
throw new BadRequestError67("No learners found for this grade level.");
|
|
44097
|
+
const cached = await getCache(cacheKey);
|
|
44098
|
+
if (cached) {
|
|
44099
|
+
logger41.log({
|
|
44100
|
+
level: "info",
|
|
44101
|
+
message: `Cache hit for getById building unit: ${cacheKey}`
|
|
44102
|
+
});
|
|
44103
|
+
return cached;
|
|
43745
44104
|
}
|
|
43746
|
-
const
|
|
43747
|
-
|
|
43748
|
-
|
|
44105
|
+
const result = await collection.findOne({
|
|
44106
|
+
building,
|
|
44107
|
+
level,
|
|
44108
|
+
status: "active"
|
|
43749
44109
|
});
|
|
43750
|
-
|
|
43751
|
-
|
|
44110
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
44111
|
+
logger41.log({
|
|
44112
|
+
level: "info",
|
|
44113
|
+
message: `Cache set for building unit by id: ${cacheKey}`
|
|
44114
|
+
});
|
|
44115
|
+
}).catch((err) => {
|
|
44116
|
+
logger41.log({
|
|
44117
|
+
level: "error",
|
|
44118
|
+
message: `Failed to set cache for building unit by id: ${err.message}`
|
|
44119
|
+
});
|
|
44120
|
+
});
|
|
44121
|
+
return result;
|
|
44122
|
+
} catch (error) {
|
|
44123
|
+
if (error instanceof AppError27) {
|
|
44124
|
+
throw error;
|
|
44125
|
+
} else {
|
|
44126
|
+
throw new InternalServerError23("Failed to get building unit.");
|
|
43752
44127
|
}
|
|
43753
|
-
|
|
43754
|
-
|
|
43755
|
-
|
|
43756
|
-
|
|
43757
|
-
|
|
43758
|
-
|
|
43759
|
-
|
|
44128
|
+
}
|
|
44129
|
+
}
|
|
44130
|
+
async function getByBuilding(building) {
|
|
44131
|
+
try {
|
|
44132
|
+
building = new ObjectId43(building);
|
|
44133
|
+
} catch (error) {
|
|
44134
|
+
throw new BadRequestError69("Invalid building ID.");
|
|
44135
|
+
}
|
|
44136
|
+
const cacheKey = makeCacheKey23(namespace_collection, {
|
|
44137
|
+
building: String(building)
|
|
44138
|
+
});
|
|
44139
|
+
try {
|
|
44140
|
+
const cached = await getCache(cacheKey);
|
|
44141
|
+
if (cached) {
|
|
44142
|
+
logger41.log({
|
|
44143
|
+
level: "info",
|
|
44144
|
+
message: `Cache hit for getById building unit: ${cacheKey}`
|
|
44145
|
+
});
|
|
44146
|
+
return cached;
|
|
43760
44147
|
}
|
|
43761
|
-
const
|
|
43762
|
-
|
|
43763
|
-
|
|
43764
|
-
|
|
43765
|
-
)
|
|
43766
|
-
|
|
43767
|
-
|
|
44148
|
+
const result = await collection.findOne({
|
|
44149
|
+
building,
|
|
44150
|
+
status: "active"
|
|
44151
|
+
});
|
|
44152
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
44153
|
+
logger41.log({
|
|
44154
|
+
level: "info",
|
|
44155
|
+
message: `Cache set for building unit by id: ${cacheKey}`
|
|
44156
|
+
});
|
|
44157
|
+
}).catch((err) => {
|
|
44158
|
+
logger41.log({
|
|
44159
|
+
level: "error",
|
|
44160
|
+
message: `Failed to set cache for building unit by id: ${err.message}`
|
|
44161
|
+
});
|
|
44162
|
+
});
|
|
44163
|
+
return result;
|
|
44164
|
+
} catch (error) {
|
|
44165
|
+
if (error instanceof AppError27) {
|
|
44166
|
+
throw error;
|
|
44167
|
+
} else {
|
|
44168
|
+
throw new InternalServerError23("Failed to get building unit.");
|
|
43768
44169
|
}
|
|
43769
|
-
|
|
43770
|
-
|
|
43771
|
-
|
|
43772
|
-
|
|
43773
|
-
|
|
43774
|
-
|
|
43775
|
-
|
|
43776
|
-
|
|
43777
|
-
|
|
43778
|
-
|
|
43779
|
-
|
|
43780
|
-
|
|
44170
|
+
}
|
|
44171
|
+
}
|
|
44172
|
+
async function deleteById(_id, session) {
|
|
44173
|
+
try {
|
|
44174
|
+
_id = new ObjectId43(_id);
|
|
44175
|
+
} catch (error) {
|
|
44176
|
+
throw new BadRequestError69(namespace_collection + " Invalid ID.");
|
|
44177
|
+
}
|
|
44178
|
+
try {
|
|
44179
|
+
const res = await collection.updateOne(
|
|
44180
|
+
{ _id },
|
|
44181
|
+
{ $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } },
|
|
44182
|
+
{ session }
|
|
44183
|
+
);
|
|
44184
|
+
delCachedData();
|
|
44185
|
+
return "Room/Facility deleted successfully.";
|
|
44186
|
+
} catch (error) {
|
|
44187
|
+
logger41.log({
|
|
44188
|
+
level: "error",
|
|
44189
|
+
message: error.message
|
|
44190
|
+
});
|
|
44191
|
+
if (error instanceof AppError27) {
|
|
44192
|
+
throw error;
|
|
43781
44193
|
} else {
|
|
43782
|
-
throw new
|
|
44194
|
+
throw new Error("Failed to deleted room/facility.");
|
|
43783
44195
|
}
|
|
43784
44196
|
}
|
|
43785
44197
|
}
|
|
43786
|
-
return {
|
|
44198
|
+
return {
|
|
44199
|
+
createIndexes,
|
|
44200
|
+
add,
|
|
44201
|
+
getAll,
|
|
44202
|
+
getById,
|
|
44203
|
+
getByBuildingLevel,
|
|
44204
|
+
updateById,
|
|
44205
|
+
getByBuilding,
|
|
44206
|
+
deleteById,
|
|
44207
|
+
updateByBuildingId,
|
|
44208
|
+
countByBuilding
|
|
44209
|
+
};
|
|
43787
44210
|
}
|
|
43788
44211
|
|
|
43789
|
-
// src/resources/
|
|
43790
|
-
function
|
|
44212
|
+
// src/resources/building/building.service.ts
|
|
44213
|
+
function useBuildingService() {
|
|
43791
44214
|
const {
|
|
43792
|
-
|
|
43793
|
-
getAll: _getAll,
|
|
44215
|
+
updateById: _updateById,
|
|
43794
44216
|
getById: _getById,
|
|
43795
|
-
getByName: _getByName,
|
|
43796
|
-
getBySchool: _getBySchool,
|
|
43797
|
-
updateFieldById: _updateFieldById,
|
|
43798
|
-
addStudentToSection: _addStudentToSection,
|
|
43799
|
-
removeStudentFromSection: _removeStudentFromSection,
|
|
43800
44217
|
deleteById: _deleteById
|
|
43801
|
-
} =
|
|
43802
|
-
const {
|
|
43803
|
-
|
|
43804
|
-
|
|
43805
|
-
|
|
43806
|
-
|
|
43807
|
-
|
|
43808
|
-
|
|
43809
|
-
|
|
43810
|
-
|
|
43811
|
-
|
|
44218
|
+
} = useBuildingRepo();
|
|
44219
|
+
const { getByBuildingLevel, getByBuilding, updateByBuildingId } = useBuildingUnitRepo();
|
|
44220
|
+
async function updateById(id, data) {
|
|
44221
|
+
data.levels = Number(data.levels);
|
|
44222
|
+
const session = useAtlas33.getClient()?.startSession();
|
|
44223
|
+
try {
|
|
44224
|
+
const building = await _getById(id);
|
|
44225
|
+
if (!building) {
|
|
44226
|
+
throw new NotFoundError3("Building not found.");
|
|
44227
|
+
}
|
|
44228
|
+
if (data.levels < building.levels) {
|
|
44229
|
+
const unit = await getByBuildingLevel(id, building.levels);
|
|
44230
|
+
if (unit) {
|
|
44231
|
+
throw new BadRequestError70(
|
|
44232
|
+
"Cannot reduce floors, there are existing building units at higher floors."
|
|
44233
|
+
);
|
|
44234
|
+
}
|
|
44235
|
+
}
|
|
44236
|
+
session?.startTransaction();
|
|
44237
|
+
if (building.name !== data.name) {
|
|
44238
|
+
await updateByBuildingId(id, { buildingName: data.name }, session);
|
|
44239
|
+
}
|
|
44240
|
+
const result = await _updateById(id, data, session);
|
|
44241
|
+
await session?.commitTransaction();
|
|
44242
|
+
return result;
|
|
44243
|
+
} catch (error) {
|
|
44244
|
+
await session?.abortTransaction();
|
|
44245
|
+
throw error;
|
|
44246
|
+
} finally {
|
|
44247
|
+
session?.endSession();
|
|
44248
|
+
}
|
|
44249
|
+
}
|
|
44250
|
+
async function deleteById(id) {
|
|
44251
|
+
const building = await getByBuilding(id);
|
|
44252
|
+
if (building) {
|
|
44253
|
+
throw new BadRequestError70(
|
|
44254
|
+
"Cannot delete building with existing room/facility. Please delete room/facility first."
|
|
44255
|
+
);
|
|
43812
44256
|
}
|
|
43813
44257
|
try {
|
|
43814
|
-
|
|
43815
|
-
|
|
43816
|
-
|
|
43817
|
-
|
|
43818
|
-
});
|
|
43819
|
-
return;
|
|
43820
|
-
} catch (error2) {
|
|
43821
|
-
next(error2);
|
|
44258
|
+
await _deleteById(id);
|
|
44259
|
+
return "Building deleted successfully.";
|
|
44260
|
+
} catch (error) {
|
|
44261
|
+
throw error;
|
|
43822
44262
|
}
|
|
43823
44263
|
}
|
|
43824
|
-
|
|
44264
|
+
return {
|
|
44265
|
+
updateById,
|
|
44266
|
+
deleteById
|
|
44267
|
+
};
|
|
44268
|
+
}
|
|
44269
|
+
|
|
44270
|
+
// src/resources/building/building.controller.ts
|
|
44271
|
+
import { BadRequestError as BadRequestError71, logger as logger42 } from "@eeplatform/nodejs-utils";
|
|
44272
|
+
import Joi46 from "joi";
|
|
44273
|
+
function useBuildingController() {
|
|
44274
|
+
const { getAll: _getAll, getById: _getById, add: _add } = useBuildingRepo();
|
|
44275
|
+
const { updateById: _updateById, deleteById: _deleteById } = useBuildingService();
|
|
44276
|
+
async function createBuilding(req, res, next) {
|
|
43825
44277
|
const value = req.body;
|
|
43826
|
-
const
|
|
44278
|
+
const validation = Joi46.object({
|
|
44279
|
+
name: Joi46.string().required(),
|
|
44280
|
+
school: Joi46.string().hex().required(),
|
|
44281
|
+
levels: Joi46.number().integer().min(1).required(),
|
|
44282
|
+
serial: Joi46.string().optional().allow("", null),
|
|
44283
|
+
status: Joi46.string().optional().allow("", null)
|
|
44284
|
+
});
|
|
44285
|
+
const { error } = validation.validate(value);
|
|
43827
44286
|
if (error) {
|
|
43828
|
-
next(new
|
|
44287
|
+
next(new BadRequestError71(error.message));
|
|
44288
|
+
logger42.info(`Controller: ${error.message}`);
|
|
43829
44289
|
return;
|
|
43830
44290
|
}
|
|
43831
44291
|
try {
|
|
43832
|
-
const
|
|
43833
|
-
res.json(
|
|
43834
|
-
message: "Successfully created section.",
|
|
43835
|
-
data
|
|
43836
|
-
});
|
|
44292
|
+
const result = await _add(value);
|
|
44293
|
+
res.json(result);
|
|
43837
44294
|
return;
|
|
43838
44295
|
} catch (error2) {
|
|
43839
44296
|
next(error2);
|
|
43840
44297
|
}
|
|
43841
44298
|
}
|
|
43842
|
-
async function
|
|
44299
|
+
async function updateById(req, res, next) {
|
|
43843
44300
|
const value = req.body;
|
|
43844
|
-
const
|
|
44301
|
+
const id = req.params.id ?? "";
|
|
44302
|
+
const validation = Joi46.object({
|
|
44303
|
+
id: Joi46.string().hex().required(),
|
|
44304
|
+
value: Joi46.object({
|
|
44305
|
+
name: Joi46.string().required(),
|
|
44306
|
+
serial: Joi46.string().optional().allow("", null),
|
|
44307
|
+
levels: Joi46.number().integer().min(1).required()
|
|
44308
|
+
})
|
|
44309
|
+
});
|
|
44310
|
+
const { error } = validation.validate({ id, value });
|
|
43845
44311
|
if (error) {
|
|
43846
|
-
next(new
|
|
44312
|
+
next(new BadRequestError71(error.message));
|
|
44313
|
+
logger42.info(`Controller: ${error.message}`);
|
|
43847
44314
|
return;
|
|
43848
44315
|
}
|
|
43849
44316
|
try {
|
|
43850
|
-
const
|
|
43851
|
-
res.json(
|
|
44317
|
+
const result = await _updateById(id, value);
|
|
44318
|
+
res.json(result);
|
|
43852
44319
|
return;
|
|
43853
44320
|
} catch (error2) {
|
|
43854
44321
|
next(error2);
|
|
@@ -43856,48 +44323,42 @@ function useSectionController() {
|
|
|
43856
44323
|
}
|
|
43857
44324
|
async function getAll(req, res, next) {
|
|
43858
44325
|
const query = req.query;
|
|
43859
|
-
const validation =
|
|
43860
|
-
page:
|
|
43861
|
-
limit:
|
|
43862
|
-
search:
|
|
43863
|
-
|
|
43864
|
-
|
|
43865
|
-
schoolYear: Joi45.string().optional().allow("", null),
|
|
43866
|
-
gradeLevel: Joi45.string().optional().allow("", null)
|
|
44326
|
+
const validation = Joi46.object({
|
|
44327
|
+
page: Joi46.number().min(1).optional().allow("", null),
|
|
44328
|
+
limit: Joi46.number().min(1).optional().allow("", null),
|
|
44329
|
+
search: Joi46.string().optional().allow("", null),
|
|
44330
|
+
school: Joi46.string().hex().optional().allow("", null),
|
|
44331
|
+
status: Joi46.string().optional().allow("", null)
|
|
43867
44332
|
});
|
|
43868
44333
|
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
44334
|
if (error) {
|
|
43887
|
-
next(new
|
|
44335
|
+
next(new BadRequestError71(error.message));
|
|
43888
44336
|
return;
|
|
43889
44337
|
}
|
|
44338
|
+
const page = parseInt(req.query.page) ?? 1;
|
|
44339
|
+
let limit = parseInt(req.query.limit) ?? 20;
|
|
44340
|
+
limit = isNaN(limit) ? 20 : limit;
|
|
44341
|
+
const sort = req.query.sort ? String(req.query.sort).split(",") : "";
|
|
44342
|
+
const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
|
|
44343
|
+
const sortObj = {};
|
|
44344
|
+
if (sort && Array.isArray(sort) && sort.length && sortOrder && Array.isArray(sortOrder) && sortOrder.length) {
|
|
44345
|
+
sort.forEach((field, index) => {
|
|
44346
|
+
sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
|
|
44347
|
+
});
|
|
44348
|
+
}
|
|
44349
|
+
const status = req.query.status ?? "active";
|
|
44350
|
+
const school = req.query.school ?? "";
|
|
44351
|
+
const search = req.query.search ?? "";
|
|
43890
44352
|
try {
|
|
43891
|
-
const
|
|
44353
|
+
const buildings = await _getAll({
|
|
43892
44354
|
page,
|
|
43893
44355
|
limit,
|
|
43894
|
-
|
|
44356
|
+
sort: sortObj,
|
|
43895
44357
|
status,
|
|
43896
44358
|
school,
|
|
43897
|
-
|
|
43898
|
-
gradeLevel
|
|
44359
|
+
search
|
|
43899
44360
|
});
|
|
43900
|
-
res.json(
|
|
44361
|
+
res.json(buildings);
|
|
43901
44362
|
return;
|
|
43902
44363
|
} catch (error2) {
|
|
43903
44364
|
next(error2);
|
|
@@ -43905,654 +44366,424 @@ function useSectionController() {
|
|
|
43905
44366
|
}
|
|
43906
44367
|
async function getById(req, res, next) {
|
|
43907
44368
|
const id = req.params.id;
|
|
43908
|
-
const validation =
|
|
43909
|
-
id:
|
|
44369
|
+
const validation = Joi46.object({
|
|
44370
|
+
id: Joi46.string().hex().required()
|
|
43910
44371
|
});
|
|
43911
44372
|
const { error } = validation.validate({ id });
|
|
43912
44373
|
if (error) {
|
|
43913
|
-
next(new
|
|
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));
|
|
44374
|
+
next(new BadRequestError71(error.message));
|
|
43932
44375
|
return;
|
|
43933
44376
|
}
|
|
43934
44377
|
try {
|
|
43935
|
-
const
|
|
44378
|
+
const building = await _getById(id);
|
|
43936
44379
|
res.json({
|
|
43937
|
-
message: "Successfully retrieved
|
|
43938
|
-
data
|
|
44380
|
+
message: "Successfully retrieved building.",
|
|
44381
|
+
data: { building }
|
|
43939
44382
|
});
|
|
43940
44383
|
return;
|
|
43941
44384
|
} catch (error2) {
|
|
43942
44385
|
next(error2);
|
|
43943
44386
|
}
|
|
43944
44387
|
}
|
|
43945
|
-
async function
|
|
43946
|
-
const
|
|
43947
|
-
const validation =
|
|
43948
|
-
|
|
44388
|
+
async function deleteById(req, res, next) {
|
|
44389
|
+
const id = req.params.id;
|
|
44390
|
+
const validation = Joi46.object({
|
|
44391
|
+
id: Joi46.string().hex().required()
|
|
43949
44392
|
});
|
|
43950
|
-
const { error } = validation.validate({
|
|
44393
|
+
const { error } = validation.validate({ id });
|
|
43951
44394
|
if (error) {
|
|
43952
|
-
next(new
|
|
44395
|
+
next(new BadRequestError71(error.message));
|
|
43953
44396
|
return;
|
|
43954
44397
|
}
|
|
43955
44398
|
try {
|
|
43956
|
-
const
|
|
43957
|
-
res.json(
|
|
43958
|
-
message: "Successfully retrieved sections.",
|
|
43959
|
-
data
|
|
43960
|
-
});
|
|
44399
|
+
const message = await _deleteById(id);
|
|
44400
|
+
res.json(message);
|
|
43961
44401
|
return;
|
|
43962
44402
|
} catch (error2) {
|
|
43963
44403
|
next(error2);
|
|
43964
44404
|
}
|
|
43965
44405
|
}
|
|
43966
|
-
|
|
43967
|
-
|
|
43968
|
-
|
|
43969
|
-
|
|
43970
|
-
|
|
43971
|
-
|
|
43972
|
-
|
|
43973
|
-
|
|
43974
|
-
|
|
43975
|
-
|
|
43976
|
-
|
|
43977
|
-
|
|
44406
|
+
return {
|
|
44407
|
+
createBuilding,
|
|
44408
|
+
getAll,
|
|
44409
|
+
getById,
|
|
44410
|
+
updateById,
|
|
44411
|
+
deleteById
|
|
44412
|
+
};
|
|
44413
|
+
}
|
|
44414
|
+
|
|
44415
|
+
// src/resources/building/building-unit.service.ts
|
|
44416
|
+
import { useAtlas as useAtlas34 } from "@eeplatform/nodejs-utils";
|
|
44417
|
+
function useBuildingUnitService() {
|
|
44418
|
+
const {
|
|
44419
|
+
add: _add,
|
|
44420
|
+
countByBuilding,
|
|
44421
|
+
deleteById: _deleteById
|
|
44422
|
+
} = useBuildingUnitRepo();
|
|
44423
|
+
async function add(value) {
|
|
44424
|
+
const session = useAtlas34.getClient()?.startSession();
|
|
44425
|
+
if (!session) {
|
|
44426
|
+
throw new Error("Unable to start session for building unit service.");
|
|
43978
44427
|
}
|
|
43979
44428
|
try {
|
|
43980
|
-
|
|
43981
|
-
|
|
43982
|
-
|
|
43983
|
-
|
|
43984
|
-
|
|
44429
|
+
await session.startTransaction();
|
|
44430
|
+
const existingCount = await countByBuilding(
|
|
44431
|
+
value.building.building,
|
|
44432
|
+
value.building.level
|
|
44433
|
+
);
|
|
44434
|
+
for (let index = 0; index < value.qty; index++) {
|
|
44435
|
+
const unitNumber = existingCount ? existingCount + index + 1 : index + 1;
|
|
44436
|
+
await _add(
|
|
44437
|
+
{ ...value.building, name: `${value.building.name} R${unitNumber}` },
|
|
44438
|
+
session
|
|
44439
|
+
);
|
|
44440
|
+
}
|
|
44441
|
+
await session.commitTransaction();
|
|
44442
|
+
return "Building unit added successfully.";
|
|
44443
|
+
} catch (error) {
|
|
44444
|
+
await session.abortTransaction();
|
|
44445
|
+
throw error;
|
|
44446
|
+
} finally {
|
|
44447
|
+
session.endSession();
|
|
43985
44448
|
}
|
|
43986
44449
|
}
|
|
43987
|
-
|
|
43988
|
-
|
|
43989
|
-
|
|
43990
|
-
|
|
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);
|
|
44450
|
+
const { getById: getSectionSubjectByClassroom } = useSectionSubjectRepo();
|
|
44451
|
+
async function deleteById(id) {
|
|
44452
|
+
if (!id) {
|
|
44453
|
+
throw new Error("Invalid building unit ID.");
|
|
44005
44454
|
}
|
|
44006
|
-
|
|
44007
|
-
|
|
44008
|
-
|
|
44009
|
-
|
|
44010
|
-
|
|
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;
|
|
44455
|
+
const sectionSubject = await getSectionSubjectByClassroom(id);
|
|
44456
|
+
if (sectionSubject) {
|
|
44457
|
+
throw new Error(
|
|
44458
|
+
"Cannot delete building unit as it is assigned to a section subject."
|
|
44459
|
+
);
|
|
44018
44460
|
}
|
|
44019
44461
|
try {
|
|
44020
|
-
|
|
44021
|
-
|
|
44022
|
-
|
|
44023
|
-
|
|
44024
|
-
next(error2);
|
|
44462
|
+
await _deleteById(id);
|
|
44463
|
+
return "Building unit deleted successfully.";
|
|
44464
|
+
} catch (error) {
|
|
44465
|
+
throw new Error("Failed to delete building unit.");
|
|
44025
44466
|
}
|
|
44026
44467
|
}
|
|
44027
|
-
|
|
44028
|
-
|
|
44029
|
-
|
|
44030
|
-
|
|
44468
|
+
return {
|
|
44469
|
+
add,
|
|
44470
|
+
deleteById
|
|
44471
|
+
};
|
|
44472
|
+
}
|
|
44473
|
+
|
|
44474
|
+
// src/resources/building/building-unit.controller.ts
|
|
44475
|
+
import { BadRequestError as BadRequestError72 } from "@eeplatform/nodejs-utils";
|
|
44476
|
+
import Joi47 from "joi";
|
|
44477
|
+
function useBuildingUnitController() {
|
|
44478
|
+
const {
|
|
44479
|
+
getAll: _getAll,
|
|
44480
|
+
getById: _getById,
|
|
44481
|
+
updateById: _updateById
|
|
44482
|
+
} = useBuildingUnitRepo();
|
|
44483
|
+
const { add: _add, deleteById: _deleteById } = useBuildingUnitService();
|
|
44484
|
+
async function add(req, res, next) {
|
|
44485
|
+
const data = req.body;
|
|
44486
|
+
const validation = Joi47.object({
|
|
44487
|
+
building: Joi47.object({
|
|
44488
|
+
school: Joi47.string().hex().required(),
|
|
44489
|
+
name: Joi47.string().optional().allow("", null),
|
|
44490
|
+
building: Joi47.string().hex().required(),
|
|
44491
|
+
buildingName: Joi47.string().optional().allow("", null),
|
|
44492
|
+
level: Joi47.number().integer().min(1).required(),
|
|
44493
|
+
category: Joi47.string().required(),
|
|
44494
|
+
type: Joi47.string().required(),
|
|
44495
|
+
seating_capacity: Joi47.number().integer().min(0).required(),
|
|
44496
|
+
standing_capacity: Joi47.number().integer().min(0).required(),
|
|
44497
|
+
description: Joi47.string().optional().allow("", null),
|
|
44498
|
+
unit_of_measurement: Joi47.string().valid("sqm").required(),
|
|
44499
|
+
area: Joi47.number().positive().required(),
|
|
44500
|
+
status: Joi47.string().optional().allow("", null)
|
|
44501
|
+
}),
|
|
44502
|
+
qty: Joi47.number().integer().min(1).max(20).optional().default(1)
|
|
44031
44503
|
});
|
|
44032
|
-
const { error } = validation.validate(
|
|
44504
|
+
const { error } = validation.validate(data);
|
|
44033
44505
|
if (error) {
|
|
44034
|
-
next(new
|
|
44506
|
+
next(new BadRequestError72(error.message));
|
|
44035
44507
|
return;
|
|
44036
44508
|
}
|
|
44037
44509
|
try {
|
|
44038
|
-
const
|
|
44039
|
-
res.json({
|
|
44040
|
-
|
|
44510
|
+
const buildingUnit = await _add(data);
|
|
44511
|
+
res.json({
|
|
44512
|
+
message: "Building unit added successfully.",
|
|
44513
|
+
data: { buildingUnit }
|
|
44514
|
+
});
|
|
44041
44515
|
} catch (error2) {
|
|
44042
44516
|
next(error2);
|
|
44043
44517
|
}
|
|
44044
44518
|
}
|
|
44045
|
-
|
|
44046
|
-
|
|
44047
|
-
|
|
44048
|
-
|
|
44049
|
-
|
|
44050
|
-
|
|
44051
|
-
|
|
44052
|
-
|
|
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);
|
|
44519
|
+
async function updateById(req, res, next) {
|
|
44520
|
+
const data = req.body;
|
|
44521
|
+
const id = req.params.id ?? "";
|
|
44522
|
+
const validation = Joi47.object({
|
|
44523
|
+
id: Joi47.string().hex().required(),
|
|
44524
|
+
value: schemaUpdateOptions
|
|
44525
|
+
});
|
|
44526
|
+
const { error } = validation.validate({ id, value: data });
|
|
44068
44527
|
if (error) {
|
|
44069
|
-
next(new
|
|
44528
|
+
next(new BadRequestError72(error.message));
|
|
44070
44529
|
return;
|
|
44071
44530
|
}
|
|
44072
44531
|
try {
|
|
44073
|
-
const
|
|
44532
|
+
const buildingUnit = await _updateById(id, data);
|
|
44074
44533
|
res.json({
|
|
44075
|
-
message: "
|
|
44076
|
-
data
|
|
44534
|
+
message: "Building unit updated successfully.",
|
|
44535
|
+
data: { buildingUnit }
|
|
44077
44536
|
});
|
|
44078
|
-
return;
|
|
44079
44537
|
} catch (error2) {
|
|
44080
44538
|
next(error2);
|
|
44081
44539
|
}
|
|
44082
44540
|
}
|
|
44083
44541
|
async function getAll(req, res, next) {
|
|
44084
44542
|
const query = req.query;
|
|
44085
|
-
const validation =
|
|
44086
|
-
page:
|
|
44087
|
-
limit:
|
|
44088
|
-
search:
|
|
44089
|
-
|
|
44090
|
-
|
|
44091
|
-
|
|
44092
|
-
|
|
44093
|
-
schoolYear: Joi46.string().optional().allow("", null)
|
|
44543
|
+
const validation = Joi47.object({
|
|
44544
|
+
page: Joi47.number().min(1).optional().allow("", null),
|
|
44545
|
+
limit: Joi47.number().min(1).optional().allow("", null),
|
|
44546
|
+
search: Joi47.string().optional().allow("", null),
|
|
44547
|
+
school: Joi47.string().hex().optional().allow("", null),
|
|
44548
|
+
building: Joi47.string().hex().optional().allow("", null),
|
|
44549
|
+
status: Joi47.string().optional().allow("", null),
|
|
44550
|
+
type: Joi47.string().optional().allow("", null)
|
|
44094
44551
|
});
|
|
44095
44552
|
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
44553
|
if (error) {
|
|
44115
|
-
next(new
|
|
44554
|
+
next(new BadRequestError72(error.message));
|
|
44116
44555
|
return;
|
|
44117
44556
|
}
|
|
44557
|
+
const page = parseInt(req.query.page) ?? 1;
|
|
44558
|
+
let limit = parseInt(req.query.limit) ?? 20;
|
|
44559
|
+
limit = isNaN(limit) ? 20 : limit;
|
|
44560
|
+
const sort = req.query.sort ? String(req.query.sort).split(",") : "";
|
|
44561
|
+
const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
|
|
44562
|
+
const sortObj = {};
|
|
44563
|
+
if (sort && Array.isArray(sort) && sort.length && sortOrder && Array.isArray(sortOrder) && sortOrder.length) {
|
|
44564
|
+
sort.forEach((field, index) => {
|
|
44565
|
+
sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
|
|
44566
|
+
});
|
|
44567
|
+
}
|
|
44568
|
+
const status = req.query.status ?? "active";
|
|
44569
|
+
const school = req.query.school ?? "";
|
|
44570
|
+
const building = req.query.building ?? "";
|
|
44571
|
+
const search = req.query.search ?? "";
|
|
44572
|
+
const type = req.query.type ?? "";
|
|
44118
44573
|
try {
|
|
44119
|
-
const
|
|
44574
|
+
const buildings = await _getAll({
|
|
44120
44575
|
page,
|
|
44121
44576
|
limit,
|
|
44122
|
-
|
|
44577
|
+
sort: sortObj,
|
|
44123
44578
|
status,
|
|
44124
44579
|
school,
|
|
44125
|
-
|
|
44126
|
-
|
|
44127
|
-
|
|
44580
|
+
search,
|
|
44581
|
+
building,
|
|
44582
|
+
type
|
|
44128
44583
|
});
|
|
44129
|
-
res.json(
|
|
44584
|
+
res.json(buildings);
|
|
44130
44585
|
return;
|
|
44131
44586
|
} catch (error2) {
|
|
44132
44587
|
next(error2);
|
|
44133
44588
|
}
|
|
44134
44589
|
}
|
|
44135
|
-
|
|
44136
|
-
|
|
44137
|
-
|
|
44138
|
-
|
|
44139
|
-
}
|
|
44140
|
-
|
|
44141
|
-
|
|
44142
|
-
|
|
44143
|
-
|
|
44144
|
-
|
|
44145
|
-
var schemaBuilding = Joi47.object({
|
|
44146
|
-
_id: Joi47.string().hex().optional(),
|
|
44147
|
-
school: Joi47.string().hex().required(),
|
|
44148
|
-
serial: Joi47.string().optional().allow("", null),
|
|
44149
|
-
name: Joi47.string().required(),
|
|
44150
|
-
levels: Joi47.number().integer().min(1).required(),
|
|
44151
|
-
createdAt: Joi47.date().optional().allow("", null),
|
|
44152
|
-
updatedAt: Joi47.date().optional().allow("", null),
|
|
44153
|
-
deletedAt: Joi47.date().optional().allow("", null),
|
|
44154
|
-
status: Joi47.string().optional().allow("", null)
|
|
44155
|
-
});
|
|
44156
|
-
var schemaBuildingUnit = Joi47.object({
|
|
44157
|
-
_id: Joi47.string().hex().optional(),
|
|
44158
|
-
school: Joi47.string().hex().required(),
|
|
44159
|
-
name: Joi47.string().optional().allow("", null),
|
|
44160
|
-
building: Joi47.string().hex().required(),
|
|
44161
|
-
buildingName: Joi47.string().optional().allow("", null),
|
|
44162
|
-
level: Joi47.number().integer().min(1).required(),
|
|
44163
|
-
category: Joi47.string().required(),
|
|
44164
|
-
type: Joi47.string().required(),
|
|
44165
|
-
seating_capacity: Joi47.number().integer().min(0).required(),
|
|
44166
|
-
standing_capacity: Joi47.number().integer().min(0).required(),
|
|
44167
|
-
description: Joi47.string().optional().allow("", null),
|
|
44168
|
-
unit_of_measurement: Joi47.string().valid("sqm").required(),
|
|
44169
|
-
area: Joi47.number().positive().required(),
|
|
44170
|
-
status: Joi47.string().optional().allow("", null)
|
|
44171
|
-
});
|
|
44172
|
-
var schemaUpdateOptions = Joi47.object({
|
|
44173
|
-
name: Joi47.string().optional().allow("", null),
|
|
44174
|
-
building: Joi47.string().hex().optional().allow("", null),
|
|
44175
|
-
buildingName: Joi47.string().optional().allow("", null),
|
|
44176
|
-
level: Joi47.number().integer().min(1).optional().allow("", null),
|
|
44177
|
-
category: Joi47.string().optional().allow("", null),
|
|
44178
|
-
type: Joi47.string().optional().allow("", null),
|
|
44179
|
-
seating_capacity: Joi47.number().integer().min(0).optional().allow("", null),
|
|
44180
|
-
standing_capacity: Joi47.number().integer().min(0).optional().allow("", null),
|
|
44181
|
-
area: Joi47.number().positive().optional().allow("", null)
|
|
44182
|
-
});
|
|
44183
|
-
function MBuilding(value) {
|
|
44184
|
-
const { error } = schemaBuilding.validate(value);
|
|
44185
|
-
if (error) {
|
|
44186
|
-
logger40.info(`Building Model: ${error.message}`);
|
|
44187
|
-
throw new BadRequestError70(error.message);
|
|
44188
|
-
}
|
|
44189
|
-
if (value._id && typeof value._id === "string") {
|
|
44590
|
+
async function getById(req, res, next) {
|
|
44591
|
+
const id = req.params.id;
|
|
44592
|
+
const validation = Joi47.object({
|
|
44593
|
+
id: Joi47.string().hex().required()
|
|
44594
|
+
});
|
|
44595
|
+
const { error } = validation.validate({ id });
|
|
44596
|
+
if (error) {
|
|
44597
|
+
next(new BadRequestError72(error.message));
|
|
44598
|
+
return;
|
|
44599
|
+
}
|
|
44190
44600
|
try {
|
|
44191
|
-
|
|
44601
|
+
const buildingUnit = await _getById(id);
|
|
44602
|
+
res.json({
|
|
44603
|
+
message: "Successfully retrieved building unit.",
|
|
44604
|
+
data: { buildingUnit }
|
|
44605
|
+
});
|
|
44606
|
+
return;
|
|
44192
44607
|
} catch (error2) {
|
|
44193
|
-
|
|
44608
|
+
next(error2);
|
|
44194
44609
|
}
|
|
44195
44610
|
}
|
|
44196
|
-
|
|
44197
|
-
|
|
44198
|
-
|
|
44199
|
-
|
|
44200
|
-
|
|
44201
|
-
|
|
44202
|
-
|
|
44203
|
-
|
|
44204
|
-
|
|
44205
|
-
|
|
44206
|
-
levels: value.levels ?? 0,
|
|
44207
|
-
status: value.status ?? "active",
|
|
44208
|
-
createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
|
|
44209
|
-
updatedAt: value.updatedAt ?? "",
|
|
44210
|
-
deletedAt: value.deletedAt ?? ""
|
|
44211
|
-
};
|
|
44212
|
-
}
|
|
44213
|
-
function MBuildingUnit(value) {
|
|
44214
|
-
const { error } = schemaBuildingUnit.validate(value);
|
|
44215
|
-
if (error) {
|
|
44216
|
-
logger40.info(`Building Unit Model: ${error.message}`);
|
|
44217
|
-
throw new BadRequestError70(error.message);
|
|
44218
|
-
}
|
|
44219
|
-
if (value._id && typeof value._id === "string") {
|
|
44611
|
+
async function deleteById(req, res, next) {
|
|
44612
|
+
const id = req.params.id;
|
|
44613
|
+
const validation = Joi47.object({
|
|
44614
|
+
id: Joi47.string().hex().required()
|
|
44615
|
+
});
|
|
44616
|
+
const { error } = validation.validate({ id });
|
|
44617
|
+
if (error) {
|
|
44618
|
+
next(new BadRequestError72(error.message));
|
|
44619
|
+
return;
|
|
44620
|
+
}
|
|
44220
44621
|
try {
|
|
44221
|
-
|
|
44622
|
+
const message = await _deleteById(id);
|
|
44623
|
+
res.json({ message });
|
|
44624
|
+
return;
|
|
44222
44625
|
} catch (error2) {
|
|
44223
|
-
|
|
44626
|
+
next(error2);
|
|
44224
44627
|
}
|
|
44225
44628
|
}
|
|
44226
|
-
try {
|
|
44227
|
-
value.school = new ObjectId43(value.school);
|
|
44228
|
-
} catch (error2) {
|
|
44229
|
-
throw new BadRequestError70("Invalid school ID");
|
|
44230
|
-
}
|
|
44231
|
-
try {
|
|
44232
|
-
value.building = new ObjectId43(value.building);
|
|
44233
|
-
} catch (error2) {
|
|
44234
|
-
throw new BadRequestError70("Invalid building ID");
|
|
44235
|
-
}
|
|
44236
44629
|
return {
|
|
44237
|
-
|
|
44238
|
-
|
|
44239
|
-
|
|
44240
|
-
|
|
44241
|
-
|
|
44242
|
-
level: value.level ?? 0,
|
|
44243
|
-
category: value.category ?? "",
|
|
44244
|
-
type: value.type ?? "",
|
|
44245
|
-
seating_capacity: value.seating_capacity ?? 0,
|
|
44246
|
-
standing_capacity: value.standing_capacity ?? 0,
|
|
44247
|
-
description: value.description ?? "",
|
|
44248
|
-
unit_of_measurement: value.unit_of_measurement ?? "sqm",
|
|
44249
|
-
area: value.area ?? 0,
|
|
44250
|
-
status: value.status ?? "active",
|
|
44251
|
-
createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
|
|
44252
|
-
updatedAt: value.updatedAt ?? "",
|
|
44253
|
-
deletedAt: value.deletedAt ?? ""
|
|
44630
|
+
add,
|
|
44631
|
+
getAll,
|
|
44632
|
+
getById,
|
|
44633
|
+
updateById,
|
|
44634
|
+
deleteById
|
|
44254
44635
|
};
|
|
44255
44636
|
}
|
|
44256
44637
|
|
|
44257
|
-
// src/resources/
|
|
44258
|
-
import {
|
|
44259
|
-
|
|
44260
|
-
BadRequestError as BadRequestError71,
|
|
44261
|
-
InternalServerError as InternalServerError23,
|
|
44262
|
-
logger as logger41,
|
|
44263
|
-
makeCacheKey as makeCacheKey23,
|
|
44264
|
-
paginate as paginate22,
|
|
44265
|
-
useAtlas as useAtlas32,
|
|
44266
|
-
useCache as useCache23
|
|
44267
|
-
} from "@eeplatform/nodejs-utils";
|
|
44638
|
+
// src/resources/kindergarten-routine/kindergarten.routine.model.ts
|
|
44639
|
+
import { BadRequestError as BadRequestError73 } from "@eeplatform/nodejs-utils";
|
|
44640
|
+
import Joi48 from "joi";
|
|
44268
44641
|
import { ObjectId as ObjectId44 } from "mongodb";
|
|
44269
|
-
|
|
44270
|
-
|
|
44271
|
-
|
|
44272
|
-
|
|
44273
|
-
|
|
44274
|
-
|
|
44275
|
-
|
|
44276
|
-
|
|
44277
|
-
|
|
44278
|
-
|
|
44279
|
-
|
|
44280
|
-
|
|
44281
|
-
|
|
44282
|
-
|
|
44283
|
-
|
|
44284
|
-
}
|
|
44285
|
-
|
|
44286
|
-
|
|
44287
|
-
|
|
44288
|
-
|
|
44289
|
-
|
|
44290
|
-
|
|
44291
|
-
|
|
44292
|
-
|
|
44293
|
-
|
|
44294
|
-
|
|
44295
|
-
|
|
44296
|
-
|
|
44297
|
-
|
|
44298
|
-
|
|
44299
|
-
|
|
44300
|
-
|
|
44301
|
-
|
|
44302
|
-
|
|
44303
|
-
|
|
44304
|
-
|
|
44305
|
-
|
|
44306
|
-
|
|
44307
|
-
|
|
44308
|
-
}
|
|
44642
|
+
var schemaKindergartenRoutine = Joi48.object({
|
|
44643
|
+
_id: Joi48.string().hex().optional().allow(null, ""),
|
|
44644
|
+
title: Joi48.string().max(100).required(),
|
|
44645
|
+
section: Joi48.string().hex().optional().allow(null, ""),
|
|
44646
|
+
sectionName: Joi48.string().max(100).optional().allow(null, ""),
|
|
44647
|
+
classroom: Joi48.string().hex().optional().allow(null, ""),
|
|
44648
|
+
classroomName: Joi48.string().max(100).optional().allow(null, ""),
|
|
44649
|
+
blockTimes: Joi48.array().items(
|
|
44650
|
+
Joi48.object({
|
|
44651
|
+
id: Joi48.number().required(),
|
|
44652
|
+
title: Joi48.string().required(),
|
|
44653
|
+
startTime: Joi48.string().required(),
|
|
44654
|
+
endTime: Joi48.string().required(),
|
|
44655
|
+
durationMinutes: Joi48.number().required(),
|
|
44656
|
+
domains: Joi48.array().items(Joi48.string()).optional()
|
|
44657
|
+
})
|
|
44658
|
+
).required(),
|
|
44659
|
+
type: Joi48.string().required(),
|
|
44660
|
+
durationMinutes: Joi48.number().optional().allow(null, 0),
|
|
44661
|
+
school: Joi48.string().hex().required(),
|
|
44662
|
+
schoolYear: Joi48.string().optional().allow(null, ""),
|
|
44663
|
+
createdAt: Joi48.string().isoDate().optional().allow(null, ""),
|
|
44664
|
+
updatedAt: Joi48.string().isoDate().optional().allow(null, ""),
|
|
44665
|
+
deletedAt: Joi48.string().isoDate().optional().allow(null, "")
|
|
44666
|
+
});
|
|
44667
|
+
var schemaKindergartenRoutineUpdate = Joi48.object({
|
|
44668
|
+
title: Joi48.string().max(100).optional().allow(null, ""),
|
|
44669
|
+
section: Joi48.string().hex().optional().allow(null, ""),
|
|
44670
|
+
sectionName: Joi48.string().max(100).optional().allow(null, ""),
|
|
44671
|
+
classroom: Joi48.string().hex().optional().allow(null, ""),
|
|
44672
|
+
classroomName: Joi48.string().max(100).optional().allow(null, ""),
|
|
44673
|
+
blockTimes: Joi48.array().items(
|
|
44674
|
+
Joi48.object({
|
|
44675
|
+
id: Joi48.number().required(),
|
|
44676
|
+
title: Joi48.string().required(),
|
|
44677
|
+
startTime: Joi48.string().required(),
|
|
44678
|
+
endTime: Joi48.string().required(),
|
|
44679
|
+
durationMinutes: Joi48.number().required(),
|
|
44680
|
+
domains: Joi48.array().items(Joi48.string()).optional()
|
|
44681
|
+
})
|
|
44682
|
+
).optional(),
|
|
44683
|
+
durationMinutes: Joi48.number().optional().allow(null, 0)
|
|
44684
|
+
});
|
|
44685
|
+
function modelKindergartenRoutine(value) {
|
|
44686
|
+
const { error } = schemaKindergartenRoutine.validate(value);
|
|
44687
|
+
if (error) {
|
|
44688
|
+
throw new BadRequestError73(
|
|
44689
|
+
`Invalid kindergarten routine data: ${error.message}`
|
|
44690
|
+
);
|
|
44309
44691
|
}
|
|
44310
|
-
|
|
44311
|
-
try {
|
|
44312
|
-
_id = new ObjectId44(_id);
|
|
44313
|
-
} catch (error) {
|
|
44314
|
-
throw new BadRequestError71(namespace_collection + " Invalid ID.");
|
|
44315
|
-
}
|
|
44692
|
+
if (value._id && typeof value._id === "string") {
|
|
44316
44693
|
try {
|
|
44317
|
-
|
|
44318
|
-
|
|
44319
|
-
|
|
44320
|
-
{ session }
|
|
44321
|
-
);
|
|
44322
|
-
delCachedData();
|
|
44323
|
-
return res;
|
|
44324
|
-
} catch (error) {
|
|
44325
|
-
logger41.log({
|
|
44326
|
-
level: "error",
|
|
44327
|
-
message: error.message
|
|
44328
|
-
});
|
|
44329
|
-
if (error instanceof AppError27) {
|
|
44330
|
-
throw error;
|
|
44331
|
-
} else {
|
|
44332
|
-
throw new Error("Failed to update building.");
|
|
44333
|
-
}
|
|
44694
|
+
value._id = new ObjectId44(value._id);
|
|
44695
|
+
} catch (error2) {
|
|
44696
|
+
throw new Error("Invalid _id.");
|
|
44334
44697
|
}
|
|
44335
44698
|
}
|
|
44336
|
-
|
|
44337
|
-
search = "",
|
|
44338
|
-
page = 1,
|
|
44339
|
-
limit = 10,
|
|
44340
|
-
sort = {},
|
|
44341
|
-
school = "",
|
|
44342
|
-
status = "active"
|
|
44343
|
-
} = {}) {
|
|
44344
|
-
page = page > 0 ? page - 1 : 0;
|
|
44345
|
-
const query = {
|
|
44346
|
-
status
|
|
44347
|
-
};
|
|
44348
|
-
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
44349
|
-
if (search) {
|
|
44350
|
-
query.$text = { $search: search };
|
|
44351
|
-
}
|
|
44352
|
-
if (school) {
|
|
44353
|
-
try {
|
|
44354
|
-
query.school = new ObjectId44(school);
|
|
44355
|
-
} catch (error) {
|
|
44356
|
-
throw new BadRequestError71("Invalid school ID.");
|
|
44357
|
-
}
|
|
44358
|
-
}
|
|
44359
|
-
const cacheParams = {
|
|
44360
|
-
page,
|
|
44361
|
-
limit,
|
|
44362
|
-
sort: JSON.stringify(sort)
|
|
44363
|
-
};
|
|
44364
|
-
if (search)
|
|
44365
|
-
cacheParams.search = search;
|
|
44366
|
-
if (school)
|
|
44367
|
-
cacheParams.school = school;
|
|
44368
|
-
if (status !== "active")
|
|
44369
|
-
cacheParams.status = status;
|
|
44370
|
-
const cacheKey = makeCacheKey23(namespace_collection, cacheParams);
|
|
44371
|
-
logger41.log({
|
|
44372
|
-
level: "info",
|
|
44373
|
-
message: `Cache key for getAll buildings: ${cacheKey}`
|
|
44374
|
-
});
|
|
44699
|
+
if (value.school && typeof value.school === "string") {
|
|
44375
44700
|
try {
|
|
44376
|
-
|
|
44377
|
-
|
|
44378
|
-
|
|
44379
|
-
level: "info",
|
|
44380
|
-
message: `Cache hit for getAll buildings: ${cacheKey}`
|
|
44381
|
-
});
|
|
44382
|
-
return cached;
|
|
44383
|
-
}
|
|
44384
|
-
const items = await collection.aggregate([
|
|
44385
|
-
{ $match: query },
|
|
44386
|
-
{ $sort: sort },
|
|
44387
|
-
{ $skip: page * limit },
|
|
44388
|
-
{ $limit: limit }
|
|
44389
|
-
]).toArray();
|
|
44390
|
-
const length = await collection.countDocuments(query);
|
|
44391
|
-
const data = paginate22(items, page, limit, length);
|
|
44392
|
-
setCache(cacheKey, data, 600).then(() => {
|
|
44393
|
-
logger41.log({
|
|
44394
|
-
level: "info",
|
|
44395
|
-
message: `Cache set for getAll buildings: ${cacheKey}`
|
|
44396
|
-
});
|
|
44397
|
-
}).catch((err) => {
|
|
44398
|
-
logger41.log({
|
|
44399
|
-
level: "error",
|
|
44400
|
-
message: `Failed to set cache for getAll buildings: ${err.message}`
|
|
44401
|
-
});
|
|
44402
|
-
});
|
|
44403
|
-
return data;
|
|
44404
|
-
} catch (error) {
|
|
44405
|
-
logger41.log({ level: "error", message: `${error}` });
|
|
44406
|
-
throw error;
|
|
44701
|
+
value.school = new ObjectId44(value.school);
|
|
44702
|
+
} catch (error2) {
|
|
44703
|
+
throw new Error("Invalid school.");
|
|
44407
44704
|
}
|
|
44408
44705
|
}
|
|
44409
|
-
|
|
44410
|
-
try {
|
|
44411
|
-
_id = new ObjectId44(_id);
|
|
44412
|
-
} catch (error) {
|
|
44413
|
-
throw new BadRequestError71(namespace_collection + " Invalid ID.");
|
|
44414
|
-
}
|
|
44415
|
-
const cacheKey = makeCacheKey23(namespace_collection, { _id: String(_id) });
|
|
44706
|
+
if (value.section && typeof value.section === "string") {
|
|
44416
44707
|
try {
|
|
44417
|
-
|
|
44418
|
-
|
|
44419
|
-
|
|
44420
|
-
level: "info",
|
|
44421
|
-
message: `Cache hit for getById building: ${cacheKey}`
|
|
44422
|
-
});
|
|
44423
|
-
return cached;
|
|
44424
|
-
}
|
|
44425
|
-
const result = await collection.findOne({
|
|
44426
|
-
_id
|
|
44427
|
-
});
|
|
44428
|
-
setCache(cacheKey, result, 300).then(() => {
|
|
44429
|
-
logger41.log({
|
|
44430
|
-
level: "info",
|
|
44431
|
-
message: `Cache set for building by id: ${cacheKey}`
|
|
44432
|
-
});
|
|
44433
|
-
}).catch((err) => {
|
|
44434
|
-
logger41.log({
|
|
44435
|
-
level: "error",
|
|
44436
|
-
message: `Failed to set cache for building by id: ${err.message}`
|
|
44437
|
-
});
|
|
44438
|
-
});
|
|
44439
|
-
return result;
|
|
44440
|
-
} catch (error) {
|
|
44441
|
-
if (error instanceof AppError27) {
|
|
44442
|
-
throw error;
|
|
44443
|
-
} else {
|
|
44444
|
-
throw new InternalServerError23("Failed to get building.");
|
|
44445
|
-
}
|
|
44708
|
+
value.section = new ObjectId44(value.section);
|
|
44709
|
+
} catch (error2) {
|
|
44710
|
+
throw new Error("Invalid section.");
|
|
44446
44711
|
}
|
|
44447
44712
|
}
|
|
44448
|
-
|
|
44449
|
-
try {
|
|
44450
|
-
_id = new ObjectId44(_id);
|
|
44451
|
-
} catch (error) {
|
|
44452
|
-
throw new BadRequestError71(namespace_collection + " Invalid ID.");
|
|
44453
|
-
}
|
|
44713
|
+
if (value.classroom && typeof value.classroom === "string") {
|
|
44454
44714
|
try {
|
|
44455
|
-
|
|
44456
|
-
|
|
44457
|
-
|
|
44458
|
-
);
|
|
44459
|
-
delCachedData();
|
|
44460
|
-
return res;
|
|
44461
|
-
} catch (error) {
|
|
44462
|
-
logger41.log({
|
|
44463
|
-
level: "error",
|
|
44464
|
-
message: error.message
|
|
44465
|
-
});
|
|
44466
|
-
if (error instanceof AppError27) {
|
|
44467
|
-
throw error;
|
|
44468
|
-
} else {
|
|
44469
|
-
throw new InternalServerError23("Failed to delete building.");
|
|
44470
|
-
}
|
|
44715
|
+
value.classroom = new ObjectId44(value.classroom);
|
|
44716
|
+
} catch (error2) {
|
|
44717
|
+
throw new Error("Invalid classroom.");
|
|
44471
44718
|
}
|
|
44472
44719
|
}
|
|
44473
|
-
function delCachedData() {
|
|
44474
|
-
delNamespace().then(() => {
|
|
44475
|
-
logger41.log({
|
|
44476
|
-
level: "info",
|
|
44477
|
-
message: `Cache namespace cleared for ${namespace_collection}`
|
|
44478
|
-
});
|
|
44479
|
-
}).catch((err) => {
|
|
44480
|
-
logger41.log({
|
|
44481
|
-
level: "error",
|
|
44482
|
-
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
44483
|
-
});
|
|
44484
|
-
});
|
|
44485
|
-
}
|
|
44486
44720
|
return {
|
|
44487
|
-
|
|
44488
|
-
|
|
44489
|
-
|
|
44490
|
-
|
|
44491
|
-
|
|
44492
|
-
|
|
44721
|
+
_id: value._id,
|
|
44722
|
+
title: value.title,
|
|
44723
|
+
section: value.section,
|
|
44724
|
+
sectionName: value.sectionName ?? "",
|
|
44725
|
+
classroom: value.classroom,
|
|
44726
|
+
classroomName: value.classroomName ?? "",
|
|
44727
|
+
blockTimes: value.blockTimes,
|
|
44728
|
+
type: value.type,
|
|
44729
|
+
durationMinutes: value.durationMinutes ?? 0,
|
|
44730
|
+
status: value.status ?? "active",
|
|
44731
|
+
school: value.school,
|
|
44732
|
+
schoolYear: value.schoolYear ?? "",
|
|
44733
|
+
createdAt: value.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
44734
|
+
updatedAt: value.updatedAt ?? "",
|
|
44735
|
+
deletedAt: value.deletedAt ?? ""
|
|
44493
44736
|
};
|
|
44494
44737
|
}
|
|
44495
44738
|
|
|
44496
|
-
// src/resources/
|
|
44497
|
-
import {
|
|
44498
|
-
BadRequestError as BadRequestError73,
|
|
44499
|
-
NotFoundError as NotFoundError3,
|
|
44500
|
-
useAtlas as useAtlas34
|
|
44501
|
-
} from "@eeplatform/nodejs-utils";
|
|
44502
|
-
|
|
44503
|
-
// src/resources/building/building-unit.repository.ts
|
|
44739
|
+
// src/resources/kindergarten-routine/kindergarten.routine.repository.ts
|
|
44504
44740
|
import {
|
|
44505
44741
|
AppError as AppError28,
|
|
44506
|
-
BadRequestError as
|
|
44742
|
+
BadRequestError as BadRequestError74,
|
|
44507
44743
|
InternalServerError as InternalServerError24,
|
|
44508
|
-
logger as
|
|
44744
|
+
logger as logger43,
|
|
44509
44745
|
makeCacheKey as makeCacheKey24,
|
|
44510
44746
|
paginate as paginate23,
|
|
44511
|
-
useAtlas as
|
|
44747
|
+
useAtlas as useAtlas35,
|
|
44512
44748
|
useCache as useCache24
|
|
44513
44749
|
} from "@eeplatform/nodejs-utils";
|
|
44514
44750
|
import { ObjectId as ObjectId45 } from "mongodb";
|
|
44515
|
-
function
|
|
44516
|
-
const db =
|
|
44751
|
+
function useKindergartenRoutineRepo() {
|
|
44752
|
+
const db = useAtlas35.getDb();
|
|
44517
44753
|
if (!db) {
|
|
44518
44754
|
throw new Error("Unable to connect to server.");
|
|
44519
44755
|
}
|
|
44520
|
-
const namespace_collection = "deped.
|
|
44756
|
+
const namespace_collection = "deped.kindergarten.routines";
|
|
44521
44757
|
const collection = db.collection(namespace_collection);
|
|
44522
44758
|
const { getCache, setCache, delNamespace } = useCache24(namespace_collection);
|
|
44523
44759
|
async function createIndexes() {
|
|
44524
44760
|
try {
|
|
44525
44761
|
await collection.createIndexes([
|
|
44526
|
-
{
|
|
44527
|
-
|
|
44528
|
-
|
|
44529
|
-
|
|
44530
|
-
},
|
|
44531
|
-
{ key: { school: 1 } },
|
|
44532
|
-
{ key: { building: 1 } },
|
|
44533
|
-
{ key: { status: 1 } },
|
|
44762
|
+
{ key: { section: 1 } },
|
|
44763
|
+
{ key: { classroom: 1 } },
|
|
44764
|
+
{ key: { schedule: 1 } },
|
|
44765
|
+
{ key: { type: 1 } },
|
|
44534
44766
|
{ key: { createdAt: 1 } },
|
|
44767
|
+
{ key: { createdBy: 1 } },
|
|
44768
|
+
{ key: { sectionName: "text", classroomName: "text" } },
|
|
44535
44769
|
{
|
|
44536
|
-
key: {
|
|
44537
|
-
|
|
44538
|
-
|
|
44539
|
-
category: "text",
|
|
44540
|
-
type: "text"
|
|
44541
|
-
}
|
|
44770
|
+
key: { title: 1, school: 1, type: 1, section: 1, status: 1 },
|
|
44771
|
+
unique: true,
|
|
44772
|
+
name: "unique_kindergarten_routine"
|
|
44542
44773
|
}
|
|
44543
44774
|
]);
|
|
44544
44775
|
} catch (error) {
|
|
44545
|
-
throw new Error("Failed to create index on
|
|
44776
|
+
throw new Error("Failed to create index on kindergarten routines.");
|
|
44546
44777
|
}
|
|
44547
44778
|
}
|
|
44548
44779
|
function delCachedData() {
|
|
44549
44780
|
delNamespace().then(() => {
|
|
44550
|
-
|
|
44781
|
+
logger43.log({
|
|
44551
44782
|
level: "info",
|
|
44552
44783
|
message: `Cache namespace cleared for ${namespace_collection}`
|
|
44553
44784
|
});
|
|
44554
44785
|
}).catch((err) => {
|
|
44555
|
-
|
|
44786
|
+
logger43.log({
|
|
44556
44787
|
level: "error",
|
|
44557
44788
|
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
44558
44789
|
});
|
|
@@ -44560,79 +44791,23 @@ function useBuildingUnitRepo() {
|
|
|
44560
44791
|
}
|
|
44561
44792
|
async function add(value, session) {
|
|
44562
44793
|
try {
|
|
44563
|
-
value =
|
|
44794
|
+
value = modelKindergartenRoutine(value);
|
|
44564
44795
|
const res = await collection.insertOne(value, { session });
|
|
44565
44796
|
delCachedData();
|
|
44566
44797
|
return res.insertedId;
|
|
44567
44798
|
} catch (error) {
|
|
44568
|
-
|
|
44799
|
+
logger43.log({
|
|
44569
44800
|
level: "error",
|
|
44570
44801
|
message: error.message
|
|
44571
44802
|
});
|
|
44572
44803
|
if (error instanceof AppError28) {
|
|
44573
44804
|
throw error;
|
|
44574
44805
|
} else {
|
|
44575
|
-
|
|
44576
|
-
|
|
44577
|
-
|
|
44578
|
-
|
|
44579
|
-
|
|
44580
|
-
const { error } = schemaUpdateOptions.validate(value);
|
|
44581
|
-
if (error) {
|
|
44582
|
-
throw new BadRequestError72(error.message);
|
|
44583
|
-
}
|
|
44584
|
-
try {
|
|
44585
|
-
_id = new ObjectId45(_id);
|
|
44586
|
-
} catch (error2) {
|
|
44587
|
-
throw new BadRequestError72(namespace_collection + " Invalid ID.");
|
|
44588
|
-
}
|
|
44589
|
-
try {
|
|
44590
|
-
const res = await collection.updateOne(
|
|
44591
|
-
{ _id },
|
|
44592
|
-
{ $set: value },
|
|
44593
|
-
{ session }
|
|
44594
|
-
);
|
|
44595
|
-
delCachedData();
|
|
44596
|
-
return res;
|
|
44597
|
-
} catch (error2) {
|
|
44598
|
-
logger42.log({
|
|
44599
|
-
level: "error",
|
|
44600
|
-
message: error2.message
|
|
44601
|
-
});
|
|
44602
|
-
if (error2 instanceof AppError28) {
|
|
44603
|
-
throw error2;
|
|
44604
|
-
} else {
|
|
44605
|
-
throw new Error("Failed to create building unit.");
|
|
44606
|
-
}
|
|
44607
|
-
}
|
|
44608
|
-
}
|
|
44609
|
-
async function updateByBuildingId(building, value, session) {
|
|
44610
|
-
const { error } = schemaUpdateOptions.validate(value);
|
|
44611
|
-
if (error) {
|
|
44612
|
-
throw new BadRequestError72(error.message);
|
|
44613
|
-
}
|
|
44614
|
-
try {
|
|
44615
|
-
building = new ObjectId45(building);
|
|
44616
|
-
} catch (error2) {
|
|
44617
|
-
throw new BadRequestError72("Invalid building ID.");
|
|
44618
|
-
}
|
|
44619
|
-
try {
|
|
44620
|
-
const res = await collection.updateMany(
|
|
44621
|
-
{ building },
|
|
44622
|
-
{ $set: value },
|
|
44623
|
-
{ session }
|
|
44624
|
-
);
|
|
44625
|
-
delCachedData();
|
|
44626
|
-
return res;
|
|
44627
|
-
} catch (error2) {
|
|
44628
|
-
logger42.log({
|
|
44629
|
-
level: "error",
|
|
44630
|
-
message: error2.message
|
|
44631
|
-
});
|
|
44632
|
-
if (error2 instanceof AppError28) {
|
|
44633
|
-
throw error2;
|
|
44634
|
-
} else {
|
|
44635
|
-
throw new Error("Failed to update building unit.");
|
|
44806
|
+
const isDuplicated = error.message.includes("duplicate");
|
|
44807
|
+
if (isDuplicated) {
|
|
44808
|
+
throw new BadRequestError74("Kinder schedule already exists.");
|
|
44809
|
+
}
|
|
44810
|
+
throw new Error("Failed to create kindergarten routine.");
|
|
44636
44811
|
}
|
|
44637
44812
|
}
|
|
44638
44813
|
}
|
|
@@ -44641,57 +44816,81 @@ function useBuildingUnitRepo() {
|
|
|
44641
44816
|
page = 1,
|
|
44642
44817
|
limit = 10,
|
|
44643
44818
|
sort = {},
|
|
44819
|
+
status = "active",
|
|
44820
|
+
createdBy,
|
|
44644
44821
|
school = "",
|
|
44645
|
-
|
|
44822
|
+
section = "",
|
|
44823
|
+
classroom = "",
|
|
44646
44824
|
type = "",
|
|
44647
|
-
|
|
44825
|
+
schoolYear = ""
|
|
44648
44826
|
} = {}) {
|
|
44649
44827
|
page = page > 0 ? page - 1 : 0;
|
|
44650
44828
|
const query = {
|
|
44651
44829
|
deletedAt: { $in: ["", null] },
|
|
44652
|
-
status
|
|
44830
|
+
status
|
|
44653
44831
|
};
|
|
44654
|
-
|
|
44832
|
+
sort = Object.keys(sort).length > 0 ? sort : { _id: 1 };
|
|
44833
|
+
const cacheKeyOptions = {
|
|
44834
|
+
status,
|
|
44655
44835
|
page,
|
|
44656
44836
|
limit,
|
|
44657
44837
|
sort: JSON.stringify(sort)
|
|
44658
44838
|
};
|
|
44659
|
-
|
|
44839
|
+
if (createdBy) {
|
|
44840
|
+
try {
|
|
44841
|
+
query.createdBy = new ObjectId45(createdBy);
|
|
44842
|
+
} catch (error) {
|
|
44843
|
+
throw new BadRequestError74("Invalid createdBy ID.");
|
|
44844
|
+
}
|
|
44845
|
+
cacheKeyOptions.createdBy = createdBy;
|
|
44846
|
+
}
|
|
44660
44847
|
if (search) {
|
|
44661
44848
|
query.$text = { $search: search };
|
|
44662
|
-
|
|
44849
|
+
cacheKeyOptions.search = search;
|
|
44850
|
+
}
|
|
44851
|
+
if (school) {
|
|
44852
|
+
try {
|
|
44853
|
+
query.school = new ObjectId45(school);
|
|
44854
|
+
} catch (error) {
|
|
44855
|
+
throw new BadRequestError74("Invalid school ID.");
|
|
44856
|
+
}
|
|
44857
|
+
cacheKeyOptions.school = school;
|
|
44663
44858
|
}
|
|
44664
|
-
if (
|
|
44859
|
+
if (section) {
|
|
44665
44860
|
try {
|
|
44666
|
-
query.
|
|
44861
|
+
query.section = new ObjectId45(section);
|
|
44667
44862
|
} catch (error) {
|
|
44668
|
-
throw new
|
|
44863
|
+
throw new BadRequestError74("Invalid section ID.");
|
|
44669
44864
|
}
|
|
44670
|
-
|
|
44865
|
+
cacheKeyOptions.section = section;
|
|
44671
44866
|
}
|
|
44672
|
-
if (
|
|
44867
|
+
if (classroom) {
|
|
44673
44868
|
try {
|
|
44674
|
-
query.
|
|
44869
|
+
query.classroom = new ObjectId45(classroom);
|
|
44675
44870
|
} catch (error) {
|
|
44676
|
-
throw new
|
|
44871
|
+
throw new BadRequestError74("Invalid classroom ID.");
|
|
44677
44872
|
}
|
|
44678
|
-
|
|
44873
|
+
cacheKeyOptions.classroom = classroom;
|
|
44679
44874
|
}
|
|
44680
44875
|
if (type) {
|
|
44681
44876
|
query.type = type;
|
|
44682
|
-
|
|
44877
|
+
cacheKeyOptions.type = type;
|
|
44878
|
+
}
|
|
44879
|
+
if (schoolYear) {
|
|
44880
|
+
query.schoolYear = schoolYear;
|
|
44881
|
+
cacheKeyOptions.schoolYear = schoolYear;
|
|
44683
44882
|
}
|
|
44684
|
-
const cacheKey = makeCacheKey24(namespace_collection,
|
|
44685
|
-
|
|
44883
|
+
const cacheKey = makeCacheKey24(namespace_collection, cacheKeyOptions);
|
|
44884
|
+
logger43.log({
|
|
44686
44885
|
level: "info",
|
|
44687
|
-
message: `Cache key for getAll
|
|
44886
|
+
message: `Cache key for getAll kindergarten routines: ${cacheKey}`
|
|
44688
44887
|
});
|
|
44689
44888
|
try {
|
|
44690
44889
|
const cached = await getCache(cacheKey);
|
|
44691
44890
|
if (cached) {
|
|
44692
|
-
|
|
44891
|
+
logger43.log({
|
|
44693
44892
|
level: "info",
|
|
44694
|
-
message: `Cache hit for getAll
|
|
44893
|
+
message: `Cache hit for getAll kindergarten routines: ${cacheKey}`
|
|
44695
44894
|
});
|
|
44696
44895
|
return cached;
|
|
44697
44896
|
}
|
|
@@ -44704,60 +44903,35 @@ function useBuildingUnitRepo() {
|
|
|
44704
44903
|
const length = await collection.countDocuments(query);
|
|
44705
44904
|
const data = paginate23(items, page, limit, length);
|
|
44706
44905
|
setCache(cacheKey, data, 600).then(() => {
|
|
44707
|
-
|
|
44906
|
+
logger43.log({
|
|
44708
44907
|
level: "info",
|
|
44709
|
-
message: `Cache set for getAll
|
|
44908
|
+
message: `Cache set for getAll kindergarten routines: ${cacheKey}`
|
|
44710
44909
|
});
|
|
44711
44910
|
}).catch((err) => {
|
|
44712
|
-
|
|
44911
|
+
logger43.log({
|
|
44713
44912
|
level: "error",
|
|
44714
|
-
message: `Failed to set cache for getAll
|
|
44913
|
+
message: `Failed to set cache for getAll kindergarten routines: ${err.message}`
|
|
44715
44914
|
});
|
|
44716
44915
|
});
|
|
44717
44916
|
return data;
|
|
44718
44917
|
} catch (error) {
|
|
44719
|
-
|
|
44918
|
+
logger43.log({ level: "error", message: `${error}` });
|
|
44720
44919
|
throw error;
|
|
44721
44920
|
}
|
|
44722
44921
|
}
|
|
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
44922
|
async function getById(_id) {
|
|
44749
44923
|
try {
|
|
44750
44924
|
_id = new ObjectId45(_id);
|
|
44751
44925
|
} catch (error) {
|
|
44752
|
-
throw new
|
|
44926
|
+
throw new BadRequestError74(namespace_collection + " Invalid ID.");
|
|
44753
44927
|
}
|
|
44754
44928
|
const cacheKey = makeCacheKey24(namespace_collection, { _id: String(_id) });
|
|
44755
44929
|
try {
|
|
44756
44930
|
const cached = await getCache(cacheKey);
|
|
44757
44931
|
if (cached) {
|
|
44758
|
-
|
|
44932
|
+
logger43.log({
|
|
44759
44933
|
level: "info",
|
|
44760
|
-
message: `Cache hit for getById
|
|
44934
|
+
message: `Cache hit for getById kindergarten routine: ${cacheKey}`
|
|
44761
44935
|
});
|
|
44762
44936
|
return cached;
|
|
44763
44937
|
}
|
|
@@ -44765,18 +44939,15 @@ function useBuildingUnitRepo() {
|
|
|
44765
44939
|
_id,
|
|
44766
44940
|
deletedAt: { $in: ["", null] }
|
|
44767
44941
|
});
|
|
44768
|
-
if (!result) {
|
|
44769
|
-
throw new BadRequestError72("Building unit not found.");
|
|
44770
|
-
}
|
|
44771
44942
|
setCache(cacheKey, result, 300).then(() => {
|
|
44772
|
-
|
|
44943
|
+
logger43.log({
|
|
44773
44944
|
level: "info",
|
|
44774
|
-
message: `Cache set for
|
|
44945
|
+
message: `Cache set for kindergarten routine by id: ${cacheKey}`
|
|
44775
44946
|
});
|
|
44776
44947
|
}).catch((err) => {
|
|
44777
|
-
|
|
44948
|
+
logger43.log({
|
|
44778
44949
|
level: "error",
|
|
44779
|
-
message: `Failed to set cache for
|
|
44950
|
+
message: `Failed to set cache for kindergarten routine by id: ${err.message}`
|
|
44780
44951
|
});
|
|
44781
44952
|
});
|
|
44782
44953
|
return result;
|
|
@@ -44784,43 +44955,37 @@ function useBuildingUnitRepo() {
|
|
|
44784
44955
|
if (error instanceof AppError28) {
|
|
44785
44956
|
throw error;
|
|
44786
44957
|
} else {
|
|
44787
|
-
throw new InternalServerError24("Failed to get
|
|
44958
|
+
throw new InternalServerError24("Failed to get kindergarten routine.");
|
|
44788
44959
|
}
|
|
44789
44960
|
}
|
|
44790
44961
|
}
|
|
44791
|
-
async function
|
|
44792
|
-
try {
|
|
44793
|
-
building = new ObjectId45(building);
|
|
44794
|
-
} catch (error) {
|
|
44795
|
-
throw new BadRequestError72("Invalid building ID.");
|
|
44796
|
-
}
|
|
44962
|
+
async function countByDomain(domain) {
|
|
44797
44963
|
const cacheKey = makeCacheKey24(namespace_collection, {
|
|
44798
|
-
|
|
44799
|
-
|
|
44964
|
+
domain,
|
|
44965
|
+
tag: "getByDomain"
|
|
44800
44966
|
});
|
|
44801
44967
|
try {
|
|
44802
44968
|
const cached = await getCache(cacheKey);
|
|
44803
44969
|
if (cached) {
|
|
44804
|
-
|
|
44970
|
+
logger43.log({
|
|
44805
44971
|
level: "info",
|
|
44806
|
-
message: `Cache hit for getById
|
|
44972
|
+
message: `Cache hit for getById kindergarten routine: ${cacheKey}`
|
|
44807
44973
|
});
|
|
44808
44974
|
return cached;
|
|
44809
44975
|
}
|
|
44810
|
-
const result = await collection.
|
|
44811
|
-
|
|
44812
|
-
level,
|
|
44976
|
+
const result = await collection.countDocuments({
|
|
44977
|
+
domain,
|
|
44813
44978
|
status: "active"
|
|
44814
44979
|
});
|
|
44815
44980
|
setCache(cacheKey, result, 300).then(() => {
|
|
44816
|
-
|
|
44981
|
+
logger43.log({
|
|
44817
44982
|
level: "info",
|
|
44818
|
-
message: `Cache set for
|
|
44983
|
+
message: `Cache set for kindergarten routine by id: ${cacheKey}`
|
|
44819
44984
|
});
|
|
44820
44985
|
}).catch((err) => {
|
|
44821
|
-
|
|
44986
|
+
logger43.log({
|
|
44822
44987
|
level: "error",
|
|
44823
|
-
message: `Failed to set cache for
|
|
44988
|
+
message: `Failed to set cache for kindergarten routine by id: ${err.message}`
|
|
44824
44989
|
});
|
|
44825
44990
|
});
|
|
44826
44991
|
return result;
|
|
@@ -44828,41 +44993,41 @@ function useBuildingUnitRepo() {
|
|
|
44828
44993
|
if (error instanceof AppError28) {
|
|
44829
44994
|
throw error;
|
|
44830
44995
|
} else {
|
|
44831
|
-
throw new InternalServerError24("Failed to get
|
|
44996
|
+
throw new InternalServerError24("Failed to get kindergarten routine.");
|
|
44832
44997
|
}
|
|
44833
44998
|
}
|
|
44834
44999
|
}
|
|
44835
|
-
async function
|
|
45000
|
+
async function getBySection(section) {
|
|
44836
45001
|
try {
|
|
44837
|
-
|
|
45002
|
+
section = new ObjectId45(section);
|
|
44838
45003
|
} catch (error) {
|
|
44839
|
-
throw new
|
|
45004
|
+
throw new BadRequestError74("Invalid section ID.");
|
|
44840
45005
|
}
|
|
44841
45006
|
const cacheKey = makeCacheKey24(namespace_collection, {
|
|
44842
|
-
|
|
45007
|
+
section: String(section)
|
|
44843
45008
|
});
|
|
44844
45009
|
try {
|
|
44845
45010
|
const cached = await getCache(cacheKey);
|
|
44846
45011
|
if (cached) {
|
|
44847
|
-
|
|
45012
|
+
logger43.log({
|
|
44848
45013
|
level: "info",
|
|
44849
|
-
message: `Cache hit for
|
|
45014
|
+
message: `Cache hit for getBySection kindergarten routine: ${cacheKey}`
|
|
44850
45015
|
});
|
|
44851
45016
|
return cached;
|
|
44852
45017
|
}
|
|
44853
|
-
const result = await collection.
|
|
44854
|
-
|
|
44855
|
-
|
|
44856
|
-
});
|
|
45018
|
+
const result = await collection.find({
|
|
45019
|
+
section,
|
|
45020
|
+
deletedAt: { $in: ["", null] }
|
|
45021
|
+
}).toArray();
|
|
44857
45022
|
setCache(cacheKey, result, 300).then(() => {
|
|
44858
|
-
|
|
45023
|
+
logger43.log({
|
|
44859
45024
|
level: "info",
|
|
44860
|
-
message: `Cache set for
|
|
45025
|
+
message: `Cache set for kindergarten routine by section: ${cacheKey}`
|
|
44861
45026
|
});
|
|
44862
45027
|
}).catch((err) => {
|
|
44863
|
-
|
|
45028
|
+
logger43.log({
|
|
44864
45029
|
level: "error",
|
|
44865
|
-
message: `Failed to set cache for
|
|
45030
|
+
message: `Failed to set cache for kindergarten routine by section: ${err.message}`
|
|
44866
45031
|
});
|
|
44867
45032
|
});
|
|
44868
45033
|
return result;
|
|
@@ -44870,200 +45035,180 @@ function useBuildingUnitRepo() {
|
|
|
44870
45035
|
if (error instanceof AppError28) {
|
|
44871
45036
|
throw error;
|
|
44872
45037
|
} else {
|
|
44873
|
-
throw new InternalServerError24("Failed to get
|
|
45038
|
+
throw new InternalServerError24("Failed to get kindergarten routine.");
|
|
44874
45039
|
}
|
|
44875
45040
|
}
|
|
44876
45041
|
}
|
|
44877
|
-
async function
|
|
45042
|
+
async function updateFieldById({ _id, field, value } = {}, session) {
|
|
45043
|
+
const allowedFields = [
|
|
45044
|
+
"sectionName",
|
|
45045
|
+
"classroomName",
|
|
45046
|
+
"schedule",
|
|
45047
|
+
"blockTimes",
|
|
45048
|
+
"type"
|
|
45049
|
+
];
|
|
45050
|
+
if (!allowedFields.includes(field)) {
|
|
45051
|
+
throw new BadRequestError74(
|
|
45052
|
+
`Field "${field}" is not allowed to be updated.`
|
|
45053
|
+
);
|
|
45054
|
+
}
|
|
44878
45055
|
try {
|
|
44879
45056
|
_id = new ObjectId45(_id);
|
|
44880
45057
|
} catch (error) {
|
|
44881
|
-
throw new
|
|
45058
|
+
throw new BadRequestError74(namespace_collection + " Invalid ID.");
|
|
44882
45059
|
}
|
|
44883
45060
|
try {
|
|
44884
|
-
|
|
44885
|
-
{ _id },
|
|
44886
|
-
{ $set: {
|
|
45061
|
+
await collection.updateOne(
|
|
45062
|
+
{ _id, deletedAt: { $in: ["", null] } },
|
|
45063
|
+
{ $set: { [field]: value, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
|
|
44887
45064
|
{ session }
|
|
44888
45065
|
);
|
|
44889
45066
|
delCachedData();
|
|
44890
|
-
return
|
|
45067
|
+
return `Successfully updated kindergarten routine ${field}.`;
|
|
44891
45068
|
} 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
|
-
}
|
|
45069
|
+
throw new InternalServerError24(
|
|
45070
|
+
`Failed to update kindergarten routine ${field}.`
|
|
45071
|
+
);
|
|
44901
45072
|
}
|
|
44902
45073
|
}
|
|
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();
|
|
45074
|
+
async function updateById(_id, value, session) {
|
|
45075
|
+
const { error } = schemaKindergartenRoutineUpdate.validate(value);
|
|
45076
|
+
if (error) {
|
|
45077
|
+
throw new BadRequestError74(
|
|
45078
|
+
`Invalid kindergarten routine data: ${error.message}`
|
|
45079
|
+
);
|
|
45080
|
+
}
|
|
44928
45081
|
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();
|
|
45082
|
+
_id = new ObjectId45(_id);
|
|
45083
|
+
} catch (error2) {
|
|
45084
|
+
throw new BadRequestError74(namespace_collection + " Invalid ID.");
|
|
44953
45085
|
}
|
|
44954
|
-
|
|
44955
|
-
|
|
44956
|
-
|
|
44957
|
-
|
|
44958
|
-
|
|
44959
|
-
"Cannot delete building with existing room/facility. Please delete room/facility first."
|
|
45086
|
+
try {
|
|
45087
|
+
await collection.updateOne(
|
|
45088
|
+
{ _id },
|
|
45089
|
+
{ $set: { ...value, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
|
|
45090
|
+
{ session }
|
|
44960
45091
|
);
|
|
45092
|
+
delCachedData();
|
|
45093
|
+
return `Successfully updated kindergarten routine.`;
|
|
45094
|
+
} catch (error2) {
|
|
45095
|
+
throw new InternalServerError24("Failed to update kindergarten routine.");
|
|
45096
|
+
}
|
|
45097
|
+
}
|
|
45098
|
+
async function deleteById(_id) {
|
|
45099
|
+
try {
|
|
45100
|
+
_id = new ObjectId45(_id);
|
|
45101
|
+
} catch (error) {
|
|
45102
|
+
throw new BadRequestError74(namespace_collection + " Invalid ID.");
|
|
44961
45103
|
}
|
|
44962
45104
|
try {
|
|
44963
|
-
await
|
|
44964
|
-
|
|
45105
|
+
await collection.updateOne(
|
|
45106
|
+
{ _id },
|
|
45107
|
+
{ $set: { status: "deleted", deletedAt: (/* @__PURE__ */ new Date()).toISOString() } }
|
|
45108
|
+
);
|
|
45109
|
+
delCachedData();
|
|
45110
|
+
return "Successfully deleted kindergarten routine.";
|
|
44965
45111
|
} catch (error) {
|
|
44966
|
-
throw
|
|
45112
|
+
throw new InternalServerError24("Failed to delete kindergarten routine.");
|
|
44967
45113
|
}
|
|
44968
45114
|
}
|
|
44969
45115
|
return {
|
|
45116
|
+
createIndexes,
|
|
45117
|
+
add,
|
|
45118
|
+
getAll,
|
|
45119
|
+
getById,
|
|
45120
|
+
countByDomain,
|
|
45121
|
+
getBySection,
|
|
45122
|
+
updateFieldById,
|
|
44970
45123
|
updateById,
|
|
44971
45124
|
deleteById
|
|
44972
45125
|
};
|
|
44973
45126
|
}
|
|
44974
45127
|
|
|
44975
|
-
// src/resources/
|
|
44976
|
-
import { BadRequestError as
|
|
44977
|
-
import
|
|
44978
|
-
function
|
|
44979
|
-
const {
|
|
44980
|
-
|
|
44981
|
-
|
|
45128
|
+
// src/resources/kindergarten-routine/kindergarten.routine.controller.ts
|
|
45129
|
+
import { BadRequestError as BadRequestError75 } from "@eeplatform/nodejs-utils";
|
|
45130
|
+
import Joi49 from "joi";
|
|
45131
|
+
function useKindergartenRoutineController() {
|
|
45132
|
+
const {
|
|
45133
|
+
add: _add,
|
|
45134
|
+
getAll: _getAll,
|
|
45135
|
+
getById: _getById,
|
|
45136
|
+
getBySection: _getBySection,
|
|
45137
|
+
updateFieldById: _updateFieldById,
|
|
45138
|
+
deleteById: _deleteById,
|
|
45139
|
+
updateById: _updateById
|
|
45140
|
+
} = useKindergartenRoutineRepo();
|
|
45141
|
+
async function add(req, res, next) {
|
|
44982
45142
|
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);
|
|
45143
|
+
const { error } = schemaKindergartenRoutine.validate(value);
|
|
44991
45144
|
if (error) {
|
|
44992
|
-
next(new
|
|
44993
|
-
logger43.info(`Controller: ${error.message}`);
|
|
45145
|
+
next(new BadRequestError75(error.message));
|
|
44994
45146
|
return;
|
|
44995
45147
|
}
|
|
44996
45148
|
try {
|
|
44997
|
-
const
|
|
44998
|
-
res.json(
|
|
45149
|
+
const data = await _add(value);
|
|
45150
|
+
res.json({
|
|
45151
|
+
message: "Successfully created kinder schedule.",
|
|
45152
|
+
data
|
|
45153
|
+
});
|
|
44999
45154
|
return;
|
|
45000
45155
|
} catch (error2) {
|
|
45001
45156
|
next(error2);
|
|
45002
45157
|
}
|
|
45003
45158
|
}
|
|
45004
|
-
async function
|
|
45005
|
-
const
|
|
45006
|
-
const
|
|
45007
|
-
|
|
45008
|
-
|
|
45009
|
-
|
|
45010
|
-
|
|
45011
|
-
|
|
45012
|
-
|
|
45013
|
-
|
|
45159
|
+
async function getAll(req, res, next) {
|
|
45160
|
+
const query = req.query;
|
|
45161
|
+
const validation = Joi49.object({
|
|
45162
|
+
page: Joi49.number().min(1).optional().allow("", null),
|
|
45163
|
+
limit: Joi49.number().min(1).optional().allow("", null),
|
|
45164
|
+
search: Joi49.string().optional().allow("", null),
|
|
45165
|
+
status: Joi49.string().optional().allow("", null),
|
|
45166
|
+
school: Joi49.string().hex().optional().allow("", null),
|
|
45167
|
+
section: Joi49.string().hex().optional().allow("", null),
|
|
45168
|
+
classroom: Joi49.string().hex().optional().allow("", null),
|
|
45169
|
+
type: Joi49.string().optional().allow("", null),
|
|
45170
|
+
createdBy: Joi49.string().hex().optional().allow("", null),
|
|
45171
|
+
schoolYear: Joi49.string().optional().allow("", null)
|
|
45014
45172
|
});
|
|
45015
|
-
const { error } = validation.validate(
|
|
45016
|
-
|
|
45017
|
-
|
|
45018
|
-
|
|
45173
|
+
const { error } = validation.validate(query);
|
|
45174
|
+
const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
|
|
45175
|
+
const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
|
|
45176
|
+
const search = req.query.search ?? "";
|
|
45177
|
+
const status = req.query.status ?? "active";
|
|
45178
|
+
const school = req.query.school ?? "";
|
|
45179
|
+
const section = req.query.section ?? "";
|
|
45180
|
+
const classroom = req.query.classroom ?? "";
|
|
45181
|
+
const type = req.query.type ?? "";
|
|
45182
|
+
const createdBy = req.query.createdBy ?? "";
|
|
45183
|
+
const schoolYear = req.query.schoolYear ?? "";
|
|
45184
|
+
const isPageNumber = isFinite(page);
|
|
45185
|
+
if (!isPageNumber) {
|
|
45186
|
+
next(new BadRequestError75("Invalid page number."));
|
|
45019
45187
|
return;
|
|
45020
45188
|
}
|
|
45021
|
-
|
|
45022
|
-
|
|
45023
|
-
|
|
45189
|
+
const isLimitNumber = isFinite(limit);
|
|
45190
|
+
if (!isLimitNumber) {
|
|
45191
|
+
next(new BadRequestError75("Invalid limit number."));
|
|
45024
45192
|
return;
|
|
45025
|
-
} catch (error2) {
|
|
45026
|
-
next(error2);
|
|
45027
45193
|
}
|
|
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
45194
|
if (error) {
|
|
45040
|
-
next(new
|
|
45195
|
+
next(new BadRequestError75(error.message));
|
|
45041
45196
|
return;
|
|
45042
45197
|
}
|
|
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
45198
|
try {
|
|
45058
|
-
const
|
|
45199
|
+
const data = await _getAll({
|
|
45059
45200
|
page,
|
|
45060
45201
|
limit,
|
|
45061
|
-
|
|
45202
|
+
search,
|
|
45062
45203
|
status,
|
|
45063
45204
|
school,
|
|
45064
|
-
|
|
45205
|
+
section,
|
|
45206
|
+
classroom,
|
|
45207
|
+
type,
|
|
45208
|
+
createdBy: createdBy || void 0,
|
|
45209
|
+
schoolYear
|
|
45065
45210
|
});
|
|
45066
|
-
res.json(
|
|
45211
|
+
res.json(data);
|
|
45067
45212
|
return;
|
|
45068
45213
|
} catch (error2) {
|
|
45069
45214
|
next(error2);
|
|
@@ -45071,260 +45216,100 @@ function useBuildingController() {
|
|
|
45071
45216
|
}
|
|
45072
45217
|
async function getById(req, res, next) {
|
|
45073
45218
|
const id = req.params.id;
|
|
45074
|
-
const validation =
|
|
45075
|
-
id:
|
|
45219
|
+
const validation = Joi49.object({
|
|
45220
|
+
id: Joi49.string().hex().required()
|
|
45076
45221
|
});
|
|
45077
45222
|
const { error } = validation.validate({ id });
|
|
45078
45223
|
if (error) {
|
|
45079
|
-
next(new
|
|
45224
|
+
next(new BadRequestError75(error.message));
|
|
45080
45225
|
return;
|
|
45081
45226
|
}
|
|
45082
45227
|
try {
|
|
45083
|
-
const
|
|
45228
|
+
const data = await _getById(id);
|
|
45084
45229
|
res.json({
|
|
45085
|
-
message: "Successfully retrieved
|
|
45086
|
-
data
|
|
45230
|
+
message: "Successfully retrieved kinder schedule.",
|
|
45231
|
+
data
|
|
45087
45232
|
});
|
|
45088
45233
|
return;
|
|
45089
45234
|
} catch (error2) {
|
|
45090
45235
|
next(error2);
|
|
45091
45236
|
}
|
|
45092
45237
|
}
|
|
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;
|
|
45238
|
+
async function getBySection(req, res, next) {
|
|
45239
|
+
const section = req.params.section;
|
|
45191
45240
|
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)
|
|
45241
|
+
section: Joi49.string().hex().required()
|
|
45208
45242
|
});
|
|
45209
|
-
const { error } = validation.validate(
|
|
45243
|
+
const { error } = validation.validate({ section });
|
|
45210
45244
|
if (error) {
|
|
45211
45245
|
next(new BadRequestError75(error.message));
|
|
45212
45246
|
return;
|
|
45213
45247
|
}
|
|
45214
45248
|
try {
|
|
45215
|
-
const
|
|
45249
|
+
const data = await _getBySection(section);
|
|
45216
45250
|
res.json({
|
|
45217
|
-
message: "
|
|
45218
|
-
data
|
|
45251
|
+
message: "Successfully retrieved kinder schedules.",
|
|
45252
|
+
data
|
|
45219
45253
|
});
|
|
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
45254
|
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
45255
|
} catch (error2) {
|
|
45243
45256
|
next(error2);
|
|
45244
45257
|
}
|
|
45245
45258
|
}
|
|
45246
|
-
async function
|
|
45247
|
-
const
|
|
45259
|
+
async function updateField(req, res, next) {
|
|
45260
|
+
const _id = req.params.id;
|
|
45261
|
+
const { field, value } = req.body;
|
|
45248
45262
|
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)
|
|
45263
|
+
_id: Joi49.string().hex().required(),
|
|
45264
|
+
field: Joi49.string().valid("sectionName", "classroomName", "schedule", "blockTimes", "type").required(),
|
|
45265
|
+
value: Joi49.alternatives().try(Joi49.string(), Joi49.array(), Joi49.object()).required()
|
|
45256
45266
|
});
|
|
45257
|
-
const { error } = validation.validate(
|
|
45267
|
+
const { error } = validation.validate({ _id, field, value });
|
|
45258
45268
|
if (error) {
|
|
45259
45269
|
next(new BadRequestError75(error.message));
|
|
45260
45270
|
return;
|
|
45261
45271
|
}
|
|
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
45272
|
try {
|
|
45279
|
-
const
|
|
45280
|
-
|
|
45281
|
-
limit,
|
|
45282
|
-
sort: sortObj,
|
|
45283
|
-
status,
|
|
45284
|
-
school,
|
|
45285
|
-
search,
|
|
45286
|
-
building,
|
|
45287
|
-
type
|
|
45288
|
-
});
|
|
45289
|
-
res.json(buildings);
|
|
45273
|
+
const message = await _updateFieldById({ _id, field, value });
|
|
45274
|
+
res.json({ message });
|
|
45290
45275
|
return;
|
|
45291
45276
|
} catch (error2) {
|
|
45292
45277
|
next(error2);
|
|
45293
45278
|
}
|
|
45294
45279
|
}
|
|
45295
|
-
async function
|
|
45296
|
-
const
|
|
45297
|
-
const
|
|
45298
|
-
|
|
45299
|
-
|
|
45300
|
-
|
|
45280
|
+
async function updateById(req, res, next) {
|
|
45281
|
+
const _id = req.params.id;
|
|
45282
|
+
const payload = req.body;
|
|
45283
|
+
const { error: errorId } = Joi49.string().hex().required().validate(_id);
|
|
45284
|
+
if (errorId) {
|
|
45285
|
+
next(new BadRequestError75(errorId.message));
|
|
45286
|
+
return;
|
|
45287
|
+
}
|
|
45288
|
+
const { error } = schemaKindergartenRoutineUpdate.validate(payload);
|
|
45301
45289
|
if (error) {
|
|
45302
45290
|
next(new BadRequestError75(error.message));
|
|
45303
45291
|
return;
|
|
45304
45292
|
}
|
|
45305
45293
|
try {
|
|
45306
|
-
const
|
|
45307
|
-
res.json({
|
|
45308
|
-
message: "Successfully retrieved building unit.",
|
|
45309
|
-
data: { buildingUnit }
|
|
45310
|
-
});
|
|
45294
|
+
const message = await _updateById(_id, payload);
|
|
45295
|
+
res.json({ message });
|
|
45311
45296
|
return;
|
|
45312
45297
|
} catch (error2) {
|
|
45313
45298
|
next(error2);
|
|
45314
45299
|
}
|
|
45315
45300
|
}
|
|
45316
45301
|
async function deleteById(req, res, next) {
|
|
45317
|
-
const
|
|
45302
|
+
const _id = req.params.id;
|
|
45318
45303
|
const validation = Joi49.object({
|
|
45319
|
-
|
|
45304
|
+
_id: Joi49.string().hex().required()
|
|
45320
45305
|
});
|
|
45321
|
-
const { error } = validation.validate({
|
|
45306
|
+
const { error } = validation.validate({ _id });
|
|
45322
45307
|
if (error) {
|
|
45323
45308
|
next(new BadRequestError75(error.message));
|
|
45324
45309
|
return;
|
|
45325
45310
|
}
|
|
45326
45311
|
try {
|
|
45327
|
-
const message = await _deleteById(
|
|
45312
|
+
const message = await _deleteById(_id);
|
|
45328
45313
|
res.json({ message });
|
|
45329
45314
|
return;
|
|
45330
45315
|
} catch (error2) {
|
|
@@ -45335,6 +45320,8 @@ function useBuildingUnitController() {
|
|
|
45335
45320
|
add,
|
|
45336
45321
|
getAll,
|
|
45337
45322
|
getById,
|
|
45323
|
+
getBySection,
|
|
45324
|
+
updateField,
|
|
45338
45325
|
updateById,
|
|
45339
45326
|
deleteById
|
|
45340
45327
|
};
|