feat: save branch

This commit is contained in:
Methapon2001 2024-08-06 16:34:12 +07:00
parent 2993cf0f02
commit 80ac35dce0
3 changed files with 322 additions and 9 deletions

View file

@ -1883,6 +1883,12 @@ watch(
customerFormState.editReadonly === false
"
@add-branch="customerFormStore.addCurrentCustomerBranch()"
@save-branch="
(idx) => {
customerFormState.saveMode = 'branch';
customerFormState.branchIndex = idx;
}
"
v-model:customer-branch="customerFormData.customerBranch"
/>
</div>

View file

@ -1,5 +1,6 @@
<script setup lang="ts">
import FormAddress from 'src/components/02_personnel-management/FormAddress.vue';
import FormBusiness from './FormBusiness.vue';
import { CustomerCreate } from 'src/stores/customer/types';
import { dateFormat, parseAndFormatDate } from 'src/utils/datetime';
import { ref, watch } from 'vue';
@ -21,7 +22,9 @@ watch(
tab.value =
branch.value?.map((a) => ({
branch: a,
tab: tab.value.find((b) => b.branch === a)?.tab || 'main',
tab:
tab.value.find((b) => (b.branch === a ? true : b.branch.id === a.id))
?.tab || 'main',
})) || [];
},
{ deep: true },
@ -29,8 +32,8 @@ watch(
defineEmits<{
(e: 'addBranch'): void;
(e: 'saveBranch', v: (typeof tab.value)[number]['branch']): void;
(e: 'deleteBranch', v: (typeof tab.value)[number]['branch']): void;
(e: 'saveBranch', i: number, v: (typeof tab.value)[number]['branch']): void;
(e: 'deleteBranch', i: number, v: (typeof tab.value)[number]['branch']): void;
}>();
defineProps<{
editable?: boolean;
@ -79,7 +82,7 @@ defineProps<{
text-color="red-9"
color="red-2"
:label="$t('delete')"
@click="$emit('deleteBranch', item)"
@click="$emit('deleteBranch', idx, item)"
class="q-px-md q-ml-auto rounded"
/>
<q-btn
@ -89,7 +92,7 @@ defineProps<{
unelevated
color="primary"
:label="$t('save')"
@click="$emit('saveBranch', item)"
@click="$emit('saveBranch', idx, item)"
class="q-px-md q-ml-sm rounded"
/>
</span>
@ -106,6 +109,7 @@ defineProps<{
>
<q-tab name="main" label="Main"></q-tab>
<q-tab name="address" label="Address"></q-tab>
<q-tab name="business" label="Business"></q-tab>
</q-tabs>
<q-tab-panels v-model="tab[idx].tab">
<q-tab-panel name="main">
@ -273,17 +277,34 @@ defineProps<{
:prefix-id="prefixId || 'employer'"
hide-title
dense
:readonly="!editable"
outlined
:title="$t('form.address')"
v-model:address="item.address"
v-model:addressEN="item.addressEN"
v-model:provinceId="item.provinceId"
v-model:districtId="item.districtId"
v-model:subDistrictId="item.subDistrictId"
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)' })"
/>
{{ $t('form.address', { suffix: '(EN)' }) }}
</q-tab-panel>
<q-tab-panel name="business">
<FormBusiness
dense
outlined
:prefix-id="prefixId || 'employer'"
:readonly="!editable"
v-model:employment-office="item.employmentOffice"
v-model:bussiness-type="item.bussinessType"
v-model:bussiness-type-en="item.bussinessTypeEN"
v-model:job-position="item.jobPosition"
v-model:job-position-en="item.jobPositionEN"
v-model:job-description="item.jobDescription"
v-model:sale-employee="item.saleEmployee"
v-model:pay-date="item.payDate"
v-model:wage-rate="item.wageRate"
/>
</q-tab-panel>
</q-tab-panels>
</div>

View file

@ -0,0 +1,286 @@
<script setup lang="ts">
import { selectFilterOptionRefMod } from 'src/stores/utils';
import { dateFormat, parseAndFormatDate } from 'src/utils/datetime';
import { onMounted, watch } from 'vue';
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
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 typeBusinessOption = ref([]);
const jobPositionOption = ref([]);
defineProps<{
title?: string;
dense?: boolean;
outlined?: boolean;
readonly?: boolean;
prefixId: string;
}>();
onMounted(async () => {
const resultOption = await fetch('/option/option.json');
rawOption.value = await resultOption.json();
if (locale.value === 'en-US') {
typeBusinessOption.value = rawOption.value.eng.businessType;
jobPositionOption.value = rawOption.value.eng.position;
}
if (locale.value === 'th-th') {
typeBusinessOption.value = rawOption.value.tha.businessType;
jobPositionOption.value = rawOption.value.tha.position;
}
});
watch(typeBusinessOption, () => {
typeBusinessFilter = selectFilterOptionRefMod(
typeBusinessOption,
typeBusinessOptions,
'label',
);
});
watch(jobPositionOption, () => {
jobPositionFilter = selectFilterOptionRefMod(
jobPositionOption,
jobPositionOptions,
'label',
);
});
const typeBusinessOptions = ref<Record<string, unknown>[]>([]);
let typeBusinessFilter = selectFilterOptionRefMod(
typeBusinessOption,
typeBusinessOptions,
'label',
);
const jobPositionOptions = ref<Record<string, unknown>[]>([]);
let jobPositionFilter = selectFilterOptionRefMod(
jobPositionOption,
jobPositionOptions,
'label',
);
</script>
<template>
<div class="col-12 row q-col-gutter-sm">
<q-input
lazy-rules="ondemand"
:for="`${prefixId}-input-employment-office`"
:id="`${prefixId}-input-employment-office`"
:dense="dense"
outlined
:readonly="readonly"
hide-bottom-space
class="col-12"
:label="$t('inputCustomerAddress')"
v-model="employmentOffice"
/>
<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"
lazy-rules="ondemand"
v-model="bussinessType"
class="col-md-6 col-12"
:dense="dense"
:readonly="readonly"
:label="$t('businessType')"
:options="typeBusinessOptions"
:for="`${prefixId}-select-business-type`"
@filter="typeBusinessFilter"
>
<template v-slot:no-option>
<q-item>
<q-item-section class="text-grey">
{{ $t('noResults') }}
</q-item-section>
</q-item>
</template>
</q-select>
<q-input
lazy-rules="ondemand"
:for="`${prefixId}-input-bussiness-type-en`"
:id="`${prefixId}-input-bussiness-type-en`"
:dense="dense"
outlined
:readonly="readonly"
hide-bottom-space
class="col-md-6 col-12"
:label="$t('businessTypeEN')"
v-model="bussinessTypeEN"
/>
<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"
lazy-rules="ondemand"
v-model="jobPosition"
class="col-md-6 col-12"
:dense="dense"
:readonly="readonly"
:label="$t('jobPosition')"
:options="jobPositionOptions"
:for="`${prefixId}-select-job-position`"
@filter="jobPositionFilter"
>
<template v-slot:no-option>
<q-item>
<q-item-section class="text-grey">
{{ $t('noResults') }}
</q-item-section>
</q-item>
</template>
</q-select>
<q-input
lazy-rules="ondemand"
:for="`${prefixId}-input-job-position-en`"
:id="`${prefixId}-input-job-position-en`"
:dense="dense"
outlined
:readonly="readonly"
hide-bottom-space
class="col-md-6 col-12"
:label="$t('jobPositionEN')"
v-model="jobPositionEN"
/>
<q-input
lazy-rules="ondemand"
:for="`${prefixId}-input-job-description`"
:id="`${prefixId}-input-job-description`"
:dense="dense"
outlined
:readonly="readonly"
hide-bottom-space
class="col-md-6 col-12"
:label="$t('jobDescription')"
v-model="jobDescription"
/>
<VueDatePicker
:id="`${prefixId}-date-picker-start-date`"
:teleport="true"
utc
autoApply
v-model="payDate"
:dark="$q.dark.isActive"
:locale="$i18n.locale === 'th-th' ? 'th' : 'en'"
:enableTimePicker="false"
:disabled="readonly"
class="col-md-3 col-12"
>
<template #year="{ value }">
{{ $i18n.locale === 'th-th' ? value + 543 : value }}
</template>
<template #year-overlay-value="{ value }">
{{ $i18n.locale === 'th-th' ? value + 543 : value }}
</template>
<template #trigger>
<q-input
lazy-rules="ondemand"
:for="`${prefixId}-input-start-date`"
:id="`${prefixId}-input-start-date`"
:label="$t('payDay')"
:dense="dense"
outlined
:readonly="readonly"
placeholder="DD/MM/YYYY"
:mask="readonly ? '' : '##/##/####'"
:model-value="
payDate
? readonly
? dateFormat(payDate)
: dateFormat(payDate, false, false, true)
: undefined
"
@update:model-value="
(v) => {
if (v && v.toString().length === 10) {
payDate = parseAndFormatDate(v, locale);
}
}
"
>
<template v-slot:prepend>
<q-icon
size="xs"
name="mdi-calendar-blank-outline"
class="cursor-pointer"
color="primary"
/>
</template>
<template v-slot:append>
<q-icon
v-if="payDate && !readonly"
name="mdi-close-circle"
class="cursor-pointer app-text-muted"
size="sm"
@click="payDate = undefined"
/>
</template>
</q-input>
</template>
</VueDatePicker>
<q-input
lazy-rules="ondemand"
: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="$t('payRate')"
v-model="wageRate"
/>
<q-input
lazy-rules="ondemand"
:for="`${prefixId}-input-sales-person`"
:id="`${prefixId}-input-sales-person`"
:dense="dense"
outlined
:readonly="readonly"
hide-bottom-space
class="col-6"
:label="$t('salesPerson')"
v-model="saleEmployee"
/>
</div>
</template>