@7365admin1/core 2.61.0 → 2.63.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4301,7 +4301,9 @@ function useVerificationRepo() {
4301
4301
  status = "active",
4302
4302
  app = "",
4303
4303
  type = {},
4304
- email = ""
4304
+ email = "",
4305
+ siteId = "",
4306
+ orgId = ""
4305
4307
  }) {
4306
4308
  page = page > 0 ? page - 1 : 0;
4307
4309
  const query = { status };
@@ -4328,6 +4330,24 @@ function useVerificationRepo() {
4328
4330
  query.email = email;
4329
4331
  cacheOptions.email = email;
4330
4332
  }
4333
+ if (siteId) {
4334
+ const siteCandidates = [siteId];
4335
+ try {
4336
+ siteCandidates.push(new import_mongodb13.ObjectId(siteId));
4337
+ } catch {
4338
+ }
4339
+ query["metadata.siteId"] = { $in: siteCandidates };
4340
+ cacheOptions.siteId = siteId;
4341
+ }
4342
+ if (orgId) {
4343
+ const orgCandidates = [orgId];
4344
+ try {
4345
+ orgCandidates.push(new import_mongodb13.ObjectId(orgId));
4346
+ } catch {
4347
+ }
4348
+ query["metadata.org"] = { $in: orgCandidates };
4349
+ cacheOptions.orgId = orgId;
4350
+ }
4331
4351
  const cacheKey = (0, import_node_server_utils15.makeCacheKey)(namespace_collection, cacheOptions);
4332
4352
  const cachedData = await getCache(cacheKey);
4333
4353
  if (cachedData) {
@@ -8547,7 +8567,10 @@ function useVerificationController() {
8547
8567
  status: import_joi16.default.string().required(),
8548
8568
  app: import_joi16.default.string().optional().allow("", null),
8549
8569
  type: import_joi16.default.alternatives().try(import_joi16.default.string(), import_joi16.default.array().items(import_joi16.default.string())).optional().allow("", null),
8550
- email: import_joi16.default.string().optional().allow("", null)
8570
+ email: import_joi16.default.string().optional().allow("", null),
8571
+ siteId: import_joi16.default.string().hex().optional().allow("", null),
8572
+ orgId: import_joi16.default.string().hex().optional().allow("", null),
8573
+ limit: import_joi16.default.number().integer().min(1).allow("", null).default(10)
8551
8574
  });
8552
8575
  const query = { ...req.query };
8553
8576
  const { error } = validation.validate(query);
@@ -8561,6 +8584,9 @@ function useVerificationController() {
8561
8584
  const status = req.query.status ?? "pending";
8562
8585
  const app = req.query.app ?? "";
8563
8586
  const email = req.query.email ?? "";
8587
+ const siteId = req.query.siteId ?? "";
8588
+ const orgId = req.query.orgId ?? "";
8589
+ const limit = parseInt(req.query.limit ?? "10");
8564
8590
  const type = req.query.type ? String(req.query.type).split(",") : "";
8565
8591
  const typeObj = {};
8566
8592
  if (type && Array.isArray(type) && type.length) {
@@ -8575,7 +8601,10 @@ function useVerificationController() {
8575
8601
  status,
8576
8602
  app,
8577
8603
  type: typeObj,
8578
- email
8604
+ email,
8605
+ siteId,
8606
+ orgId,
8607
+ limit
8579
8608
  });
8580
8609
  res.json(data);
8581
8610
  return;
@@ -12260,6 +12289,7 @@ function useServiceProviderRepo() {
12260
12289
  throw new import_node_server_utils56.BadRequestError("Invalid site ID format.");
12261
12290
  }
12262
12291
  }
12292
+ cacheOptions.membersLookup = "1";
12263
12293
  const cacheKey = (0, import_node_server_utils56.makeCacheKey)(namespace_collection, cacheOptions);
12264
12294
  const cachedData = await getCache(cacheKey);
12265
12295
  if (cachedData) {
@@ -12275,7 +12305,7 @@ function useServiceProviderRepo() {
12275
12305
  localField: "serviceProviderOrgId",
12276
12306
  foreignField: "_id",
12277
12307
  as: "organization",
12278
- pipeline: [{ $project: { nature: 1 } }]
12308
+ pipeline: [{ $project: { nature: 1, email: 1 } }]
12279
12309
  }
12280
12310
  },
12281
12311
  {
@@ -12284,17 +12314,50 @@ function useServiceProviderRepo() {
12284
12314
  preserveNullAndEmptyArrays: true
12285
12315
  }
12286
12316
  },
12317
+ {
12318
+ $lookup: {
12319
+ from: "members",
12320
+ let: { spOrgId: "$serviceProviderOrgId" },
12321
+ pipeline: [
12322
+ {
12323
+ $match: {
12324
+ $expr: { $eq: ["$org", "$$spOrgId"] },
12325
+ status: "active"
12326
+ }
12327
+ },
12328
+ { $count: "c" }
12329
+ ],
12330
+ as: "_memberCount"
12331
+ }
12332
+ },
12287
12333
  {
12288
12334
  $project: {
12289
12335
  name: 1,
12290
12336
  type: 1,
12337
+ email: {
12338
+ $cond: {
12339
+ if: {
12340
+ $gt: [{ $strLenCP: { $ifNull: ["$email", ""] } }, 0]
12341
+ },
12342
+ then: "$email",
12343
+ else: { $ifNull: ["$organization.email", ""] }
12344
+ }
12345
+ },
12291
12346
  nature: "$organization.nature",
12292
12347
  orgId: 1,
12293
12348
  siteId: 1,
12294
12349
  siteName: 1,
12295
12350
  serviceProviderOrgId: 1,
12296
12351
  status: 1,
12297
- category: 1
12352
+ category: 1,
12353
+ members: {
12354
+ $let: {
12355
+ vars: {
12356
+ mc: { $arrayElemAt: ["$_memberCount", 0] }
12357
+ },
12358
+ in: { $ifNull: ["$$mc.c", 0] }
12359
+ }
12360
+ }
12298
12361
  }
12299
12362
  },
12300
12363
  { $sort: sort },
@@ -18292,6 +18355,167 @@ function useVehicleService() {
18292
18355
  throw error;
18293
18356
  }
18294
18357
  }
