Tax Management
Within the Price Systems there is a Tax Management component to deal with all sorts of taxes. So it is possible to calculate and print out taxes as needed.
The Tax Management is quite transparent and should not affect the system very deeply. As a result - if not necessary (e.g. because you have a B2B system, etc.) - you don't need to deal with taxes in E-Commerce Framework at all. Also, if you have your very own tax implementation, this should be perfectly possible and you should need to not deal with the Tax Management in the E-Commerce Framework at all. Just use all the default values and every thing should be fine.
Components of Tax Management
If you need to deal with taxes following components are important to know of:
Tax Configuration with OnlineShopTaxClass
The configuration of taxes is done with OnlineShopTaxClass
Pimcore objects within in the Pimcore Backend UI. The actual
tax calculation is always based on the configuration of such a tax class. So, tax configurations for different countries
and product groups can be established. The tax calculation is always based on one tax class, a combination of tax classes
is not possible.
The configuration concludes a TaxEntryCombinationMode (combine
and one after another
) and one or more tax entries
with a name and a tax rate in percent.
The selection of the correct tax class (for a certain country and a certain product group) is done by the Price System (see next section).
Tax Class Selection with Price Systems
The Price System decides for each product and environment which tax class to take for tax calculation. Therefore following two methods need to be implemented:
getTaxClassForProduct
: Should return tax class for given product. The default implementation returns a generic tax class based on the Website Settings or - if not set - an empty tax class.getTaxClassForPriceModification
: See later for more information.
The logic behind the tax class selection can be of any complexity. It can be based on a simple Website Setting (for one tax class fits all), or based on a complex matrix with product group, sending country, delivering country and several other aspects.
Tax Calculation with TaxCalculationService
The actual tax calculation is done in the TaxCalculationService::updateTaxes(PriceInterface $price, $calculationMode = self::CALCULATION_FROM_NET)
method. It updates taxes in given price object by using its tax entries, tax combination mode and net or gross amount
based on the given $calculationMode
.
The calculation is done by the framework in two places:
- By Price Systems when creating the
PriceInfo
objects - By
PriceInterface
objects whensetAmount
,setGrossAmount
orsetNetAmount
is called and$recalc
is set to true.
The PriceInterface
object
Every price in the E-Commerce Framework comes down to an PriceInterface
object. Therefore also all calculated taxes and all
necessary information for calculating taxes is stored in PriceInterface
objects. Following methods are important:
getTaxEntries()
,setTaxEntries($taxEntries)
: Sets and gets tax entries for price. Each price can have one or more tax entries based on the tax laws. Each of these tax entries contain percent rate and calculated amount. The order of the tax entries is important.getTaxEntryCombinationMode()
,setTaxEntryCombinationMode($taxEntryCombinationMode)
: Sets and gets the tax entry combination mode which defines how tax calculation is done based on the tax entries:TaxEntry::CALCULATION_MODE_COMBINE
: Sum up all tax rates and calculate tax amount afterwards.TaxEntry::CALCULATION_MODE_ONE_AFTER_ANOTHER
: For each tax rate calculate tax amount, add it to total price and then calculate tax amount for next tax rate based on new total sum.TaxEntry::CALCULATION_MODE_FIXED
: Amounts and percent rates are fixed and cannot be (re)calculated based on information within thePriceInterface
object. This mode is needed forsubTotal
andgrandTotal
inCartPriceCalculator
.
getGrossAmount()
,setGrossAmount($grossAmount, $recalc = false)
: Sets and gets gross amount of price. If$recalc
is set totrue
, corresponding net price is calculated based on tax entries and tax entry combination mode.getNetAmount()
,setNetAmount($netAmount, $recalc = false)
: Sets and gets net amount of price. If$recalc
is set totrue
, corresponding gross price is calculated based on tax entries and tax entry combination mode.getAmount()
,setAmount($amount, $priceMode = self::PRICE_MODE_GROSS, $recalc = false)
: Gets the gross amount by default and sets the gross or net amount based on the params.