Jump to content

Shipping cost as a % of the final order amount?


Recommended Posts

Unfortunately, there is no way to do this using the Back Office. I had to edit the code to do this. Unfortunately, I don't know how to create a module. Hopefully someone else can create a module using this code, otherwise I'll need time to learn how to write modules. Here is what I did:

First of all, make sure that on the Shipping tab under Billing, "According to total price" is selected.

In admin/tabs/AdminShipping.php, do the following:

Replace _fieldsHandling definition with:

$this->_fieldsHandling = array('PS_SHIPPING_HANDLING' => array('title' => $this->l('Handling fee'), 'suffix' => $currency, 'validation' => 'isPrice', 'cast' => 'floatval'), 'PS_SHIPPING_HANDLING_PERCENTAGE' => array('title' => $this->l('Handling percentage'), 'suffix' => '%', 'validation' => 'isUnsignedFloat', 'cast' => 'floatval'));



In the display function, comment out $this->displayFormFees(); to hide the Fees section, which is unneeded.

In the function displayFormHandling, comment out the 'Billing:' label and margin-form div.

In classes/Carrier.php, replace the contents of the getDeliveryPriceByPrice function with:

return $orderTotal * (Configuration::get('PS_SHIPPING_HANDLING_PERCENTAGE') / 100);



When finished, your shipping tab should look like the attached image. You can than set the shipping cost to $5 + 5% of the total order like I have here, or you can set it to $0 + 5% if you want percentage of total order only.

4550_yzhmWOdwiBTta6fKaBSX_t

Share this post


Link to post
Share on other sites

Hi tempdbS.

Sorry if I wasn't clear enough. I'll try to be more precise for those who aren't familiar with programming. The two files that need to be modified are admin/tabs/AdminShipping.php and classes/Carrier.php.

Starting with the original AdminShipping.php from Prestashop v1.1, replace lines 25-29 with:

         $this->_fieldsHandling = array(
       'PS_SHIPPING_HANDLING' => array('title' => $this->l('Handling fee'), 'suffix' => $currency, 'validation' => 'isPrice', 'cast' => 'floatval'),
       'PS_SHIPPING_HANDLING_PERCENTAGE' => array('title' => $this->l('Handling percentage'), 'suffix' => '%', 'validation' => 'isUnsignedFloat', 'cast' => 'floatval'));



Replace line 127 with:

//        $this->displayFormFees();



Replace lines 158-172 with:

        echo '

                   <input type="submit" value="'.$this->l('   Save   ').'" name="submitHandling'.$this->table.'" class="button" />


       </form>';



Starting with the original Carrier.php from Prestashop v1.1, replace lines 163-176 with:

        return $orderTotal * (Configuration::get('PS_SHIPPING_HANDLING_PERCENTAGE') / 100);



That is all you need to do. You should now be able to go into the Shipping tab, enter a handling fee and percentage, click Save, and then it should work.

Please let me know if this works for you.

Share this post


Link to post
Share on other sites

Hi tempdbS.

It is hard to give you a complete path since I don't know where you have installed Prestashop. The paths I've given start at the base directory of Prestashop, which contains the files 404.php, address.php, addresses.php, ..., classes, etc. When you installed Prestashop, you had to change the admin folder name to something else. That is the directory to look for tabs/AdminShipping.php in.

If your Prestashop website is installed at http://www.yourwebsite.com/ the files would be http://www.yourwebsite.com/classes/Carrier.php and http://www.yourwebsite.com/admin/tabs/AdminShipping.php though the source code can't be viewed in a browser. You must use whatever HTML editor you use, for example Dreamweaver. If you installed Prestashop in a /shop/ directory, it would be http://www.yourwebsite.com/shop/classes/Carrier.php for example.

I hope this helps.

Share this post


Link to post
Share on other sites

On more thing Rocky -

can you please tell me replace waht with what....
Becoz once i have replaced the first 25-29 lines (which are four) replaced by new two lines, then totally its getting mal-functioning.

PS: I gotch it dude.........

Share this post


Link to post
Share on other sites

Hi tempdbS.

Oops, sorry. I forgot about that. Starting from the bottom of my list and working your way up should work. I was trying to save space by leaving out the original code.

In AdminShipping.php, replace:

Replace:

        $this->_fieldsHandling = array(
       'PS_SHIPPING_HANDLING' => array('title' => $this->l('Handling charges'), 'suffix' => $currency, 'validation' => 'isPrice', 'cast' => 'floatval'),
       'PS_SHIPPING_FREE_PRICE' => array('title' => $this->l('Free shipping starting at'), 'suffix' => $currency, 'validation' => 'isPrice', 'cast' => 'floatval'),
       'PS_SHIPPING_FREE_WEIGHT' => array('title' => $this->l('Free shipping starting at'), 'suffix' => Configuration::get('PS_WEIGHT_UNIT'), 'validation' => 'isUnsignedFloat', 'cast' => 'floatval'),
       'PS_SHIPPING_METHOD' => array('title' => $this->l('Billing'), 'validation' => 'isBool', 'cast' => 'intval'));



with:

        $this->_fieldsHandling = array(
       'PS_SHIPPING_HANDLING' => array('title' => $this->l('Handling fee'), 'suffix' => $currency, 'validation' => 'isPrice', 'cast' => 'floatval'),
       'PS_SHIPPING_HANDLING_PERCENTAGE' => array('title' => $this->l('Handling percentage'), 'suffix' => '%', 'validation' => 'isUnsignedFloat', 'cast' => 'floatval'));



Replace:

       $this->displayFormFees();



with:

//        $this->displayFormFees();



Replace:

       echo '
'.$this->l('Billing:').' 

                   <input type="radio" name="PS_SHIPPING_METHOD" value="0" id="total_price"
                   '.((isset($confValues['PS_SHIPPING_METHOD']) AND $confValues['PS_SHIPPING_METHOD'] == 0) ? 'checked="checked"' : '').'/>
'.$this->l('According to total price').'

                   <input type="radio" name="PS_SHIPPING_METHOD" value="1" id="total_weight"
                   '.((!isset($confValues['PS_SHIPPING_METHOD']) OR $confValues['PS_SHIPPING_METHOD'] == 1) ? 'checked="checked"' : '').'/>
'.$this->l('According to total weight').'


                   <input type="submit" value="'.$this->l('   Save   ').'" name="submitHandling'.$this->table.'" class="button" />


       </form>';


with:

       echo '

                   <input type="submit" value="'.$this->l('   Save   ').'" name="submitHandling'.$this->table.'" class="button" />


       </form>';



In Carrier.php, replace:

        if (isset(self::$priceByPrice[$this->id]))
           return self::$priceByPrice[$this->id];
       $result = Db::getInstance()->getRow('
       SELECT d.`price`
       FROM `'._DB_PREFIX_.'delivery` d
       LEFT JOIN `'._DB_PREFIX_.'range_price` r ON d.`id_range_price` = r.`id_range_price`
       WHERE d.`id_zone` = '.intval($id_zone).'
       AND '.floatval($orderTotal).' < r.`delimiter2`
       AND d.`id_carrier` = '.intval($this->id).'
       ORDER BY r.`delimiter1` ASC');
       if (!isset($result['price']))
           return $this->getMaxDeliveryPriceByPrice($id_zone);
       return $result['price'];



with:

        return $orderTotal * (Configuration::get('PS_SHIPPING_HANDLING_PERCENTAGE') / 100);

Share this post


Link to post
Share on other sites

Did you test it to confirm that it works? Are you getting the shipping cost you wanted? If so, we can tell others who want percentage shipping to use the code.

Share this post


Link to post
Share on other sites

That's strange. Something must be preventing the function getDeliveryPriceByPrice being called. Did you make sure "According to total price" was selected before making the changes? It might be calling the getDeliveryPriceByWeight function instead. If it is, you will have to change that code too.

Can you check whether the PS_SHIPPING_HANDLING_PERCENTAGE entry is in the ps_configuration table of your database?

Share this post


Link to post
Share on other sites

You'll have to change:

echo '

                   <input type="submit" value="'.$this->l('   Save   ').'" name="submitHandling'.$this->table.'" class="button" />


       </form>';



back to:

echo '
'.$this->l('Billing:').' 

                   <input type="radio" name="PS_SHIPPING_METHOD" value="0" id="total_price"
                   '.((isset($confValues['PS_SHIPPING_METHOD']) AND $confValues['PS_SHIPPING_METHOD'] == 0) ? 'checked="checked"' : '').'/>
'.$this->l('According to total price').'

                   <input type="radio" name="PS_SHIPPING_METHOD" value="1" id="total_weight"
                   '.((!isset($confValues['PS_SHIPPING_METHOD']) OR $confValues['PS_SHIPPING_METHOD'] == 1) ? 'checked="checked"' : '').'/>
'.$this->l('According to total weight').'


                   <input type="submit" value="'.$this->l('   Save   ').'" name="submitHandling'.$this->table.'" class="button" />


       </form>';


To display the radio buttons again.

Share this post


Link to post
Share on other sites

The change won't affect the shipping costs, it will only display the option to choose between calculating "According to price" or "According to weight". Go to the Shipping tab and check which one is selected. It should be "According to price".

This has turned out to be a lot more work than I thought it would be. :)

Share this post


Link to post
Share on other sites

Is there any way to make this work with "weight based shipping" ?
I want another tax for my items.
Example: A product cost 100$ and the shipping is 6$. (COD). But my carier is charging % of the price (in our case 100$). The charge is % of the price (in our case 2.4% of 100$). Is there any way to show this to the buyer, separetad from the final price?

Sorry for my poor english.

Share this post


Link to post
Share on other sites

Thanks rocky, I haven't tried this code yet but is there a way to set a minimum shipping charge? Say the minimum shipping charge is $5.99 in case 15% of the final price is less then $5.99?

Say I put in the order and a script looks at it and checks the total. Makes a 15% calculation of that total and determines whether the % is higher or lower than 5.99 at that time it makes a decision how much to charge.

Thanks.

Share this post


Link to post
Share on other sites

Hi mechelaar,

You can set the Handling fee to $5.99 and the Handling percentage to 15%. The shipping cost will always be at least $5.99, even on free orders. All other orders will have an additional 15% of total order price added. If you want the price to be 15% of the total order price OR $5.99, whichever is large, this code won't work.

Share this post


Link to post
Share on other sites

@mechelaar

Actually, after thinking about it some more, I think it would work. Try it and tell me if it is what you want.

@mirkov

Are you asking for two different shipping costs to be displayed: one that you charge the customer and another that the carrier charges you? I'm not sure how to display multiple shipping costs.

Share this post


Link to post
Share on other sites
  • 6 months later...

hi rocky, this uses the percentage of total about for delivery/shipping right ? If some of my customers can pick-up in the local store then i would like to provide a free local pickup or give them a discount lets say 5%.

thanks a lot.

Share this post


Link to post
Share on other sites
  • 2 months later...
  • 1 year later...

Hey Rocky
First of all thanks a LOT for all your contribution

Listen i made all the changes , made sure it was "per price" before switching the codes.... but it is still not showing in the Cart..... the handling price isnt showing.....

Any idea what that could be? also i do NOT have in my database the PS_SHIPPING_HANDLING_PERCENTAGE Entry

I appreciate your help - tons

Cheers

Sal

Share this post


Link to post
Share on other sites
  • 2 years later...
  • 11 months later...

Im also having troubles could you assist here is my code could you possibly assist

<?php
/*
* 2007-2011 PrestaShop 
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
*  @author PrestaShop SA <contact@prestashop.com>
*  @copyright  2007-2011 PrestaShop SA
*  @version  Release: $Revision: 8861 $
*  @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
*  International Registered Trademark & Property of PrestaShop SA
*/

class AdminShipping extends AdminTab
{
	private $_fieldsHandling;

	public function __construct()
	{
	 	$this->table = 'delivery';
 		$currency = new Currency(Configuration::get('PS_CURRENCY_DEFAULT'));
 		
 		$this->_fieldsHandling = array(        'PS_SHIPPING_HANDLING' => array('title' => $this->l('Handling fee'), 'suffix' => $currency, 'validation' => 'isPrice', 'cast' => 'floatval'),        'PS_SHIPPING_HANDLING_PERCENTAGE' => array('title' => $this->l('Handling percentage'), 'suffix' => '%', 'validation' => 'isUnsignedFloat', 'cast' => 'floatval'));

		parent::__construct();
	}

	public function postProcess()
	{
		global $currentIndex;

		/* Handling settings */
		if (isset($_POST['submitHandling'.$this->table]))
		{
		 	if ($this->tabAccess['edit'] === '1')
			{
			 	/* Check required fields */
				foreach ($this->_fieldsHandling AS $field => $values)
					if (($value = Tools::getValue($field)) == false AND (string)$value != '0')
						$this->_errors[] = Tools::displayError('field').' <b>'.$values['title'].'</b> '.Tools::displayError('is required.');

				/* Check field validity */
				foreach ($this->_fieldsHandling AS $field => $values)
					if (Tools::getValue($field))
					{
						$function = $values['validation'];
						if (!Validate::$function(Tools::getValue($field)))
							$this->_errors[] = Tools::displayError('field').' <b>'.$values['title'].'</b> '.Tools::displayError('is invalid.');
					}

				/* Update configuration values */
				if (!sizeof($this->_errors))
				{
					foreach ($this->_fieldsHandling AS $field => $values)
					{
						$function = $values['cast'];
						Configuration::updateValue($field, call_user_func($function, Tools::getValue($field)));
					}

					Tools::redirectAdmin($currentIndex.'&conf=6'.'&token='.$this->token);
				}
			}
			else
				$this->_errors[] = Tools::displayError('You do not have permission to edit here.');
		}

		/* Shipping fees */
		elseif (isset($_POST['submitFees'.$this->table]))
		{
		 	if ($this->tabAccess['edit'] === '1')
			{
				if (($id_carrier = (int)(Tools::getValue('id_carrier'))) AND $id_carrier == ($id_carrier2 = (int)(Tools::getValue('id_carrier2'))))
				{
					$carrier = new Carrier($id_carrier);
					if (Validate::isLoadedObject($carrier))
					{
					 	/* Get configuration values */
						$shipping_method = $carrier->getShippingMethod();
						$rangeTable = $carrier->getRangeTable(); 
						
						$carrier->deleteDeliveryPrice($rangeTable);

						/* Build prices list */
						$priceList = '';
						foreach ($_POST AS $key => $value)
							if (strstr($key, 'fees_'))
							{
								$tmpArray = explode('_', $key);
								$priceList .= '('.($shipping_method == Carrier::SHIPPING_METHOD_PRICE ? (int)($tmpArray[2]) : 'NULL').',
								'.($shipping_method == Carrier::SHIPPING_METHOD_WEIGHT ? (int)($tmpArray[2]) : 'NULL').', '.(int)$carrier->id.',
								'.(int)$tmpArray[1].', '.number_format(abs(preg_replace("#,#", '.', $value)), 6, '.', '').'),';
								unset($tmpArray);
							}
						$priceList = rtrim($priceList, ',');
						/* Update delivery prices */
						$carrier->addDeliveryPrice($priceList);
						Tools::redirectAdmin($currentIndex.'&conf=6'.'&token='.$this->token);
					}
					else
						$this->_errors[] = Tools::displayError('An error occurred while updating fees (cannot load carrier object).');
				}
				elseif (isset($id_carrier2))
				{
					$_POST['id_carrier'] = $id_carrier2;
				}
				else
					$this->_errors[] = Tools::displayError('An error occurred while updating fees (cannot load carrier object).');
			}
			else
				$this->_errors[] = Tools::displayError('You do not have permission to edit here.');
		}
	}

	public function display()
	{
		$this->displayFormHandling();
		//        $this->displayFormFees();
	}

	public function displayFormHandling()
	{
		global $currentIndex;

		$confKeys = $this->_fieldsHandling;
		foreach ($confKeys AS $key => $confKey)
			$getConf[] = $key;
		$confValues = Configuration::getMultiple($getConf);
		unset($confKeys['PS_SHIPPING_METHOD']);

		echo '
		<form action="'.$currentIndex.'&submitHandling'.$this->table.'=1&token='.$this->token.'" method="post">
			<fieldset>
				<legend><img src="../img/admin/delivery.gif" />'.$this->l('Handling').'</legend>';

		foreach ($confKeys AS $key => $confKey)
		{
			$postValue = Tools::getValue($key);
			$sign_left = (is_object($confKey['suffix']) ? $confKey['suffix']->getSign('left') : '');
			$sign_right = (is_object($confKey['suffix']) ? $confKey['suffix']->getSign('right') : (is_string($confKey['suffix']) ? ' '.$confKey['suffix'] : ''));
			echo '
			<label class="clear">'.$confKey['title'].':</label>
			<div class="margin-form">';
			echo $sign_left;
			echo '<input size="6" type="text" name="'.$key.'" value="'.(($postValue != false OR (string)$postValue == '0') ? $postValue : $confValues[$key]).'" />';
			echo $sign_right.' '.($key == 'PS_SHIPPING_HANDLING' ? $this->l('(tax excl.)') : '');
			echo '</div>';
		}
		echo '
			<div class="margin-form" style="margin-top: 20px;">
				<input type="submit" value="'.$this->l('   Save   ').'" name="submitHandling'.$this->table.'" class="button" />
			</div>
			<p style="font-weight: bold; font-size: 11px;">'.$this->l('Tips:').'</p>
			<ul style="list-style-type: disc; font-size: 11px; color:#7F7F7F; margin-left: 30px; line-height: 20px;">
				<li>'.$this->l('If you set these parameters to 0, they will be disabled').'</li>
				<li>'.$this->l('Coupons are not taken into account when calculating free shipping').'</li>
			</ul>
		</fieldset>
		<br />
		<fieldset>
			<legend><img src="../img/admin/money.gif" />'.$this->l('Billing').'</legend>
				<label class="clear">'.$this->l('Choice of range:').' </label>
				<div class="margin-form">
					<input type="radio" name="PS_SHIPPING_METHOD" value="0" id="total_price"
					'.((isset($confValues['PS_SHIPPING_METHOD']) AND $confValues['PS_SHIPPING_METHOD'] == 0) ? 'checked="checked"' : '').'/>
					<label class="t" for="total_price"> '.$this->l('According to total price').'</label><br />
					<input type="radio" name="PS_SHIPPING_METHOD" value="1" id="total_weight"
					'.((!isset($confValues['PS_SHIPPING_METHOD']) OR $confValues['PS_SHIPPING_METHOD'] == 1) ? 'checked="checked"' : '').'/>
					<label class="t" for="total_weight"> '.$this->l('According to total weight').'</label>
				</div>
				<div class="margin-form">
					<input type="submit" value="'.$this->l('   Save   ').'" name="submitHandling'.$this->table.'" class="button" />
				</div>
			</fieldset>
		</form>';
	}

	public function displayFormFees()
	{
		global $currentIndex;
		
		$carrierArray = array();
		$id_carrier = Tools::getValue('id_carrier');
		$carriers = Carrier::getCarriers((int)(Configuration::get('PS_LANG_DEFAULT')), true , false,false, NULL, Carrier::PS_CARRIERS_AND_CARRIER_MODULES_NEED_RANGE);
		foreach ($carriers AS $carrier)
			if (!$carrier['is_free'])
				$carrierArray[] = array(
					'id' => $carrier['id_carrier'],
					'display' => '<option value="'.(int)($carrier['id_carrier']).'"'.(($carrier['id_carrier'] == $id_carrier) ? ' selected="selected"' : '').'>'.$carrier['name'].'</option>'
				);
		if (count($carrierArray))
		{
			if (!$id_carrier)
				$id_carrier = (int)$carrierArray[0]['id'];
			$carrierSelected = new Carrier($id_carrier);
		}
		
		echo '<br /><br />
		<h2>'.$this->l('Fees by carrier, geographical zone, and ranges').'</h2>
		<form action="'.$currentIndex.'&token='.$this->token.'" id="fees" name="fees" method="post">
			<fieldset>
				<legend><img src="../img/admin/delivery.gif" />'.$this->l('Fees').'</legend>';
		
		if (!count($carrierArray))
			echo $this->l('You only have free carriers, there is no need to configure your delivery prices.');
		else
		{
			echo '<b>'.$this->l('Carrier:').' </b>
				<select name="id_carrier2" onchange="document.fees.submit();">';
			foreach ($carrierArray AS $carrierOption)
				echo $carrierOption['display'];
			echo '
				</select><br />
				<table class="table space" cellpadding="0" cellspacing="0">
					<tr>
						<th>'.$this->l('Zone / Range').'</th>';

			$currency = new Currency(Configuration::get('PS_CURRENCY_DEFAULT'));
			
			$rangeObj = $carrierSelected->getRangeObject();
			$rangeTable = $carrierSelected->getRangeTable();
			$suffix = $carrierSelected->getRangeSuffix();

			$rangeIdentifier = 'id_'.$rangeTable;
			$ranges = $rangeObj->getRanges($id_carrier);
			$delivery = Carrier::getDeliveryPriceByRanges($rangeTable, $id_carrier);
			foreach ($delivery AS $deliv)
				$deliveryArray[$deliv['id_zone']][$deliv['id_carrier']][$deliv[$rangeIdentifier]] = $deliv['price'];
			if (!$carrierSelected->is_free)
				foreach ($ranges AS $range)
					echo '<th style="font-size: 11px;">'.(float)($range['delimiter1']).$suffix.' '.$this->l('to').' '.(float)($range['delimiter2']).$suffix.'</th>';
				echo '</tr>';

			$zones = $carrierSelected->getZones();
			if (sizeof($ranges) && !$carrierSelected->is_free)
			{
				if (sizeof($zones) > 1)
				{
					echo '
					<tr>
						<th style="height: 30px;">'.$this->l('All').'</th>';
						foreach ($ranges AS $range)
							echo '<td class="center">'.$currency->getSign('left').'<input type="text" id="fees_all_'.$range[$rangeIdentifier].'" onchange="this.value = this.value.replace(/,/g, \'.\');" onkeyup="if ((event.keyCode||event.which) != 9){ spreadFees('.$range[$rangeIdentifier].') }" style="width: 45px;" />'.$currency->getSign('right').'</td>';
					echo '</tr>';
				}
			
				foreach ($zones AS $zone)
				{
					echo '
					<tr>
						<th style="height: 30px;">'.$zone['name'].'</th>';
					foreach ($ranges AS $range)
					{
						if (isset($deliveryArray[$zone['id_zone']][$id_carrier][$range[$rangeIdentifier]]))
							$price = $deliveryArray[$zone['id_zone']][$id_carrier][$range[$rangeIdentifier]];
						else
							$price = '0.00';
						echo '<td class="center">'.$currency->getSign('left').'<input type="text" class="fees_'.$range[$rangeIdentifier].'" onchange="this.value = this.value.replace(/,/g, \'.\');" name="fees_'.$zone['id_zone'].'_'.$range[$rangeIdentifier].'" onkeyup="clearAllFees('.$range[$rangeIdentifier].')" value="'.$price.'" style="width: 45px;" />'.$currency->getSign('right').'</td>';
					}
					echo '
					</tr>';
				}
			}
				
			echo '<tr>
					<td colspan="'.(sizeof($ranges) + 1).'" class="center" style="border-bottom: none; height: 40px;">
						<input type="hidden" name="submitFees'.$this->table.'" value="1" />';
			if (sizeof($ranges) && !$carrierSelected->is_free)
				echo '	<input type="submit" value="'.$this->l('   Save   ').'" class="button" />';
			elseif ($carrierSelected->is_free)
				echo $this->l('This is a free carrier');
			else
				echo $this->l('No ranges set for this carrier');
			echo '
					</td>
				</tr>';
			echo '
			</table>
			<p>'.$this->l('Prices do not include tax.').'</p>';
		}
		echo '
			</fieldset>
			<input type="hidden" name="id_carrier" value="'.$id_carrier.'" />
		</form>';
	}
}