18358
+ async function blocklistVehicles(_id, value) {
18359
+ const session = import_node_server_utils75.useAtlas.getClient()?.startSession();
18360
+ if (!session) {
18361
+ throw new Error("Unable to start session for vehicle service.");
18362
+ }
18363
+ try {
18364
+ session.startTransaction();
18365
+ const vehicle = await _getVehicleById(_id);
18366
+ const plate = vehicle.plates.find((p) => p._id.toString() === _id);
18367
+ const _name = value.name ? value.name : vehicle.name;
18368
+ const _plateNumber = plate?.plateNumber;
18369
+ const _start = vehicle.start;
18370
+ const _end = vehicle.end;
18371
+ const _recNo = plate.recNo;
18372
+ const _type = plate.type;
18373
+ if (value.peopleId) {
18374
+ value.peopleId = new import_mongodb46.ObjectId(value.peopleId);
18375
+ }
18376
+ const { site } = value;
18377
+ const startDahua = formatDahuaDate(_start);
18378
+ const endPlus24Hours = _end ? _end : new Date(new Date(_end).getTime() + 24 * 60 * 60 * 1e3);
18379
+ const endDahua = formatDahuaDate(endPlus24Hours);
18380
+ if (_plateNumber) {
18381
+ const siteCameras = [];
18382
+ let page = 1;
18383
+ let pages = 1;
18384
+ const limit = 20;
18385
+ do {
18386
+ const siteCameraReq = await _getAllSiteCameras({
18387
+ site,
18388
+ type: "anpr",
18389
+ direction: ["both", "entry"],
18390
+ page,
18391
+ limit
18392
+ });
18393
+ pages = siteCameraReq.pages || 1;
18394
+ siteCameras.push(...siteCameraReq.items);
18395
+ page++;
18396
+ } while (page < pages);
18397
+ if (!siteCameras.length) {
18398
+ throw new import_node_server_utils75.BadRequestError("No site cameras found.");
18399
+ }
18400
+ for (const camera of siteCameras) {
18401
+ const { host, username, password } = camera;
18402
+ const removePlateNumber = {
18403
+ host,
18404
+ username,
18405
+ password,
18406
+ mode: _type === "blocklist" /* BLOCKLIST */ ? "TrafficBlackList" /* TRAFFIC_BLACKLIST */ : "TrafficRedList" /* TRAFFIC_REDLIST */,
18407
+ recno: _recNo
18408
+ };
18409
+ const responseForDeletion = await _removePlateNumber(
18410
+ removePlateNumber
18411
+ );
18412
+ if (responseForDeletion?.statusCode !== 200) {
18413
+ throw new import_node_server_utils75.BadRequestError("Failed to delete plate number to ANPR");
18414
+ }
18415
+ const dahuaPayload = {
18416
+ host,
18417
+ username,
18418
+ password,
18419
+ plateNumber: _plateNumber,
18420
+ mode: "TrafficBlackList" /* TRAFFIC_BLACKLIST */,
18421
+ owner: _name,
18422
+ ...startDahua ? { start: startDahua } : {},
18423
+ ...endDahua ? { end: endDahua } : {}
18424
+ };
18425
+ const dahuaResponse = await _addPlateNumber(dahuaPayload);
18426
+ if (dahuaResponse?.statusCode !== 200) {
18427
+ throw new import_node_server_utils75.BadRequestError("Failed to update plate number to ANPR");
18428
+ }
18429
+ const responseData = dahuaResponse?.data?.toString("utf-8") ?? "";
18430
+ value.recNo = responseData.split("=")[1]?.trim();
18431
+ const normalizedPlateNumber = _plateNumber;
18432
+ if (value.peopleId && value.recNo) {
18433
+ await _pushVehicleById(
18434
+ value.peopleId,
18435
+ {
18436
+ plateNumber: normalizedPlateNumber,
18437
+ recNo: value.recNo
18438
+ },
18439
+ session
18440
+ );
18441
+ }
18442
+ }
18443
+ }
18444
+ const formattedValue = {
18445
+ type: "blocklist" /* BLOCKLIST */,
18446
+ recNo: value.recNo
18447
+ };
18448
+ await _updateVehicleById(_id, formattedValue, session);
18449
+ await session.commitTransaction();
18450
+ } catch (error) {
18451
+ await session.abortTransaction();
18452
+ throw error;
18453
+ } finally {
18454
+ session.endSession();
18455
+ }
18456
+ }
18457
+ async function removeFromBlocklist(_id, value) {
18458
+ const session = import_node_server_utils75.useAtlas.getClient()?.startSession();
18459
+ if (!session) {
18460
+ throw new Error("Unable to start session for vehicle service.");
18461
+ }
18462
+ try {
18463
+ session.startTransaction();
18464
+ const vehicle = await _getVehicleById(_id);
18465
+ const plate = vehicle.plates.find((p) => p._id.toString() === _id);
18466
+ const _plateNumber = plate?.plateNumber;
18467
+ const _recNo = plate.recNo;
18468
+ if (value.peopleId) {
18469
+ value.peopleId = new import_mongodb46.ObjectId(value.peopleId);
18470
+ }
18471
+ const { site } = value;
18472
+ if (_plateNumber) {
18473
+ const siteCameras = [];
18474
+ let page = 1;
18475
+ let pages = 1;
18476
+ const limit = 20;
18477
+ do {
18478
+ const siteCameraReq = await _getAllSiteCameras({
18479
+ site,
18480
+ type: "anpr",
18481
+ direction: ["both", "entry"],
18482
+ page,
18483
+ limit
18484
+ });
18485
+ pages = siteCameraReq.pages || 1;
18486
+ siteCameras.push(...siteCameraReq.items);
18487
+ page++;
18488
+ } while (page < pages);
18489
+ if (!siteCameras.length) {
18490
+ throw new import_node_server_utils75.BadRequestError("No site cameras found.");
18491
+ }
18492
+ for (const camera of siteCameras) {
18493
+ const { host, username, password } = camera;
18494
+ const removePlateNumber = {
18495
+ host,
18496
+ username,
18497
+ password,
18498
+ mode: "TrafficBlackList" /* TRAFFIC_BLACKLIST */,
18499
+ recno: _recNo
18500
+ };
18501
+ console.log(removePlateNumber);
18502
+ const responseForDeletion = await _removePlateNumber(
18503
+ removePlateNumber
18504
+ );
18505
+ if (responseForDeletion?.statusCode !== 200) {
18506
+ throw new import_node_server_utils75.BadRequestError("Failed to delete plate number to ANPR");
18507
+ }
18508
+ }
18509
+ }
18510
+ await _deleteVehicle(_id, session);
18511
+ await session.commitTransaction();
18512
+ } catch (error) {
18513
+ await session.abortTransaction();
18514
+ throw error;
18515
+ } finally {
18516
+ session.endSession();
18517
+ }
18518
+ }
18295
18519
  return {
18296
18520
  add,
18297
18521
  deleteVehicle,
@@ -18299,7 +18523,9 @@ function useVehicleService() {
18299
18523
  processDeletingExpiredVehicles,
18300
18524
  reactivateVehicleById,
18301
18525
  updateVehicleById,
18302
- bulkUpsertVehicles
18526
+ bulkUpsertVehicles,
18527
+ blocklistVehicles,
18528
+ removeFromBlocklist
18303
18529
  };
18304
18530
  }
18305
18531
 
@@ -20650,7 +20876,7 @@ function useBuildingService() {
20650
20876
  getByBuildingLevel,
20651
20877
  updateLevelByBuildingLevel,
20652
20878
  updateByBuildingId,
20653
- add: _addBuildingUnit
20879
+ bulkAddBuildingUnits: _bulkAddBuildingUnits
20654
20880
  } = useBuildingUnitRepo();
20655
20881
  const { updateStatusById } = useFileRepo();
20656
20882
  const { deleteFile } = useFileService();
@@ -20839,15 +21065,16 @@ function useBuildingService() {
20839
21065
  companyName: "",
20840
21066
  companyRegistrationNumber: "",
20841
21067
  billing: [],
20842
- unitNumber: parseInt(unit.replace("Unit ", ""), 10) || null
21068
+ unitNumber: parseInt(unit.replace("Unit ", ""), 10) || null,
21069
+ createdAt: /* @__PURE__ */ new Date(),
21070
+ updatedAt: "",
21071
+ deletedAt: ""
20843
21072
  });
20844
21073
  });
20845
21074
  });
20846
21075
  }
20847
21076
  );
20848
- for (const buildingUnitPayload of buildingUnitPayloads) {
20849
- const result = await _addBuildingUnit(buildingUnitPayload);
20850
- }
21077
+ await _bulkAddBuildingUnits(buildingUnitPayloads);
20851
21078
  await session?.commitTransaction();
20852
21079
  return { buildingPayloads, buildingUnitPayloads };
20853
21080
  } catch (error) {
@@ -21588,7 +21815,9 @@ function useVehicleController() {
21588
21815
  approveVehicleById: _approveVehicleById,
21589
21816
  reactivateVehicleById: _reactivateVehicleById,
21590
21817
  updateVehicleById: _updateVehicleById,
21591
- bulkUpsertVehicles: _bulkUpsertVehicles
21818
+ bulkUpsertVehicles: _bulkUpsertVehicles,
21819
+ blocklistVehicles: _blocklistVehicles,
21820
+ removeFromBlocklist: _removeFromBlocklist
21592
21821
  } = useVehicleService();
21593
21822
  const {
21594
21823
  getSeasonPassTypes: _getSeasonPassTypes,
@@ -22165,6 +22394,68 @@ function useVehicleController() {
22165
22394
  return;
22166
22395
  }
22167
22396
  }
22397
+ async function blocklistVehicles(req, res, next) {
22398
+ try {
22399
+ const schema2 = import_joi47.default.object({
22400
+ _id: import_joi47.default.string().hex().length(24).required(),
22401
+ site: import_joi47.default.string().hex().length(24).required(),
22402
+ peopleId: import_joi47.default.string().hex().length(24).optional().allow(null, ""),
22403
+ remarks: import_joi47.default.string().optional().allow("", null)
22404
+ });
22405
+ const { error, value } = schema2.validate(
22406
+ {
22407
+ _id: req.params.id,
22408
+ ...req.body
22409
+ },
22410
+ { abortEarly: false }
22411
+ );
22412
+ if (error) {
22413
+ const messages = error.details.map((d) => d.message).join(", ");
22414
+ import_node_server_utils88.logger.log({ level: "error", message: messages });
22415
+ next(new import_node_server_utils88.BadRequestError(messages));
22416
+ return;
22417
+ }
22418
+ const { _id, ...rest } = value;
22419
+ await _blocklistVehicles(_id, rest);
22420
+ res.json({ message: "Successfully blocked vehicle." });
22421
+ return;
22422
+ } catch (error) {
22423
+ import_node_server_utils88.logger.log({ level: "error", message: error.message });
22424
+ next(error);
22425
+ return;
22426
+ }
22427
+ }
22428
+ async function removeFromBlocklist(req, res, next) {
22429
+ try {
22430
+ const schema2 = import_joi47.default.object({
22431
+ _id: import_joi47.default.string().hex().length(24).required(),
22432
+ site: import_joi47.default.string().hex().length(24).required(),
22433
+ peopleId: import_joi47.default.string().hex().length(24).optional().allow(null, ""),
22434
+ remarks: import_joi47.default.string().optional().allow("", null)
22435
+ });
22436
+ const { error, value } = schema2.validate(
22437
+ {
22438
+ _id: req.params.id,
22439
+ ...req.body
22440
+ },
22441
+ { abortEarly: false }
22442
+ );
22443
+ if (error) {
22444
+ const messages = error.details.map((d) => d.message).join(", ");
22445
+ import_node_server_utils88.logger.log({ level: "error", message: messages });
22446
+ next(new import_node_server_utils88.BadRequestError(messages));
22447
+ return;
22448
+ }
22449
+ const { _id, ...rest } = value;
22450
+ await _removeFromBlocklist(_id, rest);
22451
+ res.json({ message: "Successfully removed vehicle from blocklist." });
22452
+ return;
22453
+ } catch (error) {
22454
+ import_node_server_utils88.logger.log({ level: "error", message: error.message });
22455
+ next(error);
22456
+ return;
22457
+ }
22458
+ }
22168
22459
  return {
22169
22460
  add,
22170
22461
  getVehicles,
@@ -22178,7 +22469,9 @@ function useVehicleController() {
22178
22469
  getAllVehiclesByUnitId,
22179
22470
  uploadSpreadsheetVehicles,
22180
22471
  getSpecificVehicleById,
22181
- getBlocklistedVehicles
22472
+ getBlocklistedVehicles,
22473
+ blocklistVehicles,
22474
+ removeFromBlocklist
22182
22475
  };
22183
22476
  }
22184
22477
 
@@ -31669,6 +31962,18 @@ function MBulletinBoard(value) {
31669
31962
  throw new Error("Invalid org ID.");
31670
31963
  }
31671
31964
  }
