AnonSec Shell
Server IP : 54.36.91.62  /  Your IP : 216.73.217.111
Web Server : Apache
System : Linux webm013.cluster127.gra.hosting.ovh.net 5.15.206-ovh-vps-grsec-zfs-classid #1 SMP Fri May 15 02:41:25 UTC 2026 x86_64
User : coopiak ( 151928)
PHP Version : 8.3.23
Disable Function : _dyuweyrj4,_dyuweyrj4r,dl
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /home/coopiak/amisdesseniors-fr/nimes/components/com_djcatalog2/controllers/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ HOME ]     

Current File : /home/coopiak/amisdesseniors-fr/nimes/components/com_djcatalog2/controllers/cart.php
<?php
/**
 * @package DJ-Catalog2
 * @copyright Copyright (C) DJ-Extensions.com, All rights reserved.
 * @license http://www.gnu.org/licenses GNU/GPL
 * @author url: http://dj-extensions.com
 * @author email contact@dj-extensions.com
 */
defined ('_JEXEC') or die('Restricted access');

jimport('joomla.application.component.controller');
jimport('joomla.filesystem.file');

class DJCatalog2ControllerCart extends JControllerLegacy
{

	function __construct($config = array())
	{
		parent::__construct($config);

		JPluginHelper::importPlugin('djcatalog2');
	}
	
	function add() {
		$params = JComponentHelper::getParams('com_djcatalog2');
		$app = JFactory::getApplication();
		$item_id = $app->input->getInt('item_id', 0);
		$combination_id = $app->input->getInt('combination_id', 0);
		//$quantity = max(1, $app->input->getInt('quantity', 0));
		$quantity = $app->input->getFloat('quantity', 0);
		$customisations = $app->input->get('customisation', array(), 'array');
		$features = $app->input->get('feature_field', array(), 'array');
		$configurable = $app->input->get('config_field', array(), 'array');
		$dimensions = $app->input->get('dimension', array(), 'array');
		
		$sid = Djcatalog2HelperCart::getSid($item_id, $combination_id, $features, $customisations, $dimensions, $configurable);
		
		$return = base64_decode($app->input->get('return', null, 'base64'));

		$is_ajax = (bool)($app->input->get('ajax', null) == '1');

		if (!$return) {
			$return = JRoute::_(DJCatalogHelperRoute::getCartRoute(), false);
		}
		
		$direct_checkout = $params->get('cart_direct_checkout', 0);

		if (!$item_id) {
			if ($is_ajax) {
				$response = array(
					'code' 		=> '400',
					'error' 	=> '1',
					'message' 	=>  JText::_('COM_DJCATALOG2_UPDATE_CART_FAILED'),
					'html'		=> '',
					'item_id'	=> $item_id
				);
				echo json_encode($response);
				$app->close();
			} else {
				$this->setRedirect($return, JText::_('COM_DJCATALOG2_UPDATE_CART_FAILED'), 'error');
				return false;
			}
		}

		$basket = Djcatalog2HelperCart::getInstance(true);
		
		//$dispatcher = JDispatcher::getInstance();
		Joomla\CMS\Factory::getApplication()->triggerEvent('onCartBeforeAddItem', array('djcatalog2.cart.add', $item_id, $quantity, $features, $customisations));

		if ($basket->addItem($item_id, $combination_id, $features, $customisations, $dimensions, $configurable, $quantity) == false) {
			$error = $basket->getError();
			$errMsg = JText::_('COM_DJCATALOG2_ADD_TO_CART_FAILED');
			if (!empty($error)) {
				$errMsg = $error;
			}
			if ($is_ajax) {
				$response = array(
					'code' 		=> '400',
					'error' 	=> '1',
					'message' 	=> $errMsg,
					'html'		=> '',
					'item_id'	=> $item_id
				);
				echo json_encode($response);
				$app->close();
			} else {
				$this->setRedirect($return, $errMsg, 'error');
				return false;
			}
		}

		//$item_obj = $basket->getItem($item_id, $combination_id);
		$item_obj = $basket->getItemBySid($sid);

		if (is_array($customisations) && !empty($customisations)) {
			foreach($customisations as $ckey => $customId) {

				$customValues = $app->input->get('customValues-'.$customId, array(), 'array');

				$temp = array(
					'id' => $customId,
					'data' => array()
				);

				if (is_array($customValues) && count($customValues)) {
					$temp['data'] = $customValues;
				}
				$customisations[$ckey] = $temp;
			}

			$basket->addCustomisations($customisations, $item_obj);
		}
		
		if (is_array($features) && !empty($features)) {
			$basket->addFeatures($sid, $item_obj, $features);
		}
		
		if ($basket->addDimensions($sid, $item_obj, $dimensions) == false) {
			$basket->removeItem($sid);
			
			$error = $basket->getError();
			$errMsg = JText::_('COM_DJCATALOG2_ADD_TO_CART_FAILED');
			if (!empty($error)) {
				$errMsg = $error;
			}
			if ($is_ajax) {
				$response = array(
					'code' 		=> '400',
					'error' 	=> '1',
					'message' 	=> $errMsg,
					'html'		=> '',
					'item_id'	=> $item_id
				);
				echo json_encode($response);
				$app->close();
			} else {
				$this->setRedirect($return, $errMsg, 'error');
				return false;
			}
		}
		
		if ($basket->addConfigurable($sid, $item_obj, $configurable) == false) {
			$basket->removeItem($sid);
			
			$error = $basket->getError();
			$errMsg = JText::_('COM_DJCATALOG2_ADD_TO_CART_FAILED');
			if (!empty($error)) {
				$errMsg = $error;
			}
			if ($is_ajax) {
				$response = array(
					'code' 		=> '400',
					'error' 	=> '1',
					'message' 	=> $errMsg,
					'html'		=> '',
					'item_id'	=> $item_id
				);
				echo json_encode($response);
				$app->close();
			} else {
				$this->setRedirect($return, $errMsg, 'error');
				return false;
			}
		}
		
		$direct_checkout = (bool)($direct_checkout == '1' || ($direct_checkout == '2' && ($item_obj->product_type == 'subscription' || $item_obj->product_type == 'virtual')));
		if ($direct_checkout) {
			foreach(array_keys($basket->getItems()) as $bsid ) {
				if ($bsid != $sid) {
					$basket->removeItem($bsid, true);
				} else {
					$basket->updateQuantity($bsid, 1);
				}
			}
		}
		
		$basket->saveToStorage();
		

		$items = $basket->getItems();

		$total = $basket->getTotal();
		$product_total = $basket->getProductTotal();

		foreach($total as $k=>$v) {
			$total[$k] =  DJCatalog2HtmlHelper::formatPrice($v, $params);
		}

		foreach($product_total as $k=>$v) {
			$product_total[$k] =  DJCatalog2HtmlHelper::formatPrice($v, $params);
		}

		if ($is_ajax) {
            $response = array(
                'code' 		=> '200',
                'error' 	=> '0',
                'message' 	=>  JText::sprintf('COM_DJCATALOG2_ADD_TO_CART_SUCCESS', $item_obj->name, JRoute::_(DJCatalogHelperRoute::getCartRoute())),
                'html'		=> '',
                'item'      => json_encode($item_obj),
                'quantity' => $quantity,
                'item_id'	=> $item_id,
                'item_name'	=> $item_obj->name,
                'basket_count' => count($items),
                'total' => $total,
                'product_total' => $product_total
            );
            
            if ($direct_checkout) {
            	$response['redirect'] = JRoute::_(DJCatalogHelperRoute::getCheckoutRoute(), false);
            }
            
			echo json_encode($response);
			$app->close();
		}

		if ($direct_checkout) {
			$this->setRedirect(JRoute::_(DJCatalogHelperRoute::getCheckoutRoute(), false));
			return true;
		}
		$msg = JText::sprintf('COM_DJCATALOG2_ADD_TO_CART_SUCCESS_NO_AJAX', $item_obj->name, JRoute::_(DJCatalogHelperRoute::getCartRoute()));
		$this->setRedirect($return, $msg, 'message');
		return true;
	}

	function add_multiple_combinations() {
		//JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN'));

		$app = JFactory::getApplication();
		$item_id = $app->input->getInt('item_id', 0);

		$quantities = $app->input->get('combination_qty', array(), 'array');
		$customisations = $app->input->get('customisation', array(), 'array');

		$return = base64_decode($app->input->get('return', null, 'base64'));

		$is_ajax = (bool)($app->input->get('ajax', null) == '1');

		if (!$return) {
			$return = JRoute::_(DJCatalogHelperRoute::getCartRoute(), false);
		}

		if (!$item_id) {
			if ($is_ajax) {
				$response = array(
					'code' 		=> '400',
					'error' 	=> '1',
					'message' 	=>  JText::_('COM_DJCATALOG2_UPDATE_CART_FAILED'),
					'html'		=> '',
					'item_id'	=> $item_id
				);
				echo json_encode($response);
				$app->close();
			} else {
				$this->setRedirect($return, JText::_('COM_DJCATALOG2_UPDATE_CART_FAILED'), 'error');
				return false;
			}
		}

		$basket = Djcatalog2HelperCart::getInstance(true);

		foreach($quantities as $combination_id => $quantity) {
			if (!$quantity) {
				unset($quantities[$combination_id]);
				continue;
			}

			if ($basket->addItem($item_id, $combination_id, $quantity) == false) {
				if ($is_ajax) {
					$response = array(
						'code' 		=> '400',
						'error' 	=> '1',
						'message' 	=> JText::_('COM_DJCATALOG2_ADD_TO_CART_FAILED'),
						'html'		=> '',
						'item_id'	=> $item_id
					);
					echo json_encode($response);
					$app->close();
				} else {
					$this->setRedirect($return, JText::_('COM_DJCATALOG2_ADD_TO_CART_FAILED'), 'error');
					return false;
				}
			}
		}

		$basket->saveToStorage();

		if (is_array($customisations) && !empty($customisations)) {
			foreach($customisations as $ckey => $customId) {

				$customValues = $app->input->get('customValues-'.$customId, array(), 'array');

				$temp = array(
					'id' => $customId,
					'data' => array()
				);

				if (is_array($customValues) && count($customValues)) {
					$temp['data'] = $customValues;
				}
				$customisations[$ckey] = $temp;
			}

			foreach($quantities as $combination_id => $quantity) {
				$item_obj = $basket->getItem($item_id, $combination_id);
				$basket->addCustomisations($customisations, $item_obj);
			}
		}

		$items = $basket->getItems();

		if ($is_ajax) {
			$response = array(
				'code' 		=> '200',
				'error' 	=> '0',
				'message' 	=>  JText::sprintf('COM_DJCATALOG2_ADD_TO_CART_SUCCESS_COMBINATIONS', count($quantities) , JRoute::_(DJCatalogHelperRoute::getCartRoute())),
				'html'		=> '',
				'item_id'	=> '',
				'item_name'	=> '',
				'basket_count' => count($items)
			);
			echo json_encode($response);
			$app->close();
		}

		$msg = JText::sprintf('COM_DJCATALOG2_ADD_TO_CART_SUCCESS_COMBINATIONS', count($quantities), JRoute::_(DJCatalogHelperRoute::getCartRoute()));
		$this->setRedirect($return, $msg, 'message');
		return true;
	}
	
	public function update() {
		JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN'));
		$app = JFactory::getApplication();
		//$item_id = $app->input->getInt('item_id', 0);
		$sid = $app->input->getCmd('sid', 0);

		//$quantity = max(0, $app->input->getInt('quantity', 0));
		$quantity = $app->input->getFloat('quantity', 0);

		$return = base64_decode($app->input->get('return', null, 'base64'));

		if (!$return) {
			$return = JRoute::_(DJCatalogHelperRoute::getCartRoute(), false);
		}

		if (!$sid) {
			$this->setRedirect($return, JText::_('COM_DJCATALOG2_UPDATE_CART_FAILED'), 'error');
			return false;
		}

		$msg = JText::_('COM_DJCATALOG2_UPDATE_CART_SUCCESS');
		$basket = Djcatalog2HelperCart::getInstance(true);
		
		// resetting delivery & payment
		$basket->setDelivery(0);
		$basket->setPayment(0);

		if (!$quantity || $quantity <= 0.0000) {
			$basket->removeItem($sid);
			$msg = JText::_('COM_DJCATALOG2_PRODUCT_REMOVED_FROM_CART');
		}
		else if ($basket->updateQuantity($sid, $quantity) == false) {
			$this->setRedirect($return, JText::_('COM_DJCATALOG2_UPDATE_CART_FAILED'), 'error');
			return false;
		}

		$basket->saveToStorage();

		$this->setRedirect($return, $msg, 'message');
		return true;

	}

	public function update_batch() {
		JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN'));

		$app = JFactory::getApplication();
		$user = JFactory::getUser();
		$salesman = $user->authorise('djcatalog2.salesman', 'com_djcatalog2');

		$quantities = $app->input->get('quantity', array(), 'array');
		$prices = $app->input->get('price', array(), 'array');
		$append = $app->input->getInt('append', 0);
		
		$return = base64_decode($app->input->get('return', null, 'base64'));
		if (!$return) {
			$return = JRoute::_(DJCatalogHelperRoute::getCartRoute(), false);
		}

		if (empty($quantities)) {
			$this->setRedirect($return, JText::_('COM_DJCATALOG2_UPDATE_CART_FAILED'), 'error');
			return false;
		}

		$attributes = $app->input->get('attribute', array(), 'array');
		$msg = JText::_('COM_DJCATALOG2_UPDATE_CART_SUCCESS');
		$basket = Djcatalog2HelperCart::getInstance(true);
		
		// resetting delivery & payment
		$basket->setDelivery(0);
		$basket->setPayment(0);

		foreach ($quantities as $item_id => $quantity) {
			$item_attr = isset($attributes[$item_id]) ? $attributes[$item_id] : null;
			if (!$quantity || $quantity <= 0.0000) {
				$basket->removeItem($item_id);
			}
			else if ($basket->updateQuantity($item_id, $quantity, $item_attr, $append) == false) {
				$error = $basket->getError();
				$errMsg = JText::_('COM_DJCATALOG2_UPDATE_CART_FAILED');
				if (!empty($error)) {
					$errMsg = $error;
				}
				
				$this->setRedirect($return, $errMsg, 'error');
				return false;
			}

			if (isset($prices[$item_id]) && is_numeric($prices[$item_id])) {
				$basket->prices[$item_id] = $prices[$item_id];
			}
		}

		if ($salesman) {
			$basket->recalculate();
		}

		$basket->saveToStorage();

		$this->setRedirect($return, $msg, 'message');
		return true;

	}

	public function remove() {
		//JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN'));

		$app = JFactory::getApplication();
		$sid = $app->input->getCmd('sid', 0);
		$is_ajax = $app->input->getBool('isAjax', false);

		$return = base64_decode($app->input->get('return', null, 'base64'));
		if (!$return) {
			$return = JRoute::_(DJCatalogHelperRoute::getCartRoute(), false);
		}

		// sid can be empty - e.g. when removing global product customisations
		/*if (!$sid) {
		 $this->setRedirect($return, JText::_('COM_DJCATALOG2_UPDATE_CART_FAILED'), 'error');
		 return false;
		 }*/

		$msg = JText::_('COM_DJCATALOG2_PRODUCT_REMOVED_FROM_CART');
		$basket = Djcatalog2HelperCart::getInstance(true);
		
		// resetting delivery & payment
		$basket->setDelivery(0);
		$basket->setPayment(0);

		if ($basket->removeItem($sid) == false) {

			if(!$is_ajax) {
				$this->setRedirect($return, JText::_('COM_DJCATALOG2_UPDATE_CART_FAILED'), 'error');
				return false;
			}

			$response = array(
				'code' 		=> '400',
				'error' 	=> '1',
				'message' 	=> JText::_('COM_DJCATALOG2_REMOVED_FROM_CART_FAILED'),
				'html'		=> ''
			);
			echo json_encode($response);
			$app->close();
		}

		$basket->saveToStorage();

		if(!$is_ajax) {
			$this->setRedirect($return, $msg, 'message');
			return true;
		}

		$response = array(
			'code' 		=> '200',
			'error' 	=> '0',
			'message' 	=>  JText::_('COM_DJCATALOG2_REMOVED_FROM_CART_SUCCESS'),
			'html'		=> '',
			'basket_count' => count($basket->getItems())
		);
		echo json_encode($response);
		$app->close();
	}

	public function clear() {
		if (!JSession::checkToken('post') && !JSession::checkToken('get')) {
			jexit(JText::_('JINVALID_TOKEN'));
		}

		$app = JFactory::getApplication();

		$return = base64_decode($app->input->get('return', null, 'base64'));
		if (!$return) {
			$return = JRoute::_(DJCatalogHelperRoute::getCartRoute(), false);
		}


		$msg = JText::_('COM_DJCATALOG2_CART_HAS_BEEN_CLEARED');
		$basket = Djcatalog2HelperCart::getInstance(true);

		$basket->clear();

		$this->setRedirect($return, $msg, 'message');
		return true;

	}

	public function clearfree() {

		$app = JFactory::getApplication();

		$return = base64_decode($app->input->get('return', null, 'base64'));
		if (!$return) {
			$return = JRoute::_(DJCatalogHelperRoute::getCartRoute(), false);
		}


		$basket = Djcatalog2HelperCart::getInstance(true);

		foreach ($basket->items as $item) {
			if ($item->_prices['base']['display'] == 0.0 || !$item->onstock || $item->stock == 0.0) {
				$basket->removeItem($item->_sid);
			}
		}

		$basket->saveToStorage();

		$this->setRedirect($return, JText::_('COM_DJCATALOG2_UPDATE_CART_SUCCESS'));
		return true;

	}

	public function add_customisation() {
		JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN'));

		$app = JFactory::getApplication();

		$customisations = $app->input->get('customisation', array(), 'array');

		$return = base64_decode($app->input->get('return', null, 'base64'));

		$is_ajax = (bool)($app->input->get('ajax', null) == '1');

		if (!$return) {
			$return = JRoute::_(DJCatalogHelperRoute::getCartRoute(), false);
		}

		$basket = Djcatalog2HelperCart::getInstance(true);

		if (is_array($customisations) && !empty($customisations)) {
			foreach($customisations as $ckey => $customId) {

				$customValues = $app->input->get('customValues-'.$customId, array(), 'array');

				$temp = array(
					'id' => $customId,
					'data' => array()
				);

				if (is_array($customValues) && count($customValues)) {
					$temp['data'] = $customValues;
				}
				$customisations[$ckey] = $temp;
			}

			$basket->addCustomisations($customisations, null);
		} else {
			if ($is_ajax) {
				$response = array(
					'code' 		=> '400',
					'error' 	=> '1',
					'message' 	=>  JText::_('COM_DJCATALOG2_CUSTOMISATION_ADD_TO_CART_ERROR'),
					'html'		=> ''
				);
				echo json_encode($response);
				$app->close();
			} else {
				$this->setRedirect($return, JText::_('COM_DJCATALOG2_CUSTOMISATION_ADD_TO_CART_ERROR'), 'error');
				return false;
			}
		}

		$items = $basket->getItems();

		$params = JComponentHelper::getParams('com_djcatalog2');

		$total = $basket->getTotal();
		$product_total = $basket->getProductTotal();

		foreach($total as $k=>$v) {
			$total[$k] =  DJCatalog2HtmlHelper::formatPrice($v, $params);
		}

		foreach($product_total as $k=>$v) {
			$product_total[$k] =  DJCatalog2HtmlHelper::formatPrice($v, $params);
		}

		if ($is_ajax) {
			$response = array(
				'code' 		=> '200',
				'error' 	=> '0',
				'message' 	=>  JText::_('COM_DJCATALOG2_CUSTOMISATION_ADD_TO_CART_SUCCESS'),
				'html'		=> '',
				'basket_count' => count($items),
				'total' => $total,
				'product_total' => $product_total
			);
			echo json_encode($response);
			$app->close();
		}

		$msg = JText::_('COM_DJCATALOG2_CUSTOMISATION_ADD_TO_CART_SUCCESS');
		$this->setRedirect($return, $msg, 'message');
		return true;
	}

	public function coupon_apply() {
		JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN'));

		$app = JFactory::getApplication();
		$db = JFactory::getDBO();
		$user = JFactory::getUser();
		$nowDate = $db->Quote(JFactory::getDate()->toSql());

		$code = $app->input->getVar('coupon_code', '');
		$return = base64_decode($app->input->get('return', null, 'base64'));

		if (!$return) {
			$return = JRoute::_(DJCatalogHelperRoute::getCheckoutRoute(), false);
		}

		// get coupon by coupon code provided by user
		$coupon = Djcatalog2HelperCoupon::getCouponByCode($code);

		if (!$coupon) {
			$this->setRedirect($return, JText::_('COM_DJCATALOG2_INVALID_COUPON_CODE'), 'error');
			return false;
		}

		// get basket object from storage
		$basket = Djcatalog2HelperCart::getInstance(true);

		// try to assign a coupon to current basket
		if(!$basket->setCoupon($coupon)){
			$this->setRedirect($return, $coupon->getError(), 'error');
			return false;
		}

		$coupon->increaseReuse();

		$this->setRedirect($return, JText::_('COM_DJCATALOG2_COUPON_APPLIED'), 'message');

		return true;
	}

	public function coupon_remove() {
		JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN'));

		$app = JFactory::getApplication();
		$db = JFactory::getDBO();
		$user = JFactory::getUser();

		$return = base64_decode($app->input->get('return', null, 'base64'));
		if (!$return) {
			$return = JRoute::_(DJCatalogHelperRoute::getCheckoutRoute(), false);
		}

		$basket = Djcatalog2HelperCart::getInstance(true);

		$coupon = $basket->removeCoupon();

		if(!$coupon){
			$this->setRedirect($return, JText::_('COM_DJCATALOG2_NO_COUPON_TO_REMOVE'), 'message');
			return false;
		}

		$coupon->decreaseReuse();

		$this->setRedirect($return, JText::_('COM_DJCATALOG2_COUPON_REMOVED'), 'message');
		return true;
	}

	public function reorder() {

		$app = JFactory::getApplication();
		$user = JFactory::getUser();

		$return = base64_decode($app->input->get('return', null, 'base64'));
		if (!$return) {
			$return = JRoute::_(DJCatalogHelperRoute::getOrdersRoute(), false);
		}

		$order_id = $app->input->get('oid', null, 'int');
		$model = $this->getModel('Order', 'DJCatalog2Model');
		$order = $model->getItem($order_id);
		if(!$order) {
			throw new Exception(JText::_('COM_DJCATALOG2_ERROR_ORDER_NOT_FOUND'), 404);
			return false;
		}

		$salesman = $user->authorise('djcatalog2.salesman', 'com_djcatalog2');
		if ($order->user_id != $user->id && !($user->authorise('core.admin') || $salesman)) {
			throw new Exception(JText::_('JERROR_ALERTNOAUTHOR'), 403);
		}

		$basket = Djcatalog2HelperCart::getInstance(true);
		$basket->clear();

		$db = JFactory::getDbo();
		$db->setQuery('select * from #__djc2_order_items where order_id='.$order->id);
		$items = $db->loadObjectList();

		foreach ($items as $item) {

			if(!$basket->addItem($item->item_id, $item->combination_id, $item->quantity, true)) {
				$search_link = JRoute::_('index.php?option=com_djcatalog2&task=search&search='.urlencode($item->item_name));
				$app->enqueueMessage(JText::sprintf('COM_DJCATALOG2_REORDER_ITEM_NOT_ADDED', $search_link, $item->item_name), 'notice');
			}
		}

		$basket->saveToStorage();

		$this->setRedirect(JRoute::_(DJCatalogHelperRoute::getCartRoute(), false), JText::_('COM_DJCATALOG2_REORDER_ITEMS_ADDED_TO_CART'), 'message');
		return true;

	}

	public function getSummary() {
		$app = JFactory::getApplication();
		$delivery_id = $app->input->getInt('delivery', 0);
		$payment_id = $app->input->getInt('payment', 0);
		$shipping_days = $app->input->getInt('shipping_days', 0);

		$basket = Djcatalog2HelperCart::getInstance(true);

		$output = array('error'=> 0, 'data' => array());
		
		// we need to "reset" the cart that the price rules could be re-applied the way they should
		if (
			($basket->delivery && $basket->delivery->id != $delivery_id)
			|| ($basket->payment && $basket->payment->id != $payment_id)
			|| (!$basket->delivery && $delivery_id)
			|| (!$basket->payment && $payment_id)
			) {
			$basket->setDelivery(0);
			$basket->setPayment(0);
			$basket->recalculate();
			$basket->saveToStorage();
			
			$basket = Djcatalog2HelperCart::getInstance(true);
			
			if (isset(Djcatalog2HelperPrice::$runOnce['afterInitMinPrice'])) {
				unset(Djcatalog2HelperPrice::$runOnce['afterInitMinPrice']);
			}
		}
		
		try {
			$basket->setShippingDays($shipping_days);
			$basket->setDelivery($delivery_id);
			$basket->setPayment($payment_id);
		}
		catch (Exception $e) {
			$output['error'] = 1;
			$output['error_message'] = $e->getMessage();
		}
		
		$basket->recalculate();

		$basket->saveToStorage();

		$params = Djcatalog2Helper::getParams();

		$payment_price = $delivery_price = 0;

		if (!empty($basket->delivery) && isset($basket->delivery->_prices)) {
			$delivery_price = $basket->delivery->_prices['total']['gross'];
		}
		if (!empty($basket->payment) && isset($basket->payment->_prices)) {
			$payment_price = $basket->payment->_prices['total']['gross'];
		}
		
		$totalComponents = 0.0;
		$components = $basket->getPriceComponents();
		if (!empty($components)) {
			foreach($components as $price_component) {
				if ($price_component->type == 'coupon' || ($price_component->type == 'rule' && $price_component->rule->calc_type != 'grand_total')) {
					continue;
				}
				$totalComponents += $price_component->value['gross'];
			}
		}

		$output['data']['products'] = DJCatalog2HtmlHelper::formatPrice($basket->product_total['gross'], $params, false);
		$output['data']['delivery'] = DJCatalog2HtmlHelper::formatPrice($delivery_price, $params, false);
		$output['data']['payment'] = DJCatalog2HtmlHelper::formatPrice($payment_price, $params, false);
		$output['data']['components'] = DJCatalog2HtmlHelper::formatPrice($totalComponents, $params, false);
		$output['data']['total'] = DJCatalog2HtmlHelper::formatPrice($basket->total['gross'], $params, false);

        $output['delivery'] = $delivery_id;

        if (!count(array_diff(ob_list_handlers(), array('default output handler'))) || ob_get_length()) {
            @ob_clean();
        }

		//$dispatcher = JDispatcher::getInstance();
		foreach (Joomla\CMS\Factory::getApplication()->triggerEvent('onCartAfterGetSummary', array('djcatalog2.cart.get_summary', $output)) as $response) {
			$output = $response;
		}

		echo json_encode($output);

		$app->close();
	}

	public function getInfo() {
		$app = JFactory::getApplication();
		$params = JComponentHelper::getParams('com_djcatalog2');

		$basket = Djcatalog2HelperCart::getInstance(true);
		$items = $basket->getItems();

		$total = $basket->getTotal();
		$product_total = $basket->getProductTotal();

		foreach($total as $k=>$v) {
			$total[$k] =  DJCatalog2HtmlHelper::formatPrice($v, $params);
		}

		foreach($product_total as $k=>$v) {
			$product_total[$k] =  DJCatalog2HtmlHelper::formatPrice($v, $params);
		}

		if (!count(array_diff(ob_list_handlers(), array('default output handler'))) || ob_get_length()) {
			@ob_clean();
		}

		$response = array(
			'code' 		=> '200',
			'error' 	=> '0',
			'html'		=> '',
			'basket_count' => count($items),
			'total' => $total,
			'product_total' => $product_total
		);
		echo json_encode($response);

		$app->close();
	}

	public function checkout() {

		JSession::checkToken('get') or JSession::checkToken('post') or jexit(JText::_('JINVALID_TOKEN'));

		$app = JFactory::getApplication();
		$params     = JComponentHelper::getParams('com_djcatalog2');
		$user = JFactory::getUser();

		if ($this->allowCheckout() == false) {
			return false;
		}

        JPluginHelper::importPlugin('djcatalog2');

        // Get the dispatcher.
        $dispatcher = Joomla\CMS\Factory::getApplication()->getDispatcher();
        Joomla\CMS\Factory::getApplication()->triggerEvent('onDJCatalog2BeforeCheckout');

		if (!$user->guest || ($params->get('cart_registered', '1') == '0' && $params->get('cart_skip_login', '0') == '1')) {
			$this->setRedirect(JRoute::_(DJCatalogHelperRoute::getCheckoutRoute() , false));
		} else {
			$this->setRedirect(JRoute::_(DJCatalog2HelperRoute::getCartRoute().'&layout=login' , false));
		}

		return true;
	}

	public function query() {

		JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN'));

		$app = JFactory::getApplication();

		if ($this->allowQuery() == false) {
			return false;
		}

		$app->redirect(JRoute::_(DJCatalogHelperRoute::getQueryRoute(), false));
		return true;
	}

	public function confirm() {
		JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN'));

		if ($this->allowCheckout() == false) {
			return false;
		}

		$app = JFactory::getApplication();


		$date = JFactory::getDate();
		$model = $this->getModel('Order');
		$db = JFactory::getDbo();

		$params = Djcatalog2Helper::getParams();
		$language = JFactory::getLanguage();

		$post_data  = $this->input->post->get('jform', array(), 'array');

		$juser = JFactory::getUser();
		$salesman = $juser->authorise('djcatalog2.salesman', 'com_djcatalog2');
		$user_id = null;
		if ($salesman && !empty($post_data['djcatalog2profile']) && isset($post_data['djcatalog2profile']['user_id'])) {
			$user_id = (int)$post_data['djcatalog2profile']['user_id'];
		}

		$basket = Djcatalog2HelperCart::getInstance();

		$items = $basket->getItems();

		$user = Djcatalog2HelperUser::getUserProfile($user_id);
		$user_data = (isset($user->djcatalog2profile)) ? array('djcatalog2profile' => Joomla\Utilities\ArrayHelper::fromObject($user->djcatalog2profile, true)) : array();
		
		$form = $model->getForm(array(), false);

		if (!$form) {
			$app->enqueueMessage($model->getError(), 'error');
			return false;
		}

		$form_data = array();
		$fields = $form->getFieldset('basicprofile');
		foreach ($fields as $field) {
			if (isset($user_data[$field->fieldname])) {
				$form_data[$field->fieldname] = $user_data[$field->fieldname];
			}

			if (isset($post_data['djcatalog2profile'][$field->fieldname])) {
				$form_data[$field->fieldname] = $post_data['djcatalog2profile'][$field->fieldname];
			}

			if (!isset($form_data[$field->fieldname])) {
				$form_data[$field->fieldname] = null;
			}
		}

		$data = $post_data;
		$data['djcatalog2profile'] = $form_data;


		if (empty($data) || empty($data['djcatalog2profile'])) {
			$data['djcatalog2profile'] = $user_data;
		}

		if (isset($data['djcatalog2delivery']) && isset($data['djcatalog2delivery']['delivery_to_billing']) && $data['djcatalog2delivery']['delivery_to_billing'] == 1) {
			foreach ($data['djcatalog2profile'] as $k=>$v) {
				$data['djcatalog2delivery'][$k] = $v;
			}
		}

		if (!isset($data['djcatalog2orderdetails'])) {
			$data['djcatalog2orderdetails'] = array();
		}
		if (!isset($data['djcatalog2orderdetails']['delivery_method_id'])) {
			$data['djcatalog2orderdetails']['delivery_method_id'] = empty($basket->delivery->id) ? 0 : $basket->delivery->id;
		}
		if (!isset($data['djcatalog2orderdetails']['payment_method_id'])) {
			$data['djcatalog2orderdetails']['payment_method_id'] = empty($basket->payment->id) ? 0 : $basket->payment->id;
		}

		//$dispatcher = JDispatcher::getInstance();
		$onCartBeforeValidData = Joomla\CMS\Factory::getApplication()->triggerEvent('onCartBeforeValidData', array('djcatalog2.cart.confirm', &$data));
		foreach ($onCartBeforeValidData as $pluginResponse) {
			$data = $pluginResponse;
		}
		
		//echo '<pre>' . print_r($data, true) . '</pre>';
		// Test whether the data is valid.
		Djcatalog2HelperUser::prepareFormValidation($form, $data);
		//echo '<pre>' . print_r($form, true) . '</pre>';
		
		$validData = $model->validate($form, $data);
		//echo '<pre>' . print_r($validData, true) . '</pre>';die();
		$errors = $model->getErrors();

		$app->setUserState('com_djcatalog2.order.data', $validData);

		// Check for validation errors.
		if ($validData === false)
		{
			// Get the validation messages.
			$errors = $model->getErrors();

			// Push up to three validation messages out to the user.
			for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++) {
				if ($errors[$i] instanceof Exception) {
					$app->enqueueMessage($errors[$i]->getMessage(), 'warning');
				}
				else {
					$app->enqueueMessage($errors[$i], 'warning');
				}
			}

			// Save the data in the session.
			$app->setUserState('com_djcatalog2.order.data', $data);

			// Redirect back to the quote screen.
			$this->setRedirect(JRoute::_(DJCatalogHelperRoute::getCheckoutRoute(), false));

			return false;
		}

		if (isset($validData['djcatalog2profile']) && isset($validData['djcatalog2profile']['country_id']) && isset($validData['djcatalog2profile']['vat_id'])) {
			$currentCountry = $currentVatid = null;
			if (isset($validData['djcatalog2profile']['country_id'])) {
				$currentCountry = $validData['djcatalog2profile']['country_id'];
			}
			if (isset($validData['djcatalog2profile']['vat_id'])) {
				$currentVatid = $validData['djcatalog2profile']['vat_id'];
			}

			/*if ($user_data['country_id'] != $currentCountry || $user_data['vat_id'] != $currentVatid) {
				$this->setRedirect(JRoute::_(DJCatalogHelperRoute::getCheckoutRoute(), false), JText::_('COM_DJCATALOG2_CHECHOUT_COUNTRY_TAX_CHANGED'), 'notice');
				return false;
			}*/
		}

		$tax_rules = $user_data['djcatalog2profile']['tax_rules'];

		$app->setUserState('com_djcatalog2.order.data', $validData);

		$orderData = $validData['djcatalog2profile'];
		$messageData = $validData['djcatalog2message'];
		$statementsData = isset($validData['djcatalog2statements']) ? $validData['djcatalog2statements'] : array();

		$deliveryData = isset($validData['djcatalog2delivery']) ? $validData['djcatalog2delivery'] : array();
		$orderDetailsData = isset($validData['djcatalog2orderdetails']) ? $validData['djcatalog2orderdetails'] : array();

		$order = array();

		$order['id'] 				= null;
		$order['user_id'] 			= $user->id;
		$order['token'] 			= Djcatalog2Helper::createSecureToken();

		$order['salesman_id'] = $salesman ? $juser->id : 0;

		if (($user->guest || empty($user->email)) && !empty($orderData['email'])) {
			$order['email'] 		= $orderData['email'];
		} else {
			if (!empty($orderData['email'])) {
				$order['email'] 		= $orderData['email'];
			} else {
				$order['email'] 		= $user->email;
			}
		}

		$order['order_number']	 	= null;
		$order['invoice_number'] 	= null;
		$order['created_date'] 		= $date->toSql(true);
		
		if($basket->coupon) {
			$order['coupon_id']		= $basket->coupon->id;
			$order['coupon_code']		= $basket->coupon->code;
			$order['coupon_type']		= $basket->coupon->type;
			$order['coupon_value']		= $basket->coupon->value;
		} else if ($basket->discount_value > 0.0) {
			$order['coupon_id']       = 0;
			$order['coupon_code']     = '-';
			$order['coupon_type']     = 'other';
			$order['coupon_value']    = $basket->discount_value;
		}
		
		
		// B/C compatibility - in order to remain compat for installations where user forgot to set up default currency
		$user_currency_id = $app->getUserState('com_djcatalog2.checkout.currency');
		$default_currency = Djcatalog2HelperPrice::getCurrencyDefault();
		$order_currency = '';
		
		if (!$default_currency) {
			$order_currency = strtoupper($params->get('cart_currency', ''));
			$user_currency_id  = false;
		} else {
			$order_currency = $default_currency->currency;
		}
		
		$user_currency = Djcatalog2HelperPrice::getCurrencyById($user_currency_id);
		if (!empty($user_currency)) {
			$order_currency = $user_currency->currency;
		}

		$order['currency'] 			= $order_currency;// strtoupper($params->get('cart_currency', ''));
		
		//$order['status'] 			= $user->guest ? 'N' : 'A';
		$order['status'] 			= $user->guest ? $params->get('cart_status_new_guest', 'N') : $params->get('cart_status_new_reg', 'A');

		$order['firstname'] 		= !empty($orderData['firstname']) ? $orderData['firstname'] : '';
		$order['lastname'] 			= !empty($orderData['lastname']) ? $orderData['lastname'] : '';
		$order['company'] 			= !empty($orderData['company']) ? $orderData['company'] : '';
		$order['address'] 			= !empty($orderData['address']) ? $orderData['address'] : '';
		$order['city'] 				= !empty($orderData['city']) ? $orderData['city'] : '';
		$order['postcode'] 			= !empty($orderData['postcode']) ? $orderData['postcode'] : '';

		$order['position']       = !empty($orderData['position']) ? $orderData['position'] : '';
		$order['phone']          = !empty($orderData['phone']) ? $orderData['phone'] : '';
		$order['fax']            = !empty($orderData['fax']) ? $orderData['fax'] : '';
		$order['www']            = !empty($orderData['www']) ? $orderData['www'] : '';

		$order['country_id'] 		= !empty($orderData['country_id']) ? $orderData['country_id'] : '';
		$order['state_id'] 		= !empty($orderData['state_id']) ? $orderData['state_id'] : '';

		if ((empty($orderData['country_name']) || $orderData['country_name'] == '*') && !empty($orderData['country_id'])) {
			$db->setQuery('select country_name from #__djc2_countries where id='.(int)$orderData['country_id']);
			$country = $db->loadResult();
			$order['country'] = $country ? $country : '';
		} else {
			$order['country'] = !empty($orderData['country_name']) ? $orderData['country_name'] : '';
		}

		if ((empty($orderData['state_name']) || $orderData['state_name'] == '*') && !empty($orderData['state_id'])) {
			$db->setQuery('select name from #__djc2_countries_states where id='.(int)$orderData['state_id']);
			$state = $db->loadResult();
			$order['state'] = $state ? $state : '';
		} else {
			$order['state'] = !empty($orderData['state_name']) ? $orderData['state_name'] : '';
		}

		$order['vat_id'] 			= !empty($orderData['vat_id']) ? $orderData['vat_id'] : '';

		$order['customer_note'] 	= !empty($messageData['customer_note']) ? $messageData['customer_note'] : '';

		//$gdpr_policy = $params->get('cart_gdpr_policy');
		if (!empty($statementsData['gdpr_policy']) /* && $gdpr_policy*/){
			$order['gdpr_policy'] = 1;
		}

		//$gdpr_agreement = $params->get('cart_gdpr_agreement');
		if (!empty($statementsData['gdpr_agreement']) /*&& $gdpr_agreement*/){
			$order['gdpr_agreement'] = 1;
		}
		
		$order['want_invoice'] = -1;
		if (isset($orderData['want_invoice'])) {
			$order['want_invoice'] = $orderData['want_invoice'];
		} else {
			$invoicesEnabled = (bool)$params->get('cart_invoices');
			
			if (isset($data['djcatalog2profile']['want_invoice'])) {
				// this means that in submitted data there is not "want_invoice" field,
				// but the field existed in the form
				if (isset($orderData['client_type'])) {
					$order['want_invoice'] = $orderData['client_type'] == 'W' ? 1 : 0;
				}
			} else {
				$order['want_invoice'] = $invoicesEnabled ? 1 : -1;
			}
		}

		// shipping details
		foreach($deliveryData as $k=>$v) {
			if ($k == 'delivery_to_billing') {
				$order[$k] = $v;
			} else {
				$order['delivery_'.$k] = $v;
			}
		}

		if ((empty($deliveryData['country_name']) || $deliveryData['country_name'] == '*') && !empty($deliveryData['country_id'])) {
			$db->setQuery('select country_name from #__djc2_countries where id='.(int)$deliveryData['country_id']);
			$country = $db->loadResult();
			$order['delivery_country'] = $country ? $country : '';
		} else {
			$order['delivery_country'] = !empty($deliveryData['country_name']) ? $deliveryData['country_name'] : '';
		}

		if ((empty($deliveryData['state_name']) || $deliveryData['state_name'] == '*') && !empty($deliveryData['state_id'])) {
			$db->setQuery('select name from #__djc2_countries_states where id='.(int)$deliveryData['state_id']);
			$state = $db->loadResult();
			$order['delivery_state'] = $state ? $state : '';
		} else {
			$order['delivery_state'] = !empty($deliveryData['state_name']) ? $deliveryData['state_name'] : '';
		}

		// save delivery address in addreess book
		if(!$deliveryData['delivery_to_billing'] && isset($deliveryData['save']) && $deliveryData['save'] == 1) {
			$address = $this->getModel('Address','DJCatalog2Model');
			if(empty($deliveryData['name'])) $deliveryData['name'] = $deliveryData['address'];
			$address->save($deliveryData);
		}

		// order payment & delivery
		if (!empty($orderDetailsData)) {
			
			// we need to "reset" the cart that the price rules could be re-applied the way they should
			$basket->setDelivery(0);
			$basket->setPayment(0);
			$basket->recalculate();
			$basket->saveToStorage();
			
			$basket = Djcatalog2HelperCart::getInstance(true);
			
			if (isset(Djcatalog2HelperPrice::$runOnce['afterInitMinPrice'])) {
				unset(Djcatalog2HelperPrice::$runOnce['afterInitMinPrice']);
			}
			
			if (isset($orderDetailsData['delivery_method_id'])) {

				try {
					$basket->setDelivery((int)$orderDetailsData['delivery_method_id']);
				}
				catch (Exception $e) {
					$this->setRedirect(JRoute::_(DJCatalogHelperRoute::getCheckoutRoute(), false), $e->getMessage(), 'error');
					return false;
				}
				$order['delivery_method_id'] = $orderDetailsData['delivery_method_id'];
			}
			if (isset($orderDetailsData['payment_method_id'])) {

				try {
					$basket->setPayment((int)$orderDetailsData['payment_method_id']);
				}
				catch (Exception $e) {
					$this->setRedirect(JRoute::_(DJCatalogHelperRoute::getCheckoutRoute(), false), $e->getMessage(), 'error');
					return true;
				}

				$order['payment_method_id'] = $orderDetailsData['payment_method_id'];
			}
			
			$basket->recalculate();
			$basket->saveToStorage();
			$items = $basket->getItems();
			
			if (!empty($basket->delivery)) {
				$order['delivery_method'] = $basket->delivery->name;
				$order['delivery_shipping_days'] = $basket->shipping_days;
				$order['delivery_price'] = $basket->delivery->_prices['total']['net'];
				$order['delivery_tax'] = $basket->delivery->_prices['total']['tax'];
				$order['delivery_total'] = $basket->delivery->_prices['total']['gross'];
				$order['delivery_tax_rate'] = round(Djcatalog2HelperPrice::getTaxRate($basket->delivery->tax_rule_id)/100, 4);
				$order['cash_on_delivery'] = (int)$basket->delivery->cash_on_delivery;
			} else if ($basket->productTypes['tangible'] > 0 || $basket->productTypes['hybrid'] > 0) {
				$this->setRedirect(JRoute::_(DJCatalogHelperRoute::getCheckoutRoute(), false), JText::_('COM_DJCATALOG2_DELIVERY_METHOD_NOT_SET_ERROR'), 'error');
				return false;
			}
			
			if (!empty($basket->payment)) {
				$order['payment_method'] = $basket->payment->name;
				$order['payment_price'] = $basket->payment->_prices['total']['net'];
				$order['payment_tax'] = $basket->payment->_prices['total']['tax'];
				$order['payment_total'] = $basket->payment->_prices['total']['gross'];
				$order['payment_tax_rate'] = round(Djcatalog2HelperPrice::getTaxRate($basket->payment->tax_rule_id)/100, 4);
			} else {
				$this->setRedirect(JRoute::_(DJCatalogHelperRoute::getCheckoutRoute(), false), JText::_('COM_DJCATALOG2_PAYMENT_METHOD_NOT_SET_ERROR'), 'error');
				return false;
			}
		}
		
		// moved here, after delivery/payment validation
		$totals = $basket->getTotal();
		$order['total'] 			= $totals['net'];
		$order['tax'] 				= $totals['tax'];
		$order['grand_total'] 		= $totals['gross'];

		$parents = array();
		foreach ($items as $item) {
			if ($item->parent_id > 0) {
				$parents[] = $item->parent_id;
			}
		}
		
		if (count($parents) > 0) {
			$itemsModel = JModelLegacy::getInstance('Items', 'Djcatalog2Model', array('ignore_request'=>true));
			$state      = $itemsModel->getState();
			$itemsModel->setState('list.start', 0);
			$itemsModel->setState('list.limit', 0);
			$itemsModel->setState('filter.catalogue',false);
			$itemsModel->setState('list.ordering', 'i.name');
			$itemsModel->setState('list.direction', 'asc');
			$itemsModel->setState('filter.parent', '*');
			$itemsModel->setState('filter.state', '3');

			$itemsModel->setState('filter.item_ids', $parents);

			$parentItems = $itemsModel->getItems();

			foreach ($items as $id=>$item) {
				if ($item->parent_id > 0 && isset($parentItems[$item->parent_id])) {
					$items[$id]->parent =  $parentItems[$item->parent_id];
				} else {
					$items[$id]->parent =  false;
				}
			}
		}

		$order_items = array();
		
		$language = JFactory::getLanguage();
		
