diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php
index c89fc5937454e99385edaf59b0c77b3aaad9e1b2..bd1daca8886a7d042dde3dc556060d87dd865851 100644
--- a/htdocs/core/class/extrafields.class.php
+++ b/htdocs/core/class/extrafields.class.php
@@ -1681,7 +1681,7 @@ class ExtraFields
 					// Clean parameters
 					$value_key=dol_mktime($_POST[$keysuffix."options_".$key.$keyprefix."hour"], $_POST[$keysuffix."options_".$key.$keyprefix."min"], 0, $_POST[$keysuffix."options_".$key.$keyprefix."month"], $_POST[$keysuffix."options_".$key.$keyprefix."day"], $_POST[$keysuffix."options_".$key.$keyprefix."year"]);
 				}
-				else if (in_array($key_type,array('checkbox')))
+				else if (in_array($key_type,array('checkbox', 'chkbxlst')))
 				{
 					$value_arr=GETPOST($keysuffix."options_".$key.$keyprefix);
 					// Make sure we get an array even if there's only one checkbox
diff --git a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql
index 11a86724cf0a8f86bf354f589826673bc6af7216..d7e683465110ee9b809d992735ea47ba1d00d8f6 100644
--- a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql
+++ b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql
@@ -159,6 +159,9 @@ CREATE TABLE llx_product_attribute_combination
 
 ALTER TABLE llx_bank_account drop foreign key bank_fk_accountancy_journal;
 
+-- Fix missing entity column after init demo
+ALTER TABLE llx_accounting_journal ADD COLUMN entity integer DEFAULT 1;
+
 -- Add journal entries
 INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (1,'VT', 'Sale journal', 2, 1);
 INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (2,'AC', 'Purchase journal', 3, 1);
@@ -355,4 +358,24 @@ delete from llx_categorie_member where fk_categorie not in (select rowid from ll
 delete from llx_categorie_contact where fk_categorie not in (select rowid from llx_categorie where type = 4);
 delete from llx_categorie_project where fk_categorie not in (select rowid from llx_categorie where type = 5);
 
-ALTER TABLE llx_inventory ADD COLUMN ref varchar(48);
\ No newline at end of file
+ALTER TABLE llx_inventory ADD COLUMN ref varchar(48);
+
+create table llx_loan_schedule
+(
+  rowid				integer AUTO_INCREMENT PRIMARY KEY,
+  fk_loan			integer,
+  datec				datetime,         
+  tms				timestamp,
+  datep				datetime,         
+  amount_capital	real DEFAULT 0,
+  amount_insurance	real DEFAULT 0,
+  amount_interest	real DEFAULT 0,
+  fk_typepayment	integer NOT NULL,
+  num_payment		varchar(50),
+  note_private      text,
+  note_public       text,
+  fk_bank			integer NOT NULL,
+  fk_user_creat		integer,          
+  fk_user_modif		integer           
+)ENGINE=innodb;
+
diff --git a/htdocs/install/mysql/tables/llx_loan_schedule.sql b/htdocs/install/mysql/tables/llx_loan_schedule.sql
new file mode 100644
index 0000000000000000000000000000000000000000..c682b22f276150f132f13275976e0f11bd397d45
--- /dev/null
+++ b/htdocs/install/mysql/tables/llx_loan_schedule.sql
@@ -0,0 +1,37 @@
+-- ===================================================================
+-- Copyright (C) 2014		Alexandre Spangaro   <aspangaro.dolibarr@gmail.com>
+-- Copyright (C) 2015       Frederic France      <frederic.france@free.fr>
+--
+-- 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 <http://www.gnu.org/licenses/>.
+--
+-- ===================================================================
+
+create table llx_loan_schedule
+(
+  rowid				integer AUTO_INCREMENT PRIMARY KEY,
+  fk_loan			integer,
+  datec				datetime,         -- creation date
+  tms				timestamp,
+  datep				datetime,         -- payment date
+  amount_capital	real DEFAULT 0,
+  amount_insurance	real DEFAULT 0,
+  amount_interest	real DEFAULT 0,
+  fk_typepayment	integer NOT NULL,
+  num_payment		varchar(50),
+  note_private      text,
+  note_public       text,
+  fk_bank			integer NOT NULL,
+  fk_user_creat		integer,          -- creation user
+  fk_user_modif		integer           -- last modification user
+)ENGINE=innodb;
diff --git a/htdocs/langs/en_US/loan.lang b/htdocs/langs/en_US/loan.lang
index 927aab2abf4a86ad3a97b04ed4c65202d99277f6..d00b11738be75484b24da384c4695e3211f8064c 100644
--- a/htdocs/langs/en_US/loan.lang
+++ b/htdocs/langs/en_US/loan.lang
@@ -50,3 +50,4 @@ ConfigLoan=Configuration of the module loan
 LOAN_ACCOUNTING_ACCOUNT_CAPITAL=Accounting account capital by default
 LOAN_ACCOUNTING_ACCOUNT_INTEREST=Accounting account interest by default
 LOAN_ACCOUNTING_ACCOUNT_INSURANCE=Accounting account insurance by default
+CreateCalcSchedule=Créer / Modifier échéancier de pret
diff --git a/htdocs/loan/calcmens.php b/htdocs/loan/calcmens.php
new file mode 100644
index 0000000000000000000000000000000000000000..3778f455b041af7afa3e36188a56327d65386831
--- /dev/null
+++ b/htdocs/loan/calcmens.php
@@ -0,0 +1,72 @@
+<?php
+/* TVI
+ * Copyright (C) 2015	Florian HENRY 		<florian.henry@open-concept.pro>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * \file tvi/ajax/list.php
+ * \brief File to return datables output
+ */
+if (! defined('NOTOKENRENEWAL'))
+	define('NOTOKENRENEWAL', '1'); // Disables token renewal
+if (! defined('NOREQUIREMENU'))
+	define('NOREQUIREMENU', '1');
+	// if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1');
+if (! defined('NOREQUIREAJAX'))
+	define('NOREQUIREAJAX', '1');
+	// if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1');
+	// if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1');
+
+
+require '../main.inc.php';
+require DOL_DOCUMENT_ROOT.'/loan/class/loanschedule.class.php';
+
+$mens=GETPOST('mens');
+$capital=GETPOST('capital');
+$rate=GETPOST('rate');
+$echance=GETPOST('echeance');
+$nbterm=GETPOST('nbterm');
+
+top_httphead();
+
+$output=array();
+
+$object = new LoanSchedule($db);
+
+$int = ($capital*($rate/12));
+$int = round($int ,2,PHP_ROUND_HALF_UP);
+$cap_rest = round($capital - ($mens-$int),2,PHP_ROUND_HALF_UP);
+$output[$echance]=array('cap_rest'=>$cap_rest,'cap_rest_str'=>price($cap_rest),'interet'=>$int,'interet_str'=>price($int,0,'',1),'mens'=>$mens);
+
+$echance++;
+$capital=$cap_rest;
+while ($echance<=$nbterm) {
+
+	$mens = round($object->calc_mens($capital,$rate,$nbterm-$echance+1),2,PHP_ROUND_HALF_UP);
+
+	$int = ($capital*($rate/12));
+	$int = round($int ,2,PHP_ROUND_HALF_UP);
+	$cap_rest = round($capital - ($mens-$int),2,PHP_ROUND_HALF_UP);
+
+	$output[$echance]=array('cap_rest'=>$cap_rest,'cap_rest_str'=>price($cap_rest),'interet'=>$int,'interet_str'=>price($int,0,'',1),'mens'=>$mens);
+
+	$capital=$cap_rest;
+	$echance++;
+}
+
+echo json_encode($output);
+
diff --git a/htdocs/loan/card.php b/htdocs/loan/card.php
index 81d43e46ab0bcd0d78b0d42ac8ce92131ba72151..557d48be6802a2e1622ce7debd6eff2ca7f4881b 100644
--- a/htdocs/loan/card.php
+++ b/htdocs/loan/card.php
@@ -72,7 +72,7 @@ if (empty($reshook))
             setEventMessages($loan->error, null, 'errors');
         }
     }
