CoolCMS API

OrderTaxManager
in package

FinalYes

Converts the unified tax engine result into the order VAT snapshot.

The only place where the e-shop deals with VAT: TaxManager decides the rate, treatment and clause; this class writes them into the order snapshot (orders.tax_*, order_items.vat with supply kind, shipping and payment). Consumers (checkout, state transition, invoice) only read the snapshot and never branch on VAT elsewhere.

Checkout order: buildItems(), resolveForOrder() + applyItemTaxes() + applyHeader(), buildShipper() (needs the cart value with VAT for free_from), buildPaymentMethod(), applyAncillaryTaxes(), vouchers, recalculate().

Shipping (and a payment without its own supply kind) is an ancillary supply: it shares the main supply treatment and is allocated proportionally to item bases per rate by OrderCalculator::ancillaryShares(). The invoice and recap use the same split, so they never diverge.

IMPORTANT: TaxManager reads code lists via raw DBAL, so it can be called in the middle of building the order graph. A find() there would call UoW::clear() and break the graph.

Tags
phpstan-import-type

TOrderGraph from OrderCalculator

Table of Contents

Constants

ERROR_CODE  : string = 'taxUnavailable'
Error for the caller: the engine gave no usable answer (missing seller status, rate or supply kind).

Properties

$calculator  : OrderCalculator
$countryManager  : CountryManager
$em  : EntityManagerInterface
$settingContext  : SettingContext
$supplyKindManager  : SupplyKindManager
$taxManager  : TaxManager
$translator  : Translator
$vatIdCheckManager  : VatIdCheckManager

Methods

__construct()  : mixed
applyAncillaryTaxes()  : void
Sets shipping and payment rates. A payment with its own supply kind (`payment_methods.supply_kind_id`) is a separate supply with its own rate; otherwise (and always for shipping) it is an ancillary supply allocated proportionally to item rates.
applyHeader()  : void
Writes the header snapshot: treatment code, rate date and country, clause in the order language (plus Czech), VAT id verification, flags and summary report code. `with_vat` is only derived from `chargeVat` (read by the calculator and the invoice).
applyItemTaxes()  : void
Sets item (and fee) rates from the engine treatment: `vat` is the treatment rate (0 = no VAT charged), `price*WithVat*` are derived. Resolution lines are in the same order as order items.
displayRate()  : string
Returns the rate for display and admin prefill: an anonymous consumer in the payment region country. An unknown supply kind or a seller without status gives `'0.00'` (never a silent default).
findCountryText()  : string|null
Returns the country name from the code list for printing (the ISO code is the single source of truth).
hasUnverifiedVatId()  : bool
Tells whether to show the customer the "VAT id not verified" notice in the order summary.
normalizeCountryCode()  : string|null
Returns the ISO code from the code list (unknown gives `null`, never a silent default).
reRateAtShipping()  : bool
Re-rates an order paid after dispatch (cash on delivery, invoice with due date): on the shipping day only the rate at the dispatch date is resolved again; customer class and treatment code stay from the order. Writes straight to the DB (runs inside a state transition, outside `save()`) and to the entity, so the e-mail and invoice show the new amount, and cash on delivery is collected in the new amount.
resolveForOrder()  : TaxResolution|null
Resolves the VAT treatment of the whole order at the tax date. Returns `null` when the engine gave no usable answer; the caller must not finish the purchase with zero tax but show the customer an error ({@see ERROR_CODE}).
resolveSellerId()  : int|null
Resolves the e-shop seller: order snapshot, then `4/invoicer.sellerId`, then `7/invoice.default.sellerId` (the same chain as the invoice created from an order).
buildContext()  : TaxContext
Builds the engine context: billing and delivery country, company by buyer type, VAT id and company number. The order region is the country fallback.
buildItemLines()  : array<int, TaxLine>
Builds engine lines from order items (base after discounts times quantity). The supply kind comes from the item snapshot; an item without one falls back to the default kind.
isUsable()  : bool
itemBase()  : string
Returns the item base after both discounts times quantity, the same values {@see OrderCalculator::itemsTotals()} uses (ancillary allocation weights and main supply choice).
money()  : numeric-string
Returns a decimal column value for bcmath (non-numeric or empty gives zero).
persistReRate()  : void
Persists the dispatch re-rate with raw UPDATEs of the module tables. It runs inside a state transition, outside `OrderManager::save()`, which would trigger reservations and invoice issuing again.
rateOf()  : string
Returns the treatment rate for the snapshot: `0.00` when no VAT is charged or the engine returned no line.
resolveOwnTreatment()  : TaxTreatment|null
Resolves the treatment of one separate supply (a payment with its own kind) in the same context as the order. Always `CacheOnly`: the VAT id check already ran in the main resolution.
translateNote()  : string|null
Returns the VAT clause in the order language (plus Czech).
withFlag()  : array<int, string>

Constants

ERROR_CODE

Error for the caller: the engine gave no usable answer (missing seller status, rate or supply kind).

public string ERROR_CODE = 'taxUnavailable'

Properties

Methods

__construct()

public __construct(TaxManager $taxManager, SupplyKindManager $supplyKindManager, VatIdCheckManager $vatIdCheckManager, CountryManager $countryManager, OrderCalculator $calculator, Translator $translator, SettingContext $settingContext, EntityManagerInterface $em) : mixed
Parameters
$taxManager : TaxManager
$supplyKindManager : SupplyKindManager
$vatIdCheckManager : VatIdCheckManager
$countryManager : CountryManager
$calculator : OrderCalculator
$translator : Translator
$settingContext : SettingContext
$em : EntityManagerInterface

applyAncillaryTaxes()

Sets shipping and payment rates. A payment with its own supply kind (`payment_methods.supply_kind_id`) is a separate supply with its own rate; otherwise (and always for shipping) it is an ancillary supply allocated proportionally to item rates.

public applyAncillaryTaxes(TOrderGraph $order, TaxResolution $resolution, int $sellerId) : void
Parameters
$order : TOrderGraph
$resolution : TaxResolution
$sellerId : int

applyHeader()

Writes the header snapshot: treatment code, rate date and country, clause in the order language (plus Czech), VAT id verification, flags and summary report code. `with_vat` is only derived from `chargeVat` (read by the calculator and the invoice).

public applyHeader(TOrderGraph $order, TaxResolution $resolution) : void
Parameters
$order : TOrderGraph
$resolution : TaxResolution

applyItemTaxes()

Sets item (and fee) rates from the engine treatment: `vat` is the treatment rate (0 = no VAT charged), `price*WithVat*` are derived. Resolution lines are in the same order as order items.

public applyItemTaxes(TOrderGraph $order, TaxResolution $resolution) : void
Parameters
$order : TOrderGraph
$resolution : TaxResolution

displayRate()

Returns the rate for display and admin prefill: an anonymous consumer in the payment region country. An unknown supply kind or a seller without status gives `'0.00'` (never a silent default).

public displayRate(int|null $paymentRegionId, int|null $supplyKindId[, int|null $sellerId = null ][, DateTimeInterface|null $at = null ]) : string
Parameters
$paymentRegionId : int|null
$supplyKindId : int|null
$sellerId : int|null = null
$at : DateTimeInterface|null = null
Return values
string

findCountryText()

Returns the country name from the code list for printing (the ISO code is the single source of truth).

public findCountryText(string|null $countryCode[, int|null $languageId = null ]) : string|null
Parameters
$countryCode : string|null
$languageId : int|null = null
Return values
string|null

hasUnverifiedVatId()

Tells whether to show the customer the "VAT id not verified" notice in the order summary.

public hasUnverifiedVatId(TOrderGraph $order) : bool
Parameters
$order : TOrderGraph
Return values
bool

normalizeCountryCode()

Returns the ISO code from the code list (unknown gives `null`, never a silent default).

public normalizeCountryCode(string|null $countryCode) : string|null
Parameters
$countryCode : string|null
Return values
string|null

reRateAtShipping()

Re-rates an order paid after dispatch (cash on delivery, invoice with due date): on the shipping day only the rate at the dispatch date is resolved again; customer class and treatment code stay from the order. Writes straight to the DB (runs inside a state transition, outside `save()`) and to the entity, so the e-mail and invoice show the new amount, and cash on delivery is collected in the new amount.

