dolibarr  21.0.0-alpha
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@netlogic.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 
31 require '../../main.inc.php';
32 require_once DOL_DOCUMENT_ROOT.'/core/lib/report.lib.php';
33 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
34 require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
35 require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
36 require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
37 require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
38 require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
39 require_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 = GETPOSTINT('id_journal');
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');
54 if ($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
64 if (!isModEnabled('accounting')) {
66 }
67 if ($user->socid > 0) {
69 }
70 if (!$user->hasRight('accounting', 'bind', 'write')) {
72 }
73 
74 $error = 0;
75 $errorforinvoice = array();
76 
77 
78 /*
79  * Actions
80  */
81 
82 $accountingaccount = new AccountingAccount($db);
83 
84 // Get information of a 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 
93 if (empty($date_startmonth)) {
94  // Period by default on transfer
95  $dates = getDefaultDatesForTransfer();
96  $date_start = $dates['date_start'];
97  $pastmonthyear = $dates['pastmonthyear'];
98  $pastmonth = $dates['pastmonth'];
99 }
100 if (empty($date_endmonth)) {
101  // Period by default on transfer
102  $dates = getDefaultDatesForTransfer();
103  $date_end = $dates['date_end'];
104  $pastmonthyear = $dates['pastmonthyear'];
105  $pastmonth = $dates['pastmonth'];
106 }
107 
108 if (!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, er.date_fin as df,";
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
131 if ($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
135 if (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
139 if ($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 }
142 if ($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 
150 dol_syslog('accountancy/journal/expensereportsjournal.php', LOG_DEBUG);
151 $result = $db->query($sql);
152 if ($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('ACCOUNTING_ACCOUNT_EXPENSEREPORT', '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'] : $cpttva);
179  $compta_localtax2 = (!empty($vatdata['accountancy_code_buy']) ? $vatdata['accountancy_code_buy'] : $cpttva);
180 
181  // Define an 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  if (getDolGlobalInt('ACCOUNTANCY_ER_DATE_RECORD')) {
187  $taber[$obj->rowid]["date"] = $db->jdate($obj->df);
188  } else {
189  $taber[$obj->rowid]["date"] = $db->jdate($obj->de);
190  }
191  $taber[$obj->rowid]["ref"] = $obj->ref;
192  $taber[$obj->rowid]["comments"] = $obj->comments;
193  $taber[$obj->rowid]["fk_expensereportdet"] = $obj->erdid;
194 
195  // Avoid warnings
196  if (!isset($tabttc[$obj->rowid][$compta_user])) {
197  $tabttc[$obj->rowid][$compta_user] = 0;
198  }
199  if (!isset($tabht[$obj->rowid][$compta_fees])) {
200  $tabht[$obj->rowid][$compta_fees] = 0;
201  }
202  if (!isset($tabtva[$obj->rowid][$compta_tva])) {
203  $tabtva[$obj->rowid][$compta_tva] = 0;
204  }
205  if (!isset($tablocaltax1[$obj->rowid][$compta_localtax1])) {
206  $tablocaltax1[$obj->rowid][$compta_localtax1] = 0;
207  }
208  if (!isset($tablocaltax2[$obj->rowid][$compta_localtax2])) {
209  $tablocaltax2[$obj->rowid][$compta_localtax2] = 0;
210  }
211 
212  $tabttc[$obj->rowid][$compta_user] += $obj->total_ttc;
213  $tabht[$obj->rowid][$compta_fees] += $obj->total_ht;
214  $tabtva[$obj->rowid][$compta_tva] += $obj->total_tva;
215  $tablocaltax1[$obj->rowid][$compta_localtax1] += $obj->total_localtax1;
216  $tablocaltax2[$obj->rowid][$compta_localtax2] += $obj->total_localtax2;
217  $tabuser[$obj->rowid] = array(
218  'id' => $obj->uid,
219  'name' => dolGetFirstLastname($obj->firstname, $obj->lastname),
220  'user_accountancy_code' => $obj->user_accountancy_account
221  );
222 
223  $i++;
224  }
225 } else {
226  dol_print_error($db);
227 }
228 
229 // Load all unbound lines
230 $sql = "SELECT fk_expensereport, COUNT(erd.rowid) as nb";
231 $sql .= " FROM ".MAIN_DB_PREFIX."expensereport_det as erd";
232 $sql .= " WHERE erd.fk_code_ventilation <= 0";
233 $sql .= " AND erd.total_ttc <> 0";
234 $sql .= " AND fk_expensereport IN (".$db->sanitize(implode(",", array_keys($taber))).")";
235 $sql .= " GROUP BY fk_expensereport";
236 $resql = $db->query($sql);
237 
238 $num = $db->num_rows($resql);
239 $i = 0;
240 while ($i < $num) {
241  $obj = $db->fetch_object($resql);
242  if ($obj->nb > 0) {
243  $errorforinvoice[$obj->fk_expensereport] = 'somelinesarenotbound';
244  }
245  $i++;
246 }
247 
248 // Bookkeeping Write
249 if ($action == 'writebookkeeping' && !$error) {
250  $now = dol_now();
251  $error = 0;
252 
253  $accountingaccountexpense = new AccountingAccount($db);
254  $accountingaccountexpense->fetch(null, getDolGlobalString('ACCOUNTING_ACCOUNT_EXPENSEREPORT'), true);
255 
256  foreach ($taber as $key => $val) { // Loop on each expense report
257  $errorforline = 0;
258 
259  $totalcredit = 0;
260  $totaldebit = 0;
261 
262  $db->begin();
263 
264  // Error if some lines are not binded/ready to be journalized
265  if (!empty($errorforinvoice[$key]) && $errorforinvoice[$key] == 'somelinesarenotbound') {
266  $error++;
267  $errorforline++;
268  setEventMessages($langs->trans('ErrorInvoiceContainsLinesNotYetBounded', $val['ref']), null, 'errors');
269  }
270 
271  // Thirdparty
272  if (!$errorforline) {
273  foreach ($tabttc[$key] as $k => $mt) {
274  if ($mt) {
275  $bookkeeping = new BookKeeping($db);
276  $bookkeeping->doc_date = $val["date"];
277  $bookkeeping->doc_ref = $val["ref"];
278  $bookkeeping->date_creation = $now;
279  $bookkeeping->doc_type = 'expense_report';
280  $bookkeeping->fk_doc = $key;
281  $bookkeeping->fk_docdet = $val["fk_expensereportdet"];
282 
283  $bookkeeping->subledger_account = $tabuser[$key]['user_accountancy_code'];
284  $bookkeeping->subledger_label = $tabuser[$key]['name'];
285 
286  $bookkeeping->numero_compte = getDolGlobalString('ACCOUNTING_ACCOUNT_EXPENSEREPORT');
287  $bookkeeping->label_compte = $accountingaccountexpense->label;
288 
289  $bookkeeping->label_operation = $tabuser[$key]['name'];
290  $bookkeeping->montant = $mt;
291  $bookkeeping->sens = ($mt >= 0) ? 'C' : 'D';
292  $bookkeeping->debit = ($mt <= 0) ? -$mt : 0;
293  $bookkeeping->credit = ($mt > 0) ? $mt : 0;
294  $bookkeeping->code_journal = $journal;
295  $bookkeeping->journal_label = $langs->transnoentities($journal_label);
296  $bookkeeping->fk_user_author = $user->id;
297  $bookkeeping->entity = $conf->entity;
298 
299  $totaldebit += $bookkeeping->debit;
300  $totalcredit += $bookkeeping->credit;
301 
302  $result = $bookkeeping->create($user);
303  if ($result < 0) {
304  if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
305  $error++;
306  $errorforline++;
307  $errorforinvoice[$key] = 'alreadyjournalized';
308  //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
309  } else {
310  $error++;
311  $errorforline++;
312  $errorforinvoice[$key] = 'other';
313  setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
314  }
315  }
316  }
317  }
318  }
319 
320  // Fees
321  if (!$errorforline) {
322  foreach ($tabht[$key] as $k => $mt) {
323  if ($mt) {
324  // get compte id and label
325  if ($accountingaccount->fetch(null, $k, true)) {
326  $bookkeeping = new BookKeeping($db);
327  $bookkeeping->doc_date = $val["date"];
328  $bookkeeping->doc_ref = $val["ref"];
329  $bookkeeping->date_creation = $now;
330  $bookkeeping->doc_type = 'expense_report';
331  $bookkeeping->fk_doc = $key;
332  $bookkeeping->fk_docdet = $val["fk_expensereportdet"];
333 
334  $bookkeeping->subledger_account = '';
335  $bookkeeping->subledger_label = '';
336 
337  $bookkeeping->numero_compte = $k;
338  $bookkeeping->label_compte = $accountingaccount->label;
339 
340  $bookkeeping->label_operation = $accountingaccount->label;
341  $bookkeeping->montant = $mt;
342  $bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
343  $bookkeeping->debit = ($mt > 0) ? $mt : 0;
344  $bookkeeping->credit = ($mt <= 0) ? -$mt : 0;
345  $bookkeeping->code_journal = $journal;
346  $bookkeeping->journal_label = $langs->transnoentities($journal_label);
347  $bookkeeping->fk_user_author = $user->id;
348  $bookkeeping->entity = $conf->entity;
349 
350  $totaldebit += $bookkeeping->debit;
351  $totalcredit += $bookkeeping->credit;
352 
353  $result = $bookkeeping->create($user);
354  if ($result < 0) {
355  if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
356  $error++;
357  $errorforline++;
358  $errorforinvoice[$key] = 'alreadyjournalized';
359  //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
360  } else {
361  $error++;
362  $errorforline++;
363  $errorforinvoice[$key] = 'other';
364  setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
365  }
366  }
367  }
368  }
369  }
370  }
371 
372  // VAT
373  if (!$errorforline) {
374  $listoftax = array(0, 1, 2);
375  foreach ($listoftax as $numtax) {
376  $arrayofvat = $tabtva;
377  if ($numtax == 1) {
378  $arrayofvat = $tablocaltax1;
379  }
380  if ($numtax == 2) {
381  $arrayofvat = $tablocaltax2;
382  }
383 
384  foreach ($arrayofvat[$key] as $k => $mt) {
385  if ($mt) {
386  if (empty($conf->cache['accountingaccountincurrententity'][$k])) {
387  $accountingaccount = new AccountingAccount($db);
388  $accountingaccount->fetch(0, $k, true);
389  $conf->cache['accountingaccountincurrententity'][$k] = $accountingaccount;
390  } else {
391  $accountingaccount = $conf->cache['accountingaccountincurrententity'][$k];
392  }
393 
394  $account_label = $accountingaccount->label;
395 
396  // get compte id and label
397  $bookkeeping = new BookKeeping($db);
398  $bookkeeping->doc_date = $val["date"];
399  $bookkeeping->doc_ref = $val["ref"];
400  $bookkeeping->date_creation = $now;
401  $bookkeeping->doc_type = 'expense_report';
402  $bookkeeping->fk_doc = $key;
403  $bookkeeping->fk_docdet = $val["fk_expensereportdet"];
404 
405  $bookkeeping->subledger_account = '';
406  $bookkeeping->subledger_label = '';
407 
408  $bookkeeping->numero_compte = $k;
409  $bookkeeping->label_compte = $account_label;
410 
411  $bookkeeping->label_operation = $langs->trans("VAT").' '.implode(', ', $def_tva[$key][$k]).' %';
412  $bookkeeping->montant = $mt;
413  $bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
414  $bookkeeping->debit = ($mt > 0) ? $mt : 0;
415  $bookkeeping->credit = ($mt <= 0) ? -$mt : 0;
416  $bookkeeping->code_journal = $journal;
417  $bookkeeping->journal_label = $langs->transnoentities($journal_label);
418  $bookkeeping->fk_user_author = $user->id;
419  $bookkeeping->entity = $conf->entity;
420 
421  $totaldebit += $bookkeeping->debit;
422  $totalcredit += $bookkeeping->credit;
423 
424  $result = $bookkeeping->create($user);
425  if ($result < 0) {
426  if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
427  $error++;
428  $errorforline++;
429  $errorforinvoice[$key] = 'alreadyjournalized';
430  //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
431  } else {
432  $error++;
433  $errorforline++;
434  $errorforinvoice[$key] = 'other';
435  setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
436  }
437  }
438  }
439  }
440  }
441  }
442 
443  // Protection against a bug on lines before
444  if (!$errorforline && (price2num($totaldebit, 'MT') != price2num($totalcredit, 'MT'))) {
445  $error++;
446  $errorforline++;
447  $errorforinvoice[$key] = 'amountsnotbalanced';
448  setEventMessages('We tried to insert a non balanced transaction in book for '.$val["ref"].'. Canceled. Surely a bug.', null, 'errors');
449  }
450 
451  if (!$errorforline) {
452  $db->commit();
453  } else {
454  $db->rollback();
455 
456  if ($error >= 10) {
457  setEventMessages($langs->trans("ErrorTooManyErrorsProcessStopped"), null, 'errors');
458  break; // Break in the foreach
459  }
460  }
461  }
462 
463  $tabpay = $taber;
464 
465  if (empty($error) && count($tabpay) > 0) {
466  setEventMessages($langs->trans("GeneralLedgerIsWritten"), null, 'mesgs');
467  } elseif (count($tabpay) == $error) {
468  setEventMessages($langs->trans("NoNewRecordSaved"), null, 'warnings');
469  } else {
470  setEventMessages($langs->trans("GeneralLedgerSomeRecordWasNotRecorded"), null, 'warnings');
471  }
472 
473  $action = '';
474 
475  // Must reload data, so we make a redirect
476  if (count($tabpay) != $error) {
477  $param = 'id_journal='.$id_journal;
478  $param .= '&date_startday='.$date_startday;
479  $param .= '&date_startmonth='.$date_startmonth;
480  $param .= '&date_startyear='.$date_startyear;
481  $param .= '&date_endday='.$date_endday;
482  $param .= '&date_endmonth='.$date_endmonth;
483  $param .= '&date_endyear='.$date_endyear;
484  $param .= '&in_bookkeeping='.$in_bookkeeping;
485 
486  header("Location: ".$_SERVER['PHP_SELF'].($param ? '?'.$param : ''));
487  exit;
488  }
489 }
490 
491 
492 /*
493  * View
494  */
495 
496 $form = new Form($db);
497 
498 $userstatic = new User($db);
499 
500 // Export
501 if ($action == 'exportcsv' && !$error) { // ISO and not UTF8 !
502  $sep = getDolGlobalString('ACCOUNTING_EXPORT_SEPARATORCSV');
503 
504  $filename = 'journal';
505  $type_export = 'journal';
506  include DOL_DOCUMENT_ROOT.'/accountancy/tpl/export_journal.tpl.php';
507 
508  // CSV header line
509  print '"'.$langs->transnoentitiesnoconv("Date").'"'.$sep;
510  print '"'.$langs->transnoentitiesnoconv("Piece").'"'.$sep;
511  print '"'.$langs->transnoentitiesnoconv("AccountAccounting").'"'.$sep;
512  print '"'.$langs->transnoentitiesnoconv("LabelOperation").'"'.$sep;
513  print '"'.$langs->transnoentitiesnoconv("AccountingDebit").'"'.$sep;
514  print '"'.$langs->transnoentitiesnoconv("AccountingCredit").'"'.$sep;
515  print "\n";
516 
517  foreach ($taber as $key => $val) {
518  $date = dol_print_date($val["date"], 'day');
519 
520  $userstatic->id = $tabuser[$key]['id'];
521  $userstatic->name = $tabuser[$key]['name'];
522 
523  // Fees
524  foreach ($tabht[$key] as $k => $mt) {
525  $accountingaccount = new AccountingAccount($db);
526  $accountingaccount->fetch(null, $k, true);
527  if ($mt) {
528  print '"'.$date.'"'.$sep;
529  print '"'.$val["ref"].'"'.$sep;
530  print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
531  print '"'.dol_trunc($accountingaccount->label, 32).'"'.$sep;
532  print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
533  print '"'.($mt < 0 ? price(-$mt) : '').'"';
534  print "\n";
535  }
536  }
537 
538  // VAT
539  foreach ($tabtva[$key] as $k => $mt) {
540  if ($mt) {
541  print '"'.$date.'"'.$sep;
542  print '"'.$val["ref"].'"'.$sep;
543  print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
544  print '"'.dol_trunc($langs->trans("VAT")).'"'.$sep;
545  print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
546  print '"'.($mt < 0 ? price(-$mt) : '').'"';
547  print "\n";
548  }
549  }
550 
551  // Third party
552  foreach ($tabttc[$key] as $k => $mt) {
553  print '"'.$date.'"'.$sep;
554  print '"'.$val["ref"].'"'.$sep;
555  print '"'.length_accounta(html_entity_decode($k)).'"'.$sep;
556  print '"'.dol_trunc($userstatic->name).'"'.$sep;
557  print '"'.($mt < 0 ? price(-$mt) : '').'"'.$sep;
558  print '"'.($mt >= 0 ? price($mt) : '').'"';
559  }
560  print "\n";
561  }
562 }
563 
564 if (empty($action) || $action == 'view') {
565  $title = $langs->trans("GenerationOfAccountingEntries").' - '.$accountingjournalstatic->getNomUrl(0, 2, 1, '', 1);
566  $help_url ='EN:Module_Double_Entry_Accounting|FR:Module_Comptabilit&eacute;_en_Partie_Double#G&eacute;n&eacute;ration_des_&eacute;critures_en_comptabilit&eacute;';
567  llxHeader('', dol_string_nohtmltag($title), $help_url, '', 0, 0, '', '', '', 'mod-accountancy accountancy-generation page-expensereportsjournal');
568 
569  $nom = $title;
570  $nomlink = '';
571  $periodlink = '';
572  $exportlink = '';
573  $builddate = dol_now();
574  $description = $langs->trans("DescJournalOnlyBindedVisible").'<br>';
575 
576  $listofchoices = array('notyet'=>$langs->trans("NotYetInGeneralLedger"), 'already'=>$langs->trans("AlreadyInGeneralLedger"));
577  $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);
578  $period .= ' - '.$langs->trans("JournalizationInLedgerStatus").' '.$form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1);
579 
580  $varlink = 'id_journal='.$id_journal;
581 
582  journalHead($nom, $nomlink, $period, $periodlink, $description, $builddate, $exportlink, array('action' => ''), '', $varlink);
583 
584  if (getDolGlobalString('ACCOUNTANCY_FISCAL_PERIOD_MODE') != 'blockedonclosed') {
585  // Test that setup is complete (we are in accounting, so test on entity is always on $conf->entity only, no sharing allowed)
586  // Fiscal period test
587  $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."accounting_fiscalyear WHERE entity = ".((int) $conf->entity);
588  $resql = $db->query($sql);
589  if ($resql) {
590  $obj = $db->fetch_object($resql);
591  if ($obj->nb == 0) {
592  print '<br><div class="warning">'.img_warning().' '.$langs->trans("TheFiscalPeriodIsNotDefined");
593  $desc = ' : '.$langs->trans("AccountancyAreaDescFiscalPeriod", 4, '{link}');
594  $desc = str_replace('{link}', '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("FiscalPeriod").'</strong>', $desc);
595  print $desc;
596  print '</div>';
597  }
598  } else {
599  dol_print_error($db);
600  }
601  }
602 
603  // Button to write into Ledger
604  if (!getDolGlobalString('ACCOUNTING_ACCOUNT_EXPENSEREPORT') || getDolGlobalString('ACCOUNTING_ACCOUNT_EXPENSEREPORT') == '-1') {
605  print '<br><div class="warning">'.img_warning().' '.$langs->trans("SomeMandatoryStepsOfSetupWereNotDone");
606  $desc = ' : '.$langs->trans("AccountancyAreaDescMisc", 4, '{link}');
607  $desc = str_replace('{link}', '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</strong>', $desc);
608  print $desc;
609  print '</div>';
610  }
611  print '<br><div class="tabsAction tabsActionNoBottom centerimp">';
612 
613  if (getDolGlobalString('ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL') && $in_bookkeeping == 'notyet') {
614  print '<input type="button" class="butAction" name="exportcsv" value="'.$langs->trans("ExportDraftJournal").'" onclick="launch_export();" />';
615  }
616  if (!getDolGlobalString('ACCOUNTING_ACCOUNT_EXPENSEREPORT') || getDolGlobalString('ACCOUNTING_ACCOUNT_EXPENSEREPORT') == '-1') {
617  print '<input type="button" class="butActionRefused classfortooltip" title="'.dol_escape_htmltag($langs->trans("SomeMandatoryStepsOfSetupWereNotDone")).'" value="'.$langs->trans("WriteBookKeeping").'" />';
618  } else {
619  if ($in_bookkeeping == 'notyet') {
620  print '<input type="button" class="butAction" name="writebookkeeping" value="'.$langs->trans("WriteBookKeeping").'" onclick="writebookkeeping();" />';
621  } else {
622  print '<a href="#" class="butActionRefused classfortooltip" name="writebookkeeping">'.$langs->trans("WriteBookKeeping").'</a>';
623  }
624  }
625  print '</div>';
626 
627  // TODO Avoid using js. We can use a direct link with $param
628  print '
629  <script type="text/javascript">
630  function launch_export() {
631  $("div.fiche form input[name=\"action\"]").val("exportcsv");
632  $("div.fiche form input[type=\"submit\"]").click();
633  $("div.fiche form input[name=\"action\"]").val("");
634  }
635  function writebookkeeping() {
636  console.log("click on writebookkeeping");
637  $("div.fiche form input[name=\"action\"]").val("writebookkeeping");
638  $("div.fiche form input[type=\"submit\"]").click();
639  $("div.fiche form input[name=\"action\"]").val("");
640  }
641  </script>';
642 
643  /*
644  * Show result array
645  */
646  print '<br>';
647 
648  $i = 0;
649  print '<div class="div-table-responsive">';
650  print "<table class=\"noborder\" width=\"100%\">";
651  print "<tr class=\"liste_titre\">";
652  print "<td>".$langs->trans("Date")."</td>";
653  print "<td>".$langs->trans("Piece").' ('.$langs->trans("ExpenseReportRef").")</td>";
654  print "<td>".$langs->trans("AccountAccounting")."</td>";
655  print "<td>".$langs->trans("SubledgerAccount")."</td>";
656  print "<td>".$langs->trans("LabelOperation")."</td>";
657  print '<td class="right">'.$langs->trans("AccountingDebit")."</td>";
658  print '<td class="right">'.$langs->trans("AccountingCredit")."</td>";
659  print "</tr>\n";
660 
661  $i = 0;
662 
663  $expensereportstatic = new ExpenseReport($db);
664  $expensereportlinestatic = new ExpenseReportLine($db);
665 
666  foreach ($taber as $key => $val) {
667  $expensereportstatic->id = $key;
668  $expensereportstatic->ref = $val["ref"];
669  $expensereportlinestatic->comments = html_entity_decode(dol_trunc($val["comments"], 32));
670 
671  $date = dol_print_date($val["date"], 'day');
672 
673  if ($errorforinvoice[$key] == 'somelinesarenotbound') {
674  print '<tr class="oddeven">';
675  print "<!-- Some lines are not bound -->";
676  print "<td>".$date."</td>";
677  print "<td>".$expensereportstatic->getNomUrl(1)."</td>";
678  // Account
679  print "<td>";
680  print '<span class="error">'.$langs->trans('ErrorInvoiceContainsLinesNotYetBoundedShort', $val['ref']).'</span>';
681  print '</td>';
682  // Subledger account
683  print "<td>";
684  print '</td>';
685  print "<td>";
686  print "</td>";
687  print '<td class="right"></td>';
688  print '<td class="right"></td>';
689  print "</tr>";
690 
691  $i++;
692  }
693 
694  // Fees
695  foreach ($tabht[$key] as $k => $mt) {
696  if (empty($conf->cache['accountingaccountincurrententity'][$k])) {
697  $accountingaccount = new AccountingAccount($db);
698  $accountingaccount->fetch(0, $k, true);
699  $conf->cache['accountingaccountincurrententity'][$k] = $accountingaccount;
700  } else {
701  $accountingaccount = $conf->cache['accountingaccountincurrententity'][$k];
702  }
703 
704  if ($mt) {
705  print '<tr class="oddeven">';
706  print "<!-- Fees -->";
707  print "<td>".$date."</td>";
708  print "<td>".$expensereportstatic->getNomUrl(1)."</td>";
709  $userstatic->id = $tabuser[$key]['id'];
710  $userstatic->name = $tabuser[$key]['name'];
711  // Account
712  print "<td>";
713  $accountoshow = length_accountg($k);
714  if (($accountoshow == "") || $accountoshow == 'NotDefined') {
715  print '<span class="error">'.$langs->trans("FeeAccountNotDefined").'</span>';
716  } else {
717  print $accountoshow;
718  }
719  print '</td>';
720  // Subledger account
721  print "<td>";
722  print '</td>';
723  $userstatic->id = $tabuser[$key]['id'];
724  $userstatic->name = $tabuser[$key]['name'];
725  print "<td>".$userstatic->getNomUrl(0, 'user', 16).' - '.$accountingaccount->label."</td>";
726  print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
727  print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
728  print "</tr>";
729 
730  $i++;
731  }
732  }
733 
734  // Third party
735  foreach ($tabttc[$key] as $k => $mt) {
736  $userstatic->id = $tabuser[$key]['id'];
737  $userstatic->name = $tabuser[$key]['name'];
738 
739  print '<tr class="oddeven">';
740  print "<!-- Thirdparty -->";
741  print "<td>".$date."</td>";
742  print "<td>".$expensereportstatic->getNomUrl(1)."</td>";
743  // Account
744  print "<td>";
745  $accountoshow = length_accountg(getDolGlobalString('ACCOUNTING_ACCOUNT_EXPENSEREPORT'));
746  if (($accountoshow == "") || $accountoshow == 'NotDefined') {
747  print '<span class="error">'.$langs->trans("MainAccountForUsersNotDefined").'</span>';
748  } else {
749  print $accountoshow;
750  }
751  print "</td>";
752  // Subledger account
753  print "<td>";
754  $accountoshow = length_accounta($k);
755  if (($accountoshow == "") || $accountoshow == 'NotDefined') {
756  print '<span class="error">'.$langs->trans("UserAccountNotDefined").'</span>';
757  } else {
758  print $accountoshow;
759  }
760  print '</td>';
761  print "<td>".$userstatic->getNomUrl(0, 'user', 16).' - '.$langs->trans("SubledgerAccount")."</td>";
762  print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
763  print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
764  print "</tr>";
765 
766  $i++;
767  }
768 
769  // VAT
770  $listoftax = array(0, 1, 2);
771  foreach ($listoftax as $numtax) {
772  $arrayofvat = $tabtva;
773  if ($numtax == 1) {
774  $arrayofvat = $tablocaltax1;
775  }
776  if ($numtax == 2) {
777  $arrayofvat = $tablocaltax2;
778  }
779 
780  foreach ($arrayofvat[$key] as $k => $mt) {
781  if ($mt) {
782  print '<tr class="oddeven">';
783  print "<!-- VAT -->";
784  print "<td>".$date."</td>";
785  print "<td>".$expensereportstatic->getNomUrl(1)."</td>";
786  // Account
787  print "<td>";
788  $accountoshow = length_accountg($k);
789  if (($accountoshow == "") || $accountoshow == 'NotDefined') {
790  print '<span class="error">'.$langs->trans("VATAccountNotDefined").'</span>';
791  } else {
792  print $accountoshow;
793  }
794  print "</td>";
795  // Subledger account
796  print "<td>";
797  print '</td>';
798  print "<td>".$userstatic->getNomUrl(0, 'user', 16).' - '.$langs->trans("VAT").' '.implode(', ', $def_tva[$key][$k]).' %'.($numtax ? ' - Localtax '.$numtax : '');
799  print "</td>";
800  print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
801  print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
802  print "</tr>";
803 
804  $i++;
805  }
806  }
807  }
808  }
809 
810  if (!$i) {
811  $colspan = 7;
812  print '<tr class="oddeven"><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
813  }
814 
815  print "</table>";
816  print '</div>';
817 
818  // End of page
819  llxFooter();
820 }
821 $db->close();
length_accountg($account)
Return General accounting account with defined length (used for product and miscellaneous)
journalHead($nom, $variant, $period, $periodlink, $description, $builddate, $exportlink='', $moreparam=array(), $calcmode='', $varlink='', $moreoptions=array())
Show header of a page used to transfer/dispatch data in accounting.
getDefaultDatesForTransfer()
Return Default dates for transfer based on periodicity option in accountancy setup.
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.
Definition: user.class.php:50
if(isModEnabled('invoice') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&!getDolGlobalString('MAIN_USE_NEW_SUPPLIERMOD') && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') && $user->hasRight('tax', 'charges', 'lire')) if(isModEnabled('invoice') &&isModEnabled('order') && $user->hasRight("commande", "lire") &&!getDolGlobalString('WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER')) $sql
Social contributions to pay.
Definition: index.php:751
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 information (by default a local PHP server timestamp) Rep...
vatrate($rate, $addpercent=false, $info_bits=0, $usestarfornpr=0, $html=0)
Return a string with VAT rate label formatted for view output Used into pdf and HTML pages.
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
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 '.
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_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
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_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
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.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
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.