-    
+
     // Delete loan
     if ($action == 'confirm_delete' && $confirm == 'yes')
     {
@@ -89,7 +89,7 @@ if (empty($reshook))
     		setEventMessages($loan->error, null, 'errors');
     	}
     }
-    
+
     // Add loan
     if ($action == 'add' && $user->rights->loan->write)
     {
@@ -99,7 +99,7 @@ if (empty($reshook))
     		$dateend	= dol_mktime(12, 0, 0, GETPOST('endmonth','int'), GETPOST('endday','int'), GETPOST('endyear','int'));
     		$capital 	= price2num(GETPOST('capital'));
             $rate       = GETPOST('rate');
-            
+
     		if (! $capital)
     		{
     		    $error++; $action = 'create';
@@ -120,7 +120,7 @@ if (empty($reshook))
     		    $error++; $action = 'create';
     		    setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Rate")), null, 'errors');
     		}
-    		
+
     		if (! $error)
     		{
     			$object->label					= GETPOST('label');
@@ -133,15 +133,15 @@ if (empty($reshook))
     			$object->note_private 			= GETPOST('note_private');
     			$object->note_public 			= GETPOST('note_public');
     			$object->fk_project 			= GETPOST('fk_project');
-    			
+
     			$accountancy_account_capital	= GETPOST('accountancy_account_capital');
     			$accountancy_account_insurance	= GETPOST('accountancy_account_insurance');
     			$accountancy_account_interest	= GETPOST('accountancy_account_interest');
-    
+
     			if ($accountancy_account_capital <= 0) { $object->account_capital = ''; } else { $object->account_capital = $accountancy_account_capital; }
     			if ($accountancy_account_insurance <= 0) { $object->account_insurance = ''; } else { $object->account_insurance = $accountancy_account_insurance; }
     			if ($accountancy_account_interest <= 0) { $object->account_interest = ''; } else { $object->account_interest = $accountancy_account_interest; }
-    
+
     			$id=$object->create($user);
     			if ($id <= 0)
     			{
@@ -157,7 +157,7 @@ if (empty($reshook))
     		exit();
     	}
     }
-    
+
     // Update record
     else if ($action == 'update' && $user->rights->loan->write)
     {
@@ -168,7 +168,7 @@ if (empty($reshook))
     		$datestart	= dol_mktime(12, 0, 0, GETPOST('startmonth','int'), GETPOST('startday','int'), GETPOST('startyear','int'));
     		$dateend	= dol_mktime(12, 0, 0, GETPOST('endmonth','int'), GETPOST('endday','int'), GETPOST('endyear','int'));
     		$capital 	= price2num(GETPOST('capital'));
-    
+
     		if (! $capital)
     		{
     			setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("LoanCapital")), null, 'errors');
@@ -185,14 +185,14 @@ if (empty($reshook))
 				$accountancy_account_capital	= GETPOST('accountancy_account_capital');
 				$accountancy_account_insurance	= GETPOST('accountancy_account_insurance');
 				$accountancy_account_interest	= GETPOST('accountancy_account_interest');
-	
+
 				if ($accountancy_account_capital <= 0) { $object->account_capital = ''; } else { $object->account_capital = $accountancy_account_capital; }
 				if ($accountancy_account_insurance <= 0) { $object->account_insurance = ''; } else { $object->account_insurance = $accountancy_account_insurance; }
 				if ($accountancy_account_interest <= 0) { $object->account_interest = ''; } else { $object->account_interest = $accountancy_account_interest; }
     		}