and Carrier 

<?php
/*
* 2007-2011 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
*  @author PrestaShop SA <contact@prestashop.com>
*  @copyright  2007-2011 PrestaShop SA
*  @version  Release: $Revision: 12891 $
*  @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
*  International Registered Trademark & Property of PrestaShop SA
*/

class CarrierCore extends ObjectModel
{
	/**
	 * getCarriers method filter
	 */
	const PS_CARRIERS_ONLY = 1;
	const CARRIERS_MODULE = 2;
	const CARRIERS_MODULE_NEED_RANGE = 3;
	const PS_CARRIERS_AND_CARRIER_MODULES_NEED_RANGE = 4;
	const ALL_CARRIERS = 5;
	
	const SHIPPING_METHOD_DEFAULT = 0;
	const SHIPPING_METHOD_WEIGHT = 1;
	const SHIPPING_METHOD_PRICE = 2;
	const SHIPPING_METHOD_FREE = 3;

	/** @var int Tax id (none = 0) */
	public $id_tax_rules_group;

 	/** @var string Name */
	public $name;

 	/** @var string URL with a '@' for */
	public $url;

	/** @var string Delay needed to deliver customer */
	public $delay;

	/** @var boolean Carrier statuts */
	public $active = true;

	/** @var boolean True if carrier has been deleted (staying in database as deleted) */
	public $deleted = 0;

	/** @var boolean Active or not the shipping handling */
	public $shipping_handling = true;

	/** @var int Behavior taken for unknown range */
	public $range_behavior;

	/** @var boolean Carrier module */
	public $is_module;

	/** @var boolean Free carrier */
	public $is_free = false;
	
	/** @var int shipping behavior: by weight or by price */
	public $shipping_method = 0;

	/** @var boolean Shipping external */
	public $shipping_external = 0;

	/** @var string Shipping external */
	public $external_module_name = null;

	/** @var boolean Need Range */
	public $need_range = 0;

 	protected $fieldsRequired = array('name', 'active');
 	protected $fieldsSize = array('name' => 64);
 	protected $fieldsValidate = array('id_tax_rules_group' => 'isInt',
 									  'name' => 'isCarrierName',
 									  'active' => 'isBool',
 									  'is_free' => 'isBool',
 									  'url' => 'isAbsoluteUrl',
 									  'shipping_handling' => 'isBool',
 									  'range_behavior' => 'isBool',
 									  'shipping_method' => 'isUnsignedInt');
 	protected $fieldsRequiredLang = array('delay');
 	protected $fieldsSizeLang = array('delay' => 128);
 	protected $fieldsValidateLang = array('delay' => 'isGenericName');

	protected $table = 'carrier';
	protected $identifier = 'id_carrier';

	protected static $priceByWeight = array();
	protected static $priceByWeight2 = array();
	protected static $priceByPrice = array();
	protected static $priceByPrice2 = array();

	protected static $_cache_tax_rule = array();

	protected	$webserviceParameters = array(
		'fields' => array(
			'id_tax_rules_group' => array(),
			'deleted' => array(),
			'is_module' => array(),
		),
	);

	public function getFields()
	{
		parent::validateFields();
		$fields['id_tax_rules_group'] = (int)($this->id_tax_rules_group);
		$fields['name'] = pSQL($this->name);
		$fields['url'] = pSQL($this->url);
		$fields['active'] = (int)($this->active);
		$fields['deleted'] = (int)($this->deleted);
		$fields['shipping_handling'] = (int)($this->shipping_handling);
		$fields['range_behavior'] = (int)($this->range_behavior);
		$fields['shipping_method'] = (int)($this->shipping_method);
		$fields['is_module'] = (int)($this->is_module);
		$fields['is_free'] = (int)($this->is_free);
		$fields['shipping_external'] = (int)($this->shipping_external);
		$fields['external_module_name'] = pSQL($this->external_module_name);
		$fields['need_range'] = (boolean)$this->need_range;

		return $fields;
	}

