/**
  * Compounds rates of this compounder added with addRate() method
  *
  * @param  cbpaidPaymentBasket       $paymentBasket
  * @param  cbpaidPaymentTotalizerCompoundable[]  $taxableTotalizers
  * @param  string                    $totalizerType
  * @return void
  */
 public function computeAllTaxes($paymentBasket, &$taxableTotalizers, $totalizerType)
 {
     $currency = $paymentBasket->mc_currency;
     $anyAutoRecurringInBasket = $paymentBasket->isAnyAutoRecurringPossibleWithThisBasket();
     foreach ($this->ratesToCompound as $ratesOfPriorityItem) {
         // handle first taxes-inclusive items:
         //TODO		$this->_getItemsTaxesInclusiveToExclusive( $ratesOfPriorityItem, $currency );
         $itemsTaxesToAdd = array();
         foreach ($ratesOfPriorityItem as $ratesOfItem) {
             $item = $ratesOfItem['item'];
             // item can have first_rate and first_period SOMETIMES, but only of $anyAutoRecurringInBasket
             // totalizer is same rules as basket: if basket has first_period then totalizer follows basket.
             // So:
             // Now $first.... below is refering to the $item :
             $extraAmountBefore = 0;
             $extraPercents = 0;
             $extraAmountAfter = 0;
             $firstExtraAmountBefore = 0;
             $firstExtraPercents = 0;
             $firstExtraAmountAfter = 0;
             $itemHasReallyFirstRate = isset($item->first_validity) && $item->first_validity || $item->first_rate;
             // when $item is cbpaidPaymentTotalizer then it doesn't have first_validity
             $itemHasFirstRate = $itemHasReallyFirstRate || $item->first_discount_amount || $item->first_tax_amount;
             $amountTaxExcl = $this->_getItemAmount_first_incl($item, false, false);
             $amount = $this->_getItemAmount_first_incl($item, true, false);
             if ($itemHasFirstRate) {
                 $firstAmountTaxExcl = $this->_getItemAmount_first_incl($item, false, true, $itemHasReallyFirstRate);
                 $firstAmount = $this->_getItemAmount_first_incl($item, true, true, $itemHasReallyFirstRate);
             } else {
                 $firstAmountTaxExcl = null;
                 $firstAmount = null;
             }
             // first handles the item:
             $totalizerRatesOfItem = array();
             // first period first, as some totalizers differ after use (e.g. wallet use), then the normal period:
             foreach ($ratesOfItem['ratestots'] as $k => $rateTotalizer) {
                 /** @var $rate cbpaidTotalizertypeCompoundable */
                 list($rate, $totalizer) = $rateTotalizer;
                 $rate->setBasket($paymentBasket);
                 $rate->setPaymentItem($item);
                 /* NOT NOW, MAYBE LATER DIFFERENTLY:
                 					if ( $item->getPlanParam( 'tax_taxing_date', 1 ) == 2 ) {
                 						$tax_taxing_date_ratio	=	$item->getPlanParam( 'tax_taxing_date_ratio', 0.0 );
                 						// we have a non-linear taxation on this item:
                 		$item = NEW cbpaidPaymentItem();
                 						// Does this taxRate start after the start (or stops before the stop) of the initiating time of the basket ? :
                 						$itemStartDay			=	cbpaidTimes::getInstance()->localDate( 'Y-m-d', cbpaidTimes::getInstance()->strToTime( $item->start_date ) );
                 						$taxRate_stop_date		=	( $rate->stop_date == '0000-00-00' ? '9999-99-99' : $rate->stop_date );
                 						if ( ( $rate->start_date <= $itemStartDay ) && ( $taxRate_stop_date >= $itemStartDay ) ) {
                 							// The item starts during the validity period of this tax rate: we need to fix the ratios:
                 							
                 						} else {
                 							$proraterFactor		=	( 100.0 - (float) $tax_taxing_date_ratio ) / 100;
                 						}
                 	
                 					} else {
                 						$proraterFactor			=	1;
                 					}
                 */
                 //			if ( $totalizer->first_rate !== null ) {
                 /** @var $totalizer cbpaidPaymentTotalizerCompoundable */
                 $firstPeriodProrater = $totalizer->proRatePeriod($item, true);
                 $totalizerRatesOfItem[$k]['fr'] = $firstPeriodProrater;
                 if ($itemHasFirstRate) {
                     $firstExtraAmountBefore += $totalizerRatesOfItem[$k]['fb'] = $rate->getAmountBeforePercents($firstAmount, $firstAmountTaxExcl, $firstPeriodProrater, true, $currency);
                     $firstExtraPercents += $totalizerRatesOfItem[$k]['fp'] = $rate->getPercents($firstAmount, $firstAmountTaxExcl, $firstPeriodProrater, true);
                     $firstExtraAmountAfter += $totalizerRatesOfItem[$k]['fa'] = $rate->getAmountAfterPercents($firstAmount, $firstAmountTaxExcl, $firstPeriodProrater, true, $currency);
                 } else {
                     $firstExtraAmountBefore += $totalizerRatesOfItem[$k]['fb'] = $rate->getAmountBeforePercents($amount, $amountTaxExcl, $firstPeriodProrater, true, $currency);
                     $firstExtraPercents += $totalizerRatesOfItem[$k]['fp'] = $rate->getPercents($amount, $amountTaxExcl, $firstPeriodProrater, true);
                     $firstExtraAmountAfter += $totalizerRatesOfItem[$k]['fa'] = $rate->getAmountAfterPercents($amount, $amountTaxExcl, $firstPeriodProrater, true, $currency);
                 }
                 //			}
             }
             // Now the normal recurring period:
             if ($anyAutoRecurringInBasket && $item->autorecurring > 0) {
                 foreach ($ratesOfItem['ratestots'] as $k => $rateTotalizer) {
                     list($rate, $totalizer) = $rateTotalizer;
                     if ($totalizer->rate !== null) {
                         $periodProrater = $totalizer->proRatePeriod($item, false);
                         $totalizerRatesOfItem[$k]['r'] = $periodProrater;
                         $extraAmountBefore += $totalizerRatesOfItem[$k]['b'] = $rate->getAmountBeforePercents($amount, $amountTaxExcl, $periodProrater, false, $currency);
                         $extraPercents += $totalizerRatesOfItem[$k]['p'] = $rate->getPercents($amount, $amountTaxExcl, $periodProrater, false);
                         $extraAmountAfter += $totalizerRatesOfItem[$k]['a'] = $rate->getAmountAfterPercents($amount, $amountTaxExcl, $periodProrater, false, $currency);
                     }
                 }
             }
             // Now adds to the item:
             if ($itemHasFirstRate) {
                 $first_tax_amount = ($firstAmount + $firstExtraAmountBefore) * (1 + $firstExtraPercents) + $firstExtraAmountAfter - $firstAmount;
             } else {
                 $first_tax_amount = ($amount + $firstExtraAmountBefore) * (1 + $firstExtraPercents) + $firstExtraAmountAfter - $amount;
             }
             $second_tax_amount = ($amount + $extraAmountBefore) * (1 + $extraPercents) + $extraAmountAfter - $amount;
             if ($anyAutoRecurringInBasket && $item->autorecurring > 0) {
                 // We cannot do this now, otherwise same-priority taxes will be compounded:
                 // $item->first_tax_amount	+=	$first_tax_amount;
                 // So store that for after all rates totalizers of this priority have been handled:
                 if ($first_tax_amount != 0 && ($itemHasFirstRate || $first_tax_amount != $second_tax_amount)) {
                     if (!$itemHasFirstRate) {
                         // As the following step will create the first rate for the item, we need to copy current discount from regular discount amount:
                         $item->first_discount_amount = $item->discount_amount;
                         $item->first_tax_amount = $item->tax_amount;
                     }
                     // Now prepare following statement but deferred:
                     // $item->first_discount_amount (or ->first_tax_amount)		+=	$first_tax_amount;
                     $itemsTaxesToAdd[] = array($item, $this->_getItemTotalizerColumnName(true), $first_tax_amount);
                 } else {
                     $second_tax_amount = ($amount + $firstExtraAmountBefore) * (1 + $firstExtraPercents) + $firstExtraAmountAfter - $amount;
                 }
                 if ($second_tax_amount != 0) {
                     // Now prepare following statement but deferred:
                     // $item->discount_amount (or ->tax_amount)		+=	$tax_amount;
                     $itemsTaxesToAdd[] = array($item, $this->_getItemTotalizerColumnName(false), $second_tax_amount);
                 }
             } else {
                 $itemsTaxesToAdd[] = array($item, $this->_getItemTotalizerColumnName(false), $first_tax_amount);
             }
             // then, now that totals for this item in this tax priority are known, handles the totalizers (of that priority, for that item):
             foreach ($ratesOfItem['ratestots'] as $k => $rateTotalizer) {
                 list(, $totalizer) = $rateTotalizer;
                 if ($totalizer->first_rate !== null) {
                     if ($itemHasFirstRate) {
                         $totalizer->first_original_rate += $firstAmount * $totalizerRatesOfItem[$k]['fr'];
                         $totalizer->first_rate += $totalizerRatesOfItem[$k]['fb'] + (($firstAmount + $firstExtraAmountBefore) * (0 + $totalizerRatesOfItem[$k]['fp']) + $totalizerRatesOfItem[$k]['fa']);
                     } else {
                         // Basket and totalizer have first rate but the item doesn't have one: still add item's non-first tax to totalizer's first tax:
                         $totalizer->first_original_rate += $amount * $totalizerRatesOfItem[$k]['fr'];
                         $totalizer->first_rate += $totalizerRatesOfItem[$k]['fb'] + (($amount + $firstExtraAmountBefore) * (0 + $totalizerRatesOfItem[$k]['fp']) + $totalizerRatesOfItem[$k]['fa']);
                     }
                     $totalizer->first_original_rate = round($totalizer->first_original_rate, 2);
                     $totalizer->first_rate = round($totalizer->first_rate, 2);
                 }
                 if ($totalizer->rate !== null && (!$anyAutoRecurringInBasket || $anyAutoRecurringInBasket && $item->autorecurring > 0)) {
                     if ($anyAutoRecurringInBasket) {
                         $totalizer->original_rate += $amount * $totalizerRatesOfItem[$k]['r'];
                         $totalizer->rate += $totalizerRatesOfItem[$k]['b'] + (($amount + $extraAmountBefore) * (0 + $totalizerRatesOfItem[$k]['p']) + $totalizerRatesOfItem[$k]['a']);
                     } else {
                         $totalizer->original_rate += $amount * $totalizerRatesOfItem[$k]['fr'];
                         $totalizer->rate += $totalizerRatesOfItem[$k]['fb'] + (($amount + $extraAmountBefore) * (0 + $totalizerRatesOfItem[$k]['fp']) + $totalizerRatesOfItem[$k]['fa']);
                     }
                     $totalizer->original_rate = round($totalizer->original_rate, 2);
                     $totalizer->rate = round($totalizer->rate, 2);
                     if ($totalizer->first_rate == null && $anyAutoRecurringInBasket) {
                         $totalizer->first_rate = '0.0';
                         $totalizer->first_item_days = $totalizer->item_days;
                         $totalizer->first_totalizer_days = $totalizer->totalizer_days;
                         $totalizer->first_original_rate = '0.0';
                     }
                 }
             }
         }
         unset($totalizerRatesOfItem);
         // Now can add to items the taxes, before we look at next tax rates priorities:
         foreach ($itemsTaxesToAdd as $taxToAdd) {
             $taxToAdd[0]->{$taxToAdd[1]} += $taxToAdd[2];
         }
     }
     // Now that all items and totalizers have been computed, adjust basket:
     foreach ($taxableTotalizers as $k => $totalizer) {
         if ($totalizer->totalizer_type == $totalizerType && $totalizer->hasItems()) {
             if (!$totalizer->applyThisTotalizerToBasket($paymentBasket, $anyAutoRecurringInBasket)) {
                 unset($taxableTotalizers[$k]);
             }
         }
     }
 }