refactor: add page invoice
This commit is contained in:
parent
1f4edc7363
commit
f4d225985a
4 changed files with 313 additions and 180 deletions
|
|
@ -105,6 +105,9 @@ const $q = useQuasar();
|
||||||
const {
|
const {
|
||||||
currentFormData: quotationFormData,
|
currentFormData: quotationFormData,
|
||||||
currentFormState: quotationFormState,
|
currentFormState: quotationFormState,
|
||||||
|
|
||||||
|
invoicePayload: invoiceFormData,
|
||||||
|
|
||||||
newWorkerList,
|
newWorkerList,
|
||||||
fileItemNewWorker,
|
fileItemNewWorker,
|
||||||
quotationFull,
|
quotationFull,
|
||||||
|
|
@ -140,6 +143,7 @@ const workerList = ref<Employee[]>([]);
|
||||||
|
|
||||||
const selectedProductGroup = ref('');
|
const selectedProductGroup = ref('');
|
||||||
const selectedInstallmentNo = ref<number[]>([]);
|
const selectedInstallmentNo = ref<number[]>([]);
|
||||||
|
const selectedInstallment = ref();
|
||||||
const agentPrice = ref(false);
|
const agentPrice = ref(false);
|
||||||
|
|
||||||
function getPrice(
|
function getPrice(
|
||||||
|
|
@ -248,6 +252,79 @@ const productServiceList = ref<
|
||||||
Required<QuotationPayload['productServiceList'][number]>[]
|
Required<QuotationPayload['productServiceList'][number]>[]
|
||||||
>([]);
|
>([]);
|
||||||
|
|
||||||
|
async function fetchStatus() {
|
||||||
|
statusQuotationForm.value = [
|
||||||
|
{
|
||||||
|
title: 'ใบเสนอราคา',
|
||||||
|
status: getStatus(quotationFormData.value.quotationStatus, -1, -1),
|
||||||
|
handler: () => (view.value = View.Quotation),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'ลูกค้าตอบรับ',
|
||||||
|
status: getStatus(quotationFormData.value.quotationStatus, 0, -1),
|
||||||
|
handler: () => (view.value = View.Accepted),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'ใบแจ้งหนี้',
|
||||||
|
status: getStatus(quotationFormData.value.quotationStatus, 4, 0),
|
||||||
|
handler: () => {
|
||||||
|
view.value =
|
||||||
|
quotationFormData.value.payCondition === 'Full' ||
|
||||||
|
quotationFormData.value.payCondition === 'BillFull'
|
||||||
|
? View.Invoice
|
||||||
|
: View.InvoicePre;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'ชำระเงิน',
|
||||||
|
status: getStatus(quotationFormData.value.quotationStatus, 4, 1),
|
||||||
|
handler: () => {
|
||||||
|
view.value =
|
||||||
|
quotationFormData.value.payCondition === 'Full' ||
|
||||||
|
quotationFormData.value.payCondition === 'BillFull'
|
||||||
|
? View.Payment
|
||||||
|
: View.PaymentPre;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'ใบเสร็จรับเงิน',
|
||||||
|
status: getStatus(quotationFormData.value.quotationStatus, 4, 1),
|
||||||
|
handler: () => {
|
||||||
|
view.value =
|
||||||
|
quotationFormData.value.payCondition === 'Full' ||
|
||||||
|
quotationFormData.value.payCondition === 'BillFull'
|
||||||
|
? View.Receipt
|
||||||
|
: View.ReceiptPre;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'เสร็จสิ้น',
|
||||||
|
status: getStatus(quotationFormData.value.quotationStatus, 5, 4),
|
||||||
|
handler: () => {
|
||||||
|
view.value = View.Complete;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchQuotation() {
|
||||||
|
if (
|
||||||
|
currentQuotationId.value !== undefined &&
|
||||||
|
quotationFormState.value.mode &&
|
||||||
|
quotationFormState.value.mode !== 'create'
|
||||||
|
) {
|
||||||
|
await quotationForm.assignFormData(
|
||||||
|
currentQuotationId.value,
|
||||||
|
quotationFormState.value.mode,
|
||||||
|
);
|
||||||
|
await assignWorkerToSelectedWorker();
|
||||||
|
}
|
||||||
|
|
||||||
|
await assignToProductServiceList();
|
||||||
|
|
||||||
|
await fetchStatus();
|
||||||
|
}
|
||||||
|
|
||||||
async function closeTab() {
|
async function closeTab() {
|
||||||
if (quotationFormState.value.mode === 'edit') {
|
if (quotationFormState.value.mode === 'edit') {
|
||||||
quotationForm.resetForm();
|
quotationForm.resetForm();
|
||||||
|
|
@ -306,16 +383,33 @@ async function submitAccepted() {
|
||||||
action: async () => {
|
action: async () => {
|
||||||
if (!quotationFormData.value.id) return;
|
if (!quotationFormData.value.id) return;
|
||||||
|
|
||||||
await quotationForm.accepted(quotationFormData.value.id);
|
const res = await quotationForm.accepted(quotationFormData.value.id);
|
||||||
|
if (res) {
|
||||||
|
await fetchQuotation();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
cancel: () => {},
|
cancel: () => {},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function convertInvoiceToSubmit() {
|
||||||
|
if (quotationFormData.value.id) {
|
||||||
|
invoiceFormData.value = {
|
||||||
|
installmentNo: selectedInstallmentNo.value,
|
||||||
|
amount: summaryPrice.value.finalPrice,
|
||||||
|
quotationId: quotationFormData.value.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
const res = await quotationForm.submitInvoice();
|
||||||
|
if (res) view.value = View.Payment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function convertDataToFormSubmit() {
|
async function convertDataToFormSubmit() {
|
||||||
quotationFormData.value.productServiceList = JSON.parse(
|
quotationFormData.value.productServiceList = JSON.parse(
|
||||||
JSON.stringify(
|
JSON.stringify(
|
||||||
productServiceList.value.map((v) => ({
|
productServiceList.value.map((v) => ({
|
||||||
|
installmentNo: v.installmentNo,
|
||||||
workerIndex: v.workerIndex,
|
workerIndex: v.workerIndex,
|
||||||
discount: v.discount,
|
discount: v.discount,
|
||||||
amount: v.amount,
|
amount: v.amount,
|
||||||
|
|
@ -386,6 +480,7 @@ async function convertDataToFormSubmit() {
|
||||||
|
|
||||||
if (res === true) {
|
if (res === true) {
|
||||||
quotationFormState.value.mode = 'info';
|
quotationFormState.value.mode = 'info';
|
||||||
|
await fetchQuotation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -493,19 +588,24 @@ function convertToTable(nodes: Node[]) {
|
||||||
};
|
};
|
||||||
const list = nodes.flatMap(_recursive).map((v) => v.value);
|
const list = nodes.flatMap(_recursive).map((v) => v.value);
|
||||||
|
|
||||||
|
quotationFormData.value.paySplitCount = Math.max(
|
||||||
|
...list.map((v) => v.installmentNo || 0),
|
||||||
|
);
|
||||||
|
|
||||||
list.forEach((v) => {
|
list.forEach((v) => {
|
||||||
v.amount = Math.max(selectedWorker.value.length, 1);
|
v.amount = Math.max(selectedWorker.value.length, 1);
|
||||||
if (!v.workerIndex) v.workerIndex = [];
|
if (!v.workerIndex) v.workerIndex = [];
|
||||||
for (let i = 0; i < selectedWorker.value.length; i++) {
|
for (let i = 0; i < selectedWorker.value.length; i++) {
|
||||||
v.workerIndex.push(i);
|
v.workerIndex.push(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!v.installmentNo) {
|
||||||
|
v.installmentNo = quotationFormData.value.paySplitCount;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
productServiceList.value = list;
|
productServiceList.value = list;
|
||||||
|
|
||||||
quotationFormData.value.paySplitCount = Math.max(
|
|
||||||
...list.map((v) => v.installmentNo || 0),
|
|
||||||
);
|
|
||||||
quotationFormData.value.paySplit = Array.apply(
|
quotationFormData.value.paySplit = Array.apply(
|
||||||
null,
|
null,
|
||||||
new Array(quotationFormData.value.paySplitCount),
|
new Array(quotationFormData.value.paySplitCount),
|
||||||
|
|
@ -627,17 +727,7 @@ onMounted(async () => {
|
||||||
quotationFormData.value.customerBranchId = parsed.customerBranchId;
|
quotationFormData.value.customerBranchId = parsed.customerBranchId;
|
||||||
currentQuotationId.value = parsed.quotationId;
|
currentQuotationId.value = parsed.quotationId;
|
||||||
agentPrice.value = parsed.agentPrice;
|
agentPrice.value = parsed.agentPrice;
|
||||||
if (
|
await fetchQuotation();
|
||||||
currentQuotationId.value !== undefined &&
|
|
||||||
quotationFormState.value.mode &&
|
|
||||||
quotationFormState.value.mode !== 'create'
|
|
||||||
) {
|
|
||||||
await quotationForm.assignFormData(
|
|
||||||
currentQuotationId.value,
|
|
||||||
quotationFormState.value.mode,
|
|
||||||
);
|
|
||||||
await assignWorkerToSelectedWorker();
|
|
||||||
}
|
|
||||||
sessionData.value = parsed;
|
sessionData.value = parsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -647,63 +737,20 @@ onMounted(async () => {
|
||||||
if (locale.value === 'eng') optionStore.globalOption = rawOption.eng;
|
if (locale.value === 'eng') optionStore.globalOption = rawOption.eng;
|
||||||
if (locale.value === 'tha') optionStore.globalOption = rawOption.tha;
|
if (locale.value === 'tha') optionStore.globalOption = rawOption.tha;
|
||||||
|
|
||||||
await assignToProductServiceList();
|
await fetchStatus();
|
||||||
|
|
||||||
statusQuotationForm.value = [
|
|
||||||
{
|
|
||||||
title: 'ใบเสนอราคา',
|
|
||||||
status: getStatus(quotationFormData.value.quotationStatus, -1, -1),
|
|
||||||
handler: () => (view.value = View.Quotation),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'ลูกค้าตอบรับ',
|
|
||||||
status: getStatus(quotationFormData.value.quotationStatus, 0, -1),
|
|
||||||
handler: () => (view.value = View.Accepted),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'ใบแจ้งหนี้',
|
|
||||||
status: getStatus(quotationFormData.value.quotationStatus, 4, 0),
|
|
||||||
handler: () => {
|
|
||||||
quotationFormData.value.payCondition === 'Full' ||
|
|
||||||
quotationFormData.value.payCondition === 'BillFull'
|
|
||||||
? View.Invoice
|
|
||||||
: View.InvoicePre;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'ชำระเงิน',
|
|
||||||
status: getStatus(quotationFormData.value.quotationStatus, 4, 1),
|
|
||||||
handler: () => {
|
|
||||||
view.value =
|
|
||||||
quotationFormData.value.payCondition === 'Full' ||
|
|
||||||
quotationFormData.value.payCondition === 'BillFull'
|
|
||||||
? View.Payment
|
|
||||||
: View.PaymentPre;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'ใบเสร็จรับเงิน',
|
|
||||||
status: getStatus(quotationFormData.value.quotationStatus, 4, 1),
|
|
||||||
handler: () => {
|
|
||||||
view.value =
|
|
||||||
quotationFormData.value.payCondition === 'Full' ||
|
|
||||||
quotationFormData.value.payCondition === 'BillFull'
|
|
||||||
? View.Receipt
|
|
||||||
: View.ReceiptPre;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'เสร็จสิ้น',
|
|
||||||
status: getStatus(quotationFormData.value.quotationStatus, 5, 4),
|
|
||||||
handler: () => {
|
|
||||||
view.value = View.Complete;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
pageState.isLoaded = true;
|
pageState.isLoaded = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => quotationFormData.value.status,
|
||||||
|
() => {
|
||||||
|
fetchStatus();
|
||||||
|
|
||||||
|
statusQuotationForm.value.filter((v) => v.title === 'ลูกค้าตอบรับ');
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => quotationFormData.value.customerBranchId,
|
() => quotationFormData.value.customerBranchId,
|
||||||
async (v) => {
|
async (v) => {
|
||||||
|
|
@ -934,13 +981,6 @@ const view = ref<View>(View.Quotation);
|
||||||
/>
|
/>
|
||||||
{{ value.title }}
|
{{ value.title }}
|
||||||
</button>
|
</button>
|
||||||
<div class="col">
|
|
||||||
<MainButton
|
|
||||||
color="red"
|
|
||||||
icon="mdi-check-all"
|
|
||||||
@click="submitAccepted()"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<template
|
<template
|
||||||
v-if="
|
v-if="
|
||||||
|
|
@ -1014,83 +1054,6 @@ const view = ref<View>(View.Quotation);
|
||||||
</div>
|
</div>
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
|
|
||||||
<q-expansion-item
|
|
||||||
for="item-up"
|
|
||||||
id="item-up"
|
|
||||||
dense
|
|
||||||
class="overflow-hidden"
|
|
||||||
switch-toggle-side
|
|
||||||
default-opened
|
|
||||||
style="border-radius: var(--radius-2)"
|
|
||||||
expand-icon="mdi-chevron-down-circle"
|
|
||||||
header-class="surface-1"
|
|
||||||
>
|
|
||||||
<div class="surface-1 q-pa-md full-width">
|
|
||||||
<SwitchItem :value="view">
|
|
||||||
<template #[View.Quotation]>
|
|
||||||
<q-table
|
|
||||||
flat
|
|
||||||
bordered
|
|
||||||
:columns="columnPaySplit"
|
|
||||||
:rows="quotationFormData.paySplit"
|
|
||||||
selection="multiple"
|
|
||||||
v-model:selected="selectedInstallmentNo"
|
|
||||||
row-key="no"
|
|
||||||
>
|
|
||||||
<template v-slot:header="props">
|
|
||||||
<q-tr
|
|
||||||
:props="props"
|
|
||||||
:style="`background-color:hsla(var(--info-bg) / 0.07)`"
|
|
||||||
>
|
|
||||||
<q-th auto-width>
|
|
||||||
<q-checkbox v-model="props.selected" />
|
|
||||||
</q-th>
|
|
||||||
<q-th
|
|
||||||
v-for="col in props.cols"
|
|
||||||
:key="col.name"
|
|
||||||
:props="props"
|
|
||||||
>
|
|
||||||
{{ $t(col.label) }}
|
|
||||||
</q-th>
|
|
||||||
</q-tr>
|
|
||||||
</template>
|
|
||||||
<template v-slot:body="props">
|
|
||||||
<q-tr :props="props">
|
|
||||||
<q-td auto-width>
|
|
||||||
<q-checkbox v-model="props.selected" />
|
|
||||||
</q-td>
|
|
||||||
<q-td
|
|
||||||
v-for="col in props.cols"
|
|
||||||
:key="col.name"
|
|
||||||
:props="props"
|
|
||||||
>
|
|
||||||
<template v-if="col.name === 'installmentNo'">
|
|
||||||
{{ col.value }}
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-if="col.name === 'amount'">
|
|
||||||
{{ formatNumberDecimal(col.value, 2) }}
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-if="col.name === 'status'">
|
|
||||||
<BadgeComponent
|
|
||||||
:title="
|
|
||||||
!!col.value
|
|
||||||
? 'สร้างใบแจ้งหนี้เเล้ว'
|
|
||||||
: 'ยังไม่สร้างใบแจ้งหนี้'
|
|
||||||
"
|
|
||||||
:hsla-color="!!col.value ? '' : '--red-7-hsl'"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</q-td>
|
|
||||||
</q-tr>
|
|
||||||
</template>
|
|
||||||
</q-table>
|
|
||||||
</template>
|
|
||||||
</SwitchItem>
|
|
||||||
</div>
|
|
||||||
</q-expansion-item>
|
|
||||||
|
|
||||||
<q-expansion-item
|
<q-expansion-item
|
||||||
for="item-up"
|
for="item-up"
|
||||||
id="item-up"
|
id="item-up"
|
||||||
|
|
@ -1211,11 +1174,13 @@ const view = ref<View>(View.Quotation);
|
||||||
@delete="toggleDeleteProduct"
|
@delete="toggleDeleteProduct"
|
||||||
:rows="
|
:rows="
|
||||||
selectedInstallmentNo.length > 0
|
selectedInstallmentNo.length > 0
|
||||||
? productServiceList.filter(
|
? productServiceList.filter((v) => {
|
||||||
(v) =>
|
console.log(v.installmentNo, selectedInstallmentNo);
|
||||||
|
return (
|
||||||
v.installmentNo &&
|
v.installmentNo &&
|
||||||
selectedInstallmentNo.includes(v.installmentNo),
|
selectedInstallmentNo.includes(v.installmentNo)
|
||||||
)
|
);
|
||||||
|
})
|
||||||
: productServiceList
|
: productServiceList
|
||||||
"
|
"
|
||||||
@update:rows="
|
@update:rows="
|
||||||
|
|
@ -1249,26 +1214,20 @@ const view = ref<View>(View.Quotation);
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div class="surface-1 q-pa-md full-width">
|
<div class="surface-1 q-pa-md full-width">
|
||||||
<SwitchItem :value="view">
|
<template v-if="true">
|
||||||
<template #[View.Quotation]>
|
<QuotationFormInfo
|
||||||
<QuotationFormInfo
|
:info-type="view"
|
||||||
:type="view"
|
v-model:pay-type="quotationFormData.payCondition"
|
||||||
v-model:pay-type="quotationFormData.payCondition"
|
v-model:pay-bank="payBank"
|
||||||
v-model:pay-bank="payBank"
|
v-model:pay-split-count="quotationFormData.paySplitCount"
|
||||||
v-model:pay-split-count="quotationFormData.paySplitCount"
|
v-model:pay-split="quotationFormData.paySplit"
|
||||||
v-model:pay-split="quotationFormData.paySplit"
|
:readonly
|
||||||
:readonly
|
v-model:final-discount="quotationFormData.discount"
|
||||||
v-model:final-discount="quotationFormData.discount"
|
v-model:pay-bill-date="quotationFormData.payBillDate"
|
||||||
v-model:pay-bill-date="quotationFormData.payBillDate"
|
v-model:summary-price="summaryPrice"
|
||||||
v-model:summary-price="summaryPrice"
|
class="q-mb-md"
|
||||||
class="q-mb-md"
|
/>
|
||||||
/>
|
</template>
|
||||||
</template>
|
|
||||||
|
|
||||||
<template #b>
|
|
||||||
<div>bbb</div>
|
|
||||||
</template>
|
|
||||||
</SwitchItem>
|
|
||||||
</div>
|
</div>
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
<q-expansion-item
|
<q-expansion-item
|
||||||
|
|
@ -1329,6 +1288,89 @@ const view = ref<View>(View.Quotation);
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<PaymentForm :data="quotationFormState.source" />
|
<PaymentForm :data="quotationFormState.source" />
|
||||||
|
|
||||||
|
<q-expansion-item
|
||||||
|
for="item-up"
|
||||||
|
id="item-up"
|
||||||
|
dense
|
||||||
|
class="overflow-hidden"
|
||||||
|
switch-toggle-side
|
||||||
|
default-opened
|
||||||
|
style="border-radius: var(--radius-2)"
|
||||||
|
expand-icon="mdi-chevron-down-circle"
|
||||||
|
header-class="surface-1"
|
||||||
|
>
|
||||||
|
<div class="surface-1 q-pa-md full-width">
|
||||||
|
<SwitchItem :value="view">
|
||||||
|
<template #[View.InvoicePre]>
|
||||||
|
<q-table
|
||||||
|
flat
|
||||||
|
bordered
|
||||||
|
:columns="columnPaySplit"
|
||||||
|
:rows="quotationFormData.paySplit"
|
||||||
|
selection="multiple"
|
||||||
|
v-model:selected="selectedInstallment"
|
||||||
|
@update:selected="
|
||||||
|
(v) => {
|
||||||
|
selectedInstallmentNo = v.map((value) => value.no);
|
||||||
|
}
|
||||||
|
"
|
||||||
|
row-key="no"
|
||||||
|
>
|
||||||
|
<template v-slot:header="props">
|
||||||
|
<q-tr
|
||||||
|
:props="props"
|
||||||
|
:style="`background-color:hsla(var(--info-bg) / 0.07)`"
|
||||||
|
>
|
||||||
|
<q-th auto-width>
|
||||||
|
<q-checkbox v-model="props.selected" />
|
||||||
|
</q-th>
|
||||||
|
<q-th
|
||||||
|
v-for="col in props.cols"
|
||||||
|
:key="col.name"
|
||||||
|
:props="props"
|
||||||
|
>
|
||||||
|
{{ $t(col.label) }}
|
||||||
|
</q-th>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
<template v-slot:body="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-checkbox v-model="props.selected" />
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
v-for="col in props.cols"
|
||||||
|
:key="col.name"
|
||||||
|
:props="props"
|
||||||
|
>
|
||||||
|
<template v-if="col.name === 'installmentNo'">
|
||||||
|
{{ col.value }}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-if="col.name === 'amount'">
|
||||||
|
{{ formatNumberDecimal(col.value, 2) }}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-if="col.name === 'status'">
|
||||||
|
<BadgeComponent
|
||||||
|
:title="
|
||||||
|
!!col.value
|
||||||
|
? 'สร้างใบแจ้งหนี้เเล้ว'
|
||||||
|
: 'ยังไม่สร้างใบแจ้งหนี้'
|
||||||
|
"
|
||||||
|
:hsla-color="!!col.value ? '' : '--red-7-hsl'"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</q-table>
|
||||||
|
</template>
|
||||||
|
</SwitchItem>
|
||||||
|
</div>
|
||||||
|
.
|
||||||
|
</q-expansion-item>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -1344,6 +1386,48 @@ const view = ref<View>(View.Quotation);
|
||||||
>
|
>
|
||||||
{{ $t('general.view', { msg: $t('general.example') }) }}
|
{{ $t('general.view', { msg: $t('general.example') }) }}
|
||||||
</MainButton>
|
</MainButton>
|
||||||
|
|
||||||
|
<div v-if="view === View.Accepted">
|
||||||
|
<MainButton
|
||||||
|
outlined
|
||||||
|
icon="mdi-play-box-outline"
|
||||||
|
color="207 96% 32%"
|
||||||
|
@click="storeDataLocal"
|
||||||
|
>
|
||||||
|
{{ $t('general.view', { msg: $t('general.example') }) }}
|
||||||
|
</MainButton>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="view === View.InvoicePre">
|
||||||
|
<MainButton
|
||||||
|
solid
|
||||||
|
icon="mdi-account-multiple-check-outline"
|
||||||
|
color="207 96% 32%"
|
||||||
|
@click="
|
||||||
|
() => {
|
||||||
|
view = View.Invoice;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ $t('quotation.selectInvoice') }}
|
||||||
|
</MainButton>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="view === View.Invoice">
|
||||||
|
<MainButton
|
||||||
|
solid
|
||||||
|
icon="mdi-account-multiple-check-outline"
|
||||||
|
color="207 96% 32%"
|
||||||
|
@click="
|
||||||
|
() => {
|
||||||
|
convertInvoiceToSubmit();
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ $t('quotation.approveInvoice') }}
|
||||||
|
</MainButton>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="row"
|
class="row"
|
||||||
style="gap: var(--size-2)"
|
style="gap: var(--size-2)"
|
||||||
|
|
@ -1380,6 +1464,19 @@ const view = ref<View>(View.Quotation);
|
||||||
@click="quotationFormState.mode = 'edit'"
|
@click="quotationFormState.mode = 'edit'"
|
||||||
solid
|
solid
|
||||||
/>
|
/>
|
||||||
|
<MainButton
|
||||||
|
v-if="view === View.Quotation"
|
||||||
|
solid
|
||||||
|
icon="mdi-account-multiple-check-outline"
|
||||||
|
color="207 96% 32%"
|
||||||
|
@click="
|
||||||
|
() => {
|
||||||
|
submitAccepted();
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ $t('quotation.customerAcceptance') }}
|
||||||
|
</MainButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ const summaryPrice = defineModel<{
|
||||||
|
|
||||||
const finalDiscount = defineModel<number>('finalDiscount', { default: 0 });
|
const finalDiscount = defineModel<number>('finalDiscount', { default: 0 });
|
||||||
const finalDiscount4Show = ref<string>(finalDiscount.value.toString());
|
const finalDiscount4Show = ref<string>(finalDiscount.value.toString());
|
||||||
const payTypeOpion = computed(() => [
|
const payTypeOption = computed(() => [
|
||||||
{
|
{
|
||||||
value: 'Full',
|
value: 'Full',
|
||||||
label: t('quotation.type.fullAmountCash'),
|
label: t('quotation.type.fullAmountCash'),
|
||||||
|
|
@ -201,7 +201,7 @@ watch(
|
||||||
<SelectInput
|
<SelectInput
|
||||||
class="col-6"
|
class="col-6"
|
||||||
:label="$t('quotation.payType')"
|
:label="$t('quotation.payType')"
|
||||||
:option="payTypeOpion"
|
:option="payTypeOption"
|
||||||
:readonly
|
:readonly
|
||||||
id="pay-type"
|
id="pay-type"
|
||||||
v-model="payType"
|
v-model="payType"
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ export const columnPaySplit = [
|
||||||
name: 'status',
|
name: 'status',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
label: 'general.status',
|
label: 'general.status',
|
||||||
field: 'status',
|
field: 'invoice',
|
||||||
},
|
},
|
||||||
] satisfies QTableProps['columns'];
|
] satisfies QTableProps['columns'];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,11 @@ import {
|
||||||
QuotationFull,
|
QuotationFull,
|
||||||
} from 'src/stores/quotations/types';
|
} from 'src/stores/quotations/types';
|
||||||
|
|
||||||
|
import { InvoicePayload } from 'src/stores/payment/types';
|
||||||
|
|
||||||
// NOTE: Import stores
|
// NOTE: Import stores
|
||||||
import { useQuotationStore } from 'stores/quotations';
|
import { useQuotationStore } from 'stores/quotations';
|
||||||
|
import { useInvoice } from 'stores/payment';
|
||||||
import useEmployeeStore from 'stores/employee';
|
import useEmployeeStore from 'stores/employee';
|
||||||
import { getName } from 'src/services/keycloak';
|
import { getName } from 'src/services/keycloak';
|
||||||
|
|
||||||
|
|
@ -36,12 +39,23 @@ const DEFAULT_DATA: QuotationPayload = {
|
||||||
remark: undefined,
|
remark: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const DEFAULT_DATA_INVOICE: InvoicePayload = {
|
||||||
|
quotationId: '',
|
||||||
|
amount: 0,
|
||||||
|
productServiceListId: [],
|
||||||
|
installmentNo: [],
|
||||||
|
};
|
||||||
|
|
||||||
export const useQuotationForm = defineStore('form-quotation', () => {
|
export const useQuotationForm = defineStore('form-quotation', () => {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const quotationStore = useQuotationStore();
|
const quotationStore = useQuotationStore();
|
||||||
const employeeStore = useEmployeeStore();
|
const employeeStore = useEmployeeStore();
|
||||||
|
const invoiceStore = useInvoice();
|
||||||
const quotationFull = ref<QuotationFull | undefined>(undefined);
|
const quotationFull = ref<QuotationFull | undefined>(undefined);
|
||||||
|
const invoicePayload = ref<InvoicePayload & { id?: string }>(
|
||||||
|
DEFAULT_DATA_INVOICE,
|
||||||
|
);
|
||||||
const newWorkerList = ref<
|
const newWorkerList = ref<
|
||||||
(EmployeeWorker & {
|
(EmployeeWorker & {
|
||||||
attachment?: {
|
attachment?: {
|
||||||
|
|
@ -122,7 +136,7 @@ export const useQuotationForm = defineStore('form-quotation', () => {
|
||||||
payBillDate: data.payBillDate ? new Date(data.payBillDate) : undefined,
|
payBillDate: data.payBillDate ? new Date(data.payBillDate) : undefined,
|
||||||
paySplit: data.paySplit.map((p, index) => ({
|
paySplit: data.paySplit.map((p, index) => ({
|
||||||
no: index + 1,
|
no: index + 1,
|
||||||
date: p.date,
|
invoice: p.invoice,
|
||||||
amount: p.amount,
|
amount: p.amount,
|
||||||
})),
|
})),
|
||||||
worker: data.worker.map((v) =>
|
worker: data.worker.map((v) =>
|
||||||
|
|
@ -144,6 +158,8 @@ export const useQuotationForm = defineStore('form-quotation', () => {
|
||||||
if (mode === 'assign') return;
|
if (mode === 'assign') return;
|
||||||
|
|
||||||
currentFormState.value.mode = mode;
|
currentFormState.value.mode = mode;
|
||||||
|
|
||||||
|
console.log(currentFormData.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function submitQuotation() {
|
async function submitQuotation() {
|
||||||
|
|
@ -242,6 +258,22 @@ export const useQuotationForm = defineStore('form-quotation', () => {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function submitInvoice() {
|
||||||
|
let status = false;
|
||||||
|
|
||||||
|
if (invoicePayload.value.id === undefined) {
|
||||||
|
const res = await invoiceStore.creatInvoice(invoicePayload.value);
|
||||||
|
if (res) status = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (invoicePayload.value.id !== undefined) {
|
||||||
|
const res = await invoiceStore.editInvoice(invoicePayload.value);
|
||||||
|
if (res) status = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
DEFAULT_DATA,
|
DEFAULT_DATA,
|
||||||
currentFormState,
|
currentFormState,
|
||||||
|
|
@ -250,12 +282,16 @@ export const useQuotationForm = defineStore('form-quotation', () => {
|
||||||
fileItemNewWorker,
|
fileItemNewWorker,
|
||||||
quotationFull,
|
quotationFull,
|
||||||
|
|
||||||
|
invoicePayload,
|
||||||
|
|
||||||
isFormDataDifferent,
|
isFormDataDifferent,
|
||||||
injectNewEmployee,
|
injectNewEmployee,
|
||||||
assignFormData,
|
assignFormData,
|
||||||
dialogDelete,
|
dialogDelete,
|
||||||
resetForm,
|
resetForm,
|
||||||
|
|
||||||
|
submitInvoice,
|
||||||
|
|
||||||
accepted,
|
accepted,
|
||||||
|
|
||||||
submitQuotation,
|
submitQuotation,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue