fburn Posted October 27, 2008 Share Posted October 27, 2008 Hello,The company I work for has a wide variety of products that are complex with respect to shipping based on weight and dimensions. Specifically, they range in weight from a few pounds up to several hundred and can be shipped parcel or on a pallet. The current shipping method simply doesn't work under these conditions.I am going to implement a per item shipping by:1) adding the following to the Carrier class: public function getDeliveryPriceByProduct($id_product, $id_zone) { } // getDeliveryPriceByProduct() public static function checkDeliveryPriceByProduct($id_carrier, $id_product, $id_zone) { } // checkDeliveryPriceByProduct() 2) adding another table ps_delivery_product: DROP TABLE IF EXISTS `criterion_store`.`ps_delivery_product`; CREATE TABLE `criterion_store`.`ps_delivery_product` ( `id_delivery_product` int(10) unsigned NOT NULL auto_increment, `id_carrier` int(10) unsigned NOT NULL, `id_product` int(10) unsigned NOT NULL, `id_zone` int(10) unsigned NOT NULL, `price` decimal(10,2) NOT NULL, PRIMARY KEY (`id_delivery_product`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 3) Adding another object DeliveryProduct that models the ps_delivery_product table3) Altering the cart object. Specifically, function getOrderShippingCost($id_carrier = NULL) Does anyone have input, information or suggestions on this feature or implementation? Link to comment Share on other sites More sharing options...
fburn Posted October 27, 2008 Author Share Posted October 27, 2008 Here is the DeliveryProduct class: /** * DeliveryProduct class, DeliveryProduct.php * Delivery management on a per product basis * * @category classes * * @author Finnian F Burn * * @license http://www.opensource.org/licenses/osl-3.0.php Open-source licence 3.0 * @version 1.0 **/ class DeliveryProduct extends ObjectModel { /** @var integer */ public $id_delivery_product; /** @var integer */ public $id_carrier; /** @var integer */ public $id_product; /** @var integer */ public $id_zone; /** @var float */ public $price; /** @var array */ protected $fieldsRequired = array ('id_carrier', 'id_product', 'id_zone', 'price'); /** @var array */ protected $fieldsValidate = array ('id_carrier' => 'isUnsignedId', 'id_product' => 'isUnsignedId', 'id_zone' => 'isUnsignedId', 'price' => 'isPrice'); /** @var string */ protected $table = 'delivery_product'; /** @var string */ protected $identifier = 'id_delivery_product'; /** * retrieve the fields for this class * * @return array **/ public function getFields() { // validate the fields parent::validateFields(); // populate the fields array $fields['id_carrier'] = intval($this->id_carrier); $fields['id_product'] = intval($this->id_product); $fields['id_zone'] = intval($this->id_zone); $fields['price'] = floatval($this->price); // return the array return $fields; } // getFields() } // DeliveryProduct Link to comment Share on other sites More sharing options...
fburn Posted October 27, 2008 Author Share Posted October 27, 2008 Here's the Carrier->checkDeliveryPriceByProduct method: public static function checkDeliveryPriceByProduct($id_carrier, $id_product, $id_zone) { $result = Db::getInstance()->getRow(' SELECT dp.`price` FROM `'._DB_PREFIX_.'delivery_product` dp WHERE dp.`id_zone` = '.intval($id_zone).' AND dp.`id_product` = '.intval($id_product).' AND dp.`id_carrier` = '.intval($id_carrier)); if (!isset($result['price'])) return false; return true; } // checkDeliveryPriceByProduct() Link to comment Share on other sites More sharing options...
fburn Posted October 27, 2008 Author Share Posted October 27, 2008 OK, I feel like a total hack. The maximal effort required to make these features work within the prestashop world is extraordinary. So many things are linked together that modifying something as fundamental as shipping becomes cost prohibitive. Forget the stuff above, this is my quick and VERY dirty solution:Run the following SQL: INSERT INTO ps_configuration SET name='PS_DELIVERY_PRODUCT', value='1', date_add=NOW(), date_upd=NOW() in cart->getOrderShippingCost() add/change the following code (around line 535): if (Configuration::get('PS_DELIVERY_PRODUCT') == 1) { $products = $this->getProducts(); foreach ($products as $row) { $shipping_cost += $row['shipping_cost']; } // foreach } // if // Get shipping cost using correct method else if ($carrier->range_behavior) Change the Cart->getProducts() method SQL follows: $sql = ' SELECT cp.`id_product_attribute`, cp.`id_product`, cp.`quantity` AS cart_quantity, pl.`name`, pl.`description_short`, pl.`availability`, p.`id_product`, p.`id_supplier`, p.`id_manufacturer`, p.`id_tax`, p.`on_sale`, p.`ecotax`, p.`quantity`, p.`price`, p.`reduction_price`, p.`reduction_percent`, p.`weight`, p.`out_of_stock`, p.`active`, p.`date_add`, p.`date_upd`, p.`shipping_cost`, t.`id_tax`, tl.`name` AS tax, t.`rate`, pa.`price` AS price_attribute, pa.`weight` AS weight_attribute, pa.`quantity` AS quantity_attribute, pa.`ecotax` AS ecotax_attr, i.`id_image`, il.`legend`, pl.`link_rewrite`, IF (IFNULL(pa.`reference`, \'\') = \'\', p.`reference`, pa.`reference`) AS reference, IF (IFNULL(pa.`supplier_reference`, \'\') = \'\', p.`supplier_reference`, pa.`supplier_reference`) AS supplier_reference, IF (IFNULL(pa.`weight`, \'\') = \'\', p.`weight`, pa.`weight`) AS weight_attribute, IF (IFNULL(pa.`ean13`, \'\') = \'\', p.`ean13`, pa.`ean13`) AS ean13 FROM `'._DB_PREFIX_.'cart_product` cp LEFT JOIN `'._DB_PREFIX_.'product` p ON p.`id_product` = cp.`id_product` LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.intval($this->id_lang).') LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa ON (pa.`id_product_attribute` = cp.`id_product_attribute`) LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = p.`id_tax`) LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.intval($this->id_lang).') LEFT JOIN `'._DB_PREFIX_.'image` i ON (i.`id_product` = cp.`id_product` AND (IF(pa.`id_image`, pa.`id_image` = i.`id_image`, i.`cover` = 1))) LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.intval($this->id_lang).') WHERE `id_cart` = '.intval($this->id).' '.($id_product ? ' AND cp.`id_product` = '.intval($id_product) : '').' AND p.`id_product` IS NOT NULL'; $result = Db::getInstance()->ExecuteS($sql); And here...: $row['features'] = Product::getFeaturesStatic(intval($row['id_product'])); $row['shipping_cost'] = floatval($row['shipping_cost']) * intval($row['quantity']); Update the Product class to feature a per product shipping: public $shipping_cost; /** @var array tables */ protected $tables = array ('product', 'product_lang'); protected $fieldsRequired = array('id_tax', 'quantity', 'price'); protected $fieldsSize = array('reference' => 32, 'supplier_reference' => 32, 'ean13' => 13); protected $fieldsValidate = array( 'id_tax' => 'isUnsignedId', ................................... 'active' => 'isBool', 'ean13' => 'isEan13', 'shipping_cost' => 'isPrice' ); public function getFields() { parent::validateFields(); ................................ $fields['date_upd'] = pSQL($this->date_upd); $fields['shipping_cost'] = floatval($this->shipping_cost); return $fields; } Update the ps_product table: DROP TABLE IF EXISTS `criterion_store`.`ps_product`; CREATE TABLE `criterion_store`.`ps_product` ( `id_product` int(10) unsigned NOT NULL auto_increment, `id_supplier` int(10) unsigned default NULL, `id_manufacturer` int(10) unsigned default NULL, `id_tax` int(10) unsigned NOT NULL, `id_category_default` int(10) unsigned default NULL, `id_color_default` int(10) unsigned default NULL, `on_sale` tinyint(1) unsigned NOT NULL default '0', `ean13` varchar(13) default NULL, `ecotax` decimal(10,2) NOT NULL default '0.00', `quantity` int(10) unsigned NOT NULL default '0', `price` decimal(13,6) NOT NULL default '0.000000', `wholesale_price` decimal(13,6) NOT NULL default '0.000000', `reduction_price` decimal(10,2) default NULL, `reduction_percent` float default NULL, `reduction_from` date default NULL, `reduction_to` date default NULL, `reference` varchar(32) default NULL, `supplier_reference` varchar(32) default NULL, `weight` float NOT NULL default '0', `out_of_stock` int(10) unsigned NOT NULL default '2', `quantity_discount` tinyint(1) default '0', `active` tinyint(1) unsigned NOT NULL default '0', `date_add` datetime NOT NULL, `date_upd` datetime NOT NULL, `shipping_cost` decimal(10,2) default NULL, PRIMARY KEY (`id_product`), KEY `product_supplier` (`id_supplier`), KEY `product_manufacturer` (`id_manufacturer`) ) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; The rest in the next message... Link to comment Share on other sites More sharing options...
fburn Posted October 27, 2008 Author Share Posted October 27, 2008 For the back-office, we need to update the AdminProduct tab...Here's the changes to copyFromPost(): protected function copyFromPost(&$object, $table) { parent::copyFromPost($object, $table); /* Additional fields */ $languages = Language::getLanguages(); foreach ($languages as $language) if (isset($_POST['meta_keywords_'.$language['id_lang']])) $_POST['meta_keywords_'.$language['id_lang']] = preg_replace('/ *,? +,*/', ',', strtolower($_POST['meta_keywords_'.$language['id_lang']])); $_POST['weight'] = empty($_POST['weight']) ? '0' : str_replace(',', '.', $_POST['weight']); if ($_POST['reduction_price'] != NULL) $object->reduction_price = str_replace(',', '.', $_POST['reduction_price']); if ($_POST['reduction_percent'] != NULL) $object->reduction_percent = str_replace(',', '.', $_POST['reduction_percent']); if ($_POST['ecotax'] != NULL) $object->ecotax = str_replace(',', '.', $_POST['ecotax']); $object->active = (!isset($_POST['active']) OR $_POST['active']) ? true : false; $object->on_sale = (!isset($_POST['on_sale']) ? false : true); $object->shipping_cost = $_POST['shipping'] != NULL ? $_POST['shipping'] : '0'; } Add the last of the following table rows (the other is for reference): '.$this->l('Weight:').' <input size="3" maxlength="4" name="weight" type="text" value="'.htmlentities($this->getFieldValue($obj, 'weight'), ENT_COMPAT, 'UTF-8').'" onKeyUp="[removed]this.value = this.value.replace(/,/g, \'.\');" /> '.Configuration::get('PS_WEIGHT_UNIT').' '.$this->l('Shipping:').' $ <input size="5" maxlength="6" name="shipping" type="text" value="'.htmlentities($this->getFieldValue($obj, 'shipping_cost'), ENT_COMPAT, 'UTF-8').'" style="width: 110px; margin-right: 44px;" /> '; Phew! I know it's not elegant, but it works. It's getting time for me to finish up for the day, but tomorrow I will update the AdminShipping tabs so that you can choose to switch between the three different shipping methods.As much as possible I have tested the code today, and it works smoothly on my linux boxes. I'm going to put this into production in the next couple weeks. Anyone who is interested in additional help implementing this solution until the prestashop team adds this functionality, please feel free to contact me.I'm not particularly good with regular expressions, so if some one wants to contribute verification for the shipping costs in the copyFromPost above, I'd love it.Have a good evening (for those in my time zone)! Link to comment Share on other sites More sharing options...
Davey Posted November 1, 2008 Share Posted November 1, 2008 Thanks for this, it looks like something i could do with.Could you please make the code above a little easier to implement, by adding something like. In file blah.php, After "blah blah blah" around line 1234 add the following etc etc.I have tried to follow the above instructions, but it isnt making much sense.Hope this makes sense to you Link to comment Share on other sites More sharing options...
fburn Posted November 3, 2008 Author Share Posted November 3, 2008 Can you email me at [email protected] and I will walk you through the code changes one step at a time.We can also talk by phone if that would work easier for you. Link to comment Share on other sites More sharing options...
Matthieu Biart Posted November 3, 2008 Share Posted November 3, 2008 Hi everyone!Very nice contribution fburn :-)It's not a so dirty way ;-)It's just a shame that it converts the shipping costs of the entire shop :SI think you can resolve it by replacing : if (Configuration::get('PS_DELIVERY_PRODUCT') == 1) { $products = $this->getProducts(); foreach ($products as $row) { $shipping_cost += $row['shipping_cost']; } // foreach } by $products = $this->getProducts(); foreach ($products as $row) { if ($product['shipping_cost']) $shipping_cost += floatval($row['shipping_cost']); } // foreach Link to comment Share on other sites More sharing options...
fburn Posted November 3, 2008 Author Share Posted November 3, 2008 Mattheiu,Great idea! I've been looking for a way to handle this so it doesn't disable the rest of the shipping methods. There must be a lot of users out there who require per item shipping, if anyone else needs help implementing this, please feel free to email me at [email protected].For the prestashop team, what about including this code or a variant in the next release? Link to comment Share on other sites More sharing options...
Matthieu Biart Posted November 3, 2008 Share Posted November 3, 2008 Mattheiu,Great idea! :red: For the prestashop team, what about including this code or a variant in the next release? Sorry, but we're currently working on making as much as possible the current version stable so we try to not add new features until the final 1.1 release. Link to comment Share on other sites More sharing options...
fburn Posted November 3, 2008 Author Share Posted November 3, 2008 So is that a yes for 1.1? Link to comment Share on other sites More sharing options...
Matthieu Biart Posted November 3, 2008 Share Posted November 3, 2008 Sorry, but we're currently working on making as much as possible the current version stable so we try to not add new features until the final 1.1 release. So is that a yes for 1.1? I thought it was clearly a no Link to comment Share on other sites More sharing options...
fburn Posted November 3, 2008 Author Share Posted November 3, 2008 My mistake, I thought you were referring to changes in stability of 1.0, not the 1.1 release. Link to comment Share on other sites More sharing options...
myndcraft Posted January 13, 2009 Share Posted January 13, 2009 Anyone with updated instructions on this for 1.1? I tried following along (demo server), but am getting lost in places. Link to comment Share on other sites More sharing options...
Travis Posted January 14, 2009 Share Posted January 14, 2009 Will this work for 1.1 or is it only compatible with 1.0? If it works with 1.1 is there a better explanation with steps for the installation of this code? Link to comment Share on other sites More sharing options...
myndcraft Posted January 14, 2009 Share Posted January 14, 2009 From my understanding (and looking thru all the code) this will work with 1.1, but requires some modification. Hopefully fburn can chime in with some updated instructions, but I'm also planning to try installing on a demo box today and trying to make it work if I can. Link to comment Share on other sites More sharing options...
Travis Posted January 14, 2009 Share Posted January 14, 2009 If you do get it working can you post how you did it? So everyone knows. Link to comment Share on other sites More sharing options...
myndcraft Posted January 14, 2009 Share Posted January 14, 2009 Try as I might I can't get it to work. I've gone thru and compared the supplied code to the 1.1 source and attempted to get the two to work together, but no dice.If anyone has this working on 1.1 I would love to talk to you. I love PrestaShop and I know it's free, but I can't deploy this without a shipping method like this. Thanks to anyone who may be able to help. Link to comment Share on other sites More sharing options...
myndcraft Posted January 15, 2009 Share Posted January 15, 2009 After much frustration with not being able to make this work I downgraded (ie reinstalled) 1.0 on my live server out of desperation for a working solution. Unfortunately at that point it would work there either. At that point I realized there must be a PEBKAC error and I started again.This time I was able to get the mod working on a 1.0 install AS WELL as a demo 1.1 install.Tomorrow I am going to reinstall the the "live" server with 1.1 and try my luck again with the modification. If that works I will post some more detailed instructions as well as the actual PHP files themselves.The next step though is to get the additional modification Matthieu Biart provided working because so far that is not. Link to comment Share on other sites More sharing options...
Paweł Sokołowski - Studio Eline.pl Posted January 30, 2009 Share Posted January 30, 2009 Im also interested - waiting for any tips Link to comment Share on other sites More sharing options...
Scooter Posted January 31, 2009 Share Posted January 31, 2009 I SO hope that the fine makers of PrestaShop will make a module for this dilemma! I have a collectibles and antique store. I have different shipping needs for each item. One item may only require $5.00 shipping fee, while another may be $25.00 shipping fee. It would be nice to see "Enter Shipping Amount" on each product entry page! PLEASE come out with a module for this that allows individual shipping fees. I really am a BIG fan of PrestaShop, (I left ZenCart because it was way too bloated and difficult to figure out) just need this "individual item shipping" addition. In the mean time, how do I allow for individual shipping? Link to comment Share on other sites More sharing options...
Paweł Sokołowski - Studio Eline.pl Posted January 31, 2009 Share Posted January 31, 2009 I have this same problem - but just a field with fixed price its not enough. What about many items in cart? If I buy 10 I must pay 10 shipping price per ich item?Just think over and easy way to fix price - use weight fields as a delivery price and add this value product.weight to delivery price in delivery.phpWhen stanard delivery will by set to 0, this gives You weight as a delivery priceBuy this don solve many items shipping .... Link to comment Share on other sites More sharing options...
Scooter Posted January 31, 2009 Share Posted January 31, 2009 I just think a module that will dsplay a shipping charges box, on each products page will be the answer. Then have a tick box that says "Charge shipping on multiple orders"..... if you don't tick the box, it will only charge a one time shipping fee. Good idea folks? Link to comment Share on other sites More sharing options...
Paweł Sokołowski - Studio Eline.pl Posted January 31, 2009 Share Posted January 31, 2009 I found another solution - which as a see now is working. Im gonna test it more to by sure is working well .PM my in few days - I will see what can by done for You Link to comment Share on other sites More sharing options...
Travis Posted February 2, 2009 Share Posted February 2, 2009 I found another solution - which as a see now is working. Im gonna test it more to by sure is working well .PM my in few days - I will see what can by done for You Are you charging a fee? Link to comment Share on other sites More sharing options...
Paweł Sokołowski - Studio Eline.pl Posted February 2, 2009 Share Posted February 2, 2009 If solution must by made as a hard source change - yes, but in this case not Link to comment Share on other sites More sharing options...
mickey21 Posted March 13, 2009 Share Posted March 13, 2009 Hello, are there news for this point ? I also have to find a solution : in my case, each manufacturer will send the products to the buyers. So each product must have a shipping cost. Except if the products come from the same manufacturers... I don t know how to solve this question now... if somenone has an idea...?sorry for my english, i am very bad ! have a good day Link to comment Share on other sites More sharing options...
Paulw01 Posted July 16, 2009 Share Posted July 16, 2009 hi there,shipping fee per item would be great, had to offer customers option of selecting shipping fees during checkout, which not the best method but does allow multiple orders discount.paul Link to comment Share on other sites More sharing options...
mopar Posted May 10, 2010 Share Posted May 10, 2010 Any new news on the progress of the mod? Link to comment Share on other sites More sharing options...
TravisNPS Posted May 10, 2010 Share Posted May 10, 2010 none that i know of Link to comment Share on other sites More sharing options...
Recommended Posts