Browse Source

Fix perf. Make only one request per group for year N-1.

Laurent Destailleur 6 years ago
parent
commit
fe35e72e83

+ 22 - 3
htdocs/accountancy/class/accountancycategory.class.php

@@ -717,7 +717,7 @@ class AccountancyCategory // extends CommonObject
 	/**
 	 * Function to show result of an accounting account from the ledger with a direction and a period
 	 *
-	 * @param int 		$cpt 				Id accounting account
+	 * @param int[array	$cpt 				Accounting account or array of accounting account
 	 * @param string 	$date_start			Date start
 	 * @param string 	$date_end			Date end
 	 * @param int 		$sens 				Sens of the account:  0: credit - debit, 1: debit - credit
@@ -734,10 +734,24 @@ class AccountancyCategory // extends CommonObject
 		$this->sdcpermonth = array();
 
 		$sql = "SELECT SUM(t.debit) as debit, SUM(t.credit) as credit";
+		if (is_array($cpt)) $sql.=", t.numero_compte as accountancy_account";
 		$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as t";
 		//if (in_array($this->db->type, array('mysql', 'mysqli'))) $sql.=' USE INDEX idx_accounting_bookkeeping_doc_date';
 		$sql .= " WHERE t.entity = ".$conf->entity;
-		$sql .= " AND t.numero_compte = '" . $this->db->escape($cpt) . "'";
+		if (is_array($cpt))
+		{
+			$listofaccount='';
+			foreach($cpt as $cptcursor)
+			{
+				if ($listofaccount) $listofaccount.=",";
+				$listofaccount.="'".$cptcursor."'";
+			}
+			$sql .= " AND t.numero_compte IN (" .$listofaccount. ")";
+		}
+		else
+		{
+			$sql .= " AND t.numero_compte = '" . $this->db->escape($cpt) . "'";
+		}
 		if (! empty($date_start) && ! empty($date_end) && (empty($month) || empty($year)))	// If month/year provided, it is stronger than filter date_start/date_end
 			$sql .= " AND (t.doc_date BETWEEN '".$this->db->idate($date_start)."' AND '".$this->db->idate($date_end)."')";
 		if (! empty($month) && ! empty($year)) {
@@ -747,6 +761,7 @@ class AccountancyCategory // extends CommonObject
 		{
 			$sql .= " AND t.thirdparty_code = '".$this->db->escape($thirdparty_code)."'";
 		}
+		if (is_array($cpt)) $sql.=" GROUP BY t.numero_compte";
 		//print $sql;
 
 		$resql = $this->db->query($sql);
@@ -761,11 +776,15 @@ class AccountancyCategory // extends CommonObject
 				} else {
 					$this->sdc = $obj->credit - $obj->debit;
 				}
-				$this->sdcpermonth[$year.'_'.$month.'_'.$sens] = $this->sdc;
+				if (is_array($cpt))
+				{
+					$this->sdcperaccount[$obj->accountancy_account] = $this->sdc;
+				}
 			}
 			return $num;
 		} else {
 			$this->error = "Error " . $this->db->lasterror();
+			$this->errors[] = $this->error;
 			dol_syslog(__METHOD__ . " " . $this->error, LOG_ERR);
 			return -1;
 		}

+ 59 - 54
htdocs/compta/resultat/result.php

@@ -382,6 +382,8 @@ elseif ($modecompta=="BOOKKEEPING")
 		}
 		else			// normal category
 		{
+			$code = $cat['code'];	// Category code we process
+
 			$totCat = array();
 			$totCat['NP'] = 0;
 			$totCat['N'] = 0;
@@ -394,60 +396,38 @@ elseif ($modecompta=="BOOKKEEPING")
 			// Set $cpts with array of accounts in the category/group
 			$cpts = $AccCat->getCptsCat($cat['rowid']);
 
-			print "<tr>";
-
-			// Column group
-			print '<td class="width200">';
-			print $cat['code'];
-			print '</td>';
+			$arrayofaccountforfilter=array();
+			foreach($cpts as $i => $cpt)	// Loop on each account.
+			{
+				$arrayofaccountforfilter[]=$cpt['account_number'];
+			}
 
-			// Label of group
-			print '<td>';
-			print $cat['label'];
-			if (count($cpts) > 0)	// Show example of 5 first accounting accounts
+			// N-1
+			if (! empty($arrayofaccountforfilter))
 			{
-				$i=0;
-				foreach($cpts as $cpt)
-				{
-					if ($i > 5)
+				$return = $AccCat->getSumDebitCredit($arrayofaccountforfilter, $date_start_previous, $date_end_previous, $cpt['dc']?$cpt['dc']:0);
+				var_dump($AccCat->sdcperaccount);
+				if ($return < 0) {
+					setEventMessages(null, $AccCat->errors, 'errors');
+					$resultNP=0;
+				} else {
+					foreach($cpts as $i => $cpt)	// Loop on each account.
 					{
-						print '...)';
-						break;
+						$resultNP = empty($AccCat->sdcperaccount[$cpt['account_number']])?0:$AccCat->sdcperaccount[$cpt['account_number']];
+
+						$totCat['NP'] += $resultNP;
+						$sommes[$code]['NP'] += $resultNP;
+						$totPerAccount[$cpt['account_number']]['NP'] = $resultNP;
 					}
-					if ($i > 0) print ', ';
-					else print ' (';
-					print $cpt['account_number'];
-					$i++;
 				}
-				if ($i <= 5) print ')';
 			}
-			else
-			{
-				print ' - <span class="warning">'.$langs->trans("GroupIsEmptyCheckSetup").'</span>';
-			}
-			print '</td>';
-
-			$code = $cat['code'];
 
 			// Set value into column N-1, N and each month M ($totCat)
 			// This make 14 calls for each detail of account (N-1, N and 12 monthes m)
 			foreach($cpts as $i => $cpt)	// Loop on each account.
 			{
-				// We make 1 loop for each account because we may want detail.
-				// @TODO Optimize mode when $showaccountdetail == 'no'
-
-				// N-1
-				$return = $AccCat->getSumDebitCredit($cpt['account_number'], $date_start_previous, $date_end_previous, $cpt['dc']?$cpt['dc']:0);
-				if ($return < 0) {
-					setEventMessages(null, $AccCat->errors, 'errors');
-					$resultNP=0;
-				} else {
-					$resultNP=$AccCat->sdc;
-				}
-
-				$totCat['NP'] += $resultNP;
-				$sommes[$code]['NP'] += $resultNP;
-				$totPerAccount[$cpt['account_number']]['NP'] = $resultNP;
+				// We make 1 loop for each account because we may want detail per account.
+				// @TODO Optimize to ask a 'group by' account and a filter with account in (..., ...) in request
 
 				// Each month
 				$resultN = 0;
@@ -472,21 +452,47 @@ elseif ($modecompta=="BOOKKEEPING")
 					$resultN += $resultM;
 				}
 
-				// N
-				/*$return = $AccCat->getSumDebitCredit($cpt['account_number'], $date_start, $date_end, $cpt['dc']);
-				if ($return < 0) {
-					setEventMessages(null, $AccCat->errors, 'errors');
-					$resultN=0;
-				} else {
-					$resultN=$AccCat->sdc;
-				}*/
-
 				$totCat['N'] += $resultN;
 				$sommes[$code]['N'] += $resultN;
 				$totPerAccount[$cpt['account_number']]['N'] = $resultN;
 			}
 
