feat: price summary
This commit is contained in:
parent
47272f46de
commit
b292e00380
4 changed files with 85 additions and 32 deletions
|
|
@ -48,6 +48,8 @@ const groupList = ref<
|
||||||
}[]
|
}[]
|
||||||
>([]);
|
>([]);
|
||||||
|
|
||||||
|
const finalDiscount = defineModel<number>('finalDiscount', { default: 0 });
|
||||||
|
|
||||||
const summaryPrice = defineModel<{
|
const summaryPrice = defineModel<{
|
||||||
totalPrice: number;
|
totalPrice: number;
|
||||||
totalDiscount: number;
|
totalDiscount: number;
|
||||||
|
|
@ -66,14 +68,13 @@ const summaryPrice = defineModel<{
|
||||||
const currentBtnOpen = ref<{ title: string; opened: boolean[] }[]>([
|
const currentBtnOpen = ref<{ title: string; opened: boolean[] }[]>([
|
||||||
{ title: '', opened: [] },
|
{ title: '', opened: [] },
|
||||||
]);
|
]);
|
||||||
const finalDiscount = ref<number>(0);
|
|
||||||
const finalDiscount4Show = ref<string>(finalDiscount.value.toString());
|
const finalDiscount4Show = ref<string>(finalDiscount.value.toString());
|
||||||
|
|
||||||
function calcPrice(c: (typeof rows.value)[number]) {
|
function calcPrice(c: (typeof rows.value)[number]) {
|
||||||
return precisionRound(
|
return precisionRound(
|
||||||
c.pricePerUnit * c.amount -
|
c.pricePerUnit * c.amount -
|
||||||
c.discount +
|
c.discount +
|
||||||
c.pricePerUnit * (config.value?.vat || 0.07) * c.amount,
|
(c.pricePerUnit * c.amount - c.discount) * (config.value?.vat || 0.07),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,7 +89,9 @@ const summary = 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 = precisionRound(a.vat + vat);
|
||||||
a.finalPrice = precisionRound(a.finalPrice + price + vat);
|
a.finalPrice = precisionRound(
|
||||||
|
a.totalPrice - a.totalDiscount + a.vat - Number(finalDiscount.value),
|
||||||
|
);
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
},
|
},
|
||||||
|
|
@ -96,7 +99,7 @@ const summary = computed(() =>
|
||||||
totalPrice: 0,
|
totalPrice: 0,
|
||||||
totalDiscount: 0,
|
totalDiscount: 0,
|
||||||
vat: 0,
|
vat: 0,
|
||||||
finalPrice: -(+finalDiscount.value || 0),
|
finalPrice: 0,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -200,7 +200,6 @@ function mapNode() {
|
||||||
opened: v.work.length > 0,
|
opened: v.work.length > 0,
|
||||||
checked: true,
|
checked: true,
|
||||||
icon: 'mdi-server-outline',
|
icon: 'mdi-server-outline',
|
||||||
attributes: v.attributes,
|
|
||||||
bg: 'hsla(var(--orange-5-hsl)/0.1)',
|
bg: 'hsla(var(--orange-5-hsl)/0.1)',
|
||||||
fg: 'var(--orange-5)',
|
fg: 'var(--orange-5)',
|
||||||
children: (function () {
|
children: (function () {
|
||||||
|
|
@ -240,13 +239,11 @@ function mapNode() {
|
||||||
const withNameObjects = v.work
|
const withNameObjects = v.work
|
||||||
.filter((w: Work) => w.name)
|
.filter((w: Work) => w.name)
|
||||||
.flatMap((w: Work) => ({
|
.flatMap((w: Work) => ({
|
||||||
type: 'work',
|
|
||||||
id: w.id,
|
id: w.id,
|
||||||
title: w.name,
|
title: w.name,
|
||||||
subtitle: ' ',
|
subtitle: ' ',
|
||||||
opened: w.productOnWork.length > 0,
|
opened: w.productOnWork.length > 0,
|
||||||
checked: true,
|
checked: true,
|
||||||
attributes: w.attributes,
|
|
||||||
children: w.productOnWork.map((p) => {
|
children: w.productOnWork.map((p) => {
|
||||||
const price = prop.agentPrice
|
const price = prop.agentPrice
|
||||||
? p.product.agentPrice
|
? p.product.agentPrice
|
||||||
|
|
@ -259,8 +256,6 @@ function mapNode() {
|
||||||
title: p.product.name,
|
title: p.product.name,
|
||||||
subtitle: p.product.code || ' ',
|
subtitle: p.product.code || ' ',
|
||||||
checked: true,
|
checked: true,
|
||||||
detail: p.product.detail,
|
|
||||||
remark: p.product.remark,
|
|
||||||
value: {
|
value: {
|
||||||
vat: 0,
|
vat: 0,
|
||||||
pricePerUnit,
|
pricePerUnit,
|
||||||
|
|
@ -270,7 +265,6 @@ function mapNode() {
|
||||||
work: w,
|
work: w,
|
||||||
product: p.product,
|
product: p.product,
|
||||||
},
|
},
|
||||||
type: 'product',
|
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
}));
|
}));
|
||||||
|
|
@ -286,8 +280,6 @@ function mapNode() {
|
||||||
id: v.id,
|
id: v.id,
|
||||||
title: v.name,
|
title: v.name,
|
||||||
subtitle: v.code,
|
subtitle: v.code,
|
||||||
detail: v.detail,
|
|
||||||
remark: v.remark,
|
|
||||||
value: {
|
value: {
|
||||||
vat: 0,
|
vat: 0,
|
||||||
pricePerUnit,
|
pricePerUnit,
|
||||||
|
|
@ -296,7 +288,6 @@ function mapNode() {
|
||||||
product: v.raw,
|
product: v.raw,
|
||||||
},
|
},
|
||||||
checked: true,
|
checked: true,
|
||||||
type: 'product',
|
|
||||||
icon: 'mdi-shopping-outline',
|
icon: 'mdi-shopping-outline',
|
||||||
bg: 'hsla(var(--teal-10-hsl)/0.1)',
|
bg: 'hsla(var(--teal-10-hsl)/0.1)',
|
||||||
fg: 'var(--teal-10)',
|
fg: 'var(--teal-10)',
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,15 @@
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { useQuasar } from 'quasar';
|
import { useQuasar } from 'quasar';
|
||||||
import { nextTick, onBeforeMount, onMounted, reactive, ref, watch } from 'vue';
|
import {
|
||||||
|
computed,
|
||||||
|
nextTick,
|
||||||
|
onBeforeMount,
|
||||||
|
onMounted,
|
||||||
|
reactive,
|
||||||
|
ref,
|
||||||
|
watch,
|
||||||
|
} from 'vue';
|
||||||
import { dialog } from 'stores/utils';
|
import { dialog } from 'stores/utils';
|
||||||
|
|
||||||
// NOTE: Import stores
|
// NOTE: Import stores
|
||||||
|
|
@ -53,6 +61,8 @@ import {
|
||||||
columnsAttachment,
|
columnsAttachment,
|
||||||
} from 'src/pages/03_customer-management/constant';
|
} from 'src/pages/03_customer-management/constant';
|
||||||
import { group } from 'node:console';
|
import { group } from 'node:console';
|
||||||
|
import { precisionRound } from 'src/utils/arithmetic';
|
||||||
|
import { useConfigStore } from 'src/stores/config';
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
readonly?: boolean;
|
readonly?: boolean;
|
||||||
|
|
@ -71,6 +81,7 @@ type Node = {
|
||||||
type ProductGroupId = string;
|
type ProductGroupId = string;
|
||||||
type Id = string;
|
type Id = string;
|
||||||
|
|
||||||
|
const configStore = useConfigStore();
|
||||||
const productServiceStore = useProductServiceStore();
|
const productServiceStore = useProductServiceStore();
|
||||||
const employeeFormStore = useEmployeeForm();
|
const employeeFormStore = useEmployeeForm();
|
||||||
const customerStore = useCustomerStore();
|
const customerStore = useCustomerStore();
|
||||||
|
|
@ -89,6 +100,8 @@ const {
|
||||||
quotationFull,
|
quotationFull,
|
||||||
} = storeToRefs(quotationForm);
|
} = storeToRefs(quotationForm);
|
||||||
|
|
||||||
|
const { data: config } = storeToRefs(configStore);
|
||||||
|
|
||||||
const refSelectZoneEmployee = ref<InstanceType<typeof SelectZone>>();
|
const refSelectZoneEmployee = ref<InstanceType<typeof SelectZone>>();
|
||||||
const mrz = ref<Awaited<ReturnType<typeof parseResultMRZ>>>();
|
const mrz = ref<Awaited<ReturnType<typeof parseResultMRZ>>>();
|
||||||
const selectedBranchIssuer = ref('');
|
const selectedBranchIssuer = ref('');
|
||||||
|
|
@ -115,17 +128,33 @@ const workerList = ref<Employee[]>([]);
|
||||||
|
|
||||||
const selectedProductGroup = ref('');
|
const selectedProductGroup = ref('');
|
||||||
const agentPrice = ref(false);
|
const agentPrice = ref(false);
|
||||||
const summaryPrice = ref<{
|
const finalDiscount = ref(0);
|
||||||
totalPrice: number;
|
const summaryPrice = computed(() =>
|
||||||
totalDiscount: number;
|
productServiceList.value.reduce(
|
||||||
vat: number;
|
(a, c) => {
|
||||||
finalPrice: number;
|
console.log(finalDiscount.value);
|
||||||
}>({
|
const price = precisionRound(c.pricePerUnit * c.amount);
|
||||||
totalPrice: 0,
|
const vat = precisionRound(
|
||||||
totalDiscount: 0,
|
(c.pricePerUnit * c.amount - c.discount) * (config.value?.vat || 0.07),
|
||||||
vat: 0,
|
);
|
||||||
finalPrice: 0,
|
|
||||||
});
|
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 quotationNo = ref('');
|
const quotationNo = ref('');
|
||||||
const payBank = ref('');
|
const payBank = ref('');
|
||||||
|
|
@ -409,6 +438,7 @@ function changeMode(mode: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
await configStore.getConfig();
|
||||||
// get language
|
// get language
|
||||||
const getCurLang = localStorage.getItem('currentLanguage');
|
const getCurLang = localStorage.getItem('currentLanguage');
|
||||||
if (getCurLang === 'English') {
|
if (getCurLang === 'English') {
|
||||||
|
|
@ -748,6 +778,7 @@ watch(
|
||||||
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="finalDiscount"
|
||||||
v-model:summary-price="summaryPrice"
|
v-model:summary-price="summaryPrice"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1082,7 +1113,7 @@ watch(
|
||||||
mrz = await runOcr(file, parseResultMRZ);
|
mrz = await runOcr(file, parseResultMRZ);
|
||||||
|
|
||||||
if (mrz !== null) {
|
if (mrz !== null) {
|
||||||
const mapMrz = Object.entries(mrz.result).map(
|
const mapMrz = Object.entries(mrz.result || {}).map(
|
||||||
([key, value]) => ({
|
([key, value]) => ({
|
||||||
name: key,
|
name: key,
|
||||||
value: value,
|
value: value,
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ const summaryPrice = defineModel<{
|
||||||
|
|
||||||
const optionStore = useOptionStore();
|
const optionStore = useOptionStore();
|
||||||
|
|
||||||
const finalDiscount = ref<number>(0);
|
const finalDiscount = defineModel('finalDiscount', { default: 0 });
|
||||||
const payTypeOpion = ref([
|
const payTypeOpion = ref([
|
||||||
{
|
{
|
||||||
value: 'Full',
|
value: 'Full',
|
||||||
|
|
@ -429,7 +429,9 @@ watch(
|
||||||
<span class="q-ml-auto">
|
<span class="q-ml-auto">
|
||||||
{{
|
{{
|
||||||
formatNumberDecimal(
|
formatNumberDecimal(
|
||||||
summaryPrice.finalPrice + Number(finalDiscount),
|
summaryPrice.finalPrice +
|
||||||
|
summaryPrice.totalDiscount +
|
||||||
|
Number(finalDiscount),
|
||||||
2,
|
2,
|
||||||
) || 0
|
) || 0
|
||||||
}}
|
}}
|
||||||
|
|
@ -444,15 +446,41 @@ watch(
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
{{ $t('general.totalAfterDiscount') }}
|
{{ $t('general.totalAfterDiscount') }}
|
||||||
<span class="q-ml-auto">{{ data?.totalAfterDiscount || 0 }} ฿</span>
|
<span class="q-ml-auto">
|
||||||
|
{{
|
||||||
|
formatNumberDecimal(
|
||||||
|
summaryPrice.finalPrice + Number(finalDiscount),
|
||||||
|
2,
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
฿
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
{{ $t('general.totalVatExcluded') }}
|
{{ $t('general.totalVatExcluded') }}
|
||||||
<span class="q-ml-auto">{{ data?.totalVatExcluded || 0 }} ฿</span>
|
<span class="q-ml-auto">
|
||||||
|
{{
|
||||||
|
formatNumberDecimal(
|
||||||
|
summaryPrice.finalPrice +
|
||||||
|
Number(finalDiscount) -
|
||||||
|
Number(summaryPrice.vat),
|
||||||
|
2,
|
||||||
|
) || 0
|
||||||
|
}}
|
||||||
|
฿
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
{{ $t('general.totalVatIncluded') }}
|
{{ $t('general.totalVatIncluded') }}
|
||||||
<span class="q-ml-auto">{{ data?.totalVatIncluded || 0 }} ฿</span>
|
<span class="q-ml-auto">
|
||||||
|
{{
|
||||||
|
formatNumberDecimal(
|
||||||
|
summaryPrice.finalPrice + Number(finalDiscount),
|
||||||
|
2,
|
||||||
|
) || 0
|
||||||
|
}}
|
||||||
|
฿
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
{{
|
{{
|
||||||
|
|
@ -460,7 +488,7 @@ watch(
|
||||||
msg: `${config && Math.round(config.vat * 100)}%`,
|
msg: `${config && Math.round(config.vat * 100)}%`,
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
<span class="q-ml-auto">{{ data?.totalVatIncluded || 0 }} ฿</span>
|
<span class="q-ml-auto">{{ summaryPrice.vat || 0 }} ฿</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
{{ $t('general.discountAfterVat') }}
|
{{ $t('general.discountAfterVat') }}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue