Currency Exchange
Converts supplier prices to market currency when creating offers. Rates are fetched daily from the European Central Bank via Frankfurter API.
When Conversion Happens
Section titled “When Conversion Happens”The OfferObserver automatically converts land_base_price when:
- Offer has a
supplier_tour_rate_id(linked to a supplier rate) - Service rate price currency differs from market’s
default_currency_code - An exchange rate exists for the currency pair
The source currency is resolved from supplier_service_rate_prices (the actual records that compose the land price), with a fallback to the supplier’s currency.
No conversion occurs if currencies match. Throws an error if currencies differ but no exchange rate exists.
Syncing Exchange Rates
Section titled “Syncing Exchange Rates”Rates sync daily via scheduler. Manual sync:
# Sync today's rates (base: EUR)php artisan currency:sync-rates
# Sync specific datephp artisan currency:sync-rates --date=2025-01-15
# Different base currencyphp artisan currency:sync-rates --base=USDSource: backend/app/Console/Commands/SyncExchangeRatesCommand.php
Key Models
Section titled “Key Models”| Model | Purpose |
|---|---|
CurrencyExchangeRate | Stores rates with inverse calculation support |
Currency | Reference currencies (EUR, USD, GBP, etc.) |
SupplierServiceRatePrice | Stores service price + currency per room type |
Observers
Section titled “Observers”SupplierObserver: When a supplier’s currency_id changes, cascades the update to all related SupplierTourRateRoomPrice records.
OfferObserver: Converts land_base_price from service rate price currency to market currency during offer creation.
Configuration
Section titled “Configuration”Exchange rates use worksome/exchange package configured in config/exchange.php.
Required: Active currencies must exist in currencies table before syncing.