Compare commits
5 commits
36b1469016
...
e374f2e339
| Author | SHA1 | Date | |
|---|---|---|---|
| e374f2e339 | |||
| bca04f2881 | |||
| 9a5184bb55 | |||
| a28c099f86 | |||
| 300f073638 |
7 changed files with 418 additions and 90 deletions
|
|
@ -123,18 +123,25 @@ export class AuthRoleController extends Controller {
|
||||||
|
|
||||||
// เช็คว่าถ้ามีค่า current_holderId ให้ลบ key สิทธิ์ใน redis
|
// เช็คว่าถ้ามีค่า current_holderId ให้ลบ key สิทธิ์ใน redis
|
||||||
if (posMaster.current_holderId) {
|
if (posMaster.current_holderId) {
|
||||||
const redisClient = await this.redis.createClient({
|
let redisClient;
|
||||||
host: REDIS_HOST,
|
try {
|
||||||
port: REDIS_PORT,
|
redisClient = await this.redis.createClient({
|
||||||
});
|
host: REDIS_HOST,
|
||||||
|
port: REDIS_PORT,
|
||||||
|
});
|
||||||
|
|
||||||
redisClient.del("role_" + posMaster.current_holderId, (err: Error, response: Response) => {
|
redisClient.del("role_" + posMaster.current_holderId, (err: Error) => {
|
||||||
if (err) throw err;
|
if (err) console.error("Redis delete role error:", err);
|
||||||
});
|
});
|
||||||
|
|
||||||
redisClient.del("menu_" + posMaster.current_holderId, (err: Error, response: Response) => {
|
redisClient.del("menu_" + posMaster.current_holderId, (err: Error) => {
|
||||||
if (err) throw err;
|
if (err) console.error("Redis delete menu error:", err);
|
||||||
});
|
});
|
||||||
|
} finally {
|
||||||
|
if (redisClient) {
|
||||||
|
redisClient.quit();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new HttpSuccess();
|
return new HttpSuccess();
|
||||||
|
|
@ -260,20 +267,45 @@ export class AuthRoleController extends Controller {
|
||||||
return newAttr;
|
return newAttr;
|
||||||
});
|
});
|
||||||
const before = structuredClone(record);
|
const before = structuredClone(record);
|
||||||
await Promise.all([
|
|
||||||
this.authRoleRepo.save(record, { data: req }),
|
|
||||||
setLogDataDiff(req, { before, after: record }),
|
|
||||||
...newAttrs.map((attr) => this.authRoleAttrRepo.save(attr)),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const redisClient = await this.redis.createClient({
|
const queryRunner = AppDataSource.createQueryRunner();
|
||||||
host: REDIS_HOST,
|
await queryRunner.connect();
|
||||||
port: REDIS_PORT,
|
await queryRunner.startTransaction();
|
||||||
});
|
|
||||||
|
|
||||||
await redisClient.flushdb(function (err: any, succeeded: any) {
|
try {
|
||||||
console.log(succeeded); // will be true if successfull
|
await queryRunner.manager.save(AuthRole, record);
|
||||||
});
|
await Promise.all(
|
||||||
|
newAttrs.map((attr) => queryRunner.manager.save(AuthRoleAttr, attr))
|
||||||
|
);
|
||||||
|
await queryRunner.commitTransaction();
|
||||||
|
|
||||||
|
setLogDataDiff(req, { before, after: record });
|
||||||
|
} catch (error) {
|
||||||
|
await queryRunner.rollbackTransaction();
|
||||||
|
console.error("Error saving auth role:", error);
|
||||||
|
throw new HttpError(
|
||||||
|
HttpStatusCode.INTERNAL_SERVER_ERROR,
|
||||||
|
"เกิดข้อผิดพลาดในการบันทึกข้อมูลบทบาท กรุณาลองใหม่ในภายหลัง"
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
await queryRunner.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
let redisClient;
|
||||||
|
try {
|
||||||
|
redisClient = await this.redis.createClient({
|
||||||
|
host: REDIS_HOST,
|
||||||
|
port: REDIS_PORT,
|
||||||
|
});
|
||||||
|
|
||||||
|
await redisClient.flushdb(function (err: any, succeeded: any) {
|
||||||
|
console.log(succeeded); // will be true if successfull
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
if (redisClient) {
|
||||||
|
redisClient.quit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new HttpSuccess();
|
return new HttpSuccess();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import {
|
||||||
Path,
|
Path,
|
||||||
Request,
|
Request,
|
||||||
Response,
|
Response,
|
||||||
Get
|
Get,
|
||||||
} from "tsoa";
|
} from "tsoa";
|
||||||
import { LessThan, MoreThan } from "typeorm";
|
import { LessThan, MoreThan } from "typeorm";
|
||||||
import { AppDataSource } from "../database/data-source";
|
import { AppDataSource } from "../database/data-source";
|
||||||
|
|
@ -37,9 +37,7 @@ export class CommandOperatorController extends Controller {
|
||||||
* @param commandId คีย์คำสั่ง
|
* @param commandId คีย์คำสั่ง
|
||||||
*/
|
*/
|
||||||
@Get("{commandId}")
|
@Get("{commandId}")
|
||||||
async getCommandOperatorByCommandId(
|
async getCommandOperatorByCommandId(@Path() commandId: string) {
|
||||||
@Path() commandId: string
|
|
||||||
) {
|
|
||||||
const command = await this.commandRepo.findOne({
|
const command = await this.commandRepo.findOne({
|
||||||
where: { id: commandId },
|
where: { id: commandId },
|
||||||
select: { id: true },
|
select: { id: true },
|
||||||
|
|
@ -61,10 +59,7 @@ export class CommandOperatorController extends Controller {
|
||||||
* @param operatorId คีย์เจ้าหน้าที่ดำเนินการ
|
* @param operatorId คีย์เจ้าหน้าที่ดำเนินการ
|
||||||
*/
|
*/
|
||||||
@Get("swap/{direction}/{operatorId}")
|
@Get("swap/{direction}/{operatorId}")
|
||||||
async swapCommandOperator(
|
async swapCommandOperator(@Path() direction: string, @Path() operatorId: string) {
|
||||||
@Path() direction: string,
|
|
||||||
@Path() operatorId: string,
|
|
||||||
) {
|
|
||||||
const source = await this.commandOperatorRepo.findOne({
|
const source = await this.commandOperatorRepo.findOne({
|
||||||
where: { id: operatorId },
|
where: { id: operatorId },
|
||||||
});
|
});
|
||||||
|
|
@ -106,10 +101,7 @@ export class CommandOperatorController extends Controller {
|
||||||
source.orderNo = dest.orderNo;
|
source.orderNo = dest.orderNo;
|
||||||
dest.orderNo = temp;
|
dest.orderNo = temp;
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([this.commandOperatorRepo.save(source), this.commandOperatorRepo.save(dest)]);
|
||||||
this.commandOperatorRepo.save(source),
|
|
||||||
this.commandOperatorRepo.save(dest),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return new HttpSuccess();
|
return new HttpSuccess();
|
||||||
}
|
}
|
||||||
|
|
@ -141,35 +133,29 @@ export class CommandOperatorController extends Controller {
|
||||||
const nextOrderNo = (lastOrderNo?.orderNo ?? 1) + 1;
|
const nextOrderNo = (lastOrderNo?.orderNo ?? 1) + 1;
|
||||||
|
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const operator = Object.assign(
|
const operator = Object.assign(new CommandOperator(), {
|
||||||
new CommandOperator(),
|
...body,
|
||||||
{
|
commandId: command.id,
|
||||||
...body,
|
orderNo: nextOrderNo,
|
||||||
commandId: command.id,
|
createdUserId: request.user.sub,
|
||||||
orderNo: nextOrderNo,
|
createdFullName: request.user.name,
|
||||||
createdUserId: request.user.sub,
|
createdAt: now,
|
||||||
createdFullName: request.user.name,
|
lastUpdateUserId: request.user.sub,
|
||||||
createdAt: now,
|
lastUpdateFullName: request.user.name,
|
||||||
lastUpdateUserId: request.user.sub,
|
lastUpdatedAt: now,
|
||||||
lastUpdateFullName: request.user.name,
|
});
|
||||||
lastUpdatedAt: now,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
await this.commandOperatorRepo.save(operator);
|
await this.commandOperatorRepo.save(operator);
|
||||||
return new HttpSuccess();
|
return new HttpSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API ลบเจ้าหน้าที่ดำเนินการที่คำสั่ง
|
* API ลบเจ้าหน้าที่ดำเนินการที่คำสั่ง
|
||||||
* @summary API ลบเจ้าหน้าที่ดำเนินการที่คำสั่ง
|
* @summary API ลบเจ้าหน้าที่ดำเนินการที่คำสั่ง
|
||||||
* @param commandId คีย์คำสั่ง
|
* @param commandId คีย์คำสั่ง
|
||||||
* @param operatorId คีย์เจ้าหน้าที่ดำเนินการ
|
* @param operatorId คีย์เจ้าหน้าที่ดำเนินการ
|
||||||
*/
|
*/
|
||||||
@Delete("{commandId}/{operatorId}")
|
@Delete("{commandId}/{operatorId}")
|
||||||
public async deleteCommandOperator(
|
public async deleteCommandOperator(@Path() commandId: string, @Path() operatorId: string) {
|
||||||
@Path() commandId: string,
|
|
||||||
@Path() operatorId: string,
|
|
||||||
) {
|
|
||||||
const queryRunner = AppDataSource.createQueryRunner();
|
const queryRunner = AppDataSource.createQueryRunner();
|
||||||
await queryRunner.connect();
|
await queryRunner.connect();
|
||||||
await queryRunner.startTransaction();
|
await queryRunner.startTransaction();
|
||||||
|
|
@ -215,10 +201,9 @@ export class CommandOperatorController extends Controller {
|
||||||
return new HttpSuccess(true);
|
return new HttpSuccess(true);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await queryRunner.rollbackTransaction();
|
await queryRunner.rollbackTransaction();
|
||||||
throw error;
|
console.error("Delete command operator error:", error);
|
||||||
} finally {
|
} finally {
|
||||||
await queryRunner.release();
|
await queryRunner.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -214,6 +214,7 @@ export class OrganizationController extends Controller {
|
||||||
await sendToQueueOrgDraft(msg);
|
await sendToQueueOrgDraft(msg);
|
||||||
return new HttpSuccess("Draft is being created... Processing in the background.");
|
return new HttpSuccess("Draft is being created... Processing in the background.");
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
|
console.error("Error creating draft organization:", error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2529,6 +2530,7 @@ export class OrganizationController extends Controller {
|
||||||
await sendToQueueOrg(msg);
|
await sendToQueueOrg(msg);
|
||||||
return new HttpSuccess();
|
return new HttpSuccess();
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
|
console.error("Error publishing draft organization:", error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,11 +37,13 @@ export class PermissionController extends Controller {
|
||||||
|
|
||||||
@Get("")
|
@Get("")
|
||||||
public async getPermission(@Request() request: RequestWithUser) {
|
public async getPermission(@Request() request: RequestWithUser) {
|
||||||
const redisClient = await this.redis.createClient({
|
let redisClient;
|
||||||
host: REDIS_HOST,
|
try {
|
||||||
port: REDIS_PORT,
|
redisClient = await this.redis.createClient({
|
||||||
});
|
host: REDIS_HOST,
|
||||||
const getAsync = promisify(redisClient.get).bind(redisClient);
|
port: REDIS_PORT,
|
||||||
|
});
|
||||||
|
const getAsync = promisify(redisClient.get).bind(redisClient);
|
||||||
|
|
||||||
let profile: any = await this.profileRepo.findOne({
|
let profile: any = await this.profileRepo.findOne({
|
||||||
select: ["id"],
|
select: ["id"],
|
||||||
|
|
@ -270,6 +272,11 @@ export class PermissionController extends Controller {
|
||||||
redisClient.setex("role_" + profile.id, 86400, JSON.stringify(reply));
|
redisClient.setex("role_" + profile.id, 86400, JSON.stringify(reply));
|
||||||
}
|
}
|
||||||
return new HttpSuccess(reply);
|
return new HttpSuccess(reply);
|
||||||
|
} finally {
|
||||||
|
if (redisClient) {
|
||||||
|
redisClient.quit();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get("menu")
|
@Get("menu")
|
||||||
|
|
@ -281,11 +288,13 @@ export class PermissionController extends Controller {
|
||||||
orgRevisionIsCurrent: true,
|
orgRevisionIsCurrent: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const redisClient = await this.redis.createClient({
|
let redisClient;
|
||||||
host: REDIS_HOST,
|
try {
|
||||||
port: REDIS_PORT,
|
redisClient = await this.redis.createClient({
|
||||||
});
|
host: REDIS_HOST,
|
||||||
const getAsync = promisify(redisClient.get).bind(redisClient);
|
port: REDIS_PORT,
|
||||||
|
});
|
||||||
|
const getAsync = promisify(redisClient.get).bind(redisClient);
|
||||||
|
|
||||||
let profileType = "OFFICER";
|
let profileType = "OFFICER";
|
||||||
let profile: any = await this.profileRepo.findOne({
|
let profile: any = await this.profileRepo.findOne({
|
||||||
|
|
@ -438,6 +447,11 @@ export class PermissionController extends Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
return new HttpSuccess(reply);
|
return new HttpSuccess(reply);
|
||||||
|
} finally {
|
||||||
|
if (redisClient) {
|
||||||
|
redisClient.quit();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -672,11 +686,13 @@ export class PermissionController extends Controller {
|
||||||
@Path() system: string,
|
@Path() system: string,
|
||||||
@Path() action: string,
|
@Path() action: string,
|
||||||
) {
|
) {
|
||||||
const redisClient = await this.redis.createClient({
|
let redisClient;
|
||||||
host: REDIS_HOST,
|
try {
|
||||||
port: REDIS_PORT,
|
redisClient = await this.redis.createClient({
|
||||||
});
|
host: REDIS_HOST,
|
||||||
const getAsync = promisify(redisClient.get).bind(redisClient);
|
port: REDIS_PORT,
|
||||||
|
});
|
||||||
|
const getAsync = promisify(redisClient.get).bind(redisClient);
|
||||||
|
|
||||||
let profileType = "OFFICER";
|
let profileType = "OFFICER";
|
||||||
let profile: any = await this.profileRepo.findOne({
|
let profile: any = await this.profileRepo.findOne({
|
||||||
|
|
@ -765,6 +781,11 @@ export class PermissionController extends Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
return new HttpSuccess(reply);
|
return new HttpSuccess(reply);
|
||||||
|
} finally {
|
||||||
|
if (redisClient) {
|
||||||
|
redisClient.quit();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get("user/{system}/{action}/{id}")
|
@Get("user/{system}/{action}/{id}")
|
||||||
|
|
@ -781,11 +802,13 @@ export class PermissionController extends Controller {
|
||||||
orgRevisionIsCurrent: true,
|
orgRevisionIsCurrent: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const redisClient = await this.redis.createClient({
|
let redisClient;
|
||||||
host: REDIS_HOST,
|
try {
|
||||||
port: REDIS_PORT,
|
redisClient = await this.redis.createClient({
|
||||||
});
|
host: REDIS_HOST,
|
||||||
const getAsync = promisify(redisClient.get).bind(redisClient);
|
port: REDIS_PORT,
|
||||||
|
});
|
||||||
|
const getAsync = promisify(redisClient.get).bind(redisClient);
|
||||||
|
|
||||||
let org = this.PermissionOrg(request, system, action);
|
let org = this.PermissionOrg(request, system, action);
|
||||||
let reply = await getAsync("user_" + id);
|
let reply = await getAsync("user_" + id);
|
||||||
|
|
@ -866,14 +889,21 @@ export class PermissionController extends Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
return new HttpSuccess(reply);
|
return new HttpSuccess(reply);
|
||||||
|
} finally {
|
||||||
|
if (redisClient) {
|
||||||
|
redisClient.quit();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getPermissionFunc(@Request() request: RequestWithUser) {
|
public async getPermissionFunc(@Request() request: RequestWithUser) {
|
||||||
const redisClient = await this.redis.createClient({
|
let redisClient;
|
||||||
host: REDIS_HOST,
|
try {
|
||||||
port: REDIS_PORT,
|
redisClient = await this.redis.createClient({
|
||||||
});
|
host: REDIS_HOST,
|
||||||
const getAsync = promisify(redisClient.get).bind(redisClient);
|
port: REDIS_PORT,
|
||||||
|
});
|
||||||
|
const getAsync = promisify(redisClient.get).bind(redisClient);
|
||||||
|
|
||||||
let profile: any = await this.profileRepo.findOne({
|
let profile: any = await this.profileRepo.findOne({
|
||||||
select: ["id"],
|
select: ["id"],
|
||||||
|
|
@ -1090,6 +1120,11 @@ export class PermissionController extends Controller {
|
||||||
redisClient.setex("role_" + profile.id, 86400, JSON.stringify(reply));
|
redisClient.setex("role_" + profile.id, 86400, JSON.stringify(reply));
|
||||||
}
|
}
|
||||||
return reply;
|
return reply;
|
||||||
|
} finally {
|
||||||
|
if (redisClient) {
|
||||||
|
redisClient.quit();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Permission(req: RequestWithUser, system: string, action: string) {
|
public async Permission(req: RequestWithUser, system: string, action: string) {
|
||||||
|
|
@ -1115,11 +1150,13 @@ export class PermissionController extends Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async listAuthSysOrgFunc(request: RequestWithUser, system: string, action: string) {
|
public async listAuthSysOrgFunc(request: RequestWithUser, system: string, action: string) {
|
||||||
const redisClient = await this.redis.createClient({
|
let redisClient;
|
||||||
host: REDIS_HOST,
|
try {
|
||||||
port: REDIS_PORT,
|
redisClient = await this.redis.createClient({
|
||||||
});
|
host: REDIS_HOST,
|
||||||
const getAsync = promisify(redisClient.get).bind(redisClient);
|
port: REDIS_PORT,
|
||||||
|
});
|
||||||
|
const getAsync = promisify(redisClient.get).bind(redisClient);
|
||||||
|
|
||||||
let profileType = "OFFICER";
|
let profileType = "OFFICER";
|
||||||
let profile: any = await this.profileRepo.findOne({
|
let profile: any = await this.profileRepo.findOne({
|
||||||
|
|
@ -1187,6 +1224,11 @@ export class PermissionController extends Controller {
|
||||||
redisClient.setex("posMaster_" + profile.id, 86400, JSON.stringify(reply));
|
redisClient.setex("posMaster_" + profile.id, 86400, JSON.stringify(reply));
|
||||||
}
|
}
|
||||||
return reply;
|
return reply;
|
||||||
|
} finally {
|
||||||
|
if (redisClient) {
|
||||||
|
redisClient.quit();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper method: ดึง org scope จากตำแหน่งปกติ
|
// Helper method: ดึง org scope จากตำแหน่งปกติ
|
||||||
|
|
@ -1366,11 +1408,13 @@ export class PermissionController extends Controller {
|
||||||
|
|
||||||
@Get("checkOrg/{keycloakId}")
|
@Get("checkOrg/{keycloakId}")
|
||||||
public async checkOrg(@Path() keycloakId: string) {
|
public async checkOrg(@Path() keycloakId: string) {
|
||||||
const redisClient = await this.redis.createClient({
|
let redisClient;
|
||||||
host: REDIS_HOST,
|
try {
|
||||||
port: REDIS_PORT,
|
redisClient = await this.redis.createClient({
|
||||||
});
|
host: REDIS_HOST,
|
||||||
// const getAsync = promisify(redisClient.get).bind(redisClient);
|
port: REDIS_PORT,
|
||||||
|
});
|
||||||
|
// const getAsync = promisify(redisClient.get).bind(redisClient);
|
||||||
|
|
||||||
// let profileType = "OFFICER";
|
// let profileType = "OFFICER";
|
||||||
let profile: any = await this.profileRepo.findOne({
|
let profile: any = await this.profileRepo.findOne({
|
||||||
|
|
@ -1448,5 +1492,10 @@ export class PermissionController extends Controller {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
return new HttpSuccess(reply);
|
return new HttpSuccess(reply);
|
||||||
|
} finally {
|
||||||
|
if (redisClient) {
|
||||||
|
redisClient.quit();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
27
src/scripts/ClearOldOrgRevision.ts
Normal file
27
src/scripts/ClearOldOrgRevision.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
import "dotenv/config";
|
||||||
|
import "reflect-metadata";
|
||||||
|
import { AppDataSource } from "../database/data-source";
|
||||||
|
import { clearOldOrgRevisionData } from "../services/ClearOldOrgRevisionService";
|
||||||
|
|
||||||
|
// "clear:old-org-revision": "ts-node src/scripts/ClearOldOrgRevision.ts",
|
||||||
|
|
||||||
|
const defaultOrgRevisionId = "24dacf63-d289-496c-8102-8b25079dbaf2";
|
||||||
|
|
||||||
|
async function main(): Promise<void> {
|
||||||
|
const orgRevisionId = process.argv[2] || defaultOrgRevisionId;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await AppDataSource.initialize();
|
||||||
|
const result = await clearOldOrgRevisionData(orgRevisionId);
|
||||||
|
console.info(JSON.stringify(result, null, 2));
|
||||||
|
} catch (error) {
|
||||||
|
console.error("[ClearOldOrgRevision] Failed:", error);
|
||||||
|
process.exitCode = 1;
|
||||||
|
} finally {
|
||||||
|
if (AppDataSource.isInitialized) {
|
||||||
|
await AppDataSource.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main();
|
||||||
232
src/services/ClearOldOrgRevisionService.ts
Normal file
232
src/services/ClearOldOrgRevisionService.ts
Normal file
|
|
@ -0,0 +1,232 @@
|
||||||
|
import { EntityManager, EntityTarget, In } from "typeorm";
|
||||||
|
import { AppDataSource } from "../database/data-source";
|
||||||
|
import { OrgRevision } from "../entities/OrgRevision";
|
||||||
|
import { PosMaster } from "../entities/PosMaster";
|
||||||
|
import { Position } from "../entities/Position";
|
||||||
|
import { OrgRoot } from "../entities/OrgRoot";
|
||||||
|
import { OrgChild1 } from "../entities/OrgChild1";
|
||||||
|
import { OrgChild2 } from "../entities/OrgChild2";
|
||||||
|
import { OrgChild3 } from "../entities/OrgChild3";
|
||||||
|
import { OrgChild4 } from "../entities/OrgChild4";
|
||||||
|
import { PosMasterAct } from "../entities/PosMasterAct";
|
||||||
|
import { PosMasterAssign } from "../entities/PosMasterAssign";
|
||||||
|
import { PermissionOrg } from "../entities/PermissionOrg";
|
||||||
|
import { PermissionProfile } from "../entities/PermissionProfile";
|
||||||
|
import { EmployeePosMaster } from "../entities/EmployeePosMaster";
|
||||||
|
import { EmployeeTempPosMaster } from "../entities/EmployeeTempPosMaster";
|
||||||
|
import { EmployeePosition } from "../entities/EmployeePosition";
|
||||||
|
import { orgStructureCache } from "../utils/OrgStructureCache";
|
||||||
|
|
||||||
|
export interface ClearOldOrgRevisionSummary {
|
||||||
|
orgRevisionId: string;
|
||||||
|
orgRevisionName: string;
|
||||||
|
deleted: {
|
||||||
|
positions: number;
|
||||||
|
employeePositionsByPosMaster: number;
|
||||||
|
employeePositionsByTempPosMaster: number;
|
||||||
|
posMasterActsByParent: number;
|
||||||
|
posMasterActsByChild: number;
|
||||||
|
posMasterAssigns: number;
|
||||||
|
posMasters: number;
|
||||||
|
employeePosMasters: number;
|
||||||
|
employeeTempPosMasters: number;
|
||||||
|
permissionOrgs: number;
|
||||||
|
permissionProfiles: number;
|
||||||
|
orgChild4s: number;
|
||||||
|
orgChild3s: number;
|
||||||
|
orgChild2s: number;
|
||||||
|
orgChild1s: number;
|
||||||
|
orgRoots: number;
|
||||||
|
orgRevisions: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface OrgRevisionSnapshot {
|
||||||
|
id: string;
|
||||||
|
orgRevisionName: string;
|
||||||
|
orgRevisionIsCurrent: boolean;
|
||||||
|
orgRevisionIsDraft: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function clearOldOrgRevisionData(
|
||||||
|
orgRevisionId: string,
|
||||||
|
): Promise<ClearOldOrgRevisionSummary> {
|
||||||
|
const result = await AppDataSource.transaction(async (manager) => {
|
||||||
|
const orgRevision = await manager.findOne(OrgRevision, {
|
||||||
|
where: { id: orgRevisionId },
|
||||||
|
select: ["id", "orgRevisionName", "orgRevisionIsCurrent", "orgRevisionIsDraft"],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!orgRevision) {
|
||||||
|
throw new Error(`ไม่พบ orgRevision ที่ต้องการล้างข้อมูล: ${orgRevisionId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
validateOrgRevisionForDeletion(orgRevision);
|
||||||
|
|
||||||
|
const [posMasters, orgRoots, employeePosMasters, employeeTempPosMasters] = await Promise.all([
|
||||||
|
manager.find(PosMaster, {
|
||||||
|
where: { orgRevisionId },
|
||||||
|
select: ["id"],
|
||||||
|
}),
|
||||||
|
manager.find(OrgRoot, {
|
||||||
|
where: { orgRevisionId },
|
||||||
|
select: ["id"],
|
||||||
|
}),
|
||||||
|
manager.find(EmployeePosMaster, {
|
||||||
|
where: { orgRevisionId },
|
||||||
|
select: ["id"],
|
||||||
|
}),
|
||||||
|
manager.find(EmployeeTempPosMaster, {
|
||||||
|
where: { orgRevisionId },
|
||||||
|
select: ["id"],
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const posMasterIds = posMasters.map((item) => item.id);
|
||||||
|
const orgRootIds = orgRoots.map((item) => item.id);
|
||||||
|
const employeePosMasterIds = employeePosMasters.map((item) => item.id);
|
||||||
|
const employeeTempPosMasterIds = employeeTempPosMasters.map((item) => item.id);
|
||||||
|
|
||||||
|
const [
|
||||||
|
positionsCount,
|
||||||
|
employeePositionsByPosMasterCount,
|
||||||
|
employeePositionsByTempPosMasterCount,
|
||||||
|
posMasterActsByParentCount,
|
||||||
|
posMasterActsByChildCount,
|
||||||
|
posMasterAssignsCount,
|
||||||
|
permissionOrgsCount,
|
||||||
|
permissionProfilesCount,
|
||||||
|
orgChild4sCount,
|
||||||
|
orgChild3sCount,
|
||||||
|
orgChild2sCount,
|
||||||
|
orgChild1sCount,
|
||||||
|
] = await Promise.all([
|
||||||
|
countByIds(manager, Position, "posMasterId", posMasterIds),
|
||||||
|
countByIds(manager, EmployeePosition, "posMasterId", employeePosMasterIds),
|
||||||
|
countByIds(manager, EmployeePosition, "posMasterTempId", employeeTempPosMasterIds),
|
||||||
|
countByIds(manager, PosMasterAct, "posMasterId", posMasterIds),
|
||||||
|
countByIds(manager, PosMasterAct, "posMasterChildId", posMasterIds),
|
||||||
|
countByIds(manager, PosMasterAssign, "posMasterId", posMasterIds),
|
||||||
|
countByIds(manager, PermissionOrg, "orgRootId", orgRootIds),
|
||||||
|
countByIds(manager, PermissionProfile, "orgRootId", orgRootIds),
|
||||||
|
manager.count(OrgChild4, { where: { orgRevisionId } }),
|
||||||
|
manager.count(OrgChild3, { where: { orgRevisionId } }),
|
||||||
|
manager.count(OrgChild2, { where: { orgRevisionId } }),
|
||||||
|
manager.count(OrgChild1, { where: { orgRevisionId } }),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (positionsCount > 0) {
|
||||||
|
await manager.delete(Position, { posMasterId: In(posMasterIds) });
|
||||||
|
}
|
||||||
|
if (employeePositionsByPosMasterCount > 0) {
|
||||||
|
await manager.delete(EmployeePosition, { posMasterId: In(employeePosMasterIds) });
|
||||||
|
}
|
||||||
|
if (employeePositionsByTempPosMasterCount > 0) {
|
||||||
|
await manager.delete(EmployeePosition, { posMasterTempId: In(employeeTempPosMasterIds) });
|
||||||
|
}
|
||||||
|
if (posMasterActsByParentCount > 0) {
|
||||||
|
await manager.delete(PosMasterAct, { posMasterId: In(posMasterIds) });
|
||||||
|
}
|
||||||
|
if (posMasterActsByChildCount > 0) {
|
||||||
|
await manager.delete(PosMasterAct, { posMasterChildId: In(posMasterIds) });
|
||||||
|
}
|
||||||
|
if (posMasterAssignsCount > 0) {
|
||||||
|
await manager.delete(PosMasterAssign, { posMasterId: In(posMasterIds) });
|
||||||
|
}
|
||||||
|
|
||||||
|
const posMastersCount = posMasterIds.length;
|
||||||
|
const employeePosMastersCount = employeePosMasterIds.length;
|
||||||
|
const employeeTempPosMastersCount = employeeTempPosMasterIds.length;
|
||||||
|
|
||||||
|
if (posMastersCount > 0) {
|
||||||
|
await manager.delete(PosMaster, { orgRevisionId });
|
||||||
|
}
|
||||||
|
if (employeePosMastersCount > 0) {
|
||||||
|
await manager.delete(EmployeePosMaster, { orgRevisionId });
|
||||||
|
}
|
||||||
|
if (employeeTempPosMastersCount > 0) {
|
||||||
|
await manager.delete(EmployeeTempPosMaster, { orgRevisionId });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (permissionOrgsCount > 0) {
|
||||||
|
await manager.delete(PermissionOrg, { orgRootId: In(orgRootIds) });
|
||||||
|
}
|
||||||
|
if (permissionProfilesCount > 0) {
|
||||||
|
await manager.delete(PermissionProfile, { orgRootId: In(orgRootIds) });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (orgChild4sCount > 0) {
|
||||||
|
await manager.delete(OrgChild4, { orgRevisionId });
|
||||||
|
}
|
||||||
|
if (orgChild3sCount > 0) {
|
||||||
|
await manager.delete(OrgChild3, { orgRevisionId });
|
||||||
|
}
|
||||||
|
if (orgChild2sCount > 0) {
|
||||||
|
await manager.delete(OrgChild2, { orgRevisionId });
|
||||||
|
}
|
||||||
|
if (orgChild1sCount > 0) {
|
||||||
|
await manager.delete(OrgChild1, { orgRevisionId });
|
||||||
|
}
|
||||||
|
|
||||||
|
const orgRootsCount = orgRootIds.length;
|
||||||
|
if (orgRootsCount > 0) {
|
||||||
|
await manager.delete(OrgRoot, { orgRevisionId });
|
||||||
|
}
|
||||||
|
|
||||||
|
await manager.delete(OrgRevision, { id: orgRevisionId });
|
||||||
|
|
||||||
|
return {
|
||||||
|
orgRevisionId: orgRevision.id,
|
||||||
|
orgRevisionName: orgRevision.orgRevisionName,
|
||||||
|
deleted: {
|
||||||
|
positions: positionsCount,
|
||||||
|
employeePositionsByPosMaster: employeePositionsByPosMasterCount,
|
||||||
|
employeePositionsByTempPosMaster: employeePositionsByTempPosMasterCount,
|
||||||
|
posMasterActsByParent: posMasterActsByParentCount,
|
||||||
|
posMasterActsByChild: posMasterActsByChildCount,
|
||||||
|
posMasterAssigns: posMasterAssignsCount,
|
||||||
|
posMasters: posMastersCount,
|
||||||
|
employeePosMasters: employeePosMastersCount,
|
||||||
|
employeeTempPosMasters: employeeTempPosMastersCount,
|
||||||
|
permissionOrgs: permissionOrgsCount,
|
||||||
|
permissionProfiles: permissionProfilesCount,
|
||||||
|
orgChild4s: orgChild4sCount,
|
||||||
|
orgChild3s: orgChild3sCount,
|
||||||
|
orgChild2s: orgChild2sCount,
|
||||||
|
orgChild1s: orgChild1sCount,
|
||||||
|
orgRoots: orgRootsCount,
|
||||||
|
orgRevisions: 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
orgStructureCache.invalidate(orgRevisionId);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateOrgRevisionForDeletion(orgRevision: OrgRevisionSnapshot): void {
|
||||||
|
if (orgRevision.orgRevisionIsCurrent) {
|
||||||
|
throw new Error(`ไม่สามารถลบ orgRevision ปัจจุบันได้: ${orgRevision.id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (orgRevision.orgRevisionIsDraft) {
|
||||||
|
throw new Error(`ไม่สามารถลบ orgRevision แบบร่างได้ด้วยสคริปต์นี้: ${orgRevision.id}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function countByIds<Entity extends object>(
|
||||||
|
manager: EntityManager,
|
||||||
|
entity: EntityTarget<Entity>,
|
||||||
|
field: keyof Entity,
|
||||||
|
ids: string[],
|
||||||
|
): Promise<number> {
|
||||||
|
if (ids.length === 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const alias = "entity";
|
||||||
|
return manager
|
||||||
|
.createQueryBuilder(entity, alias)
|
||||||
|
.where(`${alias}.${String(field)} IN (:...ids)`, { ids })
|
||||||
|
.getCount();
|
||||||
|
}
|
||||||
|
|
@ -188,6 +188,7 @@ export async function CreatePosMasterHistoryOfficer(
|
||||||
return true;
|
return true;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (manager) {
|
if (manager) {
|
||||||
|
console.error("CreatePosMasterHistoryOfficer error (external transaction):", err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
console.error("CreatePosMasterHistoryOfficer transaction error:", err);
|
console.error("CreatePosMasterHistoryOfficer transaction error:", err);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue