/** * {@inheritdoc} */ protected function calculateWithTaxNotInPrice(QuoteDetailsItem $item, $quantity) { $taxRateRequest = $this->getAddressRateRequest()->setProductClassId($this->taxClassService->getTaxClassId($item->getTaxClassKey())); $rate = $this->calculationTool->getRate($taxRateRequest); $appliedRates = $this->calculationTool->getAppliedRates($taxRateRequest); $applyTaxAfterDiscount = $this->config->applyTaxAfterDiscount($this->storeId); $discountAmount = $item->getDiscountAmount(); $discountTaxCompensationAmount = 0; // Calculate $rowTotal $price = $this->calculationTool->round($item->getUnitPrice()); $rowTotal = $price * $quantity; $rowTaxes = []; $rowTaxesBeforeDiscount = []; $appliedTaxes = []; //Apply each tax rate separately foreach ($appliedRates as $appliedRate) { $taxId = $appliedRate['id']; $taxRate = $appliedRate['percent']; $rowTaxPerRate = $this->calculationTool->calcTaxAmount($rowTotal, $taxRate, false, false); $rowTaxPerRate = $this->roundAmount($rowTaxPerRate, $taxRate, false); $rowTaxAfterDiscount = $rowTaxPerRate; //Handle discount if ($discountAmount && $applyTaxAfterDiscount) { //TODO: handle originalDiscountAmount $taxableAmount = max($rowTotal - $discountAmount, 0); $rowTaxAfterDiscount = $this->calculationTool->calcTaxAmount($taxableAmount, $taxRate, false, false); $rowTaxAfterDiscount = $this->roundAmount($rowTaxAfterDiscount, $taxRate, false, self::KEY_TAX_AFTER_DISCOUNT_DELTA_ROUNDING); } $appliedTaxes[$taxId] = $this->getAppliedTax($rowTaxAfterDiscount, $appliedRate); $rowTaxes[] = $rowTaxAfterDiscount; $rowTaxesBeforeDiscount[] = $rowTaxPerRate; } $rowTax = array_sum($rowTaxes); $rowTaxBeforeDiscount = array_sum($rowTaxesBeforeDiscount); $rowTotalInclTax = $rowTotal + $rowTaxBeforeDiscount; $priceInclTax = $this->calculationTool->round($rowTotalInclTax / $quantity); $this->taxDetailsItemBuilder->setCode($item->getCode()); $this->taxDetailsItemBuilder->setType($item->getType()); $this->taxDetailsItemBuilder->setRowTax($rowTax); $this->taxDetailsItemBuilder->setPrice($price); $this->taxDetailsItemBuilder->setPriceInclTax($priceInclTax); $this->taxDetailsItemBuilder->setRowTotal($rowTotal); $this->taxDetailsItemBuilder->setRowTotalInclTax($rowTotalInclTax); $this->taxDetailsItemBuilder->setDiscountTaxCompensationAmount($discountTaxCompensationAmount); $this->taxDetailsItemBuilder->setAssociatedItemCode($item->getAssociatedItemCode()); $this->taxDetailsItemBuilder->setTaxPercent($rate); $this->taxDetailsItemBuilder->setAppliedTaxes($appliedTaxes); return $this->taxDetailsItemBuilder->create(); }
/** * Callback function that creates a tax details item with applied taxes from a quote details item for testing. * * @param QuoteDetailsItem $item * @return Data\TaxDetails\Item */ public function createTaxDetailsItemWithAppliedTaxes(QuoteDetailsItem $item) { $appliedTaxRateBuilder = $this->taxDetailsBuilder->getAppliedTaxBuilder(); $taxRateBuilder = $appliedTaxRateBuilder->getAppliedTaxRateBuilder(); $rate = $taxRateBuilder->setPercent(self::TAX)->setCode('TAX')->setTitle('Tax')->create(); $appliedTaxes = $appliedTaxRateBuilder->setAmount($item->getUnitPrice() * self::TAX)->setTaxRateKey('TAX_RATE')->setPercent(self::TAX)->setRates([$rate])->create(); return $this->taxDetailsItemBuilder->populate($this->createTaxDetailsItem($item))->setAppliedTaxes([$appliedTaxes])->create(); }