hrms-mgt/src/modules/13_salary/components/Command/step01.vue

726 lines
23 KiB
Vue

<script setup lang="ts">
import { ref, onMounted, watch } from "vue";
import { useCounterMixin } from "@/stores/mixin";
import type { QForm } from "quasar";
import { useQuasar } from "quasar";
import { useRoute, useRouter } from "vue-router";
import http from "@/plugins/http";
import config from "@/app.config";
import type { treeTab } from "@/modules/05_placement/interface/index/Main";
import type { ResponseOrganiz } from "@/modules/05_placement/interface/response/Order";
import type { complaintLists } from "@/modules/10_order/interface/response/Order";
import type { QTableProps } from "quasar";
import type {
DataOption1,
OrederResult,
} from "@/modules/10_order/interface/index/Main";
import { useOrderPlacementDataStore } from "@/modules/10_order/store";
const DataStore = useOrderPlacementDataStore();
const mixin = useCounterMixin();
const {
date2Thai,
messageError,
showLoader,
hideLoader,
success,
dialogConfirm,
dialogMessageNotify,
} = mixin;
const $q = useQuasar(); //ใช้ noti quasar
const route = useRoute();
const router = useRouter();
const orderId = route.params.id;
const orderId_paramsName = route.name;
const props = defineProps({
next: {
type: Function,
default: () => console.log("not function"),
},
previous: {
type: Function,
default: () => console.log("not function"),
},
});
const next = () => props.next();
const myForm = ref<QForm>();
//option
const typeOrderOption = ref<DataOption1[]>([]);
const byOrderOptionMain = ref<DataOption1[]>([]);
const byOrderOption = ref<DataOption1[]>([]);
const CommandOption = ref<DataOption1[]>([]);
const salaryRoundOptionMain = ref<DataOption1[]>([]);
const salaryRoundOption = ref<DataOption1[]>([]);
//Main
const typeOrder = ref<any>();
const nameOrder = ref<any>("");
const command = ref<number | "">();
const dateYear = ref<number | null>(null);
const dateCommand = ref<Date | null>(null);
const byOrder = ref<string>("");
const nameCommand = ref<any>();
const positionCommand = ref<string>("");
const year = ref<number>(0);
const SalaryRound = ref<any>(null);
// 33-34-35
const input33 = ref<string>("");
const input34 = ref<string>("");
const input35 = ref<string>("");
const typeOrderFilter = ref<any>({
typeOrderOption: [],
});
onMounted(async () => {
if (orderId) {
await fecthTypeOption("hasData");
} else {
await fecthTypeOption("noData");
}
});
// เลือกคำสั่งโดย
watch(byOrder, async () => {
await http
.get(config.API.approverOC(byOrder.value))
.then((res) => {
CommandOption.value = res.data.result;
})
.catch((e) => {
messageError($q, e);
});
});
//เลือกผู้ลงนาม
watch(nameCommand, async () => {
if (positionCommand.value === "" || positionCommand.value === undefined) {
positionCommand.value = nameCommand.value.positionName;
}
});
const commandCodes = ref<string[]>([
"C-PM-33",
"C-PM-34",
"C-PM-35",
"C-PM-36",
"C-PM-37",
]);
// เรียกคำสั่ง
const fecthTypeOption = async (actions: string) => {
showLoader();
await http
.get(config.API.typeOrder())
.then((res) => {
const response = res.data.result;
const filterRes = response.filter((e: any) =>
commandCodes.value.includes(e.commandCode)
);
const data =
orderId_paramsName === "OrderDetail" ||
orderId_paramsName === "OrderAdd"
? response
: filterRes;
typeOrderOption.value = data.map((e: OrederResult) => ({
id: e.id,
name: e.name,
category: e.category,
commandCode: e.commandCode,
fullname: e.name,
}));
typeOrderFilter.value = data.map((e: OrederResult) => ({
id: e.id,
name: e.name,
category: e.category,
commandCode: e.commandCode,
fullname: e.name,
}));
})
.catch((e) => {
messageError($q, e);
})
.finally(async () => {
await fecthCommand();
if (actions == "hasData") {
await fetchdetailOrder(); // เมื่อแก้ไขจะเรียกข้อมูลรายละเอียด
}
hideLoader();
});
};
// เรียกรายละเอียดของคำสั่ง
const fetchdetailOrder = async () => {
let orderIdString = orderId.toString();
await http
.get(config.API.detailOrder(orderIdString))
.then(async (res: any) => {
const data = res.data.result;
const orderTypeCode = await data.orderTypeCode.toUpperCase();
typeOrder.value = typeOrderOption.value.find(
(e) => e.id === data.orderTypeValue
);
nameOrder.value = data.orderTitle;
command.value = data.orderNo;
dateYear.value = Number(data.orderYear);
dateCommand.value = data.orderDate;
byOrder.value = data.orderBy;
nameCommand.value = data.signatoryBy;
positionCommand.value = data.signatoryPosition;
SalaryRound.value = data.salaryPeriodId;
year.value = Number(data.year);
fetchSalaryRound();
})
.catch((e) => {
messageError($q, e);
})
.finally(async () => {
// await fecthCommand();
hideLoader();
});
};
const fecthCommand = async () => {
await http
.get(config.API.organizationsOrder())
.then((res) => {
byOrderOptionMain.value = res.data.result;
byOrderOption.value = res.data.result;
})
.catch((e) => {
messageError($q, e);
});
};
function casePm(val: string) {
switch (val) {
case "C-PM-33":
return "เลื่อนเงินเดือนและให้ข้าราชการกรุงเทพมหานครสามัญ ได้รับเงินเดือนสูงกว่าขั้นสูงของตำแหน่งที่ได้รับแต่งตั้ง";
case "C-PM-34":
return "ให้ข้าราชการกรุงเทพมหานครสามัญได้รับค่าตอบแทนพิเศษ";
case "C-PM-35":
return `เลื่อนเงินเดือนและให้ข้าราชการกรุงเทพมหานครสามัญที่เกษียณอายุราชการ ในสิ้นปีงบประมาณ พ.ศ. ${
new Date().getFullYear() + 543
} ได้รับเงินเดือนสูงกว่าชั้นสูงของตำแหน่งที่ได้รับแต่งตั้ง`;
case "C-PM-36":
return "เลื่อนขั้นค่าจ้างและให้ลูกจ้างประจำกรุงเทพมหานครได้รับอัตราค่าจ้าง สูงกว่าอัตราค่าจ้างขั้นสูงของตำแหน่งที่ได้รับแต่งตั้งในแต่ละระดับ";
case "C-PM-37":
return "ให้ลูกจ้างประจำกรุงเทพมหานครได้รับค่าตอบแทนพิเศษ";
default:
return null;
}
}
async function selectCMP(selectOrder: OrederResult) {
if (selectOrder != null) {
const orderTypeCode = await selectOrder.commandCode.toUpperCase();
nameOrder.value = casePm(orderTypeCode);
}
}
// บันทึกข้อมูล
const submit = async () => {
let signBy = null;
// หาคนออกคำสั่ง
if (!nameCommand.value.length) {
signBy = await nameCommand.value.name;
} else if (nameCommand.value !== "") {
signBy = await nameCommand.value;
} else {
const name2 = await CommandOption.value.find(
(x: any) => x.name == nameCommand.value
);
signBy = await name2?.name;
}
const orderByOrganizationName = await byOrderOption.value.find(
(x: any) => x.id == byOrder.value
)?.name;
const formdata = {
orderTypeValue: typeOrder.value.id,
orderTitle: nameOrder.value,
orderNo:
command.value == undefined || command.value == "" ? "" : command.value,
orderYear: dateYear.value,
orderDate: dateCommand.value,
orderBy: byOrder.value,
orderByOrganizationName: orderByOrganizationName,
registerPosition: "",
signatoryBy: signBy === "" ? nameCommand.value : signBy,
signatoryPosition: positionCommand.value,
year: year.value,
salaryPeriodId: SalaryRound.value.id,
salaryPeriod: SalaryRound.value.code,
};
// if (
// typeOrder.value.commandCode == "C-PM-33" ||
// typeOrder.value.commandCode == "C-PM-34" ||
// typeOrder.value.commandCode == "C-PM-35"
// ) {
// Object.assign(formdata, {
// // examRound: examRound.value,
// // conclusionRegisterNo: conclusionRegisterNo.value,
// // conclusionRegisterDate: conclusionRegisterDate.value,
// // conclusionResultNo: conclusionResultNo.value.toString(),
// // conclusionResultDate: conclusionResultDate.value,
// });
// }
// เช็คค่าว่าง
// await myForm.value!.validate().then((result: boolean) => {
// if (result) {
dialogConfirm($q, () => {
// ถ้ามี orderId ให้ อัพเดท ไม่มีให้สร้าง
if (!orderId) {
createListOrder(formdata, typeOrder.value.commandCode);
} else {
let orderIdString = orderId.toString();
updateOrder(formdata, orderIdString, typeOrder.value.commandCode);
}
});
// }
// });
};
// สร้างคำสัง
const createListOrder = async (formData: Object, type: string) => {
showLoader();
await http
.post(config.API.orderCPM(type), formData)
.then((res) => {
const data = res.data.result;
localStorage.setItem("orderId", data.id);
router.push(`/salary/command/detail/${data.id}?step=${2}`); // สร้างเสร็จแล้วให้ไป Step 2
next();
success($q, "บันทึกข้อมูลสำเร็จ");
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
};
const updateOrder = async (formData: Object, orderId: string, type: string) => {
showLoader();
await http
.put(config.API.orderCPMUpdate(type, orderId), formData)
.then(() => {
next(); // แก้ไขเสร็จแล้วให้ไป Step 2
success($q, "บันทึกข้อมูลสำเร็จ");
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
};
function filterSelector(val: any, update: Function, fullname: any) {
switch (fullname) {
case "typeOrderOption":
update(() => {
typeOrderOption.value = typeOrderFilter.value.filter(
(v: any) => v.fullname.toLowerCase().indexOf(val.toLowerCase()) > -1
);
});
break;
case "byOrderOption":
update(() => {
byOrderOption.value = byOrderOptionMain.value.filter(
(v: any) => v.name.toLowerCase().indexOf(val.toLowerCase()) > -1
);
});
break;
case "SalaryRound":
update(() => {
salaryRoundOption.value = salaryRoundOptionMain.value.filter(
(v: any) => v.name.toLowerCase().indexOf(val.toLowerCase()) > -1
);
});
break;
default:
break;
}
}
/**
* class จัดรูปแบบแสดงระหว่างข้อมูลที่แก้ไขหรือแสดงเฉยๆ
* @param val ข้อมูล input สำหรับแก้ไขหรือไม่
*/
function getClass(val: boolean) {
return {
"full-width inputgreen cursor-pointer": val,
"full-width cursor-pointer": !val,
};
}
/** ดึงข้อมูลเริ่มต้น */
function fetchSalaryRound() {
showLoader();
http
.get(
config.API.salaryPeriod() +
`?page=${1}&pageSise=${10}&keyword=${""}&year=${year.value}`
)
.then((res) => {
const data = res.data.result.data;
const list = data.map((e: any) => ({
id: e.id,
name:
e.period === "SPECIAL"
? "รอบพิเศษ"
: e.period === "APR"
? "รอบเมษายน"
: e.period === "OCT"
? "รอบตุลาคม"
: "-",
code: e.period,
}));
salaryRoundOptionMain.value = list;
if (SalaryRound.value) {
SalaryRound.value = list.find((x: any) => x.id == SalaryRound.value);
}
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
}
</script>
<template>
<q-form greedy @submit.prevent @validation-success="submit">
<div class="q-pa-md">
<!-- Main -->
<div class="row col-12 q-col-gutter-x-lg q-col-gutter-y-md">
<div class="col-xs-12 col-md-6">
<q-select
:class="getClass(true)"
outlined
dense
v-model="typeOrder"
:rules="[(val) => !!val || `${'กรุณาเลือกประเภทคำสั่ง'}`]"
hide-bottom-space
:label="`${'ประเภทคำสั่ง'}`"
map-options
option-label="fullname"
:options="typeOrderOption"
option-value="id"
use-input
input-debounce="0"
lazy-rules
@update:model-value="selectCMP(typeOrder)"
@filter="(inputValue:any,
doneFn:Function) => filterSelector(inputValue, doneFn,'typeOrderOption'
) "
/>
</div>
<div class="col-xs-12 col-md-6">
<q-input
:class="getClass(true)"
outlined
autogrow
lazy-rules
dense
v-model="nameOrder"
:rules="[(val) => !!val || `${'กรุณากรอกคำสั่งเรื่อง'}`]"
:label="`${'คำสั่งเรื่อง'}`"
hide-bottom-space
/>
</div>
<div class="row col-xs-7 col-md-3">
<div class="col-6">
<q-input
:class="getClass(true)"
outlined
dense
lazy-rules
v-model="command"
hide-bottom-space
:label="`${'คำสั่งเลขที่'}`"
/>
</div>
<label class="col-1 flex justify-center items-center text-bold"
>/</label
>
<div class="col-5">
<datepicker
v-model="dateYear"
:locale="'th'"
autoApply
year-picker
:enableTimePicker="false"
>
<template #year="{ year }">{{ year + 543 }}</template>
<template #year-overlay-value="{ value }">{{
parseInt(value + 543)
}}</template>
<template #trigger>
<q-input
class="inputgreen"
:model-value="dateYear !== null ? dateYear + 543 : null"
:rules="[(val) => !!val || `${'กรุณากรอก พ.ศ.'}`]"
:label="`${'พ.ศ.'}`"
dense
outlined
>
</q-input>
</template>
</datepicker>
</div>
</div>
<div class="col-xs-5 col-md-3">
<datepicker
menu-class-name="modalfix"
v-model="dateCommand"
:locale="'th'"
autoApply
borderless
:enableTimePicker="false"
week-start="0"
>
<template #year="{ year }">
{{ year + 543 }}
</template>
<template #year-overlay-value="{ value }">
{{ parseInt(value + 543) }}
</template>
<template #trigger>
<q-input
outlined
dense
class="inputgreen"
:model-value="
dateCommand != null ? date2Thai(dateCommand) : null
"
:label="`${'วันที่คำสั่งมีผล'}`"
:rules="[(val) => !!val || `${'กรุณาเลือกวันที่คำสั่งมีผล'}`]"
>
<template v-slot:prepend>
<q-icon
name="event"
class="cursor-pointer"
style="color: var(--q-primary)"
>
</q-icon>
</template>
</q-input>
</template>
</datepicker>
</div>
<div class="col-xs-12 col-md-6">
<selector
:class="getClass(true)"
outlined
dense
v-model="byOrder"
:rules="[(val: string) => !!val || `${'กรุณาเลือกคำสั่งโดย'}`]"
emit-value
hide-bottom-space
:label="`${'คำสั่งโดย'}`"
map-options
option-label="name"
:options="byOrderOption"
option-value="id"
use-input
lazy-rules
input-debounce="0"
@update:model-value="(nameCommand = ''), (positionCommand = '')"
@filter="(inputValue:any,
doneFn:Function) => filterSelector(inputValue, doneFn,'byOrderOption'
) "
/>
</div>
<div
class="col-xs-12 col-md-6"
v-if="byOrder !== '00000000-0000-0000-0000-000000000000'"
>
<selector
:class="getClass(true)"
outlined
dense
lazy-rules
v-model="nameCommand"
:rules="[(val: string) => !!val || `${'กรุณาเลือกผู้มีอำนาจลงนาม'}`]"
hide-bottom-space
:label="`${'ผู้มีอำนาจลงนาม'}`"
map-options
option-label="name"
:options="CommandOption"
option-value="id"
use-input
input-debounce="0"
>
<template v-if="CommandOption.length === 0" v-slot:no-option>
<q-item>
<q-item-section class="text-primary">
กรณาเลอกคำสงโดยกอน
</q-item-section>
</q-item>
</template>
</selector>
</div>
<div
class="col-xs-12 col-md-6"
v-if="byOrder !== '00000000-0000-0000-0000-000000000000'"
>
<q-input
:class="getClass(true)"
outlined
dense
lazy-rules
v-model="positionCommand"
:rules="[(val) => !!val || `${'กรุณากรอกตำแหน่งผู้มีอำนาจลงนาม'}`]"
:label="`${'ตำแหน่งผู้มีอำนาจลงนาม'}`"
hide-bottom-space
disable
/>
</div>
<div
class="col-xs-12 col-md-6"
v-if="byOrder == '00000000-0000-0000-0000-000000000000'"
>
<q-input
:class="getClass(true)"
outlined
lazy-rules
dense
v-model="nameCommand"
:rules="[(val) => !!val || `${'กรุณากรอกผู้มีอำนาจลงนาม'}`]"
:label="`${'ผู้มีอำนาจลงนาม'}`"
hide-bottom-space
/>
</div>
<div
class="col-xs-12 col-md-6"
v-if="byOrder == '00000000-0000-0000-0000-000000000000'"
>
<q-input
:class="getClass(true)"
outlined
dense
lazy-rules
v-model="positionCommand"
:rules="[(val) => !!val || `${'กรุณากรอกตำแหน่งผู้มีอำนาจลงนาม'}`]"
:label="`${'ตำแหน่งผู้มีอำนาจลงนาม'}`"
hide-bottom-space
/>
</div>
<div class="col-xs-12 col-md-2">
<datepicker
menu-class-name="modalfix"
v-model="year"
:locale="'th'"
autoApply
year-picker
:enableTimePicker="false"
@update:model-value="fetchSalaryRound(), (SalaryRound = '')"
>
<template #year="{ year }">{{ year + 543 }}</template>
<template #year-overlay-value="{ value }">{{
parseInt(value + 543)
}}</template>
<template #trigger>
<q-input
dense
outlined
:model-value="year === 0 ? null : Number(year) + 543"
:label="`${'ปีงบประมาณ'}`"
class="inputgreen"
:rules="[(val: string) => !!val || `${'กรุณาเลือกปีงบประมาณ'}`]"
>
<template v-slot:prepend>
<q-icon
name="event"
class="cursor-pointer"
style="color: var(--q-primary)"
>
</q-icon>
</template>
</q-input>
</template>
</datepicker>
</div>
<div class="col-xs-12 col-md-4">
<q-select
class="inputgreen"
outlined
dense
v-model="SalaryRound"
:rules="[(val: string) => !!val || `${'กรุณาเลือกรอบการขึ้นเงินเดือน'}`]"
hide-bottom-space
:label="`${'รอบการขึ้นเงินเดือน'}`"
option-label="name"
:options="salaryRoundOption"
option-value="id"
use-input
input-debounce="0"
lazy-rules
@filter="(inputValue:any,
doneFn:Function) => filterSelector(inputValue, doneFn,'SalaryRound'
) "
/>
</div>
</div>
</div>
<q-separator />
<div class="flex justify-end q-pa-sm q-gutter-sm">
<q-btn unelevated label="บันทึก" type="submit" color="public">
<q-tooltip>นทกขอม</q-tooltip>
</q-btn>
</div>
</q-form>
</template>
<style>
.q-field--with-bottom {
padding-bottom: 0px;
}
.custom-header-table {
max-height: 64vh;
.q-table tr:nth-child(odd) td {
background: white;
}
.q-table tr:nth-child(even) td {
background: #f8f8f8;
}
.q-table thead tr {
background: #ecebeb;
}
.q-table thead tr th {
position: sticky;
z-index: 1;
}
.q-table thead tr:last-child th {
top: 48px;
}
.q-table thead tr:first-child th {
top: 0;
}
}
</style>