@eeplatform/basic-edu 1.9.3 → 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 +12 -0
- package/dist/index.d.ts +127 -2
- package/dist/index.js +1603 -305
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2755 -1449
- 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,436 +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
|
-
|
|
42987
|
-
|
|
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;
|
|
44424
|
+
}
|
|
44425
|
+
const result = await collection.findOne({
|
|
44426
|
+
_id
|
|
44427
|
+
});
|
|
44428
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
44429
|
+
logger41.log({
|
|
44430
|
+
level: "info",
|
|
44431
|
+
message: `Cache set for building by id: ${cacheKey}`
|
|
44432
|
+
});
|
|
44433
|
+
}).catch((err) => {
|
|
44434
|
+
logger41.log({
|
|
44435
|
+
level: "error",
|
|
44436
|
+
message: `Failed to set cache for building by id: ${err.message}`
|
|
44437
|
+
});
|
|
44438
|
+
});
|
|
44439
|
+
return result;
|
|
44440
|
+
} catch (error) {
|
|
44441
|
+
if (error instanceof AppError27) {
|
|
44442
|
+
throw error;
|
|
44443
|
+
} else {
|
|
44444
|
+
throw new InternalServerError23("Failed to get building.");
|
|
44445
|
+
}
|
|
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"
|
|
42988
44541
|
}
|
|
42989
|
-
await addTeachingLoad(
|
|
42990
|
-
{
|
|
42991
|
-
school: value.school,
|
|
42992
|
-
schoolName: schoolData.name,
|
|
42993
|
-
schoolYear: value.schoolYear,
|
|
42994
|
-
teacher: teacher._id.toString(),
|
|
42995
|
-
teacherName: `${teacher.firstName} ${teacher.lastName}`,
|
|
42996
|
-
status: "draft"
|
|
42997
|
-
},
|
|
42998
|
-
session
|
|
42999
|
-
);
|
|
43000
44542
|
}
|
|
43001
|
-
|
|
43002
|
-
|
|
43003
|
-
|
|
43004
|
-
}
|
|
43005
|
-
|
|
43006
|
-
|
|
43007
|
-
|
|
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;
|
|
43008
44574
|
} else {
|
|
43009
|
-
throw new
|
|
44575
|
+
throw new Error("Failed to create building unit.");
|
|
43010
44576
|
}
|
|
43011
|
-
} finally {
|
|
43012
|
-
await session?.endSession();
|
|
43013
44577
|
}
|
|
43014
44578
|
}
|
|
43015
|
-
async function
|
|
43016
|
-
const { error } =
|
|
44579
|
+
async function updateById(_id, value, session) {
|
|
44580
|
+
const { error } = schemaUpdateOptions.validate(value);
|
|
43017
44581
|
if (error) {
|
|
43018
|
-
throw new
|
|
43019
|
-
`Invalid section generation data: ${error.message}`
|
|
43020
|
-
);
|
|
44582
|
+
throw new BadRequestError72(error.message);
|
|
43021
44583
|
}
|
|
43022
44584
|
try {
|
|
43023
|
-
|
|
43024
|
-
|
|
43025
|
-
|
|
43026
|
-
|
|
43027
|
-
|
|
43028
|
-
|
|
43029
|
-
|
|
43030
|
-
|
|
43031
|
-
|
|
43032
|
-
const gradeLevelData = await getByGradeLevel({
|
|
43033
|
-
school: value.school,
|
|
43034
|
-
gradeLevel: value.gradeLevel
|
|
43035
|
-
});
|
|
43036
|
-
if (!gradeLevelData) {
|
|
43037
|
-
throw new BadRequestError64("Grade level not found.");
|
|
43038
|
-
}
|
|
43039
|
-
const minPerSection = value.minStudents ?? gradeLevelData.minNumberOfLearners;
|
|
43040
|
-
const maxPerSection = value.maxStudents ?? gradeLevelData.maxNumberOfLearners;
|
|
43041
|
-
const sectionsNeeded = Math.ceil(studentCount / minPerSection);
|
|
43042
|
-
if (sectionsNeeded > value.set.length) {
|
|
43043
|
-
throw new BadRequestError64(
|
|
43044
|
-
"Insufficient number of section names in set[]."
|
|
43045
|
-
);
|
|
43046
|
-
}
|
|
43047
|
-
const sectionSizes = distributeStudents(
|
|
43048
|
-
studentCount,
|
|
43049
|
-
minPerSection,
|
|
43050
|
-
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 }
|
|
43051
44594
|
);
|
|
43052
|
-
|
|
43053
|
-
|
|
43054
|
-
}
|
|
43055
|
-
const sections = sectionSizes.map((size, index) => ({
|
|
43056
|
-
name: value.set[index],
|
|
43057
|
-
value: size
|
|
43058
|
-
}));
|
|
43059
|
-
return {
|
|
43060
|
-
totalSectionsGenerated: sectionSizes.length,
|
|
43061
|
-
totalStudentsAssigned: studentCount,
|
|
43062
|
-
sections
|
|
43063
|
-
};
|
|
44595
|
+
delCachedData();
|
|
44596
|
+
return res;
|
|
43064
44597
|
} catch (error2) {
|
|
43065
|
-
|
|
44598
|
+
logger42.log({
|
|
44599
|
+
level: "error",
|
|
44600
|
+
message: error2.message
|
|
44601
|
+
});
|
|
44602
|
+
if (error2 instanceof AppError28) {
|
|
43066
44603
|
throw error2;
|
|
43067
44604
|
} else {
|
|
43068
|
-
throw new
|
|
44605
|
+
throw new Error("Failed to create building unit.");
|
|
43069
44606
|
}
|
|
43070
44607
|
}
|
|
43071
44608
|
}
|
|
43072
|
-
|
|
43073
|
-
}
|
|
43074
|
-
|
|
43075
|
-
// src/resources/section/section.controller.ts
|
|
43076
|
-
function useSectionController() {
|
|
43077
|
-
const {
|
|
43078
|
-
add: _add,
|
|
43079
|
-
getAll: _getAll,
|
|
43080
|
-
getById: _getById,
|
|
43081
|
-
getByName: _getByName,
|
|
43082
|
-
getBySchool: _getBySchool,
|
|
43083
|
-
updateFieldById: _updateFieldById,
|
|
43084
|
-
addStudentToSection: _addStudentToSection,
|
|
43085
|
-
removeStudentFromSection: _removeStudentFromSection,
|
|
43086
|
-
deleteById: _deleteById
|
|
43087
|
-
} = useSectionRepo();
|
|
43088
|
-
const {
|
|
43089
|
-
generateSections: _generateSections,
|
|
43090
|
-
generateSectionPreview: _generateSectionPreview
|
|
43091
|
-
} = useSectionService();
|
|
43092
|
-
async function add(req, res, next) {
|
|
43093
|
-
const value = req.body;
|
|
43094
|
-
const { error } = schemaSection.validate(value);
|
|
44609
|
+
async function updateByBuildingId(building, value, session) {
|
|
44610
|
+
const { error } = schemaUpdateOptions.validate(value);
|
|
43095
44611
|
if (error) {
|
|
43096
|
-
|
|
43097
|
-
return;
|
|
44612
|
+
throw new BadRequestError72(error.message);
|
|
43098
44613
|
}
|
|
43099
44614
|
try {
|
|
43100
|
-
|
|
43101
|
-
res.json({
|
|
43102
|
-
message: "Successfully created section.",
|
|
43103
|
-
data
|
|
43104
|
-
});
|
|
43105
|
-
return;
|
|
44615
|
+
building = new ObjectId45(building);
|
|
43106
44616
|
} catch (error2) {
|
|
43107
|
-
|
|
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
|
+
}
|
|
43108
44637
|
}
|
|
43109
44638
|
}
|
|
43110
|
-
async function
|
|
43111
|
-
|
|
43112
|
-
|
|
43113
|
-
|
|
43114
|
-
|
|
43115
|
-
|
|
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;
|
|
43116
44683
|
}
|
|
44684
|
+
const cacheKey = makeCacheKey24(namespace_collection, cacheParams);
|
|
44685
|
+
logger42.log({
|
|
44686
|
+
level: "info",
|
|
44687
|
+
message: `Cache key for getAll building units: ${cacheKey}`
|
|
44688
|
+
});
|
|
43117
44689
|
try {
|
|
43118
|
-
const
|
|
43119
|
-
|
|
43120
|
-
|
|
43121
|
-
|
|
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
|
+
});
|
|
43122
44716
|
});
|
|
43123
|
-
return;
|
|
43124
|
-
} catch (
|
|
43125
|
-
|
|
44717
|
+
return data;
|
|
44718
|
+
} catch (error) {
|
|
44719
|
+
logger42.log({ level: "error", message: `${error}` });
|
|
44720
|
+
throw error;
|
|
43126
44721
|
}
|
|
43127
44722
|
}
|
|
43128
|
-
async function
|
|
43129
|
-
const
|
|
43130
|
-
|
|
43131
|
-
|
|
43132
|
-
|
|
43133
|
-
|
|
43134
|
-
|
|
44723
|
+
async function countByBuilding(building, level) {
|
|
44724
|
+
const query = {
|
|
44725
|
+
status: "active"
|
|
44726
|
+
};
|
|
44727
|
+
const cacheKeyOptions = {
|
|
44728
|
+
...query,
|
|
44729
|
+
tag: "countByBuilding"
|
|
44730
|
+
};
|
|
43135
44731
|
try {
|
|
43136
|
-
|
|
43137
|
-
|
|
43138
|
-
|
|
43139
|
-
|
|
43140
|
-
next(error2);
|
|
44732
|
+
query.building = new ObjectId45(building);
|
|
44733
|
+
cacheKeyOptions.building = String(building);
|
|
44734
|
+
} catch (error) {
|
|
44735
|
+
throw new BadRequestError72("Invalid building ID.");
|
|
43141
44736
|
}
|
|
43142
|
-
|
|
43143
|
-
|
|
43144
|
-
|
|
43145
|
-
const validation = Joi43.object({
|
|
43146
|
-
page: Joi43.number().min(1).optional().allow("", null),
|
|
43147
|
-
limit: Joi43.number().min(1).optional().allow("", null),
|
|
43148
|
-
search: Joi43.string().optional().allow("", null),
|
|
43149
|
-
status: Joi43.string().optional().allow("", null),
|
|
43150
|
-
school: Joi43.string().hex().optional().allow("", null),
|
|
43151
|
-
schoolYear: Joi43.string().optional().allow("", null),
|
|
43152
|
-
gradeLevel: Joi43.string().optional().allow("", null)
|
|
43153
|
-
});
|
|
43154
|
-
const { error } = validation.validate(query);
|
|
43155
|
-
const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
|
|
43156
|
-
const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
|
|
43157
|
-
const search = req.query.search ?? "";
|
|
43158
|
-
const status = req.query.status ?? "active";
|
|
43159
|
-
const school = req.query.school ?? "";
|
|
43160
|
-
const schoolYear = req.query.schoolYear ?? "";
|
|
43161
|
-
const gradeLevel = req.query.gradeLevel ?? "";
|
|
43162
|
-
const isPageNumber = isFinite(page);
|
|
43163
|
-
if (!isPageNumber) {
|
|
43164
|
-
next(new BadRequestError65("Invalid page number."));
|
|
43165
|
-
return;
|
|
44737
|
+
if (level) {
|
|
44738
|
+
query.level = level;
|
|
44739
|
+
cacheKeyOptions.level = level;
|
|
43166
44740
|
}
|
|
43167
|
-
|
|
43168
|
-
|
|
43169
|
-
|
|
43170
|
-
|
|
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.");
|
|
43171
44746
|
}
|
|
43172
|
-
|
|
43173
|
-
|
|
43174
|
-
|
|
44747
|
+
}
|
|
44748
|
+
async function getById(_id) {
|
|
44749
|
+
try {
|
|
44750
|
+
_id = new ObjectId45(_id);
|
|
44751
|
+
} catch (error) {
|
|
44752
|
+
throw new BadRequestError72(namespace_collection + " Invalid ID.");
|
|
43175
44753
|
}
|
|
44754
|
+
const cacheKey = makeCacheKey24(namespace_collection, { _id: String(_id) });
|
|
43176
44755
|
try {
|
|
43177
|
-
const
|
|
43178
|
-
|
|
43179
|
-
|
|
43180
|
-
|
|
43181
|
-
|
|
43182
|
-
|
|
43183
|
-
|
|
43184
|
-
|
|
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] }
|
|
43185
44767
|
});
|
|
43186
|
-
|
|
43187
|
-
|
|
43188
|
-
|
|
43189
|
-
|
|
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
|
+
}
|
|
43190
44789
|
}
|
|
43191
44790
|
}
|
|
43192
|
-
async function
|
|
43193
|
-
const id = req.params.id;
|
|
43194
|
-
const validation = Joi43.object({
|
|
43195
|
-
id: Joi43.string().hex().required()
|
|
43196
|
-
});
|
|
43197
|
-
const { error } = validation.validate({ id });
|
|
43198
|
-
if (error) {
|
|
43199
|
-
next(new BadRequestError65(error.message));
|
|
43200
|
-
return;
|
|
43201
|
-
}
|
|
44791
|
+
async function getByBuildingLevel(building, level) {
|
|
43202
44792
|
try {
|
|
43203
|
-
|
|
43204
|
-
|
|
43205
|
-
|
|
43206
|
-
} catch (error2) {
|
|
43207
|
-
next(error2);
|
|
44793
|
+
building = new ObjectId45(building);
|
|
44794
|
+
} catch (error) {
|
|
44795
|
+
throw new BadRequestError72("Invalid building ID.");
|
|
43208
44796
|
}
|
|
43209
|
-
|
|
43210
|
-
|
|
43211
|
-
|
|
43212
|
-
const validation = Joi43.object({
|
|
43213
|
-
name: Joi43.string().required()
|
|
44797
|
+
const cacheKey = makeCacheKey24(namespace_collection, {
|
|
44798
|
+
building: String(building),
|
|
44799
|
+
level
|
|
43214
44800
|
});
|
|
43215
|
-
const { error } = validation.validate({ name });
|
|
43216
|
-
if (error) {
|
|
43217
|
-
next(new BadRequestError65(error.message));
|
|
43218
|
-
return;
|
|
43219
|
-
}
|
|
43220
44801
|
try {
|
|
43221
|
-
const
|
|
43222
|
-
|
|
43223
|
-
|
|
43224
|
-
|
|
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"
|
|
43225
44814
|
});
|
|
43226
|
-
|
|
43227
|
-
|
|
43228
|
-
|
|
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
|
+
}
|
|
43229
44833
|
}
|
|
43230
44834
|
}
|
|
43231
|
-
async function
|
|
43232
|
-
|
|
43233
|
-
|
|
43234
|
-
|
|
43235
|
-
|
|
43236
|
-
const { error } = validation.validate({ school });
|
|
43237
|
-
if (error) {
|
|
43238
|
-
next(new BadRequestError65(error.message));
|
|
43239
|
-
return;
|
|
44835
|
+
async function getByBuilding(building) {
|
|
44836
|
+
try {
|
|
44837
|
+
building = new ObjectId45(building);
|
|
44838
|
+
} catch (error) {
|
|
44839
|
+
throw new BadRequestError72("Invalid building ID.");
|
|
43240
44840
|
}
|
|
44841
|
+
const cacheKey = makeCacheKey24(namespace_collection, {
|
|
44842
|
+
building: String(building)
|
|
44843
|
+
});
|
|
43241
44844
|
try {
|
|
43242
|
-
const
|
|
43243
|
-
|
|
43244
|
-
|
|
43245
|
-
|
|
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"
|
|
43246
44856
|
});
|
|
43247
|
-
|
|
43248
|
-
|
|
43249
|
-
|
|
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
|
+
}
|
|
43250
44875
|
}
|
|
43251
44876
|
}
|
|
43252
|
-
async function
|
|
43253
|
-
|
|
43254
|
-
|
|
43255
|
-
|
|
43256
|
-
|
|
43257
|
-
field: Joi43.string().valid("name", "schoolYear", "gradeLevel", "adviser", "adviserName").required(),
|
|
43258
|
-
value: Joi43.string().required()
|
|
43259
|
-
});
|
|
43260
|
-
const { error } = validation.validate({ _id, field, value });
|
|
43261
|
-
if (error) {
|
|
43262
|
-
next(new BadRequestError65(error.message));
|
|
43263
|
-
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.");
|
|
43264
44882
|
}
|
|
43265
44883
|
try {
|
|
43266
|
-
const
|
|
43267
|
-
|
|
43268
|
-
|
|
43269
|
-
|
|
43270
|
-
|
|
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
|
+
}
|
|
43271
44901
|
}
|
|
43272
44902
|
}
|
|
43273
|
-
|
|
43274
|
-
|
|
43275
|
-
|
|
43276
|
-
|
|
43277
|
-
|
|
43278
|
-
|
|
43279
|
-
|
|
43280
|
-
|
|
43281
|
-
|
|
43282
|
-
|
|
43283
|
-
|
|
43284
|
-
|
|
43285
|
-
|
|
43286
|
-
|
|
43287
|
-
|
|
43288
|
-
|
|
43289
|
-
|
|
43290
|
-
|
|
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();
|
|
43291
44953
|
}
|
|
43292
44954
|
}
|
|
43293
|
-
async function
|
|
43294
|
-
const
|
|
43295
|
-
|
|
43296
|
-
|
|
43297
|
-
|
|
43298
|
-
|
|
43299
|
-
});
|
|
43300
|
-
const { error } = validation.validate({ _id, studentId });
|
|
43301
|
-
if (error) {
|
|
43302
|
-
next(new BadRequestError65(error.message));
|
|
43303
|
-
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
|
+
);
|
|
43304
44961
|
}
|
|
43305
44962
|
try {
|
|
43306
|
-
|
|
43307
|
-
|
|
43308
|
-
|
|
43309
|
-
|
|
43310
|
-
next(error2);
|
|
44963
|
+
await _deleteById(id);
|
|
44964
|
+
return "Building deleted successfully.";
|
|
44965
|
+
} catch (error) {
|
|
44966
|
+
throw error;
|
|
43311
44967
|
}
|
|
43312
44968
|
}
|
|
43313
|
-
|
|
43314
|
-
|
|
43315
|
-
|
|
43316
|
-
|
|
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)
|
|
43317
44989
|
});
|
|
43318
|
-
const { error } = validation.validate(
|
|
44990
|
+
const { error } = validation.validate(value);
|
|
43319
44991
|
if (error) {
|
|
43320
|
-
next(new
|
|
44992
|
+
next(new BadRequestError74(error.message));
|
|
44993
|
+
logger43.info(`Controller: ${error.message}`);
|
|
43321
44994
|
return;
|
|
43322
44995
|
}
|
|
43323
44996
|
try {
|
|
43324
|
-
const
|
|
43325
|
-
res.json(
|
|
44997
|
+
const result = await _add(value);
|
|
44998
|
+
res.json(result);
|
|
43326
44999
|
return;
|
|
43327
45000
|
} catch (error2) {
|
|
43328
45001
|
next(error2);
|
|
43329
45002
|
}
|
|
43330
45003
|
}
|
|
43331
|
-
|
|
43332
|
-
add,
|
|
43333
|
-
generateSections,
|
|
43334
|
-
generateSectionPreview,
|
|
43335
|
-
getAll,
|
|
43336
|
-
getById,
|
|
43337
|
-
getByName,
|
|
43338
|
-
getBySchool,
|
|
43339
|
-
updateField,
|
|
43340
|
-
addStudent,
|
|
43341
|
-
removeStudent,
|
|
43342
|
-
deleteById
|
|
43343
|
-
};
|
|
43344
|
-
}
|
|
43345
|
-
|
|
43346
|
-
// src/resources/section-student/section.student.controller.ts
|
|
43347
|
-
import { BadRequestError as BadRequestError66 } from "@eeplatform/nodejs-utils";
|
|
43348
|
-
import Joi44 from "joi";
|
|
43349
|
-
function useSectionStudentController() {
|
|
43350
|
-
const { add: _add, getAll: _getAll } = useSectionStudentRepo();
|
|
43351
|
-
async function add(req, res, next) {
|
|
45004
|
+
async function updateById(req, res, next) {
|
|
43352
45005
|
const value = req.body;
|
|
43353
|
-
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 });
|
|
43354
45016
|
if (error) {
|
|
43355
|
-
next(new
|
|
45017
|
+
next(new BadRequestError74(error.message));
|
|
45018
|
+
logger43.info(`Controller: ${error.message}`);
|
|
43356
45019
|
return;
|
|
43357
45020
|
}
|
|
43358
45021
|
try {
|
|
43359
|
-
const
|
|
43360
|
-
res.json(
|
|
43361
|
-
message: "Successfully created section student.",
|
|
43362
|
-
data
|
|
43363
|
-
});
|
|
45022
|
+
const result = await _updateById(id, value);
|
|
45023
|
+
res.json(result);
|
|
43364
45024
|
return;
|
|
43365
45025
|
} catch (error2) {
|
|
43366
45026
|
next(error2);
|
|
@@ -43368,409 +45028,310 @@ function useSectionStudentController() {
|
|
|
43368
45028
|
}
|
|
43369
45029
|
async function getAll(req, res, next) {
|
|
43370
45030
|
const query = req.query;
|
|
43371
|
-
const validation =
|
|
43372
|
-
page:
|
|
43373
|
-
limit:
|
|
43374
|
-
search:
|
|
43375
|
-
|
|
43376
|
-
|
|
43377
|
-
gradeLevel: Joi44.string().optional().allow("", null),
|
|
43378
|
-
section: Joi44.string().optional().allow("", null),
|
|
43379
|
-
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)
|
|
43380
45037
|
});
|
|
43381
45038
|
const { error } = validation.validate(query);
|
|
43382
|
-
const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
|
|
43383
|
-
const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
|
|
43384
|
-
const search = req.query.search ?? "";
|
|
43385
|
-
const status = req.query.status ?? "active";
|
|
43386
|
-
const school = req.query.school ?? "";
|
|
43387
|
-
const gradeLevel = req.query.gradeLevel ?? "";
|
|
43388
|
-
const section = req.query.section ?? "";
|
|
43389
|
-
const schoolYear = req.query.schoolYear ?? "";
|
|
43390
|
-
const isPageNumber = isFinite(page);
|
|
43391
|
-
if (!isPageNumber) {
|
|
43392
|
-
next(new BadRequestError66("Invalid page number."));
|
|
43393
|
-
return;
|
|
43394
|
-
}
|
|
43395
|
-
const isLimitNumber = isFinite(limit);
|
|
43396
|
-
if (!isLimitNumber) {
|
|
43397
|
-
next(new BadRequestError66("Invalid limit number."));
|
|
43398
|
-
return;
|
|
43399
|
-
}
|
|
43400
45039
|
if (error) {
|
|
43401
|
-
next(new
|
|
45040
|
+
next(new BadRequestError74(error.message));
|
|
43402
45041
|
return;
|
|
43403
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 ?? "";
|
|
43404
45057
|
try {
|
|
43405
|
-
const
|
|
45058
|
+
const buildings = await _getAll({
|
|
43406
45059
|
page,
|
|
43407
45060
|
limit,
|
|
43408
|
-
|
|
45061
|
+
sort: sortObj,
|
|
43409
45062
|
status,
|
|
43410
45063
|
school,
|
|
43411
|
-
|
|
43412
|
-
section,
|
|
43413
|
-
schoolYear
|
|
45064
|
+
search
|
|
43414
45065
|
});
|
|
43415
|
-
res.json(
|
|
45066
|
+
res.json(buildings);
|
|
43416
45067
|
return;
|
|
43417
45068
|
} catch (error2) {
|
|
43418
45069
|
next(error2);
|
|
43419
45070
|
}
|
|
43420
45071
|
}
|
|
43421
|
-
|
|
43422
|
-
|
|
43423
|
-
|
|
43424
|
-
|
|
43425
|
-
}
|
|
43426
|
-
|
|
43427
|
-
|
|
43428
|
-
|
|
43429
|
-
|
|
43430
|
-
import { ObjectId as ObjectId41 } from "mongodb";
|
|
43431
|
-
var schemaBuilding = Joi45.object({
|
|
43432
|
-
_id: Joi45.string().hex().optional(),
|
|
43433
|
-
school: Joi45.string().hex().required(),
|
|
43434
|
-
serial: Joi45.string().optional().allow("", null),
|
|
43435
|
-
name: Joi45.string().required(),
|
|
43436
|
-
levels: Joi45.number().integer().min(1).required(),
|
|
43437
|
-
createdAt: Joi45.date().optional().allow("", null),
|
|
43438
|
-
updatedAt: Joi45.date().optional().allow("", null),
|
|
43439
|
-
deletedAt: Joi45.date().optional().allow("", null),
|
|
43440
|
-
status: Joi45.string().optional().allow("", null)
|
|
43441
|
-
});
|
|
43442
|
-
var schemaBuildingUnit = Joi45.object({
|
|
43443
|
-
_id: Joi45.string().hex().optional(),
|
|
43444
|
-
school: Joi45.string().hex().required(),
|
|
43445
|
-
name: Joi45.string().optional().allow("", null),
|
|
43446
|
-
building: Joi45.string().hex().required(),
|
|
43447
|
-
buildingName: Joi45.string().optional().allow("", null),
|
|
43448
|
-
level: Joi45.number().integer().min(1).required(),
|
|
43449
|
-
category: Joi45.string().required(),
|
|
43450
|
-
type: Joi45.string().required(),
|
|
43451
|
-
seating_capacity: Joi45.number().integer().min(0).required(),
|
|
43452
|
-
standing_capacity: Joi45.number().integer().min(0).required(),
|
|
43453
|
-
description: Joi45.string().optional().allow("", null),
|
|
43454
|
-
unit_of_measurement: Joi45.string().valid("sqm").required(),
|
|
43455
|
-
area: Joi45.number().positive().required(),
|
|
43456
|
-
status: Joi45.string().optional().allow("", null)
|
|
43457
|
-
});
|
|
43458
|
-
var schemaUpdateOptions = Joi45.object({
|
|
43459
|
-
name: Joi45.string().optional().allow("", null),
|
|
43460
|
-
building: Joi45.string().hex().optional().allow("", null),
|
|
43461
|
-
buildingName: Joi45.string().optional().allow("", null),
|
|
43462
|
-
level: Joi45.number().integer().min(1).optional().allow("", null),
|
|
43463
|
-
category: Joi45.string().optional().allow("", null),
|
|
43464
|
-
type: Joi45.string().optional().allow("", null),
|
|
43465
|
-
seating_capacity: Joi45.number().integer().min(0).optional().allow("", null),
|
|
43466
|
-
standing_capacity: Joi45.number().integer().min(0).optional().allow("", null),
|
|
43467
|
-
area: Joi45.number().positive().optional().allow("", null)
|
|
43468
|
-
});
|
|
43469
|
-
function MBuilding(value) {
|
|
43470
|
-
const { error } = schemaBuilding.validate(value);
|
|
43471
|
-
if (error) {
|
|
43472
|
-
logger39.info(`Building Model: ${error.message}`);
|
|
43473
|
-
throw new BadRequestError67(error.message);
|
|
43474
|
-
}
|
|
43475
|
-
if (value._id && typeof value._id === "string") {
|
|
43476
|
-
try {
|
|
43477
|
-
value._id = new ObjectId41(value._id);
|
|
43478
|
-
} catch (error2) {
|
|
43479
|
-
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;
|
|
43480
45081
|
}
|
|
43481
|
-
}
|
|
43482
|
-
try {
|
|
43483
|
-
value.school = new ObjectId41(value.school);
|
|
43484
|
-
} catch (error2) {
|
|
43485
|
-
throw new BadRequestError67("Invalid school format");
|
|
43486
|
-
}
|
|
43487
|
-
return {
|
|
43488
|
-
_id: value._id ?? void 0,
|
|
43489
|
-
school: value.school,
|
|
43490
|
-
serial: value.serial ?? "",
|
|
43491
|
-
name: value.name ?? "",
|
|
43492
|
-
levels: value.levels ?? 0,
|
|
43493
|
-
status: value.status ?? "active",
|
|
43494
|
-
createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
|
|
43495
|
-
updatedAt: value.updatedAt ?? "",
|
|
43496
|
-
deletedAt: value.deletedAt ?? ""
|
|
43497
|
-
};
|
|
43498
|
-
}
|
|
43499
|
-
function MBuildingUnit(value) {
|
|
43500
|
-
const { error } = schemaBuildingUnit.validate(value);
|
|
43501
|
-
if (error) {
|
|
43502
|
-
logger39.info(`Building Unit Model: ${error.message}`);
|
|
43503
|
-
throw new BadRequestError67(error.message);
|
|
43504
|
-
}
|
|
43505
|
-
if (value._id && typeof value._id === "string") {
|
|
43506
45082
|
try {
|
|
43507
|
-
|
|
45083
|
+
const building = await _getById(id);
|
|
45084
|
+
res.json({
|
|
45085
|
+
message: "Successfully retrieved building.",
|
|
45086
|
+
data: { building }
|
|
45087
|
+
});
|
|
45088
|
+
return;
|
|
43508
45089
|
} catch (error2) {
|
|
43509
|
-
|
|
43510
|
-
}
|
|
43511
|
-
}
|
|
43512
|
-
try {
|
|
43513
|
-
value.school = new ObjectId41(value.school);
|
|
43514
|
-
} catch (error2) {
|
|
43515
|
-
throw new BadRequestError67("Invalid school ID");
|
|
43516
|
-
}
|
|
43517
|
-
try {
|
|
43518
|
-
value.building = new ObjectId41(value.building);
|
|
43519
|
-
} catch (error2) {
|
|
43520
|
-
throw new BadRequestError67("Invalid building ID");
|
|
43521
|
-
}
|
|
43522
|
-
return {
|
|
43523
|
-
_id: value._id ?? void 0,
|
|
43524
|
-
school: value.school,
|
|
43525
|
-
name: value.name ?? "",
|
|
43526
|
-
building: value.building,
|
|
43527
|
-
buildingName: value.buildingName ?? "",
|
|
43528
|
-
level: value.level ?? 0,
|
|
43529
|
-
category: value.category ?? "",
|
|
43530
|
-
type: value.type ?? "",
|
|
43531
|
-
seating_capacity: value.seating_capacity ?? 0,
|
|
43532
|
-
standing_capacity: value.standing_capacity ?? 0,
|
|
43533
|
-
description: value.description ?? "",
|
|
43534
|
-
unit_of_measurement: value.unit_of_measurement ?? "sqm",
|
|
43535
|
-
area: value.area ?? 0,
|
|
43536
|
-
status: value.status ?? "active",
|
|
43537
|
-
createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
|
|
43538
|
-
updatedAt: value.updatedAt ?? "",
|
|
43539
|
-
deletedAt: value.deletedAt ?? ""
|
|
43540
|
-
};
|
|
43541
|
-
}
|
|
43542
|
-
|
|
43543
|
-
// src/resources/building/building.repository.ts
|
|
43544
|
-
import {
|
|
43545
|
-
AppError as AppError26,
|
|
43546
|
-
BadRequestError as BadRequestError68,
|
|
43547
|
-
InternalServerError as InternalServerError22,
|
|
43548
|
-
logger as logger40,
|
|
43549
|
-
makeCacheKey as makeCacheKey22,
|
|
43550
|
-
paginate as paginate21,
|
|
43551
|
-
useAtlas as useAtlas31,
|
|
43552
|
-
useCache as useCache22
|
|
43553
|
-
} from "@eeplatform/nodejs-utils";
|
|
43554
|
-
import { ObjectId as ObjectId42 } from "mongodb";
|
|
43555
|
-
function useBuildingRepo() {
|
|
43556
|
-
const db = useAtlas31.getDb();
|
|
43557
|
-
if (!db) {
|
|
43558
|
-
throw new Error("Unable to connect to server.");
|
|
43559
|
-
}
|
|
43560
|
-
const namespace_collection = "deped.buildings";
|
|
43561
|
-
const collection = db.collection(namespace_collection);
|
|
43562
|
-
const { getCache, setCache, delNamespace } = useCache22(namespace_collection);
|
|
43563
|
-
async function createIndexes() {
|
|
43564
|
-
try {
|
|
43565
|
-
await collection.createIndexes([
|
|
43566
|
-
{ key: { name: 1 }, unique: true, name: "unique_name_index" },
|
|
43567
|
-
{ key: { school: 1 } },
|
|
43568
|
-
{ key: { status: 1 } }
|
|
43569
|
-
]);
|
|
43570
|
-
} catch (error) {
|
|
43571
|
-
throw new Error("Failed to create index on buildings.");
|
|
45090
|
+
next(error2);
|
|
43572
45091
|
}
|
|
43573
45092
|
}
|
|
43574
|
-
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
|
+
}
|
|
43575
45103
|
try {
|
|
43576
|
-
|
|
43577
|
-
|
|
43578
|
-
|
|
43579
|
-
|
|
43580
|
-
|
|
43581
|
-
logger40.log({
|
|
43582
|
-
level: "error",
|
|
43583
|
-
message: error.message
|
|
43584
|
-
});
|
|
43585
|
-
if (error instanceof AppError26) {
|
|
43586
|
-
throw error;
|
|
43587
|
-
} else {
|
|
43588
|
-
const isDuplicated = error.message.includes("duplicate");
|
|
43589
|
-
if (isDuplicated) {
|
|
43590
|
-
throw new BadRequestError68("Building already exists.");
|
|
43591
|
-
}
|
|
43592
|
-
throw new Error("Failed to create building.");
|
|
43593
|
-
}
|
|
45104
|
+
const message = await _deleteById(id);
|
|
45105
|
+
res.json(message);
|
|
45106
|
+
return;
|
|
45107
|
+
} catch (error2) {
|
|
45108
|
+
next(error2);
|
|
43594
45109
|
}
|
|
43595
45110
|
}
|
|
43596
|
-
|
|
43597
|
-
|
|
43598
|
-
|
|
43599
|
-
|
|
43600
|
-
|
|
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.");
|
|
43601
45132
|
}
|
|
43602
45133
|
try {
|
|
43603
|
-
|
|
43604
|
-
|
|
43605
|
-
|
|
43606
|
-
|
|
45134
|
+
await session.startTransaction();
|
|
45135
|
+
const existingCount = await countByBuilding(
|
|
45136
|
+
value.building.building,
|
|
45137
|
+
value.building.level
|
|
43607
45138
|
);
|
|
43608
|
-
|
|
43609
|
-
|
|
43610
|
-
|
|
43611
|
-
|
|
43612
|
-
|
|
43613
|
-
|
|
43614
|
-
});
|
|
43615
|
-
if (error instanceof AppError26) {
|
|
43616
|
-
throw error;
|
|
43617
|
-
} else {
|
|
43618
|
-
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
|
+
);
|
|
43619
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();
|
|
43620
45153
|
}
|
|
43621
45154
|
}
|
|
43622
|
-
|
|
43623
|
-
|
|
43624
|
-
|
|
43625
|
-
|
|
43626
|
-
sort = {},
|
|
43627
|
-
school = "",
|
|
43628
|
-
status = "active"
|
|
43629
|
-
} = {}) {
|
|
43630
|
-
page = page > 0 ? page - 1 : 0;
|
|
43631
|
-
const query = {
|
|
43632
|
-
status
|
|
43633
|
-
};
|
|
43634
|
-
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
43635
|
-
if (search) {
|
|
43636
|
-
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.");
|
|
43637
45159
|
}
|
|
43638
|
-
|
|
43639
|
-
|
|
43640
|
-
|
|
43641
|
-
|
|
43642
|
-
|
|
43643
|
-
}
|
|
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
|
+
);
|
|
43644
45165
|
}
|
|
43645
|
-
const cacheParams = {
|
|
43646
|
-
page,
|
|
43647
|
-
limit,
|
|
43648
|
-
sort: JSON.stringify(sort)
|
|
43649
|
-
};
|
|
43650
|
-
if (search)
|
|
43651
|
-
cacheParams.search = search;
|
|
43652
|
-
if (school)
|
|
43653
|
-
cacheParams.school = school;
|
|
43654
|
-
if (status !== "active")
|
|
43655
|
-
cacheParams.status = status;
|
|
43656
|
-
const cacheKey = makeCacheKey22(namespace_collection, cacheParams);
|
|
43657
|
-
logger40.log({
|
|
43658
|
-
level: "info",
|
|
43659
|
-
message: `Cache key for getAll buildings: ${cacheKey}`
|
|
43660
|
-
});
|
|
43661
45166
|
try {
|
|
43662
|
-
|
|
43663
|
-
|
|
43664
|
-
logger40.log({
|
|
43665
|
-
level: "info",
|
|
43666
|
-
message: `Cache hit for getAll buildings: ${cacheKey}`
|
|
43667
|
-
});
|
|
43668
|
-
return cached;
|
|
43669
|
-
}
|
|
43670
|
-
const items = await collection.aggregate([
|
|
43671
|
-
{ $match: query },
|
|
43672
|
-
{ $sort: sort },
|
|
43673
|
-
{ $skip: page * limit },
|
|
43674
|
-
{ $limit: limit }
|
|
43675
|
-
]).toArray();
|
|
43676
|
-
const length = await collection.countDocuments(query);
|
|
43677
|
-
const data = paginate21(items, page, limit, length);
|
|
43678
|
-
setCache(cacheKey, data, 600).then(() => {
|
|
43679
|
-
logger40.log({
|
|
43680
|
-
level: "info",
|
|
43681
|
-
message: `Cache set for getAll buildings: ${cacheKey}`
|
|
43682
|
-
});
|
|
43683
|
-
}).catch((err) => {
|
|
43684
|
-
logger40.log({
|
|
43685
|
-
level: "error",
|
|
43686
|
-
message: `Failed to set cache for getAll buildings: ${err.message}`
|
|
43687
|
-
});
|
|
43688
|
-
});
|
|
43689
|
-
return data;
|
|
45167
|
+
await _deleteById(id);
|
|
45168
|
+
return "Building unit deleted successfully.";
|
|
43690
45169
|
} catch (error) {
|
|
43691
|
-
|
|
43692
|
-
throw error;
|
|
45170
|
+
throw new Error("Failed to delete building unit.");
|
|
43693
45171
|
}
|
|
43694
45172
|
}
|
|
43695
|
-
|
|
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
|
+
}
|
|
43696
45214
|
try {
|
|
43697
|
-
|
|
43698
|
-
|
|
43699
|
-
|
|
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;
|
|
43700
45235
|
}
|
|
43701
|
-
const cacheKey = makeCacheKey22(namespace_collection, { _id: String(_id) });
|
|
43702
45236
|
try {
|
|
43703
|
-
const
|
|
43704
|
-
|
|
43705
|
-
|
|
43706
|
-
|
|
43707
|
-
message: `Cache hit for getById building: ${cacheKey}`
|
|
43708
|
-
});
|
|
43709
|
-
return cached;
|
|
43710
|
-
}
|
|
43711
|
-
const result = await collection.findOne({
|
|
43712
|
-
_id
|
|
45237
|
+
const buildingUnit = await _updateById(id, data);
|
|
45238
|
+
res.json({
|
|
45239
|
+
message: "Building unit updated successfully.",
|
|
45240
|
+
data: { buildingUnit }
|
|
43713
45241
|
});
|
|
43714
|
-
|
|
43715
|
-
|
|
43716
|
-
|
|
43717
|
-
|
|
43718
|
-
|
|
43719
|
-
|
|
43720
|
-
|
|
43721
|
-
|
|
43722
|
-
|
|
43723
|
-
|
|
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;
|
|
43724
45271
|
});
|
|
43725
|
-
|
|
43726
|
-
|
|
43727
|
-
|
|
43728
|
-
|
|
43729
|
-
|
|
43730
|
-
|
|
43731
|
-
|
|
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);
|
|
43732
45293
|
}
|
|
43733
45294
|
}
|
|
43734
|
-
async function
|
|
43735
|
-
|
|
43736
|
-
|
|
43737
|
-
|
|
43738
|
-
|
|
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;
|
|
43739
45304
|
}
|
|
43740
45305
|
try {
|
|
43741
|
-
const
|
|
43742
|
-
|
|
43743
|
-
|
|
43744
|
-
|
|
43745
|
-
delCachedData();
|
|
43746
|
-
return res;
|
|
43747
|
-
} catch (error) {
|
|
43748
|
-
logger40.log({
|
|
43749
|
-
level: "error",
|
|
43750
|
-
message: error.message
|
|
45306
|
+
const buildingUnit = await _getById(id);
|
|
45307
|
+
res.json({
|
|
45308
|
+
message: "Successfully retrieved building unit.",
|
|
45309
|
+
data: { buildingUnit }
|
|
43751
45310
|
});
|
|
43752
|
-
|
|
43753
|
-
|
|
43754
|
-
|
|
43755
|
-
throw new InternalServerError22("Failed to delete building.");
|
|
43756
|
-
}
|
|
45311
|
+
return;
|
|
45312
|
+
} catch (error2) {
|
|
45313
|
+
next(error2);
|
|
43757
45314
|
}
|
|
43758
45315
|
}
|
|
43759
|
-
function
|
|
43760
|
-
|
|
43761
|
-
|
|
43762
|
-
|
|
43763
|
-
message: `Cache namespace cleared for ${namespace_collection}`
|
|
43764
|
-
});
|
|
43765
|
-
}).catch((err) => {
|
|
43766
|
-
logger40.log({
|
|
43767
|
-
level: "error",
|
|
43768
|
-
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
43769
|
-
});
|
|
45316
|
+
async function deleteById(req, res, next) {
|
|
45317
|
+
const id = req.params.id;
|
|
45318
|
+
const validation = Joi49.object({
|
|
45319
|
+
id: Joi49.string().hex().required()
|
|
43770
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
|
+
}
|
|
43771
45333
|
}
|
|
43772
45334
|
return {
|
|
43773
|
-
createIndexes,
|
|
43774
45335
|
add,
|
|
43775
45336
|
getAll,
|
|
43776
45337
|
getById,
|
|
@@ -43779,66 +45340,97 @@ function useBuildingRepo() {
|
|
|
43779
45340
|
};
|
|
43780
45341
|
}
|
|
43781
45342
|
|
|
43782
|
-
// src/resources/
|
|
43783
|
-
import {
|
|
43784
|
-
|
|
43785
|
-
|
|
43786
|
-
|
|
43787
|
-
|
|
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
|
+
}
|
|
43788
45387
|
|
|
43789
|
-
// src/resources/
|
|
45388
|
+
// src/resources/kindergarten-domain/kindergarten.domain.repository.ts
|
|
43790
45389
|
import {
|
|
43791
|
-
AppError as
|
|
43792
|
-
BadRequestError as
|
|
43793
|
-
InternalServerError as
|
|
43794
|
-
logger as
|
|
43795
|
-
makeCacheKey as
|
|
43796
|
-
paginate as
|
|
43797
|
-
useAtlas as
|
|
43798
|
-
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
|
|
43799
45398
|
} from "@eeplatform/nodejs-utils";
|
|
43800
|
-
import { ObjectId as
|
|
43801
|
-
function
|
|
43802
|
-
const db =
|
|
45399
|
+
import { ObjectId as ObjectId47 } from "mongodb";
|
|
45400
|
+
function useKindergartenDomainRepo() {
|
|
45401
|
+
const db = useAtlas36.getDb();
|
|
43803
45402
|
if (!db) {
|
|
43804
45403
|
throw new Error("Unable to connect to server.");
|
|
43805
45404
|
}
|
|
43806
|
-
const namespace_collection = "deped.
|
|
45405
|
+
const namespace_collection = "deped.kindergarten.domains";
|
|
43807
45406
|
const collection = db.collection(namespace_collection);
|
|
43808
|
-
const { getCache, setCache, delNamespace } =
|
|
45407
|
+
const { getCache, setCache, delNamespace } = useCache25(namespace_collection);
|
|
43809
45408
|
async function createIndexes() {
|
|
43810
45409
|
try {
|
|
43811
45410
|
await collection.createIndexes([
|
|
43812
|
-
{
|
|
43813
|
-
key: { name: 1, building: 1, level: 1 },
|
|
43814
|
-
unique: true,
|
|
43815
|
-
name: "unique_name_index"
|
|
43816
|
-
},
|
|
45411
|
+
{ key: { title: 1 } },
|
|
43817
45412
|
{ key: { school: 1 } },
|
|
43818
|
-
{ key: { building: 1 } },
|
|
43819
|
-
{ key: { status: 1 } },
|
|
43820
45413
|
{ key: { createdAt: 1 } },
|
|
45414
|
+
{ key: { createdBy: 1 } },
|
|
45415
|
+
{ key: { title: "text" } },
|
|
43821
45416
|
{
|
|
43822
|
-
key: {
|
|
43823
|
-
|
|
43824
|
-
|
|
43825
|
-
category: "text",
|
|
43826
|
-
type: "text"
|
|
43827
|
-
}
|
|
45417
|
+
key: { title: 1, school: 1, status: 1 },
|
|
45418
|
+
unique: true,
|
|
45419
|
+
name: "unique_kindergarten_domain"
|
|
43828
45420
|
}
|
|
43829
45421
|
]);
|
|
43830
45422
|
} catch (error) {
|
|
43831
|
-
throw new Error("Failed to create index on
|
|
45423
|
+
throw new Error("Failed to create index on kindergarten domains.");
|
|
43832
45424
|
}
|
|
43833
45425
|
}
|
|
43834
45426
|
function delCachedData() {
|
|
43835
45427
|
delNamespace().then(() => {
|
|
43836
|
-
|
|
45428
|
+
logger44.log({
|
|
43837
45429
|
level: "info",
|
|
43838
45430
|
message: `Cache namespace cleared for ${namespace_collection}`
|
|
43839
45431
|
});
|
|
43840
45432
|
}).catch((err) => {
|
|
43841
|
-
|
|
45433
|
+
logger44.log({
|
|
43842
45434
|
level: "error",
|
|
43843
45435
|
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
43844
45436
|
});
|
|
@@ -43846,79 +45438,23 @@ function useBuildingUnitRepo() {
|
|
|
43846
45438
|
}
|
|
43847
45439
|
async function add(value, session) {
|
|
43848
45440
|
try {
|
|
43849
|
-
value =
|
|
45441
|
+
value = modelKindergartenDomain(value);
|
|
43850
45442
|
const res = await collection.insertOne(value, { session });
|
|
43851
45443
|
delCachedData();
|
|
43852
45444
|
return res.insertedId;
|
|
43853
45445
|
} catch (error) {
|
|
43854
|
-
|
|
45446
|
+
logger44.log({
|
|
43855
45447
|
level: "error",
|
|
43856
45448
|
message: error.message
|
|
43857
45449
|
});
|
|
43858
|
-
if (error instanceof
|
|
45450
|
+
if (error instanceof AppError29) {
|
|
43859
45451
|
throw error;
|
|
43860
45452
|
} else {
|
|
43861
|
-
|
|
43862
|
-
|
|
43863
|
-
|
|
43864
|
-
|
|
43865
|
-
|
|
43866
|
-
const { error } = schemaUpdateOptions.validate(value);
|
|
43867
|
-
if (error) {
|
|
43868
|
-
throw new BadRequestError69(error.message);
|
|
43869
|
-
}
|
|
43870
|
-
try {
|
|
43871
|
-
_id = new ObjectId43(_id);
|
|
43872
|
-
} catch (error2) {
|
|
43873
|
-
throw new BadRequestError69(namespace_collection + " Invalid ID.");
|
|
43874
|
-
}
|
|
43875
|
-
try {
|
|
43876
|
-
const res = await collection.updateOne(
|
|
43877
|
-
{ _id },
|
|
43878
|
-
{ $set: value },
|
|
43879
|
-
{ session }
|
|
43880
|
-
);
|
|
43881
|
-
delCachedData();
|
|
43882
|
-
return res;
|
|
43883
|
-
} catch (error2) {
|
|
43884
|
-
logger41.log({
|
|
43885
|
-
level: "error",
|
|
43886
|
-
message: error2.message
|
|
43887
|
-
});
|
|
43888
|
-
if (error2 instanceof AppError27) {
|
|
43889
|
-
throw error2;
|
|
43890
|
-
} else {
|
|
43891
|
-
throw new Error("Failed to create building unit.");
|
|
43892
|
-
}
|
|
43893
|
-
}
|
|
43894
|
-
}
|
|
43895
|
-
async function updateByBuildingId(building, value, session) {
|
|
43896
|
-
const { error } = schemaUpdateOptions.validate(value);
|
|
43897
|
-
if (error) {
|
|
43898
|
-
throw new BadRequestError69(error.message);
|
|
43899
|
-
}
|
|
43900
|
-
try {
|
|
43901
|
-
building = new ObjectId43(building);
|
|
43902
|
-
} catch (error2) {
|
|
43903
|
-
throw new BadRequestError69("Invalid building ID.");
|
|
43904
|
-
}
|
|
43905
|
-
try {
|
|
43906
|
-
const res = await collection.updateMany(
|
|
43907
|
-
{ building },
|
|
43908
|
-
{ $set: value },
|
|
43909
|
-
{ session }
|
|
43910
|
-
);
|
|
43911
|
-
delCachedData();
|
|
43912
|
-
return res;
|
|
43913
|
-
} catch (error2) {
|
|
43914
|
-
logger41.log({
|
|
43915
|
-
level: "error",
|
|
43916
|
-
message: error2.message
|
|
43917
|
-
});
|
|
43918
|
-
if (error2 instanceof AppError27) {
|
|
43919
|
-
throw error2;
|
|
43920
|
-
} else {
|
|
43921
|
-
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.");
|
|
43922
45458
|
}
|
|
43923
45459
|
}
|
|
43924
45460
|
}
|
|
@@ -43927,652 +45463,368 @@ function useBuildingUnitRepo() {
|
|
|
43927
45463
|
page = 1,
|
|
43928
45464
|
limit = 10,
|
|
43929
45465
|
sort = {},
|
|
43930
|
-
|
|
43931
|
-
|
|
43932
|
-
|
|
43933
|
-
status = "active"
|
|
45466
|
+
status = "active",
|
|
45467
|
+
createdBy,
|
|
45468
|
+
school = ""
|
|
43934
45469
|
} = {}) {
|
|
43935
45470
|
page = page > 0 ? page - 1 : 0;
|
|
43936
45471
|
const query = {
|
|
43937
|
-
deletedAt: { $in: ["", null] },
|
|
43938
|
-
status
|
|
43939
|
-
};
|
|
43940
|
-
const cacheParams = {
|
|
43941
|
-
page,
|
|
43942
|
-
limit,
|
|
43943
|
-
sort: JSON.stringify(sort)
|
|
43944
|
-
};
|
|
43945
|
-
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
43946
|
-
if (search) {
|
|
43947
|
-
query.$text = { $search: search };
|
|
43948
|
-
cacheParams.search = search;
|
|
43949
|
-
}
|
|
43950
|
-
if (school) {
|
|
43951
|
-
try {
|
|
43952
|
-
query.school = new ObjectId43(school);
|
|
43953
|
-
} catch (error) {
|
|
43954
|
-
throw new BadRequestError69("Invalid school ID.");
|
|
43955
|
-
}
|
|
43956
|
-
cacheParams.school = school;
|
|
43957
|
-
}
|
|
43958
|
-
if (building) {
|
|
43959
|
-
try {
|
|
43960
|
-
query.building = new ObjectId43(building);
|
|
43961
|
-
} catch (error) {
|
|
43962
|
-
throw new BadRequestError69("Invalid building ID.");
|
|
43963
|
-
}
|
|
43964
|
-
cacheParams.building = building;
|
|
43965
|
-
}
|
|
43966
|
-
if (type) {
|
|
43967
|
-
query.type = type;
|
|
43968
|
-
cacheParams.type = type;
|
|
43969
|
-
}
|
|
43970
|
-
const cacheKey = makeCacheKey23(namespace_collection, cacheParams);
|
|
43971
|
-
logger41.log({
|
|
43972
|
-
level: "info",
|
|
43973
|
-
message: `Cache key for getAll building units: ${cacheKey}`
|
|
43974
|
-
});
|
|
43975
|
-
try {
|
|
43976
|
-
const cached = await getCache(cacheKey);
|
|
43977
|
-
if (cached) {
|
|
43978
|
-
logger41.log({
|
|
43979
|
-
level: "info",
|
|
43980
|
-
message: `Cache hit for getAll building units: ${cacheKey}`
|
|
43981
|
-
});
|
|
43982
|
-
return cached;
|
|
43983
|
-
}
|
|
43984
|
-
const items = await collection.aggregate([
|
|
43985
|
-
{ $match: query },
|
|
43986
|
-
{ $sort: sort },
|
|
43987
|
-
{ $skip: page * limit },
|
|
43988
|
-
{ $limit: limit }
|
|
43989
|
-
]).toArray();
|
|
43990
|
-
const length = await collection.countDocuments(query);
|
|
43991
|
-
const data = paginate22(items, page, limit, length);
|
|
43992
|
-
setCache(cacheKey, data, 600).then(() => {
|
|
43993
|
-
logger41.log({
|
|
43994
|
-
level: "info",
|
|
43995
|
-
message: `Cache set for getAll building units: ${cacheKey}`
|
|
43996
|
-
});
|
|
43997
|
-
}).catch((err) => {
|
|
43998
|
-
logger41.log({
|
|
43999
|
-
level: "error",
|
|
44000
|
-
message: `Failed to set cache for getAll building units: ${err.message}`
|
|
44001
|
-
});
|
|
44002
|
-
});
|
|
44003
|
-
return data;
|
|
44004
|
-
} catch (error) {
|
|
44005
|
-
logger41.log({ level: "error", message: `${error}` });
|
|
44006
|
-
throw error;
|
|
44007
|
-
}
|
|
44008
|
-
}
|
|
44009
|
-
async function countByBuilding(building, level) {
|
|
44010
|
-
const query = {
|
|
44011
|
-
status: "active"
|
|
45472
|
+
deletedAt: { $in: ["", null] },
|
|
45473
|
+
status
|
|
44012
45474
|
};
|
|
45475
|
+
sort = Object.keys(sort).length > 0 ? sort : { _id: 1 };
|
|
44013
45476
|
const cacheKeyOptions = {
|
|
44014
|
-
|
|
44015
|
-
|
|
45477
|
+
status,
|
|
45478
|
+
page,
|
|
45479
|
+
limit,
|
|
45480
|
+
sort: JSON.stringify(sort)
|
|
44016
45481
|
};
|
|
44017
|
-
|
|
44018
|
-
|
|
44019
|
-
|
|
44020
|
-
|
|
44021
|
-
|
|
44022
|
-
|
|
44023
|
-
|
|
44024
|
-
query.level = level;
|
|
44025
|
-
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;
|
|
44026
45489
|
}
|
|
44027
|
-
|
|
44028
|
-
|
|
44029
|
-
|
|
44030
|
-
logger41.log({ level: "error", message: `${error}` });
|
|
44031
|
-
throw new InternalServerError23("Failed to count building units.");
|
|
45490
|
+
if (search) {
|
|
45491
|
+
query.$text = { $search: search };
|
|
45492
|
+
cacheKeyOptions.search = search;
|
|
44032
45493
|
}
|
|
44033
|
-
|
|
44034
|
-
|
|
44035
|
-
|
|
44036
|
-
|
|
44037
|
-
|
|
44038
|
-
|
|
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;
|
|
44039
45501
|
}
|
|
44040
|
-
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
|
+
});
|
|
44041
45507
|
try {
|
|
44042
45508
|
const cached = await getCache(cacheKey);
|
|
44043
45509
|
if (cached) {
|
|
44044
|
-
|
|
45510
|
+
logger44.log({
|
|
44045
45511
|
level: "info",
|
|
44046
|
-
message: `Cache hit for
|
|
45512
|
+
message: `Cache hit for getAll kindergarten domains: ${cacheKey}`
|
|
44047
45513
|
});
|
|
44048
45514
|
return cached;
|
|
44049
45515
|
}
|
|
44050
|
-
const
|
|
44051
|
-
|
|
44052
|
-
|
|
44053
|
-
|
|
44054
|
-
|
|
44055
|
-
|
|
44056
|
-
|
|
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);
|
|
44057
45524
|
setCache(cacheKey, result, 300).then(() => {
|
|
44058
|
-
|
|
45525
|
+
logger44.log({
|
|
44059
45526
|
level: "info",
|
|
44060
|
-
message: `Cache set for
|
|
45527
|
+
message: `Cache set for getAll kindergarten domains: ${cacheKey}`
|
|
44061
45528
|
});
|
|
44062
45529
|
}).catch((err) => {
|
|
44063
|
-
|
|
45530
|
+
logger44.log({
|
|
44064
45531
|
level: "error",
|
|
44065
|
-
message: `Failed to set cache for
|
|
45532
|
+
message: `Failed to set cache for getAll kindergarten domains: ${err.message}`
|
|
44066
45533
|
});
|
|
44067
45534
|
});
|
|
44068
45535
|
return result;
|
|
44069
45536
|
} catch (error) {
|
|
44070
|
-
if (error instanceof
|
|
45537
|
+
if (error instanceof AppError29) {
|
|
44071
45538
|
throw error;
|
|
44072
45539
|
} else {
|
|
44073
|
-
throw new
|
|
45540
|
+
throw new InternalServerError25("Failed to get kindergarten domains.");
|
|
44074
45541
|
}
|
|
44075
45542
|
}
|
|
44076
45543
|
}
|
|
44077
|
-
async function
|
|
45544
|
+
async function getById(_id) {
|
|
44078
45545
|
try {
|
|
44079
|
-
|
|
45546
|
+
_id = new ObjectId47(_id);
|
|
44080
45547
|
} catch (error) {
|
|
44081
|
-
throw new
|
|
45548
|
+
throw new BadRequestError77(namespace_collection + " Invalid ID.");
|
|
44082
45549
|
}
|
|
44083
|
-
const cacheKey =
|
|
44084
|
-
|
|
44085
|
-
|
|
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}`
|
|
44086
45556
|
});
|
|
44087
45557
|
try {
|
|
44088
45558
|
const cached = await getCache(cacheKey);
|
|
44089
45559
|
if (cached) {
|
|
44090
|
-
|
|
45560
|
+
logger44.log({
|
|
44091
45561
|
level: "info",
|
|
44092
|
-
message: `Cache hit for getById
|
|
45562
|
+
message: `Cache hit for getById kindergarten domain: ${cacheKey}`
|
|
44093
45563
|
});
|
|
44094
45564
|
return cached;
|
|
44095
45565
|
}
|
|
44096
45566
|
const result = await collection.findOne({
|
|
44097
|
-
|
|
44098
|
-
|
|
44099
|
-
status: "active"
|
|
45567
|
+
_id,
|
|
45568
|
+
deletedAt: { $in: ["", null] }
|
|
44100
45569
|
});
|
|
45570
|
+
if (!result) {
|
|
45571
|
+
throw new BadRequestError77("Kindergarten domain not found.");
|
|
45572
|
+
}
|
|
44101
45573
|
setCache(cacheKey, result, 300).then(() => {
|
|
44102
|
-
|
|
45574
|
+
logger44.log({
|
|
44103
45575
|
level: "info",
|
|
44104
|
-
message: `Cache set for
|
|
45576
|
+
message: `Cache set for getById kindergarten domain: ${cacheKey}`
|
|
44105
45577
|
});
|
|
44106
45578
|
}).catch((err) => {
|
|
44107
|
-
|
|
45579
|
+
logger44.log({
|
|
44108
45580
|
level: "error",
|
|
44109
|
-
message: `Failed to set cache for
|
|
45581
|
+
message: `Failed to set cache for getById kindergarten domain: ${err.message}`
|
|
44110
45582
|
});
|
|
44111
45583
|
});
|
|
44112
45584
|
return result;
|
|
44113
45585
|
} catch (error) {
|
|
44114
|
-
if (error instanceof
|
|
45586
|
+
if (error instanceof AppError29) {
|
|
44115
45587
|
throw error;
|
|
44116
45588
|
} else {
|
|
44117
|
-
throw new
|
|
45589
|
+
throw new InternalServerError25("Failed to get kindergarten domain.");
|
|
44118
45590
|
}
|
|
44119
45591
|
}
|
|
44120
45592
|
}
|
|
44121
|
-
async function
|
|
45593
|
+
async function getBySchool(school) {
|
|
44122
45594
|
try {
|
|
44123
|
-
|
|
45595
|
+
school = new ObjectId47(school);
|
|
44124
45596
|
} catch (error) {
|
|
44125
|
-
throw new
|
|
45597
|
+
throw new BadRequestError77("Invalid school ID.");
|
|
44126
45598
|
}
|
|
44127
|
-
const cacheKey =
|
|
44128
|
-
|
|
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}`
|
|
44129
45605
|
});
|
|
44130
45606
|
try {
|
|
44131
45607
|
const cached = await getCache(cacheKey);
|
|
44132
45608
|
if (cached) {
|
|
44133
|
-
|
|
45609
|
+
logger44.log({
|
|
44134
45610
|
level: "info",
|
|
44135
|
-
message: `Cache hit for
|
|
45611
|
+
message: `Cache hit for kindergarten domain by school: ${cacheKey}`
|
|
44136
45612
|
});
|
|
44137
45613
|
return cached;
|
|
44138
45614
|
}
|
|
44139
|
-
const result = await collection.
|
|
44140
|
-
|
|
44141
|
-
|
|
44142
|
-
});
|
|
45615
|
+
const result = await collection.find({
|
|
45616
|
+
school,
|
|
45617
|
+
deletedAt: { $in: ["", null] }
|
|
45618
|
+
}).toArray();
|
|
44143
45619
|
setCache(cacheKey, result, 300).then(() => {
|
|
44144
|
-
|
|
45620
|
+
logger44.log({
|
|
44145
45621
|
level: "info",
|
|
44146
|
-
message: `Cache set for
|
|
45622
|
+
message: `Cache set for kindergarten domain by school: ${cacheKey}`
|
|
44147
45623
|
});
|
|
44148
45624
|
}).catch((err) => {
|
|
44149
|
-
|
|
45625
|
+
logger44.log({
|
|
44150
45626
|
level: "error",
|
|
44151
|
-
message: `Failed to set cache for
|
|
45627
|
+
message: `Failed to set cache for kindergarten domain by school: ${err.message}`
|
|
44152
45628
|
});
|
|
44153
45629
|
});
|
|
44154
45630
|
return result;
|
|
44155
45631
|
} catch (error) {
|
|
44156
|
-
if (error instanceof
|
|
44157
|
-
throw error;
|
|
44158
|
-
} else {
|
|
44159
|
-
throw new InternalServerError23("Failed to get building unit.");
|
|
44160
|
-
}
|
|
44161
|
-
}
|
|
44162
|
-
}
|
|
44163
|
-
async function deleteById(_id, session) {
|
|
44164
|
-
try {
|
|
44165
|
-
_id = new ObjectId43(_id);
|
|
44166
|
-
} catch (error) {
|
|
44167
|
-
throw new BadRequestError69(namespace_collection + " Invalid ID.");
|
|
44168
|
-
}
|
|
44169
|
-
try {
|
|
44170
|
-
const res = await collection.updateOne(
|
|
44171
|
-
{ _id },
|
|
44172
|
-
{ $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } },
|
|
44173
|
-
{ session }
|
|
44174
|
-
);
|
|
44175
|
-
delCachedData();
|
|
44176
|
-
return "Room/Facility deleted successfully.";
|
|
44177
|
-
} catch (error) {
|
|
44178
|
-
logger41.log({
|
|
44179
|
-
level: "error",
|
|
44180
|
-
message: error.message
|
|
44181
|
-
});
|
|
44182
|
-
if (error instanceof AppError27) {
|
|
45632
|
+
if (error instanceof AppError29) {
|
|
44183
45633
|
throw error;
|
|
44184
45634
|
} else {
|
|
44185
|
-
throw new
|
|
44186
|
-
}
|
|
44187
|
-
}
|
|
44188
|
-
}
|
|
44189
|
-
|
|
44190
|
-
|
|
44191
|
-
|
|
44192
|
-
|
|
44193
|
-
|
|
44194
|
-
|
|
44195
|
-
updateById,
|
|
44196
|
-
getByBuilding,
|
|
44197
|
-
deleteById,
|
|
44198
|
-
updateByBuildingId,
|
|
44199
|
-
countByBuilding
|
|
44200
|
-
};
|
|
44201
|
-
}
|
|
44202
|
-
|
|
44203
|
-
// src/resources/building/building.service.ts
|
|
44204
|
-
function useBuildingService() {
|
|
44205
|
-
const {
|
|
44206
|
-
updateById: _updateById,
|
|
44207
|
-
getById: _getById,
|
|
44208
|
-
deleteById: _deleteById
|
|
44209
|
-
} = useBuildingRepo();
|
|
44210
|
-
const { getByBuildingLevel, getByBuilding, updateByBuildingId } = useBuildingUnitRepo();
|
|
44211
|
-
async function updateById(id, data) {
|
|
44212
|
-
data.levels = Number(data.levels);
|
|
44213
|
-
const session = useAtlas33.getClient()?.startSession();
|
|
44214
|
-
try {
|
|
44215
|
-
const building = await _getById(id);
|
|
44216
|
-
if (!building) {
|
|
44217
|
-
throw new NotFoundError3("Building not found.");
|
|
44218
|
-
}
|
|
44219
|
-
if (data.levels < building.levels) {
|
|
44220
|
-
const unit = await getByBuildingLevel(id, building.levels);
|
|
44221
|
-
if (unit) {
|
|
44222
|
-
throw new BadRequestError70(
|
|
44223
|
-
"Cannot reduce floors, there are existing building units at higher floors."
|
|
44224
|
-
);
|
|
44225
|
-
}
|
|
44226
|
-
}
|
|
44227
|
-
session?.startTransaction();
|
|
44228
|
-
if (building.name !== data.name) {
|
|
44229
|
-
await updateByBuildingId(id, { buildingName: data.name }, session);
|
|
44230
|
-
}
|
|
44231
|
-
const result = await _updateById(id, data, session);
|
|
44232
|
-
await session?.commitTransaction();
|
|
44233
|
-
return result;
|
|
44234
|
-
} catch (error) {
|
|
44235
|
-
await session?.abortTransaction();
|
|
44236
|
-
throw error;
|
|
44237
|
-
} finally {
|
|
44238
|
-
session?.endSession();
|
|
44239
|
-
}
|
|
44240
|
-
}
|
|
44241
|
-
async function deleteById(id) {
|
|
44242
|
-
const building = await getByBuilding(id);
|
|
44243
|
-
if (building) {
|
|
44244
|
-
throw new BadRequestError70(
|
|
44245
|
-
"Cannot delete building with existing room/facility. Please delete room/facility first."
|
|
44246
|
-
);
|
|
44247
|
-
}
|
|
44248
|
-
try {
|
|
44249
|
-
await _deleteById(id);
|
|
44250
|
-
return "Building deleted successfully.";
|
|
44251
|
-
} catch (error) {
|
|
44252
|
-
throw error;
|
|
44253
|
-
}
|
|
44254
|
-
}
|
|
44255
|
-
return {
|
|
44256
|
-
updateById,
|
|
44257
|
-
deleteById
|
|
44258
|
-
};
|
|
44259
|
-
}
|
|
44260
|
-
|
|
44261
|
-
// src/resources/building/building.controller.ts
|
|
44262
|
-
import { BadRequestError as BadRequestError71, logger as logger42 } from "@eeplatform/nodejs-utils";
|
|
44263
|
-
import Joi46 from "joi";
|
|
44264
|
-
function useBuildingController() {
|
|
44265
|
-
const { getAll: _getAll, getById: _getById, add: _add } = useBuildingRepo();
|
|
44266
|
-
const { updateById: _updateById, deleteById: _deleteById } = useBuildingService();
|
|
44267
|
-
async function createBuilding(req, res, next) {
|
|
44268
|
-
const value = req.body;
|
|
44269
|
-
const validation = Joi46.object({
|
|
44270
|
-
name: Joi46.string().required(),
|
|
44271
|
-
school: Joi46.string().hex().required(),
|
|
44272
|
-
levels: Joi46.number().integer().min(1).required(),
|
|
44273
|
-
serial: Joi46.string().optional().allow("", null),
|
|
44274
|
-
status: Joi46.string().optional().allow("", null)
|
|
44275
|
-
});
|
|
44276
|
-
const { error } = validation.validate(value);
|
|
44277
|
-
if (error) {
|
|
44278
|
-
next(new BadRequestError71(error.message));
|
|
44279
|
-
logger42.info(`Controller: ${error.message}`);
|
|
44280
|
-
return;
|
|
44281
|
-
}
|
|
44282
|
-
try {
|
|
44283
|
-
const result = await _add(value);
|
|
44284
|
-
res.json(result);
|
|
44285
|
-
return;
|
|
44286
|
-
} catch (error2) {
|
|
44287
|
-
next(error2);
|
|
44288
|
-
}
|
|
44289
|
-
}
|
|
44290
|
-
async function updateById(req, res, next) {
|
|
44291
|
-
const value = req.body;
|
|
44292
|
-
const id = req.params.id ?? "";
|
|
44293
|
-
const validation = Joi46.object({
|
|
44294
|
-
id: Joi46.string().hex().required(),
|
|
44295
|
-
value: Joi46.object({
|
|
44296
|
-
name: Joi46.string().required(),
|
|
44297
|
-
serial: Joi46.string().optional().allow("", null),
|
|
44298
|
-
levels: Joi46.number().integer().min(1).required()
|
|
44299
|
-
})
|
|
44300
|
-
});
|
|
44301
|
-
const { error } = validation.validate({ id, value });
|
|
44302
|
-
if (error) {
|
|
44303
|
-
next(new BadRequestError71(error.message));
|
|
44304
|
-
logger42.info(`Controller: ${error.message}`);
|
|
44305
|
-
return;
|
|
44306
|
-
}
|
|
44307
|
-
try {
|
|
44308
|
-
const result = await _updateById(id, value);
|
|
44309
|
-
res.json(result);
|
|
44310
|
-
return;
|
|
44311
|
-
} catch (error2) {
|
|
44312
|
-
next(error2);
|
|
44313
|
-
}
|
|
44314
|
-
}
|
|
44315
|
-
async function getAll(req, res, next) {
|
|
44316
|
-
const query = req.query;
|
|
44317
|
-
const validation = Joi46.object({
|
|
44318
|
-
page: Joi46.number().min(1).optional().allow("", null),
|
|
44319
|
-
limit: Joi46.number().min(1).optional().allow("", null),
|
|
44320
|
-
search: Joi46.string().optional().allow("", null),
|
|
44321
|
-
school: Joi46.string().hex().optional().allow("", null),
|
|
44322
|
-
status: Joi46.string().optional().allow("", null)
|
|
44323
|
-
});
|
|
44324
|
-
const { error } = validation.validate(query);
|
|
44325
|
-
if (error) {
|
|
44326
|
-
next(new BadRequestError71(error.message));
|
|
44327
|
-
return;
|
|
44328
|
-
}
|
|
44329
|
-
const page = parseInt(req.query.page) ?? 1;
|
|
44330
|
-
let limit = parseInt(req.query.limit) ?? 20;
|
|
44331
|
-
limit = isNaN(limit) ? 20 : limit;
|
|
44332
|
-
const sort = req.query.sort ? String(req.query.sort).split(",") : "";
|
|
44333
|
-
const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
|
|
44334
|
-
const sortObj = {};
|
|
44335
|
-
if (sort && Array.isArray(sort) && sort.length && sortOrder && Array.isArray(sortOrder) && sortOrder.length) {
|
|
44336
|
-
sort.forEach((field, index) => {
|
|
44337
|
-
sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
|
|
44338
|
-
});
|
|
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
|
+
);
|
|
44339
45645
|
}
|
|
44340
|
-
const status = req.query.status ?? "active";
|
|
44341
|
-
const school = req.query.school ?? "";
|
|
44342
|
-
const search = req.query.search ?? "";
|
|
44343
45646
|
try {
|
|
44344
|
-
|
|
44345
|
-
|
|
44346
|
-
|
|
44347
|
-
|
|
44348
|
-
|
|
44349
|
-
|
|
44350
|
-
|
|
44351
|
-
|
|
44352
|
-
|
|
44353
|
-
|
|
44354
|
-
|
|
44355
|
-
|
|
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
|
+
);
|
|
44356
45663
|
}
|
|
44357
45664
|
}
|
|
44358
|
-
async function
|
|
44359
|
-
const
|
|
44360
|
-
const validation = Joi46.object({
|
|
44361
|
-
id: Joi46.string().hex().required()
|
|
44362
|
-
});
|
|
44363
|
-
const { error } = validation.validate({ id });
|
|
45665
|
+
async function updateById(_id, value, session) {
|
|
45666
|
+
const { error } = schemaKindergartenDomain.validate(value);
|
|
44364
45667
|
if (error) {
|
|
44365
|
-
|
|
44366
|
-
|
|
45668
|
+
throw new BadRequestError77(
|
|
45669
|
+
`Invalid kindergarten domain data: ${error.message}`
|
|
45670
|
+
);
|
|
44367
45671
|
}
|
|
44368
45672
|
try {
|
|
44369
|
-
|
|
44370
|
-
res.json({
|
|
44371
|
-
message: "Successfully retrieved building.",
|
|
44372
|
-
data: { building }
|
|
44373
|
-
});
|
|
44374
|
-
return;
|
|
45673
|
+
_id = new ObjectId47(_id);
|
|
44375
45674
|
} catch (error2) {
|
|
44376
|
-
|
|
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.");
|
|
44377
45687
|
}
|
|
44378
45688
|
}
|
|
44379
|
-
async function deleteById(
|
|
44380
|
-
|
|
44381
|
-
|
|
44382
|
-
|
|
44383
|
-
|
|
44384
|
-
const { error } = validation.validate({ id });
|
|
44385
|
-
if (error) {
|
|
44386
|
-
next(new BadRequestError71(error.message));
|
|
44387
|
-
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.");
|
|
44388
45694
|
}
|
|
44389
45695
|
try {
|
|
44390
|
-
|
|
44391
|
-
|
|
44392
|
-
|
|
44393
|
-
|
|
44394
|
-
|
|
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.");
|
|
44395
45705
|
}
|
|
44396
45706
|
}
|
|
44397
45707
|
return {
|
|
44398
|
-
|
|
45708
|
+
createIndexes,
|
|
45709
|
+
add,
|
|
44399
45710
|
getAll,
|
|
44400
45711
|
getById,
|
|
45712
|
+
getBySchool,
|
|
45713
|
+
updateFieldById,
|
|
44401
45714
|
updateById,
|
|
44402
45715
|
deleteById
|
|
44403
45716
|
};
|
|
44404
45717
|
}
|
|
44405
45718
|
|
|
44406
|
-
// src/resources/
|
|
44407
|
-
import { useAtlas as
|
|
44408
|
-
function
|
|
44409
|
-
const {
|
|
44410
|
-
|
|
44411
|
-
|
|
44412
|
-
|
|
44413
|
-
} = useBuildingUnitRepo();
|
|
44414
|
-
async function add(value) {
|
|
44415
|
-
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();
|
|
44416
45726
|
if (!session) {
|
|
44417
|
-
throw new Error("
|
|
45727
|
+
throw new Error("Failed to start database session.");
|
|
44418
45728
|
}
|
|
44419
45729
|
try {
|
|
44420
|
-
|
|
44421
|
-
const
|
|
44422
|
-
|
|
44423
|
-
|
|
44424
|
-
|
|
44425
|
-
|
|
44426
|
-
|
|
44427
|
-
|
|
44428
|
-
|
|
44429
|
-
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."
|
|
44430
45739
|
);
|
|
44431
45740
|
}
|
|
44432
|
-
await session
|
|
44433
|
-
return "Building unit added successfully.";
|
|
45741
|
+
await _deleteById(id, session);
|
|
44434
45742
|
} catch (error) {
|
|
44435
45743
|
await session.abortTransaction();
|
|
44436
|
-
|
|
45744
|
+
if (error instanceof AppError30) {
|
|
45745
|
+
throw error;
|
|
45746
|
+
} else {
|
|
45747
|
+
throw new AppError30("Failed to delete kindergarten domain.", 500);
|
|
45748
|
+
}
|
|
44437
45749
|
} finally {
|
|
44438
|
-
session.endSession();
|
|
44439
|
-
}
|
|
44440
|
-
}
|
|
44441
|
-
const { getById: getSectionSubjectByClassroom } = useSectionSubjectRepo();
|
|
44442
|
-
async function deleteById(id) {
|
|
44443
|
-
if (!id) {
|
|
44444
|
-
throw new Error("Invalid building unit ID.");
|
|
44445
|
-
}
|
|
44446
|
-
const sectionSubject = await getSectionSubjectByClassroom(id);
|
|
44447
|
-
if (sectionSubject) {
|
|
44448
|
-
throw new Error(
|
|
44449
|
-
"Cannot delete building unit as it is assigned to a section subject."
|
|
44450
|
-
);
|
|
44451
|
-
}
|
|
44452
|
-
try {
|
|
44453
|
-
await _deleteById(id);
|
|
44454
|
-
return "Building unit deleted successfully.";
|
|
44455
|
-
} catch (error) {
|
|
44456
|
-
throw new Error("Failed to delete building unit.");
|
|
45750
|
+
await session.endSession();
|
|
44457
45751
|
}
|
|
44458
45752
|
}
|
|
44459
45753
|
return {
|
|
44460
|
-
add,
|
|
44461
45754
|
deleteById
|
|
44462
45755
|
};
|
|
44463
45756
|
}
|
|
44464
45757
|
|
|
44465
|
-
// src/resources/
|
|
44466
|
-
import { BadRequestError as
|
|
44467
|
-
import
|
|
44468
|
-
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() {
|
|
44469
45762
|
const {
|
|
45763
|
+
add: _add,
|
|
44470
45764
|
getAll: _getAll,
|
|
44471
45765
|
getById: _getById,
|
|
44472
|
-
|
|
44473
|
-
|
|
44474
|
-
|
|
45766
|
+
getBySchool: _getBySchool,
|
|
45767
|
+
updateFieldById: _updateFieldById
|
|
45768
|
+
} = useKindergartenDomainRepo();
|
|
44475
45769
|
async function add(req, res, next) {
|
|
44476
|
-
const
|
|
44477
|
-
const
|
|
44478
|
-
building: Joi47.object({
|
|
44479
|
-
school: Joi47.string().hex().required(),
|
|
44480
|
-
name: Joi47.string().optional().allow("", null),
|
|
44481
|
-
building: Joi47.string().hex().required(),
|
|
44482
|
-
buildingName: Joi47.string().optional().allow("", null),
|
|
44483
|
-
level: Joi47.number().integer().min(1).required(),
|
|
44484
|
-
category: Joi47.string().required(),
|
|
44485
|
-
type: Joi47.string().required(),
|
|
44486
|
-
seating_capacity: Joi47.number().integer().min(0).required(),
|
|
44487
|
-
standing_capacity: Joi47.number().integer().min(0).required(),
|
|
44488
|
-
description: Joi47.string().optional().allow("", null),
|
|
44489
|
-
unit_of_measurement: Joi47.string().valid("sqm").required(),
|
|
44490
|
-
area: Joi47.number().positive().required(),
|
|
44491
|
-
status: Joi47.string().optional().allow("", null)
|
|
44492
|
-
}),
|
|
44493
|
-
qty: Joi47.number().integer().min(1).max(20).optional().default(1)
|
|
44494
|
-
});
|
|
44495
|
-
const { error } = validation.validate(data);
|
|
45770
|
+
const value = req.body;
|
|
45771
|
+
const { error } = schemaKindergartenDomain.validate(value);
|
|
44496
45772
|
if (error) {
|
|
44497
|
-
next(new
|
|
45773
|
+
next(new BadRequestError79(error.message));
|
|
44498
45774
|
return;
|
|
44499
45775
|
}
|
|
44500
45776
|
try {
|
|
44501
|
-
const
|
|
45777
|
+
const data = await _add(value);
|
|
44502
45778
|
res.json({
|
|
44503
|
-
message: "
|
|
44504
|
-
data
|
|
45779
|
+
message: "Successfully created kindergarten domain.",
|
|
45780
|
+
data
|
|
44505
45781
|
});
|
|
44506
|
-
} catch (error2) {
|
|
44507
|
-
next(error2);
|
|
44508
|
-
}
|
|
44509
|
-
}
|
|
44510
|
-
async function updateById(req, res, next) {
|
|
44511
|
-
const data = req.body;
|
|
44512
|
-
const id = req.params.id ?? "";
|
|
44513
|
-
const validation = Joi47.object({
|
|
44514
|
-
id: Joi47.string().hex().required(),
|
|
44515
|
-
value: schemaUpdateOptions
|
|
44516
|
-
});
|
|
44517
|
-
const { error } = validation.validate({ id, value: data });
|
|
44518
|
-
if (error) {
|
|
44519
|
-
next(new BadRequestError72(error.message));
|
|
44520
45782
|
return;
|
|
44521
|
-
}
|
|
44522
|
-
try {
|
|
44523
|
-
const buildingUnit = await _updateById(id, data);
|
|
44524
|
-
res.json({
|
|
44525
|
-
message: "Building unit updated successfully.",
|
|
44526
|
-
data: { buildingUnit }
|
|
44527
|
-
});
|
|
44528
45783
|
} catch (error2) {
|
|
44529
45784
|
next(error2);
|
|
44530
45785
|
}
|
|
44531
45786
|
}
|
|
44532
45787
|
async function getAll(req, res, next) {
|
|
44533
45788
|
const query = req.query;
|
|
44534
|
-
const validation =
|
|
44535
|
-
page:
|
|
44536
|
-
limit:
|
|
44537
|
-
search:
|
|
44538
|
-
|
|
44539
|
-
|
|
44540
|
-
|
|
44541
|
-
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)
|
|
44542
45796
|
});
|
|
44543
45797
|
const { error } = validation.validate(query);
|
|
44544
|
-
|
|
44545
|
-
|
|
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."));
|
|
44546
45807
|
return;
|
|
44547
45808
|
}
|
|
44548
|
-
const
|
|
44549
|
-
|
|
44550
|
-
|
|
44551
|
-
|
|
44552
|
-
|
|
44553
|
-
|
|
44554
|
-
|
|
44555
|
-
|
|
44556
|
-
sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
|
|
44557
|
-
});
|
|
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;
|
|
44558
45817
|
}
|
|
44559
|
-
const status = req.query.status ?? "active";
|
|
44560
|
-
const school = req.query.school ?? "";
|
|
44561
|
-
const building = req.query.building ?? "";
|
|
44562
|
-
const search = req.query.search ?? "";
|
|
44563
|
-
const type = req.query.type ?? "";
|
|
44564
45818
|
try {
|
|
44565
|
-
const
|
|
45819
|
+
const data = await _getAll({
|
|
44566
45820
|
page,
|
|
44567
45821
|
limit,
|
|
44568
|
-
|
|
45822
|
+
search,
|
|
44569
45823
|
status,
|
|
44570
45824
|
school,
|
|
44571
|
-
|
|
44572
|
-
building,
|
|
44573
|
-
type
|
|
45825
|
+
createdBy: createdBy || void 0
|
|
44574
45826
|
});
|
|
44575
|
-
res.json(
|
|
45827
|
+
res.json(data);
|
|
44576
45828
|
return;
|
|
44577
45829
|
} catch (error2) {
|
|
44578
45830
|
next(error2);
|
|
@@ -44580,37 +45832,80 @@ function useBuildingUnitController() {
|
|
|
44580
45832
|
}
|
|
44581
45833
|
async function getById(req, res, next) {
|
|
44582
45834
|
const id = req.params.id;
|
|
44583
|
-
const validation =
|
|
44584
|
-
id:
|
|
45835
|
+
const validation = Joi51.object({
|
|
45836
|
+
id: Joi51.string().hex().required()
|
|
44585
45837
|
});
|
|
44586
45838
|
const { error } = validation.validate({ id });
|
|
44587
45839
|
if (error) {
|
|
44588
|
-
next(new
|
|
45840
|
+
next(new BadRequestError79(error.message));
|
|
44589
45841
|
return;
|
|
44590
45842
|
}
|
|
44591
45843
|
try {
|
|
44592
|
-
const
|
|
45844
|
+
const data = await _getById(id);
|
|
44593
45845
|
res.json({
|
|
44594
|
-
message: "Successfully retrieved
|
|
44595
|
-
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
|
|
44596
45869
|
});
|
|
44597
45870
|
return;
|
|
44598
45871
|
} catch (error2) {
|
|
44599
45872
|
next(error2);
|
|
44600
45873
|
}
|
|
44601
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();
|
|
44602
45897
|
async function deleteById(req, res, next) {
|
|
44603
|
-
const
|
|
44604
|
-
const validation =
|
|
44605
|
-
|
|
45898
|
+
const _id = req.params.id;
|
|
45899
|
+
const validation = Joi51.object({
|
|
45900
|
+
_id: Joi51.string().hex().required()
|
|
44606
45901
|
});
|
|
44607
|
-
const { error } = validation.validate({
|
|
45902
|
+
const { error } = validation.validate({ _id });
|
|
44608
45903
|
if (error) {
|
|
44609
|
-
next(new
|
|
45904
|
+
next(new BadRequestError79(error.message));
|
|
44610
45905
|
return;
|
|
44611
45906
|
}
|
|
44612
45907
|
try {
|
|
44613
|
-
const message = await _deleteById(
|
|
45908
|
+
const message = await _deleteById(_id);
|
|
44614
45909
|
res.json({ message });
|
|
44615
45910
|
return;
|
|
44616
45911
|
} catch (error2) {
|
|
@@ -44621,7 +45916,8 @@ function useBuildingUnitController() {
|
|
|
44621
45916
|
add,
|
|
44622
45917
|
getAll,
|
|
44623
45918
|
getById,
|
|
44624
|
-
|
|
45919
|
+
getBySchool,
|
|
45920
|
+
updateField,
|
|
44625
45921
|
deleteById
|
|
44626
45922
|
};
|
|
44627
45923
|
}
|
|
@@ -44642,6 +45938,8 @@ export {
|
|
|
44642
45938
|
allowedSectionStudentStatuses,
|
|
44643
45939
|
modelBasicEduCount,
|
|
44644
45940
|
modelDivision,
|
|
45941
|
+
modelKindergartenDomain,
|
|
45942
|
+
modelKindergartenRoutine,
|
|
44645
45943
|
modelProgram,
|
|
44646
45944
|
modelProgramScreening,
|
|
44647
45945
|
modelRegion,
|
|
@@ -44664,6 +45962,9 @@ export {
|
|
|
44664
45962
|
schemaEnrollment,
|
|
44665
45963
|
schemaGenerateSections,
|
|
44666
45964
|
schemaGradeLevel,
|
|
45965
|
+
schemaKindergartenDomain,
|
|
45966
|
+
schemaKindergartenRoutine,
|
|
45967
|
+
schemaKindergartenRoutineUpdate,
|
|
44667
45968
|
schemaPersonnel,
|
|
44668
45969
|
schemaPlantilla,
|
|
44669
45970
|
schemaProgram,
|
|
@@ -44705,6 +46006,11 @@ export {
|
|
|
44705
46006
|
useEnrollmentService,
|
|
44706
46007
|
useGradeLevelController,
|
|
44707
46008
|
useGradeLevelRepo,
|
|
46009
|
+
useKindergartenDomainController,
|
|
46010
|
+
useKindergartenDomainRepo,
|
|
46011
|
+
useKindergartenDomainService,
|
|
46012
|
+
useKindergartenRoutineController,
|
|
46013
|
+
useKindergartenRoutineRepo,
|
|
44708
46014
|
useLearnerController,
|
|
44709
46015
|
useLearnerRepo,
|
|
44710
46016
|
usePersonnelController,
|