fix: calc price

This commit is contained in:
Thanaphon Saengchan 2025-09-15 17:02:25 +07:00 committed by Methapon2001
parent 67cde37e34
commit c430b6082e
5 changed files with 119 additions and 50 deletions

View file

@ -31,6 +31,7 @@ import {
EditButton,
UndoButton,
} from 'src/components/button';
import { precisionRound } from 'src/utils/arithmetic';
import { DebitNote, useDebitNote } from 'src/stores/debit-note';
import { RequestWork } from 'src/stores/request-list/types';
import { storeToRefs } from 'pinia';
@ -40,6 +41,8 @@ import { useI18n } from 'vue-i18n';
import { QForm } from 'quasar';
import { getName } from 'src/services/keycloak';
import { RequestWorkStatus } from 'src/stores/request-list/types';
const route = useRoute();
const router = useRouter();
const creditNote = useCreditNote();
@ -49,6 +52,7 @@ const configStore = useConfigStore();
const { data: config } = storeToRefs(configStore);
const { t } = useI18n();
const agentPrice = ref<boolean>(false);
const refForm = ref<InstanceType<typeof QForm>>();
const creditNoteData = ref<CreditNote>();
const quotationData = ref<DebitNote | QuotationFull>();
@ -206,22 +210,23 @@ function getPrice(
) {
return list.reduce(
(a, c) => {
const pricePerUnit =
c.product.pricePerUnit - c.product.discount / c.product.amount;
const amount = c.list.length;
const priceNoVat = pricePerUnit;
const priceDiscountNoVat = priceNoVat * amount;
const value = creditNote.getfinalPriceCredit(c.list || []);
const rawVatTotal = priceDiscountNoVat * (config.value?.vat || 0.07);
a.totalPrice = precisionRound(a.totalPrice + value.totalPrice);
a.totalDiscount = precisionRound(a.totalDiscount + value.totalDiscount);
a.vat = precisionRound(a.vat + value.vat);
a.vatIncluded = precisionRound(a.vatIncluded + value.vatIncluded);
a.vatExcluded = precisionRound(a.vatExcluded + value.vatExcluded);
a.finalPrice = precisionRound(a.finalPrice + value.finalPrice);
a.totalPrice = a.totalPrice + priceDiscountNoVat;
a.vat = c.product.vat !== 0 ? a.vat + rawVatTotal : a.vat;
a.finalPrice = a.totalPrice + a.vat;
return a;
},
{
totalPrice: 0,
totalDiscount: 0,
vat: 0,
vatIncluded: 0,
vatExcluded: 0,
finalPrice: 0,
},
);
@ -296,6 +301,8 @@ async function getQuotation() {
if (!ret) return;
quotationData.value = ret;
agentPrice.value = quotationData.value.agentPrice;
}
async function submit() {

View file

@ -245,22 +245,9 @@ function calcPricePerUnit(product: RequestWork['productService']['product']) {
: product.price;
}
function calcPrice(
product: RequestWork['productService']['product'],
amount: number,
vat: number = 0,
) {
const pricePerUnit = agentPrice.value ? product.agentPrice : product.price;
const priceNoVat = product.vatIncluded
? pricePerUnit / (1 + (config.value?.vat || 0.07))
: pricePerUnit;
const priceDiscountNoVat = priceNoVat * amount - 0;
const rawVatTotal =
vat === 0 ? 0 : priceDiscountNoVat * (config.value?.vat || 0.07);
return precisionRound(priceNoVat * amount + rawVatTotal);
function calcPrice(c: RequestWork[]): number {
const price = creditNoteStore.getfinalPriceCredit(c);
return price.finalPrice;
}
watch(elements, () => {});
@ -327,13 +314,11 @@ function closeAble() {
<th>{{ $t('preview.pricePerUnit') }}</th>
<th>{{ $t('preview.value') }}</th>
</tr>
{{ console.log(chunks) }}
{{ console.log(chunk) }}
<tr v-for="(v, i) in chunk" :key="i">
<td class="text-center">{{ i + 1 }}</td>
<td>{{ v.product.product.code }}</td>
<td>{{ v.product.product.name }}</td>
<td style="text-align: center">
<td style="text-align: right">
{{
formatNumberDecimal(
calcPricePerUnit(v.product.product) +
@ -345,13 +330,8 @@ function closeAble() {
)
}}
</td>
<td style="text-align: center">
{{
formatNumberDecimal(
calcPrice(v.product.product, v.list.length, v.product.vat),
2,
)
}}
<td style="text-align: right">
{{ formatNumberDecimal(calcPrice(v.list), 2) }}
</td>
</tr>
</tbody>
@ -409,8 +389,8 @@ function closeAble() {
{{
formatNumberDecimal(
summaryPrice.totalPrice -
summaryPrice.totalDiscount +
summaryPrice.vat,
summaryPrice.totalDiscount -
summaryPrice.vatExcluded,
2,
)
}}

View file

@ -12,10 +12,13 @@ import { baseUrl, formatNumberDecimal } from 'src/stores/utils';
import { precisionRound } from 'src/utils/arithmetic';
import { productColumn } from '../constants';
import { useCreditNote } from 'src/stores/credit-note';
const configStore = useConfigStore();
const { data: config } = storeToRefs(configStore);
const currentExpanded = ref<boolean[]>([]);
const creditNote = useCreditNote();
defineProps<{
readonly?: boolean;
@ -44,15 +47,22 @@ function calcPricePerUnit(product: RequestWork['productService']) {
return product.pricePerUnit - product.discount / product.amount;
}
function calcPrice(c: RequestWork['productService'], amount: number) {
const pricePerUnit = c.pricePerUnit - c.discount / c.amount;
const priceNoVat = pricePerUnit;
const priceDiscountNoVat = priceNoVat * amount;
function calcVat(c: RequestWork['productService']) {
const vatFactor = c.product.serviceChargeCalcVat
? (config.value?.vat ?? 0.07)
: 0;
const rawVatTotal =
c.vat === 0 ? 0 : priceDiscountNoVat * (config.value?.vat || 0.07);
const price = precisionRound(
c.pricePerUnit * (1 + vatFactor) - c.discount / (1 + vatFactor),
);
return precisionRound(priceNoVat * amount + rawVatTotal);
const vat = (price / (1 + vatFactor)) * vatFactor;
return vat;
}
function calcPrice(c: RequestWork[]) {
const price = creditNote.getfinalPriceCredit(c);
return price.finalPrice;
}
</script>
<template>
@ -162,12 +172,7 @@ function calcPrice(c: RequestWork['productService'], amount: number) {
<!-- total -->
<q-td class="text-right">
{{
formatNumberDecimal(
calcPrice(props.row.product, props.row.list.length),
2,
)
}}
{{ formatNumberDecimal(calcPrice(props.row.list), 2) }}
</q-td>
<q-td>
<q-btn

View file

@ -9,6 +9,10 @@ import { defineStore } from 'pinia';
import { api } from 'src/boot/axios';
import { PaginationResult } from 'src/types';
import { RequestWork, RequestWorkStatus } from 'src/stores/request-list/types';
import { precisionRound } from 'src/utils/arithmetic';
import { useConfigStore } from 'src/stores/config';
import { manageAttachment, manageFile } from '../utils';
const ENDPOINT = 'credit-note';
@ -80,6 +84,7 @@ export async function acceptCreditNote(id: string) {
}
export const useCreditNote = defineStore('credit-note-store', () => {
const configStore = useConfigStore();
const data = ref<Data[]>([]);
const page = ref<number>(1);
const pageMax = ref<number>(1);
@ -90,6 +95,75 @@ export const useCreditNote = defineStore('credit-note-store', () => {
[Status.Success]: 0,
});
function getfinalPriceCredit(c: RequestWork[]): {
totalPrice: number;
totalDiscount: number;
vat: number;
vatIncluded: number;
vatExcluded: number;
finalPrice: number;
} {
const price = c.reduce(
(acc, crr) => {
const servicesChargeStepCount =
crr.productService.work?.productOnWork?.find(
(item) => item.productId === crr.productService.productId,
).stepCount;
const successCount = crr.stepStatus.filter(
(item) => item.workStatus === RequestWorkStatus.Completed,
).length;
const vatFactor =
crr.productService.vat > 0 ? (configStore.data?.vat ?? 0.07) : 0;
const price = precisionRound(
crr.productService.pricePerUnit * (1 + vatFactor) -
crr.productService.discount,
);
const vat = crr.productService.product.calcVat
? (price / (1 + vatFactor)) * vatFactor
: 0;
acc.totalPrice = precisionRound(
acc.totalPrice + price + crr.productService.discount,
);
acc.totalDiscount = precisionRound(
acc.totalDiscount + crr.productService.discount,
);
acc.vat = precisionRound(acc.vat + vat);
acc.vatExcluded = crr.productService.product.agentPriceCalcVat
? acc.vatExcluded
: precisionRound(acc.vatExcluded + price / (1 + vatFactor));
if (servicesChargeStepCount && successCount) {
acc.finalPrice = precisionRound(
acc.finalPrice +
price -
crr.productService.product.serviceCharge * successCount,
);
return acc;
}
acc.finalPrice = precisionRound(acc.finalPrice + price);
return acc;
},
{
totalPrice: 0,
totalDiscount: 0,
vat: 0,
vatIncluded: 0,
vatExcluded: 0,
finalPrice: 0,
},
);
return price;
}
return {
data,
page,
@ -97,6 +171,8 @@ export const useCreditNote = defineStore('credit-note-store', () => {
pageSize,
stats,
getfinalPriceCredit,
getCreditNoteStats,
getCreditNote,
getCreditNoteList,

View file

@ -178,6 +178,7 @@ type WorkRelation = {
createdByUserId?: string;
updatedAt: string;
updatedByUserId?: string;
productOnWork?: { productId: string; stepCount: number }[];
};
type ServiceRelation = {