From a49bfc79a4821c9ee5bea9e1b5d3657e0a4981ca Mon Sep 17 00:00:00 2001 From: Carl Date: Tue, 20 Jun 2023 16:43:37 +0800 Subject: [PATCH] fix: quote price display with bc settings --- .../src/pages/quote/QuoteDetail.tsx | 64 ++++++++++++++++++- .../quote/components/QuoteDetailSummary.tsx | 27 +++----- .../quote/components/QuoteDetailTable.tsx | 49 +++----------- .../quote/components/QuoteDetailTableCard.tsx | 25 ++++++-- .../src/pages/quote/shared/config.ts | 1 + 5 files changed, 101 insertions(+), 65 deletions(-) diff --git a/apps/storefront/src/pages/quote/QuoteDetail.tsx b/apps/storefront/src/pages/quote/QuoteDetail.tsx index 79a5f532..a50c2cab 100644 --- a/apps/storefront/src/pages/quote/QuoteDetail.tsx +++ b/apps/storefront/src/pages/quote/QuoteDetail.tsx @@ -14,6 +14,7 @@ import { searchB2BProducts, searchBcProducts, } from '@/shared/service/b2b' +import { store, TaxZoneRates, TaxZoneRatesProps } from '@/store' import { getDefaultCurrencyInfo, getSearchVal, snackbar } from '@/utils' import { conversionProductsList } from '@/utils/b3Product/shared/config' @@ -58,10 +59,47 @@ function QuoteDetail() { const [isShowFooter, setIsShowFooter] = useState(false) const { currency_code: currencyCode } = getDefaultCurrencyInfo() - const [quoteDetailTaxRate, setQuoteDetailTaxRate] = useState(0) + const [quoteDetailTax, setQuoteDetailTax] = useState(0) const location = useLocation() + const { + global: { taxZoneRates, enteredInclusive: enteredInclusiveTax }, + } = store.getState() + + const classRates: TaxZoneRates[] = [] + if (taxZoneRates.length) { + const defaultTaxZone: TaxZoneRatesProps = taxZoneRates.find( + (taxZone: { id: number }) => taxZone.id === 1 + ) + if (defaultTaxZone) { + const { rates } = defaultTaxZone + const { enabled } = rates[0] + if (enabled && rates[0].classRates.length) { + rates[0].classRates.forEach((rate) => classRates.push(rate)) + } + } + } + + const getTaxRate = (taxClassId: number, variants: any) => { + if (variants.length) { + const { + bc_calculated_price: { + tax_exclusive: taxExclusive, + tax_inclusive: taxInclusive, + }, + } = variants[0] + return (taxInclusive - taxExclusive) / taxExclusive + } + if (classRates.length) { + return ( + (classRates.find((rate) => rate.taxClassId === taxClassId)?.rate || 0) / + 100 + ) + } + return 0 + } + const handleGetProductsById = async (listProducts: ProductInfoProps[]) => { if (listProducts.length > 0) { const productIds: number[] = [] @@ -133,6 +171,26 @@ function QuoteDetail() { }) setProductList(productsWithMoreInfo) + if (+quote.shippingTotal === 0) { + setQuoteDetailTax(+quote.taxTotal) + } else { + let taxPrice = 0 + productsWithMoreInfo?.forEach((product) => { + const { + quantity, + offeredPrice, + productsSearch: { variants = [], taxClassId }, + } = product + + const taxRate = getTaxRate(taxClassId, variants) + taxPrice += enteredInclusiveTax + ? ((+offeredPrice * taxRate) / (1 + taxRate)) * +quantity + : +offeredPrice * taxRate * +quantity + }) + + setQuoteDetailTax(taxPrice) + } + const { backendAttachFiles = [], storefrontAttachFiles = [] } = quote const newFileList: CustomFieldItems[] = [] @@ -392,7 +450,7 @@ function QuoteDetail() { @@ -418,7 +476,7 @@ function QuoteDetail() { > diff --git a/apps/storefront/src/pages/quote/components/QuoteDetailSummary.tsx b/apps/storefront/src/pages/quote/components/QuoteDetailSummary.tsx index d612bd93..58506041 100644 --- a/apps/storefront/src/pages/quote/components/QuoteDetailSummary.tsx +++ b/apps/storefront/src/pages/quote/components/QuoteDetailSummary.tsx @@ -13,38 +13,27 @@ interface Summary { interface QuoteDetailSummaryProps { quoteSummary: Summary - quoteDetailTaxRate: number + quoteDetailTax: number } export default function QuoteDetailSummary(props: QuoteDetailSummaryProps) { const { quoteSummary: { originalSubtotal, discount, tax, shipping, totalAmount }, - quoteDetailTaxRate: taxRates = 0, + quoteDetailTax = 0, } = props const { - global: { showInclusiveTaxPrice }, + global: { enteredInclusive: enteredInclusiveTax, showInclusiveTaxPrice }, } = store.getState() const subtotalPrice = +originalSubtotal const quotedSubtotal = +originalSubtotal - +discount - const taxTotal = - +shipping === 0 - ? +tax - : +totalAmount + +discount - +shipping - subtotalPrice - let enteredInclusiveTax = false - if (+shipping) { - enteredInclusiveTax = +shipping > taxTotal - } else { - enteredInclusiveTax = +totalAmount + +discount === +originalSubtotal - } - - const getCurrentPrice = (price: number, taxRate: number) => { + const getCurrentPrice = (price: number, quoteDetailTax: number) => { if (enteredInclusiveTax) { - return showInclusiveTaxPrice ? price : price / (1 + taxRate) + return showInclusiveTaxPrice ? price : price - quoteDetailTax } - return showInclusiveTaxPrice ? price * (1 + taxRate) : price + return showInclusiveTaxPrice ? price + quoteDetailTax : price } const priceFormat = (price: number) => `${currencyFormat(price)}` @@ -69,7 +58,7 @@ export default function QuoteDetailSummary(props: QuoteDetailSummaryProps) { > Original subtotal - {priceFormat(getCurrentPrice(subtotalPrice, taxRates))} + {priceFormat(getCurrentPrice(subtotalPrice, quoteDetailTax))} - {priceFormat(getCurrentPrice(quotedSubtotal, taxRates))} + {priceFormat(getCurrentPrice(quotedSubtotal, quoteDetailTax))} diff --git a/apps/storefront/src/pages/quote/components/QuoteDetailTable.tsx b/apps/storefront/src/pages/quote/components/QuoteDetailTable.tsx index d37f2c61..6a82c87c 100644 --- a/apps/storefront/src/pages/quote/components/QuoteDetailTable.tsx +++ b/apps/storefront/src/pages/quote/components/QuoteDetailTable.tsx @@ -4,7 +4,7 @@ import { Box, styled, Typography } from '@mui/material' import { B3PaginationTable } from '@/components/table/B3PaginationTable' import { TableColumnItem } from '@/components/table/B3Table' import { PRODUCT_DEFAULT_IMAGE } from '@/constants' -import { store, TaxZoneRates, TaxZoneRatesProps } from '@/store' +import { store } from '@/store' import { currencyFormat } from '@/utils' import { getBCPrice } from '@/utils/b3Product/b3Product' @@ -46,7 +46,7 @@ interface ShoppingDetailTableProps { edges: any[] totalCount: number }> - setQuoteDetailTaxRate: React.Dispatch> + getTaxRate: (taxClassId: number, variants: any) => number } interface SearchProps { @@ -96,26 +96,12 @@ const StyledImage = styled('img')(() => ({ })) function QuoteDetailTable(props: ShoppingDetailTableProps, ref: Ref) { - const { total, getQuoteTableDetails, setQuoteDetailTaxRate } = props + const { total, getQuoteTableDetails, getTaxRate } = props const { - global: { taxZoneRates, enteredInclusive: enteredInclusiveTax }, + global: { enteredInclusive: enteredInclusiveTax }, } = store.getState() - const classRates: TaxZoneRates[] = [] - if (taxZoneRates.length) { - const defaultTaxZone: TaxZoneRatesProps = taxZoneRates.find( - (taxZone: { id: number }) => taxZone.id === 1 - ) - if (defaultTaxZone) { - const { rates } = defaultTaxZone - const { enabled } = rates[0] - if (enabled && rates[0].classRates.length) { - rates[0].classRates.forEach((rate) => classRates.push(rate)) - } - } - } - const paginationTableRef = useRef(null) const [search, setSearch] = useState({ @@ -132,25 +118,6 @@ function QuoteDetailTable(props: ShoppingDetailTableProps, ref: Ref) { }, })) - const getTaxRate = (taxClassId: number, variants: any) => { - if (variants.length) { - const { - bc_calculated_price: { - tax_exclusive: taxExclusive, - tax_inclusive: taxInclusive, - }, - } = variants[0] - return (taxInclusive - taxExclusive) / taxExclusive - } - if (classRates.length) { - return ( - (classRates.find((rate) => rate.taxClassId === taxClassId)?.rate || 0) / - 100 - ) - } - return 0 - } - const columnItems: TableColumnItem[] = [ { key: 'Product', @@ -242,7 +209,6 @@ function QuoteDetailTable(props: ShoppingDetailTableProps, ref: Ref) { } = row const taxRate = getTaxRate(taxClassId, variants) - setQuoteDetailTaxRate(taxRate) const taxPrice = enteredInclusiveTax ? (+basePrice * taxRate) / (1 + taxRate) : +basePrice * taxRate @@ -390,7 +356,12 @@ function QuoteDetailTable(props: ShoppingDetailTableProps, ref: Ref) { noDataText="No products found" tableKey="productId" renderItem={(row: ProductInfoProps, index?: number) => ( - + )} /> diff --git a/apps/storefront/src/pages/quote/components/QuoteDetailTableCard.tsx b/apps/storefront/src/pages/quote/components/QuoteDetailTableCard.tsx index a4b6ddb5..a2bf98e7 100644 --- a/apps/storefront/src/pages/quote/components/QuoteDetailTableCard.tsx +++ b/apps/storefront/src/pages/quote/components/QuoteDetailTableCard.tsx @@ -1,11 +1,14 @@ import { Box, CardContent, styled, Typography } from '@mui/material' import { PRODUCT_DEFAULT_IMAGE } from '@/constants' +import { store } from '@/store' import { currencyFormat } from '@/utils' +import { getBCPrice } from '@/utils/b3Product/b3Product' interface QuoteTableCardProps { item: any len: number + getTaxRate: (taxClassId: number, variants: any) => number itemIndex?: number } @@ -16,7 +19,11 @@ const StyledImage = styled('img')(() => ({ })) function QuoteDetailTableCard(props: QuoteTableCardProps) { - const { item: quoteTableItem, len, itemIndex } = props + const { item: quoteTableItem, len, itemIndex, getTaxRate } = props + + const { + global: { enteredInclusive: enteredInclusiveTax }, + } = store.getState() const { basePrice, @@ -27,14 +34,24 @@ function QuoteDetailTableCard(props: QuoteTableCardProps) { sku, notes, offeredPrice, - productsSearch: { productUrl }, + productsSearch: { productUrl, variants = [], taxClassId }, } = quoteTableItem - const price = +basePrice + const taxRate = getTaxRate(taxClassId, variants) + const taxPrice = enteredInclusiveTax + ? (+basePrice * taxRate) / (1 + taxRate) + : +basePrice * taxRate + const discountTaxPrice = enteredInclusiveTax + ? (+offeredPrice * taxRate) / (1 + taxRate) + : +offeredPrice * taxRate + + const price = getBCPrice(+basePrice, taxPrice) + const discountPrice = getBCPrice(+offeredPrice, discountTaxPrice) + const isDiscount = +basePrice - +offeredPrice > 0 const total = +price * +quantity - const totalWithDiscount = +offeredPrice * +quantity + const totalWithDiscount = discountPrice * +quantity return (