/** * {@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 $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); $unitTaxAfterDiscount = $unitTaxPerRate; //Handle discount if ($discountAmount && $applyTaxAfterDiscount) { //TODO: handle originalDiscountAmount $unitDiscountAmount = $discountAmount / $quantity; $taxableAmount = max($price - $unitDiscountAmount, 0); $unitTaxAfterDiscount = $this->calculationTool->calcTaxAmount($taxableAmount, $taxRate, false, true); } $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; $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($price * $quantity); $this->taxDetailsItemBuilder->setRowTotalInclTax($priceInclTax * $quantity); $this->taxDetailsItemBuilder->setDiscountTaxCompensationAmount($discountTaxCompensationAmount); $this->taxDetailsItemBuilder->setAssociatedItemCode($item->getAssociatedItemCode()); $this->taxDetailsItemBuilder->setTaxPercent($rate); $this->taxDetailsItemBuilder->setAppliedTaxes($appliedTaxes); return $this->taxDetailsItemBuilder->create(); }
/** * Calculates the total quantity for this item. * * What this really means is that if this is a child item, it return the parent quantity times * the child quantity and return that as the child's quantity. * * @param QuoteDetailsItem $item * @return float */ protected function getTotalQuantity(QuoteDetailsItem $item) { if ($item->getParentCode()) { $parentQuantity = $this->keyedItems[$item->getParentCode()]->getQuantity(); return $parentQuantity * $item->getQuantity(); } return $item->getQuantity(); }
/** * Calculate tax details for quote item with given quantity * * @param QuoteDetailsItem $item * @param int $quantity * @return TaxDetailsItem */ public function calculate(QuoteDetailsItem $item, $quantity) { if ($item->getTaxIncluded()) { return $this->calculateWithTaxInPrice($item, $quantity); } else { return $this->calculateWithTaxNotInPrice($item, $quantity); } }
/** * 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(); }