Merge branch 'develop' into dev
All checks were successful
Build & Deploy on Dev / build (push) Successful in 2m0s

This commit is contained in:
DESKTOP-1R2VSQH\Lenovo ThinkPad E490 2025-12-16 16:32:19 +07:00
commit 0cd88b725b
15 changed files with 615 additions and 165 deletions

View file

@ -8,13 +8,11 @@ import config from "@/app.config";
import type { QTableColumn } from "quasar";
import type { FormEmployee } from "@/modules/04_registryPerson/interface/request/Employee";
import type {
EmployeeHistory,
ResEmployee,
} from "@/modules/04_registryPerson/interface/response/Employee";
import type { ResEmployee } from "@/modules/04_registryPerson/interface/response/Employee";
import DialogHeader from "@/components/DialogHeader.vue";
import DialogHistory from "@/modules/04_registryPerson/components/detail/DialogHistory.vue";
import CurruncyInput from "@/components/CurruncyInput.vue";
import { useCounterMixin } from "@/stores/mixin";
@ -27,7 +25,6 @@ const {
date2Thai,
messageError,
dialogConfirm,
onSearchDataTable,
} = useCounterMixin();
const profileId = ref<string>(
@ -60,11 +57,11 @@ const formData = reactive<FormEmployee>({
positionEmployeePositionId: "",
employeeOc: "",
employeeTypeIndividual: "",
employeeWage: "",
employeeMoneyIncrease: "",
employeeMoneyAllowance: "",
employeeMoneyEmployee: "",
employeeMoneyEmployer: "",
employeeWage: undefined,
employeeMoneyIncrease: undefined,
employeeMoneyAllowance: undefined,
employeeMoneyEmployee: undefined,
employeeMoneyEmployer: undefined,
});
/** function fetch ข้อมูลลูกจ้างชั่วคราว*/
@ -101,11 +98,15 @@ function onClickEdit() {
formData.positionEmployeePositionId = dataEmployee.positionEmployeePositionId;
formData.employeeOc = dataEmployee.employeeOc;
formData.employeeTypeIndividual = dataEmployee.employeeTypeIndividual;
formData.employeeWage = dataEmployee.employeeWage;
formData.employeeMoneyIncrease = dataEmployee.employeeMoneyIncrease;
formData.employeeMoneyAllowance = dataEmployee.employeeMoneyAllowance;
formData.employeeMoneyEmployee = dataEmployee.employeeMoneyEmployee;
formData.employeeMoneyEmployer = dataEmployee.employeeMoneyEmployer;
formData.employeeWage = Number(dataEmployee.employeeWage) || undefined;
formData.employeeMoneyIncrease =
Number(dataEmployee.employeeMoneyIncrease) || undefined;
formData.employeeMoneyAllowance =
Number(dataEmployee.employeeMoneyAllowance) || undefined;
formData.employeeMoneyEmployee =
Number(dataEmployee.employeeMoneyEmployee) || undefined;
formData.employeeMoneyEmployer =
Number(dataEmployee.employeeMoneyEmployer) || undefined;
}
/** function ปิด Dialog แก้ไขมูลลูกจ้างชั่วคราว*/
@ -116,11 +117,11 @@ function onCloseDialog() {
formData.positionEmployeePositionId = "";
formData.employeeOc = "";
formData.employeeTypeIndividual = "";
formData.employeeWage = "";
formData.employeeMoneyIncrease = "";
formData.employeeMoneyAllowance = "";
formData.employeeMoneyEmployee = "";
formData.employeeMoneyEmployer = "";
formData.employeeWage = undefined;
formData.employeeMoneyIncrease = undefined;
formData.employeeMoneyAllowance = undefined;
formData.employeeMoneyEmployee = undefined;
formData.employeeMoneyEmployer = undefined;
}
/** function บันทึกแก้ไขมูลลูกจ้างชั่วคราว*/
@ -128,7 +129,15 @@ function onSubmit() {
dialogConfirm($q, () => {
showLoader();
http
.put(config.API.informationEmployee(profileId.value), formData)
.put(config.API.informationEmployee(profileId.value), {
...formData,
employeeWage: formData.employeeWage?.toString() || "",
employeeMoneyIncrease: formData.employeeMoneyIncrease?.toString() || "",
employeeMoneyAllowance:
formData.employeeMoneyAllowance?.toString() || "",
employeeMoneyEmployee: formData.employeeMoneyEmployee?.toString() || "",
employeeMoneyEmployer: formData.employeeMoneyEmployer?.toString() || "",
})
.then(async () => {
await fetchData();
await success($q, "บันทึกข้อมูลสำเร็จ");
@ -533,7 +542,8 @@ onMounted(() => {
<!-- :rules="[(val: string) => !!val || `${'กรุณากรอกประเภทบุคคล'}`]" -->
</div>
<div class="col-xs-12 col-sm-6 col-md-6">
<q-input
<CurruncyInput
:edit="true"
dense
outlined
lazy-rules
@ -541,14 +551,18 @@ onMounted(() => {
v-model="formData.employeeWage"
class="inputgreen"
label="ค่าจ้าง"
mask="###,###,###,###"
reverse-fill-mask
:rules="[(val:number) => {
if (!val) return true;
const numVal = typeof val === 'number' ? val : Number(String(val).replace(/,/g, ''));
return numVal <= 10000000 || 'ค่าจ้างต้องไม่เกิน 10,000,000 บาท';
}]"
/>
<!-- :rules="[(val: string) => !!val || `${'กรุณากรอกค่าจ้าง'}`]" -->
</div>
<div class="col-xs-12 col-sm-6 col-md-6">
<q-input
<CurruncyInput
:edit="true"
dense
outlined
lazy-rules
@ -556,13 +570,17 @@ onMounted(() => {
v-model="formData.employeeMoneyIncrease"
class="inputgreen"
label="เงินเพิ่มการครองชีพชั่วคราว"
mask="###,###,###,###"
reverse-fill-mask
:rules="[(val:number) => {
if (!val) return true;
const numVal = typeof val === 'number' ? val : Number(String(val).replace(/,/g, ''));
return numVal <= 10000000 || 'เงินเพิ่มการครองชีพชั่วคราวต้องไม่เกิน 10,000,000 บาท';
}]"
/>
<!-- :rules="[(val: string) => !!val || `${'กรุณากรอกเงินเพิ่มการครองชีพชั่วคราว'}`]" -->
</div>
<div class="col-xs-12 col-sm-6 col-md-6">
<q-input
<CurruncyInput
:edit="true"
dense
outlined
lazy-rules
@ -570,13 +588,17 @@ onMounted(() => {
v-model="formData.employeeMoneyAllowance"
class="inputgreen"
label="เงินช่วยเหลือการครองชีพชั่วคราว"
mask="###,###,###,###"
reverse-fill-mask
:rules="[(val:number) => {
if (!val) return true;
const numVal = typeof val === 'number' ? val : Number(String(val).replace(/,/g, ''));
return numVal <= 10000000 || 'เงินช่วยเหลือการครองชีพชั่วคราวต้องไม่เกิน 10,000,000 บาท';
}]"
/>
<!-- :rules="[(val: string) => !!val || `${'กรุณากรอกเงินช่วยเหลือการครองชีพชั่วคราว'}`]" -->
</div>
<div class="col-xs-12 col-sm-6 col-md-6">
<q-input
<CurruncyInput
:edit="true"
dense
outlined
lazy-rules
@ -584,13 +606,17 @@ onMounted(() => {
v-model="formData.employeeMoneyEmployee"
class="inputgreen"
label="เงินสมทบประกันสังคม(ลูกจ้าง)"
mask="###,###,###,###"
reverse-fill-mask
:rules="[(val:number) => {
if (!val) return true;
const numVal = typeof val === 'number' ? val : Number(String(val).replace(/,/g, ''));
return numVal <= 10000000 || 'เงินสมทบประกันสังคม(ลูกจ้าง)ต้องไม่เกิน 10,000,000 บาท';
}]"
/>
<!-- :rules="[(val: string) => !!val || `${'กรุณากรอกเงินสมทบประกันสังคม(ลูกจ้าง)'}`]" -->
</div>
<div class="col-xs-12 col-sm-6 col-md-6">
<q-input
<CurruncyInput
:edit="true"
dense
outlined
lazy-rules
@ -598,8 +624,11 @@ onMounted(() => {
v-model="formData.employeeMoneyEmployer"
class="inputgreen"
label="เงินสมทบประกันสังคม(นายจ้าง)"
mask="###,###,###,###"
reverse-fill-mask
:rules="[(val:number) => {
if (!val) return true;
const numVal = typeof val === 'number' ? val : Number(String(val).replace(/,/g, ''));
return numVal <= 10000000 || 'เงินสมทบประกันสังคม(นายจ้าง)ต้องไม่เกิน 10,000,000 บาท';
}]"
/>
<!-- :rules="[(val: string) => !!val || `${'กรุณากรอกเงินสมทบประกันสังคม(นายจ้าง))'}`]" -->
</div>

View file

@ -27,6 +27,7 @@ import type { DataCardPos } from "@/modules/04_registryPerson/interface/index/go
import DialogHeader from "@/components/DialogHeader.vue";
import DialogHistory from "@/modules/04_registryPerson/components/detail/DialogHistory.vue";
import DialogPreviewCommand from "@/modules/18_command/components/DialogPreviewCommand.vue";
import CurruncyInput from "@/components/CurruncyInput.vue";
const $q = useQuasar();
const route = useRoute();
@ -370,8 +371,8 @@ const formData = reactive<FormPostition>({
positionExecutive: "", //
positionExecutiveField: "", //
positionArea: "", ///
amount: null, //
amountSpecial: null, //
amount: undefined, //
amountSpecial: undefined, //
orgRoot: "", //
orgChild1: "", // 1
orgChild2: "", // 2
@ -685,8 +686,8 @@ async function onClickOpenDialog(
? data.positionExecutiveField
: "";
formData.positionArea = statusEdit ? data.positionArea : "";
formData.amount = statusEdit ? data.amount : null;
formData.amountSpecial = statusEdit ? data.amountSpecial : null;
formData.amount = statusEdit ? data.amount : undefined;
formData.amountSpecial = statusEdit ? data.amountSpecial : undefined;
formData.orgRoot = statusEdit ? data.orgRoot : "";
formData.orgChild1 = statusEdit ? data.orgChild1 : "";
formData.orgChild2 = statusEdit ? data.orgChild2 : "";
@ -1468,31 +1469,43 @@ onMounted(async () => {
<div class="col-xs-6 col-sm-6 col-md-4">
<!-- :rules="[(val:string) => !!val || `${'กรุณากรอกเงินเดือน'}`]" -->
<q-input
<CurruncyInput
:class="classInput(true)"
:edit="true"
ref="salaryRef"
dense
outlined
v-model="formData.amount"
:label="empType == '' ? 'เงินเดือน' : 'ค่าจ้าง'"
mask="###,###,###,###"
reverse-fill-mask
lazy-rules
hide-bottom-space
:rules="[
(val:number) => {
if (!val) return true;
const numVal = typeof val === 'number' ? val : Number(String(val).replace(/,/g, ''));
return numVal <= 10000000 || ` ${empType == '' ? 'เงินเดือน' : 'ค่าจ้าง'} ต้องไม่เกิน 10,000,000 บาท`;
}
]"
/>
</div>
<div class="col-xs-6 col-sm-6 col-md-4">
<q-input
<CurruncyInput
:class="classInput(true)"
:edit="true"
ref="amountSpecialRef"
dense
outlined
v-model="formData.amountSpecial"
label="เงินค่าตอบแทนพิเศษ"
mask="###,###,###,###"
reverse-fill-mask
hide-bottom-space
:rules="[
(val:number) => {
if (!val) return true;
const numVal = typeof val === 'number' ? val : Number(String(val).replace(/,/g, ''));
return numVal <= 10000000 || 'เงินค่าตอบแทนพิเศษต้องไม่เกิน 10,000,000 บาท';
}
]"
/>
</div>

View file

@ -26,6 +26,7 @@ import type { ResListSalary } from "@/modules/04_registryPerson/interface/respon
import DialogHeader from "@/components/DialogHeader.vue";
import DialogHistory from "@/modules/04_registryPerson/components/detail/DialogHistory.vue";
import DialogPreviewCommand from "@/modules/18_command/components/DialogPreviewCommand.vue";
import CurruncyInput from "@/components/CurruncyInput.vue";
const { findOrgName } = useCounterMixin();
const $q = useQuasar();
@ -423,10 +424,10 @@ const formData = reactive<FormSalary>({
positionExecutive: "", //
positionExecutiveField: "", //
positionArea: "", ///
amount: null, //
amountSpecial: null, //
positionSalaryAmount: null, //
mouthSalaryAmount: null, //
amount: undefined, //
amountSpecial: undefined, //
positionSalaryAmount: undefined, //
mouthSalaryAmount: undefined, //
orgRoot: "", //
orgChild1: "", // 1
orgChild2: "", // 2
@ -666,10 +667,12 @@ async function onClickOpenDialog(
? data.positionExecutiveField
: "";
formData.positionArea = statusEdit ? data.positionArea : "";
formData.amount = statusEdit ? data.amount : null;
formData.amountSpecial = statusEdit ? data.amountSpecial : null;
formData.positionSalaryAmount = statusEdit ? data.positionSalaryAmount : null;
formData.mouthSalaryAmount = statusEdit ? data.mouthSalaryAmount : null;
formData.amount = statusEdit ? data.amount : undefined;
formData.amountSpecial = statusEdit ? data.amountSpecial : undefined;
formData.positionSalaryAmount = statusEdit
? data.positionSalaryAmount
: undefined;
formData.mouthSalaryAmount = statusEdit ? data.mouthSalaryAmount : undefined;
formData.orgRoot = statusEdit ? data.orgRoot : "";
formData.orgChild1 = statusEdit ? data.orgChild1 : "";
formData.orgChild2 = statusEdit ? data.orgChild2 : "";
@ -1433,60 +1436,75 @@ onMounted(async () => {
<div class="col-12">
<div class="row q-col-gutter-sm">
<div class="col-xs-6 col-sm-6 col-md-4">
<q-input
<CurruncyInput
:class="classInput(true)"
:edit="true"
ref="salaryRef"
dense
outlined
v-model="formData.amount"
:label="empType == '' ? 'เงินเดือน' : 'ค่าจ้าง'"
mask="###,###,###,###"
reverse-fill-mask
:rules="[(val:string) => !!val || `กรุณากรอก${empType == '' ? 'เงินเดือน' : 'ค่าจ้าง'}`]"
:rules="[(val:string) => !!val || `กรุณากรอก${empType == '' ? 'เงินเดือน' : 'ค่าจ้าง'}`, (val:number) => {
if (!val) return true;
const numVal = typeof val === 'number' ? val : Number(String(val).replace(/,/g, ''));
return numVal <= 10000000 || ` ${empType == '' ? 'เงินเดือน' : 'ค่าจ้าง'} ต้องไม่เกิน 10,000,000 บาท`;
}]"
lazy-rules
hide-bottom-space
/>
</div>
<div class="col-xs-6 col-sm-6 col-md-4">
<q-input
<CurruncyInput
:class="classInput(true)"
:edit="true"
ref="amountSpecialRef"
dense
outlined
v-model="formData.amountSpecial"
label="เงินค่าตอบแทนพิเศษ"
mask="###,###,###,###"
reverse-fill-mask
hide-bottom-space
:rules="[(val:number) => {
if (!val) return true;
const numVal = typeof val === 'number' ? val : Number(String(val).replace(/,/g, ''));
return numVal <= 10000000 || 'เงินค่าตอบแทนพิเศษต้องไม่เกิน 10,000,000 บาท';
}]"
/>
</div>
<div class="col-xs-6 col-sm-6 col-md-4">
<q-input
<CurruncyInput
:class="classInput(true)"
:edit="true"
dense
outlined
v-model="formData.positionSalaryAmount"
label="เงินประจำตำแหน่ง"
mask="###,###,###,###"
reverse-fill-mask
lazy-rules
hide-bottom-space
:rules="[(val:number) => {
if (!val) return true;
const numVal = typeof val === 'number' ? val : Number(String(val).replace(/,/g, ''));
return numVal <= 10000000 || 'เงินประจำตำแหน่งต้องไม่เกิน 10,000,000 บาท';
}]"
/>
</div>
<div class="col-xs-6 col-sm-6 col-md-4">
<q-input
<CurruncyInput
:class="classInput(true)"
:edit="true"
dense
outlined
v-model="formData.mouthSalaryAmount"
label="เงินค่าตอบแทนรายเดือน"
mask="###,###,###,###"
reverse-fill-mask
lazy-rules
hide-bottom-space
:rules="[(val:number) => {
if (!val) return true;
const numVal = typeof val === 'number' ? val : Number(String(val).replace(/,/g, ''));
return numVal <= 10000000 || 'เงินค่าตอบแทนรายเดือนต้องไม่เกิน 10,000,000 บาท';
}]"
/>
</div>
</div>

View file

@ -75,8 +75,8 @@ interface FormPostition {
positionExecutiveField?: string; //ด้านทางการบริหาร
positionArea?: string; //ด้าน/สาขา
positionCee: string; //ระดับซี
amount: number | null; //เงินเดือน
amountSpecial: number | null; //เงินค่าตอบแทนพิเศษ
amount: number | undefined; //เงินเดือน
amountSpecial: number | undefined; //เงินค่าตอบแทนพิเศษ
orgRoot: string; //หน่วยงาน
orgChild1: string; //ส่วนราชการระดับ 1
orgChild2: string; //ส่วนราชการระดับ 2

View file

@ -22,10 +22,10 @@ interface FormDataSalary {
positionPathSide: string; //ด้าน/สาขา
positionExecutive: string; //ตำแหน่งทางการบริหาร
positionExecutiveField: string; //ด้านทางการบริหาร
amount: number | null; //เงินเดือน
amountSpecial: number | null; //เงินค่าตอบแทนพิเศษ
positionSalaryAmount: number | null; //เงินประจำตำแหน่ง
mouthSalaryAmount: number | null; //เงินค่าตอบแทนรายเดือน
amount: number | undefined; //เงินเดือน
amountSpecial: number | undefined; //เงินค่าตอบแทนพิเศษ
positionSalaryAmount: number | undefined; //เงินประจำตำแหน่ง
mouthSalaryAmount: number | undefined; //เงินค่าตอบแทนรายเดือน
orgRoot: string; //หน่วยงาน
orgChild1: string; //ส่วนราชการระดับ 1
orgChild2: string; //ส่วนราชการระดับ 2

View file

@ -4,11 +4,11 @@ interface FormEmployee {
positionEmployeePositionId: string;
employeeOc: string;
employeeTypeIndividual: string;
employeeWage: string;
employeeMoneyIncrease: string;
employeeMoneyAllowance: string;
employeeMoneyEmployee: string;
employeeMoneyEmployer: string;
employeeWage: number | undefined;
employeeMoneyIncrease: number | undefined;
employeeMoneyAllowance: number | undefined;
employeeMoneyEmployee: number | undefined;
employeeMoneyEmployer: number | undefined;
}
interface FormEmployment {

View file

@ -15,10 +15,10 @@ interface FormSalary {
positionExecutive: string; //ตำแหน่งทางการบริหาร
positionExecutiveField?: string; //ด้านทางการบริหาร
positionArea?: string; //ด้าน/สาขา
amount: number | null; //เงินเดือน
amountSpecial: number | null; //เงินค่าตอบแทนพิเศษ
positionSalaryAmount: number | null; //เงินประจำตำแหน่ง
mouthSalaryAmount: number | null; //เงินค่าตอบแทนรายเดือน
amount: number | undefined; //เงินเดือน
amountSpecial: number | undefined; //เงินค่าตอบแทนพิเศษ
positionSalaryAmount: number | undefined; //เงินประจำตำแหน่ง
mouthSalaryAmount: number | undefined; //เงินค่าตอบแทนรายเดือน
orgRoot: string; //หน่วยงาน
orgChild1: string; //ส่วนราชการระดับ 1
orgChild2: string; //ส่วนราชการระดับ 2

View file

@ -62,10 +62,10 @@ const formData = reactive<FormDataSalary>({
positionPathSide: "", ///
positionExecutive: "", //
positionExecutiveField: "", //
amount: null, //
amountSpecial: null, //
positionSalaryAmount: null, //
mouthSalaryAmount: null, //
amount: undefined, //
amountSpecial: undefined, //
positionSalaryAmount: undefined, //
mouthSalaryAmount: undefined, //
orgRoot: "", //
orgChild1: "", // 1
orgChild2: "", // 2
@ -91,10 +91,10 @@ const formReadonly = reactive<FormDataSalary>({
positionPathSide: "", ///
positionExecutive: "", //
positionExecutiveField: "", //
amount: null, //
amountSpecial: null, //
positionSalaryAmount: null, //
mouthSalaryAmount: null, //
amount: undefined, //
amountSpecial: undefined, //
positionSalaryAmount: undefined, //
mouthSalaryAmount: undefined, //
orgRoot: "", //
orgChild1: "", // 1
orgChild2: "", // 2
@ -377,10 +377,10 @@ function onClickCloseDialog() {
formData.positionPathSide = "";
formData.positionExecutive = "";
formData.positionExecutiveField = "";
formData.amount = null;
formData.amountSpecial = null;
formData.positionSalaryAmount = null;
formData.mouthSalaryAmount = null;
formData.amount = undefined;
formData.amountSpecial = undefined;
formData.positionSalaryAmount = undefined;
formData.mouthSalaryAmount = undefined;
formData.orgRoot = "";
formData.orgChild1 = "";
formData.orgChild2 = "";
@ -405,9 +405,9 @@ function onClickCloseDialog() {
formReadonly.positionPathSide = "";
formReadonly.positionExecutive = "";
formReadonly.positionExecutiveField = "";
formReadonly.amount = null;
formReadonly.positionSalaryAmount = null;
formReadonly.mouthSalaryAmount = null;
formReadonly.amount = undefined;
formReadonly.positionSalaryAmount = undefined;
formReadonly.mouthSalaryAmount = undefined;
formReadonly.orgRoot = "";
formReadonly.orgChild1 = "";
formReadonly.orgChild2 = "";

View file

@ -5,6 +5,8 @@ import { useEditPosDataStore } from "@/modules/04_registryPerson/stores/Edit";
import type { DataOption } from "@/modules/04_registryPerson/interface/index/Main";
import type { FormDataSalary } from "@/modules/04_registryPerson/interface/request/Edit";
import CurruncyInput from "@/components/CurruncyInput.vue";
const { date2Thai } = useCounterMixin();
const store = useEditPosDataStore();
@ -597,7 +599,7 @@ function classInput(val: boolean) {
<div class="col-12">
<div class="row q-col-gutter-sm">
<div class="col-xs-6 col-sm-6 col-md-4">
<q-input
<CurruncyInput
:class="classInput(isReadonly)"
:readonly="isReadonly"
ref="salaryRef"
@ -605,15 +607,20 @@ function classInput(val: boolean) {
outlined
v-model="formData.amount"
label="เงินเดือน"
mask="###,###,###,###"
reverse-fill-mask
lazy-rules
hide-bottom-space
:rules="[
(val:number) => {
if (!val) return true;
const numVal = typeof val === 'number' ? val : Number(String(val).replace(/,/g, ''));
return numVal <= 10000000 || 'เงินเดือนต้องไม่เกิน 10,000,000 บาท';
}
]"
/>
</div>
<div class="col-xs-6 col-sm-6 col-md-4">
<q-input
<CurruncyInput
:class="classInput(isReadonly)"
:readonly="isReadonly"
ref="amountSpecialRef"
@ -621,39 +628,54 @@ function classInput(val: boolean) {
outlined
v-model="formData.amountSpecial"
label="เงินค่าตอบแทนพิเศษ"
mask="###,###,###,###"
reverse-fill-mask
hide-bottom-space
:rules="[
(val:number) => {
if (!val) return true;
const numVal = typeof val === 'number' ? val : Number(String(val).replace(/,/g, ''));
return numVal <= 10000000 || 'เงินค่าตอบแทนพิเศษต้องไม่เกิน 10,000,000 บาท';
}
]"
/>
</div>
<div class="col-xs-6 col-sm-6 col-md-4">
<q-input
<CurruncyInput
:class="classInput(isReadonly)"
:readonly="isReadonly"
dense
outlined
v-model="formData.positionSalaryAmount"
label="เงินประจำตำแหน่ง"
mask="###,###,###,###"
reverse-fill-mask
lazy-rules
hide-bottom-space
lazy-rules
:rules="[
(val:number) => {
if (!val) return true;
const numVal = typeof val === 'number' ? val : Number(String(val).replace(/,/g, ''));
return numVal <= 10000000 || 'เงินประจำตำแหน่งต้องไม่เกิน 10,000,000 บาท';
}
]"
/>
</div>
<div class="col-xs-6 col-sm-6 col-md-4">
<q-input
<CurruncyInput
:class="classInput(isReadonly)"
:readonly="isReadonly"
dense
outlined
v-model="formData.mouthSalaryAmount"
label="เงินค่าตอบแทนรายเดือน"
mask="###,###,###,###"
reverse-fill-mask
lazy-rules
hide-bottom-space
:rules="[
(val:number) => {
if (!val) return true;
const numVal = typeof val === 'number' ? val : Number(String(val).replace(/,/g, ''));
return numVal <= 10000000 || 'เงินค่าตอบแทนรายเดือนต้องไม่เกิน 10,000,000 บาท';
}
]"
/>
</div>
</div>

View file

@ -20,6 +20,7 @@ import type {
import DialogForm from "@/modules/04_registryPerson/views/edit/components/DialogForm.vue";
import DialogSort from "@/modules/04_registryPerson/views/edit/components/DialogSort.vue";
import CurruncyInput from "@/components/CurruncyInput.vue";
const $q = useQuasar();
const route = useRoute();
@ -47,6 +48,10 @@ const statusCheckEdit = defineModel<string>("statusCheckEdit", {
required: true,
});
const amountRef = ref<any>(null);
const amountSpecialRef = ref<any>(null);
const currencyPopupRef = ref<any>(null);
//Table
const isLoad = ref<boolean>(true);
const rowIndex = ref<number>(0);
@ -341,7 +346,6 @@ function onEditData(index: number) {
rowIndex.value = index;
modal.value = true;
isAddPosition.value = index === -1; // index -1
console.log(`isAddPosition: ${isAddPosition.value}`);
}
/**
@ -559,6 +563,14 @@ function onShow(data: DataPosition, colName: string) {
* @param close
*/
async function onSave(val: any, id: string, close?: () => void) {
// validation amountRef validate method
if (amountRef.value && typeof amountRef.value.validate === "function") {
const isValid = amountRef.value.validate();
if (isValid === false) {
return; // validation
}
}
if (isUpdateData.value) {
showLoader();
const isCol = (key: string) => colNameMain.value === key;
@ -746,6 +758,97 @@ function onUpdateData() {
isUpdateData.value = true;
}
/**
* งกนตรวจสอบ validation และบนทกขอมลสำหรบทกประเภท
*/
async function validateAndSave(
val: any,
id: string,
close?: () => void,
fieldType: "amount" | "currency" | "normal" = "normal"
) {
let isValid = true;
// validation amount fields
if (fieldType === "amount") {
// Validate
if (formData.amount !== null && formData.amount !== undefined) {
const amountNum =
typeof formData.amount === "number"
? formData.amount
: Number(String(formData.amount).replace(/,/g, ""));
if (amountNum > 10000000) {
isValid = false;
}
}
// Validate
if (
isValid &&
formData.amountSpecial !== null &&
formData.amountSpecial !== undefined
) {
const amountSpecialNum =
typeof formData.amountSpecial === "number"
? formData.amountSpecial
: Number(String(formData.amountSpecial).replace(/,/g, ""));
if (amountSpecialNum > 10000000) {
isValid = false;
}
}
// Force validate refs
if (
isValid &&
amountRef.value &&
typeof amountRef.value.validate === "function"
) {
const amountValid = amountRef.value.validate();
isValid = isValid && amountValid !== false;
}
if (
isValid &&
amountSpecialRef.value &&
typeof amountSpecialRef.value.validate === "function"
) {
const amountSpecialValid = amountSpecialRef.value.validate();
isValid = isValid && amountSpecialValid !== false;
}
}
// validation currency fields
else if (fieldType === "currency") {
// Validate
if (val !== null && val !== undefined) {
const numVal =
typeof val === "number" ? val : Number(String(val).replace(/,/g, ""));
if (numVal > 10000000) {
isValid = false;
}
}
// Force validate ref
if (
isValid &&
currencyPopupRef.value &&
typeof currencyPopupRef.value.validate === "function"
) {
const currencyValid = currencyPopupRef.value.validate();
isValid = isValid && currencyValid !== false;
}
}
// validation
if (isValid) {
await onSave(val, id, close);
return true;
} else {
// validation (rules error message )
return false;
}
}
onMounted(async () => {
await Promise.all([fetchData(), fetchType()]);
});
@ -946,7 +1049,11 @@ onMounted(async () => {
label-set="บันทึก"
label-cancel="ยกเลิก"
@before-show="onShow(props.row, col.name)"
:persistent="col.name === 'commandNo'"
:persistent="
col.name === 'commandNo' || col.name === 'amount'
"
:buttons="false"
@save="null"
>
<div class="q-mb-xs">
{{ `แก้ไข${col.label}` }}
@ -999,27 +1106,65 @@ onMounted(async () => {
</div>
<div class="q-gutter-sm" v-if="col.name === 'amount'">
<q-input
<CurruncyInput
ref="amountRef"
:edit="true"
dense
outlined
v-model="formData.amount"
label="เงินเดือน"
mask="###,###,###,###"
reverse-fill-mask
lazy-rules
hide-bottom-space
@update:model-value="onUpdateData"
:rules="[
(val:number) => {
if (!val) return true;
const numVal = typeof val === 'number' ? val : Number(String(val).replace(/,/g, ''));
return numVal <= 10000000 || 'เงินเดือนต้องไม่เกิน 10,000,000 บาท';
}
]"
/>
<q-input
<CurruncyInput
ref="amountSpecialRef"
:edit="true"
dense
outlined
v-model="formData.amountSpecial"
label="เงินค่าตอบแทนพิเศษ"
mask="###,###,###,###"
reverse-fill-mask
hide-bottom-space
lazy-rules
@update:model-value="onUpdateData"
:rules="[
(val:number) => {
if (!val) return true;
const numVal = typeof val === 'number' ? val : Number(String(val).replace(/,/g, ''));
return numVal <= 10000000 || 'เงินค่าตอบแทนพิเศษต้องไม่เกิน 10,000,000 บาท';
}
]"
/>
<!-- Custom buttons สำหร amount -->
<div class="row justify-around q-pt-sm">
<q-btn
flat
color="primary"
label="ยกเลิก"
@click="scope.cancel"
/>
<q-btn
flat
color="primary"
label="บันทึก"
@click="
validateAndSave(
formData,
props.row.id,
scope.cancel,
'amount'
)
"
/>
</div>
</div>
<div class="q-gutter-sm" v-else-if="col.name === 'posNo'">
@ -1165,7 +1310,11 @@ onMounted(async () => {
</q-select>
</div>
<div class="row justify-around q-pt-sm">
<!-- Default buttons สำหร fields นๆ (ไมใช amount และ positionLevel) -->
<div
v-if="col.name !== 'amount' && col.name !== 'positionLevel'"
class="row justify-around q-pt-sm"
>
<q-btn
flat
color="primary"
@ -1177,7 +1326,40 @@ onMounted(async () => {
flat
color="primary"
label="บันทึก"
@click="onSave(formData, props.row.id, scope.cancel)"
@click="
validateAndSave(
formData,
props.row.id,
scope.cancel,
'normal'
)
"
/>
</div>
<!-- Custom buttons สำหร positionLevel -->
<div
v-if="col.name === 'positionLevel'"
class="row justify-around q-pt-sm"
>
<q-btn
flat
color="primary"
label="ยกเลิก"
@click="scope.cancel"
/>
<q-btn
flat
color="primary"
label="บันทึก"
@click="
validateAndSave(
formData,
props.row.id,
scope.cancel,
'normal'
)
"
/>
</div>
</q-popup-edit>
@ -1205,6 +1387,8 @@ onMounted(async () => {
label-set="บันทึก"
label-cancel="ยกเลิก"
@before-show="onShow(props.row, col.name)"
:buttons="false"
@save="null"
>
<div class="q-mb-xs">
{{ `แก้ไข${col.label}` }}
@ -1276,7 +1460,14 @@ onMounted(async () => {
flat
color="primary"
label="บันทึก"
@click="onSave(formData, props.row.id, scope.cancel)"
@click="
validateAndSave(
formData,
props.row.id,
scope.cancel,
'normal'
)
"
/>
</div>
</q-popup-edit>
@ -1293,13 +1484,37 @@ onMounted(async () => {
v-slot="scope"
:persistent="
col.name === 'commandDateAffect' ||
col.name === 'commandDateSign'
col.name === 'commandDateSign' ||
col.name === 'mouthSalaryAmount' ||
col.name === 'positionSalaryAmount'
"
v-model="props.row[col.name]"
buttons
:buttons="
col.name !== 'mouthSalaryAmount' &&
col.name !== 'positionSalaryAmount' &&
col.name !== 'commandDateAffect' &&
col.name !== 'commandDateSign' &&
col.name !== 'positionName' &&
col.name !== 'positionExecutive' &&
col.name !== 'positionExecutiveField' &&
col.name !== 'remark' &&
col.name !== 'positionType'
"
label-set="บันทึก"
label-cancel="ยกเลิก"
@save="onSave"
@save="
col.name === 'mouthSalaryAmount' ||
col.name === 'positionSalaryAmount' ||
col.name === 'commandDateAffect' ||
col.name === 'commandDateSign' ||
col.name === 'positionName' ||
col.name === 'positionExecutive' ||
col.name === 'positionExecutiveField' ||
col.name === 'remark' ||
col.name === 'positionType'
? null
: onSave
"
@before-show="onShow(props.row, col.name)"
>
<div class="q-mb-xs">
@ -1360,19 +1575,26 @@ onMounted(async () => {
@update:model-value="onUpdateData"
/>
<q-input
<CurruncyInput
v-else-if="
col.name === 'mouthSalaryAmount' ||
col.name === 'positionSalaryAmount'
"
:ref="`currencyRef_${col.name}`"
:edit="true"
dense
outlined
v-model="scope.value"
mask="###,###,###,###"
reverse-fill-mask
lazy-rules
hide-bottom-space
@update:model-value="onUpdateData"
:rules="[
(val:number) => {
if (!val) return true;
const numVal = typeof val === 'number' ? val : Number(String(val).replace(/,/g, ''));
return numVal <= 10000000 || `${col.label}ต้องไม่เกิน 10,000,000 บาท`;
}
]"
/>
<q-select
@ -1409,6 +1631,77 @@ onMounted(async () => {
</q-item>
</template>
</q-select>
<!-- Custom buttons สำหร persistent fields -->
<div
v-if="
col.name === 'mouthSalaryAmount' ||
col.name === 'positionSalaryAmount' ||
col.name === 'commandDateAffect' ||
col.name === 'commandDateSign'
"
class="row justify-around q-pt-sm"
>
<q-btn
flat
color="primary"
label="ยกเลิก"
@click="scope.cancel"
/>
<q-btn
flat
color="primary"
label="บันทึก"
@click="
col.name === 'mouthSalaryAmount' ||
col.name === 'positionSalaryAmount'
? validateAndSave(
scope.value,
props.row.id,
scope.cancel,
'currency'
)
: validateAndSave(
scope.value,
props.row.id,
scope.cancel,
'normal'
)
"
/>
</div>
<!-- Default buttons สำหร fields นๆ ไมใช persistent -->
<div
v-else-if="
col.name === 'positionName' ||
col.name === 'positionExecutive' ||
col.name === 'positionExecutiveField' ||
col.name === 'remark' ||
col.name === 'positionType'
"
class="row justify-around q-pt-sm"
>
<q-btn
flat
color="primary"
label="ยกเลิก"
@click="scope.cancel"
/>
<q-btn
flat
color="primary"
label="บันทึก"
@click="
validateAndSave(
scope.value,
props.row.id,
scope.cancel,
'normal'
)
"
/>
</div>
</q-popup-edit>
</div>
</q-td>

View file

@ -365,20 +365,24 @@ async function fetchDetailLeave(paramsId: string) {
formData.coupleDayLevelCountry = data.coupleDayLevelCountry
? data.coupleDayLevelCountry
: "-";
formData.coupleDayCountryHistory = data.coupleDayCountryHistory
? data.coupleDayCountryHistory
: "-";
formData.coupleDayTotalHistory = data.coupleDayTotalHistory
? data.coupleDayTotalHistory
: "-";
formData.coupleDayCountryHistory =
data.coupleDayCountryHistory && data.coupleDayCountryHistory !== "null"
? data.coupleDayCountryHistory
: "-";
formData.coupleDayTotalHistory =
data.coupleDayTotalHistory && data.coupleDayTotalHistory !== "null"
? data.coupleDayTotalHistory
: "-";
formData.coupleDayStartDateHistory =
data.coupleDayStartDateHistory &&
date2Thai(data.coupleDayStartDateHistory);
formData.coupleDayEndDateHistory =
data.coupleDayEndDateHistory && date2Thai(data.coupleDayEndDateHistory);
formData.coupleDaySumTotalHistory = data.coupleDaySumTotalHistory
? data.coupleDaySumTotalHistory
: "";
formData.coupleDaySumTotalHistory =
data.coupleDaySumTotalHistory &&
data.coupleDaySumTotalHistory !== "null"
? data.coupleDaySumTotalHistory
: "";
formData.approveStep = data.approveStep ? data.approveStep : "-";
formData.dear = data.dear ? data.dear : "-";
formData.profileType = data.profileType;

View file

@ -1,10 +1,10 @@
<script setup lang="ts">
/** importStore */
import { useCounterMixin } from "@/stores/mixin";
import { useLeavelistDataStore } from '@/modules/09_leave/stores/LeaveStore';
import { useLeavelistDataStore } from "@/modules/09_leave/stores/LeaveStore";
const store = useLeavelistDataStore()
const { converstType } = store
const store = useLeavelistDataStore();
const { converstType } = store;
const mixin = useCounterMixin();
const { calculateDurationYmd } = mixin;
@ -51,15 +51,40 @@ function convertDateToEng(dataThia: string) {
</div>
<div class="row">
<div class="col text-grey-8">ลาตงแตนท</div>
<div class="col">{{ props.data.leaveDateStart }} {{ `${props.data.leaveRange && props.data.leaveRange !== 'ALL' ? `(${converstType(props.data.leaveRange)})`:''}` }}</div>
<div class="col">
{{ props.data.leaveDateStart }}
{{
`${
props.data.leaveRange && props.data.leaveRange !== "ALL"
? `(${converstType(props.data.leaveRange)})`
: ""
}`
}}
</div>
</div>
<div class="row">
<div class="col text-grey-8">ลาถงวนท</div>
<div class="col">{{ props.data.leaveDateEnd }} {{ `${props.data.leaveDateStart !== props.data.leaveDateEnd ? `${props.data.leaveRangeEnd && props.data.leaveRangeEnd !== 'ALL' ? `(${converstType(props.data.leaveRangeEnd)})`:''}` :''}` }}</div>
<div class="col">
{{ props.data.leaveDateEnd }}
{{
`${
props.data.leaveDateStart !== props.data.leaveDateEnd
? `${
props.data.leaveRangeEnd &&
props.data.leaveRangeEnd !== "ALL"
? `(${converstType(props.data.leaveRangeEnd)})`
: ""
}`
: ""
}`
}}
</div>
</div>
<div class="row">
<div class="col text-grey-8">จำนวนวนทลา</div>
<div class="col">{{ props.data.leaveTotal ? props.data.leaveTotal + " วัน" : "-" }}</div>
<div class="col">
{{ props.data.leaveTotal ? props.data.leaveTotal + " วัน" : "-" }}
</div>
</div>
<div class="row">
<div class="col text-grey-8">นเดอนปเก</div>
@ -80,7 +105,9 @@ function convertDateToEng(dataThia: string) {
<div class="row">
<div class="col text-grey-8">เงนเดอนปจจ</div>
<div class="col">
{{ props.data.leaveSalary.toLocaleString() }} ({{ props.data.leaveSalaryText }})
{{ props.data.leaveSalary.toLocaleString() }} ({{
props.data.leaveSalaryText
}})
</div>
</div>
<div class="row">
@ -111,9 +138,15 @@ function convertDateToEng(dataThia: string) {
<div class="col">
<div>{{ props.data.coupleDayCountryHistory }}</div>
<div>{{ props.data.coupleDayTotalHistory }}</div>
<div>{{ props.data.coupleDayStartDateHistory }}</div>
<div>{{ props.data.coupleDayEndDateHistory }}</div>
<div>{{ props.data.coupleDaySumTotalHistory ? props.data.coupleDaySumTotalHistory + ` วัน`:'-'}}</div>
<div>{{ props.data.coupleDayStartDateHistory || "-" }}</div>
<div>{{ props.data.coupleDayEndDateHistory || "-" }}</div>
<div>
{{
props.data.coupleDaySumTotalHistory
? props.data.coupleDaySumTotalHistory + ` วัน`
: "-"
}}
</div>
</div>
</div>
<div class="row">

View file

@ -7,6 +7,7 @@ import config from "@/app.config";
/** importComponents*/
import Header from "@/components/DialogHeader.vue";
import CurruncyInput from "@/components/CurruncyInput.vue";
/** use*/
const $q = useQuasar();
@ -15,7 +16,7 @@ const { dialogConfirm, success, messageError, showLoader, hideLoader } = mixin;
/** props*/
const modal = defineModel<boolean>("modal", { required: true });
const amount = defineModel<number | null>("amount", { required: true });
const amount = defineModel<number | undefined>("amount", { required: true });
const profileId = defineModel<string>("profileId", { required: true });
const props = defineProps({
fetchData: {
@ -28,7 +29,7 @@ const props = defineProps({
*/
function close() {
modal.value = false;
amount.value = null;
amount.value = undefined;
}
/**
@ -36,7 +37,7 @@ function close() {
*/
function onSubmit() {
dialogConfirm($q, async () => {
if (amount.value !== null) {
if (amount.value !== undefined) {
showLoader();
const amountString: string = amount.value.toString();
const body = {
@ -73,7 +74,7 @@ function onSubmit() {
<q-card-section class="scroll" style="max-height: 70vh">
<div class="q-gutter-y-sm">
<q-input
<!-- <q-input
ref="amountRef"
dense
outlined
@ -85,6 +86,24 @@ function onSubmit() {
lazy-rules
hide-bottom-space
class="inputgreen"
/> -->
<CurruncyInput
class="inputgreen"
v-model="amount"
:edit="true"
dense
outlined
hide-bottom-space
lazy-rules
label="เงินเดือนฐาน"
:rules="[
(val:string) => !!val || 'กรุณากรอกเงินเดือนฐาน',
(val:number) => {
if (!val) return true;
const numVal = typeof val === 'number' ? val : Number(String(val).replace(/,/g, ''));
return numVal <= 10000000 || 'เงินเดือนฐานต้องไม่เกิน 10,000,000 บาท';
}
]"
/>
</div>
</q-card-section>

View file

@ -7,6 +7,7 @@ import config from "@/app.config";
/** importComponents*/
import Header from "@/components/DialogHeader.vue";
import CurruncyInput from "@/components/CurruncyInput.vue";
/** use*/
const $q = useQuasar();
@ -15,7 +16,7 @@ const { dialogConfirm, success, messageError, showLoader, hideLoader } = mixin;
/** props*/
const modal = defineModel<boolean>("modal", { required: true });
const amount = defineModel<number | null>("amount", { required: true });
const amount = defineModel<number | undefined>("amount", { required: true });
const profileId = defineModel<string>("profileId", { required: true });
const props = defineProps({
fetchData: {
@ -26,7 +27,7 @@ const props = defineProps({
/** function ปิด Popup */
function close() {
modal.value = false;
amount.value = null;
amount.value = undefined;
}
/**
@ -34,7 +35,7 @@ function close() {
*/
function onSubmit() {
dialogConfirm($q, async () => {
if (amount.value !== null) {
if (amount.value !== undefined) {
showLoader();
const amountString: string = amount.value.toString();
const body = {
@ -71,7 +72,7 @@ function onSubmit() {
<q-card-section class="scroll" style="max-height: 70vh">
<div class="q-gutter-y-sm">
<q-input
<!-- <q-input
ref="amountRef"
dense
outlined
@ -83,6 +84,24 @@ function onSubmit() {
lazy-rules
hide-bottom-space
class="inputgreen"
/> -->
<CurruncyInput
class="inputgreen"
v-model="amount"
:edit="true"
dense
outlined
hide-bottom-space
lazy-rules
label="เงินเดือนฐาน"
:rules="[
(val:string) => !!val || 'กรุณากรอกเงินเดือนฐาน',
(val:number) => {
if (!val) return true;
const numVal = typeof val === 'number' ? val : Number(String(val).replace(/,/g, ''));
return numVal <= 10000000 || 'เงินเดือนฐานต้องไม่เกิน 10,000,000 บาท';
}
]"
/>
</div>
</q-card-section>