示例#1
0
 /**
  * Get formatted error message from GetTaxResult
  *
  * @param GetTaxResult $getTaxResult
  * @return string
  */
 protected function getErrorMessageFromGetTaxResult(GetTaxResult $getTaxResult)
 {
     $message = '';
     $message .= __('Result code: ') . $getTaxResult->getResultCode() . PHP_EOL;
     /** @var \AvaTax\Message $avataxMessage */
     foreach ($getTaxResult->getMessages() as $avataxMessage) {
         $message .= __('Message:') . PHP_EOL;
         $message .= __('    Name: ') . $avataxMessage->getName() . PHP_EOL;
         $message .= __('    Summary: ') . $avataxMessage->getSummary() . PHP_EOL;
         $message .= __('    Details: ') . $avataxMessage->getDetails() . PHP_EOL;
         $message .= __('    RefersTo: ') . $avataxMessage->getRefersTo() . PHP_EOL;
         $message .= __('    Severity: ') . $avataxMessage->getSeverity() . PHP_EOL;
         $message .= __('    Source: ') . $avataxMessage->getSource() . PHP_EOL;
     }
     return $message;
 }
 /**
  * Convert the AvaTax Tax Summary to a Magento object
  *
  * @see \Magento\Tax\Model\Calculation\AbstractCalculator::getAppliedTax()
  *
  * @param GetTaxResult $getTaxResult
  * @param float $rowTax
  * @return \Magento\Tax\Api\Data\AppliedTaxInterface
  */
 protected function getAppliedTax(GetTaxResult $getTaxResult, $rowTax)
 {
     $totalPercent = 0.0;
     $taxNames = [];
     /** @var  \Magento\Tax\Api\Data\AppliedTaxRateInterface[] $rateDataObjects */
     $rateDataObjects = [];
     /**
      * There are rare situations in which the Tax Summary from AvaTax will contain items that have the same TaxName,
      * JurisCode, JurisName, and Rate. e.g., an order with shipping with VAT tax from Germany (example below).
      * To account for this, we need to group rates by a combination of JurisCode and JurisName. Otherwise the same
      * rate will get added twice. This is problematic for two reasons:
      *     1. If a merchant has configured Magento to "Display Full Tax Summary" then the user will see the same
      *        same rate with the same percentage displayed twice. This will be confusing.
      *     2. When an order is placed, the \Magento\Tax\Model\Plugin\OrderSave::saveOrderTax method populates the
      *        sales_order_tax[_item] tables with information based on the information contained in the Applied Taxes
      *        array. Having duplicates rates will throw things off.
      *
      * 'TaxSummary' => ['TaxDetail' => [
      *     // This rate was applied to shipping
      *     0 => [
      *         'JurisType' => 'State',
      *         'JurisCode' => 'DE',
      *         'TaxType' => 'Sales',
      *         'Taxable' => '20',
      *         'Rate' => '0.189995',
      *         'Tax' => '3.8',
      *         'JurisName' => 'GERMANY',
      *         'TaxName' => 'Standard Rate',
      *         'Country' => 'DE',
      *         'Region' => 'DE',
      *         'TaxCalculated' => '3.8',
      *     ],
      *     // This rate was applied to products
      *     1 => [
      *         'JurisType' => 'State',
      *         'JurisCode' => 'DE',
      *         'TaxType' => 'Sales',
      *         'Base' => '150',
      *         'Taxable' => '150',
      *         'Rate' => '0.190000',
      *         'Tax' => '28.5',
      *         'JurisName' => 'GERMANY',
      *         'TaxName' => 'Standard Rate',
      *         'Country' => 'DE',
      *         'Region' => 'DE',
      *         'TaxCalculated' => '28.5',
      *     ]
      * ]]
      */
     $taxRatesByCode = [];
     /* @var \AvaTax\TaxDetail $row */
     foreach ($getTaxResult->getTaxSummary() as $key => $row) {
         $arrayKey = $row->getJurisCode() . '_' . $row->getJurisName();
         // Since the total percent is for display purposes only, round to 5 digits. Since the tax percent returned
         // from AvaTax is not the actual tax rate, but the effective rate, rounding makes the presentation make more
         // sense to the user. For example, a tax rate may be 19%, but AvaTax may return a value of 0.189995.
         $roundedRate = round((double) $row->getRate(), 4);
         $ratePercent = $roundedRate * Tax::RATE_MULTIPLIER;
         if (!isset($taxRatesByCode[$arrayKey])) {
             $taxRatesByCode[$arrayKey] = ['id' => $key . '_' . $row->getJurisCode(), 'ratePercent' => $ratePercent, 'taxName' => $row->getTaxName(), 'jurisCode' => $row->getJurisCode(), 'taxable' => (double) $row->getTaxable(), 'tax' => (double) $row->getTax()];
         } elseif ($taxRatesByCode[$arrayKey]['ratePercent'] != $ratePercent) {
             /**
              * There are rare situations in which a duplicate rate will have a slightly different percentage (see
              * example in DocBlock above). In these cases, we will just determine the "effective" rate" ourselves.
              */
             $taxRatesByCode[$arrayKey]['taxable'] += (double) $row->getTaxable();
             $taxRatesByCode[$arrayKey]['tax'] += (double) $row->getTax();
             // Avoid division by 0
             if ($taxRatesByCode[$arrayKey]['taxable'] > 0) {
                 $blendedRate = $taxRatesByCode[$arrayKey]['tax'] / $taxRatesByCode[$arrayKey]['taxable'];
                 $taxRatesByCode[$arrayKey]['ratePercent'] = $blendedRate;
             }
         }
     }
     foreach ($taxRatesByCode as $rowArray) {
         $ratePercent = $rowArray['ratePercent'];
         $totalPercent += $ratePercent;
         $taxCode = $rowArray['jurisCode'];
         $taxName = $rowArray['taxName'];
         $taxNames[] = $rowArray['taxName'];
         // In case jurisdiction codes are duplicated, prepending the $key ensures we have a unique ID
         $id = $rowArray['id'];
         // Skipped position, priority and rule_id
         $rateDataObjects[$id] = $this->appliedTaxRateDataObjectFactory->create()->setPercent($ratePercent)->setCode($taxCode)->setTitle($taxName);
     }
     $rateKey = implode(' - ', $taxNames);
     $appliedTaxDataObject = $this->appliedTaxDataObjectFactory->create();
     $appliedTaxDataObject->setAmount($rowTax);
     $appliedTaxDataObject->setPercent($totalPercent);
     $appliedTaxDataObject->setTaxRateKey($rateKey);
     $appliedTaxDataObject->setRates($rateDataObjects);
     return $appliedTaxDataObject;
 }