@7365admin1/core 2.9.0 → 2.10.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
@@ -372,7 +372,8 @@ function useFeedbackRepo() {
372
372
  query.$or = [
373
373
  { subject: { $regex: search, $options: "i" } },
374
374
  { description: { $regex: search, $options: "i" } },
375
- { createdByName: { $regex: search, $options: "i" } }
375
+ { createdByName: { $regex: search, $options: "i" } },
376
+ { category: { $regex: search, $options: "i" } }
376
377
  ];
377
378
  cacheOptions.search = search;
378
379
  }
@@ -993,7 +994,9 @@ function useWorkOrderRepo() {
993
994
  if (search) {
994
995
  query.$or = [
995
996
  { subject: { $regex: search, $options: "i" } },
996
- { createdByName: { $regex: search, $options: "i" } }
997
+ { createdByName: { $regex: search, $options: "i" } },
998
+ { description: { $regex: search, $options: "i" } },
999
+ { category: { $regex: search, $options: "i" } }
997
1000
  ];
998
1001
  cacheOptions.search = search;
999
1002
  }
@@ -3226,7 +3229,8 @@ var allowedFieldsSite = [
3226
3229
  "metadata.block",
3227
3230
  "metadata.guardPosts",
3228
3231
  "metadata.gracePeriod",
3229
- "metadata.incidentCounter"
3232
+ "metadata.incidentCounter",
3233
+ "metadata.incidentLogo"
3230
3234
  ];
3231
3235
  var siteSchema = Joi8.object({
3232
3236
  name: Joi8.string().required(),
@@ -10802,7 +10806,8 @@ function useFeedbackController() {
10802
10806
  }
10803
10807
  async function deleteFeedback(req, res, next) {
10804
10808
  const validation = Joi28.string().hex().required();
10805
- const _id = req.params.id;
10809
+ const _id = req.query.id;
10810
+ console.log(_id);
10806
10811
  const { error } = validation.validate(_id);
10807
10812
  if (error) {
10808
10813
  logger39.log({ level: "error", message: error.message });
@@ -11166,7 +11171,8 @@ function useWorkOrderController() {
11166
11171
  }
11167
11172
  async function deleteWorkOrder(req, res, next) {
11168
11173
  const validation = Joi29.string().hex().required();
11169
- const _id = req.params.id;
11174
+ const _id = req.query.id;
11175
+ console.log(_id);
11170
11176
  const { error } = validation.validate(_id);
11171
11177
  if (error) {
11172
11178
  logger40.log({ level: "error", message: error.message });
@@ -12706,7 +12712,7 @@ function useSiteController() {
12706
12712
  const validation = Joi36.object({
12707
12713
  _id: Joi36.string().hex().required(),
12708
12714
  field: Joi36.string().valid(...allowedFieldsSite).required(),
12709
- value: Joi36.number().integer().min(0).required()
12715
+ value: Joi36.alternatives().try(Joi36.number().integer().min(0), Joi36.string().hex().length(24)).required()
12710
12716
  });
12711
12717
  const _id = req.params.id ?? "";
12712
12718
  const field = req.body.field ?? "";
@@ -27207,11 +27213,11 @@ var EAccessCardTypes = /* @__PURE__ */ ((EAccessCardTypes2) => {
27207
27213
  EAccessCardTypes2["QR"] = "QRCODE";
27208
27214
  return EAccessCardTypes2;
27209
27215
  })(EAccessCardTypes || {});
27210
- var EAccessCardUserTypes = /* @__PURE__ */ ((EAccessCardUserTypes2) => {
27211
- EAccessCardUserTypes2["RESIDENT"] = "Resident/Tenant";
27212
- EAccessCardUserTypes2["CONTRACTOR"] = "Contractor";
27213
- EAccessCardUserTypes2["VISITOR"] = "Visitor";
27214
- return EAccessCardUserTypes2;
27216
+ var EAccessCardUserTypes = /* @__PURE__ */ ((EAccessCardUserTypes4) => {
27217
+ EAccessCardUserTypes4["RESIDENT"] = "Resident/Tenant";
27218
+ EAccessCardUserTypes4["CONTRACTOR"] = "Contractor";
27219
+ EAccessCardUserTypes4["VISITOR"] = "Visitor";
27220
+ return EAccessCardUserTypes4;
27215
27221
  })(EAccessCardUserTypes || {});
27216
27222
  var AccessTypeProps = /* @__PURE__ */ ((AccessTypeProps2) => {
27217
27223
  AccessTypeProps2["NORMAL"] = "Normal";
@@ -27273,7 +27279,8 @@ var MAccessCard = class {
27273
27279
  doorName,
27274
27280
  liftName,
27275
27281
  replacementStatus,
27276
- vmsRemarks
27282
+ vmsRemarks,
27283
+ isWinsland = false
27277
27284
  } = {}) {
27278
27285
  this._id = _id;
27279
27286
  this.userId = userId;
@@ -27300,12 +27307,14 @@ var MAccessCard = class {
27300
27307
  this.liftName = liftName;
27301
27308
  this.replacementStatus = replacementStatus;
27302
27309
  this.vmsRemarks = vmsRemarks;
27310
+ this.isWinsland = isWinsland;
27303
27311
  }
27304
27312
  };
27305
27313
 
27306
27314
  // src/repositories/access-management.repo.ts
27307
27315
  import {
27308
27316
  InternalServerError as InternalServerError47,
27317
+ paginate as paginate38,
27309
27318
  useAtlas as useAtlas74
27310
27319
  } from "@7365admin1/node-server-utils";
27311
27320
  import { ObjectId as ObjectId83 } from "mongodb";
@@ -27352,6 +27361,15 @@ function UseAccessManagementRepo() {
27352
27361
  return Promise.reject("Failed to create Access cards indexes.");
27353
27362
  }
27354
27363
  }
27364
+ async function createIndexForEntrypass() {
27365
+ try {
27366
+ const entrypass = collectionName("entrypass-settings");
27367
+ await Promise.all([entrypass.createIndex({ site: 1 })]);
27368
+ return Promise.resolve("Access cards indexes created.");
27369
+ } catch (error) {
27370
+ return Promise.reject("Failed to create Access cards indexes.");
27371
+ }
27372
+ }
27355
27373
  async function addPhysicalCardRepo({
27356
27374
  payload
27357
27375
  }) {
@@ -27442,7 +27460,8 @@ function UseAccessManagementRepo() {
27442
27460
  liftName: params.liftName,
27443
27461
  assignedUnit: new ObjectId83(units[i]),
27444
27462
  createdAt: new Date(params.createdAt),
27445
- updatedAt: new Date(params.updatedAt)
27463
+ updatedAt: new Date(params.updatedAt),
27464
+ isWinsland: params.isWinsland
27446
27465
  });
27447
27466
  try {
27448
27467
  const result = await collection().insertOne(newCard);
@@ -27494,7 +27513,8 @@ function UseAccessManagementRepo() {
27494
27513
  liftName: params.liftName,
27495
27514
  assignedUnit: null,
27496
27515
  createdAt: new Date(params.createdAt),
27497
- updatedAt: new Date(params.updatedAt)
27516
+ updatedAt: new Date(params.updatedAt),
27517
+ isWinsland: params.isWinsland
27498
27518
  });
27499
27519
  try {
27500
27520
  const result = await collection().insertOne(newCard);
@@ -27526,10 +27546,362 @@ function UseAccessManagementRepo() {
27526
27546
  throw new Error(error.message);
27527
27547
  }
27528
27548
  }
27549
+ async function accessManagementSettingsRepo(params) {
27550
+ try {
27551
+ params.site = new ObjectId83(params.site);
27552
+ const result = collectionName("entrypass-settings").updateOne(
27553
+ { site: params.site },
27554
+ {
27555
+ $set: {
27556
+ ...params,
27557
+ updatedAt: /* @__PURE__ */ new Date()
27558
+ },
27559
+ $setOnInsert: {
27560
+ createdAt: /* @__PURE__ */ new Date()
27561
+ }
27562
+ },
27563
+ { upsert: true }
27564
+ );
27565
+ await createIndexForEntrypass();
27566
+ return result;
27567
+ } catch (error) {
27568
+ throw new Error(error.message);
27569
+ }
27570
+ }
27571
+ async function allAccessCardsCountsRepo(params) {
27572
+ try {
27573
+ const site = new ObjectId83(params.site);
27574
+ const userType = params.userType;
27575
+ const result = await collection().aggregate([
27576
+ {
27577
+ $match: { site, userType }
27578
+ },
27579
+ {
27580
+ $facet: {
27581
+ available_physical: [{ $match: { assignedUnit: { $eq: null }, type: "NFC" /* NFC */ } }, { $count: "count" }],
27582
+ available_non_physical: [{ $match: { assignedUnit: { $eq: null }, type: "QRCODE" /* QR */ } }, { $count: "count" }],
27583
+ assigned_physical: [{ $match: { assignedUnit: { $ne: null }, type: "NFC" /* NFC */ } }, { $count: "count" }],
27584
+ assigned_non_physical: [{ $match: { assignedUnit: { $ne: null }, type: "QRCODE" /* QR */ } }, { $count: "count" }]
27585
+ }
27586
+ }
27587
+ ]).toArray();
27588
+ const totalCardCount = {
27589
+ available_physical: result[0].available_physical[0] ? result[0].available_physical[0].count : 0,
27590
+ available_non_physical: result[0].available_non_physical[0] ? result[0].available_non_physical[0].count : 0,
27591
+ assigned_physical: result[0].assigned_physical[0] ? result[0].assigned_physical[0].count : 0,
27592
+ assigned_non_physical: result[0].assigned_non_physical[0] ? result[0].assigned_non_physical[0].count : 0
27593
+ };
27594
+ return totalCardCount;
27595
+ } catch (error) {
27596
+ throw new Error(error.message);
27597
+ }
27598
+ }
27599
+ async function availableAccessCardsRepo(params) {
27600
+ try {
27601
+ const site = new ObjectId83(params.site);
27602
+ const userType = params.userType;
27603
+ const type = params.type;
27604
+ const query = {
27605
+ site: { $in: [site] },
27606
+ userType,
27607
+ assignedUnit: null,
27608
+ type,
27609
+ isActivated: true
27610
+ };
27611
+ const result = await collection().aggregate([
27612
+ {
27613
+ $match: { ...query }
27614
+ },
27615
+ {
27616
+ $project: {
27617
+ accessLevel: 1,
27618
+ liftAccessLevel: 1,
27619
+ doorName: 1,
27620
+ liftName: 1
27621
+ }
27622
+ },
27623
+ {
27624
+ $group: {
27625
+ _id: {
27626
+ accessLevel: "$accessLevel",
27627
+ liftAccessLevel: "$liftAccessLevel",
27628
+ doorName: "$doorName",
27629
+ liftName: "$liftName"
27630
+ },
27631
+ count: { $sum: 1 }
27632
+ }
27633
+ },
27634
+ {
27635
+ $project: {
27636
+ _id: 0,
27637
+ accessLevel: "$_id.accessLevel",
27638
+ liftAccessLevel: "$_id.liftAccessLevel",
27639
+ doorName: "$_id.doorName",
27640
+ liftName: "$_id.liftName",
27641
+ count: 1
27642
+ }
27643
+ }
27644
+ ]).toArray();
27645
+ return result;
27646
+ } catch (error) {
27647
+ throw new Error(error.message);
27648
+ }
27649
+ }
27650
+ function buildSearchQuery(search) {
27651
+ if (!search) {
27652
+ return {};
27653
+ }
27654
+ const terms = search.split("/").map((s) => s.trim()).filter(Boolean);
27655
+ if (search.includes("/") && terms.length <= 3) {
27656
+ switch (terms.length) {
27657
+ case 3:
27658
+ return {
27659
+ $and: [
27660
+ { $expr: { $eq: [{ $toLower: "$name" }, terms[0].toLowerCase()] } },
27661
+ { $expr: { $eq: [{ $toLower: "$level.level" }, terms[1].toLowerCase()] } },
27662
+ { $expr: { $eq: [{ $toLower: "$level.units.name" }, terms[2].toLowerCase()] } }
27663
+ ]
27664
+ };
27665
+ case 2:
27666
+ return {
27667
+ $and: [
27668
+ { $expr: { $eq: [{ $toLower: "$name" }, terms[0].toLowerCase()] } },
27669
+ { $expr: { $eq: [{ $toLower: "$level.level" }, terms[1].toLowerCase()] } }
27670
+ ]
27671
+ };
27672
+ default:
27673
+ return {
27674
+ $expr: { $eq: [{ $toLower: "$name" }, terms[0].toLowerCase()] }
27675
+ };
27676
+ }
27677
+ }
27678
+ return {
27679
+ $or: [
27680
+ { name: { $regex: search.trim(), $options: "i" } },
27681
+ { "level.level": { $regex: search.trim(), $options: "i" } },
27682
+ { "level.units.name": { $regex: search.trim(), $options: "i" } }
27683
+ ]
27684
+ };
27685
+ }
27686
+ async function userTypeAccessCardsRepo(params) {
27687
+ try {
27688
+ const site = new ObjectId83(params.site);
27689
+ const userType = params.userType;
27690
+ const page = params.page ? Number(params.page) - 1 : 0;
27691
+ const limit = Number(params.limit) || 10;
27692
+ const search = params.search;
27693
+ const defaultQuery = {
27694
+ site
27695
+ };
27696
+ const searchQuery = buildSearchQuery(search);
27697
+ const result = await collectionName("buildings").aggregate([
27698
+ // ✅ Match early with index-friendly query
27699
+ {
27700
+ $match: {
27701
+ ...defaultQuery,
27702
+ status: { $ne: "deleted" }
27703
+ }
27704
+ },
27705
+ // ✅ Only project needed fields before heavy lookups
27706
+ {
27707
+ $project: {
27708
+ _id: 1,
27709
+ name: 1,
27710
+ site: 1
27711
+ }
27712
+ },
27713
+ // ✅ Use localField/foreignField for better index usage
27714
+ {
27715
+ $lookup: {
27716
+ from: "building-levels",
27717
+ localField: "_id",
27718
+ foreignField: "block",
27719
+ pipeline: [
27720
+ { $match: { status: { $ne: "deleted" } } },
27721
+ {
27722
+ $lookup: {
27723
+ from: "building-units",
27724
+ localField: "_id",
27725
+ foreignField: "level",
27726
+ pipeline: [
27727
+ { $match: { status: { $ne: "deleted" } } },
27728
+ { $project: { _id: 1, name: 1 } }
27729
+ ],
27730
+ as: "units"
27731
+ }
27732
+ },
27733
+ {
27734
+ $match: { "units.0": { $exists: true } }
27735
+ },
27736
+ {
27737
+ $project: {
27738
+ _id: 1,
27739
+ level: 1,
27740
+ units: 1
27741
+ }
27742
+ }
27743
+ ],
27744
+ as: "level"
27745
+ }
27746
+ },
27747
+ // ✅ Filter out buildings with no levels early
27748
+ {
27749
+ $match: { "level.0": { $exists: true } }
27750
+ },
27751
+ // ✅ Unwind to flatten the hierarchy
27752
+ {
27753
+ $unwind: {
27754
+ path: "$level",
27755
+ preserveNullAndEmptyArrays: false
27756
+ }
27757
+ },
27758
+ {
27759
+ $unwind: {
27760
+ path: "$level.units",
27761
+ preserveNullAndEmptyArrays: false
27762
+ }
27763
+ },
27764
+ // Groups by unit _id and keeps only the first occurrence
27765
+ {
27766
+ $group: {
27767
+ _id: "$level.units._id",
27768
+ doc: { $first: "$$ROOT" }
27769
+ }
27770
+ },
27771
+ {
27772
+ $replaceRoot: { newRoot: "$doc" }
27773
+ },
27774
+ // ✅ Apply search filter
27775
+ {
27776
+ $match: {
27777
+ ...searchQuery
27778
+ }
27779
+ },
27780
+ {
27781
+ $facet: {
27782
+ totalCount: [{ $count: "count" }],
27783
+ items: [
27784
+ // ✅ Sort BEFORE skip/limit for correct pagination
27785
+ { $sort: { _id: -1 } },
27786
+ { $skip: page * limit },
27787
+ { $limit: limit },
27788
+ // ✅ Users lookup - optimized with index hint
27789
+ {
27790
+ $lookup: {
27791
+ from: "users",
27792
+ let: { unit: "$level.units._id" },
27793
+ pipeline: [
27794
+ {
27795
+ $match: {
27796
+ $expr: { $eq: ["$unitNumber", "$$unit"] },
27797
+ residentType: "House/Unit Owner"
27798
+ }
27799
+ },
27800
+ { $limit: 1 },
27801
+ { $project: { _id: 1, givenName: 1, surname: 1 } }
27802
+ ],
27803
+ as: "unitOwner"
27804
+ }
27805
+ },
27806
+ // ✅ Access card lookup - optimized query
27807
+ {
27808
+ $lookup: {
27809
+ from: "access-cards",
27810
+ let: { unit: "$level.units._id" },
27811
+ pipeline: [
27812
+ {
27813
+ $match: {
27814
+ $expr: {
27815
+ $in: [
27816
+ "$$unit",
27817
+ { $cond: [{ $isArray: "$assignedUnit" }, "$assignedUnit", ["$assignedUnit"]] }
27818
+ ]
27819
+ },
27820
+ userType
27821
+ }
27822
+ },
27823
+ { $project: { _id: 1, userId: 1, type: 1, cardNo: 1, isActivated: 1 } }
27824
+ ],
27825
+ as: "accessCards"
27826
+ }
27827
+ },
27828
+ // ✅ Compute all card categorization and counts in ONE stage
27829
+ {
27830
+ $addFields: {
27831
+ f_Available: {
27832
+ $filter: {
27833
+ input: "$accessCards",
27834
+ as: "card",
27835
+ cond: { $and: [{ $eq: ["$$card.userId", null] }, { $eq: ["$$card.isActivated", true] }] }
27836
+ }
27837
+ },
27838
+ f_Assigned: {
27839
+ $filter: {
27840
+ input: "$accessCards",
27841
+ as: "card",
27842
+ cond: { $ne: ["$$card.userId", null] }
27843
+ }
27844
+ }
27845
+ }
27846
+ },
27847
+ // ✅ Final projection with all computed fields
27848
+ {
27849
+ $project: {
27850
+ _id: "$level.units._id",
27851
+ name: "$level.units.name",
27852
+ level: { _id: "$level._id", level: "$level.level" },
27853
+ block: { _id: "$_id", name: "$name" },
27854
+ site: "$site",
27855
+ unit_owner: { $arrayElemAt: ["$unitOwner", 0] },
27856
+ available: {
27857
+ physical: { $filter: { input: "$f_Available", as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } },
27858
+ non_physical: { $filter: { input: "$f_Available", as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } }
27859
+ },
27860
+ assigned: {
27861
+ physical: { $filter: { input: "$f_Assigned", as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } },
27862
+ non_physical: { $filter: { input: "$f_Assigned", as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } }
27863
+ },
27864
+ cardCounts: {
27865
+ available: {
27866
+ physical: { $size: { $filter: { input: { $ifNull: ["$f_Available", []] }, as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } } },
27867
+ non_physical: { $size: { $filter: { input: { $ifNull: ["$f_Available", []] }, as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } } }
27868
+ },
27869
+ assigned: {
27870
+ physical: { $size: { $filter: { input: { $ifNull: ["$f_Assigned", []] }, as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } } },
27871
+ non_physical: { $size: { $filter: { input: { $ifNull: ["$f_Assigned", []] }, as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } } }
27872
+ }
27873
+ },
27874
+ totalCardCount: {
27875
+ $add: [
27876
+ { $size: { $filter: { input: { $ifNull: ["$f_Available", []] }, as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } } },
27877
+ { $size: { $filter: { input: { $ifNull: ["$f_Available", []] }, as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } } },
27878
+ { $size: { $filter: { input: { $ifNull: ["$f_Assigned", []] }, as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } } },
27879
+ { $size: { $filter: { input: { $ifNull: ["$f_Assigned", []] }, as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } } }
27880
+ ]
27881
+ }
27882
+ }
27883
+ }
27884
+ ]
27885
+ }
27886
+ }
27887
+ ], { allowDiskUse: true }).toArray();
27888
+ const totalCount = result[0]?.totalCount?.[0]?.count ?? 0;
27889
+ const items = result[0]?.items ?? [];
27890
+ const paginatedResult = paginate38(items, page, limit, totalCount);
27891
+ return paginatedResult;
27892
+ } catch (error) {
27893
+ throw new Error(error.message);
27894
+ }
27895
+ }
27529
27896
  return {
27530
27897
  createIndexes,
27898
+ createIndexForEntrypass,
27531
27899
  addPhysicalCardRepo,
27532
- addNonPhysicalCardRepo
27900
+ addNonPhysicalCardRepo,
27901
+ accessManagementSettingsRepo,
27902
+ allAccessCardsCountsRepo,
27903
+ availableAccessCardsRepo,
27904
+ userTypeAccessCardsRepo
27533
27905
  };
27534
27906
  }
27535
27907
 
@@ -27635,7 +28007,14 @@ var formatAccessGroup = (data, search) => {
27635
28007
  // src/services/access-management.service.ts
27636
28008
  import { parseStringPromise } from "xml2js";
27637
28009
  function useAccessManagementSvc() {
27638
- const { addPhysicalCardRepo, addNonPhysicalCardRepo } = UseAccessManagementRepo();
28010
+ const {
28011
+ addPhysicalCardRepo,
28012
+ addNonPhysicalCardRepo,
28013
+ accessManagementSettingsRepo,
28014
+ allAccessCardsCountsRepo,
28015
+ availableAccessCardsRepo,
28016
+ userTypeAccessCardsRepo
28017
+ } = UseAccessManagementRepo();
27639
28018
  const addPhysicalCardSvc = async (payload) => {
27640
28019
  try {
27641
28020
  const response = await addPhysicalCardRepo({ payload });
@@ -27682,7 +28061,39 @@ function useAccessManagementSvc() {
27682
28061
  const format = await formatAccessGroup(res);
27683
28062
  return format;
27684
28063
  } catch (err) {
27685
- console.error("Failed to connect:", err);
28064
+ throw new Error(err.message);
28065
+ }
28066
+ };
28067
+ const accessManagementSettingsSvc = async (settings) => {
28068
+ try {
28069
+ const response = await accessManagementSettingsRepo({ ...settings });
28070
+ return response;
28071
+ } catch (err) {
28072
+ throw new Error(err.message);
28073
+ }
28074
+ };
28075
+ const allAccessCardsCountsSvc = async (params) => {
28076
+ try {
28077
+ const response = await allAccessCardsCountsRepo({ ...params });
28078
+ return response;
28079
+ } catch (err) {
28080
+ throw new Error(err.message);
28081
+ }
28082
+ };
28083
+ const availableAccessCardsSvc = async (params) => {
28084
+ try {
28085
+ const response = await availableAccessCardsRepo({ ...params });
28086
+ return response;
28087
+ } catch (err) {
28088
+ throw new Error(err.message);
28089
+ }
28090
+ };
28091
+ const userTypeAccessCardsSvc = async (params) => {
28092
+ try {
28093
+ const response = await userTypeAccessCardsRepo({ ...params });
28094
+ return response;
28095
+ } catch (err) {
28096
+ throw new Error(err.message);
27686
28097
  }
27687
28098
  };
27688
28099
  return {
@@ -27690,7 +28101,11 @@ function useAccessManagementSvc() {
27690
28101
  addNonPhysicalCardSvc,
27691
28102
  doorAccessLevelsSvc,
27692
28103
  liftAccessLevelsSvc,
27693
- accessGroupsSvc
28104
+ accessGroupsSvc,
28105
+ accessManagementSettingsSvc,
28106
+ allAccessCardsCountsSvc,
28107
+ availableAccessCardsSvc,
28108
+ userTypeAccessCardsSvc
27694
28109
  };
27695
28110
  }
27696
28111
 
@@ -27701,7 +28116,11 @@ function useAccessManagementController() {
27701
28116
  addNonPhysicalCardSvc,
27702
28117
  doorAccessLevelsSvc,
27703
28118
  liftAccessLevelsSvc,
27704
- accessGroupsSvc
28119
+ accessGroupsSvc,
28120
+ accessManagementSettingsSvc,
28121
+ allAccessCardsCountsSvc,
28122
+ availableAccessCardsSvc,
28123
+ userTypeAccessCardsSvc
27705
28124
  } = useAccessManagementSvc();
27706
28125
  const addPhysicalCard = async (req, res) => {
27707
28126
  try {
@@ -27761,7 +28180,8 @@ function useAccessManagementController() {
27761
28180
  createdAt,
27762
28181
  updatedAt,
27763
28182
  startDate,
27764
- endDate
28183
+ endDate,
28184
+ isWinsland
27765
28185
  } = req.body;
27766
28186
  const schema2 = Joi85.object({
27767
28187
  site: Joi85.string().hex().required(),
@@ -27777,7 +28197,8 @@ function useAccessManagementController() {
27777
28197
  startDate: Joi85.date().required(),
27778
28198
  endDate: Joi85.date().required(),
27779
28199
  createdAt: Joi85.date().required(),
27780
- updatedAt: Joi85.date().required()
28200
+ updatedAt: Joi85.date().required(),
28201
+ isWinsland: Joi85.boolean().optional().allow(null)
27781
28202
  });
27782
28203
  const { error } = schema2.validate({
27783
28204
  site,
@@ -27793,7 +28214,8 @@ function useAccessManagementController() {
27793
28214
  startDate,
27794
28215
  endDate,
27795
28216
  createdAt,
27796
- updatedAt
28217
+ updatedAt,
28218
+ isWinsland
27797
28219
  });
27798
28220
  if (error) {
27799
28221
  throw new Error(`${error.message}`);
@@ -27812,7 +28234,8 @@ function useAccessManagementController() {
27812
28234
  startDate,
27813
28235
  endDate,
27814
28236
  createdAt,
27815
- updatedAt
28237
+ updatedAt,
28238
+ isWinsland
27816
28239
  });
27817
28240
  return res.status(201).json({
27818
28241
  data: result,
@@ -27870,12 +28293,100 @@ function useAccessManagementController() {
27870
28293
  });
27871
28294
  }
27872
28295
  };
28296
+ const accessManagementSettings = async (req, res) => {
28297
+ try {
28298
+ const settings = req.body;
28299
+ const result = await accessManagementSettingsSvc(settings);
28300
+ return res.status(201).json({ message: "Success", data: result });
28301
+ } catch (error) {
28302
+ return res.status(400).json({
28303
+ data: null,
28304
+ message: error.message
28305
+ });
28306
+ }
28307
+ };
28308
+ const allAccessCardsCounts = async (req, res) => {
28309
+ try {
28310
+ const { site, userType } = req.query;
28311
+ const schema2 = Joi85.object({
28312
+ site: Joi85.string().hex().required(),
28313
+ userType: Joi85.string().required()
28314
+ });
28315
+ const { error } = schema2.validate({ site, userType });
28316
+ if (error) {
28317
+ throw new Error(`${error.message}`);
28318
+ }
28319
+ const result = await allAccessCardsCountsSvc({ site, userType });
28320
+ return res.status(200).json({ message: "Success", data: result });
28321
+ } catch (error) {
28322
+ return res.status(400).json({
28323
+ data: null,
28324
+ message: error.message
28325
+ });
28326
+ }
28327
+ };
28328
+ const availableAccessCards = async (req, res) => {
28329
+ try {
28330
+ const { site, userType, type } = req.query;
28331
+ const schema2 = Joi85.object({
28332
+ site: Joi85.string().hex().required(),
28333
+ userType: Joi85.string().optional().allow("", null),
28334
+ type: Joi85.string().optional().allow("", null)
28335
+ });
28336
+ const { error } = schema2.validate({ site, userType, type });
28337
+ if (error) {
28338
+ return res.status(400).json({ message: error.message });
28339
+ }
28340
+ const result = await availableAccessCardsSvc({ site, userType, type });
28341
+ return res.status(200).json({ message: "Success", data: result });
28342
+ } catch (error) {
28343
+ return res.status(400).json({
28344
+ data: null,
28345
+ message: error.message
28346
+ });
28347
+ }
28348
+ };
28349
+ const userTypeAccessCards = async (req, res) => {
28350
+ try {
28351
+ const {
28352
+ page = 1,
28353
+ limit = 10,
28354
+ search = "",
28355
+ site,
28356
+ organization,
28357
+ userType
28358
+ } = req.query;
28359
+ const schema2 = Joi85.object({
28360
+ page: Joi85.number().required(),
28361
+ limit: Joi85.number().optional().default(10),
28362
+ site: Joi85.string().hex().required(),
28363
+ organization: Joi85.string().hex().optional().allow("", null),
28364
+ search: Joi85.string().optional().allow("", null),
28365
+ userType: Joi85.string().required()
28366
+ });
28367
+ const { error } = schema2.validate({ page, limit, site, organization, search, userType });
28368
+ if (error) {
28369
+ return res.status(400).json({ message: error.message });
28370
+ }
28371
+ const result = await userTypeAccessCardsSvc({ page, limit, search, site, organization, userType });
28372
+ return res.status(200).json({ message: "Success", data: result });
28373
+ } catch (error) {
28374
+ return res.status(500).json({
28375
+ data: null,
28376
+ message: error.message
28377
+ });
28378
+ }
28379
+ };
27873
28380
  return {
27874
28381
  addPhysicalCard,
27875
28382
  addNonPhysicalCard,
27876
28383
  doorAccessLevels,
27877
28384
  liftAccessLevels,
27878
- accessGroups
28385
+ accessGroups,
28386
+ accessManagementSettings,
28387
+ allAccessCardsCounts,
28388
+ availableAccessCards,
28389
+ userTypeAccessCards
27879
28390
  };
27880
28391
  }
27881
28392
 
@@ -31819,7 +32330,11 @@ function MIncidentReport(value) {
31819
32330
  }
31820
32331
 
31821
32332
  // src/services/incident-report.service.ts
31822
- import { useAtlas as useAtlas88, BadRequestError as BadRequestError160 } from "@7365admin1/node-server-utils";
32333
+ import {
32334
+ useAtlas as useAtlas88,
32335
+ BadRequestError as BadRequestError160,
32336
+ NotFoundError as NotFoundError44
32337
+ } from "@7365admin1/node-server-utils";
31823
32338
 
31824
32339
  // src/repositories/incident-report.repo.ts
31825
32340
  import {
@@ -32151,15 +32666,18 @@ function useIncidentReportService() {
32151
32666
  const {
32152
32667
  add: _add,
32153
32668
  updateIncidentReportById: _updateIncidentReportById,
32154
- reviewIncidentReport: _reviewIncidentReport
32669
+ reviewIncidentReport: _reviewIncidentReport,
32670
+ getIncidentReportById: _getIncidentReportById
32155
32671
  } = useIncidentReportRepo();
32156
32672
  const {
32157
32673
  updateSiteIncidentCounter: _updateSiteIncidentCounter,
32158
32674
  getSiteById: _getSiteById
32159
32675
  } = useSiteRepo();
32676
+ const { updateStatusById } = useFileRepo();
32160
32677
  const { getUserById } = useUserRepo();
32161
32678
  const { getById: _getUnitById } = useBuildingUnitRepo();
32162
32679
  const { getById: _getOrganizationById } = useOrgRepo();
32680
+ const { deleteFile } = useFileService();
32163
32681
  async function add(value) {
32164
32682
  const session = useAtlas88.getClient()?.startSession();
32165
32683
  session?.startTransaction();
@@ -32177,6 +32695,19 @@ function useIncidentReportService() {
32177
32695
  );
32178
32696
  }
32179
32697
  }
32698
+ const incidentAttachments = value?.photos ?? [];
32699
+ if (incidentAttachments.length > 0) {
32700
+ for (const attachment of incidentAttachments) {
32701
+ const file = await updateStatusById(
32702
+ attachment,
32703
+ { status: "active" },
32704
+ session
32705
+ );
32706
+ if (!file) {
32707
+ throw new NotFoundError44("File not found.");
32708
+ }
32709
+ }
32710
+ }
32180
32711
  const result = await _add(value, session);
32181
32712
  await session?.commitTransaction();
32182
32713
  return result;
@@ -32191,6 +32722,26 @@ function useIncidentReportService() {
32191
32722
  const session = useAtlas88.getClient()?.startSession();
32192
32723
  session?.startTransaction();
32193
32724
  try {
32725
+ const incidentReport = await _getIncidentReportById(id);
32726
+ const dataAttchments = value?.photos || [];
32727
+ const incidentAttachments = incidentReport?.photos || [];
32728
+ const deletedFiles = [];
32729
+ incidentAttachments.forEach((id2) => {
32730
+ if (!dataAttchments.includes(id2)) {
32731
+ deletedFiles.push(id2);
32732
+ }
32733
+ });
32734
+ if (deletedFiles.length > 0) {
32735
+ await Promise.all(
32736
+ deletedFiles.map(async (id2) => {
32737
+ try {
32738
+ await deleteFile(id2);
32739
+ } catch (error) {
32740
+ throw error;
32741
+ }
32742
+ })
32743
+ );
32744
+ }
32194
32745
  await _updateIncidentReportById(id, value, session);
32195
32746
  await session?.commitTransaction();
32196
32747
  return "Successfully updated incident report.";
@@ -32564,7 +33115,7 @@ import {
32564
33115
  InternalServerError as InternalServerError56,
32565
33116
  logger as logger142,
32566
33117
  makeCacheKey as makeCacheKey53,
32567
- NotFoundError as NotFoundError44,
33118
+ NotFoundError as NotFoundError45,
32568
33119
  useAtlas as useAtlas89,
32569
33120
  useCache as useCache55
32570
33121
  } from "@7365admin1/node-server-utils";
@@ -32654,7 +33205,7 @@ function useNfcPatrolSettingsRepository() {
32654
33205
  { session }
32655
33206
  );
32656
33207
  if (res.matchedCount === 0) {
32657
- throw new NotFoundError44("NFC patrol settings not found for this site.");
33208
+ throw new NotFoundError45("NFC patrol settings not found for this site.");
32658
33209
  }
32659
33210
  delNamespace().then(() => {
32660
33211
  logger142.info(`Cache cleared for namespace: ${namespace_collection}`);
@@ -32818,7 +33369,7 @@ import {
32818
33369
  InternalServerError as InternalServerError57,
32819
33370
  logger as logger145,
32820
33371
  makeCacheKey as makeCacheKey54,
32821
- NotFoundError as NotFoundError45,
33372
+ NotFoundError as NotFoundError46,
32822
33373
  paginate as paginate46,
32823
33374
  useAtlas as useAtlas91,
32824
33375
  useCache as useCache56
@@ -33037,7 +33588,7 @@ function useOccurrenceSubjectRepo() {
33037
33588
  try {
33038
33589
  const data = await collection.findOne({ _id }, { session });
33039
33590
  if (!data) {
33040
- throw new NotFoundError45("Occurrence subject not found.");
33591
+ throw new NotFoundError46("Occurrence subject not found.");
33041
33592
  }
33042
33593
  setCache(cacheKey, data, 15 * 60).then(() => {
33043
33594
  logger145.info(`Cache set for key: ${cacheKey}`);
@@ -33463,7 +34014,7 @@ import {
33463
34014
  InternalServerError as InternalServerError58,
33464
34015
  logger as logger147,
33465
34016
  makeCacheKey as makeCacheKey55,
33466
- NotFoundError as NotFoundError46,
34017
+ NotFoundError as NotFoundError47,
33467
34018
  paginate as paginate47,
33468
34019
  useAtlas as useAtlas93,
33469
34020
  useCache as useCache57
@@ -33599,7 +34150,7 @@ function useOnlineFormRepo() {
33599
34150
  }
33600
34151
  ]).toArray();
33601
34152
  if (!data || !data.length) {
33602
- throw new NotFoundError46("Document not found.");
34153
+ throw new NotFoundError47("Document not found.");
33603
34154
  }
33604
34155
  setCache(cacheKey, data[0], 15 * 60).then(() => {
33605
34156
  logger147.info(`Cache set for key: ${cacheKey}`);