';
diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php
index b31a1972dd1..e0a683e31c0 100644
--- a/htdocs/admin/dict.php
+++ b/htdocs/admin/dict.php
@@ -456,7 +456,7 @@ $tabhelp[8] = array('code'=>$langs->trans("EnterAnyCode"), 'position'=>$langs->
$tabhelp[9] = array('code'=>$langs->trans("EnterAnyCode"), 'unicode'=>$langs->trans("UnicodeCurrency"));
$tabhelp[10] = array('code'=>$langs->trans("EnterAnyCode"), 'taux'=>$langs->trans("SellTaxRate"), 'recuperableonly'=>$langs->trans("RecuperableOnly"), 'localtax1_type'=>$langs->trans("LocalTaxDesc"), 'localtax2_type'=>$langs->trans("LocalTaxDesc"));
$tabhelp[11] = array('code'=>$langs->trans("EnterAnyCode"), 'position'=>$langs->trans("PositionIntoComboList"));
-$tabhelp[12] = array('code'=>$langs->trans("EnterAnyCode"), 'type_cdr'=>$langs->trans("TypeCdr"));
+$tabhelp[12] = array('code'=>$langs->trans("EnterAnyCode"), 'type_cdr'=>$langs->trans("TypeCdr", $langs->transnoentitiesnoconv("NbOfDays"), $langs->transnoentitiesnoconv("Offset"), $langs->transnoentitiesnoconv("NbOfDays"), $langs->transnoentitiesnoconv("Offset")));
$tabhelp[13] = array('code'=>$langs->trans("EnterAnyCode"));
$tabhelp[14] = array('code'=>$langs->trans("EnterAnyCode"));
$tabhelp[15] = array('code'=>$langs->trans("EnterAnyCode"));
diff --git a/htdocs/core/class/commoninvoice.class.php b/htdocs/core/class/commoninvoice.class.php
index 9b1cb8776c3..b8987141b13 100644
--- a/htdocs/core/class/commoninvoice.class.php
+++ b/htdocs/core/class/commoninvoice.class.php
@@ -587,7 +587,7 @@ abstract class CommonInvoice extends CommonObject
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
/**
* Renvoi une date limite de reglement de facture en fonction des
- * conditions de reglements de la facture et date de facturation
+ * conditions de reglements de la facture et date de facturation.
*
* @param integer $cond_reglement Condition of payment (code or id) to use. If 0, we use current condition.
* @return date Date limite de reglement si ok, <0 si ko
@@ -602,7 +602,7 @@ abstract class CommonInvoice extends CommonObject
$cdr_type=0;
$cdr_decalage=0;
- $sqltemp = 'SELECT c.type_cdr,c.nbjour,c.decalage';
+ $sqltemp = 'SELECT c.type_cdr, c.nbjour, c.decalage';
$sqltemp.= ' FROM '.MAIN_DB_PREFIX.'c_payment_term as c';
if (is_numeric($cond_reglement)) $sqltemp.= " WHERE c.rowid=".$cond_reglement;
else {
@@ -631,12 +631,18 @@ abstract class CommonInvoice extends CommonObject
/* Definition de la date limite */
- // 1 : ajout du nombre de jours
- $datelim = $this->date + ($cdr_nbjour * 3600 * 24);
-
- // 2 : application de la regle "fin de mois"
- if ($cdr_type == 1)
+ // 0 : ajout du nombre de jours
+ if ($cdr_type == 0)
{
+ $datelim = $this->date + ($cdr_nbjour * 3600 * 24);
+
+ $datelim += ($cdr_decalage * 3600 * 24);
+ }
+ // 1 : application de la regle "fin de mois"
+ elseif ($cdr_type == 1)
+ {
+ $datelim = $this->date + ($cdr_nbjour * 3600 * 24);
+
$mois=date('m', $datelim);
$annee=date('Y', $datelim);
if ($mois == 12)
@@ -651,23 +657,24 @@ abstract class CommonInvoice extends CommonObject
// On se deplace au debut du mois suivant, et on retire un jour
$datelim=dol_mktime(12,0,0,$mois,1,$annee);
$datelim -= (3600 * 24);
- }
- elseif($cdr_type == 2 && !empty($cdr_nbjour)) // Application de la règle, le N du mois courant ou suivant
- {
- $date_piece = dol_mktime(0,0,0,date('m', $this->date),date('d', $this->date),date('Y', $this->date)); // Sans les heures minutes et secondes
- $date_lim_current = dol_mktime(0,0,0,date('m', $this->date),$cdr_nbjour,date('Y', $this->date)); // Sans les heures minutes et secondes
- $date_lim_next = strtotime(date('Y-m-d', $date_lim_current).' +1month');
+ $datelim += ($cdr_decalage * 3600 * 24);
+ }
+ // 2 : application de la règle, le N du mois courant ou suivant
+ elseif ($cdr_type == 2 && !empty($cdr_decalage))
+ {
+ $datelim = $this->date + ($cdr_nbjour * 3600 * 24);
+
+ $date_piece = dol_mktime(0, 0, 0, date('m', $datelim),date('d', $datelim),date('Y', $datelim)); // Sans les heures minutes et secondes
+ $date_lim_current = dol_mktime(0, 0, 0, date('m', $datelim), $cdr_decalage, date('Y', $datelim)); // Sans les heures minutes et secondes
+ $date_lim_next = dol_time_plus_duree($date_lim_current, 1, 'm'); // Add 1 month
$diff = $date_piece - $date_lim_current;
- if($diff < 0) $datelim = $date_lim_current;
+ if ($diff < 0) $datelim = $date_lim_current;
else $datelim = $date_lim_next;
-
}
-
- // 3 : application du decalage
- $datelim += ($cdr_decalage * 3600 * 24);
+ else return 'Bad value for type_cdr in database for record cond_reglement = '.$cond_reglement;
return $datelim;
}
diff --git a/htdocs/install/mysql/migration/8.0.0-9.0.0.sql b/htdocs/install/mysql/migration/8.0.0-9.0.0.sql
index c461bc3d47d..2fcf5cc882f 100644
--- a/htdocs/install/mysql/migration/8.0.0-9.0.0.sql
+++ b/htdocs/install/mysql/migration/8.0.0-9.0.0.sql
@@ -101,3 +101,5 @@ CREATE TABLE llx_takepos_floor_tables(
floor smallint
) ENGINE=innodb;
+
+UPDATE llx_c_payment_term SET decalage = nbjour, nbjour = 0 where decalage IS NULL AND type_cdr = 2;
diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang
index 613492899ce..bbb42399db0 100644
--- a/htdocs/langs/en_US/admin.lang
+++ b/htdocs/langs/en_US/admin.lang
@@ -1787,7 +1787,7 @@ LandingPage=Landing page
SamePriceAlsoForSharedCompanies=If you use a multicompany module, with the choice "Single price", price will be also the same for all companies if products are shared between environments
ModuleEnabledAdminMustCheckRights=Module has been activated. Permissions for activated module(s) were given to admin users only. You may need to grant permissions to other users or groups manually if necessary.
UserHasNoPermissions=This user has no permission defined
-TypeCdr=Use "None" if the date of payment term is date of invoice plus a delta in days (delta is field "Nb of days") Use "At end of month", if, after delta, the date must be increased to reach the end of month (+ an optional "Offset" in days) Use "Current/Next" to have payment term date being the first Nth of the month (N is stored into field "Nb of days")
+TypeCdr=Use "None" if the date of payment term is date of invoice plus a delta in days (delta is field "%s") Use "At end of month", if, after delta, the date must be increased to reach the end of month (+ an optional "%s" in days) Use "Current/Next" to have payment term date being the first Nth of the month after delta (delta is field "%s", N is stored into field "%s")
BaseCurrency=Reference currency of the company (go into setup of company to change this)
WarningNoteModuleInvoiceForFrenchLaw=This module %s is compliant with french laws (Loi Finance 2016).
WarningNoteModulePOSForFrenchLaw=This module %s is compliant with french laws (Loi Finance 2016) because module Non Reversible Logs is automatically activated.
diff --git a/test/phpunit/CommonInvoiceTest.php b/test/phpunit/CommonInvoiceTest.php
new file mode 100644
index 00000000000..4fab182ad69
--- /dev/null
+++ b/test/phpunit/CommonInvoiceTest.php
@@ -0,0 +1,147 @@
+
+ *
+ * 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
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ * or see http://www.gnu.org/
+ */
+
+/**
+ * \file test/phpunit/CommonObjectTest.php
+ * \ingroup test
+ * \brief PHPUnit test
+ * \remarks To run this script as CLI: phpunit filename.php
+ */
+
+global $conf,$user,$langs,$db;
+//define('TEST_DB_FORCE_TYPE','mysql'); // This is to force using mysql driver
+//require_once 'PHPUnit/Autoload.php';
+require_once dirname(__FILE__).'/../../htdocs/master.inc.php';
+require_once dirname(__FILE__).'/../../htdocs/compta/facture/class/facture.class.php';
+
+if (empty($user->id)) {
+ print "Load permissions for admin user nb 1\n";
+ $user->fetch(1);
+ $user->getrights();
+}
+$conf->global->MAIN_DISABLE_ALL_MAILS=1;
+
+
+/**
+ * Class for PHPUnit tests
+ *
+ * @backupGlobals disabled
+ * @backupStaticAttributes enabled
+ * @remarks backupGlobals must be disabled to have db,conf,user and lang not erased.
+ */
+class CommonInvoiceTest extends PHPUnit\Framework\TestCase
+{
+ protected $savconf;
+ protected $savuser;
+ protected $savlangs;
+ protected $savdb;
+
+ /**
+ * Constructor
+ * We save global variables into local variables
+ *
+ * @return CommonObjectTest
+ */
+ function __construct()
+ {
+ parent::__construct();
+
+ //$this->sharedFixture
+ global $conf,$user,$langs,$db;
+ $this->savconf=$conf;
+ $this->savuser=$user;
+ $this->savlangs=$langs;
+ $this->savdb=$db;
+
+ print __METHOD__." db->type=".$db->type." user->id=".$user->id;
+ //print " - db ".$db->db;
+ print "\n";
+ }
+
+ // Static methods
+ public static function setUpBeforeClass()
+ {
+ global $conf,$user,$langs,$db;
+ $db->begin(); // This is to have all actions inside a transaction even if test launched without suite.
+
+ print __METHOD__."\n";
+ }
+
+ // tear down after class
+ public static function tearDownAfterClass()
+ {
+ global $conf,$user,$langs,$db;
+ $db->rollback();
+
+ print __METHOD__."\n";
+ }
+
+ /**
+ * Init phpunit tests
+ *
+ * @return void
+ */
+ protected function setUp()
+ {
+ global $conf,$user,$langs,$db;
+ $conf=$this->savconf;
+ $user=$this->savuser;
+ $langs=$this->savlangs;
+ $db=$this->savdb;
+
+ print __METHOD__."\n";
+ }
+ /**
+ * End phpunit tests
+ *
+ * @return void
+ */
+ protected function tearDown()
+ {
+ print __METHOD__."\n";
+ }
+
+
+ /**
+ * testFetchUser
+ *
+ * @return void
+ */
+ public function testCalculateDateLimReglement()
+ {
+ global $conf,$user,$langs,$db;
+ $conf=$this->savconf;
+ $user=$this->savuser;
+ $langs=$this->savlangs;
+ $db=$this->savdb;
+
+ $localobject=new Facture($this->savdb);
+ $localobject->fetch(1);
+ $localobject->date = dol_mktime(12, 0, 0, 1, 1, 2010);
+
+ $result = 0;
+
+ // TODO Insert payment terms
+
+
+ //$result=$localobject->calculate_date_lim_reglement(1);
+ //print __METHOD__." result=".$result."\n";
+ $this->assertEquals($result, 0);
+ return $result;
+ }
+}