-    
+
             $result = $object->update($user);
-    
+
             if ($result > 0)
             {
                 header("Location: " . $_SERVER["PHP_SELF"] . "?id=" . $id);
@@ -209,7 +209,7 @@ if (empty($reshook))
             exit;
         }
     }
-    
+
 	// Link to a project
 	if ($action == 'classin' && $user->rights->loan->write)
 	{
@@ -307,12 +307,12 @@ if ($action == 'create')
 		$langs->load("projects");
 
     	print '<tr><td>'.$langs->trans("Project").'</td><td>';
-        
+
         $numproject=$formproject->select_projects(-1,GETPOST("fk_project"),'fk_project',16,0,1,1);
-        
+
         print '</td></tr>';
     }
-    
+
     // Note Private
     print '<tr>';
     print '<td class="tdtop">'.$langs->trans('NotePrivate').'</td>';
@@ -352,7 +352,7 @@ if ($action == 'create')
 		print $formaccounting->select_account($object->accountancy_account_interest, 'accountancy_account_interest', 1, '', 0, 1);
         print '</td></tr>';
 	}
-	else // For external software 
+	else // For external software
 	{
         // Accountancy_account_capital
         print '<tr><td class="titlefieldcreate">'.$langs->trans("LoanAccountancyCapitalCode").'</td>';
@@ -417,10 +417,22 @@ if ($id > 0)
 
 		dol_fiche_head($head, 'card', $langs->trans("Loan"), 0, 'bill');
 
+		print '<script type="text/javascript">' . "\n";
+		print '  	function popEcheancier() {' . "\n";
+		print '  		$div = $(\'<div id="popCalendar"><iframe width="100%" height="100%" frameborder="0" src="createschedule.php?loanid=' . $object->id . '"></iframe></div>\');' . "\n";
+		print '  		$div.dialog({' . "\n";
+		print '  			modal:true' . "\n";
+		print '  			,width:"90%"' . "\n";
+		print '  			,height:$(window).height() - 150' . "\n";
+		print '  		});' . "\n";
+		print '  	}' . "\n";
+		print '</script>';
+
+
 		// Loan card
-		
+
 		$linkback = '<a href="' . DOL_URL_ROOT . '/loan/index.php">' . $langs->trans("BackToList") . '</a>';
-		
+
 		$morehtmlref='<div class="refidno">';
 		// Ref loan
 		$morehtmlref.=$form->editfieldkey("Label", 'label', $object->label, $object, $user->rights->loan->write, 'string', '', 0, 1);
@@ -458,7 +470,7 @@ if ($id > 0)
 	        }
 	    }
 	    $morehtmlref.='</div>';
-		
+
 		$object->totalpaid = $totalpaid;   // To give a chance to dol_banner_tab to use already paid amount to show correct status
 
 		dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', $morehtmlref, '', 0, '', $morehtmlright);
@@ -652,7 +664,7 @@ if ($id > 0)
 			while ($i < $num)
 			{
 				$objp = $db->fetch_object($resql);
-				
+
 				print '<tr class="oddeven">';
 				print '<td><a href="'.DOL_URL_ROOT.'/loan/payment/card.php?id='.$objp->rowid.'">'.img_object($langs->trans("Payment"),"payment").' '.$objp->rowid.'</a></td>';
 				print '<td>'.dol_print_date($db->jdate($objp->dp),'day')."</td>\n";
@@ -713,31 +725,33 @@ if ($id > 0)
  			if (empty($reshook))
             {
                 print '<div class="tabsAction">';
-    
+
     			// Edit
     			if ($user->rights->loan->write)
     			{
+    				print '<a href="javascript:popEcheancier()" class="butAction">'.$langs->trans('CreateCalcSchedule').'</a>';
+
     				print '<a class="butAction" href="'.DOL_URL_ROOT.'/loan/card.php?id='.$object->id.'&amp;action=edit">'.$langs->trans("Modify").'</a>';
     			}
-    
+
     			// Emit payment
     			if ($object->paid == 0 && ((price2num($object->capital) > 0 && round($staytopay) < 0) || (price2num($object->capital) > 0 && round($staytopay) > 0)) && $user->rights->loan->write)
     			{
     				print '<a class="butAction" href="'.DOL_URL_ROOT.'/loan/payment/payment.php?id='.$object->id.'&amp;action=create">'.$langs->trans("DoPayment").'</a>';
     			}
-    
+
     			// Classify 'paid'
     			if ($object->paid == 0 && round($staytopay) <=0 && $user->rights->loan->write)
     			{
     				print '<a class="butAction" href="'.DOL_URL_ROOT.'/loan/card.php?id='.$object->id.'&amp;action=paid">'.$langs->trans("ClassifyPaid").'</a>';
     			}
-    
+
     			// Delete
     			if ($user->rights->loan->delete)
     			{
     				print '<a class="butActionDelete" href="'.DOL_URL_ROOT.'/loan/card.php?id='.$object->id.'&amp;action=delete">'.$langs->trans("Delete").'</a>';
     			}
-    
+
     			print "</div>";
             }
 		}
