/** * Test convert money. * * @param $isoFrom * @param $isoTo * @param $amount * @param $resultAmount * * @dataProvider dataConvertMoney */ public function testConvertMoney($isoFrom, $isoTo, $amount, $resultAmount) { $currencyFrom = $this->createCurrency($isoFrom); $currencyTo = $this->createCurrency($isoTo); $money = Money::create($amount, $currencyFrom); $moneyResult = $this->currencyConverter->convertMoney($money, $currencyTo); $this->assertEquals($moneyResult->getAmount(), $resultAmount); $this->assertEquals($moneyResult->getCurrency(), $currencyTo); }
/** * Given a set of shipping methods, return the one with the lowest price. * * @param ShippingMethod[] $shippingMethods Shipping methods * * @return ShippingMethod Lowest price shipping method */ public function getCheapestShippingMethod(array $shippingMethods) { return array_reduce($shippingMethods, function ($lowestPriceShippingMethod, ShippingMethod $shippingMethod) { $shippingMethodPrice = $shippingMethod->getPrice(); if (!$lowestPriceShippingMethod instanceof ShippingMethod || $shippingMethodPrice->isLessThan($this->currencyConverter->convertMoney($lowestPriceShippingMethod->getPrice(), $shippingMethodPrice->getCurrency()))) { return $shippingMethod; } return $lowestPriceShippingMethod; }, null); }
/** * Check if cart meets minimum price requirements for a coupon. * * @param CartInterface $cart Cart * @param CouponInterface $coupon Coupon * * @throws CouponBelowMinimumPurchaseException Minimum value not reached */ public function validateCartCouponMinimumPrice(CartInterface $cart, CouponInterface $coupon) { $couponMinimumPrice = $coupon->getMinimumPurchase(); if ($couponMinimumPrice->getAmount() === 0) { return; } $productMoney = $cart->getProductAmount(); if ($couponMinimumPrice->getCurrency() != $productMoney->getCurrency()) { $couponMinimumPrice = $this->currencyConverter->convertMoney($couponMinimumPrice, $productMoney->getCurrency()); } if ($productMoney->isLessThan($couponMinimumPrice)) { throw new CouponBelowMinimumPurchaseException(); } }
/** * Check if cart meets minimum price requirements for a coupon * * @param CartCouponOnCheckEvent $event Event * * @return null * * @throws CouponBelowMinimumPurchaseException Minimum value not reached */ public function checkMinimumPrice(CartCouponOnCheckEvent $event) { $couponMinimumPrice = $event->getCoupon()->getMinimumPurchase(); if ($couponMinimumPrice->getAmount() === 0) { return null; } $productMoney = $event->getCart()->getProductAmount(); if ($couponMinimumPrice->getCurrency() != $productMoney->getCurrency()) { $couponMinimumPrice = $this->currencyConverter->convertMoney($couponMinimumPrice, $productMoney->getCurrency()); } if ($productMoney->isLessThan($couponMinimumPrice)) { throw new CouponBelowMinimumPurchaseException(); } }
/** * Performs all processes to be performed after the order creation * * Flushes all loaded order and related entities. * * @param CartOnLoadEvent $event Event * * @return $this Self object */ public function loadShippingPrice(CartOnLoadEvent $event) { $cart = $event->getCart(); $shippingMethodId = $cart->getShippingMethod(); if (empty($shippingMethodId)) { return $this; } $shippingMethod = $this->shippingWrapper->getOneById($cart, $shippingMethodId); if ($shippingMethod instanceof ShippingMethod) { $cartAmount = $cart->getAmount(); $convertedShippingAmount = $this->currencyConverter->convertMoney($shippingMethod->getPrice(), $cartAmount->getCurrency()); $cart->setAmount($cartAmount->add($convertedShippingAmount)); } return $this; }
/** * Given ShippingPriceRange is satisfied by a cart * * @param CartInterface $cart Cart * @param ShippingRangeInterface $shippingRange Carrier Range * * @return boolean ShippingRange is satisfied by cart */ private function isShippingPriceRangeSatisfiedByCart(CartInterface $cart, ShippingRangeInterface $shippingRange) { $cartPrice = $cart->getProductAmount(); $cartPriceCurrency = $cartPrice->getCurrency(); $shippingRangeFromPrice = $shippingRange->getFromPrice(); $shippingRangeToPrice = $shippingRange->getToPrice(); return $this->isShippingRangeZonesSatisfiedByCart($cart, $shippingRange) && $this->currencyConverter->convertMoney($shippingRangeFromPrice, $cartPriceCurrency)->compareTo($cartPrice) <= 0 && $this->currencyConverter->convertMoney($shippingRangeToPrice, $cartPriceCurrency)->compareTo($cartPrice) > 0; }
/** * Return a formatted price given an Money object and the target currency * * If money is null, print empty string * * @param MoneyInterface $money the Money object to print * @param CurrencyInterface $targetCurrency Iso code of the target currency (optional) * * @throws \Exception if source-target exchange is missing * * @return string The formatted price */ public function printConvertMoney(MoneyInterface $money = null, CurrencyInterface $targetCurrency = null) { if (!$money instanceof MoneyInterface) { return ''; } if (!$targetCurrency instanceof CurrencyInterface) { $targetCurrency = $this->currencyWrapper->loadCurrency(); } $moneyConverted = $this->currencyConverter->convertMoney($money, $targetCurrency); return $this->printMoney($moneyConverted); }
/** * Test convert money * * @dataProvider dataConvertMoney */ public function testConvertMoney($isoFrom, $isoTo, $amount, $resultAmount) { $currencyManager = $this->getMockBuilder('Elcodi\\Component\\Currency\\Services\\CurrencyManager')->setMethods(['getExchangeRateList'])->disableOriginalConstructor()->getMock(); $currencyFactory = new CurrencyFactory(); $currencyFactory->setEntityNamespace('Elcodi\\Component\\Currency\\Entity\\Currency'); $currencyBase = 'USD'; /** * @var CurrencyManager $currencyManager */ $currencyManager->expects($this->any())->method('getExchangeRateList')->will($this->returnValue(['EUR' => ['rate' => '0.7365960000', 'currency' => $currencyFactory->create()], 'GBP' => ['rate' => '0.5887650000', 'currency' => $currencyFactory->create()], 'JPY' => ['rate' => '101.8226250000', 'currency' => $currencyFactory->create()]])); $currencyConverter = new CurrencyConverter($currencyManager, $currencyBase); $currencyFrom = $currencyFactory->create(); $currencyFrom->setIso($isoFrom); $currencyTo = $currencyFactory->create(); $currencyTo->setIso($isoTo); $money = Money::create($amount, $currencyFrom); $moneyResult = $currencyConverter->convertMoney($money, $currencyTo); $this->assertEquals($moneyResult->getAmount(), $resultAmount); $this->assertEquals($moneyResult->getCurrency(), $currencyTo); }
/** * Given a cart and a coupon, returns the real value of the coupon * * @param CartInterface $cart Abstract Cart object * @param CouponInterface $coupon Coupon * * @return MoneyInterface Coupon price */ protected function getPriceCoupon(CartInterface $cart, CouponInterface $coupon) { $currency = $this->currencyWrapper->getCurrency(); switch ($coupon->getType()) { case ElcodiCouponTypes::TYPE_AMOUNT: $amount = $coupon->getPrice(); return $this->currencyConverter->convertMoney($amount, $currency); case ElcodiCouponTypes::TYPE_PERCENT: $couponPercent = $coupon->getDiscount(); return $cart->getProductAmount()->multiply($couponPercent / 100); } }
/** * Get extra data * * Returns the order lines as array in the following form * * [ * 1 => [ 'item' => 'Item 1', 'amount' => 1234, 'currency_code' => 'EUR ], * 2 => [ 'item_name' => 'Item 2', 'item_amount' => 2345, 'item_currency_code' => 'EUR ], * ] * * @return array */ public function getExtraData() { $extraData = []; $orderDescription = []; if ($this->order instanceof Order) { $currency = $this->order->getAmount()->getCurrency(); /** * @var OrderLine $orderLine * * Line prices must be converted to the currency * of the Cart when they are defined in another * currency */ foreach ($this->order->getOrderLines() as $orderLine) { $orderLineArray = []; $purchasable = $orderLine->getPurchasable(); $orderLineName = $this->purchasableNameResolver->getPurchasableName($purchasable); $orderLineArray['item_name'] = $orderLineName; $lineAmount = $orderLine->getProductAmount(); /* * We need to convert any price to match * current order currency */ $convertedAmount = $this->currencyConverter->convertMoney($lineAmount, $currency); $orderLineArray['amount'] = $convertedAmount->getAmount(); /** * Line items currency should always match * the one from the order */ $orderLineArray['item_currency_code'] = $this->getCurrency(); $orderDescription[] = $orderLineName; $orderLineArray['quantity'] = $orderLine->getQuantity(); $extraData['items'][$orderLine->getId()] = $orderLineArray; } // We add the shipping costs as a new "shadow" line in the extraData structure. $shippingAmount = $this->order->getShippingAmount(); if ($shippingAmount->isGreaterThan(Money::create(0, $shippingAmount->getCurrency()))) { $extraData['items'][] = ['item_name' => 'shipping', 'item_currency_code' => $shippingAmount->getCurrency(), 'quantity' => 1, 'amount' => $shippingAmount->getAmount()]; } // We add the coupon discounts as a new "shadow" line in the extraData structure. $couponAmount = $this->order->getCouponAmount(); if ($couponAmount->isGreaterThan(Money::create(0, $couponAmount->getCurrency()))) { $extraData['discount_amount_cart'] = $couponAmount->getAmount(); } $extraData['order_description'] = implode(" - ", $orderDescription); } return $extraData; }
/** * Given a cart and a coupon, returns the real value of the coupon. * If the type of the coupon is not valid, then an empty Money instance will * be returned, with value 0. * * @param CartInterface $cart Abstract Cart object * @param CouponInterface $coupon Coupon * * @return MoneyInterface Coupon price */ public function getCouponAbsolutePrice(CartInterface $cart, CouponInterface $coupon) { $currency = $this->currencyWrapper->get(); $couponPrice = Money::create(0, $currency); switch ($coupon->getType()) { case ElcodiCouponTypes::TYPE_PERCENT: $couponPercent = $coupon->getDiscount(); $couponPrice = $cart->getProductAmount()->multiply($couponPercent / 100); break; case ElcodiCouponTypes::TYPE_AMOUNT: $amount = $coupon->getPrice(); $couponPrice = $this->currencyConverter->convertMoney($amount, $currency); break; } return $couponPrice; }
/** * Calculates all the amounts for a given a Cart * * @param CartInterface $cart Cart * * @return CartInterface Cart */ private function calculateCartPrices(CartInterface $cart) { $currency = $this->currencyWrapper->get(); $productAmount = Money::create(0, $currency); /** * Calculate Amount and ProductAmount */ foreach ($cart->getCartLines() as $cartLine) { /** * @var CartLineInterface $cartLine */ $cartLine = $this->loadCartLinePrices($cartLine); /** * @var MoneyInterface $productAmount * @var MoneyInterface $totalAmount */ $convertedProductAmount = $this->currencyConverter->convertMoney($cartLine->getProductAmount(), $currency); $productAmount = $productAmount->add($convertedProductAmount->multiply($cartLine->getQuantity())); } $cart->setProductAmount($productAmount)->setAmount($productAmount); }
/** * Load cart total price. * * @param CartInterface $cart Cart */ public function loadCartTotalAmount(CartInterface $cart) { $currency = $this->currencyWrapper->get(); $finalAmount = clone $cart->getPurchasableAmount(); /** * Calculates the shipping amount. */ $shippingAmount = $cart->getShippingAmount(); if ($shippingAmount instanceof MoneyInterface) { $convertedShippingAmount = $this->currencyConverter->convertMoney($shippingAmount, $currency); $finalAmount = $finalAmount->add($convertedShippingAmount); } /** * Calculates the coupon amount. */ $couponAmount = $cart->getCouponAmount(); if ($couponAmount instanceof MoneyInterface) { $convertedCouponAmount = $this->currencyConverter->convertMoney($couponAmount, $currency); $finalAmount = $finalAmount->subtract($convertedCouponAmount); } $cart->setAmount($finalAmount); }
/** * Calculate coupon absolute value. * * @param CartInterface $cart Cart * @param CouponInterface $coupon Coupon * * @return MoneyInterface|false Absolute value for this coupon in this cart */ public function getCouponAbsoluteValue(CartInterface $cart, CouponInterface $coupon) { $currency = $this->currencyWrapper->get(); $amount = $coupon->getPrice(); return $this->currencyConverter->convertMoney($amount, $currency); }