diff --git a/.changeset/chatty-taxes-hammer.md b/.changeset/chatty-taxes-hammer.md new file mode 100644 index 0000000..64fea79 --- /dev/null +++ b/.changeset/chatty-taxes-hammer.md @@ -0,0 +1,5 @@ +--- +'@epilot/pricing': patch +--- + +Fix computeCumulativeValue to handle tax computation correctly diff --git a/src/tiers/compute-cumulative-value.test.ts b/src/tiers/compute-cumulative-value.test.ts index 3b83a68..fb7f684 100644 --- a/src/tiers/compute-cumulative-value.test.ts +++ b/src/tiers/compute-cumulative-value.test.ts @@ -57,11 +57,11 @@ describe('computeCumulativeValue', () => { tiers | quantityToSelectTier | unit | locale | currency | isTaxInclusive | showOnRequest | showStartsAt | tax | expected ${baseTiersUnitAmount} | ${1} | ${'kWh'} | ${undefined} | ${'EUR'} | ${true} | ${undefined} | ${undefined} | ${{ rate: 19 }} | ${{ total: '10,00\xa0€', totalWithPrecision: '10,00\xa0€', average: '10,00\xa0€/kWh', subtotal: '8,40\xa0€', subtotalWithPrecision: '8,403361344538\xa0€', subAverage: '8,40\xa0€/kWh', breakdown: [{ quantityUsed: '1 kWh', tierAmountDecimal: '10,00\xa0€/kWh', totalAmountDecimal: '10,00\xa0€' }] }} ${baseTiersUnitAmount} | ${1} | ${'kWh'} | ${undefined} | ${'EUR'} | ${undefined} | ${undefined} | ${undefined} | ${{ rate: 19 }} | ${{ total: '10,00\xa0€', totalWithPrecision: '10,00\xa0€', average: '10,00\xa0€/kWh', subtotal: '8,40\xa0€', subtotalWithPrecision: '8,403361344538\xa0€', subAverage: '8,40\xa0€/kWh', breakdown: [{ quantityUsed: '1 kWh', tierAmountDecimal: '10,00\xa0€/kWh', totalAmountDecimal: '10,00\xa0€' }] }} - ${baseTiersUnitAmount} | ${1} | ${'kWh'} | ${undefined} | ${'EUR'} | ${false} | ${undefined} | ${undefined} | ${{ rate: 19 }} | ${{ total: '11,90\xa0€', totalWithPrecision: '11,90\xa0€', average: '11,90\xa0€/kWh', subtotal: '10,00\xa0€', subtotalWithPrecision: '10,00\xa0€', subAverage: '10,00\xa0€/kWh', breakdown: [{ quantityUsed: '1 kWh', tierAmountDecimal: '10,00\xa0€/kWh', totalAmountDecimal: '10,00\xa0€' }] }} + ${baseTiersUnitAmount} | ${1} | ${'kWh'} | ${undefined} | ${'EUR'} | ${false} | ${undefined} | ${undefined} | ${{ rate: 19 }} | ${{ total: '11,90\xa0€', totalWithPrecision: '11,90\xa0€', average: '11,90\xa0€/kWh', subtotal: '10,00\xa0€', subtotalWithPrecision: '10,00\xa0€', subAverage: '10,00\xa0€/kWh', breakdown: [{ quantityUsed: '1 kWh', tierAmountDecimal: '11,90\xa0€/kWh', totalAmountDecimal: '11,90\xa0€' }] }} ${baseTiersUnitAmount} | ${1} | ${'kWh'} | ${undefined} | ${'EUR'} | ${false} | ${undefined} | ${undefined} | ${undefined} | ${{ total: '10,00\xa0€', totalWithPrecision: '10,00\xa0€', average: '10,00\xa0€/kWh', subtotal: '10,00\xa0€', subtotalWithPrecision: '10,00\xa0€', subAverage: '10,00\xa0€/kWh', breakdown: [{ quantityUsed: '1 kWh', tierAmountDecimal: '10,00\xa0€/kWh', totalAmountDecimal: '10,00\xa0€' }] }} ${baseTiersUnitAmount} | ${2} | ${'kWh'} | ${undefined} | ${'EUR'} | ${true} | ${undefined} | ${undefined} | ${{ rate: 19 }} | ${{ total: '20,00\xa0€', totalWithPrecision: '20,00\xa0€', average: '10,00\xa0€/kWh', subtotal: '16,81\xa0€', subtotalWithPrecision: '16,806722689076\xa0€', subAverage: '8,40\xa0€/kWh', breakdown: [{ quantityUsed: '2 kWh', tierAmountDecimal: '10,00\xa0€/kWh', totalAmountDecimal: '20,00\xa0€' }] }} ${baseTiersUnitAmount} | ${2} | ${'kWh'} | ${undefined} | ${'EUR'} | ${undefined} | ${undefined} | ${undefined} | ${{ rate: 19 }} | ${{ total: '20,00\xa0€', totalWithPrecision: '20,00\xa0€', average: '10,00\xa0€/kWh', subtotal: '16,81\xa0€', subtotalWithPrecision: '16,806722689076\xa0€', subAverage: '8,40\xa0€/kWh', breakdown: [{ quantityUsed: '2 kWh', tierAmountDecimal: '10,00\xa0€/kWh', totalAmountDecimal: '20,00\xa0€' }] }} - ${baseTiersUnitAmount} | ${2} | ${'kWh'} | ${undefined} | ${'EUR'} | ${false} | ${undefined} | ${undefined} | ${{ rate: 19 }} | ${{ total: '23,80\xa0€', totalWithPrecision: '23,80\xa0€', average: '11,90\xa0€/kWh', subtotal: '20,00\xa0€', subtotalWithPrecision: '20,00\xa0€', subAverage: '10,00\xa0€/kWh', breakdown: [{ quantityUsed: '2 kWh', tierAmountDecimal: '10,00\xa0€/kWh', totalAmountDecimal: '20,00\xa0€' }] }} + ${baseTiersUnitAmount} | ${2} | ${'kWh'} | ${undefined} | ${'EUR'} | ${false} | ${undefined} | ${undefined} | ${{ rate: 19 }} | ${{ total: '23,80\xa0€', totalWithPrecision: '23,80\xa0€', average: '11,90\xa0€/kWh', subtotal: '20,00\xa0€', subtotalWithPrecision: '20,00\xa0€', subAverage: '10,00\xa0€/kWh', breakdown: [{ quantityUsed: '2 kWh', tierAmountDecimal: '11,90\xa0€/kWh', totalAmountDecimal: '23,80\xa0€' }] }} ${baseTiersUnitAmount} | ${2} | ${'kWh'} | ${undefined} | ${'EUR'} | ${false} | ${undefined} | ${undefined} | ${undefined} | ${{ total: '20,00\xa0€', totalWithPrecision: '20,00\xa0€', average: '10,00\xa0€/kWh', subtotal: '20,00\xa0€', subtotalWithPrecision: '20,00\xa0€', subAverage: '10,00\xa0€/kWh', breakdown: [{ quantityUsed: '2 kWh', tierAmountDecimal: '10,00\xa0€/kWh', totalAmountDecimal: '20,00\xa0€' }] }} ${baseTiersUnitAmount} | ${5} | ${'kWh'} | ${'en'} | ${'EUR'} | ${undefined} | ${undefined} | ${undefined} | ${{ rate: 19 }} | ${{ total: '€50.00', totalWithPrecision: '€50.00', average: '€10.00/kWh', subAverage: '€8.40/kWh', subtotal: '€42.02', subtotalWithPrecision: '€42.016806722689', breakdown: [{ quantityUsed: '5 kWh', tierAmountDecimal: '€10.00/kWh', totalAmountDecimal: '€50.00' }] }} ${baseTiersUnitAmount} | ${15} | ${'banana'} | ${'en'} | ${'EUR'} | ${undefined} | ${undefined} | ${undefined} | ${{ rate: 19 }} | ${{ total: '€145.00', totalWithPrecision: '€145.00', average: '€9.67/banana', subAverage: '€8.12/banana', subtotal: '€121.85', subtotalWithPrecision: '€121.848739495798', breakdown: [{ quantityUsed: '10 banana', tierAmountDecimal: '€10.00/banana', totalAmountDecimal: '€100.00' }, { quantityUsed: '5 banana', tierAmountDecimal: '€9.00/banana', totalAmountDecimal: '€45.00' }] }} diff --git a/src/tiers/compute-cumulative-value.ts b/src/tiers/compute-cumulative-value.ts index f852041..ae37b5a 100644 --- a/src/tiers/compute-cumulative-value.ts +++ b/src/tiers/compute-cumulative-value.ts @@ -73,6 +73,7 @@ export const computeCumulativeValue = ( }; const breakdown: CumulativePriceBreakdownItem[] = []; + const taxRate = getTaxValue(tax); const total = priceTiersForQuantity.reduce( (total: Dinero, tier: PriceTier, index: number) => { @@ -84,17 +85,20 @@ export const computeCumulativeValue = ( quantity: quantityToSelectTier, }); const tierAmount = toDinero(tier.unit_amount_decimal!, formatOptions.currency).multiply(graduatedQuantity); + const tierAmountWithTax = isTaxInclusive ? tierAmount : tierAmount.multiply(1 + taxRate); + const unitAmount = toDinero(tier.unit_amount_decimal!, formatOptions.currency); + const unitAmountWithTax = isTaxInclusive ? unitAmount : unitAmount.multiply(1 + taxRate); breakdown.push({ quantityUsed: `${graduatedQuantity.toLocaleString(formatOptions.locale, { maximumFractionDigits: 6, })} ${formattedUnit}`, tierAmountDecimal: `${formatAmountFromString({ - decimalAmount: tier.unit_amount_decimal!, + decimalAmount: addSeparatorToDineroString(unitAmountWithTax.getAmount().toString()), ...formatOptions, })}${formattedUnit ? `/${formattedUnit}` : ''}`, totalAmountDecimal: formatAmountFromString({ - decimalAmount: addSeparatorToDineroString(tierAmount.getAmount().toString()), + decimalAmount: addSeparatorToDineroString(tierAmountWithTax.getAmount().toString()), ...formatOptions, }), }); @@ -111,7 +115,6 @@ export const computeCumulativeValue = ( defaultValue: 'Starts at', }); - const taxRate = getTaxValue(tax); const amountTotal = isTaxInclusive ? total : total.multiply(1 + taxRate); const amountSubtotal = isTaxInclusive ? total.divide(1 + taxRate) : total;