Jump to content

Employee permissions


endriu107

Recommended Posts

Hi,

 

I'm looking for a way to limit the discretion of the employee.

I create new employee and give him access only to order tab in BO, but my employee can see all detail of order like customer name, adres email etc. I don't want that. How to give him permission to view only order status (like payment accept, shipping, delivery) and total price of order?

  • Like 1
Link to comment
Share on other sites

For a standard PrestaShop install, you can't restrict access to just parts of an order. But since you're here in the Development forum, we should be able to point you in the right direction, if you're willing to do the coding...

  1. Create an employee profile that will have restricted viewing rights: Administration > Profiles > Add New [Let's use 'Employee (Restricted)']
  2. Assign the default permissions to the view-restricted profile: Administration > Permissions > Edit > Employee (Restricted)
  3. Assign your employee the view-restricted profile: Administration > Employees > Edit > (the employee)
  4. Create a configuration setting that will store the id_profile of the view-restricted profile: MY_RESTRICTED_PROFILE_ID = N where N is the id_profile of the profile you created in step 1.
  5. Override Employee with a function to check for a view restricted profile:
    public function isViewRestricted {
    		return $this->id_profile == Configuration::getValue('MY_RESTRICTED_PROFILE_ID');
    	}


  6. Override AdminOrdersController to add the flag to the Smarty assignment in renderForm() :
    'isViewRestricted' => $this->context->employee->isViewRestricted(),


  7. Override/Modify most of your BO templates in [store BO directory]/themes/default/template/controllers/orders/ to not display items if the flag is set. This is probably the hardest part, as it is probably going to be a mix of HTML, PHP, and Javascript you will need to change to get the restricted view you want.

You should wrap this in a module framework ( Developer Documentation ) to make it easier to upgrade your store.

 

Also you could start from scratch and write your own restricted view template file ( replacing step 5 above ) and then assign it as the template file based on the isViewRestricted flag ( replacing step 6 above ).

 

Either way, it will be a bit of work...

 

Good Luck,

Edited by Terragg (see edit history)
Link to comment
Share on other sites

Thanks, but I think it's to much complicated for me now.

 

At AdminEmployeeController.php I have:

 

class AdminEmployeesControllerCore extends AdminController
{
 /** @var array profiles list */
protected $profiles_array = array();
/** @var array themes list*/
protected $themes = array();
/** @var array tabs list*/
protected $tabs_list = array();

protected $restrict_edition = false;
public function __construct()
{
  $this->table = 'employee';
 $this->className = 'Employee';
  $this->lang = false;
 $this->addRowAction('edit');
 $this->addRowAction('delete');
 $this->context = Context::getContext();
  $this->bulk_actions = array('delete' => array('text' => $this->l('Delete selected'), 'confirm' => $this->l('Delete selected items?')));
 /*
 check if there are more than one superAdmin
 if it's the case then we can delete a superAdmin
 */
 $super_admin = Employee::countProfile(_PS_ADMIN_PROFILE_, true);
 if ($super_admin == 1)
 {
  $super_admin_array = Employee::getEmployeesByProfile(_PS_ADMIN_PROFILE_, true);
  $super_admin_id = array();
  foreach ($super_admin_array as $key => $val)
   $super_admin_id[] = $val['id_employee'];
  $this->addRowActionSkipList('delete', $super_admin_id);
 }
 $profiles = Profile::getProfiles($this->context->language->id);
 if (!$profiles)
  $this->errors[] = Tools::displayError('No profile');
 else
  foreach ($profiles as $profile)
   $this->profiles_array[$profile['name']] = $profile['name'];
 $this->fields_list = array(
  'id_employee' => array('title' => $this->l('ID'), 'align' => 'center', 'width' => 25),
  'lastname' => array('title' => $this->l('Last name'), 'width' => 'auto'),
  'firstname' => array('title' => $this->l('First name'), 'width' => 130),
  'email' => array('title' => $this->l('E-mail address'), 'width' => 180),
  'profile' => array('title' => $this->l('Profile'), 'width' => 90, 'type' => 'select', 'list' => $this->profiles_array, 'filter_key' => 'pl!name'),
  'active' => array('title' => $this->l('Can log in'), 'align' => 'center', 'active' => 'status', 'type' => 'bool', 'width' => 30),
 );
 $this->fields_options = array(
  'general' => array(
   'title' => $this->l('Employee options'),
   'fields' => array(
 'PS_PASSWD_TIME_BACK' => array(
  'title' => $this->l('Password regeneration'),
  'desc' => $this->l('Security: minimum time to wait between two password changes'),
  'cast' => 'intval',
  'size' => 5,
  'type' => 'text',
  'suffix' => ' '.$this->l('minutes'),
  'visibility' => Shop::CONTEXT_ALL
 ),
 'PS_BO_ALLOW_EMPLOYEE_FORM_LANG' => array(
  'title' => $this->l('Memorize language used in Admin panel forms'),
  'desc' => $this->l('Allow employees to select a specific language for Admin panel forms'),
  'cast' => 'intval',
  'type' => 'select',
  'identifier' => 'value',
  'list' => array(
   '0' => array('value' => 0, 'name' => $this->l('No')),
   '1' => array('value' => 1, 'name' => $this->l('Yes')
  )
 ), 'visibility' => Shop::CONTEXT_ALL)
   ),
   'submit' => array()
  )
 );
 $path = _PS_ADMIN_DIR_.'/themes/';
 foreach (scandir($path) as $theme)
  if ($theme[0] != '.' && is_dir($path.$theme) && file_exists($path.$theme.'/css/admin.css'))
   $this->themes[] = $theme;
 $home_tab = Tab::getInstanceFromClassName('adminHome');
 $this->tabs_list[$home_tab->id] = array(
   'name' => $home_tab->name[$this->context->language->id],
   'id_tab' => $home_tab->id,
   'children' => array(array('id_tab' =>$home_tab->id, 'name' => $home_tab->name[$this->context->language->id])));
 foreach (Tab::getTabs($this->context->language->id, 0) as $tab)
 {
  if (Tab::checkTabRights($tab['id_tab']))
  {
   $this->tabs_list[$tab['id_tab']] = $tab;
   foreach (Tab::getTabs($this->context->language->id, $tab['id_tab']) as $children)
 if (Tab::checkTabRights($children['id_tab']))
  $this->tabs_list[$tab['id_tab']]['children'][] = $children;
  }
 }
 parent::__construct();
 // An employee can edit its own profile
 if ($this->context->employee->id == Tools::getValue('id_employee'))
 {
  $this->tabAccess['view'] = '1';
  if (!$this->tabAccess['edit'])
   $this->restrict_edition = true;
  $this->tabAccess['edit'] = '1';
 }
}
public function renderList()
{
  $this->_select = 'pl.`name` AS profile';
 $this->_join = 'LEFT JOIN `'._DB_PREFIX_.'profile` p ON a.`id_profile` = p.`id_profile`
 LEFT JOIN `'._DB_PREFIX_.'profile_lang` pl ON (pl.`id_profile` = p.`id_profile` AND pl.`id_lang` = '.(int)$this->context->language->id.')';
 return parent::renderList();
}
public function renderForm()
{
 if (!($obj = $this->loadObject(true)))
  return;
 $available_profiles = Profile::getProfiles($this->context->language->id);
 if ($obj->id_profile == _PS_ADMIN_PROFILE_ && $this->context->employee->id_profile != _PS_ADMIN_PROFILE_)
 {
  $this->errors[] = Tools::displayError('You cannot edit SuperAdmin profile.');
  return parent::renderForm();
 }
 $this->fields_form = array(
  'legend' => array(
   'title' => $this->l('Employees'),
   'image' => '../img/admin/nav-user.gif'
  ),
  'input' => array(
   array(
 'type' => 'text',
 'label' => $this->l('First name:'),
 'name' => 'firstname',
 'size' => 33,
 'required' => true
   ),
   array(
 'type' => 'text',
 'label' => $this->l('Last name:'),
 'name' => 'lastname',
 'size' => 33,
 'required' => true
   ),
   array(
 'type' => 'password',
 'label' => $this->l('Password:'),
 'name' => 'passwd',
 'required' => true,
 'size' => 33,
 'desc' => ($obj->id ?
    $this->l('Leave blank if you do not want to change your password') :
	 $this->l('Min. 8 characters; use only letters, numbers or').' -_')
   ),
   array(
 'type' => 'text',
 'label' => $this->l('E-mail address:'),
 'name' => 'email',
 'size' => 33,
 'required' => true
   ),
   array(
 'type' => 'color',
 'label' => $this->l('Admin panel color:'),
 'name' => 'bo_color',
 'class' => 'color mColorPickerInput',
 'size' => 20,
 'desc' => $this->l('Admin panel background will be displayed in this color. HTML colors only (e.g.').' "lightblue", "#CC6600")'
   ),
   array(
 'type' => 'default_tab',
 'label' => $this->l('Default page:'),
 'name' => 'default_tab',
 'desc' => $this->l('This page will be displayed just after login'),
 'options' => $this->tabs_list
   ),
   array(
 'type' => 'text',
 'label' => $this->l('Back Office width:'),
 'name' => 'bo_width',
 'size' => 10,
 'desc' => $this->l('Back Office width, in pixels. The value "0" means that the Back Office width will be flexible.')
   ),
   array(
 'type' => 'select',
 'label' => $this->l('Language:'),
 'name' => 'id_lang',
 'required' => true,
 'options' => array(
  'query' => Language::getLanguages(),
  'id' => 'id_lang',
  'name' => 'name'
 )
   ),
   array(
 'type' => 'select_theme',
 'label' => $this->l('Theme:'),
 'name' => 'bo_theme',
 'options' => array('query' => $this->themes),
 'desc' => $this->l('Back Office theme')
   ),
   array(
 'type' => 'radio',
 'label' => $this->l('Show screencast at log in:'),
 'name' => 'bo_show_screencast',
 'desc' => $this->l('Display the welcome video in the Admin panel dashboard at log in'),
 'required' => false,
 'class' => 't',
 'is_bool' => true,
 'values' => array(
  array(
   'id' => 'bo_show_screencast_on',
   'value' => 1,
   'label' => $this->l('Enabled')
  ),
  array(
   'id' => 'bo_show_screencast_off',
   'value' => 0,
   'label' => $this->l('Disabled')
  )
 )
   )
  )
 );
 if ((int)$this->tabAccess['edit'] && !$this->restrict_edition)
 {
  $this->fields_form['input'][] = array(
   'type' => 'radio',
   'label' => $this->l('Status:'),
   'name' => 'active',
   'required' => false,
   'class' => 't',
   'is_bool' => true,
   'values' => array(
 array(
  'id' => 'active_on',
  'value' => 1,
  'label' => $this->l('Enabled')
 ),
 array(
  'id' => 'active_off',
  'value' => 0,
  'label' => $this->l('Disabled')
 )
   ),
   'desc' => $this->l('Allow or disallow this employee to log into the Admin panel')
  );
  // if employee is not SuperAdmin (id_profile = 1), don't make it possible to select the admin profile
  if ($this->context->employee->id_profile != _PS_ADMIN_PROFILE_)
 foreach ($available_profiles as $i => $profile)
  if ($available_profiles[$i]['id_profile'] == _PS_ADMIN_PROFILE_)
 {
  unset($available_profiles[$i]);
  break;
 }
  $this->fields_form['input'][] = array(
   'type' => 'select',
   'label' => $this->l('Profile:'),
   'name' => 'id_profile',
   'required' => true,
   'options' => array(
 'query' => $available_profiles,
 'id' => 'id_profile',
 'name' => 'name',
 'default' => array(
  'value' => '',
  'label' => $this->l('-- Choose --')
 )
   )
  );
  if (Shop::isFeatureActive())
  {
   $this->context->smarty->assign('_PS_ADMIN_PROFILE_', (int)_PS_ADMIN_PROFILE_);
   $this->fields_form['input'][] = array(
 'type' => 'shop',
 'label' => $this->l('Shop association:'),
 'desc' => $this->l('Select the shops the employee is allowed to access'),
 'name' => 'checkBoxShopAsso',
   );
  }
 }
 $this->fields_form['submit'] = array(
  'title' => $this->l('   Save   '),
  'class' => 'button'
 );
 $this->fields_value['passwd'] = false;
 if (empty($obj->id))
  $this->fields_value['id_lang'] = $this->context->language->id;
 return parent::renderForm();
}
protected function _childValidation()
{
 if (!($obj = $this->loadObject(true)))
  return false;
 $email = $this->getFieldValue($obj, 'email');
 if (!Validate::isEmail($email))
   $this->errors[] = Tools::displayError('Invalid e-mail');
 else if (Employee::employeeExists($email) && !Tools::getValue('id_employee'))
  $this->errors[] = Tools::displayError('An account already exists for this e-mail address:').' '.$email;
}
public function postProcess()
{
 if (Tools::isSubmit('deleteemployee') || Tools::isSubmit('status') || Tools::isSubmit('statusemployee'))
 {
  /* PrestaShop demo mode */
  if (_PS_MODE_DEMO_ && $id_employee = Tools::getValue('id_employee') && (int)$id_employee == _PS_DEMO_MAIN_BO_ACCOUNT_)
  {
   $this->errors[] = Tools::displayError('This functionality has been disabled.');
   return;
  }
  if ($this->context->employee->id == Tools::getValue('id_employee'))
  {
   $this->errors[] = Tools::displayError('You cannot disable or delete your own account.');
   return false;
  }
  $employee = new Employee(Tools::getValue('id_employee'));
  if ($employee->isLastAdmin())
  {
   $this->errors[] = Tools::displayError('You cannot disable or delete the last administrator account.');
   return false;
  }
  // It is not possible to delete an employee if he manages warehouses
  $warehouses = Warehouse::getWarehousesByEmployee((int)Tools::getValue('id_employee'));
  if (Tools::isSubmit('deleteemployee') && count($warehouses) > 0)
  {
   $this->errors[] = Tools::displayError('You cannot delete this account because it manages warehouses. Check your warehouses first.');
   return false;
  }
 }
 elseif (Tools::isSubmit('submitAddemployee'))
 {
  $employee = new Employee((int)Tools::getValue('id_employee'));
  // If the employee is editing its own account
  if ($this->restrict_edition)
  {
   $_POST['id_profile'] = $_GET['id_profile'] = $employee->id_profile;
   $_POST['active'] = $_GET['active'] = $employee->active;

   // Unset set shops
   foreach ($_POST as $postkey => $postvalue)
 if (strstr($postkey, 'checkBoxShopAsso_'.$this->table) !== false)
  unset($_POST[$postkey]);
   foreach ($_GET as $postkey => $postvalue)
 if (strstr($postkey, 'checkBoxShopAsso_'.$this->table) !== false)
  unset($_GET[$postkey]);

   // Add current shops associated to the employee
   $result = Shop::getShopById((int)$employee->id, $this->identifier, $this->table);
   foreach ($result as $row)
   {
 $key = 'checkBoxShopAsso_'.$this->table;
 if (!isset($_POST[$key]))
  $_POST[$key] = array();
 if (!isset($_GET[$key]))
  $_GET[$key] = array();
 $_POST[$key][$row['id_shop']] = 1;
 $_GET[$key][$row['id_shop']] = 1;
   }
  }
  //if profile is super admin, manually fill checkBoxShopAsso_employee because in the form they are disabled.
  if ($_POST['id_profile'] == _PS_ADMIN_PROFILE_)
  {
   $result = Db::getInstance()->executeS('SELECT id_shop FROM '._DB_PREFIX_.'shop');
   foreach ($result as $row)
   {
 $key = 'checkBoxShopAsso_'.$this->table;
 if (!isset($_POST[$key]))
  $_POST[$key] = array();
 if (!isset($_GET[$key]))
  $_GET[$key] = array();
 $_POST[$key][$row['id_shop']] = 1;
 $_GET[$key][$row['id_shop']] = 1;
   }
  }
  if ($employee->isLastAdmin())
  {
   if (Tools::getValue('id_profile') != (int)_PS_ADMIN_PROFILE_)
   {
 $this->errors[] = Tools::displayError('You should have at least one employee in the administrator group.');
 return false;
   }
   if (Tools::getvalue('active') == 0)
   {
 $this->errors[] = Tools::displayError('You cannot disable or delete the last administrator account.');
 return false;
   }
  }
  if (!in_array(Tools::getValue('bo_theme'), $this->themes))
  {
   $this->errors[] = Tools::displayError('Invalid theme.');
   return false;
  }
  $assos = $this->getSelectedAssoShop($this->table);
  if (!$assos && $this->table = 'employee')
   if (Shop::isFeatureActive() && _PS_ADMIN_PROFILE_ != $_POST['id_profile'])
 $this->errors[] = Tools::displayError('The employee must be associated with at least one shop');
 }
 return parent::postProcess();
}
public function initContent()
{
 if ($this->context->employee->id == Tools::getValue('id_employee'))
  $this->display = 'edit';
 return parent::initContent();
}
public function ajaxProcessGetTabByIdProfile()
{
 $id_profile = Tools::getValue('id_profile');
 $tabs = Tab::getTabByIdProfile(0, $id_profile);
 $this->tabs_list = array();
 foreach ($tabs as $tab)
 {
  if (Tab::checkTabRights($tab['id_tab']))
  {
   $this->tabs_list[$tab['id_tab']] = $tab;
   foreach (Tab::getTabByIdProfile($tab['id_tab'], $id_profile) as $children)
 if (Tab::checkTabRights($children['id_tab']))
  $this->tabs_list[$tab['id_tab']]['children'][] = $children;
  }
 }
 die(Tools::jsonEncode($this->tabs_list));
}
}

 

and at AdminOrdersController.php

class AdminOrdersControllerCore extends AdminController
{
public $toolbar_title;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]public function __construct()
{
 $this->table = 'order';
 $this->className = 'Order';
 $this->lang = false;
 $this->addRowAction('view');
 $this->explicitSelect = true;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $this->deleted = false;
 $this->context = Context::getContext();[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $this->_select = '
 a.id_currency,
 a.id_order AS id_pdf,
 CONCAT(LEFT(c.`firstname`, 1), \'. \', c.`lastname`) AS `customer`,
 osl.`name` AS `osname`,
 os.`color`,
 IF((SELECT COUNT(so.id_order) FROM `'._DB_PREFIX_.'orders` so WHERE so.id_customer = a.id_customer) > 1, 0, 1) as new';[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $this->_join = '
 LEFT JOIN `'._DB_PREFIX_.'customer` c ON (c.`id_customer` = a.`id_customer`)
 LEFT JOIN `'._DB_PREFIX_.'order_state` os ON (os.`id_order_state` = a.`current_state`)
 LEFT JOIN `'._DB_PREFIX_.'order_state_lang` osl ON (os.`id_order_state` = osl.`id_order_state` AND osl.`id_lang` = '.(int)$this->context->language->id.')';
 $this->_orderBy = 'id_order';
 $this->_orderWay = 'DESC';[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $statuses_array = array();
 $statuses = OrderState::getOrderStates((int)$this->context->language->id);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  foreach ($statuses as $status)
  $statuses_array[$status['id_order_state']] = $status['name'];[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $this->fields_list = array(
 'id_order' => array(
  'title' => $this->l('ID'),
  'align' => 'center',
  'width' => 25
 ),
 'reference' => array(
  'title' => $this->l('Reference'),
  'align' => 'center',
  'width' => 65
 ),
 'new' => array(
  'title' => $this->l('New'),
  'width' => 25,
  'align' => 'center',
  'type' => 'bool',
  'tmpTableFilter' => true,
  'icon' => array(
   0 => 'blank.gif',
   1 => array(
 'src' => 'note.png',
 'alt' => $this->l('First customer order'),
   )
  ),
  'orderby' => false
 ),
 'customer' => array(
  'title' => $this->l('Customer'),
  'havingFilter' => true,
 ),
 'total_paid_tax_incl' => array(
  'title' => $this->l('Total'),
  'width' => 70,
  'align' => 'right',
  'prefix' => '<b>',
  'suffix' => '</b>',
  'type' => 'price',
  'currency' => true
 ),
 'payment' => array(
  'title' => $this->l('Payment'),
  'width' => 100
 ),
 'osname' => array(
  'title' => $this->l('Status'),
  'color' => 'color',
  'width' => 280,
  'type' => 'select',
  'list' => $statuses_array,
  'filter_key' => 'os!id_order_state',
  'filter_type' => 'int'
 ),
 'date_add' => array(
  'title' => $this->l('Date'),
  'width' => 130,
  'align' => 'right',
  'type' => 'datetime',
  'filter_key' => 'a!date_add'
 ),
 'id_pdf' => array(
  'title' => $this->l('PDF'),
  'width' => 35,
  'align' => 'center',
  'callback' => 'printPDFIcons',
  'orderby' => false,
  'search' => false,
  'remove_onclick' => true)
 );[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $this->shopLinkType = 'shop';
 $this->shopShareDatas = Shop::SHARE_ORDER;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  if (Tools::isSubmit('id_order'))
 {
  // Save context (in order to apply cart rule)
  $order = new Order((int)Tools::getValue('id_order'));
  if (!Validate::isLoadedObject($order))
   throw new PrestaShopException('Cannot load Order object');
  $this->context->cart = new Cart($order->id_cart);
  $this->context->customer = new Customer($order->id_customer);
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  parent::__construct();
}[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]public function renderForm()
{
 if (Context::getContext()->shop->getContext() != Shop::CONTEXT_SHOP && Shop::isFeatureActive())
  $this->errors[] = $this->l('You have to select a shop in order to create new orders.');[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $id_cart = (int)Tools::getValue('id_cart');
 $cart = new Cart((int)$id_cart);
 if ($id_cart && !Validate::isLoadedObject($cart))
  $this->errors[] = $this->l('This cart does not exists');
 if ($id_cart && Validate::isLoadedObject($cart) && !$cart->id_customer)
  $this->errors[] = $this->l('The cart must have a customer');
 if (count($this->errors))
  return false;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  parent::renderForm();
 unset($this->toolbar_btn['save']);
 $this->addJqueryPlugin(array('autocomplete', 'fancybox', 'typewatch'));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $defaults_order_state = array('cheque' => (int)Configuration::get('PS_OS_CHEQUE'),
	    'bankwire' => (int)Configuration::get('PS_OS_BANKWIRE'),
	    'cashondelivery' => (int)Configuration::get('PS_OS_PREPARATION'),
	    'other' => (int)Configuration::get('PS_OS_PAYMENT'));
 $payment_modules = array();
 foreach (PaymentModule::getInstalledPaymentModules() as $p_module)
  $payment_modules[] = Module::getInstanceById((int)$p_module['id_module']);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $this->context->smarty->assign(array(
  'recyclable_pack' => (int)Configuration::get('PS_RECYCLABLE_PACK'),
  'gift_wrapping' => (int)Configuration::get('PS_GIFT_WRAPPING'),
  'cart' => $cart,
  'currencies' => Currency::getCurrencies(),
  'langs' => Language::getLanguages(true, Context::getContext()->shop->id),
  'payment_modules' => $payment_modules,
  'order_states' => OrderState::getOrderStates((int)Context::getContext()->language->id),
  'defaults_order_state' => $defaults_order_state,
  'show_toolbar' => $this->show_toolbar,
  'toolbar_btn' => $this->toolbar_btn,
  'toolbar_scroll' => $this->toolbar_scroll,
  'title' => array($this->l('Orders'), $this->l('create order'))
 ));
 $this->content .= $this->createTemplate('form.tpl')->fetch();
}[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]public function initToolbar()
{
 if ($this->display == 'view')
 {
  $order = new Order((int)Tools::getValue('id_order'));
  if ($order->hasBeenShipped())
   $type = $this->l('Return products');
  elseif ($order->hasBeenPaid())
   $type = $this->l('Standard refund');
  else
   $type = $this->l('Cancel products');[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]   if (!$order->hasBeenShipped() && !$this->lite_display)
   $this->toolbar_btn['new'] = array(
 'short' => 'Create',
 'href' => '#',
 'desc' => $this->l('Add a product'),
 'class' => 'add_product'
   );[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]   if (Configuration::get('PS_ORDER_RETURN') && !$this->lite_display)
   $this->toolbar_btn['standard_refund'] = array(
 'short' => 'Create',
 'href' => '',
 'desc' => $type,
 'class' => 'process-icon-standardRefund'
   );

  if ($order->hasInvoice() && !$this->lite_display)
   $this->toolbar_btn['partial_refund'] = array(
 'short' => 'Create',
 'href' => '',
 'desc' => $this->l('Partial refund'),
 'class' => 'process-icon-partialRefund'
   );
 }
 $res = parent::initToolbar();
 if (Context::getContext()->shop->getContext() != Shop::CONTEXT_SHOP && isset($this->toolbar_btn['new']) && Shop::isFeatureActive())
  unset($this->toolbar_btn['new']);
 return $res;
}[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]public function setMedia()
{
 parent::setMedia();
 $this->addJqueryUI('ui.datepicker');
 if ($this->tabAccess['edit'] == 1 && $this->display == 'view')
 {
  $this->addJS(_PS_JS_DIR_.'admin_order.js');
  $this->addJS(_PS_JS_DIR_.'tools.js');
  $this->addJqueryPlugin('autocomplete');
 }
}[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]public function printPDFIcons($id_order, $tr)
{
 $order = new Order($id_order);
 $order_state = $order->getCurrentOrderState();
 if (!Validate::isLoadedObject($order_state) || !Validate::isLoadedObject($order))
  return '';[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $this->context->smarty->assign(array(
  'order' => $order,
  'order_state' => $order_state,
  'tr' => $tr
 ));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  return $this->createTemplate('_print_pdf_icon.tpl')->fetch();
}[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]public function postProcess()
{
 // If id_order is sent, we instanciate a new Order object
 if (Tools::isSubmit('id_order') && Tools::getValue('id_order') > 0)
 {
  $order = new Order(Tools::getValue('id_order'));
  if (!Validate::isLoadedObject($order))
   throw new PrestaShopException('Can\'t load Order object');
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  /* Update shipping number */
 if (Tools::isSubmit('submitShippingNumber') && isset($order))
 {
  if ($this->tabAccess['edit'] === '1')
  {
   $order_carrier = new OrderCarrier(Tools::getValue('id_order_carrier'));
   if (!Validate::isLoadedObject($order_carrier))
 $this->errors[] = Tools::displayError('Order carrier ID is invalid');
   elseif (!Validate::isTrackingNumber(Tools::getValue('tracking_number')))
 $this->errors[] = Tools::displayError('Tracking number is incorrect');
   else
   {
 // update shipping number
 // Keep these two following lines for backward compatibility, remove on 1.6 version
 $order->shipping_number = Tools::getValue('tracking_number');
 $order->update();[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	 // Update order_carrier
 $order_carrier->tracking_number = pSQL(Tools::getValue('tracking_number'));
 if ($order_carrier->update())
 {
  // Send mail to customer
  $customer = new Customer((int)$order->id_customer);
  $carrier = new Carrier((int)$order->id_carrier, $order->id_lang);
  if (!Validate::isLoadedObject($customer))
   throw new PrestaShopException('Can\'t load Customer object');
  if (!Validate::isLoadedObject($carrier))
   throw new PrestaShopException('Can\'t load Carrier object');
  $templateVars = array(
   '{followup}' => str_replace('@', $order->shipping_number, $carrier->url),
   '{firstname}' => $customer->firstname,
   '{lastname}' => $customer->lastname,
   '{id_order}' => $order->id,
   '{order_name}' => $order->getUniqReference()
  );
  if (@Mail::Send((int)$order->id_lang, 'in_transit', Mail::l('Package in transit', (int)$order->id_lang), $templateVars,
   $customer->email, $customer->firstname.' '.$customer->lastname, null, null, null, null,
   _PS_MAIL_DIR_, true, (int)$order->id_shop))
  {
   Hook::exec('actionAdminOrdersTrackingNumberUpdate', array('order' => $order));
   Tools::redirectAdmin(self::$currentIndex.'&id_order='.$order->id.'&vieworder&conf=4&token='.$this->token);
  }
  else
   $this->errors[] = Tools::displayError('An error occurred while sending e-mail to the customer.');
 }
 else
  $this->errors[] = Tools::displayError('Order carrier can\'t be updated');
   }
  }
  else
   $this->errors[] = Tools::displayError('You do not have permission to edit here.');
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  /* Change order state, add a new entry in order history and send an e-mail to the customer if needed */
 elseif (Tools::isSubmit('submitState') && isset($order))
 {
  if ($this->tabAccess['edit'] === '1')
  {
   $order_state = new OrderState(Tools::getValue('id_order_state'));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]    if (!Validate::isLoadedObject($order_state))
 $this->errors[] = Tools::displayError('Invalid new order status');
   else
   {
 $current_order_state = $order->getCurrentOrderState();
 if ($current_order_state->id != $order_state->id)
 {
  // Create new OrderHistory
  $history = new OrderHistory();
  $history->id_order = $order->id;
  $history->id_employee = (int)$this->context->employee->id;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	  $use_existings_payment = false;
  if (!$order->hasInvoice())
   $use_existings_payment = true;
  $history->changeIdOrderState((int)$order_state->id, $order, $use_existings_payment);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	  $carrier = new Carrier($order->id_carrier, $order->id_lang);
  $templateVars = array();
  if ($history->id_order_state == Configuration::get('PS_OS_SHIPPING') && $order->shipping_number)
   $templateVars = array('{followup}' => str_replace('@', $order->shipping_number, $carrier->url));
  // Save all changes
  if ($history->addWithemail(true, $templateVars))
  {
   // synchronizes quantities if needed..
   if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT'))
   {
    foreach ($order->getProducts() as $product)
    {
	 if (StockAvailable::dependsOnStock($product['product_id']))
	  StockAvailable::synchronize($product['product_id'], (int)$product['id_shop']);
    }
   }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	   Tools::redirectAdmin(self::$currentIndex.'&id_order='.(int)$order->id.'&vieworder&token='.$this->token);
  }
  $this->errors[] = Tools::displayError('An error occurred while changing the status or was unable to send e-mail to the customer.');
 }
 else
  $this->errors[] = Tools::displayError('This order is already assigned this status');
   }
  }
  else
   $this->errors[] = Tools::displayError('You do not have permission to edit here.');
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  /* Add a new message for the current order and send an e-mail to the customer if needed */
 elseif (Tools::isSubmit('submitMessage') && isset($order))
 {
  if ($this->tabAccess['edit'] === '1')
  {
   $customer = new Customer(Tools::getValue('id_customer'));
   if (!Validate::isLoadedObject($customer))
 $this->errors[] = Tools::displayError('Customer is invalid');
   elseif (!Tools::getValue('message'))
 $this->errors[] = Tools::displayError('Message cannot be blank');
   else
   {
 /* Get message rules and and check fields validity */
 $rules = call_user_func(array('Message', 'getValidationRules'), 'Message');
 foreach ($rules['required'] as $field)
  if (($value = Tools::getValue($field)) == false && (string)$value != '0')
   if (!Tools::getValue('id_'.$this->table) || $field != 'passwd')
    $this->errors[] = sprintf(Tools::displayError('field %s is required.'), $field);
 foreach ($rules['size'] as $field => $maxLength)
  if (Tools::getValue($field) && Tools::strlen(Tools::getValue($field)) > $maxLength)
   $this->errors[] = sprintf(Tools::displayError('field %1$s is too long (%2$d chars max).'), $field, $maxLength);
 foreach ($rules['validate'] as $field => $function)
  if (Tools::getValue($field))
   if (!Validate::$function(htmlentities(Tools::getValue($field), ENT_COMPAT, 'UTF-8')))
    $this->errors[] = sprintf(Tools::displayError('field %s is invalid.'), $field);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	 if (!count($this->errors))
 {
  //check if a thread already exist
  $id_customer_thread = CustomerThread::getIdCustomerThreadByEmailAndIdOrder($customer->email, $order->id);
  if (!$id_customer_thread)
  {
   $customer_thread = new CustomerThread();
   $customer_thread->id_contact = 0;
   $customer_thread->id_customer = (int)$order->id_customer;
   $customer_thread->id_shop = (int)$this->context->shop->id;
   $customer_thread->id_order = (int)$order->id;
   $customer_thread->id_lang = (int)$this->context->language->id;
   $customer_thread->email = $customer->email;
   $customer_thread->status = 'open';
   $customer_thread->token = Tools::passwdGen(12);
   $customer_thread->add();
  }
  else
   $customer_thread = new CustomerThread((int)$id_customer_thread);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	  $customer_message = new CustomerMessage();
  $customer_message->id_customer_thread = $customer_thread->id;
  $customer_message->id_employee = (int)$this->context->employee->id;
  $customer_message->message = htmlentities(Tools::getValue('message'), ENT_COMPAT, 'UTF-8');
  $customer_message->private = Tools::getValue('visibility');[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	  if (!$customer_message->add())
   $this->errors[] = Tools::displayError('An error occurred while saving message');
  elseif ($customer_message->private)
   Tools::redirectAdmin(self::$currentIndex.'&id_order='.(int)$order->id.'&vieworder&conf=11&token='.$this->token);
  else
  {
   $message = $customer_message->message;
   if (Configuration::get('PS_MAIL_TYPE') != Mail::TYPE_TEXT)
    $message = Tools::nl2br($customer_message->message);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	   $varsTpl = array(
    '{lastname}' => $customer->lastname,
    '{firstname}' => $customer->firstname,
    '{id_order}' => $order->id,
    '{order_name}' => $order->getUniqReference(),
    '{message}' => $message
   );
   if (@Mail::Send((int)$order->id_lang, 'order_merchant_comment',
    Mail::l('New message regarding your order', (int)$order->id_lang), $varsTpl, $customer->email,
    $customer->firstname.' '.$customer->lastname, null, null, null, null, _PS_MAIL_DIR_, true, (int)$order->id_shop))
    Tools::redirectAdmin(self::$currentIndex.'&id_order='.$order->id.'&vieworder&conf=11'.'&token='.$this->token);
  }
  $this->errors[] = Tools::displayError('An error occurred while sending e-mail to the customer.');
 }
   }
  }
  else
   $this->errors[] = Tools::displayError('You do not have permission to delete here.');
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  /* Partial refund from order */
 elseif (Tools::isSubmit('partialRefund') && isset($order))
 {
  if ($this->tabAccess['edit'] == '1')
  {
   if (is_array($_POST['partialRefundProduct']))
   {
 $amount = 0;
 $order_detail_list = array();
 foreach ($_POST['partialRefundProduct'] as $id_order_detail => $amount_detail)
 {
  $order_detail_list[$id_order_detail]['quantity'] = (int)$_POST['partialRefundProductQuantity'][$id_order_detail];[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	  if (empty($amount_detail))
  {
   $order_detail = new OrderDetail((int)$id_order_detail);
   $order_detail_list[$id_order_detail]['amount'] = $order_detail->unit_price_tax_incl * $order_detail_list[$id_order_detail]['quantity'];
  }
  else
   $order_detail_list[$id_order_detail]['amount'] = (float)str_replace(',', '.', $amount_detail);
  $amount += $order_detail_list[$id_order_detail]['amount'];[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	  $order_detail = new OrderDetail((int)$id_order_detail);
  if (!$order->hasBeenDelivered() || ($order->hasBeenDelivered() && Tools::isSubmit('reinjectQuantities')) && $order_detail_list[$id_order_detail]['quantity'] > 0)
   $this->reinjectQuantity($order_detail, $order_detail_list[$id_order_detail]['quantity']);
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	 $shipping_cost_amount = (float)str_replace(',', '.', Tools::getValue('partialRefundShippingCost'));
 if ($shipping_cost_amount > 0)
  $amount += $shipping_cost_amount;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	 if ($amount > 0)
 {
  if (!OrderSlip::createPartialOrderSlip($order, $amount, $shipping_cost_amount, $order_detail_list))
   $this->errors[] = Tools::displayError('Cannot generate partial credit slip');[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	  // Generate voucher
  if (Tools::isSubmit('generateDiscountRefund') && !count($this->errors))
  {
   $cart_rule = new CartRule();
   $cart_rule->description = sprintf($this->l('Credit Slip for order #%d'), $order->id);
   $languages = Language::getLanguages(false);
   foreach ($languages as $language)
    // Define a temporary name
    $cart_rule->name[$language['id_lang']] = sprintf('V0C%1$dO%2$d', $order->id_customer, $order->id);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	   // Define a temporary code
   $cart_rule->code = sprintf('V0C%1$dO%2$d', $order->id_customer, $order->id);
   $cart_rule->quantity = 1;
   $cart_rule->quantity_per_user = 1;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	   // Specific to the customer
   $cart_rule->id_customer = $order->id_customer;
   $now = time();
   $cart_rule->date_from = date('Y-m-d H:i:s', $now);
   $cart_rule->date_to = date('Y-m-d H:i:s', $now + (3600 * 24 * 365.25)); /* 1 year */
   $cart_rule->active = 1;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	   $cart_rule->reduction_amount = $amount;
   $cart_rule->reduction_tax = true;
   $cart_rule->minimum_amount_currency = $order->id_currency;
   $cart_rule->reduction_currency = $order->id_currency;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	   if (!$cart_rule->add())
    $this->errors[] = Tools::displayError('Cannot generate voucher');
   else
   {
    // Update the voucher code and name
    foreach ($languages as $language)
	 $cart_rule->name[$language['id_lang']] = sprintf('V%1$dC%2$dO%3$d', $cart_rule->id, $order->id_customer, $order->id);
    $cart_rule->code = sprintf('V%1$dC%2$dO%3$d', $cart_rule->id, $order->id_customer, $order->id);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	    if (!$cart_rule->update())
	 $this->errors[] = Tools::displayError('Cannot generate voucher');
    else
    {
	 $currency = $this->context->currency;
	 $customer = new Customer((int)($order->id_customer));
	 $params['{lastname}'] = $customer->lastname;
	 $params['{firstname}'] = $customer->firstname;
	 $params['{id_order}'] = $order->id;
	 $params['{order_name}'] = $order->getUniqReference();
	 $params['{voucher_amount}'] = Tools::displayPrice($cart_rule->reduction_amount, $currency, false);
	 $params['{voucher_num}'] = $cart_rule->code;
	 $customer = new Customer((int)$order->id_customer);
	 @Mail::Send((int)$order->id_lang, 'voucher', sprintf(Mail::l('New voucher regarding your order %s', (int)$order->id_lang), $order->reference),
	  $params, $customer->email, $customer->firstname.' '.$customer->lastname, null, null, null,
	  null, _PS_MAIL_DIR_, true, (int)$order->id_shop);
    }
   }
  }
 }
 else
  $this->errors[] = Tools::displayError('You have to write an amount if you want to do a partial credit slip');[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	 // Redirect if no errors
 if (!count($this->errors))
  Tools::redirectAdmin(self::$currentIndex.'&id_order='.$order->id.'&vieworder&conf=30&token='.$this->token);
   }
   else
 $this->errors[] = Tools::displayError('Partial refund data is incorrect');
  }
  else
   $this->errors[] = Tools::displayError('You do not have permission to delete here.');
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  /* Cancel product from order */
 elseif (Tools::isSubmit('cancelProduct') && isset($order))
 {
   if ($this->tabAccess['delete'] === '1')
  {
   if (!Tools::isSubmit('id_order_detail'))
 $this->errors[] = Tools::displayError('You must select a product');
   elseif (!Tools::isSubmit('cancelQuantity'))
 $this->errors[] = Tools::displayError('You must enter a quantity');
   else
   {
 $productList = Tools::getValue('id_order_detail');
 if ($productList)
  $productList = array_map('intval', $productList);

 $customizationList = Tools::getValue('id_customization');
 if ($customizationList)
  $customizationList = array_map('intval', $customizationList);

 $qtyList = Tools::getValue('cancelQuantity');
 if ($qtyList)
  $qtyList = array_map('intval', $qtyList);

 $customizationQtyList = Tools::getValue('cancelCustomizationQuantity');
 if ($customizationQtyList)
  $customizationQtyList = array_map('intval', $customizationQtyList);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	 $full_product_list = $productList;
 $full_quantity_list = $qtyList;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	 if ($customizationList)
  foreach ($customizationList as $key => $id_order_detail)
  {
   $full_product_list[(int)$id_order_detail] = $id_order_detail;
   $full_quantity_list[(int)$id_order_detail] += $customizationQtyList[$key];
  }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	 if ($productList || $customizationList)
 {
  if ($productList)
  {
   $id_cart = Cart::getCartIdByOrderId($order->id);
   $customization_quantities = Customization::countQuantityByCart($id_cart);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	   foreach ($productList as $key => $id_order_detail)
   {
    $qtyCancelProduct = abs($qtyList[$key]);
    if (!$qtyCancelProduct)
	 $this->errors[] = Tools::displayError('No quantity selected for product.');[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	    $order_detail = new OrderDetail($id_order_detail);
    $customization_quantity = 0;
    if (array_key_exists($order_detail->product_id, $customization_quantities) && array_key_exists($order_detail->product_attribute_id, $customization_quantities[$order_detail->product_id]))
	 $customization_quantity = (int)$customization_quantities[$order_detail->product_id][$order_detail->product_attribute_id];[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	    if (($order_detail->product_quantity - $customization_quantity - $order_detail->product_quantity_refunded - $order_detail->product_quantity_return) < $qtyCancelProduct)
	 $this->errors[] = Tools::displayError('Invalid quantity selected for product.');[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	   }
  }
  if ($customizationList)
  {
   $customization_quantities = Customization::retrieveQuantitiesFromIds(array_keys($customizationList));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	   foreach ($customizationList as $id_customization => $id_order_detail)
   {
    $qtyCancelProduct = abs($customizationQtyList[$id_customization]);
    $customization_quantity = $customization_quantities[$id_customization];[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	    if (!$qtyCancelProduct)
	 $this->errors[] = Tools::displayError('No quantity selected for product.');[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	    if ($qtyCancelProduct > ($customization_quantity['quantity'] - ($customization_quantity['quantity_refunded'] + $customization_quantity['quantity_returned'])))
	 $this->errors[] = Tools::displayError('Invalid quantity selected for product.');
   }
  }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	  if (!count($this->errors) && $productList)
   foreach ($productList as $key => $id_order_detail)
   {
    $qty_cancel_product = abs($qtyList[$key]);
    $order_detail = new OrderDetail((int)($id_order_detail));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	    if (!$order->hasBeenDelivered() || ($order->hasBeenDelivered() && Tools::isSubmit('reinjectQuantities')) && $qty_cancel_product > 0)
	 $this->reinjectQuantity($order_detail, $qty_cancel_product);

    // Delete product
    $order_detail = new OrderDetail((int)$id_order_detail);
    if (!$order->deleteProduct($order, $order_detail, $qtyCancelProduct))
	 $this->errors[] = Tools::displayError('An error occurred during deletion of the product.').' <span class="bold">'.$order_detail->product_name.'</span>';
    Hook::exec('actionProductCancel', array('order' => $order, 'id_order_detail' => (int)$id_order_detail));
   }
  if (!count($this->errors) && $customizationList)
   foreach ($customizationList as $id_customization => $id_order_detail)
   {
    $order_detail = new OrderDetail((int)($id_order_detail));
    $qtyCancelProduct = abs($customizationQtyList[$id_customization]);
    if (!$order->deleteCustomization($id_customization, $qtyCancelProduct, $order_detail))
	 $this->errors[] = Tools::displayError('An error occurred during deletion of product customization.').' '.$id_customization;
   }
  // E-mail params
  if ((Tools::isSubmit('generateCreditSlip') || Tools::isSubmit('generateDiscount')) && !count($this->errors))
  {
   $customer = new Customer((int)($order->id_customer));
   $params['{lastname}'] = $customer->lastname;
   $params['{firstname}'] = $customer->firstname;
   $params['{id_order}'] = $order->id;
   $params['{order_name}'] = $order->getUniqReference();
  }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	  // Generate credit slip
  if (Tools::isSubmit('generateCreditSlip') && !count($this->errors))
  {
   if (!OrderSlip::createOrderSlip($order, $full_product_list, $full_quantity_list, Tools::isSubmit('shippingBack')))
    $this->errors[] = Tools::displayError('Cannot generate credit slip');
   else
   {
    Hook::exec('actionOrderSlipAdd', array('order' => $order, 'productList' => $full_product_list, 'qtyList' => $full_quantity_list));
    @Mail::Send(
	 (int)$order->id_lang,
	 'credit_slip',
	 Mail::l('New credit slip regarding your order', $order->id_lang),
	 $params,
	 $customer->email,
	 $customer->firstname.' '.$customer->lastname,
	 null,
	 null,
	 null,
	 null,
	 _PS_MAIL_DIR_,
	 true,
	 (int)$order->id_shop
    );
   }
  }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	  // Generate voucher
  if (Tools::isSubmit('generateDiscount') && !count($this->errors))
  {
   $cartrule = new CartRule();
   $languages = Language::getLanguages($order);
   $cartrule->description = sprintf($this->l('Credit Slip for order #%d'), $order->id);
   foreach ($languages as $language)
   {
    // Define a temporary name
    $cartrule->name[$language['id_lang']] = 'V0C'.(int)($order->id_customer).'O'.(int)($order->id);
   }
   // Define a temporary code
   $cartrule->code = 'V0C'.(int)($order->id_customer).'O'.(int)($order->id);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	   $cartrule->quantity = 1;
   $cartrule->quantity_per_user = 1;
   // Specific to the customer
   $cartrule->id_customer = $order->id_customer;
   $now = time();
   $cartrule->date_from = date('Y-m-d H:i:s', $now);
   $cartrule->date_to = date('Y-m-d H:i:s', $now + (3600 * 24 * 365.25)); /* 1 year */
   $cartrule->active = 1;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	   $products = $order->getProducts(false, $full_product_list, $full_quantity_list);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	   $total = 0;
   foreach ($products as $product)
    $total += $product['unit_price_tax_incl'] * $product['product_quantity'];[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	   if (Tools::isSubmit('shippingBack'))
    $total += $order->total_shipping;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	   $cartrule->reduction_amount = $total;
   $cartrule->reduction_tax = true;
   $cartrule->minimum_amount_currency = $order->id_currency;
   $cartrule->reduction_currency = $order->id_currency;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	   if (!$cartrule->add())
    $this->errors[] = Tools::displayError('Cannot generate voucher');
   else
   {
    // Update the voucher code and name
    foreach ($languages as $language)
	 $cartrule->name[$language['id_lang']] = 'V'.(int)($cartrule->id).'C'.(int)($order->id_customer).'O'.$order->id;
    $cartrule->code = 'V'.(int)($cartrule->id).'C'.(int)($order->id_customer).'O'.$order->id;
    if (!$cartrule->update())
	 $this->errors[] = Tools::displayError('Cannot generate voucher');
    else
    {
	 $currency = $this->context->currency;
	 $params['{voucher_amount}'] = Tools::displayPrice($cartrule->reduction_amount, $currency, false);
	 $params['{voucher_num}'] = $cartrule->code;
	 @Mail::Send((int)$order->id_lang, 'voucher', sprintf(Mail::l('New voucher regarding your order %s', (int)$order->id_lang), $order->reference),
	 $params, $customer->email, $customer->firstname.' '.$customer->lastname, null, null, null,
	 null, _PS_MAIL_DIR_, true, (int)$order->id_shop);
    }
   }
  }
 }
 else
  $this->errors[] = Tools::displayError('No product or quantity selected.');[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	 // Redirect if no errors
 if (!count($this->errors))
  Tools::redirectAdmin(self::$currentIndex.'&id_order='.$order->id.'&vieworder&conf=31&token='.$this->token);
   }
  }
  else
   $this->errors[] = Tools::displayError('You do not have permission to delete here.');
 }
 elseif (Tools::isSubmit('messageReaded'))
  Message::markAsReaded(Tools::getValue('messageReaded'), $this->context->employee->id);
 elseif (Tools::isSubmit('submitAddPayment') && isset($order))
 {
  if ($this->tabAccess['edit'] === '1')
  {
   $amount = str_replace(',', '.', Tools::getValue('payment_amount'));
   $currency = new Currency(Tools::getValue('payment_currency'));
   $order_has_invoice = $order->hasInvoice();
   if ($order_has_invoice)
 $order_invoice = new OrderInvoice(Tools::getValue('payment_invoice'));
   else
 $order_invoice = null;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]    if (!Validate::isLoadedObject($order))
 $this->errors[] = Tools::displayError('Order can\'t be found');
   elseif (!Validate::isNegativePrice($amount))
 $this->errors[] = Tools::displayError('Amount is invalid');
   elseif (!Validate::isString(Tools::getValue('payment_method')))
 $this->errors[] = Tools::displayError('Payment method is invalid');
   elseif (!Validate::isString(Tools::getValue('payment_transaction_id')))
 $this->errors[] = Tools::displayError('Transaction ID is invalid');
   elseif (!Validate::isLoadedObject($currency))
 $this->errors[] = Tools::displayError('Currency is invalid');
   elseif ($order_has_invoice && !Validate::isLoadedObject($order_invoice))
 $this->errors[] = Tools::displayError('Invoice is invalid');
   elseif (!Validate::isDate(Tools::getValue('payment_date')))
 $this->errors[] = Tools::displayError('Date is invalid');
   else
   {
 if (!$order->addOrderPayment($amount, Tools::getValue('payment_method'), Tools::getValue('payment_transaction_id'), $currency, Tools::getValue('payment_date'), $order_invoice))
  $this->errors[] = Tools::displayError('An error occurred on adding order payment');
 else
  Tools::redirectAdmin(self::$currentIndex.'&id_order='.$order->id.'&vieworder&conf=4&token='.$this->token);
   }
  }
  else
   $this->errors[] = Tools::displayError('You do not have permission to edit here.');
 }
 elseif (Tools::isSubmit('submitEditNote'))
 {
  $note = Tools::getValue('note');
  $order_invoice = new OrderInvoice((int)Tools::getValue('id_order_invoice'));
  if (Validate::isLoadedObject($order_invoice) && Validate::isCleanHtml($note))
  {
   if ($this->tabAccess['edit'] === '1')
   {
 $order_invoice->note = $note;
 if ($order_invoice->save())
  Tools::redirectAdmin(self::$currentIndex.'&id_order='.$order_invoice->id_order.'&vieworder&conf=4&token='.$this->token);
 else
  $this->errors[] = Tools::displayError('Unable to save invoice note.');
   }
   else
 $this->errors[] = Tools::displayError('You do not have permission to edit here.');
  }
  else
   $this->errors[] = Tools::displayError('Unable to load invoice for edit note.');
 }
 elseif (Tools::isSubmit('submitAddOrder') && ($id_cart = Tools::getValue('id_cart')) &&
  ($module_name = Tools::getValue('payment_module_name')) &&
  ($id_order_state = Tools::getValue('id_order_state')) && Validate::isModuleName($module_name))
 {
  if ($this->tabAccess['edit'] === '1')
  {
   $payment_module = Module::getInstanceByName($module_name);
   $cart = new Cart((int)$id_cart);
   Context::getContext()->currency = new Currency((int)$cart->id_currency);
   Context::getContext()->customer = new Customer((int)$cart->id_customer);
   $employee = new Employee((int)Context::getContext()->cookie->id_employee);
   $payment_module->validateOrder(
 (int)$cart->id, (int)$id_order_state,
 $cart->getOrderTotal(true, Cart::BOTH), $payment_module->displayName, $this->l('Manual order - Employee:').
 Tools::safeOutput(substr($employee->firstname, 0, 1).'. '.$employee->lastname), array(), null, false, $cart->secure_key
   );
   if ($payment_module->currentOrder)
 Tools::redirectAdmin(self::$currentIndex.'&id_order='.$payment_module->currentOrder.'&vieworder'.'&token='.$this->token);
  }
  else
   $this->errors[] = Tools::displayError('You do not have permission to add here.');
 }
 elseif ((Tools::isSubmit('submitAddressShipping') || Tools::isSubmit('submitAddressInvoice')) && isset($order))
 {
  if ($this->tabAccess['edit'] === '1')
  {
   $address = new Address(Tools::getValue('id_address'));
   if (Validate::isLoadedObject($address))
   {
 // Update the address on order
 if (Tools::isSubmit('submitAddressShipping'))
  $order->id_address_delivery = $address->id;
 elseif (Tools::isSubmit('submitAddressInvoice'))
  $order->id_address_invoice = $address->id;
 $order->update();
 Tools::redirectAdmin(self::$currentIndex.'&id_order='.$order->id.'&vieworder&conf=4&token='.$this->token);
   }
   else
 $this->errors[] = Tools::displayErrror('This address can\'t be loaded');
  }
  else
   $this->errors[] = Tools::displayError('You do not have permission to edit here.');
 }
 elseif (Tools::isSubmit('submitChangeCurrency') && isset($order))
 {
  if ($this->tabAccess['edit'] === '1')
  {
   if (Tools::getValue('new_currency') != $order->id_currency && !$order->valid)
   {
 $old_currency = new Currency($order->id_currency);
 $currency = new Currency(Tools::getValue('new_currency'));
 if (!Validate::isLoadedObject($currency))
  throw new PrestaShopException('Can\'t load Currency object');[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	 // Update order detail amount
 foreach ($order->getOrderDetailList() as $row)
 {
  $order_detail = new OrderDetail($row['id_order_detail']);
  $fields = array(
   'ecotax',
   'product_price',
   'reduction_amount',
   'total_shipping_price_tax_excl',
   'total_shipping_price_tax_incl',
   'total_price_tax_incl',
   'total_price_tax_excl',
   'product_quantity_discount',
   'purchase_supplier_price',
   'reduction_amount',
   'reduction_amount_tax_incl',
   'reduction_amount_tax_excl',
   'unit_price_tax_incl',
   'unit_price_tax_excl',
   'original_product_price'

  );
  foreach ($fields as $field)
   $order_detail->{$field} = Tools::convertPriceFull($order_detail->{$field}, $old_currency, $currency);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	  $order_detail->update();
  $order_detail->updateTaxAmount($order);
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	 $id_order_carrier = Db::getInstance()->getValue('
  SELECT `id_order_carrier`
  FROM `'._DB_PREFIX_.'order_carrier`
  WHERE `id_order` = '.(int)$order->id);
 if ($id_order_carrier)
 {
  $order_carrier = new OrderCarrier($id_order_carrier);
  $order_carrier->shipping_cost_tax_excl = (float)Tools::convertPriceFull($order_carrier->shipping_cost_tax_excl, $old_currency, $currency);
  $order_carrier->shipping_cost_tax_incl = (float)Tools::convertPriceFull($order_carrier->shipping_cost_tax_incl, $old_currency, $currency);
  $order_carrier->update();
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	 // Update order && order_invoice amount
 $fields = array(
  'total_discounts',
  'total_discounts_tax_incl',
  'total_discounts_tax_excl',
  'total_discount_tax_excl',
  'total_discount_tax_incl',
  'total_paid',
  'total_paid_tax_incl',
  'total_paid_tax_excl',
  'total_paid_real',
  'total_products',
  'total_products_wt',
  'total_shipping',
  'total_shipping_tax_incl',
  'total_shipping_tax_excl',
  'total_wrapping',
  'total_wrapping_tax_incl',
  'total_wrapping_tax_excl',
 );[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	 $invoices = $order->getInvoicesCollection();
 if ($invoices)
  foreach ($invoices as $invoice)
  {
   foreach ($fields as $field)
    if (isset($invoice->$field))
	 $invoice->{$field} = Tools::convertPriceFull($invoice->{$field}, $old_currency, $currency);
   $invoice->save();
  }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	 foreach ($fields as $field)
  if (isset($order->$field))
   $order->{$field} = Tools::convertPriceFull($order->{$field}, $old_currency, $currency);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	 // Update currency in order
 $order->id_currency = $currency->id;
 // Update conversion rate
 $order->conversion_rate = (float)$currency->conversion_rate;
 $order->update();
   }
   else
 $this->errors[] = Tools::displayError('You cannot change the currency');
  }
  else
   $this->errors[] = Tools::displayError('You do not have permission to edit here.');
 }
 elseif (Tools::isSubmit('submitGenerateInvoice') && isset($order))
 {
  if (!Configuration::get('PS_INVOICE'))
   $this->errors[] = Tools::displayError('Invoice management has been disabled');
  elseif ($order->hasInvoice())
   $this->errors[] = Tools::displayError('This order already has an invoice');
  else
  {
   $order->setInvoice(true);
   Tools::redirectAdmin(self::$currentIndex.'&id_order='.$order->id.'&vieworder&conf=4&token='.$this->token);
  }
 }
 elseif (Tools::isSubmit('submitDeleteVoucher') && isset($order))
 {
  if ($this->tabAccess['edit'] === '1')
  {
   $order_cart_rule = new OrderCartRule(Tools::getValue('id_order_cart_rule'));
   if (Validate::isLoadedObject($order_cart_rule) && $order_cart_rule->id_order == $order->id)
   {
 if ($order_cart_rule->id_order_invoice)
 {
  $order_invoice = new OrderInvoice($order_cart_rule->id_order_invoice);
  if (!Validate::isLoadedObject($order_invoice))
   throw new PrestaShopException('Can\'t load Order Invoice object');[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	  // Update amounts of Order Invoice
  $order_invoice->total_discount_tax_excl -= $order_cart_rule->value_tax_excl;
  $order_invoice->total_discount_tax_incl -= $order_cart_rule->value;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	  $order_invoice->total_paid_tax_excl += $order_cart_rule->value_tax_excl;
  $order_invoice->total_paid_tax_incl += $order_cart_rule->value;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	  // Update Order Invoice
  $order_invoice->update();
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	 // Update amounts of order
 $order->total_discounts -= $order_cart_rule->value;
 $order->total_discounts_tax_incl -= $order_cart_rule->value;
 $order->total_discounts_tax_excl -= $order_cart_rule->value_tax_excl;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	 $order->total_paid += $order_cart_rule->value;
 $order->total_paid_tax_incl += $order_cart_rule->value;
 $order->total_paid_tax_excl += $order_cart_rule->value_tax_excl;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	 // Delete Order Cart Rule and update Order
 $order_cart_rule->delete();
 $order->update();
 Tools::redirectAdmin(self::$currentIndex.'&id_order='.$order->id.'&vieworder&conf=4&token='.$this->token);
   }
   else
 $this->errors[] = Tools::displayError('Cannot edit this Order Cart Rule');
  }
  else
   $this->errors[] = Tools::displayError('You do not have permission to edit here.');
 }
 elseif (Tools::getValue('submitNewVoucher') && isset($order))
 {
  if ($this->tabAccess['edit'] === '1')
  {
   if (!Tools::getValue('discount_name'))
 $this->errors[] = Tools::displayError('You must specify a name in order to create a new discount');
   else
   {
 if ($order->hasInvoice())
 {
  // If the discount is for only one invoice
  if (!Tools::isSubmit('discount_all_invoices'))
  {
   $order_invoice = new OrderInvoice(Tools::getValue('discount_invoice'));
   if (!Validate::isLoadedObject($order_invoice))
    throw new PrestaShopException('Can\'t load Order Invoice object');
  }
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	 $cart_rules = array();
 switch (Tools::getValue('discount_type'))
 {
  // Percent type
  case 1:
   if (Tools::getValue('discount_value') < 100)
   {
    if (isset($order_invoice))
    {
	 $cart_rules[$order_invoice->id]['value_tax_incl'] = Tools::ps_round($order_invoice->total_paid_tax_incl * Tools::getValue('discount_value') / 100, 2);
	 $cart_rules[$order_invoice->id]['value_tax_excl'] = Tools::ps_round($order_invoice->total_paid_tax_excl * Tools::getValue('discount_value') / 100, 2);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]		 // Update OrderInvoice
	 $this->applyDiscountOnInvoice($order_invoice, $cart_rules[$order_invoice->id]['value_tax_incl'], $cart_rules[$order_invoice->id]['value_tax_excl']);
    }
    elseif ($order->hasInvoice())
    {
	 $order_invoices_collection = $order->getInvoicesCollection();
	 foreach ($order_invoices_collection as $order_invoice)
	 {
	  $cart_rules[$order_invoice->id]['value_tax_incl'] = Tools::ps_round($order_invoice->total_paid_tax_incl * Tools::getValue('discount_value') / 100, 2);
	  $cart_rules[$order_invoice->id]['value_tax_excl'] = Tools::ps_round($order_invoice->total_paid_tax_excl * Tools::getValue('discount_value') / 100, 2);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]		  // Update OrderInvoice
	  $this->applyDiscountOnInvoice($order_invoice, $cart_rules[$order_invoice->id]['value_tax_incl'], $cart_rules[$order_invoice->id]['value_tax_excl']);
	 }
    }
    else
    {
	 $cart_rules[0]['value_tax_incl'] = Tools::ps_round($order->total_paid_tax_incl * Tools::getValue('discount_value') / 100, 2);
	 $cart_rules[0]['value_tax_excl'] = Tools::ps_round($order->total_paid_tax_excl * Tools::getValue('discount_value') / 100, 2);
    }
   }
   else
    $this->errors[] = Tools::displayError('Discount value is invalid');
   break;
  // Amount type
  case 2:
   if (isset($order_invoice))
   {
    if (Tools::getValue('discount_value') > $order_invoice->total_paid_tax_incl)
	 $this->errors[] = Tools::displayError('Discount value is greater than the order invoice total');
    else
    {
	 $cart_rules[$order_invoice->id]['value_tax_incl'] = Tools::ps_round(Tools::getValue('discount_value'), 2);
	 $cart_rules[$order_invoice->id]['value_tax_excl'] = Tools::ps_round(Tools::getValue('discount_value') / (1 + ($order->getTaxesAverageUsed() / 100)), 2);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]		 // Update OrderInvoice
	 $this->applyDiscountOnInvoice($order_invoice, $cart_rules[$order_invoice->id]['value_tax_incl'], $cart_rules[$order_invoice->id]['value_tax_excl']);
    }
   }
   elseif ($order->hasInvoice())
   {
    $order_invoices_collection = $order->getInvoicesCollection();
    foreach ($order_invoices_collection as $order_invoice)
    {
	 if (Tools::getValue('discount_value') > $order_invoice->total_paid_tax_incl)
	  $this->errors[] = Tools::displayError('Discount value is greater than the order invoice total (Invoice:').$order_invoice->getInvoiceNumberFormatted(Context::getContext()->language->id).')';
	 else
	 {
	  $cart_rules[$order_invoice->id]['value_tax_incl'] = Tools::ps_round(Tools::getValue('discount_value'), 2);
	  $cart_rules[$order_invoice->id]['value_tax_excl'] = Tools::ps_round(Tools::getValue('discount_value') / (1 + ($order->getTaxesAverageUsed() / 100)), 2);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]		  // Update OrderInvoice
	  $this->applyDiscountOnInvoice($order_invoice, $cart_rules[$order_invoice->id]['value_tax_incl'], $cart_rules[$order_invoice->id]['value_tax_excl']);
	 }
    }
   }
   else
   {
    if (Tools::getValue('discount_value') > $order->total_paid_tax_incl)
	 $this->errors[] = Tools::displayError('Discount value is greater than the order total');
    else
    {
	 $cart_rules[0]['value_tax_incl'] = Tools::ps_round(Tools::getValue('discount_value'), 2);
	 $cart_rules[0]['value_tax_excl'] = Tools::ps_round(Tools::getValue('discount_value') / (1 + ($order->getTaxesAverageUsed() / 100)), 2);
    }
   }
   break;
  // Free shipping type
  case 3:
   if (isset($order_invoice))
   {
    if ($order_invoice->total_shipping_tax_incl > 0)
    {
	 $cart_rules[$order_invoice->id]['value_tax_incl'] = $order_invoice->total_shipping_tax_incl;
	 $cart_rules[$order_invoice->id]['value_tax_excl'] = $order_invoice->total_shipping_tax_excl;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]		 // Update OrderInvoice
	 $this->applyDiscountOnInvoice($order_invoice, $cart_rules[$order_invoice->id]['value_tax_incl'], $cart_rules[$order_invoice->id]['value_tax_excl']);
    }
   }
   elseif ($order->hasInvoice())
   {
    $order_invoices_collection = $order->getInvoicesCollection();
    foreach ($order_invoices_collection as $order_invoice)
    {
	 if ($order_invoice->total_shipping_tax_incl <= 0)
	  continue;
	 $cart_rules[$order_invoice->id]['value_tax_incl'] = $order_invoice->total_shipping_tax_incl;
	 $cart_rules[$order_invoice->id]['value_tax_excl'] = $order_invoice->total_shipping_tax_excl;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]		 // Update OrderInvoice
	 $this->applyDiscountOnInvoice($order_invoice, $cart_rules[$order_invoice->id]['value_tax_incl'], $cart_rules[$order_invoice->id]['value_tax_excl']);
    }
   }
   else
   {
    $cart_rules[0]['value_tax_incl'] = $order->total_shipping_tax_incl;
    $cart_rules[0]['value_tax_excl'] = $order->total_shipping_tax_excl;
   }
   break;
  default:
   $this->errors[] = Tools::displayError('Discount type is invalid');
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	 $res = true;
 foreach ($cart_rules as &$cart_rule)
 {
  $cartRuleObj = new CartRule();
  $cartRuleObj->date_from = date('Y-m-d H:i:s', strtotime('-1 hour', strtotime($order->date_add)));
  $cartRuleObj->date_to = date('Y-m-d H:i:s', strtotime('+1 hour'));
  $cartRuleObj->name[Configuration::get('PS_LANG_DEFAULT')] = Tools::getValue('discount_name');
  $cartRuleObj->quantity = 0;
  $cartRuleObj->quantity_per_user = 1;
  if (Tools::getValue('discount_type') == 1)
   $cartRuleObj->reduction_percent = Tools::getValue('discount_value');
  elseif (Tools::getValue('discount_type') == 2)
   $cartRuleObj->reduction_amount = $cart_rule['value_tax_excl'];
  elseif (Tools::getValue('discount_type') == 3)
   $cartRuleObj->free_shipping = 1;
  $cartRuleObj->active = 0;
  if ($res = $cartRuleObj->add())
   $cart_rule['id'] = $cartRuleObj->id;
  else
   break;
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	 if ($res)
 {
  foreach ($cart_rules as $id_order_invoice => $cart_rule)
  {
   // Create OrderCartRule
   $order_cart_rule = new OrderCartRule();
   $order_cart_rule->id_order = $order->id;
   $order_cart_rule->id_cart_rule = $cart_rule['id'];
   $order_cart_rule->id_order_invoice = $id_order_invoice;
   $order_cart_rule->name = Tools::getValue('discount_name');
   $order_cart_rule->value = $cart_rule['value_tax_incl'];
   $order_cart_rule->value_tax_excl = $cart_rule['value_tax_excl'];
   $res &= $order_cart_rule->add();[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	   $order->total_discounts += $order_cart_rule->value;
   $order->total_discounts_tax_incl += $order_cart_rule->value;
   $order->total_discounts_tax_excl += $order_cart_rule->value_tax_excl;
   $order->total_paid -= $order_cart_rule->value;
   $order->total_paid_tax_incl -= $order_cart_rule->value;
   $order->total_paid_tax_excl -= $order_cart_rule->value_tax_excl;
  }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	  // Update Order
  $res &= $order->update();
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	 if ($res)
  Tools::redirectAdmin(self::$currentIndex.'&id_order='.$order->id.'&vieworder&conf=4&token='.$this->token);
 else
  $this->errors[] = Tools::displayError('An error occurred on OrderCartRule creation');
   }
  }
  else
   $this->errors[] = Tools::displayError('You do not have permission to edit here.');
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  parent::postProcess();
}[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]public function renderView()
{
 $order = new Order(Tools::getValue('id_order'));
 if (!Validate::isLoadedObject($order))
  throw new PrestaShopException('object can\'t be loaded');[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $customer = new Customer($order->id_customer);
 $carrier = new Carrier($order->id_carrier);
 $products = $this->getProducts($order);
 $currency = new Currency((int)$order->id_currency);
 // Carrier module call
 $carrier_module_call = null;
 if ($carrier->is_module)
 {
  $module = Module::getInstanceByName($carrier->external_module_name);
  if (method_exists($module, 'displayInfoByCart'))
   $carrier_module_call = call_user_func(array($module, 'displayInfoByCart'), $order->id_cart);
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // Retrieve addresses information
 $addressInvoice = new Address($order->id_address_invoice, $this->context->language->id);
 if (Validate::isLoadedObject($addressInvoice) && $addressInvoice->id_state)
  $invoiceState = new State((int)$addressInvoice->id_state);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  if ($order->id_address_invoice == $order->id_address_delivery)
 {
  $addressDelivery = $addressInvoice;
  if (isset($invoiceState))
   $deliveryState = $invoiceState;
 }
 else
 {
  $addressDelivery = new Address($order->id_address_delivery, $this->context->language->id);
  if (Validate::isLoadedObject($addressDelivery) && $addressDelivery->id_state)
   $deliveryState = new State((int)($addressDelivery->id_state));
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $this->toolbar_title = sprintf($this->l('Order #%1$d (%2$s) - %3$s %4$s'), $order->id, $order->reference, $customer->firstname, $customer->lastname);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // gets warehouses to ship products, if and only if advanced stock management is activated
 $warehouse_list = null;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $order_details = $order->getOrderDetailList();
 foreach ($order_details as $order_detail)
 {
  $product = new Product($order_detail['product_id']);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]   if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')
   && $product->advanced_stock_management)
  {
   $warehouses = Warehouse::getWarehousesByProductId($order_detail['product_id'], $order_detail['product_attribute_id']);
   foreach ($warehouses as $warehouse)
   {
 if (!isset($warehouse_list[$warehouse['id_warehouse']]))
  $warehouse_list[$warehouse['id_warehouse']] = $warehouse;
   }
  }
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $payment_methods = array();
 foreach (PaymentModule::getInstalledPaymentModules() as $payment)
 {
  $module = Module::getInstanceByName($payment['name']);
  if (Validate::isLoadedObject($module))
   $payment_methods[] = $module->displayName;
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // display warning if there are products out of stock
 $display_out_of_stock_warning = false;
 $current_order_state = $order->getCurrentOrderState();
 if ($current_order_state->delivery != 1 && $current_order_state->shipped != 1)
  $display_out_of_stock_warning = true;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // products current stock (from stock_available)
 foreach ($products as &$product)
 {
  $product['current_stock'] = StockAvailable::getQuantityAvailableByProduct($product['product_id'], $product['product_attribute_id'], $product['id_shop']);

  $resume = OrderSlip::getProductSlipResume($product['id_order_detail']);
  $product['quantity_refundable'] = $product['product_quantity'] - $resume['product_quantity'];
  $product['amount_refundable'] = $product['total_price_tax_incl'] - $resume['amount_tax_incl'];
  $product['amount_refund'] = Tools::displayPrice($resume['amount_tax_incl'], $currency);
  $product['refund_history'] = OrderSlip::getProductSlipDetail($product['id_order_detail']);
  $product['return_history'] = OrderReturn::getProductReturnDetail($product['id_order_detail']);

  // if the current stock requires a warning
  if ($product['current_stock'] == 0 && $display_out_of_stock_warning)
   $this->displayWarning($this->l('This product is out of stock: ').' '.$product['product_name']);
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // Smarty assign
 $this->tpl_view_vars = array(
  'order' => $order,
  'cart' => new Cart($order->id_cart),
  'customer' => $customer,
  'customer_addresses' => $customer->getAddresses($this->context->language->id),
  'addresses' => array(
   'delivery' => $addressDelivery,
   'deliveryState' => isset($deliveryState) ? $deliveryState : null,
   'invoice' => $addressInvoice,
   'invoiceState' => isset($invoiceState) ? $invoiceState : null
  ),
  'customerStats' => $customer->getStats(),
  'products' => $products,
  'discounts' => $order->getCartRules(),
  'orders_total_paid_tax_incl' => $order->getOrdersTotalPaid(), // Get the sum of total_paid_tax_incl of the order with similar reference
  'total_paid' => $order->getTotalPaid(),
  'returns' => OrderReturn::getOrdersReturn($order->id_customer, $order->id),
  'customer_thread_message' => CustomerThread::getCustomerMessages($order->id_customer, 0),
  'orderMessages' => OrderMessage::getOrderMessages($order->id_lang),
  'messages' => Message::getMessagesByOrderId($order->id, true),
  'carrier' => new Carrier($order->id_carrier),
  'history' => $order->getHistory($this->context->language->id),
  'states' => OrderState::getOrderStates($this->context->language->id),
  'warehouse_list' => $warehouse_list,
  'sources' => ConnectionsSource::getOrderSources($order->id),
  'currentState' => $order->getCurrentOrderState(),
  'currency' => new Currency($order->id_currency),
  'currencies' => Currency::getCurrencies(),
  'previousOrder' => $order->getPreviousOrderId(),
  'nextOrder' => $order->getNextOrderId(),
  'current_index' => self::$currentIndex,
  'carrierModuleCall' => $carrier_module_call,
  'iso_code_lang' => $this->context->language->iso_code,
  'id_lang' => $this->context->language->id,
  'can_edit' => ($this->tabAccess['edit'] == 1),
  'current_id_lang' => $this->context->language->id,
  'invoices_collection' => $order->getInvoicesCollection(),
  'not_paid_invoices_collection' => $order->getNotPaidInvoicesCollection(),
  'payment_methods' => $payment_methods,
  'invoice_management_active' => Configuration::get('PS_INVOICE')
 );[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  return parent::renderView();
}[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]public function ajaxProcessSearchCustomers()
{
 if ($customers = Customer::searchByName(pSQL(Tools::getValue('customer_search'))))
  $to_return = array('customers' => $customers,
	 'found' => true);
 else
  $to_return = array('found' => false);
 $this->content = Tools::jsonEncode($to_return);
}[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]public function ajaxProcessSearchProducts()
{
 Context::getContext()->customer = new Customer((int)Tools::getValue('id_customer'));
 $currency = new Currency((int)Tools::getValue('id_currency'));
 if ($products = Product::searchByName((int)$this->context->language->id, pSQL(Tools::getValue('product_search'))))
 {
  foreach ($products as &$product)
  {
   // Formatted price
   $product['formatted_price'] = Tools::displayPrice(Tools::convertPrice($product['price_tax_incl'], $currency), $currency);
   // Concret price
   $product['price_tax_incl'] = Tools::ps_round(Tools::convertPrice($product['price_tax_incl'], $currency), 2);
   $product['price_tax_excl'] = Tools::ps_round(Tools::convertPrice($product['price_tax_excl'], $currency), 2);
   $productObj = new Product((int)$product['id_product'], false, (int)$this->context->language->id);
   $combinations = array();
   $attributes = $productObj->getAttributesGroups((int)$this->context->language->id);

   // Tax rate for this customer
   if (Tools::isSubmit('id_address'))
 $product['tax_rate'] = $productObj->getTaxesRate(new Address(Tools::getValue('id_address')));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]    $product['warehouse_list'] = array();[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]    foreach ($attributes as $attribute)
   {
 if (!isset($combinations[$attribute['id_product_attribute']]['attributes']))
  $combinations[$attribute['id_product_attribute']]['attributes'] = '';
 $combinations[$attribute['id_product_attribute']]['attributes'] .= $attribute['attribute_name'].' - ';
 $combinations[$attribute['id_product_attribute']]['id_product_attribute'] = $attribute['id_product_attribute'];
 $combinations[$attribute['id_product_attribute']]['default_on'] = $attribute['default_on'];
 if (!isset($combinations[$attribute['id_product_attribute']]['price']))
 {
  $price_tax_incl = Product::getPriceStatic((int)$product['id_product'], true, $attribute['id_product_attribute']);
  $price_tax_excl = Product::getPriceStatic((int)$product['id_product'], false, $attribute['id_product_attribute']);
  $combinations[$attribute['id_product_attribute']]['price_tax_incl'] = Tools::ps_round(Tools::convertPrice($price_tax_incl, $currency), 2);
  $combinations[$attribute['id_product_attribute']]['price_tax_excl'] = Tools::ps_round(Tools::convertPrice($price_tax_excl, $currency), 2);
  $combinations[$attribute['id_product_attribute']]['formatted_price'] = Tools::displayPrice(Tools::convertPrice($price_tax_excl, $currency), $currency);
 }
 if (!isset($combinations[$attribute['id_product_attribute']]['qty_in_stock']))
  $combinations[$attribute['id_product_attribute']]['qty_in_stock'] = StockAvailable::getQuantityAvailableByProduct((int)$product['id_product'], $attribute['id_product_attribute'], (int)$this->context->shop->id);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	 if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') && (int)$product['advanced_stock_management'] == 1)
  $product['warehouse_list'][$attribute['id_product_attribute']] = Warehouse::getProductWarehouseList($product['id_product'], $attribute['id_product_attribute']);
 else
  $product['warehouse_list'][$attribute['id_product_attribute']] = array();[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	 $product['stock'][$attribute['id_product_attribute']] = Product::getRealQuantity($product['id_product'], $attribute['id_product_attribute']);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]    }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]    if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') && (int)$product['advanced_stock_management'] == 1)
 $product['warehouse_list'][0] = Warehouse::getProductWarehouseList($product['id_product']);
   else
 $product['warehouse_list'][0] = array();[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]    $product['stock'][0] = StockAvailable::getQuantityAvailableByProduct((int)$product['id_product'], 0, (int)$this->context->shop->id);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]    foreach ($combinations as &$combination)
 $combination['attributes'] = rtrim($combination['attributes'], ' - ');
   $product['combinations'] = $combinations;

   if ($product['customizable'])
   {
 $product_instance = new Product((int)$product['id_product']);
 $product['customization_fields'] = $product_instance->getCustomizationFields($this->context->language->id);
   }
  }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]   $to_return = array(
   'products' => $products,
   'found' => true
  );
 }
 else
  $to_return = array('found' => false);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $this->content = Tools::jsonEncode($to_return);
}[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]public function ajaxProcessSendMailValidateOrder()
{
 if ($this->tabAccess['edit'] === '1')
 {
  $cart = new Cart((int)Tools::getValue('id_cart'));
  if (Validate::isLoadedObject($cart))
  {
   $customer = new Customer((int)$cart->id_customer);
   if (Validate::isLoadedObject($customer))
   {
 $mailVars = array(
  '{order_link}' => Context::getContext()->link->getPageLink('order', false, (int)$cart->id_lang, 'step=3&recover_cart='.(int)$cart->id.'&token_cart='.md5(_COOKIE_KEY_.'recover_cart_'.(int)$cart->id)),
  '{firstname}' => $customer->firstname,
  '{lastname}' => $customer->lastname
 );
 if (Mail::Send((int)$cart->id_lang, 'backoffice_order', Mail::l('Process the payment of your order', (int)$cart->id_lang), $mailVars, $customer->email,
   $customer->firstname.' '.$customer->lastname, null, null, null, null, _PS_MAIL_DIR_, true, $cart->id_shop))
  die(Tools::jsonEncode(array('errors' => false, 'result' => $this->l('The mail was sent to your customer.'))));
   }
  }
  $this->content = Tools::jsonEncode(array('errors' => true, 'result' => $this->l('Error in sending the e-mail to your customer.')));
 }
}[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]public function ajaxProcessAddProductOnOrder()
{
 // Load object
 $order = new Order((int)Tools::getValue('id_order'));
 if (!Validate::isLoadedObject($order))
  die(Tools::jsonEncode(array(
   'result' => false,
   'error' => Tools::displayError('Can\'t load Order object')
  )));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  if ($order->hasBeenShipped())
  die(Tools::jsonEncode(array(
   'result' => false,
   'error' => Tools::displayError('Can\'t add a product on delivered order')
  )));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $product_informations = $_POST['add_product'];
 if (isset($_POST['add_invoice']))
  $invoice_informations = $_POST['add_invoice'];
 else
  $invoice_informations = array();
 $product = new Product($product_informations['product_id'], false, $order->id_lang);
 if (!Validate::isLoadedObject($product))
  die(Tools::jsonEncode(array(
   'result' => false,
   'error' => Tools::displayError('Can\'t load Product object')
  )));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  if (isset($product_informations['product_attribute_id']) && $product_informations['product_attribute_id'])
 {
  $combination = new Combination($product_informations['product_attribute_id']);
  if (!Validate::isLoadedObject($combination))
   die(Tools::jsonEncode(array(
   'result' => false,
   'error' => Tools::displayError('Can\'t load Combination object')
  )));
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // Total method
 $total_method = Cart::BOTH_WITHOUT_SHIPPING;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // Create new cart
 $cart = new Cart();
 $cart->id_shop_group = $order->id_shop_group;
 $cart->id_shop = $order->id_shop;
 $cart->id_customer = $order->id_customer;
 $cart->id_carrier = $order->id_carrier;
 $cart->id_address_delivery = $order->id_address_delivery;
 $cart->id_address_invoice = $order->id_address_invoice;
 $cart->id_currency = $order->id_currency;
 $cart->id_lang = $order->id_lang;
 $cart->secure_key = $order->secure_key;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // Save new cart
 $cart->add();[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // Save context (in order to apply cart rule)
 $this->context->cart = $cart;
 $this->context->customer = new Customer($order->id_customer);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // always add taxes even if there are not displayed to the customer
 $use_taxes = true;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $initial_product_price_tax_incl = Product::getPriceStatic($product->id, $use_taxes, isset($combination) ? $combination->id : null, 2, null, false, true, 1,
  false, $order->id_customer, $cart->id, $order->{Configuration::get('PS_TAX_ADDRESS_TYPE')});[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // Creating specific price if needed
 if ($product_informations['product_price_tax_incl'] != $initial_product_price_tax_incl)
 {
  $specific_price = new SpecificPrice();
  $specific_price->id_shop = 0;
  $specific_price->id_shop_group = 0;
  $specific_price->id_currency = 0;
  $specific_price->id_country = 0;
  $specific_price->id_group = 0;
  $specific_price->id_customer = $order->id_customer;
  $specific_price->id_product = $product->id;
  if (isset($combination))
   $specific_price->id_product_attribute = $combination->id;
  else
   $specific_price->id_product_attribute = 0;
  $specific_price->price = $product_informations['product_price_tax_excl'];
  $specific_price->from_quantity = 1;
  $specific_price->reduction = 0;
  $specific_price->reduction_type = 'amount';
  $specific_price->from = '0000-00-00 00:00:00';
  $specific_price->to = '0000-00-00 00:00:00';
  $specific_price->add();
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // Add product to cart
 $update_quantity = $cart->updateQty($product_informations['product_quantity'], $product->id, isset($product_informations['product_attribute_id']) ? $product_informations['product_attribute_id'] : null,
  isset($combination) ? $combination->id : null, 'up', 0, new Shop($cart->id_shop));

 if ($update_quantity < 0)
 {
  // If product has attribute, minimal quantity is set with minimal quantity of attribute
  $minimal_quantity = ($product_informations['product_attribute_id']) ? Attribute::getAttributeMinimalQty($product_informations['product_attribute_id']) : $product->minimal_quantity;
  die(Tools::jsonEncode(array('error' => sprintf(Tools::displayError('You must add %d minimum quantity', false), $minimal_quantity))));
 }
 elseif (!$update_quantity)
  die(Tools::jsonEncode(array('error' => Tools::displayError('You already have the maximum quantity available for this product.', false))));

 // If order is valid, we can create a new invoice or edit an existing invoice
 if ($order->hasInvoice())
 {
  $order_invoice = new OrderInvoice($product_informations['invoice']);
  // Create new invoice
  if ($order_invoice->id == 0)
  {
   // If we create a new invoice, we calculate shipping cost
   $total_method = Cart::BOTH;
   // Create Cart rule in order to make free shipping
   if (isset($invoice_informations['free_shipping']) && $invoice_informations['free_shipping'])
   {
 $cart_rule = new CartRule();
 $cart_rule->id_customer = $order->id_customer;
 $cart_rule->name = array(
  Configuration::get('PS_LANG_DEFAULT') => $this->l('[Generated] CartRule for Free Shipping')
 );
 $cart_rule->date_from = date('Y-m-d H:i:s', time());
 $cart_rule->date_to = date('Y-m-d H:i:s', time() + 24 * 3600);
 $cart_rule->quantity = 1;
 $cart_rule->quantity_per_user = 1;
 $cart_rule->minimum_amount_currency = $order->id_currency;
 $cart_rule->reduction_currency = $order->id_currency;
 $cart_rule->free_shipping = true;
 $cart_rule->active = 1;
 $cart_rule->add();[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	 // Add cart rule to cart and in order
 $cart->addCartRule($cart_rule->id);
 $values = array(
  'tax_incl' => $cart_rule->getContextualValue(true),
  'tax_excl' => $cart_rule->getContextualValue(false)
 );
 $order->addCartRule($cart_rule->id, $cart_rule->name[Configuration::get('PS_LANG_DEFAULT')], $values);
   }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]    $order_invoice->id_order = $order->id;
   if ($order_invoice->number)
 Configuration::updateValue('PS_INVOICE_START_NUMBER', false);
   else
 $order_invoice->number = Order::getLastInvoiceNumber() + 1;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]    $invoice_address = new Address((int)$order->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
   $carrier = new Carrier((int)$order->id_carrier);
   $tax_calculator = $carrier->getTaxCalculator($invoice_address);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]    $order_invoice->total_paid_tax_excl = Tools::ps_round((float)$cart->getOrderTotal(false, $total_method), 2);
   $order_invoice->total_paid_tax_incl = Tools::ps_round((float)$cart->getOrderTotal($use_taxes, $total_method), 2);
   $order_invoice->total_products = (float)$cart->getOrderTotal(false, Cart::ONLY_PRODUCTS);
   $order_invoice->total_products_wt = (float)$cart->getOrderTotal($use_taxes, Cart::ONLY_PRODUCTS);
   $order_invoice->total_shipping_tax_excl = (float)$cart->getTotalShippingCost(null, false);
   $order_invoice->total_shipping_tax_incl = (float)$cart->getTotalShippingCost();[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]    $order_invoice->total_wrapping_tax_excl = abs($cart->getOrderTotal(false, Cart::ONLY_WRAPPING));
   $order_invoice->total_wrapping_tax_incl = abs($cart->getOrderTotal($use_taxes, Cart::ONLY_WRAPPING));
   $order_invoice->shipping_tax_computation_method = (int)$tax_calculator->computation_method;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]    // Update current order field, only shipping because other field is updated later
   $order->total_shipping += $order_invoice->total_shipping_tax_incl;
   $order->total_shipping_tax_excl += $order_invoice->total_shipping_tax_excl;
   $order->total_shipping_tax_incl += ($use_taxes) ? $order_invoice->total_shipping_tax_incl : $order_invoice->total_shipping_tax_excl;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]    $order->total_wrapping += abs($cart->getOrderTotal($use_taxes, Cart::ONLY_WRAPPING));
   $order->total_wrapping_tax_excl += abs($cart->getOrderTotal(false, Cart::ONLY_WRAPPING));
   $order->total_wrapping_tax_incl += abs($cart->getOrderTotal($use_taxes, Cart::ONLY_WRAPPING));
   $order_invoice->add();[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]    $order_invoice->saveCarrierTaxCalculator($tax_calculator->getTaxesAmount($order_invoice->total_shipping_tax_excl));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]    $order_carrier = new OrderCarrier();
   $order_carrier->id_order = (int)$order->id;
   $order_carrier->id_carrier = (int)$order->id_carrier;
   $order_carrier->id_order_invoice = (int)$order_invoice->id;
   $order_carrier->weight = (float)$cart->getTotalWeight();
   $order_carrier->shipping_cost_tax_excl = (float)$order_invoice->total_shipping_tax_excl;
   $order_carrier->shipping_cost_tax_incl = ($use_taxes) ? (float)$order_invoice->total_shipping_tax_incl : (float)$order_invoice->total_shipping_tax_excl;
   $order_carrier->add();
  }
  // Update current invoice
  else
  {
   $order_invoice->total_paid_tax_excl += Tools::ps_round((float)($cart->getOrderTotal(false, $total_method)), 2);
   $order_invoice->total_paid_tax_incl += Tools::ps_round((float)($cart->getOrderTotal($use_taxes, $total_method)), 2);
   $order_invoice->total_products += (float)$cart->getOrderTotal(false, Cart::ONLY_PRODUCTS);
   $order_invoice->total_products_wt += (float)$cart->getOrderTotal($use_taxes, Cart::ONLY_PRODUCTS);
   $order_invoice->update();
  }
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // Create Order detail information
 $order_detail = new OrderDetail();
 $order_detail->createList($order, $cart, $order->getCurrentOrderState(), $cart->getProducts(), (isset($order_invoice) ? $order_invoice->id : 0), $use_taxes, (int)Tools::getValue('add_product_warehouse'));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // update totals amount of order
 $order->total_products += (float)$cart->getOrderTotal(false, Cart::ONLY_PRODUCTS);
 $order->total_products_wt += (float)$cart->getOrderTotal($use_taxes, Cart::ONLY_PRODUCTS);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $order->total_paid += Tools::ps_round((float)($cart->getOrderTotal(true, $total_method)), 2);
 $order->total_paid_tax_excl += Tools::ps_round((float)($cart->getOrderTotal(false, $total_method)), 2);
 $order->total_paid_tax_incl += Tools::ps_round((float)($cart->getOrderTotal($use_taxes, $total_method)), 2);

 if (isset($order_invoice) && Validate::isLoadedObject($order_invoice))
 {
  $order->total_shipping = $order_invoice->total_shipping_tax_incl;
  $order->total_shipping_tax_incl = $order_invoice->total_shipping_tax_incl;
  $order->total_shipping_tax_excl = $order_invoice->total_shipping_tax_excl;
 }
 // discount
 $order->total_discounts += (float)abs($cart->getOrderTotal(true, Cart::ONLY_DISCOUNTS));
 $order->total_discounts_tax_excl += (float)abs($cart->getOrderTotal(false, Cart::ONLY_DISCOUNTS));
 $order->total_discounts_tax_incl += (float)abs($cart->getOrderTotal(true, Cart::ONLY_DISCOUNTS));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // Save changes of order
 $order->update();[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // Update Tax lines
 $order_detail->updateTaxAmount($order);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // Delete specific price if exists
 if (isset($specific_price))
  $specific_price->delete();[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $products = $this->getProducts($order);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // Get the last product
 $product = end($products);
 $resume = OrderSlip::getProductSlipResume((int)$product['id_order_detail']);
 $product['quantity_refundable'] = $product['product_quantity'] - $resume['product_quantity'];
 $product['amount_refundable'] = $product['total_price_tax_incl'] - $resume['amount_tax_incl'];
 $product['amount_refund'] = Tools::displayPrice($resume['amount_tax_incl']);
 $product['return_history'] = OrderReturn::getProductReturnDetail((int)$product['id_order_detail']);
 $product['refund_history'] = OrderSlip::getProductSlipDetail((int)$product['id_order_detail']);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // Get invoices collection
 $invoice_collection = $order->getInvoicesCollection();[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $invoice_array = array();
 foreach ($invoice_collection as $invoice)
 {
  $invoice->name = $invoice->getInvoiceNumberFormatted(Context::getContext()->language->id);
  $invoice_array[] = $invoice;
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // Assign to smarty informations in order to show the new product line
 $this->context->smarty->assign(array(
  'product' => $product,
  'order' => $order,
  'currency' => new Currency($order->id_currency),
  'can_edit' => $this->tabAccess['edit'],
  'invoices_collection' => $invoice_collection,
  'current_id_lang' => Context::getContext()->language->id,
  'link' => Context::getContext()->link,
  'current_index' => self::$currentIndex
 ));

 $this->sendChangedNotification($order);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  die(Tools::jsonEncode(array(
  'result' => true,
  'view' => $this->createTemplate('_product_line.tpl')->fetch(),
  'can_edit' => $this->tabAccess['add'],
  'order' => $order,
  'invoices' => $invoice_array,
  'documents_html' => $this->createTemplate('_documents.tpl')->fetch(),
  'shipping_html' => $this->createTemplate('_shipping.tpl')->fetch(),
  'discount_form_html' => $this->createTemplate('_discount_form.tpl')->fetch()
 )));
}

public function sendChangedNotification(Order $order = null)
{
 if (is_null($order))
  $order = new Order(Tools::getValue('id_order'));

 $data = array(
  '{lastname}' => $order->getCustomer()->lastname,
  '{firstname}' => $order->getCustomer()->firstname,
  '{id_order}' => (int)$order->id,
  '{order_name}' => $order->getUniqReference()
 );

 Mail::Send(
  (int)$order->id_lang,
  'order_changed',
  Mail::l('Your order has been changed', $order->id_lang),
  $data,
  $order->getCustomer()->email,
  $order->getCustomer()->firstname.' '.$order->getCustomer()->lastname,
  null, null, null, null, _PS_MAIL_DIR_, true, (int)$order->id_shop);
}[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]public function ajaxProcessLoadProductInformation()
{
 $order_detail = new OrderDetail(Tools::getValue('id_order_detail'));
 if (!Validate::isLoadedObject($order_detail))
  die(Tools::jsonEncode(array(
   'result' => false,
   'error' => Tools::displayError('Can\'t load OrderDetail object')
  )));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $product = new Product($order_detail->product_id);
 if (!Validate::isLoadedObject($product))
  die(Tools::jsonEncode(array(
   'result' => false,
   'error' => Tools::displayError('Can\'t load Product object')
  )));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $address = new Address(Tools::getValue('id_address'));
 if (!Validate::isLoadedObject($address))
  die(Tools::jsonEncode(array(
   'result' => false,
   'error' => Tools::displayError('Can\'t load Address object')
  )));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  die(Tools::jsonEncode(array(
  'result' => true,
  'product' => $product,
  'tax_rate' => $product->getTaxesRate($address),
  'price_tax_incl' => Product::getPriceStatic($product->id, true, $order_detail->product_attribute_id, 2),
  'price_tax_excl' => Product::getPriceStatic($product->id, false, $order_detail->product_attribute_id, 2)
 )));
}[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]public function ajaxProcessEditProductOnOrder()
{
 // Return value
 $res = true;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $order = new Order((int)Tools::getValue('id_order'));
 $order_detail = new OrderDetail((int)Tools::getValue('product_id_order_detail'));
 if (Tools::isSubmit('product_invoice'))
  $order_invoice = new OrderInvoice((int)Tools::getValue('product_invoice'));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // Check fields validity
 $this->doEditProductValidation($order_detail, $order, isset($order_invoice) ? $order_invoice : null);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // If multiple product_quantity, the order details concern a product customized
 $product_quantity = 0;
 if (is_array(Tools::getValue('product_quantity')))
  foreach (Tools::getValue('product_quantity') as $id_customization => $qty)
  {
   // Update quantity of each customization
   Db::getInstance()->update('customization', array('quantity' => $qty), 'id_customization = '.(int)$id_customization);
   // Calculate the real quantity of the product
   $product_quantity += $qty;
  }
 else
  $product_quantity = Tools::getValue('product_quantity');[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $product_price_tax_incl = Tools::ps_round(Tools::getValue('product_price_tax_incl'), 2);
 $product_price_tax_excl = Tools::ps_round(Tools::getValue('product_price_tax_excl'), 2);
 $total_products_tax_incl = $product_price_tax_incl * $product_quantity;
 $total_products_tax_excl = $product_price_tax_excl * $product_quantity;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // Calculate differences of price (Before / After)
 $diff_price_tax_incl = $total_products_tax_incl - $order_detail->total_price_tax_incl;
 $diff_price_tax_excl = $total_products_tax_excl - $order_detail->total_price_tax_excl;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // Apply change on OrderInvoice
 if (isset($order_invoice))
  // If OrderInvoice to use is different, we update the old invoice and new invoice
  if ($order_detail->id_order_invoice != $order_invoice->id)
  {
   $old_order_invoice = new OrderInvoice($order_detail->id_order_invoice);
   // We remove cost of products
   $old_order_invoice->total_products -= $order_detail->total_price_tax_excl;
   $old_order_invoice->total_products_wt -= $order_detail->total_price_tax_incl;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]    $old_order_invoice->total_paid_tax_excl -= $order_detail->total_price_tax_excl;
   $old_order_invoice->total_paid_tax_incl -= $order_detail->total_price_tax_incl;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]    $res &= $old_order_invoice->update();[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]    $order_invoice->total_products += $order_detail->total_price_tax_excl;
   $order_invoice->total_products_wt += $order_detail->total_price_tax_incl;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]    $order_invoice->total_paid_tax_excl += $order_detail->total_price_tax_excl;
   $order_invoice->total_paid_tax_incl += $order_detail->total_price_tax_incl;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]    $order_detail->id_order_invoice = $order_invoice->id;
  }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  if ($diff_price_tax_incl != 0 && $diff_price_tax_excl != 0)
 {
  $order_detail->unit_price_tax_excl = $product_price_tax_excl;
  $order_detail->unit_price_tax_incl = $product_price_tax_incl;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]   $order_detail->total_price_tax_incl += $diff_price_tax_incl;
  $order_detail->total_price_tax_excl += $diff_price_tax_excl;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]   if (isset($order_invoice))
  {
   // Apply changes on OrderInvoice
   $order_invoice->total_products += $diff_price_tax_excl;
   $order_invoice->total_products_wt += $diff_price_tax_incl;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]    $order_invoice->total_paid_tax_excl += $diff_price_tax_excl;
   $order_invoice->total_paid_tax_incl += $diff_price_tax_incl;
  }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]   // Apply changes on Order
  $order = new Order($order_detail->id_order);
  $order->total_products += $diff_price_tax_excl;
  $order->total_products_wt += $diff_price_tax_incl;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]   $order->total_paid += $diff_price_tax_incl;
  $order->total_paid_tax_excl += $diff_price_tax_excl;
  $order->total_paid_tax_incl += $diff_price_tax_incl;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]   $res &= $order->update();
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $old_quantity = $order_detail->product_quantity;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $order_detail->product_quantity = $product_quantity;

 // update taxes
 $res &= $order_detail->updateTaxAmount($order);

 // Save order detail
 $res &= $order_detail->update();
 // Save order invoice
 if (isset($order_invoice))
   $res &= $order_invoice->update();[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // Update product available quantity
 StockAvailable::updateQuantity($order_detail->product_id, $order_detail->product_attribute_id, ($old_quantity - $order_detail->product_quantity), $order->id_shop);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $products = $this->getProducts($order);
 // Get the last product
 $product = $products[$order_detail->id];
 $resume = OrderSlip::getProductSlipResume($order_detail->id);
 $product['quantity_refundable'] = $product['product_quantity'] - $resume['product_quantity'];
 $product['amount_refundable'] = $product['total_price_tax_incl'] - $resume['amount_tax_incl'];
 $product['amount_refund'] = Tools::displayPrice($resume['amount_tax_incl']);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // Get invoices collection
 $invoice_collection = $order->getInvoicesCollection();[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $invoice_array = array();
 foreach ($invoice_collection as $invoice)
 {
  $invoice->name = $invoice->getInvoiceNumberFormatted(Context::getContext()->language->id);
  $invoice_array[] = $invoice;
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // Assign to smarty informations in order to show the new product line
 $this->context->smarty->assign(array(
  'product' => $product,
  'order' => $order,
  'currency' => new Currency($order->id_currency),
  'can_edit' => $this->tabAccess['edit'],
  'invoices_collection' => $invoice_collection,
  'current_id_lang' => Context::getContext()->language->id,
  'link' => Context::getContext()->link,
  'current_index' => self::$currentIndex
 ));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  if (!$res)
  die(Tools::jsonEncode(array(
   'result' => $res,
   'error' => Tools::displayError('Error occurred while editing this product line')
  )));[/size][/font][/color]

[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  if (is_array(Tools::getValue('product_quantity')))
  $view = $this->createTemplate('_customized_data.tpl')->fetch();
 else
  $view = $this->createTemplate('_product_line.tpl')->fetch();

 $this->sendChangedNotification($order);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  die(Tools::jsonEncode(array(
  'result' => $res,
  'view' => $view,
  'can_edit' => $this->tabAccess['add'],
  'invoices_collection' => $invoice_collection,
  'order' => $order,
  'invoices' => $invoice_array,
  'documents_html' => $this->createTemplate('_documents.tpl')->fetch(),
  'shipping_html' => $this->createTemplate('_shipping.tpl')->fetch(),
  'customized_product' => is_array(Tools::getValue('product_quantity'))
 )));
}[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]public function ajaxProcessDeleteProductLine()
{
 $res = true;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $order_detail = new OrderDetail(Tools::getValue('id_order_detail'));
 $order = new Order(Tools::getValue('id_order'));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $this->doDeleteProductLineValidation($order_detail, $order);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // Update OrderInvoice of this OrderDetail
 if ($order_detail->id_order_invoice != 0)
 {
  $order_invoice = new OrderInvoice($order_detail->id_order_invoice);
  $order_invoice->total_paid_tax_excl -= $order_detail->total_price_tax_excl;
  $order_invoice->total_paid_tax_incl -= $order_detail->total_price_tax_incl;
  $order_invoice->total_products -= $order_detail->total_price_tax_excl;
  $order_invoice->total_products_wt -= $order_detail->total_price_tax_incl;
  $res &= $order_invoice->update();
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // Update Order
 $order->total_paid -= $order_detail->total_price_tax_incl;
 $order->total_paid_tax_incl -= $order_detail->total_price_tax_incl;
 $order->total_paid_tax_excl -= $order_detail->total_price_tax_excl;
 $order->total_products -= $order_detail->total_price_tax_excl;
 $order->total_products_wt -= $order_detail->total_price_tax_incl;[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $res &= $order->update();[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // Delete OrderDetail
 $res &= $order_detail->delete();[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  if (!$res)
  die(Tools::jsonEncode(array(
   'result' => $res,
   'error' => Tools::displayError('Error occurred on deletion of this product line')
  )));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // Get invoices collection
 $invoice_collection = $order->getInvoicesCollection();[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $invoice_array = array();
 foreach ($invoice_collection as $invoice)
 {
  $invoice->name = $invoice->getInvoiceNumberFormatted(Context::getContext()->language->id);
  $invoice_array[] = $invoice;
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // Assign to smarty informations in order to show the new product line
 $this->context->smarty->assign(array(
  'order' => $order,
  'currency' => new Currency($order->id_currency),
  'invoices_collection' => $invoice_collection,
  'current_id_lang' => Context::getContext()->language->id,
  'link' => Context::getContext()->link,
  'current_index' => self::$currentIndex
 ));

 $this->sendChangedNotification($order);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  die(Tools::jsonEncode(array(
  'result' => $res,
  'order' => $order,
  'invoices' => $invoice_array,
  'documents_html' => $this->createTemplate('_documents.tpl')->fetch(),
  'shipping_html' => $this->createTemplate('_shipping.tpl')->fetch()
 )));
}[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]protected function doEditProductValidation(OrderDetail $order_detail, Order $order, OrderInvoice $order_invoice = null)
{
 if (!Validate::isLoadedObject($order_detail))
  die(Tools::jsonEncode(array(
   'result' => false,
   'error' => Tools::displayError('Can\'t load Order Detail object')
  )));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  if (!empty($order_invoice) && !Validate::isLoadedObject($order_invoice))
  die(Tools::jsonEncode(array(
   'result' => false,
   'error' => Tools::displayError('Can\'t load Invoice object')
  )));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  if (!Validate::isLoadedObject($order))
  die(Tools::jsonEncode(array(
   'result' => false,
   'error' => Tools::displayError('Can\'t load Order object')
  )));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  if ($order_detail->id_order != $order->id)
  die(Tools::jsonEncode(array(
   'result' => false,
   'error' => Tools::displayError('Can\'t edit this Order Detail for this order')
  )));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // We can't edit a delivered order
 if ($order->hasBeenDelivered())
  die(Tools::jsonEncode(array(
   'result' => false,
   'error' => Tools::displayError('Can\'t edit a delivered order')
  )));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  if (!empty($order_invoice) && $order_invoice->id_order != Tools::getValue('id_order'))
  die(Tools::jsonEncode(array(
   'result' => false,
   'error' => Tools::displayError('Can\'t use this invoice for this order')
  )));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // Clean price
 $product_price_tax_incl = str_replace(',', '.', Tools::getValue('product_price_tax_incl'));
 $product_price_tax_excl = str_replace(',', '.', Tools::getValue('product_price_tax_excl'));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  if (!Validate::isPrice($product_price_tax_incl) || !Validate::isPrice($product_price_tax_excl))
  die(Tools::jsonEncode(array(
   'result' => false,
   'error' => Tools::displayError('Invalid price')
  )));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  if (!is_array(Tools::getValue('product_quantity')) && !Validate::isUnsignedInt(Tools::getValue('product_quantity')))
  die(Tools::jsonEncode(array(
   'result' => false,
   'error' => Tools::displayError('Invalid quantity')
  )));
 elseif (is_array(Tools::getValue('product_quantity')))
  foreach (Tools::getValue('product_quantity') as $qty)
   if (!Validate::isUnsignedInt($qty))
 die(Tools::jsonEncode(array(
  'result' => false,
  'error' => Tools::displayError('Invalid quantity')
 )));
}[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]protected function doDeleteProductLineValidation(OrderDetail $order_detail, Order $order)
{
 if (!Validate::isLoadedObject($order_detail))
  die(Tools::jsonEncode(array(
   'result' => false,
   'error' => Tools::displayError('Can\'t load Order Detail object')
  )));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  if (!Validate::isLoadedObject($order))
  die(Tools::jsonEncode(array(
   'result' => false,
   'error' => Tools::displayError('Can\'t load Order object')
  )));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  if ($order_detail->id_order != $order->id)
  die(Tools::jsonEncode(array(
   'result' => false,
   'error' => Tools::displayError('Can\'t delete this Order Detail for this order')
  )));[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  // We can't edit a delivered order
 if ($order->hasBeenDelivered())
  die(Tools::jsonEncode(array(
   'result' => false,
   'error' => Tools::displayError('Can\'t edit a delivered order')
  )));
}[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]protected function getProducts($order)
{
 $products = $order->getProducts();[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  foreach ($products as &$product)
 {
  if ($product['image'] != null)
  {
   $name = 'product_mini_'.(int)$product['product_id'].(isset($product['product_attribute_id']) ? '_'.(int)$product['product_attribute_id'] : '').'.jpg';
   // generate image cache, only for back office
   $product['image_tag'] = ImageManager::thumbnail(_PS_IMG_DIR_.'p/'.$product['image']->getExistingImgPath().'.jpg', $name, 45, 'jpg');
   if (file_exists(_PS_TMP_IMG_DIR_.$name))
 $product['image_size'] = getimagesize(_PS_TMP_IMG_DIR_.$name);
   else
 $product['image_size'] = false;
  }
 }[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  return $products;
}

protected function reinjectQuantity($order_detail, $qty_cancel_product)
{
 // Reinject product
 $reinjectable_quantity = (int)$order_detail->product_quantity - (int)$order_detail->product_quantity_reinjected;
 $quantity_to_reinject = $qty_cancel_product > $reinjectable_quantity ? $reinjectable_quantity : $qty_cancel_product;
 // @since 1.5.0 : Advanced Stock Management
 $product_to_inject = new Product($order_detail->product_id, false, (int)$this->context->language->id, (int)$order_detail->id_shop);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  $product = new Product($order_detail->product_id, false, (int)$this->context->language->id, (int)$order_detail->id_shop);[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]  if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') && $product->advanced_stock_management && $order_detail->id_warehouse != 0)
 {
  $manager = StockManagerFactory::getManager();
  $movements = StockMvt::getNegativeStockMvts(
    $order_detail->id_order,
    $order_detail->product_id,
    $order_detail->product_attribute_id,
    $quantity_to_reinject
   );
   $left_to_reinject = $quantity_to_reinject;
   foreach ($movements as $movement)
   {
 if ($left_to_reinject > $movement['physical_quantity'])
  $quantity_to_reinject = $movement['physical_quantity'];[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]	 $left_to_reinject -= $quantity_to_reinject;

 $manager->addProduct(
  $order_detail->product_id,
  $order_detail->product_attribute_id,
  new Warehouse($movement['id_warehouse']),
  $quantity_to_reinject,
  null,
  $movement['price_te'],
  true
 );
   }
 StockAvailable::synchronize($order_detail->product_id);
  }
  elseif ($order_detail->id_warehouse == 0)
  {
   StockAvailable::updateQuantity(
 $order_detail->product_id,
 $order_detail->product_attribute_id,
 $quantity_to_reinject,
 $order_detail->id_shop
   );
  }
  else
   $this->errors[] = Tools::displayError('Cannot re-stock product');
}[/size][/font][/color]
[color=#343943][font=Arial, Helvetica, sans-serif][size=3]protected function applyDiscountOnInvoice($order_invoice, $value_tax_incl, $value_tax_excl)
{
 // Update OrderInvoice
 $order_invoice->total_discount_tax_incl += $value_tax_incl;
 $order_invoice->total_discount_tax_excl += $value_tax_excl;
 $order_invoice->total_paid_tax_incl -= $value_tax_incl;
 $order_invoice->total_paid_tax_excl -= $value_tax_excl;
 $order_invoice->update();
}
}

 

Create a configuration setting that will store the id_profile of the view-restricted profile: MY_RESTRICTED_PROFILE_ID = N

Where i have create this setting?

 

Sorry for my question but I didn't speak english well, and I maybe didn't understand a sense of your answer.

 

Thanks

Link to comment
Share on other sites

Please don't take my comments as being rude. I am trying to explain complex thoughts in less complex english.

 

Thanks, but I think it's to much complicated for me now.

 

You asked about restricting access to information. By default PrestaShop cannot do what you ask. Multiple files will need to be changed. Changing them will be complex - if you choose to do it yourself. You may want to find a local developer and inquire about this change.

 

Where i have create this setting?

 

You will need to add a row in the ps_configuration table of your store. You have to use what your host is using to manage databases, or phpmyadmin, or add it by command line.

 

Hope this helps,

Link to comment
Share on other sites

  • 9 months later...

This is what worked for me.

 

1. Create a profile with desired permissions for Orders page. Lets say this profile ID is 3.

2. Create an employee belonging to this profile.

 

3. Edit this file /public_html/tds747/themes/default/template/controllers/orders/helpers/view/view.tpl by using this code

{if ((int)Context::getContext()->employee->id_profile) == 3}
{else}
{/if}

Lets say you don't want the employee to see the sectioned called Customer information in BO Orders page. In Line 165 change from

{if $customer->id}
			<!-- Customer informations -->
			<br />
			<fieldset>
					<legend><img src="../img/admin/tab-customers.gif" /> {l s='Customer information'}</legend>
				<span style="font-weight: bold; font-size: 14px;"><a href="?tab=AdminCustomers&id_customer={$customer->id}&viewcustomer&token={getAdminToken tab='AdminCustomers'}">
					
					{$customer->firstname} {$customer->lastname}</a></span> ({l s='#'}{$customer->id})<br />
				(<a href="mailto:{$customer->email}">{$customer->email}</a>)<br /><br />
				{if ($customer->isGuest())}
					{l s='This order has been placed by a guest.'}
					{if (!Customer::customerExists($customer->email))}
					<form method="post" action="index.php?tab=AdminCustomers&id_customer={$customer->id}&token={getAdminToken tab='AdminCustomers'}">
						<input type="hidden" name="id_lang" value="{$order->id_lang}" />
						<p class="center"><input class="button" type="submit" name="submitGuestToCustomer" value="{l s='Transform guest into customer'}" /></p>
						{l s='This feature will generate a random password and send an e-mail to the customer'}
					</form>
					{else}
						<div><b style="color:red;">{l s='A registered customer account already exists with this e-mail address'}</b></div>
					{/if}
				{else}
					{l s='Account registered:'} <b>{dateFormat date=$customer->date_add full=true}</b><br />
					{l s='Valid orders placed:'} <b>{$customerStats['nb_orders']}</b><br />
					{l s='Total spent since registration:'} <b>{displayPrice price=Tools::ps_round(Tools::convertPrice($customerStats['total_orders'], $currency), 2) currency=$currency->id}</b><br />
			</fieldset>
				{/if}
                        {/if}

to

{if ((int)Context::getContext()->employee->id_profile) == 3}
{else}
			{if $customer->id}
			<!-- Customer informations -->
			<br />
			<fieldset>
					<legend><img src="../img/admin/tab-customers.gif" /> {l s='Customer information'}</legend>
				<span style="font-weight: bold; font-size: 14px;"><a href="?tab=AdminCustomers&id_customer={$customer->id}&viewcustomer&token={getAdminToken tab='AdminCustomers'}">
					
					{$customer->firstname} {$customer->lastname}</a></span> ({l s='#'}{$customer->id})<br />
				(<a href="mailto:{$customer->email}">{$customer->email}</a>)<br /><br />
				{if ($customer->isGuest())}
					{l s='This order has been placed by a guest.'}
					{if (!Customer::customerExists($customer->email))}
					<form method="post" action="index.php?tab=AdminCustomers&id_customer={$customer->id}&token={getAdminToken tab='AdminCustomers'}">
						<input type="hidden" name="id_lang" value="{$order->id_lang}" />
						<p class="center"><input class="button" type="submit" name="submitGuestToCustomer" value="{l s='Transform guest into customer'}" /></p>
						{l s='This feature will generate a random password and send an e-mail to the customer'}
					</form>
					{else}
						<div><b style="color:red;">{l s='A registered customer account already exists with this e-mail address'}</b></div>
					{/if}
				{else}
					{l s='Account registered:'} <b>{dateFormat date=$customer->date_add full=true}</b><br />
					{l s='Valid orders placed:'} <b>{$customerStats['nb_orders']}</b><br />
					{l s='Total spent since registration:'} <b>{displayPrice price=Tools::ps_round(Tools::convertPrice($customerStats['total_orders'], $currency), 2) currency=$currency->id}</b><br />
			</fieldset>
				{/if}
			{/if}
			{/if}

Voila! Employees belonging to profile ID 3 do not see this section anymore.

Edited by Matti (see edit history)
Link to comment
Share on other sites

  • 3 weeks later...

Hi, Matti Thanks it's works! But still there is one problem, employee can click on button Delivery Slips or Invoices and get PDF with all informations about customers.

You can easily hide it for specific profile using the code. Like so:

{if ((int)Context::getContext()->employee->id_profile) == 3}
{else}

WHATEVER YOU WANT TO HIDE FOR PROFILE 3 (just locate the code string)

{/if}

Give it ago, and let me know if it worked for you.

Link to comment
Share on other sites

I was trying to locate code, but cant find it... anyway thanks!

No, not thanks anyway. Change this one (lines 65-83):

<div class="button-command">
			{if (count($invoices_collection))}
				<a class="button" href="{$link->getAdminLink('AdminPdf')|escape:'htmlall':'UTF-8'}&submitAction=generateInvoicePDF&id_order={$order->id}" target="_blank">
					<img src="../img/admin/charged_ok.gif" alt="{l s='View invoice'}" /> {l s='View invoice'}
				</a>
			{else}
				<img src="../img/admin/charged_ko.gif" alt="{l s='No invoice'}" /> {l s='No invoice'}
			{/if}
			 |
			{if (($currentState && $currentState->delivery) || $order->delivery_number)}
				<a class="button"  href="{$link->getAdminLink('AdminPdf')|escape:'htmlall':'UTF-8'}&submitAction=generateDeliverySlipPDF&id_order={$order->id}" target="_blank">
					<img src="../img/admin/delivery.gif" alt="{l s='View delivery slip'}" /> {l s='View delivery slip'}
				</a>
			{else}
				<img src="../img/admin/delivery_ko.gif" alt="{l s='No delivery slip'}" /> {l s='No delivery slip'}
			{/if}
			 |
			<a class="button" href="javascript:window.print()"><img src="../img/admin/printer.gif" alt="{l s='Print order'}" title="{l s='Print order'}" /> {l s='Print order'}</a>
		</div>

to:

{if ((int)Context::getContext()->employee->id_profile) == 3}
			{else}
<div class="button-command">
			{if (count($invoices_collection))}
				<a class="button" href="{$link->getAdminLink('AdminPdf')|escape:'htmlall':'UTF-8'}&submitAction=generateInvoicePDF&id_order={$order->id}" target="_blank">
					<img src="../img/admin/charged_ok.gif" alt="{l s='View invoice'}" /> {l s='View invoice'}
				</a>
			{else}
				<img src="../img/admin/charged_ko.gif" alt="{l s='No invoice'}" /> {l s='No invoice'}
			{/if}
			 |
			{if (($currentState && $currentState->delivery) || $order->delivery_number)}
				<a class="button"  href="{$link->getAdminLink('AdminPdf')|escape:'htmlall':'UTF-8'}&submitAction=generateDeliverySlipPDF&id_order={$order->id}" target="_blank">
					<img src="../img/admin/delivery.gif" alt="{l s='View delivery slip'}" /> {l s='View delivery slip'}
				</a>
			{else}
				<img src="../img/admin/delivery_ko.gif" alt="{l s='No delivery slip'}" /> {l s='No delivery slip'}
			{/if}
			 |
			<a class="button" href="javascript:window.print()"><img src="../img/admin/printer.gif" alt="{l s='Print order'}" title="{l s='Print order'}" /> {l s='Print order'}</a>
		</div>
{/if}
  • Like 1
Link to comment
Share on other sites

  • 6 months later...

Very good posting guys. im realy apreciated.

Anyone know? how about create permission employe for MANUFACTURERS,

just 1 name manufacturers can see with 1 employe. 

 

on admin if employe login, they can see manufacturers with produk in manufatrurers.

after on tab manufacturers, employe can easy manage and update stok produk.

Link to comment
Share on other sites

  • 5 months later...
  • 11 months later...
  • 6 months later...
  • 4 years later...

Hello all

I have a simelar problem to solve. Is it possible to solve it with the way descriped above ?

1) I have ~20 sales employees. They should make fast orders in the BO of PS (1.7.7). (why BO ? Because they should first search the customer and then the product, because fast cheackout)
2) The sales employee should not see all the orders, but mybe only their own
3) The sales employee should not see any KPIs
4) The Admin should she alle orders with extended table with name of the sales

Has anyone a idea ? Is this possible ?

BR Patrick

Edited by HAKO (see edit history)
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...