/** * @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]; }
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); }
/** * 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; }
public function getTaxedPromoPrice(Country $country) { $taxCalculator = new Calculator(); return round($taxCalculator->load($this->getProduct(), $country)->getTaxedPrice($this->getPromoPrice()), 2); }
/** * @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()); }
/** * @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); } }