From 1c98979ca10035cd46f29f884623d8279924e76a Mon Sep 17 00:00:00 2001
From: gauthier <gauthier.verdol@atm-consulting.fr>
Date: Tue, 4 Oct 2016 15:45:23 +0200
Subject: [PATCH] NEW : option "Current/Next" for limit payment date (in
 payment terms) to use a specific day of current month or jump to same day of
 next month

---
 htdocs/admin/dict.php                         | 28 ++++++++++++-------
 .../facture/class/paymentterm.class.php       | 18 ++++++------
 htdocs/core/class/commoninvoice.class.php     | 21 +++++++++++---
 .../install/mysql/data/llx_c_payment_term.sql | 16 +++++------
 .../mysql/tables/llx_c_payment_term.sql       |  2 +-
 htdocs/langs/en_US/admin.lang                 |  1 +
 6 files changed, 54 insertions(+), 32 deletions(-)

diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php
index bef8c6951bf..ef8d7eca38b 100644
--- a/htdocs/admin/dict.php
+++ b/htdocs/admin/dict.php
@@ -41,6 +41,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
 
 $langs->load("errors");
 $langs->load("admin");
+$langs->load("main");
 $langs->load("companies");
 $langs->load("resource");
 $langs->load("holiday");
@@ -155,7 +156,7 @@ $tabsql[8] = "SELECT t.id    as rowid, t.code as code, t.libelle, t.fk_country a
 $tabsql[9] = "SELECT c.code_iso as code, c.label, c.unicode, c.active FROM ".MAIN_DB_PREFIX."c_currencies AS c";
 $tabsql[10]= "SELECT t.rowid, t.code, t.taux, t.localtax1_type, t.localtax1, t.localtax2_type, t.localtax2, c.label as country, c.code as country_code, t.fk_pays as country_id, t.recuperableonly, t.note, t.active, t.accountancy_code_sell, t.accountancy_code_buy FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c WHERE t.fk_pays=c.rowid";
 $tabsql[11]= "SELECT t.rowid as rowid, element, source, code, libelle, active FROM ".MAIN_DB_PREFIX."c_type_contact AS t";
-$tabsql[12]= "SELECT c.rowid as rowid, c.code, c.libelle, c.libelle_facture, c.nbjour, c.fdm, c.decalage, c.active, c.sortorder FROM ".MAIN_DB_PREFIX.'c_payment_term AS c';
+$tabsql[12]= "SELECT c.rowid as rowid, c.code, c.libelle, c.libelle_facture, c.nbjour, c.type_cdr, c.decalage, c.active, c.sortorder FROM ".MAIN_DB_PREFIX.'c_payment_term AS c';
 $tabsql[13]= "SELECT c.id    as rowid, c.code, c.libelle, c.type, c.active, c.accountancy_code FROM ".MAIN_DB_PREFIX."c_paiement AS c";
 $tabsql[14]= "SELECT e.rowid as rowid, e.code as code, e.libelle, e.price, e.organization, e.fk_pays as country_id, c.code as country_code, c.label as country, e.active FROM ".MAIN_DB_PREFIX."c_ecotaxe AS e, ".MAIN_DB_PREFIX."c_country as c WHERE e.fk_pays=c.rowid and c.active=1";
 $tabsql[15]= "SELECT rowid   as rowid, code, label as libelle, width, height, unit, active FROM ".MAIN_DB_PREFIX."c_paper_format";
@@ -219,7 +220,7 @@ $tabfield[8] = "code,libelle,country_id,country";
 $tabfield[9] = "code,label,unicode";
 $tabfield[10]= "country_id,country,code,taux,recuperableonly,localtax1_type,localtax1,localtax2_type,localtax2,accountancy_code_sell,accountancy_code_buy,note";
 $tabfield[11]= "element,source,code,libelle";
-$tabfield[12]= "code,libelle,libelle_facture,nbjour,fdm,decalage,sortorder";
+$tabfield[12]= "code,libelle,libelle_facture,nbjour,type_cdr,decalage,sortorder";
 $tabfield[13]= "code,libelle,type,accountancy_code";
 $tabfield[14]= "code,libelle,price,organization,country_id,country";
 $tabfield[15]= "code,libelle,width,height,unit";
@@ -251,7 +252,7 @@ $tabfieldvalue[8] = "code,libelle,country";
 $tabfieldvalue[9] = "code,label,unicode";
 $tabfieldvalue[10]= "country,code,taux,recuperableonly,localtax1_type,localtax1,localtax2_type,localtax2,accountancy_code_sell,accountancy_code_buy,note";
 $tabfieldvalue[11]= "element,source,code,libelle";
-$tabfieldvalue[12]= "code,libelle,libelle_facture,nbjour,fdm,decalage,sortorder";
+$tabfieldvalue[12]= "code,libelle,libelle_facture,nbjour,type_cdr,decalage,sortorder";
 $tabfieldvalue[13]= "code,libelle,type,accountancy_code";
 $tabfieldvalue[14]= "code,libelle,price,organization,country";
 $tabfieldvalue[15]= "code,libelle,width,height,unit";
@@ -283,7 +284,7 @@ $tabfieldinsert[8] = "code,libelle,fk_country";
 $tabfieldinsert[9] = "code_iso,label,unicode";
 $tabfieldinsert[10]= "fk_pays,code,taux,recuperableonly,localtax1_type,localtax1,localtax2_type,localtax2,accountancy_code_sell,accountancy_code_buy,note";
 $tabfieldinsert[11]= "element,source,code,libelle";
-$tabfieldinsert[12]= "code,libelle,libelle_facture,nbjour,fdm,decalage,sortorder";
+$tabfieldinsert[12]= "code,libelle,libelle_facture,nbjour,type_cdr,decalage,sortorder";
 $tabfieldinsert[13]= "code,libelle,type,accountancy_code";
 $tabfieldinsert[14]= "code,libelle,price,organization,fk_pays";
 $tabfieldinsert[15]= "code,label,width,height,unit";
@@ -920,7 +921,7 @@ if ($id)
             }
             if ($fieldlist[$field]=='recuperableonly') { $valuetoshow=$langs->trans("NPR"); $align="center"; }
             if ($fieldlist[$field]=='nbjour')          { $valuetoshow=$langs->trans("NbOfDays"); }
-            if ($fieldlist[$field]=='fdm')             { $valuetoshow=$langs->trans("AtEndOfMonth"); }
+            if ($fieldlist[$field]=='type_cdr')             { $valuetoshow=$langs->trans("Type"); }
             if ($fieldlist[$field]=='decalage')        { $valuetoshow=$langs->trans("Offset"); }
             if ($fieldlist[$field]=='width')           { $valuetoshow=$langs->trans("Width"); }
             if ($fieldlist[$field]=='height')          { $valuetoshow=$langs->trans("Height"); }
@@ -1077,7 +1078,7 @@ if ($id)
                 if ($fieldlist[$field]=='country')         { $valuetoshow=$langs->trans("Country"); }
                 if ($fieldlist[$field]=='recuperableonly') { $valuetoshow=$langs->trans("NPR"); $align="center"; }
                 if ($fieldlist[$field]=='nbjour')          { $valuetoshow=$langs->trans("NbOfDays"); }
-                if ($fieldlist[$field]=='fdm')             { $valuetoshow=$langs->trans("AtEndOfMonth"); }
+                if ($fieldlist[$field]=='type_cdr')             { $valuetoshow=$langs->trans("Type"); }
                 if ($fieldlist[$field]=='decalage')        { $valuetoshow=$langs->trans("Offset"); }
                 if ($fieldlist[$field]=='width')           { $valuetoshow=$langs->trans("Width"); }
                 if ($fieldlist[$field]=='height')          { $valuetoshow=$langs->trans("Height"); }
@@ -1174,8 +1175,11 @@ if ($id)
                                     $valuetoshow=($key != "Country".strtoupper($obj->country_code)?$obj->country_code." - ".$key:$obj->country);
                                 }
                             }
