feat: add vat excluded calc
This commit is contained in:
parent
8749e48178
commit
369a7a406d
4 changed files with 18 additions and 73 deletions
|
|
@ -1,17 +1,14 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, ref, watch } from 'vue';
|
import { ref, watch } from 'vue';
|
||||||
import { QTableProps } from 'quasar';
|
import { QTableProps } from 'quasar';
|
||||||
import { toWords } from 'number-to-words';
|
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
|
|
||||||
import WorkerItem from './WorkerItem.vue';
|
import WorkerItem from './WorkerItem.vue';
|
||||||
import DeleteButton from '../button/DeleteButton.vue';
|
import DeleteButton from '../button/DeleteButton.vue';
|
||||||
import { commaInput } from 'stores/utils';
|
|
||||||
import { precisionRound } from 'src/utils/arithmetic';
|
import { precisionRound } from 'src/utils/arithmetic';
|
||||||
import { QuotationPayload } from 'stores/quotations/types';
|
import { QuotationPayload } from 'stores/quotations/types';
|
||||||
import { formatNumberDecimal } from 'stores/utils';
|
import { formatNumberDecimal } from 'stores/utils';
|
||||||
import { useConfigStore } from 'stores/config';
|
import { useConfigStore } from 'stores/config';
|
||||||
import { Product, Service, Work } from 'src/stores/product-service/types';
|
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
readonly?: boolean;
|
readonly?: boolean;
|
||||||
|
|
@ -40,23 +37,6 @@ const rows = defineModel<
|
||||||
Required<QuotationPayload['productServiceList'][number]>[]
|
Required<QuotationPayload['productServiceList'][number]>[]
|
||||||
>('rows', { required: true });
|
>('rows', { required: true });
|
||||||
|
|
||||||
const finalDiscount = defineModel<number>('finalDiscount', { default: 0 });
|
|
||||||
|
|
||||||
const summaryPrice = defineModel<{
|
|
||||||
totalPrice: number;
|
|
||||||
totalDiscount: number;
|
|
||||||
vat: number;
|
|
||||||
finalPrice: number;
|
|
||||||
}>('summaryPrice', {
|
|
||||||
required: true,
|
|
||||||
default: {
|
|
||||||
totalPrice: 0,
|
|
||||||
totalDiscount: 0,
|
|
||||||
vat: 0,
|
|
||||||
finalPrice: 0,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const currentBtnOpen = ref<{ title: string; opened: boolean[] }[]>([
|
const currentBtnOpen = ref<{ title: string; opened: boolean[] }[]>([
|
||||||
{ title: '', opened: [] },
|
{ title: '', opened: [] },
|
||||||
]);
|
]);
|
||||||
|
|
@ -69,32 +49,6 @@ function calcPrice(c: (typeof rows.value)[number]) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const summary = computed(() =>
|
|
||||||
rows.value.reduce(
|
|
||||||
(a, c) => {
|
|
||||||
const price = precisionRound(c.pricePerUnit * c.amount);
|
|
||||||
const vat = precisionRound(
|
|
||||||
(c.pricePerUnit * c.amount - c.discount) * (config.value?.vat || 0.07),
|
|
||||||
);
|
|
||||||
|
|
||||||
a.totalPrice = precisionRound(a.totalPrice + price);
|
|
||||||
a.totalDiscount = precisionRound(a.totalDiscount + Number(c.discount));
|
|
||||||
a.vat = precisionRound(a.vat + vat);
|
|
||||||
a.finalPrice = precisionRound(
|
|
||||||
a.totalPrice - a.totalDiscount + a.vat - Number(finalDiscount.value),
|
|
||||||
);
|
|
||||||
|
|
||||||
return a;
|
|
||||||
},
|
|
||||||
{
|
|
||||||
totalPrice: 0,
|
|
||||||
totalDiscount: 0,
|
|
||||||
vat: 0,
|
|
||||||
finalPrice: 0,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
name: 'order',
|
name: 'order',
|
||||||
|
|
@ -152,15 +106,6 @@ const columns = [
|
||||||
},
|
},
|
||||||
] satisfies QTableProps['columns'];
|
] satisfies QTableProps['columns'];
|
||||||
|
|
||||||
const EngBahtText = (number: number) => {
|
|
||||||
const [baht, satang] = number.toString().split('.');
|
|
||||||
const bahtText =
|
|
||||||
toWords(baht).charAt(0).toUpperCase() + toWords(baht).slice(1);
|
|
||||||
const satangText =
|
|
||||||
toWords(satang).charAt(0).toUpperCase() + toWords(satang).slice(1);
|
|
||||||
return `${bahtText} Baht${satang ? ` and ${satangText} Satang` : ''}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
function openEmployeeTable(title: string, index: number) {
|
function openEmployeeTable(title: string, index: number) {
|
||||||
currentBtnOpen.value[0].title = title;
|
currentBtnOpen.value[0].title = title;
|
||||||
currentBtnOpen.value[0].opened.map((_, i) => {
|
currentBtnOpen.value[0].opened.map((_, i) => {
|
||||||
|
|
@ -252,13 +197,6 @@ function handleCheck(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(
|
|
||||||
() => summary.value,
|
|
||||||
() => {
|
|
||||||
summaryPrice.value = summary.value;
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.employeeRows,
|
() => props.employeeRows,
|
||||||
(a, b) => {
|
(a, b) => {
|
||||||
|
|
@ -311,7 +249,7 @@ watch(
|
||||||
>
|
>
|
||||||
<template #header="{ cols }">
|
<template #header="{ cols }">
|
||||||
<q-tr style="background-color: hsla(var(--info-bg) / 0.07)">
|
<q-tr style="background-color: hsla(var(--info-bg) / 0.07)">
|
||||||
<q-th v-for="(v, i) in cols" :key="v">
|
<q-th v-for="v in cols" :key="v">
|
||||||
{{ $t(v.label) }}
|
{{ $t(v.label) }}
|
||||||
</q-th>
|
</q-th>
|
||||||
<q-th auto-width />
|
<q-th auto-width />
|
||||||
|
|
@ -374,11 +312,13 @@ watch(
|
||||||
<q-td align="right">
|
<q-td align="right">
|
||||||
{{
|
{{
|
||||||
formatNumberDecimal(
|
formatNumberDecimal(
|
||||||
precisionRound(
|
props.row.product.calcVat
|
||||||
(props.row.pricePerUnit * props.row.amount -
|
? precisionRound(
|
||||||
props.row.discount) *
|
(props.row.pricePerUnit * props.row.amount -
|
||||||
(config?.vat || 0.07),
|
props.row.discount) *
|
||||||
),
|
(config?.vat || 0.07),
|
||||||
|
)
|
||||||
|
: 0,
|
||||||
2,
|
2,
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,10 @@ const summaryPrice = computed(() =>
|
||||||
|
|
||||||
a.totalPrice = precisionRound(a.totalPrice + price);
|
a.totalPrice = precisionRound(a.totalPrice + price);
|
||||||
a.totalDiscount = precisionRound(a.totalDiscount + Number(c.discount));
|
a.totalDiscount = precisionRound(a.totalDiscount + Number(c.discount));
|
||||||
a.vat = precisionRound(a.vat + vat);
|
a.vat = c.product.calcVat ? precisionRound(a.vat + vat) : a.vat;
|
||||||
|
a.vatExcluded = c.product.calcVat
|
||||||
|
? a.vatExcluded
|
||||||
|
: precisionRound(a.vat + vat);
|
||||||
a.finalPrice = precisionRound(
|
a.finalPrice = precisionRound(
|
||||||
a.totalPrice -
|
a.totalPrice -
|
||||||
a.totalDiscount +
|
a.totalDiscount +
|
||||||
|
|
@ -146,6 +149,7 @@ const summaryPrice = computed(() =>
|
||||||
totalPrice: 0,
|
totalPrice: 0,
|
||||||
totalDiscount: 0,
|
totalDiscount: 0,
|
||||||
vat: 0,
|
vat: 0,
|
||||||
|
vatExcluded: 0,
|
||||||
finalPrice: 0,
|
finalPrice: 0,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
@ -759,7 +763,7 @@ async function searchEmployee(text: string) {
|
||||||
<ProductItem
|
<ProductItem
|
||||||
:readonly="readonly"
|
:readonly="readonly"
|
||||||
:agent-price="agentPrice"
|
:agent-price="agentPrice"
|
||||||
:employeeRows="
|
:employee-rows="
|
||||||
selectedWorker.map((e: Employee) => ({
|
selectedWorker.map((e: Employee) => ({
|
||||||
foreignRefNo: '123456789',
|
foreignRefNo: '123456789',
|
||||||
employeeName:
|
employeeName:
|
||||||
|
|
@ -777,7 +781,6 @@ async function searchEmployee(text: string) {
|
||||||
"
|
"
|
||||||
@delete="toggleDeleteProduct"
|
@delete="toggleDeleteProduct"
|
||||||
v-model:rows="productServiceList"
|
v-model:rows="productServiceList"
|
||||||
v-model:summary-price="summaryPrice"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@ const summaryPrice = defineModel<{
|
||||||
totalPrice: number;
|
totalPrice: number;
|
||||||
totalDiscount: number;
|
totalDiscount: number;
|
||||||
vat: number;
|
vat: number;
|
||||||
|
vatExlucded: number;
|
||||||
finalPrice: number;
|
finalPrice: number;
|
||||||
}>('summaryPrice', {
|
}>('summaryPrice', {
|
||||||
required: true,
|
required: true,
|
||||||
|
|
@ -543,7 +544,7 @@ watch(
|
||||||
<div class="row">
|
<div class="row">
|
||||||
{{ $t('general.totalVatExcluded') }}
|
{{ $t('general.totalVatExcluded') }}
|
||||||
<span class="q-ml-auto">
|
<span class="q-ml-auto">
|
||||||
{{ formatNumberDecimal(0, 2) || 0 }}
|
{{ formatNumberDecimal(summaryPrice.vatExcluded, 2) || 0 }}
|
||||||
฿
|
฿
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,7 @@ type ProductRelation = {
|
||||||
agentPrice: number;
|
agentPrice: number;
|
||||||
serviceCharge: number;
|
serviceCharge: number;
|
||||||
vatIncluded: boolean;
|
vatIncluded: boolean;
|
||||||
|
calcVat: boolean;
|
||||||
expenseType: string;
|
expenseType: string;
|
||||||
status: Status;
|
status: Status;
|
||||||
statusOrder: number;
|
statusOrder: number;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue