diff --git a/ChangeLog b/ChangeLog
index 30c741222d434ec33e966d3efc8e6c75092544bd..43dc578e49bb52c7d88aa1e7d91d151d1b0de5ac 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,8 +6,8 @@ English Dolibarr ChangeLog
 For users:
 - New: [ task #877 ] Reorganize menus.
 - New: [ task #858 ] Holiday module: note on manual holiday assignation.
-- New: [ task #892 ] Add hidden option in thirdparty customer/supplier module to
-  hide non active companies in select_company method.
+- New: [ task #892 ] Add hidden option in thirdparty customer/supplier module to hide non active
+  companies in select_company method.
 - New: [ task #531 ] Add a workload field on tasks.
 - New: Add graph of bank account input/output into input-output report page.
 - New: Add script export-bank-receipts.php
@@ -24,7 +24,8 @@ For users:
 - New: [ task #928 ] Add extrafield feature on invoice lines.
 - New: Add option ADHERENT_LOGIN_NOT_REQUIRED.
 - New: Add a cron module to define scheduled jobs.
-- New: Add new graphical boxes (customer invoices per month).
+- New: Add new graphical boxes (customer invoices and orders per month).
+- New: [ task #286 ] Enhance rounding function of prices to allow round of sum instead of sum of rounding.
 - Qual: Implement same rule for return value of all command line scripts (0 when success, <>0 if error).
 
 For translators:
diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
index 1bb675a6a0bf18b7e306b3edd0a47de5a4ef271b..0de5f388b42f2e185a0da08719850e4581fc4c7f 100644
--- a/htdocs/core/class/commonobject.class.php
+++ b/htdocs/core/class/commonobject.class.php
@@ -42,7 +42,7 @@ abstract class CommonObject
     public $firstname;
     public $civility_id;
     public $import_key;
-    
+
     public $array_options=array();
 
     public $linkedObjectsIds;
@@ -53,7 +53,7 @@ abstract class CommonObject
 
     /**
      * Method to output saved errors
-     * 
+     *
      * @return	string		String with errors
      */
     function errorsToString()
@@ -1464,15 +1464,18 @@ abstract class CommonObject
     }
 
     /**
-     *	Update total_ht, total_ttc and total_vat for an object (sum of lines)
+     *	Update total_ht, total_ttc, total_vat, total_localtax1, total_localtax2 for an object (sum of lines).
+     *  Must be called at end of methods addline, updateline.
      *
      *	@param	int		$exclspec          	Exclude special product (product_type=9)
-     *  @param  int		$roundingadjust    	-1=Use default method (MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND or 0), 0=Use total of rounding, 1=Use rounding of total
+     *  @param  int		$roundingadjust    	-1=Use default method (MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND if defined, or 0), 0=Force use total of rounding, 1=Force use rounding of total
      *  @param	int		$nodatabaseupdate	1=Do not update database. Update only properties of object.
      *	@return	int    			           	<0 if KO, >0 if OK
      */
     function update_price($exclspec=0,$roundingadjust=-1,$nodatabaseupdate=0)
     {
+    	global $conf;
+
         include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
 
         if ($roundingadjust < 0 && isset($conf->global->MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND)) $roundingadjust=$conf->global->MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND;
@@ -1486,7 +1489,7 @@ abstract class CommonObject
         $fieldlocaltax2='total_localtax2';
         if ($this->element == 'facture_fourn' || $this->element == 'invoice_supplier') $fieldtva='tva';
 
-        $sql = 'SELECT qty, total_ht, '.$fieldtva.' as total_tva, total_ttc, '.$fieldlocaltax1.' as total_localtax1, '.$fieldlocaltax2.' as total_localtax2,';
+        $sql = 'SELECT rowid, qty, total_ht, '.$fieldtva.' as total_tva, total_ttc, '.$fieldlocaltax1.' as total_localtax1, '.$fieldlocaltax2.' as total_localtax2,';
         $sql.= ' tva_tx as vatrate, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type';
         $sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element_line;
         $sql.= ' WHERE '.$this->fk_element.' = '.$this->id;
@@ -1496,6 +1499,7 @@ abstract class CommonObject
             if ($this->table_element_line == 'contratdet') $product_field='';    // contratdet table has no product_type field
             if ($product_field) $sql.= ' AND '.$product_field.' <> 9';
         }
+        $sql.= ' ORDER by rowid';	// We want to be sure to always use same order of line to not change lines differently when option MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND is used
 
         dol_syslog(get_class($this)."::update_price sql=".$sql);
         $resql = $this->db->query($sql);
@@ -1506,8 +1510,9 @@ abstract class CommonObject
             $this->total_localtax1 = 0;
             $this->total_localtax2 = 0;
             $this->total_ttc = 0;
-            $vatrates = array();
-            $vatrates_alllines = array();
+            $total_ht_by_vats  = array();
+            $total_tva_by_vats = array();
+            $total_ttc_by_vats = array();
 
             $num = $this->db->num_rows($resql);
             $i = 0;
@@ -1515,42 +1520,34 @@ abstract class CommonObject
             {
                 $obj = $this->db->fetch_object($resql);
 
-                $this->total_ht        += $obj->total_ht;
+                $this->total_ht        += $obj->total_ht;	// The only field visible at line level
                 $this->total_tva       += $obj->total_tva;
                 $this->total_localtax1 += $obj->total_localtax1;
                 $this->total_localtax2 += $obj->total_localtax2;
                 $this->total_ttc       += $obj->total_ttc;
+                $total_ht_by_vats[$obj->vatrate]  += $obj->total_ht;
+                $total_tva_by_vats[$obj->vatrate] += $obj->total_tva;
+                $total_ttc_by_vats[$obj->vatrate] += $obj->total_ttc;
 
-                // Check if there is a global invoice tax for this vat rate
-                // FIXME: We should have no database access into this function. Also localtax 7 seems to have problem so i add condition to avoid it into standard usage without loosing it.
-                if (! empty($conf->global->MAIN_USE_LOCALTAX_TYPE_7))
+                if ($roundingadjust)	// Check if we need adjustement onto line for vat
                 {
-                	if ($this->total_localtax1 == 0)
-                    {
-						// Search to know if there is a localtax of type 7
-                    	// TODO : store local taxes types into object lines and remove this. We should use here $obj->localtax1_type but it is not yet filled into database, so we search into table of vat rate
-                		global $mysoc;
-                    	$localtax1_array=getLocalTaxesFromRate($vatrate,1,$mysoc);
-                    	if (empty($obj->localtax1_type))
-                    	{
-                    		$obj->localtax1_type = $localtax1_array[0];
-                    		$obj->localtax1_tx = $localtax1_array[1];
-                    	}
-                    	//end TODO
-					}
-                    if ($this->total_localtax2 == 0)
-                    {
-						// Search to know if there is a localtax of type 7
-                    	// TODO : store local taxes types into object lines and remove this. We should use here $obj->localtax1_type but it is not yet filled into database, so we search into table of vat rate
-                		global $mysoc;
-                    	$localtax2_array=getLocalTaxesFromRate($vatrate,2,$mysoc);
-                    	if (empty($obj->localtax2_type))
-                    	{
-                    		$obj->localtax2_type = $localtax2_array[0];
-                    		$obj->localtax2_tx = $localtax2_array[1];
-                    	}
-                    	//end TODO
-                    }
+                	$tmpvat=price2num($total_ht_by_vats[$obj->vatrate] * $obj->vatrate / 100, 'MT', 1);
+                	$diff=price2num($total_tva_by_vats[$obj->vatrate]-$tmpvat, 'MT', 1);
+                	//print 'Line '.$i.' rowid='.$obj->rowid.' vat_rate='.$obj->vatrate.' total_ht='.$obj->total_ht.' total_tva='.$obj->total_tva.' total_ttc='.$obj->total_ttc.' total_ht_by_vats='.$total_ht_by_vats[$obj->vatrate].' total_tva_by_vats='.$total_tva_by_vats[$obj->vatrate].' (new calculation = '.$tmpvat.') total_ttc_by_vats='.$total_ttc_by_vats[$obj->vatrate].($diff?" => DIFF":"")."<br>\n";
+                	if ($diff)
+                	{
+                		if ($diff > 0.1) { dol_print_error('','A rounding difference was detected but is to high to be corrected'); exit; }
+                		$sqlfix="UPDATE ".MAIN_DB_PREFIX.$this->table_element_line." SET ".$fieldtva." = ".($obj->total_tva - $diff).", total_ttc = ".($obj->total_ttc - $diff)." WHERE rowid = ".$obj->rowid;
+						//print 'We found a difference of '.$diff.' for line rowid = '.$obj->rowid.". Run sqlfix = ".$sqlfix."<br>\n";
+                		dol_syslog('We found a difference of '.$diff.' for line rowid = '.$obj->rowid.". Run sqlfix = ".$sqlfix);
+						$resqlfix=$this->db->query($sqlfix);
+						if (! $resqlfix) dol_print_error($this->db,'Failed to update line');
+						$this->total_tva -= $diff;
+						$this->total_ttc -= $diff;
+						$total_tva_by_vats[$obj->vatrate] -= $diff;
+						$total_ttc_by_vats[$obj->vatrate] -= $diff;
+
+                	}
                 }
 
                 $i++;
@@ -1567,6 +1564,7 @@ abstract class CommonObject
             $fieldlocaltax1='localtax1';
             $fieldlocaltax2='localtax2';
             $fieldttc='total_ttc';
+            // Specific code for backward compatibility with old field names
             if ($this->element == 'facture' || $this->element == 'facturerec')             $fieldht='total';
             if ($this->element == 'facture_fourn' || $this->element == 'invoice_supplier') $fieldtva='total_tva';
             if ($this->element == 'propal')                                                $fieldttc='total';
diff --git a/test/phpunit/FactureTestRounding.php b/test/phpunit/FactureTestRounding.php
index f000b74289d529992fac187a61aafe274c2ff6dd..446b6893ae0ac18ed77ca5729549a6924ae5f890 100644
--- a/test/phpunit/FactureTestRounding.php
+++ b/test/phpunit/FactureTestRounding.php
@@ -1,5 +1,5 @@
 <?php
-/* Copyright (C) 2012 Laurent Destailleur  <eldy@users.sourceforge.net>
+/* Copyright (C) 2012-2013 Laurent Destailleur  <eldy@users.sourceforge.net>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -157,9 +157,9 @@ class FactureTestRounding extends PHPUnit_Framework_TestCase
 
     /**
      * testFactureRoundingCreate2
-     * 
+     *
      * @return int
-     * 
+     *
      * @depends	testFactureRoundingCreate1
      * Test according to page http://wiki.dolibarr.org/index.php/Draft:VAT_calculation_and_rounding#Standard_usage
      */
@@ -194,5 +194,133 @@ class FactureTestRounding extends PHPUnit_Framework_TestCase
         //$this->assertEquals($newlocalobject->total_ttc, 2.73);
         return $result;
     }
+
+
+    /**
+     * testFactureAddLine1
+     *
+     * @return	void
+     */
+    public function testFactureAddLine1()
+    {
+    	global $conf,$user,$langs,$db;
+    	$conf=$this->savconf;
+    	$user=$this->savuser;
+    	$langs=$this->savlangs;
+    	$db=$this->savdb;
+
+    	// With option MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND = 0
+    	$conf->global->MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND=0;
+    	$localobject1a=new Facture($this->savdb);
+    	$localobject1a->initAsSpecimen('nolines');
+    	$facid=$localobject1a->create($user);
+    	$localobject1a->addline($facid, 'Line 1', 6.36, 15, 21);	// This include update_price
+    	print __METHOD__." id=".$facid." total_ttc=".$localobject1a->total_ttc."\n";
+    	$this->assertEquals( 95.40, $localobject1a->total_ht);
+    	$this->assertEquals( 20.03, $localobject1a->total_tva);
+    	$this->assertEquals(115.43, $localobject1a->total_ttc);
+
+    	// With option MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND = 1
+    	$conf->global->MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND=1;
+    	$localobject1b=new Facture($this->savdb);
+    	$localobject1b->initAsSpecimen('nolines');
+    	$facid=$localobject1b->create($user);
+    	$localobject1b->addline($facid, 'Line 1', 6.36, 15, 21);	// This include update_price
+    	print __METHOD__." id=".$facid." total_ttc=".$localobject1b->total_ttc."\n";
+    	$this->assertEquals( 95.40, $localobject1b->total_ht, 'testFactureAddLine1 total_ht');
+    	$this->assertEquals( 20.03, $localobject1b->total_tva, 'testFactureAddLine1 total_tva');
+    	$this->assertEquals(115.43, $localobject1b->total_ttc, 'testFactureAddLine1 total_ttc');
+    }
+
+    /**
+     * testFactureAddLine2
+     *
+     * @return	void
+     *
+     * @depends	testFactureAddLine1
+     * The depends says test is run only if previous is ok
+     */
+    public function testFactureAddLine2()
+    {
+    	global $conf,$user,$langs,$db;
+    	$conf=$this->savconf;
+    	$user=$this->savuser;
+    	$langs=$this->savlangs;
+    	$db=$this->savdb;
+
+    	// With option MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND = 0
+    	$conf->global->MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND=0;
+    	$localobject2=new Facture($this->savdb);
+    	$localobject2->initAsSpecimen('nolines');
+    	$facid=$localobject2->create($user);
+    	$localobject2->addline($facid, 'Line 1', 6.36, 5, 21);
+    	$localobject2->addline($facid, 'Line 2', 6.36, 5, 21);
+    	$localobject2->addline($facid, 'Line 3', 6.36, 5, 21);
+    	print __METHOD__." id=".$facid." total_ttc=".$localobject2->total_ttc."\n";
+    	$this->assertEquals( 95.40, $localobject2->total_ht);
+    	$this->assertEquals( 20.04, $localobject2->total_tva);
+    	$this->assertEquals(115.44, $localobject2->total_ttc);
+
+    	// With option MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND = 1
+    	$conf->global->MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND=1;
+    	$localobject2=new Facture($this->savdb);
+    	$localobject2->initAsSpecimen('nolines');
+    	$facid=$localobject2->create($user);
+    	$localobject2->addline($facid, 'Line 1', 6.36, 5, 21);
+    	$localobject2->addline($facid, 'Line 2', 6.36, 5, 21);
+    	$localobject2->addline($facid, 'Line 3', 6.36, 5, 21);
+    	print __METHOD__." id=".$facid." total_ttc=".$localobject2->total_ttc."\n";
+    	$this->assertEquals( 95.40, $localobject2->total_ht);
+    	$this->assertEquals( 20.03, $localobject2->total_tva);
+    	$this->assertEquals(115.43, $localobject2->total_ttc);
+    }
+
+    /**
+     * testFactureAddLine3
+     *
+     * @return	void
+     *
+     * @depends	testFactureAddLine2
+     * The depends says test is run only if previous is ok
+     */
+    public function testFactureAddLine3()
+    {
+    	global $conf,$user,$langs,$db;
+    	$conf=$this->savconf;
+    	$user=$this->savuser;
+    	$langs=$this->savlangs;
+    	$db=$this->savdb;
+
+    	// With option MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND = 0
+    	$conf->global->MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND=0;
+    	$localobject3=new Facture($this->savdb);
+    	$localobject3->initAsSpecimen('nolines');
+    	$facid=$localobject3->create($user);
+    	$localobject3->addline($facid, 'Line 1', 6.36, 3, 21);
+    	$localobject3->addline($facid, 'Line 2', 6.36, 3, 21);
+    	$localobject3->addline($facid, 'Line 3', 6.36, 3, 21);
+    	$localobject3->addline($facid, 'Line 4', 6.36, 3, 21);
+    	$localobject3->addline($facid, 'Line 5', 6.36, 3, 21);
+    	print __METHOD__." id=".$facid." total_ttc=".$localobject3->total_ttc."\n";
+    	$this->assertEquals( 95.40, $localobject3->total_ht);
+    	$this->assertEquals( 20.05, $localobject3->total_tva);
+    	$this->assertEquals(115.45, $localobject3->total_ttc);
+
+    	// With option MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND = 1
+    	$conf->global->MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND=1;
+    	$localobject3=new Facture($this->savdb);
+    	$localobject3->initAsSpecimen('nolines');
+    	$facid=$localobject3->create($user);
+    	$localobject3->addline($facid, 'Line 1', 6.36, 3, 21);
+    	$localobject3->addline($facid, 'Line 2', 6.36, 3, 21);
+    	$localobject3->addline($facid, 'Line 3', 6.36, 3, 21);
+    	$localobject3->addline($facid, 'Line 4', 6.36, 3, 21);
+    	$localobject3->addline($facid, 'Line 5', 6.36, 3, 21);
+    	print __METHOD__." id=".$facid." total_ttc=".$localobject3->total_ttc."\n";
+    	$this->assertEquals( 95.40, $localobject3->total_ht);
+    	$this->assertEquals( 20.03, $localobject3->total_tva);
+    	$this->assertEquals(115.43, $localobject3->total_ttc);
+    }
+
 }
 ?>
\ No newline at end of file