dolibarr 19.0.3
expensereportsjournal.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2007-2010 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2007-2010 Jean Heimburger <jean@tiaris.info>
4 * Copyright (C) 2011 Juanjo Menent <jmenent@2byte.es>
5 * Copyright (C) 2012 Regis Houssin <regis.houssin@inodbox.com>
6 * Copyright (C) 2013-2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
7 * Copyright (C) 2013-2016 Olivier Geffroy <jeff@jeffinfo.com>
8 * Copyright (C) 2013-2016 Florian Henry <florian.henry@open-concept.pro>
9 * Copyright (C) 2018 Frédéric France <frederic.france@free.fr>
10 * Copyright (C) 2018 Eric Seigne <eric.seigne@cap-rel.fr>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 3 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <https://www.gnu.org/licenses/>.
24 */
25
31require '../../main.inc.php';
32require_once DOL_DOCUMENT_ROOT.'/core/lib/report.lib.php';
33require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
34require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
35require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
36require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
37require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
38require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
39require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php';
40
41// Load translation files required by the page
42$langs->loadLangs(array("commercial", "compta", "bills", "other", "accountancy", "trips", "errors"));
43
44$id_journal = GETPOST('id_journal', 'int');
45$action = GETPOST('action', 'aZ09');
46
47$date_startmonth = GETPOST('date_startmonth');
48$date_startday = GETPOST('date_startday');
49$date_startyear = GETPOST('date_startyear');
50$date_endmonth = GETPOST('date_endmonth');
51$date_endday = GETPOST('date_endday');
52$date_endyear = GETPOST('date_endyear');
53$in_bookkeeping = GETPOST('in_bookkeeping');
54if ($in_bookkeeping == '') {
55 $in_bookkeeping = 'notyet';
56}
57
58$now = dol_now();
59
60$hookmanager->initHooks(array('expensereportsjournal'));
61$parameters = array();
62
63// Security check
64if (!isModEnabled('accounting')) {
66}
67if ($user->socid > 0) {
69}
70if (!$user->hasRight('accounting', 'mouvements', 'lire')) {
72}
73
74$error = 0;
75$errorforinvoice = array();
76
77
78/*
79 * Actions
80 */
81
82$accountingaccount = new AccountingAccount($db);
83
84// Get informations of journal
85$accountingjournalstatic = new AccountingJournal($db);
86$accountingjournalstatic->fetch($id_journal);
87$journal = $accountingjournalstatic->code;
88$journal_label = $accountingjournalstatic->label;
89
90$date_start = dol_mktime(0, 0, 0, $date_startmonth, $date_startday, $date_startyear);
91$date_end = dol_mktime(23, 59, 59, $date_endmonth, $date_endday, $date_endyear);
92
93if (empty($date_startmonth)) {
94 // Period by default on transfer
96 $date_start = $dates['date_start'];
97 $pastmonthyear = $dates['pastmonthyear'];
98 $pastmonth = $dates['pastmonth'];
99}
100if (empty($date_endmonth)) {
101 // Period by default on transfer
103 $date_end = $dates['date_end'];
104 $pastmonthyear = $dates['pastmonthyear'];
105 $pastmonth = $dates['pastmonth'];
106}
107
108if (!GETPOSTISSET('date_startmonth') && (empty($date_start) || empty($date_end))) { // We define date_start and date_end, only if we did not submit the form
109 $date_start = dol_get_first_day($pastmonthyear, $pastmonth, false);
110 $date_end = dol_get_last_day($pastmonthyear, $pastmonth, false);
111}
112
113$sql = "SELECT er.rowid, er.ref, er.date_debut as de,";
114$sql .= " erd.rowid as erdid, erd.comments, erd.total_ht, erd.total_tva, erd.total_localtax1, erd.total_localtax2, erd.tva_tx, erd.total_ttc, erd.fk_code_ventilation, erd.vat_src_code, ";
115$sql .= " u.rowid as uid, u.firstname, u.lastname, u.accountancy_code as user_accountancy_account,";
116$sql .= " f.accountancy_code, aa.rowid as fk_compte, aa.account_number as compte, aa.label as label_compte";
117$parameters = array();
118$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook
119$sql .= $hookmanager->resPrint;
120$sql .= " FROM ".MAIN_DB_PREFIX."expensereport_det as erd";
121$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_type_fees as f ON f.id = erd.fk_c_type_fees";
122$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa ON aa.rowid = erd.fk_code_ventilation";
123$sql .= " JOIN ".MAIN_DB_PREFIX."expensereport as er ON er.rowid = erd.fk_expensereport";
124$sql .= " JOIN ".MAIN_DB_PREFIX."user as u ON u.rowid = er.fk_user_author";
125$parameters = array();
126$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters); // Note that $action and $object may have been modified by hook
127$sql .= $hookmanager->resPrint;
128$sql .= " WHERE er.fk_statut > 0";
129$sql .= " AND erd.fk_code_ventilation > 0";
130$sql .= " AND er.entity IN (".getEntity('expensereport', 0).")"; // We don't share object for accountancy
131if ($date_start && $date_end) {
132 $sql .= " AND er.date_debut >= '".$db->idate($date_start)."' AND er.date_debut <= '".$db->idate($date_end)."'";
133}
134// Define begin binding date
135if (getDolGlobalString('ACCOUNTING_DATE_START_BINDING')) {
136 $sql .= " AND er.date_debut >= '".$db->idate(getDolGlobalString('ACCOUNTING_DATE_START_BINDING'))."'";
137}
138// Already in bookkeeping or not
139if ($in_bookkeeping == 'already') {
140 $sql .= " AND er.rowid IN (SELECT fk_doc FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as ab WHERE ab.doc_type='expense_report')";
141}
142if ($in_bookkeeping == 'notyet') {
143 $sql .= " AND er.rowid NOT IN (SELECT fk_doc FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as ab WHERE ab.doc_type='expense_report')";
144}
145$parameters = array();
146$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook
147$sql .= $hookmanager->resPrint;
148$sql .= " ORDER BY er.date_debut";
149
150dol_syslog('accountancy/journal/expensereportsjournal.php', LOG_DEBUG);
151$result = $db->query($sql);
152if ($result) {
153 $taber = array();
154 $tabht = array();
155 $tabtva = array();
156 $def_tva = array();
157 $tabttc = array();
158 $tablocaltax1 = array();
159 $tablocaltax2 = array();
160 $tabuser = array();
161
162 $num = $db->num_rows($result);
163
164 // Variables
165 $account_salary = getDolGlobalString('SALARIES_ACCOUNTING_ACCOUNT_PAYMENT', 'NotDefined');
166 $account_vat = getDolGlobalString('ACCOUNTING_VAT_BUY_ACCOUNT', 'NotDefined');
167
168 $i = 0;
169 while ($i < $num) {
170 $obj = $db->fetch_object($result);
171
172 // Controls
173 $compta_user = (!empty($obj->user_accountancy_account)) ? $obj->user_accountancy_account : $account_salary;
174 $compta_fees = $obj->compte;
175
176 $vatdata = getTaxesFromId($obj->tva_tx.($obj->vat_src_code ? ' ('.$obj->vat_src_code.')' : ''), $mysoc, $mysoc, 0);
177 $compta_tva = (!empty($vatdata['accountancy_code_buy']) ? $vatdata['accountancy_code_buy'] : $account_vat);
178 $compta_localtax1 = (!empty($vatdata['accountancy_code_buy']) ? $vatdata['accountancy_code_buy'] : $account_vat);
179 $compta_localtax2 = (!empty($vatdata['accountancy_code_buy']) ? $vatdata['accountancy_code_buy'] : $account_vat);
180
181 // Define array to display all VAT rates that use this accounting account $compta_tva
182 if (price2num($obj->tva_tx) || !empty($obj->vat_src_code)) {
183 $def_tva[$obj->rowid][$compta_tva][vatrate($obj->tva_tx).($obj->vat_src_code ? ' ('.$obj->vat_src_code.')' : '')] = (vatrate($obj->tva_tx).($obj->vat_src_code ? ' ('.$obj->vat_src_code.')' : ''));
184 }
185
186 $taber[$obj->rowid]["date"] = $db->jdate($obj->de);
187 $taber[$obj->rowid]["ref"] = $obj->ref;
188 $taber[$obj->rowid]["comments"] = $obj->comments;
189 $taber[$obj->rowid]["fk_expensereportdet"] = $obj->erdid;
190
191 // Avoid warnings
192 if (!isset($tabttc[$obj->rowid][$compta_user])) {
193 $tabttc[$obj->rowid][$compta_user] = 0;
194 }
195 if (!isset($tabht[$obj->rowid][$compta_fees])) {
196 $tabht[$obj->rowid][$compta_fees] = 0;
197 }
198 if (!isset($tabtva[$obj->rowid][$compta_tva])) {
199 $tabtva[$obj->rowid][$compta_tva] = 0;
200 }
201 if (!isset($tablocaltax1[$obj->rowid][$compta_localtax1])) {
202 $tablocaltax1[$obj->rowid][$compta_localtax1] = 0;
203 }
204 if (!isset($tablocaltax2[$obj->rowid][$compta_localtax2])) {
205 $tablocaltax2[$obj->rowid][$compta_localtax2] = 0;
206 }
207
208 $tabttc[$obj->rowid][$compta_user] += $obj->total_ttc;
209 $tabht[$obj->rowid][$compta_fees] += $obj->total_ht;
210 $tabtva[$obj->rowid][$compta_tva] += $obj->total_tva;
211 $tablocaltax1[$obj->rowid][$compta_localtax1] += $obj->total_localtax1;
212 $tablocaltax2[$obj->rowid][$compta_localtax2] += $obj->total_localtax2;
213 $tabuser[$obj->rowid] = array(
214 'id' => $obj->uid,
215 'name' => dolGetFirstLastname($obj->firstname, $obj->lastname),
216 'user_accountancy_code' => $obj->user_accountancy_account
217 );
218
219 $i++;
220 }
221} else {
222 dol_print_error($db);
223}
224
225// Load all unbound lines
226$sql = "SELECT fk_expensereport, COUNT(erd.rowid) as nb";
227$sql .= " FROM ".MAIN_DB_PREFIX."expensereport_det as erd";
228$sql .= " WHERE erd.fk_code_ventilation <= 0";
229$sql .= " AND erd.total_ttc <> 0";
230$sql .= " AND fk_expensereport IN (".$db->sanitize(join(",", array_keys($taber))).")";
231$sql .= " GROUP BY fk_expensereport";
232$resql = $db->query($sql);
233
234$num = $db->num_rows($resql);
235$i = 0;
236while ($i < $num) {
237 $obj = $db->fetch_object($resql);
238 if ($obj->nb > 0) {
239 $errorforinvoice[$obj->fk_expensereport] = 'somelinesarenotbound';
240 }
241 $i++;
242}
243
244// Bookkeeping Write
245if ($action == 'writebookkeeping' && !$error) {
246 $now = dol_now();
247 $error = 0;
248
249 $accountingaccountexpense = new AccountingAccount($db);
250 $accountingaccountexpense->fetch(null, getDolGlobalString('SALARIES_ACCOUNTING_ACCOUNT_PAYMENT'), true);
251
252 foreach ($taber as $key => $val) { // Loop on each expense report
253 $errorforline = 0;
254
255 $totalcredit = 0;
256 $totaldebit = 0;
257
258 $db->begin();
259
260 // Error if some lines are not binded/ready to be journalized
261 if (!empty($errorforinvoice[$key]) && $errorforinvoice[$key] == 'somelinesarenotbound') {
262 $error++;
263 $errorforline++;
264 setEventMessages($langs->trans('ErrorInvoiceContainsLinesNotYetBounded', $val['ref']), null, 'errors');
265 }
266
267 // Thirdparty
268 if (!$errorforline) {
269 foreach ($tabttc[$key] as $k => $mt) {
270 if ($mt) {
271 $bookkeeping = new BookKeeping($db);
272 $bookkeeping->doc_date = $val["date"];
273 $bookkeeping->doc_ref = $val["ref"];
274 $bookkeeping->date_creation = $now;
275 $bookkeeping->doc_type = 'expense_report';
276 $bookkeeping->fk_doc = $key;
277 $bookkeeping->fk_docdet = $val["fk_expensereportdet"];
278
279 $bookkeeping->subledger_account = $tabuser[$key]['user_accountancy_code'];
280 $bookkeeping->subledger_label = $tabuser[$key]['name'];
281
282 $bookkeeping->numero_compte = getDolGlobalString('SALARIES_ACCOUNTING_ACCOUNT_PAYMENT');
283 $bookkeeping->label_compte = $accountingaccountexpense->label;
284
285 $bookkeeping->label_operation = $tabuser[$key]['name'];
286 $bookkeeping->montant = $mt;
287 $bookkeeping->sens = ($mt >= 0) ? 'C' : 'D';
288 $bookkeeping->debit = ($mt <= 0) ? -$mt : 0;
289 $bookkeeping->credit = ($mt > 0) ? $mt : 0;
290 $bookkeeping->code_journal = $journal;
291 $bookkeeping->journal_label = $langs->transnoentities($journal_label);
292 $bookkeeping->fk_user_author = $user->id;
293 $bookkeeping->entity = $conf->entity;
294
295 $totaldebit += $bookkeeping->debit;
296 $totalcredit += $bookkeeping->credit;
297
298 $result = $bookkeeping->create($user);
299 if ($result < 0) {
300 if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
301 $error++;
302 $errorforline++;
303 $errorforinvoice[$key] = 'alreadyjournalized';
304 //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
305 } else {
306 $error++;
307 $errorforline++;
308 $errorforinvoice[$key] = 'other';
309 setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
310 }
311 }
312 }
313 }
314 }
315
316 // Fees
317 if (!$errorforline) {
318 foreach ($tabht[$key] as $k => $mt) {
319 if ($mt) {
320 // get compte id and label
321 if ($accountingaccount->fetch(null, $k, true)) {
322 $bookkeeping = new BookKeeping($db);
323 $bookkeeping->doc_date = $val["date"];
324 $bookkeeping->doc_ref = $val["ref"];
325 $bookkeeping->date_creation = $now;
326 $bookkeeping->doc_type = 'expense_report';
327 $bookkeeping->fk_doc = $key;
328 $bookkeeping->fk_docdet = $val["fk_expensereportdet"];
329
330 $bookkeeping->subledger_account = '';
331 $bookkeeping->subledger_label = '';
332
333 $bookkeeping->numero_compte = $k;
334 $bookkeeping->label_compte = $accountingaccount->label;
335
336 $bookkeeping->label_operation = $accountingaccount->label;
337 $bookkeeping->montant = $mt;
338 $bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
339 $bookkeeping->debit = ($mt > 0) ? $mt : 0;
340 $bookkeeping->credit = ($mt <= 0) ? -$mt : 0;
341 $bookkeeping->code_journal = $journal;
342 $bookkeeping->journal_label = $langs->transnoentities($journal_label);
343 $bookkeeping->fk_user_author = $user->id;
344 $bookkeeping->entity = $conf->entity;
345
346 $totaldebit += $bookkeeping->debit;
347 $totalcredit += $bookkeeping->credit;
348
349 $result = $bookkeeping->create($user);
350 if ($result < 0) {
351 if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
352 $error++;
353 $errorforline++;
354 $errorforinvoice[$key] = 'alreadyjournalized';
355 //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
356 } else {
357 $error++;
358 $errorforline++;
359 $errorforinvoice[$key] = 'other';
360 setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
361 }
362 }
363 }
364 }
365 }
366 }
367
368 // VAT
369 if (!$errorforline) {
370 $listoftax = array(0, 1, 2);
371 foreach ($listoftax as $numtax) {
372 $arrayofvat = $tabtva;
373 if ($numtax == 1) {
374 $arrayofvat = $tablocaltax1;
375 }
376 if ($numtax == 2) {
377 $arrayofvat = $tablocaltax2;
378 }
379
380 foreach ($arrayofvat[$key] as $k => $mt) {
381 if ($mt) {
382 $accountingaccount->fetch(null, $k, true); // TODO Use a cache for label
383 $account_label = $accountingaccount->label;
384
385 // get compte id and label
386 $bookkeeping = new BookKeeping($db);
387 $bookkeeping->doc_date = $val["date"];
388 $bookkeeping->doc_ref = $val["ref"];
389 $bookkeeping->date_creation = $now;
390 $bookkeeping->doc_type = 'expense_report';
391 $bookkeeping->fk_doc = $key;
392 $bookkeeping->fk_docdet = $val["fk_expensereportdet"];
393
394 $bookkeeping->subledger_account = '';
395 $bookkeeping->subledger_label = '';
396
397 $bookkeeping->numero_compte = $k;
398 $bookkeeping->label_compte = $account_label;
399
400 $bookkeeping->label_operation = $langs->trans("VAT").' '.join(', ', $def_tva[$key][$k]).' %';
401 $bookkeeping->montant = $mt;
402 $bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
403 $bookkeeping->debit = ($mt > 0) ? $mt : 0;
404 $bookkeeping->credit = ($mt <= 0) ? -$mt : 0;
405 $bookkeeping->code_journal = $journal;
406 $bookkeeping->journal_label = $langs->transnoentities($journal_label);
407 $bookkeeping->fk_user_author = $user->id;
408 $bookkeeping->entity = $conf->entity;
409
410 $totaldebit += $bookkeeping->debit;
411 $totalcredit += $bookkeeping->credit;
412
413 $result = $bookkeeping->create($user);
414 if ($result < 0) {
415 if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
416 $error++;
417 $errorforline++;
418 $errorforinvoice[$key] = 'alreadyjournalized';
419 //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
420 } else {
421 $error++;
422 $errorforline++;
423 $errorforinvoice[$key] = 'other';
424 setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
425 }
426 }
427 }
428 }
429 }
430 }
431
432 // Protection against a bug on lines before
433 if (!$errorforline && (price2num($totaldebit, 'MT') != price2num($totalcredit, 'MT'))) {
434 $error++;
435 $errorforline++;
436 $errorforinvoice[$key] = 'amountsnotbalanced';
437 setEventMessages('We tried to insert a non balanced transaction in book for '.$val["ref"].'. Canceled. Surely a bug.', null, 'errors');
438 }
439
440 if (!$errorforline) {
441 $db->commit();
442 } else {
443 $db->rollback();
444
445 if ($error >= 10) {
446 setEventMessages($langs->trans("ErrorTooManyErrorsProcessStopped"), null, 'errors');
447 break; // Break in the foreach
448 }
449 }
450 }
451
452 $tabpay = $taber;
453
454 if (empty($error) && count($tabpay) > 0) {
455 setEventMessages($langs->trans("GeneralLedgerIsWritten"), null, 'mesgs');
456 } elseif (count($tabpay) == $error) {
457 setEventMessages($langs->trans("NoNewRecordSaved"), null, 'warnings');
458 } else {
459 setEventMessages($langs->trans("GeneralLedgerSomeRecordWasNotRecorded"), null, 'warnings');
460 }
461
462 $action = '';
463
464 // Must reload data, so we make a redirect
465 if (count($tabpay) != $error) {
466 $param = 'id_journal='.$id_journal;
467 $param .= '&date_startday='.$date_startday;
468 $param .= '&date_startmonth='.$date_startmonth;
469 $param .= '&date_startyear='.$date_startyear;
470 $param .= '&date_endday='.$date_endday;
471 $param .= '&date_endmonth='.$date_endmonth;
472 $param .= '&date_endyear='.$date_endyear;
473 $param .= '&in_bookkeeping='.$in_bookkeeping;
474
475 header("Location: ".$_SERVER['PHP_SELF'].($param ? '?'.$param : ''));
476 exit;
477 }
478}
479
480
481/*
482 * View
483 */
484
485$form = new Form($db);
486
487$userstatic = new User($db);
488
489// Export
490if ($action == 'exportcsv' && !$error) { // ISO and not UTF8 !
491 $sep = $conf->global->ACCOUNTING_EXPORT_SEPARATORCSV;
492
493 $filename = 'journal';
494 $type_export = 'journal';
495 include DOL_DOCUMENT_ROOT.'/accountancy/tpl/export_journal.tpl.php';
496
497 // CSV header line
498 print '"'.$langs->transnoentitiesnoconv("Date").'"'.$sep;
499 print '"'.$langs->transnoentitiesnoconv("Piece").'"'.$sep;
500 print '"'.$langs->transnoentitiesnoconv("AccountAccounting").'"'.$sep;
501 print '"'.$langs->transnoentitiesnoconv("LabelOperation").'"'.$sep;
502 print '"'.$langs->transnoentitiesnoconv("AccountingDebit").'"'.$sep;
503 print '"'.$langs->transnoentitiesnoconv("AccountingCredit").'"'.$sep;
504 print "\n";
505
506 foreach ($taber as $key => $val) {
507 $date = dol_print_date($val["date"], 'day');
508
509 $userstatic->id = $tabuser[$key]['id'];
510 $userstatic->name = $tabuser[$key]['name'];
511
512 // Fees
513 foreach ($tabht[$key] as $k => $mt) {
514 $accountingaccount = new AccountingAccount($db);
515 $accountingaccount->fetch(null, $k, true);
516 if ($mt) {
517 print '"'.$date.'"'.$sep;
518 print '"'.$val["ref"].'"'.$sep;
519 print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
520 print '"'.dol_trunc($accountingaccount->label, 32).'"'.$sep;
521 print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
522 print '"'.($mt < 0 ? price(-$mt) : '').'"';
523 print "\n";
524 }
525 }
526
527 // VAT
528 foreach ($tabtva[$key] as $k => $mt) {
529 if ($mt) {
530 print '"'.$date.'"'.$sep;
531 print '"'.$val["ref"].'"'.$sep;
532 print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
533 print '"'.dol_trunc($langs->trans("VAT")).'"'.$sep;
534 print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
535 print '"'.($mt < 0 ? price(-$mt) : '').'"';
536 print "\n";
537 }
538 }
539
540 // Third party
541 foreach ($tabttc[$key] as $k => $mt) {
542 print '"'.$date.'"'.$sep;
543 print '"'.$val["ref"].'"'.$sep;
544 print '"'.length_accounta(html_entity_decode($k)).'"'.$sep;
545 print '"'.dol_trunc($userstatic->name).'"'.$sep;
546 print '"'.($mt < 0 ? price(-$mt) : '').'"'.$sep;
547 print '"'.($mt >= 0 ? price($mt) : '').'"';
548 }
549 print "\n";
550 }
551}
552
553if (empty($action) || $action == 'view') {
554 $title = $langs->trans("GenerationOfAccountingEntries").' - '.$accountingjournalstatic->getNomUrl(0, 2, 1, '', 1);
555
556 llxHeader('', dol_string_nohtmltag($title));
557
558 $nom = $title;
559 $nomlink = '';
560 $periodlink = '';
561 $exportlink = '';
562 $builddate = dol_now();
563 $description = $langs->trans("DescJournalOnlyBindedVisible").'<br>';
564
565 $listofchoices = array('notyet'=>$langs->trans("NotYetInGeneralLedger"), 'already'=>$langs->trans("AlreadyInGeneralLedger"));
566 $period = $form->selectDate($date_start ? $date_start : -1, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end ? $date_end : -1, 'date_end', 0, 0, 0, '', 1, 0);
567 $period .= ' - '.$langs->trans("JournalizationInLedgerStatus").' '.$form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1);
568
569 $varlink = 'id_journal='.$id_journal;
570
571 journalHead($nom, $nomlink, $period, $periodlink, $description, $builddate, $exportlink, array('action' => ''), '', $varlink);
572
573 if (getDolGlobalString('ACCOUNTANCY_FISCAL_PERIOD_MODE') != 'blockedonclosed') {
574 // Test that setup is complete (we are in accounting, so test on entity is always on $conf->entity only, no sharing allowed)
575 // Fiscal period test
576 $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."accounting_fiscalyear WHERE entity = ".((int) $conf->entity);
577 $resql = $db->query($sql);
578 if ($resql) {
579 $obj = $db->fetch_object($resql);
580 if ($obj->nb == 0) {
581 print '<br><div class="warning">'.img_warning().' '.$langs->trans("TheFiscalPeriodIsNotDefined");
582 $desc = ' : '.$langs->trans("AccountancyAreaDescFiscalPeriod", 4, '{link}');
583 $desc = str_replace('{link}', '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("FiscalPeriod").'</strong>', $desc);
584 print $desc;
585 print '</div>';
586 }
587 } else {
588 dol_print_error($db);
589 }
590 }
591
592 // Button to write into Ledger
593 if (!getDolGlobalString('SALARIES_ACCOUNTING_ACCOUNT_PAYMENT') || getDolGlobalString('SALARIES_ACCOUNTING_ACCOUNT_PAYMENT') == '-1') {
594 print '<br><div class="warning">'.img_warning().' '.$langs->trans("SomeMandatoryStepsOfSetupWereNotDone");
595 $desc = ' : '.$langs->trans("AccountancyAreaDescMisc", 4, '{link}');
596 $desc = str_replace('{link}', '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</strong>', $desc);
597 print $desc;
598 print '</div>';
599 }
600 print '<br><div class="tabsAction tabsActionNoBottom centerimp">';
601
602 if (getDolGlobalString('ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL') && $in_bookkeeping == 'notyet') {
603 print '<input type="button" class="butAction" name="exportcsv" value="'.$langs->trans("ExportDraftJournal").'" onclick="launch_export();" />';
604 }
605 if (!getDolGlobalString('SALARIES_ACCOUNTING_ACCOUNT_PAYMENT') || getDolGlobalString('SALARIES_ACCOUNTING_ACCOUNT_PAYMENT') == '-1') {
606 print '<input type="button" class="butActionRefused classfortooltip" title="'.dol_escape_htmltag($langs->trans("SomeMandatoryStepsOfSetupWereNotDone")).'" value="'.$langs->trans("WriteBookKeeping").'" />';
607 } else {
608 if ($in_bookkeeping == 'notyet') {
609 print '<input type="button" class="butAction" name="writebookkeeping" value="'.$langs->trans("WriteBookKeeping").'" onclick="writebookkeeping();" />';
610 } else {
611 print '<a href="#" class="butActionRefused classfortooltip" name="writebookkeeping">'.$langs->trans("WriteBookKeeping").'</a>';
612 }
613 }
614 print '</div>';
615
616 // TODO Avoid using js. We can use a direct link with $param
617 print '
618 <script type="text/javascript">
619 function launch_export() {
620 $("div.fiche form input[name=\"action\"]").val("exportcsv");
621 $("div.fiche form input[type=\"submit\"]").click();
622 $("div.fiche form input[name=\"action\"]").val("");
623 }
624 function writebookkeeping() {
625 console.log("click on writebookkeeping");
626 $("div.fiche form input[name=\"action\"]").val("writebookkeeping");
627 $("div.fiche form input[type=\"submit\"]").click();
628 $("div.fiche form input[name=\"action\"]").val("");
629 }
630 </script>';
631
632 /*
633 * Show result array
634 */
635 print '<br>';
636
637 $i = 0;
638 print '<div class="div-table-responsive">';
639 print "<table class=\"noborder\" width=\"100%\">";
640 print "<tr class=\"liste_titre\">";
641 print "<td>".$langs->trans("Date")."</td>";
642 print "<td>".$langs->trans("Piece").' ('.$langs->trans("ExpenseReportRef").")</td>";
643 print "<td>".$langs->trans("AccountAccounting")."</td>";
644 print "<td>".$langs->trans("SubledgerAccount")."</td>";
645 print "<td>".$langs->trans("LabelOperation")."</td>";
646 print '<td class="right">'.$langs->trans("AccountingDebit")."</td>";
647 print '<td class="right">'.$langs->trans("AccountingCredit")."</td>";
648 print "</tr>\n";
649
650 $i = 0;
651
652 $expensereportstatic = new ExpenseReport($db);
653 $expensereportlinestatic = new ExpenseReportLine($db);
654
655 foreach ($taber as $key => $val) {
656 $expensereportstatic->id = $key;
657 $expensereportstatic->ref = $val["ref"];
658 $expensereportlinestatic->comments = html_entity_decode(dol_trunc($val["comments"], 32));
659
660 $date = dol_print_date($val["date"], 'day');
661
662 if ($errorforinvoice[$key] == 'somelinesarenotbound') {
663 print '<tr class="oddeven">';
664 print "<!-- Some lines are not bound -->";
665 print "<td>".$date."</td>";
666 print "<td>".$expensereportstatic->getNomUrl(1)."</td>";
667 // Account
668 print "<td>";
669 print '<span class="error">'.$langs->trans('ErrorInvoiceContainsLinesNotYetBoundedShort', $val['ref']).'</span>';
670 print '</td>';
671 // Subledger account
672 print "<td>";
673 print '</td>';
674 print "<td>";
675 print "</td>";
676 print '<td class="right"></td>';
677 print '<td class="right"></td>';
678 print "</tr>";
679
680 $i++;
681 }
682
683 // Fees
684 foreach ($tabht[$key] as $k => $mt) {
685 $accountingaccount = new AccountingAccount($db);
686 $accountingaccount->fetch(null, $k, true);
687
688 if ($mt) {
689 print '<tr class="oddeven">';
690 print "<!-- Fees -->";
691 print "<td>".$date."</td>";
692 print "<td>".$expensereportstatic->getNomUrl(1)."</td>";
693 $userstatic->id = $tabuser[$key]['id'];
694 $userstatic->name = $tabuser[$key]['name'];
695 // Account
696 print "<td>";
697 $accountoshow = length_accountg($k);
698 if (($accountoshow == "") || $accountoshow == 'NotDefined') {
699 print '<span class="error">'.$langs->trans("FeeAccountNotDefined").'</span>';
700 } else {
701 print $accountoshow;
702 }
703 print '</td>';
704 // Subledger account
705 print "<td>";
706 print '</td>';
707 $userstatic->id = $tabuser[$key]['id'];
708 $userstatic->name = $tabuser[$key]['name'];
709 print "<td>".$userstatic->getNomUrl(0, 'user', 16).' - '.$accountingaccount->label."</td>";
710 print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
711 print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
712 print "</tr>";
713
714 $i++;
715 }
716 }
717
718 // Third party
719 foreach ($tabttc[$key] as $k => $mt) {
720 $userstatic->id = $tabuser[$key]['id'];
721 $userstatic->name = $tabuser[$key]['name'];
722
723 print '<tr class="oddeven">';
724 print "<!-- Thirdparty -->";
725 print "<td>".$date."</td>";
726 print "<td>".$expensereportstatic->getNomUrl(1)."</td>";
727 // Account
728 print "<td>";
729 $accountoshow = length_accountg(getDolGlobalString('SALARIES_ACCOUNTING_ACCOUNT_PAYMENT'));
730 if (($accountoshow == "") || $accountoshow == 'NotDefined') {
731 print '<span class="error">'.$langs->trans("MainAccountForUsersNotDefined").'</span>';
732 } else {
733 print $accountoshow;
734 }
735 print "</td>";
736 // Subledger account
737 print "<td>";
738 $accountoshow = length_accounta($k);
739 if (($accountoshow == "") || $accountoshow == 'NotDefined') {
740 print '<span class="error">'.$langs->trans("UserAccountNotDefined").'</span>';
741 } else {
742 print $accountoshow;
743 }
744 print '</td>';
745 print "<td>".$userstatic->getNomUrl(0, 'user', 16).' - '.$langs->trans("SubledgerAccount")."</td>";
746 print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
747 print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
748 print "</tr>";
749
750 $i++;
751 }
752
753 // VAT
754 $listoftax = array(0, 1, 2);
755 foreach ($listoftax as $numtax) {
756 $arrayofvat = $tabtva;
757 if ($numtax == 1) {
758 $arrayofvat = $tablocaltax1;
759 }
760 if ($numtax == 2) {
761 $arrayofvat = $tablocaltax2;
762 }
763
764 foreach ($arrayofvat[$key] as $k => $mt) {
765 if ($mt) {
766 print '<tr class="oddeven">';
767 print "<!-- VAT -->";
768 print "<td>".$date."</td>";
769 print "<td>".$expensereportstatic->getNomUrl(1)."</td>";
770 // Account
771 print "<td>";
772 $accountoshow = length_accountg($k);
773 if (($accountoshow == "") || $accountoshow == 'NotDefined') {
774 print '<span class="error">'.$langs->trans("VATAccountNotDefined").'</span>';
775 } else {
776 print $accountoshow;
777 }
778 print "</td>";
779 // Subledger account
780 print "<td>";
781 print '</td>';
782 print "<td>".$userstatic->getNomUrl(0, 'user', 16).' - '.$langs->trans("VAT").' '.join(', ', $def_tva[$key][$k]).' %'.($numtax ? ' - Localtax '.$numtax : '');
783 print "</td>";
784 print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
785 print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
786 print "</tr>";
787
788 $i++;
789 }
790 }
791 }
792 }
793
794 if (!$i) {
795 $colspan = 7;
796 print '<tr class="oddeven"><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
797 }
798
799 print "</table>";
800 print '</div>';
801
802 // End of page
803 llxFooter();
804}
805$db->close();
length_accountg($account)
Return General accounting account with defined length (used for product and miscellaneous)
getDefaultDatesForTransfer()
Return Default dates for transfer based on periodicity option in accountancy setup.
journalHead($nom, $variante, $period, $periodlink, $description, $builddate, $exportlink='', $moreparam=array(), $calcmode='', $varlink='')
Show header of a page used to transfer/dispatch data in accounting.
length_accounta($accounta)
Return Auxiliary accounting account of thirdparties with defined length.
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader()
Empty header.
Definition wrapper.php:55
llxFooter()
Empty footer.
Definition wrapper.php:69
Class to manage accounting accounts.
Class to manage accounting journals.
Class to manage Ledger (General Ledger and Subledger)
Class to manage Trips and Expenses.
Class of expense report details lines.
Class to manage generation of HTML components Only common components must be here.
Class to manage Dolibarr users.
dol_get_first_day($year, $month=1, $gm=false)
Return GMT time for first day of a month or year.
Definition date.lib.php:594
dol_get_last_day($year, $month=12, $gm=false)
Return GMT time for last day of a month or year.
Definition date.lib.php:613
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed informations (by default a local PHP server timestamp) Re...
vatrate($rate, $addpercent=false, $info_bits=0, $usestarfornpr=0, $html=0)
Return a string with VAT rate label formated for view output Used into pdf and HTML pages.
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getTaxesFromId($vatrate, $buyer=null, $seller=null, $firstparamisid=1)
Get tax (VAT) main information from Id.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_now($mode='auto')
Return date for now.
dolGetFirstLastname($firstname, $lastname, $nameorder=-1)
Return firstname and lastname in correct order.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.