diff --git a/src/app.ts b/src/app.ts index ee4eced4..eb97cdfd 100644 --- a/src/app.ts +++ b/src/app.ts @@ -37,8 +37,11 @@ async function main() { const APP_PORT = +(process.env.APP_PORT || 3000); const cronTime = "0 8 * * * *"; // ตั้งเวลาทุกวันเวลา 08:00:00 + // const cronTime = "*/10 * * * * *"; cron.schedule(cronTime, async () => { try { + console.log("[Runing cronjob]"); + const orgController = new OrganizationController(); await orgController.cronjobRevision(); } catch (error) { diff --git a/src/controllers/CommandController.ts b/src/controllers/CommandController.ts index a677171c..4cb88806 100644 --- a/src/controllers/CommandController.ts +++ b/src/controllers/CommandController.ts @@ -1091,9 +1091,8 @@ export class CommandController extends Controller { } async cronjobCommand(@Request() request?: RequestWithUser) { - console.log(request); const today = new Date(); - today.setHours(7, 0, 0, 0); //+7 เพื่อให้ตรง local time (อาจจะต้องใช้ moment) + today.setUTCHours(0, 0, 0, 0); const tomorrow = new Date(today); tomorrow.setDate(tomorrow.getDate() + 1); diff --git a/src/controllers/OrganizationController.ts b/src/controllers/OrganizationController.ts index ee160ad0..e4c80cdd 100644 --- a/src/controllers/OrganizationController.ts +++ b/src/controllers/OrganizationController.ts @@ -31,6 +31,7 @@ import permission from "../interfaces/permission"; import { PermissionOrg } from "../entities/PermissionOrg"; import { setLogDataDiff } from "../interfaces/utils"; import { AuthRole } from "../entities/AuthRole"; +import { sendToQueue, sendToQueueOrg } from "../services/rabbitmq"; @Route("api/v1/org") @Tags("Organization") @@ -120,7 +121,6 @@ export class OrganizationController extends Controller { @Body() requestBody: CreateOrgRevision, @Request() request: RequestWithUser, ) { - console.log("fucntion draft"); //new main revision const before = null; const revision = Object.assign(new OrgRevision(), requestBody) as OrgRevision; @@ -3408,76 +3408,18 @@ export class OrganizationController extends Controller { orgRevisionDraft.orgRevisionIsCurrent = true; orgRevisionDraft.orgRevisionIsDraft = false; await this.orgRevisionRepository.save(orgRevisionDraft); - - const posMaster = await this.posMasterRepository.find({ - where: { orgRevisionId: orgRevisionDraft.id }, - relations: [ - "orgRoot", - "orgChild4", - "orgChild3", - "orgChild2", - "orgChild1", - "positions", - "positions.posLevel", - "positions.posType", - "positions.posExecutive", - ], - }); - await Promise.all( - posMaster.map(async (item) => { - // if(item.next_holderId != null){ - if (item.next_holderId != null) { - const profile = await this.profileRepo.findOne({ - where: { id: item.next_holderId == null ? "" : item.next_holderId }, - }); - const position = await item.positions.find((x) => x.positionIsSelected == true); - const _null: any = null; - if (profile != null) { - profile.posLevelId = position?.posLevelId ?? _null; - profile.posTypeId = position?.posTypeId ?? _null; - profile.position = position?.positionName ?? _null; - await this.profileRepo.save(profile); - } - // const profileSalary = await this.salaryRepository.findOne({ - // where: { profileId: item.next_holderId }, - // order: { createdAt: "DESC" }, - // }); - - // const shortName = - // item != null && item.orgChild4 != null - // ? `${item.orgChild4.orgChild4ShortName}${item.posMasterNo}` - // : item != null && item?.orgChild3 != null - // ? `${item.orgChild3.orgChild3ShortName}${item.posMasterNo}` - // : item != null && item?.orgChild2 != null - // ? `${item.orgChild2.orgChild2ShortName}${item.posMasterNo}` - // : item != null && item?.orgChild1 != null - // ? `${item.orgChild1.orgChild1ShortName}${item.posMasterNo}` - // : item != null && item?.orgRoot != null - // ? `${item.orgRoot.orgRootShortName}${item.posMasterNo}` - // : null; - // await new FunctionMain().newSalaryFunction(request, { - // profileId: item.next_holderId, - // date: new Date(), - // amount: profileSalary?.amount ?? null, - // positionSalaryAmount: profileSalary?.positionSalaryAmount ?? null, - // mouthSalaryAmount: profileSalary?.mouthSalaryAmount ?? null, - // posNo: shortName, - // position: position?.positionName ?? _null, - // positionLine: position?.positionField ?? _null, - // positionPathSide: position?.positionArea ?? _null, - // positionExecutive: position?.posExecutive?.posExecutiveName ?? _null, - // positionType: position?.posType?.posTypeName ?? _null, - // positionLevel: position?.posLevel?.posLevelName ?? _null, - // refCommandNo: null, - // templateDoc: "ปรับโครงสร้าง", - // }); - } - item.current_holderId = item.next_holderId; - item.next_holderId = null; - await this.posMasterRepository.save(item); - // } - }), - ); + const msg = { + data: { + id: orgRevisionDraft.id, + status: "NOW", + lastUpdateUserId: request.user.sub, + lastUpdateFullName: request.user.name, + lastUpdatedAt: new Date(), + }, + user: request.user, + token: request.headers["authorization"], + }; + sendToQueueOrg(msg); return new HttpSuccess(); } @@ -3486,7 +3428,10 @@ export class OrganizationController extends Controller { */ async cronjobRevision() { const today = new Date(); - today.setHours(0, 0, 0, 0); // Set time to the beginning of the day + today.setUTCHours(0, 0, 0, 0); // Set time to the beginning of the day + const tomorrow = new Date(today); + tomorrow.setDate(tomorrow.getDate() + 1); + const orgRevisionPublish = await this.orgRevisionRepository .createQueryBuilder("orgRevision") .where("orgRevision.orgRevisionIsDraft = false") @@ -3497,8 +3442,9 @@ export class OrganizationController extends Controller { .createQueryBuilder("orgRevision") .where("orgRevision.orgRevisionIsDraft = true") .andWhere("orgRevision.orgRevisionIsCurrent = false") - .andWhere("DATE(orgRevision.orgPublishDate) = :today", { today }) + .andWhere("orgRevision.orgPublishDate BETWEEN :today AND :tomorrow", { today, tomorrow }) .getOne(); + if (!orgRevisionDraft) { return new HttpSuccess(); } @@ -3511,17 +3457,26 @@ export class OrganizationController extends Controller { orgRevisionDraft.orgRevisionIsDraft = false; await this.orgRevisionRepository.save(orgRevisionDraft); - const posMaster = await this.posMasterRepository.find({ - where: { orgRevisionId: orgRevisionDraft.id }, - }); - posMaster.forEach(async (item) => { - // if(item.next_holderId != null){ - item.current_holderId = item.next_holderId; - item.next_holderId = null; - await this.posMasterRepository.save(item); - // } - }); - + // const posMaster = await this.posMasterRepository.find({ + // where: { orgRevisionId: orgRevisionDraft.id }, + // }); + // posMaster.forEach(async (item) => { + // // if(item.next_holderId != null){ + // item.current_holderId = item.next_holderId; + // item.next_holderId = null; + // await this.posMasterRepository.save(item); + // // } + // }); + const msg = { + data: { + id: orgRevisionDraft.id, + status: "ON_SCHEDULE", + lastUpdateUserId: "system", + lastUpdateFullName: "system", + lastUpdatedAt: new Date(), + } + }; + sendToQueueOrg(msg); return new HttpSuccess(); } diff --git a/src/services/rabbitmq.ts b/src/services/rabbitmq.ts index 7d53079c..1ad374b4 100644 --- a/src/services/rabbitmq.ts +++ b/src/services/rabbitmq.ts @@ -6,20 +6,23 @@ import CallAPI from "../interfaces/call-api"; import HttpError from "../interfaces/http-error"; import HttpStatusCode from "../interfaces/http-status"; import { RequestWithUser } from "../middlewares/user"; +import { PosMaster } from "../entities/PosMaster"; +import { Profile } from "../entities/Profile"; export let sendToQueue: (payload: any) => void; - +export let sendToQueueOrg: (payload: any) => void; export async function init() { //----> (1) Producer - if (!process.env.AMQ_URL || !process.env.AMQ_QUEUE) return; + if (!process.env.AMQ_URL || !process.env.AMQ_QUEUE || !process.env.AMQ_QUEUE_ORG) return; - const { AMQ_URL: url, AMQ_QUEUE: queue } = process.env; //----> (1.2) get url and queue from .env + const { AMQ_URL: url, AMQ_QUEUE: queue, AMQ_QUEUE_ORG: queue_org } = process.env; //----> (1.2) get url and queue from .env const connection = await amqp.connect(url); //----> (1.3) set up url with amqp protocol const channel = await connection.createChannel(); //----> (1.4) create Channel channel.assertQueue(queue, { durable: true }); //----> (1.5) assert queue and set durable (if "true" save to disk on RabbitMQ) + channel.assertQueue(queue_org, { durable: true }); channel.prefetch(1); sendToQueue = (payload: any, persistent = true) => { @@ -29,10 +32,14 @@ export async function init() { }); }; + sendToQueueOrg = (payload: any, persistent = true) => { + channel.sendToQueue(queue_org, Buffer.from(JSON.stringify(payload)), { persistent }); + }; + console.log("[AMQ] Listening for message..."); createConsumer(queue, channel, handler); //----> (3) Process Consumer - // createConsumer(queue1, channel, handler1); + createConsumer(queue_org, channel, handler_org); // createConsumer(queue2, channel, handler2); } @@ -107,24 +114,54 @@ async function handler(msg: amqp.ConsumeMessage): Promise { }); } -// async function handler(msg: amqp.ConsumeMessage): Promise { //----> condition before process consumer -// const repo = AppDataSource.getRepository(Command); - -// const { id, status, lastUpdateUserId, lastUpdateFullName, lastUpdatedAt } = JSON.parse( -// msg.content.toString(), -// ); - -// const record = await repo.findOne({ -// where: { id }, -// }); - -// if (!record) return true; - -// Object.assign(record, { status, lastUpdateUserId, lastUpdateFullName, lastUpdatedAt }); - -// const result = await repo.save(record).catch((e) => console.log(e)); - -// if (result) return true; - -// return false; -// } +async function handler_org(msg: amqp.ConsumeMessage): Promise { + //----> condition before process consume + const repoPosmaster = AppDataSource.getRepository(PosMaster); + const repoProfile = AppDataSource.getRepository(Profile); + const { data, token, user } = JSON.parse(msg.content.toString()); + const { id, status, lastUpdateUserId, lastUpdateFullName, lastUpdatedAt } = data; + try { + const posMaster = await repoPosmaster.find({ + where: { orgRevisionId: id }, + relations: [ + "orgRoot", + "orgChild4", + "orgChild3", + "orgChild2", + "orgChild1", + "positions", + "positions.posLevel", + "positions.posType", + "positions.posExecutive", + ], + }); + await Promise.all( + posMaster.map(async (item) => { + if (item.next_holderId != null && status == "NOW") { + const profile = await repoProfile.findOne({ + where: { id: item.next_holderId == null ? "" : item.next_holderId }, + }); + const position = await item.positions.find((x) => x.positionIsSelected == true); + const _null: any = null; + if (profile != null) { + profile.posLevelId = position?.posLevelId ?? _null; + profile.posTypeId = position?.posTypeId ?? _null; + profile.position = position?.positionName ?? _null; + await repoProfile.save(profile); + } + } + item.current_holderId = item.next_holderId; + item.next_holderId = null; + item.lastUpdateUserId = lastUpdateUserId; + item.lastUpdateFullName = lastUpdateFullName; + item.lastUpdatedAt = lastUpdatedAt; + await repoPosmaster.save(item).catch((e) => console.log(e)); + }), + ); + console.log("[AMQ] Excecute Organization Success"); + return true; + } catch (error) { + console.error(error); + return false; + } +}