Compare commits

..

11 commits

Author SHA1 Message Date
664f5153da Merge branch 'develop' into adiDev
All checks were successful
Build & Deploy on Dev / build (push) Successful in 1m3s
2026-06-04 09:25:29 +07:00
219a2908a3 แก้ format ฟิว posMasterNo (5) สำหรับบันทึกลงระบบที่พัฒนาบน .net
1.ปรับระดับชั้นงาน-ย้ายลูกจ้าง (เลข Prefix / Suffix ไม่แสดง)
2.รายการอื่นๆ (เลข Prefix / Suffix ไม่แสดง)
3.รายการลาออก (เลข Prefix / Suffix ไม่แสดง)
4.รายการลาออกลูกจ้างฯ (เลข Prefix / Suffix ไม่แสดง)
5.เรื่องร้องเรียน (เลข Prefix / Suffix ไม่แสดง)
6.สืบสวนฯ (เลข Prefix / Suffix ไม่แสดง)
7.สอบสวนฯ (เลข Prefix / Suffix ไม่แสดง)
8.สรุปผลการพิจารณาฯ (เลข Prefix / Suffix ไม่แสดง)
2026-06-04 09:25:01 +07:00
harid
b0cfbc7036 fix #2510
All checks were successful
Build & Deploy on Dev / build (push) Successful in 1m5s
2026-05-29 17:37:19 +07:00
185aedc53f remove log success 2026-05-29 17:23:45 +07:00
20c6c412b8 remove log success 2026-05-29 14:24:50 +07:00
harid
ad9a7dcbb6 fix ระบบไม่ปั๊มประวัติข้อมูลเดิมให้ row แรก #2535
All checks were successful
Build & Deploy on Dev / build (push) Successful in 1m2s
2026-05-29 14:08:25 +07:00
harid
774a58bc22 Merge branch 'develop' into develop-Bright 2026-05-29 10:36:56 +07:00
755ae992dd #246 เสริมคำสั่ง C-PM-25,C-PM-26
All checks were successful
Build & Deploy on Dev / build (push) Successful in 1m10s
2026-05-29 10:12:46 +07:00
harid
d495137aaf devTest Controller สำหรับทดสอบ 2026-05-28 17:11:06 +07:00
harid
521a748de1 fix แก้ไขประวัติส่วนตัว ไม่ปั๊มประวัติรายการคนครอง #244
All checks were successful
Build & Deploy on Dev / build (push) Successful in 1m9s
2026-05-28 13:02:58 +07:00
ccfb2754fd API apiKey list return accessType and orgName
All checks were successful
Build & Deploy on Dev / build (push) Successful in 1m4s
2026-05-28 09:49:21 +07:00
9 changed files with 913 additions and 233 deletions

View file

