diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 0d07ac5e..c4b02bcc 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -1,5 +1,5 @@ -name: release-test -run-name: release-test ${{ github.actor }} +name: release +run-name: release ${{ github.actor }} on: push: tags: @@ -9,11 +9,11 @@ env: REGISTRY: docker.frappet.com IMAGE_NAME: ehr/bma-ehr-org-service DEPLOY_HOST: frappet.com - # COMPOSE_PATH: /home/frappet/docker/bma-ehr COMPOSE_PATH: /home/frappet/docker/bma/bma-ehr-org + jobs: # act workflow_dispatch -W .github/workflows/release.yaml --input IMAGE_VER=latest -s DOCKER_USER=admin -s DOCKER_PASS=FPTadmin2357 -s SSH_PASSWORD=FPTadmin2357 - release-test: + release: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -52,6 +52,7 @@ jobs: with: context: . platforms: linux/amd64 + file: docker/Dockerfile push: true tags: ${{env.REGISTRY}}/${{env.IMAGE_NAME}}:${{ steps.gen_ver.outputs.image_ver }},${{env.REGISTRY}}/${{env.IMAGE_NAME}}:latest - name: Remote Deployment @@ -66,21 +67,40 @@ jobs: docker compose pull docker compose up -d echo "${{ steps.gen_ver.outputs.image_ver }}"> success - - uses: snow-actions/line-notify@v1.1.0 + - name: Notify Discord Success if: success() - with: - access_token: ${{ secrets.TOKEN_LINE }} - message: | - -Success✅✅✅ - Image: ${{env.IMAGE_NAME}} - Version: ${{ steps.gen_ver.outputs.IMAGE_VER }} - By: ${{github.actor}} - - uses: snow-actions/line-notify@v1.1.0 + run: | + curl -H "Content-Type: application/json" \ + -X POST \ + -d '{ + "embeds": [{ + "title": "✅ Deployment Success!", + "description": "**Details:**\n- Image: `${{env.IMAGE_NAME}}`\n- Version: `${{ steps.gen_ver.outputs.image_ver }}`\n- Deployed by: `${{github.actor}}`", + "color": 3066993, + "footer": { + "text": "Release Notification", + "icon_url": "https://example.com/success-icon.png" + }, + "timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'" + }] + }' \ + ${{ secrets.DISCORD_WEBHOOK }} + + - name: Notify Discord Failure if: failure() - with: - access_token: ${{ secrets.TOKEN_LINE }} - message: | - -Failure❌❌❌ - Image: ${{env.IMAGE_NAME}} - Version: ${{ steps.gen_ver.outputs.IMAGE_VER }} - By: ${{github.actor}} + run: | + curl -H "Content-Type: application/json" \ + -X POST \ + -d '{ + "embeds": [{ + "title": "❌ Deployment Failed!", + "description": "**Details:**\n- Image: `${{env.IMAGE_NAME}}`\n- Version: `${{ steps.gen_ver.outputs.image_ver }}`\n- Attempted by: `${{github.actor}}`", + "color": 15158332, + "footer": { + "text": "Release Notification", + "icon_url": "https://example.com/failure-icon.png" + }, + "timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'" + }] + }' \ + ${{ secrets.DISCORD_WEBHOOK }} diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 4ca0f482..00000000 --- a/Dockerfile +++ /dev/null @@ -1,35 +0,0 @@ -FROM node:18-alpine as builder - -# Create app directory -WORKDIR /app - -# Install app dependencies -COPY package*.json ./ - -RUN npm ci - -COPY . . - -RUN npm run build - -FROM node:18-alpine - -ENV NODE_ENV production -USER node - -# Create app directory -WORKDIR /app - -# Install app dependencies -COPY package*.json ./ -# COPY .env ./ - -RUN npm ci --production - -COPY --from=builder /app/dist ./dist - -# COPY entrypoint.sh /usr/local/bin/entrypoint.sh -# RUN chmod u+x /usr/local/bin/entrypoint.sh - -# ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] -CMD [ "node", "dist/app.js" ] \ No newline at end of file diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 00000000..07492be8 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,34 @@ +# Build Stage +FROM node:lts-alpine AS build-stage + +# Create app directory +WORKDIR /app + +# Install app dependencies +COPY package*.json ./ + +RUN npm ci + +# Copy source files and build the app +COPY . . +RUN npm run build + +# Production Stage +FROM node:lts-alpine + +ENV NODE_ENV production +USER node + +# Create app directory +WORKDIR /app + +# Copy built app from build stage +COPY --from=build-stage /app/dist ./dist + +# Install only production dependencies +COPY package*.json ./ +RUN npm ci --production + +# Define the entrypoint and default command +# If you have a custom entrypoint script +CMD [ "node", "dist/app.js" ] diff --git a/src/controllers/ApiKeyController.ts b/src/controllers/ApiKeyController.ts index 5dd2dbd1..ce9e312d 100644 --- a/src/controllers/ApiKeyController.ts +++ b/src/controllers/ApiKeyController.ts @@ -128,4 +128,56 @@ export class ApiKeyController extends Controller { }); return new HttpSuccess(apiName); } + + /** + * API สร้าง Api Key + * + * @summary สร้าง Api Key (ADMIN) + * + */ + @Post("history") + async getHistory( + @Body() + requestBody: { + startDate: Date; + endDate: Date; + apiNameId: string | null; + }, + @Request() request: RequestWithUser, + ) { + if (requestBody.apiNameId) { + const apiName = await this.apiNameRepository.findOne({ + where: { id: requestBody.apiNameId }, + }); + if (!apiName) + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบรายการ Web Service นี้ในระบบ"); + } + const apiHistory = await AppDataSource.getRepository(ApiHistory) + .createQueryBuilder("apiHistory") + .leftJoinAndSelect("apiHistory.apiKey", "apiKey") + .leftJoinAndSelect("apiHistory.apiName", "apiName") + .andWhere(requestBody.apiNameId ? `apiHistory.apiNameId = :apiNameId` : "1=1", { + apiNameId: requestBody.apiNameId, + }) + .andWhere( + `apiHistory.createdAt >= DATE(:startDate) AND apiHistory.createdAt <= DATE(:endDate)`, + { + startDate: new Date(requestBody.startDate), + endDate: new Date( + requestBody.endDate.setDate(new Date(requestBody.endDate).getDate() + 1), + ), + }, + ) + .orderBy("apiHistory.createdAt", "DESC") + .getMany(); + const result = apiHistory.map((x) => ({ + id: x.id, + apiName: x.apiName.name, + apiKey: x.apiKey.name, + createdAt: x.createdAt, + ipApi: x.ipApi, + })); + + return new HttpSuccess(result); + } } diff --git a/src/controllers/CommandController.ts b/src/controllers/CommandController.ts index 4454e041..c5796f00 100644 --- a/src/controllers/CommandController.ts +++ b/src/controllers/CommandController.ts @@ -1615,19 +1615,23 @@ export class CommandController extends Controller { persons: { refId: string; profileId?: string | null; - citizenId: string | null; - prefix: string | null; - firstName: string | null; - lastName: string | null; + citizenId?: string | null; + prefix?: string | null; + firstName?: string | null; + lastName?: string | null; remarkVertical?: string | null; remarkHorizontal?: string | null; rootId?: string | null; + amount?: Double | null; + amountSpecial?: Double | null; + positionSalaryAmount?: Double | null; + mouthSalaryAmount?: Double | null; }[]; }, @Request() request: RequestWithUser, ) { let command = new Command(); - let commandCode = null; + let commandCode:string = ""; let null_: any = null; if ( requestBody.commandId != undefined && @@ -1707,30 +1711,40 @@ export class CommandController extends Controller { commandRecive = Object.assign(new CommandRecive(), item); commandRecive.order = order; let salaryData = null_; - if (item.profileId) { - salaryData = await this.profileRepository.findOne({ - where: { - id: item.profileId, - }, - }); - let null_: any = 0; - if (!salaryData) { - salaryData = await this.profileEmployeeRepository.findOne({ + + const excludedCommands = ["C-PM-33", "C-PM-34", "C-PM-35", "C-PM-36", "C-PM-37"]; + if (!excludedCommands.includes(commandCode)) { + if (item.profileId) { + salaryData = await this.profileRepository.findOne({ where: { id: item.profileId, }, }); + let null_: any = 0; + if (!salaryData) { + salaryData = await this.profileEmployeeRepository.findOne({ + where: { + id: item.profileId, + }, + }); + } + commandRecive.amount = salaryData ? salaryData.amount : null_; + commandRecive.positionSalaryAmount = salaryData + ? salaryData.positionSalaryAmount + : null_; + commandRecive.mouthSalaryAmount = salaryData ? salaryData.mouthSalaryAmount : null_; + } else { + commandRecive.amount = null_; + commandRecive.positionSalaryAmount = null_; + commandRecive.mouthSalaryAmount = null_; } - commandRecive.amount = salaryData ? salaryData.amount : null_; - commandRecive.positionSalaryAmount = salaryData - ? salaryData.positionSalaryAmount - : null_; - commandRecive.mouthSalaryAmount = salaryData ? salaryData.mouthSalaryAmount : null_; } else { - commandRecive.amount = null_; - commandRecive.positionSalaryAmount = null_; - commandRecive.mouthSalaryAmount = null_; + commandRecive.amount = item.amount ?? null_; + commandRecive.amountSpecial = item.amountSpecial ?? null_; + commandRecive.positionSalaryAmount = item.positionSalaryAmount ?? null_; + commandRecive.mouthSalaryAmount = item.mouthSalaryAmount ?? null_; } + commandRecive.remarkVertical = item.remarkVertical == null ? null_ : item.remarkVertical; commandRecive.remarkHorizontal = @@ -1898,6 +1912,7 @@ export class CommandController extends Controller { profileId: string; date?: Date | null; amount?: Double | null; + amountSpecial?: Double | null; positionSalaryAmount?: Double | null; mouthSalaryAmount?: Double | null; posNo: string | null; @@ -1917,7 +1932,7 @@ export class CommandController extends Controller { ) { await Promise.all( body.data.map(async (item) => { - const profile = await this.profileRepository.findOneBy({ id: item.profileId }); + const profile:any = await this.profileRepository.findOneBy({ id: item.profileId }); if (!profile) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลทะเบียนประวัตินี้"); } @@ -2002,6 +2017,8 @@ export class CommandController extends Controller { profile.posLevelId = positionNew.posLevelId; profile.posTypeId = positionNew.posTypeId; profile.position = positionNew.positionName; + profile.amount = item.amount ?? null; + profile.amountSpecial = item.amountSpecial ?? null; await this.profileRepository.save(profile); await this.positionRepository.save(positionNew); } @@ -2020,6 +2037,7 @@ export class CommandController extends Controller { profileId: string; date?: Date | null; amount?: Double | null; + amountSpecial?: Double | null; positionSalaryAmount?: Double | null; mouthSalaryAmount?: Double | null; posNo: string | null; @@ -2036,7 +2054,7 @@ export class CommandController extends Controller { ) { await Promise.all( body.data.map(async (item) => { - const profile = await this.profileEmployeeRepository.findOneBy({ id: item.profileId }); + const profile:any = await this.profileEmployeeRepository.findOneBy({ id: item.profileId }); if (!profile) { throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); } @@ -2131,7 +2149,8 @@ export class CommandController extends Controller { profile.position = positionNew.positionName; profile.employeeOc = posMaster?.orgRoot?.orgRootName ?? null; profile.positionEmployeePositionId = positionNew.positionName; - + profile.amount = item.amount ?? null; + profile.amountSpecial = item.amountSpecial ?? null; await this.profileEmployeeRepository.save(profile); await this.employeePositionRepository.save(positionNew); } @@ -2150,6 +2169,7 @@ export class CommandController extends Controller { profileId: string; date?: Date | null; amount?: Double | null; + amountSpecial?: Double | null; positionSalaryAmount?: Double | null; mouthSalaryAmount?: Double | null; posNo: string | null; @@ -2215,7 +2235,6 @@ export class CommandController extends Controller { profile.lastUpdateUserId = req.user.sub; profile.lastUpdateFullName = req.user.name; profile.lastUpdatedAt = new Date(); - // profile.dateStart = new Date(); if (item.isLeave == true) { await removeProfileInOrganize(profile.id, "OFFICER"); } @@ -2236,21 +2255,28 @@ export class CommandController extends Controller { const returnWork = await checkReturnCommandType(String(item.commandId)); //คำสั่งบรรจุกลับเข้ารับราชการ หรือ ผู้ออกไปรับราชการทหารกลับเข้ารับราชการ solutionเดิม ให้ enable user เปลี่ยนเป็นสร้าง user ใหม่เลยเพราะยังไงตอนถูกพักก็ถูกลบ user if (returnWork && item.isGovernment) { - /*if (profile.keycloak != null) { - const enableActive = await enableStatus(profile.keycloak, true); - if (!enableActive) throw new Error("Failed. Cannot change enable status."); - } else {*/ - const userKeycloakId = await createUser(profile.citizenId, profile.citizenId, { - firstName: profile.firstName, - lastName: profile.lastName, - }); - // if (typeof userKeycloakId !== "string") { - // throw new Error(userKeycloakId.errorMessage); - // } - const list = await getRoles(); - if (!Array.isArray(list)) - throw new Error("Failed. Cannot get role(s) data from the server."); - const result = await addUserRoles( + let userKeycloakId; + userKeycloakId = await createUser(profile.citizenId, profile.citizenId, { + firstName: profile.firstName, + lastName: profile.lastName, + }); + // กรณี Keycloak ไม่ถูกลบ ให้ลบซ้ำอีกรอบแล้วสร้างใหม่ และหากยังไม่สามารถลบได้ให้แสดง Error + if (profile.keycloak != null && userKeycloakId && userKeycloakId.errorMessage === "User exists with same username") { + const delUserKeycloak = await deleteUser(profile.keycloak); + if(delUserKeycloak) { + userKeycloakId = await createUser(profile.citizenId, profile.citizenId, { + firstName: profile.firstName, + lastName: profile.lastName, + }); + } + else { + throw new HttpError(HttpStatus.BAD_REQUEST, "พบข้อผิดพลาด ไม่สามารถจัดการผู้ใช้งานได้"); + } + } + const list = await getRoles(); + let result = false; + if (Array.isArray(list) && userKeycloakId) { + result = await addUserRoles( userKeycloakId, list .filter((v) => v.name === "USER") @@ -2259,10 +2285,11 @@ export class CommandController extends Controller { name: x.name, })), ); - // if (!result) throw new Error("Failed. Cannot set user's role."); - profile.keycloak = typeof userKeycloakId === "string" ? userKeycloakId : ""; - /*}*/ + } + profile.amount = item.amount ?? _null; + profile.amountSpecial = item.amountSpecial ?? _null; profile.isActive = true; + profile.keycloak = typeof userKeycloakId === "string" ? userKeycloakId : ""; profile.roleKeycloaks = result && roleKeycloak ? [roleKeycloak] : []; } await this.profileRepository.save(profile); @@ -2378,6 +2405,7 @@ export class CommandController extends Controller { profileId: string; date?: Date | null; amount?: Double | null; + amountSpecial?: Double | null; positionSalaryAmount?: Double | null; mouthSalaryAmount?: Double | null; posNo: string | null; @@ -2398,7 +2426,7 @@ export class CommandController extends Controller { ) { await Promise.all( body.data.map(async (item) => { - const profile = await this.profileRepository.findOne({ + const profile:any = await this.profileRepository.findOne({ where: { id: item.profileId }, relations: ["roleKeycloaks"], }); @@ -2441,6 +2469,8 @@ export class CommandController extends Controller { profile.posLevelId = _null; profile.leaveReason = item.leaveReason ?? _null; profile.dateLeave = item.dateLeave ?? _null; + profile.amount = item.amount ?? _null; + profile.amountSpecial = item.amountSpecial ?? _null; await this.profileRepository.save(profile, { data: req }); } Object.assign(data, { ...item, ...meta }); @@ -3082,6 +3112,8 @@ export class CommandController extends Controller { profile.roleKeycloaks = result && roleKeycloak ? [roleKeycloak] : []; profile.email = item.bodyProfile.email; profile.dateStart = item.bodyProfile.dateStart; + profile.amount = item.bodyProfile.amount ?? null; + profile.amountSpecial = item.bodyProfile.amountSpecial ?? null; await this.profileRepository.save(profile); setLogDataDiff(req, { before, after: profile }); } @@ -3125,13 +3157,17 @@ export class CommandController extends Controller { where: { profileId: profile.id }, order: { order: "DESC" }, }); - const profileSal = new ProfileSalary(); + const profileSal: any = new ProfileSalary(); Object.assign(profileSal, { ...item.bodySalarys, ...meta }); const salaryHistory = new ProfileSalaryHistory(); Object.assign(salaryHistory, { ...profileSal, id: undefined }); profileSal.order = dest_item == null ? 1 : dest_item.order + 1; profileSal.profileId = profile.id; profileSal.dateGovernment = meta.createdAt; + profileSal.amount = item.bodySalarys.amount ?? null; + profileSal.amountSpecial = item.bodySalarys.amountSpecial ?? null; + profileSal.positionSalaryAmount = item.bodySalarys.positionSalaryAmount ?? null; + profileSal.mouthSalaryAmount = item.bodySalarys.mouthSalaryAmount ?? null; await this.salaryRepo.save(profileSal, { data: req }); setLogDataDiff(req, { before, after: profileSal }); salaryHistory.profileSalaryId = profileSal.id; @@ -3279,6 +3315,7 @@ export class CommandController extends Controller { commandYear: number; templateDoc: string | null; amount: Double | null; + amountSpecial: Double | null; positionSalaryAmount: Double | null; mouthSalaryAmount: Double | null; }[]; @@ -3308,6 +3345,7 @@ export class CommandController extends Controller { profileEmployeeId: profile.id, date: new Date(), amount: item.amount, + amountSpecial: item.amountSpecial, commandId: item.commandId, positionSalaryAmount: item.positionSalaryAmount, mouthSalaryAmount: item.mouthSalaryAmount, @@ -3426,9 +3464,8 @@ export class CommandController extends Controller { const _null: any = null; profile.employeeWage = item.amount == null ? _null : item.amount.toString(); profile.dateStart = new Date(); - // profile.amount = item.amount == null ? _null : item.amount.toString(); //เผื่อไว้ - // profile.positionSalaryAmount = item.positionSalaryAmount == null ? _null : item.positionSalaryAmount.toString(); - // profile.mouthSalaryAmount = item.mouthSalaryAmount == null ? _null : item.mouthSalaryAmount.toString(); + profile.amount = item.amount == null ? _null : item.amount; + profile.amountSpecial = item.amountSpecial == null ? _null : item.amountSpecial; await this.profileEmployeeRepository.save(profile); await this.employeePositionRepository.save(positionNew); diff --git a/src/controllers/OrganizationDotnetController.ts b/src/controllers/OrganizationDotnetController.ts index 090d7ad9..f0b051e1 100644 --- a/src/controllers/OrganizationDotnetController.ts +++ b/src/controllers/OrganizationDotnetController.ts @@ -199,7 +199,7 @@ export class OrganizationDotnetController extends Controller { dateStart: item.dateStart, govAgeAbsent: item.govAgeAbsent, govAgePlus: item.govAgePlus, - birthDate: item.birthDate, + birthDate: item.birthDate ?? new Date(), reasonSameDate: item.reasonSameDate, ethnicity: item.ethnicity, telephoneNumber: item.telephoneNumber, @@ -495,7 +495,7 @@ export class OrganizationDotnetController extends Controller { dateStart: profile.dateStart, govAgeAbsent: profile.govAgeAbsent, govAgePlus: profile.govAgePlus, - birthDate: profile.birthDate, + birthDate: profile.birthDate ?? new Date(), reasonSameDate: profile.reasonSameDate, telephoneNumber: profile.telephoneNumber, nationality: profile.nationality, @@ -732,7 +732,7 @@ export class OrganizationDotnetController extends Controller { dateStart: profile.dateStart, govAgeAbsent: profile.govAgeAbsent, govAgePlus: profile.govAgePlus, - birthDate: profile.birthDate, + birthDate: profile.birthDate ?? new Date(), reasonSameDate: profile.reasonSameDate, telephoneNumber: profile.telephoneNumber, nationality: profile.nationality, @@ -1028,7 +1028,7 @@ export class OrganizationDotnetController extends Controller { dateStart: profile.dateStart, govAgeAbsent: profile.govAgeAbsent, govAgePlus: profile.govAgePlus, - birthDate: profile.birthDate, + birthDate: profile.birthDate ?? new Date(), reasonSameDate: profile.reasonSameDate, telephoneNumber: profile.telephoneNumber, nationality: profile.nationality, @@ -1295,7 +1295,7 @@ export class OrganizationDotnetController extends Controller { dateStart: profile.dateStart, govAgeAbsent: profile.govAgeAbsent, govAgePlus: profile.govAgePlus, - birthDate: profile.birthDate, + birthDate: profile.birthDate ?? new Date(), reasonSameDate: profile.reasonSameDate, telephoneNumber: profile.telephoneNumber, nationality: profile.nationality, @@ -1621,7 +1621,7 @@ export class OrganizationDotnetController extends Controller { dateStart: profile.dateStart, govAgeAbsent: profile.govAgeAbsent, govAgePlus: profile.govAgePlus, - birthDate: profile.birthDate, + birthDate: profile.birthDate ?? new Date(), reasonSameDate: profile.reasonSameDate, telephoneNumber: profile.telephoneNumber, nationality: profile.nationality, @@ -1888,7 +1888,7 @@ export class OrganizationDotnetController extends Controller { dateStart: profile.dateStart, govAgeAbsent: profile.govAgeAbsent, govAgePlus: profile.govAgePlus, - birthDate: profile.birthDate, + birthDate: profile.birthDate ?? new Date(), reasonSameDate: profile.reasonSameDate, telephoneNumber: profile.telephoneNumber, nationality: profile.nationality, @@ -2072,7 +2072,7 @@ export class OrganizationDotnetController extends Controller { dateStart: profile.dateStart, govAgeAbsent: profile.govAgeAbsent, govAgePlus: profile.govAgePlus, - birthDate: profile.birthDate, + birthDate: profile.birthDate ?? new Date(), reasonSameDate: profile.reasonSameDate, telephoneNumber: profile.telephoneNumber, nationality: profile.nationality, @@ -2209,7 +2209,7 @@ export class OrganizationDotnetController extends Controller { dateStart: profile.dateStart, govAgeAbsent: profile.govAgeAbsent, govAgePlus: profile.govAgePlus, - birthDate: profile.birthDate, + birthDate: profile.birthDate ?? new Date(), reasonSameDate: profile.reasonSameDate, telephoneNumber: profile.telephoneNumber, nationality: profile.nationality, @@ -2316,7 +2316,7 @@ export class OrganizationDotnetController extends Controller { firstName: profile.firstName, lastName: profile.lastName, citizenId: profile.citizenId, - birthDate: profile.birthDate, + birthDate: profile.birthDate ?? new Date(), position: profile.position, rootId: root == null ? null : root.id, root: root == null ? null : root.orgRootName, @@ -2417,7 +2417,7 @@ export class OrganizationDotnetController extends Controller { firstName: profile.firstName, lastName: profile.lastName, citizenId: profile.citizenId, - birthDate: profile.birthDate, + birthDate: profile.birthDate ?? new Date(), position: profile.position, posMaster: posMaster == null ? null : posMaster.posMasterNo, posMasterNo: posMaster == null ? null : posMaster.posMasterNo, @@ -2589,7 +2589,7 @@ export class OrganizationDotnetController extends Controller { dateStart: item.dateStart, govAgeAbsent: item.govAgeAbsent, govAgePlus: item.govAgePlus, - birthDate: item.birthDate, + birthDate: item.birthDate ?? new Date(), reasonSameDate: item.reasonSameDate, ethnicity: item.ethnicity, telephoneNumber: item.telephoneNumber, diff --git a/src/controllers/OrganizationUnauthorizeController.ts b/src/controllers/OrganizationUnauthorizeController.ts index 35b28e48..a637fdea 100644 --- a/src/controllers/OrganizationUnauthorizeController.ts +++ b/src/controllers/OrganizationUnauthorizeController.ts @@ -163,10 +163,11 @@ export class OrganizationUnauthorizeController extends Controller { : item.positions?.find((position) => position.positionIsSelected == true)?.posExecutive .posExecutiveName; - const amount = - item.current_holder == null || item.current_holder.profileSalary.length == 0 - ? null - : item.current_holder.profileSalary.sort((a: any, b: any) => b.date - a.date)[0].amount; + // const amount = + // item.current_holder == null || item.current_holder.profileSalary.length == 0 + // ? null + // : item.current_holder.profileSalary.sort((a: any, b: any) => b.date - a.date)[0].amount; + const amount = item.current_holder?item.current_holder.amount:null; let datePeriodStart = new Date( `${new Date().getFullYear()}-${String(new Date().getMonth() + 1).padStart(2, "0")}-${String(new Date().getDate() + 1).padStart(2, "0")}T00:00:00.000Z`, ); @@ -380,10 +381,11 @@ export class OrganizationUnauthorizeController extends Controller { orgShortName = item.orgChild4?.orgChild4ShortName; } - const amount = - item.current_holder == null || item.current_holder.profileSalary.length == 0 - ? null - : item.current_holder.profileSalary.sort((a: any, b: any) => b.date - a.date)[0].amount; + // const amount = + // item.current_holder == null || item.current_holder.profileSalary.length == 0 + // ? null + // : item.current_holder.profileSalary.sort((a: any, b: any) => b.date - a.date)[0].amount; + const amount = item.current_holder?item.current_holder.amount:null; let datePeriodStart = new Date( `${new Date().getFullYear()}-${String(new Date().getMonth() + 1).padStart(2, "0")}-${String(new Date().getDate() + 1).padStart(2, "0")}T00:00:00.000Z`, ); diff --git a/src/controllers/PermissionOrgController.ts b/src/controllers/PermissionOrgController.ts index a1fb62c5..a281dbc7 100644 --- a/src/controllers/PermissionOrgController.ts +++ b/src/controllers/PermissionOrgController.ts @@ -106,22 +106,15 @@ export class PermissionOrgController extends Controller { } else if (searchField == "position") { queryLike = "profile.position LIKE :keyword"; } else if (searchField == "posNo") { - queryLike = `CONCAT( - IFNULL(orgChild4.orgChild4ShortName, ''), - IFNULL(current_holders.posMasterNo , '') - ) LIKE :keyword OR CONCAT( - IFNULL(orgChild3.orgChild3ShortName, ''), - IFNULL(current_holders.posMasterNo , '') - ) LIKE :keyword OR CONCAT( - IFNULL(orgChild2.orgChild2ShortName, ''), - IFNULL(current_holders.posMasterNo , '') - ) LIKE :keyword OR CONCAT( - IFNULL(orgChild1.orgChild1ShortName, ''), - IFNULL(current_holders.posMasterNo , '') - ) LIKE :keyword OR CONCAT( - IFNULL(orgRoot.orgRootShortName, ''), - IFNULL(current_holders.posMasterNo , '') - ) LIKE :keyword`; + queryLike = ` + CASE + WHEN current_holders.orgChild4Id IS NOT NULL THEN CONCAT(orgChild4.orgChild4ShortName, current_holders.posMasterNo) + WHEN current_holders.orgChild3Id IS NOT NULL THEN CONCAT(orgChild3.orgChild3ShortName, current_holders.posMasterNo) + WHEN current_holders.orgChild2Id IS NOT NULL THEN CONCAT(orgChild2.orgChild2ShortName, current_holders.posMasterNo) + WHEN current_holders.orgChild1Id IS NOT NULL THEN CONCAT(orgChild1.orgChild1ShortName, current_holders.posMasterNo) + ELSE CONCAT(orgRoot.orgRootShortName, current_holders.posMasterNo) + END LIKE :keyword + `; } const findRevision = await this.orgRevisionRepository.findOne({ where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false }, diff --git a/src/controllers/ProfileController.ts b/src/controllers/ProfileController.ts index b720295a..527f7d06 100644 --- a/src/controllers/ProfileController.ts +++ b/src/controllers/ProfileController.ts @@ -3757,22 +3757,15 @@ export class ProfileController extends Controller { } else if (searchField == "position") { queryLike = "profile.position LIKE :keyword"; } else if (searchField == "posNo") { - queryLike = `CONCAT( - IFNULL(orgChild4.orgChild4ShortName, ''), - IFNULL(current_holders.posMasterNo , '') - ) LIKE :keyword OR CONCAT( - IFNULL(orgChild3.orgChild3ShortName, ''), - IFNULL(current_holders.posMasterNo , '') - ) LIKE :keyword OR CONCAT( - IFNULL(orgChild2.orgChild2ShortName, ''), - IFNULL(current_holders.posMasterNo , '') - ) LIKE :keyword OR CONCAT( - IFNULL(orgChild1.orgChild1ShortName, ''), - IFNULL(current_holders.posMasterNo , '') - ) LIKE :keyword OR CONCAT( - IFNULL(orgRoot.orgRootShortName, ''), - IFNULL(current_holders.posMasterNo , '') - ) LIKE :keyword`; + queryLike = ` + CASE + WHEN current_holders.orgChild4Id IS NOT NULL THEN CONCAT(orgChild4.orgChild4ShortName, current_holders.posMasterNo) + WHEN current_holders.orgChild3Id IS NOT NULL THEN CONCAT(orgChild3.orgChild3ShortName, current_holders.posMasterNo) + WHEN current_holders.orgChild2Id IS NOT NULL THEN CONCAT(orgChild2.orgChild2ShortName, current_holders.posMasterNo) + WHEN current_holders.orgChild1Id IS NOT NULL THEN CONCAT(orgChild1.orgChild1ShortName, current_holders.posMasterNo) + ELSE CONCAT(orgRoot.orgRootShortName, current_holders.posMasterNo) + END LIKE :keyword + `; } let nodeCondition = "1=1"; let nodeAll = ""; @@ -4116,22 +4109,15 @@ export class ProfileController extends Controller { } else if (searchField == "position") { queryLike = "profile.position LIKE :keyword"; } else if (searchField == "posNo") { - queryLike = `CONCAT( - IFNULL(orgChild4.orgChild4ShortName, ''), - IFNULL(current_holders.posMasterNo , '') - ) LIKE :keyword OR CONCAT( - IFNULL(orgChild3.orgChild3ShortName, ''), - IFNULL(current_holders.posMasterNo , '') - ) LIKE :keyword OR CONCAT( - IFNULL(orgChild2.orgChild2ShortName, ''), - IFNULL(current_holders.posMasterNo , '') - ) LIKE :keyword OR CONCAT( - IFNULL(orgChild1.orgChild1ShortName, ''), - IFNULL(current_holders.posMasterNo , '') - ) LIKE :keyword OR CONCAT( - IFNULL(orgRoot.orgRootShortName, ''), - IFNULL(current_holders.posMasterNo , '') - ) LIKE :keyword`; + queryLike = ` + CASE + WHEN current_holders.orgChild4Id IS NOT NULL THEN CONCAT(orgChild4.orgChild4ShortName, current_holders.posMasterNo) + WHEN current_holders.orgChild3Id IS NOT NULL THEN CONCAT(orgChild3.orgChild3ShortName, current_holders.posMasterNo) + WHEN current_holders.orgChild2Id IS NOT NULL THEN CONCAT(orgChild2.orgChild2ShortName, current_holders.posMasterNo) + WHEN current_holders.orgChild1Id IS NOT NULL THEN CONCAT(orgChild1.orgChild1ShortName, current_holders.posMasterNo) + ELSE CONCAT(orgRoot.orgRootShortName, current_holders.posMasterNo) + END LIKE :keyword + `; } let nodeCondition = "1=1"; let nodeAll = ""; @@ -4249,20 +4235,22 @@ export class ProfileController extends Controller { : `profile.dateLeave IS NOT NULL` : "1=1", ) - .andWhere( - searchKeyword != undefined && searchKeyword != null && searchKeyword != "" - ? queryLike - : "1=1", - { - keyword: `%${searchKeyword}%`, - }, - ) .andWhere(nodeCondition, { - nodeId: nodeId, + nodeId: nodeId, }) - // .andWhere(`current_holders.orgRevisionId LIKE :orgRevisionId`, { - // orgRevisionId: findRevision.id, - // }) + + .andWhere( + new Brackets((qb) => { + qb.orWhere( + searchKeyword != undefined && searchKeyword != null && searchKeyword != "" + ? queryLike + : "1=1", + { + keyword: `%${searchKeyword}%`, + }, + ) + }) + ) .orderBy("current_holders.posMasterNo", "ASC") .skip((page - 1) * pageSize) .take(pageSize) @@ -6039,7 +6027,12 @@ export class ProfileController extends Controller { switch (body.fieldName) { case "citizenId": [findProfile, total] = await this.profileRepo.findAndCount({ - where: { citizenId: Like(`%${body.keyword}%`) }, + where: { + citizenId: Like(`%${body.keyword}%`), + current_holders:{ + orgRevisionId:revision?.id + } + }, relations: [ "posType", "posLevel", @@ -6066,7 +6059,8 @@ export class ProfileController extends Controller { .leftJoinAndSelect("current_holders.orgChild2", "orgChild2") .leftJoinAndSelect("current_holders.orgChild3", "orgChild3") .leftJoinAndSelect("current_holders.orgChild4", "orgChild4") - .where("CONCAT(profile.prefix, profile.firstName, ' ', profile.lastName) LIKE :keyword", { keyword: `%${body.keyword}%` }) + .where("current_holders.orgRevision = :revisionId", { revisionId: revision?.id }) + .andWhere("CONCAT(profile.prefix, profile.firstName, ' ', profile.lastName) LIKE :keyword", { keyword: `%${body.keyword}%` }) .skip(skip) .take(take) .getManyAndCount(); @@ -6074,7 +6068,12 @@ export class ProfileController extends Controller { case "position": [findProfile, total] = await this.profileRepo.findAndCount({ - where: { position: Like(`%${body.keyword}%`) }, + where: { + position: Like(`%${body.keyword}%`), + current_holders:{ + orgRevisionId:revision?.id + } + }, relations: [ "posType", "posLevel", @@ -6122,6 +6121,9 @@ export class ProfileController extends Controller { where: { posType: { posTypeName:Like(`%${body.keyword}%`) + }, + current_holders:{ + orgRevisionId:revision?.id } }, relations: [ @@ -6145,6 +6147,9 @@ export class ProfileController extends Controller { where: { posLevel: { posLevelName:Like(`%${body.keyword}%`) + }, + current_holders:{ + orgRevisionId:revision?.id } }, relations: [ @@ -6167,6 +6172,7 @@ export class ProfileController extends Controller { [findProfile, total] = await this.profileRepo.findAndCount({ where: { current_holders:{ + orgRevisionId:revision?.id, orgRoot:{ orgRootName:Like(`%${body.keyword}%`) } @@ -6189,6 +6195,11 @@ export class ProfileController extends Controller { default: [findProfile, total] = await this.profileRepo.findAndCount({ + where:{ + current_holders:{ + orgRevisionId:revision?.id + } + }, relations: [ "posType", "posLevel", @@ -7236,10 +7247,11 @@ export class ProfileController extends Controller { : item.positions?.find((position) => position.positionIsSelected == true)?.posExecutive .posExecutiveName; - const amount = - item.current_holder == null || item.current_holder.profileSalary.length == 0 - ? null - : item.current_holder.profileSalary.sort((a: any, b: any) => b.date - a.date)[0].amount; + // const amount = + // item.current_holder == null || item.current_holder.profileSalary.length == 0 + // ? null + // : item.current_holder.profileSalary.sort((a: any, b: any) => b.date - a.date)[0].amount; + const amount = item.current_holder?item.current_holder.amount:null; let datePeriodStart = new Date( `${new Date().getFullYear()}-${String(new Date().getMonth() + 1).padStart(2, "0")}-${String(new Date().getDate() + 1).padStart(2, "0")}T00:00:00.000Z`, ); diff --git a/src/controllers/ProfileEmployeeController.ts b/src/controllers/ProfileEmployeeController.ts index 1ea3919e..006eb088 100644 --- a/src/controllers/ProfileEmployeeController.ts +++ b/src/controllers/ProfileEmployeeController.ts @@ -1385,22 +1385,15 @@ export class ProfileEmployeeController extends Controller { } else if (searchField == "position") { queryLike = "profileEmployee.position LIKE :keyword"; } else if (searchField == "posNo") { - queryLike = `CONCAT( - IFNULL(orgChild4.orgChild4ShortName, ''), - IFNULL(current_holders.posMasterNo , '') - ) LIKE :keyword OR CONCAT( - IFNULL(orgChild3.orgChild3ShortName, ''), - IFNULL(current_holders.posMasterNo , '') - ) LIKE :keyword OR CONCAT( - IFNULL(orgChild2.orgChild2ShortName, ''), - IFNULL(current_holders.posMasterNo , '') - ) LIKE :keyword OR CONCAT( - IFNULL(orgChild1.orgChild1ShortName, ''), - IFNULL(current_holders.posMasterNo , '') - ) LIKE :keyword OR CONCAT( - IFNULL(orgRoot.orgRootShortName, ''), - IFNULL(current_holders.posMasterNo , '') - ) LIKE :keyword`; + queryLike = ` + CASE + WHEN current_holders.orgChild4Id IS NOT NULL THEN CONCAT(orgChild4.orgChild4ShortName, current_holders.posMasterNo) + WHEN current_holders.orgChild3Id IS NOT NULL THEN CONCAT(orgChild3.orgChild3ShortName, current_holders.posMasterNo) + WHEN current_holders.orgChild2Id IS NOT NULL THEN CONCAT(orgChild2.orgChild2ShortName, current_holders.posMasterNo) + WHEN current_holders.orgChild1Id IS NOT NULL THEN CONCAT(orgChild1.orgChild1ShortName, current_holders.posMasterNo) + ELSE CONCAT(orgRoot.orgRootShortName, current_holders.posMasterNo) + END LIKE :keyword + `; } let nodeCondition = "1=1"; let nodeAll = ""; @@ -2957,10 +2950,11 @@ export class ProfileEmployeeController extends Controller { orgShortName = item.orgChild4?.orgChild4ShortName; } - const amount = - item.current_holder == null || item.current_holder.profileSalary.length == 0 - ? null - : item.current_holder.profileSalary.sort((a: any, b: any) => b.date - a.date)[0].amount; + // const amount = + // item.current_holder == null || item.current_holder.profileSalary.length == 0 + // ? null + // : item.current_holder.profileSalary.sort((a: any, b: any) => b.date - a.date)[0].amount; + const amount = item.current_holder?item.current_holder.amount:null; let datePeriodStart = new Date( `${new Date().getFullYear()}-${String(new Date().getMonth() + 1).padStart(2, "0")}-${String(new Date().getDate() + 1).padStart(2, "0")}T00:00:00.000Z`, ); diff --git a/src/controllers/ProfileEmployeeTempController.ts b/src/controllers/ProfileEmployeeTempController.ts index 22e1a1f2..d608d753 100644 --- a/src/controllers/ProfileEmployeeTempController.ts +++ b/src/controllers/ProfileEmployeeTempController.ts @@ -2699,10 +2699,11 @@ export class ProfileEmployeeTempController extends Controller { orgShortName = item.orgChild4?.orgChild4ShortName; } - const amount = - item.current_holder == null || item.current_holder.profileSalary.length == 0 - ? null - : item.current_holder.profileSalary.sort((a: any, b: any) => b.date - a.date)[0].amount; + // const amount = + // item.current_holder == null || item.current_holder.profileSalary.length == 0 + // ? null + // : item.current_holder.profileSalary.sort((a: any, b: any) => b.date - a.date)[0].amount; + const amount = item.current_holder?item.current_holder.amount:null; let datePeriodStart = new Date( `${new Date().getFullYear()}-${String(new Date().getMonth() + 1).padStart(2, "0")}-${String(new Date().getDate() + 1).padStart(2, "0")}T00:00:00.000Z`, ); diff --git a/src/controllers/ProfileSalaryController.ts b/src/controllers/ProfileSalaryController.ts index b5b0d8a5..74daa7e0 100644 --- a/src/controllers/ProfileSalaryController.ts +++ b/src/controllers/ProfileSalaryController.ts @@ -122,7 +122,7 @@ export class ProfileSalaryController extends Controller { createdAt: new Date(), lastUpdatedAt: new Date(), }; - + const _null:any = null; Object.assign(data, { ...body, ...meta }); const history = new ProfileSalaryHistory(); Object.assign(history, { ...data, id: undefined }); @@ -131,6 +131,11 @@ export class ProfileSalaryController extends Controller { history.profileSalaryId = data.id; await this.salaryHistoryRepo.save(history, { data: req }); + profile.amount = body?.amount??_null; + profile.positionSalaryAmount = body?.positionSalaryAmount??_null; + profile.mouthSalaryAmount = body.mouthSalaryAmount??_null; + await this.profileRepo.save(profile, { data: req }); + return new HttpSuccess(); } @@ -173,6 +178,7 @@ export class ProfileSalaryController extends Controller { let null_:any = null; profile.amount = body.amount ?? null_; + profile.amountSpecial = body.amountSpecial ?? null_; profile.positionSalaryAmount = body.positionSalaryAmount ?? null_; profile.mouthSalaryAmount = body.mouthSalaryAmount ?? null_; await this.profileRepo.save(profile); diff --git a/src/controllers/ProfileSalaryEmployeeController.ts b/src/controllers/ProfileSalaryEmployeeController.ts index 0ebc07d3..0fb5bc9e 100644 --- a/src/controllers/ProfileSalaryEmployeeController.ts +++ b/src/controllers/ProfileSalaryEmployeeController.ts @@ -137,12 +137,17 @@ export class ProfileSalaryEmployeeController extends Controller { Object.assign(data, { ...body, ...meta }); const history = new ProfileSalaryHistory(); Object.assign(history, { ...data, id: undefined }); - + const _null:any = null; await this.salaryRepo.save(data, { data: req }); setLogDataDiff(req, { before, after: data }); history.profileSalaryId = data.id; await this.salaryHistoryRepo.save(history, { data: req }); + profile.amount = body?.amount??_null; + profile.positionSalaryAmount = body?.positionSalaryAmount??_null; + profile.mouthSalaryAmount = body.mouthSalaryAmount??_null; + await this.profileRepo.save(profile, { data: req }); + return new HttpSuccess(); } @@ -189,6 +194,7 @@ export class ProfileSalaryEmployeeController extends Controller { let null_:any = null; profile.amount = body.amount ?? null_; + profile.amountSpecial = body.amountSpecial ?? null_; profile.positionSalaryAmount = body.positionSalaryAmount ?? null_; profile.mouthSalaryAmount = body.mouthSalaryAmount ?? null_; await this.profileRepo.save(profile); diff --git a/src/database/data-source.ts b/src/database/data-source.ts index 67ff5b79..5bd34db2 100644 --- a/src/database/data-source.ts +++ b/src/database/data-source.ts @@ -41,7 +41,7 @@ export const AppDataSource = new DataSource({ password: process.env.DB_PASSWORD, connectorPackage: "mysql2", synchronize: false, - logging: ["query", "error"], + logging: true, entities: process.env.NODE_ENV !== "production" ? ["src/entities/**/*.ts"] diff --git a/src/entities/ApiHistory.ts b/src/entities/ApiHistory.ts index 94cffcaf..c5f640d0 100644 --- a/src/entities/ApiHistory.ts +++ b/src/entities/ApiHistory.ts @@ -1,6 +1,7 @@ import { Entity, Column, ManyToOne, JoinColumn } from "typeorm"; import { EntityBase } from "./base/Base"; import { ApiKey } from "./ApiKey"; +import { ApiName } from "./ApiName"; @Entity("apiHistory") export class ApiHistory extends EntityBase { @@ -63,4 +64,16 @@ export class ApiHistory extends EntityBase { @ManyToOne(() => ApiKey, (apiKey) => apiKey.apiHistorys) @JoinColumn({ name: "apiKeyId" }) apiKey: ApiKey; + + @Column({ + nullable: true, + length: 40, + comment: "คีย์นอก(FK)ของตาราง ApiName", + default: null, + }) + apiNameId: string; + + @ManyToOne(() => ApiName, (apiName) => apiName.apiHistorys) + @JoinColumn({ name: "apiNameId" }) + apiName: ApiName; } diff --git a/src/entities/ApiName.ts b/src/entities/ApiName.ts index 635e2114..510e51df 100644 --- a/src/entities/ApiName.ts +++ b/src/entities/ApiName.ts @@ -1,6 +1,7 @@ -import { Entity, Column, ManyToMany, JoinTable } from "typeorm"; +import { Entity, Column, ManyToMany, JoinTable, OneToMany } from "typeorm"; import { EntityBase } from "./base/Base"; import { ApiKey } from "./ApiKey"; +import { ApiHistory } from "./ApiHistory"; @Entity("apiName") export class ApiName extends EntityBase { @@ -31,4 +32,7 @@ export class ApiName extends EntityBase { @ManyToMany(() => ApiKey, (apiKey) => apiKey.apiNames) @JoinTable() apiKeys: ApiKey[]; + + @OneToMany(() => ApiHistory, (v) => v.apiName) + apiHistorys: ApiHistory[]; } diff --git a/src/entities/CommandRecive.ts b/src/entities/CommandRecive.ts index 2e9c62d6..2ed7d823 100644 --- a/src/entities/CommandRecive.ts +++ b/src/entities/CommandRecive.ts @@ -67,6 +67,14 @@ export class CommandRecive extends EntityBase { }) amount: Double; + @Column({ + comment: "เงินพิเศษ", + default: 0, + nullable: true, + type: "double", + }) + amountSpecial: Double; + @Column({ comment: "เงินประจำตำแหน่ง", default: 0, diff --git a/src/entities/CommandType.ts b/src/entities/CommandType.ts index 86a34ba3..2ec53177 100644 --- a/src/entities/CommandType.ts +++ b/src/entities/CommandType.ts @@ -80,6 +80,12 @@ export class CommandType extends EntityBase { }) isAttachment: boolean; + @Column({ + comment: "สถานะแก้ไขเงินเดือน", + default: true, + }) + isSalary: boolean; + @Column({ nullable: true, comment: "คำอธิบาย", @@ -119,6 +125,9 @@ export class CreateCommandType { @Column() isAttachment: boolean; + + @Column() + isSalary?: boolean | null; } export type UpdateCommandType = Partial; diff --git a/src/entities/Profile.ts b/src/entities/Profile.ts index 06609028..3b3818e3 100644 --- a/src/entities/Profile.ts +++ b/src/entities/Profile.ts @@ -339,6 +339,14 @@ export class Profile extends EntityBase { }) amount: Double; + @Column({ + comment: "เงินพิเศษ", + default: 0, + nullable: true, + type: "double", + }) + amountSpecial: Double; + @Column({ comment: "เงินประจำตำแหน่ง", default: 0, @@ -778,6 +786,8 @@ export class CreateProfileAllFields { currentDistrictId: string | null; currentSubDistrictId: string | null; currentZipCode: string | null; + amount?: Double | null; + amountSpecial?: Double | null; } export type UpdateProfile = { diff --git a/src/entities/ProfileEmployee.ts b/src/entities/ProfileEmployee.ts index c492a457..4706f399 100644 --- a/src/entities/ProfileEmployee.ts +++ b/src/entities/ProfileEmployee.ts @@ -592,6 +592,14 @@ export class ProfileEmployee extends EntityBase { }) amount: Double; + @Column({ + comment: "เงินพิเศษ", + default: 0, + nullable: true, + type: "double", + }) + amountSpecial: Double; + @Column({ comment: "เงินประจำตำแหน่ง", default: 0, diff --git a/src/entities/ProfileSalary.ts b/src/entities/ProfileSalary.ts index c3e6adc7..ad7217bd 100644 --- a/src/entities/ProfileSalary.ts +++ b/src/entities/ProfileSalary.ts @@ -95,6 +95,14 @@ export class ProfileSalary extends EntityBase { }) amount: Double; + @Column({ + comment: "เงินพิเศษ", + default: 0, + nullable: true, + type: "double", + }) + amountSpecial: Double; + @Column({ comment: "เงินประจำตำแหน่ง", default: 0, @@ -184,6 +192,7 @@ export class CreateProfileSalary { profileId: string; date?: Date | null; amount?: Double | null; + amountSpecial?: Double | null; positionSalaryAmount?: Double | null; mouthSalaryAmount?: Double | null; posNo: string | null; @@ -204,6 +213,7 @@ export class CreateProfileSalaryEmployee { profileEmployeeId: string | null; date?: Date | null; amount?: Double | null; + amountSpecial?: Double | null; commandId?: string | null; positionSalaryAmount?: Double | null; mouthSalaryAmount?: Double | null; @@ -221,6 +231,7 @@ export class CreateProfileSalaryEmployee { export class UpdateProfileSalaryEmployee { date?: Date | null; amount?: Double | null; + amountSpecial?: Double | null; positionSalaryAmount?: Double | null; mouthSalaryAmount?: Double | null; posNo: string | null; @@ -237,6 +248,7 @@ export class UpdateProfileSalaryEmployee { export type UpdateProfileSalary = { date?: Date | null; amount?: Double | null; + amountSpecial?: Double | null; positionSalaryAmount?: Double | null; mouthSalaryAmount?: Double | null; posNo?: string | null; diff --git a/src/entities/ProfileSalaryHistory.ts b/src/entities/ProfileSalaryHistory.ts index f8f9193d..f419c222 100644 --- a/src/entities/ProfileSalaryHistory.ts +++ b/src/entities/ProfileSalaryHistory.ts @@ -83,6 +83,14 @@ export class ProfileSalaryHistory extends EntityBase { }) amount: Double; + @Column({ + comment: "เงินพิเศษ", + default: 0, + nullable: true, + type: "double", + }) + amountSpecial: Double; + @Column({ comment: "เงินประจำตำแหน่ง", default: 0, @@ -149,6 +157,7 @@ export class CreateProfileSalaryHistory { profileId: string; date?: Date | null; amount?: Double | null; + amountSpecial?: Double | null; positionSalaryAmount?: Double | null; mouthSalaryAmount?: Double | null; posNo: string | null; @@ -165,6 +174,7 @@ export class CreateProfileSalaryHistory { export class UpdateProfileSalaryHistory { date?: Date | null; amount?: Double | null; + amountSpecial?: Double | null; positionSalaryAmount?: Double | null; mouthSalaryAmount?: Double | null; posNo?: string | null; diff --git a/src/migration/1733318856709-update_keyapi_add_KeynameId.ts b/src/migration/1733318856709-update_keyapi_add_KeynameId.ts new file mode 100644 index 00000000..712e7182 --- /dev/null +++ b/src/migration/1733318856709-update_keyapi_add_KeynameId.ts @@ -0,0 +1,16 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class UpdateKeyapiAddKeynameId1733318856709 implements MigrationInterface { + name = 'UpdateKeyapiAddKeynameId1733318856709' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`apiHistory\` ADD \`apiNameId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง ApiName'`); + await queryRunner.query(`ALTER TABLE \`apiHistory\` ADD CONSTRAINT \`FK_0b7ae98d4f342bf920339ada78b\` FOREIGN KEY (\`apiNameId\`) REFERENCES \`apiName\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`apiHistory\` DROP FOREIGN KEY \`FK_0b7ae98d4f342bf920339ada78b\``); + await queryRunner.query(`ALTER TABLE \`apiHistory\` DROP COLUMN \`apiNameId\``); + } + +} diff --git a/src/migration/1733463321778-update_table_profileSalary_add_amountSpecial.ts b/src/migration/1733463321778-update_table_profileSalary_add_amountSpecial.ts new file mode 100644 index 00000000..4cff7e82 --- /dev/null +++ b/src/migration/1733463321778-update_table_profileSalary_add_amountSpecial.ts @@ -0,0 +1,14 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class UpdateTableProfileSalaryAddAmountSpecial1733463321778 implements MigrationInterface { + name = 'UpdateTableProfileSalaryAddAmountSpecial1733463321778' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`profileSalary\` ADD \`amountSpecial\` double NULL COMMENT 'เงินพิเศษ' DEFAULT '0'`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`profileSalary\` DROP COLUMN \`amountSpecial\``); + } + +} diff --git a/src/migration/1733471256767-update_3table__add_amountSpecial.ts b/src/migration/1733471256767-update_3table__add_amountSpecial.ts new file mode 100644 index 00000000..8c94690e --- /dev/null +++ b/src/migration/1733471256767-update_3table__add_amountSpecial.ts @@ -0,0 +1,22 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class Update3table_addAmountSpecial1733471256767 implements MigrationInterface { + name = 'Update3table_addAmountSpecial1733471256767' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`profileEmployee\` ADD \`amountSpecial\` double NULL COMMENT 'เงินพิเศษ' DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE \`profileEmployeeHistory\` ADD \`amountSpecial\` double NULL COMMENT 'เงินพิเศษ' DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE \`commandRecive\` ADD \`amountSpecial\` double NULL COMMENT 'เงินพิเศษ' DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE \`profile\` ADD \`amountSpecial\` double NULL COMMENT 'เงินพิเศษ' DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE \`profileHistory\` ADD \`amountSpecial\` double NULL COMMENT 'เงินพิเศษ' DEFAULT '0'`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`profileHistory\` DROP COLUMN \`amountSpecial\``); + await queryRunner.query(`ALTER TABLE \`profile\` DROP COLUMN \`amountSpecial\``); + await queryRunner.query(`ALTER TABLE \`commandRecive\` DROP COLUMN \`amountSpecial\``); + await queryRunner.query(`ALTER TABLE \`profileEmployeeHistory\` DROP COLUMN \`amountSpecial\``); + await queryRunner.query(`ALTER TABLE \`profileEmployee\` DROP COLUMN \`amountSpecial\``); + } + +} diff --git a/src/migration/1733482389096-update_table_commandType_add_isSalary.ts b/src/migration/1733482389096-update_table_commandType_add_isSalary.ts new file mode 100644 index 00000000..0ebc05fd --- /dev/null +++ b/src/migration/1733482389096-update_table_commandType_add_isSalary.ts @@ -0,0 +1,14 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class UpdateTableCommandTypeAddIsSalary1733482389096 implements MigrationInterface { + name = 'UpdateTableCommandTypeAddIsSalary1733482389096' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`commandType\` ADD \`isSalary\` tinyint NOT NULL COMMENT 'สถานะแก้ไขเงินเดือน' DEFAULT 1`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`commandType\` DROP COLUMN \`isSalary\``); + } + +} diff --git a/src/migration/1733798795372-update_table_add_field.ts b/src/migration/1733798795372-update_table_add_field.ts new file mode 100644 index 00000000..596c200c --- /dev/null +++ b/src/migration/1733798795372-update_table_add_field.ts @@ -0,0 +1,14 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class UpdateTableAddField1733798795372 implements MigrationInterface { + name = 'UpdateTableAddField1733798795372' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`profileSalaryHistory\` ADD \`amountSpecial\` double NULL COMMENT 'เงินพิเศษ' DEFAULT '0'`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`profileSalaryHistory\` DROP COLUMN \`amountSpecial\``); + } + +} diff --git a/src/services/rabbitmq.ts b/src/services/rabbitmq.ts index f97fde19..eb373d1f 100644 --- a/src/services/rabbitmq.ts +++ b/src/services/rabbitmq.ts @@ -98,6 +98,7 @@ async function handler(msg: amqp.ConsumeMessage): Promise { commandId: command.id, templateDoc: command.positionDetail, amount: x.amount, + amountSpecial: x.amountSpecial, positionSalaryAmount: x.positionSalaryAmount, mouthSalaryAmount: x.mouthSalaryAmount, })),