31965
+ if (value.file && Array.isArray(value.file)) {
31966
+ value.file = value.file.map((f) => {
31967
+ if (f._id && typeof f._id === "string") {
31968
+ try {
31969
+ return { ...f, _id: new import_mongodb78.ObjectId(f._id) };
31970
+ } catch {
31971
+ throw new Error("Invalid file ID.");
31972
+ }
31973
+ }
31974
+ return f;
31975
+ });
31976
+ }
31672
31977
  return {
31673
31978
  _id: value._id ?? new import_mongodb78.ObjectId(),
31674
31979
  site: value.site ?? "",
@@ -31737,7 +32042,8 @@ function useBulletinBoardRepo() {
31737
32042
  sort = {},
31738
32043
  site = "",
31739
32044
  status = "active",
31740
- recipients = []
32045
+ recipients = [],
32046
+ expiration
31741
32047
  }, session) {
31742
32048
  page = page > 0 ? page - 1 : 0;
31743
32049
  try {
@@ -31748,8 +32054,13 @@ function useBulletinBoardRepo() {
31748
32054
  const query = {
31749
32055
  site,
31750
32056
  status,
31751
- ...search && { $text: { $search: search } },
31752
- ...recipients?.length && { recipients: { $in: recipients } }
32057
+ ...search && {
32058
+ $or: [{ title: { $regex: search, $options: "i" } }]
32059
+ },
32060
+ ...recipients?.length && { recipients: { $all: recipients } },
32061
+ ...expiration !== void 0 && {
32062
+ noExpiration: expiration === "yes"
32063
+ }
31753
32064
  };
31754
32065
  sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
31755
32066
  const cacheOptions = {
@@ -31759,7 +32070,8 @@ function useBulletinBoardRepo() {
31759
32070
  page,
31760
32071
  limit,
31761
32072
  ...search && { search },
31762
- ...recipients?.length && { recipients: recipients.sort().join(",") }
32073
+ ...recipients?.length && { recipients: recipients.sort().join(",") },
32074
+ ...expiration !== void 0 && { expiration }
31763
32075
  };
31764
32076
  const cacheKey = (0, import_node_server_utils136.makeCacheKey)(
31765
32077
  bulletin_boards_namespace_collection,
@@ -31947,7 +32259,9 @@ function useBulletinBoardRepo() {
31947
32259
  { session }
31948
32260
  );
31949
32261
  if (res.matchedCount === 0) {
31950
- throw new import_node_server_utils136.NotFoundError("No upcoming bulletin boards found to activate.");
32262
+ throw new import_node_server_utils136.NotFoundError(
32263
+ "No upcoming bulletin boards found to activate."
32264
+ );
31951
32265
  }
31952
32266
  delNamespace().then(() => {
31953
32267
  import_node_server_utils136.logger.info(
@@ -31987,7 +32301,7 @@ function useBulletinBoardService() {
31987
32301
  deleteBulletinBoardById: _deleteBulletinBoardById,
31988
32302
  getBulletinBoardById: _getBulletinBoardById
31989
32303
  } = useBulletinBoardRepo();
31990
- const { deleteFileById: _deleteFileById } = useFileRepo();
32304
+ const { deleteFileById: _deleteFileById, updateStatusById } = useFileRepo();
31991
32305
  async function add(value) {
31992
32306
  const session = import_node_server_utils137.useAtlas.getClient()?.startSession();
31993
32307
  session?.startTransaction();
@@ -31995,6 +32309,21 @@ function useBulletinBoardService() {
31995
32309
  value.status = "upcoming" /* UPCOMING */;
31996
32310
  }
31997
32311
  try {
32312
+ const bulletinFiles = value?.file ?? [];
32313
+ if (bulletinFiles.length > 0) {
32314
+ for (const bulletinFile of bulletinFiles) {
32315
+ if (!bulletinFile._id)
32316
+ continue;
32317
+ const file = await updateStatusById(
32318
+ bulletinFile._id.toString(),
32319
+ { status: "active" },
32320
+ session
32321
+ );
32322
+ if (!file) {
32323
+ throw new import_node_server_utils137.NotFoundError("File not found.");
32324
+ }
32325
+ }
32326
+ }
31998
32327
  await _add(value, session);
31999
32328
  await session?.commitTransaction();
32000
32329
  return "Successfully added bulletin board.";
@@ -32118,32 +32447,35 @@ function useBulletinBoardController() {
32118
32447
  order: import_joi77.default.string().valid(...Object.values(BulletinOrder)).default("desc" /* DESC */),
32119
32448
  site: import_joi77.default.string().hex().length(24).required(),
32120
32449
  status: import_joi77.default.string().valid(...Object.values(BulletinStatus)).optional().default("active" /* ACTIVE */),
32121
- recipients: import_joi77.default.alternatives().try(
32122
- import_joi77.default.array().items(
32123
- import_joi77.default.string().valid(...Object.values(BulletinRecipient))
32124
- ),
32125
- import_joi77.default.string().allow("")
32126
- ).optional().allow(null).custom((value2, helpers) => {
32127
- if (!value2 || value2 === "") {
32450
+ recipients: import_joi77.default.any().optional().allow(null, "").custom((value2, helpers) => {
32451
+ if (!value2 || value2 === "")
32128
32452
  return [];
32129
- }
32130
- let parsed = [];
32453
+ let parsed;
32131
32454
  if (Array.isArray(value2)) {
32132
32455
  parsed = value2;
32133
- } else if (typeof value2 === "string") {
32134
- parsed = value2.split(",").map((v) => v.trim()).filter(Boolean);
32135
- }
32136
- for (const r of parsed) {
32137
- if (!Object.values(BulletinRecipient).includes(r)) {
32138
- return helpers.error("any.only");
32456
+ } else if (typeof value2 === "string" && value2.trim().startsWith("[")) {
32457
+ try {
32458
+ const result = JSON.parse(value2);
32459
+ parsed = Array.isArray(result) ? result : [value2];
32460
+ } catch {
32461
+ return helpers.error("any.invalid");
32139
32462
  }
32463
+ } else {
32464
+ parsed = [value2];
32140
32465
  }
32466
+ const validValues = Object.values(BulletinRecipient);
32467
+ const isValid = parsed.every(
32468
+ (r) => validValues.includes(r)
32469
+ );
32470
+ if (!isValid)
32471
+ return helpers.error("any.invalid");
32141
32472
  return parsed;
32142
32473
  }).messages({
32143
- "any.only": `Recipients must be one of: ${Object.values(
32474
+ "any.invalid": `Recipients must be one of: ${Object.values(
32144
32475
  BulletinRecipient
32145
32476
  ).join(", ")}`
32146
- })
32477
+ }),
32478
+ expiration: import_joi77.default.string().valid("yes", "no").optional().allow("", null)
32147
32479
  });
32148
32480
  const { error, value } = validation.validate(req.query, {
32149
32481
  abortEarly: false
@@ -32154,7 +32486,17 @@ function useBulletinBoardController() {
32154
32486
  next(new import_node_server_utils138.BadRequestError(messages));
32155
32487
  return;
32156
32488
  }
32157
- const { search, page, limit, site, status, recipients, sort, order } = value;
32489
+ const {
32490
+ search,
32491
+ page,
32492
+ limit,
32493
+ site,
32494
+ status,
32495
+ recipients,
32496
+ sort,
32497
+ order,
32498
+ expiration
32499
+ } = value;
32158
32500
  const sortObj = {
32159
32501
  [sort ? sort : "_id" /* ID */]: order === "asc" /* ASC */ ? 1 : -1
32160
32502
  };
@@ -32166,7 +32508,8 @@ function useBulletinBoardController() {
32166
32508
  sort: sortObj,
32167
32509
  site,
32168
32510
  status,
32169
- recipients
32511
+ recipients,
32512
+ expiration
32170
32513
  });
32171
32514
  res.status(200).json(data);
32172
32515
  return;
@@ -37756,6 +38099,19 @@ function UseAccessManagementRepo() {
37756
38099
  await session?.endSession();
37757
38100
  }
37758
38101
  }
38102
+ async function uploadTemplateRepo({ site, id, name }) {
38103
+ site = new import_mongodb90.ObjectId(site);
38104
+ id = new import_mongodb90.ObjectId(id);
38105
+ try {
38106
+ const result = await collectionName("sites").updateOne(
38107
+ { _id: site },
38108
+ { $set: { "siteSettings.entryPass.settings.template": { id, name } } }
38109
+ );
38110
+ return result;
38111
+ } catch (error) {
38112
+ throw new Error(error.message);
38113
+ }
38114
+ }
37759
38115
  return {
37760
38116
  createIndexes,
37761
38117
  createIndexForEntrypass,
@@ -37790,7 +38146,8 @@ function UseAccessManagementRepo() {
37790
38146
  indexCombination,
37791
38147
  getTransactionsRepo,
37792
38148
  assignMultipleCardsRepo,
37793
- visitorCheckoutRepo
38149
+ visitorCheckoutRepo,
38150
+ uploadTemplateRepo
37794
38151
  };
37795
38152
  }
37796
38153
 
@@ -37833,7 +38190,8 @@ function useAccessManagementSvc() {
37833
38190
  getBlockLevelAndUnitListRepo,
37834
38191
  getTransactionsRepo,
37835
38192
  assignMultipleCardsRepo,
37836
- visitorCheckoutRepo
38193
+ visitorCheckoutRepo,
38194
+ uploadTemplateRepo
37837
38195
  } = UseAccessManagementRepo();
37838
38196
  const addPhysicalCardSvc = async (payload) => {
37839
38197
  try {
@@ -38146,7 +38504,15 @@ function useAccessManagementSvc() {
38146
38504
  const response = await visitorCheckoutRepo({ userId });
38147
38505
  return response;
38148
38506
  } catch (err) {
38149
- return Promise.reject("Server internal error.");
38507
+ throw new Error(err.message);
38508
+ }
38509
+ };
38510
+ const uploadTemplateSvc = async ({ site, id, name }) => {
38511
+ try {
38512
+ const response = await uploadTemplateRepo({ site, id, name });
38513
+ return response;
38514
+ } catch (err) {
38515
+ throw new Error(err.message);
38150
38516
  }
38151
38517
  };
38152
38518
  return {
@@ -38186,7 +38552,8 @@ function useAccessManagementSvc() {
38186
38552
  getBlockLevelAndUnitListSvc,
38187
38553
  getTransactionsSvc,
38188
38554
  assignMultipleCardsSvc,
38189
- visitorCheckoutSvc
38555
+ visitorCheckoutSvc,
38556
+ uploadTemplateSvc
38190
38557
  };
38191
38558
  }
38192
38559
 
@@ -38229,7 +38596,8 @@ function useAccessManagementController() {
38229
38596
  getBlockLevelAndUnitListSvc,
38230
38597
  getTransactionsSvc,
38231
38598
  assignMultipleCardsSvc,
38232
- visitorCheckoutSvc
38599
+ visitorCheckoutSvc,
38600
+ uploadTemplateSvc
38233
38601
  } = useAccessManagementSvc();
38234
38602
  const addPhysicalCard = async (req, res) => {
38235
38603
  try {
@@ -39046,7 +39414,32 @@ function useAccessManagementController() {
39046
39414
  const result = await visitorCheckoutSvc({ userId });
39047
39415
  return res.status(200).json({ message: "Success", data: result });
39048
39416
  } catch (error) {
39049
- return Promise.reject("Internal Server Error");
39417
+ return res.status(400).json({
39418
+ data: null,
39419
+ message: error.message
39420
+ });
39421
+ }
39422
+ };
39423
+ const uploadTemplate = async (req, res) => {
39424
+ try {
39425
+ const { site } = req.query;
39426
+ const { id, name } = req.body;
39427
+ const schema2 = import_joi86.default.object({
39428
+ site: import_joi86.default.string().hex().required(),
39429
+ id: import_joi86.default.string().hex().required(),
39430
+ name: import_joi86.default.string().required()
39431
+ });
39432
+ const { error } = schema2.validate({ site, id, name });
39433
+ if (error) {
39434
+ return res.status(400).json({ message: error.message });
39435
+ }
39436
+ const result = await uploadTemplateSvc({ site, id, name });
39437
+ return res.status(200).json({ message: "Success", data: result });
39438
+ } catch (error) {
39439
+ return res.status(400).json({
39440
+ data: null,
39441
+ message: error.message
39442
+ });
39050
39443
  }
39051
39444
  };
39052
39445
  return {
@@ -39084,7 +39477,8 @@ function useAccessManagementController() {
39084
39477
  getBlockLevelAndUnitList,
39085
39478
  getTransactions: getTransactions2,
39086
39479
  assignMultipleCards,
39087
- visitorCheckout
39480
+ visitorCheckout,
39481
+ uploadTemplate
39088
39482
  };
39089
39483
  }
39090
39484
 
@@ -40311,7 +40705,9 @@ function useBulletinVideoRepo() {
40311
40705
  page = 1,
40312
40706
  limit = 10,
40313
40707
  sort = {},
40314
- site = ""
40708
+ site = "",
40709
+ startDate,
40710
+ endDate
40315
40711
  }, session) {
40316
40712
  page = page > 0 ? page - 1 : 0;
40317
40713
  try {
@@ -40319,10 +40715,33 @@ function useBulletinVideoRepo() {
40319
40715
  } catch (error) {
40320
40716
  throw new import_node_server_utils162.BadRequestError("Invalid site ID format.");
40321
40717
  }
40718
+ let dateExpr = {};
40719
+ if (startDate && endDate) {
40720
+ const startingDate = new Date(startDate);
40721
+ startingDate.setUTCHours(0, 0, 0, 0);
40722
+ const endingDate = new Date(endDate);
40723
+ endingDate.setUTCHours(23, 59, 59, 999);
40724
+ const parsedCreatedAt = {
40725
+ $dateFromString: {
40726
+ dateString: "$createdAt",
40727
+ onError: /* @__PURE__ */ new Date(0),
40728
+ onNull: /* @__PURE__ */ new Date(0)
40729
+ }
40730
+ };
40731
+ dateExpr = {
40732
+ $expr: {
40733
+ $and: [
40734
+ { $gte: [parsedCreatedAt, startingDate] },
40735
+ { $lte: [parsedCreatedAt, endingDate] }
40736
+ ]
40737
+ }
40738
+ };
40739
+ }
40322
40740
  const query = {
40323
40741
  site,
40324
40742
  status: { $ne: "deleted" },
40325
- ...search && { $text: { $search: search } }
40743
+ ...search && { $text: { $search: search } },
40744
+ ...dateExpr
40326
40745
  };
40327
40746
  sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
40328
40747
  const cacheOptions = {
@@ -40331,7 +40750,9 @@ function useBulletinVideoRepo() {
40331
40750
  page,
40332
40751
  limit,
40333
40752
  status: { $ne: "deleted" },
40334
- ...search && { search }
40753
+ ...search && { search },
40754
+ ...startDate && { startDate },
40755
+ ...endDate && { endDate }
40335
40756
  };
40336
40757
  if (search) {
40337
40758
  query.$or = [
@@ -40487,11 +40908,22 @@ function useBulletinVideoService() {
40487
40908
  deleteBulletinVideoById: _deleteBulletinVideoById,
40488
40909
  getBulletinVideoById: _getBulletinVideoById
40489
40910
  } = useBulletinVideoRepo();
40490
- const { deleteFileById: _deleteFileById } = useFileRepo();
40911
+ const { deleteFileById: _deleteFileById, updateStatusById } = useFileRepo();
40491
40912
  async function add(value) {
40492
40913
  const session = import_node_server_utils163.useAtlas.getClient()?.startSession();
40493
40914
  session?.startTransaction();
40494
40915
  try {
40916
+ const bulletinVideo = value.file;
40917
+ if (bulletinVideo) {
40918
+ const file = await updateStatusById(
40919
+ bulletinVideo,
40920
+ { status: "active" },
40921
+ session
40922
+ );
40923
+ if (!file) {
40924
+ throw new import_node_server_utils163.NotFoundError("File not found.");
40925
+ }
40926
+ }
40495
40927
  await _add(value, session);
40496
40928
  await session?.commitTransaction();
40497
40929
  return "Successfully added bulletin video.";
@@ -40579,7 +41011,9 @@ function useBulletinVideoController() {
40579
41011
  limit: import_joi92.default.number().integer().min(1).max(100).allow("", null).default(10),
40580
41012
  sort: import_joi92.default.string().valid(...Object.values(BulletinVideoSort)).default("_id" /* ID */),
40581
41013
  order: import_joi92.default.string().valid(...Object.values(BulletinVideoOrder)).default("desc" /* DESC */),
40582
- site: import_joi92.default.string().hex().length(24).required()
41014
+ site: import_joi92.default.string().hex().length(24).required(),
41015
+ startDate: import_joi92.default.string().optional().allow("", null),
41016
+ endDate: import_joi92.default.string().optional().allow("", null)
40583
41017
  });
40584
41018
  const { error, value } = validation.validate(req.query, {
40585
41019
  abortEarly: false
@@ -40590,7 +41024,7 @@ function useBulletinVideoController() {
40590
41024
  next(new import_node_server_utils164.BadRequestError(messages));
40591
41025
  return;
40592
41026
  }
40593
- const { search, page, limit, site, sort, order } = value;
41027
+ const { search, page, limit, site, sort, order, startDate, endDate } = value;
40594
41028
  const sortObj = {
40595
41029
  [sort ?? "_id" /* ID */]: order === "asc" /* ASC */ ? 1 : -1
40596
41030
  };
@@ -40600,7 +41034,9 @@ function useBulletinVideoController() {
40600
41034
  page,
40601
41035
  limit,
40602
41036
  sort: sortObj,
40603
- site
41037
+ site,
41038
+ startDate,
41039
+ endDate
40604
41040
  });
40605
41041
  res.status(200).json(data);
40606
41042
  return;