dolibarr  16.0.1
card.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2004-2020 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2005-2009 Regis Houssin <regis.houssin@inodbox.com>
5  * Copyright (C) 2015-2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
6  * Copyright (C) 2017 Ferran Marcet <fmarcet@2byte.es>
7  * Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <https://www.gnu.org/licenses/>.
21  */
22 
29 require '../main.inc.php';
30 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formexpensereport.class.php';
31 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
32 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
33 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
34 require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
35 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
36 require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
37 require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
38 require_once DOL_DOCUMENT_ROOT.'/core/lib/expensereport.lib.php';
39 require_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
40 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
41 require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
42 require_once DOL_DOCUMENT_ROOT.'/core/modules/expensereport/modules_expensereport.php';
43 require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
44 require_once DOL_DOCUMENT_ROOT.'/expensereport/class/paymentexpensereport.class.php';
45 require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
46 require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
47 if (!empty($conf->accounting->enabled)) {
48  require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
49 }
50 
51 // Load translation files required by the page
52 $langs->loadLangs(array("trips", "bills", "mails"));
53 
54 $action = GETPOST('action', 'aZ09');
55 $cancel = GETPOST('cancel', 'alpha');
56 $confirm = GETPOST('confirm', 'alpha');
57 
58 $id = GETPOST('id', 'int');
59 $date_start = dol_mktime(0, 0, 0, GETPOST('date_debutmonth', 'int'), GETPOST('date_debutday', 'int'), GETPOST('date_debutyear', 'int'));
60 $date_end = dol_mktime(0, 0, 0, GETPOST('date_finmonth', 'int'), GETPOST('date_finday', 'int'), GETPOST('date_finyear', 'int'));
61 $date = dol_mktime(0, 0, 0, GETPOST('datemonth', 'int'), GETPOST('dateday', 'int'), GETPOST('dateyear', 'int'));
62 $fk_project = GETPOST('fk_project', 'int');
63 $vatrate = GETPOST('vatrate', 'alpha');
64 $ref = GETPOST("ref", 'alpha');
65 $comments = GETPOST('comments', 'restricthtml');
66 $fk_c_type_fees = GETPOST('fk_c_type_fees', 'int');
67 $socid = GETPOST('socid', 'int') ?GETPOST('socid', 'int') : GETPOST('socid_id', 'int');
68 
69 $childids = $user->getAllChildIds(1);
70 
71 if (! empty($conf->global->EXPENSEREPORT_PREFILL_DATES_WITH_CURRENT_MONTH)) {
72  if (empty($date_start)) {
73  $date_start = dol_mktime(0, 0, 0, (int) dol_print_date(dol_now(), '%m'), 1, (int) dol_print_date(dol_now(), '%Y'));
74  }
75 
76  if (empty($date_end)) {
77  // date('t') => number of days in the month, so last day of the month too
78  $date_end = dol_mktime(0, 0, 0, (int) dol_print_date(dol_now(), '%m'), (int) date('t'), (int) dol_print_date(dol_now(), '%Y'));
79  }
80 }
81 
82 // Hack to use expensereport dir
83 $rootfordata = DOL_DATA_ROOT;
84 $rootforuser = DOL_DATA_ROOT;
85 // If multicompany module is enabled, we redefine the root of data
86 if (!empty($conf->multicompany->enabled) && !empty($conf->entity) && $conf->entity > 1) {
87  $rootfordata .= '/'.$conf->entity;
88 }
89 $conf->expensereport->dir_output = $rootfordata.'/expensereport';
90 
91 // Define $urlwithroot
92 $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
93 $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
94 //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
95 
96 // PDF
97 $hidedetails = (GETPOST('hidedetails', 'int') ? GETPOST('hidedetails', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0));
98 $hidedesc = (GETPOST('hidedesc', 'int') ? GETPOST('hidedesc', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0));
99 $hideref = (GETPOST('hideref', 'int') ? GETPOST('hideref', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0));
100 
101 
102 $object = new ExpenseReport($db);
103 $extrafields = new ExtraFields($db);
104 
105 // fetch optionals attributes and labels
106 $extrafields->fetch_name_optionals_label($object->table_element);
107 
108 // Load object
109 include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once
110 
111 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
112 $hookmanager->initHooks(array('expensereportcard', 'globalcard'));
113 
114 $permissionnote = $user->rights->expensereport->creer; // Used by the include of actions_setnotes.inc.php
115 $permissiondellink = $user->rights->expensereport->creer; // Used by the include of actions_dellink.inc.php
116 $permissiontoadd = $user->rights->expensereport->creer; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
117 
118 $upload_dir = $conf->expensereport->dir_output.'/'.dol_sanitizeFileName($object->ref);
119 
120 $projectRequired = $conf->project->enabled && ! empty($conf->global->EXPENSEREPORT_PROJECT_IS_REQUIRED);
121 $fileRequired = !empty($conf->global->EXPENSEREPORT_FILE_IS_REQUIRED);
122 
123 if ($object->id > 0) {
124  // Check current user can read this expense report
125  $canread = 0;
126  if (!empty($user->rights->expensereport->readall)) {
127  $canread = 1;
128  }
129  if (!empty($user->rights->expensereport->lire) && in_array($object->fk_user_author, $childids)) {
130  $canread = 1;
131  }
132  if (!$canread) {
133  accessforbidden();
134  }
135 }
136 
137 $candelete = 0;
138 if (!empty($user->rights->expensereport->supprimer)) {
139  $candelete = 1;
140 }
141 if ($object->statut == ExpenseReport::STATUS_DRAFT && $user->hasRight('expensereport', 'write') && in_array($object->fk_user_author, $childids)) {
142  $candelete = 1;
143 }
144 
145 // Security check
146 if ($user->socid) {
147  $socid = $user->socid;
148 }
149 $result = restrictedArea($user, 'expensereport', $object->id, 'expensereport');
150 
151 $permissiontoadd = $user->rights->expensereport->creer; // Used by the include of actions_dellink.inc.php
152 
153 
154 /*
155  * Actions
156  */
157 
158 $parameters = array('socid' => $socid);
159 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
160 if ($reshook < 0) {
161  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
162 }
163 
164 if (empty($reshook)) {
165  $backurlforlist = DOL_URL_ROOT.'/expensereport/list.php';
166 
167  if (empty($backtopage) || ($cancel && empty($id))) {
168  if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
169  if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
170  $backtopage = $backurlforlist;
171  } else {
172  $backtopage = DOL_URL_ROOT.'/expensereport/card.php?id='.((!empty($id) && $id > 0) ? $id : '__ID__');
173  }
174  }
175  }
176 
177  if ($cancel) {
178  if (!empty($backtopageforcancel)) {
179  header("Location: ".$backtopageforcancel);
180  exit;
181  } elseif (!empty($backtopage)) {
182  header("Location: ".$backtopage);
183  exit;
184  }
185  $action = '';
186 
187  $fk_project = '';
188  $date_start = '';
189  $date_end = '';
190  $date = '';
191  $comments = '';
192  $vatrate = '';
193  $value_unit_ht = '';
194  $value_unit = '';
195  $qty = 1;
196  $fk_c_type_fees = -1;
197  }
198 
199  include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php';
200 
201  if (!empty(GETPOST('sendit', 'alpha'))) { // If we just submit a file
202  if ($action == 'updateline') {
203  $action = 'editline'; // To avoid to make the updateline now
204  } else {
205  $action = ''; // To avoid to make the addline now
206  }
207  }
208 
209  include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not include_once
210 
211  include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once
212 
213  include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php'; // Must be include, not include_once
214 
215  // Action clone object
216  if ($action == 'confirm_clone' && $confirm == 'yes' && $user->rights->expensereport->creer) {
217  if (1 == 0 && !GETPOST('clone_content', 'alpha') && !GETPOST('clone_receivers', 'alpha')) {
218  setEventMessages($langs->trans("NoCloneOptionsSpecified"), null, 'errors');
219  } else {
220  if ($object->id > 0) {
221  // Because createFromClone modifies the object, we must clone it so that we can restore it later if it fails
222  $orig = clone $object;
223 
224  $result = $object->createFromClone($user, GETPOST('fk_user_author', 'int'));
225  if ($result > 0) {
226  header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result);
227  exit;
228  } else {
229  setEventMessages($object->error, $object->errors, 'errors');
230  $object = $orig;
231  $action = '';
232  }
233  }
234  }
235  }
236 
237  if ($action == 'confirm_delete' && GETPOST("confirm", 'alpha') == "yes" && $id > 0 && $candelete) {
238  $object = new ExpenseReport($db);
239  $result = $object->fetch($id);
240  $result = $object->delete($user);
241  if ($result >= 0) {
242  header("Location: index.php");
243  exit;
244  } else {
245  setEventMessages($object->error, $object->errors, 'errors');
246  }
247  }
248 
249  if ($action == 'add' && $user->rights->expensereport->creer) {
250  $error = 0;
251 
252  $object = new ExpenseReport($db);
253 
254  $object->date_debut = $date_start;
255  $object->date_fin = $date_end;
256 
257  $object->fk_user_author = GETPOST('fk_user_author', 'int');
258  if (!($object->fk_user_author > 0)) {
259  $object->fk_user_author = $user->id;
260  }
261 
262  // Check that expense report is for a user inside the hierarchy, or that advanced permission for all is set
263  if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->expensereport->creer))
264  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->expensereport->creer) && empty($user->rights->expensereport->writeall_advance))) {
265  $error++;
266  setEventMessages($langs->trans("NotEnoughPermissions"), null, 'errors');
267  }
268  if (!$error) {
269  if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || empty($user->rights->expensereport->writeall_advance)) {
270  if (!in_array($object->fk_user_author, $childids)) {
271  $error++;
272  setEventMessages($langs->trans("UserNotInHierachy"), null, 'errors');
273  }
274  }
275  }
276 
277  $fuser = new User($db);
278  $fuser->fetch($object->fk_user_author);
279 
280  $object->status = 1;
281  $object->fk_c_paiement = GETPOST('fk_c_paiement', 'int');
282  $object->fk_user_validator = GETPOST('fk_user_validator', 'int');
283  $object->note_public = GETPOST('note_public', 'restricthtml');
284  $object->note_private = GETPOST('note_private', 'restricthtml');
285  // Fill array 'array_options' with data from add form
286  if (!$error) {
287  $ret = $extrafields->setOptionalsFromPost(null, $object);
288  if ($ret < 0) {
289  $error++;
290  }
291  }
292 
293  if (!$error && empty($conf->global->EXPENSEREPORT_ALLOW_OVERLAPPING_PERIODS)) {
294  $overlappingExpenseReportID = $object->periode_existe($fuser, $object->date_debut, $object->date_fin, true);
295 
296  if ($overlappingExpenseReportID > 0) {
297  $error++;
298  setEventMessages($langs->trans("ErrorDoubleDeclaration").' <a href="'.$_SERVER['PHP_SELF'].'?id='.$overlappingExpenseReportID.'">'. $langs->trans('ShowTrip').'</a>', null, 'errors');
299  $action = 'create';
300  }
301  }
302 
303  if (!$error) {
304  $db->begin();
305 
306  $id = $object->create($user);
307  if ($id <= 0) {
308  $error++;
309  }
310 
311  if (!$error) {
312  $db->commit();
313  Header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id);
314  exit;
315  } else {
316  setEventMessages($object->error, $object->errors, 'errors');
317  $db->rollback();
318  $action = 'create';
319  }
320  }
321  }
322 
323  if ($action == 'update' && $user->rights->expensereport->creer) {
324  $object = new ExpenseReport($db);
325  $object->fetch($id);
326 
327  $object->date_debut = $date_start;
328  $object->date_fin = $date_end;
329 
330  if ($object->status < 3) {
331  $object->fk_user_validator = GETPOST('fk_user_validator', 'int');
332  }
333 
334  $object->fk_c_paiement = GETPOST('fk_c_paiement', 'int');
335  $object->note_public = GETPOST('note_public', 'restricthtml');
336  $object->note_private = GETPOST('note_private', 'restricthtml');
337  $object->fk_user_modif = $user->id;
338 
339  $result = $object->update($user);
340  if ($result > 0) {
341  header("Location: ".$_SERVER["PHP_SELF"]."?id=".GETPOST('id', 'int'));
342  exit;
343  } else {
344  setEventMessages($object->error, $object->errors, 'errors');
345  }
346  }
347 
348  if ($action == 'update_extras') {
349  $object->oldcopy = dol_clone($object);
350 
351  // Fill array 'array_options' with data from update form
352  $ret = $extrafields->setOptionalsFromPost(null, $object, GETPOST('attribute', 'restricthtml'));
353  if ($ret < 0) {
354  $error++;
355  }
356 
357  if (!$error) {
358  // Actions on extra fields
359  $result = $object->insertExtraFields('EXPENSEREPORT_MODIFY');
360  if ($result < 0) {
361  setEventMessages($object->error, $object->errors, 'errors');
362  $error++;
363  }
364  }
365 
366  if ($error) {
367  $action = 'edit_extras';
368  }
369  }
370 
371  if ($action == "confirm_validate" && GETPOST("confirm", 'alpha') == "yes" && $id > 0 && $user->rights->expensereport->creer) {
372  $error = 0;
373 
374  $db->begin();
375 
376  $object = new ExpenseReport($db);
377  $object->fetch($id);
378 
379  $result = $object->setValidate($user);
380 
381  if ($result >= 0) {
382  // Define output language
383  if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
384  $outputlangs = $langs;
385  $newlang = '';
386  if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
387  $newlang = GETPOST('lang_id', 'aZ09');
388  }
389  if ($conf->global->MAIN_MULTILANGS && empty($newlang)) {
390  $newlang = $object->thirdparty->default_lang;
391  }
392  if (!empty($newlang)) {
393  $outputlangs = new Translate("", $conf);
394  $outputlangs->setDefaultLang($newlang);
395  }
396  $model = $object->model_pdf;
397  $ret = $object->fetch($id); // Reload to get new records
398 
399  $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
400  }
401  } else {
402  setEventMessages($object->error, $object->errors, 'errors');
403  $error++;
404  }
405 
406  if (!$error && $result > 0 && $object->fk_user_validator > 0) {
407  $langs->load("mails");
408 
409  // TO
410  $destinataire = new User($db);
411  $destinataire->fetch($object->fk_user_validator);
412  $emailTo = $destinataire->email;
413 
414  // FROM
415  $expediteur = new User($db);
416  $expediteur->fetch($object->fk_user_author);
417  $emailFrom = $expediteur->email;
418 
419  if ($emailTo && $emailFrom) {
420  $filename = array(); $filedir = array(); $mimetype = array();
421 
422  // SUBJECT
423  $societeName = $conf->global->MAIN_INFO_SOCIETE_NOM;
424  if (!empty($conf->global->MAIN_APPLICATION_TITLE)) {
425  $societeName = $conf->global->MAIN_APPLICATION_TITLE;
426  }
427 
428  $subject = $societeName." - ".$langs->transnoentities("ExpenseReportWaitingForApproval");
429 
430  // CONTENT
431  $link = $urlwithroot.'/expensereport/card.php?id='.$object->id;
432  $link = '<a href="'.$link.'">'.$link.'</a>';
433  $message = $langs->transnoentities("ExpenseReportWaitingForApprovalMessage", $expediteur->getFullName($langs), get_date_range($object->date_debut, $object->date_fin, '', $langs), $link);
434 
435  // Rebuild pdf
436  /*
437  $object->setDocModel($user,"");
438  $resultPDF = expensereport_pdf_create($db,$id,'',"",$langs);
439 
440  if($resultPDF):
441  // ATTACHMENT
442  array_push($filename,dol_sanitizeFileName($object->ref).".pdf");
443  array_push($filedir,$conf->expensereport->dir_output . "/" . dol_sanitizeFileName($object->ref) . "/" . dol_sanitizeFileName($object->ref).".pdf");
444  array_push($mimetype,"application/pdf");
445  */
446 
447  // PREPARE SEND
448  $mailfile = new CMailFile($subject, $emailTo, $emailFrom, $message, $filedir, $mimetype, $filename, '', '', 0, -1);
449 
450  if ($mailfile) {
451  // SEND
452  $result = $mailfile->sendfile();
453  if ($result) {
454  $mesg = $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($emailFrom, 2), $mailfile->getValidAddress($emailTo, 2));
455  setEventMessages($mesg, null, 'mesgs');
456  } else {
457  $langs->load("other");
458  if ($mailfile->error) {
459  $mesg = '';
460  $mesg .= $langs->trans('ErrorFailedToSendMail', $emailFrom, $emailTo);
461  $mesg .= '<br>'.$mailfile->error;
462  setEventMessages($mesg, null, 'errors');
463  } else {
464  setEventMessages('No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS', null, 'warnings');
465  }
466  }
467  } else {
468  setEventMessages($mailfile->error, $mailfile->errors, 'errors');
469  $action = '';
470  }
471  } else {
472  setEventMessages($langs->trans("NoEmailSentBadSenderOrRecipientEmail"), null, 'warnings');
473  $action = '';
474  }
475  }
476 
477  if (!$error) {
478  $db->commit();
479  header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id);
480  exit;
481  } else {
482  $db->rollback();
483  }
484  }
485 
486  if ($action == "confirm_save_from_refuse" && GETPOST("confirm", 'alpha') == "yes" && $id > 0 && $user->rights->expensereport->creer) {
487  $object = new ExpenseReport($db);
488  $object->fetch($id);
489  $result = $object->set_save_from_refuse($user);
490 
491  if ($result > 0) {
492  // Define output language
493  if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
494  $outputlangs = $langs;
495  $newlang = '';
496  if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
497  $newlang = GETPOST('lang_id', 'aZ09');
498  }
499  if ($conf->global->MAIN_MULTILANGS && empty($newlang)) {
500  $newlang = $object->thirdparty->default_lang;
501  }
502  if (!empty($newlang)) {
503  $outputlangs = new Translate("", $conf);
504  $outputlangs->setDefaultLang($newlang);
505  }
506  $model = $object->model_pdf;
507  $ret = $object->fetch($id); // Reload to get new records
508 
509  $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
510  }
511  }
512 
513  if ($result > 0) {
514  // Send mail
515 
516  // TO
517  $destinataire = new User($db);
518  $destinataire->fetch($object->fk_user_validator);
519  $emailTo = $destinataire->email;
520 
521  // FROM
522  $expediteur = new User($db);
523  $expediteur->fetch($object->fk_user_author);
524  $emailFrom = $expediteur->email;
525 
526  if ($emailFrom && $emailTo) {
527  $filename = array(); $filedir = array(); $mimetype = array();
528 
529  // SUBJECT
530  $societeName = $conf->global->MAIN_INFO_SOCIETE_NOM;
531  if (!empty($conf->global->MAIN_APPLICATION_TITLE)) {
532  $societeName = $conf->global->MAIN_APPLICATION_TITLE;
533  }
534 
535  $subject = $societeName." - ".$langs->transnoentities("ExpenseReportWaitingForReApproval");
536 
537  // CONTENT
538  $link = $urlwithroot.'/expensereport/card.php?id='.$object->id;
539  $link = '<a href="'.$link.'">'.$link.'</a>';
540  $dateRefusEx = explode(" ", $object->date_refuse);
541  $message = $langs->transnoentities("ExpenseReportWaitingForReApprovalMessage", $dateRefusEx[0], $object->detail_refuse, $expediteur->getFullName($langs), $link);
542 
543  // Rebuild pdf
544  /*
545  $object->setDocModel($user,"");
546  $resultPDF = expensereport_pdf_create($db,$object,'',"",$langs);
547 
548  if($resultPDF)
549  {
550  // ATTACHMENT
551  $filename=array(); $filedir=array(); $mimetype=array();
552  array_push($filename,dol_sanitizeFileName($object->ref).".pdf");
553  array_push($filedir,$conf->expensereport->dir_output . "/" . dol_sanitizeFileName($object->ref) . "/" . dol_sanitizeFileName($object->ref_number).".pdf");
554  array_push($mimetype,"application/pdf");
555  }
556  */
557 
558 
559  // PREPARE SEND
560  $mailfile = new CMailFile($subject, $emailTo, $emailFrom, $message, $filedir, $mimetype, $filename, '', '', 0, -1);
561 
562  if ($mailfile) {
563  // SEND
564  $result = $mailfile->sendfile();
565  if ($result) {
566  $mesg = $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($emailFrom, 2), $mailfile->getValidAddress($emailTo, 2));
567  setEventMessages($mesg, null, 'mesgs');
568  header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id);
569  exit;
570  } else {
571  $langs->load("other");
572  if ($mailfile->error) {
573  $mesg = '';
574  $mesg .= $langs->trans('ErrorFailedToSendMail', $emailFrom, $emailTo);
575  $mesg .= '<br>'.$mailfile->error;
576  setEventMessages($mesg, null, 'errors');
577  } else {
578  setEventMessages('No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS', null, 'warnings');
579  }
580  }
581  } else {
582  setEventMessages($mailfile->error, $mailfile->errors, 'errors');
583  $action = '';
584  }
585  } else {
586  setEventMessages($langs->trans("NoEmailSentBadSenderOrRecipientEmail"), null, 'warnings');
587  $action = '';
588  }
589  } else {
590  setEventMessages($object->error, $object->errors, 'errors');
591  }
592  }
593 
594  // Approve
595  if ($action == "confirm_approve" && GETPOST("confirm", 'alpha') == "yes" && $id > 0 && $user->rights->expensereport->approve) {
596  $object = new ExpenseReport($db);
597  $object->fetch($id);
598 
599  $result = $object->setApproved($user);
600 
601  if ($result > 0) {
602  // Define output language
603  if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
604  $outputlangs = $langs;
605  $newlang = '';
606  if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
607  $newlang = GETPOST('lang_id', 'aZ09');
608  }
609  if ($conf->global->MAIN_MULTILANGS && empty($newlang)) {
610  $newlang = $object->thirdparty->default_lang;
611  }
612  if (!empty($newlang)) {
613  $outputlangs = new Translate("", $conf);
614  $outputlangs->setDefaultLang($newlang);
615  }
616  $model = $object->model_pdf;
617  $ret = $object->fetch($id); // Reload to get new records
618 
619  $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
620  }
621  }
622 
623  if ($result > 0) {
624  // Send mail
625 
626  // TO
627  $destinataire = new User($db);
628  $destinataire->fetch($object->fk_user_author);
629  $emailTo = $destinataire->email;
630 
631  // CC
632  $emailCC = $conf->global->NDF_CC_EMAILS;
633  if (empty($emailTo)) {
634  $emailTo = $emailCC;
635  }
636 
637  // FROM
638  $expediteur = new User($db);
639  $expediteur->fetch($object->fk_user_approve > 0 ? $object->fk_user_approve : $object->fk_user_validator);
640  $emailFrom = $expediteur->email;
641 
642  if ($emailFrom && $emailTo) {
643  $filename = array(); $filedir = array(); $mimetype = array();
644 
645  // SUBJECT
646  $societeName = $conf->global->MAIN_INFO_SOCIETE_NOM;
647  if (!empty($conf->global->MAIN_APPLICATION_TITLE)) {
648  $societeName = $conf->global->MAIN_APPLICATION_TITLE;
649  }
650 
651  $subject = $societeName." - ".$langs->transnoentities("ExpenseReportApproved");
652 
653  // CONTENT
654  $link = $urlwithroot.'/expensereport/card.php?id='.$object->id;
655  $link = '<a href="'.$link.'">'.$link.'</a>';
656  $message = $langs->transnoentities("ExpenseReportApprovedMessage", $object->ref, $destinataire->getFullName($langs), $expediteur->getFullName($langs), $link);
657 
658  // Rebuilt pdf
659  /*
660  $object->setDocModel($user,"");
661  $resultPDF = expensereport_pdf_create($db,$object,'',"",$langs);
662 
663  if($resultPDF
664  {
665  // ATTACHMENT
666  $filename=array(); $filedir=array(); $mimetype=array();
667  array_push($filename,dol_sanitizeFileName($object->ref).".pdf");
668  array_push($filedir, $conf->expensereport->dir_output."/".dol_sanitizeFileName($object->ref)."/".dol_sanitizeFileName($object->ref).".pdf");
669  array_push($mimetype,"application/pdf");
670  }
671  */
672 
673  $mailfile = new CMailFile($subject, $emailTo, $emailFrom, $message, $filedir, $mimetype, $filename, '', '', 0, -1);
674 
675  if ($mailfile) {
676  // SEND
677  $result = $mailfile->sendfile();
678  if ($result) {
679  $mesg = $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($emailFrom, 2), $mailfile->getValidAddress($emailTo, 2));
680  setEventMessages($mesg, null, 'mesgs');
681  header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id);
682  exit;
683  } else {
684  $langs->load("other");
685  if ($mailfile->error) {
686  $mesg = '';
687  $mesg .= $langs->trans('ErrorFailedToSendMail', $emailFrom, $emailTo);
688  $mesg .= '<br>'.$mailfile->error;
689  setEventMessages($mesg, null, 'errors');
690  } else {
691  setEventMessages('No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS', null, 'warnings');
692  }
693  }
694  } else {
695  setEventMessages($mailfile->error, $mailfile->errors, 'errors');
696  $action = '';
697  }
698  } else {
699  setEventMessages($langs->trans("NoEmailSentBadSenderOrRecipientEmail"), null, 'warnings');
700  $action = '';
701  }
702  } else {
703  setEventMessages($langs->trans("FailedtoSetToApprove"), null, 'warnings');
704  $action = '';
705  }
706  }
707 
708  if ($action == "confirm_refuse" && GETPOST('confirm', 'alpha') == "yes" && $id > 0 && $user->rights->expensereport->approve) {
709  $object = new ExpenseReport($db);
710  $object->fetch($id);
711 
712  $detailRefuse = GETPOST('detail_refuse', 'alpha');
713  $result = $object->setDeny($user, $detailRefuse);
714 
715  if ($result > 0) {
716  // Define output language
717  if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
718  $outputlangs = $langs;
719  $newlang = '';
720  if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
721  $newlang = GETPOST('lang_id', 'aZ09');
722  }
723  if ($conf->global->MAIN_MULTILANGS && empty($newlang)) {
724  $newlang = $object->thirdparty->default_lang;
725  }
726  if (!empty($newlang)) {
727  $outputlangs = new Translate("", $conf);
728  $outputlangs->setDefaultLang($newlang);
729  }
730  $model = $object->model_pdf;
731  $ret = $object->fetch($id); // Reload to get new records
732 
733  $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
734  }
735  }
736 
737  if ($result > 0) {
738  // Send mail
739 
740  // TO
741  $destinataire = new User($db);
742  $destinataire->fetch($object->fk_user_author);
743  $emailTo = $destinataire->email;
744 
745  // FROM
746  $expediteur = new User($db);
747  $expediteur->fetch($object->fk_user_refuse);
748  $emailFrom = $expediteur->email;
749 
750  if ($emailFrom && $emailTo) {
751  $filename = array(); $filedir = array(); $mimetype = array();
752 
753  // SUBJECT
754  $societeName = $conf->global->MAIN_INFO_SOCIETE_NOM;
755  if (!empty($conf->global->MAIN_APPLICATION_TITLE)) {
756  $societeName = $conf->global->MAIN_APPLICATION_TITLE;
757  }
758 
759  $subject = $societeName." - ".$langs->transnoentities("ExpenseReportRefused");
760 
761  // CONTENT
762  $link = $urlwithroot.'/expensereport/card.php?id='.$object->id;
763  $link = '<a href="'.$link.'">'.$link.'</a>';
764  $message = $langs->transnoentities("ExpenseReportRefusedMessage", $object->ref, $destinataire->getFullName($langs), $expediteur->getFullName($langs), $detailRefuse, $link);
765 
766  // Rebuilt pdf
767  /*
768  $object->setDocModel($user,"");
769  $resultPDF = expensereport_pdf_create($db,$object,'',"",$langs);
770 
771  if($resultPDF
772  {
773  // ATTACHMENT
774  $filename=array(); $filedir=array(); $mimetype=array();
775  array_push($filename,dol_sanitizeFileName($object->ref).".pdf");
776  array_push($filedir, $conf->expensereport->dir_output."/".dol_sanitizeFileName($object->ref)."/".dol_sanitizeFileName($object->ref).".pdf");
777  array_push($mimetype,"application/pdf");
778  }
779  */
780 
781  // PREPARE SEND
782  $mailfile = new CMailFile($subject, $emailTo, $emailFrom, $message, $filedir, $mimetype, $filename, '', '', 0, -1);
783 
784  if ($mailfile) {
785  // SEND
786  $result = $mailfile->sendfile();
787  if ($result) {
788  $mesg = $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($emailFrom, 2), $mailfile->getValidAddress($emailTo, 2));
789  setEventMessages($mesg, null, 'mesgs');
790  header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id);
791  exit;
792  } else {
793  $langs->load("other");
794  if ($mailfile->error) {
795  $mesg = '';
796  $mesg .= $langs->trans('ErrorFailedToSendMail', $emailFrom, $emailTo);
797  $mesg .= '<br>'.$mailfile->error;
798  setEventMessages($mesg, null, 'errors');
799  } else {
800  setEventMessages('No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS', null, 'warnings');
801  }
802  }
803  } else {
804  setEventMessages($mailfile->error, $mailfile->errors, 'errors');
805  $action = '';
806  }
807  } else {
808  setEventMessages($langs->trans("NoEmailSentBadSenderOrRecipientEmail"), null, 'warnings');
809  $action = '';
810  }
811  } else {
812  setEventMessages($langs->trans("FailedtoSetToDeny"), null, 'warnings');
813  $action = '';
814  }
815  }
816 
817  //var_dump($user->id == $object->fk_user_validator);exit;
818  if ($action == "confirm_cancel" && GETPOST('confirm', 'alpha') == "yes" && $id > 0 && $user->rights->expensereport->creer) {
819  if (!GETPOST('detail_cancel', 'alpha')) {
820  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Comment")), null, 'errors');
821  } else {
822  $object = new ExpenseReport($db);
823  $object->fetch($id);
824 
825  if ($user->id == $object->fk_user_valid || $user->id == $object->fk_user_author) {
826  $detailCancel = GETPOST('detail_cancel', 'alpha');
827  $result = $object->set_cancel($user, $detailCancel);
828 
829  if ($result > 0) {
830  // Define output language
831  if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
832  $outputlangs = $langs;
833  $newlang = '';
834  if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
835  $newlang = GETPOST('lang_id', 'aZ09');
836  }
837  if ($conf->global->MAIN_MULTILANGS && empty($newlang)) {
838  $newlang = $object->thirdparty->default_lang;
839  }
840  if (!empty($newlang)) {
841  $outputlangs = new Translate("", $conf);
842  $outputlangs->setDefaultLang($newlang);
843  }
844  $model = $object->model_pdf;
845  $ret = $object->fetch($id); // Reload to get new records
846 
847  $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
848  }
849  }
850 
851  if ($result > 0) {
852  // Send mail
853 
854  // TO
855  $destinataire = new User($db);
856  $destinataire->fetch($object->fk_user_author);
857  $emailTo = $destinataire->email;
858 
859  // FROM
860  $expediteur = new User($db);
861  $expediteur->fetch($object->fk_user_cancel);
862  $emailFrom = $expediteur->email;
863 
864  if ($emailFrom && $emailTo) {
865  $filename = array(); $filedir = array(); $mimetype = array();
866 
867  // SUBJECT
868  $societeName = $conf->global->MAIN_INFO_SOCIETE_NOM;
869  if (!empty($conf->global->MAIN_APPLICATION_TITLE)) {
870  $societeName = $conf->global->MAIN_APPLICATION_TITLE;
871  }
872 
873  $subject = $societeName." - ".$langs->transnoentities("ExpenseReportCanceled");
874 
875  // CONTENT
876  $link = $urlwithroot.'/expensereport/card.php?id='.$object->id;
877  $link = '<a href="'.$link.'">'.$link.'</a>';
878  $message = $langs->transnoentities("ExpenseReportCanceledMessage", $object->ref, $destinataire->getFullName($langs), $expediteur->getFullName($langs), $detailCancel, $link);
879 
880  // Rebuilt pdf
881  /*
882  $object->setDocModel($user,"");
883  $resultPDF = expensereport_pdf_create($db,$object,'',"",$langs);
884 
885  if($resultPDF
886  {
887  // ATTACHMENT
888  $filename=array(); $filedir=array(); $mimetype=array();
889  array_push($filename,dol_sanitizeFileName($object->ref).".pdf");
890  array_push($filedir, $conf->expensereport->dir_output."/".dol_sanitizeFileName($object->ref)."/".dol_sanitizeFileName($object->ref).".pdf");
891  array_push($mimetype,"application/pdf");
892  }
893  */
894 
895  // PREPARE SEND
896  $mailfile = new CMailFile($subject, $emailTo, $emailFrom, $message, $filedir, $mimetype, $filename, '', '', 0, -1);
897 
898  if ($mailfile) {
899  // SEND
900  $result = $mailfile->sendfile();
901  if ($result) {
902  $mesg = $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($emailFrom, 2), $mailfile->getValidAddress($emailTo, 2));
903  setEventMessages($mesg, null, 'mesgs');
904  header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id);
905  exit;
906  } else {
907  $langs->load("other");
908  if ($mailfile->error) {
909  $mesg = '';
910  $mesg .= $langs->trans('ErrorFailedToSendMail', $emailFrom, $emailTo);
911  $mesg .= '<br>'.$mailfile->error;
912  setEventMessages($mesg, null, 'errors');
913  } else {
914  setEventMessages('No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS', null, 'warnings');
915  }
916  }
917  } else {
918  setEventMessages($mailfile->error, $mailfile->errors, 'errors');
919  $action = '';
920  }
921  } else {
922  setEventMessages($langs->trans("NoEmailSentBadSenderOrRecipientEmail"), null, 'warnings');
923  $action = '';
924  }
925  } else {
926  setEventMessages($langs->trans("FailedToSetToCancel"), null, 'warnings');
927  $action = '';
928  }
929  } else {
930  setEventMessages($object->error, $object->errors, 'errors');
931  }
932  }
933  }
934 
935  if ($action == "confirm_setdraft" && GETPOST('confirm', 'alpha') == "yes" && $id > 0 && $user->rights->expensereport->creer) {
936  $object = new ExpenseReport($db);
937  $object->fetch($id);
938  if ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) {
939  $result = $object->setStatut(0);
940 
941  if ($result > 0) {
942  // Define output language
943  if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
944  $outputlangs = $langs;
945  $newlang = '';
946  if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
947  $newlang = GETPOST('lang_id', 'aZ09');
948  }
949  if ($conf->global->MAIN_MULTILANGS && empty($newlang)) {
950  $newlang = $object->thirdparty->default_lang;
951  }
952  if (!empty($newlang)) {
953  $outputlangs = new Translate("", $conf);
954  $outputlangs->setDefaultLang($newlang);
955  }
956  $model = $object->model_pdf;
957  $ret = $object->fetch($id); // Reload to get new records
958 
959  $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
960  }
961  }
962 
963  if ($result > 0) {
964  header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id);
965  exit;
966  } else {
967  setEventMessages($object->error, $object->errors, 'errors');
968  }
969  } else {
970  setEventMessages("NOT_AUTHOR", '', 'errors');
971  }
972  }
973 
974  if ($action == 'set_unpaid' && $id > 0 && $user->rights->expensereport->to_paid) {
975  $object = new ExpenseReport($db);
976  $object->fetch($id);
977 
978  $result = $object->setUnpaid($user);
979 
980  if ($result > 0) {
981  // Define output language
982  if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
983  $outputlangs = $langs;
984  $newlang = '';
985  if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
986  $newlang = GETPOST('lang_id', 'aZ09');
987  }
988  if ($conf->global->MAIN_MULTILANGS && empty($newlang)) {
989  $newlang = $object->thirdparty->default_lang;
990  }
991  if (!empty($newlang)) {
992  $outputlangs = new Translate("", $conf);
993  $outputlangs->setDefaultLang($newlang);
994  }
995  $model = $object->model_pdf;
996  $ret = $object->fetch($id); // Reload to get new records
997 
998  $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
999  }
1000  }
1001  }
1002 
1003  if ($action == 'set_paid' && $id > 0 && $user->rights->expensereport->to_paid) {
1004  $object = new ExpenseReport($db);
1005  $object->fetch($id);
1006 
1007  $result = $object->setPaid($id, $user);
1008 
1009  if ($result > 0) {
1010  // Define output language
1011  if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
1012  $outputlangs = $langs;
1013  $newlang = '';
1014  if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
1015  $newlang = GETPOST('lang_id', 'aZ09');
1016  }
1017  if ($conf->global->MAIN_MULTILANGS && empty($newlang)) {
1018  $newlang = $object->thirdparty->default_lang;
1019  }
1020  if (!empty($newlang)) {
1021  $outputlangs = new Translate("", $conf);
1022  $outputlangs->setDefaultLang($newlang);
1023  }
1024  $model = $object->model_pdf;
1025  $ret = $object->fetch($id); // Reload to get new records
1026 
1027  $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
1028  }
1029  }
1030 
1031  if ($result > 0) {
1032  // Send mail
1033 
1034  // TO
1035  $destinataire = new User($db);
1036  $destinataire->fetch($object->fk_user_author);
1037  $emailTo = $destinataire->email;
1038 
1039  // FROM
1040  $expediteur = new User($db);
1041  $expediteur->fetch($user->id);
1042  $emailFrom = $expediteur->email;
1043 
1044  if ($emailFrom && $emailTo) {
1045  $filename = array(); $filedir = array(); $mimetype = array();
1046 
1047  // SUBJECT
1048  $societeName = $conf->global->MAIN_INFO_SOCIETE_NOM;
1049  if (!empty($conf->global->MAIN_APPLICATION_TITLE)) {
1050  $societeName = $conf->global->MAIN_APPLICATION_TITLE;
1051  }
1052 
1053  $subject = $societeName." - ".$langs->transnoentities("ExpenseReportPaid");
1054 
1055  // CONTENT
1056  $link = $urlwithroot.'/expensereport/card.php?id='.$object->id;
1057  $link = '<a href="'.$link.'">'.$link.'</a>';
1058  $message = $langs->transnoentities("ExpenseReportPaidMessage", $object->ref, $destinataire->getFullName($langs), $expediteur->getFullName($langs), $link);
1059 
1060  // Generate pdf before attachment
1061  $object->setDocModel($user, "");
1062  $resultPDF = expensereport_pdf_create($db, $object, '', "", $langs);
1063 
1064  // PREPARE SEND
1065  $mailfile = new CMailFile($subject, $emailTo, $emailFrom, $message, $filedir, $mimetype, $filename, '', '', 0, -1);
1066 
1067  if ($mailfile) {
1068  // SEND
1069  $result = $mailfile->sendfile();
1070  if ($result) {
1071  $mesg = $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($emailFrom, 2), $mailfile->getValidAddress($emailTo, 2));
1072  setEventMessages($mesg, null, 'mesgs');
1073  header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id);
1074  exit;
1075  } else {
1076  $langs->load("other");
1077  if ($mailfile->error) {
1078  $mesg = '';
1079  $mesg .= $langs->trans('ErrorFailedToSendMail', $emailFrom, $emailTo);
1080  $mesg .= '<br>'.$mailfile->error;
1081  setEventMessages($mesg, null, 'errors');
1082  } else {
1083  setEventMessages('No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS', null, 'warnings');
1084  }
1085  }
1086  } else {
1087  setEventMessages($mailfile->error, $mailfile->errors, 'errors');
1088  $action = '';
1089  }
1090  } else {
1091  setEventMessages($langs->trans("NoEmailSentBadSenderOrRecipientEmail"), null, 'warnings');
1092  $action = '';
1093  }
1094  } else {
1095  setEventMessages($langs->trans("FailedToSetPaid"), null, 'warnings');
1096  $action = '';
1097  }
1098  }
1099 
1100  if ($action == "addline" && $user->rights->expensereport->creer) {
1101  $error = 0;
1102 
1103  // First save uploaded file
1104  $fk_ecm_files = 0;
1105  if (GETPOSTISSET('attachfile')) {
1106  $arrayoffiles = GETPOST('attachfile', 'array');
1107  if (is_array($arrayoffiles) && !empty($arrayoffiles[0])) {
1108  include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
1109  $entityprefix = ($conf->entity != '1') ? $conf->entity.'/' : '';
1110  $relativepath = 'expensereport/'.$object->ref.'/'.$arrayoffiles[0];
1111  $ecmfiles = new EcmFiles($db);
1112  $ecmfiles->fetch(0, '', $relativepath);
1113  $fk_ecm_files = $ecmfiles->id;
1114  }
1115  }
1116 
1117  // if VAT is not used in Dolibarr, set VAT rate to 0 because VAT rate is necessary.
1118  if (empty($vatrate)) {
1119  $vatrate = "0.000";
1120  }
1121  $tmpvat = price2num(preg_replace('/\s*\(.*\)/', '', $vatrate));
1122 
1123  $value_unit_ht = price2num(GETPOST('value_unit_ht', 'alpha'), 'MU');
1124  $value_unit = price2num(GETPOST('value_unit', 'alpha'), 'MU');
1125  if (empty($value_unit)) {
1126  $value_unit = price2num($value_unit_ht + ($value_unit_ht * $tmpvat / 100), 'MU');
1127  }
1128 
1129  $fk_c_exp_tax_cat = GETPOST('fk_c_exp_tax_cat', 'int');
1130 
1131  $qty = price2num(GETPOST('qty', 'alpha'));
1132  if (empty($qty)) {
1133  $qty = 1;
1134  }
1135 
1136  if (!($fk_c_type_fees > 0)) {
1137  $error++;
1138  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors');
1139  $action = '';
1140  }
1141 
1142  if ((float) $tmpvat < 0 || $tmpvat === '') {
1143  $error++;
1144  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("VAT")), null, 'errors');
1145  $action = '';
1146  }
1147 
1148  // If no date entered
1149  if (empty($date) || $date == "--") {
1150  $error++;
1151  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors');
1152  } elseif ($date < $object->date_debut || $date > ($object->date_fin + (24 * 3600 - 1))) {
1153  // Warning if date out of range
1154  $langs->load("errors");
1155  setEventMessages($langs->trans("WarningDateOfLineMustBeInExpenseReportRange"), null, 'warnings');
1156  }
1157 
1158  // If no price entered
1159  if ($value_unit == 0) {
1160  $error++;
1161  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("PriceUTTC")), null, 'errors');
1162  }
1163 
1164  // If no project entered
1165  if ($projectRequired && $fk_project <= 0) {
1166  $error++;
1167  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Project")), null, 'errors');
1168  }
1169 
1170  // If no file associated
1171  if ($fileRequired && $fk_ecm_files == 0) {
1172  $error++;
1173  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("File")), null, 'errors');
1174  }
1175 
1176  if (!$error) {
1177  $type = 0; // TODO What if service ? We should take the type product/service from the type of expense report llx_c_type_fees
1178 
1179  // Insert line
1180  $result = $object->addline($qty, $value_unit, $fk_c_type_fees, $vatrate, $date, $comments, $fk_project, $fk_c_exp_tax_cat, $type, $fk_ecm_files);
1181  if ($result > 0) {
1182  $ret = $object->fetch($object->id); // Reload to get new records
1183 
1184  if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
1185  // Define output language
1186  $outputlangs = $langs;
1187  $newlang = GETPOST('lang_id', 'alpha');
1188  if (!empty($conf->global->MAIN_MULTILANGS) && empty($newlang)) {
1189  $newlang = $object->thirdparty->default_lang;
1190  }
1191  if (!empty($newlang)) {
1192  $outputlangs = new Translate("", $conf);
1193  $outputlangs->setDefaultLang($newlang);
1194  }
1195 
1196  $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
1197  }
1198 
1199  unset($qty);
1200  unset($value_unit_ht);
1201  unset($value_unit);
1202  unset($vatrate);
1203  unset($comments);
1204  unset($fk_c_type_fees);
1205  unset($fk_project);
1206 
1207  unset($date);
1208  } else {
1209  setEventMessages($object->error, $object->errors, 'errors');
1210  }
1211  }
1212 
1213  $action = '';
1214  }
1215 
1216  if ($action == 'confirm_delete_line' && GETPOST("confirm", 'alpha') == "yes" && $user->rights->expensereport->creer) {
1217  $object = new ExpenseReport($db);
1218  $object->fetch($id);
1219 
1220  $object_ligne = new ExpenseReportLine($db);
1221  $object_ligne->fetch(GETPOST("rowid", 'int'));
1222  $total_ht = $object_ligne->total_ht;
1223  $total_tva = $object_ligne->total_tva;
1224 
1225  $result = $object->deleteline(GETPOST("rowid", 'int'), $user);
1226  if ($result >= 0) {
1227  if ($result > 0) {
1228  // Define output language
1229  if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
1230  $outputlangs = $langs;
1231  $newlang = '';
1232  if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
1233  $newlang = GETPOST('lang_id', 'aZ09');
1234  }
1235  if ($conf->global->MAIN_MULTILANGS && empty($newlang)) {
1236  $newlang = $object->thirdparty->default_lang;
1237  }
1238  if (!empty($newlang)) {
1239  $outputlangs = new Translate("", $conf);
1240  $outputlangs->setDefaultLang($newlang);
1241  }
1242  $model = $object->model_pdf;
1243  $ret = $object->fetch($id); // Reload to get new records
1244 
1245  $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
1246  }
1247  }
1248 
1249  header("Location: ".$_SERVER["PHP_SELF"]."?id=".GETPOST('id', 'int'));
1250  exit;
1251  } else {
1252  setEventMessages($object->error, $object->errors, 'errors');
1253  }
1254  }
1255 
1256  if ($action == "updateline" && $user->rights->expensereport->creer) {
1257  $object = new ExpenseReport($db);
1258  $object->fetch($id);
1259 
1260  // First save uploaded file
1261  $fk_ecm_files = 0;
1262  if (GETPOSTISSET('attachfile')) {
1263  $arrayoffiles = GETPOST('attachfile', 'array');
1264  if (is_array($arrayoffiles) && !empty($arrayoffiles[0])) {
1265  include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
1266  $relativepath = 'expensereport/'.$object->ref.'/'.$arrayoffiles[0];
1267  $ecmfiles = new EcmFiles($db);
1268  $ecmfiles->fetch(0, '', $relativepath);
1269  $fk_ecm_files = $ecmfiles->id;
1270  }
1271  }
1272 
1273  $rowid = GETPOST('rowid', 'int');
1274  $type_fees_id = GETPOST('fk_c_type_fees', 'int');
1275  $fk_c_exp_tax_cat = GETPOST('fk_c_exp_tax_cat', 'int');
1276  $projet_id = $fk_project;
1277  $comments = GETPOST('comments', 'restricthtml');
1278  $qty = price2num(GETPOST('qty', 'alpha'));
1279  $vatrate = GETPOST('vatrate', 'alpha');
1280 
1281  // if VAT is not used in Dolibarr, set VAT rate to 0 because VAT rate is necessary.
1282  if (empty($vatrate)) {
1283  $vatrate = "0.000";
1284  }
1285  $tmpvat = price2num(preg_replace('/\s*\(.*\)/', '', $vatrate));
1286 
1287  $value_unit_ht = price2num(GETPOST('value_unit_ht', 'alpha'), 'MU');
1288  $value_unit = price2num(GETPOST('value_unit', 'alpha'), 'MU');
1289  if (empty($value_unit)) {
1290  $value_unit = price2num($value_unit_ht + ($value_unit_ht * $tmpvat / 100), 'MU');
1291  }
1292 
1293  if (!GETPOST('fk_c_type_fees', 'int') > 0) {
1294  $error++;
1295  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors');
1296  $action = '';
1297  }
1298  if ((float) $tmpvat < 0 || $tmpvat == '') {
1299  $error++;
1300  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Vat")), null, 'errors');
1301  $action = '';
1302  }
1303  // Warning if date out of range
1304  if ($date < $object->date_debut || $date > ($object->date_fin + (24 * 3600 - 1))) {
1305  $langs->load("errors");
1306  setEventMessages($langs->trans("WarningDateOfLineMustBeInExpenseReportRange"), null, 'warnings');
1307  }
1308 
1309  // If no project entered
1310  if ($projectRequired && $projet_id <= 0) {
1311  $error++;
1312  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Project")), null, 'errors');
1313  }
1314 
1315  if (!$error) {
1316  // TODO Use update method of ExpenseReportLine
1317  $result = $object->updateline($rowid, $type_fees_id, $projet_id, $vatrate, $comments, $qty, $value_unit, $date, $id, $fk_c_exp_tax_cat, $fk_ecm_files);
1318  if ($result >= 0) {
1319  if ($result > 0) {
1320  // Define output language
1321  if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
1322  $outputlangs = $langs;
1323  $newlang = '';
1324  if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
1325  $newlang = GETPOST('lang_id', 'aZ09');
1326  }
1327  if ($conf->global->MAIN_MULTILANGS && empty($newlang)) {
1328  $newlang = $object->thirdparty->default_lang;
1329  }
1330  if (!empty($newlang)) {
1331  $outputlangs = new Translate("", $conf);
1332  $outputlangs->setDefaultLang($newlang);
1333  }
1334  $model = $object->model_pdf;
1335  $ret = $object->fetch($id); // Reload to get new records
1336 
1337  $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
1338  }
1339 
1340  unset($qty);
1341  unset($value_unit_ht);
1342  unset($value_unit);
1343  unset($vatrate);
1344  unset($comments);
1345  unset($fk_c_type_fees);
1346  unset($fk_project);
1347  unset($date);
1348  }
1349 
1350  //header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id);
1351  //exit;
1352  } else {
1353  setEventMessages($object->error, $object->errors, 'errors');
1354  }
1355  }
1356  }
1357 
1358  // Actions when printing a doc from card
1359  include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
1360 
1361  // Actions to send emails
1362  $triggersendname = 'EXPENSEREPORT_SENTBYMAIL';
1363  $autocopy = 'MAIN_MAIL_AUTOCOPY_EXPENSEREPORT_TO';
1364  $trackid = 'exp'.$object->id;
1365  include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
1366 
1367  // Actions to build doc
1368  $upload_dir = $conf->expensereport->dir_output;
1369  include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
1370 }
1371 
1372 
1373 /*
1374  * View
1375  */
1376 
1377 $title = $langs->trans("ExpenseReport")." - ".$langs->trans("Card");
1378 $help_url = "EN:Module_Expense_Reports|FR:Module_Notes_de_frais";
1379 
1380 llxHeader("", $title, $help_url);
1381 
1382 $form = new Form($db);
1383 $formfile = new FormFile($db);
1384 $formproject = new FormProjets($db);
1385 $projecttmp = new Project($db);
1386 $paymentexpensereportstatic = new PaymentExpenseReport($db);
1387 $bankaccountstatic = new Account($db);
1388 $ecmfilesstatic = new EcmFiles($db);
1389 $formexpensereport = new FormExpenseReport($db);
1390 
1391 // Create
1392 if ($action == 'create') {
1393  print load_fiche_titre($langs->trans("NewTrip"), '', 'trip');
1394 
1395  print '<form action="'.$_SERVER['PHP_SELF'].'" method="post" name="create">';
1396  print '<input type="hidden" name="token" value="'.newToken().'">';
1397  print '<input type="hidden" name="action" value="add">';
1398 
1399  print dol_get_fiche_head('');
1400 
1401  print '<table class="border centpercent">';
1402  print '<tbody>';
1403 
1404  // Date start
1405  print '<tr>';
1406  print '<td class="titlefieldcreate fieldrequired">'.$langs->trans("DateStart").'</td>';
1407  print '<td>';
1408  print $form->selectDate($date_start ? $date_start : -1, 'date_debut', 0, 0, 0, '', 1, 1);
1409  print '</td>';
1410  print '</tr>';
1411 
1412  // Date end
1413  print '<tr>';
1414  print '<td class="fieldrequired">'.$langs->trans("DateEnd").'</td>';
1415  print '<td>';
1416  print $form->selectDate($date_end ? $date_end : -1, 'date_fin', 0, 0, 0, '', 1, 1);
1417  print '</td>';
1418  print '</tr>';
1419 
1420  // User for expense report
1421  print '<tr>';
1422  print '<td class="fieldrequired">'.$langs->trans("User").'</td>';
1423  print '<td>';
1424  $defaultselectuser = $user->id;
1425  if (GETPOST('fk_user_author', 'int') > 0) {
1426  $defaultselectuser = GETPOST('fk_user_author', 'int');
1427  }
1428  $include_users = 'hierarchyme';
1429  if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->expensereport->writeall_advance)) {
1430  $include_users = array();
1431  }
1432  $s = $form->select_dolusers($defaultselectuser, "fk_user_author", 0, "", 0, $include_users, '', '0,'.$conf->entity);
1433  print $s;
1434  print '</td>';
1435  print '</tr>';
1436 
1437  // Approver
1438  print '<tr>';
1439  print '<td>'.$langs->trans("VALIDATOR").'</td>';
1440  print '<td>';
1441  $object = new ExpenseReport($db);
1442  $include_users = $object->fetch_users_approver_expensereport();
1443  if (empty($include_users)) {
1444  print img_warning().' '.$langs->trans("NobodyHasPermissionToValidateExpenseReport");
1445  } else {
1446  $defaultselectuser = (empty($user->fk_user_expense_validator) ? $user->fk_user : $user->fk_user_expense_validator); // Will work only if supervisor has permission to approve so is inside include_users
1447  if (!empty($conf->global->EXPENSEREPORT_DEFAULT_VALIDATOR)) {
1448  $defaultselectuser = $conf->global->EXPENSEREPORT_DEFAULT_VALIDATOR; // Can force default approver
1449  }
1450  if (GETPOST('fk_user_validator', 'int') > 0) {
1451  $defaultselectuser = GETPOST('fk_user_validator', 'int');
1452  }
1453  $s = $form->select_dolusers($defaultselectuser, "fk_user_validator", 1, "", ((empty($defaultselectuser) || empty($conf->global->EXPENSEREPORT_DEFAULT_VALIDATOR_UNCHANGEABLE)) ? 0 : 1), $include_users);
1454  print $form->textwithpicto($s, $langs->trans("AnyOtherInThisListCanValidate"));
1455  }
1456  print '</td>';
1457  print '</tr>';
1458 
1459  // Payment mode
1460  if (!empty($conf->global->EXPENSEREPORT_ASK_PAYMENTMODE_ON_CREATION)) {
1461  print '<tr>';
1462  print '<td>'.$langs->trans("ModePaiement").'</td>';
1463  print '<td>';
1464  $form->select_types_paiements('', 'fk_c_paiement');
1465  print '</td>';
1466  print '</tr>';
1467  }
1468 
1469  // Public note
1470  $note_public = GETPOSTISSET('note_public') ? GETPOST('note_public', 'restricthtml') : '';
1471 
1472  print '<tr>';
1473  print '<td class="tdtop">'.$langs->trans('NotePublic').'</td>';
1474  print '<td>';
1475 
1476  $doleditor = new DolEditor('note_public', $note_public, '', 80, 'dolibarr_notes', 'In', 0, false, empty($conf->global->FCKEDITOR_ENABLE_NOTE_PUBLIC) ? 0 : 1, ROWS_3, '90%');
1477  print $doleditor->Create(1);
1478  print '</td></tr>';
1479 
1480  // Private note
1481  $note_private = GETPOSTISSET('note_private') ? GETPOST('note_private', 'restricthtml') : '';
1482 
1483  if (empty($user->socid)) {
1484  print '<tr>';
1485  print '<td class="tdtop">'.$langs->trans('NotePrivate').'</td>';
1486  print '<td>';
1487 
1488  $doleditor = new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', 0, false, empty($conf->global->FCKEDITOR_ENABLE_NOTE_PRIVATE) ? 0 : 1, ROWS_3, '90%');
1489  print $doleditor->Create(1);
1490  print '</td></tr>';
1491  }
1492 
1493  // Other attributes
1494  $parameters = array('colspan' => ' colspan="3"', 'cols' => 3);
1495  $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by
1496  print $hookmanager->resPrint;
1497  if (empty($reshook)) {
1498  print $object->showOptionals($extrafields, 'create', $parameters);
1499  }
1500 
1501  print '<tbody>';
1502  print '</table>';
1503 
1504  print dol_get_fiche_end();
1505 
1506  print $form->buttonsSaveCancel("AddTrip");
1507 
1508  print '</form>';
1509 } elseif ($id > 0 || $ref) {
1510  $result = $object->fetch($id, $ref);
1511 
1512  if ($result > 0) {
1513  if (!in_array($object->fk_user_author, $user->getAllChildIds(1))) {
1514  if (empty($user->rights->expensereport->readall) && empty($user->rights->expensereport->lire_tous)
1515  && (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || empty($user->rights->expensereport->writeall_advance))) {
1516  print load_fiche_titre($langs->trans('TripCard'), '', 'trip');
1517 
1518  print '<div class="tabBar">';
1519  print $langs->trans('NotUserRightToView');
1520  print '</div>';
1521 
1522  // End of page
1523  llxFooter();
1524  $db->close();
1525 
1526  exit;
1527  }
1528  }
1529 
1530  $head = expensereport_prepare_head($object);
1531 
1532  if ($action == 'edit' && ($object->status < 3 || $object->status == 99)) {
1533  print "<form name='update' action=\"".$_SERVER['PHP_SELF']."\" method=\"post\">\n";
1534  print '<input type="hidden" name="token" value="'.newToken().'">';
1535  print '<input type="hidden" name="id" value="'.$id.'">';
1536 
1537  print dol_get_fiche_head($head, 'card', $langs->trans("ExpenseReport"), 0, 'trip');
1538 
1539  if ($object->status == 99) {
1540  print '<input type="hidden" name="action" value="updateFromRefuse">';
1541  } else {
1542  print '<input type="hidden" name="action" value="update">';
1543  }
1544 
1545  $linkback = '<a href="'.DOL_URL_ROOT.'/expensereport/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
1546 
1547  print '<table class="border" style="width:100%;">';
1548 
1549  print '<tr>';
1550  print '<td>'.$langs->trans("User").'</td>';
1551  print '<td>';
1552  $userfee = new User($db);
1553  if ($object->fk_user_author > 0) {
1554  $userfee->fetch($object->fk_user_author);
1555  print $userfee->getNomUrl(-1);
1556  }
1557  print '</td></tr>';
1558 
1559  // Ref
1560  print '<tr><td class="titlefieldcreate">'.$langs->trans("Ref").'</td><td>';
1561  print $form->showrefnav($object, 'ref', $linkback, 1, 'ref', 'ref', '');
1562  print '</td></tr>';
1563 
1564  print '<tr>';
1565  print '<td>'.$langs->trans("DateStart").'</td>';
1566  print '<td>';
1567  print $form->selectDate($object->date_debut, 'date_debut');
1568  print '</td>';
1569  print '</tr>';
1570  print '<tr>';
1571  print '<td>'.$langs->trans("DateEnd").'</td>';
1572  print '<td>';
1573  print $form->selectDate($object->date_fin, 'date_fin');
1574  print '</td>';
1575  print '</tr>';
1576 
1577  if (!empty($conf->global->EXPENSEREPORT_ASK_PAYMENTMODE_ON_CREATION)) {
1578  print '<tr>';
1579  print '<td>'.$langs->trans("ModePaiement").'</td>';
1580  print '<td>';
1581  $form->select_types_paiements($object->fk_c_paiement, 'fk_c_paiement');
1582  print '</td>';
1583  print '</tr>';
1584  }
1585 
1586  if ($object->status < 3) {
1587  print '<tr>';
1588  print '<td>'.$langs->trans("VALIDATOR").'</td>'; // Approbator
1589  print '<td>';
1590  $include_users = $object->fetch_users_approver_expensereport();
1591  $s = $form->select_dolusers($object->fk_user_validator, "fk_user_validator", 1, "", 0, $include_users);
1592  print $form->textwithpicto($s, $langs->trans("AnyOtherInThisListCanValidate"));
1593  print '</td>';
1594  print '</tr>';
1595  } else {
1596  print '<tr>';
1597  print '<td>'.$langs->trans("VALIDOR").'</td>';
1598  print '<td>';
1599  $userfee = new User($db);
1600  $userfee->fetch($object->fk_user_valid);
1601  print $userfee->getNomUrl(-1);
1602  print '</td></tr>';
1603  }
1604 
1605  if ($object->status == 6) {
1606  print '<tr>';
1607  print '<td>'.$langs->trans("AUTHORPAIEMENT").'</td>';
1608  print '<td>';
1609  $userfee = new User($db);
1610  $userfee->fetch($user->id);
1611  print $userfee->getNomUrl(-1);
1612  print '</td></tr>';
1613  }
1614 
1615  // Other attributes
1616  //$cols = 3;
1617  //include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_edit.tpl.php';
1618 
1619  print '</table>';
1620 
1621  print dol_get_fiche_end();
1622 
1623  print $form->buttonsSaveCancel("Modify");
1624 
1625  print '</form>';
1626  } else {
1627  $taxlessUnitPriceDisabled = ! empty($conf->global->EXPENSEREPORT_FORCE_LINE_AMOUNTS_INCLUDING_TAXES_ONLY) ? ' disabled' : '';
1628 
1629  print dol_get_fiche_head($head, 'card', $langs->trans("ExpenseReport"), -1, 'trip');
1630 
1631  $formconfirm = '';
1632 
1633  // Clone confirmation
1634  if ($action == 'clone') {
1635  // Create an array for form
1636  $criteriaforfilter = 'hierarchyme';
1637  if (!empty($user->rights->expensereport->readall)) {
1638  $criteriaforfilter = '';
1639  }
1640  $formquestion = array(
1641  'text' => '',
1642  array('type' => 'other', 'name' => 'fk_user_author', 'label' => $langs->trans("SelectTargetUser"), 'value' => $form->select_dolusers((GETPOST('fk_user_author', 'int') > 0 ? GETPOST('fk_user_author', 'int') : $user->id), 'fk_user_author', 0, null, 0, $criteriaforfilter, '', '0', 0, 0, '', 0, '', 'maxwidth150'))
1643  );
1644  // Paiement incomplet. On demande si motif = escompte ou autre
1645  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneExpenseReport', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
1646  }
1647 
1648  if ($action == 'save') {
1649  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id, $langs->trans("SaveTrip"), $langs->trans("ConfirmSaveTrip"), "confirm_validate", "", "", 1);
1650  }
1651 
1652  if ($action == 'save_from_refuse') {
1653  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id, $langs->trans("SaveTrip"), $langs->trans("ConfirmSaveTrip"), "confirm_save_from_refuse", "", "", 1);
1654  }
1655 
1656  if ($action == 'delete') {
1657  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id, $langs->trans("DeleteTrip"), $langs->trans("ConfirmDeleteTrip"), "confirm_delete", "", "", 1);
1658  }
1659 
1660  if ($action == 'validate') {
1661  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id, $langs->trans("ValideTrip"), $langs->trans("ConfirmValideTrip"), "confirm_approve", "", "", 1);
1662  }
1663 
1664  if ($action == 'paid') {
1665  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id, $langs->trans("PaidTrip"), $langs->trans("ConfirmPaidTrip"), "confirm_paid", "", "", 1);
1666  }
1667 
1668  if ($action == 'cancel') {
1669  $array_input = array('text'=>$langs->trans("ConfirmCancelTrip"), array('type'=>"text", 'label'=>'<strong>'.$langs->trans("Comment").'</strong>', 'name'=>"detail_cancel", 'value'=>""));
1670  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id, $langs->trans("Cancel"), "", "confirm_cancel", $array_input, "", 1);
1671  }
1672 
1673  if ($action == 'setdraft') {
1674  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id, $langs->trans("BrouillonnerTrip"), $langs->trans("ConfirmBrouillonnerTrip"), "confirm_setdraft", "", "", 1);
1675  }
1676 
1677  if ($action == 'refuse') { // Deny
1678  $array_input = array('text'=>$langs->trans("ConfirmRefuseTrip"), array('type'=>"text", 'label'=>$langs->trans("Comment"), 'name'=>"detail_refuse", 'value'=>""));
1679  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id, $langs->trans("Deny"), '', "confirm_refuse", $array_input, "yes", 1);
1680  }
1681 
1682  if ($action == 'delete_line') {
1683  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id."&rowid=".GETPOST('rowid', 'int'), $langs->trans("DeleteLine"), $langs->trans("ConfirmDeleteLine"), "confirm_delete_line", '', 'yes', 1);
1684  }
1685 
1686  // Print form confirm
1687  print $formconfirm;
1688 
1689  // Expense report card
1690  $linkback = '<a href="'.DOL_URL_ROOT.'/expensereport/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
1691 
1692  $morehtmlref = '<div class="refidno">';
1693  /*
1694  // Ref customer
1695  $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, $user->rights->commande->creer, 'string', '', 0, 1);
1696  $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, $user->rights->commande->creer, 'string', '', null, null, '', 1);
1697  // Thirdparty
1698  $morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : ' . $soc->getNomUrl(1);
1699  // Project
1700  if (! empty($conf->project->enabled))
1701  {
1702  $langs->load("projects");
1703  $morehtmlref.='<br>'.$langs->trans('Project') . ' ';
1704  if ($user->rights->commande->creer)
1705  {
1706  if ($action != 'classify')
1707  $morehtmlref.='<a class="editfielda" href="' . $_SERVER['PHP_SELF'] . '?action=classify&token='.newToken().'&id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> : ';
1708  if ($action == 'classify') {
1709  //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
1710  $morehtmlref.='<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
1711  $morehtmlref.='<input type="hidden" name="action" value="classin">';
1712  $morehtmlref.='<input type="hidden" name="token" value="'.newToken().'">';
1713  $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1);
1714  $morehtmlref.='<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
1715  $morehtmlref.='</form>';
1716  } else {
1717  $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1);
1718  }
1719  } else {
1720  if (! empty($object->fk_project)) {
1721  $proj = new Project($db);
1722  $proj->fetch($object->fk_project);
1723  $morehtmlref.='<a href="'.DOL_URL_ROOT.'/projet/card.php?id=' . $object->fk_project . '" title="' . $langs->trans('ShowProject') . '">';
1724  $morehtmlref.=$proj->ref;
1725  $morehtmlref.='</a>';
1726  } else {
1727  $morehtmlref.='';
1728  }
1729  }
1730  }*/
1731  $morehtmlref .= '</div>';
1732 
1733  dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
1734 
1735  print '<div class="fichecenter">';
1736  print '<div class="fichehalfleft">';
1737  print '<div class="underbanner clearboth"></div>';
1738 
1739  print '<table class="border tableforfield centpercent">';
1740 
1741  // Author
1742  print '<tr>';
1743  print '<td class="titlefield">'.$langs->trans("User").'</td>';
1744  print '<td>';
1745  if ($object->fk_user_author > 0) {
1746  $userauthor = new User($db);
1747  $result = $userauthor->fetch($object->fk_user_author);
1748  if ($result < 0) {
1749  dol_print_error('', $userauthor->error);
1750  } elseif ($result > 0) {
1751  print $userauthor->getNomUrl(-1);
1752  }
1753  }
1754  print '</td></tr>';
1755 
1756  // Period
1757  print '<tr>';
1758  print '<td class="titlefield">'.$langs->trans("Period").'</td>';
1759  print '<td>';
1760  print get_date_range($object->date_debut, $object->date_fin, 'day', $langs, 0);
1761  print '</td>';
1762  print '</tr>';
1763  if (!empty($conf->global->EXPENSEREPORT_ASK_PAYMENTMODE_ON_CREATION)) {
1764  print '<tr>';
1765  print '<td>'.$langs->trans("ModePaiement").'</td>';
1766  print '<td>'.$object->fk_c_paiement.'</td>';
1767  print '</tr>';
1768  }
1769 
1770  // Validation date
1771  print '<tr>';
1772  print '<td>'.$langs->trans("DATE_SAVE").'</td>';
1773  print '<td>'.dol_print_date($object->date_valid, 'dayhour', 'tzuser');
1774  if ($object->status == 2 && $object->hasDelay('toapprove')) {
1775  print ' '.img_warning($langs->trans("Late").' - '.$langs->trans("ToApprove"));
1776  }
1777  if ($object->status == 5 && $object->hasDelay('topay')) {
1778  print ' '.img_warning($langs->trans("Late").' - '.$langs->trans("ToPay"));
1779  }
1780  print '</td></tr>';
1781  print '</tr>';
1782 
1783  // User to inform for approval
1784  if ($object->status <= ExpenseReport::STATUS_VALIDATED) { // informed
1785  print '<tr>';
1786  print '<td>'.$langs->trans("VALIDATOR").'</td>'; // approver
1787  print '<td>';
1788  if ($object->fk_user_validator > 0) {
1789  $userfee = new User($db);
1790  $result = $userfee->fetch($object->fk_user_validator);
1791  if ($result > 0) {
1792  print $userfee->getNomUrl(-1);
1793  }
1794  if (empty($userfee->email) || !isValidEmail($userfee->email)) {
1795  $langs->load("errors");
1796  print img_warning($langs->trans("ErrorBadEMail", $userfee->email));
1797  }
1798  }
1799  print '</td></tr>';
1800  } elseif ($object->status == ExpenseReport::STATUS_CANCELED) {
1801  print '<tr>';
1802  print '<td>'.$langs->trans("CANCEL_USER").'</span></td>';
1803  print '<td>';
1804  if ($object->fk_user_cancel > 0) {
1805  $userfee = new User($db);
1806  $result = $userfee->fetch($object->fk_user_cancel);
1807  if ($result > 0) {
1808  print $userfee->getNomUrl(-1);
1809  }
1810  }
1811  print '</td></tr>';
1812 
1813  print '<tr>';
1814  print '<td>'.$langs->trans("MOTIF_CANCEL").'</td>';
1815  print '<td>'.$object->detail_cancel.'</td></tr>';
1816  print '</tr>';
1817  print '<tr>';
1818  print '<td>'.$langs->trans("DATE_CANCEL").'</td>';
1819  print '<td>'.dol_print_date($object->date_cancel, 'dayhour', 'tzuser').'</td></tr>';
1820  print '</tr>';
1821  } else {
1822  print '<tr>';
1823  print '<td>'.$langs->trans("ApprovedBy").'</td>';
1824  print '<td>';
1825  if ($object->fk_user_approve > 0) {
1826  $userapp = new User($db);
1827  $result = $userapp->fetch($object->fk_user_approve);
1828  if ($result > 0) {
1829  print $userapp->getNomUrl(-1);
1830  }
1831  }
1832  print '</td></tr>';
1833 
1834  print '<tr>';
1835  print '<td>'.$langs->trans("DateApprove").'</td>';
1836  print '<td>'.dol_print_date($object->date_approve, 'dayhour', 'tzuser').'</td></tr>';
1837  print '</tr>';
1838  }
1839 
1840  if ($object->status == 99 || !empty($object->detail_refuse)) {
1841  print '<tr>';
1842  print '<td>'.$langs->trans("REFUSEUR").'</td>';
1843  print '<td>';
1844  $userfee = new User($db);
1845  $result = $userfee->fetch($object->fk_user_refuse);
1846  if ($result > 0) {
1847  print $userfee->getNomUrl(-1);
1848  }
1849  print '</td></tr>';
1850 
1851  print '<tr>';
1852  print '<td>'.$langs->trans("DATE_REFUS").'</td>';
1853  print '<td>'.dol_print_date($object->date_refuse, 'dayhour', 'tzuser');
1854  if ($object->detail_refuse) {
1855  print ' - '.$object->detail_refuse;
1856  }
1857  print '</td>';
1858  print '</tr>';
1859  }
1860 
1861  if ($object->status == $object::STATUS_CLOSED) {
1862  /* TODO this fields are not yet filled
1863  print '<tr>';
1864  print '<td>'.$langs->trans("AUTHORPAIEMENT").'</td>';
1865  print '<td>';
1866  $userfee=new User($db);
1867  $userfee->fetch($object->fk_user_paid);
1868  print $userfee->getNomUrl(-1);
1869  print '</td></tr>';
1870  print '<tr>';
1871  print '<td>'.$langs->trans("DATE_PAIEMENT").'</td>';
1872  print '<td>'.$object->date_paiement.'</td></tr>';
1873  print '</tr>';
1874  */
1875  }
1876 
1877  // Other attributes
1878  $cols = 2;
1879  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
1880 
1881  print '</table>';
1882 
1883  print '</div>';
1884  print '<div class="fichehalfright">';
1885  print '<div class="underbanner clearboth"></div>';
1886 
1887  print '<table class="border tableforfield centpercent">';
1888 
1889  // Amount
1890  print '<tr>';
1891  print '<td class="titlefieldmiddle">'.$langs->trans("AmountHT").'</td>';
1892  print '<td class="nowrap amountcard">'.price($object->total_ht, 1, '', 1, - 1, - 1, $conf->currency).'</td>';
1893  $rowspan = 5;
1894  if ($object->status <= ExpenseReport::STATUS_VALIDATED) {
1895  $rowspan++;
1896  } elseif ($object->status == ExpenseReport::STATUS_CANCELED) {
1897  $rowspan += 2;
1898  } else {
1899  $rowspan += 2;
1900  }
1901  if ($object->status == ExpenseReport::STATUS_REFUSED || !empty($object->detail_refuse)) {
1902  $rowspan += 2;
1903  }
1904  if ($object->status == ExpenseReport::STATUS_CLOSED) {
1905  $rowspan += 2;
1906  }
1907  print "</td>";
1908  print '</tr>';
1909 
1910  print '<tr>';
1911  print '<td>'.$langs->trans("AmountVAT").'</td>';
1912  print '<td class="nowrap amountcard">'.price($object->total_tva, 1, '', 1, -1, -1, $conf->currency).'</td>';
1913  print '</tr>';
1914 
1915  // Amount Local Taxes
1916  if ($mysoc->localtax1_assuj == "1" || $object->total_localtax1 != 0) { // Localtax1
1917  print '<tr><td>'.$langs->transcountry("AmountLT1", $mysoc->country_code).'</td>';
1918  print '<td class="valuefield">'.price($object->total_localtax1, 1, '', 1, -1, -1, $conf->currency).'</td></tr>';
1919  }
1920  if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0) { // Localtax2 IRPF
1921  print '<tr><td>'.$langs->transcountry("AmountLT2", $mysoc->country_code).'</td>';
1922  print '<td class="valuefield">'.price($object->total_localtax2, 1, '', 1, -1, -1, $conf->currency).'</td></tr>';
1923  }
1924 
1925  print '<tr>';
1926  print '<td>'.$langs->trans("AmountTTC").'</td>';
1927  print '<td class="nowrap amountcard">'.price($object->total_ttc, 1, '', 1, -1, -1, $conf->currency).'</td>';
1928  print '</tr>';
1929 
1930  // List of payments already done
1931  $nbcols = 3;
1932  $nbrows = 0;
1933  if (!empty($conf->banque->enabled)) {
1934  $nbrows++;
1935  $nbcols++;
1936  }
1937 
1938  print '<table class="noborder paymenttable centpercent">';
1939 
1940  print '<tr class="liste_titre">';
1941  print '<td class="liste_titre">'.$langs->trans('Payments').'</td>';
1942  print '<td class="liste_titre">'.$langs->trans('Date').'</td>';
1943  print '<td class="liste_titre">'.$langs->trans('Type').'</td>';
1944  if (!empty($conf->banque->enabled)) {
1945  print '<td class="liste_titre right">'.$langs->trans('BankAccount').'</td>';
1946  }
1947  print '<td class="liste_titre right">'.$langs->trans('Amount').'</td>';
1948  print '<td class="liste_titre" width="18">&nbsp;</td>';
1949  print '</tr>';
1950 
1951  // Payments already done (from payment on this expensereport)
1952  $sql = "SELECT p.rowid, p.num_payment, p.datep as dp, p.amount, p.fk_bank,";
1953  $sql .= "c.code as payment_code, c.libelle as payment_type,";
1954  $sql .= "ba.rowid as baid, ba.ref as baref, ba.label, ba.number as banumber, ba.account_number, ba.fk_accountancy_journal";
1955  $sql .= " FROM ".MAIN_DB_PREFIX."expensereport as e, ".MAIN_DB_PREFIX."payment_expensereport as p";
1956  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as c ON p.fk_typepayment = c.id";
1957  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid';
1958  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid';
1959  $sql .= " WHERE e.rowid = ".((int) $id);
1960  $sql .= " AND p.fk_expensereport = e.rowid";
1961  $sql .= ' AND e.entity IN ('.getEntity('expensereport').')';
1962  $sql .= " ORDER BY dp";
1963 
1964  $resql = $db->query($sql);
1965  if ($resql) {
1966  $num = $db->num_rows($resql);
1967  $i = 0; $totalpaid = 0;
1968  while ($i < $num) {
1969  $objp = $db->fetch_object($resql);
1970 
1971  $paymentexpensereportstatic->id = $objp->rowid;
1972  $paymentexpensereportstatic->datep = $db->jdate($objp->dp);
1973  $paymentexpensereportstatic->ref = $objp->rowid;
1974  $paymentexpensereportstatic->num_payment = $objp->num_payment;
1975  $paymentexpensereportstatic->type_code = $objp->payment_code;
1976  $paymentexpensereportstatic->type_label = $objp->payment_type;
1977 
1978  print '<tr class="oddseven">';
1979  print '<td>';
1980  print $paymentexpensereportstatic->getNomUrl(1);
1981  print '</td>';
1982  print '<td>'.dol_print_date($db->jdate($objp->dp), 'day')."</td>\n";
1983  $labeltype = $langs->trans("PaymentType".$objp->payment_code) != ("PaymentType".$objp->payment_code) ? $langs->trans("PaymentType".$objp->payment_code) : $objp->payment_type;
1984  print "<td>".$labeltype.' '.$objp->num_payment."</td>\n";
1985  // Bank account
1986  if (!empty($conf->banque->enabled)) {
1987  $bankaccountstatic->id = $objp->baid;
1988  $bankaccountstatic->ref = $objp->baref;
1989  $bankaccountstatic->label = $objp->baref;
1990  $bankaccountstatic->number = $objp->banumber;
1991 
1992  if (!empty($conf->accounting->enabled)) {
1993  $bankaccountstatic->account_number = $objp->account_number;
1994 
1995  $accountingjournal = new AccountingJournal($db);
1996  $accountingjournal->fetch($objp->fk_accountancy_journal);
1997  $bankaccountstatic->accountancy_journal = $accountingjournal->getNomUrl(0, 1, 1, '', 1);
1998  }
1999 
2000  print '<td class="right">';
2001  if ($bankaccountstatic->id) {
2002  print $bankaccountstatic->getNomUrl(1, 'transactions');
2003  }
2004  print '</td>';
2005  }
2006  print '<td class="right">'.price($objp->amount)."</td>";
2007  print '<td></td>';
2008  print "</tr>";
2009  $totalpaid += $objp->amount;
2010  $i++;
2011  }
2012  if (!is_null($totalpaid)) {
2013  $totalpaid = price2num($totalpaid); // Round $totalpaid to fix floating problem after addition into loop
2014  }
2015 
2016  $remaintopay = price2num($object->total_ttc - $totalpaid);
2017  $resteapayeraffiche = $remaintopay;
2018 
2019  $cssforamountpaymentcomplete = 'amountpaymentcomplete';
2020 
2021  if ($object->status == ExpenseReport::STATUS_REFUSED) {
2022  $cssforamountpaymentcomplete = 'amountpaymentneutral';
2023  $resteapayeraffiche = 0;
2024  } elseif ($object->paid == 0) {
2025  $cssforamountpaymentcomplete = 'amountpaymentneutral';
2026  }
2027  print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans("AlreadyPaid").':</td><td class="right">'.price($totalpaid).'</td><td></td></tr>';
2028  print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans("AmountExpected").':</td><td class="right">'.price($object->total_ttc).'</td><td></td></tr>';
2029 
2030  print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans("RemainderToPay").':</td>';
2031  print '<td class="right'.($resteapayeraffiche ? ' amountremaintopay' : (' '.$cssforamountpaymentcomplete)).'">'.price($resteapayeraffiche).'</td><td></td></tr>';
2032 
2033  $db->free($resql);
2034  } else {
2035  dol_print_error($db);
2036  }
2037  print "</table>";
2038 
2039  print '</div>';
2040  print '</div>';
2041 
2042  print '<div class="clearboth"></div><br>';
2043 
2044  print '<div style="clear: both;"></div>';
2045 
2046  $actiontouse = 'updateline';
2047  if (($object->status == 0 || $object->status == 99) && $action != 'editline') {
2048  $actiontouse = 'addline';
2049  }
2050 
2051  print '<form name="expensereport" action="'.$_SERVER["PHP_SELF"].'" enctype="multipart/form-data" method="post" >';
2052  print '<input type="hidden" name="token" value="'.newToken().'">';
2053  print '<input type="hidden" name="action" value="'.$actiontouse.'">';
2054  print '<input type="hidden" name="id" value="'.$object->id.'">';
2055  print '<input type="hidden" name="fk_expensereport" value="'.$object->id.'" />';
2056 
2057  print '<div class="div-table-responsive-no-min">';
2058  print '<table id="tablelines" class="noborder centpercent">';
2059 
2060  if (!empty($object->lines)) {
2061  $i = 0; $total = 0;
2062 
2063  print '<tr class="liste_titre headerexpensereportdet">';
2064  print '<td class="center linecollinenb">'.$langs->trans('LineNb').'</td>';
2065  //print '<td class="center">'.$langs->trans('Piece').'</td>';
2066  print '<td class="center linecoldate">'.$langs->trans('Date').'</td>';
2067  if (!empty($conf->project->enabled)) {
2068  print '<td class="minwidth100imp linecolproject">'.$langs->trans('Project').'</td>';
2069  }
2070  print '<td class="center linecoltype">'.$langs->trans('Type').'</td>';
2071  if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) {
2072  print '<td class="center linecolcarcategory">'.$langs->trans('CarCategory').'</td>';
2073  }
2074  print '<td class="center linecoldescription">'.$langs->trans('Description').'</td>';
2075  print '<td class="right linecolvat">'.$langs->trans('VAT').'</td>';
2076  print '<td class="right linecolpriceuht">'.$langs->trans('PriceUHT').'</td>';
2077  print '<td class="right linecolpriceuttc">'.$langs->trans('PriceUTTC').'</td>';
2078  print '<td class="right linecolqty">'.$langs->trans('Qty').'</td>';
2079  if ($action != 'editline') {
2080  print '<td class="right linecolamountht">'.$langs->trans('AmountHT').'</td>';
2081  print '<td class="right linecolamountttc">'.$langs->trans('AmountTTC').'</td>';
2082  }
2083  // Picture
2084  print '<td>';
2085  print '</td>';
2086 
2087  // Information if theres a rule restriction
2088  print '<td>';
2089  print '</td>';
2090 
2091  // Ajout des boutons de modification/suppression
2092  if (($object->status < 2 || $object->status == 99) && $user->rights->expensereport->creer) {
2093  print '<td class="right"></td>';
2094  }
2095  print '</tr>';
2096 
2097  foreach ($object->lines as &$line) {
2098  $numline = $i + 1;
2099 
2100  if ($action != 'editline' || $line->rowid != GETPOST('rowid', 'int')) {
2101  print '<tr class="oddeven linetr" data-id="'.$line->id.'">';
2102 
2103  // Num
2104  print '<td class="center linecollinenb">';
2105  print $numline;
2106  print '</td>';
2107 
2108  // Date
2109  print '<td class="center linecoldate">'.dol_print_date($db->jdate($line->date), 'day').'</td>';
2110 
2111  // Project
2112  if (!empty($conf->project->enabled)) {
2113  print '<td class="center dateproject">';
2114  if ($line->fk_project > 0) {
2115  $projecttmp->id = $line->fk_project;
2116  $projecttmp->ref = $line->projet_ref;
2117  $projecttmp->title = $line->projet_title;
2118  print $projecttmp->getNomUrl(1);
2119  }
2120  print '</td>';
2121  }
2122 
2123  $titlealt = '';
2124  if (!empty($conf->accounting->enabled)) {
2125  require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
2126  $accountingaccount = new AccountingAccount($db);
2127  $resaccountingaccount = $accountingaccount->fetch(0, $line->type_fees_accountancy_code, 1);
2128  //$titlealt .= '<span class="opacitymedium">';
2129  $titlealt .= $langs->trans("AccountancyCode").': ';
2130  if ($resaccountingaccount > 0) {
2131  $titlealt .= $accountingaccount->account_number;
2132  } else {
2133  $titlealt .= $langs->trans("NotFound");
2134  }
2135  //$titlealt .= '</span>';
2136  }
2137 
2138  // Type of fee
2139  print '<td class="center linecoltype" title="'.dol_escape_htmltag($titlealt).'">';
2140  $labeltype = ($langs->trans(($line->type_fees_code)) == $line->type_fees_code ? $line->type_fees_libelle : $langs->trans($line->type_fees_code));
2141  print $labeltype;
2142  print '</td>';
2143 
2144  // IK
2145  if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) {
2146  print '<td class="fk_c_exp_tax_cat linecoltaxcat">';
2147  $exp_tax_cat_label = dol_getIdFromCode($db, $line->fk_c_exp_tax_cat, 'c_exp_tax_cat', 'rowid', 'label');
2148  print $langs->trans($exp_tax_cat_label);
2149  print '</td>';
2150  }
2151 
2152  // Comment
2153  print '<td class="left linecolcomment">'.dol_nl2br($line->comments).'</td>';
2154 
2155  // VAT rate
2156  print '<td class="right linecolvatrate">'.vatrate($line->vatrate.($line->vat_src_code ? ' ('.$line->vat_src_code.')' : ''), true).'</td>';
2157 
2158  // Unit price HT
2159  print '<td class="right linecolunitht">';
2160  if (!empty($line->value_unit_ht)) {
2161  print price($line->value_unit_ht);
2162  } else {
2163  $tmpvat = price2num(preg_replace('/\s*\(.*\)/', '', $line->vatrate));
2164  $pricenettoshow = price2num($line->value_unit / (1 + $tmpvat / 100), 'MU');
2165  print price($pricenettoshow);
2166  }
2167  print '</td>';
2168 
2169  print '<td class="right linecolunitttc">'.price($line->value_unit).'</td>';
2170 
2171  print '<td class="right linecolqty">'.dol_escape_htmltag($line->qty).'</td>';
2172 
2173  if ($action != 'editline') {
2174  print '<td class="right linecoltotalht">'.price($line->total_ht).'</td>';
2175  print '<td class="right linecoltotalttc">'.price($line->total_ttc).'</td>';
2176  }
2177 
2178  // Column with preview
2179  print '<td class="center linecolpreview">';
2180  if ($line->fk_ecm_files > 0) {
2181  $modulepart = 'expensereport';
2182  $maxheightmini = 32;
2183 
2184  $result = $ecmfilesstatic->fetch($line->fk_ecm_files);
2185  if ($result > 0) {
2186  $relativepath = preg_replace('/expensereport\//', '', $ecmfilesstatic->filepath);
2187  $fileinfo = pathinfo($ecmfilesstatic->filepath.'/'.$ecmfilesstatic->filename);
2188  if (image_format_supported($fileinfo['basename']) > 0) {
2189  $minifile = getImageFileNameForSize($fileinfo['basename'], '_mini'); // For new thumbs using same ext (in lower case howerver) than original
2190  if (!dol_is_file($conf->expensereport->dir_output.'/'.$relativepath.'/'.$minifile)) {
2191  $minifile = getImageFileNameForSize($fileinfo['basename'], '_mini', '.png'); // For backward compatibility of old thumbs that were created with filename in lower case and with .png extension
2192  }
2193  //print $file['path'].'/'.$minifile.'<br>';
2194  $urlforhref = getAdvancedPreviewUrl($modulepart, $relativepath.'/'.$fileinfo['filename'].'.'.strtolower($fileinfo['extension']), 1, '&entity='.(!empty($object->entity) ? $object->entity : $conf->entity));
2195  if (empty($urlforhref)) {
2196  $urlforhref = DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.(!empty($object->entity) ? $object->entity : $conf->entity).'&file='.urlencode($relativepath.$fileinfo['filename'].'.'.strtolower($fileinfo['extension']));
2197  print '<a href="'.$urlforhref.'" class="aphoto" target="_blank" rel="noopener noreferrer">';
2198  } else {
2199  print '<a href="'.$urlforhref['url'].'" class="'.$urlforhref['css'].'" target="'.$urlforhref['target'].'" mime="'.$urlforhref['mime'].'">';
2200  }
2201  print '<img class="photo" height="'.$maxheightmini.'" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.(!empty($object->entity) ? $object->entity : $conf->entity).'&file='.urlencode($relativepath.'/'.$minifile).'" title="">';
2202  print '</a>';
2203  } else {
2204  $modulepart = 'expensereport';
2205  $thumbshown = 0;
2206  if (preg_match('/\.pdf$/i', $ecmfilesstatic->filename)) {
2207  $filepdf = $conf->expensereport->dir_output.'/'.$relativepath.'/'.$ecmfilesstatic->filename;
2208  $fileimage = $conf->expensereport->dir_output.'/'.$relativepath.'/'.$ecmfilesstatic->filename.'_preview.png';
2209  $relativepathimage = $relativepath.'/'.$ecmfilesstatic->filename.'_preview.png';
2210 
2211  $pdfexists = file_exists($filepdf);
2212  if ($pdfexists) {
2213  // Conversion du PDF en image png si fichier png non existant
2214  if (!file_exists($fileimage) || (filemtime($fileimage) < filemtime($filepdf))) {
2215  if (empty($conf->global->MAIN_DISABLE_PDF_THUMBS)) { // If you experience trouble with pdf thumb generation and imagick, you can disable here.
2216  include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
2217  $ret = dol_convert_file($filepdf, 'png', $fileimage, '0'); // Convert first page of PDF into a file _preview.png
2218  if ($ret < 0) {
2219  $error++;
2220  }
2221  }
2222  }
2223  }
2224 
2225  if ($pdfexists && !$error) {
2226  $heightforphotref = 70;
2227  if (!empty($conf->dol_optimize_smallscreen)) {
2228  $heightforphotref = 60;
2229  }
2230  // If the preview file is found
2231  if (file_exists($fileimage)) {
2232  $thumbshown = 1;
2233  $urlforhref = getAdvancedPreviewUrl($modulepart, $relativepath.'/'.$fileinfo['filename'].'.'.strtolower($fileinfo['extension']), 1, '&entity='.(!empty($object->entity) ? $object->entity : $conf->entity));
2234  print '<a href="'.$urlforhref['url'].'" class="'.$urlforhref['css'].'" target="'.$urlforhref['target'].'" mime="'.$urlforhref['mime'].'">';
2235  print '<img height="'.$heightforphotref.'" class="photo photowithmargin photowithborder" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart=apercu'.$modulepart.'&amp;file='.urlencode($relativepathimage).'">';
2236  print '</a>';
2237  }
2238  }
2239  }
2240 
2241  if (!$thumbshown) {
2242  print img_mime($ecmfilesstatic->filename);
2243  }
2244  }
2245  }
2246  }
2247  print '</td>';
2248 
2249  print '<td class="nowrap right linecolwarning">';
2250  print !empty($line->rule_warning_message) ? img_warning(html_entity_decode($line->rule_warning_message)) : '&nbsp;';
2251  print '</td>';
2252 
2253  // Ajout des boutons de modification/suppression
2254  if (($object->status < ExpenseReport::STATUS_VALIDATED || $object->status == ExpenseReport::STATUS_REFUSED) && $user->rights->expensereport->creer) {
2255  print '<td class="nowrap right linecolaction">';
2256 
2257  print '<a class="editfielda reposition paddingrightonly" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=editline&token='.newToken().'&rowid='.$line->rowid.'">';
2258  print img_edit();
2259  print '</a> &nbsp; ';
2260  print '<a class="paddingrightonly" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete_line&token='.newToken().'&rowid='.$line->rowid.'">';
2261  print img_delete();
2262  print '</a>';
2263 
2264  print '</td>';
2265  }
2266 
2267  print '</tr>';
2268  }
2269 
2270  if ($action == 'editline' && $line->rowid == GETPOST('rowid', 'int')) {
2271  // Add line with link to add new file or attach line to an existing file
2272  $colspan = 11;
2273  if (!empty($conf->project->enabled)) {
2274  $colspan++;
2275  }
2276  if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) {
2277  $colspan++;
2278  }
2279 
2280  print '<!-- line of expense report -->'."\n";
2281  print '<tr class="tredited">';
2282 
2283  print '<td class="center">';
2284  print $numline;
2285  print '</td>';
2286 
2287  print '<td colspan="'.($colspan - 1).'" class="liste_titre"> ';
2288  print '<a href="" class="commonlink auploadnewfilenow reposition">'.$langs->trans("UploadANewFileNow");
2289  print img_picto($langs->trans("UploadANewFileNow"), 'chevron-down', '', false, 0, 0, '', 'marginleftonly');
2290  print '</a>';
2291  if (empty($conf->global->EXPENSEREPORT_DISABLE_ATTACHMENT_ON_LINES)) {
2292  print ' &nbsp; - &nbsp; <a href="" class="commonlink aattachtodoc reposition">'.$langs->trans("AttachTheNewLineToTheDocument");
2293  print img_picto($langs->trans("AttachTheNewLineToTheDocument"), 'chevron-down', '', false, 0, 0, '', 'marginleftonly');
2294  print '</a>';
2295  }
2296 
2297  print '<!-- Code to open/close section to submit or link files in edit mode -->'."\n";
2298  print '<script type="text/javascript">'."\n";
2299  print '$(document).ready(function() {
2300  $( ".auploadnewfilenow" ).click(function() {
2301  jQuery(".truploadnewfilenow").toggle();
2302  jQuery(".trattachnewfilenow").hide();
2303  return false;
2304  });
2305  $( ".aattachtodoc" ).click(function() {
2306  jQuery(".trattachnewfilenow").toggle();
2307  jQuery(".truploadnewfilenow").hide();
2308  return false;
2309  });';
2310  if (is_array(GETPOST('attachfile', 'array')) && count(GETPOST('attachfile', 'array'))) {
2311  print 'jQuery(".trattachnewfilenow").toggle();'."\n";
2312  }
2313  print '
2314  jQuery("form[name=\"expensereport\"]").submit(function() {
2315  if (jQuery(".truploadnewfilenow").is(":hidden")) {
2316  jQuery("input[name=\"sendit\"]").val("");
2317  }
2318  });
2319  ';
2320  print '
2321  });
2322  ';
2323  print '</script>'."\n";
2324  print '</td></tr>';
2325 
2326  $filenamelinked = '';
2327  if ($line->fk_ecm_files > 0) {
2328  $result = $ecmfilesstatic->fetch($line->fk_ecm_files);
2329  if ($result > 0) {
2330  $filenamelinked = $ecmfilesstatic->filename;
2331  }
2332  }
2333 
2334  $tredited = 'tredited';
2335  include DOL_DOCUMENT_ROOT.'/expensereport/tpl/expensereport_addfile.tpl.php';
2336  include DOL_DOCUMENT_ROOT.'/expensereport/tpl/expensereport_linktofile.tpl.php';
2337 
2338  print '<tr class="oddeven tredited">';
2339 
2340  print '<td></td>';
2341 
2342  // Select date
2343  print '<td class="center">';
2344  print $form->selectDate($line->date, 'date');
2345  print '</td>';
2346 
2347  // Select project
2348  if (!empty($conf->project->enabled)) {
2349  print '<td>';
2350  $formproject->select_projects(-1, $line->fk_project, 'fk_project', 0, 0, $projectRequired ? 0 : 1, 1, 0, 0, 0, '', 0, 0, 'maxwidth300');
2351  print '</td>';
2352  }
2353 
2354  // Select type
2355  print '<td class="center">';
2356  print $formexpensereport->selectTypeExpenseReport($line->fk_c_type_fees, 'fk_c_type_fees');
2357  print '</td>';
2358 
2359  if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) {
2360  print '<td class="fk_c_exp_tax_cat">';
2361  $params = array('fk_expense' => $object->id, 'fk_expense_det' => $line->rowid, 'date' => $line->dates);
2362  print $form->selectExpenseCategories($line->fk_c_exp_tax_cat, 'fk_c_exp_tax_cat', 1, array(), 'fk_c_type_fees', $userauthor->default_c_exp_tax_cat, $params);
2363  print '</td>';
2364  }
2365 
2366  // Add comments
2367  print '<td>';
2368  print '<textarea name="comments" class="flat_ndf centpercent">'.dol_escape_htmltag($line->comments, 0, 1).'</textarea>';
2369  print '</td>';
2370 
2371  // VAT
2372  $selectedvat = price2num($line->vatrate).($line->vat_src_code ? ' ('.$line->vat_src_code.')' : '');
2373  print '<td class="right">';
2374  print $form->load_tva('vatrate', (GETPOSTISSET("vatrate") ? GETPOST("vatrate") : $selectedvat), $mysoc, '', 0, 0, '', false, 1);
2375  print '</td>';
2376 
2377  // Unit price
2378  print '<td class="right">';
2379  print '<input type="text" min="0" class="right maxwidth50" id="value_unit_ht" name="value_unit_ht" value="'.dol_escape_htmltag(price2num($line->value_unit_ht)).'"'.$taxlessUnitPriceDisabled.' />';
2380  print '</td>';
2381 
2382  // Unit price with tax
2383  print '<td class="right">';
2384  print '<input type="text" min="0" class="right maxwidth50" id="value_unit" name="value_unit" value="'.dol_escape_htmltag(price2num($line->value_unit)).'" />';
2385  print '</td>';
2386 
2387  // Quantity
2388  print '<td class="right">';
2389  print '<input type="text" min="0" class="input_qty right maxwidth50" name="qty" value="'.dol_escape_htmltag($line->qty).'" />'; // We must be able to enter decimal qty
2390  print '</td>';
2391 
2392  //print '<td class="right">'.$langs->trans('AmountHT').'</td>';
2393  //print '<td class="right">'.$langs->trans('AmountTTC').'</td>';
2394 
2395  // Picture
2396  print '<td class="center">';
2397  //print $line->fk_ecm_files;
2398  print '</td>';
2399  // Information if theres a rule restriction
2400  print '<td class="center">';
2401  print '</td>';
2402 
2403  print '<td>';
2404  print '<input type="hidden" name="rowid" value="'.$line->rowid.'">';
2405  print $form->buttonsSaveCancel('Save', 'Cancel', array(), 0, 'small');
2406  print '</td>';
2407 
2408  print '</tr>';
2409  }
2410 
2411  $i++;
2412  }
2413  }
2414 
2415  // Add a new line
2416  if (($object->status == ExpenseReport::STATUS_DRAFT || $object->status == ExpenseReport::STATUS_REFUSED) && $action != 'editline' && $user->rights->expensereport->creer) {
2417  $colspan = 12;
2418  if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) {
2419  $colspan++;
2420  }
2421  if (!empty($conf->project->enabled)) {
2422  $colspan++;
2423  }
2424  if ($action != 'editline') {
2425  $colspan++;
2426  }
2427 
2428  $nbFiles = $nbLinks = 0;
2429  $arrayoffiles = array();
2430  if (empty($conf->global->EXPENSEREPORT_DISABLE_ATTACHMENT_ON_LINES)) {
2431  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
2432  require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
2433  require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php';
2434  $upload_dir = $conf->expensereport->dir_output."/".dol_sanitizeFileName($object->ref);
2435  $arrayoffiles = dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png|'.preg_quote(dol_sanitizeFileName($object->ref.'.pdf'), '/').')$');
2436  $nbFiles = count($arrayoffiles);
2437  $nbLinks = Link::count($db, $object->element, $object->id);
2438  }
2439 
2440  // Add line with link to add new file or attach to an existing file
2441  print '<tr class="liste_titre">';
2442  print '<td colspan="'.$colspan.'" class="liste_titre expensereportautoload">';
2443  print '<a href="" class="commonlink auploadnewfilenow reposition">'.$langs->trans("UploadANewFileNow");
2444  print img_picto($langs->trans("UploadANewFileNow"), 'chevron-down', '', false, 0, 0, '', 'marginleftonly');
2445  print '</a>';
2446  if (empty($conf->global->EXPENSEREPORT_DISABLE_ATTACHMENT_ON_LINES)) {
2447  print ' &nbsp; - &nbsp; <a href="" class="commonlink aattachtodoc reposition">'.$langs->trans("AttachTheNewLineToTheDocument");
2448  print img_picto($langs->trans("AttachTheNewLineToTheDocument"), 'chevron-down', '', false, 0, 0, '', 'marginleftonly');
2449  print '</a>';
2450  }
2451 
2452  print '<!-- Code to open/close section to submit or link files in the form to add new line -->'."\n";
2453  print '<script type="text/javascript">'."\n";
2454  print '$(document).ready(function() {
2455  $( ".auploadnewfilenow" ).click(function() {
2456  console.log("We click on toggle of auploadnewfilenow");
2457  jQuery(".truploadnewfilenow").toggle();
2458  jQuery(".trattachnewfilenow").hide();
2459  if (jQuery(".truploadnewfilenow").is(":hidden")) {
2460  jQuery("input[name=\"sendit\"]").prop("name", "senditdisabled");
2461  } else {
2462  jQuery("input[name=\"senditdisabled\"]").prop("name", "sendit");
2463  }
2464  return false;
2465  });
2466  $( ".aattachtodoc" ).click(function() {
2467  console.log("We click on toggle of aattachtodoc");
2468  jQuery(".trattachnewfilenow").toggle();
2469  jQuery(".truploadnewfilenow").hide();
2470  return false;
2471  });'."\n";
2472  if (is_array(GETPOST('attachfile', 'array')) && count(GETPOST('attachfile', 'array')) && $action != 'updateline') {
2473  print 'jQuery(".trattachnewfilenow").show();'."\n";
2474  }
2475  print '
2476  jQuery("form[name=\"expensereport\"]").submit(function() {
2477  if (jQuery(".truploadnewfilenow").is(":hidden")) {
2478  /* When section to send file is not expanded, we disable the button sendit that submit form to add a new file, so button to submit line will work. */
2479  jQuery("input[name=\"sendit\"]").val("");
2480  jQuery("input[name=\"sendit\"]").prop("name", "senditdisabled");
2481  } else {
2482  jQuery("input[name=\"senditdisabled\"]").prop("name", "sendit");
2483  }
2484  });
2485  ';
2486  print '
2487  });
2488  ';
2489  print '</script>'."\n";
2490  print '</td></tr>';
2491 
2492  include DOL_DOCUMENT_ROOT.'/expensereport/tpl/expensereport_linktofile.tpl.php';
2493  include DOL_DOCUMENT_ROOT.'/expensereport/tpl/expensereport_addfile.tpl.php';
2494 
2495  print '<tr class="liste_titre expensereportcreate">';
2496  print '<td></td>';
2497  print '<td class="center expensereportcreatedate">'.$langs->trans('Date').'</td>';
2498  if (!empty($conf->project->enabled)) {
2499  print '<td class="minwidth100imp">'.$form->textwithpicto($langs->trans('Project'), $langs->trans("ClosedProjectsAreHidden")).'</td>';
2500  }
2501  print '<td class="center expensereportcreatetype">'.$langs->trans('Type').'</td>';
2502  if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) {
2503  print '<td>'.$langs->trans('CarCategory').'</td>';
2504  }
2505  print '<td class="right expensereportcreatedescription">'.$langs->trans('Description').'</td>';
2506  print '<td class="right expensereportcreatevat">'.$langs->trans('VAT').'</td>';
2507  print '<td class="right expensereportcreatepriceuth">'.$langs->trans('PriceUHT').'</td>';
2508  print '<td class="right expensereportcreatepricettc">'.$langs->trans('PriceUTTC').'</td>';
2509  print '<td class="right expensereportcreateqty">'.$langs->trans('Qty').'</td>';
2510  print '<td></td>';
2511  print '<td></td>';
2512  print '<td></td>';
2513  print '<td></td>';
2514  print '<td></td>';
2515  print '</tr>';
2516  print '<tr class="oddeven nohover">';
2517 
2518  // Line number
2519  print '<td></td>';
2520 
2521  // Select date
2522  print '<td class="center inputdate">';
2523  print $form->selectDate($date ? $date : -1, 'date', 0, 0, 0, '', 1, 1);
2524  print '</td>';
2525 
2526  // Select project
2527  if (!empty($conf->project->enabled)) {
2528  print '<td class="inputproject">';
2529  $formproject->select_projects(-1, $fk_project, 'fk_project', 0, 0, $projectRequired ? 0 : 1, -1, 0, 0, 0, '', 0, 0, 'maxwidth300');
2530  print '</td>';
2531  }
2532 
2533  // Select type
2534  print '<td class="center inputtype">';
2535  print $formexpensereport->selectTypeExpenseReport($fk_c_type_fees, 'fk_c_type_fees', 1);
2536  print '</td>';
2537 
2538  if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) {
2539  print '<td class="fk_c_exp_tax_cat">';
2540  $params = array('fk_expense' => $object->id);
2541  print $form->selectExpenseCategories('', 'fk_c_exp_tax_cat', 1, array(), 'fk_c_type_fees', $userauthor->default_c_exp_tax_cat, $params, 0);
2542  print '</td>';
2543  }
2544 
2545  // Add comments
2546  print '<td class="inputcomment">';
2547  print '<textarea class="flat_ndf centpercent" name="comments" rows="'.ROWS_2.'">'.dol_escape_htmltag($comments, 0, 1).'</textarea>';
2548  print '</td>';
2549 
2550  // Select VAT
2551  print '<td class="right inputvat">';
2552  $defaultvat = -1;
2553  if (!empty($conf->global->EXPENSEREPORT_NO_DEFAULT_VAT)) {
2554  $conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS = 'none';
2555  }
2556  print $form->load_tva('vatrate', ($vatrate != '' ? $vatrate : $defaultvat), $mysoc, '', 0, 0, '', false, 1);
2557  print '</td>';
2558 
2559  // Unit price net
2560  print '<td class="right inputpricenet">';
2561  print '<input type="text" class="right maxwidth50" id="value_unit_ht" name="value_unit_ht" value="'.dol_escape_htmltag($value_unit_ht).'"'.$taxlessUnitPriceDisabled.' />';
2562  print '</td>';
2563 
2564  // Unit price with tax
2565  print '<td class="right inputtax">';
2566  print '<input type="text" class="right maxwidth50" id="value_unit" name="value_unit" value="'.dol_escape_htmltag($value_unit).'">';
2567  print '</td>';
2568 
2569  // Quantity
2570  print '<td class="right inputqty">';
2571  print '<input type="text" min="0" class=" input_qty right maxwidth50" name="qty" value="'.dol_escape_htmltag($qty ? $qty : 1).'">'; // We must be able to enter decimal qty
2572  print '</td>';
2573 
2574  // Picture
2575  print '<td></td>';
2576 
2577  if ($action != 'editline') {
2578  print '<td class="right"></td>';
2579  print '<td class="right"></td>';
2580  }
2581 
2582  print '<td class="center inputbuttons">';
2583  print $form->buttonsSaveCancel("Add", '', '', 1);
2584  print '</td>';
2585 
2586  print '</tr>';
2587  } // Fin si c'est payé/validé
2588 
2589  print '</table>';
2590  print '</div>';
2591  //var_dump($object);
2592  print '<script javascript>
2593 
2594  /* JQuery for product free or predefined select */
2595  jQuery(document).ready(function() {
2596  jQuery("#value_unit_ht").keyup(function(event) {
2597  console.log(event.which); // discard event tag and arrows
2598  if (event.which != 9 && (event.which < 37 ||event.which > 40) && jQuery("#value_unit_ht").val() != "") {
2599  jQuery("#value_unit").val("");
2600  }
2601  });
2602  jQuery("#value_unit").keyup(function(event) {
2603  console.log(event.which); // discard event tag and arrows
2604  if (event.which != 9 && (event.which < 37 || event.which > 40) && jQuery("#value_unit").val() != "") {
2605  jQuery("#value_unit_ht").val("");
2606  }
2607  });
2608 
2609  /* unit price coéf calculation */
2610  jQuery(".input_qty, #fk_c_type_fees, #select_fk_c_exp_tax_cat, #vatrate ").change(function(event) {
2611 
2612  let type_fee = jQuery("#fk_c_type_fees").find(":selected").val();
2613  let tax_cat = jQuery("#select_fk_c_exp_tax_cat").find(":selected").val();
2614  let tva = jQuery("#vatrate").find(":selected").val();
2615  let qty = jQuery(".input_qty").val();
2616 
2617 
2618 
2619  let path = "'.dol_buildpath("/expensereport/ajax/ajaxik.php", 1) .'";
2620  path += "?fk_c_exp_tax_cat="+tax_cat;
2621  path +="&fk_expense="+'.$object->id.';
2622  path += "&vatrate="+tva;
2623  path += "&qty="+qty;
2624 
2625  if (type_fee == 4) { // frais_kilométriques
2626 
2627  if (tax_cat == "" || parseInt(tax_cat) <= 0){
2628  return ;
2629  }
2630 
2631  jQuery.ajax({
2632  url: path
2633  ,async:false
2634  ,dataType:"json"
2635  ,success:function(response) {
2636  if (response.response_status == "success"){
2637  jQuery("#value_unit_ht").val(response.data);
2638  jQuery("#value_unit_ht").trigger("change");
2639  jQuery("#value_unit").val("");
2640  } else if(response.response_status == "error" && response.errorMessage != undefined && response.errorMessage.length > 0 ){
2641  $.jnotify(response.errorMessage, "error", {timeout: 0, type: "error"},{ remove: function (){} } );
2642  }
2643  },
2644 
2645  });
2646  }
2647 
2648  /*console.log(event.which); // discard event tag and arrows
2649  if (event.which != 9 && (event.which < 37 || event.which > 40) && jQuery("#value_unit").val() != "") {
2650  jQuery("#value_unit_ht").val("");
2651  }*/
2652  });
2653 
2654  });
2655 
2656  </script>';
2657 
2658  print '</form>';
2659 
2660  print dol_get_fiche_end();
2661  }
2662  } else {
2663  dol_print_error($db);
2664  }
2665 } else {
2666  print 'Record not found';
2667 
2668  llxFooter();
2669  exit(1);
2670 }
2671 
2672 
2673 /*
2674  * Action bar
2675  */
2676 
2677 print '<div class="tabsAction">';
2678 
2679 if ($action != 'create' && $action != 'edit' && $action != 'editline') {
2680  $object = new ExpenseReport($db);
2681  $object->fetch($id, $ref);
2682 
2683  // Send
2684  if (empty($user->socid)) {
2685  if ($object->status > ExpenseReport::STATUS_DRAFT) {
2686  //if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->expensereport->expensereport_advance->send)) {
2687  print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=presend&mode=init#formmailbeforetitle">'.$langs->trans('SendMail').'</a></div>';
2688  //} else
2689  // print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#">' . $langs->trans('SendMail') . '</a></div>';
2690  }
2691  }
2692 
2693  /* Si l'état est "Brouillon"
2694  * ET user à droit "creer/supprimer"
2695  * ET fk_user_author == user courant
2696  * Afficher : "Enregistrer" / "Modifier" / "Supprimer"
2697  */
2698  if ($user->rights->expensereport->creer && $object->status == ExpenseReport::STATUS_DRAFT) {
2699  if (in_array($object->fk_user_author, $user->getAllChildIds(1)) || !empty($user->rights->expensereport->writeall_advance)) {
2700  // Modify
2701  print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=edit&token='.newToken().'&id='.$object->id.'">'.$langs->trans('Modify').'</a></div>';
2702 
2703  // Validate
2704  if (count($object->lines) > 0) {
2705  print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=save&token='.newToken().'&id='.$object->id.'">'.$langs->trans('ValidateAndSubmit').'</a></div>';
2706  }
2707  }
2708  }
2709 
2710  /* Si l'état est "Refusée"
2711  * ET user à droit "creer/supprimer"
2712  * ET fk_user_author == user courant
2713  * Afficher : "Enregistrer" / "Modifier" / "Supprimer"
2714  */
2715  if ($user->rights->expensereport->creer && $object->status == ExpenseReport::STATUS_REFUSED) {
2716  if ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) {
2717  // Modify
2718  print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=edit&token='.newToken().'&id='.$object->id.'">'.$langs->trans('Modify').'</a></div>';
2719 
2720  // setdraft (le statut refusée est identique à brouillon)
2721  //print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=brouillonner&id='.$id.'">'.$langs->trans('ReOpen').'</a>';
2722  // Enregistrer depuis le statut "Refusée"
2723  print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=save_from_refuse&token='.newToken().'&id='.$object->id.'">'.$langs->trans('ValidateAndSubmit').'</a></div>';
2724  }
2725  }
2726 
2727  if ($user->rights->expensereport->to_paid && $object->status == ExpenseReport::STATUS_APPROVED) {
2728  if ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) {
2729  // setdraft
2730  print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=setdraft&token='.newToken().'&id='.$object->id.'">'.$langs->trans('SetToDraft').'</a></div>';
2731  }
2732  }
2733 
2734  /* Si l'état est "En attente d'approbation"
2735  * ET user à droit de "approve"
2736  * ET fk_user_validator == user courant
2737  * Afficher : "Valider" / "Refuser" / "Supprimer"
2738  */
2739  if ($object->status == ExpenseReport::STATUS_VALIDATED) {
2740  if (in_array($object->fk_user_author, $user->getAllChildIds(1))) {
2741  // set draft
2742  print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=setdraft&token='.newToken().'&id='.$object->id.'">'.$langs->trans('SetToDraft').'</a></div>';
2743  }
2744  }
2745 
2746  if ($user->rights->expensereport->approve && $object->status == ExpenseReport::STATUS_VALIDATED) {
2747  //if($object->fk_user_validator==$user->id)
2748  //{
2749  // Validate
2750  print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=validate&id='.$object->id.'">'.$langs->trans('Approve').'</a></div>';
2751  // Deny
2752  print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=refuse&id='.$object->id.'">'.$langs->trans('Deny').'</a></div>';
2753  //}
2754 
2755  if ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) {
2756  // Cancel
2757  print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=cancel&id='.$object->id.'">'.$langs->trans("Cancel").'</a></div>';
2758  }
2759  }
2760 
2761 
2762  // If status is Approved
2763  // ---------------------
2764 
2765  if ($user->rights->expensereport->approve && $object->status == ExpenseReport::STATUS_APPROVED) {
2766  print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=refuse&id='.$object->id.'">'.$langs->trans('Deny').'</a></div>';
2767  }
2768 
2769  // If bank module is used
2770  if ($user->rights->expensereport->to_paid && !empty($conf->banque->enabled) && $object->status == ExpenseReport::STATUS_APPROVED) {
2771  // Pay
2772  if ($remaintopay == 0) {
2773  print '<div class="inline-block divButAction"><span class="butActionRefused classfortooltip" title="'.$langs->trans("DisabledBecauseRemainderToPayIsZero").'">'.$langs->trans('DoPayment').'</span></div>';
2774  } else {
2775  print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/expensereport/payment/payment.php?id='.$object->id.'&amp;action=create">'.$langs->trans('DoPayment').'</a></div>';
2776  }
2777  }
2778 
2779  // If bank module is not used
2780  if (($user->rights->expensereport->to_paid || empty($conf->banque->enabled)) && $object->status == ExpenseReport::STATUS_APPROVED) {
2781  //if ((round($remaintopay) == 0 || empty($conf->banque->enabled)) && $object->paid == 0)
2782  if ($object->paid == 0) {
2783  print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=set_paid&token='.newToken().'">'.$langs->trans("ClassifyPaid")."</a></div>";
2784  }
2785  }
2786 
2787  if ($user->rights->expensereport->creer && ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) && $object->status == ExpenseReport::STATUS_APPROVED) {
2788  // Cancel
2789  print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=cancel&token='.newToken().'&id='.$object->id.'">'.$langs->trans("Cancel").'</a></div>';
2790  }
2791 
2792  // TODO Replace this. It should be SetUnpaid and should go back to status unpaid not canceled.
2793  if (($user->rights->expensereport->approve || $user->rights->expensereport->to_paid) && $object->status == ExpenseReport::STATUS_CLOSED) {
2794  // Cancel
2795  print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=cancel&token='.newToken().'&id='.$object->id.'">'.$langs->trans("Cancel").'</a></div>';
2796  }
2797 
2798  if ($user->rights->expensereport->to_paid && $object->paid && $object->status == ExpenseReport::STATUS_CLOSED) {
2799  // Set unpaid
2800  print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=set_unpaid&token='.newToken().'&id='.$object->id.'">'.$langs->trans('ClassifyUnPaid').'</a></div>';
2801  }
2802 
2803  // Clone
2804  if ($user->rights->expensereport->creer) {
2805  print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=clone&token='.newToken().'">'.$langs->trans("ToClone").'</a></div>';
2806  }
2807 
2808  /* If draft, validated, cancel, and user can create, he can always delete its card before it is approved */
2809  if ($user->rights->expensereport->creer && $user->id == $object->fk_user_author && $object->status < ExpenseReport::STATUS_APPROVED) {
2810  // Delete
2811  print '<div class="inline-block divButAction"><a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?action=delete&token='.newToken().'&id='.$object->id.'">'.$langs->trans('Delete').'</a></div>';
2812  } elseif ($candelete && $object->status != ExpenseReport::STATUS_CLOSED) {
2813  // Delete
2814  print '<div class="inline-block divButAction"><a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?action=delete&token='.newToken().'&id='.$object->id.'">'.$langs->trans('Delete').'</a></div>';
2815  }
2816 
2817  $parameters = array();
2818  $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
2819 }
2820 
2821 print '</div>';
2822 
2823 
2824 // Select mail models is same action as presend
2825 if (GETPOST('modelselected', 'alpha')) {
2826  $action = 'presend';
2827 }
2828 
2829 if ($action != 'presend') {
2830  /*
2831  * Generate documents
2832  */
2833 
2834  print '<div class="fichecenter"><div class="fichehalfleft">';
2835  print '<a name="builddoc"></a>'; // ancre
2836 
2837  if ($user->rights->expensereport->creer && $action != 'create' && $action != 'edit') {
2838  $filename = dol_sanitizeFileName($object->ref);
2839  $filedir = $conf->expensereport->dir_output."/".dol_sanitizeFileName($object->ref);
2840  $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
2841  $genallowed = $user->rights->expensereport->creer;
2842  $delallowed = $user->rights->expensereport->creer;
2843  $var = true;
2844  print $formfile->showdocuments('expensereport', $filename, $filedir, $urlsource, $genallowed, $delallowed);
2845  $somethingshown = $formfile->numoffiles;
2846  }
2847 
2848  // Disabled for expensereport, there is no thirdparty on expensereport, so nothing to define the list of other object we can suggest to link to
2849  /*
2850  if ($action != 'create' && $action != 'edit' && ($id || $ref))
2851  {
2852  $linktoelem = $form->showLinkToObjectBlock($object, null, array('expensereport'));
2853  $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
2854  }
2855  */
2856 
2857  print '</div><div class="fichehalfright">';
2858  // List of actions on element
2859  include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
2860  $formactions = new FormActions($db);
2861  $somethingshown = $formactions->showactions($object, 'expensereport', null);
2862 
2863  print '</div></div>';
2864 }
2865 
2866 // Presend form
2867 $modelmail = 'expensereport';
2868 $defaulttopic = 'SendExpenseReportRef';
2869 $diroutput = $conf->expensereport->dir_output;
2870 $trackid = 'exp'.$object->id;
2871 
2872 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
2873 
2874 
2875 llxFooter();
2876 
2877 $db->close();
dol_convert_file($fileinput, $ext= 'png', $fileoutput= '', $page= '')
Convert an image file or a PDF into another image format.
Definition: files.lib.php:1963
GETPOST($paramname, $check= 'alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
img_edit($titlealt= 'default', $float=0, $other= '')
Show logo editer/modifier fiche.
if(preg_match('/set_([a-z0-9_\-]+)/i', $action, $reg)) if(preg_match('/del_([a-z0-9_\-]+)/i', $action, $reg)) if($action== 'set') elseif($action== 'specimen') elseif($action== 'setmodel') elseif($action== 'del') elseif($action== 'setdoc') $formactions
View.
Class to manage generation of HTML components for contract module.
const STATUS_APPROVED
Classified approved.
const STATUS_VALIDATED
Validated (need to be paid)
if($cancel &&!$id) if($action== 'add'&&!$cancel) if($action== 'delete') if($id) $form
Actions.
Definition: card.php:142
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...
Class to manage building of HTML components.
Class of expense report details lines.
dol_now($mode= 'auto')
Return date for now.
get_date_range($date_start, $date_end, $format= '', $outputlangs= '', $withparenthesis=1)
Format output for start and end date.
Class to manage Dolibarr users.
Definition: user.class.php:44
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOCSRFCHECK')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
Definition: wrapper.php:59
const STATUS_CLOSED
Classified paid.
dol_clone($object, $native=0)
Create a clone of instance of object (new instance with same value for properties) With native = 0: P...
const STATUS_CANCELED
Classified canceled.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags= '', $escapeonlyhtmltags=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields...
dol_getIdFromCode($db, $key, $tablename, $fieldkey= 'code', $fieldid= 'id', $entityfilter=0, $filters= '')
Return an id or code from a code or id.
if(GETPOST('button_removefilter_x', 'alpha')||GETPOST('button_removefilter.x', 'alpha')||GETPOST('button_removefilter', 'alpha')) if(GETPOST('button_search_x', 'alpha')||GETPOST('button_search.x', 'alpha')||GETPOST('button_search', 'alpha')) if($action=="save"&&empty($cancel)) $help_url
View.
Definition: agenda.php:116
img_mime($file, $titlealt= '', $morecss= '')
Show MIME img of a file.
const STATUS_REFUSED
Classified refused.
Class to manage bank accounts.
image_format_supported($file, $acceptsvg=0)
Return if a filename is file name of a supported image format.
Definition: images.lib.php:58
img_warning($titlealt= 'default', $moreatt= '', $morecss= 'pictowarning')
Show warning logo.
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...
isValidEmail($address, $acceptsupervisorkey=0, $acceptuserkey=0)
Return true if email syntax is ok.
Class to manage standard extra fields.
getImageFileNameForSize($file, $extName, $extImgTarget= '')
Return the filename of file to get the thumbs.
setEventMessages($mesg, $mesgs, $style= 'mesgs', $messagekey= '')
Set event messages in dol_events session object.
Class to manage generation of HTML components Only common components must be here.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form...
Class to manage projects.
load_fiche_titre($titre, $morehtmlright= '', $picto= 'generic', $pictoisfullpath=0, $id= '', $morecssontable= '', $morehtmlcenter= '')
Load a title with picto.
price2num($amount, $rounding= '', $option=0)
Function that return a number with universal decimal format (decimal separator is &#39;...
Class to manage building of HTML components.
Class to send emails (with attachments or not) Usage: $mailfile = new CMailFile($subject,$sendto,$replyto,$message,$filepath,$mimetype,$filename,$cc,$ccc,$deliveryreceipt,$msgishtml,$errors_to,$css,$trackid,$moreinheader,$sendcontext,$replyto); $mailfile-&gt;sendfile();.
img_picto($titlealt, $picto, $moreatt= '', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt= '', $morecss= '', $marginleftonlyshort=2)
Show picto whatever it&#39;s its name (generic function)
expensereport_prepare_head($object)
Prepare array with list of tabs.
accessforbidden($message= '', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program Calling this function terminate execution ...
Class to manage translations.
dol_sanitizeFileName($str, $newstr= '_', $unaccent=1)
Clean a string to use it as a file name.
dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0)
Scan a directory and return a list of files/directories.
Definition: files.lib.php:60
Class to manage Trips and Expenses.
Class to offer components to list and upload files.
dol_is_file($pathoffile)
Return if path is a file.
Definition: files.lib.php:476
restrictedArea($user, $features, $objectid=0, $tableandshare= '', $feature2= '', $dbt_keyfield= 'fk_soc', $dbt_select= 'rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.
if(isModEnabled('facture')&&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur')&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)&&$user->rights->fournisseur->facture->lire)||(isModEnabled('supplier_invoice')&&$user->rights->supplier_invoice->lire)) if(isModEnabled('don')&&!empty($user->rights->don->lire)) if(isModEnabled('tax')&&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture')&&isModEnabled('commande')&&$user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
Definition: index.php:742
dol_get_fiche_head($links=array(), $active= '', $title= '', $notab=0, $picto= '', $pictoisfullpath=0, $morehtmlright= '', $morecss= '', $limittoshow=0, $moretabssuffix= '')
Show tabs of a record.
dol_print_date($time, $format= '', $tzoutput= 'auto', $outputlangs= '', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
Class to manage payments of expense report.
dol_print_error($db= '', $error= '', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
newToken()
Return the value of token currently saved into session with name &#39;newtoken&#39;.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
Class to manage a WYSIWYG editor.
Class to manage accounting accounts.
Class to manage accounting accounts.
dol_banner_tab($object, $paramid, $morehtml= '', $shownav=1, $fieldid= 'rowid', $fieldref= 'ref', $morehtmlref= '', $moreparam= '', $nodbprefix=0, $morehtmlleft= '', $morehtmlstatus= '', $onlybanner=0, $morehtmlright= '')
Show tab footer of a card.
llxFooter()
Empty footer.
Definition: wrapper.php:73
img_delete($titlealt= 'default', $other= 'class="pictodelete"', $morecss= '')
Show delete logo.
Class to manage ECM files.
const STATUS_DRAFT
Draft status.
getAdvancedPreviewUrl($modulepart, $relativepath, $alldata=0, $param= '')
Return URL we can use for advanced preview links.
$formconfirm
if ($action == &#39;delbookkeepingyear&#39;) {
fetch($id, $ref= '', $relativepath= '', $hashoffile= '', $hashforshare= '', $src_object_type= '', $src_object_id=0)
Load object in memory from the database.