/**
  * Getter for product price
  * May be decorated by the module silvercart_graduatedprices
  *
  * @param string $priceType          Set to 'gross' or 'net' to get the desired prices.
  *                                   If not given the price type will be automatically determined.
  * @param bool   $ignoreTaxExemption Determines whether to ignore tax exemption or not.
  *
  * @return Money price dependent on customer class and configuration
  *
  * @author Roland Lehmann <*****@*****.**>,
  *         Sebastian Diel <*****@*****.**>
  * @since 15.11.2014
  */
 public function getPrice($priceType = '', $ignoreTaxExemption = false)
 {
     $cacheHash = md5($priceType);
     $cacheKey = 'getPrice_' . $cacheHash . '_' . $ignoreTaxExemption ? '1' : '0';
     if (array_key_exists($cacheKey, $this->cacheHashes)) {
         return $this->cacheHashes[$cacheKey];
     }
     if (empty($priceType)) {
         $priceType = SilvercartConfig::PriceType();
     }
     if ($priceType == "net") {
         $price = clone $this->PriceNet;
     } elseif ($priceType == "gross") {
         $price = clone $this->PriceGross;
     } else {
         $price = clone $this->PriceGross;
     }
     $member = SilvercartCustomer::currentUser();
     if (!$ignoreTaxExemption && !$this->ignoreTaxExemption && $member instanceof Member && $member->doesNotHaveToPayTaxes() && $priceType != "net") {
         $this->ignoreTaxExemption = true;
         $price->setAmount($price->getAmount() - $this->getTaxAmount());
         $this->ignoreTaxExemption = false;
     }
     $price->setAmount(round($price->getAmount(), 2));
     if ($price->getAmount() < 0) {
         $price->setAmount(0);
     }
     //overwrite the price in a decorator
     $this->extend('updatePrice', $price);
     $this->price = $price;
     $this->cacheHashes[$cacheKey] = $this->price;
     return $this->price;
 }
 /**
  * Returns the prices amount
  *
  * @return float
  */
 public function getPriceAmount()
 {
     $price = (double) $this->amount->getAmount();
     if (SilvercartConfig::PriceType() == 'net') {
         $price = $price - $this->getTaxAmount();
     }
     return $price;
 }
 /**
  * Returns the prices amount
  * 
  * @param bool              $plain              Set to true to load the price amount without any manipulation
  * @param float             $amountToGetFeeFor  Amount to get fee for
  * @param SilvercartCountry $countryToGetFeeFor Amount to get fee for
  *
  * @return float
  *
  * @author Sebastian Diel <*****@*****.**>,
  *         Sascha Koehler <*****@*****.**>
  * @since 15.11.2014
  */
 public function getPriceAmount($plain = false, $amountToGetFeeFor = null, $countryToGetFeeFor = null)
 {
     $price = (double) $this->Price->getAmount();
     if (!$plain) {
         if (SilvercartConfig::PriceType() == 'net') {
             $price = $price - $this->getTaxAmount($price);
         }
         if (SilvercartCustomer::currentUser() && SilvercartCustomer::currentUser()->SilvercartShoppingCartID > 0) {
             $silvercartShoppingCart = SilvercartCustomer::currentUser()->getCart();
             $shoppingCartValue = $silvercartShoppingCart->getTaxableAmountWithoutFees();
             if (is_null($amountToGetFeeFor)) {
                 $amountToGetFeeFor = $shoppingCartValue->getAmount();
             }
             if (is_null($countryToGetFeeFor)) {
                 $countryToGetFeeFor = $this->SilvercartShippingMethod()->getShippingCountry();
             }
             if ($this->ShippingIsFree($amountToGetFeeFor, $countryToGetFeeFor)) {
                 $price = 0.0;
             }
         }
         $price = round($price, 2);
         $this->extend('updatePriceAmount', $price);
     } elseif (!is_null($amountToGetFeeFor) && !is_null($countryToGetFeeFor) && $this->ShippingIsFree($amountToGetFeeFor, $countryToGetFeeFor)) {
         $price = 0.0;
     }
     return $price;
 }
 /**
  * Returns tax amounts included in the shoppingcart separated by tax rates
  * without fee taxes.
  *
  * @return ArrayList
  */
 public function getTaxRatesWithoutFees()
 {
     $taxes = $this->getTaxRatesWithoutFeesAndCharges();
     // Charges and disounts
     $chargesAndDiscounts = $this->ChargesAndDiscountsForProducts();
     if ($this->HasChargesAndDiscountsForProducts()) {
         $mostValuableTaxRate = $this->getMostValuableTaxRate($taxes);
         if ($mostValuableTaxRate) {
             $taxSection = $taxes->find('Rate', $mostValuableTaxRate->Rate);
             $chargeAndDiscountAmount = $chargesAndDiscounts->Price->getAmount();
             if (SilvercartConfig::PriceType() == 'gross') {
                 $taxSection->AmountRaw += $chargeAndDiscountAmount - $chargeAndDiscountAmount / (100 + $taxSection->Rate) * 100;
             } else {
                 $taxSection->AmountRaw += $chargeAndDiscountAmount / 100 * (100 + $taxSection->Rate) - $chargeAndDiscountAmount;
             }
         }
     }
     foreach ($taxes as $tax) {
         $taxObj = new Money();
         $taxObj->setAmount($tax->AmountRaw);
         $taxObj->setCurrency(SilvercartConfig::DefaultCurrency());
         $tax->Amount = $taxObj;
     }
     return $taxes;
 }
 /**
  * Returns the charges and discounts for the shopping cart total for
  * this payment method.
  * 
  * @param SilvercartShoppingCart $silvercartShoppingCart The shopping cart object
  * @param string                 $priceType              'gross' or 'net'
  *
  * @return mixed boolean|DataObject
  * 
  * @author Sascha Koehler <*****@*****.**>,
  *         Sebastian Diel <*****@*****.**>
  * @since 16.11.2013
  */
 public function getChargesAndDiscountsForTotal(SilvercartShoppingCart $silvercartShoppingCart, $priceType = false)
 {
     $handlingCosts = new Money();
     $handlingCosts->setAmount(0);
     $handlingCosts->setCurrency(SilvercartConfig::DefaultCurrency());
     if ($priceType === false) {
         $priceType = SilvercartConfig::PriceType();
     }
     if ($this->useSumModification && $this->sumModificationImpact == 'totalValue') {
         $excludedPositions = array();
         switch ($this->sumModificationValueType) {
             case 'percent':
                 $amount = $silvercartShoppingCart->getAmountTotal(array(), false, true);
                 $modificationValue = $amount->getAmount() / 100 * $this->sumModificationValue;
                 $index = 1;
                 foreach ($silvercartShoppingCart->SilvercartShoppingCartPositions() as $position) {
                     if ($position->SilvercartProductID > 0 && $position->SilvercartProduct() instanceof SilvercartProduct && $position->SilvercartProduct()->ExcludeFromPaymentDiscounts) {
                         $modificationValue -= $position->getPrice()->getAmount() / 100 * $this->sumModificationValue;
                         $excludedPositions[] = $index;
                     }
                     $index++;
                 }
                 break;
             case 'absolute':
             default:
                 $modificationValue = $this->sumModificationValue;
         }
         if (count($excludedPositions) > 0) {
             if (count($excludedPositions) == 1) {
                 $this->sumModificationLabel .= ' (' . sprintf(_t('SilvercartPaymentMethod.ExcludedPosition'), implode(', ', $excludedPositions)) . ')';
             } else {
                 $this->sumModificationLabel .= ' (' . sprintf(_t('SilvercartPaymentMethod.ExcludedPositions'), implode(', ', $excludedPositions)) . ')';
             }
         }
         if ($this->sumModificationImpactType == 'charge') {
             $handlingCostAmount = $modificationValue;
         } else {
             $handlingCostAmount = "-" . $modificationValue;
         }
         if (SilvercartConfig::PriceType() == 'gross') {
             $shoppingCartTotal = $silvercartShoppingCart->getAmountTotal(array(), false, true);
         } else {
             $shoppingCartTotal = $silvercartShoppingCart->getAmountTotalNetWithoutVat(array(), false, true);
             $taxRate = $silvercartShoppingCart->getMostValuableTaxRate();
             $handlingCostAmount = round($handlingCostAmount / (100 + $taxRate->Rate) * 100, 4);
         }
         if ($handlingCostAmount < 0 && $shoppingCartTotal->getAmount() < $handlingCostAmount * -1) {
             $handlingCostAmount = $shoppingCartTotal->getAmount() * -1;
         }
         $handlingCosts->setAmount($handlingCostAmount);
     }
     $this->extend('updateChargesAndDiscountsForTotal', $handlingCosts);
     if ($handlingCosts->getAmount() == 0) {
         $handlingCosts = false;
     }
     return $handlingCosts;
 }
 /**
  * returns the tax amount included in $this
  *
  * @param boolean $forSingleProduct Indicates wether the price for the total
  *                                  quantity of products should be returned
  *                                  or for one product only.
  * 
  * @return float
  */
 public function getTaxAmount($forSingleProduct = false)
 {
     if (SilvercartConfig::PriceType() == 'gross') {
         $taxRate = $this->getPrice($forSingleProduct)->getAmount() - $this->getPrice($forSingleProduct)->getAmount() / (100 + $this->SilvercartProduct()->getTaxRate()) * 100;
     } else {
         $taxRate = $this->getPrice($forSingleProduct)->getAmount() * ($this->SilvercartProduct()->getTaxRate() / 100);
     }
     return $taxRate;
 }