@7365admin1/core 2.65.0 → 2.66.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
@@ -125,7 +125,15 @@ var userSchema = Joi2.object({
125
125
  email: Joi2.string().email().required(),
126
126
  password: Joi2.string().min(8).required(),
127
127
  name: Joi2.string().required(),
128
- defaultOrg: Joi2.string().hex().optional().allow("", null)
128
+ defaultOrg: Joi2.string().hex().optional().allow("", null),
129
+ status: Joi2.string().optional().allow("", null),
130
+ block: Joi2.number().optional().allow(null),
131
+ level: Joi2.string().optional().allow("", null),
132
+ type: Joi2.string().optional().allow("", null),
133
+ unitName: Joi2.string().optional().allow("", null),
134
+ contact: Joi2.string().optional().allow("", null),
135
+ site: Joi2.string().hex().optional().allow("", null),
136
+ unitId: Joi2.string().hex().optional().allow("", null)
129
137
  });
130
138
  function MUser(value) {
131
139
  const { error } = userSchema.validate(value);
@@ -139,12 +147,33 @@ function MUser(value) {
139
147
  throw new BadRequestError2("Invalid default org ID format.");
140
148
  }
141
149
  }
150
+ if (value.site && typeof value.site === "string") {
151
+ try {
152
+ value.site = new ObjectId(value.site);
153
+ } catch {
154
+ throw new BadRequestError2("Invalid site ID format.");
155
+ }
156
+ }
157
+ if (value.unitId && typeof value.unitId === "string") {
158
+ try {
159
+ value.unitId = new ObjectId(value.unitId);
160
+ } catch {
161
+ throw new BadRequestError2("Invalid unit ID format.");
162
+ }
163
+ }
142
164
  return {
143
165
  email: value.email,
144
166
  password: value.password,
145
167
  name: value.name ?? "",
146
168
  defaultOrg: value.defaultOrg ?? "",
147
- status: "active" /* ACTIVE */,
169
+ status: value.status ?? "active" /* ACTIVE */,
170
+ block: value.block ?? null,
171
+ level: value.level ?? "",
172
+ type: value.type ?? "",
173
+ unitName: value.unitName ?? "",
174
+ contact: value.contact ?? "",
175
+ site: value.site ?? "",
176
+ unitId: value.unitId ?? "",
148
177
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
149
178
  updatedAt: value.updatedAt ?? "",
150
179
  deletedAt: value.deletedAt ?? ""
@@ -4372,6 +4401,30 @@ function useOrgRepo() {
4372
4401
  throw error;
4373
4402
  }
4374
4403
  }
