/**
  * Process product items in the quote.
  * Set the following aggregated values in the quote object:
  * subtotal, subtotalInclTax, tax, discount_tax_compensation,
  *
  * @param ShippingAssignmentInterface $shippingAssignment
  * @param array $itemTaxDetails
  * @param QuoteAddress\Total $total
  * @return $this
  */
 protected function processProductItems(ShippingAssignmentInterface $shippingAssignment, array $itemTaxDetails, QuoteAddress\Total $total)
 {
     $store = $shippingAssignment->getShipping()->getAddress()->getQuote()->getStore();
     /** @var AbstractItem[] $keyedAddressItems */
     $keyedAddressItems = [];
     foreach ($shippingAssignment->getItems() as $addressItem) {
         $keyedAddressItems[$addressItem->getTaxCalculationItemId()] = $addressItem;
     }
     $subtotal = $baseSubtotal = 0;
     $discountTaxCompensation = $baseDiscountTaxCompensation = 0;
     $tax = $baseTax = 0;
     $subtotalInclTax = $baseSubtotalInclTax = 0;
     foreach ($itemTaxDetails as $code => $itemTaxDetail) {
         /** @var TaxDetailsItemInterface $taxDetail */
         $taxDetail = $itemTaxDetail[self::KEY_ITEM];
         /** @var TaxDetailsItemInterface $baseTaxDetail */
         $baseTaxDetail = $itemTaxDetail[self::KEY_BASE_ITEM];
         $quoteItem = $keyedAddressItems[$code];
         $this->updateItemTaxInfo($quoteItem, $taxDetail, $baseTaxDetail, $store);
         //Update aggregated values
         if ($quoteItem->getHasChildren() && $quoteItem->isChildrenCalculated()) {
             //avoid double counting
             continue;
         }
         $subtotal += $taxDetail->getRowTotal();
         $baseSubtotal += $baseTaxDetail->getRowTotal();
         $discountTaxCompensation += $taxDetail->getDiscountTaxCompensationAmount();
         $baseDiscountTaxCompensation += $baseTaxDetail->getDiscountTaxCompensationAmount();
         $tax += $taxDetail->getRowTax();
         $baseTax += $baseTaxDetail->getRowTax();
         $subtotalInclTax += $taxDetail->getRowTotalInclTax();
         $baseSubtotalInclTax += $baseTaxDetail->getRowTotalInclTax();
     }
     //Set aggregated values
     $total->setTotalAmount('subtotal', $subtotal);
     $total->setBaseTotalAmount('subtotal', $baseSubtotal);
     $total->setTotalAmount('tax', $tax);
     $total->setBaseTotalAmount('tax', $baseTax);
     $total->setTotalAmount('discount_tax_compensation', $discountTaxCompensation);
     $total->setBaseTotalAmount('discount_tax_compensation', $baseDiscountTaxCompensation);
     $total->setSubtotalInclTax($subtotalInclTax);
     $total->setBaseSubtotalTotalInclTax($baseSubtotalInclTax);
     $total->setBaseSubtotalInclTax($baseSubtotalInclTax);
     return $this;
 }