+
 			// Now output columns for row $code ('VTE', 'MAR', ...)
+
+			print "<tr>";
+
+			// Column group
+			print '<td class="width200">';
+			print $cat['code'];
+			print '</td>';
+
+			// Label of group
+			print '<td>';
+			print $cat['label'];
+			if (count($cpts) > 0)	// Show example of 5 first accounting accounts
+			{
+				$i=0;
+				foreach($cpts as $cpt)
+				{
+					if ($i > 5)
+					{
+						print '...)';
+						break;
+					}
+					if ($i > 0) print ', ';
+					else print ' (';
+					print $cpt['account_number'];
+					$i++;
+				}
+				if ($i <= 5) print ')';
+			}
+			else
+			{
+				print ' - <span class="warning">'.$langs->trans("GroupIsEmptyCheckSetup").'</span>';
+			}
+			print '</td>';
+
 			print '<td align="right">' . price($totCat['NP'])  . '</td>';
 			print '<td align="right">' . price($totCat['N']) . '</td>';
 
@@ -500,7 +506,7 @@ elseif ($modecompta=="BOOKKEEPING")
 
 			print "</tr>\n";
 
-			// Loop on detail of all accounts
+			// Loop on detail of all accounts to output the detail
 			if ($showaccountdetail != 'no')
 			{
 				foreach($cpts as $i => $cpt)
@@ -537,7 +543,6 @@ elseif ($modecompta=="BOOKKEEPING")
 								print '<td align="right">' . price($resultM) . '</td>';
 							}
 						}
-
 						print "</tr>\n";
 					}
 				}