From 19bec6b0b393edd9d3a156260a528cf2d9aa86e7 Mon Sep 17 00:00:00 2001
From: bobby <bobby@bobby-ubuntu>
Date: Thu, 14 Jan 2016 18:24:02 +0100
Subject: [PATCH] Manual merge from 3.8 backported

---
 htdocs/accountancy/bookkeeping/card.php       |   14 +-
 htdocs/accountancy/bookkeeping/list.php       |  290 ++--
 htdocs/accountancy/bookkeeping/listbyyear.php |  259 ++-
 .../class/accountingaccount.class.php         |    5 +
 .../accountancy/class/bookkeeping.class.php   | 1408 +++++++++++------
 .../class/html.formventilation.class.php      |   32 +-
 htdocs/accountancy/customer/list.php          |    3 +
 htdocs/accountancy/journal/bankjournal.php    |    4 +-
 .../accountancy/journal/purchasesjournal.php  |    6 +-
 htdocs/accountancy/journal/sellsjournal.php   |    7 +-
 10 files changed, 1274 insertions(+), 754 deletions(-)

diff --git a/htdocs/accountancy/bookkeeping/card.php b/htdocs/accountancy/bookkeeping/card.php
index 77c9a4a135e..d2092a32944 100644
--- a/htdocs/accountancy/bookkeeping/card.php
+++ b/htdocs/accountancy/bookkeeping/card.php
@@ -91,7 +91,7 @@ if ($action == "confirm_update") {
                 $book->sens = 'C';
             }
 
