@eeplatform/core 1.4.5 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -10384,7 +10384,7 @@ var require_ms = __commonJS({
10384
10384
  options = options || {};
10385
10385
  var type = typeof val;
10386
10386
  if (type === "string" && val.length > 0) {
10387
- return parse3(val);
10387
+ return parse4(val);
10388
10388
  } else if (type === "number" && isNaN(val) === false) {
10389
10389
  return options.long ? fmtLong(val) : fmtShort(val);
10390
10390
  }
@@ -10392,7 +10392,7 @@ var require_ms = __commonJS({
10392
10392
  "val is not a non-empty string or a valid number. val=" + JSON.stringify(val)
10393
10393
  );
10394
10394
  };
10395
- function parse3(str) {
10395
+ function parse4(str) {
10396
10396
  str = String(str);
10397
10397
  if (str.length > 100) {
10398
10398
  return;
@@ -11345,12 +11345,14 @@ __export(src_exports, {
11345
11345
  MAsset: () => MAsset,
11346
11346
  MBuilding: () => MBuilding,
11347
11347
  MBuildingUnit: () => MBuildingUnit,
11348
+ MCurriculum: () => MCurriculum,
11348
11349
  MDivision: () => MDivision,
11349
11350
  MEntity: () => MEntity,
11350
11351
  MFile: () => MFile,
11351
11352
  MMember: () => MMember,
11352
11353
  MONGO_DB: () => MONGO_DB,
11353
11354
  MONGO_URI: () => MONGO_URI,
11355
+ MOffice: () => MOffice,
11354
11356
  MOrder: () => MOrder,
11355
11357
  MOrg: () => MOrg,
11356
11358
  MPaymentMethod: () => MPaymentMethod,
@@ -11391,7 +11393,9 @@ __export(src_exports, {
11391
11393
  schemaAssetUpdateOption: () => schemaAssetUpdateOption,
11392
11394
  schemaBuilding: () => schemaBuilding,
11393
11395
  schemaBuildingUnit: () => schemaBuildingUnit,
11396
+ schemaCurriculum: () => schemaCurriculum,
11394
11397
  schemaDivision: () => schemaDivision,
11398
+ schemaOffice: () => schemaOffice,
11395
11399
  schemaPlantilla: () => schemaPlantilla,
11396
11400
  schemaRegion: () => schemaRegion,
11397
11401
  schemaSchool: () => schemaSchool,
@@ -11409,6 +11413,8 @@ __export(src_exports, {
11409
11413
  useBuildingUnitRepo: () => useBuildingUnitRepo,
11410
11414
  useCounterModel: () => useCounterModel,
11411
11415
  useCounterRepo: () => useCounterRepo,
11416
+ useCurriculumController: () => useCurriculumController,
11417
+ useCurriculumRepo: () => useCurriculumRepo,
11412
11418
  useDivisionController: () => useDivisionController,
11413
11419
  useDivisionRepo: () => useDivisionRepo,
11414
11420
  useDivisionService: () => useDivisionService,
@@ -11424,6 +11430,9 @@ __export(src_exports, {
11424
11430
  useInvoiceService: () => useInvoiceService,
11425
11431
  useMemberController: () => useMemberController,
11426
11432
  useMemberRepo: () => useMemberRepo,
11433
+ useOfficeController: () => useOfficeController,
11434
+ useOfficeRepo: () => useOfficeRepo,
11435
+ useOfficeService: () => useOfficeService,
11427
11436
  useOrderController: () => useOrderController,
11428
11437
  useOrderRepo: () => useOrderRepo,
11429
11438
  useOrgController: () => useOrgController,
@@ -28328,7 +28337,10 @@ function useBuildingUnitService() {
28328
28337
  try {
28329
28338
  await session.startTransaction();
28330
28339
  for (let index = 0; index < value.qty; index++) {
28331
- await _add({ ...value.building }, session);
28340
+ await _add(
28341
+ { ...value.building, name: `${value.building.name} ${index + 1}` },
28342
+ session
28343
+ );
28332
28344
  }
28333
28345
  await session.commitTransaction();
28334
28346
  return "Building unit added successfully.";
@@ -29820,6 +29832,10 @@ var import_joi41 = __toESM(require("joi"));
29820
29832
  var import_mongodb46 = require("mongodb");
29821
29833
  var schemaPlantilla = import_joi41.default.object({
29822
29834
  _id: import_joi41.default.string().hex().optional().allow(null, ""),
29835
+ org: import_joi41.default.string().hex().required(),
29836
+ orgUnitCode: import_joi41.default.string().optional().allow(null, ""),
29837
+ employmentType: import_joi41.default.string().optional().allow(null, ""),
29838
+ personnelType: import_joi41.default.string().required(),
29823
29839
  itemNumber: import_joi41.default.string().required(),
29824
29840
  positionTitle: import_joi41.default.string().required(),
29825
29841
  positionCategory: import_joi41.default.string().required(),
@@ -29828,8 +29844,7 @@ var schemaPlantilla = import_joi41.default.object({
29828
29844
  division: import_joi41.default.string().hex().optional().allow(null, ""),
29829
29845
  divisionName: import_joi41.default.string().optional().allow(null, ""),
29830
29846
  salaryGrade: import_joi41.default.number().required(),
29831
- step: import_joi41.default.number().optional().allow(null, 0),
29832
- incumbent: import_joi41.default.string().optional().allow(null, ""),
29847
+ employeeName: import_joi41.default.string().optional().allow(null, ""),
29833
29848
  annualSalary: import_joi41.default.number().optional().allow(null, 0),
29834
29849
  monthlySalary: import_joi41.default.number().optional().allow(null, 0),
29835
29850
  status: import_joi41.default.string().required(),
@@ -29857,14 +29872,18 @@ function MPlantilla(data) {
29857
29872
  positionCategory: data.positionCategory ?? "",
29858
29873
  status: data.status ?? "active",
29859
29874
  salaryGrade: data.salaryGrade ?? 0,
29860
- step: data.step ?? 0,
29861
29875
  monthlySalary: data.monthlySalary ?? 0,
29862
29876
  annualSalary: data.annualSalary ?? 0,
29863
29877
  region: data.region ?? "",
29864
29878
  regionName: data.regionName ?? "",
29865
29879
  division: data.division ?? "",
29866
29880
  divisionName: data.divisionName ?? "",
29867
- incumbent: data.incumbent ?? "",
29881
+ org: data.org ?? "",
29882
+ orgUnitCode: data.orgUnitCode ?? "",
29883
+ employmentType: data.employmentType ?? "",
29884
+ personnelType: data.personnelType ?? "",
29885
+ employee: data.employee ?? "",
29886
+ employeeName: data.employeeName ?? "",
29868
29887
  createdAt: data.createdAt ? new Date(data.createdAt) : /* @__PURE__ */ new Date(),
29869
29888
  updatedAt: data.updatedAt ? new Date(data.updatedAt) : "",
29870
29889
  deletedAt: data.deletedAt ? new Date(data.deletedAt) : ""
@@ -30205,7 +30224,8 @@ function usePlantillaService() {
30205
30224
  salaryGrade: parseInt(
30206
30225
  plantillaData.salarygrade || plantillaData.salary_grade || "1"
30207
30226
  ) || 1,
30208
- step: parseInt(plantillaData.step || "1") || 1,
30227
+ org: "",
30228
+ personnelType: "",
30209
30229
  status: status.trim() || "active"
30210
30230
  };
30211
30231
  if (region)
@@ -30218,9 +30238,6 @@ function usePlantillaService() {
30218
30238
  if (plantillaData.divisionname || plantillaData.division_name) {
30219
30239
  plantilla.divisionName = plantillaData.divisionname || plantillaData.division_name;
30220
30240
  }
30221
- if (plantillaData.incumbent) {
30222
- plantilla.incumbent = plantillaData.incumbent;
30223
- }
30224
30241
  if (plantillaData.employee) {
30225
30242
  plantilla.employee = plantillaData.employee;
30226
30243
  }
@@ -30501,6 +30518,1136 @@ function usePlantillaController() {
30501
30518
  bulkAddPlantillas
30502
30519
  };
30503
30520
  }
30521
+
30522
+ // src/models/office.model.ts
30523
+ var import_nodejs_utils86 = require("@eeplatform/nodejs-utils");
30524
+ var import_joi43 = __toESM(require("joi"));
30525
+ var import_mongodb48 = require("mongodb");
30526
+ var schemaOffice = import_joi43.default.object({
30527
+ _id: import_joi43.default.string().hex().optional().allow(null, ""),
30528
+ name: import_joi43.default.string().required(),
30529
+ code: import_joi43.default.string().required(),
30530
+ type: import_joi43.default.string().required(),
30531
+ parent: import_joi43.default.string().hex().optional().allow(null, ""),
30532
+ path: import_joi43.default.string().required(),
30533
+ status: import_joi43.default.string().required(),
30534
+ createdAt: import_joi43.default.date().iso().optional().allow(null, ""),
30535
+ updatedAt: import_joi43.default.date().iso().optional().allow(null, ""),
30536
+ deletedAt: import_joi43.default.date().iso().optional().allow(null, "")
30537
+ });
30538
+ function MOffice(data) {
30539
+ const { error } = schemaOffice.validate(data);
30540
+ if (error) {
30541
+ throw new import_nodejs_utils86.BadRequestError(error.message);
30542
+ }
30543
+ if (data._id && typeof data._id === "string") {
30544
+ try {
30545
+ data._id = new import_mongodb48.ObjectId(data._id);
30546
+ } catch (error2) {
30547
+ throw new import_nodejs_utils86.BadRequestError("Invalid _id.");
30548
+ }
30549
+ }
30550
+ if (data.parent && typeof data.parent === "string") {
30551
+ try {
30552
+ data.parent = new import_mongodb48.ObjectId(data.parent);
30553
+ } catch (error2) {
30554
+ throw new import_nodejs_utils86.BadRequestError("Invalid parent.");
30555
+ }
30556
+ }
30557
+ return {
30558
+ _id: data._id,
30559
+ name: data.name ?? "",
30560
+ code: data.code ?? "",
30561
+ type: data.type ?? "",
30562
+ parent: data.parent ?? "",
30563
+ path: data.path ?? "",
30564
+ status: data.status ?? "active",
30565
+ createdAt: data.createdAt ? new Date(data.createdAt) : /* @__PURE__ */ new Date(),
30566
+ updatedAt: data.updatedAt ? new Date(data.updatedAt) : "",
30567
+ deletedAt: data.deletedAt ? new Date(data.deletedAt) : ""
30568
+ };
30569
+ }
30570
+
30571
+ // src/repositories/office.repository.ts
30572
+ var import_nodejs_utils87 = require("@eeplatform/nodejs-utils");
30573
+ var import_mongodb49 = require("mongodb");
30574
+ function useOfficeRepo() {
30575
+ const db = import_nodejs_utils87.useAtlas.getDb();
30576
+ if (!db) {
30577
+ throw new Error("Unable to connect to server.");
30578
+ }
30579
+ const namespace_collection = "offices";
30580
+ const collection = db.collection(namespace_collection);
30581
+ const { getCache, setCache, delNamespace } = (0, import_nodejs_utils87.useCache)(namespace_collection);
30582
+ async function createIndexes() {
30583
+ try {
30584
+ await collection.createIndexes([
30585
+ {
30586
+ key: { name: 1, code: 1 },
30587
+ unique: true,
30588
+ name: "unique_name_code_index"
30589
+ },
30590
+ { key: { type: 1 } },
30591
+ { key: { parent: 1 } },
30592
+ { key: { status: 1 } }
30593
+ ]);
30594
+ } catch (error) {
30595
+ throw new Error("Failed to create index on offices.");
30596
+ }
30597
+ }
30598
+ async function add(value, session, clearCache = true) {
30599
+ try {
30600
+ value = MOffice(value);
30601
+ const res = await collection.insertOne(value, { session });
30602
+ if (clearCache) {
30603
+ delCachedData();
30604
+ }
30605
+ return res.insertedId;
30606
+ } catch (error) {
30607
+ import_nodejs_utils87.logger.log({
30608
+ level: "error",
30609
+ message: error.message
30610
+ });
30611
+ if (error instanceof import_nodejs_utils87.AppError) {
30612
+ throw error;
30613
+ } else {
30614
+ const isDuplicated = error.message.includes("duplicate");
30615
+ if (isDuplicated) {
30616
+ throw new import_nodejs_utils87.BadRequestError("Office already exists.");
30617
+ }
30618
+ throw new Error("Failed to create office.");
30619
+ }
30620
+ }
30621
+ }
30622
+ async function updateById(_id, value, session) {
30623
+ try {
30624
+ _id = new import_mongodb49.ObjectId(_id);
30625
+ } catch (error) {
30626
+ throw new import_nodejs_utils87.BadRequestError("Invalid ID.");
30627
+ }
30628
+ value.updatedAt = /* @__PURE__ */ new Date();
30629
+ try {
30630
+ const res = await collection.updateOne(
30631
+ { _id },
30632
+ { $set: value },
30633
+ { session }
30634
+ );
30635
+ delCachedData();
30636
+ return res;
30637
+ } catch (error) {
30638
+ import_nodejs_utils87.logger.log({
30639
+ level: "error",
30640
+ message: error.message
30641
+ });
30642
+ if (error instanceof import_nodejs_utils87.AppError) {
30643
+ throw error;
30644
+ } else {
30645
+ throw new Error("Failed to update office.");
30646
+ }
30647
+ }
30648
+ }
30649
+ async function getAll({
30650
+ search = "",
30651
+ page = 1,
30652
+ limit = 10,
30653
+ sort = {},
30654
+ type = "",
30655
+ parent = "",
30656
+ status = "active"
30657
+ } = {}) {
30658
+ page = page > 0 ? page - 1 : 0;
30659
+ const query = {
30660
+ status
30661
+ };
30662
+ sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
30663
+ if (search) {
30664
+ query.$text = { $search: search };
30665
+ }
30666
+ if (type) {
30667
+ query.type = type;
30668
+ }
30669
+ if (parent) {
30670
+ try {
30671
+ query.parent = new import_mongodb49.ObjectId(parent);
30672
+ } catch (error) {
30673
+ throw new import_nodejs_utils87.BadRequestError("Invalid parent ID.");
30674
+ }
30675
+ }
30676
+ const cacheParams = {
30677
+ page,
30678
+ limit,
30679
+ sort: JSON.stringify(sort)
30680
+ };
30681
+ if (search)
30682
+ cacheParams.search = search;
30683
+ if (type)
30684
+ cacheParams.type = type;
30685
+ if (parent)
30686
+ cacheParams.parent = parent;
30687
+ if (status !== "active")
30688
+ cacheParams.status = status;
30689
+ const cacheKey = (0, import_nodejs_utils87.makeCacheKey)(namespace_collection, cacheParams);
30690
+ import_nodejs_utils87.logger.log({
30691
+ level: "info",
30692
+ message: `Cache key for getAll offices: ${cacheKey}`
30693
+ });
30694
+ try {
30695
+ const cached = await getCache(cacheKey);
30696
+ if (cached) {
30697
+ import_nodejs_utils87.logger.log({
30698
+ level: "info",
30699
+ message: `Cache hit for getAll offices: ${cacheKey}`
30700
+ });
30701
+ return cached;
30702
+ }
30703
+ const items = await collection.aggregate([
30704
+ { $match: query },
30705
+ { $sort: sort },
30706
+ { $skip: page * limit },
30707
+ { $limit: limit }
30708
+ ]).toArray();
30709
+ const length = await collection.countDocuments(query);
30710
+ const data = (0, import_nodejs_utils87.paginate)(items, page, limit, length);
30711
+ setCache(cacheKey, data, 600).then(() => {
30712
+ import_nodejs_utils87.logger.log({
30713
+ level: "info",
30714
+ message: `Cache set for getAll offices: ${cacheKey}`
30715
+ });
30716
+ }).catch((err) => {
30717
+ import_nodejs_utils87.logger.log({
30718
+ level: "error",
30719
+ message: `Failed to set cache for getAll offices: ${err.message}`
30720
+ });
30721
+ });
30722
+ return data;
30723
+ } catch (error) {
30724
+ import_nodejs_utils87.logger.log({ level: "error", message: `${error}` });
30725
+ throw error;
30726
+ }
30727
+ }
30728
+ async function getById(_id) {
30729
+ try {
30730
+ _id = new import_mongodb49.ObjectId(_id);
30731
+ } catch (error) {
30732
+ throw new import_nodejs_utils87.BadRequestError("Invalid ID.");
30733
+ }
30734
+ const cacheKey = (0, import_nodejs_utils87.makeCacheKey)(namespace_collection, { _id: String(_id) });
30735
+ try {
30736
+ const cached = await getCache(cacheKey);
30737
+ if (cached) {
30738
+ import_nodejs_utils87.logger.log({
30739
+ level: "info",
30740
+ message: `Cache hit for getById office: ${cacheKey}`
30741
+ });
30742
+ return cached;
30743
+ }
30744
+ const result = await collection.findOne({
30745
+ _id
30746
+ });
30747
+ setCache(cacheKey, result, 300).then(() => {
30748
+ import_nodejs_utils87.logger.log({
30749
+ level: "info",
30750
+ message: `Cache set for office by id: ${cacheKey}`
30751
+ });
30752
+ }).catch((err) => {
30753
+ import_nodejs_utils87.logger.log({
30754
+ level: "error",
30755
+ message: `Failed to set cache for office by id: ${err.message}`
30756
+ });
30757
+ });
30758
+ return result;
30759
+ } catch (error) {
30760
+ if (error instanceof import_nodejs_utils87.AppError) {
30761
+ throw error;
30762
+ } else {
30763
+ throw new import_nodejs_utils87.InternalServerError("Failed to get office.");
30764
+ }
30765
+ }
30766
+ }
30767
+ async function deleteById(_id, session) {
30768
+ try {
30769
+ _id = new import_mongodb49.ObjectId(_id);
30770
+ } catch (error) {
30771
+ throw new import_nodejs_utils87.BadRequestError("Invalid ID.");
30772
+ }
30773
+ try {
30774
+ const res = await collection.updateOne(
30775
+ { _id },
30776
+ { $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } }
30777
+ );
30778
+ delCachedData();
30779
+ return res;
30780
+ } catch (error) {
30781
+ import_nodejs_utils87.logger.log({
30782
+ level: "error",
30783
+ message: error.message
30784
+ });
30785
+ if (error instanceof import_nodejs_utils87.AppError) {
30786
+ throw error;
30787
+ } else {
30788
+ throw new import_nodejs_utils87.InternalServerError("Failed to delete office.");
30789
+ }
30790
+ }
30791
+ }
30792
+ function delCachedData() {
30793
+ delNamespace().then(() => {
30794
+ import_nodejs_utils87.logger.log({
30795
+ level: "info",
30796
+ message: `Cache namespace cleared for ${namespace_collection}`
30797
+ });
30798
+ }).catch((err) => {
30799
+ import_nodejs_utils87.logger.log({
30800
+ level: "error",
30801
+ message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
30802
+ });
30803
+ });
30804
+ }
30805
+ return {
30806
+ createIndexes,
30807
+ add,
30808
+ getAll,
30809
+ getById,
30810
+ updateById,
30811
+ deleteById,
30812
+ delCachedData
30813
+ };
30814
+ }
30815
+
30816
+ // src/services/office.service.ts
30817
+ var import_nodejs_utils88 = require("@eeplatform/nodejs-utils");
30818
+ var XLSX3 = __toESM(require("xlsx"));
30819
+ var Papa3 = __toESM(require("papaparse"));
30820
+ function useOfficeService() {
30821
+ const { add: addOffice, delCachedData } = useOfficeRepo();
30822
+ async function addBulk(file) {
30823
+ import_nodejs_utils88.logger.log({
30824
+ level: "info",
30825
+ message: `Starting office bulk upload. File: ${file.originalname}, Size: ${file.size} bytes`
30826
+ });
30827
+ const MAX_SIZE = 16 * 1024 * 1024;
30828
+ let offices = [];
30829
+ let totalSize = 0;
30830
+ let validatedOffices = [];
30831
+ if (!file.buffer) {
30832
+ throw new import_nodejs_utils88.BadRequestError("File buffer is empty or corrupted");
30833
+ }
30834
+ try {
30835
+ const fileExtension = file.originalname.split(".").pop()?.toLowerCase();
30836
+ if (fileExtension === "csv") {
30837
+ const csvData = file.buffer.toString("utf-8");
30838
+ totalSize = Buffer.byteLength(csvData, "utf8");
30839
+ if (totalSize > MAX_SIZE) {
30840
+ throw new import_nodejs_utils88.BadRequestError(
30841
+ `File size exceeds limit. Maximum allowed: ${MAX_SIZE / 1024 / 1024}MB, Received: ${(totalSize / 1024 / 1024).toFixed(2)}MB`
30842
+ );
30843
+ }
30844
+ const parseResult = Papa3.parse(csvData, {
30845
+ header: true,
30846
+ skipEmptyLines: true,
30847
+ transformHeader: (header) => {
30848
+ return header.toLowerCase().replace(/\s+/g, "").replace(/[^\w]/g, "");
30849
+ }
30850
+ });
30851
+ if (parseResult.errors.length > 0) {
30852
+ throw new import_nodejs_utils88.BadRequestError(
30853
+ `CSV parsing errors: ${parseResult.errors.map((e) => e.message).join(", ")}`
30854
+ );
30855
+ }
30856
+ offices = parseResult.data || [];
30857
+ } else if (["xlsx", "xls"].includes(fileExtension || "")) {
30858
+ totalSize = file.buffer.length;
30859
+ if (totalSize > MAX_SIZE) {
30860
+ throw new import_nodejs_utils88.BadRequestError(
30861
+ `File size exceeds limit. Maximum allowed: ${MAX_SIZE / 1024 / 1024}MB, Received: ${(totalSize / 1024 / 1024).toFixed(2)}MB`
30862
+ );
30863
+ }
30864
+ const workbook = XLSX3.read(file.buffer, { type: "buffer" });
30865
+ const sheetName = workbook.SheetNames[0];
30866
+ if (!sheetName) {
30867
+ throw new import_nodejs_utils88.BadRequestError("Excel file contains no sheets");
30868
+ }
30869
+ const worksheet = workbook.Sheets[sheetName];
30870
+ offices = XLSX3.utils.sheet_to_json(worksheet, {
30871
+ header: 1,
30872
+ defval: ""
30873
+ });
30874
+ if (offices.length > 0) {
30875
+ const headers = offices[0];
30876
+ offices = offices.slice(1).map((row) => {
30877
+ const obj = {};
30878
+ headers.forEach((header, index) => {
30879
+ obj[header.trim()] = row[index] || "";
30880
+ });
30881
+ return obj;
30882
+ });
30883
+ }
30884
+ } else {
30885
+ throw new import_nodejs_utils88.BadRequestError(
30886
+ "Unsupported file format. Please upload CSV, XLS, or XLSX files."
30887
+ );
30888
+ }
30889
+ if (!offices || offices.length === 0) {
30890
+ throw new import_nodejs_utils88.BadRequestError("File is empty or contains no valid data");
30891
+ }
30892
+ const results = {
30893
+ total: offices.length,
30894
+ successful: 0,
30895
+ failed: 0,
30896
+ errors: []
30897
+ };
30898
+ import_nodejs_utils88.logger.log({
30899
+ level: "info",
30900
+ message: `Processing ${offices.length} offices from file`
30901
+ });
30902
+ for (let i = 0; i < offices.length; i++) {
30903
+ const officeData = offices[i];
30904
+ try {
30905
+ const cleanOffice = {
30906
+ name: String(officeData.name || "").trim(),
30907
+ code: String(officeData.code || "").trim(),
30908
+ type: String(officeData.type || "").trim(),
30909
+ path: String(officeData.path || "").trim(),
30910
+ status: String(officeData.status || "active").trim()
30911
+ };
30912
+ if (officeData.parent && String(officeData.parent).trim()) {
30913
+ cleanOffice.parent = String(officeData.parent).trim();
30914
+ }
30915
+ const { error } = schemaOffice.validate(cleanOffice);
30916
+ if (error) {
30917
+ results.errors.push(`Row ${i + 1}: ${error.message}`);
30918
+ results.failed++;
30919
+ continue;
30920
+ }
30921
+ validatedOffices.push(cleanOffice);
30922
+ } catch (error) {
30923
+ results.errors.push(`Row ${i + 1}: ${error.message}`);
30924
+ results.failed++;
30925
+ }
30926
+ }
30927
+ if (validatedOffices.length === 0) {
30928
+ throw new import_nodejs_utils88.BadRequestError(
30929
+ "No valid offices found in file. Please check the format and data."
30930
+ );
30931
+ }
30932
+ const db = import_nodejs_utils88.useAtlas.getDb();
30933
+ if (!db) {
30934
+ throw new Error("Database connection not available");
30935
+ }
30936
+ const session = db.client.startSession();
30937
+ try {
30938
+ await session.withTransaction(async () => {
30939
+ const batchSize = 100;
30940
+ for (let i = 0; i < validatedOffices.length; i += batchSize) {
30941
+ const batch = validatedOffices.slice(i, i + batchSize);
30942
+ for (const office of batch) {
30943
+ try {
30944
+ await addOffice(office, session, false);
30945
+ results.successful++;
30946
+ } catch (error) {
30947
+ results.failed++;
30948
+ results.errors.push(
30949
+ `Failed to insert office "${office.name}": ${error.message}`
30950
+ );
30951
+ import_nodejs_utils88.logger.log({
30952
+ level: "error",
30953
+ message: `Failed to insert office: ${error.message}`
30954
+ });
30955
+ }
30956
+ }
30957
+ }
30958
+ });
30959
+ delCachedData();
30960
+ import_nodejs_utils88.logger.log({
30961
+ level: "info",
30962
+ message: `Bulk upload completed. Successful: ${results.successful}, Failed: ${results.failed}`
30963
+ });
30964
+ return results;
30965
+ } catch (error) {
30966
+ import_nodejs_utils88.logger.log({
30967
+ level: "error",
30968
+ message: `Transaction failed: ${error.message}`
30969
+ });
30970
+ throw new import_nodejs_utils88.BadRequestError(`Bulk upload failed: ${error.message}`);
30971
+ } finally {
30972
+ await session.endSession();
30973
+ }
30974
+ } catch (error) {
30975
+ import_nodejs_utils88.logger.log({
30976
+ level: "error",
30977
+ message: `Bulk office upload failed: ${error.message}`
30978
+ });
30979
+ if (error instanceof import_nodejs_utils88.BadRequestError) {
30980
+ throw error;
30981
+ }
30982
+ throw new import_nodejs_utils88.BadRequestError(`File processing failed: ${error.message}`);
30983
+ }
30984
+ }
30985
+ return {
30986
+ addBulk
30987
+ };
30988
+ }
30989
+
30990
+ // src/controllers/office.controller.ts
30991
+ var import_nodejs_utils89 = require("@eeplatform/nodejs-utils");
30992
+ var import_joi44 = __toESM(require("joi"));
30993
+ function useOfficeController() {
30994
+ const {
30995
+ add: _add,
30996
+ getAll: _getAll,
30997
+ getById: _getById,
30998
+ updateById: _updateByIdById,
30999
+ deleteById: _deleteByIdById
31000
+ } = useOfficeRepo();
31001
+ const { addBulk: _addBulk } = useOfficeService();
31002
+ async function add(req, res, next) {
31003
+ const value = req.body;
31004
+ const validation = import_joi44.default.object({
31005
+ name: import_joi44.default.string().required(),
31006
+ code: import_joi44.default.string().required(),
31007
+ type: import_joi44.default.string().required(),
31008
+ path: import_joi44.default.string().required(),
31009
+ parent: import_joi44.default.string().hex().optional().allow(null, ""),
31010
+ status: import_joi44.default.string().optional().allow(null, "")
31011
+ });
31012
+ const { error } = validation.validate(value);
31013
+ if (error) {
31014
+ next(new import_nodejs_utils89.BadRequestError(error.message));
31015
+ return;
31016
+ }
31017
+ try {
31018
+ const id = await _add(value);
31019
+ res.json({ message: "Office created successfully", id });
31020
+ return;
31021
+ } catch (error2) {
31022
+ next(error2);
31023
+ }
31024
+ }
31025
+ async function getAll(req, res, next) {
31026
+ const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
31027
+ const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
31028
+ const search = req.query.search ?? "";
31029
+ const type = req.query.type ?? "";
31030
+ const parent = req.query.parent ?? "";
31031
+ const status = req.query.status ?? "active";
31032
+ const isPageNumber = isFinite(page);
31033
+ if (!isPageNumber) {
31034
+ next(new import_nodejs_utils89.BadRequestError("Invalid page number."));
31035
+ return;
31036
+ }
31037
+ const isLimitNumber = isFinite(limit);
31038
+ if (!isLimitNumber) {
31039
+ next(new import_nodejs_utils89.BadRequestError("Invalid limit number."));
31040
+ return;
31041
+ }
31042
+ const validation = import_joi44.default.object({
31043
+ page: import_joi44.default.number().min(1).optional().allow("", null),
31044
+ limit: import_joi44.default.number().min(1).optional().allow("", null),
31045
+ search: import_joi44.default.string().optional().allow("", null),
31046
+ type: import_joi44.default.string().optional().allow("", null),
31047
+ parent: import_joi44.default.string().optional().allow("", null),
31048
+ status: import_joi44.default.string().optional().allow("", null)
31049
+ });
31050
+ const { error } = validation.validate({
31051
+ page,
31052
+ limit,
31053
+ search,
31054
+ type,
31055
+ parent,
31056
+ status
31057
+ });
31058
+ if (error) {
31059
+ next(new import_nodejs_utils89.BadRequestError(error.message));
31060
+ return;
31061
+ }
31062
+ try {
31063
+ const offices = await _getAll({
31064
+ search,
31065
+ page,
31066
+ limit,
31067
+ type,
31068
+ parent,
31069
+ status
31070
+ });
31071
+ res.json(offices);
31072
+ return;
31073
+ } catch (error2) {
31074
+ next(error2);
31075
+ }
31076
+ }
31077
+ async function getById(req, res, next) {
31078
+ const id = req.params.id;
31079
+ const validation = import_joi44.default.object({
31080
+ id: import_joi44.default.string().hex().required()
31081
+ });
31082
+ const { error } = validation.validate({ id });
31083
+ if (error) {
31084
+ next(new import_nodejs_utils89.BadRequestError(error.message));
31085
+ return;
31086
+ }
31087
+ try {
31088
+ const office = await _getById(id);
31089
+ if (!office) {
31090
+ next(new import_nodejs_utils89.BadRequestError("Office not found."));
31091
+ return;
31092
+ }
31093
+ res.json(office);
31094
+ return;
31095
+ } catch (error2) {
31096
+ next(error2);
31097
+ }
31098
+ }
31099
+ async function updateById(req, res, next) {
31100
+ const id = req.params.id;
31101
+ const value = req.body;
31102
+ const validation = import_joi44.default.object({
31103
+ id: import_joi44.default.string().hex().required(),
31104
+ name: import_joi44.default.string().optional(),
31105
+ code: import_joi44.default.string().optional(),
31106
+ type: import_joi44.default.string().optional(),
31107
+ parent: import_joi44.default.string().hex().optional().allow(null, ""),
31108
+ path: import_joi44.default.string().optional(),
31109
+ status: import_joi44.default.string().optional()
31110
+ });
31111
+ const { error } = validation.validate({ id, ...value });
31112
+ if (error) {
31113
+ next(new import_nodejs_utils89.BadRequestError(error.message));
31114
+ return;
31115
+ }
31116
+ try {
31117
+ const result = await _updateByIdById(id, value);
31118
+ if (result.matchedCount === 0) {
31119
+ next(new import_nodejs_utils89.BadRequestError("Office not found."));
31120
+ return;
31121
+ }
31122
+ res.json({ message: "Office updated successfully" });
31123
+ return;
31124
+ } catch (error2) {
31125
+ next(error2);
31126
+ }
31127
+ }
31128
+ async function deleteById(req, res, next) {
31129
+ const id = req.params.id;
31130
+ const validation = import_joi44.default.object({
31131
+ id: import_joi44.default.string().hex().required()
31132
+ });
31133
+ const { error } = validation.validate({ id });
31134
+ if (error) {
31135
+ next(new import_nodejs_utils89.BadRequestError(error.message));
31136
+ return;
31137
+ }
31138
+ try {
31139
+ const result = await _deleteByIdById(id);
31140
+ if (result.matchedCount === 0) {
31141
+ next(new import_nodejs_utils89.BadRequestError("Office not found."));
31142
+ return;
31143
+ }
31144
+ res.json({ message: "Office deleted successfully" });
31145
+ return;
31146
+ } catch (error2) {
31147
+ next(error2);
31148
+ }
31149
+ }
31150
+ async function bulkAddOffices(req, res, next) {
31151
+ if (!req.file) {
31152
+ res.status(400).send("File is required!");
31153
+ return;
31154
+ }
31155
+ try {
31156
+ const result = await _addBulk(req.file);
31157
+ res.status(201).json(result);
31158
+ return;
31159
+ } catch (error) {
31160
+ next(error);
31161
+ return;
31162
+ }
31163
+ }
31164
+ return {
31165
+ add,
31166
+ getAll,
31167
+ getById,
31168
+ updateById,
31169
+ deleteById,
31170
+ bulkAddOffices
31171
+ };
31172
+ }
31173
+
31174
+ // src/models/curriculum.model.ts
31175
+ var import_nodejs_utils90 = require("@eeplatform/nodejs-utils");
31176
+ var import_joi45 = __toESM(require("joi"));
31177
+ var import_mongodb50 = require("mongodb");
31178
+ var schemaCurriculum = import_joi45.default.object({
31179
+ _id: import_joi45.default.string().hex().optional(),
31180
+ school: import_joi45.default.string().hex().required(),
31181
+ code: import_joi45.default.string().required(),
31182
+ educationLevel: import_joi45.default.string().required(),
31183
+ gradeLevel: import_joi45.default.string().required(),
31184
+ subjectCode: import_joi45.default.string().required(),
31185
+ subjectName: import_joi45.default.string().required(),
31186
+ subjectType: import_joi45.default.string().required(),
31187
+ sessionFrequency: import_joi45.default.number().integer().min(0).required(),
31188
+ sessionDuration: import_joi45.default.number().integer().min(0).required(),
31189
+ totalMinutesPerWeek: import_joi45.default.number().integer().min(0).required(),
31190
+ curriculumMemoRef: import_joi45.default.string().optional().allow("", null),
31191
+ status: import_joi45.default.string().optional().allow("", null),
31192
+ createdAt: import_joi45.default.date().optional().allow("", null),
31193
+ updatedAt: import_joi45.default.date().optional().allow("", null),
31194
+ deletedAt: import_joi45.default.date().optional().allow("", null),
31195
+ createdBy: import_joi45.default.string().optional().allow("", null),
31196
+ updatedBy: import_joi45.default.string().optional().allow("", null),
31197
+ deletedBy: import_joi45.default.string().optional().allow("", null)
31198
+ });
31199
+ function MCurriculum(value) {
31200
+ const { error } = schemaCurriculum.validate(value);
31201
+ if (error) {
31202
+ import_nodejs_utils90.logger.info(`Curriculum Model: ${error.message}`);
31203
+ throw new import_nodejs_utils90.BadRequestError(error.message);
31204
+ }
31205
+ if (value._id && typeof value._id === "string") {
31206
+ try {
31207
+ value._id = new import_mongodb50.ObjectId(value._id);
31208
+ } catch (error2) {
31209
+ throw new import_nodejs_utils90.BadRequestError("Invalid _id format");
31210
+ }
31211
+ }
31212
+ return {
31213
+ _id: value._id ?? void 0,
31214
+ school: value.school ?? "",
31215
+ code: value.code ?? "",
31216
+ educationLevel: value.educationLevel ?? "",
31217
+ gradeLevel: value.gradeLevel ?? "",
31218
+ subjectCode: value.subjectCode ?? "",
31219
+ subjectName: value.subjectName ?? "",
31220
+ subjectType: value.subjectType ?? "",
31221
+ sessionFrequency: value.sessionFrequency ?? 0,
31222
+ sessionDuration: value.sessionDuration ?? 0,
31223
+ totalMinutesPerWeek: value.totalMinutesPerWeek ?? 0,
31224
+ curriculumMemoRef: value.curriculumMemoRef ?? "",
31225
+ status: value.status ?? "active",
31226
+ createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
31227
+ updatedAt: value.updatedAt ?? "",
31228
+ deletedAt: value.deletedAt ?? "",
31229
+ createdBy: value.createdBy ?? "",
31230
+ updatedBy: value.updatedBy ?? "",
31231
+ deletedBy: value.deletedBy ?? ""
31232
+ };
31233
+ }
31234
+
31235
+ // src/repositories/curriculum.repository.ts
31236
+ var import_nodejs_utils91 = require("@eeplatform/nodejs-utils");
31237
+ var import_mongodb51 = require("mongodb");
31238
+ function useCurriculumRepo() {
31239
+ const db = import_nodejs_utils91.useAtlas.getDb();
31240
+ if (!db) {
31241
+ throw new Error("Unable to connect to server.");
31242
+ }
31243
+ const namespace_collection = "school.curriculums";
31244
+ const collection = db.collection(namespace_collection);
31245
+ const { getCache, setCache, delNamespace } = (0, import_nodejs_utils91.useCache)(namespace_collection);
31246
+ async function createIndexes() {
31247
+ try {
31248
+ await collection.createIndexes([
31249
+ { key: { code: 1 }, unique: true, name: "unique_code_index" },
31250
+ { key: { educationLevel: 1 } },
31251
+ { key: { gradeLevel: 1 } },
31252
+ { key: { subjectCode: 1 } },
31253
+ { key: { status: 1 } }
31254
+ ]);
31255
+ } catch (error) {
31256
+ throw new Error("Failed to create index on curriculums.");
31257
+ }
31258
+ }
31259
+ async function add(value, session) {
31260
+ try {
31261
+ value = MCurriculum(value);
31262
+ const res = await collection.insertOne(value, { session });
31263
+ delCachedData();
31264
+ return res.insertedId;
31265
+ } catch (error) {
31266
+ import_nodejs_utils91.logger.log({
31267
+ level: "error",
31268
+ message: error.message
31269
+ });
31270
+ if (error instanceof import_nodejs_utils91.AppError) {
31271
+ throw error;
31272
+ } else {
31273
+ const isDuplicated = error.message.includes("duplicate");
31274
+ if (isDuplicated) {
31275
+ throw new import_nodejs_utils91.BadRequestError("Curriculum already exists.");
31276
+ }
31277
+ throw new Error("Failed to create curriculum.");
31278
+ }
31279
+ }
31280
+ }
31281
+ async function updateById(_id, value, session) {
31282
+ try {
31283
+ _id = new import_mongodb51.ObjectId(_id);
31284
+ } catch (error) {
31285
+ throw new import_nodejs_utils91.BadRequestError("Invalid ID.");
31286
+ }
31287
+ try {
31288
+ const res = await collection.updateOne(
31289
+ { _id },
31290
+ { $set: { ...value, updatedAt: /* @__PURE__ */ new Date() } },
31291
+ { session }
31292
+ );
31293
+ delCachedData();
31294
+ return res;
31295
+ } catch (error) {
31296
+ import_nodejs_utils91.logger.log({
31297
+ level: "error",
31298
+ message: error.message
31299
+ });
31300
+ if (error instanceof import_nodejs_utils91.AppError) {
31301
+ throw error;
31302
+ } else {
31303
+ throw new Error("Failed to update curriculum.");
31304
+ }
31305
+ }
31306
+ }
31307
+ async function getAll({
31308
+ search = "",
31309
+ page = 1,
31310
+ limit = 10,
31311
+ sort = {},
31312
+ educationLevel = "",
31313
+ gradeLevel = "",
31314
+ subjectCode = "",
31315
+ status = "active"
31316
+ } = {}) {
31317
+ page = page > 0 ? page - 1 : 0;
31318
+ const query = {
31319
+ status
31320
+ };
31321
+ sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
31322
+ if (search) {
31323
+ query.$or = [
31324
+ { code: { $regex: search, $options: "i" } },
31325
+ { subjectName: { $regex: search, $options: "i" } },
31326
+ { subjectCode: { $regex: search, $options: "i" } }
31327
+ ];
31328
+ }
31329
+ if (educationLevel) {
31330
+ query.educationLevel = educationLevel;
31331
+ }
31332
+ if (gradeLevel) {
31333
+ query.gradeLevel = gradeLevel;
31334
+ }
31335
+ if (subjectCode) {
31336
+ query.subjectCode = subjectCode;
31337
+ }
31338
+ const cacheParams = {
31339
+ page,
31340
+ limit,
31341
+ sort: JSON.stringify(sort)
31342
+ };
31343
+ if (search)
31344
+ cacheParams.search = search;
31345
+ if (educationLevel)
31346
+ cacheParams.educationLevel = educationLevel;
31347
+ if (gradeLevel)
31348
+ cacheParams.gradeLevel = gradeLevel;
31349
+ if (subjectCode)
31350
+ cacheParams.subjectCode = subjectCode;
31351
+ if (status !== "active")
31352
+ cacheParams.status = status;
31353
+ const cacheKey = (0, import_nodejs_utils91.makeCacheKey)(namespace_collection, cacheParams);
31354
+ import_nodejs_utils91.logger.log({
31355
+ level: "info",
31356
+ message: `Cache key for getAll curriculums: ${cacheKey}`
31357
+ });
31358
+ try {
31359
+ const cached = await getCache(cacheKey);
31360
+ if (cached) {
31361
+ import_nodejs_utils91.logger.log({
31362
+ level: "info",
31363
+ message: `Cache hit for getAll curriculums: ${cacheKey}`
31364
+ });
31365
+ return cached;
31366
+ }
31367
+ const items = await collection.aggregate([
31368
+ { $match: query },
31369
+ { $sort: sort },
31370
+ { $skip: page * limit },
31371
+ { $limit: limit }
31372
+ ]).toArray();
31373
+ const length = await collection.countDocuments(query);
31374
+ const data = (0, import_nodejs_utils91.paginate)(items, page, limit, length);
31375
+ setCache(cacheKey, data, 600).then(() => {
31376
+ import_nodejs_utils91.logger.log({
31377
+ level: "info",
31378
+ message: `Cache set for getAll curriculums: ${cacheKey}`
31379
+ });
31380
+ }).catch((err) => {
31381
+ import_nodejs_utils91.logger.log({
31382
+ level: "error",
31383
+ message: `Failed to set cache for getAll curriculums: ${err.message}`
31384
+ });
31385
+ });
31386
+ return data;
31387
+ } catch (error) {
31388
+ import_nodejs_utils91.logger.log({ level: "error", message: `${error}` });
31389
+ throw error;
31390
+ }
31391
+ }
31392
+ async function getById(_id) {
31393
+ try {
31394
+ _id = new import_mongodb51.ObjectId(_id);
31395
+ } catch (error) {
31396
+ throw new import_nodejs_utils91.BadRequestError("Invalid ID.");
31397
+ }
31398
+ const cacheKey = (0, import_nodejs_utils91.makeCacheKey)(namespace_collection, { _id: String(_id) });
31399
+ try {
31400
+ const cached = await getCache(cacheKey);
31401
+ if (cached) {
31402
+ import_nodejs_utils91.logger.log({
31403
+ level: "info",
31404
+ message: `Cache hit for getById curriculum: ${cacheKey}`
31405
+ });
31406
+ return cached;
31407
+ }
31408
+ const result = await collection.findOne({
31409
+ _id
31410
+ });
31411
+ setCache(cacheKey, result, 300).then(() => {
31412
+ import_nodejs_utils91.logger.log({
31413
+ level: "info",
31414
+ message: `Cache set for curriculum by id: ${cacheKey}`
31415
+ });
31416
+ }).catch((err) => {
31417
+ import_nodejs_utils91.logger.log({
31418
+ level: "error",
31419
+ message: `Failed to set cache for curriculum by id: ${err.message}`
31420
+ });
31421
+ });
31422
+ return result;
31423
+ } catch (error) {
31424
+ if (error instanceof import_nodejs_utils91.AppError) {
31425
+ throw error;
31426
+ } else {
31427
+ throw new import_nodejs_utils91.InternalServerError("Failed to get curriculum.");
31428
+ }
31429
+ }
31430
+ }
31431
+ async function deleteById(_id, session) {
31432
+ try {
31433
+ _id = new import_mongodb51.ObjectId(_id);
31434
+ } catch (error) {
31435
+ throw new import_nodejs_utils91.BadRequestError("Invalid ID.");
31436
+ }
31437
+ try {
31438
+ const res = await collection.updateOne(
31439
+ { _id },
31440
+ { $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } }
31441
+ );
31442
+ delCachedData();
31443
+ return res;
31444
+ } catch (error) {
31445
+ import_nodejs_utils91.logger.log({
31446
+ level: "error",
31447
+ message: error.message
31448
+ });
31449
+ if (error instanceof import_nodejs_utils91.AppError) {
31450
+ throw error;
31451
+ } else {
31452
+ throw new import_nodejs_utils91.InternalServerError("Failed to delete curriculum.");
31453
+ }
31454
+ }
31455
+ }
31456
+ function delCachedData() {
31457
+ delNamespace().then(() => {
31458
+ import_nodejs_utils91.logger.log({
31459
+ level: "info",
31460
+ message: `Cache namespace cleared for ${namespace_collection}`
31461
+ });
31462
+ }).catch((err) => {
31463
+ import_nodejs_utils91.logger.log({
31464
+ level: "error",
31465
+ message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
31466
+ });
31467
+ });
31468
+ }
31469
+ return {
31470
+ createIndexes,
31471
+ add,
31472
+ getAll,
31473
+ getById,
31474
+ updateById,
31475
+ deleteById
31476
+ };
31477
+ }
31478
+
31479
+ // src/controllers/curriculum.controller.ts
31480
+ var import_nodejs_utils92 = require("@eeplatform/nodejs-utils");
31481
+ var import_joi46 = __toESM(require("joi"));
31482
+ function useCurriculumController() {
31483
+ const {
31484
+ getAll: _getAll,
31485
+ getById: _getById,
31486
+ add: _add,
31487
+ updateById: _updateById,
31488
+ deleteById: _deleteById
31489
+ } = useCurriculumRepo();
31490
+ async function add(req, res, next) {
31491
+ const value = req.body;
31492
+ const validation = import_joi46.default.object({
31493
+ code: import_joi46.default.string().required(),
31494
+ school: import_joi46.default.string().hex().required(),
31495
+ educationLevel: import_joi46.default.string().required(),
31496
+ gradeLevel: import_joi46.default.string().required(),
31497
+ subjectCode: import_joi46.default.string().required(),
31498
+ subjectName: import_joi46.default.string().required(),
31499
+ subjectType: import_joi46.default.string().required(),
31500
+ sessionFrequency: import_joi46.default.number().integer().min(0).required(),
31501
+ sessionDuration: import_joi46.default.number().integer().min(0).required(),
31502
+ totalMinutesPerWeek: import_joi46.default.number().integer().min(0).required(),
31503
+ curriculumMemoRef: import_joi46.default.string().optional().allow("", null),
31504
+ status: import_joi46.default.string().optional().allow("", null)
31505
+ });
31506
+ const { error } = validation.validate(value);
31507
+ if (error) {
31508
+ next(new import_nodejs_utils92.BadRequestError(error.message));
31509
+ import_nodejs_utils92.logger.info(`Controller: ${error.message}`);
31510
+ return;
31511
+ }
31512
+ try {
31513
+ const result = await _add(value);
31514
+ res.json(result);
31515
+ return;
31516
+ } catch (error2) {
31517
+ next(error2);
31518
+ }
31519
+ }
31520
+ async function updateById(req, res, next) {
31521
+ const value = req.body;
31522
+ const id = req.params.id ?? "";
31523
+ const validation = import_joi46.default.object({
31524
+ id: import_joi46.default.string().hex().required(),
31525
+ value: import_joi46.default.object({
31526
+ code: import_joi46.default.string().optional(),
31527
+ educationLevel: import_joi46.default.string().optional(),
31528
+ gradeLevel: import_joi46.default.string().optional(),
31529
+ subjectCode: import_joi46.default.string().optional(),
31530
+ subjectName: import_joi46.default.string().optional(),
31531
+ subjectType: import_joi46.default.string().optional(),
31532
+ sessionFrequency: import_joi46.default.number().integer().min(0).optional(),
31533
+ sessionDuration: import_joi46.default.number().integer().min(0).optional(),
31534
+ totalMinutesPerWeek: import_joi46.default.number().integer().min(0).optional(),
31535
+ curriculumMemoRef: import_joi46.default.string().optional().allow("", null)
31536
+ }).min(1)
31537
+ });
31538
+ const { error } = validation.validate({ id, value });
31539
+ if (error) {
31540
+ next(new import_nodejs_utils92.BadRequestError(error.message));
31541
+ import_nodejs_utils92.logger.info(`Controller: ${error.message}`);
31542
+ return;
31543
+ }
31544
+ try {
31545
+ const result = await _updateById(id, value);
31546
+ res.json(result);
31547
+ return;
31548
+ } catch (error2) {
31549
+ next(error2);
31550
+ }
31551
+ }
31552
+ async function getAll(req, res, next) {
31553
+ const query = req.query;
31554
+ const validation = import_joi46.default.object({
31555
+ page: import_joi46.default.number().min(1).optional().allow("", null),
31556
+ limit: import_joi46.default.number().min(1).optional().allow("", null),
31557
+ search: import_joi46.default.string().optional().allow("", null),
31558
+ educationLevel: import_joi46.default.string().optional().allow("", null),
31559
+ gradeLevel: import_joi46.default.string().optional().allow("", null),
31560
+ subjectCode: import_joi46.default.string().optional().allow("", null),
31561
+ status: import_joi46.default.string().optional().allow("", null)
31562
+ });
31563
+ const { error } = validation.validate(query);
31564
+ if (error) {
31565
+ next(new import_nodejs_utils92.BadRequestError(error.message));
31566
+ return;
31567
+ }
31568
+ const page = parseInt(req.query.page) ?? 1;
31569
+ let limit = parseInt(req.query.limit) ?? 20;
31570
+ limit = isNaN(limit) ? 20 : limit;
31571
+ const sort = req.query.sort ? String(req.query.sort).split(",") : "";
31572
+ const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
31573
+ const sortObj = {};
31574
+ if (sort && Array.isArray(sort) && sort.length && sortOrder && Array.isArray(sortOrder) && sortOrder.length) {
31575
+ sort.forEach((field, index) => {
31576
+ sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
31577
+ });
31578
+ }
31579
+ const status = req.query.status ?? "active";
31580
+ const educationLevel = req.query.educationLevel ?? "";
31581
+ const gradeLevel = req.query.gradeLevel ?? "";
31582
+ const subjectCode = req.query.subjectCode ?? "";
31583
+ const search = req.query.search ?? "";
31584
+ try {
31585
+ const curriculums = await _getAll({
31586
+ page,
31587
+ limit,
31588
+ sort: sortObj,
31589
+ status,
31590
+ educationLevel,
31591
+ gradeLevel,
31592
+ subjectCode,
31593
+ search
31594
+ });
31595
+ res.json(curriculums);
31596
+ return;
31597
+ } catch (error2) {
31598
+ next(error2);
31599
+ }
31600
+ }
31601
+ async function getById(req, res, next) {
31602
+ const id = req.params.id;
31603
+ const validation = import_joi46.default.object({
31604
+ id: import_joi46.default.string().hex().required()
31605
+ });
31606
+ const { error } = validation.validate({ id });
31607
+ if (error) {
31608
+ next(new import_nodejs_utils92.BadRequestError(error.message));
31609
+ return;
31610
+ }
31611
+ try {
31612
+ const curriculum = await _getById(id);
31613
+ res.json({
31614
+ message: "Successfully retrieved curriculum.",
31615
+ data: { curriculum }
31616
+ });
31617
+ return;
31618
+ } catch (error2) {
31619
+ next(error2);
31620
+ }
31621
+ }
31622
+ async function deleteById(req, res, next) {
31623
+ const id = req.params.id;
31624
+ const validation = import_joi46.default.object({
31625
+ id: import_joi46.default.string().hex().required()
31626
+ });
31627
+ const { error } = validation.validate({ id });
31628
+ if (error) {
31629
+ next(new import_nodejs_utils92.BadRequestError(error.message));
31630
+ return;
31631
+ }
31632
+ try {
31633
+ const result = await _deleteById(id);
31634
+ res.json({
31635
+ message: "Successfully deleted curriculum.",
31636
+ data: result
31637
+ });
31638
+ return;
31639
+ } catch (error2) {
31640
+ next(error2);
31641
+ }
31642
+ }
31643
+ return {
31644
+ add,
31645
+ getAll,
31646
+ getById,
31647
+ updateById,
31648
+ deleteById
31649
+ };
31650
+ }
30504
31651
  // Annotate the CommonJS export names for ESM import in node:
30505
31652
  0 && (module.exports = {
30506
31653
  ACCESS_TOKEN_EXPIRY,
@@ -30523,12 +31670,14 @@ function usePlantillaController() {
30523
31670
  MAsset,
30524
31671
  MBuilding,
30525
31672
  MBuildingUnit,
31673
+ MCurriculum,
30526
31674
  MDivision,
30527
31675
  MEntity,
30528
31676
  MFile,
30529
31677
  MMember,
30530
31678
  MONGO_DB,
30531
31679
  MONGO_URI,
31680
+ MOffice,
30532
31681
  MOrder,
30533
31682
  MOrg,
30534
31683
  MPaymentMethod,
@@ -30569,7 +31718,9 @@ function usePlantillaController() {
30569
31718
  schemaAssetUpdateOption,
30570
31719
  schemaBuilding,
30571
31720
  schemaBuildingUnit,
31721
+ schemaCurriculum,
30572
31722
  schemaDivision,
31723
+ schemaOffice,
30573
31724
  schemaPlantilla,
30574
31725
  schemaRegion,
30575
31726
  schemaSchool,
@@ -30587,6 +31738,8 @@ function usePlantillaController() {
30587
31738
  useBuildingUnitRepo,
30588
31739
  useCounterModel,
30589
31740
  useCounterRepo,
31741
+ useCurriculumController,
31742
+ useCurriculumRepo,
30590
31743
  useDivisionController,
30591
31744
  useDivisionRepo,
30592
31745
  useDivisionService,
@@ -30602,6 +31755,9 @@ function usePlantillaController() {
30602
31755
  useInvoiceService,
30603
31756
  useMemberController,
30604
31757
  useMemberRepo,
31758
+ useOfficeController,
31759
+ useOfficeRepo,
31760
+ useOfficeService,
30605
31761
  useOrderController,
30606
31762
  useOrderRepo,
30607
31763
  useOrgController,