';
print '
';
@@ -571,20 +593,6 @@ if ($resql) {
$num = $db->num_rows($resql);
$i = 0;
- $param = '&id='.$id;
- if ($search_country_id > 0) {
- $param .= '&search_country_id='.urlencode($search_country_id);
- }
- $paramwithsearch = $param;
- if ($sortorder) {
- $paramwithsearch .= '&sortorder='.$sortorder;
- }
- if ($sortfield) {
- $paramwithsearch .= '&sortfield='.$sortfield;
- }
- if (GETPOST('from', 'alpha')) {
- $paramwithsearch .= '&from='.GETPOST('from', 'alpha');
- }
// There is several pages
if ($num > $listlimit) {
print '';
@@ -743,7 +751,8 @@ if ($resql) {
foreach ($fieldlist as $field => $value) {
$showfield = 1;
$class = "left";
- $valuetoshow = $obj->{$fieldlist[$field]};
+ $tmpvar = $fieldlist[$field];
+ $valuetoshow = $obj->$tmpvar;
if ($value == 'category_type') {
$valuetoshow = yn($valuetoshow);
} elseif ($valuetoshow == 'all') {
@@ -822,7 +831,7 @@ if ($resql) {
}
// Link to setup the group
- print ' ';
+ print ' ';
if (empty($obj->formula)) {
print '';
print $langs->trans("ListOfAccounts");
diff --git a/htdocs/accountancy/admin/defaultaccounts.php b/htdocs/accountancy/admin/defaultaccounts.php
index 9a3b63adcc3..2bd1037db39 100644
--- a/htdocs/accountancy/admin/defaultaccounts.php
+++ b/htdocs/accountancy/admin/defaultaccounts.php
@@ -84,6 +84,9 @@ $list_account[] = 'ACCOUNTING_VAT_PAY_ACCOUNT';
if (isModEnabled('banque')) {
$list_account[] = 'ACCOUNTING_ACCOUNT_TRANSFER_CASH';
}
+if (!empty($conf->global->INVOICE_USE_RETAINED_WARRANTY)) {
+ $list_account[] = 'ACCOUNTING_ACCOUNT_CUSTOMER_RETAINED_WARRANTY';
+}
if (isModEnabled('don')) {
$list_account[] = 'DONATION_ACCOUNTINGACCOUNT';
}
diff --git a/htdocs/accountancy/admin/index.php b/htdocs/accountancy/admin/index.php
index 385c105451e..3a7be3e073e 100644
--- a/htdocs/accountancy/admin/index.php
+++ b/htdocs/accountancy/admin/index.php
@@ -261,6 +261,20 @@ if ($action == 'setenablelettering') {
}
}
+if ($action == 'setenableautolettering') {
+ $setenableautolettering = GETPOST('value', 'int');
+ $res = dolibarr_set_const($db, "ACCOUNTING_ENABLE_AUTOLETTERING", $setenableautolettering, 'yesno', 0, '', $conf->entity);
+ if (!($res > 0)) {
+ $error++;
+ }
+
+ if (!$error) {
+ setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
+ } else {
+ setEventMessages($langs->trans("Error"), null, 'mesgs');
+ }
+}
+
/*
* View
@@ -430,7 +444,7 @@ foreach ($list_binding as $key) {
print $form->selectDate((!empty($conf->global->$key) ? $db->idate($conf->global->$key) : -1), $key, 0, 0, 1);
} elseif ($key == 'ACCOUNTING_DEFAULT_PERIOD_ON_TRANSFER') {
$array = array(0=>$langs->trans("PreviousMonth"), 1=>$langs->trans("CurrentMonth"), 2=>$langs->trans("Fiscalyear"));
- print $form->selectarray($key, $array, (isset($conf->global->ACCOUNTING_DEFAULT_PERIOD_ON_TRANSFER) ? $conf->global->ACCOUNTING_DEFAULT_PERIOD_ON_TRANSFER : 0));
+ print $form->selectarray($key, $array, (isset($conf->global->ACCOUNTING_DEFAULT_PERIOD_ON_TRANSFER) ? $conf->global->ACCOUNTING_DEFAULT_PERIOD_ON_TRANSFER : 0), 0, 0, 0, '', 0, 0, 0, '', 'onrightofpage');
} else {
print ' ';
}
@@ -479,6 +493,7 @@ if (!empty($conf->global->ACCOUNTING_DISABLE_BINDING_ON_EXPENSEREPORTS)) {
print ' ';
print '
';
+print '
';
// Lettering params
print '
';
print '
';
diff --git a/htdocs/accountancy/admin/journals_list.php b/htdocs/accountancy/admin/journals_list.php
index e1a07fef5fc..ba2d867ebd6 100644
--- a/htdocs/accountancy/admin/journals_list.php
+++ b/htdocs/accountancy/admin/journals_list.php
@@ -587,7 +587,8 @@ if ($id) {
foreach ($fieldlist as $field => $value) {
$showfield = 1;
$class = "left";
- $valuetoshow = $obj->{$fieldlist[$field]};
+ $tmpvar = $fieldlist[$field];
+ $valuetoshow = $obj->$tmpvar;
if ($valuetoshow == 'all') {
$valuetoshow = $langs->trans('All');
} elseif ($fieldlist[$field] == 'nature' && $tabname[$id] == MAIN_DB_PREFIX.'accounting_journal') {
diff --git a/htdocs/accountancy/admin/subaccount.php b/htdocs/accountancy/admin/subaccount.php
index 4f2274269d8..40055a4b75f 100644
--- a/htdocs/accountancy/admin/subaccount.php
+++ b/htdocs/accountancy/admin/subaccount.php
@@ -19,17 +19,18 @@
/**
* \file htdocs/accountancy/admin/subaccount.php
- * \ingroup Accountancy (Double entries)
- * \brief List of accounting sub-account (auxiliary accounts)
+ * \ingroup Accountancy (Double entries)
+ * \brief List of accounting sub-account (auxiliary accounts)
*/
// Load Dolibarr environment
require '../../main.inc.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
+
// Load translation files required by the page
-$langs->loadLangs(array("compta", "bills", "admin", "accountancy", "salaries", "hrm", "errors"));
+$langs->loadLangs(array("accountancy", "admin", "bills", "compta", "errors", "hrm", "salaries"));
$mesg = '';
$action = GETPOST('action', 'aZ09');
@@ -81,6 +82,7 @@ if ($conf->global->MAIN_FEATURES_LEVEL < 2) {
unset($arrayfields['reconcilable']);
}
+
/*
* Actions
*/
@@ -120,11 +122,13 @@ if (empty($reshook)) {
$form = new Form($db);
-$help_url = '';
-$title = $langs->trans('ChartOfIndividualAccountsOfSubsidiaryLedger');
+// Page Header
+$help_url = 'EN:Module_Double_Entry_Accounting#Setup';
+$title = $langs->trans('ChartOfIndividualAccountsOfSubsidiaryLedger');
llxHeader('', $title, $help_url);
+
// Customer
$sql = "SELECT sa.rowid, sa.nom as label, sa.code_compta as subaccount, '1' as type, sa.entity";
$sql .= " FROM ".MAIN_DB_PREFIX."societe sa";
@@ -219,7 +223,7 @@ if (!empty($search_type) && $search_type >= 0) {
$sql .= " HAVING type LIKE '".$db->escape($search_type)."'";
}
-// User
+// User - Employee
$sql .= " UNION ";
$sql .= " SELECT u.rowid, u.lastname as label, u.accountancy_code as subaccount, '3' as type, u.entity FROM ".MAIN_DB_PREFIX."user u";
$sql .= " WHERE u.entity IN (".getEntity('user').")";
@@ -400,6 +404,7 @@ if ($resql) {
if (!empty($arrayfields['type']['checked'])) {
print '
';
$s = '';
+
// Customer
if ($obj->type == 1) {
$s .= ''.$langs->trans("Customer").' ';
@@ -407,7 +412,7 @@ if ($resql) {
// Supplier
$s .= ''.$langs->trans("Supplier").' ';
} elseif ($obj->type == 3) {
- // User
+ // User - Employee
$s .= ''.$langs->trans("Employee").' ';
}
print $s;
@@ -440,6 +445,7 @@ if ($resql) {
// Action
print ' ';
$e = '';
+
// Customer
if ($obj->type == 1) {
$e .= ''.img_edit().' ';
@@ -447,7 +453,7 @@ if ($resql) {
// Supplier
$e .= ''.img_edit().' ';
} elseif ($obj->type == 3) {
- // User
+ // User - Employee
$e .= ''.img_edit().' ';
}
print $e;
diff --git a/htdocs/accountancy/bookkeeping/balance.php b/htdocs/accountancy/bookkeeping/balance.php
index 01d89f1168d..fd8cd8ad688 100644
--- a/htdocs/accountancy/bookkeeping/balance.php
+++ b/htdocs/accountancy/bookkeeping/balance.php
@@ -1,7 +1,7 @@
* Copyright (C) 2016 Florian Henry
- * Copyright (C) 2016-2022 Alexandre Spangaro
+ * Copyright (C) 2016-2023 Alexandre Spangaro
* Copyright (C) 2018 Frédéric France
*
* This program is free software; you can redistribute it and/or modify
@@ -42,22 +42,13 @@ $langs->loadLangs(array("accountancy", "compta"));
$action = GETPOST('action', 'aZ09');
$optioncss = GETPOST('optioncss', 'alpha');
-$contextpage = GETPOST('contextpage', 'aZ09');
-
-// Load variable for pagination
-$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
-$sortfield = GETPOST('sortfield', 'aZ09comma');
-$sortorder = GETPOST('sortorder', 'aZ09comma');
-$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
-if (empty($page) || $page == -1 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha') || (empty($toselect) && $massaction === '0')) {
- $page = 0;
-} // If $page is not defined, or '' or -1 or if we click on clear filters or if we select empty mass action
-$offset = $limit * $page;
-$pageprev = $page - 1;
-$pagenext = $page + 1;
-//if (! $sortfield) $sortfield="p.date_fin";
-//if (! $sortorder) $sortorder="DESC";
-
+$type = GETPOST('type', 'alpha');
+if ($type == 'sub') {
+ $context_default = 'balancesubaccountlist';
+} else {
+ $context_default = 'balancelist';
+}
+$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : $context_default;
$show_subgroup = GETPOST('show_subgroup', 'alpha');
$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(23, 59, 59, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int'));
@@ -70,10 +61,29 @@ $search_accountancy_code_end = GETPOST('search_accountancy_code_end', 'alpha');
if ($search_accountancy_code_end == - 1) {
$search_accountancy_code_end = '';
}
+$search_not_reconciled = GETPOST('search_not_reconciled', 'alpha');
+
+// Load variable for pagination
+$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
+$sortfield = GETPOST('sortfield', 'aZ09comma');
+$sortorder = GETPOST('sortorder', 'aZ09comma');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
+if (empty($page) || $page == -1 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha') || (empty($toselect) && $massaction === '0')) {
+ $page = 0;
+} // If $page is not defined, or '' or -1 or if we click on clear filters or if we select empty mass action
+$offset = $limit * $page;
+$pageprev = $page - 1;
+$pagenext = $page + 1;
+if ($sortorder == "") {
+ $sortorder = "ASC";
+}
+if ($sortfield == "") {
+ $sortfield = "t.numero_compte";
+}
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
$object = new BookKeeping($db);
-$hookmanager->initHooks(array('balancelist')); // Note that conf->hooks_modules contains array
+$hookmanager->initHooks(array($contextpage)); // Note that conf->hooks_modules contains array
$formaccounting = new FormAccounting($db);
$formother = new FormOther($db);
@@ -84,6 +94,7 @@ if (empty($search_date_start) && !GETPOSTISSET('formfilteraction')) {
$sql .= " WHERE date_start < '".$db->idate(dol_now())."' AND date_end > '".$db->idate(dol_now())."'";
$sql .= $db->plimit(1);
$res = $db->query($sql);
+
if ($res->num_rows > 0) {
$fiscalYear = $db->fetch_object($res);
$search_date_start = strtotime($fiscalYear->date_start);
@@ -104,45 +115,6 @@ if (empty($search_date_start) && !GETPOSTISSET('formfilteraction')) {
$search_date_end = dol_get_last_day($year_end, $month_end);
}
}
-if ($sortorder == "") {
- $sortorder = "ASC";
-}
-if ($sortfield == "") {
- $sortfield = "t.numero_compte";
-}
-
-
-$param = '';
-if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
- $param .= '&contextpage='.urlencode($contextpage);
-}
-if ($limit > 0 && $limit != $conf->liste_limit) {
- $param .= '&limit='.urlencode($limit);
-}
-
-$filter = array();
-if (!empty($search_date_start)) {
- $filter['t.doc_date>='] = $search_date_start;
- $param .= '&date_startmonth='.GETPOST('date_startmonth', 'int').'&date_startday='.GETPOST('date_startday', 'int').'&date_startyear='.GETPOST('date_startyear', 'int');
-}
-if (!empty($search_date_end)) {
- $filter['t.doc_date<='] = $search_date_end;
- $param .= '&date_endmonth='.GETPOST('date_endmonth', 'int').'&date_endday='.GETPOST('date_endday', 'int').'&date_endyear='.GETPOST('date_endyear', 'int');
-}
-if (!empty($search_accountancy_code_start)) {
- $filter['t.numero_compte>='] = $search_accountancy_code_start;
- $param .= '&search_accountancy_code_start='.urlencode($search_accountancy_code_start);
-}
-if (!empty($search_accountancy_code_end)) {
- $filter['t.numero_compte<='] = $search_accountancy_code_end;
- $param .= '&search_accountancy_code_end='.urlencode($search_accountancy_code_end);
-}
-if (!empty($search_ledger_code)) {
- $filter['t.code_journal'] = $search_ledger_code;
- foreach ($search_ledger_code as $code) {
- $param .= '&search_ledger_code[]='.urlencode($code);
- }
-}
if (!isModEnabled('accounting')) {
accessforbidden();
@@ -154,14 +126,13 @@ if (!$user->hasRight('accounting', 'mouvements', 'lire')) {
accessforbidden();
}
-
-
/*
* Action
*/
-$parameters = array();
-$arrayfields = array();
+$param = '';
+
+$parameters = array('socid'=>$socid);
$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
if ($reshook < 0) {
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
@@ -172,16 +143,67 @@ if (empty($reshook)) {
$show_subgroup = '';
$search_date_start = '';
$search_date_end = '';
+ $search_date_startyear = '';
+ $search_date_startmonth = '';
+ $search_date_startday = '';
+ $search_date_endyear = '';
+ $search_date_endmonth = '';
+ $search_date_endday = '';
$search_accountancy_code_start = '';
$search_accountancy_code_end = '';
+ $search_not_reconciled = '';
$search_ledger_code = array();
$filter = array();
}
-}
-/*
- * View
- */
+ // Must be after the remove filter action, before the export.
+ $filter = array();
+
+ if (!empty($search_date_start)) {
+ $filter['t.doc_date>='] = $search_date_start;
+ $param .= '&date_startmonth=' . GETPOST('date_startmonth', 'int') . '&date_startday=' . GETPOST('date_startday', 'int') . '&date_startyear=' . GETPOST('date_startyear', 'int');
+ }
+ if (!empty($search_date_end)) {
+ $filter['t.doc_date<='] = $search_date_end;
+ $param .= '&date_endmonth=' . GETPOST('date_endmonth', 'int') . '&date_endday=' . GETPOST('date_endday', 'int') . '&date_endyear=' . GETPOST('date_endyear', 'int');
+ }
+ if (!empty($search_doc_date)) {
+ $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 (!empty($search_accountancy_code_start)) {
+ if ($type == 'sub') {
+ $filter['t.subledger_account>='] = $search_accountancy_code_start;
+ } else {
+ $filter['t.numero_compte>='] = $search_accountancy_code_start;
+ }
+ $param .= '&search_accountancy_code_start=' . urlencode($search_accountancy_code_start);
+ }
+ if (!empty($search_accountancy_code_end)) {
+ if ($type == 'sub') {
+ $filter['t.subledger_account<='] = $search_accountancy_code_end;
+ } else {
+ $filter['t.numero_compte<='] = $search_accountancy_code_end;
+ }
+ $param .= '&search_accountancy_code_end=' . urlencode($search_accountancy_code_end);
+ }
+ if (!empty($search_ledger_code)) {
+ $filter['t.code_journal'] = $search_ledger_code;
+ foreach ($search_ledger_code as $code) {
+ $param .= '&search_ledger_code[]=' . urlencode($code);
+ }
+ }
+ if (!empty($search_not_reconciled)) {
+ $filter['t.reconciled_option'] = $search_not_reconciled;
+ $param .= '&search_not_reconciled='.urlencode($search_not_reconciled);
+ }
+
+ // param with type of list
+ $url_param = substr($param, 1); // remove first "&"
+ if (!empty($type)) {
+ $param = '&type=' . $type . $param;
+ }
+}
if ($action == 'export_csv') {
$sep = $conf->global->ACCOUNTING_EXPORT_SEPARATORCSV;
@@ -190,14 +212,23 @@ if ($action == 'export_csv') {
$type_export = 'balance';
include DOL_DOCUMENT_ROOT.'/accountancy/tpl/export_journal.tpl.php';
- $result = $object->fetchAllBalance($sortorder, $sortfield, $limit, 0, $filter);
+ if ($type == 'sub') {
+ $result = $object->fetchAllBalance($sortorder, $sortfield, $limit, 0, $filter, 'AND', 1);
+ } else {
+ $result = $object->fetchAllBalance($sortorder, $sortfield, $limit, 0, $filter);
+ }
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
}
foreach ($object->lines as $line) {
- print '"'.length_accountg($line->numero_compte).'"'.$sep;
- print '"'.$object->get_compte_desc($line->numero_compte).'"'.$sep;
+ if ($type == 'sub') {
+ print '"' . length_accounta($line->subledger_account) . '"' . $sep;
+ print '"' . $line->subledger_label . '"' . $sep;
+ } else {
+ print '"' . length_accountg($line->numero_compte) . '"' . $sep;
+ print '"' . $object->get_compte_desc($line->numero_compte) . '"' . $sep;
+ }
print '"'.price($line->debit).'"'.$sep;
print '"'.price($line->credit).'"'.$sep;
print '"'.price($line->debit - $line->credit).'"'.$sep;
@@ -207,8 +238,15 @@ if ($action == 'export_csv') {
exit;
}
+/*
+ * View
+ */
-$title_page = $langs->trans("AccountBalance");
+if ($type == 'sub') {
+ $title_page = $langs->trans("AccountBalanceSubAccount");
+} else {
+ $title_page = $langs->trans("AccountBalance");
+}
llxHeader('', $title_page);
@@ -217,39 +255,52 @@ if ($action != 'export_csv') {
// List
$nbtotalofrecords = '';
if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
- $nbtotalofrecords = $object->fetchAllBalance($sortorder, $sortfield, 0, 0, $filter);
+ if ($type == 'sub') {
+ $nbtotalofrecords = $object->fetchAllBalance($sortorder, $sortfield, 0, 0, $filter, 'AND', 1);
+ } else {
+ $nbtotalofrecords = $object->fetchAllBalance($sortorder, $sortfield, 0, 0, $filter);
+ }
+
if ($nbtotalofrecords < 0) {
setEventMessages($object->error, $object->errors, 'errors');
}
}
- $result = $object->fetchAllBalance($sortorder, $sortfield, $limit, $offset, $filter);
+ if ($type == 'sub') {
+ $result = $object->fetchAllBalance($sortorder, $sortfield, $limit, $offset, $filter, 'AND', 1);
+ } else {
+ $result = $object->fetchAllBalance($sortorder, $sortfield, $limit, $offset, $filter);
+ }
+
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
}
print '