-            $result = $book->update();
+			$result = $book->update($user);
             if ($result < 0) {
                 setEventMessages($book->error, $book->errors, 'errors');
             } else {
@@ -214,6 +214,18 @@ if ($action == 'create') {
             $conf->global->ACCOUNTING_EXPENSEREPORT_JOURNAL => $conf->global->ACCOUNTING_EXPENSEREPORT_JOURNAL
     );
 
+    $sql = 'SELECT DISTINCT accountancy_journal FROM '.MAIN_DB_PREFIX.'bank_account WHERE clos=0';
+    $resql=$db->query($sql);
+    if (!$resql) {
+    	setEventMessages($db->lasterror,null,'errors');
+    } else {
+    	while ($obj_bank=$db->fetch_object($resql)) {
+    		if (!empty($obj_bank->accountancy_journal)) {
+    			$code_journal_array[$obj_bank->accountancy_journal]=$obj_bank->accountancy_journal;
+    		}
+    	}
+    }
+
     $book = new BookKeeping($db);
     $next_num_mvt = $book->getNextNumMvt();
 
diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php
index c5fea407a12..4180c741205 100644
--- a/htdocs/accountancy/bookkeeping/list.php
+++ b/htdocs/accountancy/bookkeeping/list.php
@@ -43,17 +43,20 @@ $search_doc_ref = GETPOST("search_doc_ref");
 $search_account = GETPOST("search_account");
 $search_thirdparty = GETPOST("search_thirdparty");
 $search_journal = GETPOST("search_journal");
-$limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit;
+$limit = GETPOST('limit') ? GETPOST('limit', 'int') : $conf->liste_limit;
 
 if ($sortorder == "")
 	$sortorder = "ASC";
 if ($sortfield == "")
-	$sortfield = "bk.rowid";
+	$sortfield = "t.rowid";
 
 $offset = $limit * $page;
 
+$object = new BookKeeping($db);
+
 $formventilation = new FormVentilation($db);
 $formother = new FormOther($db);
+$form = new Form($db);
 
 if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter")) // Both test are required to be compatible with all browsers
 {
@@ -64,6 +67,33 @@ if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter")) // Both
 	$search_journal = "";
 }
 
+$options='';
+$filter = array ();
+if (! empty($search_doc_type)) {
+	$filter['t.piece_num'] = $search_piece_num;
+	$options.='&amp;search_doc_type='.$search_piece_num;
+	if (! empty($search_doc_ref)) {
+		$filter['t.doc_ref'] = $search_doc_ref;
+		$options.='&amp;search_doc_ref='.$search_doc_ref;
+	}
+}
+if (! empty($search_doc_ref)) {
+	$filter['t.doc_ref'] = $search_doc_ref;
+	$options.='&amp;search_doc_ref='.$search_doc_ref;
+}
+if (! empty($search_account)) {
+	$filter['t.numero_compte'] = $search_account;
+	$options.='&amp;search_account='.$search_account;
+}
+if (! empty($search_thirdparty)) {
+	$filter['t.code_tiers'] = $search_thirdparty;
+	$options.='&amp;search_thirdparty='.$search_thirdparty;
+}
+if (! empty($search_journal)) {
+	$filter['t.code_journal'] = $search_journal;
+	$options.='&amp;search_journal='.$search_journal;
+}
+
 /*
  * Action
  */
@@ -72,7 +102,6 @@ if ($action == 'delbookkeeping') {
 	$import_key = GETPOST('importkey', 'alpha');
 	
 	if (! empty($import_key)) {
-		$object = new BookKeeping($db);
 		$result = $object->delete_by_importkey($import_key);
 		Header("Location: list.php");
 		if ($result < 0) {
@@ -84,32 +113,28 @@ if ($action == 'delbookkeeping') {
 	$delyear = GETPOST('delyear', 'int');
 	
 	if (! empty($delyear)) {
-		$object = new BookKeeping($db);
 		$result = $object->delete_by_year($delyear);
 		Header("Location: list.php");
 		if ($result < 0) {
 			setEventMessages($object->error, $object->errors, 'errors');
 		}
 	}
-} elseif ($action == 'delbookkeepingyear') {
+} elseif ($action == 'delmouvconfirm') {
 	
-	$delyear = GETPOST('delyear', 'int');
+	$piece_num = GETPOST('piece_num', 'int');
 	
-	if (! empty($delyear)) {
-		$object = new BookKeeping($db);
-		$result = $object->delete_by_year($delyear);
+	if (! empty($piece_num)) {
+		$result = $object->delete_piece_num($piece_num);
 		Header("Location: list.php");
 		if ($result < 0) {
 			setEventMessages($object->error, $object->errors, 'errors');
 		}
 	}
-}  // Export
-else if ($action == 'export_csv') {
-	
+} elseif ($action == 'export_csv') {
+	// Export
 	header('Content-Type: text/csv');
 	header('Content-Disposition: attachment;filename=export_csv.csv');
 	
-	$object = new BookKeeping($db);
 	$result = $object->export_bookkeping('ebp');
 	if ($result < 0) {
 		setEventMessages($object->error, $object->errors, 'errors');
@@ -124,7 +149,7 @@ else if ($action == 'export_csv') {
 			print '"' . $line->numero_compte . '",';
 			print '"' . substr($line->code_journal, 0, 2) . '",';
 			print '"' . substr($line->doc_ref, 0, 40) . '",';
-			print '"' . $line->num_piece . '",';
+			print '"' . $line->piece_num . '",';
 			print '"' . $line->debit . '",';
 			print '"' . $line->credit . '",';
 			print '"' . $conf->currency . '",';
@@ -140,7 +165,7 @@ else if ($action == 'export_csv') {
 			print '"' . $line->numero_compte . '",';
 			print '"' . substr($line->code_journal, 0, 2) . '",';
 			print '"' . substr($line->doc_ref, 0, 40) . '",';
-			print '"' . $line->num_piece . '",';
+			print '"' . $line->piece_num . '",';
 			print '"' . $line->montant . '",';
 			print '"' . $line->sens . '",';
 			print '"' . dol_print_date($line->doc_date, '%d%m%Y') . '",';
@@ -157,7 +182,7 @@ else if ($action == 'export_csv') {
 			print '"' . $line->numero_compte . '",';
 			print '"' . substr($line->code_journal, 0, 2) . '",';
 			print '"' . substr($line->doc_ref, 0, 40) . '",';
-			print '"' . $line->num_piece . '",';
+			print '"' . $line->piece_num . '",';
 			print '"' . $line->montant . '",';
 			print '"' . $line->sens . '",';
 			print '"' . dol_print_date($line->doc_date, '%d%m%Y') . '",';
@@ -175,150 +200,121 @@ else {
 	 * List
 	 */
 	
-	$sql = "SELECT bk.rowid, bk.doc_date, bk.doc_type, bk.doc_ref, bk.code_tiers, bk.numero_compte , bk.label_compte, bk.debit , bk.credit, bk.montant , bk.sens , bk.code_journal , bk.piece_num ";
-	$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as bk";
-	
-	if (dol_strlen(trim($search_doc_type))) {
-		
-		$sql .= " WHERE bk.piece_num LIKE '%" . $search_piece_num . "%'";
-		
-		if (dol_strlen(trim($search_doc_ref))) {
-			$sql .= " AND bk.doc_ref LIKE '%" . $search_doc_ref . "%'";
+	$nbtotalofrecords = 0;
+	if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
+		$nbtotalofrecords = $object->fetchAll($sortorder, $sortfield, 0, 0, $filter);
+		if ($nbtotalofrecords < 0) {
+			setEventMessages($object->error, $object->errors, 'errors');
 		}
 	}
-	if (dol_strlen(trim($search_doc_ref))) {
-		$sql .= " WHERE bk.doc_ref LIKE '%" . $search_doc_ref . "%'";
-	}
-	if (dol_strlen(trim($search_account))) {
-		$sql .= " WHERE bk.numero_compte LIKE '%" . $search_account . "%'";
-	}
-	if (dol_strlen(trim($search_thirdparty))) {
-		$sql .= " WHERE bk.code_tiers LIKE '%" . $search_thirdparty . "%'";
+	
+	$result = $object->fetchAll($sortorder, $sortfield, $limit, $offset, $filter);
+	if ($result < 0) {
+		setEventMessages($object->error, $object->errors, 'errors');
 	}
-	if (dol_strlen(trim($search_journal))) {
-		$sql .= " WHERE bk.code_journal LIKE '%" . $search_journal . "%'";
+	
+	if ($action == 'delmouv') {
+		$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?piece_num=' . GETPOST('piece_num'), $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvt'), 'delmouvconfirm', '', 0, 1);
+		print $formconfirm;
 	}
 	
-	$sql .= " ORDER BY $sortfield $sortorder " . $db->plimit($conf->liste_limit + 1, $offset);
+	print_barre_liste($langs->trans("Bookkeeping"), $page, $_SERVER["PHP_SELF"], $options, $sortfield, $sortorder, '', $result, $nbtotalofrecords);
 	
-	dol_syslog('accountancy/bookkeeping/list.php:: $sql=' . $sql);
-	$resql = $db->query($sql);
-	if ($resql) {
-		$num = $db->num_rows($resql);
-		$i = 0;
-		
-		print_barre_liste($langs->trans("Bookkeeping"), $page, $_SERVER["PHP_SELF"], "", $sortfield, $sortorder, '', $num);
-		
-		/*print '<form name="add" action="' . $_SERVER["PHP_SELF"] . '" method="POST">';
-		 print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
-		 print '<input type="hidden" name="action" value="delbookkeeping">';
-		 
-		 print $formventilation->select_bookkeeping_importkey('importkey', GETPOST('importkey'));
-		 
-		 print '<div class="inline-block divButAction"><input type="submit" class="butAction" value="' . $langs->trans("DelBookKeeping") . '" /></div>';
-		 
-		 print '</form>';*/
-		
-		print '<form name="add" action="' . $_SERVER["PHP_SELF"] . '" method="POST">';
-		print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
-		print '<input type="hidden" name="action" value="delbookkeepingyear">';
-		
-		print $formother->select_year(GETPOST('delyear'), 'delyear');
-		
-		print '<div class="inline-block divButAction"><input type="submit" class="butAction" value="' . $langs->trans("DelBookKeeping") . '" /></div>';
-		
-		print '</form>';
+	/*print '<form name="add" action="' . $_SERVER["PHP_SELF"] . '" method="POST">';
+	 print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
+	 print '<input type="hidden" name="action" value="delbookkeeping">';
+	 
+	 print $formventilation->select_bookkeeping_importkey('importkey', GETPOST('importkey'));
+	 
+	 print '<div class="inline-block divButAction"><input type="submit" class="butAction" value="' . $langs->trans("DelBookKeeping") . '" /></div>';
+	 
+	 print '</form>';*/
+	
+	print '<form name="add" action="' . $_SERVER["PHP_SELF"] . '" method="POST">';
+	print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
+	print '<input type="hidden" name="action" value="delbookkeepingyear">';
+	
+	print $formother->select_year(GETPOST('delyear'), 'delyear');
+	
+	print '<div class="inline-block divButAction"><input type="submit" class="butAction" value="' . $langs->trans("DelBookKeeping") . '" /></div>';
+	print '<a class="butAction" href="./card.php?action=create">' . $langs->trans("NewAccountingMvt") . '</a>';
+	print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?action=export_csv">' . $langs->trans("Export") . '</a>';
+	
+	print '</form>';
+	
+	print '<table class="noborder" width="100%">';
+	print '<tr class="liste_titre">';
+	print_liste_field_titre($langs->trans("NumPiece"), $_SERVER['PHP_SELF'], "t.piece_num", "", $options, "", $sortfield, $sortorder);
+	print_liste_field_titre($langs->trans("Docdate"), $_SERVER['PHP_SELF'], "t.doc_date", "", $options, "", $sortfield, $sortorder);
+	print_liste_field_titre($langs->trans("Docref"), $_SERVER['PHP_SELF'], "t.doc_ref", "", $options, "", $sortfield, $sortorder);
+	print_liste_field_titre($langs->trans("Numerocompte"), $_SERVER['PHP_SELF'], "t.numero_compte", "", $options, "", $sortfield, $sortorder);
+	print_liste_field_titre($langs->trans("Code_tiers"), $_SERVER['PHP_SELF'], "t.code_tiers", "", $options, "", $sortfield, $sortorder);
+	print_liste_field_titre($langs->trans("Labelcompte"), $_SERVER['PHP_SELF'], "bk_label_compte", "", $options, "", $sortfield, $sortorder);
+	print_liste_field_titre($langs->trans("Debit"), $_SERVER['PHP_SELF'], "t.debit", "", $options, 'align="center"', $sortfield, $sortorder);
+	print_liste_field_titre($langs->trans("Credit"), $_SERVER['PHP_SELF'], "t.credit", "", $options, 'align="center"', $sortfield, $sortorder);
+	print_liste_field_titre($langs->trans("Amount"), $_SERVER['PHP_SELF'], "t.montant", "", $options, 'align="center"', $sortfield, $sortorder);
+	print_liste_field_titre($langs->trans("Sens"), $_SERVER['PHP_SELF'], "t.sens", "", $options, 'align="center"', $sortfield, $sortorder);
+	print_liste_field_titre($langs->trans("Codejournal"), $_SERVER['PHP_SELF'], "t.code_journal", "", $options, "", $sortfield, $sortorder);
+	print_liste_field_titre($langs->trans("Action"), $_SERVER["PHP_SELF"], "", $options, "", 'width="60" align="center"', $sortfield, $sortorder);
+	print "</tr>\n";
+	
+	print '<tr class="liste_titre">';
+	print '<form action="' . $_SERVER["PHP_SELF"] . '" method="GET">';
+	print '<td><input type="text" name="search_doc_type" size="8" value="' . $search_piece_num . '"></td>';
+	print '<td>&nbsp;</td>';
+	print '<td><input type="text" name="search_doc_ref" size="8" value="' . $search_doc_ref . '"></td>';
+	print '<td><input type="text" name="search_account" size="8" value="' . $search_account . '"></td>';
+	print '<td><input type="text" name="search_thirdparty" size="8" value="' . $search_thirdparty . '"></td>';
+	print '<td>&nbsp;</td>';
+	print '<td>&nbsp;</td>';
+	print '<td>&nbsp;</td>';
+	print '<td>&nbsp;</td>';
+	print '<td>&nbsp;</td>';
+	print '<td><input type="text" name="search_journal" size="3" value="' . $search_journal . '"></td>';
+	print '<td align="right" colspan="2" class="liste_titre">';
+	print '<input type="image" class="liste_titre" src="' . img_picto($langs->trans("Search"), 'search.png', '', '', 1) . '" name="button_search" value="' . dol_escape_htmltag($langs->trans("Search")) . '" title="' . dol_escape_htmltag($langs->trans("Search")) . '">';
+	print '&nbsp;';
+	print '<input type="image" class="liste_titre" src="' . img_picto($langs->trans("Search"), 'searchclear.png', '', '', 1) . '" name="button_removefilter" value="' . dol_escape_htmltag($langs->trans("RemoveFilter")) . '" title="' . dol_escape_htmltag($langs->trans("RemoveFilter")) . '">';
+	print '</td>';
+	print '</form>';
+	print '</tr>';
+	
+	$var = True;
+	
+	foreach ( $object->lines as $line ) {
+		$var = ! $var;
 		
-		print '<form name="add" action="' . $_SERVER["PHP_SELF"] . '" method="POST">';
-		print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
-		print '<input type="hidden" name="action" value="export_csv">';
-		print '<input type="submit" class="button" style="float: right;" value="' . $langs->trans("Export") . '" onclick="launch_export();" />';
-		print '</form>';
+		print "<tr $bc[$var]>";
 		
-		print '<table class="noborder" width="100%">';
-		print '<tr class="liste_titre">';
-		print_liste_field_titre($langs->trans("NumPiece"), $_SERVER['PHP_SELF'], "bk.piece_num", "", "", "", $sortfield, $sortorder);
-		print_liste_field_titre($langs->trans("Docdate"), $_SERVER['PHP_SELF'], "bk.doc_date", "", "", "", $sortfield, $sortorder);
-		print_liste_field_titre($langs->trans("Docref"), $_SERVER['PHP_SELF'], "bk.doc_ref", "", "", "", $sortfield, $sortorder);
-		print_liste_field_titre($langs->trans("Numerocompte"), $_SERVER['PHP_SELF'], "bk.numero_compte", "", "", "", $sortfield, $sortorder);
-		print_liste_field_titre($langs->trans("Code_tiers"), $_SERVER['PHP_SELF'], "bk.code_tiers", "", "", "", $sortfield, $sortorder);
-		print_liste_field_titre($langs->trans("Labelcompte"), $_SERVER['PHP_SELF'], "bk_label_compte", "", "", "", $sortfield, $sortorder);
-		print_liste_field_titre($langs->trans("Debit"), $_SERVER['PHP_SELF'], "bk.debit", "", "", 'align="center"', $sortfield, $sortorder);
-		print_liste_field_titre($langs->trans("Credit"), $_SERVER['PHP_SELF'], "bk.credit", "", "", 'align="center"', $sortfield, $sortorder);
-		print_liste_field_titre($langs->trans("Amount"), $_SERVER['PHP_SELF'], "bk.montant", "", "", 'align="center"', $sortfield, $sortorder);
-		print_liste_field_titre($langs->trans("Sens"), $_SERVER['PHP_SELF'], "bk.sens", "", "", 'align="center"', $sortfield, $sortorder);
-		print_liste_field_titre($langs->trans("Codejournal"), $_SERVER['PHP_SELF'], "bk.code_journal", "", "", "", $sortfield, $sortorder);
-		print_liste_field_titre($langs->trans("Action"), $_SERVER["PHP_SELF"], "", $param, "", 'width="60" align="center"', $sortfield, $sortorder);
-		print "</tr>\n";
+		/*if ($old_piecenum!=$obj->piece_num) {
+		 $total_debit=0;
+		 $total_credit=0;
+		 } else {
+		 $total_debit+=$obj->debit;
+		 $total_credit+=$obj->credit;
+		 }
+		 */
 		
-		print '<tr class="liste_titre">';
-		print '<form action="' . $_SERVER["PHP_SELF"] . '" method="GET">';
-		print '<td><input type="text" name="search_doc_type" size="8" value="' . $search_piece_num . '"></td>';
-		print '<td>&nbsp;</td>';
-		print '<td><input type="text" name="search_doc_ref" size="8" value="' . $search_doc_ref . '"></td>';
-		print '<td><input type="text" name="search_account" size="8" value="' . $search_account . '"></td>';
-		print '<td><input type="text" name="search_thirdparty" size="8" value="' . $search_thirdparty . '"></td>';
-		print '<td>&nbsp;</td>';
-		print '<td>&nbsp;</td>';
-		print '<td>&nbsp;</td>';
-		print '<td>&nbsp;</td>';
-		print '<td>&nbsp;</td>';
-		print '<td><input type="text" name="search_journal" size="3" value="' . $search_journal . '"></td>';
-		print '<td align="right" colspan="2" class="liste_titre">';
-		print '<input type="image" class="liste_titre" src="' . img_picto($langs->trans("Search"), 'search.png', '', '', 1) . '" name="button_search" value="' . dol_escape_htmltag($langs->trans("Search")) . '" title="' . dol_escape_htmltag($langs->trans("Search")) . '">';
-		print '&nbsp;';
-		print '<input type="image" class="liste_titre" src="' . img_picto($langs->trans("Search"), 'searchclear.png', '', '', 1) . '" name="button_removefilter" value="' . dol_escape_htmltag($langs->trans("RemoveFilter")) . '" title="' . dol_escape_htmltag($langs->trans("RemoveFilter")) . '">';
+		print '<td><a href="./card.php?piece_num=' . $line->piece_num . '">' . $line->piece_num . '</a></td>';
+		print '<td align="center">' . dol_print_date($line->doc_date, 'day') . '</td>';
+		print '<td>' . $line->doc_ref . '</td>';
+		print '<td>' . length_accountg($line->numero_compte) . '</td>';
+		print '<td>' . length_accounta($line->code_tiers) . '</td>';
+		print '<td>' . $line->label_compte . '</td>';
+		print '<td align="right">' . price($line->debit) . '</td>';
+		print '<td align="right">' . price($line->credit) . '</td>';
+		print '<td align="right">' . price($line->montant) . '</td>';
+		print '<td align="center">' . $line->sens . '</td>';
+		print '<td>' . $line->code_journal . '</td>';
+		print '<td align="center">';
+		print '<a href="./card.php?piece_num=' . $line->piece_num . '">' . img_edit() . '</a>';
+		print '<a href="' . $_SERVER['PHP_SELF'] . '?action=delmouv&piece_num=' . $line->piece_num . '">' . img_delete() . '</a>';
 		print '</td>';
-		print '</form>';
-		print '</tr>';
-		
-		$var = True;
-		
-		while ( $i < min($num, $conf->liste_limit) ) {
-			$obj = $db->fetch_object($resql);
-			$var = ! $var;
-			
-			print "<tr $bc[$var]>";
-			
-		/*	if ($old_piecenum!=$obj->piece_num) {
-				$total_debit=0;
-				$total_credit=0;
-			} else {
-				$total_debit+=$obj->debit;
-				$total_credit+=$obj->credit;
-			}
-			*/
-			
-			print '<td>' . $obj->piece_num . '</td>';
-			print '<td align="center">' . dol_print_date($db->jdate($obj->doc_date), 'day') . '</td>';
-			print '<td>' . $obj->doc_ref . '</td>';
-			print '<td>' . length_accountg($obj->numero_compte) . '</td>';
-			print '<td>' . length_accounta($obj->code_tiers) . '</td>';
-			print '<td>' . $obj->label_compte . '</td>';
-			print '<td align="right">' . price($obj->debit) . '</td>';
-			print '<td align="right">' . price($obj->credit) . '</td>';
-			print '<td align="right">' . price($obj->montant) . '</td>';
-			print '<td align="center">' . $obj->sens . '</td>';
-			print '<td>' . $obj->code_journal . '</td>';
-			print '<td align="center"><a href="./card.php?piece_num=' . $obj->piece_num . '">' . img_edit() . '</a></td>';
-			print "</tr>\n";
-			
-			//$old_piecenum= $obj->piece_num;
-			$i ++;
-		}
-		print "</table>";
-		
-		print '<div class="tabsAction">';
-		print '<a class="butAction" href="./card.php?action=create">' . $langs->trans("NewAccountingMvt") . '</a>';
-		print '</div>';
-		
-		$db->free($resql);
-	} else {
-		dol_print_error($db);
+		print "</tr>\n";
 	}
+	print "</table>";
 	
 	llxFooter();
 }
 
-
 $db->close();
\ No newline at end of file
diff --git a/htdocs/accountancy/bookkeeping/listbyyear.php b/htdocs/accountancy/bookkeeping/listbyyear.php
index c6a26755365..19f3c97a08f 100644
--- a/htdocs/accountancy/bookkeeping/listbyyear.php
+++ b/htdocs/accountancy/bookkeeping/listbyyear.php
@@ -19,16 +19,16 @@
  */
 
 /**
- * \file		htdocs/accountancy/bookkeeping/listbyyear.php
- * \ingroup		Accounting Expert
- * \brief		Book keeping by year
+ * \file htdocs/accountancy/bookkeeping/listbyyear.php
+ * \ingroup Accounting Expert
+ * \brief Book keeping by year
  */
-
 require '../../main.inc.php';
-	
+
 // Class
-require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
+require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
+require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
+require_once DOL_DOCUMENT_ROOT . '/accountancy/class/bookkeeping.class.php';
 
 // Langs
 $langs->load("accountancy");
@@ -36,93 +36,204 @@ $langs->load("accountancy");
 $page = GETPOST("page");
 $sortorder = GETPOST("sortorder");
 $sortfield = GETPOST("sortfield");
-$limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit;
+$limit = GETPOST('limit') ? GETPOST('limit', 'int') : $conf->liste_limit;
+$search_date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth', 'int'), GETPOST('date_startday', 'int'), GETPOST('date_startyear', 'int'));
+$search_date_end = dol_mktime(0, 0, 0, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int'));
+$search_doc_type=GETPOST('search_doc_type','alpha');
+$search_doc_date=dol_mktime(0, 0, 0, GETPOST('doc_datemonth', 'int'), GETPOST('doc_dateday', 'int'), GETPOST('doc_dateyear', 'int'));
+$search_doc_ref=GETPOST('search_doc_ref','alpha');
+$search_numero_compte=GETPOST('search_numero_compte','alpha');
+$search_code_tiers=GETPOST('search_code_tiers','alpha');
+$search_label_compte=GETPOST('search_label_compte','alpha');
+$search_sens=GETPOST('search_sens','alpha');
+$search_code_journal=GETPOST('search_code_journal','alpha');
+
+$object = new BookKeeping($db);
+$form = new Form($db);
 
 // Filter
-$year = GETPOST("year", 'int');
-if ($year == 0) {
-	$year_current = strftime("%Y", time());
-	$year_start = $year_current;
-} else {
-	$year_current = $year;
-	$year_start = $year;
+if (empty($search_date_start)) {
+	$search_date_start = dol_mktime(0, 0, 0, 1, 1, dol_print_date(dol_now(), '%Y'));
+	$search_date_end = dol_mktime(0, 0, 0, 12, 31, dol_print_date(dol_now(), '%Y'));
 }
-
 if ($sortorder == "")
 	$sortorder = "ASC";
 if ($sortfield == "")
-	$sortfield = "bk.rowid";
+	$sortfield = "t.rowid";
 
 $offset = $limit * $page;
 
 llxHeader('', $langs->trans("Bookkeeping"));
 
-$textprevyear = '<a href="' . $_SERVER["PHP_SELF"] . '?year=' . ($year_current - 1) . '">' . img_previous() . '</a>';
-$textnextyear = '&nbsp;<a href="' . $_SERVER["PHP_SELF"] . '?year=' . ($year_current + 1) . '">' . img_next() . '</a>';
+if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter")) // Both test are required to be compatible with all browsers
+{
+	$search_doc_type = "";
+	$search_doc_date = "";
+	$search_doc_ref = "";
+	$search_numero_compte = "";
+	$search_code_tiers = "";
+	$search_label_compte = "";
+	$search_sens = "";
+	$search_code_journal = "";
+}
+
+$options = '';
+$filter = array ();
+if (! empty($search_date_start)) {
+	$filter['t.doc_date>='] = $search_date_start;
+	$options .= '&amp;date_startmonth=' . GETPOST('date_startmonth', 'int') . '&amp;date_startday=' . GETPOST('date_startday', 'int') . '&amp;date_startyear=' . GETPOST('date_startyear', 'int');
+}
+if (! empty($search_date_end)) {
+	$filter['t.doc_date<='] = $search_date_end;
+	$options .= '&amp;date_endmonth=' . GETPOST('date_endmonth', 'int') . '&amp;date_endday=' . GETPOST('date_endday', 'int') . '&amp;date_endyear=' . GETPOST('date_endyear', 'int');
+}
+if (! empty($search_doc_type)) {
+	$filter['t.doc_type'] = $search_doc_type;
+	$options .= '&amp;search_doc_type=' . $search_doc_type;
+}
+if (! empty($search_doc_date)) {
+	$filter['t.doc_date'] = $search_doc_date;
+	$options .= '&amp;doc_datemonth=' . GETPOST('doc_datemonth', 'int') . '&amp;doc_dateday=' . GETPOST('doc_dateday', 'int') . '&amp;doc_dateyear=' . GETPOST('doc_dateyear', 'int');
+}
+if (! empty($search_doc_ref)) {
+	$filter['t.doc_ref'] = $search_doc_ref;
+	$options .= '&amp;search_doc_ref=' . $search_doc_ref;
+}
+if (! empty($search_numero_compte)) {
+	$filter['t.numero_compte'] = $search_numero_compte;
+	$options .= '&amp;search_numero_compte=' . $search_numero_compte;
+}
+if (! empty($search_code_tiers)) {
+	$filter['t.code_tiers'] = $search_code_tiers;
+	$options .= '&amp;search_code_tiers=' . $search_code_tiers;
+}
+if (! empty($search_label_compte)) {
+	$filter['t.label_compte'] = $search_label_compte;
+	$options .= '&amp;search_label_compte=' . $search_label_compte;
+}
+if (! empty($search_sens)) {
+	$filter['t.sens'] = $search_sens;
+	$options .= '&amp;search_sens=' . $search_sens;
+}
+if (! empty($search_code_journal)) {
+	$filter['t.code_journal'] = $search_code_journal;
+	$options .= '&amp;search_code_journal=' . $search_code_journal;
+}
 
 /*
  * Mode List
  */
 
-$sql = "SELECT bk.rowid, bk.doc_date, bk.doc_type, bk.doc_ref, bk.code_tiers, bk.numero_compte , bk.label_compte, bk.debit , bk.credit, bk.montant , bk.sens, bk.code_journal";
-$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as bk";
-// $sql .= " WHERE bk.doc_date >= '".$db->idate(dol_get_first_day($y,1,false))."'";
-// $sql .= " AND bk.doc_date <= '".$db->idate(dol_get_last_day($y,12,false))."'";
-$sql .= " ORDER BY $sortfield $sortorder " . $db->plimit($conf->liste_limit + 1, $offset);
-
-dol_syslog('accountancy/bookkeeping/listbyyear.php:: $sql=' . $sql);
-$resql = $db->query($sql);
-if ($resql) {
-	$num = $db->num_rows($resql);
-	$i = 0;
+$nbtotalofrecords = 0;
+if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
+	$nbtotalofrecords = $object->fetchAll($sortorder, $sortfield, 0, 0);
+	if ($nbtotalofrecords < 0) {
+		setEventMessages($object->error, $object->errors, 'errors');
+	}
+}
+
+$result = $object->fetchAll($sortorder, $sortfield, $limit, $offset, $filter);
+if ($result < 0) {
+	setEventMessages($object->error, $object->errors, 'errors');
+}
+
+print_barre_liste($langs->trans("Bookkeeping") .' '. dol_print_date($search_date_start).'-'.dol_print_date($search_date_end), $page, $_SERVER['PHP_SELF'], $options, $sortfield, $sortorder, '', $result, $nbtotalofrecords);
+
+print '<form method="GET" id="searchFormList" action="' . $_SERVER["PHP_SELF"] . '">';
+print '<div class="liste_titre">';
+print $langs->trans('DateStart') . ': ';
+print $form->select_date($search_date_start, 'date_start');
+print $langs->trans('DateEnd') . ': ';
+print $form->select_date($search_date_end, 'date_end');
+print '</div>';
+print "<table class=\"noborder\" width=\"100%\">";
+
+print '<tr class="liste_titre">';
+print_liste_field_titre($langs->trans("Doctype"), $_SERVER['PHP_SELF'], "t.doc_type", "", $options, "", $sortfield, $sortorder);
+print_liste_field_titre($langs->trans("Date"), $_SERVER['PHP_SELF'], "t.doc_date", "", $options, "", $sortfield, $sortorder);
+print_liste_field_titre($langs->trans("Docref"), $_SERVER['PHP_SELF'], "t.doc_ref", "", $options, "", $sortfield, $sortorder);
+print_liste_field_titre($langs->trans("AccountAccounting"), $_SERVER['PHP_SELF'], "t.numero_compte", "", $options, "", $sortfield, $sortorder);
+print_liste_field_titre($langs->trans("ThirdPartyAccount"), $_SERVER['PHP_SELF'], "t.code_tiers", "", $options, "", $sortfield, $sortorder);
+print_liste_field_titre($langs->trans("Label"), $_SERVER['PHP_SELF'], "t.label_compte", "", $options, "", $sortfield, $sortorder);
+print_liste_field_titre($langs->trans("Debit"), $_SERVER['PHP_SELF'], "t.debit", "", $options, "", $sortfield, $sortorder);
+print_liste_field_titre($langs->trans("Credit"), $_SERVER['PHP_SELF'], "t.credit", "", $options, "", $sortfield, $sortorder);
+print_liste_field_titre($langs->trans("Amount"), $_SERVER['PHP_SELF'], "t.montant", "", $options, "", $sortfield, $sortorder);
+print_liste_field_titre($langs->trans("Sens"), $_SERVER['PHP_SELF'], "t.sens", "", $options, "", $sortfield, $sortorder);
+print_liste_field_titre($langs->trans("Codejournal"), $_SERVER['PHP_SELF'], "t.code_journal", "", $options, "", $sortfield, $sortorder);
+print '<th class="liste_titre" align="right"><input type="image" class="liste_titre" name="button_search" src="' . img_picto($langs->trans("Search"), 'search.png', '', '', 1) . '" value="' . dol_escape_htmltag($langs->trans("Search")) . '" title="' . dol_escape_htmltag($langs->trans("Search")) . '">';
+print '<input type="image" class="liste_titre" name="button_removefilter" src="' . img_picto($langs->trans("Search"), 'searchclear.png', '', '', 1) . '" value="' . dol_escape_htmltag($langs->trans("RemoveFilter")) . '" title="' . dol_escape_htmltag($langs->trans("RemoveFilter")) . '"></td>';
+print "</tr>\n";
+print '<tr class="liste_titre">';
+
+print '<td class="liste_titre">';
+print '<input type="text" size=7 class="flat" name="search_doc_type" value="'.$search_doc_type.'"/>';
+print '</td>';
+
+print '<td class="liste_titre">';
+print $form->select_date($search_doc_date,'doc_date',0, 0, 1);
+print '</td>';
+
+print '<td class="liste_titre">';
+print '<input type="text" size=6 class="flat" name="search_doc_ref" value="'.$search_doc_ref.'"/>';
+print '</td>';
+
+print '<td class="liste_titre">';
+print '<input type="text" size=6 class="flat" name="search_numero_compte" value="'.$search_numero_compte.'"/>';
+print '</td>';
+
+print '<td class="liste_titre">';
+print '<input type="text" size=6 class="flat" name="search_code_tiers" value="'.$search_code_tiers.'"/>';
+print '</td>';
+
+print '<td class="liste_titre">';
+print '<input type="text" size=6 class="flat" name="search_label_compte" value="'.$search_label_compte.'"/>';
+print '</td>';
+
+print '<td class="liste_titre">';
+print '</td>';
+
+print '<td class="liste_titre">';
+print '</td>';
+
+print '<td class="liste_titre">';
+print '</td>';
+
+print '<td class="liste_titre">';
+print '<input type="text" size=2 class="flat" name="search_sens" value="'.$search_sens.'"/>';
+print '</td>';
+
+print '<td class="liste_titre">';
+print '<input type="text" size=3 class="flat" name="search_code_journal" value="'.$search_code_journal.'"/>';
+print '</td>';
+
+print '<td class="liste_titre">';
+print '</td>';
+
+print "</tr>\n";
+
+$var = True;
+
+foreach ( $object->lines as $line ) {
+	$var = ! $var;
 	
-	print_barre_liste($langs->trans("Bookkeeping") . " $textprevyear " . $langs->trans("Year") . " $year_start $textnextyear", $page, $_SERVER['PHP_SELF'], "", $sortfield, $sortorder, '', $num);
-	print "<table class=\"noborder\" width=\"100%\">";
+	print "<tr $bc[$var]>";
 	
-	print '<tr class="liste_titre">';
-	print_liste_field_titre($langs->trans("Doctype"), $_SERVER['PHP_SELF'], "bk.doc_type", "", "", "", $sortfield, $sortorder);
-	print_liste_field_titre($langs->trans("Date"), $_SERVER['PHP_SELF'], "bk.doc_date", "", "", "", $sortfield, $sortorder);
-	print_liste_field_titre($langs->trans("Docref"), $_SERVER['PHP_SELF'], "bk.doc_ref", "", "", "", $sortfield, $sortorder);
-	print_liste_field_titre($langs->trans("AccountAccounting"), $_SERVER['PHP_SELF'], "bk.numero_compte", "", "", "", $sortfield, $sortorder);
-	print_liste_field_titre($langs->trans("ThirdPartyAccount"), $_SERVER['PHP_SELF'], "bk.code_tiers", "", "", "", $sortfield, $sortorder);
-	print_liste_field_titre($langs->trans("Label"), $_SERVER['PHP_SELF'], "bk_label_compte", "", "", "", $sortfield, $sortorder);
-	print_liste_field_titre($langs->trans("Debit"), $_SERVER['PHP_SELF'], "bk.debit", "", "", "", $sortfield, $sortorder);
-	print_liste_field_titre($langs->trans("Credit"), $_SERVER['PHP_SELF'], "bk.credit", "", "", "", $sortfield, $sortorder);
-	print_liste_field_titre($langs->trans("Amount"), $_SERVER['PHP_SELF'], "bk.montant", "", "", "", $sortfield, $sortorder);
-	print_liste_field_titre($langs->trans("Sens"), $_SERVER['PHP_SELF'], "bk.sens", "", "", "", $sortfield, $sortorder);
-	print_liste_field_titre($langs->trans("Codejournal"), $_SERVER['PHP_SELF'], "bk.code_journal", "", "", "", $sortfield, $sortorder);
-	print_liste_field_titre('');
+	print '<td>' . $line->doc_type . '</td>' . "\n";
+	print '<td>' . dol_print_date($line->doc_date) . '</td>';
+	print '<td>' . $line->doc_ref . '</td>';
+	print '<td>' . length_accountg($line->numero_compte) . '</td>';
+	print '<td>' . length_accounta($line->code_tiers) . '</td>';
+	print '<td>' . $line->label_compte . '</td>';
+	print '<td align="right">' . price($line->debit) . '</td>';
+	print '<td align="right">' . price($line->credit) . '</td>';
+	print '<td align="right">' . price($line->montant) . '</td>';
+	print '<td>' . $line->sens . '</td>';
+	print '<td>' . $line->code_journal . '</td>';
+	print '<td><a href="./card.php?action=update&amp;piece_num=' . $line->piece_num . '">' . img_edit() . '</a></td>';
 	print "</tr>\n";
-	
-	$var = True;
-	
-	while ( $i < min($num, $conf->liste_limit) ) {
-		$obj = $db->fetch_object($resql);
-		$var = ! $var;
-		
-		print "<tr $bc[$var]>";
-		
-		print '<td>' . $obj->doc_type . '</td>' . "\n";
-		print '<td>' . dol_print_date($db->jdate($obj->doc_date)) . '</td>';
-		print '<td>' . $obj->doc_ref . '</td>';
-		print '<td>' . length_accountg($obj->numero_compte) . '</td>';
-		print '<td>' . length_accounta($obj->code_tiers) . '</td>';
-		print '<td>' . $obj->label_compte . '</td>';
-		print '<td align="right">' . price($obj->debit) . '</td>';
-		print '<td align="right">' . price($obj->credit) . '</td>';
-		print '<td align="right">' . price($obj->montant) . '</td>';
-		print '<td>' . $obj->sens . '</td>';
-		print '<td>' . $obj->code_journal . '</td>';
-		print '<td><a href="./card.php?action=update&id=' . $obj->rowid . '">' . img_edit() . '</a></td>';
-		print "</tr>\n";
-		
-		$i ++;
-	}
-	print "</table>";
-	$db->free($resql);
-} else {
-	dol_print_error($db);
 }
+print "</table>";
+print '</form>';
 
 llxFooter();
 $db->close();
\ No newline at end of file
diff --git a/htdocs/accountancy/class/accountingaccount.class.php b/htdocs/accountancy/class/accountingaccount.class.php
index 9277bcd9a70..856306c3304 100644
--- a/htdocs/accountancy/class/accountingaccount.class.php
+++ b/htdocs/accountancy/class/accountingaccount.class.php
@@ -30,6 +30,11 @@
  */
 class AccountingAccount extends CommonObject
 {
+	var $db;
+	var $error;
+	var $errors;
+
+	var $id;
 	var $rowid;
 
 	var $datec; // Creation date
diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php
index d3801b4a4d1..75811a5763e 100644
--- a/htdocs/accountancy/class/bookkeeping.class.php
+++ b/htdocs/accountancy/class/bookkeeping.class.php
@@ -1,8 +1,8 @@
 <?php
-/* Copyright (C) 2004-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
- * Copyright (C) 2013-2014 Olivier Geffroy      <jeff@jeffinfo.com>
- * Copyright (C) 2013-2015 Alexandre Spangaro   <alexandre.spangaro@gmail.com>
- * Copyright (C) 2013-2014 Florian Henry		<florian.henry@open-concept.pro>
+/* Copyright (C) 2007-2012  Laurent Destailleur <eldy@users.sourceforge.net>
+ * Copyright (C) 2014       Juanjo Menent       <jmenent@2byte.es>
+ * Copyright (C) 2015       Florian Henry       <florian.henry@open-concept.pro>
+ * Copyright (C) 2015       Raphaƫl Doursenaud  <rdoursenaud@gpcsolutions.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
@@ -19,245 +19,187 @@
  */
 
 /**
- * \file		htdocs/accountancy/class/bookkeeping.class.php
- * \ingroup		Accounting Expert
- * \brief		File of class to manage book keeping
+ * \file accountancy/bookkeeping.class.php
+ * \ingroup accountancy
+ * \brief This file is an example for a CRUD class file (Create/Read/Update/Delete)
+ * Put some comments here
  */
 
+// Put here all includes required by your class file
+require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php';
+// require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
+// require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
+
 /**
- *	Class to manage accountancy book keeping
+ * Class Accountingbookkeeping
+ *
+ * Put here description of your class
  */
-class BookKeeping extends CommonObject
-{
-	var $doc_date;
-	var $doc_type;
-	var $doc_ref;
-	var $date_create;
-	var $fk_doc;
-	var $fk_docdet;
-	var $code_tiers;
-	var $numero_compte;
-	var $label_compte;
-	var $debit;
-	var $credit;
-	var $montant;
-	var $sens;
-	var $fk_user_author;
-	var $code_journal;
-	var $piece_num;
-	var $linesexport = array ();
-	var $linesmvt = array ();
-
-    /**
-     *  Constructor
-     *
-     *  @param	DoliDB		$db		Database handler
-     */
-    function __construct($db)
-    {
-        $this->db = $db;
-    }
-
+class BookKeeping extends CommonObject {
 	/**
-     *      Load a line into memory from database
-     *
-     *      @param	int		$id		 	id of line to get
-     *      @return	int					<0 if KO, >0 if OK
-     */
-	function fetch($id)
-	{
-		$sql = "SELECT rowid, doc_date, doc_type,";
-		$sql .= " doc_ref, fk_doc, fk_docdet, code_tiers, ";
-		$sql .= " numero_compte, label_compte, debit, credit, ";
-		$sql .= " montant, sens, fk_user_author, import_key, code_journal, piece_num  ";
-		$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping ";
-		$sql .= " WHERE rowid = '" . $id . "'";
-
-		dol_syslog(get_class($this) . "fetch sql=" . $sql, LOG_DEBUG);
-		$result = $this->db->query($sql);
-		if ($result) {
-			$obj = $this->db->fetch_object($result);
-
-			$this->id = $obj->rowid;
-
-			$this->doc_date = $this->db->jdate($obj->doc_date);
-			$this->doc_type = $obj->doc_type;
-			$this->doc_ref = $obj->doc_ref;
-			$this->fk_doc = $obj->fk_doc;
-			$this->fk_docdet = $obj->fk_docdet;
-			$this->code_tiers = $obj->code_tiers;
-			$this->numero_compte = $obj->numero_compte;
-			$this->label_compte = $obj->label_compte;
-			$this->debit = $obj->debit;
-			$this->credit = $obj->credit;
-			$this->montant = $obj->montant;
-			$this->sens = $obj->sens;
-			$this->code_journal = $obj->code_journal;
-			$this->piece_num = $obj->piece_num;
-		}
-		else
-		{
-			$this->error = "Error " . $this->db->lasterror();
-			dol_syslog(get_class($this) . "::fetch " . $this->error, LOG_ERR);
-			return - 1;
-		}
-
-		return 1;
-	}
-
+	 *
+	 * @var string Error code (or message)
+	 * @deprecated
+	 *
+	 * @see Accountingbookkeeping::errors
+	 */
+	public $error;
 	/**
-     *      Load an accounting document into memory from database
-     *
-     *      @param	int		$piecenum 	Accounting document to get
-     *      @return	int					<0 if KO, >0 if OK
-     */
-	function fetch_per_mvt($piecenum)
-	{
-		$sql = "SELECT piece_num,doc_date,code_journal,doc_ref,doc_type";
-		$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping";
-		$sql .= " WHERE piece_num = '" . $piecenum . "'";
-
-		dol_syslog(get_class($this) . "fetch_per_mvt sql=" . $sql, LOG_DEBUG);
-		$result = $this->db->query($sql);
-		if ($result) {
-			$obj = $this->db->fetch_object($result);
-
-			$this->piece_num = $obj->piece_num;
-			$this->code_journal = $obj->code_journal;
-			$this->doc_date = $this->db->jdate($obj->doc_date);
-			$this->doc_ref = $obj->doc_ref;
-			$this->doc_type = $obj->doc_type;
-		} else {
-			$this->error = "Error " . $this->db->lasterror();
-			dol_syslog(get_class($this) . "::fetch_per_mvt " . $this->error, LOG_ERR);
-			return - 1;
-		}
-
-		return 1;
-	}
-
+	 *
+	 * @var string[] Error codes (or messages)
+	 */
+	public $errors = array ();
 	/**
-     *      Return next number movement
-     *
-     *      @return    string			Last number
-     */
-	function getNextNumMvt() {
-		$sql = "SELECT MAX(piece_num)+1 as max FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping";
-
-		dol_syslog(get_class($this) . "getNextNumMvt sql=" . $sql, LOG_DEBUG);
-		$result = $this->db->query($sql);
-
-		if ($result)
-		{
-			$obj = $this->db->fetch_object($result);
-
-			return $obj->max;
-		}
-		else
-		{
-			$this->error = "Error " . $this->db->lasterror();
-			dol_syslog(get_class($this) . "::getNextNumMvt " . $this->error, LOG_ERR);
-			return - 1;
-		}
-	}
-
+	 *
+	 * @var string Id to identify managed objects
+	 */
+	public $element = 'accountingbookkeeping';
 	/**
-     *      Load all informations of accountancy document
-     *
-     *      @param	int		$piecenum	id of line to get
-     *      @return	int					<0 if KO, >0 if OK
-     */
-	function fetch_all_per_mvt($piecenum)
-	{
-		$sql = "SELECT rowid, doc_date, doc_type,";
-		$sql .= " doc_ref, fk_doc, fk_docdet, code_tiers,";
-		$sql .= " numero_compte, label_compte, debit, credit,";
-		$sql .= " montant, sens, fk_user_author, import_key, code_journal, piece_num";
-		$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping ";
-		$sql .= " WHERE piece_num = '" . $piecenum . "'";
-
-		dol_syslog(get_class($this) . "fetch_all_per_mvt sql=" . $sql, LOG_DEBUG);
-		$result = $this->db->query($sql);
-		if ($result) {
-
-			while ( $obj = $this->db->fetch_object($result) ) {
-
-				$line = new BookKeepingLine();
-
-				$line->id = $obj->rowid;
-
-				$line->doc_date = $this->db->jdate($obj->doc_date);
-				$line->doc_type = $obj->doc_type;
-				$line->doc_ref = $obj->doc_ref;
-				$line->fk_doc = $obj->fk_doc;
-				$line->fk_docdet = $obj->fk_docdet;
-				$line->code_tiers = $obj->code_tiers;
-				$line->numero_compte = $obj->numero_compte;
-				$line->label_compte = $obj->label_compte;
-				$line->debit = $obj->debit;
-				$line->credit = $obj->credit;
-				$line->montant = $obj->montant;
-				$line->sens = $obj->sens;
-				$line->code_journal = $obj->code_journal;
-				$line->piece_num = $obj->piece_num;
-
-				$this->linesmvt[] = $line;
-			}
-		} else {
-			$this->error = "Error " . $this->db->lasterror();
-			dol_syslog(get_class($this) . "::fetch_per_mvt " . $this->error, LOG_ERR);
-			return - 1;
-		}
-
+	 *
+	 * @var string Name of table without prefix where object is stored
+	 */
+	public $table_element = 'accounting_bookkeeping';
+	
+	/**
+	 *
+	 * @var BookKeepingLine[] Lines
+	 */
+	public $lines = array ();
+	
+	/**
+	 *
+	 * @var int ID
+	 */
+	public $id;
+	/**
+	 */
+	public $doc_date = '';
+	public $doc_type;
+	public $doc_ref;
+	public $fk_doc;
+	public $fk_docdet;
+	public $code_tiers;
+	public $numero_compte;
+	public $label_compte;
+	public $debit;
+	public $credit;
+	public $montant;
+	public $sens;
+	public $fk_user_author;
+	public $import_key;
+	public $code_journal;
+	public $piece_num;
+	
+	/**
+	 */
+	
+	/**
+	 * Constructor
+	 *
+	 * @param DoliDb $db Database handler
+	 */
+	public function __construct(DoliDB $db) {
+		$this->db = $db;
 		return 1;
 	}
-
+	
 	/**
-	 * Insert line into bookkeeping
+	 * Create object into database
 	 *
-	 * @param 	User	$user		User who inserted operation
-	 * @return	int <0 KO >0 OK
+	 * @param User $user User that creates
+	 * @param bool $notrigger false=launch triggers after, true=disable triggers
+	 *       
+	 * @return int <0 if KO, Id of created object if OK
 	 */
-	function create($user='')
-	{
-		global $conf;
-
+	public function create(User $user, $notrigger = false) {
+		dol_syslog(__METHOD__, LOG_DEBUG);
+		
+		$error = 0;
+		
+		// Clean parameters
+		
+		if (isset($this->doc_type)) {
+			$this->doc_type = trim($this->doc_type);
+		}
+		if (isset($this->doc_ref)) {
+			$this->doc_ref = trim($this->doc_ref);
+		}
+		if (isset($this->fk_doc)) {
+			$this->fk_doc = trim($this->fk_doc);
+		}
+		if (isset($this->fk_docdet)) {
+			$this->fk_docdet = trim($this->fk_docdet);
+		}
+		if (isset($this->code_tiers)) {
+			$this->code_tiers = trim($this->code_tiers);
+		}
+		if (isset($this->numero_compte)) {
+			$this->numero_compte = trim($this->numero_compte);
+		}
+		if (isset($this->label_compte)) {
+			$this->label_compte = trim($this->label_compte);
+		}
+		if (isset($this->debit)) {
+			$this->debit = trim($this->debit);
+		}
+		if (isset($this->credit)) {
+			$this->credit = trim($this->credit);
+		}
+		if (isset($this->montant)) {
+			$this->montant = trim($this->montant);
+		}
+		if (isset($this->sens)) {
+			$this->sens = trim($this->sens);
+		}
+		if (isset($this->fk_user_author)) {
+			$this->fk_user_author = trim($this->fk_user_author);
+		}
+		if (isset($this->import_key)) {
+			$this->import_key = trim($this->import_key);
+		}
+		if (isset($this->code_journal)) {
+			$this->code_journal = trim($this->code_journal);
+		}
+		if (isset($this->piece_num)) {
+			$this->piece_num = trim($this->piece_num);
+		}
+		
+		$this->db->begin();
+		
 		$this->piece_num = 0;
-
+		
 		// first check if line not yet in bookkeeping
 		$sql = "SELECT count(*)";
-		$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping ";
+		$sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element;
 		$sql .= " WHERE doc_type = '" . $this->doc_type . "'";
 		$sql .= " AND fk_docdet = " . $this->fk_docdet;
 		$sql .= " AND numero_compte = '" . $this->numero_compte . "'";
-
+		
 		dol_syslog(get_class($this) . ":: create sql=" . $sql, LOG_DEBUG);
 		$resql = $this->db->query($sql);
-
+		
 		if ($resql) {
 			$row = $this->db->fetch_array($resql);
 			if ($row[0] == 0) {
-
+				
 				// Determine piece_num
 				$sqlnum = "SELECT piece_num";
-				$sqlnum .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping ";
+				$sqlnum .= " FROM " . MAIN_DB_PREFIX . $this->table_element;
 				$sqlnum .= " WHERE doc_type = '" . $this->doc_type . "'";
 				$sqlnum .= " AND fk_docdet = '" . $this->fk_docdet . "'";
 				$sqlnum .= " AND doc_ref = '" . $this->doc_ref . "'";
-
+				
 				dol_syslog(get_class($this) . ":: create sqlnum=" . $sqlnum, LOG_DEBUG);
 				$resqlnum = $this->db->query($sqlnum);
-				if ($resqlnum)
-				{
+				if ($resqlnum) {
 					$objnum = $this->db->fetch_object($resqlnum);
 					$this->piece_num = $objnum->piece_num;
 				}
 				dol_syslog(get_class($this) . ":: create this->piece_num=" . $this->piece_num, LOG_DEBUG);
-				if (empty($this->piece_num))
-				{
+				if (empty($this->piece_num)) {
 					$sqlnum = "SELECT MAX(piece_num)+1 as maxpiecenum";
-					$sqlnum .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping ";
-
+					$sqlnum .= " FROM " . MAIN_DB_PREFIX . $this->table_element;
+					
 					dol_syslog(get_class($this) . ":: create sqlnum=" . $sqlnum, LOG_DEBUG);
 					$resqlnum = $this->db->query($sqlnum);
 					if ($resqlnum) {
@@ -269,13 +211,13 @@ class BookKeeping extends CommonObject
 				if (empty($this->piece_num)) {
 					$this->piece_num = 1;
 				}
-
+				
 				$now = dol_now();
 				if (empty($this->date_create)) {
 					$this->date_create = $now;
 				}
-
-				$sql = "INSERT INTO " . MAIN_DB_PREFIX . "accounting_bookkeeping (";
+				
+				$sql = "INSERT INTO " . MAIN_DB_PREFIX . $this->table_element." (";
 				
 				$sql .= "doc_date";
 				$sql .= ", doc_type";
@@ -293,7 +235,7 @@ class BookKeeping extends CommonObject
 				$sql .= ", import_key";
 				$sql .= ", code_journal";
 				$sql .= ", piece_num";
-
+				
 				$sql .= ") VALUES (";
 				
 				$sql .= "'" . $this->doc_date . "'";
@@ -308,41 +250,567 @@ class BookKeeping extends CommonObject
 				$sql .= "," . $this->credit;
 				$sql .= "," . $this->montant;
 				$sql .= ",'" . $this->sens . "'";
-				$sql .= ",'" . $this->fk_user_author."'";
+				$sql .= ",'" . $this->fk_user_author . "'";
 				$sql .= ",'" . $this->date_create . "'";
 				$sql .= ",'" . $this->code_journal . "'";
 				$sql .= "," . $this->piece_num;
 				
 				$sql .= ")";
-
+				
 				dol_syslog(get_class($this) . ":: create sql=" . $sql, LOG_DEBUG);
 				$resql = $this->db->query($sql);
 				if ($resql) {
-					$id = $this->db->last_insert_id(MAIN_DB_PREFIX . "accounting_bookkeeping");
-
+					$id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element);
+					
 					if ($id > 0) {
 						$this->id = $id;
 						$result = 0;
 					} else {
 						$result = - 2;
-						dol_syslog("BookKeeping::Create Error $result lecture ID");
+						$error ++;
+						$this->errors[] = 'Error Create Error ' . $result . ' lecture ID';
+						dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
 					}
 				} else {
 					$result = - 1;
-					dol_syslog("BookKeeping::Create Error $result INSERT Mysql");
+					$error ++;
+					$this->errors[] = 'Error ' . $this->db->lasterror();
+					dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
 				}
 			} else {
 				$result = - 3;
-				dol_syslog("BookKeeping::Create Error $result SELECT Mysql");
+				$error ++;
+				$this->errors[] = 'Error ' . $this->db->lasterror();
+				dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
+			}
+		} else {
+			$result = - 5;
+			$error ++;
+			$this->errors[] = 'Error ' . $this->db->lasterror();
+			dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
+		}
+		
+		
+		if (! $error) {
+			
+			if (! $notrigger) {
+				// Uncomment this and change MYOBJECT to your own tag if you
+				// want this action to call a trigger.
+				
+				// // Call triggers
+				// $result=$this->call_trigger('MYOBJECT_CREATE',$user);
+				// if ($result < 0) $error++;
+				// // End call triggers
+			}
+		}
+		
+		// Commit or rollback
+		if ($error) {
+			$this->db->rollback();
+			
+			return - 1 * $error;
+		} else {
+			$this->db->commit();
+			
+			return $result;
+		}
+	}
+	
+	/**
+	 * Create object into database
+	 *
+	 * @param  User $user      User that creates
+	 * @param  bool $notrigger false=launch triggers after, true=disable triggers
+	 *
+	 * @return int <0 if KO, Id of created object if OK
+	 */
+	public function create_std(User $user, $notrigger = false)
+	{
+		dol_syslog(__METHOD__, LOG_DEBUG);
+	
+		$error = 0;
+	
+		// Clean parameters
+	
+		if (isset($this->doc_type)) {
+			$this->doc_type = trim($this->doc_type);
+		}
+		if (isset($this->doc_ref)) {
+			$this->doc_ref = trim($this->doc_ref);
+		}
+		if (isset($this->fk_doc)) {
+			$this->fk_doc = trim($this->fk_doc);
+		}
+		if (isset($this->fk_docdet)) {
+			$this->fk_docdet = trim($this->fk_docdet);
+		}
+		if (isset($this->code_tiers)) {
+			$this->code_tiers = trim($this->code_tiers);
+		}
+		if (isset($this->numero_compte)) {
+			$this->numero_compte = trim($this->numero_compte);
+		}
+		if (isset($this->label_compte)) {
+			$this->label_compte = trim($this->label_compte);
+		}
+		if (isset($this->debit)) {
+			$this->debit = trim($this->debit);
+		}
+		if (isset($this->credit)) {
+			$this->credit = trim($this->credit);
+		}
+		if (isset($this->montant)) {
+			$this->montant = trim($this->montant);
+		}
+		if (isset($this->sens)) {
+			$this->sens = trim($this->sens);
+		}
+		if (isset($this->fk_user_author)) {
+			$this->fk_user_author = trim($this->fk_user_author);
+		}
+		if (isset($this->import_key)) {
+			$this->import_key = trim($this->import_key);
+		}
+		if (isset($this->code_journal)) {
+			$this->code_journal = trim($this->code_journal);
+		}
+		if (isset($this->piece_num)) {
+			$this->piece_num = trim($this->piece_num);
+		}
+	
+	
+	
+		// Check parameters
+		// Put here code to add control on parameters values
+	
+		// Insert request
+		$sql = 'INSERT INTO ' . MAIN_DB_PREFIX . $this->table_element . '(';
+	
+		$sql.= 'doc_date,';
+		$sql.= 'doc_type,';
+		$sql.= 'doc_ref,';
+		$sql.= 'fk_doc,';
+		$sql.= 'fk_docdet,';
+		$sql.= 'code_tiers,';
+		$sql.= 'numero_compte,';
+		$sql.= 'label_compte,';
+		$sql.= 'debit,';
+		$sql.= 'credit,';
+		$sql.= 'montant,';
+		$sql.= 'sens,';
+		$sql.= 'fk_user_author,';
+		$sql.= 'import_key,';
+		$sql.= 'code_journal,';
+		$sql.= 'piece_num';
+	
+	
+		$sql .= ') VALUES (';
+	
+		$sql .= ' '.(! isset($this->doc_date) || dol_strlen($this->doc_date)==0?'NULL':"'".$this->db->idate($this->doc_date)."'").',';
+		$sql .= ' '.(! isset($this->doc_type)?'NULL':"'".$this->db->escape($this->doc_type)."'").',';
+		$sql .= ' '.(! isset($this->doc_ref)?'NULL':"'".$this->db->escape($this->doc_ref)."'").',';
+		$sql .= ' '.(empty($this->fk_doc)?'0':$this->fk_doc).',';
+		$sql .= ' '.(empty($this->fk_docdet)?'0':$this->fk_docdet).',';
+		$sql .= ' '.(! isset($this->code_tiers)?'NULL':"'".$this->db->escape($this->code_tiers)."'").',';
+		$sql .= ' '.(! isset($this->numero_compte)?'NULL':"'".$this->db->escape($this->numero_compte)."'").',';
+		$sql .= ' '.(! isset($this->label_compte)?'NULL':"'".$this->db->escape($this->label_compte)."'").',';
+		$sql .= ' '.(! isset($this->debit)?'NULL':"'".$this->debit."'").',';
+		$sql .= ' '.(! isset($this->credit)?'NULL':"'".$this->credit."'").',';
+		$sql .= ' '.(! isset($this->montant)?'NULL':"'".$this->montant."'").',';
+		$sql .= ' '.(! isset($this->sens)?'NULL':"'".$this->db->escape($this->sens)."'").',';
+		$sql .= ' '.$user->id.',';
+		$sql .= ' '.(! isset($this->import_key)?'NULL':"'".$this->db->escape($this->import_key)."'").',';
+		$sql .= ' '.(! isset($this->code_journal)?'NULL':"'".$this->db->escape($this->code_journal)."'").',';
+		$sql .= ' '.(! isset($this->piece_num)?'NULL':$this->piece_num);
+	
+	
+		$sql .= ')';
+	
+		$this->db->begin();
+	
+		$resql = $this->db->query($sql);
+		if (!$resql) {
+			$error ++;
+			$this->errors[] = 'Error ' . $this->db->lasterror();
+			dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
+		}
+	
+		if (!$error) {
+			$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element);
+	
+			if (!$notrigger) {
+				// Uncomment this and change MYOBJECT to your own tag if you
+				// want this action to call a trigger.
+	
+				//// Call triggers
+				//$result=$this->call_trigger('MYOBJECT_CREATE',$user);
+				//if ($result < 0) $error++;
+				//// End call triggers
+			}
+		}
+	
+		// Commit or rollback
+		if ($error) {
+			$this->db->rollback();
+	
+			return - 1 * $error;
+		} else {
+			$this->db->commit();
+	
+			return $this->id;
+		}
+	}
+	
+	/**
+	 * Load object in memory from the database
+	 *
+	 * @param int $id Id object
+	 * @param string $ref Ref
+	 *       
+	 * @return int <0 if KO, 0 if not found, >0 if OK
+	 */
+	public function fetch($id, $ref = null) {
+		dol_syslog(__METHOD__, LOG_DEBUG);
+		
+		$sql = 'SELECT';
+		$sql .= ' t.rowid,';
+		
+		$sql .= " t.doc_date,";
+		$sql .= " t.doc_type,";
+		$sql .= " t.doc_ref,";
+		$sql .= " t.fk_doc,";
+		$sql .= " t.fk_docdet,";
+		$sql .= " t.code_tiers,";
+		$sql .= " t.numero_compte,";
+		$sql .= " t.label_compte,";
+		$sql .= " t.debit,";
+		$sql .= " t.credit,";
+		$sql .= " t.montant,";
+		$sql .= " t.sens,";
+		$sql .= " t.fk_user_author,";
+		$sql .= " t.import_key,";
+		$sql .= " t.code_journal,";
+		$sql .= " t.piece_num";
+		
+		$sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t';
+		if (null !== $ref) {
+			$sql .= ' WHERE t.ref = ' . '\'' . $ref . '\'';
+		} else {
+			$sql .= ' WHERE t.rowid = ' . $id;
+		}
+		
+		$resql = $this->db->query($sql);
+		if ($resql) {
+			$numrows = $this->db->num_rows($resql);
+			if ($numrows) {
+				$obj = $this->db->fetch_object($resql);
+				
+				$this->id = $obj->rowid;
+				
+				$this->doc_date = $this->db->jdate($obj->doc_date);
+				$this->doc_type = $obj->doc_type;
+				$this->doc_ref = $obj->doc_ref;
+				$this->fk_doc = $obj->fk_doc;
+				$this->fk_docdet = $obj->fk_docdet;
+				$this->code_tiers = $obj->code_tiers;
+				$this->numero_compte = $obj->numero_compte;
+				$this->label_compte = $obj->label_compte;
+				$this->debit = $obj->debit;
+				$this->credit = $obj->credit;
+				$this->montant = $obj->montant;
+				$this->sens = $obj->sens;
+				$this->fk_user_author = $obj->fk_user_author;
+				$this->import_key = $obj->import_key;
+				$this->code_journal = $obj->code_journal;
+				$this->piece_num = $obj->piece_num;
+			}
+			$this->db->free($resql);
+			
+			if ($numrows) {
+				return 1;
+			} else {
+				return 0;
+			}
+		} else {
+			$this->errors[] = 'Error ' . $this->db->lasterror();
+			dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
+			
+			return - 1;
+		}
+	}
+	
+	/**
+	 * Load object in memory from the database
+	 *
+	 * @param string $sortorder Sort Order
+	 * @param string $sortfield Sort field
+	 * @param int $limit offset limit
+	 * @param int $offset offset limit
+	 * @param array $filter filter array
+	 * @param string $filtermode filter mode (AND or OR)
+	 *       
+	 * @return int <0 if KO, >0 if OK
+	 */
+	public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND') {
+		dol_syslog(__METHOD__, LOG_DEBUG);
+		
+		$sql = 'SELECT';
+		$sql .= ' t.rowid,';
+		
+		$sql .= " t.doc_date,";
+		$sql .= " t.doc_type,";
+		$sql .= " t.doc_ref,";
+		$sql .= " t.fk_doc,";
+		$sql .= " t.fk_docdet,";
+		$sql .= " t.code_tiers,";
+		$sql .= " t.numero_compte,";
+		$sql .= " t.label_compte,";
+		$sql .= " t.debit,";
+		$sql .= " t.credit,";
+		$sql .= " t.montant,";
+		$sql .= " t.sens,";
+		$sql .= " t.fk_user_author,";
+		$sql .= " t.import_key,";
+		$sql .= " t.code_journal,";
+		$sql .= " t.piece_num";
+		
+		$sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t';
+		
+		// Manage filter
+		$sqlwhere = array ();
+		if (count($filter) > 0) {
+			foreach ( $filter as $key => $value ) {
+				if ($key=='t.doc_date') {
+					$sqlwhere[] = $key . '=\'' . $this->db->idate($value) . '\'';
+				} elseif($key=='t.doc_date>=' || $key=='t.doc_date<=') {
+					$sqlwhere[] = $key . '\'' . $this->db->idate($value) . '\'';
+				}  elseif($key=='t.fk_doc' || $key=='t.fk_docdet' ||$key=='t.piece_num') {
+					$sqlwhere[] = $key . '=' . $value;
+				} else {
+					$sqlwhere[] = $key . ' LIKE \'%' . $this->db->escape($value) . '%\'';
+				}
+			}
+		}
+		
+		if (count($sqlwhere) > 0) {
+			$sql .= ' WHERE ' . implode(' ' . $filtermode . ' ', $sqlwhere);
+		}
+		
+		if (! empty($sortfield)) {
+			$sql .= $this->db->order($sortfield, $sortorder);
+		}
+		if (! empty($limit)) {
+			$sql .= ' ' . $this->db->plimit($limit + 1, $offset);
+		}
+		$this->lines = array ();
+		
+		$resql = $this->db->query($sql);
+		if ($resql) {
+			$num = $this->db->num_rows($resql);
+			
+			while ( $obj = $this->db->fetch_object($resql) ) {
+				$line = new BookKeepingLine();
+				
+				$line->id = $obj->rowid;
+				
+				$line->doc_date = $this->db->jdate($obj->doc_date);
+				$line->doc_type = $obj->doc_type;
+				$line->doc_ref = $obj->doc_ref;
+				$line->fk_doc = $obj->fk_doc;
+				$line->fk_docdet = $obj->fk_docdet;
+				$line->code_tiers = $obj->code_tiers;
+				$line->numero_compte = $obj->numero_compte;
+				$line->label_compte = $obj->label_compte;
+				$line->debit = $obj->debit;
+				$line->credit = $obj->credit;
+				$line->montant = $obj->montant;
+				$line->sens = $obj->sens;
+				$line->fk_user_author = $obj->fk_user_author;
+				$line->import_key = $obj->import_key;
+				$line->code_journal = $obj->code_journal;
+				$line->piece_num = $obj->piece_num;
+				
+				$this->lines[] = $line;
+			}
+			$this->db->free($resql);
+			
+			return $num;
+		} else {
+			$this->errors[] = 'Error ' . $this->db->lasterror();
+			dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
+			
+			return - 1;
+		}
+	}
+	
+	/**
+	 * Update object into database
+	 *
+	 * @param User $user User that modifies
+	 * @param bool $notrigger false=launch triggers after, true=disable triggers
+	 *       
+	 * @return int <0 if KO, >0 if OK
+	 */
+	public function update(User $user, $notrigger = false) {
+		$error = 0;
+		
+		dol_syslog(__METHOD__, LOG_DEBUG);
+		
+		// Clean parameters
+		
+		if (isset($this->doc_type)) {
+			$this->doc_type = trim($this->doc_type);
+		}
+		if (isset($this->doc_ref)) {
+			$this->doc_ref = trim($this->doc_ref);
+		}
+		if (isset($this->fk_doc)) {
+			$this->fk_doc = trim($this->fk_doc);
+		}
+		if (isset($this->fk_docdet)) {
+			$this->fk_docdet = trim($this->fk_docdet);
+		}
+		if (isset($this->code_tiers)) {
+			$this->code_tiers = trim($this->code_tiers);
+		}
+		if (isset($this->numero_compte)) {
+			$this->numero_compte = trim($this->numero_compte);
+		}
+		if (isset($this->label_compte)) {
+			$this->label_compte = trim($this->label_compte);
+		}
+		if (isset($this->debit)) {
+			$this->debit = trim($this->debit);
+		}
+		if (isset($this->credit)) {
+			$this->credit = trim($this->credit);
+		}
+		if (isset($this->montant)) {
+			$this->montant = trim($this->montant);
+		}
+		if (isset($this->sens)) {
+			$this->sens = trim($this->sens);
+		}
+		if (isset($this->fk_user_author)) {
+			$this->fk_user_author = trim($this->fk_user_author);
+		}
+		if (isset($this->import_key)) {
+			$this->import_key = trim($this->import_key);
+		}
+		if (isset($this->code_journal)) {
+			$this->code_journal = trim($this->code_journal);
+		}
+		if (isset($this->piece_num)) {
+			$this->piece_num = trim($this->piece_num);
+		}
+		
+		// Check parameters
+		// Put here code to add a control on parameters values
+		
+		// Update request
+		$sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element . ' SET';
+		
+		$sql .= ' doc_date = ' . (! isset($this->doc_date) || dol_strlen($this->doc_date) != 0 ? "'" . $this->db->idate($this->doc_date) . "'" : 'null') . ',';
+		$sql .= ' doc_type = ' . (isset($this->doc_type) ? "'" . $this->db->escape($this->doc_type) . "'" : "null") . ',';
+		$sql .= ' doc_ref = ' . (isset($this->doc_ref) ? "'" . $this->db->escape($this->doc_ref) . "'" : "null") . ',';
+		$sql .= ' fk_doc = ' . (isset($this->fk_doc) ? $this->fk_doc : "null") . ',';
+		$sql .= ' fk_docdet = ' . (isset($this->fk_docdet) ? $this->fk_docdet : "null") . ',';
+		$sql .= ' code_tiers = ' . (isset($this->code_tiers) ? "'" . $this->db->escape($this->code_tiers) . "'" : "null") . ',';
+		$sql .= ' numero_compte = ' . (isset($this->numero_compte) ? "'" . $this->db->escape($this->numero_compte) . "'" : "null") . ',';
+		$sql .= ' label_compte = ' . (isset($this->label_compte) ? "'" . $this->db->escape($this->label_compte) . "'" : "null") . ',';
+		$sql .= ' debit = ' . (isset($this->debit) ? $this->debit : "null") . ',';
+		$sql .= ' credit = ' . (isset($this->credit) ? $this->credit : "null") . ',';
+		$sql .= ' montant = ' . (isset($this->montant) ? $this->montant : "null") . ',';
+		$sql .= ' sens = ' . (isset($this->sens) ? "'" . $this->db->escape($this->sens) . "'" : "null") . ',';
+		$sql .= ' fk_user_author = ' . (isset($this->fk_user_author) ? $this->fk_user_author : "null") . ',';
+		$sql .= ' import_key = ' . (isset($this->import_key) ? "'" . $this->db->escape($this->import_key) . "'" : "null") . ',';
+		$sql .= ' code_journal = ' . (isset($this->code_journal) ? "'" . $this->db->escape($this->code_journal) . "'" : "null") . ',';
+		$sql .= ' piece_num = ' . (isset($this->piece_num) ? $this->piece_num : "null");
+		
+		$sql .= ' WHERE rowid=' . $this->id;
+		
+		$this->db->begin();
+		
+		$resql = $this->db->query($sql);
+		if (! $resql) {
+			$error ++;
+			$this->errors[] = 'Error ' . $this->db->lasterror();
+			dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
+		}
+		
+		if (! $error && ! $notrigger) {
+			// Uncomment this and change MYOBJECT to your own tag if you
+			// want this action calls a trigger.
+			
+			// // Call triggers
+			// $result=$this->call_trigger('MYOBJECT_MODIFY',$user);
+			// if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail}
+			// // 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 deletes
+	 * @param bool $notrigger false=launch triggers after, true=disable triggers
+	 *       
+	 * @return int <0 if KO, >0 if OK
+	 */
+	public function delete(User $user, $notrigger = false) {
+		dol_syslog(__METHOD__, LOG_DEBUG);
+		
+		$error = 0;
+		
+		$this->db->begin();
+		
+		if (! $error) {
+			if (! $notrigger) {
+				// Uncomment this and change MYOBJECT to your own tag if you
+				// want this action calls a trigger.
+				
+				// // Call triggers
+				// $result=$this->call_trigger('MYOBJECT_DELETE',$user);
+				// if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail}
+				// // End call triggers
 			}
+		}
+		
+		if (! $error) {
+			$sql = 'DELETE FROM ' . MAIN_DB_PREFIX . $this->table_element;
+			$sql .= ' WHERE rowid=' . $this->id;
+			
+			$resql = $this->db->query($sql);
+			if (! $resql) {
+				$error ++;
+				$this->errors[] = 'Error ' . $this->db->lasterror();
+				dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
+			}
+		}
+		
+		// Commit or rollback
+		if ($error) {
+			$this->db->rollback();
+			
+			return - 1 * $error;
 		} else {
-			$result = - 5;
-			dol_syslog("BookKeeping::Create Error $result SELECT Mysql");
+			$this->db->commit();
+			
+			return 1;
 		}
-
-		return $result;
 	}
-
+	
 	/**
 	 * Delete bookkepping by importkey
 	 *
@@ -351,14 +819,14 @@ class BookKeeping extends CommonObject
 	 */
 	function delete_by_importkey($importkey) {
 		$this->db->begin();
-
+	
 		// first check if line not yet in bookkeeping
 		$sql = "DELETE";
-		$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping ";
+		$sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element;
 		$sql .= " WHERE import_key = '" . $importkey . "'";
-
+	
 		$resql = $this->db->query($sql);
-
+	
 		if (! $resql) {
 			$this->errors[] = "Error " . $this->db->lasterror();
 			foreach ( $this->errors as $errmsg ) {
@@ -368,13 +836,13 @@ class BookKeeping extends CommonObject
 			$this->db->rollback();
 			return - 1;
 		}
-
+	
 		$this->db->commit();
 		return 1;
 	}
 	
 	/**
-	 * Delete bookkepping by importkey
+	 * Delete bookkepping by year
 	 *
 	 * @param	string 	$delyear		year to delete
 	 * @return	int						Result
@@ -384,7 +852,7 @@ class BookKeeping extends CommonObject
 	
 		// first check if line not yet in bookkeeping
 		$sql = "DELETE";
-		$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping ";
+		$sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element;
 		$sql .= " WHERE YEAR(doc_date) = ".$delyear;
 	
 		$resql = $this->db->query($sql);
@@ -402,288 +870,214 @@ class BookKeeping extends CommonObject
 		$this->db->commit();
 		return 1;
 	}
-
+	
 	/**
-	 *	Create object into database
+	 * Delete bookkepping by piece number
 	 *
-	 *	@param	User	$user      		Object user that create
-	 *	@param  int		$notrigger		1=Does not execute triggers, 0 otherwise
-	 *	@return	int						<0 if KO, >0 if OK
+	 * @param	int 	$piecenum		peicenum to delete
+	 * @return	int						Result
 	 */
-	function create_std($user, $notrigger = 0)
-	{
-		$error = 0;
-
-		// Clean parameters
-		if (isset($this->doc_type))
-			$this->doc_type = trim($this->doc_type);
-		if (isset($this->doc_ref))
-			$this->doc_ref = trim($this->doc_ref);
-		if (isset($this->fk_doc))
-			$this->fk_doc = trim($this->fk_doc);
-		if (isset($this->fk_docdet))
-			$this->fk_docdet = trim($this->fk_docdet);
-		if (isset($this->code_tiers))
-			$this->code_tiers = trim($this->code_tiers);
-		if (isset($this->numero_compte))
-			$this->numero_compte = trim($this->numero_compte);
-		if (isset($this->label_compte))
-			$this->label_compte = trim($this->label_compte);
-		if (isset($this->debit))
-			$this->debit = trim($this->debit);
-		if (isset($this->credit))
-			$this->credit = trim($this->credit);
-		if (isset($this->montant))
-			$this->montant = trim($this->montant);
-		if (isset($this->sens))
-			$this->sens = trim($this->sens);
-		if (isset($this->fk_user_author))
-			$this->fk_user_author = trim($this->fk_user_author);
-		if (isset($this->import_key))
-			$this->import_key = trim($this->import_key);
-		if (isset($this->code_journal))
-			$this->code_journal = trim($this->code_journal);
-		if (isset($this->piece_num))
-			$this->piece_num = trim($this->piece_num);
-
-		// Check parameters
-		// Put here code to add control on parameters values
-
-		// Insert request
-		$sql = "INSERT INTO " . MAIN_DB_PREFIX . "accounting_bookkeeping(";
-		$sql .= "doc_date,";
-		$sql .= "doc_type,";
-		$sql .= "doc_ref,";
-		$sql .= "fk_doc,";
-		$sql .= "fk_docdet,";
-		$sql .= "code_tiers,";
-		$sql .= "numero_compte,";
-		$sql .= "label_compte,";
-		$sql .= "debit,";
-		$sql .= "credit,";
-		$sql .= "montant,";
-		$sql .= "sens,";
-		$sql .= "fk_user_author,";
-		$sql .= "import_key,";
-		$sql .= "code_journal,";
-		$sql .= "piece_num";
-
-		$sql .= ") VALUES (";
-
-		$sql .= " " . (! isset($this->doc_date) || dol_strlen($this->doc_date) == 0 ? 'NULL' : $this->db->idate($this->doc_date)) . ",";
-		$sql .= " " . (! isset($this->doc_type) ? 'NULL' : "'" . $this->db->escape($this->doc_type) . "'") . ",";
-		$sql .= " " . (! isset($this->doc_ref) ? 'NULL' : "'" . $this->db->escape($this->doc_ref) . "'") . ",";
-		$sql .= " " . (! isset($this->fk_doc) ? 'NULL' : "'" . $this->fk_doc . "'") . ",";
-		$sql .= " " . (! isset($this->fk_docdet) ? 'NULL' : "'" . $this->fk_docdet . "'") . ",";
-		$sql .= " " . (! isset($this->code_tiers) ? 'NULL' : "'" . $this->db->escape($this->code_tiers) . "'") . ",";
-		$sql .= " " . (! isset($this->numero_compte) ? 'NULL' : "'" . $this->db->escape($this->numero_compte) . "'") . ",";
-		$sql .= " " . (! isset($this->label_compte) ? 'NULL' : "'" . $this->db->escape($this->label_compte) . "'") . ",";
-		$sql .= " " . (! isset($this->debit) ? 'NULL' : "'" . $this->debit . "'") . ",";
-		$sql .= " " . (! isset($this->credit) ? 'NULL' : "'" . $this->credit . "'") . ",";
-		$sql .= " " . (! isset($this->montant) ? 'NULL' : "'" . $this->montant . "'") . ",";
-		$sql .= " " . (! isset($this->sens) ? 'NULL' : "'" . $this->db->escape($this->sens) . "'") . ",";
-		$sql .= " " . $user->id . ",";
-		$sql .= " " . (! isset($this->import_key) ? 'NULL' : "'" . $this->db->escape($this->import_key) . "'") . ",";
-		$sql .= " " . (! isset($this->code_journal) ? 'NULL' : "'" . $this->db->escape($this->code_journal) . "'") . ",";
-		$sql .= " " . (! isset($this->piece_num) ? 'NULL' : "'" . $this->piece_num . "'") . "";
-
-		$sql .= ")";
-
+	function delete_piece_num($piecenum) {
 		$this->db->begin();
-
-		dol_syslog(get_class($this) . "::create_std sql=" . $sql, LOG_DEBUG);
+	
+		// first check if line not yet in bookkeeping
+		$sql = "DELETE";
+		$sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element;
+		$sql .= " WHERE piece_num = ".$piecenum;
+	
 		$resql = $this->db->query($sql);
+	
 		if (! $resql) {
-			$error ++;
 			$this->errors[] = "Error " . $this->db->lasterror();
-		}
-
-		if (! $error) {
-			$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . "accounting_bookkeeping");
-
-//			if (! $notrigger) {
-				// Uncomment this and change MYOBJECT to your own tag if you
-				// want this action calls a trigger.
-
-				// // Call triggers
-				// include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
-				// $interface=new Interfaces($this->db);
-				// $result=$interface->run_triggers('MYOBJECT_CREATE',$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) . "::create_std " . $errmsg, LOG_ERR);
+				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 $this->id;
+			return - 1;
 		}
+	
+		$this->db->commit();
+		return 1;
 	}
-
+	
 	/**
-	 *	Update object into database
+	 * Load an object from its id and create a new one in database
 	 *
-	 *	@param	User	$user      		Object user that create
-	 *	@param  int		$notrigger		1=Does not execute triggers, 0 otherwise
-	 *	@return	int						<0 if KO, >0 if OK
+	 * @param int $fromid Id of object to clone
+	 *       
+	 * @return int New id of clone
 	 */
-	function update($user = 0, $notrigger = 0)
-	{
+	public function createFromClone($fromid) {
+		dol_syslog(__METHOD__, LOG_DEBUG);
+		
+		global $user;
 		$error = 0;
-
-		// Clean parameters
-		if (isset($this->doc_type))
-			$this->doc_type = trim($this->doc_type);
-		if (isset($this->doc_ref))
-			$this->doc_ref = trim($this->doc_ref);
-		if (isset($this->fk_doc))
-			$this->fk_doc = trim($this->fk_doc);
-		if (isset($this->fk_docdet))
-			$this->fk_docdet = trim($this->fk_docdet);
-		if (isset($this->code_tiers))
-			$this->code_tiers = trim($this->code_tiers);
-		if (isset($this->numero_compte))
-			$this->numero_compte = trim($this->numero_compte);
-		if (isset($this->label_compte))
-			$this->label_compte = trim($this->label_compte);
-		if (isset($this->debit))
-			$this->debit = trim($this->debit);
-		if (isset($this->credit))
-			$this->credit = trim($this->credit);
-		if (isset($this->montant))
-			$this->montant = trim($this->montant);
-		if (isset($this->sens))
-			$this->sens = trim($this->sens);
-		if (isset($this->fk_user_author))
-			$this->fk_user_author = trim($this->fk_user_author);
-		if (isset($this->import_key))
-			$this->import_key = trim($this->import_key);
-		if (isset($this->code_journal))
-			$this->code_journal = trim($this->code_journal);
-		if (isset($this->piece_num))
-			$this->piece_num = trim($this->piece_num);
-
-		// Check parameters
-		// Put here code to add a control on parameters values
-
-		// Update request
-		$sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_bookkeeping SET";
-
-		$sql .= " doc_date=" . (dol_strlen($this->doc_date) != 0 ? "'" . $this->db->idate($this->doc_date) . "'" : 'null') . ",";
-		$sql .= " doc_type=" . (isset($this->doc_type) ? "'" . $this->db->escape($this->doc_type) . "'" : "null") . ",";
-		$sql .= " doc_ref=" . (isset($this->doc_ref) ? "'" . $this->db->escape($this->doc_ref) . "'" : "null") . ",";
-		$sql .= " fk_doc=" . (isset($this->fk_doc) ? $this->fk_doc : "null") . ",";
-		$sql .= " fk_docdet=" . (isset($this->fk_docdet) ? $this->fk_docdet : "null") . ",";
-		$sql .= " code_tiers=" . (isset($this->code_tiers) ? "'" . $this->db->escape($this->code_tiers) . "'" : "null") . ",";
-		$sql .= " numero_compte=" . (isset($this->numero_compte) ? "'" . $this->db->escape($this->numero_compte) . "'" : "null") . ",";
-		$sql .= " label_compte=" . (isset($this->label_compte) ? "'" . $this->db->escape($this->label_compte) . "'" : "null") . ",";
-		$sql .= " debit=" . (isset($this->debit) ? $this->debit : "null") . ",";
-		$sql .= " credit=" . (isset($this->credit) ? $this->credit : "null") . ",";
-		$sql .= " montant=" . (isset($this->montant) ? $this->montant : "null") . ",";
-		$sql .= " sens=" . (isset($this->sens) ? "'" . $this->db->escape($this->sens) . "'" : "null") . ",";
-		$sql .= " fk_user_author=" . (isset($this->fk_user_author) ? $this->fk_user_author : "null") . ",";
-		$sql .= " import_key=" . (isset($this->import_key) ? "'" . $this->db->escape($this->import_key) . "'" : "null") . ",";
-		$sql .= " code_journal=" . (isset($this->code_journal) ? "'" . $this->db->escape($this->code_journal) . "'" : "null") . ",";
-		$sql .= " piece_num=" . (isset($this->piece_num) ? $this->piece_num : "null") . "";
-
-		$sql .= " WHERE rowid=" . $this->id;
-
+		$object = new Accountingbookkeeping($this->db);
+		
 		$this->db->begin();
-
-		dol_syslog(get_class($this) . "::update sql=" . $sql, LOG_DEBUG);
-		$resql = $this->db->query($sql);
-		if (! $resql) {
+		
+		// Load source object
+		$object->fetch($fromid);
+		// Reset object
+		$object->id = 0;
+		
+		// Clear fields
+		// ...
+		
+		// Create clone
+		$result = $object->create($user);
+		
+		// Other options
+		if ($result < 0) {
 			$error ++;
-			$this->errors[] = "Error " . $this->db->lasterror();
+			$this->errors = $object->errors;
+			dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
 		}
-
-//		if (! $error) {
-//			if (! $notrigger) {
-				// Uncomment this and change MYOBJECT to your own tag if you
-				// want this action calls 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) {
-			foreach ( $this->errors as $errmsg ) {
-				dol_syslog(get_class($this) . "::update " . $errmsg, LOG_ERR);
-				$this->error .= ($this->error ? ', ' . $errmsg : $errmsg);
-			}
+		
+		// End
+		if (! $error) {
+			$this->db->commit();
+			
+			return $object->id;
+		} else {
 			$this->db->rollback();
-			return - 1 * $error;
+			
+			return - 1;
+		}
+	}
+	
+	/**
+	 * Initialise object with example values
+	 * Id must be 0 if object instance is a specimen
+	 *
+	 * @return void
+	 */
+	public function initAsSpecimen() {
+		$this->id = 0;
+		
+		$this->doc_date = '';
+		$this->doc_type = '';
+		$this->doc_ref = '';
+		$this->fk_doc = '';
+		$this->fk_docdet = '';
+		$this->code_tiers = '';
+		$this->numero_compte = '';
+		$this->label_compte = '';
+		$this->debit = '';
+		$this->credit = '';
+		$this->montant = '';
+		$this->sens = '';
+		$this->fk_user_author = '';
+		$this->import_key = '';
+		$this->code_journal = '';
+		$this->piece_num = '';
+	}
+	
+	/**
+	 * Load an accounting document into memory from database
+	 *
+	 * @param int $piecenum Accounting document to get
+	 * @return int <0 if KO, >0 if OK
+	 */
+	public function fetch_per_mvt($piecenum) {
+		$sql = "SELECT piece_num,doc_date,code_journal,doc_ref,doc_type";
+		$sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element;
+		$sql .= " WHERE piece_num = " . $piecenum;
+		
+		dol_syslog(get_class($this) . "fetch_per_mvt sql=" . $sql, LOG_DEBUG);
+		$result = $this->db->query($sql);
+		if ($result) {
+			$obj = $this->db->fetch_object($result);
+			
+			$this->piece_num = $obj->piece_num;
+			$this->code_journal = $obj->code_journal;
+			$this->doc_date = $this->db->jdate($obj->doc_date);
+			$this->doc_ref = $obj->doc_ref;
+			$this->doc_type = $obj->doc_type;
 		} else {
-			$this->db->commit();
-			return 1;
+			$this->error = "Error " . $this->db->lasterror();
+			dol_syslog(get_class($this) . "::fetch_per_mvt " . $this->error, LOG_ERR);
+			return - 1;
 		}
+		
+		return 1;
 	}
-
+	
 	/**
-	 *	Delete object in database
+	 * Return next number movement
 	 *
-	 *	@param	User	$user      		Object user that create
-	 *	@param  int		$notrigger		1=Does not execute triggers, 0 otherwise
-	 *	@return	int						<0 if KO, >0 if OK
+	 * @return string Last number
 	 */
-	function delete($user, $notrigger = 0)
-	{
-		$error = 0;
-
-		$this->db->begin();
-
-//		if (! $notrigger)
-//		{
-//			// Call trigger
-//			$result=$this->call_trigger('ACCOUNTING_NUMPIECE_DELETE',$user);
-//			if ($result < 0) $error++;
-//            // End call triggers
-//		}
-
-		if (! $error) {
-			$sql = "DELETE FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping";
-			$sql .= " WHERE rowid=" . $this->id;
-
-			dol_syslog(get_class($this) . "::delete sql=" . $sql);
-			$resql = $this->db->query($sql);
-			if (! $resql) {
-				$error ++;
-				$this->errors[] = "Error " . $this->db->lasterror();
-			}
+	public function getNextNumMvt() {
+		$sql = "SELECT MAX(piece_num)+1 as max FROM " . MAIN_DB_PREFIX . $this->table_element;
+		
+		dol_syslog(get_class($this) . "getNextNumMvt sql=" . $sql, LOG_DEBUG);
+		$result = $this->db->query($sql);
+		
+		if ($result) {
+			$obj = $this->db->fetch_object($result);
+			
+			return $obj->max;
+		} else {
+			$this->error = "Error " . $this->db->lasterror();
+			dol_syslog(get_class($this) . "::getNextNumMvt " . $this->error, LOG_ERR);
+			return - 1;
 		}
-
-		// 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);
+	}
+	
+	/**
+	 * Load all informations of accountancy document
+	 *
+	 * @param int $piecenum id of line to get
+	 * @return int <0 if KO, >0 if OK
+	 */
+	function fetch_all_per_mvt($piecenum) {
+		$sql = "SELECT rowid, doc_date, doc_type,";
+		$sql .= " doc_ref, fk_doc, fk_docdet, code_tiers,";
+		$sql .= " numero_compte, label_compte, debit, credit,";
+		$sql .= " montant, sens, fk_user_author, import_key, code_journal, piece_num";
+		$sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element;
+		$sql .= " WHERE piece_num = " . $piecenum;
+		
+		dol_syslog(get_class($this) . "fetch_all_per_mvt sql=" . $sql, LOG_DEBUG);
+		$result = $this->db->query($sql);
+		if ($result) {
+			
+			while ( $obj = $this->db->fetch_object($result) ) {
+				
+				$line = new BookKeepingLine();
+				
+				$line->id = $obj->rowid;
+				
+				$line->doc_date = $this->db->jdate($obj->doc_date);
+				$line->doc_type = $obj->doc_type;
+				$line->doc_ref = $obj->doc_ref;
+				$line->fk_doc = $obj->fk_doc;
+				$line->fk_docdet = $obj->fk_docdet;
+				$line->code_tiers = $obj->code_tiers;
+				$line->numero_compte = $obj->numero_compte;
+				$line->label_compte = $obj->label_compte;
+				$line->debit = $obj->debit;
+				$line->credit = $obj->credit;
+				$line->montant = $obj->montant;
+				$line->sens = $obj->sens;
+				$line->code_journal = $obj->code_journal;
+				$line->piece_num = $obj->piece_num;
+				
+				$this->linesmvt[] = $line;
 			}
-			$this->db->rollback();
-			return - 1 * $error;
-		}
-		else
-		{
-			$this->db->commit();
-			return 1;
+		} else {
+			$this->error = "Error " . $this->db->lasterror();
+			dol_syslog(get_class($this) . "::fetch_per_mvt " . $this->error, LOG_ERR);
+			return - 1;
 		}
+		
+		return 1;
 	}
-
+	
 	/**
-	 * Delete bookkepping by importkey
+	 * Export bookkeping
 	 *
 	 * @param	string	$model		Model
 	 * @return	int					Result
@@ -694,21 +1088,21 @@ class BookKeeping extends CommonObject
 		$sql .= " doc_ref, fk_doc, fk_docdet, code_tiers,";
 		$sql .= " numero_compte, label_compte, debit, credit,";
 		$sql .= " montant, sens, fk_user_author, import_key, code_journal, piece_num";
-		$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping";
-
+		$sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element;
+	
 		dol_syslog(get_class($this) . "::export_bookkeping", LOG_DEBUG);
-
+	
 		$resql = $this->db->query($sql);
-
+	
 		if ($resql) {
 			$this->linesexport = array ();
-
+	
 			$num = $this->db->num_rows($resql);
 			while ( $obj = $this->db->fetch_object($resql) ) {
 				$line = new BookKeepingLine();
-
+	
 				$line->id = $obj->rowid;
-
+	
 				$line->doc_date = $this->db->jdate($obj->doc_date);
 				$line->doc_type = $obj->doc_type;
 				$line->doc_ref = $obj->doc_ref;
@@ -723,11 +1117,11 @@ class BookKeeping extends CommonObject
 				$line->sens = $obj->sens;
 				$line->code_journal = $obj->code_journal;
 				$line->piece_num = $obj->piece_num;
-
+	
 				$this->linesexport[] = $line;
 			}
 			$this->db->free($resql);
-
+	
 			return $num;
 		}
 		else
@@ -742,22 +1136,22 @@ class BookKeeping extends CommonObject
 /**
  * Class BookKeepingLine
  */
-class BookKeepingLine
-{
-	var $id;
-	var $doc_date;
-	var $doc_type;
-	var $doc_ref;
-	var $fk_doc;
-	var $fk_docdet;
-	var $code_tiers;
-	var $numero_compte;
-	var $label_compte;
-	var $debit;
-	var $credit;
-	var $montant;
-	var $sens;
-	var $fk_user_author;
-	var $code_journal;
-	var $piece_num;
+class BookKeepingLine {
+	public $id;
+	public $doc_date = '';
+	public $doc_type;
+	public $doc_ref;
+	public $fk_doc;
+	public $fk_docdet;
+	public $code_tiers;
+	public $numero_compte;
+	public $label_compte;
+	public $debit;
+	public $credit;
+	public $montant;
+	public $sens;
+	public $fk_user_author;
+	public $import_key;
+	public $code_journal;
+	public $piece_num;
 }
diff --git a/htdocs/accountancy/class/html.formventilation.class.php b/htdocs/accountancy/class/html.formventilation.class.php
index 5e838fb475f..077b35b82b4 100644
--- a/htdocs/accountancy/class/html.formventilation.class.php
+++ b/htdocs/accountancy/class/html.formventilation.class.php
@@ -27,8 +27,7 @@
 /**
  *	Class to manage generation of HTML components for bank module
  */
-class FormVentilation extends Form
-{
+class FormVentilation extends Form {
 	var $db;
 	var $error;
 
@@ -37,8 +36,7 @@ class FormVentilation extends Form
      *
      * @param		DoliDB		$db      Database handler
      */
-	public function __construct($db)
-    {
+	public function __construct($db) {
         $this->db = $db;
     }
 
@@ -49,8 +47,7 @@ class FormVentilation extends Form
 	 *	@param	string	$selectedkey	Value
 	 *	@return	string					HTML edit field
 	 */
-	function select_bookkeeping_importkey($htmlname = 'importkey', $selectedkey='')
-	{
+	function select_bookkeeping_importkey($htmlname = 'importkey', $selectedkey = '') {
 		$sql  = 'SELECT DISTINCT import_key from ' . MAIN_DB_PREFIX . 'accounting_bookkeeping';
 		$sql .= ' ORDER BY import_key DESC';
 
@@ -94,12 +91,11 @@ class FormVentilation extends Form
 	 *  @param	array	$event			Event options
      *	@param	int		$select_in		$selectid value is a aa.rowid (0 default) or aa.account_number (1)
      *	@param	int		$select_out		set value returned by select 0=rowid (default), 1=account_number
-     *	@param	int		$aabase			set accounting_account base class to display empty=all or from 1 to 8 will display only account beginning by
+	 * @param int $aabase set accountingaccount base class to display empty=all or from 1 to 8 will display only account beginning by
      *
 	 *	@return	string					String with HTML select
 	 */
-	function select_account($selectid, $htmlname = 'account', $showempty = 0, $event = array(), $select_in = 0, $select_out = 0, $aabase = '')
-	{
+	function select_account($selectid, $htmlname = 'account', $showempty = 0, $event = array(), $select_in = 0, $select_out = 0, $aabase = '') {
 		global $conf;
 
 		$out = '';
@@ -128,10 +124,14 @@ class FormVentilation extends Form
 					$obj = $this->db->fetch_object($resql);
 					$label = $obj->account_number . ' - ' . $obj->label;
 					$label = dol_trunc($label, $trunclength);
-					if ($select_in == 0 )  $select_value_in =  $obj->rowid;
-					if ($select_in == 1 )  $select_value_in =  $obj->account_number;
-					if ($select_out == 0 ) $select_value_out = $obj->rowid;
-					if ($select_out == 1 ) $select_value_out = $obj->account_number;
+					if ($select_in == 0)
+						$select_value_in = $obj->rowid;
+					if ($select_in == 1)
+						$select_value_in = $obj->account_number;
+					if ($select_out == 0)
+						$select_value_out = $obj->rowid;
+					if ($select_out == 1)
+						$select_value_out = $obj->account_number;
 					// Remember guy's we store in database llx_facturedet the rowid of accounting_account and not the account_number
 					// Because same account_number can be share between different accounting_system and do have the same meaning
 					if (($selectid != '') && $selectid == $select_value_in) {
@@ -164,8 +164,7 @@ class FormVentilation extends Form
      *
 	 *	@return	string					String with HTML select
 	 */
-	function select_pcgtype($selectid, $htmlname = 'pcg_type', $showempty = 0, $event = array())
-	{
+	function select_pcgtype($selectid, $htmlname = 'pcg_type', $showempty = 0, $event = array()) {
 		global $conf;
 
 		$out = '';
@@ -220,8 +219,7 @@ class FormVentilation extends Form
      *
 	 *	@return	string					String with HTML select
 	 */
-	function select_pcgsubtype($selectid, $htmlname = 'pcg_subtype', $showempty = 0, $event = array())
-	{
+	function select_pcgsubtype($selectid, $htmlname = 'pcg_subtype', $showempty = 0, $event = array()) {
 		global $conf;
 
 		$out = '';
diff --git a/htdocs/accountancy/customer/list.php b/htdocs/accountancy/customer/list.php
index 7c025c8a893..fe5ac61f9c1 100644
--- a/htdocs/accountancy/customer/list.php
+++ b/htdocs/accountancy/customer/list.php
@@ -228,6 +228,9 @@ if ($result) {
 	
 	print_barre_liste($langs->trans("InvoiceLines"), $page, $_SERVER["PHP_SELF"], "", $sortfield, $sortorder, '', $num_lines);
 	print '<br><b>' . $langs->trans("DescVentilTodoCustomer") . '</b></br>';
+	print_liste_field_titre($langs->trans("Date"), $_SERVER["PHP_SELF"], "f.datef", "", $param, '', $sortfield, $sortorder);
+	print '&nbsp;&nbsp;';
+	print_liste_field_titre($langs->trans("RowId"), $_SERVER["PHP_SELF"], "l.rowid", "", $param, '', $sortfield, $sortorder);
 
 	print '<form action="' . $_SERVER["PHP_SELF"] . '" method="post">' . "\n";
 	print '<input type="hidden" name="action" value="ventil">';
diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php
index b33becb3f47..d077b6edebc 100644
--- a/htdocs/accountancy/journal/bankjournal.php
+++ b/htdocs/accountancy/journal/bankjournal.php
@@ -343,7 +343,7 @@ if ($action == 'writebookkeeping')
 				}
 			}
 
-			$result = $bookkeeping->create();
+			$result = $bookkeeping->create($user);
 			if ($result < 0) {
 				$error ++;
 				setEventMessages($object->error, $object->errors, 'errors');
@@ -421,7 +421,7 @@ if ($action == 'writebookkeeping')
 				$bookkeeping->numero_compte = $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER;
 			}
 
-			$result = $bookkeeping->create();
+			$result = $bookkeeping->create($user);
 			if ($result < 0) {
 				$error ++;
 				setEventMessages($object->error, $object->errors, 'errors');
diff --git a/htdocs/accountancy/journal/purchasesjournal.php b/htdocs/accountancy/journal/purchasesjournal.php
index 2346df27c77..b9f6fe2d542 100644
--- a/htdocs/accountancy/journal/purchasesjournal.php
+++ b/htdocs/accountancy/journal/purchasesjournal.php
@@ -182,7 +182,7 @@ if ($action == 'writebookkeeping') {
 			$bookkeeping->code_journal = $conf->global->ACCOUNTING_PURCHASE_JOURNAL;
 			$bookkeeping->fk_user_author = $user->id;
 
-			$result = $bookkeeping->create();
+			$result = $bookkeeping->create($user);
 			if ($result < 0) {
 				$error ++;
 				setEventMessages($object->error, $object->errors, 'errors');
@@ -212,7 +212,7 @@ if ($action == 'writebookkeeping') {
 					$bookkeeping->code_journal = $conf->global->ACCOUNTING_PURCHASE_JOURNAL;
 					$bookkeeping->fk_user_author = $user->id;
 
-					$result = $bookkeeping->create();
+					$result = $bookkeeping->create($user);
 					if ($result < 0) {
 						$error ++;
 						setEventMessages($object->error, $object->errors, 'errors');
@@ -243,7 +243,7 @@ if ($action == 'writebookkeeping') {
 				$bookkeeping->code_journal = $conf->global->ACCOUNTING_PURCHASE_JOURNAL;
 				$bookkeeping->fk_user_author = $user->id;
 
-				$result = $bookkeeping->create();
+				$result = $bookkeeping->create($user);
 				if ($result < 0) {
 					$error ++;
 					setEventMessages($object->error, $object->errors, 'errors');
diff --git a/htdocs/accountancy/journal/sellsjournal.php b/htdocs/accountancy/journal/sellsjournal.php
index b0ebc8e8df7..1c7ef749e33 100644
--- a/htdocs/accountancy/journal/sellsjournal.php
+++ b/htdocs/accountancy/journal/sellsjournal.php
@@ -217,7 +217,7 @@ if ($action == 'writebookkeeping')
 			$bookkeeping->code_journal = $conf->global->ACCOUNTING_SELL_JOURNAL;
 			$bookkeeping->fk_user_author = $user->id;
 
-			$result = $bookkeeping->create();
+			$result = $bookkeeping->create($user);
 			if ($result < 0) {
 				$error ++;
 				setEventMessages($object->error, $object->errors, 'errors');
@@ -247,7 +247,7 @@ if ($action == 'writebookkeeping')
 					$bookkeeping->code_journal = $conf->global->ACCOUNTING_SELL_JOURNAL;
 					$bookkeeping->fk_user_author = $user->id;
 
-					$result = $bookkeeping->create();
+					$result = $bookkeeping->create($user);
 					if ($result < 0) {
 						$error ++;
 						setEventMessages($object->error, $object->errors, 'errors');
@@ -279,7 +279,7 @@ if ($action == 'writebookkeeping')
 				$bookkeeping->code_journal = $conf->global->ACCOUNTING_SELL_JOURNAL;
 				$bookkeeping->fk_user_author = $user->id;
 
-				$result = $bookkeeping->create();
+				$result = $bookkeeping->create($user);
 				if ($result < 0) {
 					$error ++;
 					setEventMessages($object->error, $object->errors, 'errors');
@@ -531,6 +531,7 @@ if ($action == 'export_csv')
 
 	print "</table>";
 
+	// End of page
 	llxFooter();
 }
 
-- 
GitLab