| Current Path : /home/rtorresani/www/vendor/magento/module-tax/Model/Calculation/ |
| Current File : //home/rtorresani/www/vendor/magento/module-tax/Model/Calculation/UnitBaseCalculator.php |
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Tax\Model\Calculation;
use Magento\Tax\Api\Data\QuoteDetailsItemInterface;
class UnitBaseCalculator extends AbstractCalculator
{
/**
* Determines the rounding operation type and rounds the amount
*
* @param float $amount
* @param string $rate
* @param bool $direction
* @param string $type
* @param bool $round
* @param QuoteDetailsItemInterface $item
* @return float|string
*/
protected function roundAmount(
$amount,
$rate = null,
$direction = null,
$type = self::KEY_REGULAR_DELTA_ROUNDING,
$round = true,
$item = null
) {
if ($item->getAssociatedItemCode()) {
// Use delta rounding of the product's instead of the weee's
$type = $type . $item->getAssociatedItemCode();
} else {
$type = $type . $item->getCode();
}
return $this->deltaRound($amount, $rate, $direction, $type, $round);
}
/**
* Calculate tax details for quote item with tax in price with given quantity
*
* @param QuoteDetailsItemInterface $item
* @param int $quantity
* @param bool $round
* @return \Magento\Tax\Api\Data\TaxDetailsItemInterface
*/
protected function calculateWithTaxInPrice(QuoteDetailsItemInterface $item, $quantity, $round = true)
{
$taxRateRequest = $this->getAddressRateRequest()->setProductClassId(
$this->taxClassManagement->getTaxClassId($item->getTaxClassKey())
);
$rate = $this->calculationTool->getRate($taxRateRequest);
$storeRate = $this->calculationTool->getStoreRate($taxRateRequest, $this->storeId);
// Calculate $priceInclTax
$applyTaxAfterDiscount = $this->config->applyTaxAfterDiscount($this->storeId);
$priceInclTax = $this->calculationTool->round($item->getUnitPrice());
if (!$this->isSameRateAsStore($rate, $storeRate)) {
$priceInclTax = $this->calculatePriceInclTax($priceInclTax, $storeRate, $rate, $round);
}
$uniTax = $this->calculationTool->calcTaxAmount($priceInclTax, $rate, true, false);
$deltaRoundingType = self::KEY_REGULAR_DELTA_ROUNDING;
if ($applyTaxAfterDiscount) {
$deltaRoundingType = self::KEY_TAX_BEFORE_DISCOUNT_DELTA_ROUNDING;
}
$uniTax = $this->roundAmount($uniTax, $rate, true, $deltaRoundingType, $round, $item);
$price = $priceInclTax - $uniTax;
//Handle discount
$discountTaxCompensationAmount = 0;
$discountAmount = $item->getDiscountAmount();
if ($applyTaxAfterDiscount) {
//TODO: handle originalDiscountAmount
$unitDiscountAmount = $discountAmount / $quantity;
$taxableAmount = max($priceInclTax - $unitDiscountAmount, 0);
$unitTaxAfterDiscount = $this->calculationTool->calcTaxAmount(
$taxableAmount,
$rate,
true,
false
);
$unitTaxAfterDiscount = $this->roundAmount(
$unitTaxAfterDiscount,
$rate,
true,
self::KEY_REGULAR_DELTA_ROUNDING,
$round,
$item
);
// Set discount tax compensation
$unitDiscountTaxCompensationAmount = $uniTax - $unitTaxAfterDiscount;
$discountTaxCompensationAmount = $unitDiscountTaxCompensationAmount * $quantity;
$uniTax = $unitTaxAfterDiscount;
}
$rowTax = $uniTax * $quantity;
// Calculate applied taxes
/** @var \Magento\Tax\Api\Data\AppliedTaxInterface[] $appliedTaxes */
$appliedRates = $this->calculationTool->getAppliedRates($taxRateRequest);
$appliedTaxes = $this->getAppliedTaxes($rowTax, $rate, $appliedRates);
return $this->taxDetailsItemDataObjectFactory->create()
->setCode($item->getCode())
->setType($item->getType())
->setRowTax($rowTax)
->setPrice($price)
->setPriceInclTax($priceInclTax)
->setRowTotal($price * $quantity)
->setRowTotalInclTax($priceInclTax * $quantity)
->setDiscountTaxCompensationAmount($discountTaxCompensationAmount)
->setAssociatedItemCode($item->getAssociatedItemCode())
->setTaxPercent($rate)
->setAppliedTaxes($appliedTaxes);
}
/**
* Calculate tax details for quote item with tax not in price with given quantity
*
* @param QuoteDetailsItemInterface $item
* @param int $quantity
* @param bool $round
* @return \Magento\Tax\Api\Data\TaxDetailsItemInterface
*/
protected function calculateWithTaxNotInPrice(QuoteDetailsItemInterface $item, $quantity, $round = true)
{
$taxRateRequest = $this->getAddressRateRequest()->setProductClassId(
$this->taxClassManagement->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 $price
$price = $this->calculationTool->round($item->getUnitPrice());
$unitTaxes = [];
$unitTaxesBeforeDiscount = [];
$appliedTaxes = [];
//Apply each tax rate separately
foreach ($appliedRates as $appliedRate) {
$taxId = $appliedRate['id'];
$taxRate = $appliedRate['percent'];
$unitTaxPerRate = $this->calculationTool->calcTaxAmount($price, $taxRate, false, false);
$deltaRoundingType = self::KEY_REGULAR_DELTA_ROUNDING;
if ($applyTaxAfterDiscount) {
$deltaRoundingType = self::KEY_TAX_BEFORE_DISCOUNT_DELTA_ROUNDING;
}
$unitTaxPerRate = $this->roundAmount($unitTaxPerRate, $taxId, false, $deltaRoundingType, $round, $item);
$unitTaxAfterDiscount = $unitTaxPerRate;
//Handle discount
if ($applyTaxAfterDiscount) {
//TODO: handle originalDiscountAmount
$unitDiscountAmount = $discountAmount / $quantity;
$taxableAmount = max($price - $unitDiscountAmount, 0);
$unitTaxAfterDiscount = $this->calculationTool->calcTaxAmount(
$taxableAmount,
$taxRate,
false,
false
);
$unitTaxAfterDiscount = $this->roundAmount(
$unitTaxAfterDiscount,
$taxId,
false,
self::KEY_REGULAR_DELTA_ROUNDING,
$round,
$item
);
}
$appliedTaxes[$taxId] = $this->getAppliedTax(
$unitTaxAfterDiscount * $quantity,
$appliedRate
);
$unitTaxes[] = $unitTaxAfterDiscount;
$unitTaxesBeforeDiscount[] = $unitTaxPerRate;
}
$unitTax = array_sum($unitTaxes);
$unitTaxBeforeDiscount = array_sum($unitTaxesBeforeDiscount);
$rowTax = $unitTax * $quantity;
$priceInclTax = $price + $unitTaxBeforeDiscount;
return $this->taxDetailsItemDataObjectFactory->create()
->setCode($item->getCode())
->setType($item->getType())
->setRowTax($rowTax)
->setPrice($price)
->setPriceInclTax($priceInclTax)
->setRowTotal($price * $quantity)
->setRowTotalInclTax($priceInclTax * $quantity)
->setDiscountTaxCompensationAmount($discountTaxCompensationAmount)
->setAssociatedItemCode($item->getAssociatedItemCode())
->setTaxPercent($rate)
->setAppliedTaxes($appliedTaxes);
}
}