@eeplatform/basic-edu 1.9.4 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/index.d.ts +127 -2
- package/dist/index.js +1599 -306
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2754 -1453
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -39814,15 +39814,15 @@ function useSectionRepo() {
|
|
|
39814
39814
|
}
|
|
39815
39815
|
|
|
39816
39816
|
// src/resources/section/section.controller.ts
|
|
39817
|
-
import { BadRequestError as
|
|
39818
|
-
import
|
|
39817
|
+
import { BadRequestError as BadRequestError68 } from "@eeplatform/nodejs-utils";
|
|
39818
|
+
import Joi45 from "joi";
|
|
39819
39819
|
|
|
39820
39820
|
// src/resources/section/section.service.ts
|
|
39821
39821
|
import {
|
|
39822
|
-
AppError as
|
|
39823
|
-
BadRequestError as
|
|
39824
|
-
InternalServerError as
|
|
39825
|
-
useAtlas as
|
|
39822
|
+
AppError as AppError26,
|
|
39823
|
+
BadRequestError as BadRequestError67,
|
|
39824
|
+
InternalServerError as InternalServerError22,
|
|
39825
|
+
useAtlas as useAtlas31
|
|
39826
39826
|
} from "@eeplatform/nodejs-utils";
|
|
39827
39827
|
|
|
39828
39828
|
// src/resources/section-student/section.student.repository.ts
|
|
@@ -41557,9 +41557,11 @@ var schemaTeachingLoadSlot = Joi39.object({
|
|
|
41557
41557
|
gradeLevel: Joi39.string().required(),
|
|
41558
41558
|
startTime: Joi39.string().required(),
|
|
41559
41559
|
endTime: Joi39.string().required(),
|
|
41560
|
-
subject: Joi39.string().hex().
|
|
41560
|
+
subject: Joi39.string().hex().optional().allow("", null),
|
|
41561
41561
|
subjectName: Joi39.string().optional().allow("", null),
|
|
41562
41562
|
subjectCode: Joi39.string().optional().allow("", null),
|
|
41563
|
+
routine: Joi39.string().hex().optional().allow("", null),
|
|
41564
|
+
routineName: Joi39.string().optional().allow("", null),
|
|
41563
41565
|
section: Joi39.string().hex().required(),
|
|
41564
41566
|
sectionName: Joi39.string().optional().allow("", null),
|
|
41565
41567
|
duration: Joi39.number().min(0).required(),
|
|
@@ -41595,6 +41597,13 @@ function modelTeachingLoadSlot(value) {
|
|
|
41595
41597
|
throw new BadRequestError58("Invalid subject format");
|
|
41596
41598
|
}
|
|
41597
41599
|
}
|
|
41600
|
+
if (value.routine && typeof value.routine === "string") {
|
|
41601
|
+
try {
|
|
41602
|
+
value.routine = new ObjectId37(value.routine);
|
|
41603
|
+
} catch (error2) {
|
|
41604
|
+
throw new BadRequestError58("Invalid routine format");
|
|
41605
|
+
}
|
|
41606
|
+
}
|
|
41598
41607
|
if (value.section && typeof value.section === "string") {
|
|
41599
41608
|
try {
|
|
41600
41609
|
value.section = new ObjectId37(value.section);
|
|
@@ -41612,9 +41621,11 @@ function modelTeachingLoadSlot(value) {
|
|
|
41612
41621
|
gradeLevel: value.gradeLevel ?? "",
|
|
41613
41622
|
startTime: value.startTime ?? "",
|
|
41614
41623
|
endTime: value.endTime ?? "",
|
|
41615
|
-
subject: value.subject,
|
|
41624
|
+
subject: value.subject ?? "",
|
|
41616
41625
|
subjectName: value.subjectName ?? "",
|
|
41617
41626
|
subjectCode: value.subjectCode ?? "",
|
|
41627
|
+
routine: value.routine ?? "",
|
|
41628
|
+
routineName: value.routineName ?? "",
|
|
41618
41629
|
section: value.section,
|
|
41619
41630
|
sectionName: value.sectionName ?? "",
|
|
41620
41631
|
duration: value.duration ?? 0,
|
|
@@ -42786,142 +42797,834 @@ function usePersonnelController() {
|
|
|
42786
42797
|
};
|
|
42787
42798
|
}
|
|
42788
42799
|
|
|
42789
|
-
// src/resources/
|
|
42790
|
-
|
|
42791
|
-
|
|
42792
|
-
|
|
42793
|
-
|
|
42794
|
-
|
|
42795
|
-
|
|
42796
|
-
|
|
42797
|
-
|
|
42798
|
-
|
|
42799
|
-
|
|
42800
|
-
|
|
42801
|
-
|
|
42802
|
-
|
|
42803
|
-
|
|
42804
|
-
|
|
42805
|
-
|
|
42806
|
-
|
|
42807
|
-
|
|
42808
|
-
|
|
42809
|
-
|
|
42810
|
-
|
|
42811
|
-
|
|
42812
|
-
|
|
42813
|
-
|
|
42814
|
-
|
|
42815
|
-
|
|
42816
|
-
|
|
42817
|
-
|
|
42818
|
-
|
|
42819
|
-
|
|
42820
|
-
|
|
42821
|
-
|
|
42822
|
-
|
|
42800
|
+
// src/resources/kindergarten-routine/kindergarten.routine.model.ts
|
|
42801
|
+
import { BadRequestError as BadRequestError64 } from "@eeplatform/nodejs-utils";
|
|
42802
|
+
import Joi43 from "joi";
|
|
42803
|
+
import { ObjectId as ObjectId41 } from "mongodb";
|
|
42804
|
+
var schemaKindergartenRoutine = Joi43.object({
|
|
42805
|
+
_id: Joi43.string().hex().optional().allow(null, ""),
|
|
42806
|
+
title: Joi43.string().max(100).required(),
|
|
42807
|
+
section: Joi43.string().hex().optional().allow(null, ""),
|
|
42808
|
+
sectionName: Joi43.string().max(100).optional().allow(null, ""),
|
|
42809
|
+
classroom: Joi43.string().hex().optional().allow(null, ""),
|
|
42810
|
+
classroomName: Joi43.string().max(100).optional().allow(null, ""),
|
|
42811
|
+
schedule: Joi43.array().items(Joi43.string()).required(),
|
|
42812
|
+
blockTimes: Joi43.array().items(
|
|
42813
|
+
Joi43.object({
|
|
42814
|
+
title: Joi43.string().required(),
|
|
42815
|
+
startTime: Joi43.string().required(),
|
|
42816
|
+
endTime: Joi43.string().required(),
|
|
42817
|
+
durationMinutes: Joi43.number().required(),
|
|
42818
|
+
domains: Joi43.array().items(Joi43.string()).optional()
|
|
42819
|
+
})
|
|
42820
|
+
).required(),
|
|
42821
|
+
type: Joi43.string().required(),
|
|
42822
|
+
durationMinutes: Joi43.number().optional().allow(null, 0),
|
|
42823
|
+
school: Joi43.string().hex().required(),
|
|
42824
|
+
createdAt: Joi43.string().isoDate().optional().allow(null, ""),
|
|
42825
|
+
updatedAt: Joi43.string().isoDate().optional().allow(null, ""),
|
|
42826
|
+
deletedAt: Joi43.string().isoDate().optional().allow(null, "")
|
|
42827
|
+
});
|
|
42828
|
+
var schemaKindergartenRoutineUpdate = Joi43.object({
|
|
42829
|
+
title: Joi43.string().max(100).optional().allow(null, ""),
|
|
42830
|
+
section: Joi43.string().hex().optional().allow(null, ""),
|
|
42831
|
+
sectionName: Joi43.string().max(100).optional().allow(null, ""),
|
|
42832
|
+
classroom: Joi43.string().hex().optional().allow(null, ""),
|
|
42833
|
+
classroomName: Joi43.string().max(100).optional().allow(null, ""),
|
|
42834
|
+
schedule: Joi43.array().items(Joi43.string()).optional().allow(null, ""),
|
|
42835
|
+
blockTimes: Joi43.array().items(
|
|
42836
|
+
Joi43.object({
|
|
42837
|
+
title: Joi43.string().required(),
|
|
42838
|
+
startTime: Joi43.string().required(),
|
|
42839
|
+
endTime: Joi43.string().required(),
|
|
42840
|
+
durationMinutes: Joi43.number().required(),
|
|
42841
|
+
domains: Joi43.array().items(Joi43.string()).optional()
|
|
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}`);
|
|
42850
|
+
}
|
|
42851
|
+
if (value._id && typeof value._id === "string") {
|
|
42852
|
+
try {
|
|
42853
|
+
value._id = new ObjectId41(value._id);
|
|
42854
|
+
} catch (error2) {
|
|
42855
|
+
throw new Error("Invalid _id.");
|
|
42823
42856
|
}
|
|
42824
|
-
|
|
42825
|
-
|
|
42826
|
-
|
|
42827
|
-
|
|
42828
|
-
|
|
42829
|
-
|
|
42857
|
+
}
|
|
42858
|
+
if (value.school && typeof value.school === "string") {
|
|
42859
|
+
try {
|
|
42860
|
+
value.school = new ObjectId41(value.school);
|
|
42861
|
+
} catch (error2) {
|
|
42862
|
+
throw new Error("Invalid school.");
|
|
42830
42863
|
}
|
|
42831
|
-
return sizes;
|
|
42832
42864
|
}
|
|
42833
|
-
|
|
42834
|
-
|
|
42835
|
-
|
|
42836
|
-
|
|
42837
|
-
|
|
42838
|
-
);
|
|
42865
|
+
if (value.section && typeof value.section === "string") {
|
|
42866
|
+
try {
|
|
42867
|
+
value.section = new ObjectId41(value.section);
|
|
42868
|
+
} catch (error2) {
|
|
42869
|
+
throw new Error("Invalid section.");
|
|
42839
42870
|
}
|
|
42840
|
-
|
|
42841
|
-
|
|
42842
|
-
|
|
42871
|
+
}
|
|
42872
|
+
if (value.classroom && typeof value.classroom === "string") {
|
|
42873
|
+
try {
|
|
42874
|
+
value.classroom = new ObjectId41(value.classroom);
|
|
42875
|
+
} catch (error2) {
|
|
42876
|
+
throw new Error("Invalid classroom.");
|
|
42843
42877
|
}
|
|
42878
|
+
}
|
|
42879
|
+
return {
|
|
42880
|
+
_id: value._id,
|
|
42881
|
+
title: value.title,
|
|
42882
|
+
section: value.section,
|
|
42883
|
+
sectionName: value.sectionName ?? "",
|
|
42884
|
+
classroom: value.classroom,
|
|
42885
|
+
classroomName: value.classroomName ?? "",
|
|
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() {
|
|
42844
42919
|
try {
|
|
42845
|
-
await
|
|
42846
|
-
|
|
42920
|
+
await collection.createIndexes([
|
|
42921
|
+
{ key: { section: 1 } },
|
|
42922
|
+
{ key: { classroom: 1 } },
|
|
42923
|
+
{ key: { schedule: 1 } },
|
|
42924
|
+
{ key: { type: 1 } },
|
|
42925
|
+
{ key: { createdAt: 1 } },
|
|
42926
|
+
{ key: { createdBy: 1 } },
|
|
42927
|
+
{ key: { sectionName: "text", classroomName: "text" } },
|
|
42847
42928
|
{
|
|
42848
|
-
school:
|
|
42849
|
-
|
|
42850
|
-
|
|
42851
|
-
|
|
42852
|
-
|
|
42853
|
-
|
|
42854
|
-
);
|
|
42855
|
-
|
|
42856
|
-
|
|
42929
|
+
key: { title: 1, school: 1, type: 1, status: 1 },
|
|
42930
|
+
unique: true,
|
|
42931
|
+
name: "unique_kindergarten_routine"
|
|
42932
|
+
}
|
|
42933
|
+
]);
|
|
42934
|
+
} catch (error) {
|
|
42935
|
+
throw new Error("Failed to create index on kindergarten routines.");
|
|
42936
|
+
}
|
|
42937
|
+
}
|
|
42938
|
+
function delCachedData() {
|
|
42939
|
+
delNamespace().then(() => {
|
|
42940
|
+
logger39.log({
|
|
42941
|
+
level: "info",
|
|
42942
|
+
message: `Cache namespace cleared for ${namespace_collection}`
|
|
42943
|
+
});
|
|
42944
|
+
}).catch((err) => {
|
|
42945
|
+
logger39.log({
|
|
42946
|
+
level: "error",
|
|
42947
|
+
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
42948
|
+
});
|
|
42949
|
+
});
|
|
42950
|
+
}
|
|
42951
|
+
async function add(value, session) {
|
|
42952
|
+
try {
|
|
42953
|
+
value = modelKindergartenRoutine(value);
|
|
42954
|
+
const res = await collection.insertOne(value, { session });
|
|
42955
|
+
delCachedData();
|
|
42956
|
+
return res.insertedId;
|
|
42957
|
+
} catch (error) {
|
|
42958
|
+
logger39.log({
|
|
42959
|
+
level: "error",
|
|
42960
|
+
message: error.message
|
|
42961
|
+
});
|
|
42962
|
+
if (error instanceof AppError25) {
|
|
42963
|
+
throw error;
|
|
42964
|
+
} else {
|
|
42965
|
+
const isDuplicated = error.message.includes("duplicate");
|
|
42966
|
+
if (isDuplicated) {
|
|
42967
|
+
throw new BadRequestError65("Kinder schedule already exists.");
|
|
42968
|
+
}
|
|
42969
|
+
throw new Error("Failed to create kindergarten routine.");
|
|
42857
42970
|
}
|
|
42858
|
-
|
|
42859
|
-
|
|
42860
|
-
|
|
42861
|
-
|
|
42862
|
-
|
|
42863
|
-
|
|
42864
|
-
|
|
42865
|
-
|
|
42866
|
-
|
|
42971
|
+
}
|
|
42972
|
+
}
|
|
42973
|
+
async function getAll({
|
|
42974
|
+
search = "",
|
|
42975
|
+
page = 1,
|
|
42976
|
+
limit = 10,
|
|
42977
|
+
sort = {},
|
|
42978
|
+
status = "active",
|
|
42979
|
+
createdBy,
|
|
42980
|
+
school = "",
|
|
42981
|
+
section = "",
|
|
42982
|
+
classroom = "",
|
|
42983
|
+
type = ""
|
|
42984
|
+
} = {}) {
|
|
42985
|
+
page = page > 0 ? page - 1 : 0;
|
|
42986
|
+
const query = {
|
|
42987
|
+
deletedAt: { $in: ["", null] },
|
|
42988
|
+
status
|
|
42989
|
+
};
|
|
42990
|
+
sort = Object.keys(sort).length > 0 ? sort : { _id: 1 };
|
|
42991
|
+
const cacheKeyOptions = {
|
|
42992
|
+
status,
|
|
42993
|
+
page,
|
|
42994
|
+
limit,
|
|
42995
|
+
sort: JSON.stringify(sort)
|
|
42996
|
+
};
|
|
42997
|
+
if (createdBy) {
|
|
42998
|
+
try {
|
|
42999
|
+
query.createdBy = new ObjectId42(createdBy);
|
|
43000
|
+
} catch (error) {
|
|
43001
|
+
throw new BadRequestError65("Invalid createdBy ID.");
|
|
42867
43002
|
}
|
|
42868
|
-
|
|
42869
|
-
|
|
42870
|
-
|
|
42871
|
-
|
|
42872
|
-
|
|
42873
|
-
|
|
42874
|
-
|
|
43003
|
+
cacheKeyOptions.createdBy = createdBy;
|
|
43004
|
+
}
|
|
43005
|
+
if (search) {
|
|
43006
|
+
query.$text = { $search: search };
|
|
43007
|
+
cacheKeyOptions.search = search;
|
|
43008
|
+
}
|
|
43009
|
+
if (school) {
|
|
43010
|
+
try {
|
|
43011
|
+
query.school = new ObjectId42(school);
|
|
43012
|
+
} catch (error) {
|
|
43013
|
+
throw new BadRequestError65("Invalid school ID.");
|
|
42875
43014
|
}
|
|
42876
|
-
|
|
42877
|
-
|
|
42878
|
-
|
|
42879
|
-
|
|
42880
|
-
|
|
42881
|
-
|
|
42882
|
-
throw new
|
|
43015
|
+
cacheKeyOptions.school = school;
|
|
43016
|
+
}
|
|
43017
|
+
if (section) {
|
|
43018
|
+
try {
|
|
43019
|
+
query.section = new ObjectId42(section);
|
|
43020
|
+
} catch (error) {
|
|
43021
|
+
throw new BadRequestError65("Invalid section ID.");
|
|
42883
43022
|
}
|
|
42884
|
-
|
|
42885
|
-
|
|
42886
|
-
|
|
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.");
|
|
42887
43030
|
}
|
|
42888
|
-
|
|
42889
|
-
|
|
42890
|
-
|
|
42891
|
-
|
|
42892
|
-
|
|
42893
|
-
|
|
42894
|
-
|
|
42895
|
-
|
|
42896
|
-
|
|
42897
|
-
|
|
42898
|
-
|
|
42899
|
-
|
|
42900
|
-
|
|
42901
|
-
|
|
42902
|
-
|
|
42903
|
-
|
|
42904
|
-
{
|
|
42905
|
-
|
|
42906
|
-
|
|
42907
|
-
|
|
42908
|
-
|
|
42909
|
-
|
|
42910
|
-
|
|
42911
|
-
|
|
42912
|
-
|
|
42913
|
-
|
|
42914
|
-
|
|
42915
|
-
|
|
42916
|
-
|
|
42917
|
-
|
|
42918
|
-
|
|
42919
|
-
}
|
|
42920
|
-
|
|
42921
|
-
|
|
42922
|
-
|
|
42923
|
-
|
|
42924
|
-
|
|
43031
|
+
cacheKeyOptions.classroom = classroom;
|
|
43032
|
+
}
|
|
43033
|
+
if (type) {
|
|
43034
|
+
query.type = type;
|
|
43035
|
+
cacheKeyOptions.type = type;
|
|
43036
|
+
}
|
|
43037
|
+
const cacheKey = makeCacheKey22(namespace_collection, cacheKeyOptions);
|
|
43038
|
+
logger39.log({
|
|
43039
|
+
level: "info",
|
|
43040
|
+
message: `Cache key for getAll kindergarten routines: ${cacheKey}`
|
|
43041
|
+
});
|
|
43042
|
+
try {
|
|
43043
|
+
const cached = await getCache(cacheKey);
|
|
43044
|
+
if (cached) {
|
|
43045
|
+
logger39.log({
|
|
43046
|
+
level: "info",
|
|
43047
|
+
message: `Cache hit for getAll kindergarten routines: ${cacheKey}`
|
|
43048
|
+
});
|
|
43049
|
+
return cached;
|
|
43050
|
+
}
|
|
43051
|
+
const items = await collection.aggregate([
|
|
43052
|
+
{ $match: query },
|
|
43053
|
+
{ $sort: sort },
|
|
43054
|
+
{ $skip: page * limit },
|
|
43055
|
+
{ $limit: limit }
|
|
43056
|
+
]).toArray();
|
|
43057
|
+
const length = await collection.countDocuments(query);
|
|
43058
|
+
const data = paginate21(items, page, limit, length);
|
|
43059
|
+
setCache(cacheKey, data, 600).then(() => {
|
|
43060
|
+
logger39.log({
|
|
43061
|
+
level: "info",
|
|
43062
|
+
message: `Cache set for getAll kindergarten routines: ${cacheKey}`
|
|
43063
|
+
});
|
|
43064
|
+
}).catch((err) => {
|
|
43065
|
+
logger39.log({
|
|
43066
|
+
level: "error",
|
|
43067
|
+
message: `Failed to set cache for getAll kindergarten routines: ${err.message}`
|
|
43068
|
+
});
|
|
43069
|
+
});
|
|
43070
|
+
return data;
|
|
43071
|
+
} catch (error) {
|
|
43072
|
+
logger39.log({ level: "error", message: `${error}` });
|
|
43073
|
+
throw error;
|
|
43074
|
+
}
|
|
43075
|
+
}
|
|
43076
|
+
async function getById(_id) {
|
|
43077
|
+
try {
|
|
43078
|
+
_id = new ObjectId42(_id);
|
|
43079
|
+
} catch (error) {
|
|
43080
|
+
throw new BadRequestError65(namespace_collection + " Invalid ID.");
|
|
43081
|
+
}
|
|
43082
|
+
const cacheKey = makeCacheKey22(namespace_collection, { _id: String(_id) });
|
|
43083
|
+
try {
|
|
43084
|
+
const cached = await getCache(cacheKey);
|
|
43085
|
+
if (cached) {
|
|
43086
|
+
logger39.log({
|
|
43087
|
+
level: "info",
|
|
43088
|
+
message: `Cache hit for getById kindergarten routine: ${cacheKey}`
|
|
43089
|
+
});
|
|
43090
|
+
return cached;
|
|
43091
|
+
}
|
|
43092
|
+
const result = await collection.findOne({
|
|
43093
|
+
_id,
|
|
43094
|
+
deletedAt: { $in: ["", null] }
|
|
43095
|
+
});
|
|
43096
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
43097
|
+
logger39.log({
|
|
43098
|
+
level: "info",
|
|
43099
|
+
message: `Cache set for kindergarten routine by id: ${cacheKey}`
|
|
43100
|
+
});
|
|
43101
|
+
}).catch((err) => {
|
|
43102
|
+
logger39.log({
|
|
43103
|
+
level: "error",
|
|
43104
|
+
message: `Failed to set cache for kindergarten routine by id: ${err.message}`
|
|
43105
|
+
});
|
|
43106
|
+
});
|
|
43107
|
+
return result;
|
|
43108
|
+
} catch (error) {
|
|
43109
|
+
if (error instanceof AppError25) {
|
|
43110
|
+
throw error;
|
|
43111
|
+
} else {
|
|
43112
|
+
throw new InternalServerError21("Failed to get kindergarten routine.");
|
|
43113
|
+
}
|
|
43114
|
+
}
|
|
43115
|
+
}
|
|
43116
|
+
async function countByDomain(domain) {
|
|
43117
|
+
const cacheKey = makeCacheKey22(namespace_collection, {
|
|
43118
|
+
domain,
|
|
43119
|
+
tag: "getByDomain"
|
|
43120
|
+
});
|
|
43121
|
+
try {
|
|
43122
|
+
const cached = await getCache(cacheKey);
|
|
43123
|
+
if (cached) {
|
|
43124
|
+
logger39.log({
|
|
43125
|
+
level: "info",
|
|
43126
|
+
message: `Cache hit for getById kindergarten routine: ${cacheKey}`
|
|
43127
|
+
});
|
|
43128
|
+
return cached;
|
|
43129
|
+
}
|
|
43130
|
+
const result = await collection.countDocuments({
|
|
43131
|
+
domain,
|
|
43132
|
+
status: "active"
|
|
43133
|
+
});
|
|
43134
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
43135
|
+
logger39.log({
|
|
43136
|
+
level: "info",
|
|
43137
|
+
message: `Cache set for kindergarten routine by id: ${cacheKey}`
|
|
43138
|
+
});
|
|
43139
|
+
}).catch((err) => {
|
|
43140
|
+
logger39.log({
|
|
43141
|
+
level: "error",
|
|
43142
|
+
message: `Failed to set cache for kindergarten routine by id: ${err.message}`
|
|
43143
|
+
});
|
|
43144
|
+
});
|
|
43145
|
+
return result;
|
|
43146
|
+
} catch (error) {
|
|
43147
|
+
if (error instanceof AppError25) {
|
|
43148
|
+
throw error;
|
|
43149
|
+
} else {
|
|
43150
|
+
throw new InternalServerError21("Failed to get kindergarten routine.");
|
|
43151
|
+
}
|
|
43152
|
+
}
|
|
43153
|
+
}
|
|
43154
|
+
async function getBySection(section) {
|
|
43155
|
+
try {
|
|
43156
|
+
section = new ObjectId42(section);
|
|
43157
|
+
} catch (error) {
|
|
43158
|
+
throw new BadRequestError65("Invalid section ID.");
|
|
43159
|
+
}
|
|
43160
|
+
const cacheKey = makeCacheKey22(namespace_collection, {
|
|
43161
|
+
section: String(section)
|
|
43162
|
+
});
|
|
43163
|
+
try {
|
|
43164
|
+
const cached = await getCache(cacheKey);
|
|
43165
|
+
if (cached) {
|
|
43166
|
+
logger39.log({
|
|
43167
|
+
level: "info",
|
|
43168
|
+
message: `Cache hit for getBySection kindergarten routine: ${cacheKey}`
|
|
43169
|
+
});
|
|
43170
|
+
return cached;
|
|
43171
|
+
}
|
|
43172
|
+
const result = await collection.find({
|
|
43173
|
+
section,
|
|
43174
|
+
deletedAt: { $in: ["", null] }
|
|
43175
|
+
}).toArray();
|
|
43176
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
43177
|
+
logger39.log({
|
|
43178
|
+
level: "info",
|
|
43179
|
+
message: `Cache set for kindergarten routine by section: ${cacheKey}`
|
|
43180
|
+
});
|
|
43181
|
+
}).catch((err) => {
|
|
43182
|
+
logger39.log({
|
|
43183
|
+
level: "error",
|
|
43184
|
+
message: `Failed to set cache for kindergarten routine by section: ${err.message}`
|
|
43185
|
+
});
|
|
43186
|
+
});
|
|
43187
|
+
return result;
|
|
43188
|
+
} catch (error) {
|
|
43189
|
+
if (error instanceof AppError25) {
|
|
43190
|
+
throw error;
|
|
43191
|
+
} else {
|
|
43192
|
+
throw new InternalServerError21("Failed to get kindergarten routine.");
|
|
43193
|
+
}
|
|
43194
|
+
}
|
|
43195
|
+
}
|
|
43196
|
+
async function updateFieldById({ _id, field, value } = {}, session) {
|
|
43197
|
+
const allowedFields = [
|
|
43198
|
+
"sectionName",
|
|
43199
|
+
"classroomName",
|
|
43200
|
+
"schedule",
|
|
43201
|
+
"blockTimes",
|
|
43202
|
+
"type"
|
|
43203
|
+
];
|
|
43204
|
+
if (!allowedFields.includes(field)) {
|
|
43205
|
+
throw new BadRequestError65(
|
|
43206
|
+
`Field "${field}" is not allowed to be updated.`
|
|
43207
|
+
);
|
|
43208
|
+
}
|
|
43209
|
+
try {
|
|
43210
|
+
_id = new ObjectId42(_id);
|
|
43211
|
+
} catch (error) {
|
|
43212
|
+
throw new BadRequestError65(namespace_collection + " Invalid ID.");
|
|
43213
|
+
}
|
|
43214
|
+
try {
|
|
43215
|
+
await collection.updateOne(
|
|
43216
|
+
{ _id, deletedAt: { $in: ["", null] } },
|
|
43217
|
+
{ $set: { [field]: value, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
|
|
43218
|
+
{ session }
|
|
43219
|
+
);
|
|
43220
|
+
delCachedData();
|
|
43221
|
+
return `Successfully updated kindergarten routine ${field}.`;
|
|
43222
|
+
} catch (error) {
|
|
43223
|
+
throw new InternalServerError21(
|
|
43224
|
+
`Failed to update kindergarten routine ${field}.`
|
|
43225
|
+
);
|
|
43226
|
+
}
|
|
43227
|
+
}
|
|
43228
|
+
async function updateById(_id, value, session) {
|
|
43229
|
+
const { error } = schemaKindergartenRoutineUpdate.validate(value);
|
|
43230
|
+
if (error) {
|
|
43231
|
+
throw new BadRequestError65(
|
|
43232
|
+
`Invalid kindergarten routine data: ${error.message}`
|
|
43233
|
+
);
|
|
43234
|
+
}
|
|
43235
|
+
try {
|
|
43236
|
+
_id = new ObjectId42(_id);
|
|
43237
|
+
} catch (error2) {
|
|
43238
|
+
throw new BadRequestError65(namespace_collection + " Invalid ID.");
|
|
43239
|
+
}
|
|
43240
|
+
try {
|
|
43241
|
+
await collection.updateOne(
|
|
43242
|
+
{ _id },
|
|
43243
|
+
{ $set: { ...value, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
|
|
43244
|
+
{ session }
|
|
43245
|
+
);
|
|
43246
|
+
delCachedData();
|
|
43247
|
+
return `Successfully updated kindergarten routine.`;
|
|
43248
|
+
} catch (error2) {
|
|
43249
|
+
throw new InternalServerError21("Failed to update kindergarten routine.");
|
|
43250
|
+
}
|
|
43251
|
+
}
|
|
43252
|
+
async function deleteById(_id) {
|
|
43253
|
+
try {
|
|
43254
|
+
_id = new ObjectId42(_id);
|
|
43255
|
+
} catch (error) {
|
|
43256
|
+
throw new BadRequestError65(namespace_collection + " Invalid ID.");
|
|
43257
|
+
}
|
|
43258
|
+
try {
|
|
43259
|
+
await collection.updateOne(
|
|
43260
|
+
{ _id },
|
|
43261
|
+
{ $set: { status: "deleted", deletedAt: (/* @__PURE__ */ new Date()).toISOString() } }
|
|
43262
|
+
);
|
|
43263
|
+
delCachedData();
|
|
43264
|
+
return "Successfully deleted kindergarten routine.";
|
|
43265
|
+
} catch (error) {
|
|
43266
|
+
throw new InternalServerError21("Failed to delete kindergarten routine.");
|
|
43267
|
+
}
|
|
43268
|
+
}
|
|
43269
|
+
return {
|
|
43270
|
+
createIndexes,
|
|
43271
|
+
add,
|
|
43272
|
+
getAll,
|
|
43273
|
+
getById,
|
|
43274
|
+
countByDomain,
|
|
43275
|
+
getBySection,
|
|
43276
|
+
updateFieldById,
|
|
43277
|
+
updateById,
|
|
43278
|
+
deleteById
|
|
43279
|
+
};
|
|
43280
|
+
}
|
|
43281
|
+
|
|
43282
|
+
// src/resources/kindergarten-routine/kindergarten.routine.controller.ts
|
|
43283
|
+
import { BadRequestError as BadRequestError66 } from "@eeplatform/nodejs-utils";
|
|
43284
|
+
import Joi44 from "joi";
|
|
43285
|
+
function useKindergartenRoutineController() {
|
|
43286
|
+
const {
|
|
43287
|
+
add: _add,
|
|
43288
|
+
getAll: _getAll,
|
|
43289
|
+
getById: _getById,
|
|
43290
|
+
getBySection: _getBySection,
|
|
43291
|
+
updateFieldById: _updateFieldById,
|
|
43292
|
+
deleteById: _deleteById,
|
|
43293
|
+
updateById: _updateById
|
|
43294
|
+
} = useKindergartenRoutineRepo();
|
|
43295
|
+
async function add(req, res, next) {
|
|
43296
|
+
const value = req.body;
|
|
43297
|
+
const { error } = schemaKindergartenRoutine.validate(value);
|
|
43298
|
+
if (error) {
|
|
43299
|
+
next(new BadRequestError66(error.message));
|
|
43300
|
+
return;
|
|
43301
|
+
}
|
|
43302
|
+
try {
|
|
43303
|
+
const data = await _add(value);
|
|
43304
|
+
res.json({
|
|
43305
|
+
message: "Successfully created kinder schedule.",
|
|
43306
|
+
data
|
|
43307
|
+
});
|
|
43308
|
+
return;
|
|
43309
|
+
} catch (error2) {
|
|
43310
|
+
next(error2);
|
|
43311
|
+
}
|
|
43312
|
+
}
|
|
43313
|
+
async function getAll(req, res, next) {
|
|
43314
|
+
const query = req.query;
|
|
43315
|
+
const validation = Joi44.object({
|
|
43316
|
+
page: Joi44.number().min(1).optional().allow("", null),
|
|
43317
|
+
limit: Joi44.number().min(1).optional().allow("", null),
|
|
43318
|
+
search: Joi44.string().optional().allow("", null),
|
|
43319
|
+
status: Joi44.string().optional().allow("", null),
|
|
43320
|
+
school: Joi44.string().hex().optional().allow("", null),
|
|
43321
|
+
section: Joi44.string().hex().optional().allow("", null),
|
|
43322
|
+
classroom: Joi44.string().hex().optional().allow("", null),
|
|
43323
|
+
type: Joi44.string().optional().allow("", null),
|
|
43324
|
+
createdBy: Joi44.string().hex().optional().allow("", null)
|
|
43325
|
+
});
|
|
43326
|
+
const { error } = validation.validate(query);
|
|
43327
|
+
const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
|
|
43328
|
+
const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
|
|
43329
|
+
const search = req.query.search ?? "";
|
|
43330
|
+
const status = req.query.status ?? "active";
|
|
43331
|
+
const school = req.query.school ?? "";
|
|
43332
|
+
const section = req.query.section ?? "";
|
|
43333
|
+
const classroom = req.query.classroom ?? "";
|
|
43334
|
+
const type = req.query.type ?? "";
|
|
43335
|
+
const createdBy = req.query.createdBy ?? "";
|
|
43336
|
+
const isPageNumber = isFinite(page);
|
|
43337
|
+
if (!isPageNumber) {
|
|
43338
|
+
next(new BadRequestError66("Invalid page number."));
|
|
43339
|
+
return;
|
|
43340
|
+
}
|
|
43341
|
+
const isLimitNumber = isFinite(limit);
|
|
43342
|
+
if (!isLimitNumber) {
|
|
43343
|
+
next(new BadRequestError66("Invalid limit number."));
|
|
43344
|
+
return;
|
|
43345
|
+
}
|
|
43346
|
+
if (error) {
|
|
43347
|
+
next(new BadRequestError66(error.message));
|
|
43348
|
+
return;
|
|
43349
|
+
}
|
|
43350
|
+
try {
|
|
43351
|
+
const data = await _getAll({
|
|
43352
|
+
page,
|
|
43353
|
+
limit,
|
|
43354
|
+
search,
|
|
43355
|
+
status,
|
|
43356
|
+
school,
|
|
43357
|
+
section,
|
|
43358
|
+
classroom,
|
|
43359
|
+
type,
|
|
43360
|
+
createdBy: createdBy || void 0
|
|
43361
|
+
});
|
|
43362
|
+
res.json(data);
|
|
43363
|
+
return;
|
|
43364
|
+
} catch (error2) {
|
|
43365
|
+
next(error2);
|
|
43366
|
+
}
|
|
43367
|
+
}
|
|
43368
|
+
async function getById(req, res, next) {
|
|
43369
|
+
const id = req.params.id;
|
|
43370
|
+
const validation = Joi44.object({
|
|
43371
|
+
id: Joi44.string().hex().required()
|
|
43372
|
+
});
|
|
43373
|
+
const { error } = validation.validate({ id });
|
|
43374
|
+
if (error) {
|
|
43375
|
+
next(new BadRequestError66(error.message));
|
|
43376
|
+
return;
|
|
43377
|
+
}
|
|
43378
|
+
try {
|
|
43379
|
+
const data = await _getById(id);
|
|
43380
|
+
res.json({
|
|
43381
|
+
message: "Successfully retrieved kinder schedule.",
|
|
43382
|
+
data
|
|
43383
|
+
});
|
|
43384
|
+
return;
|
|
43385
|
+
} catch (error2) {
|
|
43386
|
+
next(error2);
|
|
43387
|
+
}
|
|
43388
|
+
}
|
|
43389
|
+
async function getBySection(req, res, next) {
|
|
43390
|
+
const section = req.params.section;
|
|
43391
|
+
const validation = Joi44.object({
|
|
43392
|
+
section: Joi44.string().hex().required()
|
|
43393
|
+
});
|
|
43394
|
+
const { error } = validation.validate({ section });
|
|
43395
|
+
if (error) {
|
|
43396
|
+
next(new BadRequestError66(error.message));
|
|
43397
|
+
return;
|
|
43398
|
+
}
|
|
43399
|
+
try {
|
|
43400
|
+
const data = await _getBySection(section);
|
|
43401
|
+
res.json({
|
|
43402
|
+
message: "Successfully retrieved kinder schedules.",
|
|
43403
|
+
data
|
|
43404
|
+
});
|
|
43405
|
+
return;
|
|
43406
|
+
} catch (error2) {
|
|
43407
|
+
next(error2);
|
|
43408
|
+
}
|
|
43409
|
+
}
|
|
43410
|
+
async function updateField(req, res, next) {
|
|
43411
|
+
const _id = req.params.id;
|
|
43412
|
+
const { field, value } = req.body;
|
|
43413
|
+
const validation = Joi44.object({
|
|
43414
|
+
_id: Joi44.string().hex().required(),
|
|
43415
|
+
field: Joi44.string().valid("sectionName", "classroomName", "schedule", "blockTimes", "type").required(),
|
|
43416
|
+
value: Joi44.alternatives().try(Joi44.string(), Joi44.array(), Joi44.object()).required()
|
|
43417
|
+
});
|
|
43418
|
+
const { error } = validation.validate({ _id, field, value });
|
|
43419
|
+
if (error) {
|
|
43420
|
+
next(new BadRequestError66(error.message));
|
|
43421
|
+
return;
|
|
43422
|
+
}
|
|
43423
|
+
try {
|
|
43424
|
+
const message = await _updateFieldById({ _id, field, value });
|
|
43425
|
+
res.json({ message });
|
|
43426
|
+
return;
|
|
43427
|
+
} catch (error2) {
|
|
43428
|
+
next(error2);
|
|
43429
|
+
}
|
|
43430
|
+
}
|
|
43431
|
+
async function updateById(req, res, next) {
|
|
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
|
+
}
|
|
43444
|
+
try {
|
|
43445
|
+
const message = await _updateById(_id, payload);
|
|
43446
|
+
res.json({ message });
|
|
43447
|
+
return;
|
|
43448
|
+
} catch (error2) {
|
|
43449
|
+
next(error2);
|
|
43450
|
+
}
|
|
43451
|
+
}
|
|
43452
|
+
async function deleteById(req, res, next) {
|
|
43453
|
+
const _id = req.params.id;
|
|
43454
|
+
const validation = Joi44.object({
|
|
43455
|
+
_id: Joi44.string().hex().required()
|
|
43456
|
+
});
|
|
43457
|
+
const { error } = validation.validate({ _id });
|
|
43458
|
+
if (error) {
|
|
43459
|
+
next(new BadRequestError66(error.message));
|
|
43460
|
+
return;
|
|
43461
|
+
}
|
|
43462
|
+
try {
|
|
43463
|
+
const message = await _deleteById(_id);
|
|
43464
|
+
res.json({ message });
|
|
43465
|
+
return;
|
|
43466
|
+
} catch (error2) {
|
|
43467
|
+
next(error2);
|
|
43468
|
+
}
|
|
43469
|
+
}
|
|
43470
|
+
return {
|
|
43471
|
+
add,
|
|
43472
|
+
getAll,
|
|
43473
|
+
getById,
|
|
43474
|
+
getBySection,
|
|
43475
|
+
updateField,
|
|
43476
|
+
updateById,
|
|
43477
|
+
deleteById
|
|
43478
|
+
};
|
|
43479
|
+
}
|
|
43480
|
+
|
|
43481
|
+
// src/resources/section/section.service.ts
|
|
43482
|
+
function useSectionService() {
|
|
43483
|
+
const { getCountByGradeLevel, getByGradeLevel: getLeanerByGradeLevel } = useLearnerRepo();
|
|
43484
|
+
const { getByGradeLevel } = useGradeLevelRepo();
|
|
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;
|
|
43510
|
+
}
|
|
43511
|
+
const base = Math.floor(total / sectionCount);
|
|
43512
|
+
const extra = total % sectionCount;
|
|
43513
|
+
const sizes = new Array(sectionCount).fill(base);
|
|
43514
|
+
for (let i = 0; i < extra; i++) {
|
|
43515
|
+
sizes[i] += 1;
|
|
43516
|
+
}
|
|
43517
|
+
for (const size of sizes) {
|
|
43518
|
+
if (size > maxPer) {
|
|
43519
|
+
throw new BadRequestError67(
|
|
43520
|
+
`Generated section exceeds max limit of ${maxPer}.`
|
|
43521
|
+
);
|
|
43522
|
+
}
|
|
43523
|
+
}
|
|
43524
|
+
return sizes;
|
|
43525
|
+
}
|
|
43526
|
+
async function generateSections(value) {
|
|
43527
|
+
const { error } = schemaGenerateSections.validate(value);
|
|
43528
|
+
if (error) {
|
|
43529
|
+
throw new BadRequestError67(
|
|
43530
|
+
`Invalid section generation data: ${error.message}`
|
|
43531
|
+
);
|
|
43532
|
+
}
|
|
43533
|
+
const session = useAtlas31.getClient()?.startSession();
|
|
43534
|
+
if (!session) {
|
|
43535
|
+
throw new Error("Unable to start database session.");
|
|
43536
|
+
}
|
|
43537
|
+
try {
|
|
43538
|
+
await session.startTransaction();
|
|
43539
|
+
const isKindergarten = value.gradeLevel.toLowerCase() === "kindergarten";
|
|
43540
|
+
let kindergartenRoutine = null;
|
|
43541
|
+
if (isKindergarten) {
|
|
43542
|
+
kindergartenRoutine = await getKindergartenRoutineById(
|
|
43543
|
+
value.routine ?? ""
|
|
43544
|
+
);
|
|
43545
|
+
if (!kindergartenRoutine) {
|
|
43546
|
+
throw new BadRequestError67("Kindergarten routine not found.");
|
|
43547
|
+
}
|
|
43548
|
+
}
|
|
43549
|
+
const studentCount = await getCountByGradeLevel(
|
|
43550
|
+
{
|
|
43551
|
+
school: value.school,
|
|
43552
|
+
schoolYear: value.schoolYear,
|
|
43553
|
+
gradeLevel: value.gradeLevel,
|
|
43554
|
+
specialProgram: value.specialProgram
|
|
43555
|
+
},
|
|
43556
|
+
session
|
|
43557
|
+
);
|
|
43558
|
+
if (studentCount === 0) {
|
|
43559
|
+
throw new BadRequestError67("No learners found for this grade level.");
|
|
43560
|
+
}
|
|
43561
|
+
const gradeLevelData = await getByGradeLevel(
|
|
43562
|
+
{
|
|
43563
|
+
school: value.school,
|
|
43564
|
+
gradeLevel: value.gradeLevel
|
|
43565
|
+
},
|
|
43566
|
+
session
|
|
43567
|
+
);
|
|
43568
|
+
if (!gradeLevelData) {
|
|
43569
|
+
throw new BadRequestError67("Grade level not found.");
|
|
43570
|
+
}
|
|
43571
|
+
const minPerSection = value.minStudents ?? gradeLevelData.minNumberOfLearners;
|
|
43572
|
+
const maxPerSection = value.maxStudents ?? gradeLevelData.maxNumberOfLearners;
|
|
43573
|
+
const sectionsNeeded = Math.ceil(studentCount / minPerSection);
|
|
43574
|
+
if (sectionsNeeded > value.set.length) {
|
|
43575
|
+
throw new BadRequestError67(
|
|
43576
|
+
"Insufficient number of section names in set[]."
|
|
43577
|
+
);
|
|
43578
|
+
}
|
|
43579
|
+
const sectionSizes = distributeStudents(
|
|
43580
|
+
studentCount,
|
|
43581
|
+
minPerSection,
|
|
43582
|
+
maxPerSection
|
|
43583
|
+
);
|
|
43584
|
+
if (sectionSizes.length === 0) {
|
|
43585
|
+
throw new BadRequestError67("Unable to compute section sizes.");
|
|
43586
|
+
}
|
|
43587
|
+
const schoolData = await getSchoolById(value.school);
|
|
43588
|
+
if (!schoolData) {
|
|
43589
|
+
throw new BadRequestError67("School not found.");
|
|
43590
|
+
}
|
|
43591
|
+
let totalStudentsProcessed = 0;
|
|
43592
|
+
for (let i = 0; i < sectionSizes.length; i++) {
|
|
43593
|
+
const size = sectionSizes[i];
|
|
43594
|
+
const sectionName = value.set[i];
|
|
43595
|
+
const section = await createSection(
|
|
43596
|
+
{
|
|
43597
|
+
school: value.school,
|
|
43598
|
+
schoolYear: value.schoolYear,
|
|
43599
|
+
gradeLevel: value.gradeLevel,
|
|
43600
|
+
name: sectionName,
|
|
43601
|
+
students: size
|
|
43602
|
+
},
|
|
43603
|
+
session
|
|
43604
|
+
);
|
|
43605
|
+
const skip = totalStudentsProcessed;
|
|
43606
|
+
const learners = await getLeanerByGradeLevel(
|
|
43607
|
+
{
|
|
43608
|
+
school: value.school,
|
|
43609
|
+
gradeLevel: value.gradeLevel,
|
|
43610
|
+
skip,
|
|
43611
|
+
limit: size
|
|
43612
|
+
},
|
|
43613
|
+
session
|
|
43614
|
+
);
|
|
43615
|
+
if (!learners.length) {
|
|
43616
|
+
throw new BadRequestError67(`No learners found for section #${i + 1}.`);
|
|
43617
|
+
}
|
|
43618
|
+
totalStudentsProcessed += learners.length;
|
|
43619
|
+
for (const student of learners) {
|
|
43620
|
+
if (!student._id) {
|
|
43621
|
+
throw new BadRequestError67("Learner ID is missing.");
|
|
43622
|
+
}
|
|
43623
|
+
if (!student.learnerInfo.lrn) {
|
|
43624
|
+
throw new BadRequestError67("Learner LRN is missing.");
|
|
43625
|
+
}
|
|
43626
|
+
await assignStudent(
|
|
43627
|
+
{
|
|
42925
43628
|
section: section.toString(),
|
|
42926
43629
|
lrn: student.learnerInfo.lrn,
|
|
42927
43630
|
student: student._id?.toString(),
|
|
@@ -42931,441 +43634,1393 @@ function useSectionService() {
|
|
|
42931
43634
|
gradeLevel: value.gradeLevel,
|
|
42932
43635
|
educationLevel: gradeLevelData.educationLevel,
|
|
42933
43636
|
schoolYear: value.schoolYear,
|
|
42934
|
-
status: "active"
|
|
43637
|
+
status: "active"
|
|
43638
|
+
},
|
|
43639
|
+
session
|
|
43640
|
+
);
|
|
43641
|
+
}
|
|
43642
|
+
const curriculumSubjects = await getAllCurriculumSubjects({
|
|
43643
|
+
schoolYear: Number(value.schoolYear),
|
|
43644
|
+
gradeLevel: value.gradeLevel,
|
|
43645
|
+
limit: 20
|
|
43646
|
+
});
|
|
43647
|
+
for (const curriculumSubject of curriculumSubjects.items) {
|
|
43648
|
+
await addSectionSubject(
|
|
43649
|
+
{
|
|
43650
|
+
curriculum: curriculumSubject.curriculum.toString(),
|
|
43651
|
+
school: value.school,
|
|
43652
|
+
schoolName: schoolData.name,
|
|
43653
|
+
gradeLevel: value.gradeLevel,
|
|
43654
|
+
educationLevel: gradeLevelData.educationLevel,
|
|
43655
|
+
schoolYear: value.schoolYear,
|
|
43656
|
+
section: section.toString(),
|
|
43657
|
+
sectionName,
|
|
43658
|
+
subjectCode: curriculumSubject.subjectCode,
|
|
43659
|
+
subjectName: curriculumSubject.subjectName,
|
|
43660
|
+
teacher: "",
|
|
43661
|
+
teacherName: "",
|
|
43662
|
+
schedule: "",
|
|
43663
|
+
daysOfWeek: [],
|
|
43664
|
+
classroom: "",
|
|
43665
|
+
classroomName: "",
|
|
43666
|
+
sessionDuration: curriculumSubject.sessionDuration,
|
|
43667
|
+
sessionFrequency: curriculumSubject.sessionFrequency,
|
|
43668
|
+
status: "draft"
|
|
43669
|
+
},
|
|
43670
|
+
session
|
|
43671
|
+
);
|
|
43672
|
+
}
|
|
43673
|
+
if (isKindergarten && kindergartenRoutine) {
|
|
43674
|
+
kindergartenRoutine.section = section;
|
|
43675
|
+
kindergartenRoutine.sectionName = sectionName;
|
|
43676
|
+
kindergartenRoutine.type = "actual";
|
|
43677
|
+
await addKindergartenRoutine(kindergartenRoutine, session);
|
|
43678
|
+
}
|
|
43679
|
+
}
|
|
43680
|
+
let pageTeacher = 1;
|
|
43681
|
+
let pagesTeachers = 1;
|
|
43682
|
+
let teachers = [];
|
|
43683
|
+
do {
|
|
43684
|
+
const teachersData = await getAllPersonnel({
|
|
43685
|
+
school: value.school,
|
|
43686
|
+
limit: 100
|
|
43687
|
+
});
|
|
43688
|
+
pagesTeachers = teachersData.pages;
|
|
43689
|
+
teachers.push(...teachersData.items);
|
|
43690
|
+
pageTeacher++;
|
|
43691
|
+
} while (pageTeacher < pagesTeachers);
|
|
43692
|
+
if (!teachers.length) {
|
|
43693
|
+
throw new BadRequestError67(
|
|
43694
|
+
"Could not proceed, no teaching personnel found."
|
|
43695
|
+
);
|
|
43696
|
+
}
|
|
43697
|
+
if (teachers.length) {
|
|
43698
|
+
for (let index = 0; index < teachers.length; index++) {
|
|
43699
|
+
const teacher = teachers[index];
|
|
43700
|
+
if (!teacher._id) {
|
|
43701
|
+
throw new BadRequestError67("Teacher ID is missing.");
|
|
43702
|
+
}
|
|
43703
|
+
await addTeachingLoad(
|
|
43704
|
+
{
|
|
43705
|
+
school: value.school,
|
|
43706
|
+
schoolName: schoolData.name,
|
|
43707
|
+
schoolYear: value.schoolYear,
|
|
43708
|
+
teacher: teacher._id.toString(),
|
|
43709
|
+
teacherName: `${teacher.firstName} ${teacher.lastName}`,
|
|
43710
|
+
status: "draft"
|
|
42935
43711
|
},
|
|
42936
43712
|
session
|
|
42937
43713
|
);
|
|
42938
43714
|
}
|
|
42939
|
-
|
|
42940
|
-
|
|
42941
|
-
|
|
42942
|
-
|
|
43715
|
+
}
|
|
43716
|
+
await session.commitTransaction();
|
|
43717
|
+
return "Sections generated successfully.";
|
|
43718
|
+
} catch (error2) {
|
|
43719
|
+
await session.abortTransaction();
|
|
43720
|
+
if (error2 instanceof AppError26) {
|
|
43721
|
+
throw error2;
|
|
43722
|
+
} else {
|
|
43723
|
+
throw new InternalServerError22("Failed to generate sections.");
|
|
43724
|
+
}
|
|
43725
|
+
} finally {
|
|
43726
|
+
await session?.endSession();
|
|
43727
|
+
}
|
|
43728
|
+
}
|
|
43729
|
+
async function generateSectionPreview(value) {
|
|
43730
|
+
const { error } = schemaGenerateSections.validate(value);
|
|
43731
|
+
if (error) {
|
|
43732
|
+
throw new BadRequestError67(
|
|
43733
|
+
`Invalid section generation data: ${error.message}`
|
|
43734
|
+
);
|
|
43735
|
+
}
|
|
43736
|
+
try {
|
|
43737
|
+
const studentCount = await getCountByGradeLevel({
|
|
43738
|
+
school: value.school,
|
|
43739
|
+
schoolYear: value.schoolYear,
|
|
43740
|
+
gradeLevel: value.gradeLevel,
|
|
43741
|
+
specialProgram: value.specialProgram
|
|
43742
|
+
});
|
|
43743
|
+
if (studentCount === 0) {
|
|
43744
|
+
throw new BadRequestError67("No learners found for this grade level.");
|
|
43745
|
+
}
|
|
43746
|
+
const gradeLevelData = await getByGradeLevel({
|
|
43747
|
+
school: value.school,
|
|
43748
|
+
gradeLevel: value.gradeLevel
|
|
43749
|
+
});
|
|
43750
|
+
if (!gradeLevelData) {
|
|
43751
|
+
throw new BadRequestError67("Grade level not found.");
|
|
43752
|
+
}
|
|
43753
|
+
const minPerSection = value.minStudents ?? gradeLevelData.minNumberOfLearners;
|
|
43754
|
+
const maxPerSection = value.maxStudents ?? gradeLevelData.maxNumberOfLearners;
|
|
43755
|
+
const sectionsNeeded = Math.ceil(studentCount / minPerSection);
|
|
43756
|
+
if (sectionsNeeded > value.set.length) {
|
|
43757
|
+
throw new BadRequestError67(
|
|
43758
|
+
"Insufficient number of section names in set[]."
|
|
43759
|
+
);
|
|
43760
|
+
}
|
|
43761
|
+
const sectionSizes = distributeStudents(
|
|
43762
|
+
studentCount,
|
|
43763
|
+
minPerSection,
|
|
43764
|
+
maxPerSection
|
|
43765
|
+
);
|
|
43766
|
+
if (sectionSizes.length === 0) {
|
|
43767
|
+
throw new BadRequestError67("Unable to compute section sizes.");
|
|
43768
|
+
}
|
|
43769
|
+
const sections = sectionSizes.map((size, index) => ({
|
|
43770
|
+
name: value.set[index],
|
|
43771
|
+
value: size
|
|
43772
|
+
}));
|
|
43773
|
+
return {
|
|
43774
|
+
totalSectionsGenerated: sectionSizes.length,
|
|
43775
|
+
totalStudentsAssigned: studentCount,
|
|
43776
|
+
sections
|
|
43777
|
+
};
|
|
43778
|
+
} catch (error2) {
|
|
43779
|
+
if (error2 instanceof AppError26) {
|
|
43780
|
+
throw error2;
|
|
43781
|
+
} else {
|
|
43782
|
+
throw new InternalServerError22("Failed to generate section preview.");
|
|
43783
|
+
}
|
|
43784
|
+
}
|
|
43785
|
+
}
|
|
43786
|
+
return { generateSections, generateSectionPreview };
|
|
43787
|
+
}
|
|
43788
|
+
|
|
43789
|
+
// src/resources/section/section.controller.ts
|
|
43790
|
+
function useSectionController() {
|
|
43791
|
+
const {
|
|
43792
|
+
add: _add,
|
|
43793
|
+
getAll: _getAll,
|
|
43794
|
+
getById: _getById,
|
|
43795
|
+
getByName: _getByName,
|
|
43796
|
+
getBySchool: _getBySchool,
|
|
43797
|
+
updateFieldById: _updateFieldById,
|
|
43798
|
+
addStudentToSection: _addStudentToSection,
|
|
43799
|
+
removeStudentFromSection: _removeStudentFromSection,
|
|
43800
|
+
deleteById: _deleteById
|
|
43801
|
+
} = useSectionRepo();
|
|
43802
|
+
const {
|
|
43803
|
+
generateSections: _generateSections,
|
|
43804
|
+
generateSectionPreview: _generateSectionPreview
|
|
43805
|
+
} = useSectionService();
|
|
43806
|
+
async function add(req, res, next) {
|
|
43807
|
+
const value = req.body;
|
|
43808
|
+
const { error } = schemaSection.validate(value);
|
|
43809
|
+
if (error) {
|
|
43810
|
+
next(new BadRequestError68(error.message));
|
|
43811
|
+
return;
|
|
43812
|
+
}
|
|
43813
|
+
try {
|
|
43814
|
+
const data = await _add(value);
|
|
43815
|
+
res.json({
|
|
43816
|
+
message: "Successfully created section.",
|
|
43817
|
+
data
|
|
43818
|
+
});
|
|
43819
|
+
return;
|
|
43820
|
+
} catch (error2) {
|
|
43821
|
+
next(error2);
|
|
43822
|
+
}
|
|
43823
|
+
}
|
|
43824
|
+
async function generateSections(req, res, next) {
|
|
43825
|
+
const value = req.body;
|
|
43826
|
+
const { error } = schemaGenerateSections.validate(value);
|
|
43827
|
+
if (error) {
|
|
43828
|
+
next(new BadRequestError68(error.message));
|
|
43829
|
+
return;
|
|
43830
|
+
}
|
|
43831
|
+
try {
|
|
43832
|
+
const data = await _generateSections(value);
|
|
43833
|
+
res.json({
|
|
43834
|
+
message: "Successfully created section.",
|
|
43835
|
+
data
|
|
43836
|
+
});
|
|
43837
|
+
return;
|
|
43838
|
+
} catch (error2) {
|
|
43839
|
+
next(error2);
|
|
43840
|
+
}
|
|
43841
|
+
}
|
|
43842
|
+
async function generateSectionPreview(req, res, next) {
|
|
43843
|
+
const value = req.body;
|
|
43844
|
+
const { error } = schemaGenerateSections.validate(value);
|
|
43845
|
+
if (error) {
|
|
43846
|
+
next(new BadRequestError68(error.message));
|
|
43847
|
+
return;
|
|
43848
|
+
}
|
|
43849
|
+
try {
|
|
43850
|
+
const data = await _generateSectionPreview(value);
|
|
43851
|
+
res.json(data);
|
|
43852
|
+
return;
|
|
43853
|
+
} catch (error2) {
|
|
43854
|
+
next(error2);
|
|
43855
|
+
}
|
|
43856
|
+
}
|
|
43857
|
+
async function getAll(req, res, next) {
|
|
43858
|
+
const query = req.query;
|
|
43859
|
+
const validation = Joi45.object({
|
|
43860
|
+
page: Joi45.number().min(1).optional().allow("", null),
|
|
43861
|
+
limit: Joi45.number().min(1).optional().allow("", null),
|
|
43862
|
+
search: Joi45.string().optional().allow("", null),
|
|
43863
|
+
status: Joi45.string().optional().allow("", null),
|
|
43864
|
+
school: Joi45.string().hex().optional().allow("", null),
|
|
43865
|
+
schoolYear: Joi45.string().optional().allow("", null),
|
|
43866
|
+
gradeLevel: Joi45.string().optional().allow("", null)
|
|
43867
|
+
});
|
|
43868
|
+
const { error } = validation.validate(query);
|
|
43869
|
+
const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
|
|
43870
|
+
const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
|
|
43871
|
+
const search = req.query.search ?? "";
|
|
43872
|
+
const status = req.query.status ?? "active";
|
|
43873
|
+
const school = req.query.school ?? "";
|
|
43874
|
+
const schoolYear = req.query.schoolYear ?? "";
|
|
43875
|
+
const gradeLevel = req.query.gradeLevel ?? "";
|
|
43876
|
+
const isPageNumber = isFinite(page);
|
|
43877
|
+
if (!isPageNumber) {
|
|
43878
|
+
next(new BadRequestError68("Invalid page number."));
|
|
43879
|
+
return;
|
|
43880
|
+
}
|
|
43881
|
+
const isLimitNumber = isFinite(limit);
|
|
43882
|
+
if (!isLimitNumber) {
|
|
43883
|
+
next(new BadRequestError68("Invalid limit number."));
|
|
43884
|
+
return;
|
|
43885
|
+
}
|
|
43886
|
+
if (error) {
|
|
43887
|
+
next(new BadRequestError68(error.message));
|
|
43888
|
+
return;
|
|
43889
|
+
}
|
|
43890
|
+
try {
|
|
43891
|
+
const data = await _getAll({
|
|
43892
|
+
page,
|
|
43893
|
+
limit,
|
|
43894
|
+
search,
|
|
43895
|
+
status,
|
|
43896
|
+
school,
|
|
43897
|
+
schoolYear,
|
|
43898
|
+
gradeLevel
|
|
43899
|
+
});
|
|
43900
|
+
res.json(data);
|
|
43901
|
+
return;
|
|
43902
|
+
} catch (error2) {
|
|
43903
|
+
next(error2);
|
|
43904
|
+
}
|
|
43905
|
+
}
|
|
43906
|
+
async function getById(req, res, next) {
|
|
43907
|
+
const id = req.params.id;
|
|
43908
|
+
const validation = Joi45.object({
|
|
43909
|
+
id: Joi45.string().hex().required()
|
|
43910
|
+
});
|
|
43911
|
+
const { error } = validation.validate({ id });
|
|
43912
|
+
if (error) {
|
|
43913
|
+
next(new BadRequestError68(error.message));
|
|
43914
|
+
return;
|
|
43915
|
+
}
|
|
43916
|
+
try {
|
|
43917
|
+
const data = await _getById(id);
|
|
43918
|
+
res.json(data);
|
|
43919
|
+
return;
|
|
43920
|
+
} catch (error2) {
|
|
43921
|
+
next(error2);
|
|
43922
|
+
}
|
|
43923
|
+
}
|
|
43924
|
+
async function getByName(req, res, next) {
|
|
43925
|
+
const name = req.params.name;
|
|
43926
|
+
const validation = Joi45.object({
|
|
43927
|
+
name: Joi45.string().required()
|
|
43928
|
+
});
|
|
43929
|
+
const { error } = validation.validate({ name });
|
|
43930
|
+
if (error) {
|
|
43931
|
+
next(new BadRequestError68(error.message));
|
|
43932
|
+
return;
|
|
43933
|
+
}
|
|
43934
|
+
try {
|
|
43935
|
+
const data = await _getByName(name);
|
|
43936
|
+
res.json({
|
|
43937
|
+
message: "Successfully retrieved section.",
|
|
43938
|
+
data
|
|
43939
|
+
});
|
|
43940
|
+
return;
|
|
43941
|
+
} catch (error2) {
|
|
43942
|
+
next(error2);
|
|
43943
|
+
}
|
|
43944
|
+
}
|
|
43945
|
+
async function getBySchool(req, res, next) {
|
|
43946
|
+
const school = req.params.school;
|
|
43947
|
+
const validation = Joi45.object({
|
|
43948
|
+
school: Joi45.string().hex().required()
|
|
43949
|
+
});
|
|
43950
|
+
const { error } = validation.validate({ school });
|
|
43951
|
+
if (error) {
|
|
43952
|
+
next(new BadRequestError68(error.message));
|
|
43953
|
+
return;
|
|
43954
|
+
}
|
|
43955
|
+
try {
|
|
43956
|
+
const data = await _getBySchool(school);
|
|
43957
|
+
res.json({
|
|
43958
|
+
message: "Successfully retrieved sections.",
|
|
43959
|
+
data
|
|
43960
|
+
});
|
|
43961
|
+
return;
|
|
43962
|
+
} catch (error2) {
|
|
43963
|
+
next(error2);
|
|
43964
|
+
}
|
|
43965
|
+
}
|
|
43966
|
+
async function updateField(req, res, next) {
|
|
43967
|
+
const _id = req.params.id;
|
|
43968
|
+
const { field, value } = req.body;
|
|
43969
|
+
const validation = Joi45.object({
|
|
43970
|
+
_id: Joi45.string().hex().required(),
|
|
43971
|
+
field: Joi45.string().valid("name", "schoolYear", "gradeLevel", "adviser", "adviserName").required(),
|
|
43972
|
+
value: Joi45.string().required()
|
|
43973
|
+
});
|
|
43974
|
+
const { error } = validation.validate({ _id, field, value });
|
|
43975
|
+
if (error) {
|
|
43976
|
+
next(new BadRequestError68(error.message));
|
|
43977
|
+
return;
|
|
43978
|
+
}
|
|
43979
|
+
try {
|
|
43980
|
+
const message = await _updateFieldById({ _id, field, value });
|
|
43981
|
+
res.json({ message });
|
|
43982
|
+
return;
|
|
43983
|
+
} catch (error2) {
|
|
43984
|
+
next(error2);
|
|
43985
|
+
}
|
|
43986
|
+
}
|
|
43987
|
+
async function addStudent(req, res, next) {
|
|
43988
|
+
const _id = req.params.id;
|
|
43989
|
+
const { studentId } = req.body;
|
|
43990
|
+
const validation = Joi45.object({
|
|
43991
|
+
_id: Joi45.string().hex().required(),
|
|
43992
|
+
studentId: Joi45.string().required()
|
|
43993
|
+
});
|
|
43994
|
+
const { error } = validation.validate({ _id, studentId });
|
|
43995
|
+
if (error) {
|
|
43996
|
+
next(new BadRequestError68(error.message));
|
|
43997
|
+
return;
|
|
43998
|
+
}
|
|
43999
|
+
try {
|
|
44000
|
+
const message = await _addStudentToSection(_id, studentId);
|
|
44001
|
+
res.json({ message });
|
|
44002
|
+
return;
|
|
44003
|
+
} catch (error2) {
|
|
44004
|
+
next(error2);
|
|
44005
|
+
}
|
|
44006
|
+
}
|
|
44007
|
+
async function removeStudent(req, res, next) {
|
|
44008
|
+
const _id = req.params.id;
|
|
44009
|
+
const { studentId } = req.body;
|
|
44010
|
+
const validation = Joi45.object({
|
|
44011
|
+
_id: Joi45.string().hex().required(),
|
|
44012
|
+
studentId: Joi45.string().required()
|
|
44013
|
+
});
|
|
44014
|
+
const { error } = validation.validate({ _id, studentId });
|
|
44015
|
+
if (error) {
|
|
44016
|
+
next(new BadRequestError68(error.message));
|
|
44017
|
+
return;
|
|
44018
|
+
}
|
|
44019
|
+
try {
|
|
44020
|
+
const message = await _removeStudentFromSection(_id, studentId);
|
|
44021
|
+
res.json({ message });
|
|
44022
|
+
return;
|
|
44023
|
+
} catch (error2) {
|
|
44024
|
+
next(error2);
|
|
44025
|
+
}
|
|
44026
|
+
}
|
|
44027
|
+
async function deleteById(req, res, next) {
|
|
44028
|
+
const _id = req.params.id;
|
|
44029
|
+
const validation = Joi45.object({
|
|
44030
|
+
_id: Joi45.string().hex().required()
|
|
44031
|
+
});
|
|
44032
|
+
const { error } = validation.validate({ _id });
|
|
44033
|
+
if (error) {
|
|
44034
|
+
next(new BadRequestError68(error.message));
|
|
44035
|
+
return;
|
|
44036
|
+
}
|
|
44037
|
+
try {
|
|
44038
|
+
const message = await _deleteById(_id);
|
|
44039
|
+
res.json({ message });
|
|
44040
|
+
return;
|
|
44041
|
+
} catch (error2) {
|
|
44042
|
+
next(error2);
|
|
44043
|
+
}
|
|
44044
|
+
}
|
|
44045
|
+
return {
|
|
44046
|
+
add,
|
|
44047
|
+
generateSections,
|
|
44048
|
+
generateSectionPreview,
|
|
44049
|
+
getAll,
|
|
44050
|
+
getById,
|
|
44051
|
+
getByName,
|
|
44052
|
+
getBySchool,
|
|
44053
|
+
updateField,
|
|
44054
|
+
addStudent,
|
|
44055
|
+
removeStudent,
|
|
44056
|
+
deleteById
|
|
44057
|
+
};
|
|
44058
|
+
}
|
|
44059
|
+
|
|
44060
|
+
// src/resources/section-student/section.student.controller.ts
|
|
44061
|
+
import { BadRequestError as BadRequestError69 } from "@eeplatform/nodejs-utils";
|
|
44062
|
+
import Joi46 from "joi";
|
|
44063
|
+
function useSectionStudentController() {
|
|
44064
|
+
const { add: _add, getAll: _getAll } = useSectionStudentRepo();
|
|
44065
|
+
async function add(req, res, next) {
|
|
44066
|
+
const value = req.body;
|
|
44067
|
+
const { error } = schemaSectionStudent.validate(value);
|
|
44068
|
+
if (error) {
|
|
44069
|
+
next(new BadRequestError69(error.message));
|
|
44070
|
+
return;
|
|
44071
|
+
}
|
|
44072
|
+
try {
|
|
44073
|
+
const data = await _add(value);
|
|
44074
|
+
res.json({
|
|
44075
|
+
message: "Successfully created section student.",
|
|
44076
|
+
data
|
|
44077
|
+
});
|
|
44078
|
+
return;
|
|
44079
|
+
} catch (error2) {
|
|
44080
|
+
next(error2);
|
|
44081
|
+
}
|
|
44082
|
+
}
|
|
44083
|
+
async function getAll(req, res, next) {
|
|
44084
|
+
const query = req.query;
|
|
44085
|
+
const validation = Joi46.object({
|
|
44086
|
+
page: Joi46.number().min(1).optional().allow("", null),
|
|
44087
|
+
limit: Joi46.number().min(1).optional().allow("", null),
|
|
44088
|
+
search: Joi46.string().optional().allow("", null),
|
|
44089
|
+
status: Joi46.string().optional().allow("", null),
|
|
44090
|
+
school: Joi46.string().optional().allow("", null),
|
|
44091
|
+
gradeLevel: Joi46.string().optional().allow("", null),
|
|
44092
|
+
section: Joi46.string().optional().allow("", null),
|
|
44093
|
+
schoolYear: Joi46.string().optional().allow("", null)
|
|
44094
|
+
});
|
|
44095
|
+
const { error } = validation.validate(query);
|
|
44096
|
+
const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
|
|
44097
|
+
const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
|
|
44098
|
+
const search = req.query.search ?? "";
|
|
44099
|
+
const status = req.query.status ?? "active";
|
|
44100
|
+
const school = req.query.school ?? "";
|
|
44101
|
+
const gradeLevel = req.query.gradeLevel ?? "";
|
|
44102
|
+
const section = req.query.section ?? "";
|
|
44103
|
+
const schoolYear = req.query.schoolYear ?? "";
|
|
44104
|
+
const isPageNumber = isFinite(page);
|
|
44105
|
+
if (!isPageNumber) {
|
|
44106
|
+
next(new BadRequestError69("Invalid page number."));
|
|
44107
|
+
return;
|
|
44108
|
+
}
|
|
44109
|
+
const isLimitNumber = isFinite(limit);
|
|
44110
|
+
if (!isLimitNumber) {
|
|
44111
|
+
next(new BadRequestError69("Invalid limit number."));
|
|
44112
|
+
return;
|
|
44113
|
+
}
|
|
44114
|
+
if (error) {
|
|
44115
|
+
next(new BadRequestError69(error.message));
|
|
44116
|
+
return;
|
|
44117
|
+
}
|
|
44118
|
+
try {
|
|
44119
|
+
const data = await _getAll({
|
|
44120
|
+
page,
|
|
44121
|
+
limit,
|
|
44122
|
+
search,
|
|
44123
|
+
status,
|
|
44124
|
+
school,
|
|
44125
|
+
gradeLevel,
|
|
44126
|
+
section,
|
|
44127
|
+
schoolYear
|
|
44128
|
+
});
|
|
44129
|
+
res.json(data);
|
|
44130
|
+
return;
|
|
44131
|
+
} catch (error2) {
|
|
44132
|
+
next(error2);
|
|
44133
|
+
}
|
|
44134
|
+
}
|
|
44135
|
+
return {
|
|
44136
|
+
add,
|
|
44137
|
+
getAll
|
|
44138
|
+
};
|
|
44139
|
+
}
|
|
44140
|
+
|
|
44141
|
+
// src/resources/building/building.model.ts
|
|
44142
|
+
import { BadRequestError as BadRequestError70, logger as logger40 } from "@eeplatform/nodejs-utils";
|
|
44143
|
+
import Joi47 from "joi";
|
|
44144
|
+
import { ObjectId as ObjectId43 } from "mongodb";
|
|
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") {
|
|
44190
|
+
try {
|
|
44191
|
+
value._id = new ObjectId43(value._id);
|
|
44192
|
+
} catch (error2) {
|
|
44193
|
+
throw new BadRequestError70("Invalid _id format");
|
|
44194
|
+
}
|
|
44195
|
+
}
|
|
44196
|
+
try {
|
|
44197
|
+
value.school = new ObjectId43(value.school);
|
|
44198
|
+
} catch (error2) {
|
|
44199
|
+
throw new BadRequestError70("Invalid school format");
|
|
44200
|
+
}
|
|
44201
|
+
return {
|
|
44202
|
+
_id: value._id ?? void 0,
|
|
44203
|
+
school: value.school,
|
|
44204
|
+
serial: value.serial ?? "",
|
|
44205
|
+
name: value.name ?? "",
|
|
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") {
|
|
44220
|
+
try {
|
|
44221
|
+
value._id = new ObjectId43(value._id);
|
|
44222
|
+
} catch (error2) {
|
|
44223
|
+
throw new BadRequestError70("Invalid ID");
|
|
44224
|
+
}
|
|
44225
|
+
}
|
|
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
|
+
return {
|
|
44237
|
+
_id: value._id ?? void 0,
|
|
44238
|
+
school: value.school,
|
|
44239
|
+
name: value.name ?? "",
|
|
44240
|
+
building: value.building,
|
|
44241
|
+
buildingName: value.buildingName ?? "",
|
|
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 ?? ""
|
|
44254
|
+
};
|
|
44255
|
+
}
|
|
44256
|
+
|
|
44257
|
+
// src/resources/building/building.repository.ts
|
|
44258
|
+
import {
|
|
44259
|
+
AppError as AppError27,
|
|
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";
|
|
44268
|
+
import { ObjectId as ObjectId44 } from "mongodb";
|
|
44269
|
+
function useBuildingRepo() {
|
|
44270
|
+
const db = useAtlas32.getDb();
|
|
44271
|
+
if (!db) {
|
|
44272
|
+
throw new Error("Unable to connect to server.");
|
|
44273
|
+
}
|
|
44274
|
+
const namespace_collection = "deped.buildings";
|
|
44275
|
+
const collection = db.collection(namespace_collection);
|
|
44276
|
+
const { getCache, setCache, delNamespace } = useCache23(namespace_collection);
|
|
44277
|
+
async function createIndexes() {
|
|
44278
|
+
try {
|
|
44279
|
+
await collection.createIndexes([
|
|
44280
|
+
{ key: { name: 1 }, unique: true, name: "unique_name_index" },
|
|
44281
|
+
{ key: { school: 1 } },
|
|
44282
|
+
{ key: { status: 1 } }
|
|
44283
|
+
]);
|
|
44284
|
+
} catch (error) {
|
|
44285
|
+
throw new Error("Failed to create index on buildings.");
|
|
44286
|
+
}
|
|
44287
|
+
}
|
|
44288
|
+
async function add(value, session) {
|
|
44289
|
+
try {
|
|
44290
|
+
value = MBuilding(value);
|
|
44291
|
+
const res = await collection.insertOne(value, { session });
|
|
44292
|
+
delCachedData();
|
|
44293
|
+
return res.insertedId;
|
|
44294
|
+
} catch (error) {
|
|
44295
|
+
logger41.log({
|
|
44296
|
+
level: "error",
|
|
44297
|
+
message: error.message
|
|
44298
|
+
});
|
|
44299
|
+
if (error instanceof AppError27) {
|
|
44300
|
+
throw error;
|
|
44301
|
+
} else {
|
|
44302
|
+
const isDuplicated = error.message.includes("duplicate");
|
|
44303
|
+
if (isDuplicated) {
|
|
44304
|
+
throw new BadRequestError71("Building already exists.");
|
|
44305
|
+
}
|
|
44306
|
+
throw new Error("Failed to create building.");
|
|
44307
|
+
}
|
|
44308
|
+
}
|
|
44309
|
+
}
|
|
44310
|
+
async function updateById(_id, value, session) {
|
|
44311
|
+
try {
|
|
44312
|
+
_id = new ObjectId44(_id);
|
|
44313
|
+
} catch (error) {
|
|
44314
|
+
throw new BadRequestError71(namespace_collection + " Invalid ID.");
|
|
44315
|
+
}
|
|
44316
|
+
try {
|
|
44317
|
+
const res = await collection.updateOne(
|
|
44318
|
+
{ _id },
|
|
44319
|
+
{ $set: value },
|
|
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
|
+
}
|
|
44334
|
+
}
|
|
44335
|
+
}
|
|
44336
|
+
async function getAll({
|
|
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
|
+
});
|
|
44375
|
+
try {
|
|
44376
|
+
const cached = await getCache(cacheKey);
|
|
44377
|
+
if (cached) {
|
|
44378
|
+
logger41.log({
|
|
44379
|
+
level: "info",
|
|
44380
|
+
message: `Cache hit for getAll buildings: ${cacheKey}`
|
|
42943
44381
|
});
|
|
42944
|
-
|
|
42945
|
-
await addSectionSubject(
|
|
42946
|
-
{
|
|
42947
|
-
curriculum: curriculumSubject.curriculum.toString(),
|
|
42948
|
-
school: value.school,
|
|
42949
|
-
schoolName: schoolData.name,
|
|
42950
|
-
gradeLevel: value.gradeLevel,
|
|
42951
|
-
educationLevel: gradeLevelData.educationLevel,
|
|
42952
|
-
schoolYear: value.schoolYear,
|
|
42953
|
-
section: section.toString(),
|
|
42954
|
-
sectionName,
|
|
42955
|
-
subjectCode: curriculumSubject.subjectCode,
|
|
42956
|
-
subjectName: curriculumSubject.subjectName,
|
|
42957
|
-
teacher: "",
|
|
42958
|
-
teacherName: "",
|
|
42959
|
-
schedule: "",
|
|
42960
|
-
daysOfWeek: [],
|
|
42961
|
-
classroom: "",
|
|
42962
|
-
classroomName: "",
|
|
42963
|
-
sessionDuration: curriculumSubject.sessionDuration,
|
|
42964
|
-
sessionFrequency: curriculumSubject.sessionFrequency,
|
|
42965
|
-
status: "draft"
|
|
42966
|
-
},
|
|
42967
|
-
session
|
|
42968
|
-
);
|
|
42969
|
-
}
|
|
44382
|
+
return cached;
|
|
42970
44383
|
}
|
|
42971
|
-
|
|
42972
|
-
|
|
42973
|
-
|
|
42974
|
-
|
|
42975
|
-
|
|
42976
|
-
|
|
42977
|
-
|
|
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}`
|
|
42978
44396
|
});
|
|
42979
|
-
|
|
42980
|
-
|
|
42981
|
-
|
|
42982
|
-
|
|
42983
|
-
|
|
42984
|
-
|
|
42985
|
-
|
|
42986
|
-
|
|
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;
|
|
44407
|
+
}
|
|
44408
|
+
}
|
|
44409
|
+
async function getById(_id) {
|
|
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) });
|
|
44416
|
+
try {
|
|
44417
|
+
const cached = await getCache(cacheKey);
|
|
44418
|
+
if (cached) {
|
|
44419
|
+
logger41.log({
|
|
44420
|
+
level: "info",
|
|
44421
|
+
message: `Cache hit for getById building: ${cacheKey}`
|
|
44422
|
+
});
|
|
44423
|
+
return cached;
|
|
42987
44424
|
}
|
|
42988
|
-
|
|
42989
|
-
|
|
42990
|
-
|
|
42991
|
-
|
|
42992
|
-
|
|
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
|
+
}
|
|
44446
|
+
}
|
|
44447
|
+
}
|
|
44448
|
+
async function deleteById(_id, session) {
|
|
44449
|
+
try {
|
|
44450
|
+
_id = new ObjectId44(_id);
|
|
44451
|
+
} catch (error) {
|
|
44452
|
+
throw new BadRequestError71(namespace_collection + " Invalid ID.");
|
|
44453
|
+
}
|
|
44454
|
+
try {
|
|
44455
|
+
const res = await collection.updateOne(
|
|
44456
|
+
{ _id },
|
|
44457
|
+
{ $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } }
|
|
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
|
+
}
|
|
44471
|
+
}
|
|
44472
|
+
}
|
|
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
|
+
return {
|
|
44487
|
+
createIndexes,
|
|
44488
|
+
add,
|
|
44489
|
+
getAll,
|
|
44490
|
+
getById,
|
|
44491
|
+
updateById,
|
|
44492
|
+
deleteById
|
|
44493
|
+
};
|
|
44494
|
+
}
|
|
44495
|
+
|
|
44496
|
+
// src/resources/building/building.service.ts
|
|
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
|
|
44504
|
+
import {
|
|
44505
|
+
AppError as AppError28,
|
|
44506
|
+
BadRequestError as BadRequestError72,
|
|
44507
|
+
InternalServerError as InternalServerError24,
|
|
44508
|
+
logger as logger42,
|
|
44509
|
+
makeCacheKey as makeCacheKey24,
|
|
44510
|
+
paginate as paginate23,
|
|
44511
|
+
useAtlas as useAtlas33,
|
|
44512
|
+
useCache as useCache24
|
|
44513
|
+
} from "@eeplatform/nodejs-utils";
|
|
44514
|
+
import { ObjectId as ObjectId45 } from "mongodb";
|
|
44515
|
+
function useBuildingUnitRepo() {
|
|
44516
|
+
const db = useAtlas33.getDb();
|
|
44517
|
+
if (!db) {
|
|
44518
|
+
throw new Error("Unable to connect to server.");
|
|
44519
|
+
}
|
|
44520
|
+
const namespace_collection = "deped.building.units";
|
|
44521
|
+
const collection = db.collection(namespace_collection);
|
|
44522
|
+
const { getCache, setCache, delNamespace } = useCache24(namespace_collection);
|
|
44523
|
+
async function createIndexes() {
|
|
44524
|
+
try {
|
|
44525
|
+
await collection.createIndexes([
|
|
44526
|
+
{
|
|
44527
|
+
key: { name: 1, building: 1, level: 1 },
|
|
44528
|
+
unique: true,
|
|
44529
|
+
name: "unique_name_index"
|
|
44530
|
+
},
|
|
44531
|
+
{ key: { school: 1 } },
|
|
44532
|
+
{ key: { building: 1 } },
|
|
44533
|
+
{ key: { status: 1 } },
|
|
44534
|
+
{ key: { createdAt: 1 } },
|
|
44535
|
+
{
|
|
44536
|
+
key: {
|
|
44537
|
+
name: "text",
|
|
44538
|
+
buildingName: "text",
|
|
44539
|
+
category: "text",
|
|
44540
|
+
type: "text"
|
|
42993
44541
|
}
|
|
42994
|
-
await addTeachingLoad(
|
|
42995
|
-
{
|
|
42996
|
-
school: value.school,
|
|
42997
|
-
schoolName: schoolData.name,
|
|
42998
|
-
schoolYear: value.schoolYear,
|
|
42999
|
-
teacher: teacher._id.toString(),
|
|
43000
|
-
teacherName: `${teacher.firstName} ${teacher.lastName}`,
|
|
43001
|
-
status: "draft"
|
|
43002
|
-
},
|
|
43003
|
-
session
|
|
43004
|
-
);
|
|
43005
44542
|
}
|
|
43006
|
-
|
|
43007
|
-
|
|
43008
|
-
|
|
43009
|
-
}
|
|
43010
|
-
|
|
43011
|
-
|
|
43012
|
-
|
|
44543
|
+
]);
|
|
44544
|
+
} catch (error) {
|
|
44545
|
+
throw new Error("Failed to create index on building units.");
|
|
44546
|
+
}
|
|
44547
|
+
}
|
|
44548
|
+
function delCachedData() {
|
|
44549
|
+
delNamespace().then(() => {
|
|
44550
|
+
logger42.log({
|
|
44551
|
+
level: "info",
|
|
44552
|
+
message: `Cache namespace cleared for ${namespace_collection}`
|
|
44553
|
+
});
|
|
44554
|
+
}).catch((err) => {
|
|
44555
|
+
logger42.log({
|
|
44556
|
+
level: "error",
|
|
44557
|
+
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
44558
|
+
});
|
|
44559
|
+
});
|
|
44560
|
+
}
|
|
44561
|
+
async function add(value, session) {
|
|
44562
|
+
try {
|
|
44563
|
+
value = MBuildingUnit(value);
|
|
44564
|
+
const res = await collection.insertOne(value, { session });
|
|
44565
|
+
delCachedData();
|
|
44566
|
+
return res.insertedId;
|
|
44567
|
+
} catch (error) {
|
|
44568
|
+
logger42.log({
|
|
44569
|
+
level: "error",
|
|
44570
|
+
message: error.message
|
|
44571
|
+
});
|
|
44572
|
+
if (error instanceof AppError28) {
|
|
44573
|
+
throw error;
|
|
43013
44574
|
} else {
|
|
43014
|
-
throw new
|
|
44575
|
+
throw new Error("Failed to create building unit.");
|
|
43015
44576
|
}
|
|
43016
|
-
} finally {
|
|
43017
|
-
await session?.endSession();
|
|
43018
44577
|
}
|
|
43019
44578
|
}
|
|
43020
|
-
async function
|
|
43021
|
-
const { error } =
|
|
44579
|
+
async function updateById(_id, value, session) {
|
|
44580
|
+
const { error } = schemaUpdateOptions.validate(value);
|
|
43022
44581
|
if (error) {
|
|
43023
|
-
throw new
|
|
43024
|
-
`Invalid section generation data: ${error.message}`
|
|
43025
|
-
);
|
|
44582
|
+
throw new BadRequestError72(error.message);
|
|
43026
44583
|
}
|
|
43027
44584
|
try {
|
|
43028
|
-
|
|
43029
|
-
|
|
43030
|
-
|
|
43031
|
-
|
|
43032
|
-
|
|
43033
|
-
|
|
43034
|
-
|
|
43035
|
-
|
|
43036
|
-
|
|
43037
|
-
const gradeLevelData = await getByGradeLevel({
|
|
43038
|
-
school: value.school,
|
|
43039
|
-
gradeLevel: value.gradeLevel
|
|
43040
|
-
});
|
|
43041
|
-
if (!gradeLevelData) {
|
|
43042
|
-
throw new BadRequestError64("Grade level not found.");
|
|
43043
|
-
}
|
|
43044
|
-
const minPerSection = value.minStudents ?? gradeLevelData.minNumberOfLearners;
|
|
43045
|
-
const maxPerSection = value.maxStudents ?? gradeLevelData.maxNumberOfLearners;
|
|
43046
|
-
const sectionsNeeded = Math.ceil(studentCount / minPerSection);
|
|
43047
|
-
if (sectionsNeeded > value.set.length) {
|
|
43048
|
-
throw new BadRequestError64(
|
|
43049
|
-
"Insufficient number of section names in set[]."
|
|
43050
|
-
);
|
|
43051
|
-
}
|
|
43052
|
-
const sectionSizes = distributeStudents(
|
|
43053
|
-
studentCount,
|
|
43054
|
-
minPerSection,
|
|
43055
|
-
maxPerSection
|
|
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 }
|
|
43056
44594
|
);
|
|
43057
|
-
|
|
43058
|
-
|
|
43059
|
-
}
|
|
43060
|
-
const sections = sectionSizes.map((size, index) => ({
|
|
43061
|
-
name: value.set[index],
|
|
43062
|
-
value: size
|
|
43063
|
-
}));
|
|
43064
|
-
return {
|
|
43065
|
-
totalSectionsGenerated: sectionSizes.length,
|
|
43066
|
-
totalStudentsAssigned: studentCount,
|
|
43067
|
-
sections
|
|
43068
|
-
};
|
|
44595
|
+
delCachedData();
|
|
44596
|
+
return res;
|
|
43069
44597
|
} catch (error2) {
|
|
43070
|
-
|
|
44598
|
+
logger42.log({
|
|
44599
|
+
level: "error",
|
|
44600
|
+
message: error2.message
|
|
44601
|
+
});
|
|
44602
|
+
if (error2 instanceof AppError28) {
|
|
43071
44603
|
throw error2;
|
|
43072
44604
|
} else {
|
|
43073
|
-
throw new
|
|
44605
|
+
throw new Error("Failed to create building unit.");
|
|
43074
44606
|
}
|
|
43075
44607
|
}
|
|
43076
44608
|
}
|
|
43077
|
-
|
|
43078
|
-
}
|
|
43079
|
-
|
|
43080
|
-
// src/resources/section/section.controller.ts
|
|
43081
|
-
function useSectionController() {
|
|
43082
|
-
const {
|
|
43083
|
-
add: _add,
|
|
43084
|
-
getAll: _getAll,
|
|
43085
|
-
getById: _getById,
|
|
43086
|
-
getByName: _getByName,
|
|
43087
|
-
getBySchool: _getBySchool,
|
|
43088
|
-
updateFieldById: _updateFieldById,
|
|
43089
|
-
addStudentToSection: _addStudentToSection,
|
|
43090
|
-
removeStudentFromSection: _removeStudentFromSection,
|
|
43091
|
-
deleteById: _deleteById
|
|
43092
|
-
} = useSectionRepo();
|
|
43093
|
-
const {
|
|
43094
|
-
generateSections: _generateSections,
|
|
43095
|
-
generateSectionPreview: _generateSectionPreview
|
|
43096
|
-
} = useSectionService();
|
|
43097
|
-
async function add(req, res, next) {
|
|
43098
|
-
const value = req.body;
|
|
43099
|
-
const { error } = schemaSection.validate(value);
|
|
44609
|
+
async function updateByBuildingId(building, value, session) {
|
|
44610
|
+
const { error } = schemaUpdateOptions.validate(value);
|
|
43100
44611
|
if (error) {
|
|
43101
|
-
|
|
43102
|
-
return;
|
|
44612
|
+
throw new BadRequestError72(error.message);
|
|
43103
44613
|
}
|
|
43104
44614
|
try {
|
|
43105
|
-
|
|
43106
|
-
res.json({
|
|
43107
|
-
message: "Successfully created section.",
|
|
43108
|
-
data
|
|
43109
|
-
});
|
|
43110
|
-
return;
|
|
44615
|
+
building = new ObjectId45(building);
|
|
43111
44616
|
} catch (error2) {
|
|
43112
|
-
|
|
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.");
|
|
44636
|
+
}
|
|
43113
44637
|
}
|
|
43114
44638
|
}
|
|
43115
|
-
async function
|
|
43116
|
-
|
|
43117
|
-
|
|
43118
|
-
|
|
43119
|
-
|
|
43120
|
-
|
|
44639
|
+
async function getAll({
|
|
44640
|
+
search = "",
|
|
44641
|
+
page = 1,
|
|
44642
|
+
limit = 10,
|
|
44643
|
+
sort = {},
|
|
44644
|
+
school = "",
|
|
44645
|
+
building = "",
|
|
44646
|
+
type = "",
|
|
44647
|
+
status = "active"
|
|
44648
|
+
} = {}) {
|
|
44649
|
+
page = page > 0 ? page - 1 : 0;
|
|
44650
|
+
const query = {
|
|
44651
|
+
deletedAt: { $in: ["", null] },
|
|
44652
|
+
status: { $in: [status, "", null] }
|
|
44653
|
+
};
|
|
44654
|
+
const cacheParams = {
|
|
44655
|
+
page,
|
|
44656
|
+
limit,
|
|
44657
|
+
sort: JSON.stringify(sort)
|
|
44658
|
+
};
|
|
44659
|
+
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
44660
|
+
if (search) {
|
|
44661
|
+
query.$text = { $search: search };
|
|
44662
|
+
cacheParams.search = search;
|
|
44663
|
+
}
|
|
44664
|
+
if (school) {
|
|
44665
|
+
try {
|
|
44666
|
+
query.school = new ObjectId45(school);
|
|
44667
|
+
} catch (error) {
|
|
44668
|
+
throw new BadRequestError72("Invalid school ID.");
|
|
44669
|
+
}
|
|
44670
|
+
cacheParams.school = school;
|
|
44671
|
+
}
|
|
44672
|
+
if (building) {
|
|
44673
|
+
try {
|
|
44674
|
+
query.building = new ObjectId45(building);
|
|
44675
|
+
} catch (error) {
|
|
44676
|
+
throw new BadRequestError72("Invalid building ID.");
|
|
44677
|
+
}
|
|
44678
|
+
cacheParams.building = building;
|
|
44679
|
+
}
|
|
44680
|
+
if (type) {
|
|
44681
|
+
query.type = type;
|
|
44682
|
+
cacheParams.type = type;
|
|
43121
44683
|
}
|
|
44684
|
+
const cacheKey = makeCacheKey24(namespace_collection, cacheParams);
|
|
44685
|
+
logger42.log({
|
|
44686
|
+
level: "info",
|
|
44687
|
+
message: `Cache key for getAll building units: ${cacheKey}`
|
|
44688
|
+
});
|
|
43122
44689
|
try {
|
|
43123
|
-
const
|
|
43124
|
-
|
|
43125
|
-
|
|
43126
|
-
|
|
44690
|
+
const cached = await getCache(cacheKey);
|
|
44691
|
+
if (cached) {
|
|
44692
|
+
logger42.log({
|
|
44693
|
+
level: "info",
|
|
44694
|
+
message: `Cache hit for getAll building units: ${cacheKey}`
|
|
44695
|
+
});
|
|
44696
|
+
return cached;
|
|
44697
|
+
}
|
|
44698
|
+
const items = await collection.aggregate([
|
|
44699
|
+
{ $match: query },
|
|
44700
|
+
{ $sort: sort },
|
|
44701
|
+
{ $skip: page * limit },
|
|
44702
|
+
{ $limit: limit }
|
|
44703
|
+
]).toArray();
|
|
44704
|
+
const length = await collection.countDocuments(query);
|
|
44705
|
+
const data = paginate23(items, page, limit, length);
|
|
44706
|
+
setCache(cacheKey, data, 600).then(() => {
|
|
44707
|
+
logger42.log({
|
|
44708
|
+
level: "info",
|
|
44709
|
+
message: `Cache set for getAll building units: ${cacheKey}`
|
|
44710
|
+
});
|
|
44711
|
+
}).catch((err) => {
|
|
44712
|
+
logger42.log({
|
|
44713
|
+
level: "error",
|
|
44714
|
+
message: `Failed to set cache for getAll building units: ${err.message}`
|
|
44715
|
+
});
|
|
43127
44716
|
});
|
|
43128
|
-
return;
|
|
43129
|
-
} catch (
|
|
43130
|
-
|
|
44717
|
+
return data;
|
|
44718
|
+
} catch (error) {
|
|
44719
|
+
logger42.log({ level: "error", message: `${error}` });
|
|
44720
|
+
throw error;
|
|
43131
44721
|
}
|
|
43132
44722
|
}
|
|
43133
|
-
async function
|
|
43134
|
-
const
|
|
43135
|
-
|
|
43136
|
-
|
|
43137
|
-
|
|
43138
|
-
|
|
43139
|
-
|
|
44723
|
+
async function countByBuilding(building, level) {
|
|
44724
|
+
const query = {
|
|
44725
|
+
status: "active"
|
|
44726
|
+
};
|
|
44727
|
+
const cacheKeyOptions = {
|
|
44728
|
+
...query,
|
|
44729
|
+
tag: "countByBuilding"
|
|
44730
|
+
};
|
|
43140
44731
|
try {
|
|
43141
|
-
|
|
43142
|
-
|
|
43143
|
-
|
|
43144
|
-
|
|
43145
|
-
next(error2);
|
|
44732
|
+
query.building = new ObjectId45(building);
|
|
44733
|
+
cacheKeyOptions.building = String(building);
|
|
44734
|
+
} catch (error) {
|
|
44735
|
+
throw new BadRequestError72("Invalid building ID.");
|
|
43146
44736
|
}
|
|
43147
|
-
|
|
43148
|
-
|
|
43149
|
-
|
|
43150
|
-
const validation = Joi43.object({
|
|
43151
|
-
page: Joi43.number().min(1).optional().allow("", null),
|
|
43152
|
-
limit: Joi43.number().min(1).optional().allow("", null),
|
|
43153
|
-
search: Joi43.string().optional().allow("", null),
|
|
43154
|
-
status: Joi43.string().optional().allow("", null),
|
|
43155
|
-
school: Joi43.string().hex().optional().allow("", null),
|
|
43156
|
-
schoolYear: Joi43.string().optional().allow("", null),
|
|
43157
|
-
gradeLevel: Joi43.string().optional().allow("", null)
|
|
43158
|
-
});
|
|
43159
|
-
const { error } = validation.validate(query);
|
|
43160
|
-
const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
|
|
43161
|
-
const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
|
|
43162
|
-
const search = req.query.search ?? "";
|
|
43163
|
-
const status = req.query.status ?? "active";
|
|
43164
|
-
const school = req.query.school ?? "";
|
|
43165
|
-
const schoolYear = req.query.schoolYear ?? "";
|
|
43166
|
-
const gradeLevel = req.query.gradeLevel ?? "";
|
|
43167
|
-
const isPageNumber = isFinite(page);
|
|
43168
|
-
if (!isPageNumber) {
|
|
43169
|
-
next(new BadRequestError65("Invalid page number."));
|
|
43170
|
-
return;
|
|
44737
|
+
if (level) {
|
|
44738
|
+
query.level = level;
|
|
44739
|
+
cacheKeyOptions.level = level;
|
|
43171
44740
|
}
|
|
43172
|
-
|
|
43173
|
-
|
|
43174
|
-
|
|
43175
|
-
|
|
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.");
|
|
43176
44746
|
}
|
|
43177
|
-
|
|
43178
|
-
|
|
43179
|
-
|
|
44747
|
+
}
|
|
44748
|
+
async function getById(_id) {
|
|
44749
|
+
try {
|
|
44750
|
+
_id = new ObjectId45(_id);
|
|
44751
|
+
} catch (error) {
|
|
44752
|
+
throw new BadRequestError72(namespace_collection + " Invalid ID.");
|
|
43180
44753
|
}
|
|
44754
|
+
const cacheKey = makeCacheKey24(namespace_collection, { _id: String(_id) });
|
|
43181
44755
|
try {
|
|
43182
|
-
const
|
|
43183
|
-
|
|
43184
|
-
|
|
43185
|
-
|
|
43186
|
-
|
|
43187
|
-
|
|
43188
|
-
|
|
43189
|
-
|
|
44756
|
+
const cached = await getCache(cacheKey);
|
|
44757
|
+
if (cached) {
|
|
44758
|
+
logger42.log({
|
|
44759
|
+
level: "info",
|
|
44760
|
+
message: `Cache hit for getById building unit: ${cacheKey}`
|
|
44761
|
+
});
|
|
44762
|
+
return cached;
|
|
44763
|
+
}
|
|
44764
|
+
const result = await collection.findOne({
|
|
44765
|
+
_id,
|
|
44766
|
+
deletedAt: { $in: ["", null] }
|
|
43190
44767
|
});
|
|
43191
|
-
|
|
43192
|
-
|
|
43193
|
-
|
|
43194
|
-
|
|
44768
|
+
if (!result) {
|
|
44769
|
+
throw new BadRequestError72("Building unit not found.");
|
|
44770
|
+
}
|
|
44771
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
44772
|
+
logger42.log({
|
|
44773
|
+
level: "info",
|
|
44774
|
+
message: `Cache set for building unit by id: ${cacheKey}`
|
|
44775
|
+
});
|
|
44776
|
+
}).catch((err) => {
|
|
44777
|
+
logger42.log({
|
|
44778
|
+
level: "error",
|
|
44779
|
+
message: `Failed to set cache for building unit by id: ${err.message}`
|
|
44780
|
+
});
|
|
44781
|
+
});
|
|
44782
|
+
return result;
|
|
44783
|
+
} catch (error) {
|
|
44784
|
+
if (error instanceof AppError28) {
|
|
44785
|
+
throw error;
|
|
44786
|
+
} else {
|
|
44787
|
+
throw new InternalServerError24("Failed to get building unit.");
|
|
44788
|
+
}
|
|
43195
44789
|
}
|
|
43196
44790
|
}
|
|
43197
|
-
async function
|
|
43198
|
-
const id = req.params.id;
|
|
43199
|
-
const validation = Joi43.object({
|
|
43200
|
-
id: Joi43.string().hex().required()
|
|
43201
|
-
});
|
|
43202
|
-
const { error } = validation.validate({ id });
|
|
43203
|
-
if (error) {
|
|
43204
|
-
next(new BadRequestError65(error.message));
|
|
43205
|
-
return;
|
|
43206
|
-
}
|
|
44791
|
+
async function getByBuildingLevel(building, level) {
|
|
43207
44792
|
try {
|
|
43208
|
-
|
|
43209
|
-
|
|
43210
|
-
|
|
43211
|
-
} catch (error2) {
|
|
43212
|
-
next(error2);
|
|
44793
|
+
building = new ObjectId45(building);
|
|
44794
|
+
} catch (error) {
|
|
44795
|
+
throw new BadRequestError72("Invalid building ID.");
|
|
43213
44796
|
}
|
|
43214
|
-
|
|
43215
|
-
|
|
43216
|
-
|
|
43217
|
-
const validation = Joi43.object({
|
|
43218
|
-
name: Joi43.string().required()
|
|
44797
|
+
const cacheKey = makeCacheKey24(namespace_collection, {
|
|
44798
|
+
building: String(building),
|
|
44799
|
+
level
|
|
43219
44800
|
});
|
|
43220
|
-
const { error } = validation.validate({ name });
|
|
43221
|
-
if (error) {
|
|
43222
|
-
next(new BadRequestError65(error.message));
|
|
43223
|
-
return;
|
|
43224
|
-
}
|
|
43225
44801
|
try {
|
|
43226
|
-
const
|
|
43227
|
-
|
|
43228
|
-
|
|
43229
|
-
|
|
44802
|
+
const cached = await getCache(cacheKey);
|
|
44803
|
+
if (cached) {
|
|
44804
|
+
logger42.log({
|
|
44805
|
+
level: "info",
|
|
44806
|
+
message: `Cache hit for getById building unit: ${cacheKey}`
|
|
44807
|
+
});
|
|
44808
|
+
return cached;
|
|
44809
|
+
}
|
|
44810
|
+
const result = await collection.findOne({
|
|
44811
|
+
building,
|
|
44812
|
+
level,
|
|
44813
|
+
status: "active"
|
|
43230
44814
|
});
|
|
43231
|
-
|
|
43232
|
-
|
|
43233
|
-
|
|
44815
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
44816
|
+
logger42.log({
|
|
44817
|
+
level: "info",
|
|
44818
|
+
message: `Cache set for building unit by id: ${cacheKey}`
|
|
44819
|
+
});
|
|
44820
|
+
}).catch((err) => {
|
|
44821
|
+
logger42.log({
|
|
44822
|
+
level: "error",
|
|
44823
|
+
message: `Failed to set cache for building unit by id: ${err.message}`
|
|
44824
|
+
});
|
|
44825
|
+
});
|
|
44826
|
+
return result;
|
|
44827
|
+
} catch (error) {
|
|
44828
|
+
if (error instanceof AppError28) {
|
|
44829
|
+
throw error;
|
|
44830
|
+
} else {
|
|
44831
|
+
throw new InternalServerError24("Failed to get building unit.");
|
|
44832
|
+
}
|
|
43234
44833
|
}
|
|
43235
44834
|
}
|
|
43236
|
-
async function
|
|
43237
|
-
|
|
43238
|
-
|
|
43239
|
-
|
|
43240
|
-
|
|
43241
|
-
const { error } = validation.validate({ school });
|
|
43242
|
-
if (error) {
|
|
43243
|
-
next(new BadRequestError65(error.message));
|
|
43244
|
-
return;
|
|
44835
|
+
async function getByBuilding(building) {
|
|
44836
|
+
try {
|
|
44837
|
+
building = new ObjectId45(building);
|
|
44838
|
+
} catch (error) {
|
|
44839
|
+
throw new BadRequestError72("Invalid building ID.");
|
|
43245
44840
|
}
|
|
44841
|
+
const cacheKey = makeCacheKey24(namespace_collection, {
|
|
44842
|
+
building: String(building)
|
|
44843
|
+
});
|
|
43246
44844
|
try {
|
|
43247
|
-
const
|
|
43248
|
-
|
|
43249
|
-
|
|
43250
|
-
|
|
44845
|
+
const cached = await getCache(cacheKey);
|
|
44846
|
+
if (cached) {
|
|
44847
|
+
logger42.log({
|
|
44848
|
+
level: "info",
|
|
44849
|
+
message: `Cache hit for getById building unit: ${cacheKey}`
|
|
44850
|
+
});
|
|
44851
|
+
return cached;
|
|
44852
|
+
}
|
|
44853
|
+
const result = await collection.findOne({
|
|
44854
|
+
building,
|
|
44855
|
+
status: "active"
|
|
43251
44856
|
});
|
|
43252
|
-
|
|
43253
|
-
|
|
43254
|
-
|
|
44857
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
44858
|
+
logger42.log({
|
|
44859
|
+
level: "info",
|
|
44860
|
+
message: `Cache set for building unit by id: ${cacheKey}`
|
|
44861
|
+
});
|
|
44862
|
+
}).catch((err) => {
|
|
44863
|
+
logger42.log({
|
|
44864
|
+
level: "error",
|
|
44865
|
+
message: `Failed to set cache for building unit by id: ${err.message}`
|
|
44866
|
+
});
|
|
44867
|
+
});
|
|
44868
|
+
return result;
|
|
44869
|
+
} catch (error) {
|
|
44870
|
+
if (error instanceof AppError28) {
|
|
44871
|
+
throw error;
|
|
44872
|
+
} else {
|
|
44873
|
+
throw new InternalServerError24("Failed to get building unit.");
|
|
44874
|
+
}
|
|
43255
44875
|
}
|
|
43256
44876
|
}
|
|
43257
|
-
async function
|
|
43258
|
-
|
|
43259
|
-
|
|
43260
|
-
|
|
43261
|
-
|
|
43262
|
-
field: Joi43.string().valid("name", "schoolYear", "gradeLevel", "adviser", "adviserName").required(),
|
|
43263
|
-
value: Joi43.string().required()
|
|
43264
|
-
});
|
|
43265
|
-
const { error } = validation.validate({ _id, field, value });
|
|
43266
|
-
if (error) {
|
|
43267
|
-
next(new BadRequestError65(error.message));
|
|
43268
|
-
return;
|
|
44877
|
+
async function deleteById(_id, session) {
|
|
44878
|
+
try {
|
|
44879
|
+
_id = new ObjectId45(_id);
|
|
44880
|
+
} catch (error) {
|
|
44881
|
+
throw new BadRequestError72(namespace_collection + " Invalid ID.");
|
|
43269
44882
|
}
|
|
43270
44883
|
try {
|
|
43271
|
-
const
|
|
43272
|
-
|
|
43273
|
-
|
|
43274
|
-
|
|
43275
|
-
|
|
44884
|
+
const res = await collection.updateOne(
|
|
44885
|
+
{ _id },
|
|
44886
|
+
{ $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } },
|
|
44887
|
+
{ session }
|
|
44888
|
+
);
|
|
44889
|
+
delCachedData();
|
|
44890
|
+
return "Room/Facility deleted successfully.";
|
|
44891
|
+
} catch (error) {
|
|
44892
|
+
logger42.log({
|
|
44893
|
+
level: "error",
|
|
44894
|
+
message: error.message
|
|
44895
|
+
});
|
|
44896
|
+
if (error instanceof AppError28) {
|
|
44897
|
+
throw error;
|
|
44898
|
+
} else {
|
|
44899
|
+
throw new Error("Failed to deleted room/facility.");
|
|
44900
|
+
}
|
|
43276
44901
|
}
|
|
43277
44902
|
}
|
|
43278
|
-
|
|
43279
|
-
|
|
43280
|
-
|
|
43281
|
-
|
|
43282
|
-
|
|
43283
|
-
|
|
43284
|
-
|
|
43285
|
-
|
|
43286
|
-
|
|
43287
|
-
|
|
43288
|
-
|
|
43289
|
-
|
|
43290
|
-
|
|
43291
|
-
|
|
43292
|
-
|
|
43293
|
-
|
|
43294
|
-
|
|
43295
|
-
|
|
44903
|
+
return {
|
|
44904
|
+
createIndexes,
|
|
44905
|
+
add,
|
|
44906
|
+
getAll,
|
|
44907
|
+
getById,
|
|
44908
|
+
getByBuildingLevel,
|
|
44909
|
+
updateById,
|
|
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();
|
|
44928
|
+
try {
|
|
44929
|
+
const building = await _getById(id);
|
|
44930
|
+
if (!building) {
|
|
44931
|
+
throw new NotFoundError3("Building not found.");
|
|
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();
|
|
43296
44953
|
}
|
|
43297
44954
|
}
|
|
43298
|
-
async function
|
|
43299
|
-
const
|
|
43300
|
-
|
|
43301
|
-
|
|
43302
|
-
|
|
43303
|
-
|
|
43304
|
-
});
|
|
43305
|
-
const { error } = validation.validate({ _id, studentId });
|
|
43306
|
-
if (error) {
|
|
43307
|
-
next(new BadRequestError65(error.message));
|
|
43308
|
-
return;
|
|
44955
|
+
async function deleteById(id) {
|
|
44956
|
+
const building = await getByBuilding(id);
|
|
44957
|
+
if (building) {
|
|
44958
|
+
throw new BadRequestError73(
|
|
44959
|
+
"Cannot delete building with existing room/facility. Please delete room/facility first."
|
|
44960
|
+
);
|
|
43309
44961
|
}
|
|
43310
44962
|
try {
|
|
43311
|
-
|
|
43312
|
-
|
|
43313
|
-
|
|
43314
|
-
|
|
43315
|
-
next(error2);
|
|
44963
|
+
await _deleteById(id);
|
|
44964
|
+
return "Building deleted successfully.";
|
|
44965
|
+
} catch (error) {
|
|
44966
|
+
throw error;
|
|
43316
44967
|
}
|
|
43317
44968
|
}
|
|
43318
|
-
|
|
43319
|
-
|
|
43320
|
-
|
|
43321
|
-
|
|
44969
|
+
return {
|
|
44970
|
+
updateById,
|
|
44971
|
+
deleteById
|
|
44972
|
+
};
|
|
44973
|
+
}
|
|
44974
|
+
|
|
44975
|
+
// src/resources/building/building.controller.ts
|
|
44976
|
+
import { BadRequestError as BadRequestError74, logger as logger43 } from "@eeplatform/nodejs-utils";
|
|
44977
|
+
import Joi48 from "joi";
|
|
44978
|
+
function useBuildingController() {
|
|
44979
|
+
const { getAll: _getAll, getById: _getById, add: _add } = useBuildingRepo();
|
|
44980
|
+
const { updateById: _updateById, deleteById: _deleteById } = useBuildingService();
|
|
44981
|
+
async function createBuilding(req, res, next) {
|
|
44982
|
+
const value = req.body;
|
|
44983
|
+
const validation = Joi48.object({
|
|
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)
|
|
43322
44989
|
});
|
|
43323
|
-
const { error } = validation.validate(
|
|
44990
|
+
const { error } = validation.validate(value);
|
|
43324
44991
|
if (error) {
|
|
43325
|
-
next(new
|
|
44992
|
+
next(new BadRequestError74(error.message));
|
|
44993
|
+
logger43.info(`Controller: ${error.message}`);
|
|
43326
44994
|
return;
|
|
43327
44995
|
}
|
|
43328
44996
|
try {
|
|
43329
|
-
const
|
|
43330
|
-
res.json(
|
|
44997
|
+
const result = await _add(value);
|
|
44998
|
+
res.json(result);
|
|
43331
44999
|
return;
|
|
43332
45000
|
} catch (error2) {
|
|
43333
45001
|
next(error2);
|
|
43334
45002
|
}
|
|
43335
45003
|
}
|
|
43336
|
-
|
|
43337
|
-
add,
|
|
43338
|
-
generateSections,
|
|
43339
|
-
generateSectionPreview,
|
|
43340
|
-
getAll,
|
|
43341
|
-
getById,
|
|
43342
|
-
getByName,
|
|
43343
|
-
getBySchool,
|
|
43344
|
-
updateField,
|
|
43345
|
-
addStudent,
|
|
43346
|
-
removeStudent,
|
|
43347
|
-
deleteById
|
|
43348
|
-
};
|
|
43349
|
-
}
|
|
43350
|
-
|
|
43351
|
-
// src/resources/section-student/section.student.controller.ts
|
|
43352
|
-
import { BadRequestError as BadRequestError66 } from "@eeplatform/nodejs-utils";
|
|
43353
|
-
import Joi44 from "joi";
|
|
43354
|
-
function useSectionStudentController() {
|
|
43355
|
-
const { add: _add, getAll: _getAll } = useSectionStudentRepo();
|
|
43356
|
-
async function add(req, res, next) {
|
|
45004
|
+
async function updateById(req, res, next) {
|
|
43357
45005
|
const value = req.body;
|
|
43358
|
-
const
|
|
45006
|
+
const id = req.params.id ?? "";
|
|
45007
|
+
const validation = Joi48.object({
|
|
45008
|
+
id: Joi48.string().hex().required(),
|
|
45009
|
+
value: Joi48.object({
|
|
45010
|
+
name: Joi48.string().required(),
|
|
45011
|
+
serial: Joi48.string().optional().allow("", null),
|
|
45012
|
+
levels: Joi48.number().integer().min(1).required()
|
|
45013
|
+
})
|
|
45014
|
+
});
|
|
45015
|
+
const { error } = validation.validate({ id, value });
|
|
43359
45016
|
if (error) {
|
|
43360
|
-
next(new
|
|
45017
|
+
next(new BadRequestError74(error.message));
|
|
45018
|
+
logger43.info(`Controller: ${error.message}`);
|
|
43361
45019
|
return;
|
|
43362
45020
|
}
|
|
43363
45021
|
try {
|
|
43364
|
-
const
|
|
43365
|
-
res.json(
|
|
43366
|
-
message: "Successfully created section student.",
|
|
43367
|
-
data
|
|
43368
|
-
});
|
|
45022
|
+
const result = await _updateById(id, value);
|
|
45023
|
+
res.json(result);
|
|
43369
45024
|
return;
|
|
43370
45025
|
} catch (error2) {
|
|
43371
45026
|
next(error2);
|
|
@@ -43373,409 +45028,310 @@ function useSectionStudentController() {
|
|
|
43373
45028
|
}
|
|
43374
45029
|
async function getAll(req, res, next) {
|
|
43375
45030
|
const query = req.query;
|
|
43376
|
-
const validation =
|
|
43377
|
-
page:
|
|
43378
|
-
limit:
|
|
43379
|
-
search:
|
|
43380
|
-
|
|
43381
|
-
|
|
43382
|
-
gradeLevel: Joi44.string().optional().allow("", null),
|
|
43383
|
-
section: Joi44.string().optional().allow("", null),
|
|
43384
|
-
schoolYear: Joi44.string().optional().allow("", null)
|
|
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)
|
|
43385
45037
|
});
|
|
43386
45038
|
const { error } = validation.validate(query);
|
|
43387
|
-
const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
|
|
43388
|
-
const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
|
|
43389
|
-
const search = req.query.search ?? "";
|
|
43390
|
-
const status = req.query.status ?? "active";
|
|
43391
|
-
const school = req.query.school ?? "";
|
|
43392
|
-
const gradeLevel = req.query.gradeLevel ?? "";
|
|
43393
|
-
const section = req.query.section ?? "";
|
|
43394
|
-
const schoolYear = req.query.schoolYear ?? "";
|
|
43395
|
-
const isPageNumber = isFinite(page);
|
|
43396
|
-
if (!isPageNumber) {
|
|
43397
|
-
next(new BadRequestError66("Invalid page number."));
|
|
43398
|
-
return;
|
|
43399
|
-
}
|
|
43400
|
-
const isLimitNumber = isFinite(limit);
|
|
43401
|
-
if (!isLimitNumber) {
|
|
43402
|
-
next(new BadRequestError66("Invalid limit number."));
|
|
43403
|
-
return;
|
|
43404
|
-
}
|
|
43405
45039
|
if (error) {
|
|
43406
|
-
next(new
|
|
45040
|
+
next(new BadRequestError74(error.message));
|
|
43407
45041
|
return;
|
|
43408
45042
|
}
|
|
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 ?? "";
|
|
43409
45057
|
try {
|
|
43410
|
-
const
|
|
45058
|
+
const buildings = await _getAll({
|
|
43411
45059
|
page,
|
|
43412
45060
|
limit,
|
|
43413
|
-
|
|
45061
|
+
sort: sortObj,
|
|
43414
45062
|
status,
|
|
43415
45063
|
school,
|
|
43416
|
-
|
|
43417
|
-
section,
|
|
43418
|
-
schoolYear
|
|
45064
|
+
search
|
|
43419
45065
|
});
|
|
43420
|
-
res.json(
|
|
45066
|
+
res.json(buildings);
|
|
43421
45067
|
return;
|
|
43422
45068
|
} catch (error2) {
|
|
43423
45069
|
next(error2);
|
|
43424
45070
|
}
|
|
43425
45071
|
}
|
|
43426
|
-
|
|
43427
|
-
|
|
43428
|
-
|
|
43429
|
-
|
|
43430
|
-
}
|
|
43431
|
-
|
|
43432
|
-
|
|
43433
|
-
|
|
43434
|
-
|
|
43435
|
-
import { ObjectId as ObjectId41 } from "mongodb";
|
|
43436
|
-
var schemaBuilding = Joi45.object({
|
|
43437
|
-
_id: Joi45.string().hex().optional(),
|
|
43438
|
-
school: Joi45.string().hex().required(),
|
|
43439
|
-
serial: Joi45.string().optional().allow("", null),
|
|
43440
|
-
name: Joi45.string().required(),
|
|
43441
|
-
levels: Joi45.number().integer().min(1).required(),
|
|
43442
|
-
createdAt: Joi45.date().optional().allow("", null),
|
|
43443
|
-
updatedAt: Joi45.date().optional().allow("", null),
|
|
43444
|
-
deletedAt: Joi45.date().optional().allow("", null),
|
|
43445
|
-
status: Joi45.string().optional().allow("", null)
|
|
43446
|
-
});
|
|
43447
|
-
var schemaBuildingUnit = Joi45.object({
|
|
43448
|
-
_id: Joi45.string().hex().optional(),
|
|
43449
|
-
school: Joi45.string().hex().required(),
|
|
43450
|
-
name: Joi45.string().optional().allow("", null),
|
|
43451
|
-
building: Joi45.string().hex().required(),
|
|
43452
|
-
buildingName: Joi45.string().optional().allow("", null),
|
|
43453
|
-
level: Joi45.number().integer().min(1).required(),
|
|
43454
|
-
category: Joi45.string().required(),
|
|
43455
|
-
type: Joi45.string().required(),
|
|
43456
|
-
seating_capacity: Joi45.number().integer().min(0).required(),
|
|
43457
|
-
standing_capacity: Joi45.number().integer().min(0).required(),
|
|
43458
|
-
description: Joi45.string().optional().allow("", null),
|
|
43459
|
-
unit_of_measurement: Joi45.string().valid("sqm").required(),
|
|
43460
|
-
area: Joi45.number().positive().required(),
|
|
43461
|
-
status: Joi45.string().optional().allow("", null)
|
|
43462
|
-
});
|
|
43463
|
-
var schemaUpdateOptions = Joi45.object({
|
|
43464
|
-
name: Joi45.string().optional().allow("", null),
|
|
43465
|
-
building: Joi45.string().hex().optional().allow("", null),
|
|
43466
|
-
buildingName: Joi45.string().optional().allow("", null),
|
|
43467
|
-
level: Joi45.number().integer().min(1).optional().allow("", null),
|
|
43468
|
-
category: Joi45.string().optional().allow("", null),
|
|
43469
|
-
type: Joi45.string().optional().allow("", null),
|
|
43470
|
-
seating_capacity: Joi45.number().integer().min(0).optional().allow("", null),
|
|
43471
|
-
standing_capacity: Joi45.number().integer().min(0).optional().allow("", null),
|
|
43472
|
-
area: Joi45.number().positive().optional().allow("", null)
|
|
43473
|
-
});
|
|
43474
|
-
function MBuilding(value) {
|
|
43475
|
-
const { error } = schemaBuilding.validate(value);
|
|
43476
|
-
if (error) {
|
|
43477
|
-
logger39.info(`Building Model: ${error.message}`);
|
|
43478
|
-
throw new BadRequestError67(error.message);
|
|
43479
|
-
}
|
|
43480
|
-
if (value._id && typeof value._id === "string") {
|
|
43481
|
-
try {
|
|
43482
|
-
value._id = new ObjectId41(value._id);
|
|
43483
|
-
} catch (error2) {
|
|
43484
|
-
throw new BadRequestError67("Invalid _id format");
|
|
45072
|
+
async function getById(req, res, next) {
|
|
45073
|
+
const id = req.params.id;
|
|
45074
|
+
const validation = Joi48.object({
|
|
45075
|
+
id: Joi48.string().hex().required()
|
|
45076
|
+
});
|
|
45077
|
+
const { error } = validation.validate({ id });
|
|
45078
|
+
if (error) {
|
|
45079
|
+
next(new BadRequestError74(error.message));
|
|
45080
|
+
return;
|
|
43485
45081
|
}
|
|
43486
|
-
}
|
|
43487
|
-
try {
|
|
43488
|
-
value.school = new ObjectId41(value.school);
|
|
43489
|
-
} catch (error2) {
|
|
43490
|
-
throw new BadRequestError67("Invalid school format");
|
|
43491
|
-
}
|
|
43492
|
-
return {
|
|
43493
|
-
_id: value._id ?? void 0,
|
|
43494
|
-
school: value.school,
|
|
43495
|
-
serial: value.serial ?? "",
|
|
43496
|
-
name: value.name ?? "",
|
|
43497
|
-
levels: value.levels ?? 0,
|
|
43498
|
-
status: value.status ?? "active",
|
|
43499
|
-
createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
|
|
43500
|
-
updatedAt: value.updatedAt ?? "",
|
|
43501
|
-
deletedAt: value.deletedAt ?? ""
|
|
43502
|
-
};
|
|
43503
|
-
}
|
|
43504
|
-
function MBuildingUnit(value) {
|
|
43505
|
-
const { error } = schemaBuildingUnit.validate(value);
|
|
43506
|
-
if (error) {
|
|
43507
|
-
logger39.info(`Building Unit Model: ${error.message}`);
|
|
43508
|
-
throw new BadRequestError67(error.message);
|
|
43509
|
-
}
|
|
43510
|
-
if (value._id && typeof value._id === "string") {
|
|
43511
45082
|
try {
|
|
43512
|
-
|
|
45083
|
+
const building = await _getById(id);
|
|
45084
|
+
res.json({
|
|
45085
|
+
message: "Successfully retrieved building.",
|
|
45086
|
+
data: { building }
|
|
45087
|
+
});
|
|
45088
|
+
return;
|
|
43513
45089
|
} catch (error2) {
|
|
43514
|
-
|
|
43515
|
-
}
|
|
43516
|
-
}
|
|
43517
|
-
try {
|
|
43518
|
-
value.school = new ObjectId41(value.school);
|
|
43519
|
-
} catch (error2) {
|
|
43520
|
-
throw new BadRequestError67("Invalid school ID");
|
|
43521
|
-
}
|
|
43522
|
-
try {
|
|
43523
|
-
value.building = new ObjectId41(value.building);
|
|
43524
|
-
} catch (error2) {
|
|
43525
|
-
throw new BadRequestError67("Invalid building ID");
|
|
43526
|
-
}
|
|
43527
|
-
return {
|
|
43528
|
-
_id: value._id ?? void 0,
|
|
43529
|
-
school: value.school,
|
|
43530
|
-
name: value.name ?? "",
|
|
43531
|
-
building: value.building,
|
|
43532
|
-
buildingName: value.buildingName ?? "",
|
|
43533
|
-
level: value.level ?? 0,
|
|
43534
|
-
category: value.category ?? "",
|
|
43535
|
-
type: value.type ?? "",
|
|
43536
|
-
seating_capacity: value.seating_capacity ?? 0,
|
|
43537
|
-
standing_capacity: value.standing_capacity ?? 0,
|
|
43538
|
-
description: value.description ?? "",
|
|
43539
|
-
unit_of_measurement: value.unit_of_measurement ?? "sqm",
|
|
43540
|
-
area: value.area ?? 0,
|
|
43541
|
-
status: value.status ?? "active",
|
|
43542
|
-
createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
|
|
43543
|
-
updatedAt: value.updatedAt ?? "",
|
|
43544
|
-
deletedAt: value.deletedAt ?? ""
|
|
43545
|
-
};
|
|
43546
|
-
}
|
|
43547
|
-
|
|
43548
|
-
// src/resources/building/building.repository.ts
|
|
43549
|
-
import {
|
|
43550
|
-
AppError as AppError26,
|
|
43551
|
-
BadRequestError as BadRequestError68,
|
|
43552
|
-
InternalServerError as InternalServerError22,
|
|
43553
|
-
logger as logger40,
|
|
43554
|
-
makeCacheKey as makeCacheKey22,
|
|
43555
|
-
paginate as paginate21,
|
|
43556
|
-
useAtlas as useAtlas31,
|
|
43557
|
-
useCache as useCache22
|
|
43558
|
-
} from "@eeplatform/nodejs-utils";
|
|
43559
|
-
import { ObjectId as ObjectId42 } from "mongodb";
|
|
43560
|
-
function useBuildingRepo() {
|
|
43561
|
-
const db = useAtlas31.getDb();
|
|
43562
|
-
if (!db) {
|
|
43563
|
-
throw new Error("Unable to connect to server.");
|
|
43564
|
-
}
|
|
43565
|
-
const namespace_collection = "deped.buildings";
|
|
43566
|
-
const collection = db.collection(namespace_collection);
|
|
43567
|
-
const { getCache, setCache, delNamespace } = useCache22(namespace_collection);
|
|
43568
|
-
async function createIndexes() {
|
|
43569
|
-
try {
|
|
43570
|
-
await collection.createIndexes([
|
|
43571
|
-
{ key: { name: 1 }, unique: true, name: "unique_name_index" },
|
|
43572
|
-
{ key: { school: 1 } },
|
|
43573
|
-
{ key: { status: 1 } }
|
|
43574
|
-
]);
|
|
43575
|
-
} catch (error) {
|
|
43576
|
-
throw new Error("Failed to create index on buildings.");
|
|
45090
|
+
next(error2);
|
|
43577
45091
|
}
|
|
43578
45092
|
}
|
|
43579
|
-
async function
|
|
45093
|
+
async function deleteById(req, res, next) {
|
|
45094
|
+
const id = req.params.id;
|
|
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
|
+
}
|
|
43580
45103
|
try {
|
|
43581
|
-
|
|
43582
|
-
|
|
43583
|
-
|
|
43584
|
-
|
|
43585
|
-
|
|
43586
|
-
logger40.log({
|
|
43587
|
-
level: "error",
|
|
43588
|
-
message: error.message
|
|
43589
|
-
});
|
|
43590
|
-
if (error instanceof AppError26) {
|
|
43591
|
-
throw error;
|
|
43592
|
-
} else {
|
|
43593
|
-
const isDuplicated = error.message.includes("duplicate");
|
|
43594
|
-
if (isDuplicated) {
|
|
43595
|
-
throw new BadRequestError68("Building already exists.");
|
|
43596
|
-
}
|
|
43597
|
-
throw new Error("Failed to create building.");
|
|
43598
|
-
}
|
|
45104
|
+
const message = await _deleteById(id);
|
|
45105
|
+
res.json(message);
|
|
45106
|
+
return;
|
|
45107
|
+
} catch (error2) {
|
|
45108
|
+
next(error2);
|
|
43599
45109
|
}
|
|
43600
45110
|
}
|
|
43601
|
-
|
|
43602
|
-
|
|
43603
|
-
|
|
43604
|
-
|
|
43605
|
-
|
|
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.");
|
|
43606
45132
|
}
|
|
43607
45133
|
try {
|
|
43608
|
-
|
|
43609
|
-
|
|
43610
|
-
|
|
43611
|
-
|
|
45134
|
+
await session.startTransaction();
|
|
45135
|
+
const existingCount = await countByBuilding(
|
|
45136
|
+
value.building.building,
|
|
45137
|
+
value.building.level
|
|
43612
45138
|
);
|
|
43613
|
-
|
|
43614
|
-
|
|
43615
|
-
|
|
43616
|
-
|
|
43617
|
-
|
|
43618
|
-
|
|
43619
|
-
});
|
|
43620
|
-
if (error instanceof AppError26) {
|
|
43621
|
-
throw error;
|
|
43622
|
-
} else {
|
|
43623
|
-
throw new Error("Failed to update building.");
|
|
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
|
+
);
|
|
43624
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();
|
|
43625
45153
|
}
|
|
43626
45154
|
}
|
|
43627
|
-
|
|
43628
|
-
|
|
43629
|
-
|
|
43630
|
-
|
|
43631
|
-
sort = {},
|
|
43632
|
-
school = "",
|
|
43633
|
-
status = "active"
|
|
43634
|
-
} = {}) {
|
|
43635
|
-
page = page > 0 ? page - 1 : 0;
|
|
43636
|
-
const query = {
|
|
43637
|
-
status
|
|
43638
|
-
};
|
|
43639
|
-
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
43640
|
-
if (search) {
|
|
43641
|
-
query.$text = { $search: search };
|
|
45155
|
+
const { getById: getSectionSubjectByClassroom } = useSectionSubjectRepo();
|
|
45156
|
+
async function deleteById(id) {
|
|
45157
|
+
if (!id) {
|
|
45158
|
+
throw new Error("Invalid building unit ID.");
|
|
43642
45159
|
}
|
|
43643
|
-
|
|
43644
|
-
|
|
43645
|
-
|
|
43646
|
-
|
|
43647
|
-
|
|
43648
|
-
}
|
|
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
|
+
);
|
|
43649
45165
|
}
|
|
43650
|
-
const cacheParams = {
|
|
43651
|
-
page,
|
|
43652
|
-
limit,
|
|
43653
|
-
sort: JSON.stringify(sort)
|
|
43654
|
-
};
|
|
43655
|
-
if (search)
|
|
43656
|
-
cacheParams.search = search;
|
|
43657
|
-
if (school)
|
|
43658
|
-
cacheParams.school = school;
|
|
43659
|
-
if (status !== "active")
|
|
43660
|
-
cacheParams.status = status;
|
|
43661
|
-
const cacheKey = makeCacheKey22(namespace_collection, cacheParams);
|
|
43662
|
-
logger40.log({
|
|
43663
|
-
level: "info",
|
|
43664
|
-
message: `Cache key for getAll buildings: ${cacheKey}`
|
|
43665
|
-
});
|
|
43666
45166
|
try {
|
|
43667
|
-
|
|
43668
|
-
|
|
43669
|
-
logger40.log({
|
|
43670
|
-
level: "info",
|
|
43671
|
-
message: `Cache hit for getAll buildings: ${cacheKey}`
|
|
43672
|
-
});
|
|
43673
|
-
return cached;
|
|
43674
|
-
}
|
|
43675
|
-
const items = await collection.aggregate([
|
|
43676
|
-
{ $match: query },
|
|
43677
|
-
{ $sort: sort },
|
|
43678
|
-
{ $skip: page * limit },
|
|
43679
|
-
{ $limit: limit }
|
|
43680
|
-
]).toArray();
|
|
43681
|
-
const length = await collection.countDocuments(query);
|
|
43682
|
-
const data = paginate21(items, page, limit, length);
|
|
43683
|
-
setCache(cacheKey, data, 600).then(() => {
|
|
43684
|
-
logger40.log({
|
|
43685
|
-
level: "info",
|
|
43686
|
-
message: `Cache set for getAll buildings: ${cacheKey}`
|
|
43687
|
-
});
|
|
43688
|
-
}).catch((err) => {
|
|
43689
|
-
logger40.log({
|
|
43690
|
-
level: "error",
|
|
43691
|
-
message: `Failed to set cache for getAll buildings: ${err.message}`
|
|
43692
|
-
});
|
|
43693
|
-
});
|
|
43694
|
-
return data;
|
|
45167
|
+
await _deleteById(id);
|
|
45168
|
+
return "Building unit deleted successfully.";
|
|
43695
45169
|
} catch (error) {
|
|
43696
|
-
|
|
43697
|
-
throw error;
|
|
45170
|
+
throw new Error("Failed to delete building unit.");
|
|
43698
45171
|
}
|
|
43699
45172
|
}
|
|
43700
|
-
|
|
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;
|
|
45191
|
+
const validation = Joi49.object({
|
|
45192
|
+
building: Joi49.object({
|
|
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)
|
|
45208
|
+
});
|
|
45209
|
+
const { error } = validation.validate(data);
|
|
45210
|
+
if (error) {
|
|
45211
|
+
next(new BadRequestError75(error.message));
|
|
45212
|
+
return;
|
|
45213
|
+
}
|
|
43701
45214
|
try {
|
|
43702
|
-
|
|
43703
|
-
|
|
43704
|
-
|
|
45215
|
+
const buildingUnit = await _add(data);
|
|
45216
|
+
res.json({
|
|
45217
|
+
message: "Building unit added successfully.",
|
|
45218
|
+
data: { buildingUnit }
|
|
45219
|
+
});
|
|
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
|
+
return;
|
|
43705
45235
|
}
|
|
43706
|
-
const cacheKey = makeCacheKey22(namespace_collection, { _id: String(_id) });
|
|
43707
45236
|
try {
|
|
43708
|
-
const
|
|
43709
|
-
|
|
43710
|
-
|
|
43711
|
-
|
|
43712
|
-
message: `Cache hit for getById building: ${cacheKey}`
|
|
43713
|
-
});
|
|
43714
|
-
return cached;
|
|
43715
|
-
}
|
|
43716
|
-
const result = await collection.findOne({
|
|
43717
|
-
_id
|
|
45237
|
+
const buildingUnit = await _updateById(id, data);
|
|
45238
|
+
res.json({
|
|
45239
|
+
message: "Building unit updated successfully.",
|
|
45240
|
+
data: { buildingUnit }
|
|
43718
45241
|
});
|
|
43719
|
-
|
|
43720
|
-
|
|
43721
|
-
|
|
43722
|
-
|
|
43723
|
-
|
|
43724
|
-
|
|
43725
|
-
|
|
43726
|
-
|
|
43727
|
-
|
|
43728
|
-
|
|
45242
|
+
} catch (error2) {
|
|
45243
|
+
next(error2);
|
|
45244
|
+
}
|
|
45245
|
+
}
|
|
45246
|
+
async function getAll(req, res, next) {
|
|
45247
|
+
const query = req.query;
|
|
45248
|
+
const validation = Joi49.object({
|
|
45249
|
+
page: Joi49.number().min(1).optional().allow("", null),
|
|
45250
|
+
limit: Joi49.number().min(1).optional().allow("", null),
|
|
45251
|
+
search: Joi49.string().optional().allow("", null),
|
|
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)
|
|
45256
|
+
});
|
|
45257
|
+
const { error } = validation.validate(query);
|
|
45258
|
+
if (error) {
|
|
45259
|
+
next(new BadRequestError75(error.message));
|
|
45260
|
+
return;
|
|
45261
|
+
}
|
|
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;
|
|
43729
45271
|
});
|
|
43730
|
-
|
|
43731
|
-
|
|
43732
|
-
|
|
43733
|
-
|
|
43734
|
-
|
|
43735
|
-
|
|
43736
|
-
|
|
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
|
+
try {
|
|
45279
|
+
const buildings = await _getAll({
|
|
45280
|
+
page,
|
|
45281
|
+
limit,
|
|
45282
|
+
sort: sortObj,
|
|
45283
|
+
status,
|
|
45284
|
+
school,
|
|
45285
|
+
search,
|
|
45286
|
+
building,
|
|
45287
|
+
type
|
|
45288
|
+
});
|
|
45289
|
+
res.json(buildings);
|
|
45290
|
+
return;
|
|
45291
|
+
} catch (error2) {
|
|
45292
|
+
next(error2);
|
|
43737
45293
|
}
|
|
43738
45294
|
}
|
|
43739
|
-
async function
|
|
43740
|
-
|
|
43741
|
-
|
|
43742
|
-
|
|
43743
|
-
|
|
45295
|
+
async function getById(req, res, next) {
|
|
45296
|
+
const id = req.params.id;
|
|
45297
|
+
const validation = Joi49.object({
|
|
45298
|
+
id: Joi49.string().hex().required()
|
|
45299
|
+
});
|
|
45300
|
+
const { error } = validation.validate({ id });
|
|
45301
|
+
if (error) {
|
|
45302
|
+
next(new BadRequestError75(error.message));
|
|
45303
|
+
return;
|
|
43744
45304
|
}
|
|
43745
45305
|
try {
|
|
43746
|
-
const
|
|
43747
|
-
|
|
43748
|
-
|
|
43749
|
-
|
|
43750
|
-
delCachedData();
|
|
43751
|
-
return res;
|
|
43752
|
-
} catch (error) {
|
|
43753
|
-
logger40.log({
|
|
43754
|
-
level: "error",
|
|
43755
|
-
message: error.message
|
|
45306
|
+
const buildingUnit = await _getById(id);
|
|
45307
|
+
res.json({
|
|
45308
|
+
message: "Successfully retrieved building unit.",
|
|
45309
|
+
data: { buildingUnit }
|
|
43756
45310
|
});
|
|
43757
|
-
|
|
43758
|
-
|
|
43759
|
-
|
|
43760
|
-
throw new InternalServerError22("Failed to delete building.");
|
|
43761
|
-
}
|
|
45311
|
+
return;
|
|
45312
|
+
} catch (error2) {
|
|
45313
|
+
next(error2);
|
|
43762
45314
|
}
|
|
43763
45315
|
}
|
|
43764
|
-
function
|
|
43765
|
-
|
|
43766
|
-
|
|
43767
|
-
|
|
43768
|
-
message: `Cache namespace cleared for ${namespace_collection}`
|
|
43769
|
-
});
|
|
43770
|
-
}).catch((err) => {
|
|
43771
|
-
logger40.log({
|
|
43772
|
-
level: "error",
|
|
43773
|
-
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
43774
|
-
});
|
|
45316
|
+
async function deleteById(req, res, next) {
|
|
45317
|
+
const id = req.params.id;
|
|
45318
|
+
const validation = Joi49.object({
|
|
45319
|
+
id: Joi49.string().hex().required()
|
|
43775
45320
|
});
|
|
45321
|
+
const { error } = validation.validate({ id });
|
|
45322
|
+
if (error) {
|
|
45323
|
+
next(new BadRequestError75(error.message));
|
|
45324
|
+
return;
|
|
45325
|
+
}
|
|
45326
|
+
try {
|
|
45327
|
+
const message = await _deleteById(id);
|
|
45328
|
+
res.json({ message });
|
|
45329
|
+
return;
|
|
45330
|
+
} catch (error2) {
|
|
45331
|
+
next(error2);
|
|
45332
|
+
}
|
|
43776
45333
|
}
|
|
43777
45334
|
return {
|
|
43778
|
-
createIndexes,
|
|
43779
45335
|
add,
|
|
43780
45336
|
getAll,
|
|
43781
45337
|
getById,
|
|
@@ -43784,66 +45340,97 @@ function useBuildingRepo() {
|
|
|
43784
45340
|
};
|
|
43785
45341
|
}
|
|
43786
45342
|
|
|
43787
|
-
// src/resources/
|
|
43788
|
-
import {
|
|
43789
|
-
|
|
43790
|
-
|
|
43791
|
-
|
|
43792
|
-
|
|
45343
|
+
// src/resources/kindergarten-domain/kindergarten.domain.model.ts
|
|
45344
|
+
import { BadRequestError as BadRequestError76 } from "@eeplatform/nodejs-utils";
|
|
45345
|
+
import Joi50 from "joi";
|
|
45346
|
+
import { ObjectId as ObjectId46 } from "mongodb";
|
|
45347
|
+
var schemaKindergartenDomain = Joi50.object({
|
|
45348
|
+
_id: Joi50.string().hex().optional().allow(null, ""),
|
|
45349
|
+
title: Joi50.string().max(100).required(),
|
|
45350
|
+
school: Joi50.string().hex().required(),
|
|
45351
|
+
status: Joi50.string().valid("active", "inactive", "deleted").optional(),
|
|
45352
|
+
createdAt: Joi50.string().isoDate().optional().allow(null, ""),
|
|
45353
|
+
updatedAt: Joi50.string().isoDate().optional().allow(null, ""),
|
|
45354
|
+
deletedAt: Joi50.string().isoDate().optional().allow(null, "")
|
|
45355
|
+
});
|
|
45356
|
+
function modelKindergartenDomain(value) {
|
|
45357
|
+
const { error } = schemaKindergartenDomain.validate(value);
|
|
45358
|
+
if (error) {
|
|
45359
|
+
throw new BadRequestError76(
|
|
45360
|
+
`Invalid kindergarten domain data: ${error.message}`
|
|
45361
|
+
);
|
|
45362
|
+
}
|
|
45363
|
+
if (value._id && typeof value._id === "string") {
|
|
45364
|
+
try {
|
|
45365
|
+
value._id = new ObjectId46(value._id);
|
|
45366
|
+
} catch (error2) {
|
|
45367
|
+
throw new Error("Invalid _id.");
|
|
45368
|
+
}
|
|
45369
|
+
}
|
|
45370
|
+
if (value.school && typeof value.school === "string") {
|
|
45371
|
+
try {
|
|
45372
|
+
value.school = new ObjectId46(value.school);
|
|
45373
|
+
} catch (error2) {
|
|
45374
|
+
throw new Error("Invalid school.");
|
|
45375
|
+
}
|
|
45376
|
+
}
|
|
45377
|
+
return {
|
|
45378
|
+
_id: value._id,
|
|
45379
|
+
title: value.title,
|
|
45380
|
+
school: value.school,
|
|
45381
|
+
status: value.status ?? "active",
|
|
45382
|
+
createdAt: value.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
45383
|
+
updatedAt: value.updatedAt ?? "",
|
|
45384
|
+
deletedAt: value.deletedAt ?? ""
|
|
45385
|
+
};
|
|
45386
|
+
}
|
|
43793
45387
|
|
|
43794
|
-
// src/resources/
|
|
45388
|
+
// src/resources/kindergarten-domain/kindergarten.domain.repository.ts
|
|
43795
45389
|
import {
|
|
43796
|
-
AppError as
|
|
43797
|
-
BadRequestError as
|
|
43798
|
-
InternalServerError as
|
|
43799
|
-
logger as
|
|
43800
|
-
makeCacheKey as
|
|
43801
|
-
paginate as
|
|
43802
|
-
useAtlas as
|
|
43803
|
-
useCache as
|
|
45390
|
+
AppError as AppError29,
|
|
45391
|
+
BadRequestError as BadRequestError77,
|
|
45392
|
+
InternalServerError as InternalServerError25,
|
|
45393
|
+
logger as logger44,
|
|
45394
|
+
makeCacheKey as makeCacheKey25,
|
|
45395
|
+
paginate as paginate24,
|
|
45396
|
+
useAtlas as useAtlas36,
|
|
45397
|
+
useCache as useCache25
|
|
43804
45398
|
} from "@eeplatform/nodejs-utils";
|
|
43805
|
-
import { ObjectId as
|
|
43806
|
-
function
|
|
43807
|
-
const db =
|
|
45399
|
+
import { ObjectId as ObjectId47 } from "mongodb";
|
|
45400
|
+
function useKindergartenDomainRepo() {
|
|
45401
|
+
const db = useAtlas36.getDb();
|
|
43808
45402
|
if (!db) {
|
|
43809
45403
|
throw new Error("Unable to connect to server.");
|
|
43810
45404
|
}
|
|
43811
|
-
const namespace_collection = "deped.
|
|
45405
|
+
const namespace_collection = "deped.kindergarten.domains";
|
|
43812
45406
|
const collection = db.collection(namespace_collection);
|
|
43813
|
-
const { getCache, setCache, delNamespace } =
|
|
45407
|
+
const { getCache, setCache, delNamespace } = useCache25(namespace_collection);
|
|
43814
45408
|
async function createIndexes() {
|
|
43815
45409
|
try {
|
|
43816
45410
|
await collection.createIndexes([
|
|
43817
|
-
{
|
|
43818
|
-
key: { name: 1, building: 1, level: 1 },
|
|
43819
|
-
unique: true,
|
|
43820
|
-
name: "unique_name_index"
|
|
43821
|
-
},
|
|
45411
|
+
{ key: { title: 1 } },
|
|
43822
45412
|
{ key: { school: 1 } },
|
|
43823
|
-
{ key: { building: 1 } },
|
|
43824
|
-
{ key: { status: 1 } },
|
|
43825
45413
|
{ key: { createdAt: 1 } },
|
|
45414
|
+
{ key: { createdBy: 1 } },
|
|
45415
|
+
{ key: { title: "text" } },
|
|
43826
45416
|
{
|
|
43827
|
-
key: {
|
|
43828
|
-
|
|
43829
|
-
|
|
43830
|
-
category: "text",
|
|
43831
|
-
type: "text"
|
|
43832
|
-
}
|
|
45417
|
+
key: { title: 1, school: 1, status: 1 },
|
|
45418
|
+
unique: true,
|
|
45419
|
+
name: "unique_kindergarten_domain"
|
|
43833
45420
|
}
|
|
43834
45421
|
]);
|
|
43835
45422
|
} catch (error) {
|
|
43836
|
-
throw new Error("Failed to create index on
|
|
45423
|
+
throw new Error("Failed to create index on kindergarten domains.");
|
|
43837
45424
|
}
|
|
43838
45425
|
}
|
|
43839
45426
|
function delCachedData() {
|
|
43840
45427
|
delNamespace().then(() => {
|
|
43841
|
-
|
|
45428
|
+
logger44.log({
|
|
43842
45429
|
level: "info",
|
|
43843
45430
|
message: `Cache namespace cleared for ${namespace_collection}`
|
|
43844
45431
|
});
|
|
43845
45432
|
}).catch((err) => {
|
|
43846
|
-
|
|
45433
|
+
logger44.log({
|
|
43847
45434
|
level: "error",
|
|
43848
45435
|
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
43849
45436
|
});
|
|
@@ -43851,79 +45438,23 @@ function useBuildingUnitRepo() {
|
|
|
43851
45438
|
}
|
|
43852
45439
|
async function add(value, session) {
|
|
43853
45440
|
try {
|
|
43854
|
-
value =
|
|
45441
|
+
value = modelKindergartenDomain(value);
|
|
43855
45442
|
const res = await collection.insertOne(value, { session });
|
|
43856
45443
|
delCachedData();
|
|
43857
45444
|
return res.insertedId;
|
|
43858
45445
|
} catch (error) {
|
|
43859
|
-
|
|
45446
|
+
logger44.log({
|
|
43860
45447
|
level: "error",
|
|
43861
45448
|
message: error.message
|
|
43862
45449
|
});
|
|
43863
|
-
if (error instanceof
|
|
45450
|
+
if (error instanceof AppError29) {
|
|
43864
45451
|
throw error;
|
|
43865
45452
|
} else {
|
|
43866
|
-
|
|
43867
|
-
|
|
43868
|
-
|
|
43869
|
-
|
|
43870
|
-
|
|
43871
|
-
const { error } = schemaUpdateOptions.validate(value);
|
|
43872
|
-
if (error) {
|
|
43873
|
-
throw new BadRequestError69(error.message);
|
|
43874
|
-
}
|
|
43875
|
-
try {
|
|
43876
|
-
_id = new ObjectId43(_id);
|
|
43877
|
-
} catch (error2) {
|
|
43878
|
-
throw new BadRequestError69(namespace_collection + " Invalid ID.");
|
|
43879
|
-
}
|
|
43880
|
-
try {
|
|
43881
|
-
const res = await collection.updateOne(
|
|
43882
|
-
{ _id },
|
|
43883
|
-
{ $set: value },
|
|
43884
|
-
{ session }
|
|
43885
|
-
);
|
|
43886
|
-
delCachedData();
|
|
43887
|
-
return res;
|
|
43888
|
-
} catch (error2) {
|
|
43889
|
-
logger41.log({
|
|
43890
|
-
level: "error",
|
|
43891
|
-
message: error2.message
|
|
43892
|
-
});
|
|
43893
|
-
if (error2 instanceof AppError27) {
|
|
43894
|
-
throw error2;
|
|
43895
|
-
} else {
|
|
43896
|
-
throw new Error("Failed to create building unit.");
|
|
43897
|
-
}
|
|
43898
|
-
}
|
|
43899
|
-
}
|
|
43900
|
-
async function updateByBuildingId(building, value, session) {
|
|
43901
|
-
const { error } = schemaUpdateOptions.validate(value);
|
|
43902
|
-
if (error) {
|
|
43903
|
-
throw new BadRequestError69(error.message);
|
|
43904
|
-
}
|
|
43905
|
-
try {
|
|
43906
|
-
building = new ObjectId43(building);
|
|
43907
|
-
} catch (error2) {
|
|
43908
|
-
throw new BadRequestError69("Invalid building ID.");
|
|
43909
|
-
}
|
|
43910
|
-
try {
|
|
43911
|
-
const res = await collection.updateMany(
|
|
43912
|
-
{ building },
|
|
43913
|
-
{ $set: value },
|
|
43914
|
-
{ session }
|
|
43915
|
-
);
|
|
43916
|
-
delCachedData();
|
|
43917
|
-
return res;
|
|
43918
|
-
} catch (error2) {
|
|
43919
|
-
logger41.log({
|
|
43920
|
-
level: "error",
|
|
43921
|
-
message: error2.message
|
|
43922
|
-
});
|
|
43923
|
-
if (error2 instanceof AppError27) {
|
|
43924
|
-
throw error2;
|
|
43925
|
-
} else {
|
|
43926
|
-
throw new Error("Failed to update building unit.");
|
|
45453
|
+
const isDuplicated = error.message.includes("duplicate");
|
|
45454
|
+
if (isDuplicated) {
|
|
45455
|
+
throw new BadRequestError77("Kindergarten domain already exists.");
|
|
45456
|
+
}
|
|
45457
|
+
throw new Error("Failed to create kindergarten domain.");
|
|
43927
45458
|
}
|
|
43928
45459
|
}
|
|
43929
45460
|
}
|
|
@@ -43932,652 +45463,368 @@ function useBuildingUnitRepo() {
|
|
|
43932
45463
|
page = 1,
|
|
43933
45464
|
limit = 10,
|
|
43934
45465
|
sort = {},
|
|
43935
|
-
|
|
43936
|
-
|
|
43937
|
-
|
|
43938
|
-
status = "active"
|
|
45466
|
+
status = "active",
|
|
45467
|
+
createdBy,
|
|
45468
|
+
school = ""
|
|
43939
45469
|
} = {}) {
|
|
43940
45470
|
page = page > 0 ? page - 1 : 0;
|
|
43941
45471
|
const query = {
|
|
43942
|
-
deletedAt: { $in: ["", null] },
|
|
43943
|
-
status
|
|
43944
|
-
};
|
|
43945
|
-
const cacheParams = {
|
|
43946
|
-
page,
|
|
43947
|
-
limit,
|
|
43948
|
-
sort: JSON.stringify(sort)
|
|
43949
|
-
};
|
|
43950
|
-
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
43951
|
-
if (search) {
|
|
43952
|
-
query.$text = { $search: search };
|
|
43953
|
-
cacheParams.search = search;
|
|
43954
|
-
}
|
|
43955
|
-
if (school) {
|
|
43956
|
-
try {
|
|
43957
|
-
query.school = new ObjectId43(school);
|
|
43958
|
-
} catch (error) {
|
|
43959
|
-
throw new BadRequestError69("Invalid school ID.");
|
|
43960
|
-
}
|
|
43961
|
-
cacheParams.school = school;
|
|
43962
|
-
}
|
|
43963
|
-
if (building) {
|
|
43964
|
-
try {
|
|
43965
|
-
query.building = new ObjectId43(building);
|
|
43966
|
-
} catch (error) {
|
|
43967
|
-
throw new BadRequestError69("Invalid building ID.");
|
|
43968
|
-
}
|
|
43969
|
-
cacheParams.building = building;
|
|
43970
|
-
}
|
|
43971
|
-
if (type) {
|
|
43972
|
-
query.type = type;
|
|
43973
|
-
cacheParams.type = type;
|
|
43974
|
-
}
|
|
43975
|
-
const cacheKey = makeCacheKey23(namespace_collection, cacheParams);
|
|
43976
|
-
logger41.log({
|
|
43977
|
-
level: "info",
|
|
43978
|
-
message: `Cache key for getAll building units: ${cacheKey}`
|
|
43979
|
-
});
|
|
43980
|
-
try {
|
|
43981
|
-
const cached = await getCache(cacheKey);
|
|
43982
|
-
if (cached) {
|
|
43983
|
-
logger41.log({
|
|
43984
|
-
level: "info",
|
|
43985
|
-
message: `Cache hit for getAll building units: ${cacheKey}`
|
|
43986
|
-
});
|
|
43987
|
-
return cached;
|
|
43988
|
-
}
|
|
43989
|
-
const items = await collection.aggregate([
|
|
43990
|
-
{ $match: query },
|
|
43991
|
-
{ $sort: sort },
|
|
43992
|
-
{ $skip: page * limit },
|
|
43993
|
-
{ $limit: limit }
|
|
43994
|
-
]).toArray();
|
|
43995
|
-
const length = await collection.countDocuments(query);
|
|
43996
|
-
const data = paginate22(items, page, limit, length);
|
|
43997
|
-
setCache(cacheKey, data, 600).then(() => {
|
|
43998
|
-
logger41.log({
|
|
43999
|
-
level: "info",
|
|
44000
|
-
message: `Cache set for getAll building units: ${cacheKey}`
|
|
44001
|
-
});
|
|
44002
|
-
}).catch((err) => {
|
|
44003
|
-
logger41.log({
|
|
44004
|
-
level: "error",
|
|
44005
|
-
message: `Failed to set cache for getAll building units: ${err.message}`
|
|
44006
|
-
});
|
|
44007
|
-
});
|
|
44008
|
-
return data;
|
|
44009
|
-
} catch (error) {
|
|
44010
|
-
logger41.log({ level: "error", message: `${error}` });
|
|
44011
|
-
throw error;
|
|
44012
|
-
}
|
|
44013
|
-
}
|
|
44014
|
-
async function countByBuilding(building, level) {
|
|
44015
|
-
const query = {
|
|
44016
|
-
status: "active"
|
|
45472
|
+
deletedAt: { $in: ["", null] },
|
|
45473
|
+
status
|
|
44017
45474
|
};
|
|
45475
|
+
sort = Object.keys(sort).length > 0 ? sort : { _id: 1 };
|
|
44018
45476
|
const cacheKeyOptions = {
|
|
44019
|
-
|
|
44020
|
-
|
|
45477
|
+
status,
|
|
45478
|
+
page,
|
|
45479
|
+
limit,
|
|
45480
|
+
sort: JSON.stringify(sort)
|
|
44021
45481
|
};
|
|
44022
|
-
|
|
44023
|
-
|
|
44024
|
-
|
|
44025
|
-
|
|
44026
|
-
|
|
44027
|
-
|
|
44028
|
-
|
|
44029
|
-
query.level = level;
|
|
44030
|
-
cacheKeyOptions.level = level;
|
|
45482
|
+
if (createdBy) {
|
|
45483
|
+
try {
|
|
45484
|
+
query.createdBy = new ObjectId47(createdBy);
|
|
45485
|
+
} catch (error) {
|
|
45486
|
+
throw new BadRequestError77("Invalid createdBy ID.");
|
|
45487
|
+
}
|
|
45488
|
+
cacheKeyOptions.createdBy = createdBy;
|
|
44031
45489
|
}
|
|
44032
|
-
|
|
44033
|
-
|
|
44034
|
-
|
|
44035
|
-
logger41.log({ level: "error", message: `${error}` });
|
|
44036
|
-
throw new InternalServerError23("Failed to count building units.");
|
|
45490
|
+
if (search) {
|
|
45491
|
+
query.$text = { $search: search };
|
|
45492
|
+
cacheKeyOptions.search = search;
|
|
44037
45493
|
}
|
|
44038
|
-
|
|
44039
|
-
|
|
44040
|
-
|
|
44041
|
-
|
|
44042
|
-
|
|
44043
|
-
|
|
45494
|
+
if (school) {
|
|
45495
|
+
try {
|
|
45496
|
+
query.school = new ObjectId47(school);
|
|
45497
|
+
} catch (error) {
|
|
45498
|
+
throw new BadRequestError77("Invalid school ID.");
|
|
45499
|
+
}
|
|
45500
|
+
cacheKeyOptions.school = school;
|
|
44044
45501
|
}
|
|
44045
|
-
const cacheKey =
|
|
45502
|
+
const cacheKey = makeCacheKey25(namespace_collection, cacheKeyOptions);
|
|
45503
|
+
logger44.log({
|
|
45504
|
+
level: "info",
|
|
45505
|
+
message: `Cache key for getAll kindergarten domains: ${cacheKey}`
|
|
45506
|
+
});
|
|
44046
45507
|
try {
|
|
44047
45508
|
const cached = await getCache(cacheKey);
|
|
44048
45509
|
if (cached) {
|
|
44049
|
-
|
|
45510
|
+
logger44.log({
|
|
44050
45511
|
level: "info",
|
|
44051
|
-
message: `Cache hit for
|
|
45512
|
+
message: `Cache hit for getAll kindergarten domains: ${cacheKey}`
|
|
44052
45513
|
});
|
|
44053
45514
|
return cached;
|
|
44054
45515
|
}
|
|
44055
|
-
const
|
|
44056
|
-
|
|
44057
|
-
|
|
44058
|
-
|
|
44059
|
-
|
|
44060
|
-
|
|
44061
|
-
|
|
45516
|
+
const items = await collection.aggregate([
|
|
45517
|
+
{ $match: query },
|
|
45518
|
+
{ $sort: sort },
|
|
45519
|
+
{ $skip: page * limit },
|
|
45520
|
+
{ $limit: limit }
|
|
45521
|
+
]).toArray();
|
|
45522
|
+
const total = await collection.countDocuments(query);
|
|
45523
|
+
const result = paginate24(items, total, page, limit);
|
|
44062
45524
|
setCache(cacheKey, result, 300).then(() => {
|
|
44063
|
-
|
|
45525
|
+
logger44.log({
|
|
44064
45526
|
level: "info",
|
|
44065
|
-
message: `Cache set for
|
|
45527
|
+
message: `Cache set for getAll kindergarten domains: ${cacheKey}`
|
|
44066
45528
|
});
|
|
44067
45529
|
}).catch((err) => {
|
|
44068
|
-
|
|
45530
|
+
logger44.log({
|
|
44069
45531
|
level: "error",
|
|
44070
|
-
message: `Failed to set cache for
|
|
45532
|
+
message: `Failed to set cache for getAll kindergarten domains: ${err.message}`
|
|
44071
45533
|
});
|
|
44072
45534
|
});
|
|
44073
45535
|
return result;
|
|
44074
45536
|
} catch (error) {
|
|
44075
|
-
if (error instanceof
|
|
45537
|
+
if (error instanceof AppError29) {
|
|
44076
45538
|
throw error;
|
|
44077
45539
|
} else {
|
|
44078
|
-
throw new
|
|
45540
|
+
throw new InternalServerError25("Failed to get kindergarten domains.");
|
|
44079
45541
|
}
|
|
44080
45542
|
}
|
|
44081
45543
|
}
|
|
44082
|
-
async function
|
|
45544
|
+
async function getById(_id) {
|
|
44083
45545
|
try {
|
|
44084
|
-
|
|
45546
|
+
_id = new ObjectId47(_id);
|
|
44085
45547
|
} catch (error) {
|
|
44086
|
-
throw new
|
|
45548
|
+
throw new BadRequestError77(namespace_collection + " Invalid ID.");
|
|
44087
45549
|
}
|
|
44088
|
-
const cacheKey =
|
|
44089
|
-
|
|
44090
|
-
|
|
45550
|
+
const cacheKey = makeCacheKey25(namespace_collection, {
|
|
45551
|
+
_id: _id.toString()
|
|
45552
|
+
});
|
|
45553
|
+
logger44.log({
|
|
45554
|
+
level: "info",
|
|
45555
|
+
message: `Cache key for getById kindergarten domain: ${cacheKey}`
|
|
44091
45556
|
});
|
|
44092
45557
|
try {
|
|
44093
45558
|
const cached = await getCache(cacheKey);
|
|
44094
45559
|
if (cached) {
|
|
44095
|
-
|
|
45560
|
+
logger44.log({
|
|
44096
45561
|
level: "info",
|
|
44097
|
-
message: `Cache hit for getById
|
|
45562
|
+
message: `Cache hit for getById kindergarten domain: ${cacheKey}`
|
|
44098
45563
|
});
|
|
44099
45564
|
return cached;
|
|
44100
45565
|
}
|
|
44101
45566
|
const result = await collection.findOne({
|
|
44102
|
-
|
|
44103
|
-
|
|
44104
|
-
status: "active"
|
|
45567
|
+
_id,
|
|
45568
|
+
deletedAt: { $in: ["", null] }
|
|
44105
45569
|
});
|
|
45570
|
+
if (!result) {
|
|
45571
|
+
throw new BadRequestError77("Kindergarten domain not found.");
|
|
45572
|
+
}
|
|
44106
45573
|
setCache(cacheKey, result, 300).then(() => {
|
|
44107
|
-
|
|
45574
|
+
logger44.log({
|
|
44108
45575
|
level: "info",
|
|
44109
|
-
message: `Cache set for
|
|
45576
|
+
message: `Cache set for getById kindergarten domain: ${cacheKey}`
|
|
44110
45577
|
});
|
|
44111
45578
|
}).catch((err) => {
|
|
44112
|
-
|
|
45579
|
+
logger44.log({
|
|
44113
45580
|
level: "error",
|
|
44114
|
-
message: `Failed to set cache for
|
|
45581
|
+
message: `Failed to set cache for getById kindergarten domain: ${err.message}`
|
|
44115
45582
|
});
|
|
44116
45583
|
});
|
|
44117
45584
|
return result;
|
|
44118
45585
|
} catch (error) {
|
|
44119
|
-
if (error instanceof
|
|
45586
|
+
if (error instanceof AppError29) {
|
|
44120
45587
|
throw error;
|
|
44121
45588
|
} else {
|
|
44122
|
-
throw new
|
|
45589
|
+
throw new InternalServerError25("Failed to get kindergarten domain.");
|
|
44123
45590
|
}
|
|
44124
45591
|
}
|
|
44125
45592
|
}
|
|
44126
|
-
async function
|
|
45593
|
+
async function getBySchool(school) {
|
|
44127
45594
|
try {
|
|
44128
|
-
|
|
45595
|
+
school = new ObjectId47(school);
|
|
44129
45596
|
} catch (error) {
|
|
44130
|
-
throw new
|
|
45597
|
+
throw new BadRequestError77("Invalid school ID.");
|
|
44131
45598
|
}
|
|
44132
|
-
const cacheKey =
|
|
44133
|
-
|
|
45599
|
+
const cacheKey = makeCacheKey25(namespace_collection, {
|
|
45600
|
+
school: school.toString()
|
|
45601
|
+
});
|
|
45602
|
+
logger44.log({
|
|
45603
|
+
level: "info",
|
|
45604
|
+
message: `Cache key for kindergarten domain by school: ${cacheKey}`
|
|
44134
45605
|
});
|
|
44135
45606
|
try {
|
|
44136
45607
|
const cached = await getCache(cacheKey);
|
|
44137
45608
|
if (cached) {
|
|
44138
|
-
|
|
45609
|
+
logger44.log({
|
|
44139
45610
|
level: "info",
|
|
44140
|
-
message: `Cache hit for
|
|
45611
|
+
message: `Cache hit for kindergarten domain by school: ${cacheKey}`
|
|
44141
45612
|
});
|
|
44142
45613
|
return cached;
|
|
44143
45614
|
}
|
|
44144
|
-
const result = await collection.
|
|
44145
|
-
|
|
44146
|
-
|
|
44147
|
-
});
|
|
45615
|
+
const result = await collection.find({
|
|
45616
|
+
school,
|
|
45617
|
+
deletedAt: { $in: ["", null] }
|
|
45618
|
+
}).toArray();
|
|
44148
45619
|
setCache(cacheKey, result, 300).then(() => {
|
|
44149
|
-
|
|
45620
|
+
logger44.log({
|
|
44150
45621
|
level: "info",
|
|
44151
|
-
message: `Cache set for
|
|
45622
|
+
message: `Cache set for kindergarten domain by school: ${cacheKey}`
|
|
44152
45623
|
});
|
|
44153
45624
|
}).catch((err) => {
|
|
44154
|
-
|
|
45625
|
+
logger44.log({
|
|
44155
45626
|
level: "error",
|
|
44156
|
-
message: `Failed to set cache for
|
|
45627
|
+
message: `Failed to set cache for kindergarten domain by school: ${err.message}`
|
|
44157
45628
|
});
|
|
44158
45629
|
});
|
|
44159
45630
|
return result;
|
|
44160
45631
|
} catch (error) {
|
|
44161
|
-
if (error instanceof
|
|
44162
|
-
throw error;
|
|
44163
|
-
} else {
|
|
44164
|
-
throw new InternalServerError23("Failed to get building unit.");
|
|
44165
|
-
}
|
|
44166
|
-
}
|
|
44167
|
-
}
|
|
44168
|
-
async function deleteById(_id, session) {
|
|
44169
|
-
try {
|
|
44170
|
-
_id = new ObjectId43(_id);
|
|
44171
|
-
} catch (error) {
|
|
44172
|
-
throw new BadRequestError69(namespace_collection + " Invalid ID.");
|
|
44173
|
-
}
|
|
44174
|
-
try {
|
|
44175
|
-
const res = await collection.updateOne(
|
|
44176
|
-
{ _id },
|
|
44177
|
-
{ $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } },
|
|
44178
|
-
{ session }
|
|
44179
|
-
);
|
|
44180
|
-
delCachedData();
|
|
44181
|
-
return "Room/Facility deleted successfully.";
|
|
44182
|
-
} catch (error) {
|
|
44183
|
-
logger41.log({
|
|
44184
|
-
level: "error",
|
|
44185
|
-
message: error.message
|
|
44186
|
-
});
|
|
44187
|
-
if (error instanceof AppError27) {
|
|
45632
|
+
if (error instanceof AppError29) {
|
|
44188
45633
|
throw error;
|
|
44189
45634
|
} else {
|
|
44190
|
-
throw new
|
|
44191
|
-
}
|
|
44192
|
-
}
|
|
44193
|
-
}
|
|
44194
|
-
|
|
44195
|
-
|
|
44196
|
-
|
|
44197
|
-
|
|
44198
|
-
|
|
44199
|
-
|
|
44200
|
-
updateById,
|
|
44201
|
-
getByBuilding,
|
|
44202
|
-
deleteById,
|
|
44203
|
-
updateByBuildingId,
|
|
44204
|
-
countByBuilding
|
|
44205
|
-
};
|
|
44206
|
-
}
|
|
44207
|
-
|
|
44208
|
-
// src/resources/building/building.service.ts
|
|
44209
|
-
function useBuildingService() {
|
|
44210
|
-
const {
|
|
44211
|
-
updateById: _updateById,
|
|
44212
|
-
getById: _getById,
|
|
44213
|
-
deleteById: _deleteById
|
|
44214
|
-
} = useBuildingRepo();
|
|
44215
|
-
const { getByBuildingLevel, getByBuilding, updateByBuildingId } = useBuildingUnitRepo();
|
|
44216
|
-
async function updateById(id, data) {
|
|
44217
|
-
data.levels = Number(data.levels);
|
|
44218
|
-
const session = useAtlas33.getClient()?.startSession();
|
|
44219
|
-
try {
|
|
44220
|
-
const building = await _getById(id);
|
|
44221
|
-
if (!building) {
|
|
44222
|
-
throw new NotFoundError3("Building not found.");
|
|
44223
|
-
}
|
|
44224
|
-
if (data.levels < building.levels) {
|
|
44225
|
-
const unit = await getByBuildingLevel(id, building.levels);
|
|
44226
|
-
if (unit) {
|
|
44227
|
-
throw new BadRequestError70(
|
|
44228
|
-
"Cannot reduce floors, there are existing building units at higher floors."
|
|
44229
|
-
);
|
|
44230
|
-
}
|
|
44231
|
-
}
|
|
44232
|
-
session?.startTransaction();
|
|
44233
|
-
if (building.name !== data.name) {
|
|
44234
|
-
await updateByBuildingId(id, { buildingName: data.name }, session);
|
|
44235
|
-
}
|
|
44236
|
-
const result = await _updateById(id, data, session);
|
|
44237
|
-
await session?.commitTransaction();
|
|
44238
|
-
return result;
|
|
44239
|
-
} catch (error) {
|
|
44240
|
-
await session?.abortTransaction();
|
|
44241
|
-
throw error;
|
|
44242
|
-
} finally {
|
|
44243
|
-
session?.endSession();
|
|
44244
|
-
}
|
|
44245
|
-
}
|
|
44246
|
-
async function deleteById(id) {
|
|
44247
|
-
const building = await getByBuilding(id);
|
|
44248
|
-
if (building) {
|
|
44249
|
-
throw new BadRequestError70(
|
|
44250
|
-
"Cannot delete building with existing room/facility. Please delete room/facility first."
|
|
44251
|
-
);
|
|
44252
|
-
}
|
|
44253
|
-
try {
|
|
44254
|
-
await _deleteById(id);
|
|
44255
|
-
return "Building deleted successfully.";
|
|
44256
|
-
} catch (error) {
|
|
44257
|
-
throw error;
|
|
44258
|
-
}
|
|
44259
|
-
}
|
|
44260
|
-
return {
|
|
44261
|
-
updateById,
|
|
44262
|
-
deleteById
|
|
44263
|
-
};
|
|
44264
|
-
}
|
|
44265
|
-
|
|
44266
|
-
// src/resources/building/building.controller.ts
|
|
44267
|
-
import { BadRequestError as BadRequestError71, logger as logger42 } from "@eeplatform/nodejs-utils";
|
|
44268
|
-
import Joi46 from "joi";
|
|
44269
|
-
function useBuildingController() {
|
|
44270
|
-
const { getAll: _getAll, getById: _getById, add: _add } = useBuildingRepo();
|
|
44271
|
-
const { updateById: _updateById, deleteById: _deleteById } = useBuildingService();
|
|
44272
|
-
async function createBuilding(req, res, next) {
|
|
44273
|
-
const value = req.body;
|
|
44274
|
-
const validation = Joi46.object({
|
|
44275
|
-
name: Joi46.string().required(),
|
|
44276
|
-
school: Joi46.string().hex().required(),
|
|
44277
|
-
levels: Joi46.number().integer().min(1).required(),
|
|
44278
|
-
serial: Joi46.string().optional().allow("", null),
|
|
44279
|
-
status: Joi46.string().optional().allow("", null)
|
|
44280
|
-
});
|
|
44281
|
-
const { error } = validation.validate(value);
|
|
44282
|
-
if (error) {
|
|
44283
|
-
next(new BadRequestError71(error.message));
|
|
44284
|
-
logger42.info(`Controller: ${error.message}`);
|
|
44285
|
-
return;
|
|
44286
|
-
}
|
|
44287
|
-
try {
|
|
44288
|
-
const result = await _add(value);
|
|
44289
|
-
res.json(result);
|
|
44290
|
-
return;
|
|
44291
|
-
} catch (error2) {
|
|
44292
|
-
next(error2);
|
|
44293
|
-
}
|
|
44294
|
-
}
|
|
44295
|
-
async function updateById(req, res, next) {
|
|
44296
|
-
const value = req.body;
|
|
44297
|
-
const id = req.params.id ?? "";
|
|
44298
|
-
const validation = Joi46.object({
|
|
44299
|
-
id: Joi46.string().hex().required(),
|
|
44300
|
-
value: Joi46.object({
|
|
44301
|
-
name: Joi46.string().required(),
|
|
44302
|
-
serial: Joi46.string().optional().allow("", null),
|
|
44303
|
-
levels: Joi46.number().integer().min(1).required()
|
|
44304
|
-
})
|
|
44305
|
-
});
|
|
44306
|
-
const { error } = validation.validate({ id, value });
|
|
44307
|
-
if (error) {
|
|
44308
|
-
next(new BadRequestError71(error.message));
|
|
44309
|
-
logger42.info(`Controller: ${error.message}`);
|
|
44310
|
-
return;
|
|
44311
|
-
}
|
|
44312
|
-
try {
|
|
44313
|
-
const result = await _updateById(id, value);
|
|
44314
|
-
res.json(result);
|
|
44315
|
-
return;
|
|
44316
|
-
} catch (error2) {
|
|
44317
|
-
next(error2);
|
|
44318
|
-
}
|
|
44319
|
-
}
|
|
44320
|
-
async function getAll(req, res, next) {
|
|
44321
|
-
const query = req.query;
|
|
44322
|
-
const validation = Joi46.object({
|
|
44323
|
-
page: Joi46.number().min(1).optional().allow("", null),
|
|
44324
|
-
limit: Joi46.number().min(1).optional().allow("", null),
|
|
44325
|
-
search: Joi46.string().optional().allow("", null),
|
|
44326
|
-
school: Joi46.string().hex().optional().allow("", null),
|
|
44327
|
-
status: Joi46.string().optional().allow("", null)
|
|
44328
|
-
});
|
|
44329
|
-
const { error } = validation.validate(query);
|
|
44330
|
-
if (error) {
|
|
44331
|
-
next(new BadRequestError71(error.message));
|
|
44332
|
-
return;
|
|
44333
|
-
}
|
|
44334
|
-
const page = parseInt(req.query.page) ?? 1;
|
|
44335
|
-
let limit = parseInt(req.query.limit) ?? 20;
|
|
44336
|
-
limit = isNaN(limit) ? 20 : limit;
|
|
44337
|
-
const sort = req.query.sort ? String(req.query.sort).split(",") : "";
|
|
44338
|
-
const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
|
|
44339
|
-
const sortObj = {};
|
|
44340
|
-
if (sort && Array.isArray(sort) && sort.length && sortOrder && Array.isArray(sortOrder) && sortOrder.length) {
|
|
44341
|
-
sort.forEach((field, index) => {
|
|
44342
|
-
sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
|
|
44343
|
-
});
|
|
45635
|
+
throw new InternalServerError25("Failed to get kindergarten domain.");
|
|
45636
|
+
}
|
|
45637
|
+
}
|
|
45638
|
+
}
|
|
45639
|
+
async function updateFieldById({ _id, field, value } = {}, session) {
|
|
45640
|
+
const allowedFields = ["title", "status"];
|
|
45641
|
+
if (!allowedFields.includes(field)) {
|
|
45642
|
+
throw new BadRequestError77(
|
|
45643
|
+
`Field "${field}" is not allowed to be updated.`
|
|
45644
|
+
);
|
|
44344
45645
|
}
|
|
44345
|
-
const status = req.query.status ?? "active";
|
|
44346
|
-
const school = req.query.school ?? "";
|
|
44347
|
-
const search = req.query.search ?? "";
|
|
44348
45646
|
try {
|
|
44349
|
-
|
|
44350
|
-
|
|
44351
|
-
|
|
44352
|
-
|
|
44353
|
-
|
|
44354
|
-
|
|
44355
|
-
|
|
44356
|
-
|
|
44357
|
-
|
|
44358
|
-
|
|
44359
|
-
|
|
44360
|
-
|
|
45647
|
+
_id = new ObjectId47(_id);
|
|
45648
|
+
} catch (error) {
|
|
45649
|
+
throw new BadRequestError77(namespace_collection + " Invalid ID.");
|
|
45650
|
+
}
|
|
45651
|
+
try {
|
|
45652
|
+
await collection.updateOne(
|
|
45653
|
+
{ _id, deletedAt: { $in: ["", null] } },
|
|
45654
|
+
{ $set: { [field]: value, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
|
|
45655
|
+
{ session }
|
|
45656
|
+
);
|
|
45657
|
+
delCachedData();
|
|
45658
|
+
return `Successfully updated kindergarten domain ${field}.`;
|
|
45659
|
+
} catch (error) {
|
|
45660
|
+
throw new InternalServerError25(
|
|
45661
|
+
`Failed to update kindergarten domain ${field}.`
|
|
45662
|
+
);
|
|
44361
45663
|
}
|
|
44362
45664
|
}
|
|
44363
|
-
async function
|
|
44364
|
-
const
|
|
44365
|
-
const validation = Joi46.object({
|
|
44366
|
-
id: Joi46.string().hex().required()
|
|
44367
|
-
});
|
|
44368
|
-
const { error } = validation.validate({ id });
|
|
45665
|
+
async function updateById(_id, value, session) {
|
|
45666
|
+
const { error } = schemaKindergartenDomain.validate(value);
|
|
44369
45667
|
if (error) {
|
|
44370
|
-
|
|
44371
|
-
|
|
45668
|
+
throw new BadRequestError77(
|
|
45669
|
+
`Invalid kindergarten domain data: ${error.message}`
|
|
45670
|
+
);
|
|
44372
45671
|
}
|
|
44373
45672
|
try {
|
|
44374
|
-
|
|
44375
|
-
res.json({
|
|
44376
|
-
message: "Successfully retrieved building.",
|
|
44377
|
-
data: { building }
|
|
44378
|
-
});
|
|
44379
|
-
return;
|
|
45673
|
+
_id = new ObjectId47(_id);
|
|
44380
45674
|
} catch (error2) {
|
|
44381
|
-
|
|
45675
|
+
throw new BadRequestError77(namespace_collection + " Invalid ID.");
|
|
45676
|
+
}
|
|
45677
|
+
try {
|
|
45678
|
+
await collection.updateOne(
|
|
45679
|
+
{ _id },
|
|
45680
|
+
{ $set: { ...value, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
|
|
45681
|
+
{ session }
|
|
45682
|
+
);
|
|
45683
|
+
delCachedData();
|
|
45684
|
+
return `Successfully updated kindergarten domain.`;
|
|
45685
|
+
} catch (error2) {
|
|
45686
|
+
throw new InternalServerError25("Failed to update kindergarten domain.");
|
|
44382
45687
|
}
|
|
44383
45688
|
}
|
|
44384
|
-
async function deleteById(
|
|
44385
|
-
|
|
44386
|
-
|
|
44387
|
-
|
|
44388
|
-
|
|
44389
|
-
const { error } = validation.validate({ id });
|
|
44390
|
-
if (error) {
|
|
44391
|
-
next(new BadRequestError71(error.message));
|
|
44392
|
-
return;
|
|
45689
|
+
async function deleteById(_id, session) {
|
|
45690
|
+
try {
|
|
45691
|
+
_id = new ObjectId47(_id);
|
|
45692
|
+
} catch (error) {
|
|
45693
|
+
throw new BadRequestError77(namespace_collection + " Invalid ID.");
|
|
44393
45694
|
}
|
|
44394
45695
|
try {
|
|
44395
|
-
|
|
44396
|
-
|
|
44397
|
-
|
|
44398
|
-
|
|
44399
|
-
|
|
45696
|
+
await collection.updateOne(
|
|
45697
|
+
{ _id },
|
|
45698
|
+
{ $set: { status: "deleted", deletedAt: (/* @__PURE__ */ new Date()).toISOString() } },
|
|
45699
|
+
{ session }
|
|
45700
|
+
);
|
|
45701
|
+
delCachedData();
|
|
45702
|
+
return "Successfully deleted kindergarten domain.";
|
|
45703
|
+
} catch (error) {
|
|
45704
|
+
throw new InternalServerError25("Failed to delete kindergarten domain.");
|
|
44400
45705
|
}
|
|
44401
45706
|
}
|
|
44402
45707
|
return {
|
|
44403
|
-
|
|
45708
|
+
createIndexes,
|
|
45709
|
+
add,
|
|
44404
45710
|
getAll,
|
|
44405
45711
|
getById,
|
|
45712
|
+
getBySchool,
|
|
45713
|
+
updateFieldById,
|
|
44406
45714
|
updateById,
|
|
44407
45715
|
deleteById
|
|
44408
45716
|
};
|
|
44409
45717
|
}
|
|
44410
45718
|
|
|
44411
|
-
// src/resources/
|
|
44412
|
-
import { useAtlas as
|
|
44413
|
-
function
|
|
44414
|
-
const {
|
|
44415
|
-
|
|
44416
|
-
|
|
44417
|
-
|
|
44418
|
-
} = useBuildingUnitRepo();
|
|
44419
|
-
async function add(value) {
|
|
44420
|
-
const session = useAtlas34.getClient()?.startSession();
|
|
45719
|
+
// src/resources/kindergarten-domain/kindergarten.domain.service.ts
|
|
45720
|
+
import { AppError as AppError30, BadRequestError as BadRequestError78, useAtlas as useAtlas37 } from "@eeplatform/nodejs-utils";
|
|
45721
|
+
function useKindergartenDomainService() {
|
|
45722
|
+
const { deleteById: _deleteById, getById } = useKindergartenDomainRepo();
|
|
45723
|
+
const { countByDomain } = useKindergartenRoutineRepo();
|
|
45724
|
+
async function deleteById(id) {
|
|
45725
|
+
const session = useAtlas37.getClient()?.startSession();
|
|
44421
45726
|
if (!session) {
|
|
44422
|
-
throw new Error("
|
|
45727
|
+
throw new Error("Failed to start database session.");
|
|
44423
45728
|
}
|
|
44424
45729
|
try {
|
|
44425
|
-
|
|
44426
|
-
const
|
|
44427
|
-
|
|
44428
|
-
|
|
44429
|
-
|
|
44430
|
-
|
|
44431
|
-
|
|
44432
|
-
|
|
44433
|
-
|
|
44434
|
-
session
|
|
45730
|
+
session.startTransaction();
|
|
45731
|
+
const domain = await getById(id);
|
|
45732
|
+
if (!domain) {
|
|
45733
|
+
throw new BadRequestError78("Kindergarten domain not found.");
|
|
45734
|
+
}
|
|
45735
|
+
const usageCount = await countByDomain(domain.title);
|
|
45736
|
+
if (usageCount > 0) {
|
|
45737
|
+
throw new BadRequestError78(
|
|
45738
|
+
"Cannot delete domain as it is currently in use."
|
|
44435
45739
|
);
|
|
44436
45740
|
}
|
|
44437
|
-
await session
|
|
44438
|
-
return "Building unit added successfully.";
|
|
45741
|
+
await _deleteById(id, session);
|
|
44439
45742
|
} catch (error) {
|
|
44440
45743
|
await session.abortTransaction();
|
|
44441
|
-
|
|
45744
|
+
if (error instanceof AppError30) {
|
|
45745
|
+
throw error;
|
|
45746
|
+
} else {
|
|
45747
|
+
throw new AppError30("Failed to delete kindergarten domain.", 500);
|
|
45748
|
+
}
|
|
44442
45749
|
} finally {
|
|
44443
|
-
session.endSession();
|
|
44444
|
-
}
|
|
44445
|
-
}
|
|
44446
|
-
const { getById: getSectionSubjectByClassroom } = useSectionSubjectRepo();
|
|
44447
|
-
async function deleteById(id) {
|
|
44448
|
-
if (!id) {
|
|
44449
|
-
throw new Error("Invalid building unit ID.");
|
|
44450
|
-
}
|
|
44451
|
-
const sectionSubject = await getSectionSubjectByClassroom(id);
|
|
44452
|
-
if (sectionSubject) {
|
|
44453
|
-
throw new Error(
|
|
44454
|
-
"Cannot delete building unit as it is assigned to a section subject."
|
|
44455
|
-
);
|
|
44456
|
-
}
|
|
44457
|
-
try {
|
|
44458
|
-
await _deleteById(id);
|
|
44459
|
-
return "Building unit deleted successfully.";
|
|
44460
|
-
} catch (error) {
|
|
44461
|
-
throw new Error("Failed to delete building unit.");
|
|
45750
|
+
await session.endSession();
|
|
44462
45751
|
}
|
|
44463
45752
|
}
|
|
44464
45753
|
return {
|
|
44465
|
-
add,
|
|
44466
45754
|
deleteById
|
|
44467
45755
|
};
|
|
44468
45756
|
}
|
|
44469
45757
|
|
|
44470
|
-
// src/resources/
|
|
44471
|
-
import { BadRequestError as
|
|
44472
|
-
import
|
|
44473
|
-
function
|
|
45758
|
+
// src/resources/kindergarten-domain/kindergarten.domain.controller.ts
|
|
45759
|
+
import { BadRequestError as BadRequestError79 } from "@eeplatform/nodejs-utils";
|
|
45760
|
+
import Joi51 from "joi";
|
|
45761
|
+
function useKindergartenDomainController() {
|
|
44474
45762
|
const {
|
|
45763
|
+
add: _add,
|
|
44475
45764
|
getAll: _getAll,
|
|
44476
45765
|
getById: _getById,
|
|
44477
|
-
|
|
44478
|
-
|
|
44479
|
-
|
|
45766
|
+
getBySchool: _getBySchool,
|
|
45767
|
+
updateFieldById: _updateFieldById
|
|
45768
|
+
} = useKindergartenDomainRepo();
|
|
44480
45769
|
async function add(req, res, next) {
|
|
44481
|
-
const
|
|
44482
|
-
const
|
|
44483
|
-
building: Joi47.object({
|
|
44484
|
-
school: Joi47.string().hex().required(),
|
|
44485
|
-
name: Joi47.string().optional().allow("", null),
|
|
44486
|
-
building: Joi47.string().hex().required(),
|
|
44487
|
-
buildingName: Joi47.string().optional().allow("", null),
|
|
44488
|
-
level: Joi47.number().integer().min(1).required(),
|
|
44489
|
-
category: Joi47.string().required(),
|
|
44490
|
-
type: Joi47.string().required(),
|
|
44491
|
-
seating_capacity: Joi47.number().integer().min(0).required(),
|
|
44492
|
-
standing_capacity: Joi47.number().integer().min(0).required(),
|
|
44493
|
-
description: Joi47.string().optional().allow("", null),
|
|
44494
|
-
unit_of_measurement: Joi47.string().valid("sqm").required(),
|
|
44495
|
-
area: Joi47.number().positive().required(),
|
|
44496
|
-
status: Joi47.string().optional().allow("", null)
|
|
44497
|
-
}),
|
|
44498
|
-
qty: Joi47.number().integer().min(1).max(20).optional().default(1)
|
|
44499
|
-
});
|
|
44500
|
-
const { error } = validation.validate(data);
|
|
45770
|
+
const value = req.body;
|
|
45771
|
+
const { error } = schemaKindergartenDomain.validate(value);
|
|
44501
45772
|
if (error) {
|
|
44502
|
-
next(new
|
|
45773
|
+
next(new BadRequestError79(error.message));
|
|
44503
45774
|
return;
|
|
44504
45775
|
}
|
|
44505
45776
|
try {
|
|
44506
|
-
const
|
|
45777
|
+
const data = await _add(value);
|
|
44507
45778
|
res.json({
|
|
44508
|
-
message: "
|
|
44509
|
-
data
|
|
45779
|
+
message: "Successfully created kindergarten domain.",
|
|
45780
|
+
data
|
|
44510
45781
|
});
|
|
44511
|
-
} catch (error2) {
|
|
44512
|
-
next(error2);
|
|
44513
|
-
}
|
|
44514
|
-
}
|
|
44515
|
-
async function updateById(req, res, next) {
|
|
44516
|
-
const data = req.body;
|
|
44517
|
-
const id = req.params.id ?? "";
|
|
44518
|
-
const validation = Joi47.object({
|
|
44519
|
-
id: Joi47.string().hex().required(),
|
|
44520
|
-
value: schemaUpdateOptions
|
|
44521
|
-
});
|
|
44522
|
-
const { error } = validation.validate({ id, value: data });
|
|
44523
|
-
if (error) {
|
|
44524
|
-
next(new BadRequestError72(error.message));
|
|
44525
45782
|
return;
|
|
44526
|
-
}
|
|
44527
|
-
try {
|
|
44528
|
-
const buildingUnit = await _updateById(id, data);
|
|
44529
|
-
res.json({
|
|
44530
|
-
message: "Building unit updated successfully.",
|
|
44531
|
-
data: { buildingUnit }
|
|
44532
|
-
});
|
|
44533
45783
|
} catch (error2) {
|
|
44534
45784
|
next(error2);
|
|
44535
45785
|
}
|
|
44536
45786
|
}
|
|
44537
45787
|
async function getAll(req, res, next) {
|
|
44538
45788
|
const query = req.query;
|
|
44539
|
-
const validation =
|
|
44540
|
-
page:
|
|
44541
|
-
limit:
|
|
44542
|
-
search:
|
|
44543
|
-
|
|
44544
|
-
|
|
44545
|
-
|
|
44546
|
-
type: Joi47.string().optional().allow("", null)
|
|
45789
|
+
const validation = Joi51.object({
|
|
45790
|
+
page: Joi51.number().min(1).optional().allow("", null),
|
|
45791
|
+
limit: Joi51.number().min(1).optional().allow("", null),
|
|
45792
|
+
search: Joi51.string().optional().allow("", null),
|
|
45793
|
+
status: Joi51.string().optional().allow("", null),
|
|
45794
|
+
school: Joi51.string().hex().optional().allow("", null),
|
|
45795
|
+
createdBy: Joi51.string().hex().optional().allow("", null)
|
|
44547
45796
|
});
|
|
44548
45797
|
const { error } = validation.validate(query);
|
|
44549
|
-
|
|
44550
|
-
|
|
45798
|
+
const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
|
|
45799
|
+
const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
|
|
45800
|
+
const search = req.query.search ?? "";
|
|
45801
|
+
const status = req.query.status ?? "active";
|
|
45802
|
+
const school = req.query.school ?? "";
|
|
45803
|
+
const createdBy = req.query.createdBy ?? "";
|
|
45804
|
+
const isPageNumber = isFinite(page);
|
|
45805
|
+
if (!isPageNumber) {
|
|
45806
|
+
next(new BadRequestError79("Invalid page number."));
|
|
44551
45807
|
return;
|
|
44552
45808
|
}
|
|
44553
|
-
const
|
|
44554
|
-
|
|
44555
|
-
|
|
44556
|
-
|
|
44557
|
-
|
|
44558
|
-
|
|
44559
|
-
|
|
44560
|
-
|
|
44561
|
-
sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
|
|
44562
|
-
});
|
|
45809
|
+
const isLimitNumber = isFinite(limit);
|
|
45810
|
+
if (!isLimitNumber) {
|
|
45811
|
+
next(new BadRequestError79("Invalid limit number."));
|
|
45812
|
+
return;
|
|
45813
|
+
}
|
|
45814
|
+
if (error) {
|
|
45815
|
+
next(new BadRequestError79(error.message));
|
|
45816
|
+
return;
|
|
44563
45817
|
}
|
|
44564
|
-
const status = req.query.status ?? "active";
|
|
44565
|
-
const school = req.query.school ?? "";
|
|
44566
|
-
const building = req.query.building ?? "";
|
|
44567
|
-
const search = req.query.search ?? "";
|
|
44568
|
-
const type = req.query.type ?? "";
|
|
44569
45818
|
try {
|
|
44570
|
-
const
|
|
45819
|
+
const data = await _getAll({
|
|
44571
45820
|
page,
|
|
44572
45821
|
limit,
|
|
44573
|
-
|
|
45822
|
+
search,
|
|
44574
45823
|
status,
|
|
44575
45824
|
school,
|
|
44576
|
-
|
|
44577
|
-
building,
|
|
44578
|
-
type
|
|
45825
|
+
createdBy: createdBy || void 0
|
|
44579
45826
|
});
|
|
44580
|
-
res.json(
|
|
45827
|
+
res.json(data);
|
|
44581
45828
|
return;
|
|
44582
45829
|
} catch (error2) {
|
|
44583
45830
|
next(error2);
|
|
@@ -44585,37 +45832,80 @@ function useBuildingUnitController() {
|
|
|
44585
45832
|
}
|
|
44586
45833
|
async function getById(req, res, next) {
|
|
44587
45834
|
const id = req.params.id;
|
|
44588
|
-
const validation =
|
|
44589
|
-
id:
|
|
45835
|
+
const validation = Joi51.object({
|
|
45836
|
+
id: Joi51.string().hex().required()
|
|
44590
45837
|
});
|
|
44591
45838
|
const { error } = validation.validate({ id });
|
|
44592
45839
|
if (error) {
|
|
44593
|
-
next(new
|
|
45840
|
+
next(new BadRequestError79(error.message));
|
|
44594
45841
|
return;
|
|
44595
45842
|
}
|
|
44596
45843
|
try {
|
|
44597
|
-
const
|
|
45844
|
+
const data = await _getById(id);
|
|
44598
45845
|
res.json({
|
|
44599
|
-
message: "Successfully retrieved
|
|
44600
|
-
data
|
|
45846
|
+
message: "Successfully retrieved kindergarten domain.",
|
|
45847
|
+
data
|
|
45848
|
+
});
|
|
45849
|
+
return;
|
|
45850
|
+
} catch (error2) {
|
|
45851
|
+
next(error2);
|
|
45852
|
+
}
|
|
45853
|
+
}
|
|
45854
|
+
async function getBySchool(req, res, next) {
|
|
45855
|
+
const school = req.params.school;
|
|
45856
|
+
const validation = Joi51.object({
|
|
45857
|
+
school: Joi51.string().hex().required()
|
|
45858
|
+
});
|
|
45859
|
+
const { error } = validation.validate({ school });
|
|
45860
|
+
if (error) {
|
|
45861
|
+
next(new BadRequestError79(error.message));
|
|
45862
|
+
return;
|
|
45863
|
+
}
|
|
45864
|
+
try {
|
|
45865
|
+
const data = await _getBySchool(school);
|
|
45866
|
+
res.json({
|
|
45867
|
+
message: "Successfully retrieved kindergarten domains.",
|
|
45868
|
+
data
|
|
44601
45869
|
});
|
|
44602
45870
|
return;
|
|
44603
45871
|
} catch (error2) {
|
|
44604
45872
|
next(error2);
|
|
44605
45873
|
}
|
|
44606
45874
|
}
|
|
45875
|
+
async function updateField(req, res, next) {
|
|
45876
|
+
const _id = req.params.id;
|
|
45877
|
+
const { field, value } = req.body;
|
|
45878
|
+
const validation = Joi51.object({
|
|
45879
|
+
_id: Joi51.string().hex().required(),
|
|
45880
|
+
field: Joi51.string().valid("title", "status").required(),
|
|
45881
|
+
value: Joi51.alternatives().try(Joi51.string(), Joi51.array(), Joi51.object()).required()
|
|
45882
|
+
});
|
|
45883
|
+
const { error } = validation.validate({ _id, field, value });
|
|
45884
|
+
if (error) {
|
|
45885
|
+
next(new BadRequestError79(error.message));
|
|
45886
|
+
return;
|
|
45887
|
+
}
|
|
45888
|
+
try {
|
|
45889
|
+
const message = await _updateFieldById({ _id, field, value });
|
|
45890
|
+
res.json({ message });
|
|
45891
|
+
return;
|
|
45892
|
+
} catch (error2) {
|
|
45893
|
+
next(error2);
|
|
45894
|
+
}
|
|
45895
|
+
}
|
|
45896
|
+
const { deleteById: _deleteById } = useKindergartenDomainService();
|
|
44607
45897
|
async function deleteById(req, res, next) {
|
|
44608
|
-
const
|
|
44609
|
-
const validation =
|
|
44610
|
-
|
|
45898
|
+
const _id = req.params.id;
|
|
45899
|
+
const validation = Joi51.object({
|
|
45900
|
+
_id: Joi51.string().hex().required()
|
|
44611
45901
|
});
|
|
44612
|
-
const { error } = validation.validate({
|
|
45902
|
+
const { error } = validation.validate({ _id });
|
|
44613
45903
|
if (error) {
|
|
44614
|
-
next(new
|
|
45904
|
+
next(new BadRequestError79(error.message));
|
|
44615
45905
|
return;
|
|
44616
45906
|
}
|
|
44617
45907
|
try {
|
|
44618
|
-
const message = await _deleteById(
|
|
45908
|
+
const message = await _deleteById(_id);
|
|
44619
45909
|
res.json({ message });
|
|
44620
45910
|
return;
|
|
44621
45911
|
} catch (error2) {
|
|
@@ -44626,7 +45916,8 @@ function useBuildingUnitController() {
|
|
|
44626
45916
|
add,
|
|
44627
45917
|
getAll,
|
|
44628
45918
|
getById,
|
|
44629
|
-
|
|
45919
|
+
getBySchool,
|
|
45920
|
+
updateField,
|
|
44630
45921
|
deleteById
|
|
44631
45922
|
};
|
|
44632
45923
|
}
|
|
@@ -44647,6 +45938,8 @@ export {
|
|
|
44647
45938
|
allowedSectionStudentStatuses,
|
|
44648
45939
|
modelBasicEduCount,
|
|
44649
45940
|
modelDivision,
|
|
45941
|
+
modelKindergartenDomain,
|
|
45942
|
+
modelKindergartenRoutine,
|
|
44650
45943
|
modelProgram,
|
|
44651
45944
|
modelProgramScreening,
|
|
44652
45945
|
modelRegion,
|
|
@@ -44669,6 +45962,9 @@ export {
|
|
|
44669
45962
|
schemaEnrollment,
|
|
44670
45963
|
schemaGenerateSections,
|
|
44671
45964
|
schemaGradeLevel,
|
|
45965
|
+
schemaKindergartenDomain,
|
|
45966
|
+
schemaKindergartenRoutine,
|
|
45967
|
+
schemaKindergartenRoutineUpdate,
|
|
44672
45968
|
schemaPersonnel,
|
|
44673
45969
|
schemaPlantilla,
|
|
44674
45970
|
schemaProgram,
|
|
@@ -44710,6 +46006,11 @@ export {
|
|
|
44710
46006
|
useEnrollmentService,
|
|
44711
46007
|
useGradeLevelController,
|
|
44712
46008
|
useGradeLevelRepo,
|
|
46009
|
+
useKindergartenDomainController,
|
|
46010
|
+
useKindergartenDomainRepo,
|
|
46011
|
+
useKindergartenDomainService,
|
|
46012
|
+
useKindergartenRoutineController,
|
|
46013
|
+
useKindergartenRoutineRepo,
|
|
44713
46014
|
useLearnerController,
|
|
44714
46015
|
useLearnerRepo,
|
|
44715
46016
|
usePersonnelController,
|