- 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>
This commit is contained in:
55
pos/services/currency.py
Normal file
55
pos/services/currency.py
Normal file
@@ -0,0 +1,55 @@
|
||||
"""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
|
||||
Reference in New Issue
Block a user