@7365admin1/core 2.56.0 → 2.57.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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # @iservice365/core
2
2
 
3
+ ## 2.57.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 72c98df: get latest changes 12-05-2026
8
+
3
9
  ## 2.56.0
4
10
 
5
11
  ### Minor Changes
package/dist/index.d.ts CHANGED
@@ -850,15 +850,15 @@ declare const TInvoice: z.ZodObject<{
850
850
  total: z.ZodNumber;
851
851
  }, "strip", z.ZodTypeAny, {
852
852
  description: string;
853
+ total: number;
853
854
  unitPrice: number;
854
855
  quantity: number;
855
- total: number;
856
856
  seats?: number | undefined;
857
857
  }, {
858
858
  description: string;
859
+ total: number;
859
860
  unitPrice: number;
860
861
  quantity: number;
861
- total: number;
862
862
  seats?: number | undefined;
863
863
  }>, "many">;
864
864
  metadata: z.ZodEffects<z.ZodOptional<z.ZodDefault<z.ZodObject<{
@@ -908,9 +908,9 @@ declare const TInvoice: z.ZodObject<{
908
908
  dueDate: Date;
909
909
  items: {
910
910
  description: string;
911
+ total: number;
911
912
  unitPrice: number;
912
913
  quantity: number;
913
- total: number;
914
914
  seats?: number | undefined;
915
915
  }[];
916
916
  createdAt?: Date | undefined;
@@ -931,9 +931,9 @@ declare const TInvoice: z.ZodObject<{
931
931
  dueDate: Date;
932
932
  items: {
933
933
  description: string;
934
+ total: number;
934
935
  unitPrice: number;
935
936
  quantity: number;
936
- total: number;
937
937
  seats?: number | undefined;
938
938
  }[];
939
939
  createdAt?: Date | undefined;
@@ -962,9 +962,9 @@ declare function useInvoiceModel(db: Db): {
962
962
  dueDate: Date;
963
963
  items: {
964
964
  description: string;
965
+ total: number;
965
966
  unitPrice: number;
966
967
  quantity: number;
967
- total: number;
968
968
  seats?: number | undefined;
969
969
  }[];
970
970
  createdAt?: Date | undefined;
@@ -994,9 +994,9 @@ declare function useInvoiceRepo(): {
994
994
  dueDate: Date;
995
995
  items: {
996
996
  description: string;
997
+ total: number;
997
998
  unitPrice: number;
998
999
  quantity: number;
999
- total: number;
1000
1000
  seats?: number | undefined;
1001
1001
  }[];
1002
1002
  createdAt?: Date | undefined;
@@ -1030,9 +1030,9 @@ declare function useInvoiceRepo(): {
1030
1030
  dueDate: Date;
1031
1031
  items: {
1032
1032
  description: string;
1033
+ total: number;
1033
1034
  unitPrice: number;
1034
1035
  quantity: number;
1035
- total: number;
1036
1036
  seats?: number | undefined;
1037
1037
  }[];
1038
1038
  createdAt?: Date | undefined;
@@ -1056,9 +1056,9 @@ declare function useInvoiceRepo(): {
1056
1056
  dueDate: Date;
1057
1057
  items: {
1058
1058
  description: string;
1059
+ total: number;
1059
1060
  unitPrice: number;
1060
1061
  quantity: number;
1061
- total: number;
1062
1062
  seats?: number | undefined;
1063
1063
  }[];
1064
1064
  createdAt?: Date | undefined;
@@ -1756,7 +1756,7 @@ declare enum BuildingStatus {
1756
1756
  }
1757
1757
  type TBuilding = {
1758
1758
  _id?: ObjectId;
1759
- site: ObjectId;
1759
+ site: string | ObjectId;
1760
1760
  name?: string;
1761
1761
  block: number;
1762
1762
  levels: string[];
@@ -1852,6 +1852,18 @@ declare function useBuildingRepo(): {
1852
1852
  site?: string | undefined;
1853
1853
  status?: BuildingStatus | undefined;
1854
1854
  }) => Promise<Record<string, any>>;
1855
+ getAllBuildingForResident: ({ search, page, limit, sort, site, status, }?: {
1856
+ search?: string | undefined;
1857
+ page?: number | undefined;
1858
+ limit?: number | undefined;
1859
+ sort?: {} | undefined;
1860
+ site?: string | undefined;
1861
+ status?: BuildingStatus | undefined;
1862
+ }) => Promise<{
1863
+ items: any[];
1864
+ pages: number;
1865
+ pageRange: string;
1866
+ }>;
1855
1867
  getById: (_id: string | ObjectId) => Promise<TBuilding | null>;
1856
1868
  updateById: (_id: ObjectId | string, value: Pick<TBuilding, "name" | "block" | "levels" | "buildingFiles">, session?: ClientSession) => Promise<mongodb.UpdateResult<bson.Document>>;
1857
1869
  deleteById: (_id: string | ObjectId, session?: ClientSession) => Promise<mongodb.UpdateResult<bson.Document>>;
@@ -1860,14 +1872,21 @@ declare function useBuildingRepo(): {
1860
1872
  };
1861
1873
 
1862
1874
  declare function useBuildingService(): {
1863
- add: (value: TBuilding) => Promise<bson.ObjectId>;
1875
+ add: (value: TBuilding) => Promise<ObjectId>;
1864
1876
  updateById: (id: string, data: Pick<TBuilding, "name" | "block" | "levels" | "buildingFiles">) => Promise<mongodb.UpdateResult<bson.Document>>;
1865
1877
  deleteById: (id: string) => Promise<string>;
1878
+ uploadSpreadsheetBuilding: (data: any[], site: string) => Promise<{
1879
+ site: string;
1880
+ block: number;
1881
+ name: string;
1882
+ levels: string[];
1883
+ }[]>;
1866
1884
  };
1867
1885
 
1868
1886
  declare function useBuildingController(): {
1869
1887
  createBuilding: (req: Request, res: Response, next: NextFunction) => Promise<void>;
1870
1888
  getAll: (req: Request, res: Response, next: NextFunction) => Promise<void>;
1889
+ getAllBuildingForResident: (req: Request, res: Response, next: NextFunction) => Promise<void>;
1871
1890
  getById: (req: Request, res: Response, next: NextFunction) => Promise<void>;
1872
1891
  updateById: (req: Request, res: Response, next: NextFunction) => Promise<void>;
1873
1892
  deleteById: (req: Request, res: Response, next: NextFunction) => Promise<void>;
package/dist/index.js CHANGED
@@ -5250,34 +5250,55 @@ function useSiteRepo() {
5250
5250
  const query = {
5251
5251
  status: { $ne: "deleted" }
5252
5252
  };
5253
- const cacheOptions = {
5254
- status: { $ne: "deleted" },
5255
- page,
5256
- limit
5257
- };
5258
5253
  if (search) {
5259
5254
  query.$or = [{ name: { $regex: search, $options: "i" } }];
5260
- cacheOptions.search = search;
5261
- }
5262
- const cacheKey = (0, import_node_server_utils19.makeCacheKey)(namespace_collection, cacheOptions);
5263
- const cachedData = await getCache(cacheKey);
5264
- if (cachedData) {
5265
- import_node_server_utils19.logger.info(`Cache hit for key: ${cacheKey}`);
5266
- return cachedData;
5267
5255
  }
5256
+ const basePipeline = [
5257
+ { $match: query },
5258
+ {
5259
+ $lookup: {
5260
+ from: "buildings",
5261
+ let: { siteId: "$_id" },
5262
+ pipeline: [
5263
+ {
5264
+ $match: {
5265
+ $expr: { $eq: ["$site", "$$siteId"] },
5266
+ status: { $ne: "deleted" }
5267
+ }
5268
+ }
5269
+ ],
5270
+ as: "buildings"
5271
+ }
5272
+ },
5273
+ { $match: { "buildings.0": { $exists: true } } },
5274
+ {
5275
+ $lookup: {
5276
+ from: "building-units",
5277
+ let: { buildingIds: "$buildings._id" },
5278
+ pipeline: [
5279
+ {
5280
+ $match: {
5281
+ $expr: { $in: ["$building", "$$buildingIds"] },
5282
+ status: { $ne: "deleted" }
5283
+ }
5284
+ },
5285
+ { $limit: 1 }
5286
+ ],
5287
+ as: "units"
5288
+ }
5289
+ },
5290
+ { $match: { "units.0": { $exists: true } } }
5291
+ ];
5268
5292
  try {
5269
5293
  const items = await collection.aggregate([
5270
- { $match: query },
5294
+ ...basePipeline,
5295
+ { $project: { _id: 1, name: 1 } },
5271
5296
  { $skip: page * limit },
5272
5297
  { $limit: limit }
5273
5298
  ]).toArray();
5274
- const length = await collection.countDocuments(query);
5299
+ const countResult = await collection.aggregate([...basePipeline, { $count: "total" }]).toArray();
5300
+ const length = countResult[0]?.total ?? 0;
5275
5301
  const data = (0, import_node_server_utils19.paginate)(items, page, limit, length);
5276
- setCache(cacheKey, data, 15 * 60).then(() => {
5277
- import_node_server_utils19.logger.info(`Cache set for key: ${cacheKey}`);
5278
- }).catch((err) => {
5279
- import_node_server_utils19.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
5280
- });
5281
5302
  return data;
5282
5303
  } catch (error) {
5283
5304
  throw error;
@@ -19527,6 +19548,66 @@ function useBuildingRepo() {
19527
19548
  throw error;
19528
19549
  }
19529
19550
  }
19551
+ async function getAllBuildingForResident({
19552
+ search = "",
19553
+ page = 1,
19554
+ limit = 10,
19555
+ sort = {},
19556
+ site = "",
19557
+ status = "active" /* ACTIVE */
19558
+ } = {}) {
19559
+ page = page > 0 ? page - 1 : 0;
19560
+ let siteId;
19561
+ if (site) {
19562
+ try {
19563
+ siteId = new import_mongodb49.ObjectId(site);
19564
+ } catch (error) {
19565
+ throw new import_node_server_utils82.BadRequestError("Invalid site ID.");
19566
+ }
19567
+ }
19568
+ const query = {
19569
+ status,
19570
+ ...search && { $text: { $search: search } },
19571
+ ...siteId && { site: siteId }
19572
+ };
19573
+ sort = Object.keys(sort).length ? sort : { _id: -1 };
19574
+ const basePipeline = [
19575
+ { $match: query },
19576
+ { $match: { $expr: { $gt: [{ $size: "$levels" }, 0] } } },
19577
+ {
19578
+ $lookup: {
19579
+ from: "building-units",
19580
+ let: { buildingId: "$_id" },
19581
+ pipeline: [
19582
+ {
19583
+ $match: {
19584
+ $expr: { $eq: ["$building", "$$buildingId"] },
19585
+ status: { $ne: "deleted" }
19586
+ }
19587
+ },
19588
+ { $limit: 1 }
19589
+ ],
19590
+ as: "units"
19591
+ }
19592
+ },
19593
+ { $match: { "units.0": { $exists: true } } }
19594
+ ];
19595
+ try {
19596
+ const items = await collection.aggregate([
19597
+ ...basePipeline,
19598
+ { $project: { units: 0 } },
19599
+ { $sort: sort },
19600
+ { $skip: page * limit },
19601
+ { $limit: limit }
19602
+ ]).toArray();
19603
+ const countResult = await collection.aggregate([...basePipeline, { $count: "total" }]).toArray();
19604
+ const length = countResult[0]?.total ?? 0;
19605
+ return (0, import_node_server_utils82.paginate)(items, page, limit, length);
19606
+ } catch (error) {
19607
+ import_node_server_utils82.logger.log({ level: "error", message: `${error}` });
19608
+ throw error;
19609
+ }
19610
+ }
19530
19611
  async function getById(_id) {
19531
19612
  try {
19532
19613
  _id = new import_mongodb49.ObjectId(_id);
@@ -19648,7 +19729,6 @@ function useBuildingRepo() {
19648
19729
  const cacheOptions = { ...query };
19649
19730
  const cacheKey = (0, import_node_server_utils82.makeCacheKey)(buildings_namespace_collection, cacheOptions);
19650
19731
  try {
19651
- console.log(query);
19652
19732
  const result = await collection.aggregate([
19653
19733
  {
19654
19734
  $match: {
@@ -19698,16 +19778,16 @@ function useBuildingRepo() {
19698
19778
  },
19699
19779
  {
19700
19780
  $project: {
19701
- "_id": 1,
19702
- "site": 1,
19703
- "name": 1,
19704
- "block": 1,
19705
- "status": 1,
19706
- "buildingFloorPlan": 1,
19707
- "createdAt": 1,
19708
- "updatedAt": 1,
19709
- "deletedAt": 1,
19710
- "levels": "$buildingLevels"
19781
+ _id: 1,
19782
+ site: 1,
19783
+ name: 1,
19784
+ block: 1,
19785
+ status: 1,
19786
+ buildingFloorPlan: 1,
19787
+ createdAt: 1,
19788
+ updatedAt: 1,
19789
+ deletedAt: 1,
19790
+ levels: "$buildingLevels"
19711
19791
  }
19712
19792
  }
19713
19793
  ]).toArray();
@@ -19740,6 +19820,7 @@ function useBuildingRepo() {
19740
19820
  createIndexes,
19741
19821
  add,
19742
19822
  getAll,
19823
+ getAllBuildingForResident,
19743
19824
  getById,
19744
19825
  updateById,
19745
19826
  deleteById,
@@ -19881,10 +19962,56 @@ function useBuildingService() {
19881
19962
  throw error;
19882
19963
  }
19883
19964
  }
19965
+ async function uploadSpreadsheetBuilding(data, site) {
19966
+ const session = import_node_server_utils83.useAtlas.getClient()?.startSession();
19967
+ if (!session) {
19968
+ throw new import_node_server_utils83.BadRequestError("Database session not available.");
19969
+ }
19970
+ try {
19971
+ session?.startTransaction();
19972
+ const blockMap = /* @__PURE__ */ new Map();
19973
+ for (const row of data) {
19974
+ const block = row.block;
19975
+ const name = row.name;
19976
+ const rawLevel = row.level?.toString().trim();
19977
+ const normalizedLevel = /^(na|n\/a)$/i.test(rawLevel) ? null : `Lvl${rawLevel}`;
19978
+ if (!blockMap.has(block)) {
19979
+ blockMap.set(block, { name, levels: [] });
19980
+ }
19981
+ const blockEntry = blockMap.get(block);
19982
+ if (blockEntry.name !== name) {
19983
+ blockEntry.name = `${blockEntry.name}, ${name}`;
19984
+ }
19985
+ if (normalizedLevel && !blockEntry.levels.includes(normalizedLevel)) {
19986
+ blockEntry.levels.push(normalizedLevel);
19987
+ }
19988
+ }
19989
+ const buildingPayloads = Array.from(blockMap.entries()).map(
19990
+ ([block, { name, levels }]) => ({
19991
+ site,
19992
+ block,
19993
+ name,
19994
+ levels
19995
+ })
19996
+ );
19997
+ for (const buildingPayload of buildingPayloads) {
19998
+ const result = await _add(buildingPayload);
19999
+ console.log("Inserted:", result);
20000
+ }
20001
+ await session?.commitTransaction();
20002
+ return buildingPayloads;
20003
+ } catch (error) {
20004
+ await session?.abortTransaction();
20005
+ throw error;
20006
+ } finally {
20007
+ session?.endSession();
20008
+ }
20009
+ }
19884
20010
  return {
19885
20011
  add,
19886
20012
  updateById,
19887
- deleteById
20013
+ deleteById,
20014
+ uploadSpreadsheetBuilding
19888
20015
  };
19889
20016
  }
19890
20017
 
@@ -19897,6 +20024,7 @@ var import_fs2 = __toESM(require("fs"));
19897
20024
  function useBuildingController() {
19898
20025
  const {
19899
20026
  getAll: _getAll,
20027
+ getAllBuildingForResident: _getAllBuildingForResident,
19900
20028
  getById: _getById,
19901
20029
  getBuildingLevel: _getBuildingLevel,
19902
20030
  getBuildingLevelWithUnits: _getBuildingLevelWithUnits
@@ -19904,7 +20032,8 @@ function useBuildingController() {
19904
20032
  const {
19905
20033
  updateById: _updateById,
19906
20034
  deleteById: _deleteById,
19907
- add: _add
20035
+ add: _add,
20036
+ uploadSpreadsheetBuilding: _uploadSpreadsheetBuilding
19908
20037
  } = useBuildingService();
19909
20038
  async function createBuilding(req, res, next) {
19910
20039
  const value = req.body;
@@ -19997,6 +20126,40 @@ function useBuildingController() {
19997
20126
  next(error2);
19998
20127
  }
19999
20128
  }
20129
+ async function getAllBuildingForResident(req, res, next) {
20130
+ const query = req.query;
20131
+ const validation = import_joi44.default.object({
20132
+ page: import_joi44.default.number().min(1).optional().default(1),
20133
+ limit: import_joi44.default.number().min(1).optional().default(10),
20134
+ search: import_joi44.default.string().optional().allow("", null),
20135
+ site: import_joi44.default.string().hex().optional().allow("", null),
20136
+ status: import_joi44.default.string().valid(...Object.values(BuildingStatus)).default("active" /* ACTIVE */),
20137
+ sort: import_joi44.default.string().valid(...Object.values(SortFields)).default("_id" /* ID */),
20138
+ order: import_joi44.default.string().valid(...Object.values(SortOrder)).default("asc" /* ASC */)
20139
+ });
20140
+ const { error, value } = validation.validate(query);
20141
+ if (error) {
20142
+ next(new import_node_server_utils84.BadRequestError(error.message));
20143
+ return;
20144
+ }
20145
+ const sortObj = {
20146
+ [value.sort]: value.order === "asc" /* ASC */ ? 1 : -1
20147
+ };
20148
+ try {
20149
+ const buildings = await _getAllBuildingForResident({
20150
+ page: value.page,
20151
+ limit: value.limit,
20152
+ sort: sortObj,
20153
+ status: value.status,
20154
+ site: value.site ?? "",
20155
+ search: value.search ?? ""
20156
+ });
20157
+ res.json(buildings);
20158
+ return;
20159
+ } catch (error2) {
20160
+ next(error2);
20161
+ }
20162
+ }
20000
20163
  async function getById(req, res, next) {
20001
20164
  const id = req.params.id;
20002
20165
  const validation = import_joi44.default.object({
@@ -20151,6 +20314,7 @@ function useBuildingController() {
20151
20314
  validRows.push(value);
20152
20315
  }
20153
20316
  });
20317
+ await _uploadSpreadsheetBuilding(validRows, site);
20154
20318
  res.status(200).json({
20155
20319
  message: "Spreadsheet import completed (buildings).",
20156
20320
  fileName: originalname,
@@ -20191,6 +20355,7 @@ function useBuildingController() {
20191
20355
  return {
20192
20356
  createBuilding,
20193
20357
  getAll,
20358
+ getAllBuildingForResident,
20194
20359
  getById,
20195
20360
  updateById,
20196
20361
  deleteById,