fix: customer

This commit is contained in:
puriphatt 2024-09-16 14:38:04 +07:00
parent cfaf1467a6
commit 4bf1a4a346
11 changed files with 1569 additions and 533 deletions

View file

@ -23,6 +23,7 @@ defineProps<{
prefixId: string; prefixId: string;
hideTitle?: boolean; hideTitle?: boolean;
useEmployment?: boolean;
useWorkPlace?: boolean; useWorkPlace?: boolean;
}>(); }>();
@ -43,6 +44,14 @@ const subDistrictId = defineModel<string | null | undefined>('subDistrictId');
const zipCode = defineModel<string | null | undefined>('zipCode'); const zipCode = defineModel<string | null | undefined>('zipCode');
const sameWithEmployer = defineModel<boolean>('sameWithEmployer'); const sameWithEmployer = defineModel<boolean>('sameWithEmployer');
const homeCode = defineModel<string | null | undefined>('homeCode');
const employmentOffice = defineModel<string | null | undefined>(
'employmentOffice',
);
const employmentOfficeEN = defineModel<string | null | undefined>(
'employmentOfficeEN',
);
const addrOptions = reactive<{ const addrOptions = reactive<{
provinceOps: Province[]; provinceOps: Province[];
districtOps: District[]; districtOps: District[];
@ -274,6 +283,43 @@ watch(districtId, fetchSubDistrict);
</div> </div>
<div class="col-12 row q-col-gutter-y-md"> <div class="col-12 row q-col-gutter-y-md">
<div v-if="useEmployment" class="col-12 row q-col-gutter-sm">
<q-input
outlined
hide-bottom-space
class="col-3"
v-model="homeCode"
:dense="dense"
:label="$t('customer.form.homeCode')"
:readonly="readonly || sameWithEmployer"
:for="`${prefixId}-${indexId !== undefined ? `input-address-${indexId}` : 'input-address'}`"
:rules="
disabledRule
? []
: [(val) => (val && val.length > 0) || $t('form.error.required')]
"
/>
<q-input
outlined
hide-bottom-space
class="col"
v-model="employmentOffice"
:dense="dense"
:label="$t('customer.form.employmentOffice')"
:readonly="readonly || sameWithEmployer"
:for="`${prefixId}-${indexId !== undefined ? `input-address-${indexId}` : 'input-address'}`"
/>
<q-input
outlined
hide-bottom-space
class="col"
v-model="employmentOfficeEN"
:dense="dense"
:label="`${$t('customer.form.employmentOffice')} (EN)`"
:readonly="readonly || sameWithEmployer"
:for="`${prefixId}-${indexId !== undefined ? `input-address-${indexId}` : 'input-address'}`"
/>
</div>
<div class="col-12 app-text-muted-2"> <div class="col-12 app-text-muted-2">
<q-icon size="xs" class="q-mr-xs" name="mdi-map-marker-outline" /> <q-icon size="xs" class="q-mr-xs" name="mdi-map-marker-outline" />
{{ addressTitle || $t('form.address') }} {{ addressTitle || $t('form.address') }}

View file

@ -563,7 +563,7 @@ function customerFormUndo(close = true) {
customerFormState.value.readonly = true; customerFormState.value.readonly = true;
} }
function createCustomerForm(customerType: 'CORP' | 'PERS') { async function createCustomerForm(customerType: 'CORP' | 'PERS') {
customerFormState.value.dialogModal = true; customerFormState.value.dialogModal = true;
customerFormState.value.dialogType = 'create'; customerFormState.value.dialogType = 'create';
customerFormData.value.customerType = customerType; customerFormData.value.customerType = customerType;
@ -1765,6 +1765,7 @@ const emptyCreateDialog = ref(false);
customerFormStore.resetForm(customerFormState.dialogType === 'create'); customerFormStore.resetForm(customerFormState.dialogType === 'create');
onCreateImageList = { selectedImage: '', list: [] }; onCreateImageList = { selectedImage: '', list: [] };
await fetchListOfOptionBranch(); await fetchListOfOptionBranch();
await customerFormStore.addCurrentCustomerBranch();
} }
" "
:on-close=" :on-close="
@ -1777,23 +1778,22 @@ const emptyCreateDialog = ref(false);
<template #header> <template #header>
<DialogHeader <DialogHeader
:title=" :title="
$t(`form.title.${customerFormState.dialogType}`, { $t(`general.add`, {
name: `${$t('customer.employer')} ${ text: `${$t('customer.employer')} `,
customerFormData.customerType === 'CORP'
? $t('customer.employerLegalEntity')
: $t('customer.employerNaturalPerson')
}`,
}) })
" "
> >
<template <template #title-after>
v-if=" <span
customerFormState.dialogType !== 'create' && :style="`color: hsla(var(--${customerFormData.customerType === 'PERS' ? 'teal-10-hsl' : 'violet-11-hsl'})/1)`"
customerFormState.editCustomerCode
"
#title-after
> >
{{ customerFormState.editCustomerCode }} :
{{
customerFormData.customerType === 'CORP'
? $t('customer.employerLegalEntity')
: $t('customer.employerNaturalPerson')
}}
</span>
</template> </template>
</DialogHeader> </DialogHeader>
</template> </template>
@ -1876,17 +1876,16 @@ const emptyCreateDialog = ref(false);
<q-form <q-form
@submit.prevent=" @submit.prevent="
async () => { async () => {
await customerFormStore.submitFormCustomer(onCreateImageList); console.log(customerFormData);
customerFormState.readonly = true; // await customerFormStore.submitFormCustomer(onCreateImageList);
// customerFormState.readonly = true;
notify('create', $t('general.success')); notify('create', $t('general.success'));
await fetchListCustomer(); // await fetchListCustomer();
} }
" "
greedy greedy
:style="{
opacity: customerFormState.branchIndex !== -1 ? '0.5' : undefined,
}"
> >
<!-- :create="customerFormState.dialogType === 'create'" -->
<EmployerFormBasicInfo <EmployerFormBasicInfo
class="q-mb-xl" class="q-mb-xl"
:readonly=" :readonly="
@ -1896,7 +1895,7 @@ const emptyCreateDialog = ref(false);
" "
:action-disabled="customerFormState.branchIndex !== -1" :action-disabled="customerFormState.branchIndex !== -1"
id="form-basic-info-customer" id="form-basic-info-customer"
:create="customerFormState.dialogType === 'create'" :create="false"
@edit=" @edit="
(customerFormState.dialogType = 'edit'), (customerFormState.dialogType = 'edit'),
(customerFormState.readonly = false) (customerFormState.readonly = false)
@ -1907,26 +1906,19 @@ const emptyCreateDialog = ref(false);
deleteCustomerById(customerFormState.editCustomerId) deleteCustomerById(customerFormState.editCustomerId)
" "
:customer-type="customerFormData.customerType" :customer-type="customerFormData.customerType"
v-model:code="customerFormData.code"
v-model:registered-branch-id="customerFormData.registeredBranchId" v-model:registered-branch-id="customerFormData.registeredBranchId"
v-mode:customerName="customerFormData.customerName"
v-mode:registerName="customerFormData.registerName"
v-mode:citizenId="customerFormData.citizenId"
v-mode:legalPersonNo="customerFormData.legalPersonNo"
v-mode:businessType="customerFormData.businessType"
v-mode:jobPosition="customerFormData.jobPosition"
v-mode:telephoneNo="customerFormData.telephoneNo"
v-model:branch-options="registerAbleBranchOption" v-model:branch-options="registerAbleBranchOption"
v-model:first-name="customerFormData.firstName"
v-model:last-name="customerFormData.lastName"
v-model:first-name-en="customerFormData.firstNameEN"
v-model:last-name-en="customerFormData.lastNameEN"
v-model:name-prefix="customerFormData.namePrefix"
v-model:gender="customerFormData.gender"
v-model:birth-date="customerFormData.birthDate"
/> />
</q-form> </q-form>
<div class="row q-col-gutter-sm" id="form-branch-customer-branch"> <div class="row q-col-gutter-sm" id="form-branch-customer-branch">
<div <div class="col-12 text-weight-bold text-body1 row items-center">
class="col-12 text-weight-bold text-body1 row items-center"
:style="{
opacity:
customerFormState.branchIndex !== -1 ? '0.5' : undefined,
}"
>
<q-icon <q-icon
flat flat
size="xs" size="xs"
@ -1940,20 +1932,18 @@ const emptyCreateDialog = ref(false);
type="button" type="button"
class="q-ml-sm" class="q-ml-sm"
@click="customerFormStore.addCurrentCustomerBranch()" @click="customerFormStore.addCurrentCustomerBranch()"
v-if=" v-if="false"
customerFormState.branchIndex === -1 &&
!!customerFormState.editCustomerId
"
:disabled="!customerFormState.readonly" :disabled="!customerFormState.readonly"
/> />
</div> </div>
<template <template
v-for="(_, idx) in customerFormData.customerBranch" v-for="(_, idx) in customerFormData.customerBranch"
:key="idx" :key="idx"
> >
<!-- v-if="customerFormData.customerBranch" -->
<q-form <q-form
class="full-width" class="full-width"
v-if="customerFormData.customerBranch"
greedy greedy
@submit.prevent=" @submit.prevent="
async () => { async () => {
@ -1961,7 +1951,12 @@ const emptyCreateDialog = ref(false);
if (!customerFormState.editCustomerId) return; if (!customerFormState.editCustomerId) return;
if (customerFormData.customerType === 'CORP') { if (customerFormData.customerType === 'CORP') {
filtdRequire.main = ['legalPersonNo', 'registerName']; filtdRequire.main = [
'legalPersonNo',
'registerName',
'address',
'addressEN',
];
} }
if (customerFormData.customerType === 'PERS') { if (customerFormData.customerType === 'PERS') {
filtdRequire.main = ['citizenId']; filtdRequire.main = ['citizenId'];
@ -1988,11 +1983,17 @@ const emptyCreateDialog = ref(false);
}); });
} else { } else {
if (!customerFormData.customerBranch[idx].id) { if (!customerFormData.customerBranch[idx].id) {
await customerStore.createBranch({ await customerFormStore.submitFormCustomer(
...customerFormData.customerBranch[idx], onCreateImageList,
customerId: customerFormState.editCustomerId, );
id: undefined, customerFormState.readonly = true;
}); notify('create', $t('general.success'));
await fetchListCustomer();
// await customerStore.createBranch({
// ...customerFormData.customerBranch[idx],
// customerId: customerFormState.editCustomerId,
// id: undefined,
// });
} else { } else {
await customerStore.editBranchById( await customerStore.editBranchById(
customerFormData.customerBranch[idx].id || '', customerFormData.customerBranch[idx].id || '',
@ -2034,18 +2035,18 @@ const emptyCreateDialog = ref(false);
} }
" "
> >
<!-- v-if="!!customerFormState.editCustomerId" -->
<!-- :action-disabled="
!customerFormState.readonly ||
(customerFormState.branchIndex !== -1 &&
customerFormState.branchIndex !== idx)
" -->
<EmployerFormBranch <EmployerFormBranch
v-if="!!customerFormState.editCustomerId"
:index="idx" :index="idx"
v-model:customer="customerFormData" v-model:customer="customerFormData"
v-model:customer-branch="customerFormData.customerBranch[idx]" v-model:customer-branch="customerFormData.customerBranch[idx]"
:customer-type="customerFormData.customerType" :customer-type="customerFormData.customerType"
:customer-name="`${customerFormData.firstName} ${customerFormData.lastName}`" :customer-name="`${customerFormData.firstName} ${customerFormData.lastName}`"
:action-disabled="
!customerFormState.readonly ||
(customerFormState.branchIndex !== -1 &&
customerFormState.branchIndex !== idx)
"
:readonly="customerFormState.branchIndex !== idx" :readonly="customerFormState.branchIndex !== idx"
@edit="() => (customerFormState.branchIndex = idx)" @edit="() => (customerFormState.branchIndex = idx)"
@cancel="() => customerFormUndo(false)" @cancel="() => customerFormUndo(false)"

View file

@ -1,52 +1,134 @@
<script setup lang="ts"> <script setup lang="ts">
import DatePicker from 'src/components/shared/DatePicker.vue'; import { QSelect } from 'quasar';
import { formatNumberDecimal } from 'stores/utils'; import { onMounted, ref, watch, capitalize } from 'vue';
import { formatNumberDecimal, selectFilterOptionRefMod } from 'stores/utils';
import { calculateAge, disabledAfterToday } from 'src/utils/datetime';
import useOptionStore from 'src/stores/options';
import DatePicker from 'src/components/shared/DatePicker.vue';
const props = defineProps<{
index: string;
code?: string;
readonly?: boolean;
prefixId?: string;
customerType?: 'PERS' | 'CORP';
}>();
const optionStore = useOptionStore();
// PERS
const citizenId = defineModel<string | undefined>('citizenId', { const citizenId = defineModel<string | undefined>('citizenId', {
required: true, required: true,
}); });
const prefixName = defineModel<string | null>('prefixName');
const firstName = defineModel<string>('firstName');
const lastName = defineModel<string>('lastName');
const firstNameEN = defineModel<string>('firstNameEN');
const lastNameEN = defineModel<string>('lastNameEN');
const gender = defineModel<string>('gender');
const birthDate = defineModel<Date | string | null>('birthDate');
// CORP
const customerName = defineModel<string>('customerName');
const legalPersonNo = defineModel<string | undefined>('legalPersonNo', { const legalPersonNo = defineModel<string | undefined>('legalPersonNo', {
required: true, required: true,
}); });
const branchCode = defineModel<string | undefined>('branchCode', { const branchCode = defineModel<string | undefined>('branchCode', {
required: true, required: true,
}); });
const customerCode = defineModel<string | undefined>('customerCode', {
required: true,
});
const registerName = defineModel<string | undefined>('registerName', { const registerName = defineModel<string | undefined>('registerName', {
required: true, required: true,
}); });
const registerNameEN = defineModel<string>('registerNameEn'); const registerNameEN = defineModel<string | undefined>('registerNameEN', {
required: true,
});
const registerDate = defineModel<Date | null>('registerDate'); const registerDate = defineModel<Date | null>('registerDate');
const authorizedCapital = defineModel<string>('authorizedCapital', { const authorizedCapital = defineModel<string>('authorizedCapital', {
default: '0', default: '0',
}); });
defineProps<{ // both
index: string; const telephoneNo = defineModel<string>('telephoneNo');
customerName?: string; const customerCode = defineModel<string | undefined>('customerCode', {
code?: string; required: true,
readonly?: boolean; });
prefixId?: string;
customerType?: 'PERS' | 'CORP'; const prefixNameOptions = ref<Record<string, unknown>[]>([]);
}>(); let prefixNameFilter: (
value: string,
update: (callbackFn: () => void, afterFn?: (ref: QSelect) => void) => void,
) => void;
const genderOptions = ref<Record<string, unknown>[]>([]);
let genderFilter: (
value: string,
update: (callbackFn: () => void, afterFn?: (ref: QSelect) => void) => void,
) => void;
onMounted(() => {
prefixNameFilter = selectFilterOptionRefMod(
ref(optionStore.globalOption?.prefix),
prefixNameOptions,
'label',
);
genderFilter = selectFilterOptionRefMod(
ref(optionStore.globalOption?.gender),
genderOptions,
'label',
);
});
watch(
() => optionStore.globalOption,
() => {
prefixNameFilter = selectFilterOptionRefMod(
ref(optionStore.globalOption.prefix),
prefixNameOptions,
'label',
);
genderFilter = selectFilterOptionRefMod(
ref(optionStore.globalOption.gender),
genderOptions,
'label',
);
},
);
watch(
() => prefixName.value,
(v) => {
if (props.readonly) return;
if (v === 'mr') gender.value = 'male';
else if (v !== '') gender.value = 'female';
},
);
</script> </script>
<template> <template>
<div class="row q-col-gutter-md"> <div class="row q-col-gutter-sm">
<template v-if="customerType === 'CORP'"> <template v-if="customerType === 'CORP'">
<div class="col-12 row q-col-gutter-sm">
<q-input <q-input
dense dense
outlined outlined
:readonly="readonly" :readonly="readonly"
hide-bottom-space hide-bottom-space
class="col-12 col-md-3" class="col-6 col-md-5"
:label="$t('customer.form.legalPersonNo')" :label="$t('customer.form.employerName')"
for="input-legal-person-no" for="input-legal-person-no"
v-model="customerName"
:rules="[(val: string) => !!val || $t('form.error.required')]"
/>
<q-input
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col-12 col-md"
:label="$t('customer.form.legalPersonCode')"
for="input-legal-person-code"
v-model="legalPersonNo" v-model="legalPersonNo"
/> />
@ -54,37 +136,28 @@ defineProps<{
dense dense
outlined outlined
hide-bottom-space hide-bottom-space
class="col-12 col-md-3" class="col-12 col-md"
for="input-customer-code"
:disable="!readonly"
:readonly="readonly"
:label="$t('customer.form.customerCode')"
:model-value="customerCode"
/>
<q-input
dense
outlined
hide-bottom-space
class="col-12 col-md"
for="input-branch-code" for="input-branch-code"
:label="$t('customer.form.branchCode')" :label="$t('customer.form.branchCode')"
:disable="!readonly" :disable="!readonly"
:readonly="readonly" :readonly="readonly"
:model-value="`${branchCode?.slice(0, -2) || '-'}${index.toString().padStart(2, '0')}`" :model-value="`${branchCode?.slice(0, -2) || '-'}${index.toString().padStart(2, '0')}`"
/> />
</div>
<q-input <div class="col-12 row q-col-gutter-sm">
dense
outlined
hide-bottom-space
class="col-12 col-md-3"
for="input-customer-code"
:disable="!readonly"
:readonly="readonly"
:label="$t('customer.form.customerCode')"
:model-value="legalPersonNo"
/>
<q-input
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col-12 col-md-3"
:label="$t('customer.form.legalPersonCode')"
for="input-legal-person-code"
:model-value="legalPersonNo"
/>
<q-input <q-input
dense dense
outlined outlined
@ -94,6 +167,7 @@ defineProps<{
:label="$t('customer.form.registerName')" :label="$t('customer.form.registerName')"
for="input-register-name" for="input-register-name"
v-model="registerName" v-model="registerName"
:rules="[(val: string) => !!val || $t('form.error.required')]"
/> />
<q-input <q-input
@ -102,20 +176,33 @@ defineProps<{
:readonly="readonly" :readonly="readonly"
hide-bottom-space hide-bottom-space
class="col-12 col-md-6" class="col-12 col-md-6"
:label="$t('customer.form.registerNameEN')" label="Company name"
for="input-register-name-en" for="input-register-name-en"
v-model="registerNameEN" v-model="registerNameEN"
:rules="[(val) => /^[A-Za-z]+$/.test(val)]" :rules="[
:error-message="$t('form.error.letterOnly')" (val: string) => !!val || $t('form.error.required'),
(val: string) =>
/^[A-Za-z]+$/.test(val) || $t('form.error.letterOnly'),
]"
/> />
</div>
<div class="col-12 row q-col-gutter-sm">
<DatePicker
v-model="registerDate"
class="col-6 col-md-2"
:id="`${prefixId}-input-register-date`"
:label="$t('customer.form.registerDate')"
:readonly="readonly"
clearable
/>
<q-input <q-input
dense dense
outlined outlined
type="text" type="text"
:readonly="readonly" :readonly="readonly"
hide-bottom-space hide-bottom-space
class="col-12 col-md-3" class="col-12 col-md-2"
:label="$t('customer.form.authorizedCapital')" :label="$t('customer.form.authorizedCapital')"
for="input-authorized-capital" for="input-authorized-capital"
:model-value=" :model-value="
@ -129,52 +216,247 @@ defineProps<{
} }
" "
/> />
<q-input
<DatePicker dense
v-model="registerDate" outlined
:id="`${prefixId}-input-register-date`"
:label="$t('customer.form.registerDate')"
:readonly="readonly" :readonly="readonly"
clearable hide-bottom-space
class="col-6 col-md-3"
:label="$t('customer.form.headQuarters.telephoneNo')"
for="input-first-name-en"
v-model="telephoneNo"
>
<template #prepend>
<q-icon
size="xs"
name="mdi-phone-outline"
class="cursor-pointer"
color="primary"
/> />
</template> </template>
</q-input>
</div>
</template>
<template v-if="customerType === 'PERS'"> <template v-if="customerType === 'PERS'">
<div class="col-6 row q-col-gutter-sm">
<q-input
dense
outlined
hide-bottom-space
class="col-12 col-md-5"
for="input-customer-code"
:disable="!readonly"
:readonly="readonly"
:label="$t('customer.form.customerCode')"
:model-value="customerCode"
/>
<q-input <q-input
dense dense
outlined outlined
:disable="index !== '0'" :disable="index !== '0'"
:readonly="readonly" :readonly="readonly"
hide-bottom-space hide-bottom-space
class="col-12 col-md-3" class="col-12 col-md-7"
:label="$t('customer.form.cardNumber')" :label="$t('customer.form.cardNumber')"
for="input-legal-person-no" for="input-legal-person-no"
v-model="citizenId" v-model="citizenId"
/> />
</div>
<div class="col-8 row q-col-gutter-sm">
<q-select
outlined
use-input
fill-input
emit-value
map-options
hide-selected
hide-bottom-space
input-debounce="0"
option-label="label"
option-value="value"
hide-dropdown-icon
class="col-md-2 col-6"
dense
:readonly="readonly"
:options="prefixNameOptions"
:for="`${prefixId}-select-prefix-name`"
:label="$t('personnel.form.prefixName')"
@filter="prefixNameFilter"
:model-value="readonly ? prefixName || '-' : prefixName"
@update:model-value="
(v) => (typeof v === 'string' ? (prefixName = v) : '')
"
@clear="prefixName = ''"
>
<template v-slot:no-option>
<q-item>
<q-item-section class="text-grey">
{{ $t('general.noData') }}
</q-item-section>
</q-item>
</template>
</q-select>
<q-input <q-input
:for="`${prefixId}-input-first-name`"
dense dense
outlined outlined
:disable="!readonly"
:readonly="readonly" :readonly="readonly"
hide-bottom-space hide-bottom-space
class="col-12 col-md-3" class="col"
:label="$t('customer.form.branchCode')" :label="$t('personnel.form.firstName')"
for="input-branch-code" v-model="firstName"
:model-value="`${branchCode?.slice(0, -2) || '-'}${index.toString().padStart(2, '0')}`" :rules="[(val: string) => !!val || $t('form.error.required')]"
/>
<q-input
:for="`${prefixId}-input-last-name`"
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col"
:label="$t('personnel.form.lastName')"
v-model="lastName"
:rules="[(val: string) => !!val || $t('form.error.required')]"
/>
</div>
<div class="col-8 row q-col-gutter-sm">
<q-input
:for="`${prefixId}-input-first-name`"
dense
outlined
hide-bottom-space
:readonly="readonly"
:disable="!readonly"
class="col-md-2 col-6"
label="Title"
:model-value="
readonly
? capitalize(prefixName || '') || '-'
: capitalize(prefixName || '')
"
@update:model-value="
(v) => (typeof v === 'string' ? (prefixName = v) : '')
"
@clear="prefixName = ''"
/> />
<q-input <q-input
:for="`${prefixId}-input-first-name`"
dense dense
outlined outlined
:disable="!readonly"
:readonly="readonly" :readonly="readonly"
hide-bottom-space hide-bottom-space
class="col-12 col-md-3" class="col"
:label="$t('customer.form.customerCode')" label="Name"
for="input-customer-code" v-model="firstNameEN"
:model-value="citizenId" :rules="[(val: string) => !!val || $t('form.error.required')]"
/> />
<q-input
:for="`${prefixId}-input-last-name`"
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col"
label="Surname"
v-model="lastNameEN"
:rules="[(val: string) => !!val || $t('form.error.required')]"
/>
</div>
<div class="row col-8 q-col-gutter-sm">
<q-input
:for="`${prefixId}-input-telephone`"
dense
outlined
:readonly="readonly"
class="col-md col-6"
:label="$t('form.telephone')"
:mask="readonly ? '' : '##########'"
:model-value="readonly ? telephoneNo || '-' : telephoneNo"
@update:model-value="
(v) => (typeof v === 'string' ? (telephoneNo = v) : '')
"
@clear="telephoneNo = ''"
>
<template #prepend>
<q-icon
size="xs"
name="mdi-phone-outline"
class="cursor-pointer"
color="primary"
/>
</template>
</q-input>
<q-select
outlined
use-input
fill-input
emit-value
map-options
hide-selected
hide-bottom-space
input-debounce="0"
option-label="label"
option-value="value"
class="col-md-2 col-6"
dense
:readonly="readonly"
:options="genderOptions"
:hide-dropdown-icon="readonly"
:for="`${prefixId}-select-gender`"
:label="$t('form.gender')"
@filter="genderFilter"
:model-value="readonly ? gender || '-' : gender"
@update:model-value="
(v) => (typeof v === 'string' ? (gender = v) : '')
"
@clear="gender = ''"
>
<template v-slot:no-option>
<q-item>
<q-item-section class="text-grey">
{{ $t('general.noData') }}
</q-item-section>
</q-item>
</template>
</q-select>
<DatePicker
v-model="birthDate"
class="col-md col-6"
:id="`${prefixId}-input-birth-date`"
:readonly="readonly"
:label="$t('form.birthDate')"
:disabled-dates="disabledAfterToday"
:rules="[
(val: string) =>
!!val ||
$t('form.error.selectField', { field: $t('form.birthDate') }),
]"
/>
<q-input
:for="`${prefixId}-input-age`"
:id="`${prefixId}-input-age`"
dense
outlined
readonly
:label="$t('personnel.age')"
class="col-md-2 col-12"
:model-value="
birthDate?.toString() === 'Invalid Date' ||
birthDate?.toString() === undefined
? ''
: calculateAge(birthDate)
"
/>
</div>
</template> </template>
</div> </div>
</template> </template>

View file

@ -0,0 +1,35 @@
<script lang="ts" setup>
defineProps<{
readonly?: boolean;
prefixId?: string;
}>();
const authorizedName = defineModel<string>('authorizedName');
const authorizedNameEN = defineModel<string>('authorizedNameEN');
</script>
<template>
<div class="col-md-9 col-12 row q-col-gutter-sm">
<q-input
:for="`${prefixId}-input-contact-name`"
:id="`${prefixId}-input-contact-name`"
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col-md-6 col-12"
:label="$t('customerBranch.tab.authorized')"
v-model="authorizedName"
/>
<q-input
:for="`${prefixId}-input-contact-name`"
:id="`${prefixId}-input-contact-name`"
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col-md-6 col-12"
:label="`${$t('customerBranch.tab.authorized')} (EN)`"
v-model="authorizedNameEN"
/>
</div>
</template>

View file

@ -1,19 +1,10 @@
<script lang="ts" setup> <script lang="ts" setup>
import { ref, watch, capitalize } from 'vue'; import { ref, watch } from 'vue';
import { QSelect } from 'quasar'; import { QSelect } from 'quasar';
import { selectFilterOptionRefMod } from 'stores/utils'; import { selectFilterOptionRefMod } from 'stores/utils';
import { getRole } from 'src/services/keycloak'; import { getRole } from 'src/services/keycloak';
import useOptionStore from 'stores/options'; import useOptionStore from 'stores/options';
import { onMounted } from 'vue'; import { onMounted } from 'vue';
import { useI18n } from 'vue-i18n';
const { locale } = useI18n();
import {
dateFormat,
calculateAge,
parseAndFormatDate,
disabledAfterToday,
} from 'src/utils/datetime';
import { import {
SaveButton, SaveButton,
@ -21,6 +12,7 @@ import {
DeleteButton, DeleteButton,
UndoButton, UndoButton,
} from 'components/button'; } from 'components/button';
withDefaults( withDefaults(
defineProps<{ defineProps<{
prefixId?: string; prefixId?: string;
@ -43,20 +35,20 @@ defineEmits<{
}>(); }>();
const optionStore = useOptionStore(); const optionStore = useOptionStore();
const code = defineModel<string>('code', { required: true });
const namePrefix = defineModel<string | null>('namePrefix');
const birthDate = defineModel<Date | string | null>('birthDate');
const gender = defineModel<string>('gender');
const firstName = defineModel<string>('firstName', { required: true });
const lastName = defineModel<string>('lastName', { required: true });
const firstNameEN = defineModel<string>('firstNameEn', { required: true });
const lastNameEN = defineModel<string>('lastNameEn', { required: true });
const registeredBranchId = defineModel<string>('registeredBranchId', { const registeredBranchId = defineModel<string>('registeredBranchId', {
required: true, required: true,
}); });
const customerName = defineModel<string>('customerName');
const registerName = defineModel<string>('registerName');
const citizenId = defineModel<string>('citizenId');
const legalPersonNo = defineModel<string>('legalPersonNo');
const businessType = defineModel<'strinf'>('businessType');
const jobPosition = defineModel<'strinf'>('jobPosition');
const telephoneNo = defineModel<string>('telephoneNo');
const branchOptions = defineModel<{ id: string; name: string }[]>( const branchOptions = defineModel<{ id: string; name: string }[]>(
'branchOptions', 'branchOptions',
{ default: [] }, { default: [] },
@ -87,69 +79,63 @@ watch(
}, },
); );
const prefixNameOptions = ref<Record<string, unknown>[]>([]); // const prefixNameOptions = ref<Record<string, unknown>[]>([]);
let prefixNameFilter: ( // let prefixNameFilter: (
value: string, // value: string,
update: (callbackFn: () => void, afterFn?: (ref: QSelect) => void) => void, // update: (callbackFn: () => void, afterFn?: (ref: QSelect) => void) => void,
) => void; // ) => void;
const prefixNameEnOptions = ref<Record<string, unknown>[]>([]); // const genderOptions = ref<Record<string, unknown>[]>([]);
let prefixNameEnFilter: ( // let genderFilter: (
value: string, // value: string,
update: (callbackFn: () => void, afterFn?: (ref: QSelect) => void) => void, // update: (callbackFn: () => void, afterFn?: (ref: QSelect) => void) => void,
) => void; // ) => void;
const genderOptions = ref<Record<string, unknown>[]>([]); // onMounted(() => {
let genderFilter: ( // prefixNameFilter = selectFilterOptionRefMod(
value: string, // ref(optionStore.globalOption?.prefix),
update: (callbackFn: () => void, afterFn?: (ref: QSelect) => void) => void, // prefixNameOptions,
) => void; // 'label',
// );
// genderFilter = selectFilterOptionRefMod(
// ref(optionStore.globalOption?.gender),
// genderOptions,
// 'label',
// );
// });
onMounted(() => { // watch(
prefixNameFilter = selectFilterOptionRefMod( // () => optionStore.globalOption,
ref(optionStore.globalOption?.prefix), // () => {
prefixNameOptions, // prefixNameFilter = selectFilterOptionRefMod(
'label', // ref(optionStore.globalOption.prefix),
); // prefixNameOptions,
genderFilter = selectFilterOptionRefMod( // 'label',
ref(optionStore.globalOption?.gender), // );
genderOptions, // genderFilter = selectFilterOptionRefMod(
'label', // ref(optionStore.globalOption.gender),
); // genderOptions,
}); // 'label',
// );
// },
// );
watch( // watch(
() => optionStore.globalOption, // () => namePrefix.value,
() => { // (v) => {
prefixNameFilter = selectFilterOptionRefMod( // if (v === 'mr') gender.value = 'male';
ref(optionStore.globalOption.prefix), // else gender.value = 'female';
prefixNameOptions, // },
'label', // );
);
genderFilter = selectFilterOptionRefMod(
ref(optionStore.globalOption.gender),
genderOptions,
'label',
);
},
);
watch( // function formatCode(input: string | undefined, type: 'code' | 'number') {
() => namePrefix.value, // if (!input) return;
(v) => { // return input.slice(...(type === 'code' ? [0, -6] : [-6]));
if (v === 'mr') gender.value = 'male'; // }
else gender.value = 'female';
},
);
function formatCode(input: string | undefined, type: 'code' | 'number') {
if (!input) return;
return input.slice(...(type === 'code' ? [0, -6] : [-6]));
}
</script> </script>
<template> <template>
<div class="row q-col-gutter-sm q-mb-sm"> <div class="row q-col-gutter-sm">
<div <div
v-if="!hideAction" v-if="!hideAction"
class="col-12 text-weight-bold text-body1 row items-center" class="col-12 text-weight-bold text-body1 row items-center"
@ -162,8 +148,18 @@ function formatCode(input: string | undefined, type: 'code' | 'number') {
name="mdi-office-building-outline" name="mdi-office-building-outline"
style="background-color: var(--surface-3)" style="background-color: var(--surface-3)"
/> />
<span>{{ $t('form.field.basicInformation') }}</span> <span>
<EditButton {{
$t('general.information', {
msg: `${$t('customer.employer')}${
customerType === 'CORP'
? $t('customer.employerLegalEntity')
: $t('customer.employerNaturalPerson')
}`,
})
}}
</span>
<!-- <EditButton
icon-only icon-only
v-if="readonly && !create" v-if="readonly && !create"
type="button" type="button"
@ -193,10 +189,540 @@ function formatCode(input: string | undefined, type: 'code' | 'number') {
@click="$emit('save')" @click="$emit('save')"
type="submit" type="submit"
:disabled="actionDisabled" :disabled="actionDisabled"
/> /> -->
</div> </div>
<div class="col-12 row q-col-gutter-sm"> <div class="col-12 row q-col-gutter-sm">
<div class="col-12 row q-col-gutter-sm">
<q-select
outlined
clearable
use-input
fill-input
emit-value
map-options
hide-selected
hide-bottom-space
dense
class="col-6"
option-value="id"
input-debounce="0"
option-label="name"
v-model="registeredBranchId"
:readonly="readonly"
:options="filteredBranchOptions"
:hide-dropdown-icon="readonly"
:label="$t('customer.form.registeredBranch')"
:for="`${prefixId}-input-source-nationality`"
:rules="[
(val) => {
const roles = getRole() || [];
return (
['admin', 'system', 'head_of_admin'].some((v) =>
roles.includes(v),
) ||
!!val ||
$t('form.error.required')
);
},
]"
@filter="branchFilter"
>
<template v-slot:no-option>
<q-item>
<q-item-section class="text-grey">
{{ $t('general.noData') }}
</q-item-section>
</q-item>
</template>
</q-select>
</div>
<div
v-if="customerType === 'CORP' && !create"
class="row col-12 q-col-gutter-sm"
>
<q-input
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col-12 col-md-6"
:label="$t('customer.form.customerName')"
for="input-first-name"
v-model="registerName"
/>
<q-input
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col-6 col-md-3"
:label="$t('general.taxNo')"
for="input-first-name-en"
v-model="legalPersonNo"
/>
<q-input
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col-6 col-md-3"
:label="$t('customer.table.businessTypePure')"
for="input-first-name-en"
v-model="businessType"
/>
</div>
<div
v-if="customerType === 'PERS' && !create"
class="row col-12 q-col-gutter-sm"
>
<q-input
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col-12 col-md-6"
:label="$t('customer.form.employerName')"
for="input-first-name"
v-model="customerName"
/>
<q-input
outlined
class="col-md-3 col-6"
hide-bottom-space
v-model="citizenId"
mask="#############"
:readonly="readonly"
dense
:label="$t('personnel.form.citizenId')"
for="input-citizen-id"
/>
<q-input
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col-6 col-md-3"
:label="$t('customer.table.businessTypePure')"
for="input-first-name-en"
v-model="businessType"
/>
</div>
<div v-if="!create" class="row col-12 q-col-gutter-sm">
<q-input
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col-6 col-md-5"
:label="$t('customer.form.jobPosition')"
for="input-first-name-en"
v-model="jobPosition"
/>
<q-input
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col-6 col-md-3"
:label="$t('customer.form.headQuarters.telephoneNo')"
for="input-first-name-en"
v-model="telephoneNo"
>
<template #prepend>
<q-icon
size="xs"
name="mdi-phone-outline"
class="cursor-pointer"
color="primary"
/>
</template>
</q-input>
</div>
</div>
<!-- <div v-if="customerType === 'CORP'" class="col-12 row q-col-gutter-sm">
<q-input
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col-12 col-md-6"
:label="$t('customer.form.customerName')"
for="input-first-name"
v-model="customerName"
:rules="[(val: string) => !!val || $t('form.error.required')]"
/>
<q-input
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col-12 col-md-6"
:label="$t('customer.form.customerNameEN')"
for="input-first-name-en"
v-model="customerNameEN"
:rules="[
(val: string) => !!val || $t('form.error.required'),
(val: string) =>
/^[A-Za-z]+$/.test(val) || $t('form.error.letterOnly'),
]"
/>
<q-input
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col-6 col-md-3"
:label="$t('general.taxNo')"
for="input-first-name-en"
v-model="taxNo"
mask="#############"
:rules="[
(val) => (val && val.length > 0) || $t('form.error.required'),
(val) =>
(val && val.length === 13 && /[0-9]+/.test(val)) ||
$t('form.error.invalidCustomeMessage', {
msg: $t('form.error.requireLength', { msg: 13 }),
}),
]"
/>
<q-input
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col-6 col-md-3"
:label="$t('customer.table.businessTypePure')"
for="input-first-name-en"
v-model="businessType"
/>
<q-input
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col-6 col-md-3"
:label="$t('customer.form.jobPosition')"
for="input-first-name-en"
v-model="jobPosition"
/>
<q-input
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col-6 col-md-3"
:label="$t('customer.form.headQuarters.telephoneNo')"
for="input-first-name-en"
v-model="telephoneNo"
>
<template #prepend>
<q-icon
size="xs"
name="mdi-phone-outline"
class="cursor-pointer"
color="primary"
/>
</template>
</q-input>
</div>
<div v-if="customerType === 'PERS'" class="col-12 row q-col-gutter-sm">
<div class="col-9 row q-col-gutter-sm">
<q-select
outlined
clearable
use-input
fill-input
emit-value
map-options
hide-selected
hide-bottom-space
dense
class="col-12"
option-value="id"
input-debounce="0"
option-label="name"
v-model="registeredBranchId"
:readonly="readonly"
:options="filteredBranchOptions"
:hide-dropdown-icon="readonly"
:label="$t('customer.form.registeredBranch')"
:for="`${prefixId}-input-source-nationality`"
:rules="[
(val) => {
const roles = getRole() || [];
return (
['admin', 'system', 'head_of_admin'].some((v) =>
roles.includes(v),
) ||
!!val ||
$t('form.error.required')
);
},
]"
@filter="branchFilter"
>
<template v-slot:no-option>
<q-item>
<q-item-section class="text-grey">
{{ $t('general.noData') }}
</q-item-section>
</q-item>
</template>
</q-select>
<q-select
outlined
use-input
fill-input
emit-value
map-options
hide-selected
hide-bottom-space
input-debounce="0"
option-label="label"
option-value="value"
hide-dropdown-icon
class="col-12 col-md-2"
dense
:readonly="readonly"
:options="prefixNameOptions"
:for="`${prefixId}-select-prefix-name`"
:label="$t('form.prefixName')"
@filter="prefixNameFilter"
:model-value="readonly ? namePrefix || '-' : namePrefix"
@update:model-value="
(v) => {
typeof v === 'string' ? (namePrefix = v) : '';
}
"
@clear="namePrefix = ''"
:rules="[
(val) => {
const roles = getRole() || [];
return !!val || $t('form.error.required');
},
]"
>
<template v-slot:no-option>
<q-item>
<q-item-section class="text-grey">
{{ $t('general.noData') }}
</q-item-section>
</q-item>
</template>
</q-select>
<q-input
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col-12 col-md-5"
:label="$t('customer.form.firstName')"
for="input-first-name"
v-model="firstName"
:rules="[
(val) => {
const roles = getRole() || [];
return !!val || $t('form.error.required');
},
]"
/>
<q-input
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col-12 col-md-5"
:label="$t('customer.form.lastName')"
for="input-last-name"
v-model="lastName"
:rules="[
(val) => {
const roles = getRole() || [];
return !!val || $t('form.error.required');
},
]"
/>
<q-input
dense
outlined
:disable="!readonly"
readonly
hide-bottom-space
class="col-12 col-md-2"
label="Title"
for="input-prefix-name-en"
:model-value="
readonly
? capitalize(namePrefix || '') || '-'
: capitalize(namePrefix || '')
"
/>
<q-input
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col-12 col-md-5"
label="Name"
for="input-first-name-en"
v-model="firstNameEN"
:rules="[
(val: string) => !!val || $t('form.error.required'),
(val: string) =>
/^[A-Za-z]+$/.test(val) || $t('form.error.letterOnly'),
]"
/>
<q-input
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col-12 col-md-5"
label="Surname"
for="input-last-name-en"
v-model="lastNameEN"
:rules="[
(val: string) => !!val || $t('form.error.required'),
(val: string) =>
/^[A-Za-z]+$/.test(val) || $t('form.error.letterOnly'),
]"
/>
<q-input
outlined
class="col-md-5 col-12"
hide-bottom-space
v-model="lastNameEN"
mask="#############"
:readonly="readonly"
dense
:label="$t('personnel.form.citizenId')"
:rules="[
(val) => (val && val.length > 0) || $t('form.error.required'),
(val) =>
(val && val.length === 13 && /[0-9]+/.test(val)) ||
$t('form.error.invalidCustomeMessage', {
msg: $t('form.error.requireLength', { msg: 13 }),
}),
]"
for="input-citizen-id"
/>
<q-select
outlined
use-input
fill-input
emit-value
map-options
hide-selected
hide-bottom-space
input-debounce="0"
option-label="label"
option-value="value"
class="col-md-2 col-6"
dense
:readonly="readonly"
:options="genderOptions"
:hide-dropdown-icon="readonly"
:for="`${prefixId}-select-gender`"
:label="$t('form.gender')"
@filter="genderFilter"
:model-value="readonly ? gender || '-' : gender"
@update:model-value="
(v) => (typeof v === 'string' ? (gender = v) : '')
"
@clear="gender = ''"
>
<template v-slot:no-option>
<q-item>
<q-item-section class="text-grey">
{{ $t('general.noData') }}
</q-item-section>
</q-item>
</template>
</q-select>
<DatePicker
v-model="birthDate"
class="col-md col-6"
:id="`${prefixId}-input-birth-date`"
:readonly="readonly"
:label="$t('form.birthDate')"
:disabled-dates="disabledAfterToday"
:rules="[
(val: string) =>
!!val ||
$t('form.error.selectField', { field: $t('form.birthDate') }),
]"
/>
<q-input
:for="`${prefixId}-input-age`"
:id="`${prefixId}-input-age`"
dense
outlined
:label="$t('personnel.age')"
class="col-md col-12"
:model-value="
birthDate?.toString() === 'Invalid Date' ||
birthDate?.toString() === undefined
? ''
: calculateAge(birthDate)
"
/>
</div>
<div class="row col-12 q-col-gutter-sm">
<q-input
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col-6 col-md"
:label="$t('customer.table.businessTypePure')"
for="input-first-name-en"
v-model="firstNameEN"
/>
<q-input
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col-6 col-md"
:label="$t('customer.form.jobPosition')"
for="input-first-name-en"
v-model="firstNameEN"
/>
<q-input
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col-6 col-md-3"
:label="$t('customer.form.headQuarters.telephoneNo')"
for="input-first-name-en"
v-model="firstNameEN"
>
<template #prepend>
<q-icon
size="xs"
name="mdi-phone-outline"
class="cursor-pointer"
color="primary"
/>
</template>
</q-input>
</div>
</div> -->
<!-- <div class="col-12 row q-col-gutter-sm">
<q-select <q-select
outlined outlined
clearable clearable
@ -482,6 +1008,6 @@ function formatCode(input: string | undefined, type: 'code' | 'number') {
: calculateAge(birthDate) : calculateAge(birthDate)
" "
/> />
</div> </div> -->
</div> </div>
</template> </template>

View file

@ -5,6 +5,7 @@ import EmployerFormBusiness from './EmployerFormBusiness.vue';
import EmployerFormContact from './EmployerFormContact.vue'; import EmployerFormContact from './EmployerFormContact.vue';
import { CustomerCreate } from 'stores/customer/types'; import { CustomerCreate } from 'stores/customer/types';
import EmployerFormAbout from './EmployerFormAbout.vue'; import EmployerFormAbout from './EmployerFormAbout.vue';
import EmployerFormAuthorized from './EmployerFormAuthorized.vue';
import { useCustomerForm } from 'src/pages/03_customer-management/form'; import { useCustomerForm } from 'src/pages/03_customer-management/form';
const customerFormStore = useCustomerForm(); const customerFormStore = useCustomerForm();
@ -68,7 +69,7 @@ withDefaults(
? $t('customer.form.headQuarters.title') ? $t('customer.form.headQuarters.title')
: $t('customer.form.branch.title', { name: index || 0 }) : $t('customer.form.branch.title', { name: index || 0 })
}} }}
<EditButton <!-- <EditButton
icon-only icon-only
v-if="readonly" v-if="readonly"
@click="$emit('edit')" @click="$emit('edit')"
@ -90,11 +91,12 @@ withDefaults(
type="button" type="button"
class="q-ml-auto" class="q-ml-auto"
:disabled="actionDisabled" :disabled="actionDisabled"
/> /> -->
<!-- v-if="!readonly" -->
<SaveButton <SaveButton
icon-only icon-only
v-if="!readonly"
@click="$emit('save')" @click="$emit('save')"
class="q-ml-auto"
type="submit" type="submit"
:disabled="actionDisabled" :disabled="actionDisabled"
/> />
@ -109,10 +111,16 @@ withDefaults(
class="bordered-b" class="bordered-b"
active-color="primary" active-color="primary"
no-caps no-caps
style="color: hsl(var(--text-mute))"
> >
<q-tab name="main" :label="$t('customerBranch.tab.main')" /> <q-tab name="main" :label="$t('customerBranch.tab.main')" />
<q-tab name="address" :label="$t('customerBranch.tab.address')" />
<q-tab name="business" :label="$t('customerBranch.tab.business')" /> <q-tab name="business" :label="$t('customerBranch.tab.business')" />
<q-tab
v-if="customerType === 'CORP'"
name="authorized"
:label="$t('customerBranch.tab.authorized')"
/>
<q-tab name="address" :label="$t('customerBranch.tab.address')" />
<q-tab name="contact" :label="$t('customerBranch.tab.contact')" /> <q-tab name="contact" :label="$t('customerBranch.tab.contact')" />
<q-tab name="attachment" :label="$t('customerBranch.tab.attachment')" /> <q-tab name="attachment" :label="$t('customerBranch.tab.attachment')" />
</q-tabs> </q-tabs>
@ -122,37 +130,23 @@ withDefaults(
:index="index.toString()" :index="index.toString()"
:readonly="readonly" :readonly="readonly"
:customer-type="customerType" :customer-type="customerType"
:customer-name="customerName"
v-model:citizen-id="item.citizenId" v-model:citizen-id="item.citizenId"
v-model:id="item.id" v-model:prefixName="item.namePrefix"
v-model:legal-person-no="item.legalPersonNo" v-model:firstName="item.firstName"
v-model:branch-code="item.code" v-model:lastName="item.lastName"
v-model:customer-code="customer.code" v-model:firstNameEN="item.firstNameEN"
v-model:register-company-name="item.registerCompanyName" v-model:lastNameEN="item.lastNameEN"
v-model:register-name="item.registerName" v-model:gender="item.gender"
v-model:register-name-en="item.registerNameEN" v-model:birthDate="item.birthDate"
v-model:register-date="item.registerDate" v-model:customerName="item.customerName"
v-model:authorized-capital="item.authorizedCapital" v-model:legalPersonNo="item.legalPersonNo"
/> v-model:branchCode="item.branchCode"
</q-tab-panel> v-model:registerName="item.registerName"
<q-tab-panel name="address"> v-model:registerNameEN="item.registerNameEN"
<AddressForm v-model:registerDate="item.registerDate"
use-work-place v-model:authorizedCapital="item.authorizedCapital"
:prefix-id="prefixId || 'employer'" v-model:telephoneNo="item.telephoneNo"
hide-title v-model:customerCode="item.customerCode"
dense
:readonly="readonly"
outlined
:title="$t('form.address')"
v-model:workplace="item.workplace"
v-model:workplace-en="item.workplaceEN"
v-model:address="item.address"
v-model:addressEN="item.addressEN"
v-model:province-id="item.provinceId"
v-model:district-id="item.districtId"
v-model:sub-district-id="item.subDistrictId"
:addressTitle="$t('form.address')"
:addressTitleEN="$t('form.address', { suffix: '(EN)' })"
/> />
</q-tab-panel> </q-tab-panel>
<q-tab-panel name="business"> <q-tab-panel name="business">
@ -161,15 +155,48 @@ withDefaults(
outlined outlined
:prefix-id="prefixId || 'employer'" :prefix-id="prefixId || 'employer'"
:readonly="readonly" :readonly="readonly"
v-model:employment-office="item.employmentOffice"
v-model:bussiness-type="item.businessType" v-model:bussiness-type="item.businessType"
v-model:bussiness-type-en="item.businessTypeEN"
v-model:job-position="item.jobPosition" v-model:job-position="item.jobPosition"
v-model:job-position-en="item.jobPositionEN"
v-model:job-description="item.jobDescription" v-model:job-description="item.jobDescription"
v-model:sale-employee="item.saleEmployee"
v-model:pay-date="item.payDate" v-model:pay-date="item.payDate"
v-model:pay-date-e-n="item.payDateEN"
v-model:wage-rate="item.wageRate" v-model:wage-rate="item.wageRate"
v-model:wage-rate-text="item.wageRateText"
/>
</q-tab-panel>
<q-tab-panel v-if="customerType === 'CORP'" name="authorized">
<EmployerFormAuthorized
:prefix-id="prefixId || 'employer'"
:readonly="readonly"
v-model:authorized-name="item.authorizedName"
v-model:authorized-name-e-n="item.authorizedNameEN"
/>
</q-tab-panel>
<q-tab-panel name="address">
<AddressForm
:prefix-id="prefixId || 'employer'"
hide-title
dense
outlined
use-employment
:readonly="readonly"
:title="$t('form.address')"
v-model:homeCode="item.homeCode"
v-model:employmentOffice="item.employmentOffice"
v-model:employmentOfficeEN="item.employmentOfficeEN"
v-model:address="item.address"
v-model:addressEN="item.addressEN"
v-model:street="item.street"
v-model:streetEN="item.streetEN"
v-model:moo="item.moo"
v-model:mooEN="item.mooEN"
v-model:soi="item.soi"
v-model:soiEN="item.soiEN"
v-model:province-id="item.provinceId"
v-model:district-id="item.districtId"
v-model:sub-district-id="item.subDistrictId"
:addressTitle="$t('form.address')"
:addressTitleEN="$t('form.address', { suffix: '(EN)' })"
/> />
</q-tab-panel> </q-tab-panel>
<q-tab-panel name="contact"> <q-tab-panel name="contact">
@ -177,7 +204,9 @@ withDefaults(
:readonly="readonly" :readonly="readonly"
v-model:contactName="item.contactName" v-model:contactName="item.contactName"
v-model:email="item.email" v-model:email="item.email"
v-model:telephone="item.telephoneNo" v-model:contactTel="item.contactTel"
v-model:officeTel="item.officeTel"
v-model:agent="item.agent"
/> />
</q-tab-panel> </q-tab-panel>
<q-tab-panel name="attachment"> <q-tab-panel name="attachment">

View file

@ -1,31 +1,25 @@
<script setup lang="ts"> <script setup lang="ts">
import { selectFilterOptionRefMod } from 'stores/utils'; import { selectFilterOptionRefMod } from 'stores/utils';
import { dateFormat, parseAndFormatDate } from 'src/utils/datetime';
import { onMounted, watch } from 'vue'; import { onMounted, watch } from 'vue';
import { ref } from 'vue'; import { ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import DatePicker from 'src/components/shared/DatePicker.vue';
const { locale } = useI18n({ useScope: 'global' }); const { locale } = useI18n({ useScope: 'global' });
const employmentOffice = defineModel<string>('employmentOffice');
const bussinessType = defineModel<string>('bussinessType');
const jobPosition = defineModel<string>('jobPosition');
const bussinessTypeEN = defineModel<string>('bussinessTypeEn');
const jobPositionEN = defineModel<string>('jobPositionEn');
const jobDescription = defineModel<string>('jobDescription');
const payDate = defineModel<Date | null | string>('payDate');
const wageRate = defineModel<number>('wageRate');
const saleEmployee = defineModel<string>('saleEmployee');
const rawOption = ref(); const rawOption = ref();
const bussinessType = defineModel<string>('bussinessType');
const jobPosition = defineModel<string>('jobPosition');
const jobDescription = defineModel<string>('jobDescription');
const payDate = defineModel<string>('payDate');
const payDateEN = defineModel<string>('payDateEN');
const wageRate = defineModel<number>('wageRate');
const wageRateText = defineModel<string>('wageRateText');
const typeBusinessOption = ref([]); const typeBusinessOption = ref([]);
const typeBusinessENOption = ref([]);
const jobPositionOption = ref([]); const jobPositionOption = ref([]);
const jobPositionENOption = ref([]);
defineProps<{ defineProps<{
title?: string; title?: string;
@ -38,6 +32,8 @@ defineProps<{
onMounted(async () => { onMounted(async () => {
const resultOption = await fetch('/option/option.json'); const resultOption = await fetch('/option/option.json');
rawOption.value = await resultOption.json(); rawOption.value = await resultOption.json();
typeBusinessENOption.value = rawOption.value.eng.businessType;
jobPositionENOption.value = rawOption.value.eng.position;
if (locale.value === 'eng') { if (locale.value === 'eng') {
typeBusinessOption.value = rawOption.value.eng.businessType; typeBusinessOption.value = rawOption.value.eng.businessType;
@ -48,20 +44,31 @@ onMounted(async () => {
jobPositionOption.value = rawOption.value.tha.position; jobPositionOption.value = rawOption.value.tha.position;
} }
}); });
watch(typeBusinessOption, () => {
watch([typeBusinessOption, typeBusinessENOption], () => {
typeBusinessFilter = selectFilterOptionRefMod( typeBusinessFilter = selectFilterOptionRefMod(
typeBusinessOption, typeBusinessOption,
typeBusinessOptions, typeBusinessOptions,
'label', 'label',
); );
typeBusinessENFilter = selectFilterOptionRefMod(
typeBusinessENOption,
typeBusinessENOptions,
'label',
);
}); });
watch(jobPositionOption, () => { watch([jobPositionOption, jobPositionENOption], () => {
jobPositionFilter = selectFilterOptionRefMod( jobPositionFilter = selectFilterOptionRefMod(
jobPositionOption, jobPositionOption,
jobPositionOptions, jobPositionOptions,
'label', 'label',
); );
jobPositionENFilter = selectFilterOptionRefMod(
jobPositionENOption,
jobPositionENOptions,
'label',
);
}); });
const typeBusinessOptions = ref<Record<string, unknown>[]>([]); const typeBusinessOptions = ref<Record<string, unknown>[]>([]);
@ -77,21 +84,23 @@ let jobPositionFilter = selectFilterOptionRefMod(
jobPositionOptions, jobPositionOptions,
'label', 'label',
); );
const typeBusinessENOptions = ref<Record<string, unknown>[]>([]);
let typeBusinessENFilter = selectFilterOptionRefMod(
typeBusinessENOption,
typeBusinessENOptions,
'label',
);
const jobPositionENOptions = ref<Record<string, unknown>[]>([]);
let jobPositionENFilter = selectFilterOptionRefMod(
jobPositionENOption,
jobPositionENOptions,
'label',
);
</script> </script>
<template> <template>
<div class="col-12 row q-col-gutter-sm"> <div class="col-12 row q-col-gutter-sm">
<q-input
:for="`${prefixId}-input-employment-office`"
:id="`${prefixId}-input-employment-office`"
:dense="dense"
outlined
:readonly="readonly"
hide-bottom-space
class="col-12"
:label="$t('form.address')"
v-model="employmentOffice"
/>
<q-select <q-select
outlined outlined
clearable clearable
@ -121,18 +130,36 @@ let jobPositionFilter = selectFilterOptionRefMod(
</q-item> </q-item>
</template> </template>
</q-select> </q-select>
<q-select
<q-input
:for="`${prefixId}-input-bussiness-type-en`" :for="`${prefixId}-input-bussiness-type-en`"
:id="`${prefixId}-input-bussiness-type-en`" :id="`${prefixId}-input-bussiness-type-en`"
:dense="dense" :label="`${$t('customer.form.businessType')} (EN)`"
outlined outlined
:readonly="readonly" clearable
use-input
fill-input
emit-value
map-options
hide-selected
hide-bottom-space hide-bottom-space
input-debounce="0"
option-value="value"
option-label="label"
v-model="bussinessType"
class="col-md-6 col-12" class="col-md-6 col-12"
:label="$t('customer.form.businessTypeEN')" :dense="dense"
v-model="bussinessTypeEN" :readonly="readonly"
/> :options="typeBusinessENOptions"
@filter="typeBusinessENFilter"
>
<template v-slot:no-option>
<q-item>
<q-item-section class="text-grey">
{{ $t('general.noData') }}
</q-item-section>
</q-item>
</template>
</q-select>
<q-select <q-select
outlined outlined
@ -164,19 +191,36 @@ let jobPositionFilter = selectFilterOptionRefMod(
</template> </template>
</q-select> </q-select>
<q-input <q-select
outlined
clearable
use-input
fill-input
emit-value
map-options
hide-selected
hide-bottom-space
input-debounce="0"
option-value="value"
option-label="label"
v-model="jobPosition"
class="col-md-6 col-12"
:dense="dense"
:readonly="readonly"
:label="`${$t('customer.form.jobPosition')} (EN)`"
:options="jobPositionENOptions"
:for="`${prefixId}-input-job-position-en`" :for="`${prefixId}-input-job-position-en`"
:id="`${prefixId}-input-job-position-en`" :id="`${prefixId}-input-job-position-en`"
:dense="dense" @filter="jobPositionENFilter"
outlined >
:readonly="readonly" <template v-slot:no-option>
hide-bottom-space <q-item>
class="col-md-6 col-12" <q-item-section class="text-grey">
:label="$t('customer.form.jobPositionEN')" {{ $t('general.noData') }}
v-model="jobPositionEN" </q-item-section>
:rules="[(val) => /^[A-Za-z]+$/.test(val)]" </q-item>
:error-message="$t('form.error.letterOnly')" </template>
/> </q-select>
<q-input <q-input
:for="`${prefixId}-input-job-description`" :for="`${prefixId}-input-job-description`"
@ -190,12 +234,28 @@ let jobPositionFilter = selectFilterOptionRefMod(
v-model="jobDescription" v-model="jobDescription"
/> />
<DatePicker <q-input
:id="`${prefixId}-date-picker-pay-date`" :for="`${prefixId}-input-pay-rate`"
v-model="payDate" :id="`${prefixId}-input-pay-rate`"
:label="$t('customer.form.payDay')" :dense="dense"
outlined
:readonly="readonly" :readonly="readonly"
clearable hide-bottom-space
class="col-md-3 col-6"
:label="$t('customer.form.payDay')"
v-model="payDate"
/>
<q-input
:for="`${prefixId}-input-pay-rate`"
:id="`${prefixId}-input-pay-rate`"
:dense="dense"
outlined
:readonly="readonly"
hide-bottom-space
class="col-md-3 col-6"
label="Pay day"
v-model="payDateEN"
/> />
<q-input <q-input
@ -211,15 +271,15 @@ let jobPositionFilter = selectFilterOptionRefMod(
/> />
<q-input <q-input
:for="`${prefixId}-input-sales-person`" :for="`${prefixId}-input-pay-rate`"
:id="`${prefixId}-input-sales-person`" :id="`${prefixId}-input-pay-rate`"
:dense="dense" :dense="dense"
outlined outlined
:readonly="readonly" :readonly="readonly"
hide-bottom-space hide-bottom-space
class="col-6" class="col-md-3 col-6"
:label="$t('customer.form.salesPerson')" :label="`${$t('customer.form.payRate')} (Text)`"
v-model="saleEmployee" v-model="wageRateText"
/> />
</div> </div>
</template> </template>

View file

@ -4,12 +4,14 @@ defineProps<{
prefixId?: string; prefixId?: string;
}>(); }>();
const contactName = defineModel<string>('contactName'); const contactName = defineModel<string>('contactName');
const mail = defineModel<string>('email'); const email = defineModel<string>('email');
const telephone = defineModel<string>('telephone'); const contactTel = defineModel<string>('contactTel');
const officeTel = defineModel<string>('officeTel');
const agent = defineModel<string>('agent');
</script> </script>
<template> <template>
<div class="col-md-9 col-12 row q-col-gutter-md"> <div class="col-md-9 col-12 row q-col-gutter-sm">
<q-input <q-input
:for="`${prefixId}-input-contact-name`" :for="`${prefixId}-input-contact-name`"
:id="`${prefixId}-input-contact-name`" :id="`${prefixId}-input-contact-name`"
@ -41,8 +43,17 @@ const telephone = defineModel<string>('telephone');
$t('form.error.invalid'), $t('form.error.invalid'),
] ]
" "
v-model="mail" v-model="email"
>
<template #prepend>
<q-icon
size="xs"
name="mdi-email-outline"
class="cursor-pointer"
color="primary"
/> />
</template>
</q-input>
<q-input <q-input
:for="`${prefixId}-input-telephone`" :for="`${prefixId}-input-telephone`"
:id="`${prefixId}-input-telephone`" :id="`${prefixId}-input-telephone`"
@ -52,7 +63,49 @@ const telephone = defineModel<string>('telephone');
hide-bottom-space hide-bottom-space
class="col-md-6 col-12" class="col-md-6 col-12"
:label="$t('form.telephone')" :label="$t('form.telephone')"
v-model="telephone" v-model="contactTel"
>
<template #prepend>
<q-icon
size="xs"
name="mdi-phone-outline"
class="cursor-pointer"
color="primary"
/>
</template>
</q-input>
<q-input
:for="`${prefixId}-input-telephone`"
:id="`${prefixId}-input-telephone`"
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col-md-6 col-12"
:label="$t('customer.form.headQuarters.telephoneNo')"
v-model="officeTel"
>
<template #prepend>
<q-icon
size="xs"
name="mdi-phone-outline"
class="cursor-pointer"
color="primary"
/>
</template>
</q-input>
<q-input
:for="`${prefixId}-input-telephone`"
:id="`${prefixId}-input-telephone`"
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col-md-6 col-12"
:label="$t('customer.form.agent')"
v-model="agent"
/> />
</div> </div>
</template> </template>

View file

@ -18,20 +18,20 @@ export const useCustomerForm = defineStore('form-customer', () => {
const branchStore = useMyBranch(); const branchStore = useMyBranch();
const defaultFormData: CustomerCreate = { const defaultFormData: CustomerCreate = {
code: '', // code: '',
// namePrefix: '',
// firstName: '',
// lastName: '',
// firstNameEN: '',
// lastNameEN: '',
// gender: '',
// birthDate: new Date(),
customerBranch: [],
selectedImage: '',
status: 'CREATED', status: 'CREATED',
customerType: 'CORP', customerType: 'CORP',
namePrefix: '',
firstName: '',
lastName: '',
firstNameEN: '',
lastNameEN: '',
gender: '',
birthDate: new Date(),
registeredBranchId: branchStore.currentMyBranch?.id || '', registeredBranchId: branchStore.currentMyBranch?.id || '',
customerBranch: [],
image: null, image: null,
selectedImage: '',
}; };
let resetFormData = structuredClone(defaultFormData); let resetFormData = structuredClone(defaultFormData);
@ -138,9 +138,9 @@ export const useCustomerForm = defineStore('form-customer', () => {
state.value.defaultCustomerImageUrl = `${baseUrl}/customer/${id}/image/${data.selectedImage}`; state.value.defaultCustomerImageUrl = `${baseUrl}/customer/${id}/image/${data.selectedImage}`;
resetFormData.registeredBranchId = data.registeredBranchId; resetFormData.registeredBranchId = data.registeredBranchId;
resetFormData.code = data.code || '';
resetFormData.status = data.status; resetFormData.status = data.status;
resetFormData.customerType = data.customerType; resetFormData.customerType = data.customerType;
resetFormData.code = data.code || '';
resetFormData.namePrefix = data.namePrefix; resetFormData.namePrefix = data.namePrefix;
resetFormData.firstName = data.firstName; resetFormData.firstName = data.firstName;
resetFormData.lastName = data.lastName; resetFormData.lastName = data.lastName;
@ -160,7 +160,8 @@ export const useCustomerForm = defineStore('form-customer', () => {
districtId: v.districtId, districtId: v.districtId,
subDistrictId: v.subDistrictId, subDistrictId: v.subDistrictId,
wageRate: v.wageRate, wageRate: v.wageRate,
payDate: new Date(v.payDate), // Convert the string to a Date object payDate: v.payDate, // Convert the string to a Date object
payDateEN: v.payDateEN,
saleEmployee: v.saleEmployee, saleEmployee: v.saleEmployee,
jobDescription: v.jobDescription, jobDescription: v.jobDescription,
jobPositionEN: v.jobPositionEN, jobPositionEN: v.jobPositionEN,
@ -208,57 +209,77 @@ export const useCustomerForm = defineStore('form-customer', () => {
currentFormData.value = structuredClone(resetFormData); currentFormData.value = structuredClone(resetFormData);
} }
function addCurrentCustomerBranch() { async function addCurrentCustomerBranch() {
if (currentFormData.value.customerBranch?.some((v) => !v.id)) return; if (currentFormData.value.customerBranch?.some((v) => !v.id)) return;
currentFormData.value.customerBranch?.push({ currentFormData.value.customerBranch?.push({
id: '', 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: '', customerId: '',
citizenId: branchCode:
currentFormData.value.customerBranch.length !== 0 currentFormData.value.customerBranch.length !== 0
? currentFormData.value.customerBranch?.[0].citizenId === null ? currentFormData.value.customerBranch?.[0].branchCode === null
? '' ? ''
: currentFormData.value.customerBranch?.[0].citizenId : currentFormData.value.customerBranch?.[0].branchCode
: '', : '',
authorizedCapital: '', customerCode: '',
registerDate: new Date(), // Convert the string to a Date object
registerNameEN: '',
registerName: '',
legalPersonNo: legalPersonNo:
currentFormData.value.customerBranch.length !== 0 currentFormData.value.customerBranch.length !== 0
? currentFormData.value.customerBranch?.[0].legalPersonNo === null ? currentFormData.value.customerBranch?.[0].legalPersonNo === null
? '' ? ''
: currentFormData.value.customerBranch?.[0].legalPersonNo : currentFormData.value.customerBranch?.[0].legalPersonNo
: '', : '',
registerCompanyName: '', citizenId:
currentFormData.value.customerBranch.length !== 0
? currentFormData.value.customerBranch?.[0].citizenId === null
? ''
: currentFormData.value.customerBranch?.[0].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: '',
districtId: '',
subDistrictId: '',
contactName: '', contactName: '',
email: '',
contactTel: '',
officeTel: '',
agent: '',
status: 'CREATED',
customerName: '',
registerName: '',
registerNameEN: '',
registerDate: null,
authorizedCapital: '',
authorizedName: '',
authorizedNameEN: '',
file: [], file: [],
}); });
state.value.branchIndex = state.value.branchIndex =
@ -329,7 +350,8 @@ export const useCustomerBranchForm = defineStore('form-customer-branch', () => {
districtId: '', districtId: '',
subDistrictId: '', subDistrictId: '',
wageRate: 0, wageRate: 0,
payDate: new Date(), // Convert the string to a Date object payDate: '',
payDateEN: '',
saleEmployee: '', saleEmployee: '',
jobDescription: '', jobDescription: '',
jobPositionEN: '', jobPositionEN: '',
@ -395,7 +417,8 @@ export const useCustomerBranchForm = defineStore('form-customer-branch', () => {
districtId: _data.districtId, districtId: _data.districtId,
subDistrictId: _data.subDistrictId, subDistrictId: _data.subDistrictId,
wageRate: _data.wageRate, wageRate: _data.wageRate,
payDate: new Date(_data.payDate), // Convert the string to a Date object payDate: _data.payDate, // Convert the string to a Date object
payDateEN: _data.payDateEN,
saleEmployee: _data.saleEmployee, saleEmployee: _data.saleEmployee,
jobDescription: _data.jobDescription, jobDescription: _data.jobDescription,
jobPositionEN: _data.jobPositionEN, jobPositionEN: _data.jobPositionEN,

View file

@ -333,15 +333,24 @@ const useCustomerStore = defineStore('api-customer', () => {
transactionId?: string; transactionId?: string;
}, },
) { ) {
const { code, customerBranch, image, ...payload } = data; if (data.customerBranch) {
if (data.customerBranch[0].citizenId) {
console.log('1');
delete data.customerBranch[0]['authorizedNameEN'];
delete data.customerBranch[0]['authorizedName'];
delete data.customerBranch[0]['authorizedCapital'];
delete data.customerBranch[0]['registerDate'];
delete data.customerBranch[0]['registerNameEN'];
delete data.customerBranch[0]['registerName'];
delete data.customerBranch[0]['legalPersonNo'];
} else {
delete data.customerBranch[0]['citizenId'];
}
if (!data.customerBranch[0].birthDate)
delete data.customerBranch[0]['birthDate'];
}
// const attachment = payload.customerBranch?.map((v) => v.file); const { customerBranch, image, ...payload } = data;
// if (payload.customerBranch?.length) {
// for (let i = 0; i < payload.customerBranch?.length; i++) {
// delete payload.customerBranch[i].file;
// }
// }
const res = await api.post< const res = await api.post<
Customer & { Customer & {
@ -351,7 +360,18 @@ const useCustomerStore = defineStore('api-customer', () => {
} }
>( >(
'/customer', '/customer',
{ ...payload, selectedImage: imgList.selectedImage }, {
...payload,
branch: data.customerBranch?.map((v) => ({
...v,
file: undefined,
branchCode: undefined,
id: undefined,
customerId: undefined,
customerCode: undefined,
})),
selectedImage: imgList.selectedImage,
},
{ {
headers: { headers: {
'X-Session-Id': flow?.sessionId, 'X-Session-Id': flow?.sessionId,
@ -361,21 +381,6 @@ const useCustomerStore = defineStore('api-customer', () => {
}, },
); );
// await Promise.allSettled([
// ...res.data.branch.map(async (v, i) => {
// const fileList = attachment?.[i];
// if (fileList)
// return await addBranchAttachment(v.id, { file: fileList });
// }),
// image &&
// (await api
// .put(`/customer/${res.data.id}/image`, image, {
// headers: { 'Content-Type': image?.type },
// onUploadProgress: (e) => console.log(e),
// })
// .catch((e) => console.error(e)));
// ]);
if (imgList.list.length > 0 && res.data.id) { if (imgList.list.length > 0 && res.data.id) {
for (let index = 0; index < imgList.list.length; index++) { for (let index = 0; index < imgList.list.length; index++) {
const imgFile = imgList.list[index].imgFile; const imgFile = imgList.list[index].imgFile;

View file

@ -34,20 +34,16 @@ export type CustomerBranch = {
contactName: string; contactName: string;
wageRate: number; wageRate: number;
payDate: string; payDate: string;
saleEmployee: string; payDateEN: string;
jobDescription: string; jobDescription: string;
jobPositionEN: string;
jobPosition: string; jobPosition: string;
businessTypeEN: string;
businessType: string; businessType: string;
employmentOffice: string; employmentOffice: string;
workplaceEN: string;
workplace: string;
authorizedCapital: string; authorizedCapital: string;
registerDate: string; registerDate: Date | null;
registerNameEN: string; registerNameEN: string;
registerName: string; registerName: string;
legalPersonNo: string; legalPersonNo?: string;
citizenId: string; citizenId: string;
updatedByUserId: string; updatedByUserId: string;
createdByUserId: string; createdByUserId: string;
@ -76,101 +72,81 @@ export type CustomerBranch = {
}; };
export type CustomerBranchCreate = { export type CustomerBranchCreate = {
code?: string; customerId: string;
customerCode?: string; legalPersonNo?: string;
citizenId?: string;
contactName: string; namePrefix?: string;
firstName?: string;
lastName?: string;
firstNameEN?: string;
lastNameEN?: string;
telephoneNo?: string;
gender?: string;
birthDate?: string;
businessType: string;
jobPosition: string;
jobDescription: string;
payDate?: string;
payDateEN?: string;
wageRate: number;
wageRateText: string;
homeCode: string;
employmentOffice: string;
employmentOfficeEN?: string;
address: string;
addressEN?: string;
street: string;
streetEN?: string;
moo?: string;
mooEN?: string;
soi?: string;
soiEN?: string;
provinceId: string; provinceId: string;
districtId: string; districtId: string;
subDistrictId: string; subDistrictId: string;
wageRate: number; contactName: string;
payDate: Date | null;
saleEmployee: string;
jobDescription: string;
jobPositionEN: string;
jobPosition: string;
businessTypeEN: string;
businessType: string;
employmentOffice: string;
telephoneNo: string;
email: string; email: string;
addressEN: string; contactTel?: string;
address: string; officeTel?: string;
workplaceEN: string; agent?: string;
workplace: string; status: Status;
status: Status | undefined; customerName?: string;
customerId: string;
citizenId?: string;
authorizedCapital?: string;
registerDate?: Date | null;
registerNameEN?: string;
registerName?: string; registerName?: string;
legalPersonNo?: string; registerNameEN?: string;
registerCompanyName: string; registerDate?: Date | null;
authorizedCapital?: string;
statusSave?: boolean; authorizedName?: string;
authorizedNameEN?: string;
file?: { file?: {
name?: string; name?: string;
group?: string; group?: string;
url?: string; url?: string;
file?: File; file?: File;
}[]; }[];
// id?: string;
// code?: string;
// provinceId?: string | null;
// branchNo?: number;
// address: string;
// addressEN: string;
// districtId?: string | null;
// subDistrictId?: string | null;
// zipCode: string;
// email: string;
// telephoneNo: string;
// status?: Status;
// name: string;
// taxNo?: string | null;
// nameEN: string;
// legalPersonNo: string;
// registerName: string;
// registerDate: Date | null;
// authorizedCapital: string;
// employmentOffice: string;
// bussinessType: string;
// bussinessTypeEN: string;
// jobPosition: string;
// jobPositionEN: string;
// jobDescription: string;
// saleEmployee: string;
// payDate: Date;
// wageRate: number;
// file?: File[];
// statusSave?: boolean;
}; };
export type CustomerCreate = { export type CustomerCreate = {
customerBranch?: (CustomerBranchCreate & {
id?: string;
branchCode?: string;
customerCode?: string;
})[];
selectedImage?: string; selectedImage?: string;
code: string;
customerBranch?: (CustomerBranchCreate & { id?: string })[];
customerType: CustomerType;
status?: Status; status?: Status;
image: File | null; customerType: CustomerType;
registeredBranchId: string; registeredBranchId: string;
namePrefix: string; image: File | null;
firstName: string;
lastName: string;
firstNameEN: string;
lastNameEN: string;
gender: string;
birthDate: Date;
}; };
export type CustomerUpdate = { export type CustomerUpdate = {
selectedImage?: string; selectedImage?: string;
status?: Status; status?: Status;
customerType?: CustomerType; customerType?: CustomerType;
customerBranch?: (CustomerBranchCreate & { id?: string })[]; customerBranch?: (CustomerBranchCreate & {
id?: string;
branchCode?: string;
customerCode?: string;
})[];
image?: File; image?: File;
registeredBranchId: string; registeredBranchId: string;