fix: calc price
This commit is contained in:
parent
67cde37e34
commit
c430b6082e
5 changed files with 119 additions and 50 deletions
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -178,6 +178,7 @@ type WorkRelation = {
|
|||
createdByUserId?: string;
|
||||
updatedAt: string;
|
||||
updatedByUserId?: string;
|
||||
productOnWork?: { productId: string; stepCount: number }[];
|
||||
};
|
||||
|
||||
type ServiceRelation = {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue