PageRenderTime 63ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/controllers/admin/AdminCartsController.php

https://github.com/netplayer/PrestaShop
PHP | 883 lines | 769 code | 83 blank | 31 comment | 160 complexity | ccc5acb667b39f2cd02471f1dc69c4d6 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, LGPL-2.1, LGPL-3.0
  1. <?php
  2. /*
  3. * 2007-2014 PrestaShop
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@prestashop.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
  18. * versions in the future. If you wish to customize PrestaShop for your
  19. * needs please refer to http://www.prestashop.com for more information.
  20. *
  21. * @author PrestaShop SA <contact@prestashop.com>
  22. * @copyright 2007-2014 PrestaShop SA
  23. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  24. * International Registered Trademark & Property of PrestaShop SA
  25. */
  26. class AdminCartsControllerCore extends AdminController
  27. {
  28. public function __construct()
  29. {
  30. $this->bootstrap = true;
  31. $this->table = 'cart';
  32. $this->className = 'Cart';
  33. $this->lang = false;
  34. $this->explicitSelect = true;
  35. $this->addRowAction('view');
  36. $this->addRowAction('delete');
  37. $this->allow_export = true;
  38. $this->_orderWay = 'DESC';
  39. $this->_select = 'CONCAT(LEFT(c.`firstname`, 1), \'. \', c.`lastname`) `customer`, a.id_cart total, ca.name carrier,
  40. IF (IFNULL(o.id_order, \''.$this->l('Non ordered').'\') = \''.$this->l('Non ordered').'\', IF(TIME_TO_SEC(TIMEDIFF(NOW(), a.`date_add`)) > 86400, \''.$this->l('Abandoned cart').'\', \''.$this->l('Non ordered').'\'), o.id_order) id_order, IF(o.id_order, 1, 0) badge_success, IF(o.id_order, 0, 1) badge_danger, IF(co.id_guest, 1, 0) id_guest';
  41. $this->_join = 'LEFT JOIN '._DB_PREFIX_.'customer c ON (c.id_customer = a.id_customer)
  42. LEFT JOIN '._DB_PREFIX_.'currency cu ON (cu.id_currency = a.id_currency)
  43. LEFT JOIN '._DB_PREFIX_.'carrier ca ON (ca.id_carrier = a.id_carrier)
  44. LEFT JOIN '._DB_PREFIX_.'orders o ON (o.id_cart = a.id_cart)
  45. LEFT JOIN `'._DB_PREFIX_.'connections` co ON (a.id_guest = co.id_guest AND TIME_TO_SEC(TIMEDIFF(NOW(), co.`date_add`)) < 1800)';
  46. if (Tools::getValue('action') && Tools::getValue('action') == 'filterOnlyAbandonedCarts')
  47. $this->_having = 'id_order = \''.$this->l('Abandoned cart').'\'';
  48. $this->fields_list = array(
  49. 'id_cart' => array(
  50. 'title' => $this->l('ID'),
  51. 'align' => 'text-center',
  52. 'class' => 'fixed-width-xs'
  53. ),
  54. 'id_order' => array(
  55. 'title' => $this->l('Order ID'),
  56. 'align' => 'text-center',
  57. 'badge_danger' => true
  58. ),
  59. 'customer' => array(
  60. 'title' => $this->l('Customer'),
  61. 'filter_key' => 'c!lastname'
  62. ),
  63. 'total' => array(
  64. 'title' => $this->l('Total'),
  65. 'callback' => 'getOrderTotalUsingTaxCalculationMethod',
  66. 'orderby' => false,
  67. 'search' => false,
  68. 'align' => 'text-right',
  69. 'badge_success' => true
  70. ),
  71. 'carrier' => array(
  72. 'title' => $this->l('Carrier'),
  73. 'align' => 'text-center',
  74. 'callback' => 'replaceZeroByShopName',
  75. 'filter_key' => 'ca!name'
  76. ),
  77. 'date_add' => array(
  78. 'title' => $this->l('Date'),
  79. 'align' => 'text-right',
  80. 'type' => 'datetime',
  81. 'filter_key' => 'a!date_add'
  82. ),
  83. 'id_guest' => array(
  84. 'title' => $this->l('Online'),
  85. 'align' => 'text-center',
  86. 'type' => 'bool',
  87. 'havingFilter' => true,
  88. 'icon' => array(0 => 'blank.gif', 1 => 'tab-customers.gif')
  89. )
  90. );
  91. $this->shopLinkType = 'shop';
  92. $this->bulk_actions = array(
  93. 'delete' => array(
  94. 'text' => $this->l('Delete selected'),
  95. 'confirm' => $this->l('Delete selected items?'),
  96. 'icon' => 'icon-trash'
  97. )
  98. );
  99. parent::__construct();
  100. }
  101. public function initPageHeaderToolbar()
  102. {
  103. if (empty($this->display))
  104. $this->page_header_toolbar_btn['export_cart'] = array(
  105. 'href' => self::$currentIndex.'&exportcart&token='.$this->token,
  106. 'desc' => $this->l('Export carts', null, null, false),
  107. 'icon' => 'process-icon-export'
  108. );
  109. parent::initPageHeaderToolbar();
  110. }
  111. public function renderKpis()
  112. {
  113. $time = time();
  114. $kpis = array();
  115. /* The data generation is located in AdminStatsControllerCore */
  116. $helper = new HelperKpi();
  117. $helper->id = 'box-conversion-rate';
  118. $helper->icon = 'icon-sort-by-attributes-alt';
  119. //$helper->chart = true;
  120. $helper->color = 'color1';
  121. $helper->title = $this->l('Conversion Rate', null, null, false);
  122. $helper->subtitle = $this->l('30 days', null, null, false);
  123. if (ConfigurationKPI::get('CONVERSION_RATE') !== false)
  124. $helper->value = ConfigurationKPI::get('CONVERSION_RATE');
  125. if (ConfigurationKPI::get('CONVERSION_RATE_CHART') !== false)
  126. $helper->data = ConfigurationKPI::get('CONVERSION_RATE_CHART');
  127. if (ConfigurationKPI::get('CONVERSION_RATE_EXPIRE') < $time)
  128. $helper->source = $this->context->link->getAdminLink('AdminStats').'&ajax=1&action=getKpi&kpi=conversion_rate';
  129. $kpis[] = $helper->generate();
  130. $helper = new HelperKpi();
  131. $helper->id = 'box-carts';
  132. $helper->icon = 'icon-shopping-cart';
  133. $helper->color = 'color2';
  134. $helper->title = $this->l('Abandoned Carts', null, null, false);
  135. $date_from = date(Context::getContext()->language->date_format_lite, strtotime('-2 day'));
  136. $date_to = date(Context::getContext()->language->date_format_lite, strtotime('-1 day'));
  137. $helper->subtitle = sprintf($this->l('From %s to %s', null, null, false), $date_from, $date_to);
  138. $helper->href = $this->context->link->getAdminLink('AdminCarts').'&action=filterOnlyAbandonedCarts';
  139. if (ConfigurationKPI::get('ABANDONED_CARTS') !== false)
  140. $helper->value = ConfigurationKPI::get('ABANDONED_CARTS');
  141. if (ConfigurationKPI::get('ABANDONED_CARTS_EXPIRE') < $time)
  142. $helper->source = $this->context->link->getAdminLink('AdminStats').'&ajax=1&action=getKpi&kpi=abandoned_cart';
  143. $kpis[] = $helper->generate();
  144. $helper = new HelperKpi();
  145. $helper->id = 'box-average-order';
  146. $helper->icon = 'icon-money';
  147. $helper->color = 'color3';
  148. $helper->title = $this->l('Average Order Value', null, null, false);
  149. $helper->subtitle = $this->l('30 days', null, null, false);
  150. if (ConfigurationKPI::get('AVG_ORDER_VALUE') !== false)
  151. $helper->value = ConfigurationKPI::get('AVG_ORDER_VALUE');
  152. if (ConfigurationKPI::get('AVG_ORDER_VALUE_EXPIRE') < $time)
  153. $helper->source = $this->context->link->getAdminLink('AdminStats').'&ajax=1&action=getKpi&kpi=average_order_value';
  154. $kpis[] = $helper->generate();
  155. $helper = new HelperKpi();
  156. $helper->id = 'box-net-profit-visitor';
  157. $helper->icon = 'icon-user';
  158. $helper->color = 'color4';
  159. $helper->title = $this->l('Net Profit per Visitor', null, null, false);
  160. $helper->subtitle = $this->l('30 days', null, null, false);
  161. if (ConfigurationKPI::get('NETPROFIT_VISITOR') !== false)
  162. $helper->value = ConfigurationKPI::get('NETPROFIT_VISITOR');
  163. if (ConfigurationKPI::get('NETPROFIT_VISITOR_EXPIRE') < $time)
  164. $helper->source = $this->context->link->getAdminLink('AdminStats').'&ajax=1&action=getKpi&kpi=netprofit_visitor';
  165. $kpis[] = $helper->generate();
  166. $helper = new HelperKpiRow();
  167. $helper->kpis = $kpis;
  168. return $helper->generate();
  169. }
  170. public function renderView()
  171. {
  172. if (!($cart = $this->loadObject(true)))
  173. return;
  174. $customer = new Customer($cart->id_customer);
  175. $currency = new Currency($cart->id_currency);
  176. $this->context->cart = $cart;
  177. $this->context->currency = $currency;
  178. $this->context->customer = $customer;
  179. $this->toolbar_title = sprintf($this->l('Cart #%06d'), $this->context->cart->id);
  180. $products = $cart->getProducts();
  181. $customized_datas = Product::getAllCustomizedDatas((int)$cart->id);
  182. Product::addCustomizationPrice($products, $customized_datas);
  183. $summary = $cart->getSummaryDetails();
  184. /* Display order information */
  185. $id_order = (int)Order::getOrderByCartId($cart->id);
  186. $order = new Order($id_order);
  187. if (Validate::isLoadedObject($order))
  188. {
  189. $tax_calculation_method = $order->getTaxCalculationMethod();
  190. $id_shop = (int)$order->id_shop;
  191. }
  192. else
  193. {
  194. $id_shop = (int)$cart->id_shop;
  195. $tax_calculation_method = Group::getPriceDisplayMethod(Group::getCurrent()->id);
  196. }
  197. if ($tax_calculation_method == PS_TAX_EXC)
  198. {
  199. $total_products = $summary['total_products'];
  200. $total_discounts = $summary['total_discounts_tax_exc'];
  201. $total_wrapping = $summary['total_wrapping_tax_exc'];
  202. $total_price = $summary['total_price_without_tax'];
  203. $total_shipping = $summary['total_shipping_tax_exc'];
  204. }
  205. else
  206. {
  207. $total_products = $summary['total_products_wt'];
  208. $total_discounts = $summary['total_discounts'];
  209. $total_wrapping = $summary['total_wrapping'];
  210. $total_price = $summary['total_price'];
  211. $total_shipping = $summary['total_shipping'];
  212. }
  213. foreach ($products as $k => &$product)
  214. {
  215. if ($tax_calculation_method == PS_TAX_EXC)
  216. {
  217. $product['product_price'] = $product['price'];
  218. $product['product_total'] = $product['total'];
  219. }
  220. else
  221. {
  222. $product['product_price'] = $product['price_wt'];
  223. $product['product_total'] = $product['total_wt'];
  224. }
  225. $image = array();
  226. if (isset($product['id_product_attribute']) && (int)$product['id_product_attribute'])
  227. $image = Db::getInstance()->getRow('SELECT id_image
  228. FROM '._DB_PREFIX_.'product_attribute_image
  229. WHERE id_product_attribute = '.(int)$product['id_product_attribute']);
  230. if (!isset($image['id_image']))
  231. $image = Db::getInstance()->getRow('SELECT id_image
  232. FROM '._DB_PREFIX_.'image
  233. WHERE id_product = '.(int)$product['id_product'].' AND cover = 1');
  234. $product_obj = new Product($product['id_product']);
  235. $product['qty_in_stock'] = StockAvailable::getQuantityAvailableByProduct($product['id_product'], isset($product['id_product_attribute']) ? $product['id_product_attribute'] : null, (int)$id_shop);
  236. $image_product = new Image($image['id_image']);
  237. $product['image'] = (isset($image['id_image']) ? ImageManager::thumbnail(_PS_IMG_DIR_.'p/'.$image_product->getExistingImgPath().'.jpg', 'product_mini_'.(int)$product['id_product'].(isset($product['id_product_attribute']) ? '_'.(int)$product['id_product_attribute'] : '').'.jpg', 45, 'jpg') : '--');
  238. }
  239. $this->tpl_view_vars = array(
  240. 'products' => $products,
  241. 'discounts' => $cart->getCartRules(),
  242. 'order' => $order,
  243. 'cart' => $cart,
  244. 'currency' => $currency,
  245. 'customer' => $customer,
  246. 'customer_stats' => $customer->getStats(),
  247. 'total_products' => $total_products,
  248. 'total_discounts' => $total_discounts,
  249. 'total_wrapping' => $total_wrapping,
  250. 'total_price' => $total_price,
  251. 'total_shipping' => $total_shipping,
  252. 'customized_datas' => $customized_datas
  253. );
  254. return parent::renderView();
  255. }
  256. public function ajaxPreProcess()
  257. {
  258. if ($this->tabAccess['edit'] === '1')
  259. {
  260. $id_customer = (int)Tools::getValue('id_customer');
  261. $customer = new Customer((int)$id_customer);
  262. $this->context->customer = $customer;
  263. $id_cart = (int)Tools::getValue('id_cart');
  264. if (!$id_cart)
  265. $id_cart = $customer->getLastCart(false);
  266. $this->context->cart = new Cart((int)$id_cart);
  267. if (!$this->context->cart->id)
  268. {
  269. $this->context->cart->recyclable = 0;
  270. $this->context->cart->gift = 0;
  271. }
  272. if (!$this->context->cart->id_customer)
  273. $this->context->cart->id_customer = $id_customer;
  274. if (Validate::isLoadedObject($this->context->cart) && $this->context->cart->OrderExists())
  275. return;
  276. if (!$this->context->cart->secure_key)
  277. $this->context->cart->secure_key = $this->context->customer->secure_key;
  278. if (!$this->context->cart->id_shop)
  279. $this->context->cart->id_shop = (int)$this->context->shop->id;
  280. if (!$this->context->cart->id_lang)
  281. $this->context->cart->id_lang = (($id_lang = (int)Tools::getValue('id_lang')) ? $id_lang : Configuration::get('PS_LANG_DEFAULT'));
  282. if (!$this->context->cart->id_currency)
  283. $this->context->cart->id_currency = (($id_currency = (int)Tools::getValue('id_currency')) ? $id_currency : Configuration::get('PS_CURRENCY_DEFAULT'));
  284. $addresses = $customer->getAddresses((int)$this->context->cart->id_lang);
  285. $id_address_delivery = (int)Tools::getValue('id_address_delivery');
  286. $id_address_invoice = (int)Tools::getValue('id_address_delivery');
  287. if (!$this->context->cart->id_address_invoice && isset($addresses[0]))
  288. $this->context->cart->id_address_invoice = (int)$addresses[0]['id_address'];
  289. elseif ($id_address_invoice)
  290. $this->context->cart->id_address_invoice = (int)$id_address_invoice;
  291. if (!$this->context->cart->id_address_delivery && isset($addresses[0]))
  292. $this->context->cart->id_address_delivery = $addresses[0]['id_address'];
  293. elseif ($id_address_delivery)
  294. $this->context->cart->id_address_delivery = (int)$id_address_delivery;
  295. $this->context->cart->setNoMultishipping();
  296. $this->context->cart->save();
  297. $currency = new Currency((int)$this->context->cart->id_currency);
  298. $this->context->currency = $currency;
  299. }
  300. }
  301. public function ajaxProcessDeleteProduct()
  302. {
  303. if ($this->tabAccess['edit'] === '1')
  304. {
  305. $errors = array();
  306. if ((!$id_product = (int)Tools::getValue('id_product')) || !Validate::isInt($id_product))
  307. $errors[] = Tools::displayError('Invalid product');
  308. if (($id_product_attribute = (int)Tools::getValue('id_product_attribute')) && !Validate::isInt($id_product_attribute))
  309. $errors[] = Tools::displayError('Invalid combination');
  310. if (count($errors))
  311. die(Tools::jsonEncode($errors));
  312. if ($this->context->cart->deleteProduct($id_product, $id_product_attribute, (int)Tools::getValue('id_customization')))
  313. echo Tools::jsonEncode($this->ajaxReturnVars());
  314. }
  315. }
  316. public function ajaxProcessUpdateCustomizationFields()
  317. {
  318. $errors = array();
  319. if ($this->tabAccess['edit'] === '1')
  320. {
  321. $errors = array();
  322. if (Tools::getValue('only_display') != 1)
  323. {
  324. if (!$this->context->cart->id || (!$id_product = (int)Tools::getValue('id_product')))
  325. return;
  326. $product = new Product((int)$id_product);
  327. if (!$customization_fields = $product->getCustomizationFieldIds())
  328. return;
  329. foreach ($customization_fields as $customization_field)
  330. {
  331. $field_id = 'customization_'.$id_product.'_'.$customization_field['id_customization_field'];
  332. if ($customization_field['type'] == Product::CUSTOMIZE_TEXTFIELD)
  333. {
  334. if (!Tools::getValue($field_id))
  335. {
  336. if ($customization_field['required'])
  337. $errors[] = Tools::displayError('Please fill in all the required fields.');
  338. continue;
  339. }
  340. if (!Validate::isMessage(Tools::getValue($field_id)))
  341. $errors[] = Tools::displayError('Invalid message');
  342. $this->context->cart->addTextFieldToProduct((int)$product->id, (int)$customization_field['id_customization_field'], Product::CUSTOMIZE_TEXTFIELD, Tools::getValue($field_id));
  343. }
  344. elseif ($customization_field['type'] == Product::CUSTOMIZE_FILE)
  345. {
  346. if (!isset($_FILES[$field_id]) || !isset($_FILES[$field_id]['tmp_name']) || empty($_FILES[$field_id]['tmp_name']))
  347. {
  348. if ($customization_field['required'])
  349. $errors[] = Tools::displayError('Please fill in all the required fields.');
  350. continue;
  351. }
  352. if ($error = ImageManager::validateUpload($_FILES[$field_id], (int)Configuration::get('PS_PRODUCT_PICTURE_MAX_SIZE')))
  353. $errors[] = $error;
  354. if (!($tmp_name = tempnam(_PS_TMP_IMG_DIR_, 'PS')) || !move_uploaded_file($_FILES[$field_id]['tmp_name'], $tmp_name))
  355. $errors[] = Tools::displayError('An error occurred during the image upload process.');
  356. $file_name = md5(uniqid(rand(), true));
  357. if (!ImageManager::resize($tmp_name, _PS_UPLOAD_DIR_.$file_name))
  358. continue;
  359. elseif (!ImageManager::resize($tmp_name, _PS_UPLOAD_DIR_.$file_name.'_small', (int)Configuration::get('PS_PRODUCT_PICTURE_WIDTH'), (int)Configuration::get('PS_PRODUCT_PICTURE_HEIGHT')))
  360. $errors[] = Tools::displayError('An error occurred during the image upload process.');
  361. elseif (!chmod(_PS_UPLOAD_DIR_.$file_name, 0777) || !chmod(_PS_UPLOAD_DIR_.$file_name.'_small', 0777))
  362. $errors[] = Tools::displayError('An error occurred during the image upload process.');
  363. else
  364. $this->context->cart->addPictureToProduct((int)$product->id, (int)$customization_field['id_customization_field'], Product::CUSTOMIZE_FILE, $file_name);
  365. unlink($tmp_name);
  366. }
  367. }
  368. }
  369. $this->setMedia();
  370. $this->initFooter();
  371. $this->context->smarty->assign(array('customization_errors' => implode('<br />', $errors),
  372. 'css_files' => $this->css_files));
  373. return $this->smartyOutputContent('controllers/orders/form_customization_feedback.tpl');
  374. }
  375. }
  376. public function ajaxProcessUpdateQty()
  377. {
  378. if ($this->tabAccess['edit'] === '1')
  379. {
  380. $errors = array();
  381. if (!$this->context->cart->id)
  382. return;
  383. if ($this->context->cart->OrderExists())
  384. $errors[] = Tools::displayError('An order has already been placed with this cart.');
  385. elseif (!($id_product = (int)Tools::getValue('id_product')) || !($product = new Product((int)$id_product, true, $this->context->language->id)))
  386. $errors[] = Tools::displayError('Invalid product');
  387. elseif (!($qty = Tools::getValue('qty')) || $qty == 0)
  388. $errors[] = Tools::displayError('Invalid quantity');
  389. // Don't try to use a product if not instanciated before due to errors
  390. if (isset($product) && $product->id)
  391. {
  392. if (($id_product_attribute = Tools::getValue('id_product_attribute')) != 0)
  393. {
  394. if (!Product::isAvailableWhenOutOfStock($product->out_of_stock) && !Attribute::checkAttributeQty((int)$id_product_attribute, (int)$qty))
  395. $errors[] = Tools::displayError('There is not enough product in stock.');
  396. }
  397. else
  398. if (!$product->checkQty((int)$qty))
  399. $errors[] = Tools::displayError('There is not enough product in stock.');
  400. if (!($id_customization = (int)Tools::getValue('id_customization', 0)) && !$product->hasAllRequiredCustomizableFields())
  401. $errors[] = Tools::displayError('Please fill in all the required fields.');
  402. $this->context->cart->save();
  403. }
  404. else
  405. $errors[] = Tools::displayError('This product cannot be added to the cart.');
  406. if (!count($errors))
  407. {
  408. if ((int)$qty < 0)
  409. {
  410. $qty = str_replace('-', '', $qty);
  411. $operator = 'down';
  412. }
  413. else
  414. $operator = 'up';
  415. if (!($qty_upd = $this->context->cart->updateQty($qty, $id_product, (int)$id_product_attribute, (int)$id_customization, $operator)))
  416. $errors[] = Tools::displayError('You already have the maximum quantity available for this product.');
  417. elseif ($qty_upd < 0)
  418. {
  419. $minimal_qty = $id_product_attribute ? Attribute::getAttributeMinimalQty((int)$id_product_attribute) : $product->minimal_quantity;
  420. $errors[] = sprintf(Tools::displayError('You must add a minimum quantity of %d', false), $minimal_qty);
  421. }
  422. }
  423. echo Tools::jsonEncode(array_merge($this->ajaxReturnVars(), array('errors' => $errors)));
  424. }
  425. }
  426. public function ajaxProcessUpdateDeliveryOption()
  427. {
  428. if ($this->tabAccess['edit'] === '1')
  429. {
  430. $delivery_option = Tools::getValue('delivery_option');
  431. if ($delivery_option !== false)
  432. $this->context->cart->setDeliveryOption(array($this->context->cart->id_address_delivery => $delivery_option));
  433. if (Validate::isBool(($recyclable = (int)Tools::getValue('recyclable'))))
  434. $this->context->cart->recyclable = $recyclable;
  435. if (Validate::isBool(($gift = (int)Tools::getValue('gift'))))
  436. $this->context->cart->gift = $gift;
  437. if (Validate::isMessage(($gift_message = pSQL(Tools::getValue('gift_message')))))
  438. $this->context->cart->gift_message = $gift_message;
  439. $this->context->cart->save();
  440. echo Tools::jsonEncode($this->ajaxReturnVars());
  441. }
  442. }
  443. public function ajaxProcessUpdateOrderMessage()
  444. {
  445. if ($this->tabAccess['edit'] === '1')
  446. {
  447. $id_message = false;
  448. if ($old_message = Message::getMessageByCartId((int)$this->context->cart->id))
  449. $id_message = $old_message['id_message'];
  450. $message = new Message((int)$id_message);
  451. if ($message_content = Tools::getValue('message'))
  452. {
  453. if (Validate::isMessage($message_content))
  454. {
  455. $message->message = $message_content;
  456. $message->id_cart = (int)$this->context->cart->id;
  457. $message->id_customer = (int)$this->context->cart->id_customer;
  458. $message->save();
  459. }
  460. }
  461. else
  462. if (Validate::isLoadedObject($message))
  463. $message->delete();
  464. echo Tools::jsonEncode($this->ajaxReturnVars());
  465. }
  466. }
  467. public function ajaxProcessUpdateCurrency()
  468. {
  469. if ($this->tabAccess['edit'] === '1')
  470. {
  471. $currency = new Currency((int)Tools::getValue('id_currency'));
  472. if (Validate::isLoadedObject($currency) && !$currency->deleted && $currency->active)
  473. {
  474. $this->context->cart->id_currency = (int)$currency->id;
  475. $this->context->currency = $currency;
  476. $this->context->cart->save();
  477. }
  478. echo Tools::jsonEncode($this->ajaxReturnVars());
  479. }
  480. }
  481. public function ajaxProcessUpdateLang()
  482. {
  483. if ($this->tabAccess['edit'] === '1')
  484. {
  485. $lang = new Language((int)Tools::getValue('id_lang'));
  486. if (Validate::isLoadedObject($lang) && $lang->active)
  487. {
  488. $this->context->cart->id_lang = (int)$lang->id;
  489. $this->context->cart->save();
  490. }
  491. echo Tools::jsonEncode($this->ajaxReturnVars());
  492. }
  493. }
  494. public function ajaxProcessDuplicateOrder()
  495. {
  496. if ($this->tabAccess['edit'] === '1')
  497. {
  498. $errors = array();
  499. if (!$id_order = Tools::getValue('id_order'))
  500. $errors[] = Tools::displayError('Invalid order');
  501. $cart = Cart::getCartByOrderId($id_order);
  502. $new_cart = $cart->duplicate();
  503. if (!$new_cart || !Validate::isLoadedObject($new_cart['cart']))
  504. $errors[] = Tools::displayError('The order cannot be renewed.');
  505. else if (!$new_cart['success'])
  506. $errors[] = Tools::displayError('The order cannot be renewed.');
  507. else
  508. {
  509. $this->context->cart = $new_cart['cart'];
  510. echo Tools::jsonEncode($this->ajaxReturnVars());
  511. }
  512. }
  513. }
  514. public function ajaxProcessDeleteVoucher()
  515. {
  516. if ($this->tabAccess['edit'] === '1')
  517. {
  518. if ($this->context->cart->removeCartRule((int)Tools::getValue('id_cart_rule')))
  519. echo Tools::jsonEncode($this->ajaxReturnVars());
  520. }
  521. }
  522. public function ajaxProcessupdateFreeShipping()
  523. {
  524. if ($this->tabAccess['edit'] === '1')
  525. {
  526. if (!$id_cart_rule = CartRule::getIdByCode('BO_ORDER_'.(int)$this->context->cart->id))
  527. {
  528. $cart_rule = new CartRule();
  529. $cart_rule->code = CartRule::BO_ORDER_CODE_PREFIX.(int)$this->context->cart->id;
  530. $cart_rule->name = array(Configuration::get('PS_LANG_DEFAULT') => $this->l('Free Shipping', 'AdminTab', false, false));
  531. $cart_rule->id_customer = (int)$this->context->cart->id_customer;
  532. $cart_rule->free_shipping = true;
  533. $cart_rule->quantity = 1;
  534. $cart_rule->quantity_per_user = 1;
  535. $cart_rule->minimum_amount_currency = (int)$this->context->cart->id_currency;
  536. $cart_rule->reduction_currency = (int)$this->context->cart->id_currency;
  537. $cart_rule->date_from = date('Y-m-d H:i:s', time());
  538. $cart_rule->date_to = date('Y-m-d H:i:s', time() + 24 * 36000);
  539. $cart_rule->active = 1;
  540. $cart_rule->add();
  541. }
  542. else
  543. $cart_rule = new CartRule((int)$id_cart_rule);
  544. $this->context->cart->removeCartRule((int)$cart_rule->id);
  545. if (Tools::getValue('free_shipping'))
  546. $this->context->cart->addCartRule((int)$cart_rule->id);
  547. echo Tools::jsonEncode($this->ajaxReturnVars());
  548. }
  549. }
  550. public function ajaxProcessAddVoucher()
  551. {
  552. if ($this->tabAccess['edit'] === '1')
  553. {
  554. $errors = array();
  555. if (!($id_cart_rule = Tools::getValue('id_cart_rule')) || !$cart_rule = new CartRule((int)$id_cart_rule))
  556. $errors[] = Tools::displayError('Invalid voucher.');
  557. elseif ($err = $cart_rule->checkValidity($this->context))
  558. $errors[] = $err;
  559. if (!count($errors))
  560. if (!$this->context->cart->addCartRule((int)$cart_rule->id))
  561. $errors[] = Tools::displayError('Can\'t add the voucher.');
  562. echo Tools::jsonEncode(array_merge($this->ajaxReturnVars(), array('errors' => $errors)));
  563. }
  564. }
  565. public function ajaxProcessUpdateAddress()
  566. {
  567. if ($this->tabAccess['edit'] === '1')
  568. echo Tools::jsonEncode(array('addresses' => $this->context->customer->getAddresses((int)$this->context->cart->id_lang)));
  569. }
  570. public function ajaxProcessUpdateAddresses()
  571. {
  572. if ($this->tabAccess['edit'] === '1')
  573. {
  574. if (($id_address_delivery = (int)Tools::getValue('id_address_delivery')) &&
  575. ($address_delivery = new Address((int)$id_address_delivery)) &&
  576. $address_delivery->id_customer == $this->context->cart->id_customer)
  577. $this->context->cart->id_address_delivery = (int)$address_delivery->id;
  578. if (($id_address_invoice = (int)Tools::getValue('id_address_invoice')) &&
  579. ($address_invoice = new Address((int)$id_address_invoice)) &&
  580. $address_invoice->id_customer = $this->context->cart->id_customer)
  581. $this->context->cart->id_address_invoice = (int)$address_invoice->id;
  582. $this->context->cart->save();
  583. echo Tools::jsonEncode($this->ajaxReturnVars());
  584. }
  585. }
  586. protected function getCartSummary()
  587. {
  588. $summary = $this->context->cart->getSummaryDetails(null, true);
  589. $currency = Context::getContext()->currency;
  590. if (count($summary['products']))
  591. foreach ($summary['products'] as &$product)
  592. {
  593. $product['numeric_price'] = $product['price'];
  594. $product['numeric_total'] = $product['total'];
  595. $product['price'] = str_replace($currency->sign, '', Tools::displayPrice($product['price'], $currency));
  596. $product['total'] = str_replace($currency->sign, '', Tools::displayPrice($product['total'], $currency));
  597. $product['image_link'] = $this->context->link->getImageLink($product['link_rewrite'], $product['id_image'], 'small_default');
  598. if (!isset($product['attributes_small']))
  599. $product['attributes_small'] = '';
  600. $product['customized_datas'] = Product::getAllCustomizedDatas((int)$this->context->cart->id, null, true);
  601. }
  602. if (count($summary['discounts']))
  603. foreach ($summary['discounts'] as &$voucher)
  604. $voucher['value_real'] = Tools::displayPrice($voucher['value_real'], $currency);
  605. if (isset($summary['gift_products']) && count($summary['gift_products']))
  606. foreach ($summary['gift_products'] as &$product)
  607. {
  608. $product['image_link'] = $this->context->link->getImageLink($product['link_rewrite'], $product['id_image'], 'small_default');
  609. if (!isset($product['attributes_small']))
  610. $product['attributes_small'] = '';
  611. }
  612. return $summary;
  613. }
  614. protected function getDeliveryOptionList()
  615. {
  616. $delivery_option_list_formated = array();
  617. $delivery_option_list = $this->context->cart->getDeliveryOptionList();
  618. if (!count($delivery_option_list))
  619. return array();
  620. $id_default_carrier = (int)Configuration::get('PS_CARRIER_DEFAULT');
  621. foreach (current($delivery_option_list) as $key => $delivery_option)
  622. {
  623. $name = '';
  624. $first = true;
  625. $id_default_carrier_delivery = false;
  626. foreach ($delivery_option['carrier_list'] as $carrier)
  627. {
  628. if (!$first)
  629. $name .= ', ';
  630. else
  631. $first = false;
  632. $name .= $carrier['instance']->name;
  633. if ($delivery_option['unique_carrier'])
  634. $name .= ' - '.$carrier['instance']->delay[$this->context->employee->id_lang];
  635. if (!$id_default_carrier_delivery)
  636. $id_default_carrier_delivery = (int)$carrier['instance']->id;
  637. if ($carrier['instance']->id == $id_default_carrier)
  638. $id_default_carrier_delivery = $id_default_carrier;
  639. if (!$this->context->cart->id_carrier)
  640. {
  641. $this->context->cart->setDeliveryOption(array($this->context->cart->id_address_delivery => (int)$carrier['instance']->id.','));
  642. $this->context->cart->save();
  643. }
  644. }
  645. $delivery_option_list_formated[] = array('name' => $name, 'key' => $key);
  646. }
  647. return $delivery_option_list_formated;
  648. }
  649. public function displayAjaxSearchCarts()
  650. {
  651. $id_customer = (int)Tools::getValue('id_customer');
  652. $carts = Cart::getCustomerCarts((int)$id_customer);
  653. $orders = Order::getCustomerOrders((int)$id_customer);
  654. $customer = new Customer((int)$id_customer);
  655. if (count($carts))
  656. foreach ($carts as $key => &$cart)
  657. {
  658. $cart_obj = new Cart((int)$cart['id_cart']);
  659. if ($cart['id_cart'] == $this->context->cart->id || !Validate::isLoadedObject($cart_obj) || $cart_obj->OrderExists())
  660. unset($carts[$key]);
  661. $currency = new Currency((int)$cart['id_currency']);
  662. $cart['total_price'] = Tools::displayPrice($cart_obj->getOrderTotal(), $currency);
  663. }
  664. if (count($orders))
  665. foreach ($orders as &$order)
  666. $order['total_paid_real'] = Tools::displayPrice($order['total_paid_real'], $currency);
  667. if ($orders || $carts)
  668. $to_return = array_merge($this->ajaxReturnVars(),
  669. array('carts' => $carts,
  670. 'orders' => $orders,
  671. 'found' => true));
  672. else
  673. $to_return = array_merge($this->ajaxReturnVars(), array('found' => false));
  674. echo Tools::jsonEncode($to_return);
  675. }
  676. public function ajaxReturnVars()
  677. {
  678. $id_cart = (int)$this->context->cart->id;
  679. $message_content = '';
  680. if ($message = Message::getMessageByCartId((int)$this->context->cart->id))
  681. $message_content = $message['message'];
  682. $cart_rules = $this->context->cart->getCartRules(CartRule::FILTER_ACTION_SHIPPING);
  683. $free_shipping = false;
  684. if (count($cart_rules))
  685. foreach ($cart_rules as $cart_rule)
  686. if ($cart_rule['id_cart_rule'] == CartRule::getIdByCode('BO_ORDER_'.(int)$this->context->cart->id))
  687. {
  688. $free_shipping = true;
  689. break;
  690. }
  691. $addresses = $this->context->customer->getAddresses((int)$this->context->cart->id_lang);
  692. foreach ($addresses as &$data)
  693. {
  694. $address = new Address((int)$data['id_address']);
  695. $data['formated_address'] = AddressFormat::generateAddress($address, array(), "<br />");
  696. }
  697. return array(
  698. 'summary' => $this->getCartSummary(),
  699. 'delivery_option_list' => $this->getDeliveryOptionList(),
  700. 'cart' => $this->context->cart,
  701. 'currency' => new Currency($this->context->cart->id_currency),
  702. 'addresses' => $addresses,
  703. 'id_cart' => $id_cart,
  704. 'order_message' => $message_content,
  705. 'link_order' => $this->context->link->getPageLink(
  706. 'order', false,
  707. (int)$this->context->cart->id_lang,
  708. 'step=3&recover_cart='.$id_cart.'&token_cart='.md5(_COOKIE_KEY_.'recover_cart_'.$id_cart)
  709. ),
  710. 'free_shipping' => (int)$free_shipping
  711. );
  712. }
  713. public function initToolbar()
  714. {
  715. parent::initToolbar();
  716. unset($this->toolbar_btn['new']);
  717. }
  718. public function displayAjaxGetSummary()
  719. {
  720. echo Tools::jsonEncode($this->ajaxReturnVars());
  721. }
  722. public function ajaxProcessUpdateProductPrice()
  723. {
  724. if ($this->tabAccess['edit'] === '1')
  725. {
  726. SpecificPrice::deleteByIdCart((int)$this->context->cart->id, (int)Tools::getValue('id_product'), (int)Tools::getValue('id_product_attribute'));
  727. $specific_price = new SpecificPrice();
  728. $specific_price->id_cart = (int)$this->context->cart->id;
  729. $specific_price->id_shop = 0;
  730. $specific_price->id_shop_group = 0;
  731. $specific_price->id_currency = 0;
  732. $specific_price->id_country = 0;
  733. $specific_price->id_group = 0;
  734. $specific_price->id_customer = (int)$this->context->customer->id;
  735. $specific_price->id_product = (int)Tools::getValue('id_product');
  736. $specific_price->id_product_attribute = (int)Tools::getValue('id_product_attribute');
  737. $specific_price->price = (float)Tools::getValue('price');
  738. $specific_price->from_quantity = 1;
  739. $specific_price->reduction = 0;
  740. $specific_price->reduction_type = 'amount';
  741. $specific_price->from = '0000-00-00 00:00:00';
  742. $specific_price->to = '0000-00-00 00:00:00';
  743. $specific_price->add();
  744. echo Tools::jsonEncode($this->ajaxReturnVars());
  745. }
  746. }
  747. public static function getOrderTotalUsingTaxCalculationMethod($id_cart)
  748. {
  749. $context = Context::getContext();
  750. $context->cart = new Cart($id_cart);
  751. $context->currency = new Currency((int)$context->cart->id_currency);
  752. $context->customer = new Customer((int)$context->cart->id_customer);
  753. return Cart::getTotalCart($id_cart, true, Cart::BOTH_WITHOUT_SHIPPING);
  754. }
  755. public static function replaceZeroByShopName($echo, $tr)
  756. {
  757. return ($echo == '0' ? Configuration::get('PS_SHOP_NAME') : $echo);
  758. }
  759. public function displayDeleteLink($token = null, $id, $name = null)
  760. {
  761. // don't display ordered carts
  762. foreach ($this->_list as $row)
  763. if ($row['id_cart'] == $id && isset($row['id_order']) && is_numeric($row['id_order']))
  764. return ;
  765. return $this->helper->displayDeleteLink($token, $id, $name);
  766. }
  767. public function renderList()
  768. {
  769. if (!($this->fields_list && is_array($this->fields_list)))
  770. return false;
  771. $this->getList($this->context->language->id);
  772. $helper = new HelperList();
  773. // Empty list is ok
  774. if (!is_array($this->_list))
  775. {
  776. $this->displayWarning($this->l('Bad SQL query', 'Helper').'<br />'.htmlspecialchars($this->_list_error));
  777. return false;
  778. }
  779. $this->setHelperDisplay($helper);
  780. $helper->tpl_vars = $this->tpl_list_vars;
  781. $helper->tpl_delete_link_vars = $this->tpl_delete_link_vars;
  782. // For compatibility reasons, we have to check standard actions in class attributes
  783. foreach ($this->actions_available as $action)
  784. {
  785. if (!in_array($action, $this->actions) && isset($this->$action) && $this->$action)
  786. $this->actions[] = $action;
  787. }
  788. $helper->is_cms = $this->is_cms;
  789. $skip_list = array();
  790. foreach ($this->_list as $row)
  791. if (isset($row['id_order']) && is_numeric($row['id_order']))
  792. $skip_list[] = $row['id_cart'];
  793. if (array_key_exists('delete', $helper->list_skip_actions))
  794. $helper->list_skip_actions['delete'] = array_merge($helper->list_skip_actions['delete'], (array)$skip_list);
  795. else
  796. $helper->list_skip_actions['delete'] = (array)$skip_list;
  797. $list = $helper->generateList($this->_list, $this->fields_list);
  798. return $list;
  799. }
  800. }