From b12d145aba25d50f22ea83d23668e26859e3fa85 Mon Sep 17 00:00:00 2001 From: Kittapath Date: Wed, 13 Mar 2024 13:37:53 +0700 Subject: [PATCH 1/2] =?UTF-8?q?=E0=B9=80=E0=B8=9E=E0=B8=B4=E0=B9=88?= =?UTF-8?q?=E0=B8=A1table=E0=B9=80=E0=B8=84=E0=B8=A3=E0=B8=B7=E0=B9=88?= =?UTF-8?q?=E0=B8=AD=E0=B8=87=E0=B8=A3=E0=B8=B2=E0=B8=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/entities/Insignia.ts | 72 +++++++++++++++++++ src/entities/InsigniaType.ts | 33 +++++++++ .../1710311804080-add_table_insignia.ts | 18 +++++ 3 files changed, 123 insertions(+) create mode 100644 src/entities/Insignia.ts create mode 100644 src/entities/InsigniaType.ts create mode 100644 src/migration/1710311804080-add_table_insignia.ts diff --git a/src/entities/Insignia.ts b/src/entities/Insignia.ts new file mode 100644 index 00000000..40771f37 --- /dev/null +++ b/src/entities/Insignia.ts @@ -0,0 +1,72 @@ +import { Entity, Column, ManyToOne, JoinColumn } from "typeorm"; +import { EntityBase } from "./base/Base"; +import { InsigniaType } from "./InsigniaType"; + +@Entity("insignia") +export class Insignia extends EntityBase { + @Column({ + nullable: true, + comment: "ชื่อเครื่องราช", + length: 255, + default: null, + }) + name: string; + + @Column({ + nullable: true, + comment: "ชื่อย่อเครื่องราช", + length: 255, + default: null, + }) + shortName: string; + + @Column({ + nullable: true, + comment: + "ลำดับชั้นของเครื่องราช เอาไว้ตรวจสอบเวลาขอว่าต้องได้ชั้นที่สูงกว่าที่เคยได้รับแล้วเท่านั้น", + default: null, + }) + level: number; + + @Column({ + comment: "สถานะการใช้งาน", + default: false, + }) + isActive: boolean; + + @Column({ + nullable: true, + comment: "หมายเหตุ", + default: null, + }) + note: string; + + @Column({ + length: 40, + comment: "id ประเภทเครื่องราช", + }) + insigniaTypeId: string; + + @ManyToOne(() => InsigniaType, (insigniaType) => insigniaType.insignias) + @JoinColumn({ name: "insigniaTypeId" }) + insigniaType: InsigniaType; +} + +export class CreateInsignias { + @Column() + name: string; + + @Column() + shortName: string; + + @Column() + isActive: boolean; + + @Column() + note: string; + + @Column("uuid") + insigniaTypeId: string; +} + +export type UpdateInsignias = Partial; diff --git a/src/entities/InsigniaType.ts b/src/entities/InsigniaType.ts new file mode 100644 index 00000000..f342cd93 --- /dev/null +++ b/src/entities/InsigniaType.ts @@ -0,0 +1,33 @@ +import { Entity, Column, OneToMany } from "typeorm"; +import { EntityBase } from "./base/Base"; +import { Insignia } from "./Insignia"; + +@Entity("insigniaType") +export class InsigniaType extends EntityBase { + @Column({ + nullable: true, + comment: "ชื่อประเภทเครื่องราช", + length: 255, + default: null, + }) + name: string; + + @Column({ + comment: "สถานะการใช้งาน", + default: false, + }) + isActive: boolean; + + @OneToMany(() => Insignia, (insignia) => insignia.insigniaType) + insignias: Insignia[]; +} + +export class CreateInsigniaType { + @Column() + name: string; + + @Column() + isActive: boolean; +} + +export type UpdateInsigniaType = Partial; diff --git a/src/migration/1710311804080-add_table_insignia.ts b/src/migration/1710311804080-add_table_insignia.ts new file mode 100644 index 00000000..06cb5256 --- /dev/null +++ b/src/migration/1710311804080-add_table_insignia.ts @@ -0,0 +1,18 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class AddTableInsignia1710311804080 implements MigrationInterface { + name = 'AddTableInsignia1710311804080' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE TABLE \`insignia\` (\`id\` varchar(36) NOT NULL, \`createdAt\` datetime(6) NOT NULL COMMENT 'สร้างข้อมูลเมื่อ' DEFAULT CURRENT_TIMESTAMP(6), \`createdUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่สร้างข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`lastUpdatedAt\` datetime(6) NOT NULL COMMENT 'แก้ไขข้อมูลล่าสุดเมื่อ' DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`lastUpdateUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่แก้ไขข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`createdFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่สร้างข้อมูล' DEFAULT 'string', \`lastUpdateFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่แก้ไขข้อมูลล่าสุด' DEFAULT 'string', \`name\` varchar(255) NULL COMMENT 'ชื่อเครื่องราช', \`shortName\` varchar(255) NULL COMMENT 'ชื่อย่อเครื่องราช', \`level\` int NULL COMMENT 'ลำดับชั้นของเครื่องราช เอาไว้ตรวจสอบเวลาขอว่าต้องได้ชั้นที่สูงกว่าที่เคยได้รับแล้วเท่านั้น', \`isActive\` tinyint NOT NULL COMMENT 'สถานะการใช้งาน' DEFAULT 0, \`note\` varchar(255) NULL COMMENT 'หมายเหตุ', \`insigniaTypeId\` varchar(40) NOT NULL COMMENT 'id ประเภทเครื่องราช', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`); + await queryRunner.query(`CREATE TABLE \`insigniaType\` (\`id\` varchar(36) NOT NULL, \`createdAt\` datetime(6) NOT NULL COMMENT 'สร้างข้อมูลเมื่อ' DEFAULT CURRENT_TIMESTAMP(6), \`createdUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่สร้างข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`lastUpdatedAt\` datetime(6) NOT NULL COMMENT 'แก้ไขข้อมูลล่าสุดเมื่อ' DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`lastUpdateUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่แก้ไขข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`createdFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่สร้างข้อมูล' DEFAULT 'string', \`lastUpdateFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่แก้ไขข้อมูลล่าสุด' DEFAULT 'string', \`name\` varchar(255) NULL COMMENT 'ชื่อประเภทเครื่องราช', \`isActive\` tinyint NOT NULL COMMENT 'สถานะการใช้งาน' DEFAULT 0, PRIMARY KEY (\`id\`)) ENGINE=InnoDB`); + await queryRunner.query(`ALTER TABLE \`insignia\` ADD CONSTRAINT \`FK_bf8cd951a7eb12a0eff9b17f82d\` FOREIGN KEY (\`insigniaTypeId\`) REFERENCES \`insigniaType\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`insignia\` DROP FOREIGN KEY \`FK_bf8cd951a7eb12a0eff9b17f82d\``); + await queryRunner.query(`DROP TABLE \`insigniaType\``); + await queryRunner.query(`DROP TABLE \`insignia\``); + } + +} From 7f77a80cd548a97de1b339e0928921278dddbece Mon Sep 17 00:00:00 2001 From: Bright Date: Wed, 13 Mar 2024 15:30:39 +0700 Subject: [PATCH 2/2] =?UTF-8?q?api=20=E0=B9=80=E0=B8=84=E0=B8=A3=E0=B8=B7?= =?UTF-8?q?=E0=B9=88=E0=B8=AD=E0=B8=87=E0=B8=A3=E0=B8=B2=E0=B8=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/InsigniaController.ts | 200 ++++++++++++++++++++++ src/controllers/InsigniaTypeController.ts | 171 ++++++++++++++++++ tsoa.json | 6 + 3 files changed, 377 insertions(+) create mode 100644 src/controllers/InsigniaController.ts create mode 100644 src/controllers/InsigniaTypeController.ts diff --git a/src/controllers/InsigniaController.ts b/src/controllers/InsigniaController.ts new file mode 100644 index 00000000..8e3a49db --- /dev/null +++ b/src/controllers/InsigniaController.ts @@ -0,0 +1,200 @@ +import { + Controller, + Get, + Post, + Put, + Delete, + Patch, + Route, + Security, + Tags, + Body, + Path, + Request, + Example, + SuccessResponse, + Response, + 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 { Equal, ILike, In, IsNull, Like, Not, Brackets, Between } from "typeorm"; +import { InsigniaType, CreateInsigniaType, UpdateInsigniaType } from "../entities/InsigniaType"; +import { Insignia, CreateInsignias, UpdateInsignias } from "../entities/Insignia"; + +@Route("api/v1/org/insignia/Insignias") +@Tags("Insignia") +@Security("bearerAuth") +@Response( + HttpStatusCode.INTERNAL_SERVER_ERROR, + "เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง", +) +@SuccessResponse(HttpStatusCode.OK, "สำเร็จ") +export class InsigniaController extends Controller { + + private insigniaTypeRepository = AppDataSource.getRepository(InsigniaType); + private insigniaRepository = AppDataSource.getRepository(Insignia); + + /** + * API เพิ่มข้อมูลเครื่องราชอิสริยาภรณ์ + * + * @summary ORG_ - เพิ่มข้อมูลเครื่องราชอิสริยาภรณ์ (ADMIN) # + * + */ + @Post("") + async CreateInsignia( + @Body() requestBody: CreateInsignias, + @Request() request: { user: Record }, + ) { + + const insignia = Object.assign(new Insignia(), requestBody); + if (!insignia) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล"); + } + const insigniaType = await this.insigniaTypeRepository.findOne({ + where: { id: requestBody.insigniaTypeId}, + }); + if (!insigniaType) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลลำดับชั้นเครื่องราชอิสริยาภรณ์นี้"); + } + const rowRepeated = await this.insigniaRepository.findOne({ + where: { + name: requestBody.name, + isActive: requestBody.isActive, + }, + }); + if (rowRepeated) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ข้อมูล Row นี้มีอยู่ในระบบแล้ว"); + } + + insignia.createdUserId = request.user.sub; + insignia.createdFullName = request.user.name; + insignia.lastUpdateUserId = request.user.sub; + insignia.lastUpdateFullName = request.user.name; + await this.insigniaRepository.save(insignia); + return new HttpSuccess(insignia.id); + } + + /** + * API แก้ไขเครื่องราชอิสริยาภรณ์ + * + * @summary แก้ไขเครื่องราชอิสริยาภรณ์ (ADMIN) + * + * @param {string} id Id เครื่องราชอิสริยาภรณ์ + */ + @Put("{id}") + async UpdateInsignia( + @Path() id: string, + @Body() requestBody: UpdateInsignias, + @Request() request: { user: Record }, + ) { + const insignia = await this.insigniaRepository.findOne({ + where: { id: id }, + }); + if (!insignia) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลเครื่องราชอิสริยาภรณ์นี้"); + } + const insigniaType = await this.insigniaTypeRepository.findOne({ + where: { id: requestBody.insigniaTypeId}, + }); + if (!insigniaType) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลลำดับชั้นเครื่องราชอิสริยาภรณ์นี้"); + } + const rowRepeated = await this.insigniaRepository.findOne({ + where: { + id: Not(id), + name: requestBody.name, + isActive: requestBody.isActive, + }, + }); + if (rowRepeated) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ข้อมูล Row นี้มีอยู่ในระบบแล้ว"); + } + + insignia.lastUpdateUserId = request.user.sub; + insignia.lastUpdateFullName = request.user.name; + this.insigniaRepository.merge(insignia, requestBody); + await this.insigniaRepository.save(insignia); + return new HttpSuccess(insignia.id); + } + + /** + * API ลบเครื่องราชอิสริยาภรณ์ + * + * @summary ORG_ - ลบเครื่องราชอิสริยาภรณ์ (ADMIN) # + * + * @param {string} id Id เครื่องราชอิสริยาภรณ์ + */ + @Delete("{id}") + async delete(@Path() id: string) { + const delInsignia = await this.insigniaRepository.findOne({ where: { id } }); + if (!delInsignia) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลเครื่องราชอิสริยาภรณ์นี้"); + } + await this.insigniaRepository.remove(delInsignia); + return new HttpSuccess(); + } + + /** + * API รายละเอียดเครื่องราชอิสริยาภรณ์ + * + * @summary ORG_037 - รายละเอียดเครื่องราชอิสริยาภรณ์ (ADMIN) # + * + * @param {string} id Id เครื่องราชอิสริยาภรณ์ + */ + @Get("{id}") + async GetInsigniaById(@Path() id: string) { + const insignia = await this.insigniaRepository.findOne({ + relations: ["insigniaType"], + select: ["id", "name", "shortName", "createdAt", "lastUpdatedAt", "lastUpdateFullName", "isActive", "note"], + where: { id: id }, + }); + if (!insignia) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลเครื่องราชอิสริยาภรณ์นี้"); + } + const mapInsignia = { + id: insignia.id, + name: insignia.name, + shortName: insignia.shortName, + insigniaTypeName: insignia.insigniaType == null ? null : insignia.insigniaType.name, //ลำดับชั้นเครื่องราช + createdAt: insignia.createdAt, + lastUpdatedAt: insignia.lastUpdatedAt, + lastUpdateFullName: insignia.lastUpdateFullName, + isActive: insignia.isActive, + note: insignia.note + } + return new HttpSuccess(mapInsignia); + } + + /** + * API รายการเครื่องราชอิสริยาภรณ์ + * + * @summary ORG_ - รายการเครื่องราชอิสริยาภรณ์ (ADMIN) # + * + */ + @Get("") + async GetInsignia() { + + const insigniaAll = await this.insigniaRepository.find({ + relations: ["insigniaType"], + select: ["id", "name", "shortName", "createdAt", "lastUpdatedAt", "lastUpdateFullName", "isActive", "note"], + }); + if (!insigniaAll) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลเครื่องราชอิสริยาภรณ์นี้"); + } + const mapInsigniaAll = insigniaAll.map((item) => ({ + id: item.id, + name: item.name, + shortName: item.shortName, + insigniaTypeName: item.insigniaType == null ? null : item.insigniaType.name, //ลำดับชั้นเครื่องราช + createdAt: item.createdAt, + lastUpdatedAt: item.lastUpdatedAt, + lastUpdateFullName: item.lastUpdateFullName, + isActive: item.isActive, + note: item.note + })); + return new HttpSuccess(mapInsigniaAll); + } +} diff --git a/src/controllers/InsigniaTypeController.ts b/src/controllers/InsigniaTypeController.ts new file mode 100644 index 00000000..cfd8ec86 --- /dev/null +++ b/src/controllers/InsigniaTypeController.ts @@ -0,0 +1,171 @@ +import { + Controller, + Get, + Post, + Put, + Delete, + Patch, + Route, + Security, + Tags, + Body, + Path, + Request, + Example, + SuccessResponse, + Response, + 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 { Equal, ILike, In, IsNull, Like, Not, Brackets, Between } from "typeorm"; +import { InsigniaType, CreateInsigniaType, UpdateInsigniaType } from "../entities/InsigniaType"; +import { Insignia, } from "../entities/Insignia"; + +@Route("api/v1/org/insignia/insignia-type") +@Tags("InsigniaType") +@Security("bearerAuth") +@Response( + HttpStatusCode.INTERNAL_SERVER_ERROR, + "เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง", +) +@SuccessResponse(HttpStatusCode.OK, "สำเร็จ") +export class InsigniaTypeController extends Controller { + + private insigniaTypeRepository = AppDataSource.getRepository(InsigniaType); + private insigniaRepository = AppDataSource.getRepository(Insignia); + + /** + * API เพิ่มข้อมูลลำดับชั้นเครื่องราชอิสริยาภรณ์ + * + * @summary ORG_ - เพิ่มข้อมูลลำดับชั้นเครื่องราชอิสริยาภรณ์ (ADMIN) # + * + */ + @Post("") + async CreateInsigniaType( + @Body() requestBody: CreateInsigniaType, + @Request() request: { user: Record }, + ) { + + const insigniaType = Object.assign(new InsigniaType(), requestBody); + if (!insigniaType) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล"); + } + + const rowRepeated = await this.insigniaTypeRepository.findOne({ + where: { + name: requestBody.name, + isActive: requestBody.isActive, + }, + }); + if (rowRepeated) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ข้อมูล Row นี้มีอยู่ในระบบแล้ว"); + } + + insigniaType.createdUserId = request.user.sub; + insigniaType.createdFullName = request.user.name; + insigniaType.lastUpdateUserId = request.user.sub; + insigniaType.lastUpdateFullName = request.user.name; + await this.insigniaTypeRepository.save(insigniaType); + return new HttpSuccess(insigniaType.id); + } + + /** + * API แก้ไขลำดับชั้นเครื่องราชอิสริยาภรณ์ + * + * @summary แก้ไขลำดับชั้นเครื่องราชอิสริยาภรณ์ (ADMIN) + * + * @param {string} id Id ลำดับชั้นเครื่องราชอิสริยาภรณ์ + */ + @Put("{id}") + async UpdateInsigniaType( + @Path() id: string, + @Body() requestBody: UpdateInsigniaType, + @Request() request: { user: Record }, + ) { + const insigniaType = await this.insigniaTypeRepository.findOne({ + where: { id: id }, + }); + if (!insigniaType) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลลำดับชั้นเครื่องราชอิสริยาภรณ์นี้"); + } + const rowRepeated = await this.insigniaTypeRepository.findOne({ + where: { + id: Not(id), + name: requestBody.name, + isActive: requestBody.isActive, + }, + }); + if (rowRepeated) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ข้อมูล Row นี้มีอยู่ในระบบแล้ว"); + } + + insigniaType.lastUpdateUserId = request.user.sub; + insigniaType.lastUpdateFullName = request.user.name; + this.insigniaTypeRepository.merge(insigniaType, requestBody); + await this.insigniaTypeRepository.save(insigniaType); + return new HttpSuccess(insigniaType.id); + } + + /** + * API ลบลำดับชั้นเครื่องราชอิสริยาภรณ์ + * + * @summary ORG_ - ลบลำดับชั้นเครื่องราชอิสริยาภรณ์ (ADMIN) # + * + * @param {string} id Id ลำดับชั้นเครื่องราชอิสริยาภรณ์ + */ + @Delete("{id}") + async delete(@Path() id: string) { + const delInsigniaType = await this.insigniaTypeRepository.findOne({ where: { id } }); + if (!delInsigniaType) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลลำดับชั้นเครื่องราชอิสริยาภรณ์นี้"); + } + const Insignia = await this.insigniaRepository.find({ + where: { insigniaTypeId: id } + }); + if (Insignia.length > 0) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่สามารถลบได้ เนื่องจากพบข้อมูลที่ตารางเครื่องราชอิสริยาภรณ์"); + } + await this.insigniaTypeRepository.remove(delInsigniaType); + return new HttpSuccess(); + } + + /** + * API รายละเอียดข้อมูลลำดับชั้นเครื่องราชอิสริยาภรณ์ + * + * @summary ORG_037 - รายละเอียดข้อมูลลำดับชั้นเครื่องราชอิสริยาภรณ์ (ADMIN) # + * + * @param {string} id Id ลำดับชั้นเครื่องราชอิสริยาภรณ์ + */ + @Get("{id}") + async GetInsigniaTypeById(@Path() id: string) { + const insigniaType = await this.insigniaTypeRepository.findOne({ + select: ["id", "name", "createdAt", "lastUpdatedAt", "lastUpdateFullName", "isActive"], + where: { id: id }, + }); + if (!insigniaType) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลลำดับชั้นเครื่องราชอิสริยาภรณ์ นี้"); + } + return new HttpSuccess(insigniaType); + } + + /** + * API รายการลำดับชั้นเครื่องราชอิสริยาภรณ์ + * + * @summary ORG_ - รายการลำดับชั้นเครื่องราชอิสริยาภรณ์ (ADMIN) # + * + */ + @Get("") + async GetInsigniaType() { + + const insigniaTypeAll = await this.insigniaTypeRepository.find({ + select: ["id", "name", "createdAt", "lastUpdatedAt", "lastUpdateFullName", "isActive"] + }); + if (!insigniaTypeAll) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลลำดับชั้นเครื่องราชอิสริยาภรณ์ นี้"); + } + return new HttpSuccess(insigniaTypeAll); + } +} diff --git a/tsoa.json b/tsoa.json index f83c7074..a34af6cb 100644 --- a/tsoa.json +++ b/tsoa.json @@ -88,6 +88,12 @@ }, { "name": "EmployeePosLevel", "description": "ระดับชั้นงานลูกจ้างประจำ" + }, + { + "name": "InsigniaType", "description": "ลำดับชั้นเครื่องราชอิสริยาภรณ์" + }, + { + "name": "Insignia", "description": "เครื่องราชอิสริยาภรณ์" } ] },