Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into ST-2160-coupons-displ…
Browse files Browse the repository at this point in the history
…ay-bonus-in-order-table
  • Loading branch information
JoFont committed Nov 18, 2024
2 parents d1b14ea + 2b4323e commit b83845a
Show file tree
Hide file tree
Showing 9 changed files with 8,573 additions and 116 deletions.
8,386 changes: 8,383 additions & 3 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
"author": "epilot GmbH",
"license": "UNLICENSED",
"dependencies": {
"@epilot/pricing-client": "^3.35.14-beta.2",
"@epilot/pricing-client": "^3.35.15",
"@types/dinero.js": "^1.9.0",
"axios": "^1.7.7",
"dinero.js": "^1.9.1"
Expand Down
2 changes: 2 additions & 0 deletions src/__tests__/fixtures/coupon.samples.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export const fixedCashbackCoupon: Coupon = {
fixed_value: 1000,
fixed_value_decimal: '10.00',
fixed_value_currency: 'EUR',
cashback_period: '12',

Check failure on line 44 in src/__tests__/fixtures/coupon.samples.ts

View workflow job for this annotation

GitHub Actions / Test (16.x)

An object literal cannot have multiple properties with the same name.
};

export const percentageCashbackCoupon: Coupon = {
Expand All @@ -54,4 +55,5 @@ export const percentageCashbackCoupon: Coupon = {
type: 'percentage',
category: 'cashback',
percentage_value: '10',
cashback_period: '12',
};
3 changes: 3 additions & 0 deletions src/__tests__/fixtures/price.samples.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ export const priceItem1: PriceItemDto = {
is_tax_inclusive: true,
};

/**
* @todo Rename to recurringPriceItem
*/
export const priceItem2: PriceItemDto = {
quantity: 1,
taxes: [
Expand Down
19 changes: 11 additions & 8 deletions src/__tests__/fixtures/pricing.results.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6993,27 +6993,29 @@ export const computedPriceWithFixedAmountCashbackCoupon = {
fixed_value: 1000,
fixed_value_decimal: '10.00',
fixed_value_currency: 'EUR',
cashback_period: '12',
},
],
currency: 'EUR',
description: 'Winter Sale',
unit_amount: 10000,
unit_amount_net: 9091,
unit_amount_net_decimal: '90.909090909091',
unit_amount_gross: 10000,
unit_amount_gross_decimal: '100',
unit_amount_decimal: '100',
amount_subtotal: 9091,
amount_total: 10000,
amount_tax: 909,
cashback_amount: 1000,
cashback_amount_decimal: '10',
currency: 'EUR',
description: 'Winter Sale',
unit_amount_decimal: '100',
amount_tax: 909,
amount_subtotal_decimal: '90.909090909091',
amount_total_decimal: '100',
},
],
currency: 'EUR',
};

/**
* Simple price with a fixed amount cashback coupon applied to it
*/
Expand Down Expand Up @@ -7124,21 +7126,22 @@ export const computedPriceWithPercentageCashbackCoupon = {
type: 'percentage',
category: 'cashback',
percentage_value: '10',
cashback_period: '12',
},
],
currency: 'EUR',
description: 'Winter Sale',
unit_amount: 10000,
unit_amount_net: 9091,
unit_amount_net_decimal: '90.909090909091',
unit_amount_gross: 10000,
unit_amount_gross_decimal: '100',
unit_amount_decimal: '100',
amount_subtotal: 9091,
amount_total: 10000,
amount_tax: 909,
cashback_amount: 1000,
cashback_amount_decimal: '10',
currency: 'EUR',
description: 'Winter Sale',
unit_amount_decimal: '100',
amount_tax: 909,
amount_subtotal_decimal: '90.909090909091',
amount_total_decimal: '100',
},
Expand Down
8 changes: 8 additions & 0 deletions src/normalizers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@ export const normalizeTimeFrequencyToDinero = (
): Dinero => {
const dineroInputValue = toDinero(String(timeValue));

return normalizeTimeFrequencyFromDineroInputValue(dineroInputValue, timeValueFrequency, targetTimeFrequency);
};

