Simone Salerno Posted January 21, 2015 Share Posted January 21, 2015 Hi all, in this post/guide I'd like to show you how to have an independent invoices' numeration for each shop in the multistore feature. Prestashop let's you specify a different prefix for each shop, but the numbers are globally shared among all shops. This is due to the fact that the records in the DB are stored as *id_order --> invoice_number* and Prestashop doesn't care about the shop. The solution consists in *JOINING* the invoice number table with the order table in the *Order* class. file: root/override/classes/Order.php public static function getLastInvoiceNumber() { $id_shop = Context::getContext()->shop->id; $next = Db::getInstance()->getValue(' SELECT MAX(inv.number) FROM `'._DB_PREFIX_.'order_invoice` inv INNER JOIN `'._DB_PREFIX_.'orders` ord ON ord.id_order = inv.id_order WHERE ord.id_shop = ' . (int)$id_shop ); return $next ? $next : 0; } public static function setLastInvoiceNumber($order_invoice_id, $id_shop) { if (!$order_invoice_id) return false; $number = Configuration::get('PS_INVOICE_START_NUMBER', null, null, $id_shop); // If invoice start number has been set, you clean the value of this configuration if ($number) Configuration::updateValue('PS_INVOICE_START_NUMBER', false, false, null, $id_shop); $sql = 'UPDATE `'._DB_PREFIX_.'order_invoice` SET number ='; if ($number) $sql .= (int)$number; else $sql .= '(SELECT new_number FROM (SELECT (MAX(inv.number) + 1) AS new_number FROM `'._DB_PREFIX_.'order_invoice` inv INNER JOIN `'._DB_PREFIX_.'orders` ord ON ord.id_order = inv.id_order WHERE ord.id_shop = ' . (int)$id_shop.') AS result)'; $sql .=' WHERE `id_order_invoice` = '.(int)$order_invoice_id; return Db::getInstance()->execute($sql); } Now you have the desired behavior. Hope you found this useful. If it doesn't work for you, I found a module that claims to do this for you (I am not affiliated with the author neither have used the module) : http://addons.prestashop.com/it/fatturazione-contabilita-moduli-prestashop/17583-different-invoice-numbers-multistore.html 5 Link to comment Share on other sites More sharing options...
kaitzu Posted March 25, 2015 Share Posted March 25, 2015 Did I understood correctly. I need to make a file Order.php with lines above??This is my original Order.php: class Order extends OrderCore { public function add($autodate = true, $null_values = true) { $cart = new Cart($this->id_cart); Hook::exec('actionBeforeAddOrder', array('order'=>$this,'cart'=>$cart)); if (ObjectModel::add($autodate, $null_values)) return SpecificPrice::deleteByIdCart($this->id_cart); return false; } public static function setLastInvoiceNumber($order_invoice_id, $id_shop) { if (!$order_invoice_id) return false; $number = Configuration::get('PS_INVOICE_START_NUMBER', null, null, $id_shop); // If invoice start number has been set, you clean the value of this configuration if ($number) Configuration::updateValue('PS_INVOICE_START_NUMBER', false, false, null, $id_shop); $order_invoice = new OrderInvoice($order_invoice_id); $order = new Order($order_invoice->id_order); $cart = new Cart($order->id_cart); if($ref = Hook::exec('actionBeforeAddOrderInvoice', array('order_invoice'=>$order_invoice,'order'=>$order,'cart'=>$cart))) $number = $ref; $sql = 'UPDATE `'._DB_PREFIX_.'order_invoice` SET number ='; if ($number) $sql .= (int)$number; else $sql .= '(SELECT new_number FROM (SELECT (MAX(`number`) + 1) AS new_number FROM `'._DB_PREFIX_.'order_invoice`) AS result)'; $sql .=' WHERE `id_order_invoice` = '.(int)$order_invoice_id; return Db::getInstance()->execute($sql); } public function setDeliveryNumber($order_invoice_id, $id_shop) { if (!$order_invoice_id) return false; $number = Configuration::get('PS_DELIVERY_NUMBER', null, null, $id_shop); // If invoice start number has been set, you clean the value of this configuration if ($number) Configuration::updateValue('PS_DELIVERY_NUMBER', false, false, null, $id_shop); $order_invoice = new OrderInvoice($order_invoice_id); $order = new Order($order_invoice->id_order); $cart = new Cart($order->id_cart); if($ref = Hook::exec('actionBeforeAddDeliveryNumber', array('order'=>$order,'cart'=>$cart,'number'=>$number))) $number = $ref; $sql = 'UPDATE `'._DB_PREFIX_.'order_invoice` SET delivery_number ='; if ($number) $sql .= (int)$number; else $sql .= '(SELECT new_number FROM (SELECT (MAX(`delivery_number`) + 1) AS new_number FROM `'._DB_PREFIX_.'order_invoice`) AS result)'; $sql .=' WHERE `id_order_invoice` = '.(int)$order_invoice_id; return Db::getInstance()->execute($sql); } } Link to comment Share on other sites More sharing options...
kaitzu Posted March 26, 2015 Share Posted March 26, 2015 Someone??? Link to comment Share on other sites More sharing options...
Simone Salerno Posted March 26, 2015 Author Share Posted March 26, 2015 It s an override, it replaces the core functions of PrestaShop. Are you saying you dont know what an ovverde is? Or that you already have an override for Order? Link to comment Share on other sites More sharing options...
kaitzu Posted March 26, 2015 Share Posted March 26, 2015 (edited) It s an override, it replaces the core functions of PrestaShop. Are you saying you dont know what an ovverde is? Or that you already have an override for Order? I know what is the function with override but those lines what you wrote, are there all lines so I can make totally new order.php with those?? If you take a look my own order.php lines you can see there are few lines more in the beginning. Yes, my lines from order.php are from folder override. Edited March 26, 2015 by kaitzu (see edit history) Link to comment Share on other sites More sharing options...
Simone Salerno Posted March 26, 2015 Author Share Posted March 26, 2015 If you already have an override for Order, you have to merge mine with yours. Copy the getLastInvoiceNumber function as-is (since you haven't one), and update your if ($number) ... else ... in setLastInvoiceNumber with mine. Should be the same with delivery number. Link to comment Share on other sites More sharing options...
kaitzu Posted March 31, 2015 Share Posted March 31, 2015 (edited) So here´s my modification, haven´t tested that code yet but can someone check are there any errors? I have read those lines several times but i think I came blind for this... <?php class Order extends OrderCore{ public function add($autodate = true, $null_values = true){ $cart = new Cart($this->id_cart); Hook::exec('actionBeforeAddOrder', array('order'=>$this,'cart'=>$cart)); if (ObjectModel::add($autodate, $null_values)) return SpecificPrice::deleteByIdCart($this->id_cart); return false;}public static function getLastInvoiceNumber(){ $id_shop = Context::getContext()->shop->id; $next = Db::getInstance()->getValue(' SELECT MAX(inv.number) FROM `'._DB_PREFIX_.'order_invoice` inv INNER JOIN `'._DB_PREFIX_.'orders` ord ON ord.id_order = inv.id_order WHERE ord.id_shop = ' . (int)$id_shop ); return $next ? $next : 0;} public static function setLastInvoiceNumber($order_invoice_id, $id_shop){ if (!$order_invoice_id) return false; $number = Configuration::get('PS_INVOICE_START_NUMBER', null, null, $id_shop); // If invoice start number has been set, you clean the value of this configuration if ($number) Configuration::updateValue('PS_INVOICE_START_NUMBER', false, false, null, $id_shop); $sql = 'UPDATE `'._DB_PREFIX_.'order_invoice` SET number ='; if ($number) $sql .= (int)$number; else $sql .= '(SELECT new_number FROM (SELECT (MAX(inv.number) + 1) AS new_number FROM `'._DB_PREFIX_.'order_invoice` inv INNER JOIN `'._DB_PREFIX_.'orders` ord ON ord.id_order = inv.id_order WHERE ord.id_shop = ' . (int)$id_shop.') AS result)'; $sql .=' WHERE `id_order_invoice` = '.(int)$order_invoice_id; return Db::getInstance()->execute($sql);} public function setDeliveryNumber($order_invoice_id, $id_shop){ if (!$order_invoice_id) return false; $number = Configuration::get('PS_DELIVERY_NUMBER', null, null, $id_shop); // If invoice start number has been set, you clean the value of this configuration if ($number) Configuration::updateValue('PS_DELIVERY_NUMBER', false, false, null, $id_shop); $sql = 'UPDATE `'._DB_PREFIX_.'order_invoice` SET delivery_number ='; if ($number) $sql .= (int)$number; else $sql .= '(SELECT new_number FROM (SELECT (MAX(`delivery_number`) + 1) AS new_number FROM `'._DB_PREFIX_.'order_invoice` inv INNER JOIN `'._DB_PREFIX_.'orders` ord ON ord.id_order = inv.id_order WHERE ord.id_shop = ' . (int)$id_shop.') AS result)'; $sql .=' WHERE `id_order_invoice` = '.(int)$order_invoice_id; return Db::getInstance()->execute($sql);}} Edited March 31, 2015 by kaitzu (see edit history) 1 Link to comment Share on other sites More sharing options...
FranciscoVillen Posted January 19, 2017 Share Posted January 19, 2017 Hi Simone Salerno, Thanks for this post. It worked fine. Best regards. Link to comment Share on other sites More sharing options...
jmelich Posted March 4, 2020 Share Posted March 4, 2020 Hi, as I can see it still works on 1.7.5.1 I've modified getLastInvoiceNumer() taking into account every year the number is being reinitiallized to zero. So the max(number) were returning last invoice from last year. There is the code and thanks for your guide and solution public static function getLastInvoiceNumber() { $id_shop = Context::getContext()->shop->id; $next = Db::getInstance()->getValue(' SELECT MAX(inv.number) FROM `'._DB_PREFIX_.'order_invoice` inv INNER JOIN `'._DB_PREFIX_.'orders` ord ON ord.id_order = inv.id_order WHERE YEAR(inv.date_add) = YEAR(NOW()) AND ord.id_shop = ' . (int)$id_shop ); return $next ? $next : 0; } Link to comment Share on other sites More sharing options...
jon88 Posted May 6, 2020 Share Posted May 6, 2020 You saved me Simone Salerno. I could not belived that in the multistore you cannot set different invoice numbers based on shop id. PS team did not added this not even in 1.7 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now