Exemple #1
0
 /**
  * @param Product $product
  * @param Country $country
  * @param $untaxedAmount
  * @param $untaxedPromoAmount
  * @param null    $askedLocale
  *
  * @return OrderProductTaxCollection
  */
 public function getTaxDetail(Product $product, Country $country, $untaxedAmount, $untaxedPromoAmount, $askedLocale = null)
 {
     $taxCalculator = new Calculator();
     $taxCollection = new OrderProductTaxCollection();
     $taxCalculator->loadTaxRule($this, $country, $product)->getTaxedPrice($untaxedAmount, $taxCollection, $askedLocale);
     $promoTaxCollection = new OrderProductTaxCollection();
     $taxCalculator->loadTaxRule($this, $country, $product)->getTaxedPrice($untaxedPromoAmount, $promoTaxCollection, $askedLocale);
     foreach ($taxCollection as $index => $tax) {
         $tax->setPromoAmount($promoTaxCollection->getKey($index)->getAmount());
     }
     return $taxCollection;
 }
 /**
  * @param array $data
  * @return array
  *
  * Return the untaxed prices to store
  */
 protected function extractPrices(array $data)
 {
     $calculator = new Calculator();
     $calculator->loadTaxRuleWithoutProduct(TaxRuleQuery::create()->findPk($data["tax_rule_id"]), Country::getShopLocation());
     $price = null === $data["price_with_tax"] ? $data["price"] : $calculator->getUntaxedPrice($data["price_with_tax"]);
     $salePrice = null === $data["sale_price_with_tax"] ? $data["sale_price"] : $calculator->getUntaxedPrice($data["sale_price_with_tax"]);
     return [$price, $salePrice];
 }
Exemple #3
0
 public function getTaxedPromoPrice(Country $country, $price)
 {
     $taxCalculator = new Calculator();
     return round($taxCalculator->load($this, $country)->getTaxedPrice($price), 2);
 }
 public function getTaxedPromoPrice(Country $country, $virtualColumnName = 'price_PROMO_PRICE', $discount = 0)
 {
     $taxCalculator = new Calculator();
     return round($taxCalculator->load($this->getProduct(), $country)->getTaxedPrice($this->getPromoPrice($virtualColumnName, $discount)), 2);
 }
 /**
  * Calculate taxed/untexted price for a product
  *
  * @param $price
  * @param $price_type
  * @param  Product $product
  * @param  bool    $convert
  * @return string
  */
 protected function computePrice($price, $price_type, Product $product, $convert = false)
 {
     $calc = new Calculator();
     $calc->load($product, Country::getShopLocation());
     if ($price_type == 'without_tax') {
         $return_price = $calc->getTaxedPrice($price);
     } elseif ($price_type == 'with_tax') {
         $return_price = $calc->getUntaxedPrice($price);
     } else {
         $return_price = $price;
     }
     if ($convert != 0) {
         $return_price = $price * Currency::getDefaultCurrency()->getRate();
     }
     return floatval($return_price);
 }
 /**
  * Calculate taxed/untexted price for a product
  *
  * @param $price
  * @param $price_type
  * @param  Product $product
  * @param  bool    $convert
  * @return string
  */
 protected function computePrice($price, $price_type, Product $product, $convert = false)
 {
     $calc = new Calculator();
     $calc->load($product, Country::getShopLocation());
     if ($price_type == 'without_tax') {
         $return_price = $calc->getTaxedPrice($price);
     } elseif ($price_type == 'with_tax') {
         $return_price = $calc->getUntaxedPrice($price);
     } else {
         $return_price = $price;
     }
     if ($convert != 0) {
         $return_price = $price * Currency::getDefaultCurrency()->getRate();
     }
     // Format the number using '.', to perform further calculation
     return NumberFormat::getInstance($this->getRequest())->formatStandardNumber($return_price);
 }