@ -20,6 +20,12 @@ import { In } from "typeorm";
import { RequestWithUser } from "../middlewares/user"; import { RequestWithUser } from "../middlewares/user";
import { ApiName } from "../entities/ApiName"; import { ApiName } from "../entities/ApiName";
import { ApiHistory } from "../entities/ApiHistory"; import { ApiHistory } from "../entities/ApiHistory";
import { OrgRoot } from "../entities/OrgRoot";
import { OrgChild1 } from "../entities/OrgChild1";
import { OrgChild2 } from "../entities/OrgChild2";
import { OrgChild3 } from "../entities/OrgChild3";
import { OrgChild4 } from "../entities/OrgChild4";
import { OrgRevision } from "../entities/OrgRevision";
const jwt = require("jsonwebtoken"); const jwt = require("jsonwebtoken");
@Route("api/v1/org/apiKey") @Route("api/v1/org/apiKey")
@ -33,6 +39,12 @@ export class ApiKeyController extends Controller {
private apiKeyRepository = AppDataSource.getRepository(ApiKey); private apiKeyRepository = AppDataSource.getRepository(ApiKey);
private apiNameRepository = AppDataSource.getRepository(ApiName); private apiNameRepository = AppDataSource.getRepository(ApiName);
private apiHistoryRepository = AppDataSource.getRepository(ApiHistory); private apiHistoryRepository = AppDataSource.getRepository(ApiHistory);
private orgRootRepository = AppDataSource.getRepository(OrgRoot);
private orgChild1Repository = AppDataSource.getRepository(OrgChild1);
private orgChild2Repository = AppDataSource.getRepository(OrgChild2);
private orgChild3Repository = AppDataSource.getRepository(OrgChild3);
private orgChild4Repository = AppDataSource.getRepository(OrgChild4);
private orgRevisionRepository = AppDataSource.getRepository(OrgRevision);
/** /**
* API JWT token * API JWT token
@ -151,6 +163,9 @@ export class ApiKeyController extends Controller {
relations: ["apiNames", "apiHistorys"], relations: ["apiNames", "apiHistorys"],
order: { createdAt: "DESC", apiNames: { createdAt: "DESC" } }, order: { createdAt: "DESC", apiNames: { createdAt: "DESC" } },
}); });
const orgNames = await this.buildOrgNameBatch(apiKey);
const data = apiKey.map((_data) => ({ const data = apiKey.map((_data) => ({
id: _data.id, id: _data.id,
createdAt: _data.createdAt, createdAt: _data.createdAt,
@ -163,6 +178,7 @@ export class ApiKeyController extends Controller {
dnaChild2Id: _data.dnaChild2Id, dnaChild2Id: _data.dnaChild2Id,
dnaChild3Id: _data.dnaChild3Id, dnaChild3Id: _data.dnaChild3Id,
dnaChild4Id: _data.dnaChild4Id, dnaChild4Id: _data.dnaChild4Id,
orgName: orgNames.get(_data.id),
apiNames: _data.apiNames.map((x) => ({ apiNames: _data.apiNames.map((x) => ({
id: x.id, id: x.id,
name: x.name, name: x.name,
@ -174,10 +190,139 @@ export class ApiKeyController extends Controller {
return new HttpSuccess(data); return new HttpSuccess(data);
} }
private async buildOrgNameBatch(apiKeys: ApiKey[]): Promise<Map<string, string | null>> {
const currentRevision = await this.orgRevisionRepository.findOne({
where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
});
if (!currentRevision) {
return new Map(apiKeys.map((k) => [k.id, null]));
}
const currentRevisionId = currentRevision.id;
const rootIds = [...new Set(apiKeys.map((k) => k.dnaRootId).filter(Boolean))];
const child1Ids = [...new Set(apiKeys.map((k) => k.dnaChild1Id).filter(Boolean))];
const child2Ids = [...new Set(apiKeys.map((k) => k.dnaChild2Id).filter(Boolean))];
const child3Ids = [...new Set(apiKeys.map((k) => k.dnaChild3Id).filter(Boolean))];
const child4Ids = [...new Set(apiKeys.map((k) => k.dnaChild4Id).filter(Boolean))];
const [roots, child1s, child2s, child3s, child4s] = await Promise.all([
rootIds.length > 0
? this.orgRootRepository.find({
where: [
{ id: In(rootIds), orgRevisionId: currentRevisionId },
{ ancestorDNA: In(rootIds), orgRevisionId: currentRevisionId },
],
select: ["id", "ancestorDNA", "orgRootName"],
})
: [],
child1Ids.length > 0
? this.orgChild1Repository.find({
where: [
{ id: In(child1Ids), orgRevisionId: currentRevisionId },
{ ancestorDNA: In(child1Ids), orgRevisionId: currentRevisionId },
],
select: ["id", "ancestorDNA", "orgChild1Name"],
})
: [],
child2Ids.length > 0
? this.orgChild2Repository.find({
where: [
{ id: In(child2Ids), orgRevisionId: currentRevisionId },
{ ancestorDNA: In(child2Ids), orgRevisionId: currentRevisionId },
],
select: ["id", "ancestorDNA", "orgChild2Name"],
})
: [],
child3Ids.length > 0
? this.orgChild3Repository.find({
where: [
{ id: In(child3Ids), orgRevisionId: currentRevisionId },
{ ancestorDNA: In(child3Ids), orgRevisionId: currentRevisionId },
],
select: ["id", "ancestorDNA", "orgChild3Name"],
})
: [],
child4Ids.length > 0
? this.orgChild4Repository.find({
where: [
{ id: In(child4Ids), orgRevisionId: currentRevisionId },
{ ancestorDNA: In(child4Ids), orgRevisionId: currentRevisionId },
],
select: ["id", "ancestorDNA", "orgChild4Name"],
})
: [],
]);
const rootMap = new Map(
roots.map((r) => [r.id, { name: r.orgRootName, ancestorDNA: r.ancestorDNA }]),
);
const child1Map = new Map(
child1s.map((c) => [c.id, { name: c.orgChild1Name, ancestorDNA: c.ancestorDNA }]),
);
const child2Map = new Map(
child2s.map((c) => [c.id, { name: c.orgChild2Name, ancestorDNA: c.ancestorDNA }]),
);
const child3Map = new Map(
child3s.map((c) => [c.id, { name: c.orgChild3Name, ancestorDNA: c.ancestorDNA }]),
);
const child4Map = new Map(
child4s.map((c) => [c.id, { name: c.orgChild4Name, ancestorDNA: c.ancestorDNA }]),
);
const result = new Map<string, string | null>();
for (const apiKey of apiKeys) {
if (apiKey.accessType === "ALL") {
result.set(apiKey.id, null);
continue;
}
const parts: string[] = [];
const getOrgName = (
dnaId: string,
orgMap: Map<string, { name: string; ancestorDNA: string }>,
): string | null => {
const byId = orgMap.get(dnaId);
if (byId) return byId.name;
for (const [, value] of orgMap) {
if (value.ancestorDNA === dnaId) return value.name;
}
return null;
};
if (apiKey.dnaChild4Id) {
const name = getOrgName(apiKey.dnaChild4Id, child4Map);
if (name) parts.push(name);
}
if (apiKey.dnaChild3Id) {
const name = getOrgName(apiKey.dnaChild3Id, child3Map);
if (name) parts.push(name);
}
if (apiKey.dnaChild2Id) {
const name = getOrgName(apiKey.dnaChild2Id, child2Map);
if (name) parts.push(name);
}
if (apiKey.dnaChild1Id) {
const name = getOrgName(apiKey.dnaChild1Id, child1Map);
if (name) parts.push(name);
}
if (apiKey.dnaRootId) {
const name = getOrgName(apiKey.dnaRootId, rootMap);
if (name) parts.push(name);
}
result.set(apiKey.id, parts.length > 0 ? parts.join(" ") : null);
}
return result;
}
/** /**
* API Api Key * API Api Name
* *
* @summary Api Key (ADMIN) * @summary Api Name (ADMIN)
* *
*/ */
@Get("name") @Get("name")

View file

@ -41,7 +41,6 @@ import {
removeProfileInOrganize, removeProfileInOrganize,
setLogDataDiff, setLogDataDiff,
checkReturnCommandType, checkReturnCommandType,
checkExceptCommandType,
checkCommandType, checkCommandType,
removePostMasterAct, removePostMasterAct,
logPositionIsSelectedChange, logPositionIsSelectedChange,
@ -4313,11 +4312,8 @@ export class CommandController extends Controller {
body.data.map(async (item) => { body.data.map(async (item) => {
const profile = await this.profileRepository.findOne({ const profile = await this.profileRepository.findOne({
where: { id: item.profileId }, where: { id: item.profileId },
// relations: ["roleKeycloaks"],
relations: { relations: {
roleKeycloaks: true, roleKeycloaks: true
posType: true,
posLevel: true,
}, },
}); });
if (!profile) { if (!profile) {
@ -4613,6 +4609,8 @@ export class CommandController extends Controller {
await this.positionRepository.save(positionNew, { data: req }); await this.positionRepository.save(positionNew, { data: req });
} }
await CreatePosMasterHistoryOfficer(posMaster.id, req); await CreatePosMasterHistoryOfficer(posMaster.id, req);
profile.posMasterNo = getPosMasterNo(posMaster);
profile.org = getOrgFullName(posMaster);
} }
const newMapProfileSalary = { const newMapProfileSalary = {
profileId: profile.id, profileId: profile.id,
@ -5629,20 +5627,10 @@ export class CommandController extends Controller {
_profile.lastUpdateFullName = req.user.name; _profile.lastUpdateFullName = req.user.name;
_profile.lastUpdatedAt = new Date(); _profile.lastUpdatedAt = new Date();
if (item.isLeave == true) { if (item.isLeave == true) {
const exceptClear = await checkExceptCommandType(String(item.commandId)); if (orgRevisionRef) {
if (exceptClear.status) { await CreatePosMasterHistoryOfficer(orgRevisionRef.id, req, "DELETE");
_profile.leaveReason = item.leaveReason ?? _null;
_profile.leaveCommandId = item.commandId ?? _null;
_profile.leaveCommandNo = `${item.commandNo}/${_commandYear}`;
_profile.leaveRemark = exceptClear.leaveRemark ?? _null;
_profile.leaveDate = item.commandDateAffect ?? _null;
_profile.leaveType = exceptClear.LeaveType ?? _null;
} else {
if (orgRevisionRef) {
await CreatePosMasterHistoryOfficer(orgRevisionRef.id, req, "DELETE");
}
await removeProfileInOrganize(_profile.id, "OFFICER");
} }
await removeProfileInOrganize(_profile.id, "OFFICER");
} }
const clearProfile = await checkCommandType(String(item.commandId)); const clearProfile = await checkCommandType(String(item.commandId));
if (clearProfile.status) { if (clearProfile.status) {
@ -5821,32 +5809,22 @@ export class CommandController extends Controller {
_profile.lastUpdateFullName = req.user.name; _profile.lastUpdateFullName = req.user.name;
_profile.lastUpdatedAt = new Date(); _profile.lastUpdatedAt = new Date();
if (item.isLeave == true) { if (item.isLeave == true) {
const exceptClear = await checkExceptCommandType(String(item.commandId)); // บันทึกประวัติก่อนลบตำแหน่ง
if (exceptClear.status) { const curRevision = await this.orgRevisionRepo.findOne({
_profile.leaveReason = item.leaveReason ?? _null; where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
_profile.leaveCommandId = item.commandId ?? _null; });
_profile.leaveCommandNo = `${item.commandNo}/${_commandYear}`; if (curRevision) {
_profile.leaveRemark = exceptClear.leaveRemark ?? _null; const curPosMaster = await this.employeePosMasterRepository.findOne({
_profile.leaveDate = item.commandDateAffect ?? _null; where: {
_profile.leaveType = exceptClear.LeaveType ?? _null; current_holderId: _profile.id,
} else { orgRevisionId: curRevision.id,
// บันทึกประวัติก่อนลบตำแหน่ง },
const curRevision = await this.orgRevisionRepo.findOne({
where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
}); });
if (curRevision) { if (curPosMaster) {
const curPosMaster = await this.employeePosMasterRepository.findOne({ await CreatePosMasterHistoryEmployee(curPosMaster.id, req, "DELETE");
where: {
current_holderId: _profile.id,
orgRevisionId: curRevision.id,
},
});
if (curPosMaster) {
await CreatePosMasterHistoryEmployee(curPosMaster.id, req, "DELETE");
}
} }
await removeProfileInOrganize(_profile.id, "EMPLOYEE");
} }
await removeProfileInOrganize(_profile.id, "EMPLOYEE");
} }
const clearProfile = await checkCommandType(String(item.commandId)); const clearProfile = await checkCommandType(String(item.commandId));
if (clearProfile.status) { if (clearProfile.status) {
@ -6166,32 +6144,22 @@ export class CommandController extends Controller {
_profile.lastUpdateFullName = req.user.name; _profile.lastUpdateFullName = req.user.name;
_profile.lastUpdatedAt = new Date(); _profile.lastUpdatedAt = new Date();
if (item.isLeave == true) { if (item.isLeave == true) {
const exceptClear = await checkExceptCommandType(String(item.commandId)); // บันทึกประวัติก่อนลบตำแหน่ง
if (exceptClear.status) { const curRevision = await this.orgRevisionRepo.findOne({
_profile.leaveReason = item.leaveReason ?? _null; where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
_profile.leaveCommandId = item.commandId ?? _null; });
_profile.leaveCommandNo = `${item.commandNo}/${_commandYear}`; if (curRevision) {
_profile.leaveRemark = exceptClear.leaveRemark ?? _null; const curPosMaster = await this.employeePosMasterRepository.findOne({
_profile.leaveDate = item.commandDateAffect ?? _null; where: {
_profile.leaveType = exceptClear.LeaveType ?? _null; current_holderId: _profile.id,
} else { orgRevisionId: curRevision.id,
// บันทึกประวัติก่อนลบตำแหน่ง },
const curRevision = await this.orgRevisionRepo.findOne({
where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
}); });
if (curRevision) { if (curPosMaster) {
const curPosMaster = await this.employeePosMasterRepository.findOne({ await CreatePosMasterHistoryEmployee(curPosMaster.id, req, "DELETE");
where: {
current_holderId: _profile.id,
orgRevisionId: curRevision.id,
},
});
if (curPosMaster) {
await CreatePosMasterHistoryEmployee(curPosMaster.id, req, "DELETE");
}
} }
await removeProfileInOrganize(_profile.id, "EMPLOYEE");
} }
await removeProfileInOrganize(_profile.id, "EMPLOYEE");
} }
const clearProfile = await checkCommandType(String(item.commandId)); const clearProfile = await checkCommandType(String(item.commandId));
if (clearProfile.status) { if (clearProfile.status) {

View file

@ -0,0 +1,576 @@
import {
Controller,
Post,
Put,
Patch,
Delete,
Route,
Security,
Tags,
Body,
Path,
Request,
Response,
Get,
Query,
} from "tsoa";
import { AppDataSource } from "../database/data-source";
import HttpStatus from "../interfaces/http-status";
import HttpSuccess from "../interfaces/http-success";
import HttpStatusCode from "../interfaces/http-status";
import HttpError from "../interfaces/http-error";
import { Command } from "../entities/Command";
import { Brackets, LessThan, MoreThan, Double, In, Between, IsNull, Not, Any } from "typeorm";
import { CommandType } from "../entities/CommandType";
import { Profile, CreateProfileAllFields } from "../entities/Profile";
import { RequestWithUser, RequestWithUserWebService } from "../middlewares/user";
import { OrgRevision } from "../entities/OrgRevision";
import { ProfileEmployee } from "../entities/ProfileEmployee";
import { PosMaster } from "../entities/PosMaster";
import permission from "../interfaces/permission";
import { viewCurrentTenureOfficer } from "../entities/view/viewCurrentTenureOfficer";
import { CommandController } from "./CommandController";
import Extension from "../interfaces/extension";
import { viewRegistryOfficer } from "../entities/view/viewRegistryOfficer";
import { viewRegistryEmployee } from "../entities/view/viewRegistryEmployee";
import { Registry } from "../entities/Registry";
import { RegistryEmployee } from "../entities/RegistryEmployee";
import { TenurePositionOfficer } from "../entities/TenurePositionOfficer";
import { PosMasterAssign, PosMasterAssignDTO } from "../entities/PosMasterAssign";
import { PermissionProfile } from "../entities/PermissionProfile";
import { OrgRoot } from "../entities/OrgRoot";
import { MetaWorkflow } from "../entities/MetaWorkflow";
import { MetaState } from "../entities/MetaState";
import { MetaStateOperator } from "../entities/MetaStateOperator";
import { Workflow } from "../entities/Workflow";
import { State } from "../entities/State";
import { StateOperator } from "../entities/StateOperator";
import { StateOperatorUser } from "../entities/StateOperatorUser";
import {
commandTypePath,
calculateGovAge,
calculateAge,
calculateRetireDate,
calculateRetireLaw,
removeProfileInOrganize,
setLogDataDiff,
} from "../interfaces/utils";
import CallAPI from "../interfaces/call-api";
import { PostRetireToExprofile } from "./ExRetirementController"
import { Position } from "../entities/Position";
import { PosLevel } from "../entities/PosLevel";
import { TenureLevelOfficer } from "../entities/TenureLevelOfficer";
import { TenurePositionEmployee } from "../entities/TenurePositionEmployee";
import { TenureLevelEmployee } from "../entities/TenureLevelEmployee";
import { TenurePositionExecutiveOfficer } from "../entities/TenurePositionExecutiveOfficer";
@Route("api/v1/org/DevTest")
@Tags("DevTest")
@Security("bearerAuth")
@Response(
HttpStatusCode.INTERNAL_SERVER_ERROR,
"เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง",
)
export class DevTestController extends Controller {
private commandRepository = AppDataSource.getRepository(Command);
private commandTypeRepository = AppDataSource.getRepository(CommandType);
private orgRevisionRepo = AppDataSource.getRepository(OrgRevision);
private orgRootRepo = AppDataSource.getRepository(OrgRoot);
private posMasterRepo = AppDataSource.getRepository(PosMaster);
private profileRepo = AppDataSource.getRepository(Profile);
private profileEmpRepo = AppDataSource.getRepository(ProfileEmployee);
private registryRepo = AppDataSource.getRepository(Registry);
private registryEmployeeRepo = AppDataSource.getRepository(RegistryEmployee);
private posMasterAssignRepository = AppDataSource.getRepository(PosMasterAssign);
private permissionProfilesRepository = AppDataSource.getRepository(PermissionProfile);
private profileEmployeeRepo = AppDataSource.getRepository(ProfileEmployee);
private metaWorkflowRepo = AppDataSource.getRepository(MetaWorkflow);
private metaStateRepo = AppDataSource.getRepository(MetaState);
private metaStateOperatorRepo = AppDataSource.getRepository(MetaStateOperator);
private workflowRepo = AppDataSource.getRepository(Workflow);
private stateRepo = AppDataSource.getRepository(State);
private stateOperatorRepo = AppDataSource.getRepository(StateOperator);
private stateOperatorUserRepo = AppDataSource.getRepository(StateOperatorUser);
private positionRepository = AppDataSource.getRepository(Position);
private positionOfficerRepo = AppDataSource.getRepository(TenurePositionOfficer);
private positionEmployeeRepo = AppDataSource.getRepository(TenurePositionEmployee);
private levelOfficerRepo = AppDataSource.getRepository(TenureLevelOfficer);
private levelEmployeeRepo = AppDataSource.getRepository(TenureLevelEmployee);
private positionExecutiveOfficerRepo = AppDataSource.getRepository(
TenurePositionExecutiveOfficer,
);
@Patch("tick-officer-registry")
public async calculateOfficerPosition(
@Request() req: RequestWithUser,
@Body()
body: {
profileIds: string[];
},
) {
console.log("1.")
/**
* ===============================
* PREPARE DATA
* ===============================
*/
const profile = await this.profileRepo.find({
where: { id: In(body.profileIds) },
relations: {
posLevel: true,
posType: true,
},
});
if (!profile.length) return;
const [{ today }] = await AppDataSource.query(
"SELECT CURRENT_DATE() as today",
);
const orgRevision = await this.orgRevisionRepo.findOne({
select: ["id"],
where: {
orgRevisionIsDraft: false,
orgRevisionIsCurrent: true,
},
});
/**
* ===============================
* TRANSACTION
* ===============================
*/
const queryRunner = AppDataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
console.log("2.")
try {
/**
* ===============================
* RESULT BUFFERS (SAVE ARRAY)
* ===============================
*/
const positionOfficerBulk: any[] = [];
const levelOfficerBulk: any[] = [];
const executiveOfficerBulk: any[] = [];
console.log("3.")
/**
* ===============================
* MAIN LOOP (SINGLE LOOP)
* ===============================
*/
for (const x of profile) {
const currentDate =
x.isLeave && x.leaveDate
? Extension.toDateOnlyString(x.leaveDate)
: today;
/**
* ====================================
* PARALLEL STORED PROCEDURES
* ====================================
*/
const [
positionResult,
levelResult,
executiveResult,
] = await Promise.all([
AppDataSource.query("CALL GetProfileSalaryPosition(?, ?)", [
x.id,
currentDate,
]),
AppDataSource.query("CALL GetProfileSalaryLevel(?, ?)", [
x.id,
currentDate,
]),
AppDataSource.query("CALL GetProfileSalaryExecutive(?, ?)", [
x.id,
currentDate,
]),
]);
console.log("4.",x.id)
/**
* ====================================
* POSITION
* ====================================
*/
const posRows = positionResult?.[0] ?? [];
const posMap =
posRows.length > 1
? posRows.slice(1).map((r: any, i: number) => ({
days_diff: Number(r.days_diff) || 0,
positionName: posRows[i]?.positionName,
}))
: [];
const posCal = posMap
.filter((p:any) => p.positionName === x.position)
.reduce(
(a:any, c:any) => ({
days_diff: a.days_diff + c.days_diff,
positionName: c.positionName,
}),
{ days_diff: 0, positionName: null },
);
positionOfficerBulk.push({
profileId: x.id,
positionName: posCal.positionName,
days_diff: posCal.days_diff,
Years: Math.floor(posCal.days_diff / 365.2524),
Months: Math.floor((posCal.days_diff / 30.4375) % 12),
Days: Math.floor(posCal.days_diff % 30.4375),
});
console.log("5.",x.id)
/**
* ====================================
* 2 POSITION LEVEL
* ====================================
*/
const lvlRows = levelResult?.[0] ?? [];
const lvlMap =
lvlRows.length > 1
? lvlRows.slice(1).map((r: any, i: number) => ({
days_diff: Number(r.days_diff) || 0,
positionType: lvlRows[i]?.positionType,
positionLevel: lvlRows[i]?.positionLevel,
positionCee: lvlRows[i]?.positionCee,
}))
: [];
const lvlCal = lvlMap
.filter(
(l:any) =>
l.positionLevel === x.posLevel?.posLevelName &&
l.positionType === x.posType?.posTypeName,
)
.reduce(
(a:any, c:any) => ({
days_diff: a.days_diff + c.days_diff,
positionType: c.positionType,
positionLevel: c.positionLevel,
positionCee: c.positionCee,
}),
{
days_diff: 0,
positionType: null,
positionLevel: null,
positionCee: null,
},
);
levelOfficerBulk.push({
profileId: x.id,
positionType: lvlCal.positionType,
positionLevel: lvlCal.positionLevel,
positionCee: lvlCal.positionCee,
days_diff: lvlCal.days_diff,
Years: x.posLevel ? (lvlCal.days_diff / 365.2524).toFixed(4) : 0,
Months: x.posLevel ? ((lvlCal.days_diff / 30.4375) % 12).toFixed(4) : 0,
Days: x.posLevel ? (lvlCal.days_diff % 30.4375).toFixed(4) : 0,
});
console.log("6.",x.id)
/**
* ====================================
* 3 POSITION EXECUTIVE
* ====================================
*/
const exeRows = executiveResult?.[0] ?? [];
const exeMap =
exeRows.length > 1
? exeRows.slice(1).map((r: any, i: number) => ({
days_diff: Number(r.days_diff) || 0,
positionExecutive: exeRows[i]?.positionExecutive,
}))
: [];
const position = await this.positionRepository.findOne({
where: {
positionIsSelected: true,
posMaster: {
orgRevisionId: orgRevision?.id,
current_holderId: x.id,
},
},
order: { createdAt: "DESC" },
relations: {
posExecutive: true,
},
});
const exeName = position?.posExecutive?.posExecutiveName;
const exeCal = exeMap
.filter((e:any) => exeName && e.positionExecutive === exeName)
.reduce(
(a:any, c:any) => ({
days_diff: a.days_diff + c.days_diff,
positionExecutive: c.positionExecutive,
}),
{ days_diff: 0, positionExecutive: null },
);
executiveOfficerBulk.push({
profileId: x.id,
positionExecutiveName: exeCal.positionExecutive,
days_diff: exeCal.days_diff,
Years: (exeCal.days_diff / 365.2524).toFixed(4),
Months: ((exeCal.days_diff / 30.4375) % 12).toFixed(4),
Days: (exeCal.days_diff % 30.4375).toFixed(4),
});
}
console.log("7.")
/**
* ===============================
* CLEAR ALL DATA AND SAVE ARRAY (BULK)
* ===============================
*/
await queryRunner.manager
.createQueryBuilder()
.delete()
.from(this.positionOfficerRepo.target)
.execute();
await queryRunner.manager
.createQueryBuilder()
.delete()
.from(this.levelOfficerRepo.target)
.execute();
await queryRunner.manager
.createQueryBuilder()
.delete()
.from(this.positionExecutiveOfficerRepo.target)
.execute();
console.log("8.")
await queryRunner.manager.save(this.positionOfficerRepo.target, positionOfficerBulk);
await queryRunner.manager.save(this.levelOfficerRepo.target, levelOfficerBulk);
await queryRunner.manager.save(this.positionExecutiveOfficerRepo.target,executiveOfficerBulk);
console.log("9.")
/**
* ===============================
* REGISTRY OFFICER (SYNC VIEW)
* ===============================
*/
const allRegis = await queryRunner.manager
.getRepository(viewRegistryOfficer)
.createQueryBuilder("registryOfficer")
.where("registryOfficer.profileId IN (:...profileIds)", {
profileIds: new Set(profile.map((p) => p.id))
})
.getMany();
const mapRegistryData = allRegis.map((x) => ({
...x,
isProbation: Boolean(x.isProbation),
isLeave: Boolean(x.isLeave),
isRetirement: Boolean(x.isRetirement),
Educations: x.Educations ? JSON.stringify(x.Educations) : "",
}));
console.log("10.")
await queryRunner.manager
.createQueryBuilder()
.delete()
.from(this.registryRepo.target)
.execute();
if (mapRegistryData.length > 0) {
await queryRunner.manager.save(this.registryRepo.target, mapRegistryData);
}
console.log("11.")
/**
* ===============================
* COMMIT
* ===============================
*/
await queryRunner.commitTransaction();
} catch (error) {
await queryRunner.rollbackTransaction();
throw error;
} finally {
await queryRunner.release();
}
}
@Post("getDNA")
public async GetData(
@Request() req: RequestWithUser
){
let _data: any = {
root: null,
child1: null,
child2: null,
child3: null,
child4: null,
};
_data = await new permission().PermissionOrgList(req, "COMMAND");
return new HttpSuccess(_data);
}
@Post("calculateGovAge")
public async calculateGovAge(
@Request() req: RequestWithUser,
@Body()
body: {
profileId: string;
},
){
return new HttpSuccess(await calculateGovAge(body.profileId, "OFFICER"));
}
/**
* @summary Test Job 2
*/
@Post("cronjobCommand")
async CronjobCommand() {
const commandController = new CommandController();
await commandController.cronjobCommand();
}
/**
* @summary payload & Endpoint
*/
@Put("path-excec/{id}")
async Bright(
@Path() id: string,
@Request() request: RequestWithUser,
) {
const command = await this.commandRepository.findOne({
where: { id: id },
relations: ["commandType", "commandRecives", "commandSends", "commandSends.commandSendCCs"],
});
if (!command) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลคำสั่งนี้");
}
const path = commandTypePath(command.commandType.code);
return new HttpSuccess({
path: path + "/excecute",
refIds: command.commandRecives
.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,
})),
});
}
/**
* API tab4
* @summary API tab4
* @param {string} id Id
* @param {string} profileId profileId
*/
@Get("tab4/attachment/{id}/{profileId}")
async GetByIdTab4Attachment(
@Path() id: string,
@Path() profileId: string,
@Request() request: RequestWithUser
) {
await new permission().PermissionGet(request, "COMMAND");
let profile: Profile | ProfileEmployee | null = null;
profile = await this.profileRepo.findOne({ where: { id: profileId } });
if (!profile) {
profile = await this.profileEmpRepo.findOne({ where: { id: profileId } });
if (!profile)
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลบุคคลากรนี้");
}
const command = await this.commandRepository.findOne({
where: { id },
relations: ["commandType", "commandRecives"],
});
if (!command) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลคำสั่งนี้");
}
let _command: any = [];
const path = commandTypePath(command.commandType.code);
if (path == null) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบประเภทคำสั่งนี้ในระบบ");
await new CallAPI()
.PostData(request, path + "/attachment", {
refIds: command.commandRecives
.filter((x) =>
x.refId != null &&
x.profileId != null && x.profileId == profileId
)
.map((x) => ({
refId: x.refId,
Sequence: x.order,
CitizenId: x.citizenId,
Prefix: x.prefix,
FirstName: x.firstName,
LastName: x.lastName,
Amount: x.amount,
PositionSalaryAmount: x.positionSalaryAmount,
MouthSalaryAmount: x.mouthSalaryAmount,
RemarkHorizontal: x.remarkHorizontal,
RemarkVertical: x.remarkVertical,
CommandYear: command.commandYear,
CommandExcecuteDate: command.commandExcecuteDate,
})),
})
.then(async (res) => {
_command = res;
})
.catch(() => {});
let issue =
command.isBangkok == "OFFICE"
? "สำนักปลัดกรุงเทพมหานคร"
: command.isBangkok == "BANGKOK"
? "กรุงเทพมหานคร"
: null;
if (issue == null) {
const orgRevisionActive = await this.orgRevisionRepo.findOne({
where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
relations: ["posMasters", "posMasters.orgRoot"],
});
if (orgRevisionActive != null) {
const profile = await this.profileRepo.findOne({
where: {
keycloak: command.createdUserId.toString(),
},
});
if (profile != null) {
issue =
orgRevisionActive?.posMasters?.filter((x) => x.current_holderId == profile.id)[0]
?.orgRoot?.orgRootName || null;
}
}
}
if (issue == null) issue = "...................................";
return new HttpSuccess({
template: command.commandType.fileAttachment,
reportName: "xlsx-report",
data: {
data: _command,
issuerOrganizationName: issue,
commandNo: command.commandNo == null ? "" : Extension.ToThaiNumber(command.commandNo),
commandYear:
command.commandYear == null
? ""
: Extension.ToThaiNumber(Extension.ToThaiYear(command.commandYear).toString()),
commandExcecuteDate:
command.commandExcecuteDate == null
? ""
: Extension.ToThaiNumber(Extension.ToThaiFullDate2(command.commandExcecuteDate)),
},
});
}
}

View file

@ -2372,7 +2372,7 @@ export class OrganizationDotnetController extends Controller {
@Security("internalAuth") @Security("internalAuth")
async GetProfileForProcessCheckInAsync(@Path() keycloakId: string) { async GetProfileForProcessCheckInAsync(@Path() keycloakId: string) {
try { try {
console.log(`[check-keycloak] START - keycloakId=${keycloakId}`); // console.log(`[check-keycloak] START - keycloakId=${keycloakId}`);
/* ========================= /* =========================
* 1. Load profile (Officer) * 1. Load profile (Officer)
@ -2447,14 +2447,14 @@ export class OrganizationDotnetController extends Controller {
child4DnaId: currentHolder?.orgChild4?.ancestorDNA ?? null, child4DnaId: currentHolder?.orgChild4?.ancestorDNA ?? null,
}; };
console.log( // console.log(
`[check-keycloak] SUCCESS_EMPLOYEE - keycloakId=${keycloakId}, profileType=EMPLOYEE`, // `[check-keycloak] SUCCESS_EMPLOYEE - keycloakId=${keycloakId}, profileType=EMPLOYEE`,
); // );
return new HttpSuccess(mapProfile); return new HttpSuccess(mapProfile);
} }
console.log(`[check-keycloak] OFFICER_FOUND - keycloakId=${keycloakId}`); // console.log(`[check-keycloak] OFFICER_FOUND - keycloakId=${keycloakId}`);
/* ========================================= /* =========================================
* 2. current holder (Officer) * 2. current holder (Officer)
@ -2494,9 +2494,9 @@ export class OrganizationDotnetController extends Controller {
child4DnaId: currentHolder?.orgChild4?.ancestorDNA ?? null, child4DnaId: currentHolder?.orgChild4?.ancestorDNA ?? null,
}; };
console.log( // console.log(
`[check-keycloak] SUCCESS_OFFICER - keycloakId=${keycloakId}, profileType=OFFICER`, // `[check-keycloak] SUCCESS_OFFICER - keycloakId=${keycloakId}, profileType=OFFICER`,
); // );
return new HttpSuccess(mapProfile); return new HttpSuccess(mapProfile);
} catch (error: any) { } catch (error: any) {
@ -9151,4 +9151,30 @@ export class OrganizationDotnetController extends Controller {
}); });
return new HttpSuccess(filteredPosMasters); return new HttpSuccess(filteredPosMasters);
} }
/**
* API profileId
* @summary API profileId
*/
@Post("check-isLeave")
@Security("internalAuth")
async findProfileIsLeave(
@Body()
req: { profileIds: string[] }
) {
const profile = await this.profileRepo.find({
select: { id: true },
where: {
id: In(req.profileIds),
isLeave: true
}
});
if (profile.length === 0) {
return new HttpSuccess([]);
}
return new HttpSuccess(profile.map(p => p.id));
}
} }

View file

@ -93,6 +93,7 @@ import { CreatePosMasterHistoryOfficer, getTopDegrees, getPosMasterPositions } f
import { ProfileLeaveService } from "../services/ProfileLeaveService"; import { ProfileLeaveService } from "../services/ProfileLeaveService";
// import { PostRetireToExprofile } from "./ExRetirementController"; // import { PostRetireToExprofile } from "./ExRetirementController";
import { getPosNumCodeSit } from "../services/CommandService"; import { getPosNumCodeSit } from "../services/CommandService";
import { updateHolderProfileHistory } from "../services/PositionService";
@Route("api/v1/org/profile") @Route("api/v1/org/profile")
@Tags("Profile") @Tags("Profile")
@Security("bearerAuth") @Security("bearerAuth")
@ -5774,29 +5775,26 @@ export class ProfileController extends Controller {
} }
if (body.citizenId) { if (body.citizenId) {
const citizenIdDigits = body.citizenId.toString().split("").map(Number); Extension.CheckCitizen(body.citizenId);
const cal =
citizenIdDigits[0] * 13 +
citizenIdDigits[1] * 12 +
citizenIdDigits[2] * 11 +
citizenIdDigits[3] * 10 +
citizenIdDigits[4] * 9 +
citizenIdDigits[5] * 8 +
citizenIdDigits[6] * 7 +
citizenIdDigits[7] * 6 +
citizenIdDigits[8] * 5 +
citizenIdDigits[9] * 4 +
citizenIdDigits[10] * 3 +
citizenIdDigits[11] * 2;
const calStp2 = cal % 11;
const chkDigit = (11 - calStp2) % 10;
if (citizenIdDigits[12] !== chkDigit) {
throw new HttpError(HttpStatus.NOT_FOUND, "ข้อมูลรหัสบัตรประจำตัวประชาชนไม่ถูกต้อง");
}
} }
const record = await this.profileRepo.findOneBy({ id }); const record = await this.profileRepo.findOneBy({ id });
const before = structuredClone(record); const before = structuredClone(record);
// เช็คว่ามี profileHistory ของ profile นี้หรือไม่
const historyCount = await this.profileHistoryRepo.count({
where: { profileId: id },
});
// ถ้าไม่มีเลย ให้บันทึกข้อมูลเริ่มต้น (ก่อน update) ลงไปก่อน
if (historyCount === 0) {
await this.profileHistoryRepo.save(
Object.assign(new ProfileHistory(), {
...before,
birthDateOld: before?.birthDate,
profileId: id,
id: undefined,
}),
);
}
if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลโปรไฟล์นี้"); if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลโปรไฟล์นี้");
@ -5833,6 +5831,9 @@ export class ProfileController extends Controller {
} }
} }
// บันทึกประวัติคนครองตำแหน่ง (ถ้า profile นี้ครองตำแหน่งอยู่)
await updateHolderProfileHistory(record.id, request);
return new HttpSuccess(); return new HttpSuccess();
} }
@ -7950,40 +7951,38 @@ export class ProfileController extends Controller {
privacyUser: profile.privacyUser, privacyUser: profile.privacyUser,
privacyMgt: profile.privacyMgt, privacyMgt: profile.privacyMgt,
isDeputy: root?.isDeputy ?? false, isDeputy: root?.isDeputy ?? false,
// root?.orgRootShortName && posMaster?.posMasterNo
// ? `${root?.orgRootShortName} ${posMaster?.posMasterNo}`
// : "",
}; };
const _numPart = posMaster ? [posMaster.posMasterNoPrefix, posMaster.posMasterNo, posMaster.posMasterNoSuffix].filter((p) => p !== null && p !== undefined && p !== '').join(' ') : '';
if (_profile.child4Id != null) { if (_profile.child4Id != null) {
_profile.node = 4; _profile.node = 4;
_profile.nodeId = _profile.child4Id; _profile.nodeId = _profile.child4Id;
_profile.nodeDnaId = _profile.child4DnaId; _profile.nodeDnaId = _profile.child4DnaId;
_profile.nodeShortName = _profile.child4ShortName; _profile.nodeShortName = _profile.child4ShortName;
_profile.posNo = `${_profile.child4ShortName} ${_profile.posMasterNo}`; _profile.posNo = `${_profile.child4ShortName} ${_numPart}`;
} else if (_profile.child3Id != null) { } else if (_profile.child3Id != null) {
_profile.node = 3; _profile.node = 3;
_profile.nodeId = _profile.child3Id; _profile.nodeId = _profile.child3Id;
_profile.nodeDnaId = _profile.child3DnaId; _profile.nodeDnaId = _profile.child3DnaId;
_profile.nodeShortName = _profile.child3ShortName; _profile.nodeShortName = _profile.child3ShortName;
_profile.posNo = `${_profile.child3ShortName} ${_profile.posMasterNo}`; _profile.posNo = `${_profile.child3ShortName} ${_numPart}`;
} else if (_profile.child2Id != null) { } else if (_profile.child2Id != null) {
_profile.node = 2; _profile.node = 2;
_profile.nodeId = _profile.child2Id; _profile.nodeId = _profile.child2Id;
_profile.nodeDnaId = _profile.child2DnaId; _profile.nodeDnaId = _profile.child2DnaId;
_profile.nodeShortName = _profile.child2ShortName; _profile.nodeShortName = _profile.child2ShortName;
_profile.posNo = `${_profile.child2ShortName} ${_profile.posMasterNo}`; _profile.posNo = `${_profile.child2ShortName} ${_numPart}`;
} else if (_profile.child1Id != null) { } else if (_profile.child1Id != null) {
_profile.node = 1; _profile.node = 1;
_profile.nodeId = _profile.child1Id; _profile.nodeId = _profile.child1Id;
_profile.nodeDnaId = _profile.child1DnaId; _profile.nodeDnaId = _profile.child1DnaId;
_profile.nodeShortName = _profile.child1ShortName; _profile.nodeShortName = _profile.child1ShortName;
_profile.posNo = `${_profile.child1ShortName} ${_profile.posMasterNo}`; _profile.posNo = `${_profile.child1ShortName} ${_numPart}`;
} else if (_profile.rootId != null) { } else if (_profile.rootId != null) {
_profile.node = 0; _profile.node = 0;
_profile.nodeId = _profile.rootId; _profile.nodeId = _profile.rootId;
_profile.nodeDnaId = _profile.rootDnaId; _profile.nodeDnaId = _profile.rootDnaId;
_profile.nodeShortName = _profile.rootShortName; _profile.nodeShortName = _profile.rootShortName;
_profile.posNo = `${_profile.rootShortName} ${_profile.posMasterNo}`; _profile.posNo = `${_profile.rootShortName} ${_numPart}`;
} }
return new HttpSuccess(_profile); return new HttpSuccess(_profile);
} }
@ -8123,41 +8122,39 @@ export class ProfileController extends Controller {
privacyUser: profile.privacyUser, privacyUser: profile.privacyUser,
privacyMgt: profile.privacyMgt, privacyMgt: profile.privacyMgt,
isDeputy: root?.isDeputy ?? false, isDeputy: root?.isDeputy ?? false,
// root?.orgRootShortName && posMaster?.posMasterNo
// ? `${root?.orgRootShortName} ${posMaster?.posMasterNo}`
// : "",
}; };
const _numPart = posMaster ? [posMaster.posMasterNoPrefix, posMaster.posMasterNo, posMaster.posMasterNoSuffix].filter((p) => p !== null && p !== undefined && p !== '').join(' ') : '';
if (_profile.child4Id != null) { if (_profile.child4Id != null) {
_profile.node = 4; _profile.node = 4;
_profile.nodeId = _profile.child4Id; _profile.nodeId = _profile.child4Id;
_profile.nodeDnaId = _profile.child4DnaId; _profile.nodeDnaId = _profile.child4DnaId;
_profile.nodeShortName = _profile.child4ShortName; _profile.nodeShortName = _profile.child4ShortName;
_profile.posNo = `${_profile.child4ShortName} ${posMaster?.posMasterNo}`; _profile.posNo = `${_profile.child4ShortName} ${_numPart}`;
} else if (_profile.child3Id != null) { } else if (_profile.child3Id != null) {
_profile.node = 3; _profile.node = 3;
_profile.nodeId = _profile.child3Id; _profile.nodeId = _profile.child3Id;
_profile.nodeDnaId = _profile.child3DnaId; _profile.nodeDnaId = _profile.child3DnaId;
_profile.nodeShortName = _profile.child3ShortName; _profile.nodeShortName = _profile.child3ShortName;
_profile.posNo = `${_profile.child3ShortName} ${posMaster?.posMasterNo}`; _profile.posNo = `${_profile.child3ShortName} ${_numPart}`;
} else if (_profile.child2Id != null) { } else if (_profile.child2Id != null) {
_profile.node = 2; _profile.node = 2;
_profile.nodeId = _profile.child2Id; _profile.nodeId = _profile.child2Id;
_profile.nodeDnaId = _profile.child2DnaId; _profile.nodeDnaId = _profile.child2DnaId;
_profile.nodeShortName = _profile.child2ShortName; _profile.nodeShortName = _profile.child2ShortName;
_profile.posNo = `${_profile.child2ShortName} ${posMaster?.posMasterNo}`; _profile.posNo = `${_profile.child2ShortName} ${_numPart}`;
} else if (_profile.child1Id != null) { } else if (_profile.child1Id != null) {
_profile.node = 1; _profile.node = 1;
_profile.nodeId = _profile.child1Id; _profile.nodeId = _profile.child1Id;
_profile.nodeDnaId = _profile.child1DnaId; _profile.nodeDnaId = _profile.child1DnaId;
_profile.nodeShortName = _profile.child1ShortName; _profile.nodeShortName = _profile.child1ShortName;
_profile.posNo = `${_profile.child1ShortName} ${posMaster?.posMasterNo}`; _profile.posNo = `${_profile.child1ShortName} ${_numPart}`;
} else if (_profile.rootId != null) { } else if (_profile.rootId != null) {
_profile.node = 0; _profile.node = 0;
_profile.nodeId = _profile.rootId; _profile.nodeId = _profile.rootId;
_profile.nodeDnaId = _profile.rootDnaId; _profile.nodeDnaId = _profile.rootDnaId;
_profile.nodeShortName = _profile.rootShortName; _profile.nodeShortName = _profile.rootShortName;
_profile.posNo = `${_profile.rootShortName} ${posMaster?.posMasterNo}`; _profile.posNo = `${_profile.rootShortName} ${_numPart}`;
} }
return new HttpSuccess(_profile); return new HttpSuccess(_profile);
} }
@ -9328,26 +9325,32 @@ export class ProfileController extends Controller {
: "-", : "-",
}; };
const _numPart = posMaster ? [posMaster.posMasterNoPrefix, posMaster.posMasterNo, posMaster.posMasterNoSuffix].filter((p) => p !== null && p !== undefined && p !== '').join(' ') : '';
if (_profile.child4Id != null) { if (_profile.child4Id != null) {
_profile.node = 4; _profile.node = 4;
_profile.nodeId = _profile.child4Id; _profile.nodeId = _profile.child4Id;
_profile.nodeShortName = _profile.child4ShortName; _profile.nodeShortName = _profile.child4ShortName;
_profile.posNo = `${_profile.child4ShortName} ${_numPart}`;
} else if (_profile.child3Id != null) { } else if (_profile.child3Id != null) {
_profile.node = 3; _profile.node = 3;
_profile.nodeId = _profile.child3Id; _profile.nodeId = _profile.child3Id;
_profile.nodeShortName = _profile.child3ShortName; _profile.nodeShortName = _profile.child3ShortName;
_profile.posNo = `${_profile.child3ShortName} ${_numPart}`;
} else if (_profile.child2Id != null) { } else if (_profile.child2Id != null) {
_profile.node = 2; _profile.node = 2;
_profile.nodeId = _profile.child2Id; _profile.nodeId = _profile.child2Id;
_profile.nodeShortName = _profile.child2ShortName; _profile.nodeShortName = _profile.child2ShortName;
_profile.posNo = `${_profile.child2ShortName} ${_numPart}`;
} else if (_profile.child1Id != null) { } else if (_profile.child1Id != null) {
_profile.node = 1; _profile.node = 1;
_profile.nodeId = _profile.child1Id; _profile.nodeId = _profile.child1Id;
_profile.nodeShortName = _profile.child1ShortName; _profile.nodeShortName = _profile.child1ShortName;
_profile.posNo = `${_profile.child1ShortName} ${_numPart}`;
} else if (_profile.rootId != null) { } else if (_profile.rootId != null) {
_profile.node = 0; _profile.node = 0;
_profile.nodeId = _profile.rootId; _profile.nodeId = _profile.rootId;
_profile.nodeShortName = _profile.rootShortName; _profile.nodeShortName = _profile.rootShortName;
_profile.posNo = `${_profile.rootShortName} ${_numPart}`;
} }
return new HttpSuccess(_profile); return new HttpSuccess(_profile);
} }
@ -9528,38 +9531,28 @@ export class ProfileController extends Controller {
const mapDataProfile = await Promise.all( const mapDataProfile = await Promise.all(
findProfile.map(async (item: Profile) => { findProfile.map(async (item: Profile) => {
const fullName = `${item.prefix}${item.firstName} ${item.lastName}`; const fullName = `${item.prefix}${item.firstName} ${item.lastName}`;
const shortName = const holder = item.current_holders?.find((x) => x.orgRevisionId == findRevision.id);
item.current_holders.length == 0 const _numPart = holder ? [holder.posMasterNoPrefix, holder.posMasterNo, holder.posMasterNoSuffix].filter((p) => p !== null && p !== undefined && p !== '').join(' ') : '';
? null const shortName = !holder
: item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && ? null
item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4 != : holder.orgChild4 != null
null ? `${holder.orgChild4.orgChild4ShortName} ${_numPart}`
? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4.orgChild4ShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` : holder.orgChild3 != null
: item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && ? `${holder.orgChild3.orgChild3ShortName} ${_numPart}`
item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3 != : holder.orgChild2 != null
null ? `${holder.orgChild2.orgChild2ShortName} ${_numPart}`
? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3.orgChild3ShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` : holder.orgChild1 != null
: item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && ? `${holder.orgChild1.orgChild1ShortName} ${_numPart}`
item.current_holders.find((x) => x.orgRevisionId == findRevision.id) : holder.orgRoot != null
?.orgChild2 != null ? `${holder.orgRoot.orgRootShortName} ${_numPart}`
? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild2.orgChild2ShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` : null;
: item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null &&
item.current_holders.find((x) => x.orgRevisionId == findRevision.id)
?.orgChild1 != null
? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild1.orgChild1ShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}`
: item.current_holders.find((x) => x.orgRevisionId == findRevision.id) !=
null &&
item.current_holders.find((x) => x.orgRevisionId == findRevision.id)
?.orgRoot != null
? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot.orgRootShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}`
: null;
const root = const root =
item.current_holders.length == 0 || item.current_holders.length == 0 ||
(item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && (holder != null &&
item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot == null) holder?.orgRoot == null)
? null ? null
: item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot; : holder?.orgRoot;
const rootHolder = item.current_holders?.find( const rootHolder = item.current_holders?.find(
(x) => x.orgRevisionId == findRevision.id, (x) => x.orgRevisionId == findRevision.id,

View file

@ -84,6 +84,7 @@ import { ProfileDuty } from "../entities/ProfileDuty";
import { CreatePosMasterHistoryEmployee, getTopDegrees } from "../services/PositionService"; import { CreatePosMasterHistoryEmployee, getTopDegrees } from "../services/PositionService";
import { ProfileLeaveService } from "../services/ProfileLeaveService"; import { ProfileLeaveService } from "../services/ProfileLeaveService";
import { CommandCode } from "../entities/CommandCode"; import { CommandCode } from "../entities/CommandCode";
import { updateHolderProfileHistory } from "../services/PositionService";
@Route("api/v1/org/profile-employee") @Route("api/v1/org/profile-employee")
@Tags("ProfileEmployee") @Tags("ProfileEmployee")
@Security("bearerAuth") @Security("bearerAuth")
@ -2381,28 +2382,27 @@ export class ProfileEmployeeController extends Controller {
} }
if (body.citizenId) { if (body.citizenId) {
const citizenIdDigits = body.citizenId.toString().split("").map(Number); Extension.CheckCitizen(body.citizenId);
const cal =
citizenIdDigits[0] * 13 +
citizenIdDigits[1] * 12 +
citizenIdDigits[2] * 11 +
citizenIdDigits[3] * 10 +
citizenIdDigits[4] * 9 +
citizenIdDigits[5] * 8 +
citizenIdDigits[6] * 7 +
citizenIdDigits[7] * 6 +
citizenIdDigits[8] * 5 +
citizenIdDigits[9] * 4 +
citizenIdDigits[10] * 3 +
citizenIdDigits[11] * 2;
const calStp2 = cal % 11;
const chkDigit = (11 - calStp2) % 10;
if (citizenIdDigits[12] !== chkDigit) {
throw new HttpError(HttpStatus.NOT_FOUND, "ข้อมูลรหัสบัตรประจำตัวประชาชนไม่ถูกต้อง");
}
} }
const record = await this.profileRepo.findOneBy({ id }); const record = await this.profileRepo.findOneBy({ id });
const before = structuredClone(record);
// เช็คว่ามี profileHistory ของ profile นี้หรือไม่
const historyCount = await this.profileHistoryRepo.count({
where: { profileEmployeeId: id },
});
// ถ้าไม่มีเลย ให้บันทึกข้อมูลเริ่มต้น (ก่อน update) ลงไปก่อน
if (historyCount === 0) {
await this.profileHistoryRepo.save(
Object.assign(new ProfileEmployeeHistory(), {
...before,
birthDateOld: before?.birthDate,
profileEmployeeId: id,
id: undefined,
}),
);
}
if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลโปรไฟล์นี้"); if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลโปรไฟล์นี้");
if (body.employeeClass == null || body.employeeClass == undefined || body.employeeClass == "") { if (body.employeeClass == null || body.employeeClass == undefined || body.employeeClass == "") {
@ -2434,6 +2434,8 @@ export class ProfileEmployeeController extends Controller {
}), }),
); );
await this.profileRepo.save(record); await this.profileRepo.save(record);
// บันทึกประวัติคนครองตำแหน่ง (ถ้า profile นี้ครองตำแหน่งอยู่)
await updateHolderProfileHistory(record.id, request, "EMPLOYEE");
return new HttpSuccess(); return new HttpSuccess();
} }
@ -4019,40 +4021,38 @@ export class ProfileEmployeeController extends Controller {
salary: profile ? profile.amount : null, salary: profile ? profile.amount : null,
amountSpecial: profile ? profile.amountSpecial : null, amountSpecial: profile ? profile.amountSpecial : null,
posNo: null, posNo: null,
// root?.orgRootShortName && posMaster?.posMasterNo
// ? `${root?.orgRootShortName} ${posMaster?.posMasterNo}`
// : "",
}; };
const _numPart = posMaster ? [posMaster.posMasterNoPrefix, posMaster.posMasterNo, posMaster.posMasterNoSuffix].filter((p) => p !== null && p !== undefined && p !== '').join(' ') : '';
if (_profile.child4Id != null) { if (_profile.child4Id != null) {
_profile.node = 4; _profile.node = 4;
_profile.nodeId = _profile.child4Id; _profile.nodeId = _profile.child4Id;
_profile.nodeDnaId = _profile.child4DnaId; _profile.nodeDnaId = _profile.child4DnaId;
_profile.nodeShortName = _profile.child4ShortName; _profile.nodeShortName = _profile.child4ShortName;
_profile.posNo = `${_profile.child4ShortName} ${_profile.posMasterNo}`; _profile.posNo = `${_profile.child4ShortName} ${_numPart}`;
} else if (_profile.child3Id != null) { } else if (_profile.child3Id != null) {
_profile.node = 3; _profile.node = 3;
_profile.nodeId = _profile.child3Id; _profile.nodeId = _profile.child3Id;
_profile.nodeDnaId = _profile.child3DnaId; _profile.nodeDnaId = _profile.child3DnaId;
_profile.nodeShortName = _profile.child3ShortName; _profile.nodeShortName = _profile.child3ShortName;
_profile.posNo = `${_profile.child3ShortName} ${_profile.posMasterNo}`; _profile.posNo = `${_profile.child3ShortName} ${_numPart}`;
} else if (_profile.child2Id != null) { } else if (_profile.child2Id != null) {
_profile.node = 2; _profile.node = 2;
_profile.nodeId = _profile.child2Id; _profile.nodeId = _profile.child2Id;
_profile.nodeDnaId = _profile.child2DnaId; _profile.nodeDnaId = _profile.child2DnaId;
_profile.nodeShortName = _profile.child2ShortName; _profile.nodeShortName = _profile.child2ShortName;
_profile.posNo = `${_profile.child2ShortName} ${_profile.posMasterNo}`; _profile.posNo = `${_profile.child2ShortName} ${_numPart}`;
} else if (_profile.child1Id != null) { } else if (_profile.child1Id != null) {
_profile.node = 1; _profile.node = 1;
_profile.nodeId = _profile.child1Id; _profile.nodeId = _profile.child1Id;
_profile.nodeDnaId = _profile.child1DnaId; _profile.nodeDnaId = _profile.child1DnaId;
_profile.nodeShortName = _profile.child1ShortName; _profile.nodeShortName = _profile.child1ShortName;
_profile.posNo = `${_profile.child1ShortName} ${_profile.posMasterNo}`; _profile.posNo = `${_profile.child1ShortName} ${_numPart}`;
} else if (_profile.rootId != null) { } else if (_profile.rootId != null) {
_profile.node = 0; _profile.node = 0;
_profile.nodeId = _profile.rootId; _profile.nodeId = _profile.rootId;
_profile.nodeDnaId = _profile.rootDnaId; _profile.nodeDnaId = _profile.rootDnaId;
_profile.nodeShortName = _profile.rootShortName; _profile.nodeShortName = _profile.rootShortName;
_profile.posNo = `${_profile.rootShortName} ${_profile.posMasterNo}`; _profile.posNo = `${_profile.rootShortName} ${_numPart}`;
} }
return new HttpSuccess(_profile); return new HttpSuccess(_profile);
} }
@ -6460,33 +6460,7 @@ export class ProfileEmployeeController extends Controller {
null null
? null ? null
: profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild4; : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild4;
const shortName = const _numPart = posMaster ? [posMaster.posMasterNoPrefix, posMaster.posMasterNo, posMaster.posMasterNoSuffix].filter((p) => p !== null && p !== undefined && p !== '').join(' ') : '';
profile.current_holders.length == 0
? null
: profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) != null &&
profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)
?.orgChild4 != null
? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild4.orgChild4ShortName} ${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.posMasterNo}`
: profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) != null &&
profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)
?.orgChild3 != null
? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild3.orgChild3ShortName} ${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.posMasterNo}`
: profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) !=
null &&
profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)
?.orgChild2 != null
? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild2.orgChild2ShortName} ${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.posMasterNo}`
: profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) !=
null &&
profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)
?.orgChild1 != null
? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild1.orgChild1ShortName} ${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.posMasterNo}`
: profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) !=
null &&
profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)
?.orgRoot != null
? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgRoot.orgRootShortName} ${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.posMasterNo}`
: null;
const _profile: any = { const _profile: any = {
profileId: profile.id, profileId: profile.id,
prefix: profile.prefix, prefix: profile.prefix,
@ -6528,7 +6502,7 @@ export class ProfileEmployeeController extends Controller {
child4ShortName: child4 == null ? null : child4.orgChild4ShortName, child4ShortName: child4 == null ? null : child4.orgChild4ShortName,
node: null, node: null,
nodeId: null, nodeId: null,
posNo: shortName, posNo: null,
salary: profile.amount, salary: profile.amount,
education: education:
profile && profile.profileEducations.length > 0 profile && profile.profileEducations.length > 0
@ -6543,22 +6517,27 @@ export class ProfileEmployeeController extends Controller {
_profile.node = 4; _profile.node = 4;
_profile.nodeId = _profile.child4Id; _profile.nodeId = _profile.child4Id;
_profile.nodeShortName = _profile.child4ShortName; _profile.nodeShortName = _profile.child4ShortName;
_profile.posNo = `${_profile.child4ShortName} ${_numPart}`;
} else if (_profile.child3Id != null) { } else if (_profile.child3Id != null) {
_profile.node = 3; _profile.node = 3;
_profile.nodeId = _profile.child3Id; _profile.nodeId = _profile.child3Id;
_profile.nodeShortName = _profile.child3ShortName; _profile.nodeShortName = _profile.child3ShortName;
_profile.posNo = `${_profile.child3ShortName} ${_numPart}`;
} else if (_profile.child2Id != null) { } else if (_profile.child2Id != null) {
_profile.node = 2; _profile.node = 2;
_profile.nodeId = _profile.child2Id; _profile.nodeId = _profile.child2Id;
_profile.nodeShortName = _profile.child2ShortName; _profile.nodeShortName = _profile.child2ShortName;
_profile.posNo = `${_profile.child2ShortName} ${_numPart}`;
} else if (_profile.child1Id != null) { } else if (_profile.child1Id != null) {
_profile.node = 1; _profile.node = 1;
_profile.nodeId = _profile.child1Id; _profile.nodeId = _profile.child1Id;
_profile.nodeShortName = _profile.child1ShortName; _profile.nodeShortName = _profile.child1ShortName;
_profile.posNo = `${_profile.child1ShortName} ${_numPart}`;
} else if (_profile.rootId != null) { } else if (_profile.rootId != null) {
_profile.node = 0; _profile.node = 0;
_profile.nodeId = _profile.rootId; _profile.nodeId = _profile.rootId;
_profile.nodeShortName = _profile.rootShortName; _profile.nodeShortName = _profile.rootShortName;
_profile.posNo = `${_profile.rootShortName} ${_numPart}`;
} }
return new HttpSuccess(_profile); return new HttpSuccess(_profile);
} }

View file

@ -1001,6 +1001,24 @@ export class ProfileEmployeeTempController extends Controller {
} }
const record = await this.profileRepo.findOneBy({ id }); const record = await this.profileRepo.findOneBy({ id });
const before = structuredClone(record);
// เช็คว่ามี profileHistory ของ profile นี้หรือไม่
const historyCount = await this.profileHistoryRepo.count({
where: { profileEmployeeId: id },
});
// ถ้าไม่มีเลย ให้บันทึกข้อมูลเริ่มต้น (ก่อน update) ลงไปก่อน
if (historyCount === 0) {
await this.profileHistoryRepo.save(
Object.assign(new ProfileEmployeeHistory(), {
...before,
birthDateOld: before?.birthDate,
profileEmployeeId: id,
id: undefined,
}),
);
}
if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลโปรไฟล์นี้"); if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลโปรไฟล์นี้");
if (body.employeeClass == null || body.employeeClass == undefined || body.employeeClass == "") { if (body.employeeClass == null || body.employeeClass == undefined || body.employeeClass == "") {

View file

@ -326,7 +326,7 @@ export async function removeProfileInOrganize(profileId: string, type: string) {
await AppDataSource.getRepository(EmployeePosMaster) await AppDataSource.getRepository(EmployeePosMaster)
.createQueryBuilder() .createQueryBuilder()
.update(EmployeePosMaster) .update(EmployeePosMaster)
.set({ current_holderId: null }) .set({ current_holderId: null, isSit: false })
.where("id = :id", { id: findProfileInEmpPosMaster?.id }) .where("id = :id", { id: findProfileInEmpPosMaster?.id })
.execute(); .execute();
@ -395,43 +395,6 @@ export async function checkReturnCommandType(commandId: string) {
return true; return true;
} }
export async function checkExceptCommandType(commandId: string) {
const commandRepository = AppDataSource.getRepository(Command);
const commandReciveRepository = AppDataSource.getRepository(CommandRecive);
const _type = await commandRepository.findOne({
where: {
id: commandId,
},
relations: ["commandType"],
});
if (!["C-PM-25", "C-PM-26"].includes(String(_type?.commandType.code))) {
return { status: false, LeaveType: null, leaveRemark: null };
}
const _commandRecive = await commandReciveRepository.findOne({
where: { commandId: commandId },
});
let _leaveType: string = "";
switch (String(_type?.commandType.code)) {
case "C-PM-25": {
_leaveType = "DISCIPLINE_SUSPEND"; //คำสั่งพักจากราชการ
break;
}
case "C-PM-26": {
_leaveType = "DISCIPLINE_TEMP_SUSPEND"; //คำสั่งให้ออกจากราชการไว้ก่อน
break;
}
default: {
_leaveType = "";
}
}
return {
status: true,
LeaveType: _leaveType,
leaveRemark: _commandRecive ? _commandRecive.remarkVertical : null,
};
}
export async function checkCommandType(commandId: string) { export async function checkCommandType(commandId: string) {
const commandRepository = AppDataSource.getRepository(Command); const commandRepository = AppDataSource.getRepository(Command);
const commandReciveRepository = AppDataSource.getRepository(CommandRecive); const commandReciveRepository = AppDataSource.getRepository(CommandRecive);
@ -451,6 +414,8 @@ export async function checkCommandType(commandId: string) {
"C-PM-23", "C-PM-23",
"C-PM-19", "C-PM-19",
"C-PM-20", "C-PM-20",
"C-PM-25",
"C-PM-26",
"C-PM-43", "C-PM-43",
].includes(String(_type?.commandType.code)) ].includes(String(_type?.commandType.code))
) { ) {
@ -500,6 +465,16 @@ export async function checkCommandType(commandId: string) {
_retireTypeName = "ลาออกจากราชการ"; _retireTypeName = "ลาออกจากราชการ";
break; break;
} }
case "C-PM-25": {
_leaveType = "DISCIPLINE_SUSPEND";
_retireTypeName = "พักจากราชการ";
break;
}
case "C-PM-26": {
_leaveType = "DISCIPLINE_TEMP_SUSPEND";
_retireTypeName = "ให้ออกจากราชการไว้ก่อน";
break;
}
case "C-PM-43": { case "C-PM-43": {
_leaveType = "RETIRE_OUT_EMP"; _leaveType = "RETIRE_OUT_EMP";
_retireTypeName = "ให้ออกจากราชการ"; _retireTypeName = "ให้ออกจากราชการ";

View file

@ -19,7 +19,7 @@ export async function handleInternalAuth(request: express.Request) {
throw new HttpError(HttpStatus.UNAUTHORIZED, "Invalid API Key"); throw new HttpError(HttpStatus.UNAUTHORIZED, "Invalid API Key");
} }
console.log(`[InternalAuth] Authentication successful`); // console.log(`[InternalAuth] Authentication successful`);
return { return {
sub: "internal_service", sub: "internal_service",