import { ref, watch } from 'vue'; import { defineStore } from 'pinia'; import { useI18n } from 'vue-i18n'; import { CustomerBranch, CustomerBranchCreate, CustomerCreate, CustomerType, } from 'stores/customer/types'; import { Employee, EmployeeCreate } from 'stores/employee/types'; import { dialog } from 'stores/utils'; import useMyBranch from 'stores/my-branch'; import useCustomerStore from 'stores/customer'; import useEmployeeStore from 'stores/employee'; import useFlowStore from 'stores/flow'; import useMyBranchStore from 'stores/my-branch'; import { baseUrl } from 'src/stores/utils'; import { getRole, getUserId } from 'src/services/keycloak'; import { useRoute } from 'vue-router'; export const useCustomerForm = defineStore('form-customer', () => { const customerStore = useCustomerStore(); const onCreateImageList = ref<{ selectedImage: string; list: { url: string; imgFile: File | null; name: string }[]; }>({ selectedImage: '', list: [] }); const { t } = useI18n(); const flowStore = useFlowStore(); const userBranchStore = useMyBranchStore(); const registerAbleBranchOption = ref<{ id: string; name: string }[]>(); const currentBranchRootId = ref(''); const tabFieldRequired = ref<{ [key: string]: (keyof CustomerBranchCreate)[]; }>({ main: [], business: ['businessTypeId', 'jobPosition'], address: [ 'address', 'addressEN', 'provinceId', 'districtId', 'subDistrictId', ], contact: [], }); const defaultFormData: CustomerCreate = { // code: '', // namePrefix: '', // firstName: '', // lastName: '', // firstNameEN: '', // lastNameEN: '', // gender: '', // birthDate: new Date(), customerBranch: [], selectedImage: '', status: 'CREATED', customerType: CustomerType.Corporate, registeredBranchId: '', image: null, }; let resetFormData = structuredClone(defaultFormData); const currentFormData = ref(structuredClone(defaultFormData)); const state = ref<{ dialogType: 'info' | 'create' | 'edit'; dialogOpen: boolean; dialogModal: boolean; drawerModal: boolean; branchIndex: number; customerImageUrl: string; defaultCustomerImageUrl: string; imageDialog: boolean; imageEdit: boolean; readonly: boolean; editCustomerId?: string; editCustomerCode?: string; editCustomerBranchId?: string; treeFile: { label: string; file: { label: string }[] }[]; formDataOcr: Record; isImageEdit: boolean; currentCustomerId?: string; }>({ dialogType: 'info', dialogOpen: false, dialogModal: false, drawerModal: false, imageDialog: false, branchIndex: -1, readonly: true, imageEdit: false, customerImageUrl: '', editCustomerId: undefined, editCustomerBranchId: '', defaultCustomerImageUrl: '', treeFile: [], formDataOcr: {}, isImageEdit: false, }); watch( currentFormData, (v) => (defaultFormData.customerType = v.customerType), ); async function deleteAttachment( id: { branchId: string; customerId: string }, filename: string, ) { const res = await customerStore.deleteAttachment(id.branchId, filename); if (res) { assignFormData(id.customerId); } } function isFormDataDifferent() { const { status: resetStatus, ...resetData } = resetFormData; const { status: currStatus, ...currData } = currentFormData.value; return JSON.stringify(resetData) !== JSON.stringify(currData); } function resetForm(clean = false) { state.value.branchIndex = -1; if (clean) { defaultFormData.customerType = currentFormData.value.customerType; currentFormData.value = structuredClone(defaultFormData); resetFormData = structuredClone(defaultFormData); resetFormData.registeredBranchId = ''; state.value.editCustomerId = ''; state.value.treeFile = []; return; } if (state.value.dialogType === 'create') { state.value.editCustomerId = ''; } const currentImg = currentFormData.value.selectedImage; currentFormData.value = structuredClone(resetFormData); currentFormData.value.selectedImage = currentImg; } async function assignFormData(id?: string) { state.value.readonly = true; if (!id) { resetFormData = structuredClone(defaultFormData); return; } const data = await customerStore.fetchById(id); if (!data) return; state.value.dialogType = 'edit'; state.value.editCustomerId = id; state.value.editCustomerCode = data.code; state.value.customerImageUrl = `${baseUrl}/customer/${id}/image/${data.selectedImage}`; state.value.defaultCustomerImageUrl = `${baseUrl}/customer/${id}/image/${data.selectedImage}`; currentBranchRootId.value = data.branch[0].id || ''; resetFormData.registeredBranchId = data.registeredBranchId; resetFormData.status = data.status; resetFormData.customerType = data.customerType; resetFormData.image = null; resetFormData.selectedImage = data.selectedImage; resetFormData.customerBranch = await Promise.all( data.branch.map(async (v) => ({ firstName: v.firstName, firstNameEN: v.firstNameEN, lastName: v.lastName, lastNameEN: v.lastNameEN, gender: v.gender, birthDate: v.birthDate, namePrefix: v.namePrefix, wageRate: v.wageRate, wageRateText: v.wageRateText, payDate: v.payDate, jobDescription: v.jobDescription, jobPosition: v.jobPosition, businessTypeId: v.businessTypeId, employmentOffice: v.employmentOffice, employmentOfficeEN: v.employmentOfficeEN, telephoneNo: v.telephoneNo, contactName: v.contactName, email: v.email, subDistrictId: v.subDistrictId, districtId: v.districtId, provinceId: v.provinceId, streetEN: v.streetEN, street: v.street, mooEN: v.mooEN, moo: v.moo, soiEN: v.soiEN, soi: v.soi, addressEN: v.addressEN, address: v.address, authorizedCapital: v.authorizedCapital, registerDate: v.registerDate, registerNameEN: v.registerNameEN, registerName: v.registerName, legalPersonNo: v.legalPersonNo, citizenId: v.citizenId, codeCustomer: v.codeCustomer, updatedByUserId: v.updatedByUserId, updatedAt: v.updatedAt, createdByUserId: v.createdByUserId, createdAt: v.createdAt, code: v.code, statusOrder: v.statusOrder, status: v.status, customerId: v.customerId, id: v.id, homeCode: v.homeCode, contactTel: v.contactTel, officeTel: v.officeTel, agentUserId: v.agentUserId || undefined, authorizedName: v.authorizedName, authorizedNameEN: v.authorizedNameEN, payDateEN: v.payDateEN, statusSave: true, file: await customerStore .listAttachment({ parentId: v.id }) .then(async (r) => { if (r) { return await Promise.all( r.map(async (item) => { const fragment = item.split('-'); const group = fragment.length === 1 ? 'other' : fragment.at(0); return { url: await customerStore.getAttachment({ parentId: v.id, name: item, }), name: item, group: group, }; }), ); } return []; }), })), ); currentFormData.value = structuredClone(resetFormData); } async function addCurrentCustomerBranch() { if (currentFormData.value.customerBranch?.some((v) => !v.id)) return; currentFormData.value.customerBranch?.push({ customerId: '', branchCode: currentFormData.value.customerBranch.length !== 0 ? currentFormData.value.customerBranch?.[0].branchCode === null ? '' : currentFormData.value.customerBranch?.[0].branchCode : '', codeCustomer: undefined, legalPersonNo: currentFormData.value.customerBranch.length !== 0 ? currentFormData.value.customerBranch?.[0].legalPersonNo === null ? '' : currentFormData.value.customerBranch?.[0].legalPersonNo : '', citizenId: currentFormData.value.customerBranch.length !== 0 ? currentFormData.value.customerBranch?.[0].citizenId === null ? '' : currentFormData.value.customerBranch?.[0].citizenId : '', namePrefix: currentFormData.value.customerBranch?.at(0)?.namePrefix || '', firstName: currentFormData.value.customerBranch?.at(0)?.firstName || '', lastName: currentFormData.value.customerBranch?.at(0)?.lastName || '', firstNameEN: currentFormData.value.customerBranch?.at(0)?.firstNameEN || '', lastNameEN: currentFormData.value.customerBranch?.at(0)?.lastNameEN || '', telephoneNo: currentFormData.value.customerBranch?.at(0)?.telephoneNo || '', gender: currentFormData.value.customerBranch?.at(0)?.gender || '', birthDate: currentFormData.value.customerBranch?.at(0)?.birthDate || undefined, businessTypeId: currentFormData.value.customerBranch?.at(0)?.businessTypeId || '', jobPosition: currentFormData.value.customerBranch?.at(0)?.jobPosition || '', jobDescription: currentFormData.value.customerBranch?.at(0)?.jobDescription || '', payDate: currentFormData.value.customerBranch?.at(0)?.payDate || '', payDateEN: currentFormData.value.customerBranch?.at(0)?.payDateEN || '', wageRate: currentFormData.value.customerBranch?.at(0)?.wageRate || 0, wageRateText: currentFormData.value.customerBranch?.at(0)?.wageRateText || '', homeCode: currentFormData.value.customerBranch?.at(0)?.homeCode || '', employmentOffice: currentFormData.value.customerBranch?.at(0)?.employmentOffice || '', employmentOfficeEN: currentFormData.value.customerBranch?.at(0)?.employmentOfficeEN || '', address: '', addressEN: '', street: '', streetEN: '', moo: '', mooEN: '', soi: '', soiEN: '', provinceId: '', districtId: '', subDistrictId: '', contactName: currentFormData.value.customerBranch?.at(0)?.contactTel || '', email: currentFormData.value.customerBranch?.at(0)?.email || '', contactTel: currentFormData.value.customerBranch?.at(0)?.contactTel || '', officeTel: currentFormData.value.customerBranch?.at(0)?.officeTel || '', agentUserId: currentFormData.value.customerBranch?.at(0)?.agentUserId || undefined, status: 'CREATED', registerName: currentFormData.value.customerBranch?.at(0)?.registerName || '', registerNameEN: currentFormData.value.customerBranch?.at(0)?.registerNameEN || '', registerDate: currentFormData.value.customerBranch?.at(0)?.registerDate || null, authorizedCapital: currentFormData.value.customerBranch?.at(0)?.authorizedCapital || '', authorizedName: currentFormData.value.customerBranch?.at(0)?.authorizedName || '', authorizedNameEN: currentFormData.value.customerBranch?.at(0)?.authorizedNameEN || '', file: [], }); state.value.branchIndex = (currentFormData.value.customerBranch?.length || 0) - 1; } async function submitFormCustomer(imgList?: { selectedImage: string; list: { url: string; imgFile: File | null; name: string }[]; }) { if (state.value.dialogType === 'info') return; if (state.value.dialogType === 'create') { const _data = await customerStore.create(currentFormData.value, imgList); if (_data) await assignFormData(_data.id); return; } if (!state.value.editCustomerId) { throw new Error( 'Form mode is set to edit but no ID is provided. Make sure to set customer ID.', ); } const { code: _, ...payload } = currentFormData.value; const _data = await customerStore.editById(state.value.editCustomerId, { ...payload, status: currentFormData.value.status !== 'CREATED' ? currentFormData.value.status : undefined, image: currentFormData.value.image || undefined, customerBranch: undefined, }); if (_data) { await assignFormData(_data.id); state.value.dialogType = 'edit'; state.value.readonly = true; state.value.editCustomerId = _data.id; } } async function fetchListOfOptionBranch() { if (registerAbleBranchOption.value) return; const uid = getUserId(); const role = getRole(); if (!uid) return; // should not possible as the system require login to be able to access resource. if (role?.includes('system')) { const result = await userBranchStore.fetchListOptionBranch(); if (result && result.total > 0) registerAbleBranchOption.value = result.result; } else { const result = await userBranchStore.fetchListMyBranch(uid); if (result && result.total > 0) registerAbleBranchOption.value = result.result; } // TODO: Assign (first) branch of the user as register branch of the data } function customerFormUndo(close = true) { if (isFormDataDifferent()) { return customerConfirmUnsave(close); } resetForm(); state.value.readonly = true; } function customerConfirmUnsave(close = true) { dialog({ color: 'warning', icon: 'mdi-alert', title: t('form.warning.title'), actionText: t('general.ok'), persistent: true, message: t('form.warning.unsave'), action: () => { resetForm(); state.value.readonly = true; if (!state.value.drawerModal) { state.value.dialogModal = !close; } else { state.value.drawerModal = !close; } }, cancel: () => {}, }); } function deleteCustomerById( id: string, fetch?: (...args: unknown[]) => unknown, ) { dialog({ color: 'negative', icon: 'mdi-alert', title: t('dialog.title.confirmDelete'), actionText: t('general.delete'), persistent: true, message: t('dialog.message.confirmDelete'), action: async () => { await customerStore.deleteById(id); await fetch(); state.value.dialogModal = false; flowStore.rotate(); }, cancel: () => {}, }); } function validateTabField( value: T, fieldRequired: { [key: string]: (keyof T)[] }, ) { const list: string[] = []; for (const tab in fieldRequired) { for (const field of fieldRequired[tab]) { if (!value[field] && !list.includes(tab)) list.push(tab); } } return list; } async function deleteCustomerBranchById(id: string) { return await new Promise((resolve) => { dialog({ color: 'negative', icon: 'mdi-alert', title: t('dialog.title.confirmDelete'), actionText: t('general.delete'), persistent: true, message: t('dialog.message.confirmDelete'), action: async () => { await customerStore.deleteBranchById(id); flowStore.rotate(); resolve(true); }, cancel: () => { resolve(false); }, }); }); } return { onCreateImageList, tabFieldRequired, registerAbleBranchOption, state, resetFormData, currentFormData, currentBranchRootId, isFormDataDifferent, resetForm, assignFormData, submitFormCustomer, addCurrentCustomerBranch, deleteAttachment, fetchListOfOptionBranch, customerFormUndo, customerConfirmUnsave, deleteCustomerById, validateTabField, deleteCustomerBranchById, }; }); export const useCustomerBranchForm = defineStore('form-customer-branch', () => { const customerStore = useCustomerStore(); const customerFormStore = useCustomerForm(); const defaultFormData: CustomerBranchCreate & { id?: string; codeCustomer?: string; } = { id: undefined, customerId: '', // branchCode: '', // codeCustomer: '', legalPersonNo: '', citizenId: '', namePrefix: '', firstName: '', lastName: '', firstNameEN: '', lastNameEN: '', telephoneNo: '', gender: '', birthDate: undefined, businessTypeId: '', jobPosition: '', jobDescription: '', payDate: '', payDateEN: '', wageRate: 0, wageRateText: '', homeCode: '', employmentOffice: '', employmentOfficeEN: '', address: '', addressEN: '', street: '', streetEN: '', moo: '', mooEN: '', soi: '', soiEN: '', provinceId: '', districtId: '', subDistrictId: '', contactName: '', email: '', contactTel: '', officeTel: '', agentUserId: undefined, status: 'CREATED', registerName: '', registerNameEN: '', registerDate: undefined, authorizedCapital: '', authorizedName: '', authorizedNameEN: '', file: [], }; let resetFormData = structuredClone(defaultFormData); const currentFormData = ref< CustomerBranchCreate & { id?: string; codeCustomer?: string } >(structuredClone(defaultFormData)); const state = ref<{ dialogType: 'info' | 'create' | 'edit'; dialogOpen: boolean; dialogModal: boolean; currentCustomerId: string; customerType?: 'CORP' | 'PERS'; }>({ dialogType: 'info', dialogOpen: false, dialogModal: false, currentCustomerId: '', }); async function initForm(form: 'create'): Promise; async function initForm(form: 'info' | 'edit', id: string): Promise; async function initForm(form: 'info' | 'create' | 'edit', id?: string) { state.value.dialogType = form; resetFormData = structuredClone(defaultFormData); if (!id) return; const _data = await customerStore.getBranchById(id); if (!_data) return; resetFormData = { id: _data.id, code: _data.code, provinceId: _data.provinceId, districtId: _data.districtId, subDistrictId: _data.subDistrictId, wageRate: _data.wageRate, payDate: _data.payDate, // Convert the string to a Date object payDateEN: _data.payDateEN, jobDescription: _data.jobDescription, jobPosition: _data.jobPosition, businessTypeId: _data.businessTypeId, employmentOffice: _data.employmentOffice, employmentOfficeEN: _data.employmentOfficeEN, telephoneNo: _data.telephoneNo, email: _data.email, addressEN: _data.addressEN, address: _data.address, status: 'CREATED', customerId: _data.customerId, citizenId: _data.citizenId, authorizedCapital: _data.authorizedCapital, registerDate: new Date(), // Convert the string to a Date object registerNameEN: _data.registerNameEN, registerName: _data.registerName, legalPersonNo: _data.legalPersonNo, contactName: _data.contactName, namePrefix: _data.namePrefix, firstName: _data.firstName, firstNameEN: _data.firstNameEN, lastName: _data.lastName, lastNameEN: _data.lastNameEN, gender: _data.gender, birthDate: _data.birthDate, moo: _data.moo, mooEN: _data.mooEN, soi: _data.soi, soiEN: _data.soiEN, street: _data.street, streetEN: _data.streetEN, wageRateText: _data.wageRateText, contactTel: _data.contactTel, officeTel: _data.officeTel, agentUserId: _data.agentUserId || undefined, codeCustomer: _data.codeCustomer, homeCode: _data.homeCode, authorizedName: _data.authorizedName, authorizedNameEN: _data.authorizedNameEN, file: [], }; currentFormData.value = structuredClone(resetFormData); } function resetForm() { resetFormData = structuredClone(defaultFormData); currentFormData.value = structuredClone(resetFormData); } function isFormDataDifferent() { return ( JSON.stringify(resetFormData) !== JSON.stringify(currentFormData.value) ); } watch( () => state.value.dialogType, () => { if (state.value.dialogType === 'create') { currentFormData.value = structuredClone(defaultFormData); } }, ); async function submitForm() { if (!state.value.currentCustomerId) { throw new Error( 'Employer id cannot be found. Did you properly set employer id?', ); } if (!currentFormData.value.id) { const res = await customerStore.createBranch({ ...currentFormData.value, citizenId: (state.value.customerType || customerFormStore.currentFormData.customerType) === 'CORP' ? undefined : currentFormData.value.citizenId, customerId: state.value.currentCustomerId, }); if (res) return res; } else { const res = await customerStore.editBranchById(currentFormData.value.id, { ...currentFormData.value, id: undefined, }); if (res) return res; } } return { state, currentFormData, initForm, isFormDataDifferent, submitForm, resetForm, }; }); export const useEmployeeForm = defineStore('form-employee', () => { const { t } = useI18n(); const customerStore = useCustomerStore(); const employeeStore = useEmployeeStore(); const flowStore = useFlowStore(); const branchStore = useMyBranch(); const route = useRoute(); const refreshImageState = ref(false); const onCreateImageList = ref<{ selectedImage: string; list: { url: string; imgFile: File | null; name: string }[]; }>({ selectedImage: '', list: [] }); const statusEmployeeCreate = ref(false); const state = ref<{ dialogType: 'info' | 'create' | 'edit'; imageDialog: boolean; currentTab: string; dialogModal: boolean; drawerModal: boolean; isImageEdit: boolean; currentBranchId: string; currentCustomerBranch?: CustomerBranch; currentEmployeeCode: string; currentEmployee: Employee | null; currentIndexPassport: number; currentIndexVisa: number; currentIndexCheckup: number; currentIndexWorkHistory: number; profileUrl: string; isEmployeeEdit: boolean; profileSubmit: boolean; formDataEmployeeSameAddr: boolean; editReadonly: boolean; statusSavePersonal: boolean; infoEmployeePersonCard: { id: string; img?: string; name: string; male: boolean; female: boolean; badge: string; disabled: boolean; }[]; formDataEmployeeOwner: | { id: string; address: string; addressEN: string; provinceId: string; districtId: string; subDistrictId: string; } | undefined; ocr: boolean; }>({ currentBranchId: '', isImageEdit: false, currentIndexPassport: -1, currentIndexVisa: -1, currentIndexCheckup: -1, currentIndexWorkHistory: -1, statusSavePersonal: false, drawerModal: false, imageDialog: false, currentTab: 'personalInfo', dialogModal: false, dialogType: 'info', currentEmployeeCode: '', currentEmployee: null, profileUrl: '', isEmployeeEdit: false, profileSubmit: false, formDataEmployeeSameAddr: true, editReadonly: false, infoEmployeePersonCard: [], formDataEmployeeOwner: undefined, ocr: false, }); const defaultFormData: EmployeeCreate & { image?: File } = { id: '', code: '', customerBranchId: '', nrcNo: '', dateOfBirth: null, gender: '', nationality: '', status: 'CREATED', namePrefix: '', firstName: '', firstNameEN: '', lastName: '', lastNameEN: '', middleName: '', middleNameEN: '', addressEN: '', address: '', street: '', streetEN: '', moo: '', mooEN: '', soi: '', soiEN: '', subDistrictId: '', districtId: '', provinceId: '', employeeCheckup: [ { coverageExpireDate: null, coverageStartDate: null, insuranceCompany: '', medicalBenefitScheme: '', remark: '', hospitalName: '', provinceId: '', checkupResult: '', checkupType: '', }, ], employeeWork: [ { workPermitExpireDate: null, workPermitIssueDate: null, workPermitNo: '', workplace: '', jobType: '', positionName: '', ownerName: '', }, ], employeeInCountryNotice: [ { noticeNumber: '', noticeDate: '', nextNoticeDate: new Date(), tmNumber: '', entryDate: new Date(), travelBy: '', travelFrom: '', }, ], employeeVisa: [ { arrivalAt: '', arrivalTMNo: '', arrivalTM: '', mrz: undefined, entryCount: 0, issuePlace: '', issueCountry: '', issueDate: new Date(), type: '', expireDate: new Date(), remark: undefined, workerType: '', reportDate: null, number: '', }, ], employeePassport: [ { birthCountry: '', previousPassportRef: '', issuePlace: '', issueCountry: '', issueDate: new Date(), type: '', expireDate: new Date(), birthDate: new Date(), workerStatus: '', nationality: '', gender: '', lastNameEN: '', lastName: '', middleNameEN: '', middleName: '', firstNameEN: '', firstName: '', namePrefix: '', number: '', }, ], employeeOtherInfo: { citizenId: '', fatherFirstName: '', fatherLastName: '', fatherFirstNameEN: '', fatherLastNameEN: '', fatherBirthPlace: '', motherFirstName: '', motherLastName: '', motherFirstNameEN: '', motherLastNameEN: '', motherBirthPlace: '', }, }; let resetEmployeeData = structuredClone(defaultFormData); const currentFromDataEmployee = ref( structuredClone(defaultFormData), ); function isFormDataDifferent() { return ( JSON.stringify(resetEmployeeData) !== JSON.stringify(currentFromDataEmployee.value) ); } // function resetFormDataEmployee(cb?: (...args: any[]) => unknown) { // state.value.dialogType = 'create'; // currentFromDataEmployee.value = structuredClone(resetEmployeeData); // cb?.(); // } function resetFormDataEmployee(clean = false) { state.value.currentIndexPassport = -1; state.value.currentIndexVisa = -1; state.value.currentIndexCheckup = -1; state.value.currentIndexWorkHistory = -1; // state.value.currentTab = 'personalInfo'; if (clean) { state.value.formDataEmployeeOwner = undefined; resetEmployeeData = structuredClone(defaultFormData); state.value.statusSavePersonal = false; state.value.profileUrl = ''; state.value.currentBranchId = ''; } else { resetEmployeeData.selectedImage = currentFromDataEmployee.value.selectedImage; } currentFromDataEmployee.value = structuredClone(resetEmployeeData); } async function submitPassport() { if ( currentFromDataEmployee.value.employeePassport?.[ state.value.currentIndexPassport ] === undefined ) return; if ( currentFromDataEmployee.value.employeePassport?.[ state.value.currentIndexPassport ].id === undefined ) { const { id, employeeId, updatedAt, createdAt, file, ...payload } = currentFromDataEmployee.value.employeePassport?.[ state.value.currentIndexPassport ]; const res = await employeeStore.postMeta({ parentId: currentFromDataEmployee.value.id || '', group: 'passport', meta: payload, file: file, }); if (res) { currentFromDataEmployee.value.employeePassport[ state.value.currentIndexPassport ].id = res.id; } } if ( currentFromDataEmployee.value.employeePassport?.[ state.value.currentIndexPassport ].id !== undefined ) { const { id, employeeId, updatedAt, createdAt, file, ...payload } = currentFromDataEmployee.value.employeePassport?.[ state.value.currentIndexPassport ]; await employeeStore.putMeta({ parentId: currentFromDataEmployee.value.id || '', group: 'passport', metaId: currentFromDataEmployee.value.employeePassport?.[ state.value.currentIndexPassport ].id || '', meta: payload, file: file || undefined, }); } await assignFormDataEmployee(currentFromDataEmployee.value.id); state.value.currentIndexPassport = -1; } async function submitVisa() { if ( currentFromDataEmployee.value.employeeVisa?.[ state.value.currentIndexVisa ] === undefined ) return; if ( currentFromDataEmployee.value.employeeVisa?.[state.value.currentIndexVisa] .id === undefined ) { const res = await employeeStore.postMeta({ parentId: currentFromDataEmployee.value.id || '', group: 'visa', meta: currentFromDataEmployee.value.employeeVisa?.[ state.value.currentIndexVisa ], }); if (res) { currentFromDataEmployee.value.employeeVisa[ state.value.currentIndexVisa ].id = res.id; } } if ( currentFromDataEmployee.value.employeeVisa?.[state.value.currentIndexVisa] .id !== undefined ) { const { id, updatedAt, createdAt, employeeId, ...payload } = currentFromDataEmployee.value.employeeVisa?.[ state.value.currentIndexVisa ]; await employeeStore.putMeta({ parentId: currentFromDataEmployee.value.id || '', group: 'visa', metaId: currentFromDataEmployee.value.employeeVisa?.[ state.value.currentIndexVisa ].id || '', meta: payload, }); } await assignFormDataEmployee(currentFromDataEmployee.value.id); state.value.currentIndexVisa = -1; } async function submitOther() { if (!currentFromDataEmployee.value.employeeOtherInfo) return; if (!currentFromDataEmployee.value.employeeOtherInfo.id) { const res = await employeeStore.createEmployeeOtherInfo( currentFromDataEmployee.value?.id || '', currentFromDataEmployee.value.employeeOtherInfo, ); if (res) { currentFromDataEmployee.value.employeeOtherInfo.id = res.id; currentFromDataEmployee.value.employeeOtherInfo.statusSave = true; } } else { const res = await employeeStore.editByIdEmployeeOtherInfo( currentFromDataEmployee.value?.id || '', currentFromDataEmployee.value.employeeOtherInfo, ); if (res) { currentFromDataEmployee.value.employeeOtherInfo.statusSave = true; } } await assignFormDataEmployee(currentFromDataEmployee.value.id); } async function deletePassport(index: number) { const res = await employeeStore.delMeta({ parentId: currentFromDataEmployee.value.id || '', group: 'passport', metaId: currentFromDataEmployee.value.employeePassport?.[index].id || '', }); if (res) { currentFromDataEmployee.value.employeePassport?.splice(index, 1); await assignFormDataEmployee(currentFromDataEmployee.value.id); } } async function deleteVisa(index: number) { const res = await employeeStore.delMeta({ parentId: currentFromDataEmployee.value.id || '', group: 'visa', metaId: currentFromDataEmployee.value.employeeVisa?.[index].id || '', }); if (res) { currentFromDataEmployee.value.employeeVisa?.splice(index, 1); await assignFormDataEmployee(currentFromDataEmployee.value.id); } } async function deleteWorkHistory(index: number) { if (!currentFromDataEmployee.value.employeeWork) return; const res = await employeeStore.deleteByIdWork({ employeeId: currentFromDataEmployee.value.id || '', workId: currentFromDataEmployee.value.employeeWork[index]?.id, }); if (res) { state.value.currentIndexWorkHistory = -1; await assignFormDataEmployee(currentFromDataEmployee.value.id); } } async function deleteHealthCheck(index: number) { if (!currentFromDataEmployee.value.employeeCheckup) return; const res = await employeeStore.deleteByIdCheckUp({ employeeId: currentFromDataEmployee.value.id || '', checkUpId: currentFromDataEmployee.value.employeeCheckup[index]?.id, }); if (res) { state.value.currentIndexCheckup = -1; await assignFormDataEmployee(currentFromDataEmployee.value.id); } } async function submitWorkHistory() { if (!currentFromDataEmployee.value.employeeWork) return; if ( !currentFromDataEmployee.value.employeeWork[ state.value.currentIndexWorkHistory ].id ) { const res = await employeeStore.createEmployeeWork( currentFromDataEmployee.value?.id || '', currentFromDataEmployee.value.employeeWork[ state.value.currentIndexWorkHistory ], ); if (res) { currentFromDataEmployee.value.employeeWork[ state.value.currentIndexWorkHistory ].id = res.id; currentFromDataEmployee.value.employeeWork[ state.value.currentIndexWorkHistory ].statusSave = true; } } else { const data = currentFromDataEmployee.value?.employeeWork[ state.value.currentIndexWorkHistory ]; const res = await employeeStore.editByIdEmployeeWork( currentFromDataEmployee.value?.id || '', data, ); if (res) { currentFromDataEmployee.value.employeeWork[ state.value.currentIndexWorkHistory ].statusSave = true; } } state.value.currentIndexWorkHistory = -1; await assignFormDataEmployee(currentFromDataEmployee.value.id); } async function submitHealthCheck() { if (!currentFromDataEmployee.value.employeeCheckup) return; if ( !currentFromDataEmployee.value.employeeCheckup[ state.value.currentIndexCheckup ].id ) { const res = await employeeStore.createEmployeeCheckup( state.value.currentEmployee?.id || '', currentFromDataEmployee.value.employeeCheckup[ state.value.currentIndexCheckup ], ); if (res) { currentFromDataEmployee.value.employeeCheckup[ state.value.currentIndexCheckup ].id = res.id; currentFromDataEmployee.value.employeeCheckup[ state.value.currentIndexCheckup ].statusSave = true; } } else { const data = currentFromDataEmployee.value.employeeCheckup[ state.value.currentIndexCheckup ]; const res = await employeeStore.editByIdEmployeeCheckup( state.value.currentEmployee?.id || '', data, ); if (res) { currentFromDataEmployee.value.employeeCheckup[ state.value.currentIndexCheckup ].statusSave = true; } } state.value.currentIndexCheckup = -1; await assignFormDataEmployee(currentFromDataEmployee.value.id); } async function submitPersonal(imgList?: { selectedImage: string; list: { url: string; imgFile: File | null; name: string }[]; }) { let employeeId: string | undefined = undefined; currentFromDataEmployee.value.firstName = currentFromDataEmployee.value.firstName.trim(); currentFromDataEmployee.value.middleName = currentFromDataEmployee.value.middleName?.trim(); currentFromDataEmployee.value.lastName = currentFromDataEmployee.value.lastName.trim(); currentFromDataEmployee.value.firstNameEN = currentFromDataEmployee.value.firstNameEN.trim(); currentFromDataEmployee.value.middleNameEN = currentFromDataEmployee.value.middleNameEN?.trim(); currentFromDataEmployee.value.lastNameEN = currentFromDataEmployee.value.lastNameEN.trim(); if (state.value.dialogType === 'create') { delete currentFromDataEmployee.value.image; const res = await employeeStore.create( { ...currentFromDataEmployee.value, customerBranchId: state.value.currentBranchId || '', employeeWork: [], employeeCheckup: [], employeeOtherInfo: undefined, }, imgList, ); if (res) { employeeId = res.id; await assignFormDataEmployee(res.id); currentFromDataEmployee.value.id = res.id; state.value.statusSavePersonal = true; } } if (state.value.dialogType === 'edit') { const res = await employeeStore.editById( state.value.currentEmployee?.id || '', { ...currentFromDataEmployee.value, status: state.value.currentEmployee?.status === 'CREATED' ? 'ACTIVE' : state.value.currentEmployee?.status, customerBranchId: state.value.currentBranchId || '', employeeWork: [], employeeCheckup: [], employeeOtherInfo: undefined, }, ); if (res) { employeeId = res.id; await assignFormDataEmployee(res.id); state.value.statusSavePersonal = true; } } return employeeId; } async function assignFormDataEmployee(id?: string) { if (!id) { resetEmployeeData = structuredClone(defaultFormData); return; } const _data = await employeeStore.fetchById(id); if (_data) { const _attach = await employeeStore.listAttachment({ parentId: _data.id, }); state.value.currentEmployee = _data; const { createdAt, createdByUserId, statusOrder, province, district, subDistrict, updatedAt, updatedByUserId, createdBy, updatedBy, ...payload } = _data; resetEmployeeData = { ...payload, provinceId: province?.id || '', districtId: district?.id || '', subDistrictId: subDistrict?.id || '', employeePassport: structuredClone( payload.employeePassport?.length === 0 ? state.value.dialogModal ? defaultFormData.employeePassport.map((v) => ({ ...v, namePrefix: payload.namePrefix, firstName: payload.firstName, firstNameEN: payload.firstNameEN, middleName: payload.middleName, middleNameEN: payload.middleNameEN, lastName: payload.lastName, lastNameEN: payload.lastNameEN, gender: payload.gender, nationality: payload.nationality, birthDate: payload.dateOfBirth, })) : [] : payload.employeePassport, ), employeeVisa: structuredClone( payload.employeeVisa?.length === 0 ? state.value.dialogModal ? defaultFormData.employeeVisa : [] : payload.employeeVisa, ), employeeCheckup: structuredClone( payload.employeeCheckup?.length === 0 ? state.value.dialogModal ? defaultFormData.employeeCheckup : [] : payload.employeeCheckup?.map((item) => ({ ...item, statusSave: true, })), ), employeeOtherInfo: structuredClone( { ...payload.employeeOtherInfo, statusSave: !!payload.employeeOtherInfo?.id ? true : false, } || {}, ), employeeWork: structuredClone( payload.employeeWork?.length === 0 ? state.value.dialogModal ? defaultFormData.employeeWork : [] : payload.employeeWork?.map((item) => ({ ...item, statusSave: true, })), ), file: _attach ? await Promise.all( _attach.map(async (name) => { const fragment = name.split('-'); const group = fragment.length === 1 ? 'other' : fragment.at(0); return { url: await employeeStore.getAttachment({ parentId: _data.id, name, }), name, group, }; }), ) : [], }; currentFromDataEmployee.value = structuredClone(resetEmployeeData); state.value.currentIndexPassport = (currentFromDataEmployee.value.employeePassport?.length || 0) - 1; state.value.currentIndexVisa = (currentFromDataEmployee.value.employeeVisa?.length || 0) - 1; if ( currentFromDataEmployee.value.employeePassport?.[ state.value.currentIndexPassport ] && currentFromDataEmployee.value.employeePassport?.[ state.value.currentIndexPassport ].id !== undefined ) { state.value.currentIndexPassport = -1; } if ( currentFromDataEmployee.value.employeeVisa?.[ state.value.currentIndexVisa ] && currentFromDataEmployee.value.employeeVisa?.[ state.value.currentIndexVisa ].id !== undefined ) { state.value.currentIndexVisa = -1; } state.value.currentBranchId = payload.customerBranchId; const foundBranch = await customerStore.fetchListCustomerBranchById( payload.customerBranchId, ); state.value.currentEmployeeCode = payload.code; state.value.profileUrl = `${baseUrl}/employee/${id}/image/${_data.selectedImage}` || ''; state.value.formDataEmployeeOwner = { ...foundBranch }; if ( foundBranch.address === payload.address && foundBranch.subDistrict.id === payload.subDistrictId ) { state.value.formDataEmployeeSameAddr = true; } else { state.value.formDataEmployeeSameAddr = false; } if ( state.value.infoEmployeePersonCard && Array.isArray(state.value.infoEmployeePersonCard) && state.value.infoEmployeePersonCard.length > 0 ) { if (typeof state.value.infoEmployeePersonCard[0] === 'object') { } } flowStore.rotate(); } } async function employeeFilterOwnerBranch( val: string, update: (...args: unknown[]) => void, ) { update(async () => { const result = await customerStore.fetchListCustomerBranch({ includeCustomer: true, query: val, pageSize: 30, }); if (result) employeeStore.ownerOption = result.result; }); } function addPassport() { currentFromDataEmployee.value.employeePassport?.push({ birthCountry: '', previousPassportRef: '', issuePlace: '', issueCountry: '', issueDate: new Date(), type: '', expireDate: new Date(), birthDate: currentFromDataEmployee.value.dateOfBirth, workerStatus: '', nationality: currentFromDataEmployee.value.nationality, gender: currentFromDataEmployee.value.gender, lastNameEN: currentFromDataEmployee.value.lastNameEN, lastName: currentFromDataEmployee.value.lastName, middleNameEN: currentFromDataEmployee.value.middleNameEN, middleName: currentFromDataEmployee.value.middleName, firstNameEN: currentFromDataEmployee.value.firstNameEN, firstName: currentFromDataEmployee.value.firstName, namePrefix: currentFromDataEmployee.value.namePrefix, number: '', }); state.value.currentIndexPassport = (currentFromDataEmployee.value.employeePassport?.length || 0) - 1; } function addVisa() { currentFromDataEmployee.value.employeeVisa?.push({ arrivalAt: '', arrivalTMNo: '', arrivalTM: '', mrz: undefined, entryCount: 0, issuePlace: '', issueCountry: '', issueDate: new Date(), type: '', expireDate: new Date(), remark: undefined, workerType: '', reportDate: null, number: '', }); state.value.currentIndexVisa = (currentFromDataEmployee.value.employeeVisa?.length || 0) - 1; } function addCheckup() { currentFromDataEmployee.value.employeeCheckup?.push({ coverageExpireDate: null, coverageStartDate: null, insuranceCompany: '', medicalBenefitScheme: '', remark: '', hospitalName: '', provinceId: '', checkupResult: '', checkupType: '', }); state.value.currentIndexCheckup = (currentFromDataEmployee.value.employeeCheckup?.length || 0) - 1; } function addWorkHistory() { currentFromDataEmployee.value.employeeWork?.push({ workPermitExpireDate: null, workPermitIssueDate: null, workPermitNo: '', workplace: '', jobType: '', positionName: '', ownerName: '', }); state.value.currentIndexWorkHistory = (currentFromDataEmployee.value.employeeWork?.length || 0) - 1; } function employeeFormUndo(close = true) { if (isFormDataDifferent()) { return employeeConfirmUnsave(close); } resetFormDataEmployee(); state.value.editReadonly = true; } function employeeConfirmUnsave(close = true) { dialog({ color: 'warning', icon: 'mdi-alert', title: t('form.warning.title'), actionText: t('general.ok'), persistent: true, message: t('form.warning.unsave'), action: () => { resetFormDataEmployee(); onCreateImageList.value = { selectedImage: '', list: [] }; state.value.editReadonly = true; state.value.dialogModal = !close; state.value.drawerModal = !close; }, cancel: () => {}, }); } async function deleteEmployeeById(opts: { id?: string; type?: 'passport' | 'visa' | 'healthCheck' | 'work'; index?: number; fetch?: (...args: unknown[]) => unknown; removeArray?: (...args: unknown[]) => unknown; }) { dialog({ color: 'negative', icon: 'mdi-alert', title: t('dialog.title.confirmDelete'), actionText: t('general.delete'), persistent: true, message: t('dialog.message.confirmDelete'), action: async () => { if (opts.type === 'passport' && opts.index !== undefined) { await deletePassport(opts.index); } if (opts.type === 'visa' && opts.index !== undefined) { await deleteVisa(opts.index); } if (opts.type === 'healthCheck' && opts.index !== undefined) { await deleteHealthCheck(opts.index); } if (opts.type === 'work' && opts.index !== undefined) { await deleteWorkHistory(opts.index); } else { if (!!opts.id) { const result = await employeeStore.deleteById(opts.id); if (result) { state.value.drawerModal = false; state.value.dialogModal = false; } } } if (route.name !== 'CustomerBranchManagement') { await opts.fetch?.(); flowStore.rotate(); } opts.removeArray?.(); }, cancel: () => {}, }); } return { refreshImageState, statusEmployeeCreate, onCreateImageList, state, currentFromDataEmployee, resetEmployeeData, addPassport, addVisa, addCheckup, addWorkHistory, submitPassport, submitVisa, submitOther, submitWorkHistory, submitPersonal, submitHealthCheck, deletePassport, deleteVisa, deleteWorkHistory, deleteHealthCheck, resetFormDataEmployee, assignFormDataEmployee, employeeFilterOwnerBranch, isFormDataDifferent, employeeFormUndo, employeeConfirmUnsave, deleteEmployeeById, }; });