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