PaymentPriceResolver
in package
Resolves the payment-method price matrix `cms_mod_eshop_payment_method_prices`.
The key is shipperTariffId x paymentMethodId x currencyId; the matrix hangs on the
tariff, not on one tariff price row. shipper_tariff_prices is an append-only time series,
so keying on a price row would lose the payment matrix with every new price generation.
The currency is part of the key because the payment surcharge is entered per currency (no
exchange-rate conversion), so currencyId is required in every resolve*() method.
The table is a time series (date_from): rows with date_from <= $at ($at defaults to
now) are considered and the newest valid row wins.
IMPORTANT: the newest valid row is picked per cell (tariff x method x currency), never as
"the latest generation as a whole". The two-level guard in resolveForTariffs()
($result[$tariffId][$methodId]) is deliberate. Simplifying it to one level (per tariff)
would let a partially filled generation (price changed for one method only) drop all other
methods of that tariff, and they would vanish from checkout.
Prices are without VAT (same convention as shipping price); the rate is applied later in
the order snapshot. ?DateTimeInterface $at has the same purpose as in
ShippingPriceResolver: OrderSnapshotBuilder takes the time once and passes it to
every resolver, so an order at a midnight boundary cannot mix generations.
The free_from / use_free_from threshold works like the shipping one: the surcharge is
waived when the caller passes cartTotal at or above it (compared with bcmath, no float
rounding).
Uses raw DBAL (IN (?) batch), not Doctrine find(), like ShippingPriceResolver.
Table of Contents
Constants
- DECIMAL_SCALE : int = 3
- TABLE : string = 'cms_mod_eshop_payment_method_prices'
Properties
- $em : EntityManagerInterface
Methods
- __construct() : mixed
- resolve() : PaymentPriceResult|null
- resolveForTariff() : array<int, PaymentPriceResult>
- All payment-method rows of one tariff in one currency (e.g. checkout payment step, once the customer picked a shipping tariff).
- resolveForTariffs() : array<int, array<int, PaymentPriceResult>>
- Batch resolve — one SQL for N tariffs (e.g. rendering the whole shipping × payment grid at checkout). Tariffs with no valid row in the given currency are simply absent.
- applyFreeFrom() : array{0: bool, 1: string}
- buildResult() : PaymentPriceResult
- normalizeDecimal() : numeric-string
- toInt() : int
- toStr() : string
Constants
DECIMAL_SCALE
private
int
DECIMAL_SCALE
= 3
TABLE
private
string
TABLE
= 'cms_mod_eshop_payment_method_prices'
Properties
$em read-only
private
EntityManagerInterface
$em
Methods
__construct()
public
__construct(EntityManagerInterface $em) : mixed
Parameters
- $em : EntityManagerInterface
resolve()
public
resolve(int $tariffId, int $paymentMethodId, int $currencyId[, string|null $cartTotal = null ][, DateTimeInterface|null $at = null ]) : PaymentPriceResult|null
Parameters
- $tariffId : int
- $paymentMethodId : int
- $currencyId : int
- $cartTotal : string|null = null
- $at : DateTimeInterface|null = null
-
time of validity; null = now. The order snapshot passes a single shared instant into every resolver so a checkout at a generation boundary cannot mix prices from two generations.
Return values
PaymentPriceResult|nullresolveForTariff()
All payment-method rows of one tariff in one currency (e.g. checkout payment step, once the customer picked a shipping tariff).
public
resolveForTariff(int $tariffId, int $currencyId[, string|null $cartTotal = null ][, DateTimeInterface|null $at = null ]) : array<int, PaymentPriceResult>
Parameters
- $tariffId : int
- $currencyId : int
- $cartTotal : string|null = null
- $at : DateTimeInterface|null = null
-
time of validity; NULL = now (see resolve())
Return values
array<int, PaymentPriceResult> —keyed by paymentMethodId; available is not
filtered here, the caller decides what to offer
resolveForTariffs()
Batch resolve — one SQL for N tariffs (e.g. rendering the whole shipping × payment grid at checkout). Tariffs with no valid row in the given currency are simply absent.
public
resolveForTariffs(array<string|int, int> $tariffIds, int $currencyId[, string|null $cartTotal = null ][, DateTimeInterface|null $at = null ]) : array<int, array<int, PaymentPriceResult>>
IMPORTANT: ordering tariff ASC, method ASC, date_from DESC plus the guard
if (isset($result[$tariffId][$methodId])) continue; is first-hit-wins per (tariff,
method) pair, on purpose; see the class docblock. A guard on $tariffId alone would
let a partially filled generation drop untouched payment methods.
Parameters
- $tariffIds : array<string|int, int>
- $currencyId : int
- $cartTotal : string|null = null
- $at : DateTimeInterface|null = null
-
time of validity; NULL = now (see resolve())
Return values
array<int, array<int, PaymentPriceResult>> —keyed by [tariffId][paymentMethodId]
applyFreeFrom()
private
applyFreeFrom(string $price, string|null $freeFrom, bool $useFreeFrom, string|null $cartTotal) : array{0: bool, 1: string}
Parameters
- $price : string
- $freeFrom : string|null
- $useFreeFrom : bool
- $cartTotal : string|null
Return values
array{0: bool, 1: string} —[isFree, priceAfterFreeFrom]
buildResult()
private
buildResult(array<string, mixed> $row, int $tariffId, int $methodId, string|null $cartTotal) : PaymentPriceResult
Parameters
- $row : array<string, mixed>
- $tariffId : int
- $methodId : int
- $cartTotal : string|null
Return values
PaymentPriceResultnormalizeDecimal()
private
normalizeDecimal(string $value) : numeric-string
Parameters
- $value : string
Return values
numeric-stringtoInt()
private
toInt(mixed $value) : int
Parameters
- $value : mixed
Return values
inttoStr()
private
toStr(mixed $value) : string
Parameters
- $value : mixed