@7365admin1/core 2.12.0 → 2.14.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 +12 -0
- package/dist/index.d.ts +135 -18
- package/dist/index.js +2005 -841
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1386 -222
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -3
package/dist/index.mjs
CHANGED
|
@@ -4759,7 +4759,8 @@ function useMemberRepo() {
|
|
|
4759
4759
|
try {
|
|
4760
4760
|
const data = await collection.find({
|
|
4761
4761
|
role: { $in: roles },
|
|
4762
|
-
type,
|
|
4762
|
+
// type,
|
|
4763
|
+
// ...(type && { type }),
|
|
4763
4764
|
status: "active"
|
|
4764
4765
|
}).toArray();
|
|
4765
4766
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
@@ -6880,7 +6881,7 @@ function useMemberService() {
|
|
|
6880
6881
|
throw new BadRequestError29("No owner role found.");
|
|
6881
6882
|
}
|
|
6882
6883
|
const roles = owner.map((r) => r._id?.toString() ?? "");
|
|
6883
|
-
const ownerMembers = await getByRoles(roles, type);
|
|
6884
|
+
const ownerMembers = await getByRoles(roles, type = "");
|
|
6884
6885
|
if (!ownerMembers.length) {
|
|
6885
6886
|
throw new BadRequestError29("No owner members found.");
|
|
6886
6887
|
}
|
|
@@ -14674,7 +14675,7 @@ function MPerson(value) {
|
|
|
14674
14675
|
return {
|
|
14675
14676
|
_id: value._id,
|
|
14676
14677
|
name: value.name,
|
|
14677
|
-
contact: value.contact,
|
|
14678
|
+
contact: value.contact ?? "",
|
|
14678
14679
|
block: value.block,
|
|
14679
14680
|
level: value.level,
|
|
14680
14681
|
unit: value.unit,
|
|
@@ -15136,7 +15137,8 @@ function usePersonRepo() {
|
|
|
15136
15137
|
$or: [
|
|
15137
15138
|
{ name: { $regex: search, $options: "i" } },
|
|
15138
15139
|
{ email: { $regex: search, $options: "i" } },
|
|
15139
|
-
{ nric: { $regex: search, $options: "i" } }
|
|
15140
|
+
{ nric: { $regex: search, $options: "i" } },
|
|
15141
|
+
{ "plates.plateNumber": { $regex: search, $options: "i" } }
|
|
15140
15142
|
]
|
|
15141
15143
|
},
|
|
15142
15144
|
...ObjectId44.isValid(org) && { org: new ObjectId44(org) },
|
|
@@ -18561,7 +18563,7 @@ function useVisitorTransactionService() {
|
|
|
18561
18563
|
} else {
|
|
18562
18564
|
const payload = {
|
|
18563
18565
|
name: value.name || "",
|
|
18564
|
-
contact: value.contact,
|
|
18566
|
+
contact: value.contact ?? "",
|
|
18565
18567
|
nric,
|
|
18566
18568
|
type: value.type,
|
|
18567
18569
|
companyName: value.company ? [value.company] : [],
|
|
@@ -20151,7 +20153,10 @@ function usePatrolQuestionRepo() {
|
|
|
20151
20153
|
const query = {
|
|
20152
20154
|
status,
|
|
20153
20155
|
...search && {
|
|
20154
|
-
$or: [
|
|
20156
|
+
$or: [
|
|
20157
|
+
{ question: { $regex: search, $options: "i" } },
|
|
20158
|
+
{ answers: { $regex: search, $options: "i" } }
|
|
20159
|
+
]
|
|
20155
20160
|
},
|
|
20156
20161
|
...ObjectId58.isValid(site) && { site: new ObjectId58(site) }
|
|
20157
20162
|
};
|
|
@@ -20579,9 +20584,6 @@ function usePatrolRouteRepo() {
|
|
|
20579
20584
|
page = page > 0 ? page - 1 : 0;
|
|
20580
20585
|
const query = {
|
|
20581
20586
|
status,
|
|
20582
|
-
...search && {
|
|
20583
|
-
$or: [{ name: { $regex: search, $options: "i" } }]
|
|
20584
|
-
},
|
|
20585
20587
|
...ObjectId60.isValid(site) && { site: new ObjectId60(site) }
|
|
20586
20588
|
};
|
|
20587
20589
|
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
@@ -20601,14 +20603,57 @@ function usePatrolRouteRepo() {
|
|
|
20601
20603
|
}
|
|
20602
20604
|
try {
|
|
20603
20605
|
const basePipeline = [
|
|
20604
|
-
{
|
|
20606
|
+
{
|
|
20607
|
+
$lookup: {
|
|
20608
|
+
from: "members",
|
|
20609
|
+
localField: "assignee",
|
|
20610
|
+
foreignField: "_id",
|
|
20611
|
+
as: "assigneeData"
|
|
20612
|
+
}
|
|
20613
|
+
},
|
|
20614
|
+
{
|
|
20615
|
+
$match: {
|
|
20616
|
+
...query,
|
|
20617
|
+
...search && {
|
|
20618
|
+
$or: [
|
|
20619
|
+
{ name: { $regex: search, $options: "i" } },
|
|
20620
|
+
{ "assigneeData.name": { $regex: search, $options: "i" } },
|
|
20621
|
+
{ start: { $regex: search, $options: "i" } },
|
|
20622
|
+
{ end: { $regex: search, $options: "i" } }
|
|
20623
|
+
]
|
|
20624
|
+
}
|
|
20625
|
+
}
|
|
20626
|
+
},
|
|
20605
20627
|
{ $sort: sort },
|
|
20606
20628
|
{ $skip: page * limit },
|
|
20607
20629
|
{ $limit: limit }
|
|
20608
20630
|
];
|
|
20631
|
+
const countPipeline = [
|
|
20632
|
+
{
|
|
20633
|
+
$lookup: {
|
|
20634
|
+
from: "members",
|
|
20635
|
+
localField: "assignee",
|
|
20636
|
+
foreignField: "_id",
|
|
20637
|
+
as: "assigneeData"
|
|
20638
|
+
}
|
|
20639
|
+
},
|
|
20640
|
+
{
|
|
20641
|
+
$match: {
|
|
20642
|
+
...query,
|
|
20643
|
+
...search && {
|
|
20644
|
+
$or: [
|
|
20645
|
+
{ name: { $regex: search, $options: "i" } },
|
|
20646
|
+
{ "assigneeData.name": { $regex: search, $options: "i" } },
|
|
20647
|
+
{ start: { $regex: search, $options: "i" } },
|
|
20648
|
+
{ end: { $regex: search, $options: "i" } }
|
|
20649
|
+
]
|
|
20650
|
+
}
|
|
20651
|
+
}
|
|
20652
|
+
}
|
|
20653
|
+
];
|
|
20609
20654
|
const [items, countResult] = await Promise.all([
|
|
20610
20655
|
collection.aggregate(basePipeline, { session }).toArray(),
|
|
20611
|
-
collection.aggregate([
|
|
20656
|
+
collection.aggregate([...countPipeline, { $count: "total" }], { session }).toArray()
|
|
20612
20657
|
]);
|
|
20613
20658
|
const totalCount = countResult[0]?.total || 0;
|
|
20614
20659
|
const data = paginate27(items, page, limit, totalCount);
|
|
@@ -20717,24 +20762,16 @@ function usePatrolRouteRepo() {
|
|
|
20717
20762
|
{
|
|
20718
20763
|
$multiply: [
|
|
20719
20764
|
{
|
|
20720
|
-
$
|
|
20721
|
-
$
|
|
20722
|
-
startDate: { $toDate: "$start" },
|
|
20723
|
-
unit: "hour",
|
|
20724
|
-
amount: 8
|
|
20725
|
-
}
|
|
20765
|
+
$toInt: {
|
|
20766
|
+
$arrayElemAt: [{ $split: ["$start", ":"] }, 0]
|
|
20726
20767
|
}
|
|
20727
20768
|
},
|
|
20728
20769
|
60
|
|
20729
20770
|
]
|
|
20730
20771
|
},
|
|
20731
20772
|
{
|
|
20732
|
-
$
|
|
20733
|
-
$
|
|
20734
|
-
startDate: { $toDate: "$start" },
|
|
20735
|
-
unit: "hour",
|
|
20736
|
-
amount: 8
|
|
20737
|
-
}
|
|
20773
|
+
$toInt: {
|
|
20774
|
+
$arrayElemAt: [{ $split: ["$start", ":"] }, 1]
|
|
20738
20775
|
}
|
|
20739
20776
|
}
|
|
20740
20777
|
]
|
|
@@ -20747,24 +20784,16 @@ function usePatrolRouteRepo() {
|
|
|
20747
20784
|
{
|
|
20748
20785
|
$multiply: [
|
|
20749
20786
|
{
|
|
20750
|
-
$
|
|
20751
|
-
$
|
|
20752
|
-
startDate: { $toDate: "$end" },
|
|
20753
|
-
unit: "hour",
|
|
20754
|
-
amount: 8
|
|
20755
|
-
}
|
|
20787
|
+
$toInt: {
|
|
20788
|
+
$arrayElemAt: [{ $split: ["$end", ":"] }, 0]
|
|
20756
20789
|
}
|
|
20757
20790
|
},
|
|
20758
20791
|
60
|
|
20759
20792
|
]
|
|
20760
20793
|
},
|
|
20761
20794
|
{
|
|
20762
|
-
$
|
|
20763
|
-
$
|
|
20764
|
-
startDate: { $toDate: "$end" },
|
|
20765
|
-
unit: "hour",
|
|
20766
|
-
amount: 8
|
|
20767
|
-
}
|
|
20795
|
+
$toInt: {
|
|
20796
|
+
$arrayElemAt: [{ $split: ["$end", ":"] }, 1]
|
|
20768
20797
|
}
|
|
20769
20798
|
}
|
|
20770
20799
|
]
|
|
@@ -21102,6 +21131,8 @@ var schemeLogCamera = Joi65.object({
|
|
|
21102
21131
|
start: Joi65.string().optional().allow("", null),
|
|
21103
21132
|
end: Joi65.string().optional().allow("", null),
|
|
21104
21133
|
duration: Joi65.number().optional().allow("", null),
|
|
21134
|
+
status: Joi65.string().optional().allow("", null),
|
|
21135
|
+
description: Joi65.string().optional().allow("", null),
|
|
21105
21136
|
questions: Joi65.array().items(
|
|
21106
21137
|
Joi65.object({
|
|
21107
21138
|
questionId: Joi65.string().hex().required(),
|
|
@@ -21122,7 +21153,7 @@ var schemaPatrolLog = Joi65.object({
|
|
|
21122
21153
|
start: Joi65.string().required(),
|
|
21123
21154
|
end: Joi65.string().required(),
|
|
21124
21155
|
cameras: Joi65.array().items(schemeLogCamera).required(),
|
|
21125
|
-
status: Joi65.array().items(Joi65.string().valid("complete", "late")).required(),
|
|
21156
|
+
status: Joi65.array().items(Joi65.string().valid("complete", "late", "incomplete")).required(),
|
|
21126
21157
|
createdAt: Joi65.date().optional(),
|
|
21127
21158
|
updatedAt: Joi65.date().optional(),
|
|
21128
21159
|
deletedAt: Joi65.date().optional()
|
|
@@ -21135,7 +21166,7 @@ var schemaUpdatePatrolLog = Joi65.object({
|
|
|
21135
21166
|
start: Joi65.string().optional().allow(null, ""),
|
|
21136
21167
|
end: Joi65.string().optional().allow(null, ""),
|
|
21137
21168
|
cameras: Joi65.array().items(schemeLogCamera).optional().allow(null, ""),
|
|
21138
|
-
status: Joi65.array().items(Joi65.string().valid("complete", "late")).optional().allow(null, "")
|
|
21169
|
+
status: Joi65.array().items(Joi65.string().valid("complete", "late", "incomplete")).optional().allow(null, "")
|
|
21139
21170
|
});
|
|
21140
21171
|
function MPatrolLog(value) {
|
|
21141
21172
|
const { error } = schemaPatrolLog.validate(value);
|
|
@@ -21273,9 +21304,6 @@ function usePatrolLogRepo() {
|
|
|
21273
21304
|
}, session) {
|
|
21274
21305
|
page = page > 0 ? page - 1 : 0;
|
|
21275
21306
|
const query = {
|
|
21276
|
-
...search && {
|
|
21277
|
-
$or: [{ name: { $regex: search, $options: "i" } }]
|
|
21278
|
-
},
|
|
21279
21307
|
...ObjectId62.isValid(site) && { site: new ObjectId62(site) }
|
|
21280
21308
|
};
|
|
21281
21309
|
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
@@ -21295,14 +21323,113 @@ function usePatrolLogRepo() {
|
|
|
21295
21323
|
}
|
|
21296
21324
|
try {
|
|
21297
21325
|
const basePipeline = [
|
|
21298
|
-
{
|
|
21326
|
+
{
|
|
21327
|
+
$lookup: {
|
|
21328
|
+
from: "members",
|
|
21329
|
+
localField: "assignee",
|
|
21330
|
+
foreignField: "_id",
|
|
21331
|
+
as: "assigneeData"
|
|
21332
|
+
}
|
|
21333
|
+
},
|
|
21334
|
+
{
|
|
21335
|
+
$match: {
|
|
21336
|
+
...query,
|
|
21337
|
+
...search && {
|
|
21338
|
+
$or: [
|
|
21339
|
+
{ name: { $regex: search, $options: "i" } },
|
|
21340
|
+
{ "assigneeData.name": { $regex: search, $options: "i" } },
|
|
21341
|
+
{
|
|
21342
|
+
$expr: {
|
|
21343
|
+
$regexMatch: {
|
|
21344
|
+
input: {
|
|
21345
|
+
$dateToString: {
|
|
21346
|
+
date: { $toDate: "$start" },
|
|
21347
|
+
format: "%H:%M",
|
|
21348
|
+
timezone: "Asia/Singapore"
|
|
21349
|
+
}
|
|
21350
|
+
},
|
|
21351
|
+
regex: search,
|
|
21352
|
+
options: "i"
|
|
21353
|
+
}
|
|
21354
|
+
}
|
|
21355
|
+
},
|
|
21356
|
+
{
|
|
21357
|
+
$expr: {
|
|
21358
|
+
$regexMatch: {
|
|
21359
|
+
input: {
|
|
21360
|
+
$dateToString: {
|
|
21361
|
+
date: { $toDate: "$start" },
|
|
21362
|
+
format: "%H:%M",
|
|
21363
|
+
timezone: "Asia/Singapore"
|
|
21364
|
+
}
|
|
21365
|
+
},
|
|
21366
|
+
regex: search,
|
|
21367
|
+
options: "i"
|
|
21368
|
+
}
|
|
21369
|
+
}
|
|
21370
|
+
}
|
|
21371
|
+
]
|
|
21372
|
+
}
|
|
21373
|
+
}
|
|
21374
|
+
},
|
|
21299
21375
|
{ $sort: sort },
|
|
21300
21376
|
{ $skip: page * limit },
|
|
21301
21377
|
{ $limit: limit }
|
|
21302
21378
|
];
|
|
21379
|
+
const countPipeline = [
|
|
21380
|
+
{
|
|
21381
|
+
$lookup: {
|
|
21382
|
+
from: "members",
|
|
21383
|
+
localField: "assignee",
|
|
21384
|
+
foreignField: "_id",
|
|
21385
|
+
as: "assigneeData"
|
|
21386
|
+
}
|
|
21387
|
+
},
|
|
21388
|
+
{
|
|
21389
|
+
$match: {
|
|
21390
|
+
...query,
|
|
21391
|
+
...search && {
|
|
21392
|
+
$or: [
|
|
21393
|
+
{ name: { $regex: search, $options: "i" } },
|
|
21394
|
+
{ "assigneeData.name": { $regex: search, $options: "i" } },
|
|
21395
|
+
{
|
|
21396
|
+
$expr: {
|
|
21397
|
+
$regexMatch: {
|
|
21398
|
+
input: {
|
|
21399
|
+
$dateToString: {
|
|
21400
|
+
date: { $toDate: "$start" },
|
|
21401
|
+
format: "%H:%M",
|
|
21402
|
+
timezone: "Asia/Singapore"
|
|
21403
|
+
}
|
|
21404
|
+
},
|
|
21405
|
+
regex: search,
|
|
21406
|
+
options: "i"
|
|
21407
|
+
}
|
|
21408
|
+
}
|
|
21409
|
+
},
|
|
21410
|
+
{
|
|
21411
|
+
$expr: {
|
|
21412
|
+
$regexMatch: {
|
|
21413
|
+
input: {
|
|
21414
|
+
$dateToString: {
|
|
21415
|
+
date: { $toDate: "$start" },
|
|
21416
|
+
format: "%H:%M",
|
|
21417
|
+
timezone: "Asia/Singapore"
|
|
21418
|
+
}
|
|
21419
|
+
},
|
|
21420
|
+
regex: search,
|
|
21421
|
+
options: "i"
|
|
21422
|
+
}
|
|
21423
|
+
}
|
|
21424
|
+
}
|
|
21425
|
+
]
|
|
21426
|
+
}
|
|
21427
|
+
}
|
|
21428
|
+
}
|
|
21429
|
+
];
|
|
21303
21430
|
const [items, countResult] = await Promise.all([
|
|
21304
21431
|
collection.aggregate(basePipeline, { session }).toArray(),
|
|
21305
|
-
collection.aggregate([
|
|
21432
|
+
collection.aggregate([...countPipeline, { $count: "total" }], { session }).toArray()
|
|
21306
21433
|
]);
|
|
21307
21434
|
const totalCount = countResult[0]?.total || 0;
|
|
21308
21435
|
const data = paginate28(items, page, limit, totalCount);
|
|
@@ -23717,16 +23844,26 @@ function useDocumentManagementRepo() {
|
|
|
23717
23844
|
site = ""
|
|
23718
23845
|
}) {
|
|
23719
23846
|
page = page > 0 ? page - 1 : 0;
|
|
23847
|
+
try {
|
|
23848
|
+
site = new ObjectId70(site);
|
|
23849
|
+
} catch (error) {
|
|
23850
|
+
throw new BadRequestError119("Invalid site ID format.");
|
|
23851
|
+
}
|
|
23720
23852
|
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
23721
23853
|
const cacheOptions = {
|
|
23722
23854
|
page,
|
|
23723
23855
|
limit,
|
|
23724
23856
|
status,
|
|
23857
|
+
site: site?.toString(),
|
|
23725
23858
|
sort: JSON.stringify(sort)
|
|
23726
23859
|
};
|
|
23727
23860
|
const query = {
|
|
23728
23861
|
...status ? { $and: [{ status }, { status: { $ne: "deleted" } }] } : { status: { $ne: "deleted" } }
|
|
23729
23862
|
};
|
|
23863
|
+
if (site) {
|
|
23864
|
+
query.site = site;
|
|
23865
|
+
cacheOptions.site = site;
|
|
23866
|
+
}
|
|
23730
23867
|
if (search) {
|
|
23731
23868
|
query.$or = [
|
|
23732
23869
|
{ name: { $regex: search, $options: "i" } },
|
|
@@ -25997,14 +26134,16 @@ var schemaEventManagement = Joi81.object({
|
|
|
25997
26134
|
title: Joi81.string().required(),
|
|
25998
26135
|
description: Joi81.string().optional().allow(""),
|
|
25999
26136
|
dateTime: Joi81.alternatives().try(Joi81.string(), Joi81.date()).required(),
|
|
26000
|
-
status: Joi81.string().optional().default("planned")
|
|
26137
|
+
status: Joi81.string().optional().default("planned"),
|
|
26138
|
+
type: Joi81.string().optional().default("TASK")
|
|
26001
26139
|
});
|
|
26002
26140
|
var schemaUpdateEventManagement = Joi81.object({
|
|
26003
26141
|
_id: Joi81.string().hex().required(),
|
|
26004
26142
|
title: Joi81.string().optional().allow(null, ""),
|
|
26005
26143
|
description: Joi81.string().optional().allow(null, ""),
|
|
26006
26144
|
dateTime: Joi81.alternatives().try(Joi81.string(), Joi81.date()).optional().allow(null, ""),
|
|
26007
|
-
status: Joi81.string().optional().allow(null, "")
|
|
26145
|
+
status: Joi81.string().optional().allow(null, ""),
|
|
26146
|
+
type: Joi81.string().optional().allow(null, "")
|
|
26008
26147
|
});
|
|
26009
26148
|
function MEventManagement(value) {
|
|
26010
26149
|
if (value._id && typeof value._id === "string") {
|
|
@@ -26028,6 +26167,7 @@ function MEventManagement(value) {
|
|
|
26028
26167
|
description: value.description ?? "",
|
|
26029
26168
|
dateTime: value.dateTime,
|
|
26030
26169
|
status: value.status ?? "planned",
|
|
26170
|
+
type: value.type ?? "TASK",
|
|
26031
26171
|
createdAt: value.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
26032
26172
|
updatedAt: value.updatedAt,
|
|
26033
26173
|
deletedAt: value.deletedAt
|
|
@@ -26102,7 +26242,8 @@ function useEventManagementRepo() {
|
|
|
26102
26242
|
limit = 10,
|
|
26103
26243
|
sort = {},
|
|
26104
26244
|
site = "",
|
|
26105
|
-
status = ""
|
|
26245
|
+
status = "",
|
|
26246
|
+
type = ""
|
|
26106
26247
|
}, session) {
|
|
26107
26248
|
page = page > 0 ? page - 1 : 0;
|
|
26108
26249
|
try {
|
|
@@ -26112,7 +26253,8 @@ function useEventManagementRepo() {
|
|
|
26112
26253
|
}
|
|
26113
26254
|
const baseQuery = {
|
|
26114
26255
|
site,
|
|
26115
|
-
status: status ? status : { $ne: "deleted" }
|
|
26256
|
+
status: status ? status : { $ne: "deleted" },
|
|
26257
|
+
...type && { type }
|
|
26116
26258
|
};
|
|
26117
26259
|
let query = { ...baseQuery };
|
|
26118
26260
|
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
@@ -26121,7 +26263,8 @@ function useEventManagementRepo() {
|
|
|
26121
26263
|
status: status ? status : { $ne: "deleted" },
|
|
26122
26264
|
sort: JSON.stringify(sort),
|
|
26123
26265
|
page,
|
|
26124
|
-
limit
|
|
26266
|
+
limit,
|
|
26267
|
+
...type && { type }
|
|
26125
26268
|
};
|
|
26126
26269
|
if (search) {
|
|
26127
26270
|
query.$text = { $search: search };
|
|
@@ -26408,7 +26551,8 @@ function useEventManagementController() {
|
|
|
26408
26551
|
sort: Joi82.string().pattern(/^([a-zA-Z0-9_]+)(,[a-zA-Z0-9_]+)*$/).optional().allow("", ...allowedFields),
|
|
26409
26552
|
order: Joi82.string().pattern(/^(asc|desc)(,(asc|desc))*$/).optional().allow("", ...allowedOrder),
|
|
26410
26553
|
site: Joi82.string().hex().required(),
|
|
26411
|
-
status: Joi82.string().optional()
|
|
26554
|
+
status: Joi82.string().optional(),
|
|
26555
|
+
type: Joi82.string().optional().valid("TASK", "EVENT").allow(null, "")
|
|
26412
26556
|
});
|
|
26413
26557
|
const query = { ...req.query };
|
|
26414
26558
|
const { error } = validation.validate(query, {
|
|
@@ -26425,6 +26569,7 @@ function useEventManagementController() {
|
|
|
26425
26569
|
const limit = parseInt(req.query.limit ?? "10");
|
|
26426
26570
|
const site = req.query.site ?? "";
|
|
26427
26571
|
const status = req.query.status ?? "";
|
|
26572
|
+
const type = req.query.type ?? "";
|
|
26428
26573
|
const sortObj = {};
|
|
26429
26574
|
const sortFields = String(req.query.sort).split(",");
|
|
26430
26575
|
const sortOrders = String(req.query.order).split(",");
|
|
@@ -26441,7 +26586,8 @@ function useEventManagementController() {
|
|
|
26441
26586
|
limit,
|
|
26442
26587
|
sort: sortObj,
|
|
26443
26588
|
site,
|
|
26444
|
-
status
|
|
26589
|
+
status,
|
|
26590
|
+
type
|
|
26445
26591
|
});
|
|
26446
26592
|
res.status(200).json(data);
|
|
26447
26593
|
return;
|
|
@@ -27400,11 +27546,12 @@ var EAccessCardTypes = /* @__PURE__ */ ((EAccessCardTypes2) => {
|
|
|
27400
27546
|
EAccessCardTypes2["QR"] = "QRCODE";
|
|
27401
27547
|
return EAccessCardTypes2;
|
|
27402
27548
|
})(EAccessCardTypes || {});
|
|
27403
|
-
var EAccessCardUserTypes = /* @__PURE__ */ ((
|
|
27404
|
-
|
|
27405
|
-
|
|
27406
|
-
|
|
27407
|
-
|
|
27549
|
+
var EAccessCardUserTypes = /* @__PURE__ */ ((EAccessCardUserTypes2) => {
|
|
27550
|
+
EAccessCardUserTypes2["RESIDENT"] = "Resident/Tenant";
|
|
27551
|
+
EAccessCardUserTypes2["CONTRACTOR"] = "Contractor";
|
|
27552
|
+
EAccessCardUserTypes2["VISITOR"] = "Visitor";
|
|
27553
|
+
EAccessCardUserTypes2["DEFAULT"] = "Visitor/Resident";
|
|
27554
|
+
return EAccessCardUserTypes2;
|
|
27408
27555
|
})(EAccessCardUserTypes || {});
|
|
27409
27556
|
var AccessTypeProps = /* @__PURE__ */ ((AccessTypeProps2) => {
|
|
27410
27557
|
AccessTypeProps2["NORMAL"] = "Normal";
|
|
@@ -27505,6 +27652,114 @@ import {
|
|
|
27505
27652
|
useAtlas as useAtlas74
|
|
27506
27653
|
} from "@7365admin1/node-server-utils";
|
|
27507
27654
|
import { ObjectId as ObjectId83 } from "mongodb";
|
|
27655
|
+
|
|
27656
|
+
// src/utils/access-management.ts
|
|
27657
|
+
import fs2 from "fs";
|
|
27658
|
+
import path2 from "path";
|
|
27659
|
+
import axios from "axios";
|
|
27660
|
+
import crypto from "crypto";
|
|
27661
|
+
var ALGORITHM = "aes-256-gcm";
|
|
27662
|
+
var SECRET_KEY = crypto.createSecretKey(
|
|
27663
|
+
new Uint8Array(crypto.createHash("sha256").update("acm-secret-key").digest())
|
|
27664
|
+
);
|
|
27665
|
+
function decryptAcmUrl(encryptedText) {
|
|
27666
|
+
const [ivB64, authTagB64, encryptedB64] = encryptedText.split(":");
|
|
27667
|
+
const iv = Buffer.from(ivB64, "base64");
|
|
27668
|
+
const authTag = Buffer.from(authTagB64, "base64");
|
|
27669
|
+
const encrypted = Buffer.from(encryptedB64, "base64");
|
|
27670
|
+
const decipher = crypto.createDecipheriv(
|
|
27671
|
+
ALGORITHM,
|
|
27672
|
+
SECRET_KEY,
|
|
27673
|
+
new Uint8Array(iv)
|
|
27674
|
+
);
|
|
27675
|
+
decipher.setAuthTag(new Uint8Array(authTag));
|
|
27676
|
+
const decrypted = Buffer.concat([
|
|
27677
|
+
decipher.update(encrypted),
|
|
27678
|
+
decipher.final()
|
|
27679
|
+
]);
|
|
27680
|
+
return decrypted.toString("utf8");
|
|
27681
|
+
}
|
|
27682
|
+
var minifyXml = (xml) => {
|
|
27683
|
+
return xml.replace(/>\s+</g, "><").replace(/\n/g, "").replace(/\r/g, "").replace(/\t/g, "").trim();
|
|
27684
|
+
};
|
|
27685
|
+
var readTemplate = (name, params) => {
|
|
27686
|
+
const template = fs2.readFileSync(
|
|
27687
|
+
path2.join(__dirname, `../src/public/xml-templates/${name}.xml`),
|
|
27688
|
+
"utf-8"
|
|
27689
|
+
);
|
|
27690
|
+
if (!params)
|
|
27691
|
+
return minifyXml(template);
|
|
27692
|
+
const replacedTemplate = Object.entries(params).reduce(
|
|
27693
|
+
(acc, [key, value]) => acc.replace(`{{${key}}}`, value),
|
|
27694
|
+
template
|
|
27695
|
+
);
|
|
27696
|
+
return minifyXml(replacedTemplate);
|
|
27697
|
+
};
|
|
27698
|
+
async function sendCommand(command, url) {
|
|
27699
|
+
try {
|
|
27700
|
+
const decrypt = decryptAcmUrl(url);
|
|
27701
|
+
const response = await axios.post(decrypt, {
|
|
27702
|
+
command
|
|
27703
|
+
});
|
|
27704
|
+
if (response.status === 200 || response.status === 201)
|
|
27705
|
+
return response.data;
|
|
27706
|
+
} catch (error) {
|
|
27707
|
+
return Promise.reject(error);
|
|
27708
|
+
}
|
|
27709
|
+
}
|
|
27710
|
+
var formatDoorAccessLevels = (data) => {
|
|
27711
|
+
const doorAccessLevels = data.RESULT.TRACKID.SUB_RESULT.ACCESS_LEVEL;
|
|
27712
|
+
return doorAccessLevels.map((door) => {
|
|
27713
|
+
return {
|
|
27714
|
+
name: door._.trim(),
|
|
27715
|
+
// Remove any leading/trailing spaces
|
|
27716
|
+
no: door.$.NO
|
|
27717
|
+
// Extract the number
|
|
27718
|
+
};
|
|
27719
|
+
});
|
|
27720
|
+
};
|
|
27721
|
+
var formatLiftAccessLevels = (data, search) => {
|
|
27722
|
+
const liftAccessLevels = data.RESULT.TRACKID.SUB_RESULT.LIFT_ACCESS_LEVEL;
|
|
27723
|
+
const result = liftAccessLevels.map((level) => {
|
|
27724
|
+
return {
|
|
27725
|
+
name: level._.trim(),
|
|
27726
|
+
no: level.$.NO
|
|
27727
|
+
};
|
|
27728
|
+
});
|
|
27729
|
+
if (search) {
|
|
27730
|
+
return result.filter(
|
|
27731
|
+
(item) => item.name.toLowerCase().includes(search.toLowerCase())
|
|
27732
|
+
);
|
|
27733
|
+
}
|
|
27734
|
+
return result;
|
|
27735
|
+
};
|
|
27736
|
+
var formatAccessGroup = (data, search) => {
|
|
27737
|
+
const accessGroup = data.RESULT.TRACKID.SUB_RESULT.ACCESS_GROUP;
|
|
27738
|
+
const result = accessGroup.map((ag) => {
|
|
27739
|
+
return {
|
|
27740
|
+
no: ag._.trim(),
|
|
27741
|
+
name: ag.$.NAME
|
|
27742
|
+
};
|
|
27743
|
+
});
|
|
27744
|
+
if (search) {
|
|
27745
|
+
return result.filter(
|
|
27746
|
+
(item) => item.name.toLowerCase().includes(search.toLowerCase())
|
|
27747
|
+
);
|
|
27748
|
+
}
|
|
27749
|
+
return result;
|
|
27750
|
+
};
|
|
27751
|
+
var formatEntryPassDate = (date) => {
|
|
27752
|
+
if (!date)
|
|
27753
|
+
return null;
|
|
27754
|
+
const newDate = new Date(date);
|
|
27755
|
+
const year = newDate.getFullYear();
|
|
27756
|
+
const month = String(newDate.getMonth() + 1).padStart(2, "0");
|
|
27757
|
+
const day = String(newDate.getDate()).padStart(2, "0");
|
|
27758
|
+
return `${year}${month}${day}`;
|
|
27759
|
+
};
|
|
27760
|
+
|
|
27761
|
+
// src/repositories/access-management.repo.ts
|
|
27762
|
+
import { parseStringPromise } from "xml2js";
|
|
27508
27763
|
function UseAccessManagementRepo() {
|
|
27509
27764
|
function collection() {
|
|
27510
27765
|
const db = useAtlas74.getDb();
|
|
@@ -27957,16 +28212,16 @@ function UseAccessManagementRepo() {
|
|
|
27957
28212
|
preserveNullAndEmptyArrays: false
|
|
27958
28213
|
}
|
|
27959
28214
|
},
|
|
27960
|
-
// Groups by unit _id and keeps only the first occurrence
|
|
27961
|
-
{
|
|
27962
|
-
|
|
27963
|
-
|
|
27964
|
-
|
|
27965
|
-
|
|
27966
|
-
},
|
|
27967
|
-
{
|
|
27968
|
-
|
|
27969
|
-
},
|
|
28215
|
+
// // Groups by unit _id and keeps only the first occurrence
|
|
28216
|
+
// {
|
|
28217
|
+
// $group: {
|
|
28218
|
+
// _id: "$level.units._id",
|
|
28219
|
+
// doc: { $first: "$$ROOT" },
|
|
28220
|
+
// },
|
|
28221
|
+
// },
|
|
28222
|
+
// {
|
|
28223
|
+
// $replaceRoot: { newRoot: "$doc" },
|
|
28224
|
+
// },
|
|
27970
28225
|
// ✅ Apply search filter
|
|
27971
28226
|
{
|
|
27972
28227
|
$match: {
|
|
@@ -27978,7 +28233,6 @@ function UseAccessManagementRepo() {
|
|
|
27978
28233
|
totalCount: [{ $count: "count" }],
|
|
27979
28234
|
items: [
|
|
27980
28235
|
// ✅ Sort BEFORE skip/limit for correct pagination
|
|
27981
|
-
{ $sort: { _id: -1 } },
|
|
27982
28236
|
{ $skip: page * limit },
|
|
27983
28237
|
{ $limit: limit },
|
|
27984
28238
|
// ✅ Users lookup - optimized with index hint
|
|
@@ -28076,7 +28330,8 @@ function UseAccessManagementRepo() {
|
|
|
28076
28330
|
]
|
|
28077
28331
|
}
|
|
28078
28332
|
}
|
|
28079
|
-
}
|
|
28333
|
+
},
|
|
28334
|
+
{ $sort: { totalCardCount: -1 } }
|
|
28080
28335
|
]
|
|
28081
28336
|
}
|
|
28082
28337
|
}
|
|
@@ -28290,122 +28545,618 @@ function UseAccessManagementRepo() {
|
|
|
28290
28545
|
await session?.endSession();
|
|
28291
28546
|
}
|
|
28292
28547
|
}
|
|
28293
|
-
|
|
28294
|
-
|
|
28295
|
-
|
|
28296
|
-
|
|
28297
|
-
|
|
28298
|
-
|
|
28299
|
-
|
|
28300
|
-
|
|
28301
|
-
|
|
28302
|
-
|
|
28303
|
-
|
|
28304
|
-
|
|
28305
|
-
|
|
28306
|
-
|
|
28307
|
-
|
|
28308
|
-
|
|
28309
|
-
|
|
28310
|
-
|
|
28311
|
-
|
|
28312
|
-
|
|
28313
|
-
|
|
28314
|
-
|
|
28315
|
-
|
|
28316
|
-
|
|
28317
|
-
|
|
28318
|
-
)
|
|
28319
|
-
|
|
28320
|
-
|
|
28321
|
-
const iv = Buffer.from(ivB64, "base64");
|
|
28322
|
-
const authTag = Buffer.from(authTagB64, "base64");
|
|
28323
|
-
const encrypted = Buffer.from(encryptedB64, "base64");
|
|
28324
|
-
const decipher = crypto.createDecipheriv(
|
|
28325
|
-
ALGORITHM,
|
|
28326
|
-
SECRET_KEY,
|
|
28327
|
-
new Uint8Array(iv)
|
|
28328
|
-
);
|
|
28329
|
-
decipher.setAuthTag(new Uint8Array(authTag));
|
|
28330
|
-
const decrypted = Buffer.concat([
|
|
28331
|
-
decipher.update(encrypted),
|
|
28332
|
-
decipher.final()
|
|
28333
|
-
]);
|
|
28334
|
-
return decrypted.toString("utf8");
|
|
28335
|
-
}
|
|
28336
|
-
var minifyXml = (xml) => {
|
|
28337
|
-
return xml.replace(/>\s+</g, "><").replace(/\n/g, "").replace(/\r/g, "").replace(/\t/g, "").trim();
|
|
28338
|
-
};
|
|
28339
|
-
var readTemplate = (name, params) => {
|
|
28340
|
-
const template = fs2.readFileSync(
|
|
28341
|
-
path2.join(__dirname, `../src/public/xml-templates/${name}.xml`),
|
|
28342
|
-
"utf-8"
|
|
28343
|
-
);
|
|
28344
|
-
if (!params)
|
|
28345
|
-
return minifyXml(template);
|
|
28346
|
-
const replacedTemplate = Object.entries(params).reduce(
|
|
28347
|
-
(acc, [key, value]) => acc.replace(`{{${key}}}`, value),
|
|
28348
|
-
template
|
|
28349
|
-
);
|
|
28350
|
-
return minifyXml(replacedTemplate);
|
|
28351
|
-
};
|
|
28352
|
-
async function sendCommand(command, url) {
|
|
28353
|
-
try {
|
|
28354
|
-
const decrypt = decryptAcmUrl(url);
|
|
28355
|
-
const response = await axios.post(decrypt, {
|
|
28356
|
-
command
|
|
28357
|
-
});
|
|
28358
|
-
if (response.status === 200 || response.status === 201)
|
|
28359
|
-
return response.data;
|
|
28360
|
-
} catch (error) {
|
|
28361
|
-
return Promise.reject(error);
|
|
28548
|
+
async function accessandLiftCardsRepo(params) {
|
|
28549
|
+
try {
|
|
28550
|
+
const { accessLevel, liftAccessLevel, site, userType, type } = params;
|
|
28551
|
+
const siteId = new ObjectId83(site);
|
|
28552
|
+
const query = {
|
|
28553
|
+
site: { $in: [siteId] },
|
|
28554
|
+
userType,
|
|
28555
|
+
type,
|
|
28556
|
+
userId: null,
|
|
28557
|
+
assignedUnit: null,
|
|
28558
|
+
accessLevel,
|
|
28559
|
+
liftAccessLevel,
|
|
28560
|
+
isActivated: true
|
|
28561
|
+
};
|
|
28562
|
+
const result = await collection().aggregate([
|
|
28563
|
+
{
|
|
28564
|
+
$match: query
|
|
28565
|
+
},
|
|
28566
|
+
{
|
|
28567
|
+
$facet: {
|
|
28568
|
+
counts: [{ $count: "count" }]
|
|
28569
|
+
}
|
|
28570
|
+
}
|
|
28571
|
+
], { allowDiskUse: true }).toArray();
|
|
28572
|
+
return result;
|
|
28573
|
+
} catch (error) {
|
|
28574
|
+
throw new Error(error.message);
|
|
28575
|
+
}
|
|
28362
28576
|
}
|
|
28363
|
-
|
|
28364
|
-
|
|
28365
|
-
|
|
28366
|
-
|
|
28367
|
-
|
|
28368
|
-
|
|
28369
|
-
|
|
28370
|
-
|
|
28371
|
-
|
|
28372
|
-
|
|
28373
|
-
|
|
28374
|
-
}
|
|
28375
|
-
|
|
28376
|
-
|
|
28377
|
-
|
|
28378
|
-
|
|
28379
|
-
|
|
28380
|
-
|
|
28381
|
-
|
|
28382
|
-
|
|
28383
|
-
|
|
28384
|
-
|
|
28385
|
-
|
|
28386
|
-
|
|
28577
|
+
async function replaceCardRepo(params) {
|
|
28578
|
+
const session = useAtlas74.getClient()?.startSession();
|
|
28579
|
+
try {
|
|
28580
|
+
session?.startTransaction();
|
|
28581
|
+
const siteId = new ObjectId83(params.site);
|
|
28582
|
+
const userId = new ObjectId83(params.userId);
|
|
28583
|
+
const cardId = new ObjectId83(params.cardId);
|
|
28584
|
+
const quantity = 1;
|
|
28585
|
+
const cardCredentials = await collection().findOneAndUpdate(
|
|
28586
|
+
{ _id: cardId },
|
|
28587
|
+
{ $set: { replacementStatus: "Issuance" } },
|
|
28588
|
+
{ returnDocument: "after" }
|
|
28589
|
+
);
|
|
28590
|
+
const unit = [cardCredentials?.assignedUnit];
|
|
28591
|
+
const date = /* @__PURE__ */ new Date();
|
|
28592
|
+
const endDate = new Date(date.setFullYear(date.getFullYear() + 10));
|
|
28593
|
+
const res = await collection().aggregate([{ $sort: { cardNo: -1 } }, { $limit: 2 }]).toArray();
|
|
28594
|
+
const prevCard = res && res?.[1]?.cardNo || "-1";
|
|
28595
|
+
const currentCard = res && res?.[0]?.cardNo || "0";
|
|
28596
|
+
let availableCardNo = [];
|
|
28597
|
+
let num = parseInt(prevCard, 10) + 1;
|
|
28598
|
+
while (availableCardNo.length < (unit.length > 0 ? unit.length : quantity)) {
|
|
28599
|
+
if (num === parseInt(currentCard, 10)) {
|
|
28600
|
+
num++;
|
|
28601
|
+
}
|
|
28602
|
+
availableCardNo.push(num);
|
|
28603
|
+
num++;
|
|
28604
|
+
}
|
|
28605
|
+
const cardNumbers = availableCardNo.map((no) => no.toString().padStart(10, "0"));
|
|
28606
|
+
const accessCards = [];
|
|
28607
|
+
const convertedUnits = unit.map((obj) => new ObjectId83(obj));
|
|
28608
|
+
for (let j = 0; j < (unit.length > 0 ? unit.length : quantity); j++) {
|
|
28609
|
+
accessCards.push(
|
|
28610
|
+
new MAccessCard({
|
|
28611
|
+
userId,
|
|
28612
|
+
site: siteId,
|
|
28613
|
+
type: cardCredentials?.type,
|
|
28614
|
+
accessLevel: cardCredentials?.accessLevel,
|
|
28615
|
+
accessGroup: cardCredentials?.accessGroup,
|
|
28616
|
+
accessType: cardCredentials?.accessType,
|
|
28617
|
+
cardNo: cardNumbers[j],
|
|
28618
|
+
pin: "123456",
|
|
28619
|
+
qrData: "092222",
|
|
28620
|
+
startDate: /* @__PURE__ */ new Date(),
|
|
28621
|
+
endDate,
|
|
28622
|
+
isActivated: true,
|
|
28623
|
+
isAntiPassBack: false,
|
|
28624
|
+
isLiftCard: cardCredentials?.isLiftCard ? true : false,
|
|
28625
|
+
liftAccessLevel: cardCredentials?.liftAccessLevel,
|
|
28626
|
+
userType: cardCredentials?.userType,
|
|
28627
|
+
doorName: cardCredentials?.doorName,
|
|
28628
|
+
liftName: cardCredentials?.liftName,
|
|
28629
|
+
assignedUnit: convertedUnits[j],
|
|
28630
|
+
replacementStatus: "Issuance",
|
|
28631
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
28632
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
28633
|
+
})
|
|
28634
|
+
);
|
|
28635
|
+
}
|
|
28636
|
+
const commands = accessCards.map((item, index) => {
|
|
28637
|
+
let ag = null;
|
|
28638
|
+
if (item.accessGroup !== void 0) {
|
|
28639
|
+
if (item.accessGroup?.length > 0) {
|
|
28640
|
+
ag = item.accessGroup.map((g) => `<GROUP_NAME>${g}</GROUP_NAME>`).join("\n ");
|
|
28641
|
+
}
|
|
28642
|
+
}
|
|
28643
|
+
const command = {
|
|
28644
|
+
commandId1: index * 2 + 1,
|
|
28645
|
+
commandId2: index * 2 + 2,
|
|
28646
|
+
staffName: `STAFF-${item._id.toString().slice(-10)}`,
|
|
28647
|
+
staffNo1: `STAFF-${item._id.toString().slice(-10)}`,
|
|
28648
|
+
staffNo2: `STAFF-${item._id.toString().slice(-10)}`,
|
|
28649
|
+
dateOfJoin: formatEntryPassDate(item.startDate),
|
|
28650
|
+
accessLevel: item.accessLevel ?? "0",
|
|
28651
|
+
cardNo: item.cardNo,
|
|
28652
|
+
pin: typeof item.pin === "string" && item.pin.trim() !== "" ? item.pin : "123456",
|
|
28653
|
+
startDate: formatEntryPassDate(item.startDate),
|
|
28654
|
+
endDate: formatEntryPassDate(item.endDate),
|
|
28655
|
+
cardType: 0,
|
|
28656
|
+
isActivated: item.isActivated ? 1 : 0,
|
|
28657
|
+
isAntiPassBack: item.isAntiPassBack ? 1 : 0,
|
|
28658
|
+
isLiftCard: item.isLiftCard ? 1 : 0,
|
|
28659
|
+
isLiftActivate: item.isLiftCard ? 1 : 0,
|
|
28660
|
+
liftAccessLevel: item.liftAccessLevel || 1,
|
|
28661
|
+
liftAccessStartDate: formatEntryPassDate(item.liftAccessStartDate) || "19770510",
|
|
28662
|
+
liftAccessEndDate: formatEntryPassDate(item.liftAccessEndDate) || "19770510",
|
|
28663
|
+
accessGroup: ag
|
|
28664
|
+
};
|
|
28665
|
+
return readTemplate(`${item.accessLevel !== null ? "add-card" : "add-card-lift"}`, { ...command });
|
|
28666
|
+
}).flat();
|
|
28667
|
+
const response = await sendCommand(commands.join("").toString(), params.acm_url);
|
|
28668
|
+
const result = await parseStringPromise(response, { explicitArray: false });
|
|
28669
|
+
if (result && result.RESULT.$.STCODE !== "0") {
|
|
28670
|
+
throw new Error("Command failed, server error.");
|
|
28671
|
+
}
|
|
28672
|
+
const card = await collection().insertMany(accessCards);
|
|
28673
|
+
await session?.commitTransaction();
|
|
28674
|
+
return card;
|
|
28675
|
+
} catch (error) {
|
|
28676
|
+
await session?.abortTransaction();
|
|
28677
|
+
throw new Error(error.message);
|
|
28678
|
+
} finally {
|
|
28679
|
+
await session?.endSession();
|
|
28680
|
+
}
|
|
28387
28681
|
}
|
|
28388
|
-
|
|
28389
|
-
|
|
28390
|
-
|
|
28391
|
-
|
|
28392
|
-
|
|
28393
|
-
|
|
28394
|
-
|
|
28395
|
-
|
|
28396
|
-
|
|
28397
|
-
|
|
28398
|
-
|
|
28399
|
-
|
|
28400
|
-
|
|
28401
|
-
|
|
28682
|
+
async function updateNFCStatusRepo(params) {
|
|
28683
|
+
const session = useAtlas74.getClient()?.startSession();
|
|
28684
|
+
try {
|
|
28685
|
+
session?.startTransaction();
|
|
28686
|
+
const results = [];
|
|
28687
|
+
for (let nfc of params.nfcList) {
|
|
28688
|
+
nfc._id = new ObjectId83(nfc._id);
|
|
28689
|
+
const card = await collection().findOne({ _id: nfc._id }, { session });
|
|
28690
|
+
if (card) {
|
|
28691
|
+
const updateFields = {
|
|
28692
|
+
status: nfc.status,
|
|
28693
|
+
vmsRemarks: nfc?.vmsRemarks,
|
|
28694
|
+
userId: null,
|
|
28695
|
+
updatedAt: nfc?.updatedAt ?? /* @__PURE__ */ new Date()
|
|
28696
|
+
};
|
|
28697
|
+
if (nfc.status !== "Returned") {
|
|
28698
|
+
updateFields.isActivated = false;
|
|
28699
|
+
} else {
|
|
28700
|
+
updateFields.isActivated = true;
|
|
28701
|
+
}
|
|
28702
|
+
const res = await collection().updateOne({ _id: card._id }, { $set: updateFields }, { session });
|
|
28703
|
+
results.push({ nfcId: nfc._id, modifiedCount: res.modifiedCount });
|
|
28704
|
+
}
|
|
28705
|
+
}
|
|
28706
|
+
await session?.commitTransaction();
|
|
28707
|
+
return results;
|
|
28708
|
+
} catch (error) {
|
|
28709
|
+
await session?.abortTransaction();
|
|
28710
|
+
throw new Error(error.message);
|
|
28711
|
+
} finally {
|
|
28712
|
+
await session?.endSession();
|
|
28713
|
+
}
|
|
28402
28714
|
}
|
|
28403
|
-
|
|
28404
|
-
|
|
28715
|
+
async function doorAndLiftDropdownRepo(params) {
|
|
28716
|
+
try {
|
|
28717
|
+
const { site, type, userType } = params;
|
|
28718
|
+
const id = new ObjectId83(site);
|
|
28719
|
+
const res = collection().aggregate([
|
|
28720
|
+
{
|
|
28721
|
+
$match: {
|
|
28722
|
+
site: { $in: [id] },
|
|
28723
|
+
type,
|
|
28724
|
+
userType,
|
|
28725
|
+
isActivated: true,
|
|
28726
|
+
assignedUnit: null,
|
|
28727
|
+
userId: null,
|
|
28728
|
+
$or: [
|
|
28729
|
+
{ $and: [{ doorName: { $ne: null } }, { doorName: { $ne: "" } }, { accessLevel: { $ne: null } }] },
|
|
28730
|
+
{ $and: [{ liftName: { $ne: null } }, { liftName: { $ne: "" } }, { liftAccessLevel: { $ne: null } }] }
|
|
28731
|
+
]
|
|
28732
|
+
}
|
|
28733
|
+
},
|
|
28734
|
+
{
|
|
28735
|
+
$facet: {
|
|
28736
|
+
totalCount: [{ $count: "count" }],
|
|
28737
|
+
accessData: [
|
|
28738
|
+
{
|
|
28739
|
+
$group: {
|
|
28740
|
+
_id: null,
|
|
28741
|
+
accessLevels: {
|
|
28742
|
+
$addToSet: {
|
|
28743
|
+
$cond: [
|
|
28744
|
+
{ $and: [{ $ne: ["$doorName", null] }, { $ne: ["$doorName", ""] }, { $ne: ["$accessLevel", null] }] },
|
|
28745
|
+
{ name: "$doorName", no: "$accessLevel" },
|
|
28746
|
+
"$$REMOVE"
|
|
28747
|
+
]
|
|
28748
|
+
}
|
|
28749
|
+
},
|
|
28750
|
+
liftAccessLevels: {
|
|
28751
|
+
$addToSet: {
|
|
28752
|
+
$cond: [
|
|
28753
|
+
{ $and: [{ $ne: ["$liftName", null] }, { $ne: ["$liftName", ""] }, { $ne: ["$liftAccessLevel", null] }] },
|
|
28754
|
+
{ name: "$liftName", no: "$liftAccessLevel" },
|
|
28755
|
+
"$$REMOVE"
|
|
28756
|
+
]
|
|
28757
|
+
}
|
|
28758
|
+
}
|
|
28759
|
+
}
|
|
28760
|
+
},
|
|
28761
|
+
{
|
|
28762
|
+
$project: {
|
|
28763
|
+
_id: 0,
|
|
28764
|
+
accessLevels: 1,
|
|
28765
|
+
liftAccessLevels: 1
|
|
28766
|
+
}
|
|
28767
|
+
}
|
|
28768
|
+
]
|
|
28769
|
+
}
|
|
28770
|
+
}
|
|
28771
|
+
]).toArray();
|
|
28772
|
+
return res;
|
|
28773
|
+
} catch (error) {
|
|
28774
|
+
throw new Error(error.message);
|
|
28775
|
+
}
|
|
28776
|
+
}
|
|
28777
|
+
async function cardReplacementRepo(params) {
|
|
28778
|
+
const session = useAtlas74.getClient()?.startSession();
|
|
28779
|
+
try {
|
|
28780
|
+
const { cardId, remarks } = params;
|
|
28781
|
+
const id = new ObjectId83(cardId);
|
|
28782
|
+
session?.startTransaction();
|
|
28783
|
+
const card = await collection().findOneAndUpdate(
|
|
28784
|
+
{ _id: id },
|
|
28785
|
+
{ $set: { remarks, replacementStatus: "Pending", requestDate: /* @__PURE__ */ new Date(), isActivated: false } },
|
|
28786
|
+
{ returnDocument: "after", session }
|
|
28787
|
+
);
|
|
28788
|
+
await session?.commitTransaction();
|
|
28789
|
+
return card;
|
|
28790
|
+
} catch (error) {
|
|
28791
|
+
await session?.abortTransaction();
|
|
28792
|
+
throw new Error(error.message);
|
|
28793
|
+
} finally {
|
|
28794
|
+
await session?.endSession();
|
|
28795
|
+
}
|
|
28796
|
+
}
|
|
28797
|
+
async function visitorAccessCardsRepo(params) {
|
|
28798
|
+
try {
|
|
28799
|
+
const page = params.page ? params.page - 1 : 0;
|
|
28800
|
+
const siteId = new ObjectId83(params.site);
|
|
28801
|
+
const search = params.search;
|
|
28802
|
+
const type = params.type;
|
|
28803
|
+
const limit = Number(params.limit);
|
|
28804
|
+
const query = {
|
|
28805
|
+
site: siteId,
|
|
28806
|
+
assignedUnit: { $ne: null },
|
|
28807
|
+
type: "NFC" /* NFC */
|
|
28808
|
+
};
|
|
28809
|
+
if (search) {
|
|
28810
|
+
query.$or = [{ accessLevel: { $regex: search, $options: "i" } }, { cardNo: { $regex: search, $options: "i" } }];
|
|
28811
|
+
}
|
|
28812
|
+
if (type) {
|
|
28813
|
+
query.userType = type;
|
|
28814
|
+
} else {
|
|
28815
|
+
query.userType = { $ne: "Resident/Tenant" /* RESIDENT */ };
|
|
28816
|
+
}
|
|
28817
|
+
const res = await collection().aggregate([
|
|
28818
|
+
{
|
|
28819
|
+
$match: query
|
|
28820
|
+
},
|
|
28821
|
+
{
|
|
28822
|
+
$project: {
|
|
28823
|
+
cardNo: 1,
|
|
28824
|
+
accessLevel: 1,
|
|
28825
|
+
site: 1,
|
|
28826
|
+
userType: 1,
|
|
28827
|
+
qrTag: 1,
|
|
28828
|
+
qrTagCardNo: 1,
|
|
28829
|
+
qrData: 1
|
|
28830
|
+
}
|
|
28831
|
+
},
|
|
28832
|
+
{
|
|
28833
|
+
$addFields: {
|
|
28834
|
+
extractedCardNo: {
|
|
28835
|
+
$substr: ["$cardNo", { $subtract: [{ $strLenCP: "$cardNo" }, 5] }, 5]
|
|
28836
|
+
}
|
|
28837
|
+
}
|
|
28838
|
+
},
|
|
28839
|
+
{
|
|
28840
|
+
$facet: {
|
|
28841
|
+
totalCount: [{ $count: "count" }],
|
|
28842
|
+
items: [{ $sort: { _id: -1 } }, { $skip: page * limit }, { $limit: limit }]
|
|
28843
|
+
}
|
|
28844
|
+
}
|
|
28845
|
+
]).toArray();
|
|
28846
|
+
const length = res[0].totalCount[0] ? res[0].totalCount[0].count : 0;
|
|
28847
|
+
const items = res[0].items;
|
|
28848
|
+
const paginatedResult = paginate38(items, page, limit, length);
|
|
28849
|
+
return paginatedResult;
|
|
28850
|
+
} catch (error) {
|
|
28851
|
+
throw new Error(error.message);
|
|
28852
|
+
}
|
|
28853
|
+
}
|
|
28854
|
+
async function getCardReplacementRepo(params) {
|
|
28855
|
+
try {
|
|
28856
|
+
const site = new ObjectId83(params.site);
|
|
28857
|
+
const search = params.search;
|
|
28858
|
+
const statusFilter = params.statusFilter;
|
|
28859
|
+
const dateFrom = params.dateFrom;
|
|
28860
|
+
const dateTo = params.dateTo;
|
|
28861
|
+
const page = Number(params.page) - 1;
|
|
28862
|
+
const limit = Number(params.limit);
|
|
28863
|
+
const query = {
|
|
28864
|
+
site,
|
|
28865
|
+
replacementStatus: { $in: ["Complete", "Issuance", "Pending"] },
|
|
28866
|
+
isActivated: false
|
|
28867
|
+
};
|
|
28868
|
+
const searchQuery = buildSearchQuery(search);
|
|
28869
|
+
if (statusFilter) {
|
|
28870
|
+
query.replacementStatus = statusFilter;
|
|
28871
|
+
}
|
|
28872
|
+
if (dateFrom && dateTo) {
|
|
28873
|
+
query.requestDate = { $gte: new Date(dateFrom), $lte: new Date(dateTo) };
|
|
28874
|
+
} else if (dateFrom) {
|
|
28875
|
+
query.requestDate = { $gte: new Date(dateFrom) };
|
|
28876
|
+
} else if (dateTo) {
|
|
28877
|
+
query.requestDate = { $lte: new Date(dateTo) };
|
|
28878
|
+
}
|
|
28879
|
+
const res = await collection().aggregate([
|
|
28880
|
+
{
|
|
28881
|
+
$match: { ...query }
|
|
28882
|
+
},
|
|
28883
|
+
{
|
|
28884
|
+
$lookup: {
|
|
28885
|
+
from: "building-units",
|
|
28886
|
+
let: { unit: "$assignedUnit" },
|
|
28887
|
+
pipeline: [
|
|
28888
|
+
{
|
|
28889
|
+
$match: {
|
|
28890
|
+
$expr: {
|
|
28891
|
+
$eq: ["$_id", "$$unit"]
|
|
28892
|
+
}
|
|
28893
|
+
}
|
|
28894
|
+
},
|
|
28895
|
+
{
|
|
28896
|
+
$project: {
|
|
28897
|
+
_id: 1,
|
|
28898
|
+
name: 1,
|
|
28899
|
+
level: 1
|
|
28900
|
+
}
|
|
28901
|
+
}
|
|
28902
|
+
],
|
|
28903
|
+
as: "unit"
|
|
28904
|
+
}
|
|
28905
|
+
},
|
|
28906
|
+
{
|
|
28907
|
+
$unwind: { path: "$unit", preserveNullAndEmptyArrays: true }
|
|
28908
|
+
},
|
|
28909
|
+
{
|
|
28910
|
+
$lookup: {
|
|
28911
|
+
from: "building-levels",
|
|
28912
|
+
let: { level: "$unit.level" },
|
|
28913
|
+
pipeline: [
|
|
28914
|
+
{
|
|
28915
|
+
$match: {
|
|
28916
|
+
$expr: {
|
|
28917
|
+
$eq: ["$_id", "$$level"]
|
|
28918
|
+
}
|
|
28919
|
+
}
|
|
28920
|
+
},
|
|
28921
|
+
{
|
|
28922
|
+
$project: {
|
|
28923
|
+
_id: 1,
|
|
28924
|
+
level: 1,
|
|
28925
|
+
block: 1
|
|
28926
|
+
}
|
|
28927
|
+
}
|
|
28928
|
+
],
|
|
28929
|
+
as: "level"
|
|
28930
|
+
}
|
|
28931
|
+
},
|
|
28932
|
+
{
|
|
28933
|
+
$unwind: { path: "$level", preserveNullAndEmptyArrays: true }
|
|
28934
|
+
},
|
|
28935
|
+
{
|
|
28936
|
+
$lookup: {
|
|
28937
|
+
from: "buildings",
|
|
28938
|
+
let: { block: "$level.block" },
|
|
28939
|
+
pipeline: [
|
|
28940
|
+
{
|
|
28941
|
+
$match: {
|
|
28942
|
+
$expr: {
|
|
28943
|
+
$eq: ["$_id", "$$block"]
|
|
28944
|
+
}
|
|
28945
|
+
}
|
|
28946
|
+
},
|
|
28947
|
+
{
|
|
28948
|
+
$project: {
|
|
28949
|
+
_id: 1,
|
|
28950
|
+
name: 1
|
|
28951
|
+
}
|
|
28952
|
+
}
|
|
28953
|
+
],
|
|
28954
|
+
as: "building"
|
|
28955
|
+
}
|
|
28956
|
+
},
|
|
28957
|
+
{
|
|
28958
|
+
$unwind: { path: "$building", preserveNullAndEmptyArrays: true }
|
|
28959
|
+
},
|
|
28960
|
+
{
|
|
28961
|
+
$lookup: {
|
|
28962
|
+
from: "users",
|
|
28963
|
+
let: { id: "$userId" },
|
|
28964
|
+
pipeline: [
|
|
28965
|
+
{
|
|
28966
|
+
$match: {
|
|
28967
|
+
$expr: {
|
|
28968
|
+
$eq: ["$_id", "$$id"]
|
|
28969
|
+
}
|
|
28970
|
+
}
|
|
28971
|
+
},
|
|
28972
|
+
{
|
|
28973
|
+
$project: {
|
|
28974
|
+
givenName: 1,
|
|
28975
|
+
surname: 1
|
|
28976
|
+
}
|
|
28977
|
+
}
|
|
28978
|
+
],
|
|
28979
|
+
as: "user"
|
|
28980
|
+
}
|
|
28981
|
+
},
|
|
28982
|
+
{
|
|
28983
|
+
$unwind: { path: "$user", preserveNullAndEmptyArrays: true }
|
|
28984
|
+
},
|
|
28985
|
+
{
|
|
28986
|
+
$match: { ...searchQuery }
|
|
28987
|
+
},
|
|
28988
|
+
{
|
|
28989
|
+
$facet: {
|
|
28990
|
+
data: [
|
|
28991
|
+
{ $skip: page * limit },
|
|
28992
|
+
{ $limit: limit },
|
|
28993
|
+
{
|
|
28994
|
+
$project: {
|
|
28995
|
+
_id: 1,
|
|
28996
|
+
cardNo: 1,
|
|
28997
|
+
accessLevel: 1,
|
|
28998
|
+
liftAccessLevel: 1,
|
|
28999
|
+
replacementStatus: 1,
|
|
29000
|
+
remarks: 1,
|
|
29001
|
+
block: "$building.name",
|
|
29002
|
+
level: "$level.level",
|
|
29003
|
+
unit: "$unit.name",
|
|
29004
|
+
user: "$user"
|
|
29005
|
+
}
|
|
29006
|
+
}
|
|
29007
|
+
],
|
|
29008
|
+
totalCount: [{ $count: "count" }]
|
|
29009
|
+
}
|
|
29010
|
+
}
|
|
29011
|
+
], { allowDiskUse: true }).toArray();
|
|
29012
|
+
const count = res[0]?.totalCount[0] ? res[0].totalCount[0].count : 0;
|
|
29013
|
+
const pagination = paginate38(res[0].data, page, limit, count);
|
|
29014
|
+
return pagination;
|
|
29015
|
+
} catch (error) {
|
|
29016
|
+
throw new Error(error.message);
|
|
29017
|
+
}
|
|
29018
|
+
}
|
|
29019
|
+
async function getAccessManagementSettingsRepo(params) {
|
|
29020
|
+
try {
|
|
29021
|
+
const { site } = params;
|
|
29022
|
+
const siteId = new ObjectId83(site);
|
|
29023
|
+
const res = await collectionName("entrypass-settings").findOne({ site: siteId }, { allowDiskUse: true });
|
|
29024
|
+
return res;
|
|
29025
|
+
} catch (error) {
|
|
29026
|
+
throw new Error(error.message);
|
|
29027
|
+
}
|
|
29028
|
+
}
|
|
29029
|
+
async function bulkPhysicalAccessCardRepo(params) {
|
|
29030
|
+
const session = useAtlas74.getClient()?.startSession();
|
|
29031
|
+
try {
|
|
29032
|
+
const { dataJson, site } = params;
|
|
29033
|
+
const rawItems = JSON.parse(dataJson).filter((_, index) => index !== -1);
|
|
29034
|
+
const items = await Promise.all(
|
|
29035
|
+
rawItems.map(async (item) => {
|
|
29036
|
+
const date = new Date(item["startDate (format MM/DD/YYYY)"]);
|
|
29037
|
+
const endDate = new Date(date.setFullYear(date.getFullYear() + 10));
|
|
29038
|
+
const cardNumber = item["cardNo (number 0-65535 ex. 301)"].toString().padStart(10, "0");
|
|
29039
|
+
const pin = item["pin (number 6 digits only)"] ? item["pin (number 6 digits only)"].toString().padStart(6, "0") : "123456";
|
|
29040
|
+
const match = item["accessLevel (number ex. 1)"];
|
|
29041
|
+
const accessLevel = match ? match : null;
|
|
29042
|
+
const userType = item["userType(Contractor, Visitor, Resident/Tenant, Visitor/Resident)"];
|
|
29043
|
+
const rawAccessGroup = item["accessGroup (value ex. Full Access, No Access)"];
|
|
29044
|
+
const accessGroup = typeof rawAccessGroup === "string" ? rawAccessGroup.split(",").map((v) => v.trim()).filter((v) => v !== "") : [];
|
|
29045
|
+
return new MAccessCard({
|
|
29046
|
+
site: new ObjectId83(site),
|
|
29047
|
+
type: "NFC" /* NFC */,
|
|
29048
|
+
staffNo: null,
|
|
29049
|
+
accessLevel,
|
|
29050
|
+
accessGroup,
|
|
29051
|
+
accessType: "Normal" /* NORMAL */,
|
|
29052
|
+
cardNo: cardNumber,
|
|
29053
|
+
pin,
|
|
29054
|
+
qrData: await createQrData({ cardNumber }),
|
|
29055
|
+
startDate: new Date(item["startDate (format MM/DD/YYYY)"]),
|
|
29056
|
+
endDate: new Date(item["endDate (format MM/DD/YYYY)"] || endDate),
|
|
29057
|
+
isActivated: true,
|
|
29058
|
+
isAntiPassBack: false,
|
|
29059
|
+
isLiftCard: item["isLiftCard (TRUE OR FALSE)"] === "TRUE" ? true : false,
|
|
29060
|
+
liftAccessLevel: item["liftAccessLevel(number ex. 1)"] || null,
|
|
29061
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
29062
|
+
updatedAt: /* @__PURE__ */ new Date(),
|
|
29063
|
+
assignedUnit: null,
|
|
29064
|
+
userType: userType.toLowerCase() === "contractor" ? "Contractor" /* CONTRACTOR */ : userType.toLowerCase() === "visitor" ? "Visitor" /* VISITOR */ : userType.toLowerCase() === "resident/tenant" ? "Resident/Tenant" /* RESIDENT */ : "Visitor/Resident" /* DEFAULT */,
|
|
29065
|
+
doorName: item["Door Name (ex. Main Door)"] || null,
|
|
29066
|
+
liftName: item["Lift Name (ex. Main Lift)"] || null
|
|
29067
|
+
});
|
|
29068
|
+
})
|
|
29069
|
+
);
|
|
29070
|
+
const result = await collection().insertMany(items, { session, ordered: false });
|
|
29071
|
+
const mapping = items.map((item, i) => ({
|
|
29072
|
+
cardNo: item.cardNo,
|
|
29073
|
+
insertedId: result.insertedIds[i]
|
|
29074
|
+
}));
|
|
29075
|
+
return mapping;
|
|
29076
|
+
} catch (error) {
|
|
29077
|
+
throw new Error(error.message);
|
|
29078
|
+
}
|
|
29079
|
+
}
|
|
29080
|
+
async function assignAccessCardToUnitRepo(params) {
|
|
29081
|
+
const session = useAtlas74.getClient()?.startSession();
|
|
29082
|
+
try {
|
|
29083
|
+
session?.startTransaction();
|
|
29084
|
+
const { units, quantity, type, site, userType, accessLevel, liftAccessLevel } = params;
|
|
29085
|
+
const [convertedUnits, convertedSite] = await Promise.all([Promise.all(units.map((id) => new ObjectId83(id))), new ObjectId83(site)]);
|
|
29086
|
+
const totalRequired = quantity * convertedUnits.length;
|
|
29087
|
+
const availableCards = await collection().find({
|
|
29088
|
+
assignedUnit: null,
|
|
29089
|
+
userId: null,
|
|
29090
|
+
type,
|
|
29091
|
+
userType,
|
|
29092
|
+
isActivated: true,
|
|
29093
|
+
site: convertedSite,
|
|
29094
|
+
accessLevel: accessLevel ?? null,
|
|
29095
|
+
liftAccessLevel: liftAccessLevel ?? null
|
|
29096
|
+
}).limit(totalRequired).toArray();
|
|
29097
|
+
if (availableCards.length < totalRequired) {
|
|
29098
|
+
session?.abortTransaction();
|
|
29099
|
+
return {
|
|
29100
|
+
status: "error",
|
|
29101
|
+
message: `Insufficient ${type} access cards. Need ${totalRequired}, but only ${availableCards.length} available.`
|
|
29102
|
+
};
|
|
29103
|
+
}
|
|
29104
|
+
const bulkUpdates = availableCards.map((card, index) => ({
|
|
29105
|
+
updateOne: {
|
|
29106
|
+
filter: { _id: card._id },
|
|
29107
|
+
update: {
|
|
29108
|
+
$set: {
|
|
29109
|
+
assignedUnit: convertedUnits[Math.floor(index / quantity)]
|
|
29110
|
+
}
|
|
29111
|
+
}
|
|
29112
|
+
}
|
|
29113
|
+
}));
|
|
29114
|
+
await collection().bulkWrite(bulkUpdates, { session });
|
|
29115
|
+
session?.commitTransaction();
|
|
29116
|
+
return {
|
|
29117
|
+
status: "success",
|
|
29118
|
+
message: "Cards assigned to units successfully.",
|
|
29119
|
+
assigned: bulkUpdates.length
|
|
29120
|
+
};
|
|
29121
|
+
} catch (error) {
|
|
29122
|
+
session?.abortTransaction();
|
|
29123
|
+
return Promise.reject(error.message);
|
|
29124
|
+
} finally {
|
|
29125
|
+
session?.endSession();
|
|
29126
|
+
}
|
|
29127
|
+
}
|
|
29128
|
+
return {
|
|
29129
|
+
createIndexes,
|
|
29130
|
+
createIndexForEntrypass,
|
|
29131
|
+
addPhysicalCardRepo,
|
|
29132
|
+
addNonPhysicalCardRepo,
|
|
29133
|
+
accessManagementSettingsRepo,
|
|
29134
|
+
allAccessCardsCountsRepo,
|
|
29135
|
+
availableAccessCardsRepo,
|
|
29136
|
+
userTypeAccessCardsRepo,
|
|
29137
|
+
assignedAccessCardsRepo,
|
|
29138
|
+
acknowlegdeCardRepo,
|
|
29139
|
+
accessandLiftCardsRepo,
|
|
29140
|
+
replaceCardRepo,
|
|
29141
|
+
updateNFCStatusRepo,
|
|
29142
|
+
doorAndLiftDropdownRepo,
|
|
29143
|
+
cardReplacementRepo,
|
|
29144
|
+
visitorAccessCardsRepo,
|
|
29145
|
+
getCardReplacementRepo,
|
|
29146
|
+
getAccessManagementSettingsRepo,
|
|
29147
|
+
bulkPhysicalAccessCardRepo,
|
|
29148
|
+
assignAccessCardToUnitRepo
|
|
29149
|
+
};
|
|
29150
|
+
}
|
|
29151
|
+
|
|
29152
|
+
// src/controllers/access-management.controller.ts
|
|
29153
|
+
import Joi85 from "joi";
|
|
28405
29154
|
|
|
28406
29155
|
// src/services/access-management.service.ts
|
|
28407
|
-
import { parseStringPromise } from "xml2js";
|
|
29156
|
+
import { parseStringPromise as parseStringPromise2 } from "xml2js";
|
|
28408
29157
|
import { useCache as useCache47 } from "@7365admin1/node-server-utils";
|
|
29158
|
+
import { Readable } from "stream";
|
|
29159
|
+
import * as xlsx from "xlsx";
|
|
28409
29160
|
var namespace = "cache:acm";
|
|
28410
29161
|
function useAccessManagementSvc() {
|
|
28411
29162
|
const {
|
|
@@ -28416,7 +29167,17 @@ function useAccessManagementSvc() {
|
|
|
28416
29167
|
availableAccessCardsRepo,
|
|
28417
29168
|
userTypeAccessCardsRepo,
|
|
28418
29169
|
assignedAccessCardsRepo,
|
|
28419
|
-
acknowlegdeCardRepo
|
|
29170
|
+
acknowlegdeCardRepo,
|
|
29171
|
+
accessandLiftCardsRepo,
|
|
29172
|
+
replaceCardRepo,
|
|
29173
|
+
updateNFCStatusRepo,
|
|
29174
|
+
doorAndLiftDropdownRepo,
|
|
29175
|
+
cardReplacementRepo,
|
|
29176
|
+
visitorAccessCardsRepo,
|
|
29177
|
+
getCardReplacementRepo,
|
|
29178
|
+
getAccessManagementSettingsRepo,
|
|
29179
|
+
bulkPhysicalAccessCardRepo,
|
|
29180
|
+
assignAccessCardToUnitRepo
|
|
28420
29181
|
} = UseAccessManagementRepo();
|
|
28421
29182
|
const addPhysicalCardSvc = async (payload) => {
|
|
28422
29183
|
try {
|
|
@@ -28458,7 +29219,7 @@ function useAccessManagementSvc() {
|
|
|
28458
29219
|
}
|
|
28459
29220
|
const command = readTemplate("door-levels");
|
|
28460
29221
|
const response = await sendCommand(command, params.acm_url);
|
|
28461
|
-
const res = await
|
|
29222
|
+
const res = await parseStringPromise2(response, { explicitArray: false });
|
|
28462
29223
|
const format = await formatDoorAccessLevels(res);
|
|
28463
29224
|
await setCache({ key, data: format, ttlSeconds: 60, redis });
|
|
28464
29225
|
redis.lrem(listKey, 0, key).then(() => redis.lpush(listKey, key)).then(() => redis.ltrim(listKey, 0, 9)).catch(console.error);
|
|
@@ -28481,7 +29242,7 @@ function useAccessManagementSvc() {
|
|
|
28481
29242
|
}
|
|
28482
29243
|
const command = readTemplate("lift-levels");
|
|
28483
29244
|
const response = await sendCommand(command, params.acm_url);
|
|
28484
|
-
const res = await
|
|
29245
|
+
const res = await parseStringPromise2(response, { explicitArray: false });
|
|
28485
29246
|
const format = await formatLiftAccessLevels(res);
|
|
28486
29247
|
await setCache({ key, data: format, ttlSeconds: 60, redis });
|
|
28487
29248
|
redis.lrem(listKey, 0, key).then(() => redis.lpush(listKey, key)).then(() => redis.ltrim(listKey, 0, 9)).catch(console.error);
|
|
@@ -28504,7 +29265,7 @@ function useAccessManagementSvc() {
|
|
|
28504
29265
|
}
|
|
28505
29266
|
const command = readTemplate("access-group");
|
|
28506
29267
|
const response = await sendCommand(command, params.acm_url);
|
|
28507
|
-
const res = await
|
|
29268
|
+
const res = await parseStringPromise2(response, { explicitArray: false });
|
|
28508
29269
|
const format = await formatAccessGroup(res);
|
|
28509
29270
|
await setCache({ key, data: format, ttlSeconds: 60, redis });
|
|
28510
29271
|
redis.lrem(listKey, 0, key).then(() => redis.lpush(listKey, key)).then(() => redis.ltrim(listKey, 0, 9)).catch(console.error);
|
|
@@ -28513,49 +29274,152 @@ function useAccessManagementSvc() {
|
|
|
28513
29274
|
throw new Error(err.message);
|
|
28514
29275
|
}
|
|
28515
29276
|
};
|
|
28516
|
-
const accessManagementSettingsSvc = async (settings) => {
|
|
29277
|
+
const accessManagementSettingsSvc = async (settings) => {
|
|
29278
|
+
try {
|
|
29279
|
+
const response = await accessManagementSettingsRepo({ ...settings });
|
|
29280
|
+
return response;
|
|
29281
|
+
} catch (err) {
|
|
29282
|
+
throw new Error(err.message);
|
|
29283
|
+
}
|
|
29284
|
+
};
|
|
29285
|
+
const allAccessCardsCountsSvc = async (params) => {
|
|
29286
|
+
try {
|
|
29287
|
+
const response = await allAccessCardsCountsRepo({ ...params });
|
|
29288
|
+
return response;
|
|
29289
|
+
} catch (err) {
|
|
29290
|
+
throw new Error(err.message);
|
|
29291
|
+
}
|
|
29292
|
+
};
|
|
29293
|
+
const availableAccessCardsSvc = async (params) => {
|
|
29294
|
+
try {
|
|
29295
|
+
const response = await availableAccessCardsRepo({ ...params });
|
|
29296
|
+
return response;
|
|
29297
|
+
} catch (err) {
|
|
29298
|
+
throw new Error(err.message);
|
|
29299
|
+
}
|
|
29300
|
+
};
|
|
29301
|
+
const userTypeAccessCardsSvc = async (params) => {
|
|
29302
|
+
try {
|
|
29303
|
+
const response = await userTypeAccessCardsRepo({ ...params });
|
|
29304
|
+
return response;
|
|
29305
|
+
} catch (err) {
|
|
29306
|
+
throw new Error(err.message);
|
|
29307
|
+
}
|
|
29308
|
+
};
|
|
29309
|
+
const assignedAccessCardsSvc = async (params) => {
|
|
29310
|
+
try {
|
|
29311
|
+
const response = await assignedAccessCardsRepo({ ...params });
|
|
29312
|
+
return response;
|
|
29313
|
+
} catch (err) {
|
|
29314
|
+
throw new Error(err.message);
|
|
29315
|
+
}
|
|
29316
|
+
};
|
|
29317
|
+
const acknowlegdeCardSvc = async (params) => {
|
|
29318
|
+
try {
|
|
29319
|
+
const response = await acknowlegdeCardRepo({ ...params });
|
|
29320
|
+
return response;
|
|
29321
|
+
} catch (err) {
|
|
29322
|
+
throw new Error(err.message);
|
|
29323
|
+
}
|
|
29324
|
+
};
|
|
29325
|
+
const accessandLiftCardsSvc = async (params) => {
|
|
29326
|
+
try {
|
|
29327
|
+
const response = await accessandLiftCardsRepo({ ...params });
|
|
29328
|
+
return response;
|
|
29329
|
+
} catch (err) {
|
|
29330
|
+
throw new Error(err.message);
|
|
29331
|
+
}
|
|
29332
|
+
};
|
|
29333
|
+
const replaceCardSvc = async (params) => {
|
|
29334
|
+
try {
|
|
29335
|
+
const response = await replaceCardRepo({ ...params });
|
|
29336
|
+
return response;
|
|
29337
|
+
} catch (err) {
|
|
29338
|
+
throw new Error(err.message);
|
|
29339
|
+
}
|
|
29340
|
+
};
|
|
29341
|
+
const updateNFCStatusSvc = async (params) => {
|
|
28517
29342
|
try {
|
|
28518
|
-
const response = await
|
|
29343
|
+
const response = await updateNFCStatusRepo({ ...params });
|
|
28519
29344
|
return response;
|
|
28520
29345
|
} catch (err) {
|
|
28521
29346
|
throw new Error(err.message);
|
|
28522
29347
|
}
|
|
28523
29348
|
};
|
|
28524
|
-
const
|
|
29349
|
+
const doorAndLiftDropdownSvc = async (params) => {
|
|
28525
29350
|
try {
|
|
28526
|
-
const response = await
|
|
29351
|
+
const response = await doorAndLiftDropdownRepo({ ...params });
|
|
28527
29352
|
return response;
|
|
28528
29353
|
} catch (err) {
|
|
28529
29354
|
throw new Error(err.message);
|
|
28530
29355
|
}
|
|
28531
29356
|
};
|
|
28532
|
-
const
|
|
29357
|
+
const cardReplacementSvc = async (params) => {
|
|
28533
29358
|
try {
|
|
28534
|
-
const response = await
|
|
29359
|
+
const response = await cardReplacementRepo({ ...params });
|
|
28535
29360
|
return response;
|
|
28536
29361
|
} catch (err) {
|
|
28537
29362
|
throw new Error(err.message);
|
|
28538
29363
|
}
|
|
28539
29364
|
};
|
|
28540
|
-
const
|
|
29365
|
+
const visitorAccessCardsSvc = async (params) => {
|
|
28541
29366
|
try {
|
|
28542
|
-
const response = await
|
|
29367
|
+
const response = await visitorAccessCardsRepo({ ...params });
|
|
28543
29368
|
return response;
|
|
28544
29369
|
} catch (err) {
|
|
28545
29370
|
throw new Error(err.message);
|
|
28546
29371
|
}
|
|
28547
29372
|
};
|
|
28548
|
-
const
|
|
29373
|
+
const getCardReplacementSvc = async (params) => {
|
|
28549
29374
|
try {
|
|
28550
|
-
const response = await
|
|
29375
|
+
const response = await getCardReplacementRepo({ ...params });
|
|
28551
29376
|
return response;
|
|
28552
29377
|
} catch (err) {
|
|
28553
29378
|
throw new Error(err.message);
|
|
28554
29379
|
}
|
|
28555
29380
|
};
|
|
28556
|
-
const
|
|
29381
|
+
const getAccessManagementSettingsSvc = async (params) => {
|
|
28557
29382
|
try {
|
|
28558
|
-
const response = await
|
|
29383
|
+
const response = await getAccessManagementSettingsRepo({ ...params });
|
|
29384
|
+
return response;
|
|
29385
|
+
} catch (err) {
|
|
29386
|
+
throw new Error(err.message);
|
|
29387
|
+
}
|
|
29388
|
+
};
|
|
29389
|
+
const convertBufferFile = async (bufferFile) => {
|
|
29390
|
+
return new Promise((resolve, reject) => {
|
|
29391
|
+
const fileStream = Readable.from(bufferFile);
|
|
29392
|
+
let fileBuffer = Buffer.alloc(0);
|
|
29393
|
+
fileStream.on("data", (chunk) => {
|
|
29394
|
+
fileBuffer = Buffer.concat([fileBuffer, chunk]);
|
|
29395
|
+
});
|
|
29396
|
+
fileStream.on("end", () => {
|
|
29397
|
+
try {
|
|
29398
|
+
const workbook = xlsx.read(fileBuffer, { type: "buffer" });
|
|
29399
|
+
const sheetName = workbook.SheetNames[0];
|
|
29400
|
+
const sheet = workbook.Sheets[sheetName];
|
|
29401
|
+
const jsonData = xlsx.utils.sheet_to_json(sheet, { raw: false });
|
|
29402
|
+
resolve(jsonData);
|
|
29403
|
+
} catch (error) {
|
|
29404
|
+
reject("Error parsing file");
|
|
29405
|
+
}
|
|
29406
|
+
});
|
|
29407
|
+
fileStream.on("error", (err) => {
|
|
29408
|
+
reject("Error Reading File: " + err.message);
|
|
29409
|
+
});
|
|
29410
|
+
});
|
|
29411
|
+
};
|
|
29412
|
+
const bulkPhysicalAccessCardSvc = async (params) => {
|
|
29413
|
+
try {
|
|
29414
|
+
const response = await bulkPhysicalAccessCardRepo({ ...params });
|
|
29415
|
+
return response;
|
|
29416
|
+
} catch (err) {
|
|
29417
|
+
throw new Error(err.message);
|
|
29418
|
+
}
|
|
29419
|
+
};
|
|
29420
|
+
const assignAccessCardToUnitSvc = async (params) => {
|
|
29421
|
+
try {
|
|
29422
|
+
const response = await assignAccessCardToUnitRepo({ ...params });
|
|
28559
29423
|
return response;
|
|
28560
29424
|
} catch (err) {
|
|
28561
29425
|
throw new Error(err.message);
|
|
@@ -28567,16 +29431,31 @@ function useAccessManagementSvc() {
|
|
|
28567
29431
|
doorAccessLevelsSvc,
|
|
28568
29432
|
liftAccessLevelsSvc,
|
|
28569
29433
|
accessGroupsSvc,
|
|
29434
|
+
setCache,
|
|
29435
|
+
getCache,
|
|
28570
29436
|
accessManagementSettingsSvc,
|
|
28571
29437
|
allAccessCardsCountsSvc,
|
|
28572
29438
|
availableAccessCardsSvc,
|
|
28573
29439
|
userTypeAccessCardsSvc,
|
|
28574
29440
|
assignedAccessCardsSvc,
|
|
28575
|
-
acknowlegdeCardSvc
|
|
29441
|
+
acknowlegdeCardSvc,
|
|
29442
|
+
accessandLiftCardsSvc,
|
|
29443
|
+
replaceCardSvc,
|
|
29444
|
+
updateNFCStatusSvc,
|
|
29445
|
+
doorAndLiftDropdownSvc,
|
|
29446
|
+
cardReplacementSvc,
|
|
29447
|
+
visitorAccessCardsSvc,
|
|
29448
|
+
getCardReplacementSvc,
|
|
29449
|
+
getAccessManagementSettingsSvc,
|
|
29450
|
+
convertBufferFile,
|
|
29451
|
+
bulkPhysicalAccessCardSvc,
|
|
29452
|
+
assignAccessCardToUnitSvc
|
|
28576
29453
|
};
|
|
28577
29454
|
}
|
|
28578
29455
|
|
|
28579
29456
|
// src/controllers/access-management.controller.ts
|
|
29457
|
+
import { useCache as useCache48 } from "@7365admin1/node-server-utils";
|
|
29458
|
+
var namespace2 = "cache:acm";
|
|
28580
29459
|
function useAccessManagementController() {
|
|
28581
29460
|
const {
|
|
28582
29461
|
addPhysicalCardSvc,
|
|
@@ -28584,12 +29463,25 @@ function useAccessManagementController() {
|
|
|
28584
29463
|
doorAccessLevelsSvc,
|
|
28585
29464
|
liftAccessLevelsSvc,
|
|
28586
29465
|
accessGroupsSvc,
|
|
29466
|
+
setCache,
|
|
29467
|
+
getCache,
|
|
28587
29468
|
accessManagementSettingsSvc,
|
|
28588
29469
|
allAccessCardsCountsSvc,
|
|
28589
29470
|
availableAccessCardsSvc,
|
|
28590
29471
|
userTypeAccessCardsSvc,
|
|
28591
29472
|
assignedAccessCardsSvc,
|
|
28592
|
-
acknowlegdeCardSvc
|
|
29473
|
+
acknowlegdeCardSvc,
|
|
29474
|
+
accessandLiftCardsSvc,
|
|
29475
|
+
replaceCardSvc,
|
|
29476
|
+
updateNFCStatusSvc,
|
|
29477
|
+
doorAndLiftDropdownSvc,
|
|
29478
|
+
cardReplacementSvc,
|
|
29479
|
+
visitorAccessCardsSvc,
|
|
29480
|
+
getCardReplacementSvc,
|
|
29481
|
+
getAccessManagementSettingsSvc,
|
|
29482
|
+
convertBufferFile,
|
|
29483
|
+
bulkPhysicalAccessCardSvc,
|
|
29484
|
+
assignAccessCardToUnitSvc
|
|
28593
29485
|
} = useAccessManagementSvc();
|
|
28594
29486
|
const addPhysicalCard = async (req, res) => {
|
|
28595
29487
|
try {
|
|
@@ -28661,7 +29553,7 @@ function useAccessManagementController() {
|
|
|
28661
29553
|
accessGroup: Joi85.array().items(Joi85.string().required()).required(),
|
|
28662
29554
|
userType: Joi85.string().required(),
|
|
28663
29555
|
doorName: Joi85.string().required(),
|
|
28664
|
-
liftName: Joi85.string().
|
|
29556
|
+
liftName: Joi85.string().optional().allow("", null),
|
|
28665
29557
|
unit: Joi85.array().items(Joi85.string()).optional().allow(null),
|
|
28666
29558
|
startDate: Joi85.date().required(),
|
|
28667
29559
|
endDate: Joi85.date().required(),
|
|
@@ -28780,6 +29672,7 @@ function useAccessManagementController() {
|
|
|
28780
29672
|
const allAccessCardsCounts = async (req, res) => {
|
|
28781
29673
|
try {
|
|
28782
29674
|
const { site, userType } = req.query;
|
|
29675
|
+
const user = req.cookies?.sid;
|
|
28783
29676
|
const schema2 = Joi85.object({
|
|
28784
29677
|
site: Joi85.string().hex().required(),
|
|
28785
29678
|
userType: Joi85.string().required()
|
|
@@ -28788,7 +29681,19 @@ function useAccessManagementController() {
|
|
|
28788
29681
|
if (error) {
|
|
28789
29682
|
throw new Error(`${error.message}`);
|
|
28790
29683
|
}
|
|
29684
|
+
const key = `${namespace2}:${user}:access-card-counts`;
|
|
29685
|
+
const listKey = `${namespace2}:${user}:list`;
|
|
29686
|
+
const { redis } = useCache48(key);
|
|
29687
|
+
const cachedData = await getCache({ key, redis });
|
|
29688
|
+
if (cachedData) {
|
|
29689
|
+
console.log("\u26A1 Cache hit:", key);
|
|
29690
|
+
redis.expire(key, 60).catch(console.error);
|
|
29691
|
+
redis.lrem(listKey, 0, key).then(() => redis.lpush(listKey, key)).then(() => redis.ltrim(listKey, 0, 9)).catch(console.error);
|
|
29692
|
+
return res.status(200).json({ message: "Success", data: cachedData });
|
|
29693
|
+
}
|
|
28791
29694
|
const result = await allAccessCardsCountsSvc({ site, userType });
|
|
29695
|
+
await setCache({ key, data: result, ttlSeconds: 60, redis });
|
|
29696
|
+
redis.lrem(listKey, 0, key).then(() => redis.lpush(listKey, key)).then(() => redis.ltrim(listKey, 0, 9)).catch(console.error);
|
|
28792
29697
|
return res.status(200).json({ message: "Success", data: result });
|
|
28793
29698
|
} catch (error) {
|
|
28794
29699
|
return res.status(400).json({
|
|
@@ -28892,6 +29797,245 @@ function useAccessManagementController() {
|
|
|
28892
29797
|
});
|
|
28893
29798
|
}
|
|
28894
29799
|
};
|
|
29800
|
+
const accessandLiftCards = async (req, res) => {
|
|
29801
|
+
try {
|
|
29802
|
+
const {
|
|
29803
|
+
accessLevel = null,
|
|
29804
|
+
liftAccessLevel = null,
|
|
29805
|
+
site,
|
|
29806
|
+
userType,
|
|
29807
|
+
type
|
|
29808
|
+
} = req.query;
|
|
29809
|
+
const schema2 = Joi85.object({
|
|
29810
|
+
accessLevel: Joi85.string().optional().allow("", null),
|
|
29811
|
+
liftAccessLevel: Joi85.string().optional().allow("", null),
|
|
29812
|
+
site: Joi85.string().hex().required(),
|
|
29813
|
+
userType: Joi85.string().valid(...Object.values(EAccessCardUserTypes)).required(),
|
|
29814
|
+
type: Joi85.string().valid(...Object.values(EAccessCardTypes)).required()
|
|
29815
|
+
});
|
|
29816
|
+
const { error } = schema2.validate({ accessLevel, liftAccessLevel, site, userType, type });
|
|
29817
|
+
if (error) {
|
|
29818
|
+
return res.status(400).json({ message: error.message });
|
|
29819
|
+
}
|
|
29820
|
+
const result = await accessandLiftCardsSvc({ accessLevel, liftAccessLevel, site, userType, type });
|
|
29821
|
+
return res.status(200).json({ message: "Success", data: result });
|
|
29822
|
+
} catch (error) {
|
|
29823
|
+
return res.status(500).json({
|
|
29824
|
+
data: null,
|
|
29825
|
+
message: error.message
|
|
29826
|
+
});
|
|
29827
|
+
}
|
|
29828
|
+
};
|
|
29829
|
+
const replaceCard = async (req, res) => {
|
|
29830
|
+
try {
|
|
29831
|
+
const { userId, cardId, site, acm_url } = req.body;
|
|
29832
|
+
const schema2 = Joi85.object({
|
|
29833
|
+
userId: Joi85.string().required(),
|
|
29834
|
+
cardId: Joi85.string().required(),
|
|
29835
|
+
site: Joi85.string().required(),
|
|
29836
|
+
acm_url: Joi85.string().required()
|
|
29837
|
+
});
|
|
29838
|
+
const { error } = schema2.validate({ userId, cardId, site, acm_url });
|
|
29839
|
+
if (error) {
|
|
29840
|
+
return res.status(400).json({ message: error.message });
|
|
29841
|
+
}
|
|
29842
|
+
const result = await replaceCardSvc({ userId, cardId, site, acm_url });
|
|
29843
|
+
return res.status(200).json({ message: "Success", data: result });
|
|
29844
|
+
} catch (error) {
|
|
29845
|
+
return res.status(500).json({
|
|
29846
|
+
data: null,
|
|
29847
|
+
message: error.message
|
|
29848
|
+
});
|
|
29849
|
+
}
|
|
29850
|
+
};
|
|
29851
|
+
const updateNFCStatus = async (req, res) => {
|
|
29852
|
+
try {
|
|
29853
|
+
const { nfcList = [], visitorId } = req.body;
|
|
29854
|
+
const schema2 = Joi85.object({
|
|
29855
|
+
nfcList: Joi85.array().items({
|
|
29856
|
+
_id: Joi85.string().hex().length(24).required(),
|
|
29857
|
+
status: Joi85.string().required(),
|
|
29858
|
+
vmsRemarks: Joi85.string().allow(null, "").optional(),
|
|
29859
|
+
updatedAt: Joi85.date().optional().allow(null, "")
|
|
29860
|
+
}),
|
|
29861
|
+
visitorId: Joi85.string().optional().allow(null, "")
|
|
29862
|
+
});
|
|
29863
|
+
const { error } = schema2.validate({ nfcList, visitorId });
|
|
29864
|
+
if (error) {
|
|
29865
|
+
return res.status(400).json({ message: error.message });
|
|
29866
|
+
}
|
|
29867
|
+
const result = await updateNFCStatusSvc({ nfcList, visitorId });
|
|
29868
|
+
return res.status(200).json({ message: "Success", data: result });
|
|
29869
|
+
} catch (error) {
|
|
29870
|
+
return res.status(500).json({
|
|
29871
|
+
data: null,
|
|
29872
|
+
message: error.message
|
|
29873
|
+
});
|
|
29874
|
+
}
|
|
29875
|
+
};
|
|
29876
|
+
const doorAndLiftDropdown = async (req, res) => {
|
|
29877
|
+
try {
|
|
29878
|
+
const { site, type, userType } = req.query;
|
|
29879
|
+
const schema2 = Joi85.object({
|
|
29880
|
+
site: Joi85.string().hex().required(),
|
|
29881
|
+
type: Joi85.string().required(),
|
|
29882
|
+
userType: Joi85.string().required()
|
|
29883
|
+
});
|
|
29884
|
+
const { error } = schema2.validate({ site, type, userType });
|
|
29885
|
+
if (error) {
|
|
29886
|
+
return res.status(400).json({ message: error.message });
|
|
29887
|
+
}
|
|
29888
|
+
const result = await doorAndLiftDropdownSvc({ site, type, userType });
|
|
29889
|
+
return res.status(200).json({ message: "Success", data: result });
|
|
29890
|
+
} catch (error) {
|
|
29891
|
+
return res.status(500).json({
|
|
29892
|
+
data: null,
|
|
29893
|
+
message: error.message
|
|
29894
|
+
});
|
|
29895
|
+
}
|
|
29896
|
+
};
|
|
29897
|
+
const cardReplacement = async (req, res) => {
|
|
29898
|
+
try {
|
|
29899
|
+
const { cardId, remarks } = req.body;
|
|
29900
|
+
const schema2 = Joi85.object({
|
|
29901
|
+
cardId: Joi85.string().required(),
|
|
29902
|
+
remarks: Joi85.string().optional().allow("", null)
|
|
29903
|
+
});
|
|
29904
|
+
const { error } = schema2.validate({ cardId, remarks });
|
|
29905
|
+
if (error) {
|
|
29906
|
+
return res.status(400).json({ message: error.message });
|
|
29907
|
+
}
|
|
29908
|
+
const result = await cardReplacementSvc({ cardId, remarks });
|
|
29909
|
+
return res.status(200).json({ message: "Success", data: result });
|
|
29910
|
+
} catch (error) {
|
|
29911
|
+
return res.status(500).json({
|
|
29912
|
+
data: null,
|
|
29913
|
+
message: error.message
|
|
29914
|
+
});
|
|
29915
|
+
}
|
|
29916
|
+
};
|
|
29917
|
+
const visitorAccessCards = async (req, res) => {
|
|
29918
|
+
try {
|
|
29919
|
+
const {
|
|
29920
|
+
page = 1,
|
|
29921
|
+
limit = 10,
|
|
29922
|
+
search,
|
|
29923
|
+
type,
|
|
29924
|
+
site
|
|
29925
|
+
} = req.query;
|
|
29926
|
+
const schema2 = Joi85.object({
|
|
29927
|
+
site: Joi85.string().hex().required(),
|
|
29928
|
+
page: Joi85.number().required(),
|
|
29929
|
+
limit: Joi85.number().optional().default(10),
|
|
29930
|
+
type: Joi85.string().required().valid(...Object.values(EAccessCardUserTypes)),
|
|
29931
|
+
search: Joi85.string().optional().allow("", null)
|
|
29932
|
+
});
|
|
29933
|
+
const { error } = schema2.validate({ site, page, limit, type, search });
|
|
29934
|
+
if (error) {
|
|
29935
|
+
return res.status(400).json({ message: error.message });
|
|
29936
|
+
}
|
|
29937
|
+
const result = await visitorAccessCardsSvc({ site, page, limit, type, search });
|
|
29938
|
+
return res.status(200).json({ message: "Success", data: result });
|
|
29939
|
+
} catch (error) {
|
|
29940
|
+
return res.status(500).json({
|
|
29941
|
+
data: null,
|
|
29942
|
+
message: error.message
|
|
29943
|
+
});
|
|
29944
|
+
}
|
|
29945
|
+
};
|
|
29946
|
+
const getCardReplacement = async (req, res) => {
|
|
29947
|
+
try {
|
|
29948
|
+
const site = req.params.site;
|
|
29949
|
+
const {
|
|
29950
|
+
search,
|
|
29951
|
+
statusFilter,
|
|
29952
|
+
dateFrom,
|
|
29953
|
+
dateTo,
|
|
29954
|
+
page = 0,
|
|
29955
|
+
limit = 10
|
|
29956
|
+
} = req.query;
|
|
29957
|
+
const schema2 = Joi85.object({
|
|
29958
|
+
search: Joi85.string().optional().allow("", null),
|
|
29959
|
+
statusFilter: Joi85.string().optional().allow("", null),
|
|
29960
|
+
dateFrom: Joi85.date().optional().allow("", null),
|
|
29961
|
+
dateTo: Joi85.date().optional().allow("", null),
|
|
29962
|
+
page: Joi85.number().optional().default(0),
|
|
29963
|
+
limit: Joi85.number().optional().default(10),
|
|
29964
|
+
site: Joi85.string().hex().required()
|
|
29965
|
+
});
|
|
29966
|
+
const { error } = schema2.validate({ search, statusFilter, dateFrom, dateTo, page, limit, site });
|
|
29967
|
+
if (error) {
|
|
29968
|
+
return res.status(400).json({ message: error.message });
|
|
29969
|
+
}
|
|
29970
|
+
const result = await getCardReplacementSvc({ site, page, limit, search, statusFilter, dateFrom, dateTo });
|
|
29971
|
+
return res.status(200).json({ message: "Success", data: result });
|
|
29972
|
+
} catch (error) {
|
|
29973
|
+
return res.status(500).json({
|
|
29974
|
+
data: null,
|
|
29975
|
+
message: error.message
|
|
29976
|
+
});
|
|
29977
|
+
}
|
|
29978
|
+
};
|
|
29979
|
+
const getAccessManagementSettings = async (req, res) => {
|
|
29980
|
+
try {
|
|
29981
|
+
const { site } = req.params;
|
|
29982
|
+
const schema2 = Joi85.object({
|
|
29983
|
+
site: Joi85.string().hex().required()
|
|
29984
|
+
});
|
|
29985
|
+
const { error } = schema2.validate({ site });
|
|
29986
|
+
if (error) {
|
|
29987
|
+
return res.status(400).json({ message: error.message });
|
|
29988
|
+
}
|
|
29989
|
+
const result = await getAccessManagementSettingsSvc({ site });
|
|
29990
|
+
return res.status(200).json({ message: "Success", data: result });
|
|
29991
|
+
} catch (error) {
|
|
29992
|
+
return res.status(500).json({
|
|
29993
|
+
data: null,
|
|
29994
|
+
message: error.message
|
|
29995
|
+
});
|
|
29996
|
+
}
|
|
29997
|
+
};
|
|
29998
|
+
const bulkPhysicalAccessCard = async (req, res) => {
|
|
29999
|
+
try {
|
|
30000
|
+
const { site } = req.query;
|
|
30001
|
+
if (!req.file)
|
|
30002
|
+
throw new Error("File is required!");
|
|
30003
|
+
const xlsData = await convertBufferFile(req.file.buffer);
|
|
30004
|
+
const dataJson = JSON.stringify(xlsData);
|
|
30005
|
+
const result = await bulkPhysicalAccessCardSvc({ dataJson, site });
|
|
30006
|
+
return res.status(200).json({ message: "Success", data: result });
|
|
30007
|
+
} catch (error) {
|
|
30008
|
+
return res.status(500).json({
|
|
30009
|
+
data: null,
|
|
30010
|
+
message: error.message
|
|
30011
|
+
});
|
|
30012
|
+
}
|
|
30013
|
+
};
|
|
30014
|
+
const assignAccessCardToUnit = async (req, res) => {
|
|
30015
|
+
try {
|
|
30016
|
+
const { units, type, quantity, site, userType, accessLevel, liftAccessLevel } = req.body;
|
|
30017
|
+
const schema2 = Joi85.object({
|
|
30018
|
+
units: Joi85.array().items(Joi85.string().hex()).required(),
|
|
30019
|
+
quantity: Joi85.number().required(),
|
|
30020
|
+
type: Joi85.string().required(),
|
|
30021
|
+
site: Joi85.string().hex().required(),
|
|
30022
|
+
userType: Joi85.string().required(),
|
|
30023
|
+
accessLevel: Joi85.string().optional().allow("", null),
|
|
30024
|
+
liftAccessLevel: Joi85.string().optional().allow("", null)
|
|
30025
|
+
});
|
|
30026
|
+
const { error } = schema2.validate({ units, quantity, type, site, userType, accessLevel, liftAccessLevel });
|
|
30027
|
+
if (error) {
|
|
30028
|
+
return res.status(400).json({ message: error.message });
|
|
30029
|
+
}
|
|
30030
|
+
const result = await assignAccessCardToUnitSvc({ units, quantity, type, site, userType, accessLevel, liftAccessLevel });
|
|
30031
|
+
return res.status(200).json({ message: "Success", data: result });
|
|
30032
|
+
} catch (error) {
|
|
30033
|
+
return res.status(500).json({
|
|
30034
|
+
data: null,
|
|
30035
|
+
message: error.message
|
|
30036
|
+
});
|
|
30037
|
+
}
|
|
30038
|
+
};
|
|
28895
30039
|
return {
|
|
28896
30040
|
addPhysicalCard,
|
|
28897
30041
|
addNonPhysicalCard,
|
|
@@ -28903,7 +30047,17 @@ function useAccessManagementController() {
|
|
|
28903
30047
|
availableAccessCards,
|
|
28904
30048
|
userTypeAccessCards,
|
|
28905
30049
|
assignedAccessCards,
|
|
28906
|
-
acknowlegdeCard
|
|
30050
|
+
acknowlegdeCard,
|
|
30051
|
+
accessandLiftCards,
|
|
30052
|
+
replaceCard,
|
|
30053
|
+
updateNFCStatus,
|
|
30054
|
+
doorAndLiftDropdown,
|
|
30055
|
+
cardReplacement,
|
|
30056
|
+
visitorAccessCards,
|
|
30057
|
+
getCardReplacement,
|
|
30058
|
+
getAccessManagementSettings,
|
|
30059
|
+
bulkPhysicalAccessCard,
|
|
30060
|
+
assignAccessCardToUnit
|
|
28907
30061
|
};
|
|
28908
30062
|
}
|
|
28909
30063
|
|
|
@@ -28973,7 +30127,7 @@ import {
|
|
|
28973
30127
|
makeCacheKey as makeCacheKey45,
|
|
28974
30128
|
paginate as paginate39,
|
|
28975
30129
|
useAtlas as useAtlas75,
|
|
28976
|
-
useCache as
|
|
30130
|
+
useCache as useCache49
|
|
28977
30131
|
} from "@7365admin1/node-server-utils";
|
|
28978
30132
|
import { ObjectId as ObjectId85 } from "mongodb";
|
|
28979
30133
|
function useNfcPatrolTagRepo() {
|
|
@@ -28984,8 +30138,8 @@ function useNfcPatrolTagRepo() {
|
|
|
28984
30138
|
const namespace_collection = "nfc-patrol-tags";
|
|
28985
30139
|
const namespace_collection_nfc_patrol_routes = "nfc-patrol-routes";
|
|
28986
30140
|
const collection = db.collection(namespace_collection);
|
|
28987
|
-
const { delNamespace, getCache, setCache } =
|
|
28988
|
-
const { delNamespace: delNamespaceNfcPatrolRoutes } =
|
|
30141
|
+
const { delNamespace, getCache, setCache } = useCache49(namespace_collection);
|
|
30142
|
+
const { delNamespace: delNamespaceNfcPatrolRoutes } = useCache49(
|
|
28989
30143
|
namespace_collection_nfc_patrol_routes
|
|
28990
30144
|
);
|
|
28991
30145
|
async function createIndexes() {
|
|
@@ -29432,7 +30586,7 @@ import {
|
|
|
29432
30586
|
NotFoundError as NotFoundError37,
|
|
29433
30587
|
paginate as paginate40,
|
|
29434
30588
|
useAtlas as useAtlas77,
|
|
29435
|
-
useCache as
|
|
30589
|
+
useCache as useCache50
|
|
29436
30590
|
} from "@7365admin1/node-server-utils";
|
|
29437
30591
|
import { ObjectId as ObjectId87 } from "mongodb";
|
|
29438
30592
|
function useOccurrenceBookRepo() {
|
|
@@ -29464,7 +30618,7 @@ function useOccurrenceBookRepo() {
|
|
|
29464
30618
|
}
|
|
29465
30619
|
const namespace_collection = "occurrence-books";
|
|
29466
30620
|
const collection = db.collection(namespace_collection);
|
|
29467
|
-
const { delNamespace, getCache, setCache } =
|
|
30621
|
+
const { delNamespace, getCache, setCache } = useCache50(namespace_collection);
|
|
29468
30622
|
async function add(value, session) {
|
|
29469
30623
|
try {
|
|
29470
30624
|
value = MOccurrenceBook(value);
|
|
@@ -30042,7 +31196,7 @@ import {
|
|
|
30042
31196
|
NotFoundError as NotFoundError38,
|
|
30043
31197
|
paginate as paginate41,
|
|
30044
31198
|
useAtlas as useAtlas79,
|
|
30045
|
-
useCache as
|
|
31199
|
+
useCache as useCache51
|
|
30046
31200
|
} from "@7365admin1/node-server-utils";
|
|
30047
31201
|
import { ObjectId as ObjectId89 } from "mongodb";
|
|
30048
31202
|
function useBulletinVideoRepo() {
|
|
@@ -30061,7 +31215,7 @@ function useBulletinVideoRepo() {
|
|
|
30061
31215
|
}
|
|
30062
31216
|
const namespace_collection = "bulletin-videos";
|
|
30063
31217
|
const collection = db.collection(namespace_collection);
|
|
30064
|
-
const { delNamespace, getCache, setCache } =
|
|
31218
|
+
const { delNamespace, getCache, setCache } = useCache51(namespace_collection);
|
|
30065
31219
|
async function add(value, session) {
|
|
30066
31220
|
try {
|
|
30067
31221
|
value = MBulletinVideo(value);
|
|
@@ -30593,7 +31747,7 @@ import {
|
|
|
30593
31747
|
InternalServerError as InternalServerError51,
|
|
30594
31748
|
logger as logger127,
|
|
30595
31749
|
useAtlas as useAtlas81,
|
|
30596
|
-
useCache as
|
|
31750
|
+
useCache as useCache52,
|
|
30597
31751
|
paginate as paginate42,
|
|
30598
31752
|
makeCacheKey as makeCacheKey48
|
|
30599
31753
|
} from "@7365admin1/node-server-utils";
|
|
@@ -30605,7 +31759,7 @@ function useStatementOfAccountRepo() {
|
|
|
30605
31759
|
}
|
|
30606
31760
|
const namespace_collection = "site.statement-of-accounts";
|
|
30607
31761
|
const collection = db.collection(namespace_collection);
|
|
30608
|
-
const { delNamespace, getCache, setCache } =
|
|
31762
|
+
const { delNamespace, getCache, setCache } = useCache52(namespace_collection);
|
|
30609
31763
|
async function createTextIndex() {
|
|
30610
31764
|
try {
|
|
30611
31765
|
await collection.createIndex({
|
|
@@ -31368,7 +32522,7 @@ import {
|
|
|
31368
32522
|
NotFoundError as NotFoundError40,
|
|
31369
32523
|
paginate as paginate43,
|
|
31370
32524
|
useAtlas as useAtlas83,
|
|
31371
|
-
useCache as
|
|
32525
|
+
useCache as useCache53
|
|
31372
32526
|
} from "@7365admin1/node-server-utils";
|
|
31373
32527
|
import { ObjectId as ObjectId93 } from "mongodb";
|
|
31374
32528
|
function useEntryPassSettingsRepo() {
|
|
@@ -31378,7 +32532,7 @@ function useEntryPassSettingsRepo() {
|
|
|
31378
32532
|
}
|
|
31379
32533
|
const namespace_collection = "site.entrypass-settings";
|
|
31380
32534
|
const collection = db.collection(namespace_collection);
|
|
31381
|
-
const { delNamespace, getCache, setCache } =
|
|
32535
|
+
const { delNamespace, getCache, setCache } = useCache53(namespace_collection);
|
|
31382
32536
|
async function createTextIndex() {
|
|
31383
32537
|
try {
|
|
31384
32538
|
await collection.createIndex({
|
|
@@ -31940,7 +33094,7 @@ import {
|
|
|
31940
33094
|
logger as logger133,
|
|
31941
33095
|
makeCacheKey as makeCacheKey50,
|
|
31942
33096
|
useAtlas as useAtlas84,
|
|
31943
|
-
useCache as
|
|
33097
|
+
useCache as useCache54
|
|
31944
33098
|
} from "@7365admin1/node-server-utils";
|
|
31945
33099
|
function useDashboardRepo() {
|
|
31946
33100
|
const db = useAtlas84.getDb();
|
|
@@ -31951,7 +33105,7 @@ function useDashboardRepo() {
|
|
|
31951
33105
|
const work_order_collection = db.collection("work-orders");
|
|
31952
33106
|
const visitor_collection = db.collection("visitor.transactions");
|
|
31953
33107
|
const namespace_collection = "dashboard";
|
|
31954
|
-
const { delNamespace, getCache, setCache } =
|
|
33108
|
+
const { delNamespace, getCache, setCache } = useCache54(namespace_collection);
|
|
31955
33109
|
async function getAll({
|
|
31956
33110
|
site = ""
|
|
31957
33111
|
}, session) {
|
|
@@ -32115,7 +33269,7 @@ import {
|
|
|
32115
33269
|
makeCacheKey as makeCacheKey51,
|
|
32116
33270
|
paginate as paginate44,
|
|
32117
33271
|
useAtlas as useAtlas85,
|
|
32118
|
-
useCache as
|
|
33272
|
+
useCache as useCache55
|
|
32119
33273
|
} from "@7365admin1/node-server-utils";
|
|
32120
33274
|
import { ObjectId as ObjectId95 } from "mongodb";
|
|
32121
33275
|
function useNfcPatrolRouteRepo() {
|
|
@@ -32125,7 +33279,7 @@ function useNfcPatrolRouteRepo() {
|
|
|
32125
33279
|
}
|
|
32126
33280
|
const namespace_collection = "nfc-patrol-routes";
|
|
32127
33281
|
const collection = db.collection(namespace_collection);
|
|
32128
|
-
const { delNamespace, getCache, setCache } =
|
|
33282
|
+
const { delNamespace, getCache, setCache } = useCache55(namespace_collection);
|
|
32129
33283
|
async function createIndexes() {
|
|
32130
33284
|
try {
|
|
32131
33285
|
await collection.createIndexes([
|
|
@@ -32862,7 +34016,7 @@ import {
|
|
|
32862
34016
|
NotFoundError as NotFoundError43,
|
|
32863
34017
|
paginate as paginate45,
|
|
32864
34018
|
useAtlas as useAtlas87,
|
|
32865
|
-
useCache as
|
|
34019
|
+
useCache as useCache56
|
|
32866
34020
|
} from "@7365admin1/node-server-utils";
|
|
32867
34021
|
import { ObjectId as ObjectId97 } from "mongodb";
|
|
32868
34022
|
function useIncidentReportRepo() {
|
|
@@ -32893,7 +34047,7 @@ function useIncidentReportRepo() {
|
|
|
32893
34047
|
}
|
|
32894
34048
|
const namespace_collection = "incident-reports";
|
|
32895
34049
|
const collection = db.collection(namespace_collection);
|
|
32896
|
-
const { delNamespace, getCache, setCache } =
|
|
34050
|
+
const { delNamespace, getCache, setCache } = useCache56(namespace_collection);
|
|
32897
34051
|
async function add(value, session) {
|
|
32898
34052
|
try {
|
|
32899
34053
|
value = MIncidentReport(value);
|
|
@@ -33634,7 +34788,7 @@ import {
|
|
|
33634
34788
|
makeCacheKey as makeCacheKey53,
|
|
33635
34789
|
NotFoundError as NotFoundError45,
|
|
33636
34790
|
useAtlas as useAtlas89,
|
|
33637
|
-
useCache as
|
|
34791
|
+
useCache as useCache57
|
|
33638
34792
|
} from "@7365admin1/node-server-utils";
|
|
33639
34793
|
import { ObjectId as ObjectId99 } from "mongodb";
|
|
33640
34794
|
function useNfcPatrolSettingsRepository() {
|
|
@@ -33644,7 +34798,7 @@ function useNfcPatrolSettingsRepository() {
|
|
|
33644
34798
|
}
|
|
33645
34799
|
const namespace_collection = "site.nfc-patrol-settings";
|
|
33646
34800
|
const collection = db.collection(namespace_collection);
|
|
33647
|
-
const { delNamespace, setCache, getCache } =
|
|
34801
|
+
const { delNamespace, setCache, getCache } = useCache57(namespace_collection);
|
|
33648
34802
|
async function createIndexes() {
|
|
33649
34803
|
try {
|
|
33650
34804
|
await collection.createIndexes([{ key: { site: 1 }, unique: true }]);
|
|
@@ -33889,7 +35043,7 @@ import {
|
|
|
33889
35043
|
NotFoundError as NotFoundError46,
|
|
33890
35044
|
paginate as paginate46,
|
|
33891
35045
|
useAtlas as useAtlas91,
|
|
33892
|
-
useCache as
|
|
35046
|
+
useCache as useCache58
|
|
33893
35047
|
} from "@7365admin1/node-server-utils";
|
|
33894
35048
|
|
|
33895
35049
|
// src/models/occurrence-subject.model.ts
|
|
@@ -33966,7 +35120,7 @@ function useOccurrenceSubjectRepo() {
|
|
|
33966
35120
|
}
|
|
33967
35121
|
const namespace_collection = "occurrence-subjects";
|
|
33968
35122
|
const collection = db.collection(namespace_collection);
|
|
33969
|
-
const { delNamespace, getCache, setCache } =
|
|
35123
|
+
const { delNamespace, getCache, setCache } = useCache58(namespace_collection);
|
|
33970
35124
|
async function add(value, session) {
|
|
33971
35125
|
try {
|
|
33972
35126
|
value = MOccurrenceSubject(value);
|
|
@@ -34534,7 +35688,7 @@ import {
|
|
|
34534
35688
|
NotFoundError as NotFoundError47,
|
|
34535
35689
|
paginate as paginate47,
|
|
34536
35690
|
useAtlas as useAtlas93,
|
|
34537
|
-
useCache as
|
|
35691
|
+
useCache as useCache59
|
|
34538
35692
|
} from "@7365admin1/node-server-utils";
|
|
34539
35693
|
import { ObjectId as ObjectId103 } from "mongodb";
|
|
34540
35694
|
function useOnlineFormRepo() {
|
|
@@ -34544,7 +35698,7 @@ function useOnlineFormRepo() {
|
|
|
34544
35698
|
}
|
|
34545
35699
|
const namespace_collection = "online-forms";
|
|
34546
35700
|
const collection = db.collection(namespace_collection);
|
|
34547
|
-
const { delNamespace, getCache, setCache } =
|
|
35701
|
+
const { delNamespace, getCache, setCache } = useCache59(namespace_collection);
|
|
34548
35702
|
async function createTextIndex() {
|
|
34549
35703
|
try {
|
|
34550
35704
|
await collection.createIndex({
|
|
@@ -34587,16 +35741,26 @@ function useOnlineFormRepo() {
|
|
|
34587
35741
|
site = ""
|
|
34588
35742
|
}) {
|
|
34589
35743
|
page = page > 0 ? page - 1 : 0;
|
|
35744
|
+
try {
|
|
35745
|
+
site = new ObjectId103(site);
|
|
35746
|
+
} catch (error) {
|
|
35747
|
+
throw new BadRequestError168("Invalid site ID format.");
|
|
35748
|
+
}
|
|
34590
35749
|
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
34591
35750
|
const cacheOptions = {
|
|
34592
35751
|
page,
|
|
34593
35752
|
limit,
|
|
34594
35753
|
status,
|
|
35754
|
+
site: site?.toString(),
|
|
34595
35755
|
sort: JSON.stringify(sort)
|
|
34596
35756
|
};
|
|
34597
35757
|
const query = {
|
|
34598
35758
|
...status ? { $and: [{ status }, { status: { $ne: "deleted" } }] } : { status: { $ne: "deleted" } }
|
|
34599
35759
|
};
|
|
35760
|
+
if (site) {
|
|
35761
|
+
query.site = site;
|
|
35762
|
+
cacheOptions.site = site;
|
|
35763
|
+
}
|
|
34600
35764
|
if (search) {
|
|
34601
35765
|
query.$or = [{ name: { $regex: search, $options: "i" } }];
|
|
34602
35766
|
cacheOptions.search = search;
|
|
@@ -34940,7 +36104,7 @@ function useOnlineFormController() {
|
|
|
34940
36104
|
}
|
|
34941
36105
|
async function deleteOnlineFormById(req, res, next) {
|
|
34942
36106
|
const validation = Joi106.string().hex().required();
|
|
34943
|
-
const _id = req.
|
|
36107
|
+
const _id = req.query.id;
|
|
34944
36108
|
const { error } = validation.validate(_id);
|
|
34945
36109
|
if (error) {
|
|
34946
36110
|
logger148.log({ level: "error", message: error.message });
|
|
@@ -35280,7 +36444,7 @@ import {
|
|
|
35280
36444
|
makeCacheKey as makeCacheKey56,
|
|
35281
36445
|
paginate as paginate48,
|
|
35282
36446
|
useAtlas as useAtlas95,
|
|
35283
|
-
useCache as
|
|
36447
|
+
useCache as useCache60
|
|
35284
36448
|
} from "@7365admin1/node-server-utils";
|
|
35285
36449
|
import { ObjectId as ObjectId105 } from "mongodb";
|
|
35286
36450
|
function useNfcPatrolLogRepo() {
|
|
@@ -35290,7 +36454,7 @@ function useNfcPatrolLogRepo() {
|
|
|
35290
36454
|
}
|
|
35291
36455
|
const namespace_collection = "nfc-patrol-logs";
|
|
35292
36456
|
const collection = db.collection(namespace_collection);
|
|
35293
|
-
const { delNamespace, getCache, setCache } =
|
|
36457
|
+
const { delNamespace, getCache, setCache } = useCache60(namespace_collection);
|
|
35294
36458
|
async function createIndexes() {
|
|
35295
36459
|
try {
|
|
35296
36460
|
await collection.createIndexes([
|