From 86ee75363a0df5f0cfb74f28909237e9d2bb3746 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Wed, 28 Oct 2020 09:49:38 +0100 Subject: [PATCH] NEW: Accountancy - Add a ledger for subaccount --- .../accountancy/bookkeeping/listbyaccount.php | 12 +- .../bookkeeping/listbysubaccount.php | 766 ++++++++++++++++++ .../accountancy/class/bookkeeping.class.php | 11 +- htdocs/langs/en_US/main.lang | 4 +- 4 files changed, 782 insertions(+), 11 deletions(-) create mode 100644 htdocs/accountancy/bookkeeping/listbysubaccount.php diff --git a/htdocs/accountancy/bookkeeping/listbyaccount.php b/htdocs/accountancy/bookkeeping/listbyaccount.php index 4ed055be0b1..5a197b2cc7d 100644 --- a/htdocs/accountancy/bookkeeping/listbyaccount.php +++ b/htdocs/accountancy/bookkeeping/listbyaccount.php @@ -36,7 +36,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; // Load translation files required by the page -$langs->loadLangs(array("accountancy")); +$langs->loadLangs(array("accountancy", "compta")); $action = GETPOST('action', 'aZ09'); $search_date_start = dol_mktime(0, 0, 0, GETPOST('search_date_startmonth', 'int'), GETPOST('search_date_startday', 'int'), GETPOST('search_date_startyear', 'int')); @@ -377,17 +377,13 @@ print ''; print ''; -$newcardbutton .= dolGetButtonTitle($langs->trans('ViewFlatList'), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?'.$param); -$newcardbutton .= dolGetButtonTitle($langs->trans('VueByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?'.$param, '', 1, array('morecss'=>'marginleftonly btnTitleSelected')); - -$newcardbutton .= '   '; - -$newcardbutton .= dolGetButtonTitle($langs->trans('NewAccountingMvt'), '', 'fa fa-plus-circle paddingleft', './card.php?action=create'); +$newcardbutton = dolGetButtonTitle($langs->trans('ViewSubAccountList'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbysubaccount.php', '', 1, array('morecss'=>'marginleftonly btnTitleSelected')); +$newcardbutton .= dolGetButtonTitle($langs->trans('NewAccountingMvt'), '', 'fa fa-plus-circle paddingleft', DOL_URL_ROOT.'/accountancy/bookkeeping/card.php?action=create'); if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param .= '&contextpage='.urlencode($contextpage); if ($limit > 0 && $limit != $conf->liste_limit) $param .= '&limit='.urlencode($limit); -print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $result, $nbtotalofrecords, 'title_accountancy', 0, $viewflat.$newcardbutton, '', $limit, 0, 0, 1); +print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $result, $nbtotalofrecords, 'title_accountancy', 0, $newcardbutton, '', $limit); $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields diff --git a/htdocs/accountancy/bookkeeping/listbysubaccount.php b/htdocs/accountancy/bookkeeping/listbysubaccount.php new file mode 100644 index 00000000000..9f3749690e2 --- /dev/null +++ b/htdocs/accountancy/bookkeeping/listbysubaccount.php @@ -0,0 +1,766 @@ + + * Copyright (C) 2013-2016 Olivier Geffroy + * Copyright (C) 2013-2016 Florian Henry + * Copyright (C) 2013-2020 Alexandre Spangaro + * Copyright (C) 2018 Frédéric France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/accountancy/bookkeeping/listbysubaccount.php + * \ingroup Accountancy (Double entries) + * \brief List operation of ledger ordered by subaccount number + */ + +require '../../main.inc.php'; + +require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php'; +require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array("accountancy", "compta")); + +$action = GETPOST('action', 'aZ09'); +$search_date_start = dol_mktime(0, 0, 0, GETPOST('search_date_startmonth', 'int'), GETPOST('search_date_startday', 'int'), GETPOST('search_date_startyear', 'int')); +$search_date_end = dol_mktime(0, 0, 0, GETPOST('search_date_endmonth', 'int'), GETPOST('search_date_endday', 'int'), GETPOST('search_date_endyear', 'int')); +$search_doc_date = dol_mktime(0, 0, 0, GETPOST('doc_datemonth', 'int'), GETPOST('doc_dateday', 'int'), GETPOST('doc_dateyear', 'int')); + +$search_accountancy_code = GETPOST("search_accountancy_code"); +$search_accountancy_code_start = GETPOST('search_accountancy_code_start', 'alpha'); +if ($search_accountancy_code_start == - 1) { + $search_accountancy_code_start = ''; +} +$search_accountancy_code_end = GETPOST('search_accountancy_code_end', 'alpha'); +if ($search_accountancy_code_end == - 1) { + $search_accountancy_code_end = ''; +} +$search_doc_ref = GETPOST('search_doc_ref', 'alpha'); +$search_label_operation = GETPOST('search_label_operation', 'alpha'); +$search_mvt_num = GETPOST('search_mvt_num', 'int'); +$search_direction = GETPOST('search_direction', 'alpha'); +$search_ledger_code = GETPOST('search_ledger_code', 'alpha'); +$search_debit = GETPOST('search_debit', 'alpha'); +$search_credit = GETPOST('search_credit', 'alpha'); +$search_lettering_code = GETPOST('search_lettering_code', 'alpha'); +$search_not_reconciled = GETPOST('search_reconciled_option', 'alpha'); + +if (GETPOST("button_delmvt_x") || GETPOST("button_delmvt.x") || GETPOST("button_delmvt")) { + $action = 'delbookkeepingyear'; +} + +// Load variable for pagination +$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : (empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION) ? $conf->liste_limit : $conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION); +$sortfield = GETPOST('sortfield', 'aZ09comma'); +$sortorder = GETPOST('sortorder', 'aZ09comma'); +$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); +if (empty($page) || $page < 0) { $page = 0; } +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +if ($sortorder == "") $sortorder = "ASC"; +if ($sortfield == "") $sortfield = "t.doc_date,t.rowid"; + +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$object = new BookKeeping($db); +$formfile = new FormFile($db); +$hookmanager->initHooks(array('bookkeepingbysubaccountlist')); + +$formaccounting = new FormAccounting($db); +$form = new Form($db); + +if (empty($search_date_start) && empty($search_date_end) && !GETPOSTISSET('search_date_startday') && !GETPOSTISSET('search_date_startmonth') && !GETPOSTISSET('search_date_starthour')) { + $sql = "SELECT date_start, date_end from ".MAIN_DB_PREFIX."accounting_fiscalyear "; + $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); + $search_date_end = strtotime($fiscalYear->date_end); + } else { + $month_start = ($conf->global->SOCIETE_FISCAL_MONTH_START ? ($conf->global->SOCIETE_FISCAL_MONTH_START) : 1); + $year_start = dol_print_date(dol_now(), '%Y'); + if (dol_print_date(dol_now(), '%m') < $month_start) $year_start--; // If current month is lower that starting fiscal month, we start last year + $year_end = $year_start + 1; + $month_end = $month_start - 1; + if ($month_end < 1) + { + $month_end = 12; + $year_end--; + } + $search_date_start = dol_mktime(0, 0, 0, $month_start, 1, $year_start); + $search_date_end = dol_get_last_day($year_end, $month_end); + } +} + +$arrayfields = array( + // 't.subledger_account'=>array('label'=>$langs->trans("SubledgerAccount"), 'checked'=>1), + 't.code_journal'=>array('label'=>$langs->trans("Codejournal"), 'checked'=>1), + 't.piece_num'=>array('label'=>$langs->trans("TransactionNumShort"), 'checked'=>1), + 't.doc_date'=>array('label'=>$langs->trans("Docdate"), 'checked'=>1), + 't.doc_ref'=>array('label'=>$langs->trans("Piece"), 'checked'=>1), + 't.label_operation'=>array('label'=>$langs->trans("Label"), 'checked'=>1), + 't.debit'=>array('label'=>$langs->trans("Debit"), 'checked'=>1), + 't.credit'=>array('label'=>$langs->trans("Credit"), 'checked'=>1), + 't.lettering_code'=>array('label'=>$langs->trans("LetteringCode"), 'checked'=>1), +); + +if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) unset($arrayfields['t.lettering_code']); + +/* + * Action + */ +if (GETPOST('cancel', 'alpha')) { $action = 'list'; $massaction = ''; } +if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction = ''; } + +$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'); + +if (empty($reshook)) +{ + include DOL_DOCUMENT_ROOT . '/core/actions_changeselectedfields.inc.php'; + + 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_accountancy_code_start = ''; + $search_accountancy_code_end = ''; + $search_label_account = ''; + $search_doc_ref = ''; + $search_label_operation = ''; + $search_mvt_num = ''; + $search_direction = ''; + $search_ledger_code = ''; + $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_debit = ''; + $search_credit = ''; + $search_lettering_code = ''; + $search_not_reconciled = ''; + } + + // Must be after the remove filter action, before the export. + $param = ''; + $filter = array(); + + if (!empty($search_date_start)) { + $filter['t.doc_date>='] = $search_date_start; + $param .= '&search_date_startmonth=' . GETPOST('search_date_startmonth', 'int') . '&search_date_startday=' . GETPOST('search_date_startday', 'int') . '&search_date_startyear=' . GETPOST('search_date_startyear', 'int'); + } + if (!empty($search_date_end)) { + $filter['t.doc_date<='] = $search_date_end; + $param .= '&search_date_endmonth=' . GETPOST('search_date_endmonth', 'int') . '&search_date_endday=' . GETPOST('search_date_endday', 'int') . '&search_date_endyear=' . GETPOST('search_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)) { + $filter['t.subledger_account>='] = $search_accountancy_code_start; + $param .= '&search_accountancy_code_start=' . urlencode($search_accountancy_code_start); + } + if (!empty($search_accountancy_code_end)) { + $filter['t.subledger_account<='] = $search_accountancy_code_end; + $param .= '&search_accountancy_code_end=' . urlencode($search_accountancy_code_end); + } + if (!empty($search_label_account)) { + $filter['t.label_compte'] = $search_label_account; + $param .= '&search_label_compte=' . urlencode($search_label_account); + } + if (!empty($search_mvt_num)) { + $filter['t.piece_num'] = $search_mvt_num; + $param .= '&search_mvt_num=' . urlencode($search_mvt_num); + } + if (!empty($search_doc_ref)) { + $filter['t.doc_ref'] = $search_doc_ref; + $param .= '&search_doc_ref=' . urlencode($search_doc_ref); + } + if (!empty($search_label_operation)) { + $filter['t.label_operation'] = $search_label_operation; + $param .= '&search_label_operation=' . urlencode($search_label_operation); + } + if (!empty($search_direction)) { + $filter['t.sens'] = $search_direction; + $param .= '&search_direction=' . urlencode($search_direction); + } + if (!empty($search_ledger_code)) { + $filter['t.code_journal'] = $search_ledger_code; + $param .= '&search_ledger_code=' . urlencode($search_ledger_code); + } + if (!empty($search_debit)) { + $filter['t.debit'] = $search_debit; + $param .= '&search_debit=' . urlencode($search_debit); + } + if (!empty($search_credit)) { + $filter['t.credit'] = $search_credit; + $param .= '&search_credit=' . urlencode($search_credit); + } + if (!empty($search_lettering_code)) { + $filter['t.lettering_code'] = $search_lettering_code; + $param .= '&search_lettering_code='.urlencode($search_lettering_code); + } + if (!empty($search_not_reconciled)) { + $filter['t.reconciled_option'] = $search_not_reconciled; + $param .= '&search_not_reconciled='.urlencode($search_not_reconciled); + } +} + +if ($action == 'delbookkeeping' && $user->rights->accounting->mouvements->supprimer) { + $import_key = GETPOST('importkey', 'alpha'); + + if (!empty($import_key)) { + $result = $object->deleteByImportkey($import_key); + if ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); + } + + // Make a redirect to avoid to launch the delete later after a back button + header("Location: listbyaccount.php".($param ? '?'.$param : '')); + exit; + } +} +if ($action == 'delbookkeepingyearconfirm' && $user->rights->accounting->mouvements->supprimer_tous) { + $delmonth = GETPOST('delmonth', 'int'); + $delyear = GETPOST('delyear', 'int'); + if ($delyear == -1) { + $delyear = 0; + } + $deljournal = GETPOST('deljournal', 'alpha'); + if ($deljournal == -1) { + $deljournal = 0; + } + + if (!empty($delmonth) || !empty($delyear) || !empty($deljournal)) + { + $result = $object->deleteByYearAndJournal($delyear, $deljournal, '', ($delmonth > 0 ? $delmonth : 0)); + if ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); + } else { + setEventMessages("RecordDeleted", null, 'mesgs'); + } + + // Make a redirect to avoid to launch the delete later after a back button + header("Location: listbysubaccount.php".($param ? '?'.$param : '')); + exit; + } else { + setEventMessages("NoRecordDeleted", null, 'warnings'); + } +} +if ($action == 'delmouvconfirm' && $user->rights->accounting->mouvements->supprimer) { + $mvt_num = GETPOST('mvt_num', 'int'); + + if (!empty($mvt_num)) { + $result = $object->deleteMvtNum($mvt_num); + if ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); + } else { + setEventMessages($langs->trans("RecordDeleted"), null, 'mesgs'); + } + + header("Location: listbysubaccount.php?noreset=1".($param ? '&'.$param : '')); + exit; + } +} + + +/* + * View + */ + +$formaccounting = new FormAccounting($db); +$formfile = new FormFile($db); +$formother = new FormOther($db); +$form = new Form($db); + +$title_page = $langs->trans("Operations").' - '.$langs->trans("VueByAccountAccounting").' ('.$langs->trans("BookkeepingSubAccount").')'; + +llxHeader('', $title_page); + + +// List +$nbtotalofrecords = ''; +if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { + $nbtotalofrecords = $object->fetchAllByAccount($sortorder, $sortfield, 0, 0, $filter, 'AND', 1); + if ($nbtotalofrecords < 0) { + setEventMessages($object->error, $object->errors, 'errors'); + } +} + +$result = $object->fetchAllByAccount($sortorder, $sortfield, $limit, $offset, $filter, 'AND', 1); + +if ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); +} + +$num = count($object->lines); + + +if ($action == 'delmouv') { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?mvt_num='.GETPOST('mvt_num'), $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvtPartial'), 'delmouvconfirm', '', 0, 1); + print $formconfirm; +} +if ($action == 'delbookkeepingyear') { + $form_question = array(); + $delyear = GETPOST('delyear', 'int'); + $deljournal = GETPOST('deljournal', 'alpha'); + + if (empty($delyear)) { + $delyear = dol_print_date(dol_now(), '%Y'); + } + $month_array = array(); + for ($i = 1; $i <= 12; $i++) { + $month_array[$i] = $langs->trans("Month".sprintf("%02d", $i)); + } + $year_array = $formaccounting->selectyear_accountancy_bookkepping($delyear, 'delyear', 0, 'array'); + $journal_array = $formaccounting->select_journal($deljournal, 'deljournal', '', 1, 1, 1, '', 0, 1); + + $form_question['delmonth'] = array( + 'name' => 'delmonth', + 'type' => 'select', + 'label' => $langs->trans('DelMonth'), + 'values' => $month_array, + 'default' => '' + ); + $form_question['delyear'] = array( + 'name' => 'delyear', + 'type' => 'select', + 'label' => $langs->trans('DelYear'), + 'values' => $year_array, + 'default' => $delyear + ); + $form_question['deljournal'] = array( + 'name' => 'deljournal', + 'type' => 'other', // We don't use select here, the journal_array is already a select html component + 'label' => $langs->trans('DelJournal'), + 'value' => $journal_array, + 'default' => $deljournal + ); + + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvt', $langs->transnoentitiesnoconv("RegistrationInAccounting")), 'delbookkeepingyearconfirm', $form_question, '', 1, 300); + print $formconfirm; +} + + +print '
'; +print ''; +print ''; +if ($optioncss != '') print ''; +print ''; +print ''; +print ''; + + +$newcardbutton = dolGetButtonTitle($langs->trans('ViewAccountList'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php', '', 1, array('morecss'=>'marginleftonly btnTitleSelected')); +$newcardbutton .= dolGetButtonTitle($langs->trans('NewAccountingMvt'), '', 'fa fa-plus-circle paddingleft', DOL_URL_ROOT.'/accountancy/bookkeeping/card.php?action=create'); + +if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param .= '&contextpage='.urlencode($contextpage); +if ($limit > 0 && $limit != $conf->liste_limit) $param .= '&limit='.urlencode($limit); + +print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $result, $nbtotalofrecords, 'title_accountancy', 0, $newcardbutton, '', $limit); + +$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; +$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields +if ($massactionbutton) $selectedfields .= $form->showCheckAddButtons('checkforselect', 1); + +// Reverse sort order +if (preg_match('/^asc/i', $sortorder)) $sortorder = "asc"; +else $sortorder = "desc"; + +$moreforfilter = ''; + +// Accountancy account +$moreforfilter .= '
'; +$moreforfilter .= $langs->trans('AccountAccounting').': '; +$moreforfilter .= '
'; +$moreforfilter .= $langs->trans('From').' '; +$moreforfilter .= $formaccounting->select_auxaccount($search_accountancy_code_start, 'search_accountancy_code_start', 1, array(), 1, 1, 'maxwidth200'); +$moreforfilter .= ' '.$langs->trans('to').' '; +$moreforfilter .= $formaccounting->select_auxaccount($search_accountancy_code_end, 'search_accountancy_code_end', 1, array(), 1, 1, 'maxwidth200'); +$moreforfilter .= '
'; +$moreforfilter .= '
'; + +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook +if (empty($reshook)) $moreforfilter .= $hookmanager->resPrint; +else $moreforfilter = $hookmanager->resPrint; + +print '
'; +print $moreforfilter; +print '
'; + +print '
'; +print ''; + +// Filters lines +print ''; + +// Code journal +if (!empty($arrayfields['t.code_journal']['checked'])) { + print ''; +} +// Date document +if (!empty($arrayfields['t.doc_date']['checked'])) { + print ''; +} +// Movement number +if (!empty($arrayfields['t.piece_num']['checked'])) +{ + print ''; +} +// Ref document +if (!empty($arrayfields['t.doc_ref']['checked'])) { + print ''; +} +// Label operation +if (!empty($arrayfields['t.label_operation']['checked'])) { + print ''; +} +// Debit +if (!empty($arrayfields['t.debit']['checked'])) { + print ''; +} +// Credit +if (!empty($arrayfields['t.credit']['checked'])) { + print ''; +} +// Lettering code +if (!empty($arrayfields['t.lettering_code']['checked'])) +{ + print ''; +} + +// Fields from hook +$parameters = array('arrayfields'=>$arrayfields); +$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; + +// Action column +print ''; +print "\n"; + +print ''; +if (!empty($arrayfields['t.code_journal']['checked'])) print_liste_field_titre($arrayfields['t.code_journal']['label'], $_SERVER['PHP_SELF'], "t.code_journal", "", $param, '', $sortfield, $sortorder, 'center '); +if (!empty($arrayfields['t.doc_date']['checked'])) print_liste_field_titre($arrayfields['t.doc_date']['label'], $_SERVER['PHP_SELF'], "t.doc_date", "", $param, '', $sortfield, $sortorder, 'center '); +if (!empty($arrayfields['t.piece_num']['checked'])) print_liste_field_titre($arrayfields['t.piece_num']['label'], $_SERVER['PHP_SELF'], "t.piece_num", "", $param, '', $sortfield, $sortorder); +if (!empty($arrayfields['t.doc_ref']['checked'])) print_liste_field_titre($arrayfields['t.doc_ref']['label'], $_SERVER['PHP_SELF'], "t.doc_ref", "", $param, "", $sortfield, $sortorder); +if (!empty($arrayfields['t.label_operation']['checked'])) print_liste_field_titre($arrayfields['t.label_operation']['label'], $_SERVER['PHP_SELF'], "t.label_operation", "", $param, "", $sortfield, $sortorder); +if (!empty($arrayfields['t.debit']['checked'])) print_liste_field_titre($arrayfields['t.debit']['label'], $_SERVER['PHP_SELF'], "t.debit", "", $param, '', $sortfield, $sortorder, 'right '); +if (!empty($arrayfields['t.credit']['checked'])) print_liste_field_titre($arrayfields['t.credit']['label'], $_SERVER['PHP_SELF'], "t.credit", "", $param, '', $sortfield, $sortorder, 'right '); +if (!empty($arrayfields['t.lettering_code']['checked'])) print_liste_field_titre($arrayfields['t.lettering_code']['label'], $_SERVER['PHP_SELF'], "t.lettering_code", "", $param, '', $sortfield, $sortorder, 'center '); +// Hook fields +$parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder); +$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch '); +print "\n"; + + +$total_debit = 0; +$total_credit = 0; +$sous_total_debit = 0; +$sous_total_credit = 0; +$displayed_account_number = null; // Start with undefined to be able to distinguish with empty + +// Loop on record +// -------------------------------------------------------------------- +$i = 0; +$totalarray = array(); +while ($i < min($num, $limit)) +{ + $line = $object->lines[$i]; + + $total_debit += $line->debit; + $total_credit += $line->credit; + + $accountg = length_accounta($line->subledger_account); + //if (empty($accountg)) $accountg = '-'; + + // Is it a break ? + if ($accountg != $displayed_account_number || !isset($displayed_account_number)) { + $colspan = $totalarray['nbfield'] - 3; + $colspanend = $totalarray['nbfield'] - 7; + // Show a subtotal by accounting account + if (isset($displayed_account_number)) { + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + // Show balance of last shown account + $balance = $sous_total_debit - $sous_total_credit; + print ''; + print ''; + if ($balance > 0 ) + { + print ''; + print ''; + } else { + print ''; + print ''; + } + print ''; + print ''; + } + + // Show the break account + print ""; + print ''; + print ''; + + $displayed_account_number = $accountg; + //if (empty($displayed_account_number)) $displayed_account_number='-'; + $sous_total_debit = 0; + $sous_total_credit = 0; + + $colspan = 0; + } + + print ''; + + // Journal code + if (!empty($arrayfields['t.code_journal']['checked'])) + { + $accountingjournal = new AccountingJournal($db); + $result = $accountingjournal->fetch('', $line->code_journal); + $journaltoshow = (($result > 0) ? $accountingjournal->getNomUrl(0, 0, 0, '', 0) : $line->code_journal); + print ''; + if (!$i) $totalarray['nbfield']++; + } + + // Document date + if (!empty($arrayfields['t.doc_date']['checked'])) + { + print ''; + if (!$i) $totalarray['nbfield']++; + } + + // Piece number + if (!empty($arrayfields['t.piece_num']['checked'])) + { + print ''; + if (!$i) $totalarray['nbfield']++; + } + + // Document ref + if (!empty($arrayfields['t.doc_ref']['checked'])) + { + if ($line->doc_type == 'customer_invoice') + { + $langs->loadLangs(array('bills')); + + require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; + $objectstatic = new Facture($db); + $objectstatic->fetch($line->fk_doc); + //$modulepart = 'facture'; + + $filename = dol_sanitizeFileName($line->doc_ref); + $filedir = $conf->facture->dir_output.'/'.dol_sanitizeFileName($line->doc_ref); + $urlsource = $_SERVER['PHP_SELF'].'?id='.$objectstatic->id; + $documentlink = $formfile->getDocumentsLink($objectstatic->element, $filename, $filedir); + } elseif ($line->doc_type == 'supplier_invoice') + { + $langs->loadLangs(array('bills')); + + require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; + $objectstatic = new FactureFournisseur($db); + $objectstatic->fetch($line->fk_doc); + //$modulepart = 'invoice_supplier'; + + $filename = dol_sanitizeFileName($line->doc_ref); + $filedir = $conf->fournisseur->facture->dir_output.'/'.get_exdir($line->fk_doc, 2, 0, 0, $objectstatic, $modulepart).dol_sanitizeFileName($line->doc_ref); + $subdir = get_exdir($objectstatic->id, 2, 0, 0, $objectstatic, $modulepart).dol_sanitizeFileName($line->doc_ref); + $documentlink = $formfile->getDocumentsLink($objectstatic->element, $subdir, $filedir); + } elseif ($line->doc_type == 'expense_report') + { + $langs->loadLangs(array('trips')); + + require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; + $objectstatic = new ExpenseReport($db); + $objectstatic->fetch($line->fk_doc); + //$modulepart = 'expensereport'; + + $filename = dol_sanitizeFileName($line->doc_ref); + $filedir = $conf->expensereport->dir_output.'/'.dol_sanitizeFileName($line->doc_ref); + $urlsource = $_SERVER['PHP_SELF'].'?id='.$objectstatic->id; + $documentlink = $formfile->getDocumentsLink($objectstatic->element, $filename, $filedir); + } else { + // Other type + } + + print '\n"; + if (!$i) $totalarray['nbfield']++; + } + + // Label operation + if (!empty($arrayfields['t.label_operation']['checked'])) { + // Affiche un lien vers la facture client/fournisseur + $doc_ref = preg_replace('/\(.*\)/', '', $line->doc_ref); + print strlen(length_accounta($line->subledger_account)) == 0 ? '' : ''; + if (!$i) $totalarray['nbfield']++; + } + + // Amount debit + if (!empty($arrayfields['t.debit']['checked'])) + { + print ''; + if (!$i) $totalarray['nbfield']++; + if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 'totaldebit'; + $totalarray['val']['totaldebit'] += $line->debit; + } + + // Amount credit + if (!empty($arrayfields['t.credit']['checked'])) { + print ''; + if (!$i) $totalarray['nbfield']++; + if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 'totalcredit'; + $totalarray['val']['totalcredit'] += $line->credit; + } + + // Lettering code + if (!empty($arrayfields['t.lettering_code']['checked'])) + { + print ''; + if (!$i) $totalarray['nbfield']++; + } + + // Fields from hook + $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + + // Action column + print ''; + if (!$i) $totalarray['nbfield']++; + + // Comptabilise le sous-total + $sous_total_debit += $line->debit; + $sous_total_credit += $line->credit; + + print "\n"; + + $i++; +} + +// Show sub-total of last shown account +$colspan = $totalarray['nbfield'] - 3; +$colspanend = $totalarray['nbfield'] - 8; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +// Show balance of last shown account +$balance = $sous_total_debit - $sous_total_credit; +print ''; +print ''; +if ($balance > 0 ) +{ + print ''; + print ''; +} else { + print ''; + print ''; +} +print ''; +print ''; + +// Show total line +include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php'; + + +print "
'; + print '
'; + print $form->selectDate($search_date_start, 'search_date_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); + print '
'; + print '
'; + print $form->selectDate($search_date_end, 'search_date_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to")); + print '
'; + print '
'; + print ''; + print '
'.$langs->trans("NotReconciled").''; + print '
'; +$searchpicto = $form->showFilterButtons(); +print $searchpicto; +print '
'.$langs->trans("TotalForAccount").' '.length_accounta($displayed_account_number).':'.price($sous_total_debit).''.price($sous_total_credit).'
'.$langs->trans("Balance").':'; + print price($sous_total_debit - $sous_total_credit); + print ''; + print price($sous_total_credit - $sous_total_debit); + print '
'; + if ($line->subledger_account != "" && $line->subledger_account != '-1') print length_accounta($line->subledger_account).' : '.$object->get_compte_desc($line->numero_compte); + else print ''.$langs->trans("Unknown").''; + print '
'.$journaltoshow.''.dol_print_date($line->doc_date, 'day').''; + $object->id = $line->id; + $object->piece_num = $line->piece_num; + print $object->getNomUrl(1, '', 0, '', 1); + print ''; + + print ''; + // Picto + Ref + print '
'; + + if ($line->doc_type == 'customer_invoice' || $line->doc_type == 'supplier_invoice' || $line->doc_type == 'expense_report') + { + print $objectstatic->getNomUrl(1, '', 0, 0, '', 0, -1, 1); + print $documentlink; + } else { + print $line->doc_ref; + } + print '
'; + + print "
' . $line->label_operation . '' . $line->label_operation . '
(' . length_accounta($line->subledger_account) . ')
'.($line->debit ? price($line->debit) : '').'' . ($line->credit ? price($line->credit) : '') . ''.$line->lettering_code.''; + if (empty($line->date_export)) { + if ($user->rights->accounting->mouvements->creer) { + print ''.img_edit().''; + } + if ($user->rights->accounting->mouvements->supprimer) { + print '   '.img_delete().''; + } + } + print '
'.$langs->trans("TotalForAccount").' '.$accountg.':'.price($sous_total_debit).''.price($sous_total_credit).'
'.$langs->trans("Balance").':'; + print price($sous_total_debit - $sous_total_credit); + print ''; + print price($sous_total_credit - $sous_total_debit); + print '
"; +print '
'; + +// TODO Replace this with mass delete action +if ($user->rights->accounting->mouvements->supprimer_tous) { + print '
'."\n"; + print ''.$langs->trans("DeleteMvt").''; + print '
'; +} + +print '
'; + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php index f5f4bf80221..3dcf2784676 100644 --- a/htdocs/accountancy/class/bookkeeping.class.php +++ b/htdocs/accountancy/class/bookkeeping.class.php @@ -768,10 +768,11 @@ class BookKeeping extends CommonObject * @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 */ - public function fetchAllByAccount($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND') + public function fetchAllByAccount($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND', $option = 0) { global $conf; @@ -836,7 +837,13 @@ class BookKeeping extends CommonObject $sql .= ' AND '.implode(' '.$filtermode.' ', $sqlwhere); } // Affichage par compte comptable - $sql .= ' ORDER BY t.numero_compte ASC'; + if (!empty($option)) { + $sql .= ' AND t.subledger_account IS NOT NULL'; + $sql .= ' ORDER BY t.subledger_account ASC'; + } else { + $sql .= ' ORDER BY t.numero_compte ASC'; + } + if (!empty($sortfield)) { $sql .= ', '.$sortfield.' '.$sortorder; } diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 1096b9857f1..2068a37af2b 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -884,6 +884,8 @@ Miscellaneous=Miscellaneous Calendar=Calendar GroupBy=Group by... ViewFlatList=View flat list +ViewAccountList=View ledger +ViewSubAccountList=View subaccount ledger RemoveString=Remove string '%s' SomeTranslationAreUncomplete=Some of the languages offered may be only partially translated or may contain errors. Please help to correct your language by registering at https://transifex.com/projects/p/dolibarr/ to add your improvements. DirectDownloadLink=Direct download link (public/external) @@ -1099,4 +1101,4 @@ DateOfBirth=Date of birth SecurityTokenHasExpiredSoActionHasBeenCanceledPleaseRetry=Security token has expired, so action has been canceled. Please try again. UpToDate=Up-to-date OutOfDate=Out-of-date -EventReminder=Event Reminder \ No newline at end of file +EventReminder=Event Reminder