	public function __construct($id = null, $id_lang = null)
	{
		parent::__construct($id, $id_lang);
		if ($this->name == '0')
	 $this->name = Configuration::get('PS_SHOP_NAME');
	}

	/**
	* Check then return multilingual fields for database interaction
	*
	* @return array Multilingual fields
	*/
	public function getTranslationsFieldsChild()
	{
		parent::validateFieldsLang();
		return parent::getTranslationsFields(array('delay'));
	}

	public function add($autodate = true, $nullValues = false)
	{
		if (!parent::add($autodate, $nullValues) || !Validate::isLoadedObject($this))
			return false;
		if (!Db::getInstance()->ExecuteS('SELECT `id_carrier` FROM `'._DB_PREFIX_.$this->table.'` WHERE `deleted` = 0'))
			return false;
		if (!$numRows = Db::getInstance()->NumRows())
			return false;
		if ((int)($numRows) == 1)
			Configuration::updateValue('PS_CARRIER_DEFAULT', (int)($this->id));
		return true;
	}

	/**
	* Change carrier id in delivery prices when updating a carrier
	*
	* @param integer $id_old Old id carrier
	*/
	public function setConfiguration($id_old)
	{
		Db::getInstance()->Execute('UPDATE `'._DB_PREFIX_.'delivery` SET `id_carrier` = '.(int)($this->id).' WHERE `id_carrier` = '.(int)($id_old));
	}