Exemple #7
0
 /**
  * Update the promo status of the sale's selected products and combinations
  *
  * @param  ProductSaleStatusUpdateEvent              $event
  * @throws \RuntimeException
  * @throws \Exception
  * @throws \Propel\Runtime\Exception\PropelException
  */
 public function updateProductsSaleStatus(ProductSaleStatusUpdateEvent $event)
 {
     $taxCalculator = new Calculator();
     $sale = $event->getSale();
     // Get all selected product sale elements for this sale
     if (null !== ($saleProducts = SaleProductQuery::create()->filterBySale($sale)->orderByProductId())) {
         $saleOffsetByCurrency = $sale->getPriceOffsets();
         $offsetType = $sale->getPriceOffsetType();
         $con = Propel::getWriteConnection(SaleTableMap::DATABASE_NAME);
         $con->beginTransaction();
         try {
             /** @var SaleProduct $saleProduct */
             foreach ($saleProducts as $saleProduct) {
                 // Reset all sale status on product's PSE
                 ProductSaleElementsQuery::create()->filterByProductId($saleProduct->getProductId())->update(['Promo' => false], $con);
                 $taxCalculator->load($saleProduct->getProduct($con), CountryModel::getShopLocation());
                 $attributeAvId = $saleProduct->getAttributeAvId();
                 $pseRequest = ProductSaleElementsQuery::create()->filterByProductId($saleProduct->getProductId());
                 // If no attribute AV id is defined, consider ALL product combinations
                 if (!is_null($attributeAvId)) {
                     // Find PSE attached to combination containing this attribute av :
                     // SELECT * from product_sale_elements pse
                     // left join attribute_combination ac on ac.product_sale_elements_id = pse.id
                     // where pse.product_id=363
                     // and ac.attribute_av_id = 7
                     // group by pse.id
                     $pseRequest->useAttributeCombinationQuery(null, Criteria::LEFT_JOIN)->filterByAttributeAvId($attributeAvId)->endUse();
                 }
                 $pseList = $pseRequest->find();
                 if (null !== $pseList) {
                     $this->updateProductSaleElementsPrices($pseList, $sale->getActive(), $offsetType, $taxCalculator, $saleOffsetByCurrency, $con);
                 }
             }
             $con->commit();
         } catch (PropelException $e) {
             $con->rollback();
             throw $e;
         }
     }
 }
 public function processGetOrders(ApiCallEvent $event)
 {
     $api = $event->getApi();
     $response = $api->getResponse();
     if ($response->isInError()) {
         $this->logger->error($response->getFormattedError());
         throw new BadResponseException($response->getFormattedError());
     }
     $dispatcher = $event->getDispatcher();
     $orders = $response->getGroup("Orders");
     $validOrders = [];
     /** @var \Thelia\Model\Country $country */
     $shopCountry = CountryQuery::create()->findOneByShopCountry(true);
     $calculator = new Calculator();
     /**
      * Check if there is only one order: reformat the array in that case
      */
     if (array_key_exists("IdOrder", $orders["Order"])) {
         $orders = array("Order" => [$orders["Order"]]);
     }
     $notImportedOrders = [];
     /**
      * Then treat the orders
      */
     foreach ($orders["Order"] as $orderArray) {
         /**
          * I) create the addresses
          */
         /**
          * Get delivery address, and format empty fields
          */
         $deliveryAddressArray =& $orderArray["ShippingAddress"];
         $deliveryCountryId = CountryQuery::create()->findOneByIsoalpha2(strtolower($deliveryAddressArray["Country"]))->getId();
         foreach ($deliveryAddressArray as &$value) {
             if (is_array($value)) {
                 $value = "";
             }
         }
         /**
          * Same for invoice address
          */
         $invoiceAddressArray =& $orderArray["BillingAddress"];
         $invoiceCountry = CountryQuery::create()->findOneByIsoalpha2(strtolower($invoiceAddressArray["Country"]));
         $invoiceCountryId = $invoiceCountry->getId();
         foreach ($invoiceAddressArray as &$value) {
             if (is_array($value)) {
                 $value = "";
             }
         }
         $title = CustomerTitleQuery::create()->findOne()->getId();
         /**
          * Create the order addresses
          */
         $deliveryAddressEvent = new AddressCreateOrUpdateEvent("Delivery address", $title, $deliveryAddressArray["FirstName"], $deliveryAddressArray["LastName"], $deliveryAddressArray["Street"], $deliveryAddressArray["Street1"], $deliveryAddressArray["Street2"], $deliveryAddressArray["PostalCode"], $deliveryAddressArray["Town"], $deliveryCountryId, $deliveryAddressArray["PhoneMobile"], $deliveryAddressArray["Phone"], $deliveryAddressArray["Company"]);
         $deliveryAddressEvent->setCustomer($this->shoppingFluxCustomer);
         $dispatcher->dispatch(TheliaEvents::ADDRESS_CREATE, $deliveryAddressEvent);
         $invoiceAddressEvent = new AddressCreateOrUpdateEvent("Invoice address", $title, $invoiceAddressArray["FirstName"], $invoiceAddressArray["LastName"], $invoiceAddressArray["Street"], $invoiceAddressArray["Street1"], $invoiceAddressArray["Street2"], $invoiceAddressArray["PostalCode"], $invoiceAddressArray["Town"], $deliveryCountryId, $invoiceAddressArray["PhoneMobile"], $invoiceAddressArray["Phone"], $invoiceAddressArray["Company"]);
         $invoiceAddressEvent->setCustomer($this->shoppingFluxCustomer);
         $dispatcher->dispatch(TheliaEvents::ADDRESS_CREATE, $invoiceAddressEvent);
         /**
          * II) Add the products to a cart
          */
         /**
          * Format the products array
          */
         if ($orderArray["NumberOfProducts"] == "1") {
             $orderArray["Products"] = array("Product" => [$orderArray["Products"]["Product"]]);
         }
         $productsArray =& $orderArray["Products"]["Product"];
         /**
          * Create a fake cart
          */
         $cart = new Cart();
         /**
          * And fulfil it with the products
          */
         foreach ($productsArray as &$productArray) {
             $ids = explode("_", $productArray["SKU"]);
             $cartPse = ProductSaleElementsQuery::create()->findPk($ids[1]);
             $calculator->load($cartPse->getProduct(), $shopCountry);
             $price = $calculator->getUntaxedPrice((double) $productArray["Price"]);
             $cart->addCartItem((new CartItem())->setProductSaleElements($cartPse)->setProduct($cartPse->getProduct())->setQuantity($productArray["Quantity"])->setPrice($price)->setPromoPrice(0)->setPromo(0));
         }
         /**
          * III) Create/Save the order
          */
         /**
          * Construct order model
          */
         $lang = LangQuery::create()->findOneByLocale($invoiceCountry->getLocale());
         $currency = CurrencyQuery::create()->findOneByCode("EUR");
         $order = OrderQuery::create()->findOneByRef($orderArray["IdOrder"]);
         if ($order !== null) {
             $order->delete();
         }
         $order = new Order();
         $order->setPostage($orderArray["TotalShipping"])->setChoosenDeliveryAddress($deliveryAddressEvent->getAddress()->getId())->setChoosenInvoiceAddress($invoiceAddressEvent->getAddress()->getId())->setDeliveryModuleId(ShoppingFluxConfigQuery::getDeliveryModuleId())->setPaymentModuleId($this->shoppingFluxPaymentModuleId)->setTransactionRef($orderArray["Marketplace"]);
         /**
          * Construct event
          */
         $orderEvent = new OrderManualEvent($order, $currency, $lang, $cart, $this->shoppingFluxCustomer);
         $orderEvent->setDispatcher($dispatcher);
         $dispatcher->dispatch(TheliaEvents::ORDER_CREATE_MANUAL, $orderEvent);
         $placedOrder = $orderEvent->getPlacedOrder();
         $placedOrder->setRef($orderArray["IdOrder"])->setPaid();
         $validOrders[] = ["IdOrder" => $placedOrder->getRef(), "Marketplace" => $placedOrder->getTransactionRef()];
     }
     /**
      * IV) Valid the orders to Shopping Flux
      */
     $request = new Request("ValidOrders");
     foreach ($validOrders as $validOrder) {
         $request->addOrder($validOrder);
     }
     $validOrdersApi = new ValidOrders($response->getToken(), $response->getMode());
     $validOrdersApi->setRequest($request);
     $validOrdersResponse = $validOrdersApi->getResponse();
     if ($validOrdersResponse->isInError()) {
         $this->logger->error($response->getFormattedError());
     }
 }
 /**
  * @param Cart $cart
  * @param $areaId
  * @return |null
  */
 protected function getSlicePostage(Cart $cart, Country $country)
 {
     $config = self::getConfig();
     $currency = $cart->getCurrency();
     $areaId = $country->getAreaId();
     $query = CustomDeliverySliceQuery::create()->filterByAreaId($areaId);
     if ($config['method'] != CustomDelivery::METHOD_PRICE) {
         $query->filterByWeightMax($cart->getWeight(), Criteria::GREATER_THAN);
         $query->orderByWeightMax(Criteria::ASC);
     }
     if ($config['method'] != CustomDelivery::METHOD_WEIGHT) {
         $total = $cart->getTotalAmount();
         // convert amount to the default currency
         if (0 == $currency->getByDefault()) {
             $total = $total / $currency->getRate();
         }
         $query->filterByPriceMax($total, Criteria::GREATER_THAN);
         $query->orderByPriceMax(Criteria::ASC);
     }
     $slice = $query->findOne();
     $postage = null;
     if (null !== $slice) {
         $postage = new OrderPostage();
         if (0 == $currency->getByDefault()) {
             $price = $slice->getPrice() * $currency->getRate();
         } else {
             $price = $slice->getPrice();
         }
         $price = round($price, 2);
         $postage->setAmount($price);
         $postage->setAmountTax(0);
         // taxed amount
         if (0 !== $config['tax']) {
             $taxRuleI18N = I18n::forceI18nRetrieving($this->getRequest()->getSession()->getLang()->getLocale(), 'TaxRule', $config['tax']);
             $taxRule = TaxRuleQuery::create()->findPk($config['tax']);
             if (null !== $taxRule) {
                 $taxCalculator = new Calculator();
                 $taxCalculator->loadTaxRuleWithoutProduct($taxRule, $country);
                 $postage->setAmount(round($taxCalculator->getTaxedPrice($price), 2));
                 $postage->setAmountTax($postage->getAmount() - $price);
                 $postage->setTaxRuleTitle($taxRuleI18N->getTitle());
             }
         }
     }
     return $postage;
 }
