@eeplatform/core 1.4.4 → 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/CHANGELOG.md +12 -0
- package/dist/index.d.ts +177 -19
- package/dist/index.js +2060 -255
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2070 -256
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -1
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
|
|
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
|
|
10395
|
+
function parse4(str) {
|
|
10396
10396
|
str = String(str);
|
|
10397
10397
|
if (str.length > 100) {
|
|
10398
10398
|
return;
|
|
@@ -10839,7 +10839,7 @@ var require_follow_redirects = __commonJS({
|
|
|
10839
10839
|
(function detectUnsupportedEnvironment() {
|
|
10840
10840
|
var looksLikeNode = typeof process !== "undefined";
|
|
10841
10841
|
var looksLikeBrowser = typeof window !== "undefined" && typeof document !== "undefined";
|
|
10842
|
-
var looksLikeV8 =
|
|
10842
|
+
var looksLikeV8 = isFunction3(Error.captureStackTrace);
|
|
10843
10843
|
if (!looksLikeNode && (looksLikeBrowser || !looksLikeV8)) {
|
|
10844
10844
|
console.warn("The follow-redirects package should be excluded from browser builds.");
|
|
10845
10845
|
}
|
|
@@ -10934,7 +10934,7 @@ var require_follow_redirects = __commonJS({
|
|
|
10934
10934
|
if (!isString2(data) && !isBuffer2(data)) {
|
|
10935
10935
|
throw new TypeError("data should be a string, Buffer or Uint8Array");
|
|
10936
10936
|
}
|
|
10937
|
-
if (
|
|
10937
|
+
if (isFunction3(encoding)) {
|
|
10938
10938
|
callback = encoding;
|
|
10939
10939
|
encoding = null;
|
|
10940
10940
|
}
|
|
@@ -10954,10 +10954,10 @@ var require_follow_redirects = __commonJS({
|
|
|
10954
10954
|
}
|
|
10955
10955
|
};
|
|
10956
10956
|
RedirectableRequest.prototype.end = function(data, encoding, callback) {
|
|
10957
|
-
if (
|
|
10957
|
+
if (isFunction3(data)) {
|
|
10958
10958
|
callback = data;
|
|
10959
10959
|
data = encoding = null;
|
|
10960
|
-
} else if (
|
|
10960
|
+
} else if (isFunction3(encoding)) {
|
|
10961
10961
|
callback = encoding;
|
|
10962
10962
|
encoding = null;
|
|
10963
10963
|
}
|
|
@@ -11158,7 +11158,7 @@ var require_follow_redirects = __commonJS({
|
|
|
11158
11158
|
if (redirectUrl.protocol !== currentUrlParts.protocol && redirectUrl.protocol !== "https:" || redirectUrl.host !== currentHost && !isSubdomain(redirectUrl.host, currentHost)) {
|
|
11159
11159
|
removeMatchingHeaders(/^(?:(?:proxy-)?authorization|cookie)$/i, this._options.headers);
|
|
11160
11160
|
}
|
|
11161
|
-
if (
|
|
11161
|
+
if (isFunction3(beforeRedirect)) {
|
|
11162
11162
|
var responseDetails = {
|
|
11163
11163
|
headers: response.headers,
|
|
11164
11164
|
statusCode
|
|
@@ -11193,7 +11193,7 @@ var require_follow_redirects = __commonJS({
|
|
|
11193
11193
|
options = validateUrl(input);
|
|
11194
11194
|
input = { protocol };
|
|
11195
11195
|
}
|
|
11196
|
-
if (
|
|
11196
|
+
if (isFunction3(options)) {
|
|
11197
11197
|
callback = options;
|
|
11198
11198
|
options = null;
|
|
11199
11199
|
}
|
|
@@ -11273,7 +11273,7 @@ var require_follow_redirects = __commonJS({
|
|
|
11273
11273
|
}
|
|
11274
11274
|
function createErrorType(code, message, baseClass) {
|
|
11275
11275
|
function CustomError(properties) {
|
|
11276
|
-
if (
|
|
11276
|
+
if (isFunction3(Error.captureStackTrace)) {
|
|
11277
11277
|
Error.captureStackTrace(this, this.constructor);
|
|
11278
11278
|
}
|
|
11279
11279
|
Object.assign(this, properties || {});
|
|
@@ -11308,7 +11308,7 @@ var require_follow_redirects = __commonJS({
|
|
|
11308
11308
|
function isString2(value) {
|
|
11309
11309
|
return typeof value === "string" || value instanceof String;
|
|
11310
11310
|
}
|
|
11311
|
-
function
|
|
11311
|
+
function isFunction3(value) {
|
|
11312
11312
|
return typeof value === "function";
|
|
11313
11313
|
}
|
|
11314
11314
|
function isBuffer2(value) {
|
|
@@ -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,
|
|
@@ -13652,7 +13661,7 @@ var _global = (() => {
|
|
|
13652
13661
|
})();
|
|
13653
13662
|
var isContextDefined = (context) => !isUndefined(context) && context !== _global;
|
|
13654
13663
|
function merge() {
|
|
13655
|
-
const { caseless } = isContextDefined(this) && this || {};
|
|
13664
|
+
const { caseless, skipUndefined } = isContextDefined(this) && this || {};
|
|
13656
13665
|
const result = {};
|
|
13657
13666
|
const assignValue = (val, key) => {
|
|
13658
13667
|
const targetKey = caseless && findKey(result, key) || key;
|
|
@@ -13662,7 +13671,7 @@ function merge() {
|
|
|
13662
13671
|
result[targetKey] = merge({}, val);
|
|
13663
13672
|
} else if (isArray(val)) {
|
|
13664
13673
|
result[targetKey] = val.slice();
|
|
13665
|
-
} else {
|
|
13674
|
+
} else if (!skipUndefined || !isUndefined(val)) {
|
|
13666
13675
|
result[targetKey] = val;
|
|
13667
13676
|
}
|
|
13668
13677
|
};
|
|
@@ -13998,9 +14007,13 @@ AxiosError.from = (error, code, config2, request, response, customProps) => {
|
|
|
13998
14007
|
}, (prop) => {
|
|
13999
14008
|
return prop !== "isAxiosError";
|
|
14000
14009
|
});
|
|
14001
|
-
|
|
14002
|
-
|
|
14003
|
-
axiosError
|
|
14010
|
+
const msg = error && error.message ? error.message : "Error";
|
|
14011
|
+
const errCode = code == null && error ? error.code : code;
|
|
14012
|
+
AxiosError.call(axiosError, msg, errCode, config2, request, response);
|
|
14013
|
+
if (error && axiosError.cause == null) {
|
|
14014
|
+
Object.defineProperty(axiosError, "cause", { value: error, configurable: true });
|
|
14015
|
+
}
|
|
14016
|
+
axiosError.name = error && error.name || "Error";
|
|
14004
14017
|
customProps && Object.assign(axiosError, customProps);
|
|
14005
14018
|
return axiosError;
|
|
14006
14019
|
};
|
|
@@ -14163,7 +14176,7 @@ var AxiosURLSearchParams_default = AxiosURLSearchParams;
|
|
|
14163
14176
|
|
|
14164
14177
|
// node_modules/axios/lib/helpers/buildURL.js
|
|
14165
14178
|
function encode2(val) {
|
|
14166
|
-
return encodeURIComponent(val).replace(/%3A/gi, ":").replace(/%24/g, "$").replace(/%2C/gi, ",").replace(/%20/g, "+")
|
|
14179
|
+
return encodeURIComponent(val).replace(/%3A/gi, ":").replace(/%24/g, "$").replace(/%2C/gi, ",").replace(/%20/g, "+");
|
|
14167
14180
|
}
|
|
14168
14181
|
function buildURL(url2, params, options) {
|
|
14169
14182
|
if (!params) {
|
|
@@ -14461,7 +14474,7 @@ var defaults = {
|
|
|
14461
14474
|
const silentJSONParsing = transitional2 && transitional2.silentJSONParsing;
|
|
14462
14475
|
const strictJSONParsing = !silentJSONParsing && JSONRequested;
|
|
14463
14476
|
try {
|
|
14464
|
-
return JSON.parse(data);
|
|
14477
|
+
return JSON.parse(data, this.parseReviver);
|
|
14465
14478
|
} catch (e) {
|
|
14466
14479
|
if (strictJSONParsing) {
|
|
14467
14480
|
if (e.name === "SyntaxError") {
|
|
@@ -14848,7 +14861,7 @@ var import_follow_redirects = __toESM(require_follow_redirects(), 1);
|
|
|
14848
14861
|
var import_zlib = __toESM(require("zlib"), 1);
|
|
14849
14862
|
|
|
14850
14863
|
// node_modules/axios/lib/env/data.js
|
|
14851
|
-
var VERSION = "1.
|
|
14864
|
+
var VERSION = "1.12.2";
|
|
14852
14865
|
|
|
14853
14866
|
// node_modules/axios/lib/helpers/parseProtocol.js
|
|
14854
14867
|
function parseProtocol(url2) {
|
|
@@ -15247,6 +15260,60 @@ var progressEventDecorator = (total, throttled) => {
|
|
|
15247
15260
|
};
|
|
15248
15261
|
var asyncDecorator = (fn) => (...args) => utils_default.asap(() => fn(...args));
|
|
15249
15262
|
|
|
15263
|
+
// node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js
|
|
15264
|
+
function estimateDataURLDecodedBytes(url2) {
|
|
15265
|
+
if (!url2 || typeof url2 !== "string")
|
|
15266
|
+
return 0;
|
|
15267
|
+
if (!url2.startsWith("data:"))
|
|
15268
|
+
return 0;
|
|
15269
|
+
const comma = url2.indexOf(",");
|
|
15270
|
+
if (comma < 0)
|
|
15271
|
+
return 0;
|
|
15272
|
+
const meta = url2.slice(5, comma);
|
|
15273
|
+
const body = url2.slice(comma + 1);
|
|
15274
|
+
const isBase64 = /;base64/i.test(meta);
|
|
15275
|
+
if (isBase64) {
|
|
15276
|
+
let effectiveLen = body.length;
|
|
15277
|
+
const len = body.length;
|
|
15278
|
+
for (let i = 0; i < len; i++) {
|
|
15279
|
+
if (body.charCodeAt(i) === 37 && i + 2 < len) {
|
|
15280
|
+
const a = body.charCodeAt(i + 1);
|
|
15281
|
+
const b = body.charCodeAt(i + 2);
|
|
15282
|
+
const isHex = (a >= 48 && a <= 57 || a >= 65 && a <= 70 || a >= 97 && a <= 102) && (b >= 48 && b <= 57 || b >= 65 && b <= 70 || b >= 97 && b <= 102);
|
|
15283
|
+
if (isHex) {
|
|
15284
|
+
effectiveLen -= 2;
|
|
15285
|
+
i += 2;
|
|
15286
|
+
}
|
|
15287
|
+
}
|
|
15288
|
+
}
|
|
15289
|
+
let pad = 0;
|
|
15290
|
+
let idx = len - 1;
|
|
15291
|
+
const tailIsPct3D = (j) => j >= 2 && body.charCodeAt(j - 2) === 37 && // '%'
|
|
15292
|
+
body.charCodeAt(j - 1) === 51 && // '3'
|
|
15293
|
+
(body.charCodeAt(j) === 68 || body.charCodeAt(j) === 100);
|
|
15294
|
+
if (idx >= 0) {
|
|
15295
|
+
if (body.charCodeAt(idx) === 61) {
|
|
15296
|
+
pad++;
|
|
15297
|
+
idx--;
|
|
15298
|
+
} else if (tailIsPct3D(idx)) {
|
|
15299
|
+
pad++;
|
|
15300
|
+
idx -= 3;
|
|
15301
|
+
}
|
|
15302
|
+
}
|
|
15303
|
+
if (pad === 1 && idx >= 0) {
|
|
15304
|
+
if (body.charCodeAt(idx) === 61) {
|
|
15305
|
+
pad++;
|
|
15306
|
+
} else if (tailIsPct3D(idx)) {
|
|
15307
|
+
pad++;
|
|
15308
|
+
}
|
|
15309
|
+
}
|
|
15310
|
+
const groups = Math.floor(effectiveLen / 4);
|
|
15311
|
+
const bytes = groups * 3 - (pad || 0);
|
|
15312
|
+
return bytes > 0 ? bytes : 0;
|
|
15313
|
+
}
|
|
15314
|
+
return Buffer.byteLength(body, "utf8");
|
|
15315
|
+
}
|
|
15316
|
+
|
|
15250
15317
|
// node_modules/axios/lib/adapters/http.js
|
|
15251
15318
|
var zlibOptions = {
|
|
15252
15319
|
flush: import_zlib.default.constants.Z_SYNC_FLUSH,
|
|
@@ -15390,6 +15457,17 @@ var http_default = isHttpAdapterSupported && function httpAdapter(config2) {
|
|
|
15390
15457
|
const parsed = new URL(fullPath, platform_default.hasBrowserEnv ? platform_default.origin : void 0);
|
|
15391
15458
|
const protocol = parsed.protocol || supportedProtocols[0];
|
|
15392
15459
|
if (protocol === "data:") {
|
|
15460
|
+
if (config2.maxContentLength > -1) {
|
|
15461
|
+
const dataUrl = String(config2.url || fullPath || "");
|
|
15462
|
+
const estimated = estimateDataURLDecodedBytes(dataUrl);
|
|
15463
|
+
if (estimated > config2.maxContentLength) {
|
|
15464
|
+
return reject(new AxiosError_default(
|
|
15465
|
+
"maxContentLength size of " + config2.maxContentLength + " exceeded",
|
|
15466
|
+
AxiosError_default.ERR_BAD_RESPONSE,
|
|
15467
|
+
config2
|
|
15468
|
+
));
|
|
15469
|
+
}
|
|
15470
|
+
}
|
|
15393
15471
|
let convertedData;
|
|
15394
15472
|
if (method !== "GET") {
|
|
15395
15473
|
return settle(resolve, reject, {
|
|
@@ -15885,13 +15963,17 @@ var resolveConfig_default = (config2) => {
|
|
|
15885
15963
|
"Basic " + btoa((auth.username || "") + ":" + (auth.password ? unescape(encodeURIComponent(auth.password)) : ""))
|
|
15886
15964
|
);
|
|
15887
15965
|
}
|
|
15888
|
-
let contentType;
|
|
15889
15966
|
if (utils_default.isFormData(data)) {
|
|
15890
15967
|
if (platform_default.hasStandardBrowserEnv || platform_default.hasStandardBrowserWebWorkerEnv) {
|
|
15891
15968
|
headers.setContentType(void 0);
|
|
15892
|
-
} else if ((
|
|
15893
|
-
const
|
|
15894
|
-
|
|
15969
|
+
} else if (utils_default.isFunction(data.getHeaders)) {
|
|
15970
|
+
const formHeaders = data.getHeaders();
|
|
15971
|
+
const allowedHeaders = ["content-type", "content-length"];
|
|
15972
|
+
Object.entries(formHeaders).forEach(([key, val]) => {
|
|
15973
|
+
if (allowedHeaders.includes(key.toLowerCase())) {
|
|
15974
|
+
headers.set(key, val);
|
|
15975
|
+
}
|
|
15976
|
+
});
|
|
15895
15977
|
}
|
|
15896
15978
|
}
|
|
15897
15979
|
if (platform_default.hasStandardBrowserEnv) {
|
|
@@ -15971,8 +16053,11 @@ var xhr_default = isXHRAdapterSupported && function(config2) {
|
|
|
15971
16053
|
reject(new AxiosError_default("Request aborted", AxiosError_default.ECONNABORTED, config2, request));
|
|
15972
16054
|
request = null;
|
|
15973
16055
|
};
|
|
15974
|
-
request.onerror = function handleError() {
|
|
15975
|
-
|
|
16056
|
+
request.onerror = function handleError(event) {
|
|
16057
|
+
const msg = event && event.message ? event.message : "Network Error";
|
|
16058
|
+
const err = new AxiosError_default(msg, AxiosError_default.ERR_NETWORK, config2, request);
|
|
16059
|
+
err.event = event || null;
|
|
16060
|
+
reject(err);
|
|
15976
16061
|
request = null;
|
|
15977
16062
|
};
|
|
15978
16063
|
request.ontimeout = function handleTimeout() {
|
|
@@ -16147,9 +16232,16 @@ var trackStream = (stream4, chunkSize, onProgress, onFinish) => {
|
|
|
16147
16232
|
};
|
|
16148
16233
|
|
|
16149
16234
|
// node_modules/axios/lib/adapters/fetch.js
|
|
16150
|
-
var
|
|
16151
|
-
var
|
|
16152
|
-
var
|
|
16235
|
+
var DEFAULT_CHUNK_SIZE = 64 * 1024;
|
|
16236
|
+
var { isFunction: isFunction2 } = utils_default;
|
|
16237
|
+
var globalFetchAPI = (({ Request, Response }) => ({
|
|
16238
|
+
Request,
|
|
16239
|
+
Response
|
|
16240
|
+
}))(utils_default.global);
|
|
16241
|
+
var {
|
|
16242
|
+
ReadableStream: ReadableStream2,
|
|
16243
|
+
TextEncoder: TextEncoder2
|
|
16244
|
+
} = utils_default.global;
|
|
16153
16245
|
var test = (fn, ...args) => {
|
|
16154
16246
|
try {
|
|
16155
16247
|
return !!fn(...args);
|
|
@@ -16157,164 +16249,204 @@ var test = (fn, ...args) => {
|
|
|
16157
16249
|
return false;
|
|
16158
16250
|
}
|
|
16159
16251
|
};
|
|
16160
|
-
var
|
|
16161
|
-
|
|
16162
|
-
|
|
16163
|
-
|
|
16164
|
-
|
|
16165
|
-
|
|
16166
|
-
|
|
16167
|
-
|
|
16168
|
-
|
|
16169
|
-
|
|
16170
|
-
return duplexAccessed && !hasContentType;
|
|
16171
|
-
});
|
|
16172
|
-
var DEFAULT_CHUNK_SIZE = 64 * 1024;
|
|
16173
|
-
var supportsResponseStream = isReadableStreamSupported && test(() => utils_default.isReadableStream(new Response("").body));
|
|
16174
|
-
var resolvers = {
|
|
16175
|
-
stream: supportsResponseStream && ((res) => res.body)
|
|
16176
|
-
};
|
|
16177
|
-
isFetchSupported && ((res) => {
|
|
16178
|
-
["text", "arrayBuffer", "blob", "formData", "stream"].forEach((type) => {
|
|
16179
|
-
!resolvers[type] && (resolvers[type] = utils_default.isFunction(res[type]) ? (res2) => res2[type]() : (_, config2) => {
|
|
16180
|
-
throw new AxiosError_default(`Response type '${type}' is not supported`, AxiosError_default.ERR_NOT_SUPPORT, config2);
|
|
16181
|
-
});
|
|
16182
|
-
});
|
|
16183
|
-
})(new Response());
|
|
16184
|
-
var getBodyLength = async (body) => {
|
|
16185
|
-
if (body == null) {
|
|
16186
|
-
return 0;
|
|
16187
|
-
}
|
|
16188
|
-
if (utils_default.isBlob(body)) {
|
|
16189
|
-
return body.size;
|
|
16252
|
+
var factory = (env) => {
|
|
16253
|
+
env = utils_default.merge.call({
|
|
16254
|
+
skipUndefined: true
|
|
16255
|
+
}, globalFetchAPI, env);
|
|
16256
|
+
const { fetch: envFetch, Request, Response } = env;
|
|
16257
|
+
const isFetchSupported = envFetch ? isFunction2(envFetch) : typeof fetch === "function";
|
|
16258
|
+
const isRequestSupported = isFunction2(Request);
|
|
16259
|
+
const isResponseSupported = isFunction2(Response);
|
|
16260
|
+
if (!isFetchSupported) {
|
|
16261
|
+
return false;
|
|
16190
16262
|
}
|
|
16191
|
-
|
|
16192
|
-
|
|
16263
|
+
const isReadableStreamSupported = isFetchSupported && isFunction2(ReadableStream2);
|
|
16264
|
+
const encodeText = isFetchSupported && (typeof TextEncoder2 === "function" ? ((encoder) => (str) => encoder.encode(str))(new TextEncoder2()) : async (str) => new Uint8Array(await new Request(str).arrayBuffer()));
|
|
16265
|
+
const supportsRequestStream = isRequestSupported && isReadableStreamSupported && test(() => {
|
|
16266
|
+
let duplexAccessed = false;
|
|
16267
|
+
const hasContentType = new Request(platform_default.origin, {
|
|
16268
|
+
body: new ReadableStream2(),
|
|
16193
16269
|
method: "POST",
|
|
16194
|
-
|
|
16195
|
-
|
|
16196
|
-
|
|
16197
|
-
|
|
16198
|
-
|
|
16199
|
-
return
|
|
16200
|
-
}
|
|
16201
|
-
if (utils_default.isURLSearchParams(body)) {
|
|
16202
|
-
body = body + "";
|
|
16203
|
-
}
|
|
16204
|
-
if (utils_default.isString(body)) {
|
|
16205
|
-
return (await encodeText(body)).byteLength;
|
|
16206
|
-
}
|
|
16207
|
-
};
|
|
16208
|
-
var resolveBodyLength = async (headers, body) => {
|
|
16209
|
-
const length = utils_default.toFiniteNumber(headers.getContentLength());
|
|
16210
|
-
return length == null ? getBodyLength(body) : length;
|
|
16211
|
-
};
|
|
16212
|
-
var fetch_default = isFetchSupported && (async (config2) => {
|
|
16213
|
-
let {
|
|
16214
|
-
url: url2,
|
|
16215
|
-
method,
|
|
16216
|
-
data,
|
|
16217
|
-
signal,
|
|
16218
|
-
cancelToken,
|
|
16219
|
-
timeout,
|
|
16220
|
-
onDownloadProgress,
|
|
16221
|
-
onUploadProgress,
|
|
16222
|
-
responseType,
|
|
16223
|
-
headers,
|
|
16224
|
-
withCredentials = "same-origin",
|
|
16225
|
-
fetchOptions
|
|
16226
|
-
} = resolveConfig_default(config2);
|
|
16227
|
-
responseType = responseType ? (responseType + "").toLowerCase() : "text";
|
|
16228
|
-
let composedSignal = composeSignals_default([signal, cancelToken && cancelToken.toAbortSignal()], timeout);
|
|
16229
|
-
let request;
|
|
16230
|
-
const unsubscribe = composedSignal && composedSignal.unsubscribe && (() => {
|
|
16231
|
-
composedSignal.unsubscribe();
|
|
16270
|
+
get duplex() {
|
|
16271
|
+
duplexAccessed = true;
|
|
16272
|
+
return "half";
|
|
16273
|
+
}
|
|
16274
|
+
}).headers.has("Content-Type");
|
|
16275
|
+
return duplexAccessed && !hasContentType;
|
|
16232
16276
|
});
|
|
16233
|
-
|
|
16234
|
-
|
|
16235
|
-
|
|
16236
|
-
|
|
16277
|
+
const supportsResponseStream = isResponseSupported && isReadableStreamSupported && test(() => utils_default.isReadableStream(new Response("").body));
|
|
16278
|
+
const resolvers = {
|
|
16279
|
+
stream: supportsResponseStream && ((res) => res.body)
|
|
16280
|
+
};
|
|
16281
|
+
isFetchSupported && (() => {
|
|
16282
|
+
["text", "arrayBuffer", "blob", "formData", "stream"].forEach((type) => {
|
|
16283
|
+
!resolvers[type] && (resolvers[type] = (res, config2) => {
|
|
16284
|
+
let method = res && res[type];
|
|
16285
|
+
if (method) {
|
|
16286
|
+
return method.call(res);
|
|
16287
|
+
}
|
|
16288
|
+
throw new AxiosError_default(`Response type '${type}' is not supported`, AxiosError_default.ERR_NOT_SUPPORT, config2);
|
|
16289
|
+
});
|
|
16290
|
+
});
|
|
16291
|
+
})();
|
|
16292
|
+
const getBodyLength = async (body) => {
|
|
16293
|
+
if (body == null) {
|
|
16294
|
+
return 0;
|
|
16295
|
+
}
|
|
16296
|
+
if (utils_default.isBlob(body)) {
|
|
16297
|
+
return body.size;
|
|
16298
|
+
}
|
|
16299
|
+
if (utils_default.isSpecCompliantForm(body)) {
|
|
16300
|
+
const _request = new Request(platform_default.origin, {
|
|
16237
16301
|
method: "POST",
|
|
16238
|
-
body
|
|
16239
|
-
duplex: "half"
|
|
16302
|
+
body
|
|
16240
16303
|
});
|
|
16241
|
-
|
|
16242
|
-
if (utils_default.isFormData(data) && (contentTypeHeader = _request.headers.get("content-type"))) {
|
|
16243
|
-
headers.setContentType(contentTypeHeader);
|
|
16244
|
-
}
|
|
16245
|
-
if (_request.body) {
|
|
16246
|
-
const [onProgress, flush] = progressEventDecorator(
|
|
16247
|
-
requestContentLength,
|
|
16248
|
-
progressEventReducer(asyncDecorator(onUploadProgress))
|
|
16249
|
-
);
|
|
16250
|
-
data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush);
|
|
16251
|
-
}
|
|
16304
|
+
return (await _request.arrayBuffer()).byteLength;
|
|
16252
16305
|
}
|
|
16253
|
-
if (
|
|
16254
|
-
|
|
16306
|
+
if (utils_default.isArrayBufferView(body) || utils_default.isArrayBuffer(body)) {
|
|
16307
|
+
return body.byteLength;
|
|
16255
16308
|
}
|
|
16256
|
-
|
|
16257
|
-
|
|
16258
|
-
...fetchOptions,
|
|
16259
|
-
signal: composedSignal,
|
|
16260
|
-
method: method.toUpperCase(),
|
|
16261
|
-
headers: headers.normalize().toJSON(),
|
|
16262
|
-
body: data,
|
|
16263
|
-
duplex: "half",
|
|
16264
|
-
credentials: isCredentialsSupported ? withCredentials : void 0
|
|
16265
|
-
});
|
|
16266
|
-
let response = await fetch(request, fetchOptions);
|
|
16267
|
-
const isStreamResponse = supportsResponseStream && (responseType === "stream" || responseType === "response");
|
|
16268
|
-
if (supportsResponseStream && (onDownloadProgress || isStreamResponse && unsubscribe)) {
|
|
16269
|
-
const options = {};
|
|
16270
|
-
["status", "statusText", "headers"].forEach((prop) => {
|
|
16271
|
-
options[prop] = response[prop];
|
|
16272
|
-
});
|
|
16273
|
-
const responseContentLength = utils_default.toFiniteNumber(response.headers.get("content-length"));
|
|
16274
|
-
const [onProgress, flush] = onDownloadProgress && progressEventDecorator(
|
|
16275
|
-
responseContentLength,
|
|
16276
|
-
progressEventReducer(asyncDecorator(onDownloadProgress), true)
|
|
16277
|
-
) || [];
|
|
16278
|
-
response = new Response(
|
|
16279
|
-
trackStream(response.body, DEFAULT_CHUNK_SIZE, onProgress, () => {
|
|
16280
|
-
flush && flush();
|
|
16281
|
-
unsubscribe && unsubscribe();
|
|
16282
|
-
}),
|
|
16283
|
-
options
|
|
16284
|
-
);
|
|
16309
|
+
if (utils_default.isURLSearchParams(body)) {
|
|
16310
|
+
body = body + "";
|
|
16285
16311
|
}
|
|
16286
|
-
|
|
16287
|
-
|
|
16288
|
-
|
|
16289
|
-
|
|
16290
|
-
|
|
16291
|
-
|
|
16292
|
-
|
|
16293
|
-
|
|
16294
|
-
|
|
16295
|
-
|
|
16296
|
-
|
|
16297
|
-
|
|
16312
|
+
if (utils_default.isString(body)) {
|
|
16313
|
+
return (await encodeText(body)).byteLength;
|
|
16314
|
+
}
|
|
16315
|
+
};
|
|
16316
|
+
const resolveBodyLength = async (headers, body) => {
|
|
16317
|
+
const length = utils_default.toFiniteNumber(headers.getContentLength());
|
|
16318
|
+
return length == null ? getBodyLength(body) : length;
|
|
16319
|
+
};
|
|
16320
|
+
return async (config2) => {
|
|
16321
|
+
let {
|
|
16322
|
+
url: url2,
|
|
16323
|
+
method,
|
|
16324
|
+
data,
|
|
16325
|
+
signal,
|
|
16326
|
+
cancelToken,
|
|
16327
|
+
timeout,
|
|
16328
|
+
onDownloadProgress,
|
|
16329
|
+
onUploadProgress,
|
|
16330
|
+
responseType,
|
|
16331
|
+
headers,
|
|
16332
|
+
withCredentials = "same-origin",
|
|
16333
|
+
fetchOptions
|
|
16334
|
+
} = resolveConfig_default(config2);
|
|
16335
|
+
let _fetch = envFetch || fetch;
|
|
16336
|
+
responseType = responseType ? (responseType + "").toLowerCase() : "text";
|
|
16337
|
+
let composedSignal = composeSignals_default([signal, cancelToken && cancelToken.toAbortSignal()], timeout);
|
|
16338
|
+
let request = null;
|
|
16339
|
+
const unsubscribe = composedSignal && composedSignal.unsubscribe && (() => {
|
|
16340
|
+
composedSignal.unsubscribe();
|
|
16298
16341
|
});
|
|
16299
|
-
|
|
16300
|
-
|
|
16301
|
-
|
|
16302
|
-
|
|
16303
|
-
|
|
16304
|
-
|
|
16305
|
-
|
|
16342
|
+
let requestContentLength;
|
|
16343
|
+
try {
|
|
16344
|
+
if (onUploadProgress && supportsRequestStream && method !== "get" && method !== "head" && (requestContentLength = await resolveBodyLength(headers, data)) !== 0) {
|
|
16345
|
+
let _request = new Request(url2, {
|
|
16346
|
+
method: "POST",
|
|
16347
|
+
body: data,
|
|
16348
|
+
duplex: "half"
|
|
16349
|
+
});
|
|
16350
|
+
let contentTypeHeader;
|
|
16351
|
+
if (utils_default.isFormData(data) && (contentTypeHeader = _request.headers.get("content-type"))) {
|
|
16352
|
+
headers.setContentType(contentTypeHeader);
|
|
16306
16353
|
}
|
|
16307
|
-
|
|
16354
|
+
if (_request.body) {
|
|
16355
|
+
const [onProgress, flush] = progressEventDecorator(
|
|
16356
|
+
requestContentLength,
|
|
16357
|
+
progressEventReducer(asyncDecorator(onUploadProgress))
|
|
16358
|
+
);
|
|
16359
|
+
data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush);
|
|
16360
|
+
}
|
|
16361
|
+
}
|
|
16362
|
+
if (!utils_default.isString(withCredentials)) {
|
|
16363
|
+
withCredentials = withCredentials ? "include" : "omit";
|
|
16364
|
+
}
|
|
16365
|
+
const isCredentialsSupported = isRequestSupported && "credentials" in Request.prototype;
|
|
16366
|
+
const resolvedOptions = {
|
|
16367
|
+
...fetchOptions,
|
|
16368
|
+
signal: composedSignal,
|
|
16369
|
+
method: method.toUpperCase(),
|
|
16370
|
+
headers: headers.normalize().toJSON(),
|
|
16371
|
+
body: data,
|
|
16372
|
+
duplex: "half",
|
|
16373
|
+
credentials: isCredentialsSupported ? withCredentials : void 0
|
|
16374
|
+
};
|
|
16375
|
+
request = isRequestSupported && new Request(url2, resolvedOptions);
|
|
16376
|
+
let response = await (isRequestSupported ? _fetch(request, fetchOptions) : _fetch(url2, resolvedOptions));
|
|
16377
|
+
const isStreamResponse = supportsResponseStream && (responseType === "stream" || responseType === "response");
|
|
16378
|
+
if (supportsResponseStream && (onDownloadProgress || isStreamResponse && unsubscribe)) {
|
|
16379
|
+
const options = {};
|
|
16380
|
+
["status", "statusText", "headers"].forEach((prop) => {
|
|
16381
|
+
options[prop] = response[prop];
|
|
16382
|
+
});
|
|
16383
|
+
const responseContentLength = utils_default.toFiniteNumber(response.headers.get("content-length"));
|
|
16384
|
+
const [onProgress, flush] = onDownloadProgress && progressEventDecorator(
|
|
16385
|
+
responseContentLength,
|
|
16386
|
+
progressEventReducer(asyncDecorator(onDownloadProgress), true)
|
|
16387
|
+
) || [];
|
|
16388
|
+
response = new Response(
|
|
16389
|
+
trackStream(response.body, DEFAULT_CHUNK_SIZE, onProgress, () => {
|
|
16390
|
+
flush && flush();
|
|
16391
|
+
unsubscribe && unsubscribe();
|
|
16392
|
+
}),
|
|
16393
|
+
options
|
|
16394
|
+
);
|
|
16395
|
+
}
|
|
16396
|
+
responseType = responseType || "text";
|
|
16397
|
+
let responseData = await resolvers[utils_default.findKey(resolvers, responseType) || "text"](response, config2);
|
|
16398
|
+
!isStreamResponse && unsubscribe && unsubscribe();
|
|
16399
|
+
return await new Promise((resolve, reject) => {
|
|
16400
|
+
settle(resolve, reject, {
|
|
16401
|
+
data: responseData,
|
|
16402
|
+
headers: AxiosHeaders_default.from(response.headers),
|
|
16403
|
+
status: response.status,
|
|
16404
|
+
statusText: response.statusText,
|
|
16405
|
+
config: config2,
|
|
16406
|
+
request
|
|
16407
|
+
});
|
|
16408
|
+
});
|
|
16409
|
+
} catch (err) {
|
|
16410
|
+
unsubscribe && unsubscribe();
|
|
16411
|
+
if (err && err.name === "TypeError" && /Load failed|fetch/i.test(err.message)) {
|
|
16412
|
+
throw Object.assign(
|
|
16413
|
+
new AxiosError_default("Network Error", AxiosError_default.ERR_NETWORK, config2, request),
|
|
16414
|
+
{
|
|
16415
|
+
cause: err.cause || err
|
|
16416
|
+
}
|
|
16417
|
+
);
|
|
16418
|
+
}
|
|
16419
|
+
throw AxiosError_default.from(err, err && err.code, config2, request);
|
|
16308
16420
|
}
|
|
16309
|
-
|
|
16310
|
-
|
|
16311
|
-
|
|
16421
|
+
};
|
|
16422
|
+
};
|
|
16423
|
+
var seedCache = /* @__PURE__ */ new Map();
|
|
16424
|
+
var getFetch = (config2) => {
|
|
16425
|
+
let env = config2 ? config2.env : {};
|
|
16426
|
+
const { fetch: fetch2, Request, Response } = env;
|
|
16427
|
+
const seeds = [
|
|
16428
|
+
Request,
|
|
16429
|
+
Response,
|
|
16430
|
+
fetch2
|
|
16431
|
+
];
|
|
16432
|
+
let len = seeds.length, i = len, seed, target, map = seedCache;
|
|
16433
|
+
while (i--) {
|
|
16434
|
+
seed = seeds[i];
|
|
16435
|
+
target = map.get(seed);
|
|
16436
|
+
target === void 0 && map.set(seed, target = i ? /* @__PURE__ */ new Map() : factory(env));
|
|
16437
|
+
map = target;
|
|
16438
|
+
}
|
|
16439
|
+
return target;
|
|
16440
|
+
};
|
|
16441
|
+
var adapter = getFetch();
|
|
16312
16442
|
|
|
16313
16443
|
// node_modules/axios/lib/adapters/adapters.js
|
|
16314
16444
|
var knownAdapters = {
|
|
16315
16445
|
http: http_default,
|
|
16316
16446
|
xhr: xhr_default,
|
|
16317
|
-
fetch:
|
|
16447
|
+
fetch: {
|
|
16448
|
+
get: getFetch
|
|
16449
|
+
}
|
|
16318
16450
|
};
|
|
16319
16451
|
utils_default.forEach(knownAdapters, (fn, value) => {
|
|
16320
16452
|
if (fn) {
|
|
@@ -16326,30 +16458,30 @@ utils_default.forEach(knownAdapters, (fn, value) => {
|
|
|
16326
16458
|
}
|
|
16327
16459
|
});
|
|
16328
16460
|
var renderReason = (reason) => `- ${reason}`;
|
|
16329
|
-
var isResolvedHandle = (
|
|
16461
|
+
var isResolvedHandle = (adapter2) => utils_default.isFunction(adapter2) || adapter2 === null || adapter2 === false;
|
|
16330
16462
|
var adapters_default = {
|
|
16331
|
-
getAdapter: (adapters) => {
|
|
16463
|
+
getAdapter: (adapters, config2) => {
|
|
16332
16464
|
adapters = utils_default.isArray(adapters) ? adapters : [adapters];
|
|
16333
16465
|
const { length } = adapters;
|
|
16334
16466
|
let nameOrAdapter;
|
|
16335
|
-
let
|
|
16467
|
+
let adapter2;
|
|
16336
16468
|
const rejectedReasons = {};
|
|
16337
16469
|
for (let i = 0; i < length; i++) {
|
|
16338
16470
|
nameOrAdapter = adapters[i];
|
|
16339
16471
|
let id;
|
|
16340
|
-
|
|
16472
|
+
adapter2 = nameOrAdapter;
|
|
16341
16473
|
if (!isResolvedHandle(nameOrAdapter)) {
|
|
16342
|
-
|
|
16343
|
-
if (
|
|
16474
|
+
adapter2 = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()];
|
|
16475
|
+
if (adapter2 === void 0) {
|
|
16344
16476
|
throw new AxiosError_default(`Unknown adapter '${id}'`);
|
|
16345
16477
|
}
|
|
16346
16478
|
}
|
|
16347
|
-
if (
|
|
16479
|
+
if (adapter2 && (utils_default.isFunction(adapter2) || (adapter2 = adapter2.get(config2)))) {
|
|
16348
16480
|
break;
|
|
16349
16481
|
}
|
|
16350
|
-
rejectedReasons[id || "#" + i] =
|
|
16482
|
+
rejectedReasons[id || "#" + i] = adapter2;
|
|
16351
16483
|
}
|
|
16352
|
-
if (!
|
|
16484
|
+
if (!adapter2) {
|
|
16353
16485
|
const reasons = Object.entries(rejectedReasons).map(
|
|
16354
16486
|
([id, state]) => `adapter ${id} ` + (state === false ? "is not supported by the environment" : "is not available in the build")
|
|
16355
16487
|
);
|
|
@@ -16359,7 +16491,7 @@ var adapters_default = {
|
|
|
16359
16491
|
"ERR_NOT_SUPPORT"
|
|
16360
16492
|
);
|
|
16361
16493
|
}
|
|
16362
|
-
return
|
|
16494
|
+
return adapter2;
|
|
16363
16495
|
},
|
|
16364
16496
|
adapters: knownAdapters
|
|
16365
16497
|
};
|
|
@@ -16383,8 +16515,8 @@ function dispatchRequest(config2) {
|
|
|
16383
16515
|
if (["post", "put", "patch"].indexOf(config2.method) !== -1) {
|
|
16384
16516
|
config2.headers.setContentType("application/x-www-form-urlencoded", false);
|
|
16385
16517
|
}
|
|
16386
|
-
const
|
|
16387
|
-
return
|
|
16518
|
+
const adapter2 = adapters_default.getAdapter(config2.adapter || defaults_default.adapter, config2);
|
|
16519
|
+
return adapter2(config2).then(function onAdapterResolution(response) {
|
|
16388
16520
|
throwIfCancellationRequested(config2);
|
|
16389
16521
|
response.data = transformData.call(
|
|
16390
16522
|
config2,
|
|
@@ -16590,7 +16722,6 @@ var Axios = class {
|
|
|
16590
16722
|
}
|
|
16591
16723
|
len = requestInterceptorChain.length;
|
|
16592
16724
|
let newConfig = config2;
|
|
16593
|
-
i = 0;
|
|
16594
16725
|
while (i < len) {
|
|
16595
16726
|
const onFulfilled = requestInterceptorChain[i++];
|
|
16596
16727
|
const onRejected = requestInterceptorChain[i++];
|
|
@@ -26312,11 +26443,8 @@ function useDivisionController() {
|
|
|
26312
26443
|
return;
|
|
26313
26444
|
}
|
|
26314
26445
|
try {
|
|
26315
|
-
const
|
|
26316
|
-
res.json(
|
|
26317
|
-
message: "Successfully retrieved division.",
|
|
26318
|
-
data: { division }
|
|
26319
|
-
});
|
|
26446
|
+
const data = await _getById(id);
|
|
26447
|
+
res.json(data);
|
|
26320
26448
|
return;
|
|
26321
26449
|
} catch (error2) {
|
|
26322
26450
|
next(error2);
|
|
@@ -26403,16 +26531,17 @@ var import_joi31 = __toESM(require("joi"));
|
|
|
26403
26531
|
var import_mongodb37 = require("mongodb");
|
|
26404
26532
|
var schemaSchool = import_joi31.default.object({
|
|
26405
26533
|
_id: import_joi31.default.string().hex().optional().allow("", null),
|
|
26406
|
-
id: import_joi31.default.string().
|
|
26407
|
-
name: import_joi31.default.string().
|
|
26408
|
-
country: import_joi31.default.string().
|
|
26409
|
-
address: import_joi31.default.string().
|
|
26534
|
+
id: import_joi31.default.string().optional().allow("", null),
|
|
26535
|
+
name: import_joi31.default.string().optional().allow("", null),
|
|
26536
|
+
country: import_joi31.default.string().optional().allow("", null),
|
|
26537
|
+
address: import_joi31.default.string().optional().allow("", null),
|
|
26410
26538
|
continuedAddress: import_joi31.default.string().optional().allow("", null),
|
|
26411
|
-
city: import_joi31.default.string().required(),
|
|
26412
|
-
province: import_joi31.default.string().required(),
|
|
26413
|
-
|
|
26414
|
-
|
|
26415
|
-
|
|
26539
|
+
city: import_joi31.default.string().required().allow("", null),
|
|
26540
|
+
province: import_joi31.default.string().required().allow("", null),
|
|
26541
|
+
district: import_joi31.default.string().optional().allow("", null),
|
|
26542
|
+
postalCode: import_joi31.default.string().required().allow("", null),
|
|
26543
|
+
courses: import_joi31.default.array().items(import_joi31.default.string()).optional(),
|
|
26544
|
+
principalName: import_joi31.default.string().required().allow("", null),
|
|
26416
26545
|
principalEmail: import_joi31.default.string().email().optional().allow("", null),
|
|
26417
26546
|
principalNumber: import_joi31.default.string().optional().allow("", null),
|
|
26418
26547
|
region: import_joi31.default.string().hex().required(),
|
|
@@ -26422,7 +26551,7 @@ var schemaSchool = import_joi31.default.object({
|
|
|
26422
26551
|
status: import_joi31.default.string().optional().allow(null, ""),
|
|
26423
26552
|
createdAt: import_joi31.default.date().optional().allow("", null),
|
|
26424
26553
|
updatedAt: import_joi31.default.date().optional().allow("", null),
|
|
26425
|
-
createdBy: import_joi31.default.string().hex().
|
|
26554
|
+
createdBy: import_joi31.default.string().hex().optional().allow("", null)
|
|
26426
26555
|
});
|
|
26427
26556
|
function MSchool(value) {
|
|
26428
26557
|
const { error } = schemaSchool.validate(value);
|
|
@@ -26461,15 +26590,15 @@ function MSchool(value) {
|
|
|
26461
26590
|
_id: value._id ? value._id : new import_mongodb37.ObjectId(),
|
|
26462
26591
|
id: value.id,
|
|
26463
26592
|
name: value.name,
|
|
26464
|
-
country: value.country,
|
|
26465
|
-
address: value.address,
|
|
26593
|
+
country: value.country ?? "",
|
|
26594
|
+
address: value.address ?? "",
|
|
26466
26595
|
continuedAddress: value.continuedAddress ?? "",
|
|
26467
|
-
city: value.city,
|
|
26468
|
-
province: value.province,
|
|
26469
|
-
postalCode: value.postalCode,
|
|
26596
|
+
city: value.city ?? "",
|
|
26597
|
+
province: value.province ?? "",
|
|
26598
|
+
postalCode: value.postalCode ?? "",
|
|
26470
26599
|
courses: value.courses || [],
|
|
26471
|
-
principalName: value.principalName,
|
|
26472
|
-
principalEmail: value.principalEmail,
|
|
26600
|
+
principalName: value.principalName ?? "",
|
|
26601
|
+
principalEmail: value.principalEmail ?? "",
|
|
26473
26602
|
principalNumber: value.principalNumber ?? "",
|
|
26474
26603
|
region: value.region,
|
|
26475
26604
|
regionName: value.regionName ?? "",
|
|
@@ -26478,7 +26607,7 @@ function MSchool(value) {
|
|
|
26478
26607
|
createdAt: value.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
26479
26608
|
updatedAt: value.updatedAt ?? "",
|
|
26480
26609
|
status: value.status ?? "pending",
|
|
26481
|
-
createdBy: value.createdBy
|
|
26610
|
+
createdBy: value.createdBy ?? ""
|
|
26482
26611
|
};
|
|
26483
26612
|
}
|
|
26484
26613
|
|
|
@@ -26746,8 +26875,16 @@ function useSchoolRepo() {
|
|
|
26746
26875
|
|
|
26747
26876
|
// src/services/school.service.ts
|
|
26748
26877
|
var import_nodejs_utils64 = require("@eeplatform/nodejs-utils");
|
|
26878
|
+
var XLSX = __toESM(require("xlsx"));
|
|
26879
|
+
var Papa = __toESM(require("papaparse"));
|
|
26880
|
+
var BSON = __toESM(require("bson"));
|
|
26749
26881
|
function useSchoolService() {
|
|
26750
|
-
const {
|
|
26882
|
+
const {
|
|
26883
|
+
add: addSchool,
|
|
26884
|
+
getPendingByCreatedBy,
|
|
26885
|
+
updateStatusById,
|
|
26886
|
+
getPendingById
|
|
26887
|
+
} = useSchoolRepo();
|
|
26751
26888
|
const { addRole } = useRoleRepo();
|
|
26752
26889
|
const { getUserById } = useUserRepo();
|
|
26753
26890
|
const { add: addMember } = useMemberRepo();
|
|
@@ -26764,7 +26901,7 @@ function useSchoolService() {
|
|
|
26764
26901
|
}
|
|
26765
26902
|
try {
|
|
26766
26903
|
value.status = "pending";
|
|
26767
|
-
await
|
|
26904
|
+
await addSchool(value);
|
|
26768
26905
|
return "Request to register school has been sent successfully. Please wait for approval.";
|
|
26769
26906
|
} catch (error2) {
|
|
26770
26907
|
throw error2;
|
|
@@ -26783,7 +26920,7 @@ function useSchoolService() {
|
|
|
26783
26920
|
session.startTransaction();
|
|
26784
26921
|
school.status = "approved";
|
|
26785
26922
|
await updateStatusById(id, "active", session);
|
|
26786
|
-
const roleType = "school";
|
|
26923
|
+
const roleType = "basic-edu-school";
|
|
26787
26924
|
const roleName = "Admin";
|
|
26788
26925
|
const roleId = await addRole(
|
|
26789
26926
|
{
|
|
@@ -26828,9 +26965,245 @@ function useSchoolService() {
|
|
|
26828
26965
|
await session.endSession();
|
|
26829
26966
|
}
|
|
26830
26967
|
}
|
|
26968
|
+
async function add(value) {
|
|
26969
|
+
const { error } = schemaSchool.validate(value);
|
|
26970
|
+
if (error) {
|
|
26971
|
+
throw new import_nodejs_utils64.BadRequestError(error.message);
|
|
26972
|
+
}
|
|
26973
|
+
const session = import_nodejs_utils64.useAtlas.getClient()?.startSession();
|
|
26974
|
+
if (!session) {
|
|
26975
|
+
throw new Error("Unable to start session for school service.");
|
|
26976
|
+
}
|
|
26977
|
+
try {
|
|
26978
|
+
session.startTransaction();
|
|
26979
|
+
value.status = "active";
|
|
26980
|
+
const schoolId = await addSchool(value, session);
|
|
26981
|
+
const roleType = "basic-edu-school";
|
|
26982
|
+
const roleName = "Admin";
|
|
26983
|
+
const roleId = await addRole(
|
|
26984
|
+
{
|
|
26985
|
+
id: schoolId.toString(),
|
|
26986
|
+
type: roleType,
|
|
26987
|
+
name: roleName,
|
|
26988
|
+
permissions: ["*"],
|
|
26989
|
+
status: "active",
|
|
26990
|
+
default: true
|
|
26991
|
+
},
|
|
26992
|
+
session
|
|
26993
|
+
);
|
|
26994
|
+
if (!value.createdBy) {
|
|
26995
|
+
throw new import_nodejs_utils64.BadRequestError("School must have a creator.");
|
|
26996
|
+
}
|
|
26997
|
+
const user = await getUserById(value.createdBy ?? "");
|
|
26998
|
+
if (!user) {
|
|
26999
|
+
throw new import_nodejs_utils64.BadRequestError("User not found for the school creator.");
|
|
27000
|
+
}
|
|
27001
|
+
await addMember(
|
|
27002
|
+
{
|
|
27003
|
+
org: schoolId.toString(),
|
|
27004
|
+
orgName: value.name,
|
|
27005
|
+
user: value.createdBy.toString(),
|
|
27006
|
+
name: `${user.firstName} ${user.lastName}`,
|
|
27007
|
+
role: roleId.toString(),
|
|
27008
|
+
roleName,
|
|
27009
|
+
type: roleType
|
|
27010
|
+
},
|
|
27011
|
+
session
|
|
27012
|
+
);
|
|
27013
|
+
await session.commitTransaction();
|
|
27014
|
+
return "School has been added and activated successfully.";
|
|
27015
|
+
} catch (error2) {
|
|
27016
|
+
import_nodejs_utils64.logger.log({
|
|
27017
|
+
level: "error",
|
|
27018
|
+
message: `Error adding school: ${error2.message}`
|
|
27019
|
+
});
|
|
27020
|
+
await session.abortTransaction();
|
|
27021
|
+
throw error2;
|
|
27022
|
+
} finally {
|
|
27023
|
+
await session.endSession();
|
|
27024
|
+
}
|
|
27025
|
+
}
|
|
27026
|
+
async function addBulk(file, region, division) {
|
|
27027
|
+
const MAX_SIZE = 16 * 1024 * 1024;
|
|
27028
|
+
if (file.size > MAX_SIZE) {
|
|
27029
|
+
throw new import_nodejs_utils64.BadRequestError(
|
|
27030
|
+
"File size exceeds 16MB limit. Please use a smaller file to ensure transaction compatibility."
|
|
27031
|
+
);
|
|
27032
|
+
}
|
|
27033
|
+
let schools = [];
|
|
27034
|
+
const validatedSchools = [];
|
|
27035
|
+
const totalSize = validatedSchools.reduce(
|
|
27036
|
+
(sum, school) => sum + BSON.calculateObjectSize(school),
|
|
27037
|
+
0
|
|
27038
|
+
);
|
|
27039
|
+
try {
|
|
27040
|
+
if (file.mimetype.includes("sheet") || file.originalname.endsWith(".xlsx") || file.originalname.endsWith(".xls")) {
|
|
27041
|
+
const workbook = XLSX.read(file.buffer);
|
|
27042
|
+
const sheetName = workbook.SheetNames[0];
|
|
27043
|
+
const worksheet = workbook.Sheets[sheetName];
|
|
27044
|
+
schools = XLSX.utils.sheet_to_json(worksheet);
|
|
27045
|
+
} else if (file.mimetype.includes("csv") || file.originalname.endsWith(".csv")) {
|
|
27046
|
+
const csvText = file.buffer.toString("utf8");
|
|
27047
|
+
const parseResult = Papa.parse(csvText, {
|
|
27048
|
+
header: true,
|
|
27049
|
+
skipEmptyLines: true,
|
|
27050
|
+
transformHeader: (header) => header.trim()
|
|
27051
|
+
});
|
|
27052
|
+
if (parseResult.errors.length > 0) {
|
|
27053
|
+
throw new import_nodejs_utils64.BadRequestError(
|
|
27054
|
+
`CSV parsing error: ${parseResult.errors[0].message}`
|
|
27055
|
+
);
|
|
27056
|
+
}
|
|
27057
|
+
schools = parseResult.data;
|
|
27058
|
+
} else {
|
|
27059
|
+
throw new import_nodejs_utils64.BadRequestError(
|
|
27060
|
+
"Unsupported file type. Please upload an Excel (.xlsx, .xls) or CSV (.csv) file."
|
|
27061
|
+
);
|
|
27062
|
+
}
|
|
27063
|
+
if (!schools || schools.length === 0) {
|
|
27064
|
+
throw new import_nodejs_utils64.BadRequestError("No data found in the uploaded file.");
|
|
27065
|
+
}
|
|
27066
|
+
const errors = [];
|
|
27067
|
+
for (let i = 0; i < schools.length; i++) {
|
|
27068
|
+
const schoolData = schools[i];
|
|
27069
|
+
const rowNumber = i + 1;
|
|
27070
|
+
try {
|
|
27071
|
+
const schoolName = schoolData.schoolName || schoolData.name || "";
|
|
27072
|
+
const schoolId = schoolData.schoolId || schoolData.id || "";
|
|
27073
|
+
const district = schoolData.district || "";
|
|
27074
|
+
if (!schoolName.trim()) {
|
|
27075
|
+
errors.push(`Row ${rowNumber}: School name is required`);
|
|
27076
|
+
continue;
|
|
27077
|
+
}
|
|
27078
|
+
if (!schoolId.trim()) {
|
|
27079
|
+
errors.push(`Row ${rowNumber}: School ID is required`);
|
|
27080
|
+
continue;
|
|
27081
|
+
}
|
|
27082
|
+
if (!district.trim()) {
|
|
27083
|
+
errors.push(`Row ${rowNumber}: District is required`);
|
|
27084
|
+
continue;
|
|
27085
|
+
}
|
|
27086
|
+
const school = {
|
|
27087
|
+
id: schoolId.trim(),
|
|
27088
|
+
name: schoolName.trim(),
|
|
27089
|
+
country: "Philippines",
|
|
27090
|
+
// Default country
|
|
27091
|
+
address: district.trim(),
|
|
27092
|
+
// Use district as address
|
|
27093
|
+
continuedAddress: "",
|
|
27094
|
+
city: district.trim(),
|
|
27095
|
+
// Use district as city
|
|
27096
|
+
province: "",
|
|
27097
|
+
// Will need to be set based on region/division
|
|
27098
|
+
postalCode: "",
|
|
27099
|
+
courses: [],
|
|
27100
|
+
// Empty array for courses
|
|
27101
|
+
principalName: "",
|
|
27102
|
+
principalEmail: "",
|
|
27103
|
+
principalNumber: "",
|
|
27104
|
+
region,
|
|
27105
|
+
regionName: "",
|
|
27106
|
+
// Will be populated from region lookup
|
|
27107
|
+
division,
|
|
27108
|
+
divisionName: "",
|
|
27109
|
+
// Will be populated from division lookup
|
|
27110
|
+
status: "active"
|
|
27111
|
+
};
|
|
27112
|
+
const { error } = schemaSchool.validate(school);
|
|
27113
|
+
if (error) {
|
|
27114
|
+
errors.push(`Row ${rowNumber}: ${error.message}`);
|
|
27115
|
+
continue;
|
|
27116
|
+
}
|
|
27117
|
+
validatedSchools.push(school);
|
|
27118
|
+
} catch (error) {
|
|
27119
|
+
errors.push(
|
|
27120
|
+
`Row ${rowNumber}: ${error.message || "Invalid data format"}`
|
|
27121
|
+
);
|
|
27122
|
+
}
|
|
27123
|
+
}
|
|
27124
|
+
if (errors.length > 0) {
|
|
27125
|
+
throw new import_nodejs_utils64.BadRequestError(
|
|
27126
|
+
`Validation errors found:
|
|
27127
|
+
${errors.slice(0, 10).join("\n")}${errors.length > 10 ? `
|
|
27128
|
+
... and ${errors.length - 10} more errors` : ""}`
|
|
27129
|
+
);
|
|
27130
|
+
}
|
|
27131
|
+
if (validatedSchools.length === 0) {
|
|
27132
|
+
throw new import_nodejs_utils64.BadRequestError(
|
|
27133
|
+
"No valid school records found after validation."
|
|
27134
|
+
);
|
|
27135
|
+
}
|
|
27136
|
+
if (totalSize > MAX_SIZE) {
|
|
27137
|
+
throw new import_nodejs_utils64.BadRequestError(
|
|
27138
|
+
`Data payload (${Math.round(
|
|
27139
|
+
totalSize / 1024 / 1024
|
|
27140
|
+
)}MB) exceeds MongoDB transaction limit of 16MB. Please reduce the number of records or split into smaller files.`
|
|
27141
|
+
);
|
|
27142
|
+
}
|
|
27143
|
+
} catch (error) {
|
|
27144
|
+
if (error instanceof import_nodejs_utils64.BadRequestError) {
|
|
27145
|
+
throw error;
|
|
27146
|
+
}
|
|
27147
|
+
throw new import_nodejs_utils64.BadRequestError(`File processing error: ${error.message}`);
|
|
27148
|
+
}
|
|
27149
|
+
const session = import_nodejs_utils64.useAtlas.getClient()?.startSession();
|
|
27150
|
+
if (!session) {
|
|
27151
|
+
throw new Error("Unable to start session for bulk school upload.");
|
|
27152
|
+
}
|
|
27153
|
+
try {
|
|
27154
|
+
session.startTransaction();
|
|
27155
|
+
const results = {
|
|
27156
|
+
successful: 0,
|
|
27157
|
+
failed: 0,
|
|
27158
|
+
errors: []
|
|
27159
|
+
};
|
|
27160
|
+
for (const school of validatedSchools) {
|
|
27161
|
+
try {
|
|
27162
|
+
const schoolId = await addSchool(school, session);
|
|
27163
|
+
await addRole(
|
|
27164
|
+
{
|
|
27165
|
+
id: schoolId.toString(),
|
|
27166
|
+
type: "basic-edu-school",
|
|
27167
|
+
name: "Admin",
|
|
27168
|
+
permissions: ["*"],
|
|
27169
|
+
status: "active",
|
|
27170
|
+
default: true
|
|
27171
|
+
},
|
|
27172
|
+
session
|
|
27173
|
+
);
|
|
27174
|
+
results.successful++;
|
|
27175
|
+
} catch (error) {
|
|
27176
|
+
results.failed++;
|
|
27177
|
+
results.errors.push(`School "${school.name}": ${error.message}`);
|
|
27178
|
+
}
|
|
27179
|
+
}
|
|
27180
|
+
await session.commitTransaction();
|
|
27181
|
+
return {
|
|
27182
|
+
message: `Bulk upload completed. ${results.successful} schools added successfully.`,
|
|
27183
|
+
details: {
|
|
27184
|
+
successful: results.successful,
|
|
27185
|
+
failed: results.failed,
|
|
27186
|
+
total: validatedSchools.length,
|
|
27187
|
+
totalSizeMB: Math.round(totalSize / 1024 / 1024 * 100) / 100,
|
|
27188
|
+
errors: results.errors
|
|
27189
|
+
}
|
|
27190
|
+
};
|
|
27191
|
+
} catch (error) {
|
|
27192
|
+
import_nodejs_utils64.logger.log({
|
|
27193
|
+
level: "error",
|
|
27194
|
+
message: `Error in bulk school upload: ${error.message}`
|
|
27195
|
+
});
|
|
27196
|
+
await session.abortTransaction();
|
|
27197
|
+
throw error;
|
|
27198
|
+
} finally {
|
|
27199
|
+
await session.endSession();
|
|
27200
|
+
}
|
|
27201
|
+
}
|
|
26831
27202
|
return {
|
|
26832
27203
|
register,
|
|
26833
|
-
approve
|
|
27204
|
+
approve,
|
|
27205
|
+
add,
|
|
27206
|
+
addBulk
|
|
26834
27207
|
};
|
|
26835
27208
|
}
|
|
26836
27209
|
|
|
@@ -26839,11 +27212,16 @@ var import_nodejs_utils65 = require("@eeplatform/nodejs-utils");
|
|
|
26839
27212
|
var import_joi32 = __toESM(require("joi"));
|
|
26840
27213
|
function useSchoolController() {
|
|
26841
27214
|
const {
|
|
26842
|
-
add: _add,
|
|
26843
27215
|
getAll: _getAll,
|
|
26844
27216
|
getPendingByCreatedBy: _getPendingByCreatedBy,
|
|
26845
27217
|
updateStatusById: _updateStatusById
|
|
26846
27218
|
} = useSchoolRepo();
|
|
27219
|
+
const {
|
|
27220
|
+
add: _addSchool,
|
|
27221
|
+
register: _registerSchool,
|
|
27222
|
+
approve,
|
|
27223
|
+
addBulk: _addBulk
|
|
27224
|
+
} = useSchoolService();
|
|
26847
27225
|
async function add(req, res, next) {
|
|
26848
27226
|
const payload = req.body;
|
|
26849
27227
|
const { error } = schemaSchool.validate(payload);
|
|
@@ -26852,8 +27230,8 @@ function useSchoolController() {
|
|
|
26852
27230
|
return;
|
|
26853
27231
|
}
|
|
26854
27232
|
try {
|
|
26855
|
-
const
|
|
26856
|
-
res.status(201).json(
|
|
27233
|
+
const result = await _addSchool(payload);
|
|
27234
|
+
res.status(201).json({ message: result });
|
|
26857
27235
|
return;
|
|
26858
27236
|
} catch (error2) {
|
|
26859
27237
|
next(error2);
|
|
@@ -26943,7 +27321,6 @@ function useSchoolController() {
|
|
|
26943
27321
|
next(error2);
|
|
26944
27322
|
}
|
|
26945
27323
|
}
|
|
26946
|
-
const { register: _registerSchool, approve } = useSchoolService();
|
|
26947
27324
|
async function registerSchool(req, res, next) {
|
|
26948
27325
|
const payload = req.body;
|
|
26949
27326
|
const { error } = schemaSchool.validate(payload);
|
|
@@ -26978,13 +27355,38 @@ function useSchoolController() {
|
|
|
26978
27355
|
next(error2);
|
|
26979
27356
|
}
|
|
26980
27357
|
}
|
|
27358
|
+
async function addBulk(req, res, next) {
|
|
27359
|
+
if (!req.file) {
|
|
27360
|
+
res.status(400).send("File is required!");
|
|
27361
|
+
return;
|
|
27362
|
+
}
|
|
27363
|
+
const { region, division } = req.body;
|
|
27364
|
+
const validation = import_joi32.default.object({
|
|
27365
|
+
region: import_joi32.default.string().hex().required(),
|
|
27366
|
+
division: import_joi32.default.string().hex().required()
|
|
27367
|
+
});
|
|
27368
|
+
const { error } = validation.validate({ region, division });
|
|
27369
|
+
if (error) {
|
|
27370
|
+
next(new import_nodejs_utils65.BadRequestError(`Validation error: ${error.message}`));
|
|
27371
|
+
return;
|
|
27372
|
+
}
|
|
27373
|
+
try {
|
|
27374
|
+
const result = await _addBulk(req.file, region, division);
|
|
27375
|
+
res.status(201).json(result);
|
|
27376
|
+
return;
|
|
27377
|
+
} catch (error2) {
|
|
27378
|
+
next(error2);
|
|
27379
|
+
return;
|
|
27380
|
+
}
|
|
27381
|
+
}
|
|
26981
27382
|
return {
|
|
26982
27383
|
add,
|
|
26983
27384
|
getAll,
|
|
26984
27385
|
getByCreatedBy,
|
|
26985
27386
|
updateStatusById,
|
|
26986
27387
|
registerSchool,
|
|
26987
|
-
approveSchool
|
|
27388
|
+
approveSchool,
|
|
27389
|
+
addBulk
|
|
26988
27390
|
};
|
|
26989
27391
|
}
|
|
26990
27392
|
|
|
@@ -27935,7 +28337,10 @@ function useBuildingUnitService() {
|
|
|
27935
28337
|
try {
|
|
27936
28338
|
await session.startTransaction();
|
|
27937
28339
|
for (let index = 0; index < value.qty; index++) {
|
|
27938
|
-
await _add(
|
|
28340
|
+
await _add(
|
|
28341
|
+
{ ...value.building, name: `${value.building.name} ${index + 1}` },
|
|
28342
|
+
session
|
|
28343
|
+
);
|
|
27939
28344
|
}
|
|
27940
28345
|
await session.commitTransaction();
|
|
27941
28346
|
return "Building unit added successfully.";
|
|
@@ -29427,12 +29832,23 @@ var import_joi41 = __toESM(require("joi"));
|
|
|
29427
29832
|
var import_mongodb46 = require("mongodb");
|
|
29428
29833
|
var schemaPlantilla = import_joi41.default.object({
|
|
29429
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(),
|
|
29430
29839
|
itemNumber: import_joi41.default.string().required(),
|
|
29431
29840
|
positionTitle: import_joi41.default.string().required(),
|
|
29432
|
-
|
|
29433
|
-
|
|
29841
|
+
positionCategory: import_joi41.default.string().required(),
|
|
29842
|
+
region: import_joi41.default.string().hex().optional().allow(null, ""),
|
|
29843
|
+
regionName: import_joi41.default.string().optional().allow(null, ""),
|
|
29844
|
+
division: import_joi41.default.string().hex().optional().allow(null, ""),
|
|
29845
|
+
divisionName: import_joi41.default.string().optional().allow(null, ""),
|
|
29846
|
+
salaryGrade: import_joi41.default.number().required(),
|
|
29847
|
+
employeeName: import_joi41.default.string().optional().allow(null, ""),
|
|
29848
|
+
annualSalary: import_joi41.default.number().optional().allow(null, 0),
|
|
29849
|
+
monthlySalary: import_joi41.default.number().optional().allow(null, 0),
|
|
29434
29850
|
status: import_joi41.default.string().required(),
|
|
29435
|
-
|
|
29851
|
+
employee: import_joi41.default.string().hex().optional().allow(null, ""),
|
|
29436
29852
|
createdAt: import_joi41.default.date().iso().optional().allow(null, ""),
|
|
29437
29853
|
updatedAt: import_joi41.default.date().iso().optional().allow(null, ""),
|
|
29438
29854
|
deletedAt: import_joi41.default.date().iso().optional().allow(null, "")
|
|
@@ -29449,21 +29865,25 @@ function MPlantilla(data) {
|
|
|
29449
29865
|
throw new import_nodejs_utils82.BadRequestError("Invalid _id.");
|
|
29450
29866
|
}
|
|
29451
29867
|
}
|
|
29452
|
-
if (data.employeeId && typeof data.employeeId === "string") {
|
|
29453
|
-
try {
|
|
29454
|
-
data.employeeId = new import_mongodb46.ObjectId(data.employeeId);
|
|
29455
|
-
} catch (error2) {
|
|
29456
|
-
throw new import_nodejs_utils82.BadRequestError("Invalid employeeId.");
|
|
29457
|
-
}
|
|
29458
|
-
}
|
|
29459
29868
|
return {
|
|
29460
29869
|
_id: data._id,
|
|
29461
29870
|
itemNumber: data.itemNumber ?? "",
|
|
29462
29871
|
positionTitle: data.positionTitle ?? "",
|
|
29463
|
-
|
|
29464
|
-
officeAssignment: data.officeAssignment ?? "",
|
|
29872
|
+
positionCategory: data.positionCategory ?? "",
|
|
29465
29873
|
status: data.status ?? "active",
|
|
29466
|
-
|
|
29874
|
+
salaryGrade: data.salaryGrade ?? 0,
|
|
29875
|
+
monthlySalary: data.monthlySalary ?? 0,
|
|
29876
|
+
annualSalary: data.annualSalary ?? 0,
|
|
29877
|
+
region: data.region ?? "",
|
|
29878
|
+
regionName: data.regionName ?? "",
|
|
29879
|
+
division: data.division ?? "",
|
|
29880
|
+
divisionName: data.divisionName ?? "",
|
|
29881
|
+
org: data.org ?? "",
|
|
29882
|
+
orgUnitCode: data.orgUnitCode ?? "",
|
|
29883
|
+
employmentType: data.employmentType ?? "",
|
|
29884
|
+
personnelType: data.personnelType ?? "",
|
|
29885
|
+
employee: data.employee ?? "",
|
|
29886
|
+
employeeName: data.employeeName ?? "",
|
|
29467
29887
|
createdAt: data.createdAt ? new Date(data.createdAt) : /* @__PURE__ */ new Date(),
|
|
29468
29888
|
updatedAt: data.updatedAt ? new Date(data.updatedAt) : "",
|
|
29469
29889
|
deletedAt: data.deletedAt ? new Date(data.deletedAt) : ""
|
|
@@ -29492,11 +29912,14 @@ function usePlantillaRepo() {
|
|
|
29492
29912
|
throw new Error("Failed to create index on plantillas.");
|
|
29493
29913
|
}
|
|
29494
29914
|
}
|
|
29495
|
-
async function add(value, session) {
|
|
29915
|
+
async function add(value, session, clearCache = true) {
|
|
29916
|
+
console.log(value);
|
|
29496
29917
|
try {
|
|
29497
29918
|
value = MPlantilla(value);
|
|
29498
29919
|
const res = await collection.insertOne(value, { session });
|
|
29499
|
-
|
|
29920
|
+
if (clearCache) {
|
|
29921
|
+
delCachedData();
|
|
29922
|
+
}
|
|
29500
29923
|
return res.insertedId;
|
|
29501
29924
|
} catch (error) {
|
|
29502
29925
|
import_nodejs_utils83.logger.log({
|
|
@@ -29697,34 +30120,243 @@ function usePlantillaRepo() {
|
|
|
29697
30120
|
getAll,
|
|
29698
30121
|
getById,
|
|
29699
30122
|
updateById,
|
|
29700
|
-
deleteById
|
|
30123
|
+
deleteById,
|
|
30124
|
+
delCachedData
|
|
29701
30125
|
};
|
|
29702
30126
|
}
|
|
29703
30127
|
|
|
29704
30128
|
// src/controllers/plantilla.controller.ts
|
|
29705
|
-
var
|
|
30129
|
+
var import_nodejs_utils85 = require("@eeplatform/nodejs-utils");
|
|
29706
30130
|
var import_joi42 = __toESM(require("joi"));
|
|
29707
|
-
|
|
29708
|
-
|
|
29709
|
-
|
|
29710
|
-
|
|
29711
|
-
|
|
29712
|
-
|
|
30131
|
+
|
|
30132
|
+
// src/services/plantilla.service.ts
|
|
30133
|
+
var import_nodejs_utils84 = require("@eeplatform/nodejs-utils");
|
|
30134
|
+
var XLSX2 = __toESM(require("xlsx"));
|
|
30135
|
+
var Papa2 = __toESM(require("papaparse"));
|
|
30136
|
+
function usePlantillaService() {
|
|
30137
|
+
const { add: addPlantilla, delCachedData } = usePlantillaRepo();
|
|
30138
|
+
async function addBulk(file, region, division) {
|
|
30139
|
+
import_nodejs_utils84.logger.log({
|
|
30140
|
+
level: "info",
|
|
30141
|
+
message: `Starting plantilla bulk upload. File: ${file.originalname}, Size: ${file.size} bytes`
|
|
30142
|
+
});
|
|
30143
|
+
const MAX_SIZE = 16 * 1024 * 1024;
|
|
30144
|
+
let plantillas = [];
|
|
30145
|
+
let totalSize = 0;
|
|
30146
|
+
let validatedPlantillas = [];
|
|
30147
|
+
if (!file.buffer) {
|
|
30148
|
+
throw new import_nodejs_utils84.BadRequestError("File buffer is empty or corrupted");
|
|
30149
|
+
}
|
|
30150
|
+
try {
|
|
30151
|
+
const fileExtension = file.originalname.split(".").pop()?.toLowerCase();
|
|
30152
|
+
if (fileExtension === "csv") {
|
|
30153
|
+
const csvData = file.buffer.toString("utf-8");
|
|
30154
|
+
totalSize = Buffer.byteLength(csvData, "utf8");
|
|
30155
|
+
const parseResult = Papa2.parse(csvData, {
|
|
30156
|
+
header: true,
|
|
30157
|
+
skipEmptyLines: true,
|
|
30158
|
+
transformHeader: (header) => {
|
|
30159
|
+
return header.toLowerCase().replace(/\s+/g, "").replace(/[^\w]/g, "");
|
|
30160
|
+
}
|
|
30161
|
+
});
|
|
30162
|
+
if (parseResult.errors.length > 0) {
|
|
30163
|
+
throw new import_nodejs_utils84.BadRequestError(
|
|
30164
|
+
`CSV parsing errors: ${parseResult.errors.map((e) => e.message).join(", ")}`
|
|
30165
|
+
);
|
|
30166
|
+
}
|
|
30167
|
+
plantillas = parseResult.data;
|
|
30168
|
+
} else if (fileExtension === "xlsx" || fileExtension === "xls") {
|
|
30169
|
+
totalSize = file.buffer.length;
|
|
30170
|
+
const workbook = XLSX2.read(file.buffer, { type: "buffer" });
|
|
30171
|
+
const sheetName = workbook.SheetNames[0];
|
|
30172
|
+
const worksheet = workbook.Sheets[sheetName];
|
|
30173
|
+
plantillas = XLSX2.utils.sheet_to_json(worksheet, {
|
|
30174
|
+
header: 1,
|
|
30175
|
+
defval: ""
|
|
30176
|
+
});
|
|
30177
|
+
if (plantillas.length === 0) {
|
|
30178
|
+
throw new import_nodejs_utils84.BadRequestError("Excel file is empty.");
|
|
30179
|
+
}
|
|
30180
|
+
const headers = plantillas[0];
|
|
30181
|
+
const normalizedHeaders = headers.map(
|
|
30182
|
+
(header) => header.toLowerCase().replace(/\s+/g, "").replace(/[^\w]/g, "")
|
|
30183
|
+
);
|
|
30184
|
+
plantillas = plantillas.slice(1).map((row) => {
|
|
30185
|
+
const obj = {};
|
|
30186
|
+
normalizedHeaders.forEach((header, index) => {
|
|
30187
|
+
obj[header] = row[index] || "";
|
|
30188
|
+
});
|
|
30189
|
+
return obj;
|
|
30190
|
+
});
|
|
30191
|
+
} else {
|
|
30192
|
+
throw new import_nodejs_utils84.BadRequestError(
|
|
30193
|
+
"Unsupported file type. Please upload an Excel (.xlsx, .xls) or CSV (.csv) file."
|
|
30194
|
+
);
|
|
30195
|
+
}
|
|
30196
|
+
if (!plantillas || plantillas.length === 0) {
|
|
30197
|
+
throw new import_nodejs_utils84.BadRequestError("No data found in the uploaded file.");
|
|
30198
|
+
}
|
|
30199
|
+
const errors = [];
|
|
30200
|
+
for (let i = 0; i < plantillas.length; i++) {
|
|
30201
|
+
const plantillaData = plantillas[i];
|
|
30202
|
+
const rowNumber = i + 1;
|
|
30203
|
+
try {
|
|
30204
|
+
const itemNumber = plantillaData.itemnumber || plantillaData.item_number || "";
|
|
30205
|
+
const positionTitle = plantillaData.positiontitle || plantillaData.position_title || plantillaData.title || "";
|
|
30206
|
+
const positionCategory = plantillaData.positioncategory || plantillaData.position_category || "";
|
|
30207
|
+
const status = plantillaData.status || "active";
|
|
30208
|
+
if (!itemNumber.trim()) {
|
|
30209
|
+
errors.push(`Row ${rowNumber}: Item Number is required`);
|
|
30210
|
+
continue;
|
|
30211
|
+
}
|
|
30212
|
+
if (!positionTitle.trim()) {
|
|
30213
|
+
errors.push(`Row ${rowNumber}: Position Title is required`);
|
|
30214
|
+
continue;
|
|
30215
|
+
}
|
|
30216
|
+
if (!positionCategory.trim()) {
|
|
30217
|
+
errors.push(`Row ${rowNumber}: Position Category is required`);
|
|
30218
|
+
continue;
|
|
30219
|
+
}
|
|
30220
|
+
const plantilla = {
|
|
30221
|
+
itemNumber: itemNumber.trim(),
|
|
30222
|
+
positionTitle: positionTitle.trim(),
|
|
30223
|
+
positionCategory: positionCategory.trim(),
|
|
30224
|
+
salaryGrade: parseInt(
|
|
30225
|
+
plantillaData.salarygrade || plantillaData.salary_grade || "1"
|
|
30226
|
+
) || 1,
|
|
30227
|
+
org: "",
|
|
30228
|
+
personnelType: "",
|
|
30229
|
+
status: status.trim() || "active"
|
|
30230
|
+
};
|
|
30231
|
+
if (region)
|
|
30232
|
+
plantilla.region = region;
|
|
30233
|
+
if (division)
|
|
30234
|
+
plantilla.division = division;
|
|
30235
|
+
if (plantillaData.regionname || plantillaData.region_name) {
|
|
30236
|
+
plantilla.regionName = plantillaData.regionname || plantillaData.region_name;
|
|
30237
|
+
}
|
|
30238
|
+
if (plantillaData.divisionname || plantillaData.division_name) {
|
|
30239
|
+
plantilla.divisionName = plantillaData.divisionname || plantillaData.division_name;
|
|
30240
|
+
}
|
|
30241
|
+
if (plantillaData.employee) {
|
|
30242
|
+
plantilla.employee = plantillaData.employee;
|
|
30243
|
+
}
|
|
30244
|
+
if (plantillaData.annualsalary || plantillaData.annual_salary) {
|
|
30245
|
+
plantilla.annualSalary = parseFloat(
|
|
30246
|
+
plantillaData.annualsalary || plantillaData.annual_salary
|
|
30247
|
+
) || void 0;
|
|
30248
|
+
}
|
|
30249
|
+
if (plantillaData.monthlysalary || plantillaData.monthly_salary) {
|
|
30250
|
+
plantilla.monthlySalary = parseFloat(
|
|
30251
|
+
plantillaData.monthlysalary || plantillaData.monthly_salary
|
|
30252
|
+
) || void 0;
|
|
30253
|
+
}
|
|
30254
|
+
if (!plantilla.itemNumber || !plantilla.positionTitle || !plantilla.positionCategory) {
|
|
30255
|
+
errors.push(`Row ${rowNumber}: Missing required fields`);
|
|
30256
|
+
continue;
|
|
30257
|
+
}
|
|
30258
|
+
validatedPlantillas.push(plantilla);
|
|
30259
|
+
} catch (error) {
|
|
30260
|
+
errors.push(
|
|
30261
|
+
`Row ${rowNumber}: ${error.message || "Invalid data format"}`
|
|
30262
|
+
);
|
|
30263
|
+
}
|
|
30264
|
+
}
|
|
30265
|
+
if (errors.length > 0) {
|
|
30266
|
+
throw new import_nodejs_utils84.BadRequestError(
|
|
30267
|
+
`Validation errors found:
|
|
30268
|
+
${errors.slice(0, 10).join("\n")}${errors.length > 10 ? `
|
|
30269
|
+
... and ${errors.length - 10} more errors` : ""}`
|
|
30270
|
+
);
|
|
30271
|
+
}
|
|
30272
|
+
if (validatedPlantillas.length === 0) {
|
|
30273
|
+
throw new import_nodejs_utils84.BadRequestError(
|
|
30274
|
+
"No valid plantilla records found after validation."
|
|
30275
|
+
);
|
|
30276
|
+
}
|
|
30277
|
+
if (totalSize > MAX_SIZE) {
|
|
30278
|
+
throw new import_nodejs_utils84.BadRequestError(
|
|
30279
|
+
`Data payload (${Math.round(
|
|
30280
|
+
totalSize / 1024 / 1024
|
|
30281
|
+
)}MB) exceeds MongoDB transaction limit of 16MB. Please reduce the number of records or split into smaller files.`
|
|
30282
|
+
);
|
|
30283
|
+
}
|
|
30284
|
+
} catch (error) {
|
|
30285
|
+
if (error instanceof import_nodejs_utils84.BadRequestError) {
|
|
30286
|
+
throw error;
|
|
30287
|
+
}
|
|
30288
|
+
throw new import_nodejs_utils84.BadRequestError(`File processing error: ${error.message}`);
|
|
30289
|
+
}
|
|
30290
|
+
const session = import_nodejs_utils84.useAtlas.getClient()?.startSession();
|
|
30291
|
+
if (!session) {
|
|
30292
|
+
throw new Error("Unable to start session for bulk plantilla upload.");
|
|
30293
|
+
}
|
|
30294
|
+
import_nodejs_utils84.logger.log({
|
|
30295
|
+
level: "info",
|
|
30296
|
+
message: `Starting bulk plantilla upload with ${validatedPlantillas.length} records`
|
|
30297
|
+
});
|
|
30298
|
+
try {
|
|
30299
|
+
session.startTransaction();
|
|
30300
|
+
const results = {
|
|
30301
|
+
successful: 0,
|
|
30302
|
+
failed: 0,
|
|
30303
|
+
errors: []
|
|
30304
|
+
};
|
|
30305
|
+
const promises = [];
|
|
30306
|
+
for (let i = 0; i < validatedPlantillas.length; i++) {
|
|
30307
|
+
const plantilla = validatedPlantillas[i];
|
|
30308
|
+
promises.push(addPlantilla(plantilla, session, false));
|
|
30309
|
+
}
|
|
30310
|
+
await Promise.all(promises);
|
|
30311
|
+
await delCachedData();
|
|
30312
|
+
await session.commitTransaction();
|
|
30313
|
+
return {
|
|
30314
|
+
message: `Bulk upload completed. ${results.successful} plantillas added successfully.`,
|
|
30315
|
+
details: {
|
|
30316
|
+
successful: results.successful,
|
|
30317
|
+
failed: results.failed,
|
|
30318
|
+
total: validatedPlantillas.length,
|
|
30319
|
+
totalSizeMB: Math.round(totalSize / 1024 / 1024 * 100) / 100,
|
|
30320
|
+
errors: results.errors
|
|
30321
|
+
}
|
|
30322
|
+
};
|
|
30323
|
+
} catch (error) {
|
|
30324
|
+
import_nodejs_utils84.logger.log({
|
|
30325
|
+
level: "error",
|
|
30326
|
+
message: `Error in bulk plantilla upload: ${error.message}`
|
|
30327
|
+
});
|
|
30328
|
+
await session.abortTransaction();
|
|
30329
|
+
throw error;
|
|
30330
|
+
} finally {
|
|
30331
|
+
await session.endSession();
|
|
30332
|
+
}
|
|
30333
|
+
}
|
|
30334
|
+
return {
|
|
30335
|
+
addBulk
|
|
30336
|
+
};
|
|
30337
|
+
}
|
|
30338
|
+
|
|
30339
|
+
// src/controllers/plantilla.controller.ts
|
|
30340
|
+
function usePlantillaController() {
|
|
30341
|
+
const {
|
|
30342
|
+
add: _addPlantilla,
|
|
30343
|
+
getAll: _getAllPlantillas,
|
|
30344
|
+
getById: _getPlantillaById,
|
|
30345
|
+
updateById: _updatePlantillaById,
|
|
29713
30346
|
deleteById: _deletePlantillaById
|
|
29714
30347
|
} = usePlantillaRepo();
|
|
30348
|
+
const { addBulk: _addBulk } = usePlantillaService();
|
|
29715
30349
|
async function createPlantilla(req, res, next) {
|
|
29716
30350
|
const value = req.body;
|
|
29717
30351
|
const validation = import_joi42.default.object({
|
|
29718
30352
|
itemNumber: import_joi42.default.string().required(),
|
|
29719
30353
|
positionTitle: import_joi42.default.string().required(),
|
|
29720
|
-
|
|
29721
|
-
|
|
29722
|
-
status: import_joi42.default.string().required(),
|
|
29723
|
-
employeeId: import_joi42.default.string().hex().optional().allow(null, "")
|
|
30354
|
+
positionCategory: import_joi42.default.string().required(),
|
|
30355
|
+
status: import_joi42.default.string().required()
|
|
29724
30356
|
});
|
|
29725
30357
|
const { error } = validation.validate(value);
|
|
29726
30358
|
if (error) {
|
|
29727
|
-
next(new
|
|
30359
|
+
next(new import_nodejs_utils85.BadRequestError(error.message));
|
|
29728
30360
|
return;
|
|
29729
30361
|
}
|
|
29730
30362
|
try {
|
|
@@ -29742,12 +30374,12 @@ function usePlantillaController() {
|
|
|
29742
30374
|
const org = req.query.org ?? "";
|
|
29743
30375
|
const isPageNumber = isFinite(page);
|
|
29744
30376
|
if (!isPageNumber) {
|
|
29745
|
-
next(new
|
|
30377
|
+
next(new import_nodejs_utils85.BadRequestError("Invalid page number."));
|
|
29746
30378
|
return;
|
|
29747
30379
|
}
|
|
29748
30380
|
const isLimitNumber = isFinite(limit);
|
|
29749
30381
|
if (!isLimitNumber) {
|
|
29750
|
-
next(new
|
|
30382
|
+
next(new import_nodejs_utils85.BadRequestError("Invalid limit number."));
|
|
29751
30383
|
return;
|
|
29752
30384
|
}
|
|
29753
30385
|
const validation = import_joi42.default.object({
|
|
@@ -29758,7 +30390,7 @@ function usePlantillaController() {
|
|
|
29758
30390
|
});
|
|
29759
30391
|
const { error } = validation.validate({ page, limit, search, org });
|
|
29760
30392
|
if (error) {
|
|
29761
|
-
next(new
|
|
30393
|
+
next(new import_nodejs_utils85.BadRequestError(error.message));
|
|
29762
30394
|
return;
|
|
29763
30395
|
}
|
|
29764
30396
|
try {
|
|
@@ -29781,13 +30413,13 @@ function usePlantillaController() {
|
|
|
29781
30413
|
});
|
|
29782
30414
|
const { error } = validation.validate({ id });
|
|
29783
30415
|
if (error) {
|
|
29784
|
-
next(new
|
|
30416
|
+
next(new import_nodejs_utils85.BadRequestError(error.message));
|
|
29785
30417
|
return;
|
|
29786
30418
|
}
|
|
29787
30419
|
try {
|
|
29788
30420
|
const plantilla = await _getPlantillaById(id);
|
|
29789
30421
|
if (!plantilla) {
|
|
29790
|
-
next(new
|
|
30422
|
+
next(new import_nodejs_utils85.BadRequestError("Plantilla not found."));
|
|
29791
30423
|
return;
|
|
29792
30424
|
}
|
|
29793
30425
|
res.json(plantilla);
|
|
@@ -29801,19 +30433,20 @@ function usePlantillaController() {
|
|
|
29801
30433
|
const value = req.body;
|
|
29802
30434
|
const validation = import_joi42.default.object({
|
|
29803
30435
|
id: import_joi42.default.string().hex().required(),
|
|
29804
|
-
|
|
30436
|
+
employee: import_joi42.default.string().hex().optional().allow(null, ""),
|
|
29805
30437
|
status: import_joi42.default.string().optional(),
|
|
29806
|
-
positionTitle: import_joi42.default.string().optional()
|
|
30438
|
+
positionTitle: import_joi42.default.string().optional(),
|
|
30439
|
+
positionCategory: import_joi42.default.string().optional()
|
|
29807
30440
|
});
|
|
29808
30441
|
const { error } = validation.validate({ id, ...value });
|
|
29809
30442
|
if (error) {
|
|
29810
|
-
next(new
|
|
30443
|
+
next(new import_nodejs_utils85.BadRequestError(error.message));
|
|
29811
30444
|
return;
|
|
29812
30445
|
}
|
|
29813
30446
|
try {
|
|
29814
30447
|
const result = await _updatePlantillaById(id, value);
|
|
29815
30448
|
if (result.matchedCount === 0) {
|
|
29816
|
-
next(new
|
|
30449
|
+
next(new import_nodejs_utils85.BadRequestError("Plantilla not found."));
|
|
29817
30450
|
return;
|
|
29818
30451
|
}
|
|
29819
30452
|
res.json({ message: "Plantilla updated successfully" });
|
|
@@ -29829,13 +30462,13 @@ function usePlantillaController() {
|
|
|
29829
30462
|
});
|
|
29830
30463
|
const { error } = validation.validate({ id });
|
|
29831
30464
|
if (error) {
|
|
29832
|
-
next(new
|
|
30465
|
+
next(new import_nodejs_utils85.BadRequestError(error.message));
|
|
29833
30466
|
return;
|
|
29834
30467
|
}
|
|
29835
30468
|
try {
|
|
29836
30469
|
const result = await _deletePlantillaById(id);
|
|
29837
30470
|
if (result.matchedCount === 0) {
|
|
29838
|
-
next(new
|
|
30471
|
+
next(new import_nodejs_utils85.BadRequestError("Plantilla not found."));
|
|
29839
30472
|
return;
|
|
29840
30473
|
}
|
|
29841
30474
|
res.json({ message: "Plantilla deleted successfully" });
|
|
@@ -29844,12 +30477,1175 @@ function usePlantillaController() {
|
|
|
29844
30477
|
next(error2);
|
|
29845
30478
|
}
|
|
29846
30479
|
}
|
|
30480
|
+
async function bulkAddPlantillas(req, res, next) {
|
|
30481
|
+
if (!req.file) {
|
|
30482
|
+
res.status(400).send("File is required!");
|
|
30483
|
+
return;
|
|
30484
|
+
}
|
|
30485
|
+
const { region, division } = req.body;
|
|
30486
|
+
const validation = import_joi42.default.object({
|
|
30487
|
+
region: import_joi42.default.string().hex().optional(),
|
|
30488
|
+
division: import_joi42.default.string().hex().optional()
|
|
30489
|
+
});
|
|
30490
|
+
const { error } = validation.validate({ region, division });
|
|
30491
|
+
if (error) {
|
|
30492
|
+
next(new import_nodejs_utils85.BadRequestError(`Validation error: ${error.message}`));
|
|
30493
|
+
return;
|
|
30494
|
+
}
|
|
30495
|
+
if (!region && !division) {
|
|
30496
|
+
next(
|
|
30497
|
+
new import_nodejs_utils85.BadRequestError(
|
|
30498
|
+
"At least one of region or division must be provided"
|
|
30499
|
+
)
|
|
30500
|
+
);
|
|
30501
|
+
return;
|
|
30502
|
+
}
|
|
30503
|
+
try {
|
|
30504
|
+
const result = await _addBulk(req.file, region, division);
|
|
30505
|
+
res.status(201).json(result);
|
|
30506
|
+
return;
|
|
30507
|
+
} catch (error2) {
|
|
30508
|
+
next(error2);
|
|
30509
|
+
return;
|
|
30510
|
+
}
|
|
30511
|
+
}
|
|
29847
30512
|
return {
|
|
29848
30513
|
createPlantilla,
|
|
29849
30514
|
getAllPlantillas,
|
|
29850
30515
|
getPlantillaById,
|
|
29851
30516
|
updatePlantilla,
|
|
29852
|
-
deletePlantilla
|
|
30517
|
+
deletePlantilla,
|
|
30518
|
+
bulkAddPlantillas
|
|
30519
|
+
};
|
|
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
|
|
29853
31649
|
};
|
|
29854
31650
|
}
|
|
29855
31651
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -29874,12 +31670,14 @@ function usePlantillaController() {
|
|
|
29874
31670
|
MAsset,
|
|
29875
31671
|
MBuilding,
|
|
29876
31672
|
MBuildingUnit,
|
|
31673
|
+
MCurriculum,
|
|
29877
31674
|
MDivision,
|
|
29878
31675
|
MEntity,
|
|
29879
31676
|
MFile,
|
|
29880
31677
|
MMember,
|
|
29881
31678
|
MONGO_DB,
|
|
29882
31679
|
MONGO_URI,
|
|
31680
|
+
MOffice,
|
|
29883
31681
|
MOrder,
|
|
29884
31682
|
MOrg,
|
|
29885
31683
|
MPaymentMethod,
|
|
@@ -29920,7 +31718,9 @@ function usePlantillaController() {
|
|
|
29920
31718
|
schemaAssetUpdateOption,
|
|
29921
31719
|
schemaBuilding,
|
|
29922
31720
|
schemaBuildingUnit,
|
|
31721
|
+
schemaCurriculum,
|
|
29923
31722
|
schemaDivision,
|
|
31723
|
+
schemaOffice,
|
|
29924
31724
|
schemaPlantilla,
|
|
29925
31725
|
schemaRegion,
|
|
29926
31726
|
schemaSchool,
|
|
@@ -29938,6 +31738,8 @@ function usePlantillaController() {
|
|
|
29938
31738
|
useBuildingUnitRepo,
|
|
29939
31739
|
useCounterModel,
|
|
29940
31740
|
useCounterRepo,
|
|
31741
|
+
useCurriculumController,
|
|
31742
|
+
useCurriculumRepo,
|
|
29941
31743
|
useDivisionController,
|
|
29942
31744
|
useDivisionRepo,
|
|
29943
31745
|
useDivisionService,
|
|
@@ -29953,6 +31755,9 @@ function usePlantillaController() {
|
|
|
29953
31755
|
useInvoiceService,
|
|
29954
31756
|
useMemberController,
|
|
29955
31757
|
useMemberRepo,
|
|
31758
|
+
useOfficeController,
|
|
31759
|
+
useOfficeRepo,
|
|
31760
|
+
useOfficeService,
|
|
29956
31761
|
useOrderController,
|
|
29957
31762
|
useOrderRepo,
|
|
29958
31763
|
useOrgController,
|