@7365admin1/core 2.56.0 → 2.58.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.mjs CHANGED
@@ -4892,34 +4892,55 @@ function useSiteRepo() {
4892
4892
  const query = {
4893
4893
  status: { $ne: "deleted" }
4894
4894
  };
4895
- const cacheOptions = {
4896
- status: { $ne: "deleted" },
4897
- page,
4898
- limit
4899
- };
4900
4895
  if (search) {
4901
4896
  query.$or = [{ name: { $regex: search, $options: "i" } }];
4902
- cacheOptions.search = search;
4903
- }
4904
- const cacheKey = makeCacheKey9(namespace_collection, cacheOptions);
4905
- const cachedData = await getCache(cacheKey);
4906
- if (cachedData) {
4907
- logger12.info(`Cache hit for key: ${cacheKey}`);
4908
- return cachedData;
4909
4897
  }
4898
+ const basePipeline = [
4899
+ { $match: query },
4900
+ {
4901
+ $lookup: {
4902
+ from: "buildings",
4903
+ let: { siteId: "$_id" },
4904
+ pipeline: [
4905
+ {
4906
+ $match: {
4907
+ $expr: { $eq: ["$site", "$$siteId"] },
4908
+ status: { $ne: "deleted" }
4909
+ }
4910
+ }
4911
+ ],
4912
+ as: "buildings"
4913
+ }
4914
+ },
4915
+ { $match: { "buildings.0": { $exists: true } } },
4916
+ {
4917
+ $lookup: {
4918
+ from: "building-units",
4919
+ let: { buildingIds: "$buildings._id" },
4920
+ pipeline: [
4921
+ {
4922
+ $match: {
4923
+ $expr: { $in: ["$building", "$$buildingIds"] },
4924
+ status: { $ne: "deleted" }
4925
+ }
4926
+ },
4927
+ { $limit: 1 }
4928
+ ],
4929
+ as: "units"
4930
+ }
4931
+ },
4932
+ { $match: { "units.0": { $exists: true } } }
4933
+ ];
4910
4934
  try {
4911
4935
  const items = await collection.aggregate([
4912
- { $match: query },
4936
+ ...basePipeline,
4937
+ { $project: { _id: 1, name: 1 } },
4913
4938
  { $skip: page * limit },
4914
4939
  { $limit: limit }
4915
4940
  ]).toArray();
4916
- const length = await collection.countDocuments(query);
4941
+ const countResult = await collection.aggregate([...basePipeline, { $count: "total" }]).toArray();
4942
+ const length = countResult[0]?.total ?? 0;
4917
4943
  const data = paginate8(items, page, limit, length);
4918
- setCache(cacheKey, data, 15 * 60).then(() => {
4919
- logger12.info(`Cache set for key: ${cacheKey}`);
4920
- }).catch((err) => {
4921
- logger12.error(`Failed to set cache for key: ${cacheKey}`, err);
4922
- });
4923
4944
  return data;
4924
4945
  } catch (error) {
4925
4946
  throw error;
@@ -19359,6 +19380,66 @@ function useBuildingRepo() {
19359
19380
  throw error;
19360
19381
  }
19361
19382
  }
19383
+ async function getAllBuildingForResident({
19384
+ search = "",
19385
+ page = 1,
19386
+ limit = 10,
19387
+ sort = {},
19388
+ site = "",
19389
+ status = "active" /* ACTIVE */
19390
+ } = {}) {
19391
+ page = page > 0 ? page - 1 : 0;
19392
+ let siteId;
19393
+ if (site) {
19394
+ try {
19395
+ siteId = new ObjectId49(site);
19396
+ } catch (error) {
19397
+ throw new BadRequestError79("Invalid site ID.");
19398
+ }
19399
+ }
19400
+ const query = {
19401
+ status,
19402
+ ...search && { $text: { $search: search } },
19403
+ ...siteId && { site: siteId }
19404
+ };
19405
+ sort = Object.keys(sort).length ? sort : { _id: -1 };
19406
+ const basePipeline = [
19407
+ { $match: query },
19408
+ { $match: { $expr: { $gt: [{ $size: "$levels" }, 0] } } },
19409
+ {
19410
+ $lookup: {
19411
+ from: "building-units",
19412
+ let: { buildingId: "$_id" },
19413
+ pipeline: [
19414
+ {
19415
+ $match: {
19416
+ $expr: { $eq: ["$building", "$$buildingId"] },
19417
+ status: { $ne: "deleted" }
19418
+ }
19419
+ },
19420
+ { $limit: 1 }
19421
+ ],
19422
+ as: "units"
19423
+ }
19424
+ },
19425
+ { $match: { "units.0": { $exists: true } } }
19426
+ ];
19427
+ try {
19428
+ const items = await collection.aggregate([
19429
+ ...basePipeline,
19430
+ { $project: { units: 0 } },
19431
+ { $sort: sort },
19432
+ { $skip: page * limit },
19433
+ { $limit: limit }
19434
+ ]).toArray();
19435
+ const countResult = await collection.aggregate([...basePipeline, { $count: "total" }]).toArray();
19436
+ const length = countResult[0]?.total ?? 0;
19437
+ return paginate22(items, page, limit, length);
19438
+ } catch (error) {
19439
+ logger60.log({ level: "error", message: `${error}` });
19440
+ throw error;
19441
+ }
19442
+ }
19362
19443
  async function getById(_id) {
19363
19444
  try {
19364
19445
  _id = new ObjectId49(_id);
@@ -19480,7 +19561,6 @@ function useBuildingRepo() {
19480
19561
  const cacheOptions = { ...query };
19481
19562
  const cacheKey = makeCacheKey26(buildings_namespace_collection, cacheOptions);
19482
19563
  try {
19483
- console.log(query);
19484
19564
  const result = await collection.aggregate([
19485
19565
  {
19486
19566
  $match: {
@@ -19530,16 +19610,16 @@ function useBuildingRepo() {
19530
19610
  },
19531
19611
  {
19532
19612
  $project: {
19533
- "_id": 1,
19534
- "site": 1,
19535
- "name": 1,
19536
- "block": 1,
19537
- "status": 1,
19538
- "buildingFloorPlan": 1,
19539
- "createdAt": 1,
19540
- "updatedAt": 1,
19541
- "deletedAt": 1,
19542
- "levels": "$buildingLevels"
19613
+ _id: 1,
19614
+ site: 1,
19615
+ name: 1,
19616
+ block: 1,
19617
+ status: 1,
19618
+ buildingFloorPlan: 1,
19619
+ createdAt: 1,
19620
+ updatedAt: 1,
19621
+ deletedAt: 1,
19622
+ levels: "$buildingLevels"
19543
19623
  }
19544
19624
  }
19545
19625
  ]).toArray();
@@ -19572,6 +19652,7 @@ function useBuildingRepo() {
19572
19652
  createIndexes,
19573
19653
  add,
19574
19654
  getAll,
19655
+ getAllBuildingForResident,
19575
19656
  getById,
19576
19657
  updateById,
19577
19658
  deleteById,
@@ -19718,10 +19799,56 @@ function useBuildingService() {
19718
19799
  throw error;
19719
19800
  }
19720
19801
  }
19802
+ async function uploadSpreadsheetBuilding(data, site) {
19803
+ const session = useAtlas39.getClient()?.startSession();
19804
+ if (!session) {
19805
+ throw new BadRequestError80("Database session not available.");
19806
+ }
19807
+ try {
19808
+ session?.startTransaction();
19809
+ const blockMap = /* @__PURE__ */ new Map();
19810
+ for (const row of data) {
19811
+ const block = row.block;
19812
+ const name = row.name;
19813
+ const rawLevel = row.level?.toString().trim();
19814
+ const normalizedLevel = /^(na|n\/a)$/i.test(rawLevel) ? null : `Lvl${rawLevel}`;
19815
+ if (!blockMap.has(block)) {
19816
+ blockMap.set(block, { name, levels: [] });
19817
+ }
19818
+ const blockEntry = blockMap.get(block);
19819
+ if (blockEntry.name !== name) {
19820
+ blockEntry.name = `${blockEntry.name}, ${name}`;
19821
+ }
19822
+ if (normalizedLevel && !blockEntry.levels.includes(normalizedLevel)) {
19823
+ blockEntry.levels.push(normalizedLevel);
19824
+ }
19825
+ }
19826
+ const buildingPayloads = Array.from(blockMap.entries()).map(
19827
+ ([block, { name, levels }]) => ({
19828
+ site,
19829
+ block,
19830
+ name,
19831
+ levels
19832
+ })
19833
+ );
19834
+ for (const buildingPayload of buildingPayloads) {
19835
+ const result = await _add(buildingPayload);
19836
+ console.log("Inserted:", result);
19837
+ }
19838
+ await session?.commitTransaction();
19839
+ return buildingPayloads;
19840
+ } catch (error) {
19841
+ await session?.abortTransaction();
19842
+ throw error;
19843
+ } finally {
19844
+ session?.endSession();
19845
+ }
19846
+ }
19721
19847
  return {
19722
19848
  add,
19723
19849
  updateById,
19724
- deleteById
19850
+ deleteById,
19851
+ uploadSpreadsheetBuilding
19725
19852
  };
19726
19853
  }
19727
19854
 
@@ -19734,6 +19861,7 @@ import fs from "fs";
19734
19861
  function useBuildingController() {
19735
19862
  const {
19736
19863
  getAll: _getAll,
19864
+ getAllBuildingForResident: _getAllBuildingForResident,
19737
19865
  getById: _getById,
19738
19866
  getBuildingLevel: _getBuildingLevel,
19739
19867
  getBuildingLevelWithUnits: _getBuildingLevelWithUnits
@@ -19741,7 +19869,8 @@ function useBuildingController() {
19741
19869
  const {
19742
19870
  updateById: _updateById,
19743
19871
  deleteById: _deleteById,
19744
- add: _add
19872
+ add: _add,
19873
+ uploadSpreadsheetBuilding: _uploadSpreadsheetBuilding
19745
19874
  } = useBuildingService();
19746
19875
  async function createBuilding(req, res, next) {
19747
19876
  const value = req.body;
@@ -19834,6 +19963,40 @@ function useBuildingController() {
19834
19963
  next(error2);
19835
19964
  }
19836
19965
  }
19966
+ async function getAllBuildingForResident(req, res, next) {
19967
+ const query = req.query;
19968
+ const validation = Joi44.object({
19969
+ page: Joi44.number().min(1).optional().default(1),
19970
+ limit: Joi44.number().min(1).optional().default(10),
19971
+ search: Joi44.string().optional().allow("", null),
19972
+ site: Joi44.string().hex().optional().allow("", null),
19973
+ status: Joi44.string().valid(...Object.values(BuildingStatus)).default("active" /* ACTIVE */),
19974
+ sort: Joi44.string().valid(...Object.values(SortFields)).default("_id" /* ID */),
19975
+ order: Joi44.string().valid(...Object.values(SortOrder)).default("asc" /* ASC */)
19976
+ });
19977
+ const { error, value } = validation.validate(query);
19978
+ if (error) {
19979
+ next(new BadRequestError81(error.message));
19980
+ return;
19981
+ }
19982
+ const sortObj = {
19983
+ [value.sort]: value.order === "asc" /* ASC */ ? 1 : -1
19984
+ };
19985
+ try {
19986
+ const buildings = await _getAllBuildingForResident({
19987
+ page: value.page,
19988
+ limit: value.limit,
19989
+ sort: sortObj,
19990
+ status: value.status,
19991
+ site: value.site ?? "",
19992
+ search: value.search ?? ""
19993
+ });
19994
+ res.json(buildings);
19995
+ return;
19996
+ } catch (error2) {
19997
+ next(error2);
19998
+ }
19999
+ }
19837
20000
  async function getById(req, res, next) {
19838
20001
  const id = req.params.id;
19839
20002
  const validation = Joi44.object({
@@ -19988,6 +20151,7 @@ function useBuildingController() {
19988
20151
  validRows.push(value);
19989
20152
  }
19990
20153
  });
20154
+ await _uploadSpreadsheetBuilding(validRows, site);
19991
20155
  res.status(200).json({
19992
20156
  message: "Spreadsheet import completed (buildings).",
19993
20157
  fileName: originalname,
@@ -20028,6 +20192,7 @@ function useBuildingController() {
20028
20192
  return {
20029
20193
  createBuilding,
20030
20194
  getAll,
20195
+ getAllBuildingForResident,
20031
20196
  getById,
20032
20197
  updateById,
20033
20198
  deleteById,
@@ -30467,6 +30632,7 @@ var BulletinRecipient = /* @__PURE__ */ ((BulletinRecipient2) => {
30467
30632
  })(BulletinRecipient || {});
30468
30633
  var BulletinStatus = /* @__PURE__ */ ((BulletinStatus2) => {
30469
30634
  BulletinStatus2["ACTIVE"] = "active";
30635
+ BulletinStatus2["UPCOMING"] = "upcoming";
30470
30636
  BulletinStatus2["EXPIRED"] = "expired";
30471
30637
  BulletinStatus2["DELETED"] = "deleted";
30472
30638
  return BulletinStatus2;
@@ -30820,12 +30986,48 @@ function useBulletinBoardRepo() {
30820
30986
  throw error;
30821
30987
  }
30822
30988
  }
30989
+ async function processUpcomingBulletinBoards(session) {
30990
+ const now = (/* @__PURE__ */ new Date()).toISOString();
30991
+ const query = {
30992
+ status: "upcoming" /* UPCOMING */,
30993
+ startDate: { $lte: now }
30994
+ };
30995
+ try {
30996
+ const res = await collection.updateMany(
30997
+ query,
30998
+ {
30999
+ $set: {
31000
+ status: "active" /* ACTIVE */,
31001
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
31002
+ }
31003
+ },
31004
+ { session }
31005
+ );
31006
+ if (res.matchedCount === 0) {
31007
+ throw new NotFoundError30("No upcoming bulletin boards found to activate.");
31008
+ }
31009
+ delNamespace().then(() => {
31010
+ logger104.info(
31011
+ `Cache cleared for namespace: ${bulletin_boards_namespace_collection}`
31012
+ );
31013
+ }).catch((err) => {
31014
+ logger104.error(
31015
+ `Failed to clear cache for namespace: ${bulletin_boards_namespace_collection}`,
31016
+ err
31017
+ );
31018
+ });
31019
+ return res;
31020
+ } catch (error) {
31021
+ throw error;
31022
+ }
31023
+ }
30823
31024
  return {
30824
31025
  add,
30825
31026
  getAll,
30826
31027
  getBulletinBoardById,
30827
31028
  updateBulletinBoardById,
30828
31029
  processExpiredBulletinBoards,
31030
+ processUpcomingBulletinBoards,
30829
31031
  deleteBulletinBoardById,
30830
31032
  createIndexes
30831
31033
  };
@@ -30838,6 +31040,7 @@ function useBulletinBoardService() {
30838
31040
  add: _add,
30839
31041
  updateBulletinBoardById: _updateBulletinBoardById,
30840
31042
  processExpiredBulletinBoards: _processExpiredBulletinBoards,
31043
+ processUpcomingBulletinBoards: _processUpcomingBulletinBoards,
30841
31044
  deleteBulletinBoardById: _deleteBulletinBoardById,
30842
31045
  getBulletinBoardById: _getBulletinBoardById
30843
31046
  } = useBulletinBoardRepo();
@@ -30845,6 +31048,9 @@ function useBulletinBoardService() {
30845
31048
  async function add(value) {
30846
31049
  const session = useAtlas67.getClient()?.startSession();
30847
31050
  session?.startTransaction();
31051
+ if (value.startDate && new Date(value.startDate) > /* @__PURE__ */ new Date()) {
31052
+ value.status = "upcoming" /* UPCOMING */;
31053
+ }
30848
31054
  try {
30849
31055
  await _add(value, session);
30850
31056
  await session?.commitTransaction();
@@ -30870,6 +31076,20 @@ function useBulletinBoardService() {
30870
31076
  session?.endSession();
30871
31077
  }
30872
31078
  }
31079
+ async function processUpcomingBulletinBoards() {
31080
+ const session = useAtlas67.getClient()?.startSession();
31081
+ session?.startTransaction();
31082
+ try {
31083
+ await _processUpcomingBulletinBoards(session);
31084
+ await session?.commitTransaction();
31085
+ return;
31086
+ } catch (error) {
31087
+ await session?.abortTransaction();
31088
+ throw error;
31089
+ } finally {
31090
+ session?.endSession();
31091
+ }
31092
+ }
30873
31093
  async function processExpiredBulletinBoards() {
30874
31094
  const session = useAtlas67.getClient()?.startSession();
30875
31095
  session?.startTransaction();
@@ -30911,6 +31131,7 @@ function useBulletinBoardService() {
30911
31131
  add,
30912
31132
  updateBulletinBoardById,
30913
31133
  processExpiredBulletinBoards,
31134
+ processUpcomingBulletinBoards,
30914
31135
  deleteBulletinBoardById
30915
31136
  };
30916
31137
  }
@@ -32538,14 +32759,15 @@ function useEventManagementRepo() {
32538
32759
  } catch (error) {
32539
32760
  throw new BadRequestError136("Invalid site ID format.");
32540
32761
  }
32762
+ const datePart = date ? new Date(date).toISOString().split("T")[0] : "";
32541
32763
  const baseQuery = {
32542
32764
  site,
32543
32765
  status: status ? status : { $ne: "deleted" },
32544
32766
  ...type && { type },
32545
- ...date && {
32767
+ ...datePart && {
32546
32768
  dateTime: {
32547
- $gte: `${date}T00:00:00.000Z`,
32548
- $lt: `${date}T23:59:59.999Z`
32769
+ $gte: /* @__PURE__ */ new Date(`${datePart}T00:00:00.000Z`),
32770
+ $lte: /* @__PURE__ */ new Date(`${datePart}T23:59:59.999Z`)
32549
32771
  }
32550
32772
  }
32551
32773
  };
@@ -32558,7 +32780,7 @@ function useEventManagementRepo() {
32558
32780
  page,
32559
32781
  limit,
32560
32782
  ...type && { type },
32561
- ...date && { dateTime: date }
32783
+ ...datePart && { dateTime: datePart }
32562
32784
  };
32563
32785
  if (search) {
32564
32786
  query.$or = [{ title: { $regex: search, $options: "i" } }];