Support stacking multiple discount codes #2
@@ -0,0 +1,10 @@
|
|||||||
|
import type { Discount } from './cart'
|
||||||
|
|
||||||
|
/** Combine multiple discount codes into one effective factor. */
|
||||||
|
export function applyDiscounts(subtotalCents: number, discounts: Discount[]): number {
|
||||||
|
let totalPercentOff = 0
|
||||||
|
for (const discount of discounts) {
|
||||||
|
totalPercentOff += discount.percentOff
|
||||||
|
}
|
||||||
|
return Math.round(subtotalCents * (1 - totalPercentOff / 100))
|
||||||
|
|
|||||||
|
}
|
||||||
|
greptile-bot
commented
When <a href="#"><img alt="P2" src="https://greptile-static-assets.s3.amazonaws.com/badges/p2.svg?v=9" align="top"></a> **No guard against an empty discount list**
When `discounts` is an empty array, `totalPercentOff` stays `0` and the function returns `subtotalCents` unchanged — which is mathematically correct. However, there is also no guard against individual `percentOff` values that are negative (a negative discount would _increase_ the price) or individually greater than 100. The `Discount` interface places no constraint on `percentOff`, so a caller could pass `{ code: "BAD", percentOff: -20 }` and silently inflate the total. Consider validating each entry or documenting the expected range.
|
|||||||
Reference in New Issue
Block a user
If two or more discount codes sum to more than 100%,
(1 - totalPercentOff / 100)becomes negative andMath.roundreturns a negative cents value — effectively charging the customer. For example, two 60%-off codes produce a factor of-0.2, turning a $10 subtotal into-$2. ClampingtotalPercentOffto100prevents this.