- Auto-fixed 4,496 lint issues (import sorting, modern syntax, etc.) - Added ignore rules for patterns intentional in this codebase: E402 (late imports), E712 (SQLAlchemy filters), B904 (raise from), SIM108/SIM105/SIM117 (readability preferences) - Added per-file ignores for tests and scripts - Excluded broken scripts/rename_terminology.py (has curly quotes) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
186 lines
6.2 KiB
Python
186 lines
6.2 KiB
Python
# tests/unit/utils/test_vat.py
|
|
"""Tests for VAT calculation utilities."""
|
|
|
|
from decimal import Decimal
|
|
|
|
from app.utils.vat import (
|
|
EU_VAT_RATES,
|
|
VATRegime,
|
|
calculate_vat_amount,
|
|
determine_vat_regime,
|
|
get_vat_rate_for_country,
|
|
get_vat_rate_label,
|
|
is_eu_country,
|
|
)
|
|
|
|
|
|
class TestGetVatRateForCountry:
|
|
"""Tests for get_vat_rate_for_country function."""
|
|
|
|
def test_luxembourg_rate(self):
|
|
"""Luxembourg should have 17% VAT."""
|
|
assert get_vat_rate_for_country("LU") == Decimal("17.00")
|
|
|
|
def test_germany_rate(self):
|
|
"""Germany should have 19% VAT."""
|
|
assert get_vat_rate_for_country("DE") == Decimal("19.00")
|
|
|
|
def test_france_rate(self):
|
|
"""France should have 20% VAT."""
|
|
assert get_vat_rate_for_country("FR") == Decimal("20.00")
|
|
|
|
def test_hungary_rate(self):
|
|
"""Hungary should have 27% VAT (highest in EU)."""
|
|
assert get_vat_rate_for_country("HU") == Decimal("27.00")
|
|
|
|
def test_non_eu_country(self):
|
|
"""Non-EU countries should have 0% VAT."""
|
|
assert get_vat_rate_for_country("US") == Decimal("0.00")
|
|
assert get_vat_rate_for_country("CH") == Decimal("0.00")
|
|
|
|
def test_lowercase_country_code(self):
|
|
"""Should handle lowercase country codes."""
|
|
assert get_vat_rate_for_country("lu") == Decimal("17.00")
|
|
|
|
def test_all_eu_countries_covered(self):
|
|
"""All 27 EU member states should be in the VAT rates."""
|
|
assert len(EU_VAT_RATES) == 27
|
|
|
|
|
|
class TestIsEuCountry:
|
|
"""Tests for is_eu_country function."""
|
|
|
|
def test_eu_countries(self):
|
|
"""EU countries should return True."""
|
|
assert is_eu_country("LU") is True
|
|
assert is_eu_country("DE") is True
|
|
assert is_eu_country("FR") is True
|
|
|
|
def test_non_eu_countries(self):
|
|
"""Non-EU countries should return False."""
|
|
assert is_eu_country("US") is False
|
|
assert is_eu_country("CH") is False
|
|
assert is_eu_country("UK") is False
|
|
|
|
|
|
class TestGetVatRateLabel:
|
|
"""Tests for get_vat_rate_label function."""
|
|
|
|
def test_luxembourg_label(self):
|
|
"""Luxembourg label should be formatted correctly."""
|
|
label = get_vat_rate_label("LU", Decimal("17.00"))
|
|
assert label == "Luxembourg VAT 17.00%"
|
|
|
|
def test_germany_label(self):
|
|
"""Germany label should be formatted correctly."""
|
|
label = get_vat_rate_label("DE", Decimal("19.00"))
|
|
assert label == "Germany VAT 19.00%"
|
|
|
|
|
|
class TestDetermineVatRegime:
|
|
"""Tests for determine_vat_regime function."""
|
|
|
|
def test_domestic_sale(self):
|
|
"""Same country should be domestic VAT."""
|
|
result = determine_vat_regime(
|
|
seller_country="LU",
|
|
buyer_country="LU",
|
|
)
|
|
assert result.regime == VATRegime.DOMESTIC
|
|
assert result.rate == Decimal("17.00")
|
|
assert result.destination_country is None
|
|
|
|
def test_domestic_sale_germany(self):
|
|
"""German domestic sale should use 19% VAT."""
|
|
result = determine_vat_regime(
|
|
seller_country="DE",
|
|
buyer_country="DE",
|
|
)
|
|
assert result.regime == VATRegime.DOMESTIC
|
|
assert result.rate == Decimal("19.00")
|
|
|
|
def test_cross_border_b2b_reverse_charge(self):
|
|
"""B2B with VAT number should be reverse charge (0%)."""
|
|
result = determine_vat_regime(
|
|
seller_country="LU",
|
|
buyer_country="DE",
|
|
buyer_vat_number="DE123456789",
|
|
)
|
|
assert result.regime == VATRegime.REVERSE_CHARGE
|
|
assert result.rate == Decimal("0.00")
|
|
assert result.destination_country == "DE"
|
|
assert result.label == "Reverse charge"
|
|
|
|
def test_cross_border_b2c_with_oss(self):
|
|
"""B2C with OSS should use destination country VAT."""
|
|
result = determine_vat_regime(
|
|
seller_country="LU",
|
|
buyer_country="DE",
|
|
seller_oss_registered=True,
|
|
)
|
|
assert result.regime == VATRegime.OSS
|
|
assert result.rate == Decimal("19.00") # German VAT
|
|
assert result.destination_country == "DE"
|
|
|
|
def test_cross_border_b2c_without_oss(self):
|
|
"""B2C without OSS should use origin country VAT."""
|
|
result = determine_vat_regime(
|
|
seller_country="LU",
|
|
buyer_country="DE",
|
|
seller_oss_registered=False,
|
|
)
|
|
assert result.regime == VATRegime.ORIGIN
|
|
assert result.rate == Decimal("17.00") # Luxembourg VAT
|
|
assert result.destination_country == "DE"
|
|
|
|
def test_non_eu_sale(self):
|
|
"""Non-EU sales should be VAT exempt."""
|
|
result = determine_vat_regime(
|
|
seller_country="LU",
|
|
buyer_country="US",
|
|
)
|
|
assert result.regime == VATRegime.EXEMPT
|
|
assert result.rate == Decimal("0.00")
|
|
assert result.destination_country == "US"
|
|
|
|
def test_default_to_luxembourg(self):
|
|
"""Empty seller country should default to Luxembourg."""
|
|
result = determine_vat_regime(
|
|
seller_country="",
|
|
buyer_country="LU",
|
|
)
|
|
assert result.regime == VATRegime.DOMESTIC
|
|
assert result.rate == Decimal("17.00")
|
|
|
|
|
|
class TestCalculateVatAmount:
|
|
"""Tests for calculate_vat_amount function."""
|
|
|
|
def test_standard_calculation(self):
|
|
"""Test standard VAT calculation."""
|
|
# €100 at 17% = €17
|
|
result = calculate_vat_amount(10000, Decimal("17.00"))
|
|
assert result == 1700
|
|
|
|
def test_zero_rate(self):
|
|
"""Zero rate should return 0."""
|
|
result = calculate_vat_amount(10000, Decimal("0.00"))
|
|
assert result == 0
|
|
|
|
def test_negative_rate(self):
|
|
"""Negative rate should return 0."""
|
|
result = calculate_vat_amount(10000, Decimal("-5.00"))
|
|
assert result == 0
|
|
|
|
def test_rounding(self):
|
|
"""Test proper rounding to cents."""
|
|
# €33.33 at 19% = €6.3327, should round to €6.33 (633 cents)
|
|
result = calculate_vat_amount(3333, Decimal("19.00"))
|
|
assert result == 633
|
|
|
|
def test_large_amount(self):
|
|
"""Test calculation with large amounts."""
|
|
# €10,000 at 27% = €2,700
|
|
result = calculate_vat_amount(1000000, Decimal("27.00"))
|
|
assert result == 270000
|