Compare commits

...

2 commits

Author SHA1 Message Date
net
5ca4f7e112 refactor: can create new type
Some checks failed
Spell Check / Spell Check with Typos (push) Failing after 6s
2025-09-11 13:37:03 +07:00
net
85a05c3a24 fix: select customer 2025-09-11 13:36:09 +07:00
6 changed files with 113 additions and 13 deletions

View file

@ -158,6 +158,39 @@ function setDefaultValue() {
<q-separator class="q-mx-sm" /> <q-separator class="q-mx-sm" />
</template> </template>
<template #before-options v-if="creatable">
<q-item
:disable="creatableDisabled"
clickable
v-close-popup
@click.stop="$emit('create')"
for="select-business-type-add-new"
id="select-business-type-add-new"
>
<q-item-section>
<span class="row items-center">
<q-icon
name="mdi-plus-circle-outline"
class="q-mr-sm"
style="color: hsl(var(--positive-bg))"
/>
<b>
{{ $t('general.add', { text: $t('menu.manage.businessType') }) }}
</b>
<span
v-if="creatableDisabled && creatableDisabledText"
class="app-text-muted q-pl-xs"
style="font-size: 80%"
>
{{ creatableDisabledText }}
</span>
</span>
</q-item-section>
</q-item>
<q-separator class="q-mx-sm" />
</template>
<template #option="{ opt, scope }"> <template #option="{ opt, scope }">
<q-item v-bind="scope.itemProps"> <q-item v-bind="scope.itemProps">
<span class="row items-center"> <span class="row items-center">

View file

@ -30,6 +30,7 @@ defineEmits<{
type ExclusiveProps = { type ExclusiveProps = {
simple?: boolean; simple?: boolean;
simpleBranchNo?: boolean; simpleBranchNo?: boolean;
selectFirstValue?: boolean;
}; };
const props = defineProps<SelectProps<typeof getList> & ExclusiveProps>(); const props = defineProps<SelectProps<typeof getList> & ExclusiveProps>();
@ -64,10 +65,14 @@ onMounted(async () => {
setFirstValue(); setFirstValue();
} }
await getSelectedOption(); if (props.selectFirstValue) {
setDefaultValue();
valueOption.value = selectOptions.value.find((v) => v.id === value.value); } else await getSelectedOption();
}); });
function setDefaultValue() {
setFirstValue();
}
</script> </script>
<template> <template>
<SelectInput <SelectInput
@ -160,11 +165,9 @@ onMounted(async () => {
</template> </template>
<template #option="{ opt, scope }"> <template #option="{ opt, scope }">
<q-item @click="valueOption = opt" v-bind="scope.itemProps"> <q-item v-bind="scope.itemProps" class="q-mx-sm bodrder">
<SelectCustomerItem :data="opt" :simple :simple-branch-no /> <SelectCustomerItem :data="opt" :simple :simple-branch-no />
</q-item> </q-item>
<q-separator class="q-mx-sm" />
</template> </template>
<template #append v-if="clearable"> <template #append v-if="clearable">
@ -177,3 +180,11 @@ onMounted(async () => {
</template> </template>
</SelectInput> </SelectInput>
</template> </template>
<style scoped>
.bodrder {
border-bottom: solid;
border-bottom-width: 1px;
border-color: var(--border-color);
}
</style>

View file

@ -2263,7 +2263,7 @@ const emptyCreateDialog = ref(false);
customerFormData.customerBranch[0].legalPersonNo customerFormData.customerBranch[0].legalPersonNo
" "
v-model:business-type=" v-model:business-type="
customerFormData.customerBranch[0].businessType customerFormData.customerBranch[0].businessTypeId
" "
v-model:job-position=" v-model:job-position="
customerFormData.customerBranch[0].jobPosition customerFormData.customerBranch[0].jobPosition

View file

@ -10,10 +10,25 @@ import { useI18n } from 'vue-i18n';
import ThaiBahtText from 'thai-baht-text'; import ThaiBahtText from 'thai-baht-text';
import SelectBusinessType from 'src/components/shared/select/SelectBusinessType.vue'; import SelectBusinessType from 'src/components/shared/select/SelectBusinessType.vue';
import BusinessTypeDialog from 'src/pages/16_business-type-management/BusinessTypeDialog.vue';
import useBusinessTypeStore from 'src/stores/business-type';
const { locale } = useI18n({ useScope: 'global' }); const { locale } = useI18n({ useScope: 'global' });
const rawOption = ref(); const rawOption = ref();
const businessTypeDialog = ref<boolean>(false);
const formDataBusinessType = ref<{
name: string;
nameEN: string;
}>({
name: '',
nameEN: '',
});
const useBusinessType = useBusinessTypeStore();
const businessTypeId = defineModel<string>('businessTypeId'); const businessTypeId = defineModel<string>('businessTypeId');
const jobPosition = defineModel<string>('jobPosition'); const jobPosition = defineModel<string>('jobPosition');
const jobDescription = defineModel<string>('jobDescription'); const jobDescription = defineModel<string>('jobDescription');
@ -29,6 +44,8 @@ const typeBusinessENOption = ref([]);
const jobPositionOption = ref([]); const jobPositionOption = ref([]);
const jobPositionENOption = ref([]); const jobPositionENOption = ref([]);
const keySelect = ref<number>(0);
defineProps<{ defineProps<{
title?: string; title?: string;
dense?: boolean; dense?: boolean;
@ -38,6 +55,20 @@ defineProps<{
showTitle?: boolean; showTitle?: boolean;
}>(); }>();
function resetFormBusinessType() {
businessTypeDialog.value = false;
formDataBusinessType.value = { name: '', nameEN: '' };
}
async function submitBusinessType() {
const res = await useBusinessType.create(formDataBusinessType.value);
if (res) {
businessTypeId.value = res.id;
resetFormBusinessType();
keySelect.value++;
}
}
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();
@ -121,16 +152,24 @@ let jobPositionENFilter = selectFilterOptionRefMod(
</div> </div>
<SelectBusinessType <SelectBusinessType
:key="keySelect"
class="col-md-6 col-12" class="col-md-6 col-12"
v-model:value="businessTypeId" v-model:value="businessTypeId"
:readonly :readonly
creatable
lang="tha" lang="tha"
:rules="[(val: string) => !!val || $t('form.error.required')]"
@create="() => (businessTypeDialog = true)"
/> />
<SelectBusinessType <SelectBusinessType
:key="keySelect"
class="col-md-6 col-12" class="col-md-6 col-12"
v-model:value="businessTypeId" v-model:value="businessTypeId"
lang="eng"
:readonly :readonly
creatable
lang="eng"
:rules="[(val: string) => !!val || $t('form.error.required')]"
@create="() => (businessTypeDialog = true)"
/> />
<q-select <q-select
@ -282,4 +321,12 @@ let jobPositionENFilter = selectFilterOptionRefMod(
" "
/> />
</div> </div>
<BusinessTypeDialog
ref="refBusinessTypeDialog"
@close="resetFormBusinessType()"
@submit="submitBusinessType()"
v-model="businessTypeDialog"
v-model:data="formDataBusinessType"
/>
</template> </template>

View file

@ -30,6 +30,8 @@ export const useCustomerForm = defineStore('form-customer', () => {
const registerAbleBranchOption = ref<{ id: string; name: string }[]>(); const registerAbleBranchOption = ref<{ id: string; name: string }[]>();
const currentBranchRootId = ref<string>('');
const tabFieldRequired = ref<{ const tabFieldRequired = ref<{
[key: string]: (keyof CustomerBranchCreate)[]; [key: string]: (keyof CustomerBranchCreate)[];
}>({ }>({
@ -160,6 +162,7 @@ export const useCustomerForm = defineStore('form-customer', () => {
state.value.editCustomerCode = data.code; state.value.editCustomerCode = data.code;
state.value.customerImageUrl = `${baseUrl}/customer/${id}/image/${data.selectedImage}`; state.value.customerImageUrl = `${baseUrl}/customer/${id}/image/${data.selectedImage}`;
state.value.defaultCustomerImageUrl = `${baseUrl}/customer/${id}/image/${data.selectedImage}`; state.value.defaultCustomerImageUrl = `${baseUrl}/customer/${id}/image/${data.selectedImage}`;
currentBranchRootId.value = data.branch[0].id || '';
resetFormData.registeredBranchId = data.registeredBranchId; resetFormData.registeredBranchId = data.registeredBranchId;
resetFormData.status = data.status; resetFormData.status = data.status;
@ -500,6 +503,8 @@ export const useCustomerForm = defineStore('form-customer', () => {
state, state,
resetFormData, resetFormData,
currentFormData, currentFormData,
currentBranchRootId,
isFormDataDifferent, isFormDataDifferent,
resetForm, resetForm,
assignFormData, assignFormData,
@ -1663,6 +1668,7 @@ export const useEmployeeForm = defineStore('form-employee', () => {
state, state,
currentFromDataEmployee, currentFromDataEmployee,
resetEmployeeData, resetEmployeeData,
addPassport, addPassport,
addVisa, addVisa,
addCheckup, addCheckup,

View file

@ -60,7 +60,6 @@ const flowStore = useFlowStore();
const userBranch = useMyBranch(); const userBranch = useMyBranch();
const navigatorStore = useNavigator(); const navigatorStore = useNavigator();
const customerStore = useCustomerStore(); const customerStore = useCustomerStore();
const { const {
fetchListOfOptionBranch, fetchListOfOptionBranch,
customerFormUndo, customerFormUndo,
@ -76,6 +75,7 @@ const {
const { const {
state: customerFormState, state: customerFormState,
currentFormData: customerFormData, currentFormData: customerFormData,
currentBranchRootId,
registerAbleBranchOption, registerAbleBranchOption,
tabFieldRequired, tabFieldRequired,
} = storeToRefs(customerFormStore); } = storeToRefs(customerFormStore);
@ -89,6 +89,8 @@ const fieldSelectedOption = computed(() => {
value: v.name, value: v.name,
})); }));
}); });
const keyAddDialog = ref<number>(0);
const special = ref(false); const special = ref(false);
const branchId = ref(''); const branchId = ref('');
const agentPrice = ref<boolean>(false); const agentPrice = ref<boolean>(false);
@ -865,6 +867,7 @@ async function filterBySellerId() {
<!-- NOTE: START - Quotation Form, Add Quotation --> <!-- NOTE: START - Quotation Form, Add Quotation -->
<DialogForm <DialogForm
:key="keyAddDialog"
:title="$t('general.add', { text: $t('quotation.title') })" :title="$t('general.add', { text: $t('quotation.title') })"
v-model:modal="pageState.addModal" v-model:modal="pageState.addModal"
:submit-label="$t('general.add', { text: $t('quotation.title') })" :submit-label="$t('general.add', { text: $t('quotation.title') })"
@ -880,7 +883,7 @@ async function filterBySellerId() {
:close=" :close="
() => { () => {
branchId = ''; branchId = '';
quotationFormData.customerBranchId = ''; currentBranchRootId = '';
} }
" "
:beforeClose=" :beforeClose="
@ -930,7 +933,7 @@ async function filterBySellerId() {
v-model:agent-price="agentPrice" v-model:agent-price="agentPrice"
v-model:branch-id="branchId" v-model:branch-id="branchId"
v-model:special="special" v-model:special="special"
v-model:customer-branch-id="quotationFormData.customerBranchId" v-model:customer-branch-id="currentBranchRootId"
@add-customer="triggerSelectTypeCustomerd()" @add-customer="triggerSelectTypeCustomerd()"
/> />
</div> </div>
@ -999,6 +1002,7 @@ async function filterBySellerId() {
() => { () => {
customerFormState.dialogModal = false; customerFormState.dialogModal = false;
onCreateImageList = { selectedImage: '', list: [] }; onCreateImageList = { selectedImage: '', list: [] };
keyAddDialog++;
} }
" "
> >
@ -1190,7 +1194,7 @@ async function filterBySellerId() {
customerFormData.customerBranch[0].legalPersonNo customerFormData.customerBranch[0].legalPersonNo
" "
v-model:business-type=" v-model:business-type="
customerFormData.customerBranch[0].businessType customerFormData.customerBranch[0].businessTypeId
" "
v-model:job-position=" v-model:job-position="
customerFormData.customerBranch[0].jobPosition customerFormData.customerBranch[0].jobPosition
@ -1271,7 +1275,6 @@ async function filterBySellerId() {
res = await customerStore.createBranch({ res = await customerStore.createBranch({
...customerFormData.customerBranch[idx], ...customerFormData.customerBranch[idx],
customerId: customerFormState.editCustomerId || '', customerId: customerFormState.editCustomerId || '',
id: undefined,
}); });
} }
if (res) { if (res) {