@7365admin1/core 2.15.0 → 2.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/index.d.ts +18 -5
- package/dist/index.js +548 -218
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +548 -218
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -11040,7 +11040,7 @@ function useFeedbackController() {
|
|
|
11040
11040
|
}
|
|
11041
11041
|
async function deleteFeedback(req, res, next) {
|
|
11042
11042
|
const validation = import_joi28.default.string().hex().required();
|
|
11043
|
-
const _id = req.
|
|
11043
|
+
const _id = req.params.id;
|
|
11044
11044
|
const { error } = validation.validate(_id);
|
|
11045
11045
|
if (error) {
|
|
11046
11046
|
import_node_server_utils55.logger.log({ level: "error", message: error.message });
|
|
@@ -11404,8 +11404,7 @@ function useWorkOrderController() {
|
|
|
11404
11404
|
}
|
|
11405
11405
|
async function deleteWorkOrder(req, res, next) {
|
|
11406
11406
|
const validation = import_joi29.default.string().hex().required();
|
|
11407
|
-
const _id = req.
|
|
11408
|
-
console.log(_id);
|
|
11407
|
+
const _id = req.params.id;
|
|
11409
11408
|
const { error } = validation.validate(_id);
|
|
11410
11409
|
if (error) {
|
|
11411
11410
|
import_node_server_utils57.logger.log({ level: "error", message: error.message });
|
|
@@ -15126,11 +15125,14 @@ function usePersonRepo() {
|
|
|
15126
15125
|
const namespace_collection = "site.people";
|
|
15127
15126
|
const collection = db.collection(namespace_collection);
|
|
15128
15127
|
const { delNamespace, getCache, setCache } = (0, import_node_server_utils79.useCache)(namespace_collection);
|
|
15129
|
-
async function
|
|
15128
|
+
async function createIndexes() {
|
|
15130
15129
|
try {
|
|
15131
|
-
await collection.
|
|
15130
|
+
await collection.createIndexes([
|
|
15131
|
+
{ key: { contact: 1 } },
|
|
15132
|
+
{ key: { nric: 1 } }
|
|
15133
|
+
]);
|
|
15132
15134
|
} catch (error) {
|
|
15133
|
-
throw new import_node_server_utils79.InternalServerError("Failed to create index.");
|
|
15135
|
+
throw new import_node_server_utils79.InternalServerError("Failed to create index on site people.");
|
|
15134
15136
|
}
|
|
15135
15137
|
}
|
|
15136
15138
|
async function createTextIndex() {
|
|
@@ -15520,6 +15522,47 @@ function usePersonRepo() {
|
|
|
15520
15522
|
throw new import_node_server_utils79.InternalServerError("Failed to fetch people by plate number.");
|
|
15521
15523
|
}
|
|
15522
15524
|
}
|
|
15525
|
+
async function getPeopleByNRIC({
|
|
15526
|
+
page = 1,
|
|
15527
|
+
limit = 10,
|
|
15528
|
+
nric = "",
|
|
15529
|
+
sort = {},
|
|
15530
|
+
site = ""
|
|
15531
|
+
}) {
|
|
15532
|
+
page = page > 0 ? page - 1 : 0;
|
|
15533
|
+
const normalizedNric = nric.trim();
|
|
15534
|
+
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
15535
|
+
const query = {
|
|
15536
|
+
...nric && { nric: normalizedNric },
|
|
15537
|
+
site: typeof site === "string" ? new import_mongodb44.ObjectId(site) : site
|
|
15538
|
+
};
|
|
15539
|
+
const cacheOptions = {
|
|
15540
|
+
site,
|
|
15541
|
+
...nric && { nric: normalizedNric },
|
|
15542
|
+
page: String(page),
|
|
15543
|
+
limit: String(limit),
|
|
15544
|
+
sort: JSON.stringify(sort)
|
|
15545
|
+
};
|
|
15546
|
+
try {
|
|
15547
|
+
const cacheKey = (0, import_node_server_utils79.makeCacheKey)(namespace_collection, cacheOptions);
|
|
15548
|
+
const cachedData = await getCache(cacheKey);
|
|
15549
|
+
if (cachedData) {
|
|
15550
|
+
import_node_server_utils79.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
15551
|
+
return cachedData;
|
|
15552
|
+
}
|
|
15553
|
+
const items = await collection.find(query).sort(sort).skip(page * limit).limit(limit).toArray();
|
|
15554
|
+
const length = await collection.countDocuments(query);
|
|
15555
|
+
const data = (0, import_node_server_utils79.paginate)(items, page, limit, length);
|
|
15556
|
+
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
15557
|
+
import_node_server_utils79.logger.info(`Cache set for key: ${cacheKey}`);
|
|
15558
|
+
}).catch((err) => {
|
|
15559
|
+
import_node_server_utils79.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
15560
|
+
});
|
|
15561
|
+
return data;
|
|
15562
|
+
} catch (error) {
|
|
15563
|
+
throw new import_node_server_utils79.InternalServerError("Failed to retrieve person by NRIC.");
|
|
15564
|
+
}
|
|
15565
|
+
}
|
|
15523
15566
|
return {
|
|
15524
15567
|
add,
|
|
15525
15568
|
getAll,
|
|
@@ -15529,11 +15572,12 @@ function usePersonRepo() {
|
|
|
15529
15572
|
createTextIndex,
|
|
15530
15573
|
getPersonByPlateNumber,
|
|
15531
15574
|
getByNRIC,
|
|
15532
|
-
|
|
15575
|
+
createIndexes,
|
|
15533
15576
|
getPersonByPhoneNumber,
|
|
15534
15577
|
getPeopleByUnit,
|
|
15535
15578
|
getCompany,
|
|
15536
|
-
getPeopleByPlateNumber
|
|
15579
|
+
getPeopleByPlateNumber,
|
|
15580
|
+
getPeopleByNRIC
|
|
15537
15581
|
};
|
|
15538
15582
|
}
|
|
15539
15583
|
|
|
@@ -15572,7 +15616,15 @@ var ANPRMode = /* @__PURE__ */ ((ANPRMode2) => {
|
|
|
15572
15616
|
return ANPRMode2;
|
|
15573
15617
|
})(ANPRMode || {});
|
|
15574
15618
|
var vehicleSchema = import_joi43.default.object({
|
|
15575
|
-
plateNumber: import_joi43.default.
|
|
15619
|
+
plateNumber: import_joi43.default.alternatives().try(
|
|
15620
|
+
import_joi43.default.array().items(import_joi43.default.string().trim().min(1)).min(1),
|
|
15621
|
+
import_joi43.default.string().trim().min(1)
|
|
15622
|
+
).custom((value) => {
|
|
15623
|
+
if (typeof value === "string") {
|
|
15624
|
+
return value.split(",").map((p) => p.trim()).filter(Boolean);
|
|
15625
|
+
}
|
|
15626
|
+
return value;
|
|
15627
|
+
}).required(),
|
|
15576
15628
|
type: import_joi43.default.string().required().valid(...Object.values(VehicleType)),
|
|
15577
15629
|
category: import_joi43.default.string().required().valid(...Object.values(VehicleCategory)),
|
|
15578
15630
|
name: import_joi43.default.string().required(),
|
|
@@ -15706,19 +15758,9 @@ function useVehicleRepo() {
|
|
|
15706
15758
|
await collection.createIndexes([
|
|
15707
15759
|
{ key: { status: 1 } },
|
|
15708
15760
|
{ key: { type: 1 } },
|
|
15709
|
-
{ key: { category: 1 } }
|
|
15710
|
-
{
|
|
15711
|
-
key: { nric: 1 },
|
|
15712
|
-
name: "uniq_nric_not_deleted_nonempty",
|
|
15713
|
-
unique: true,
|
|
15714
|
-
partialFilterExpression: {
|
|
15715
|
-
nric: { $type: "string", $gt: "" },
|
|
15716
|
-
deletedAt: ""
|
|
15717
|
-
}
|
|
15718
|
-
}
|
|
15761
|
+
{ key: { category: 1 } }
|
|
15719
15762
|
]);
|
|
15720
15763
|
} catch (error) {
|
|
15721
|
-
console.error("createIndexes error:", error);
|
|
15722
15764
|
throw new import_node_server_utils81.InternalServerError("Failed to create index on vehicle.");
|
|
15723
15765
|
}
|
|
15724
15766
|
}
|
|
@@ -15776,14 +15818,14 @@ function useVehicleRepo() {
|
|
|
15776
15818
|
const baseQuery = {
|
|
15777
15819
|
...status && { status },
|
|
15778
15820
|
...type && { type },
|
|
15779
|
-
...
|
|
15821
|
+
...category && { category }
|
|
15780
15822
|
};
|
|
15781
15823
|
let query = { ...baseQuery };
|
|
15782
15824
|
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
15783
15825
|
const cacheOptions = {
|
|
15784
15826
|
...status && { status },
|
|
15785
15827
|
...type && { type },
|
|
15786
|
-
...
|
|
15828
|
+
...category && { category },
|
|
15787
15829
|
page: String(page),
|
|
15788
15830
|
limit: String(limit),
|
|
15789
15831
|
sort: JSON.stringify(sort)
|
|
@@ -15799,47 +15841,130 @@ function useVehicleRepo() {
|
|
|
15799
15841
|
return cachedData;
|
|
15800
15842
|
}
|
|
15801
15843
|
const escapeRegex = (input) => input.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
15802
|
-
|
|
15803
|
-
|
|
15804
|
-
|
|
15805
|
-
|
|
15806
|
-
|
|
15807
|
-
|
|
15808
|
-
|
|
15809
|
-
|
|
15810
|
-
|
|
15811
|
-
|
|
15812
|
-
|
|
15813
|
-
|
|
15814
|
-
|
|
15815
|
-
|
|
15816
|
-
|
|
15844
|
+
const buildGroupedPipeline = (matchQuery) => [
|
|
15845
|
+
{ $match: matchQuery },
|
|
15846
|
+
{
|
|
15847
|
+
$lookup: {
|
|
15848
|
+
from: "building-units",
|
|
15849
|
+
localField: "unit",
|
|
15850
|
+
foreignField: "_id",
|
|
15851
|
+
as: "units",
|
|
15852
|
+
pipeline: [{ $project: { name: 1 } }]
|
|
15853
|
+
}
|
|
15854
|
+
},
|
|
15855
|
+
{ $unwind: { path: "$units", preserveNullAndEmptyArrays: true } },
|
|
15856
|
+
{
|
|
15857
|
+
$project: {
|
|
15858
|
+
_id: 1,
|
|
15859
|
+
name: 1,
|
|
15860
|
+
type: 1,
|
|
15861
|
+
category: 1,
|
|
15862
|
+
status: 1,
|
|
15863
|
+
phoneNumber: 1,
|
|
15864
|
+
block: 1,
|
|
15865
|
+
level: 1,
|
|
15866
|
+
unit: "$units.name",
|
|
15867
|
+
recNo: 1,
|
|
15868
|
+
nric: 1,
|
|
15869
|
+
plateNumber: 1
|
|
15870
|
+
}
|
|
15871
|
+
},
|
|
15872
|
+
{
|
|
15873
|
+
$group: {
|
|
15874
|
+
_id: {
|
|
15875
|
+
$cond: [
|
|
15876
|
+
{
|
|
15877
|
+
$and: [{ $ne: ["$nric", null] }, { $ne: ["$nric", ""] }]
|
|
15878
|
+
},
|
|
15879
|
+
{
|
|
15880
|
+
nric: "$nric",
|
|
15881
|
+
block: "$block",
|
|
15882
|
+
level: "$level",
|
|
15883
|
+
unit: "$unit"
|
|
15884
|
+
},
|
|
15885
|
+
"$_id"
|
|
15886
|
+
]
|
|
15887
|
+
},
|
|
15888
|
+
vehicleId: { $first: "$_id" },
|
|
15889
|
+
name: { $first: "$name" },
|
|
15890
|
+
category: { $first: "$category" },
|
|
15891
|
+
phoneNumber: { $first: "$phoneNumber" },
|
|
15892
|
+
block: { $first: "$block" },
|
|
15893
|
+
level: { $first: "$level" },
|
|
15894
|
+
unit: { $first: "$unit" },
|
|
15895
|
+
nric: { $first: "$nric" },
|
|
15896
|
+
plates: {
|
|
15897
|
+
$addToSet: {
|
|
15898
|
+
plateNumber: "$plateNumber",
|
|
15899
|
+
recNo: "$recNo",
|
|
15900
|
+
status: "$status",
|
|
15901
|
+
type: "$type"
|
|
15902
|
+
}
|
|
15817
15903
|
}
|
|
15818
|
-
}
|
|
15819
|
-
|
|
15820
|
-
|
|
15821
|
-
|
|
15822
|
-
|
|
15823
|
-
|
|
15824
|
-
|
|
15825
|
-
|
|
15826
|
-
|
|
15827
|
-
|
|
15828
|
-
|
|
15829
|
-
|
|
15830
|
-
|
|
15831
|
-
|
|
15832
|
-
|
|
15904
|
+
}
|
|
15905
|
+
},
|
|
15906
|
+
{
|
|
15907
|
+
$project: {
|
|
15908
|
+
_id: "$vehicleId",
|
|
15909
|
+
name: 1,
|
|
15910
|
+
type: 1,
|
|
15911
|
+
category: 1,
|
|
15912
|
+
status: 1,
|
|
15913
|
+
phoneNumber: 1,
|
|
15914
|
+
block: 1,
|
|
15915
|
+
level: 1,
|
|
15916
|
+
unit: 1,
|
|
15917
|
+
nric: 1,
|
|
15918
|
+
plates: {
|
|
15919
|
+
$filter: {
|
|
15920
|
+
input: "$plates",
|
|
15921
|
+
as: "plate",
|
|
15922
|
+
cond: {
|
|
15923
|
+
$and: [
|
|
15924
|
+
{ $ne: ["$$plate.plateNumber", null] },
|
|
15925
|
+
{ $ne: ["$$plate.plateNumber", ""] }
|
|
15926
|
+
]
|
|
15927
|
+
}
|
|
15928
|
+
}
|
|
15833
15929
|
}
|
|
15834
15930
|
}
|
|
15835
|
-
|
|
15836
|
-
|
|
15931
|
+
},
|
|
15932
|
+
{ $sort: sort },
|
|
15933
|
+
{ $skip: page * limit },
|
|
15934
|
+
{ $limit: limit }
|
|
15935
|
+
];
|
|
15936
|
+
const buildGroupedCountPipeline = (matchQuery) => [
|
|
15937
|
+
{ $match: matchQuery },
|
|
15938
|
+
{
|
|
15939
|
+
$group: {
|
|
15940
|
+
_id: {
|
|
15941
|
+
$cond: [
|
|
15942
|
+
{
|
|
15943
|
+
$and: [{ $ne: ["$nric", null] }, { $ne: ["$nric", ""] }]
|
|
15944
|
+
},
|
|
15945
|
+
{
|
|
15946
|
+
nric: "$nric",
|
|
15947
|
+
block: "$block",
|
|
15948
|
+
level: "$level",
|
|
15949
|
+
unit: "$unit"
|
|
15950
|
+
},
|
|
15951
|
+
"$_id"
|
|
15952
|
+
]
|
|
15953
|
+
}
|
|
15954
|
+
}
|
|
15955
|
+
},
|
|
15956
|
+
{ $count: "total" }
|
|
15957
|
+
];
|
|
15958
|
+
try {
|
|
15959
|
+
let items = [];
|
|
15960
|
+
let length = 0;
|
|
15961
|
+
items = await collection.aggregate(buildGroupedPipeline(query)).toArray();
|
|
15962
|
+
const countResult = await collection.aggregate(buildGroupedCountPipeline(query)).toArray();
|
|
15963
|
+
length = countResult[0]?.total || 0;
|
|
15837
15964
|
if ((!items || items.length === 0) && search) {
|
|
15838
15965
|
const escaped = escapeRegex(search);
|
|
15839
15966
|
const regexQuery = {
|
|
15840
15967
|
...baseQuery,
|
|
15841
|
-
...type && { type },
|
|
15842
|
-
...category && { category },
|
|
15843
15968
|
$or: [
|
|
15844
15969
|
{ name: { $regex: escaped, $options: "i" } },
|
|
15845
15970
|
{ plateNumber: { $regex: escaped, $options: "i" } },
|
|
@@ -15850,38 +15975,9 @@ function useVehicleRepo() {
|
|
|
15850
15975
|
{ nric: { $regex: escaped, $options: "i" } }
|
|
15851
15976
|
]
|
|
15852
15977
|
};
|
|
15853
|
-
items = await collection.aggregate(
|
|
15854
|
-
|
|
15855
|
-
|
|
15856
|
-
{ $skip: page * limit },
|
|
15857
|
-
{ $limit: limit },
|
|
15858
|
-
{
|
|
15859
|
-
$lookup: {
|
|
15860
|
-
from: "building-units",
|
|
15861
|
-
localField: "unit",
|
|
15862
|
-
foreignField: "_id",
|
|
15863
|
-
as: "units",
|
|
15864
|
-
pipeline: [{ $project: { name: 1 } }]
|
|
15865
|
-
}
|
|
15866
|
-
},
|
|
15867
|
-
{ $unwind: { path: "$units", preserveNullAndEmptyArrays: true } },
|
|
15868
|
-
{
|
|
15869
|
-
$project: {
|
|
15870
|
-
name: 1,
|
|
15871
|
-
type: 1,
|
|
15872
|
-
category: 1,
|
|
15873
|
-
status: 1,
|
|
15874
|
-
phoneNumber: 1,
|
|
15875
|
-
block: 1,
|
|
15876
|
-
level: 1,
|
|
15877
|
-
unit: "$units.name",
|
|
15878
|
-
plateNumber: 1,
|
|
15879
|
-
recNo: 1,
|
|
15880
|
-
nric: 1
|
|
15881
|
-
}
|
|
15882
|
-
}
|
|
15883
|
-
]).toArray();
|
|
15884
|
-
length = await collection.countDocuments(regexQuery);
|
|
15978
|
+
items = await collection.aggregate(buildGroupedPipeline(regexQuery)).toArray();
|
|
15979
|
+
const regexCountResult = await collection.aggregate(buildGroupedCountPipeline(regexQuery)).toArray();
|
|
15980
|
+
length = regexCountResult[0]?.total || 0;
|
|
15885
15981
|
}
|
|
15886
15982
|
const data = (0, import_node_server_utils81.paginate)(items, page, limit, length);
|
|
15887
15983
|
setCache(cacheKey, data, 15 * 60).then(() => import_node_server_utils81.logger.info(`Cache set for key: ${cacheKey}`)).catch(
|
|
@@ -15959,43 +16055,176 @@ function useVehicleRepo() {
|
|
|
15959
16055
|
}
|
|
15960
16056
|
const data = await collection.aggregate([
|
|
15961
16057
|
{ $match: { _id } },
|
|
16058
|
+
{ $limit: 1 },
|
|
16059
|
+
{
|
|
16060
|
+
$project: {
|
|
16061
|
+
_id: 1,
|
|
16062
|
+
nric: 1,
|
|
16063
|
+
block: 1,
|
|
16064
|
+
level: 1,
|
|
16065
|
+
unit: 1
|
|
16066
|
+
}
|
|
16067
|
+
},
|
|
15962
16068
|
{
|
|
15963
16069
|
$lookup: {
|
|
15964
|
-
from:
|
|
15965
|
-
|
|
15966
|
-
|
|
15967
|
-
|
|
15968
|
-
|
|
16070
|
+
from: collection.collectionName,
|
|
16071
|
+
let: {
|
|
16072
|
+
vehicleId: "$_id",
|
|
16073
|
+
vehicleNric: "$nric",
|
|
16074
|
+
vehicleBlock: "$block",
|
|
16075
|
+
vehicleLevel: "$level",
|
|
16076
|
+
vehicleUnit: "$unit"
|
|
16077
|
+
},
|
|
16078
|
+
pipeline: [
|
|
16079
|
+
{
|
|
16080
|
+
$match: {
|
|
16081
|
+
$expr: {
|
|
16082
|
+
$cond: [
|
|
16083
|
+
{
|
|
16084
|
+
$and: [
|
|
16085
|
+
{ $ne: ["$$vehicleNric", null] },
|
|
16086
|
+
{ $ne: ["$$vehicleNric", ""] }
|
|
16087
|
+
]
|
|
16088
|
+
},
|
|
16089
|
+
{
|
|
16090
|
+
$and: [
|
|
16091
|
+
{ $eq: ["$nric", "$$vehicleNric"] },
|
|
16092
|
+
{ $eq: ["$block", "$$vehicleBlock"] },
|
|
16093
|
+
{ $eq: ["$level", "$$vehicleLevel"] },
|
|
16094
|
+
{ $eq: ["$unit", "$$vehicleUnit"] }
|
|
16095
|
+
]
|
|
16096
|
+
},
|
|
16097
|
+
{ $eq: ["$_id", "$$vehicleId"] }
|
|
16098
|
+
]
|
|
16099
|
+
}
|
|
16100
|
+
}
|
|
16101
|
+
},
|
|
16102
|
+
{
|
|
16103
|
+
$lookup: {
|
|
16104
|
+
from: "building-units",
|
|
16105
|
+
localField: "unit",
|
|
16106
|
+
foreignField: "_id",
|
|
16107
|
+
as: "units",
|
|
16108
|
+
pipeline: [{ $project: { name: 1 } }]
|
|
16109
|
+
}
|
|
16110
|
+
},
|
|
16111
|
+
{
|
|
16112
|
+
$unwind: { path: "$units", preserveNullAndEmptyArrays: true }
|
|
16113
|
+
},
|
|
16114
|
+
{
|
|
16115
|
+
$project: {
|
|
16116
|
+
_id: 1,
|
|
16117
|
+
name: 1,
|
|
16118
|
+
phoneNumber: 1,
|
|
16119
|
+
plateNumber: 1,
|
|
16120
|
+
nric: 1,
|
|
16121
|
+
block: 1,
|
|
16122
|
+
level: 1,
|
|
16123
|
+
rawUnit: "$unit",
|
|
16124
|
+
unit: "$units.name",
|
|
16125
|
+
type: 1,
|
|
16126
|
+
category: 1,
|
|
16127
|
+
status: 1,
|
|
16128
|
+
recNo: 1,
|
|
16129
|
+
start: 1,
|
|
16130
|
+
end: 1,
|
|
16131
|
+
seasonPassType: 1
|
|
16132
|
+
}
|
|
16133
|
+
},
|
|
16134
|
+
{
|
|
16135
|
+
$group: {
|
|
16136
|
+
_id: {
|
|
16137
|
+
$cond: [
|
|
16138
|
+
{
|
|
16139
|
+
$and: [
|
|
16140
|
+
{ $ne: ["$nric", null] },
|
|
16141
|
+
{ $ne: ["$nric", ""] }
|
|
16142
|
+
]
|
|
16143
|
+
},
|
|
16144
|
+
{
|
|
16145
|
+
nric: "$nric",
|
|
16146
|
+
block: "$block",
|
|
16147
|
+
level: "$level",
|
|
16148
|
+
unit: "$unit"
|
|
16149
|
+
},
|
|
16150
|
+
"$_id"
|
|
16151
|
+
]
|
|
16152
|
+
},
|
|
16153
|
+
vehicleId: { $first: "$_id" },
|
|
16154
|
+
name: { $first: "$name" },
|
|
16155
|
+
category: { $first: "$category" },
|
|
16156
|
+
phoneNumber: { $first: "$phoneNumber" },
|
|
16157
|
+
block: { $first: "$block" },
|
|
16158
|
+
level: { $first: "$level" },
|
|
16159
|
+
unit: { $first: "$unit" },
|
|
16160
|
+
nric: { $first: "$nric" },
|
|
16161
|
+
start: { $first: "$start" },
|
|
16162
|
+
end: { $first: "$end" },
|
|
16163
|
+
seasonPassType: { $first: "$seasonPassType" },
|
|
16164
|
+
plates: {
|
|
16165
|
+
$addToSet: {
|
|
16166
|
+
plateNumber: "$plateNumber",
|
|
16167
|
+
recNo: "$recNo",
|
|
16168
|
+
status: "$status",
|
|
16169
|
+
type: "$type"
|
|
16170
|
+
}
|
|
16171
|
+
}
|
|
16172
|
+
}
|
|
16173
|
+
},
|
|
16174
|
+
{
|
|
16175
|
+
$project: {
|
|
16176
|
+
_id: "$vehicleId",
|
|
16177
|
+
name: 1,
|
|
16178
|
+
phoneNumber: 1,
|
|
16179
|
+
nric: 1,
|
|
16180
|
+
block: 1,
|
|
16181
|
+
level: 1,
|
|
16182
|
+
unit: 1,
|
|
16183
|
+
type: 1,
|
|
16184
|
+
category: 1,
|
|
16185
|
+
status: 1,
|
|
16186
|
+
start: 1,
|
|
16187
|
+
end: 1,
|
|
16188
|
+
seasonPassType: 1,
|
|
16189
|
+
plates: {
|
|
16190
|
+
$filter: {
|
|
16191
|
+
input: "$plates",
|
|
16192
|
+
as: "plate",
|
|
16193
|
+
cond: {
|
|
16194
|
+
$and: [
|
|
16195
|
+
{ $ne: ["$$plate.plateNumber", null] },
|
|
16196
|
+
{ $ne: ["$$plate.plateNumber", ""] }
|
|
16197
|
+
]
|
|
16198
|
+
}
|
|
16199
|
+
}
|
|
16200
|
+
}
|
|
16201
|
+
}
|
|
16202
|
+
}
|
|
16203
|
+
],
|
|
16204
|
+
as: "vehicle"
|
|
15969
16205
|
}
|
|
15970
16206
|
},
|
|
15971
|
-
{ $unwind: { path: "$units", preserveNullAndEmptyArrays: true } },
|
|
15972
16207
|
{
|
|
15973
16208
|
$project: {
|
|
15974
|
-
|
|
15975
|
-
|
|
15976
|
-
|
|
15977
|
-
|
|
15978
|
-
|
|
15979
|
-
|
|
15980
|
-
type: 1,
|
|
15981
|
-
category: 1,
|
|
15982
|
-
status: 1,
|
|
15983
|
-
recNo: 1,
|
|
15984
|
-
start: 1,
|
|
15985
|
-
end: 1,
|
|
15986
|
-
seasonPassType: 1
|
|
16209
|
+
vehicle: { $arrayElemAt: ["$vehicle", 0] }
|
|
16210
|
+
}
|
|
16211
|
+
},
|
|
16212
|
+
{
|
|
16213
|
+
$replaceRoot: {
|
|
16214
|
+
newRoot: "$vehicle"
|
|
15987
16215
|
}
|
|
15988
16216
|
}
|
|
15989
16217
|
]).toArray();
|
|
15990
16218
|
if (!data || !data.length) {
|
|
15991
16219
|
throw new import_node_server_utils81.NotFoundError("Vehicle not found.");
|
|
15992
16220
|
}
|
|
15993
|
-
|
|
16221
|
+
const result = data[0];
|
|
16222
|
+
setCache(cacheKey, result, 15 * 60).then(() => {
|
|
15994
16223
|
import_node_server_utils81.logger.info(`Cache set for key: ${cacheKey}`);
|
|
15995
16224
|
}).catch((err) => {
|
|
15996
16225
|
import_node_server_utils81.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
15997
16226
|
});
|
|
15998
|
-
return
|
|
16227
|
+
return result;
|
|
15999
16228
|
} catch (error) {
|
|
16000
16229
|
throw error;
|
|
16001
16230
|
}
|
|
@@ -16129,36 +16358,34 @@ function useVehicleRepo() {
|
|
|
16129
16358
|
async function getVehiclesByNRIC({
|
|
16130
16359
|
page = 1,
|
|
16131
16360
|
limit = 10,
|
|
16132
|
-
|
|
16361
|
+
nric = "",
|
|
16133
16362
|
sort = {}
|
|
16134
16363
|
}) {
|
|
16135
16364
|
page = page > 0 ? page - 1 : 0;
|
|
16136
|
-
|
|
16137
|
-
|
|
16365
|
+
if (!nric) {
|
|
16366
|
+
throw new import_node_server_utils81.BadRequestError("NRIC is required.");
|
|
16367
|
+
}
|
|
16368
|
+
const _nric = nric.trim();
|
|
16369
|
+
const query = {
|
|
16370
|
+
deletedAt: "",
|
|
16371
|
+
nric: _nric
|
|
16138
16372
|
};
|
|
16139
|
-
let query = { ...baseQuery };
|
|
16140
16373
|
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
16141
16374
|
const cacheOptions = {
|
|
16142
16375
|
deletedAt: "",
|
|
16376
|
+
nric: _nric,
|
|
16143
16377
|
page: String(page),
|
|
16144
16378
|
limit: String(limit),
|
|
16145
16379
|
sort: JSON.stringify(sort)
|
|
16146
16380
|
};
|
|
16147
|
-
if (search) {
|
|
16148
|
-
query.$text = { $search: search };
|
|
16149
|
-
cacheOptions.search = search;
|
|
16150
|
-
}
|
|
16151
16381
|
const cacheKey = (0, import_node_server_utils81.makeCacheKey)(namespace_collection, cacheOptions);
|
|
16152
16382
|
const cachedData = await getCache(cacheKey);
|
|
16153
16383
|
if (cachedData) {
|
|
16154
16384
|
import_node_server_utils81.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
16155
16385
|
return cachedData;
|
|
16156
16386
|
}
|
|
16157
|
-
const escapeRegex = (input) => input.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
16158
16387
|
try {
|
|
16159
|
-
|
|
16160
|
-
let length = 0;
|
|
16161
|
-
items = await collection.aggregate([
|
|
16388
|
+
const items = await collection.aggregate([
|
|
16162
16389
|
{ $match: query },
|
|
16163
16390
|
{ $sort: sort },
|
|
16164
16391
|
{ $skip: page * limit },
|
|
@@ -16175,37 +16402,7 @@ function useVehicleRepo() {
|
|
|
16175
16402
|
}
|
|
16176
16403
|
}
|
|
16177
16404
|
]).toArray();
|
|
16178
|
-
length = await collection.countDocuments(query);
|
|
16179
|
-
if ((!items || items.length === 0) && search) {
|
|
16180
|
-
const escaped = escapeRegex(search);
|
|
16181
|
-
const regexQuery = {
|
|
16182
|
-
...baseQuery,
|
|
16183
|
-
$or: [
|
|
16184
|
-
{ name: { $regex: escaped, $options: "i" } },
|
|
16185
|
-
{ plateNumber: { $regex: escaped, $options: "i" } },
|
|
16186
|
-
{ level: { $regex: escaped, $options: "i" } },
|
|
16187
|
-
{ nric: { $regex: escaped, $options: "i" } }
|
|
16188
|
-
]
|
|
16189
|
-
};
|
|
16190
|
-
items = await collection.aggregate([
|
|
16191
|
-
{ $match: regexQuery },
|
|
16192
|
-
{ $sort: sort },
|
|
16193
|
-
{ $skip: page * limit },
|
|
16194
|
-
{ $limit: limit },
|
|
16195
|
-
{
|
|
16196
|
-
$project: {
|
|
16197
|
-
name: 1,
|
|
16198
|
-
phoneNumber: 1,
|
|
16199
|
-
plateNumber: 1,
|
|
16200
|
-
recNo: 1,
|
|
16201
|
-
nric: 1,
|
|
16202
|
-
status: 1,
|
|
16203
|
-
type: 1
|
|
16204
|
-
}
|
|
16205
|
-
}
|
|
16206
|
-
]).toArray();
|
|
16207
|
-
length = await collection.countDocuments(regexQuery);
|
|
16208
|
-
}
|
|
16405
|
+
const length = await collection.countDocuments(query);
|
|
16209
16406
|
const data = (0, import_node_server_utils81.paginate)(items, page, limit, length);
|
|
16210
16407
|
setCache(cacheKey, data, 15 * 60).then(() => import_node_server_utils81.logger.info(`Cache set for key: ${cacheKey}`)).catch(
|
|
16211
16408
|
(err) => import_node_server_utils81.logger.error(`Failed to set cache for key: ${cacheKey}`, err)
|
|
@@ -16665,7 +16862,7 @@ function useDahuaService() {
|
|
|
16665
16862
|
host: value.host,
|
|
16666
16863
|
username: value.username,
|
|
16667
16864
|
password: value.password,
|
|
16668
|
-
endpoint: `/cgi-bin/recordUpdater.cgi?action=insert&name=${value.mode}&PlateNumber=${value.plateNumber}&BeginTime=${value.start}&CancelTime=${value.end}
|
|
16865
|
+
endpoint: `/cgi-bin/recordUpdater.cgi?action=insert&name=${value.mode}&PlateNumber=${value.plateNumber}&BeginTime=${value.start}&CancelTime=${value.end}&+OpenGate=true&MasterOfCar=${value.owner}`
|
|
16669
16866
|
});
|
|
16670
16867
|
return response;
|
|
16671
16868
|
} catch (error2) {
|
|
@@ -16731,8 +16928,9 @@ function useVehicleService() {
|
|
|
16731
16928
|
const { getById: _getById } = useOrgRepo();
|
|
16732
16929
|
async function add(value) {
|
|
16733
16930
|
const session = import_node_server_utils83.useAtlas.getClient()?.startSession();
|
|
16734
|
-
if (!session)
|
|
16931
|
+
if (!session) {
|
|
16735
16932
|
throw new Error("Unable to start session for vehicle service.");
|
|
16933
|
+
}
|
|
16736
16934
|
const org = await _getById(value.org);
|
|
16737
16935
|
if (!org)
|
|
16738
16936
|
throw new import_node_server_utils83.BadRequestError("Org not found");
|
|
@@ -16780,11 +16978,12 @@ function useVehicleService() {
|
|
|
16780
16978
|
}
|
|
16781
16979
|
}
|
|
16782
16980
|
const owner = String(value.name ?? "").substring(0, 15);
|
|
16981
|
+
const plateNumbers = value.plateNumber;
|
|
16783
16982
|
try {
|
|
16784
16983
|
session.startTransaction();
|
|
16785
16984
|
let message = "Vehicle plate number needs approval from property management.";
|
|
16985
|
+
let siteCameras = [];
|
|
16786
16986
|
if (value.status && value.status !== "pending" /* PENDING */) {
|
|
16787
|
-
const siteCameras = [];
|
|
16788
16987
|
let page = 1;
|
|
16789
16988
|
let pages = 1;
|
|
16790
16989
|
const limit = 20;
|
|
@@ -16799,40 +16998,44 @@ function useVehicleService() {
|
|
|
16799
16998
|
pages = siteCameraReq.pages || 1;
|
|
16800
16999
|
siteCameras.push(...siteCameraReq.items);
|
|
16801
17000
|
page++;
|
|
16802
|
-
} while (page
|
|
16803
|
-
if (!siteCameras.length)
|
|
17001
|
+
} while (page <= pages);
|
|
17002
|
+
if (!siteCameras.length) {
|
|
16804
17003
|
throw new import_node_server_utils83.BadRequestError("No site cameras found.");
|
|
16805
|
-
|
|
16806
|
-
|
|
16807
|
-
|
|
16808
|
-
|
|
16809
|
-
|
|
16810
|
-
|
|
16811
|
-
|
|
16812
|
-
|
|
16813
|
-
|
|
16814
|
-
|
|
16815
|
-
|
|
16816
|
-
|
|
16817
|
-
|
|
16818
|
-
|
|
16819
|
-
|
|
16820
|
-
|
|
16821
|
-
|
|
17004
|
+
}
|
|
17005
|
+
}
|
|
17006
|
+
for (const plateNumber of plateNumbers) {
|
|
17007
|
+
const vehicleValue = {
|
|
17008
|
+
...value,
|
|
17009
|
+
plateNumber,
|
|
17010
|
+
start,
|
|
17011
|
+
end
|
|
17012
|
+
};
|
|
17013
|
+
if (vehicleValue.status && vehicleValue.status !== "pending" /* PENDING */) {
|
|
17014
|
+
for (const camera of siteCameras) {
|
|
17015
|
+
const { host, username, password } = camera;
|
|
17016
|
+
const dahuaPayload = {
|
|
17017
|
+
host,
|
|
17018
|
+
username,
|
|
17019
|
+
password,
|
|
17020
|
+
plateNumber,
|
|
17021
|
+
mode: _mode,
|
|
17022
|
+
owner,
|
|
17023
|
+
...startDateDahua ? { start: startDateDahua } : {},
|
|
17024
|
+
...endDateDahua ? { end: endDateDahua } : {}
|
|
17025
|
+
};
|
|
17026
|
+
const dahuaResponse = await _addPlateNumber(dahuaPayload);
|
|
17027
|
+
if (dahuaResponse?.statusCode !== 200) {
|
|
17028
|
+
throw new import_node_server_utils83.BadRequestError(
|
|
17029
|
+
`Failed to add plate number to ANPR ${_type}`
|
|
17030
|
+
);
|
|
17031
|
+
}
|
|
17032
|
+
const responseData = dahuaResponse?.data?.toString("utf-8") ?? "";
|
|
17033
|
+
vehicleValue.recNo = responseData.split("=")[1]?.trim();
|
|
16822
17034
|
}
|
|
16823
|
-
const responseData = dahuaResponse?.data.toString("utf-8");
|
|
16824
|
-
value.recNo = responseData.split("=")[1]?.trim();
|
|
16825
17035
|
message = `Vehicle plate number added to ${_type} successfully.`;
|
|
16826
17036
|
}
|
|
17037
|
+
await _add(vehicleValue, session);
|
|
16827
17038
|
}
|
|
16828
|
-
const formattedValue = {
|
|
16829
|
-
...value,
|
|
16830
|
-
start,
|
|
16831
|
-
// ISO string or ""
|
|
16832
|
-
end
|
|
16833
|
-
// ISO string or ""
|
|
16834
|
-
};
|
|
16835
|
-
await _add(formattedValue, session);
|
|
16836
17039
|
await session.commitTransaction();
|
|
16837
17040
|
return message;
|
|
16838
17041
|
} catch (error) {
|
|
@@ -17037,14 +17240,14 @@ function useVehicleController() {
|
|
|
17037
17240
|
} = useVehicleRepo();
|
|
17038
17241
|
async function add(req, res, next) {
|
|
17039
17242
|
const payload = req.body;
|
|
17040
|
-
const { error } = vehicleSchema.validate(payload);
|
|
17243
|
+
const { error, value } = vehicleSchema.validate(payload);
|
|
17041
17244
|
if (error) {
|
|
17042
17245
|
import_node_server_utils84.logger.log({ level: "error", message: error.message });
|
|
17043
17246
|
next(new import_node_server_utils84.BadRequestError(error.message));
|
|
17044
17247
|
return;
|
|
17045
17248
|
}
|
|
17046
17249
|
try {
|
|
17047
|
-
const data = await _add(
|
|
17250
|
+
const data = await _add(value);
|
|
17048
17251
|
res.status(201).json({
|
|
17049
17252
|
message: "Vehicle added successfully.",
|
|
17050
17253
|
data
|
|
@@ -17064,9 +17267,9 @@ function useVehicleController() {
|
|
|
17064
17267
|
limit: import_joi46.default.number().integer().min(1).max(100).allow("", null).default(10),
|
|
17065
17268
|
sort: import_joi46.default.string().pattern(/^([a-zA-Z0-9_]+)(,[a-zA-Z0-9_]+)*$/).optional().allow("", ...allowedFields),
|
|
17066
17269
|
order: import_joi46.default.string().pattern(/^(asc|desc)(,(asc|desc))*$/).optional().allow("", ...allowedOrder),
|
|
17067
|
-
type: import_joi46.default.string().optional().valid(...Object.values(VehicleType)),
|
|
17068
|
-
category: import_joi46.default.string().optional().valid(...Object.values(VehicleCategory)),
|
|
17069
|
-
status: import_joi46.default.string().optional().valid(...Object.values(VehicleStatus)).allow("")
|
|
17270
|
+
type: import_joi46.default.string().optional().valid(...Object.values(VehicleType)).allow(null, ""),
|
|
17271
|
+
category: import_joi46.default.string().optional().valid(...Object.values(VehicleCategory)).allow(null, ""),
|
|
17272
|
+
status: import_joi46.default.string().optional().valid(...Object.values(VehicleStatus)).allow(null, "")
|
|
17070
17273
|
});
|
|
17071
17274
|
const query = { ...req.query };
|
|
17072
17275
|
const { error } = validation.validate(query);
|
|
@@ -17231,7 +17434,7 @@ function useVehicleController() {
|
|
|
17231
17434
|
const allowedFields = ["start", "end"];
|
|
17232
17435
|
const allowedOrder = ["asc", "desc"];
|
|
17233
17436
|
const validation = import_joi46.default.object({
|
|
17234
|
-
|
|
17437
|
+
nric: import_joi46.default.string().optional().allow("", null),
|
|
17235
17438
|
page: import_joi46.default.number().integer().min(1).allow("", null).default(1),
|
|
17236
17439
|
limit: import_joi46.default.number().integer().min(1).max(100).allow("", null).default(10),
|
|
17237
17440
|
sort: import_joi46.default.string().pattern(/^([a-zA-Z0-9_]+)(,[a-zA-Z0-9_]+)*$/).optional().allow("", ...allowedFields),
|
|
@@ -17244,7 +17447,7 @@ function useVehicleController() {
|
|
|
17244
17447
|
next(new import_node_server_utils84.BadRequestError(error.message));
|
|
17245
17448
|
return;
|
|
17246
17449
|
}
|
|
17247
|
-
const
|
|
17450
|
+
const nric = req.query.nric ?? "";
|
|
17248
17451
|
const page = parseInt(req.query.page ?? "1");
|
|
17249
17452
|
const limit = parseInt(req.query.limit ?? "10");
|
|
17250
17453
|
const sortObj = {};
|
|
@@ -17258,7 +17461,7 @@ function useVehicleController() {
|
|
|
17258
17461
|
});
|
|
17259
17462
|
try {
|
|
17260
17463
|
const data = await _getVehiclesByNRIC({
|
|
17261
|
-
|
|
17464
|
+
nric,
|
|
17262
17465
|
page,
|
|
17263
17466
|
limit,
|
|
17264
17467
|
sort: sortObj
|
|
@@ -19859,25 +20062,15 @@ function usePersonService() {
|
|
|
19859
20062
|
}
|
|
19860
20063
|
async function plateValidity(value) {
|
|
19861
20064
|
const now = /* @__PURE__ */ new Date();
|
|
19862
|
-
if (
|
|
19863
|
-
|
|
19864
|
-
|
|
19865
|
-
if (value.type === "resident") {
|
|
20065
|
+
if (["resident" /* RESIDENT */, "tenant" /* TENANT */].includes(
|
|
20066
|
+
value?.type
|
|
20067
|
+
)) {
|
|
19866
20068
|
const end = new Date(now);
|
|
19867
20069
|
end.setFullYear(end.getFullYear() + 10);
|
|
19868
|
-
return {
|
|
19869
|
-
|
|
19870
|
-
|
|
19871
|
-
|
|
19872
|
-
if (!unit) {
|
|
19873
|
-
throw new import_node_server_utils103.BadRequestError("Building unit not found for tenant.");
|
|
19874
|
-
}
|
|
19875
|
-
if (unit.leaseStart && unit.leaseEnd) {
|
|
19876
|
-
return {
|
|
19877
|
-
start: new Date(unit.leaseStart).toISOString(),
|
|
19878
|
-
end: new Date(unit.leaseEnd).toISOString()
|
|
19879
|
-
};
|
|
19880
|
-
}
|
|
20070
|
+
return {
|
|
20071
|
+
start: now.toISOString(),
|
|
20072
|
+
end: end.toISOString()
|
|
20073
|
+
};
|
|
19881
20074
|
}
|
|
19882
20075
|
return { start: "", end: "" };
|
|
19883
20076
|
}
|
|
@@ -19896,7 +20089,8 @@ function usePersonController() {
|
|
|
19896
20089
|
getPersonByPhoneNumber: _getPersonByPhoneNumber,
|
|
19897
20090
|
getPeopleByUnit: _getPeopleByUnit,
|
|
19898
20091
|
getCompany: _getCompany,
|
|
19899
|
-
getPeopleByPlateNumber: _getPeopleByPlateNumber
|
|
20092
|
+
getPeopleByPlateNumber: _getPeopleByPlateNumber,
|
|
20093
|
+
getPeopleByNRIC: _getPeopleByNRIC
|
|
19900
20094
|
} = usePersonRepo();
|
|
19901
20095
|
const { add: _add, updateById: _updateById } = usePersonService();
|
|
19902
20096
|
async function add(req, res, next) {
|
|
@@ -20131,6 +20325,53 @@ function usePersonController() {
|
|
|
20131
20325
|
return;
|
|
20132
20326
|
}
|
|
20133
20327
|
}
|
|
20328
|
+
async function getPeopleByNRIC(req, res, next) {
|
|
20329
|
+
const allowedFields = ["start", "end"];
|
|
20330
|
+
const allowedOrder = ["asc", "desc"];
|
|
20331
|
+
const validation = import_joi58.default.object({
|
|
20332
|
+
nric: import_joi58.default.string().optional().allow("", null),
|
|
20333
|
+
page: import_joi58.default.number().integer().min(1).allow("", null).default(1),
|
|
20334
|
+
limit: import_joi58.default.number().integer().min(1).max(100).allow("", null).default(10),
|
|
20335
|
+
sort: import_joi58.default.string().pattern(/^([a-zA-Z0-9_]+)(,[a-zA-Z0-9_]+)*$/).optional().allow("", ...allowedFields),
|
|
20336
|
+
order: import_joi58.default.string().pattern(/^(asc|desc)(,(asc|desc))*$/).optional().allow("", ...allowedOrder),
|
|
20337
|
+
site: import_joi58.default.string().hex().length(24).required()
|
|
20338
|
+
});
|
|
20339
|
+
const query = { ...req.query };
|
|
20340
|
+
const { error } = validation.validate(query);
|
|
20341
|
+
if (error) {
|
|
20342
|
+
import_node_server_utils104.logger.log({ level: "error", message: error.message });
|
|
20343
|
+
next(new import_node_server_utils104.BadRequestError(error.message));
|
|
20344
|
+
return;
|
|
20345
|
+
}
|
|
20346
|
+
const nric = req.query.nric ?? "";
|
|
20347
|
+
const page = parseInt(req.query.page ?? "1");
|
|
20348
|
+
const limit = parseInt(req.query.limit ?? "10");
|
|
20349
|
+
const site = req.query.site ?? "";
|
|
20350
|
+
const sortObj = {};
|
|
20351
|
+
const sortFields = String(req.query.sort).split(",");
|
|
20352
|
+
const sortOrders = String(req.query.order).split(",");
|
|
20353
|
+
sortFields.forEach((field, index) => {
|
|
20354
|
+
if (allowedFields.includes(field)) {
|
|
20355
|
+
const order = sortOrders[index] === "asc" ? 1 : -1;
|
|
20356
|
+
sortObj[field] = order;
|
|
20357
|
+
}
|
|
20358
|
+
});
|
|
20359
|
+
try {
|
|
20360
|
+
const data = await _getPeopleByNRIC({
|
|
20361
|
+
nric,
|
|
20362
|
+
page,
|
|
20363
|
+
limit,
|
|
20364
|
+
sort: sortObj,
|
|
20365
|
+
site
|
|
20366
|
+
});
|
|
20367
|
+
res.json(data);
|
|
20368
|
+
return;
|
|
20369
|
+
} catch (error2) {
|
|
20370
|
+
import_node_server_utils104.logger.log({ level: "error", message: error2.message });
|
|
20371
|
+
next(error2);
|
|
20372
|
+
return;
|
|
20373
|
+
}
|
|
20374
|
+
}
|
|
20134
20375
|
return {
|
|
20135
20376
|
add,
|
|
20136
20377
|
getAll,
|
|
@@ -20140,7 +20381,8 @@ function usePersonController() {
|
|
|
20140
20381
|
getPersonByPhoneNumber,
|
|
20141
20382
|
getPeopleByUnit,
|
|
20142
20383
|
getCompany,
|
|
20143
|
-
getPeopleByPlateNumber
|
|
20384
|
+
getPeopleByPlateNumber,
|
|
20385
|
+
getPeopleByNRIC
|
|
20144
20386
|
};
|
|
20145
20387
|
}
|
|
20146
20388
|
|
|
@@ -29267,7 +29509,8 @@ function UseAccessManagementRepo() {
|
|
|
29267
29509
|
const query = {
|
|
29268
29510
|
site: siteId,
|
|
29269
29511
|
assignedUnit: { $ne: null },
|
|
29270
|
-
type: "NFC" /* NFC
|
|
29512
|
+
type: "NFC" /* NFC */,
|
|
29513
|
+
isActivated: true
|
|
29271
29514
|
};
|
|
29272
29515
|
if (search) {
|
|
29273
29516
|
query.$or = [{ accessLevel: { $regex: search, $options: "i" } }, { cardNo: { $regex: search, $options: "i" } }];
|
|
@@ -29275,7 +29518,7 @@ function UseAccessManagementRepo() {
|
|
|
29275
29518
|
if (type) {
|
|
29276
29519
|
query.userType = type;
|
|
29277
29520
|
} else {
|
|
29278
|
-
query.userType = { $ne: "Resident
|
|
29521
|
+
query.userType = { $ne: "Visitor/Resident" /* DEFAULT */ };
|
|
29279
29522
|
}
|
|
29280
29523
|
const res = await collection().aggregate([
|
|
29281
29524
|
{
|
|
@@ -29649,6 +29892,52 @@ function UseAccessManagementRepo() {
|
|
|
29649
29892
|
throw new Error(error.message);
|
|
29650
29893
|
}
|
|
29651
29894
|
}
|
|
29895
|
+
async function addQrTagRepo(params) {
|
|
29896
|
+
try {
|
|
29897
|
+
const { site, payload } = params;
|
|
29898
|
+
const id = new import_mongodb83.ObjectId(site);
|
|
29899
|
+
const highestCardNo = await collection().aggregate([
|
|
29900
|
+
{ $match: { site: id, type: "NFC" /* NFC */, userType: "Visitor/Resident" /* DEFAULT */ } },
|
|
29901
|
+
{
|
|
29902
|
+
$addFields: {
|
|
29903
|
+
qrTagCardNoNumeric: { $toInt: "$qrTagCardNo" }
|
|
29904
|
+
// Convert string to integer
|
|
29905
|
+
}
|
|
29906
|
+
},
|
|
29907
|
+
{
|
|
29908
|
+
$sort: { qrTagCardNoNumeric: -1 }
|
|
29909
|
+
// Sort in descending order
|
|
29910
|
+
},
|
|
29911
|
+
{
|
|
29912
|
+
$limit: 1
|
|
29913
|
+
// Get the highest
|
|
29914
|
+
}
|
|
29915
|
+
]).toArray();
|
|
29916
|
+
let start = 0;
|
|
29917
|
+
if (highestCardNo.length > 0) {
|
|
29918
|
+
start = highestCardNo[0].qrTagCardNoNumeric || 0;
|
|
29919
|
+
}
|
|
29920
|
+
const nextCardNumbers = Array.from({ length: payload.length }, (_, i) => String(start + i + 1).padStart(5, "0"));
|
|
29921
|
+
const bulkOps = await Promise.all(
|
|
29922
|
+
payload.map(async (doc, index) => {
|
|
29923
|
+
const id2 = new import_mongodb83.ObjectId(doc._id);
|
|
29924
|
+
return {
|
|
29925
|
+
updateOne: {
|
|
29926
|
+
filter: { _id: id2 },
|
|
29927
|
+
update: { $set: { qrTag: doc.qrTag, qrTagCardNo: nextCardNumbers[index] } }
|
|
29928
|
+
}
|
|
29929
|
+
};
|
|
29930
|
+
})
|
|
29931
|
+
);
|
|
29932
|
+
let result;
|
|
29933
|
+
if (bulkOps.length > 0) {
|
|
29934
|
+
result = await collection().bulkWrite(bulkOps);
|
|
29935
|
+
}
|
|
29936
|
+
return result;
|
|
29937
|
+
} catch (error) {
|
|
29938
|
+
throw new Error(error.message);
|
|
29939
|
+
}
|
|
29940
|
+
}
|
|
29652
29941
|
return {
|
|
29653
29942
|
createIndexes,
|
|
29654
29943
|
createIndexForEntrypass,
|
|
@@ -29671,7 +29960,8 @@ function UseAccessManagementRepo() {
|
|
|
29671
29960
|
bulkPhysicalAccessCardRepo,
|
|
29672
29961
|
assignAccessCardToUnitRepo,
|
|
29673
29962
|
deleteCardRepo,
|
|
29674
|
-
getCardDetailsRepo
|
|
29963
|
+
getCardDetailsRepo,
|
|
29964
|
+
addQrTagRepo
|
|
29675
29965
|
};
|
|
29676
29966
|
}
|
|
29677
29967
|
|
|
@@ -29705,7 +29995,8 @@ function useAccessManagementSvc() {
|
|
|
29705
29995
|
bulkPhysicalAccessCardRepo,
|
|
29706
29996
|
assignAccessCardToUnitRepo,
|
|
29707
29997
|
deleteCardRepo,
|
|
29708
|
-
getCardDetailsRepo
|
|
29998
|
+
getCardDetailsRepo,
|
|
29999
|
+
addQrTagRepo
|
|
29709
30000
|
} = UseAccessManagementRepo();
|
|
29710
30001
|
const addPhysicalCardSvc = async (payload) => {
|
|
29711
30002
|
try {
|
|
@@ -29969,6 +30260,14 @@ function useAccessManagementSvc() {
|
|
|
29969
30260
|
throw new Error(err.message);
|
|
29970
30261
|
}
|
|
29971
30262
|
};
|
|
30263
|
+
const addQrTagSvc = async (params) => {
|
|
30264
|
+
try {
|
|
30265
|
+
const response = await addQrTagRepo({ ...params });
|
|
30266
|
+
return response;
|
|
30267
|
+
} catch (err) {
|
|
30268
|
+
throw new Error(err.message);
|
|
30269
|
+
}
|
|
30270
|
+
};
|
|
29972
30271
|
return {
|
|
29973
30272
|
addPhysicalCardSvc,
|
|
29974
30273
|
addNonPhysicalCardSvc,
|
|
@@ -29995,7 +30294,8 @@ function useAccessManagementSvc() {
|
|
|
29995
30294
|
bulkPhysicalAccessCardSvc,
|
|
29996
30295
|
assignAccessCardToUnitSvc,
|
|
29997
30296
|
deleteCardSvc,
|
|
29998
|
-
getCardDetailsSvc
|
|
30297
|
+
getCardDetailsSvc,
|
|
30298
|
+
addQrTagSvc
|
|
29999
30299
|
};
|
|
30000
30300
|
}
|
|
30001
30301
|
|
|
@@ -30029,7 +30329,8 @@ function useAccessManagementController() {
|
|
|
30029
30329
|
bulkPhysicalAccessCardSvc,
|
|
30030
30330
|
assignAccessCardToUnitSvc,
|
|
30031
30331
|
deleteCardSvc,
|
|
30032
|
-
getCardDetailsSvc
|
|
30332
|
+
getCardDetailsSvc,
|
|
30333
|
+
addQrTagSvc
|
|
30033
30334
|
} = useAccessManagementSvc();
|
|
30034
30335
|
const addPhysicalCard = async (req, res) => {
|
|
30035
30336
|
try {
|
|
@@ -30640,6 +30941,34 @@ function useAccessManagementController() {
|
|
|
30640
30941
|
});
|
|
30641
30942
|
}
|
|
30642
30943
|
};
|
|
30944
|
+
const addQrTag = async (req, res) => {
|
|
30945
|
+
try {
|
|
30946
|
+
const payload = req.body;
|
|
30947
|
+
const site = req.params.site;
|
|
30948
|
+
const schema2 = import_joi85.default.object({
|
|
30949
|
+
site: import_joi85.default.string().hex().required(),
|
|
30950
|
+
payload: import_joi85.default.array().items(
|
|
30951
|
+
import_joi85.default.object({
|
|
30952
|
+
_id: import_joi85.default.string().hex().required(),
|
|
30953
|
+
cardNo: import_joi85.default.string().required(),
|
|
30954
|
+
qrTag: import_joi85.default.string().required(),
|
|
30955
|
+
qrTagCardNo: import_joi85.default.string().required()
|
|
30956
|
+
})
|
|
30957
|
+
).required()
|
|
30958
|
+
});
|
|
30959
|
+
const { error } = schema2.validate({ site, payload });
|
|
30960
|
+
if (error) {
|
|
30961
|
+
return res.status(400).json({ message: error.message });
|
|
30962
|
+
}
|
|
30963
|
+
const result = await addQrTagSvc({ payload, site });
|
|
30964
|
+
return res.status(200).json({ message: "Success", data: result });
|
|
30965
|
+
} catch (error) {
|
|
30966
|
+
return res.status(500).json({
|
|
30967
|
+
data: null,
|
|
30968
|
+
message: error.message
|
|
30969
|
+
});
|
|
30970
|
+
}
|
|
30971
|
+
};
|
|
30643
30972
|
return {
|
|
30644
30973
|
addPhysicalCard,
|
|
30645
30974
|
addNonPhysicalCard,
|
|
@@ -30663,7 +30992,8 @@ function useAccessManagementController() {
|
|
|
30663
30992
|
bulkPhysicalAccessCard,
|
|
30664
30993
|
assignAccessCardToUnit,
|
|
30665
30994
|
deleteCard,
|
|
30666
|
-
getCardDetails
|
|
30995
|
+
getCardDetails,
|
|
30996
|
+
addQrTag
|
|
30667
30997
|
};
|
|
30668
30998
|
}
|
|
30669
30999
|
|