Merge branch 'develop'
This commit is contained in:
commit
4103863df3
22 changed files with 3085 additions and 224 deletions
780
src/controllers/ApiManageController.ts
Normal file
780
src/controllers/ApiManageController.ts
Normal file
|
|
@ -0,0 +1,780 @@
|
||||||
|
import { Position } from "./../entities/Position";
|
||||||
|
import { ApiKey } from "./../entities/ApiKey";
|
||||||
|
import { ApiAttribute } from "./../entities/ApiAttribute";
|
||||||
|
import { CreateApi } from "./../entities/ApiName";
|
||||||
|
import { PosMaster } from "../entities/PosMaster";
|
||||||
|
import { OrgChild4 } from "../entities/OrgChild4";
|
||||||
|
import { OrgChild3 } from "../entities/OrgChild3";
|
||||||
|
import { OrgChild2 } from "../entities/OrgChild2";
|
||||||
|
import { OrgChild1 } from "../entities/OrgChild1";
|
||||||
|
import { OrgRoot } from "../entities/OrgRoot";
|
||||||
|
import { ProfileEmployee } from "../entities/ProfileEmployee";
|
||||||
|
import { ProfileSalary } from "../entities/ProfileSalary";
|
||||||
|
import { ProfileOther } from "../entities/ProfileOther";
|
||||||
|
import { ProfileNopaid } from "../entities/ProfileNopaid";
|
||||||
|
import { ProfileLeave } from "../entities/ProfileLeave";
|
||||||
|
import { ProfileInsignia } from "../entities/ProfileInsignia";
|
||||||
|
import { ProfileHonor } from "../entities/ProfileHonor";
|
||||||
|
import { ProfileGovernment } from "../entities/ProfileGovernment";
|
||||||
|
import { ProfileFamilyMother } from "../entities/ProfileFamilyMother";
|
||||||
|
import { ProfileFamilyFather } from "../entities/ProfileFamilyFather";
|
||||||
|
import { ProfileFamilyCouple } from "../entities/ProfileFamilyCouple";
|
||||||
|
import { ProfileEducation } from "../entities/ProfileEducation";
|
||||||
|
import { ProfileDuty } from "../entities/ProfileDuty";
|
||||||
|
import { ProfileDiscipline } from "../entities/ProfileDiscipline";
|
||||||
|
import { ProfileDevelopment } from "../entities/ProfileDevelopment";
|
||||||
|
import { ProfileChildren } from "../entities/ProfileChildren";
|
||||||
|
import { ProfileChangeName } from "../entities/ProfileChangeName";
|
||||||
|
import { ProfileCertificate } from "../entities/ProfileCertificate";
|
||||||
|
import { ProfileAssessment } from "../entities/ProfileAssessment";
|
||||||
|
import { ProfileAbility } from "../entities/ProfileAbility";
|
||||||
|
import {
|
||||||
|
Controller,
|
||||||
|
Post,
|
||||||
|
Delete,
|
||||||
|
Route,
|
||||||
|
Security,
|
||||||
|
Tags,
|
||||||
|
Body,
|
||||||
|
Path,
|
||||||
|
Request,
|
||||||
|
Response,
|
||||||
|
Get,
|
||||||
|
Put,
|
||||||
|
Query,
|
||||||
|
} from "tsoa";
|
||||||
|
import { AppDataSource } from "../database/data-source";
|
||||||
|
import HttpSuccess from "../interfaces/http-success";
|
||||||
|
import HttpStatusCode from "../interfaces/http-status";
|
||||||
|
import HttpError from "../interfaces/http-error";
|
||||||
|
import { RequestWithUser } from "../middlewares/user";
|
||||||
|
import { ApiName } from "../entities/ApiName";
|
||||||
|
import { Profile } from "../entities/Profile";
|
||||||
|
import { SystemDefinition, EntityDefinition, SystemCode } from "./../interfaces/api-type";
|
||||||
|
@Route("api/v1/org/api-manage")
|
||||||
|
@Tags("ApiManage")
|
||||||
|
@Security("bearerAuth")
|
||||||
|
@Response(
|
||||||
|
HttpStatusCode.INTERNAL_SERVER_ERROR,
|
||||||
|
"เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง",
|
||||||
|
)
|
||||||
|
export class ApiManageController extends Controller {
|
||||||
|
private readonly profileRepository = AppDataSource.getRepository(Profile);
|
||||||
|
private readonly profileEmployeeRepository = AppDataSource.getRepository(ProfileEmployee);
|
||||||
|
private readonly profileGovernmentRepository = AppDataSource.getRepository(ProfileGovernment);
|
||||||
|
private readonly profileProfileSalaryRepository = AppDataSource.getRepository(ProfileSalary);
|
||||||
|
private readonly profileAbilityRepository = AppDataSource.getRepository(ProfileAbility);
|
||||||
|
private readonly profileAssessmentRepository = AppDataSource.getRepository(ProfileAssessment);
|
||||||
|
private readonly profileCertificateRepository = AppDataSource.getRepository(ProfileCertificate);
|
||||||
|
private readonly profileHonorRepository = AppDataSource.getRepository(ProfileHonor);
|
||||||
|
private readonly profileInsigniaRepository = AppDataSource.getRepository(ProfileInsignia);
|
||||||
|
private readonly profileLeaveRepository = AppDataSource.getRepository(ProfileLeave);
|
||||||
|
private readonly profileChangeNameRepository = AppDataSource.getRepository(ProfileChangeName);
|
||||||
|
private readonly profileDevelopmentRepository = AppDataSource.getRepository(ProfileDevelopment);
|
||||||
|
private readonly profileDisciplineRepository = AppDataSource.getRepository(ProfileDiscipline);
|
||||||
|
private readonly profileDutyRepository = AppDataSource.getRepository(ProfileDuty);
|
||||||
|
private readonly profileEducationRepository = AppDataSource.getRepository(ProfileEducation);
|
||||||
|
private readonly profileFamilyCoupleRepository = AppDataSource.getRepository(ProfileFamilyCouple);
|
||||||
|
private readonly profileFamilyFatherRepository = AppDataSource.getRepository(ProfileFamilyFather);
|
||||||
|
private readonly profileFamilyMotherRepository = AppDataSource.getRepository(ProfileFamilyMother);
|
||||||
|
private readonly profileChildrenRepository = AppDataSource.getRepository(ProfileChildren);
|
||||||
|
private readonly profileNopaidRepository = AppDataSource.getRepository(ProfileNopaid);
|
||||||
|
private readonly profileOtherRepository = AppDataSource.getRepository(ProfileOther);
|
||||||
|
private readonly orgRootRepository = AppDataSource.getRepository(OrgRoot);
|
||||||
|
private readonly orgChild1Repository = AppDataSource.getRepository(OrgChild1);
|
||||||
|
private readonly orgChild2Repository = AppDataSource.getRepository(OrgChild2);
|
||||||
|
private readonly orgChild3Repository = AppDataSource.getRepository(OrgChild3);
|
||||||
|
private readonly orgChild4Repository = AppDataSource.getRepository(OrgChild4);
|
||||||
|
private readonly posMasterRepository = AppDataSource.getRepository(PosMaster);
|
||||||
|
private readonly positionRepository = AppDataSource.getRepository(Position);
|
||||||
|
|
||||||
|
// รายการระบบ
|
||||||
|
private readonly systems: SystemDefinition[] = [
|
||||||
|
{
|
||||||
|
code: "registry",
|
||||||
|
name: "ข้อมูลทะเบียนประวัติข้าราชการ",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "registry_emp",
|
||||||
|
name: "ข้อมูลทะเบียนประวัติลูกจ้างประจำ",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "registry_temp",
|
||||||
|
name: "ข้อมูลทะเบียนประวัติลูกจ้างชั่วคราว",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "organization",
|
||||||
|
name: "ข้อมูลโครงสร้าง",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "position",
|
||||||
|
name: "ข้อมูลอัตรากำลัง",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// รายการเอนทิตีทั้งหมด
|
||||||
|
private readonly entities: EntityDefinition[] = [
|
||||||
|
{
|
||||||
|
name: "Profile",
|
||||||
|
repository: this.profileRepository,
|
||||||
|
description: "ข้อมูลหลัก",
|
||||||
|
isMain: true,
|
||||||
|
system: ["registry"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ProfileEmployee",
|
||||||
|
repository: this.profileEmployeeRepository,
|
||||||
|
description: "ข้อมูลหลัก",
|
||||||
|
isMain: true,
|
||||||
|
system: ["registry_emp", "registry_temp"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ProfileGovernment",
|
||||||
|
repository: this.profileGovernmentRepository,
|
||||||
|
description: "ข้อมูลราชการ",
|
||||||
|
system: ["registry", "registry_emp", "registry_temp"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ProfileSalary",
|
||||||
|
repository: this.profileProfileSalaryRepository,
|
||||||
|
description: "ข้อมูลตำแหน่ง/เงินเดือน",
|
||||||
|
system: ["registry", "registry_emp", "registry_temp"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ProfileAbility",
|
||||||
|
repository: this.profileAbilityRepository,
|
||||||
|
description: "ข้อมูลความสามารถ",
|
||||||
|
system: ["registry", "registry_emp", "registry_temp"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ProfileAssessment",
|
||||||
|
repository: this.profileAssessmentRepository,
|
||||||
|
description: "ข้อมูลการประเมิน",
|
||||||
|
system: ["registry", "registry_emp", "registry_temp"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ProfileCertificate",
|
||||||
|
repository: this.profileCertificateRepository,
|
||||||
|
description: "ข้อมูลใบรับรอง",
|
||||||
|
system: ["registry", "registry_emp", "registry_temp"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ProfileHonor",
|
||||||
|
repository: this.profileHonorRepository,
|
||||||
|
description: "ข้อมูลเกียรติบัตร",
|
||||||
|
system: ["registry", "registry_emp", "registry_temp"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ProfileInsignia",
|
||||||
|
repository: this.profileInsigniaRepository,
|
||||||
|
description: "ข้อมูลเครื่องหมาย",
|
||||||
|
system: ["registry", "registry_emp", "registry_temp"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ProfileLeave",
|
||||||
|
repository: this.profileLeaveRepository,
|
||||||
|
description: "ข้อมูลการลา",
|
||||||
|
system: ["registry", "registry_emp", "registry_temp"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ProfileChangeName",
|
||||||
|
repository: this.profileChangeNameRepository,
|
||||||
|
description: "ข้อมูลการเปลี่ยนชื่อ",
|
||||||
|
system: ["registry", "registry_emp", "registry_temp"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ProfileDevelopment",
|
||||||
|
repository: this.profileDevelopmentRepository,
|
||||||
|
description: "ข้อมูลการพัฒนา",
|
||||||
|
system: ["registry", "registry_emp", "registry_temp"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ProfileDiscipline",
|
||||||
|
repository: this.profileDisciplineRepository,
|
||||||
|
description: "ข้อมูลวินัย",
|
||||||
|
system: ["registry", "registry_emp", "registry_temp"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ProfileDuty",
|
||||||
|
repository: this.profileDutyRepository,
|
||||||
|
description: "ข้อมูลหน้าที่ปฏิบัติราชการ",
|
||||||
|
system: ["registry", "registry_emp", "registry_temp"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ProfileEducation",
|
||||||
|
repository: this.profileEducationRepository,
|
||||||
|
description: "ข้อมูลการศึกษา",
|
||||||
|
system: ["registry", "registry_emp", "registry_temp"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ProfileFamilyCouple",
|
||||||
|
repository: this.profileFamilyCoupleRepository,
|
||||||
|
description: "ข้อมูลคู่สมรส",
|
||||||
|
system: ["registry", "registry_emp", "registry_temp"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ProfileFamilyFather",
|
||||||
|
repository: this.profileFamilyFatherRepository,
|
||||||
|
description: "ข้อมูลบิดา",
|
||||||
|
system: ["registry", "registry_emp", "registry_temp"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ProfileFamilyMother",
|
||||||
|
repository: this.profileFamilyMotherRepository,
|
||||||
|
description: "ข้อมูลมารดา",
|
||||||
|
system: ["registry", "registry_emp", "registry_temp"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ProfileChildren",
|
||||||
|
repository: this.profileChildrenRepository,
|
||||||
|
description: "ข้อมูลบุตร",
|
||||||
|
system: ["registry", "registry_emp", "registry_temp"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ProfileNopaid",
|
||||||
|
repository: this.profileNopaidRepository,
|
||||||
|
description: "ข้อมูลการไม่จ่ายเงินเดือน",
|
||||||
|
system: ["registry", "registry_emp", "registry_temp"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ProfileOther",
|
||||||
|
repository: this.profileOtherRepository,
|
||||||
|
description: "ข้อมูลอื่นๆ",
|
||||||
|
system: ["registry", "registry_emp", "registry_temp"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "OrgRoot",
|
||||||
|
repository: this.orgRootRepository,
|
||||||
|
description: "ข้อมูลหน่วยงาน",
|
||||||
|
isMain: true,
|
||||||
|
system: ["organization"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "OrgChild1",
|
||||||
|
repository: this.orgChild1Repository,
|
||||||
|
description: "ข้อมูลส่วนราชการ ระดับที่ 1",
|
||||||
|
system: ["organization"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "OrgChild2",
|
||||||
|
repository: this.orgChild2Repository,
|
||||||
|
description: "ข้อมูลส่วนราชการ ระดับที่ 2",
|
||||||
|
system: ["organization"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "OrgChild3",
|
||||||
|
repository: this.orgChild3Repository,
|
||||||
|
description: "ข้อมูลส่วนราชการ ระดับที่ 3",
|
||||||
|
system: ["organization"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "OrgChild4",
|
||||||
|
repository: this.orgChild4Repository,
|
||||||
|
description: "ข้อมูลส่วนราชการ ระดับที่ 4",
|
||||||
|
system: ["organization"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PosMaster",
|
||||||
|
repository: this.posMasterRepository,
|
||||||
|
description: "ข้อมูลอัตรากำลัง",
|
||||||
|
isMain: true,
|
||||||
|
system: ["position"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Position",
|
||||||
|
repository: this.positionRepository,
|
||||||
|
description: "ข้อมูลตำแหน่ง",
|
||||||
|
system: ["position"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "OrgRoot",
|
||||||
|
repository: this.orgRootRepository,
|
||||||
|
description: "ข้อมูลหน่วยงาน",
|
||||||
|
system: ["position"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "OrgChild1",
|
||||||
|
repository: this.orgChild1Repository,
|
||||||
|
description: "ข้อมูลส่วนราชการ ระดับที่ 1",
|
||||||
|
system: ["position"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "OrgChild2",
|
||||||
|
repository: this.orgChild2Repository,
|
||||||
|
description: "ข้อมูลส่วนราชการ ระดับที่ 2",
|
||||||
|
system: ["position"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "OrgChild3",
|
||||||
|
repository: this.orgChild3Repository,
|
||||||
|
description: "ข้อมูลส่วนราชการ ระดับที่ 3",
|
||||||
|
system: ["position"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "OrgChild4",
|
||||||
|
repository: this.orgChild4Repository,
|
||||||
|
description: "ข้อมูลส่วนราชการ ระดับที่ 4",
|
||||||
|
system: ["position"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Profile",
|
||||||
|
repository: this.profileRepository,
|
||||||
|
description: "ข้อมูลคนครอง",
|
||||||
|
system: ["position"],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
private readonly DEFAULT_PAGE_SIZE = 10; // ขนาดหน้าเริ่มต้น
|
||||||
|
private readonly EXCLUDED_COLUMNS = ["createdUserId", "lastUpdateUserId"]; // ฟิลด์ที่ไม่ต้องการแสดงในผลลัพธ์
|
||||||
|
|
||||||
|
private validateSuperAdminRole(user: any): void {
|
||||||
|
if (!user.role.includes("SUPER_ADMIN")) {
|
||||||
|
throw new HttpError(HttpStatusCode.FORBIDDEN, "คุณไม่มีสิทธิ์ในการเข้าถึงข้อมูลนี้");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private generateApiCode(): string {
|
||||||
|
return Math.random().toString(36).substring(2, 10).toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
private createApiPath(system: SystemCode = "registry", code: string): string {
|
||||||
|
return `/api/v1/org/api-service/${system}/${code}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list systems
|
||||||
|
* @summary รายการ systems
|
||||||
|
*/
|
||||||
|
@Get("/systems")
|
||||||
|
async listSystems(): Promise<HttpSuccess> {
|
||||||
|
return new HttpSuccess(this.systems);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list fields by systems
|
||||||
|
* @summary รายการ fields ตาม systems
|
||||||
|
*/
|
||||||
|
@Get("/:system/fields")
|
||||||
|
async listAttribute(
|
||||||
|
@Request() req: RequestWithUser,
|
||||||
|
@Path("system") system: SystemCode,
|
||||||
|
): Promise<HttpSuccess | HttpError> {
|
||||||
|
try {
|
||||||
|
this.validateSuperAdminRole(req.user);
|
||||||
|
|
||||||
|
const result = this.entities
|
||||||
|
.filter((entity) => entity.system.includes(system))
|
||||||
|
.map(({ name, repository, description, isMain }) => ({
|
||||||
|
tb: name,
|
||||||
|
description,
|
||||||
|
isMain: isMain || false,
|
||||||
|
propertys: repository.metadata.columns
|
||||||
|
.filter(
|
||||||
|
(column: any) =>
|
||||||
|
!column.isPrimary && !this.EXCLUDED_COLUMNS.includes(column.propertyName),
|
||||||
|
)
|
||||||
|
.map((column: any) => ({
|
||||||
|
propertyName: column.propertyName,
|
||||||
|
type: typeof column.type === "string" ? column.type : "string",
|
||||||
|
comment: column.comment,
|
||||||
|
key: column.propertyName,
|
||||||
|
})),
|
||||||
|
}));
|
||||||
|
|
||||||
|
return new HttpSuccess(result);
|
||||||
|
} catch (error) {
|
||||||
|
throw new HttpError(
|
||||||
|
HttpStatusCode.INTERNAL_SERVER_ERROR,
|
||||||
|
(error instanceof Error ? error.message : String(error)) ||
|
||||||
|
"เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list api
|
||||||
|
* @summary รายการ api
|
||||||
|
*/
|
||||||
|
@Get("/lists")
|
||||||
|
async listApi(
|
||||||
|
@Request() req: RequestWithUser,
|
||||||
|
@Query("page") page: number = 1,
|
||||||
|
@Query("pageSize") pageSize: number = this.DEFAULT_PAGE_SIZE,
|
||||||
|
@Query("keyword") keyword: string = "",
|
||||||
|
@Query("system") system: SystemCode | "" = "",
|
||||||
|
@Query("isActive") isActive: boolean = true,
|
||||||
|
): Promise<HttpSuccess | HttpError> {
|
||||||
|
try {
|
||||||
|
this.validateSuperAdminRole(req.user);
|
||||||
|
|
||||||
|
const offset = (page - 1) * pageSize;
|
||||||
|
const queryBuilder = AppDataSource.getRepository(ApiName)
|
||||||
|
.createQueryBuilder("apiName")
|
||||||
|
.where("apiName.isActive = :isActive", { isActive })
|
||||||
|
.select([
|
||||||
|
"apiName.id",
|
||||||
|
"apiName.name",
|
||||||
|
"apiName.code",
|
||||||
|
"apiName.pathApi",
|
||||||
|
"apiName.methodApi",
|
||||||
|
"apiName.system",
|
||||||
|
"apiName.isActive",
|
||||||
|
"apiName.createdAt",
|
||||||
|
"apiName.lastUpdatedAt",
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (keyword?.trim()) {
|
||||||
|
queryBuilder.andWhere(
|
||||||
|
"(apiName.name LIKE :keyword OR apiName.code LIKE :keyword OR apiName.pathApi LIKE :keyword)",
|
||||||
|
{ keyword: `%${keyword.trim()}%` },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (system) {
|
||||||
|
queryBuilder.andWhere("apiName.system = :system", { system });
|
||||||
|
}
|
||||||
|
|
||||||
|
const [apiNames, total] = await queryBuilder
|
||||||
|
.skip(offset)
|
||||||
|
.take(pageSize)
|
||||||
|
.orderBy("apiName.lastUpdatedAt", "DESC")
|
||||||
|
.addOrderBy("apiName.createdAt", "ASC")
|
||||||
|
.getManyAndCount();
|
||||||
|
|
||||||
|
return new HttpSuccess({
|
||||||
|
data: apiNames.map((api) => ({
|
||||||
|
...api,
|
||||||
|
system: this.systems.find((s) => s.code === api.system)?.name || api.system,
|
||||||
|
})),
|
||||||
|
total,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
throw new HttpError(
|
||||||
|
HttpStatusCode.INTERNAL_SERVER_ERROR,
|
||||||
|
(error instanceof Error ? error.message : String(error)) ||
|
||||||
|
"เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* สร้าง api
|
||||||
|
* @summary สร้าง api
|
||||||
|
*/
|
||||||
|
@Post("")
|
||||||
|
async createApi(
|
||||||
|
@Request() req: RequestWithUser,
|
||||||
|
@Body() apiData: CreateApi,
|
||||||
|
): Promise<HttpSuccess | HttpError> {
|
||||||
|
const queryRunner = AppDataSource.createQueryRunner();
|
||||||
|
await queryRunner.connect();
|
||||||
|
await queryRunner.startTransaction();
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.validateSuperAdminRole(req.user);
|
||||||
|
|
||||||
|
const code = this.generateApiCode();
|
||||||
|
const postData = {
|
||||||
|
name: apiData.name,
|
||||||
|
code,
|
||||||
|
pathApi: this.createApiPath(apiData.system as SystemCode, code),
|
||||||
|
methodApi: apiData.methodApi || "GET",
|
||||||
|
system: apiData.system || "registry",
|
||||||
|
isActive: apiData.isActive || false,
|
||||||
|
createdUserId: req.user?.sub,
|
||||||
|
createdFullName: req.user?.name || "",
|
||||||
|
};
|
||||||
|
|
||||||
|
const apiName = await queryRunner.manager.getRepository(ApiName).save(postData);
|
||||||
|
|
||||||
|
if (apiData.apiAttributes?.length) {
|
||||||
|
let orderingCounter = 0;
|
||||||
|
const attributesToSave = apiData.apiAttributes.flatMap((attr) =>
|
||||||
|
attr.propertyKey.map((propertyKey) => ({
|
||||||
|
apiNameId: apiName.id,
|
||||||
|
tbName: attr.tbName,
|
||||||
|
propertyKey,
|
||||||
|
ordering: orderingCounter++,
|
||||||
|
createdUserId: req.user?.sub,
|
||||||
|
createdFullName: req.user?.name || "",
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.manager.getRepository(ApiAttribute).save(attributesToSave);
|
||||||
|
}
|
||||||
|
|
||||||
|
await queryRunner.commitTransaction();
|
||||||
|
return new HttpSuccess(apiName.id);
|
||||||
|
} catch (error) {
|
||||||
|
await queryRunner.rollbackTransaction();
|
||||||
|
throw new HttpError(
|
||||||
|
HttpStatusCode.INTERNAL_SERVER_ERROR,
|
||||||
|
(error instanceof Error ? error.message : String(error)) ||
|
||||||
|
"เกิดข้อผิดพลาด ไม่สามารถบันทึกข้อมูลได้ กรุณาลองใหม่ในภายหลัง",
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
await queryRunner.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* รายละเอียด api ตามไอดี
|
||||||
|
* @summary รายละเอียด api ตามไอดี
|
||||||
|
*/
|
||||||
|
@Get("/{id}")
|
||||||
|
async getApiById(
|
||||||
|
@Request() req: RequestWithUser,
|
||||||
|
@Path("id") id: string,
|
||||||
|
): Promise<HttpSuccess | HttpError> {
|
||||||
|
try {
|
||||||
|
this.validateSuperAdminRole(req.user);
|
||||||
|
|
||||||
|
const apiName = await AppDataSource.getRepository(ApiName).findOne({
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
name: true,
|
||||||
|
code: true,
|
||||||
|
pathApi: true,
|
||||||
|
methodApi: true,
|
||||||
|
system: true,
|
||||||
|
isActive: true,
|
||||||
|
apiAttributes: true,
|
||||||
|
},
|
||||||
|
where: { id },
|
||||||
|
relations: ["apiAttributes"],
|
||||||
|
order: {
|
||||||
|
apiAttributes: {
|
||||||
|
ordering: "ASC",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!apiName) {
|
||||||
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบ API ที่ต้องการแก้ไข");
|
||||||
|
}
|
||||||
|
|
||||||
|
const items = {
|
||||||
|
...apiName,
|
||||||
|
apiAttributes: apiName.apiAttributes.map((attr) => ({
|
||||||
|
tbName: attr.tbName,
|
||||||
|
propertyKey: attr.propertyKey,
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
|
||||||
|
return new HttpSuccess(items);
|
||||||
|
} catch (error) {
|
||||||
|
throw new HttpError(
|
||||||
|
HttpStatusCode.INTERNAL_SERVER_ERROR,
|
||||||
|
(error instanceof Error ? error.message : String(error)) ||
|
||||||
|
"เกิดข้อผิดพลาด ไม่สามารถบันทึกข้อมูลได้ กรุณาลองใหม่ในภายหลัง",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แก้ไข api
|
||||||
|
* @summary แก้ไขข้อมูล api
|
||||||
|
*/
|
||||||
|
@Put("/{id}")
|
||||||
|
async editApi(
|
||||||
|
@Request() req: RequestWithUser,
|
||||||
|
@Path("id") id: string,
|
||||||
|
@Body() apiData: CreateApi,
|
||||||
|
): Promise<HttpSuccess | HttpError> {
|
||||||
|
const queryRunner = AppDataSource.createQueryRunner();
|
||||||
|
await queryRunner.connect();
|
||||||
|
await queryRunner.startTransaction();
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.validateSuperAdminRole(req.user);
|
||||||
|
|
||||||
|
const apiName = await queryRunner.manager.getRepository(ApiName).findOneBy({ id });
|
||||||
|
if (!apiName) {
|
||||||
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบ API ที่ต้องการแก้ไข");
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateData = {
|
||||||
|
name: apiData.name,
|
||||||
|
pathApi: this.createApiPath(apiData.system as SystemCode, apiName.code),
|
||||||
|
methodApi: apiData.methodApi || "GET",
|
||||||
|
system: apiData.system || "registry",
|
||||||
|
isActive: apiData.isActive || false,
|
||||||
|
lastUpdateUserId: req.user?.sub,
|
||||||
|
lastUpdateFullName: req.user?.name || "",
|
||||||
|
};
|
||||||
|
|
||||||
|
await queryRunner.manager.getRepository(ApiName).update(id, updateData);
|
||||||
|
await queryRunner.manager.getRepository(ApiAttribute).delete({ apiNameId: id });
|
||||||
|
|
||||||
|
if (apiData.apiAttributes?.length) {
|
||||||
|
let orderingCounter = 0;
|
||||||
|
const attributesToSave = apiData.apiAttributes.flatMap((attr) =>
|
||||||
|
attr.propertyKey.map((propertyKey) => ({
|
||||||
|
apiNameId: apiName.id,
|
||||||
|
tbName: attr.tbName,
|
||||||
|
propertyKey,
|
||||||
|
ordering: orderingCounter++,
|
||||||
|
lastUpdateUserId: req.user?.sub,
|
||||||
|
lastUpdateFullName: req.user?.name || "",
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.manager.getRepository(ApiAttribute).save(attributesToSave);
|
||||||
|
}
|
||||||
|
|
||||||
|
await queryRunner.commitTransaction();
|
||||||
|
return new HttpSuccess();
|
||||||
|
} catch (error) {
|
||||||
|
await queryRunner.rollbackTransaction();
|
||||||
|
throw new HttpError(
|
||||||
|
HttpStatusCode.INTERNAL_SERVER_ERROR,
|
||||||
|
(error instanceof Error ? error.message : String(error)) ||
|
||||||
|
"เกิดข้อผิดพลาด ไม่สามารถบันทึกข้อมูลได้ กรุณาลองใหม่ในภายหลัง",
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
await queryRunner.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ลบ api
|
||||||
|
* @summary ลบข้อมูล api
|
||||||
|
*/
|
||||||
|
@Delete("/{id}")
|
||||||
|
async deleteApi(
|
||||||
|
@Request() req: RequestWithUser,
|
||||||
|
@Path("id") id: string,
|
||||||
|
): Promise<HttpSuccess | HttpError> {
|
||||||
|
const queryRunner = AppDataSource.createQueryRunner();
|
||||||
|
await queryRunner.connect();
|
||||||
|
await queryRunner.startTransaction();
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.validateSuperAdminRole(req.user);
|
||||||
|
|
||||||
|
const checkUsed = await AppDataSource.getRepository(ApiKey)
|
||||||
|
.createQueryBuilder("apiKey")
|
||||||
|
.innerJoin("apiKey.apiNames", "apiName")
|
||||||
|
.where("apiName.id = :id", { id })
|
||||||
|
.getCount();
|
||||||
|
|
||||||
|
if (checkUsed > 0) {
|
||||||
|
throw new HttpError(
|
||||||
|
HttpStatusCode.BAD_REQUEST,
|
||||||
|
"ไม่สามารถลบ API นี้ได้ เนื่องจากมีการใช้งานอยู่",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await queryRunner.manager.getRepository(ApiAttribute).delete({ apiNameId: id });
|
||||||
|
await queryRunner.manager.getRepository(ApiName).delete({ id });
|
||||||
|
|
||||||
|
await queryRunner.commitTransaction();
|
||||||
|
return new HttpSuccess();
|
||||||
|
} catch (error) {
|
||||||
|
await queryRunner.rollbackTransaction();
|
||||||
|
throw new HttpError(
|
||||||
|
HttpStatusCode.INTERNAL_SERVER_ERROR,
|
||||||
|
(error instanceof Error ? error.message : String(error)) ||
|
||||||
|
"เกิดข้อผิดพลาด ไม่สามารถบันทึกข้อมูลได้ กรุณาลองใหม่ในภายหลัง",
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
await queryRunner.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list systems
|
||||||
|
* @summary รายการ systems
|
||||||
|
*/
|
||||||
|
@Get("/manual/swagger")
|
||||||
|
async getManualRequestWebService(): Promise<HttpSuccess> {
|
||||||
|
const json = {
|
||||||
|
openapi: "3.0.0",
|
||||||
|
info: {
|
||||||
|
title: "Request Web Service",
|
||||||
|
version: "1.0.0",
|
||||||
|
description: "This is a manual request web service.",
|
||||||
|
},
|
||||||
|
servers: [
|
||||||
|
{
|
||||||
|
url: process.env.API_URL?.replace("/api/v1", "") || "http://localhost:13009",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: "http://localhost:13009",
|
||||||
|
description: "Local server",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
paths: {
|
||||||
|
"/api/v1/org/api-service/{system}/{code}": {
|
||||||
|
get: {
|
||||||
|
summary: "Get Registry Data",
|
||||||
|
parameters: [
|
||||||
|
{
|
||||||
|
name: "system",
|
||||||
|
in: "path",
|
||||||
|
required: true,
|
||||||
|
schema: {
|
||||||
|
type: "string",
|
||||||
|
enum: ["registry", "registry_emp", "registry_temp", "organization", "position"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "code",
|
||||||
|
in: "path",
|
||||||
|
required: true,
|
||||||
|
schema: {
|
||||||
|
type: "string",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "page",
|
||||||
|
in: "query",
|
||||||
|
required: false,
|
||||||
|
schema: {
|
||||||
|
type: "integer",
|
||||||
|
default: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "pageSize",
|
||||||
|
in: "query",
|
||||||
|
required: false,
|
||||||
|
schema: {
|
||||||
|
type: "integer",
|
||||||
|
default: 100,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: "Successful response",
|
||||||
|
},
|
||||||
|
400: {
|
||||||
|
description: "Bad request",
|
||||||
|
},
|
||||||
|
500: {
|
||||||
|
description: "Internal server error",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
securitySchemes: {
|
||||||
|
ApiKeyAuth: {
|
||||||
|
type: "apiKey",
|
||||||
|
in: "header",
|
||||||
|
name: "X-API-Key",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
security: [
|
||||||
|
{
|
||||||
|
ApiKeyAuth: [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
return new HttpSuccess(json);
|
||||||
|
}
|
||||||
|
}
|
||||||
200
src/controllers/ApiWebServiceController.ts
Normal file
200
src/controllers/ApiWebServiceController.ts
Normal file
|
|
@ -0,0 +1,200 @@
|
||||||
|
import { Controller, Route, Security, Tags, Path, Request, Response, Get, Query } from "tsoa";
|
||||||
|
import { AppDataSource } from "../database/data-source";
|
||||||
|
import HttpSuccess from "../interfaces/http-success";
|
||||||
|
import HttpStatusCode from "../interfaces/http-status";
|
||||||
|
import HttpError from "../interfaces/http-error";
|
||||||
|
import { ApiName } from "../entities/ApiName";
|
||||||
|
import { isPermissionRequest } from "../middlewares/authWebService";
|
||||||
|
import { RequestWithUserWebService } from "../middlewares/user";
|
||||||
|
import { OrgRevision } from "../entities/OrgRevision";
|
||||||
|
import { ApiHistory } from "../entities/ApiHistory";
|
||||||
|
import { SystemCode } from "./../interfaces/api-type";
|
||||||
|
@Route("api/v1/org/api-service")
|
||||||
|
@Tags("ApiKey")
|
||||||
|
@Security("webServiceAuth")
|
||||||
|
@Response(
|
||||||
|
HttpStatusCode.INTERNAL_SERVER_ERROR,
|
||||||
|
"เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง",
|
||||||
|
)
|
||||||
|
export class ApiWebServiceController extends Controller {
|
||||||
|
private apiNameRepository = AppDataSource.getRepository(ApiName);
|
||||||
|
private orgRevisionRepository = AppDataSource.getRepository(OrgRevision);
|
||||||
|
private apiHistoryRepository = AppDataSource.getRepository(ApiHistory);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list fields by systems
|
||||||
|
* @summary รายการ fields ตาม systems
|
||||||
|
*/
|
||||||
|
@Get("/:system/:code")
|
||||||
|
async listAttribute(
|
||||||
|
@Request() request: RequestWithUserWebService,
|
||||||
|
@Path("system")
|
||||||
|
system: SystemCode,
|
||||||
|
@Path("code") code: string,
|
||||||
|
@Query("page") page: number = 1,
|
||||||
|
@Query("pageSize") pageSize: number = 100,
|
||||||
|
): Promise<HttpSuccess | HttpError> {
|
||||||
|
const apiName = await this.apiNameRepository.findOne({
|
||||||
|
where: { code },
|
||||||
|
select: ["id", "code", "methodApi", "system", "isActive"],
|
||||||
|
relations: ["apiAttributes"],
|
||||||
|
order: {
|
||||||
|
apiAttributes: {
|
||||||
|
ordering: "ASC",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!apiName || apiName.system != system || !apiName.isActive || apiName.methodApi != "GET") {
|
||||||
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบ API ที่ระบุ");
|
||||||
|
}
|
||||||
|
await isPermissionRequest(request, apiName.id);
|
||||||
|
const offset = (page - 1) * pageSize;
|
||||||
|
const propertyKey = apiName.apiAttributes.map((attr) => `${attr.tbName}.${attr.propertyKey}`);
|
||||||
|
|
||||||
|
let tbMain: string = "";
|
||||||
|
let condition: string = "1=1";
|
||||||
|
if (system == "registry") {
|
||||||
|
tbMain = "Profile";
|
||||||
|
} else if (system == "registry_emp") {
|
||||||
|
tbMain = "ProfileEmployee";
|
||||||
|
condition = `ProfileEmployee.employeeClass = "PERM"`;
|
||||||
|
} else if (system == "registry_temp") {
|
||||||
|
tbMain = "ProfileEmployee";
|
||||||
|
condition = `ProfileEmployee.employeeClass = "TEMP"`;
|
||||||
|
} else if (system == "organization") {
|
||||||
|
tbMain = "OrgRoot";
|
||||||
|
const revision = await this.orgRevisionRepository.findOne({
|
||||||
|
select: ["id"],
|
||||||
|
where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
|
||||||
|
});
|
||||||
|
condition = `OrgRoot.orgRevisionId = "${revision?.id}"`;
|
||||||
|
} else if (system == "position") {
|
||||||
|
tbMain = "PosMaster";
|
||||||
|
const revision = await this.orgRevisionRepository.findOne({
|
||||||
|
select: ["id"],
|
||||||
|
where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
|
||||||
|
});
|
||||||
|
condition = `PosMaster.orgRevisionId = "${revision?.id}"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const repo = AppDataSource.getRepository(tbMain);
|
||||||
|
const metadata = repo.metadata;
|
||||||
|
|
||||||
|
const relationMap: Record<string, string> = {};
|
||||||
|
metadata.relations.forEach((rel) => {
|
||||||
|
relationMap[rel.inverseEntityMetadata.name] = rel.propertyName;
|
||||||
|
});
|
||||||
|
|
||||||
|
// ดึงเฉพาะตารางรอง (ถ้าเลือกไว้)
|
||||||
|
let propertyOtherKey: any[] = [];
|
||||||
|
propertyOtherKey = [
|
||||||
|
...new Set(propertyKey.map((x) => x.split(".")[0]).filter((tb) => tb !== tbMain)),
|
||||||
|
];
|
||||||
|
|
||||||
|
const queryBuilder = repo.createQueryBuilder(tbMain);
|
||||||
|
|
||||||
|
// join กับตารารอง
|
||||||
|
if (propertyOtherKey.length > 0) {
|
||||||
|
propertyOtherKey.forEach((tb) => {
|
||||||
|
const relationName = relationMap[tb];
|
||||||
|
if (relationName) {
|
||||||
|
queryBuilder.leftJoin(
|
||||||
|
`${tbMain}.${relationName === "next_holder" ? "current_holder" : relationName}`, // เช็คว่าถ้าเป็น next_holder ให้ใช้ current_holder แทน
|
||||||
|
tb,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// // เพิ่ม Main.id เพราะจะใช้ pk ในการแมบและนับจำนวน
|
||||||
|
// if (!propertyKey.includes(`${Main}.id`)) {
|
||||||
|
// propertyKey.push(`${Main}.id`);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// add FK
|
||||||
|
let pk: string = "";
|
||||||
|
const primaryColumns = metadata.primaryColumns;
|
||||||
|
primaryColumns.forEach((col) => {
|
||||||
|
pk = col.propertyName;
|
||||||
|
if (!propertyKey.includes(`${tbMain}.${pk}`)) {
|
||||||
|
propertyKey.push(`${tbMain}.${pk}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const [items, total] = await queryBuilder
|
||||||
|
.select(propertyKey)
|
||||||
|
.where(condition)
|
||||||
|
.orderBy(propertyKey[0], "ASC")
|
||||||
|
.skip(offset)
|
||||||
|
.take(pageSize)
|
||||||
|
.getManyAndCount();
|
||||||
|
|
||||||
|
// ลบ Main.id
|
||||||
|
// const results = items.map(({ id, ...x }) => x);
|
||||||
|
// const results = items.map(({ pk, ...x }) => x);
|
||||||
|
|
||||||
|
// const results = items.map(item => {
|
||||||
|
// primaryColumns.forEach(col => delete item[col.propertyName]);
|
||||||
|
// return item;
|
||||||
|
// });
|
||||||
|
|
||||||
|
// split object id ออกก่อน return
|
||||||
|
const data = items.map((item) => {
|
||||||
|
const { [pk]: removedPk, ...x } = item;
|
||||||
|
return x;
|
||||||
|
});
|
||||||
|
|
||||||
|
// console.log("queryBuilder ===> ", queryBuilder.getQuery());
|
||||||
|
|
||||||
|
// save api history after query success
|
||||||
|
const history = {
|
||||||
|
headerApi: JSON.stringify({
|
||||||
|
host: request.headers.host,
|
||||||
|
"x-api-key": request.headers["x-api-key"],
|
||||||
|
connection: request.headers.connection,
|
||||||
|
accept: request.headers.accept,
|
||||||
|
}),
|
||||||
|
tokenApi: Array.isArray(request.headers["x-api-key"])
|
||||||
|
? request.headers["x-api-key"][0] || ""
|
||||||
|
: request.headers["x-api-key"] || "",
|
||||||
|
requestApi: `${request.method} ${request.protocol}://${request.headers.host}${request.originalUrl || request.url}`,
|
||||||
|
responseApi: "OK",
|
||||||
|
ipApi: request.ip,
|
||||||
|
codeApi: code,
|
||||||
|
apiKeyId: request.user.id,
|
||||||
|
apiNameId: apiName.id,
|
||||||
|
createdFullName: request.user.name,
|
||||||
|
lastUpdateFullName: request.user.name,
|
||||||
|
};
|
||||||
|
await this.apiHistoryRepository.save(history);
|
||||||
|
|
||||||
|
// const results = data.map((item) => {
|
||||||
|
// const flattenedItem: any = {};
|
||||||
|
|
||||||
|
// // Extract nested object properties to top level
|
||||||
|
// Object.keys(item).forEach((key) => {
|
||||||
|
// const value = item[key];
|
||||||
|
// if (value && typeof value === "object") {
|
||||||
|
// // if (Array.isArray(value) && value.length === 1) {
|
||||||
|
// // // If array has single item, extract it as object
|
||||||
|
// // Object.assign(flattenedItem, value[0]);
|
||||||
|
// // } else
|
||||||
|
// if (!Array.isArray(value)) {
|
||||||
|
// // Merge nested object properties to top level
|
||||||
|
// Object.assign(flattenedItem, value);
|
||||||
|
// } else {
|
||||||
|
// // Keep arrays with multiple items or empty arrays as is
|
||||||
|
// flattenedItem[key] = value;
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// // Keep primitive values as is
|
||||||
|
// flattenedItem[key] = value;
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
// return flattenedItem;
|
||||||
|
// });
|
||||||
|
return new HttpSuccess({ data: data, total });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3120,7 +3120,10 @@ export class CommandController extends Controller {
|
||||||
orgRevisionId: posMaster.orgRevisionId,
|
orgRevisionId: posMaster.orgRevisionId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (posMasterOld != null) posMasterOld.current_holderId = null;
|
if (posMasterOld != null) {
|
||||||
|
posMasterOld.current_holderId = null;
|
||||||
|
posMasterOld.lastUpdatedAt = new Date();
|
||||||
|
}
|
||||||
|
|
||||||
const positionOld = await this.positionRepository.findOne({
|
const positionOld = await this.positionRepository.findOne({
|
||||||
where: {
|
where: {
|
||||||
|
|
@ -3148,6 +3151,7 @@ export class CommandController extends Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
posMaster.current_holderId = item.profileId;
|
posMaster.current_holderId = item.profileId;
|
||||||
|
posMaster.lastUpdatedAt = new Date();
|
||||||
posMaster.conditionReason = _null;
|
posMaster.conditionReason = _null;
|
||||||
posMaster.isCondition = false;
|
posMaster.isCondition = false;
|
||||||
if (posMasterOld != null) await this.posMasterRepository.save(posMasterOld);
|
if (posMasterOld != null) await this.posMasterRepository.save(posMasterOld);
|
||||||
|
|
@ -3304,7 +3308,10 @@ export class CommandController extends Controller {
|
||||||
orgRevisionId: posMaster.orgRevisionId,
|
orgRevisionId: posMaster.orgRevisionId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (posMasterOld != null) posMasterOld.current_holderId = null;
|
if (posMasterOld != null) {
|
||||||
|
posMasterOld.current_holderId = null;
|
||||||
|
posMasterOld.lastUpdatedAt = new Date();
|
||||||
|
}
|
||||||
// if (posMasterOld != null) posMasterOld.next_holderId = null;
|
// if (posMasterOld != null) posMasterOld.next_holderId = null;
|
||||||
|
|
||||||
const positionOld = await this.employeePositionRepository.findOne({
|
const positionOld = await this.employeePositionRepository.findOne({
|
||||||
|
|
@ -3333,6 +3340,7 @@ export class CommandController extends Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
posMaster.current_holderId = item.profileId;
|
posMaster.current_holderId = item.profileId;
|
||||||
|
posMaster.lastUpdatedAt = new Date();
|
||||||
posMaster.next_holderId = null;
|
posMaster.next_holderId = null;
|
||||||
if (posMasterOld != null) await this.employeePosMasterRepository.save(posMasterOld);
|
if (posMasterOld != null) await this.employeePosMasterRepository.save(posMasterOld);
|
||||||
await this.employeePosMasterRepository.save(posMaster);
|
await this.employeePosMasterRepository.save(posMaster);
|
||||||
|
|
@ -3561,6 +3569,7 @@ export class CommandController extends Controller {
|
||||||
await this.positionRepository.save(clearPosition);
|
await this.positionRepository.save(clearPosition);
|
||||||
}
|
}
|
||||||
posMaster.current_holderId = profile.id;
|
posMaster.current_holderId = profile.id;
|
||||||
|
posMaster.lastUpdatedAt = new Date();
|
||||||
posMaster.conditionReason = _null;
|
posMaster.conditionReason = _null;
|
||||||
posMaster.isCondition = false;
|
posMaster.isCondition = false;
|
||||||
await this.posMasterRepository.save(posMaster);
|
await this.posMasterRepository.save(posMaster);
|
||||||
|
|
@ -5987,7 +5996,10 @@ export class CommandController extends Controller {
|
||||||
orgRevisionId: posMaster.orgRevisionId,
|
orgRevisionId: posMaster.orgRevisionId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (posMasterOld != null) posMasterOld.current_holderId = null;
|
if (posMasterOld != null) {
|
||||||
|
posMasterOld.current_holderId = null;
|
||||||
|
posMasterOld.lastUpdatedAt = new Date();
|
||||||
|
}
|
||||||
|
|
||||||
const positionOld = await this.positionRepository.findOne({
|
const positionOld = await this.positionRepository.findOne({
|
||||||
where: {
|
where: {
|
||||||
|
|
@ -6015,6 +6027,7 @@ export class CommandController extends Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
posMaster.current_holderId = profile.id;
|
posMaster.current_holderId = profile.id;
|
||||||
|
posMaster.lastUpdatedAt = new Date();
|
||||||
posMaster.conditionReason = _null;
|
posMaster.conditionReason = _null;
|
||||||
posMaster.isCondition = false;
|
posMaster.isCondition = false;
|
||||||
if (posMasterOld != null) await this.posMasterRepository.save(posMasterOld);
|
if (posMasterOld != null) await this.posMasterRepository.save(posMasterOld);
|
||||||
|
|
@ -6364,7 +6377,10 @@ export class CommandController extends Controller {
|
||||||
orgRevisionId: posMaster.orgRevisionId,
|
orgRevisionId: posMaster.orgRevisionId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (posMasterOld != null) posMasterOld.current_holderId = null;
|
if (posMasterOld != null) {
|
||||||
|
posMasterOld.current_holderId = null;
|
||||||
|
posMasterOld.lastUpdatedAt = new Date();
|
||||||
|
}
|
||||||
// if (posMasterOld != null) posMasterOld.next_holderId = null;
|
// if (posMasterOld != null) posMasterOld.next_holderId = null;
|
||||||
|
|
||||||
const positionOld = await this.employeePositionRepository.findOne({
|
const positionOld = await this.employeePositionRepository.findOne({
|
||||||
|
|
@ -6393,6 +6409,7 @@ export class CommandController extends Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
posMaster.current_holderId = profile.id;
|
posMaster.current_holderId = profile.id;
|
||||||
|
posMaster.lastUpdatedAt = new Date();
|
||||||
posMaster.next_holderId = null;
|
posMaster.next_holderId = null;
|
||||||
if (posMasterOld != null) await this.employeePosMasterRepository.save(posMasterOld);
|
if (posMasterOld != null) await this.employeePosMasterRepository.save(posMasterOld);
|
||||||
await this.employeePosMasterRepository.save(posMaster);
|
await this.employeePosMasterRepository.save(posMaster);
|
||||||
|
|
@ -6673,23 +6690,11 @@ export class CommandController extends Controller {
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 8. บันทึกข้อมูลใหม่
|
// 8. ปิดสถานะรักษาการ
|
||||||
const dataAct = new ProfileActposition();
|
|
||||||
Object.assign(dataAct, metaAct);
|
|
||||||
|
|
||||||
const historyAct = new ProfileActpositionHistory();
|
|
||||||
Object.assign(historyAct, { ...dataAct, id: undefined });
|
|
||||||
|
|
||||||
await this.actpositionRepository.save(dataAct);
|
|
||||||
historyAct.profileActpositionId = dataAct.id;
|
|
||||||
await this.actpositionHistoryRepository.save(historyAct);
|
|
||||||
|
|
||||||
// 9. ปิดสถานะรักษาการ
|
|
||||||
const existingActPositions = await this.actpositionRepository.find({
|
const existingActPositions = await this.actpositionRepository.find({
|
||||||
where: {
|
where: {
|
||||||
profileId: item.posMasterChild.current_holderId,
|
profileId: item.posMasterChild.current_holderId,
|
||||||
status: true,
|
status: true,
|
||||||
id: Not(dataAct.id),
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -6702,6 +6707,17 @@ export class CommandController extends Controller {
|
||||||
|
|
||||||
await this.actpositionRepository.save(updatedActPositions);
|
await this.actpositionRepository.save(updatedActPositions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 9. บันทึกข้อมูลใหม่
|
||||||
|
const dataAct = new ProfileActposition();
|
||||||
|
Object.assign(dataAct, metaAct);
|
||||||
|
|
||||||
|
const historyAct = new ProfileActpositionHistory();
|
||||||
|
Object.assign(historyAct, { ...dataAct, id: undefined });
|
||||||
|
|
||||||
|
await this.actpositionRepository.save(dataAct);
|
||||||
|
historyAct.profileActpositionId = dataAct.id;
|
||||||
|
await this.actpositionHistoryRepository.save(historyAct);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error processing item ${item.id}:`, error);
|
console.error(`Error processing item ${item.id}:`, error);
|
||||||
throw new HttpError(
|
throw new HttpError(
|
||||||
|
|
|
||||||
|
|
@ -372,18 +372,22 @@ export class EmployeePositionController extends Controller {
|
||||||
// });
|
// });
|
||||||
// }
|
// }
|
||||||
findData = await this.employeePosDictRepository
|
findData = await this.employeePosDictRepository
|
||||||
.createQueryBuilder("posDict")
|
.createQueryBuilder("posDict")
|
||||||
.leftJoinAndSelect("posDict.posType", "posType")
|
.leftJoinAndSelect("posDict.posType", "posType")
|
||||||
.leftJoinAndSelect("posDict.posLevel", "posLevel")
|
.leftJoinAndSelect("posDict.posLevel", "posLevel")
|
||||||
.where( keyword
|
.where(
|
||||||
? "CONCAT(posType.posTypeShortName, ' ', posLevel.posLevelName) LIKE :keyword":"1=1", {keyword: `%${keyword}%`})
|
keyword
|
||||||
.orderBy("posDict.posDictName", "ASC")
|
? "CONCAT(posType.posTypeShortName, ' ', posLevel.posLevelName) LIKE :keyword"
|
||||||
.addOrderBy("posDict.createdAt", "DESC")
|
: "1=1",
|
||||||
.addOrderBy("posType.posTypeRank", "ASC")
|
{ keyword: `%${keyword}%` },
|
||||||
.addOrderBy("posType.createdAt", "DESC")
|
)
|
||||||
.addOrderBy("posLevel.posLevelName", "ASC")
|
.orderBy("posDict.posDictName", "ASC")
|
||||||
.addOrderBy("posLevel.createdAt", "DESC")
|
.addOrderBy("posDict.createdAt", "DESC")
|
||||||
.getMany();
|
.addOrderBy("posType.posTypeRank", "ASC")
|
||||||
|
.addOrderBy("posType.createdAt", "DESC")
|
||||||
|
.addOrderBy("posLevel.posLevelName", "ASC")
|
||||||
|
.addOrderBy("posLevel.createdAt", "DESC")
|
||||||
|
.getMany();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -2258,6 +2262,7 @@ export class EmployeePositionController extends Controller {
|
||||||
|
|
||||||
dataMaster.isSit = requestBody.isSit;
|
dataMaster.isSit = requestBody.isSit;
|
||||||
dataMaster.current_holderId = requestBody.profileId;
|
dataMaster.current_holderId = requestBody.profileId;
|
||||||
|
dataMaster.lastUpdatedAt = new Date();
|
||||||
// dataMaster.next_holderId = requestBody.profileId;
|
// dataMaster.next_holderId = requestBody.profileId;
|
||||||
await this.employeePosMasterRepository.save(dataMaster);
|
await this.employeePosMasterRepository.save(dataMaster);
|
||||||
|
|
||||||
|
|
@ -2394,7 +2399,10 @@ export class EmployeePositionController extends Controller {
|
||||||
orgRevisionId: posMaster.orgRevisionId,
|
orgRevisionId: posMaster.orgRevisionId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (posMasterOld != null) posMasterOld.current_holderId = null;
|
if (posMasterOld != null) {
|
||||||
|
posMasterOld.current_holderId = null;
|
||||||
|
posMasterOld.lastUpdatedAt = new Date();
|
||||||
|
}
|
||||||
// if (posMasterOld != null) posMasterOld.next_holderId = null;
|
// if (posMasterOld != null) posMasterOld.next_holderId = null;
|
||||||
|
|
||||||
const positionOld = await this.employeePositionRepository.findOne({
|
const positionOld = await this.employeePositionRepository.findOne({
|
||||||
|
|
@ -2429,6 +2437,7 @@ export class EmployeePositionController extends Controller {
|
||||||
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลทะเบียนประวัตินี้");
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลทะเบียนประวัตินี้");
|
||||||
|
|
||||||
posMaster.current_holderId = body.profileId;
|
posMaster.current_holderId = body.profileId;
|
||||||
|
posMaster.lastUpdatedAt = new Date();
|
||||||
// posMaster.next_holderId = body.profileId;
|
// posMaster.next_holderId = body.profileId;
|
||||||
if (posMasterOld != null) await this.employeePosMasterRepository.save(posMasterOld);
|
if (posMasterOld != null) await this.employeePosMasterRepository.save(posMasterOld);
|
||||||
await this.employeePosMasterRepository.save(posMaster);
|
await this.employeePosMasterRepository.save(posMaster);
|
||||||
|
|
|
||||||
|
|
@ -2001,6 +2001,7 @@ export class EmployeeTempPositionController extends Controller {
|
||||||
|
|
||||||
dataMaster.isSit = requestBody.isSit;
|
dataMaster.isSit = requestBody.isSit;
|
||||||
dataMaster.current_holderId = requestBody.profileId;
|
dataMaster.current_holderId = requestBody.profileId;
|
||||||
|
dataMaster.lastUpdatedAt = new Date();
|
||||||
// dataMaster.next_holderId = requestBody.profileId;
|
// dataMaster.next_holderId = requestBody.profileId;
|
||||||
await this.employeeTempPosMasterRepository.save(dataMaster);
|
await this.employeeTempPosMasterRepository.save(dataMaster);
|
||||||
|
|
||||||
|
|
@ -2137,7 +2138,10 @@ export class EmployeeTempPositionController extends Controller {
|
||||||
orgRevisionId: posMaster.orgRevisionId,
|
orgRevisionId: posMaster.orgRevisionId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (posMasterOld != null) posMasterOld.current_holderId = null;
|
if (posMasterOld != null) {
|
||||||
|
posMasterOld.current_holderId = null;
|
||||||
|
posMasterOld.lastUpdatedAt = new Date();
|
||||||
|
}
|
||||||
// if (posMasterOld != null) posMasterOld.next_holderId = null;
|
// if (posMasterOld != null) posMasterOld.next_holderId = null;
|
||||||
|
|
||||||
const positionOld = await this.employeePositionRepository.findOne({
|
const positionOld = await this.employeePositionRepository.findOne({
|
||||||
|
|
@ -2172,6 +2176,7 @@ export class EmployeeTempPositionController extends Controller {
|
||||||
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลทะเบียนประวัตินี้");
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลทะเบียนประวัตินี้");
|
||||||
|
|
||||||
posMaster.current_holderId = body.profileId;
|
posMaster.current_holderId = body.profileId;
|
||||||
|
posMaster.lastUpdatedAt = new Date();
|
||||||
// posMaster.next_holderId = body.profileId;
|
// posMaster.next_holderId = body.profileId;
|
||||||
if (posMasterOld != null) await this.employeeTempPosMasterRepository.save(posMasterOld);
|
if (posMasterOld != null) await this.employeeTempPosMasterRepository.save(posMasterOld);
|
||||||
await this.employeeTempPosMasterRepository.save(posMaster);
|
await this.employeeTempPosMasterRepository.save(posMaster);
|
||||||
|
|
|
||||||
|
|
@ -340,7 +340,7 @@ export class OrgRootController extends Controller {
|
||||||
const before = structuredClone(orgRoot);
|
const before = structuredClone(orgRoot);
|
||||||
orgRoot.lastUpdateUserId = request.user.sub;
|
orgRoot.lastUpdateUserId = request.user.sub;
|
||||||
orgRoot.lastUpdateFullName = request.user.name;
|
orgRoot.lastUpdateFullName = request.user.name;
|
||||||
orgRoot.lastUpdatedAt = new Date();
|
// orgRoot.lastUpdatedAt = new Date();
|
||||||
this.orgRootRepository.merge(orgRoot, {
|
this.orgRootRepository.merge(orgRoot, {
|
||||||
...requestBody,
|
...requestBody,
|
||||||
DEPARTMENT_CODE: requestBody.DEPARTMENT_CODE != null ? requestBody.DEPARTMENT_CODE : _null,
|
DEPARTMENT_CODE: requestBody.DEPARTMENT_CODE != null ? requestBody.DEPARTMENT_CODE : _null,
|
||||||
|
|
|
||||||
|
|
@ -693,7 +693,11 @@ export class OrganizationDotnetController extends Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let positionLeaveName = profile.posLevel?.posLevelName ?? null;
|
let positionLeaveName =
|
||||||
|
profile.posType == null && profile.posLevel == null
|
||||||
|
? ""
|
||||||
|
: `${profile.posType?.posTypeShortName ?? ""} ${profile.posLevel?.posLevelName ?? ""}`
|
||||||
|
|
||||||
const _profileCurrent = profile?.current_holders?.find(
|
const _profileCurrent = profile?.current_holders?.find(
|
||||||
(x) =>
|
(x) =>
|
||||||
x.orgRevision?.orgRevisionIsDraft === false &&
|
x.orgRevision?.orgRevisionIsDraft === false &&
|
||||||
|
|
|
||||||
|
|
@ -1431,11 +1431,77 @@ export class PositionController extends Controller {
|
||||||
@Get("position/{id}")
|
@Get("position/{id}")
|
||||||
async detailPosition(@Path() id: string) {
|
async detailPosition(@Path() id: string) {
|
||||||
const posMaster = await this.posMasterRepository.findOne({
|
const posMaster = await this.posMasterRepository.findOne({
|
||||||
|
relations: ["orgRoot", "orgChild1", "orgChild2", "orgChild3", "orgChild4"],
|
||||||
where: { id },
|
where: { id },
|
||||||
});
|
});
|
||||||
if (!posMaster) {
|
if (!posMaster) {
|
||||||
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล");
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล");
|
||||||
}
|
}
|
||||||
|
let orgLevel: any;
|
||||||
|
|
||||||
|
switch (true) {
|
||||||
|
case !!posMaster.orgChild4Id:
|
||||||
|
orgLevel = 4;
|
||||||
|
break;
|
||||||
|
case !!posMaster.orgChild3Id:
|
||||||
|
orgLevel = 3;
|
||||||
|
break;
|
||||||
|
case !!posMaster.orgChild2Id:
|
||||||
|
orgLevel = 2;
|
||||||
|
break;
|
||||||
|
case !!posMaster.orgChild1Id:
|
||||||
|
orgLevel = 1;
|
||||||
|
break;
|
||||||
|
case !!posMaster.orgRootId:
|
||||||
|
orgLevel = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
orgLevel = null; // ถ้าไม่มีข้อมูลเลย
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let shortName = "";
|
||||||
|
let orgId: any;
|
||||||
|
if (
|
||||||
|
posMaster.orgRootId !== null &&
|
||||||
|
posMaster.orgChild1Id == null &&
|
||||||
|
posMaster.orgChild2Id == null &&
|
||||||
|
posMaster.orgChild3Id == null
|
||||||
|
) {
|
||||||
|
shortName = posMaster.orgRoot.orgRootShortName;
|
||||||
|
orgId = posMaster.orgRootId;
|
||||||
|
} else if (
|
||||||
|
posMaster.orgRootId !== null &&
|
||||||
|
posMaster.orgChild1Id !== null &&
|
||||||
|
posMaster.orgChild2Id == null &&
|
||||||
|
posMaster.orgChild3Id == null
|
||||||
|
) {
|
||||||
|
shortName = posMaster.orgChild1.orgChild1ShortName;
|
||||||
|
orgId = posMaster.orgChild1Id;
|
||||||
|
} else if (
|
||||||
|
posMaster.orgRootId !== null &&
|
||||||
|
posMaster.orgChild1Id !== null &&
|
||||||
|
posMaster.orgChild2Id !== null &&
|
||||||
|
posMaster.orgChild3Id == null
|
||||||
|
) {
|
||||||
|
shortName = posMaster.orgChild2.orgChild2ShortName;
|
||||||
|
orgId = posMaster.orgChild2Id;
|
||||||
|
} else if (
|
||||||
|
posMaster.orgRootId !== null &&
|
||||||
|
posMaster.orgChild1Id !== null &&
|
||||||
|
posMaster.orgChild2Id !== null &&
|
||||||
|
posMaster.orgChild3Id !== null
|
||||||
|
) {
|
||||||
|
shortName = posMaster.orgChild3.orgChild3ShortName;
|
||||||
|
orgId = posMaster.orgChild3Id;
|
||||||
|
} else if (
|
||||||
|
posMaster.orgRootId !== null &&
|
||||||
|
posMaster.orgChild1Id !== null &&
|
||||||
|
posMaster.orgChild2Id !== null &&
|
||||||
|
posMaster.orgChild3Id !== null
|
||||||
|
) {
|
||||||
|
shortName = posMaster.orgChild4.orgChild4ShortName;
|
||||||
|
orgId = posMaster.orgChild4Id;
|
||||||
|
}
|
||||||
const positions = await this.positionRepository.find({
|
const positions = await this.positionRepository.find({
|
||||||
where: { posMasterId: posMaster.id },
|
where: { posMasterId: posMaster.id },
|
||||||
relations: ["posType", "posLevel", "posExecutive"],
|
relations: ["posType", "posLevel", "posExecutive"],
|
||||||
|
|
@ -1457,6 +1523,9 @@ export class PositionController extends Controller {
|
||||||
reason: posMaster.reason,
|
reason: posMaster.reason,
|
||||||
// isOfficer: posMaster.isOfficer,
|
// isOfficer: posMaster.isOfficer,
|
||||||
isStaff: posMaster.isStaff,
|
isStaff: posMaster.isStaff,
|
||||||
|
orgLevel: orgLevel,
|
||||||
|
orgShortname: shortName,
|
||||||
|
orgId: orgId,
|
||||||
isDirector: posMaster.isDirector,
|
isDirector: posMaster.isDirector,
|
||||||
positionSign: posMaster.positionSign,
|
positionSign: posMaster.positionSign,
|
||||||
positions: positions.map((position) => ({
|
positions: positions.map((position) => ({
|
||||||
|
|
@ -2582,69 +2651,72 @@ export class PositionController extends Controller {
|
||||||
async getHistoryPosMater(@Path() id: string, @Request() request: RequestWithUser) {
|
async getHistoryPosMater(@Path() id: string, @Request() request: RequestWithUser) {
|
||||||
let _workflow = await new permission().Workflow(request, id, "SYS_ORG");
|
let _workflow = await new permission().Workflow(request, id, "SYS_ORG");
|
||||||
if (_workflow == false) await new permission().PermissionGet(request, "SYS_ORG");
|
if (_workflow == false) await new permission().PermissionGet(request, "SYS_ORG");
|
||||||
const posMaster = await this.posMasterRepository.findOne({
|
|
||||||
where: { id },
|
// ใช้ query builder สำหรับประสิทธิภาพที่ดีขึ้น
|
||||||
});
|
const queryBuilder = this.posMasterRepository
|
||||||
|
.createQueryBuilder("pm")
|
||||||
|
.leftJoinAndSelect("pm.orgRevision", "orgRevision")
|
||||||
|
.leftJoinAndSelect("pm.orgRoot", "orgRoot")
|
||||||
|
.leftJoinAndSelect("pm.orgChild1", "orgChild1")
|
||||||
|
.leftJoinAndSelect("pm.orgChild2", "orgChild2")
|
||||||
|
.leftJoinAndSelect("pm.orgChild3", "orgChild3")
|
||||||
|
.leftJoinAndSelect("pm.orgChild4", "orgChild4")
|
||||||
|
.leftJoinAndSelect("pm.current_holder", "current_holder")
|
||||||
|
.leftJoinAndSelect("pm.positions", "positions")
|
||||||
|
.leftJoinAndSelect("positions.posLevel", "posLevel")
|
||||||
|
.leftJoinAndSelect("positions.posType", "posType")
|
||||||
|
.leftJoinAndSelect("positions.posExecutive", "posExecutive");
|
||||||
|
|
||||||
|
// หาข้อมูลหลัก
|
||||||
|
const posMaster = await queryBuilder.where("pm.id = :id", { id }).getOne();
|
||||||
|
|
||||||
if (!posMaster) {
|
if (!posMaster) {
|
||||||
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลตำแหน่งนี้");
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลตำแหน่งนี้");
|
||||||
}
|
}
|
||||||
const posMasters = await this.posMasterRepository.find({
|
|
||||||
where: {
|
// สร้าง conditions
|
||||||
ancestorDNA:
|
const ancestorDNA = posMaster.ancestorDNA || "123";
|
||||||
posMaster.ancestorDNA == null || posMaster.ancestorDNA == ""
|
let historyQuery = queryBuilder.where("pm.ancestorDNA = :ancestorDNA", { ancestorDNA });
|
||||||
? "123"
|
|
||||||
: posMaster.ancestorDNA,
|
// เพิ่มเงื่อนไข draft
|
||||||
},
|
if (
|
||||||
order: { lastUpdatedAt: "DESC" },
|
posMaster.orgRevision?.orgRevisionIsCurrent != false &&
|
||||||
relations: [
|
posMaster.orgRevision?.orgRevisionIsDraft != true
|
||||||
"orgRoot",
|
) {
|
||||||
"orgChild1",
|
historyQuery = historyQuery.andWhere("orgRevision.orgRevisionIsDraft != :isDraft", {
|
||||||
"orgChild2",
|
isDraft: true,
|
||||||
"orgChild3",
|
});
|
||||||
"orgChild4",
|
}
|
||||||
"current_holder",
|
|
||||||
"positions",
|
const posMasters = await historyQuery.orderBy("pm.lastUpdatedAt", "DESC").getMany();
|
||||||
"positions.posLevel",
|
|
||||||
"positions.posType",
|
|
||||||
"positions.posExecutive",
|
|
||||||
],
|
|
||||||
});
|
|
||||||
const _data = posMasters.map((item) => ({
|
const _data = posMasters.map((item) => ({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
orgShortName:
|
orgShortName:
|
||||||
item.orgRoot == null
|
item.orgChild4?.orgChild4ShortName ||
|
||||||
? null
|
item.orgChild3?.orgChild3ShortName ||
|
||||||
: item.orgChild1 == null
|
item.orgChild2?.orgChild2ShortName ||
|
||||||
? item.orgRoot.orgRootShortName
|
item.orgChild1?.orgChild1ShortName ||
|
||||||
: item.orgChild2 == null
|
item.orgRoot?.orgRootShortName ||
|
||||||
? item.orgChild1.orgChild1ShortName
|
null,
|
||||||
: item.orgChild3 == null
|
lastUpdatedAt: item.lastUpdatedAt,
|
||||||
? item.orgChild2.orgChild2ShortName
|
posMasterNoPrefix: item.posMasterNoPrefix,
|
||||||
: item.orgChild4 == null
|
posMasterNo: item.posMasterNo,
|
||||||
? item.orgChild3.orgChild3ShortName
|
posMasterNoSuffix: item.posMasterNoSuffix,
|
||||||
: item.orgChild4.orgChild4ShortName,
|
reason: item.reason,
|
||||||
lastUpdatedAt: item.lastUpdatedAt ? item.lastUpdatedAt : null,
|
|
||||||
posMasterNoPrefix: item.posMasterNoPrefix ? item.posMasterNoPrefix : null,
|
|
||||||
posMasterNo: item.posMasterNo ? item.posMasterNo : null,
|
|
||||||
posMasterNoSuffix: item.posMasterNoSuffix ? item.posMasterNoSuffix : null,
|
|
||||||
reason: item.reason ? item.reason : null,
|
|
||||||
position: item.positions.map((x) => x.positionName).join("/"),
|
position: item.positions.map((x) => x.positionName).join("/"),
|
||||||
posExecutive: item.positions
|
posExecutive: item.positions
|
||||||
.filter((x) => x.posExecutive != null)
|
.filter((x) => x.posExecutive)
|
||||||
.map((x) => x.posExecutive?.posExecutiveName ?? null)
|
.map((x) => x.posExecutive!.posExecutiveName)
|
||||||
.join("/"),
|
.join("/"),
|
||||||
posLevel: item.positions.map((x) => x.posLevel.posLevelName).join("/"),
|
posLevel: item.positions.map((x) => x.posLevel.posLevelName).join("/"),
|
||||||
posType: item.positions.map((x) => x.posType.posTypeName).join("/"),
|
posType: item.positions.map((x) => x.posType.posTypeName).join("/"),
|
||||||
fullname:
|
fullname:
|
||||||
(item?.current_holder?.prefix ?? "") +
|
`${item.current_holder?.prefix || ""}${item.current_holder?.firstName || ""} ${item.current_holder?.lastName || ""}`.trim(),
|
||||||
"" +
|
|
||||||
(item?.current_holder?.firstName ?? "") +
|
|
||||||
" " +
|
|
||||||
(item?.current_holder?.lastName ?? ""),
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return new HttpSuccess(_data);
|
return new HttpSuccess(_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API ย้ายอัตรากำลัง
|
* API ย้ายอัตรากำลัง
|
||||||
*
|
*
|
||||||
|
|
@ -3518,6 +3590,7 @@ export class PositionController extends Controller {
|
||||||
const before = null;
|
const before = null;
|
||||||
dataMaster.isSit = requestBody.isSit;
|
dataMaster.isSit = requestBody.isSit;
|
||||||
dataMaster.next_holderId = requestBody.profileId;
|
dataMaster.next_holderId = requestBody.profileId;
|
||||||
|
dataMaster.lastUpdatedAt = new Date();
|
||||||
//add on
|
//add on
|
||||||
dataMaster.conditionReason = _null;
|
dataMaster.conditionReason = _null;
|
||||||
dataMaster.isCondition = false;
|
dataMaster.isCondition = false;
|
||||||
|
|
@ -4658,7 +4731,10 @@ export class PositionController extends Controller {
|
||||||
orgRevisionId: posMaster.orgRevisionId,
|
orgRevisionId: posMaster.orgRevisionId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (posMasterOld != null) posMasterOld.current_holderId = null;
|
if (posMasterOld != null) {
|
||||||
|
posMasterOld.current_holderId = null;
|
||||||
|
posMasterOld.lastUpdatedAt = new Date();
|
||||||
|
}
|
||||||
|
|
||||||
const positionOld = await this.positionRepository.findOne({
|
const positionOld = await this.positionRepository.findOne({
|
||||||
where: {
|
where: {
|
||||||
|
|
@ -4692,6 +4768,7 @@ export class PositionController extends Controller {
|
||||||
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลทะเบียนประวัตินี้");
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลทะเบียนประวัตินี้");
|
||||||
|
|
||||||
posMaster.current_holderId = body.profileId;
|
posMaster.current_holderId = body.profileId;
|
||||||
|
posMaster.lastUpdatedAt = new Date();
|
||||||
const _null: any = null;
|
const _null: any = null;
|
||||||
posMaster.conditionReason = _null;
|
posMaster.conditionReason = _null;
|
||||||
posMaster.isCondition = false;
|
posMaster.isCondition = false;
|
||||||
|
|
@ -5245,6 +5322,7 @@ export class PositionController extends Controller {
|
||||||
if (!profile) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลผู้ใช้งาน");
|
if (!profile) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลผู้ใช้งาน");
|
||||||
|
|
||||||
posMaster.next_holderId = requestBody.profileId;
|
posMaster.next_holderId = requestBody.profileId;
|
||||||
|
posMaster.lastUpdatedAt = new Date();
|
||||||
posMaster.lastUpdateUserId = request.user.sub;
|
posMaster.lastUpdateUserId = request.user.sub;
|
||||||
posMaster.lastUpdateFullName = request.user.name;
|
posMaster.lastUpdateFullName = request.user.name;
|
||||||
posMaster.lastUpdatedAt = new Date();
|
posMaster.lastUpdatedAt = new Date();
|
||||||
|
|
|
||||||
|
|
@ -1321,7 +1321,7 @@ export class ProfileController extends Controller {
|
||||||
"profileLeave.dateLeaveEnd AS dateLeaveEnd",
|
"profileLeave.dateLeaveEnd AS dateLeaveEnd",
|
||||||
"profileLeave.leaveDays AS leaveDays",
|
"profileLeave.leaveDays AS leaveDays",
|
||||||
"profileLeave.reason AS reason",
|
"profileLeave.reason AS reason",
|
||||||
"leaveType.name as name"
|
"leaveType.name as name",
|
||||||
])
|
])
|
||||||
.where("profileLeave.profileId = :profileId", { profileId: id })
|
.where("profileLeave.profileId = :profileId", { profileId: id })
|
||||||
.andWhere("leaveType.code IN (:...codes)", { codes: ["LV-008", "LV-009", "LV-010"] })
|
.andWhere("leaveType.code IN (:...codes)", { codes: ["LV-008", "LV-009", "LV-010"] })
|
||||||
|
|
@ -1331,10 +1331,12 @@ export class ProfileController extends Controller {
|
||||||
const leaves2 =
|
const leaves2 =
|
||||||
leave2_raw.length > 0
|
leave2_raw.length > 0
|
||||||
? leave2_raw.map((item) => ({
|
? leave2_raw.map((item) => ({
|
||||||
date: item.dateLeaveStart && item.dateLeaveEnd
|
date:
|
||||||
? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.dateLeaveStart)) + " - "
|
item.dateLeaveStart && item.dateLeaveEnd
|
||||||
+ Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.dateLeaveEnd))
|
? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.dateLeaveStart)) +
|
||||||
: "-",
|
" - " +
|
||||||
|
Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.dateLeaveEnd))
|
||||||
|
: "-",
|
||||||
type: item.name || "-",
|
type: item.name || "-",
|
||||||
leaveDays: item.leaveDays ? Extension.ToThaiNumber(item.leaveDays.toString()) : "-",
|
leaveDays: item.leaveDays ? Extension.ToThaiNumber(item.leaveDays.toString()) : "-",
|
||||||
reason: item.reason || "-",
|
reason: item.reason || "-",
|
||||||
|
|
@ -1684,24 +1686,22 @@ export class ProfileController extends Controller {
|
||||||
)
|
)
|
||||||
: "";
|
: "";
|
||||||
|
|
||||||
let portfolios:any
|
let portfolios: any;
|
||||||
await new CallAPI()
|
await new CallAPI()
|
||||||
.GetData(req, `/development/portfolio/kk1/${profiles?.keycloak}`)
|
.GetData(req, `/development/portfolio/kk1/${profiles?.keycloak}`)
|
||||||
.then((x) => {
|
.then((x) => {
|
||||||
portfolios = x;
|
portfolios = x;
|
||||||
})
|
})
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
if (!portfolios) {
|
if (!portfolios) {
|
||||||
portfolios = [{ name: "-", year: "-" }]
|
portfolios = [{ name: "-", year: "-" }];
|
||||||
|
} else {
|
||||||
|
portfolios = portfolios.map((x: any) => ({
|
||||||
|
name: x.name ? Extension.ToThaiNumber(x.name) : "-",
|
||||||
|
year: x.year ? Extension.ToThaiNumber(x.year.toString()) : "-",
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
portfolios = portfolios.map((x:any) => ({
|
|
||||||
name: x.name ? x.name : "-",
|
|
||||||
year: x.year ? Extension.ToThaiNumber(x.year.toString()) : "-"
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
fullName: `${profiles?.prefix}${profiles?.firstName} ${profiles?.lastName}`,
|
fullName: `${profiles?.prefix}${profiles?.firstName} ${profiles?.lastName}`,
|
||||||
prefix: profiles?.prefix != null ? profiles.prefix : "",
|
prefix: profiles?.prefix != null ? profiles.prefix : "",
|
||||||
|
|
@ -1855,7 +1855,7 @@ export class ProfileController extends Controller {
|
||||||
assessments,
|
assessments,
|
||||||
profileAbility,
|
profileAbility,
|
||||||
otherIncome,
|
otherIncome,
|
||||||
portfolios
|
portfolios,
|
||||||
};
|
};
|
||||||
|
|
||||||
return new HttpSuccess({
|
return new HttpSuccess({
|
||||||
|
|
@ -2855,7 +2855,8 @@ export class ProfileController extends Controller {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (!posMaster) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลการครองตำแหน่ง");
|
if (!posMaster) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลการครองตำแหน่ง");
|
||||||
posMaster.current_holderId = "";
|
posMaster.current_holderId = null;
|
||||||
|
posMaster.lastUpdatedAt = new Date();
|
||||||
// return new HttpSuccess({ data: [], total: 0 });
|
// return new HttpSuccess({ data: [], total: 0 });
|
||||||
} else if ((posMaster?.current_holder?.posLevel?.posLevelAuthority ?? null) == "GOVERNOR") {
|
} else if ((posMaster?.current_holder?.posLevel?.posLevelAuthority ?? null) == "GOVERNOR") {
|
||||||
return new HttpSuccess({ data: [], total: 0 });
|
return new HttpSuccess({ data: [], total: 0 });
|
||||||
|
|
@ -9616,6 +9617,46 @@ export class ProfileController extends Controller {
|
||||||
keyword: `%${body.keyword}%`,
|
keyword: `%${body.keyword}%`,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
.orWhere(
|
||||||
|
body.keyword != null && body.keyword != ""
|
||||||
|
? "CONCAT(orgRoot.orgRootShortName,' ',posMaster.posMasterNo) LIKE :keyword"
|
||||||
|
: "1=1",
|
||||||
|
{
|
||||||
|
keyword: `%${body.keyword}%`,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.orWhere(
|
||||||
|
body.keyword != null && body.keyword != ""
|
||||||
|
? "CONCAT(orgChild1.orgChild1ShortName,' ',posMaster.posMasterNo) LIKE :keyword"
|
||||||
|
: "1=1",
|
||||||
|
{
|
||||||
|
keyword: `%${body.keyword}%`,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.orWhere(
|
||||||
|
body.keyword != null && body.keyword != ""
|
||||||
|
? "CONCAT(orgChild2.orgChild2ShortName,' ',posMaster.posMasterNo) LIKE :keyword"
|
||||||
|
: "1=1",
|
||||||
|
{
|
||||||
|
keyword: `%${body.keyword}%`,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.orWhere(
|
||||||
|
body.keyword != null && body.keyword != ""
|
||||||
|
? "CONCAT(orgChild3.orgChild3ShortName,' ',posMaster.posMasterNo) LIKE :keyword"
|
||||||
|
: "1=1",
|
||||||
|
{
|
||||||
|
keyword: `%${body.keyword}%`,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.orWhere(
|
||||||
|
body.keyword != null && body.keyword != ""
|
||||||
|
? "CONCAT(orgChild4.orgChild4ShortName,' ',posMaster.posMasterNo) LIKE :keyword"
|
||||||
|
: "1=1",
|
||||||
|
{
|
||||||
|
keyword: `%${body.keyword}%`,
|
||||||
|
},
|
||||||
|
)
|
||||||
.orWhere(
|
.orWhere(
|
||||||
body.keyword != null && body.keyword != ""
|
body.keyword != null && body.keyword != ""
|
||||||
? "current_holder.position LIKE :keyword"
|
? "current_holder.position LIKE :keyword"
|
||||||
|
|
|
||||||
|
|
@ -5038,6 +5038,46 @@ export class ProfileEmployeeController extends Controller {
|
||||||
keyword: `%${body.keyword}%`,
|
keyword: `%${body.keyword}%`,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
.orWhere(
|
||||||
|
body.keyword != null && body.keyword != ""
|
||||||
|
? "CONCAT(orgRoot.orgRootShortName,' ',employeePosMaster.posMasterNo) LIKE :keyword"
|
||||||
|
: "1=1",
|
||||||
|
{
|
||||||
|
keyword: `%${body.keyword}%`,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.orWhere(
|
||||||
|
body.keyword != null && body.keyword != ""
|
||||||
|
? "CONCAT(orgChild1.orgChild1ShortName,' ',employeePosMaster.posMasterNo) LIKE :keyword"
|
||||||
|
: "1=1",
|
||||||
|
{
|
||||||
|
keyword: `%${body.keyword}%`,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.orWhere(
|
||||||
|
body.keyword != null && body.keyword != ""
|
||||||
|
? "CONCAT(orgChild2.orgChild2ShortName,' ',employeePosMaster.posMasterNo) LIKE :keyword"
|
||||||
|
: "1=1",
|
||||||
|
{
|
||||||
|
keyword: `%${body.keyword}%`,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.orWhere(
|
||||||
|
body.keyword != null && body.keyword != ""
|
||||||
|
? "CONCAT(orgChild3.orgChild3ShortName,' ',employeePosMaster.posMasterNo) LIKE :keyword"
|
||||||
|
: "1=1",
|
||||||
|
{
|
||||||
|
keyword: `%${body.keyword}%`,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.orWhere(
|
||||||
|
body.keyword != null && body.keyword != ""
|
||||||
|
? "CONCAT(orgChild4.orgChild4ShortName,' ',employeePosMaster.posMasterNo) LIKE :keyword"
|
||||||
|
: "1=1",
|
||||||
|
{
|
||||||
|
keyword: `%${body.keyword}%`,
|
||||||
|
},
|
||||||
|
)
|
||||||
.orWhere(
|
.orWhere(
|
||||||
body.keyword != null && body.keyword != ""
|
body.keyword != null && body.keyword != ""
|
||||||
? "current_holder.position LIKE :keyword"
|
? "current_holder.position LIKE :keyword"
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import {
|
||||||
import permission from "../interfaces/permission";
|
import permission from "../interfaces/permission";
|
||||||
import { OrgRevision } from "../entities/OrgRevision";
|
import { OrgRevision } from "../entities/OrgRevision";
|
||||||
import { In } from "typeorm";
|
import { In } from "typeorm";
|
||||||
|
import { ProfileSalary } from "../entities/ProfileSalary";
|
||||||
@Route("api/v1/org/profile-employee/government")
|
@Route("api/v1/org/profile-employee/government")
|
||||||
@Tags("ProfileEmployeeGovernment")
|
@Tags("ProfileEmployeeGovernment")
|
||||||
@Security("bearerAuth")
|
@Security("bearerAuth")
|
||||||
|
|
@ -26,6 +27,7 @@ export class ProfileGovernmentEmployeeController extends Controller {
|
||||||
private positionRepo = AppDataSource.getRepository(EmployeePosition);
|
private positionRepo = AppDataSource.getRepository(EmployeePosition);
|
||||||
private posMasterRepo = AppDataSource.getRepository(EmployeePosMaster);
|
private posMasterRepo = AppDataSource.getRepository(EmployeePosMaster);
|
||||||
private orgRevisionRepository = AppDataSource.getRepository(OrgRevision);
|
private orgRevisionRepository = AppDataSource.getRepository(OrgRevision);
|
||||||
|
private salaryRepo = AppDataSource.getRepository(ProfileSalary);
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @summary ข้อมูลราชการ
|
* @summary ข้อมูลราชการ
|
||||||
|
|
@ -150,32 +152,32 @@ export class ProfileGovernmentEmployeeController extends Controller {
|
||||||
const record = await this.profileEmployeeRepo.findOne({
|
const record = await this.profileEmployeeRepo.findOne({
|
||||||
where: {
|
where: {
|
||||||
id: profileEmployeeId,
|
id: profileEmployeeId,
|
||||||
profileSalary: {
|
// profileSalary: {
|
||||||
commandCode: In([
|
// commandCode: In([
|
||||||
"0",
|
// "0",
|
||||||
"9",
|
// "9",
|
||||||
"1",
|
// "1",
|
||||||
"2",
|
// "2",
|
||||||
"3",
|
// "3",
|
||||||
"4",
|
// "4",
|
||||||
"8",
|
// "8",
|
||||||
"10",
|
// "10",
|
||||||
"11",
|
// "11",
|
||||||
"12",
|
// "12",
|
||||||
"13",
|
// "13",
|
||||||
"14",
|
// "14",
|
||||||
"15",
|
// "15",
|
||||||
"16",
|
// "16",
|
||||||
]),
|
// ]),
|
||||||
}
|
// }
|
||||||
},
|
},
|
||||||
relations: ["posType", "posLevel", "profileSalary"],
|
relations: ["posType", "posLevel"/*, "profileSalary"*/],
|
||||||
order: {
|
// order: {
|
||||||
profileSalary: {
|
// profileSalary: {
|
||||||
order: "DESC",
|
// order: "DESC",
|
||||||
createdAt: "DESC"
|
// createdAt: "DESC"
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
});
|
});
|
||||||
const posMaster = await this.posMasterRepo.findOne({
|
const posMaster = await this.posMasterRepo.findOne({
|
||||||
where: {
|
where: {
|
||||||
|
|
@ -216,16 +218,55 @@ export class ProfileGovernmentEmployeeController extends Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let _OrgLeave:any = []
|
let _OrgLeave:any = []
|
||||||
if (record?.isLeave && record?.profileSalary.length > 0) {
|
let orgLeave:string = ""
|
||||||
|
let posNoLeave:string = ""
|
||||||
|
if (record?.isLeave /*&& record?.profileSalary.length > 0*/) {
|
||||||
|
const profileSalary = await this.salaryRepo.find({
|
||||||
|
select: [
|
||||||
|
"orgRoot",
|
||||||
|
"orgChild1",
|
||||||
|
"orgChild2",
|
||||||
|
"orgChild3",
|
||||||
|
"orgChild4",
|
||||||
|
"posNoAbb",
|
||||||
|
"posNo"
|
||||||
|
],
|
||||||
|
where: {
|
||||||
|
profileEmployeeId: profileEmployeeId,
|
||||||
|
commandCode: In([
|
||||||
|
"0",
|
||||||
|
"9",
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
"4",
|
||||||
|
"8",
|
||||||
|
"10",
|
||||||
|
"11",
|
||||||
|
"12",
|
||||||
|
"13",
|
||||||
|
"14",
|
||||||
|
"15",
|
||||||
|
"16",
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
order: {
|
||||||
|
order: "DESC",
|
||||||
|
createdAt: "DESC"
|
||||||
|
}
|
||||||
|
});
|
||||||
_OrgLeave = [
|
_OrgLeave = [
|
||||||
record?.profileSalary[0].orgChild4 ? record?.profileSalary[0].orgChild4 : null,
|
profileSalary.length > 0 && profileSalary[0].orgChild4 ? profileSalary[0].orgChild4 : null,
|
||||||
record?.profileSalary[0].orgChild3 ? record?.profileSalary[0].orgChild3 : null,
|
profileSalary.length > 0 && profileSalary[0].orgChild3 ? profileSalary[0].orgChild3 : null,
|
||||||
record?.profileSalary[0].orgChild2 ? record?.profileSalary[0].orgChild2 : null,
|
profileSalary.length > 0 && profileSalary[0].orgChild2 ? profileSalary[0].orgChild2 : null,
|
||||||
record?.profileSalary[0].orgChild1 ? record?.profileSalary[0].orgChild1 : null,
|
profileSalary.length > 0 && profileSalary[0].orgChild1 ? profileSalary[0].orgChild1 : null,
|
||||||
record?.profileSalary[0].orgRoot ? record?.profileSalary[0].orgRoot : null,
|
profileSalary.length > 0 && profileSalary[0].orgRoot ? profileSalary[0].orgRoot : null,
|
||||||
];
|
];
|
||||||
|
orgLeave = _OrgLeave.filter((x:any) => x !== undefined && x !== null).join("\n");
|
||||||
|
posNoLeave = profileSalary.length > 0
|
||||||
|
? `${profileSalary[0].posNoAbb} ${profileSalary[0].posNo}`
|
||||||
|
: ""
|
||||||
}
|
}
|
||||||
const orgLeave = _OrgLeave.filter((x:any) => x !== undefined && x !== null).join("\n");
|
|
||||||
const data = {
|
const data = {
|
||||||
org: record?.isLeave == false ? org : orgLeave, //สังกัด
|
org: record?.isLeave == false ? org : orgLeave, //สังกัด
|
||||||
position: record?.position, //ตำแหน่ง
|
position: record?.position, //ตำแหน่ง
|
||||||
|
|
@ -235,9 +276,9 @@ export class ProfileGovernmentEmployeeController extends Controller {
|
||||||
: `${record?.posType?.posTypeShortName ?? ""} ${record?.posLevel?.posLevelName ?? ""}`, //ระดับ
|
: `${record?.posType?.posTypeShortName ?? ""} ${record?.posLevel?.posLevelName ?? ""}`, //ระดับ
|
||||||
posMasterNo: record?.isLeave == false
|
posMasterNo: record?.isLeave == false
|
||||||
? posMaster == null ? null : `${orgShortName} ${posMaster.posMasterNo}`
|
? posMaster == null ? null : `${orgShortName} ${posMaster.posMasterNo}`
|
||||||
: record && record?.profileSalary.length > 0
|
: posNoLeave/*record && record?.profileSalary.length > 0
|
||||||
? `${record?.profileSalary[0].posNoAbb} ${record?.profileSalary[0].posNo}`
|
? `${record?.profileSalary[0].posNoAbb} ${record?.profileSalary[0].posNo}`
|
||||||
: null, //เลขที่ตำแหน่ง
|
: null*/, //เลขที่ตำแหน่ง
|
||||||
posType: record?.posType == null ? null : record?.posType.posTypeName, //ประเภท
|
posType: record?.posType == null ? null : record?.posType.posTypeName, //ประเภท
|
||||||
dateLeave: record?.birthDate == null ? null : calculateRetireDate(record?.birthDate), //วันเกษียณ
|
dateLeave: record?.birthDate == null ? null : calculateRetireDate(record?.birthDate), //วันเกษียณ
|
||||||
dateAppoint: record?.dateAppoint, //วันที่สั่งบรรจุ
|
dateAppoint: record?.dateAppoint, //วันที่สั่งบรรจุ
|
||||||
|
|
@ -265,29 +306,29 @@ export class ProfileGovernmentEmployeeController extends Controller {
|
||||||
const record = await this.profileEmployeeRepo.findOne({
|
const record = await this.profileEmployeeRepo.findOne({
|
||||||
where: {
|
where: {
|
||||||
id: profileEmployeeId,
|
id: profileEmployeeId,
|
||||||
profileSalary:{
|
// profileSalary:{
|
||||||
commandCode: In([
|
// commandCode: In([
|
||||||
"0",
|
// "0",
|
||||||
"9",
|
// "9",
|
||||||
"1",
|
// "1",
|
||||||
"2",
|
// "2",
|
||||||
"3",
|
// "3",
|
||||||
"4",
|
// "4",
|
||||||
"8",
|
// "8",
|
||||||
"10",
|
// "10",
|
||||||
"11",
|
// "11",
|
||||||
"12",
|
// "12",
|
||||||
"13",
|
// "13",
|
||||||
"14",
|
// "14",
|
||||||
"15",
|
// "15",
|
||||||
"16",
|
// "16",
|
||||||
]),
|
// ]),
|
||||||
}
|
// }
|
||||||
},
|
},
|
||||||
relations: {
|
relations: {
|
||||||
posType: true,
|
posType: true,
|
||||||
posLevel: true,
|
posLevel: true,
|
||||||
profileSalary: true
|
// profileSalary: true
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const posMaster = await this.posMasterRepo.findOne({
|
const posMaster = await this.posMasterRepo.findOne({
|
||||||
|
|
@ -329,16 +370,55 @@ export class ProfileGovernmentEmployeeController extends Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let _OrgLeave:any = []
|
let _OrgLeave:any = []
|
||||||
if (record?.isLeave && record?.profileSalary.length > 0) {
|
let orgLeave:string = ""
|
||||||
|
let posNoLeave:string = ""
|
||||||
|
if (record?.isLeave /*&& record?.profileSalary.length > 0*/) {
|
||||||
|
const profileSalary = await this.salaryRepo.find({
|
||||||
|
select: [
|
||||||
|
"orgRoot",
|
||||||
|
"orgChild1",
|
||||||
|
"orgChild2",
|
||||||
|
"orgChild3",
|
||||||
|
"orgChild4",
|
||||||
|
"posNoAbb",
|
||||||
|
"posNo"
|
||||||
|
],
|
||||||
|
where: {
|
||||||
|
profileEmployeeId: profileEmployeeId,
|
||||||
|
commandCode: In([
|
||||||
|
"0",
|
||||||
|
"9",
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
"4",
|
||||||
|
"8",
|
||||||
|
"10",
|
||||||
|
"11",
|
||||||
|
"12",
|
||||||
|
"13",
|
||||||
|
"14",
|
||||||
|
"15",
|
||||||
|
"16",
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
order: {
|
||||||
|
order: "DESC",
|
||||||
|
createdAt: "DESC"
|
||||||
|
}
|
||||||
|
});
|
||||||
_OrgLeave = [
|
_OrgLeave = [
|
||||||
record?.profileSalary[0].orgChild4 ? record?.profileSalary[0].orgChild4 : null,
|
profileSalary.length > 0 && profileSalary[0].orgChild4 ? profileSalary[0].orgChild4 : null,
|
||||||
record?.profileSalary[0].orgChild3 ? record?.profileSalary[0].orgChild3 : null,
|
profileSalary.length > 0 && profileSalary[0].orgChild3 ? profileSalary[0].orgChild3 : null,
|
||||||
record?.profileSalary[0].orgChild2 ? record?.profileSalary[0].orgChild2 : null,
|
profileSalary.length > 0 && profileSalary[0].orgChild2 ? profileSalary[0].orgChild2 : null,
|
||||||
record?.profileSalary[0].orgChild1 ? record?.profileSalary[0].orgChild1 : null,
|
profileSalary.length > 0 && profileSalary[0].orgChild1 ? profileSalary[0].orgChild1 : null,
|
||||||
record?.profileSalary[0].orgRoot ? record?.profileSalary[0].orgRoot : null,
|
profileSalary.length > 0 && profileSalary[0].orgRoot ? profileSalary[0].orgRoot : null,
|
||||||
];
|
];
|
||||||
|
orgLeave = _OrgLeave.filter((x:any) => x !== undefined && x !== null).join("\n");
|
||||||
|
posNoLeave = profileSalary.length > 0
|
||||||
|
? `${profileSalary[0].posNoAbb} ${profileSalary[0].posNo}`
|
||||||
|
: ""
|
||||||
}
|
}
|
||||||
const orgLeave = _OrgLeave.filter((x:any) => x !== undefined && x !== null).join("\n");
|
|
||||||
const data = {
|
const data = {
|
||||||
org: record?.isLeave == false ? org : orgLeave, //สังกัด
|
org: record?.isLeave == false ? org : orgLeave, //สังกัด
|
||||||
position: record?.position, //ตำแหน่ง
|
position: record?.position, //ตำแหน่ง
|
||||||
|
|
@ -350,9 +430,9 @@ export class ProfileGovernmentEmployeeController extends Controller {
|
||||||
? posMaster == null
|
? posMaster == null
|
||||||
? null
|
? null
|
||||||
: `${orgShortName} ${posMaster.posMasterNo}`
|
: `${orgShortName} ${posMaster.posMasterNo}`
|
||||||
: record && record.profileSalary.length > 0
|
: posNoLeave/*record && record.profileSalary.length > 0
|
||||||
? `${record?.profileSalary[0].posNoAbb} ${record?.profileSalary[0].posNo}`
|
? `${record?.profileSalary[0].posNoAbb} ${record?.profileSalary[0].posNo}`
|
||||||
: null, //เลขที่ตำแหน่ง
|
: null*/, //เลขที่ตำแหน่ง
|
||||||
posType: record?.posType == null ? null : record?.posType.posTypeName, //ประเภท
|
posType: record?.posType == null ? null : record?.posType.posTypeName, //ประเภท
|
||||||
dateLeave: record?.birthDate == null ? null : calculateRetireDate(record?.birthDate), //วันเกษียณ
|
dateLeave: record?.birthDate == null ? null : calculateRetireDate(record?.birthDate), //วันเกษียณ
|
||||||
dateAppoint: record?.dateAppoint, //วันที่สั่งบรรจุ
|
dateAppoint: record?.dateAppoint, //วันที่สั่งบรรจุ
|
||||||
|
|
|
||||||
|
|
@ -47,9 +47,13 @@ export const AppDataSource = new DataSource({
|
||||||
logging: true,
|
logging: true,
|
||||||
// timezone: "Z",
|
// timezone: "Z",
|
||||||
entities:
|
entities:
|
||||||
process.env.NODE_ENV !== "production" ? ["src/entities/**/*.ts"] : ["dist/entities/**/*{.ts,.js}"],
|
process.env.NODE_ENV !== "production"
|
||||||
|
? ["src/entities/**/*.ts"]
|
||||||
|
: ["dist/entities/**/*{.ts,.js}"],
|
||||||
migrations:
|
migrations:
|
||||||
process.env.NODE_ENV !== "production" ? ["src/entities/*.ts"] : ["dist/entities/*{.ts,.js}"],
|
process.env.NODE_ENV !== "production"
|
||||||
|
? ["src/migration/**/*.ts"]
|
||||||
|
: ["dist/migration/**/*{.ts,.js}"],
|
||||||
subscribers: [],
|
subscribers: [],
|
||||||
logger: new MyCustomLogger(),
|
logger: new MyCustomLogger(),
|
||||||
});
|
});
|
||||||
|
|
|
||||||
39
src/entities/ApiAttribute.ts
Normal file
39
src/entities/ApiAttribute.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { ApiName } from "./ApiName";
|
||||||
|
import { Entity, Column, ManyToOne, JoinColumn } from "typeorm";
|
||||||
|
import { EntityBase } from "./base/Base";
|
||||||
|
|
||||||
|
@Entity("apiAttribute")
|
||||||
|
export class ApiAttribute extends EntityBase {
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "ชื่อตาราง",
|
||||||
|
length: 50,
|
||||||
|
})
|
||||||
|
tbName: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คีย์ของแอตทริบิวต์",
|
||||||
|
length: 255,
|
||||||
|
})
|
||||||
|
propertyKey: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "ลำดับการแสดงผล",
|
||||||
|
default: 0,
|
||||||
|
type: "int",
|
||||||
|
})
|
||||||
|
ordering: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "ไอดีของ API Name",
|
||||||
|
length: 36, // UUID length
|
||||||
|
})
|
||||||
|
apiNameId: string;
|
||||||
|
|
||||||
|
@ManyToOne(() => ApiName, (apiName) => apiName.apiAttributes)
|
||||||
|
@JoinColumn({ name: "apiNameId" })
|
||||||
|
apiName: ApiName;
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { ApiAttribute } from "./ApiAttribute";
|
||||||
import { Entity, Column, ManyToMany, JoinTable, OneToMany } from "typeorm";
|
import { Entity, Column, ManyToMany, JoinTable, OneToMany } from "typeorm";
|
||||||
import { EntityBase } from "./base/Base";
|
import { EntityBase } from "./base/Base";
|
||||||
import { ApiKey } from "./ApiKey";
|
import { ApiKey } from "./ApiKey";
|
||||||
|
|
@ -29,10 +30,61 @@ export class ApiName extends EntityBase {
|
||||||
})
|
})
|
||||||
methodApi: string;
|
methodApi: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "code สำหรับการเรียก API",
|
||||||
|
length: 8,
|
||||||
|
})
|
||||||
|
code: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "code ระบบสำหรับการเรียก API",
|
||||||
|
length: 50,
|
||||||
|
default: "registry",
|
||||||
|
})
|
||||||
|
system: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "สถานะการใช้งาน",
|
||||||
|
type: "boolean",
|
||||||
|
default: false,
|
||||||
|
})
|
||||||
|
isActive: boolean;
|
||||||
|
|
||||||
@ManyToMany(() => ApiKey, (apiKey) => apiKey.apiNames)
|
@ManyToMany(() => ApiKey, (apiKey) => apiKey.apiNames)
|
||||||
@JoinTable()
|
@JoinTable()
|
||||||
apiKeys: ApiKey[];
|
apiKeys: ApiKey[];
|
||||||
|
|
||||||
@OneToMany(() => ApiHistory, (v) => v.apiName)
|
@OneToMany(() => ApiHistory, (v) => v.apiName)
|
||||||
apiHistorys: ApiHistory[];
|
apiHistorys: ApiHistory[];
|
||||||
|
|
||||||
|
@OneToMany(() => ApiAttribute, (v) => v.apiName)
|
||||||
|
apiAttributes: ApiAttribute[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CreateApi {
|
||||||
|
@Column()
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
methodApi: "GET" | "POST" | "PUT";
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
system: string;
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
isActive: boolean;
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
apiAttributes: CreateApiAttribute[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CreateApiAttribute {
|
||||||
|
@Column()
|
||||||
|
tbName: string;
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
propertyKey: string[];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
16
src/interfaces/api-type.ts
Normal file
16
src/interfaces/api-type.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
type SystemCode = "registry" | "registry_emp" | "registry_temp" | "organization" | "position";
|
||||||
|
|
||||||
|
interface SystemDefinition {
|
||||||
|
code: SystemCode;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface EntityDefinition {
|
||||||
|
name: string;
|
||||||
|
repository: any;
|
||||||
|
description: string;
|
||||||
|
isMain?: boolean;
|
||||||
|
system: SystemCode[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export { SystemCode, SystemDefinition, EntityDefinition };
|
||||||
|
|
@ -553,6 +553,14 @@ export async function checkQueueInProgress(queueName: string) {
|
||||||
// return false;
|
// return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function chunkArray(array: any, size: number) {
|
||||||
|
const result = [];
|
||||||
|
for (let i = 0; i < array.length; i += size) {
|
||||||
|
result.push(array.slice(i, i + size));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
export function commandTypePath(commandCode: string): string | null {
|
export function commandTypePath(commandCode: string): string | null {
|
||||||
switch (commandCode) {
|
switch (commandCode) {
|
||||||
case "C-PM-01":
|
case "C-PM-01":
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { createDecoder, createVerifier } from "fast-jwt";
|
||||||
|
|
||||||
import HttpError from "../interfaces/http-error";
|
import HttpError from "../interfaces/http-error";
|
||||||
import HttpStatus from "../interfaces/http-status";
|
import HttpStatus from "../interfaces/http-status";
|
||||||
|
import { handleWebServiceAuth } from "./authWebService";
|
||||||
|
|
||||||
if (!process.env.AUTH_PUBLIC_KEY && !process.env.AUTH_REALM_URL) {
|
if (!process.env.AUTH_PUBLIC_KEY && !process.env.AUTH_REALM_URL) {
|
||||||
throw new Error("Require keycloak AUTH_PUBLIC_KEY or AUTH_REALM_URL.");
|
throw new Error("Require keycloak AUTH_PUBLIC_KEY or AUTH_REALM_URL.");
|
||||||
|
|
@ -30,6 +31,11 @@ export async function expressAuthentication(
|
||||||
return { preferred_username: "bypassed" };
|
return { preferred_username: "bypassed" };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// เพิ่มการจัดการสำหรับ Web Service Authentication
|
||||||
|
if (securityName === "webServiceAuth") {
|
||||||
|
return await handleWebServiceAuth(request);
|
||||||
|
}
|
||||||
|
|
||||||
if (securityName !== "bearerAuth") throw new Error("ไม่ทราบวิธีการยืนยันตัวตน");
|
if (securityName !== "bearerAuth") throw new Error("ไม่ทราบวิธีการยืนยันตัวตน");
|
||||||
|
|
||||||
const token = request.headers["authorization"]?.includes("Bearer ")
|
const token = request.headers["authorization"]?.includes("Bearer ")
|
||||||
|
|
|
||||||
56
src/middlewares/authWebService.ts
Normal file
56
src/middlewares/authWebService.ts
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
import { RequestWithUserWebService } from "./user";
|
||||||
|
import { AppDataSource } from "../database/data-source";
|
||||||
|
import { ApiKey } from "../entities/ApiKey";
|
||||||
|
import * as express from "express";
|
||||||
|
|
||||||
|
import HttpError from "../interfaces/http-error";
|
||||||
|
import HttpStatus from "../interfaces/http-status";
|
||||||
|
|
||||||
|
// เพิ่มฟังก์ชันสำหรับจัดการ Web Service Authentication
|
||||||
|
export async function handleWebServiceAuth(request: express.Request) {
|
||||||
|
// ตัวอย่างการใช้ API Key
|
||||||
|
const apiKey = request.headers["x-api-key"] as string;
|
||||||
|
|
||||||
|
if (!apiKey) {
|
||||||
|
throw new HttpError(HttpStatus.UNAUTHORIZED, "ไม่พบข้อมูลสำหรับยืนยันตัวตน");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ตรวจสอบ API Key กับฐานข้อมูล
|
||||||
|
const apiKeyData = await AppDataSource.getRepository(ApiKey).findOne({
|
||||||
|
select: { id: true, name: true, keyApi: true },
|
||||||
|
where: { keyApi: apiKey },
|
||||||
|
relations: ["apiNames"],
|
||||||
|
});
|
||||||
|
if (!apiKeyData) {
|
||||||
|
throw new HttpError(HttpStatus.UNAUTHORIZED, "ไม่สามารถยืนยันตัวตนได้");
|
||||||
|
}
|
||||||
|
|
||||||
|
// บันทึก log data สำหรับ web service
|
||||||
|
if (!request.app.locals.logData) {
|
||||||
|
request.app.locals.logData = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
request.app.locals.logData.id = apiKeyData.id;
|
||||||
|
request.app.locals.logData.name = apiKeyData.name;
|
||||||
|
request.app.locals.logData.accessApi = apiKeyData.apiNames.map((x) => x.id) ?? [];
|
||||||
|
|
||||||
|
// ส่งคืนข้อมูลผู้ใช้ที่ยืนยันตัวตน
|
||||||
|
return {
|
||||||
|
id: apiKeyData.id,
|
||||||
|
name: apiKeyData.name,
|
||||||
|
type: "web-service",
|
||||||
|
accessApi: apiKeyData.apiNames.map((x) => x.id) ?? [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isPermissionRequest(
|
||||||
|
request: RequestWithUserWebService,
|
||||||
|
apiId: string,
|
||||||
|
): Promise<boolean> {
|
||||||
|
// ฟังก์ชันนี้ใช้เพื่อตรวจสอบสิทธิ์ของผู้ใช้ที่ร้องขอ API โดยตรวจสอบว่า user มีสิทธิ์เข้าถึง API ที่ร้องขอหรือไม่
|
||||||
|
const hasPermission = request.user.accessApi.includes(apiId);
|
||||||
|
if (!hasPermission) {
|
||||||
|
throw new HttpError(HttpStatus.FORBIDDEN, "คุณไม่มีสิทธิ์เข้าถึง API นี้");
|
||||||
|
}
|
||||||
|
return Promise.resolve(hasPermission);
|
||||||
|
}
|
||||||
|
|
@ -11,3 +11,11 @@ export type RequestWithUser = Request & {
|
||||||
role: string[];
|
role: string[];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type RequestWithUserWebService = Request & {
|
||||||
|
user: {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
accessApi: string[];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
|
||||||
1316
src/migration/1754549669635-update_api_name.ts
Normal file
1316
src/migration/1754549669635-update_api_name.ts
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -1,7 +1,7 @@
|
||||||
import amqp from "amqplib";
|
import amqp from "amqplib";
|
||||||
import { AppDataSource } from "../database/data-source";
|
import { AppDataSource } from "../database/data-source";
|
||||||
import { Command } from "../entities/Command";
|
import { Command } from "../entities/Command";
|
||||||
import { commandTypePath } from "../interfaces/utils";
|
import { chunkArray, commandTypePath } from "../interfaces/utils";
|
||||||
import CallAPI from "../interfaces/call-api";
|
import CallAPI from "../interfaces/call-api";
|
||||||
import HttpError from "../interfaces/http-error";
|
import HttpError from "../interfaces/http-error";
|
||||||
import HttpStatusCode from "../interfaces/http-status";
|
import HttpStatusCode from "../interfaces/http-status";
|
||||||
|
|
@ -115,46 +115,139 @@ function createConsumer( //----> consumer
|
||||||
|
|
||||||
async function handler(msg: amqp.ConsumeMessage): Promise<boolean> {
|
async function handler(msg: amqp.ConsumeMessage): Promise<boolean> {
|
||||||
//----> condition before process consumer
|
//----> condition before process consumer
|
||||||
|
// const repo = AppDataSource.getRepository(Command);
|
||||||
|
// const { data, token, user } = JSON.parse(msg.content.toString());
|
||||||
|
// const { id, status, lastUpdateUserId, lastUpdateFullName, lastUpdatedAt } = data;
|
||||||
|
// const command = await repo.findOne({
|
||||||
|
// where: { id: id },
|
||||||
|
// relations: ["commandType", "commandRecives"],
|
||||||
|
// });
|
||||||
|
// if (!command) return true;
|
||||||
|
// let waiting_message = `ระบบทำการออกคำสั่งเลขที่ ${command.commandNo}/${command.commandYear + 543}`;
|
||||||
|
// let success_message = `ระบบออกคำสั่งเลขที่ ${command.commandNo}/${command.commandYear + 543} เสร็จสิ้น`;
|
||||||
|
// let error_message = `ระบบออกคำสั่งเลขที่ ${command.commandNo}/${command.commandYear + 543} ผิดพลาด`
|
||||||
|
// if(command.commandType?.code == "C-PM-47"){
|
||||||
|
// waiting_message = `ระบบทำการออกคำสั่งเลขที่ ${command.commandNo}`;
|
||||||
|
// success_message = `ระบบออกคำสั่งเลขที่ ${command.commandNo} เสร็จสิ้น`;
|
||||||
|
// error_message = `ระบบออกคำสั่งเลขที่ ${command.commandNo} ผิดพลาด`;
|
||||||
|
// }
|
||||||
|
// if (user) {
|
||||||
|
// sendWebSocket(
|
||||||
|
// "send-command-notification",
|
||||||
|
// {
|
||||||
|
// success: true,
|
||||||
|
// message: waiting_message,
|
||||||
|
// payload: command,
|
||||||
|
// },
|
||||||
|
// { userId: user?.sub },
|
||||||
|
// ).catch(console.error);
|
||||||
|
// }
|
||||||
|
// const path = commandTypePath(command.commandType.code);
|
||||||
|
// if (path == null) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบประเภทคำสั่งนี้ในระบบ");
|
||||||
|
// return await new CallAPI()
|
||||||
|
// //chunk 50
|
||||||
|
// .PostData(
|
||||||
|
// {
|
||||||
|
// headers: { authorization: token },
|
||||||
|
// },
|
||||||
|
// path + "/excecute",
|
||||||
|
// {
|
||||||
|
// refIds: command.commandRecives //chunk
|
||||||
|
// .filter((x) => x.refId != null)
|
||||||
|
// .map((x) => ({
|
||||||
|
// refId: x.refId,
|
||||||
|
// commandNo: command.commandNo,
|
||||||
|
// commandYear: command.commandYear,
|
||||||
|
// commandId: command.id,
|
||||||
|
// remark: command.positionDetail,
|
||||||
|
// amount: x.amount,
|
||||||
|
// amountSpecial: x.amountSpecial,
|
||||||
|
// positionSalaryAmount: x.positionSalaryAmount,
|
||||||
|
// mouthSalaryAmount: x.mouthSalaryAmount,
|
||||||
|
// commandCode: command.commandType.commandCode,
|
||||||
|
// commandName: command.commandType.name,
|
||||||
|
// commandDateAffect: command.commandExcecuteDate,
|
||||||
|
// commandDateSign: command.commandAffectDate,
|
||||||
|
// })),
|
||||||
|
// },
|
||||||
|
// false,
|
||||||
|
// )
|
||||||
|
// .then(async (res) => {
|
||||||
|
// console.log("[AMQ] Excecute Command Success");
|
||||||
|
// Object.assign(command, { status, lastUpdateUserId, lastUpdateFullName, lastUpdatedAt });
|
||||||
|
// const result = await repo.save(command).catch((e) => console.log(e));
|
||||||
|
// if (user) {
|
||||||
|
// sendWebSocket(
|
||||||
|
// "send-command-notification",
|
||||||
|
// {
|
||||||
|
// success: true,
|
||||||
|
// message: success_message,
|
||||||
|
// payload: command,
|
||||||
|
// },
|
||||||
|
// { userId: user?.sub },
|
||||||
|
// ).catch(console.error);
|
||||||
|
// }
|
||||||
|
// return !!result;
|
||||||
|
// })
|
||||||
|
// .catch((e) => {
|
||||||
|
// console.error(e);
|
||||||
|
// if (user) {
|
||||||
|
// sendWebSocket(
|
||||||
|
// "send-command-notification",
|
||||||
|
// {
|
||||||
|
// success: false,
|
||||||
|
// message: error_message,
|
||||||
|
// payload: command,
|
||||||
|
// },
|
||||||
|
// { userId: user?.sub },
|
||||||
|
// ).catch(console.error);
|
||||||
|
// }
|
||||||
|
// return false;
|
||||||
|
// });
|
||||||
const repo = AppDataSource.getRepository(Command);
|
const repo = AppDataSource.getRepository(Command);
|
||||||
const { data, token, user } = JSON.parse(msg.content.toString());
|
const { data, token, user } = JSON.parse(msg.content.toString());
|
||||||
const { id, status, lastUpdateUserId, lastUpdateFullName, lastUpdatedAt } = data;
|
const { id, status, lastUpdateUserId, lastUpdateFullName, lastUpdatedAt } = data;
|
||||||
|
|
||||||
const command = await repo.findOne({
|
const command = await repo.findOne({
|
||||||
where: { id: id },
|
where: { id: id },
|
||||||
relations: ["commandType", "commandRecives"],
|
relations: ["commandType", "commandRecives"],
|
||||||
});
|
});
|
||||||
if (!command) return true;
|
if (!command) return true;
|
||||||
|
|
||||||
let waiting_message = `ระบบทำการออกคำสั่งเลขที่ ${command.commandNo}/${command.commandYear + 543}`;
|
let waiting_message = `ระบบทำการออกคำสั่งเลขที่ ${command.commandNo}/${command.commandYear + 543}`;
|
||||||
let success_message = `ระบบออกคำสั่งเลขที่ ${command.commandNo}/${command.commandYear + 543} เสร็จสิ้น`;
|
let success_message = `ระบบออกคำสั่งเลขที่ ${command.commandNo}/${command.commandYear + 543} เสร็จสิ้น`;
|
||||||
let error_message = `ระบบออกคำสั่งเลขที่ ${command.commandNo}/${command.commandYear + 543} ผิดพลาด`
|
let error_message = `ระบบออกคำสั่งเลขที่ ${command.commandNo}/${command.commandYear + 543} ผิดพลาด`;
|
||||||
if(command.commandType?.code == "C-PM-47"){
|
|
||||||
|
if (command.commandType?.code == "C-PM-47") {
|
||||||
waiting_message = `ระบบทำการออกคำสั่งเลขที่ ${command.commandNo}`;
|
waiting_message = `ระบบทำการออกคำสั่งเลขที่ ${command.commandNo}`;
|
||||||
success_message = `ระบบออกคำสั่งเลขที่ ${command.commandNo} เสร็จสิ้น`;
|
success_message = `ระบบออกคำสั่งเลขที่ ${command.commandNo} เสร็จสิ้น`;
|
||||||
error_message = `ระบบออกคำสั่งเลขที่ ${command.commandNo} ผิดพลาด`;
|
error_message = `ระบบออกคำสั่งเลขที่ ${command.commandNo} ผิดพลาด`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
sendWebSocket(
|
sendWebSocket(
|
||||||
"send-command-notification",
|
"send-command-notification",
|
||||||
{
|
{ success: true, message: waiting_message, payload: command },
|
||||||
success: true,
|
|
||||||
message: waiting_message,
|
|
||||||
payload: command,
|
|
||||||
},
|
|
||||||
{ userId: user?.sub },
|
{ userId: user?.sub },
|
||||||
).catch(console.error);
|
).catch(console.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
const path = commandTypePath(command.commandType.code);
|
const path = commandTypePath(command.commandType.code);
|
||||||
if (path == null) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบประเภทคำสั่งนี้ในระบบ");
|
if (path == null) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบประเภทคำสั่งนี้ในระบบ");
|
||||||
return await new CallAPI()
|
|
||||||
|
try {
|
||||||
.PostData(
|
const allRefIds = new Set<string>();
|
||||||
{
|
const chunks = chunkArray(
|
||||||
headers: { authorization: token },
|
command.commandRecives
|
||||||
},
|
.filter((x) => x.refId != null)
|
||||||
path + "/excecute",
|
.map((x) => {
|
||||||
{
|
const key = `${x.refId}-${command.id}`;
|
||||||
refIds: command.commandRecives
|
if (allRefIds.has(key)) {
|
||||||
.filter((x) => x.refId != null)
|
return null;
|
||||||
.map((x) => ({
|
}
|
||||||
|
allRefIds.add(key);
|
||||||
|
|
||||||
|
return {
|
||||||
refId: x.refId,
|
refId: x.refId,
|
||||||
commandNo: command.commandNo,
|
commandNo: command.commandNo,
|
||||||
commandYear: command.commandYear,
|
commandYear: command.commandYear,
|
||||||
|
|
@ -168,42 +261,46 @@ async function handler(msg: amqp.ConsumeMessage): Promise<boolean> {
|
||||||
commandName: command.commandType.name,
|
commandName: command.commandType.name,
|
||||||
commandDateAffect: command.commandExcecuteDate,
|
commandDateAffect: command.commandExcecuteDate,
|
||||||
commandDateSign: command.commandAffectDate,
|
commandDateSign: command.commandAffectDate,
|
||||||
})),
|
};
|
||||||
},
|
})
|
||||||
false,
|
.filter(Boolean),
|
||||||
)
|
20
|
||||||
.then(async (res) => {
|
);
|
||||||
console.log("[AMQ] Excecute Command Success");
|
|
||||||
Object.assign(command, { status, lastUpdateUserId, lastUpdateFullName, lastUpdatedAt });
|
for (const chunk of chunks) {
|
||||||
const result = await repo.save(command).catch((e) => console.log(e));
|
await new CallAPI().PostData(
|
||||||
if (user) {
|
{ headers: { authorization: token } },
|
||||||
sendWebSocket(
|
path + "/excecute",
|
||||||
"send-command-notification",
|
{ refIds: chunk },
|
||||||
{
|
false
|
||||||
success: true,
|
);
|
||||||
message: success_message,
|
}
|
||||||
payload: command,
|
|
||||||
},
|
Object.assign(command, { status, lastUpdateUserId, lastUpdateFullName, lastUpdatedAt });
|
||||||
{ userId: user?.sub },
|
const result = await repo.save(command);
|
||||||
).catch(console.error);
|
|
||||||
}
|
if (user) {
|
||||||
return !!result;
|
sendWebSocket(
|
||||||
})
|
"send-command-notification",
|
||||||
.catch((e) => {
|
{ success: true, message: success_message, payload: command },
|
||||||
console.error(e);
|
{ userId: user?.sub },
|
||||||
if (user) {
|
).catch(console.error);
|
||||||
sendWebSocket(
|
}
|
||||||
"send-command-notification",
|
|
||||||
{
|
console.log("[AMQ] Excecute Command Success");
|
||||||
success: false,
|
return !!result;
|
||||||
message: error_message,
|
|
||||||
payload: command,
|
} catch (e) {
|
||||||
},
|
console.error(e);
|
||||||
{ userId: user?.sub },
|
if (user) {
|
||||||
).catch(console.error);
|
sendWebSocket(
|
||||||
}
|
"send-command-notification",
|
||||||
return false;
|
{ success: false, message: error_message, payload: command },
|
||||||
});
|
{ userId: user?.sub },
|
||||||
|
).catch(console.error);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// async function handler(msg: amqp.ConsumeMessage): Promise<boolean> {
|
// async function handler(msg: amqp.ConsumeMessage): Promise<boolean> {
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,12 @@
|
||||||
"name": "Authorization",
|
"name": "Authorization",
|
||||||
"description": "Keycloak Bearer Token",
|
"description": "Keycloak Bearer Token",
|
||||||
"in": "header"
|
"in": "header"
|
||||||
|
},
|
||||||
|
"webServiceAuth": {
|
||||||
|
"type": "apiKey",
|
||||||
|
"name": "X-API-Key",
|
||||||
|
"description": "API KEY สำหรับ Web Service",
|
||||||
|
"in": "header"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tags": [
|
"tags": [
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue