diff --git a/htdocs/accountancy/admin/card.php b/htdocs/accountancy/admin/card.php
index 97d2509b898..43d1852c720 100644
--- a/htdocs/accountancy/admin/card.php
+++ b/htdocs/accountancy/admin/card.php
@@ -282,7 +282,7 @@ if ($action == 'create') {
print $form->textwithpicto($langs->trans("AccountingCategory"), $langs->transnoentitiesnoconv("AccountingAccountGroupsDesc"));
print '';
print '
';
- $formaccounting->select_accounting_category($object->account_category, 'account_category', 1, 0, 1);
+ print $formaccounting->select_accounting_category($object->account_category, 'account_category', 1, 0, 1);
print ' ';
print '';
@@ -359,7 +359,7 @@ if ($action == 'create') {
print $form->textwithpicto($langs->trans("AccountingCategory"), $langs->transnoentitiesnoconv("AccountingAccountGroupsDesc"));
print '';
print '';
- $formaccounting->select_accounting_category($object->account_category, 'account_category', 1);
+ print $formaccounting->select_accounting_category($object->account_category, 'account_category', 1);
print ' ';
print '';
diff --git a/htdocs/accountancy/admin/categories.php b/htdocs/accountancy/admin/categories.php
index 442c0d6763b..3414c36cd52 100644
--- a/htdocs/accountancy/admin/categories.php
+++ b/htdocs/accountancy/admin/categories.php
@@ -111,7 +111,7 @@ print '';
// Select the category
print ''.$langs->trans("AccountingCategory").' ';
print '';
-$formaccounting->select_accounting_category($cat_id, 'account_category', 1, 0, 0, 0);
+print $formaccounting->select_accounting_category($cat_id, 'account_category', 1, 0, 0, 0);
print ' ';
print ' ';
diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php
index 9590c3551cf..ac1cc93cba7 100644
--- a/htdocs/accountancy/bookkeeping/list.php
+++ b/htdocs/accountancy/bookkeeping/list.php
@@ -102,7 +102,9 @@ if (GETPOST("button_export_file_x") || GETPOST("button_export_file.x") || GETPOS
$action = 'export_file';
}
-$search_accountancy_code = GETPOST("search_accountancy_code");
+$search_account_category = GETPOST('search_account_category', 'int');
+
+$search_accountancy_code = GETPOST("search_accountancy_code", 'alpha');
$search_accountancy_code_start = GETPOST('search_accountancy_code_start', 'alpha');
if ($search_accountancy_code_start == - 1) {
$search_accountancy_code_start = '';
@@ -253,6 +255,7 @@ if (empty($reshook)) {
$search_doc_type = '';
$search_doc_ref = '';
$search_doc_date = '';
+ $search_account_category = '';
$search_accountancy_code = '';
$search_accountancy_code_start = '';
$search_accountancy_code_end = '';
@@ -335,6 +338,20 @@ if (empty($reshook)) {
$filter['t.doc_ref'] = $search_doc_ref;
$param .= '&search_doc_ref='.urlencode($search_doc_ref);
}
+ if ($search_account_category != '-1' && !empty($search_account_category)) {
+ require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountancycategory.class.php';
+ $accountingcategory = new AccountancyCategory($db);
+
+ $listofaccountsforgroup = $accountingcategory->getCptsCat(0, 'fk_accounting_category = '.((int) $search_account_category));
+ $listofaccountsforgroup2 = array();
+ if (is_array($listofaccountsforgroup)) {
+ foreach ($listofaccountsforgroup as $tmpval) {
+ $listofaccountsforgroup2[] = $tmpval['id'];
+ }
+ }
+ $filter['t.search_accounting_code_in'] = join(',', $listofaccountsforgroup2);
+ $param .= '&search_account_category='.urlencode($search_account_category);
+ }
if (!empty($search_accountancy_code)) {
$filter['t.numero_compte'] = $search_accountancy_code;
$param .= '&search_accountancy_code='.urlencode($search_accountancy_code);
@@ -642,6 +659,9 @@ $sql .= " t.tms as date_modification,";
$sql .= " t.date_export,";
$sql .= " t.date_validated as date_validation,";
$sql .= " t.import_key";
+
+$sqlfields = $sql; // $sql fields to remove for count total
+
$sql .= ' FROM '.MAIN_DB_PREFIX.$object->table_element.' as t';
// Manage filter
$sqlwhere = array();
@@ -672,7 +692,13 @@ if (count($filter) > 0) {
} elseif ($key == 't.reconciled_option') {
$sqlwhere[] = 't.lettering_code IS NULL';
} elseif ($key == 't.code_journal' && !empty($value)) {
- $sqlwhere[] = natural_search("t.code_journal", join(',', $value), 3, 1);
+ if (is_array($value)) {
+ $sqlwhere[] = natural_search("t.code_journal", join(',', $value), 3, 1);
+ } else {
+ $sqlwhere[] = natural_search("t.code_journal", $value, 3, 1);
+ }
+ } elseif ($key == 't.search_accounting_code_in' && !empty($value)) {
+ $sqlwhere[] = 't.numero_compte IN ('.$value.')';
} else {
$sqlwhere[] = natural_search($key, $value, 0, 1);
}
@@ -685,9 +711,6 @@ if (empty($conf->global->ACCOUNTING_REEXPORT)) {
if (count($sqlwhere) > 0) {
$sql .= ' AND '.implode(' AND ', $sqlwhere);
}
-if (!empty($sortfield)) {
- $sql .= $db->order($sortfield, $sortorder);
-}
//print $sql;
@@ -783,28 +806,38 @@ $title_page = $langs->trans("Operations").' - '.$langs->trans("Journals");
// Count total nb of records
$nbtotalofrecords = '';
if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
- $resql = $db->query($sql);
- $nbtotalofrecords = $db->num_rows($resql);
- if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0
+ /* The fast and low memory method to get and count full list converts the sql into a sql count */
+ $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql);
+ $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
+ $resql = $db->query($sqlforcount);
+ if ($resql) {
+ $objforcount = $db->fetch_object($resql);
+ $nbtotalofrecords = $objforcount->nbtotalofrecords;
+ } else {
+ dol_print_error($db);
+ }
+
+ if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
$page = 0;
$offset = 0;
}
+ $db->free($resql);
}
-// if total of record found is smaller than limit, no need to do paging and to restart another select with limits set.
-if (is_numeric($nbtotalofrecords) && $limit > $nbtotalofrecords) {
- $num = $nbtotalofrecords;
-} else {
+
+// Complete request and execute it with limit
+$sql .= $db->order($sortfield, $sortorder);
+if ($limit) {
$sql .= $db->plimit($limit + 1, $offset);
-
- $resql = $db->query($sql);
- if (!$resql) {
- dol_print_error($db);
- exit;
- }
-
- $num = $db->num_rows($resql);
}
+$resql = $db->query($sql);
+if (!$resql) {
+ dol_print_error($db);
+ exit;
+}
+
+$num = $db->num_rows($resql);
+
$arrayofselected = is_array($toselect) ? $toselect : array();
// Output page
@@ -997,6 +1030,12 @@ if ($massactionbutton && $contextpage != 'poslist') {
}
$moreforfilter = '';
+$moreforfilter .= '';
+$moreforfilter .= $langs->trans('AccountingCategory').': ';
+$moreforfilter .= '
';
+$moreforfilter .= $formaccounting->select_accounting_category($search_account_category, 'search_account_category', 1, 0, 0, 0);
+$moreforfilter .= '
';
+$moreforfilter .= '
';
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
@@ -1006,6 +1045,10 @@ if (empty($reshook)) {
$moreforfilter = $hookmanager->resPrint;
}
+print '';
+print $moreforfilter;
+print '
';
+
print '';
print '
';
diff --git a/htdocs/accountancy/bookkeeping/listbyaccount.php b/htdocs/accountancy/bookkeeping/listbyaccount.php
index 4a6e37ceb29..c24e509ff60 100644
--- a/htdocs/accountancy/bookkeeping/listbyaccount.php
+++ b/htdocs/accountancy/bookkeeping/listbyaccount.php
@@ -79,7 +79,8 @@ $search_date_validation_start = dol_mktime(0, 0, 0, $search_date_validation_star
$search_date_validation_end = dol_mktime(23, 59, 59, $search_date_validation_endmonth, $search_date_validation_endday, $search_date_validation_endyear);
$search_import_key = GETPOST("search_import_key", 'alpha');
-$search_accountancy_code = GETPOST("search_accountancy_code");
+$search_account_category = GETPOST('search_account_category', 'int');
+
$search_accountancy_code_start = GETPOST('search_accountancy_code_start', 'alpha');
if ($search_accountancy_code_start == - 1) {
$search_accountancy_code_start = '';
@@ -198,6 +199,8 @@ if (!$user->hasRight('accounting', 'mouvements', 'lire')) {
accessforbidden();
}
+$error = 0;
+
/*
* Action
@@ -224,7 +227,7 @@ if (empty($reshook)) {
if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers
$search_doc_date = '';
- $search_accountancy_code = '';
+ $search_account_category = '';
$search_accountancy_code_start = '';
$search_accountancy_code_end = '';
$search_label_account = '';
@@ -280,6 +283,20 @@ if (empty($reshook)) {
$filter['t.doc_date'] = $search_doc_date;
$param .= '&doc_datemonth='.GETPOST('doc_datemonth', 'int').'&doc_dateday='.GETPOST('doc_dateday', 'int').'&doc_dateyear='.GETPOST('doc_dateyear', 'int');
}
+ if ($search_account_category != '-1' && !empty($search_account_category)) {
+ require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountancycategory.class.php';
+ $accountingcategory = new AccountancyCategory($db);
+
+ $listofaccountsforgroup = $accountingcategory->getCptsCat(0, 'fk_accounting_category = '.((int) $search_account_category));
+ $listofaccountsforgroup2 = array();
+ if (is_array($listofaccountsforgroup)) {
+ foreach ($listofaccountsforgroup as $tmpval) {
+ $listofaccountsforgroup2[] = $tmpval['id'];
+ }
+ }
+ $filter['t.search_accounting_code_in'] = join(',', $listofaccountsforgroup2);
+ $param .= '&search_account_category='.urlencode($search_account_category);
+ }
if (!empty($search_accountancy_code_start)) {
if ($type == 'sub') {
$filter['t.subledger_account>='] = $search_accountancy_code_start;
@@ -358,7 +375,6 @@ if (empty($reshook)) {
$filter['t.import_key'] = $search_import_key;
$param .= '&search_import_key='.urlencode($search_import_key);
}
-
// param with type of list
$url_param = substr($param, 1); // remove first "&"
if (!empty($type)) {
@@ -544,25 +560,29 @@ llxHeader('', $title_page);
// List
$nbtotalofrecords = '';
if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
+ // TODO Perf Replace this by a count
if ($type == 'sub') {
- $nbtotalofrecords = $object->fetchAllByAccount($sortorder, $sortfield, 0, 0, $filter, 'AND', 1);
+ $nbtotalofrecords = $object->fetchAllByAccount($sortorder, $sortfield, 0, 0, $filter, 'AND', 1, 1);
} else {
- $nbtotalofrecords = $object->fetchAllByAccount($sortorder, $sortfield, 0, 0, $filter);
+ $nbtotalofrecords = $object->fetchAllByAccount($sortorder, $sortfield, 0, 0, $filter, 'AND', 0, 1);
}
if ($nbtotalofrecords < 0) {
setEventMessages($object->error, $object->errors, 'errors');
+ $error++;
}
}
-if ($type == 'sub') {
- $result = $object->fetchAllByAccount($sortorder, $sortfield, $limit, $offset, $filter, 'AND', 1);
-} else {
- $result = $object->fetchAllByAccount($sortorder, $sortfield, $limit, $offset, $filter);
-}
+if (!$error) {
+ if ($type == 'sub') {
+ $result = $object->fetchAllByAccount($sortorder, $sortfield, $limit, $offset, $filter, 'AND', 1);
+ } else {
+ $result = $object->fetchAllByAccount($sortorder, $sortfield, $limit, $offset, $filter, 'AND', 0);
+ }
-if ($result < 0) {
- setEventMessages($object->error, $object->errors, 'errors');
+ if ($result < 0) {
+ setEventMessages($object->error, $object->errors, 'errors');
+ }
}
$arrayofselected = is_array($toselect) ? $toselect : array();
@@ -711,7 +731,7 @@ if ($type == 'sub') {
$moreforfilter = '';
-// Accountancy account
+// Search on accountancy custom groups or account
$moreforfilter .= '';
$moreforfilter .= $langs->trans('AccountAccounting').': ';
$moreforfilter .= '
';
@@ -729,6 +749,13 @@ if ($type == 'sub') {
$moreforfilter .= '
';
$moreforfilter .= '
';
+$moreforfilter .= '';
+$moreforfilter .= $langs->trans('AccountingCategory').': ';
+$moreforfilter .= '
';
+$moreforfilter .= $formaccounting->select_accounting_category($search_account_category, 'search_account_category', 1, 0, 0, 0);
+$moreforfilter .= '
';
+$moreforfilter .= '
';
+
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook
if (empty($reshook)) {
diff --git a/htdocs/accountancy/class/accountancycategory.class.php b/htdocs/accountancy/class/accountancycategory.class.php
index 2f6c71dde7f..74626aa61e0 100644
--- a/htdocs/accountancy/class/accountancycategory.class.php
+++ b/htdocs/accountancy/class/accountancycategory.class.php
@@ -605,60 +605,6 @@ class AccountancyCategory // extends CommonObject
}
}
- /**
- * Function to know all custom groupd from an accounting account
- *
- * @return array|integer Result in table (array), -1 if KO
- */
- public function getCatsCpts()
- {
- global $mysoc, $conf;
-
- if (empty($mysoc->country_id)) {
- dol_print_error('', 'Call to select_accounting_account with mysoc country not yet defined');
- exit();
- }
-
- $sql = "SELECT t.rowid, t.account_number, t.label as account_label, cat.code, cat.position, cat.label as name_cat, cat.sens ";
- $sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as t, ".MAIN_DB_PREFIX."c_accounting_category as cat";
- $sql .= " WHERE t.fk_accounting_category IN ( SELECT c.rowid ";
- $sql .= " FROM ".MAIN_DB_PREFIX."c_accounting_category as c";
- $sql .= " WHERE c.active = 1";
- $sql .= " AND c.entity = ".$conf->entity;
- $sql .= " AND (c.fk_country = ".((int) $mysoc->country_id)." OR c.fk_country = 0)";
- $sql .= " AND cat.rowid = t.fk_accounting_category";
- $sql .= " AND t.entity = ".$conf->entity;
- $sql .= " ORDER BY cat.position ASC";
-
- $resql = $this->db->query($sql);
- if ($resql) {
- $i = 0;
- $obj = '';
- $num = $this->db->num_rows($resql);
- $data = array();
- if ($num) {
- while ($obj = $this->db->fetch_object($resql)) {
- $name_cat = $obj->name_cat;
- $data[$name_cat][$i] = array(
- 'id' => $obj->rowid,
- 'code' => $obj->code,
- 'position' => $obj->position,
- 'account_number' => $obj->account_number,
- 'account_label' => $obj->account_label,
- 'sens' => $obj->sens
- );
- $i++;
- }
- }
- return $data;
- } else {
- $this->error = "Error ".$this->db->lasterror();
- dol_syslog(__METHOD__." ".$this->error, LOG_ERR);
-
- return -1;
- }
- }
-
/**
* Function to show result of an accounting account from the ledger with a direction and a period
*
@@ -734,12 +680,75 @@ class AccountancyCategory // extends CommonObject
}
}
+ /**
+ * Function to get an array of all active custom groups (llx_c_accunting_categories) with their accounts from the chart of account (ll_accounting_acount)
+ *
+ * @param int $catid Custom group ID
+ * @return array|integer Result in table (array), -1 if KO
+ * @see getCats(), getCptsCat()
+ */
+ public function getCatsCpts($catid = 0)
+ {
+ global $mysoc, $conf;
+
+ if (empty($mysoc->country_id)) {
+ $this->error = "Error ".$this->db->lasterror();
+ dol_syslog(__METHOD__." ".$this->error, LOG_ERR);
+ return -1;
+ }
+
+ $sql = "SELECT t.rowid, t.account_number, t.label as account_label,";
+ $sql .= " cat.code, cat.position, cat.label as name_cat, cat.sens, cat.category_type, cat.formula";
+ $sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as t, ".MAIN_DB_PREFIX."c_accounting_category as cat";
+ $sql .= " WHERE t.fk_accounting_category IN (SELECT c.rowid";
+ $sql .= " FROM ".MAIN_DB_PREFIX."c_accounting_category as c";
+ $sql .= " WHERE c.active = 1";
+ $sql .= " AND c.entity = ".$conf->entity;
+ $sql .= " AND (c.fk_country = ".((int) $mysoc->country_id)." OR c.fk_country = 0)";
+ $sql .= " AND cat.rowid = t.fk_accounting_category";
+ $sql .= " AND t.entity = ".$conf->entity;
+ if ($catid > 0) {
+ $sql .= " AND cat.rowid = ".((int) $catid);
+ }
+ $sql .= " ORDER BY cat.position ASC";
+
+ $resql = $this->db->query($sql);
+ if ($resql) {
+ $obj = '';
+ $num = $this->db->num_rows($resql);
+ $data = array();
+ if ($num) {
+ while ($obj = $this->db->fetch_object($resql)) {
+ $name_cat = $obj->name_cat;
+ $data[$name_cat][$obj->rowid] = array(
+ 'id' => $obj->rowid,
+ 'code' => $obj->code,
+ 'label' => $obj->label,
+ 'position' => $obj->position,
+ 'category_type' => $obj->category_type,
+ 'formula' => $obj->formula,
+ 'sens' => $obj->sens,
+ 'account_number' => $obj->account_number,
+ 'account_label' => $obj->account_label
+ );
+ }
+ }
+ return $data;
+ } else {
+ $this->error = "Error ".$this->db->lasterror();
+ dol_syslog(__METHOD__." ".$this->error, LOG_ERR);
+ return -1;
+ }
+ }
+
/**
* Return list of custom groups.
+ * For list + detail of accounting account, see getCatsCpt()
*
* @param int $categorytype -1=All, 0=Only non computed groups, 1=Only computed groups
* @param int $active 1= active, 0=not active
* @return array|int Array of groups or -1 if error
+ * @see getCatsCpts(), getCptsCat()
*/
public function getCats($categorytype = -1, $active = 1)
{
@@ -774,9 +783,10 @@ class AccountancyCategory // extends CommonObject
'rowid' => $obj->rowid,
'code' => $obj->code,
'label' => $obj->label,
- 'formula' => $obj->formula,
'position' => $obj->position,
'category_type' => $obj->category_type,
+ 'formula' => $obj->formula,
+ 'sens' => $obj->sens,
'bc' => $obj->sens
);
$i++;
@@ -794,12 +804,15 @@ class AccountancyCategory // extends CommonObject
/**
- * Get all accounting account of a custom group (or a list of custom groups).
+ * Get all accounting account of a given custom group (or a list of custom groups).
* You must choose between first parameter (personalized group) or the second (free criteria filter)
*
* @param int $cat_id Id if personalized accounting group/category
- * @param string $predefinedgroupwhere Sql criteria filter to select accounting accounts. This value must not come from an input of a user.
+ * @param string $predefinedgroupwhere Sql criteria filter to select accounting accounts. This value must be sanitized and not come from an input of a user.
+ * Example: "pcg_type = 'EXPENSE' AND fk_pcg_version = 'xx'"
+ * Example: "fk_accounting_category = 99"
* @return array|int Array of accounting accounts or -1 if error
+ * @see getCats(), getCatsCpts()
*/
public function getCptsCat($cat_id, $predefinedgroupwhere = '')
{
diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php
index 95ba38d20bb..0458250489f 100644
--- a/htdocs/accountancy/class/bookkeeping.class.php
+++ b/htdocs/accountancy/class/bookkeeping.class.php
@@ -817,56 +817,61 @@ class BookKeeping extends CommonObject
/**
- * Load object in memory from the database
+ * Load object in memory from the database in ->lines. Or just make a simple count if $countonly=1.
*
- * @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)
- * @param int $option option (0: general account or 1: subaccount)
- *
- * @return int <0 if KO, >=0 if OK
+ * @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)
+ * @param int $option option (0: general account or 1: subaccount)
+ * @param int $countonly Do not fill the $object->lines, return only the count.
+ * @return int <0 if KO, Number of lines if OK
*/
- public function fetchAllByAccount($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND', $option = 0)
+ public function fetchAllByAccount($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND', $option = 0, $countonly = 0)
{
global $conf;
dol_syslog(__METHOD__, LOG_DEBUG);
$this->lines = array();
+ $num = 0;
$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.thirdparty_code,";
- $sql .= " t.subledger_account,";
- $sql .= " t.subledger_label,";
- $sql .= " t.numero_compte,";
- $sql .= " t.label_compte,";
- $sql .= " t.label_operation,";
- $sql .= " t.debit,";
- $sql .= " t.credit,";
- $sql .= " t.montant as amount,";
- $sql .= " t.sens,";
- $sql .= " t.multicurrency_amount,";
- $sql .= " t.multicurrency_code,";
- $sql .= " t.lettering_code,";
- $sql .= " t.date_lettering,";
- $sql .= " t.fk_user_author,";
- $sql .= " t.import_key,";
- $sql .= " t.code_journal,";
- $sql .= " t.journal_label,";
- $sql .= " t.piece_num,";
- $sql .= " t.date_creation,";
- $sql .= " t.date_export,";
- $sql .= " t.date_validated as date_validation,";
- $sql .= " t.import_key";
+ if ($countonly) {
+ $sql .= ' COUNT(t.rowid) as nb';
+ } else {
+ $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.thirdparty_code,";
+ $sql .= " t.subledger_account,";
+ $sql .= " t.subledger_label,";
+ $sql .= " t.numero_compte,";
+ $sql .= " t.label_compte,";
+ $sql .= " t.label_operation,";
+ $sql .= " t.debit,";
+ $sql .= " t.credit,";
+ $sql .= " t.montant as amount,";
+ $sql .= " t.sens,";
+ $sql .= " t.multicurrency_amount,";
+ $sql .= " t.multicurrency_code,";
+ $sql .= " t.lettering_code,";
+ $sql .= " t.date_lettering,";
+ $sql .= " t.fk_user_author,";
+ $sql .= " t.import_key,";
+ $sql .= " t.code_journal,";
+ $sql .= " t.journal_label,";
+ $sql .= " t.piece_num,";
+ $sql .= " t.date_creation,";
+ $sql .= " t.date_export,";
+ $sql .= " t.date_validated as date_validation,";
+ $sql .= " t.import_key";
+ }
// Manage filter
$sqlwhere = array();
if (count($filter) > 0) {
@@ -880,7 +885,7 @@ class BookKeeping extends CommonObject
} elseif ($key == 't.fk_doc' || $key == 't.fk_docdet' || $key == 't.piece_num') {
$sqlwhere[] = $key.'='.$value;
} elseif ($key == 't.subledger_account' || $key == 't.numero_compte') {
- $sqlwhere[] = $key.' LIKE \''.$this->db->escape($value).'%\'';
+ $sqlwhere[] = $key.' LIKE \''.$this->db->escapeforlike($this->db->escape($value)).'%\'';
} elseif ($key == 't.date_creation>=' || $key == 't.date_creation<=') {
$sqlwhere[] = $key.'\''.$this->db->idate($value).'\'';
} elseif ($key == 't.date_export>=' || $key == 't.date_export<=') {
@@ -897,18 +902,19 @@ class BookKeeping extends CommonObject
} else {
$sqlwhere[] = natural_search("t.code_journal", $value, 3, 1);
}
+ } elseif ($key == 't.search_accounting_code_in' && !empty($value)) {
+ $sqlwhere[] = 't.numero_compte IN ('.$value.')';
} else {
$sqlwhere[] = natural_search($key, $value, 0, 1);
}
}
}
$sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
- $sql .= ' WHERE 1 = 1';
- $sql .= " AND entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features
+ $sql .= ' WHERE entity = ' . ((int) $conf->entity); // Do not use getEntity for accounting features
if (count($sqlwhere) > 0) {
$sql .= " AND ".implode(" ".$filtermode." ", $sqlwhere);
}
- // Affichage par compte comptable
+ // Filter by ledger account or subledger account
if (!empty($option)) {
$sql .= " AND t.subledger_account IS NOT NULL";
$sql .= " AND t.subledger_account <> ''";
@@ -919,54 +925,63 @@ class BookKeeping extends CommonObject
$sortorder = 'ASC'.($sortorder ? ','.$sortorder : '');
}
- $sql .= $this->db->order($sortfield, $sortorder);
- if (!empty($limit)) {
- $sql .= $this->db->plimit($limit + 1, $offset);
+ if (!$countonly) {
+ $sql .= $this->db->order($sortfield, $sortorder);
+ if (!empty($limit)) {
+ $sql .= $this->db->plimit($limit + 1, $offset);
+ }
}
$resql = $this->db->query($sql);
if ($resql) {
- $num = $this->db->num_rows($resql);
+ if ($countonly) {
+ $obj = $this->db->fetch_object($resql);
+ if ($obj) {
+ $num = $obj->nb;
+ }
+ } else {
+ $num = $this->db->num_rows($resql);
- $i = 0;
- while (($obj = $this->db->fetch_object($resql)) && (empty($limit) || $i < min($limit, $num))) {
- $line = new BookKeepingLine();
+ $i = 0;
+ while (($obj = $this->db->fetch_object($resql)) && (empty($limit) || $i < min($limit, $num))) {
+ $line = new BookKeepingLine();
- $line->id = $obj->rowid;
+ $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->thirdparty_code = $obj->thirdparty_code;
- $line->subledger_account = $obj->subledger_account;
- $line->subledger_label = $obj->subledger_label;
- $line->numero_compte = $obj->numero_compte;
- $line->label_compte = $obj->label_compte;
- $line->label_operation = $obj->label_operation;
- $line->debit = $obj->debit;
- $line->credit = $obj->credit;
- $line->montant = $obj->amount; // deprecated
- $line->amount = $obj->amount;
- $line->sens = $obj->sens;
- $line->multicurrency_amount = $obj->multicurrency_amount;
- $line->multicurrency_code = $obj->multicurrency_code;
- $line->lettering_code = $obj->lettering_code;
- $line->date_lettering = $obj->date_lettering;
- $line->fk_user_author = $obj->fk_user_author;
- $line->import_key = $obj->import_key;
- $line->code_journal = $obj->code_journal;
- $line->journal_label = $obj->journal_label;
- $line->piece_num = $obj->piece_num;
- $line->date_creation = $this->db->jdate($obj->date_creation);
- $line->date_export = $this->db->jdate($obj->date_export);
- $line->date_validation = $this->db->jdate($obj->date_validation);
- $line->import_key = $obj->import_key;
+ $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->thirdparty_code = $obj->thirdparty_code;
+ $line->subledger_account = $obj->subledger_account;
+ $line->subledger_label = $obj->subledger_label;
+ $line->numero_compte = $obj->numero_compte;
+ $line->label_compte = $obj->label_compte;
+ $line->label_operation = $obj->label_operation;
+ $line->debit = $obj->debit;
+ $line->credit = $obj->credit;
+ $line->montant = $obj->amount; // deprecated
+ $line->amount = $obj->amount;
+ $line->sens = $obj->sens;
+ $line->multicurrency_amount = $obj->multicurrency_amount;
+ $line->multicurrency_code = $obj->multicurrency_code;
+ $line->lettering_code = $obj->lettering_code;
+ $line->date_lettering = $obj->date_lettering;
+ $line->fk_user_author = $obj->fk_user_author;
+ $line->import_key = $obj->import_key;
+ $line->code_journal = $obj->code_journal;
+ $line->journal_label = $obj->journal_label;
+ $line->piece_num = $obj->piece_num;
+ $line->date_creation = $this->db->jdate($obj->date_creation);
+ $line->date_export = $this->db->jdate($obj->date_export);
+ $line->date_validation = $this->db->jdate($obj->date_validation);
+ $line->import_key = $obj->import_key;
- $this->lines[] = $line;
+ $this->lines[] = $line;
- $i++;
+ $i++;
+ }
}
$this->db->free($resql);
diff --git a/htdocs/core/class/html.formaccounting.class.php b/htdocs/core/class/html.formaccounting.class.php
index 8ebac3611cb..545d0da67a1 100644
--- a/htdocs/core/class/html.formaccounting.class.php
+++ b/htdocs/core/class/html.formaccounting.class.php
@@ -224,7 +224,7 @@ class FormAccounting extends Form
* @param int $maxlen Max length of text in combo box
* @param int $help Add or not the admin help picto
* @param int $allcountries All countries
- * @return void
+ * @return string HTML component with the select
*/
public function select_accounting_category($selected = '', $htmlname = 'account_category', $useempty = 0, $maxlen = 0, $help = 1, $allcountries = 0)
{
@@ -295,7 +295,7 @@ class FormAccounting extends Form
$out .= ajax_combobox($htmlname, array());
- print $out;
+ return $out;
}
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang
index b6bf1b90aef..03af44134e2 100644
--- a/htdocs/langs/en_US/accountancy.lang
+++ b/htdocs/langs/en_US/accountancy.lang
@@ -217,7 +217,7 @@ Codejournal=Journal
JournalLabel=Journal label
NumPiece=Piece number
TransactionNumShort=Num. transaction
-AccountingCategory=Custom group
+AccountingCategory=Custom group of accounts
GroupByAccountAccounting=Group by general ledger account
GroupBySubAccountAccounting=Group by subledger account
AccountingAccountGroupsDesc=You can define here some groups of accounting account. They will be used for personalized accounting reports.