Source code for app.discount_strategy
from abc import ABC, abstractmethod
[docs]
class DiscountStrategy(ABC):
"""Abstract base class for discount calculation strategies."""
[docs]
@abstractmethod
def calculate_discount(self, subtotal: float) -> float:
"""
Calculate the discount amount for a given subtotal.
Args:
subtotal: The subtotal before discount
Returns:
float: The discount amount (positive value)
"""
...
[docs]
class NoDiscount(DiscountStrategy):
"""No discount applied."""
[docs]
def calculate_discount(self, subtotal: float) -> float:
return 0.0
[docs]
class PercentageDiscount(DiscountStrategy):
"""Apply a percentage discount."""
def __init__(self, percentage: float):
"""
Initialize the percentage discount strategy.
Args:
percentage: Discount percentage (e.g., 10 for 10%)
Raises:
ValueError: If percentage is negative or greater than 100
"""
if percentage < 0 or percentage > 100:
raise ValueError("Percentage must be between 0 and 100")
self.percentage = percentage
[docs]
def calculate_discount(self, subtotal: float) -> float:
return round(subtotal * (self.percentage / 100), 2)
[docs]
class ThresholdFixedDiscount(DiscountStrategy):
"""Apply a fixed discount if a threshold is reached."""
def __init__(self, threshold: float, amount: float):
"""
Initialize the threshold-based discount strategy.
Args:
threshold: Minimum subtotal required for discount
amount: Fixed discount amount to apply
Raises:
ValueError: If threshold or amount is negative
"""
if threshold < 0:
raise ValueError("Threshold must be non-negative")
if amount < 0:
raise ValueError("Amount must be non-negative")
self.threshold = threshold
self.amount = amount
[docs]
def calculate_discount(self, subtotal: float) -> float:
if subtotal >= self.threshold:
return round(min(subtotal, self.amount), 2)
return 0.0