Packages
phoenix_kit
1.7.80
1.7.207
1.7.206
1.7.205
1.7.204
1.7.203
1.7.202
1.7.201
1.7.200
1.7.199
1.7.198
1.7.197
1.7.196
1.7.194
1.7.193
1.7.192
1.7.191
1.7.190
1.7.189
1.7.187
1.7.186
1.7.185
1.7.184
1.7.183
1.7.182
1.7.181
1.7.180
1.7.179
1.7.178
1.7.177
1.7.176
1.7.175
1.7.174
1.7.173
1.7.172
1.7.171
1.7.170
1.7.169
1.7.168
1.7.167
1.7.166
1.7.165
1.7.164
1.7.162
1.7.161
1.7.160
1.7.159
1.7.157
1.7.156
1.7.155
1.7.154
1.7.153
1.7.152
1.7.151
1.7.150
1.7.149
1.7.146
1.7.145
1.7.144
1.7.143
1.7.138
1.7.133
1.7.132
1.7.131
1.7.130
1.7.128
1.7.126
1.7.125
1.7.121
1.7.120
1.7.119
1.7.118
1.7.117
1.7.116
1.7.115
1.7.114
1.7.113
1.7.112
1.7.111
1.7.110
1.7.109
1.7.108
1.7.107
1.7.106
1.7.105
1.7.104
1.7.103
1.7.102
1.7.101
1.7.100
1.7.99
1.7.98
1.7.97
1.7.96
1.7.95
1.7.94
1.7.93
1.7.92
1.7.91
1.7.90
1.7.89
1.7.88
1.7.87
1.7.86
1.7.85
1.7.84
1.7.83
1.7.82
1.7.81
1.7.80
1.7.79
1.7.78
1.7.77
1.7.76
1.7.75
1.7.74
1.7.71
1.7.70
1.7.69
1.7.66
1.7.65
1.7.64
1.7.63
1.7.62
1.7.61
1.7.59
1.7.58
1.7.57
1.7.56
1.7.55
1.7.54
1.7.53
1.7.52
1.7.51
1.7.49
1.7.44
1.7.43
1.7.42
1.7.41
1.7.39
1.7.38
1.7.37
1.7.36
1.7.34
1.7.33
1.7.31
1.7.30
1.7.29
1.7.28
1.7.27
1.7.26
1.7.25
1.7.24
1.7.23
1.7.22
1.7.21
1.7.20
1.7.19
1.7.18
1.7.17
1.7.16
1.7.15
1.7.14
1.7.13
1.7.12
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.20
1.6.19
1.6.18
1.6.17
1.6.16
1.6.15
1.6.14
1.6.13
1.6.12
1.6.11
1.6.10
1.6.9
1.6.8
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.5.2
1.5.1
1.5.0
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.10
1.2.9
1.2.8
1.2.7
1.2.5
1.2.4
1.2.2
1.2.1
1.2.0
1.1.0
1.0.0
A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more
Current section
Files
Jump to
Current section
Files
lib/modules/billing/web/settings.ex
defmodule PhoenixKit.Modules.Billing.Web.Settings do
@moduledoc """
Billing settings LiveView for the billing module.
Provides configuration interface for billing module settings.
Company and bank information is now managed in Organization Settings.
"""
use PhoenixKitWeb, :live_view
alias PhoenixKit.Modules.Billing
alias PhoenixKit.Modules.Billing.CountryData
alias PhoenixKit.Settings
alias PhoenixKit.Utils.Routes
@impl true
def mount(_params, _session, socket) do
project_title = Settings.get_project_title()
billing_enabled = Billing.enabled?()
socket =
socket
|> assign(:page_title, "Billing Settings")
|> assign(:project_title, project_title)
|> assign(:url_path, Routes.path("/admin/billing/settings"))
|> assign(:billing_enabled, billing_enabled)
|> load_settings()
{:ok, socket}
end
@impl true
def handle_params(_params, _url, socket) do
{:noreply, socket}
end
defp load_settings(socket) do
# Get company info from consolidated Settings (with fallback to legacy keys)
company_info = CountryData.get_company_info()
bank_details = CountryData.get_bank_details()
company_country = company_info["country"] || ""
socket
# General settings
|> assign(:default_currency, Settings.get_setting("billing_default_currency", "EUR"))
|> assign(:invoice_prefix, Settings.get_setting("billing_invoice_prefix", "INV"))
|> assign(:order_prefix, Settings.get_setting("billing_order_prefix", "ORD"))
|> assign(:receipt_prefix, Settings.get_setting("billing_receipt_prefix", "RCP"))
|> assign(:invoice_due_days, Settings.get_setting("billing_invoice_due_days", "14"))
|> assign(:tax_enabled, Settings.get_setting("billing_tax_enabled", "false") == "true")
|> assign(:tax_rate, Settings.get_setting("billing_default_tax_rate", "0"))
# Company info (from consolidated source)
|> assign(:company_info, company_info)
|> assign(:company_address_formatted, CountryData.format_company_address())
|> assign(:company_country_name, get_country_name(company_country))
|> assign(:company_country, company_country)
# For suggested tax rate
|> assign_suggested_tax_rate()
# Bank details (from consolidated source)
|> assign(:bank_details, bank_details)
end
# Helper to get country name from code
defp get_country_name(""), do: ""
defp get_country_name(nil), do: ""
defp get_country_name(country_code) do
case BeamLabCountries.get(country_code) do
nil -> country_code
country -> country.name
end
end
@impl true
def handle_event("save_general", params, socket) do
# Convert checkbox value to "true"/"false" string
tax_enabled = if params["tax_enabled"] == "true", do: "true", else: "false"
settings = [
{"billing_default_currency", params["default_currency"]},
{"billing_invoice_prefix", params["invoice_prefix"]},
{"billing_order_prefix", params["order_prefix"]},
{"billing_receipt_prefix", params["receipt_prefix"]},
{"billing_invoice_due_days", params["invoice_due_days"]},
{"billing_tax_enabled", tax_enabled},
{"billing_default_tax_rate", params["tax_rate"]}
]
Enum.each(settings, fn {key, value} ->
Settings.update_setting(key, value)
end)
{:noreply,
socket
|> load_settings()
|> put_flash(:info, "General settings saved")}
end
@impl true
def handle_event("tax_rate_changed", %{"tax_rate" => tax_rate}, socket) do
current_rate = parse_tax_rate(tax_rate)
country_code = socket.assigns.company_country
suggested_rate =
if country_code != "" do
rate = CountryData.get_standard_vat_percent(country_code)
if rate == current_rate, do: nil, else: rate
else
nil
end
{:noreply,
socket
|> assign(:tax_rate, tax_rate)
|> assign(:suggested_tax_rate, suggested_rate)}
end
@impl true
def handle_event("apply_suggested_tax", _params, socket) do
case socket.assigns.suggested_tax_rate do
nil ->
{:noreply, socket}
rate ->
{:noreply,
socket
|> assign(:tax_rate, to_string(rate))
|> assign(:suggested_tax_rate, nil)}
end
end
# Suggested tax rate helper
defp assign_suggested_tax_rate(socket) do
country_code = socket.assigns.company_country
current_rate = parse_tax_rate(socket.assigns.tax_rate)
suggested_rate =
if country_code != "" do
rate = CountryData.get_standard_vat_percent(country_code)
# Hide suggestion if it matches current rate
if rate == current_rate, do: nil, else: rate
else
nil
end
assign(socket, :suggested_tax_rate, suggested_rate)
end
defp parse_tax_rate(rate) when is_binary(rate) do
case Float.parse(rate) do
{value, _} -> if value == trunc(value), do: trunc(value), else: value
:error -> 0
end
end
defp parse_tax_rate(rate) when is_number(rate), do: rate
defp parse_tax_rate(_), do: 0
end