Merge branch 'develop' of github.com:Frappet/bma-ehr-organization into develop

This commit is contained in:
Warunee Tamkoo 2025-03-05 17:35:57 +07:00
commit 9fa83891f2
10 changed files with 539 additions and 149 deletions

View file

@ -12,37 +12,19 @@ import { RegisterRoutes } from "./routes";
import { OrganizationController } from "./controllers/OrganizationController";
import logMiddleware from "./middlewares/logs";
import { CommandController } from "./controllers/CommandController";
// import { WebSocketServer } from "ws";
// import http from "http";
// export const wss = new WebSocketServer({ noServer: true });
// export const wss = new WebSocketServer({
// port: 8080,
// perMessageDeflate: {
// zlibDeflateOptions: {
// // See zlib defaults.
// chunkSize: 1024,
// memLevel: 7,
// level: 3
// },
// zlibInflateOptions: {
// chunkSize: 10 * 1024
// },
// // Other options settable:
// clientNoContextTakeover: true, // Defaults to negotiated value.
// serverNoContextTakeover: true, // Defaults to negotiated value.
// serverMaxWindowBits: 10, // Defaults to negotiated value.
// // Below options specified as default values.
// concurrencyLimit: 10, // Limits zlib concurrency for perf.
// threshold: 1024 // Size (in bytes) below which messages
// // should not be compressed if context takeover is disabled.
// }
// });
// export const wss = new WebSocketServer({ noServer: true,
// path: "/api/v1/org/socket",
// });
async function main() {
await AppDataSource.initialize();
const app = express();
// สร้างเซิร์ฟเวอร์ HTTP
// const server = http.createServer(app);
app.use(
@ -94,23 +76,6 @@ async function main() {
}
});
// การจัดการคำขออัปเกรดจาก HTTP เป็น WebSocket
// server.on("upgrade", (request:any, socket:any, head:any) => {
// console.log("🔹 Handling upgrade request...");
// wss.handleUpgrade(request, socket, head, (ws:any) => {
// console.log("🔹 WebSocket connection established");
// wss.emit("connection", ws, request);
// });
// });
// wss.on("connection", (ws:any) => {
// console.log("✅ Client connected to WebSocket");
// ws.on("close", () => {
// console.log("❌ Client disconnected");
// });
// });
// app.listen(APP_PORT, APP_HOST, () => console.log(`Listening on: http://localhost:${APP_PORT}`));
app.listen(
APP_PORT,
@ -131,11 +96,35 @@ async function main() {
runMessageQueue();
// สร้างเซิร์ฟเวอร์ HTTP
// การจัดการคำขออัปเกรดจาก HTTP เป็น WebSocket
// server.on("upgrade", (request:any, socket:any, head:any) => {
// console.log("🔹 Handling upgrade request...");
// wss.handleUpgrade(request, socket, head, (ws:any) => {
// console.log("🔹 WebSocket connection established");
// wss.emit("connection", ws, request);
// });
// });
// wss.on("connection", (ws:any) => {
// console.log("✅ Client connected to WebSocket");
// เริ่มเซิร์ฟเวอร์ที่พอร์ตปัจจุบัน
// server.listen(8080, () => {
// ws.on("close", () => {
// console.log("❌ Client disconnected");
// });
// ws.on("error", (error:any) => {
// console.error("WebSocket error:", error);
// });
// });
// // ตั้งค่า Express routes
// app.get('/', (req, res) => {
// res.send('Hello from Express!');
// });
// server.listen(APP_PORT, APP_HOST, () => {
// console.log(`[APP] Application is running on: http://${APP_HOST}:${APP_PORT}`);
// console.log(`[APP] Swagger on: http://${APP_HOST}:${APP_PORT}/api-docs`);
// console.log("[APP] HTTP Server is listening on current port");
// });

View file

@ -236,23 +236,23 @@ export class ProfileController extends Controller {
let _child4 = child4 == null || child4 == undefined ? "" : `${child4.orgChild4Name}/`;
const salary_raw = await this.salaryRepo.find({
select: [
"commandDateAffect",
"positionName",
"posNo",
"positionType",
"positionLevel",
"positionSalaryAmount",
"commandNo",
"amount",
"remark",
"orgRoot",
"orgChild1",
"orgChild2",
"orgChild3",
"orgChild4",
"positionExecutive",
],
// select: [
// "commandDateAffect",
// "positionName",
// "posNo",
// "positionType",
// "positionLevel",
// "positionSalaryAmount",
// "commandNo",
// "amount",
// "remark",
// "orgRoot",
// "orgChild1",
// "orgChild2",
// "orgChild3",
// "orgChild4",
// "positionExecutive",
// ],
where: {
profileId: id,
commandCode: In(["1", "2", "3", "4", "8", "10", "11", "12", "15", "16"]),
@ -266,7 +266,11 @@ export class ProfileController extends Controller {
date: item.commandDateAffect
? Extension.ToThaiNumber(Extension.ToThaiShortDate(item.commandDateAffect))
: null,
position: item.positionName != null ? item.positionName : "-",
position: Extension.ToThaiNumber(
Extension.ToThaiNumber(
`${item.positionName != null ? item.positionName : "-"} ${item.positionType == null ? item.positionCee : (item.positionType == "อำนวยการ" || item.positionType == "บริหาร" ? item.positionType : "") + item.positionLevel}`,
),
),
posNo: item.posNo != null ? Extension.ToThaiNumber(item.posNo) : null,
orgRoot: item.orgRoot,
orgChild1: item.orgChild1,
@ -349,7 +353,11 @@ export class ProfileController extends Controller {
: "",
position:
salary_raw.length > 0 && salary_raw[0].positionName != null
? Extension.ToThaiNumber(Extension.ToThaiNumber(salary_raw[0].positionName))
? Extension.ToThaiNumber(
Extension.ToThaiNumber(
`${salary_raw[0].positionName != null ? salary_raw[0].positionName : "-"} ${salary_raw[0].positionType == null ? salary_raw[0].positionCee : (salary_raw[0].positionType == "อำนวยการ" || salary_raw[0].positionType == "บริหาร" ? salary_raw[0].positionType : "") + salary_raw[0].positionLevel}`,
),
)
: "",
positionCee:
salary_raw.length > 0 && salary_raw[0].positionCee != null
@ -1156,7 +1164,11 @@ export class ProfileController extends Controller {
"amount",
"remark",
],
where: { profileId: id },
where: {
profileId: id,
commandCode: In(["5","6"]),
isEntry: false
},
order: { order: "ASC" },
});
@ -1313,7 +1325,11 @@ export class ProfileController extends Controller {
];
const position_raw = await this.salaryRepo.find({
where: { profileId: id },
where: {
profileId: id,
commandCode: In(["1", "2", "3", "4", "8", "10", "11", "12", "15", "16"]),
isEntry: false
},
order: { order: "ASC" },
});
const positionList =
@ -1342,7 +1358,6 @@ export class ProfileController extends Controller {
{
commandDateAffect: "-",
commandDateSign: "-",
refCommandNo: "-",
posNo: "-",
position: "-",
posType: "-",
@ -1441,49 +1456,48 @@ export class ProfileController extends Controller {
const profileAbility =
profileAbility_raw.length > 0
? profileAbility_raw.map((item) => ({
field: item.field ? item.field : "",
detail: item.detail ? item.detail : "",
}))
: [
{
field: "-",
detail: "-",
},
];
const sum = profiles
? Extension.ToThaiNumber(
(
Number(profiles.amount) +
Number(profiles.positionSalaryAmount) +
Number(profiles.mouthSalaryAmount) +
Number(profiles.amountSpecial)
).toLocaleString(),
)
: "";
const fullCurrentAddress = profiles
? Extension.ToThaiNumber(
profiles.currentAddress +
" ตำบล/แขวง " +
profiles.currentSubDistrict.name +
" อำเภอ/เขต " +
profiles.currentDistrict.name +
" จังหวัด " +
profiles.currentProvince.name +
profiles.currentZipCode,
)
: "";
const fullRegistrationAddress = profiles
? Extension.ToThaiNumber(
profiles.registrationAddress +
" ตำบล/แขวง " +
profiles.registrationSubDistrict.name +
" อำเภอ/เขต " +
profiles.registrationDistrict.name +
" จังหวัด " +
profiles.registrationProvince.name +
profiles.registrationZipCode,
)
: "";
field: item.field?item.field:"",
detail: item.detail?item.detail:"",
}))
: [
{
field: "-",
detail: "-",
},
];
const otherIncome_raw = await this.salaryRepo.find({
where: {
profileId: id,
commandCode: "7",
isEntry: false
},
order: { order: "ASC" },
});
const otherIncome =
otherIncome_raw.length > 0
? otherIncome_raw.map((item) => ({
commandDateAffect: item.commandDateAffect?Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.commandDateAffect)):"",
commandDateSign: item.commandDateSign?Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.commandDateSign)):"",
commandNo: item.commandNo?Extension.ToThaiNumber(item.commandNo):"",
position: item.positionName,
posLevel: item.positionLevel?Extension.ToThaiNumber(item.positionLevel):"",
amount: item.amount?Extension.ToThaiNumber(Number(item.amount).toLocaleString()):"",
}))
: [
{
commandDateAffect: "-",
commandDateSign: "-",
commandNo: "-",
position: "-",
posLevel: "-",
amount: "-",
},
];
const sum = profiles?Extension.ToThaiNumber((Number(profiles.amount) + Number(profiles.positionSalaryAmount) + Number(profiles.mouthSalaryAmount) + Number(profiles.amountSpecial)).toLocaleString()):"";
const fullCurrentAddress = profiles?Extension.ToThaiNumber(profiles.currentAddress + " ตำบล/แขวง " + profiles.currentSubDistrict.name + " อำเภอ/เขต " + profiles.currentDistrict.name + " จังหวัด " + profiles.currentProvince.name + profiles.currentZipCode):"";
const fullRegistrationAddress = profiles?Extension.ToThaiNumber(profiles.registrationAddress + " ตำบล/แขวง " + profiles.registrationSubDistrict.name + " อำเภอ/เขต " + profiles.registrationDistrict.name + " จังหวัด " + profiles.registrationProvince.name + profiles.registrationZipCode):"";
const data = {
fullName: `${profiles?.prefix}${profiles?.firstName} ${profiles?.lastName}`,
prefix: profiles?.prefix != null ? profiles.prefix : "",
@ -1627,6 +1641,7 @@ export class ProfileController extends Controller {
duty,
assessments,
profileAbility,
otherIncome
};
return new HttpSuccess({

View file

@ -228,24 +228,24 @@ export class ProfileEmployeeController extends Controller {
let _child4 = child4 == null || child4 == undefined ? "" : `${child4.orgChild4Name}/`;
const salary_raw = await this.salaryRepo.find({
select: [
"commandDateAffect",
"posNo",
"positionType",
"positionLevel",
"positionSalaryAmount",
"commandNo",
"amount",
"remark",
"positionName",
"orgRoot",
"orgChild1",
"orgChild2",
"orgChild3",
"orgChild4",
"positionCee",
"positionExecutive",
],
// select: [
// "commandDateAffect",
// "posNo",
// "positionType",
// "positionLevel",
// "positionSalaryAmount",
// "commandNo",
// "amount",
// "remark",
// "positionName",
// "orgRoot",
// "orgChild1",
// "orgChild2",
// "orgChild3",
// "orgChild4",
// "positionCee",
// "positionExecutive",
// ],
where: {
profileEmployeeId: id,
commandCode: In(["1", "2", "3", "4", "8", "10", "11", "12", "15", "16"]),
@ -258,7 +258,11 @@ export class ProfileEmployeeController extends Controller {
date: item.commandDateAffect
? Extension.ToThaiNumber(Extension.ToThaiShortDate(item.commandDateAffect))
: null,
position: item.positionName != null ? item.positionName : "-",
position: Extension.ToThaiNumber(
Extension.ToThaiNumber(
`${item.positionName != null ? item.positionName : "-"} ${item.positionType == null ? item.positionCee : (item.positionType == "อำนวยการ" || item.positionType == "บริหาร" ? item.positionType : "") + item.positionLevel}`,
),
),
posNo: item.posNo != null ? Extension.ToThaiNumber(item.posNo) : null,
orgRoot: item.orgRoot,
orgChild1: item.orgChild1,
@ -341,7 +345,11 @@ export class ProfileEmployeeController extends Controller {
: "",
position:
salary_raw.length > 0 && salary_raw[0].positionName != null
? Extension.ToThaiNumber(Extension.ToThaiNumber(salary_raw[0].positionName))
? Extension.ToThaiNumber(
Extension.ToThaiNumber(
`${salary_raw[0].positionName != null ? salary_raw[0].positionName : "-"} ${salary_raw[0].positionType == null ? salary_raw[0].positionCee : (salary_raw[0].positionType == "อำนวยการ" || salary_raw[0].positionType == "บริหาร" ? salary_raw[0].positionType : "") + salary_raw[0].positionLevel}`,
),
)
: "",
positionCee:
salary_raw.length > 0 && salary_raw[0].positionCee != null

View file

@ -223,24 +223,24 @@ export class ProfileEmployeeTempController extends Controller {
let _child4 = child4 == null || child4 == undefined ? "" : `${child4.orgChild4Name}/`;
const salary_raw = await this.salaryRepo.find({
select: [
"commandDateAffect",
"positionName",
"posNo",
"positionType",
"positionLevel",
"positionSalaryAmount",
"commandNo",
"amount",
"remark",
"orgRoot",
"orgChild1",
"orgChild2",
"orgChild3",
"orgChild4",
"positionCee",
"positionExecutive",
],
// select: [
// "commandDateAffect",
// "positionName",
// "posNo",
// "positionType",
// "positionLevel",
// "positionSalaryAmount",
// "commandNo",
// "amount",
// "remark",
// "orgRoot",
// "orgChild1",
// "orgChild2",
// "orgChild3",
// "orgChild4",
// "positionCee",
// "positionExecutive",
// ],
where: {
profileEmployeeId: id,
commandCode: In(["1", "2", "3", "4", "8", "10", "11", "12", "15", "16"]),
@ -253,7 +253,11 @@ export class ProfileEmployeeTempController extends Controller {
date: item.commandDateAffect
? Extension.ToThaiNumber(Extension.ToThaiShortDate(item.commandDateAffect))
: null,
position: item.positionName != null ? item.positionName : "-",
position: Extension.ToThaiNumber(
Extension.ToThaiNumber(
`${item.positionName != null ? item.positionName : "-"} ${item.positionType == null ? item.positionCee : (item.positionType == "อำนวยการ" || item.positionType == "บริหาร" ? item.positionType : "") + item.positionLevel}`,
),
),
posNo: item.posNo != null ? Extension.ToThaiNumber(item.posNo) : null,
orgRoot: item.orgRoot,
orgChild1: item.orgChild1,
@ -335,7 +339,11 @@ export class ProfileEmployeeTempController extends Controller {
: "",
position:
salary_raw.length > 0 && salary_raw[0].positionName != null
? Extension.ToThaiNumber(Extension.ToThaiNumber(salary_raw[0].positionName))
? Extension.ToThaiNumber(
Extension.ToThaiNumber(
`${salary_raw[0].positionName != null ? salary_raw[0].positionName : "-"} ${salary_raw[0].positionType == null ? salary_raw[0].positionCee : (salary_raw[0].positionType == "อำนวยการ" || salary_raw[0].positionType == "บริหาร" ? salary_raw[0].positionType : "") + salary_raw[0].positionLevel}`,
),
)
: "",
positionCee:
salary_raw.length > 0 && salary_raw[0].positionCee != null

View file

@ -22,6 +22,10 @@ import { Profile } from "../entities/Profile";
import { In, LessThan, MoreThan } from "typeorm";
import permission from "../interfaces/permission";
import { setLogDataDiff } from "../interfaces/utils";
import { TenurePositionOfficer } from "../entities/TenurePositionOfficer";
import { TenureLevelOfficer } from "../entities/TenureLevelOfficer";
import { TenurePositionEmployee } from "../entities/TenurePositionEmployee";
import { TenureLevelEmployee } from "../entities/TenureLevelEmployee";
@Route("api/v1/org/profile/salary")
@Tags("ProfileSalary")
@Security("bearerAuth")
@ -29,7 +33,54 @@ export class ProfileSalaryController extends Controller {
private profileRepo = AppDataSource.getRepository(Profile);
private salaryRepo = AppDataSource.getRepository(ProfileSalary);
private salaryHistoryRepo = AppDataSource.getRepository(ProfileSalaryHistory);
private positionOfficerRepo = AppDataSource.getRepository(TenurePositionOfficer);
private levelOfficerRepo = AppDataSource.getRepository(TenureLevelOfficer);
// async cronjobTenurePositionOfficer() {
@Get("XXX")
public async cronjobTenurePositionOfficer() {
let data: any = [];
const profile = await this.profileRepo.find({where:{id: "09e89026-c420-4136-bd9e-7e408f530b69"}})
await Promise.all(
profile.map(async (x) => {
const sql_mode = await AppDataSource.query(
"SET SESSION sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));",
);
const position = await AppDataSource.query("CALL GetProfileSalaryPosition(?)", [x.id]);
const _position = position.length > 0 ? position[0] : [];
const mapPosition =
_position.length > 1
? _position.slice(1)
.map((curr: any, index: number) => ({
days_diff: curr.days_diff,
positionName: _position[index]?.positionName,
}))
: [];
const calDayDiff = mapPosition
.filter((curr: any) => curr.positionName == x.position)
.reduce(
(acc: any, curr: any) => {
acc.days_diff += Number(curr.days_diff) || 0;
return acc;
},
{ days_diff: 0}
);
console.log("==========> ", calDayDiff)
const _mapData = {
profileId: x.id,
positionName: x.position,
days_diff: null,
Years: null,
Months: null,
Days: null,
}
data.push(_mapData);
})
// await this.positionOfficerRepo.save(data);
);
return new HttpSuccess();
}
@Get("user")
public async getSalaryUser(@Request() request: { user: Record<string, any> }) {
const profile = await this.profileRepo.findOneBy({ keycloak: request.user.sub });

View file

@ -31,6 +31,7 @@ import { Profile } from "../entities/Profile";
import { viewRegistryOfficer } from "../entities/view/viewRegistryOfficer";
import { viewRegistryEmployee } from "../entities/view/viewRegistryEmployee";
import { EmployeeTempPosMaster } from "../entities/EmployeeTempPosMaster";
// import { WebSocket } from "ws";
// import { wss } from "../app";
@ -3577,7 +3578,7 @@ export class ReportController extends Controller {
// }
// });
return new HttpSuccess({ template: "report2", reportName: "report2", data: { data } });
return new HttpSuccess({ template: "report2", reportName: "report2", data: { data } });
}
/**

View file

@ -0,0 +1,88 @@
import {
Entity,
Column,
OneToMany,
JoinColumn,
ManyToOne,
Double,
ManyToMany,
JoinTable,
} from "typeorm";
import { EntityBase } from "./base/Base";
@Entity("tenureLevelEmployee")
export class TenureLevelEmployee extends EntityBase {
@Column({
nullable: true,
length: 40,
comment: "คีย์นอก(FK)ของตาราง profileEmployee",
default: null,
})
profileEmployeeId: string;
@Column({
nullable: true,
comment: "ระดับซี",
default: null,
length: 255,
})
positionCee: string;
@Column({
nullable: true,
comment: "จำนวนวัน",
default: null,
})
days_diff: number;
@Column({
nullable: true,
comment: "จำนวนปีดำรงตำแหน่งงปัจจุบัน",
default: null,
})
Years: number;
@Column({
nullable: true,
comment: "จำนวนเดือนดำรงตำแหน่งงปัจจุบัน",
default: null,
})
Months: number;
@Column({
nullable: true,
comment: "จำนวนวันดำรงตำแหน่งงปัจจุบัน",
default: null,
})
Days: number;
@Column({
nullable: true,
comment: "ชื่อประเภทตำแหน่ง",
default: null,
length: 255,
})
positionType: string;
@Column({
nullable: true,
comment: "ชื่อระดับตำแหน่ง",
default: null,
length: 255,
})
positionLevel: string;
}
export class CreateTenureLevelOfficer {
profileEmployeeId: string;
positionCee: string | null;
days_diff: number | null;
Years: number | null;
Months: number | null;
Days: number | null;
positionType: string | null;
positionLevel: string | null;
}

View file

@ -0,0 +1,88 @@
import {
Entity,
Column,
OneToMany,
JoinColumn,
ManyToOne,
Double,
ManyToMany,
JoinTable,
} from "typeorm";
import { EntityBase } from "./base/Base";
@Entity("tenureLevelOfficer")
export class TenureLevelOfficer extends EntityBase {
@Column({
nullable: true,
length: 40,
comment: "คีย์นอก(FK)ของตาราง Profile",
default: null,
})
profileId: string;
@Column({
nullable: true,
comment: "ระดับซี",
default: null,
length: 255,
})
positionCee: string;
@Column({
nullable: true,
comment: "จำนวนวัน",
default: null,
})
days_diff: number;
@Column({
nullable: true,
comment: "จำนวนปีดำรงตำแหน่งงปัจจุบัน",
default: null,
})
Years: number;
@Column({
nullable: true,
comment: "จำนวนเดือนดำรงตำแหน่งงปัจจุบัน",
default: null,
})
Months: number;
@Column({
nullable: true,
comment: "จำนวนวันดำรงตำแหน่งงปัจจุบัน",
default: null,
})
Days: number;
@Column({
nullable: true,
comment: "ชื่อประเภทตำแหน่ง",
default: null,
length: 255,
})
positionType: string;
@Column({
nullable: true,
comment: "ชื่อระดับตำแหน่ง",
default: null,
length: 255,
})
positionLevel: string;
}
export class CreateTenureLevelOfficer {
profileId: string;
positionCee: string | null;
days_diff: number | null;
Years: number | null;
Months: number | null;
Days: number | null;
positionType: string | null;
positionLevel: string | null;
}

View file

@ -0,0 +1,71 @@
import {
Entity,
Column,
OneToMany,
JoinColumn,
ManyToOne,
Double,
ManyToMany,
JoinTable,
} from "typeorm";
import { EntityBase } from "./base/Base";
@Entity("tenurePositionEmployee")
export class TenurePositionEmployee extends EntityBase {
@Column({
nullable: true,
length: 40,
comment: "คีย์นอก(FK)ของตาราง ProfileEmployee",
default: null,
})
profileEmployeeId: string;
@Column({
nullable: true,
comment: "ชื่อตำแหน่ง",
default: null,
length: 255,
})
positionName: string;
@Column({
nullable: true,
comment: "จำนวนวัน",
default: null,
})
days_diff: number;
@Column({
nullable: true,
comment: "จำนวนปีดำรงตำแหน่งงปัจจุบัน",
default: null,
})
Years: number;
@Column({
nullable: true,
comment: "จำนวนเดือนดำรงตำแหน่งงปัจจุบัน",
default: null,
})
Months: number;
@Column({
nullable: true,
comment: "จำนวนวันดำรงตำแหน่งงปัจจุบัน",
default: null,
})
Days: number;
}
export class CreateTenurePositionEmployee {
profileEmployeeId: string;
positionName: string | null;
days_diff: number | null;
Years: number | null;
Months: number | null;
Days: number | null;
}

View file

@ -0,0 +1,71 @@
import {
Entity,
Column,
OneToMany,
JoinColumn,
ManyToOne,
Double,
ManyToMany,
JoinTable,
} from "typeorm";
import { EntityBase } from "./base/Base";
@Entity("tenurePositionOfficer")
export class TenurePositionOfficer extends EntityBase {
@Column({
nullable: true,
length: 40,
comment: "คีย์นอก(FK)ของตาราง Profile",
default: null,
})
profileId: string;
@Column({
nullable: true,
comment: "ชื่อตำแหน่ง",
default: null,
length: 255,
})
positionName: string;
@Column({
nullable: true,
comment: "จำนวนวัน",
default: null,
})
days_diff: number;
@Column({
nullable: true,
comment: "จำนวนปีดำรงตำแหน่งงปัจจุบัน",
default: null,
})
Years: number;
@Column({
nullable: true,
comment: "จำนวนเดือนดำรงตำแหน่งงปัจจุบัน",
default: null,
})
Months: number;
@Column({
nullable: true,
comment: "จำนวนวันดำรงตำแหน่งงปัจจุบัน",
default: null,
})
Days: number;
}
export class CreateTenurePositionOfficer {
profileId: string;
positionName: string | null;
days_diff: number | null;
Years: number | null;
Months: number | null;
Days: number | null;
}