import { ref, toRaw, watch } from 'vue'; import { defineStore } from 'pinia'; import { CustomerBranchCreate, CustomerCreate } from 'stores/customer/types'; import { Employee, EmployeeCreate } from 'stores/employee/types'; import useMyBranch from 'stores/my-branch'; import useCustomerStore from 'stores/customer'; import useEmployeeStore from 'stores/employee'; import useFlowStore from 'stores/flow'; export const useCustomerForm = defineStore('form-customer', () => { const apiBaseUrl = import.meta.env.VITE_API_BASE_URL; const customerStore = useCustomerStore(); const branchStore = useMyBranch(); const defaultFormData: CustomerCreate = { code: '', status: 'CREATED', customerType: 'CORP', namePrefix: '', firstName: '', lastName: '', firstNameEN: '', lastNameEN: '', gender: '', birthDate: new Date(), registeredBranchId: branchStore.currentMyBranch?.id || '', customerBranch: [], image: null, }; let resetFormData = structuredClone(defaultFormData); const currentFormData = ref(structuredClone(defaultFormData)); const state = ref<{ dialogType: 'info' | 'create' | 'edit'; dialogOpen: boolean; dialogModal: boolean; branchIndex: number; customerImageUrl: string; defaultCustomerImageUrl: string; imageDialog: boolean; imageEdit: boolean; readonly: boolean; editCustomerId?: string; editCustomerCode?: string; editCustomerBranchId?: string; }>({ dialogType: 'info', dialogOpen: false, dialogModal: false, imageDialog: false, branchIndex: -1, readonly: true, imageEdit: false, customerImageUrl: '', editCustomerId: '', editCustomerBranchId: '', defaultCustomerImageUrl: '', }); watch( currentFormData, (v) => (defaultFormData.customerType = v.customerType), ); function isFormDataDifferent() { return ( JSON.stringify(resetFormData) !== JSON.stringify(currentFormData.value) ); } function resetForm(clean = false) { state.value.branchIndex = -1; if (clean) { defaultFormData.customerType = currentFormData.value.customerType; currentFormData.value = structuredClone(defaultFormData); currentFormData.value.registeredBranchId = branchStore.currentMyBranch?.id || ''; resetFormData = structuredClone(defaultFormData); resetFormData.registeredBranchId = branchStore.currentMyBranch?.id || ''; state.value.editCustomerId = ''; return; } if (!resetFormData.registeredBranchId) { resetFormData.registeredBranchId = branchStore.currentMyBranch?.id || ''; } if (state.value.dialogType === 'create') { state.value.editCustomerId = ''; } currentFormData.value = structuredClone(resetFormData); } 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 = `${apiBaseUrl}/customer/${id}/image`; state.value.defaultCustomerImageUrl = `${apiBaseUrl}/customer/${id}/image`; resetFormData.registeredBranchId = data.registeredBranchId; resetFormData.code = data.code || ''; resetFormData.status = data.status; resetFormData.customerType = data.customerType; resetFormData.namePrefix = data.namePrefix; resetFormData.firstName = data.firstName; resetFormData.lastName = data.lastName; resetFormData.firstNameEN = data.firstNameEN; resetFormData.lastNameEN = data.lastNameEN; resetFormData.gender = data.gender; resetFormData.birthDate = new Date(data.birthDate); resetFormData.image = null; resetFormData.customerBranch = data.branch.map((v) => ({ id: v.id, code: v.code || '', customerCode: '', provinceId: v.provinceId, districtId: v.districtId, subDistrictId: v.subDistrictId, wageRate: v.wageRate, payDate: new Date(v.payDate), // Convert the string to a Date object saleEmployee: v.saleEmployee, jobDescription: v.jobDescription, jobPositionEN: v.jobPositionEN, jobPosition: v.jobPosition, businessTypeEN: v.businessTypeEN, businessType: v.businessType, employmentOffice: v.employmentOffice, telephoneNo: v.telephoneNo, email: v.email, addressEN: v.addressEN, address: v.address, workplaceEN: v.workplaceEN, workplace: v.workplace, status: v.status, customerId: v.customerId, citizenId: v.citizenId || '', authorizedCapital: v.authorizedCapital || '', registerDate: new Date(v.registerDate), // Convert the string to a Date object registerNameEN: v.registerNameEN || '', registerName: v.registerName || '', legalPersonNo: v.legalPersonNo || '', registerCompanyName: '', statusSave: true, contactName: v.contactName || '', file: undefined, })); currentFormData.value = structuredClone(resetFormData); } function addCurrentCustomerBranch() { if (currentFormData.value.customerBranch?.some((v) => !v.id)) return; currentFormData.value.customerBranch?.push({ id: '', code: currentFormData.value.customerBranch.length !== 0 ? currentFormData.value.customerBranch?.[0].code === null ? '' : currentFormData.value.customerBranch?.[0].code : '', customerCode: '', provinceId: '', districtId: '', subDistrictId: '', wageRate: 0, payDate: new Date(), // Convert the string to a Date object saleEmployee: '', jobDescription: '', jobPositionEN: '', jobPosition: '', businessTypeEN: '', businessType: '', employmentOffice: '', telephoneNo: '', email: '', addressEN: '', address: '', workplaceEN: '', workplace: '', status: 'CREATED', customerId: '', citizenId: currentFormData.value.customerBranch.length !== 0 ? currentFormData.value.customerBranch?.[0].citizenId === null ? '' : currentFormData.value.customerBranch?.[0].citizenId : '', authorizedCapital: '', registerDate: new Date(), // Convert the string to a Date object registerNameEN: '', registerName: '', legalPersonNo: currentFormData.value.customerBranch.length !== 0 ? currentFormData.value.customerBranch?.[0].legalPersonNo === null ? '' : currentFormData.value.customerBranch?.[0].legalPersonNo : '', registerCompanyName: '', contactName: '', file: undefined, }); state.value.branchIndex = (currentFormData.value.customerBranch?.length || 0) - 1; } async function submitFormCustomer() { if (state.value.dialogType === 'info') return; if (state.value.dialogType === 'create') { const _data = await customerStore.create(currentFormData.value); 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; } } return { state, resetFormData, currentFormData, isFormDataDifferent, resetForm, assignFormData, submitFormCustomer, addCurrentCustomerBranch, }; }); export const useCustomerBranchForm = defineStore('form-customer-branch', () => { const customerStore = useCustomerStore(); const defaultFormData: CustomerBranchCreate & { id?: string } = { code: '', customerCode: '', provinceId: '', districtId: '', subDistrictId: '', wageRate: 0, payDate: new Date(), // Convert the string to a Date object saleEmployee: '', jobDescription: '', jobPositionEN: '', jobPosition: '', businessTypeEN: '', businessType: '', employmentOffice: '', telephoneNo: '', email: '', addressEN: '', address: '', workplaceEN: '', workplace: '', status: 'CREATED', customerId: '', citizenId: '', authorizedCapital: '', registerDate: new Date(), // Convert the string to a Date object registerNameEN: '', registerName: '', legalPersonNo: '', registerCompanyName: '', statusSave: false, contactName: '', file: undefined, }; let resetFormData = structuredClone(defaultFormData); const currentFormData = ref( structuredClone(defaultFormData), ); const state = ref<{ dialogType: 'info' | 'create' | 'edit'; dialogOpen: boolean; dialogModal: boolean; currentCustomerId: string; }>({ 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 = { code: _data.code, customerCode: '', provinceId: _data.provinceId, districtId: _data.districtId, subDistrictId: _data.subDistrictId, wageRate: _data.wageRate, payDate: new Date(_data.payDate), // Convert the string to a Date object saleEmployee: _data.saleEmployee, jobDescription: _data.jobDescription, jobPositionEN: _data.jobPositionEN, jobPosition: _data.jobPosition, businessTypeEN: _data.businessTypeEN, businessType: _data.businessType, employmentOffice: _data.employmentOffice, telephoneNo: _data.telephoneNo, email: _data.email, addressEN: _data.addressEN, address: _data.address, workplaceEN: _data.workplaceEN, workplace: _data.workplace, 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, registerCompanyName: '', statusSave: false, file: undefined, }; 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, 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, initForm, currentFormData, isFormDataDifferent, submitForm, }; }); export const useEmployeeForm = defineStore('form-employee', () => { const customerStore = useCustomerStore(); const employeeStore = useEmployeeStore(); const flowStore = useFlowStore(); const branchStore = useMyBranch(); const state = ref<{ dialogType: 'info' | 'create' | 'edit'; imageDialog: boolean; currentTab: string; dialogModal: boolean; drawerModal: boolean; currentEmployeeCode: string; currentEmployee: Employee | null; currentIndex: 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; zipCode: string; } | undefined; }>({ currentIndex: -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, }); const defaultFormData: EmployeeCreate = { id: '', code: '', image: null, customerBranchId: '', nrcNo: '', dateOfBirth: null, gender: '', nationality: '', status: 'CREATED', firstName: '', firstNameEN: '', lastName: '', lastNameEN: '', addressEN: '', address: '', zipCode: '', passportType: '', passportNumber: '', passportIssueDate: null, passportExpiryDate: null, passportIssuingCountry: '', passportIssuingPlace: '', previousPassportReference: '', visaType: '', visaNumber: '', visaIssueDate: null, visaExpiryDate: null, visaIssuingPlace: '', visaStayUntilDate: null, tm6Number: '', entryDate: null, workerStatus: '', subDistrictId: '', districtId: '', provinceId: '', employeeWork: [ { workEndDate: null, workPermitExpireDate: null, workPermitIssuDate: null, workPermitNo: '', workplace: '', jobType: '', positionName: '', ownerName: '', remark: '', }, ], employeeCheckup: [ { coverageExpireDate: null, coverageStartDate: null, insuranceCompany: '', medicalBenefitScheme: '', remark: '', hospitalName: '', provinceId: '', checkupResult: '', checkupType: '', }, ], 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) { if (clean) { state.value.currentTab = 'personalInfo'; state.value.formDataEmployeeOwner = undefined; resetEmployeeData = structuredClone(defaultFormData); state.value.statusSavePersonal = false; } currentFromDataEmployee.value = structuredClone(resetEmployeeData); } 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 deleteWorkHistory() { if (!currentFromDataEmployee.value.employeeWork) return; const res = await employeeStore.deleteByIdWork({ employeeId: currentFromDataEmployee.value.id || '', workId: currentFromDataEmployee.value.employeeWork[state.value.currentIndex] ?.id, }); if (res) { await assignFormDataEmployee(currentFromDataEmployee.value.id); } } async function deleteHealthCheck() { if (!currentFromDataEmployee.value.employeeCheckup) return; const res = await employeeStore.deleteByIdCheckUp({ employeeId: currentFromDataEmployee.value.id || '', checkUpId: currentFromDataEmployee.value.employeeCheckup[state.value.currentIndex] ?.id, }); if (res) { currentFromDataEmployee.value.employeeCheckup.splice( state.value.currentIndex, 1, ); } await assignFormDataEmployee(currentFromDataEmployee.value.id); } async function submitWorkHistory() { if (!currentFromDataEmployee.value.employeeWork) return; if ( !currentFromDataEmployee.value.employeeWork[state.value.currentIndex].id ) { const res = await employeeStore.createEmployeeWork( currentFromDataEmployee.value?.id || '', currentFromDataEmployee.value.employeeWork[state.value.currentIndex], ); if (res) { currentFromDataEmployee.value.employeeWork[ state.value.currentIndex ].id = res.id; currentFromDataEmployee.value.employeeWork[ state.value.currentIndex ].statusSave = true; } } else { const data = currentFromDataEmployee.value?.employeeWork[state.value.currentIndex]; const res = await employeeStore.editByIdEmployeeWork( currentFromDataEmployee.value?.id || '', data, ); if (res) { currentFromDataEmployee.value.employeeWork[ state.value.currentIndex ].statusSave = true; } } await assignFormDataEmployee(currentFromDataEmployee.value.id); } async function submitHealthCheck() { if (!currentFromDataEmployee.value.employeeCheckup) return; if ( !currentFromDataEmployee.value.employeeCheckup[state.value.currentIndex] .id ) { const res = await employeeStore.createEmployeeCheckup( state.value.currentEmployee?.id || '', currentFromDataEmployee.value.employeeCheckup[state.value.currentIndex], ); if (res) { currentFromDataEmployee.value.employeeCheckup[ state.value.currentIndex ].id = res.id; currentFromDataEmployee.value.employeeCheckup[ state.value.currentIndex ].statusSave = true; } } else { const data = currentFromDataEmployee.value.employeeCheckup[state.value.currentIndex]; const res = await employeeStore.editByIdEmployeeCheckup( state.value.currentEmployee?.id || '', data, ); if (res) { currentFromDataEmployee.value.employeeCheckup[ state.value.currentIndex ].statusSave = true; } } await assignFormDataEmployee(currentFromDataEmployee.value.id); } async function submitPersonal() { if (state.value.dialogType === 'create') { const res = await employeeStore.create({ ...currentFromDataEmployee.value, customerBranchId: state.value.formDataEmployeeOwner?.id || '', employeeWork: [], employeeCheckup: [], employeeOtherInfo: undefined, }); if (res) { 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.formDataEmployeeOwner?.id || '', employeeWork: [], employeeCheckup: [], employeeOtherInfo: undefined, }, ); if (res) { await assignFormDataEmployee(res.id); state.value.statusSavePersonal = true; } } } async function assignFormDataEmployee(id?: string) { if (!id) { resetEmployeeData = structuredClone(defaultFormData); return; } const res = await employeeStore.fetchById(id); if (res) { state.value.currentEmployee = res; const { createdAt, createdByUserId, statusOrder, province, district, subDistrict, updatedAt, updatedByUserId, createdBy, updatedBy, profileImageUrl, ...playlond } = res; resetEmployeeData = { ...playlond, provinceId: province?.id, districtId: district?.id, subDistrictId: subDistrict?.id, employeeCheckup: structuredClone( playlond.employeeCheckup?.length === 0 ? defaultFormData.employeeCheckup : playlond.employeeCheckup?.map((item) => ({ ...item, statusSave: true, })), ), employeeOtherInfo: structuredClone( { ...playlond.employeeOtherInfo, statusSave: !!playlond.employeeOtherInfo?.id ? true : false, } || {}, ), employeeWork: structuredClone( playlond.employeeWork?.length === 0 ? defaultFormData.employeeWork : playlond.employeeWork?.map((item) => ({ ...item, statusSave: true, })), ), image: null, }; currentFromDataEmployee.value = structuredClone(resetEmployeeData); const foundBranch = await customerStore.fetchListCustomeBranchById( playlond.customerBranchId, ); state.value.currentEmployeeCode = playlond.code; state.value.profileUrl = profileImageUrl || ' '; profileImageUrl ? (state.value.profileSubmit = true) : (state.value.profileSubmit = false); state.value.formDataEmployeeOwner = { ...foundBranch }; if (foundBranch.address === playlond.address) { state.value.formDataEmployeeSameAddr = true; } else { state.value.formDataEmployeeSameAddr = false; } if ( state.value.infoEmployeePersonCard && Array.isArray(state.value.infoEmployeePersonCard) && state.value.infoEmployeePersonCard.length > 0 && profileImageUrl !== null ) { if (typeof state.value.infoEmployeePersonCard[0] === 'object') { state.value.infoEmployeePersonCard[0].img = profileImageUrl; } } flowStore.rotate(); } } async function employeeFilterOwnerBranch( val: string, update: (...args: unknown[]) => void, ) { update(async () => { const result = await customerStore.fetchListCustomeBranch({ includeCustomer: true, query: val, pageSize: 30, }); if (result) employeeStore.ownerOption = result.result; }); } return { state, currentFromDataEmployee, resetEmployeeData, submitOther, submitWorkHistory, submitPersonal, submitHealthCheck, deleteWorkHistory, deleteHealthCheck, resetFormDataEmployee, assignFormDataEmployee, employeeFilterOwnerBranch, isFormDataDifferent, }; });