diff --git a/htdocs/loan/class/loanschedule.class.php b/htdocs/loan/class/loanschedule.class.php
new file mode 100644
index 0000000000000000000000000000000000000000..1e519e6a2af6e2d0a845e1914c1e162fe7d29ebe
--- /dev/null
+++ b/htdocs/loan/class/loanschedule.class.php
@@ -0,0 +1,526 @@
+<?php
+/* Copyright (C) 2017	Florian HENRY <florian.henry@atm-consulting.fr>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ *      \file       htdocs/loan/class/loanschedule.class.php
+ *		\ingroup    facture
+ *		\brief      File of class to manage schedule of loans
+ */
+
+require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
+
+
+/**     \class      LoanSchedule
+ *		\brief      Class to manage Schedule of loans
+ */
+class LoanSchedule extends CommonObject
+{
+	public $element='loan_schedule';			//!< Id that identify managed objects
+	public $table_element='loan_schedule';	//!< Name of table without prefix where object is stored
+
+	var $fk_loan;
+	var $datec='';
+	var $tms='';
+	var $datep='';
+    var $amounts=array();   // Array of amounts
+    var $amount_capital;    // Total amount of payment
+	var $amount_insurance;
+	var $amount_interest;
+	var $fk_typepayment;
+	var $num_payment;
+	var $fk_bank;
+	var $fk_user_creat;
+	var $fk_user_modif;
+	var $lines=array();
+
+	/**
+	 * @deprecated
+	 * @see amount, amounts
+	 */
+	var $total;
+
+	/**
+	 *	Constructor
+	 *
+	 *  @param		DoliDB		$db      Database handler
+	 */
+	function __construct($db)
+	{
+		$this->db = $db;
+	}
+
+	/**
+	 *  Create payment of loan into database.
+     *  Use this->amounts to have list of lines for the payment
+     *
+	 *  @param      User		$user   User making payment
+	 *  @return     int     			<0 if KO, id of payment if OK
+	 */
+	function create($user)
+	{
+		global $conf, $langs;
+
+		$error=0;
+
+        $now=dol_now();
+
+        // Validate parameters
+		if (! $this->datepaid)
+		{
+			$this->error='ErrorBadValueForParameter';
+			return -1;
+		}
+
+		// Clean parameters
+		if (isset($this->fk_loan)) 			$this->fk_loan = trim($this->fk_loan);
+		if (isset($this->amount_capital))	$this->amount_capital = trim($this->amount_capital?$this->amount_capital:0);
+		if (isset($this->amount_insurance))	$this->amount_insurance = trim($this->amount_insurance?$this->amount_insurance:0);
+		if (isset($this->amount_interest))	$this->amount_interest = trim($this->amount_interest?$this->amount_interest:0);
+		if (isset($this->fk_typepayment))	$this->fk_typepayment = trim($this->fk_typepayment);
+		if (isset($this->fk_bank))			$this->fk_bank = trim($this->fk_bank);
+		if (isset($this->fk_user_creat))	$this->fk_user_creat = trim($this->fk_user_creat);
+		if (isset($this->fk_user_modif))	$this->fk_user_modif = trim($this->fk_user_modif);
+
+        $totalamount = $this->amount_capital + $this->amount_insurance + $this->amount_interest;
+        $totalamount = price2num($totalamount);
+
+        // Check parameters
+        if ($totalamount == 0) {
+        	$this->errors[]='step1';
+        	return -1; // Negative amounts are accepted for reject prelevement but not null
+        }
+
+
+		$this->db->begin();
+
+		if ($totalamount != 0)
+		{
+			$sql = "INSERT INTO ".MAIN_DB_PREFIX.$this->table_element." (fk_loan, datec, datep, amount_capital, amount_insurance, amount_interest,";
+			$sql.= " fk_typepayment, fk_user_creat, fk_bank)";
+			$sql.= " VALUES (".$this->fk_loan.", '".$this->db->idate($now)."',";
+			$sql.= " '".$this->db->idate($this->datepaid)."',";
+			$sql.= " ".$this->amount_capital.",";
+			$sql.= " ".$this->amount_insurance.",";
+			$sql.= " ".$this->amount_interest.",";
+			$sql.= " ".$this->fk_typepayment.", ";
+			$sql.= " ".$user->id.",";
+			$sql.= " ".$this->fk_bank . ")";
+
+			dol_syslog(get_class($this)."::create", LOG_DEBUG);
+			$resql=$this->db->query($sql);
+			if ($resql)
+			{
+				$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."payment_loan");
+			}
+			else
+			{
+                $this->error=$this->db->lasterror();
+				$error++;
+			}
+
+		}
+
+		if ($totalamount != 0 && ! $error)
+		{
+		    $this->amount_capital=$totalamount;
+            $this->total=$totalamount;    // deprecated
+		    $this->db->commit();
+			return $this->id;
+		}
+		else
+		{
+			$this->errors[]=$this->db->lasterror();
+			$this->db->rollback();
+			return -1;
+		}
+	}
+
+	/**
+	 *  Load object in memory from database
+	 *
+	 *  @param	int		$id         Id object
+	 *  @return int         		<0 if KO, >0 if OK
+	 */
+	function fetch($id)
+	{
+		global $langs;
+		$sql = "SELECT";
+		$sql.= " t.rowid,";
+		$sql.= " t.fk_loan,";
+		$sql.= " t.datec,";
+		$sql.= " t.tms,";
+		$sql.= " t.datep,";
+		$sql.= " t.amount_capital,";
+		$sql.= " t.amount_insurance,";
+		$sql.= " t.amount_interest,";
+		$sql.= " t.fk_typepayment,";
+		$sql.= " t.num_payment,";
+        $sql.= " t.note_private,";
+        $sql.= " t.note_public,";
+		$sql.= " t.fk_bank,";
+		$sql.= " t.fk_user_creat,";
+		$sql.= " t.fk_user_modif,";
+		$sql.= " pt.code as type_code, pt.libelle as type_libelle,";
+		$sql.= ' b.fk_account';
+		$sql.= " FROM (".MAIN_DB_PREFIX."c_paiement as pt, ".MAIN_DB_PREFIX.$this->table_element." as t)";
+		$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON t.fk_bank = b.rowid';
+		$sql.= " WHERE t.rowid = ".$id." AND t.fk_typepayment = pt.id";
+
+		dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
+		$resql=$this->db->query($sql);
+		if ($resql)
+	{
+		if ($this->db->num_rows($resql))
+		{
+			$obj = $this->db->fetch_object($resql);
+
+			$this->id = $obj->rowid;
+			$this->ref = $obj->rowid;
+
+			$this->fk_loan = $obj->fk_loan;
+			$this->datec = $this->db->jdate($obj->datec);
+			$this->tms = $this->db->jdate($obj->tms);
+			$this->datep = $this->db->jdate($obj->datep);
+			$this->amount_capital = $obj->amount_capital;
+			$this->amount_insurance = $obj->amount_insurance;
+			$this->amount_interest = $obj->amount_interest;
+			$this->fk_typepayment = $obj->fk_typepayment;
+			$this->num_payment = $obj->num_payment;
+			$this->note_private = $obj->note_private;
+			$this->note_public = $obj->note_public;
+			$this->fk_bank = $obj->fk_bank;
+			$this->fk_user_creat = $obj->fk_user_creat;
+			$this->fk_user_modif = $obj->fk_user_modif;
+
+			$this->type_code = $obj->type_code;
+			$this->type_libelle = $obj->type_libelle;
+
+			$this->bank_account   = $obj->fk_account;
+			$this->bank_line      = $obj->fk_bank;
+		}
+		$this->db->free($resql);
+
+			return 1;
+		}
+		else
+		{
+			$this->error="Error ".$this->db->lasterror();
+			return -1;
+		}
+	}
+
+
+	/**
+	 *  Update database
+	 *
+	 *  @param	User	$user        	User that modify
+	 *  @param  int		$notrigger	    0=launch triggers after, 1=disable triggers
+	 *  @return int         			<0 if KO, >0 if OK
+	 */
+	function update($user=0, $notrigger=0)
+	{
+		global $conf, $langs;
+		$error=0;
+
+		// Clean parameters
+		if (isset($this->fk_loan)) $this->fk_loan=trim($this->fk_loan);
+		if (isset($this->amount_capital)) $this->amount_capital=trim($this->amount_capital);
+		if (isset($this->amount_insurance)) $this->amount_insurance=trim($this->amount_insurance);
+		if (isset($this->amount_interest)) $this->amount_interest=trim($this->amount_interest);
+		if (isset($this->fk_typepayment)) $this->fk_typepayment=trim($this->fk_typepayment);
+		if (isset($this->num_payment)) $this->num_payment=trim($this->num_payment);
+		if (isset($this->note_private)) $this->note_private=trim($this->note_private);
+		if (isset($this->note_public)) $this->note_public=trim($this->note_public);
+		if (isset($this->fk_bank)) $this->fk_bank=trim($this->fk_bank);
+		if (isset($this->fk_user_creat)) $this->fk_user_creat=trim($this->fk_user_creat);
+		if (isset($this->fk_user_modif)) $this->fk_user_modif=trim($this->fk_user_modif);
+
+		// Check parameters
+		// Put here code to add control on parameters values
+
+		// Update request
+		$sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET";
+
+		$sql.= " fk_loan=".(isset($this->fk_loan)?$this->fk_loan:"null").",";
+		$sql.= " datec=".(dol_strlen($this->datec)!=0 ? "'".$this->db->idate($this->datec)."'" : 'null').",";
+		$sql.= " tms=".(dol_strlen($this->tms)!=0 ? "'".$this->db->idate($this->tms)."'" : 'null').",";
+		$sql.= " datep=".(dol_strlen($this->datep)!=0 ? "'".$this->db->idate($this->datep)."'" : 'null').",";
+		$sql.= " amount_capital=".(isset($this->amount_capital)?$this->amount_capital:"null").",";
+		$sql.= " amount_insurance=".(isset($this->amount_insurance)?$this->amount_insurance:"null").",";
+		$sql.= " amount_interest=".(isset($this->amount_interest)?$this->amount_interest:"null").",";
+		$sql.= " fk_typepayment=".(isset($this->fk_typepayment)?$this->fk_typepayment:"null").",";
+		$sql.= " num_payment=".(isset($this->num_payment)?"'".$this->db->escape($this->num_payment)."'":"null").",";
+		$sql.= " note_private=".(isset($this->note_private)?"'".$this->db->escape($this->note_private)."'":"null").",";
+		$sql.= " note_public=".(isset($this->note_public)?"'".$this->db->escape($this->note_public)."'":"null").",";
+		$sql.= " fk_bank=".(isset($this->fk_bank)?$this->fk_bank:"null").",";
+		$sql.= " fk_user_creat=".(isset($this->fk_user_creat)?$this->fk_user_creat:"null").",";
+		$sql.= " fk_user_modif=".(isset($this->fk_user_modif)?$this->fk_user_modif:"null")."";
+
+		$sql.= " WHERE rowid=".$this->id;
+
+		$this->db->begin();
+
+		dol_syslog(get_class($this)."::update", LOG_DEBUG);
+		$resql = $this->db->query($sql);
+		if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); }
+
+		if (! $error)
+		{
+			if (! $notrigger)
+			{
+				// Uncomment this and change MYOBJECT to your own tag if you
+				// want this action call a trigger.
+
+				//// Call triggers
+				//include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
+				//$interface=new Interfaces($this->db);
+				//$result=$interface->run_triggers('MYOBJECT_MODIFY',$this,$user,$langs,$conf);
+				//if ($result < 0) { $error++; $this->errors=$interface->errors; }
+				//// End call triggers
+			}
+		}
+
+		// Commit or rollback
+		if ($error)
+		{
+			$this->db->rollback();
+			return -1*$error;
+		}
+		else
+		{
+			$this->db->commit();
+			return 1;
+		}
+	}
+
+
+	/**
+	 *  Delete object in database
+	 *
+	 *  @param	User	$user        	User that delete
+	 *  @param  int		$notrigger		0=launch triggers after, 1=disable triggers
+	 *  @return int						<0 if KO, >0 if OK
+	 */
+	function delete($user, $notrigger=0)
+	{
+		global $conf, $langs;
+		$error=0;
+
+		$this->db->begin();
+
+	    if (! $error)
+		{
+			$sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element;
+			$sql.= " WHERE rowid=".$this->id;
+
+			dol_syslog(get_class($this)."::delete", LOG_DEBUG);
+			$resql = $this->db->query($sql);
+			if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); }
+		}
+
+		if (! $error)
+		{
+			if (! $notrigger)
+			{
+				// Uncomment this and change MYOBJECT to your own tag if you
+				// want this action call a trigger.
+
+				//// Call triggers
+				//include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
+				//$interface=new Interfaces($this->db);
+				//$result=$interface->run_triggers('MYOBJECT_DELETE',$this,$user,$langs,$conf);
+				//if ($result < 0) { $error++; $this->errors=$interface->errors; }
+				//// End call triggers
+			}
+		}
+
+		// Commit or rollback
+		if ($error)
+		{
+			foreach($this->errors as $errmsg)
+			{
+				dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR);
+				$this->error.=($this->error?', '.$errmsg:$errmsg);
+			}
+			$this->db->rollback();
+			return -1*$error;
+		}
+		else
+		{
+			$this->db->commit();
+			return 1;
+		}
+	}
+
+	function calc_mens($capital,$rate,$nbterm)
+	{
+		$result='';
+
+		if (!empty($capital)&&!empty($rate)&&!empty($nbterm))
+		{
+			$result=($capital*($rate/12))/(1-pow((1+($rate/12)),($nbterm*-1)));
+		}
+
+		return $result;
+	}
+
+
+	/**
+	 *  Load all object in memory from database
+	 *
+	 *  @param	int		$id         Id object
+	 *  @return int         		<0 if KO, >0 if OK
+	 */
+	function fetchall($loan)
+	{
+		global $langs;
+
+		$sql = "SELECT";
+		$sql.= " t.rowid,";
+		$sql.= " t.fk_loan,";
+		$sql.= " t.datec,";
+		$sql.= " t.tms,";
+		$sql.= " t.datep,";
+		$sql.= " t.amount_capital,";
+		$sql.= " t.amount_insurance,";
+		$sql.= " t.amount_interest,";
+		$sql.= " t.fk_typepayment,";
+		$sql.= " t.num_payment,";
+		$sql.= " t.note_private,";
+		$sql.= " t.note_public,";
+		$sql.= " t.fk_bank,";
+		$sql.= " t.fk_user_creat,";
+		$sql.= " t.fk_user_modif";
+		$sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t";
+		$sql.= " WHERE t.fk_loan = ".$loan;
+
+		dol_syslog(get_class($this)."::fetchall", LOG_DEBUG);
+		$resql=$this->db->query($sql);
+
+		if ($resql)
+		{
+			while($obj = $this->db->fetch_object($resql))
+			{
+				$line = New LoanSchedule($this->db);
+				$line->id = $obj->rowid;
+				$line->ref = $obj->rowid;
+
+				$line->fk_loan = $obj->fk_loan;
+				$line->datec = $this->db->jdate($obj->datec);
+				$line->tms = $this->db->jdate($obj->tms);
+				$line->datep = $this->db->jdate($obj->datep);
+				$line->amount_capital = $obj->amount_capital;
+				$line->amount_insurance = $obj->amount_insurance;
+				$line->amount_interest = $obj->amount_interest;
+				$line->fk_typepayment = $obj->fk_typepayment;
+				$line->num_payment = $obj->num_payment;
+				$line->note_private = $obj->note_private;
+				$line->note_public = $obj->note_public;
+				$line->fk_bank = $obj->fk_bank;
+				$line->fk_user_creat = $obj->fk_user_creat;
+				$line->fk_user_modif = $obj->fk_user_modif;
+
+				$this->lines[] = $line;
+			}
+			$this->db->free($resql);
+			return 1;
+		}
+		else
+		{
+			$this->error="Error ".$this->db->lasterror();
+			return -1;
+		}
+	}
+
+	function trans_paiment()
+	{
+		require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php';
+		require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php';
+		require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
+
+		$toinsert = array();
+
+		$sql = "SELECT l.rowid";
+		$sql.= " FROM ".MAIN_DB_PREFIX."loan as l ";
+		$sql.= " WHERE l.paid = 0";
+		$resql=$this->db->query($sql);
+
+		if($resql){
+			while($obj = $this->db->fetch_object($resql)){
+				$lastrecorded = $this->lastpaiment($obj->rowid);
+				$toinsert = $this->paimenttorecord($obj->rowid, $lastrecorded);
+				if(count($toinsert)>0){
+					foreach ($toinsert as $echid){
+						$this->db->begin();
+						$sql = "INSERT INTO " .MAIN_DB_PREFIX . "payment_loan ";
+						$sql.= "(fk_loan,datec,tms,datep,amount_capital,amount_insurance,amount_interest,fk_typepayment,num_payment,note_private,note_public,fk_bank,fk_user_creat,fk_user_modif) ";
+						$sql.= "SELECT fk_loan,datec,tms,datep,amount_capital,amount_insurance,amount_interest,fk_typepayment,num_payment,note_private,note_public,fk_bank,fk_user_creat,fk_user_modif FROM " . MAIN_DB_PREFIX . "loan_schedule WHERE rowid =" .$echid;
+						$res=$this->db->query($sql);
+						if($res){
+							$this->db->commit();
+						}else {
+							$this->db->rollback();
+						}
+					}
+				}
+			}
+		}
+	}
+
+
+	function lastpaiment($loan)
+	{
+		$sql = "SELECT p.datep";
+		$sql.= " FROM ".MAIN_DB_PREFIX."payment_loan as p ";
+		$sql.= " WHERE p.fk_loan = " . $loan;
+		$sql.= " ORDER BY p.datep DESC ";
+		$sql.= " LIMIT 1 ";
+
+		$resql=$this->db->query($sql);
+
+		if($resql){
+			$obj = $this->db->fetch_object($resql);
+			return $this->db->jdate($obj->datep);
+		}else{
+			return -1;
+		}
+	}
+
+	function paimenttorecord($loan,$datemax)
+	{
+		$sql = "SELECT p.rowid";
+		$sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element." as p ";
+		$sql.= " WHERE p.fk_loan = " . $loan;
+		if(!empty($datemax)){ $sql.= " AND p.datep > '" . $this->db->idate($datemax) ."'";}
+		$sql.= " AND p.datep <= '" . $this->db->idate(dol_now()). "'";
+
+
+		$resql=$this->db->query($sql);
+
+		if($resql){
+			while($obj = $this->db->fetch_object($resql))
+			{
+				$result[] = $obj->rowid;
+
+			}
+
+		}
+
+		return $result;
+	}
+}
+
diff --git a/htdocs/loan/createschedule.php b/htdocs/loan/createschedule.php
new file mode 100644
index 0000000000000000000000000000000000000000..0d15d1b2de652284ba296f84de418fba1ef5d5d3
--- /dev/null
+++ b/htdocs/loan/createschedule.php
@@ -0,0 +1,208 @@
+<?php
+/* Copyright (C) 2017	Franck Moreau   <franck.moreau@theobald.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ *      \file       htdocs/loan/createecheancier.php
+ *		\ingroup    loan
+ *		\brief      Schedule card
+ */
+
+require '../main.inc.php';
+
+require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/loan/class/loanschedule.class.php';
+
+global $user;
+
+$loanid = GETPOST('loanid', 'int');
+$action = GETPOST('action');
+
+$object = new Loan($db);
+$object->fetch($loanid);
+
+$langs->load('loan');
+
+if ($action == 'createecheancier') {
+
+	$i=1;
+	while($i <$object->nbterm+1){
+
+		$date =  GETPOST('hi_date'.$i,'int');
+		$mens = GETPOST('mens'.$i);
+		$int = GETPOST('hi_interets'.$i);
+
+		$echeance = new LoanSchedule($db);
+
+		$echeance->fk_loan = $object->id;
+		$echeance->datec = dol_now();
+		$echeance->tms = dol_now();
+		$echeance->datepaid = $date;
+		$echeance->amount_capital = $mens-$int;
+		$echeance->amount_insurance = 0;
+		$echeance->amount_interest = $int;
+		$echeance->fk_typepayment = 3;
+		$echeance->fk_bank = 1;
+		$echeance->fk_user_creat = $user->id;
+		$echeance->fk_user_modif = $user->id;
+		$result=$echeance->create($user);
+		if ($result<0) {
+			setEventMessages(null, $echeance->errors,'errors');
+		}
+		$i++;
+	}
+}
+
+if ($action == 'updateecheancier') {
+
+	$i=1;
+	while($i <$object->nbterm+1){
+
+		$mens = GETPOST('mens'.$i);
+		$int = GETPOST('hi_interets'.$i);
+		$id = GETPOST('hi_rowid'.$i);
+		$echeance = new LoanSchedule($db);
+		$echeance->fetch($id);
+		$echeance->tms = dol_now();
+		$echeance->amount_capital = $mens-$int;
+		$echeance->amount_insurance = 0;
+		$echeance->amount_interest = $int;
+		$echeance->fk_user_modif = $user->id;
+		$result= $echeance->update($user,0);
+		if ($result<0) {
+			setEventMessages(null, $echeance->errors,'errors');
+		}
+		$i++;
+	}
+}
+
+$echeance = new LoanSchedule($db);
+$echeance->fetchall($object->id);
+
+top_htmlhead('', '');
+$var = ! $var;
+
+
+?>
+<script type="text/javascript" language="javascript">
+$(document).ready(function() {
+	$('[name^="mens"]').focusout(function() {
+		var echeance=$(this).attr('ech');
+		var mens=$(this).val();
+		var idcap=echeance-1;
+		idcap = '#hi_capital'+idcap;
+		var capital=$(idcap).val();
+		$.ajax({
+			  dataType: 'json',
+			  url: 'calcmens.php',
+			  data: { echeance: echeance, mens: mens, capital:capital, rate:<?php echo $object->rate/100;?> , nbterm : <?php echo $object->nbterm;?>},
+			  success: function(data) {
+				$.each(data, function(index, element) {
+					var idcap_res='#hi_capital'+index;
+					var idcap_res_srt='#capital'+index;
+					var interet_res='#hi_interets'+index;
+					var interet_res_str='#interets'+index;
+					var men_res='#mens'+index;
+					$(idcap_res).val(element.cap_rest);
+					$(idcap_res_srt).text(element.cap_rest_str+' €');
+					$(interet_res).val(element.interet);
+					$(interet_res_str).text(element.interet_str+' €');
+					$(men_res).val(element.mens);
+				});
+			}
+		});
+	});
+});
+</script>
+<?php
+
+
+print '<form name="createecheancier" action="' . $_SERVER["PHP_SELF"] . '" method="POST">';
+print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
+print '<input type="hidden" name="loanid" value="' . $loanid . '">';
+if(count($echeance->lines)>0){
+	print '<input type="hidden" name="action" value="updateecheancier">';
+}else{
+	print '<input type="hidden" name="action" value="createecheancier">';
+}
+print '<table class="border" width="100%">';
+print '<tr class="liste_titre">';
+print '<th align="center" colspan="5">' . "Création d'échéancier</th>";
+print '</tr>';
+
+print '<tr class="liste_titre">';
+Print '<th width="10%" align="center"> Echéance </th>';
+Print '<th width="10%" align="center"> Date </th>';
+Print '<th width="10%" align="center"> Montant </th>';
+Print '<th width="20%" align="center"> Intérêts </th>';
+Print '<th width="40%" align="center"> Capital restant du </th>';
+print '</tr>';
+
+if ($object->nbterm > 0 && count($echeance->lines)==0)
+{
+	$i=1;
+	$capital = $object->capital;
+	while($i <$object->nbterm+1){
+		$mens = round($echeance->calc_mens($capital, $object->rate/100, $object->nbterm-$i+1),2,PHP_ROUND_HALF_UP);
+		$int = ($capital*($object->rate/12))/100;
+		$int = round($int ,2,PHP_ROUND_HALF_UP);
+		$cap_rest = round($capital - ($mens-$int),2,PHP_ROUND_HALF_UP);
+		print '<tr>';
+		print '<td align="center" id="n'.$i.'">' . $i .'</td>';
+		print '<td align="center" id ="date' .$i .'"><input type="hidden" name="hi_date' .$i .'" id ="hi_date' .$i .'" value="' . dol_time_plus_duree($object->datestart, $i-1, 'm') . '">' . dol_print_date(dol_time_plus_duree($object->datestart, $i-1, 'm'),'day') . '</td>';
+		print '<td align="center"><input name="mens'.$i.'" id="mens'.$i.'" size="5" value="'.$mens.'" ech="'.$i.'"> €</td>';
+		print '<td align="center" id="interets'.$i.'">'.price($int,0,'',1).' €</td><input type="hidden" name="hi_interets' .$i .'" id ="hi_interets' .$i .'" value="' . $int . '">';
+		print '<td align="center" id="capital'.$i.'">'.price($cap_rest).' €</td><input type="hidden" name="hi_capital' .$i .'" id ="hi_capital' .$i .'" value="' . $cap_rest . '">';
+		print '</tr>';
+		$i++;
+		$capital = $cap_rest;
+	}
+}elseif(count($echeance->lines)>0){
+	$i=1;
+	$capital = $object->capital;
+	foreach ($echeance->lines as $line){
+		$mens = $line->amount_capital+$line->amount_insurance+$line->amount_interest;
+		$int = $line->amount_interest;
+		$cap_rest = round($capital - ($mens-$int),2,PHP_ROUND_HALF_UP);
+		print '<tr>';
+		print '<td align="center" id="n'.$i.'"><input type="hidden" name="hi_rowid' .$i .'" id ="hi_rowid' .$i .'" value="' . $line->id . '">' . $i .'</td>';
+		print '<td align="center" id ="date' .$i .'"><input type="hidden" name="hi_date' .$i .'" id ="hi_date' .$i .'" value="' . $line->datep . '">' . dol_print_date($line->datep,'day') . '</td>';
+		if($line->datep > dol_now()){
+			print '<td align="center"><input name="mens'.$i.'" id="mens'.$i.'" size="5" value="'.$mens.'" ech="'.$i.'"> €</td>';
+		}else{
+			print '<td align="center">' . price($mens) . ' €</td><input type="hidden" name="mens' .$i .'" id ="mens' .$i .'" value="' . $mens . '">';
+		}
+		print '<td align="center" id="interets'.$i.'">'.price($int,0,'',1).' €</td><input type="hidden" name="hi_interets' .$i .'" id ="hi_interets' .$i .'" value="' . $int . '">';
+		print '<td align="center" id="capital'.$i.'">'.price($cap_rest).' €</td><input type="hidden" name="hi_capital' .$i .'" id ="hi_capital' .$i .'" value="' . $cap_rest . '">';
+		print '</tr>';
+		$i++;
+		$capital = $cap_rest;
+	}
+}
+
+print '</table>';
+print '</br>';
+print '</br>';
+print '<div align="center"><input class="button" type="submit" value="'.$langs->trans("Save").'"></div>';
+print '</form>';
+
+llxFooter();
+$db->close();
+
+
+