export const normalizeTimeFrequencyFromDineroInputValue = (
dineroInputValue: Dinero,
timeValueFrequency: TimeFrequency,
targetTimeFrequency: TimeFrequency,
): Dinero => {
if (
!timeFrequencyNormalizerMatrix[targetTimeFrequency] ||
!timeFrequencyNormalizerMatrix[targetTimeFrequency][timeValueFrequency]
Expand Down
4 changes: 2 additions & 2 deletions src/pricing.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -515,12 +515,12 @@ describe('computeAggregatedAndPriceTotals', () => {
expect(result).toEqual(results.computedResultWithPricesWithAndWithoutCoupons);
});

it.only('should compute cashbacks and totals correctly', () => {
it('should compute fixed amount cashbacks and totals correctly', () => {
const result = computeAggregatedAndPriceTotals([samples.priceItemWithFixedAmountCashbackCoupon]);
expect(result).toEqual(results.computedPriceWithFixedAmountCashbackCoupon);
});

it('should compute cashbacks and totals correctly', () => {
it('should compute percentage amount cashbacks and totals correctly', () => {
const result = computeAggregatedAndPriceTotals([samples.priceItemWithPercentageCashbackCoupon]);
expect(result).toEqual(results.computedPriceWithPercentageCashbackCoupon);
});
Expand Down
88 changes: 47 additions & 41 deletions src/pricing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import type {
CompositePrice,
CompositePriceItem,
CompositePriceItemDto,
Coupon,
ExternalFeeMapping,
Price,
PriceInputMapping,
Expand Down Expand Up @@ -97,14 +96,12 @@ export const computePriceComponent = (
const safeParentQuantity = isNaN(priceItem.quantity!) ? 1 : priceItem.quantity!;
const quantity = toDinero(String(safeQuantity)).multiply(safeParentQuantity).toUnit();

return computePriceItem(
priceItemComponent,
priceItemComponent._price,
return computePriceItem(priceItemComponent, {
tax,
quantity,
priceMapping,
externalFeeMapping,
);
});
};

const isValidPrice = (priceComponent: Price): boolean => {
Expand Down Expand Up @@ -354,7 +351,6 @@ export const computeAggregatedAndPriceTotals = (priceItems: PriceItemsDto): Pric
};
} else {
const price = priceItem._price;
const coupons = priceItem._coupons;
const tax = priceItem.taxes?.[0]?.tax;
const priceMapping = priceItem._price
? priceItem.price_mappings?.find(({ price_id }) => priceItem._price!._id === price_id)
Expand All @@ -366,7 +362,12 @@ export const computeAggregatedAndPriceTotals = (priceItems: PriceItemsDto): Pric

const priceItemToAppend = immutablePriceItem
? (immutablePriceItem as PriceItemDto)
: computePriceItem(priceItem, price, tax, priceItem.quantity!, priceMapping, externalFeeMapping, coupons);
: computePriceItem(priceItem, {
tax,
quantity: priceItem.quantity!,
priceMapping,
externalFeeMapping,
});

const updatedTotals = isUnitAmountApproved(
priceItem,
Expand Down Expand Up @@ -687,13 +688,19 @@ export const mapToProductSnapshot = (product?: Product): Product | undefined =>
*/
export const computePriceItem = (
priceItem: PriceItemDto,
price: Price | undefined,
applicableTax: Tax | undefined,
quantity: number,
priceMapping?: PriceInputMapping,
externalFeeMapping?: ExternalFeeMapping,
coupons: ReadonlyArray<Coupon> = [],
{
tax: applicableTax,
quantity,
priceMapping,
externalFeeMapping,
}: {
tax?: Tax;
quantity: number;
priceMapping?: PriceInputMapping;
externalFeeMapping?: ExternalFeeMapping;
},
): PriceItem => {
const price = priceItem._price;
const currency = (price?.unit_amount_currency || DEFAULT_CURRENCY).toUpperCase() as Currency;
const priceItemDescription = priceItem.description ?? price?.description;

Expand All @@ -714,60 +721,59 @@ export const computePriceItem = (

switch (price?.pricing_model) {
case PricingModel.tieredVolume:
itemValues = computeTieredVolumePriceItemValues(
price.tiers,
itemValues = computeTieredVolumePriceItemValues(priceItem, {
tiers: price.tiers,
currency,
isTaxInclusive,
quantityToSelectTier,
priceTax,
tax: priceTax,
unitAmountMultiplier,
priceItem._price?.unchanged_price_display_in_journeys,
);
unchangedPriceDisplayInJourneys: priceItem._price?.unchanged_price_display_in_journeys,
});
break;
case PricingModel.tieredFlatFee:
itemValues = computeTieredFlatFeePriceItemValues(
price.tiers,
itemValues = computeTieredFlatFeePriceItemValues(priceItem, {
tiers: price.tiers,
currency,
isTaxInclusive,
quantityToSelectTier,
priceTax,
safeQuantity,
isUsingPriceMappingToSelectTier,
priceItem._price?.unchanged_price_display_in_journeys,
);
tax: priceTax,
quantity: safeQuantity,
isUsingPriceMappingToSelectTier: isUsingPriceMappingToSelectTier,
unchangedPriceDisplayInJourneys: priceItem._price?.unchanged_price_display_in_journeys,
});
break;
case PricingModel.tieredGraduated:
itemValues = computeTieredGraduatedPriceItemValues(
price.tiers,
itemValues = computeTieredGraduatedPriceItemValues(priceItem, {
tiers: price.tiers,
currency,
isTaxInclusive,
quantityToSelectTier,
priceTax,
safeQuantity,
isUsingPriceMappingToSelectTier,
priceItem._price?.unchanged_price_display_in_journeys,
);
tax: priceTax,
quantity: safeQuantity,
isUsingPriceMappingToSelectTier: isUsingPriceMappingToSelectTier,
unchangedPriceDisplayInJourneys: priceItem._price?.unchanged_price_display_in_journeys,
});
break;
case PricingModel.externalGetAG:
itemValues = computeExternalGetAGItemValues(
price?.get_ag!,
itemValues = computeExternalGetAGItemValues(priceItem, {
getAg: price?.get_ag!,
currency,
isTaxInclusive,
unitAmountMultiplier,
quantityToSelectTier,
userInput: quantityToSelectTier,
externalFeeAmountDecimal,
priceTax,
);
tax: priceTax,
});
break;
default:
itemValues = computePriceItemValues(
itemValues = computePriceItemValues(priceItem, {
unitAmountDecimal,
currency,
isTaxInclusive,
unitAmountMultiplier,
priceTax,
coupons,
);
tax: priceTax,
});
}

return {
Expand Down
Loading

0 comments on commit b83845a

Please sign in to comment.