- i18n.js with 130+ translation keys for es/en, loaded in all 11 templates - sidebar.js uses t() for all nav labels, adds MX/US language toggle - app-init.js role labels use i18n - currency.py service with convert() and format_currency() - config.py adds DEFAULT_CURRENCY and EXCHANGE_RATE_USD_MXN settings - config_bp.py adds GET/PUT /pos/api/config/currency endpoints - config.html adds currency/exchange-rate section (Section 8) - config.js adds loadCurrency/saveCurrency with localStorage sync - pos.js fmt() reads pos_currency from localStorage for USD/MXN display Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
56 lines
1.7 KiB
Python
56 lines
1.7 KiB
Python
"""Multi-currency support for border refaccionarias.
|
|
|
|
Supports MXN and USD with configurable exchange rate.
|
|
"""
|
|
|
|
from config import DEFAULT_CURRENCY, EXCHANGE_RATE_USD_MXN
|
|
|
|
CURRENCIES = {
|
|
'MXN': {'symbol': '$', 'name': 'Peso Mexicano', 'name_en': 'Mexican Peso', 'decimals': 2},
|
|
'USD': {'symbol': 'US$', 'name': 'Dolar Estadounidense', 'name_en': 'US Dollar', 'decimals': 2},
|
|
}
|
|
|
|
|
|
def convert(amount, from_currency, to_currency, rate=None):
|
|
"""Convert an amount between currencies.
|
|
|
|
Args:
|
|
amount: The numeric amount to convert.
|
|
from_currency: Source currency code ('MXN' or 'USD').
|
|
to_currency: Target currency code ('MXN' or 'USD').
|
|
rate: Optional custom exchange rate (USD->MXN). Defaults to config value.
|
|
|
|
Returns:
|
|
The converted amount, rounded to 2 decimals.
|
|
"""
|
|
if from_currency == to_currency:
|
|
return amount
|
|
if rate is None:
|
|
rate = EXCHANGE_RATE_USD_MXN
|
|
if from_currency == 'USD' and to_currency == 'MXN':
|
|
return round(amount * rate, 2)
|
|
if from_currency == 'MXN' and to_currency == 'USD':
|
|
return round(amount / rate, 2)
|
|
return amount
|
|
|
|
|
|
def format_currency(amount, currency='MXN'):
|
|
"""Format an amount with the appropriate currency symbol.
|
|
|
|
Args:
|
|
amount: Numeric value.
|
|
currency: Currency code.
|
|
|
|
Returns:
|
|
Formatted string like '$1,234.56' or 'US$1,234.56'.
|
|
"""
|
|
info = CURRENCIES.get(currency, CURRENCIES['MXN'])
|
|
return f"{info['symbol']}{amount:,.{info['decimals']}f}"
|
|
|
|
|
|
def get_currency_info(code=None):
|
|
"""Return currency metadata dict. If code is None, return all."""
|
|
if code:
|
|
return CURRENCIES.get(code)
|
|
return CURRENCIES
|