Skip to content

Currency Exchange

Converts supplier prices to market currency when creating offers. Rates are fetched daily from the European Central Bank via Frankfurter API.

The OfferObserver automatically converts land_base_price when:

  1. Offer has a supplier_tour_rate_id (linked to a supplier rate)
  2. Room price currency differs from market’s default_currency_code
  3. An exchange rate exists for the currency pair

No conversion occurs if currencies match or if no rate exists (throws error).

Rates sync daily via scheduler. Manual sync:

Terminal window
# Sync today's rates (base: EUR)
php artisan currency:sync-rates
# Sync specific date
php artisan currency:sync-rates --date=2025-01-15
# Different base currency
php artisan currency:sync-rates --base=USD

Source: backend/app/Console/Commands/SyncExchangeRatesCommand.php

ModelPurpose
CurrencyExchangeRateStores rates with inverse calculation support
CurrencyReference currencies (EUR, USD, GBP, etc.)
SupplierTourRateRoomPriceStores price + currency for each room type

SupplierObserver: When a supplier’s currency_id changes, cascades the update to all related SupplierTourRateRoomPrice records.

OfferObserver: Converts land_base_price from room price currency to market currency during offer creation.

Exchange rates use worksome/exchange package configured in config/exchange.php.

Required: Active currencies must exist in currencies table before syncing.

  • Suppliers - Supplier currency assignment
  • Offers - Offer pricing calculation
  • Source: backend/app/Services/CurrencyExchangeService.php