	/**
	 * Get delivery prices for a given order
	 *
	 * @param floatval $totalWeight Order total weight
	 * @param integer $id_zone Zone id (for customer delivery address)
	 * @return float Delivery price
	 */
	public function getDeliveryPriceByWeight($totalWeight, $id_zone)
	{
 $cache_key = $this->id.'_'.$totalWeight.'_'.$id_zone;
		if (!isset(self::$priceByWeight[$cache_key]))
		{
	 $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow('
			SELECT d.`price`
			FROM `'._DB_PREFIX_.'delivery` d
			LEFT JOIN `'._DB_PREFIX_.'range_weight` w ON (d.`id_range_weight` = w.`id_range_weight`)
			WHERE d.`id_zone` = '.(int)($id_zone).'
			AND '.(float)($totalWeight).' >= w.`delimiter1`
			AND '.(float)($totalWeight).' < w.`delimiter2`
			AND d.`id_carrier` = '.(int)($this->id).'
			ORDER BY w.`delimiter1` ASC');
			if (!isset($result['price']))
				self::$priceByWeight[$cache_key] = $this->getMaxDeliveryPriceByWeight($id_zone);
			else
				self::$priceByWeight[$cache_key] = $result['price'];
		}
		return self::$priceByWeight[$cache_key];
	}

	public static function checkDeliveryPriceByWeight($id_carrier, $totalWeight, $id_zone)
	{
 $cache_key = $id_carrier.'_'.$totalWeight.'_'.$id_zone;
		if (!isset(self::$priceByWeight2[$cache_key]))
		{
	 $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow('
			SELECT d.`price`
			FROM `'._DB_PREFIX_.'delivery` d
			LEFT JOIN `'._DB_PREFIX_.'range_weight` w ON d.`id_range_weight` = w.`id_range_weight`
			WHERE d.`id_zone` = '.(int)($id_zone).'
			AND '.(float)($totalWeight).' >= w.`delimiter1`
			AND '.(float)($totalWeight).' < w.`delimiter2`
			AND d.`id_carrier` = '.(int)($id_carrier).'
			ORDER BY w.`delimiter1` ASC');
			self::$priceByWeight2[$cache_key] = (isset($result['price']));
		}
		return self::$priceByWeight2[$cache_key];
	}

	public function getMaxDeliveryPriceByWeight($id_zone)
	{
 $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS('
		SELECT d.`price`
		FROM `'._DB_PREFIX_.'delivery` d
		INNER JOIN `'._DB_PREFIX_.'range_weight` w ON d.`id_range_weight` = w.`id_range_weight`
		WHERE d.`id_zone` = '.(int)($id_zone).'
		AND d.`id_carrier` = '.(int)($this->id).'
		ORDER BY w.`delimiter2` DESC LIMIT 1');
		if (!isset($result[0]['price']))
			return false;
		return $result[0]['price'];
	}

	/**
	 * Get delivery prices for a given order
	 *
	 * @param floatval $orderTotal Order total to pay
	 * @param integer $id_zone Zone id (for customer delivery address)
	 * @return float Delivery price
	 */
	public function getDeliveryPriceByPrice($orderTotal, $id_zone, $id_currency = null)
	{
 $cache_key = $this->id.'_'.$orderTotal.'_'.$id_zone.'_'.$id_currency;
		if (!isset(self::$priceByPrice[$cache_key]))
		{
			if (!empty($id_currency))
		 $orderTotal = Tools::convertPrice($orderTotal, $id_currency, false);

	 $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow('
			SELECT d.`price`
			FROM `'._DB_PREFIX_.'delivery` d
			LEFT JOIN `'._DB_PREFIX_.'range_price` r ON d.`id_range_price` = r.`id_range_price`
			WHERE d.`id_zone` = '.(int)($id_zone).'
			AND '.(float)($orderTotal).' >= r.`delimiter1`
			AND '.(float)($orderTotal).' < r.`delimiter2`
			AND d.`id_carrier` = '.(int)($this->id).'
			ORDER BY r.`delimiter1` ASC');
			if (!isset($result['price']))
				self::$priceByPrice[$cache_key] = $this->getMaxDeliveryPriceByPrice($id_zone);
			else
				self::$priceByPrice[$cache_key] = $result['price'];
		}
		return self::$priceByPrice[$cache_key];
	}

	/**
	 * Check delivery prices for a given order
	 *
	 * @param id_carrier
	 * @param floatval $orderTotal Order total to pay
	 * @param integer $id_zone Zone id (for customer delivery address)
	 * @param integer $id_currency
	 * @return float Delivery price
	 */
	public static function checkDeliveryPriceByPrice($id_carrier, $orderTotal, $id_zone, $id_currency = null)
	{
 $cache_key = $id_carrier.'_'.$orderTotal.'_'.$id_zone.'_'.$id_currency;
		if (!isset(self::$priceByPrice2[$cache_key]))
		{
			if (!empty($id_currency))
		 $orderTotal = Tools::convertPrice($orderTotal, $id_currency, false);

	 $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow('
			SELECT d.`price`
			FROM `'._DB_PREFIX_.'delivery` d
			LEFT JOIN `'._DB_PREFIX_.'range_price` r ON d.`id_range_price` = r.`id_range_price`
			WHERE d.`id_zone` = '.(int)($id_zone).'
			AND '.(float)($orderTotal).' >= r.`delimiter1`
			AND '.(float)($orderTotal).' < r.`delimiter2`
			AND d.`id_carrier` = '.(int)($id_carrier).'
			ORDER BY r.`delimiter1` ASC');
			self::$priceByPrice2[$cache_key] = (isset($result['price']));
		}
		return self::$priceByPrice2[$cache_key];
	}

	public function getMaxDeliveryPriceByPrice($id_zone)
	{
 $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS('
		SELECT d.`price`
		FROM `'._DB_PREFIX_.'delivery` d
		INNER JOIN `'._DB_PREFIX_.'range_price` r ON d.`id_range_price` = r.`id_range_price`
		WHERE d.`id_zone` = '.(int)($id_zone).'
		AND d.`id_carrier` = '.(int)($this->id).'
		ORDER BY r.`delimiter2` DESC LIMIT 1');
		if (!isset($result[0]['price']))
			return false;
		return $result[0]['price'];
	}

	/**
	 * Get delivery prices for a given shipping method (price/weight)
	 *
	 * @param string $rangeTable Table name (price or weight)
	 * @return array Delivery prices
	 */
	public static function getDeliveryPriceByRanges($rangeTable, $id_carrier)
	{
 $rangeTable = pSQL($rangeTable);
		return Db::getInstance()->ExecuteS('
		SELECT d.`id_'.$rangeTable.'`, d.`id_carrier`, d.`id_zone`, d.`price`
		FROM `'._DB_PREFIX_.'delivery` d
		LEFT JOIN `'._DB_PREFIX_.$rangeTable.'` r ON r.`id_'.$rangeTable.'` = d.`id_'.$rangeTable.'`
		WHERE (d.`id_'.$rangeTable.'` IS NOT NULL AND d.`id_'.$rangeTable.'` != 0 AND d.`id_carrier` = '.(int)($id_carrier).')
		ORDER BY r.`delimiter1` ASC');
	}

	/**
	 * Get all carriers in a given language
	 *
	 * @param integer $id_lang Language id
	 * @param $modules_filters, possible values:
			PS_CARRIERS_ONLY
			CARRIERS_MODULE
			CARRIERS_MODULE_NEED_RANGE
			PS_CARRIERS_AND_CARRIER_MODULES_NEED_RANGE
			ALL_CARRIERS
	 * @param boolean $active Returns only active carriers when true
	 * @return array Carriers
	 */
	public static function getCarriers($id_lang, $active = false, $delete = false, $id_zone = false, $ids_group = null, $modules_filters = self::PS_CARRIERS_ONLY)
	{
	 	if (!Validate::isBool($active))
	 		die(Tools::displayError());
	 	if ($ids_group)
		{
	 $ids = '';
			foreach ($ids_group as $id)
		 $ids .= (int)($id).', ';
	 $ids = rtrim($ids, ', ');
			if ($ids == '')
				return array();
		}
 $sql = '
			SELECT c.*, cl.delay
			FROM `'._DB_PREFIX_.'carrier` c
			LEFT JOIN `'._DB_PREFIX_.'carrier_lang` cl ON (c.`id_carrier` = cl.`id_carrier` AND cl.`id_lang` = '.(int)($id_lang).')
			LEFT JOIN `'._DB_PREFIX_.'carrier_zone` cz  ON (cz.`id_carrier` = c.`id_carrier`)'.
			($id_zone ? 'LEFT JOIN `'._DB_PREFIX_.'zone` z  ON (z.`id_zone` = '.(int)($id_zone).')' : '').'
			WHERE c.`deleted` '.($delete ? '= 1' : ' = 0').
			($active ? ' AND c.`active` = 1' : '').
			($id_zone ? ' AND cz.`id_zone` = '.(int)($id_zone).'
			AND z.`active` = 1 ' : ' ');
		switch ($modules_filters)
		{
			case 1 :
		 $sql .= 'AND c.is_module = 0 ';
			break;
			case 2 :
		 $sql .= 'AND c.is_module = 1 ';
			break;
			case 3 :
		 $sql .= 'AND c.is_module = 1 AND c.need_range = 1 ';
			break;
			case 4 :
		 $sql .= 'AND (c.is_module = 0 OR c.need_range = 1) ';
			break;
			case 5 :
		 $sql .= '';
			break;

		}
 $sql .= ($ids_group ? ' AND c.id_carrier IN (SELECT id_carrier FROM '._DB_PREFIX_.'carrier_group WHERE id_group IN ('.$ids.')) ' : '').'
			GROUP BY c.`id_carrier`';

 $carriers = Db::getInstance()->ExecuteS($sql);

		if (is_array($carriers) && count($carriers))
		{
			foreach ($carriers as $key => $carrier)
				if ($carrier['name'] == '0')
			 $carriers[$key]['name'] = Configuration::get('PS_SHOP_NAME');
		}
		else
	 $carriers = array();

		return $carriers;
	}

	public static function getDeliveredCountries($id_lang, $activeCountries = false, $activeCarriers = false, $containStates = null)
	{
		if (!Validate::isBool($activeCountries) || !Validate::isBool($activeCarriers))
	 		die(Tools::displayError());
	 		
 $states = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS('
		SELECT s.*
		FROM `'._DB_PREFIX_.'state` s
		ORDER BY s.`name` ASC');

 $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS('
			SELECT cl.*,c.*, cl.`name` AS country, zz.`name` AS zone FROM `'._DB_PREFIX_.'country` c 
			LEFT JOIN `'._DB_PREFIX_.'country_lang` cl ON (c.`id_country` = cl.`id_country` AND cl.`id_lang` = '.(int)($id_lang).') 
			INNER JOIN (`'._DB_PREFIX_.'carrier_zone` cz INNER JOIN `'._DB_PREFIX_.'carrier` cr ON ( cr.id_carrier = cz.id_carrier AND cr.deleted = 0 '.($activeCarriers ?
			'AND cr.active = 1) ' : ') ').'
			LEFT JOIN `'._DB_PREFIX_.'zone` zz ON cz.id_zone = zz.id_zone) ON zz.`id_zone` = c.`id_zone` 
			WHERE 1
			'.($activeCountries ? 'AND c.active = 1' : '').'
			'.(!is_null($containStates) ? 'AND c.`contains_states` = '.(int)($containStates) : '').'
			ORDER BY cl.name ASC');
	
 $countries = array();
		foreach ($result as &$country)
	 $countries[$country['id_country']] = $country;
		foreach ($states as &$state)
			if (isset($countries[$state['id_country']])) /* Does not keep the state if its country has been disabled and not selected */
		 $countries[$state['id_country']]['states'][] = $state;

		return $countries;
	}
	
	/**
	 * Return the default carrier to use
	 *
	 * @param array $carriers
	 * @param array $defaultCarrier the last carrier selected
	 * @return number the id of the default carrier
	 */
	public static function getDefaultCarrierSelection($carriers, $defaultCarrier = 0)
	{
		if (empty($carriers))
			return 0;
		
		if ((int)$defaultCarrier != 0)
			foreach ($carriers as $carrier)
				if ($carrier['id_carrier'] == (int)$defaultCarrier)
					return (int)$carrier['id_carrier'];
		foreach ($carriers as $carrier)
			if ($carrier['id_carrier'] == (int)Configuration::get('PS_CARRIER_DEFAULT'))
				return (int)$carrier['id_carrier'];
			
		return (int)$carriers[0]['id_carrier'];
	}
	
	/**
	 *
	 * @param int $id_zone
	 * @param Array $groups group of the customer
	 * @return Array 
	 */
	public static function getCarriersForOrder($id_zone, $groups = null)
	{
		global $cookie, $cart;

		if (is_array($groups) && !empty($groups))
	 $result = Carrier::getCarriers((int)$cookie->id_lang, true, false, (int)$id_zone, $groups, self::PS_CARRIERS_AND_CARRIER_MODULES_NEED_RANGE);
		else
	 $result = Carrier::getCarriers((int)$cookie->id_lang, true, false, (int)$id_zone, array(1), self::PS_CARRIERS_AND_CARRIER_MODULES_NEED_RANGE);
 $resultsArray = array();

		foreach ($result as $k => $row)
		{
	 $carrier = new Carrier((int)$row['id_carrier']);
	 $shippingMethod = $carrier->getShippingMethod();
			if ($shippingMethod != Carrier::SHIPPING_METHOD_FREE)
			{
				// Get only carriers that are compliant with shipping method
				if (($shippingMethod == Carrier::SHIPPING_METHOD_WEIGHT && $carrier->getMaxDeliveryPriceByWeight($id_zone) === false)
					|| ($shippingMethod == Carrier::SHIPPING_METHOD_PRICE && $carrier->getMaxDeliveryPriceByPrice($id_zone) === false))
				{
					unset($result[$k]);
					continue;
				}

				// If out-of-range behavior carrier is set on "Desactivate carrier"
				if ($row['range_behavior'])
				{
					// Get id zone
					if (!$id_zone)
				 $id_zone = Country::getIdZone(Country::getDefaultCountryId());

					// Get only carriers that have a range compatible with cart
					if (($shippingMethod == Carrier::SHIPPING_METHOD_WEIGHT && (!Carrier::checkDeliveryPriceByWeight($row['id_carrier'], $cart->getTotalWeight(), $id_zone)))
						|| ($shippingMethod == Carrier::SHIPPING_METHOD_PRICE
							&& (!Carrier::checkDeliveryPriceByPrice($row['id_carrier'], $cart->getOrderTotal(true, Cart::BOTH_WITHOUT_SHIPPING), $id_zone, $cart->id_currency))))
					{
						unset($result[$k]);
						continue;
					}
				}
			}
			
	 $row['name'] = (strval($row['name']) != '0' ? $row['name'] : Configuration::get('PS_SHOP_NAME'));
	 $row['price'] = ($shippingMethod == Carrier::SHIPPING_METHOD_FREE ? 0 : $cart->getOrderShippingCost((int)$row['id_carrier']));
	 $row['price_tax_exc'] = ($shippingMethod == Carrier::SHIPPING_METHOD_FREE ? 0 : $cart->getOrderShippingCost((int)$row['id_carrier'], false));
	 $row['img'] = file_exists(_PS_SHIP_IMG_DIR_.(int)($row['id_carrier']).'.jpg') ? _THEME_SHIP_DIR_.(int)($row['id_carrier']).'.jpg' : '';

			// If price is false, then the carrier is unavailable (carrier module)
			if ($row['price'] === false)
			{
				unset($result[$k]);
				continue;
			}

	 $resultsArray[] = $row;
		}
		return $resultsArray;
	}

	/**
	 * @param int $id_country
	 * @param array $groups
	 * @return Array carriers list
	 * @deprecated
	 */
	public static function getCarriersOpc($id_country, $groups = null)
	{
		Tools::displayAsDeprecated();

		return self::getCarriersForOrder((int)Country::getIdZone((int)($id_country)), $groups);
	}

	public static function checkCarrierZone($id_carrier, $id_zone)
	{
		return Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS('
			SELECT c.`id_carrier`
			FROM `'._DB_PREFIX_.'carrier` c
			LEFT JOIN `'._DB_PREFIX_.'carrier_zone` cz  ON (cz.`id_carrier` = c.`id_carrier`)
			LEFT JOIN `'._DB_PREFIX_.'zone` z  ON (z.`id_zone` = '.(int)($id_zone).')
			WHERE c.`id_carrier` = '.(int)($id_carrier).'
			AND c.`deleted` = 0
			AND c.`active` = 1
			AND cz.`id_zone` = '.(int)($id_zone).'
			AND z.`active` = 1'
		);
	}

	/**
	 * Get all zones
	 *
	 * @return array Zones
	 */
	public function getZones()
	{
		return Db::getInstance()->ExecuteS('
			SELECT *
			FROM `'._DB_PREFIX_.'carrier_zone` cz
			LEFT JOIN `'._DB_PREFIX_.'zone` z ON cz.`id_zone` = z.`id_zone`
			WHERE cz.`id_carrier` = '.(int)($this->id));
	}

	/**
	 * Get a specific zones
	 *
	 * @return array Zone
	 */
	public function getZone($id_zone)
	{
		return Db::getInstance()->ExecuteS('
			SELECT *
			FROM `'._DB_PREFIX_.'carrier_zone`
			WHERE `id_carrier` = '.(int)($this->id).'
			AND `id_zone` = '.(int)($id_zone));
	}

	/**
	 * Add zone
	 */
	public function addZone($id_zone)
	{
		return Db::getInstance()->Execute('
			INSERT INTO `'._DB_PREFIX_.'carrier_zone` (`id_carrier` , `id_zone`)
			VALUES ('.(int)($this->id).', '.(int)($id_zone).')');
	}

	/**
	 * Delete zone
	 */
	public function deleteZone($id_zone)
	{
		return Db::getInstance()->Execute('
			DELETE FROM `'._DB_PREFIX_.'carrier_zone`
			WHERE `id_carrier` = '.(int)($this->id).'
			AND `id_zone` = '.(int)($id_zone).' LIMIT 1');
	}

	/**
	 * Clean delivery prices (weight/price)
	 *
	 * @param string $rangeTable Table name to clean (weight or price according to shipping method)
	 * @return boolean Deletion result
	 */
	public function deleteDeliveryPrice($rangeTable)
	{
		return Db::getInstance()->Execute('DELETE FROM `'._DB_PREFIX_.'delivery` WHERE `id_carrier` = '.(int)($this->id).' AND (`id_'.$rangeTable.'` IS NOT NULL OR `id_'.$rangeTable.'` = 0)');
	}

	/**
	 * Add new delivery prices
	 *
	 * @param string $priceList Prices list separated by commas
	 * @return boolean Insertion result
	 */
	public function addDeliveryPrice($priceList)
	{
	 	if (!Validate::isValuesList($priceList))
	 		die(Tools::displayError());
		return Db::getInstance()->Execute('INSERT INTO `'._DB_PREFIX_.'delivery` (`id_range_price`, `id_range_weight`, `id_carrier`, `id_zone`, `price`) VALUES '.$priceList);
	}

	/**
	 * Copy old carrier informations when update carrier
	 *
	 * @param integer $oldId Old id carrier (copy from that id)
	 */
	public function copyCarrierData($oldId)
	{
		if (!Validate::isUnsignedId($oldId))
			die(Tools::displayError());

 $oldLogo = _PS_SHIP_IMG_DIR_.'/'.(int)($oldId).'.jpg';
		if (file_exists($oldLogo))
			copy($oldLogo, _PS_SHIP_IMG_DIR_.'/'.(int)($this->id).'.jpg');

		// Copy existing ranges price
 $res = Db::getInstance()->ExecuteS('
		SELECT * FROM `'._DB_PREFIX_.'range_price`
		WHERE id_carrier = '.(int)($oldId));
		foreach ($res as $val)
		{
			Db::getInstance()->Execute('
			INSERT INTO `'._DB_PREFIX_.'range_price` (`id_carrier`, `delimiter1`, `delimiter2`)
			VALUES ('.(int)($this->id).','.(float)($val['delimiter1']).','.(float)($val['delimiter2']).')');
	 $maxRangePrice = Db::getInstance()->Insert_ID();
	 $res2 = Db::getInstance()->ExecuteS('
			SELECT * FROM `'._DB_PREFIX_.'delivery`
			WHERE id_carrier = '.(int)($oldId).'
			AND id_range_price = '.(int)($val['id_range_price']));
			foreach ($res2 as $val2)
				Db::getInstance()->Execute('
				INSERT INTO `'._DB_PREFIX_.'delivery` (`id_carrier`,`id_range_price`,`id_range_weight`,`id_zone`, `price`)
				VALUES ('.(int)($this->id).','.(int)($maxRangePrice).',NULL,'.(int)($val2['id_zone']).','.(float)($val2['price']).')');
		}

		// Copy existing ranges weight
 $res = Db::getInstance()->ExecuteS('
		SELECT * FROM `'._DB_PREFIX_.'range_weight`
		WHERE id_carrier = '.(int)($oldId));
		foreach ($res as $val)
		{
			Db::getInstance()->Execute('
			INSERT INTO `'._DB_PREFIX_.'range_weight` (`id_carrier`, `delimiter1`, `delimiter2`)
			VALUES ('.(int)($this->id).','.(float)($val['delimiter1']).','.(float)($val['delimiter2']).')');
	 $maxRangeWeight = Db::getInstance()->Insert_ID();
	 $res2 = Db::getInstance()->ExecuteS('
			SELECT * FROM `'._DB_PREFIX_.'delivery`
			WHERE id_carrier = '.(int)($oldId).'
			AND id_range_weight = '.(int)($val['id_range_weight']));
			foreach ($res2 as $val2)
				Db::getInstance()->Execute('
				INSERT INTO `'._DB_PREFIX_.'delivery` (`id_carrier`,`id_range_price`,`id_range_weight`,`id_zone`, `price`)
				VALUES ('.(int)($this->id).',NULL,'.(int)($maxRangeWeight).','.(int)($val2['id_zone']).','.(float)($val2['price']).')');
		}

		// Copy existing zones
 $res = Db::getInstance()->ExecuteS('
		SELECT * FROM `'._DB_PREFIX_.'carrier_zone`
		WHERE id_carrier = '.(int)($oldId));
		foreach ($res as $val)
			Db::getInstance()->Execute('
			INSERT INTO `'._DB_PREFIX_.'carrier_zone` (`id_carrier`, `id_zone`)
			VALUES ('.(int)($this->id).','.(int)($val['id_zone']).')');

		//Copy default carrier
		if ((int)(Configuration::get('PS_CARRIER_DEFAULT')) == $oldId)
			Configuration::updateValue('PS_CARRIER_DEFAULT', (int)($this->id));
	}

	/**
	 * Check if carrier is used (at least one order placed)
	 *
	 * @return integer Order count for this carrier
	 */
	public function isUsed()
	{
 $row = Db::getInstance()->getRow('
		SELECT COUNT(`id_carrier`) AS total
		FROM `'._DB_PREFIX_.'orders`
		WHERE `id_carrier` = '.(int)($this->id));

		return (int)($row['total']);
	}


	/**
	* Get the price without taxes defined in carrier
	* @deprecated
	**/
	public function getPriceWithoutTaxes($productPrice)
	{
	    Tools::displayAsDeprecated();
 $tax = new Tax($this->id_tax);
		return round($productPrice - ($productPrice * $tax->rate / 100), 2);
	}


	public function getShippingMethod()
	{
		if ($this->is_free)
			return Carrier::SHIPPING_METHOD_FREE;
			
 $method = (int)$this->shipping_method;

		if ($this->shipping_method == Carrier::SHIPPING_METHOD_DEFAULT)
		{
			// backward compatibility
			if ((int)Configuration::get('PS_SHIPPING_METHOD'))
		 $method = Carrier::SHIPPING_METHOD_WEIGHT;
			else
		 $method = Carrier::SHIPPING_METHOD_PRICE;
		}

		return $method;
	}

	public function getRangeTable()
	{
 $shippingMethod = $this->getShippingMethod();
		if ($shippingMethod == Carrier::SHIPPING_METHOD_WEIGHT)
			return 'range_weight';
		else if ($shippingMethod == Carrier::SHIPPING_METHOD_PRICE)
			return 'range_price';
		return false;
	}

	public function getRangeObject()
	{
 $shippingMethod = $this->getShippingMethod();
		if ($shippingMethod == Carrier::SHIPPING_METHOD_WEIGHT)
			return new RangeWeight();
		else if ($shippingMethod == Carrier::SHIPPING_METHOD_PRICE)
			return new RangePrice();
		return false;
	}

	public function getRangeSuffix()
	{
 $suffix = Configuration::get('PS_WEIGHT_UNIT');
		if ($this->getShippingMethod() == Carrier::SHIPPING_METHOD_PRICE)
		{
	 $currency = new Currency(Configuration::get('PS_CURRENCY_DEFAULT'));
	 $suffix = $currency->sign;
		}
		return $suffix;
	}

	public static function getIdTaxRulesGroupByIdCarrier($id_carrier)
	{
		if (!isset(self::$_cache_tax_rule[(int)$id_carrier]))
		{
			 self::$_cache_tax_rule[$id_carrier] = Db::getInstance()->getValue('
			 SELECT `id_tax_rules_group`
			 FROM `'._DB_PREFIX_.'carrier`
			 WHERE `id_carrier` = '.(int)$id_carrier);
	   }

	   return self::$_cache_tax_rule[$id_carrier];
	}
}

Edited by openshaww (see edit history)

Share this post


Link to post
Share on other sites
  • 2 months later...
Guest
This topic is now closed to further replies.
×
×
  • Create New...

Important Information

Cookies ensure the smooth running of our services. Using these, you accept the use of cookies. Learn More