public reRateAtShipping(TOrderGraph $order, DateTimeInterface $shippedAt) : bool
Parameters
$order : TOrderGraph
$shippedAt : DateTimeInterface
Return values
bool —

true when the snapshot changed (rate, totals, tax_date, RESOLVED_AT_SHIPPING flag)

resolveForOrder()

Resolves the VAT treatment of the whole order at the tax date. Returns `null` when the engine gave no usable answer; the caller must not finish the purchase with zero tax but show the customer an error ({@see ERROR_CODE}).

public resolveForOrder(TOrderGraph $order, int $sellerId, bool $binding[, string|null $ip = null ][, DateTimeInterface|null $taxDate = null ]) : TaxResolution|null
Parameters
$order : TOrderGraph
$sellerId : int
$binding : bool

binding submit: the VAT id is verified online on the tax date (once a day per VAT id, IP rate-limited); a cart preview uses stored results only (CacheOnly)

$ip : string|null = null
$taxDate : DateTimeInterface|null = null
Return values
TaxResolution|null

resolveSellerId()

Resolves the e-shop seller: order snapshot, then `4/invoicer.sellerId`, then `7/invoice.default.sellerId` (the same chain as the invoice created from an order).

public resolveSellerId([int|null $orderSellerId = null ]) : int|null
Parameters
$orderSellerId : int|null = null
Return values
int|null

buildContext()

Builds the engine context: billing and delivery country, company by buyer type, VAT id and company number. The order region is the country fallback.

private buildContext(TOrderGraph $order, int $sellerId, bool $binding, string|null $ip, DateTimeInterface|null $taxDate) : TaxContext
Parameters
$order : TOrderGraph
$sellerId : int
$binding : bool
$ip : string|null
$taxDate : DateTimeInterface|null
Return values
TaxContext

buildItemLines()

Builds engine lines from order items (base after discounts times quantity). The supply kind comes from the item snapshot; an item without one falls back to the default kind.

private buildItemLines(TOrderGraph $order) : array<int, TaxLine>
Parameters
$order : TOrderGraph
Return values
array<int, TaxLine>

itemBase()

Returns the item base after both discounts times quantity, the same values {@see OrderCalculator::itemsTotals()} uses (ancillary allocation weights and main supply choice).

private itemBase(TOrderGraph $order, OrderItem $item) : string
Parameters
$order : TOrderGraph
$item : OrderItem
Return values
string

money()

Returns a decimal column value for bcmath (non-numeric or empty gives zero).

private money(string $value) : numeric-string
Parameters
$value : string
Return values
numeric-string

persistReRate()

Persists the dispatch re-rate with raw UPDATEs of the module tables. It runs inside a state transition, outside `OrderManager::save()`, which would trigger reservations and invoice issuing again.

private persistReRate(TOrderGraph $order, int $orderId) : void
Parameters
$order : TOrderGraph
$orderId : int

rateOf()

Returns the treatment rate for the snapshot: `0.00` when no VAT is charged or the engine returned no line.

private rateOf(TaxTreatment|null $treatment) : string
Parameters
$treatment : TaxTreatment|null
Return values
string

resolveOwnTreatment()

Resolves the treatment of one separate supply (a payment with its own kind) in the same context as the order. Always `CacheOnly`: the VAT id check already ran in the main resolution.

private resolveOwnTreatment(TOrderGraph $order, int $sellerId, int $supplyKindId, string $amount, TaxResolution $resolution) : TaxTreatment|null
Parameters
$order : TOrderGraph
$sellerId : int
$supplyKindId : int
$amount : string
$resolution : TaxResolution
Return values
TaxTreatment|null

translateNote()

Returns the VAT clause in the order language (plus Czech).

private translateNote(TOrderGraph $order, string|null $noteKey) : string|null

IMPORTANT: take the language from the order entity (a lazy proxy is enough, getAlias() is only a SELECT), never via LanguageManager::find(): every Api read does UoW::clear(), which would break the identity map in the middle of building the order graph.

Parameters
$order : TOrderGraph
$noteKey : string|null
Return values
string|null

withFlag()

private withFlag(array<int, string>|null $flags, TaxFlag $flag) : array<int, string>
Parameters
$flags : array<int, string>|null
$flag : TaxFlag
Return values
array<int, string>
On this page

Search results