public function importData(array $data) { $pse = ProductSaleElementsQuery::create()->findPk($data['id']); if ($pse === null) { return Translator::getInstance()->trans('The product sale element id %id doesn\'t exist', ['%id' => $data['id']]); } else { $currency = null; if (isset($data['currency'])) { $currency = CurrencyQuery::create()->findOneByCode($data['currency']); } if ($currency === null) { $currency = Currency::getDefaultCurrency(); } $price = ProductPriceQuery::create()->filterByProductSaleElementsId($pse->getId())->findOneByCurrencyId($currency->getId()); if ($price === null) { $price = new ProductPrice(); $price->setProductSaleElements($pse)->setCurrency($currency); } $price->setPrice($data['price']); if (isset($data['promo_price'])) { $price->setPromoPrice($data['promo_price']); } if (isset($data['promo'])) { $price->getProductSaleElements()->setPromo((int) $data['promo'])->save(); } $price->save(); $this->importedRows++; } return null; }
/** * @param int $month * @param int $year * @return \stdClass */ protected function getStatus($month, $year) { $data = new \stdClass(); $data->title = $this->getTranslator()->trans("Stats on %month/%year", ['%month' => $month, '%year' => $year], HookAdminHome::DOMAIN_NAME); $data->series = []; /* sales */ $data->series[] = $saleSeries = new \stdClass(); $saleSeries->color = self::testHexColor('sales_color', '#adadad'); $saleSeries->data = OrderQuery::getMonthlySaleStats($month, $year); $saleSeries->valueFormat = "%1.2f " . Currency::getDefaultCurrency()->getSymbol(); /* new customers */ $data->series[] = $newCustomerSeries = new \stdClass(); $newCustomerSeries->color = self::testHexColor('customers_color', '#f39922'); $newCustomerSeries->data = CustomerQuery::getMonthlyNewCustomersStats($month, $year); $newCustomerSeries->valueFormat = "%d"; /* orders */ $data->series[] = $orderSeries = new \stdClass(); $orderSeries->color = self::testHexColor('orders_color', '#5cb85c'); $orderSeries->data = OrderQuery::getMonthlyOrdersStats($month, $year); $orderSeries->valueFormat = "%d"; /* first order */ $data->series[] = $firstOrderSeries = new \stdClass(); $firstOrderSeries->color = self::testHexColor('first_orders_color', '#5bc0de'); $firstOrderSeries->data = OrderQuery::getFirstOrdersStats($month, $year); $firstOrderSeries->valueFormat = "%d"; /* cancelled orders */ $data->series[] = $cancelledOrderSeries = new \stdClass(); $cancelledOrderSeries->color = self::testHexColor('cancelled_orders_color', '#d9534f'); $cancelledOrderSeries->data = OrderQuery::getMonthlyOrdersStats($month, $year, array(5)); $cancelledOrderSeries->valueFormat = "%d"; return $data; }
/** * Get product prices for a specific currency. * * When the currency is not the default currency, the product prices for this currency is : * - calculated according to the product price of the default currency. It happens when no product price exists for * the currency or when the `from_default_currency` flag is set to `true` * - set directly in the product price when `from_default_currency` is set to `false` * * @param Currency $currency * @return ProductPriceTools * @throws \RuntimeException */ public function getPricesByCurrency(Currency $currency, $discount = 0) { $defaultCurrency = Currency::getDefaultCurrency(); $productPrice = ProductPriceQuery::create()->filterByProductSaleElementsId($this->getId())->filterByCurrencyId($currency->getId())->findOne(); $price = 0.0; $promoPrice = 0.0; if (null === $productPrice || $productPrice->getFromDefaultCurrency()) { // need to calculate the prices based on the product prices for the default currency $productPrice = ProductPriceQuery::create()->filterByProductSaleElementsId($this->getId())->filterByCurrencyId($defaultCurrency->getId())->findOne(); if (null !== $productPrice) { $price = $productPrice->getPrice() * $currency->getRate() / $defaultCurrency->getRate(); $promoPrice = $productPrice->getPromoPrice() * $currency->getRate() / $defaultCurrency->getRate(); } else { throw new \RuntimeException('Cannot find product prices for currency id: `' . $currency->getId() . '`'); } } else { $price = $productPrice->getPrice(); $promoPrice = $productPrice->getPromoPrice(); } if ($discount > 0) { $price = $price * (1 - $discount / 100); $promoPrice = $promoPrice * (1 - $discount / 100); } $productPriceTools = new ProductPriceTools($price, $promoPrice); return $productPriceTools; }
public function testImport() { $currency = Currency::getDefaultCurrency(); $query = ProductSaleElementsQuery::create()->addAscendingOrderByColumn('RAND()')->limit(3)->find(); $jsonData = []; $data = []; /** @var \Thelia\Model\ProductSaleElements $pse */ foreach ($query as $pse) { $entry = []; $entry["ref"] = $pse->getRef(); /** * Be sure to get a different value. */ while ($pse->getPricesByCurrency($currency)->getPrice() === ($entry["price"] = rand(0, 1000))) { } while ($pse->getPricesByCurrency($currency)->getPromoPrice() === ($entry["promo_price"] = rand(0, 1000))) { } while ($pse->getPromo() === ($entry["promo_price"] = rand(0, 1000))) { } $data[$pse->getId()] = $entry; $jsonData[] = $entry; } $jsonString = json_encode($jsonData); $this->assertEquals("Import successfully done, 3 row(s) have been changed", $this->controller->processImport($jsonString, $this->import, new JsonFormatter(), null)); $query = ProductSaleElementsQuery::create()->findPks(array_keys($data)); /** @var \Thelia\Model\ProductSaleElements $entry */ foreach ($query as $entry) { $this->assertEquals($data[$entry->getId()], ["price" => $entry->getPricesByCurrency($currency)->getPrice(), "promo_price" => $entry->getPricesByCurrency($currency)->getPromoPrice(), "ref" => $entry->getRef()]); } }
public function getAdminEditionCurrency() { $currency = $this->get('thelia.admin.edition.currency', null); if (null === $currency) { $currency = Currency::getDefaultCurrency(); } return $currency; }
/** * @param \Thelia\Core\FileFormat\Formatting\FormatterData * @return string|array error messages * * The method does the import routine from a FormatterData */ public function retrieveFromFormatterData(FormatterData $data) { $errors = []; $translator = Translator::getInstance(); while (null !== ($row = $data->popRow())) { $this->checkMandatoryColumns($row); $obj = ProductSaleElementsQuery::create()->findOneByRef($row["ref"]); if ($obj === null) { $errorMessage = $translator->trans("The product sale element reference %ref doesn't exist", ["%ref" => $row["ref"]]); $errors[] = $errorMessage; } else { $currency = null; if (isset($row["currency"])) { $currency = CurrencyQuery::create()->findOneByCode($row["currency"]); } if ($currency === null) { $currency = Currency::getDefaultCurrency(); } $price = ProductPriceQuery::create()->filterByProductSaleElementsId($obj->getId())->findOneByCurrencyId($currency->getId()); if ($price === null) { $price = new ProductPrice(); $price->setProductSaleElements($obj)->setCurrency($currency); } $price->setPrice($row["price"]); if (isset($row["promo_price"])) { $price->setPromoPrice($row["promo_price"]); } if (isset($row["promo"])) { $price->getProductSaleElements()->setPromo((int) $row["promo"])->save(); } $price->save(); $this->importedRows++; } } return $errors; }
protected function defineCurrency(Request $request) { $currency = null; if ($request->query->has("currency")) { $currency = CurrencyQuery::create()->findOneByCode($request->query->get("currency")); if ($currency) { if (false === $this->app->getContainer()->isScopeActive('request')) { $this->app->getContainer()->enterScope('request'); $this->app->getContainer()->set('request', $request, 'request'); } $this->eventDispatcher->dispatch(TheliaEvents::CHANGE_DEFAULT_CURRENCY, new CurrencyChangeEvent($currency, $request)); } } else { $currency = $request->getSession()->getCurrency(false); } if (null === $currency) { $currency = Currency::getDefaultCurrency(); } return $currency; }
protected function buildForm() { $this->formBuilder->add("product_id", "integer", array("label" => Translator::getInstance()->trans("Product ID *"), "label_attr" => array("for" => "product_id_field"), "constraints" => array(new GreaterThan(array('value' => 0)))))->add("product_sale_element_id", "integer", array("label" => Translator::getInstance()->trans("Product sale element ID *"), "label_attr" => array("for" => "product_sale_element_id_field")))->add("reference", "text", array("label" => Translator::getInstance()->trans("Reference *"), "label_attr" => array("for" => "reference_field")))->add("price", "number", array("constraints" => array(new NotBlank()), "label" => Translator::getInstance()->trans("Product price excluding taxes *"), "label_attr" => array("for" => "price_field")))->add("price_with_tax", "number", array("label" => Translator::getInstance()->trans("Product price including taxes"), "label_attr" => array("for" => "price_with_tax_field")))->add("currency", "integer", array("constraints" => array(new NotBlank()), "label" => Translator::getInstance()->trans("Price currency *"), "label_attr" => array("for" => "currency_field")))->add("tax_rule", "integer", array("constraints" => array(new NotBlank()), "label" => Translator::getInstance()->trans("Tax rule for this product *"), "label_attr" => array("for" => "tax_rule_field")))->add("weight", "number", array("label" => Translator::getInstance()->trans("Weight"), "label_attr" => array("for" => "weight_field")))->add("quantity", "number", array("constraints" => array(new NotBlank()), "label" => Translator::getInstance()->trans("Available quantity *"), "label_attr" => array("for" => "quantity_field")))->add("sale_price", "number", array("label" => Translator::getInstance()->trans("Sale price excluding taxes"), "label_attr" => array("for" => "price_with_tax_field")))->add("sale_price_with_tax", "number", array("label" => Translator::getInstance()->trans("Sale price including taxes"), "label_attr" => array("for" => "sale_price_with_tax_field")))->add("onsale", "integer", array("label" => Translator::getInstance()->trans("This product is on sale"), "label_attr" => array("for" => "onsale_field")))->add("isnew", "integer", array("label" => Translator::getInstance()->trans("Advertise this product as new"), "label_attr" => array("for" => "isnew_field")))->add("isdefault", "integer", array("label" => Translator::getInstance()->trans("Is it the default product sale element ?"), "label_attr" => array("for" => "isdefault_field")))->add("ean_code", "text", array("label" => Translator::getInstance()->trans("EAN Code"), "label_attr" => array("for" => "ean_code_field")))->add("use_exchange_rate", "integer", array("label" => Translator::getInstance()->trans("Apply exchange rates on price in %sym", array("%sym" => Currency::getDefaultCurrency()->getSymbol())), "label_attr" => array("for" => "use_exchange_rate_field"))); }
/** * 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); }
protected function buildForm() { $this->formBuilder->add("tax_rule", "integer", array("constraints" => array(new NotBlank()), "label" => Translator::getInstance()->trans("Tax rule for this product *"), "label_attr" => array("for" => "tax_rule_field")))->add("product_id", "integer", array("label" => Translator::getInstance()->trans("Product ID *"), "label_attr" => array("for" => "product_id_field"), "constraints" => array(new GreaterThan(array('value' => 0)))))->add("default_pse", "integer", array("label" => Translator::getInstance()->trans("Default product sale element"), "label_attr" => array("for" => "default_pse_field")))->add("currency", "integer", array("constraints" => array(new NotBlank()), "label" => Translator::getInstance()->trans("Price currency *"), "label_attr" => array("for" => "currency_field")))->add("use_exchange_rate", "integer", array("label" => Translator::getInstance()->trans("Apply exchange rates on price in %sym", array("%sym" => Currency::getDefaultCurrency()->getSymbol())), "label_attr" => array("for" => "use_exchange_rate_field")))->add('product_sale_element_id', 'collection', array('type' => 'integer', 'label' => Translator::getInstance()->trans('Product sale element ID *'), 'label_attr' => array('for' => 'product_sale_element_id_field'), 'allow_add' => true, 'allow_delete' => true))->add('reference', 'collection', array('type' => 'text', 'label' => Translator::getInstance()->trans('Reference *'), 'label_attr' => array('for' => 'reference_field'), 'allow_add' => true, 'allow_delete' => true))->add('price', 'collection', array('type' => 'number', 'label' => Translator::getInstance()->trans('Product price excluding taxes *'), 'label_attr' => array('for' => 'price_field'), 'allow_add' => true, 'allow_delete' => true, 'options' => array('constraints' => array(new NotBlank()))))->add('price_with_tax', 'collection', array('type' => 'number', 'label' => Translator::getInstance()->trans('Product price including taxes'), 'label_attr' => array('for' => 'price_with_tax_field'), 'allow_add' => true, 'allow_delete' => true))->add('weight', 'collection', array('type' => 'number', 'label' => Translator::getInstance()->trans('Weight'), 'label_attr' => array('for' => 'weight_field'), 'allow_add' => true, 'allow_delete' => true))->add('quantity', 'collection', array('type' => 'number', 'label' => Translator::getInstance()->trans('Available quantity *'), 'label_attr' => array('for' => 'quantity_field'), 'allow_add' => true, 'allow_delete' => true, 'options' => array('constraints' => array(new NotBlank()))))->add('sale_price', 'collection', array('label' => Translator::getInstance()->trans('Sale price excluding taxes'), 'label_attr' => array('for' => 'price_with_tax_field'), 'allow_add' => true, 'allow_delete' => true))->add('sale_price_with_tax', 'collection', array('type' => 'number', 'label' => Translator::getInstance()->trans('Sale price including taxes'), 'label_attr' => array('for' => 'sale_price_with_tax_field'), 'allow_add' => true, 'allow_delete' => true))->add('onsale', 'collection', array('type' => 'integer', 'label' => Translator::getInstance()->trans('This product is on sale'), 'label_attr' => array('for' => 'onsale_field'), 'allow_add' => true, 'allow_delete' => true))->add('isnew', 'collection', array('type' => 'integer', 'label' => Translator::getInstance()->trans('Advertise this product as new'), 'label_attr' => array('for' => 'isnew_field'), 'allow_add' => true, 'allow_delete' => true))->add('isdefault', 'collection', array('type' => 'integer', 'label' => Translator::getInstance()->trans('Is it the default product sale element ?'), 'label_attr' => array('for' => 'isdefault_field'), 'allow_add' => true, 'allow_delete' => true))->add('ean_code', 'collection', array('type' => 'text', 'label' => Translator::getInstance()->trans('EAN Code'), 'label_attr' => array('for' => 'ean_code_field'), 'allow_add' => true, 'allow_delete' => true)); }
public function checkCurrency(GetResponseEvent $event) { /** @var Request $request */ $request = $event->getRequest(); if ($request->query->has("currency")) { if (null !== ($find = CurrencyQuery::create()->filterById($request->getSession()->getCurrency(true)->getId(), Criteria::NOT_EQUAL)->filterByCode($request->query->get("currency"))->findOne())) { $request->getSession()->setCurrency($find); $this->eventDispatcher->dispatch(TheliaEvents::CHANGE_DEFAULT_CURRENCY, new CurrencyChangeEvent($find, $request)); } else { $defaultCurrency = Currency::getDefaultCurrency(); $request->getSession()->setCurrency($defaultCurrency); $this->eventDispatcher->dispatch(TheliaEvents::CHANGE_DEFAULT_CURRENCY, new CurrencyChangeEvent($defaultCurrency, $request)); } } }
/** * 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); }
public function testGetDefaultCurrency() { $expectedCurrency = CurrencyQuery::create()->findOneByByDefault(true); $actualCurrency = Currency::getDefaultCurrency(); $this->assertEquals($expectedCurrency->getId(), $actualCurrency->getId()); }
/** * @param Lang $lang * @return array|\Propel\Runtime\ActiveQuery\ModelCriteria * * The tax engine of Thelia is in PHP, so we can't compute orders for each customers * directly in SQL, we need two SQL queries, and some computing to get the last order amount and total amount. */ public function buildDataSet(Lang $lang) { $locale = $lang->getLocale(); /** * This first query get each customer info and addresses. */ $newsletterJoin = new Join(CustomerTableMap::EMAIL, NewsletterTableMap::EMAIL, Criteria::LEFT_JOIN); $query = CustomerQuery::create()->useCustomerTitleQuery("customer_title_")->useCustomerTitleI18nQuery("customer_title_i18n_")->addAsColumn("title_TITLE", "customer_title_i18n_.SHORT")->endUse()->endUse()->useAddressQuery()->useCountryQuery()->useCountryI18nQuery()->addAsColumn("address_COUNTRY", CountryI18nTableMap::TITLE)->endUse()->endUse()->useCustomerTitleQuery("address_title")->useCustomerTitleI18nQuery("address_title_i18n")->addAsColumn("address_TITLE", "address_title_i18n.SHORT")->endUse()->endUse()->addAsColumn("address_LABEL", AddressTableMap::LABEL)->addAsColumn("address_FIRST_NAME", AddressTableMap::FIRSTNAME)->addAsColumn("address_LAST_NAME", AddressTableMap::LASTNAME)->addAsColumn("address_COMPANY", AddressTableMap::COMPANY)->addAsColumn("address_ADDRESS1", AddressTableMap::ADDRESS1)->addAsColumn("address_ADDRESS2", AddressTableMap::ADDRESS2)->addAsColumn("address_ADDRESS3", AddressTableMap::ADDRESS3)->addAsColumn("address_ZIPCODE", AddressTableMap::ZIPCODE)->addAsColumn("address_CITY", AddressTableMap::CITY)->addAsColumn("address_PHONE", AddressTableMap::PHONE)->addAsColumn("address_CELLPHONE", AddressTableMap::CELLPHONE)->addAsColumn("address_IS_DEFAULT", AddressTableMap::IS_DEFAULT)->endUse()->addJoinObject($newsletterJoin)->addAsColumn("newsletter_IS_REGISTRED", "IF(NOT ISNULL(" . NewsletterTableMap::EMAIL . "),1,0)")->select([CustomerTableMap::ID, CustomerTableMap::REF, CustomerTableMap::LASTNAME, CustomerTableMap::FIRSTNAME, CustomerTableMap::EMAIL, CustomerTableMap::DISCOUNT, CustomerTableMap::CREATED_AT, "title_TITLE", "address_TITLE", "address_LABEL", "address_COMPANY", "address_FIRST_NAME", "address_LAST_NAME", "address_ADDRESS1", "address_ADDRESS2", "address_ADDRESS3", "address_ZIPCODE", "address_CITY", "address_COUNTRY", "address_PHONE", "address_CELLPHONE", "address_IS_DEFAULT", "newsletter_IS_REGISTRED"])->orderById(); I18n::addI18nCondition($query, CountryI18nTableMap::TABLE_NAME, CountryTableMap::ID, CountryI18nTableMap::ID, CountryI18nTableMap::LOCALE, $locale); I18n::addI18nCondition($query, CustomerTitleI18nTableMap::TABLE_NAME, "`customer_title_`.ID", "`customer_title_i18n_`.ID", "`customer_title_i18n_`.LOCALE", $locale); I18n::addI18nCondition($query, CustomerTitleI18nTableMap::TABLE_NAME, "`address_title`.ID", "`address_title_i18n`.ID", "`address_title_i18n`.LOCALE", $locale); /** @var CustomerQuery $query */ $results = $query->find()->toArray(); /** * Then get the orders */ $orders = OrderQuery::create()->useCustomerQuery()->orderById()->endUse()->find(); /** * And add them info the array */ $orders->rewind(); $arrayLength = count($results); $previousCustomerId = null; for ($i = 0; $i < $arrayLength; ++$i) { $currentCustomer =& $results[$i]; $currentCustomerId = $currentCustomer[CustomerTableMap::ID]; unset($currentCustomer[CustomerTableMap::ID]); if ($currentCustomerId === $previousCustomerId) { $currentCustomer["title_TITLE"] = ""; $currentCustomer[CustomerTableMap::LASTNAME] = ""; $currentCustomer[CustomerTableMap::FIRSTNAME] = ""; $currentCustomer[CustomerTableMap::EMAIL] = ""; $currentCustomer["address_COMPANY"] = ""; $currentCustomer["newsletter_IS_REGISTRED"] = ""; $currentCustomer[CustomerTableMap::CREATED_AT] = ""; $currentCustomer[CustomerTableMap::DISCOUNT] = ""; $currentCustomer += ["order_TOTAL" => "", "last_order_AMOUNT" => "", "last_order_DATE" => ""]; } else { /** * Reformat created_at date */ $date = $currentCustomer[CustomerTableMap::CREATED_AT]; $dateTime = new \DateTime($date); $currentCustomer[CustomerTableMap::CREATED_AT] = $dateTime->format($lang->getDatetimeFormat()); /** * Then compute everything about the orders */ $total = 0; $lastOrderAmount = 0; $lastOrderDate = null; $lastOrder = null; $lastOrderCurrencyCode = null; $lastOrderId = 0; $defaultCurrency = Currency::getDefaultCurrency(); $defaultCurrencyCode = $defaultCurrency->getCode(); if (empty($defaultCurrencyCode)) { $defaultCurrencyCode = $defaultCurrency->getCode(); } $formattedDate = null; /** @var \Thelia\Model\Order $currentOrder */ while (false !== ($currentOrder = $orders->current())) { if ($currentCustomerId != $currentOrder->getCustomerId()) { break; } $amount = $currentOrder->getTotalAmount($tax); if (0 < ($rate = $currentOrder->getCurrencyRate())) { $amount = round($amount / $rate, 2); } $total += $amount; /** @var \DateTime $date */ $date = $currentOrder->getCreatedAt(); if (null === $lastOrderDate || $date >= $lastOrderDate && $lastOrderId < $currentOrder->getId()) { $lastOrder = $currentOrder; $lastOrderDate = $date; $lastOrderId = $currentOrder->getId(); } $orders->next(); } if ($lastOrderDate !== null) { $formattedDate = $lastOrderDate->format($lang->getDatetimeFormat()); $orderCurrency = $lastOrder->getCurrency(); $lastOrderCurrencyCode = $orderCurrency->getCode(); if (empty($lastOrderCurrencyCode)) { $lastOrderCurrencyCode = $orderCurrency->getCode(); } $lastOrderAmount = $lastOrder->getTotalAmount($tax_); } $currentCustomer += ["order_TOTAL" => $total . " " . $defaultCurrencyCode, "last_order_AMOUNT" => $lastOrderAmount === 0 ? "" : $lastOrderAmount . " " . $lastOrderCurrencyCode, "last_order_DATE" => $formattedDate]; } $previousCustomerId = $currentCustomerId; } return $results; }
public function buildModelCriteria() { $search = ProductSaleElementsQuery::create(); $id = $this->getId(); $product = $this->getProduct(); $ref = $this->getRef(); if (!is_null($id)) { $search->filterById($id, Criteria::IN); } elseif (!is_null($product)) { $search->filterByProductId($product, Criteria::EQUAL); } elseif (!is_null($ref)) { $search->filterByRef($ref, Criteria::EQUAL); } else { $searchTerm = $this->getArgValue('search_term'); $searchIn = $this->getArgValue('search_in'); if (null === $searchTerm || null === $searchIn) { throw new \InvalidArgumentException("Either 'id', 'product', 'ref', 'search_term/search_in' argument should be present"); } } $promo = $this->getPromo(); if (null !== $promo) { $search->filterByPromo($promo); } $new = $this->getNew(); if (null !== $new) { $search->filterByNewness($new); } $default = $this->getDefault(); if (null !== $default) { $search->filterByIsDefault($default); } $orders = $this->getOrder(); foreach ($orders as $order) { switch ($order) { case "id": $search->orderById(Criteria::ASC); break; case "id_reverse": $search->orderById(Criteria::DESC); break; case "quantity": $search->orderByQuantity(Criteria::ASC); break; case "quantity_reverse": $search->orderByQuantity(Criteria::DESC); break; case "min_price": $search->addAscendingOrderByColumn('price_FINAL_PRICE'); break; case "max_price": $search->addDescendingOrderByColumn('price_FINAL_PRICE'); break; case "promo": $search->orderByPromo(Criteria::DESC); break; case "new": $search->orderByNewness(Criteria::DESC); break; case "weight": $search->orderByWeight(Criteria::ASC); break; case "weight_reverse": $search->orderByWeight(Criteria::DESC); break; case "random": $search->clearOrderByColumns(); $search->addAscendingOrderByColumn('RAND()'); break 2; } } $currencyId = $this->getCurrency(); if (null !== $currencyId) { $currency = CurrencyQuery::create()->findPk($currencyId); if (null === $currency) { throw new \InvalidArgumentException('Cannot found currency id: `' . $currency . '` in product_sale_elements loop'); } } else { $currency = $this->getCurrentRequest()->getSession()->getCurrency(); } $defaultCurrency = CurrencyModel::getDefaultCurrency(); $defaultCurrencySuffix = '_default_currency'; $search->joinProductPrice('price', Criteria::LEFT_JOIN)->addJoinCondition('price', '`price`.`currency_id` = ?', $currency->getId(), null, \PDO::PARAM_INT); $search->joinProductPrice('price' . $defaultCurrencySuffix, Criteria::LEFT_JOIN)->addJoinCondition('price_default_currency', '`price' . $defaultCurrencySuffix . '`.`currency_id` = ?', $defaultCurrency->getId(), null, \PDO::PARAM_INT); /** * rate value is checked as a float in overloaded getRate method. */ $priceSelectorAsSQL = 'ROUND(CASE WHEN ISNULL(`price`.PRICE) OR `price`.FROM_DEFAULT_CURRENCY = 1 THEN `price_default_currency`.PRICE * ' . $currency->getRate() . ' ELSE `price`.PRICE END, 6)'; $promoPriceSelectorAsSQL = 'ROUND(CASE WHEN ISNULL(`price`.PRICE) OR `price`.FROM_DEFAULT_CURRENCY = 1 THEN `price_default_currency`.PROMO_PRICE * ' . $currency->getRate() . ' ELSE `price`.PROMO_PRICE END, 6)'; $search->withColumn($priceSelectorAsSQL, 'price_PRICE')->withColumn($promoPriceSelectorAsSQL, 'price_PROMO_PRICE')->withColumn('CASE WHEN ' . ProductSaleElementsTableMap::PROMO . ' = 1 THEN ' . $promoPriceSelectorAsSQL . ' ELSE ' . $priceSelectorAsSQL . ' END', 'price_FINAL_PRICE'); $search->groupById(); return $search; }
/** * Get the current currency used or if not present the default currency for the shop * * @return \Thelia\Model\Currency */ protected function getCurrency() { if (null === $this->currency) { $this->currency = $this->getSession() ? $this->getSession()->getCurrency(true) : Currency::getDefaultCurrency(); } return $this->currency; }
/** * @return string */ public function doExport() { /** * Define the cache */ $cache = []; $cache["brand"] = []; $cache["category"] = []; $cache["breadcrumb"] = []; $cache["feature"]["title"] = []; $cache["feature"]["value"] = []; $cache["attribute"]["title"] = []; $cache["attribute"]["value"] = []; $fakeCartItem = new CartItem(); $fakeCart = new Cart(); $fakeCart->addCartItem($fakeCartItem); /** @var \Thelia\Model\Country $country */ $country = CountryQuery::create()->findOneById(ConfigQuery::create()->read('store_country', null)); $deliveryModuleModelId = ShoppingFluxConfigQuery::getDeliveryModuleId(); $deliveryModuleModel = ModuleQuery::create()->findPk($deliveryModuleModelId); /** @var \Thelia\Module\AbstractDeliveryModule $deliveryModule */ $deliveryModule = $deliveryModuleModel->getModuleInstance($this->container); /** * Build fake Request to inject in the module */ $fakeRequest = new Request(); $fakeRequest->setSession((new FakeSession())->setCart($fakeCart)); $deliveryModule->setRequest($fakeRequest); /** * Currency */ $currency = Currency::getDefaultCurrency(); /** * Load ecotax */ $ecotax = TaxQuery::create()->findPk(ShoppingFluxConfigQuery::getEcotaxRuleId()); /** * If there's a problem in the configuration, load a fake tax */ if ($ecotax === null) { $ecotax = new Tax(); $ecotax->setType('\\Thelia\\TaxEngine\\TaxType\\FixAmountTaxType')->setRequirements(array('amount' => 0)); } /** * Load the tax instance */ $ecotaxInstance = $ecotax->getTypeInstance(); // Compatibility with Thelia <= 2.0.2 $ecotaxInstance->loadRequirements($ecotax->getRequirements()); // We can pass any product as Argument, it is not used $ecotax = $ecotaxInstance->fixAmountRetriever(new Product()); /** @var \Thelia\Model\Product $product */ foreach ($this->getData() as $product) { $product->setLocale($this->locale); $node = $this->xml->addChild("produit"); /** * Parent id */ $node->addChild("id", $product->getId()); $node->addChild("nom", $product->getTitle()); $node->addChild("url", URL::getInstance()->absoluteUrl("/", ["view" => "product", "product_id" => $product->getId()])); $node->addChild("description-courte", $product->getChapo()); $node->addChild("description", $product->getDescription()); /** * Images URL */ $imagesNode = $node->addChild("images"); /** @var \Thelia\Model\ProductImage $productImage */ foreach ($product->getProductImages() as $productImage) { $imagesNode->addChild("image", URL::getInstance()->absoluteUrl("/shoppingflux/image/" . $productImage->getId())); } /** * Product Brand */ if ($product->getBrand()) { $brand = $product->getBrand(); $brand->setLocale($this->locale); if (!array_key_exists($brandId = $brand->getId(), $cache["brand"])) { $cache["brand"][$brandId] = $brand->getTitle(); } $node->addChild("marque", $cache["brand"][$brandId]); } else { $node->addChild("marque", null); } $node->addChild("url-marque"); /** * Compute breadcrumb */ $category = $product->getCategories()[0]; $category->setLocale($this->locale); if (!array_key_exists($categoryId = $category->getId(), $cache["category"])) { $cache["category"][$categoryId] = $category->getTitle(); $breadcrumb = []; do { $category->setLocale($this->locale); $breadcrumb[] = $category->getTitle(); } while (null !== ($category = CategoryQuery::create()->findPk($category->getParent()))); $reversedBreadcrumb = array_reverse($breadcrumb); $reversedBreadcrumb[] = $product->getTitle(); $cache["breadcrumb"][$categoryId] = implode(" > ", $reversedBreadcrumb); } $node->addChild("rayon", $cache["category"][$categoryId]); $node->addChild("fil-ariane", $cache["breadcrumb"][$categoryId]); /** * Features */ $featuresNode = $node->addChild("caracteristiques"); foreach ($product->getFeatureProducts() as $featureProduct) { if ($featureProduct->getFeatureAv() !== null && $featureProduct->getFeature() !== null) { if (!array_key_exists($featureId = $featureProduct->getFeature()->getId(), $cache["feature"]["title"])) { $featureProduct->getFeatureAv()->setLocale($this->locale); $featureProduct->getFeature()->setLocale($this->locale); $cache["feature"]["title"][$featureId] = trim(preg_replace("#[^a-z0-9_\\-]#i", "_", $featureProduct->getFeature()->getTitle()), "_"); $cache["feature"]["value"][$featureId] = $featureProduct->getFeatureAv()->getTitle(); } $featuresNode->addChild($cache["feature"]["title"][$featureId], $cache["feature"]["value"][$featureId]); } } /** * Compute VAT */ $taxRuleCountry = TaxRuleCountryQuery::create()->filterByTaxRule($product->getTaxRule())->findOne(); $tax = $taxRuleCountry->getTax(); /** @var \Thelia\TaxEngine\TaxType\PricePercentTaxType $taxType*/ $taxType = $tax->getTypeInstance(); if (array_key_exists("percent", $taxRequirements = $taxType->getRequirements())) { $node->addChild("tva", $taxRequirements["percent"]); } /** * Compute product sale elements */ $productSaleElements = $product->getProductSaleElementss(); $psesNode = $node->addChild("declinaisons"); /** @var \Thelia\Model\ProductSaleElements $pse */ foreach ($productSaleElements as $pse) { /** * Fake the cart so that module::getPostage() returns the price * for only one object */ $fakeCartItem->setProductSaleElements($pse); /** * If the object is too heavy, don't export it */ try { $shipping_price = $deliveryModule->getPostage($country); } catch (DeliveryException $e) { continue; } $productPrice = $pse->getPricesByCurrency($currency); $pse->setVirtualColumn("price_PRICE", $productPrice->getPrice()); $pse->setVirtualColumn("price_PROMO_PRICE", $productPrice->getPromoPrice()); $deliveryTimeMin = null; $deliveryTimeMax = null; $pseNode = $psesNode->addChild("declinaison"); /** * Child id */ $pseNode->addChild("id", $product->getId() . "_" . $pse->getId()); $pseNode->addChild("prix-ttc", $pse->getPromo() ? $pse->getPromoPrice() : $pse->getPrice()); $pseNode->addChild("prix-ttc-barre", $pse->getPromo() ? $pse->getPrice() : null); $pseNode->addChild("quantite", $pse->getQuantity()); $pseNode->addChild("ean", $pse->getEanCode()); $pseNode->addChild("poids", $pse->getWeight()); $pseNode->addChild("ecotaxe", $ecotax); $pseNode->addChild("frais-de-port", $shipping_price); $pseNode->addChild("delai-livraison-mini", $deliveryTimeMin); $pseNode->addChild("delai-livraison-maxi", $deliveryTimeMax); $pseAttrNode = $pseNode->addChild("attributs"); /** @var \Thelia\Model\AttributeCombination $attr */ foreach ($pse->getAttributeCombinations() as $attr) { if ($attr->getAttribute() !== null && $attr->getAttributeAv() !== null) { if (!array_key_exists($attributeId = $attr->getAttribute()->getId(), $cache["attribute"]["title"])) { $attr->getAttribute()->setLocale($this->locale); $attr->getAttributeAv()->setLocale($this->locale); $cache["attribute"]["title"][$attributeId] = trim(preg_replace("#[^a-z0-9_\\-]#i", "_", $attr->getAttribute()->getTitle()), "_"); $cache["attribute"]["value"][$attributeId] = $attr->getAttributeAv()->getTitle(); } $pseAttrNode->addChild($cache["attribute"]["title"][$attributeId], $cache["attribute"]["value"][$attributeId]); } } $pseNode->addChild("promo-de"); $pseNode->addChild("promo-a"); } } /** * Then return a well formed string */ $dom = new \DOMDocument("1.0"); $dom->preserveWhiteSpace = false; $dom->formatOutput = true; $dom->loadXML($this->xml->asXML()); return $dom->saveXML(); }
public function testQuery() { new Translator(new Container()); $handler = new CustomerExport(new Container()); $lang = Lang::getDefaultLanguage(); $data = $handler->buildData($lang); $keys = ["ref", "title", "last_name", "first_name", "email", "label", "discount", "is_registered_to_newsletter", "sign_up_date", "total_orders", "last_order_amount", "last_order_date", "address_first_name", "address_last_name", "company", "address1", "address2", "address3", "zipcode", "city", "country", "phone", "cellphone", "is_default_address", "address_title"]; sort($keys); $rawData = $data->getData(); $max = CustomerQuery::create()->count(); /** * 30 customers that has more than 1 addresses or enough */ if (30 < $max) { $max = 30; } for ($i = 0; $i < $max;) { $row = $rawData[$i]; $rowKeys = array_keys($row); sort($rowKeys); $this->assertEquals($rowKeys, $keys); $customer = CustomerQuery::create()->findOneByRef($row["ref"]); $this->assertNotNull($customer); $this->assertEquals($customer->getFirstname(), $row["first_name"]); $this->assertEquals($customer->getLastname(), $row["last_name"]); $this->assertEquals($customer->getEmail(), $row["email"]); $this->assertEquals($customer->getCreatedAt()->format($lang->getDatetimeFormat()), $row["sign_up_date"]); $this->assertEquals($customer->getDiscount(), $row["discount"]); $title = CustomerTitleQuery::create()->findPk($customer->getTitleId()); $this->assertEquals($title->getShort(), $row["title"]); $total = 0; foreach ($customer->getOrders() as $order) { $amount = $order->getTotalAmount($tax); if (0 < ($rate = $order->getCurrencyRate())) { $amount = round($amount / $rate, 2); } $total += $amount; } $defaultCurrencyCode = Currency::getDefaultCurrency()->getCode(); $this->assertEquals($total . " " . $defaultCurrencyCode, $row["total_orders"]); $lastOrder = OrderQuery::create()->filterByCustomer($customer)->orderByCreatedAt(Criteria::DESC)->orderById(Criteria::DESC)->findOne(); if (null !== $lastOrder) { $expectedPrice = $lastOrder->getTotalAmount($tax_) . " " . $lastOrder->getCurrency()->getCode(); $expectedDate = $lastOrder->getCreatedAt()->format($lang->getDatetimeFormat()); } else { $expectedPrice = ""; $expectedDate = ""; } $this->assertEquals($expectedPrice, $row["last_order_amount"]); $this->assertEquals($expectedDate, $row["last_order_date"]); $newsletter = NewsletterQuery::create()->findOneByEmail($customer->getEmail()); $this->assertEquals($newsletter === null ? 0 : 1, $row["is_registered_to_newsletter"]); do { $address = AddressQuery::create()->filterByCustomer($customer)->filterByAddress1($rawData[$i]["address1"])->filterByAddress2($rawData[$i]["address2"])->filterByAddress3($rawData[$i]["address3"])->filterByFirstname($rawData[$i]["address_first_name"])->filterByLastname($rawData[$i]["address_last_name"])->filterByCountryId(CountryI18nQuery::create()->filterByLocale($lang->getLocale())->findOneByTitle($rawData[$i]["country"])->getId())->filterByCompany($rawData[$i]["company"])->_if(empty($rawData[$i]["company"]))->_or()->filterByCompany(null, Criteria::ISNULL)->_endif()->filterByZipcode($rawData[$i]["zipcode"])->filterByCity($rawData[$i]["city"])->filterByIsDefault($rawData[$i]["is_default_address"])->filterByCellphone($rawData[$i]["cellphone"])->_if(empty($rawData[$i]["cellphone"]))->_or()->filterByCellphone(null, Criteria::ISNULL)->_endif()->filterByPhone($rawData[$i]["phone"])->_if(empty($rawData[$i]["phone"]))->_or()->filterByPhone(null, Criteria::ISNULL)->_endif()->filterByLabel($rawData[$i]["label"])->_if(empty($rawData[$i]["label"]))->_or()->filterByLabel(null, Criteria::ISNULL)->_endif()->filterByTitleId(CustomerTitleI18nQuery::create()->filterByLocale($lang->getLocale())->findOneByShort($rawData[$i]["address_title"])->getId())->findOne(); $this->assertNotNull($address); $rowKeys = array_keys($rawData[$i]); sort($rowKeys); $this->assertEquals($rowKeys, $keys); } while (isset($rawData[++$i]["ref"]) && $rawData[$i - 1]["ref"] === $rawData[$i]["ref"] && ++$max); } }
protected function defineCurrency(Request $request) { $currency = null; if ($request->query->has("currency")) { $currency = Model\CurrencyQuery::create()->findOneByCode($request->query->get("currency")); if ($currency) { $this->container->get("event_dispatcher")->dispatch(TheliaEvents::CHANGE_DEFAULT_CURRENCY, new CurrencyChangeEvent($currency, $request)); } } else { $currency = $request->getSession()->getCurrency(false); } if (null === $currency) { $currency = Model\Currency::getDefaultCurrency(); } return $currency; }
public function addProduct($id) { if (null !== ($response = $this->checkAuth(array(AdminResources::MODULE), array('GoogleShopping'), AccessManager::CREATE))) { return $response; } $request = $this->getRequest()->request; $con = Propel::getConnection(GoogleshoppingProductSynchronisationTableMap::DATABASE_NAME); $con->beginTransaction(); try { $eventArgs = []; //Get local and lang by admin config flag selected $eventArgs['ignoreGtin'] = $request->get('gtin') === "on" ? true : false; $eventArgs['lang'] = LangQuery::create()->findOneById($request->get("lang")); $eventArgs['targetCountry'] = CountryQuery::create()->findOneById($request->get('country')); $merchantId = $request->get('account'); $locale = $eventArgs['lang']->getLocale(); $currencyId = $request->get('currency'); $currency = CurrencyQuery::create()->findOneById($currencyId); if (null === $currency) { $currency = Currency::getDefaultCurrency(); } if (!$eventArgs['targetCountry']) { $eventArgs['targetCountry'] = Country::getDefaultCountry(); } //If the authorisation is not set yet or has expired if (false === $this->checkGoogleAuth()) { $this->getSession()->set('google_action_url', "/admin/module/googleshopping/add/{$id}?locale={$locale}>in=" . $eventArgs['ignoreGtin']); return $this->generateRedirect('/googleshopping/oauth2callback'); } $googleShoppingHandler = new GoogleShoppingHandler($this->container, $this->getRequest()); //Init google client $client = $googleShoppingHandler->createGoogleClient(); $googleShoppingService = new \Google_Service_ShoppingContent($client); //Get the product $theliaProduct = ProductQuery::create()->joinWithI18n($eventArgs['lang']->getLocale())->findOneById($id); /** @var ProductSaleElements $productSaleElement */ $googleProductEvent = new GoogleProductEvent($theliaProduct, null, $googleShoppingService, $eventArgs); $googleProductEvent->setMerchantId($merchantId)->setCurrency($currency); $this->getDispatcher()->dispatch(GoogleShoppingEvents::GOOGLE_PRODUCT_CREATE_PRODUCT, $googleProductEvent); $googleAccountId = GoogleshoppingAccountQuery::create()->findOneByMerchantId($merchantId); //Add auomatically product to sync $productSync = GoogleshoppingProductSynchronisationQuery::create()->filterByProductId($theliaProduct->getId())->filterByLang($eventArgs['lang']->getCode())->filterByTargetCountry($eventArgs['targetCountry']->getIsoalpha2())->filterByGoogleshoppingAccountId($googleAccountId)->findOneOrCreate(); $productSync->setSyncEnable(true)->save(); $con->commit(); return JsonResponse::create(["message" => "Success"], 200); } catch (\Exception $e) { $con->rollBack(); // $deleteResponse = $this->deleteProduct($id); return JsonResponse::create($e->getMessage(), 500); } }
public function buildModelCriteria() { Tlog::getInstance()->debug("-- Starting new product build criteria"); $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->getCurrentRequest()->getSession()->getCurrency(); } $defaultCurrency = CurrencyModel::getDefaultCurrency(); $defaultCurrencySuffix = '_default_currency'; $priceToCompareAsSQL = ''; $isPSELeftJoinList = []; $isProductPriceFirstLeftJoin = []; $search = ProductQuery::create(); $complex = $this->getComplex(); if (!$complex) { $search->innerJoinProductSaleElements('pse'); $search->addJoinCondition('pse', '`pse`.IS_DEFAULT=1'); $search->innerJoinProductSaleElements('pse_count'); $priceJoin = new Join(); $priceJoin->addExplicitCondition(ProductSaleElementsTableMap::TABLE_NAME, 'ID', 'pse', ProductPriceTableMap::TABLE_NAME, 'PRODUCT_SALE_ELEMENTS_ID', 'price'); $priceJoin->setJoinType(Criteria::LEFT_JOIN); $search->addJoinObject($priceJoin, 'price_join')->addJoinCondition('price_join', '`price`.`currency_id` = ?', $currency->getId(), null, \PDO::PARAM_INT); if ($defaultCurrency->getId() != $currency->getId()) { $priceJoinDefaultCurrency = new Join(); $priceJoinDefaultCurrency->addExplicitCondition(ProductSaleElementsTableMap::TABLE_NAME, 'ID', 'pse', ProductPriceTableMap::TABLE_NAME, 'PRODUCT_SALE_ELEMENTS_ID', 'price' . $defaultCurrencySuffix); $priceJoinDefaultCurrency->setJoinType(Criteria::LEFT_JOIN); $search->addJoinObject($priceJoinDefaultCurrency, 'price_join' . $defaultCurrencySuffix)->addJoinCondition('price_join' . $defaultCurrencySuffix, '`price' . $defaultCurrencySuffix . '`.`currency_id` = ?', $defaultCurrency->getId(), null, \PDO::PARAM_INT); /** * rate value is checked as a float in overloaded getRate method. */ $priceToCompareAsSQL = 'CASE WHEN ISNULL(`price`.PRICE) OR `price`.FROM_DEFAULT_CURRENCY = 1 THEN CASE WHEN `pse`.PROMO=1 THEN `price' . $defaultCurrencySuffix . '`.PROMO_PRICE ELSE `price' . $defaultCurrencySuffix . '`.PRICE END * ' . $currency->getRate() . ' ELSE CASE WHEN `pse`.PROMO=1 THEN `price`.PROMO_PRICE ELSE `price`.PRICE END END'; $search->withColumn('ROUND(' . $priceToCompareAsSQL . ', 2)', 'real_price'); $search->withColumn('CASE WHEN ISNULL(`price`.PRICE) OR `price`.FROM_DEFAULT_CURRENCY = 1 THEN `price' . $defaultCurrencySuffix . '`.PRICE * ' . $currency->getRate() . ' ELSE `price`.PRICE END', 'price'); $search->withColumn('CASE WHEN ISNULL(`price`.PRICE) OR `price`.FROM_DEFAULT_CURRENCY = 1 THEN `price' . $defaultCurrencySuffix . '`.PROMO_PRICE * ' . $currency->getRate() . ' ELSE `price`.PROMO_PRICE END', 'promo_price'); } else { $priceToCompareAsSQL = 'CASE WHEN `pse`.PROMO=1 THEN `price`.PROMO_PRICE ELSE `price`.PRICE END'; $search->withColumn('ROUND(' . $priceToCompareAsSQL . ', 2)', 'real_price'); $search->withColumn('`price`.PRICE', 'price'); $search->withColumn('`price`.PROMO_PRICE', 'promo_price'); } } /* manage translations */ $this->configureI18nProcessing($search, ['TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM', 'META_TITLE', 'META_DESCRIPTION', 'META_KEYWORDS']); $id = $this->getId(); if (!is_null($id)) { $search->filterById($id, Criteria::IN); } $ref = $this->getRef(); if (!is_null($ref)) { $search->filterByRef($ref, Criteria::IN); } $title = $this->getTitle(); if (!is_null($title)) { $this->addSearchInI18nColumn($search, 'TITLE', Criteria::LIKE, "%" . $title . "%"); } $manualOrderAllowed = false; if (null !== ($categoryDefault = $this->getCategoryDefault())) { // Select the products which have $categoryDefault as the default category. $search->useProductCategoryQuery('CategorySelect')->filterByDefaultCategory(true)->filterByCategoryId($categoryDefault, Criteria::IN)->endUse(); // We can only sort by position if we have a single category ID $manualOrderAllowed = 1 == count($categoryDefault); } elseif (null !== ($categoryIdList = $this->getCategory())) { // Select all products which have one of the required categories as the default one, or an associated one $depth = $this->getDepth(); $allCategoryIDs = CategoryQuery::getCategoryTreeIds($categoryIdList, $depth); $search->useProductCategoryQuery('CategorySelect')->filterByCategoryId($allCategoryIDs, Criteria::IN)->endUse(); // We can only sort by position if we have a single category ID, with a depth of 1 $manualOrderAllowed = 1 == $depth && 1 == count($categoryIdList); } else { $search->leftJoinProductCategory('CategorySelect')->addJoinCondition('CategorySelect', '`CategorySelect`.DEFAULT_CATEGORY = 1'); } $search->withColumn('CASE WHEN ISNULL(`CategorySelect`.POSITION) THEN \'' . PHP_INT_MAX . '\' ELSE `CategorySelect`.POSITION END', 'position_delegate'); $search->withColumn('`CategorySelect`.CATEGORY_ID', 'default_category_id'); $search->withColumn('`CategorySelect`.DEFAULT_CATEGORY', 'is_default_category'); $current = $this->getCurrent(); if ($current === true) { $search->filterById($this->getCurrentRequest()->get("product_id"), Criteria::EQUAL); } elseif ($current === false) { $search->filterById($this->getCurrentRequest()->get("product_id"), Criteria::NOT_IN); } $brand_id = $this->getBrand(); if ($brand_id !== null) { $search->filterByBrandId($brand_id, Criteria::IN); } $contentId = $this->getContent(); if ($contentId != null) { $search->useProductAssociatedContentQuery()->filterByContentId($contentId, Criteria::IN)->endUse(); } $sale_id = $this->getSale(); if ($sale_id !== null) { $search->useSaleProductQuery("SaleProductSelect")->filterBySaleId($sale_id)->groupByProductId()->endUse(); } $current_category = $this->getCurrentCategory(); if ($current_category === true) { $search->filterByCategory(CategoryQuery::create()->filterByProduct(ProductCategoryQuery::create()->findPk($this->getCurrentRequest()->get("product_id")), Criteria::IN)->find(), Criteria::IN); } elseif ($current_category === false) { $search->filterByCategory(CategoryQuery::create()->filterByProduct(ProductCategoryQuery::create()->findPk($this->getCurrentRequest()->get("product_id")), Criteria::IN)->find(), Criteria::NOT_IN); } $visible = $this->getVisible(); if ($visible !== Type\BooleanOrBothType::ANY) { $search->filterByVisible($visible ? 1 : 0); } $virtual = $this->getVirtual(); if ($virtual !== Type\BooleanOrBothType::ANY) { $search->filterByVirtual($virtual ? 1 : 0); } $exclude = $this->getExclude(); if (!is_null($exclude)) { $search->filterById($exclude, Criteria::NOT_IN); } $exclude_category = $this->getExcludeCategory(); if (!is_null($exclude_category)) { $search->useProductCategoryQuery('ExcludeCategorySelect')->filterByCategoryId($exclude_category, Criteria::NOT_IN)->endUse(); } $new = $this->getNew(); $promo = $this->getPromo(); $min_stock = $this->getMinStock(); $min_weight = $this->getMinWeight(); $max_weight = $this->getMaxWeight(); $min_price = $this->getMinPrice(); $max_price = $this->getMaxPrice(); if ($complex) { if ($new === true) { $isPSELeftJoinList[] = 'is_new'; $search->joinProductSaleElements('is_new', Criteria::LEFT_JOIN)->where('`is_new`.NEWNESS' . Criteria::EQUAL . '1')->where('NOT ISNULL(`is_new`.ID)'); } elseif ($new === false) { $isPSELeftJoinList[] = 'is_new'; $search->joinProductSaleElements('is_new', Criteria::LEFT_JOIN)->where('`is_new`.NEWNESS' . Criteria::EQUAL . '0')->where('NOT ISNULL(`is_new`.ID)'); } if ($promo === true) { $isPSELeftJoinList[] = 'is_promo'; $search->joinProductSaleElements('is_promo', Criteria::LEFT_JOIN)->where('`is_promo`.PROMO' . Criteria::EQUAL . '1')->where('NOT ISNULL(`is_promo`.ID)'); } elseif ($promo === false) { $isPSELeftJoinList[] = 'is_promo'; $search->joinProductSaleElements('is_promo', Criteria::LEFT_JOIN)->where('`is_promo`.PROMO' . Criteria::EQUAL . '0')->where('NOT ISNULL(`is_promo`.ID)'); } if (null != $min_stock) { $isPSELeftJoinList[] = 'is_min_stock'; $search->joinProductSaleElements('is_min_stock', Criteria::LEFT_JOIN)->where('`is_min_stock`.QUANTITY' . Criteria::GREATER_EQUAL . '?', $min_stock, \PDO::PARAM_INT)->where('NOT ISNULL(`is_min_stock`.ID)'); } if (null != $min_weight) { $isPSELeftJoinList[] = 'is_min_weight'; $search->joinProductSaleElements('is_min_weight', Criteria::LEFT_JOIN)->where('`is_min_weight`.WEIGHT' . Criteria::GREATER_EQUAL . '?', $min_weight, \PDO::PARAM_STR)->where('NOT ISNULL(`is_min_weight`.ID)'); } if (null != $max_weight) { $isPSELeftJoinList[] = 'is_max_weight'; $search->joinProductSaleElements('is_max_weight', Criteria::LEFT_JOIN)->where('`is_max_weight`.WEIGHT' . Criteria::LESS_EQUAL . '?', $max_weight, \PDO::PARAM_STR)->where('NOT ISNULL(`is_max_weight`.ID)'); } $attributeNonStrictMatch = $this->getAttributeNonStrictMatch(); if ($attributeNonStrictMatch != '*') { if ($attributeNonStrictMatch == 'none') { $actuallyUsedAttributeNonStrictMatchList = $isPSELeftJoinList; } else { $actuallyUsedAttributeNonStrictMatchList = array_values(array_intersect($isPSELeftJoinList, $attributeNonStrictMatch)); } foreach ($actuallyUsedAttributeNonStrictMatchList as $key => $actuallyUsedAttributeNonStrictMatch) { if ($key == 0) { continue; } $search->where('`' . $actuallyUsedAttributeNonStrictMatch . '`.ID=' . '`' . $actuallyUsedAttributeNonStrictMatchList[$key - 1] . '`.ID'); } } if (null !== $min_price) { if (false === ConfigQuery::useTaxFreeAmounts()) { // @todo } $isPSELeftJoinList[] = 'is_min_price'; $isProductPriceFirstLeftJoin = ['is_min_price', 'min_price_data']; $minPriceJoin = new Join(); $minPriceJoin->addExplicitCondition(ProductSaleElementsTableMap::TABLE_NAME, 'ID', 'is_min_price', ProductPriceTableMap::TABLE_NAME, 'PRODUCT_SALE_ELEMENTS_ID', 'min_price_data'); $minPriceJoin->setJoinType(Criteria::LEFT_JOIN); $search->joinProductSaleElements('is_min_price', Criteria::LEFT_JOIN)->addJoinObject($minPriceJoin, 'is_min_price_join')->addJoinCondition('is_min_price_join', '`min_price_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', ProductPriceTableMap::TABLE_NAME, 'PRODUCT_SALE_ELEMENTS_ID', 'min_price_data' . $defaultCurrencySuffix); $minPriceJoinDefaultCurrency->setJoinType(Criteria::LEFT_JOIN); $search->addJoinObject($minPriceJoinDefaultCurrency, 'is_min_price_join' . $defaultCurrencySuffix)->addJoinCondition('is_min_price_join' . $defaultCurrencySuffix, '`min_price_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`.PROMO=1 THEN `min_price_data`.PROMO_PRICE ELSE `min_price_data`.PRICE END) OR `min_price_data`.FROM_DEFAULT_CURRENCY = 1 THEN CASE WHEN `is_min_price`.PROMO=1 THEN `min_price_data' . $defaultCurrencySuffix . '`.PROMO_PRICE ELSE `min_price_data' . $defaultCurrencySuffix . '`.PRICE END * ' . $currency->getRate() . ' ELSE CASE WHEN `is_min_price`.PROMO=1 THEN `min_price_data`.PROMO_PRICE ELSE `min_price_data`.PRICE END END'; } else { $MinPriceToCompareAsSQL = 'CASE WHEN `is_min_price`.PROMO=1 THEN `min_price_data`.PROMO_PRICE ELSE `min_price_data`.PRICE END'; } $search->where('ROUND(' . $MinPriceToCompareAsSQL . ', 2)>=?', $min_price, \PDO::PARAM_STR); } if (null !== $max_price) { $isPSELeftJoinList[] = 'is_max_price'; $isProductPriceFirstLeftJoin = ['is_max_price', 'max_price_data']; $maxPriceJoin = new Join(); $maxPriceJoin->addExplicitCondition(ProductSaleElementsTableMap::TABLE_NAME, 'ID', 'is_max_price', ProductPriceTableMap::TABLE_NAME, 'PRODUCT_SALE_ELEMENTS_ID', 'max_price_data'); $maxPriceJoin->setJoinType(Criteria::LEFT_JOIN); $search->joinProductSaleElements('is_max_price', Criteria::LEFT_JOIN)->addJoinObject($maxPriceJoin, 'is_max_price_join')->addJoinCondition('is_max_price_join', '`max_price_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', ProductPriceTableMap::TABLE_NAME, 'PRODUCT_SALE_ELEMENTS_ID', 'max_price_data' . $defaultCurrencySuffix); $maxPriceJoinDefaultCurrency->setJoinType(Criteria::LEFT_JOIN); $search->addJoinObject($maxPriceJoinDefaultCurrency, 'is_max_price_join' . $defaultCurrencySuffix)->addJoinCondition('is_max_price_join' . $defaultCurrencySuffix, '`max_price_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`.PROMO=1 THEN `max_price_data`.PROMO_PRICE ELSE `max_price_data`.PRICE END) OR `min_price_data`.FROM_DEFAULT_CURRENCY = 1 THEN CASE WHEN `is_max_price`.PROMO=1 THEN `max_price_data' . $defaultCurrencySuffix . '`.PROMO_PRICE ELSE `max_price_data' . $defaultCurrencySuffix . '`.PRICE END * ' . $currency->getRate() . ' ELSE CASE WHEN `is_max_price`.PROMO=1 THEN `max_price_data`.PROMO_PRICE ELSE `max_price_data`.PRICE END END'; } else { $MaxPriceToCompareAsSQL = 'CASE WHEN `is_max_price`.PROMO=1 THEN `max_price_data`.PROMO_PRICE ELSE `max_price_data`.PRICE END'; } $search->where('ROUND(' . $MaxPriceToCompareAsSQL . ', 2)<=?', $max_price, \PDO::PARAM_STR); } /* * for ordering and outputs, the product will be : * - new if at least one the criteria matching PSE is new * - in promo if at least one the criteria matching PSE is in promo */ /* if we don't have any join yet, let's make a global one */ if (empty($isProductPriceFirstLeftJoin)) { if (count($isPSELeftJoinList) == 0) { $joiningTable = "global"; $isPSELeftJoinList[] = $joiningTable; $search->joinProductSaleElements('global', Criteria::LEFT_JOIN); } else { $joiningTable = $isPSELeftJoinList[0]; } $isProductPriceFirstLeftJoin = [$joiningTable, 'global_price_data']; $globalPriceJoin = new Join(); $globalPriceJoin->addExplicitCondition(ProductSaleElementsTableMap::TABLE_NAME, 'ID', $joiningTable, ProductPriceTableMap::TABLE_NAME, 'PRODUCT_SALE_ELEMENTS_ID', 'global_price_data'); $globalPriceJoin->setJoinType(Criteria::LEFT_JOIN); $search->addJoinObject($globalPriceJoin, 'global_price_join')->addJoinCondition('global_price_join', '`global_price_data`.`currency_id` = ?', $currency->getId(), null, \PDO::PARAM_INT); if ($defaultCurrency->getId() != $currency->getId()) { $globalPriceJoinDefaultCurrency = new Join(); $globalPriceJoinDefaultCurrency->addExplicitCondition(ProductSaleElementsTableMap::TABLE_NAME, 'ID', $joiningTable, ProductPriceTableMap::TABLE_NAME, 'PRODUCT_SALE_ELEMENTS_ID', 'global_price_data' . $defaultCurrencySuffix); $globalPriceJoinDefaultCurrency->setJoinType(Criteria::LEFT_JOIN); $search->addJoinObject($globalPriceJoinDefaultCurrency, 'global_price_join' . $defaultCurrencySuffix)->addJoinCondition('global_price_join' . $defaultCurrencySuffix, '`global_price_data' . $defaultCurrencySuffix . '`.`currency_id` = ?', $defaultCurrency->getId(), null, \PDO::PARAM_INT); } } /* * we need to test all promo field from our previous conditions. Indeed ie: * product P0, attributes color : red * P0red is in promo and is the only attribute combinaton availability. * so the product might be consider as in promo (in outputs and ordering) * We got the following loop to display in promo AND new product but we don't care it's the same attribute which is new and in promo : * {loop type="product" promo="1" new="1" attribute_non_strict_match="promo,new"} {/loop} * our request will so far returns 1 line * * is_promo.ID | is_promo.PROMO | is_promo.NEWNESS | is_new.ID | is_new.PROMO | is_new.NEWNESS * NULL NULL NULL red_id 1 0 * * So that we can say the product is in global promo only with is_promo.PROMO, we must acknowledge it with (is_promo.PROMO OR is_new.PROMO) */ $booleanMatchedPromoList = []; $booleanMatchedNewnessList = []; foreach ($isPSELeftJoinList as $isPSELeftJoin) { $booleanMatchedPromoList[] = '`' . $isPSELeftJoin . '`.PROMO'; $booleanMatchedNewnessList[] = '`' . $isPSELeftJoin . '`.NEWNESS'; } $search->withColumn('ROUND(MAX(' . implode(' OR ', $booleanMatchedPromoList) . '), 2)', 'main_product_is_promo'); $search->withColumn('ROUND(MAX(' . implode(' OR ', $booleanMatchedNewnessList) . '), 2)', 'main_product_is_new'); $booleanMatchedPrice = 'CASE WHEN `' . $isProductPriceFirstLeftJoin[0] . '`.PROMO=1 THEN `' . $isProductPriceFirstLeftJoin[1] . '`.PROMO_PRICE ELSE `' . $isProductPriceFirstLeftJoin[1] . '`.PRICE END'; $booleanMatchedPriceDefaultCurrency = 'CASE WHEN `' . $isProductPriceFirstLeftJoin[0] . '`.PROMO=1 THEN `' . $isProductPriceFirstLeftJoin[1] . $defaultCurrencySuffix . '`.PROMO_PRICE ELSE `' . $isProductPriceFirstLeftJoin[1] . $defaultCurrencySuffix . '`.PRICE END'; if ($defaultCurrency->getId() != $currency->getId()) { /** * In propel we trust : $currency->getRate() always returns a float. * Or maybe not : rate value is checked as a float in overloaded getRate method. */ $priceToCompareAsSQL = 'CASE WHEN ISNULL(' . $booleanMatchedPrice . ') THEN ' . $booleanMatchedPriceDefaultCurrency . ' * ' . $currency->getRate() . ' ELSE ' . $booleanMatchedPrice . ' END'; } else { $priceToCompareAsSQL = $booleanMatchedPrice; } $search->withColumn('ROUND(MAX(' . $priceToCompareAsSQL . '), 2)', 'real_highest_price'); $search->withColumn('ROUND(MIN(' . $priceToCompareAsSQL . '), 2)', 'real_lowest_price'); } else { if ($new === true) { $search->where('`pse`.NEWNESS' . Criteria::EQUAL . '1'); } elseif ($new === false) { $search->where('`pse`.NEWNESS' . Criteria::EQUAL . '0'); } if ($promo === true) { $search->where('`pse`.PROMO' . Criteria::EQUAL . '1'); } elseif ($promo === false) { $search->where('`pse`.PROMO' . Criteria::EQUAL . '0'); } if (null != $min_stock) { $search->where('`pse`.QUANTITY' . Criteria::GREATER_EQUAL . '?', $min_stock, \PDO::PARAM_INT); } if (null != $min_weight) { $search->where('`pse`.WEIGHT' . Criteria::GREATER_EQUAL . '?', $min_weight, \PDO::PARAM_STR); } if (null != $max_weight) { $search->where('`is_max_weight`.WEIGHT' . Criteria::LESS_EQUAL . '?', $max_weight, \PDO::PARAM_STR); } if (null !== $min_price) { if (false === ConfigQuery::useTaxFreeAmounts()) { // @todo } $search->where('ROUND(' . $priceToCompareAsSQL . ', 2)>=?', $min_price, \PDO::PARAM_STR); } if (null !== $max_price) { if (false === ConfigQuery::useTaxFreeAmounts()) { // @todo } $search->where('ROUND(' . $priceToCompareAsSQL . ', 2)<=?', $max_price, \PDO::PARAM_STR); } } // First join sale_product table... $search->leftJoinSaleProduct('SaleProductPriceDisplay'); // ... then the sale table... $salesJoin = new Join(); $salesJoin->addExplicitCondition('SaleProductPriceDisplay', 'SALE_ID', null, SaleTableMap::TABLE_NAME, 'ID', 'SalePriceDisplay'); $salesJoin->setJoinType(Criteria::LEFT_JOIN); $search->addJoinObject($salesJoin, 'SalePriceDisplay')->addJoinCondition('SalePriceDisplay', '`SalePriceDisplay`.`active` = 1'); // ... to get the DISPLAY_INITIAL_PRICE column ! $search->withColumn('`SalePriceDisplay`.DISPLAY_INITIAL_PRICE', 'display_initial_price'); $feature_availability = $this->getFeatureAvailability(); $this->manageFeatureAv($search, $feature_availability); $feature_values = $this->getFeatureValues(); $this->manageFeatureValue($search, $feature_values); $search->groupBy(ProductTableMap::ID); if (!$complex) { $search->withColumn('`pse`.ID', 'pse_id'); $search->withColumn('`pse`.NEWNESS', 'is_new'); $search->withColumn('`pse`.PROMO', 'is_promo'); $search->withColumn('`pse`.QUANTITY', 'quantity'); $search->withColumn('`pse`.WEIGHT', 'weight'); $search->withColumn('`pse`.EAN_CODE', 'ean_code'); $search->withColumn('COUNT(`pse_count`.ID)', 'pse_count'); } $orders = $this->getOrder(); foreach ($orders as $order) { switch ($order) { case "id": $search->orderById(Criteria::ASC); break; case "id_reverse": $search->orderById(Criteria::DESC); break; case "alpha": $search->addAscendingOrderByColumn('i18n_TITLE'); break; case "alpha_reverse": $search->addDescendingOrderByColumn('i18n_TITLE'); break; case "min_price": if ($complex) { $search->addAscendingOrderByColumn('real_lowest_price'); } else { $search->addAscendingOrderByColumn('real_price'); } break; case "max_price": if ($complex) { $search->addDescendingOrderByColumn('real_lowest_price'); } else { $search->addDescendingOrderByColumn('real_price'); } break; case "manual": if (!$manualOrderAllowed) { throw new \InvalidArgumentException('Manual order require a *single* category ID or category_default ID, and a depth <= 1'); } $search->addAscendingOrderByColumn('position_delegate'); break; case "manual_reverse": if (!$manualOrderAllowed) { throw new \InvalidArgumentException('Manual reverse order require a *single* category ID or category_default ID, and a depth <= 1'); } $search->addDescendingOrderByColumn('position_delegate'); break; case "ref": $search->orderByRef(Criteria::ASC); break; case "ref_reverse": $search->orderByRef(Criteria::DESC); break; case "visible": $search->orderByVisible(Criteria::ASC); break; case "visible_reverse": $search->orderByVisible(Criteria::DESC); break; case "promo": if ($complex) { $search->addDescendingOrderByColumn('main_product_is_promo'); } else { $search->addDescendingOrderByColumn('is_promo'); } break; case "new": if ($complex) { $search->addDescendingOrderByColumn('main_product_is_new'); } else { $search->addDescendingOrderByColumn('is_new'); } break; case "created": $search->addAscendingOrderByColumn('created_at'); break; case "created_reverse": $search->addDescendingOrderByColumn('created_at'); break; case "updated": $search->addAscendingOrderByColumn('updated_at'); break; case "updated_reverse": $search->addDescendingOrderByColumn('updated_at'); break; case "given_id": if (null === $id) { throw new \InvalidArgumentException('Given_id order cannot be set without `id` argument'); } foreach ($id as $singleId) { $givenIdMatched = 'given_id_matched_' . $singleId; $search->withColumn(ProductTableMap::ID . "='{$singleId}'", $givenIdMatched); $search->orderBy($givenIdMatched, Criteria::DESC); } break; case "random": $search->clearOrderByColumns(); $search->addAscendingOrderByColumn('RAND()'); break 2; } } return $search; }