@7365admin1/core 2.13.0 → 2.15.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 +169 -28
- package/dist/index.js +2310 -840
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1737 -272
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -3
- package/tsconfig.json +1 -3
package/dist/index.mjs
CHANGED
|
@@ -1388,7 +1388,9 @@ var schemaOccurrenceEntry = Joi5.object({
|
|
|
1388
1388
|
subject: Joi5.string().hex().optional().allow(null, ""),
|
|
1389
1389
|
occurrence: Joi5.string().optional().allow(null, ""),
|
|
1390
1390
|
signature: Joi5.string().hex().optional().allow(null, ""),
|
|
1391
|
-
incidentReportId: Joi5.string().hex().optional().allow(null, "")
|
|
1391
|
+
incidentReportId: Joi5.string().hex().optional().allow(null, ""),
|
|
1392
|
+
eSignature: Joi5.string().required(),
|
|
1393
|
+
createdByName: Joi5.string().optional().allow(null, "")
|
|
1392
1394
|
});
|
|
1393
1395
|
var schemaUpdateOccurrenceEntry = Joi5.object({
|
|
1394
1396
|
_id: Joi5.string().hex().required(),
|
|
@@ -1397,7 +1399,9 @@ var schemaUpdateOccurrenceEntry = Joi5.object({
|
|
|
1397
1399
|
subject: Joi5.string().hex().optional().allow(null, ""),
|
|
1398
1400
|
occurrence: Joi5.string().optional().allow(null, ""),
|
|
1399
1401
|
signature: Joi5.string().hex().optional().allow(null, ""),
|
|
1400
|
-
incidentReportId: Joi5.string().hex().optional().allow(null, "")
|
|
1402
|
+
incidentReportId: Joi5.string().hex().optional().allow(null, ""),
|
|
1403
|
+
eSignature: Joi5.string().required(),
|
|
1404
|
+
createdByName: Joi5.string().optional().allow(null, "")
|
|
1401
1405
|
});
|
|
1402
1406
|
function MOccurrenceEntry(value) {
|
|
1403
1407
|
if (value._id && typeof value._id === "string") {
|
|
@@ -1454,6 +1458,8 @@ function MOccurrenceEntry(value) {
|
|
|
1454
1458
|
incidentReportId: value.incidentReportId,
|
|
1455
1459
|
signature: value.signature,
|
|
1456
1460
|
userName: value.userName,
|
|
1461
|
+
eSignature: value.eSignature,
|
|
1462
|
+
createdByName: value.createdByName,
|
|
1457
1463
|
date: value.date,
|
|
1458
1464
|
createdAt: value.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
1459
1465
|
updatedAt: value.updatedAt,
|
|
@@ -6424,12 +6430,12 @@ function useUserController() {
|
|
|
6424
6430
|
}
|
|
6425
6431
|
}
|
|
6426
6432
|
async function createUserByVerification(req, res, next) {
|
|
6427
|
-
const
|
|
6433
|
+
const allowedTypes = ["user-sign-up", "user-invite"];
|
|
6428
6434
|
const validation = Joi14.object({
|
|
6429
6435
|
id: Joi14.string().hex().required(),
|
|
6430
6436
|
name: Joi14.string().required(),
|
|
6431
6437
|
password: Joi14.string().required(),
|
|
6432
|
-
type: Joi14.string().required().valid(...
|
|
6438
|
+
type: Joi14.string().required().valid(...allowedTypes)
|
|
6433
6439
|
});
|
|
6434
6440
|
const id = req.params.id;
|
|
6435
6441
|
const payload = { ...req.body };
|
|
@@ -15493,12 +15499,37 @@ import {
|
|
|
15493
15499
|
import { BadRequestError as BadRequestError77, logger as logger61 } from "@7365admin1/node-server-utils";
|
|
15494
15500
|
import Joi43 from "joi";
|
|
15495
15501
|
import { ObjectId as ObjectId45 } from "mongodb";
|
|
15496
|
-
var
|
|
15497
|
-
|
|
15502
|
+
var VehicleType = /* @__PURE__ */ ((VehicleType2) => {
|
|
15503
|
+
VehicleType2["WHITELIST"] = "whitelist";
|
|
15504
|
+
VehicleType2["BLOCKLIST"] = "blocklist";
|
|
15505
|
+
return VehicleType2;
|
|
15506
|
+
})(VehicleType || {});
|
|
15507
|
+
var VehicleCategory = /* @__PURE__ */ ((VehicleCategory2) => {
|
|
15508
|
+
VehicleCategory2["RESIDENT"] = "resident";
|
|
15509
|
+
VehicleCategory2["VISITOR"] = "visitor";
|
|
15510
|
+
return VehicleCategory2;
|
|
15511
|
+
})(VehicleCategory || {});
|
|
15512
|
+
var VehicleStatus = /* @__PURE__ */ ((VehicleStatus2) => {
|
|
15513
|
+
VehicleStatus2["PENDING"] = "pending";
|
|
15514
|
+
VehicleStatus2["ACTIVE"] = "active";
|
|
15515
|
+
VehicleStatus2["INACTIVE"] = "inactive";
|
|
15516
|
+
VehicleStatus2["DELETED"] = "deleted";
|
|
15517
|
+
return VehicleStatus2;
|
|
15518
|
+
})(VehicleStatus || {});
|
|
15519
|
+
var OrgNature = /* @__PURE__ */ ((OrgNature2) => {
|
|
15520
|
+
OrgNature2["PROPERTY_MANAGEMENT_AGENCY"] = "property_management_agency";
|
|
15521
|
+
OrgNature2["SECURITY_AGENCY"] = "security_agency";
|
|
15522
|
+
return OrgNature2;
|
|
15523
|
+
})(OrgNature || {});
|
|
15524
|
+
var ANPRMode = /* @__PURE__ */ ((ANPRMode2) => {
|
|
15525
|
+
ANPRMode2["TRAFFIC_REDLIST"] = "TrafficRedList";
|
|
15526
|
+
ANPRMode2["TRAFFIC_BLACKLIST"] = "TrafficBlackList";
|
|
15527
|
+
return ANPRMode2;
|
|
15528
|
+
})(ANPRMode || {});
|
|
15498
15529
|
var vehicleSchema = Joi43.object({
|
|
15499
15530
|
plateNumber: Joi43.string().required(),
|
|
15500
|
-
type: Joi43.string().required().
|
|
15501
|
-
category: Joi43.string().required().
|
|
15531
|
+
type: Joi43.string().required().valid(...Object.values(VehicleType)),
|
|
15532
|
+
category: Joi43.string().required().valid(...Object.values(VehicleCategory)),
|
|
15502
15533
|
name: Joi43.string().required(),
|
|
15503
15534
|
phoneNumber: Joi43.string().optional().allow("", null),
|
|
15504
15535
|
recNo: Joi43.string().optional().allow("", null),
|
|
@@ -15512,7 +15543,8 @@ var vehicleSchema = Joi43.object({
|
|
|
15512
15543
|
seasonPassType: Joi43.string().optional().allow("", null),
|
|
15513
15544
|
start: Joi43.date().optional().allow("", null),
|
|
15514
15545
|
end: Joi43.date().optional().allow("", null),
|
|
15515
|
-
unitName: Joi43.string().optional().allow("", null)
|
|
15546
|
+
unitName: Joi43.string().optional().allow("", null),
|
|
15547
|
+
status: Joi43.string().optional().valid(...Object.values(VehicleStatus)).allow("")
|
|
15516
15548
|
});
|
|
15517
15549
|
function MVehicle(value) {
|
|
15518
15550
|
const { error } = vehicleSchema.validate(value);
|
|
@@ -15541,6 +15573,11 @@ function MVehicle(value) {
|
|
|
15541
15573
|
throw new BadRequestError77("Invalid building unit ID format.");
|
|
15542
15574
|
}
|
|
15543
15575
|
}
|
|
15576
|
+
const createdAtDate = value.createdAt ? new Date(value.createdAt) : /* @__PURE__ */ new Date();
|
|
15577
|
+
const expiredDate = new Date(createdAtDate);
|
|
15578
|
+
expiredDate.setFullYear(expiredDate.getFullYear() + 10);
|
|
15579
|
+
const createdAt = createdAtDate.toISOString();
|
|
15580
|
+
const expiredAt = value.end ?? expiredDate.toISOString();
|
|
15544
15581
|
return {
|
|
15545
15582
|
plateNumber: value.plateNumber ?? "",
|
|
15546
15583
|
type: value.type ?? "",
|
|
@@ -15556,11 +15593,11 @@ function MVehicle(value) {
|
|
|
15556
15593
|
nric: value.nric ?? "",
|
|
15557
15594
|
remarks: value.remarks ?? "",
|
|
15558
15595
|
seasonPassType: value.seasonPassType ?? "",
|
|
15559
|
-
start: value.start ??
|
|
15560
|
-
end: value.end ??
|
|
15561
|
-
status: value.status ?? "active"
|
|
15596
|
+
start: value.start ?? createdAt,
|
|
15597
|
+
end: value.end ?? expiredAt,
|
|
15598
|
+
status: value.status ?? "active" /* ACTIVE */,
|
|
15562
15599
|
unitName: value.unitName ?? "",
|
|
15563
|
-
createdAt
|
|
15600
|
+
createdAt,
|
|
15564
15601
|
updatedAt: value.updatedAt ?? "",
|
|
15565
15602
|
deletedAt: value.deletedAt ?? ""
|
|
15566
15603
|
};
|
|
@@ -15618,18 +15655,44 @@ function useVehicleRepo() {
|
|
|
15618
15655
|
}
|
|
15619
15656
|
const namespace_collection = "vehicles";
|
|
15620
15657
|
const collection = db.collection(namespace_collection);
|
|
15621
|
-
const { delNamespace, setCache, getCache
|
|
15658
|
+
const { delNamespace, setCache, getCache } = useCache28(namespace_collection);
|
|
15622
15659
|
async function createIndex() {
|
|
15623
15660
|
try {
|
|
15624
15661
|
await collection.createIndexes([
|
|
15625
15662
|
{ key: { status: 1 } },
|
|
15626
15663
|
{ key: { type: 1 } },
|
|
15627
|
-
{ key: { category: 1 } }
|
|
15664
|
+
{ key: { category: 1 } },
|
|
15665
|
+
{
|
|
15666
|
+
key: { nric: 1 },
|
|
15667
|
+
name: "uniq_nric_not_deleted_nonempty",
|
|
15668
|
+
unique: true,
|
|
15669
|
+
partialFilterExpression: {
|
|
15670
|
+
nric: { $type: "string", $gt: "" },
|
|
15671
|
+
deletedAt: ""
|
|
15672
|
+
}
|
|
15673
|
+
}
|
|
15628
15674
|
]);
|
|
15629
15675
|
} catch (error) {
|
|
15676
|
+
console.error("createIndexes error:", error);
|
|
15630
15677
|
throw new InternalServerError28("Failed to create index on vehicle.");
|
|
15631
15678
|
}
|
|
15632
15679
|
}
|
|
15680
|
+
async function createTextIndex() {
|
|
15681
|
+
try {
|
|
15682
|
+
await collection.createIndex({
|
|
15683
|
+
name: "text",
|
|
15684
|
+
plateNumber: "text",
|
|
15685
|
+
level: "text",
|
|
15686
|
+
unitName: "text",
|
|
15687
|
+
phoneNumber: "text",
|
|
15688
|
+
nric: "text"
|
|
15689
|
+
});
|
|
15690
|
+
} catch (error) {
|
|
15691
|
+
throw new InternalServerError28(
|
|
15692
|
+
"Failed to create text index on visitor transaction."
|
|
15693
|
+
);
|
|
15694
|
+
}
|
|
15695
|
+
}
|
|
15633
15696
|
async function add(value, session) {
|
|
15634
15697
|
try {
|
|
15635
15698
|
value = MVehicle(value);
|
|
@@ -15661,37 +15724,40 @@ function useVehicleRepo() {
|
|
|
15661
15724
|
search = "",
|
|
15662
15725
|
sort = {},
|
|
15663
15726
|
type = "",
|
|
15664
|
-
category = ""
|
|
15727
|
+
category = "",
|
|
15728
|
+
status = ""
|
|
15665
15729
|
}) {
|
|
15666
15730
|
page = page > 0 ? page - 1 : 0;
|
|
15667
|
-
const
|
|
15731
|
+
const baseQuery = {
|
|
15732
|
+
...status && { status },
|
|
15733
|
+
...type && { type },
|
|
15734
|
+
...type && { type }
|
|
15735
|
+
};
|
|
15736
|
+
let query = { ...baseQuery };
|
|
15737
|
+
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
15668
15738
|
const cacheOptions = {
|
|
15669
|
-
status
|
|
15739
|
+
...status && { status },
|
|
15740
|
+
...type && { type },
|
|
15741
|
+
...type && { type },
|
|
15670
15742
|
page: String(page),
|
|
15671
|
-
limit: String(limit)
|
|
15743
|
+
limit: String(limit),
|
|
15744
|
+
sort: JSON.stringify(sort)
|
|
15672
15745
|
};
|
|
15673
|
-
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
15674
|
-
cacheOptions.sort = JSON.stringify(sort);
|
|
15675
15746
|
if (search) {
|
|
15676
|
-
query.$
|
|
15747
|
+
query.$text = { $search: search };
|
|
15677
15748
|
cacheOptions.search = search;
|
|
15678
15749
|
}
|
|
15679
|
-
if (type) {
|
|
15680
|
-
query.type = type;
|
|
15681
|
-
cacheOptions.type = type;
|
|
15682
|
-
}
|
|
15683
|
-
if (category) {
|
|
15684
|
-
query.category = category;
|
|
15685
|
-
cacheOptions.category = category;
|
|
15686
|
-
}
|
|
15687
15750
|
const cacheKey = makeCacheKey26(namespace_collection, cacheOptions);
|
|
15688
15751
|
const cachedData = await getCache(cacheKey);
|
|
15689
15752
|
if (cachedData) {
|
|
15690
15753
|
logger62.info(`Cache hit for key: ${cacheKey}`);
|
|
15691
15754
|
return cachedData;
|
|
15692
15755
|
}
|
|
15756
|
+
const escapeRegex = (input) => input.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
15693
15757
|
try {
|
|
15694
|
-
|
|
15758
|
+
let items = [];
|
|
15759
|
+
let length = 0;
|
|
15760
|
+
items = await collection.aggregate([
|
|
15695
15761
|
{ $match: query },
|
|
15696
15762
|
{ $sort: sort },
|
|
15697
15763
|
{ $skip: page * limit },
|
|
@@ -15717,17 +15783,65 @@ function useVehicleRepo() {
|
|
|
15717
15783
|
level: 1,
|
|
15718
15784
|
unit: "$units.name",
|
|
15719
15785
|
plateNumber: 1,
|
|
15720
|
-
recNo: 1
|
|
15786
|
+
recNo: 1,
|
|
15787
|
+
nric: 1
|
|
15721
15788
|
}
|
|
15722
15789
|
}
|
|
15723
15790
|
]).toArray();
|
|
15724
|
-
|
|
15791
|
+
length = await collection.countDocuments(query);
|
|
15792
|
+
if ((!items || items.length === 0) && search) {
|
|
15793
|
+
const escaped = escapeRegex(search);
|
|
15794
|
+
const regexQuery = {
|
|
15795
|
+
...baseQuery,
|
|
15796
|
+
...type && { type },
|
|
15797
|
+
...category && { category },
|
|
15798
|
+
$or: [
|
|
15799
|
+
{ name: { $regex: escaped, $options: "i" } },
|
|
15800
|
+
{ plateNumber: { $regex: escaped, $options: "i" } },
|
|
15801
|
+
{ company: { $regex: escaped, $options: "i" } },
|
|
15802
|
+
{ level: { $regex: escaped, $options: "i" } },
|
|
15803
|
+
{ unitName: { $regex: escaped, $options: "i" } },
|
|
15804
|
+
{ contact: { $regex: escaped, $options: "i" } },
|
|
15805
|
+
{ nric: { $regex: escaped, $options: "i" } }
|
|
15806
|
+
]
|
|
15807
|
+
};
|
|
15808
|
+
items = await collection.aggregate([
|
|
15809
|
+
{ $match: regexQuery },
|
|
15810
|
+
{ $sort: sort },
|
|
15811
|
+
{ $skip: page * limit },
|
|
15812
|
+
{ $limit: limit },
|
|
15813
|
+
{
|
|
15814
|
+
$lookup: {
|
|
15815
|
+
from: "building-units",
|
|
15816
|
+
localField: "unit",
|
|
15817
|
+
foreignField: "_id",
|
|
15818
|
+
as: "units",
|
|
15819
|
+
pipeline: [{ $project: { name: 1 } }]
|
|
15820
|
+
}
|
|
15821
|
+
},
|
|
15822
|
+
{ $unwind: { path: "$units", preserveNullAndEmptyArrays: true } },
|
|
15823
|
+
{
|
|
15824
|
+
$project: {
|
|
15825
|
+
name: 1,
|
|
15826
|
+
type: 1,
|
|
15827
|
+
category: 1,
|
|
15828
|
+
status: 1,
|
|
15829
|
+
phoneNumber: 1,
|
|
15830
|
+
block: 1,
|
|
15831
|
+
level: 1,
|
|
15832
|
+
unit: "$units.name",
|
|
15833
|
+
plateNumber: 1,
|
|
15834
|
+
recNo: 1,
|
|
15835
|
+
nric: 1
|
|
15836
|
+
}
|
|
15837
|
+
}
|
|
15838
|
+
]).toArray();
|
|
15839
|
+
length = await collection.countDocuments(regexQuery);
|
|
15840
|
+
}
|
|
15725
15841
|
const data = paginate21(items, page, limit, length);
|
|
15726
|
-
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
15727
|
-
logger62.
|
|
15728
|
-
|
|
15729
|
-
logger62.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
15730
|
-
});
|
|
15842
|
+
setCache(cacheKey, data, 15 * 60).then(() => logger62.info(`Cache set for key: ${cacheKey}`)).catch(
|
|
15843
|
+
(err) => logger62.error(`Failed to set cache for key: ${cacheKey}`, err)
|
|
15844
|
+
);
|
|
15731
15845
|
return data;
|
|
15732
15846
|
} catch (error) {
|
|
15733
15847
|
throw error;
|
|
@@ -15821,7 +15935,10 @@ function useVehicleRepo() {
|
|
|
15821
15935
|
type: 1,
|
|
15822
15936
|
category: 1,
|
|
15823
15937
|
status: 1,
|
|
15824
|
-
recNo: 1
|
|
15938
|
+
recNo: 1,
|
|
15939
|
+
start: 1,
|
|
15940
|
+
end: 1,
|
|
15941
|
+
seasonPassType: 1
|
|
15825
15942
|
}
|
|
15826
15943
|
}
|
|
15827
15944
|
]).toArray();
|
|
@@ -15870,7 +15987,7 @@ function useVehicleRepo() {
|
|
|
15870
15987
|
throw error2;
|
|
15871
15988
|
}
|
|
15872
15989
|
}
|
|
15873
|
-
async function updateVehicle(_id, value) {
|
|
15990
|
+
async function updateVehicle(_id, value, session) {
|
|
15874
15991
|
try {
|
|
15875
15992
|
_id = new ObjectId46(_id);
|
|
15876
15993
|
} catch (error) {
|
|
@@ -15881,7 +15998,11 @@ function useVehicleRepo() {
|
|
|
15881
15998
|
...value,
|
|
15882
15999
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
15883
16000
|
};
|
|
15884
|
-
const res = await collection.updateOne(
|
|
16001
|
+
const res = await collection.updateOne(
|
|
16002
|
+
{ _id },
|
|
16003
|
+
{ $set: updateValue },
|
|
16004
|
+
{ session }
|
|
16005
|
+
);
|
|
15885
16006
|
if (res.modifiedCount === 0) {
|
|
15886
16007
|
throw new InternalServerError28("Unable to update vehicle.");
|
|
15887
16008
|
}
|
|
@@ -15960,8 +16081,126 @@ function useVehicleRepo() {
|
|
|
15960
16081
|
);
|
|
15961
16082
|
}
|
|
15962
16083
|
}
|
|
16084
|
+
async function getVehiclesByNRIC({
|
|
16085
|
+
page = 1,
|
|
16086
|
+
limit = 10,
|
|
16087
|
+
search = "",
|
|
16088
|
+
sort = {}
|
|
16089
|
+
}) {
|
|
16090
|
+
page = page > 0 ? page - 1 : 0;
|
|
16091
|
+
const baseQuery = {
|
|
16092
|
+
deletedAt: ""
|
|
16093
|
+
};
|
|
16094
|
+
let query = { ...baseQuery };
|
|
16095
|
+
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
16096
|
+
const cacheOptions = {
|
|
16097
|
+
deletedAt: "",
|
|
16098
|
+
page: String(page),
|
|
16099
|
+
limit: String(limit),
|
|
16100
|
+
sort: JSON.stringify(sort)
|
|
16101
|
+
};
|
|
16102
|
+
if (search) {
|
|
16103
|
+
query.$text = { $search: search };
|
|
16104
|
+
cacheOptions.search = search;
|
|
16105
|
+
}
|
|
16106
|
+
const cacheKey = makeCacheKey26(namespace_collection, cacheOptions);
|
|
16107
|
+
const cachedData = await getCache(cacheKey);
|
|
16108
|
+
if (cachedData) {
|
|
16109
|
+
logger62.info(`Cache hit for key: ${cacheKey}`);
|
|
16110
|
+
return cachedData;
|
|
16111
|
+
}
|
|
16112
|
+
const escapeRegex = (input) => input.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
16113
|
+
try {
|
|
16114
|
+
let items = [];
|
|
16115
|
+
let length = 0;
|
|
16116
|
+
items = await collection.aggregate([
|
|
16117
|
+
{ $match: query },
|
|
16118
|
+
{ $sort: sort },
|
|
16119
|
+
{ $skip: page * limit },
|
|
16120
|
+
{ $limit: limit },
|
|
16121
|
+
{
|
|
16122
|
+
$project: {
|
|
16123
|
+
name: 1,
|
|
16124
|
+
phoneNumber: 1,
|
|
16125
|
+
plateNumber: 1,
|
|
16126
|
+
recNo: 1,
|
|
16127
|
+
nric: 1,
|
|
16128
|
+
status: 1,
|
|
16129
|
+
type: 1
|
|
16130
|
+
}
|
|
16131
|
+
}
|
|
16132
|
+
]).toArray();
|
|
16133
|
+
length = await collection.countDocuments(query);
|
|
16134
|
+
if ((!items || items.length === 0) && search) {
|
|
16135
|
+
const escaped = escapeRegex(search);
|
|
16136
|
+
const regexQuery = {
|
|
16137
|
+
...baseQuery,
|
|
16138
|
+
$or: [
|
|
16139
|
+
{ name: { $regex: escaped, $options: "i" } },
|
|
16140
|
+
{ plateNumber: { $regex: escaped, $options: "i" } },
|
|
16141
|
+
{ level: { $regex: escaped, $options: "i" } },
|
|
16142
|
+
{ nric: { $regex: escaped, $options: "i" } }
|
|
16143
|
+
]
|
|
16144
|
+
};
|
|
16145
|
+
items = await collection.aggregate([
|
|
16146
|
+
{ $match: regexQuery },
|
|
16147
|
+
{ $sort: sort },
|
|
16148
|
+
{ $skip: page * limit },
|
|
16149
|
+
{ $limit: limit },
|
|
16150
|
+
{
|
|
16151
|
+
$project: {
|
|
16152
|
+
name: 1,
|
|
16153
|
+
phoneNumber: 1,
|
|
16154
|
+
plateNumber: 1,
|
|
16155
|
+
recNo: 1,
|
|
16156
|
+
nric: 1,
|
|
16157
|
+
status: 1,
|
|
16158
|
+
type: 1
|
|
16159
|
+
}
|
|
16160
|
+
}
|
|
16161
|
+
]).toArray();
|
|
16162
|
+
length = await collection.countDocuments(regexQuery);
|
|
16163
|
+
}
|
|
16164
|
+
const data = paginate21(items, page, limit, length);
|
|
16165
|
+
setCache(cacheKey, data, 15 * 60).then(() => logger62.info(`Cache set for key: ${cacheKey}`)).catch(
|
|
16166
|
+
(err) => logger62.error(`Failed to set cache for key: ${cacheKey}`, err)
|
|
16167
|
+
);
|
|
16168
|
+
return data;
|
|
16169
|
+
} catch (error) {
|
|
16170
|
+
throw error;
|
|
16171
|
+
}
|
|
16172
|
+
}
|
|
16173
|
+
async function deleteExpiredVehicles(session) {
|
|
16174
|
+
try {
|
|
16175
|
+
const tenYearsAgo = /* @__PURE__ */ new Date();
|
|
16176
|
+
tenYearsAgo.setFullYear(tenYearsAgo.getFullYear() - 10);
|
|
16177
|
+
const res = await collection.updateMany(
|
|
16178
|
+
{
|
|
16179
|
+
status: { $ne: "deleted" },
|
|
16180
|
+
end: { $exists: true, $lte: tenYearsAgo }
|
|
16181
|
+
// check only end
|
|
16182
|
+
},
|
|
16183
|
+
{ $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } },
|
|
16184
|
+
{ session }
|
|
16185
|
+
);
|
|
16186
|
+
if (res.modifiedCount === 0)
|
|
16187
|
+
throw new InternalServerError28("Unable to delete vehicle.");
|
|
16188
|
+
delNamespace().then(() => {
|
|
16189
|
+
logger62.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
16190
|
+
}).catch((err) => {
|
|
16191
|
+
logger62.error(
|
|
16192
|
+
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
16193
|
+
err
|
|
16194
|
+
);
|
|
16195
|
+
});
|
|
16196
|
+
return res.modifiedCount;
|
|
16197
|
+
} catch (error) {
|
|
16198
|
+
throw error;
|
|
16199
|
+
}
|
|
16200
|
+
}
|
|
15963
16201
|
return {
|
|
15964
16202
|
createIndex,
|
|
16203
|
+
createTextIndex,
|
|
15965
16204
|
add,
|
|
15966
16205
|
getVehicles,
|
|
15967
16206
|
getSeasonPassTypes,
|
|
@@ -15969,7 +16208,9 @@ function useVehicleRepo() {
|
|
|
15969
16208
|
updateVehicle,
|
|
15970
16209
|
deleteVehicle,
|
|
15971
16210
|
getByPlaceNumber,
|
|
15972
|
-
getVehicleByPlateNumber
|
|
16211
|
+
getVehicleByPlateNumber,
|
|
16212
|
+
getVehiclesByNRIC,
|
|
16213
|
+
deleteExpiredVehicles
|
|
15973
16214
|
};
|
|
15974
16215
|
}
|
|
15975
16216
|
|
|
@@ -16355,7 +16596,7 @@ function useDahuaService() {
|
|
|
16355
16596
|
username: Joi45.string().required(),
|
|
16356
16597
|
password: Joi45.string().required(),
|
|
16357
16598
|
plateNumber: Joi45.string().required(),
|
|
16358
|
-
mode: Joi45.string().valid(
|
|
16599
|
+
mode: Joi45.string().valid(...Object.values(ANPRMode)).required(),
|
|
16359
16600
|
start: Joi45.string().isoDate().optional().allow("", null),
|
|
16360
16601
|
end: Joi45.string().isoDate().optional().allow("", null),
|
|
16361
16602
|
owner: Joi45.string().optional().allow("", null)
|
|
@@ -16379,7 +16620,7 @@ function useDahuaService() {
|
|
|
16379
16620
|
host: value.host,
|
|
16380
16621
|
username: value.username,
|
|
16381
16622
|
password: value.password,
|
|
16382
|
-
endpoint: `/cgi-bin/recordUpdater.cgi?action=insert&name=${value.mode}&PlateNumber=${value.plateNumber}&BeginTime=${value.start}&CancelTime=${value.end}
|
|
16623
|
+
endpoint: `/cgi-bin/recordUpdater.cgi?action=insert&name=${value.mode}&PlateNumber=${value.plateNumber}&BeginTime=${value.start}&CancelTime=${value.end}&OpenGate=true&MasterOfCar=${value.owner}`
|
|
16383
16624
|
});
|
|
16384
16625
|
return response;
|
|
16385
16626
|
} catch (error2) {
|
|
@@ -16427,27 +16668,243 @@ import {
|
|
|
16427
16668
|
logger as logger64,
|
|
16428
16669
|
useAtlas as useAtlas39
|
|
16429
16670
|
} from "@7365admin1/node-server-utils";
|
|
16671
|
+
function formatDahuaDate(date) {
|
|
16672
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
16673
|
+
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(
|
|
16674
|
+
date.getDate()
|
|
16675
|
+
)} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(
|
|
16676
|
+
date.getSeconds()
|
|
16677
|
+
)}`;
|
|
16678
|
+
}
|
|
16430
16679
|
function useVehicleService() {
|
|
16431
|
-
const {
|
|
16680
|
+
const {
|
|
16681
|
+
add: _add,
|
|
16682
|
+
deleteVehicle: _deleteVehicle,
|
|
16683
|
+
updateVehicle: _updateVehicle,
|
|
16684
|
+
getVehicleById: _getVehicleById,
|
|
16685
|
+
deleteExpiredVehicles: _deleteExpiredVehicles
|
|
16686
|
+
} = useVehicleRepo();
|
|
16432
16687
|
const {
|
|
16433
16688
|
addPlateNumber: _addPlateNumber,
|
|
16434
16689
|
removePlateNumber: _removePlateNumber
|
|
16435
16690
|
} = useDahuaService();
|
|
16436
16691
|
const { getAllCameraWithPassword: _getAllSiteCameras } = useSiteCameraRepo();
|
|
16692
|
+
const { getById: _getById } = useOrgRepo();
|
|
16437
16693
|
async function add(value) {
|
|
16694
|
+
const session = useAtlas39.getClient()?.startSession();
|
|
16695
|
+
if (!session)
|
|
16696
|
+
throw new Error("Unable to start session for vehicle service.");
|
|
16697
|
+
const org = await _getById(value.org);
|
|
16698
|
+
if (!org)
|
|
16699
|
+
throw new BadRequestError80("Org not found");
|
|
16700
|
+
if (!Object.values(OrgNature).includes(org.nature)) {
|
|
16701
|
+
throw new BadRequestError80(
|
|
16702
|
+
"This organization is not allowed to add vehicles."
|
|
16703
|
+
);
|
|
16704
|
+
}
|
|
16705
|
+
value.status = "active" /* ACTIVE */;
|
|
16706
|
+
const addedBySecurity = org.nature === "security_agency" /* SECURITY_AGENCY */;
|
|
16707
|
+
const addedByPM = org.nature === "property_management_agency" /* PROPERTY_MANAGEMENT_AGENCY */;
|
|
16708
|
+
if (addedBySecurity)
|
|
16709
|
+
value.status = "pending" /* PENDING */;
|
|
16710
|
+
const isBlocklist = value.type === "blocklist" /* BLOCKLIST */;
|
|
16711
|
+
if (isBlocklist)
|
|
16712
|
+
value.status = "inactive" /* INACTIVE */;
|
|
16713
|
+
const _type = value.type;
|
|
16714
|
+
const _mode = isBlocklist ? "TrafficBlackList" /* TRAFFIC_BLACKLIST */ : "TrafficRedList" /* TRAFFIC_REDLIST */;
|
|
16715
|
+
const hasStart = typeof value.start === "string" ? value.start.trim() !== "" : !!value.start;
|
|
16716
|
+
const hasEnd = typeof value.end === "string" ? value.end.trim() !== "" : !!value.end;
|
|
16717
|
+
let startDate = null;
|
|
16718
|
+
let endDate = null;
|
|
16719
|
+
let start = "";
|
|
16720
|
+
let end = "";
|
|
16721
|
+
let startDateDahua;
|
|
16722
|
+
let endDateDahua;
|
|
16723
|
+
if (addedByPM && !hasStart && !hasEnd) {
|
|
16724
|
+
startDate = /* @__PURE__ */ new Date();
|
|
16725
|
+
endDate = new Date(startDate);
|
|
16726
|
+
endDate.setFullYear(endDate.getFullYear() + 10);
|
|
16727
|
+
start = startDate.toISOString();
|
|
16728
|
+
end = endDate.toISOString();
|
|
16729
|
+
startDateDahua = formatDahuaDate(startDate);
|
|
16730
|
+
endDateDahua = formatDahuaDate(endDate);
|
|
16731
|
+
} else {
|
|
16732
|
+
if (hasStart) {
|
|
16733
|
+
startDate = new Date(value.start);
|
|
16734
|
+
start = startDate.toISOString();
|
|
16735
|
+
startDateDahua = formatDahuaDate(startDate);
|
|
16736
|
+
}
|
|
16737
|
+
if (hasEnd) {
|
|
16738
|
+
endDate = new Date(value.end);
|
|
16739
|
+
end = endDate.toISOString();
|
|
16740
|
+
endDateDahua = formatDahuaDate(endDate);
|
|
16741
|
+
}
|
|
16742
|
+
}
|
|
16743
|
+
const owner = String(value.name ?? "").substring(0, 15);
|
|
16744
|
+
try {
|
|
16745
|
+
session.startTransaction();
|
|
16746
|
+
let message = "Vehicle plate number needs approval from property management.";
|
|
16747
|
+
if (value.status && value.status !== "pending" /* PENDING */) {
|
|
16748
|
+
const siteCameras = [];
|
|
16749
|
+
let page = 1;
|
|
16750
|
+
let pages = 1;
|
|
16751
|
+
const limit = 20;
|
|
16752
|
+
do {
|
|
16753
|
+
const siteCameraReq = await _getAllSiteCameras({
|
|
16754
|
+
site: value.site,
|
|
16755
|
+
type: "anpr",
|
|
16756
|
+
direction: ["both", "entry"],
|
|
16757
|
+
page,
|
|
16758
|
+
limit
|
|
16759
|
+
});
|
|
16760
|
+
pages = siteCameraReq.pages || 1;
|
|
16761
|
+
siteCameras.push(...siteCameraReq.items);
|
|
16762
|
+
page++;
|
|
16763
|
+
} while (page < pages);
|
|
16764
|
+
if (!siteCameras.length)
|
|
16765
|
+
throw new BadRequestError80("No site cameras found.");
|
|
16766
|
+
for (const camera of siteCameras) {
|
|
16767
|
+
const { host, username, password } = camera;
|
|
16768
|
+
const dahuaPayload = {
|
|
16769
|
+
host,
|
|
16770
|
+
username,
|
|
16771
|
+
password,
|
|
16772
|
+
plateNumber: value.plateNumber,
|
|
16773
|
+
mode: _mode,
|
|
16774
|
+
owner,
|
|
16775
|
+
...startDateDahua ? { start: startDateDahua } : "",
|
|
16776
|
+
...endDateDahua ? { end: endDateDahua } : ""
|
|
16777
|
+
};
|
|
16778
|
+
const dahuaResponse = await _addPlateNumber(dahuaPayload);
|
|
16779
|
+
if (dahuaResponse?.statusCode !== 200) {
|
|
16780
|
+
throw new BadRequestError80(
|
|
16781
|
+
`Failed to add plate number to ANPR ${_type}`
|
|
16782
|
+
);
|
|
16783
|
+
}
|
|
16784
|
+
const responseData = dahuaResponse?.data.toString("utf-8");
|
|
16785
|
+
value.recNo = responseData.split("=")[1]?.trim();
|
|
16786
|
+
message = `Vehicle plate number added to ${_type} successfully.`;
|
|
16787
|
+
}
|
|
16788
|
+
}
|
|
16789
|
+
const formattedValue = {
|
|
16790
|
+
...value,
|
|
16791
|
+
start,
|
|
16792
|
+
// ISO string or ""
|
|
16793
|
+
end
|
|
16794
|
+
// ISO string or ""
|
|
16795
|
+
};
|
|
16796
|
+
await _add(formattedValue, session);
|
|
16797
|
+
await session.commitTransaction();
|
|
16798
|
+
return message;
|
|
16799
|
+
} catch (error) {
|
|
16800
|
+
logger64.error("Error in vehicle service add:", error);
|
|
16801
|
+
await session.abortTransaction();
|
|
16802
|
+
throw error;
|
|
16803
|
+
} finally {
|
|
16804
|
+
session.endSession();
|
|
16805
|
+
}
|
|
16806
|
+
}
|
|
16807
|
+
async function deleteVehicle(_id, recno, site, type, bypass = false) {
|
|
16808
|
+
const session = useAtlas39.getClient()?.startSession();
|
|
16809
|
+
if (!session) {
|
|
16810
|
+
throw new Error("Unable to start session for vehicle service.");
|
|
16811
|
+
}
|
|
16812
|
+
const _mode = type !== "whitelist" /* WHITELIST */ ? "TrafficBlackList" /* TRAFFIC_BLACKLIST */ : "TrafficRedList" /* TRAFFIC_REDLIST */;
|
|
16813
|
+
try {
|
|
16814
|
+
session.startTransaction();
|
|
16815
|
+
const siteCameras = [];
|
|
16816
|
+
let page = 1;
|
|
16817
|
+
let pages = 1;
|
|
16818
|
+
const limit = 20;
|
|
16819
|
+
do {
|
|
16820
|
+
const siteCameraReq = await _getAllSiteCameras({
|
|
16821
|
+
site,
|
|
16822
|
+
type: "anpr",
|
|
16823
|
+
page,
|
|
16824
|
+
limit
|
|
16825
|
+
});
|
|
16826
|
+
pages = siteCameraReq.pages || 1;
|
|
16827
|
+
siteCameras.push(...siteCameraReq.items);
|
|
16828
|
+
page++;
|
|
16829
|
+
} while (page < pages);
|
|
16830
|
+
if (!siteCameras.length) {
|
|
16831
|
+
throw new BadRequestError80("No site cameras found.");
|
|
16832
|
+
}
|
|
16833
|
+
for (const camera of siteCameras) {
|
|
16834
|
+
const host = camera.host;
|
|
16835
|
+
const username = camera.username;
|
|
16836
|
+
const password = camera.password;
|
|
16837
|
+
const dahuaPayload = {
|
|
16838
|
+
host,
|
|
16839
|
+
username,
|
|
16840
|
+
password,
|
|
16841
|
+
recno,
|
|
16842
|
+
mode: _mode
|
|
16843
|
+
};
|
|
16844
|
+
const dahuaResponse = await _removePlateNumber(dahuaPayload);
|
|
16845
|
+
if (!bypass && dahuaResponse?.statusCode !== 200) {
|
|
16846
|
+
throw new BadRequestError80(
|
|
16847
|
+
`Failed to remove plate number to ANPR from ${type}`
|
|
16848
|
+
);
|
|
16849
|
+
}
|
|
16850
|
+
}
|
|
16851
|
+
await _deleteVehicle(_id, session);
|
|
16852
|
+
await session.commitTransaction();
|
|
16853
|
+
return `Vehicle plate number deleted from ${type} record successfully.`;
|
|
16854
|
+
} catch (error) {
|
|
16855
|
+
await session.abortTransaction();
|
|
16856
|
+
if (error instanceof AppError14)
|
|
16857
|
+
throw error;
|
|
16858
|
+
throw new InternalServerError29("Failed to delete vehicle");
|
|
16859
|
+
} finally {
|
|
16860
|
+
session.endSession();
|
|
16861
|
+
}
|
|
16862
|
+
}
|
|
16863
|
+
async function approveVehicleById(id, orgId, siteId) {
|
|
16438
16864
|
const session = useAtlas39.getClient()?.startSession();
|
|
16439
16865
|
if (!session) {
|
|
16440
16866
|
throw new Error("Unable to start session for vehicle service.");
|
|
16441
16867
|
}
|
|
16868
|
+
const org = await _getById(orgId);
|
|
16869
|
+
if (!org)
|
|
16870
|
+
throw new BadRequestError80("Org not found");
|
|
16871
|
+
const allowedNatures2 = ["property_management_agency"];
|
|
16872
|
+
if (!allowedNatures2.includes(org.nature)) {
|
|
16873
|
+
throw new BadRequestError80(
|
|
16874
|
+
"Only property management can approve vehicles."
|
|
16875
|
+
);
|
|
16876
|
+
}
|
|
16877
|
+
const vehicle = await _getVehicleById(id);
|
|
16878
|
+
if (!vehicle) {
|
|
16879
|
+
throw new BadRequestError80("Vehicle not found");
|
|
16880
|
+
}
|
|
16881
|
+
const owner = vehicle.name.substring(0, 15);
|
|
16882
|
+
const hasStart = typeof vehicle.start === "string" ? vehicle.start.trim() !== "" : !!vehicle.start;
|
|
16883
|
+
const hasEnd = typeof vehicle.end === "string" ? vehicle.end.trim() !== "" : !!vehicle.end;
|
|
16884
|
+
let startDate = null;
|
|
16885
|
+
let endDate = null;
|
|
16886
|
+
if (!hasStart && !hasEnd) {
|
|
16887
|
+
startDate = /* @__PURE__ */ new Date();
|
|
16888
|
+
endDate = new Date(startDate);
|
|
16889
|
+
endDate.setFullYear(endDate.getFullYear() + 10);
|
|
16890
|
+
} else {
|
|
16891
|
+
startDate = hasStart ? new Date(vehicle.start) : null;
|
|
16892
|
+
endDate = hasEnd ? new Date(vehicle.end) : null;
|
|
16893
|
+
}
|
|
16894
|
+
const startIso = startDate ? startDate.toISOString() : "";
|
|
16895
|
+
const endIso = endDate ? endDate.toISOString() : "";
|
|
16896
|
+
const startDahua = startDate ? formatDahuaDate(startDate) : "";
|
|
16897
|
+
const endDahua = endDate ? formatDahuaDate(endDate) : "";
|
|
16442
16898
|
try {
|
|
16443
16899
|
session.startTransaction();
|
|
16444
16900
|
const siteCameras = [];
|
|
16445
16901
|
let page = 1;
|
|
16446
16902
|
let pages = 1;
|
|
16447
16903
|
const limit = 20;
|
|
16904
|
+
let value = {};
|
|
16448
16905
|
do {
|
|
16449
16906
|
const siteCameraReq = await _getAllSiteCameras({
|
|
16450
|
-
site:
|
|
16907
|
+
site: siteId,
|
|
16451
16908
|
type: "anpr",
|
|
16452
16909
|
direction: ["both", "entry"],
|
|
16453
16910
|
page,
|
|
@@ -16466,11 +16923,11 @@ function useVehicleService() {
|
|
|
16466
16923
|
host,
|
|
16467
16924
|
username,
|
|
16468
16925
|
password,
|
|
16469
|
-
plateNumber:
|
|
16470
|
-
mode: "TrafficRedList"
|
|
16471
|
-
start:
|
|
16472
|
-
end:
|
|
16473
|
-
owner
|
|
16926
|
+
plateNumber: vehicle.plateNumber,
|
|
16927
|
+
mode: "TrafficRedList" /* TRAFFIC_REDLIST */,
|
|
16928
|
+
start: startDahua,
|
|
16929
|
+
end: endDahua,
|
|
16930
|
+
owner
|
|
16474
16931
|
};
|
|
16475
16932
|
const dahuaResponse = await _addPlateNumber(dahuaPayload);
|
|
16476
16933
|
if (dahuaResponse?.statusCode !== 200) {
|
|
@@ -16478,15 +16935,16 @@ function useVehicleService() {
|
|
|
16478
16935
|
}
|
|
16479
16936
|
const responseData = dahuaResponse?.data.toString("utf-8");
|
|
16480
16937
|
value.recNo = responseData.split("=")[1]?.trim();
|
|
16481
|
-
const formattedValue = {
|
|
16482
|
-
...value,
|
|
16483
|
-
start: value.start ? new Date(value.start).toISOString() : "",
|
|
16484
|
-
end: value.end ? new Date(value.end).toISOString() : ""
|
|
16485
|
-
};
|
|
16486
|
-
await _add(formattedValue, session);
|
|
16487
16938
|
}
|
|
16939
|
+
value.status = "active";
|
|
16940
|
+
const formattedValue = {
|
|
16941
|
+
...value,
|
|
16942
|
+
start: startIso,
|
|
16943
|
+
end: endIso
|
|
16944
|
+
};
|
|
16945
|
+
await _updateVehicle(id, formattedValue, session);
|
|
16488
16946
|
await session.commitTransaction();
|
|
16489
|
-
return "Vehicle plate number added successfully.";
|
|
16947
|
+
return "Vehicle plate number approved and added successfully.";
|
|
16490
16948
|
} catch (error) {
|
|
16491
16949
|
logger64.error("Error in vehicle service add:", error);
|
|
16492
16950
|
await session.abortTransaction();
|
|
@@ -16495,50 +16953,16 @@ function useVehicleService() {
|
|
|
16495
16953
|
session.endSession();
|
|
16496
16954
|
}
|
|
16497
16955
|
}
|
|
16498
|
-
async function
|
|
16956
|
+
async function processDeletingExpiredVehicles() {
|
|
16499
16957
|
const session = useAtlas39.getClient()?.startSession();
|
|
16500
16958
|
if (!session) {
|
|
16501
16959
|
throw new Error("Unable to start session for vehicle service.");
|
|
16502
16960
|
}
|
|
16503
16961
|
try {
|
|
16504
16962
|
session.startTransaction();
|
|
16505
|
-
|
|
16506
|
-
let page = 1;
|
|
16507
|
-
let pages = 1;
|
|
16508
|
-
const limit = 20;
|
|
16509
|
-
do {
|
|
16510
|
-
const siteCameraReq = await _getAllSiteCameras({
|
|
16511
|
-
site,
|
|
16512
|
-
type: "anpr",
|
|
16513
|
-
page,
|
|
16514
|
-
limit
|
|
16515
|
-
});
|
|
16516
|
-
pages = siteCameraReq.pages || 1;
|
|
16517
|
-
siteCameras.push(...siteCameraReq.items);
|
|
16518
|
-
page++;
|
|
16519
|
-
} while (page < pages);
|
|
16520
|
-
if (!siteCameras.length) {
|
|
16521
|
-
throw new BadRequestError80("No site cameras found.");
|
|
16522
|
-
}
|
|
16523
|
-
for (const camera of siteCameras) {
|
|
16524
|
-
const host = camera.host;
|
|
16525
|
-
const username = camera.username;
|
|
16526
|
-
const password = camera.password;
|
|
16527
|
-
const dahuaPayload = {
|
|
16528
|
-
host,
|
|
16529
|
-
username,
|
|
16530
|
-
password,
|
|
16531
|
-
recno,
|
|
16532
|
-
mode: "TrafficRedList"
|
|
16533
|
-
};
|
|
16534
|
-
const dahuaResponse = await _removePlateNumber(dahuaPayload);
|
|
16535
|
-
if (!bypass && dahuaResponse?.statusCode !== 200) {
|
|
16536
|
-
throw new BadRequestError80("Failed to remove plate number to ANPR");
|
|
16537
|
-
}
|
|
16538
|
-
}
|
|
16539
|
-
await _deleteVehicle(_id, session);
|
|
16963
|
+
await _deleteExpiredVehicles();
|
|
16540
16964
|
await session.commitTransaction();
|
|
16541
|
-
return
|
|
16965
|
+
return `Expired Vehicle plate numbers deleted successfully.`;
|
|
16542
16966
|
} catch (error) {
|
|
16543
16967
|
await session.abortTransaction();
|
|
16544
16968
|
if (error instanceof AppError14)
|
|
@@ -16550,7 +16974,9 @@ function useVehicleService() {
|
|
|
16550
16974
|
}
|
|
16551
16975
|
return {
|
|
16552
16976
|
add,
|
|
16553
|
-
deleteVehicle
|
|
16977
|
+
deleteVehicle,
|
|
16978
|
+
approveVehicleById,
|
|
16979
|
+
processDeletingExpiredVehicles
|
|
16554
16980
|
};
|
|
16555
16981
|
}
|
|
16556
16982
|
|
|
@@ -16558,12 +16984,17 @@ function useVehicleService() {
|
|
|
16558
16984
|
import { BadRequestError as BadRequestError81, logger as logger65 } from "@7365admin1/node-server-utils";
|
|
16559
16985
|
import Joi46 from "joi";
|
|
16560
16986
|
function useVehicleController() {
|
|
16561
|
-
const {
|
|
16987
|
+
const {
|
|
16988
|
+
add: _add,
|
|
16989
|
+
deleteVehicle: _deleteVehicle,
|
|
16990
|
+
approveVehicleById: _approveVehicleById
|
|
16991
|
+
} = useVehicleService();
|
|
16562
16992
|
const {
|
|
16563
16993
|
getSeasonPassTypes: _getSeasonPassTypes,
|
|
16564
16994
|
getVehicles: _getVehicles,
|
|
16565
16995
|
getVehicleById: _getVehicleById,
|
|
16566
|
-
updateVehicle: _updateVehicle
|
|
16996
|
+
updateVehicle: _updateVehicle,
|
|
16997
|
+
getVehiclesByNRIC: _getVehiclesByNRIC
|
|
16567
16998
|
} = useVehicleRepo();
|
|
16568
16999
|
async function add(req, res, next) {
|
|
16569
17000
|
const payload = req.body;
|
|
@@ -16594,8 +17025,9 @@ function useVehicleController() {
|
|
|
16594
17025
|
limit: Joi46.number().integer().min(1).max(100).allow("", null).default(10),
|
|
16595
17026
|
sort: Joi46.string().pattern(/^([a-zA-Z0-9_]+)(,[a-zA-Z0-9_]+)*$/).optional().allow("", ...allowedFields),
|
|
16596
17027
|
order: Joi46.string().pattern(/^(asc|desc)(,(asc|desc))*$/).optional().allow("", ...allowedOrder),
|
|
16597
|
-
type: Joi46.string().optional().
|
|
16598
|
-
category: Joi46.string().optional().
|
|
17028
|
+
type: Joi46.string().optional().valid(...Object.values(VehicleType)),
|
|
17029
|
+
category: Joi46.string().optional().valid(...Object.values(VehicleCategory)),
|
|
17030
|
+
status: Joi46.string().optional().valid(...Object.values(VehicleStatus)).allow("")
|
|
16599
17031
|
});
|
|
16600
17032
|
const query = { ...req.query };
|
|
16601
17033
|
const { error } = validation.validate(query);
|
|
@@ -16609,6 +17041,7 @@ function useVehicleController() {
|
|
|
16609
17041
|
const limit = parseInt(req.query.limit ?? "10");
|
|
16610
17042
|
const type = req.query.type ?? "";
|
|
16611
17043
|
const category = req.query.category ?? "";
|
|
17044
|
+
const status = req.query.status ?? "";
|
|
16612
17045
|
const sortObj = {};
|
|
16613
17046
|
const sortFields = String(req.query.sort).split(",");
|
|
16614
17047
|
const sortOrders = String(req.query.order).split(",");
|
|
@@ -16625,7 +17058,8 @@ function useVehicleController() {
|
|
|
16625
17058
|
limit,
|
|
16626
17059
|
sort: sortObj,
|
|
16627
17060
|
type,
|
|
16628
|
-
category
|
|
17061
|
+
category,
|
|
17062
|
+
status
|
|
16629
17063
|
});
|
|
16630
17064
|
res.json(data);
|
|
16631
17065
|
return;
|
|
@@ -16681,7 +17115,8 @@ function useVehicleController() {
|
|
|
16681
17115
|
block: Joi46.number().integer().optional().allow(0, null),
|
|
16682
17116
|
level: Joi46.string().optional().allow("", null),
|
|
16683
17117
|
unit: Joi46.string().optional().allow("", null),
|
|
16684
|
-
plateNumber: Joi46.string().optional().allow("", null)
|
|
17118
|
+
plateNumber: Joi46.string().optional().allow("", null),
|
|
17119
|
+
nric: Joi46.string().optional().allow("", null)
|
|
16685
17120
|
});
|
|
16686
17121
|
const _id = req.params.id;
|
|
16687
17122
|
const payload = { ...req.body };
|
|
@@ -16702,23 +17137,23 @@ function useVehicleController() {
|
|
|
16702
17137
|
}
|
|
16703
17138
|
}
|
|
16704
17139
|
async function deleteVehicle(req, res, next) {
|
|
16705
|
-
const
|
|
16706
|
-
const _id = req.params.id ?? "";
|
|
16707
|
-
const recno = req.params.recno ?? "";
|
|
16708
|
-
const bypass = req.query.bypass === "true";
|
|
17140
|
+
const _id = req.params.id;
|
|
16709
17141
|
const deleteVehicleSchema = Joi46.object({
|
|
16710
|
-
_id: Joi46.string().hex().required(),
|
|
17142
|
+
_id: Joi46.string().hex().length(24).required(),
|
|
16711
17143
|
recno: Joi46.string().required(),
|
|
16712
|
-
|
|
17144
|
+
site: Joi46.string().hex().length(24).required(),
|
|
17145
|
+
type: Joi46.string().valid("whitelist", "blocklist").required(),
|
|
17146
|
+
bypass: Joi46.boolean().optional().default(true)
|
|
16713
17147
|
});
|
|
16714
|
-
const { error } = deleteVehicleSchema.validate({ _id,
|
|
17148
|
+
const { error, value } = deleteVehicleSchema.validate({ _id, ...req.body });
|
|
16715
17149
|
if (error) {
|
|
16716
17150
|
logger65.log({ level: "error", message: error.message });
|
|
16717
17151
|
next(new BadRequestError81(error.message));
|
|
16718
17152
|
return;
|
|
16719
17153
|
}
|
|
17154
|
+
const { recno, site, type, bypass } = value;
|
|
16720
17155
|
try {
|
|
16721
|
-
const data = await _deleteVehicle(_id, recno, site, bypass);
|
|
17156
|
+
const data = await _deleteVehicle(_id, recno, site, type, bypass);
|
|
16722
17157
|
res.json({
|
|
16723
17158
|
message: "Vehicle deleted successfully.",
|
|
16724
17159
|
data
|
|
@@ -16729,13 +17164,83 @@ function useVehicleController() {
|
|
|
16729
17164
|
return;
|
|
16730
17165
|
}
|
|
16731
17166
|
}
|
|
17167
|
+
async function approveVehicleById(req, res, next) {
|
|
17168
|
+
const validation = Joi46.object({
|
|
17169
|
+
_id: Joi46.string().hex().length(24).required(),
|
|
17170
|
+
org: Joi46.string().hex().length(24).required(),
|
|
17171
|
+
site: Joi46.string().hex().length(24).required()
|
|
17172
|
+
});
|
|
17173
|
+
const _id = req.params.id;
|
|
17174
|
+
const payload = { ...req.body };
|
|
17175
|
+
const { error, value } = validation.validate({ _id, ...payload });
|
|
17176
|
+
if (error) {
|
|
17177
|
+
logger65.log({ level: "error", message: error.message });
|
|
17178
|
+
next(new BadRequestError81(error.message));
|
|
17179
|
+
return;
|
|
17180
|
+
}
|
|
17181
|
+
try {
|
|
17182
|
+
await _approveVehicleById(value._id, value.org, value.site);
|
|
17183
|
+
res.json({ message: "Successfully approved and updated vehicle." });
|
|
17184
|
+
return;
|
|
17185
|
+
} catch (error2) {
|
|
17186
|
+
logger65.log({ level: "error", message: error2.message });
|
|
17187
|
+
next(error2);
|
|
17188
|
+
return;
|
|
17189
|
+
}
|
|
17190
|
+
}
|
|
17191
|
+
async function getVehiclesByNRIC(req, res, next) {
|
|
17192
|
+
const allowedFields = ["start", "end"];
|
|
17193
|
+
const allowedOrder = ["asc", "desc"];
|
|
17194
|
+
const validation = Joi46.object({
|
|
17195
|
+
search: Joi46.string().optional().allow("", null),
|
|
17196
|
+
page: Joi46.number().integer().min(1).allow("", null).default(1),
|
|
17197
|
+
limit: Joi46.number().integer().min(1).max(100).allow("", null).default(10),
|
|
17198
|
+
sort: Joi46.string().pattern(/^([a-zA-Z0-9_]+)(,[a-zA-Z0-9_]+)*$/).optional().allow("", ...allowedFields),
|
|
17199
|
+
order: Joi46.string().pattern(/^(asc|desc)(,(asc|desc))*$/).optional().allow("", ...allowedOrder)
|
|
17200
|
+
});
|
|
17201
|
+
const query = { ...req.query };
|
|
17202
|
+
const { error } = validation.validate(query);
|
|
17203
|
+
if (error) {
|
|
17204
|
+
logger65.log({ level: "error", message: error.message });
|
|
17205
|
+
next(new BadRequestError81(error.message));
|
|
17206
|
+
return;
|
|
17207
|
+
}
|
|
17208
|
+
const search = req.query.search ?? "";
|
|
17209
|
+
const page = parseInt(req.query.page ?? "1");
|
|
17210
|
+
const limit = parseInt(req.query.limit ?? "10");
|
|
17211
|
+
const sortObj = {};
|
|
17212
|
+
const sortFields = String(req.query.sort).split(",");
|
|
17213
|
+
const sortOrders = String(req.query.order).split(",");
|
|
17214
|
+
sortFields.forEach((field, index) => {
|
|
17215
|
+
if (allowedFields.includes(field)) {
|
|
17216
|
+
const order = sortOrders[index] === "asc" ? 1 : -1;
|
|
17217
|
+
sortObj[field] = order;
|
|
17218
|
+
}
|
|
17219
|
+
});
|
|
17220
|
+
try {
|
|
17221
|
+
const data = await _getVehiclesByNRIC({
|
|
17222
|
+
search,
|
|
17223
|
+
page,
|
|
17224
|
+
limit,
|
|
17225
|
+
sort: sortObj
|
|
17226
|
+
});
|
|
17227
|
+
res.json(data);
|
|
17228
|
+
return;
|
|
17229
|
+
} catch (error2) {
|
|
17230
|
+
logger65.log({ level: "error", message: error2.message });
|
|
17231
|
+
next(error2);
|
|
17232
|
+
return;
|
|
17233
|
+
}
|
|
17234
|
+
}
|
|
16732
17235
|
return {
|
|
16733
17236
|
add,
|
|
16734
17237
|
getVehicles,
|
|
16735
17238
|
getSeasonPassTypes,
|
|
16736
17239
|
getVehicleById,
|
|
16737
17240
|
updateVehicle,
|
|
16738
|
-
deleteVehicle
|
|
17241
|
+
deleteVehicle,
|
|
17242
|
+
approveVehicleById,
|
|
17243
|
+
getVehiclesByNRIC
|
|
16739
17244
|
};
|
|
16740
17245
|
}
|
|
16741
17246
|
|
|
@@ -16837,7 +17342,7 @@ function useSiteCameraController() {
|
|
|
16837
17342
|
}
|
|
16838
17343
|
async function getAll(req, res, next) {
|
|
16839
17344
|
const query = req.query;
|
|
16840
|
-
const
|
|
17345
|
+
const allowedTypes = ["ip", "exit", "entry", "both"];
|
|
16841
17346
|
const validation = Joi47.object({
|
|
16842
17347
|
type: Joi47.string().optional(),
|
|
16843
17348
|
site: Joi47.string().optional(),
|
|
@@ -20153,7 +20658,10 @@ function usePatrolQuestionRepo() {
|
|
|
20153
20658
|
const query = {
|
|
20154
20659
|
status,
|
|
20155
20660
|
...search && {
|
|
20156
|
-
$or: [
|
|
20661
|
+
$or: [
|
|
20662
|
+
{ question: { $regex: search, $options: "i" } },
|
|
20663
|
+
{ answers: { $regex: search, $options: "i" } }
|
|
20664
|
+
]
|
|
20157
20665
|
},
|
|
20158
20666
|
...ObjectId58.isValid(site) && { site: new ObjectId58(site) }
|
|
20159
20667
|
};
|
|
@@ -20581,9 +21089,6 @@ function usePatrolRouteRepo() {
|
|
|
20581
21089
|
page = page > 0 ? page - 1 : 0;
|
|
20582
21090
|
const query = {
|
|
20583
21091
|
status,
|
|
20584
|
-
...search && {
|
|
20585
|
-
$or: [{ name: { $regex: search, $options: "i" } }]
|
|
20586
|
-
},
|
|
20587
21092
|
...ObjectId60.isValid(site) && { site: new ObjectId60(site) }
|
|
20588
21093
|
};
|
|
20589
21094
|
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
@@ -20603,14 +21108,57 @@ function usePatrolRouteRepo() {
|
|
|
20603
21108
|
}
|
|
20604
21109
|
try {
|
|
20605
21110
|
const basePipeline = [
|
|
20606
|
-
{
|
|
21111
|
+
{
|
|
21112
|
+
$lookup: {
|
|
21113
|
+
from: "members",
|
|
21114
|
+
localField: "assignee",
|
|
21115
|
+
foreignField: "_id",
|
|
21116
|
+
as: "assigneeData"
|
|
21117
|
+
}
|
|
21118
|
+
},
|
|
21119
|
+
{
|
|
21120
|
+
$match: {
|
|
21121
|
+
...query,
|
|
21122
|
+
...search && {
|
|
21123
|
+
$or: [
|
|
21124
|
+
{ name: { $regex: search, $options: "i" } },
|
|
21125
|
+
{ "assigneeData.name": { $regex: search, $options: "i" } },
|
|
21126
|
+
{ start: { $regex: search, $options: "i" } },
|
|
21127
|
+
{ end: { $regex: search, $options: "i" } }
|
|
21128
|
+
]
|
|
21129
|
+
}
|
|
21130
|
+
}
|
|
21131
|
+
},
|
|
20607
21132
|
{ $sort: sort },
|
|
20608
21133
|
{ $skip: page * limit },
|
|
20609
21134
|
{ $limit: limit }
|
|
20610
21135
|
];
|
|
21136
|
+
const countPipeline = [
|
|
21137
|
+
{
|
|
21138
|
+
$lookup: {
|
|
21139
|
+
from: "members",
|
|
21140
|
+
localField: "assignee",
|
|
21141
|
+
foreignField: "_id",
|
|
21142
|
+
as: "assigneeData"
|
|
21143
|
+
}
|
|
21144
|
+
},
|
|
21145
|
+
{
|
|
21146
|
+
$match: {
|
|
21147
|
+
...query,
|
|
21148
|
+
...search && {
|
|
21149
|
+
$or: [
|
|
21150
|
+
{ name: { $regex: search, $options: "i" } },
|
|
21151
|
+
{ "assigneeData.name": { $regex: search, $options: "i" } },
|
|
21152
|
+
{ start: { $regex: search, $options: "i" } },
|
|
21153
|
+
{ end: { $regex: search, $options: "i" } }
|
|
21154
|
+
]
|
|
21155
|
+
}
|
|
21156
|
+
}
|
|
21157
|
+
}
|
|
21158
|
+
];
|
|
20611
21159
|
const [items, countResult] = await Promise.all([
|
|
20612
21160
|
collection.aggregate(basePipeline, { session }).toArray(),
|
|
20613
|
-
collection.aggregate([
|
|
21161
|
+
collection.aggregate([...countPipeline, { $count: "total" }], { session }).toArray()
|
|
20614
21162
|
]);
|
|
20615
21163
|
const totalCount = countResult[0]?.total || 0;
|
|
20616
21164
|
const data = paginate27(items, page, limit, totalCount);
|
|
@@ -20719,24 +21267,16 @@ function usePatrolRouteRepo() {
|
|
|
20719
21267
|
{
|
|
20720
21268
|
$multiply: [
|
|
20721
21269
|
{
|
|
20722
|
-
$
|
|
20723
|
-
$
|
|
20724
|
-
startDate: { $toDate: "$start" },
|
|
20725
|
-
unit: "hour",
|
|
20726
|
-
amount: 8
|
|
20727
|
-
}
|
|
21270
|
+
$toInt: {
|
|
21271
|
+
$arrayElemAt: [{ $split: ["$start", ":"] }, 0]
|
|
20728
21272
|
}
|
|
20729
21273
|
},
|
|
20730
21274
|
60
|
|
20731
21275
|
]
|
|
20732
21276
|
},
|
|
20733
21277
|
{
|
|
20734
|
-
$
|
|
20735
|
-
$
|
|
20736
|
-
startDate: { $toDate: "$start" },
|
|
20737
|
-
unit: "hour",
|
|
20738
|
-
amount: 8
|
|
20739
|
-
}
|
|
21278
|
+
$toInt: {
|
|
21279
|
+
$arrayElemAt: [{ $split: ["$start", ":"] }, 1]
|
|
20740
21280
|
}
|
|
20741
21281
|
}
|
|
20742
21282
|
]
|
|
@@ -20749,24 +21289,16 @@ function usePatrolRouteRepo() {
|
|
|
20749
21289
|
{
|
|
20750
21290
|
$multiply: [
|
|
20751
21291
|
{
|
|
20752
|
-
$
|
|
20753
|
-
$
|
|
20754
|
-
startDate: { $toDate: "$end" },
|
|
20755
|
-
unit: "hour",
|
|
20756
|
-
amount: 8
|
|
20757
|
-
}
|
|
21292
|
+
$toInt: {
|
|
21293
|
+
$arrayElemAt: [{ $split: ["$end", ":"] }, 0]
|
|
20758
21294
|
}
|
|
20759
21295
|
},
|
|
20760
21296
|
60
|
|
20761
21297
|
]
|
|
20762
21298
|
},
|
|
20763
21299
|
{
|
|
20764
|
-
$
|
|
20765
|
-
$
|
|
20766
|
-
startDate: { $toDate: "$end" },
|
|
20767
|
-
unit: "hour",
|
|
20768
|
-
amount: 8
|
|
20769
|
-
}
|
|
21300
|
+
$toInt: {
|
|
21301
|
+
$arrayElemAt: [{ $split: ["$end", ":"] }, 1]
|
|
20770
21302
|
}
|
|
20771
21303
|
}
|
|
20772
21304
|
]
|
|
@@ -21104,6 +21636,8 @@ var schemeLogCamera = Joi65.object({
|
|
|
21104
21636
|
start: Joi65.string().optional().allow("", null),
|
|
21105
21637
|
end: Joi65.string().optional().allow("", null),
|
|
21106
21638
|
duration: Joi65.number().optional().allow("", null),
|
|
21639
|
+
status: Joi65.string().optional().allow("", null),
|
|
21640
|
+
description: Joi65.string().optional().allow("", null),
|
|
21107
21641
|
questions: Joi65.array().items(
|
|
21108
21642
|
Joi65.object({
|
|
21109
21643
|
questionId: Joi65.string().hex().required(),
|
|
@@ -21124,7 +21658,7 @@ var schemaPatrolLog = Joi65.object({
|
|
|
21124
21658
|
start: Joi65.string().required(),
|
|
21125
21659
|
end: Joi65.string().required(),
|
|
21126
21660
|
cameras: Joi65.array().items(schemeLogCamera).required(),
|
|
21127
|
-
status: Joi65.array().items(Joi65.string().valid("complete", "late")).required(),
|
|
21661
|
+
status: Joi65.array().items(Joi65.string().valid("complete", "late", "incomplete")).required(),
|
|
21128
21662
|
createdAt: Joi65.date().optional(),
|
|
21129
21663
|
updatedAt: Joi65.date().optional(),
|
|
21130
21664
|
deletedAt: Joi65.date().optional()
|
|
@@ -21137,7 +21671,7 @@ var schemaUpdatePatrolLog = Joi65.object({
|
|
|
21137
21671
|
start: Joi65.string().optional().allow(null, ""),
|
|
21138
21672
|
end: Joi65.string().optional().allow(null, ""),
|
|
21139
21673
|
cameras: Joi65.array().items(schemeLogCamera).optional().allow(null, ""),
|
|
21140
|
-
status: Joi65.array().items(Joi65.string().valid("complete", "late")).optional().allow(null, "")
|
|
21674
|
+
status: Joi65.array().items(Joi65.string().valid("complete", "late", "incomplete")).optional().allow(null, "")
|
|
21141
21675
|
});
|
|
21142
21676
|
function MPatrolLog(value) {
|
|
21143
21677
|
const { error } = schemaPatrolLog.validate(value);
|
|
@@ -21275,9 +21809,6 @@ function usePatrolLogRepo() {
|
|
|
21275
21809
|
}, session) {
|
|
21276
21810
|
page = page > 0 ? page - 1 : 0;
|
|
21277
21811
|
const query = {
|
|
21278
|
-
...search && {
|
|
21279
|
-
$or: [{ name: { $regex: search, $options: "i" } }]
|
|
21280
|
-
},
|
|
21281
21812
|
...ObjectId62.isValid(site) && { site: new ObjectId62(site) }
|
|
21282
21813
|
};
|
|
21283
21814
|
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
@@ -21297,14 +21828,113 @@ function usePatrolLogRepo() {
|
|
|
21297
21828
|
}
|
|
21298
21829
|
try {
|
|
21299
21830
|
const basePipeline = [
|
|
21300
|
-
{
|
|
21831
|
+
{
|
|
21832
|
+
$lookup: {
|
|
21833
|
+
from: "members",
|
|
21834
|
+
localField: "assignee",
|
|
21835
|
+
foreignField: "_id",
|
|
21836
|
+
as: "assigneeData"
|
|
21837
|
+
}
|
|
21838
|
+
},
|
|
21839
|
+
{
|
|
21840
|
+
$match: {
|
|
21841
|
+
...query,
|
|
21842
|
+
...search && {
|
|
21843
|
+
$or: [
|
|
21844
|
+
{ name: { $regex: search, $options: "i" } },
|
|
21845
|
+
{ "assigneeData.name": { $regex: search, $options: "i" } },
|
|
21846
|
+
{
|
|
21847
|
+
$expr: {
|
|
21848
|
+
$regexMatch: {
|
|
21849
|
+
input: {
|
|
21850
|
+
$dateToString: {
|
|
21851
|
+
date: { $toDate: "$start" },
|
|
21852
|
+
format: "%H:%M",
|
|
21853
|
+
timezone: "Asia/Singapore"
|
|
21854
|
+
}
|
|
21855
|
+
},
|
|
21856
|
+
regex: search,
|
|
21857
|
+
options: "i"
|
|
21858
|
+
}
|
|
21859
|
+
}
|
|
21860
|
+
},
|
|
21861
|
+
{
|
|
21862
|
+
$expr: {
|
|
21863
|
+
$regexMatch: {
|
|
21864
|
+
input: {
|
|
21865
|
+
$dateToString: {
|
|
21866
|
+
date: { $toDate: "$start" },
|
|
21867
|
+
format: "%H:%M",
|
|
21868
|
+
timezone: "Asia/Singapore"
|
|
21869
|
+
}
|
|
21870
|
+
},
|
|
21871
|
+
regex: search,
|
|
21872
|
+
options: "i"
|
|
21873
|
+
}
|
|
21874
|
+
}
|
|
21875
|
+
}
|
|
21876
|
+
]
|
|
21877
|
+
}
|
|
21878
|
+
}
|
|
21879
|
+
},
|
|
21301
21880
|
{ $sort: sort },
|
|
21302
21881
|
{ $skip: page * limit },
|
|
21303
21882
|
{ $limit: limit }
|
|
21304
21883
|
];
|
|
21884
|
+
const countPipeline = [
|
|
21885
|
+
{
|
|
21886
|
+
$lookup: {
|
|
21887
|
+
from: "members",
|
|
21888
|
+
localField: "assignee",
|
|
21889
|
+
foreignField: "_id",
|
|
21890
|
+
as: "assigneeData"
|
|
21891
|
+
}
|
|
21892
|
+
},
|
|
21893
|
+
{
|
|
21894
|
+
$match: {
|
|
21895
|
+
...query,
|
|
21896
|
+
...search && {
|
|
21897
|
+
$or: [
|
|
21898
|
+
{ name: { $regex: search, $options: "i" } },
|
|
21899
|
+
{ "assigneeData.name": { $regex: search, $options: "i" } },
|
|
21900
|
+
{
|
|
21901
|
+
$expr: {
|
|
21902
|
+
$regexMatch: {
|
|
21903
|
+
input: {
|
|
21904
|
+
$dateToString: {
|
|
21905
|
+
date: { $toDate: "$start" },
|
|
21906
|
+
format: "%H:%M",
|
|
21907
|
+
timezone: "Asia/Singapore"
|
|
21908
|
+
}
|
|
21909
|
+
},
|
|
21910
|
+
regex: search,
|
|
21911
|
+
options: "i"
|
|
21912
|
+
}
|
|
21913
|
+
}
|
|
21914
|
+
},
|
|
21915
|
+
{
|
|
21916
|
+
$expr: {
|
|
21917
|
+
$regexMatch: {
|
|
21918
|
+
input: {
|
|
21919
|
+
$dateToString: {
|
|
21920
|
+
date: { $toDate: "$start" },
|
|
21921
|
+
format: "%H:%M",
|
|
21922
|
+
timezone: "Asia/Singapore"
|
|
21923
|
+
}
|
|
21924
|
+
},
|
|
21925
|
+
regex: search,
|
|
21926
|
+
options: "i"
|
|
21927
|
+
}
|
|
21928
|
+
}
|
|
21929
|
+
}
|
|
21930
|
+
]
|
|
21931
|
+
}
|
|
21932
|
+
}
|
|
21933
|
+
}
|
|
21934
|
+
];
|
|
21305
21935
|
const [items, countResult] = await Promise.all([
|
|
21306
21936
|
collection.aggregate(basePipeline, { session }).toArray(),
|
|
21307
|
-
collection.aggregate([
|
|
21937
|
+
collection.aggregate([...countPipeline, { $count: "total" }], { session }).toArray()
|
|
21308
21938
|
]);
|
|
21309
21939
|
const totalCount = countResult[0]?.total || 0;
|
|
21310
21940
|
const data = paginate28(items, page, limit, totalCount);
|
|
@@ -24197,20 +24827,19 @@ function useDocumentManagementController() {
|
|
|
24197
24827
|
// src/models/bulletin-board.model.ts
|
|
24198
24828
|
import Joi75 from "joi";
|
|
24199
24829
|
import { ObjectId as ObjectId71 } from "mongodb";
|
|
24830
|
+
var BULLETIN_RECIPIENTS = [
|
|
24831
|
+
"resident",
|
|
24832
|
+
"security_agency",
|
|
24833
|
+
"cleaning_services",
|
|
24834
|
+
"mechanical_electrical",
|
|
24835
|
+
"property_management_agency"
|
|
24836
|
+
];
|
|
24837
|
+
var STATUS_VALUES = ["active", "expired", "deleted"];
|
|
24200
24838
|
var schemaBulletinBoard = Joi75.object({
|
|
24201
24839
|
_id: Joi75.string().hex().optional().allow("", null),
|
|
24202
24840
|
site: Joi75.string().hex().optional().allow("", null),
|
|
24203
24841
|
orgId: Joi75.string().hex().optional().allow("", null),
|
|
24204
|
-
recipients: Joi75.array().items(
|
|
24205
|
-
Joi75.string().valid(
|
|
24206
|
-
"admin",
|
|
24207
|
-
"organization",
|
|
24208
|
-
"site",
|
|
24209
|
-
"service-provider",
|
|
24210
|
-
"service-provider-member",
|
|
24211
|
-
"resident"
|
|
24212
|
-
)
|
|
24213
|
-
).optional(),
|
|
24842
|
+
recipients: Joi75.array().items(Joi75.string().valid(...BULLETIN_RECIPIENTS)).unique().optional(),
|
|
24214
24843
|
title: Joi75.string().optional().allow("", null),
|
|
24215
24844
|
content: Joi75.string().optional().allow("", null),
|
|
24216
24845
|
file: Joi75.array().items(
|
|
@@ -24223,23 +24852,14 @@ var schemaBulletinBoard = Joi75.object({
|
|
|
24223
24852
|
noExpiration: Joi75.boolean().optional(),
|
|
24224
24853
|
startDate: Joi75.date().optional().allow("", null),
|
|
24225
24854
|
endDate: Joi75.date().optional().allow("", null),
|
|
24226
|
-
status: Joi75.string().
|
|
24855
|
+
status: Joi75.string().valid(...STATUS_VALUES).optional(),
|
|
24227
24856
|
createdAt: Joi75.date().optional().allow(null),
|
|
24228
24857
|
updatedAt: Joi75.date().optional().allow(null),
|
|
24229
24858
|
deletedAt: Joi75.date().optional().allow(null)
|
|
24230
24859
|
});
|
|
24231
24860
|
var schemaUpdateBulletinBoard = Joi75.object({
|
|
24232
24861
|
_id: Joi75.string().hex().required(),
|
|
24233
|
-
recipients: Joi75.array().items(
|
|
24234
|
-
Joi75.string().valid(
|
|
24235
|
-
"admin",
|
|
24236
|
-
"organization",
|
|
24237
|
-
"site",
|
|
24238
|
-
"service-provider",
|
|
24239
|
-
"service-provider-member",
|
|
24240
|
-
"resident"
|
|
24241
|
-
)
|
|
24242
|
-
).optional(),
|
|
24862
|
+
recipients: Joi75.array().items(Joi75.string().valid(...BULLETIN_RECIPIENTS)).unique().optional(),
|
|
24243
24863
|
title: Joi75.string().optional().allow("", null),
|
|
24244
24864
|
content: Joi75.string().optional().allow("", null),
|
|
24245
24865
|
file: Joi75.array().items(
|
|
@@ -24252,7 +24872,7 @@ var schemaUpdateBulletinBoard = Joi75.object({
|
|
|
24252
24872
|
noExpiration: Joi75.boolean().optional(),
|
|
24253
24873
|
startDate: Joi75.date().optional().allow("", null),
|
|
24254
24874
|
endDate: Joi75.date().optional().allow("", null),
|
|
24255
|
-
status: Joi75.string().
|
|
24875
|
+
status: Joi75.string().valid(...STATUS_VALUES).optional()
|
|
24256
24876
|
});
|
|
24257
24877
|
function MBulletinBoard(value) {
|
|
24258
24878
|
const { error } = schemaBulletinBoard.validate(value);
|
|
@@ -24352,7 +24972,8 @@ function useBulletinBoardRepo() {
|
|
|
24352
24972
|
limit = 10,
|
|
24353
24973
|
sort = {},
|
|
24354
24974
|
site = "",
|
|
24355
|
-
status = "active"
|
|
24975
|
+
status = "active",
|
|
24976
|
+
recipients = []
|
|
24356
24977
|
}, session) {
|
|
24357
24978
|
page = page > 0 ? page - 1 : 0;
|
|
24358
24979
|
try {
|
|
@@ -24362,7 +24983,9 @@ function useBulletinBoardRepo() {
|
|
|
24362
24983
|
}
|
|
24363
24984
|
const query = {
|
|
24364
24985
|
site,
|
|
24365
|
-
status
|
|
24986
|
+
status,
|
|
24987
|
+
...search && { $text: { $search: search } },
|
|
24988
|
+
...recipients?.length && { recipients: { $in: recipients } }
|
|
24366
24989
|
};
|
|
24367
24990
|
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
24368
24991
|
const cacheOptions = {
|
|
@@ -24370,12 +24993,10 @@ function useBulletinBoardRepo() {
|
|
|
24370
24993
|
status,
|
|
24371
24994
|
sort: JSON.stringify(sort),
|
|
24372
24995
|
page,
|
|
24373
|
-
limit
|
|
24996
|
+
limit,
|
|
24997
|
+
...search && { search },
|
|
24998
|
+
...recipients?.length && { recipients: recipients.sort().join(",") }
|
|
24374
24999
|
};
|
|
24375
|
-
if (search) {
|
|
24376
|
-
query.$text = { $search: search };
|
|
24377
|
-
cacheOptions.search = search;
|
|
24378
|
-
}
|
|
24379
25000
|
const cacheKey = makeCacheKey39(namespace_collection, cacheOptions);
|
|
24380
25001
|
const cachedData = await getCache(cacheKey);
|
|
24381
25002
|
if (cachedData) {
|
|
@@ -24467,7 +25088,7 @@ function useBulletinBoardRepo() {
|
|
|
24467
25088
|
throw error;
|
|
24468
25089
|
}
|
|
24469
25090
|
}
|
|
24470
|
-
async function deleteBulletinBoardById(_id) {
|
|
25091
|
+
async function deleteBulletinBoardById(_id, session) {
|
|
24471
25092
|
try {
|
|
24472
25093
|
_id = new ObjectId72(_id);
|
|
24473
25094
|
} catch (error) {
|
|
@@ -24479,7 +25100,11 @@ function useBulletinBoardRepo() {
|
|
|
24479
25100
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
24480
25101
|
deletedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
24481
25102
|
};
|
|
24482
|
-
const res = await collection.updateOne(
|
|
25103
|
+
const res = await collection.updateOne(
|
|
25104
|
+
{ _id },
|
|
25105
|
+
{ $set: updateValue },
|
|
25106
|
+
{ session }
|
|
25107
|
+
);
|
|
24483
25108
|
if (res.modifiedCount === 0) {
|
|
24484
25109
|
throw new InternalServerError42("Unable to delete bulletin board.");
|
|
24485
25110
|
}
|
|
@@ -24545,8 +25170,11 @@ function useBulletinBoardService() {
|
|
|
24545
25170
|
const {
|
|
24546
25171
|
add: _add,
|
|
24547
25172
|
updateBulletinBoardById: _updateBulletinBoardById,
|
|
24548
|
-
processExpiredBulletinBoards: _processExpiredBulletinBoards
|
|
25173
|
+
processExpiredBulletinBoards: _processExpiredBulletinBoards,
|
|
25174
|
+
deleteBulletinBoardById: _deleteBulletinBoardById,
|
|
25175
|
+
getBulletinBoardById: _getBulletinBoardById
|
|
24549
25176
|
} = useBulletinBoardRepo();
|
|
25177
|
+
const { deleteFileById: _deleteFileById } = useFileRepo();
|
|
24550
25178
|
async function add(value) {
|
|
24551
25179
|
const session = useAtlas65.getClient()?.startSession();
|
|
24552
25180
|
session?.startTransaction();
|
|
@@ -24589,10 +25217,31 @@ function useBulletinBoardService() {
|
|
|
24589
25217
|
session?.endSession();
|
|
24590
25218
|
}
|
|
24591
25219
|
}
|
|
25220
|
+
async function deleteBulletinBoardById(id) {
|
|
25221
|
+
const session = useAtlas65.getClient()?.startSession();
|
|
25222
|
+
session?.startTransaction();
|
|
25223
|
+
try {
|
|
25224
|
+
const existingBulletinBoard = await _getBulletinBoardById(id);
|
|
25225
|
+
if (Array.isArray(existingBulletinBoard.file)) {
|
|
25226
|
+
for (const file of existingBulletinBoard.file) {
|
|
25227
|
+
await _deleteFileById(file, session);
|
|
25228
|
+
}
|
|
25229
|
+
}
|
|
25230
|
+
await _deleteBulletinBoardById(id, session);
|
|
25231
|
+
await session?.commitTransaction();
|
|
25232
|
+
return "Successfully deleted bulletin board.";
|
|
25233
|
+
} catch (error) {
|
|
25234
|
+
await session?.abortTransaction();
|
|
25235
|
+
throw error;
|
|
25236
|
+
} finally {
|
|
25237
|
+
session?.endSession();
|
|
25238
|
+
}
|
|
25239
|
+
}
|
|
24592
25240
|
return {
|
|
24593
25241
|
add,
|
|
24594
25242
|
updateBulletinBoardById,
|
|
24595
|
-
processExpiredBulletinBoards
|
|
25243
|
+
processExpiredBulletinBoards,
|
|
25244
|
+
deleteBulletinBoardById
|
|
24596
25245
|
};
|
|
24597
25246
|
}
|
|
24598
25247
|
|
|
@@ -24600,12 +25249,12 @@ function useBulletinBoardService() {
|
|
|
24600
25249
|
import { BadRequestError as BadRequestError123, logger as logger104 } from "@7365admin1/node-server-utils";
|
|
24601
25250
|
import Joi76 from "joi";
|
|
24602
25251
|
function useBulletinBoardController() {
|
|
24603
|
-
const { add: _add, updateBulletinBoardById: _updateBulletinBoardById } = useBulletinBoardService();
|
|
24604
25252
|
const {
|
|
24605
|
-
|
|
24606
|
-
|
|
25253
|
+
add: _add,
|
|
25254
|
+
updateBulletinBoardById: _updateBulletinBoardById,
|
|
24607
25255
|
deleteBulletinBoardById: _deleteBulletinBoardById
|
|
24608
|
-
} =
|
|
25256
|
+
} = useBulletinBoardService();
|
|
25257
|
+
const { getAll: _getAll, getBulletinBoardById: _getBulletinBoardById } = useBulletinBoardRepo();
|
|
24609
25258
|
async function add(req, res, next) {
|
|
24610
25259
|
const payload = { ...req.body };
|
|
24611
25260
|
const { error } = schemaBulletinBoard.validate(payload, {
|
|
@@ -24637,12 +25286,23 @@ function useBulletinBoardController() {
|
|
|
24637
25286
|
sort: Joi76.string().pattern(/^([a-zA-Z0-9_]+)(,[a-zA-Z0-9_]+)*$/).optional().allow("", ...allowedFields),
|
|
24638
25287
|
order: Joi76.string().pattern(/^(asc|desc)(,(asc|desc))*$/).optional().allow("", ...allowedOrder),
|
|
24639
25288
|
site: Joi76.string().hex().required(),
|
|
24640
|
-
status: Joi76.string().optional().allow(null, "")
|
|
25289
|
+
status: Joi76.string().optional().allow(null, ""),
|
|
25290
|
+
recipients: Joi76.string().optional().allow("", null).custom((value, helpers) => {
|
|
25291
|
+
const parsed = value.split(",").map((v) => v.trim()).filter(Boolean);
|
|
25292
|
+
for (const r of parsed) {
|
|
25293
|
+
if (!BULLETIN_RECIPIENTS.includes(r)) {
|
|
25294
|
+
return helpers.error("any.only");
|
|
25295
|
+
}
|
|
25296
|
+
}
|
|
25297
|
+
return value;
|
|
25298
|
+
}).messages({
|
|
25299
|
+
"any.only": `Recipients must be one of: ${BULLETIN_RECIPIENTS.join(
|
|
25300
|
+
", "
|
|
25301
|
+
)}`
|
|
25302
|
+
})
|
|
24641
25303
|
});
|
|
24642
25304
|
const query = { ...req.query };
|
|
24643
|
-
const { error } = validation.validate(query, {
|
|
24644
|
-
abortEarly: false
|
|
24645
|
-
});
|
|
25305
|
+
const { error } = validation.validate(query, { abortEarly: false });
|
|
24646
25306
|
if (error) {
|
|
24647
25307
|
const messages = error.details.map((d) => d.message).join(", ");
|
|
24648
25308
|
logger104.log({ level: "error", message: messages });
|
|
@@ -24654,9 +25314,15 @@ function useBulletinBoardController() {
|
|
|
24654
25314
|
const limit = parseInt(req.query.limit ?? "10");
|
|
24655
25315
|
const site = req.query.site ?? "";
|
|
24656
25316
|
const status = req.query.status ?? "active";
|
|
25317
|
+
const recipientsRaw = req.query.recipients ?? "";
|
|
25318
|
+
const recipients = recipientsRaw && typeof recipientsRaw === "string" ? Array.from(
|
|
25319
|
+
new Set(
|
|
25320
|
+
recipientsRaw.split(",").map((r) => r.trim()).filter(Boolean)
|
|
25321
|
+
)
|
|
25322
|
+
) : [];
|
|
24657
25323
|
const sortObj = {};
|
|
24658
|
-
const sortFields = String(req.query.sort).split(",");
|
|
24659
|
-
const sortOrders = String(req.query.order).split(",");
|
|
25324
|
+
const sortFields = String(req.query.sort ?? "").split(",").filter(Boolean);
|
|
25325
|
+
const sortOrders = String(req.query.order ?? "").split(",").filter(Boolean);
|
|
24660
25326
|
sortFields.forEach((field, index) => {
|
|
24661
25327
|
if (allowedFields.includes(field)) {
|
|
24662
25328
|
const order = sortOrders[index] === "asc" ? 1 : -1;
|
|
@@ -24670,7 +25336,8 @@ function useBulletinBoardController() {
|
|
|
24670
25336
|
limit,
|
|
24671
25337
|
sort: sortObj,
|
|
24672
25338
|
site,
|
|
24673
|
-
status
|
|
25339
|
+
status,
|
|
25340
|
+
recipients
|
|
24674
25341
|
});
|
|
24675
25342
|
res.status(200).json(data);
|
|
24676
25343
|
return;
|
|
@@ -24753,6 +25420,16 @@ function useBulletinBoardController() {
|
|
|
24753
25420
|
import { BadRequestError as BadRequestError124, logger as logger105 } from "@7365admin1/node-server-utils";
|
|
24754
25421
|
import { ObjectId as ObjectId73 } from "mongodb";
|
|
24755
25422
|
import Joi77 from "joi";
|
|
25423
|
+
|
|
25424
|
+
// src/types/enums/billing-frequency.enum.ts
|
|
25425
|
+
var EBillingFrequency = /* @__PURE__ */ ((EBillingFrequency2) => {
|
|
25426
|
+
EBillingFrequency2["MONTHLY"] = "monthly";
|
|
25427
|
+
EBillingFrequency2["QAURTERLY"] = "quarterly";
|
|
25428
|
+
EBillingFrequency2["ANNUALLY"] = "annually";
|
|
25429
|
+
return EBillingFrequency2;
|
|
25430
|
+
})(EBillingFrequency || {});
|
|
25431
|
+
|
|
25432
|
+
// src/models/site-billing-item.model.ts
|
|
24756
25433
|
var schemaUnits = Joi77.object({
|
|
24757
25434
|
_id: Joi77.string().hex().optional(),
|
|
24758
25435
|
name: Joi77.string().optional()
|
|
@@ -24763,7 +25440,7 @@ var schemaBillingItem = Joi77.object({
|
|
|
24763
25440
|
org: Joi77.string().hex().required(),
|
|
24764
25441
|
name: Joi77.string().required(),
|
|
24765
25442
|
amount: Joi77.number().required(),
|
|
24766
|
-
frequency: Joi77.string().valid(
|
|
25443
|
+
frequency: Joi77.string().valid(...Object.values(EBillingFrequency)).required(),
|
|
24767
25444
|
billingType: Joi77.string().valid("recurring", "non-recurring").required(),
|
|
24768
25445
|
dueInDays: Joi77.number().optional().allow(null, ""),
|
|
24769
25446
|
date: Joi77.string().required(),
|
|
@@ -24788,7 +25465,7 @@ var schemaUpdateSiteBillingItem = Joi77.object({
|
|
|
24788
25465
|
org: Joi77.string().hex().optional().allow(null, ""),
|
|
24789
25466
|
name: Joi77.string().optional().allow(null, ""),
|
|
24790
25467
|
amount: Joi77.number().optional().allow(null, ""),
|
|
24791
|
-
frequency: Joi77.string().valid(
|
|
25468
|
+
frequency: Joi77.string().valid(...Object.values(EBillingFrequency)).optional().allow(null, ""),
|
|
24792
25469
|
billingType: Joi77.string().valid("recurring", "non-recurring").optional().allow(null, ""),
|
|
24793
25470
|
dueInDays: Joi77.number().optional().allow(null, ""),
|
|
24794
25471
|
date: Joi77.string().optional().allow(null, ""),
|
|
@@ -24942,7 +25619,16 @@ function useSiteBillingItemRepo() {
|
|
|
24942
25619
|
...search && {
|
|
24943
25620
|
$or: [
|
|
24944
25621
|
{ name: { $regex: search, $options: "i" } },
|
|
24945
|
-
{ frequency: { $regex: search, $options: "i" } }
|
|
25622
|
+
{ frequency: { $regex: search, $options: "i" } },
|
|
25623
|
+
{
|
|
25624
|
+
$expr: {
|
|
25625
|
+
$regexMatch: {
|
|
25626
|
+
input: { $toString: "$totalAmount" },
|
|
25627
|
+
regex: search,
|
|
25628
|
+
options: "i"
|
|
25629
|
+
}
|
|
25630
|
+
}
|
|
25631
|
+
}
|
|
24946
25632
|
]
|
|
24947
25633
|
},
|
|
24948
25634
|
...ObjectId74.isValid(site) && { site: new ObjectId74(site) }
|
|
@@ -26009,14 +26695,16 @@ var schemaEventManagement = Joi81.object({
|
|
|
26009
26695
|
title: Joi81.string().required(),
|
|
26010
26696
|
description: Joi81.string().optional().allow(""),
|
|
26011
26697
|
dateTime: Joi81.alternatives().try(Joi81.string(), Joi81.date()).required(),
|
|
26012
|
-
status: Joi81.string().optional().default("planned")
|
|
26698
|
+
status: Joi81.string().optional().default("planned"),
|
|
26699
|
+
type: Joi81.string().optional().default("TASK")
|
|
26013
26700
|
});
|
|
26014
26701
|
var schemaUpdateEventManagement = Joi81.object({
|
|
26015
26702
|
_id: Joi81.string().hex().required(),
|
|
26016
26703
|
title: Joi81.string().optional().allow(null, ""),
|
|
26017
26704
|
description: Joi81.string().optional().allow(null, ""),
|
|
26018
26705
|
dateTime: Joi81.alternatives().try(Joi81.string(), Joi81.date()).optional().allow(null, ""),
|
|
26019
|
-
status: Joi81.string().optional().allow(null, "")
|
|
26706
|
+
status: Joi81.string().optional().allow(null, ""),
|
|
26707
|
+
type: Joi81.string().optional().allow(null, "")
|
|
26020
26708
|
});
|
|
26021
26709
|
function MEventManagement(value) {
|
|
26022
26710
|
if (value._id && typeof value._id === "string") {
|
|
@@ -26040,6 +26728,7 @@ function MEventManagement(value) {
|
|
|
26040
26728
|
description: value.description ?? "",
|
|
26041
26729
|
dateTime: value.dateTime,
|
|
26042
26730
|
status: value.status ?? "planned",
|
|
26731
|
+
type: value.type ?? "TASK",
|
|
26043
26732
|
createdAt: value.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
26044
26733
|
updatedAt: value.updatedAt,
|
|
26045
26734
|
deletedAt: value.deletedAt
|
|
@@ -26114,7 +26803,9 @@ function useEventManagementRepo() {
|
|
|
26114
26803
|
limit = 10,
|
|
26115
26804
|
sort = {},
|
|
26116
26805
|
site = "",
|
|
26117
|
-
status = ""
|
|
26806
|
+
status = "",
|
|
26807
|
+
type = "",
|
|
26808
|
+
date = ""
|
|
26118
26809
|
}, session) {
|
|
26119
26810
|
page = page > 0 ? page - 1 : 0;
|
|
26120
26811
|
try {
|
|
@@ -26124,7 +26815,14 @@ function useEventManagementRepo() {
|
|
|
26124
26815
|
}
|
|
26125
26816
|
const baseQuery = {
|
|
26126
26817
|
site,
|
|
26127
|
-
status: status ? status : { $ne: "deleted" }
|
|
26818
|
+
status: status ? status : { $ne: "deleted" },
|
|
26819
|
+
...type && { type },
|
|
26820
|
+
...date && {
|
|
26821
|
+
dateTime: {
|
|
26822
|
+
$gte: `${date}T00:00:00.000Z`,
|
|
26823
|
+
$lt: `${date}T23:59:59.999Z`
|
|
26824
|
+
}
|
|
26825
|
+
}
|
|
26128
26826
|
};
|
|
26129
26827
|
let query = { ...baseQuery };
|
|
26130
26828
|
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
@@ -26133,7 +26831,8 @@ function useEventManagementRepo() {
|
|
|
26133
26831
|
status: status ? status : { $ne: "deleted" },
|
|
26134
26832
|
sort: JSON.stringify(sort),
|
|
26135
26833
|
page,
|
|
26136
|
-
limit
|
|
26834
|
+
limit,
|
|
26835
|
+
...type && { type }
|
|
26137
26836
|
};
|
|
26138
26837
|
if (search) {
|
|
26139
26838
|
query.$text = { $search: search };
|
|
@@ -26420,7 +27119,9 @@ function useEventManagementController() {
|
|
|
26420
27119
|
sort: Joi82.string().pattern(/^([a-zA-Z0-9_]+)(,[a-zA-Z0-9_]+)*$/).optional().allow("", ...allowedFields),
|
|
26421
27120
|
order: Joi82.string().pattern(/^(asc|desc)(,(asc|desc))*$/).optional().allow("", ...allowedOrder),
|
|
26422
27121
|
site: Joi82.string().hex().required(),
|
|
26423
|
-
status: Joi82.string().optional()
|
|
27122
|
+
status: Joi82.string().optional(),
|
|
27123
|
+
type: Joi82.string().optional().valid("TASK", "EVENT").allow(null, ""),
|
|
27124
|
+
date: Joi82.string().optional().allow(null, "")
|
|
26424
27125
|
});
|
|
26425
27126
|
const query = { ...req.query };
|
|
26426
27127
|
const { error } = validation.validate(query, {
|
|
@@ -26437,6 +27138,8 @@ function useEventManagementController() {
|
|
|
26437
27138
|
const limit = parseInt(req.query.limit ?? "10");
|
|
26438
27139
|
const site = req.query.site ?? "";
|
|
26439
27140
|
const status = req.query.status ?? "";
|
|
27141
|
+
const type = req.query.type ?? "";
|
|
27142
|
+
const date = req.query.date ?? "";
|
|
26440
27143
|
const sortObj = {};
|
|
26441
27144
|
const sortFields = String(req.query.sort).split(",");
|
|
26442
27145
|
const sortOrders = String(req.query.order).split(",");
|
|
@@ -26453,7 +27156,9 @@ function useEventManagementController() {
|
|
|
26453
27156
|
limit,
|
|
26454
27157
|
sort: sortObj,
|
|
26455
27158
|
site,
|
|
26456
|
-
status
|
|
27159
|
+
status,
|
|
27160
|
+
type,
|
|
27161
|
+
date
|
|
26457
27162
|
});
|
|
26458
27163
|
res.status(200).json(data);
|
|
26459
27164
|
return;
|
|
@@ -26779,6 +27484,7 @@ function useSiteUnitBillingRepo() {
|
|
|
26779
27484
|
}
|
|
26780
27485
|
};
|
|
26781
27486
|
}
|
|
27487
|
+
const unitSearchRegex = search ? search.trim().replace(/\s+/g, "").replace(/\//g, "\\s*/\\s*") : null;
|
|
26782
27488
|
const query = {
|
|
26783
27489
|
paymentStatus,
|
|
26784
27490
|
status,
|
|
@@ -26786,7 +27492,16 @@ function useSiteUnitBillingRepo() {
|
|
|
26786
27492
|
$or: [
|
|
26787
27493
|
{ unitOwner: { $regex: search, $options: "i" } },
|
|
26788
27494
|
{ billName: { $regex: search, $options: "i" } },
|
|
26789
|
-
{ unit: { $regex:
|
|
27495
|
+
{ unit: { $regex: unitSearchRegex, $options: "i" } },
|
|
27496
|
+
{
|
|
27497
|
+
$expr: {
|
|
27498
|
+
$regexMatch: {
|
|
27499
|
+
input: { $toString: "$amountPaid" },
|
|
27500
|
+
regex: search,
|
|
27501
|
+
options: "i"
|
|
27502
|
+
}
|
|
27503
|
+
}
|
|
27504
|
+
}
|
|
26790
27505
|
]
|
|
26791
27506
|
},
|
|
26792
27507
|
...ObjectId80.isValid(site) && { site: new ObjectId80(site) },
|
|
@@ -27213,14 +27928,14 @@ function useSiteUnitBillingService() {
|
|
|
27213
27928
|
function isBillingChecker(billing_item, todayMonth, todayDate) {
|
|
27214
27929
|
const billingMonth = Number(billing_item.month);
|
|
27215
27930
|
const billingDay = Number(billing_item.date);
|
|
27216
|
-
if (billing_item.frequency === "
|
|
27931
|
+
if (billing_item.frequency === "monthly" /* MONTHLY */) {
|
|
27217
27932
|
return todayDate === billingDay;
|
|
27218
27933
|
}
|
|
27219
|
-
if (billing_item.frequency === "
|
|
27934
|
+
if (billing_item.frequency === "quarterly" /* QAURTERLY */) {
|
|
27220
27935
|
const monthDiff = todayMonth - billingMonth;
|
|
27221
27936
|
return monthDiff % 3 === 0 && todayDate === billingDay;
|
|
27222
27937
|
}
|
|
27223
|
-
if (billing_item.frequency === "
|
|
27938
|
+
if (billing_item.frequency === "annually" /* ANNUALLY */) {
|
|
27224
27939
|
return todayMonth === billingMonth && todayDate === billingDay;
|
|
27225
27940
|
}
|
|
27226
27941
|
return false;
|
|
@@ -27412,11 +28127,12 @@ var EAccessCardTypes = /* @__PURE__ */ ((EAccessCardTypes2) => {
|
|
|
27412
28127
|
EAccessCardTypes2["QR"] = "QRCODE";
|
|
27413
28128
|
return EAccessCardTypes2;
|
|
27414
28129
|
})(EAccessCardTypes || {});
|
|
27415
|
-
var EAccessCardUserTypes = /* @__PURE__ */ ((
|
|
27416
|
-
|
|
27417
|
-
|
|
27418
|
-
|
|
27419
|
-
|
|
28130
|
+
var EAccessCardUserTypes = /* @__PURE__ */ ((EAccessCardUserTypes2) => {
|
|
28131
|
+
EAccessCardUserTypes2["RESIDENT"] = "Resident/Tenant";
|
|
28132
|
+
EAccessCardUserTypes2["CONTRACTOR"] = "Contractor";
|
|
28133
|
+
EAccessCardUserTypes2["VISITOR"] = "Visitor";
|
|
28134
|
+
EAccessCardUserTypes2["DEFAULT"] = "Visitor/Resident";
|
|
28135
|
+
return EAccessCardUserTypes2;
|
|
27420
28136
|
})(EAccessCardUserTypes || {});
|
|
27421
28137
|
var AccessTypeProps = /* @__PURE__ */ ((AccessTypeProps2) => {
|
|
27422
28138
|
AccessTypeProps2["NORMAL"] = "Normal";
|
|
@@ -28015,7 +28731,7 @@ function UseAccessManagementRepo() {
|
|
|
28015
28731
|
{
|
|
28016
28732
|
$match: {
|
|
28017
28733
|
...defaultQuery,
|
|
28018
|
-
status: { $
|
|
28734
|
+
status: { $eq: "active" }
|
|
28019
28735
|
}
|
|
28020
28736
|
},
|
|
28021
28737
|
// ✅ Only project needed fields before heavy lookups
|
|
@@ -28077,16 +28793,16 @@ function UseAccessManagementRepo() {
|
|
|
28077
28793
|
preserveNullAndEmptyArrays: false
|
|
28078
28794
|
}
|
|
28079
28795
|
},
|
|
28080
|
-
// Groups by unit _id and keeps only the first occurrence
|
|
28081
|
-
{
|
|
28082
|
-
|
|
28083
|
-
|
|
28084
|
-
|
|
28085
|
-
|
|
28086
|
-
},
|
|
28087
|
-
{
|
|
28088
|
-
|
|
28089
|
-
},
|
|
28796
|
+
// // Groups by unit _id and keeps only the first occurrence
|
|
28797
|
+
// {
|
|
28798
|
+
// $group: {
|
|
28799
|
+
// _id: "$level.units._id",
|
|
28800
|
+
// doc: { $first: "$$ROOT" },
|
|
28801
|
+
// },
|
|
28802
|
+
// },
|
|
28803
|
+
// {
|
|
28804
|
+
// $replaceRoot: { newRoot: "$doc" },
|
|
28805
|
+
// },
|
|
28090
28806
|
// ✅ Apply search filter
|
|
28091
28807
|
{
|
|
28092
28808
|
$match: {
|
|
@@ -28098,7 +28814,6 @@ function UseAccessManagementRepo() {
|
|
|
28098
28814
|
totalCount: [{ $count: "count" }],
|
|
28099
28815
|
items: [
|
|
28100
28816
|
// ✅ Sort BEFORE skip/limit for correct pagination
|
|
28101
|
-
{ $sort: { _id: -1 } },
|
|
28102
28817
|
{ $skip: page * limit },
|
|
28103
28818
|
{ $limit: limit },
|
|
28104
28819
|
// ✅ Users lookup - optimized with index hint
|
|
@@ -28136,7 +28851,7 @@ function UseAccessManagementRepo() {
|
|
|
28136
28851
|
userType
|
|
28137
28852
|
}
|
|
28138
28853
|
},
|
|
28139
|
-
{ $project: { _id: 1, userId: 1, type: 1, cardNo: 1, isActivated: 1 } }
|
|
28854
|
+
{ $project: { _id: 1, userId: 1, type: 1, cardNo: 1, isActivated: 1, replacementStatus: 1 } }
|
|
28140
28855
|
],
|
|
28141
28856
|
as: "accessCards"
|
|
28142
28857
|
}
|
|
@@ -28155,7 +28870,21 @@ function UseAccessManagementRepo() {
|
|
|
28155
28870
|
$filter: {
|
|
28156
28871
|
input: "$accessCards",
|
|
28157
28872
|
as: "card",
|
|
28158
|
-
cond: { $ne: ["$$card.userId", null] }
|
|
28873
|
+
cond: { $and: [{ $ne: ["$$card.userId", null] }, { $eq: ["$$card.isActivated", true] }] }
|
|
28874
|
+
}
|
|
28875
|
+
},
|
|
28876
|
+
f_replaced: {
|
|
28877
|
+
$filter: {
|
|
28878
|
+
input: "$accessCards",
|
|
28879
|
+
as: "card",
|
|
28880
|
+
cond: { $and: [{ $eq: ["$$card.isActivated", false] }, { $ne: ["$$card.replacementStatus", null] }] }
|
|
28881
|
+
}
|
|
28882
|
+
},
|
|
28883
|
+
f_deleted: {
|
|
28884
|
+
$filter: {
|
|
28885
|
+
input: "$accessCards",
|
|
28886
|
+
as: "card",
|
|
28887
|
+
cond: { $and: [{ $eq: ["$$card.isActivated", false] }, { $eq: ["$$card.replacementStatus", null] }] }
|
|
28159
28888
|
}
|
|
28160
28889
|
}
|
|
28161
28890
|
}
|
|
@@ -28187,6 +28916,14 @@ function UseAccessManagementRepo() {
|
|
|
28187
28916
|
non_physical: { $size: { $filter: { input: { $ifNull: ["$f_Assigned", []] }, as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } } }
|
|
28188
28917
|
}
|
|
28189
28918
|
},
|
|
28919
|
+
replaced: {
|
|
28920
|
+
physical: { $filter: { input: "$f_replaced", as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } },
|
|
28921
|
+
non_physical: { $filter: { input: "$f_replaced", as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } }
|
|
28922
|
+
},
|
|
28923
|
+
deleted: {
|
|
28924
|
+
physical: { $filter: { input: "$f_deleted", as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } },
|
|
28925
|
+
non_physical: { $filter: { input: "$f_deleted", as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } }
|
|
28926
|
+
},
|
|
28190
28927
|
totalCardCount: {
|
|
28191
28928
|
$add: [
|
|
28192
28929
|
{ $size: { $filter: { input: { $ifNull: ["$f_Available", []] }, as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } } },
|
|
@@ -28196,7 +28933,8 @@ function UseAccessManagementRepo() {
|
|
|
28196
28933
|
]
|
|
28197
28934
|
}
|
|
28198
28935
|
}
|
|
28199
|
-
}
|
|
28936
|
+
},
|
|
28937
|
+
{ $sort: { totalCardCount: -1 } }
|
|
28200
28938
|
]
|
|
28201
28939
|
}
|
|
28202
28940
|
}
|
|
@@ -28642,16 +29380,26 @@ function UseAccessManagementRepo() {
|
|
|
28642
29380
|
async function cardReplacementRepo(params) {
|
|
28643
29381
|
const session = useAtlas74.getClient()?.startSession();
|
|
28644
29382
|
try {
|
|
28645
|
-
const { cardId, remarks } = params;
|
|
29383
|
+
const { cardId, remarks, issuedCardId, unitId, userId } = params;
|
|
28646
29384
|
const id = new ObjectId83(cardId);
|
|
29385
|
+
const newCardId = new ObjectId83(issuedCardId);
|
|
29386
|
+
const unit = new ObjectId83(unitId);
|
|
29387
|
+
const user = new ObjectId83(userId);
|
|
28647
29388
|
session?.startTransaction();
|
|
28648
|
-
const
|
|
28649
|
-
|
|
28650
|
-
|
|
28651
|
-
|
|
28652
|
-
|
|
29389
|
+
const sessionResult = await Promise.all([
|
|
29390
|
+
await collection().findOneAndUpdate(
|
|
29391
|
+
{ _id: id },
|
|
29392
|
+
{ $set: { remarks, replacementStatus: "Complete", requestDate: /* @__PURE__ */ new Date(), isActivated: false } },
|
|
29393
|
+
{ returnDocument: "after", session }
|
|
29394
|
+
),
|
|
29395
|
+
await collection().findOneAndUpdate(
|
|
29396
|
+
{ _id: newCardId },
|
|
29397
|
+
{ $set: { updatedAt: /* @__PURE__ */ new Date(), assignedUnit: unit, userId: user } },
|
|
29398
|
+
{ returnDocument: "after", session }
|
|
29399
|
+
)
|
|
29400
|
+
]);
|
|
28653
29401
|
await session?.commitTransaction();
|
|
28654
|
-
return
|
|
29402
|
+
return sessionResult;
|
|
28655
29403
|
} catch (error) {
|
|
28656
29404
|
await session?.abortTransaction();
|
|
28657
29405
|
throw new Error(error.message);
|
|
@@ -28659,6 +29407,398 @@ function UseAccessManagementRepo() {
|
|
|
28659
29407
|
await session?.endSession();
|
|
28660
29408
|
}
|
|
28661
29409
|
}
|
|
29410
|
+
async function visitorAccessCardsRepo(params) {
|
|
29411
|
+
try {
|
|
29412
|
+
const page = params.page ? params.page - 1 : 0;
|
|
29413
|
+
const siteId = new ObjectId83(params.site);
|
|
29414
|
+
const search = params.search;
|
|
29415
|
+
const type = params.type;
|
|
29416
|
+
const limit = Number(params.limit);
|
|
29417
|
+
const query = {
|
|
29418
|
+
site: siteId,
|
|
29419
|
+
assignedUnit: { $ne: null },
|
|
29420
|
+
type: "NFC" /* NFC */
|
|
29421
|
+
};
|
|
29422
|
+
if (search) {
|
|
29423
|
+
query.$or = [{ accessLevel: { $regex: search, $options: "i" } }, { cardNo: { $regex: search, $options: "i" } }];
|
|
29424
|
+
}
|
|
29425
|
+
if (type) {
|
|
29426
|
+
query.userType = type;
|
|
29427
|
+
} else {
|
|
29428
|
+
query.userType = { $ne: "Resident/Tenant" /* RESIDENT */ };
|
|
29429
|
+
}
|
|
29430
|
+
const res = await collection().aggregate([
|
|
29431
|
+
{
|
|
29432
|
+
$match: query
|
|
29433
|
+
},
|
|
29434
|
+
{
|
|
29435
|
+
$project: {
|
|
29436
|
+
cardNo: 1,
|
|
29437
|
+
accessLevel: 1,
|
|
29438
|
+
site: 1,
|
|
29439
|
+
userType: 1,
|
|
29440
|
+
qrTag: 1,
|
|
29441
|
+
qrTagCardNo: 1,
|
|
29442
|
+
qrData: 1
|
|
29443
|
+
}
|
|
29444
|
+
},
|
|
29445
|
+
{
|
|
29446
|
+
$addFields: {
|
|
29447
|
+
extractedCardNo: {
|
|
29448
|
+
$substr: ["$cardNo", { $subtract: [{ $strLenCP: "$cardNo" }, 5] }, 5]
|
|
29449
|
+
}
|
|
29450
|
+
}
|
|
29451
|
+
},
|
|
29452
|
+
{
|
|
29453
|
+
$facet: {
|
|
29454
|
+
totalCount: [{ $count: "count" }],
|
|
29455
|
+
items: [{ $sort: { _id: -1 } }, { $skip: page * limit }, { $limit: limit }]
|
|
29456
|
+
}
|
|
29457
|
+
}
|
|
29458
|
+
]).toArray();
|
|
29459
|
+
const length = res[0].totalCount[0] ? res[0].totalCount[0].count : 0;
|
|
29460
|
+
const items = res[0].items;
|
|
29461
|
+
const paginatedResult = paginate38(items, page, limit, length);
|
|
29462
|
+
return paginatedResult;
|
|
29463
|
+
} catch (error) {
|
|
29464
|
+
throw new Error(error.message);
|
|
29465
|
+
}
|
|
29466
|
+
}
|
|
29467
|
+
async function getCardReplacementRepo(params) {
|
|
29468
|
+
try {
|
|
29469
|
+
const site = new ObjectId83(params.site);
|
|
29470
|
+
const search = params.search;
|
|
29471
|
+
const statusFilter = params.statusFilter;
|
|
29472
|
+
const dateFrom = params.dateFrom;
|
|
29473
|
+
const dateTo = params.dateTo;
|
|
29474
|
+
const page = Number(params.page) - 1;
|
|
29475
|
+
const limit = Number(params.limit);
|
|
29476
|
+
const query = {
|
|
29477
|
+
site,
|
|
29478
|
+
replacementStatus: { $in: ["Complete", "Issuance", "Pending"] },
|
|
29479
|
+
isActivated: false
|
|
29480
|
+
};
|
|
29481
|
+
const searchQuery = buildSearchQuery(search);
|
|
29482
|
+
if (statusFilter) {
|
|
29483
|
+
query.replacementStatus = statusFilter;
|
|
29484
|
+
}
|
|
29485
|
+
if (dateFrom && dateTo) {
|
|
29486
|
+
query.requestDate = { $gte: new Date(dateFrom), $lte: new Date(dateTo) };
|
|
29487
|
+
} else if (dateFrom) {
|
|
29488
|
+
query.requestDate = { $gte: new Date(dateFrom) };
|
|
29489
|
+
} else if (dateTo) {
|
|
29490
|
+
query.requestDate = { $lte: new Date(dateTo) };
|
|
29491
|
+
}
|
|
29492
|
+
const res = await collection().aggregate([
|
|
29493
|
+
{
|
|
29494
|
+
$match: { ...query }
|
|
29495
|
+
},
|
|
29496
|
+
{
|
|
29497
|
+
$lookup: {
|
|
29498
|
+
from: "building-units",
|
|
29499
|
+
let: { unit: "$assignedUnit" },
|
|
29500
|
+
pipeline: [
|
|
29501
|
+
{
|
|
29502
|
+
$match: {
|
|
29503
|
+
$expr: {
|
|
29504
|
+
$eq: ["$_id", "$$unit"]
|
|
29505
|
+
}
|
|
29506
|
+
}
|
|
29507
|
+
},
|
|
29508
|
+
{
|
|
29509
|
+
$project: {
|
|
29510
|
+
_id: 1,
|
|
29511
|
+
name: 1,
|
|
29512
|
+
level: 1
|
|
29513
|
+
}
|
|
29514
|
+
}
|
|
29515
|
+
],
|
|
29516
|
+
as: "unit"
|
|
29517
|
+
}
|
|
29518
|
+
},
|
|
29519
|
+
{
|
|
29520
|
+
$unwind: { path: "$unit", preserveNullAndEmptyArrays: true }
|
|
29521
|
+
},
|
|
29522
|
+
{
|
|
29523
|
+
$lookup: {
|
|
29524
|
+
from: "building-levels",
|
|
29525
|
+
let: { level: "$unit.level" },
|
|
29526
|
+
pipeline: [
|
|
29527
|
+
{
|
|
29528
|
+
$match: {
|
|
29529
|
+
$expr: {
|
|
29530
|
+
$eq: ["$_id", "$$level"]
|
|
29531
|
+
}
|
|
29532
|
+
}
|
|
29533
|
+
},
|
|
29534
|
+
{
|
|
29535
|
+
$project: {
|
|
29536
|
+
_id: 1,
|
|
29537
|
+
level: 1,
|
|
29538
|
+
block: 1
|
|
29539
|
+
}
|
|
29540
|
+
}
|
|
29541
|
+
],
|
|
29542
|
+
as: "level"
|
|
29543
|
+
}
|
|
29544
|
+
},
|
|
29545
|
+
{
|
|
29546
|
+
$unwind: { path: "$level", preserveNullAndEmptyArrays: true }
|
|
29547
|
+
},
|
|
29548
|
+
{
|
|
29549
|
+
$lookup: {
|
|
29550
|
+
from: "buildings",
|
|
29551
|
+
let: { block: "$level.block" },
|
|
29552
|
+
pipeline: [
|
|
29553
|
+
{
|
|
29554
|
+
$match: {
|
|
29555
|
+
$expr: {
|
|
29556
|
+
$eq: ["$_id", "$$block"]
|
|
29557
|
+
}
|
|
29558
|
+
}
|
|
29559
|
+
},
|
|
29560
|
+
{
|
|
29561
|
+
$project: {
|
|
29562
|
+
_id: 1,
|
|
29563
|
+
name: 1
|
|
29564
|
+
}
|
|
29565
|
+
}
|
|
29566
|
+
],
|
|
29567
|
+
as: "building"
|
|
29568
|
+
}
|
|
29569
|
+
},
|
|
29570
|
+
{
|
|
29571
|
+
$unwind: { path: "$building", preserveNullAndEmptyArrays: true }
|
|
29572
|
+
},
|
|
29573
|
+
{
|
|
29574
|
+
$lookup: {
|
|
29575
|
+
from: "users",
|
|
29576
|
+
let: { id: "$userId" },
|
|
29577
|
+
pipeline: [
|
|
29578
|
+
{
|
|
29579
|
+
$match: {
|
|
29580
|
+
$expr: {
|
|
29581
|
+
$eq: ["$_id", "$$id"]
|
|
29582
|
+
}
|
|
29583
|
+
}
|
|
29584
|
+
},
|
|
29585
|
+
{
|
|
29586
|
+
$project: {
|
|
29587
|
+
givenName: 1,
|
|
29588
|
+
surname: 1
|
|
29589
|
+
}
|
|
29590
|
+
}
|
|
29591
|
+
],
|
|
29592
|
+
as: "user"
|
|
29593
|
+
}
|
|
29594
|
+
},
|
|
29595
|
+
{
|
|
29596
|
+
$unwind: { path: "$user", preserveNullAndEmptyArrays: true }
|
|
29597
|
+
},
|
|
29598
|
+
{
|
|
29599
|
+
$match: { ...searchQuery }
|
|
29600
|
+
},
|
|
29601
|
+
{
|
|
29602
|
+
$facet: {
|
|
29603
|
+
data: [
|
|
29604
|
+
{ $skip: page * limit },
|
|
29605
|
+
{ $limit: limit },
|
|
29606
|
+
{
|
|
29607
|
+
$project: {
|
|
29608
|
+
_id: 1,
|
|
29609
|
+
cardNo: 1,
|
|
29610
|
+
accessLevel: 1,
|
|
29611
|
+
liftAccessLevel: 1,
|
|
29612
|
+
replacementStatus: 1,
|
|
29613
|
+
remarks: 1,
|
|
29614
|
+
block: "$building.name",
|
|
29615
|
+
level: "$level.level",
|
|
29616
|
+
unit: "$unit.name",
|
|
29617
|
+
user: "$user"
|
|
29618
|
+
}
|
|
29619
|
+
}
|
|
29620
|
+
],
|
|
29621
|
+
totalCount: [{ $count: "count" }]
|
|
29622
|
+
}
|
|
29623
|
+
}
|
|
29624
|
+
], { allowDiskUse: true }).toArray();
|
|
29625
|
+
const count = res[0]?.totalCount[0] ? res[0].totalCount[0].count : 0;
|
|
29626
|
+
const pagination = paginate38(res[0].data, page, limit, count);
|
|
29627
|
+
return pagination;
|
|
29628
|
+
} catch (error) {
|
|
29629
|
+
throw new Error(error.message);
|
|
29630
|
+
}
|
|
29631
|
+
}
|
|
29632
|
+
async function getAccessManagementSettingsRepo(params) {
|
|
29633
|
+
try {
|
|
29634
|
+
const { site } = params;
|
|
29635
|
+
const siteId = new ObjectId83(site);
|
|
29636
|
+
const res = await collectionName("entrypass-settings").findOne({ site: siteId }, { allowDiskUse: true });
|
|
29637
|
+
return res;
|
|
29638
|
+
} catch (error) {
|
|
29639
|
+
throw new Error(error.message);
|
|
29640
|
+
}
|
|
29641
|
+
}
|
|
29642
|
+
async function bulkPhysicalAccessCardRepo(params) {
|
|
29643
|
+
const session = useAtlas74.getClient()?.startSession();
|
|
29644
|
+
try {
|
|
29645
|
+
const { dataJson, site } = params;
|
|
29646
|
+
const rawItems = JSON.parse(dataJson).filter((_, index) => index !== -1);
|
|
29647
|
+
const items = await Promise.all(
|
|
29648
|
+
rawItems.map(async (item) => {
|
|
29649
|
+
const date = new Date(item["startDate (format MM/DD/YYYY)"]);
|
|
29650
|
+
const endDate = new Date(date.setFullYear(date.getFullYear() + 10));
|
|
29651
|
+
const cardNumber = String(Number(item["cardNo (number 0-65535 ex. 301)"] || 0)).padStart(6, "0");
|
|
29652
|
+
const facilityCode = String(Number(item["facilityCode (number 0-255 ex. 11)"] || 0)).padStart(4, "0");
|
|
29653
|
+
const pin = item["pin (number 6 digits only)"] ? item["pin (number 6 digits only)"].toString().padStart(6, "0") : "123456";
|
|
29654
|
+
const match = item["accessLevel (number ex. 1)"];
|
|
29655
|
+
const accessLevel = match ? match : null;
|
|
29656
|
+
const userType = item["userType(Contractor, Visitor, Resident/Tenant, Visitor/Resident)"];
|
|
29657
|
+
const rawAccessGroup = item["accessGroup (value ex. Full Access, No Access)"];
|
|
29658
|
+
const accessGroup = typeof rawAccessGroup === "string" ? rawAccessGroup.split(",").map((v) => v.trim()).filter((v) => v !== "") : [];
|
|
29659
|
+
return new MAccessCard({
|
|
29660
|
+
site: new ObjectId83(site),
|
|
29661
|
+
type: "NFC" /* NFC */,
|
|
29662
|
+
staffNo: null,
|
|
29663
|
+
accessLevel,
|
|
29664
|
+
accessGroup,
|
|
29665
|
+
accessType: "Normal" /* NORMAL */,
|
|
29666
|
+
cardNo: `${facilityCode}${cardNumber}`,
|
|
29667
|
+
pin,
|
|
29668
|
+
qrData: await createQrData({ cardNumber: `${facilityCode}${cardNumber}` }),
|
|
29669
|
+
startDate: new Date(item["startDate (format MM/DD/YYYY)"]),
|
|
29670
|
+
endDate: new Date(item["endDate (format MM/DD/YYYY)"] || endDate),
|
|
29671
|
+
isActivated: true,
|
|
29672
|
+
isAntiPassBack: false,
|
|
29673
|
+
isLiftCard: item["isLiftCard (TRUE OR FALSE)"] === "TRUE" ? true : false,
|
|
29674
|
+
liftAccessLevel: item["liftAccessLevel(number ex. 1)"] || null,
|
|
29675
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
29676
|
+
updatedAt: /* @__PURE__ */ new Date(),
|
|
29677
|
+
assignedUnit: null,
|
|
29678
|
+
userType: userType.toLowerCase() === "contractor" ? "Contractor" /* CONTRACTOR */ : userType.toLowerCase() === "visitor" ? "Visitor" /* VISITOR */ : userType.toLowerCase() === "resident/tenant" ? "Resident/Tenant" /* RESIDENT */ : "Visitor/Resident" /* DEFAULT */,
|
|
29679
|
+
doorName: item["Door Name (ex. Main Door)"] || null,
|
|
29680
|
+
liftName: item["Lift Name (ex. Main Lift)"] || null
|
|
29681
|
+
});
|
|
29682
|
+
})
|
|
29683
|
+
);
|
|
29684
|
+
const result = await collection().insertMany(items, { session, ordered: false });
|
|
29685
|
+
const mapping = items.map((item, i) => ({
|
|
29686
|
+
cardNo: item.cardNo,
|
|
29687
|
+
insertedId: result.insertedIds[i]
|
|
29688
|
+
}));
|
|
29689
|
+
return mapping;
|
|
29690
|
+
} catch (error) {
|
|
29691
|
+
throw new Error(error.message);
|
|
29692
|
+
}
|
|
29693
|
+
}
|
|
29694
|
+
async function assignAccessCardToUnitRepo(params) {
|
|
29695
|
+
const session = useAtlas74.getClient()?.startSession();
|
|
29696
|
+
try {
|
|
29697
|
+
session?.startTransaction();
|
|
29698
|
+
const { units, quantity, type, site, userType, accessLevel, liftAccessLevel } = params;
|
|
29699
|
+
const [convertedUnits, convertedSite] = await Promise.all([Promise.all(units.map((id) => new ObjectId83(id))), new ObjectId83(site)]);
|
|
29700
|
+
const totalRequired = quantity * convertedUnits.length;
|
|
29701
|
+
const availableCards = await collection().find({
|
|
29702
|
+
assignedUnit: null,
|
|
29703
|
+
userId: null,
|
|
29704
|
+
type,
|
|
29705
|
+
userType,
|
|
29706
|
+
isActivated: true,
|
|
29707
|
+
site: convertedSite,
|
|
29708
|
+
accessLevel: accessLevel ?? null,
|
|
29709
|
+
liftAccessLevel: liftAccessLevel ?? null
|
|
29710
|
+
}).limit(totalRequired).toArray();
|
|
29711
|
+
if (availableCards.length < totalRequired) {
|
|
29712
|
+
session?.abortTransaction();
|
|
29713
|
+
return {
|
|
29714
|
+
status: "error",
|
|
29715
|
+
message: `Insufficient ${type} access cards. Need ${totalRequired}, but only ${availableCards.length} available.`
|
|
29716
|
+
};
|
|
29717
|
+
}
|
|
29718
|
+
const bulkUpdates = availableCards.map((card, index) => ({
|
|
29719
|
+
updateOne: {
|
|
29720
|
+
filter: { _id: card._id },
|
|
29721
|
+
update: {
|
|
29722
|
+
$set: {
|
|
29723
|
+
assignedUnit: convertedUnits[Math.floor(index / quantity)]
|
|
29724
|
+
}
|
|
29725
|
+
}
|
|
29726
|
+
}
|
|
29727
|
+
}));
|
|
29728
|
+
await collection().bulkWrite(bulkUpdates, { session });
|
|
29729
|
+
session?.commitTransaction();
|
|
29730
|
+
return {
|
|
29731
|
+
status: "success",
|
|
29732
|
+
message: "Cards assigned to units successfully.",
|
|
29733
|
+
assigned: bulkUpdates.length
|
|
29734
|
+
};
|
|
29735
|
+
} catch (error) {
|
|
29736
|
+
session?.abortTransaction();
|
|
29737
|
+
return Promise.reject(error.message);
|
|
29738
|
+
} finally {
|
|
29739
|
+
session?.endSession();
|
|
29740
|
+
}
|
|
29741
|
+
}
|
|
29742
|
+
async function deleteCardRepo(params) {
|
|
29743
|
+
try {
|
|
29744
|
+
const { cardId, remarks } = params;
|
|
29745
|
+
const id = new ObjectId83(cardId);
|
|
29746
|
+
const result = await collection().findOneAndUpdate({ _id: id }, { $set: { isActivated: false, updatedAt: /* @__PURE__ */ new Date(), remarks, requestDate: /* @__PURE__ */ new Date() } }, { returnDocument: "after" });
|
|
29747
|
+
return result;
|
|
29748
|
+
} catch (error) {
|
|
29749
|
+
throw new Error(error.message);
|
|
29750
|
+
}
|
|
29751
|
+
}
|
|
29752
|
+
async function getCardDetailsRepo(params) {
|
|
29753
|
+
try {
|
|
29754
|
+
const { siteId, cardId } = params;
|
|
29755
|
+
const convertedSiteId = new ObjectId83(siteId);
|
|
29756
|
+
const convertedCardId = new ObjectId83(cardId);
|
|
29757
|
+
const card = await collection().findOne(
|
|
29758
|
+
{
|
|
29759
|
+
_id: convertedCardId,
|
|
29760
|
+
site: convertedSiteId,
|
|
29761
|
+
type: "NFC" /* NFC */,
|
|
29762
|
+
userType: "Visitor/Resident" /* DEFAULT */
|
|
29763
|
+
},
|
|
29764
|
+
{
|
|
29765
|
+
projection: {
|
|
29766
|
+
userId: 1,
|
|
29767
|
+
site: 1,
|
|
29768
|
+
type: 1,
|
|
29769
|
+
userType: 1,
|
|
29770
|
+
cardNo: 1,
|
|
29771
|
+
isActivated: 1,
|
|
29772
|
+
replacementStatus: 1,
|
|
29773
|
+
vmsRemarks: 1,
|
|
29774
|
+
remarks: 1,
|
|
29775
|
+
requestDate: 1,
|
|
29776
|
+
createdAt: 1,
|
|
29777
|
+
updatedAt: 1
|
|
29778
|
+
}
|
|
29779
|
+
}
|
|
29780
|
+
);
|
|
29781
|
+
if (!card)
|
|
29782
|
+
return null;
|
|
29783
|
+
const site = await collectionName("sites").findOne(
|
|
29784
|
+
{ _id: card.site },
|
|
29785
|
+
{ projection: { name: 1, status: 1 } }
|
|
29786
|
+
);
|
|
29787
|
+
const user = card.userId ? await collectionName("users").findOne(
|
|
29788
|
+
{ _id: card.userId },
|
|
29789
|
+
{ projection: { name: 1, email: 1 } }
|
|
29790
|
+
) : null;
|
|
29791
|
+
const status = card.userId === null && card.isActivated === true ? "available" : card.userId !== null && card.isActivated === true ? "assigned" : card.isActivated === false && card.replacementStatus !== null ? "replaced" : "deleted";
|
|
29792
|
+
return {
|
|
29793
|
+
...card,
|
|
29794
|
+
status,
|
|
29795
|
+
site,
|
|
29796
|
+
user
|
|
29797
|
+
};
|
|
29798
|
+
} catch (error) {
|
|
29799
|
+
throw new Error(error.message);
|
|
29800
|
+
}
|
|
29801
|
+
}
|
|
28662
29802
|
return {
|
|
28663
29803
|
createIndexes,
|
|
28664
29804
|
createIndexForEntrypass,
|
|
@@ -28674,7 +29814,14 @@ function UseAccessManagementRepo() {
|
|
|
28674
29814
|
replaceCardRepo,
|
|
28675
29815
|
updateNFCStatusRepo,
|
|
28676
29816
|
doorAndLiftDropdownRepo,
|
|
28677
|
-
cardReplacementRepo
|
|
29817
|
+
cardReplacementRepo,
|
|
29818
|
+
visitorAccessCardsRepo,
|
|
29819
|
+
getCardReplacementRepo,
|
|
29820
|
+
getAccessManagementSettingsRepo,
|
|
29821
|
+
bulkPhysicalAccessCardRepo,
|
|
29822
|
+
assignAccessCardToUnitRepo,
|
|
29823
|
+
deleteCardRepo,
|
|
29824
|
+
getCardDetailsRepo
|
|
28678
29825
|
};
|
|
28679
29826
|
}
|
|
28680
29827
|
|
|
@@ -28684,6 +29831,8 @@ import Joi85 from "joi";
|
|
|
28684
29831
|
// src/services/access-management.service.ts
|
|
28685
29832
|
import { parseStringPromise as parseStringPromise2 } from "xml2js";
|
|
28686
29833
|
import { useCache as useCache47 } from "@7365admin1/node-server-utils";
|
|
29834
|
+
import { Readable } from "stream";
|
|
29835
|
+
import * as xlsx from "xlsx";
|
|
28687
29836
|
var namespace = "cache:acm";
|
|
28688
29837
|
function useAccessManagementSvc() {
|
|
28689
29838
|
const {
|
|
@@ -28699,7 +29848,14 @@ function useAccessManagementSvc() {
|
|
|
28699
29848
|
replaceCardRepo,
|
|
28700
29849
|
updateNFCStatusRepo,
|
|
28701
29850
|
doorAndLiftDropdownRepo,
|
|
28702
|
-
cardReplacementRepo
|
|
29851
|
+
cardReplacementRepo,
|
|
29852
|
+
visitorAccessCardsRepo,
|
|
29853
|
+
getCardReplacementRepo,
|
|
29854
|
+
getAccessManagementSettingsRepo,
|
|
29855
|
+
bulkPhysicalAccessCardRepo,
|
|
29856
|
+
assignAccessCardToUnitRepo,
|
|
29857
|
+
deleteCardRepo,
|
|
29858
|
+
getCardDetailsRepo
|
|
28703
29859
|
} = UseAccessManagementRepo();
|
|
28704
29860
|
const addPhysicalCardSvc = async (payload) => {
|
|
28705
29861
|
try {
|
|
@@ -28884,12 +30040,93 @@ function useAccessManagementSvc() {
|
|
|
28884
30040
|
throw new Error(err.message);
|
|
28885
30041
|
}
|
|
28886
30042
|
};
|
|
30043
|
+
const visitorAccessCardsSvc = async (params) => {
|
|
30044
|
+
try {
|
|
30045
|
+
const response = await visitorAccessCardsRepo({ ...params });
|
|
30046
|
+
return response;
|
|
30047
|
+
} catch (err) {
|
|
30048
|
+
throw new Error(err.message);
|
|
30049
|
+
}
|
|
30050
|
+
};
|
|
30051
|
+
const getCardReplacementSvc = async (params) => {
|
|
30052
|
+
try {
|
|
30053
|
+
const response = await getCardReplacementRepo({ ...params });
|
|
30054
|
+
return response;
|
|
30055
|
+
} catch (err) {
|
|
30056
|
+
throw new Error(err.message);
|
|
30057
|
+
}
|
|
30058
|
+
};
|
|
30059
|
+
const getAccessManagementSettingsSvc = async (params) => {
|
|
30060
|
+
try {
|
|
30061
|
+
const response = await getAccessManagementSettingsRepo({ ...params });
|
|
30062
|
+
return response;
|
|
30063
|
+
} catch (err) {
|
|
30064
|
+
throw new Error(err.message);
|
|
30065
|
+
}
|
|
30066
|
+
};
|
|
30067
|
+
const convertBufferFile = async (bufferFile) => {
|
|
30068
|
+
return new Promise((resolve, reject) => {
|
|
30069
|
+
const fileStream = Readable.from(bufferFile);
|
|
30070
|
+
let fileBuffer = Buffer.alloc(0);
|
|
30071
|
+
fileStream.on("data", (chunk) => {
|
|
30072
|
+
fileBuffer = Buffer.concat([fileBuffer, chunk]);
|
|
30073
|
+
});
|
|
30074
|
+
fileStream.on("end", () => {
|
|
30075
|
+
try {
|
|
30076
|
+
const workbook = xlsx.read(fileBuffer, { type: "buffer" });
|
|
30077
|
+
const sheetName = workbook.SheetNames[0];
|
|
30078
|
+
const sheet = workbook.Sheets[sheetName];
|
|
30079
|
+
const jsonData = xlsx.utils.sheet_to_json(sheet, { raw: false });
|
|
30080
|
+
resolve(jsonData);
|
|
30081
|
+
} catch (error) {
|
|
30082
|
+
reject("Error parsing file");
|
|
30083
|
+
}
|
|
30084
|
+
});
|
|
30085
|
+
fileStream.on("error", (err) => {
|
|
30086
|
+
reject("Error Reading File: " + err.message);
|
|
30087
|
+
});
|
|
30088
|
+
});
|
|
30089
|
+
};
|
|
30090
|
+
const bulkPhysicalAccessCardSvc = async (params) => {
|
|
30091
|
+
try {
|
|
30092
|
+
const response = await bulkPhysicalAccessCardRepo({ ...params });
|
|
30093
|
+
return response;
|
|
30094
|
+
} catch (err) {
|
|
30095
|
+
throw new Error(err.message);
|
|
30096
|
+
}
|
|
30097
|
+
};
|
|
30098
|
+
const assignAccessCardToUnitSvc = async (params) => {
|
|
30099
|
+
try {
|
|
30100
|
+
const response = await assignAccessCardToUnitRepo({ ...params });
|
|
30101
|
+
return response;
|
|
30102
|
+
} catch (err) {
|
|
30103
|
+
throw new Error(err.message);
|
|
30104
|
+
}
|
|
30105
|
+
};
|
|
30106
|
+
const deleteCardSvc = async (params) => {
|
|
30107
|
+
try {
|
|
30108
|
+
const response = await deleteCardRepo({ ...params });
|
|
30109
|
+
return response;
|
|
30110
|
+
} catch (err) {
|
|
30111
|
+
throw new Error(err.message);
|
|
30112
|
+
}
|
|
30113
|
+
};
|
|
30114
|
+
const getCardDetailsSvc = async (params) => {
|
|
30115
|
+
try {
|
|
30116
|
+
const response = await getCardDetailsRepo({ ...params });
|
|
30117
|
+
return response;
|
|
30118
|
+
} catch (err) {
|
|
30119
|
+
throw new Error(err.message);
|
|
30120
|
+
}
|
|
30121
|
+
};
|
|
28887
30122
|
return {
|
|
28888
30123
|
addPhysicalCardSvc,
|
|
28889
30124
|
addNonPhysicalCardSvc,
|
|
28890
30125
|
doorAccessLevelsSvc,
|
|
28891
30126
|
liftAccessLevelsSvc,
|
|
28892
30127
|
accessGroupsSvc,
|
|
30128
|
+
setCache,
|
|
30129
|
+
getCache,
|
|
28893
30130
|
accessManagementSettingsSvc,
|
|
28894
30131
|
allAccessCardsCountsSvc,
|
|
28895
30132
|
availableAccessCardsSvc,
|
|
@@ -28900,11 +30137,21 @@ function useAccessManagementSvc() {
|
|
|
28900
30137
|
replaceCardSvc,
|
|
28901
30138
|
updateNFCStatusSvc,
|
|
28902
30139
|
doorAndLiftDropdownSvc,
|
|
28903
|
-
cardReplacementSvc
|
|
30140
|
+
cardReplacementSvc,
|
|
30141
|
+
visitorAccessCardsSvc,
|
|
30142
|
+
getCardReplacementSvc,
|
|
30143
|
+
getAccessManagementSettingsSvc,
|
|
30144
|
+
convertBufferFile,
|
|
30145
|
+
bulkPhysicalAccessCardSvc,
|
|
30146
|
+
assignAccessCardToUnitSvc,
|
|
30147
|
+
deleteCardSvc,
|
|
30148
|
+
getCardDetailsSvc
|
|
28904
30149
|
};
|
|
28905
30150
|
}
|
|
28906
30151
|
|
|
28907
30152
|
// src/controllers/access-management.controller.ts
|
|
30153
|
+
import { useCache as useCache48 } from "@7365admin1/node-server-utils";
|
|
30154
|
+
var namespace2 = "cache:acm";
|
|
28908
30155
|
function useAccessManagementController() {
|
|
28909
30156
|
const {
|
|
28910
30157
|
addPhysicalCardSvc,
|
|
@@ -28912,6 +30159,8 @@ function useAccessManagementController() {
|
|
|
28912
30159
|
doorAccessLevelsSvc,
|
|
28913
30160
|
liftAccessLevelsSvc,
|
|
28914
30161
|
accessGroupsSvc,
|
|
30162
|
+
setCache,
|
|
30163
|
+
getCache,
|
|
28915
30164
|
accessManagementSettingsSvc,
|
|
28916
30165
|
allAccessCardsCountsSvc,
|
|
28917
30166
|
availableAccessCardsSvc,
|
|
@@ -28922,7 +30171,15 @@ function useAccessManagementController() {
|
|
|
28922
30171
|
replaceCardSvc,
|
|
28923
30172
|
updateNFCStatusSvc,
|
|
28924
30173
|
doorAndLiftDropdownSvc,
|
|
28925
|
-
cardReplacementSvc
|
|
30174
|
+
cardReplacementSvc,
|
|
30175
|
+
visitorAccessCardsSvc,
|
|
30176
|
+
getCardReplacementSvc,
|
|
30177
|
+
getAccessManagementSettingsSvc,
|
|
30178
|
+
convertBufferFile,
|
|
30179
|
+
bulkPhysicalAccessCardSvc,
|
|
30180
|
+
assignAccessCardToUnitSvc,
|
|
30181
|
+
deleteCardSvc,
|
|
30182
|
+
getCardDetailsSvc
|
|
28926
30183
|
} = useAccessManagementSvc();
|
|
28927
30184
|
const addPhysicalCard = async (req, res) => {
|
|
28928
30185
|
try {
|
|
@@ -29113,6 +30370,7 @@ function useAccessManagementController() {
|
|
|
29113
30370
|
const allAccessCardsCounts = async (req, res) => {
|
|
29114
30371
|
try {
|
|
29115
30372
|
const { site, userType } = req.query;
|
|
30373
|
+
const user = req.cookies?.sid;
|
|
29116
30374
|
const schema2 = Joi85.object({
|
|
29117
30375
|
site: Joi85.string().hex().required(),
|
|
29118
30376
|
userType: Joi85.string().required()
|
|
@@ -29121,7 +30379,19 @@ function useAccessManagementController() {
|
|
|
29121
30379
|
if (error) {
|
|
29122
30380
|
throw new Error(`${error.message}`);
|
|
29123
30381
|
}
|
|
30382
|
+
const key = `${namespace2}:${user}:access-card-counts`;
|
|
30383
|
+
const listKey = `${namespace2}:${user}:list`;
|
|
30384
|
+
const { redis } = useCache48(key);
|
|
30385
|
+
const cachedData = await getCache({ key, redis });
|
|
30386
|
+
if (cachedData) {
|
|
30387
|
+
console.log("\u26A1 Cache hit:", key);
|
|
30388
|
+
redis.expire(key, 60).catch(console.error);
|
|
30389
|
+
redis.lrem(listKey, 0, key).then(() => redis.lpush(listKey, key)).then(() => redis.ltrim(listKey, 0, 9)).catch(console.error);
|
|
30390
|
+
return res.status(200).json({ message: "Success", data: cachedData });
|
|
30391
|
+
}
|
|
29124
30392
|
const result = await allAccessCardsCountsSvc({ site, userType });
|
|
30393
|
+
await setCache({ key, data: result, ttlSeconds: 60, redis });
|
|
30394
|
+
redis.lrem(listKey, 0, key).then(() => redis.lpush(listKey, key)).then(() => redis.ltrim(listKey, 0, 9)).catch(console.error);
|
|
29125
30395
|
return res.status(200).json({ message: "Success", data: result });
|
|
29126
30396
|
} catch (error) {
|
|
29127
30397
|
return res.status(400).json({
|
|
@@ -29138,11 +30408,24 @@ function useAccessManagementController() {
|
|
|
29138
30408
|
userType: Joi85.string().optional().allow("", null),
|
|
29139
30409
|
type: Joi85.string().optional().allow("", null)
|
|
29140
30410
|
});
|
|
30411
|
+
const user = req.cookies?.sid;
|
|
29141
30412
|
const { error } = schema2.validate({ site, userType, type });
|
|
29142
30413
|
if (error) {
|
|
29143
30414
|
return res.status(400).json({ message: error.message });
|
|
29144
30415
|
}
|
|
30416
|
+
const key = `${namespace2}:${user}:available-access-cards`;
|
|
30417
|
+
const listKey = `${namespace2}:${user}:list`;
|
|
30418
|
+
const { redis } = useCache48(key);
|
|
30419
|
+
const cachedData = await getCache({ key, redis });
|
|
30420
|
+
if (cachedData) {
|
|
30421
|
+
console.log("\u26A1 Cache hit:", key);
|
|
30422
|
+
redis.expire(key, 60).catch(console.error);
|
|
30423
|
+
redis.lrem(listKey, 0, key).then(() => redis.lpush(listKey, key)).then(() => redis.ltrim(listKey, 0, 9)).catch(console.error);
|
|
30424
|
+
return res.status(200).json({ message: "Success", data: cachedData });
|
|
30425
|
+
}
|
|
29145
30426
|
const result = await availableAccessCardsSvc({ site, userType, type });
|
|
30427
|
+
await setCache({ key, data: result, ttlSeconds: 60, redis });
|
|
30428
|
+
redis.lrem(listKey, 0, key).then(() => redis.lpush(listKey, key)).then(() => redis.ltrim(listKey, 0, 9)).catch(console.error);
|
|
29146
30429
|
return res.status(200).json({ message: "Success", data: result });
|
|
29147
30430
|
} catch (error) {
|
|
29148
30431
|
return res.status(400).json({
|
|
@@ -29324,16 +30607,181 @@ function useAccessManagementController() {
|
|
|
29324
30607
|
};
|
|
29325
30608
|
const cardReplacement = async (req, res) => {
|
|
29326
30609
|
try {
|
|
29327
|
-
const { cardId, remarks } = req.body;
|
|
30610
|
+
const { cardId, remarks, unitId, issuedCardId, userId } = req.body;
|
|
29328
30611
|
const schema2 = Joi85.object({
|
|
29329
30612
|
cardId: Joi85.string().required(),
|
|
30613
|
+
remarks: Joi85.string().optional().allow("", null),
|
|
30614
|
+
unitId: Joi85.string().hex().required(),
|
|
30615
|
+
issuedCardId: Joi85.string().required(),
|
|
30616
|
+
userId: Joi85.string().hex().required()
|
|
30617
|
+
});
|
|
30618
|
+
const { error } = schema2.validate({ cardId, remarks, unitId, issuedCardId, userId });
|
|
30619
|
+
if (error) {
|
|
30620
|
+
return res.status(400).json({ message: error.message });
|
|
30621
|
+
}
|
|
30622
|
+
const result = await cardReplacementSvc({ cardId, remarks, unitId, issuedCardId, userId });
|
|
30623
|
+
return res.status(200).json({ message: "Success", data: result });
|
|
30624
|
+
} catch (error) {
|
|
30625
|
+
return res.status(500).json({
|
|
30626
|
+
data: null,
|
|
30627
|
+
message: error.message
|
|
30628
|
+
});
|
|
30629
|
+
}
|
|
30630
|
+
};
|
|
30631
|
+
const visitorAccessCards = async (req, res) => {
|
|
30632
|
+
try {
|
|
30633
|
+
const {
|
|
30634
|
+
page = 1,
|
|
30635
|
+
limit = 10,
|
|
30636
|
+
search,
|
|
30637
|
+
type,
|
|
30638
|
+
site
|
|
30639
|
+
} = req.query;
|
|
30640
|
+
const schema2 = Joi85.object({
|
|
30641
|
+
site: Joi85.string().hex().required(),
|
|
30642
|
+
page: Joi85.number().required(),
|
|
30643
|
+
limit: Joi85.number().optional().default(10),
|
|
30644
|
+
type: Joi85.string().required().valid(...Object.values(EAccessCardUserTypes)),
|
|
30645
|
+
search: Joi85.string().optional().allow("", null)
|
|
30646
|
+
});
|
|
30647
|
+
const { error } = schema2.validate({ site, page, limit, type, search });
|
|
30648
|
+
if (error) {
|
|
30649
|
+
return res.status(400).json({ message: error.message });
|
|
30650
|
+
}
|
|
30651
|
+
const result = await visitorAccessCardsSvc({ site, page, limit, type, search });
|
|
30652
|
+
return res.status(200).json({ message: "Success", data: result });
|
|
30653
|
+
} catch (error) {
|
|
30654
|
+
return res.status(500).json({
|
|
30655
|
+
data: null,
|
|
30656
|
+
message: error.message
|
|
30657
|
+
});
|
|
30658
|
+
}
|
|
30659
|
+
};
|
|
30660
|
+
const getCardReplacement = async (req, res) => {
|
|
30661
|
+
try {
|
|
30662
|
+
const site = req.params.site;
|
|
30663
|
+
const {
|
|
30664
|
+
search,
|
|
30665
|
+
statusFilter,
|
|
30666
|
+
dateFrom,
|
|
30667
|
+
dateTo,
|
|
30668
|
+
page = 0,
|
|
30669
|
+
limit = 10
|
|
30670
|
+
} = req.query;
|
|
30671
|
+
const schema2 = Joi85.object({
|
|
30672
|
+
search: Joi85.string().optional().allow("", null),
|
|
30673
|
+
statusFilter: Joi85.string().optional().allow("", null),
|
|
30674
|
+
dateFrom: Joi85.date().optional().allow("", null),
|
|
30675
|
+
dateTo: Joi85.date().optional().allow("", null),
|
|
30676
|
+
page: Joi85.number().optional().default(0),
|
|
30677
|
+
limit: Joi85.number().optional().default(10),
|
|
30678
|
+
site: Joi85.string().hex().required()
|
|
30679
|
+
});
|
|
30680
|
+
const { error } = schema2.validate({ search, statusFilter, dateFrom, dateTo, page, limit, site });
|
|
30681
|
+
if (error) {
|
|
30682
|
+
return res.status(400).json({ message: error.message });
|
|
30683
|
+
}
|
|
30684
|
+
const result = await getCardReplacementSvc({ site, page, limit, search, statusFilter, dateFrom, dateTo });
|
|
30685
|
+
return res.status(200).json({ message: "Success", data: result });
|
|
30686
|
+
} catch (error) {
|
|
30687
|
+
return res.status(500).json({
|
|
30688
|
+
data: null,
|
|
30689
|
+
message: error.message
|
|
30690
|
+
});
|
|
30691
|
+
}
|
|
30692
|
+
};
|
|
30693
|
+
const getAccessManagementSettings = async (req, res) => {
|
|
30694
|
+
try {
|
|
30695
|
+
const { site } = req.params;
|
|
30696
|
+
const schema2 = Joi85.object({
|
|
30697
|
+
site: Joi85.string().hex().required()
|
|
30698
|
+
});
|
|
30699
|
+
const { error } = schema2.validate({ site });
|
|
30700
|
+
if (error) {
|
|
30701
|
+
return res.status(400).json({ message: error.message });
|
|
30702
|
+
}
|
|
30703
|
+
const result = await getAccessManagementSettingsSvc({ site });
|
|
30704
|
+
return res.status(200).json({ message: "Success", data: result });
|
|
30705
|
+
} catch (error) {
|
|
30706
|
+
return res.status(500).json({
|
|
30707
|
+
data: null,
|
|
30708
|
+
message: error.message
|
|
30709
|
+
});
|
|
30710
|
+
}
|
|
30711
|
+
};
|
|
30712
|
+
const bulkPhysicalAccessCard = async (req, res) => {
|
|
30713
|
+
try {
|
|
30714
|
+
const { site } = req.query;
|
|
30715
|
+
if (!req.file)
|
|
30716
|
+
throw new Error("File is required!");
|
|
30717
|
+
const xlsData = await convertBufferFile(req.file.buffer);
|
|
30718
|
+
const dataJson = JSON.stringify(xlsData);
|
|
30719
|
+
const result = await bulkPhysicalAccessCardSvc({ dataJson, site });
|
|
30720
|
+
return res.status(200).json({ message: "Success", data: result });
|
|
30721
|
+
} catch (error) {
|
|
30722
|
+
return res.status(500).json({
|
|
30723
|
+
data: null,
|
|
30724
|
+
message: error.message
|
|
30725
|
+
});
|
|
30726
|
+
}
|
|
30727
|
+
};
|
|
30728
|
+
const assignAccessCardToUnit = async (req, res) => {
|
|
30729
|
+
try {
|
|
30730
|
+
const { units, type, quantity, site, userType, accessLevel, liftAccessLevel } = req.body;
|
|
30731
|
+
const schema2 = Joi85.object({
|
|
30732
|
+
units: Joi85.array().items(Joi85.string().hex()).required(),
|
|
30733
|
+
quantity: Joi85.number().required(),
|
|
30734
|
+
type: Joi85.string().required(),
|
|
30735
|
+
site: Joi85.string().hex().required(),
|
|
30736
|
+
userType: Joi85.string().required(),
|
|
30737
|
+
accessLevel: Joi85.string().optional().allow("", null),
|
|
30738
|
+
liftAccessLevel: Joi85.string().optional().allow("", null)
|
|
30739
|
+
});
|
|
30740
|
+
const { error } = schema2.validate({ units, quantity, type, site, userType, accessLevel, liftAccessLevel });
|
|
30741
|
+
if (error) {
|
|
30742
|
+
return res.status(400).json({ message: error.message });
|
|
30743
|
+
}
|
|
30744
|
+
const result = await assignAccessCardToUnitSvc({ units, quantity, type, site, userType, accessLevel, liftAccessLevel });
|
|
30745
|
+
return res.status(200).json({ message: "Success", data: result });
|
|
30746
|
+
} catch (error) {
|
|
30747
|
+
return res.status(500).json({
|
|
30748
|
+
data: null,
|
|
30749
|
+
message: error.message
|
|
30750
|
+
});
|
|
30751
|
+
}
|
|
30752
|
+
};
|
|
30753
|
+
const deleteCard = async (req, res) => {
|
|
30754
|
+
try {
|
|
30755
|
+
const { cardId, remarks } = req.body;
|
|
30756
|
+
const schema2 = Joi85.object({
|
|
30757
|
+
cardId: Joi85.string().hex().required(),
|
|
29330
30758
|
remarks: Joi85.string().optional().allow("", null)
|
|
29331
30759
|
});
|
|
29332
30760
|
const { error } = schema2.validate({ cardId, remarks });
|
|
29333
30761
|
if (error) {
|
|
29334
30762
|
return res.status(400).json({ message: error.message });
|
|
29335
30763
|
}
|
|
29336
|
-
const result = await
|
|
30764
|
+
const result = await deleteCardSvc({ cardId, remarks });
|
|
30765
|
+
return res.status(200).json({ message: "Success", data: result });
|
|
30766
|
+
} catch (error) {
|
|
30767
|
+
return res.status(500).json({
|
|
30768
|
+
data: null,
|
|
30769
|
+
message: error.message
|
|
30770
|
+
});
|
|
30771
|
+
}
|
|
30772
|
+
};
|
|
30773
|
+
const getCardDetails = async (req, res) => {
|
|
30774
|
+
try {
|
|
30775
|
+
const { siteId, cardId } = req.query;
|
|
30776
|
+
const schema2 = Joi85.object({
|
|
30777
|
+
siteId: Joi85.string().hex().required(),
|
|
30778
|
+
cardId: Joi85.string().hex().required()
|
|
30779
|
+
});
|
|
30780
|
+
const { error } = schema2.validate({ siteId, cardId });
|
|
30781
|
+
if (error) {
|
|
30782
|
+
return res.status(400).json({ message: error.message });
|
|
30783
|
+
}
|
|
30784
|
+
const result = await getCardDetailsSvc({ siteId, cardId });
|
|
29337
30785
|
return res.status(200).json({ message: "Success", data: result });
|
|
29338
30786
|
} catch (error) {
|
|
29339
30787
|
return res.status(500).json({
|
|
@@ -29358,7 +30806,14 @@ function useAccessManagementController() {
|
|
|
29358
30806
|
replaceCard,
|
|
29359
30807
|
updateNFCStatus,
|
|
29360
30808
|
doorAndLiftDropdown,
|
|
29361
|
-
cardReplacement
|
|
30809
|
+
cardReplacement,
|
|
30810
|
+
visitorAccessCards,
|
|
30811
|
+
getCardReplacement,
|
|
30812
|
+
getAccessManagementSettings,
|
|
30813
|
+
bulkPhysicalAccessCard,
|
|
30814
|
+
assignAccessCardToUnit,
|
|
30815
|
+
deleteCard,
|
|
30816
|
+
getCardDetails
|
|
29362
30817
|
};
|
|
29363
30818
|
}
|
|
29364
30819
|
|
|
@@ -29428,7 +30883,7 @@ import {
|
|
|
29428
30883
|
makeCacheKey as makeCacheKey45,
|
|
29429
30884
|
paginate as paginate39,
|
|
29430
30885
|
useAtlas as useAtlas75,
|
|
29431
|
-
useCache as
|
|
30886
|
+
useCache as useCache49
|
|
29432
30887
|
} from "@7365admin1/node-server-utils";
|
|
29433
30888
|
import { ObjectId as ObjectId85 } from "mongodb";
|
|
29434
30889
|
function useNfcPatrolTagRepo() {
|
|
@@ -29439,8 +30894,8 @@ function useNfcPatrolTagRepo() {
|
|
|
29439
30894
|
const namespace_collection = "nfc-patrol-tags";
|
|
29440
30895
|
const namespace_collection_nfc_patrol_routes = "nfc-patrol-routes";
|
|
29441
30896
|
const collection = db.collection(namespace_collection);
|
|
29442
|
-
const { delNamespace, getCache, setCache } =
|
|
29443
|
-
const { delNamespace: delNamespaceNfcPatrolRoutes } =
|
|
30897
|
+
const { delNamespace, getCache, setCache } = useCache49(namespace_collection);
|
|
30898
|
+
const { delNamespace: delNamespaceNfcPatrolRoutes } = useCache49(
|
|
29444
30899
|
namespace_collection_nfc_patrol_routes
|
|
29445
30900
|
);
|
|
29446
30901
|
async function createIndexes() {
|
|
@@ -29887,7 +31342,7 @@ import {
|
|
|
29887
31342
|
NotFoundError as NotFoundError37,
|
|
29888
31343
|
paginate as paginate40,
|
|
29889
31344
|
useAtlas as useAtlas77,
|
|
29890
|
-
useCache as
|
|
31345
|
+
useCache as useCache50
|
|
29891
31346
|
} from "@7365admin1/node-server-utils";
|
|
29892
31347
|
import { ObjectId as ObjectId87 } from "mongodb";
|
|
29893
31348
|
function useOccurrenceBookRepo() {
|
|
@@ -29919,7 +31374,7 @@ function useOccurrenceBookRepo() {
|
|
|
29919
31374
|
}
|
|
29920
31375
|
const namespace_collection = "occurrence-books";
|
|
29921
31376
|
const collection = db.collection(namespace_collection);
|
|
29922
|
-
const { delNamespace, getCache, setCache } =
|
|
31377
|
+
const { delNamespace, getCache, setCache } = useCache50(namespace_collection);
|
|
29923
31378
|
async function add(value, session) {
|
|
29924
31379
|
try {
|
|
29925
31380
|
value = MOccurrenceBook(value);
|
|
@@ -30497,7 +31952,7 @@ import {
|
|
|
30497
31952
|
NotFoundError as NotFoundError38,
|
|
30498
31953
|
paginate as paginate41,
|
|
30499
31954
|
useAtlas as useAtlas79,
|
|
30500
|
-
useCache as
|
|
31955
|
+
useCache as useCache51
|
|
30501
31956
|
} from "@7365admin1/node-server-utils";
|
|
30502
31957
|
import { ObjectId as ObjectId89 } from "mongodb";
|
|
30503
31958
|
function useBulletinVideoRepo() {
|
|
@@ -30516,7 +31971,7 @@ function useBulletinVideoRepo() {
|
|
|
30516
31971
|
}
|
|
30517
31972
|
const namespace_collection = "bulletin-videos";
|
|
30518
31973
|
const collection = db.collection(namespace_collection);
|
|
30519
|
-
const { delNamespace, getCache, setCache } =
|
|
31974
|
+
const { delNamespace, getCache, setCache } = useCache51(namespace_collection);
|
|
30520
31975
|
async function add(value, session) {
|
|
30521
31976
|
try {
|
|
30522
31977
|
value = MBulletinVideo(value);
|
|
@@ -31048,7 +32503,7 @@ import {
|
|
|
31048
32503
|
InternalServerError as InternalServerError51,
|
|
31049
32504
|
logger as logger127,
|
|
31050
32505
|
useAtlas as useAtlas81,
|
|
31051
|
-
useCache as
|
|
32506
|
+
useCache as useCache52,
|
|
31052
32507
|
paginate as paginate42,
|
|
31053
32508
|
makeCacheKey as makeCacheKey48
|
|
31054
32509
|
} from "@7365admin1/node-server-utils";
|
|
@@ -31060,7 +32515,7 @@ function useStatementOfAccountRepo() {
|
|
|
31060
32515
|
}
|
|
31061
32516
|
const namespace_collection = "site.statement-of-accounts";
|
|
31062
32517
|
const collection = db.collection(namespace_collection);
|
|
31063
|
-
const { delNamespace, getCache, setCache } =
|
|
32518
|
+
const { delNamespace, getCache, setCache } = useCache52(namespace_collection);
|
|
31064
32519
|
async function createTextIndex() {
|
|
31065
32520
|
try {
|
|
31066
32521
|
await collection.createIndex({
|
|
@@ -31110,9 +32565,9 @@ function useStatementOfAccountRepo() {
|
|
|
31110
32565
|
page = page > 0 ? page - 1 : 0;
|
|
31111
32566
|
let dateExpr = {};
|
|
31112
32567
|
if (dateFrom && dateTo) {
|
|
31113
|
-
|
|
32568
|
+
let startDate = new Date(dateFrom);
|
|
31114
32569
|
startDate.setHours(0, 0, 0, 0);
|
|
31115
|
-
|
|
32570
|
+
let endDate = new Date(dateTo);
|
|
31116
32571
|
endDate.setHours(23, 59, 59, 999);
|
|
31117
32572
|
dateExpr = {
|
|
31118
32573
|
$expr: {
|
|
@@ -31123,13 +32578,15 @@ function useStatementOfAccountRepo() {
|
|
|
31123
32578
|
}
|
|
31124
32579
|
};
|
|
31125
32580
|
}
|
|
32581
|
+
const unitSearchRegex = search ? search.trim().replace(/\s+/g, "").replace(/\//g, "\\s*/\\s*") : null;
|
|
31126
32582
|
const query = {
|
|
31127
32583
|
...status && status !== "all" && { status },
|
|
31128
32584
|
...search && {
|
|
31129
32585
|
$or: [
|
|
31130
32586
|
{ unitOwner: { $regex: search, $options: "i" } },
|
|
31131
|
-
{ unit: { $regex:
|
|
31132
|
-
{ email: { $regex: search, $options: "i" } }
|
|
32587
|
+
{ unit: { $regex: unitSearchRegex, $options: "i" } },
|
|
32588
|
+
{ email: { $regex: search, $options: "i" } },
|
|
32589
|
+
{ category: { $regex: search, $options: "i" } }
|
|
31133
32590
|
]
|
|
31134
32591
|
},
|
|
31135
32592
|
...ObjectId91.isValid(site) && { site: new ObjectId91(site) },
|
|
@@ -31823,7 +33280,7 @@ import {
|
|
|
31823
33280
|
NotFoundError as NotFoundError40,
|
|
31824
33281
|
paginate as paginate43,
|
|
31825
33282
|
useAtlas as useAtlas83,
|
|
31826
|
-
useCache as
|
|
33283
|
+
useCache as useCache53
|
|
31827
33284
|
} from "@7365admin1/node-server-utils";
|
|
31828
33285
|
import { ObjectId as ObjectId93 } from "mongodb";
|
|
31829
33286
|
function useEntryPassSettingsRepo() {
|
|
@@ -31833,7 +33290,7 @@ function useEntryPassSettingsRepo() {
|
|
|
31833
33290
|
}
|
|
31834
33291
|
const namespace_collection = "site.entrypass-settings";
|
|
31835
33292
|
const collection = db.collection(namespace_collection);
|
|
31836
|
-
const { delNamespace, getCache, setCache } =
|
|
33293
|
+
const { delNamespace, getCache, setCache } = useCache53(namespace_collection);
|
|
31837
33294
|
async function createTextIndex() {
|
|
31838
33295
|
try {
|
|
31839
33296
|
await collection.createIndex({
|
|
@@ -32395,7 +33852,7 @@ import {
|
|
|
32395
33852
|
logger as logger133,
|
|
32396
33853
|
makeCacheKey as makeCacheKey50,
|
|
32397
33854
|
useAtlas as useAtlas84,
|
|
32398
|
-
useCache as
|
|
33855
|
+
useCache as useCache54
|
|
32399
33856
|
} from "@7365admin1/node-server-utils";
|
|
32400
33857
|
function useDashboardRepo() {
|
|
32401
33858
|
const db = useAtlas84.getDb();
|
|
@@ -32406,7 +33863,7 @@ function useDashboardRepo() {
|
|
|
32406
33863
|
const work_order_collection = db.collection("work-orders");
|
|
32407
33864
|
const visitor_collection = db.collection("visitor.transactions");
|
|
32408
33865
|
const namespace_collection = "dashboard";
|
|
32409
|
-
const { delNamespace, getCache, setCache } =
|
|
33866
|
+
const { delNamespace, getCache, setCache } = useCache54(namespace_collection);
|
|
32410
33867
|
async function getAll({
|
|
32411
33868
|
site = ""
|
|
32412
33869
|
}, session) {
|
|
@@ -32570,7 +34027,7 @@ import {
|
|
|
32570
34027
|
makeCacheKey as makeCacheKey51,
|
|
32571
34028
|
paginate as paginate44,
|
|
32572
34029
|
useAtlas as useAtlas85,
|
|
32573
|
-
useCache as
|
|
34030
|
+
useCache as useCache55
|
|
32574
34031
|
} from "@7365admin1/node-server-utils";
|
|
32575
34032
|
import { ObjectId as ObjectId95 } from "mongodb";
|
|
32576
34033
|
function useNfcPatrolRouteRepo() {
|
|
@@ -32580,7 +34037,7 @@ function useNfcPatrolRouteRepo() {
|
|
|
32580
34037
|
}
|
|
32581
34038
|
const namespace_collection = "nfc-patrol-routes";
|
|
32582
34039
|
const collection = db.collection(namespace_collection);
|
|
32583
|
-
const { delNamespace, getCache, setCache } =
|
|
34040
|
+
const { delNamespace, getCache, setCache } = useCache55(namespace_collection);
|
|
32584
34041
|
async function createIndexes() {
|
|
32585
34042
|
try {
|
|
32586
34043
|
await collection.createIndexes([
|
|
@@ -33317,7 +34774,7 @@ import {
|
|
|
33317
34774
|
NotFoundError as NotFoundError43,
|
|
33318
34775
|
paginate as paginate45,
|
|
33319
34776
|
useAtlas as useAtlas87,
|
|
33320
|
-
useCache as
|
|
34777
|
+
useCache as useCache56
|
|
33321
34778
|
} from "@7365admin1/node-server-utils";
|
|
33322
34779
|
import { ObjectId as ObjectId97 } from "mongodb";
|
|
33323
34780
|
function useIncidentReportRepo() {
|
|
@@ -33348,7 +34805,7 @@ function useIncidentReportRepo() {
|
|
|
33348
34805
|
}
|
|
33349
34806
|
const namespace_collection = "incident-reports";
|
|
33350
34807
|
const collection = db.collection(namespace_collection);
|
|
33351
|
-
const { delNamespace, getCache, setCache } =
|
|
34808
|
+
const { delNamespace, getCache, setCache } = useCache56(namespace_collection);
|
|
33352
34809
|
async function add(value, session) {
|
|
33353
34810
|
try {
|
|
33354
34811
|
value = MIncidentReport(value);
|
|
@@ -33423,6 +34880,9 @@ function useIncidentReportRepo() {
|
|
|
33423
34880
|
$regex: search,
|
|
33424
34881
|
$options: "i"
|
|
33425
34882
|
}
|
|
34883
|
+
},
|
|
34884
|
+
{
|
|
34885
|
+
approvedByName: { $regex: search, $options: "i" }
|
|
33426
34886
|
}
|
|
33427
34887
|
]
|
|
33428
34888
|
},
|
|
@@ -34089,7 +35549,7 @@ import {
|
|
|
34089
35549
|
makeCacheKey as makeCacheKey53,
|
|
34090
35550
|
NotFoundError as NotFoundError45,
|
|
34091
35551
|
useAtlas as useAtlas89,
|
|
34092
|
-
useCache as
|
|
35552
|
+
useCache as useCache57
|
|
34093
35553
|
} from "@7365admin1/node-server-utils";
|
|
34094
35554
|
import { ObjectId as ObjectId99 } from "mongodb";
|
|
34095
35555
|
function useNfcPatrolSettingsRepository() {
|
|
@@ -34099,7 +35559,7 @@ function useNfcPatrolSettingsRepository() {
|
|
|
34099
35559
|
}
|
|
34100
35560
|
const namespace_collection = "site.nfc-patrol-settings";
|
|
34101
35561
|
const collection = db.collection(namespace_collection);
|
|
34102
|
-
const { delNamespace, setCache, getCache } =
|
|
35562
|
+
const { delNamespace, setCache, getCache } = useCache57(namespace_collection);
|
|
34103
35563
|
async function createIndexes() {
|
|
34104
35564
|
try {
|
|
34105
35565
|
await collection.createIndexes([{ key: { site: 1 }, unique: true }]);
|
|
@@ -34344,7 +35804,7 @@ import {
|
|
|
34344
35804
|
NotFoundError as NotFoundError46,
|
|
34345
35805
|
paginate as paginate46,
|
|
34346
35806
|
useAtlas as useAtlas91,
|
|
34347
|
-
useCache as
|
|
35807
|
+
useCache as useCache58
|
|
34348
35808
|
} from "@7365admin1/node-server-utils";
|
|
34349
35809
|
|
|
34350
35810
|
// src/models/occurrence-subject.model.ts
|
|
@@ -34421,7 +35881,7 @@ function useOccurrenceSubjectRepo() {
|
|
|
34421
35881
|
}
|
|
34422
35882
|
const namespace_collection = "occurrence-subjects";
|
|
34423
35883
|
const collection = db.collection(namespace_collection);
|
|
34424
|
-
const { delNamespace, getCache, setCache } =
|
|
35884
|
+
const { delNamespace, getCache, setCache } = useCache58(namespace_collection);
|
|
34425
35885
|
async function add(value, session) {
|
|
34426
35886
|
try {
|
|
34427
35887
|
value = MOccurrenceSubject(value);
|
|
@@ -34989,7 +36449,7 @@ import {
|
|
|
34989
36449
|
NotFoundError as NotFoundError47,
|
|
34990
36450
|
paginate as paginate47,
|
|
34991
36451
|
useAtlas as useAtlas93,
|
|
34992
|
-
useCache as
|
|
36452
|
+
useCache as useCache59
|
|
34993
36453
|
} from "@7365admin1/node-server-utils";
|
|
34994
36454
|
import { ObjectId as ObjectId103 } from "mongodb";
|
|
34995
36455
|
function useOnlineFormRepo() {
|
|
@@ -34999,7 +36459,7 @@ function useOnlineFormRepo() {
|
|
|
34999
36459
|
}
|
|
35000
36460
|
const namespace_collection = "online-forms";
|
|
35001
36461
|
const collection = db.collection(namespace_collection);
|
|
35002
|
-
const { delNamespace, getCache, setCache } =
|
|
36462
|
+
const { delNamespace, getCache, setCache } = useCache59(namespace_collection);
|
|
35003
36463
|
async function createTextIndex() {
|
|
35004
36464
|
try {
|
|
35005
36465
|
await collection.createIndex({
|
|
@@ -35745,7 +37205,7 @@ import {
|
|
|
35745
37205
|
makeCacheKey as makeCacheKey56,
|
|
35746
37206
|
paginate as paginate48,
|
|
35747
37207
|
useAtlas as useAtlas95,
|
|
35748
|
-
useCache as
|
|
37208
|
+
useCache as useCache60
|
|
35749
37209
|
} from "@7365admin1/node-server-utils";
|
|
35750
37210
|
import { ObjectId as ObjectId105 } from "mongodb";
|
|
35751
37211
|
function useNfcPatrolLogRepo() {
|
|
@@ -35755,7 +37215,7 @@ function useNfcPatrolLogRepo() {
|
|
|
35755
37215
|
}
|
|
35756
37216
|
const namespace_collection = "nfc-patrol-logs";
|
|
35757
37217
|
const collection = db.collection(namespace_collection);
|
|
35758
|
-
const { delNamespace, getCache, setCache } =
|
|
37218
|
+
const { delNamespace, getCache, setCache } = useCache60(namespace_collection);
|
|
35759
37219
|
async function createIndexes() {
|
|
35760
37220
|
try {
|
|
35761
37221
|
await collection.createIndexes([
|
|
@@ -35978,7 +37438,9 @@ function useNfcPatrolLogController() {
|
|
|
35978
37438
|
};
|
|
35979
37439
|
}
|
|
35980
37440
|
export {
|
|
37441
|
+
ANPRMode,
|
|
35981
37442
|
AccessTypeProps,
|
|
37443
|
+
BULLETIN_RECIPIENTS,
|
|
35982
37444
|
DEVICE_STATUS,
|
|
35983
37445
|
EAccessCardTypes,
|
|
35984
37446
|
EAccessCardUserTypes,
|
|
@@ -36037,12 +37499,15 @@ export {
|
|
|
36037
37499
|
MVerification,
|
|
36038
37500
|
MVisitorTransaction,
|
|
36039
37501
|
MWorkOrder,
|
|
37502
|
+
OrgNature,
|
|
36040
37503
|
PERSON_TYPES,
|
|
37504
|
+
STATUS_VALUES,
|
|
36041
37505
|
UseAccessManagementRepo,
|
|
36042
|
-
|
|
37506
|
+
VehicleCategory,
|
|
37507
|
+
VehicleStatus,
|
|
37508
|
+
VehicleType,
|
|
36043
37509
|
allowedFieldsSite,
|
|
36044
37510
|
allowedNatures,
|
|
36045
|
-
allowedTypes,
|
|
36046
37511
|
attendanceSchema,
|
|
36047
37512
|
attendanceSettingsSchema,
|
|
36048
37513
|
chatSchema,
|