-                            else if ($fieldlist[$field]=='recuperableonly' || $fieldlist[$field]=='fdm' || $fieldlist[$field] == 'deductible') {
-                                $valuetoshow=yn($valuetoshow);
+                            else if ($fieldlist[$field]=='recuperableonly' || $fieldlist[$field]=='type_cdr' || $fieldlist[$field] == 'deductible') {
+                                //$valuetoshow=yn($valuetoshow);
+								if(empty($valuetoshow)) $valuetoshow = $langs->trans('None');
+								elseif($valuetoshow == 1) $valuetoshow = $langs->trans('AtEndOfMonth');
+								elseif($valuetoshow == 2) $valuetoshow = $langs->trans('CurrentNext');
                                 $align="center";
                             }
                             else if ($fieldlist[$field]=='price' || preg_match('/^amount/i',$fieldlist[$field])) {
@@ -1527,9 +1531,13 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='')
 			print 'user<input type="hidden" name="type" value="user">';
 			print '</td>';
 		}
-		elseif ($fieldlist[$field] == 'recuperableonly' || $fieldlist[$field] == 'fdm' || $fieldlist[$field] == 'deductible') {
+		elseif ($fieldlist[$field] == 'recuperableonly' || $fieldlist[$field] == 'type_cdr' || $fieldlist[$field] == 'deductible') {
 			print '<td>';
-			print $form->selectyesno($fieldlist[$field],(! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:''),1);
+			if($fieldlist[$field] == 'type_cdr') {
+				print $form->selectarray($fieldlist[$field], array(0=>$langs->trans('None'), 1=>$langs->trans('AtEndOfMonth'), 2=>$langs->trans('CurrentNext')), (! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:''));
+			} else {
+				print $form->selectyesno($fieldlist[$field],(! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:''),1);
+			}
 			print '</td>';
 		}
 		elseif (in_array($fieldlist[$field],array('nbjour','decalage','taux','localtax1','localtax2'))) {
diff --git a/htdocs/compta/facture/class/paymentterm.class.php b/htdocs/compta/facture/class/paymentterm.class.php
index d524c501698..2899e3fae56 100644
--- a/htdocs/compta/facture/class/paymentterm.class.php
+++ b/htdocs/compta/facture/class/paymentterm.class.php
@@ -42,7 +42,7 @@ class PaymentTerm // extends CommonObject
 	var $active;
 	var $libelle;
 	var $libelle_facture;
-	var $fdm;
+	var $type_cdr;
 	var $nbjour;
 	var $decalage;
 
@@ -80,7 +80,7 @@ class PaymentTerm // extends CommonObject
 		if (isset($this->active)) $this->active=trim($this->active);
 		if (isset($this->libelle)) $this->libelle=trim($this->libelle);
 		if (isset($this->libelle_facture)) $this->libelle_facture=trim($this->libelle_facture);
-		if (isset($this->fdm)) $this->fdm=trim($this->fdm);
+		if (isset($this->type_cdr)) $this->type_cdr=trim($this->type_cdr);
 		if (isset($this->nbjour)) $this->nbjour=trim($this->nbjour);
 		if (isset($this->decalage)) $this->decalage=trim($this->decalage);
 
@@ -98,7 +98,7 @@ class PaymentTerm // extends CommonObject
 		$sql.= "active,";
 		$sql.= "libelle,";
 		$sql.= "libelle_facture,";
-		$sql.= "fdm,";
+		$sql.= "type_cdr,";
 		$sql.= "nbjour,";
 		$sql.= "decalage";
 
@@ -111,7 +111,7 @@ class PaymentTerm // extends CommonObject
 		$sql.= " ".(! isset($this->active)?'NULL':"'".$this->active."'").",";
 		$sql.= " ".(! isset($this->libelle)?'NULL':"'".$this->db->escape($this->libelle)."'").",";
 		$sql.= " ".(! isset($this->libelle_facture)?'NULL':"'".$this->db->escape($this->libelle_facture)."'").",";
-		$sql.= " ".(! isset($this->fdm)?'NULL':"'".$this->fdm."'").",";
+		$sql.= " ".(! isset($this->type_cdr)?'NULL':"'".$this->type_cdr."'").",";
 		$sql.= " ".(! isset($this->nbjour)?'NULL':"'".$this->nbjour."'").",";
 		$sql.= " ".(! isset($this->decalage)?'NULL':"'".$this->decalage."'")."";
 
@@ -178,7 +178,7 @@ class PaymentTerm // extends CommonObject
 		$sql.= " t.active,";
 		$sql.= " t.libelle,";
 		$sql.= " t.libelle_facture,";
-		$sql.= " t.fdm,";
+		$sql.= " t.type_cdr,";
 		$sql.= " t.nbjour,";
 		$sql.= " t.decalage";
 
@@ -201,7 +201,7 @@ class PaymentTerm // extends CommonObject
 				$this->active = $obj->active;
 				$this->libelle = $obj->libelle;
 				$this->libelle_facture = $obj->libelle_facture;
-				$this->fdm = $obj->fdm;
+				$this->type_cdr = $obj->type_cdr;
 				$this->nbjour = $obj->nbjour;
 				$this->decalage = $obj->decalage;
 
@@ -274,7 +274,7 @@ class PaymentTerm // extends CommonObject
 		if (isset($this->active)) $this->active=trim($this->active);
 		if (isset($this->libelle)) $this->libelle=trim($this->libelle);
 		if (isset($this->libelle_facture)) $this->libelle_facture=trim($this->libelle_facture);
-		if (isset($this->fdm)) $this->fdm=trim($this->fdm);
+		if (isset($this->type_cdr)) $this->type_cdr=trim($this->type_cdr);
 		if (isset($this->nbjour)) $this->nbjour=trim($this->nbjour);
 		if (isset($this->decalage)) $this->decalage=trim($this->decalage);
 
@@ -291,7 +291,7 @@ class PaymentTerm // extends CommonObject
 		$sql.= " active=".(isset($this->active)?$this->active:"null").",";
 		$sql.= " libelle=".(isset($this->libelle)?"'".$this->db->escape($this->libelle)."'":"null").",";
 		$sql.= " libelle_facture=".(isset($this->libelle_facture)?"'".$this->db->escape($this->libelle_facture)."'":"null").",";
-		$sql.= " fdm=".(isset($this->fdm)?$this->fdm:"null").",";
+		$sql.= " type_cdr=".(isset($this->type_cdr)?$this->type_cdr:"null").",";
 		$sql.= " nbjour=".(isset($this->nbjour)?$this->nbjour:"null").",";
 		$sql.= " decalage=".(isset($this->decalage)?$this->decalage:"null")."";
 
@@ -471,7 +471,7 @@ class PaymentTerm // extends CommonObject
 		$this->active='';
 		$this->libelle='';
 		$this->libelle_facture='';
-		$this->fdm='';
+		$this->type_cdr='';
 		$this->nbjour='';
 		$this->decalage='';
 	}
diff --git a/htdocs/core/class/commoninvoice.class.php b/htdocs/core/class/commoninvoice.class.php
index 42265846d04..8f34e7d44c1 100644
--- a/htdocs/core/class/commoninvoice.class.php
+++ b/htdocs/core/class/commoninvoice.class.php
@@ -362,9 +362,9 @@ abstract class CommonInvoice extends CommonObject
 		if (! $cond_reglement) $cond_reglement=$this->cond_reglement_code;
 		if (! $cond_reglement) $cond_reglement=$this->cond_reglement_id;
 
-		$cdr_nbjour=0; $cdr_fdm=0; $cdr_decalage=0;
+		$cdr_nbjour=0; $cdr_type=0; $cdr_decalage=0;
 
-		$sqltemp = 'SELECT c.fdm,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 $sqltemp.= " WHERE c.code='".$this->db->escape($cond_reglement)."'";
@@ -377,7 +377,7 @@ abstract class CommonInvoice extends CommonObject
 			{
 				$obj = $this->db->fetch_object($resqltemp);
 				$cdr_nbjour = $obj->nbjour;
-				$cdr_fdm = $obj->fdm;
+				$cdr_type = $obj->type_cdr;
 				$cdr_decalage = $obj->decalage;
 			}
 		}
