Jump to content

[Guide] Multistore - Independent invoice numerations


Simone Salerno

Recommended Posts

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

 

  • Like 5
Link to comment
Share on other sites

  • 2 months later...

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

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 by kaitzu (see edit history)
Link to comment
Share on other sites

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 by kaitzu (see edit history)
  • Like 1
Link to comment
Share on other sites

  • 1 year later...
  • 3 years later...

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

  • 2 months later...

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...