feat: add support for debit notes in credit note forms and related components
Some checks failed
Spell Check / Spell Check with Typos (push) Failing after 7s

This commit is contained in:
puriphatt 2025-07-08 13:28:27 +07:00
parent 7679c076a7
commit 2b310c667d
7 changed files with 40 additions and 7 deletions

View file

@ -36,7 +36,7 @@ withDefaults(
<span <span
:class="{ 'link cursor-pointer': clickable }" :class="{ 'link cursor-pointer': clickable }"
v-if="typeof value === 'string'" v-if="typeof value === 'string'"
@click="$emit('labelClick', value, null)" @click="clickable ? $emit('labelClick', value, null) : undefined"
> >
{{ value }} {{ value }}
<q-tooltip v-if="tooltip" :delay="500">{{ value }}</q-tooltip> <q-tooltip v-if="tooltip" :delay="500">{{ value }}</q-tooltip>

View file

@ -8,6 +8,10 @@ defineProps<{
const quotationId = defineModel<string>('quotationId', { const quotationId = defineModel<string>('quotationId', {
required: true, required: true,
}); });
const isDebitNote = defineModel<boolean>('isDebitNote', {
required: false,
default: false,
});
</script> </script>
<template> <template>
<div class="row col-12"> <div class="row col-12">
@ -37,6 +41,7 @@ const quotationId = defineModel<string>('quotationId', {
cancelIncludeDebitNote: true, cancelIncludeDebitNote: true,
hasCancel: true, hasCancel: true,
}" }"
@selected="(v) => (isDebitNote = v.isDebitNote)"
/> />
</section> </section>
</div> </div>

View file

@ -25,6 +25,7 @@ const { getQuotationList: getList, getQuotation: getById } = useStore();
defineEmits<{ defineEmits<{
(e: 'create'): void; (e: 'create'): void;
(e: 'selected', value: SelectOption): void;
}>(); }>();
type ExclusiveProps = { type ExclusiveProps = {
@ -117,6 +118,14 @@ function setDefaultValue() {
(v: string) => !props.required || !!v || $t('form.error.required'), (v: string) => !props.required || !!v || $t('form.error.required'),
]" ]"
@filter="filter" @filter="filter"
@update:model-value="
(v) => {
$emit(
'selected',
selectOptions.find((opt) => opt.id === v),
);
}
"
> >
<template #append v-if="clearable"> <template #append v-if="clearable">
<q-icon <q-icon

View file

@ -4,7 +4,7 @@ import { api } from 'src/boot/axios';
import { useRoute, useRouter } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
import { dateFormatJS } from 'src/utils/datetime'; import { dateFormatJS } from 'src/utils/datetime';
import { initLang, initTheme } from 'src/utils/ui'; import { initLang, initTheme } from 'src/utils/ui';
import { useQuotationStore } from 'src/stores/quotations'; import { QuotationFull, useQuotationStore } from 'src/stores/quotations';
import { import {
CreditNote, CreditNote,
CreditNotePaybackStatus, CreditNotePaybackStatus,
@ -31,6 +31,7 @@ import {
EditButton, EditButton,
UndoButton, UndoButton,
} from 'src/components/button'; } from 'src/components/button';
import { DebitNote, useDebitNote } from 'src/stores/debit-note';
import { RequestWork } from 'src/stores/request-list/types'; import { RequestWork } from 'src/stores/request-list/types';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
import useOptionStore from 'src/stores/options'; import useOptionStore from 'src/stores/options';
@ -42,6 +43,7 @@ import { getName } from 'src/services/keycloak';
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
const creditNote = useCreditNote(); const creditNote = useCreditNote();
const debitNote = useDebitNote();
const quotation = useQuotationStore(); const quotation = useQuotationStore();
const configStore = useConfigStore(); const configStore = useConfigStore();
const { data: config } = storeToRefs(configStore); const { data: config } = storeToRefs(configStore);
@ -49,7 +51,7 @@ const { t } = useI18n();
const refForm = ref<InstanceType<typeof QForm>>(); const refForm = ref<InstanceType<typeof QForm>>();
const creditNoteData = ref<CreditNote>(); const creditNoteData = ref<CreditNote>();
const quotationData = ref<CreditNote['quotation']>(); const quotationData = ref<DebitNote | QuotationFull>();
const view = ref<CreditNoteStatus | null>(null); const view = ref<CreditNoteStatus | null>(null);
const fileList = ref<FileList>(); const fileList = ref<FileList>();
const attachmentList = ref<FileList>(); const attachmentList = ref<FileList>();
@ -286,7 +288,10 @@ async function getQuotation() {
return; return;
} }
const ret = await quotation.getQuotation(route.query['quotationId']); const isDebitNote = route.query['isDebitNote'] === 'true';
const ret = isDebitNote
? await debitNote.getDebitNote(route.query['quotationId'])
: await quotation.getQuotation(route.query['quotationId']);
if (!ret) return; if (!ret) return;
@ -639,6 +644,10 @@ onMounted(async () => {
</nav> </nav>
<DocumentExpansion <DocumentExpansion
:noLink="
route.query['isDebitNote'] === 'true' ||
quotationData?.code.startsWith('DN')
"
readonly readonly
:registered-branch-id="quotationData?.registeredBranchId" :registered-branch-id="quotationData?.registeredBranchId"
:customer-id="quotationData?.customerBranchId" :customer-id="quotationData?.customerBranchId"

View file

@ -45,6 +45,7 @@ const pageState = reactive({
.map((v) => v.name), .map((v) => v.name),
gridView: false, gridView: false,
total: 0, total: 0,
isDebitNote: false,
creditDialog: false, creditDialog: false,
searchDate: [], searchDate: [],
@ -108,13 +109,17 @@ function navigateTo(opts: {
if (opts.statusDialog === 'create') { if (opts.statusDialog === 'create') {
url.searchParams.append('quotationId', opts.quotationId || ''); url.searchParams.append('quotationId', opts.quotationId || '');
url.searchParams.append('isDebitNote', pageState.isDebitNote.toString());
} }
window.open(url.toString(), '_blank'); window.open(url.toString(), '_blank');
} }
async function submit() { async function submit() {
navigateTo({ statusDialog: 'create', quotationId: pageState.quotationId }); navigateTo({
statusDialog: 'create',
quotationId: pageState.quotationId,
});
close(); close();
} }
@ -480,7 +485,10 @@ watch(
<section class="q-pa-md col full-width"> <section class="q-pa-md col full-width">
<div class="surface-1 rounded bordered q-pa-md full-height full-width"> <div class="surface-1 rounded bordered q-pa-md full-height full-width">
<FormCredit v-model:quotation-id="pageState.quotationId" /> <FormCredit
v-model:quotation-id="pageState.quotationId"
v-model:is-debit-note="pageState.isDebitNote"
/>
</div> </div>
</section> </section>

View file

@ -6,6 +6,7 @@ import DataDisplay from 'src/components/08_request-list/DataDisplay.vue';
defineProps<{ defineProps<{
readonly?: boolean; readonly?: boolean;
noLink?: boolean;
}>(); }>();
defineEmits<{ defineEmits<{
@ -61,7 +62,7 @@ const quotationCreatedBy = defineModel<string>('quotationCreatedBy');
/> />
<DataDisplay <DataDisplay
clickable :clickable="!noLink"
class="col-md col-6" class="col-md col-6"
style="padding-inline: 20px" style="padding-inline: 20px"
:label="$t('creditNote.label.quotationCode')" :label="$t('creditNote.label.quotationCode')"

View file

@ -268,6 +268,7 @@ export type Quotation = {
updatedByUserId: string; updatedByUserId: string;
updatedBy: UpdatedBy; updatedBy: UpdatedBy;
updatedAt: string | Date; updatedAt: string | Date;
isDebitNote?: boolean;
}; };
export type QuotationFull = { export type QuotationFull = {