PriceResolver
in package
Resolves the currently valid sale price of product sets from the read-only view `cms_mod_eshop_product_set_current_prices`.
The price table is an append-only time series; the view keeps published_time <= NOW(), so
scheduled future prices activate without a cron. Reads use raw DBAL (IN (?) array
binding), not Doctrine find(), so a batch costs one query regardless of N (listing hot
path) and nothing detaches managed entities when called from a save hook.
IMPORTANT: the returned price is the base without VAT. The resolver does not know the VAT rate; the caller adds it (OrderSnapshotBuilder for orders).
Quantity tiers: the base tier is stored as from_amount = 0 ("1+"); the highest
from_amount <= requestedAmount wins (the view yields one row per tier).
?DateTimeInterface $at: the view hardwires NOW(), so pricing "as of time T" cannot use
it. With an explicit $at the resolver reads a derived table with the same semantics
(MAX(published_time) <= :at per set, group, currency and from_amount). The order
snapshot takes the time once and passes it to every resolver, so an order at a generation
boundary cannot mix a product from the old generation with shipping from the new one.
Without $at (catalog) the cheap view path is used.
Table of Contents
Constants
- TABLE : string = 'cms_mod_eshop_product_set_prices'
- VIEW : string = 'cms_mod_eshop_product_set_current_prices'
Properties
- $em : EntityManagerInterface
Methods
- __construct() : mixed
- resolveNextPriceTimes() : array<int, string>
- Returns the nearest future `published_time` (> `NOW()`) among the prices of each given set, i.e. the end of a deal for the countdown in `LastProductList::renderDeal()`.
- resolvePrice() : ProductSetPriceResult|null
- resolvePriceBatch() : array<int, ProductSetPriceResult>
- Batch resolve — one SQL for the whole listing.
- toInt() : int
- Casts a DBAL scalar (mixed) to int, guarded.
- toStr() : string
Constants
TABLE
private
string
TABLE
= 'cms_mod_eshop_product_set_prices'
VIEW
private
string
VIEW
= 'cms_mod_eshop_product_set_current_prices'
Properties
$em read-only
private
EntityManagerInterface
$em
Methods
__construct()
public
__construct(EntityManagerInterface $em) : mixed
Parameters
- $em : EntityManagerInterface
resolveNextPriceTimes()
Returns the nearest future `published_time` (> `NOW()`) among the prices of each given set, i.e. the end of a deal for the countdown in `LastProductList::renderDeal()`.
public
resolveNextPriceTimes(array<string|int, int> $productSetIds[, int|null $currencyId = null ]) : array<int, string>
Reads the table, not the view (the view is <= NOW() only); the DB session runs in UTC
(see ProductSetManager::nowUtc()), so NOW() and the stored UTC digit string compare
without time zone changes. One SQL with GROUP BY for the whole batch: callers must
not loop with one bridge call per candidate. Without $currencyId the nearest future
price across currencies is taken; with it, only rows of that currency. A set with no
future price is absent from the result (no countdown is rendered).
Parameters
- $productSetIds : array<string|int, int>
- $currencyId : int|null = null
Return values
array<int, string> —setId => nearest future published_time (UTC digit string)
resolvePrice()
public
resolvePrice(int $productSetId, int $userGroupId, int $currencyId[, int $amount = 1 ][, DateTimeInterface|null $at = null ]) : ProductSetPriceResult|null
Parameters
- $productSetId : int
- $userGroupId : int
- $currencyId : int
- $amount : int = 1
- $at : DateTimeInterface|null = null
Return values
ProductSetPriceResult|nullresolvePriceBatch()
Batch resolve — one SQL for the whole listing.
public
resolvePriceBatch(array<string|int, int> $productSetIds, int $userGroupId, int $currencyId[, int $amount = 1 ][, DateTimeInterface|null $at = null ]) : array<int, ProductSetPriceResult>
Parameters
- $productSetIds : array<string|int, int>
- $userGroupId : int
- $currencyId : int
- $amount : int = 1
- $at : DateTimeInterface|null = null
-
time of price validity; null = now (view path). The order snapshot passes a single shared instant.
Return values
array<int, ProductSetPriceResult> —keyed by productSetId (sets without a matching price are absent)
toInt()
Casts a DBAL scalar (mixed) to int, guarded.
private
toInt(mixed $value) : int
Parameters
- $value : mixed
Return values
inttoStr()
private
toStr(mixed $value) : string
Parameters
- $value : mixed