		foreach($items as $item) {
			
			if ($item->product_type == 'bundle') {
				$bundle_items = $basket->getBundleItems($item);
				if (!empty($bundle_items)) {
					
					$bundle_prefix = ($language->hasKey('COM_DJCATALOG2_ORDER_BUNDLE_ITEM')) ? JText::sprintf('COM_DJCATALOG2_ORDER_BUNDLE_ITEM', $item->name) : $item->name;
					
					foreach($bundle_items as $bundle_item) {
						
						if ($comboStr = $basket->getCombinationAttributes($bundle_item['item'], 'string_values')) {
							$bundle_item['item']->name = $bundle_item['item']->name .' - '.$comboStr;
						}
						
						$record = array();
						$record['id'] = 0;
						$record['item_type'] = 'item';
						$record['item_id'] 		= $bundle_item['item']->id;
						$record['combination_id'] = $bundle_item['item']->_combination_id;
						$record['item_name'] 	= $bundle_prefix . ' - ' .$bundle_item['item']->name;
						$record['sku'] 			= $bundle_item['item']->sku;
						$record['quantity'] 	= $bundle_item['quantity'];
						$record['unit'] 		= $bundle_item['item']->unit;
						
						$record['cost'] 		= $bundle_item['item']->prices['total']['net'];
						$record['base_cost'] 	= $bundle_item['item']->prices['base']['net'];
						$record['tax'] 			= $bundle_item['item']->prices['total']['tax'];
						$record['total'] 		= $bundle_item['item']->prices['total']['gross'];
						$record['tax_rate'] 	= (isset($tax_rules[$bundle_item['item']->tax_rule_id]) && $bundle_item['item']->tax_rule_id > 0 ) ? round(($tax_rules[$bundle_item['item']->tax_rule_id]/100), 4) : 0;
						
						$record['additional_info'] = null;// $basket->getItemAttributes($item, true, 'json');
						$record['features_info'] = null;//$basket->getItemFeatures($item, true, 'json');
						$record['combination_info'] = null;// $basket->getCombinationAttributes($item, 'json');
						
						$order_items[] = $record;
						
						$customs = $basket->getCustomisations($item->_sid);
						if (count($customs)) {
							$customInfos = $customs;//$basket->getCustomInfos($customs);
							foreach($customInfos as $customItem) {
								$record2 = array();
								$record2['id'] = 0;
								$record2['item_type'] 	= 'customisation';
								$record2['item_id'] 	= 0;
								$record2['combination_id'] 	= 0;
								$record2['item_name'] 	= $customItem->name.' ('.$record['item_name'].')';
								$record2['sku']			= '';
								$record2['quantity'] 	= $customItem->_quantity;
								$record2['cost'] 		= $customItem->_prices['total']['net'];
								$record2['base_cost'] 	= $customItem->_prices['base']['net'];
								$record2['tax'] 			= $customItem->_prices['total']['tax'];
								$record2['total'] 		= $customItem->_prices['total']['gross'];
								$record2['tax_rate'] 	= (isset($tax_rules[$customItem->tax_rule_id]) && $customItem->tax_rule_id > 0 ) ? round(($tax_rules[$customItem->tax_rule_id]/100), 4) : 0;
								
								$record2['additional_info'] = $basket->getCustomisationData($customItem, 'json');
								$record2['combination_info'] = null;
								$record2['features_info'] = null;
								
								$order_items[] = $record2;
							}
						}
					}
					
					continue;
				}
			}
			
			$record = array();
			$record['id'] = 0;
			$record['item_type'] = 'item';
			$record['item_id'] 		= $item->id;
			$record['combination_id'] 	= $item->_combination_id;

			if (!empty($item->parent)) {
				$item->name = $item->parent->name . ' ['.$item->name.']';
			}
			if ($comboStr = $basket->getCombinationAttributes($item, 'string_values')) {
				$item->name = $item->name .' - '.$comboStr;
			}

			$record['item_name'] 	= $item->name;
			$record['sku'] 			= ($item->sku) ? $item->sku : ( ($item->_combination_id > 0) ? 'ID-'.$item->id.'-CMB-'.$item->_combination_id : 'ID-'.$item->id); //$item->sku ? $item->sku : $item->id;
			$record['quantity'] 	= $item->_quantity;
			$record['unit'] 		= $item->_unit;
			$record['cost'] 		= $item->_prices['total']['net'];
			$record['base_cost'] 	= $item->_prices['base']['net'];
			$record['tax'] 			= $item->_prices['total']['tax'];
			$record['total'] 		= $item->_prices['total']['gross'];
			$record['tax_rate'] 	= (isset($tax_rules[$item->tax_rule_id]) && $item->tax_rule_id > 0 ) ? round(($tax_rules[$item->tax_rule_id]/100), 4) : 0;

			$record['additional_info'] = $basket->getItemAttributes($item, true, 'json');
			$record['features_info'] = $basket->getItemFeatures($item, true, 'json');
			$record['combination_info'] = $basket->getCombinationAttributes($item, 'json');

			$order_items[] = $record;

			$customs = $basket->getCustomisations($item->_sid);
			if (count($customs)) {
				$customInfos = $customs;//$basket->getCustomInfos($customs);
				foreach($customInfos as $customItem) {
					$record2 = array();
					$record2['id'] = 0;
					$record2['item_type'] 	= 'customisation';
					$record2['item_id'] 	= 0;
					$record2['combination_id'] 	= 0;
					$record2['item_name'] 	= $customItem->name.' ('.$record['item_name'].')';
					$record2['sku']			= '';
					$record2['quantity'] 	= $customItem->_quantity;
					$record2['cost'] 		= $customItem->_prices['total']['net'];
					$record2['base_cost'] 	= $customItem->_prices['base']['net'];
					$record2['tax'] 			= $customItem->_prices['total']['tax'];
					$record2['total'] 		= $customItem->_prices['total']['gross'];
					$record2['tax_rate'] 	= (isset($tax_rules[$customItem->tax_rule_id]) && $customItem->tax_rule_id > 0 ) ? round(($tax_rules[$customItem->tax_rule_id]/100), 4) : 0;

					$record2['additional_info'] = $basket->getCustomisationData($customItem, 'json');
					$record2['combination_info'] = null;
					$record2['features_info'] = null;

					$order_items[] = $record2;
				}
			}
		}

		$customs = $basket->getCustomisations(0);
		if (count($customs)) {
			$customInfos = $customs;//$basket->getCustomInfos($customs);
			foreach($customInfos as $customItem) {
				$record2 = array();
				$record2['id'] = 0;
				$record2['item_type'] 	= 'customisation';
				$record2['item_id'] 	= 0;
				$record2['combination_id'] 	= 0;
				$record2['item_name'] 	= $customItem->name;
				$record2['sku']			= '';
				$record2['quantity'] 	= $customItem->_quantity;
				$record2['cost'] 		= $customItem->_prices['total']['net'];
				$record2['base_cost'] 	= $customItem->_prices['base']['net'];
				$record2['tax'] 			= $customItem->_prices['total']['tax'];
				$record2['total'] 		= $customItem->_prices['total']['gross'];
				$record2['tax_rate'] 	= (isset($tax_rules[$customItem->tax_rule_id]) && $customItem->tax_rule_id > 0 ) ? round(($tax_rules[$customItem->tax_rule_id]/100), 4) : 0;

				$record2['additional_info'] = $basket->getCustomisationData($customItem, 'json');
				$record2['combination_info'] = null;
				$record2['features_info'] = null;

				$order_items[] = $record2;
			}
		}
		
		$order['additional_user_data'] = Djcatalog2HelperUser::prepareExtraFields($validData, 'checkout', true);
		
		$order['order_items'] = array();
		
		//$dispatcher = JDispatcher::getInstance();
		Joomla\CMS\Factory::getApplication()->triggerEvent('onCartBeforeSavingItems', array('djcatalog2.cart.confirm', &$order_items));

		foreach ($order_items as $pos => $rec) {
			foreach ($rec as $key => $value) {
				if (!isset($order['order_items'][$key])) {
					$order['order_items'][$key] = array();
				}

				$order['order_items'][$key][] = $value;
			}
		}
		
		if ($model->save($order) == false) {
			$app->setUserState('com_djcatalog2.order.data', $data);
			$msg = $model->getError();
			//$app->redirect(JRoute::_(DJCatalogHelperRoute::getCheckoutRoute(), false), JText::_('COM_DJCATALOG2_ORDER_STORE_ERRROR').' '.$msg);
			$this->setRedirect(JRoute::_(DJCatalogHelperRoute::getCheckoutRoute(), false), JText::_('COM_DJCATALOG2_ORDER_STORE_ERRROR').' '.$msg);
			return false;
		}

		
		$basket->clear();
		$app->setUserState('com_djcatalog2.order.data', null);
		$app->setUserState('com_users.edit.profile.redirect', null);

		$order['id'] = $model->getState('order.id');
		$order['order_number'] = $model->getState('order.number');

		$order['items'] = $order_items;
		
		$attachments = array();
		if ($params->get('cart_proformas', 1) && $params->get('cart_proformas_email', 0)) {
			require_once JPATH_ROOT.'/components/com_djcatalog2/helpers/invoice.php';
			$pdf = DJCatalog2HelperInvoice::getPdfInvoice($order['id'], 'proforma', false);
			if ($pdf) {
				$attachments[] = $pdf;
			}
		} else if ($params->get('cart_order_pdf_email')) {
			require_once JPATH_ROOT.'/components/com_djcatalog2/helpers/invoice.php';
			$pdf = DJCatalog2HelperInvoice::getPdfInvoice($order['id'], 'order', false);
			if ($pdf) {
				$attachments[] = $pdf;
			}
		}
		
		/*if ($this->_sendEmail($order, 'order', $attachments) == false) {
			$app->enqueueMessage(JText::_('COM_DJCATLAOG2_ORDER_NOTIFICATION_ERROR'), 'error');
		}*/
		
		if ($this->orderNotification($order, $attachments) == false) {
			$app->enqueueMessage(JText::_('COM_DJCATLAOG2_ORDER_NOTIFICATION_ERROR'), 'error');
		}
		
