PhoenixKit.Modules.Billing.CountryData (phoenix_kit v1.7.71)

Copy Markdown View Source

Wrapper for BeamLabCountries with billing-specific functions.

Provides a convenient API for working with country data in a billing context: 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"

Summary

Functions

Get list of countries for select dropdown.

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

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

Get list of EU countries.

Get list of EU countries for select dropdown.

Check if country is an EU member.

Check if country with given code exists.

Format company address from Settings for document printing.

Get bank details from consolidated Settings.

Get company information from consolidated Settings.

Get country by alpha-2 code.

Get country name.

Get country currency code.

Get country flag (emoji).

Get standard VAT rate as percentage (integer).

Get standard VAT rate for a country as Decimal.

Get the subdivision label for a country.

Get all VAT rates with workaround for charlist bug.

Get all countries sorted by name.

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

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

Functions

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?(country_code)

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?(country_code)

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?(country_code)

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(code)

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(country_code)

Get country name.

Examples

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

iex> CountryData.get_country_name("XX")
nil

get_currency_code(country_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(country_code)

Get country flag (emoji).

Examples

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

get_standard_vat_percent(country_code)

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(country_code)

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(alpha2)

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(country_code)

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(iban, arg2)

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(swift)

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"}