@@ -394,7 +394,7 @@ abstract class CommonInvoice extends CommonObject
 		$datelim = $this->date + ($cdr_nbjour * 3600 * 24);
 
 		// 2 : application de la regle "fin de mois"
-		if ($cdr_fdm)
+		if ($cdr_type == 1)
 		{
 			$mois=date('m', $datelim);
 			$annee=date('Y', $datelim);
@@ -411,6 +411,19 @@ abstract class CommonInvoice extends CommonObject
 			$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');
+			
+			$diff = $date_piece - $date_lim_current;
+			
+			if($diff < 0) $datelim = $date_lim_current;
+			else $datelim = $date_lim_next;
+
+		}
 
 		// 3 : application du decalage
 		$datelim += ($cdr_decalage * 3600 * 24);
diff --git a/htdocs/install/mysql/data/llx_c_payment_term.sql b/htdocs/install/mysql/data/llx_c_payment_term.sql
index 68aae57ff4f..a444bfbc466 100644
--- a/htdocs/install/mysql/data/llx_c_payment_term.sql
+++ b/htdocs/install/mysql/data/llx_c_payment_term.sql
@@ -27,11 +27,11 @@
 -- de l'install et tous les sigles '--' sont supprimés.
 --
 
-insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, fdm, nbjour) values (1,'RECEP',       1,1, 'A réception de facture','Réception de facture',0,1);
-insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, fdm, nbjour) values (2,'30D',         2,1, '30 jours','Réglement à 30 jours',0,30);
-insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, fdm, nbjour) values (3,'30DENDMONTH', 3,1, '30 jours fin de mois','Réglement à 30 jours fin de mois',1,30);
-insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, fdm, nbjour) values (4,'60D',         4,1, '60 jours','Réglement à 60 jours',0,60);
-insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, fdm, nbjour) values (5,'60DENDMONTH', 5,1, '60 jours fin de mois','Réglement à 60 jours fin de mois',1,60);
-insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, fdm, nbjour) values (6,'PT_ORDER',    6,1, 'A réception de commande','A réception de commande',0,1);
-insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, fdm, nbjour) values (7,'PT_DELIVERY', 7,1, 'Livraison','Règlement à la livraison',0,1);
-insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, fdm, nbjour) values (8,'PT_5050',     8,1, '50 et 50','Règlement 50% à la commande, 50% à la livraison',0,1);
+insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour) values (1,'RECEP',       1,1, 'A réception de facture','Réception de facture',0,1);
+insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour) values (2,'30D',         2,1, '30 jours','Réglement à 30 jours',0,30);
+insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour) values (3,'30DENDMONTH', 3,1, '30 jours fin de mois','Réglement à 30 jours fin de mois',1,30);
+insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour) values (4,'60D',         4,1, '60 jours','Réglement à 60 jours',0,60);
+insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour) values (5,'60DENDMONTH', 5,1, '60 jours fin de mois','Réglement à 60 jours fin de mois',1,60);
+insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour) values (6,'PT_ORDER',    6,1, 'A réception de commande','A réception de commande',0,1);
+insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour) values (7,'PT_DELIVERY', 7,1, 'Livraison','Règlement à la livraison',0,1);
+insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour) values (8,'PT_5050',     8,1, '50 et 50','Règlement 50% à la commande, 50% à la livraison',0,1);
diff --git a/htdocs/install/mysql/tables/llx_c_payment_term.sql b/htdocs/install/mysql/tables/llx_c_payment_term.sql
index b9c46c7dd0c..9d348e334af 100644
--- a/htdocs/install/mysql/tables/llx_c_payment_term.sql
+++ b/htdocs/install/mysql/tables/llx_c_payment_term.sql
@@ -24,7 +24,7 @@ create table llx_c_payment_term
   active          tinyint DEFAULT 1,
   libelle         varchar(255),
   libelle_facture text,
-  fdm             tinyint,    -- reglement fin de mois
+  type_cdr        tinyint,    -- reglement fin de mois / Le N du mois courant ou suivant
   nbjour          smallint,
   decalage		  smallint,
   module          varchar(32) NULL
diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang
index d5086ca1343..14b0c8a0a3f 100755
--- a/htdocs/langs/en_US/admin.lang
+++ b/htdocs/langs/en_US/admin.lang
@@ -881,6 +881,7 @@ LabelUsedByDefault=Label used by default if no translation can be found for code
 LabelOnDocuments=Label on documents
 NbOfDays=Nb of days
 AtEndOfMonth=At end of month
+CurrentNext=Current/Next
 Offset=Offset
 AlwaysActive=Always active
 UpdateRequired=Your system needs to be updated. To do this, click on <a href="%s">Update now</a>.
-- 
GitLab