Exemple #10
0
 public function getTaxedPromoPrice(Country $country)
 {
     $taxCalculator = new Calculator();
     return round($taxCalculator->load($this->getProduct(), $country)->getTaxedPrice($this->getPromoPrice()), 2);
 }
Exemple #11
0
 /**
  * @since Version 2.3
  * @param Country $country
  * @param State|null $state
  * @return float
  */
 public function getTotalTaxedPromoPrice(Country $country, State $state = null)
 {
     $taxCalculator = new Calculator();
     return $taxCalculator->load($this->getProduct(), $country, $state)->getTaxedPrice($this->getPromoPrice() * $this->getQuantity());
 }
Exemple #12
0
 /**
  * @expectedException \Thelia\Exception\TaxEngineException
  * @expectedExceptionCode 503
  */
 public function testGetTaxedPriceBadTaxRulesCollection()
 {
     $calculator = new Calculator();
     $calculator->getTaxedPrice(500);
 }
 /**
  * Copy of default product loop price filter but with tax applied to asked price
  * @param $search
  * @param $minPriceTTC
  * @param $maxPriceTTC
  * @throws \Propel\Runtime\Exception\PropelException
  */
 protected function managePriceFilter(&$search, $minPriceTTC, $maxPriceTTC)
 {
     $categoryId = $this->getCategoryId();
     $taxeRuleQuery = TaxRuleQuery::create();
     $categoryJoin = new Join();
     $categoryJoin->addExplicitCondition(TaxRuleTableMap::TABLE_NAME, 'ID', null, CriteriaSearchCategoryTaxRuleTableMap::TABLE_NAME, 'TAX_RULE_ID', null);
     $categoryJoin->setJoinType(Criteria::LEFT_JOIN);
     $taxeRuleQuery->addJoinObject($categoryJoin, 'category_join')->addJoinCondition('category_join', CriteriaSearchCategoryTaxRuleTableMap::CATEGORY_ID . ' = ' . $categoryId);
     $taxeRule = $taxeRuleQuery->findOne();
     $taxCountry = $this->container->get('thelia.taxEngine')->getDeliveryCountry();
     $calculator = new Calculator();
     $calculator->loadTaxRuleWithoutProduct($taxeRule, $taxCountry);
     $currencyId = $this->getCurrency();
     if (null !== $currencyId) {
         $currency = CurrencyQuery::create()->findOneById($currencyId);
         if (null === $currency) {
             throw new \InvalidArgumentException('Cannot found currency id: `' . $currency . '` in product_sale_elements loop');
         }
     } else {
         $currency = $this->request->getSession()->getCurrency();
     }
     $defaultCurrency = CurrencyQuery::create()->findOneByByDefault(1);
     $defaultCurrencySuffix = '_default_currency';
     if (null !== $minPriceTTC) {
         $minPriceHt = round($calculator->getUntaxedPrice($minPriceTTC), 2);
         $isPSELeftJoinList[] = 'is_min_price';
         $minPriceJoin = new Join();
         $minPriceJoin->addExplicitCondition(ProductSaleElementsTableMap::TABLE_NAME, 'ID', 'is_min_price_ttc', ProductPriceTableMap::TABLE_NAME, 'PRODUCT_SALE_ELEMENTS_ID', 'min_price_ttc_data');
         $minPriceJoin->setJoinType(Criteria::LEFT_JOIN);
         $search->joinProductSaleElements('is_min_price_ttc', Criteria::LEFT_JOIN)->addJoinObject($minPriceJoin, 'is_min_price_ttc_join')->addJoinCondition('is_min_price_ttc_join', '`min_price_ttc_data`.`currency_id` = ?', $currency->getId(), null, \PDO::PARAM_INT);
         if ($defaultCurrency->getId() != $currency->getId()) {
             $minPriceJoinDefaultCurrency = new Join();
             $minPriceJoinDefaultCurrency->addExplicitCondition(ProductSaleElementsTableMap::TABLE_NAME, 'ID', 'is_min_price_ttc', ProductPriceTableMap::TABLE_NAME, 'PRODUCT_SALE_ELEMENTS_ID', 'min_price_ttc_data' . $defaultCurrencySuffix);
             $minPriceJoinDefaultCurrency->setJoinType(Criteria::LEFT_JOIN);
             $search->addJoinObject($minPriceJoinDefaultCurrency, 'is_min_price_ttc_join' . $defaultCurrencySuffix)->addJoinCondition('is_min_price_ttc_join' . $defaultCurrencySuffix, '`min_price_ttc_data' . $defaultCurrencySuffix . '`.`currency_id` = ?', $defaultCurrency->getId(), null, \PDO::PARAM_INT);
             /**
              * In propel we trust : $currency->getRate() always returns a float.
              * Or maybe not : rate value is checked as a float in overloaded getRate method.
              */
             $MinPriceToCompareAsSQL = 'CASE WHEN ISNULL(CASE WHEN `is_min_price_ttc`.PROMO=1 THEN `min_price_ttc_data`.PROMO_PRICE ELSE `min_price_ttc_data`.PRICE END) OR `min_price_ttc_data`.FROM_DEFAULT_CURRENCY = 1 THEN
                 CASE WHEN `is_min_price_ttc`.PROMO=1 THEN `min_price_ttc_data' . $defaultCurrencySuffix . '`.PROMO_PRICE ELSE `min_price_ttc_data' . $defaultCurrencySuffix . '`.PRICE END * ' . $currency->getRate() . '
             ELSE
                 CASE WHEN `is_min_price_ttc`.PROMO=1 THEN `min_price_ttc_data`.PROMO_PRICE ELSE `min_price_ttc_data`.PRICE END
             END';
         } else {
             $MinPriceToCompareAsSQL = 'CASE WHEN `is_min_price_ttc`.PROMO=1 THEN `min_price_ttc_data`.PROMO_PRICE ELSE `min_price_ttc_data`.PRICE END';
         }
         $search->where('ROUND(' . $MinPriceToCompareAsSQL . ', 2)>=?', $minPriceHt, \PDO::PARAM_STR);
     }
     if (null !== $maxPriceTTC) {
         $maxPriceHt = round($calculator->getUntaxedPrice($maxPriceTTC), 2);
         $isPSELeftJoinList[] = 'is_max_price_ttc';
         $maxPriceJoin = new Join();
         $maxPriceJoin->addExplicitCondition(ProductSaleElementsTableMap::TABLE_NAME, 'ID', 'is_max_price_ttc', ProductPriceTableMap::TABLE_NAME, 'PRODUCT_SALE_ELEMENTS_ID', 'max_price_ttc_data');
         $maxPriceJoin->setJoinType(Criteria::LEFT_JOIN);
         $search->joinProductSaleElements('is_max_price_ttc', Criteria::LEFT_JOIN)->addJoinObject($maxPriceJoin, 'is_max_price_ttc_join')->addJoinCondition('is_max_price_ttc_join', '`max_price_ttc_data`.`currency_id` = ?', $currency->getId(), null, \PDO::PARAM_INT);
         if ($defaultCurrency->getId() != $currency->getId()) {
             $maxPriceJoinDefaultCurrency = new Join();
             $maxPriceJoinDefaultCurrency->addExplicitCondition(ProductSaleElementsTableMap::TABLE_NAME, 'ID', 'is_max_price_ttc', ProductPriceTableMap::TABLE_NAME, 'PRODUCT_SALE_ELEMENTS_ID', 'max_price_ttc_data' . $defaultCurrencySuffix);
             $maxPriceJoinDefaultCurrency->setJoinType(Criteria::LEFT_JOIN);
             $search->addJoinObject($maxPriceJoinDefaultCurrency, 'is_max_price_ttc_join' . $defaultCurrencySuffix)->addJoinCondition('is_max_price_ttc_join' . $defaultCurrencySuffix, '`max_price_ttc_data' . $defaultCurrencySuffix . '`.`currency_id` = ?', $defaultCurrency->getId(), null, \PDO::PARAM_INT);
             /**
              * In propel we trust : $currency->getRate() always returns a float.
              * Or maybe not : rate value is checked as a float in overloaded getRate method.
              */
             $MaxPriceToCompareAsSQL = 'CASE WHEN ISNULL(CASE WHEN `is_max_price_ttc`.PROMO=1 THEN `max_price_ttc_data`.PROMO_PRICE ELSE `max_price_ttc_data`.PRICE END) OR `min_price_data`.FROM_DEFAULT_CURRENCY = 1 THEN
                 CASE WHEN `is_max_price_ttc`.PROMO=1 THEN `max_price_ttc_data' . $defaultCurrencySuffix . '`.PROMO_PRICE ELSE `max_price_ttc_data' . $defaultCurrencySuffix . '`.PRICE END * ' . $currency->getRate() . '
             ELSE
                 CASE WHEN `is_max_price_ttc`.PROMO=1 THEN `max_price_ttc_data`.PROMO_PRICE ELSE `max_price_ttc_data`.PRICE END
             END';
         } else {
             $MaxPriceToCompareAsSQL = 'CASE WHEN `is_max_price_ttc`.PROMO=1 THEN `max_price_ttc_data`.PROMO_PRICE ELSE `max_price_ttc_data`.PRICE END';
         }
         $search->where('ROUND(' . $MaxPriceToCompareAsSQL . ', 2)<=?', $maxPriceHt, \PDO::PARAM_STR);
     }
 }