@7365admin1/module-hygiene 4.2.0 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/index.d.ts +6 -74
- package/dist/index.js +279 -877
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +296 -897
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -4230,27 +4230,24 @@ function useStockController() {
|
|
|
4230
4230
|
};
|
|
4231
4231
|
}
|
|
4232
4232
|
|
|
4233
|
-
// src/models/hygiene-
|
|
4233
|
+
// src/models/hygiene-checkout-item.model.ts
|
|
4234
4234
|
import Joi14 from "joi";
|
|
4235
4235
|
import { ObjectId as ObjectId14 } from "mongodb";
|
|
4236
4236
|
import { BadRequestError as BadRequestError24, logger as logger24 } from "@7365admin1/node-server-utils";
|
|
4237
|
-
var
|
|
4238
|
-
|
|
4239
|
-
"approved",
|
|
4240
|
-
"disapproved"
|
|
4241
|
-
];
|
|
4242
|
-
var requestItemSchema = Joi14.object({
|
|
4237
|
+
var allowedCheckOutItemStatus = ["pending", "completed"];
|
|
4238
|
+
var checkOutItemSchema = Joi14.object({
|
|
4243
4239
|
site: Joi14.string().hex().required(),
|
|
4244
4240
|
supply: Joi14.string().hex().required(),
|
|
4245
4241
|
supplyName: Joi14.string().required(),
|
|
4246
4242
|
qty: Joi14.number().min(0).required(),
|
|
4243
|
+
attachment: Joi14.array().items(Joi14.string()).optional().allow(null),
|
|
4247
4244
|
createdBy: Joi14.string().hex().required(),
|
|
4248
4245
|
createdByName: Joi14.string().required()
|
|
4249
4246
|
});
|
|
4250
|
-
function
|
|
4251
|
-
const { error } =
|
|
4247
|
+
function MCheckOutItem(value) {
|
|
4248
|
+
const { error } = checkOutItemSchema.validate(value);
|
|
4252
4249
|
if (error) {
|
|
4253
|
-
logger24.info(`Hygiene
|
|
4250
|
+
logger24.info(`Hygiene Check Out Item Model: ${error.message}`);
|
|
4254
4251
|
throw new BadRequestError24(error.message);
|
|
4255
4252
|
}
|
|
4256
4253
|
if (value.site) {
|
|
@@ -4264,615 +4261,7 @@ function MRequestItem(value) {
|
|
|
4264
4261
|
try {
|
|
4265
4262
|
value.supply = new ObjectId14(value.supply);
|
|
4266
4263
|
} catch (error2) {
|
|
4267
|
-
throw new BadRequestError24("Invalid supply ID format.");
|
|
4268
|
-
}
|
|
4269
|
-
}
|
|
4270
|
-
return {
|
|
4271
|
-
site: value.site,
|
|
4272
|
-
supply: value.supply,
|
|
4273
|
-
supplyName: value.supplyName,
|
|
4274
|
-
qty: value.qty,
|
|
4275
|
-
remarks: "",
|
|
4276
|
-
createdBy: value.createdBy,
|
|
4277
|
-
createdByName: value.createdByName,
|
|
4278
|
-
status: "pending",
|
|
4279
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4280
|
-
updatedAt: "",
|
|
4281
|
-
deletedAt: ""
|
|
4282
|
-
};
|
|
4283
|
-
}
|
|
4284
|
-
|
|
4285
|
-
// src/repositories/hygiene-request-item.repository.ts
|
|
4286
|
-
import { ObjectId as ObjectId15 } from "mongodb";
|
|
4287
|
-
import {
|
|
4288
|
-
useAtlas as useAtlas11,
|
|
4289
|
-
InternalServerError as InternalServerError8,
|
|
4290
|
-
useCache as useCache8,
|
|
4291
|
-
logger as logger25,
|
|
4292
|
-
makeCacheKey as makeCacheKey8,
|
|
4293
|
-
paginate as paginate7,
|
|
4294
|
-
BadRequestError as BadRequestError25,
|
|
4295
|
-
NotFoundError as NotFoundError6
|
|
4296
|
-
} from "@7365admin1/node-server-utils";
|
|
4297
|
-
function useRequestItemRepository() {
|
|
4298
|
-
const db = useAtlas11.getDb();
|
|
4299
|
-
if (!db) {
|
|
4300
|
-
throw new InternalServerError8("Unable to connect to server.");
|
|
4301
|
-
}
|
|
4302
|
-
const namespace_collection = "site.supply.requests";
|
|
4303
|
-
const collection = db.collection(namespace_collection);
|
|
4304
|
-
const { delNamespace, setCache, getCache } = useCache8(namespace_collection);
|
|
4305
|
-
async function createIndex() {
|
|
4306
|
-
try {
|
|
4307
|
-
await collection.createIndexes([
|
|
4308
|
-
{ key: { site: 1 } },
|
|
4309
|
-
{ key: { supply: 1 } },
|
|
4310
|
-
{ key: { status: 1 } }
|
|
4311
|
-
]);
|
|
4312
|
-
} catch (error) {
|
|
4313
|
-
throw new InternalServerError8(
|
|
4314
|
-
"Failed to create index on hygiene request item."
|
|
4315
|
-
);
|
|
4316
|
-
}
|
|
4317
|
-
}
|
|
4318
|
-
async function createTextIndex() {
|
|
4319
|
-
try {
|
|
4320
|
-
await collection.createIndex({ supplyName: "text" });
|
|
4321
|
-
} catch (error) {
|
|
4322
|
-
throw new InternalServerError8(
|
|
4323
|
-
"Failed to create text index on hygiene supply."
|
|
4324
|
-
);
|
|
4325
|
-
}
|
|
4326
|
-
}
|
|
4327
|
-
async function createRequestItem(value, session) {
|
|
4328
|
-
try {
|
|
4329
|
-
value = MRequestItem(value);
|
|
4330
|
-
const res = await collection.insertOne(value, { session });
|
|
4331
|
-
delNamespace().then(() => {
|
|
4332
|
-
logger25.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
4333
|
-
}).catch((err) => {
|
|
4334
|
-
logger25.error(
|
|
4335
|
-
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
4336
|
-
err
|
|
4337
|
-
);
|
|
4338
|
-
});
|
|
4339
|
-
return res.insertedId;
|
|
4340
|
-
} catch (error) {
|
|
4341
|
-
throw error;
|
|
4342
|
-
}
|
|
4343
|
-
}
|
|
4344
|
-
async function getRequestItems({
|
|
4345
|
-
page = 1,
|
|
4346
|
-
limit = 10,
|
|
4347
|
-
search = "",
|
|
4348
|
-
site
|
|
4349
|
-
}) {
|
|
4350
|
-
page = page > 0 ? page - 1 : 0;
|
|
4351
|
-
const query = {
|
|
4352
|
-
status: { $ne: "deleted" }
|
|
4353
|
-
};
|
|
4354
|
-
const cacheOptions = {
|
|
4355
|
-
page,
|
|
4356
|
-
limit
|
|
4357
|
-
};
|
|
4358
|
-
try {
|
|
4359
|
-
site = new ObjectId15(site);
|
|
4360
|
-
query.site = site;
|
|
4361
|
-
cacheOptions.site = site.toString();
|
|
4362
|
-
} catch (error) {
|
|
4363
|
-
throw new BadRequestError25("Invalid site ID format.");
|
|
4364
|
-
}
|
|
4365
|
-
if (search) {
|
|
4366
|
-
query.$text = { $search: search };
|
|
4367
|
-
cacheOptions.search = search;
|
|
4368
|
-
}
|
|
4369
|
-
const cacheKey = makeCacheKey8(namespace_collection, cacheOptions);
|
|
4370
|
-
const cachedData = await getCache(cacheKey);
|
|
4371
|
-
if (cachedData) {
|
|
4372
|
-
logger25.info(`Cache hit for key: ${cacheKey}`);
|
|
4373
|
-
return cachedData;
|
|
4374
|
-
}
|
|
4375
|
-
try {
|
|
4376
|
-
const items = await collection.aggregate([
|
|
4377
|
-
{ $match: query },
|
|
4378
|
-
{
|
|
4379
|
-
$project: {
|
|
4380
|
-
supplyName: 1,
|
|
4381
|
-
createdAt: 1,
|
|
4382
|
-
status: 1
|
|
4383
|
-
}
|
|
4384
|
-
},
|
|
4385
|
-
{ $sort: { _id: -1 } },
|
|
4386
|
-
{ $skip: page * limit },
|
|
4387
|
-
{ $limit: limit }
|
|
4388
|
-
]).toArray();
|
|
4389
|
-
const length = await collection.countDocuments(query);
|
|
4390
|
-
const data = paginate7(items, page, limit, length);
|
|
4391
|
-
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
4392
|
-
logger25.info(`Cache set for key: ${cacheKey}`);
|
|
4393
|
-
}).catch((err) => {
|
|
4394
|
-
logger25.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
4395
|
-
});
|
|
4396
|
-
return data;
|
|
4397
|
-
} catch (error) {
|
|
4398
|
-
throw error;
|
|
4399
|
-
}
|
|
4400
|
-
}
|
|
4401
|
-
async function getRequestItemById(_id, session) {
|
|
4402
|
-
try {
|
|
4403
|
-
_id = new ObjectId15(_id);
|
|
4404
|
-
} catch (error) {
|
|
4405
|
-
throw new BadRequestError25("Invalid request item ID format.");
|
|
4406
|
-
}
|
|
4407
|
-
const query = { _id };
|
|
4408
|
-
const cacheKey = makeCacheKey8(namespace_collection, {
|
|
4409
|
-
_id: _id.toString()
|
|
4410
|
-
});
|
|
4411
|
-
if (!session) {
|
|
4412
|
-
const cachedData = await getCache(cacheKey);
|
|
4413
|
-
if (cachedData) {
|
|
4414
|
-
logger25.info(`Cache hit for key: ${cacheKey}`);
|
|
4415
|
-
return cachedData;
|
|
4416
|
-
}
|
|
4417
|
-
} else {
|
|
4418
|
-
logger25.info(`Skipping cache during transaction for key: ${cacheKey}`);
|
|
4419
|
-
}
|
|
4420
|
-
try {
|
|
4421
|
-
const data = await collection.aggregate([
|
|
4422
|
-
{ $match: query },
|
|
4423
|
-
{
|
|
4424
|
-
$lookup: {
|
|
4425
|
-
from: "site.supply.items",
|
|
4426
|
-
localField: "supply",
|
|
4427
|
-
foreignField: "_id",
|
|
4428
|
-
as: "supplyDetails"
|
|
4429
|
-
}
|
|
4430
|
-
},
|
|
4431
|
-
{
|
|
4432
|
-
$unwind: {
|
|
4433
|
-
path: "$supplyDetails",
|
|
4434
|
-
preserveNullAndEmptyArrays: true
|
|
4435
|
-
}
|
|
4436
|
-
},
|
|
4437
|
-
{
|
|
4438
|
-
$project: {
|
|
4439
|
-
site: 1,
|
|
4440
|
-
supply: 1,
|
|
4441
|
-
supplyName: 1,
|
|
4442
|
-
qty: 1,
|
|
4443
|
-
status: 1,
|
|
4444
|
-
unitOfMeasurement: "$supplyDetails.unitOfMeasurement"
|
|
4445
|
-
}
|
|
4446
|
-
}
|
|
4447
|
-
]).toArray();
|
|
4448
|
-
if (!data || data.length === 0) {
|
|
4449
|
-
throw new NotFoundError6("Request item not found.");
|
|
4450
|
-
}
|
|
4451
|
-
setCache(cacheKey, data[0], 15 * 60).then(() => {
|
|
4452
|
-
logger25.info(`Cache set for key: ${cacheKey}`);
|
|
4453
|
-
}).catch((err) => {
|
|
4454
|
-
logger25.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
4455
|
-
});
|
|
4456
|
-
return data[0];
|
|
4457
|
-
} catch (error) {
|
|
4458
|
-
throw error;
|
|
4459
|
-
}
|
|
4460
|
-
}
|
|
4461
|
-
async function approveRequestItem(_id, remarks, session) {
|
|
4462
|
-
try {
|
|
4463
|
-
_id = new ObjectId15(_id);
|
|
4464
|
-
} catch (error) {
|
|
4465
|
-
throw new BadRequestError25("Invalid request item ID format.");
|
|
4466
|
-
}
|
|
4467
|
-
try {
|
|
4468
|
-
const updateValue = {
|
|
4469
|
-
status: "approved",
|
|
4470
|
-
remarks: remarks || "",
|
|
4471
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4472
|
-
};
|
|
4473
|
-
const res = await collection.updateOne(
|
|
4474
|
-
{ _id },
|
|
4475
|
-
{ $set: updateValue },
|
|
4476
|
-
{ session }
|
|
4477
|
-
);
|
|
4478
|
-
if (res.modifiedCount === 0) {
|
|
4479
|
-
throw new InternalServerError8("Unable to approve request item.");
|
|
4480
|
-
}
|
|
4481
|
-
delNamespace().then(() => {
|
|
4482
|
-
logger25.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
4483
|
-
}).catch((err) => {
|
|
4484
|
-
logger25.error(
|
|
4485
|
-
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
4486
|
-
err
|
|
4487
|
-
);
|
|
4488
|
-
});
|
|
4489
|
-
return res.modifiedCount;
|
|
4490
|
-
} catch (error) {
|
|
4491
|
-
throw error;
|
|
4492
|
-
}
|
|
4493
|
-
}
|
|
4494
|
-
async function disapproveRequestItem(_id, remarks, session) {
|
|
4495
|
-
try {
|
|
4496
|
-
_id = new ObjectId15(_id);
|
|
4497
|
-
} catch (error) {
|
|
4498
|
-
throw new BadRequestError25("Invalid request item ID format.");
|
|
4499
|
-
}
|
|
4500
|
-
try {
|
|
4501
|
-
const updateValue = {
|
|
4502
|
-
status: "disapproved",
|
|
4503
|
-
remarks: remarks || "",
|
|
4504
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4505
|
-
};
|
|
4506
|
-
const res = await collection.updateOne(
|
|
4507
|
-
{ _id },
|
|
4508
|
-
{ $set: updateValue },
|
|
4509
|
-
{ session }
|
|
4510
|
-
);
|
|
4511
|
-
if (res.modifiedCount === 0) {
|
|
4512
|
-
throw new InternalServerError8("Unable to disapprove request item.");
|
|
4513
|
-
}
|
|
4514
|
-
delNamespace().then(() => {
|
|
4515
|
-
logger25.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
4516
|
-
}).catch((err) => {
|
|
4517
|
-
logger25.error(
|
|
4518
|
-
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
4519
|
-
err
|
|
4520
|
-
);
|
|
4521
|
-
});
|
|
4522
|
-
return res.modifiedCount;
|
|
4523
|
-
} catch (error) {
|
|
4524
|
-
throw error;
|
|
4525
|
-
}
|
|
4526
|
-
}
|
|
4527
|
-
return {
|
|
4528
|
-
createIndex,
|
|
4529
|
-
createTextIndex,
|
|
4530
|
-
createRequestItem,
|
|
4531
|
-
getRequestItems,
|
|
4532
|
-
getRequestItemById,
|
|
4533
|
-
approveRequestItem,
|
|
4534
|
-
disapproveRequestItem
|
|
4535
|
-
};
|
|
4536
|
-
}
|
|
4537
|
-
|
|
4538
|
-
// src/services/hygiene-request-item.service.ts
|
|
4539
|
-
import { useUserRepo } from "@7365admin1/core";
|
|
4540
|
-
import { BadRequestError as BadRequestError26, useAtlas as useAtlas12 } from "@7365admin1/node-server-utils";
|
|
4541
|
-
function useRequestItemService() {
|
|
4542
|
-
const {
|
|
4543
|
-
createRequestItem: _createRequestItem,
|
|
4544
|
-
getRequestItemById: _getRequestItemById,
|
|
4545
|
-
approveRequestItem: _approveRequestItem,
|
|
4546
|
-
disapproveRequestItem: _disapproveRequestItem
|
|
4547
|
-
} = useRequestItemRepository();
|
|
4548
|
-
const { getSupplyById } = useSupplyRepository();
|
|
4549
|
-
const { getUserById } = useUserRepo();
|
|
4550
|
-
const { createStock } = useStockService();
|
|
4551
|
-
async function createRequestItem(value) {
|
|
4552
|
-
try {
|
|
4553
|
-
const { supply, createdBy } = value;
|
|
4554
|
-
const supplyData = await getSupplyById(supply);
|
|
4555
|
-
const createdByData = await getUserById(createdBy);
|
|
4556
|
-
const createdRequestItem = await _createRequestItem({
|
|
4557
|
-
...value,
|
|
4558
|
-
supplyName: supplyData?.name || "",
|
|
4559
|
-
createdByName: createdByData?.name || ""
|
|
4560
|
-
});
|
|
4561
|
-
return createdRequestItem;
|
|
4562
|
-
} catch (error) {
|
|
4563
|
-
throw error;
|
|
4564
|
-
}
|
|
4565
|
-
}
|
|
4566
|
-
async function createRequestItemByBatch(value) {
|
|
4567
|
-
const session = useAtlas12.getClient()?.startSession();
|
|
4568
|
-
try {
|
|
4569
|
-
session?.startTransaction();
|
|
4570
|
-
const { site, createdBy, items } = value;
|
|
4571
|
-
const createdByData = await getUserById(createdBy);
|
|
4572
|
-
const createdRequestItemIds = [];
|
|
4573
|
-
for (const item of items) {
|
|
4574
|
-
const supplyData = await getSupplyById(item.supply, session);
|
|
4575
|
-
const createdId = await _createRequestItem(
|
|
4576
|
-
{
|
|
4577
|
-
site,
|
|
4578
|
-
supply: item.supply,
|
|
4579
|
-
qty: item.qty,
|
|
4580
|
-
supplyName: supplyData?.name || "",
|
|
4581
|
-
createdBy,
|
|
4582
|
-
createdByName: createdByData?.name || ""
|
|
4583
|
-
},
|
|
4584
|
-
session
|
|
4585
|
-
);
|
|
4586
|
-
createdRequestItemIds.push(createdId);
|
|
4587
|
-
}
|
|
4588
|
-
await session?.commitTransaction();
|
|
4589
|
-
return createdRequestItemIds;
|
|
4590
|
-
} catch (error) {
|
|
4591
|
-
await session?.abortTransaction();
|
|
4592
|
-
throw error;
|
|
4593
|
-
} finally {
|
|
4594
|
-
await session?.endSession();
|
|
4595
|
-
}
|
|
4596
|
-
}
|
|
4597
|
-
async function approveRequestItem(id, remarks) {
|
|
4598
|
-
const session = useAtlas12.getClient()?.startSession();
|
|
4599
|
-
try {
|
|
4600
|
-
session?.startTransaction();
|
|
4601
|
-
await _approveRequestItem(id, remarks, session);
|
|
4602
|
-
const requestItem = await _getRequestItemById(id, session);
|
|
4603
|
-
if (requestItem.status !== "pending") {
|
|
4604
|
-
throw new BadRequestError26(
|
|
4605
|
-
"Only 'pending' request items can be approved."
|
|
4606
|
-
);
|
|
4607
|
-
}
|
|
4608
|
-
const createdStocks = await createStock(
|
|
4609
|
-
{
|
|
4610
|
-
site: requestItem.site.toString(),
|
|
4611
|
-
supply: requestItem.supply.toString(),
|
|
4612
|
-
qty: requestItem.qty,
|
|
4613
|
-
remarks
|
|
4614
|
-
},
|
|
4615
|
-
true
|
|
4616
|
-
);
|
|
4617
|
-
await session?.commitTransaction();
|
|
4618
|
-
return createdStocks;
|
|
4619
|
-
} catch (error) {
|
|
4620
|
-
await session?.abortTransaction();
|
|
4621
|
-
throw error;
|
|
4622
|
-
} finally {
|
|
4623
|
-
await session?.endSession();
|
|
4624
|
-
}
|
|
4625
|
-
}
|
|
4626
|
-
async function disapproveRequestItem(id, remarks) {
|
|
4627
|
-
const session = useAtlas12.getClient()?.startSession();
|
|
4628
|
-
try {
|
|
4629
|
-
session?.startTransaction();
|
|
4630
|
-
const result = await _disapproveRequestItem(id, remarks, session);
|
|
4631
|
-
const requestItem = await _getRequestItemById(id, session);
|
|
4632
|
-
if (requestItem.status !== "pending") {
|
|
4633
|
-
throw new BadRequestError26(
|
|
4634
|
-
"Only 'pending' request items can be disapproved."
|
|
4635
|
-
);
|
|
4636
|
-
}
|
|
4637
|
-
await session?.commitTransaction();
|
|
4638
|
-
return result;
|
|
4639
|
-
} catch (error) {
|
|
4640
|
-
await session?.abortTransaction();
|
|
4641
|
-
throw error;
|
|
4642
|
-
} finally {
|
|
4643
|
-
await session?.endSession();
|
|
4644
|
-
}
|
|
4645
|
-
}
|
|
4646
|
-
return {
|
|
4647
|
-
createRequestItem,
|
|
4648
|
-
createRequestItemByBatch,
|
|
4649
|
-
approveRequestItem,
|
|
4650
|
-
disapproveRequestItem
|
|
4651
|
-
};
|
|
4652
|
-
}
|
|
4653
|
-
|
|
4654
|
-
// src/controllers/hygiene-request-item.controller.ts
|
|
4655
|
-
import Joi15 from "joi";
|
|
4656
|
-
import { BadRequestError as BadRequestError27, logger as logger26 } from "@7365admin1/node-server-utils";
|
|
4657
|
-
function useRequestItemController() {
|
|
4658
|
-
const {
|
|
4659
|
-
getRequestItems: _getRequestItems,
|
|
4660
|
-
getRequestItemById: _getRequestItemById
|
|
4661
|
-
} = useRequestItemRepository();
|
|
4662
|
-
const {
|
|
4663
|
-
createRequestItem: _createRequestItem,
|
|
4664
|
-
createRequestItemByBatch: _createRequestItemByBatch,
|
|
4665
|
-
approveRequestItem: _approveRequestItem,
|
|
4666
|
-
disapproveRequestItem: _disapproveRequestItem
|
|
4667
|
-
} = useRequestItemService();
|
|
4668
|
-
async function createRequestItem(req, res, next) {
|
|
4669
|
-
const cookies = req.headers.cookie ? req.headers.cookie.split(";").map((cookie) => cookie.trim().split("=")).reduce(
|
|
4670
|
-
(acc, [key, value]) => ({ ...acc, [key]: value }),
|
|
4671
|
-
{}
|
|
4672
|
-
) : {};
|
|
4673
|
-
const createdBy = cookies["user"] || "";
|
|
4674
|
-
const payload = {
|
|
4675
|
-
...req.body,
|
|
4676
|
-
...req.params,
|
|
4677
|
-
createdBy
|
|
4678
|
-
};
|
|
4679
|
-
const validation = Joi15.object({
|
|
4680
|
-
site: Joi15.string().hex().required(),
|
|
4681
|
-
supply: Joi15.string().hex().required(),
|
|
4682
|
-
qty: Joi15.number().min(0).required(),
|
|
4683
|
-
createdBy: Joi15.string().hex().required()
|
|
4684
|
-
});
|
|
4685
|
-
const { error } = validation.validate(payload);
|
|
4686
|
-
if (error) {
|
|
4687
|
-
logger26.log({ level: "error", message: error.message });
|
|
4688
|
-
next(new BadRequestError27(error.message));
|
|
4689
|
-
return;
|
|
4690
|
-
}
|
|
4691
|
-
try {
|
|
4692
|
-
const id = await _createRequestItem(payload);
|
|
4693
|
-
res.status(201).json({ message: "Request item created successfully.", id });
|
|
4694
|
-
return;
|
|
4695
|
-
} catch (error2) {
|
|
4696
|
-
logger26.log({ level: "error", message: error2.message });
|
|
4697
|
-
next(error2);
|
|
4698
|
-
return;
|
|
4699
|
-
}
|
|
4700
|
-
}
|
|
4701
|
-
async function createRequestItemByBatch(req, res, next) {
|
|
4702
|
-
const cookies = req.headers.cookie ? req.headers.cookie.split(";").map((cookie) => cookie.trim().split("=")).reduce(
|
|
4703
|
-
(acc, [key, value]) => ({ ...acc, [key]: value }),
|
|
4704
|
-
{}
|
|
4705
|
-
) : {};
|
|
4706
|
-
const createdBy = cookies["user"] || "";
|
|
4707
|
-
const payload = {
|
|
4708
|
-
...req.body,
|
|
4709
|
-
...req.params,
|
|
4710
|
-
createdBy
|
|
4711
|
-
};
|
|
4712
|
-
const validation = Joi15.object({
|
|
4713
|
-
site: Joi15.string().hex().required(),
|
|
4714
|
-
createdBy: Joi15.string().hex().required(),
|
|
4715
|
-
items: Joi15.array().items(
|
|
4716
|
-
Joi15.object({
|
|
4717
|
-
supply: Joi15.string().hex().required(),
|
|
4718
|
-
qty: Joi15.number().min(0).required()
|
|
4719
|
-
})
|
|
4720
|
-
).min(1).required()
|
|
4721
|
-
});
|
|
4722
|
-
const { error } = validation.validate(payload);
|
|
4723
|
-
if (error) {
|
|
4724
|
-
logger26.log({ level: "error", message: error.message });
|
|
4725
|
-
next(new BadRequestError27(error.message));
|
|
4726
|
-
return;
|
|
4727
|
-
}
|
|
4728
|
-
try {
|
|
4729
|
-
await _createRequestItemByBatch(payload);
|
|
4730
|
-
res.status(201).json({ message: "Request items created successfully." });
|
|
4731
|
-
return;
|
|
4732
|
-
} catch (error2) {
|
|
4733
|
-
logger26.log({ level: "error", message: error2.message });
|
|
4734
|
-
next(error2);
|
|
4735
|
-
return;
|
|
4736
|
-
}
|
|
4737
|
-
}
|
|
4738
|
-
async function getRequestItems(req, res, next) {
|
|
4739
|
-
const query = { ...req.query, ...req.params };
|
|
4740
|
-
const validation = Joi15.object({
|
|
4741
|
-
page: Joi15.number().min(1).optional().allow("", null),
|
|
4742
|
-
limit: Joi15.number().min(1).optional().allow("", null),
|
|
4743
|
-
search: Joi15.string().optional().allow("", null),
|
|
4744
|
-
site: Joi15.string().hex().required()
|
|
4745
|
-
});
|
|
4746
|
-
const { error } = validation.validate(query);
|
|
4747
|
-
if (error) {
|
|
4748
|
-
logger26.log({ level: "error", message: error.message });
|
|
4749
|
-
next(new BadRequestError27(error.message));
|
|
4750
|
-
return;
|
|
4751
|
-
}
|
|
4752
|
-
const page = parseInt(req.query.page) ?? 1;
|
|
4753
|
-
const limit = parseInt(req.query.limit) ?? 10;
|
|
4754
|
-
const search = req.query.search ?? "";
|
|
4755
|
-
const site = req.params.site ?? "";
|
|
4756
|
-
try {
|
|
4757
|
-
const data = await _getRequestItems({
|
|
4758
|
-
page,
|
|
4759
|
-
limit,
|
|
4760
|
-
search,
|
|
4761
|
-
site
|
|
4762
|
-
});
|
|
4763
|
-
res.json(data);
|
|
4764
|
-
return;
|
|
4765
|
-
} catch (error2) {
|
|
4766
|
-
logger26.log({ level: "error", message: error2.message });
|
|
4767
|
-
next(error2);
|
|
4768
|
-
return;
|
|
4769
|
-
}
|
|
4770
|
-
}
|
|
4771
|
-
async function getRequestItemById(req, res, next) {
|
|
4772
|
-
const validation = Joi15.string().hex().required();
|
|
4773
|
-
const _id = req.params.id;
|
|
4774
|
-
const { error, value } = validation.validate(_id);
|
|
4775
|
-
if (error) {
|
|
4776
|
-
logger26.log({ level: "error", message: error.message });
|
|
4777
|
-
next(new BadRequestError27(error.message));
|
|
4778
|
-
return;
|
|
4779
|
-
}
|
|
4780
|
-
try {
|
|
4781
|
-
const data = await _getRequestItemById(value);
|
|
4782
|
-
res.json(data);
|
|
4783
|
-
return;
|
|
4784
|
-
} catch (error2) {
|
|
4785
|
-
logger26.log({ level: "error", message: error2.message });
|
|
4786
|
-
next(error2);
|
|
4787
|
-
return;
|
|
4788
|
-
}
|
|
4789
|
-
}
|
|
4790
|
-
async function approveRequestItem(req, res, next) {
|
|
4791
|
-
const payload = { ...req.params, ...req.body };
|
|
4792
|
-
const validation = Joi15.object({
|
|
4793
|
-
id: Joi15.string().hex().required(),
|
|
4794
|
-
remarks: Joi15.string().optional().allow("", null)
|
|
4795
|
-
});
|
|
4796
|
-
const { error } = validation.validate(payload);
|
|
4797
|
-
if (error) {
|
|
4798
|
-
logger26.log({ level: "error", message: error.message });
|
|
4799
|
-
next(new BadRequestError27(error.message));
|
|
4800
|
-
return;
|
|
4801
|
-
}
|
|
4802
|
-
try {
|
|
4803
|
-
await _approveRequestItem(payload.id, payload.remarks);
|
|
4804
|
-
res.json({ message: "Request item approved successfully." });
|
|
4805
|
-
return;
|
|
4806
|
-
} catch (error2) {
|
|
4807
|
-
logger26.log({ level: "error", message: error2.message });
|
|
4808
|
-
next(error2);
|
|
4809
|
-
return;
|
|
4810
|
-
}
|
|
4811
|
-
}
|
|
4812
|
-
async function disapproveRequestItem(req, res, next) {
|
|
4813
|
-
const payload = { ...req.params, ...req.body };
|
|
4814
|
-
const validation = Joi15.object({
|
|
4815
|
-
id: Joi15.string().hex().required(),
|
|
4816
|
-
remarks: Joi15.string().optional().allow("", null)
|
|
4817
|
-
});
|
|
4818
|
-
const { error } = validation.validate(payload);
|
|
4819
|
-
if (error) {
|
|
4820
|
-
logger26.log({ level: "error", message: error.message });
|
|
4821
|
-
next(new BadRequestError27(error.message));
|
|
4822
|
-
return;
|
|
4823
|
-
}
|
|
4824
|
-
try {
|
|
4825
|
-
await _disapproveRequestItem(payload.id, payload.remarks);
|
|
4826
|
-
res.json({ message: "Request item disapproved successfully." });
|
|
4827
|
-
return;
|
|
4828
|
-
} catch (error2) {
|
|
4829
|
-
logger26.log({ level: "error", message: error2.message });
|
|
4830
|
-
next(error2);
|
|
4831
|
-
return;
|
|
4832
|
-
}
|
|
4833
|
-
}
|
|
4834
|
-
return {
|
|
4835
|
-
createRequestItem,
|
|
4836
|
-
createRequestItemByBatch,
|
|
4837
|
-
getRequestItems,
|
|
4838
|
-
getRequestItemById,
|
|
4839
|
-
approveRequestItem,
|
|
4840
|
-
disapproveRequestItem
|
|
4841
|
-
};
|
|
4842
|
-
}
|
|
4843
|
-
|
|
4844
|
-
// src/models/hygiene-checkout-item.model.ts
|
|
4845
|
-
import Joi16 from "joi";
|
|
4846
|
-
import { ObjectId as ObjectId16 } from "mongodb";
|
|
4847
|
-
import { BadRequestError as BadRequestError28, logger as logger27 } from "@7365admin1/node-server-utils";
|
|
4848
|
-
var allowedCheckOutItemStatus = ["pending", "completed"];
|
|
4849
|
-
var checkOutItemSchema = Joi16.object({
|
|
4850
|
-
site: Joi16.string().hex().required(),
|
|
4851
|
-
supply: Joi16.string().hex().required(),
|
|
4852
|
-
supplyName: Joi16.string().required(),
|
|
4853
|
-
qty: Joi16.number().min(0).required(),
|
|
4854
|
-
attachment: Joi16.string().optional().allow("", null),
|
|
4855
|
-
createdBy: Joi16.string().hex().required(),
|
|
4856
|
-
createdByName: Joi16.string().required()
|
|
4857
|
-
});
|
|
4858
|
-
function MCheckOutItem(value) {
|
|
4859
|
-
const { error } = checkOutItemSchema.validate(value);
|
|
4860
|
-
if (error) {
|
|
4861
|
-
logger27.info(`Hygiene Check Out Item Model: ${error.message}`);
|
|
4862
|
-
throw new BadRequestError28(error.message);
|
|
4863
|
-
}
|
|
4864
|
-
if (value.site) {
|
|
4865
|
-
try {
|
|
4866
|
-
value.site = new ObjectId16(value.site);
|
|
4867
|
-
} catch (error2) {
|
|
4868
|
-
throw new BadRequestError28("Invalid site ID format.");
|
|
4869
|
-
}
|
|
4870
|
-
}
|
|
4871
|
-
if (value.supply) {
|
|
4872
|
-
try {
|
|
4873
|
-
value.supply = new ObjectId16(value.supply);
|
|
4874
|
-
} catch (error2) {
|
|
4875
|
-
throw new BadRequestError28("Invalid supply ID format.");
|
|
4264
|
+
throw new BadRequestError24("Invalid supply ID format.");
|
|
4876
4265
|
}
|
|
4877
4266
|
}
|
|
4878
4267
|
return {
|
|
@@ -4880,7 +4269,7 @@ function MCheckOutItem(value) {
|
|
|
4880
4269
|
supply: value.supply,
|
|
4881
4270
|
supplyName: value.supplyName,
|
|
4882
4271
|
qty: value.qty,
|
|
4883
|
-
attachment:
|
|
4272
|
+
attachment: value.attachment || [],
|
|
4884
4273
|
createdBy: value.createdBy,
|
|
4885
4274
|
createdByName: value.createdByName,
|
|
4886
4275
|
status: "pending",
|
|
@@ -4891,25 +4280,25 @@ function MCheckOutItem(value) {
|
|
|
4891
4280
|
}
|
|
4892
4281
|
|
|
4893
4282
|
// src/repositories/hygiene-checkout-item.repository.ts
|
|
4894
|
-
import { ObjectId as
|
|
4283
|
+
import { ObjectId as ObjectId15 } from "mongodb";
|
|
4895
4284
|
import {
|
|
4896
|
-
useAtlas as
|
|
4897
|
-
InternalServerError as
|
|
4898
|
-
useCache as
|
|
4899
|
-
logger as
|
|
4900
|
-
makeCacheKey as
|
|
4901
|
-
paginate as
|
|
4902
|
-
BadRequestError as
|
|
4903
|
-
NotFoundError as
|
|
4285
|
+
useAtlas as useAtlas11,
|
|
4286
|
+
InternalServerError as InternalServerError8,
|
|
4287
|
+
useCache as useCache8,
|
|
4288
|
+
logger as logger25,
|
|
4289
|
+
makeCacheKey as makeCacheKey8,
|
|
4290
|
+
paginate as paginate7,
|
|
4291
|
+
BadRequestError as BadRequestError25,
|
|
4292
|
+
NotFoundError as NotFoundError6
|
|
4904
4293
|
} from "@7365admin1/node-server-utils";
|
|
4905
4294
|
function useCheckOutItemRepository() {
|
|
4906
|
-
const db =
|
|
4295
|
+
const db = useAtlas11.getDb();
|
|
4907
4296
|
if (!db) {
|
|
4908
|
-
throw new
|
|
4297
|
+
throw new InternalServerError8("Unable to connect to server.");
|
|
4909
4298
|
}
|
|
4910
4299
|
const namespace_collection = "site.supply.checkouts";
|
|
4911
4300
|
const collection = db.collection(namespace_collection);
|
|
4912
|
-
const { delNamespace, setCache, getCache } =
|
|
4301
|
+
const { delNamespace, setCache, getCache } = useCache8(namespace_collection);
|
|
4913
4302
|
async function createIndex() {
|
|
4914
4303
|
try {
|
|
4915
4304
|
await collection.createIndexes([
|
|
@@ -4918,7 +4307,7 @@ function useCheckOutItemRepository() {
|
|
|
4918
4307
|
{ key: { status: 1 } }
|
|
4919
4308
|
]);
|
|
4920
4309
|
} catch (error) {
|
|
4921
|
-
throw new
|
|
4310
|
+
throw new InternalServerError8(
|
|
4922
4311
|
"Failed to create index on hygiene check out item."
|
|
4923
4312
|
);
|
|
4924
4313
|
}
|
|
@@ -4927,7 +4316,7 @@ function useCheckOutItemRepository() {
|
|
|
4927
4316
|
try {
|
|
4928
4317
|
await collection.createIndex({ supplyName: "text" });
|
|
4929
4318
|
} catch (error) {
|
|
4930
|
-
throw new
|
|
4319
|
+
throw new InternalServerError8(
|
|
4931
4320
|
"Failed to create text index on hygiene supply."
|
|
4932
4321
|
);
|
|
4933
4322
|
}
|
|
@@ -4937,9 +4326,9 @@ function useCheckOutItemRepository() {
|
|
|
4937
4326
|
value = MCheckOutItem(value);
|
|
4938
4327
|
const res = await collection.insertOne(value, { session });
|
|
4939
4328
|
delNamespace().then(() => {
|
|
4940
|
-
|
|
4329
|
+
logger25.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
4941
4330
|
}).catch((err) => {
|
|
4942
|
-
|
|
4331
|
+
logger25.error(
|
|
4943
4332
|
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
4944
4333
|
err
|
|
4945
4334
|
);
|
|
@@ -4964,20 +4353,20 @@ function useCheckOutItemRepository() {
|
|
|
4964
4353
|
limit
|
|
4965
4354
|
};
|
|
4966
4355
|
try {
|
|
4967
|
-
site = new
|
|
4356
|
+
site = new ObjectId15(site);
|
|
4968
4357
|
query.site = site;
|
|
4969
4358
|
cacheOptions.site = site.toString();
|
|
4970
4359
|
} catch (error) {
|
|
4971
|
-
throw new
|
|
4360
|
+
throw new BadRequestError25("Invalid site ID format.");
|
|
4972
4361
|
}
|
|
4973
4362
|
if (search) {
|
|
4974
4363
|
query.$text = { $search: search };
|
|
4975
4364
|
cacheOptions.search = search;
|
|
4976
4365
|
}
|
|
4977
|
-
const cacheKey =
|
|
4366
|
+
const cacheKey = makeCacheKey8(namespace_collection, cacheOptions);
|
|
4978
4367
|
const cachedData = await getCache(cacheKey);
|
|
4979
4368
|
if (cachedData) {
|
|
4980
|
-
|
|
4369
|
+
logger25.info(`Cache hit for key: ${cacheKey}`);
|
|
4981
4370
|
return cachedData;
|
|
4982
4371
|
}
|
|
4983
4372
|
try {
|
|
@@ -5009,37 +4398,11 @@ function useCheckOutItemRepository() {
|
|
|
5009
4398
|
preserveNullAndEmptyArrays: true
|
|
5010
4399
|
}
|
|
5011
4400
|
},
|
|
5012
|
-
{
|
|
5013
|
-
$lookup: {
|
|
5014
|
-
from: "users",
|
|
5015
|
-
let: { createdById: "$createdBy" },
|
|
5016
|
-
pipeline: [
|
|
5017
|
-
{
|
|
5018
|
-
$match: {
|
|
5019
|
-
$expr: {
|
|
5020
|
-
$and: [
|
|
5021
|
-
{ $ne: ["$$createdById", ""] },
|
|
5022
|
-
{ $eq: ["$_id", "$$createdById"] }
|
|
5023
|
-
]
|
|
5024
|
-
}
|
|
5025
|
-
}
|
|
5026
|
-
},
|
|
5027
|
-
{ $project: { name: 1 } }
|
|
5028
|
-
],
|
|
5029
|
-
as: "createdByDoc"
|
|
5030
|
-
}
|
|
5031
|
-
},
|
|
5032
|
-
{
|
|
5033
|
-
$unwind: {
|
|
5034
|
-
path: "$createdByDoc",
|
|
5035
|
-
preserveNullAndEmptyArrays: true
|
|
5036
|
-
}
|
|
5037
|
-
},
|
|
5038
4401
|
{
|
|
5039
4402
|
$project: {
|
|
5040
4403
|
supplyName: 1,
|
|
5041
4404
|
supplyQty: "$supplyDoc.qty",
|
|
5042
|
-
checkOutByName: "$
|
|
4405
|
+
checkOutByName: "$createdByName",
|
|
5043
4406
|
checkOutQty: "$qty",
|
|
5044
4407
|
createdAt: 1,
|
|
5045
4408
|
status: 1
|
|
@@ -5050,11 +4413,11 @@ function useCheckOutItemRepository() {
|
|
|
5050
4413
|
{ $limit: limit }
|
|
5051
4414
|
]).toArray();
|
|
5052
4415
|
const length = await collection.countDocuments(query);
|
|
5053
|
-
const data =
|
|
4416
|
+
const data = paginate7(items, page, limit, length);
|
|
5054
4417
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
5055
|
-
|
|
4418
|
+
logger25.info(`Cache set for key: ${cacheKey}`);
|
|
5056
4419
|
}).catch((err) => {
|
|
5057
|
-
|
|
4420
|
+
logger25.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
5058
4421
|
});
|
|
5059
4422
|
return data;
|
|
5060
4423
|
} catch (error) {
|
|
@@ -5063,86 +4426,124 @@ function useCheckOutItemRepository() {
|
|
|
5063
4426
|
}
|
|
5064
4427
|
async function getCheckOutItemById(_id, session) {
|
|
5065
4428
|
try {
|
|
5066
|
-
_id = new
|
|
4429
|
+
_id = new ObjectId15(_id);
|
|
5067
4430
|
} catch (error) {
|
|
5068
|
-
throw new
|
|
4431
|
+
throw new BadRequestError25("Invalid check out item ID format.");
|
|
5069
4432
|
}
|
|
5070
4433
|
const query = { _id };
|
|
5071
|
-
const cacheKey =
|
|
4434
|
+
const cacheKey = makeCacheKey8(namespace_collection, {
|
|
5072
4435
|
_id: _id.toString()
|
|
5073
4436
|
});
|
|
5074
4437
|
if (!session) {
|
|
5075
4438
|
const cachedData = await getCache(cacheKey);
|
|
5076
4439
|
if (cachedData) {
|
|
5077
|
-
|
|
4440
|
+
logger25.info(`Cache hit for key: ${cacheKey}`);
|
|
5078
4441
|
return cachedData;
|
|
5079
4442
|
}
|
|
5080
4443
|
} else {
|
|
5081
|
-
|
|
4444
|
+
logger25.info(`Skipping cache during transaction for key: ${cacheKey}`);
|
|
5082
4445
|
}
|
|
5083
4446
|
try {
|
|
5084
|
-
const data = await collection.aggregate(
|
|
5085
|
-
|
|
5086
|
-
|
|
5087
|
-
|
|
5088
|
-
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
5094
|
-
|
|
5095
|
-
|
|
5096
|
-
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
4447
|
+
const data = await collection.aggregate(
|
|
4448
|
+
[
|
|
4449
|
+
{ $match: query },
|
|
4450
|
+
{
|
|
4451
|
+
$lookup: {
|
|
4452
|
+
from: "site.supply.items",
|
|
4453
|
+
localField: "supply",
|
|
4454
|
+
foreignField: "_id",
|
|
4455
|
+
as: "supplyDetails"
|
|
4456
|
+
}
|
|
4457
|
+
},
|
|
4458
|
+
{
|
|
4459
|
+
$unwind: {
|
|
4460
|
+
path: "$supplyDetails",
|
|
4461
|
+
preserveNullAndEmptyArrays: true
|
|
4462
|
+
}
|
|
4463
|
+
},
|
|
4464
|
+
{
|
|
4465
|
+
$project: {
|
|
4466
|
+
site: 1,
|
|
4467
|
+
supply: 1,
|
|
4468
|
+
supplyName: 1,
|
|
4469
|
+
qty: 1,
|
|
4470
|
+
status: 1,
|
|
4471
|
+
unitOfMeasurement: "$supplyDetails.unitOfMeasurement",
|
|
4472
|
+
attachment: 1
|
|
4473
|
+
}
|
|
5108
4474
|
}
|
|
5109
|
-
|
|
5110
|
-
|
|
4475
|
+
],
|
|
4476
|
+
session ? { session } : void 0
|
|
4477
|
+
).toArray();
|
|
5111
4478
|
if (!data || data.length === 0) {
|
|
5112
|
-
throw new
|
|
4479
|
+
throw new NotFoundError6("Check out item not found.");
|
|
5113
4480
|
}
|
|
5114
4481
|
setCache(cacheKey, data[0], 15 * 60).then(() => {
|
|
5115
|
-
|
|
4482
|
+
logger25.info(`Cache set for key: ${cacheKey}`);
|
|
5116
4483
|
}).catch((err) => {
|
|
5117
|
-
|
|
4484
|
+
logger25.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
5118
4485
|
});
|
|
5119
4486
|
return data[0];
|
|
5120
4487
|
} catch (error) {
|
|
5121
4488
|
throw error;
|
|
5122
4489
|
}
|
|
5123
4490
|
}
|
|
4491
|
+
async function completeCheckOutItem(_id, session) {
|
|
4492
|
+
try {
|
|
4493
|
+
_id = new ObjectId15(_id);
|
|
4494
|
+
} catch (error) {
|
|
4495
|
+
throw new BadRequestError25("Invalid check out item ID format.");
|
|
4496
|
+
}
|
|
4497
|
+
try {
|
|
4498
|
+
const updateValue = {
|
|
4499
|
+
status: "completed",
|
|
4500
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4501
|
+
};
|
|
4502
|
+
const res = await collection.updateOne(
|
|
4503
|
+
{ _id },
|
|
4504
|
+
{ $set: updateValue },
|
|
4505
|
+
{ session }
|
|
4506
|
+
);
|
|
4507
|
+
if (res.modifiedCount === 0) {
|
|
4508
|
+
throw new InternalServerError8("Unable to complete check out item.");
|
|
4509
|
+
}
|
|
4510
|
+
delNamespace().then(() => {
|
|
4511
|
+
logger25.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
4512
|
+
}).catch((err) => {
|
|
4513
|
+
logger25.error(
|
|
4514
|
+
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
4515
|
+
err
|
|
4516
|
+
);
|
|
4517
|
+
});
|
|
4518
|
+
return res.modifiedCount;
|
|
4519
|
+
} catch (error) {
|
|
4520
|
+
throw error;
|
|
4521
|
+
}
|
|
4522
|
+
}
|
|
5124
4523
|
return {
|
|
5125
4524
|
createIndex,
|
|
5126
4525
|
createTextIndex,
|
|
5127
4526
|
createCheckOutItem,
|
|
5128
4527
|
getCheckOutItems,
|
|
5129
|
-
getCheckOutItemById
|
|
4528
|
+
getCheckOutItemById,
|
|
4529
|
+
completeCheckOutItem
|
|
5130
4530
|
};
|
|
5131
4531
|
}
|
|
5132
4532
|
|
|
5133
4533
|
// src/services/hygiene-checkout-item.service.ts
|
|
5134
|
-
import { useUserRepo
|
|
5135
|
-
import { BadRequestError as
|
|
4534
|
+
import { useUserRepo } from "@7365admin1/core";
|
|
4535
|
+
import { BadRequestError as BadRequestError26, useAtlas as useAtlas12 } from "@7365admin1/node-server-utils";
|
|
5136
4536
|
function useCheckOutItemService() {
|
|
5137
4537
|
const {
|
|
5138
4538
|
createCheckOutItem: _createCheckOutItem,
|
|
5139
|
-
getCheckOutItemById: _getCheckOutItemById
|
|
4539
|
+
getCheckOutItemById: _getCheckOutItemById,
|
|
4540
|
+
completeCheckOutItem
|
|
5140
4541
|
} = useCheckOutItemRepository();
|
|
5141
4542
|
const { getSupplyById } = useSupplyRepository();
|
|
5142
|
-
const { getUserById } =
|
|
4543
|
+
const { getUserById } = useUserRepo();
|
|
5143
4544
|
const { createStock } = useStockService();
|
|
5144
4545
|
async function createCheckOutItem(value) {
|
|
5145
|
-
const session =
|
|
4546
|
+
const session = useAtlas12.getClient()?.startSession();
|
|
5146
4547
|
try {
|
|
5147
4548
|
session?.startTransaction();
|
|
5148
4549
|
const supplyData = await getSupplyById(value.supply);
|
|
@@ -5155,9 +4556,12 @@ function useCheckOutItemService() {
|
|
|
5155
4556
|
},
|
|
5156
4557
|
session
|
|
5157
4558
|
);
|
|
5158
|
-
const checkOutItem = await _getCheckOutItemById(
|
|
4559
|
+
const checkOutItem = await _getCheckOutItemById(
|
|
4560
|
+
checkOutItemId.toString(),
|
|
4561
|
+
session
|
|
4562
|
+
);
|
|
5159
4563
|
if (!checkOutItem) {
|
|
5160
|
-
throw new
|
|
4564
|
+
throw new BadRequestError26("Failed to create check out item.");
|
|
5161
4565
|
}
|
|
5162
4566
|
const createdStocks = await createStock(
|
|
5163
4567
|
{
|
|
@@ -5168,6 +4572,7 @@ function useCheckOutItemService() {
|
|
|
5168
4572
|
true,
|
|
5169
4573
|
session
|
|
5170
4574
|
);
|
|
4575
|
+
await completeCheckOutItem(checkOutItemId.toString(), session);
|
|
5171
4576
|
await session?.commitTransaction();
|
|
5172
4577
|
return createdStocks;
|
|
5173
4578
|
} catch (error) {
|
|
@@ -5178,10 +4583,10 @@ function useCheckOutItemService() {
|
|
|
5178
4583
|
}
|
|
5179
4584
|
}
|
|
5180
4585
|
async function createCheckOutItemByBatch(value) {
|
|
5181
|
-
const session =
|
|
4586
|
+
const session = useAtlas12.getClient()?.startSession();
|
|
5182
4587
|
try {
|
|
5183
4588
|
session?.startTransaction();
|
|
5184
|
-
const { site, createdBy, items } = value;
|
|
4589
|
+
const { site, attachment, createdBy, items } = value;
|
|
5185
4590
|
const createdByData = await getUserById(createdBy);
|
|
5186
4591
|
const createdCheckOutItemIds = [];
|
|
5187
4592
|
for (const item of items) {
|
|
@@ -5192,7 +4597,7 @@ function useCheckOutItemService() {
|
|
|
5192
4597
|
supply: item.supply,
|
|
5193
4598
|
supplyName: supplyData?.name || "",
|
|
5194
4599
|
qty: item.qty,
|
|
5195
|
-
attachment
|
|
4600
|
+
attachment,
|
|
5196
4601
|
createdBy,
|
|
5197
4602
|
createdByName: createdByData?.name || ""
|
|
5198
4603
|
},
|
|
@@ -5225,8 +4630,8 @@ function useCheckOutItemService() {
|
|
|
5225
4630
|
}
|
|
5226
4631
|
|
|
5227
4632
|
// src/controllers/hygiene-checkout-item.controller.ts
|
|
5228
|
-
import
|
|
5229
|
-
import { BadRequestError as
|
|
4633
|
+
import Joi15 from "joi";
|
|
4634
|
+
import { BadRequestError as BadRequestError27, logger as logger26 } from "@7365admin1/node-server-utils";
|
|
5230
4635
|
function useCheckOutItemController() {
|
|
5231
4636
|
const {
|
|
5232
4637
|
getCheckOutItems: _getCheckOutItems,
|
|
@@ -5247,17 +4652,17 @@ function useCheckOutItemController() {
|
|
|
5247
4652
|
...req.params,
|
|
5248
4653
|
createdBy
|
|
5249
4654
|
};
|
|
5250
|
-
const validation =
|
|
5251
|
-
site:
|
|
5252
|
-
supply:
|
|
5253
|
-
qty:
|
|
5254
|
-
attachment:
|
|
5255
|
-
createdBy:
|
|
4655
|
+
const validation = Joi15.object({
|
|
4656
|
+
site: Joi15.string().hex().required(),
|
|
4657
|
+
supply: Joi15.string().hex().required(),
|
|
4658
|
+
qty: Joi15.number().min(0).required(),
|
|
4659
|
+
attachment: Joi15.array().items(Joi15.string()).optional().allow(null),
|
|
4660
|
+
createdBy: Joi15.string().hex().required()
|
|
5256
4661
|
});
|
|
5257
4662
|
const { error } = validation.validate(payload);
|
|
5258
4663
|
if (error) {
|
|
5259
|
-
|
|
5260
|
-
next(new
|
|
4664
|
+
logger26.log({ level: "error", message: error.message });
|
|
4665
|
+
next(new BadRequestError27(error.message));
|
|
5261
4666
|
return;
|
|
5262
4667
|
}
|
|
5263
4668
|
try {
|
|
@@ -5265,7 +4670,7 @@ function useCheckOutItemController() {
|
|
|
5265
4670
|
res.status(201).json({ message: "Check out item created successfully.", id });
|
|
5266
4671
|
return;
|
|
5267
4672
|
} catch (error2) {
|
|
5268
|
-
|
|
4673
|
+
logger26.log({ level: "error", message: error2.message });
|
|
5269
4674
|
next(error2);
|
|
5270
4675
|
return;
|
|
5271
4676
|
}
|
|
@@ -5281,21 +4686,21 @@ function useCheckOutItemController() {
|
|
|
5281
4686
|
...req.params,
|
|
5282
4687
|
createdBy
|
|
5283
4688
|
};
|
|
5284
|
-
const validation =
|
|
5285
|
-
site:
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
4689
|
+
const validation = Joi15.object({
|
|
4690
|
+
site: Joi15.string().hex().required(),
|
|
4691
|
+
attachment: Joi15.array().items(Joi15.string()).optional().allow(null),
|
|
4692
|
+
createdBy: Joi15.string().hex().required(),
|
|
4693
|
+
items: Joi15.array().items(
|
|
4694
|
+
Joi15.object({
|
|
4695
|
+
supply: Joi15.string().hex().required(),
|
|
4696
|
+
qty: Joi15.number().min(0).required()
|
|
5292
4697
|
})
|
|
5293
4698
|
).min(1).required()
|
|
5294
4699
|
});
|
|
5295
4700
|
const { error } = validation.validate(payload);
|
|
5296
4701
|
if (error) {
|
|
5297
|
-
|
|
5298
|
-
next(new
|
|
4702
|
+
logger26.log({ level: "error", message: error.message });
|
|
4703
|
+
next(new BadRequestError27(error.message));
|
|
5299
4704
|
return;
|
|
5300
4705
|
}
|
|
5301
4706
|
try {
|
|
@@ -5303,23 +4708,23 @@ function useCheckOutItemController() {
|
|
|
5303
4708
|
res.status(201).json({ message: "Check out items created successfully." });
|
|
5304
4709
|
return;
|
|
5305
4710
|
} catch (error2) {
|
|
5306
|
-
|
|
4711
|
+
logger26.log({ level: "error", message: error2.message });
|
|
5307
4712
|
next(error2);
|
|
5308
4713
|
return;
|
|
5309
4714
|
}
|
|
5310
4715
|
}
|
|
5311
4716
|
async function getCheckOutItems(req, res, next) {
|
|
5312
4717
|
const query = { ...req.query, ...req.params };
|
|
5313
|
-
const validation =
|
|
5314
|
-
page:
|
|
5315
|
-
limit:
|
|
5316
|
-
search:
|
|
5317
|
-
site:
|
|
4718
|
+
const validation = Joi15.object({
|
|
4719
|
+
page: Joi15.number().min(1).optional().allow("", null),
|
|
4720
|
+
limit: Joi15.number().min(1).optional().allow("", null),
|
|
4721
|
+
search: Joi15.string().optional().allow("", null),
|
|
4722
|
+
site: Joi15.string().hex().required()
|
|
5318
4723
|
});
|
|
5319
4724
|
const { error } = validation.validate(query);
|
|
5320
4725
|
if (error) {
|
|
5321
|
-
|
|
5322
|
-
next(new
|
|
4726
|
+
logger26.log({ level: "error", message: error.message });
|
|
4727
|
+
next(new BadRequestError27(error.message));
|
|
5323
4728
|
return;
|
|
5324
4729
|
}
|
|
5325
4730
|
const page = parseInt(req.query.page) ?? 1;
|
|
@@ -5336,18 +4741,18 @@ function useCheckOutItemController() {
|
|
|
5336
4741
|
res.json(data);
|
|
5337
4742
|
return;
|
|
5338
4743
|
} catch (error2) {
|
|
5339
|
-
|
|
4744
|
+
logger26.log({ level: "error", message: error2.message });
|
|
5340
4745
|
next(error2);
|
|
5341
4746
|
return;
|
|
5342
4747
|
}
|
|
5343
4748
|
}
|
|
5344
4749
|
async function getCheckOutItemById(req, res, next) {
|
|
5345
|
-
const validation =
|
|
4750
|
+
const validation = Joi15.string().hex().required();
|
|
5346
4751
|
const _id = req.params.id;
|
|
5347
4752
|
const { error, value } = validation.validate(_id);
|
|
5348
4753
|
if (error) {
|
|
5349
|
-
|
|
5350
|
-
next(new
|
|
4754
|
+
logger26.log({ level: "error", message: error.message });
|
|
4755
|
+
next(new BadRequestError27(error.message));
|
|
5351
4756
|
return;
|
|
5352
4757
|
}
|
|
5353
4758
|
try {
|
|
@@ -5355,7 +4760,7 @@ function useCheckOutItemController() {
|
|
|
5355
4760
|
res.json(data);
|
|
5356
4761
|
return;
|
|
5357
4762
|
} catch (error2) {
|
|
5358
|
-
|
|
4763
|
+
logger26.log({ level: "error", message: error2.message });
|
|
5359
4764
|
next(error2);
|
|
5360
4765
|
return;
|
|
5361
4766
|
}
|
|
@@ -5369,35 +4774,35 @@ function useCheckOutItemController() {
|
|
|
5369
4774
|
}
|
|
5370
4775
|
|
|
5371
4776
|
// src/models/hygiene-schedule-task.model.ts
|
|
5372
|
-
import { BadRequestError as
|
|
5373
|
-
import
|
|
5374
|
-
import { ObjectId as
|
|
5375
|
-
var scheduleTaskSchema =
|
|
5376
|
-
site:
|
|
5377
|
-
title:
|
|
5378
|
-
time:
|
|
5379
|
-
startDate:
|
|
5380
|
-
endDate:
|
|
5381
|
-
description:
|
|
5382
|
-
areas:
|
|
5383
|
-
|
|
5384
|
-
name:
|
|
5385
|
-
value:
|
|
4777
|
+
import { BadRequestError as BadRequestError28, logger as logger27 } from "@7365admin1/node-server-utils";
|
|
4778
|
+
import Joi16 from "joi";
|
|
4779
|
+
import { ObjectId as ObjectId16 } from "mongodb";
|
|
4780
|
+
var scheduleTaskSchema = Joi16.object({
|
|
4781
|
+
site: Joi16.string().hex().required(),
|
|
4782
|
+
title: Joi16.string().required(),
|
|
4783
|
+
time: Joi16.string().pattern(/^([0-1]\d|2[0-3]):([0-5]\d)$/).required(),
|
|
4784
|
+
startDate: Joi16.string().pattern(/^\d{4}-\d{2}-\d{2}$/).required(),
|
|
4785
|
+
endDate: Joi16.string().pattern(/^\d{4}-\d{2}-\d{2}$/).optional().allow("", null),
|
|
4786
|
+
description: Joi16.string().optional().allow("", null),
|
|
4787
|
+
areas: Joi16.array().min(1).items(
|
|
4788
|
+
Joi16.object({
|
|
4789
|
+
name: Joi16.string().required(),
|
|
4790
|
+
value: Joi16.any().required()
|
|
5386
4791
|
})
|
|
5387
4792
|
).required(),
|
|
5388
|
-
createdBy:
|
|
4793
|
+
createdBy: Joi16.string().hex().required()
|
|
5389
4794
|
});
|
|
5390
4795
|
function MScheduleTask(value) {
|
|
5391
4796
|
const { error } = scheduleTaskSchema.validate(value);
|
|
5392
4797
|
if (error) {
|
|
5393
|
-
|
|
5394
|
-
throw new
|
|
4798
|
+
logger27.info(`Hygiene Schedule Task Model: ${error.message}`);
|
|
4799
|
+
throw new BadRequestError28(error.message);
|
|
5395
4800
|
}
|
|
5396
4801
|
if (value.site) {
|
|
5397
4802
|
try {
|
|
5398
|
-
value.site = new
|
|
4803
|
+
value.site = new ObjectId16(value.site);
|
|
5399
4804
|
} catch (error2) {
|
|
5400
|
-
throw new
|
|
4805
|
+
throw new BadRequestError28("Invalid site ID format.");
|
|
5401
4806
|
}
|
|
5402
4807
|
}
|
|
5403
4808
|
if (value.areas && Array.isArray(value.areas)) {
|
|
@@ -5405,18 +4810,18 @@ function MScheduleTask(value) {
|
|
|
5405
4810
|
try {
|
|
5406
4811
|
return {
|
|
5407
4812
|
name: area.name,
|
|
5408
|
-
value: new
|
|
4813
|
+
value: new ObjectId16(area.value.toString())
|
|
5409
4814
|
};
|
|
5410
4815
|
} catch (error2) {
|
|
5411
|
-
throw new
|
|
4816
|
+
throw new BadRequestError28(`Invalid area value format: ${area.name}`);
|
|
5412
4817
|
}
|
|
5413
4818
|
});
|
|
5414
4819
|
}
|
|
5415
4820
|
if (value.createdBy) {
|
|
5416
4821
|
try {
|
|
5417
|
-
value.createdBy = new
|
|
4822
|
+
value.createdBy = new ObjectId16(value.createdBy);
|
|
5418
4823
|
} catch (error2) {
|
|
5419
|
-
throw new
|
|
4824
|
+
throw new BadRequestError28("Invalid createdBy ID format.");
|
|
5420
4825
|
}
|
|
5421
4826
|
}
|
|
5422
4827
|
return {
|
|
@@ -5436,25 +4841,25 @@ function MScheduleTask(value) {
|
|
|
5436
4841
|
}
|
|
5437
4842
|
|
|
5438
4843
|
// src/repositories/hygiene-schedule-task.repository.ts
|
|
5439
|
-
import { ObjectId as
|
|
4844
|
+
import { ObjectId as ObjectId17 } from "mongodb";
|
|
5440
4845
|
import {
|
|
5441
|
-
useAtlas as
|
|
5442
|
-
InternalServerError as
|
|
5443
|
-
paginate as
|
|
5444
|
-
BadRequestError as
|
|
5445
|
-
useCache as
|
|
5446
|
-
logger as
|
|
5447
|
-
makeCacheKey as
|
|
5448
|
-
NotFoundError as
|
|
4846
|
+
useAtlas as useAtlas13,
|
|
4847
|
+
InternalServerError as InternalServerError9,
|
|
4848
|
+
paginate as paginate8,
|
|
4849
|
+
BadRequestError as BadRequestError29,
|
|
4850
|
+
useCache as useCache9,
|
|
4851
|
+
logger as logger28,
|
|
4852
|
+
makeCacheKey as makeCacheKey9,
|
|
4853
|
+
NotFoundError as NotFoundError7
|
|
5449
4854
|
} from "@7365admin1/node-server-utils";
|
|
5450
4855
|
function useScheduleTaskRepository() {
|
|
5451
|
-
const db =
|
|
4856
|
+
const db = useAtlas13.getDb();
|
|
5452
4857
|
if (!db) {
|
|
5453
|
-
throw new
|
|
4858
|
+
throw new InternalServerError9("Unable to connect to server.");
|
|
5454
4859
|
}
|
|
5455
4860
|
const namespace_collection = "site.schedule-tasks";
|
|
5456
4861
|
const collection = db.collection(namespace_collection);
|
|
5457
|
-
const { delNamespace, setCache, getCache } =
|
|
4862
|
+
const { delNamespace, setCache, getCache } = useCache9(namespace_collection);
|
|
5458
4863
|
async function createIndex() {
|
|
5459
4864
|
try {
|
|
5460
4865
|
await collection.createIndexes([
|
|
@@ -5462,7 +4867,7 @@ function useScheduleTaskRepository() {
|
|
|
5462
4867
|
{ key: { status: 1 } }
|
|
5463
4868
|
]);
|
|
5464
4869
|
} catch (error) {
|
|
5465
|
-
throw new
|
|
4870
|
+
throw new InternalServerError9(
|
|
5466
4871
|
"Failed to create index on hygiene schedule task."
|
|
5467
4872
|
);
|
|
5468
4873
|
}
|
|
@@ -5471,7 +4876,7 @@ function useScheduleTaskRepository() {
|
|
|
5471
4876
|
try {
|
|
5472
4877
|
await collection.createIndex({ title: "text", description: "text" });
|
|
5473
4878
|
} catch (error) {
|
|
5474
|
-
throw new
|
|
4879
|
+
throw new InternalServerError9(
|
|
5475
4880
|
"Failed to create text index on hygiene schedule task."
|
|
5476
4881
|
);
|
|
5477
4882
|
}
|
|
@@ -5481,9 +4886,9 @@ function useScheduleTaskRepository() {
|
|
|
5481
4886
|
value = MScheduleTask(value);
|
|
5482
4887
|
const res = await collection.insertOne(value, { session });
|
|
5483
4888
|
delNamespace().then(() => {
|
|
5484
|
-
|
|
4889
|
+
logger28.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
5485
4890
|
}).catch((err) => {
|
|
5486
|
-
|
|
4891
|
+
logger28.error(
|
|
5487
4892
|
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
5488
4893
|
err
|
|
5489
4894
|
);
|
|
@@ -5508,20 +4913,20 @@ function useScheduleTaskRepository() {
|
|
|
5508
4913
|
limit
|
|
5509
4914
|
};
|
|
5510
4915
|
try {
|
|
5511
|
-
site = new
|
|
4916
|
+
site = new ObjectId17(site);
|
|
5512
4917
|
query.site = site;
|
|
5513
4918
|
cacheOptions.site = site.toString();
|
|
5514
4919
|
} catch (error) {
|
|
5515
|
-
throw new
|
|
4920
|
+
throw new BadRequestError29("Invalid site ID format.");
|
|
5516
4921
|
}
|
|
5517
4922
|
if (search) {
|
|
5518
4923
|
query.$or = [{ name: { $regex: search, $options: "i" } }];
|
|
5519
4924
|
cacheOptions.search = search;
|
|
5520
4925
|
}
|
|
5521
|
-
const cacheKey =
|
|
4926
|
+
const cacheKey = makeCacheKey9(namespace_collection, cacheOptions);
|
|
5522
4927
|
const cachedData = await getCache(cacheKey);
|
|
5523
4928
|
if (cachedData) {
|
|
5524
|
-
|
|
4929
|
+
logger28.info(`Cache hit for key: ${cacheKey}`);
|
|
5525
4930
|
return cachedData;
|
|
5526
4931
|
}
|
|
5527
4932
|
try {
|
|
@@ -5539,11 +4944,11 @@ function useScheduleTaskRepository() {
|
|
|
5539
4944
|
{ $limit: limit }
|
|
5540
4945
|
]).toArray();
|
|
5541
4946
|
const length = await collection.countDocuments(query);
|
|
5542
|
-
const data =
|
|
4947
|
+
const data = paginate8(items, page, limit, length);
|
|
5543
4948
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
5544
|
-
|
|
4949
|
+
logger28.info(`Cache set for key: ${cacheKey}`);
|
|
5545
4950
|
}).catch((err) => {
|
|
5546
|
-
|
|
4951
|
+
logger28.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
5547
4952
|
});
|
|
5548
4953
|
return data;
|
|
5549
4954
|
} catch (error) {
|
|
@@ -5576,20 +4981,20 @@ function useScheduleTaskRepository() {
|
|
|
5576
4981
|
limit
|
|
5577
4982
|
};
|
|
5578
4983
|
try {
|
|
5579
|
-
site = new
|
|
4984
|
+
site = new ObjectId17(site);
|
|
5580
4985
|
query.site = site;
|
|
5581
4986
|
cacheOptions.site = site.toString();
|
|
5582
4987
|
} catch (error) {
|
|
5583
|
-
throw new
|
|
4988
|
+
throw new BadRequestError29("Invalid site ID format.");
|
|
5584
4989
|
}
|
|
5585
4990
|
if (search) {
|
|
5586
4991
|
query.$or = [{ name: { $regex: search, $options: "i" } }];
|
|
5587
4992
|
cacheOptions.search = search;
|
|
5588
4993
|
}
|
|
5589
|
-
const cacheKey =
|
|
4994
|
+
const cacheKey = makeCacheKey9(namespace_collection, cacheOptions);
|
|
5590
4995
|
const cachedData = await getCache(cacheKey);
|
|
5591
4996
|
if (cachedData) {
|
|
5592
|
-
|
|
4997
|
+
logger28.info(`Cache hit for key: ${cacheKey}`);
|
|
5593
4998
|
return cachedData;
|
|
5594
4999
|
}
|
|
5595
5000
|
try {
|
|
@@ -5606,11 +5011,11 @@ function useScheduleTaskRepository() {
|
|
|
5606
5011
|
{ $limit: limit }
|
|
5607
5012
|
]).toArray();
|
|
5608
5013
|
const length = await collection.countDocuments(query);
|
|
5609
|
-
const data =
|
|
5014
|
+
const data = paginate8(items, page, limit, length);
|
|
5610
5015
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
5611
|
-
|
|
5016
|
+
logger28.info(`Cache set for key: ${cacheKey}`);
|
|
5612
5017
|
}).catch((err) => {
|
|
5613
|
-
|
|
5018
|
+
logger28.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
5614
5019
|
});
|
|
5615
5020
|
return data;
|
|
5616
5021
|
} catch (error) {
|
|
@@ -5619,25 +5024,25 @@ function useScheduleTaskRepository() {
|
|
|
5619
5024
|
}
|
|
5620
5025
|
async function getScheduleTaskById(_id, session) {
|
|
5621
5026
|
try {
|
|
5622
|
-
_id = new
|
|
5027
|
+
_id = new ObjectId17(_id);
|
|
5623
5028
|
} catch (error) {
|
|
5624
|
-
throw new
|
|
5029
|
+
throw new BadRequestError29("Invalid schedule task ID format.");
|
|
5625
5030
|
}
|
|
5626
5031
|
const query = {
|
|
5627
5032
|
_id,
|
|
5628
5033
|
status: { $ne: "deleted" }
|
|
5629
5034
|
};
|
|
5630
|
-
const cacheKey =
|
|
5035
|
+
const cacheKey = makeCacheKey9(namespace_collection, {
|
|
5631
5036
|
_id: _id.toString()
|
|
5632
5037
|
});
|
|
5633
5038
|
if (!session) {
|
|
5634
5039
|
const cachedData = await getCache(cacheKey);
|
|
5635
5040
|
if (cachedData) {
|
|
5636
|
-
|
|
5041
|
+
logger28.info(`Cache hit for key: ${cacheKey}`);
|
|
5637
5042
|
return cachedData;
|
|
5638
5043
|
}
|
|
5639
5044
|
} else {
|
|
5640
|
-
|
|
5045
|
+
logger28.info(`Skipping cache during transaction for key: ${cacheKey}`);
|
|
5641
5046
|
}
|
|
5642
5047
|
try {
|
|
5643
5048
|
const data = await collection.aggregate([
|
|
@@ -5656,12 +5061,12 @@ function useScheduleTaskRepository() {
|
|
|
5656
5061
|
}
|
|
5657
5062
|
]).toArray();
|
|
5658
5063
|
if (!data || data.length === 0) {
|
|
5659
|
-
throw new
|
|
5064
|
+
throw new NotFoundError7("Schedule task not found.");
|
|
5660
5065
|
}
|
|
5661
5066
|
setCache(cacheKey, data[0], 15 * 60).then(() => {
|
|
5662
|
-
|
|
5067
|
+
logger28.info(`Cache set for key: ${cacheKey}`);
|
|
5663
5068
|
}).catch((err) => {
|
|
5664
|
-
|
|
5069
|
+
logger28.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
5665
5070
|
});
|
|
5666
5071
|
return data[0];
|
|
5667
5072
|
} catch (error) {
|
|
@@ -5670,19 +5075,19 @@ function useScheduleTaskRepository() {
|
|
|
5670
5075
|
}
|
|
5671
5076
|
async function updateScheduleTask(_id, value, session) {
|
|
5672
5077
|
try {
|
|
5673
|
-
_id = new
|
|
5078
|
+
_id = new ObjectId17(_id);
|
|
5674
5079
|
} catch (error) {
|
|
5675
|
-
throw new
|
|
5080
|
+
throw new BadRequestError29("Invalid schedule task ID format.");
|
|
5676
5081
|
}
|
|
5677
5082
|
if (value.areas && Array.isArray(value.areas)) {
|
|
5678
5083
|
value.areas = value.areas.map((area) => {
|
|
5679
5084
|
try {
|
|
5680
5085
|
return {
|
|
5681
5086
|
name: area.name,
|
|
5682
|
-
value: new
|
|
5087
|
+
value: new ObjectId17(area.value.toString())
|
|
5683
5088
|
};
|
|
5684
5089
|
} catch (error) {
|
|
5685
|
-
throw new
|
|
5090
|
+
throw new BadRequestError29(`Invalid area value format: ${area.name}`);
|
|
5686
5091
|
}
|
|
5687
5092
|
});
|
|
5688
5093
|
}
|
|
@@ -5694,14 +5099,14 @@ function useScheduleTaskRepository() {
|
|
|
5694
5099
|
{ session }
|
|
5695
5100
|
);
|
|
5696
5101
|
if (res.modifiedCount === 0) {
|
|
5697
|
-
throw new
|
|
5102
|
+
throw new InternalServerError9(
|
|
5698
5103
|
"Unable to update hygiene schedule task."
|
|
5699
5104
|
);
|
|
5700
5105
|
}
|
|
5701
5106
|
delNamespace().then(() => {
|
|
5702
|
-
|
|
5107
|
+
logger28.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
5703
5108
|
}).catch((err) => {
|
|
5704
|
-
|
|
5109
|
+
logger28.error(
|
|
5705
5110
|
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
5706
5111
|
err
|
|
5707
5112
|
);
|
|
@@ -5724,7 +5129,7 @@ function useScheduleTaskRepository() {
|
|
|
5724
5129
|
}
|
|
5725
5130
|
|
|
5726
5131
|
// src/services/hygiene-schedule-task.service.ts
|
|
5727
|
-
import { logger as
|
|
5132
|
+
import { logger as logger29 } from "@7365admin1/node-server-utils";
|
|
5728
5133
|
function useScheduleTaskService() {
|
|
5729
5134
|
const { createParentChecklist } = useParentChecklistRepo();
|
|
5730
5135
|
const { getAllScheduleTask } = useScheduleTaskRepository();
|
|
@@ -5747,13 +5152,13 @@ function useScheduleTaskService() {
|
|
|
5747
5152
|
const currentDateString = now.toLocaleDateString("en-US", {
|
|
5748
5153
|
timeZone: "Asia/Singapore"
|
|
5749
5154
|
});
|
|
5750
|
-
|
|
5155
|
+
logger29.info(
|
|
5751
5156
|
`Checking schedule ${schedule._id}: Current time ${currentHour}:${currentMinute}, Current date ${currentDateString}, Schedule time ${schedule.time}, Start date ${schedule.startDate}, End date ${schedule.endDate}`
|
|
5752
5157
|
);
|
|
5753
5158
|
const startDate = /* @__PURE__ */ new Date(schedule.startDate + "T00:00:00");
|
|
5754
5159
|
const currentDateOnly = /* @__PURE__ */ new Date(currentDateString + "T00:00:00");
|
|
5755
5160
|
if (currentDateOnly < startDate) {
|
|
5756
|
-
|
|
5161
|
+
logger29.info(
|
|
5757
5162
|
`Schedule ${schedule._id}: Current date ${currentDateString} is before start date ${schedule.startDate}`
|
|
5758
5163
|
);
|
|
5759
5164
|
return false;
|
|
@@ -5761,7 +5166,7 @@ function useScheduleTaskService() {
|
|
|
5761
5166
|
if (schedule.endDate) {
|
|
5762
5167
|
const endDate = /* @__PURE__ */ new Date(schedule.endDate + "T00:00:00");
|
|
5763
5168
|
if (currentDateOnly > endDate) {
|
|
5764
|
-
|
|
5169
|
+
logger29.info(
|
|
5765
5170
|
`Schedule ${schedule._id}: Current date ${currentDateString} is after end date ${schedule.endDate}`
|
|
5766
5171
|
);
|
|
5767
5172
|
return false;
|
|
@@ -5770,17 +5175,17 @@ function useScheduleTaskService() {
|
|
|
5770
5175
|
const [scheduleHour, scheduleMinute] = schedule.time.split(":").map(Number);
|
|
5771
5176
|
const timeMatches = currentHour === scheduleHour && currentMinute === scheduleMinute;
|
|
5772
5177
|
if (!timeMatches) {
|
|
5773
|
-
|
|
5178
|
+
logger29.info(
|
|
5774
5179
|
`Schedule ${schedule._id}: Time does not match. Current: ${currentHour}:${currentMinute}, Expected: ${scheduleHour}:${scheduleMinute}`
|
|
5775
5180
|
);
|
|
5776
5181
|
return false;
|
|
5777
5182
|
}
|
|
5778
|
-
|
|
5183
|
+
logger29.info(
|
|
5779
5184
|
`Schedule ${schedule._id}: All conditions matched - Date is within range and time matches`
|
|
5780
5185
|
);
|
|
5781
5186
|
return true;
|
|
5782
5187
|
} catch (error) {
|
|
5783
|
-
|
|
5188
|
+
logger29.error(
|
|
5784
5189
|
`Error checking schedule conditions for ${schedule._id}:`,
|
|
5785
5190
|
error
|
|
5786
5191
|
);
|
|
@@ -5789,40 +5194,40 @@ function useScheduleTaskService() {
|
|
|
5789
5194
|
}
|
|
5790
5195
|
async function processScheduledTasks(currentDate) {
|
|
5791
5196
|
try {
|
|
5792
|
-
|
|
5197
|
+
logger29.info("Starting scheduled task processing...");
|
|
5793
5198
|
const scheduleTasks = await getAllScheduleTask();
|
|
5794
5199
|
if (!scheduleTasks || scheduleTasks.length === 0) {
|
|
5795
|
-
|
|
5200
|
+
logger29.info("No schedule tasks found to process");
|
|
5796
5201
|
return { processed: 0, validated: 0 };
|
|
5797
5202
|
}
|
|
5798
|
-
|
|
5203
|
+
logger29.info(`Found ${scheduleTasks.length} schedule tasks to check`);
|
|
5799
5204
|
let processedCount = 0;
|
|
5800
5205
|
let validatedCount = 0;
|
|
5801
5206
|
const validatedTasks = [];
|
|
5802
5207
|
for (const scheduleTask of scheduleTasks) {
|
|
5803
5208
|
try {
|
|
5804
|
-
|
|
5209
|
+
logger29.info(
|
|
5805
5210
|
`Checking schedule ${scheduleTask._id} - ${scheduleTask.title}: time=${scheduleTask.time}, startDate=${scheduleTask.startDate}, endDate=${scheduleTask.endDate}`
|
|
5806
5211
|
);
|
|
5807
5212
|
const shouldRun = checkScheduleConditions(scheduleTask, currentDate);
|
|
5808
5213
|
if (!shouldRun) {
|
|
5809
|
-
|
|
5214
|
+
logger29.info(
|
|
5810
5215
|
`Schedule ${scheduleTask._id} conditions not met, skipping`
|
|
5811
5216
|
);
|
|
5812
5217
|
continue;
|
|
5813
5218
|
}
|
|
5814
|
-
|
|
5219
|
+
logger29.info(
|
|
5815
5220
|
`Schedule ${scheduleTask._id} conditions validated, creating area checklists`
|
|
5816
5221
|
);
|
|
5817
5222
|
if (!scheduleTask._id) {
|
|
5818
|
-
|
|
5223
|
+
logger29.warn(`Schedule ${scheduleTask.title} has no _id, skipping`);
|
|
5819
5224
|
continue;
|
|
5820
5225
|
}
|
|
5821
5226
|
if (!scheduleTask.site) {
|
|
5822
|
-
|
|
5227
|
+
logger29.warn(`Schedule ${scheduleTask._id} has no site, skipping`);
|
|
5823
5228
|
continue;
|
|
5824
5229
|
}
|
|
5825
|
-
|
|
5230
|
+
logger29.info(
|
|
5826
5231
|
`Getting or creating parent checklist for schedule ${scheduleTask._id} in site ${scheduleTask.site}`
|
|
5827
5232
|
);
|
|
5828
5233
|
const parentChecklistIds = await createParentChecklist({
|
|
@@ -5830,7 +5235,7 @@ function useScheduleTaskService() {
|
|
|
5830
5235
|
createdAt: /* @__PURE__ */ new Date()
|
|
5831
5236
|
});
|
|
5832
5237
|
const parentChecklistId = Array.isArray(parentChecklistIds) ? parentChecklistIds[0] : parentChecklistIds;
|
|
5833
|
-
|
|
5238
|
+
logger29.info(
|
|
5834
5239
|
`Using parent checklist ${parentChecklistId}, now creating/updating area checklists`
|
|
5835
5240
|
);
|
|
5836
5241
|
for (const area of scheduleTask.areas) {
|
|
@@ -5843,14 +5248,14 @@ function useScheduleTaskService() {
|
|
|
5843
5248
|
unit: unit.unit.toString(),
|
|
5844
5249
|
name: unit.name
|
|
5845
5250
|
}));
|
|
5846
|
-
|
|
5251
|
+
logger29.info(
|
|
5847
5252
|
`Area ${area.name} (${areaId}): Using units from area details: ${JSON.stringify(
|
|
5848
5253
|
units
|
|
5849
5254
|
)}`
|
|
5850
5255
|
);
|
|
5851
5256
|
}
|
|
5852
5257
|
if (units.length === 0) {
|
|
5853
|
-
|
|
5258
|
+
logger29.warn(
|
|
5854
5259
|
`Area ${area.name} (${areaId}): No units found, skipping area.`
|
|
5855
5260
|
);
|
|
5856
5261
|
continue;
|
|
@@ -5861,11 +5266,11 @@ function useScheduleTaskService() {
|
|
|
5861
5266
|
parentChecklistId.toString(),
|
|
5862
5267
|
areaId
|
|
5863
5268
|
);
|
|
5864
|
-
|
|
5269
|
+
logger29.info(
|
|
5865
5270
|
`Area ${area.name} (${areaId}): Existing area checklist found: ${existingAreaChecklist ? "Yes" : "No"}`
|
|
5866
5271
|
);
|
|
5867
5272
|
if (existingAreaChecklist) {
|
|
5868
|
-
|
|
5273
|
+
logger29.info(
|
|
5869
5274
|
`Area ${area.name} (${areaId}): Existing checklist content: ${JSON.stringify(
|
|
5870
5275
|
existingAreaChecklist.checklist
|
|
5871
5276
|
)}`
|
|
@@ -5873,7 +5278,7 @@ function useScheduleTaskService() {
|
|
|
5873
5278
|
}
|
|
5874
5279
|
} catch (error) {
|
|
5875
5280
|
existingAreaChecklist = null;
|
|
5876
|
-
|
|
5281
|
+
logger29.info(
|
|
5877
5282
|
`Area ${area.name} (${areaId}): No existing area checklist found (exception).`
|
|
5878
5283
|
);
|
|
5879
5284
|
}
|
|
@@ -5887,7 +5292,7 @@ function useScheduleTaskService() {
|
|
|
5887
5292
|
...existingAreaChecklist.checklist || [],
|
|
5888
5293
|
newSet
|
|
5889
5294
|
];
|
|
5890
|
-
|
|
5295
|
+
logger29.info(
|
|
5891
5296
|
`Area ${area.name} (${areaId}): Appending new set ${newSet.set} to checklist. Updated checklist: ${JSON.stringify(
|
|
5892
5297
|
updatedChecklist
|
|
5893
5298
|
)}`
|
|
@@ -5895,7 +5300,7 @@ function useScheduleTaskService() {
|
|
|
5895
5300
|
await updateAreaChecklist(existingAreaChecklist._id, {
|
|
5896
5301
|
checklist: updatedChecklist
|
|
5897
5302
|
});
|
|
5898
|
-
|
|
5303
|
+
logger29.info(
|
|
5899
5304
|
`Appended set ${newSet.set} to area checklist for area ${area.name}`
|
|
5900
5305
|
);
|
|
5901
5306
|
try {
|
|
@@ -5903,13 +5308,13 @@ function useScheduleTaskService() {
|
|
|
5903
5308
|
parentChecklistId.toString(),
|
|
5904
5309
|
areaId
|
|
5905
5310
|
);
|
|
5906
|
-
|
|
5311
|
+
logger29.info(
|
|
5907
5312
|
`Area ${area.name} (${areaId}): Checklist after update: ${JSON.stringify(
|
|
5908
5313
|
verifyChecklist.checklist
|
|
5909
5314
|
)}`
|
|
5910
5315
|
);
|
|
5911
5316
|
} catch (verifyError) {
|
|
5912
|
-
|
|
5317
|
+
logger29.warn(
|
|
5913
5318
|
`Area ${area.name} (${areaId}): Error verifying checklist after update:`,
|
|
5914
5319
|
verifyError
|
|
5915
5320
|
);
|
|
@@ -5928,50 +5333,50 @@ function useScheduleTaskService() {
|
|
|
5928
5333
|
],
|
|
5929
5334
|
createdBy: scheduleTask.createdBy
|
|
5930
5335
|
};
|
|
5931
|
-
|
|
5336
|
+
logger29.info(
|
|
5932
5337
|
`Area ${area.name} (${areaId}): Creating new area checklist with data: ${JSON.stringify(
|
|
5933
5338
|
checklistData
|
|
5934
5339
|
)}`
|
|
5935
5340
|
);
|
|
5936
5341
|
await createAreaChecklist(checklistData);
|
|
5937
|
-
|
|
5342
|
+
logger29.info(`Created new area checklist for area ${area.name}`);
|
|
5938
5343
|
try {
|
|
5939
5344
|
const verifyChecklist = await getAreaChecklistByAreaAndSchedule(
|
|
5940
5345
|
parentChecklistId.toString(),
|
|
5941
5346
|
areaId
|
|
5942
5347
|
);
|
|
5943
|
-
|
|
5348
|
+
logger29.info(
|
|
5944
5349
|
`Area ${area.name} (${areaId}): Checklist after creation: ${JSON.stringify(
|
|
5945
5350
|
verifyChecklist.checklist
|
|
5946
5351
|
)}`
|
|
5947
5352
|
);
|
|
5948
5353
|
} catch (verifyError) {
|
|
5949
|
-
|
|
5354
|
+
logger29.warn(
|
|
5950
5355
|
`Area ${area.name} (${areaId}): Error verifying checklist after creation:`,
|
|
5951
5356
|
verifyError
|
|
5952
5357
|
);
|
|
5953
5358
|
}
|
|
5954
5359
|
}
|
|
5955
5360
|
} catch (error) {
|
|
5956
|
-
|
|
5361
|
+
logger29.error(`Error processing area ${area.name}:`, error);
|
|
5957
5362
|
continue;
|
|
5958
5363
|
}
|
|
5959
5364
|
}
|
|
5960
5365
|
processedCount++;
|
|
5961
5366
|
validatedCount++;
|
|
5962
5367
|
validatedTasks.push(scheduleTask);
|
|
5963
|
-
|
|
5368
|
+
logger29.info(
|
|
5964
5369
|
`Successfully processed schedule ${scheduleTask._id}, created/updated area checklists for all areas.`
|
|
5965
5370
|
);
|
|
5966
5371
|
} catch (error) {
|
|
5967
|
-
|
|
5372
|
+
logger29.error(
|
|
5968
5373
|
`Error processing schedule task ${scheduleTask._id}:`,
|
|
5969
5374
|
error
|
|
5970
5375
|
);
|
|
5971
5376
|
continue;
|
|
5972
5377
|
}
|
|
5973
5378
|
}
|
|
5974
|
-
|
|
5379
|
+
logger29.info(
|
|
5975
5380
|
`Scheduled task processing completed. Processed: ${processedCount}, Validated: ${validatedCount} tasks`
|
|
5976
5381
|
);
|
|
5977
5382
|
return {
|
|
@@ -5980,7 +5385,7 @@ function useScheduleTaskService() {
|
|
|
5980
5385
|
tasks: validatedTasks
|
|
5981
5386
|
};
|
|
5982
5387
|
} catch (error) {
|
|
5983
|
-
|
|
5388
|
+
logger29.error("Error processing scheduled tasks:", error);
|
|
5984
5389
|
throw error;
|
|
5985
5390
|
}
|
|
5986
5391
|
}
|
|
@@ -5988,8 +5393,8 @@ function useScheduleTaskService() {
|
|
|
5988
5393
|
}
|
|
5989
5394
|
|
|
5990
5395
|
// src/controllers/hygiene-schedule-task.controller.ts
|
|
5991
|
-
import
|
|
5992
|
-
import { BadRequestError as
|
|
5396
|
+
import Joi17 from "joi";
|
|
5397
|
+
import { BadRequestError as BadRequestError30, logger as logger30 } from "@7365admin1/node-server-utils";
|
|
5993
5398
|
function useScheduleTaskController() {
|
|
5994
5399
|
const {
|
|
5995
5400
|
createScheduleTask: _createScheduleTask,
|
|
@@ -6007,8 +5412,8 @@ function useScheduleTaskController() {
|
|
|
6007
5412
|
const payload = { ...req.body, ...req.params, createdBy };
|
|
6008
5413
|
const { error } = scheduleTaskSchema.validate(payload);
|
|
6009
5414
|
if (error) {
|
|
6010
|
-
|
|
6011
|
-
next(new
|
|
5415
|
+
logger30.log({ level: "error", message: error.message });
|
|
5416
|
+
next(new BadRequestError30(error.message));
|
|
6012
5417
|
return;
|
|
6013
5418
|
}
|
|
6014
5419
|
try {
|
|
@@ -6016,23 +5421,23 @@ function useScheduleTaskController() {
|
|
|
6016
5421
|
res.status(201).json({ message: "Schedule task created successfully.", id });
|
|
6017
5422
|
return;
|
|
6018
5423
|
} catch (error2) {
|
|
6019
|
-
|
|
5424
|
+
logger30.log({ level: "error", message: error2.message });
|
|
6020
5425
|
next(error2);
|
|
6021
5426
|
return;
|
|
6022
5427
|
}
|
|
6023
5428
|
}
|
|
6024
5429
|
async function getScheduleTasks(req, res, next) {
|
|
6025
5430
|
const query = { ...req.query, ...req.params };
|
|
6026
|
-
const validation =
|
|
6027
|
-
page:
|
|
6028
|
-
limit:
|
|
6029
|
-
search:
|
|
6030
|
-
site:
|
|
5431
|
+
const validation = Joi17.object({
|
|
5432
|
+
page: Joi17.number().min(1).optional().allow("", null),
|
|
5433
|
+
limit: Joi17.number().min(1).optional().allow("", null),
|
|
5434
|
+
search: Joi17.string().optional().allow("", null),
|
|
5435
|
+
site: Joi17.string().hex().required()
|
|
6031
5436
|
});
|
|
6032
5437
|
const { error } = validation.validate(query);
|
|
6033
5438
|
if (error) {
|
|
6034
|
-
|
|
6035
|
-
next(new
|
|
5439
|
+
logger30.log({ level: "error", message: error.message });
|
|
5440
|
+
next(new BadRequestError30(error.message));
|
|
6036
5441
|
return;
|
|
6037
5442
|
}
|
|
6038
5443
|
const page = parseInt(req.query.page) ?? 1;
|
|
@@ -6049,23 +5454,23 @@ function useScheduleTaskController() {
|
|
|
6049
5454
|
res.json(data);
|
|
6050
5455
|
return;
|
|
6051
5456
|
} catch (error2) {
|
|
6052
|
-
|
|
5457
|
+
logger30.log({ level: "error", message: error2.message });
|
|
6053
5458
|
next(error2);
|
|
6054
5459
|
return;
|
|
6055
5460
|
}
|
|
6056
5461
|
}
|
|
6057
5462
|
async function getTasksForScheduleTask(req, res, next) {
|
|
6058
5463
|
const query = { ...req.query, ...req.params };
|
|
6059
|
-
const validation =
|
|
6060
|
-
page:
|
|
6061
|
-
limit:
|
|
6062
|
-
search:
|
|
6063
|
-
site:
|
|
5464
|
+
const validation = Joi17.object({
|
|
5465
|
+
page: Joi17.number().min(1).optional().allow("", null),
|
|
5466
|
+
limit: Joi17.number().min(1).optional().allow("", null),
|
|
5467
|
+
search: Joi17.string().optional().allow("", null),
|
|
5468
|
+
site: Joi17.string().hex().required()
|
|
6064
5469
|
});
|
|
6065
5470
|
const { error } = validation.validate(query);
|
|
6066
5471
|
if (error) {
|
|
6067
|
-
|
|
6068
|
-
next(new
|
|
5472
|
+
logger30.log({ level: "error", message: error.message });
|
|
5473
|
+
next(new BadRequestError30(error.message));
|
|
6069
5474
|
return;
|
|
6070
5475
|
}
|
|
6071
5476
|
const page = parseInt(req.query.page) ?? 1;
|
|
@@ -6082,18 +5487,18 @@ function useScheduleTaskController() {
|
|
|
6082
5487
|
res.json(data);
|
|
6083
5488
|
return;
|
|
6084
5489
|
} catch (error2) {
|
|
6085
|
-
|
|
5490
|
+
logger30.log({ level: "error", message: error2.message });
|
|
6086
5491
|
next(error2);
|
|
6087
5492
|
return;
|
|
6088
5493
|
}
|
|
6089
5494
|
}
|
|
6090
5495
|
async function getScheduleTaskById(req, res, next) {
|
|
6091
|
-
const validation =
|
|
5496
|
+
const validation = Joi17.string().hex().required();
|
|
6092
5497
|
const _id = req.params.id;
|
|
6093
5498
|
const { error, value } = validation.validate(_id);
|
|
6094
5499
|
if (error) {
|
|
6095
|
-
|
|
6096
|
-
next(new
|
|
5500
|
+
logger30.log({ level: "error", message: error.message });
|
|
5501
|
+
next(new BadRequestError30(error.message));
|
|
6097
5502
|
return;
|
|
6098
5503
|
}
|
|
6099
5504
|
try {
|
|
@@ -6101,31 +5506,31 @@ function useScheduleTaskController() {
|
|
|
6101
5506
|
res.json(data);
|
|
6102
5507
|
return;
|
|
6103
5508
|
} catch (error2) {
|
|
6104
|
-
|
|
5509
|
+
logger30.log({ level: "error", message: error2.message });
|
|
6105
5510
|
next(error2);
|
|
6106
5511
|
return;
|
|
6107
5512
|
}
|
|
6108
5513
|
}
|
|
6109
5514
|
async function updateScheduleTask(req, res, next) {
|
|
6110
5515
|
const payload = { id: req.params.id, ...req.body };
|
|
6111
|
-
const validation =
|
|
6112
|
-
id:
|
|
6113
|
-
title:
|
|
6114
|
-
time:
|
|
6115
|
-
startDate:
|
|
6116
|
-
endDate:
|
|
6117
|
-
description:
|
|
6118
|
-
areas:
|
|
6119
|
-
|
|
6120
|
-
name:
|
|
6121
|
-
value:
|
|
5516
|
+
const validation = Joi17.object({
|
|
5517
|
+
id: Joi17.string().hex().required(),
|
|
5518
|
+
title: Joi17.string().optional().allow("", null),
|
|
5519
|
+
time: Joi17.string().pattern(/^([0-1]\d|2[0-3]):([0-5]\d)$/).optional().allow("", null),
|
|
5520
|
+
startDate: Joi17.string().pattern(/^\d{4}-\d{2}-\d{2}$/).optional().allow("", null),
|
|
5521
|
+
endDate: Joi17.string().pattern(/^\d{4}-\d{2}-\d{2}$/).optional().allow("", null),
|
|
5522
|
+
description: Joi17.string().optional().allow("", null),
|
|
5523
|
+
areas: Joi17.array().min(1).items(
|
|
5524
|
+
Joi17.object({
|
|
5525
|
+
name: Joi17.string().required(),
|
|
5526
|
+
value: Joi17.any().required()
|
|
6122
5527
|
})
|
|
6123
5528
|
).optional()
|
|
6124
5529
|
});
|
|
6125
5530
|
const { error } = validation.validate(payload);
|
|
6126
5531
|
if (error) {
|
|
6127
|
-
|
|
6128
|
-
next(new
|
|
5532
|
+
logger30.log({ level: "error", message: error.message });
|
|
5533
|
+
next(new BadRequestError30(error.message));
|
|
6129
5534
|
return;
|
|
6130
5535
|
}
|
|
6131
5536
|
try {
|
|
@@ -6134,7 +5539,7 @@ function useScheduleTaskController() {
|
|
|
6134
5539
|
res.json({ message: "Schedule task updated successfully." });
|
|
6135
5540
|
return;
|
|
6136
5541
|
} catch (error2) {
|
|
6137
|
-
|
|
5542
|
+
logger30.log({ level: "error", message: error2.message });
|
|
6138
5543
|
next(error2);
|
|
6139
5544
|
return;
|
|
6140
5545
|
}
|
|
@@ -6152,7 +5557,6 @@ export {
|
|
|
6152
5557
|
MAreaChecklist,
|
|
6153
5558
|
MCheckOutItem,
|
|
6154
5559
|
MParentChecklist,
|
|
6155
|
-
MRequestItem,
|
|
6156
5560
|
MScheduleTask,
|
|
6157
5561
|
MStock,
|
|
6158
5562
|
MSupply,
|
|
@@ -6160,14 +5564,12 @@ export {
|
|
|
6160
5564
|
allowedCheckOutItemStatus,
|
|
6161
5565
|
allowedChecklistStatus,
|
|
6162
5566
|
allowedPeriods,
|
|
6163
|
-
allowedRequestItemStatus,
|
|
6164
5567
|
allowedStatus,
|
|
6165
5568
|
allowedTypes,
|
|
6166
5569
|
areaChecklistSchema,
|
|
6167
5570
|
areaSchema,
|
|
6168
5571
|
checkOutItemSchema,
|
|
6169
5572
|
parentChecklistSchema,
|
|
6170
|
-
requestItemSchema,
|
|
6171
5573
|
scheduleTaskSchema,
|
|
6172
5574
|
stockSchema,
|
|
6173
5575
|
supplySchema,
|
|
@@ -6185,9 +5587,6 @@ export {
|
|
|
6185
5587
|
useHygieneDashboardRepository,
|
|
6186
5588
|
useParentChecklistController,
|
|
6187
5589
|
useParentChecklistRepo,
|
|
6188
|
-
useRequestItemController,
|
|
6189
|
-
useRequestItemRepository,
|
|
6190
|
-
useRequestItemService,
|
|
6191
5590
|
useScheduleTaskController,
|
|
6192
5591
|
useScheduleTaskRepository,
|
|
6193
5592
|
useScheduleTaskService,
|