# `PhoenixKit.Utils.CountryData`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.87/lib/phoenix_kit/utils/country_data.ex#L1)

Wrapper for BeamLabCountries with country data utility functions.

Provides a convenient API for working with country data:
country selection, tax rates, EU membership.

Includes workaround for charlist bug in VAT rates until fixed upstream.

## Examples

    # Get list of countries for dropdown
    countries = CountryData.countries_for_select()
    # [{"🇦🇩 Andorra", "AD"}, {"🇦🇪 United Arab Emirates", "AE"}, ...]

    # Get standard VAT rate
    rate = CountryData.get_standard_vat_rate("EE")
    # #Decimal<0.20>

    # Check EU membership
    CountryData.eu_member?("EE")
    # true

    # Get country information
    country = CountryData.get_country("DE")
    # %BeamLabCountries.Country{name: "Germany", ...}

    # Format company address from Settings
    address = CountryData.format_company_address()
    # "123 Business Street\nTallinn 10115\nEstonia"

# `countries_for_select`

Get list of countries for select dropdown.

Returns list of tuples {display_name, alpha2_code} for use
in Phoenix form selects.

## Examples

    iex> countries = CountryData.countries_for_select()
    iex> {"🇦🇫 Afghanistan", "AF"} in countries
    true

# `eea_countries`

Get list of EEA countries (EU + Norway, Iceland, Liechtenstein).

# `eea_member?`

Check if country is an EEA (European Economic Area) member.

EEA includes EU + Norway, Iceland, Liechtenstein.

## Examples

    iex> CountryData.eea_member?("EE")
    true

    iex> CountryData.eea_member?("NO")
    true

    iex> CountryData.eea_member?("CH")
    false

# `eu_countries`

Get list of EU countries.

## Examples

    iex> eu = CountryData.eu_countries()
    iex> length(eu)
    27
    iex> Enum.map(eu, & &1.alpha2) |> Enum.sort() |> Enum.take(5)
    ["AT", "BE", "BG", "CY", "CZ"]

# `eu_countries_for_select`

Get list of EU countries for select dropdown.

# `eu_member?`

Check if country is an EU member.

## Examples

    iex> CountryData.eu_member?("EE")
    true

    iex> CountryData.eu_member?("GB")
    false

    iex> CountryData.eu_member?("US")
    false

# `exists?`

Check if country with given code exists.

## Examples

    iex> CountryData.exists?("EE")
    true

    iex> CountryData.exists?("XX")
    false

# `format_company_address`

Format company address from Settings for document printing.

Assembles address from individual fields (address_line1, address_line2, city, state,
postal_code, country) into a single string with line breaks.

## Returns

Formatted address as string, for example:
```
123 Business Street
Suite 100
Tallinn 10115
Estonia
```

## Examples

    iex> CountryData.format_company_address()
    "123 Business Street\nTallinn 10115\nEstonia"

# `get_bank_details`

Get bank details from consolidated Settings.

Reads from `company_bank_details` JSONB with fallback to legacy `billing_bank_*` keys.

# `get_company_info`

Get company information from consolidated Settings.

Reads from `company_info` JSONB with fallback to legacy `billing_company_*` keys.

# `get_country`

Get country by alpha-2 code.

## Examples

    iex> country = CountryData.get_country("EE")
    iex> country.name
    "Estonia"

    iex> CountryData.get_country("XX")
    nil

# `get_country_name`

Get country name.

## Examples

    iex> CountryData.get_country_name("EE")
    "Estonia"

    iex> CountryData.get_country_name("XX")
    nil

# `get_currency_code`

Get country currency code.

## Examples

    iex> CountryData.get_currency_code("EE")
    "EUR"

    iex> CountryData.get_currency_code("GB")
    "GBP"

    iex> CountryData.get_currency_code("US")
    "USD"

# `get_flag`

Get country flag (emoji).

## Examples

    iex> CountryData.get_flag("EE")
    "🇪🇪"

# `get_standard_vat_percent`

Get standard VAT rate as percentage (integer).

Returns rate as percentage (20 = 20%).

## Examples

    iex> CountryData.get_standard_vat_percent("EE")
    20

    iex> CountryData.get_standard_vat_percent("DE")
    19

    iex> CountryData.get_standard_vat_percent("US")
    0

# `get_standard_vat_rate`

Get standard VAT rate for a country as Decimal.

Returns rate in decimal format (0.20 = 20%).
If country not found or has no VAT rates, returns 0.

## Examples

    iex> CountryData.get_standard_vat_rate("EE")
    #Decimal<0.20>

    iex> CountryData.get_standard_vat_rate("DE")
    #Decimal<0.19>

    iex> CountryData.get_standard_vat_rate("US")
    #Decimal<0>

# `get_subdivision_label`

Get the subdivision label for a country.

Returns appropriate label like "State", "Province", "Region", etc.
based on what the country uses for administrative divisions.

## Examples

    iex> CountryData.get_subdivision_label("US")
    "State"

    iex> CountryData.get_subdivision_label("CA")
    "Province"

    iex> CountryData.get_subdivision_label("EE")
    "County"

# `get_vat_rates`

Get all VAT rates with workaround for charlist bug.

Returns map with normalized rates:
- :standard - standard rate (integer)
- :reduced - reduced rates (list of integers)
- :super_reduced - super reduced rate (integer or nil)
- :parking - parking rate (integer or nil)

## Examples

    iex> CountryData.get_vat_rates("EE")
    %{standard: 20, reduced: [9], super_reduced: nil, parking: nil}

    iex> CountryData.get_vat_rates("FR")
    %{standard: 20, reduced: [5.5, 10], super_reduced: 2.1, parking: nil}

    iex> CountryData.get_vat_rates("US")
    nil

# `list_countries`

Get all countries sorted by name.

## Examples

    iex> countries = CountryData.list_countries()
    iex> length(countries)
    250
    iex> hd(countries).name
    "Afghanistan"

# `validate_iban_format`

Validate IBAN format (length based on bank country, not company country).

Bank can be in a different country than the company - this is legal.
Validates format and length based on IBAN's country prefix.

Returns :ok or {:error, reason}.

## Examples

    iex> CountryData.validate_iban_format("EE382200221020145685", "EE")
    :ok

    iex> CountryData.validate_iban_format("DE89370400440532013000", "EE")
    :ok  # German bank for Estonian company is valid

    iex> CountryData.validate_iban_format("DE123", "EE")
    {:error, "IBAN must be 22 characters for DE"}

# `validate_swift_format`

Validate SWIFT/BIC format (8 or 11 characters).

SWIFT codes structure:
- 4 letters: bank code
- 2 letters: country code (ISO 3166)
- 2 characters: location code
- 3 characters (optional): branch code

## Examples

    iex> CountryData.validate_swift_format("HABAEE2X")
    :ok

    iex> CountryData.validate_swift_format("HABAEE2XXXX")
    :ok

    iex> CountryData.validate_swift_format("INVALID")
    {:error, "SWIFT/BIC must be 8 or 11 characters"}

---

*Consult [api-reference.md](api-reference.md) for complete listing*