4404
+ async function getOrgsByEmail(email) {
4405
+ const cacheKey = makeCacheKey8(namespace_collection, {
4406
+ type: "many",
4407
+ email
4408
+ });
4409
+ const cachedData = await getCache(cacheKey);
4410
+ if (cachedData) {
4411
+ logger10.info(`Cache hit for key: ${cacheKey}`);
4412
+ return cachedData;
4413
+ }
4414
+ try {
4415
+ const data = await collection.find({
4416
+ email
4417
+ }).toArray();
4418
+ setCache(cacheKey, data, 15 * 60).then(() => {
4419
+ logger10.info(`Cache set for key: ${cacheKey}`);
4420
+ }).catch((err) => {
4421
+ logger10.error(`Failed to set cache for key: ${cacheKey}`, err);
4422
+ });
4423
+ return data;
4424
+ } catch (error) {
4425
+ throw error;
4426
+ }
4427
+ }
4375
4428
  async function updateFieldById({
4376
4429
  _id,
4377
4430
  field,
@@ -4474,7 +4527,8 @@ function useOrgRepo() {
4474
4527
  getByEmail,
4475
4528
  updateFieldById,
4476
4529
  updateStatusById,
4477
- deleteById
4530
+ deleteById,
4531
+ getOrgsByEmail
4478
4532
  };
4479
4533
  }
4480
4534
 
@@ -5497,7 +5551,6 @@ function useVerificationService() {
5497
5551
  await getSiteById(metadata.siteId);
5498
5552
  }
5499
5553
  const verificationIds = [];
5500
- const invitedApps = [];
5501
5554
  for (const app of apps) {
5502
5555
  await useVerificationRepo().findOne({
5503
5556
  type,
@@ -5520,34 +5573,32 @@ function useVerificationService() {
5520
5573
  };
5521
5574
  const createdId = await add(value);
5522
5575
  verificationIds.push(createdId.toString());
5523
- invitedApps.push(app);
5576
+ const link = `${APP_MAIN}/verify/invitation/${createdId}`;
5577
+ const emailContent = compileHandlebar({
5578
+ context: {
5579
+ email,
5580
+ validity: VERIFICATION_USER_INVITE_DURATION,
5581
+ link,
5582
+ hasPropertyManagement: app === "property_management_agency",
5583
+ hasSecurity: app === "security_agency",
5584
+ hasCleaning: app === "cleaning_services",
5585
+ hasMechanical: app === "mechanical_electrical_services",
5586
+ hasLandscape: app === "landscaping_services",
5587
+ hasPestControl: app === "pest_control_services",
5588
+ hasPoolMaintenance: app === "pool_maintenance_services"
5589
+ },
5590
+ filePath: getDirectory(
5591
+ __dirname,
5592
+ "./public/handlebars/user-invite"
5593
+ )
5594
+ });
5595
+ await mailer.sendMail({
5596
+ to: email,
5597
+ subject: "User Invite",
5598
+ html: emailContent,
5599
+ sender: "iService365"
5600
+ });
5524
5601
  }
5525
- const link = `${APP_MAIN}/verify/invitation/${verificationIds[0]}`;
5526
- const appsSet = new Set(invitedApps);
5527
- const emailContent = compileHandlebar({
5528
- context: {
5529
- email,
5530
- validity: VERIFICATION_USER_INVITE_DURATION,
5531
- link,
5532
- hasPropertyManagement: appsSet.has("property_management_agency"),
5533
- hasSecurity: appsSet.has("security_agency"),
5534
- hasCleaning: appsSet.has("cleaning_services"),
5535
- hasMechanical: appsSet.has("mechanical_electrical_services"),
5536
- hasLandscape: appsSet.has("landscaping_services"),
5537
- hasPestControl: appsSet.has("pest_control_services"),
5538
- hasPoolMaintenance: appsSet.has("pool_maintenance_services")
5539
- },
5540
- filePath: getDirectory(
5541
- __dirname,
5542
- "./public/handlebars/user-invite"
5543
- )
5544
- });
5545
- await mailer.sendMail({
5546
- to: email,
5547
- subject: "User Invite",
5548
- html: emailContent,
5549
- sender: "iService365"
5550
- });
5551
5602
  return verificationIds;
5552
5603
  }
5553
5604
  async function createSimpleMemberInvite({
@@ -8042,7 +8093,7 @@ function useVerificationController() {
8042
8093
  siteId: Joi16.string().hex().optional().allow("", null),
8043
8094
  siteName: Joi16.string().optional().allow("", null)
8044
8095
  });
8045
- const { error } = validation.validate(payload);
8096
+ const { error, value } = validation.validate(payload);
8046
8097
  if (error) {
8047
8098
  logger22.log({
8048
8099
  level: "error",
@@ -8051,15 +8102,17 @@ function useVerificationController() {
8051
8102
  next(new BadRequestError31(error.message));
8052
8103
  return;
8053
8104
  }
8054
- const email = req.body.email ?? "";
8055
- const app = req.body.app ?? [];
8056
- const role = req.body.role ?? "";
8057
- const name = req.body.name ?? "";
8058
- const org = req.body.org ?? "";
8059
- const siteId = req.body.siteId ?? "";
8060
- const siteName = req.body.siteName ?? "";
8061
8105
  try {
8062
- await _createSimpleUserInvite({
8106
+ const {
8107
+ email,
8108
+ app,
8109
+ role,
8110
+ name,
8111
+ org,
8112
+ siteId,
8113
+ siteName
8114
+ } = value;
8115
+ const verificationIds = await _createSimpleUserInvite({
8063
8116
  email,
8064
8117
  metadata: {
8065
8118
  app,
@@ -8071,7 +8124,9 @@ function useVerificationController() {
8071
8124
  }
8072
8125
  });
8073
8126
  res.status(201).json({
8074
- message: "Successfully invited user."
8127
+ message: "Successfully invited user.",
8128
+ totalInvites: verificationIds.length,
8129
+ verificationIds
8075
8130
  });
8076
8131
  return;
8077
8132
  } catch (error2) {
@@ -8531,7 +8586,8 @@ function useOrgController() {
8531
8586
  getByEmail: _getByEmail,
8532
8587
  getAll: _getAll,
8533
8588
  add: _add,
8534
- update: _update
8589
+ update: _update,
8590
+ getOrgsByEmail: _getOrgsByEmail
8535
8591
  } = useOrgRepo();
8536
8592
  async function add(req, res, next) {
8537
8593
  const validation = Joi18.object({
@@ -8715,6 +8771,30 @@ function useOrgController() {
8715
8771
  return;
8716
8772
  }
8717
8773
  }
8774
+ async function getOrgsByEmail(req, res, next) {
8775
+ const validation = Joi18.object({
8776
+ email: Joi18.string().email().required()
8777
+ });
8778
+ const query = {
8779
+ email: req.params.email
8780
+ };
8781
+ const { error } = validation.validate(query);
8782
+ if (error) {
8783
+ logger25.log({ level: "error", message: error.message });
8784
+ next(new BadRequestError33(error.message));
8785
+ return;
8786
+ }
8787
+ const email = req.params.email;
8788
+ try {
8789
+ const data = await _getOrgsByEmail(email);
8790
+ res.json(data);
8791
+ return;
8792
+ } catch (error2) {
8793
+ logger25.log({ level: "error", message: error2.message });
8794
+ next(error2);
8795
+ return;
8796
+ }
8797
+ }
8718
8798
  async function update(req, res, next) {
8719
8799
  const validation = Joi18.object({
8720
8800
  name: Joi18.string().optional(),
@@ -8748,7 +8828,8 @@ function useOrgController() {
8748
8828
  getByName,
8749
8829
  getById,
8750
8830
  getByEmail,
8751
- update
8831
+ update,
8832
+ getOrgsByEmail
8752
8833
  };
8753
8834
  }
8754
8835
 
@@ -26552,7 +26633,14 @@ function usePersonService() {
26552
26633
  password: hashedPassword,
26553
26634
  name: value.name,
26554
26635
  status: value.platform == "mobile" ? "pending" : "active",
26555
- defaultOrg: value.org?.toString() || ""
26636
+ defaultOrg: value.org?.toString() || "",
26637
+ block: value.block,
26638
+ level: value.level,
26639
+ type: value.type,
26640
+ unitName: value.unitName,
26641
+ contact: value.contact,
26642
+ site: value.site?.toString() || "",
26643
+ unitId: value.unit?.toString() || ""
26556
26644
  };
26557
26645
  const userId = await addUser(user, session);
26558
26646
  value.user = userId.toString();
@@ -36340,10 +36428,42 @@ function UseAccessManagementRepo() {
36340
36428
  },
36341
36429
  {
36342
36430
  $facet: {
36343
- available_physical: [{ $match: { assignedUnit: { $eq: null }, type: "NFC" /* NFC */ } }, { $count: "count" }],
36344
- available_non_physical: [{ $match: { assignedUnit: { $eq: null }, type: "QRCODE" /* QR */ } }, { $count: "count" }],
36345
- assigned_physical: [{ $match: { assignedUnit: { $ne: null }, type: "NFC" /* NFC */ } }, { $count: "count" }],
36346
- assigned_non_physical: [{ $match: { assignedUnit: { $ne: null }, type: "QRCODE" /* QR */ } }, { $count: "count" }]
36431
+ available_physical: [
36432
+ {
36433
+ $match: {
36434
+ assignedUnit: { $eq: null },
36435
+ type: "NFC" /* NFC */
36436
+ }
36437
+ },
36438
+ { $count: "count" }
36439
+ ],
36440
+ available_non_physical: [
36441
+ {
36442
+ $match: {
36443
+ assignedUnit: { $eq: null },
36444
+ type: "QRCODE" /* QR */
36445
+ }
36446
+ },
36447
+ { $count: "count" }
36448
+ ],
36449
+ assigned_physical: [
36450
+ {
36451
+ $match: {
36452
+ assignedUnit: { $ne: null },
36453
+ type: "NFC" /* NFC */
36454
+ }
36455
+ },
36456
+ { $count: "count" }
36457
+ ],
36458
+ assigned_non_physical: [
36459
+ {
36460
+ $match: {
36461
+ assignedUnit: { $ne: null },
36462
+ type: "QRCODE" /* QR */
36463
+ }
36464
+ },
36465
+ { $count: "count" }
36466
+ ]
36347
36467
  }
36348
36468
  }
36349
36469
  ]).toArray();
@@ -36428,16 +36548,35 @@ function UseAccessManagementRepo() {
36428
36548
  case terms.length >= 3:
36429
36549
  return {
36430
36550
  $and: [
36431
- { $expr: { $eq: [{ $toLower: "$name" }, terms[0].toLowerCase()] } },
36432
- { $expr: { $eq: [{ $toLower: "$level.level" }, terms[1].toLowerCase()] } },
36433
- { $expr: { $eq: [{ $toLower: "$level.units.name" }, getAfterSecondSlash(search)] } }
36551
+ {
36552
+ $expr: { $eq: [{ $toLower: "$name" }, terms[0].toLowerCase()] }
36553
+ },
36554
+ {
36555
+ $expr: {
36556
+ $eq: [{ $toLower: "$level.level" }, terms[1].toLowerCase()]
36557
+ }
36558
+ },
36559
+ {
36560
+ $expr: {
36561
+ $eq: [
36562
+ { $toLower: "$level.units.name" },
36563
+ getAfterSecondSlash(search)
36564
+ ]
36565
+ }
36566
+ }
36434
36567
  ]
36435
36568
  };
36436
36569
  case terms.length === 2:
36437
36570
  return {
36438
36571
  $and: [
36439
- { $expr: { $eq: [{ $toLower: "$name" }, terms[0].toLowerCase()] } },
36440
- { $expr: { $eq: [{ $toLower: "$level.level" }, terms[1].toLowerCase()] } }
36572
+ {
36573
+ $expr: { $eq: [{ $toLower: "$name" }, terms[0].toLowerCase()] }
36574
+ },
36575
+ {
36576
+ $expr: {
36577
+ $eq: [{ $toLower: "$level.level" }, terms[1].toLowerCase()]
36578
+ }
36579
+ }
36441
36580
  ]
36442
36581
  };
36443
36582
  default:
@@ -36465,220 +36604,386 @@ function UseAccessManagementRepo() {
36465
36604
  site
36466
36605
  };
36467
36606
  const searchQuery = buildSearchQuery(search);
36468
- const result = await collectionName("buildings").aggregate([
36469
- // ✅ Match early with index-friendly query
36470
- {
36471
- $match: {
36472
- ...defaultQuery,
36473
- status: { $eq: "active" }
36474
- }
36475
- },
36476
- // ✅ Only project needed fields before heavy lookups
36477
- {
36478
- $project: {
36479
- _id: 1,
36480
- name: 1,
36481
- site: 1,
36482
- block: 1
36483
- }
36484
- },
36485
- // ✅ Use localField/foreignField for better index usage
36486
- {
36487
- $lookup: {
36488
- from: "building-levels",
36489
- localField: "_id",
36490
- foreignField: "block",
36491
- pipeline: [
36492
- { $match: { status: { $ne: "deleted" } } },
36493
- {
36494
- $lookup: {
36495
- from: "building-units",
36496
- localField: "_id",
36497
- foreignField: "level",
36498
- pipeline: [
36499
- { $match: { status: { $ne: "deleted" }, site } },
36500
- { $project: { _id: 1, name: 1 } }
36501
- ],
36502
- as: "units"
36503
- }
36504
- },
36505
- {
36506
- $match: { "units.0": { $exists: true } }
36507
- },
36508
- {
36509
- $project: {
36510
- _id: 1,
36511
- level: 1,
36512
- units: 1
36607
+ const result = await collectionName("buildings").aggregate(
36608
+ [
36609
+ // ✅ Match early with index-friendly query
36610
+ {
36611
+ $match: {
36612
+ ...defaultQuery,
36613
+ status: { $eq: "active" }
36614
+ }
36615
+ },
36616
+ // ✅ Only project needed fields before heavy lookups
36617
+ {
36618
+ $project: {
36619
+ _id: 1,
36620
+ name: 1,
36621
+ site: 1,
36622
+ block: 1
36623
+ }
36624
+ },
36625
+ // ✅ Use localField/foreignField for better index usage
36626
+ {
36627
+ $lookup: {
36628
+ from: "building-levels",
36629
+ localField: "_id",
36630
+ foreignField: "block",
36631
+ pipeline: [
36632
+ { $match: { status: { $ne: "deleted" } } },
36633
+ {
36634
+ $lookup: {
36635
+ from: "building-units",
36636
+ localField: "_id",
36637
+ foreignField: "level",
36638
+ pipeline: [
36639
+ { $match: { status: { $ne: "deleted" }, site } },
36640
+ { $project: { _id: 1, name: 1 } }
36641
+ ],
36642
+ as: "units"
36643
+ }
36644
+ },
36645
+ {
36646
+ $match: { "units.0": { $exists: true } }
36647
+ },
36648
+ {
36649
+ $project: {
36650
+ _id: 1,
36651
+ level: 1,
36652
+ units: 1
36653
+ }
36513
36654
  }
36514
- }
36515
- ],
36516
- as: "level"
36517
- }
36518
- },
36519
- // ✅ Filter out buildings with no levels early
36520
- {
36521
- $match: { "level.0": { $exists: true } }
36522
- },
36523
- // ✅ Unwind to flatten the hierarchy
36524
- {
36525
- $unwind: {
36526
- path: "$level",
36527
- preserveNullAndEmptyArrays: false
36528
- }
36529
- },
36530
- {
36531
- $unwind: {
36532
- path: "$level.units",
36533
- preserveNullAndEmptyArrays: false
36534
- }
36535
- },
36536
- // // Groups by unit _id and keeps only the first occurrence
36537
- // {
36538
- // $group: {
36539
- // _id: "$level.units._id",
36540
- // doc: { $first: "$$ROOT" },
36541
- // },
36542
- // },
36543
- // {
36544
- // $replaceRoot: { newRoot: "$doc" },
36545
- // },
36546
- // ✅ Apply search filter
36547
- {
36548
- $match: {
36549
- ...searchQuery
36550
- }
36551
- },
36552
- {
36553
- $facet: {
36554
- totalCount: [{ $count: "count" }],
36555
- items: [
36556
- // Sort BEFORE skip/limit for correct pagination
36557
- { $skip: page * limit },
36558
- { $limit: limit },
36559
- // ✅ Users lookup - optimized with index hint
36560
- {
36561
- $lookup: {
36562
- from: "users",
36563
- let: { unit: "$level.units._id" },
36564
- pipeline: [
36565
- {
36566
- $match: {
36567
- $expr: { $eq: ["$unitNumber", "$$unit"] },
36568
- residentType: "House/Unit Owner"
36655
+ ],
36656
+ as: "level"
36657
+ }
36658
+ },
36659
+ // ✅ Filter out buildings with no levels early
36660
+ {
36661
+ $match: { "level.0": { $exists: true } }
36662
+ },
36663
+ // ✅ Unwind to flatten the hierarchy
36664
+ {
36665
+ $unwind: {
36666
+ path: "$level",
36667
+ preserveNullAndEmptyArrays: false
36668
+ }
36669
+ },
36670
+ {
36671
+ $unwind: {
36672
+ path: "$level.units",
36673
+ preserveNullAndEmptyArrays: false
36674
+ }
36675
+ },
36676
+ // // Groups by unit _id and keeps only the first occurrence
36677
+ // {
36678
+ // $group: {
36679
+ // _id: "$level.units._id",
36680
+ // doc: { $first: "$$ROOT" },
36681
+ // },
36682
+ // },
36683
+ // {
36684
+ // $replaceRoot: { newRoot: "$doc" },
36685
+ // },
36686
+ // ✅ Apply search filter
36687
+ {
36688
+ $match: {
36689
+ ...searchQuery
36690
+ }
36691
+ },
36692
+ {
36693
+ $facet: {
36694
+ totalCount: [{ $count: "count" }],
36695
+ items: [
36696
+ // ✅ Sort BEFORE skip/limit for correct pagination
36697
+ { $skip: page * limit },
36698
+ { $limit: limit },
36699
+ // Users lookup - optimized with index hint
36700
+ {
36701
+ $lookup: {
36702
+ from: "users",
36703
+ let: { unit: "$level.units._id" },
36704
+ pipeline: [
36705
+ {
36706
+ $match: {
36707
+ $expr: { $eq: ["$unitNumber", "$$unit"] },
36708
+ residentType: "House/Unit Owner"
36709
+ }
36710
+ },
36711
+ { $limit: 1 },
36712
+ { $project: { _id: 1, givenName: 1, surname: 1 } }
36713
+ ],
36714
+ as: "unitOwner"
36715
+ }
36716
+ },
36717
+ // ✅ Access card lookup - optimized query
36718
+ {
36719
+ $lookup: {
36720
+ from: "access-cards",
36721
+ let: { unit: "$level.units._id" },
36722
+ pipeline: [
36723
+ {
36724
+ $match: {
36725
+ $expr: {
36726
+ $in: [
36727
+ "$$unit",
36728
+ {
36729
+ $cond: [
36730
+ { $isArray: "$assignedUnit" },
36731
+ "$assignedUnit",
36732
+ ["$assignedUnit"]
36733
+ ]
36734
+ }
36735
+ ]
36736
+ },
36737
+ userType
36738
+ }
36739
+ },
36740
+ {
36741
+ $project: {
36742
+ _id: 1,
36743
+ userId: 1,
36744
+ type: 1,
36745
+ cardNo: 1,
36746
+ isActivated: 1,
36747
+ replacementStatus: 1
36748
+ }
36749
+ }
36750
+ ],
36751
+ as: "accessCards"
36752
+ }
36753
+ },
36754
+ // ✅ Compute all card categorization and counts in ONE stage
36755
+ {
36756
+ $addFields: {
36757
+ f_Available: {
36758
+ $filter: {
36759
+ input: "$accessCards",
36760
+ as: "card",
36761
+ cond: {
36762
+ $and: [
36763
+ { $eq: ["$$card.userId", null] },
36764
+ { $eq: ["$$card.isActivated", true] }
36765
+ ]
36766
+ }
36569
36767
  }
36570
36768
  },
36571
- { $limit: 1 },
36572
- { $project: { _id: 1, givenName: 1, surname: 1 } }
36573
- ],
36574
- as: "unitOwner"
36575
- }
36576
- },
36577
- // Access card lookup - optimized query
36578
- {
36579
- $lookup: {
36580
- from: "access-cards",
36581
- let: { unit: "$level.units._id" },
36582
- pipeline: [
36583
- {
36584
- $match: {
36585
- $expr: {
36586
- $in: [
36587
- "$$unit",
36588
- { $cond: [{ $isArray: "$assignedUnit" }, "$assignedUnit", ["$assignedUnit"]] }
36769
+ f_Assigned: {
36770
+ $filter: {
36771
+ input: "$accessCards",
36772
+ as: "card",
36773
+ cond: {
36774
+ $and: [
36775
+ { $ne: ["$$card.userId", null] },
36776
+ { $eq: ["$$card.isActivated", true] }
36589
36777
  ]
36590
- },
36591
- userType
36778
+ }
36592
36779
  }
36593
36780
  },
36594
- { $project: { _id: 1, userId: 1, type: 1, cardNo: 1, isActivated: 1, replacementStatus: 1 } }
36595
- ],
36596
- as: "accessCards"
36597
- }
36598
- },
36599
- // ✅ Compute all card categorization and counts in ONE stage
36600
- {
36601
- $addFields: {
36602
- f_Available: {
36603
- $filter: {
36604
- input: "$accessCards",
36605
- as: "card",
36606
- cond: { $and: [{ $eq: ["$$card.userId", null] }, { $eq: ["$$card.isActivated", true] }] }
36607
- }
36608
- },
36609
- f_Assigned: {
36610
- $filter: {
36611
- input: "$accessCards",
36612
- as: "card",
36613
- cond: { $and: [{ $ne: ["$$card.userId", null] }, { $eq: ["$$card.isActivated", true] }] }
36614
- }
36615
- },
36616
- f_replaced: {
36617
- $filter: {
36618
- input: "$accessCards",
36619
- as: "card",
36620
- cond: { $and: [{ $eq: ["$$card.isActivated", false] }, { $ne: ["$$card.replacementStatus", null] }] }
36621
- }
36622
- },
36623
- f_deleted: {
36624
- $filter: {
36625
- input: "$accessCards",
36626
- as: "card",
36627
- cond: { $and: [{ $eq: ["$$card.isActivated", false] }, { $eq: ["$$card.replacementStatus", null] }] }
36781
+ f_replaced: {
36782
+ $filter: {
36783
+ input: "$accessCards",
36784
+ as: "card",
36785
+ cond: {
36786
+ $and: [
36787
+ { $eq: ["$$card.isActivated", false] },
36788
+ { $ne: ["$$card.replacementStatus", null] }
36789
+ ]
36790
+ }
36791
+ }
36792
+ },
36793
+ f_deleted: {
36794
+ $filter: {
36795
+ input: "$accessCards",
36796
+ as: "card",
36797
+ cond: {
36798
+ $and: [
36799
+ { $eq: ["$$card.isActivated", false] },
36800
+ { $eq: ["$$card.replacementStatus", null] }
36801
+ ]
36802
+ }
36803
+ }
36628
36804
  }
36629
36805
  }
36630
- }
36631
- },
36632
- // ✅ Final projection with all computed fields
36633
- {
36634
- $project: {
36635
- _id: "$level.units._id",
36636
- name: "$level.units.name",
36637
- level: { _id: "$level._id", level: "$level.level" },
36638
- block: { _id: "$_id", name: "$name", block: "$block" },
36639
- site: "$site",
36640
- unit_owner: { $arrayElemAt: ["$unitOwner", 0] },
36641
- available: {
36642
- physical: { $filter: { input: "$f_Available", as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } },
36643
- non_physical: { $filter: { input: "$f_Available", as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } }
36644
- },
36645
- assigned: {
36646
- physical: { $filter: { input: "$f_Assigned", as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } },
36647
- non_physical: { $filter: { input: "$f_Assigned", as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } }
36648
- },
36649
- cardCounts: {
36806
+ },
36807
+ // ✅ Final projection with all computed fields
36808
+ {
36809
+ $project: {
36810
+ _id: "$level.units._id",
36811
+ name: "$level.units.name",
36812
+ level: { _id: "$level._id", level: "$level.level" },
36813
+ block: { _id: "$_id", name: "$name", block: "$block" },
36814
+ site: "$site",
36815
+ unit_owner: { $arrayElemAt: ["$unitOwner", 0] },
36650
36816
  available: {
36651
- physical: { $size: { $filter: { input: { $ifNull: ["$f_Available", []] }, as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } } },
36652
- non_physical: { $size: { $filter: { input: { $ifNull: ["$f_Available", []] }, as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } } }
36817
+ physical: {
36818
+ $filter: {
36819
+ input: "$f_Available",
36820
+ as: "c",
36821
+ cond: { $eq: ["$$c.type", "NFC" /* NFC */] }
36822
+ }
36823
+ },
36824
+ non_physical: {
36825
+ $filter: {
36826
+ input: "$f_Available",
36827
+ as: "c",
36828
+ cond: { $eq: ["$$c.type", "QRCODE" /* QR */] }
36829
+ }
36830
+ }
36653
36831
  },
36654
36832
  assigned: {
36655
- physical: { $size: { $filter: { input: { $ifNull: ["$f_Assigned", []] }, as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } } },
36656
- non_physical: { $size: { $filter: { input: { $ifNull: ["$f_Assigned", []] }, as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } } }
36833
+ physical: {
36834
+ $filter: {
36835
+ input: "$f_Assigned",
36836
+ as: "c",
36837
+ cond: { $eq: ["$$c.type", "NFC" /* NFC */] }
36838
+ }
36839
+ },
36840
+ non_physical: {
36841
+ $filter: {
36842
+ input: "$f_Assigned",
36843
+ as: "c",
36844
+ cond: { $eq: ["$$c.type", "QRCODE" /* QR */] }
36845
+ }
36846
+ }
36847
+ },
36848
+ cardCounts: {
36849
+ available: {
36850
+ physical: {
36851
+ $size: {
36852
+ $filter: {
36853
+ input: { $ifNull: ["$f_Available", []] },
36854
+ as: "c",
36855
+ cond: {
36856
+ $eq: ["$$c.type", "NFC" /* NFC */]
36857
+ }
36858
+ }
36859
+ }
36860
+ },
36861
+ non_physical: {
36862
+ $size: {
36863
+ $filter: {
36864
+ input: { $ifNull: ["$f_Available", []] },
36865
+ as: "c",
36866
+ cond: {
36867
+ $eq: ["$$c.type", "QRCODE" /* QR */]
36868
+ }
36869
+ }
36870
+ }
36871
+ }
36872
+ },
36873
+ assigned: {
36874
+ physical: {
36875
+ $size: {
36876
+ $filter: {
36877
+ input: { $ifNull: ["$f_Assigned", []] },
36878
+ as: "c",
36879
+ cond: {
36880
+ $eq: ["$$c.type", "NFC" /* NFC */]
36881
+ }
36882
+ }
36883
+ }
36884
+ },
36885
+ non_physical: {
36886
+ $size: {
36887
+ $filter: {
36888
+ input: { $ifNull: ["$f_Assigned", []] },
36889
+ as: "c",
36890
+ cond: {
36891
+ $eq: ["$$c.type", "QRCODE" /* QR */]
36892
+ }
36893
+ }
36894
+ }
36895
+ }
36896
+ }
36897
+ },
36898
+ replaced: {
36899
+ physical: {
36900
+ $filter: {
36901
+ input: "$f_replaced",
36902
+ as: "c",
36903
+ cond: { $eq: ["$$c.type", "NFC" /* NFC */] }
36904
+ }
36905
+ },
36906
+ non_physical: {
36907
+ $filter: {
36908
+ input: "$f_replaced",
36909
+ as: "c",
36910
+ cond: { $eq: ["$$c.type", "QRCODE" /* QR */] }
36911
+ }
36912
+ }
36913
+ },
36914
+ deleted: {
36915
+ physical: {
36916
+ $filter: {
36917
+ input: "$f_deleted",
36918
+ as: "c",
36919
+ cond: { $eq: ["$$c.type", "NFC" /* NFC */] }
36920
+ }
36921
+ },
36922
+ non_physical: {
36923
+ $filter: {
36924
+ input: "$f_deleted",
36925
+ as: "c",
36926
+ cond: { $eq: ["$$c.type", "QRCODE" /* QR */] }
36927
+ }
36928
+ }
36929
+ },
36930
+ totalCardCount: {
36931
+ $add: [
36932
+ {
36933
+ $size: {
36934
+ $filter: {
36935
+ input: { $ifNull: ["$f_Available", []] },
36936
+ as: "c",
36937
+ cond: {
36938
+ $eq: ["$$c.type", "NFC" /* NFC */]
36939
+ }
36940
+ }
36941
+ }
36942
+ },
36943
+ {
36944
+ $size: {
36945
+ $filter: {
36946
+ input: { $ifNull: ["$f_Available", []] },
36947
+ as: "c",
36948
+ cond: {
36949
+ $eq: ["$$c.type", "QRCODE" /* QR */]
36950
+ }
36951
+ }
36952
+ }
36953
+ },
36954
+ {
36955
+ $size: {
36956
+ $filter: {
36957
+ input: { $ifNull: ["$f_Assigned", []] },
36958
+ as: "c",
36959
+ cond: {
36960
+ $eq: ["$$c.type", "NFC" /* NFC */]
36961
+ }
36962
+ }
36963
+ }
36964
+ },
36965
+ {
36966
+ $size: {
36967
+ $filter: {
36968
+ input: { $ifNull: ["$f_Assigned", []] },
36969
+ as: "c",
36970
+ cond: {
36971
+ $eq: ["$$c.type", "QRCODE" /* QR */]
36972
+ }
36973
+ }
36974
+ }
36975
+ }
36976
+ ]
36657
36977
  }
36658
- },
36659
- replaced: {
36660
- physical: { $filter: { input: "$f_replaced", as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } },
36661
- non_physical: { $filter: { input: "$f_replaced", as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } }
36662
- },
36663
- deleted: {
36664
- physical: { $filter: { input: "$f_deleted", as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } },
36665
- non_physical: { $filter: { input: "$f_deleted", as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } }
36666
- },
36667
- totalCardCount: {
36668
- $add: [
36669
- { $size: { $filter: { input: { $ifNull: ["$f_Available", []] }, as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } } },
36670
- { $size: { $filter: { input: { $ifNull: ["$f_Available", []] }, as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } } },
36671
- { $size: { $filter: { input: { $ifNull: ["$f_Assigned", []] }, as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } } },
36672
- { $size: { $filter: { input: { $ifNull: ["$f_Assigned", []] }, as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } } }
36673
- ]
36674
36978
  }
36675
- }
36676
- },
36677
- { $sort: { totalCardCount: -1 } }
36678
- ]
36979
+ },
36980
+ { $sort: { totalCardCount: -1 } }
36981
+ ]
36982
+ }
36679
36983
  }
36680
- }
36681
- ], { allowDiskUse: true }).toArray();
36984
+ ],
36985
+ { allowDiskUse: true }
36986
+ ).toArray();
36682
36987
  const totalCount = result[0]?.totalCount?.[0]?.count ?? 0;
36683
36988
  const items = result[0]?.items ?? [];
36684
36989
  const paginatedResult = paginate39(items, page, limit, totalCount);
@@ -36697,157 +37002,162 @@ function UseAccessManagementRepo() {
36697
37002
  site: { $in: [site] }
36698
37003
  };
36699
37004
  const searchQuery = buildSearchQuery(search);
36700
- const result = await collectionName("buildings").aggregate([
36701
- // ✅ Match early with index-friendly query
36702
- {
36703
- $match: {
36704
- ...query,
36705
- status: { $ne: "deleted" }
36706
- }
36707
- },
36708
- // ✅ Only project needed fields before heavy lookups
36709
- {
36710
- $project: {
36711
- _id: 1,
36712
- name: 1,
36713
- site: 1
36714
- }
36715
- },
36716
- // ✅ Use localField/foreignField for better index usage
36717
- {
36718
- $lookup: {
36719
- from: "building-levels",
36720
- localField: "_id",
36721
- foreignField: "block",
36722
- pipeline: [
36723
- { $match: { status: { $ne: "deleted" } } },
36724
- {
36725
- $lookup: {
36726
- from: "building-units",
36727
- localField: "_id",
36728
- foreignField: "level",
36729
- pipeline: [
36730
- { $match: { status: { $ne: "deleted" } } },
36731
- { $project: { _id: 1, name: 1 } },
36732
- {
36733
- $lookup: {
36734
- from: "access-cards",
36735
- localField: "_id",
36736
- foreignField: "assignedUnit",
36737
- pipeline: [
36738
- {
36739
- $match: {
36740
- isActivated: true,
36741
- userType,
36742
- type
36743
- }
36744
- },
36745
- {
36746
- $group: {
36747
- _id: null,
36748
- accessLevels: { $addToSet: "$accessLevel" },
36749
- liftAccessLevels: { $addToSet: "$liftAccessLevel" },
36750
- doorNames: { $addToSet: "$doorName" },
36751
- liftNames: { $addToSet: "$liftName" },
36752
- cards: {
36753
- $push: {
36754
- _id: "$_id",
36755
- cardNo: "$cardNo",
36756
- accessLevel: "$accessLevel",
36757
- liftAccessLevel: "$liftAccessLevel",
36758
- doorName: "$doorName",
36759
- liftName: "$liftName"
37005
+ const result = await collectionName("buildings").aggregate(
37006
+ [
37007
+ // ✅ Match early with index-friendly query
37008
+ {
37009
+ $match: {
37010
+ ...query,
37011
+ status: { $ne: "deleted" }
37012
+ }
37013
+ },
37014
+ // ✅ Only project needed fields before heavy lookups
37015
+ {
37016
+ $project: {
37017
+ _id: 1,
37018
+ name: 1,
37019
+ site: 1
37020
+ }
37021
+ },
37022
+ // ✅ Use localField/foreignField for better index usage
37023
+ {
37024
+ $lookup: {
37025
+ from: "building-levels",
37026
+ localField: "_id",
37027
+ foreignField: "block",
37028
+ pipeline: [
37029
+ { $match: { status: { $ne: "deleted" } } },
37030
+ {
37031
+ $lookup: {
37032
+ from: "building-units",
37033
+ localField: "_id",
37034
+ foreignField: "level",
37035
+ pipeline: [
37036
+ { $match: { status: { $ne: "deleted" } } },
37037
+ { $project: { _id: 1, name: 1 } },
37038
+ {
37039
+ $lookup: {
37040
+ from: "access-cards",
37041
+ localField: "_id",
37042
+ foreignField: "assignedUnit",
37043
+ pipeline: [
37044
+ {
37045
+ $match: {
37046
+ isActivated: true,
37047
+ userType,
37048
+ type
37049
+ }
37050
+ },
37051
+ {
37052
+ $group: {
37053
+ _id: null,
37054
+ accessLevels: { $addToSet: "$accessLevel" },
37055
+ liftAccessLevels: {
37056
+ $addToSet: "$liftAccessLevel"
37057
+ },
37058
+ doorNames: { $addToSet: "$doorName" },
37059
+ liftNames: { $addToSet: "$liftName" },
37060
+ cards: {
37061
+ $push: {
37062
+ _id: "$_id",
37063
+ cardNo: "$cardNo",
37064
+ accessLevel: "$accessLevel",
37065
+ liftAccessLevel: "$liftAccessLevel",
37066
+ doorName: "$doorName",
37067
+ liftName: "$liftName"
37068
+ }
36760
37069
  }
36761
37070
  }
37071
+ },
37072
+ {
37073
+ $project: {
37074
+ _id: 0,
37075
+ accessCardCount: {
37076
+ $size: "$cards"
37077
+ },
37078
+ accessLevels: 1,
37079
+ liftAccessLevels: 1,
37080
+ doorNames: 1,
37081
+ liftNames: 1
37082
+ }
36762
37083
  }
36763
- },
36764
- {
36765
- $project: {
36766
- _id: 0,
36767
- accessCardCount: {
36768
- $size: "$cards"
36769
- },
36770
- accessLevels: 1,
36771
- liftAccessLevels: 1,
36772
- doorNames: 1,
36773
- liftNames: 1
36774
- }
36775
- }
36776
- ],
36777
- as: "fAccessCards"
36778
- }
36779
- },
36780
- {
36781
- $match: {
36782
- "fAccessCards.0": { $exists: true }
37084
+ ],
37085
+ as: "fAccessCards"
37086
+ }
37087
+ },
37088
+ {
37089
+ $match: {
37090
+ "fAccessCards.0": { $exists: true }
37091
+ }
36783
37092
  }
36784
- }
36785
- ],
36786
- as: "units"
36787
- }
36788
- },
36789
- {
36790
- $match: { "units.0": { $exists: true } }
36791
- },
36792
- {
36793
- $project: {
36794
- _id: 1,
36795
- level: 1,
36796
- units: 1
37093
+ ],
37094
+ as: "units"
37095
+ }
37096
+ },
37097
+ {
37098
+ $match: { "units.0": { $exists: true } }
37099
+ },
37100
+ {
37101
+ $project: {
37102
+ _id: 1,
37103
+ level: 1,
37104
+ units: 1
37105
+ }
36797
37106
  }
36798
- }
36799
- ],
36800
- as: "level"
36801
- }
36802
- },
36803
- // ✅ Filter out buildings with no levels early
36804
- {
36805
- $match: { "level.0": { $exists: true } }
36806
- },
36807
- // ✅ Unwind to flatten the hierarchy
36808
- {
36809
- $unwind: {
36810
- path: "$level",
36811
- preserveNullAndEmptyArrays: false
36812
- }
36813
- },
36814
- {
36815
- $unwind: {
36816
- path: "$level.units",
36817
- preserveNullAndEmptyArrays: false
36818
- }
36819
- },
36820
- {
36821
- $unwind: {
36822
- path: "$level.units.fAccessCards",
36823
- preserveNullAndEmptyArrays: false
36824
- }
36825
- },
36826
- // // Groups by unit _id and keeps only the first occurrence
36827
- {
36828
- $group: {
36829
- _id: "$level.units._id",
36830
- doc: { $first: "$$ROOT" }
36831
- }
36832
- },
36833
- {
36834
- $replaceRoot: { newRoot: "$doc" }
36835
- },
36836
- // ✅ Apply search filter
36837
- {
36838
- $match: {
36839
- ...searchQuery
36840
- }
36841
- },
36842
- {
36843
- $project: {
36844
- name: 1,
36845
- "level.level": 1,
36846
- "level.units.name": 1,
36847
- "level.units.fAccessCards": 1
37107
+ ],
37108
+ as: "level"
37109
+ }
37110
+ },
37111
+ // ✅ Filter out buildings with no levels early
37112
+ {
37113
+ $match: { "level.0": { $exists: true } }
37114
+ },
37115
+ // ✅ Unwind to flatten the hierarchy
37116
+ {
37117
+ $unwind: {
37118
+ path: "$level",
37119
+ preserveNullAndEmptyArrays: false
37120
+ }
37121
+ },
37122
+ {
37123
+ $unwind: {
37124
+ path: "$level.units",
37125
+ preserveNullAndEmptyArrays: false
37126
+ }
37127
+ },
37128
+ {
37129
+ $unwind: {
37130
+ path: "$level.units.fAccessCards",
37131
+ preserveNullAndEmptyArrays: false
37132
+ }
37133
+ },
37134
+ // // Groups by unit _id and keeps only the first occurrence
37135
+ {
37136
+ $group: {
37137
+ _id: "$level.units._id",
37138
+ doc: { $first: "$$ROOT" }
37139
+ }
37140
+ },
37141
+ {
37142
+ $replaceRoot: { newRoot: "$doc" }
37143
+ },
37144
+ // ✅ Apply search filter
37145
+ {
37146
+ $match: {
37147
+ ...searchQuery
37148
+ }
37149
+ },
37150
+ {
37151
+ $project: {
37152
+ name: 1,
37153
+ "level.level": 1,
37154
+ "level.units.name": 1,
37155
+ "level.units.fAccessCards": 1
37156
+ }
36848
37157
  }
36849
- }
36850
- ], { allowDiskUse: true }).toArray();
37158
+ ],
37159
+ { allowDiskUse: true }
37160
+ ).toArray();
36851
37161
  return result;
36852
37162
  } catch (error) {
36853
37163
  throw new Error(error.message);
@@ -36858,8 +37168,12 @@ function UseAccessManagementRepo() {
36858
37168
  try {
36859
37169
  session?.startTransaction();
36860
37170
  const { userId, cardId, site } = params;
36861
- const allUserId = await Promise.all(userId.map(async (id) => new ObjectId90(id)));
36862
- const allCardId = await Promise.all(cardId.map(async (id) => new ObjectId90(id)));
37171
+ const allUserId = await Promise.all(
37172
+ userId.map(async (id) => new ObjectId90(id))
37173
+ );
37174
+ const allCardId = await Promise.all(
37175
+ cardId.map(async (id) => new ObjectId90(id))
37176
+ );
36863
37177
  const siteId = new ObjectId90(site);
36864
37178
  const result = await collection().updateMany(
36865
37179
  {
@@ -36902,16 +37216,19 @@ function UseAccessManagementRepo() {
36902
37216
  liftAccessLevel,
36903
37217
  isActivated: true
36904
37218
  };
36905
- const result = await collection().aggregate([
36906
- {
36907
- $match: query
36908
- },
36909
- {
36910
- $facet: {
36911
- counts: [{ $count: "count" }]
37219
+ const result = await collection().aggregate(
37220
+ [
37221
+ {
37222
+ $match: query
37223
+ },
37224
+ {
37225
+ $facet: {
37226
+ counts: [{ $count: "count" }]
37227
+ }
36912
37228
  }
36913
- }
36914
- ], { allowDiskUse: true }).toArray();
37229
+ ],
37230
+ { allowDiskUse: true }
37231
+ ).toArray();
36915
37232
  return result;
36916
37233
  } catch (error) {
36917
37234
  throw new Error(error.message);
@@ -36945,7 +37262,9 @@ function UseAccessManagementRepo() {
36945
37262
  availableCardNo.push(num);
36946
37263
  num++;
36947
37264
  }
36948
- const cardNumbers = availableCardNo.map((no) => no.toString().padStart(10, "0"));
37265
+ const cardNumbers = availableCardNo.map(
37266
+ (no) => no.toString().padStart(10, "0")
37267
+ );
36949
37268
  const accessCards = [];
36950
37269
  const convertedUnits = unit.map((obj) => new ObjectId90(obj));
36951
37270
  for (let j = 0; j < (unit.length > 0 ? unit.length : quantity); j++) {
@@ -37005,10 +37324,18 @@ function UseAccessManagementRepo() {
37005
37324
  liftAccessEndDate: formatEntryPassDate(item.liftAccessEndDate) || "19770510",
37006
37325
  accessGroup: ag
37007
37326
  };
37008
- return readTemplate(`${item.accessLevel !== null ? "add-card" : "add-card-lift"}`, { ...command });
37327
+ return readTemplate(
37328
+ `${item.accessLevel !== null ? "add-card" : "add-card-lift"}`,
37329
+ { ...command }
37330
+ );
37009
37331
  }).flat();
37010
- const response = await sendCommand(commands.join("").toString(), params.acm_url);
37011
- const result = await parseStringPromise2(response, { explicitArray: false });
37332
+ const response = await sendCommand(
37333
+ commands.join("").toString(),
37334
+ params.acm_url
37335
+ );
37336
+ const result = await parseStringPromise2(response, {
37337
+ explicitArray: false
37338
+ });
37012
37339
  if (result && result.RESULT.$.STCODE !== "0") {
37013
37340
  throw new Error("Command failed, server error.");
37014
37341
  }
@@ -37042,7 +37369,11 @@ function UseAccessManagementRepo() {
37042
37369
  } else {
37043
37370
  updateFields.isActivated = true;
37044
37371
  }
37045
- const res = await collection().updateOne({ _id: card._id }, { $set: updateFields }, { session });
37372
+ const res = await collection().updateOne(
37373
+ { _id: card._id },
37374
+ { $set: updateFields },
37375
+ { session }
37376
+ );
37046
37377
  results.push({ nfcId: nfc._id, modifiedCount: res.modifiedCount });
37047
37378
  }
37048
37379
  }
@@ -37069,8 +37400,20 @@ function UseAccessManagementRepo() {
37069
37400
  assignedUnit: null,
37070
37401
  userId: null,
37071
37402
  $or: [
37072
- { $and: [{ doorName: { $ne: null } }, { doorName: { $ne: "" } }, { accessLevel: { $ne: null } }] },
37073
- { $and: [{ liftName: { $ne: null } }, { liftName: { $ne: "" } }, { liftAccessLevel: { $ne: null } }] }
37403
+ {
37404
+ $and: [
37405
+ { doorName: { $ne: null } },
37406
+ { doorName: { $ne: "" } },
37407
+ { accessLevel: { $ne: null } }
37408
+ ]
37409
+ },
37410
+ {
37411
+ $and: [
37412
+ { liftName: { $ne: null } },
37413
+ { liftName: { $ne: "" } },
37414
+ { liftAccessLevel: { $ne: null } }
37415
+ ]
37416
+ }
37074
37417
  ]
37075
37418
  }
37076
37419
  },
@@ -37084,7 +37427,13 @@ function UseAccessManagementRepo() {
37084
37427
  accessLevels: {
37085
37428
  $addToSet: {
37086
37429
  $cond: [
37087
- { $and: [{ $ne: ["$doorName", null] }, { $ne: ["$doorName", ""] }, { $ne: ["$accessLevel", null] }] },
37430
+ {
37431
+ $and: [
37432
+ { $ne: ["$doorName", null] },
37433
+ { $ne: ["$doorName", ""] },
37434
+ { $ne: ["$accessLevel", null] }
37435
+ ]
37436
+ },
37088
37437
  { name: "$doorName", no: "$accessLevel" },
37089
37438
  "$$REMOVE"
37090
37439
  ]
@@ -37093,7 +37442,13 @@ function UseAccessManagementRepo() {
37093
37442
  liftAccessLevels: {
37094
37443
  $addToSet: {
37095
37444
  $cond: [
37096
- { $and: [{ $ne: ["$liftName", null] }, { $ne: ["$liftName", ""] }, { $ne: ["$liftAccessLevel", null] }] },
37445
+ {
37446
+ $and: [
37447
+ { $ne: ["$liftName", null] },
37448
+ { $ne: ["$liftName", ""] },
37449
+ { $ne: ["$liftAccessLevel", null] }
37450
+ ]
37451
+ },
37097
37452
  { name: "$liftName", no: "$liftAccessLevel" },
37098
37453
  "$$REMOVE"
37099
37454
  ]
@@ -37129,7 +37484,14 @@ function UseAccessManagementRepo() {
37129
37484
  const sessionResult = await Promise.all([
37130
37485
  await collection().findOneAndUpdate(
37131
37486
  { _id: id },
37132
- { $set: { remarks, replacementStatus: "Complete", requestDate: /* @__PURE__ */ new Date(), isActivated: false } },
37487
+ {
37488
+ $set: {
37489
+ remarks,
37490
+ replacementStatus: "Complete",
37491
+ requestDate: /* @__PURE__ */ new Date(),
37492
+ isActivated: false
37493
+ }
37494
+ },
37133
37495
  { returnDocument: "after", session }
37134
37496
  ),
37135
37497
  await collection().findOneAndUpdate(
@@ -37161,7 +37523,10 @@ function UseAccessManagementRepo() {
37161
37523
  isActivated: true
37162
37524
  };
37163
37525
  if (search) {
37164
- query.$or = [{ accessLevel: { $regex: search, $options: "i" } }, { cardNo: { $regex: search, $options: "i" } }];
37526
+ query.$or = [
37527
+ { accessLevel: { $regex: search, $options: "i" } },
37528
+ { cardNo: { $regex: search, $options: "i" } }
37529
+ ];
37165
37530
  }
37166
37531
  if (type) {
37167
37532
  query.userType = type;
@@ -37186,14 +37551,22 @@ function UseAccessManagementRepo() {
37186
37551
  {
37187
37552
  $addFields: {
37188
37553
  extractedCardNo: {
37189
- $substr: ["$cardNo", { $subtract: [{ $strLenCP: "$cardNo" }, 5] }, 5]
37554
+ $substr: [
37555
+ "$cardNo",
37556
+ { $subtract: [{ $strLenCP: "$cardNo" }, 5] },
37557
+ 5
37558
+ ]
37190
37559
  }
37191
37560
  }
37192
37561
  },
37193
37562
  {
37194
37563
  $facet: {
37195
37564
  totalCount: [{ $count: "count" }],
37196
- items: [{ $sort: { _id: -1 } }, { $skip: page * limit }, { $limit: limit }]
37565
+ items: [
37566
+ { $sort: { _id: -1 } },
37567
+ { $skip: page * limit },
37568
+ { $limit: limit }
37569
+ ]
37197
37570
  }
37198
37571
  }
37199
37572
  ]).toArray();
@@ -37224,145 +37597,151 @@ function UseAccessManagementRepo() {
37224
37597
  query.replacementStatus = statusFilter;
37225
37598
  }
37226
37599
  if (dateFrom && dateTo) {
37227
- query.requestDate = { $gte: new Date(dateFrom), $lte: new Date(dateTo) };
37600
+ query.requestDate = {
37601
+ $gte: new Date(dateFrom),
37602
+ $lte: new Date(dateTo)
37603
+ };
37228
37604
  } else if (dateFrom) {
37229
37605
  query.requestDate = { $gte: new Date(dateFrom) };
37230
37606
  } else if (dateTo) {
37231
37607
  query.requestDate = { $lte: new Date(dateTo) };
37232
37608
  }
37233
- const res = await collection().aggregate([
37234
- {
37235
- $match: { ...query }
37236
- },
37237
- {
37238
- $lookup: {
37239
- from: "building-units",
37240
- let: { unit: "$assignedUnit" },
37241
- pipeline: [
37242
- {
37243
- $match: {
37244
- $expr: {
37245
- $eq: ["$_id", "$$unit"]
37609
+ const res = await collection().aggregate(
37610
+ [
37611
+ {
37612
+ $match: { ...query }
37613
+ },
37614
+ {
37615
+ $lookup: {
37616
+ from: "building-units",
37617
+ let: { unit: "$assignedUnit" },
37618
+ pipeline: [
37619
+ {
37620
+ $match: {
37621
+ $expr: {
37622
+ $eq: ["$_id", "$$unit"]
37623
+ }
37246
37624
  }
37247
- }
37248
- },
37249
- {
37250
- $project: {
37251
- _id: 1,
37252
- name: 1,
37253
- level: 1
37254
- }
37255
- }
37256
- ],
37257
- as: "unit"
37258
- }
37259
- },
37260
- {
37261
- $unwind: { path: "$unit", preserveNullAndEmptyArrays: true }
37262
- },
37263
- {
37264
- $lookup: {
37265
- from: "building-levels",
37266
- let: { level: "$unit.level" },
37267
- pipeline: [
37268
- {
37269
- $match: {
37270
- $expr: {
37271
- $eq: ["$_id", "$$level"]
37625
+ },
37626
+ {
37627
+ $project: {
37628
+ _id: 1,
37629
+ name: 1,
37630
+ level: 1
37272
37631
  }
37273
37632
  }
37274
- },
37275
- {
37276
- $project: {
37277
- _id: 1,
37278
- level: 1,
37279
- block: 1
37280
- }
37281
- }
37282
- ],
37283
- as: "level"
37284
- }
37285
- },
37286
- {
37287
- $unwind: { path: "$level", preserveNullAndEmptyArrays: true }
37288
- },
37289
- {
37290
- $lookup: {
37291
- from: "buildings",
37292
- let: { block: "$level.block" },
37293
- pipeline: [
37294
- {
37295
- $match: {
37296
- $expr: {
37297
- $eq: ["$_id", "$$block"]
37633
+ ],
37634
+ as: "unit"
37635
+ }
37636
+ },
37637
+ {
37638
+ $unwind: { path: "$unit", preserveNullAndEmptyArrays: true }
37639
+ },
37640
+ {
37641
+ $lookup: {
37642
+ from: "building-levels",
37643
+ let: { level: "$unit.level" },
37644
+ pipeline: [
37645
+ {
37646
+ $match: {
37647
+ $expr: {
37648
+ $eq: ["$_id", "$$level"]
37649
+ }
37650
+ }
37651
+ },
37652
+ {
37653
+ $project: {
37654
+ _id: 1,
37655
+ level: 1,
37656
+ block: 1
37298
37657
  }
37299
37658
  }
37300
- },
37301
- {
37302
- $project: {
37303
- _id: 1,
37304
- name: 1
37305
- }
37306
- }
37307
- ],
37308
- as: "building"
37309
- }
37310
- },
37311
- {
37312
- $unwind: { path: "$building", preserveNullAndEmptyArrays: true }
37313
- },
37314
- {
37315
- $lookup: {
37316
- from: "users",
37317
- let: { id: "$userId" },
37318
- pipeline: [
37319
- {
37320
- $match: {
37321
- $expr: {
37322
- $eq: ["$_id", "$$id"]
37659
+ ],
37660
+ as: "level"
37661
+ }
37662
+ },
37663
+ {
37664
+ $unwind: { path: "$level", preserveNullAndEmptyArrays: true }
37665
+ },
37666
+ {
37667
+ $lookup: {
37668
+ from: "buildings",
37669
+ let: { block: "$level.block" },
37670
+ pipeline: [
37671
+ {
37672
+ $match: {
37673
+ $expr: {
37674
+ $eq: ["$_id", "$$block"]
37675
+ }
37676
+ }
37677
+ },
37678
+ {
37679
+ $project: {
37680
+ _id: 1,
37681
+ name: 1
37323
37682
  }
37324
37683
  }
37325
- },
37326
- {
37327
- $project: {
37328
- givenName: 1,
37329
- surname: 1
37684
+ ],
37685
+ as: "building"
37686
+ }
37687
+ },
37688
+ {
37689
+ $unwind: { path: "$building", preserveNullAndEmptyArrays: true }
37690
+ },
37691
+ {
37692
+ $lookup: {
37693
+ from: "users",
37694
+ let: { id: "$userId" },
37695
+ pipeline: [
37696
+ {
37697
+ $match: {
37698
+ $expr: {
37699
+ $eq: ["$_id", "$$id"]
37700
+ }
37701
+ }
37702
+ },
37703
+ {
37704
+ $project: {
37705
+ givenName: 1,
37706
+ surname: 1
37707
+ }
37330
37708
  }
37331
- }
37332
- ],
37333
- as: "user"
37334
- }
37335
- },
37336
- {
37337
- $unwind: { path: "$user", preserveNullAndEmptyArrays: true }
37338
- },
37339
- {
37340
- $match: { ...searchQuery }
37341
- },
37342
- {
37343
- $facet: {
37344
- data: [
37345
- { $skip: page * limit },
37346
- { $limit: limit },
37347
- {
37348
- $project: {
37349
- _id: 1,
37350
- cardNo: 1,
37351
- accessLevel: 1,
37352
- liftAccessLevel: 1,
37353
- replacementStatus: 1,
37354
- remarks: 1,
37355
- block: "$building.name",
37356
- level: "$level.level",
37357
- unit: "$unit.name",
37358
- user: "$user"
37709
+ ],
37710
+ as: "user"
37711
+ }
37712
+ },
37713
+ {
37714
+ $unwind: { path: "$user", preserveNullAndEmptyArrays: true }
37715
+ },
37716
+ {
37717
+ $match: { ...searchQuery }
37718
+ },
37719
+ {
37720
+ $facet: {
37721
+ data: [
37722
+ { $skip: page * limit },
37723
+ { $limit: limit },
37724
+ {
37725
+ $project: {
37726
+ _id: 1,
37727
+ cardNo: 1,
37728
+ accessLevel: 1,
37729
+ liftAccessLevel: 1,
37730
+ replacementStatus: 1,
37731
+ remarks: 1,
37732
+ block: "$building.name",
37733
+ level: "$level.level",
37734
+ unit: "$unit.name",
37735
+ user: "$user"
37736
+ }
37359
37737
  }
37360
- }
37361
- ],
37362
- totalCount: [{ $count: "count" }]
37738
+ ],
37739
+ totalCount: [{ $count: "count" }]
37740
+ }
37363
37741
  }
37364
- }
37365
- ], { allowDiskUse: true }).toArray();
37742
+ ],
37743
+ { allowDiskUse: true }
37744
+ ).toArray();
37366
37745
  const count = res[0]?.totalCount[0] ? res[0].totalCount[0].count : 0;
37367
37746
  const pagination = paginate39(res[0].data, page, limit, count);
37368
37747
  return pagination;
@@ -37374,7 +37753,10 @@ function UseAccessManagementRepo() {
37374
37753
  try {
37375
37754
  const { site } = params;
37376
37755
  const siteId = new ObjectId90(site);
37377
- const res = await collectionName("entrypass-settings").findOne({ site: siteId }, { allowDiskUse: true });
37756
+ const res = await collectionName("entrypass-settings").findOne(
37757
+ { site: siteId },
37758
+ { allowDiskUse: true }
37759
+ );
37378
37760
  return res;
37379
37761
  } catch (error) {
37380
37762
  throw new Error(error.message);
@@ -37384,13 +37766,19 @@ function UseAccessManagementRepo() {
37384
37766
  const session = useAtlas76.getClient()?.startSession();
37385
37767
  try {
37386
37768
  const { dataJson, site } = params;
37387
- const rawItems = JSON.parse(dataJson).filter((_, index) => index !== -1);
37769
+ const rawItems = JSON.parse(dataJson).filter(
37770
+ (_, index) => index !== -1
37771
+ );
37388
37772
  const items = await Promise.all(
37389
37773
  rawItems.map(async (item) => {
37390
37774
  const date = new Date(item["startDate (format MM/DD/YYYY)"]);
37391
37775
  const endDate = new Date(date.setFullYear(date.getFullYear() + 10));
37392
- const cardNumber = String(Number(item["cardNo (number 0-65535 ex. 301)"] || 0)).padStart(6, "0");
37393
- const facilityCode = String(Number(item["facilityCode (number 0-255 ex. 11)"] || 0)).padStart(4, "0");
37776
+ const cardNumber = String(
37777
+ Number(item["cardNo (number 0-65535 ex. 301)"] || 0)
37778
+ ).padStart(6, "0");
37779
+ const facilityCode = String(
37780
+ Number(item["facilityCode (number 0-255 ex. 11)"] || 0)
37781
+ ).padStart(4, "0");
37394
37782
  const pin = item["pin (number 6 digits only)"] ? item["pin (number 6 digits only)"].toString().padStart(6, "0") : "123456";
37395
37783
  const match = item["accessLevel (number ex. 1)"];
37396
37784
  const accessLevel = match ? match : null;
@@ -37421,7 +37809,10 @@ function UseAccessManagementRepo() {
37421
37809
  });
37422
37810
  })
37423
37811
  );
37424
- const result = await collection().insertMany(items, { session, ordered: false });
37812
+ const result = await collection().insertMany(items, {
37813
+ session,
37814
+ ordered: false
37815
+ });
37425
37816
  const mapping = items.map((item, i) => ({
37426
37817
  cardNo: item.cardNo,
37427
37818
  insertedId: result.insertedIds[i]
@@ -37436,8 +37827,19 @@ function UseAccessManagementRepo() {
37436
37827
  let isAborted = false;
37437
37828
  try {
37438
37829
  await session?.startTransaction();
37439
- const { units, quantity, type, site, userType, accessLevel, liftAccessLevel } = params;
37440
- const [convertedUnits, convertedSite] = await Promise.all([Promise.all(units.map((id) => new ObjectId90(id))), new ObjectId90(site)]);
37830
+ const {
37831
+ units,
37832
+ quantity,
37833
+ type,
37834
+ site,
37835
+ userType,
37836
+ accessLevel,
37837
+ liftAccessLevel
37838
+ } = params;
37839
+ const [convertedUnits, convertedSite] = await Promise.all([
37840
+ Promise.all(units.map((id) => new ObjectId90(id))),
37841
+ new ObjectId90(site)
37842
+ ]);
37441
37843
  const totalRequired = quantity * convertedUnits.length;
37442
37844
  const availableCards = await collection().find({
37443
37845
  assignedUnit: null,
@@ -37457,16 +37859,18 @@ function UseAccessManagementRepo() {
37457
37859
  message: `Insufficient ${type} access cards. Need ${totalRequired}, but only ${availableCards.length} available.`
37458
37860
  };
37459
37861
  }
37460
- const bulkUpdates = availableCards.map((card, index) => ({
37461
- updateOne: {
37462
- filter: { _id: card._id },
37463
- update: {
37464
- $set: {
37465
- assignedUnit: convertedUnits[Math.floor(index / quantity)]
37862
+ const bulkUpdates = availableCards.map(
37863
+ (card, index) => ({
37864
+ updateOne: {
37865
+ filter: { _id: card._id },
37866
+ update: {
37867
+ $set: {
37868
+ assignedUnit: convertedUnits[Math.floor(index / quantity)]
37869
+ }
37466
37870
  }
37467
37871
  }
37468
- }
37469
- }));
37872
+ })
37873
+ );
37470
37874
  await collection().bulkWrite(bulkUpdates, { session });
37471
37875
  await session?.commitTransaction();
37472
37876
  return {
@@ -37487,7 +37891,18 @@ function UseAccessManagementRepo() {
37487
37891
  try {
37488
37892
  const { cardId, remarks } = params;
37489
37893
  const id = new ObjectId90(cardId);
37490
- const result = await collection().findOneAndUpdate({ _id: id }, { $set: { isActivated: false, updatedAt: /* @__PURE__ */ new Date(), remarks, requestDate: /* @__PURE__ */ new Date() } }, { returnDocument: "after" });
37894
+ const result = await collection().findOneAndUpdate(
37895
+ { _id: id },
37896
+ {
37897
+ $set: {
37898
+ isActivated: false,
37899
+ updatedAt: /* @__PURE__ */ new Date(),
37900
+ remarks,
37901
+ requestDate: /* @__PURE__ */ new Date()
37902
+ }
37903
+ },
37904
+ { returnDocument: "after" }
37905
+ );
37491
37906
  return result;
37492
37907
  } catch (error) {
37493
37908
  throw new Error(error.message);
@@ -37548,7 +37963,13 @@ function UseAccessManagementRepo() {
37548
37963
  const { site, payload } = params;
37549
37964
  const id = new ObjectId90(site);
37550
37965
  const highestCardNo = await collection().aggregate([
37551
- { $match: { site: id, type: "NFC" /* NFC */, userType: "Visitor/Resident" /* DEFAULT */ } },
37966
+ {
37967
+ $match: {
37968
+ site: id,
37969
+ type: "NFC" /* NFC */,
37970
+ userType: "Visitor/Resident" /* DEFAULT */
37971
+ }
37972
+ },
37552
37973
  {
37553
37974
  $addFields: {
37554
37975
  qrTagCardNoNumeric: { $toInt: "$qrTagCardNo" }
@@ -37568,14 +37989,19 @@ function UseAccessManagementRepo() {
37568
37989
  if (highestCardNo.length > 0) {
37569
37990
  start = highestCardNo[0].qrTagCardNoNumeric || 0;
37570
37991
  }
37571
- const nextCardNumbers = Array.from({ length: payload.length }, (_, i) => String(start + i + 1).padStart(5, "0"));
37992
+ const nextCardNumbers = Array.from(
37993
+ { length: payload.length },
37994
+ (_, i) => String(start + i + 1).padStart(5, "0")
37995
+ );
37572
37996
  const bulkOps = await Promise.all(
37573
37997
  payload.map(async (doc, index) => {
37574
37998
  const id2 = new ObjectId90(doc._id);
37575
37999
  return {
37576
38000
  updateOne: {
37577
38001
  filter: { _id: id2 },
37578
- update: { $set: { qrTag: doc.qrTag, qrTagCardNo: nextCardNumbers[index] } }
38002
+ update: {
38003
+ $set: { qrTag: doc.qrTag, qrTagCardNo: nextCardNumbers[index] }
38004
+ }
37579
38005
  }
37580
38006
  };
37581
38007
  })
@@ -37617,7 +38043,11 @@ function UseAccessManagementRepo() {
37617
38043
  {
37618
38044
  $addFields: {
37619
38045
  extractedCardNo: {
37620
- $substr: ["$cardNo", { $subtract: [{ $strLenCP: "$cardNo" }, 5] }, 5]
38046
+ $substr: [
38047
+ "$cardNo",
38048
+ { $subtract: [{ $strLenCP: "$cardNo" }, 5] },
38049
+ 5
38050
+ ]
37621
38051
  }
37622
38052
  }
37623
38053
  },
@@ -37655,7 +38085,11 @@ function UseAccessManagementRepo() {
37655
38085
  },
37656
38086
  {
37657
38087
  $facet: {
37658
- items: [{ $skip: page * limit }, { $limit: limit }, { $project: { cardNo: 1 } }],
38088
+ items: [
38089
+ { $skip: page * limit },
38090
+ { $limit: limit },
38091
+ { $project: { cardNo: 1 } }
38092
+ ],
37659
38093
  totalCounts: [{ $count: "count" }]
37660
38094
  }
37661
38095
  }
@@ -37666,7 +38100,9 @@ function UseAccessManagementRepo() {
37666
38100
  _id: unitId
37667
38101
  }
37668
38102
  },
37669
- { $project: { _id: 1, name: 1, buildingName: 1, block: 1, level: 1 } },
38103
+ {
38104
+ $project: { _id: 1, name: 1, buildingName: 1, block: 1, level: 1 }
38105
+ },
37670
38106
  {
37671
38107
  $lookup: {
37672
38108
  from: "building-levels",
@@ -37754,7 +38190,18 @@ function UseAccessManagementRepo() {
37754
38190
  items: [
37755
38191
  { $skip: 0 },
37756
38192
  { $limit: 1 },
37757
- { $project: { _id: -1, accessLevel: 1, accessGroup: 1, userType: 1, doorName: 1, liftName: 1, liftAccessLevel: 1, isLiftCard: 1 } }
38193
+ {
38194
+ $project: {
38195
+ _id: -1,
38196
+ accessLevel: 1,
38197
+ accessGroup: 1,
38198
+ userType: 1,
38199
+ doorName: 1,
38200
+ liftName: 1,
38201
+ liftAccessLevel: 1,
38202
+ isLiftCard: 1
38203
+ }
38204
+ }
37758
38205
  ]
37759
38206
  }
37760
38207
  }
@@ -37803,13 +38250,25 @@ function UseAccessManagementRepo() {
37803
38250
  cardsToAttach = [...cardsId];
37804
38251
  } else if (type === "NFC" /* NFC */) {
37805
38252
  if (nfcCards && nfcCards.length > 0) {
37806
- const objectIds = nfcCards.map((card) => new ObjectId90(card._id));
38253
+ const objectIds = nfcCards.map(
38254
+ (card) => new ObjectId90(card._id)
38255
+ );
37807
38256
  cards = await collection().find({ _id: { $in: objectIds } }).toArray();
37808
- const nfcList = objectIds.map((card) => ({ _id: card, status: "In use", updatedAt: /* @__PURE__ */ new Date() }));
38257
+ const nfcList = objectIds.map((card) => ({
38258
+ _id: card,
38259
+ status: "In use",
38260
+ updatedAt: /* @__PURE__ */ new Date()
38261
+ }));
37809
38262
  cardsToAttach = [...nfcList];
37810
38263
  }
37811
38264
  }
37812
- const result = await collectionName("visitor.transactions").findOneAndUpdate({ _id: visitorId }, { $push: { cards: cardsToAttach } }, { session, returnDocument: "after" });
38265
+ const result = await collectionName(
38266
+ "visitor.transactions"
38267
+ ).findOneAndUpdate(
38268
+ { _id: visitorId },
38269
+ { $push: { cards: cardsToAttach } },
38270
+ { session, returnDocument: "after" }
38271
+ );
37813
38272
  const updatedVisitor = result?._id;
37814
38273
  const assignCards = cards.map((card) => card._id);
37815
38274
  if (assignCards.length > 0) {
@@ -37865,10 +38324,18 @@ function UseAccessManagementRepo() {
37865
38324
  liftAccessEndDate: formatEntryPassDate(item.liftAccessEndDate) || "19770510",
37866
38325
  accessGroup: ag
37867
38326
  };
37868
- return readTemplate(`${item.accessLevel !== null ? "add-card" : "add-card-lift"}`, { ...command });
38327
+ return readTemplate(
38328
+ `${item.accessLevel !== null ? "add-card" : "add-card-lift"}`,
38329
+ { ...command }
38330
+ );
37869
38331
  }).flat();
37870
- const response = await sendCommand(commands.join("").toString(), acm_url);
37871
- serverResult = await parseStringPromise2(response, { explicitArray: false });
38332
+ const response = await sendCommand(
38333
+ commands.join("").toString(),
38334
+ acm_url
38335
+ );
38336
+ serverResult = await parseStringPromise2(response, {
38337
+ explicitArray: false
38338
+ });
37872
38339
  if (result && serverResult.RESULT.$.STCODE !== "0") {
37873
38340
  throw new Error("Command failed, server error.");
37874
38341
  }
@@ -37917,7 +38384,10 @@ function UseAccessManagementRepo() {
37917
38384
  try {
37918
38385
  await session?.startTransaction();
37919
38386
  const userId = new ObjectId90(params.userId);
37920
- const result = await collection().updateMany({ userId }, { $set: { userId: null, status: "Available", updatedAt: /* @__PURE__ */ new Date() } });
38387
+ const result = await collection().updateMany(
38388
+ { userId },
38389
+ { $set: { userId: null, status: "Available", updatedAt: /* @__PURE__ */ new Date() } }
38390
+ );
37921
38391
  await session?.commitTransaction();
37922
38392
  return result;
37923
38393
  } catch (error) {
@@ -37961,7 +38431,15 @@ function UseAccessManagementRepo() {
37961
38431
  foreignField: "level",
37962
38432
  pipeline: [
37963
38433
  { $match: { status: { $ne: "deleted" } } },
37964
- { $project: { _id: 1, name: 1, buildingName: 1, level: 1, block: 1 } }
38434
+ {
38435
+ $project: {
38436
+ _id: 1,
38437
+ name: 1,
38438
+ buildingName: 1,
38439
+ level: 1,
38440
+ block: 1
38441
+ }
38442
+ }
37965
38443
  ],
37966
38444
  as: "units"
37967
38445
  }
@@ -37982,11 +38460,20 @@ function UseAccessManagementRepo() {
37982
38460
  throw new Error(error.message);
37983
38461
  }
37984
38462
  }
37985
- async function getTransactionsRepo({ page = 1, limit = 10, site, cardNo, url }) {
38463
+ async function getTransactionsRepo({
38464
+ page = 1,
38465
+ limit = 10,
38466
+ site,
38467
+ cardNo,
38468
+ url
38469
+ }) {
37986
38470
  page = page ? page - 1 : 0;
37987
38471
  site = new ObjectId90(site);
37988
38472
  try {
37989
- let index = await collectionName("access-card-transactions").findOne({}, { sort: { index: -1 } });
38473
+ let index = await collectionName("access-card-transactions").findOne(
38474
+ {},
38475
+ { sort: { index: -1 } }
38476
+ );
37990
38477
  index = index ? index.index : 0;
37991
38478
  const response = await getTransactions(index, url);
37992
38479
  if (response && Array.isArray(response.items) && response.items.length > 0) {
@@ -37995,7 +38482,9 @@ function UseAccessManagementRepo() {
37995
38482
  data: JSON.parse(item.data),
37996
38483
  timestamp: item.timestamp
37997
38484
  }));
37998
- result2 = result2.filter((item) => item.data.Event.ETYPE === "0" && item.data.Event.CARDNO !== "");
38485
+ result2 = result2.filter(
38486
+ (item) => item.data.Event.ETYPE === "0" && item.data.Event.CARDNO !== ""
38487
+ );
37999
38488
  if (result2.length > 0) {
38000
38489
  const transactions = result2.map(
38001
38490
  (item) => new MAccessCardTransaction({
@@ -38006,11 +38495,16 @@ function UseAccessManagementRepo() {
38006
38495
  accessType: item.data.Event.DEVNAME,
38007
38496
  accessStatus: item.data.Event.TRCODE,
38008
38497
  description: item.data.Event.TRDESC,
38009
- accessTime: entryPassDate(item.data.Event.TRDATE, item.data.Event.TRTIME),
38498
+ accessTime: entryPassDate(
38499
+ item.data.Event.TRDATE,
38500
+ item.data.Event.TRTIME
38501
+ ),
38010
38502
  createdAt: /* @__PURE__ */ new Date()
38011
38503
  })
38012
38504
  );
38013
- await collectionName("access-card-transactions").insertMany(transactions);
38505
+ await collectionName("access-card-transactions").insertMany(
38506
+ transactions
38507
+ );
38014
38508
  }
38015
38509
  }
38016
38510
  const result = await collectionName("access-card-transactions").aggregate([
@@ -38081,7 +38575,11 @@ function UseAccessManagementRepo() {
38081
38575
  {
38082
38576
  $facet: {
38083
38577
  totalCount: [{ $count: "count" }],
38084
- items: [{ $sort: { _id: -1 } }, { $skip: page * limit }, { $limit: limit }]
38578
+ items: [
38579
+ { $sort: { _id: -1 } },
38580
+ { $skip: page * limit },
38581
+ { $limit: limit }
38582
+ ]
38085
38583
  }
38086
38584
  }
38087
38585
  ]).toArray();
@@ -38104,7 +38602,9 @@ function UseAccessManagementRepo() {
38104
38602
  if (assignees.length < 1) {
38105
38603
  throw new Error("No user to Assign.");
38106
38604
  }
38107
- assignees = assignees.map((data) => new ObjectId90(data));
38605
+ assignees = assignees.map(
38606
+ (data) => new ObjectId90(data)
38607
+ );
38108
38608
  unit = new ObjectId90(unit);
38109
38609
  let availableCards = [];
38110
38610
  let update = [];
@@ -38114,7 +38614,18 @@ function UseAccessManagementRepo() {
38114
38614
  $match: {
38115
38615
  $expr: {
38116
38616
  $and: [
38117
- { $eq: ["$assignedUnit", unit] },
38617
+ {
38618
+ $in: [
38619
+ unit,
38620
+ {
38621
+ $cond: [
38622
+ { $isArray: "$assignedUnit" },
38623
+ "$assignedUnit",
38624
+ ["$assignedUnit"]
38625
+ ]
38626
+ }
38627
+ ]
38628
+ },
38118
38629
  { $eq: ["$userId", null] },
38119
38630
  { $eq: ["$type", type] },
38120
38631
  { $eq: ["$isActivated", true] }
@@ -38131,7 +38642,10 @@ function UseAccessManagementRepo() {
38131
38642
  card.staffNo = userId.toString().slice(-10);
38132
38643
  return card;
38133
38644
  });
38134
- update = availableCards.slice(0, assignees.length).map((card, index) => ({ _id: card._id, userId: new ObjectId90(assignees[index]) }));
38645
+ update = availableCards.slice(0, assignees.length).map((card, index) => ({
38646
+ _id: card._id,
38647
+ userId: new ObjectId90(assignees[index])
38648
+ }));
38135
38649
  const commands = cards.map((item, index) => {
38136
38650
  let ag = null;
38137
38651
  if (item.accessGroup !== void 0) {
@@ -38161,16 +38675,27 @@ function UseAccessManagementRepo() {
38161
38675
  liftAccessEndDate: formatEntryPassDate(item.liftAccessEndDate) || "19770510",
38162
38676
  accessGroup: ag
38163
38677
  };
38164
- return readTemplate(`${item.accessLevel !== null ? "add-card" : "add-card-lift"}`, { ...command });
38678
+ return readTemplate(
38679
+ `${item.accessLevel !== null ? "add-card" : "add-card-lift"}`,
38680
+ { ...command }
38681
+ );
38165
38682
  }).flat();
38166
38683
  const response = await sendCommand(commands.join("").toString(), acm_url);
38167
- const result = await parseStringPromise2(response, { explicitArray: false });
38684
+ const result = await parseStringPromise2(response, {
38685
+ explicitArray: false
38686
+ });
38168
38687
  console.log("status code", result.RESULT.$.STCODE);
38169
38688
  if (result && result.RESULT.$.STCODE !== "0") {
38170
38689
  throw new Error("Command failed, server error.");
38171
38690
  }
38172
38691
  for (const { _id, userId } of update) {
38173
- await collection().updateOne({ _id }, { $set: { userId, staffNo: `STAFF-${userId.toString().slice(-10)}` } }, { session });
38692
+ await collection().updateOne(
38693
+ { _id },
38694
+ {
38695
+ $set: { userId, staffNo: `STAFF-${userId.toString().slice(-10)}` }
38696
+ },
38697
+ { session }
38698
+ );
38174
38699
  }
38175
38700
  await session?.commitTransaction();
38176
38701
  return "Cards assigned successfully.";
@@ -38186,7 +38711,11 @@ function UseAccessManagementRepo() {
38186
38711
  try {
38187
38712
  session?.startTransaction();
38188
38713
  const id = new ObjectId90(userId);
38189
- await collection().updateMany({ userId: id }, { $set: { userId: null, status: "Available" } }, { session });
38714
+ await collection().updateMany(
38715
+ { userId: id },
38716
+ { $set: { userId: null, status: "Available" } },
38717
+ { session }
38718
+ );
38190
38719
  session?.commitTransaction();
38191
38720
  return "Successful Checkout";
38192
38721
  } catch (error) {
@@ -38196,7 +38725,11 @@ function UseAccessManagementRepo() {
38196
38725
  await session?.endSession();
38197
38726
  }
38198
38727
  }
38199
- async function uploadTemplateRepo({ site, id, name }) {
38728
+ async function uploadTemplateRepo({
38729
+ site,
38730
+ id,
38731
+ name
38732
+ }) {
38200
38733
  site = new ObjectId90(site);
38201
38734
  id = new ObjectId90(id);
38202
38735
  try {
@@ -38209,6 +38742,46 @@ function UseAccessManagementRepo() {
38209
38742
  throw new Error(error.message);
38210
38743
  }
38211
38744
  }
38745
+ async function getResidentsRepo({
38746
+ orgId,
38747
+ siteId,
38748
+ unitId
38749
+ }) {
38750
+ try {
38751
+ orgId = new ObjectId90(orgId);
38752
+ siteId = new ObjectId90(siteId);
38753
+ unitId = new ObjectId90(unitId);
38754
+ const result = await collectionName("users").aggregate([
38755
+ {
38756
+ $match: {
38757
+ $expr: {
38758
+ $and: [
38759
+ { $eq: ["$defaultOrg", orgId] },
38760
+ { $eq: ["$site", siteId] },
38761
+ { $eq: ["$unitId", unitId] }
38762
+ ]
38763
+ }
38764
+ }
38765
+ },
38766
+ {
38767
+ $project: {
38768
+ _id: 1,
38769
+ email: 1,
38770
+ unitName: 1,
38771
+ type: 1,
38772
+ status: 1,
38773
+ name: 1,
38774
+ defaultOrg: 1,
38775
+ site: 1,
38776
+ unitId: 1
38777
+ }
38778
+ }
38779
+ ]).toArray();
38780
+ return result;
38781
+ } catch (error) {
38782
+ throw new Error(error.message);
38783
+ }
38784
+ }
38212
38785
  return {
38213
38786
  createIndexes,
38214
38787
  createIndexForEntrypass,
@@ -38244,7 +38817,8 @@ function UseAccessManagementRepo() {
38244
38817
  getTransactionsRepo,
38245
38818
  assignMultipleCardsRepo,
38246
38819
  visitorCheckoutRepo,
38247
- uploadTemplateRepo
38820
+ uploadTemplateRepo,
38821
+ getResidentsRepo
38248
38822
  };
38249
38823
  }
38250
38824
 
@@ -38288,7 +38862,8 @@ function useAccessManagementSvc() {
38288
38862
  getTransactionsRepo,
38289
38863
  assignMultipleCardsRepo,
38290
38864
  visitorCheckoutRepo,
38291
- uploadTemplateRepo
38865
+ uploadTemplateRepo,
38866
+ getResidentsRepo
38292
38867
  } = UseAccessManagementRepo();
38293
38868
  const addPhysicalCardSvc = async (payload) => {
38294
38869
  try {
@@ -38580,17 +39155,39 @@ function useAccessManagementSvc() {
38580
39155
  throw new Error(err.message);
38581
39156
  }
38582
39157
  };
38583
- const getTransactionsSvc = async ({ page, limit, site, cardNo, url }) => {
39158
+ const getTransactionsSvc = async ({
39159
+ page,
39160
+ limit,
39161
+ site,
39162
+ cardNo,
39163
+ url
39164
+ }) => {
38584
39165
  try {
38585
- const response = await getTransactionsRepo({ page, limit, site, cardNo, url });
39166
+ const response = await getTransactionsRepo({
39167
+ page,
39168
+ limit,
39169
+ site,
39170
+ cardNo,
39171
+ url
39172
+ });
38586
39173
  return response;
38587
39174
  } catch (err) {
38588
39175
  throw new Error(err.message);
38589
39176
  }
38590
39177
  };
38591
- const assignMultipleCardsSvc = async ({ assignees, unit, type, acm_url }) => {
39178
+ const assignMultipleCardsSvc = async ({
39179
+ assignees,
39180
+ unit,
39181
+ type,
39182
+ acm_url
39183
+ }) => {
38592
39184
  try {
38593
- const response = await assignMultipleCardsRepo({ assignees, unit, type, acm_url });
39185
+ const response = await assignMultipleCardsRepo({
39186
+ assignees,
39187
+ unit,
39188
+ type,
39189
+ acm_url
39190
+ });
38594
39191
  return response;
38595
39192
  } catch (err) {
38596
39193
  throw new Error(err.message);
@@ -38604,7 +39201,11 @@ function useAccessManagementSvc() {
38604
39201
  throw new Error(err.message);
38605
39202
  }
38606
39203
  };
38607
- const uploadTemplateSvc = async ({ site, id, name }) => {
39204
+ const uploadTemplateSvc = async ({
39205
+ site,
39206
+ id,
39207
+ name
39208
+ }) => {
38608
39209
  try {
38609
39210
  const response = await uploadTemplateRepo({ site, id, name });
38610
39211
  return response;
@@ -38612,6 +39213,18 @@ function useAccessManagementSvc() {
38612
39213
  throw new Error(err.message);
38613
39214
  }
38614
39215
  };
39216
+ const getResidentsSvc = async ({
39217
+ orgId,
39218
+ siteId,
39219
+ unitId
39220
+ }) => {
39221
+ try {
39222
+ const response = await getResidentsRepo({ orgId, siteId, unitId });
39223
+ return response;
39224
+ } catch (err) {
39225
+ throw new Error(err.message);
39226
+ }
39227
+ };
38615
39228
  return {
38616
39229
  addPhysicalCardSvc,
38617
39230
  addNonPhysicalCardSvc,
@@ -38650,7 +39263,8 @@ function useAccessManagementSvc() {
38650
39263
  getTransactionsSvc,
38651
39264
  assignMultipleCardsSvc,
38652
39265
  visitorCheckoutSvc,
38653
- uploadTemplateSvc
39266
+ uploadTemplateSvc,
39267
+ getResidentsSvc
38654
39268
  };
38655
39269
  }
38656
39270
 
@@ -38694,7 +39308,8 @@ function useAccessManagementController() {
38694
39308
  getTransactionsSvc,
38695
39309
  assignMultipleCardsSvc,
38696
39310
  visitorCheckoutSvc,
38697
- uploadTemplateSvc
39311
+ uploadTemplateSvc,
39312
+ getResidentsSvc
38698
39313
  } = useAccessManagementSvc();
38699
39314
  const addPhysicalCard = async (req, res) => {
38700
39315
  try {
@@ -38943,11 +39558,25 @@ function useAccessManagementController() {
38943
39558
  search: Joi86.string().optional().allow("", null),
38944
39559
  userType: Joi86.string().required()
38945
39560
  });
38946
- const { error } = schema2.validate({ page, limit, site, organization, search, userType });
39561
+ const { error } = schema2.validate({
39562
+ page,
39563
+ limit,
39564
+ site,
39565
+ organization,
39566
+ search,
39567
+ userType
39568
+ });
38947
39569
  if (error) {
38948
39570
  return res.status(400).json({ message: error.message });
38949
39571
  }
38950
- const result = await userTypeAccessCardsSvc({ page, limit, search, site, organization, userType });
39572
+ const result = await userTypeAccessCardsSvc({
39573
+ page,
39574
+ limit,
39575
+ search,
39576
+ site,
39577
+ organization,
39578
+ userType
39579
+ });
38951
39580
  return res.status(200).json({ message: "Success", data: result });
38952
39581
  } catch (error) {
38953
39582
  return res.status(500).json({
@@ -38958,7 +39587,12 @@ function useAccessManagementController() {
38958
39587
  };
38959
39588
  const assignedAccessCards = async (req, res) => {
38960
39589
  try {
38961
- const { site, userType, type, search = "" } = req.query;
39590
+ const {
39591
+ site,
39592
+ userType,
39593
+ type,
39594
+ search = ""
39595
+ } = req.query;
38962
39596
  const schema2 = Joi86.object({
38963
39597
  site: Joi86.string().hex().required(),
38964
39598
  userType: Joi86.string().required(),
@@ -38969,7 +39603,12 @@ function useAccessManagementController() {
38969
39603
  if (error) {
38970
39604
  return res.status(400).json({ message: error.message });
38971
39605
  }
38972
- const result = await assignedAccessCardsSvc({ site, userType, type, search });
39606
+ const result = await assignedAccessCardsSvc({
39607
+ site,
39608
+ userType,
39609
+ type,
39610
+ search
39611
+ });
38973
39612
  return res.status(200).json({ message: "Success", data: result });
38974
39613
  } catch (error) {
38975
39614
  return res.status(500).json({
@@ -39015,11 +39654,23 @@ function useAccessManagementController() {
39015
39654
  userType: Joi86.string().valid(...Object.values(EAccessCardUserTypes)).required(),
39016
39655
  type: Joi86.string().valid(...Object.values(EAccessCardTypes)).required()
39017
39656
  });
39018
- const { error } = schema2.validate({ accessLevel, liftAccessLevel, site, userType, type });
39657
+ const { error } = schema2.validate({
39658
+ accessLevel,
39659
+ liftAccessLevel,
39660
+ site,
39661
+ userType,
39662
+ type
39663
+ });
39019
39664
  if (error) {
39020
39665
  return res.status(400).json({ message: error.message });
39021
39666
  }
39022
- const result = await accessandLiftCardsSvc({ accessLevel, liftAccessLevel, site, userType, type });
39667
+ const result = await accessandLiftCardsSvc({
39668
+ accessLevel,
39669
+ liftAccessLevel,
39670
+ site,
39671
+ userType,
39672
+ type
39673
+ });
39023
39674
  return res.status(200).json({ message: "Success", data: result });
39024
39675
  } catch (error) {
39025
39676
  return res.status(500).json({
@@ -39106,11 +39757,23 @@ function useAccessManagementController() {
39106
39757
  issuedCardId: Joi86.string().required(),
39107
39758
  userId: Joi86.string().hex().required()
39108
39759
  });
39109
- const { error } = schema2.validate({ cardId, remarks, unitId, issuedCardId, userId });
39760
+ const { error } = schema2.validate({
39761
+ cardId,
39762
+ remarks,
39763
+ unitId,
39764
+ issuedCardId,
39765
+ userId
39766
+ });
39110
39767
  if (error) {
39111
39768
  return res.status(400).json({ message: error.message });
39112
39769
  }
39113
- const result = await cardReplacementSvc({ cardId, remarks, unitId, issuedCardId, userId });
39770
+ const result = await cardReplacementSvc({
39771
+ cardId,
39772
+ remarks,
39773
+ unitId,
39774
+ issuedCardId,
39775
+ userId
39776
+ });
39114
39777
  return res.status(200).json({ message: "Success", data: result });
39115
39778
  } catch (error) {
39116
39779
  return res.status(500).json({
@@ -39139,7 +39802,13 @@ function useAccessManagementController() {
39139
39802
  if (error) {
39140
39803
  return res.status(400).json({ message: error.message });
39141
39804
  }
39142
- const result = await visitorAccessCardsSvc({ site, page, limit, type, search });
39805
+ const result = await visitorAccessCardsSvc({
39806
+ site,
39807
+ page,
39808
+ limit,
39809
+ type,
39810
+ search
39811
+ });
39143
39812
  return res.status(200).json({ message: "Success", data: result });
39144
39813
  } catch (error) {
39145
39814
  return res.status(500).json({
@@ -39168,11 +39837,27 @@ function useAccessManagementController() {
39168
39837
  limit: Joi86.number().optional().default(10),
39169
39838
  site: Joi86.string().hex().required()
39170
39839
  });
39171
- const { error } = schema2.validate({ search, statusFilter, dateFrom, dateTo, page, limit, site });
39840
+ const { error } = schema2.validate({
39841
+ search,
39842
+ statusFilter,
39843
+ dateFrom,
39844
+ dateTo,
39845
+ page,
39846
+ limit,
39847
+ site
39848
+ });
39172
39849
  if (error) {
39173
39850
  return res.status(400).json({ message: error.message });
39174
39851
  }
39175
- const result = await getCardReplacementSvc({ site, page, limit, search, statusFilter, dateFrom, dateTo });
39852
+ const result = await getCardReplacementSvc({
39853
+ site,
39854
+ page,
39855
+ limit,
39856
+ search,
39857
+ statusFilter,
39858
+ dateFrom,
39859
+ dateTo
39860
+ });
39176
39861
  return res.status(200).json({ message: "Success", data: result });
39177
39862
  } catch (error) {
39178
39863
  return res.status(500).json({
@@ -39218,7 +39903,15 @@ function useAccessManagementController() {
39218
39903
  };
39219
39904
  const assignAccessCardToUnit = async (req, res) => {
39220
39905
  try {
39221
- const { units, type, quantity, site, userType, accessLevel, liftAccessLevel } = req.body;
39906
+ const {
39907
+ units,
39908
+ type,
39909
+ quantity,
39910
+ site,
39911
+ userType,
39912
+ accessLevel,
39913
+ liftAccessLevel
39914
+ } = req.body;
39222
39915
  const schema2 = Joi86.object({
39223
39916
  units: Joi86.array().items(Joi86.string().hex()).required(),
39224
39917
  quantity: Joi86.number().required(),
@@ -39228,11 +39921,27 @@ function useAccessManagementController() {
39228
39921
  accessLevel: Joi86.string().optional().allow("", null),
39229
39922
  liftAccessLevel: Joi86.string().optional().allow("", null)
39230
39923
  });
39231
- const { error } = schema2.validate({ units, quantity, type, site, userType, accessLevel, liftAccessLevel });
39924
+ const { error } = schema2.validate({
39925
+ units,
39926
+ quantity,
39927
+ type,
39928
+ site,
39929
+ userType,
39930
+ accessLevel,
39931
+ liftAccessLevel
39932
+ });
39232
39933
  if (error) {
39233
39934
  return res.status(400).json({ message: error.message });
39234
39935
  }
39235
- const result = await assignAccessCardToUnitSvc({ units, quantity, type, site, userType, accessLevel, liftAccessLevel });
39936
+ const result = await assignAccessCardToUnitSvc({
39937
+ units,
39938
+ quantity,
39939
+ type,
39940
+ site,
39941
+ userType,
39942
+ accessLevel,
39943
+ liftAccessLevel
39944
+ });
39236
39945
  return res.status(200).json({ message: "Success", data: result });
39237
39946
  } catch (error) {
39238
39947
  return res.status(500).json({
@@ -39330,7 +40039,12 @@ function useAccessManagementController() {
39330
40039
  };
39331
40040
  const availableCardContractors = async (req, res) => {
39332
40041
  try {
39333
- const { siteId, unitId, page = 1, limit = 20 } = req.query;
40042
+ const {
40043
+ siteId,
40044
+ unitId,
40045
+ page = 1,
40046
+ limit = 20
40047
+ } = req.query;
39334
40048
  const type = req.params.type;
39335
40049
  const schema2 = Joi86.object({
39336
40050
  siteId: Joi86.string().hex().required(),
@@ -39343,7 +40057,13 @@ function useAccessManagementController() {
39343
40057
  if (error) {
39344
40058
  return res.status(400).json({ message: error.message });
39345
40059
  }
39346
- const result = await availableCardContractorsSvc({ siteId, unitId, page, limit, type });
40060
+ const result = await availableCardContractorsSvc({
40061
+ siteId,
40062
+ unitId,
40063
+ page,
40064
+ limit,
40065
+ type
40066
+ });
39347
40067
  return res.status(200).json({ message: "Success", data: result });
39348
40068
  } catch (error) {
39349
40069
  return res.status(500).json({
@@ -39354,7 +40074,11 @@ function useAccessManagementController() {
39354
40074
  };
39355
40075
  const vmsgenerateQrCodes = async (req, res) => {
39356
40076
  try {
39357
- const { site, unitId, quantity = 100 } = req.body;
40077
+ const {
40078
+ site,
40079
+ unitId,
40080
+ quantity = 100
40081
+ } = req.body;
39358
40082
  const schema2 = Joi86.object({
39359
40083
  site: Joi86.string().hex().length(24).required(),
39360
40084
  unitId: Joi86.string().hex().length(24).required(),
@@ -39365,7 +40089,12 @@ function useAccessManagementController() {
39365
40089
  return res.status(400).json({ message: error.message });
39366
40090
  }
39367
40091
  const normalizedUnitId = [unitId];
39368
- const result = await vmsgenerateQrCodesSvc({ site, unitId, normalizedUnitId, quantity });
40092
+ const result = await vmsgenerateQrCodesSvc({
40093
+ site,
40094
+ unitId,
40095
+ normalizedUnitId,
40096
+ quantity
40097
+ });
39369
40098
  return res.status(200).json({ message: "Success", data: result });
39370
40099
  } catch (error) {
39371
40100
  return res.status(500).json({
@@ -39376,21 +40105,50 @@ function useAccessManagementController() {
39376
40105
  };
39377
40106
  const addVisitorAccessCard = async (req, res) => {
39378
40107
  try {
39379
- const { site, unitId, quantity = 1, type, nfcCards, visitorId, acm_url } = req.body;
40108
+ const {
40109
+ site,
40110
+ unitId,
40111
+ quantity = 1,
40112
+ type,
40113
+ nfcCards,
40114
+ visitorId,
40115
+ acm_url
40116
+ } = req.body;
39380
40117
  const schema2 = Joi86.object({
39381
40118
  site: Joi86.string().hex().length(24).required(),
39382
40119
  unitId: Joi86.string().hex().length(24).required(),
39383
40120
  quantity: Joi86.number().allow(null, "").optional(),
39384
40121
  type: Joi86.string().required(),
39385
- nfcCards: Joi86.array().items(Joi86.object({ _id: Joi86.string().hex().required(), cardNo: Joi86.string().required() })).required(),
40122
+ nfcCards: Joi86.array().items(
40123
+ Joi86.object({
40124
+ _id: Joi86.string().hex().required(),
40125
+ cardNo: Joi86.string().required()
40126
+ })
40127
+ ).required(),
39386
40128
  acm_url: Joi86.string().required(),
39387
40129
  visitorId: Joi86.string().hex().length(24).required()
39388
40130
  });
39389
- const { error } = schema2.validate({ site, unitId, quantity, type, nfcCards, visitorId, acm_url });
40131
+ const { error } = schema2.validate({
40132
+ site,
40133
+ unitId,
40134
+ quantity,
40135
+ type,
40136
+ nfcCards,
40137
+ visitorId,
40138
+ acm_url
40139
+ });
39390
40140
  if (error) {
39391
40141
  return res.status(400).json({ message: error.message });
39392
40142
  }
39393
- const result = await addVisitorAccessCardSvc({ site, unitId, quantity, type, nfcCards, visitorId, acm_url });
40143
+ const result = await addVisitorAccessCardSvc({
40144
+ site,
40145
+ unitId,
40146
+ quantity,
40147
+ type,
40148
+ nfcCards,
40149
+ visitorId,
40150
+ acm_url
40151
+ });
39394
40152
  return res.status(200).json({ message: "Success", data: result });
39395
40153
  } catch (error) {
39396
40154
  return res.status(500).json({
@@ -39438,7 +40196,11 @@ function useAccessManagementController() {
39438
40196
  });
39439
40197
  }
39440
40198
  };
39441
- const removeAccessCard = async ({ cardNo, staffNo, url }) => {
40199
+ const removeAccessCard = async ({
40200
+ cardNo,
40201
+ staffNo,
40202
+ url
40203
+ }) => {
39442
40204
  return removeAccessGroup({ cardNo, staffNo, url });
39443
40205
  };
39444
40206
  const getBlockLevelAndUnitList = async (req, res) => {
@@ -39457,7 +40219,13 @@ function useAccessManagementController() {
39457
40219
  }
39458
40220
  };
39459
40221
  const getTransactions2 = async (req, res) => {
39460
- const { page = 1, limit = 10, site, cardNo, url } = req.query;
40222
+ const {
40223
+ page = 1,
40224
+ limit = 10,
40225
+ site,
40226
+ cardNo,
40227
+ url
40228
+ } = req.query;
39461
40229
  const schema2 = Joi86.object({
39462
40230
  page: Joi86.number().required(),
39463
40231
  limit: Joi86.number().optional().default(10),
@@ -39496,7 +40264,12 @@ function useAccessManagementController() {
39496
40264
  if (error) {
39497
40265
  throw new Error(`${error.message}`);
39498
40266
  }
39499
- const result = await assignMultipleCardsSvc({ assignees, unit, type, acm_url });
40267
+ const result = await assignMultipleCardsSvc({
40268
+ assignees,
40269
+ unit,
40270
+ type,
40271
+ acm_url
40272
+ });
39500
40273
  return res.status(200).json({ message: "Success", data: result });
39501
40274
  } catch (error) {
39502
40275
  return res.status(400).json({
@@ -39539,6 +40312,27 @@ function useAccessManagementController() {
39539
40312
  });
39540
40313
  }
39541
40314
  };
40315
+ const getResidents = async (req, res) => {
40316
+ try {
40317
+ const { orgId, siteId, unitId } = req.query;
40318
+ const schema2 = Joi86.object({
40319
+ orgId: Joi86.string().hex().required(),
40320
+ siteId: Joi86.string().hex().required(),
40321
+ unitId: Joi86.string().hex().required()
40322
+ });
40323
+ const { error } = schema2.validate({ orgId, siteId, unitId });
40324
+ if (error) {
40325
+ return res.status(400).json({ message: error.message });
40326
+ }
40327
+ const result = await getResidentsSvc({ orgId, siteId, unitId });
40328
+ return res.status(200).json({ data: result });
40329
+ } catch (error) {
40330
+ return res.status(400).json({
40331
+ data: null,
40332
+ message: error.message
40333
+ });
40334
+ }
40335
+ };
39542
40336
  return {
39543
40337
  addPhysicalCard,
39544
40338
  addNonPhysicalCard,
@@ -39575,7 +40369,8 @@ function useAccessManagementController() {
39575
40369
  getTransactions: getTransactions2,
39576
40370
  assignMultipleCards,
39577
40371
  visitorCheckout,
39578
- uploadTemplate
40372
+ uploadTemplate,
40373
+ getResidents
39579
40374
  };
39580
40375
  }
39581
40376
 
@@ -54279,6 +55074,213 @@ function usePostPrelovedController() {
54279
55074
  updateStatus
54280
55075
  };
54281
55076
  }
55077
+
55078
+ // src/models/online-forms-v2.model.ts
55079
+ import Joi134 from "joi";
55080
+ import { ObjectId as ObjectId131 } from "mongodb";
55081
+ var FormEntryStatus = /* @__PURE__ */ ((FormEntryStatus2) => {
55082
+ FormEntryStatus2["ACTIVE"] = "active";
55083
+ FormEntryStatus2["INACTIVE"] = "inactive";
55084
+ FormEntryStatus2["DELETED"] = "deleted";
55085
+ return FormEntryStatus2;
55086
+ })(FormEntryStatus || {});
55087
+ var schemaFormEntry = Joi134.object({
55088
+ _id: Joi134.string().hex().optional().allow("", null),
55089
+ formType: Joi134.string().required(),
55090
+ fields: Joi134.object().pattern(
55091
+ Joi134.string(),
55092
+ Joi134.alternatives().try(
55093
+ Joi134.string(),
55094
+ Joi134.number(),
55095
+ Joi134.boolean(),
55096
+ Joi134.valid(null)
55097
+ )
55098
+ ).required(),
55099
+ status: Joi134.string().optional().allow("", null),
55100
+ org: Joi134.string().hex().optional().allow("", null),
55101
+ site: Joi134.string().hex().optional().allow("", null),
55102
+ createdAt: Joi134.date().optional().allow("", null),
55103
+ updatedAt: Joi134.date().optional().allow("", null),
55104
+ deletedAt: Joi134.date().optional().allow("", null)
55105
+ });
55106
+ var schemaUpdateFormEntry = Joi134.object({
55107
+ _id: Joi134.string().hex().required(),
55108
+ formType: Joi134.string().optional().allow("", null),
55109
+ fields: Joi134.object().pattern(
55110
+ Joi134.string(),
55111
+ Joi134.alternatives().try(
55112
+ Joi134.string(),
55113
+ Joi134.number(),
55114
+ Joi134.boolean(),
55115
+ Joi134.valid(null)
55116
+ )
55117
+ ).optional(),
55118
+ status: Joi134.string().optional().allow("", null),
55119
+ createdAt: Joi134.date().optional().allow("", null),
55120
+ updatedAt: Joi134.date().optional().allow("", null),
55121
+ deletedAt: Joi134.date().optional().allow("", null)
55122
+ });
55123
+ function MFormEntry(value) {
55124
+ const { error } = schemaFormEntry.validate(value);
55125
+ if (error) {
55126
+ throw new Error(error.details[0].message);
55127
+ }
55128
+ if (value._id && typeof value._id === "string") {
55129
+ try {
55130
+ value._id = new ObjectId131(value._id);
55131
+ } catch {
55132
+ throw new Error("Invalid ID.");
55133
+ }
55134
+ }
55135
+ if (value.org && typeof value.org === "string") {
55136
+ try {
55137
+ value.org = new ObjectId131(value.org);
55138
+ } catch {
55139
+ throw new Error("Invalid org ID.");
55140
+ }
55141
+ }
55142
+ if (value.site && typeof value.site === "string") {
55143
+ try {
55144
+ value.site = new ObjectId131(value.site);
55145
+ } catch {
55146
+ throw new Error("Invalid site ID.");
55147
+ }
55148
+ }
55149
+ return {
55150
+ _id: value._id,
55151
+ formType: value.formType,
55152
+ fields: value.fields,
55153
+ status: value.status,
55154
+ org: value.org,
55155
+ site: value.site,
55156
+ createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
55157
+ updatedAt: value.updatedAt ?? null,
55158
+ deletedAt: value.deletedAt ?? null
55159
+ };
55160
+ }
55161
+
55162
+ // src/repositories/online-forms-v2.repository.ts
55163
+ import {
55164
+ BadRequestError as BadRequestError212,
55165
+ InternalServerError as InternalServerError75,
55166
+ logger as logger187,
55167
+ useAtlas as useAtlas118,
55168
+ useCache as useCache69
55169
+ } from "@7365admin1/node-server-utils";
55170
+ var online_forms_namespace_collection = "online-forms";
55171
+ function useFormEntryRepo() {
55172
+ const db = useAtlas118.getDb();
55173
+ if (!db) {
55174
+ throw new InternalServerError75("Unable to connect to server.");
55175
+ }
55176
+ const collection = db.collection(online_forms_namespace_collection);
55177
+ const { delNamespace, getCache, setCache } = useCache69(
55178
+ online_forms_namespace_collection
55179
+ );
55180
+ async function createTextIndex() {
55181
+ try {
55182
+ await collection.createIndex({
55183
+ name: "text"
55184
+ });
55185
+ } catch (error) {
55186
+ throw new InternalServerError75(
55187
+ "Failed to create text index on online form."
55188
+ );
55189
+ }
55190
+ }
55191
+ async function add(value, session) {
55192
+ try {
55193
+ value = MFormEntry(value);
55194
+ const res = await collection.insertOne(value, { session });
55195
+ delNamespace().then(() => {
55196
+ logger187.info(
55197
+ `Cache cleared for namespace: ${online_forms_namespace_collection}`
55198
+ );
55199
+ }).catch((err) => {
55200
+ logger187.error(
55201
+ `Failed to clear cache for namespace: ${online_forms_namespace_collection}`,
55202
+ err
55203
+ );
55204
+ });
55205
+ return res.insertedId;
55206
+ } catch (error) {
55207
+ const isDuplicated = error.message.includes("duplicate");
55208
+ if (isDuplicated) {
55209
+ throw new BadRequestError212("Online Form already exists.");
55210
+ }
55211
+ throw error;
55212
+ }
55213
+ }
55214
+ return {
55215
+ add,
55216
+ createTextIndex
55217
+ };
55218
+ }
55219
+
55220
+ // src/controllers/online-forms-v2.controller.ts
55221
+ import { BadRequestError as BadRequestError213, logger as logger188 } from "@7365admin1/node-server-utils";
55222
+ import ExcelJS3 from "exceljs";
55223
+ import fs5 from "fs";
55224
+ function useFormEntryController() {
55225
+ const { add: _add } = useFormEntryRepo();
55226
+ function toCamelCase(str) {
55227
+ return str.replace(/\s(.)/g, (_, char) => char.toUpperCase()).replace(/\s+/g, "").replace(/^(.)/, (_, char) => char.toLowerCase());
55228
+ }
55229
+ function normalizeKeys(obj) {
55230
+ const normalized = {};
55231
+ for (const [key, value] of Object.entries(obj)) {
55232
+ normalized[toCamelCase(key)] = value;
55233
+ }
55234
+ return normalized;
55235
+ }
55236
+ async function uploadFormEntrys(req, res, next) {
55237
+ try {
55238
+ if (!req.file) {
55239
+ next(new BadRequestError213("Excel file is required."));
55240
+ return;
55241
+ }
55242
+ const workbook = new ExcelJS3.Workbook();
55243
+ await workbook.xlsx.readFile(req.file.path);
55244
+ const worksheet = workbook.worksheets[0];
55245
+ if (!worksheet) {
55246
+ next(new BadRequestError213("No worksheet found in uploaded Excel file."));
55247
+ return;
55248
+ }
55249
+ const headerRow = worksheet.getRow(1);
55250
+ const headers = headerRow.values.slice(1).map((h) => String(h ?? "").trim());
55251
+ const fields = {};
55252
+ headers.forEach((header) => {
55253
+ fields[header] = null;
55254
+ });
55255
+ const formType = req.file.originalname.replace(/\.[^/.]+$/, "");
55256
+ const normalizedFields = normalizeKeys(fields);
55257
+ const payload = {
55258
+ formType,
55259
+ fields: normalizedFields,
55260
+ status: "active" /* ACTIVE */
55261
+ };
55262
+ const { error, value } = schemaFormEntry.validate(payload, {
55263
+ abortEarly: false
55264
+ });
55265
+ if (error) {
55266
+ const messages = error.details.map((d) => d.message).join(", ");
55267
+ logger188.log({ level: "error", message: messages });
55268
+ next(new BadRequestError213(messages));
55269
+ return;
55270
+ }
55271
+ const result = await _add(value);
55272
+ res.status(201).json(result);
55273
+ fs5.unlink(req.file.path, () => {
55274
+ });
55275
+ } catch (error) {
55276
+ logger188.log({ level: "error", message: error.message });
55277
+ next(error);
55278
+ }
55279
+ }
55280
+ return {
55281
+ uploadFormEntrys
55282
+ };
55283
+ }
54282
55284
  export {
54283
55285
  ANPRMode,
54284
55286
  AccessTypeProps,
@@ -54305,6 +55307,7 @@ export {
54305
55307
  EventType,
54306
55308
  FacilitySort,
54307
55309
  FacilityStatus,
55310
+ FormEntryStatus,
54308
55311
  GuestSort,
54309
55312
  GuestStatus,
54310
55313
  MAccessCard,
@@ -54326,6 +55329,7 @@ export {
54326
55329
  MEventManagement,
54327
55330
  MFeedback,
54328
55331
  MFile,
55332
+ MFormEntry,
54329
55333
  MGuestManagement,
54330
55334
  MIncidentReport,
54331
55335
  MManpowerDesignations,
@@ -54437,6 +55441,7 @@ export {
54437
55441
  nfcPatrolSettingsSchema,
54438
55442
  nfcPatrolSettingsSchemaUpdate,
54439
55443
  occurrence_book_namespace_collection,
55444
+ online_forms_namespace_collection,
54440
55445
  orgSchema,
54441
55446
  overnight_parking_requests_namespace_collection,
54442
55447
  parseDahuaFind,
@@ -54461,6 +55466,7 @@ export {
54461
55466
  schemaEntryPassSettings,
54462
55467
  schemaEventManagement,
54463
55468
  schemaFiles,
55469
+ schemaFormEntry,
54464
55470
  schemaGuestManagement,
54465
55471
  schemaIncidentReport,
54466
55472
  schemaNfcPatrolLog,
@@ -54491,6 +55497,7 @@ export {
54491
55497
  schemaUpdateDocumentManagement,
54492
55498
  schemaUpdateEntryPassSettings,
54493
55499
  schemaUpdateEventManagement,
55500
+ schemaUpdateFormEntry,
54494
55501
  schemaUpdateGuestManagement,
54495
55502
  schemaUpdateIncidentReport,
54496
55503
  schemaUpdateOccurrenceBook,
@@ -54574,6 +55581,8 @@ export {
54574
55581
  useFileController,
54575
55582
  useFileRepo,
54576
55583
  useFileService,
55584
+ useFormEntryController,
55585
+ useFormEntryRepo,
54577
55586
  useGuestManagementController,
54578
55587
  useGuestManagementRepo,
54579
55588
  useGuestManagementService,