Skip to main content

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

  1. Base Currency: All prices are stored in USD in the database
  2. Display Currency: Users can select their preferred display currency
  3. Automatic Conversion: Prices are converted on-the-fly using exchange rates
  4. Exchange Rates: Fetched from the backend and cached locally

Setting Your Currency

1

Navigate to Settings

Open Invenicum and go to SettingsGeneral Settings
2

Select Currency

Find the Currency section and click the currency dropdown
Currently supported currencies are displayed in the dropdown menu with their symbols.
3

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…
4

View Exchange Rate

After selection, you’ll see the current exchange rate:
1 USD = 0.92 EUR
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 CodeSymbolName
USD$US Dollar
EUREuro
GBP£British Pound
JPY¥Japanese Yen
CADC$Canadian Dollar
AUDA$Australian Dollar
MXN$Mexican Peso
BRLR$Brazilian Real
CNY¥Chinese Yuan
INRIndian 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:
{
  "currency": "EUR"
}

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)

Custom Price Input Field

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
  },
)

Build docs developers (and LLMs) love