@7365admin1/core 2.65.0 → 2.67.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 +204 -37
- package/dist/index.js +2248 -674
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2247 -674
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -125,7 +125,15 @@ var userSchema = Joi2.object({
|
|
|
125
125
|
email: Joi2.string().email().required(),
|
|
126
126
|
password: Joi2.string().min(8).required(),
|
|
127
127
|
name: Joi2.string().required(),
|
|
128
|
-
defaultOrg: Joi2.string().hex().optional().allow("", null)
|
|
128
|
+
defaultOrg: Joi2.string().hex().optional().allow("", null),
|
|
129
|
+
status: Joi2.string().optional().allow("", null),
|
|
130
|
+
block: Joi2.number().optional().allow(null),
|
|
131
|
+
level: Joi2.string().optional().allow("", null),
|
|
132
|
+
type: Joi2.string().optional().allow("", null),
|
|
133
|
+
unitName: Joi2.string().optional().allow("", null),
|
|
134
|
+
contact: Joi2.string().optional().allow("", null),
|
|
135
|
+
site: Joi2.string().hex().optional().allow("", null),
|
|
136
|
+
unitId: Joi2.string().hex().optional().allow("", null)
|
|
129
137
|
});
|
|
130
138
|
function MUser(value) {
|
|
131
139
|
const { error } = userSchema.validate(value);
|
|
@@ -139,12 +147,33 @@ function MUser(value) {
|
|
|
139
147
|
throw new BadRequestError2("Invalid default org ID format.");
|
|
140
148
|
}
|
|
141
149
|
}
|
|
150
|
+
if (value.site && typeof value.site === "string") {
|
|
151
|
+
try {
|
|
152
|
+
value.site = new ObjectId(value.site);
|
|
153
|
+
} catch {
|
|
154
|
+
throw new BadRequestError2("Invalid site ID format.");
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (value.unitId && typeof value.unitId === "string") {
|
|
158
|
+
try {
|
|
159
|
+
value.unitId = new ObjectId(value.unitId);
|
|
160
|
+
} catch {
|
|
161
|
+
throw new BadRequestError2("Invalid unit ID format.");
|
|
162
|
+
}
|
|
163
|
+
}
|
|
142
164
|
return {
|
|
143
165
|
email: value.email,
|
|
144
166
|
password: value.password,
|
|
145
167
|
name: value.name ?? "",
|
|
146
168
|
defaultOrg: value.defaultOrg ?? "",
|
|
147
|
-
status: "active" /* ACTIVE */,
|
|
169
|
+
status: value.status ?? "active" /* ACTIVE */,
|
|
170
|
+
block: value.block ?? null,
|
|
171
|
+
level: value.level ?? "",
|
|
172
|
+
type: value.type ?? "",
|
|
173
|
+
unitName: value.unitName ?? "",
|
|
174
|
+
contact: value.contact ?? "",
|
|
175
|
+
site: value.site ?? "",
|
|
176
|
+
unitId: value.unitId ?? "",
|
|
148
177
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
149
178
|
updatedAt: value.updatedAt ?? "",
|
|
150
179
|
deletedAt: value.deletedAt ?? ""
|
|
@@ -4182,7 +4211,7 @@ function useOrgRepo() {
|
|
|
4182
4211
|
}
|
|
4183
4212
|
async function createUniqueIndex() {
|
|
4184
4213
|
try {
|
|
4185
|
-
await collection.createIndex({ email: 1 }
|
|
4214
|
+
await collection.createIndex({ email: 1 });
|
|
4186
4215
|
} catch (error) {
|
|
4187
4216
|
throw new InternalServerError9("Failed to create unique index on name.");
|
|
4188
4217
|
}
|
|
@@ -4372,6 +4401,29 @@ function useOrgRepo() {
|
|
|
4372
4401
|
throw error;
|
|
4373
4402
|
}
|
|
4374
4403
|
}
|
|
4404
|
+
async function getOrgsByEmail(email) {
|
|
4405
|
+
const cacheKey = makeCacheKey8(namespace_collection, {
|
|
4406
|
+
email
|
|
4407
|
+
});
|
|
4408
|
+
const cachedData = await getCache(cacheKey);
|
|
4409
|
+
if (cachedData) {
|
|
4410
|
+
logger10.info(`Cache hit for key: ${cacheKey}`);
|
|
4411
|
+
return cachedData;
|
|
4412
|
+
}
|
|
4413
|
+
try {
|
|
4414
|
+
const data = await collection.find({
|
|
4415
|
+
email
|
|
4416
|
+
}).toArray();
|
|
4417
|
+
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
4418
|
+
logger10.info(`Cache set for key: ${cacheKey}`);
|
|
4419
|
+
}).catch((err) => {
|
|
4420
|
+
logger10.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
4421
|
+
});
|
|
4422
|
+
return data;
|
|
4423
|
+
} catch (error) {
|
|
4424
|
+
throw error;
|
|
4425
|
+
}
|
|
4426
|
+
}
|
|
4375
4427
|
async function updateFieldById({
|
|
4376
4428
|
_id,
|
|
4377
4429
|
field,
|
|
@@ -4474,7 +4526,8 @@ function useOrgRepo() {
|
|
|
4474
4526
|
getByEmail,
|
|
4475
4527
|
updateFieldById,
|
|
4476
4528
|
updateStatusById,
|
|
4477
|
-
deleteById
|
|
4529
|
+
deleteById,
|
|
4530
|
+
getOrgsByEmail
|
|
4478
4531
|
};
|
|
4479
4532
|
}
|
|
4480
4533
|
|
|
@@ -5497,7 +5550,6 @@ function useVerificationService() {
|
|
|
5497
5550
|
await getSiteById(metadata.siteId);
|
|
5498
5551
|
}
|
|
5499
5552
|
const verificationIds = [];
|
|
5500
|
-
const invitedApps = [];
|
|
5501
5553
|
for (const app of apps) {
|
|
5502
5554
|
await useVerificationRepo().findOne({
|
|
5503
5555
|
type,
|
|
@@ -5520,34 +5572,32 @@ function useVerificationService() {
|
|
|
5520
5572
|
};
|
|
5521
5573
|
const createdId = await add(value);
|
|
5522
5574
|
verificationIds.push(createdId.toString());
|
|
5523
|
-
|
|
5575
|
+
const link = `${APP_MAIN}/verify/invitation/${createdId}`;
|
|
5576
|
+
const emailContent = compileHandlebar({
|
|
5577
|
+
context: {
|
|
5578
|
+
email,
|
|
5579
|
+
validity: VERIFICATION_USER_INVITE_DURATION,
|
|
5580
|
+
link,
|
|
5581
|
+
hasPropertyManagement: app === "property_management_agency",
|
|
5582
|
+
hasSecurity: app === "security_agency",
|
|
5583
|
+
hasCleaning: app === "cleaning_services",
|
|
5584
|
+
hasMechanical: app === "mechanical_electrical_services",
|
|
5585
|
+
hasLandscape: app === "landscaping_services",
|
|
5586
|
+
hasPestControl: app === "pest_control_services",
|
|
5587
|
+
hasPoolMaintenance: app === "pool_maintenance_services"
|
|
5588
|
+
},
|
|
5589
|
+
filePath: getDirectory(
|
|
5590
|
+
__dirname,
|
|
5591
|
+
"./public/handlebars/user-invite"
|
|
5592
|
+
)
|
|
5593
|
+
});
|
|
5594
|
+
await mailer.sendMail({
|
|
5595
|
+
to: email,
|
|
5596
|
+
subject: "User Invite",
|
|
5597
|
+
html: emailContent,
|
|
5598
|
+
sender: "iService365"
|
|
5599
|
+
});
|
|
5524
5600
|
}
|
|
5525
|
-
const link = `${APP_MAIN}/verify/invitation/${verificationIds[0]}`;
|
|
5526
|
-
const appsSet = new Set(invitedApps);
|
|
5527
|
-
const emailContent = compileHandlebar({
|
|
5528
|
-
context: {
|
|
5529
|
-
email,
|
|
5530
|
-
validity: VERIFICATION_USER_INVITE_DURATION,
|
|
5531
|
-
link,
|
|
5532
|
-
hasPropertyManagement: appsSet.has("property_management_agency"),
|
|
5533
|
-
hasSecurity: appsSet.has("security_agency"),
|
|
5534
|
-
hasCleaning: appsSet.has("cleaning_services"),
|
|
5535
|
-
hasMechanical: appsSet.has("mechanical_electrical_services"),
|
|
5536
|
-
hasLandscape: appsSet.has("landscaping_services"),
|
|
5537
|
-
hasPestControl: appsSet.has("pest_control_services"),
|
|
5538
|
-
hasPoolMaintenance: appsSet.has("pool_maintenance_services")
|
|
5539
|
-
},
|
|
5540
|
-
filePath: getDirectory(
|
|
5541
|
-
__dirname,
|
|
5542
|
-
"./public/handlebars/user-invite"
|
|
5543
|
-
)
|
|
5544
|
-
});
|
|
5545
|
-
await mailer.sendMail({
|
|
5546
|
-
to: email,
|
|
5547
|
-
subject: "User Invite",
|
|
5548
|
-
html: emailContent,
|
|
5549
|
-
sender: "iService365"
|
|
5550
|
-
});
|
|
5551
5601
|
return verificationIds;
|
|
5552
5602
|
}
|
|
5553
5603
|
async function createSimpleMemberInvite({
|
|
@@ -8042,7 +8092,7 @@ function useVerificationController() {
|
|
|
8042
8092
|
siteId: Joi16.string().hex().optional().allow("", null),
|
|
8043
8093
|
siteName: Joi16.string().optional().allow("", null)
|
|
8044
8094
|
});
|
|
8045
|
-
const { error } = validation.validate(payload);
|
|
8095
|
+
const { error, value } = validation.validate(payload);
|
|
8046
8096
|
if (error) {
|
|
8047
8097
|
logger22.log({
|
|
8048
8098
|
level: "error",
|
|
@@ -8051,15 +8101,17 @@ function useVerificationController() {
|
|
|
8051
8101
|
next(new BadRequestError31(error.message));
|
|
8052
8102
|
return;
|
|
8053
8103
|
}
|
|
8054
|
-
const email = req.body.email ?? "";
|
|
8055
|
-
const app = req.body.app ?? [];
|
|
8056
|
-
const role = req.body.role ?? "";
|
|
8057
|
-
const name = req.body.name ?? "";
|
|
8058
|
-
const org = req.body.org ?? "";
|
|
8059
|
-
const siteId = req.body.siteId ?? "";
|
|
8060
|
-
const siteName = req.body.siteName ?? "";
|
|
8061
8104
|
try {
|
|
8062
|
-
|
|
8105
|
+
const {
|
|
8106
|
+
email,
|
|
8107
|
+
app,
|
|
8108
|
+
role,
|
|
8109
|
+
name,
|
|
8110
|
+
org,
|
|
8111
|
+
siteId,
|
|
8112
|
+
siteName
|
|
8113
|
+
} = value;
|
|
8114
|
+
const verificationIds = await _createSimpleUserInvite({
|
|
8063
8115
|
email,
|
|
8064
8116
|
metadata: {
|
|
8065
8117
|
app,
|
|
@@ -8071,7 +8123,9 @@ function useVerificationController() {
|
|
|
8071
8123
|
}
|
|
8072
8124
|
});
|
|
8073
8125
|
res.status(201).json({
|
|
8074
|
-
message: "Successfully invited user."
|
|
8126
|
+
message: "Successfully invited user.",
|
|
8127
|
+
totalInvites: verificationIds.length,
|
|
8128
|
+
verificationIds
|
|
8075
8129
|
});
|
|
8076
8130
|
return;
|
|
8077
8131
|
} catch (error2) {
|
|
@@ -8531,7 +8585,8 @@ function useOrgController() {
|
|
|
8531
8585
|
getByEmail: _getByEmail,
|
|
8532
8586
|
getAll: _getAll,
|
|
8533
8587
|
add: _add,
|
|
8534
|
-
update: _update
|
|
8588
|
+
update: _update,
|
|
8589
|
+
getOrgsByEmail: _getOrgsByEmail
|
|
8535
8590
|
} = useOrgRepo();
|
|
8536
8591
|
async function add(req, res, next) {
|
|
8537
8592
|
const validation = Joi18.object({
|
|
@@ -8715,6 +8770,30 @@ function useOrgController() {
|
|
|
8715
8770
|
return;
|
|
8716
8771
|
}
|
|
8717
8772
|
}
|
|
8773
|
+
async function getOrgsByEmail(req, res, next) {
|
|
8774
|
+
const validation = Joi18.object({
|
|
8775
|
+
email: Joi18.string().email().required()
|
|
8776
|
+
});
|
|
8777
|
+
const query = {
|
|
8778
|
+
email: req.params.email
|
|
8779
|
+
};
|
|
8780
|
+
const { error } = validation.validate(query);
|
|
8781
|
+
if (error) {
|
|
8782
|
+
logger25.log({ level: "error", message: error.message });
|
|
8783
|
+
next(new BadRequestError33(error.message));
|
|
8784
|
+
return;
|
|
8785
|
+
}
|
|
8786
|
+
const email = req.params.email;
|
|
8787
|
+
try {
|
|
8788
|
+
const data = await _getOrgsByEmail(email);
|
|
8789
|
+
res.json(data);
|
|
8790
|
+
return;
|
|
8791
|
+
} catch (error2) {
|
|
8792
|
+
logger25.log({ level: "error", message: error2.message });
|
|
8793
|
+
next(error2);
|
|
8794
|
+
return;
|
|
8795
|
+
}
|
|
8796
|
+
}
|
|
8718
8797
|
async function update(req, res, next) {
|
|
8719
8798
|
const validation = Joi18.object({
|
|
8720
8799
|
name: Joi18.string().optional(),
|
|
@@ -8748,7 +8827,8 @@ function useOrgController() {
|
|
|
8748
8827
|
getByName,
|
|
8749
8828
|
getById,
|
|
8750
8829
|
getByEmail,
|
|
8751
|
-
update
|
|
8830
|
+
update,
|
|
8831
|
+
getOrgsByEmail
|
|
8752
8832
|
};
|
|
8753
8833
|
}
|
|
8754
8834
|
|
|
@@ -26552,7 +26632,14 @@ function usePersonService() {
|
|
|
26552
26632
|
password: hashedPassword,
|
|
26553
26633
|
name: value.name,
|
|
26554
26634
|
status: value.platform == "mobile" ? "pending" : "active",
|
|
26555
|
-
defaultOrg: value.org?.toString() || ""
|
|
26635
|
+
defaultOrg: value.org?.toString() || "",
|
|
26636
|
+
block: value.block,
|
|
26637
|
+
level: value.level,
|
|
26638
|
+
type: value.type,
|
|
26639
|
+
unitName: value.unitName,
|
|
26640
|
+
contact: value.contact,
|
|
26641
|
+
site: value.site?.toString() || "",
|
|
26642
|
+
unitId: value.unit?.toString() || ""
|
|
26556
26643
|
};
|
|
26557
26644
|
const userId = await addUser(user, session);
|
|
26558
26645
|
value.user = userId.toString();
|
|
@@ -31283,26 +31370,31 @@ var schemaDocumentManagement = Joi74.object({
|
|
|
31283
31370
|
_id: Joi74.string().hex().optional().allow("", null),
|
|
31284
31371
|
name: Joi74.string().required(),
|
|
31285
31372
|
type: Joi74.string().optional().allow("", null),
|
|
31286
|
-
attachment: Joi74.string().
|
|
31287
|
-
|
|
31288
|
-
|
|
31373
|
+
attachment: Joi74.when("isFolder", { is: true, then: Joi74.forbidden(), otherwise: Joi74.string().optional().allow("", null) }),
|
|
31374
|
+
remarks: Joi74.string().optional().allow("", null),
|
|
31375
|
+
isFolder: Joi74.boolean().optional().default(false),
|
|
31289
31376
|
org: Joi74.string().hex().optional().allow("", null),
|
|
31290
31377
|
site: Joi74.string().hex().optional().allow("", null),
|
|
31378
|
+
parentId: Joi74.string().hex().optional().allow("", null),
|
|
31379
|
+
createdBy: Joi74.string().hex().required(),
|
|
31291
31380
|
updatedBy: Joi74.string().hex().optional().allow("", null),
|
|
31292
31381
|
createdAt: Joi74.date().optional().allow("", null),
|
|
31293
|
-
updatedAt: Joi74.date().optional().allow("", null)
|
|
31382
|
+
updatedAt: Joi74.date().optional().allow("", null),
|
|
31383
|
+
status: Joi74.string().optional().allow("", null).default("active")
|
|
31294
31384
|
});
|
|
31295
31385
|
var schemaUpdateDocumentManagement = Joi74.object({
|
|
31296
31386
|
_id: Joi74.string().hex().required(),
|
|
31297
31387
|
name: Joi74.string().optional().allow("", null),
|
|
31298
31388
|
type: Joi74.string().optional().allow("", null),
|
|
31299
|
-
attachment: Joi74.string().optional(),
|
|
31300
|
-
|
|
31389
|
+
attachment: Joi74.when("isFolder", { is: true, then: Joi74.forbidden(), otherwise: Joi74.string().optional().allow("", null) }),
|
|
31390
|
+
remarks: Joi74.string().optional().allow("", null),
|
|
31391
|
+
isFolder: Joi74.boolean().optional(),
|
|
31301
31392
|
org: Joi74.string().hex().optional().allow("", null),
|
|
31302
31393
|
site: Joi74.string().hex().optional().allow("", null),
|
|
31394
|
+
parentId: Joi74.string().hex().optional().allow("", null),
|
|
31303
31395
|
updatedBy: Joi74.string().hex().optional().allow("", null),
|
|
31304
|
-
|
|
31305
|
-
|
|
31396
|
+
updatedAt: Joi74.date().optional().allow("", null),
|
|
31397
|
+
status: Joi74.string().optional().allow("", null)
|
|
31306
31398
|
});
|
|
31307
31399
|
function MDocumentManagement(value) {
|
|
31308
31400
|
const { error } = schemaDocumentManagement.validate(value);
|
|
@@ -31330,18 +31422,31 @@ function MDocumentManagement(value) {
|
|
|
31330
31422
|
throw new Error("Invalid site ID.");
|
|
31331
31423
|
}
|
|
31332
31424
|
}
|
|
31425
|
+
if (value.parentId && typeof value.parentId === "string") {
|
|
31426
|
+
try {
|
|
31427
|
+
value.parentId = new ObjectId76(value.parentId);
|
|
31428
|
+
} catch (error2) {
|
|
31429
|
+
throw new Error("Invalid parentId.");
|
|
31430
|
+
}
|
|
31431
|
+
}
|
|
31432
|
+
if (value.isFolder) {
|
|
31433
|
+
value.attachment = void 0;
|
|
31434
|
+
}
|
|
31333
31435
|
return {
|
|
31334
31436
|
_id: value._id,
|
|
31335
31437
|
name: value.name,
|
|
31336
31438
|
type: value.type,
|
|
31337
31439
|
attachment: value.attachment,
|
|
31338
|
-
|
|
31440
|
+
remarks: value.remarks ?? "",
|
|
31441
|
+
isFolder: value.isFolder ?? false,
|
|
31339
31442
|
org: value.org,
|
|
31340
31443
|
site: value.site,
|
|
31444
|
+
...value.parentId ? { parentId: value.parentId } : {},
|
|
31341
31445
|
createdBy: value.createdBy,
|
|
31342
31446
|
updatedBy: value.updatedBy,
|
|
31343
31447
|
createdAt: value.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
31344
|
-
updatedAt: value.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
31448
|
+
updatedAt: value.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
31449
|
+
status: value.status ?? "active"
|
|
31345
31450
|
};
|
|
31346
31451
|
}
|
|
31347
31452
|
|
|
@@ -31365,11 +31470,22 @@ function useDocumentManagementRepo() {
|
|
|
31365
31470
|
const namespace_collection = "documents";
|
|
31366
31471
|
const collection = db.collection(namespace_collection);
|
|
31367
31472
|
const { delNamespace, getCache, setCache } = useCache40(namespace_collection);
|
|
31473
|
+
async function createIndex() {
|
|
31474
|
+
try {
|
|
31475
|
+
await collection.createIndexes([
|
|
31476
|
+
{ key: { site: 1 } },
|
|
31477
|
+
{ key: { isFolder: 1 } },
|
|
31478
|
+
{ key: { parentId: 1 } }
|
|
31479
|
+
]);
|
|
31480
|
+
} catch (error) {
|
|
31481
|
+
throw new InternalServerError41("Failed to create index on document.");
|
|
31482
|
+
}
|
|
31483
|
+
}
|
|
31368
31484
|
async function createTextIndex() {
|
|
31369
31485
|
try {
|
|
31370
31486
|
await collection.createIndex({
|
|
31371
31487
|
name: "text",
|
|
31372
|
-
|
|
31488
|
+
remarks: "text"
|
|
31373
31489
|
});
|
|
31374
31490
|
} catch (error) {
|
|
31375
31491
|
throw new InternalServerError41("Failed to create text index on document.");
|
|
@@ -31403,7 +31519,8 @@ function useDocumentManagementRepo() {
|
|
|
31403
31519
|
sort = {},
|
|
31404
31520
|
status = "active",
|
|
31405
31521
|
org = "",
|
|
31406
|
-
site = ""
|
|
31522
|
+
site = "",
|
|
31523
|
+
parentId = ""
|
|
31407
31524
|
}) {
|
|
31408
31525
|
page = page > 0 ? page - 1 : 0;
|
|
31409
31526
|
try {
|
|
@@ -31422,14 +31539,24 @@ function useDocumentManagementRepo() {
|
|
|
31422
31539
|
const query = {
|
|
31423
31540
|
...status ? { $and: [{ status }, { status: { $ne: "deleted" } }] } : { status: { $ne: "deleted" } }
|
|
31424
31541
|
};
|
|
31425
|
-
if (
|
|
31426
|
-
query.
|
|
31427
|
-
cacheOptions.
|
|
31542
|
+
if (org) {
|
|
31543
|
+
query.org = new ObjectId77(org);
|
|
31544
|
+
cacheOptions.org = org.toString();
|
|
31545
|
+
}
|
|
31546
|
+
if (parentId) {
|
|
31547
|
+
try {
|
|
31548
|
+
query.parentId = new ObjectId77(parentId);
|
|
31549
|
+
cacheOptions.parentId = parentId.toString();
|
|
31550
|
+
} catch (error) {
|
|
31551
|
+
throw new BadRequestError124("Invalid parentId format.");
|
|
31552
|
+
}
|
|
31553
|
+
} else {
|
|
31554
|
+
query.parentId = { $in: [null, ""] };
|
|
31428
31555
|
}
|
|
31429
31556
|
if (search) {
|
|
31430
31557
|
query.$or = [
|
|
31431
31558
|
{ name: { $regex: search, $options: "i" } },
|
|
31432
|
-
{
|
|
31559
|
+
{ remarks: { $regex: search, $options: "i" } }
|
|
31433
31560
|
];
|
|
31434
31561
|
cacheOptions.search = search;
|
|
31435
31562
|
}
|
|
@@ -31451,6 +31578,9 @@ function useDocumentManagementRepo() {
|
|
|
31451
31578
|
type: 1,
|
|
31452
31579
|
status: 1,
|
|
31453
31580
|
attachment: 1,
|
|
31581
|
+
parentId: 1,
|
|
31582
|
+
isFolder: 1,
|
|
31583
|
+
remarks: 1,
|
|
31454
31584
|
createdAt: 1,
|
|
31455
31585
|
updatedAt: 1
|
|
31456
31586
|
}
|
|
@@ -31622,6 +31752,7 @@ function useDocumentManagementRepo() {
|
|
|
31622
31752
|
}
|
|
31623
31753
|
}
|
|
31624
31754
|
return {
|
|
31755
|
+
createIndex,
|
|
31625
31756
|
createTextIndex,
|
|
31626
31757
|
add,
|
|
31627
31758
|
getAll,
|
|
@@ -31639,7 +31770,7 @@ import {
|
|
|
31639
31770
|
NotFoundError as NotFoundError29
|
|
31640
31771
|
} from "@7365admin1/node-server-utils";
|
|
31641
31772
|
function useDocumentManagementService() {
|
|
31642
|
-
const { add: _add
|
|
31773
|
+
const { add: _add } = useDocumentManagementRepo();
|
|
31643
31774
|
const { updateStatusById } = useFileRepo();
|
|
31644
31775
|
async function createDocument(value) {
|
|
31645
31776
|
const session = useAtlas65.getClient()?.startSession();
|
|
@@ -31669,32 +31800,8 @@ function useDocumentManagementService() {
|
|
|
31669
31800
|
session?.endSession();
|
|
31670
31801
|
}
|
|
31671
31802
|
}
|
|
31672
|
-
async function getDocuments({
|
|
31673
|
-
search,
|
|
31674
|
-
page,
|
|
31675
|
-
limit,
|
|
31676
|
-
sort,
|
|
31677
|
-
status,
|
|
31678
|
-
org,
|
|
31679
|
-
site
|
|
31680
|
-
}) {
|
|
31681
|
-
try {
|
|
31682
|
-
return await _getAll({
|
|
31683
|
-
search,
|
|
31684
|
-
page,
|
|
31685
|
-
limit,
|
|
31686
|
-
sort,
|
|
31687
|
-
status,
|
|
31688
|
-
org,
|
|
31689
|
-
site
|
|
31690
|
-
});
|
|
31691
|
-
} catch (error) {
|
|
31692
|
-
throw error;
|
|
31693
|
-
}
|
|
31694
|
-
}
|
|
31695
31803
|
return {
|
|
31696
|
-
createDocument
|
|
31697
|
-
getDocuments
|
|
31804
|
+
createDocument
|
|
31698
31805
|
};
|
|
31699
31806
|
}
|
|
31700
31807
|
|
|
@@ -31702,8 +31809,9 @@ function useDocumentManagementService() {
|
|
|
31702
31809
|
import { BadRequestError as BadRequestError126, logger as logger104 } from "@7365admin1/node-server-utils";
|
|
31703
31810
|
import Joi75 from "joi";
|
|
31704
31811
|
function useDocumentManagementController() {
|
|
31705
|
-
const { createDocument: _add
|
|
31812
|
+
const { createDocument: _add } = useDocumentManagementService();
|
|
31706
31813
|
const {
|
|
31814
|
+
getAll: _getDocuments,
|
|
31707
31815
|
getDocumentById: _getDocumentById,
|
|
31708
31816
|
updateDocumentById: _updateDocumentById,
|
|
31709
31817
|
deleteDocumentById: _deleteDocumentById,
|
|
@@ -31721,8 +31829,12 @@ function useDocumentManagementController() {
|
|
|
31721
31829
|
createdBy = req.body.createdBy;
|
|
31722
31830
|
}
|
|
31723
31831
|
const payload = { ...req.body, createdBy };
|
|
31724
|
-
if (payload.
|
|
31832
|
+
if (payload.isFolder) {
|
|
31833
|
+
delete payload.attachment;
|
|
31834
|
+
} else if (Array.isArray(payload.attachment)) {
|
|
31725
31835
|
payload.attachment = payload.attachment[0];
|
|
31836
|
+
} else if (!payload.attachment) {
|
|
31837
|
+
payload.attachment = "";
|
|
31726
31838
|
}
|
|
31727
31839
|
const { error } = schemaDocumentManagement.validate(payload, {
|
|
31728
31840
|
abortEarly: false
|
|
@@ -31750,7 +31862,8 @@ function useDocumentManagementController() {
|
|
|
31750
31862
|
limit: Joi75.number().integer().min(1).max(100).allow("", null).default(10),
|
|
31751
31863
|
status: Joi75.string().required(),
|
|
31752
31864
|
org: Joi75.string().hex().optional().allow("", null),
|
|
31753
|
-
site: Joi75.string().hex().optional().allow("", null)
|
|
31865
|
+
site: Joi75.string().hex().optional().allow("", null),
|
|
31866
|
+
parentId: Joi75.string().hex().optional().allow("", null)
|
|
31754
31867
|
});
|
|
31755
31868
|
const query = { ...req.query };
|
|
31756
31869
|
query.status = req.query.status;
|
|
@@ -31766,6 +31879,7 @@ function useDocumentManagementController() {
|
|
|
31766
31879
|
const status = req.query.status ?? "active";
|
|
31767
31880
|
const org = req.query.org ?? "";
|
|
31768
31881
|
const site = req.query.site ?? "";
|
|
31882
|
+
const parentId = req.query.parentId ?? "";
|
|
31769
31883
|
try {
|
|
31770
31884
|
const data = await _getDocuments({
|
|
31771
31885
|
search,
|
|
@@ -31773,7 +31887,8 @@ function useDocumentManagementController() {
|
|
|
31773
31887
|
limit,
|
|
31774
31888
|
status,
|
|
31775
31889
|
org,
|
|
31776
|
-
site
|
|
31890
|
+
site,
|
|
31891
|
+
parentId
|
|
31777
31892
|
});
|
|
31778
31893
|
res.json(data);
|
|
31779
31894
|
return;
|
|
@@ -31829,8 +31944,12 @@ function useDocumentManagementController() {
|
|
|
31829
31944
|
}
|
|
31830
31945
|
const _id = req.params.id;
|
|
31831
31946
|
const payload = { ...req.body, updatedBy };
|
|
31832
|
-
if (payload.
|
|
31947
|
+
if (payload.isFolder) {
|
|
31948
|
+
delete payload.attachment;
|
|
31949
|
+
} else if (Array.isArray(payload.attachment)) {
|
|
31833
31950
|
payload.attachment = payload.attachment[0];
|
|
31951
|
+
} else if (!payload.attachment) {
|
|
31952
|
+
payload.attachment = "";
|
|
31834
31953
|
}
|
|
31835
31954
|
const { error } = validation.validate({ _id, ...payload });
|
|
31836
31955
|
if (error) {
|
|
@@ -36340,10 +36459,42 @@ function UseAccessManagementRepo() {
|
|
|
36340
36459
|
},
|
|
36341
36460
|
{
|
|
36342
36461
|
$facet: {
|
|
36343
|
-
available_physical: [
|
|
36344
|
-
|
|
36345
|
-
|
|
36346
|
-
|
|
36462
|
+
available_physical: [
|
|
36463
|
+
{
|
|
36464
|
+
$match: {
|
|
36465
|
+
assignedUnit: { $eq: null },
|
|
36466
|
+
type: "NFC" /* NFC */
|
|
36467
|
+
}
|
|
36468
|
+
},
|
|
36469
|
+
{ $count: "count" }
|
|
36470
|
+
],
|
|
36471
|
+
available_non_physical: [
|
|
36472
|
+
{
|
|
36473
|
+
$match: {
|
|
36474
|
+
assignedUnit: { $eq: null },
|
|
36475
|
+
type: "QRCODE" /* QR */
|
|
36476
|
+
}
|
|
36477
|
+
},
|
|
36478
|
+
{ $count: "count" }
|
|
36479
|
+
],
|
|
36480
|
+
assigned_physical: [
|
|
36481
|
+
{
|
|
36482
|
+
$match: {
|
|
36483
|
+
assignedUnit: { $ne: null },
|
|
36484
|
+
type: "NFC" /* NFC */
|
|
36485
|
+
}
|
|
36486
|
+
},
|
|
36487
|
+
{ $count: "count" }
|
|
36488
|
+
],
|
|
36489
|
+
assigned_non_physical: [
|
|
36490
|
+
{
|
|
36491
|
+
$match: {
|
|
36492
|
+
assignedUnit: { $ne: null },
|
|
36493
|
+
type: "QRCODE" /* QR */
|
|
36494
|
+
}
|
|
36495
|
+
},
|
|
36496
|
+
{ $count: "count" }
|
|
36497
|
+
]
|
|
36347
36498
|
}
|
|
36348
36499
|
}
|
|
36349
36500
|
]).toArray();
|
|
@@ -36428,16 +36579,35 @@ function UseAccessManagementRepo() {
|
|
|
36428
36579
|
case terms.length >= 3:
|
|
36429
36580
|
return {
|
|
36430
36581
|
$and: [
|
|
36431
|
-
{
|
|
36432
|
-
|
|
36433
|
-
|
|
36582
|
+
{
|
|
36583
|
+
$expr: { $eq: [{ $toLower: "$name" }, terms[0].toLowerCase()] }
|
|
36584
|
+
},
|
|
36585
|
+
{
|
|
36586
|
+
$expr: {
|
|
36587
|
+
$eq: [{ $toLower: "$level.level" }, terms[1].toLowerCase()]
|
|
36588
|
+
}
|
|
36589
|
+
},
|
|
36590
|
+
{
|
|
36591
|
+
$expr: {
|
|
36592
|
+
$eq: [
|
|
36593
|
+
{ $toLower: "$level.units.name" },
|
|
36594
|
+
getAfterSecondSlash(search)
|
|
36595
|
+
]
|
|
36596
|
+
}
|
|
36597
|
+
}
|
|
36434
36598
|
]
|
|
36435
36599
|
};
|
|
36436
36600
|
case terms.length === 2:
|
|
36437
36601
|
return {
|
|
36438
36602
|
$and: [
|
|
36439
|
-
{
|
|
36440
|
-
|
|
36603
|
+
{
|
|
36604
|
+
$expr: { $eq: [{ $toLower: "$name" }, terms[0].toLowerCase()] }
|
|
36605
|
+
},
|
|
36606
|
+
{
|
|
36607
|
+
$expr: {
|
|
36608
|
+
$eq: [{ $toLower: "$level.level" }, terms[1].toLowerCase()]
|
|
36609
|
+
}
|
|
36610
|
+
}
|
|
36441
36611
|
]
|
|
36442
36612
|
};
|
|
36443
36613
|
default:
|
|
@@ -36465,220 +36635,386 @@ function UseAccessManagementRepo() {
|
|
|
36465
36635
|
site
|
|
36466
36636
|
};
|
|
36467
36637
|
const searchQuery = buildSearchQuery(search);
|
|
36468
|
-
const result = await collectionName("buildings").aggregate(
|
|
36469
|
-
|
|
36470
|
-
|
|
36471
|
-
|
|
36472
|
-
|
|
36473
|
-
|
|
36474
|
-
|
|
36475
|
-
|
|
36476
|
-
|
|
36477
|
-
|
|
36478
|
-
|
|
36479
|
-
|
|
36480
|
-
|
|
36481
|
-
|
|
36482
|
-
|
|
36483
|
-
|
|
36484
|
-
|
|
36485
|
-
|
|
36486
|
-
|
|
36487
|
-
|
|
36488
|
-
|
|
36489
|
-
|
|
36490
|
-
|
|
36491
|
-
|
|
36492
|
-
|
|
36493
|
-
|
|
36494
|
-
|
|
36495
|
-
|
|
36496
|
-
|
|
36497
|
-
|
|
36498
|
-
|
|
36499
|
-
|
|
36500
|
-
|
|
36501
|
-
|
|
36502
|
-
|
|
36503
|
-
|
|
36504
|
-
|
|
36505
|
-
|
|
36506
|
-
|
|
36507
|
-
|
|
36508
|
-
|
|
36509
|
-
|
|
36510
|
-
|
|
36511
|
-
|
|
36512
|
-
|
|
36638
|
+
const result = await collectionName("buildings").aggregate(
|
|
36639
|
+
[
|
|
36640
|
+
// ✅ Match early with index-friendly query
|
|
36641
|
+
{
|
|
36642
|
+
$match: {
|
|
36643
|
+
...defaultQuery,
|
|
36644
|
+
status: { $eq: "active" }
|
|
36645
|
+
}
|
|
36646
|
+
},
|
|
36647
|
+
// ✅ Only project needed fields before heavy lookups
|
|
36648
|
+
{
|
|
36649
|
+
$project: {
|
|
36650
|
+
_id: 1,
|
|
36651
|
+
name: 1,
|
|
36652
|
+
site: 1,
|
|
36653
|
+
block: 1
|
|
36654
|
+
}
|
|
36655
|
+
},
|
|
36656
|
+
// ✅ Use localField/foreignField for better index usage
|
|
36657
|
+
{
|
|
36658
|
+
$lookup: {
|
|
36659
|
+
from: "building-levels",
|
|
36660
|
+
localField: "_id",
|
|
36661
|
+
foreignField: "block",
|
|
36662
|
+
pipeline: [
|
|
36663
|
+
{ $match: { status: { $ne: "deleted" } } },
|
|
36664
|
+
{
|
|
36665
|
+
$lookup: {
|
|
36666
|
+
from: "building-units",
|
|
36667
|
+
localField: "_id",
|
|
36668
|
+
foreignField: "level",
|
|
36669
|
+
pipeline: [
|
|
36670
|
+
{ $match: { status: { $ne: "deleted" }, site } },
|
|
36671
|
+
{ $project: { _id: 1, name: 1 } }
|
|
36672
|
+
],
|
|
36673
|
+
as: "units"
|
|
36674
|
+
}
|
|
36675
|
+
},
|
|
36676
|
+
{
|
|
36677
|
+
$match: { "units.0": { $exists: true } }
|
|
36678
|
+
},
|
|
36679
|
+
{
|
|
36680
|
+
$project: {
|
|
36681
|
+
_id: 1,
|
|
36682
|
+
level: 1,
|
|
36683
|
+
units: 1
|
|
36684
|
+
}
|
|
36513
36685
|
}
|
|
36514
|
-
|
|
36515
|
-
|
|
36516
|
-
|
|
36517
|
-
}
|
|
36518
|
-
|
|
36519
|
-
|
|
36520
|
-
|
|
36521
|
-
|
|
36522
|
-
|
|
36523
|
-
|
|
36524
|
-
|
|
36525
|
-
|
|
36526
|
-
|
|
36527
|
-
|
|
36528
|
-
}
|
|
36529
|
-
|
|
36530
|
-
|
|
36531
|
-
|
|
36532
|
-
|
|
36533
|
-
|
|
36534
|
-
}
|
|
36535
|
-
|
|
36536
|
-
|
|
36537
|
-
|
|
36538
|
-
|
|
36539
|
-
|
|
36540
|
-
|
|
36541
|
-
|
|
36542
|
-
|
|
36543
|
-
|
|
36544
|
-
|
|
36545
|
-
|
|
36546
|
-
|
|
36547
|
-
|
|
36548
|
-
|
|
36549
|
-
|
|
36550
|
-
}
|
|
36551
|
-
|
|
36552
|
-
|
|
36553
|
-
|
|
36554
|
-
|
|
36555
|
-
|
|
36556
|
-
|
|
36557
|
-
|
|
36558
|
-
|
|
36559
|
-
|
|
36560
|
-
|
|
36561
|
-
|
|
36562
|
-
|
|
36563
|
-
|
|
36564
|
-
|
|
36565
|
-
|
|
36566
|
-
|
|
36567
|
-
|
|
36568
|
-
|
|
36686
|
+
],
|
|
36687
|
+
as: "level"
|
|
36688
|
+
}
|
|
36689
|
+
},
|
|
36690
|
+
// ✅ Filter out buildings with no levels early
|
|
36691
|
+
{
|
|
36692
|
+
$match: { "level.0": { $exists: true } }
|
|
36693
|
+
},
|
|
36694
|
+
// ✅ Unwind to flatten the hierarchy
|
|
36695
|
+
{
|
|
36696
|
+
$unwind: {
|
|
36697
|
+
path: "$level",
|
|
36698
|
+
preserveNullAndEmptyArrays: false
|
|
36699
|
+
}
|
|
36700
|
+
},
|
|
36701
|
+
{
|
|
36702
|
+
$unwind: {
|
|
36703
|
+
path: "$level.units",
|
|
36704
|
+
preserveNullAndEmptyArrays: false
|
|
36705
|
+
}
|
|
36706
|
+
},
|
|
36707
|
+
// // Groups by unit _id and keeps only the first occurrence
|
|
36708
|
+
// {
|
|
36709
|
+
// $group: {
|
|
36710
|
+
// _id: "$level.units._id",
|
|
36711
|
+
// doc: { $first: "$$ROOT" },
|
|
36712
|
+
// },
|
|
36713
|
+
// },
|
|
36714
|
+
// {
|
|
36715
|
+
// $replaceRoot: { newRoot: "$doc" },
|
|
36716
|
+
// },
|
|
36717
|
+
// ✅ Apply search filter
|
|
36718
|
+
{
|
|
36719
|
+
$match: {
|
|
36720
|
+
...searchQuery
|
|
36721
|
+
}
|
|
36722
|
+
},
|
|
36723
|
+
{
|
|
36724
|
+
$facet: {
|
|
36725
|
+
totalCount: [{ $count: "count" }],
|
|
36726
|
+
items: [
|
|
36727
|
+
// ✅ Sort BEFORE skip/limit for correct pagination
|
|
36728
|
+
{ $skip: page * limit },
|
|
36729
|
+
{ $limit: limit },
|
|
36730
|
+
// ✅ Users lookup - optimized with index hint
|
|
36731
|
+
{
|
|
36732
|
+
$lookup: {
|
|
36733
|
+
from: "users",
|
|
36734
|
+
let: { unit: "$level.units._id" },
|
|
36735
|
+
pipeline: [
|
|
36736
|
+
{
|
|
36737
|
+
$match: {
|
|
36738
|
+
$expr: { $eq: ["$unitNumber", "$$unit"] },
|
|
36739
|
+
residentType: "House/Unit Owner"
|
|
36740
|
+
}
|
|
36741
|
+
},
|
|
36742
|
+
{ $limit: 1 },
|
|
36743
|
+
{ $project: { _id: 1, givenName: 1, surname: 1 } }
|
|
36744
|
+
],
|
|
36745
|
+
as: "unitOwner"
|
|
36746
|
+
}
|
|
36747
|
+
},
|
|
36748
|
+
// ✅ Access card lookup - optimized query
|
|
36749
|
+
{
|
|
36750
|
+
$lookup: {
|
|
36751
|
+
from: "access-cards",
|
|
36752
|
+
let: { unit: "$level.units._id" },
|
|
36753
|
+
pipeline: [
|
|
36754
|
+
{
|
|
36755
|
+
$match: {
|
|
36756
|
+
$expr: {
|
|
36757
|
+
$in: [
|
|
36758
|
+
"$$unit",
|
|
36759
|
+
{
|
|
36760
|
+
$cond: [
|
|
36761
|
+
{ $isArray: "$assignedUnit" },
|
|
36762
|
+
"$assignedUnit",
|
|
36763
|
+
["$assignedUnit"]
|
|
36764
|
+
]
|
|
36765
|
+
}
|
|
36766
|
+
]
|
|
36767
|
+
},
|
|
36768
|
+
userType
|
|
36769
|
+
}
|
|
36770
|
+
},
|
|
36771
|
+
{
|
|
36772
|
+
$project: {
|
|
36773
|
+
_id: 1,
|
|
36774
|
+
userId: 1,
|
|
36775
|
+
type: 1,
|
|
36776
|
+
cardNo: 1,
|
|
36777
|
+
isActivated: 1,
|
|
36778
|
+
replacementStatus: 1
|
|
36779
|
+
}
|
|
36780
|
+
}
|
|
36781
|
+
],
|
|
36782
|
+
as: "accessCards"
|
|
36783
|
+
}
|
|
36784
|
+
},
|
|
36785
|
+
// ✅ Compute all card categorization and counts in ONE stage
|
|
36786
|
+
{
|
|
36787
|
+
$addFields: {
|
|
36788
|
+
f_Available: {
|
|
36789
|
+
$filter: {
|
|
36790
|
+
input: "$accessCards",
|
|
36791
|
+
as: "card",
|
|
36792
|
+
cond: {
|
|
36793
|
+
$and: [
|
|
36794
|
+
{ $eq: ["$$card.userId", null] },
|
|
36795
|
+
{ $eq: ["$$card.isActivated", true] }
|
|
36796
|
+
]
|
|
36797
|
+
}
|
|
36569
36798
|
}
|
|
36570
36799
|
},
|
|
36571
|
-
|
|
36572
|
-
|
|
36573
|
-
|
|
36574
|
-
|
|
36575
|
-
|
|
36576
|
-
|
|
36577
|
-
|
|
36578
|
-
|
|
36579
|
-
$lookup: {
|
|
36580
|
-
from: "access-cards",
|
|
36581
|
-
let: { unit: "$level.units._id" },
|
|
36582
|
-
pipeline: [
|
|
36583
|
-
{
|
|
36584
|
-
$match: {
|
|
36585
|
-
$expr: {
|
|
36586
|
-
$in: [
|
|
36587
|
-
"$$unit",
|
|
36588
|
-
{ $cond: [{ $isArray: "$assignedUnit" }, "$assignedUnit", ["$assignedUnit"]] }
|
|
36800
|
+
f_Assigned: {
|
|
36801
|
+
$filter: {
|
|
36802
|
+
input: "$accessCards",
|
|
36803
|
+
as: "card",
|
|
36804
|
+
cond: {
|
|
36805
|
+
$and: [
|
|
36806
|
+
{ $ne: ["$$card.userId", null] },
|
|
36807
|
+
{ $eq: ["$$card.isActivated", true] }
|
|
36589
36808
|
]
|
|
36590
|
-
}
|
|
36591
|
-
userType
|
|
36809
|
+
}
|
|
36592
36810
|
}
|
|
36593
36811
|
},
|
|
36594
|
-
|
|
36595
|
-
|
|
36596
|
-
|
|
36597
|
-
|
|
36598
|
-
|
|
36599
|
-
|
|
36600
|
-
|
|
36601
|
-
|
|
36602
|
-
|
|
36603
|
-
|
|
36604
|
-
|
|
36605
|
-
|
|
36606
|
-
|
|
36607
|
-
|
|
36608
|
-
|
|
36609
|
-
|
|
36610
|
-
|
|
36611
|
-
|
|
36612
|
-
|
|
36613
|
-
|
|
36614
|
-
|
|
36615
|
-
|
|
36616
|
-
|
|
36617
|
-
$filter: {
|
|
36618
|
-
input: "$accessCards",
|
|
36619
|
-
as: "card",
|
|
36620
|
-
cond: { $and: [{ $eq: ["$$card.isActivated", false] }, { $ne: ["$$card.replacementStatus", null] }] }
|
|
36621
|
-
}
|
|
36622
|
-
},
|
|
36623
|
-
f_deleted: {
|
|
36624
|
-
$filter: {
|
|
36625
|
-
input: "$accessCards",
|
|
36626
|
-
as: "card",
|
|
36627
|
-
cond: { $and: [{ $eq: ["$$card.isActivated", false] }, { $eq: ["$$card.replacementStatus", null] }] }
|
|
36812
|
+
f_replaced: {
|
|
36813
|
+
$filter: {
|
|
36814
|
+
input: "$accessCards",
|
|
36815
|
+
as: "card",
|
|
36816
|
+
cond: {
|
|
36817
|
+
$and: [
|
|
36818
|
+
{ $eq: ["$$card.isActivated", false] },
|
|
36819
|
+
{ $ne: ["$$card.replacementStatus", null] }
|
|
36820
|
+
]
|
|
36821
|
+
}
|
|
36822
|
+
}
|
|
36823
|
+
},
|
|
36824
|
+
f_deleted: {
|
|
36825
|
+
$filter: {
|
|
36826
|
+
input: "$accessCards",
|
|
36827
|
+
as: "card",
|
|
36828
|
+
cond: {
|
|
36829
|
+
$and: [
|
|
36830
|
+
{ $eq: ["$$card.isActivated", false] },
|
|
36831
|
+
{ $eq: ["$$card.replacementStatus", null] }
|
|
36832
|
+
]
|
|
36833
|
+
}
|
|
36834
|
+
}
|
|
36628
36835
|
}
|
|
36629
36836
|
}
|
|
36630
|
-
}
|
|
36631
|
-
|
|
36632
|
-
|
|
36633
|
-
|
|
36634
|
-
|
|
36635
|
-
|
|
36636
|
-
|
|
36637
|
-
|
|
36638
|
-
|
|
36639
|
-
|
|
36640
|
-
unit_owner: { $arrayElemAt: ["$unitOwner", 0] },
|
|
36641
|
-
available: {
|
|
36642
|
-
physical: { $filter: { input: "$f_Available", as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } },
|
|
36643
|
-
non_physical: { $filter: { input: "$f_Available", as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } }
|
|
36644
|
-
},
|
|
36645
|
-
assigned: {
|
|
36646
|
-
physical: { $filter: { input: "$f_Assigned", as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } },
|
|
36647
|
-
non_physical: { $filter: { input: "$f_Assigned", as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } }
|
|
36648
|
-
},
|
|
36649
|
-
cardCounts: {
|
|
36837
|
+
},
|
|
36838
|
+
// ✅ Final projection with all computed fields
|
|
36839
|
+
{
|
|
36840
|
+
$project: {
|
|
36841
|
+
_id: "$level.units._id",
|
|
36842
|
+
name: "$level.units.name",
|
|
36843
|
+
level: { _id: "$level._id", level: "$level.level" },
|
|
36844
|
+
block: { _id: "$_id", name: "$name", block: "$block" },
|
|
36845
|
+
site: "$site",
|
|
36846
|
+
unit_owner: { $arrayElemAt: ["$unitOwner", 0] },
|
|
36650
36847
|
available: {
|
|
36651
|
-
physical: {
|
|
36652
|
-
|
|
36848
|
+
physical: {
|
|
36849
|
+
$filter: {
|
|
36850
|
+
input: "$f_Available",
|
|
36851
|
+
as: "c",
|
|
36852
|
+
cond: { $eq: ["$$c.type", "NFC" /* NFC */] }
|
|
36853
|
+
}
|
|
36854
|
+
},
|
|
36855
|
+
non_physical: {
|
|
36856
|
+
$filter: {
|
|
36857
|
+
input: "$f_Available",
|
|
36858
|
+
as: "c",
|
|
36859
|
+
cond: { $eq: ["$$c.type", "QRCODE" /* QR */] }
|
|
36860
|
+
}
|
|
36861
|
+
}
|
|
36653
36862
|
},
|
|
36654
36863
|
assigned: {
|
|
36655
|
-
physical: {
|
|
36656
|
-
|
|
36864
|
+
physical: {
|
|
36865
|
+
$filter: {
|
|
36866
|
+
input: "$f_Assigned",
|
|
36867
|
+
as: "c",
|
|
36868
|
+
cond: { $eq: ["$$c.type", "NFC" /* NFC */] }
|
|
36869
|
+
}
|
|
36870
|
+
},
|
|
36871
|
+
non_physical: {
|
|
36872
|
+
$filter: {
|
|
36873
|
+
input: "$f_Assigned",
|
|
36874
|
+
as: "c",
|
|
36875
|
+
cond: { $eq: ["$$c.type", "QRCODE" /* QR */] }
|
|
36876
|
+
}
|
|
36877
|
+
}
|
|
36878
|
+
},
|
|
36879
|
+
cardCounts: {
|
|
36880
|
+
available: {
|
|
36881
|
+
physical: {
|
|
36882
|
+
$size: {
|
|
36883
|
+
$filter: {
|
|
36884
|
+
input: { $ifNull: ["$f_Available", []] },
|
|
36885
|
+
as: "c",
|
|
36886
|
+
cond: {
|
|
36887
|
+
$eq: ["$$c.type", "NFC" /* NFC */]
|
|
36888
|
+
}
|
|
36889
|
+
}
|
|
36890
|
+
}
|
|
36891
|
+
},
|
|
36892
|
+
non_physical: {
|
|
36893
|
+
$size: {
|
|
36894
|
+
$filter: {
|
|
36895
|
+
input: { $ifNull: ["$f_Available", []] },
|
|
36896
|
+
as: "c",
|
|
36897
|
+
cond: {
|
|
36898
|
+
$eq: ["$$c.type", "QRCODE" /* QR */]
|
|
36899
|
+
}
|
|
36900
|
+
}
|
|
36901
|
+
}
|
|
36902
|
+
}
|
|
36903
|
+
},
|
|
36904
|
+
assigned: {
|
|
36905
|
+
physical: {
|
|
36906
|
+
$size: {
|
|
36907
|
+
$filter: {
|
|
36908
|
+
input: { $ifNull: ["$f_Assigned", []] },
|
|
36909
|
+
as: "c",
|
|
36910
|
+
cond: {
|
|
36911
|
+
$eq: ["$$c.type", "NFC" /* NFC */]
|
|
36912
|
+
}
|
|
36913
|
+
}
|
|
36914
|
+
}
|
|
36915
|
+
},
|
|
36916
|
+
non_physical: {
|
|
36917
|
+
$size: {
|
|
36918
|
+
$filter: {
|
|
36919
|
+
input: { $ifNull: ["$f_Assigned", []] },
|
|
36920
|
+
as: "c",
|
|
36921
|
+
cond: {
|
|
36922
|
+
$eq: ["$$c.type", "QRCODE" /* QR */]
|
|
36923
|
+
}
|
|
36924
|
+
}
|
|
36925
|
+
}
|
|
36926
|
+
}
|
|
36927
|
+
}
|
|
36928
|
+
},
|
|
36929
|
+
replaced: {
|
|
36930
|
+
physical: {
|
|
36931
|
+
$filter: {
|
|
36932
|
+
input: "$f_replaced",
|
|
36933
|
+
as: "c",
|
|
36934
|
+
cond: { $eq: ["$$c.type", "NFC" /* NFC */] }
|
|
36935
|
+
}
|
|
36936
|
+
},
|
|
36937
|
+
non_physical: {
|
|
36938
|
+
$filter: {
|
|
36939
|
+
input: "$f_replaced",
|
|
36940
|
+
as: "c",
|
|
36941
|
+
cond: { $eq: ["$$c.type", "QRCODE" /* QR */] }
|
|
36942
|
+
}
|
|
36943
|
+
}
|
|
36944
|
+
},
|
|
36945
|
+
deleted: {
|
|
36946
|
+
physical: {
|
|
36947
|
+
$filter: {
|
|
36948
|
+
input: "$f_deleted",
|
|
36949
|
+
as: "c",
|
|
36950
|
+
cond: { $eq: ["$$c.type", "NFC" /* NFC */] }
|
|
36951
|
+
}
|
|
36952
|
+
},
|
|
36953
|
+
non_physical: {
|
|
36954
|
+
$filter: {
|
|
36955
|
+
input: "$f_deleted",
|
|
36956
|
+
as: "c",
|
|
36957
|
+
cond: { $eq: ["$$c.type", "QRCODE" /* QR */] }
|
|
36958
|
+
}
|
|
36959
|
+
}
|
|
36960
|
+
},
|
|
36961
|
+
totalCardCount: {
|
|
36962
|
+
$add: [
|
|
36963
|
+
{
|
|
36964
|
+
$size: {
|
|
36965
|
+
$filter: {
|
|
36966
|
+
input: { $ifNull: ["$f_Available", []] },
|
|
36967
|
+
as: "c",
|
|
36968
|
+
cond: {
|
|
36969
|
+
$eq: ["$$c.type", "NFC" /* NFC */]
|
|
36970
|
+
}
|
|
36971
|
+
}
|
|
36972
|
+
}
|
|
36973
|
+
},
|
|
36974
|
+
{
|
|
36975
|
+
$size: {
|
|
36976
|
+
$filter: {
|
|
36977
|
+
input: { $ifNull: ["$f_Available", []] },
|
|
36978
|
+
as: "c",
|
|
36979
|
+
cond: {
|
|
36980
|
+
$eq: ["$$c.type", "QRCODE" /* QR */]
|
|
36981
|
+
}
|
|
36982
|
+
}
|
|
36983
|
+
}
|
|
36984
|
+
},
|
|
36985
|
+
{
|
|
36986
|
+
$size: {
|
|
36987
|
+
$filter: {
|
|
36988
|
+
input: { $ifNull: ["$f_Assigned", []] },
|
|
36989
|
+
as: "c",
|
|
36990
|
+
cond: {
|
|
36991
|
+
$eq: ["$$c.type", "NFC" /* NFC */]
|
|
36992
|
+
}
|
|
36993
|
+
}
|
|
36994
|
+
}
|
|
36995
|
+
},
|
|
36996
|
+
{
|
|
36997
|
+
$size: {
|
|
36998
|
+
$filter: {
|
|
36999
|
+
input: { $ifNull: ["$f_Assigned", []] },
|
|
37000
|
+
as: "c",
|
|
37001
|
+
cond: {
|
|
37002
|
+
$eq: ["$$c.type", "QRCODE" /* QR */]
|
|
37003
|
+
}
|
|
37004
|
+
}
|
|
37005
|
+
}
|
|
37006
|
+
}
|
|
37007
|
+
]
|
|
36657
37008
|
}
|
|
36658
|
-
},
|
|
36659
|
-
replaced: {
|
|
36660
|
-
physical: { $filter: { input: "$f_replaced", as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } },
|
|
36661
|
-
non_physical: { $filter: { input: "$f_replaced", as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } }
|
|
36662
|
-
},
|
|
36663
|
-
deleted: {
|
|
36664
|
-
physical: { $filter: { input: "$f_deleted", as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } },
|
|
36665
|
-
non_physical: { $filter: { input: "$f_deleted", as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } }
|
|
36666
|
-
},
|
|
36667
|
-
totalCardCount: {
|
|
36668
|
-
$add: [
|
|
36669
|
-
{ $size: { $filter: { input: { $ifNull: ["$f_Available", []] }, as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } } },
|
|
36670
|
-
{ $size: { $filter: { input: { $ifNull: ["$f_Available", []] }, as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } } },
|
|
36671
|
-
{ $size: { $filter: { input: { $ifNull: ["$f_Assigned", []] }, as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } } },
|
|
36672
|
-
{ $size: { $filter: { input: { $ifNull: ["$f_Assigned", []] }, as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } } }
|
|
36673
|
-
]
|
|
36674
37009
|
}
|
|
36675
|
-
}
|
|
36676
|
-
|
|
36677
|
-
|
|
36678
|
-
|
|
37010
|
+
},
|
|
37011
|
+
{ $sort: { totalCardCount: -1 } }
|
|
37012
|
+
]
|
|
37013
|
+
}
|
|
36679
37014
|
}
|
|
36680
|
-
|
|
36681
|
-
|
|
37015
|
+
],
|
|
37016
|
+
{ allowDiskUse: true }
|
|
37017
|
+
).toArray();
|
|
36682
37018
|
const totalCount = result[0]?.totalCount?.[0]?.count ?? 0;
|
|
36683
37019
|
const items = result[0]?.items ?? [];
|
|
36684
37020
|
const paginatedResult = paginate39(items, page, limit, totalCount);
|
|
@@ -36697,157 +37033,162 @@ function UseAccessManagementRepo() {
|
|
|
36697
37033
|
site: { $in: [site] }
|
|
36698
37034
|
};
|
|
36699
37035
|
const searchQuery = buildSearchQuery(search);
|
|
36700
|
-
const result = await collectionName("buildings").aggregate(
|
|
36701
|
-
|
|
36702
|
-
|
|
36703
|
-
|
|
36704
|
-
|
|
36705
|
-
|
|
36706
|
-
|
|
36707
|
-
|
|
36708
|
-
|
|
36709
|
-
|
|
36710
|
-
|
|
36711
|
-
|
|
36712
|
-
|
|
36713
|
-
|
|
36714
|
-
|
|
36715
|
-
|
|
36716
|
-
|
|
36717
|
-
|
|
36718
|
-
|
|
36719
|
-
|
|
36720
|
-
|
|
36721
|
-
|
|
36722
|
-
|
|
36723
|
-
|
|
36724
|
-
|
|
36725
|
-
|
|
36726
|
-
|
|
36727
|
-
|
|
36728
|
-
|
|
36729
|
-
|
|
36730
|
-
|
|
36731
|
-
|
|
36732
|
-
|
|
36733
|
-
|
|
36734
|
-
|
|
36735
|
-
|
|
36736
|
-
|
|
36737
|
-
|
|
36738
|
-
|
|
36739
|
-
|
|
36740
|
-
|
|
36741
|
-
|
|
36742
|
-
|
|
36743
|
-
|
|
36744
|
-
|
|
36745
|
-
|
|
36746
|
-
|
|
36747
|
-
|
|
36748
|
-
|
|
36749
|
-
|
|
36750
|
-
|
|
36751
|
-
|
|
36752
|
-
|
|
36753
|
-
$
|
|
36754
|
-
|
|
36755
|
-
|
|
36756
|
-
|
|
36757
|
-
|
|
36758
|
-
|
|
36759
|
-
|
|
37036
|
+
const result = await collectionName("buildings").aggregate(
|
|
37037
|
+
[
|
|
37038
|
+
// ✅ Match early with index-friendly query
|
|
37039
|
+
{
|
|
37040
|
+
$match: {
|
|
37041
|
+
...query,
|
|
37042
|
+
status: { $ne: "deleted" }
|
|
37043
|
+
}
|
|
37044
|
+
},
|
|
37045
|
+
// ✅ Only project needed fields before heavy lookups
|
|
37046
|
+
{
|
|
37047
|
+
$project: {
|
|
37048
|
+
_id: 1,
|
|
37049
|
+
name: 1,
|
|
37050
|
+
site: 1
|
|
37051
|
+
}
|
|
37052
|
+
},
|
|
37053
|
+
// ✅ Use localField/foreignField for better index usage
|
|
37054
|
+
{
|
|
37055
|
+
$lookup: {
|
|
37056
|
+
from: "building-levels",
|
|
37057
|
+
localField: "_id",
|
|
37058
|
+
foreignField: "block",
|
|
37059
|
+
pipeline: [
|
|
37060
|
+
{ $match: { status: { $ne: "deleted" } } },
|
|
37061
|
+
{
|
|
37062
|
+
$lookup: {
|
|
37063
|
+
from: "building-units",
|
|
37064
|
+
localField: "_id",
|
|
37065
|
+
foreignField: "level",
|
|
37066
|
+
pipeline: [
|
|
37067
|
+
{ $match: { status: { $ne: "deleted" } } },
|
|
37068
|
+
{ $project: { _id: 1, name: 1 } },
|
|
37069
|
+
{
|
|
37070
|
+
$lookup: {
|
|
37071
|
+
from: "access-cards",
|
|
37072
|
+
localField: "_id",
|
|
37073
|
+
foreignField: "assignedUnit",
|
|
37074
|
+
pipeline: [
|
|
37075
|
+
{
|
|
37076
|
+
$match: {
|
|
37077
|
+
isActivated: true,
|
|
37078
|
+
userType,
|
|
37079
|
+
type
|
|
37080
|
+
}
|
|
37081
|
+
},
|
|
37082
|
+
{
|
|
37083
|
+
$group: {
|
|
37084
|
+
_id: null,
|
|
37085
|
+
accessLevels: { $addToSet: "$accessLevel" },
|
|
37086
|
+
liftAccessLevels: {
|
|
37087
|
+
$addToSet: "$liftAccessLevel"
|
|
37088
|
+
},
|
|
37089
|
+
doorNames: { $addToSet: "$doorName" },
|
|
37090
|
+
liftNames: { $addToSet: "$liftName" },
|
|
37091
|
+
cards: {
|
|
37092
|
+
$push: {
|
|
37093
|
+
_id: "$_id",
|
|
37094
|
+
cardNo: "$cardNo",
|
|
37095
|
+
accessLevel: "$accessLevel",
|
|
37096
|
+
liftAccessLevel: "$liftAccessLevel",
|
|
37097
|
+
doorName: "$doorName",
|
|
37098
|
+
liftName: "$liftName"
|
|
37099
|
+
}
|
|
36760
37100
|
}
|
|
36761
37101
|
}
|
|
37102
|
+
},
|
|
37103
|
+
{
|
|
37104
|
+
$project: {
|
|
37105
|
+
_id: 0,
|
|
37106
|
+
accessCardCount: {
|
|
37107
|
+
$size: "$cards"
|
|
37108
|
+
},
|
|
37109
|
+
accessLevels: 1,
|
|
37110
|
+
liftAccessLevels: 1,
|
|
37111
|
+
doorNames: 1,
|
|
37112
|
+
liftNames: 1
|
|
37113
|
+
}
|
|
36762
37114
|
}
|
|
36763
|
-
|
|
36764
|
-
|
|
36765
|
-
|
|
36766
|
-
|
|
36767
|
-
|
|
36768
|
-
|
|
36769
|
-
|
|
36770
|
-
|
|
36771
|
-
liftAccessLevels: 1,
|
|
36772
|
-
doorNames: 1,
|
|
36773
|
-
liftNames: 1
|
|
36774
|
-
}
|
|
36775
|
-
}
|
|
36776
|
-
],
|
|
36777
|
-
as: "fAccessCards"
|
|
36778
|
-
}
|
|
36779
|
-
},
|
|
36780
|
-
{
|
|
36781
|
-
$match: {
|
|
36782
|
-
"fAccessCards.0": { $exists: true }
|
|
37115
|
+
],
|
|
37116
|
+
as: "fAccessCards"
|
|
37117
|
+
}
|
|
37118
|
+
},
|
|
37119
|
+
{
|
|
37120
|
+
$match: {
|
|
37121
|
+
"fAccessCards.0": { $exists: true }
|
|
37122
|
+
}
|
|
36783
37123
|
}
|
|
36784
|
-
|
|
36785
|
-
|
|
36786
|
-
|
|
36787
|
-
}
|
|
36788
|
-
|
|
36789
|
-
|
|
36790
|
-
|
|
36791
|
-
|
|
36792
|
-
|
|
36793
|
-
|
|
36794
|
-
|
|
36795
|
-
|
|
36796
|
-
|
|
37124
|
+
],
|
|
37125
|
+
as: "units"
|
|
37126
|
+
}
|
|
37127
|
+
},
|
|
37128
|
+
{
|
|
37129
|
+
$match: { "units.0": { $exists: true } }
|
|
37130
|
+
},
|
|
37131
|
+
{
|
|
37132
|
+
$project: {
|
|
37133
|
+
_id: 1,
|
|
37134
|
+
level: 1,
|
|
37135
|
+
units: 1
|
|
37136
|
+
}
|
|
36797
37137
|
}
|
|
36798
|
-
|
|
36799
|
-
|
|
36800
|
-
|
|
36801
|
-
}
|
|
36802
|
-
|
|
36803
|
-
|
|
36804
|
-
|
|
36805
|
-
|
|
36806
|
-
|
|
36807
|
-
|
|
36808
|
-
|
|
36809
|
-
|
|
36810
|
-
|
|
36811
|
-
|
|
36812
|
-
}
|
|
36813
|
-
|
|
36814
|
-
|
|
36815
|
-
|
|
36816
|
-
|
|
36817
|
-
|
|
36818
|
-
}
|
|
36819
|
-
|
|
36820
|
-
|
|
36821
|
-
|
|
36822
|
-
|
|
36823
|
-
|
|
36824
|
-
}
|
|
36825
|
-
|
|
36826
|
-
|
|
36827
|
-
|
|
36828
|
-
|
|
36829
|
-
|
|
36830
|
-
|
|
36831
|
-
}
|
|
36832
|
-
|
|
36833
|
-
|
|
36834
|
-
|
|
36835
|
-
|
|
36836
|
-
|
|
36837
|
-
|
|
36838
|
-
|
|
36839
|
-
|
|
36840
|
-
}
|
|
36841
|
-
|
|
36842
|
-
|
|
36843
|
-
|
|
36844
|
-
|
|
36845
|
-
|
|
36846
|
-
|
|
36847
|
-
|
|
37138
|
+
],
|
|
37139
|
+
as: "level"
|
|
37140
|
+
}
|
|
37141
|
+
},
|
|
37142
|
+
// ✅ Filter out buildings with no levels early
|
|
37143
|
+
{
|
|
37144
|
+
$match: { "level.0": { $exists: true } }
|
|
37145
|
+
},
|
|
37146
|
+
// ✅ Unwind to flatten the hierarchy
|
|
37147
|
+
{
|
|
37148
|
+
$unwind: {
|
|
37149
|
+
path: "$level",
|
|
37150
|
+
preserveNullAndEmptyArrays: false
|
|
37151
|
+
}
|
|
37152
|
+
},
|
|
37153
|
+
{
|
|
37154
|
+
$unwind: {
|
|
37155
|
+
path: "$level.units",
|
|
37156
|
+
preserveNullAndEmptyArrays: false
|
|
37157
|
+
}
|
|
37158
|
+
},
|
|
37159
|
+
{
|
|
37160
|
+
$unwind: {
|
|
37161
|
+
path: "$level.units.fAccessCards",
|
|
37162
|
+
preserveNullAndEmptyArrays: false
|
|
37163
|
+
}
|
|
37164
|
+
},
|
|
37165
|
+
// // Groups by unit _id and keeps only the first occurrence
|
|
37166
|
+
{
|
|
37167
|
+
$group: {
|
|
37168
|
+
_id: "$level.units._id",
|
|
37169
|
+
doc: { $first: "$$ROOT" }
|
|
37170
|
+
}
|
|
37171
|
+
},
|
|
37172
|
+
{
|
|
37173
|
+
$replaceRoot: { newRoot: "$doc" }
|
|
37174
|
+
},
|
|
37175
|
+
// ✅ Apply search filter
|
|
37176
|
+
{
|
|
37177
|
+
$match: {
|
|
37178
|
+
...searchQuery
|
|
37179
|
+
}
|
|
37180
|
+
},
|
|
37181
|
+
{
|
|
37182
|
+
$project: {
|
|
37183
|
+
name: 1,
|
|
37184
|
+
"level.level": 1,
|
|
37185
|
+
"level.units.name": 1,
|
|
37186
|
+
"level.units.fAccessCards": 1
|
|
37187
|
+
}
|
|
36848
37188
|
}
|
|
36849
|
-
|
|
36850
|
-
|
|
37189
|
+
],
|
|
37190
|
+
{ allowDiskUse: true }
|
|
37191
|
+
).toArray();
|
|
36851
37192
|
return result;
|
|
36852
37193
|
} catch (error) {
|
|
36853
37194
|
throw new Error(error.message);
|
|
@@ -36858,8 +37199,12 @@ function UseAccessManagementRepo() {
|
|
|
36858
37199
|
try {
|
|
36859
37200
|
session?.startTransaction();
|
|
36860
37201
|
const { userId, cardId, site } = params;
|
|
36861
|
-
const allUserId = await Promise.all(
|
|
36862
|
-
|
|
37202
|
+
const allUserId = await Promise.all(
|
|
37203
|
+
userId.map(async (id) => new ObjectId90(id))
|
|
37204
|
+
);
|
|
37205
|
+
const allCardId = await Promise.all(
|
|
37206
|
+
cardId.map(async (id) => new ObjectId90(id))
|
|
37207
|
+
);
|
|
36863
37208
|
const siteId = new ObjectId90(site);
|
|
36864
37209
|
const result = await collection().updateMany(
|
|
36865
37210
|
{
|
|
@@ -36902,16 +37247,19 @@ function UseAccessManagementRepo() {
|
|
|
36902
37247
|
liftAccessLevel,
|
|
36903
37248
|
isActivated: true
|
|
36904
37249
|
};
|
|
36905
|
-
const result = await collection().aggregate(
|
|
36906
|
-
|
|
36907
|
-
|
|
36908
|
-
|
|
36909
|
-
|
|
36910
|
-
|
|
36911
|
-
|
|
37250
|
+
const result = await collection().aggregate(
|
|
37251
|
+
[
|
|
37252
|
+
{
|
|
37253
|
+
$match: query
|
|
37254
|
+
},
|
|
37255
|
+
{
|
|
37256
|
+
$facet: {
|
|
37257
|
+
counts: [{ $count: "count" }]
|
|
37258
|
+
}
|
|
36912
37259
|
}
|
|
36913
|
-
|
|
36914
|
-
|
|
37260
|
+
],
|
|
37261
|
+
{ allowDiskUse: true }
|
|
37262
|
+
).toArray();
|
|
36915
37263
|
return result;
|
|
36916
37264
|
} catch (error) {
|
|
36917
37265
|
throw new Error(error.message);
|
|
@@ -36945,7 +37293,9 @@ function UseAccessManagementRepo() {
|
|
|
36945
37293
|
availableCardNo.push(num);
|
|
36946
37294
|
num++;
|
|
36947
37295
|
}
|
|
36948
|
-
const cardNumbers = availableCardNo.map(
|
|
37296
|
+
const cardNumbers = availableCardNo.map(
|
|
37297
|
+
(no) => no.toString().padStart(10, "0")
|
|
37298
|
+
);
|
|
36949
37299
|
const accessCards = [];
|
|
36950
37300
|
const convertedUnits = unit.map((obj) => new ObjectId90(obj));
|
|
36951
37301
|
for (let j = 0; j < (unit.length > 0 ? unit.length : quantity); j++) {
|
|
@@ -37005,10 +37355,18 @@ function UseAccessManagementRepo() {
|
|
|
37005
37355
|
liftAccessEndDate: formatEntryPassDate(item.liftAccessEndDate) || "19770510",
|
|
37006
37356
|
accessGroup: ag
|
|
37007
37357
|
};
|
|
37008
|
-
return readTemplate(
|
|
37358
|
+
return readTemplate(
|
|
37359
|
+
`${item.accessLevel !== null ? "add-card" : "add-card-lift"}`,
|
|
37360
|
+
{ ...command }
|
|
37361
|
+
);
|
|
37009
37362
|
}).flat();
|
|
37010
|
-
const response = await sendCommand(
|
|
37011
|
-
|
|
37363
|
+
const response = await sendCommand(
|
|
37364
|
+
commands.join("").toString(),
|
|
37365
|
+
params.acm_url
|
|
37366
|
+
);
|
|
37367
|
+
const result = await parseStringPromise2(response, {
|
|
37368
|
+
explicitArray: false
|
|
37369
|
+
});
|
|
37012
37370
|
if (result && result.RESULT.$.STCODE !== "0") {
|
|
37013
37371
|
throw new Error("Command failed, server error.");
|
|
37014
37372
|
}
|
|
@@ -37042,7 +37400,11 @@ function UseAccessManagementRepo() {
|
|
|
37042
37400
|
} else {
|
|
37043
37401
|
updateFields.isActivated = true;
|
|
37044
37402
|
}
|
|
37045
|
-
const res = await collection().updateOne(
|
|
37403
|
+
const res = await collection().updateOne(
|
|
37404
|
+
{ _id: card._id },
|
|
37405
|
+
{ $set: updateFields },
|
|
37406
|
+
{ session }
|
|
37407
|
+
);
|
|
37046
37408
|
results.push({ nfcId: nfc._id, modifiedCount: res.modifiedCount });
|
|
37047
37409
|
}
|
|
37048
37410
|
}
|
|
@@ -37069,8 +37431,20 @@ function UseAccessManagementRepo() {
|
|
|
37069
37431
|
assignedUnit: null,
|
|
37070
37432
|
userId: null,
|
|
37071
37433
|
$or: [
|
|
37072
|
-
{
|
|
37073
|
-
|
|
37434
|
+
{
|
|
37435
|
+
$and: [
|
|
37436
|
+
{ doorName: { $ne: null } },
|
|
37437
|
+
{ doorName: { $ne: "" } },
|
|
37438
|
+
{ accessLevel: { $ne: null } }
|
|
37439
|
+
]
|
|
37440
|
+
},
|
|
37441
|
+
{
|
|
37442
|
+
$and: [
|
|
37443
|
+
{ liftName: { $ne: null } },
|
|
37444
|
+
{ liftName: { $ne: "" } },
|
|
37445
|
+
{ liftAccessLevel: { $ne: null } }
|
|
37446
|
+
]
|
|
37447
|
+
}
|
|
37074
37448
|
]
|
|
37075
37449
|
}
|
|
37076
37450
|
},
|
|
@@ -37084,7 +37458,13 @@ function UseAccessManagementRepo() {
|
|
|
37084
37458
|
accessLevels: {
|
|
37085
37459
|
$addToSet: {
|
|
37086
37460
|
$cond: [
|
|
37087
|
-
{
|
|
37461
|
+
{
|
|
37462
|
+
$and: [
|
|
37463
|
+
{ $ne: ["$doorName", null] },
|
|
37464
|
+
{ $ne: ["$doorName", ""] },
|
|
37465
|
+
{ $ne: ["$accessLevel", null] }
|
|
37466
|
+
]
|
|
37467
|
+
},
|
|
37088
37468
|
{ name: "$doorName", no: "$accessLevel" },
|
|
37089
37469
|
"$$REMOVE"
|
|
37090
37470
|
]
|
|
@@ -37093,7 +37473,13 @@ function UseAccessManagementRepo() {
|
|
|
37093
37473
|
liftAccessLevels: {
|
|
37094
37474
|
$addToSet: {
|
|
37095
37475
|
$cond: [
|
|
37096
|
-
{
|
|
37476
|
+
{
|
|
37477
|
+
$and: [
|
|
37478
|
+
{ $ne: ["$liftName", null] },
|
|
37479
|
+
{ $ne: ["$liftName", ""] },
|
|
37480
|
+
{ $ne: ["$liftAccessLevel", null] }
|
|
37481
|
+
]
|
|
37482
|
+
},
|
|
37097
37483
|
{ name: "$liftName", no: "$liftAccessLevel" },
|
|
37098
37484
|
"$$REMOVE"
|
|
37099
37485
|
]
|
|
@@ -37129,7 +37515,14 @@ function UseAccessManagementRepo() {
|
|
|
37129
37515
|
const sessionResult = await Promise.all([
|
|
37130
37516
|
await collection().findOneAndUpdate(
|
|
37131
37517
|
{ _id: id },
|
|
37132
|
-
{
|
|
37518
|
+
{
|
|
37519
|
+
$set: {
|
|
37520
|
+
remarks,
|
|
37521
|
+
replacementStatus: "Complete",
|
|
37522
|
+
requestDate: /* @__PURE__ */ new Date(),
|
|
37523
|
+
isActivated: false
|
|
37524
|
+
}
|
|
37525
|
+
},
|
|
37133
37526
|
{ returnDocument: "after", session }
|
|
37134
37527
|
),
|
|
37135
37528
|
await collection().findOneAndUpdate(
|
|
@@ -37161,7 +37554,10 @@ function UseAccessManagementRepo() {
|
|
|
37161
37554
|
isActivated: true
|
|
37162
37555
|
};
|
|
37163
37556
|
if (search) {
|
|
37164
|
-
query.$or = [
|
|
37557
|
+
query.$or = [
|
|
37558
|
+
{ accessLevel: { $regex: search, $options: "i" } },
|
|
37559
|
+
{ cardNo: { $regex: search, $options: "i" } }
|
|
37560
|
+
];
|
|
37165
37561
|
}
|
|
37166
37562
|
if (type) {
|
|
37167
37563
|
query.userType = type;
|
|
@@ -37186,14 +37582,22 @@ function UseAccessManagementRepo() {
|
|
|
37186
37582
|
{
|
|
37187
37583
|
$addFields: {
|
|
37188
37584
|
extractedCardNo: {
|
|
37189
|
-
$substr: [
|
|
37585
|
+
$substr: [
|
|
37586
|
+
"$cardNo",
|
|
37587
|
+
{ $subtract: [{ $strLenCP: "$cardNo" }, 5] },
|
|
37588
|
+
5
|
|
37589
|
+
]
|
|
37190
37590
|
}
|
|
37191
37591
|
}
|
|
37192
37592
|
},
|
|
37193
37593
|
{
|
|
37194
37594
|
$facet: {
|
|
37195
37595
|
totalCount: [{ $count: "count" }],
|
|
37196
|
-
items: [
|
|
37596
|
+
items: [
|
|
37597
|
+
{ $sort: { _id: -1 } },
|
|
37598
|
+
{ $skip: page * limit },
|
|
37599
|
+
{ $limit: limit }
|
|
37600
|
+
]
|
|
37197
37601
|
}
|
|
37198
37602
|
}
|
|
37199
37603
|
]).toArray();
|
|
@@ -37224,145 +37628,151 @@ function UseAccessManagementRepo() {
|
|
|
37224
37628
|
query.replacementStatus = statusFilter;
|
|
37225
37629
|
}
|
|
37226
37630
|
if (dateFrom && dateTo) {
|
|
37227
|
-
query.requestDate = {
|
|
37631
|
+
query.requestDate = {
|
|
37632
|
+
$gte: new Date(dateFrom),
|
|
37633
|
+
$lte: new Date(dateTo)
|
|
37634
|
+
};
|
|
37228
37635
|
} else if (dateFrom) {
|
|
37229
37636
|
query.requestDate = { $gte: new Date(dateFrom) };
|
|
37230
37637
|
} else if (dateTo) {
|
|
37231
37638
|
query.requestDate = { $lte: new Date(dateTo) };
|
|
37232
37639
|
}
|
|
37233
|
-
const res = await collection().aggregate(
|
|
37234
|
-
|
|
37235
|
-
|
|
37236
|
-
|
|
37237
|
-
|
|
37238
|
-
|
|
37239
|
-
|
|
37240
|
-
|
|
37241
|
-
|
|
37242
|
-
|
|
37243
|
-
|
|
37244
|
-
$
|
|
37245
|
-
$
|
|
37640
|
+
const res = await collection().aggregate(
|
|
37641
|
+
[
|
|
37642
|
+
{
|
|
37643
|
+
$match: { ...query }
|
|
37644
|
+
},
|
|
37645
|
+
{
|
|
37646
|
+
$lookup: {
|
|
37647
|
+
from: "building-units",
|
|
37648
|
+
let: { unit: "$assignedUnit" },
|
|
37649
|
+
pipeline: [
|
|
37650
|
+
{
|
|
37651
|
+
$match: {
|
|
37652
|
+
$expr: {
|
|
37653
|
+
$eq: ["$_id", "$$unit"]
|
|
37654
|
+
}
|
|
37246
37655
|
}
|
|
37247
|
-
}
|
|
37248
|
-
|
|
37249
|
-
|
|
37250
|
-
|
|
37251
|
-
|
|
37252
|
-
|
|
37253
|
-
level: 1
|
|
37254
|
-
}
|
|
37255
|
-
}
|
|
37256
|
-
],
|
|
37257
|
-
as: "unit"
|
|
37258
|
-
}
|
|
37259
|
-
},
|
|
37260
|
-
{
|
|
37261
|
-
$unwind: { path: "$unit", preserveNullAndEmptyArrays: true }
|
|
37262
|
-
},
|
|
37263
|
-
{
|
|
37264
|
-
$lookup: {
|
|
37265
|
-
from: "building-levels",
|
|
37266
|
-
let: { level: "$unit.level" },
|
|
37267
|
-
pipeline: [
|
|
37268
|
-
{
|
|
37269
|
-
$match: {
|
|
37270
|
-
$expr: {
|
|
37271
|
-
$eq: ["$_id", "$$level"]
|
|
37656
|
+
},
|
|
37657
|
+
{
|
|
37658
|
+
$project: {
|
|
37659
|
+
_id: 1,
|
|
37660
|
+
name: 1,
|
|
37661
|
+
level: 1
|
|
37272
37662
|
}
|
|
37273
37663
|
}
|
|
37274
|
-
|
|
37275
|
-
|
|
37276
|
-
|
|
37277
|
-
|
|
37278
|
-
|
|
37279
|
-
|
|
37280
|
-
|
|
37281
|
-
|
|
37282
|
-
|
|
37283
|
-
|
|
37284
|
-
|
|
37285
|
-
|
|
37286
|
-
|
|
37287
|
-
|
|
37288
|
-
|
|
37289
|
-
|
|
37290
|
-
|
|
37291
|
-
|
|
37292
|
-
|
|
37293
|
-
|
|
37294
|
-
|
|
37295
|
-
|
|
37296
|
-
|
|
37297
|
-
|
|
37664
|
+
],
|
|
37665
|
+
as: "unit"
|
|
37666
|
+
}
|
|
37667
|
+
},
|
|
37668
|
+
{
|
|
37669
|
+
$unwind: { path: "$unit", preserveNullAndEmptyArrays: true }
|
|
37670
|
+
},
|
|
37671
|
+
{
|
|
37672
|
+
$lookup: {
|
|
37673
|
+
from: "building-levels",
|
|
37674
|
+
let: { level: "$unit.level" },
|
|
37675
|
+
pipeline: [
|
|
37676
|
+
{
|
|
37677
|
+
$match: {
|
|
37678
|
+
$expr: {
|
|
37679
|
+
$eq: ["$_id", "$$level"]
|
|
37680
|
+
}
|
|
37681
|
+
}
|
|
37682
|
+
},
|
|
37683
|
+
{
|
|
37684
|
+
$project: {
|
|
37685
|
+
_id: 1,
|
|
37686
|
+
level: 1,
|
|
37687
|
+
block: 1
|
|
37298
37688
|
}
|
|
37299
37689
|
}
|
|
37300
|
-
|
|
37301
|
-
|
|
37302
|
-
|
|
37303
|
-
|
|
37304
|
-
|
|
37305
|
-
|
|
37306
|
-
|
|
37307
|
-
|
|
37308
|
-
|
|
37309
|
-
|
|
37310
|
-
|
|
37311
|
-
|
|
37312
|
-
|
|
37313
|
-
|
|
37314
|
-
|
|
37315
|
-
|
|
37316
|
-
|
|
37317
|
-
|
|
37318
|
-
|
|
37319
|
-
|
|
37320
|
-
|
|
37321
|
-
|
|
37322
|
-
|
|
37690
|
+
],
|
|
37691
|
+
as: "level"
|
|
37692
|
+
}
|
|
37693
|
+
},
|
|
37694
|
+
{
|
|
37695
|
+
$unwind: { path: "$level", preserveNullAndEmptyArrays: true }
|
|
37696
|
+
},
|
|
37697
|
+
{
|
|
37698
|
+
$lookup: {
|
|
37699
|
+
from: "buildings",
|
|
37700
|
+
let: { block: "$level.block" },
|
|
37701
|
+
pipeline: [
|
|
37702
|
+
{
|
|
37703
|
+
$match: {
|
|
37704
|
+
$expr: {
|
|
37705
|
+
$eq: ["$_id", "$$block"]
|
|
37706
|
+
}
|
|
37707
|
+
}
|
|
37708
|
+
},
|
|
37709
|
+
{
|
|
37710
|
+
$project: {
|
|
37711
|
+
_id: 1,
|
|
37712
|
+
name: 1
|
|
37323
37713
|
}
|
|
37324
37714
|
}
|
|
37325
|
-
|
|
37326
|
-
|
|
37327
|
-
|
|
37328
|
-
|
|
37329
|
-
|
|
37715
|
+
],
|
|
37716
|
+
as: "building"
|
|
37717
|
+
}
|
|
37718
|
+
},
|
|
37719
|
+
{
|
|
37720
|
+
$unwind: { path: "$building", preserveNullAndEmptyArrays: true }
|
|
37721
|
+
},
|
|
37722
|
+
{
|
|
37723
|
+
$lookup: {
|
|
37724
|
+
from: "users",
|
|
37725
|
+
let: { id: "$userId" },
|
|
37726
|
+
pipeline: [
|
|
37727
|
+
{
|
|
37728
|
+
$match: {
|
|
37729
|
+
$expr: {
|
|
37730
|
+
$eq: ["$_id", "$$id"]
|
|
37731
|
+
}
|
|
37732
|
+
}
|
|
37733
|
+
},
|
|
37734
|
+
{
|
|
37735
|
+
$project: {
|
|
37736
|
+
givenName: 1,
|
|
37737
|
+
surname: 1
|
|
37738
|
+
}
|
|
37330
37739
|
}
|
|
37331
|
-
|
|
37332
|
-
|
|
37333
|
-
|
|
37334
|
-
}
|
|
37335
|
-
|
|
37336
|
-
|
|
37337
|
-
|
|
37338
|
-
|
|
37339
|
-
|
|
37340
|
-
|
|
37341
|
-
|
|
37342
|
-
|
|
37343
|
-
|
|
37344
|
-
|
|
37345
|
-
|
|
37346
|
-
|
|
37347
|
-
|
|
37348
|
-
|
|
37349
|
-
|
|
37350
|
-
|
|
37351
|
-
|
|
37352
|
-
|
|
37353
|
-
|
|
37354
|
-
|
|
37355
|
-
|
|
37356
|
-
|
|
37357
|
-
|
|
37358
|
-
|
|
37740
|
+
],
|
|
37741
|
+
as: "user"
|
|
37742
|
+
}
|
|
37743
|
+
},
|
|
37744
|
+
{
|
|
37745
|
+
$unwind: { path: "$user", preserveNullAndEmptyArrays: true }
|
|
37746
|
+
},
|
|
37747
|
+
{
|
|
37748
|
+
$match: { ...searchQuery }
|
|
37749
|
+
},
|
|
37750
|
+
{
|
|
37751
|
+
$facet: {
|
|
37752
|
+
data: [
|
|
37753
|
+
{ $skip: page * limit },
|
|
37754
|
+
{ $limit: limit },
|
|
37755
|
+
{
|
|
37756
|
+
$project: {
|
|
37757
|
+
_id: 1,
|
|
37758
|
+
cardNo: 1,
|
|
37759
|
+
accessLevel: 1,
|
|
37760
|
+
liftAccessLevel: 1,
|
|
37761
|
+
replacementStatus: 1,
|
|
37762
|
+
remarks: 1,
|
|
37763
|
+
block: "$building.name",
|
|
37764
|
+
level: "$level.level",
|
|
37765
|
+
unit: "$unit.name",
|
|
37766
|
+
user: "$user"
|
|
37767
|
+
}
|
|
37359
37768
|
}
|
|
37360
|
-
|
|
37361
|
-
|
|
37362
|
-
|
|
37769
|
+
],
|
|
37770
|
+
totalCount: [{ $count: "count" }]
|
|
37771
|
+
}
|
|
37363
37772
|
}
|
|
37364
|
-
|
|
37365
|
-
|
|
37773
|
+
],
|
|
37774
|
+
{ allowDiskUse: true }
|
|
37775
|
+
).toArray();
|
|
37366
37776
|
const count = res[0]?.totalCount[0] ? res[0].totalCount[0].count : 0;
|
|
37367
37777
|
const pagination = paginate39(res[0].data, page, limit, count);
|
|
37368
37778
|
return pagination;
|
|
@@ -37374,7 +37784,10 @@ function UseAccessManagementRepo() {
|
|
|
37374
37784
|
try {
|
|
37375
37785
|
const { site } = params;
|
|
37376
37786
|
const siteId = new ObjectId90(site);
|
|
37377
|
-
const res = await collectionName("entrypass-settings").findOne(
|
|
37787
|
+
const res = await collectionName("entrypass-settings").findOne(
|
|
37788
|
+
{ site: siteId },
|
|
37789
|
+
{ allowDiskUse: true }
|
|
37790
|
+
);
|
|
37378
37791
|
return res;
|
|
37379
37792
|
} catch (error) {
|
|
37380
37793
|
throw new Error(error.message);
|
|
@@ -37384,13 +37797,19 @@ function UseAccessManagementRepo() {
|
|
|
37384
37797
|
const session = useAtlas76.getClient()?.startSession();
|
|
37385
37798
|
try {
|
|
37386
37799
|
const { dataJson, site } = params;
|
|
37387
|
-
const rawItems = JSON.parse(dataJson).filter(
|
|
37800
|
+
const rawItems = JSON.parse(dataJson).filter(
|
|
37801
|
+
(_, index) => index !== -1
|
|
37802
|
+
);
|
|
37388
37803
|
const items = await Promise.all(
|
|
37389
37804
|
rawItems.map(async (item) => {
|
|
37390
37805
|
const date = new Date(item["startDate (format MM/DD/YYYY)"]);
|
|
37391
37806
|
const endDate = new Date(date.setFullYear(date.getFullYear() + 10));
|
|
37392
|
-
const cardNumber = String(
|
|
37393
|
-
|
|
37807
|
+
const cardNumber = String(
|
|
37808
|
+
Number(item["cardNo (number 0-65535 ex. 301)"] || 0)
|
|
37809
|
+
).padStart(6, "0");
|
|
37810
|
+
const facilityCode = String(
|
|
37811
|
+
Number(item["facilityCode (number 0-255 ex. 11)"] || 0)
|
|
37812
|
+
).padStart(4, "0");
|
|
37394
37813
|
const pin = item["pin (number 6 digits only)"] ? item["pin (number 6 digits only)"].toString().padStart(6, "0") : "123456";
|
|
37395
37814
|
const match = item["accessLevel (number ex. 1)"];
|
|
37396
37815
|
const accessLevel = match ? match : null;
|
|
@@ -37421,7 +37840,10 @@ function UseAccessManagementRepo() {
|
|
|
37421
37840
|
});
|
|
37422
37841
|
})
|
|
37423
37842
|
);
|
|
37424
|
-
const result = await collection().insertMany(items, {
|
|
37843
|
+
const result = await collection().insertMany(items, {
|
|
37844
|
+
session,
|
|
37845
|
+
ordered: false
|
|
37846
|
+
});
|
|
37425
37847
|
const mapping = items.map((item, i) => ({
|
|
37426
37848
|
cardNo: item.cardNo,
|
|
37427
37849
|
insertedId: result.insertedIds[i]
|
|
@@ -37436,8 +37858,19 @@ function UseAccessManagementRepo() {
|
|
|
37436
37858
|
let isAborted = false;
|
|
37437
37859
|
try {
|
|
37438
37860
|
await session?.startTransaction();
|
|
37439
|
-
const {
|
|
37440
|
-
|
|
37861
|
+
const {
|
|
37862
|
+
units,
|
|
37863
|
+
quantity,
|
|
37864
|
+
type,
|
|
37865
|
+
site,
|
|
37866
|
+
userType,
|
|
37867
|
+
accessLevel,
|
|
37868
|
+
liftAccessLevel
|
|
37869
|
+
} = params;
|
|
37870
|
+
const [convertedUnits, convertedSite] = await Promise.all([
|
|
37871
|
+
Promise.all(units.map((id) => new ObjectId90(id))),
|
|
37872
|
+
new ObjectId90(site)
|
|
37873
|
+
]);
|
|
37441
37874
|
const totalRequired = quantity * convertedUnits.length;
|
|
37442
37875
|
const availableCards = await collection().find({
|
|
37443
37876
|
assignedUnit: null,
|
|
@@ -37457,16 +37890,18 @@ function UseAccessManagementRepo() {
|
|
|
37457
37890
|
message: `Insufficient ${type} access cards. Need ${totalRequired}, but only ${availableCards.length} available.`
|
|
37458
37891
|
};
|
|
37459
37892
|
}
|
|
37460
|
-
const bulkUpdates = availableCards.map(
|
|
37461
|
-
|
|
37462
|
-
|
|
37463
|
-
|
|
37464
|
-
|
|
37465
|
-
|
|
37893
|
+
const bulkUpdates = availableCards.map(
|
|
37894
|
+
(card, index) => ({
|
|
37895
|
+
updateOne: {
|
|
37896
|
+
filter: { _id: card._id },
|
|
37897
|
+
update: {
|
|
37898
|
+
$set: {
|
|
37899
|
+
assignedUnit: convertedUnits[Math.floor(index / quantity)]
|
|
37900
|
+
}
|
|
37466
37901
|
}
|
|
37467
37902
|
}
|
|
37468
|
-
}
|
|
37469
|
-
|
|
37903
|
+
})
|
|
37904
|
+
);
|
|
37470
37905
|
await collection().bulkWrite(bulkUpdates, { session });
|
|
37471
37906
|
await session?.commitTransaction();
|
|
37472
37907
|
return {
|
|
@@ -37487,7 +37922,18 @@ function UseAccessManagementRepo() {
|
|
|
37487
37922
|
try {
|
|
37488
37923
|
const { cardId, remarks } = params;
|
|
37489
37924
|
const id = new ObjectId90(cardId);
|
|
37490
|
-
const result = await collection().findOneAndUpdate(
|
|
37925
|
+
const result = await collection().findOneAndUpdate(
|
|
37926
|
+
{ _id: id },
|
|
37927
|
+
{
|
|
37928
|
+
$set: {
|
|
37929
|
+
isActivated: false,
|
|
37930
|
+
updatedAt: /* @__PURE__ */ new Date(),
|
|
37931
|
+
remarks,
|
|
37932
|
+
requestDate: /* @__PURE__ */ new Date()
|
|
37933
|
+
}
|
|
37934
|
+
},
|
|
37935
|
+
{ returnDocument: "after" }
|
|
37936
|
+
);
|
|
37491
37937
|
return result;
|
|
37492
37938
|
} catch (error) {
|
|
37493
37939
|
throw new Error(error.message);
|
|
@@ -37548,7 +37994,13 @@ function UseAccessManagementRepo() {
|
|
|
37548
37994
|
const { site, payload } = params;
|
|
37549
37995
|
const id = new ObjectId90(site);
|
|
37550
37996
|
const highestCardNo = await collection().aggregate([
|
|
37551
|
-
{
|
|
37997
|
+
{
|
|
37998
|
+
$match: {
|
|
37999
|
+
site: id,
|
|
38000
|
+
type: "NFC" /* NFC */,
|
|
38001
|
+
userType: "Visitor/Resident" /* DEFAULT */
|
|
38002
|
+
}
|
|
38003
|
+
},
|
|
37552
38004
|
{
|
|
37553
38005
|
$addFields: {
|
|
37554
38006
|
qrTagCardNoNumeric: { $toInt: "$qrTagCardNo" }
|
|
@@ -37568,14 +38020,19 @@ function UseAccessManagementRepo() {
|
|
|
37568
38020
|
if (highestCardNo.length > 0) {
|
|
37569
38021
|
start = highestCardNo[0].qrTagCardNoNumeric || 0;
|
|
37570
38022
|
}
|
|
37571
|
-
const nextCardNumbers = Array.from(
|
|
38023
|
+
const nextCardNumbers = Array.from(
|
|
38024
|
+
{ length: payload.length },
|
|
38025
|
+
(_, i) => String(start + i + 1).padStart(5, "0")
|
|
38026
|
+
);
|
|
37572
38027
|
const bulkOps = await Promise.all(
|
|
37573
38028
|
payload.map(async (doc, index) => {
|
|
37574
38029
|
const id2 = new ObjectId90(doc._id);
|
|
37575
38030
|
return {
|
|
37576
38031
|
updateOne: {
|
|
37577
38032
|
filter: { _id: id2 },
|
|
37578
|
-
update: {
|
|
38033
|
+
update: {
|
|
38034
|
+
$set: { qrTag: doc.qrTag, qrTagCardNo: nextCardNumbers[index] }
|
|
38035
|
+
}
|
|
37579
38036
|
}
|
|
37580
38037
|
};
|
|
37581
38038
|
})
|
|
@@ -37617,7 +38074,11 @@ function UseAccessManagementRepo() {
|
|
|
37617
38074
|
{
|
|
37618
38075
|
$addFields: {
|
|
37619
38076
|
extractedCardNo: {
|
|
37620
|
-
$substr: [
|
|
38077
|
+
$substr: [
|
|
38078
|
+
"$cardNo",
|
|
38079
|
+
{ $subtract: [{ $strLenCP: "$cardNo" }, 5] },
|
|
38080
|
+
5
|
|
38081
|
+
]
|
|
37621
38082
|
}
|
|
37622
38083
|
}
|
|
37623
38084
|
},
|
|
@@ -37655,7 +38116,11 @@ function UseAccessManagementRepo() {
|
|
|
37655
38116
|
},
|
|
37656
38117
|
{
|
|
37657
38118
|
$facet: {
|
|
37658
|
-
items: [
|
|
38119
|
+
items: [
|
|
38120
|
+
{ $skip: page * limit },
|
|
38121
|
+
{ $limit: limit },
|
|
38122
|
+
{ $project: { cardNo: 1 } }
|
|
38123
|
+
],
|
|
37659
38124
|
totalCounts: [{ $count: "count" }]
|
|
37660
38125
|
}
|
|
37661
38126
|
}
|
|
@@ -37666,7 +38131,9 @@ function UseAccessManagementRepo() {
|
|
|
37666
38131
|
_id: unitId
|
|
37667
38132
|
}
|
|
37668
38133
|
},
|
|
37669
|
-
{
|
|
38134
|
+
{
|
|
38135
|
+
$project: { _id: 1, name: 1, buildingName: 1, block: 1, level: 1 }
|
|
38136
|
+
},
|
|
37670
38137
|
{
|
|
37671
38138
|
$lookup: {
|
|
37672
38139
|
from: "building-levels",
|
|
@@ -37754,7 +38221,18 @@ function UseAccessManagementRepo() {
|
|
|
37754
38221
|
items: [
|
|
37755
38222
|
{ $skip: 0 },
|
|
37756
38223
|
{ $limit: 1 },
|
|
37757
|
-
{
|
|
38224
|
+
{
|
|
38225
|
+
$project: {
|
|
38226
|
+
_id: -1,
|
|
38227
|
+
accessLevel: 1,
|
|
38228
|
+
accessGroup: 1,
|
|
38229
|
+
userType: 1,
|
|
38230
|
+
doorName: 1,
|
|
38231
|
+
liftName: 1,
|
|
38232
|
+
liftAccessLevel: 1,
|
|
38233
|
+
isLiftCard: 1
|
|
38234
|
+
}
|
|
38235
|
+
}
|
|
37758
38236
|
]
|
|
37759
38237
|
}
|
|
37760
38238
|
}
|
|
@@ -37803,13 +38281,25 @@ function UseAccessManagementRepo() {
|
|
|
37803
38281
|
cardsToAttach = [...cardsId];
|
|
37804
38282
|
} else if (type === "NFC" /* NFC */) {
|
|
37805
38283
|
if (nfcCards && nfcCards.length > 0) {
|
|
37806
|
-
const objectIds = nfcCards.map(
|
|
38284
|
+
const objectIds = nfcCards.map(
|
|
38285
|
+
(card) => new ObjectId90(card._id)
|
|
38286
|
+
);
|
|
37807
38287
|
cards = await collection().find({ _id: { $in: objectIds } }).toArray();
|
|
37808
|
-
const nfcList = objectIds.map((card) => ({
|
|
38288
|
+
const nfcList = objectIds.map((card) => ({
|
|
38289
|
+
_id: card,
|
|
38290
|
+
status: "In use",
|
|
38291
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
38292
|
+
}));
|
|
37809
38293
|
cardsToAttach = [...nfcList];
|
|
37810
38294
|
}
|
|
37811
38295
|
}
|
|
37812
|
-
const result = await collectionName(
|
|
38296
|
+
const result = await collectionName(
|
|
38297
|
+
"visitor.transactions"
|
|
38298
|
+
).findOneAndUpdate(
|
|
38299
|
+
{ _id: visitorId },
|
|
38300
|
+
{ $push: { cards: cardsToAttach } },
|
|
38301
|
+
{ session, returnDocument: "after" }
|
|
38302
|
+
);
|
|
37813
38303
|
const updatedVisitor = result?._id;
|
|
37814
38304
|
const assignCards = cards.map((card) => card._id);
|
|
37815
38305
|
if (assignCards.length > 0) {
|
|
@@ -37865,10 +38355,18 @@ function UseAccessManagementRepo() {
|
|
|
37865
38355
|
liftAccessEndDate: formatEntryPassDate(item.liftAccessEndDate) || "19770510",
|
|
37866
38356
|
accessGroup: ag
|
|
37867
38357
|
};
|
|
37868
|
-
return readTemplate(
|
|
38358
|
+
return readTemplate(
|
|
38359
|
+
`${item.accessLevel !== null ? "add-card" : "add-card-lift"}`,
|
|
38360
|
+
{ ...command }
|
|
38361
|
+
);
|
|
37869
38362
|
}).flat();
|
|
37870
|
-
const response = await sendCommand(
|
|
37871
|
-
|
|
38363
|
+
const response = await sendCommand(
|
|
38364
|
+
commands.join("").toString(),
|
|
38365
|
+
acm_url
|
|
38366
|
+
);
|
|
38367
|
+
serverResult = await parseStringPromise2(response, {
|
|
38368
|
+
explicitArray: false
|
|
38369
|
+
});
|
|
37872
38370
|
if (result && serverResult.RESULT.$.STCODE !== "0") {
|
|
37873
38371
|
throw new Error("Command failed, server error.");
|
|
37874
38372
|
}
|
|
@@ -37917,7 +38415,10 @@ function UseAccessManagementRepo() {
|
|
|
37917
38415
|
try {
|
|
37918
38416
|
await session?.startTransaction();
|
|
37919
38417
|
const userId = new ObjectId90(params.userId);
|
|
37920
|
-
const result = await collection().updateMany(
|
|
38418
|
+
const result = await collection().updateMany(
|
|
38419
|
+
{ userId },
|
|
38420
|
+
{ $set: { userId: null, status: "Available", updatedAt: /* @__PURE__ */ new Date() } }
|
|
38421
|
+
);
|
|
37921
38422
|
await session?.commitTransaction();
|
|
37922
38423
|
return result;
|
|
37923
38424
|
} catch (error) {
|
|
@@ -37961,7 +38462,15 @@ function UseAccessManagementRepo() {
|
|
|
37961
38462
|
foreignField: "level",
|
|
37962
38463
|
pipeline: [
|
|
37963
38464
|
{ $match: { status: { $ne: "deleted" } } },
|
|
37964
|
-
{
|
|
38465
|
+
{
|
|
38466
|
+
$project: {
|
|
38467
|
+
_id: 1,
|
|
38468
|
+
name: 1,
|
|
38469
|
+
buildingName: 1,
|
|
38470
|
+
level: 1,
|
|
38471
|
+
block: 1
|
|
38472
|
+
}
|
|
38473
|
+
}
|
|
37965
38474
|
],
|
|
37966
38475
|
as: "units"
|
|
37967
38476
|
}
|
|
@@ -37982,11 +38491,20 @@ function UseAccessManagementRepo() {
|
|
|
37982
38491
|
throw new Error(error.message);
|
|
37983
38492
|
}
|
|
37984
38493
|
}
|
|
37985
|
-
async function getTransactionsRepo({
|
|
38494
|
+
async function getTransactionsRepo({
|
|
38495
|
+
page = 1,
|
|
38496
|
+
limit = 10,
|
|
38497
|
+
site,
|
|
38498
|
+
cardNo,
|
|
38499
|
+
url
|
|
38500
|
+
}) {
|
|
37986
38501
|
page = page ? page - 1 : 0;
|
|
37987
38502
|
site = new ObjectId90(site);
|
|
37988
38503
|
try {
|
|
37989
|
-
let index = await collectionName("access-card-transactions").findOne(
|
|
38504
|
+
let index = await collectionName("access-card-transactions").findOne(
|
|
38505
|
+
{},
|
|
38506
|
+
{ sort: { index: -1 } }
|
|
38507
|
+
);
|
|
37990
38508
|
index = index ? index.index : 0;
|
|
37991
38509
|
const response = await getTransactions(index, url);
|
|
37992
38510
|
if (response && Array.isArray(response.items) && response.items.length > 0) {
|
|
@@ -37995,7 +38513,9 @@ function UseAccessManagementRepo() {
|
|
|
37995
38513
|
data: JSON.parse(item.data),
|
|
37996
38514
|
timestamp: item.timestamp
|
|
37997
38515
|
}));
|
|
37998
|
-
result2 = result2.filter(
|
|
38516
|
+
result2 = result2.filter(
|
|
38517
|
+
(item) => item.data.Event.ETYPE === "0" && item.data.Event.CARDNO !== ""
|
|
38518
|
+
);
|
|
37999
38519
|
if (result2.length > 0) {
|
|
38000
38520
|
const transactions = result2.map(
|
|
38001
38521
|
(item) => new MAccessCardTransaction({
|
|
@@ -38006,11 +38526,16 @@ function UseAccessManagementRepo() {
|
|
|
38006
38526
|
accessType: item.data.Event.DEVNAME,
|
|
38007
38527
|
accessStatus: item.data.Event.TRCODE,
|
|
38008
38528
|
description: item.data.Event.TRDESC,
|
|
38009
|
-
accessTime: entryPassDate(
|
|
38529
|
+
accessTime: entryPassDate(
|
|
38530
|
+
item.data.Event.TRDATE,
|
|
38531
|
+
item.data.Event.TRTIME
|
|
38532
|
+
),
|
|
38010
38533
|
createdAt: /* @__PURE__ */ new Date()
|
|
38011
38534
|
})
|
|
38012
38535
|
);
|
|
38013
|
-
await collectionName("access-card-transactions").insertMany(
|
|
38536
|
+
await collectionName("access-card-transactions").insertMany(
|
|
38537
|
+
transactions
|
|
38538
|
+
);
|
|
38014
38539
|
}
|
|
38015
38540
|
}
|
|
38016
38541
|
const result = await collectionName("access-card-transactions").aggregate([
|
|
@@ -38081,7 +38606,11 @@ function UseAccessManagementRepo() {
|
|
|
38081
38606
|
{
|
|
38082
38607
|
$facet: {
|
|
38083
38608
|
totalCount: [{ $count: "count" }],
|
|
38084
|
-
items: [
|
|
38609
|
+
items: [
|
|
38610
|
+
{ $sort: { _id: -1 } },
|
|
38611
|
+
{ $skip: page * limit },
|
|
38612
|
+
{ $limit: limit }
|
|
38613
|
+
]
|
|
38085
38614
|
}
|
|
38086
38615
|
}
|
|
38087
38616
|
]).toArray();
|
|
@@ -38104,7 +38633,9 @@ function UseAccessManagementRepo() {
|
|
|
38104
38633
|
if (assignees.length < 1) {
|
|
38105
38634
|
throw new Error("No user to Assign.");
|
|
38106
38635
|
}
|
|
38107
|
-
assignees = assignees.map(
|
|
38636
|
+
assignees = assignees.map(
|
|
38637
|
+
(data) => new ObjectId90(data)
|
|
38638
|
+
);
|
|
38108
38639
|
unit = new ObjectId90(unit);
|
|
38109
38640
|
let availableCards = [];
|
|
38110
38641
|
let update = [];
|
|
@@ -38114,7 +38645,18 @@ function UseAccessManagementRepo() {
|
|
|
38114
38645
|
$match: {
|
|
38115
38646
|
$expr: {
|
|
38116
38647
|
$and: [
|
|
38117
|
-
{
|
|
38648
|
+
{
|
|
38649
|
+
$in: [
|
|
38650
|
+
unit,
|
|
38651
|
+
{
|
|
38652
|
+
$cond: [
|
|
38653
|
+
{ $isArray: "$assignedUnit" },
|
|
38654
|
+
"$assignedUnit",
|
|
38655
|
+
["$assignedUnit"]
|
|
38656
|
+
]
|
|
38657
|
+
}
|
|
38658
|
+
]
|
|
38659
|
+
},
|
|
38118
38660
|
{ $eq: ["$userId", null] },
|
|
38119
38661
|
{ $eq: ["$type", type] },
|
|
38120
38662
|
{ $eq: ["$isActivated", true] }
|
|
@@ -38131,7 +38673,10 @@ function UseAccessManagementRepo() {
|
|
|
38131
38673
|
card.staffNo = userId.toString().slice(-10);
|
|
38132
38674
|
return card;
|
|
38133
38675
|
});
|
|
38134
|
-
update = availableCards.slice(0, assignees.length).map((card, index) => ({
|
|
38676
|
+
update = availableCards.slice(0, assignees.length).map((card, index) => ({
|
|
38677
|
+
_id: card._id,
|
|
38678
|
+
userId: new ObjectId90(assignees[index])
|
|
38679
|
+
}));
|
|
38135
38680
|
const commands = cards.map((item, index) => {
|
|
38136
38681
|
let ag = null;
|
|
38137
38682
|
if (item.accessGroup !== void 0) {
|
|
@@ -38161,16 +38706,27 @@ function UseAccessManagementRepo() {
|
|
|
38161
38706
|
liftAccessEndDate: formatEntryPassDate(item.liftAccessEndDate) || "19770510",
|
|
38162
38707
|
accessGroup: ag
|
|
38163
38708
|
};
|
|
38164
|
-
return readTemplate(
|
|
38709
|
+
return readTemplate(
|
|
38710
|
+
`${item.accessLevel !== null ? "add-card" : "add-card-lift"}`,
|
|
38711
|
+
{ ...command }
|
|
38712
|
+
);
|
|
38165
38713
|
}).flat();
|
|
38166
38714
|
const response = await sendCommand(commands.join("").toString(), acm_url);
|
|
38167
|
-
const result = await parseStringPromise2(response, {
|
|
38715
|
+
const result = await parseStringPromise2(response, {
|
|
38716
|
+
explicitArray: false
|
|
38717
|
+
});
|
|
38168
38718
|
console.log("status code", result.RESULT.$.STCODE);
|
|
38169
38719
|
if (result && result.RESULT.$.STCODE !== "0") {
|
|
38170
38720
|
throw new Error("Command failed, server error.");
|
|
38171
38721
|
}
|
|
38172
38722
|
for (const { _id, userId } of update) {
|
|
38173
|
-
await collection().updateOne(
|
|
38723
|
+
await collection().updateOne(
|
|
38724
|
+
{ _id },
|
|
38725
|
+
{
|
|
38726
|
+
$set: { userId, staffNo: `STAFF-${userId.toString().slice(-10)}` }
|
|
38727
|
+
},
|
|
38728
|
+
{ session }
|
|
38729
|
+
);
|
|
38174
38730
|
}
|
|
38175
38731
|
await session?.commitTransaction();
|
|
38176
38732
|
return "Cards assigned successfully.";
|
|
@@ -38186,7 +38742,11 @@ function UseAccessManagementRepo() {
|
|
|
38186
38742
|
try {
|
|
38187
38743
|
session?.startTransaction();
|
|
38188
38744
|
const id = new ObjectId90(userId);
|
|
38189
|
-
await collection().updateMany(
|
|
38745
|
+
await collection().updateMany(
|
|
38746
|
+
{ userId: id },
|
|
38747
|
+
{ $set: { userId: null, status: "Available" } },
|
|
38748
|
+
{ session }
|
|
38749
|
+
);
|
|
38190
38750
|
session?.commitTransaction();
|
|
38191
38751
|
return "Successful Checkout";
|
|
38192
38752
|
} catch (error) {
|
|
@@ -38196,7 +38756,11 @@ function UseAccessManagementRepo() {
|
|
|
38196
38756
|
await session?.endSession();
|
|
38197
38757
|
}
|
|
38198
38758
|
}
|
|
38199
|
-
async function uploadTemplateRepo({
|
|
38759
|
+
async function uploadTemplateRepo({
|
|
38760
|
+
site,
|
|
38761
|
+
id,
|
|
38762
|
+
name
|
|
38763
|
+
}) {
|
|
38200
38764
|
site = new ObjectId90(site);
|
|
38201
38765
|
id = new ObjectId90(id);
|
|
38202
38766
|
try {
|
|
@@ -38209,6 +38773,46 @@ function UseAccessManagementRepo() {
|
|
|
38209
38773
|
throw new Error(error.message);
|
|
38210
38774
|
}
|
|
38211
38775
|
}
|
|
38776
|
+
async function getResidentsRepo({
|
|
38777
|
+
orgId,
|
|
38778
|
+
siteId,
|
|
38779
|
+
unitId
|
|
38780
|
+
}) {
|
|
38781
|
+
try {
|
|
38782
|
+
orgId = new ObjectId90(orgId);
|
|
38783
|
+
siteId = new ObjectId90(siteId);
|
|
38784
|
+
unitId = new ObjectId90(unitId);
|
|
38785
|
+
const result = await collectionName("users").aggregate([
|
|
38786
|
+
{
|
|
38787
|
+
$match: {
|
|
38788
|
+
$expr: {
|
|
38789
|
+
$and: [
|
|
38790
|
+
{ $eq: ["$defaultOrg", orgId] },
|
|
38791
|
+
{ $eq: ["$site", siteId] },
|
|
38792
|
+
{ $eq: ["$unitId", unitId] }
|
|
38793
|
+
]
|
|
38794
|
+
}
|
|
38795
|
+
}
|
|
38796
|
+
},
|
|
38797
|
+
{
|
|
38798
|
+
$project: {
|
|
38799
|
+
_id: 1,
|
|
38800
|
+
email: 1,
|
|
38801
|
+
unitName: 1,
|
|
38802
|
+
type: 1,
|
|
38803
|
+
status: 1,
|
|
38804
|
+
name: 1,
|
|
38805
|
+
defaultOrg: 1,
|
|
38806
|
+
site: 1,
|
|
38807
|
+
unitId: 1
|
|
38808
|
+
}
|
|
38809
|
+
}
|
|
38810
|
+
]).toArray();
|
|
38811
|
+
return result;
|
|
38812
|
+
} catch (error) {
|
|
38813
|
+
throw new Error(error.message);
|
|
38814
|
+
}
|
|
38815
|
+
}
|
|
38212
38816
|
return {
|
|
38213
38817
|
createIndexes,
|
|
38214
38818
|
createIndexForEntrypass,
|
|
@@ -38244,7 +38848,8 @@ function UseAccessManagementRepo() {
|
|
|
38244
38848
|
getTransactionsRepo,
|
|
38245
38849
|
assignMultipleCardsRepo,
|
|
38246
38850
|
visitorCheckoutRepo,
|
|
38247
|
-
uploadTemplateRepo
|
|
38851
|
+
uploadTemplateRepo,
|
|
38852
|
+
getResidentsRepo
|
|
38248
38853
|
};
|
|
38249
38854
|
}
|
|
38250
38855
|
|
|
@@ -38288,7 +38893,8 @@ function useAccessManagementSvc() {
|
|
|
38288
38893
|
getTransactionsRepo,
|
|
38289
38894
|
assignMultipleCardsRepo,
|
|
38290
38895
|
visitorCheckoutRepo,
|
|
38291
|
-
uploadTemplateRepo
|
|
38896
|
+
uploadTemplateRepo,
|
|
38897
|
+
getResidentsRepo
|
|
38292
38898
|
} = UseAccessManagementRepo();
|
|
38293
38899
|
const addPhysicalCardSvc = async (payload) => {
|
|
38294
38900
|
try {
|
|
@@ -38580,17 +39186,39 @@ function useAccessManagementSvc() {
|
|
|
38580
39186
|
throw new Error(err.message);
|
|
38581
39187
|
}
|
|
38582
39188
|
};
|
|
38583
|
-
const getTransactionsSvc = async ({
|
|
39189
|
+
const getTransactionsSvc = async ({
|
|
39190
|
+
page,
|
|
39191
|
+
limit,
|
|
39192
|
+
site,
|
|
39193
|
+
cardNo,
|
|
39194
|
+
url
|
|
39195
|
+
}) => {
|
|
38584
39196
|
try {
|
|
38585
|
-
const response = await getTransactionsRepo({
|
|
39197
|
+
const response = await getTransactionsRepo({
|
|
39198
|
+
page,
|
|
39199
|
+
limit,
|
|
39200
|
+
site,
|
|
39201
|
+
cardNo,
|
|
39202
|
+
url
|
|
39203
|
+
});
|
|
38586
39204
|
return response;
|
|
38587
39205
|
} catch (err) {
|
|
38588
39206
|
throw new Error(err.message);
|
|
38589
39207
|
}
|
|
38590
39208
|
};
|
|
38591
|
-
const assignMultipleCardsSvc = async ({
|
|
39209
|
+
const assignMultipleCardsSvc = async ({
|
|
39210
|
+
assignees,
|
|
39211
|
+
unit,
|
|
39212
|
+
type,
|
|
39213
|
+
acm_url
|
|
39214
|
+
}) => {
|
|
38592
39215
|
try {
|
|
38593
|
-
const response = await assignMultipleCardsRepo({
|
|
39216
|
+
const response = await assignMultipleCardsRepo({
|
|
39217
|
+
assignees,
|
|
39218
|
+
unit,
|
|
39219
|
+
type,
|
|
39220
|
+
acm_url
|
|
39221
|
+
});
|
|
38594
39222
|
return response;
|
|
38595
39223
|
} catch (err) {
|
|
38596
39224
|
throw new Error(err.message);
|
|
@@ -38604,7 +39232,11 @@ function useAccessManagementSvc() {
|
|
|
38604
39232
|
throw new Error(err.message);
|
|
38605
39233
|
}
|
|
38606
39234
|
};
|
|
38607
|
-
const uploadTemplateSvc = async ({
|
|
39235
|
+
const uploadTemplateSvc = async ({
|
|
39236
|
+
site,
|
|
39237
|
+
id,
|
|
39238
|
+
name
|
|
39239
|
+
}) => {
|
|
38608
39240
|
try {
|
|
38609
39241
|
const response = await uploadTemplateRepo({ site, id, name });
|
|
38610
39242
|
return response;
|
|
@@ -38612,6 +39244,18 @@ function useAccessManagementSvc() {
|
|
|
38612
39244
|
throw new Error(err.message);
|
|
38613
39245
|
}
|
|
38614
39246
|
};
|
|
39247
|
+
const getResidentsSvc = async ({
|
|
39248
|
+
orgId,
|
|
39249
|
+
siteId,
|
|
39250
|
+
unitId
|
|
39251
|
+
}) => {
|
|
39252
|
+
try {
|
|
39253
|
+
const response = await getResidentsRepo({ orgId, siteId, unitId });
|
|
39254
|
+
return response;
|
|
39255
|
+
} catch (err) {
|
|
39256
|
+
throw new Error(err.message);
|
|
39257
|
+
}
|
|
39258
|
+
};
|
|
38615
39259
|
return {
|
|
38616
39260
|
addPhysicalCardSvc,
|
|
38617
39261
|
addNonPhysicalCardSvc,
|
|
@@ -38650,7 +39294,8 @@ function useAccessManagementSvc() {
|
|
|
38650
39294
|
getTransactionsSvc,
|
|
38651
39295
|
assignMultipleCardsSvc,
|
|
38652
39296
|
visitorCheckoutSvc,
|
|
38653
|
-
uploadTemplateSvc
|
|
39297
|
+
uploadTemplateSvc,
|
|
39298
|
+
getResidentsSvc
|
|
38654
39299
|
};
|
|
38655
39300
|
}
|
|
38656
39301
|
|
|
@@ -38694,7 +39339,8 @@ function useAccessManagementController() {
|
|
|
38694
39339
|
getTransactionsSvc,
|
|
38695
39340
|
assignMultipleCardsSvc,
|
|
38696
39341
|
visitorCheckoutSvc,
|
|
38697
|
-
uploadTemplateSvc
|
|
39342
|
+
uploadTemplateSvc,
|
|
39343
|
+
getResidentsSvc
|
|
38698
39344
|
} = useAccessManagementSvc();
|
|
38699
39345
|
const addPhysicalCard = async (req, res) => {
|
|
38700
39346
|
try {
|
|
@@ -38943,11 +39589,25 @@ function useAccessManagementController() {
|
|
|
38943
39589
|
search: Joi86.string().optional().allow("", null),
|
|
38944
39590
|
userType: Joi86.string().required()
|
|
38945
39591
|
});
|
|
38946
|
-
const { error } = schema2.validate({
|
|
39592
|
+
const { error } = schema2.validate({
|
|
39593
|
+
page,
|
|
39594
|
+
limit,
|
|
39595
|
+
site,
|
|
39596
|
+
organization,
|
|
39597
|
+
search,
|
|
39598
|
+
userType
|
|
39599
|
+
});
|
|
38947
39600
|
if (error) {
|
|
38948
39601
|
return res.status(400).json({ message: error.message });
|
|
38949
39602
|
}
|
|
38950
|
-
const result = await userTypeAccessCardsSvc({
|
|
39603
|
+
const result = await userTypeAccessCardsSvc({
|
|
39604
|
+
page,
|
|
39605
|
+
limit,
|
|
39606
|
+
search,
|
|
39607
|
+
site,
|
|
39608
|
+
organization,
|
|
39609
|
+
userType
|
|
39610
|
+
});
|
|
38951
39611
|
return res.status(200).json({ message: "Success", data: result });
|
|
38952
39612
|
} catch (error) {
|
|
38953
39613
|
return res.status(500).json({
|
|
@@ -38958,7 +39618,12 @@ function useAccessManagementController() {
|
|
|
38958
39618
|
};
|
|
38959
39619
|
const assignedAccessCards = async (req, res) => {
|
|
38960
39620
|
try {
|
|
38961
|
-
const {
|
|
39621
|
+
const {
|
|
39622
|
+
site,
|
|
39623
|
+
userType,
|
|
39624
|
+
type,
|
|
39625
|
+
search = ""
|
|
39626
|
+
} = req.query;
|
|
38962
39627
|
const schema2 = Joi86.object({
|
|
38963
39628
|
site: Joi86.string().hex().required(),
|
|
38964
39629
|
userType: Joi86.string().required(),
|
|
@@ -38969,7 +39634,12 @@ function useAccessManagementController() {
|
|
|
38969
39634
|
if (error) {
|
|
38970
39635
|
return res.status(400).json({ message: error.message });
|
|
38971
39636
|
}
|
|
38972
|
-
const result = await assignedAccessCardsSvc({
|
|
39637
|
+
const result = await assignedAccessCardsSvc({
|
|
39638
|
+
site,
|
|
39639
|
+
userType,
|
|
39640
|
+
type,
|
|
39641
|
+
search
|
|
39642
|
+
});
|
|
38973
39643
|
return res.status(200).json({ message: "Success", data: result });
|
|
38974
39644
|
} catch (error) {
|
|
38975
39645
|
return res.status(500).json({
|
|
@@ -39015,11 +39685,23 @@ function useAccessManagementController() {
|
|
|
39015
39685
|
userType: Joi86.string().valid(...Object.values(EAccessCardUserTypes)).required(),
|
|
39016
39686
|
type: Joi86.string().valid(...Object.values(EAccessCardTypes)).required()
|
|
39017
39687
|
});
|
|
39018
|
-
const { error } = schema2.validate({
|
|
39688
|
+
const { error } = schema2.validate({
|
|
39689
|
+
accessLevel,
|
|
39690
|
+
liftAccessLevel,
|
|
39691
|
+
site,
|
|
39692
|
+
userType,
|
|
39693
|
+
type
|
|
39694
|
+
});
|
|
39019
39695
|
if (error) {
|
|
39020
39696
|
return res.status(400).json({ message: error.message });
|
|
39021
39697
|
}
|
|
39022
|
-
const result = await accessandLiftCardsSvc({
|
|
39698
|
+
const result = await accessandLiftCardsSvc({
|
|
39699
|
+
accessLevel,
|
|
39700
|
+
liftAccessLevel,
|
|
39701
|
+
site,
|
|
39702
|
+
userType,
|
|
39703
|
+
type
|
|
39704
|
+
});
|
|
39023
39705
|
return res.status(200).json({ message: "Success", data: result });
|
|
39024
39706
|
} catch (error) {
|
|
39025
39707
|
return res.status(500).json({
|
|
@@ -39106,11 +39788,23 @@ function useAccessManagementController() {
|
|
|
39106
39788
|
issuedCardId: Joi86.string().required(),
|
|
39107
39789
|
userId: Joi86.string().hex().required()
|
|
39108
39790
|
});
|
|
39109
|
-
const { error } = schema2.validate({
|
|
39791
|
+
const { error } = schema2.validate({
|
|
39792
|
+
cardId,
|
|
39793
|
+
remarks,
|
|
39794
|
+
unitId,
|
|
39795
|
+
issuedCardId,
|
|
39796
|
+
userId
|
|
39797
|
+
});
|
|
39110
39798
|
if (error) {
|
|
39111
39799
|
return res.status(400).json({ message: error.message });
|
|
39112
39800
|
}
|
|
39113
|
-
const result = await cardReplacementSvc({
|
|
39801
|
+
const result = await cardReplacementSvc({
|
|
39802
|
+
cardId,
|
|
39803
|
+
remarks,
|
|
39804
|
+
unitId,
|
|
39805
|
+
issuedCardId,
|
|
39806
|
+
userId
|
|
39807
|
+
});
|
|
39114
39808
|
return res.status(200).json({ message: "Success", data: result });
|
|
39115
39809
|
} catch (error) {
|
|
39116
39810
|
return res.status(500).json({
|
|
@@ -39139,7 +39833,13 @@ function useAccessManagementController() {
|
|
|
39139
39833
|
if (error) {
|
|
39140
39834
|
return res.status(400).json({ message: error.message });
|
|
39141
39835
|
}
|
|
39142
|
-
const result = await visitorAccessCardsSvc({
|
|
39836
|
+
const result = await visitorAccessCardsSvc({
|
|
39837
|
+
site,
|
|
39838
|
+
page,
|
|
39839
|
+
limit,
|
|
39840
|
+
type,
|
|
39841
|
+
search
|
|
39842
|
+
});
|
|
39143
39843
|
return res.status(200).json({ message: "Success", data: result });
|
|
39144
39844
|
} catch (error) {
|
|
39145
39845
|
return res.status(500).json({
|
|
@@ -39168,11 +39868,27 @@ function useAccessManagementController() {
|
|
|
39168
39868
|
limit: Joi86.number().optional().default(10),
|
|
39169
39869
|
site: Joi86.string().hex().required()
|
|
39170
39870
|
});
|
|
39171
|
-
const { error } = schema2.validate({
|
|
39871
|
+
const { error } = schema2.validate({
|
|
39872
|
+
search,
|
|
39873
|
+
statusFilter,
|
|
39874
|
+
dateFrom,
|
|
39875
|
+
dateTo,
|
|
39876
|
+
page,
|
|
39877
|
+
limit,
|
|
39878
|
+
site
|
|
39879
|
+
});
|
|
39172
39880
|
if (error) {
|
|
39173
39881
|
return res.status(400).json({ message: error.message });
|
|
39174
39882
|
}
|
|
39175
|
-
const result = await getCardReplacementSvc({
|
|
39883
|
+
const result = await getCardReplacementSvc({
|
|
39884
|
+
site,
|
|
39885
|
+
page,
|
|
39886
|
+
limit,
|
|
39887
|
+
search,
|
|
39888
|
+
statusFilter,
|
|
39889
|
+
dateFrom,
|
|
39890
|
+
dateTo
|
|
39891
|
+
});
|
|
39176
39892
|
return res.status(200).json({ message: "Success", data: result });
|
|
39177
39893
|
} catch (error) {
|
|
39178
39894
|
return res.status(500).json({
|
|
@@ -39218,7 +39934,15 @@ function useAccessManagementController() {
|
|
|
39218
39934
|
};
|
|
39219
39935
|
const assignAccessCardToUnit = async (req, res) => {
|
|
39220
39936
|
try {
|
|
39221
|
-
const {
|
|
39937
|
+
const {
|
|
39938
|
+
units,
|
|
39939
|
+
type,
|
|
39940
|
+
quantity,
|
|
39941
|
+
site,
|
|
39942
|
+
userType,
|
|
39943
|
+
accessLevel,
|
|
39944
|
+
liftAccessLevel
|
|
39945
|
+
} = req.body;
|
|
39222
39946
|
const schema2 = Joi86.object({
|
|
39223
39947
|
units: Joi86.array().items(Joi86.string().hex()).required(),
|
|
39224
39948
|
quantity: Joi86.number().required(),
|
|
@@ -39228,11 +39952,27 @@ function useAccessManagementController() {
|
|
|
39228
39952
|
accessLevel: Joi86.string().optional().allow("", null),
|
|
39229
39953
|
liftAccessLevel: Joi86.string().optional().allow("", null)
|
|
39230
39954
|
});
|
|
39231
|
-
const { error } = schema2.validate({
|
|
39955
|
+
const { error } = schema2.validate({
|
|
39956
|
+
units,
|
|
39957
|
+
quantity,
|
|
39958
|
+
type,
|
|
39959
|
+
site,
|
|
39960
|
+
userType,
|
|
39961
|
+
accessLevel,
|
|
39962
|
+
liftAccessLevel
|
|
39963
|
+
});
|
|
39232
39964
|
if (error) {
|
|
39233
39965
|
return res.status(400).json({ message: error.message });
|
|
39234
39966
|
}
|
|
39235
|
-
const result = await assignAccessCardToUnitSvc({
|
|
39967
|
+
const result = await assignAccessCardToUnitSvc({
|
|
39968
|
+
units,
|
|
39969
|
+
quantity,
|
|
39970
|
+
type,
|
|
39971
|
+
site,
|
|
39972
|
+
userType,
|
|
39973
|
+
accessLevel,
|
|
39974
|
+
liftAccessLevel
|
|
39975
|
+
});
|
|
39236
39976
|
return res.status(200).json({ message: "Success", data: result });
|
|
39237
39977
|
} catch (error) {
|
|
39238
39978
|
return res.status(500).json({
|
|
@@ -39330,7 +40070,12 @@ function useAccessManagementController() {
|
|
|
39330
40070
|
};
|
|
39331
40071
|
const availableCardContractors = async (req, res) => {
|
|
39332
40072
|
try {
|
|
39333
|
-
const {
|
|
40073
|
+
const {
|
|
40074
|
+
siteId,
|
|
40075
|
+
unitId,
|
|
40076
|
+
page = 1,
|
|
40077
|
+
limit = 20
|
|
40078
|
+
} = req.query;
|
|
39334
40079
|
const type = req.params.type;
|
|
39335
40080
|
const schema2 = Joi86.object({
|
|
39336
40081
|
siteId: Joi86.string().hex().required(),
|
|
@@ -39343,7 +40088,13 @@ function useAccessManagementController() {
|
|
|
39343
40088
|
if (error) {
|
|
39344
40089
|
return res.status(400).json({ message: error.message });
|
|
39345
40090
|
}
|
|
39346
|
-
const result = await availableCardContractorsSvc({
|
|
40091
|
+
const result = await availableCardContractorsSvc({
|
|
40092
|
+
siteId,
|
|
40093
|
+
unitId,
|
|
40094
|
+
page,
|
|
40095
|
+
limit,
|
|
40096
|
+
type
|
|
40097
|
+
});
|
|
39347
40098
|
return res.status(200).json({ message: "Success", data: result });
|
|
39348
40099
|
} catch (error) {
|
|
39349
40100
|
return res.status(500).json({
|
|
@@ -39354,7 +40105,11 @@ function useAccessManagementController() {
|
|
|
39354
40105
|
};
|
|
39355
40106
|
const vmsgenerateQrCodes = async (req, res) => {
|
|
39356
40107
|
try {
|
|
39357
|
-
const {
|
|
40108
|
+
const {
|
|
40109
|
+
site,
|
|
40110
|
+
unitId,
|
|
40111
|
+
quantity = 100
|
|
40112
|
+
} = req.body;
|
|
39358
40113
|
const schema2 = Joi86.object({
|
|
39359
40114
|
site: Joi86.string().hex().length(24).required(),
|
|
39360
40115
|
unitId: Joi86.string().hex().length(24).required(),
|
|
@@ -39365,7 +40120,12 @@ function useAccessManagementController() {
|
|
|
39365
40120
|
return res.status(400).json({ message: error.message });
|
|
39366
40121
|
}
|
|
39367
40122
|
const normalizedUnitId = [unitId];
|
|
39368
|
-
const result = await vmsgenerateQrCodesSvc({
|
|
40123
|
+
const result = await vmsgenerateQrCodesSvc({
|
|
40124
|
+
site,
|
|
40125
|
+
unitId,
|
|
40126
|
+
normalizedUnitId,
|
|
40127
|
+
quantity
|
|
40128
|
+
});
|
|
39369
40129
|
return res.status(200).json({ message: "Success", data: result });
|
|
39370
40130
|
} catch (error) {
|
|
39371
40131
|
return res.status(500).json({
|
|
@@ -39376,21 +40136,50 @@ function useAccessManagementController() {
|
|
|
39376
40136
|
};
|
|
39377
40137
|
const addVisitorAccessCard = async (req, res) => {
|
|
39378
40138
|
try {
|
|
39379
|
-
const {
|
|
40139
|
+
const {
|
|
40140
|
+
site,
|
|
40141
|
+
unitId,
|
|
40142
|
+
quantity = 1,
|
|
40143
|
+
type,
|
|
40144
|
+
nfcCards,
|
|
40145
|
+
visitorId,
|
|
40146
|
+
acm_url
|
|
40147
|
+
} = req.body;
|
|
39380
40148
|
const schema2 = Joi86.object({
|
|
39381
40149
|
site: Joi86.string().hex().length(24).required(),
|
|
39382
40150
|
unitId: Joi86.string().hex().length(24).required(),
|
|
39383
40151
|
quantity: Joi86.number().allow(null, "").optional(),
|
|
39384
40152
|
type: Joi86.string().required(),
|
|
39385
|
-
nfcCards: Joi86.array().items(
|
|
40153
|
+
nfcCards: Joi86.array().items(
|
|
40154
|
+
Joi86.object({
|
|
40155
|
+
_id: Joi86.string().hex().required(),
|
|
40156
|
+
cardNo: Joi86.string().required()
|
|
40157
|
+
})
|
|
40158
|
+
).required(),
|
|
39386
40159
|
acm_url: Joi86.string().required(),
|
|
39387
40160
|
visitorId: Joi86.string().hex().length(24).required()
|
|
39388
40161
|
});
|
|
39389
|
-
const { error } = schema2.validate({
|
|
40162
|
+
const { error } = schema2.validate({
|
|
40163
|
+
site,
|
|
40164
|
+
unitId,
|
|
40165
|
+
quantity,
|
|
40166
|
+
type,
|
|
40167
|
+
nfcCards,
|
|
40168
|
+
visitorId,
|
|
40169
|
+
acm_url
|
|
40170
|
+
});
|
|
39390
40171
|
if (error) {
|
|
39391
40172
|
return res.status(400).json({ message: error.message });
|
|
39392
40173
|
}
|
|
39393
|
-
const result = await addVisitorAccessCardSvc({
|
|
40174
|
+
const result = await addVisitorAccessCardSvc({
|
|
40175
|
+
site,
|
|
40176
|
+
unitId,
|
|
40177
|
+
quantity,
|
|
40178
|
+
type,
|
|
40179
|
+
nfcCards,
|
|
40180
|
+
visitorId,
|
|
40181
|
+
acm_url
|
|
40182
|
+
});
|
|
39394
40183
|
return res.status(200).json({ message: "Success", data: result });
|
|
39395
40184
|
} catch (error) {
|
|
39396
40185
|
return res.status(500).json({
|
|
@@ -39438,7 +40227,11 @@ function useAccessManagementController() {
|
|
|
39438
40227
|
});
|
|
39439
40228
|
}
|
|
39440
40229
|
};
|
|
39441
|
-
const removeAccessCard = async ({
|
|
40230
|
+
const removeAccessCard = async ({
|
|
40231
|
+
cardNo,
|
|
40232
|
+
staffNo,
|
|
40233
|
+
url
|
|
40234
|
+
}) => {
|
|
39442
40235
|
return removeAccessGroup({ cardNo, staffNo, url });
|
|
39443
40236
|
};
|
|
39444
40237
|
const getBlockLevelAndUnitList = async (req, res) => {
|
|
@@ -39457,7 +40250,13 @@ function useAccessManagementController() {
|
|
|
39457
40250
|
}
|
|
39458
40251
|
};
|
|
39459
40252
|
const getTransactions2 = async (req, res) => {
|
|
39460
|
-
const {
|
|
40253
|
+
const {
|
|
40254
|
+
page = 1,
|
|
40255
|
+
limit = 10,
|
|
40256
|
+
site,
|
|
40257
|
+
cardNo,
|
|
40258
|
+
url
|
|
40259
|
+
} = req.query;
|
|
39461
40260
|
const schema2 = Joi86.object({
|
|
39462
40261
|
page: Joi86.number().required(),
|
|
39463
40262
|
limit: Joi86.number().optional().default(10),
|
|
@@ -39496,7 +40295,12 @@ function useAccessManagementController() {
|
|
|
39496
40295
|
if (error) {
|
|
39497
40296
|
throw new Error(`${error.message}`);
|
|
39498
40297
|
}
|
|
39499
|
-
const result = await assignMultipleCardsSvc({
|
|
40298
|
+
const result = await assignMultipleCardsSvc({
|
|
40299
|
+
assignees,
|
|
40300
|
+
unit,
|
|
40301
|
+
type,
|
|
40302
|
+
acm_url
|
|
40303
|
+
});
|
|
39500
40304
|
return res.status(200).json({ message: "Success", data: result });
|
|
39501
40305
|
} catch (error) {
|
|
39502
40306
|
return res.status(400).json({
|
|
@@ -39539,6 +40343,27 @@ function useAccessManagementController() {
|
|
|
39539
40343
|
});
|
|
39540
40344
|
}
|
|
39541
40345
|
};
|
|
40346
|
+
const getResidents = async (req, res) => {
|
|
40347
|
+
try {
|
|
40348
|
+
const { orgId, siteId, unitId } = req.query;
|
|
40349
|
+
const schema2 = Joi86.object({
|
|
40350
|
+
orgId: Joi86.string().hex().required(),
|
|
40351
|
+
siteId: Joi86.string().hex().required(),
|
|
40352
|
+
unitId: Joi86.string().hex().required()
|
|
40353
|
+
});
|
|
40354
|
+
const { error } = schema2.validate({ orgId, siteId, unitId });
|
|
40355
|
+
if (error) {
|
|
40356
|
+
return res.status(400).json({ message: error.message });
|
|
40357
|
+
}
|
|
40358
|
+
const result = await getResidentsSvc({ orgId, siteId, unitId });
|
|
40359
|
+
return res.status(200).json({ data: result });
|
|
40360
|
+
} catch (error) {
|
|
40361
|
+
return res.status(400).json({
|
|
40362
|
+
data: null,
|
|
40363
|
+
message: error.message
|
|
40364
|
+
});
|
|
40365
|
+
}
|
|
40366
|
+
};
|
|
39542
40367
|
return {
|
|
39543
40368
|
addPhysicalCard,
|
|
39544
40369
|
addNonPhysicalCard,
|
|
@@ -39575,7 +40400,8 @@ function useAccessManagementController() {
|
|
|
39575
40400
|
getTransactions: getTransactions2,
|
|
39576
40401
|
assignMultipleCards,
|
|
39577
40402
|
visitorCheckout,
|
|
39578
|
-
uploadTemplate
|
|
40403
|
+
uploadTemplate,
|
|
40404
|
+
getResidents
|
|
39579
40405
|
};
|
|
39580
40406
|
}
|
|
39581
40407
|
|
|
@@ -54279,10 +55105,734 @@ function usePostPrelovedController() {
|
|
|
54279
55105
|
updateStatus
|
|
54280
55106
|
};
|
|
54281
55107
|
}
|
|
55108
|
+
|
|
55109
|
+
// src/models/category-preloved.model.ts
|
|
55110
|
+
import Joi134 from "joi";
|
|
55111
|
+
import { ObjectId as ObjectId131 } from "mongodb";
|
|
55112
|
+
var schemaCategoryPreloved = Joi134.object({
|
|
55113
|
+
name: Joi134.string().required(),
|
|
55114
|
+
createdBy: Joi134.string().hex().optional().allow("", null),
|
|
55115
|
+
site: Joi134.string().hex().optional().allow("", null)
|
|
55116
|
+
});
|
|
55117
|
+
var schemaUpdateCategoryPreloved = Joi134.object({
|
|
55118
|
+
name: Joi134.string().optional().allow("", null),
|
|
55119
|
+
site: Joi134.string().hex().optional().allow("", null)
|
|
55120
|
+
});
|
|
55121
|
+
function MCategoryPreloved(value) {
|
|
55122
|
+
const { error } = schemaCategoryPreloved.validate(value);
|
|
55123
|
+
if (error) {
|
|
55124
|
+
throw new Error(error.details[0].message);
|
|
55125
|
+
}
|
|
55126
|
+
if (value.createdBy && typeof value.createdBy === "string") {
|
|
55127
|
+
try {
|
|
55128
|
+
value.createdBy = new ObjectId131(value.createdBy);
|
|
55129
|
+
} catch {
|
|
55130
|
+
throw new Error("Invalid createdBy ID.");
|
|
55131
|
+
}
|
|
55132
|
+
}
|
|
55133
|
+
if (value.site && typeof value.site === "string") {
|
|
55134
|
+
try {
|
|
55135
|
+
value.site = new ObjectId131(value.site);
|
|
55136
|
+
} catch {
|
|
55137
|
+
throw new Error("Invalid site ID.");
|
|
55138
|
+
}
|
|
55139
|
+
}
|
|
55140
|
+
return {
|
|
55141
|
+
name: value.name ?? "",
|
|
55142
|
+
createdBy: value.createdBy ?? "",
|
|
55143
|
+
site: value.site ?? null,
|
|
55144
|
+
createdAt: value.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
55145
|
+
updatedAt: value.updatedAt ?? null
|
|
55146
|
+
};
|
|
55147
|
+
}
|
|
55148
|
+
|
|
55149
|
+
// src/repositories/category-preloved.repo.ts
|
|
55150
|
+
import {
|
|
55151
|
+
BadRequestError as BadRequestError212,
|
|
55152
|
+
InternalServerError as InternalServerError75,
|
|
55153
|
+
useAtlas as useAtlas118
|
|
55154
|
+
} from "@7365admin1/node-server-utils";
|
|
55155
|
+
import { ObjectId as ObjectId132 } from "mongodb";
|
|
55156
|
+
function useCategoryPrelovedRepo() {
|
|
55157
|
+
const db = useAtlas118.getDb();
|
|
55158
|
+
if (!db) {
|
|
55159
|
+
throw new InternalServerError75("Unable to connect to server.");
|
|
55160
|
+
}
|
|
55161
|
+
const CATEGORY_COLLECTION = "category-preloved";
|
|
55162
|
+
const collection = db.collection(CATEGORY_COLLECTION);
|
|
55163
|
+
async function getAll({
|
|
55164
|
+
search = "",
|
|
55165
|
+
site
|
|
55166
|
+
} = {}) {
|
|
55167
|
+
if (site) {
|
|
55168
|
+
try {
|
|
55169
|
+
site = new ObjectId132(site);
|
|
55170
|
+
} catch {
|
|
55171
|
+
throw new BadRequestError212("Invalid site ID format.");
|
|
55172
|
+
}
|
|
55173
|
+
}
|
|
55174
|
+
const query = {
|
|
55175
|
+
...site && { site },
|
|
55176
|
+
...search && { name: { $regex: search, $options: "i" } }
|
|
55177
|
+
};
|
|
55178
|
+
try {
|
|
55179
|
+
return await collection.find(query).sort({ name: 1 }).toArray();
|
|
55180
|
+
} catch (error) {
|
|
55181
|
+
console.error("Error in category-preloved getAll:", error);
|
|
55182
|
+
throw error;
|
|
55183
|
+
}
|
|
55184
|
+
}
|
|
55185
|
+
return { getAll };
|
|
55186
|
+
}
|
|
55187
|
+
|
|
55188
|
+
// src/controllers/category-preloved.controller.ts
|
|
55189
|
+
import { BadRequestError as BadRequestError213, logger as logger187 } from "@7365admin1/node-server-utils";
|
|
55190
|
+
import Joi135 from "joi";
|
|
55191
|
+
function useCategoryPrelovedController() {
|
|
55192
|
+
const { getAll: _getAll } = useCategoryPrelovedRepo();
|
|
55193
|
+
async function getAll(req, res, next) {
|
|
55194
|
+
const schema2 = Joi135.object({
|
|
55195
|
+
search: Joi135.string().optional().allow("", null),
|
|
55196
|
+
site: Joi135.string().hex().length(24).optional().allow("", null)
|
|
55197
|
+
});
|
|
55198
|
+
const { error, value } = schema2.validate(req.query, { abortEarly: false });
|
|
55199
|
+
if (error) {
|
|
55200
|
+
const messages = error.details.map((d) => d.message).join(", ");
|
|
55201
|
+
logger187.log({ level: "error", message: messages });
|
|
55202
|
+
next(new BadRequestError213(messages));
|
|
55203
|
+
return;
|
|
55204
|
+
}
|
|
55205
|
+
try {
|
|
55206
|
+
const data = await _getAll(value);
|
|
55207
|
+
res.status(200).json({ data });
|
|
55208
|
+
return;
|
|
55209
|
+
} catch (error2) {
|
|
55210
|
+
logger187.log({ level: "error", message: error2.message });
|
|
55211
|
+
next(error2);
|
|
55212
|
+
return;
|
|
55213
|
+
}
|
|
55214
|
+
}
|
|
55215
|
+
return { getAll };
|
|
55216
|
+
}
|
|
55217
|
+
|
|
55218
|
+
// src/models/subcategory-preloved.model.ts
|
|
55219
|
+
import Joi136 from "joi";
|
|
55220
|
+
import { ObjectId as ObjectId133 } from "mongodb";
|
|
55221
|
+
var schemaSubcategoryPreloved = Joi136.object({
|
|
55222
|
+
name: Joi136.string().required(),
|
|
55223
|
+
createdBy: Joi136.string().hex().optional().allow("", null),
|
|
55224
|
+
site: Joi136.string().hex().optional().allow("", null),
|
|
55225
|
+
category_id: Joi136.string().hex().required()
|
|
55226
|
+
});
|
|
55227
|
+
var schemaUpdateSubcategoryPreloved = Joi136.object({
|
|
55228
|
+
name: Joi136.string().optional().allow("", null),
|
|
55229
|
+
site: Joi136.string().hex().optional().allow("", null),
|
|
55230
|
+
category_id: Joi136.string().hex().optional().allow("", null)
|
|
55231
|
+
});
|
|
55232
|
+
function MSubcategoryPreloved(value) {
|
|
55233
|
+
const { error } = schemaSubcategoryPreloved.validate(value);
|
|
55234
|
+
if (error) {
|
|
55235
|
+
throw new Error(error.details[0].message);
|
|
55236
|
+
}
|
|
55237
|
+
if (value.createdBy && typeof value.createdBy === "string") {
|
|
55238
|
+
try {
|
|
55239
|
+
value.createdBy = new ObjectId133(value.createdBy);
|
|
55240
|
+
} catch {
|
|
55241
|
+
throw new Error("Invalid createdBy ID.");
|
|
55242
|
+
}
|
|
55243
|
+
}
|
|
55244
|
+
if (value.site && typeof value.site === "string") {
|
|
55245
|
+
try {
|
|
55246
|
+
value.site = new ObjectId133(value.site);
|
|
55247
|
+
} catch {
|
|
55248
|
+
throw new Error("Invalid site ID.");
|
|
55249
|
+
}
|
|
55250
|
+
}
|
|
55251
|
+
if (value.category_id && typeof value.category_id === "string") {
|
|
55252
|
+
try {
|
|
55253
|
+
value.category_id = new ObjectId133(value.category_id);
|
|
55254
|
+
} catch {
|
|
55255
|
+
throw new Error("Invalid category ID.");
|
|
55256
|
+
}
|
|
55257
|
+
}
|
|
55258
|
+
return {
|
|
55259
|
+
name: value.name ?? "",
|
|
55260
|
+
createdBy: value.createdBy ?? "",
|
|
55261
|
+
site: value.site ?? null,
|
|
55262
|
+
category_id: value.category_id ?? "",
|
|
55263
|
+
createdAt: value.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
55264
|
+
updatedAt: value.updatedAt ?? null
|
|
55265
|
+
};
|
|
55266
|
+
}
|
|
55267
|
+
|
|
55268
|
+
// src/repositories/subcategory-preloved.repo.ts
|
|
55269
|
+
import {
|
|
55270
|
+
BadRequestError as BadRequestError214,
|
|
55271
|
+
InternalServerError as InternalServerError76,
|
|
55272
|
+
useAtlas as useAtlas119
|
|
55273
|
+
} from "@7365admin1/node-server-utils";
|
|
55274
|
+
import { ObjectId as ObjectId134 } from "mongodb";
|
|
55275
|
+
function useSubcategoryPrelovedRepo() {
|
|
55276
|
+
const db = useAtlas119.getDb();
|
|
55277
|
+
if (!db) {
|
|
55278
|
+
throw new InternalServerError76("Unable to connect to server.");
|
|
55279
|
+
}
|
|
55280
|
+
const SUBCATEGORY_COLLECTION = "subcategory-preloved";
|
|
55281
|
+
const collection = db.collection(SUBCATEGORY_COLLECTION);
|
|
55282
|
+
async function getAll({
|
|
55283
|
+
search = "",
|
|
55284
|
+
site,
|
|
55285
|
+
category_id
|
|
55286
|
+
} = {}) {
|
|
55287
|
+
if (site) {
|
|
55288
|
+
try {
|
|
55289
|
+
site = new ObjectId134(site);
|
|
55290
|
+
} catch {
|
|
55291
|
+
throw new BadRequestError214("Invalid site ID format.");
|
|
55292
|
+
}
|
|
55293
|
+
}
|
|
55294
|
+
if (category_id) {
|
|
55295
|
+
try {
|
|
55296
|
+
category_id = new ObjectId134(category_id);
|
|
55297
|
+
} catch {
|
|
55298
|
+
throw new BadRequestError214("Invalid category ID format.");
|
|
55299
|
+
}
|
|
55300
|
+
}
|
|
55301
|
+
const query = {
|
|
55302
|
+
...site && { site },
|
|
55303
|
+
...category_id && { category_id },
|
|
55304
|
+
...search && { name: { $regex: search, $options: "i" } }
|
|
55305
|
+
};
|
|
55306
|
+
try {
|
|
55307
|
+
return await collection.find(query).sort({ name: 1 }).toArray();
|
|
55308
|
+
} catch (error) {
|
|
55309
|
+
throw error;
|
|
55310
|
+
}
|
|
55311
|
+
}
|
|
55312
|
+
return { getAll };
|
|
55313
|
+
}
|
|
55314
|
+
|
|
55315
|
+
// src/controllers/subcategory-preloved.controller.ts
|
|
55316
|
+
import { BadRequestError as BadRequestError215, logger as logger188 } from "@7365admin1/node-server-utils";
|
|
55317
|
+
import Joi137 from "joi";
|
|
55318
|
+
function useSubcategoryPrelovedController() {
|
|
55319
|
+
const { getAll: _getAll } = useSubcategoryPrelovedRepo();
|
|
55320
|
+
async function getAll(req, res, next) {
|
|
55321
|
+
const schema2 = Joi137.object({
|
|
55322
|
+
search: Joi137.string().optional().allow("", null),
|
|
55323
|
+
site: Joi137.string().hex().length(24).optional().allow("", null),
|
|
55324
|
+
category_id: Joi137.string().hex().length(24).optional().allow("", null)
|
|
55325
|
+
});
|
|
55326
|
+
const { error, value } = schema2.validate(req.query, { abortEarly: false });
|
|
55327
|
+
if (error) {
|
|
55328
|
+
const messages = error.details.map((d) => d.message).join(", ");
|
|
55329
|
+
logger188.log({ level: "error", message: messages });
|
|
55330
|
+
next(new BadRequestError215(messages));
|
|
55331
|
+
return;
|
|
55332
|
+
}
|
|
55333
|
+
try {
|
|
55334
|
+
const data = await _getAll(value);
|
|
55335
|
+
res.status(200).json({ data });
|
|
55336
|
+
return;
|
|
55337
|
+
} catch (error2) {
|
|
55338
|
+
logger188.log({ level: "error", message: error2.message });
|
|
55339
|
+
next(error2);
|
|
55340
|
+
return;
|
|
55341
|
+
}
|
|
55342
|
+
}
|
|
55343
|
+
return { getAll };
|
|
55344
|
+
}
|
|
55345
|
+
|
|
55346
|
+
// src/models/online-forms-v2.model.ts
|
|
55347
|
+
import Joi138 from "joi";
|
|
55348
|
+
import { ObjectId as ObjectId135 } from "mongodb";
|
|
55349
|
+
var FormEntryStatus = /* @__PURE__ */ ((FormEntryStatus2) => {
|
|
55350
|
+
FormEntryStatus2["ACTIVE"] = "active";
|
|
55351
|
+
FormEntryStatus2["INACTIVE"] = "inactive";
|
|
55352
|
+
FormEntryStatus2["DELETED"] = "deleted";
|
|
55353
|
+
return FormEntryStatus2;
|
|
55354
|
+
})(FormEntryStatus || {});
|
|
55355
|
+
var schemaFormEntry = Joi138.object({
|
|
55356
|
+
_id: Joi138.string().hex().optional().allow("", null),
|
|
55357
|
+
formType: Joi138.string().required(),
|
|
55358
|
+
fields: Joi138.object().pattern(
|
|
55359
|
+
Joi138.string(),
|
|
55360
|
+
Joi138.alternatives().try(
|
|
55361
|
+
Joi138.string(),
|
|
55362
|
+
Joi138.number(),
|
|
55363
|
+
Joi138.boolean(),
|
|
55364
|
+
Joi138.valid(null)
|
|
55365
|
+
)
|
|
55366
|
+
).required(),
|
|
55367
|
+
status: Joi138.string().optional().allow("", null),
|
|
55368
|
+
org: Joi138.string().hex().optional().allow("", null),
|
|
55369
|
+
site: Joi138.string().hex().optional().allow("", null),
|
|
55370
|
+
createdAt: Joi138.date().optional().allow("", null),
|
|
55371
|
+
updatedAt: Joi138.date().optional().allow("", null),
|
|
55372
|
+
deletedAt: Joi138.date().optional().allow("", null)
|
|
55373
|
+
});
|
|
55374
|
+
var schemaUpdateFormEntry = Joi138.object({
|
|
55375
|
+
_id: Joi138.string().hex().required(),
|
|
55376
|
+
formType: Joi138.string().optional().allow("", null),
|
|
55377
|
+
fields: Joi138.object().pattern(
|
|
55378
|
+
Joi138.string(),
|
|
55379
|
+
Joi138.alternatives().try(
|
|
55380
|
+
Joi138.string(),
|
|
55381
|
+
Joi138.number(),
|
|
55382
|
+
Joi138.boolean(),
|
|
55383
|
+
Joi138.valid(null)
|
|
55384
|
+
)
|
|
55385
|
+
).optional(),
|
|
55386
|
+
status: Joi138.string().optional().allow("", null),
|
|
55387
|
+
createdAt: Joi138.date().optional().allow("", null),
|
|
55388
|
+
updatedAt: Joi138.date().optional().allow("", null),
|
|
55389
|
+
deletedAt: Joi138.date().optional().allow("", null)
|
|
55390
|
+
});
|
|
55391
|
+
function MFormEntry(value) {
|
|
55392
|
+
const { error } = schemaFormEntry.validate(value);
|
|
55393
|
+
if (error) {
|
|
55394
|
+
throw new Error(error.details[0].message);
|
|
55395
|
+
}
|
|
55396
|
+
if (value._id && typeof value._id === "string") {
|
|
55397
|
+
try {
|
|
55398
|
+
value._id = new ObjectId135(value._id);
|
|
55399
|
+
} catch {
|
|
55400
|
+
throw new Error("Invalid ID.");
|
|
55401
|
+
}
|
|
55402
|
+
}
|
|
55403
|
+
if (value.org && typeof value.org === "string") {
|
|
55404
|
+
try {
|
|
55405
|
+
value.org = new ObjectId135(value.org);
|
|
55406
|
+
} catch {
|
|
55407
|
+
throw new Error("Invalid org ID.");
|
|
55408
|
+
}
|
|
55409
|
+
}
|
|
55410
|
+
if (value.site && typeof value.site === "string") {
|
|
55411
|
+
try {
|
|
55412
|
+
value.site = new ObjectId135(value.site);
|
|
55413
|
+
} catch {
|
|
55414
|
+
throw new Error("Invalid site ID.");
|
|
55415
|
+
}
|
|
55416
|
+
}
|
|
55417
|
+
return {
|
|
55418
|
+
_id: value._id,
|
|
55419
|
+
formType: value.formType,
|
|
55420
|
+
fields: value.fields,
|
|
55421
|
+
status: value.status,
|
|
55422
|
+
org: value.org,
|
|
55423
|
+
site: value.site,
|
|
55424
|
+
createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
|
|
55425
|
+
updatedAt: value.updatedAt ?? null,
|
|
55426
|
+
deletedAt: value.deletedAt ?? null
|
|
55427
|
+
};
|
|
55428
|
+
}
|
|
55429
|
+
|
|
55430
|
+
// src/repositories/online-forms-v2.repository.ts
|
|
55431
|
+
import {
|
|
55432
|
+
BadRequestError as BadRequestError216,
|
|
55433
|
+
InternalServerError as InternalServerError77,
|
|
55434
|
+
logger as logger189,
|
|
55435
|
+
useAtlas as useAtlas120,
|
|
55436
|
+
useCache as useCache69
|
|
55437
|
+
} from "@7365admin1/node-server-utils";
|
|
55438
|
+
var online_forms_namespace_collection = "online-forms";
|
|
55439
|
+
function useFormEntryRepo() {
|
|
55440
|
+
const db = useAtlas120.getDb();
|
|
55441
|
+
if (!db) {
|
|
55442
|
+
throw new InternalServerError77("Unable to connect to server.");
|
|
55443
|
+
}
|
|
55444
|
+
const collection = db.collection(online_forms_namespace_collection);
|
|
55445
|
+
const { delNamespace, getCache, setCache } = useCache69(
|
|
55446
|
+
online_forms_namespace_collection
|
|
55447
|
+
);
|
|
55448
|
+
async function createTextIndex() {
|
|
55449
|
+
try {
|
|
55450
|
+
await collection.createIndex({
|
|
55451
|
+
name: "text"
|
|
55452
|
+
});
|
|
55453
|
+
} catch (error) {
|
|
55454
|
+
throw new InternalServerError77(
|
|
55455
|
+
"Failed to create text index on online form."
|
|
55456
|
+
);
|
|
55457
|
+
}
|
|
55458
|
+
}
|
|
55459
|
+
async function add(value, session) {
|
|
55460
|
+
try {
|
|
55461
|
+
value = MFormEntry(value);
|
|
55462
|
+
const res = await collection.insertOne(value, { session });
|
|
55463
|
+
delNamespace().then(() => {
|
|
55464
|
+
logger189.info(
|
|
55465
|
+
`Cache cleared for namespace: ${online_forms_namespace_collection}`
|
|
55466
|
+
);
|
|
55467
|
+
}).catch((err) => {
|
|
55468
|
+
logger189.error(
|
|
55469
|
+
`Failed to clear cache for namespace: ${online_forms_namespace_collection}`,
|
|
55470
|
+
err
|
|
55471
|
+
);
|
|
55472
|
+
});
|
|
55473
|
+
return res.insertedId;
|
|
55474
|
+
} catch (error) {
|
|
55475
|
+
const isDuplicated = error.message.includes("duplicate");
|
|
55476
|
+
if (isDuplicated) {
|
|
55477
|
+
throw new BadRequestError216("Online Form already exists.");
|
|
55478
|
+
}
|
|
55479
|
+
throw error;
|
|
55480
|
+
}
|
|
55481
|
+
}
|
|
55482
|
+
return {
|
|
55483
|
+
add,
|
|
55484
|
+
createTextIndex
|
|
55485
|
+
};
|
|
55486
|
+
}
|
|
55487
|
+
|
|
55488
|
+
// src/controllers/online-forms-v2.controller.ts
|
|
55489
|
+
import { BadRequestError as BadRequestError217, logger as logger190 } from "@7365admin1/node-server-utils";
|
|
55490
|
+
import ExcelJS3 from "exceljs";
|
|
55491
|
+
import fs5 from "fs";
|
|
55492
|
+
function useFormEntryController() {
|
|
55493
|
+
const { add: _add } = useFormEntryRepo();
|
|
55494
|
+
function toCamelCase(str) {
|
|
55495
|
+
return str.replace(/\s(.)/g, (_, char) => char.toUpperCase()).replace(/\s+/g, "").replace(/^(.)/, (_, char) => char.toLowerCase());
|
|
55496
|
+
}
|
|
55497
|
+
function normalizeKeys(obj) {
|
|
55498
|
+
const normalized = {};
|
|
55499
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
55500
|
+
normalized[toCamelCase(key)] = value;
|
|
55501
|
+
}
|
|
55502
|
+
return normalized;
|
|
55503
|
+
}
|
|
55504
|
+
async function uploadFormEntrys(req, res, next) {
|
|
55505
|
+
try {
|
|
55506
|
+
if (!req.file) {
|
|
55507
|
+
next(new BadRequestError217("Excel file is required."));
|
|
55508
|
+
return;
|
|
55509
|
+
}
|
|
55510
|
+
const workbook = new ExcelJS3.Workbook();
|
|
55511
|
+
await workbook.xlsx.readFile(req.file.path);
|
|
55512
|
+
const worksheet = workbook.worksheets[0];
|
|
55513
|
+
if (!worksheet) {
|
|
55514
|
+
next(new BadRequestError217("No worksheet found in uploaded Excel file."));
|
|
55515
|
+
return;
|
|
55516
|
+
}
|
|
55517
|
+
const headerRow = worksheet.getRow(1);
|
|
55518
|
+
const headers = headerRow.values.slice(1).map((h) => String(h ?? "").trim());
|
|
55519
|
+
const fields = {};
|
|
55520
|
+
headers.forEach((header) => {
|
|
55521
|
+
fields[header] = null;
|
|
55522
|
+
});
|
|
55523
|
+
const formType = req.file.originalname.replace(/\.[^/.]+$/, "");
|
|
55524
|
+
const normalizedFields = normalizeKeys(fields);
|
|
55525
|
+
const payload = {
|
|
55526
|
+
formType,
|
|
55527
|
+
fields: normalizedFields,
|
|
55528
|
+
status: "active" /* ACTIVE */
|
|
55529
|
+
};
|
|
55530
|
+
const { error, value } = schemaFormEntry.validate(payload, {
|
|
55531
|
+
abortEarly: false
|
|
55532
|
+
});
|
|
55533
|
+
if (error) {
|
|
55534
|
+
const messages = error.details.map((d) => d.message).join(", ");
|
|
55535
|
+
logger190.log({ level: "error", message: messages });
|
|
55536
|
+
next(new BadRequestError217(messages));
|
|
55537
|
+
return;
|
|
55538
|
+
}
|
|
55539
|
+
const result = await _add(value);
|
|
55540
|
+
res.status(201).json(result);
|
|
55541
|
+
fs5.unlink(req.file.path, () => {
|
|
55542
|
+
});
|
|
55543
|
+
} catch (error) {
|
|
55544
|
+
logger190.log({ level: "error", message: error.message });
|
|
55545
|
+
next(error);
|
|
55546
|
+
}
|
|
55547
|
+
}
|
|
55548
|
+
return {
|
|
55549
|
+
uploadFormEntrys
|
|
55550
|
+
};
|
|
55551
|
+
}
|
|
55552
|
+
|
|
55553
|
+
// src/models/building-level.model.ts
|
|
55554
|
+
import { BadRequestError as BadRequestError218 } from "@7365admin1/node-server-utils";
|
|
55555
|
+
import { ObjectId as ObjectId136 } from "mongodb";
|
|
55556
|
+
import Joi139 from "joi";
|
|
55557
|
+
import { logger as logger191 } from "@7365admin1/node-server-utils";
|
|
55558
|
+
var BuildingLevelStatus = /* @__PURE__ */ ((BuildingLevelStatus2) => {
|
|
55559
|
+
BuildingLevelStatus2["ACTIVE"] = "active";
|
|
55560
|
+
BuildingLevelStatus2["DELETED"] = "deleted";
|
|
55561
|
+
return BuildingLevelStatus2;
|
|
55562
|
+
})(BuildingLevelStatus || {});
|
|
55563
|
+
var schemaBuildingLevel = Joi139.object({
|
|
55564
|
+
org: Joi139.string().hex().optional(),
|
|
55565
|
+
site: Joi139.string().hex().optional(),
|
|
55566
|
+
blockId: Joi139.string().hex().optional(),
|
|
55567
|
+
name: Joi139.string().optional(),
|
|
55568
|
+
status: Joi139.string().valid(...Object.values(BuildingLevelStatus)).optional(),
|
|
55569
|
+
createdAt: Joi139.date().optional(),
|
|
55570
|
+
updatedAt: Joi139.date().optional().allow(null),
|
|
55571
|
+
deletedAt: Joi139.date().optional().allow(null)
|
|
55572
|
+
});
|
|
55573
|
+
function MBuildingLevel(value) {
|
|
55574
|
+
const { error } = schemaBuildingLevel.validate(value);
|
|
55575
|
+
if (error) {
|
|
55576
|
+
logger191.info(`Building Level Model: ${error.message}`);
|
|
55577
|
+
throw new BadRequestError218(error.message);
|
|
55578
|
+
}
|
|
55579
|
+
if (value.org && typeof value.org === "string") {
|
|
55580
|
+
try {
|
|
55581
|
+
value.org = new ObjectId136(value.org);
|
|
55582
|
+
} catch {
|
|
55583
|
+
throw new BadRequestError218("Invalid org ID format");
|
|
55584
|
+
}
|
|
55585
|
+
}
|
|
55586
|
+
if (value.site && typeof value.site === "string") {
|
|
55587
|
+
try {
|
|
55588
|
+
value.site = new ObjectId136(value.site);
|
|
55589
|
+
} catch {
|
|
55590
|
+
throw new BadRequestError218("Invalid site ID format");
|
|
55591
|
+
}
|
|
55592
|
+
}
|
|
55593
|
+
if (value.blockId && typeof value.blockId === "string") {
|
|
55594
|
+
try {
|
|
55595
|
+
value.blockId = new ObjectId136(value.blockId);
|
|
55596
|
+
} catch {
|
|
55597
|
+
throw new BadRequestError218("Invalid block ID format");
|
|
55598
|
+
}
|
|
55599
|
+
}
|
|
55600
|
+
return {
|
|
55601
|
+
_id: new ObjectId136(),
|
|
55602
|
+
org: value.org ?? void 0,
|
|
55603
|
+
site: value.site ?? void 0,
|
|
55604
|
+
blockId: value.blockId ?? void 0,
|
|
55605
|
+
name: value.name ?? "",
|
|
55606
|
+
status: value.status ?? "active" /* ACTIVE */,
|
|
55607
|
+
createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
|
|
55608
|
+
updatedAt: value.updatedAt ?? null,
|
|
55609
|
+
deletedAt: value.deletedAt ?? null
|
|
55610
|
+
};
|
|
55611
|
+
}
|
|
55612
|
+
|
|
55613
|
+
// src/repositories/building-level.repository.ts
|
|
55614
|
+
import {
|
|
55615
|
+
AppError as AppError29,
|
|
55616
|
+
BadRequestError as BadRequestError219,
|
|
55617
|
+
logger as logger192,
|
|
55618
|
+
makeCacheKey as makeCacheKey66,
|
|
55619
|
+
paginate as paginate61,
|
|
55620
|
+
toObjectId as toObjectId20,
|
|
55621
|
+
useAtlas as useAtlas121,
|
|
55622
|
+
useCache as useCache70
|
|
55623
|
+
} from "@7365admin1/node-server-utils";
|
|
55624
|
+
var building_level_namespace_collection = "building-levels";
|
|
55625
|
+
function useBuildingLevelRepo() {
|
|
55626
|
+
const db = useAtlas121.getDb();
|
|
55627
|
+
if (!db) {
|
|
55628
|
+
throw new Error("Unable to connect to server.");
|
|
55629
|
+
}
|
|
55630
|
+
const collection = db.collection(building_level_namespace_collection);
|
|
55631
|
+
const { getCache, setCache, delNamespace, delCache } = useCache70(
|
|
55632
|
+
building_level_namespace_collection
|
|
55633
|
+
);
|
|
55634
|
+
function delCachedData() {
|
|
55635
|
+
delNamespace().then(() => {
|
|
55636
|
+
logger192.log({
|
|
55637
|
+
level: "info",
|
|
55638
|
+
message: `Cache namespace cleared for ${building_level_namespace_collection}`
|
|
55639
|
+
});
|
|
55640
|
+
}).catch((err) => {
|
|
55641
|
+
logger192.log({
|
|
55642
|
+
level: "error",
|
|
55643
|
+
message: `Failed to clear cache namespace for ${building_level_namespace_collection}: ${err.message}`
|
|
55644
|
+
});
|
|
55645
|
+
});
|
|
55646
|
+
}
|
|
55647
|
+
async function add(value, session) {
|
|
55648
|
+
try {
|
|
55649
|
+
value = MBuildingLevel(value);
|
|
55650
|
+
const res = await collection.insertOne(value, { session });
|
|
55651
|
+
delCachedData();
|
|
55652
|
+
return res.insertedId;
|
|
55653
|
+
} catch (error) {
|
|
55654
|
+
logger192.log({
|
|
55655
|
+
level: "error",
|
|
55656
|
+
message: error.message
|
|
55657
|
+
});
|
|
55658
|
+
const isDuplicated = error.message.includes("duplicate");
|
|
55659
|
+
if (isDuplicated) {
|
|
55660
|
+
throw new BadRequestError219("Building unit already exists.");
|
|
55661
|
+
}
|
|
55662
|
+
if (error instanceof AppError29) {
|
|
55663
|
+
throw error;
|
|
55664
|
+
} else {
|
|
55665
|
+
throw new Error("Failed to create building unit.");
|
|
55666
|
+
}
|
|
55667
|
+
}
|
|
55668
|
+
}
|
|
55669
|
+
async function getAll({
|
|
55670
|
+
search = "",
|
|
55671
|
+
page = 1,
|
|
55672
|
+
limit = 10,
|
|
55673
|
+
sort = {},
|
|
55674
|
+
site = "",
|
|
55675
|
+
status = "active"
|
|
55676
|
+
} = {}) {
|
|
55677
|
+
page = page > 0 ? page - 1 : 0;
|
|
55678
|
+
const query = {
|
|
55679
|
+
status,
|
|
55680
|
+
...search && { $text: { $search: search } },
|
|
55681
|
+
...site && { site: toObjectId20(site) }
|
|
55682
|
+
};
|
|
55683
|
+
const cacheParams = {
|
|
55684
|
+
page,
|
|
55685
|
+
limit,
|
|
55686
|
+
sort: JSON.stringify(sort),
|
|
55687
|
+
...search && { search },
|
|
55688
|
+
...site && { site },
|
|
55689
|
+
...status && { status }
|
|
55690
|
+
};
|
|
55691
|
+
const cacheKey = makeCacheKey66(
|
|
55692
|
+
building_level_namespace_collection,
|
|
55693
|
+
cacheParams
|
|
55694
|
+
);
|
|
55695
|
+
logger192.log({
|
|
55696
|
+
level: "info",
|
|
55697
|
+
message: `Cache key for getAll building units: ${cacheKey}`
|
|
55698
|
+
});
|
|
55699
|
+
try {
|
|
55700
|
+
const cached = await getCache(cacheKey);
|
|
55701
|
+
if (cached) {
|
|
55702
|
+
logger192.log({
|
|
55703
|
+
level: "info",
|
|
55704
|
+
message: `Cache hit for getAll building units: ${cacheKey}`
|
|
55705
|
+
});
|
|
55706
|
+
return cached;
|
|
55707
|
+
}
|
|
55708
|
+
const sortStage = Object.keys(sort).length > 0 ? { $sort: sort } : { $sort: { latestDate: -1 } };
|
|
55709
|
+
const items = await collection.aggregate([
|
|
55710
|
+
{ $match: query },
|
|
55711
|
+
{
|
|
55712
|
+
$addFields: {
|
|
55713
|
+
latestDate: { $max: ["$updatedAt", "$createdAt"] }
|
|
55714
|
+
}
|
|
55715
|
+
},
|
|
55716
|
+
sortStage,
|
|
55717
|
+
{ $unset: "latestDate" },
|
|
55718
|
+
{ $skip: page * limit },
|
|
55719
|
+
{ $limit: limit }
|
|
55720
|
+
]).toArray();
|
|
55721
|
+
const length = await collection.countDocuments(query);
|
|
55722
|
+
const data = paginate61(items, page, limit, length);
|
|
55723
|
+
setCache(cacheKey, data, 600).then(() => {
|
|
55724
|
+
logger192.log({
|
|
55725
|
+
level: "info",
|
|
55726
|
+
message: `Cache set for getAll building units: ${cacheKey}`
|
|
55727
|
+
});
|
|
55728
|
+
}).catch((err) => {
|
|
55729
|
+
logger192.log({
|
|
55730
|
+
level: "error",
|
|
55731
|
+
message: `Failed to set cache for getAll building units: ${err.message}`
|
|
55732
|
+
});
|
|
55733
|
+
});
|
|
55734
|
+
return data;
|
|
55735
|
+
} catch (error) {
|
|
55736
|
+
console.log(error);
|
|
55737
|
+
logger192.log({ level: "error", message: `${error}` });
|
|
55738
|
+
throw error;
|
|
55739
|
+
}
|
|
55740
|
+
}
|
|
55741
|
+
return {
|
|
55742
|
+
// createIndexes,
|
|
55743
|
+
add,
|
|
55744
|
+
getAll
|
|
55745
|
+
};
|
|
55746
|
+
}
|
|
55747
|
+
|
|
55748
|
+
// src/services/building-level.service.ts
|
|
55749
|
+
import { useAtlas as useAtlas122 } from "@7365admin1/node-server-utils";
|
|
55750
|
+
function useBuildingLevelService() {
|
|
55751
|
+
const { add: _add } = useBuildingLevelRepo();
|
|
55752
|
+
async function add(value) {
|
|
55753
|
+
const session = useAtlas122.getClient()?.startSession();
|
|
55754
|
+
try {
|
|
55755
|
+
session?.startTransaction();
|
|
55756
|
+
await _add(value, session);
|
|
55757
|
+
await session?.commitTransaction();
|
|
55758
|
+
return "Successfully added building level.";
|
|
55759
|
+
} catch (error) {
|
|
55760
|
+
await session?.abortTransaction();
|
|
55761
|
+
throw error;
|
|
55762
|
+
} finally {
|
|
55763
|
+
session?.endSession();
|
|
55764
|
+
}
|
|
55765
|
+
}
|
|
55766
|
+
return {
|
|
55767
|
+
add
|
|
55768
|
+
};
|
|
55769
|
+
}
|
|
55770
|
+
|
|
55771
|
+
// src/controllers/building-level.controller.ts
|
|
55772
|
+
import { BadRequestError as BadRequestError220, logger as logger193 } from "@7365admin1/node-server-utils";
|
|
55773
|
+
import Joi140 from "joi";
|
|
55774
|
+
function useBuildingLevelController() {
|
|
55775
|
+
const { add: _add } = useBuildingLevelService();
|
|
55776
|
+
const { getAll: _getAll } = useBuildingLevelRepo();
|
|
55777
|
+
async function add(req, res, next) {
|
|
55778
|
+
try {
|
|
55779
|
+
const { error, value } = schemaBuildingLevel.validate(req.body, {
|
|
55780
|
+
abortEarly: false
|
|
55781
|
+
});
|
|
55782
|
+
if (error) {
|
|
55783
|
+
const messages = error.details.map((d) => d.message).join(", ");
|
|
55784
|
+
logger193.log({ level: "error", message: messages });
|
|
55785
|
+
next(new BadRequestError220(messages));
|
|
55786
|
+
return;
|
|
55787
|
+
}
|
|
55788
|
+
const result = await _add(value);
|
|
55789
|
+
res.status(201).json(result);
|
|
55790
|
+
} catch (error) {
|
|
55791
|
+
next(error);
|
|
55792
|
+
}
|
|
55793
|
+
}
|
|
55794
|
+
async function getAll(req, res, next) {
|
|
55795
|
+
try {
|
|
55796
|
+
const validation = Joi140.object({
|
|
55797
|
+
page: Joi140.number().min(1).optional().default(1),
|
|
55798
|
+
limit: Joi140.number().min(1).optional().default(20),
|
|
55799
|
+
search: Joi140.string().optional().allow("", null),
|
|
55800
|
+
site: Joi140.string().hex().length(24).optional().allow("", null),
|
|
55801
|
+
status: Joi140.string().valid(...Object.values(BuildingLevelStatus)).default("active" /* ACTIVE */)
|
|
55802
|
+
});
|
|
55803
|
+
const { error, value } = validation.validate(req.query, {
|
|
55804
|
+
abortEarly: false
|
|
55805
|
+
});
|
|
55806
|
+
if (error) {
|
|
55807
|
+
const messages = error.details.map((d) => d.message);
|
|
55808
|
+
logger193.log({ level: "error", message: messages.join(", ") });
|
|
55809
|
+
next(new BadRequestError220(messages.join(", ")));
|
|
55810
|
+
return;
|
|
55811
|
+
}
|
|
55812
|
+
const { page, limit, status, site, search } = value;
|
|
55813
|
+
const result = await _getAll({
|
|
55814
|
+
page,
|
|
55815
|
+
limit,
|
|
55816
|
+
status,
|
|
55817
|
+
site,
|
|
55818
|
+
search
|
|
55819
|
+
});
|
|
55820
|
+
res.json(result);
|
|
55821
|
+
return;
|
|
55822
|
+
} catch (error) {
|
|
55823
|
+
next(error);
|
|
55824
|
+
}
|
|
55825
|
+
}
|
|
55826
|
+
return {
|
|
55827
|
+
add,
|
|
55828
|
+
getAll
|
|
55829
|
+
};
|
|
55830
|
+
}
|
|
54282
55831
|
export {
|
|
54283
55832
|
ANPRMode,
|
|
54284
55833
|
AccessTypeProps,
|
|
54285
55834
|
AppServiceType,
|
|
55835
|
+
BuildingLevelStatus,
|
|
54286
55836
|
BuildingStatus,
|
|
54287
55837
|
BulletinOrder,
|
|
54288
55838
|
BulletinRecipient,
|
|
@@ -54305,6 +55855,7 @@ export {
|
|
|
54305
55855
|
EventType,
|
|
54306
55856
|
FacilitySort,
|
|
54307
55857
|
FacilityStatus,
|
|
55858
|
+
FormEntryStatus,
|
|
54308
55859
|
GuestSort,
|
|
54309
55860
|
GuestStatus,
|
|
54310
55861
|
MAccessCard,
|
|
@@ -54315,9 +55866,11 @@ export {
|
|
|
54315
55866
|
MBillingConfiguration,
|
|
54316
55867
|
MBillingItem,
|
|
54317
55868
|
MBuilding,
|
|
55869
|
+
MBuildingLevel,
|
|
54318
55870
|
MBuildingUnit,
|
|
54319
55871
|
MBulletinBoard,
|
|
54320
55872
|
MBulletinVideo,
|
|
55873
|
+
MCategoryPreloved,
|
|
54321
55874
|
MChat,
|
|
54322
55875
|
MCustomer,
|
|
54323
55876
|
MCustomerSite,
|
|
@@ -54326,6 +55879,7 @@ export {
|
|
|
54326
55879
|
MEventManagement,
|
|
54327
55880
|
MFeedback,
|
|
54328
55881
|
MFile,
|
|
55882
|
+
MFormEntry,
|
|
54329
55883
|
MGuestManagement,
|
|
54330
55884
|
MIncidentReport,
|
|
54331
55885
|
MManpowerDesignations,
|
|
@@ -54362,6 +55916,7 @@ export {
|
|
|
54362
55916
|
MSiteFacility,
|
|
54363
55917
|
MSiteFacilityBooking,
|
|
54364
55918
|
MStatementOfAccount,
|
|
55919
|
+
MSubcategoryPreloved,
|
|
54365
55920
|
MSubscription,
|
|
54366
55921
|
MUnitBilling,
|
|
54367
55922
|
MUser,
|
|
@@ -54409,6 +55964,7 @@ export {
|
|
|
54409
55964
|
allowedNatures,
|
|
54410
55965
|
attendanceSchema,
|
|
54411
55966
|
attendanceSettingsSchema,
|
|
55967
|
+
building_level_namespace_collection,
|
|
54412
55968
|
building_units_namespace_collection,
|
|
54413
55969
|
buildings_namespace_collection,
|
|
54414
55970
|
bulletin_boards_namespace_collection,
|
|
@@ -54437,6 +55993,7 @@ export {
|
|
|
54437
55993
|
nfcPatrolSettingsSchema,
|
|
54438
55994
|
nfcPatrolSettingsSchemaUpdate,
|
|
54439
55995
|
occurrence_book_namespace_collection,
|
|
55996
|
+
online_forms_namespace_collection,
|
|
54440
55997
|
orgSchema,
|
|
54441
55998
|
overnight_parking_requests_namespace_collection,
|
|
54442
55999
|
parseDahuaFind,
|
|
@@ -54452,15 +56009,18 @@ export {
|
|
|
54452
56009
|
schemaBillingConfiguration,
|
|
54453
56010
|
schemaBillingItem,
|
|
54454
56011
|
schemaBuilding,
|
|
56012
|
+
schemaBuildingLevel,
|
|
54455
56013
|
schemaBuildingUnit,
|
|
54456
56014
|
schemaBuildingUpdateOptions,
|
|
54457
56015
|
schemaBulletinBoard,
|
|
54458
56016
|
schemaBulletinVideo,
|
|
56017
|
+
schemaCategoryPreloved,
|
|
54459
56018
|
schemaCustomerSite,
|
|
54460
56019
|
schemaDocumentManagement,
|
|
54461
56020
|
schemaEntryPassSettings,
|
|
54462
56021
|
schemaEventManagement,
|
|
54463
56022
|
schemaFiles,
|
|
56023
|
+
schemaFormEntry,
|
|
54464
56024
|
schemaGuestManagement,
|
|
54465
56025
|
schemaIncidentReport,
|
|
54466
56026
|
schemaNfcPatrolLog,
|
|
@@ -54485,12 +56045,15 @@ export {
|
|
|
54485
56045
|
schemaSiteFacility,
|
|
54486
56046
|
schemaSiteFacilityBooking,
|
|
54487
56047
|
schemaStatementOfAccount,
|
|
56048
|
+
schemaSubcategoryPreloved,
|
|
54488
56049
|
schemaUnitBilling,
|
|
54489
56050
|
schemaUpdateBulletinBoard,
|
|
54490
56051
|
schemaUpdateBulletinVideo,
|
|
56052
|
+
schemaUpdateCategoryPreloved,
|
|
54491
56053
|
schemaUpdateDocumentManagement,
|
|
54492
56054
|
schemaUpdateEntryPassSettings,
|
|
54493
56055
|
schemaUpdateEventManagement,
|
|
56056
|
+
schemaUpdateFormEntry,
|
|
54494
56057
|
schemaUpdateGuestManagement,
|
|
54495
56058
|
schemaUpdateIncidentReport,
|
|
54496
56059
|
schemaUpdateOccurrenceBook,
|
|
@@ -54512,6 +56075,7 @@ export {
|
|
|
54512
56075
|
schemaUpdateSiteFacilityBooking,
|
|
54513
56076
|
schemaUpdateSiteUnitBilling,
|
|
54514
56077
|
schemaUpdateStatementOfAccount,
|
|
56078
|
+
schemaUpdateSubcategoryPreloved,
|
|
54515
56079
|
schemaUpdateVisTrans,
|
|
54516
56080
|
schemaVehicleTransaction,
|
|
54517
56081
|
schemaVisitorTransaction,
|
|
@@ -54537,6 +56101,9 @@ export {
|
|
|
54537
56101
|
useAuthService,
|
|
54538
56102
|
useAuthServiceV2,
|
|
54539
56103
|
useBuildingController,
|
|
56104
|
+
useBuildingLevelController,
|
|
56105
|
+
useBuildingLevelRepo,
|
|
56106
|
+
useBuildingLevelService,
|
|
54540
56107
|
useBuildingRepo,
|
|
54541
56108
|
useBuildingService,
|
|
54542
56109
|
useBuildingUnitController,
|
|
@@ -54548,6 +56115,8 @@ export {
|
|
|
54548
56115
|
useBulletinVideoController,
|
|
54549
56116
|
useBulletinVideoRepo,
|
|
54550
56117
|
useBulletinVideoService,
|
|
56118
|
+
useCategoryPrelovedController,
|
|
56119
|
+
useCategoryPrelovedRepo,
|
|
54551
56120
|
useChatController,
|
|
54552
56121
|
useChatRepo,
|
|
54553
56122
|
useCounterModel,
|
|
@@ -54574,6 +56143,8 @@ export {
|
|
|
54574
56143
|
useFileController,
|
|
54575
56144
|
useFileRepo,
|
|
54576
56145
|
useFileService,
|
|
56146
|
+
useFormEntryController,
|
|
56147
|
+
useFormEntryRepo,
|
|
54577
56148
|
useGuestManagementController,
|
|
54578
56149
|
useGuestManagementRepo,
|
|
54579
56150
|
useGuestManagementService,
|
|
@@ -54683,6 +56254,8 @@ export {
|
|
|
54683
56254
|
useSiteUnitBillingService,
|
|
54684
56255
|
useStatementOfAccountController,
|
|
54685
56256
|
useStatementOfAccountRepo,
|
|
56257
|
+
useSubcategoryPrelovedController,
|
|
56258
|
+
useSubcategoryPrelovedRepo,
|
|
54686
56259
|
useSubscriptionController,
|
|
54687
56260
|
useSubscriptionRepo,
|
|
54688
56261
|
useSubscriptionService,
|