Skip to content

Currency Management (Admin)

Flow ID: AD-36 Module(s): eshop, Currency domain Complexity: Low Last Updated: 2026-04-04

Business Overview

Currency management provides CRUD operations for the shop's supported currencies. Each currency has an ISO 4217 code, numeric code, display symbol, exchange rate relative to the base currency, and an active flag. The default currency (loaded at controller initialization) cannot be deactivated.

Currencies are used throughout the storefront for price display and conversion, in the cart and checkout flows, and in order records. The admin interface is a straightforward form-based CRUD, while the modern REST API provides full programmatic access with create/update/delete capabilities.

API Reference

REST Endpoints (Modern Layer)

MethodPathActionAuth
GET/rest/currency/currencyList currencies (paginated, filterable)JWT
GET/rest/currency/currency/{id}Get single currency by IDJWT
GET/rest/currency/currency/itemGet single currency by filterJWT
POST/rest/currency/currencyCreate new currencyJWT
POST/rest/currency/currency/{id}Update existing currencyJWT
DELETE/rest/currency/currency/{id}Delete currencyJWT

Filters: filter[id] (exact), filter[code] (exact), filter[active] (exact), filter[symbol] (partial) Sorts: id, code, rate, active

Admin Endpoints (Legacy Layer)

RouteControllerMethodDescription
currencies_adminAdv_currencies_adminindex()List all currencies
currencies_admin/addAdv_currencies_adminadd()Create currency form
currencies_admin/edit/{id}Adv_currencies_adminedit($id)Edit currency form

Code Flow

Admin CRUD

Adv_currencies_admin::add() / edit()
  |
  +--> POST submit → validation()
  |    (code: required, symbol: required, rate: required)
  |
  +--> Build currency array: {code, num, symbol, rate, active}
  |
  +--> For edit: if ($this->defaultCurrency->id == $id) → force active=true
  |
  +--> currencies_model->add($currency) or ->edit($id, $currency)
  +--> Redirect to currencies_admin

Storefront Currency Loading

Adv_front_controller::__construct()
  |
  +--> $this->defaultCurrency = getDefaultCurrency()
  +--> $this->activeCurrencies = currencies_model->getActiveCurrencies()
  |    (indexed by ID)
  |
  +--> If customer session has currencyId:
       $this->currentCurrency = $this->activeCurrencies[$currencyId]

REST CRUD

Currency Controller (HandlesRestfulActions + HandlesWriteActions)
  |
  +--> index(): Service->all(ListRequest) → Collection
  +--> show($id): Service->get($id) → Resource
  +--> store(): WriteService->create(data) → Resource (201)
  +--> update($id): WriteService->update($id, data) → Resource
  +--> destroy($id): WriteService->delete($id) → 200

Domain Layer

Modern Domain (src/)

FileResponsibility
src/Domains/Currency/Currency/Repository/Repository.phpRead repository (table: currencies)
src/Domains/Currency/Currency/Repository/WriteRepository.phpWrite repository
src/Domains/Currency/Currency/WriteData.phpDTO: code, num, symbol, rate, active
src/Domains/Currency/Currency/ListRequest.phpFilter/sort definitions

REST Layer (src/)

FileResponsibility
src/Rest/Currency/Controllers/Currency.phpREST controller with OpenAPI annotations
src/Rest/Currency/Resources/Currency/Resource.phpJSON resource: {id, code, num, symbol, rate, active}
src/Rest/Currency/Resources/Currency/Collection.phpCollection wrapper

Legacy Layer (ecommercen/)

FileResponsibility
ecommercen/eshop/controllers/Adv_currencies_admin.phpAdmin CRUD controller
ecommercen/eshop/models/Adv_currencies_model.phpModel: getRecords(), getActiveCurrencies(), add(), edit()

Architecture

Admin UI                        REST API                     Storefront
  |                               |                             |
  Adv_currencies_admin     Currency Controller            Adv_front_controller
  |                               |                             |
  Adv_currencies_model      Currency\Service              Adv_currencies_model
  (legacy model)            Currency\WriteService          ->getActiveCurrencies()
  |                               |                             |
  v                               v                             v
  currencies table  <================================>  currencies table

The Adv_admin_controller base class loads $this->defaultCurrency via getDefaultCurrency() so all admin controllers have access to the default currency for display and protection logic.

Data Model

currencies

ColumnTypeDescription
idint(11)PK, auto-increment
codevarchar(3)ISO 4217 alpha code (e.g., EUR, USD)
numvarchar(3)ISO 4217 numeric code (e.g., 978)
symbolvarchar(25)Display symbol (e.g., EUR, $)
ratedecimal(11,4)Exchange rate relative to base currency
activetinyint(1)1 = available in storefront, 0 = hidden

Unique index: currency_code on code

Resource Response

json
{
  "id": 1,
  "code": "EUR",
  "num": "978",
  "symbol": "EUR",
  "rate": 1.0,
  "active": true
}

Configuration

  • RBAC: Admin requires AUTH_ROLE_ADVISABLE, AUTH_ROLE_ADMIN, or AUTH_ROLE_PRODUCTS
  • Default currency: Loaded by getDefaultCurrency() helper at controller initialization
  • Admin menu: Registered in application/config/admin_menu.php under the settings section at route currencies_admin
  • Routes: application/config/routes.php lines 666-669 map currencies_admin to eshop/currencies_admin

Client Extension Points

  • Override admin controller: In a client repo, create application/controllers/eshop/Currencies_admin.php
  • Custom exchange rate source: Override the model or add a job that updates rates from an external API
  • REST extensions: Extend via Custom\Domains\Currency\ in client repos

Business Rules

  1. Default currency protection: When editing the default currency, active is forced to true regardless of form input
  2. Unique currency code: The currency_code unique index prevents duplicate ISO codes at the database level
  3. Rate is relative: The base currency should have rate = 1.0000; other currencies use the exchange rate for conversion
  4. Active filtering: Only currencies with active = 1 are shown to storefront customers (getActiveCurrencies())
  5. No delete in admin: The legacy admin controller does not expose a delete action (currencies can be deactivated instead); deletion is available only via the REST API