588 lines
20 KiB
Vue
588 lines
20 KiB
Vue
<script setup lang="ts">
|
|
import { ref, reactive, watch } from "vue";
|
|
import { useQuasar } from "quasar";
|
|
import http from "@/plugins/http";
|
|
import config from "@/app.config";
|
|
|
|
/** importType*/
|
|
import type {
|
|
DataOptions,
|
|
DataListOptions,
|
|
} from "@/modules/13_salary/interface/index/EmployeeChart";
|
|
|
|
/** importComponents*/
|
|
import Header from "@/components/DialogHeader.vue";
|
|
|
|
/** importStore*/
|
|
import { useCounterMixin } from "@/stores/mixin";
|
|
|
|
const $q = useQuasar();
|
|
const { dialogConfirm, showLoader, hideLoader, messageError, success } =
|
|
useCounterMixin();
|
|
|
|
/** props*/
|
|
const modal = defineModel<boolean>("modal", { required: true });
|
|
const actionsType = defineModel<string>("actionsType", { default: "" });
|
|
const isEdit = defineModel<boolean>("isStatusEdit", { required: true });
|
|
const props = defineProps({
|
|
data: {
|
|
type: Object,
|
|
defult: [],
|
|
},
|
|
getDataMain: Function,
|
|
});
|
|
|
|
const posTypeOp = ref<DataOptions[]>([]);
|
|
const posTypeOpMain = ref<DataOptions[]>([]);
|
|
const posNameOp = ref<DataOptions[]>([]);
|
|
const posNameOpMain = ref<DataOptions[]>([]);
|
|
const groupOldOp = ref<DataOptions[]>([]);
|
|
const groupOldOpMain = ref<DataOptions[]>([]);
|
|
const posLevelOp = ref<any[]>([]);
|
|
const posNameListOp = ref<DataListOptions[]>([]);
|
|
const isReadonly = ref<boolean>(false);
|
|
|
|
const formData = reactive<any>({
|
|
id: "",
|
|
posType: "", //กลุ่มงาน
|
|
posName: "", //ตำแหน่ง
|
|
posLevel: "", //ระดับชั้นงาน
|
|
reson: "", //หมายเหตุ
|
|
rateOldMin: "", //อัตราค่าจ้าง ขั้นต่ำสุด
|
|
groupOld: null, //อัตราค่าจ้าง กลุ่มบัญชีค่าจ้าง
|
|
rateMaxOld: "", //อัตราค่าจ้าง ขั้นสูงสุดเดิม
|
|
groupRateHigh: "", //อัตราค่าจ้างสูงกว่าฯ กลุ่มบัญชีค่าจ่าง
|
|
rateHighMax: "", //อัตราค่าจ้างสูงกว่าฯ ขั้นสูงใหม่
|
|
});
|
|
|
|
/** function ปืด Dialog*/
|
|
function closeDialog() {
|
|
modal.value = !modal.value;
|
|
clearFormData();
|
|
}
|
|
|
|
/** function เคลียข้อมูล form*/
|
|
function clearFormData() {
|
|
isEdit.value = false;
|
|
formData.posType = "";
|
|
formData.posName = "";
|
|
formData.posLevel = "";
|
|
formData.reson = "";
|
|
formData.rateOldMin = "";
|
|
formData.groupOld = null;
|
|
formData.rateMaxOld = "";
|
|
formData.groupRateHigh = "";
|
|
formData.rateHighMax = "";
|
|
}
|
|
|
|
/** function บันทึกข้อมูลหลักเกณฑ์*/
|
|
function onSubmit() {
|
|
dialogConfirm($q, async () => {
|
|
showLoader();
|
|
const body = {
|
|
posTypeId: formData.posType.id,
|
|
position: formData.posName,
|
|
posLevelId: formData.posLevel.id,
|
|
details: formData.reson,
|
|
salaryMin:
|
|
typeof formData.rateOldMin === "string"
|
|
? Number(formData.rateOldMin.replace(/,/g, ""))
|
|
: formData.rateOldMin,
|
|
salaryEmployeeMinIds: formData.groupOld.map(
|
|
(group: DataOptions) => group.id
|
|
),
|
|
salary:
|
|
typeof formData.rateMaxOld === "string"
|
|
? Number(formData.rateMaxOld.replace(/,/g, ""))
|
|
: formData.rateMaxOld,
|
|
salaryEmployeeId: formData.groupRateHigh,
|
|
salaryMax:
|
|
typeof formData.rateHighMax === "string"
|
|
? Number(formData.rateHighMax.replace(/,/g, ""))
|
|
: formData.rateHighMax,
|
|
};
|
|
|
|
const url = !isEdit.value
|
|
? config.API.salaryFormula()
|
|
: config.API.salaryFormulaById(formData.id);
|
|
await http[!isEdit.value ? "post" : "put"](url, body)
|
|
.then(async () => {
|
|
await props.getDataMain?.();
|
|
await success($q, "บันทึกข้อมูลสำเร็จ");
|
|
closeDialog();
|
|
})
|
|
.catch((e) => {
|
|
messageError($q, e);
|
|
})
|
|
.finally(() => {
|
|
hideLoader();
|
|
});
|
|
});
|
|
}
|
|
|
|
/** ดึงข้อมูล กลุ่มงาน */
|
|
function getPosType() {
|
|
http
|
|
.get(config.API.salaryEmployeePosType())
|
|
.then((res) => {
|
|
const dataOp = res.data.result;
|
|
const option = dataOp.map((item: any) => ({
|
|
id: item.id,
|
|
name: item.posTypeName,
|
|
}));
|
|
posTypeOpMain.value = option;
|
|
posTypeOp.value = option;
|
|
})
|
|
.catch((e) => {
|
|
messageError($q, e);
|
|
});
|
|
}
|
|
|
|
/** ดึงข้อมูล ตำแหน่ง */
|
|
function getPosName() {
|
|
if (formData.posType) {
|
|
formData.posName = "";
|
|
formData.posLevel = "";
|
|
http
|
|
.get(config.API.salaryEmployeePositionType(formData.posType.name))
|
|
.then((res) => {
|
|
const dataOp = res.data.result;
|
|
posNameListOp.value = res.data.result;
|
|
posNameOpMain.value = [
|
|
...new Map(
|
|
dataOp.map((i: DataListOptions) => [i.posDictName, i])
|
|
).values(),
|
|
].map((i: any) => ({
|
|
id: i.id,
|
|
name: i.posDictName,
|
|
}));
|
|
})
|
|
.catch((e) => {
|
|
messageError($q, e);
|
|
});
|
|
}
|
|
}
|
|
|
|
/** ดึงข้อมูล ตำแหน่ง */
|
|
function getPosNameEdit() {
|
|
showLoader();
|
|
http
|
|
.get(config.API.salaryEmployeePositionType(formData.posType.name))
|
|
.then((res) => {
|
|
const dataOp = res.data.result;
|
|
posNameListOp.value = res.data.result;
|
|
posNameOpMain.value = [
|
|
...new Map(
|
|
dataOp.map((i: DataListOptions) => [i.posDictName, i])
|
|
).values(),
|
|
].map((i: any) => ({
|
|
id: i.id,
|
|
name: i.posDictName,
|
|
}));
|
|
})
|
|
.catch((e) => {
|
|
messageError($q, e);
|
|
})
|
|
.finally(() => {
|
|
hideLoader();
|
|
});
|
|
}
|
|
|
|
/** ดึงข้อมูล ระดับชั้นงาน */
|
|
function getPosLevel() {
|
|
formData.posLevel = "";
|
|
posLevelOp.value = posNameListOp.value
|
|
.filter((item) => item.posDictName === formData.posName)
|
|
.map((i) => ({ id: i.posLevelId, name: i.posLevelName }))
|
|
.sort((a, b) => a.name - b.name);
|
|
if (posLevelOp.value.length == 1) {
|
|
formData.posLevel = posLevelOp.value[0];
|
|
}
|
|
}
|
|
|
|
/** ดึงข้อมูล ระดับชั้นงาน */
|
|
function getPosLevelEdit() {
|
|
posLevelOp.value = posNameListOp.value
|
|
.filter((item) => item.posDictName === formData.posName)
|
|
.map((i) => ({ id: i.posLevelId, name: i.posLevelName }))
|
|
.sort((a, b) => a.name - b.name);
|
|
if (posLevelOp.value.length == 1) {
|
|
formData.posLevel = posLevelOp.value[0];
|
|
}
|
|
}
|
|
|
|
/** ดึงข้อมูล กลุ่ม */
|
|
function getSalaryGroup() {
|
|
http
|
|
.get(config.API.salaryEmployeeActive())
|
|
.then((res) => {
|
|
const list = res.data.result;
|
|
const data = list.sort((a: any, b: any) => a.group - b.group);
|
|
const option = data.map((item: any) => ({
|
|
id: item.id,
|
|
name: `กลุ่มที่ ${item.group}`,
|
|
}));
|
|
groupOldOp.value = option;
|
|
groupOldOpMain.value = option;
|
|
})
|
|
.catch((e) => {
|
|
messageError($q, e);
|
|
});
|
|
}
|
|
|
|
/** function fetch ข้อมูลหลักเกณฑ์ */
|
|
function getDataEdit() {
|
|
showLoader();
|
|
http
|
|
.get(config.API.salaryFormula() + `/${formData.id}`)
|
|
.then(async (res) => {
|
|
const data = res.data.result;
|
|
formData.posType = posTypeOp.value.find(
|
|
(a: any) => a.id == data.posTypeId
|
|
);
|
|
formData.posName = data.position;
|
|
getPosNameEdit();
|
|
setTimeout(() => {
|
|
getPosLevelEdit();
|
|
formData.posLevel = posLevelOp.value.find(
|
|
(item: any) => item.id == data.posLevelId
|
|
);
|
|
formData.reson = data.details;
|
|
formData.rateOldMin = data.salaryMin;
|
|
formData.groupOld = groupOldOp.value.filter((b: any) =>
|
|
data.salaryEmployeeMinIds.includes(b.id)
|
|
);
|
|
formData.rateMaxOld = data.salary;
|
|
formData.groupRateHigh = data.salaryEmployeeId;
|
|
formData.rateHighMax = data.salaryMax;
|
|
}, 200);
|
|
})
|
|
.catch(() => {})
|
|
.finally(() => {
|
|
setTimeout(() => {
|
|
hideLoader();
|
|
}, 1500);
|
|
});
|
|
}
|
|
watch(
|
|
() => modal.value,
|
|
(check) => {
|
|
if (check) {
|
|
getPosType();
|
|
getSalaryGroup();
|
|
|
|
if (isEdit.value) {
|
|
isReadonly.value = actionsType.value === "view" ? true : false;
|
|
formData.id = props.data?.id ? props.data.id : null;
|
|
getDataEdit();
|
|
} else {
|
|
isReadonly.value = false;
|
|
}
|
|
}
|
|
}
|
|
);
|
|
|
|
/**
|
|
* function ต้นหาข้อมูลของ Option
|
|
* @param val ค่าที่ต้องการฟิลเตอร์
|
|
* @param update อัพเดทค่า
|
|
* @param refData ดาต้าที่ต้องการฟิลเตอร์
|
|
*/
|
|
function filterOption(val: any, update: Function, type: string) {
|
|
switch (type) {
|
|
case "group":
|
|
update(() => {
|
|
formData.posType = "";
|
|
posTypeOp.value = posTypeOpMain.value.filter(
|
|
(v: any) => v.name.indexOf(val) > -1
|
|
);
|
|
});
|
|
break;
|
|
case "pos":
|
|
update(() => {
|
|
formData.posName = "";
|
|
posNameOp.value = posNameOpMain.value.filter(
|
|
(v: any) => v.name.indexOf(val) > -1
|
|
);
|
|
});
|
|
break;
|
|
case "groupOld":
|
|
update(() => {
|
|
groupOldOp.value = groupOldOpMain.value.filter(
|
|
(v: any) => v.name.indexOf(val) > -1
|
|
);
|
|
});
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* class จัดรูปแบบแสดงระหว่างข้อมูลที่แก้ไขหรือแสดงเฉยๆ
|
|
* @param val ข้อมูล input สำหรับแก้ไขหรือไม่
|
|
*/
|
|
const getClass = (val: boolean) => {
|
|
return {
|
|
"full-width inputgreen cursor-pointer": val,
|
|
"full-width cursor-pointer": !val,
|
|
};
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<q-dialog v-model="modal" persistent>
|
|
<q-card class="col-12" style="width: 80%">
|
|
<q-form greedy @submit.prevent @validation-success="onSubmit">
|
|
<Header
|
|
:tittle="
|
|
isEdit && actionsType === 'view'
|
|
? 'รายละเอียด'
|
|
: isEdit
|
|
? 'แก้ไขหลักเกณฑ์'
|
|
: 'เพิ่มหลักเกณฑ์'
|
|
"
|
|
:close="closeDialog"
|
|
/>
|
|
<q-separator />
|
|
<q-card-section>
|
|
<div class="row q-gutter-sm q-pa-sm">
|
|
<div class="row col-xs-12 col-md-12 q-col-gutter-sm">
|
|
<div class="col-4">
|
|
<q-select
|
|
ref="posTypeRef"
|
|
:class="getClass(!isReadonly)"
|
|
:readonly="isReadonly"
|
|
dense
|
|
outlined
|
|
v-model="formData.posType"
|
|
label="กลุ่มงาน"
|
|
:rules="[(val) => !!val || 'กรุณาเลือกกลุ่มงาน']"
|
|
:options="posTypeOp"
|
|
option-label="name"
|
|
option-value="id"
|
|
map-options
|
|
lazy-rules
|
|
hide-bottom-space
|
|
use-input
|
|
@update:model-value="getPosName()"
|
|
@filter="(inputValue:string,doneFn:Function) => filterOption(inputValue, doneFn,'group') "
|
|
>
|
|
<template v-slot:no-option>
|
|
<q-item>
|
|
<q-item-section class="text-grey">
|
|
ไม่มีข้อมูล
|
|
</q-item-section>
|
|
</q-item>
|
|
</template></q-select
|
|
>
|
|
</div>
|
|
<div class="col-4">
|
|
<q-select
|
|
ref="posNameRef"
|
|
:class="getClass(!isReadonly)"
|
|
:readonly="isReadonly || formData.posType"
|
|
dense
|
|
outlined
|
|
v-model="formData.posName"
|
|
label="ตำแหน่ง"
|
|
:rules="[(val) => !!val || 'กรุณาเลือกตำแหน่ง']"
|
|
:options="posNameOp"
|
|
option-label="name"
|
|
option-value="name"
|
|
emit-value
|
|
lazy-rules
|
|
use-input
|
|
@filter="(inputValue:string,doneFn:Function) => filterOption(inputValue, doneFn,'pos')"
|
|
hide-bottom-space
|
|
@update:model-value="getPosLevel()"
|
|
>
|
|
<template v-slot:no-option>
|
|
<q-item>
|
|
<q-item-section class="text-grey">
|
|
ไม่มีข้อมูล
|
|
</q-item-section>
|
|
</q-item>
|
|
</template>
|
|
</q-select>
|
|
</div>
|
|
<div class="col-4">
|
|
<q-select
|
|
:class="getClass(!isReadonly)"
|
|
:readonly="isReadonly || formData.posName"
|
|
ref="posLevelRef"
|
|
dense
|
|
outlined
|
|
v-model="formData.posLevel"
|
|
:options="posLevelOp"
|
|
option-label="name"
|
|
option-value="id"
|
|
map-options
|
|
label="ระดับชั้นงาน"
|
|
:rules="[(val) => !!val || 'กรุณาเลือกระดับชั้นงาน']"
|
|
lazy-rules
|
|
hide-bottom-space
|
|
>
|
|
<template v-slot:no-option>
|
|
<q-item>
|
|
<q-item-section class="text-grey">
|
|
ไม่มีข้อมูล
|
|
</q-item-section>
|
|
</q-item>
|
|
</template>
|
|
</q-select>
|
|
</div>
|
|
|
|
<div class="col-12">
|
|
<q-input
|
|
:class="getClass(!isReadonly)"
|
|
:readonly="isReadonly"
|
|
dense
|
|
outlined
|
|
v-model="formData.reson"
|
|
label="หมายเหตุ"
|
|
type="textarea"
|
|
/>
|
|
</div>
|
|
|
|
<div class="col-12 text-bold">อัตราค่าจ้าง</div>
|
|
<div class="col-4">
|
|
<q-input
|
|
:class="getClass(!isReadonly)"
|
|
:readonly="isReadonly"
|
|
ref="rateOldMinRef"
|
|
dense
|
|
outlined
|
|
v-model="formData.rateOldMin"
|
|
label="ขั้นต่ำสุด"
|
|
mask="###,###,###,###,###,###,###,###"
|
|
reverse-fill-mask
|
|
:rules="[
|
|
(val) => !!val || `${'กรุณากรอกอัตราค่าจ้าง ขั้นต่ำสุด'}`,
|
|
]"
|
|
lazy-rules
|
|
hide-bottom-space
|
|
/>
|
|
</div>
|
|
<div class="col-4">
|
|
<q-select
|
|
:class="getClass(!isReadonly)"
|
|
:readonly="isReadonly"
|
|
ref="groupOldRef"
|
|
dense
|
|
outlined
|
|
multiple
|
|
v-model="formData.groupOld"
|
|
label="กลุ่มของผังบัญชีอัตราค่าจ้าง"
|
|
:rules="[
|
|
(val) =>
|
|
!!val ||
|
|
`${'กรุณาเลือกอัตราค่าจ้าง กลุ่มของผังบัญชีอัตราค่าจ้าง'}`,
|
|
]"
|
|
:options="groupOldOp"
|
|
map-options
|
|
option-label="name"
|
|
option-value="id"
|
|
lazy-rules
|
|
hide-bottom-space
|
|
use-input
|
|
@filter="(inputValue:string,doneFn:Function) => filterOption(inputValue, doneFn,'groupOld')"
|
|
>
|
|
<template v-slot:no-option>
|
|
<q-item>
|
|
<q-item-section class="text-grey">
|
|
ไม่มีข้อมูล
|
|
</q-item-section>
|
|
</q-item>
|
|
</template>
|
|
</q-select>
|
|
</div>
|
|
<div class="col-4">
|
|
<q-input
|
|
:class="getClass(!isReadonly)"
|
|
:readonly="isReadonly"
|
|
ref="rateMaxOldRef"
|
|
dense
|
|
outlined
|
|
v-model="formData.rateMaxOld"
|
|
label="ขั้นสูงสุดเดิม"
|
|
mask="###,###,###,###,###,###,###,###"
|
|
reverse-fill-mask
|
|
:rules="[
|
|
(val) =>
|
|
!!val || `${'กรุณากรอกอัตราค่าจ้าง ขั้นสูงสุดเดิม'}`,
|
|
]"
|
|
lazy-rules
|
|
hide-bottom-space
|
|
/>
|
|
</div>
|
|
|
|
<div class="col-12 text-bold">
|
|
อัตราค่าจ้างสูงกว่าอัตราค่าจ้างขั้นสูงของตำแหน่งที่ได้รับแต่งตั้งในแต่ละระดับ
|
|
</div>
|
|
<div class="col-4">
|
|
<q-select
|
|
:class="getClass(!isReadonly)"
|
|
:readonly="isReadonly"
|
|
ref="groupRateHighRef"
|
|
dense
|
|
outlined
|
|
v-model="formData.groupRateHigh"
|
|
label="กลุ่มบัญชีค่าจ้าง"
|
|
:rules="[
|
|
(val) => !!val || `${'กรุณากรอกเลือกกลุ่มบัญชีค่าจ้าง'}`,
|
|
]"
|
|
lazy-rules
|
|
:options="groupOldOp"
|
|
map-options
|
|
option-label="name"
|
|
option-value="id"
|
|
emit-value
|
|
hide-bottom-space
|
|
use-input
|
|
@filter="(inputValue:string,doneFn:Function) => filterOption(inputValue, doneFn,'groupOld')"
|
|
>
|
|
<template v-slot:no-option>
|
|
<q-item>
|
|
<q-item-section class="text-grey">
|
|
ไม่มีข้อมูล
|
|
</q-item-section>
|
|
</q-item>
|
|
</template>
|
|
</q-select>
|
|
</div>
|
|
<div class="col-4">
|
|
<q-input
|
|
:class="getClass(!isReadonly)"
|
|
:readonly="isReadonly"
|
|
ref="rateHighMaxRef"
|
|
dense
|
|
outlined
|
|
v-model="formData.rateHighMax"
|
|
label="อัตราค่าจ้างขั้นสูงใหม่"
|
|
mask="###,###,###,###,###,###,###,###"
|
|
reverse-fill-mask
|
|
:rules="[
|
|
(val) => !!val || `${'กรุณากรอกอัตราค่าจ้างขั้นสูงใหม่'}`,
|
|
]"
|
|
lazy-rules
|
|
hide-bottom-space
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</q-card-section>
|
|
<q-separator />
|
|
|
|
<q-card-actions v-if="!isReadonly" align="right">
|
|
<q-btn label="บันทึก" color="secondary" type="submit"
|
|
><q-tooltip>บันทึกข้อมูล</q-tooltip></q-btn
|
|
>
|
|
</q-card-actions>
|
|
</q-form>
|
|
</q-card>
|
|
</q-dialog>
|
|
</template>
|
|
|
|
<style lang="scss" scoped></style>
|