From 7043c635d5f8a509c1ffe23483b27c15fe44f759 Mon Sep 17 00:00:00 2001 From: Thanaphon Frappet Date: Fri, 20 Dec 2024 15:56:23 +0700 Subject: [PATCH] refactor: use new select --- src/pages/05_quotation/QuotationForm.vue | 598 ++----------- .../QuotationFormWorkerSelect.vue | 831 ++++++++++++++++-- 2 files changed, 811 insertions(+), 618 deletions(-) diff --git a/src/pages/05_quotation/QuotationForm.vue b/src/pages/05_quotation/QuotationForm.vue index ea09ffab..bb25f7de 100644 --- a/src/pages/05_quotation/QuotationForm.vue +++ b/src/pages/05_quotation/QuotationForm.vue @@ -21,20 +21,18 @@ import { useInvoice, useReceipt, usePayment } from 'stores/payment'; import useCustomerStore from 'stores/customer'; import useOptionStore from 'stores/options'; import { useQuotationForm } from './form'; -import useOcrStore from 'stores/ocr'; import { deleteItem } from 'stores/utils'; -import { runOcr, parseResultMRZ } from 'src/utils/ocr'; // NOTE Import Types import { RequestData, RequestDataStatus } from 'src/stores/request-list/types'; import { View } from './types.ts'; import { + EmployeeWorker, PayCondition, ProductServiceList, QuotationPayload, } from 'src/stores/quotations/types'; -import { EmployeeWorker } from 'src/stores/quotations/types'; -import { Employee } from 'src/stores/employee/types'; +import { Employee, EmployeeWork } from 'src/stores/employee/types'; import { Receipt } from 'src/stores/payment/types'; import { ProductGroup, @@ -46,24 +44,17 @@ import { import TableRequest from './TableRequest.vue'; import SelectInput from 'components/shared/SelectInput.vue'; import SwitchItem from 'components/shared/SwitchItem.vue'; -import FormEmployeePassport from 'components/03_customer-management/FormEmployeePassport.vue'; -import FormEmployeeVisa from 'components/03_customer-management/FormEmployeeVisa.vue'; -import FormReferDocument from 'src/components/05_quotation/FormReferDocument.vue'; -import { UploadFileGroup, NoticeJobEmployment } from 'components/upload-file'; -import FormPerson from 'components/02_personnel-management/FormPerson.vue'; import ProductItem from 'components/05_quotation/ProductItem.vue'; import WorkerItem from 'components/05_quotation/WorkerItem.vue'; import ToggleButton from 'components/button/ToggleButton.vue'; import FormAbout from 'components/05_quotation/FormAbout.vue'; import SelectZone from 'components/shared/SelectZone.vue'; -import PersonCard from 'components/shared/PersonCard.vue'; import ImportWorker from './ImportWorker.vue'; import { AddButton, SaveButton, EditButton, UndoButton, - DeleteButton, CloseButton, MainButton, } from 'components/button'; @@ -72,12 +63,6 @@ import QuotationFormProductSelect from './QuotationFormProductSelect.vue'; import QuotationFormInfo from './QuotationFormInfo.vue'; import QuotationFormWorkerSelect from './QuotationFormWorkerSelect.vue'; import QuotationFormWorkerAddDialog from './QuotationFormWorkerAddDialog.vue'; -import ProfileBanner from 'components/ProfileBanner.vue'; -import DialogForm from 'components/DialogForm.vue'; -import { - uploadFileListEmployee, - columnsAttachment, -} from 'src/pages/03_customer-management/constant'; import UploadFileSection from 'src/components/upload-file/UploadFileSection.vue'; import { columnPaySplit } from './constants'; @@ -111,7 +96,6 @@ const route = useRoute(); const useReceiptStore = useReceipt(); const configStore = useConfigStore(); const productServiceStore = useProductServiceStore(); -const employeeFormStore = useEmployeeForm(); const customerStore = useCustomerStore(); const quotationForm = useQuotationForm(); const quotationStore = useQuotationStore(); @@ -120,7 +104,6 @@ const paymentStore = usePayment(); const optionStore = useOptionStore(); const requestStore = useRequestList(); const { t, locale } = useI18n(); -const ocrStore = useOcrStore(); const $q = useQuasar(); const openQuotation = ref(false); const formMetadata = ref(); @@ -145,8 +128,6 @@ const receiptList = ref([]); const templateForm = ref(''); const templateFormOption = ref<{ label: string; value: string }[]>([]); -const refSelectZoneEmployee = ref>(); -const mrz = ref>>(); const toggleWorker = ref(true); const tempTableProduct = ref([]); const tempPaySplitCount = ref(0); @@ -155,14 +136,12 @@ const tempPaySplit = ref< >([]); const currentQuotationId = ref(undefined); const date = ref(); -const preSelectedWorker = ref([]); const readonly = computed(() => { return !( quotationFormState.value.mode === 'create' || quotationFormState.value.mode === 'edit' ); }); -const test = ref(false); const selectedWorker = ref< (Employee & { @@ -175,30 +154,47 @@ const selectedWorker = ref< }[]; })[] >([]); -const selectedWorkerItem = computed(() => - selectedWorker.value.map((e) => ({ - foreignRefNo: e.employeePassport - ? e.employeePassport[0]?.number || '-' - : '-', - employeeName: - locale.value === Lang.English - ? `${e.firstNameEN} ${e.lastNameEN}` - : `${e.firstName} ${e.lastName}`, - birthDate: dateFormatJS({ date: e.dateOfBirth }), - gender: e.gender, - age: calculateAge(e.dateOfBirth), - nationality: optionStore.mapOption(e.nationality), - documentExpireDate: - e.employeePassport !== undefined && - e.employeePassport[0]?.expireDate !== undefined - ? dateFormatJS({ date: e.employeePassport[0]?.expireDate }) +const selectedWorkerItem = computed(() => { + return [ + ...selectedWorker.value.map((e) => ({ + foreignRefNo: e.employeePassport + ? e.employeePassport[0]?.number || '-' : '-', - imgUrl: e.selectedImage - ? `${API_BASE_URL}/employee/${e.id}/image/${e.selectedImage}` - : '', - status: e.status, - })), -); + employeeName: + locale.value === Lang.English + ? `${e.firstNameEN} ${e.lastNameEN}` + : `${e.firstName} ${e.lastName}`, + birthDate: dateFormatJS({ date: e.dateOfBirth }), + gender: e.gender, + age: calculateAge(e.dateOfBirth), + nationality: optionStore.mapOption(e.nationality), + documentExpireDate: + e.employeePassport !== undefined && + e.employeePassport[0]?.expireDate !== undefined + ? dateFormatJS({ date: e.employeePassport[0]?.expireDate }) + : '-', + imgUrl: e.selectedImage + ? `${API_BASE_URL}/employee/${e.id}/image/${e.selectedImage}` + : '', + status: e.status, + })), + + ...newWorkerList.value.map((v: any) => ({ + foreignRefNo: v.passportNo, + employeeName: + locale.value === Lang.English + ? `${v.firstNameEN} ${v.lastNameEN}` + : `${v.firstName} ${v.lastName}`, + birthDate: dateFormatJS({ date: v.dateOfBirth }), + gender: v.gender, + age: calculateAge(v.dateOfBirth), + nationality: optionStore.mapOption(v.nationality), + documentExpireDate: '-', + imgUrl: '', + status: 'CREATED', + })), + ]; +}); const workerList = ref([]); const selectedProductGroup = ref(''); @@ -300,36 +296,7 @@ const pageState = reactive({ const productList = ref>>({}); const serviceList = ref>>({}); const productGroup = ref([]); - -const { state: employeeFormState, currentFromDataEmployee } = - storeToRefs(employeeFormStore); - const selectedGroupSub = ref<'product' | 'service' | null>(null); -const formDataEmployee = ref< - EmployeeWorker & { - attachment?: { - name?: string; - group?: string; - url?: string; - file?: File; - _meta?: Record; - }[]; - } ->({ - passportNo: '', - documentExpireDate: new Date(), - lastNameEN: '', - lastName: '', - middleNameEN: '', - middleName: '', - firstNameEN: '', - firstName: '', - namePrefix: '', - nationality: '', - gender: '', - dateOfBirth: new Date(), - attachment: [], -}); const productServiceList = ref< Required[] @@ -599,16 +566,17 @@ async function convertDataToFormSubmit() { }); quotationFormData.value.worker = JSON.parse( - JSON.stringify( - selectedWorker.value.map((v) => { - if (v.id === undefined) { - const { attachment, ...payload } = v; - return payload; - } else { + JSON.stringify([ + ...selectedWorker.value.map((v) => { + { return v.id; } }), - ), + ...newWorkerList.value.map((v) => { + const { attachment, ...payload } = v; + return payload; + }), + ]), ); quotationFormData.value.paySplit = JSON.parse( @@ -639,6 +607,7 @@ async function convertDataToFormSubmit() { remark: quotationFormData.value.remark || '', }; + newWorkerList.value = []; const res = await quotationForm.submitQuotation(); if (res === true) { @@ -673,26 +642,6 @@ async function getAllProduct( if (ret) productList.value[groupId] = ret.result; } -function setDefaultFormEmployee() { - formDataEmployee.value = { - passportNo: '', - documentExpireDate: new Date(), - lastNameEN: '', - lastName: '', - middleNameEN: '', - middleName: '', - firstNameEN: '', - firstName: '', - namePrefix: '', - nationality: '', - gender: '', - dateOfBirth: new Date(), - attachment: [], - }; - - employeeFormState.value.dialogModal = false; -} - async function getAllService( groupId: string, opts?: { force?: boolean; page?: number; pageSize?: number; query?: string }, @@ -712,14 +661,6 @@ async function getAllService( if (ret) serviceList.value[groupId] = ret.result; } -function triggerCreateEmployee() { - employeeFormStore.resetFormDataEmployee(true); - setDefaultFormEmployee(); - employeeFormState.value.dialogType = 'create'; - employeeFormState.value.dialogModal = true; - employeeFormState.value.isEmployeeEdit = true; -} - async function triggerSelectEmployeeDialog() { pageState.employeeModal = true; await nextTick(); @@ -2275,10 +2216,11 @@ watch( v-model:open="pageState.employeeModal" @success=" (v) => { - selectedWorker = v; + console.log(v.newWorker); + selectedWorker = v.worker; + newWorkerList = v.newWorker; } " - @trigger-create-employee="() => triggerCreateEmployee()" /> @@ -2311,438 +2253,6 @@ watch( > - - - -
- -
-
-
-
-
- - - - -
-
- -
- - - - - - - -
-
-
-
- - - import { useI18n } from 'vue-i18n'; import { reactive, ref, watch } from 'vue'; -import { calculateAge } from 'src/utils/datetime'; +// NOTE: Import stores +import { dialog } from 'stores/utils'; import useOptionStore from 'src/stores/options'; import useEmployeeStore from 'src/stores/employee'; -import { useQuotationStore } from 'src/stores/quotations'; -import { Employee } from 'src/stores/employee/types'; +import { useEmployeeForm } from 'src/pages/03_customer-management/form'; +import { waitAll } from 'src/stores/utils'; +import { calculateAge, dateFormatJS } from 'src/utils/datetime'; +import { dialogCheckData } from 'stores/utils'; +import { useQuotationForm } from 'pages/05_quotation/form'; -import { CancelButton, MainButton } from 'components/button'; +// NOTE Import Types +import { Employee } from 'src/stores/employee/types'; +import { EmployeeWorker } from 'src/stores/quotations/types'; +import { runOcr, parseResultMRZ } from 'src/utils/ocr'; +import useOcrStore from 'stores/ocr'; + +// NOTE: Import Components +import { + SaveButton, + EditButton, + UndoButton, + DeleteButton, + MainButton, + CancelButton, +} from 'components/button'; import DialogContainer from 'components/dialog/DialogContainer.vue'; import DialogHeader from 'components/dialog/DialogHeader.vue'; import ImportWorker from './ImportWorker.vue'; import PersonCard from 'src/components/shared/PersonCard.vue'; -import { QuotationFull, EmployeeWorker } from 'src/stores/quotations/types'; +import NewPersonCard from 'src/components/shared/NewPersonCard.vue'; import { Lang } from 'src/utils/ui'; import NoData from 'src/components/NoData.vue'; +import FormEmployeePassport from 'components/03_customer-management/FormEmployeePassport.vue'; +import FormEmployeeVisa from 'components/03_customer-management/FormEmployeeVisa.vue'; +import FormReferDocument from 'src/components/05_quotation/FormReferDocument.vue'; +import { UploadFileGroup, NoticeJobEmployment } from 'components/upload-file'; +import FormPerson from 'components/02_personnel-management/FormPerson.vue'; +import ProfileBanner from 'components/ProfileBanner.vue'; +import DialogForm from 'components/DialogForm.vue'; +import { + uploadFileListEmployee, + columnsAttachment, +} from 'src/pages/03_customer-management/constant'; +import { storeToRefs } from 'pinia'; const API_BASE_URL = import.meta.env.VITE_API_BASE_URL; +const { t } = useI18n(); +const employeeFormStore = useEmployeeForm(); +const quotationForm = useQuotationForm(); const { locale } = useI18n(); +const ocrStore = useOcrStore(); -const props = defineProps<{ - customerBranchId?: string; - disabledWorkerId?: string[]; - preselectWorker?: Employee[]; -}>(); +const { state: employeeFormState, currentFromDataEmployee } = + storeToRefs(employeeFormStore); +const { newWorkerList } = storeToRefs(quotationForm); + +const mrz = ref>>(); + +const formDataEmployee = ref< + EmployeeWorker & { + attachment?: { + name?: string; + group?: string; + url?: string; + file?: File; + _meta?: Record; + }[]; + } +>({ + passportNo: '', + documentExpireDate: new Date(), + lastNameEN: '', + lastName: '', + middleNameEN: '', + middleName: '', + firstNameEN: '', + firstName: '', + namePrefix: '', + nationality: '', + gender: '', + dateOfBirth: new Date(), + attachment: [], +}); + +const props = withDefaults( + defineProps<{ + customerBranchId?: string; + disabledWorkerId?: string[]; + preselectWorker?: Employee[]; + }>(), + {}, +); const emits = defineEmits<{ (e: 'triggerCreateEmployee'): void; - (e: 'success', workerSelected: Employee[]): void; + ( + e: 'success', + data: { + worker: Employee[]; + newWorker: EmployeeWorker[]; + }, + ): void; }>(); const optionStore = useOptionStore(); const employeeStore = useEmployeeStore(); const open = defineModel('open', { default: false }); -const newWorkerList = defineModel('newWorkerList', { - default: [], -}); const workerSelected = ref([]); const workerList = ref([]); const importWorkerCriteria = ref<{ @@ -55,6 +127,49 @@ const state = reactive({ search: '', }); +function removeNewWorker(index: number) { + dialog({ + color: 'negative', + icon: 'mdi-trash-can-outline', + title: t('dialog.title.confirmDelete'), + actionText: t('general.delete'), + persistent: true, + message: t('dialog.message.confirmDelete'), + action: async () => { + newWorkerList.value.splice(index, 1); + }, + cancel: () => {}, + }); +} + +function triggerCreateEmployee() { + employeeFormStore.resetFormDataEmployee(true); + setDefaultFormEmployee(); + employeeFormState.value.dialogType = 'create'; + employeeFormState.value.dialogModal = true; + employeeFormState.value.isEmployeeEdit = true; +} + +function setDefaultFormEmployee() { + formDataEmployee.value = { + passportNo: '', + documentExpireDate: new Date(), + lastNameEN: '', + lastName: '', + middleNameEN: '', + middleName: '', + firstNameEN: '', + firstName: '', + namePrefix: '', + nationality: '', + gender: '', + dateOfBirth: new Date(), + attachment: [], + }; + + employeeFormState.value.dialogModal = false; +} + function clean() { workerList.value = []; workerSelected.value = []; @@ -163,7 +278,7 @@ watch(() => state.search, getWorkerList); clickable class="row items-center" style="white-space: nowrap" - @click.stop="() => emits('triggerCreateEmployee')" + @click.stop="() => triggerCreateEmployee()" > state.search, getWorkerList); -
-
+ -
- -
-
- +
+ +
+
+ +
+
- + + + + + +
+
+
+ +
+
+ +
+
+
+
+ + + + +
+ +
+
+
+
+
+ + + + +
+
+ +
+ + + + + + + +
+
+
+
+ +