@eeplatform/core 1.0.3 → 1.2.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 +138 -1
- package/dist/index.js +1113 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1120 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -25667,10 +25667,6 @@ function useRegionRepo() {
|
|
|
25667
25667
|
};
|
|
25668
25668
|
}
|
|
25669
25669
|
|
|
25670
|
-
// src/controllers/region.controller.ts
|
|
25671
|
-
import { BadRequestError as BadRequestError52 } from "@eeplatform/nodejs-utils";
|
|
25672
|
-
import Joi28 from "joi";
|
|
25673
|
-
|
|
25674
25670
|
// src/services/region.service.ts
|
|
25675
25671
|
import { useAtlas as useAtlas26 } from "@eeplatform/nodejs-utils";
|
|
25676
25672
|
function useRegionService() {
|
|
@@ -25710,6 +25706,8 @@ function useRegionService() {
|
|
|
25710
25706
|
}
|
|
25711
25707
|
|
|
25712
25708
|
// src/controllers/region.controller.ts
|
|
25709
|
+
import { BadRequestError as BadRequestError52 } from "@eeplatform/nodejs-utils";
|
|
25710
|
+
import Joi28 from "joi";
|
|
25713
25711
|
function useRegionController() {
|
|
25714
25712
|
const {
|
|
25715
25713
|
getAll: _getAll,
|
|
@@ -26230,10 +26228,6 @@ function useDivisionRepo() {
|
|
|
26230
26228
|
};
|
|
26231
26229
|
}
|
|
26232
26230
|
|
|
26233
|
-
// src/controllers/division.controller.ts
|
|
26234
|
-
import { BadRequestError as BadRequestError55 } from "@eeplatform/nodejs-utils";
|
|
26235
|
-
import Joi30 from "joi";
|
|
26236
|
-
|
|
26237
26231
|
// src/services/division.service.ts
|
|
26238
26232
|
import { useAtlas as useAtlas28 } from "@eeplatform/nodejs-utils";
|
|
26239
26233
|
function useDivisionService() {
|
|
@@ -26273,6 +26267,8 @@ function useDivisionService() {
|
|
|
26273
26267
|
}
|
|
26274
26268
|
|
|
26275
26269
|
// src/controllers/division.controller.ts
|
|
26270
|
+
import { BadRequestError as BadRequestError55 } from "@eeplatform/nodejs-utils";
|
|
26271
|
+
import Joi30 from "joi";
|
|
26276
26272
|
function useDivisionController() {
|
|
26277
26273
|
const {
|
|
26278
26274
|
getAll: _getAll,
|
|
@@ -27035,6 +27031,1111 @@ function useSchoolController() {
|
|
|
27035
27031
|
approveSchool
|
|
27036
27032
|
};
|
|
27037
27033
|
}
|
|
27034
|
+
|
|
27035
|
+
// src/models/building.model.ts
|
|
27036
|
+
import { BadRequestError as BadRequestError59, logger as logger29 } from "@eeplatform/nodejs-utils";
|
|
27037
|
+
import Joi33 from "joi";
|
|
27038
|
+
import { ObjectId as ObjectId39 } from "mongodb";
|
|
27039
|
+
var schemaBuilding = Joi33.object({
|
|
27040
|
+
_id: Joi33.string().hex().optional(),
|
|
27041
|
+
school: Joi33.string().hex().required(),
|
|
27042
|
+
serial: Joi33.string().optional().allow("", null),
|
|
27043
|
+
name: Joi33.string().required(),
|
|
27044
|
+
levels: Joi33.number().integer().min(1).required(),
|
|
27045
|
+
createdAt: Joi33.date().optional().allow("", null),
|
|
27046
|
+
updatedAt: Joi33.date().optional().allow("", null),
|
|
27047
|
+
deletedAt: Joi33.date().optional().allow("", null),
|
|
27048
|
+
status: Joi33.string().optional().allow("", null)
|
|
27049
|
+
});
|
|
27050
|
+
var schemaBuildingUnit = Joi33.object({
|
|
27051
|
+
_id: Joi33.string().hex().optional(),
|
|
27052
|
+
school: Joi33.string().hex().required(),
|
|
27053
|
+
name: Joi33.string().optional().allow("", null),
|
|
27054
|
+
building: Joi33.string().hex().required(),
|
|
27055
|
+
buildingName: Joi33.string().optional().allow("", null),
|
|
27056
|
+
level: Joi33.number().integer().min(1).required(),
|
|
27057
|
+
category: Joi33.string().required(),
|
|
27058
|
+
type: Joi33.string().required(),
|
|
27059
|
+
seating_capacity: Joi33.number().integer().min(0).required(),
|
|
27060
|
+
standing_capacity: Joi33.number().integer().min(0).required(),
|
|
27061
|
+
description: Joi33.string().optional().allow("", null),
|
|
27062
|
+
unit_of_measurement: Joi33.string().valid("sqm").required(),
|
|
27063
|
+
area: Joi33.number().positive().required(),
|
|
27064
|
+
status: Joi33.string().optional().allow("", null)
|
|
27065
|
+
});
|
|
27066
|
+
var schemaUpdateOptions = Joi33.object({
|
|
27067
|
+
name: Joi33.string().optional().allow("", null),
|
|
27068
|
+
building: Joi33.string().hex().optional().allow("", null),
|
|
27069
|
+
level: Joi33.number().integer().min(1).optional().allow("", null),
|
|
27070
|
+
category: Joi33.string().optional().allow("", null),
|
|
27071
|
+
type: Joi33.string().optional().allow("", null),
|
|
27072
|
+
seating_capacity: Joi33.number().integer().min(0).optional().allow("", null),
|
|
27073
|
+
standing_capacity: Joi33.number().integer().min(0).optional().allow("", null),
|
|
27074
|
+
area: Joi33.number().positive().optional().allow("", null)
|
|
27075
|
+
});
|
|
27076
|
+
function MBuilding(value) {
|
|
27077
|
+
const { error } = schemaBuilding.validate(value);
|
|
27078
|
+
if (error) {
|
|
27079
|
+
logger29.info(`Building Model: ${error.message}`);
|
|
27080
|
+
throw new BadRequestError59(error.message);
|
|
27081
|
+
}
|
|
27082
|
+
if (value._id && typeof value._id === "string") {
|
|
27083
|
+
try {
|
|
27084
|
+
value._id = new ObjectId39(value._id);
|
|
27085
|
+
} catch (error2) {
|
|
27086
|
+
throw new BadRequestError59("Invalid _id format");
|
|
27087
|
+
}
|
|
27088
|
+
}
|
|
27089
|
+
try {
|
|
27090
|
+
value.school = new ObjectId39(value.school);
|
|
27091
|
+
} catch (error2) {
|
|
27092
|
+
throw new BadRequestError59("Invalid school format");
|
|
27093
|
+
}
|
|
27094
|
+
return {
|
|
27095
|
+
_id: value._id ?? void 0,
|
|
27096
|
+
school: value.school,
|
|
27097
|
+
serial: value.serial ?? "",
|
|
27098
|
+
name: value.name ?? "",
|
|
27099
|
+
levels: value.levels ?? 0,
|
|
27100
|
+
status: value.status ?? "active",
|
|
27101
|
+
createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
|
|
27102
|
+
updatedAt: value.updatedAt ?? "",
|
|
27103
|
+
deletedAt: value.deletedAt ?? ""
|
|
27104
|
+
};
|
|
27105
|
+
}
|
|
27106
|
+
function MBuildingUnit(value) {
|
|
27107
|
+
const { error } = schemaBuildingUnit.validate(value);
|
|
27108
|
+
if (error) {
|
|
27109
|
+
logger29.info(`Building Unit Model: ${error.message}`);
|
|
27110
|
+
throw new BadRequestError59(error.message);
|
|
27111
|
+
}
|
|
27112
|
+
if (value._id && typeof value._id === "string") {
|
|
27113
|
+
try {
|
|
27114
|
+
value._id = new ObjectId39(value._id);
|
|
27115
|
+
} catch (error2) {
|
|
27116
|
+
throw new BadRequestError59("Invalid ID");
|
|
27117
|
+
}
|
|
27118
|
+
}
|
|
27119
|
+
try {
|
|
27120
|
+
value.school = new ObjectId39(value.school);
|
|
27121
|
+
} catch (error2) {
|
|
27122
|
+
throw new BadRequestError59("Invalid school ID");
|
|
27123
|
+
}
|
|
27124
|
+
try {
|
|
27125
|
+
value.building = new ObjectId39(value.building);
|
|
27126
|
+
} catch (error2) {
|
|
27127
|
+
throw new BadRequestError59("Invalid building ID");
|
|
27128
|
+
}
|
|
27129
|
+
return {
|
|
27130
|
+
_id: value._id ?? void 0,
|
|
27131
|
+
school: value.school,
|
|
27132
|
+
name: value.name ?? "",
|
|
27133
|
+
building: value.building,
|
|
27134
|
+
buildingName: value.buildingName ?? "",
|
|
27135
|
+
level: value.level ?? 0,
|
|
27136
|
+
category: value.category ?? "",
|
|
27137
|
+
type: value.type ?? "",
|
|
27138
|
+
seating_capacity: value.seating_capacity ?? 0,
|
|
27139
|
+
standing_capacity: value.standing_capacity ?? 0,
|
|
27140
|
+
description: value.description ?? "",
|
|
27141
|
+
unit_of_measurement: value.unit_of_measurement ?? "sqm",
|
|
27142
|
+
area: value.area ?? 0,
|
|
27143
|
+
status: value.status ?? "active",
|
|
27144
|
+
createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
|
|
27145
|
+
updatedAt: value.updatedAt ?? "",
|
|
27146
|
+
deletedAt: value.deletedAt ?? ""
|
|
27147
|
+
};
|
|
27148
|
+
}
|
|
27149
|
+
|
|
27150
|
+
// src/repositories/building.repository.ts
|
|
27151
|
+
import {
|
|
27152
|
+
AppError as AppError14,
|
|
27153
|
+
BadRequestError as BadRequestError60,
|
|
27154
|
+
InternalServerError as InternalServerError25,
|
|
27155
|
+
logger as logger30,
|
|
27156
|
+
makeCacheKey as makeCacheKey19,
|
|
27157
|
+
paginate as paginate15,
|
|
27158
|
+
useAtlas as useAtlas31,
|
|
27159
|
+
useCache as useCache20
|
|
27160
|
+
} from "@eeplatform/nodejs-utils";
|
|
27161
|
+
import { ObjectId as ObjectId40 } from "mongodb";
|
|
27162
|
+
function useBuildingRepo() {
|
|
27163
|
+
const db = useAtlas31.getDb();
|
|
27164
|
+
if (!db) {
|
|
27165
|
+
throw new Error("Unable to connect to server.");
|
|
27166
|
+
}
|
|
27167
|
+
const namespace_collection = "school.buildings";
|
|
27168
|
+
const collection = db.collection(namespace_collection);
|
|
27169
|
+
const { getCache, setCache, delNamespace } = useCache20(namespace_collection);
|
|
27170
|
+
async function createIndex() {
|
|
27171
|
+
try {
|
|
27172
|
+
await collection.createIndex([
|
|
27173
|
+
{ name: 1 },
|
|
27174
|
+
{ school: 1 },
|
|
27175
|
+
{ createdAt: 1 }
|
|
27176
|
+
]);
|
|
27177
|
+
} catch (error) {
|
|
27178
|
+
throw new Error("Failed to create index on buildings.");
|
|
27179
|
+
}
|
|
27180
|
+
}
|
|
27181
|
+
async function createTextIndex() {
|
|
27182
|
+
try {
|
|
27183
|
+
await collection.createIndex({
|
|
27184
|
+
name: "text"
|
|
27185
|
+
});
|
|
27186
|
+
} catch (error) {
|
|
27187
|
+
throw new Error("Failed to create text index on building name.");
|
|
27188
|
+
}
|
|
27189
|
+
}
|
|
27190
|
+
async function add(value, session) {
|
|
27191
|
+
try {
|
|
27192
|
+
value = MBuilding(value);
|
|
27193
|
+
const res = await collection.insertOne(value, { session });
|
|
27194
|
+
delCachedData();
|
|
27195
|
+
return res.insertedId;
|
|
27196
|
+
} catch (error) {
|
|
27197
|
+
logger30.log({
|
|
27198
|
+
level: "error",
|
|
27199
|
+
message: error.message
|
|
27200
|
+
});
|
|
27201
|
+
if (error instanceof AppError14) {
|
|
27202
|
+
throw error;
|
|
27203
|
+
} else {
|
|
27204
|
+
const isDuplicated = error.message.includes("duplicate");
|
|
27205
|
+
if (isDuplicated) {
|
|
27206
|
+
throw new BadRequestError60("Building already exists.");
|
|
27207
|
+
}
|
|
27208
|
+
throw new Error("Failed to create building.");
|
|
27209
|
+
}
|
|
27210
|
+
}
|
|
27211
|
+
}
|
|
27212
|
+
async function updateById(_id, value, session) {
|
|
27213
|
+
try {
|
|
27214
|
+
_id = new ObjectId40(_id);
|
|
27215
|
+
} catch (error) {
|
|
27216
|
+
throw new BadRequestError60("Invalid ID.");
|
|
27217
|
+
}
|
|
27218
|
+
try {
|
|
27219
|
+
const res = await collection.updateOne(
|
|
27220
|
+
{ _id },
|
|
27221
|
+
{ $set: value },
|
|
27222
|
+
{ session }
|
|
27223
|
+
);
|
|
27224
|
+
delCachedData();
|
|
27225
|
+
return res;
|
|
27226
|
+
} catch (error) {
|
|
27227
|
+
logger30.log({
|
|
27228
|
+
level: "error",
|
|
27229
|
+
message: error.message
|
|
27230
|
+
});
|
|
27231
|
+
if (error instanceof AppError14) {
|
|
27232
|
+
throw error;
|
|
27233
|
+
} else {
|
|
27234
|
+
throw new Error("Failed to update building.");
|
|
27235
|
+
}
|
|
27236
|
+
}
|
|
27237
|
+
}
|
|
27238
|
+
async function getAll({
|
|
27239
|
+
search = "",
|
|
27240
|
+
page = 1,
|
|
27241
|
+
limit = 10,
|
|
27242
|
+
sort = {},
|
|
27243
|
+
school = "",
|
|
27244
|
+
status = "active"
|
|
27245
|
+
} = {}) {
|
|
27246
|
+
page = page > 0 ? page - 1 : 0;
|
|
27247
|
+
const query = {
|
|
27248
|
+
status
|
|
27249
|
+
};
|
|
27250
|
+
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
27251
|
+
if (search) {
|
|
27252
|
+
query.$text = { $search: search };
|
|
27253
|
+
}
|
|
27254
|
+
if (school) {
|
|
27255
|
+
try {
|
|
27256
|
+
query.school = new ObjectId40(school);
|
|
27257
|
+
} catch (error) {
|
|
27258
|
+
throw new BadRequestError60("Invalid school ID.");
|
|
27259
|
+
}
|
|
27260
|
+
}
|
|
27261
|
+
const cacheParams = {
|
|
27262
|
+
page,
|
|
27263
|
+
limit,
|
|
27264
|
+
sort: JSON.stringify(sort)
|
|
27265
|
+
};
|
|
27266
|
+
if (search)
|
|
27267
|
+
cacheParams.search = search;
|
|
27268
|
+
if (school)
|
|
27269
|
+
cacheParams.school = school;
|
|
27270
|
+
if (status !== "active")
|
|
27271
|
+
cacheParams.status = status;
|
|
27272
|
+
const cacheKey = makeCacheKey19(namespace_collection, cacheParams);
|
|
27273
|
+
logger30.log({
|
|
27274
|
+
level: "info",
|
|
27275
|
+
message: `Cache key for getAll buildings: ${cacheKey}`
|
|
27276
|
+
});
|
|
27277
|
+
try {
|
|
27278
|
+
const cached = await getCache(cacheKey);
|
|
27279
|
+
if (cached) {
|
|
27280
|
+
logger30.log({
|
|
27281
|
+
level: "info",
|
|
27282
|
+
message: `Cache hit for getAll buildings: ${cacheKey}`
|
|
27283
|
+
});
|
|
27284
|
+
return cached;
|
|
27285
|
+
}
|
|
27286
|
+
const items = await collection.aggregate([
|
|
27287
|
+
{ $match: query },
|
|
27288
|
+
{ $sort: sort },
|
|
27289
|
+
{ $skip: page * limit },
|
|
27290
|
+
{ $limit: limit }
|
|
27291
|
+
]).toArray();
|
|
27292
|
+
const length = await collection.countDocuments(query);
|
|
27293
|
+
const data = paginate15(items, page, limit, length);
|
|
27294
|
+
setCache(cacheKey, data, 600).then(() => {
|
|
27295
|
+
logger30.log({
|
|
27296
|
+
level: "info",
|
|
27297
|
+
message: `Cache set for getAll buildings: ${cacheKey}`
|
|
27298
|
+
});
|
|
27299
|
+
}).catch((err) => {
|
|
27300
|
+
logger30.log({
|
|
27301
|
+
level: "error",
|
|
27302
|
+
message: `Failed to set cache for getAll buildings: ${err.message}`
|
|
27303
|
+
});
|
|
27304
|
+
});
|
|
27305
|
+
return data;
|
|
27306
|
+
} catch (error) {
|
|
27307
|
+
logger30.log({ level: "error", message: `${error}` });
|
|
27308
|
+
throw error;
|
|
27309
|
+
}
|
|
27310
|
+
}
|
|
27311
|
+
async function getById(_id) {
|
|
27312
|
+
try {
|
|
27313
|
+
_id = new ObjectId40(_id);
|
|
27314
|
+
} catch (error) {
|
|
27315
|
+
throw new BadRequestError60("Invalid ID.");
|
|
27316
|
+
}
|
|
27317
|
+
const cacheKey = makeCacheKey19(namespace_collection, { _id: String(_id) });
|
|
27318
|
+
try {
|
|
27319
|
+
const cached = await getCache(cacheKey);
|
|
27320
|
+
if (cached) {
|
|
27321
|
+
logger30.log({
|
|
27322
|
+
level: "info",
|
|
27323
|
+
message: `Cache hit for getById building: ${cacheKey}`
|
|
27324
|
+
});
|
|
27325
|
+
return cached;
|
|
27326
|
+
}
|
|
27327
|
+
const result = await collection.findOne({
|
|
27328
|
+
_id
|
|
27329
|
+
});
|
|
27330
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
27331
|
+
logger30.log({
|
|
27332
|
+
level: "info",
|
|
27333
|
+
message: `Cache set for building by id: ${cacheKey}`
|
|
27334
|
+
});
|
|
27335
|
+
}).catch((err) => {
|
|
27336
|
+
logger30.log({
|
|
27337
|
+
level: "error",
|
|
27338
|
+
message: `Failed to set cache for building by id: ${err.message}`
|
|
27339
|
+
});
|
|
27340
|
+
});
|
|
27341
|
+
return result;
|
|
27342
|
+
} catch (error) {
|
|
27343
|
+
if (error instanceof AppError14) {
|
|
27344
|
+
throw error;
|
|
27345
|
+
} else {
|
|
27346
|
+
throw new InternalServerError25("Failed to get building.");
|
|
27347
|
+
}
|
|
27348
|
+
}
|
|
27349
|
+
}
|
|
27350
|
+
async function deleteById(_id, session) {
|
|
27351
|
+
try {
|
|
27352
|
+
_id = new ObjectId40(_id);
|
|
27353
|
+
} catch (error) {
|
|
27354
|
+
throw new BadRequestError60("Invalid ID.");
|
|
27355
|
+
}
|
|
27356
|
+
try {
|
|
27357
|
+
const res = await collection.updateOne(
|
|
27358
|
+
{ _id },
|
|
27359
|
+
{ $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } }
|
|
27360
|
+
);
|
|
27361
|
+
delCachedData();
|
|
27362
|
+
return res;
|
|
27363
|
+
} catch (error) {
|
|
27364
|
+
logger30.log({
|
|
27365
|
+
level: "error",
|
|
27366
|
+
message: error.message
|
|
27367
|
+
});
|
|
27368
|
+
if (error instanceof AppError14) {
|
|
27369
|
+
throw error;
|
|
27370
|
+
} else {
|
|
27371
|
+
throw new InternalServerError25("Failed to delete building.");
|
|
27372
|
+
}
|
|
27373
|
+
}
|
|
27374
|
+
}
|
|
27375
|
+
function delCachedData() {
|
|
27376
|
+
delNamespace().then(() => {
|
|
27377
|
+
logger30.log({
|
|
27378
|
+
level: "info",
|
|
27379
|
+
message: `Cache namespace cleared for ${namespace_collection}`
|
|
27380
|
+
});
|
|
27381
|
+
}).catch((err) => {
|
|
27382
|
+
logger30.log({
|
|
27383
|
+
level: "error",
|
|
27384
|
+
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
27385
|
+
});
|
|
27386
|
+
});
|
|
27387
|
+
}
|
|
27388
|
+
return {
|
|
27389
|
+
createIndex,
|
|
27390
|
+
createTextIndex,
|
|
27391
|
+
add,
|
|
27392
|
+
getAll,
|
|
27393
|
+
getById,
|
|
27394
|
+
updateById,
|
|
27395
|
+
deleteById
|
|
27396
|
+
};
|
|
27397
|
+
}
|
|
27398
|
+
|
|
27399
|
+
// src/repositories/building-unit.repository.ts
|
|
27400
|
+
import {
|
|
27401
|
+
AppError as AppError15,
|
|
27402
|
+
BadRequestError as BadRequestError61,
|
|
27403
|
+
InternalServerError as InternalServerError26,
|
|
27404
|
+
logger as logger31,
|
|
27405
|
+
makeCacheKey as makeCacheKey20,
|
|
27406
|
+
paginate as paginate16,
|
|
27407
|
+
useAtlas as useAtlas32,
|
|
27408
|
+
useCache as useCache21
|
|
27409
|
+
} from "@eeplatform/nodejs-utils";
|
|
27410
|
+
import { ObjectId as ObjectId41 } from "mongodb";
|
|
27411
|
+
function useBuildingUnitRepo() {
|
|
27412
|
+
const db = useAtlas32.getDb();
|
|
27413
|
+
if (!db) {
|
|
27414
|
+
throw new Error("Unable to connect to server.");
|
|
27415
|
+
}
|
|
27416
|
+
const namespace_collection = "school.building-units";
|
|
27417
|
+
const collection = db.collection(namespace_collection);
|
|
27418
|
+
const { getCache, setCache, delNamespace } = useCache21(namespace_collection);
|
|
27419
|
+
async function createIndex() {
|
|
27420
|
+
try {
|
|
27421
|
+
await collection.createIndexes([
|
|
27422
|
+
{ key: { school: 1 } },
|
|
27423
|
+
{ key: { building: 1 } },
|
|
27424
|
+
{ key: { status: 1 } },
|
|
27425
|
+
{ key: { createdAt: 1 } },
|
|
27426
|
+
{
|
|
27427
|
+
key: {
|
|
27428
|
+
name: "text",
|
|
27429
|
+
buildingName: "text",
|
|
27430
|
+
category: "text",
|
|
27431
|
+
type: "text"
|
|
27432
|
+
}
|
|
27433
|
+
}
|
|
27434
|
+
]);
|
|
27435
|
+
} catch (error) {
|
|
27436
|
+
throw new Error("Failed to create index on building units.");
|
|
27437
|
+
}
|
|
27438
|
+
}
|
|
27439
|
+
function delCachedData() {
|
|
27440
|
+
delNamespace().then(() => {
|
|
27441
|
+
logger31.log({
|
|
27442
|
+
level: "info",
|
|
27443
|
+
message: `Cache namespace cleared for ${namespace_collection}`
|
|
27444
|
+
});
|
|
27445
|
+
}).catch((err) => {
|
|
27446
|
+
logger31.log({
|
|
27447
|
+
level: "error",
|
|
27448
|
+
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
27449
|
+
});
|
|
27450
|
+
});
|
|
27451
|
+
}
|
|
27452
|
+
async function add(value, session) {
|
|
27453
|
+
try {
|
|
27454
|
+
value = MBuildingUnit(value);
|
|
27455
|
+
const res = await collection.insertOne(value, { session });
|
|
27456
|
+
delCachedData();
|
|
27457
|
+
return res.insertedId;
|
|
27458
|
+
} catch (error) {
|
|
27459
|
+
logger31.log({
|
|
27460
|
+
level: "error",
|
|
27461
|
+
message: error.message
|
|
27462
|
+
});
|
|
27463
|
+
if (error instanceof AppError15) {
|
|
27464
|
+
throw error;
|
|
27465
|
+
} else {
|
|
27466
|
+
throw new Error("Failed to create building unit.");
|
|
27467
|
+
}
|
|
27468
|
+
}
|
|
27469
|
+
}
|
|
27470
|
+
async function updateById(_id, value, session) {
|
|
27471
|
+
const { error } = schemaUpdateOptions.validate(value);
|
|
27472
|
+
if (error) {
|
|
27473
|
+
throw new BadRequestError61(error.message);
|
|
27474
|
+
}
|
|
27475
|
+
try {
|
|
27476
|
+
_id = new ObjectId41(_id);
|
|
27477
|
+
} catch (error2) {
|
|
27478
|
+
throw new BadRequestError61("Invalid ID.");
|
|
27479
|
+
}
|
|
27480
|
+
try {
|
|
27481
|
+
const res = await collection.updateOne(
|
|
27482
|
+
{ _id },
|
|
27483
|
+
{ $set: value },
|
|
27484
|
+
{ session }
|
|
27485
|
+
);
|
|
27486
|
+
delCachedData();
|
|
27487
|
+
return res;
|
|
27488
|
+
} catch (error2) {
|
|
27489
|
+
logger31.log({
|
|
27490
|
+
level: "error",
|
|
27491
|
+
message: error2.message
|
|
27492
|
+
});
|
|
27493
|
+
if (error2 instanceof AppError15) {
|
|
27494
|
+
throw error2;
|
|
27495
|
+
} else {
|
|
27496
|
+
throw new Error("Failed to create building unit.");
|
|
27497
|
+
}
|
|
27498
|
+
}
|
|
27499
|
+
}
|
|
27500
|
+
async function getAll({
|
|
27501
|
+
search = "",
|
|
27502
|
+
page = 1,
|
|
27503
|
+
limit = 10,
|
|
27504
|
+
sort = {},
|
|
27505
|
+
school = "",
|
|
27506
|
+
building = "",
|
|
27507
|
+
status = "active"
|
|
27508
|
+
} = {}) {
|
|
27509
|
+
page = page > 0 ? page - 1 : 0;
|
|
27510
|
+
const query = {
|
|
27511
|
+
deletedAt: { $in: ["", null] },
|
|
27512
|
+
status: { $in: [status, "", null] }
|
|
27513
|
+
};
|
|
27514
|
+
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
27515
|
+
if (search) {
|
|
27516
|
+
query.$text = { $search: search };
|
|
27517
|
+
}
|
|
27518
|
+
if (school) {
|
|
27519
|
+
try {
|
|
27520
|
+
query.school = new ObjectId41(school);
|
|
27521
|
+
} catch (error) {
|
|
27522
|
+
throw new BadRequestError61("Invalid school ID.");
|
|
27523
|
+
}
|
|
27524
|
+
}
|
|
27525
|
+
if (building) {
|
|
27526
|
+
try {
|
|
27527
|
+
query.building = new ObjectId41(building);
|
|
27528
|
+
} catch (error) {
|
|
27529
|
+
throw new BadRequestError61("Invalid building ID.");
|
|
27530
|
+
}
|
|
27531
|
+
}
|
|
27532
|
+
const cacheParams = {
|
|
27533
|
+
page,
|
|
27534
|
+
limit,
|
|
27535
|
+
sort: JSON.stringify(sort)
|
|
27536
|
+
};
|
|
27537
|
+
if (search)
|
|
27538
|
+
cacheParams.search = search;
|
|
27539
|
+
if (school)
|
|
27540
|
+
cacheParams.school = school;
|
|
27541
|
+
if (building)
|
|
27542
|
+
cacheParams.building = building;
|
|
27543
|
+
if (status !== "active")
|
|
27544
|
+
cacheParams.status = status;
|
|
27545
|
+
const cacheKey = makeCacheKey20(namespace_collection, cacheParams);
|
|
27546
|
+
logger31.log({
|
|
27547
|
+
level: "info",
|
|
27548
|
+
message: `Cache key for getAll building units: ${cacheKey}`
|
|
27549
|
+
});
|
|
27550
|
+
try {
|
|
27551
|
+
const cached = await getCache(cacheKey);
|
|
27552
|
+
if (cached) {
|
|
27553
|
+
logger31.log({
|
|
27554
|
+
level: "info",
|
|
27555
|
+
message: `Cache hit for getAll building units: ${cacheKey}`
|
|
27556
|
+
});
|
|
27557
|
+
return cached;
|
|
27558
|
+
}
|
|
27559
|
+
const items = await collection.aggregate([
|
|
27560
|
+
{ $match: query },
|
|
27561
|
+
{ $sort: sort },
|
|
27562
|
+
{ $skip: page * limit },
|
|
27563
|
+
{ $limit: limit }
|
|
27564
|
+
]).toArray();
|
|
27565
|
+
const length = await collection.countDocuments(query);
|
|
27566
|
+
const data = paginate16(items, page, limit, length);
|
|
27567
|
+
setCache(cacheKey, data, 600).then(() => {
|
|
27568
|
+
logger31.log({
|
|
27569
|
+
level: "info",
|
|
27570
|
+
message: `Cache set for getAll building units: ${cacheKey}`
|
|
27571
|
+
});
|
|
27572
|
+
}).catch((err) => {
|
|
27573
|
+
logger31.log({
|
|
27574
|
+
level: "error",
|
|
27575
|
+
message: `Failed to set cache for getAll building units: ${err.message}`
|
|
27576
|
+
});
|
|
27577
|
+
});
|
|
27578
|
+
return data;
|
|
27579
|
+
} catch (error) {
|
|
27580
|
+
logger31.log({ level: "error", message: `${error}` });
|
|
27581
|
+
throw error;
|
|
27582
|
+
}
|
|
27583
|
+
}
|
|
27584
|
+
async function getById(_id) {
|
|
27585
|
+
try {
|
|
27586
|
+
_id = new ObjectId41(_id);
|
|
27587
|
+
} catch (error) {
|
|
27588
|
+
throw new BadRequestError61("Invalid ID.");
|
|
27589
|
+
}
|
|
27590
|
+
const cacheKey = makeCacheKey20(namespace_collection, { _id: String(_id) });
|
|
27591
|
+
try {
|
|
27592
|
+
const cached = await getCache(cacheKey);
|
|
27593
|
+
if (cached) {
|
|
27594
|
+
logger31.log({
|
|
27595
|
+
level: "info",
|
|
27596
|
+
message: `Cache hit for getById building unit: ${cacheKey}`
|
|
27597
|
+
});
|
|
27598
|
+
return cached;
|
|
27599
|
+
}
|
|
27600
|
+
const result = await collection.findOne({
|
|
27601
|
+
_id,
|
|
27602
|
+
deletedAt: { $in: ["", null] }
|
|
27603
|
+
});
|
|
27604
|
+
if (!result) {
|
|
27605
|
+
throw new BadRequestError61("Building unit not found.");
|
|
27606
|
+
}
|
|
27607
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
27608
|
+
logger31.log({
|
|
27609
|
+
level: "info",
|
|
27610
|
+
message: `Cache set for building unit by id: ${cacheKey}`
|
|
27611
|
+
});
|
|
27612
|
+
}).catch((err) => {
|
|
27613
|
+
logger31.log({
|
|
27614
|
+
level: "error",
|
|
27615
|
+
message: `Failed to set cache for building unit by id: ${err.message}`
|
|
27616
|
+
});
|
|
27617
|
+
});
|
|
27618
|
+
return result;
|
|
27619
|
+
} catch (error) {
|
|
27620
|
+
if (error instanceof AppError15) {
|
|
27621
|
+
throw error;
|
|
27622
|
+
} else {
|
|
27623
|
+
throw new InternalServerError26("Failed to get building unit.");
|
|
27624
|
+
}
|
|
27625
|
+
}
|
|
27626
|
+
}
|
|
27627
|
+
async function getByBuildingLevel(building, level) {
|
|
27628
|
+
try {
|
|
27629
|
+
building = new ObjectId41(building);
|
|
27630
|
+
} catch (error) {
|
|
27631
|
+
throw new BadRequestError61("Invalid building ID.");
|
|
27632
|
+
}
|
|
27633
|
+
const cacheKey = makeCacheKey20(namespace_collection, {
|
|
27634
|
+
building: String(building),
|
|
27635
|
+
level
|
|
27636
|
+
});
|
|
27637
|
+
try {
|
|
27638
|
+
const cached = await getCache(cacheKey);
|
|
27639
|
+
if (cached) {
|
|
27640
|
+
logger31.log({
|
|
27641
|
+
level: "info",
|
|
27642
|
+
message: `Cache hit for getById building unit: ${cacheKey}`
|
|
27643
|
+
});
|
|
27644
|
+
return cached;
|
|
27645
|
+
}
|
|
27646
|
+
const result = await collection.findOne({
|
|
27647
|
+
building,
|
|
27648
|
+
level,
|
|
27649
|
+
status: "active"
|
|
27650
|
+
});
|
|
27651
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
27652
|
+
logger31.log({
|
|
27653
|
+
level: "info",
|
|
27654
|
+
message: `Cache set for building unit by id: ${cacheKey}`
|
|
27655
|
+
});
|
|
27656
|
+
}).catch((err) => {
|
|
27657
|
+
logger31.log({
|
|
27658
|
+
level: "error",
|
|
27659
|
+
message: `Failed to set cache for building unit by id: ${err.message}`
|
|
27660
|
+
});
|
|
27661
|
+
});
|
|
27662
|
+
return result;
|
|
27663
|
+
} catch (error) {
|
|
27664
|
+
if (error instanceof AppError15) {
|
|
27665
|
+
throw error;
|
|
27666
|
+
} else {
|
|
27667
|
+
throw new InternalServerError26("Failed to get building unit.");
|
|
27668
|
+
}
|
|
27669
|
+
}
|
|
27670
|
+
}
|
|
27671
|
+
async function getByBuilding(building) {
|
|
27672
|
+
try {
|
|
27673
|
+
building = new ObjectId41(building);
|
|
27674
|
+
} catch (error) {
|
|
27675
|
+
throw new BadRequestError61("Invalid building ID.");
|
|
27676
|
+
}
|
|
27677
|
+
const cacheKey = makeCacheKey20(namespace_collection, {
|
|
27678
|
+
building: String(building)
|
|
27679
|
+
});
|
|
27680
|
+
try {
|
|
27681
|
+
const cached = await getCache(cacheKey);
|
|
27682
|
+
if (cached) {
|
|
27683
|
+
logger31.log({
|
|
27684
|
+
level: "info",
|
|
27685
|
+
message: `Cache hit for getById building unit: ${cacheKey}`
|
|
27686
|
+
});
|
|
27687
|
+
return cached;
|
|
27688
|
+
}
|
|
27689
|
+
const result = await collection.findOne({
|
|
27690
|
+
building,
|
|
27691
|
+
status: "active"
|
|
27692
|
+
});
|
|
27693
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
27694
|
+
logger31.log({
|
|
27695
|
+
level: "info",
|
|
27696
|
+
message: `Cache set for building unit by id: ${cacheKey}`
|
|
27697
|
+
});
|
|
27698
|
+
}).catch((err) => {
|
|
27699
|
+
logger31.log({
|
|
27700
|
+
level: "error",
|
|
27701
|
+
message: `Failed to set cache for building unit by id: ${err.message}`
|
|
27702
|
+
});
|
|
27703
|
+
});
|
|
27704
|
+
return result;
|
|
27705
|
+
} catch (error) {
|
|
27706
|
+
if (error instanceof AppError15) {
|
|
27707
|
+
throw error;
|
|
27708
|
+
} else {
|
|
27709
|
+
throw new InternalServerError26("Failed to get building unit.");
|
|
27710
|
+
}
|
|
27711
|
+
}
|
|
27712
|
+
}
|
|
27713
|
+
async function deleteById(_id, session) {
|
|
27714
|
+
try {
|
|
27715
|
+
_id = new ObjectId41(_id);
|
|
27716
|
+
} catch (error) {
|
|
27717
|
+
throw new BadRequestError61("Invalid ID.");
|
|
27718
|
+
}
|
|
27719
|
+
try {
|
|
27720
|
+
const res = await collection.updateOne(
|
|
27721
|
+
{ _id },
|
|
27722
|
+
{ $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } },
|
|
27723
|
+
{ session }
|
|
27724
|
+
);
|
|
27725
|
+
delCachedData();
|
|
27726
|
+
return "Room/Facility deleted successfully.";
|
|
27727
|
+
} catch (error) {
|
|
27728
|
+
logger31.log({
|
|
27729
|
+
level: "error",
|
|
27730
|
+
message: error.message
|
|
27731
|
+
});
|
|
27732
|
+
if (error instanceof AppError15) {
|
|
27733
|
+
throw error;
|
|
27734
|
+
} else {
|
|
27735
|
+
throw new Error("Failed to deleted room/facility.");
|
|
27736
|
+
}
|
|
27737
|
+
}
|
|
27738
|
+
}
|
|
27739
|
+
return {
|
|
27740
|
+
createIndex,
|
|
27741
|
+
add,
|
|
27742
|
+
getAll,
|
|
27743
|
+
getById,
|
|
27744
|
+
getByBuildingLevel,
|
|
27745
|
+
updateById,
|
|
27746
|
+
getByBuilding,
|
|
27747
|
+
deleteById
|
|
27748
|
+
};
|
|
27749
|
+
}
|
|
27750
|
+
|
|
27751
|
+
// src/controllers/building.controller.ts
|
|
27752
|
+
import { BadRequestError as BadRequestError63, logger as logger32 } from "@eeplatform/nodejs-utils";
|
|
27753
|
+
import Joi34 from "joi";
|
|
27754
|
+
|
|
27755
|
+
// src/services/building.service.ts
|
|
27756
|
+
import { BadRequestError as BadRequestError62, NotFoundError as NotFoundError11 } from "@eeplatform/nodejs-utils";
|
|
27757
|
+
function useBuildingService() {
|
|
27758
|
+
const {
|
|
27759
|
+
updateById: _updateById,
|
|
27760
|
+
getById: _getById,
|
|
27761
|
+
deleteById: _deleteById
|
|
27762
|
+
} = useBuildingRepo();
|
|
27763
|
+
const { getByBuildingLevel, getByBuilding } = useBuildingUnitRepo();
|
|
27764
|
+
async function updateById(id, data) {
|
|
27765
|
+
data.levels = Number(data.levels);
|
|
27766
|
+
try {
|
|
27767
|
+
const building = await _getById(id);
|
|
27768
|
+
if (!building) {
|
|
27769
|
+
throw new NotFoundError11("Building not found.");
|
|
27770
|
+
}
|
|
27771
|
+
if (data.levels < building.levels) {
|
|
27772
|
+
const unit = await getByBuildingLevel(id, building.levels);
|
|
27773
|
+
if (unit) {
|
|
27774
|
+
throw new BadRequestError62(
|
|
27775
|
+
"Cannot reduce floors, there are existing building units at higher floors."
|
|
27776
|
+
);
|
|
27777
|
+
}
|
|
27778
|
+
}
|
|
27779
|
+
const result = await _updateById(id, data);
|
|
27780
|
+
return result;
|
|
27781
|
+
} catch (error) {
|
|
27782
|
+
throw error;
|
|
27783
|
+
}
|
|
27784
|
+
}
|
|
27785
|
+
async function deleteById(id) {
|
|
27786
|
+
const building = await getByBuilding(id);
|
|
27787
|
+
if (building) {
|
|
27788
|
+
throw new BadRequestError62(
|
|
27789
|
+
"Cannot delete building with existing room/facility. Please delete room/facility first."
|
|
27790
|
+
);
|
|
27791
|
+
}
|
|
27792
|
+
try {
|
|
27793
|
+
await _deleteById(id);
|
|
27794
|
+
return "Building deleted successfully.";
|
|
27795
|
+
} catch (error) {
|
|
27796
|
+
throw error;
|
|
27797
|
+
}
|
|
27798
|
+
}
|
|
27799
|
+
return {
|
|
27800
|
+
updateById,
|
|
27801
|
+
deleteById
|
|
27802
|
+
};
|
|
27803
|
+
}
|
|
27804
|
+
|
|
27805
|
+
// src/controllers/building.controller.ts
|
|
27806
|
+
function useBuildingController() {
|
|
27807
|
+
const { getAll: _getAll, getById: _getById, add: _add } = useBuildingRepo();
|
|
27808
|
+
const { updateById: _updateById, deleteById: _deleteById } = useBuildingService();
|
|
27809
|
+
async function createBuilding(req, res, next) {
|
|
27810
|
+
const value = req.body;
|
|
27811
|
+
const validation = Joi34.object({
|
|
27812
|
+
name: Joi34.string().required(),
|
|
27813
|
+
school: Joi34.string().hex().required(),
|
|
27814
|
+
levels: Joi34.number().integer().min(1).required(),
|
|
27815
|
+
serial: Joi34.string().optional().allow("", null),
|
|
27816
|
+
status: Joi34.string().optional().allow("", null)
|
|
27817
|
+
});
|
|
27818
|
+
const { error } = validation.validate(value);
|
|
27819
|
+
if (error) {
|
|
27820
|
+
next(new BadRequestError63(error.message));
|
|
27821
|
+
logger32.info(`Controller: ${error.message}`);
|
|
27822
|
+
return;
|
|
27823
|
+
}
|
|
27824
|
+
try {
|
|
27825
|
+
const result = await _add(value);
|
|
27826
|
+
res.json(result);
|
|
27827
|
+
return;
|
|
27828
|
+
} catch (error2) {
|
|
27829
|
+
next(error2);
|
|
27830
|
+
}
|
|
27831
|
+
}
|
|
27832
|
+
async function updateById(req, res, next) {
|
|
27833
|
+
const value = req.body;
|
|
27834
|
+
const id = req.params.id ?? "";
|
|
27835
|
+
const validation = Joi34.object({
|
|
27836
|
+
id: Joi34.string().hex().required(),
|
|
27837
|
+
value: Joi34.object({
|
|
27838
|
+
name: Joi34.string().required(),
|
|
27839
|
+
serial: Joi34.string().optional().allow("", null),
|
|
27840
|
+
levels: Joi34.number().integer().min(1).required()
|
|
27841
|
+
})
|
|
27842
|
+
});
|
|
27843
|
+
const { error } = validation.validate({ id, value });
|
|
27844
|
+
if (error) {
|
|
27845
|
+
next(new BadRequestError63(error.message));
|
|
27846
|
+
logger32.info(`Controller: ${error.message}`);
|
|
27847
|
+
return;
|
|
27848
|
+
}
|
|
27849
|
+
try {
|
|
27850
|
+
const result = await _updateById(id, value);
|
|
27851
|
+
res.json(result);
|
|
27852
|
+
return;
|
|
27853
|
+
} catch (error2) {
|
|
27854
|
+
next(error2);
|
|
27855
|
+
}
|
|
27856
|
+
}
|
|
27857
|
+
async function getAll(req, res, next) {
|
|
27858
|
+
const query = req.query;
|
|
27859
|
+
const validation = Joi34.object({
|
|
27860
|
+
page: Joi34.number().min(1).optional().allow("", null),
|
|
27861
|
+
limit: Joi34.number().min(1).optional().allow("", null),
|
|
27862
|
+
search: Joi34.string().optional().allow("", null),
|
|
27863
|
+
school: Joi34.string().hex().optional().allow("", null),
|
|
27864
|
+
status: Joi34.string().optional().allow("", null)
|
|
27865
|
+
});
|
|
27866
|
+
const { error } = validation.validate(query);
|
|
27867
|
+
if (error) {
|
|
27868
|
+
next(new BadRequestError63(error.message));
|
|
27869
|
+
return;
|
|
27870
|
+
}
|
|
27871
|
+
const page = parseInt(req.query.page) ?? 1;
|
|
27872
|
+
let limit = parseInt(req.query.limit) ?? 20;
|
|
27873
|
+
limit = isNaN(limit) ? 20 : limit;
|
|
27874
|
+
const sort = req.query.sort ? String(req.query.sort).split(",") : "";
|
|
27875
|
+
const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
|
|
27876
|
+
const sortObj = {};
|
|
27877
|
+
if (sort && Array.isArray(sort) && sort.length && sortOrder && Array.isArray(sortOrder) && sortOrder.length) {
|
|
27878
|
+
sort.forEach((field, index) => {
|
|
27879
|
+
sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
|
|
27880
|
+
});
|
|
27881
|
+
}
|
|
27882
|
+
const status = req.query.status ?? "active";
|
|
27883
|
+
const school = req.query.school ?? "";
|
|
27884
|
+
const search = req.query.search ?? "";
|
|
27885
|
+
try {
|
|
27886
|
+
const buildings = await _getAll({
|
|
27887
|
+
page,
|
|
27888
|
+
limit,
|
|
27889
|
+
sort: sortObj,
|
|
27890
|
+
status,
|
|
27891
|
+
school,
|
|
27892
|
+
search
|
|
27893
|
+
});
|
|
27894
|
+
res.json(buildings);
|
|
27895
|
+
return;
|
|
27896
|
+
} catch (error2) {
|
|
27897
|
+
next(error2);
|
|
27898
|
+
}
|
|
27899
|
+
}
|
|
27900
|
+
async function getById(req, res, next) {
|
|
27901
|
+
const id = req.params.id;
|
|
27902
|
+
const validation = Joi34.object({
|
|
27903
|
+
id: Joi34.string().hex().required()
|
|
27904
|
+
});
|
|
27905
|
+
const { error } = validation.validate({ id });
|
|
27906
|
+
if (error) {
|
|
27907
|
+
next(new BadRequestError63(error.message));
|
|
27908
|
+
return;
|
|
27909
|
+
}
|
|
27910
|
+
try {
|
|
27911
|
+
const building = await _getById(id);
|
|
27912
|
+
res.json({
|
|
27913
|
+
message: "Successfully retrieved building.",
|
|
27914
|
+
data: { building }
|
|
27915
|
+
});
|
|
27916
|
+
return;
|
|
27917
|
+
} catch (error2) {
|
|
27918
|
+
next(error2);
|
|
27919
|
+
}
|
|
27920
|
+
}
|
|
27921
|
+
async function deleteById(req, res, next) {
|
|
27922
|
+
const id = req.params.id;
|
|
27923
|
+
const validation = Joi34.object({
|
|
27924
|
+
id: Joi34.string().hex().required()
|
|
27925
|
+
});
|
|
27926
|
+
const { error } = validation.validate({ id });
|
|
27927
|
+
if (error) {
|
|
27928
|
+
next(new BadRequestError63(error.message));
|
|
27929
|
+
return;
|
|
27930
|
+
}
|
|
27931
|
+
try {
|
|
27932
|
+
const message = await _deleteById(id);
|
|
27933
|
+
res.json(message);
|
|
27934
|
+
return;
|
|
27935
|
+
} catch (error2) {
|
|
27936
|
+
next(error2);
|
|
27937
|
+
}
|
|
27938
|
+
}
|
|
27939
|
+
return {
|
|
27940
|
+
createBuilding,
|
|
27941
|
+
getAll,
|
|
27942
|
+
getById,
|
|
27943
|
+
updateById,
|
|
27944
|
+
deleteById
|
|
27945
|
+
};
|
|
27946
|
+
}
|
|
27947
|
+
|
|
27948
|
+
// src/controllers/building-unit.controller.ts
|
|
27949
|
+
import { BadRequestError as BadRequestError64 } from "@eeplatform/nodejs-utils";
|
|
27950
|
+
import Joi35 from "joi";
|
|
27951
|
+
|
|
27952
|
+
// src/services/building-unit.service.ts
|
|
27953
|
+
import { useAtlas as useAtlas33 } from "@eeplatform/nodejs-utils";
|
|
27954
|
+
function useBuildingUnitService() {
|
|
27955
|
+
const { add: _add } = useBuildingUnitRepo();
|
|
27956
|
+
async function add(value) {
|
|
27957
|
+
const session = useAtlas33.getClient()?.startSession();
|
|
27958
|
+
if (!session) {
|
|
27959
|
+
throw new Error("Unable to start session for building unit service.");
|
|
27960
|
+
}
|
|
27961
|
+
try {
|
|
27962
|
+
await session.startTransaction();
|
|
27963
|
+
for (let index = 0; index < value.qty; index++) {
|
|
27964
|
+
await _add({ ...value.building }, session);
|
|
27965
|
+
}
|
|
27966
|
+
await session.commitTransaction();
|
|
27967
|
+
return "Building unit added successfully.";
|
|
27968
|
+
} catch (error) {
|
|
27969
|
+
await session.abortTransaction();
|
|
27970
|
+
throw error;
|
|
27971
|
+
} finally {
|
|
27972
|
+
session.endSession();
|
|
27973
|
+
}
|
|
27974
|
+
}
|
|
27975
|
+
return {
|
|
27976
|
+
add
|
|
27977
|
+
};
|
|
27978
|
+
}
|
|
27979
|
+
|
|
27980
|
+
// src/controllers/building-unit.controller.ts
|
|
27981
|
+
function useBuildingUnitController() {
|
|
27982
|
+
const {
|
|
27983
|
+
getAll: _getAll,
|
|
27984
|
+
getById: _getById,
|
|
27985
|
+
updateById: _updateById,
|
|
27986
|
+
deleteById: _deleteById
|
|
27987
|
+
} = useBuildingUnitRepo();
|
|
27988
|
+
const { add: _add } = useBuildingUnitService();
|
|
27989
|
+
async function add(req, res, next) {
|
|
27990
|
+
const data = req.body;
|
|
27991
|
+
const validation = Joi35.object({
|
|
27992
|
+
building: Joi35.object({
|
|
27993
|
+
school: Joi35.string().hex().required(),
|
|
27994
|
+
name: Joi35.string().optional().allow("", null),
|
|
27995
|
+
building: Joi35.string().hex().required(),
|
|
27996
|
+
buildingName: Joi35.string().optional().allow("", null),
|
|
27997
|
+
level: Joi35.number().integer().min(1).required(),
|
|
27998
|
+
category: Joi35.string().required(),
|
|
27999
|
+
type: Joi35.string().required(),
|
|
28000
|
+
seating_capacity: Joi35.number().integer().min(0).required(),
|
|
28001
|
+
standing_capacity: Joi35.number().integer().min(0).required(),
|
|
28002
|
+
description: Joi35.string().optional().allow("", null),
|
|
28003
|
+
unit_of_measurement: Joi35.string().valid("sqm").required(),
|
|
28004
|
+
area: Joi35.number().positive().required(),
|
|
28005
|
+
status: Joi35.string().optional().allow("", null)
|
|
28006
|
+
}),
|
|
28007
|
+
qty: Joi35.number().integer().min(1).max(20).optional().default(1)
|
|
28008
|
+
});
|
|
28009
|
+
const { error } = validation.validate(data);
|
|
28010
|
+
if (error) {
|
|
28011
|
+
next(new BadRequestError64(error.message));
|
|
28012
|
+
return;
|
|
28013
|
+
}
|
|
28014
|
+
try {
|
|
28015
|
+
const buildingUnit = await _add(data);
|
|
28016
|
+
res.json({
|
|
28017
|
+
message: "Building unit added successfully.",
|
|
28018
|
+
data: { buildingUnit }
|
|
28019
|
+
});
|
|
28020
|
+
} catch (error2) {
|
|
28021
|
+
next(error2);
|
|
28022
|
+
}
|
|
28023
|
+
}
|
|
28024
|
+
async function updateById(req, res, next) {
|
|
28025
|
+
const data = req.body;
|
|
28026
|
+
const id = req.params.id ?? "";
|
|
28027
|
+
const validation = Joi35.object({
|
|
28028
|
+
id: Joi35.string().hex().required(),
|
|
28029
|
+
value: schemaUpdateOptions
|
|
28030
|
+
});
|
|
28031
|
+
const { error } = validation.validate({ id, value: data });
|
|
28032
|
+
if (error) {
|
|
28033
|
+
next(new BadRequestError64(error.message));
|
|
28034
|
+
return;
|
|
28035
|
+
}
|
|
28036
|
+
try {
|
|
28037
|
+
const buildingUnit = await _updateById(id, data);
|
|
28038
|
+
res.json({
|
|
28039
|
+
message: "Building unit updated successfully.",
|
|
28040
|
+
data: { buildingUnit }
|
|
28041
|
+
});
|
|
28042
|
+
} catch (error2) {
|
|
28043
|
+
next(error2);
|
|
28044
|
+
}
|
|
28045
|
+
}
|
|
28046
|
+
async function getAll(req, res, next) {
|
|
28047
|
+
const query = req.query;
|
|
28048
|
+
const validation = Joi35.object({
|
|
28049
|
+
page: Joi35.number().min(1).optional().allow("", null),
|
|
28050
|
+
limit: Joi35.number().min(1).optional().allow("", null),
|
|
28051
|
+
search: Joi35.string().optional().allow("", null),
|
|
28052
|
+
school: Joi35.string().hex().optional().allow("", null),
|
|
28053
|
+
building: Joi35.string().hex().optional().allow("", null),
|
|
28054
|
+
status: Joi35.string().optional().allow("", null)
|
|
28055
|
+
});
|
|
28056
|
+
const { error } = validation.validate(query);
|
|
28057
|
+
if (error) {
|
|
28058
|
+
next(new BadRequestError64(error.message));
|
|
28059
|
+
return;
|
|
28060
|
+
}
|
|
28061
|
+
const page = parseInt(req.query.page) ?? 1;
|
|
28062
|
+
let limit = parseInt(req.query.limit) ?? 20;
|
|
28063
|
+
limit = isNaN(limit) ? 20 : limit;
|
|
28064
|
+
const sort = req.query.sort ? String(req.query.sort).split(",") : "";
|
|
28065
|
+
const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
|
|
28066
|
+
const sortObj = {};
|
|
28067
|
+
if (sort && Array.isArray(sort) && sort.length && sortOrder && Array.isArray(sortOrder) && sortOrder.length) {
|
|
28068
|
+
sort.forEach((field, index) => {
|
|
28069
|
+
sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
|
|
28070
|
+
});
|
|
28071
|
+
}
|
|
28072
|
+
const status = req.query.status ?? "active";
|
|
28073
|
+
const school = req.query.school ?? "";
|
|
28074
|
+
const building = req.query.building ?? "";
|
|
28075
|
+
const search = req.query.search ?? "";
|
|
28076
|
+
try {
|
|
28077
|
+
const buildings = await _getAll({
|
|
28078
|
+
page,
|
|
28079
|
+
limit,
|
|
28080
|
+
sort: sortObj,
|
|
28081
|
+
status,
|
|
28082
|
+
school,
|
|
28083
|
+
search,
|
|
28084
|
+
building
|
|
28085
|
+
});
|
|
28086
|
+
res.json(buildings);
|
|
28087
|
+
return;
|
|
28088
|
+
} catch (error2) {
|
|
28089
|
+
next(error2);
|
|
28090
|
+
}
|
|
28091
|
+
}
|
|
28092
|
+
async function getById(req, res, next) {
|
|
28093
|
+
const id = req.params.id;
|
|
28094
|
+
const validation = Joi35.object({
|
|
28095
|
+
id: Joi35.string().hex().required()
|
|
28096
|
+
});
|
|
28097
|
+
const { error } = validation.validate({ id });
|
|
28098
|
+
if (error) {
|
|
28099
|
+
next(new BadRequestError64(error.message));
|
|
28100
|
+
return;
|
|
28101
|
+
}
|
|
28102
|
+
try {
|
|
28103
|
+
const buildingUnit = await _getById(id);
|
|
28104
|
+
res.json({
|
|
28105
|
+
message: "Successfully retrieved building unit.",
|
|
28106
|
+
data: { buildingUnit }
|
|
28107
|
+
});
|
|
28108
|
+
return;
|
|
28109
|
+
} catch (error2) {
|
|
28110
|
+
next(error2);
|
|
28111
|
+
}
|
|
28112
|
+
}
|
|
28113
|
+
async function deleteById(req, res, next) {
|
|
28114
|
+
const id = req.params.id;
|
|
28115
|
+
const validation = Joi35.object({
|
|
28116
|
+
id: Joi35.string().hex().required()
|
|
28117
|
+
});
|
|
28118
|
+
const { error } = validation.validate({ id });
|
|
28119
|
+
if (error) {
|
|
28120
|
+
next(new BadRequestError64(error.message));
|
|
28121
|
+
return;
|
|
28122
|
+
}
|
|
28123
|
+
try {
|
|
28124
|
+
const message = await _deleteById(id);
|
|
28125
|
+
res.json({ message });
|
|
28126
|
+
return;
|
|
28127
|
+
} catch (error2) {
|
|
28128
|
+
next(error2);
|
|
28129
|
+
}
|
|
28130
|
+
}
|
|
28131
|
+
return {
|
|
28132
|
+
add,
|
|
28133
|
+
getAll,
|
|
28134
|
+
getById,
|
|
28135
|
+
updateById,
|
|
28136
|
+
deleteById
|
|
28137
|
+
};
|
|
28138
|
+
}
|
|
27038
28139
|
export {
|
|
27039
28140
|
ACCESS_TOKEN_EXPIRY,
|
|
27040
28141
|
ACCESS_TOKEN_SECRET,
|
|
@@ -27053,6 +28154,8 @@ export {
|
|
|
27053
28154
|
MAILER_TRANSPORT_PORT,
|
|
27054
28155
|
MAILER_TRANSPORT_SECURE,
|
|
27055
28156
|
MAddress,
|
|
28157
|
+
MBuilding,
|
|
28158
|
+
MBuildingUnit,
|
|
27056
28159
|
MDivision,
|
|
27057
28160
|
MEntity,
|
|
27058
28161
|
MFile,
|
|
@@ -27093,17 +28196,25 @@ export {
|
|
|
27093
28196
|
addressSchema,
|
|
27094
28197
|
isDev,
|
|
27095
28198
|
schema,
|
|
28199
|
+
schemaBuilding,
|
|
28200
|
+
schemaBuildingUnit,
|
|
27096
28201
|
schemaDivision,
|
|
27097
28202
|
schemaRegion,
|
|
27098
28203
|
schemaSchool,
|
|
28204
|
+
schemaUpdateOptions,
|
|
27099
28205
|
useAddressController,
|
|
27100
28206
|
useAddressRepo,
|
|
27101
28207
|
useAuthController,
|
|
27102
28208
|
useAuthService,
|
|
28209
|
+
useBuildingController,
|
|
28210
|
+
useBuildingRepo,
|
|
28211
|
+
useBuildingUnitController,
|
|
28212
|
+
useBuildingUnitRepo,
|
|
27103
28213
|
useCounterModel,
|
|
27104
28214
|
useCounterRepo,
|
|
27105
28215
|
useDivisionController,
|
|
27106
28216
|
useDivisionRepo,
|
|
28217
|
+
useDivisionService,
|
|
27107
28218
|
useEntityController,
|
|
27108
28219
|
useEntityRepo,
|
|
27109
28220
|
useFileController,
|
|
@@ -27134,6 +28245,7 @@ export {
|
|
|
27134
28245
|
usePromoCodeRepo,
|
|
27135
28246
|
useRegionController,
|
|
27136
28247
|
useRegionRepo,
|
|
28248
|
+
useRegionService,
|
|
27137
28249
|
useRoleController,
|
|
27138
28250
|
useRoleRepo,
|
|
27139
28251
|
useSchoolController,
|