		//$app->redirect(JRoute::_(DJCatalogHelperRoute::getOrderRoute($order['id']), false), JText::_('COM_DJCATALOG2_ORDER_SENT'));
		$this->setRedirect(JRoute::_(DJCatalogHelperRoute::getOrderRoute($order['id']).'&finished=1&token='.$order['token'], false), JText::_('COM_DJCATALOG2_ORDER_SENT'));
		return true;

	}

	public function query_confirm() {
		JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN'));

		if ($this->allowQuery() == false) {
			return false;
		}

		$app = JFactory::getApplication();
		$date = JFactory::getDate();
		$model = $this->getModel('Query');
		$db = JFactory::getDbo();

		$params = Djcatalog2Helper::getParams();
		$language = JFactory::getLanguage();

		$juser = JFactory::getUser();
		$salesman = $juser->authorise('djcatalog2.salesman', 'com_djcatalog2');
		$user_id = null;
		if ($salesman && !empty($post_data['djcatalog2profile'])) {
			$user_id = (int)$post_data['djcatalog2profile']['user_id'];
		}

		$basket = Djcatalog2HelperCart::getInstance();

		$items = $basket->getItems();

		$user = Djcatalog2HelperUser::getUserProfile($user_id);
		$user_data = (isset($user->djcatalog2profile)) ? array('djcatalog2profile' => Joomla\Utilities\ArrayHelper::fromObject($user->djcatalog2profile, true)) : array();
		
		$post_data  = $app->input->post->get('jform', array(), 'array');

		$form = $model->getForm(array(), false);

		if (!$form) {
			$app->enqueueMessage($model->getError(), 'error');
			return false;
		}

		$form_data = array();
		$fields = $form->getFieldset('basicprofile');
		foreach ($fields as $field) {
			if (isset($user_data[$field->fieldname])) {
				$form_data[$field->fieldname] = $user_data[$field->fieldname];
			}

			if (isset($post_data['djcatalog2profile'][$field->fieldname])) {
				$form_data[$field->fieldname] = $post_data['djcatalog2profile'][$field->fieldname];
			}

			if (!isset($form_data[$field->fieldname])) {
				$form_data[$field->fieldname] = null;
			}
		}

		$data = $post_data;
		$data['djcatalog2profile'] = $form_data;


		if (empty($data) || empty($data['djcatalog2profile'])) {
			$data['djcatalog2profile'] = $user_data;
		}

		Djcatalog2HelperUser::prepareFormValidation($form, $data);
		// Test whether the data is valid.
		$validData = $model->validate($form, $data);

		// Check for validation errors.
		if ($validData === false)
		{
			// Get the validation messages.
			$errors = $model->getErrors();

			// Push up to three validation messages out to the user.
			for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++) {
				if ($errors[$i] instanceof Exception) {
					$app->enqueueMessage($errors[$i]->getMessage(), 'warning');
				}
				else {
					$app->enqueueMessage($errors[$i], 'warning');
				}
			}

			// Save the data in the session.
			$app->setUserState('com_djcatalog2.query.data', $data);

			// Redirect back to the quote screen.
			$this->setRedirect(JRoute::_(DJCatalogHelperRoute::getQueryRoute(), false));

			return false;
		}

		$app->setUserState('com_djcatalog2.query.data', $validData);

		$quoteData = $validData['djcatalog2profile'];
		$messageData = $validData['djcatalog2message'];
		$statementsData = $validData['djcatalog2statements'];

		$quote = array();

		$quote['id'] 				= null;
		$quote['user_id'] 			= $user->id;

		if (($user->guest || empty($user->email)) && !empty($quoteData['email'])) {
			$quote['email'] 		= $quoteData['email'];
		} else {
			if (!empty($quoteData['email'])) {
				$quote['email'] 		= $quoteData['email'];
			} else {
				$quote['email'] 		= $user->email;
			}
		}

		$quote['token'] 			= Djcatalog2Helper::createSecureToken();

		$quote['salesman_id'] = $salesman ? $juser->id : 0;

		$quote['created_date'] 		= $date->toSql(true);

		$quote['firstname'] 		= !empty($quoteData['firstname']) ? $quoteData['firstname'] : '';
		$quote['lastname'] 			= !empty($quoteData['lastname']) ? $quoteData['lastname'] : '';
		$quote['company'] 			= !empty($quoteData['company']) ? $quoteData['company'] : '';
		$quote['address'] 			= !empty($quoteData['address']) ? $quoteData['address'] : '';
		$quote['city'] 				= !empty($quoteData['city']) ? $quoteData['city'] : '';
		$quote['postcode'] 			= !empty($quoteData['postcode']) ? $quoteData['postcode'] : '';

		$quote['position']       = !empty($quoteData['position']) ? $quoteData['position'] : '';
		$quote['phone']          = !empty($quoteData['phone']) ? $quoteData['phone'] : '';
		$quote['fax']            = !empty($quoteData['fax']) ? $quoteData['fax'] : '';
		$quote['www']            = !empty($quoteData['www']) ? $quoteData['www'] : '';

		$quote['country_id'] 		= !empty($quoteData['country_id']) ? $quoteData['country_id'] : '';
		$quote['state_id'] 			= !empty($quoteData['state_id']) ? $quoteData['state_id'] : '';

		if ((empty($quoteData['country_name']) || $quoteData['country_name'] == '*') && !empty($quoteData['country_id'])) {
			$db->setQuery('select country_name from #__djc2_countries where id='.(int)$quoteData['country_id']);
			$country = $db->loadResult();
			$quote['country'] = $country ? $country : '';
		} else {
			$quote['country'] = @$quoteData['country_name'];
		}

		if ((empty($quoteData['state_name']) || $quoteData['state_name'] == '*') && !empty($quoteData['state_id'])) {
			$db->setQuery('select name from #__djc2_countries_states where id='.(int)$quoteData['state_id']);
			$state = $db->loadResult();
			$quote['state'] = $state ? $state : '';
		} else {
			$quote['state'] = @$quoteData['state_name'];
		}

		$quote['vat_id'] 			= !empty($quoteData['vat_id']) ? $quoteData['vat_id'] : '';

		$quote['customer_note'] 	= !empty($messageData['customer_note']) ? $messageData['customer_note'] : '';

		//$gdpr_policy = $params->get('cart_gdpr_policy');
		if (!empty($statementsData['gdpr_policy'])/* && $gdpr_policy*/){
			$quote['gdpr_policy'] = 1;
		}

		//$gdpr_agreement = $params->get('cart_gdpr_agreement');
		if (!empty($statementsData['gdpr_agreement'])/* && $gdpr_agreement*/){
			$quote['gdpr_agreement'] = 1;
		}

		$parents = array();
		foreach ($items as $item) {
			if ($item->parent_id > 0) {
				$parents[] = $item->parent_id;
			}
		}

		if (count($parents) > 0) {
			$itemsModel = JModelLegacy::getInstance('Items', 'Djcatalog2Model', array('ignore_request'=>true));
			$state      = $itemsModel->getState();
			$itemsModel->setState('list.start', 0);
			$itemsModel->setState('list.limit', 0);
			$itemsModel->setState('filter.catalogue',false);
			$itemsModel->setState('list.ordering', 'i.name');
			$itemsModel->setState('list.direction', 'asc');
			$itemsModel->setState('filter.parent', '*');
			$itemsModel->setState('filter.state', '3');

			$itemsModel->setState('filter.item_ids', $parents);

			$parentItems = $itemsModel->getItems();

			foreach ($items as $id=>$item) {
				if ($item->parent_id > 0 && isset($parentItems[$item->parent_id])) {
					$items[$id]->parent =  $parentItems[$item->parent_id];
				} else {
					$items[$id]->parent =  false;
				}
			}
		}

		$quote_items = array();
		foreach($items as $item) {
			$record = array();
			$record['id'] = 0;
			$record['item_type'] 	= 'item';
			$record['item_id'] 		= $item->id;
			$record['combination_id'] 	= $item->_combination_id;
			$record['sku'] 			= ($item->sku) ? $item->sku : ( ($item->_combination_id > 0) ? 'ID-'.$item->id.'-CMB-'.$item->_combination_id : 'ID-'.$item->id);

			if (!empty($item->parent)) {
				$item->name = $item->parent->name . ' ['.$item->name.']';
			}
			if ($comboStr = $basket->getCombinationAttributes($item, 'string_values')) {
				$item->name = $item->name .' - '.$comboStr;
			}

			$record['price'] 		= $item->final_price;
			$record['total'] 		= $record['price'] * $item->_quantity;

			$record['item_name'] 	= $item->name;
			$record['quantity'] 	= $item->_quantity;
			$record['unit'] 		= $item->_unit;

			$record['additional_info'] = $basket->getItemAttributes($item, true, 'json');
			$record['features_info'] = $basket->getItemFeatures($item, true, 'json');
			$record['combination_info'] = $basket->getCombinationAttributes($item, 'json');

			$quote_items[] = $record;

			$customs = $basket->getCustomisations($item->_sid);
			if (count($customs)) {
				$customInfos = $customs;//$basket->getCustomInfos($customs);
				foreach($customInfos as $customItem) {
					$record2 = array();
					$record2['id'] = 0;
					$record2['item_type'] 	= 'customisation';
					$record2['item_id'] 	= 0;
					$record2['combination_id'] 	= 0;
					$record2['item_name'] 	= $customItem->name.' ('.$record['item_name'].')';
					$record2['sku']			= '';
					$record2['quantity'] 	= $customItem->_quantity;
					$record2['price'] 		= $customItem->price;
					$record2['total'] 		= $record2['price'] * $customItem->_quantity;

					$record2['additional_info'] = $basket->getCustomisationData($customItem, 'json');
					$record2['combination_info'] = null;
					$record2['features_info'] = null;

					$quote_items[] = $record2;
				}
			}
		}

		$customs = $basket->getCustomisations(0);
		if (count($customs)) {
			$customInfos = $customs;//$basket->getCustomInfos($customs);
			foreach($customInfos as $customItem) {
				$record2 = array();
				$record2['id'] = 0;
				$record2['item_type'] 	= 'customisation';
				$record2['item_id'] 	= 0;
				$record2['combination_id'] 	= 0;
				$record2['item_name'] 	= $customItem->name;
				$record2['sku']			= '';
				$record2['quantity'] 	= $customItem->_quantity;
				$record2['price'] 		= $customItem->price;
				$record2['total'] 		= $record2['price'] * $customItem->_quantity;

				$record2['additional_info'] = $basket->getCustomisationData($customItem, 'json');
				$record2['combination_info'] = null;
				$record2['features_info'] = null;

				$quote_items[] = $record2;
			}
		}
		
		$quote['additional_user_data'] = Djcatalog2HelperUser::prepareExtraFields($validData, 'query', true);

		$quote['quote_items'] = array();

		foreach ($quote_items as $pos => $rec) {
			foreach ($rec as $key => $value) {
				if (!isset($quote['quote_items'][$key])) {
					$quote['quote_items'][$key] = array();
				}

				$quote['quote_items'][$key][] = $value;
			}
		}

		if ($model->save($quote) == false) {
			$msg = $model->getError();
			$this->setRedirect(JRoute::_(DJCatalogHelperRoute::getQueryRoute(), false), JText::_('COM_DJCATALOG2_QUOTE_STORE_ERRROR').' '.$msg);
			return false;
		}

		$basket->clear();

		$quote['id'] = $model->getState('query.id');

		$quote['items'] = $quote_items;
		
		$attachments = array();
		if ($params->get('cart_order_pdf_email')) {
			require_once JPATH_ROOT.'/components/com_djcatalog2/helpers/invoice.php';
			$pdf = DJCatalog2HelperInvoice::getPdfQuery($quote['id'], 'quote', false);
			if ($pdf) {
				$attachments[] = $pdf;
			}
		}

		/*if ($this->_sendEmail($quote, 'query', $attachments) == false) {
			$app->enqueueMessage(JText::_('COM_DJCATLAOG2_QUOTE_NOTIFICATION_ERROR'), 'error');
		}*/
		
		if ($this->queryNotification($quote, $attachments) == false) {
			$app->enqueueMessage(JText::_('COM_DJCATLAOG2_ORDER_NOTIFICATION_ERROR'), 'error');
		}
		

		$this->setRedirect(JRoute::_(DJCatalogHelperRoute::getQuestionRoute($quote['id']).'&token='.$quote['token'], false), JText::_('COM_DJCATALOG2_QUOTE_SENT'));

		return true;

	}

	protected function allowCheckout() {
		$app = JFactory::getApplication();

		$juser = JFactory::getUser();
		$salesman = $juser->authorise('djcatalog2.salesman', 'com_djcatalog2') || $juser->authorise('core.admin', 'com_djcatalog2');

		$user_profile = Djcatalog2Helper::getUserProfile($app->getUserState('com_djcatalog2.checkout.user_id', null));
		$user = Djcatalog2Helper::getUser($app->getUserState('com_djcatalog2.checkout.user_id', null));

		$params     = JComponentHelper::getParams('com_djcatalog2');

		if ($params->get('cart_enabled', '1') != '1') {
			throw new Exception(JText::_('JERROR_ALERTNOAUTHOR'), 403);
		}

		// TODO: allow guest orders - add new paramater
		$auth = ($params->get('cart_registered', '1') == '1' &&  $user->guest) ? false : true;

		if (!$auth) {
			//$return_url = base64_encode(DJCatalogHelperRoute::getCheckoutRoute());
			//$app->redirect(JRoute::_('index.php?option=com_users&view=login&return='.$return_url, false), JText::_('COM_DJCATALOG2_PLEASE_LOGIN'));
			$this->setRedirect(JRoute::_(DJCatalog2HelperRoute::getCartRoute().'&layout=login' , false));
			return false;
		}

		$basket = Djcatalog2HelperCart::getInstance(true);

		$basket->recalculate();

		if (empty($basket) || !$basket->getItems()) {
			$this->setRedirect(JUri::base(), JText::_('COM_DJCATALOG2_CART_IS_EMPTY'));
			return false;
		}

		if (!$salesman) {
			$invalidCart = false;
			$nullPrices = false;
			foreach ($basket->items as $key => $item) {
				$qty = $basket->quantities[$item->_sid];
				if ($item->_prices['base']['display'] == 0.0) {
					$nullPrices = true;
				}
				else {
					if (!$item->onstock || $qty == 0) {
						$app->enqueueMessage(JText::sprintf('COM_DJCATALOG2_CHECKOUT_PRODUCT_OUT_OF_STOCK', $item->name));
						$basket->removeItem($item->_sid, true);
						$invalidCart = true;
					} else if ($item->product_type == 'tangible' || $item->product_type == 'hybrid') {
						if ($qty > $item->stock && $item->onstock < 2) {
							$basket->quantities[$item->_sid] = $item->stock;
							$basket->updateQuantity($key, $item->stock);
							$app->enqueueMessage(JText::sprintf('COM_DJCATALOG2_CHECKOUT_FORCE_QTY_UPDATE', $item->name));
							$invalidCart = true;
						}
					} else if ($item->product_type == 'bundle') {
						if ($item->onstock < 2) {
							$bundleStock = $basket->getBundleStock($item);
							
							if ($qty > $bundleStock) {
								$basket->quantities[$item->_sid] = $bundleStock;
								$basket->updateQuantity($key, $bundleStock);
								$app->enqueueMessage(JText::sprintf('COM_DJCATALOG2_CHECKOUT_FORCE_QTY_UPDATE', $item->name));
								$invalidCart = true;
							}
						}
					}
				}
			}

			foreach($basket->customisations as $sid => $customisations) {
				if (is_array($customisations)) {
					foreach($customisations as $custom) {

						$quantity = $custom->_quantity;

						if ($custom->type == 'c') {
							$quantity = 0;
							foreach($basket->quantities as $qty) {
								$quantity += $qty;
							}
						}

						if ($quantity < $custom->min_quantity) {
							$customInfo = $custom->name.' - '.JText::sprintf('COM_DJCATALOG2_CUSTOMISATION_MIN_NOTE', $custom->min_quantity);
							$app->enqueueMessage($customInfo);
							$invalidCart = true;
						} else if ($custom->max_quantity > 0 && $quantity > $custom->max_quantity) {
							$customInfo = $custom->name.' - '.JText::sprintf('COM_DJCATALOG2_CUSTOMISATION_MAX_NOTE', $custom->max_quantity);
							$app->enqueueMessage($customInfo);
							$invalidCart = true;
						}
					}
				}

			}

			$total = $basket->getTotal();

			if ($total['net'] == 0.0000) {
				$app->enqueueMessage(JText::_('COM_DJCATALOG2_CHECKOUT_ZERO_TOTAL_BASKET'));
			} else if ($nullPrices) {
				$app->enqueueMessage(JText::sprintf('COM_DJCATALOG2_CHECKOUT_EMPTY_PRICES', JRoute::_('index.php?option=com_djcatalog2&task=cart.clearfree')));
			}

			if ($invalidCart) {
				$basket->recalculate();
				$basket->saveToStorage();
			}

			if ($nullPrices || $invalidCart) {
				$this->setRedirect(JRoute::_(DJCatalogHelperRoute::getCartRoute(), false));
				return true;
			}
		}

		/*foreach ($basket->items as $item) {
		 if ($item->_prices['base']['display'] == 0.0 || !$item->onstock || floatval($item->stock) == 0.0) {
		 $app->redirect(JRoute::_(DJCatalogHelperRoute::getCartRoute(), false), JText::sprintf('COM_DJCATALOG2_CHECKOUT_EMPTY_PRICES', JRoute::_('index.php?option=com_djcatalog2&task=cart.clearfree')));
		 return true;
		 }
		 }*/

		return true;
	}

	protected function allowQuery() {
		$app = JFactory::getApplication();

		$user_profile = Djcatalog2Helper::getUserProfile();
		$user = Djcatalog2Helper::getUser();

		$params 	= JComponentHelper::getParams('com_djcatalog2');

		if ($params->get('cart_query_enabled', '1') != '1') {
			throw new Exception(JText::_('JERROR_ALERTNOAUTHOR'), 403);
		}

		$auth = ($params->get('cart_query_registered', '1') == '1' && $user->guest) ? false : true;

		if (!$auth) {
			$return_url = base64_encode(DJCatalogHelperRoute::getQueryRoute());
			$app->enqueueMessage(JText::_('COM_DJCATALOG2_PLEASE_LOGIN'));
			$app->redirect(JRoute::_('index.php?option=com_users&view=login&return='.$return_url, false));
			return false;
		}

		$basket = Djcatalog2HelperCart::getInstance(true);

		$basket->recalculate();

		if (empty($basket) || !$basket->getItems()) {
			$this->setRedirect(JUri::base(), JText::_('COM_DJCATALOG2_CART_IS_EMPTY'));
			return false;
		}

		return true;
	}

	private function _sendEmail($data, $type, $attachments = array())
	{
		$app		= JFactory::getApplication();
		$params 	= JComponentHelper::getParams('com_djcatalog2');
		$notifyOwners = (bool)($params->get('cart_query_notifyowners', 0) == '1');

		$user = JFactory::getUser();

		$mailfrom	= $app->getCfg('mailfrom');
		$fromname	= $app->getCfg('fromname');
		$sitename	= $app->getCfg('sitename');

		$vendors = Djcatalog2Helper::getVendors($user->id);

		$contact_list = $params->get('contact_list', false);
		$recipient_list = array();
		if ($contact_list !== false) {
			$recipient_list = explode(PHP_EOL, $params->get('contact_list', ''));
		}

		$list_is_empty = true;
		foreach ($recipient_list as $r) {
			if (strpos($r, '@') !== false) {
				$list_is_empty = false;
				break;
			}
		}

		if ($list_is_empty) {
			$recipient_list[] = $mailfrom;
		}

		if ($user->authorise('djcatalog2.salesman', 'com_djcatalog2')) {
			$recipient_list[] = $user->email;
		}

		if (count($vendors) > 0) {
			foreach($vendors as $vendor) {
				$recipient_list[] = $vendor->email;
			}
		}

		$recipient_list = array_unique($recipient_list);

		$subject = null;
		$admin_body = null;
		$client_body = null;

		switch($type) {
			case 'order' :
				$data['onEmailAfterPaymentDisplay'] = null;
				$data['onEmailAfterDeliveryDisplay'] = null;
				
				$model = JModelLegacy::getInstance('Order', 'DJCatalog2Model', array('ignore_request' => true));
				//$dispatcher = JDispatcher::getInstance();
				if (!empty($data['payment_method_id'])) {
					$paymentMethod = $model->getPaymentMethod($data['payment_method_id']);
					if ($paymentMethod) {
						$onEmailAfterPaymentDisplay = Joomla\CMS\Factory::getApplication()->triggerEvent('onEmailAfterPaymentDisplay', array('com_djcatalog2.cart.confirm', &$data, $paymentMethod));
						foreach ($onEmailAfterPaymentDisplay as $pluginResponse) {
							if (empty($pluginResponse)) continue;
							$data['onEmailAfterPaymentDisplay'] .= $pluginResponse . PHP_EOL;
						}
					}
				}
				
				if (!empty($data['delivery_method_id'])) {
					$deliveryMethod = $model->getDeliveryMethod($data['delivery_method_id']);
					if ($deliveryMethod) {
						$onEmailAfterDeliveryDisplay = Joomla\CMS\Factory::getApplication()->triggerEvent('onEmailAfterDeliveryDisplay', array('com_djcatalog2.cart.confirm', &$data, $deliveryMethod));
						foreach ($onEmailAfterDeliveryDisplay as $pluginResponse) {
							if (empty($pluginResponse)) continue;
							$data['onEmailAfterDeliveryDisplay'] .= $pluginResponse . PHP_EOL;
						}
					}
				}
				
				$subject = JText::sprintf('COM_DJCATALOG2_EMAIL_NEW_ORDER_SUBJECT', $data['order_number'], $sitename);
				$admin_body = DJCatalog2HtmlHelper::getEmailTemplate($data, 'admin.order', $attachments);
				$client_body = DJCatalog2HtmlHelper::getEmailTemplate($data, 'order', $attachments);
				break;
			case 'query' :
				$subject = JText::sprintf('COM_DJCATALOG2_EMAIL_NEW_QUOTE_SUBJECT', $sitename);
				$admin_body = DJCatalog2HtmlHelper::getEmailTemplate($data, 'admin.quote', $attachments);
				$client_body = DJCatalog2HtmlHelper::getEmailTemplate($data, 'quote', $attachments);
				break;
		}

		if (!$admin_body) {
			return false;
		}

		// Send admin's email first
		$mail = JFactory::getMailer();

		foreach ($recipient_list as $k=> $recipient) {
			$mail = JFactory::getMailer();
			$mail->addRecipient(trim((string)$recipient));
			$mail->setSender(array($mailfrom, $fromname));
			$mail->addReplyTo($data['email'], $data['firstname'].' '.$data['lastname']);
			$mail->setSubject($subject . ' - '.$data['firstname'].' '.$data['lastname']);
			$mail->setBody($admin_body);
			$mail->isHtml(true);
			
			if (is_array($attachments) && count($attachments)) {
				foreach($attachments as $file) {
					$name = basename($file);
					$mail->addAttachment($file, $name);
				}
			}
			$admin_sent = $mail->Send() ? true : $admin_sent;
		}

		// Send an email to customer
		$mail = JFactory::getMailer();

		//$mail->addRecipient($mailfrom);
		$mail->addRecipient($data['email']);

		$mail->setSender(array($mailfrom, $fromname));
		$mail->setSubject($subject);
		$mail->setBody($client_body);
		$mail->isHtml(true);
		
		if (is_array($attachments) && count($attachments)) {
			foreach($attachments as $file) {
				$name = basename($file);
				$mail->addAttachment($file, $name);
			}
		}
		
		$mail->Send();

		if ($notifyOwners && $type == 'query') {
			$db = JFactory::getDbo();
			$itemIds = array();
			foreach($data['items'] as $item) {
				$itemIds[] = $item['item_id'];
			}

			$query = $db->getQuery(true);
			$query->select('u.email, i.email as alt_email, u.id, u.name, i.id as item_id');
			$query->from('#__djc2_items AS i');
			$query->join('LEFT', '#__users AS u ON i.created_by = u.id');
			$query->where('i.id IN ('.implode(',', $itemIds).')');
			$db->setQuery($query);

			$owners = $db->loadObjectList('item_id');
			if (count($owners) > 0) {
				$allItems = $data['items'];
				$ownerItems = array();
				foreach($owners as $item_id => $owner) {
					if (!array_key_exists($owner->id, $ownerItems)) {
						$ownerItems[$owner->id] = array('owner'=>$owner, 'items'=>array());
					}
					foreach($allItems as $item) {
						if ($item['item_id'] == $item_id) {
							$ownerItems[$owner->id]['items'][] = $item;
						}
					}
				}
				
				$owner_attachments = array();

				foreach ($ownerItems as $ownerData) {
					if (empty($ownerData['items'])) {
						continue;
					}

					$owner_email = $ownerData['owner']->alt_email ? $ownerData['owner']->alt_email : $ownerData['owner']->email;
					if (trim((string)$owner_email) == '') {
						continue;
					}

					$data['items'] = $ownerData['items'];
					$data['isOwner'] = true;

					$ownerBody = DJCatalog2HtmlHelper::getEmailTemplate($data, 'admin.quote', $owner_attachments);

					$mail = JFactory::getMailer();
					$mail->setSender(array($mailfrom, $fromname));
					$mail->addRecipient(trim((string)$owner_email));
					$mail->addReplyTo($data['email'], $data['firstname'].' '.$data['lastname']);
					$mail->setSubject($subject . ' - '.$data['firstname'].' '.$data['lastname']);
					$mail->setBody($ownerBody);
					$mail->isHtml(true);
					
					if (is_array($owner_attachments) && count($owner_attachments)) {
						foreach($owner_attachments as $file) {
							$name = basename($file);
							$mail->addAttachment($file, $name);
						}
					}
					
					$mail->Send();
				}
			}

		}
		return $admin_sent;
	}
	
	public function orderNotification($data, $attachments = array()) {
		require_once(JPATH_ROOT.'/administrator/components/com_djcatalog2/helpers/messenger.php');
		
		$app		= JFactory::getApplication();
		$params 	= JComponentHelper::getParams('com_djcatalog2');
		$user = JFactory::getUser();
		
		// Prepate the data for notifications
		$data['order_number'] = str_pad($data['order_number'], 6, '0', STR_PAD_LEFT);
		
		$data['onEmailAfterPaymentDisplay'] = null;
		$data['onEmailAfterDeliveryDisplay'] = null;
		
		$model = JModelLegacy::getInstance('Order', 'DJCatalog2Model', array('ignore_request' => true));
		//$dispatcher = JDispatcher::getInstance();
		if (!empty($data['payment_method_id'])) {
			$paymentMethod = $model->getPaymentMethod($data['payment_method_id']);
			if ($paymentMethod) {
				$onEmailAfterPaymentDisplay = Joomla\CMS\Factory::getApplication()->triggerEvent('onEmailAfterPaymentDisplay', array('com_djcatalog2.cart.confirm', &$data, $paymentMethod));
				foreach ($onEmailAfterPaymentDisplay as $pluginResponse) {
					if (empty($pluginResponse)) continue;
					$data['onEmailAfterPaymentDisplay'] .= $pluginResponse . PHP_EOL;
				}
			}
		}
		
		if (!empty($data['delivery_method_id'])) {
			$deliveryMethod = $model->getDeliveryMethod($data['delivery_method_id']);
			if ($deliveryMethod) {
				$onEmailAfterDeliveryDisplay = Joomla\CMS\Factory::getApplication()->triggerEvent('onEmailAfterDeliveryDisplay', array('com_djcatalog2.cart.confirm', &$data, $deliveryMethod));
				foreach ($onEmailAfterDeliveryDisplay as $pluginResponse) {
					if (empty($pluginResponse)) continue;
					$data['onEmailAfterDeliveryDisplay'] .= $pluginResponse . PHP_EOL;
				}
			}
		}
		
		$mailfrom	= $app->getCfg('mailfrom');
		//$fromname	= $app->getCfg('fromname');
		//$sitename	= $app->getCfg('sitename');
		
		// Send notifications to admins
		$vendors = Djcatalog2Helper::getVendors($user->id);
		//echo '<pre>' . print_r($vendors, true) . '</pre>'; die();
		$contact_list = $params->get('contact_list', false);
		$recipient_list = array();
		if ($contact_list !== false) {
			$recipient_list = explode(PHP_EOL, $params->get('contact_list', ''));
		}
		
		$list_is_empty = true;
		foreach ($recipient_list as $r) {
			if (strpos($r, '@') !== false) {
				$list_is_empty = false;
				break;
			}
		}
		
		if ($list_is_empty) {
			$recipient_list[] = $mailfrom;
		}
		if ($user->authorise('djcatalog2.salesman', 'com_djcatalog2')) {
			$recipient_list[] = $user->email;
		}
		
		$vendorData = [];
		if (count($vendors) > 0) {
			foreach($vendors as $vendor) {
				$recipient_list[] = $vendor->email;
				$vendorData[] = trim((string)$vendor->name) . ' ('.$vendor->email.')';
			}
		}
		
		$recipient_list = array_unique($recipient_list);
		
		$customerName = $data['firstname'].' '.$data['lastname'];
		if (!empty($data['company'])) {
			$customerName = $data['company'];
		}
		
		$adminMailopts = [
			'recipient_name' => $customerName,
			'order_number' => $data['order_number'],
			'order_customer_data' => DJCatalog2HtmlHelper::getThemeLayout($data, 'order_customer', 'email/layouts'),
			'order_items' => DJCatalog2HtmlHelper::getThemeLayout($data, 'order_items', 'email/layouts'),
			'order_link' => JRoute::_(DJCatalog2HelperRoute::getOrderRoute($data['id']) . '&token=' . $data['token'], false, (JUri::getInstance()->isSsl() ? 1 : -1)),
			'vendor_details' => $vendorData
		];
		
		
		foreach($recipient_list as $recipient) {
			$messenger = new DJCatalog2HelperMessenger();
			$messenger->notify(trim((string)$recipient), ['type' => 'order_admin', 'reply_to_email' => trim((string)$data['email'])], $attachments, $adminMailopts );
		}
		
		// Email to the customer
		$mailopts = [
			//'recipient_name' => $data['firstname'].' '.$data['lastname'],
			'recipient_name' => $customerName,
			'order_number' => $data['order_number'],
			'order_customer_data' => DJCatalog2HtmlHelper::getThemeLayout($data, 'order_customer', 'email/layouts'),
			'order_items' => DJCatalog2HtmlHelper::getThemeLayout($data, 'order_items', 'email/layouts'),
			'order_link' => JRoute::_(DJCatalog2HelperRoute::getOrderRoute($data['id']) . '&token=' . $data['token'], false, (JUri::getInstance()->isSsl() ? 1 : -1)),
			'vendor_details' => $vendorData
		];
		
		
		$messenger = new DJCatalog2HelperMessenger();
		$messenger->notify(trim((string)$data['email']), ['type' => 'order'], $attachments, $mailopts );
	
		return true;
	}
	
	public function queryNotification($data, $attachments = array()) {
		require_once(JPATH_ROOT.'/administrator/components/com_djcatalog2/helpers/messenger.php');
		
		$app		= JFactory::getApplication();
		$params 	= JComponentHelper::getParams('com_djcatalog2');
		$user = JFactory::getUser();
		$notifyOwners = (bool)($params->get('cart_query_notifyowners', 0) == '1');
		
		$mailfrom	= $app->getCfg('mailfrom');
		//$fromname	= $app->getCfg('fromname');
		//$sitename	= $app->getCfg('sitename');
		
		// Send notifications to admins
		$vendors = Djcatalog2Helper::getVendors($user->id);
		
		$contact_list = $params->get('contact_list', false);
		$recipient_list = array();
		if ($contact_list !== false) {
			$recipient_list = explode(PHP_EOL, $params->get('contact_list', ''));
		}
		
		$list_is_empty = true;
		foreach ($recipient_list as $r) {
			if (strpos($r, '@') !== false) {
				$list_is_empty = false;
				break;
			}
		}
		
		if ($list_is_empty) {
			$recipient_list[] = $mailfrom;
		}
		if ($user->authorise('djcatalog2.salesman', 'com_djcatalog2')) {
			$recipient_list[] = $user->email;
		}
		if (count($vendors) > 0) {
			foreach($vendors as $vendor) {
				$recipient_list[] = $vendor->email;
			}
		}
		$recipient_list = array_unique($recipient_list);
		
		$customerName = $data['firstname'].' '.$data['lastname'];
		if (!empty($data['company'])) {
			$customerName = $data['company'];
		}
		
		$adminMailopts = [
			'recipient_name' => $customerName,
			'query_customer_data' => DJCatalog2HtmlHelper::getThemeLayout($data, 'query_customer', 'email/layouts'),
			'query_items' => DJCatalog2HtmlHelper::getThemeLayout($data, 'query_items', 'email/layouts'),
		];
		
		foreach($recipient_list as $recipient) {
			$messenger = new DJCatalog2HelperMessenger();
			$messenger->notify(trim((string)$recipient), ['type' => 'query_admin', 'reply_to_email' => trim((string)$data['email'])], $attachments, $adminMailopts );
		}
		
		if ($notifyOwners) {
			$db = JFactory::getDbo();
			$itemIds = array();
			foreach($data['items'] as $item) {
				$itemIds[] = $item['item_id'];
			}
			
			$query = $db->getQuery(true);
			$query->select('u.email, i.email as alt_email, u.id, u.name, i.id as item_id');
			$query->from('#__djc2_items AS i');
			$query->join('LEFT', '#__users AS u ON i.created_by = u.id');
			$query->where('i.id IN ('.implode(',', $itemIds).')');
			$db->setQuery($query);
			
			$owners = $db->loadObjectList('item_id');
			if (count($owners) > 0) {
				$allItems = $data['items'];
				$ownerItems = array();
				foreach($owners as $item_id => $owner) {
					if (!array_key_exists($owner->id, $ownerItems)) {
						$ownerItems[$owner->id] = array('owner'=>$owner, 'items'=>array());
					}
					foreach($allItems as $item) {
						if ($item['item_id'] == $item_id) {
							$ownerItems[$owner->id]['items'][] = $item;
						}
					}
				}
				
				$owner_attachments = array();
				
				foreach ($ownerItems as $ownerData) {
					if (empty($ownerData['items'])) {
						continue;
					}
					
					$owner_email = $ownerData['owner']->alt_email ? $ownerData['owner']->alt_email : $ownerData['owner']->email;
					if (trim((string)$owner_email) == '') {
						continue;
					}
					
					$data['items'] = $ownerData['items'];
					$data['isOwner'] = true;
					
					$adminMailopts = [
						'recipient_name' => $customerName,
						'query_customer_data' => DJCatalog2HtmlHelper::getThemeLayout($data, 'query_customer', 'email/layouts'),
						'query_items' => DJCatalog2HtmlHelper::getThemeLayout($data, 'query_items', 'email/layouts'),
					];
					
					$messenger = new DJCatalog2HelperMessenger();
					$messenger->notify(trim((string)$owner_email), ['type' => 'query_admin', 'reply_to_email' => trim((string)$data['email'])], $owner_attachments, $adminMailopts );
				}
			}
			
		}
		
		// Email to the customer
		$mailopts = [
			'recipient_name' => $customerName,
			'query_customer_data' => DJCatalog2HtmlHelper::getThemeLayout($data, 'query_customer', 'email/layouts'),
			'query_items' => DJCatalog2HtmlHelper::getThemeLayout($data, 'query_items', 'email/layouts'),
		];
		
		$messenger = new DJCatalog2HelperMessenger();
		$messenger->notify(trim((string)$data['email']), ['type' => 'query'], $attachments, $mailopts );

		return true;
	}

	public function selectUser() {
		$app = JFactory::getApplication();
		$juser = JFactory::getUser();
		$salesman = $juser->authorise('djcatalog2.salesman', 'com_djcatalog2') || $juser->authorise('core.admin', 'com_djcatalog2');

		if (!$salesman) {
			throw new Exception(JText::_('JERROR_ALERTNOAUTHOR'), 403);
		}

		$user_id = $app->input->getInt('user_id');
		if (!$user_id) {
			throw new Exception(JText::_('COM_DJCATALOG2_ERROR_INVALID_REQUEST'), 400);
		}

		$app->setUserState('com_djcatalog2.checkout.user_id', $user_id);
		$app->setUserState('com_djcatalog2.order.data', null);
		$basket = Djcatalog2HelperCart::getInstance(true);
		$basket->clear();

		$this->setRedirect(JURI::base(), JText::_('COM_DJCATALOG2_USER_SELECTED'). JFactory::getUser($user_id)->name);

		return true;
	}

	public function selectCheckoutUser() {
		$app = JFactory::getApplication();
		$juser = JFactory::getUser();
		$salesman = $juser->authorise('djcatalog2.salesman', 'com_djcatalog2') || $juser->authorise('core.admin', 'com_djcatalog2');

		if (!$salesman) {
			throw new Exception(JText::_('JERROR_ALERTNOAUTHOR'), 403);
		}

		$user_id = $app->input->getInt('user_id');
		if (!$user_id) {
			throw new Exception(JText::_('COM_DJCATALOG2_ERROR_INVALID_REQUEST'), 400);
		}

		$app->setUserState('com_djcatalog2.checkout.user_id', $user_id);
		$app->setUserState('com_djcatalog2.order.data', null);

		$this->setRedirect(JRoute::_(DJCatalog2HelperRoute::getCheckoutRoute() , false), JText::_('COM_DJCATALOG2_USER_SELECTED'). JFactory::getUser($user_id)->name);

		return true;
	}

	public function changeStatus() {
		$app = JFactory::getApplication();
		$juser = JFactory::getUser();
		$salesman = $juser->authorise('djcatalog2.salesman', 'com_djcatalog2') || $juser->authorise('core.admin', 'com_djcatalog2');

		if (!$salesman) {
			throw new Exception(JText::_('JERROR_ALERTNOAUTHOR'), 403);
		}

		$order_id = $app->input->getInt('oid');
		$status = $app->input->getCmd('status');

		$statuses = array('N', 'A', 'P', 'C', 'R', 'W', 'F');
		if (!$order_id || !$status || !in_array($status, $statuses)) {
			throw new Exception(JText::_('COM_DJCATALOG2_ERROR_INVALID_REQUEST'), 400);
		}

		$model = $this->getModel('Order');
		$order = $model->getItem($order_id);

		if (!$order || $order->salesman_id != $juser->id) {
			throw new Exception(JText::_('JERROR_ALERTNOAUTHOR'), 403);
		}

		if ($order->status != $status) {
			$this->setMessage(JText::_('COM_DJCATALOG2_STATUS_CHANGED_BY_SALESMAN'));
			$model->changeStatus($order, $status, true, true, JText::_('COM_DJCATALOG2_STATUS_CHANGED_BY_SALESMAN'));
		}

		$this->setRedirect(JRoute::_(DJCatalogHelperRoute::getOrderRoute($order_id),false));
		return true;
	}
}

Anon7 - 2022
AnonSec Team