hrms-mgt/src/modules/04_registryPerson/views/edit/components/DialogForm.vue
DESKTOP-1R2VSQH\Lenovo ThinkPad E490 688a54205f fix
2025-05-20 16:34:07 +07:00

535 lines
20 KiB
Vue

<script setup lang="ts">
import { ref, reactive, onMounted, nextTick, watch } from "vue";
import { useQuasar } from "quasar";
import { useCounterMixin } from "@/stores/mixin";
import { useEditPosDataStore } from "@/modules/04_registryPerson/stores/Edit";
import http from "@/plugins/http";
import config from "@/app.config";
import type { DataOption } from "@/modules/04_registryPerson/interface/index/Main";
import type { DataPosition } from "@/modules/04_registryPerson/interface/response/Edit";
import type { FormDataSalary } from "@/modules/04_registryPerson/interface/request/Edit";
import type {
DataCommandCode,
DataPosType,
DataPosLevel,
DataPosPosition,
DataPosExecutive,
} from "@/modules/04_registryPerson/interface/response/Position";
import DialogHeader from "@/components/DialogHeader.vue";
import FormPosition from "@/modules/04_registryPerson/views/edit/components/FormPosition.vue";
const $q = useQuasar();
const {
dialogConfirm,
showLoader,
hideLoader,
messageError,
success,
convertDateToAPI,
} = useCounterMixin();
const store = useEditPosDataStore();
const modal = defineModel<boolean>("modal", { required: true });
const empType = defineModel<string>("empType", { required: true });
const rowData = defineModel<DataPosition[]>("rowData", { required: true });
const rowIndex = defineModel<number>("rowIndex", { required: true });
const props = defineProps({
fetchData: { type: Function, required: true },
});
const formData = reactive<FormDataSalary>({
commandCode: "", //ประเภทคำสั่ง
commandNo: "", //เลขที่คำสั่ง
commandYear: null, //ปี
commandDateAffect: null, //วันที่มีผล
commandDateSign: null, //วันที่ลงนาม
posNoAbb: "", //ตัวย่อเลขที่ตำแหน่ง
posNo: "", //เลขที่ตำแหน่ง
positionName: "", //ตำแหน่ง
positionType: "", //ประเภทตำแหน่ง | กลุ่มงาน
positionLevel: "", //ระดับตำแหน่ง | ระดับชั้นงาน
positionCee: "", //ตำแหน่งซี
positionLine: "", // สายงาน
positionPathSide: "", //ด้าน/สาขา
positionExecutive: "", //ตำแหน่งทางการบริหาร
amount: null, //เงินเดือน
amountSpecial: null, //เงินค่าตอบแทนพิเศษ
positionSalaryAmount: null, //เงินประจำตำแหน่ง
mouthSalaryAmount: null, //เงินค่าตอบแทนรายเดือน
orgRoot: "", //หน่วยงาน
orgChild1: "", //ส่วนราชการระดับ 1
orgChild2: "", //ส่วนราชการระดับ 2
orgChild3: "", //ส่วนราชการระดับ 3
orgChild4: "", //ส่วนราชการระดับ 4
remark: "", //หมายเหตุ
posNumCodeSit: "", //หน่วยงานที่ออกคำสั่ง
posNumCodeSitAbb: "", //ตัวย่อหน่วยงานที่ออกคำสั่ง
});
const formReadonly = reactive<FormDataSalary>({
commandCode: "", //ประเภทคำสั่ง
commandNo: "", //เลขที่คำสั่ง
commandYear: null, //ปี
commandDateAffect: null, //วันที่มีผล
commandDateSign: null, //วันที่ลงนาม
posNoAbb: "", //ตัวย่อเลขที่ตำแหน่ง
posNo: "", //เลขที่ตำแหน่ง
positionName: "", //ตำแหน่ง
positionType: "", //ประเภทตำแหน่ง | กลุ่มงาน
positionLevel: "", //ระดับตำแหน่ง | ระดับชั้นงาน
positionCee: "", //ตำแหน่งซี
positionLine: "", // สายงาน
positionPathSide: "", //ด้าน/สาขา
positionExecutive: "", //ตำแหน่งทางการบริหาร
amount: null, //เงินเดือน
amountSpecial: null, //เงินค่าตอบแทนพิเศษ
positionSalaryAmount: null, //เงินประจำตำแหน่ง
mouthSalaryAmount: null, //เงินค่าตอบแทนรายเดือน
orgRoot: "", //หน่วยงาน
orgChild1: "", //ส่วนราชการระดับ 1
orgChild2: "", //ส่วนราชการระดับ 2
orgChild3: "", //ส่วนราชการระดับ 3
orgChild4: "", //ส่วนราชการระดับ 4
remark: "", //หมายเหตุ
posNumCodeSit: "", //หน่วยงานที่ออกคำสั่ง
posNumCodeSitAbb: "", //ตัวย่อหน่วยงานที่ออกคำสั่ง
});
const dataLevel = ref<DataPosType[]>([]); //รายการ ตำแหน่งเงินเดือน
const commandCodeOptions = ref<DataOption[]>(store.commandCodeData); //รายการปรเภทคำสั่ง
const posTypeOptions = ref<DataOption[]>(store.posTypeData); //รายการประเภทตำแหน่ง | กลุ่มงาน
const posLevelOptions = ref<DataOption[]>(store.posLevelData); //รายการระดับตำแหน่ง | ระดับชั้นงาน
const posLineOptions = ref<DataOption[]>(store.posLineData); //รายการสายงาน
const posPathSideOptions = ref<DataOption[]>(store.posPathSideData); //รายการด้าน/สาขา
const posExecutiveOptions = ref<DataOption[]>(store.posExecutiveData); //รายการตำแหน่งทางการบริหาร
const salaryId = ref<string>("");
/** function เรียกข้อมูลตำแหน่ง*/
async function fetchDataPosition() {
try {
showLoader();
const res = await http.get(
config.API.salaryTemp + `/get/${salaryId.value}`
);
return res.data.result;
} catch (err) {
messageError($q, err);
} finally {
hideLoader();
}
}
/** function fetch ข้อมูลประเภทคำสั่ง*/
async function fetchDataCommandCode() {
// เช็ค store.commandCodeData มีค่ามากกว่า 0 รีเทินร์ false
if (store.commandCodeData.length > 0) return false;
await http
.get(config.API.orgCommandCode)
.then((res) => {
const data = res.data.result;
store.commandCodeData = data.map((e: DataCommandCode) => ({
id: e.code.toString(),
name: e.name,
}));
commandCodeOptions.value = store.commandCodeData;
})
.catch((err) => {
messageError($q, err);
});
}
/** function fetch ข้อมูลปรเภทตำแหน่งข้าราชการ */
async function fetchType() {
await http
.get(config.API.orgPosType)
.then((res) => {
dataLevel.value = res.data.result;
store.posTypeData = res.data.result.map((e: DataPosType) => ({
id: e.id,
name: e.posTypeName,
}));
posTypeOptions.value = store.posTypeData;
})
.catch((err) => {
messageError($q, err);
});
}
/** function fetch ข้อมูลปรเภทตำแหน่งลูกจ้าง*/
async function fetchOptionGroup() {
await http
.get(config.API.orgEmployeeType)
.then((res) => {
dataLevel.value = res.data.result;
store.posTypeData = res.data.result.map((e: DataPosType) => ({
id: e.id,
name: e.posTypeName,
}));
posTypeOptions.value = store.posTypeData;
})
.catch((err) => {
messageError($q, err);
});
}
/** function fetch ข้อมูลสายงาน*/
async function fetchDataOption() {
if (store.posLineData.length > 0 && store.posPathSideData.length > 0)
return false;
await http
.get(config.API.orgPosPosition + `?keyword=&type=ALL`)
.then((res) => {
const data = res.data.result;
const seen = new Set();
const seen2 = new Set();
const listPositionField = data.filter((item: DataPosPosition) => {
if (seen.has(item.positionField)) {
return false;
} else {
seen.add(item.positionField);
return true;
}
});
store.posLineData = listPositionField.map((e: DataPosPosition) => ({
id: e.positionField,
name: e.positionField,
}));
const listPositionArea = data.filter((item: DataPosPosition) => {
if (
item.positionArea === null ||
item.positionArea === "" ||
item.positionArea === "-" ||
seen2.has(item.positionArea)
) {
return false;
} else {
seen2.add(item.positionArea);
return true;
}
});
store.posPathSideData = listPositionArea.map((e: DataPosPosition) => ({
id: e.positionArea,
name: e.positionArea,
}));
})
.catch((err) => {
messageError($q, err);
});
}
/** function fetch ข้อมูลตำแหน่งข้อมูลทางการบริหาร*/
async function fetchDataOptionExecutive() {
await http
.get(config.API.orgPosExecutive)
.then((res) => {
const data = res.data.result;
store.posExecutiveData = data.map((e: DataPosExecutive) => ({
id: e.posExecutiveName,
name: e.posExecutiveName,
}));
})
.catch((e) => {
messageError($q, e);
});
}
/**
* function เลือกประเภทตำแหน่ง
* @param val id ประเภทตำแหน่ง
* @param status แก่ไข , เพิ่ม
*/
async function updateSelectType(val: string, status: boolean = false) {
const listLevel = val
? dataLevel.value.find((e: DataPosType) => e.posTypeName === val)
: null;
if (listLevel) {
store.posLevelData = listLevel.posLevels.map((e: DataPosLevel) => ({
id: e.id,
name:
empType.value === "officer"
? e.posLevelName
: `${listLevel.posTypeShortName} ${e.posLevelName}`,
}));
formData.positionLevel = !status ? "" : formData.positionLevel;
} else {
store.posLevelData = [];
formData.positionLevel = "";
}
}
/**
* function กำหนดข้อมูล
* @param index รายการที่ต้องการดู
*/
async function onDefineData(index: number) {
// ดึงข้อมูลจาก rowData ตามตำแหน่ง index ที่รับมา
const data = rowData.value[index];
// กำหนดค่า salaryId ให้เป็น id ของข้อมูลตาม Index
salaryId.value = data.id;
// เรียก function fetchDataPosition เรียกข้อมูลตำแหน่ง
const newData = await fetchDataPosition();
// อัปเดตค่าประเภทตำแหน่งงาน
updateSelectType(data.positionType);
if (newData) {
const salaryNew = newData.salaryNew;
const salaryOld = newData.salaryOld;
formData.commandCode = salaryNew.commandCode;
formData.commandNo = salaryNew.commandNo;
formData.commandYear = salaryNew.commandYear;
formData.commandDateAffect = salaryNew.commandDateAffect;
formData.commandDateSign = salaryNew.commandDateSign;
formData.posNoAbb = salaryNew.posNoAbb;
formData.posNo = salaryNew.posNo;
formData.positionName = salaryNew.positionName;
formData.positionType = salaryNew.positionType;
formData.positionLevel = salaryNew.positionLevel;
formData.positionCee = salaryNew.positionCee;
formData.positionLine = salaryNew.positionLine;
formData.positionPathSide = salaryNew.positionPathSide;
formData.positionExecutive = salaryNew.positionExecutive;
formData.amount = salaryNew.amount;
formData.amountSpecial = salaryNew.amountSpecial;
formData.positionSalaryAmount = salaryNew.positionSalaryAmount;
formData.mouthSalaryAmount = salaryNew.mouthSalaryAmount;
formData.orgRoot = salaryNew.orgRoot;
formData.orgChild1 = salaryNew.orgChild1;
formData.orgChild2 = salaryNew.orgChild2;
formData.orgChild3 = salaryNew.orgChild3;
formData.orgChild4 = salaryNew.orgChild4;
formData.remark = salaryNew.remark;
formData.posNumCodeSit = salaryNew.posNumCodeSit;
formData.posNumCodeSitAbb = salaryNew.posNumCodeSitAbb;
formReadonly.commandCode = salaryOld.commandCode;
formReadonly.commandNo = salaryOld.commandNo;
formReadonly.commandYear = salaryOld.commandYear;
formReadonly.commandDateAffect = salaryOld.commandDateAffect;
formReadonly.commandDateSign = salaryOld.commandDateSign;
formReadonly.posNoAbb = salaryOld.posNoAbb;
formReadonly.posNo = salaryOld.posNo;
formReadonly.positionName = salaryOld.positionName;
formReadonly.positionType = salaryOld.positionType;
formReadonly.positionLevel = salaryOld.positionLevel;
formReadonly.positionCee = salaryOld.positionCee;
formReadonly.positionLine = salaryOld.positionLine;
formReadonly.positionPathSide = salaryOld.positionPathSide;
formReadonly.positionExecutive = salaryOld.positionExecutive;
formReadonly.amount = salaryOld.amount;
formReadonly.positionSalaryAmount = salaryOld.positionSalaryAmount;
formReadonly.mouthSalaryAmount = salaryOld.mouthSalaryAmount;
formReadonly.orgRoot = salaryOld.orgRoot;
formReadonly.orgChild1 = salaryOld.orgChild1;
formReadonly.orgChild2 = salaryOld.orgChild2;
formReadonly.orgChild3 = salaryOld.orgChild3;
formReadonly.orgChild4 = salaryOld.orgChild4;
formReadonly.remark = salaryOld.remark;
formReadonly.posNumCodeSit = salaryOld.posNumCodeSit;
formReadonly.posNumCodeSitAbb = salaryOld.posNumCodeSitAbb;
}
}
async function onNavigateRow(action: string) {
action === "next" ? (rowIndex.value += 1) : (rowIndex.value -= 1);
await nextTick();
onDefineData(rowIndex.value);
}
function onClickCloseDialog() {
modal.value = false;
}
function onSubmit() {
console.log(formData);
dialogConfirm($q, async () => {
showLoader();
await http
.patch(config.API.salaryTemp + `/${salaryId.value}`, {
...formData,
type: empType.value?.toLocaleUpperCase(),
commandDateAffect: convertDateToAPI(formData.commandDateAffect),
commandDateSign: convertDateToAPI(formData.commandDateSign),
amount: Number(String(formData.amount)?.replace(/,/g, "")),
amountSpecial: Number(
String(formData.amountSpecial)?.replace(/,/g, "")
),
positionSalaryAmount: Number(
String(formData.positionSalaryAmount)?.replace(/,/g, "")
),
mouthSalaryAmount: Number(
String(formData.mouthSalaryAmount)?.replace(/,/g, "")
),
})
.then(async () => {
await props.fetchData?.();
success($q, "บันทึกข้อมูลสำเร็จ");
onClickCloseDialog();
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
});
}
watch(modal, async (val) => {
if (val) {
showLoader();
if (empType.value === "officer") {
await Promise.all([
fetchType(),
// fetchDataOption(),
// fetchDataOptionExecutive(),
]);
} else {
await fetchOptionGroup();
}
commandCodeOptions.value = store.commandCodeData;
posTypeOptions.value = store.posTypeData;
posLevelOptions.value = store.posLevelData;
posLineOptions.value = store.posLineData;
posPathSideOptions.value = store.posPathSideData;
posExecutiveOptions.value = store.posExecutiveData;
await onDefineData(rowIndex.value);
hideLoader();
}
});
onMounted(async () => {
await fetchDataCommandCode();
});
</script>
<template>
<q-dialog v-model="modal" persistent full-width>
<q-card>
<q-form greedy @submit.prevent @validation-success="onSubmit">
<DialogHeader
:tittle="'แก้ไขตำแหน่ง/เงินเดือน'"
:close="onClickCloseDialog"
/>
<q-separator />
<q-card-section style="padding: 0px">
<div class="col-12 row">
<div class="col-xs-12 col-md-6 row no-wrap">
<div class="col-12 q-pa-md">
<q-card
bordered
class="col-12"
style="border: 1px solid #d6dee1"
>
<div
class="col-12 text-weight-medium bg-grey-1 q-py-xs q-px-md"
>
อมลป
</div>
<div class="col-12"><q-separator /></div>
<q-card-section>
<FormPosition
:is-readonly="true"
:form-data="formReadonly"
:command-code-options="commandCodeOptions"
:pos-type-options="posTypeOptions"
:pos-level-options="posLevelOptions"
:pos-line-options="posLineOptions"
:pos-path-side-options="posPathSideOptions"
:pos-executive-options="posExecutiveOptions"
:emp-type="empType"
:update-select-type="updateSelectType"
/>
</q-card-section>
</q-card>
</div>
<div class="col-12 row">
<q-separator :vertical="!$q.screen.lt.md" />
</div>
</div>
<div class="col-xs-12 col-md-6 row">
<div class="col-12 q-pa-md">
<q-card
bordered
class="col-12"
style="border: 1px solid #d6dee1"
>
<div
class="col-12 text-weight-medium bg-grey-1 q-py-xs q-px-md"
>
อมลทแกไข
</div>
<div class="col-12">
<q-separator />
<q-card-section>
<FormPosition
:is-readonly="false"
v-model:form-data="formData"
v-model:command-code-options="commandCodeOptions"
v-model:pos-type-options="posTypeOptions"
v-model:pos-level-options="posLevelOptions"
v-model:pos-line-options="posLineOptions"
v-model:pos-path-side-options="posPathSideOptions"
v-model:pos-executive-options="posExecutiveOptions"
:emp-type="empType"
:update-select-type="updateSelectType"
/>
</q-card-section>
</div>
</q-card>
</div>
</div>
</div>
</q-card-section>
<q-separator />
<q-card-actions align="right">
<q-btn
flat
round
:disable="rowIndex === 0"
:color="rowIndex === 0 ? 'grey' : 'public'"
icon="mdi-chevron-left"
@click.stop.pervent="onNavigateRow('previous')"
>
<q-tooltip>อมลกอนหน</q-tooltip>
</q-btn>
<q-btn
flat
round
:disable="rowIndex + 1 === rowData.length"
:color="rowIndex + 1 === rowData.length ? 'grey' : 'public'"
icon="mdi-chevron-right"
@click.stop.pervent="onNavigateRow('next')"
>
<q-tooltip>อมลถดไป</q-tooltip>
</q-btn>
<q-btn label="บันทึก" id="onSubmit" type="submit" color="public">
<q-tooltip>นทกขอม</q-tooltip>
</q-btn>
</q-card-actions>
</q-form>
</q-card>
</q-dialog>
</template>
<style scoped></style>