""" Test utilities and fixtures for pricing tests """ from decimal import Decimal from django.test import TestCase from ..models.base import Currency, Term, Unit from ..models.providers import CloudProvider from ..models.services import Service, Category from ..models.pricing import ( ProgressiveDiscountModel, DiscountTier, VSHNAppCatPrice, VSHNAppCatBaseFee, VSHNAppCatUnitRate, ) class PricingTestMixin: """Mixin providing common setup for pricing tests""" def create_test_cloud_provider(self, name="Test Provider"): """Create a test cloud provider""" return CloudProvider.objects.create( name=name, slug=name.lower().replace(" ", "-"), description=f"{name} description", website=f"https://{name.lower().replace(' ', '')}.com", ) def create_test_service(self, name="Test Service"): """Create a test service""" return Service.objects.create( name=name, slug=name.lower().replace(" ", "-"), description=f"{name} description", features=f"{name} features", ) def create_test_discount_model(self, name="Test Discount", tiers=None): """Create a test discount model with optional tiers""" discount_model = ProgressiveDiscountModel.objects.create( name=name, description=f"{name} description", active=True ) if tiers is None: # Default tiers: 0-9 (0%), 10-49 (10%), 50+ (20%) tiers = [ (0, 10, Decimal("0.00")), (10, 50, Decimal("10.00")), (50, None, Decimal("20.00")), ] for min_units, max_units, discount_percent in tiers: DiscountTier.objects.create( discount_model=discount_model, min_units=min_units, max_units=max_units, discount_percent=discount_percent, ) return discount_model def create_test_appcat_price( self, service, discount_model=None, base_fee=Decimal("50.00"), unit_rate=Decimal("5.0000"), ): """Create a test AppCat price configuration""" appcat_price = VSHNAppCatPrice.objects.create( service=service, variable_unit=VSHNAppCatPrice.VariableUnit.RAM, term=Term.MTH, discount_model=discount_model, ) # Create base fee VSHNAppCatBaseFee.objects.create( vshn_appcat_price_config=appcat_price, currency=Currency.CHF, amount=base_fee, ) # Create unit rate VSHNAppCatUnitRate.objects.create( vshn_appcat_price_config=appcat_price, currency=Currency.CHF, service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED, amount=unit_rate, ) return appcat_price def calculate_expected_discounted_price(base_rate, units, discount_tiers): """Helper function to calculate expected discounted price manually""" final_price = Decimal("0") remaining_units = units # Sort tiers by min_units sorted_tiers = sorted(discount_tiers, key=lambda x: x[0]) for min_units, max_units, discount_percent in sorted_tiers: if remaining_units <= 0: break # Skip if we haven't reached this tier yet if units < min_units: continue # Calculate units in this tier tier_max = max_units if max_units else float("inf") units_start = max(0, units - remaining_units) units_end = min(units, tier_max if max_units else units) tier_units = max(0, units_end - max(units_start, min_units - 1)) if tier_units > 0: discounted_rate = base_rate * (1 - discount_percent / 100) final_price += discounted_rate * tier_units remaining_units -= tier_units return final_price