Overview
Invenicum supports multi-currency inventory management with automatic currency conversion and real-time exchange rates. Store values in USD and display them in your preferred currency.
How It Works
- Base Currency: All prices are stored in USD in the database
- Display Currency: Users can select their preferred display currency
- Automatic Conversion: Prices are converted on-the-fly using exchange rates
- Exchange Rates: Fetched from the backend and cached locally
Setting Your Currency
Navigate to Settings
Open Invenicum and go to Settings → General Settings
Select Currency
Find the Currency section and click the currency dropdownCurrently supported currencies are displayed in the dropdown menu with their symbols.
Choose Your Currency
Select your preferred currency from the list:
- USD (United States Dollar) $
- EUR (Euro) €
- GBP (British Pound) £
- JPY (Japanese Yen) ¥
- MXN (Mexican Peso) $
- And more…
View Exchange Rate
After selection, you’ll see the current exchange rate:This rate is used for all conversions in the app.
Currency Configuration
User Preferences Model
Currency settings are stored in the user preferences:
File: lib/data/models/user_preferences.dart:6
class UserPreferences {
final String currency; // Selected currency code (e.g., 'USD', 'EUR')
final Map<String, double>? exchangeRates; // Current exchange rates
// Default values
UserPreferences({
this.currency = 'USD',
this.exchangeRates,
// ...
});
}
Exchange Rates
Exchange rates are fetched from the backend and stored locally:
{
"EUR": 0.92,
"GBP": 0.79,
"JPY": 149.50,
"MXN": 17.25,
// ...
}
Price Conversion
Automatic Conversion
All price fields are automatically converted using the PreferencesProvider:
File: lib/providers/preferences_provider.dart:123-133
double convertPrice(double amount) {
final rates = _prefs.exchangeRates;
final selectedCurrency = _prefs.currency;
// If USD or no rates available, return as-is
if (selectedCurrency == 'USD' || rates == null) {
return amount;
}
final double rate = rates[selectedCurrency] ?? 1.0;
return amount * rate;
}
Display Components
Use the PriceDisplayWidget for consistent price formatting:
File: lib/widgets/ui/price_display_widget.dart:5-36
PriceDisplayWidget(
value: item.marketValue, // Value in USD from database
fontSize: 16,
color: Colors.green,
)
// Output: "€ 92.00" (if EUR selected)
The widget automatically:
- Converts from USD to selected currency
- Applies the correct currency symbol
- Formats with 2 decimal places
Currency Symbols
Currency symbols are mapped in the preferences provider:
File: lib/providers/preferences_provider.dart:195-210
| Currency Code | Symbol | Name |
|---|
| USD | $ | US Dollar |
| EUR | € | Euro |
| GBP | £ | British Pound |
| JPY | ¥ | Japanese Yen |
| CAD | C$ | Canadian Dollar |
| AUD | A$ | Australian Dollar |
| MXN | $ | Mexican Peso |
| BRL | R$ | Brazilian Real |
| CNY | ¥ | Chinese Yuan |
| INR | ₹ | Indian Rupee |
Price History & Charts
Price history charts respect the selected currency:
File: lib/widgets/ui/price_history_chart_widget.dart:32-100
// Chart title shows selected currency
"Price Evolution (${preferencesProvider.selectedCurrency})"
// Y-axis labels use currency symbol
'${preferencesProvider.getSymbolForCurrency(
preferencesProvider.selectedCurrency
)}${value.toInt()}'
// Data points are converted
preferencesProvider.convertPrice(point.price)
Custom Fields with Price Type
Custom fields of type price are automatically handled:
File: lib/screens/assets/local_widgets/custom_fields_section.dart:221-222
// Input fields show currency prefix
prefix: fieldDef.type == CustomFieldType.price
? '${preferences.getSymbolForCurrency(
preferences.selectedCurrency
)} '
: null,
File: lib/screens/assets/asset_edit_screen.dart:340-346
// Price values are converted for editing
if (fieldDef.type == CustomFieldType.price && value != null) {
double dbValue = value;
double localValue = preferences.convertPrice(dbValue);
_controllers[fieldDef.id]!.text = localValue.toStringAsFixed(2);
}
Backend Integration
Update Currency
Currency changes are synchronized with the backend:
File: lib/data/services/preferences_service.dart:37-39
Future<void> updateCurrency(String currencyCode) async {
await _dio.put('/preferences/currency',
data: {'currency': currencyCode}
);
}
API Endpoint: PUT /api/v1/preferences/currency
Request Body:
Localization File Reference
File: lib/l10n/app_en.arb:274-433
Relevant translations:
{
"currency": "Currency",
"selectApplicationCurrency": "Select application currency",
"averageMarketValue": "Average market price",
"totalMarketValue": "Total Market Value",
"totalSpending": "Total Economic Investment"
}
Best Practices
Consistent Storage: Always store prices in USD in the database. This ensures data consistency and simplifies multi-currency support.
Exchange Rate Updates: Exchange rates are fetched from the backend. Ensure your backend has a reliable source for current rates.
Price Entry: When users enter prices, they input in their selected currency. The app converts to USD before saving to the database.
- Preferences Provider:
lib/providers/preferences_provider.dart:17-210
- Price Display Widget:
lib/widgets/ui/price_display_widget.dart
- Currency Dropdown:
lib/screens/preferences/local_widgets/currency_dropdown_widget.dart
- User Preferences Model:
lib/data/models/user_preferences.dart
Example Use Cases
Display Total Inventory Value
// Get preferences provider
final prefs = context.read<PreferencesProvider>();
// Total value in USD from database
double totalUSD = 10000.0;
// Convert to user's currency
double localValue = prefs.convertPrice(totalUSD);
// Display with symbol
String display = '${prefs.getSymbolForCurrency(
prefs.selectedCurrency
)} ${localValue.toStringAsFixed(2)}';
// Result: "€ 9,200.00" (if EUR selected)
TextField(
decoration: InputDecoration(
labelText: 'Market Value',
prefixText: prefs.getSymbolForCurrency(
prefs.selectedCurrency
) + ' ',
),
keyboardType: TextInputType.number,
onChanged: (value) {
// Value entered in user's currency
double localAmount = double.parse(value);
// Convert to USD for storage
double usdAmount = localAmount /
(prefs.exchangeRates?[prefs.selectedCurrency] ?? 1.0);
// Save usdAmount to database
},
)