dolibarr  18.0.6
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-2023 Alexandre Spangaro <aspangaro@easya.solutions>
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 = 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');
54 if ($in_bookkeeping == '') {
55  $in_bookkeeping = 'notyet';
56 }
57 
58 $now = dol_now();
59 
60 // Security check
61 if (!isModEnabled('accounting')) {
63 }
64 if ($user->socid > 0) {
66 }
67 if (!$user->hasRight('accounting', 'mouvements', 'lire')) {
69 }
70 
71 $error = 0;
72 
73 /*
74  * Actions
75  */
76 
77 $accountingaccount = new AccountingAccount($db);
78 
79 // Get informations of journal
80 $accountingjournalstatic = new AccountingJournal($db);
81 $accountingjournalstatic->fetch($id_journal);
82 $journal = $accountingjournalstatic->code;
83 $journal_label = $accountingjournalstatic->label;
84 
85 $date_start = dol_mktime(0, 0, 0, $date_startmonth, $date_startday, $date_startyear);
86 $date_end = dol_mktime(23, 59, 59, $date_endmonth, $date_endday, $date_endyear);
87 
88 if (empty($date_startmonth) || empty($date_endmonth)) {
89  // Period by default on transfer
90  $dates = getDefaultDatesForTransfer();
91  $date_start = $dates['date_start'];
92  $date_end = $dates['date_end'];
93  $pastmonthyear = $dates['pastmonthyear'];
94  $pastmonth = $dates['pastmonth'];
95 }
96 
97 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
98  $date_start = dol_get_first_day($pastmonthyear, $pastmonth, false);
99  $date_end = dol_get_last_day($pastmonthyear, $pastmonth, false);
100 }
101 
102 $sql = "SELECT er.rowid, er.ref, er.date_debut as de,";
103 $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, ";
104 $sql .= " u.rowid as uid, u.firstname, u.lastname, u.accountancy_code as user_accountancy_account,";
105 $sql .= " f.accountancy_code, aa.rowid as fk_compte, aa.account_number as compte, aa.label as label_compte";
106 $sql .= " FROM ".MAIN_DB_PREFIX."expensereport_det as erd";
107 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_type_fees as f ON f.id = erd.fk_c_type_fees";
108 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa ON aa.rowid = erd.fk_code_ventilation";
109 $sql .= " JOIN ".MAIN_DB_PREFIX."expensereport as er ON er.rowid = erd.fk_expensereport";
110 $sql .= " JOIN ".MAIN_DB_PREFIX."user as u ON u.rowid = er.fk_user_author";
111 $sql .= " WHERE er.fk_statut > 0";
112 $sql .= " AND erd.fk_code_ventilation > 0";
113 $sql .= " AND er.entity IN (".getEntity('expensereport', 0).")"; // We don't share object for accountancy
114 if ($date_start && $date_end) {
115  $sql .= " AND er.date_debut >= '".$db->idate($date_start)."' AND er.date_debut <= '".$db->idate($date_end)."'";
116 }
117 // Define begin binding date
118 if (!empty($conf->global->ACCOUNTING_DATE_START_BINDING)) {
119  $sql .= " AND er.date_debut >= '".$db->idate($conf->global->ACCOUNTING_DATE_START_BINDING)."'";
120 }
121 // Already in bookkeeping or not
122 if ($in_bookkeeping == 'already') {
123  $sql .= " AND er.rowid IN (SELECT fk_doc FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as ab WHERE ab.doc_type='expense_report')";
124 }
125 if ($in_bookkeeping == 'notyet') {
126  $sql .= " AND er.rowid NOT IN (SELECT fk_doc FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as ab WHERE ab.doc_type='expense_report')";
127 }
128 $sql .= " ORDER BY er.date_debut";
129 
130 dol_syslog('accountancy/journal/expensereportsjournal.php', LOG_DEBUG);
131 $result = $db->query($sql);
132 if ($result) {
133  $taber = array();
134  $tabht = array();
135  $tabtva = array();
136  $def_tva = array();
137  $tabttc = array();
138  $tablocaltax1 = array();
139  $tablocaltax2 = array();
140  $tabuser = array();
141 
142  $num = $db->num_rows($result);
143 
144  // Variables
145  $account_salary = (!empty($conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT)) ? $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT : 'NotDefined';
146  $account_vat = (!empty($conf->global->ACCOUNTING_VAT_BUY_ACCOUNT)) ? $conf->global->ACCOUNTING_VAT_BUY_ACCOUNT : 'NotDefined';
147 
148  $i = 0;
149  while ($i < $num) {
150  $obj = $db->fetch_object($result);
151 
152  // Controls
153  $compta_user = (!empty($obj->user_accountancy_account)) ? $obj->user_accountancy_account : $account_salary;
154  $compta_fees = $obj->compte;
155 
156  $vatdata = getTaxesFromId($obj->tva_tx.($obj->vat_src_code ? ' ('.$obj->vat_src_code.')' : ''), $mysoc, $mysoc, 0);
157  $compta_tva = (!empty($vatdata['accountancy_code_buy']) ? $vatdata['accountancy_code_buy'] : $account_vat);
158  $compta_localtax1 = (!empty($vatdata['accountancy_code_buy']) ? $vatdata['accountancy_code_buy'] : $cpttva);
159  $compta_localtax2 = (!empty($vatdata['accountancy_code_buy']) ? $vatdata['accountancy_code_buy'] : $cpttva);
160 
161  // Define array to display all VAT rates that use this accounting account $compta_tva
162  if (price2num($obj->tva_tx) || !empty($obj->vat_src_code)) {
163  $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.')' : ''));
164  }
165 
166  $taber[$obj->rowid]["date"] = $db->jdate($obj->de);
167  $taber[$obj->rowid]["ref"] = $obj->ref;
168  $taber[$obj->rowid]["comments"] = $obj->comments;
169  $taber[$obj->rowid]["fk_expensereportdet"] = $obj->erdid;
170 
171  // Avoid warnings
172  if (!isset($tabttc[$obj->rowid][$compta_user])) {
173  $tabttc[$obj->rowid][$compta_user] = 0;
174  }
175  if (!isset($tabht[$obj->rowid][$compta_fees])) {
176  $tabht[$obj->rowid][$compta_fees] = 0;
177  }
178  if (!isset($tabtva[$obj->rowid][$compta_tva])) {
179  $tabtva[$obj->rowid][$compta_tva] = 0;
180  }
181  if (!isset($tablocaltax1[$obj->rowid][$compta_localtax1])) {
182  $tablocaltax1[$obj->rowid][$compta_localtax1] = 0;
183  }
184  if (!isset($tablocaltax2[$obj->rowid][$compta_localtax2])) {
185  $tablocaltax2[$obj->rowid][$compta_localtax2] = 0;
186  }
187 
188  $tabttc[$obj->rowid][$compta_user] += $obj->total_ttc;
189  $tabht[$obj->rowid][$compta_fees] += $obj->total_ht;
190  $tabtva[$obj->rowid][$compta_tva] += $obj->total_tva;
191  $tablocaltax1[$obj->rowid][$compta_localtax1] += $obj->total_localtax1;
192  $tablocaltax2[$obj->rowid][$compta_localtax2] += $obj->total_localtax2;
193  $tabuser[$obj->rowid] = array(
194  'id' => $obj->uid,
195  'name' => dolGetFirstLastname($obj->firstname, $obj->lastname),
196  'user_accountancy_code' => $obj->user_accountancy_account
197  );
198 
199  $i++;
200  }
201 } else {
202  dol_print_error($db);
203 }
204 
205 // Load all unbound lines
206 $sql = "SELECT fk_expensereport, COUNT(erd.rowid) as nb";
207 $sql .= " FROM ".MAIN_DB_PREFIX."expensereport_det as erd";
208 $sql .= " WHERE erd.fk_code_ventilation <= 0";
209 $sql .= " AND erd.total_ttc <> 0";
210 $sql .= " AND fk_expensereport IN (".$db->sanitize(join(",", array_keys($taber))).")";
211 $sql .= " GROUP BY fk_expensereport";
212 $resql = $db->query($sql);
213 
214 $num = $db->num_rows($resql);
215 $i = 0;
216 while ($i < $num) {
217  $obj = $db->fetch_object($resql);
218  if ($obj->nb > 0) {
219  $errorforinvoice[$obj->fk_expensereport] = 'somelinesarenotbound';
220  }
221  $i++;
222 }
223 
224 // Bookkeeping Write
225 if ($action == 'writebookkeeping' && !$error) {
226  $now = dol_now();
227  $error = 0;
228 
229  $accountingaccountexpense = new AccountingAccount($db);
230  $accountingaccountexpense->fetch(null, $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT, true);
231 
232  foreach ($taber as $key => $val) { // Loop on each expense report
233  $errorforline = 0;
234 
235  $totalcredit = 0;
236  $totaldebit = 0;
237 
238  $db->begin();
239 
240  // Error if some lines are not binded/ready to be journalized
241  if ($errorforinvoice[$key] == 'somelinesarenotbound') {
242  $error++;
243  $errorforline++;
244  setEventMessages($langs->trans('ErrorInvoiceContainsLinesNotYetBounded', $val['ref']), null, 'errors');
245  }
246 
247  // Thirdparty
248  if (!$errorforline) {
249  foreach ($tabttc[$key] as $k => $mt) {
250  if ($mt) {
251  $bookkeeping = new BookKeeping($db);
252  $bookkeeping->doc_date = $val["date"];
253  $bookkeeping->doc_ref = $val["ref"];
254  $bookkeeping->date_creation = $now;
255  $bookkeeping->doc_type = 'expense_report';
256  $bookkeeping->fk_doc = $key;
257  $bookkeeping->fk_docdet = $val["fk_expensereportdet"];
258 
259  $bookkeeping->subledger_account = $tabuser[$key]['user_accountancy_code'];
260  $bookkeeping->subledger_label = $tabuser[$key]['name'];
261 
262  $bookkeeping->numero_compte = $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT;
263  $bookkeeping->label_compte = $accountingaccountexpense->label;
264 
265  $bookkeeping->label_operation = $tabuser[$key]['name'];
266  $bookkeeping->montant = $mt;
267  $bookkeeping->sens = ($mt >= 0) ? 'C' : 'D';
268  $bookkeeping->debit = ($mt <= 0) ? -$mt : 0;
269  $bookkeeping->credit = ($mt > 0) ? $mt : 0;
270  $bookkeeping->code_journal = $journal;
271  $bookkeeping->journal_label = $langs->transnoentities($journal_label);
272  $bookkeeping->fk_user_author = $user->id;
273  $bookkeeping->entity = $conf->entity;
274 
275  $totaldebit += $bookkeeping->debit;
276  $totalcredit += $bookkeeping->credit;
277 
278  $result = $bookkeeping->create($user);
279  if ($result < 0) {
280  if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
281  $error++;
282  $errorforline++;
283  $errorforinvoice[$key] = 'alreadyjournalized';
284  //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
285  } else {
286  $error++;
287  $errorforline++;
288  $errorforinvoice[$key] = 'other';
289  setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
290  }
291  }
292  }
293  }
294  }
295 
296  // Fees
297  if (!$errorforline) {
298  foreach ($tabht[$key] as $k => $mt) {
299  if ($mt) {
300  // get compte id and label
301  if ($accountingaccount->fetch(null, $k, true)) {
302  $bookkeeping = new BookKeeping($db);
303  $bookkeeping->doc_date = $val["date"];
304  $bookkeeping->doc_ref = $val["ref"];
305  $bookkeeping->date_creation = $now;
306  $bookkeeping->doc_type = 'expense_report';
307  $bookkeeping->fk_doc = $key;
308  $bookkeeping->fk_docdet = $val["fk_expensereportdet"];
309 
310  $bookkeeping->subledger_account = '';
311  $bookkeeping->subledger_label = '';
312 
313  $bookkeeping->numero_compte = $k;
314  $bookkeeping->label_compte = $accountingaccount->label;
315 
316  $bookkeeping->label_operation = $accountingaccount->label;
317  $bookkeeping->montant = $mt;
318  $bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
319  $bookkeeping->debit = ($mt > 0) ? $mt : 0;
320  $bookkeeping->credit = ($mt <= 0) ? -$mt : 0;
321  $bookkeeping->code_journal = $journal;
322  $bookkeeping->journal_label = $langs->transnoentities($journal_label);
323  $bookkeeping->fk_user_author = $user->id;
324  $bookkeeping->entity = $conf->entity;
325 
326  $totaldebit += $bookkeeping->debit;
327  $totalcredit += $bookkeeping->credit;
328 
329  $result = $bookkeeping->create($user);
330  if ($result < 0) {
331  if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
332  $error++;
333  $errorforline++;
334  $errorforinvoice[$key] = 'alreadyjournalized';
335  //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
336  } else {
337  $error++;
338  $errorforline++;
339  $errorforinvoice[$key] = 'other';
340  setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
341  }
342  }
343  }
344  }
345  }
346  }
347 
348  // VAT
349  if (!$errorforline) {
350  $listoftax = array(0, 1, 2);
351  foreach ($listoftax as $numtax) {
352  $arrayofvat = $tabtva;
353  if ($numtax == 1) {
354  $arrayofvat = $tablocaltax1;
355  }
356  if ($numtax == 2) {
357  $arrayofvat = $tablocaltax2;
358  }
359 
360  foreach ($arrayofvat[$key] as $k => $mt) {
361  if ($mt) {
362  $accountingaccount->fetch(null, $k, true); // TODO Use a cache for label
363  $account_label = $accountingaccount->label;
364 
365  // get compte id and label
366  $bookkeeping = new BookKeeping($db);
367  $bookkeeping->doc_date = $val["date"];
368  $bookkeeping->doc_ref = $val["ref"];
369  $bookkeeping->date_creation = $now;
370  $bookkeeping->doc_type = 'expense_report';
371  $bookkeeping->fk_doc = $key;
372  $bookkeeping->fk_docdet = $val["fk_expensereportdet"];
373 
374  $bookkeeping->subledger_account = '';
375  $bookkeeping->subledger_label = '';
376 
377  $bookkeeping->numero_compte = $k;
378  $bookkeeping->label_compte = $account_label;
379 
380  $bookkeeping->label_operation = $langs->trans("VAT").' '.join(', ', $def_tva[$key][$k]).' %';
381  $bookkeeping->montant = $mt;
382  $bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
383  $bookkeeping->debit = ($mt > 0) ? $mt : 0;
384  $bookkeeping->credit = ($mt <= 0) ? -$mt : 0;
385  $bookkeeping->code_journal = $journal;
386  $bookkeeping->journal_label = $langs->transnoentities($journal_label);
387  $bookkeeping->fk_user_author = $user->id;
388  $bookkeeping->entity = $conf->entity;
389 
390  $totaldebit += $bookkeeping->debit;
391  $totalcredit += $bookkeeping->credit;
392 
393  $result = $bookkeeping->create($user);
394  if ($result < 0) {
395  if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
396  $error++;
397  $errorforline++;
398  $errorforinvoice[$key] = 'alreadyjournalized';
399  //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
400  } else {
401  $error++;
402  $errorforline++;
403  $errorforinvoice[$key] = 'other';
404  setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
405  }
406  }
407  }
408  }
409  }
410  }
411 
412  // Protection against a bug on lines before
413  if (!$errorforline && (price2num($totaldebit, 'MT') != price2num($totalcredit, 'MT'))) {
414  $error++;
415  $errorforline++;
416  $errorforinvoice[$key] = 'amountsnotbalanced';
417  setEventMessages('We tried to insert a non balanced transaction in book for '.$val["ref"].'. Canceled. Surely a bug.', null, 'errors');
418  }
419 
420  if (!$errorforline) {
421  $db->commit();
422  } else {
423  $db->rollback();
424 
425  if ($error >= 10) {
426  setEventMessages($langs->trans("ErrorTooManyErrorsProcessStopped"), null, 'errors');
427  break; // Break in the foreach
428  }
429  }
430  }
431 
432  $tabpay = $taber;
433 
434  if (empty($error) && count($tabpay) > 0) {
435  setEventMessages($langs->trans("GeneralLedgerIsWritten"), null, 'mesgs');
436  } elseif (count($tabpay) == $error) {
437  setEventMessages($langs->trans("NoNewRecordSaved"), null, 'warnings');
438  } else {
439  setEventMessages($langs->trans("GeneralLedgerSomeRecordWasNotRecorded"), null, 'warnings');
440  }
441 
442  $action = '';
443 
444  // Must reload data, so we make a redirect
445  if (count($tabpay) != $error) {
446  $param = 'id_journal='.$id_journal;
447  $param .= '&date_startday='.$date_startday;
448  $param .= '&date_startmonth='.$date_startmonth;
449  $param .= '&date_startyear='.$date_startyear;
450  $param .= '&date_endday='.$date_endday;
451  $param .= '&date_endmonth='.$date_endmonth;
452  $param .= '&date_endyear='.$date_endyear;
453  $param .= '&in_bookkeeping='.$in_bookkeeping;
454 
455  header("Location: ".$_SERVER['PHP_SELF'].($param ? '?'.$param : ''));
456  exit;
457  }
458 }
459 
460 
461 /*
462  * View
463  */
464 
465 $form = new Form($db);
466 
467 $userstatic = new User($db);
468 
469 // Export
470 if ($action == 'exportcsv' && !$error) { // ISO and not UTF8 !
471  $sep = $conf->global->ACCOUNTING_EXPORT_SEPARATORCSV;
472 
473  $filename = 'journal';
474  $type_export = 'journal';
475  include DOL_DOCUMENT_ROOT.'/accountancy/tpl/export_journal.tpl.php';
476 
477  // CSV header line
478  print '"'.$langs->transnoentitiesnoconv("Date").'"'.$sep;
479  print '"'.$langs->transnoentitiesnoconv("Piece").'"'.$sep;
480  print '"'.$langs->transnoentitiesnoconv("AccountAccounting").'"'.$sep;
481  print '"'.$langs->transnoentitiesnoconv("LabelOperation").'"'.$sep;
482  print '"'.$langs->transnoentitiesnoconv("AccountingDebit").'"'.$sep;
483  print '"'.$langs->transnoentitiesnoconv("AccountingCredit").'"'.$sep;
484  print "\n";
485 
486  foreach ($taber as $key => $val) {
487  $date = dol_print_date($val["date"], 'day');
488 
489  $userstatic->id = $tabuser[$key]['id'];
490  $userstatic->name = $tabuser[$key]['name'];
491 
492  // Fees
493  foreach ($tabht[$key] as $k => $mt) {
494  $accountingaccount = new AccountingAccount($db);
495  $accountingaccount->fetch(null, $k, true);
496  if ($mt) {
497  print '"'.$date.'"'.$sep;
498  print '"'.$val["ref"].'"'.$sep;
499  print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
500  print '"'.dol_trunc($accountingaccount->label, 32).'"'.$sep;
501  print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
502  print '"'.($mt < 0 ? price(-$mt) : '').'"';
503  print "\n";
504  }
505  }
506 
507  // VAT
508  foreach ($tabtva[$key] as $k => $mt) {
509  if ($mt) {
510  print '"'.$date.'"'.$sep;
511  print '"'.$val["ref"].'"'.$sep;
512  print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
513  print '"'.dol_trunc($langs->trans("VAT")).'"'.$sep;
514  print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
515  print '"'.($mt < 0 ? price(-$mt) : '').'"';
516  print "\n";
517  }
518  }
519 
520  // Third party
521  foreach ($tabttc[$key] as $k => $mt) {
522  print '"'.$date.'"'.$sep;
523  print '"'.$val["ref"].'"'.$sep;
524  print '"'.length_accounta(html_entity_decode($k)).'"'.$sep;
525  print '"'.dol_trunc($userstatic->name).'"'.$sep;
526  print '"'.($mt < 0 ? price(-$mt) : '').'"'.$sep;
527  print '"'.($mt >= 0 ? price($mt) : '').'"';
528  }
529  print "\n";
530  }
531 }
532 
533 if (empty($action) || $action == 'view') {
534  $title = $langs->trans("GenerationOfAccountingEntries").' - '.$accountingjournalstatic->getNomUrl(0, 2, 1, '', 1);
535 
536  llxHeader('', dol_string_nohtmltag($title));
537 
538  $nom = $title;
539  $nomlink = '';
540  $periodlink = '';
541  $exportlink = '';
542  $builddate = dol_now();
543  $description = $langs->trans("DescJournalOnlyBindedVisible").'<br>';
544 
545  $listofchoices = array('notyet'=>$langs->trans("NotYetInGeneralLedger"), 'already'=>$langs->trans("AlreadyInGeneralLedger"));
546  $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);
547  $period .= ' - '.$langs->trans("JournalizationInLedgerStatus").' '.$form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1);
548 
549  $varlink = 'id_journal='.$id_journal;
550 
551  journalHead($nom, $nomlink, $period, $periodlink, $description, $builddate, $exportlink, array('action' => ''), '', $varlink);
552 
553  // Button to write into Ledger
554  if (empty($conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT) || $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT == '-1') {
555  print '<br><div class="warning">'.img_warning().' '.$langs->trans("SomeMandatoryStepsOfSetupWereNotDone");
556  $desc = ' : '.$langs->trans("AccountancyAreaDescMisc", 4, '{link}');
557  $desc = str_replace('{link}', '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</strong>', $desc);
558  print $desc;
559  print '</div>';
560  }
561  print '<div class="tabsAction tabsActionNoBottom centerimp">';
562 
563  if (!empty($conf->global->ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL) && $in_bookkeeping == 'notyet') {
564  print '<input type="button" class="butAction" name="exportcsv" value="'.$langs->trans("ExportDraftJournal").'" onclick="launch_export();" />';
565  }
566  if (empty($conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT) || $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT == '-1') {
567  print '<input type="button" class="butActionRefused classfortooltip" title="'.dol_escape_htmltag($langs->trans("SomeMandatoryStepsOfSetupWereNotDone")).'" value="'.$langs->trans("WriteBookKeeping").'" />';
568  } else {
569  if ($in_bookkeeping == 'notyet') {
570  print '<input type="button" class="butAction" name="writebookkeeping" value="'.$langs->trans("WriteBookKeeping").'" onclick="writebookkeeping();" />';
571  } else {
572  print '<a href="#" class="butActionRefused classfortooltip" name="writebookkeeping">'.$langs->trans("WriteBookKeeping").'</a>';
573  }
574  }
575  print '</div>';
576 
577  // TODO Avoid using js. We can use a direct link with $param
578  print '
579  <script type="text/javascript">
580  function launch_export() {
581  $("div.fiche form input[name=\"action\"]").val("exportcsv");
582  $("div.fiche form input[type=\"submit\"]").click();
583  $("div.fiche form input[name=\"action\"]").val("");
584  }
585  function writebookkeeping() {
586  console.log("click on writebookkeeping");
587  $("div.fiche form input[name=\"action\"]").val("writebookkeeping");
588  $("div.fiche form input[type=\"submit\"]").click();
589  $("div.fiche form input[name=\"action\"]").val("");
590  }
591  </script>';
592 
593  /*
594  * Show result array
595  */
596  print '<br>';
597 
598  $i = 0;
599  print '<div class="div-table-responsive">';
600  print "<table class=\"noborder\" width=\"100%\">";
601  print "<tr class=\"liste_titre\">";
602  print "<td>".$langs->trans("Date")."</td>";
603  print "<td>".$langs->trans("Piece").' ('.$langs->trans("ExpenseReportRef").")</td>";
604  print "<td>".$langs->trans("AccountAccounting")."</td>";
605  print "<td>".$langs->trans("SubledgerAccount")."</td>";
606  print "<td>".$langs->trans("LabelOperation")."</td>";
607  print '<td class="right">'.$langs->trans("AccountingDebit")."</td>";
608  print '<td class="right">'.$langs->trans("AccountingCredit")."</td>";
609  print "</tr>\n";
610 
611  $i = 0;
612 
613  $expensereportstatic = new ExpenseReport($db);
614  $expensereportlinestatic = new ExpenseReportLine($db);
615 
616  foreach ($taber as $key => $val) {
617  $expensereportstatic->id = $key;
618  $expensereportstatic->ref = $val["ref"];
619  $expensereportlinestatic->comments = html_entity_decode(dol_trunc($val["comments"], 32));
620 
621  $date = dol_print_date($val["date"], 'day');
622 
623  if ($errorforinvoice[$key] == 'somelinesarenotbound') {
624  print '<tr class="oddeven">';
625  print "<!-- Some lines are not bound -->";
626  print "<td>".$date."</td>";
627  print "<td>".$expensereportstatic->getNomUrl(1)."</td>";
628  // Account
629  print "<td>";
630  print '<span class="error">'.$langs->trans('ErrorInvoiceContainsLinesNotYetBoundedShort', $val['ref']).'</span>';
631  print '</td>';
632  // Subledger account
633  print "<td>";
634  print '</td>';
635  print "<td>";
636  print "</td>";
637  print '<td class="right"></td>';
638  print '<td class="right"></td>';
639  print "</tr>";
640 
641  $i++;
642  }
643 
644  // Fees
645  foreach ($tabht[$key] as $k => $mt) {
646  $accountingaccount = new AccountingAccount($db);
647  $accountingaccount->fetch(null, $k, true);
648 
649  if ($mt) {
650  print '<tr class="oddeven">';
651  print "<!-- Fees -->";
652  print "<td>".$date."</td>";
653  print "<td>".$expensereportstatic->getNomUrl(1)."</td>";
654  $userstatic->id = $tabuser[$key]['id'];
655  $userstatic->name = $tabuser[$key]['name'];
656  // Account
657  print "<td>";
658  $accountoshow = length_accountg($k);
659  if (($accountoshow == "") || $accountoshow == 'NotDefined') {
660  print '<span class="error">'.$langs->trans("FeeAccountNotDefined").'</span>';
661  } else {
662  print $accountoshow;
663  }
664  print '</td>';
665  // Subledger account
666  print "<td>";
667  print '</td>';
668  $userstatic->id = $tabuser[$key]['id'];
669  $userstatic->name = $tabuser[$key]['name'];
670  print "<td>".$userstatic->getNomUrl(0, 'user', 16).' - '.$accountingaccount->label."</td>";
671  print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
672  print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
673  print "</tr>";
674 
675  $i++;
676  }
677  }
678 
679  // Third party
680  foreach ($tabttc[$key] as $k => $mt) {
681  $userstatic->id = $tabuser[$key]['id'];
682  $userstatic->name = $tabuser[$key]['name'];
683 
684  print '<tr class="oddeven">';
685  print "<!-- Thirdparty -->";
686  print "<td>".$date."</td>";
687  print "<td>".$expensereportstatic->getNomUrl(1)."</td>";
688  // Account
689  print "<td>";
690  $accountoshow = length_accountg($conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT);
691  if (($accountoshow == "") || $accountoshow == 'NotDefined') {
692  print '<span class="error">'.$langs->trans("MainAccountForUsersNotDefined").'</span>';
693  } else {
694  print $accountoshow;
695  }
696  print "</td>";
697  // Subledger account
698  print "<td>";
699  $accountoshow = length_accounta($k);
700  if (($accountoshow == "") || $accountoshow == 'NotDefined') {
701  print '<span class="error">'.$langs->trans("UserAccountNotDefined").'</span>';
702  } else {
703  print $accountoshow;
704  }
705  print '</td>';
706  print "<td>".$userstatic->getNomUrl(0, 'user', 16).' - '.$langs->trans("SubledgerAccount")."</td>";
707  print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
708  print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
709  print "</tr>";
710 
711  $i++;
712  }
713 
714  // VAT
715  $listoftax = array(0, 1, 2);
716  foreach ($listoftax as $numtax) {
717  $arrayofvat = $tabtva;
718  if ($numtax == 1) {
719  $arrayofvat = $tablocaltax1;
720  }
721  if ($numtax == 2) {
722  $arrayofvat = $tablocaltax2;
723  }
724 
725  foreach ($arrayofvat[$key] as $k => $mt) {
726  if ($mt) {
727  print '<tr class="oddeven">';
728  print "<!-- VAT -->";
729  print "<td>".$date."</td>";
730  print "<td>".$expensereportstatic->getNomUrl(1)."</td>";
731  // Account
732  print "<td>";
733  $accountoshow = length_accountg($k);
734  if (($accountoshow == "") || $accountoshow == 'NotDefined') {
735  print '<span class="error">'.$langs->trans("VATAccountNotDefined").'</span>';
736  } else {
737  print $accountoshow;
738  }
739  print "</td>";
740  // Subledger account
741  print "<td>";
742  print '</td>';
743  print "<td>".$userstatic->getNomUrl(0, 'user', 16).' - '.$langs->trans("VAT").' '.join(', ', $def_tva[$key][$k]).' %'.($numtax ? ' - Localtax '.$numtax : '');
744  print "</td>";
745  print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
746  print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
747  print "</tr>";
748 
749  $i++;
750  }
751  }
752  }
753  }
754 
755  if (!$i) {
756  $colspan = 7;
757  print '<tr class="oddeven"><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
758  }
759 
760  print "</table>";
761  print '</div>';
762 
763  // End of page
764  llxFooter();
765 }
766 $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:56
llxFooter()
Empty footer.
Definition: wrapper.php:70
Class to manage accounting accounts.
Class to manage accounting accounts.
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:48
if(isModEnabled('facture') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&empty($conf->global->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') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $sql
Social contributions to pay.
Definition: index.php:746
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
dol_get_first_day($year, $month=1, $gm=false)
Return GMT time for first day of a month or year.
Definition: date.lib.php:577
dol_get_last_day($year, $month=12, $gm=false)
Return GMT time for last day of a month or year.
Definition: date.lib.php:596
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.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
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.