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