@eeplatform/basic-edu 1.10.0 → 1.10.2

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