1<?php 2/* Copyright (C) 2016 Neil Orley <neil.orley@oeris.fr> 3 * Copyright (C) 2013-2016 Olivier Geffroy <jeff@jeffinfo.com> 4 * Copyright (C) 2013-2020 Florian Henry <florian.henry@open-concept.pro> 5 * Copyright (C) 2013-2021 Alexandre Spangaro <aspangaro@open-dsi.fr> 6 * Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 3 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program. If not, see <https://www.gnu.org/licenses/>. 20 */ 21 22/** 23 * \file htdocs/accountancy/bookkeeping/listbyaccount.php 24 * \ingroup Accountancy (Double entries) 25 * \brief List operation of ledger ordered by account number 26 */ 27 28require '../../main.inc.php'; 29 30require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; 31require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php'; 32require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php'; 33require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php'; 34require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; 35require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; 36require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; 37 38// Load translation files required by the page 39$langs->loadLangs(array("accountancy", "compta")); 40 41$action = GETPOST('action', 'aZ09'); 42$search_date_startyear = GETPOST('search_date_startyear', 'int'); 43$search_date_startmonth = GETPOST('search_date_startmonth', 'int'); 44$search_date_startday = GETPOST('search_date_startday', 'int'); 45$search_date_endyear = GETPOST('search_date_endyear', 'int'); 46$search_date_endmonth = GETPOST('search_date_endmonth', 'int'); 47$search_date_endday = GETPOST('search_date_endday', 'int'); 48$search_date_start = dol_mktime(0, 0, 0, $search_date_startmonth, $search_date_startday, $search_date_startyear); 49$search_date_end = dol_mktime(23, 59, 59, $search_date_endmonth, $search_date_endday, $search_date_endyear); 50$search_doc_date = dol_mktime(0, 0, 0, GETPOST('doc_datemonth', 'int'), GETPOST('doc_dateday', 'int'), GETPOST('doc_dateyear', 'int')); 51$search_date_export_startyear = GETPOST('search_date_export_startyear', 'int'); 52$search_date_export_startmonth = GETPOST('search_date_export_startmonth', 'int'); 53$search_date_export_startday = GETPOST('search_date_export_startday', 'int'); 54$search_date_export_endyear = GETPOST('search_date_export_endyear', 'int'); 55$search_date_export_endmonth = GETPOST('search_date_export_endmonth', 'int'); 56$search_date_export_endday = GETPOST('search_date_export_endday', 'int'); 57$search_date_export_start = dol_mktime(0, 0, 0, $search_date_export_startmonth, $search_date_export_startday, $search_date_export_startyear); 58$search_date_export_end = dol_mktime(23, 59, 59, $search_date_export_endmonth, $search_date_export_endday, $search_date_export_endyear); 59$search_date_validation_startyear = GETPOST('search_date_validation_startyear', 'int'); 60$search_date_validation_startmonth = GETPOST('search_date_validation_startmonth', 'int'); 61$search_date_validation_startday = GETPOST('search_date_validation_startday', 'int'); 62$search_date_validation_endyear = GETPOST('search_date_validation_endyear', 'int'); 63$search_date_validation_endmonth = GETPOST('search_date_validation_endmonth', 'int'); 64$search_date_validation_endday = GETPOST('search_date_validation_endday', 'int'); 65$search_date_validation_start = dol_mktime(0, 0, 0, $search_date_validation_startmonth, $search_date_validation_startday, $search_date_validation_startyear); 66$search_date_validation_end = dol_mktime(23, 59, 59, $search_date_validation_endmonth, $search_date_validation_endday, $search_date_validation_endyear); 67 68$search_accountancy_code = GETPOST("search_accountancy_code"); 69$search_accountancy_code_start = GETPOST('search_accountancy_code_start', 'alpha'); 70if ($search_accountancy_code_start == - 1) { 71 $search_accountancy_code_start = ''; 72} 73$search_accountancy_code_end = GETPOST('search_accountancy_code_end', 'alpha'); 74if ($search_accountancy_code_end == - 1) { 75 $search_accountancy_code_end = ''; 76} 77$search_doc_ref = GETPOST('search_doc_ref', 'alpha'); 78$search_label_operation = GETPOST('search_label_operation', 'alpha'); 79$search_mvt_num = GETPOST('search_mvt_num', 'int'); 80$search_direction = GETPOST('search_direction', 'alpha'); 81$search_ledger_code = GETPOST('search_ledger_code', 'array'); 82$search_debit = GETPOST('search_debit', 'alpha'); 83$search_credit = GETPOST('search_credit', 'alpha'); 84$search_lettering_code = GETPOST('search_lettering_code', 'alpha'); 85$search_not_reconciled = GETPOST('search_not_reconciled', 'alpha'); 86 87if (GETPOST("button_delmvt_x") || GETPOST("button_delmvt.x") || GETPOST("button_delmvt")) { 88 $action = 'delbookkeepingyear'; 89} 90 91// Load variable for pagination 92$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : (empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION) ? $conf->liste_limit : $conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION); 93$sortfield = GETPOST('sortfield', 'aZ09comma'); 94$sortorder = GETPOST('sortorder', 'aZ09comma'); 95$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); 96if (empty($page) || $page < 0) { 97 $page = 0; 98} 99$offset = $limit * $page; 100$pageprev = $page - 1; 101$pagenext = $page + 1; 102if ($sortorder == "") { 103 $sortorder = "ASC"; 104} 105if ($sortfield == "") { 106 $sortfield = "t.doc_date,t.rowid"; 107} 108 109// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context 110$object = new BookKeeping($db); 111$formfile = new FormFile($db); 112$hookmanager->initHooks(array('bookkeepingbyaccountlist')); 113 114$formaccounting = new FormAccounting($db); 115$form = new Form($db); 116 117if (empty($search_date_start) && empty($search_date_end) && !GETPOSTISSET('search_date_startday') && !GETPOSTISSET('search_date_startmonth') && !GETPOSTISSET('search_date_starthour')) { 118 $sql = "SELECT date_start, date_end from ".MAIN_DB_PREFIX."accounting_fiscalyear "; 119 $sql .= " where date_start < '".$db->idate(dol_now())."' and date_end > '".$db->idate(dol_now())."'"; 120 $sql .= $db->plimit(1); 121 $res = $db->query($sql); 122 123 if ($res->num_rows > 0) { 124 $fiscalYear = $db->fetch_object($res); 125 $search_date_start = strtotime($fiscalYear->date_start); 126 $search_date_end = strtotime($fiscalYear->date_end); 127 } else { 128 $month_start = ($conf->global->SOCIETE_FISCAL_MONTH_START ? ($conf->global->SOCIETE_FISCAL_MONTH_START) : 1); 129 $year_start = dol_print_date(dol_now(), '%Y'); 130 if (dol_print_date(dol_now(), '%m') < $month_start) { 131 $year_start--; // If current month is lower that starting fiscal month, we start last year 132 } 133 $year_end = $year_start + 1; 134 $month_end = $month_start - 1; 135 if ($month_end < 1) { 136 $month_end = 12; 137 $year_end--; 138 } 139 $search_date_start = dol_mktime(0, 0, 0, $month_start, 1, $year_start); 140 $search_date_end = dol_get_last_day($year_end, $month_end); 141 } 142} 143 144$arrayfields = array( 145 // 't.subledger_account'=>array('label'=>$langs->trans("SubledgerAccount"), 'checked'=>1), 146 't.piece_num'=>array('label'=>$langs->trans("TransactionNumShort"), 'checked'=>1), 147 't.code_journal'=>array('label'=>$langs->trans("Codejournal"), 'checked'=>1), 148 't.doc_date'=>array('label'=>$langs->trans("Docdate"), 'checked'=>1), 149 't.doc_ref'=>array('label'=>$langs->trans("Piece"), 'checked'=>1), 150 't.label_operation'=>array('label'=>$langs->trans("Label"), 'checked'=>1), 151 't.debit'=>array('label'=>$langs->trans("Debit"), 'checked'=>1), 152 't.credit'=>array('label'=>$langs->trans("Credit"), 'checked'=>1), 153 't.lettering_code'=>array('label'=>$langs->trans("LetteringCode"), 'checked'=>1), 154 't.date_export'=>array('label'=>$langs->trans("DateExport"), 'checked'=>1), 155 't.date_validated'=>array('label'=>$langs->trans("DateValidation"), 'checked'=>1), 156); 157 158if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) { 159 unset($arrayfields['t.lettering_code']); 160} 161 162if ($search_date_start && empty($search_date_startyear)) { 163 $tmparray = dol_getdate($search_date_start); 164 $search_date_startyear = $tmparray['year']; 165 $search_date_startmonth = $tmparray['mon']; 166 $search_date_startday = $tmparray['mday']; 167} 168if ($search_date_end && empty($search_date_endyear)) { 169 $tmparray = dol_getdate($search_date_end); 170 $search_date_endyear = $tmparray['year']; 171 $search_date_endmonth = $tmparray['mon']; 172 $search_date_endday = $tmparray['mday']; 173} 174 175if (empty($conf->accounting->enabled)) { 176 accessforbidden(); 177} 178if ($user->socid > 0) { 179 accessforbidden(); 180} 181if (empty($user->rights->accounting->mouvements->lire)) { 182 accessforbidden(); 183} 184 185 186/* 187 * Action 188 */ 189 190if (GETPOST('cancel', 'alpha')) { 191 $action = 'list'; $massaction = ''; 192} 193if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { 194 $massaction = ''; 195} 196 197$parameters = array('socid'=>$socid); 198$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks 199if ($reshook < 0) { 200 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); 201} 202 203if (empty($reshook)) { 204 include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; 205 206 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 207 $search_doc_date = ''; 208 $search_accountancy_code = ''; 209 $search_accountancy_code_start = ''; 210 $search_accountancy_code_end = ''; 211 $search_label_account = ''; 212 $search_doc_ref = ''; 213 $search_label_operation = ''; 214 $search_mvt_num = ''; 215 $search_direction = ''; 216 $search_ledger_code = array(); 217 $search_date_start = ''; 218 $search_date_end = ''; 219 $search_date_startyear = ''; 220 $search_date_startmonth = ''; 221 $search_date_startday = ''; 222 $search_date_endyear = ''; 223 $search_date_endmonth = ''; 224 $search_date_endday = ''; 225 $search_date_export_start = ''; 226 $search_date_export_end = ''; 227 $search_date_export_startyear = ''; 228 $search_date_export_startmonth = ''; 229 $search_date_export_startday = ''; 230 $search_date_export_endyear = ''; 231 $search_date_export_endmonth = ''; 232 $search_date_export_endday = ''; 233 $search_date_validation_start = ''; 234 $search_date_validation_end = ''; 235 $search_date_validation_startyear = ''; 236 $search_date_validation_startmonth = ''; 237 $search_date_validation_startday = ''; 238 $search_date_validation_endyear = ''; 239 $search_date_validation_endmonth = ''; 240 $search_date_validation_endday = ''; 241 $search_debit = ''; 242 $search_credit = ''; 243 $search_lettering_code = ''; 244 $search_not_reconciled = ''; 245 } 246 247 // Must be after the remove filter action, before the export. 248 $param = ''; 249 $filter = array(); 250 251 if (!empty($search_date_start)) { 252 $filter['t.doc_date>='] = $search_date_start; 253 $param .= '&search_date_startmonth='.$search_date_startmonth.'&search_date_startday='.$search_date_startday.'&search_date_startyear='.$search_date_startyear; 254 } 255 if (!empty($search_date_end)) { 256 $filter['t.doc_date<='] = $search_date_end; 257 $param .= '&search_date_endmonth='.$search_date_endmonth.'&search_date_endday='.$search_date_endday.'&search_date_endyear='.$search_date_endyear; 258 } 259 if (!empty($search_doc_date)) { 260 $filter['t.doc_date'] = $search_doc_date; 261 $param .= '&doc_datemonth='.GETPOST('doc_datemonth', 'int').'&doc_dateday='.GETPOST('doc_dateday', 'int').'&doc_dateyear='.GETPOST('doc_dateyear', 'int'); 262 } 263 if (!empty($search_accountancy_code_start)) { 264 $filter['t.numero_compte>='] = $search_accountancy_code_start; 265 $param .= '&search_accountancy_code_start='.urlencode($search_accountancy_code_start); 266 } 267 if (!empty($search_accountancy_code_end)) { 268 $filter['t.numero_compte<='] = $search_accountancy_code_end; 269 $param .= '&search_accountancy_code_end='.urlencode($search_accountancy_code_end); 270 } 271 if (!empty($search_label_account)) { 272 $filter['t.label_compte'] = $search_label_account; 273 $param .= '&search_label_compte='.urlencode($search_label_account); 274 } 275 if (!empty($search_mvt_num)) { 276 $filter['t.piece_num'] = $search_mvt_num; 277 $param .= '&search_mvt_num='.urlencode($search_mvt_num); 278 } 279 if (!empty($search_doc_ref)) { 280 $filter['t.doc_ref'] = $search_doc_ref; 281 $param .= '&search_doc_ref='.urlencode($search_doc_ref); 282 } 283 if (!empty($search_label_operation)) { 284 $filter['t.label_operation'] = $search_label_operation; 285 $param .= '&search_label_operation='.urlencode($search_label_operation); 286 } 287 if (!empty($search_direction)) { 288 $filter['t.sens'] = $search_direction; 289 $param .= '&search_direction='.urlencode($search_direction); 290 } 291 if (!empty($search_ledger_code)) { 292 $filter['t.code_journal'] = $search_ledger_code; 293 foreach ($search_ledger_code as $code) { 294 $param .= '&search_ledger_code[]='.urlencode($code); 295 } 296 } 297 if (!empty($search_debit)) { 298 $filter['t.debit'] = $search_debit; 299 $param .= '&search_debit='.urlencode($search_debit); 300 } 301 if (!empty($search_credit)) { 302 $filter['t.credit'] = $search_credit; 303 $param .= '&search_credit='.urlencode($search_credit); 304 } 305 if (!empty($search_lettering_code)) { 306 $filter['t.lettering_code'] = $search_lettering_code; 307 $param .= '&search_lettering_code='.urlencode($search_lettering_code); 308 } 309 if (!empty($search_not_reconciled)) { 310 $filter['t.reconciled_option'] = $search_not_reconciled; 311 $param .= '&search_not_reconciled='.urlencode($search_not_reconciled); 312 } 313 if (!empty($search_date_export_start)) { 314 $filter['t.date_export>='] = $search_date_export_start; 315 $param .= '&search_date_export_startmonth='.$search_date_export_startmonth.'&search_date_export_startday='.$search_date_export_startday.'&search_date_export_startyear='.$search_date_export_startyear; 316 } 317 if (!empty($search_date_export_end)) { 318 $filter['t.date_export<='] = $search_date_export_end; 319 $param .= '&search_date_export_endmonth='.$search_date_export_endmonth.'&search_date_export_endday='.$search_date_export_endday.'&search_date_export_endyear='.$search_date_export_endyear; 320 } 321 if (!empty($search_date_validation_start)) { 322 $filter['t.date_validated>='] = $search_date_validation_start; 323 $param .= '&search_date_validation_startmonth='.$search_date_validation_startmonth.'&search_date_validation_startday='.$search_date_validation_startday.'&search_date_validation_startyear='.$search_date_validation_startyear; 324 } 325 if (!empty($search_date_validation_end)) { 326 $filter['t.date_validated<='] = $search_date_validation_end; 327 $param .= '&search_date_validation_endmonth='.$search_date_validation_endmonth.'&search_date_validation_endday='.$search_date_validation_endday.'&search_date_validation_endyear='.$search_date_validation_endyear; 328 } 329} 330 331if ($action == 'delbookkeeping' && $user->rights->accounting->mouvements->supprimer) { 332 $import_key = GETPOST('importkey', 'alpha'); 333 334 if (!empty($import_key)) { 335 $result = $object->deleteByImportkey($import_key); 336 if ($result < 0) { 337 setEventMessages($object->error, $object->errors, 'errors'); 338 } 339 340 // Make a redirect to avoid to launch the delete later after a back button 341 header("Location: ".$_SERVER["PHP_SELF"].($param ? '?'.$param : '')); 342 exit; 343 } 344} 345if ($action == 'delbookkeepingyearconfirm' && $user->rights->accounting->mouvements->supprimer_tous) { 346 $delmonth = GETPOST('delmonth', 'int'); 347 $delyear = GETPOST('delyear', 'int'); 348 if ($delyear == -1) { 349 $delyear = 0; 350 } 351 $deljournal = GETPOST('deljournal', 'alpha'); 352 if ($deljournal == -1) { 353 $deljournal = 0; 354 } 355 356 if (!empty($delmonth) || !empty($delyear) || !empty($deljournal)) { 357 $result = $object->deleteByYearAndJournal($delyear, $deljournal, '', ($delmonth > 0 ? $delmonth : 0)); 358 if ($result < 0) { 359 setEventMessages($object->error, $object->errors, 'errors'); 360 } else { 361 setEventMessages("RecordDeleted", null, 'mesgs'); 362 } 363 364 // Make a redirect to avoid to launch the delete later after a back button 365 header("Location: ".$_SERVER["PHP_SELF"].($param ? '?'.$param : '')); 366 exit; 367 } else { 368 setEventMessages("NoRecordDeleted", null, 'warnings'); 369 } 370} 371if ($action == 'delmouvconfirm' && $user->rights->accounting->mouvements->supprimer) { 372 $mvt_num = GETPOST('mvt_num', 'int'); 373 374 if (!empty($mvt_num)) { 375 $result = $object->deleteMvtNum($mvt_num); 376 if ($result < 0) { 377 setEventMessages($object->error, $object->errors, 'errors'); 378 } else { 379 setEventMessages($langs->trans("RecordDeleted"), null, 'mesgs'); 380 } 381 382 header("Location: ".$_SERVER["PHP_SELF"]."?noreset=1".($param ? '&'.$param : '')); 383 exit; 384 } 385} 386 387 388/* 389 * View 390 */ 391 392$formaccounting = new FormAccounting($db); 393$formfile = new FormFile($db); 394$formother = new FormOther($db); 395$form = new Form($db); 396 397$title_page = $langs->trans("Operations").' - '.$langs->trans("VueByAccountAccounting").' ('.$langs->trans("Bookkeeping").')'; 398 399llxHeader('', $title_page); 400 401// List 402$nbtotalofrecords = ''; 403if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { 404 $nbtotalofrecords = $object->fetchAllByAccount($sortorder, $sortfield, 0, 0, $filter); 405 if ($nbtotalofrecords < 0) { 406 setEventMessages($object->error, $object->errors, 'errors'); 407 } 408} 409 410$result = $object->fetchAllByAccount($sortorder, $sortfield, $limit, $offset, $filter); 411 412if ($result < 0) { 413 setEventMessages($object->error, $object->errors, 'errors'); 414} 415 416$num = count($object->lines); 417 418 419if ($action == 'delmouv') { 420 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?mvt_num='.GETPOST('mvt_num'), $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvtPartial'), 'delmouvconfirm', '', 0, 1); 421 print $formconfirm; 422} 423if ($action == 'delbookkeepingyear') { 424 $form_question = array(); 425 $delyear = GETPOST('delyear', 'int'); 426 $deljournal = GETPOST('deljournal', 'alpha'); 427 428 if (empty($delyear)) { 429 $delyear = dol_print_date(dol_now(), '%Y'); 430 } 431 $month_array = array(); 432 for ($i = 1; $i <= 12; $i++) { 433 $month_array[$i] = $langs->trans("Month".sprintf("%02d", $i)); 434 } 435 $year_array = $formaccounting->selectyear_accountancy_bookkepping($delyear, 'delyear', 0, 'array'); 436 $journal_array = $formaccounting->select_journal($deljournal, 'deljournal', '', 1, 1, 1, '', 0, 1); 437 438 $form_question['delmonth'] = array( 439 'name' => 'delmonth', 440 'type' => 'select', 441 'label' => $langs->trans('DelMonth'), 442 'values' => $month_array, 443 'default' => '' 444 ); 445 $form_question['delyear'] = array( 446 'name' => 'delyear', 447 'type' => 'select', 448 'label' => $langs->trans('DelYear'), 449 'values' => $year_array, 450 'default' => $delyear 451 ); 452 $form_question['deljournal'] = array( 453 'name' => 'deljournal', 454 'type' => 'other', // We don't use select here, the journal_array is already a select html component 455 'label' => $langs->trans('DelJournal'), 456 'value' => $journal_array, 457 'default' => $deljournal 458 ); 459 460 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvt', $langs->transnoentitiesnoconv("RegistrationInAccounting")), 'delbookkeepingyearconfirm', $form_question, '', 1, 300); 461 print $formconfirm; 462} 463 464 465print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">'; 466print '<input type="hidden" name="token" value="'.newToken().'">'; 467print '<input type="hidden" name="action" value="list">'; 468if ($optioncss != '') { 469 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">'; 470} 471print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">'; 472print '<input type="hidden" name="sortfield" value="'.$sortfield.'">'; 473print '<input type="hidden" name="sortorder" value="'.$sortorder.'">'; 474 475$parameters = array(); 476$reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook 477if (empty($reshook)) { 478 $newcardbutton = dolGetButtonTitle($langs->trans('ViewFlatList'), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?'.$param); 479 $newcardbutton .= dolGetButtonTitle($langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected')); 480 $newcardbutton .= dolGetButtonTitle($langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbysubaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly')); 481 $newcardbutton .= dolGetButtonTitle($langs->trans('NewAccountingMvt'), '', 'fa fa-plus-circle paddingleft', DOL_URL_ROOT.'/accountancy/bookkeeping/card.php?action=create'); 482} 483 484if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { 485 $param .= '&contextpage='.urlencode($contextpage); 486} 487if ($limit > 0 && $limit != $conf->liste_limit) { 488 $param .= '&limit='.urlencode($limit); 489} 490 491print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $result, $nbtotalofrecords, 'title_accountancy', 0, $newcardbutton, '', $limit, 0, 0, 1); 492 493$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; 494$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields 495if ($massactionbutton) { 496 $selectedfields .= $form->showCheckAddButtons('checkforselect', 1); 497} 498 499// Reverse sort order 500if (preg_match('/^asc/i', $sortorder)) { 501 $sortorder = "asc"; 502} else { 503 $sortorder = "desc"; 504} 505 506$moreforfilter = ''; 507 508// Accountancy account 509$moreforfilter .= '<div class="divsearchfield">'; 510$moreforfilter .= $langs->trans('AccountAccounting').': '; 511$moreforfilter .= '<div class="nowrap inline-block">'; 512$moreforfilter .= $formaccounting->select_account($search_accountancy_code_start, 'search_accountancy_code_start', $langs->trans('From'), array(), 1, 1, 'maxwidth200'); 513$moreforfilter .= ' '; 514$moreforfilter .= $formaccounting->select_account($search_accountancy_code_end, 'search_accountancy_code_end', $langs->trans('to'), array(), 1, 1, 'maxwidth200'); 515$moreforfilter .= '</div>'; 516$moreforfilter .= '</div>'; 517 518$parameters = array(); 519$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook 520if (empty($reshook)) { 521 $moreforfilter .= $hookmanager->resPrint; 522} else { 523 $moreforfilter = $hookmanager->resPrint; 524} 525 526print '<div class="liste_titre liste_titre_bydiv centpercent">'; 527print $moreforfilter; 528print '</div>'; 529 530print '<div class="div-table-responsive">'; 531print '<table class="tagtable liste centpercent">'; 532 533// Filters lines 534print '<tr class="liste_titre_filter">'; 535 536// Movement number 537if (!empty($arrayfields['t.piece_num']['checked'])) { 538 print '<td class="liste_titre"><input type="text" name="search_mvt_num" size="6" value="'.dol_escape_htmltag($search_mvt_num).'"></td>'; 539} 540// Code journal 541if (!empty($arrayfields['t.code_journal']['checked'])) { 542 print '<td class="liste_titre center">'; 543 print $formaccounting->multi_select_journal($search_ledger_code, 'search_ledger_code', 0, 1, 1, 1); 544 print '</td>'; 545} 546// Date document 547if (!empty($arrayfields['t.doc_date']['checked'])) { 548 print '<td class="liste_titre center">'; 549 print '<div class="nowrap">'; 550 print $form->selectDate($search_date_start, 'search_date_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); 551 print '</div>'; 552 print '<div class="nowrap">'; 553 print $form->selectDate($search_date_end, 'search_date_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to")); 554 print '</div>'; 555 print '</td>'; 556} 557// Ref document 558if (!empty($arrayfields['t.doc_ref']['checked'])) { 559 print '<td class="liste_titre"><input type="text" size="7" class="flat" name="search_doc_ref" value="'.dol_escape_htmltag($search_doc_ref).'"/></td>'; 560} 561// Label operation 562if (!empty($arrayfields['t.label_operation']['checked'])) { 563 print '<td class="liste_titre"><input type="text" size="7" class="flat" name="search_label_operation" value="'.dol_escape_htmltag($search_label_operation).'"/></td>'; 564} 565// Debit 566if (!empty($arrayfields['t.debit']['checked'])) { 567 print '<td class="liste_titre right"><input type="text" class="flat" name="search_debit" size="4" value="'.dol_escape_htmltag($search_debit).'"></td>'; 568} 569// Credit 570if (!empty($arrayfields['t.credit']['checked'])) { 571 print '<td class="liste_titre right"><input type="text" class="flat" name="search_credit" size="4" value="'.dol_escape_htmltag($search_credit).'"></td>'; 572} 573// Lettering code 574if (!empty($arrayfields['t.lettering_code']['checked'])) { 575 print '<td class="liste_titre center">'; 576 print '<input type="text" size="3" class="flat" name="search_lettering_code" value="'.$search_lettering_code.'"/>'; 577 print '<br><span class="nowrap"><input type="checkbox" name="search_not_reconciled" value="notreconciled"'.($search_not_reconciled == 'notreconciled' ? ' checked' : '').'>'.$langs->trans("NotReconciled").'</span>'; 578 print '</td>'; 579} 580// Date export 581if (!empty($arrayfields['t.date_export']['checked'])) { 582 print '<td class="liste_titre center">'; 583 print '<div class="nowrap">'; 584 print $form->selectDate($search_date_export_start, 'search_date_export_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); 585 print '</div>'; 586 print '<div class="nowrap">'; 587 print $form->selectDate($search_date_export_end, 'search_date_export_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to")); 588 print '</div>'; 589 print '</td>'; 590} 591// Date validation 592if (!empty($arrayfields['t.date_validated']['checked'])) { 593 print '<td class="liste_titre center">'; 594 print '<div class="nowrap">'; 595 print $form->selectDate($search_date_validation_start, 'search_date_validation_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); 596 print '</div>'; 597 print '<div class="nowrap">'; 598 print $form->selectDate($search_date_validation_end, 'search_date_validation_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to")); 599 print '</div>'; 600 print '</td>'; 601} 602 603// Fields from hook 604$parameters = array('arrayfields'=>$arrayfields); 605$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters); // Note that $action and $object may have been modified by hook 606print $hookmanager->resPrint; 607 608// Action column 609print '<td class="liste_titre center">'; 610$searchpicto = $form->showFilterButtons(); 611print $searchpicto; 612print '</td>'; 613print "</tr>\n"; 614 615print '<tr class="liste_titre">'; 616if (!empty($arrayfields['t.piece_num']['checked'])) { 617 print_liste_field_titre($arrayfields['t.piece_num']['label'], $_SERVER['PHP_SELF'], "t.piece_num", "", $param, '', $sortfield, $sortorder); 618} 619if (!empty($arrayfields['t.code_journal']['checked'])) { 620 print_liste_field_titre($arrayfields['t.code_journal']['label'], $_SERVER['PHP_SELF'], "t.code_journal", "", $param, '', $sortfield, $sortorder, 'center '); 621} 622if (!empty($arrayfields['t.doc_date']['checked'])) { 623 print_liste_field_titre($arrayfields['t.doc_date']['label'], $_SERVER['PHP_SELF'], "t.doc_date", "", $param, '', $sortfield, $sortorder, 'center '); 624} 625if (!empty($arrayfields['t.doc_ref']['checked'])) { 626 print_liste_field_titre($arrayfields['t.doc_ref']['label'], $_SERVER['PHP_SELF'], "t.doc_ref", "", $param, "", $sortfield, $sortorder); 627} 628if (!empty($arrayfields['t.label_operation']['checked'])) { 629 print_liste_field_titre($arrayfields['t.label_operation']['label'], $_SERVER['PHP_SELF'], "t.label_operation", "", $param, "", $sortfield, $sortorder); 630} 631if (!empty($arrayfields['t.debit']['checked'])) { 632 print_liste_field_titre($arrayfields['t.debit']['label'], $_SERVER['PHP_SELF'], "t.debit", "", $param, '', $sortfield, $sortorder, 'right '); 633} 634if (!empty($arrayfields['t.credit']['checked'])) { 635 print_liste_field_titre($arrayfields['t.credit']['label'], $_SERVER['PHP_SELF'], "t.credit", "", $param, '', $sortfield, $sortorder, 'right '); 636} 637if (!empty($arrayfields['t.lettering_code']['checked'])) { 638 print_liste_field_titre($arrayfields['t.lettering_code']['label'], $_SERVER['PHP_SELF'], "t.lettering_code", "", $param, '', $sortfield, $sortorder, 'center '); 639} 640if (!empty($arrayfields['t.date_export']['checked'])) { 641 print_liste_field_titre($arrayfields['t.date_export']['label'], $_SERVER['PHP_SELF'], "t.date_export", "", $param, '', $sortfield, $sortorder, 'center '); 642} 643if (!empty($arrayfields['t.date_validated']['checked'])) { 644 print_liste_field_titre($arrayfields['t.date_validated']['label'], $_SERVER['PHP_SELF'], "t.date_validated", "", $param, '', $sortfield, $sortorder, 'center '); 645} 646// Hook fields 647$parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder); 648$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook 649print $hookmanager->resPrint; 650print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch '); 651print "</tr>\n"; 652 653 654$total_debit = 0; 655$total_credit = 0; 656$sous_total_debit = 0; 657$sous_total_credit = 0; 658$displayed_account_number = null; // Start with undefined to be able to distinguish with empty 659 660// Loop on record 661// -------------------------------------------------------------------- 662$i = 0; 663$totalarray = array(); 664while ($i < min($num, $limit)) { 665 $line = $object->lines[$i]; 666 667 $total_debit += $line->debit; 668 $total_credit += $line->credit; 669 670 $accountg = length_accountg($line->numero_compte); 671 //if (empty($accountg)) $accountg = '-'; 672 673 $colspan = 0; // colspan before field 'label of operation' 674 $colspanend = 3; // colspan after debit/credit 675 if (!empty($arrayfields['t.piece_num']['checked'])) { $colspan++; } 676 if (!empty($arrayfields['t.code_journal']['checked'])) { $colspan++; } 677 if (!empty($arrayfields['t.doc_date']['checked'])) { $colspan++; } 678 if (!empty($arrayfields['t.doc_ref']['checked'])) { $colspan++; } 679 if (!empty($arrayfields['t.label_operation']['checked'])) { $colspan++; } 680 if (!empty($arrayfields['t.date_export']['checked'])) { $colspanend++; } 681 if (!empty($arrayfields['t.date_validating']['checked'])) { $colspanend++; } 682 if (!empty($arrayfields['t.lettering_code']['checked'])) { $colspanend++; } 683 684 // Is it a break ? 685 if ($accountg != $displayed_account_number || !isset($displayed_account_number)) { 686 // Show a subtotal by accounting account 687 if (isset($displayed_account_number)) { 688 print '<tr class="liste_total">'; 689 print '<td class="right" colspan="'.$colspan.'">'.$langs->trans("TotalForAccount").' '.length_accountg($displayed_account_number).':</td>'; 690 print '<td class="nowrap right">'.price($sous_total_debit).'</td>'; 691 print '<td class="nowrap right">'.price($sous_total_credit).'</td>'; 692 print '<td colspan="'.$colspanend.'"></td>'; 693 print '</tr>'; 694 // Show balance of last shown account 695 $balance = $sous_total_debit - $sous_total_credit; 696 print '<tr class="liste_total">'; 697 print '<td class="right" colspan="'.$colspan.'">'.$langs->trans("Balance").':</td>'; 698 if ($balance > 0) { 699 print '<td class="nowraponall right">'; 700 print price($sous_total_debit - $sous_total_credit); 701 print '</td>'; 702 print '<td></td>'; 703 } else { 704 print '<td></td>'; 705 print '<td class="nowraponall right">'; 706 print price($sous_total_credit - $sous_total_debit); 707 print '</td>'; 708 } 709 print '<td colspan="'.$colspanend.'"></td>'; 710 print '</tr>'; 711 } 712 713 // Show the break account 714 print "<tr>"; 715 print '<td colspan="'.($totalarray['nbfield'] ? $totalarray['nbfield'] : 10).'" style="font-weight:bold; border-bottom: 1pt solid black;">'; 716 if ($line->numero_compte != "" && $line->numero_compte != '-1') { 717 print length_accountg($line->numero_compte).' : '.$object->get_compte_desc($line->numero_compte); 718 } else { 719 print '<span class="error">'.$langs->trans("Unknown").'</span>'; 720 } 721 print '</td>'; 722 print '</tr>'; 723 724 $displayed_account_number = $accountg; 725 //if (empty($displayed_account_number)) $displayed_account_number='-'; 726 $sous_total_debit = 0; 727 $sous_total_credit = 0; 728 729 $colspan = 0; 730 } 731 732 print '<tr class="oddeven">'; 733 734 // Piece number 735 if (!empty($arrayfields['t.piece_num']['checked'])) { 736 print '<td>'; 737 $object->id = $line->id; 738 $object->piece_num = $line->piece_num; 739 print $object->getNomUrl(1, '', 0, '', 1); 740 print '</td>'; 741 if (!$i) { 742 $totalarray['nbfield']++; 743 } 744 } 745 746 // Journal code 747 if (!empty($arrayfields['t.code_journal']['checked'])) { 748 $accountingjournal = new AccountingJournal($db); 749 $result = $accountingjournal->fetch('', $line->code_journal); 750 $journaltoshow = (($result > 0) ? $accountingjournal->getNomUrl(0, 0, 0, '', 0) : $line->code_journal); 751 print '<td class="center">'.$journaltoshow.'</td>'; 752 if (!$i) { 753 $totalarray['nbfield']++; 754 } 755 } 756 757 // Document date 758 if (!empty($arrayfields['t.doc_date']['checked'])) { 759 print '<td class="center">'.dol_print_date($line->doc_date, 'day').'</td>'; 760 if (!$i) { 761 $totalarray['nbfield']++; 762 } 763 } 764 765 // Document ref 766 if (!empty($arrayfields['t.doc_ref']['checked'])) { 767 if ($line->doc_type == 'customer_invoice') { 768 $langs->loadLangs(array('bills')); 769 770 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; 771 $objectstatic = new Facture($db); 772 $objectstatic->fetch($line->fk_doc); 773 //$modulepart = 'facture'; 774 775 $filename = dol_sanitizeFileName($line->doc_ref); 776 $filedir = $conf->facture->dir_output.'/'.dol_sanitizeFileName($line->doc_ref); 777 $urlsource = $_SERVER['PHP_SELF'].'?id='.$objectstatic->id; 778 $documentlink = $formfile->getDocumentsLink($objectstatic->element, $filename, $filedir); 779 } elseif ($line->doc_type == 'supplier_invoice') { 780 $langs->loadLangs(array('bills')); 781 782 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; 783 $objectstatic = new FactureFournisseur($db); 784 $objectstatic->fetch($line->fk_doc); 785 //$modulepart = 'invoice_supplier'; 786 787 $filename = dol_sanitizeFileName($line->doc_ref); 788 $filedir = $conf->fournisseur->facture->dir_output.'/'.get_exdir($line->fk_doc, 2, 0, 0, $objectstatic, $modulepart).dol_sanitizeFileName($line->doc_ref); 789 $subdir = get_exdir($objectstatic->id, 2, 0, 0, $objectstatic, $modulepart).dol_sanitizeFileName($line->doc_ref); 790 $documentlink = $formfile->getDocumentsLink($objectstatic->element, $subdir, $filedir); 791 } elseif ($line->doc_type == 'expense_report') { 792 $langs->loadLangs(array('trips')); 793 794 require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; 795 $objectstatic = new ExpenseReport($db); 796 $objectstatic->fetch($line->fk_doc); 797 //$modulepart = 'expensereport'; 798 799 $filename = dol_sanitizeFileName($line->doc_ref); 800 $filedir = $conf->expensereport->dir_output.'/'.dol_sanitizeFileName($line->doc_ref); 801 $urlsource = $_SERVER['PHP_SELF'].'?id='.$objectstatic->id; 802 $documentlink = $formfile->getDocumentsLink($objectstatic->element, $filename, $filedir); 803 } elseif ($line->doc_type == 'bank') { 804 require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; 805 $objectstatic = new AccountLine($db); 806 $objectstatic->fetch($line->fk_doc); 807 } else { 808 // Other type 809 } 810 811 print '<td class="maxwidth400">'; 812 813 print '<table class="nobordernopadding"><tr class="nocellnopadd">'; 814 // Picto + Ref 815 print '<td class="nobordernopadding">'; 816 817 if ($line->doc_type == 'customer_invoice' || $line->doc_type == 'supplier_invoice' || $line->doc_type == 'expense_report') { 818 print $objectstatic->getNomUrl(1, '', 0, 0, '', 0, -1, 1); 819 print $documentlink; 820 } elseif ($line->doc_type == 'bank') { 821 print $objectstatic->getNomUrl(1); 822 $bank_ref = strstr($line->doc_ref, '-'); 823 print " " . $bank_ref; 824 } else { 825 print $line->doc_ref; 826 } 827 print '</td></tr></table>'; 828 829 print "</td>\n"; 830 if (!$i) { 831 $totalarray['nbfield']++; 832 } 833 } 834 835 // Label operation 836 if (!empty($arrayfields['t.label_operation']['checked'])) { 837 // Affiche un lien vers la facture client/fournisseur 838 $doc_ref = preg_replace('/\(.*\)/', '', $line->doc_ref); 839 print strlen(length_accounta($line->subledger_account)) == 0 ? '<td>'.$line->label_operation.'</td>' : '<td>'.$line->label_operation.'<br><span style="font-size:0.8em">('.length_accounta($line->subledger_account).')</span></td>'; 840 if (!$i) { 841 $totalarray['nbfield']++; 842 } 843 } 844 845 // Amount debit 846 if (!empty($arrayfields['t.debit']['checked'])) { 847 print '<td class="right nowraponall amount">'.($line->debit ? price($line->debit) : '').'</td>'; 848 if (!$i) { 849 $totalarray['nbfield']++; 850 } 851 if (!$i) { 852 $totalarray['pos'][$totalarray['nbfield']] = 'totaldebit'; 853 } 854 $totalarray['val']['totaldebit'] += $line->debit; 855 } 856 857 // Amount credit 858 if (!empty($arrayfields['t.credit']['checked'])) { 859 print '<td class="right nowraponall amount">'.($line->credit ? price($line->credit) : '').'</td>'; 860 if (!$i) { 861 $totalarray['nbfield']++; 862 } 863 if (!$i) { 864 $totalarray['pos'][$totalarray['nbfield']] = 'totalcredit'; 865 } 866 $totalarray['val']['totalcredit'] += $line->credit; 867 } 868 869 // Lettering code 870 if (!empty($arrayfields['t.lettering_code']['checked'])) { 871 print '<td class="center">'.$line->lettering_code.'</td>'; 872 if (!$i) { 873 $totalarray['nbfield']++; 874 } 875 } 876 877 // Exported operation date 878 if (!empty($arrayfields['t.date_export']['checked'])) { 879 print '<td class="center">'.dol_print_date($line->date_export, 'dayhour').'</td>'; 880 if (!$i) { 881 $totalarray['nbfield']++; 882 } 883 } 884 885 // Validated operation date 886 if (!empty($arrayfields['t.date_validated']['checked'])) { 887 print '<td class="center">'.dol_print_date($line->date_validation, 'dayhour').'</td>'; 888 if (!$i) { 889 $totalarray['nbfield']++; 890 } 891 } 892 893 // Fields from hook 894 $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj); 895 $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook 896 print $hookmanager->resPrint; 897 898 // Action column 899 print '<td class="nowraponall center">'; 900 if (empty($line->date_export) && empty($line->date_validation)) { 901 if ($user->rights->accounting->mouvements->creer) { 902 print '<a class="editfielda paddingleft marginrightonly" href="' . DOL_URL_ROOT . '/accountancy/bookkeeping/card.php?piece_num=' . $line->piece_num . $param . '&page=' . $page . ($sortfield ? '&sortfield=' . $sortfield : '') . ($sortorder ? '&sortorder=' . $sortorder : '') . '">' . img_edit() . '</a>'; 903 } 904 } 905 if (empty($line->date_validation)) { 906 if ($user->rights->accounting->mouvements->supprimer) { 907 print '<a class="reposition paddingleft marginrightonly" href="'.$_SERVER['PHP_SELF'].'?action=delmouv&mvt_num='.$line->piece_num.$param.'&page='.$page.($sortfield ? '&sortfield='.$sortfield : '').($sortorder ? '&sortorder='.$sortorder : '').'">'.img_delete().'</a>'; 908 } 909 } 910 print '</td>'; 911 if (!$i) { 912 $totalarray['nbfield']++; 913 } 914 915 // Comptabilise le sous-total 916 $sous_total_debit += $line->debit; 917 $sous_total_credit += $line->credit; 918 919 print "</tr>\n"; 920 921 $i++; 922} 923 924if ($num > 0 && $colspan > 0) { 925 print '<tr class="liste_total">'; 926 print '<td class="right" colspan="'.$colspan.'">'.$langs->trans("TotalForAccount").' '.$accountg.':</td>'; 927 print '<td class="nowrap right">'.price($sous_total_debit).'</td>'; 928 print '<td class="nowrap right">'.price($sous_total_credit).'</td>'; 929 print '<td colspan="'.$colspanend.'"></td>'; 930 print '</tr>'; 931 // Show balance of last shown account 932 $balance = $sous_total_debit - $sous_total_credit; 933 print '<tr class="liste_total">'; 934 print '<td class="right" colspan="'.$colspan.'">'.$langs->trans("Balance").':</td>'; 935 if ($balance > 0) { 936 print '<td class="nowraponall right">'; 937 print price($sous_total_debit - $sous_total_credit); 938 print '</td>'; 939 print '<td></td>'; 940 } else { 941 print '<td></td>'; 942 print '<td class="nowraponall right">'; 943 print price($sous_total_credit - $sous_total_debit); 944 print '</td>'; 945 } 946 print '<td colspan="'.$colspanend.'"></td>'; 947 print '</tr>'; 948} 949 950// Show total line 951include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php'; 952 953 954print "</table>"; 955print '</div>'; 956 957// TODO Replace this with mass delete action 958if ($user->rights->accounting->mouvements->supprimer_tous) { 959 print '<div class="tabsAction tabsActionNoBottom">'."\n"; 960 print '<a class="butActionDelete" name="button_delmvt" href="'.$_SERVER["PHP_SELF"].'?action=delbookkeepingyear'.($param ? '&'.$param : '').'">'.$langs->trans("DeleteMvt").'</a>'; 961 print '</div>'; 962} 963 964print '</form>'; 965 966// End of page 967llxFooter(); 968$db->close(); 969