refactor: customer

This commit is contained in:
puriphatt 2024-09-17 18:01:13 +07:00
parent e50904bead
commit f2b318060e
11 changed files with 596 additions and 355 deletions

View file

@ -3,15 +3,16 @@ import { baseUrl } from 'stores/utils';
defineProps<{ defineProps<{
inactive?: boolean; inactive?: boolean;
i18nKey?: string;
color?: 'none' | 'hq' | 'br' | 'br-virtual'; color?: 'none' | 'hq' | 'br' | 'br-virtual';
data: { data: {
branchLabelCode: string; branchLabelCode?: string;
branchLabelName: string; branchLabelName: string;
taxNo: string; taxNo?: string;
branchLabelTel: string; branchLabelTel?: string;
contactName: string; contactName?: string;
branchLabelAddress: string; branchLabelAddress?: string;
branchImgUrl: string; branchImgUrl?: string;
}; };
virtualBranch: boolean; virtualBranch: boolean;
metadata?: unknown; metadata?: unknown;
@ -38,7 +39,9 @@ defineProps<{
> >
<div class="branch-card__header"> <div class="branch-card__header">
<div class="branch-card__wrapper"> <div class="branch-card__wrapper">
<slot name="image"></slot>
<q-img <q-img
v-if="!$slots.image"
:src="baseUrl + data.branchImgUrl" :src="baseUrl + data.branchImgUrl"
style=" style="
height: 3rem; height: 3rem;
@ -55,9 +58,11 @@ defineProps<{
</template> </template>
</q-img> </q-img>
</div> </div>
<div class="branch-card__name"> <div class="branch-card__name flex justify-center q-ml-sm">
<b>{{ data.branchLabelName }}</b> <b>{{ data.branchLabelName }}</b>
<small class="branch-card__code">{{ data.branchLabelCode }}</small> <small class="branch-card__code" v-if="data.branchLabelCode">
{{ data.branchLabelCode }}
</small>
</div> </div>
<div class="branch-card__action"> <div class="branch-card__action">
@ -74,7 +79,7 @@ defineProps<{
> >
{{ {{
$t( $t(
`branch.card.${virtualBranch ? 'branchVirtual' : 'branchLabel'}`, `${i18nKey || 'branch.card'}.${virtualBranch ? 'branchVirtual' : 'branchLabel'}`,
) )
}} }}
</b> </b>
@ -90,18 +95,21 @@ defineProps<{
margin-bottom: var(--size-2); margin-bottom: var(--size-2);
" "
/> />
<div <slot name="data"></slot>
v-for="key in fieldSelected || [ <template v-if="!$slots.data">
'branchLabelAddress', <div
'branchLabelTel', v-for="key in fieldSelected || [
'branchLabelType', 'branchLabelAddress',
]" 'branchLabelTel',
:key="key" 'branchLabelType',
class="branch-card__data" ]"
> :key="key"
<div>{{ $t(`branch.card.${key}`) }}</div> class="branch-card__data"
<div>{{ data[key as keyof typeof data] }}</div> >
</div> <div>{{ $t(`${i18nKey || 'branch.card'}.${key}`) }}</div>
<div>{{ data[key as keyof typeof data] }}</div>
</div>
</template>
</div> </div>
</template> </template>

View file

@ -17,6 +17,7 @@ withDefaults(
statusBranch?: string; statusBranch?: string;
badgeLabel?: string; badgeLabel?: string;
badgeClass?: string; badgeClass?: string;
badgeStyle?: string;
bgColor?: string; bgColor?: string;
hideAction?: boolean; hideAction?: boolean;
editData?: (...args: unknown[]) => void; editData?: (...args: unknown[]) => void;
@ -92,6 +93,7 @@ function reset() {
v-if="badgeLabel" v-if="badgeLabel"
class="badge-label badge text-caption q-px-sm q-mr-sm" class="badge-label badge text-caption q-px-sm q-mr-sm"
:class="badgeClass" :class="badgeClass"
:style="badgeStyle"
> >
{{ badgeLabel }} {{ badgeLabel }}
</text> </text>

View file

@ -17,6 +17,7 @@ import { CustomerBranch, CustomerType } from 'stores/customer/types';
import { columnsEmployee } from './constant'; import { columnsEmployee } from './constant';
import { useCustomerBranchForm, useEmployeeForm } from './form'; import { useCustomerBranchForm, useEmployeeForm } from './form';
import EmployerFormAuthorized from './components/employer/EmployerFormAuthorized.vue';
import ButtonAddComponent from 'components/ButtonAddCompoent.vue'; import ButtonAddComponent from 'components/ButtonAddCompoent.vue';
import SideMenu from 'components/SideMenu.vue'; import SideMenu from 'components/SideMenu.vue';
import { DialogFormContainer, DialogHeader } from 'components/dialog'; import { DialogFormContainer, DialogHeader } from 'components/dialog';
@ -77,6 +78,7 @@ const prop = withDefaults(
customerType: CustomerType; customerType: CustomerType;
countEmployee?: number; countEmployee?: number;
gender: string; gender: string;
selectedImage: string;
}>(), }>(),
{ {
color: 'green', color: 'green',
@ -251,12 +253,12 @@ watch([customerId, inputSearch, currentStatus], async () => {
> >
<q-avatar no-padding size="50px"> <q-avatar no-padding size="50px">
<q-img <q-img
:src="`${baseUrl}/customer/${customerId}/image`" :src="`${baseUrl}/customer/${customerId}/image/${selectedImage}`"
class="full-height full-width" class="full-height full-width"
> >
<template #error> <template #error>
<q-img <q-img
:src="`${customerType === 'CORP' ? `/images/customer-CORP-avartar-${gender}.png` : `/images/customer-PERS-avartar-${gender}.png`}`" :src="`${customerType === 'CORP' ? `/images/customer-CORP-avartar-male.png` : `/images/customer-PERS-avartar-${gender}.png`}`"
/> />
</template> </template>
</q-img> </q-img>
@ -433,9 +435,16 @@ watch([customerId, inputSearch, currentStatus], async () => {
<div class="col" style="min-width: fit-content"> <div class="col" style="min-width: fit-content">
<div class="col"> <div class="col">
{{ {{
$i18n.locale === 'eng' customerType === 'CORP'
? props.row.registerNameEN ? $i18n.locale === 'eng'
: props.row.registerName ? props.row.registerNameEN || '-'
: props.row.registerName || '-'
: $i18n.locale === 'eng'
? props.row.firstNameEN +
' ' +
props.row.lastNameEN || '-'
: props.row.firstName + ' ' + props.row.lastName ||
'-'
}} }}
</div> </div>
<div class="col app-text-muted"> <div class="col app-text-muted">
@ -619,6 +628,7 @@ watch([customerId, inputSearch, currentStatus], async () => {
" "
@submit=" @submit="
async () => { async () => {
console.log('asasd');
const res = await customerBranchFormStore.submitForm(); const res = await customerBranchFormStore.submitForm();
if (res) { if (res) {
@ -718,7 +728,12 @@ watch([customerId, inputSearch, currentStatus], async () => {
</div> </div>
</div> </div>
<EmployerFormAbout <EmployerFormAbout
:index="customerBranchFormData.code" :readonly="customerBranchFormState.dialogType === 'info'"
class="q-mb-xl"
:index="
customerBranchFormData.code &&
Number(customerBranchFormData.code.split('-').pop()).toString()
"
:customer-type="customerType" :customer-type="customerType"
v-model:citizen-id="customerBranchFormData.citizenId" v-model:citizen-id="customerBranchFormData.citizenId"
v-model:prefixName="customerBranchFormData.namePrefix" v-model:prefixName="customerBranchFormData.namePrefix"
@ -738,35 +753,6 @@ watch([customerId, inputSearch, currentStatus], async () => {
v-model:telephoneNo="customerBranchFormData.telephoneNo" v-model:telephoneNo="customerBranchFormData.telephoneNo"
v-model:codeCustomer="customerBranchFormData.codeCustomer" v-model:codeCustomer="customerBranchFormData.codeCustomer"
/> />
<div class="row q-col-gutter-sm q-mb-sm" id="employer-branch-address">
<div class="col-12 text-weight-bold text-body1 row items-center">
<q-icon
flat
size="xs"
class="q-pa-sm rounded q-mr-sm"
color="info"
name="mdi-office-building-outline"
style="background-color: var(--surface-3)"
/>
<span>{{ $t('customerBranch.tab.address') }}</span>
</div>
</div>
<AddressForm
prefix-id="employer-branch"
class="q-mb-xl"
hide-title
dense
:readonly="customerBranchFormState.dialogType === 'info'"
outlined
:title="$t('form.address')"
v-model:address="customerBranchFormData.address"
v-model:addressEN="customerBranchFormData.addressEN"
v-model:province-id="customerBranchFormData.provinceId"
v-model:district-id="customerBranchFormData.districtId"
v-model:sub-district-id="customerBranchFormData.subDistrictId"
:addressTitle="$t('form.address')"
:addressTitleEN="$t('form.address', { suffix: '(EN)' })"
/>
<div <div
class="row q-col-gutter-sm q-mb-sm" class="row q-col-gutter-sm q-mb-sm"
id="employer-branch-business" id="employer-branch-business"
@ -789,15 +775,76 @@ watch([customerId, inputSearch, currentStatus], async () => {
outlined outlined
prefix-id="employer-branch" prefix-id="employer-branch"
:readonly="customerBranchFormState.dialogType === 'info'" :readonly="customerBranchFormState.dialogType === 'info'"
v-model:employment-office="customerBranchFormData.employmentOffice"
v-model:bussiness-type="customerBranchFormData.businessType" v-model:bussiness-type="customerBranchFormData.businessType"
v-model:bussiness-type-en="customerBranchFormData.businessTypeEN"
v-model:job-position="customerBranchFormData.jobPosition" v-model:job-position="customerBranchFormData.jobPosition"
v-model:job-position-en="customerBranchFormData.jobPositionEN"
v-model:job-description="customerBranchFormData.jobDescription" v-model:job-description="customerBranchFormData.jobDescription"
v-model:sale-employee="customerBranchFormData.saleEmployee"
v-model:pay-date="customerBranchFormData.payDate" v-model:pay-date="customerBranchFormData.payDate"
v-model:pay-date-e-n="customerBranchFormData.payDateEN"
v-model:wage-rate="customerBranchFormData.wageRate" v-model:wage-rate="customerBranchFormData.wageRate"
v-model:wage-rate-text="customerBranchFormData.wageRateText"
/>
<div class="row q-col-gutter-sm q-mb-sm" id="employer-branch-address">
<div class="col-12 text-weight-bold text-body1 row items-center">
<q-icon
flat
size="xs"
class="q-pa-sm rounded q-mr-sm"
color="info"
name="mdi-office-building-outline"
style="background-color: var(--surface-3)"
/>
<span>{{ $t('customerBranch.tab.authorized') }}</span>
</div>
</div>
<EmployerFormAuthorized
class="q-mb-xl"
prefix-id="employer-branch"
:readonly="customerBranchFormState.dialogType === 'info'"
v-model:authorized-name="customerBranchFormData.authorizedName"
v-model:authorized-name-e-n="
customerBranchFormData.authorizedNameEN
"
/>
<div class="row q-col-gutter-sm q-mb-sm" id="employer-branch-address">
<div class="col-12 text-weight-bold text-body1 row items-center">
<q-icon
flat
size="xs"
class="q-pa-sm rounded q-mr-sm"
color="info"
name="mdi-office-building-outline"
style="background-color: var(--surface-3)"
/>
<span>{{ $t('customerBranch.tab.address') }}</span>
</div>
</div>
<AddressForm
prefix-id="employer-branch"
class="q-mb-xl"
hide-title
use-employment
dense
:readonly="customerBranchFormState.dialogType === 'info'"
outlined
:title="$t('form.address')"
v-model:homeCode="customerBranchFormData.homeCode"
v-model:employmentOffice="customerBranchFormData.employmentOffice"
v-model:employmentOfficeEN="
customerBranchFormData.employmentOfficeEN
"
v-model:address="customerBranchFormData.address"
v-model:addressEN="customerBranchFormData.addressEN"
v-model:province-id="customerBranchFormData.provinceId"
v-model:district-id="customerBranchFormData.districtId"
v-model:sub-district-id="customerBranchFormData.subDistrictId"
v-model:street="customerBranchFormData.street"
v-model:streetEN="customerBranchFormData.streetEN"
v-model:moo="customerBranchFormData.moo"
v-model:mooEN="customerBranchFormData.mooEN"
v-model:soi="customerBranchFormData.soi"
v-model:soiEN="customerBranchFormData.soiEN"
:addressTitle="$t('form.address')"
:addressTitleEN="$t('form.address', { suffix: '(EN)' })"
/> />
<div class="row q-col-gutter-sm q-mb-sm" id="employer-branch-contact"> <div class="row q-col-gutter-sm q-mb-sm" id="employer-branch-contact">
<div class="col-12 text-weight-bold text-body1 row items-center"> <div class="col-12 text-weight-bold text-body1 row items-center">
@ -815,8 +862,11 @@ watch([customerId, inputSearch, currentStatus], async () => {
<EmployerFormContact <EmployerFormContact
class="q-mb-lg" class="q-mb-lg"
:readonly="customerBranchFormState.dialogType === 'info'" :readonly="customerBranchFormState.dialogType === 'info'"
v-model:contactName="customerBranchFormData.contactName"
v-model:email="customerBranchFormData.email" v-model:email="customerBranchFormData.email"
v-model:telephone="customerBranchFormData.telephoneNo" v-model:contactTel="customerBranchFormData.contactTel"
v-model:officeTel="customerBranchFormData.officeTel"
v-model:agent="customerBranchFormData.agent"
/> />
</div> </div>
</div> </div>

View file

@ -28,6 +28,7 @@ import {
} from 'components/button'; } from 'components/button';
import { AddressForm } from 'components/form'; import { AddressForm } from 'components/form';
import BranchCard from 'src/components/01_branch-management/BranchCard.vue';
import ItemCard from 'src/components/ItemCard.vue'; import ItemCard from 'src/components/ItemCard.vue';
import DrawerInfo from 'components/DrawerInfo.vue'; import DrawerInfo from 'components/DrawerInfo.vue';
import ButtonAddComponent from 'components/ButtonAddCompoent.vue'; import ButtonAddComponent from 'components/ButtonAddCompoent.vue';
@ -87,12 +88,32 @@ const ocrStore = useOcrStore();
const tabFieldRequired = ref<{ [key: string]: (keyof CustomerBranchCreate)[] }>( const tabFieldRequired = ref<{ [key: string]: (keyof CustomerBranchCreate)[] }>(
{ {
main: [], main: [],
address: ['address', 'addressEN', 'provinceId', 'districtId'], business: ['businessType', 'jobPosition'],
business: [], address: [
contact: ['contactName', 'telephoneNo'], 'homeCode',
'address',
'addressEN',
'provinceId',
'districtId',
'subDistrictId',
],
contact: [],
}, },
); );
const formMenuIcon = ref<{ icon: string; color: string; bgColor: string }[]>([
{
icon: 'mdi-office-building-outline',
color: 'hsl(var(--info-bg))',
bgColor: 'var(--surface-1)',
},
{
icon: 'mdi-briefcase-outline',
color: 'hsl(var(--info-bg))',
bgColor: 'var(--surface-1)',
},
]);
const { state: customerFormState, currentFormData: customerFormData } = const { state: customerFormState, currentFormData: customerFormData } =
storeToRefs(customerFormStore); storeToRefs(customerFormStore);
const { state: employeeFormState, currentFromDataEmployee } = const { state: employeeFormState, currentFromDataEmployee } =
@ -163,8 +184,8 @@ const customerTypeSelected = ref<{
const customerNameInfo = computed(() => { const customerNameInfo = computed(() => {
const name = const name =
locale.value === 'eng' locale.value === 'eng'
? `${customerFormData.value.customerBranch[0].firstNameEN} ${customerFormData.value.customerBranch[0].lastNameEN}` ? `${customerFormData.value.customerBranch[0]?.firstNameEN} ${customerFormData.value.customerBranch[0]?.lastNameEN}`
: `${customerFormData.value.customerBranch[0].firstName} ${customerFormData.value.customerBranch[0].lastName}`; : `${customerFormData.value.customerBranch[0]?.firstName} ${customerFormData.value.customerBranch[0]?.lastName}`;
return name || '-'; return name || '-';
}); });
const currentBtnOpen = ref<boolean[]>([]); const currentBtnOpen = ref<boolean[]>([]);
@ -447,7 +468,12 @@ async function toggleStatusEmployee(id: string, status: boolean) {
} }
async function toggleStatusCustomer(id: string, status: boolean) { async function toggleStatusCustomer(id: string, status: boolean) {
await customerStore.editById(id, { status: !status ? 'ACTIVE' : 'INACTIVE' }); const res = await customerStore.editById(id, {
status: !status ? 'ACTIVE' : 'INACTIVE',
});
if (res && customerFormState.value.drawerModal)
customerFormData.value.status = res.status;
await fetchListCustomer(); await fetchListCustomer();
flowStore.rotate(); flowStore.rotate();
} }
@ -495,7 +521,7 @@ async function openHistory(id: string) {
employeeHistoryDialog.value = true; employeeHistoryDialog.value = true;
} }
async function editCustomerForm(id: string, view?: boolean) { async function editCustomerForm(id: string) {
await customerFormStore.assignFormData(id); await customerFormStore.assignFormData(id);
await fetchListOfOptionBranch(); await fetchListOfOptionBranch();
await fetchImageList( await fetchImageList(
@ -913,6 +939,7 @@ const emptyCreateDialog = ref(false);
:class="{ 'q-pt-xs': $q.screen.lt.md }" :class="{ 'q-pt-xs': $q.screen.lt.md }"
style="white-space: nowrap" style="white-space: nowrap"
> >
<!-- :class="{ 'offset-md-5': gridView }" -->
<q-select <q-select
id="select-status" id="select-status"
for="select-status" for="select-status"
@ -922,7 +949,6 @@ const emptyCreateDialog = ref(false);
option-value="value" option-value="value"
option-label="label" option-label="label"
class="col" class="col"
:class="{ 'offset-md-5': gridView }"
map-options map-options
emit-value emit-value
:hide-dropdown-icon="$q.screen.lt.sm" :hide-dropdown-icon="$q.screen.lt.sm"
@ -932,9 +958,9 @@ const emptyCreateDialog = ref(false);
{ label: $t('status.INACTIVE'), value: 'INACTIVE' }, { label: $t('status.INACTIVE'), value: 'INACTIVE' },
]" ]"
></q-select> ></q-select>
<!-- v-if="gridView === false" -->
<q-select <q-select
id="select-field" id="select-field"
v-if="gridView === false"
for="select-field" for="select-field"
class="q-ml-sm col" class="q-ml-sm col"
:options=" :options="
@ -1201,7 +1227,7 @@ const emptyCreateDialog = ref(false);
}} }}
</q-td> </q-td>
<q-td v-if="fieldSelected.includes('customerName')"> <q-td v-if="fieldSelected.includes('fullname')">
<div class="row items-center"> <div class="row items-center">
<div <div
class="q-mr-sm" class="q-mr-sm"
@ -1238,19 +1264,19 @@ const emptyCreateDialog = ref(false);
<div class="col"> <div class="col">
{{ {{
props.row.customerType === 'CORP' props.row.customerType === 'CORP'
? props.row.branch[0].registerName || '-' ? props.row.branch[0]?.registerName || '-'
: props.row.branch[0].firstName + : props.row.branch[0]?.firstName +
' ' + ' ' +
props.row.branch[0].lastName || '-' props.row.branch[0]?.lastName || '-'
}} }}
</div> </div>
<div class="col app-text-muted"> <div class="col app-text-muted">
{{ {{
props.row.customerType === 'CORP' props.row.customerType === 'CORP'
? props.row.branch[0].registerNameEN || '-' ? props.row.branch[0]?.registerNameEN || '-'
: props.row.branch[0].firstNameEN + : props.row.branch[0]?.firstNameEN +
' ' + ' ' +
props.row.branch[0].lastNameEN || '-' props.row.branch[0]?.lastNameEN || '-'
}} }}
</div> </div>
</div> </div>
@ -1268,41 +1294,23 @@ const emptyCreateDialog = ref(false);
}} }}
</q-td> </q-td>
<q-td v-if="fieldSelected.includes('address')"> <q-td v-if="fieldSelected.includes('jobPosition')">
{{ {{
props.row.branch.length !== 0 props.row.branch.length !== 0
? props.row.branch[0].address !== null ? props.row.branch[0].jobPosition !== null
? props.row.branch[0].address ? optionStore.mapOption(
props.row.branch[0].jobPosition,
)
: '' : ''
: '-' : '-'
}} }}
</q-td> </q-td>
<q-td v-if="fieldSelected.includes('workPlace')"> <q-td v-if="fieldSelected.includes('officeTel')">
{{ {{
props.row.branch.length !== 0 props.row.branch.length !== 0
? props.row.branch[0].workplace !== null ? props.row.branch[0].officeTel !== null
? props.row.branch[0].workplace ? props.row.branch[0].officeTel
: ''
: '-'
}}
</q-td>
<q-td v-if="fieldSelected.includes('contactName')">
{{
props.row.branch.length !== 0
? props.row.branch[0].contactName !== null
? props.row.branch[0].contactName
: ''
: '-'
}}
</q-td>
<q-td v-if="fieldSelected.includes('contactPhone')">
{{
props.row.branch.length !== 0
? props.row.branch[0].telephoneNo !== null
? props.row.branch[0].telephoneNo
: '' : ''
: '-' : '-'
}} }}
@ -1353,7 +1361,7 @@ const emptyCreateDialog = ref(false);
dense dense
round round
flat flat
@click.stop="editCustomerForm(props.row.id, true)" @click.stop="editCustomerForm(props.row.id)"
/> />
<KebabAction <KebabAction
@ -1363,14 +1371,13 @@ const emptyCreateDialog = ref(false);
() => { () => {
const { branch, ...payload } = props.row; const { branch, ...payload } = props.row;
currentCustomer = payload; currentCustomer = payload;
editCustomerForm(props.row.id, true); editCustomerForm(props.row.id);
} }
" "
@edit=" @edit="
async () => { async () => {
await editCustomerForm(props.row.id); await editCustomerForm(props.row.id);
customerFormState.dialogType = 'edit'; customerFormState.branchIndex = 0;
customerFormState.readonly = false;
} }
" "
@delete="deleteCustomerById(props.row.id)" @delete="deleteCustomerById(props.row.id)"
@ -1433,84 +1440,149 @@ const emptyCreateDialog = ref(false);
</template> </template>
<template v-slot:item="props"> <template v-slot:item="props">
<div class="col-12 col-md-3 col-sm-6"> <div class="col-12 col-md-6">
<PersonCard <BranchCard
:id="`card-${props.row.customerName}`" i18nKey="customer.table"
:field-selected="fieldSelected" class="surface-1"
separateEnter :virtual-branch="props.row.virtual"
history :id="`branch-card-${props.row.name}`"
:prefix-id=" :class="{
props.row.customerNameEN ?? String(props.rowIndex) 'cursor-pointer': props.row._count.branch !== 0,
"
:data="{
code: props.row.code,
name:
$i18n.locale === 'eng'
? props.row.customerType === 'CORP'
? props.row.branch[0].registerNameEN || '-'
: props.row.branch[0].firstNameEN +
' ' +
props.row.branch[0].lastNameEN || '-'
: props.row.customerType === 'CORP'
? props.row.branch[0].registerName || '-'
: props.row.branch[0].firstName +
' ' +
props.row.branch[0].lastName || '-',
img: `${baseUrl}/customer/${props.row.id}/image/${props.row.selectedImage}`,
fallbackImg: `/images/customer-${props.row.customerType}-avartar-${props.row.customerType === 'PERS' ? props.row.branch[0].gender : 'male'}.png`,
male: undefined,
female: undefined,
detail: [
{
icon: 'mdi-phone-outline',
value: props.row.branch[0]?.telephoneNo || '-',
},
{
icon: 'mdi-account-outline',
value: props.row.personName || '-',
},
],
}" }"
:tag="[ @click="
{
color:
{
CORP: 'purple',
PERS: 'green',
}[props.row.customerType as string] || 'CORP',
value: $t(
props.row.customerType === 'CORP'
? 'customer.employerLegalEntity'
: 'customer.employerNaturalPerson',
),
},
]"
:disabled="props.row.status === 'INACTIVE'"
@history="openHistory(props.row.id)"
@update-card="
async () => {
await editCustomerForm(props.row.id);
customerFormState.dialogType = 'edit';
customerFormState.readonly = false;
}
"
@enter-card="
$router.push( $router.push(
`/customer-management/${props.row.id}/branch`, `/customer-management/${props.row.id}/branch`,
) )
" "
@view-card=" :metadata="props.row"
() => { :color="
const { branch, ...payload } = props.row; props.row.customerType === 'CORP'
currentCustomer = payload; ? 'hq'
editCustomerForm(props.row.id, true); : 'br-virtual'
}
" "
@delete-card="deleteCustomerById(props.row.id)" :key="props.row.id"
@toggle-status=" :data="{
triggerChangeStatus(props.row.id, props.row.status) branchLabelName:
props.row.customerType === 'CORP'
? $i18n.locale === 'eng'
? props.row.branch[0]?.registerNameEN || '-'
: props.row.branch[0]?.registerName || '-'
: $i18n.locale === 'eng'
? props.row.branch[0]?.firstNameEN +
' ' +
props.row.branch[0]?.lastNameEN || '-'
: props.row.branch[0]?.firstName +
' ' +
props.row.branch[0]?.lastName || '-',
taxNo: 'asdasd',
branchLabelTel: 'asdas',
contactName: 'zxczxcz',
branchImgUrl: `/customer/${props.row.id}/image/${props.row.selectedImage}`,
}"
:badge-field="['branchLabelStatus']"
:inactive="props.row.status === 'INACTIVE'"
:field-selected="
fieldSelected.filter((v) => {
return columnsCustomer.some((c) => c.name === v);
})
" "
></PersonCard> >
<template #image>
<q-avatar size="3rem">
<q-img
:src="`${baseUrl}/customer/${props.row.id}/image/${props.row.selectedImage}`"
class="full-height full-width"
>
<template #error>
<q-img
:src="`/images/customer-${props.row.customerType}-avartar-${props.row.customerType === 'PERS' ? props.row.branch[0].gender : 'male'}.png`"
/>
</template>
</q-img>
<q-badge
class="absolute-bottom-right no-padding"
style="
border-radius: 50%;
min-width: 11.31px;
min-height: 11.31px;
"
:style="{
background: `var(--${props.row.status === 'INACTIVE' ? 'stone-5' : 'green-6'})`,
}"
></q-badge>
</q-avatar>
</template>
<template #data>
<div
class="row"
style="
display: flex;
padding-block: var(--size-2);
"
>
<div
class="col-12 q-py-sm row"
v-for="key in fieldSelected
.filter((v) => {
return columnsCustomer.some(
(c) => c.name === v,
);
})
.filter((v) => {
return (
v !== 'orderNumber' && v !== 'fullname'
);
})"
:key="key"
>
<span class="col-4 app-text-muted">
{{ $t(`customer.table.${key}`) }}
</span>
<span class="col">
{{
key === 'businessTypePure'
? optionStore.mapOption(
props.row.branch[0].businessType,
)
: key === 'jobPosition'
? optionStore.mapOption(
props.row.branch[0].jobPosition,
)
: key === 'officeTel'
? props.row.branch[0].officeTel
: ''
}}
</span>
</div>
</div>
</template>
<template v-slot:action>
<KebabAction
:status="props.row.status"
:idName="props.row.name"
@view="
() => {
const { branch, ...payload } = props.row;
currentCustomer = payload;
editCustomerForm(props.row.id);
}
"
@edit="
async () => {
await editCustomerForm(props.row.id);
customerFormState.branchIndex = 0;
}
"
@delete="deleteCustomerById(props.row.id)"
@change-status="
triggerChangeStatus(
props.row.id,
props.row.status,
)
"
/>
</template>
</BranchCard>
</div> </div>
</template> </template>
</q-table> </q-table>
@ -1746,9 +1818,18 @@ const emptyCreateDialog = ref(false);
<BranchPage <BranchPage
v-if="currentCustomer" v-if="currentCustomer"
:customer-type="currentCustomer.customerType" :customer-type="currentCustomer.customerType"
:current-customer-name="`${currentCustomer.firstName} ${currentCustomer.lastName}`" :current-customer-name="
currentCustomer.customerType === 'PERS'
? locale === 'eng'
? `${currentCustomer.branch[0]?.firstNameEN} ${currentCustomer.branch[0]?.lastNameEN}`
: `${currentCustomer.branch[0]?.firstName} ${currentCustomer.branch[0]?.lastName}`
: locale === 'eng'
? currentCustomer.branch[0]?.registerNameEN
: currentCustomer.branch[0]?.registerName
"
:count-employee="currentCustomer._count.employee" :count-employee="currentCustomer._count.employee"
:gender="currentCustomer.gender" :selected-image="currentCustomer.selectedImage"
:gender="currentCustomer.branch[0]?.gender"
v-model:customer-id="currentCustomer.id" v-model:customer-id="currentCustomer.id"
v-model:mode-view="gridView" v-model:mode-view="gridView"
@back="$router.push('/customer-management')" @back="$router.push('/customer-management')"
@ -1815,9 +1896,11 @@ const emptyCreateDialog = ref(false);
<template #header> <template #header>
<DialogHeader <DialogHeader
:title=" :title="
$t(`general.add`, { customerFormState.dialogType === 'create'
text: `${$t('customer.employer')} `, ? $t(`general.add`, {
}) text: `${$t('customer.employer')} `,
})
: `${$t('customer.employer')} `
" "
> >
<template #title-after> <template #title-after>
@ -1840,8 +1923,11 @@ const emptyCreateDialog = ref(false);
active active
hide-fade hide-fade
:fallback-cover="`/images/customer-${customerFormData.customerType}-banner-bg.jpg`" :fallback-cover="`/images/customer-${customerFormData.customerType}-banner-bg.jpg`"
:img="customerFormState.customerImageUrl || null" :img="
:fallbackImg="`/images/customer-PERS-avartar-male.png`" customerFormState.customerImageUrl ||
`/images/customer-${customerFormData.customerType}-avartar-${customerFormData.customerType === 'PERS' ? customerFormData.customerBranch[0]?.gender : 'male'}.png`
"
:fallbackImg="`/images/customer-${customerFormData.customerType}-avartar-${customerFormData.customerType === 'PERS' ? customerFormData.customerBranch[0]?.gender : 'male'}.png`"
:color="`hsla(var(--${customerFormData.customerType === 'PERS' ? 'teal-10-hsl' : 'violet-11-hsl'})/1)`" :color="`hsla(var(--${customerFormData.customerType === 'PERS' ? 'teal-10-hsl' : 'violet-11-hsl'})/1)`"
:bg-color="`hsla(var(--${customerFormData.customerType === 'PERS' ? 'teal-10-hsl' : 'violet-11-hsl'})/0.1)`" :bg-color="`hsla(var(--${customerFormData.customerType === 'PERS' ? 'teal-10-hsl' : 'violet-11-hsl'})/0.1)`"
:icon=" :icon="
@ -1849,6 +1935,16 @@ const emptyCreateDialog = ref(false);
? 'mdi-account-plus-outline' ? 'mdi-account-plus-outline'
: 'mdi-office-building-outline' : 'mdi-office-building-outline'
" "
:title="
customerFormData.customerType === 'PERS'
? `${customerFormData.customerBranch[0]?.firstName} ${customerFormData.customerBranch[0]?.lastName}`
: customerFormData.customerBranch[0]?.registerName
"
:caption="
customerFormData.customerType === 'PERS'
? `${customerFormData.customerBranch[0]?.firstNameEN} ${customerFormData.customerBranch[0]?.lastNameEN}`
: customerFormData.customerBranch[0]?.registerNameEN
"
@view=" @view="
() => { () => {
customerFormState.imageDialog = true; customerFormState.imageDialog = true;
@ -1908,6 +2004,7 @@ const emptyCreateDialog = ref(false);
style="height: 100%; max-height: 100%; overflow-y: auto" style="height: 100%; max-height: 100%; overflow-y: auto"
> >
<EmployerFormBasicInfo <EmployerFormBasicInfo
v-if="customerFormData.customerBranch.length > 0"
class="q-mb-xl" class="q-mb-xl"
:readonly=" :readonly="
(customerFormState.dialogType === 'edit' && (customerFormState.dialogType === 'edit' &&
@ -1928,13 +2025,19 @@ const emptyCreateDialog = ref(false);
" "
:customer-type="customerFormData.customerType" :customer-type="customerFormData.customerType"
v-model:registered-branch-id="customerFormData.registeredBranchId" v-model:registered-branch-id="customerFormData.registeredBranchId"
v-mode:customerName="customerFormData.customerName" v-model:customerName="customerNameInfo"
v-mode:registerName="customerFormData.registerName" v-model:registerName="
v-mode:citizenId="customerFormData.citizenId" customerFormData.customerBranch[0].registerName
v-mode:legalPersonNo="customerFormData.legalPersonNo" "
v-mode:businessType="customerFormData.businessType" v-model:citizenId="customerFormData.customerBranch[0].citizenId"
v-mode:jobPosition="customerFormData.jobPosition" v-model:legalPersonNo="
v-mode:telephoneNo="customerFormData.telephoneNo" customerFormData.customerBranch[0].legalPersonNo
"
v-model:businessType="
customerFormData.customerBranch[0].businessType
"
v-model:jobPosition="customerFormData.customerBranch[0].jobPosition"
v-model:telephoneNo="customerFormData.customerBranch[0].telephoneNo"
v-model:branch-options="registerAbleBranchOption" v-model:branch-options="registerAbleBranchOption"
/> />
<div class="row q-col-gutter-sm" id="form-branch-customer-branch"> <div class="row q-col-gutter-sm" id="form-branch-customer-branch">
@ -1949,10 +2052,15 @@ const emptyCreateDialog = ref(false);
/> />
<span>{{ $t('customer.form.group.branch') }}</span> <span>{{ $t('customer.form.group.branch') }}</span>
<AddButton <AddButton
icon-only
type="button" type="button"
class="q-ml-sm" class="q-ml-sm"
@click="customerFormStore.addCurrentCustomerBranch()" @click="customerFormStore.addCurrentCustomerBranch()"
v-if="false" v-if="
customerFormState.branchIndex === -1 &&
!!customerFormState.editCustomerId &&
customerFormState.dialogType !== 'create'
"
:disabled="!customerFormState.readonly" :disabled="!customerFormState.readonly"
/> />
</div> </div>
@ -1986,10 +2094,6 @@ const emptyCreateDialog = ref(false);
'legalPersonNo', 'legalPersonNo',
'registerName', 'registerName',
'registerNameEN', 'registerNameEN',
'registerDate',
'authorizedCapital',
'authorizedName',
'authorizedNameEN',
'customerName', 'customerName',
]; ];
} }
@ -2014,16 +2118,23 @@ const emptyCreateDialog = ref(false);
}); });
} }
if (!customerFormData.customerBranch[idx].id) { if (!customerFormData.customerBranch[idx].id) {
await customerFormStore.submitFormCustomer( let res;
onCreateImageList, if (idx === 0) {
); res =
customerFormState.readonly = true; await customerFormStore.submitFormCustomer(
notify('create', $t('general.success')); onCreateImageList,
// await customerStore.createBranch({ );
// ...customerFormData.customerBranch[idx], } else {
// customerId: customerFormState.editCustomerId, res = await customerStore.createBranch({
// id: undefined, ...customerFormData.customerBranch[idx],
// }); customerId: customerFormState.editCustomerId,
id: undefined,
});
}
if (res) {
customerFormState.readonly = true;
notify('create', $t('general.success'));
}
} else { } else {
if (!customerFormState.editCustomerId) return; if (!customerFormState.editCustomerId) return;
await customerStore.editBranchById( await customerStore.editBranchById(
@ -2071,11 +2182,7 @@ const emptyCreateDialog = ref(false);
" "
> >
<!-- v-if="!!customerFormState.editCustomerId" --> <!-- v-if="!!customerFormState.editCustomerId" -->
<!-- :action-disabled="
!customerFormState.readonly ||
(customerFormState.branchIndex !== -1 &&
customerFormState.branchIndex !== idx)
" -->
<EmployerFormBranch <EmployerFormBranch
:index="idx" :index="idx"
v-model:customer="customerFormData" v-model:customer="customerFormData"
@ -2084,10 +2191,19 @@ const emptyCreateDialog = ref(false);
:customer-type="customerFormData.customerType" :customer-type="customerFormData.customerType"
:customer-name="`${customerFormData.firstName} ${customerFormData.lastName}`" :customer-name="`${customerFormData.firstName} ${customerFormData.lastName}`"
:readonly="customerFormState.branchIndex !== idx" :readonly="customerFormState.branchIndex !== idx"
:action-disabled="
!customerFormState.readonly ||
(customerFormState.branchIndex !== -1 &&
customerFormState.branchIndex !== idx)
"
@edit="() => (customerFormState.branchIndex = idx)" @edit="() => (customerFormState.branchIndex = idx)"
@cancel="() => customerFormUndo(false)" @cancel="() => customerFormUndo(false)"
@delete=" @delete="
async () => { async () => {
if (idx === 0) {
deleteCustomerById(customerFormState.editCustomerId);
return;
}
if (!!customerFormData.customerBranch?.[idx].id) { if (!!customerFormData.customerBranch?.[idx].id) {
const action = await deleteCustomerBranchById( const action = await deleteCustomerBranchById(
customerFormData.customerBranch[idx].id || '', customerFormData.customerBranch[idx].id || '',
@ -2825,7 +2941,7 @@ const emptyCreateDialog = ref(false);
}`" }`"
> >
<q-img <q-img
:src="`/images/customer-${customerFormData.customerType}-avartar-${customerFormData.gender}.png`" :src="`/images/customer-${customerFormData.customerType}-avartar-${customerFormData.customerType === 'PERS' ? customerFormData.gender : 'male'}.png`"
fit="contain" fit="contain"
style="height: 100%" style="height: 100%"
> >
@ -2943,16 +3059,19 @@ const emptyCreateDialog = ref(false);
hide-action hide-action
v-model:drawer-open="customerFormState.drawerModal" v-model:drawer-open="customerFormState.drawerModal"
:title=" :title="
$t(`form.title.${customerFormState.dialogType}`, { customerFormData.customerType === 'CORP'
name: $t('customer.employer'), ? customerFormData.customerBranch[0]?.registerName
}) : customerNameInfo
" "
:badgeClass=" :badgeLabel="
customerFormData.gender === 'male' customerFormData.customerType === 'CORP'
? 'app-bg-male text-white' ? $t('customer.employerLegalEntity')
: customerFormData.gender === 'female' : $t('customer.employerNaturalPerson')
? 'app-bg-female text-white' "
: '' :badgeStyle="
customerFormData.customerType === 'CORP'
? `color: var(--${$q.dark.isActive ? 'violet-10' : 'violet-11'}); background: hsl(var(--${$q.dark.isActive ? 'violet-10-hsl' : 'violet-11-hsl'})/0.15)`
: `color: var(--${$q.dark.isActive ? 'teal-8' : 'teal-10'}); background: hsl(var(--${$q.dark.isActive ? 'teal-8-hsl' : 'teal-10-hsl'})/0.15)`
" "
:close=" :close="
() => { () => {
@ -2991,8 +3110,12 @@ const emptyCreateDialog = ref(false);
<div class="column full-height"> <div class="column full-height">
<div class="q-px-lg q-pt-lg surface-2"> <div class="q-px-lg q-pt-lg surface-2">
<ProfileBanner <ProfileBanner
active :active="customerFormData.status !== 'INACTIVE'"
hide-fade hide-fade
useToggle
v-model:toggle-status="customerFormData.status"
:menu="formMenuIcon"
:toggleTitle="$t('status.title')"
:fallback-cover="`/images/customer-${customerFormData.customerType}-banner-bg.jpg`" :fallback-cover="`/images/customer-${customerFormData.customerType}-banner-bg.jpg`"
:img=" :img="
`${baseUrl}/customer/${customerFormState.editCustomerId}/image/${customerFormData.selectedImage}`.concat( `${baseUrl}/customer/${customerFormState.editCustomerId}/image/${customerFormData.selectedImage}`.concat(
@ -3007,6 +3130,16 @@ const emptyCreateDialog = ref(false);
? 'mdi-account-plus-outline' ? 'mdi-account-plus-outline'
: 'mdi-office-building-outline' : 'mdi-office-building-outline'
" "
:title="
customerFormData.customerType === 'PERS'
? `${customerFormData.customerBranch[0]?.firstName} ${customerFormData.customerBranch[0]?.lastName}`
: customerFormData.customerBranch[0]?.registerName
"
:caption="
customerFormData.customerType === 'PERS'
? `${customerFormData.customerBranch[0]?.firstNameEN} ${customerFormData.customerBranch[0]?.lastNameEN}`
: customerFormData.customerBranch[0]?.registerNameEN
"
@view=" @view="
() => { () => {
customerFormState.imageDialog = true; customerFormState.imageDialog = true;
@ -3016,6 +3149,12 @@ const emptyCreateDialog = ref(false);
@edit=" @edit="
customerFormState.imageDialog = customerFormState.isImageEdit = true customerFormState.imageDialog = customerFormState.isImageEdit = true
" "
@update:toggle-status="
async (v) => {
if (!customerFormState.editCustomerId) return;
await triggerChangeStatus(customerFormState.editCustomerId, v);
}
"
/> />
</div> </div>
@ -3163,15 +3302,30 @@ const emptyCreateDialog = ref(false);
if (!customerFormData.customerBranch) return; if (!customerFormData.customerBranch) return;
if (!customerFormState.editCustomerId) return; if (!customerFormState.editCustomerId) return;
if (customerFormData.customerType === 'PERS') {
tabFieldRequired.main = [
'citizenId',
'namePrefix',
'firstName',
'firstNameEN',
'lastName',
'lastNameEN',
'gender',
'birthDate',
];
}
if (customerFormData.customerType === 'CORP') { if (customerFormData.customerType === 'CORP') {
tabFieldRequired.main = [ tabFieldRequired.main = [
'legalPersonNo', 'legalPersonNo',
'registerName', 'registerName',
'registerNameEN',
'registerDate',
'authorizedCapital',
'authorizedName',
'authorizedNameEN',
'customerName',
]; ];
} }
if (customerFormData.customerType === 'PERS') {
tabFieldRequired.main = ['citizenId'];
}
let tapIsUndefined = validateTabField( let tapIsUndefined = validateTabField(
customerFormData.customerBranch?.[idx], customerFormData.customerBranch?.[idx],
@ -3179,7 +3333,7 @@ const emptyCreateDialog = ref(false);
); );
if (tapIsUndefined.length > 0) { if (tapIsUndefined.length > 0) {
dialog({ return dialog({
color: 'warning', color: 'warning',
icon: 'mdi-alert', icon: 'mdi-alert',
title: t('dialog.title.incompleteDataEntry'), title: t('dialog.title.incompleteDataEntry'),
@ -3192,52 +3346,51 @@ const emptyCreateDialog = ref(false);
return; return;
}, },
}); });
}
if (!customerFormData.customerBranch[idx].id) {
await customerStore.createBranch({
...customerFormData.customerBranch[idx],
customerId: customerFormState.editCustomerId,
id: undefined,
});
} else { } else {
if (!customerFormData.customerBranch[idx].id) { await customerStore.editBranchById(
await customerStore.createBranch({ customerFormData.customerBranch[idx].id || '',
{
...customerFormData.customerBranch[idx], ...customerFormData.customerBranch[idx],
customerId: customerFormState.editCustomerId,
id: undefined, id: undefined,
});
} else {
await customerStore.editBranchById(
customerFormData.customerBranch[idx].id || '',
{
...customerFormData.customerBranch[idx],
id: undefined,
},
);
}
customerFormData.customerBranch[idx].file?.forEach(
async (v) => {
if (!v.file) return;
const ext = v.file.name.split('.').at(-1);
let filename = v.group + '-' + new Date().getTime();
if (ext) filename += `.${ext}`;
const res = await customerStore.putAttachment({
branchId:
customerFormData.customerBranch?.[idx].id || '',
file: v.file,
filename,
});
if (res) {
await customerFormStore.assignFormData(
customerFormState.editCustomerId,
);
}
}, },
); );
await customerFormStore.assignFormData(
customerFormState.editCustomerId,
);
customerFormStore.resetForm();
} }
customerFormData.customerBranch[idx].file?.forEach(
async (v) => {
if (!v.file) return;
const ext = v.file.name.split('.').at(-1);
let filename = v.group + '-' + new Date().getTime();
if (ext) filename += `.${ext}`;
const res = await customerStore.putAttachment({
branchId:
customerFormData.customerBranch?.[idx].id || '',
file: v.file,
filename,
});
if (res) {
await customerFormStore.assignFormData(
customerFormState.editCustomerId,
);
}
},
);
await customerFormStore.assignFormData(
customerFormState.editCustomerId,
);
customerFormStore.resetForm();
} }
" "
> >

View file

@ -191,7 +191,7 @@ watch(
:rules="[ :rules="[
(val: string) => !!val || $t('form.error.required'), (val: string) => !!val || $t('form.error.required'),
(val: string) => (val: string) =>
/^[A-Za-z\s.,]+$/.test(val) || $t('form.error.letterOnly'), /^[0-9A-Za-z\s.,]+$/.test(val) || $t('form.error.letterOnly'),
]" ]"
/> />
</div> </div>
@ -248,7 +248,7 @@ watch(
</template> </template>
<template v-if="customerType === 'PERS'"> <template v-if="customerType === 'PERS'">
<div class="col-6 row q-col-gutter-sm"> <div class="col-7 row q-col-gutter-sm">
<q-input <q-input
dense dense
outlined outlined
@ -264,7 +264,7 @@ watch(
<q-input <q-input
dense dense
outlined outlined
:disable="index !== '0'" :disable="index !== '0' && !readonly"
:readonly="readonly" :readonly="readonly"
hide-bottom-space hide-bottom-space
class="col-12 col-md-7" class="col-12 col-md-7"
@ -283,7 +283,7 @@ watch(
/> />
</div> </div>
<div class="col-8 row q-col-gutter-sm"> <div class="col-9 row q-col-gutter-sm">
<q-select <q-select
outlined outlined
use-input use-input
@ -342,7 +342,7 @@ watch(
/> />
</div> </div>
<div class="col-8 row q-col-gutter-sm"> <div class="col-9 row q-col-gutter-sm">
<q-input <q-input
:for="`${prefixId}-input-first-name`" :for="`${prefixId}-input-first-name`"
dense dense
@ -387,7 +387,7 @@ watch(
/> />
</div> </div>
<div class="row col-8 q-col-gutter-sm"> <div class="row col-9 q-col-gutter-sm">
<q-input <q-input
:for="`${prefixId}-input-telephone`" :for="`${prefixId}-input-telephone`"
dense dense

View file

@ -39,15 +39,15 @@ const registeredBranchId = defineModel<string>('registeredBranchId', {
required: true, required: true,
}); });
const customerName = defineModel<string>('customerName'); const customerName = defineModel<string>('customerName', { default: '' });
const registerName = defineModel<string>('registerName'); const registerName = defineModel<string>('registerName', { default: '' });
const citizenId = defineModel<string>('citizenId'); const citizenId = defineModel<string>('citizenId', { default: '' });
const legalPersonNo = defineModel<string>('legalPersonNo'); const legalPersonNo = defineModel<string>('legalPersonNo', { default: '' });
const businessType = defineModel<'strinf'>('businessType'); const businessType = defineModel<'string'>('businessType');
const jobPosition = defineModel<'strinf'>('jobPosition'); const jobPosition = defineModel<'string'>('jobPosition');
const telephoneNo = defineModel<string>('telephoneNo'); const telephoneNo = defineModel<string>('telephoneNo', { default: '' });
const branchOptions = defineModel<{ id: string; name: string }[]>( const branchOptions = defineModel<{ id: string; name: string }[]>(
'branchOptions', 'branchOptions',

View file

@ -110,7 +110,7 @@ let jobPositionENFilter = selectFilterOptionRefMod(
map-options map-options
hide-selected hide-selected
hide-bottom-space hide-bottom-space
hide-dropdown-icon :hide-dropdown-icon="readonly"
input-debounce="0" input-debounce="0"
option-value="value" option-value="value"
option-label="label" option-label="label"
@ -122,6 +122,7 @@ let jobPositionENFilter = selectFilterOptionRefMod(
:options="typeBusinessOptions" :options="typeBusinessOptions"
:for="`${prefixId}-select-business-type`" :for="`${prefixId}-select-business-type`"
@filter="typeBusinessFilter" @filter="typeBusinessFilter"
:rules="[(val: string) => !!val || $t('form.error.required')]"
> >
<template v-slot:no-option> <template v-slot:no-option>
<q-item> <q-item>
@ -143,7 +144,7 @@ let jobPositionENFilter = selectFilterOptionRefMod(
map-options map-options
hide-selected hide-selected
hide-bottom-space hide-bottom-space
hide-dropdown-icon :hide-dropdown-icon="readonly"
input-debounce="0" input-debounce="0"
option-value="value" option-value="value"
option-label="label" option-label="label"
@ -153,6 +154,7 @@ let jobPositionENFilter = selectFilterOptionRefMod(
:readonly="readonly" :readonly="readonly"
:options="typeBusinessENOptions" :options="typeBusinessENOptions"
@filter="typeBusinessENFilter" @filter="typeBusinessENFilter"
:rules="[(val: string) => !!val || $t('form.error.required')]"
> >
<template v-slot:no-option> <template v-slot:no-option>
<q-item> <q-item>
@ -172,7 +174,7 @@ let jobPositionENFilter = selectFilterOptionRefMod(
map-options map-options
hide-selected hide-selected
hide-bottom-space hide-bottom-space
hide-dropdown-icon :hide-dropdown-icon="readonly"
input-debounce="0" input-debounce="0"
option-value="value" option-value="value"
option-label="label" option-label="label"
@ -184,6 +186,7 @@ let jobPositionENFilter = selectFilterOptionRefMod(
:options="jobPositionOptions" :options="jobPositionOptions"
:for="`${prefixId}-select-job-position`" :for="`${prefixId}-select-job-position`"
@filter="jobPositionFilter" @filter="jobPositionFilter"
:rules="[(val: string) => !!val || $t('form.error.required')]"
> >
<template v-slot:no-option> <template v-slot:no-option>
<q-item> <q-item>
@ -203,7 +206,7 @@ let jobPositionENFilter = selectFilterOptionRefMod(
map-options map-options
hide-selected hide-selected
hide-bottom-space hide-bottom-space
hide-dropdown-icon :hide-dropdown-icon="readonly"
input-debounce="0" input-debounce="0"
option-value="value" option-value="value"
option-label="label" option-label="label"
@ -216,6 +219,7 @@ let jobPositionENFilter = selectFilterOptionRefMod(
:for="`${prefixId}-input-job-position-en`" :for="`${prefixId}-input-job-position-en`"
:id="`${prefixId}-input-job-position-en`" :id="`${prefixId}-input-job-position-en`"
@filter="jobPositionENFilter" @filter="jobPositionENFilter"
:rules="[(val: string) => !!val || $t('form.error.required')]"
> >
<template v-slot:no-option> <template v-slot:no-option>
<q-item> <q-item>

View file

@ -207,10 +207,10 @@ export const columnsCustomer = [
}, },
{ {
name: 'customerName', name: 'fullname',
align: 'left', align: 'left',
label: 'customer.table.fullname', label: 'customer.table.fullname',
field: 'customerName', field: 'fullname',
sortable: true, sortable: true,
}, },
@ -223,30 +223,17 @@ export const columnsCustomer = [
}, },
{ {
name: 'address', name: 'jobPosition',
align: 'left', align: 'center',
label: 'customer.table.address', label: 'customer.table.jobPosition',
field: 'address', field: 'jobPosition',
sortable: true,
}, },
{ {
name: 'workPlace', name: 'officeTel',
align: 'left', align: 'left',
label: 'customer.table.workPlace', label: 'customer.table.officeTel',
field: 'workPlace', field: 'officeTel',
},
{
name: 'contactName',
align: 'left',
label: 'customer.table.contactName',
field: 'contactName',
},
{
name: 'contactPhone',
align: 'left',
label: 'customer.table.contactPhone',
field: 'contactPhone',
}, },
] satisfies QTableProps['columns']; ] satisfies QTableProps['columns'];

View file

@ -87,9 +87,10 @@ export const useCustomerForm = defineStore('form-customer', () => {
} }
function isFormDataDifferent() { function isFormDataDifferent() {
return ( const { status: resetStatus, ...resetData } = resetFormData;
JSON.stringify(resetFormData) !== JSON.stringify(currentFormData.value) const { status: currStatus, ...currData } = currentFormData.value;
);
return JSON.stringify(resetData) !== JSON.stringify(currData);
} }
function resetForm(clean = false) { function resetForm(clean = false) {
@ -155,7 +156,6 @@ export const useCustomerForm = defineStore('form-customer', () => {
wageRate: v.wageRate, wageRate: v.wageRate,
wageRateText: v.wageRateText, wageRateText: v.wageRateText,
payDate: v.payDate, payDate: v.payDate,
saleEmployee: v.saleEmployee,
jobDescription: v.jobDescription, jobDescription: v.jobDescription,
jobPositionEN: v.jobPositionEN, jobPositionEN: v.jobPositionEN,
jobPosition: v.jobPosition, jobPosition: v.jobPosition,
@ -177,8 +177,6 @@ export const useCustomerForm = defineStore('form-customer', () => {
soi: v.soi, soi: v.soi,
addressEN: v.addressEN, addressEN: v.addressEN,
address: v.address, address: v.address,
workplaceEN: v.workplaceEN,
workplace: v.workplace,
authorizedCapital: v.authorizedCapital, authorizedCapital: v.authorizedCapital,
registerDate: v.registerDate, registerDate: v.registerDate,
registerNameEN: v.registerNameEN, registerNameEN: v.registerNameEN,
@ -362,38 +360,63 @@ export const useCustomerBranchForm = defineStore('form-customer-branch', () => {
const customerStore = useCustomerStore(); const customerStore = useCustomerStore();
const customerFormStore = useCustomerForm(); const customerFormStore = useCustomerForm();
const defaultFormData: CustomerBranchCreate & { id?: string } = { const defaultFormData: CustomerBranchCreate & {
code: '', id?: string;
customerCode: '', codeCustomer?: string;
} = {
id: '',
customerId: '',
// branchCode: '',
// codeCustomer: '',
legalPersonNo: '',
citizenId: '',
namePrefix: '',
firstName: '',
lastName: '',
firstNameEN: '',
lastNameEN: '',
telephoneNo: '',
gender: '',
birthDate: '',
businessType: '',
jobPosition: '',
jobDescription: '',
payDate: '',
payDateEN: '',
wageRate: 0,
wageRateText: '',
homeCode: '',
employmentOffice: '',
employmentOfficeEN: '',
address: '',
addressEN: '',
street: '',
streetEN: '',
moo: '',
mooEN: '',
soi: '',
soiEN: '',
provinceId: '', provinceId: '',
districtId: '', districtId: '',
subDistrictId: '', subDistrictId: '',
wageRate: 0,
payDate: '',
payDateEN: '',
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: '',
statusSave: false,
contactName: '', contactName: '',
email: '',
contactTel: '',
officeTel: '',
agent: '',
status: 'CREATED',
customerName: '',
registerName: '',
registerNameEN: '',
registerDate: null,
authorizedCapital: '',
authorizedName: '',
authorizedNameEN: '',
file: [], file: [],
}; };
@ -427,8 +450,8 @@ export const useCustomerBranchForm = defineStore('form-customer-branch', () => {
const _data = await customerStore.getBranchById(id); const _data = await customerStore.getBranchById(id);
if (!_data) return; if (!_data) return;
resetFormData = { resetFormData = {
id: _data.id,
code: _data.code, code: _data.code,
customerCode: '', customerCode: '',
provinceId: _data.provinceId, provinceId: _data.provinceId,
@ -437,19 +460,15 @@ export const useCustomerBranchForm = defineStore('form-customer-branch', () => {
wageRate: _data.wageRate, wageRate: _data.wageRate,
payDate: _data.payDate, // Convert the string to a Date object payDate: _data.payDate, // Convert the string to a Date object
payDateEN: _data.payDateEN, payDateEN: _data.payDateEN,
saleEmployee: _data.saleEmployee,
jobDescription: _data.jobDescription, jobDescription: _data.jobDescription,
jobPositionEN: _data.jobPositionEN,
jobPosition: _data.jobPosition, jobPosition: _data.jobPosition,
businessTypeEN: _data.businessTypeEN,
businessType: _data.businessType, businessType: _data.businessType,
employmentOffice: _data.employmentOffice, employmentOffice: _data.employmentOffice,
employmentOfficeEN: _data.employmentOfficeEN,
telephoneNo: _data.telephoneNo, telephoneNo: _data.telephoneNo,
email: _data.email, email: _data.email,
addressEN: _data.addressEN, addressEN: _data.addressEN,
address: _data.address, address: _data.address,
workplaceEN: _data.workplaceEN,
workplace: _data.workplace,
status: 'CREATED', status: 'CREATED',
customerId: _data.customerId, customerId: _data.customerId,
citizenId: _data.citizenId, citizenId: _data.citizenId,
@ -459,6 +478,28 @@ export const useCustomerBranchForm = defineStore('form-customer-branch', () => {
registerName: _data.registerName, registerName: _data.registerName,
legalPersonNo: _data.legalPersonNo, legalPersonNo: _data.legalPersonNo,
contactName: _data.contactName, 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,
agent: _data.agent,
codeCustomer: _data.codeCustomer,
customerName: _data.customerName,
homeCode: _data.homeCode,
authorizedName: _data.authorizedName,
authorizedNameEN: _data.authorizedNameEN,
statusSave: false, statusSave: false,
file: [], file: [],
}; };
@ -482,6 +523,7 @@ export const useCustomerBranchForm = defineStore('form-customer-branch', () => {
); );
async function submitForm() { async function submitForm() {
console.log(currentFormData.value);
if (!state.value.currentCustomerId) { if (!state.value.currentCustomerId) {
throw new Error( throw new Error(
'Employer id cannot be found. Did you properly set employer id?', 'Employer id cannot be found. Did you properly set employer id?',

View file

@ -441,6 +441,7 @@ const useCustomerStore = defineStore('api-customer', () => {
statusOrder, statusOrder,
updatedAt, updatedAt,
updatedByUserId, updatedByUserId,
customerCode,
file, file,
registerCompanyName, registerCompanyName,
statusSave, statusSave,

View file

@ -5,24 +5,18 @@ export type CustomerType = 'CORP' | 'PERS';
export type Customer = { export type Customer = {
registeredBranchId: string; registeredBranchId: string;
selectedImage: string;
imageUrl: string; imageUrl: string;
id: string; id: string;
code: string; code: string;
customerType: CustomerType; customerType: CustomerType;
status: Status; status: Status;
namePrefix: string;
firstName: string;
lastName: string;
firstNameEN: string;
lastNameEN: string;
gender: string;
birthDate: Date;
createdBy: string | null; createdBy: string | null;
createdAt: string; createdAt: string;
updatedBy: string | null; updatedBy: string | null;
updatedAt: string; updatedAt: string;
branch: CustomerBranch[];
_count: { _count: {
employee: number; employee: number;