dolibarr  17.0.4
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' || $action == 'updateFromRefuse') && $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", '', '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  $error++;
1214  setEventMessages($object->error, $object->errors, 'errors');
1215  }
1216  }
1217 
1218  if (!$error) {
1219  header("Location: ".$_SERVER["PHP_SELF"]."?id=".GETPOST('id', 'int'));
1220  exit;
1221  } else {
1222  $action = '';
1223  }
1224  }
1225 
1226  if ($action == 'confirm_delete_line' && GETPOST("confirm", 'alpha') == "yes" && $user->rights->expensereport->creer) {
1227  $object = new ExpenseReport($db);
1228  $object->fetch($id);
1229 
1230  $object_ligne = new ExpenseReportLine($db);
1231  $object_ligne->fetch(GETPOST("rowid", 'int'));
1232  $total_ht = $object_ligne->total_ht;
1233  $total_tva = $object_ligne->total_tva;
1234 
1235  $result = $object->deleteline(GETPOST("rowid", 'int'), $user);
1236  if ($result >= 0) {
1237  if ($result > 0) {
1238  // Define output language
1239  if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
1240  $outputlangs = $langs;
1241  $newlang = '';
1242  if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
1243  $newlang = GETPOST('lang_id', 'aZ09');
1244  }
1245  if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1246  $newlang = $object->thirdparty->default_lang;
1247  }
1248  if (!empty($newlang)) {
1249  $outputlangs = new Translate("", $conf);
1250  $outputlangs->setDefaultLang($newlang);
1251  }
1252  $model = $object->model_pdf;
1253  $ret = $object->fetch($id); // Reload to get new records
1254 
1255  $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
1256  }
1257  }
1258 
1259  header("Location: ".$_SERVER["PHP_SELF"]."?id=".GETPOST('id', 'int'));
1260  exit;
1261  } else {
1262  setEventMessages($object->error, $object->errors, 'errors');
1263  }
1264  }
1265 
1266  if ($action == "updateline" && $user->rights->expensereport->creer) {
1267  $object = new ExpenseReport($db);
1268  $object->fetch($id);
1269 
1270  // First save uploaded file
1271  $fk_ecm_files = 0;
1272  if (GETPOSTISSET('attachfile')) {
1273  $arrayoffiles = GETPOST('attachfile', 'array');
1274  if (is_array($arrayoffiles) && !empty($arrayoffiles[0])) {
1275  include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
1276  $relativepath = 'expensereport/'.$object->ref.'/'.$arrayoffiles[0];
1277  $ecmfiles = new EcmFiles($db);
1278  $ecmfiles->fetch(0, '', $relativepath);
1279  $fk_ecm_files = $ecmfiles->id;
1280  }
1281  }
1282 
1283  $rowid = GETPOST('rowid', 'int');
1284  $type_fees_id = GETPOST('fk_c_type_fees', 'int');
1285  $fk_c_exp_tax_cat = GETPOST('fk_c_exp_tax_cat', 'int');
1286  $projet_id = $fk_project;
1287  $comments = GETPOST('comments', 'restricthtml');
1288  $qty = price2num(GETPOST('qty', 'alpha'));
1289  $vatrate = GETPOST('vatrate', 'alpha');
1290 
1291  // if VAT is not used in Dolibarr, set VAT rate to 0 because VAT rate is necessary.
1292  if (empty($vatrate)) {
1293  $vatrate = "0.000";
1294  }
1295  $tmpvat = price2num(preg_replace('/\s*\‍(.*\‍)/', '', $vatrate));
1296 
1297  $value_unit_ht = price2num(GETPOST('value_unit_ht', 'alpha'), 'MU');
1298  $value_unit = price2num(GETPOST('value_unit', 'alpha'), 'MU');
1299  if (empty($value_unit)) {
1300  $value_unit = price2num($value_unit_ht + ($value_unit_ht * $tmpvat / 100), 'MU');
1301  }
1302 
1303  if (!GETPOST('fk_c_type_fees', 'int') > 0) {
1304  $error++;
1305  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors');
1306  $action = '';
1307  }
1308  if ((float) $tmpvat < 0 || $tmpvat == '') {
1309  $error++;
1310  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Vat")), null, 'errors');
1311  $action = '';
1312  }
1313  // Warning if date out of range
1314  if ($date < $object->date_debut || $date > ($object->date_fin + (24 * 3600 - 1))) {
1315  $langs->load("errors");
1316  setEventMessages($langs->trans("WarningDateOfLineMustBeInExpenseReportRange"), null, 'warnings');
1317  }
1318 
1319  // If no project entered
1320  if ($projectRequired && $projet_id <= 0) {
1321  $error++;
1322  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Project")), null, 'errors');
1323  }
1324 
1325  if (!$error) {
1326  // TODO Use update method of ExpenseReportLine
1327  $result = $object->updateline($rowid, $type_fees_id, $projet_id, $vatrate, $comments, $qty, $value_unit, $date, $id, $fk_c_exp_tax_cat, $fk_ecm_files);
1328  if ($result >= 0) {
1329  if ($result > 0) {
1330  // Define output language
1331  if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
1332  $outputlangs = $langs;
1333  $newlang = '';
1334  if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
1335  $newlang = GETPOST('lang_id', 'aZ09');
1336  }
1337  if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1338  $newlang = $object->thirdparty->default_lang;
1339  }
1340  if (!empty($newlang)) {
1341  $outputlangs = new Translate("", $conf);
1342  $outputlangs->setDefaultLang($newlang);
1343  }
1344  $model = $object->model_pdf;
1345  $ret = $object->fetch($id); // Reload to get new records
1346 
1347  $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
1348  }
1349 
1350  unset($qty);
1351  unset($value_unit_ht);
1352  unset($value_unit);
1353  unset($vatrate);
1354  unset($comments);
1355  unset($fk_c_type_fees);
1356  unset($fk_project);
1357  unset($date);
1358  }
1359 
1360  //header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id);
1361  //exit;
1362  } else {
1363  setEventMessages($object->error, $object->errors, 'errors');
1364  }
1365  }
1366  }
1367 
1368  // Actions when printing a doc from card
1369  include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
1370 
1371  // Actions to send emails
1372  $triggersendname = 'EXPENSEREPORT_SENTBYMAIL';
1373  $autocopy = 'MAIN_MAIL_AUTOCOPY_EXPENSEREPORT_TO';
1374  $trackid = 'exp'.$object->id;
1375  include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
1376 
1377  // Actions to build doc
1378  $upload_dir = $conf->expensereport->dir_output;
1379  include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
1380 }
1381 
1382 
1383 /*
1384  * View
1385  */
1386 
1387 $title = $langs->trans("ExpenseReport")." - ".$langs->trans("Card");
1388 $help_url = "EN:Module_Expense_Reports|FR:Module_Notes_de_frais";
1389 
1390 llxHeader("", $title, $help_url);
1391 
1392 $form = new Form($db);
1393 $formfile = new FormFile($db);
1394 $formproject = new FormProjets($db);
1395 $projecttmp = new Project($db);
1396 $paymentexpensereportstatic = new PaymentExpenseReport($db);
1397 $bankaccountstatic = new Account($db);
1398 $ecmfilesstatic = new EcmFiles($db);
1399 $formexpensereport = new FormExpenseReport($db);
1400 
1401 // Create
1402 if ($action == 'create') {
1403  print load_fiche_titre($langs->trans("NewTrip"), '', 'trip');
1404 
1405  print '<form action="'.$_SERVER['PHP_SELF'].'" method="post" name="create">';
1406  print '<input type="hidden" name="token" value="'.newToken().'">';
1407  print '<input type="hidden" name="action" value="add">';
1408 
1409  print dol_get_fiche_head('');
1410 
1411  print '<table class="border centpercent">';
1412  print '<tbody>';
1413 
1414  // Date start
1415  print '<tr>';
1416  print '<td class="titlefieldcreate fieldrequired">'.$langs->trans("DateStart").'</td>';
1417  print '<td>';
1418  print $form->selectDate($date_start ? $date_start : -1, 'date_debut', 0, 0, 0, '', 1, 1);
1419  print '</td>';
1420  print '</tr>';
1421 
1422  // Date end
1423  print '<tr>';
1424  print '<td class="fieldrequired">'.$langs->trans("DateEnd").'</td>';
1425  print '<td>';
1426  print $form->selectDate($date_end ? $date_end : -1, 'date_fin', 0, 0, 0, '', 1, 1);
1427  print '</td>';
1428  print '</tr>';
1429 
1430  // User for expense report
1431  print '<tr>';
1432  print '<td class="fieldrequired">'.$langs->trans("User").'</td>';
1433  print '<td>';
1434  $defaultselectuser = $user->id;
1435  if (GETPOST('fk_user_author', 'int') > 0) {
1436  $defaultselectuser = GETPOST('fk_user_author', 'int');
1437  }
1438  $include_users = 'hierarchyme';
1439  if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->expensereport->writeall_advance)) {
1440  $include_users = array();
1441  }
1442  $s = $form->select_dolusers($defaultselectuser, "fk_user_author", 0, "", 0, $include_users, '', '0,'.$conf->entity);
1443  print $s;
1444  print '</td>';
1445  print '</tr>';
1446 
1447  // Approver
1448  print '<tr>';
1449  print '<td>'.$langs->trans("VALIDATOR").'</td>';
1450  print '<td>';
1451  $object = new ExpenseReport($db);
1452  $include_users = $object->fetch_users_approver_expensereport();
1453  if (empty($include_users)) {
1454  print img_warning().' '.$langs->trans("NobodyHasPermissionToValidateExpenseReport");
1455  } else {
1456  $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
1457  if (!empty($conf->global->EXPENSEREPORT_DEFAULT_VALIDATOR)) {
1458  $defaultselectuser = $conf->global->EXPENSEREPORT_DEFAULT_VALIDATOR; // Can force default approver
1459  }
1460  if (GETPOST('fk_user_validator', 'int') > 0) {
1461  $defaultselectuser = GETPOST('fk_user_validator', 'int');
1462  }
1463  $s = $form->select_dolusers($defaultselectuser, "fk_user_validator", 1, "", ((empty($defaultselectuser) || empty($conf->global->EXPENSEREPORT_DEFAULT_VALIDATOR_UNCHANGEABLE)) ? 0 : 1), $include_users);
1464  print $form->textwithpicto($s, $langs->trans("AnyOtherInThisListCanValidate"));
1465  }
1466  print '</td>';
1467  print '</tr>';
1468 
1469  // Payment mode
1470  if (!empty($conf->global->EXPENSEREPORT_ASK_PAYMENTMODE_ON_CREATION)) {
1471  print '<tr>';
1472  print '<td>'.$langs->trans("ModePaiement").'</td>';
1473  print '<td>';
1474  $form->select_types_paiements('', 'fk_c_paiement');
1475  print '</td>';
1476  print '</tr>';
1477  }
1478 
1479  // Public note
1480  $note_public = GETPOSTISSET('note_public') ? GETPOST('note_public', 'restricthtml') : '';
1481 
1482  print '<tr>';
1483  print '<td class="tdtop">'.$langs->trans('NotePublic').'</td>';
1484  print '<td>';
1485 
1486  $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%');
1487  print $doleditor->Create(1);
1488  print '</td></tr>';
1489 
1490  // Private note
1491  $note_private = GETPOSTISSET('note_private') ? GETPOST('note_private', 'restricthtml') : '';
1492 
1493  if (empty($user->socid)) {
1494  print '<tr>';
1495  print '<td class="tdtop">'.$langs->trans('NotePrivate').'</td>';
1496  print '<td>';
1497 
1498  $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%');
1499  print $doleditor->Create(1);
1500  print '</td></tr>';
1501  }
1502 
1503  // Other attributes
1504  $parameters = array('colspan' => ' colspan="3"', 'cols' => 3);
1505  $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by
1506  print $hookmanager->resPrint;
1507  if (empty($reshook)) {
1508  print $object->showOptionals($extrafields, 'create', $parameters);
1509  }
1510 
1511  print '<tbody>';
1512  print '</table>';
1513 
1514  print dol_get_fiche_end();
1515 
1516  print $form->buttonsSaveCancel("AddTrip");
1517 
1518  print '</form>';
1519 } elseif ($id > 0 || $ref) {
1520  $result = $object->fetch($id, $ref);
1521 
1522  if ($result > 0) {
1523  if (!in_array($object->fk_user_author, $user->getAllChildIds(1))) {
1524  if (empty($user->rights->expensereport->readall) && empty($user->rights->expensereport->lire_tous)
1525  && (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || empty($user->rights->expensereport->writeall_advance))) {
1526  print load_fiche_titre($langs->trans('TripCard'), '', 'trip');
1527 
1528  print '<div class="tabBar">';
1529  print $langs->trans('NotUserRightToView');
1530  print '</div>';
1531 
1532  // End of page
1533  llxFooter();
1534  $db->close();
1535 
1536  exit;
1537  }
1538  }
1539 
1540  $head = expensereport_prepare_head($object);
1541 
1542  if ($action == 'edit' && ($object->status < 3 || $object->status == 99)) {
1543  print "<form name='update' action=\"".$_SERVER['PHP_SELF']."\" method=\"post\">\n";
1544  print '<input type="hidden" name="token" value="'.newToken().'">';
1545  print '<input type="hidden" name="id" value="'.$id.'">';
1546 
1547  print dol_get_fiche_head($head, 'card', $langs->trans("ExpenseReport"), 0, 'trip');
1548 
1549  if ($object->status == 99) {
1550  print '<input type="hidden" name="action" value="updateFromRefuse">';
1551  } else {
1552  print '<input type="hidden" name="action" value="update">';
1553  }
1554 
1555  $linkback = '<a href="'.DOL_URL_ROOT.'/expensereport/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
1556 
1557  print '<table class="border" style="width:100%;">';
1558 
1559  print '<tr>';
1560  print '<td>'.$langs->trans("User").'</td>';
1561  print '<td>';
1562  $userfee = new User($db);
1563  if ($object->fk_user_author > 0) {
1564  $userfee->fetch($object->fk_user_author);
1565  print $userfee->getNomUrl(-1);
1566  }
1567  print '</td></tr>';
1568 
1569  // Ref
1570  print '<tr><td class="titlefieldcreate">'.$langs->trans("Ref").'</td><td>';
1571  print $form->showrefnav($object, 'ref', $linkback, 1, 'ref', 'ref', '');
1572  print '</td></tr>';
1573 
1574  print '<tr>';
1575  print '<td>'.$langs->trans("DateStart").'</td>';
1576  print '<td>';
1577  print $form->selectDate($object->date_debut, 'date_debut');
1578  print '</td>';
1579  print '</tr>';
1580  print '<tr>';
1581  print '<td>'.$langs->trans("DateEnd").'</td>';
1582  print '<td>';
1583  print $form->selectDate($object->date_fin, 'date_fin');
1584  print '</td>';
1585  print '</tr>';
1586 
1587  if (!empty($conf->global->EXPENSEREPORT_ASK_PAYMENTMODE_ON_CREATION)) {
1588  print '<tr>';
1589  print '<td>'.$langs->trans("ModePaiement").'</td>';
1590  print '<td>';
1591  $form->select_types_paiements($object->fk_c_paiement, 'fk_c_paiement');
1592  print '</td>';
1593  print '</tr>';
1594  }
1595 
1596  if ($object->status < 3) {
1597  print '<tr>';
1598  print '<td>'.$langs->trans("VALIDATOR").'</td>'; // Approbator
1599  print '<td>';
1600  $include_users = $object->fetch_users_approver_expensereport();
1601  $s = $form->select_dolusers($object->fk_user_validator, "fk_user_validator", 1, "", 0, $include_users);
1602  print $form->textwithpicto($s, $langs->trans("AnyOtherInThisListCanValidate"));
1603  print '</td>';
1604  print '</tr>';
1605  } else {
1606  print '<tr>';
1607  print '<td>'.$langs->trans("VALIDOR").'</td>';
1608  print '<td>';
1609  $userfee = new User($db);
1610  $userfee->fetch($object->fk_user_valid);
1611  print $userfee->getNomUrl(-1);
1612  print '</td></tr>';
1613  }
1614 
1615  if ($object->status == 6) {
1616  print '<tr>';
1617  print '<td>'.$langs->trans("AUTHORPAIEMENT").'</td>';
1618  print '<td>';
1619  $userfee = new User($db);
1620  $userfee->fetch($user->id);
1621  print $userfee->getNomUrl(-1);
1622  print '</td></tr>';
1623  }
1624 
1625  // Other attributes
1626  //$cols = 3;
1627  //include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_edit.tpl.php';
1628 
1629  print '</table>';
1630 
1631  print dol_get_fiche_end();
1632 
1633  print $form->buttonsSaveCancel("Modify");
1634 
1635  print '</form>';
1636  } else {
1637  $taxlessUnitPriceDisabled = !empty($conf->global->EXPENSEREPORT_FORCE_LINE_AMOUNTS_INCLUDING_TAXES_ONLY) ? ' disabled' : '';
1638 
1639  print dol_get_fiche_head($head, 'card', $langs->trans("ExpenseReport"), -1, 'trip');
1640 
1641  $formconfirm = '';
1642 
1643  // Clone confirmation
1644  if ($action == 'clone') {
1645  // Create an array for form
1646  $criteriaforfilter = 'hierarchyme';
1647  if (!empty($user->rights->expensereport->readall)) {
1648  $criteriaforfilter = '';
1649  }
1650  $formquestion = array(
1651  'text' => '',
1652  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'))
1653  );
1654  // Paiement incomplet. On demande si motif = escompte ou autre
1655  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneExpenseReport', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
1656  }
1657 
1658  if ($action == 'save') {
1659  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id, $langs->trans("SaveTrip"), $langs->trans("ConfirmSaveTrip"), "confirm_validate", "", "", 1);
1660  }
1661 
1662  if ($action == 'save_from_refuse') {
1663  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id, $langs->trans("SaveTrip"), $langs->trans("ConfirmSaveTrip"), "confirm_save_from_refuse", "", "", 1);
1664  }
1665 
1666  if ($action == 'delete') {
1667  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id, $langs->trans("DeleteTrip"), $langs->trans("ConfirmDeleteTrip"), "confirm_delete", "", "", 1);
1668  }
1669 
1670  if ($action == 'validate') {
1671  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id, $langs->trans("ValideTrip"), $langs->trans("ConfirmValideTrip"), "confirm_approve", "", "", 1);
1672  }
1673 
1674  if ($action == 'paid') {
1675  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id, $langs->trans("PaidTrip"), $langs->trans("ConfirmPaidTrip"), "confirm_paid", "", "", 1);
1676  }
1677 
1678  if ($action == 'cancel') {
1679  $array_input = array('text'=>$langs->trans("ConfirmCancelTrip"), array('type'=>"text", 'label'=>'<strong>'.$langs->trans("Comment").'</strong>', 'name'=>"detail_cancel", 'value'=>""));
1680  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id, $langs->trans("Cancel"), "", "confirm_cancel", $array_input, "", 1);
1681  }
1682 
1683  if ($action == 'setdraft') {
1684  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id, $langs->trans("BrouillonnerTrip"), $langs->trans("ConfirmBrouillonnerTrip"), "confirm_setdraft", "", "", 1);
1685  }
1686 
1687  if ($action == 'refuse') { // Deny
1688  $array_input = array('text'=>$langs->trans("ConfirmRefuseTrip"), array('type'=>"text", 'label'=>$langs->trans("Comment"), 'name'=>"detail_refuse", 'value'=>""));
1689  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id, $langs->trans("Deny"), '', "confirm_refuse", $array_input, "yes", 1);
1690  }
1691 
1692  if ($action == 'delete_line') {
1693  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id."&rowid=".GETPOST('rowid', 'int'), $langs->trans("DeleteLine"), $langs->trans("ConfirmDeleteLine"), "confirm_delete_line", '', 'yes', 1);
1694  }
1695 
1696  // Print form confirm
1697  print $formconfirm;
1698 
1699  // Expense report card
1700  $linkback = '<a href="'.DOL_URL_ROOT.'/expensereport/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
1701 
1702  $morehtmlref = '<div class="refidno">';
1703  $morehtmlref .= '</div>';
1704 
1705  dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
1706 
1707  print '<div class="fichecenter">';
1708  print '<div class="fichehalfleft">';
1709  print '<div class="underbanner clearboth"></div>';
1710 
1711  print '<table class="border tableforfield centpercent">';
1712 
1713  // Author
1714  print '<tr>';
1715  print '<td class="titlefield">'.$langs->trans("User").'</td>';
1716  print '<td>';
1717  if ($object->fk_user_author > 0) {
1718  $userauthor = new User($db);
1719  $result = $userauthor->fetch($object->fk_user_author);
1720  if ($result < 0) {
1721  dol_print_error('', $userauthor->error);
1722  } elseif ($result > 0) {
1723  print $userauthor->getNomUrl(-1);
1724  }
1725  }
1726  print '</td></tr>';
1727 
1728  // Period
1729  print '<tr>';
1730  print '<td class="titlefield">'.$langs->trans("Period").'</td>';
1731  print '<td>';
1732  print get_date_range($object->date_debut, $object->date_fin, 'day', $langs, 0);
1733  print '</td>';
1734  print '</tr>';
1735  if (!empty($conf->global->EXPENSEREPORT_ASK_PAYMENTMODE_ON_CREATION)) {
1736  print '<tr>';
1737  print '<td>'.$langs->trans("ModePaiement").'</td>';
1738  print '<td>'.$object->fk_c_paiement.'</td>';
1739  print '</tr>';
1740  }
1741 
1742  // Validation date
1743  print '<tr>';
1744  print '<td>'.$langs->trans("DATE_SAVE").'</td>';
1745  print '<td>'.dol_print_date($object->date_valid, 'dayhour', 'tzuser');
1746  if ($object->status == 2 && $object->hasDelay('toapprove')) {
1747  print ' '.img_warning($langs->trans("Late").' - '.$langs->trans("ToApprove"));
1748  }
1749  if ($object->status == 5 && $object->hasDelay('topay')) {
1750  print ' '.img_warning($langs->trans("Late").' - '.$langs->trans("ToPay"));
1751  }
1752  print '</td></tr>';
1753  print '</tr>';
1754 
1755  // User to inform for approval
1756  if ($object->status <= ExpenseReport::STATUS_VALIDATED) { // informed
1757  print '<tr>';
1758  print '<td>'.$langs->trans("VALIDATOR").'</td>'; // approver
1759  print '<td>';
1760  if ($object->fk_user_validator > 0) {
1761  $userfee = new User($db);
1762  $result = $userfee->fetch($object->fk_user_validator);
1763  if ($result > 0) {
1764  print $userfee->getNomUrl(-1);
1765  }
1766  if (empty($userfee->email) || !isValidEmail($userfee->email)) {
1767  $langs->load("errors");
1768  print img_warning($langs->trans("ErrorBadEMail", $userfee->email));
1769  }
1770  }
1771  print '</td></tr>';
1772  } elseif ($object->status == ExpenseReport::STATUS_CANCELED) {
1773  print '<tr>';
1774  print '<td>'.$langs->trans("CANCEL_USER").'</span></td>';
1775  print '<td>';
1776  if ($object->fk_user_cancel > 0) {
1777  $userfee = new User($db);
1778  $result = $userfee->fetch($object->fk_user_cancel);
1779  if ($result > 0) {
1780  print $userfee->getNomUrl(-1);
1781  }
1782  }
1783  print '</td></tr>';
1784 
1785  print '<tr>';
1786  print '<td>'.$langs->trans("MOTIF_CANCEL").'</td>';
1787  print '<td>'.$object->detail_cancel.'</td></tr>';
1788  print '</tr>';
1789  print '<tr>';
1790  print '<td>'.$langs->trans("DATE_CANCEL").'</td>';
1791  print '<td>'.dol_print_date($object->date_cancel, 'dayhour', 'tzuser').'</td></tr>';
1792  print '</tr>';
1793  } else {
1794  print '<tr>';
1795  print '<td>'.$langs->trans("ApprovedBy").'</td>';
1796  print '<td>';
1797  if ($object->fk_user_approve > 0) {
1798  $userapp = new User($db);
1799  $result = $userapp->fetch($object->fk_user_approve);
1800  if ($result > 0) {
1801  print $userapp->getNomUrl(-1);
1802  }
1803  }
1804  print '</td></tr>';
1805 
1806  print '<tr>';
1807  print '<td>'.$langs->trans("DateApprove").'</td>';
1808  print '<td>'.dol_print_date($object->date_approve, 'dayhour', 'tzuser').'</td></tr>';
1809  print '</tr>';
1810  }
1811 
1812  if ($object->status == 99 || !empty($object->detail_refuse)) {
1813  print '<tr>';
1814  print '<td>'.$langs->trans("REFUSEUR").'</td>';
1815  print '<td>';
1816  $userfee = new User($db);
1817  $result = $userfee->fetch($object->fk_user_refuse);
1818  if ($result > 0) {
1819  print $userfee->getNomUrl(-1);
1820  }
1821  print '</td></tr>';
1822 
1823  print '<tr>';
1824  print '<td>'.$langs->trans("DATE_REFUS").'</td>';
1825  print '<td>'.dol_print_date($object->date_refuse, 'dayhour', 'tzuser');
1826  if ($object->detail_refuse) {
1827  print ' - '.$object->detail_refuse;
1828  }
1829  print '</td>';
1830  print '</tr>';
1831  }
1832 
1833  if ($object->status == $object::STATUS_CLOSED) {
1834  /* TODO this fields are not yet filled
1835  print '<tr>';
1836  print '<td>'.$langs->trans("AUTHORPAIEMENT").'</td>';
1837  print '<td>';
1838  $userfee=new User($db);
1839  $userfee->fetch($object->fk_user_paid);
1840  print $userfee->getNomUrl(-1);
1841  print '</td></tr>';
1842  print '<tr>';
1843  print '<td>'.$langs->trans("DATE_PAIEMENT").'</td>';
1844  print '<td>'.$object->date_paiement.'</td></tr>';
1845  print '</tr>';
1846  */
1847  }
1848 
1849  // Other attributes
1850  $cols = 2;
1851  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
1852 
1853  print '</table>';
1854 
1855  print '</div>';
1856  print '<div class="fichehalfright">';
1857  print '<div class="underbanner clearboth"></div>';
1858 
1859  print '<table class="border tableforfield centpercent">';
1860 
1861  // Amount
1862  print '<tr>';
1863  print '<td class="titlefieldmiddle">'.$langs->trans("AmountHT").'</td>';
1864  print '<td class="nowrap amountcard">'.price($object->total_ht, 1, '', 1, - 1, - 1, $conf->currency).'</td>';
1865  $rowspan = 5;
1866  if ($object->status <= ExpenseReport::STATUS_VALIDATED) {
1867  $rowspan++;
1868  } elseif ($object->status == ExpenseReport::STATUS_CANCELED) {
1869  $rowspan += 2;
1870  } else {
1871  $rowspan += 2;
1872  }
1873  if ($object->status == ExpenseReport::STATUS_REFUSED || !empty($object->detail_refuse)) {
1874  $rowspan += 2;
1875  }
1876  if ($object->status == ExpenseReport::STATUS_CLOSED) {
1877  $rowspan += 2;
1878  }
1879  print "</td>";
1880  print '</tr>';
1881 
1882  print '<tr>';
1883  print '<td>'.$langs->trans("AmountVAT").'</td>';
1884  print '<td class="nowrap amountcard">'.price($object->total_tva, 1, '', 1, -1, -1, $conf->currency).'</td>';
1885  print '</tr>';
1886 
1887  // Amount Local Taxes
1888  if ($mysoc->localtax1_assuj == "1" || $object->total_localtax1 != 0) { // Localtax1
1889  print '<tr><td>'.$langs->transcountry("AmountLT1", $mysoc->country_code).'</td>';
1890  print '<td class="valuefield">'.price($object->total_localtax1, 1, '', 1, -1, -1, $conf->currency).'</td></tr>';
1891  }
1892  if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0) { // Localtax2 IRPF
1893  print '<tr><td>'.$langs->transcountry("AmountLT2", $mysoc->country_code).'</td>';
1894  print '<td class="valuefield">'.price($object->total_localtax2, 1, '', 1, -1, -1, $conf->currency).'</td></tr>';
1895  }
1896 
1897  print '<tr>';
1898  print '<td>'.$langs->trans("AmountTTC").'</td>';
1899  print '<td class="nowrap amountcard">'.price($object->total_ttc, 1, '', 1, -1, -1, $conf->currency).'</td>';
1900  print '</tr>';
1901 
1902  // List of payments already done
1903  $nbcols = 3;
1904  $nbrows = 0;
1905  if (isModEnabled("banque")) {
1906  $nbrows++;
1907  $nbcols++;
1908  }
1909 
1910  print '<table class="noborder paymenttable centpercent">';
1911 
1912  print '<tr class="liste_titre">';
1913  print '<td class="liste_titre">'.$langs->trans('Payments').'</td>';
1914  print '<td class="liste_titre">'.$langs->trans('Date').'</td>';
1915  print '<td class="liste_titre">'.$langs->trans('Type').'</td>';
1916  if (isModEnabled("banque")) {
1917  print '<td class="liste_titre right">'.$langs->trans('BankAccount').'</td>';
1918  }
1919  print '<td class="liste_titre right">'.$langs->trans('Amount').'</td>';
1920  print '<td class="liste_titre" width="18">&nbsp;</td>';
1921  print '</tr>';
1922 
1923  // Payments already done (from payment on this expensereport)
1924  $sql = "SELECT p.rowid, p.num_payment, p.datep as dp, p.amount, p.fk_bank,";
1925  $sql .= "c.code as payment_code, c.libelle as payment_type,";
1926  $sql .= "ba.rowid as baid, ba.ref as baref, ba.label, ba.number as banumber, ba.account_number, ba.fk_accountancy_journal";
1927  $sql .= " FROM ".MAIN_DB_PREFIX."expensereport as e, ".MAIN_DB_PREFIX."payment_expensereport as p";
1928  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as c ON p.fk_typepayment = c.id";
1929  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid';
1930  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid';
1931  $sql .= " WHERE e.rowid = ".((int) $id);
1932  $sql .= " AND p.fk_expensereport = e.rowid";
1933  $sql .= ' AND e.entity IN ('.getEntity('expensereport').')';
1934  $sql .= " ORDER BY dp";
1935 
1936  $resql = $db->query($sql);
1937  if ($resql) {
1938  $num = $db->num_rows($resql);
1939  $i = 0; $totalpaid = 0;
1940  while ($i < $num) {
1941  $objp = $db->fetch_object($resql);
1942 
1943  $paymentexpensereportstatic->id = $objp->rowid;
1944  $paymentexpensereportstatic->datep = $db->jdate($objp->dp);
1945  $paymentexpensereportstatic->ref = $objp->rowid;
1946  $paymentexpensereportstatic->num_payment = $objp->num_payment;
1947  $paymentexpensereportstatic->type_code = $objp->payment_code;
1948  $paymentexpensereportstatic->type_label = $objp->payment_type;
1949 
1950  print '<tr class="oddseven">';
1951  print '<td>';
1952  print $paymentexpensereportstatic->getNomUrl(1);
1953  print '</td>';
1954  print '<td>'.dol_print_date($db->jdate($objp->dp), 'day')."</td>\n";
1955  $labeltype = $langs->trans("PaymentType".$objp->payment_code) != ("PaymentType".$objp->payment_code) ? $langs->trans("PaymentType".$objp->payment_code) : $objp->payment_type;
1956  print "<td>".$labeltype.' '.$objp->num_payment."</td>\n";
1957  // Bank account
1958  if (isModEnabled("banque")) {
1959  $bankaccountstatic->id = $objp->baid;
1960  $bankaccountstatic->ref = $objp->baref;
1961  $bankaccountstatic->label = $objp->baref;
1962  $bankaccountstatic->number = $objp->banumber;
1963 
1964  if (isModEnabled('accounting')) {
1965  $bankaccountstatic->account_number = $objp->account_number;
1966 
1967  $accountingjournal = new AccountingJournal($db);
1968  $accountingjournal->fetch($objp->fk_accountancy_journal);
1969  $bankaccountstatic->accountancy_journal = $accountingjournal->getNomUrl(0, 1, 1, '', 1);
1970  }
1971 
1972  print '<td class="right">';
1973  if ($bankaccountstatic->id) {
1974  print $bankaccountstatic->getNomUrl(1, 'transactions');
1975  }
1976  print '</td>';
1977  }
1978  print '<td class="right">'.price($objp->amount)."</td>";
1979  print '<td></td>';
1980  print "</tr>";
1981  $totalpaid += $objp->amount;
1982  $i++;
1983  }
1984  if (!is_null($totalpaid)) {
1985  $totalpaid = price2num($totalpaid); // Round $totalpaid to fix floating problem after addition into loop
1986  }
1987 
1988  $remaintopay = price2num($object->total_ttc - $totalpaid);
1989  $resteapayeraffiche = $remaintopay;
1990 
1991  $cssforamountpaymentcomplete = 'amountpaymentcomplete';
1992 
1993  if ($object->status == ExpenseReport::STATUS_REFUSED) {
1994  $cssforamountpaymentcomplete = 'amountpaymentneutral';
1995  $resteapayeraffiche = 0;
1996  } elseif ($object->paid == 0) {
1997  $cssforamountpaymentcomplete = 'amountpaymentneutral';
1998  }
1999  print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans("AlreadyPaid").':</td><td class="right">'.price($totalpaid).'</td><td></td></tr>';
2000  print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans("AmountExpected").':</td><td class="right">'.price($object->total_ttc).'</td><td></td></tr>';
2001 
2002  print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans("RemainderToPay").':</td>';
2003  print '<td class="right'.($resteapayeraffiche ? ' amountremaintopay' : (' '.$cssforamountpaymentcomplete)).'">'.price($resteapayeraffiche).'</td><td></td></tr>';
2004 
2005  $db->free($resql);
2006  } else {
2007  dol_print_error($db);
2008  }
2009  print "</table>";
2010 
2011  print '</div>';
2012  print '</div>';
2013 
2014  print '<div class="clearboth"></div><br>';
2015 
2016  print '<div style="clear: both;"></div>';
2017 
2018  $actiontouse = 'updateline';
2019  if (($object->status == 0 || $object->status == 99) && $action != 'editline') {
2020  $actiontouse = 'addline';
2021  }
2022 
2023  print '<form name="expensereport" action="'.$_SERVER["PHP_SELF"].'" enctype="multipart/form-data" method="post" >';
2024  print '<input type="hidden" name="token" value="'.newToken().'">';
2025  print '<input type="hidden" name="action" value="'.$actiontouse.'">';
2026  print '<input type="hidden" name="id" value="'.$object->id.'">';
2027  print '<input type="hidden" name="fk_expensereport" value="'.$object->id.'" />';
2028  print '<input type="hidden" name="page_y" value="">';
2029 
2030  print '<div class="div-table-responsive-no-min">';
2031  print '<table id="tablelines" class="noborder centpercent">';
2032 
2033  if (!empty($object->lines)) {
2034  $i = 0; $total = 0;
2035 
2036  print '<tr class="liste_titre headerexpensereportdet">';
2037  print '<td class="center linecollinenb">'.$langs->trans('LineNb').'</td>';
2038  //print '<td class="center">'.$langs->trans('Piece').'</td>';
2039  print '<td class="center linecoldate">'.$langs->trans('Date').'</td>';
2040  if (isModEnabled('project')) {
2041  print '<td class="minwidth100imp linecolproject">'.$langs->trans('Project').'</td>';
2042  }
2043  print '<td class="center linecoltype">'.$langs->trans('Type').'</td>';
2044  if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) {
2045  print '<td class="center linecolcarcategory">'.$langs->trans('CarCategory').'</td>';
2046  }
2047  print '<td class="linecoldescription">'.$langs->trans('Description').'</td>';
2048  print '<td class="right linecolvat">'.$langs->trans('VAT').'</td>';
2049  print '<td class="right linecolpriceuht">'.$langs->trans('PriceUHT').'</td>';
2050  print '<td class="right linecolpriceuttc">'.$langs->trans('PriceUTTC').'</td>';
2051  print '<td class="right linecolqty">'.$langs->trans('Qty').'</td>';
2052  if ($action != 'editline') {
2053  print '<td class="right linecolamountht">'.$langs->trans('AmountHT').'</td>';
2054  print '<td class="right linecolamountttc">'.$langs->trans('AmountTTC').'</td>';
2055  }
2056  // Picture
2057  print '<td>';
2058  print '</td>';
2059 
2060  // Information if theres a rule restriction
2061  print '<td>';
2062  print '</td>';
2063 
2064  // Ajout des boutons de modification/suppression
2065  if (($object->status < 2 || $object->status == 99) && $user->rights->expensereport->creer) {
2066  print '<td class="right"></td>';
2067  }
2068  print '</tr>';
2069 
2070  foreach ($object->lines as &$line) {
2071  $numline = $i + 1;
2072 
2073  if ($action != 'editline' || $line->rowid != GETPOST('rowid', 'int')) {
2074  print '<tr class="oddeven linetr" data-id="'.$line->id.'">';
2075 
2076  // Num
2077  print '<td class="center linecollinenb">';
2078  print $numline;
2079  print '</td>';
2080 
2081  // Date
2082  print '<td class="center linecoldate">'.dol_print_date($db->jdate($line->date), 'day').'</td>';
2083 
2084  // Project
2085  if (isModEnabled('project')) {
2086  print '<td class="lineproject">';
2087  if ($line->fk_project > 0) {
2088  $projecttmp->id = $line->fk_project;
2089  $projecttmp->ref = $line->projet_ref;
2090  $projecttmp->title = $line->projet_title;
2091  print $projecttmp->getNomUrl(1);
2092  }
2093  print '</td>';
2094  }
2095 
2096  $titlealt = '';
2097  if (isModEnabled('accounting')) {
2098  require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
2099  $accountingaccount = new AccountingAccount($db);
2100  $resaccountingaccount = $accountingaccount->fetch(0, $line->type_fees_accountancy_code, 1);
2101  //$titlealt .= '<span class="opacitymedium">';
2102  $titlealt .= $langs->trans("AccountancyCode").': ';
2103  if ($resaccountingaccount > 0) {
2104  $titlealt .= $accountingaccount->account_number;
2105  } else {
2106  $titlealt .= $langs->trans("NotFound");
2107  }
2108  //$titlealt .= '</span>';
2109  }
2110 
2111  // Type of fee
2112  print '<td class="center linecoltype" title="'.dol_escape_htmltag($titlealt).'">';
2113  $labeltype = ($langs->trans(($line->type_fees_code)) == $line->type_fees_code ? $line->type_fees_libelle : $langs->trans($line->type_fees_code));
2114  print $labeltype;
2115  print '</td>';
2116 
2117  // IK
2118  if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) {
2119  print '<td class="fk_c_exp_tax_cat linecoltaxcat">';
2120  $exp_tax_cat_label = dol_getIdFromCode($db, $line->fk_c_exp_tax_cat, 'c_exp_tax_cat', 'rowid', 'label');
2121  print $langs->trans($exp_tax_cat_label);
2122  print '</td>';
2123  }
2124 
2125  // Comment
2126  print '<td class="left linecolcomment">'.dol_nl2br($line->comments).'</td>';
2127 
2128  // VAT rate
2129  print '<td class="right linecolvatrate">'.vatrate($line->vatrate.($line->vat_src_code ? ' ('.$line->vat_src_code.')' : ''), true).'</td>';
2130 
2131  // Unit price HT
2132  print '<td class="right linecolunitht">';
2133  if (!empty($line->value_unit_ht)) {
2134  print price($line->value_unit_ht);
2135  } else {
2136  $tmpvat = price2num(preg_replace('/\s*\‍(.*\‍)/', '', $line->vatrate));
2137  $pricenettoshow = price2num($line->value_unit / (1 + $tmpvat / 100), 'MU');
2138  print price($pricenettoshow);
2139  }
2140  print '</td>';
2141 
2142  print '<td class="right linecolunitttc">'.price($line->value_unit).'</td>';
2143 
2144  print '<td class="right linecolqty">'.dol_escape_htmltag($line->qty).'</td>';
2145 
2146  if ($action != 'editline') {
2147  print '<td class="right linecoltotalht">'.price($line->total_ht).'</td>';
2148  print '<td class="right linecoltotalttc">'.price($line->total_ttc).'</td>';
2149  }
2150 
2151  // Column with preview
2152  print '<td class="center linecolpreview">';
2153  if ($line->fk_ecm_files > 0) {
2154  $modulepart = 'expensereport';
2155  $maxheightmini = 32;
2156 
2157  $result = $ecmfilesstatic->fetch($line->fk_ecm_files);
2158  if ($result > 0) {
2159  $relativepath = preg_replace('/expensereport\//', '', $ecmfilesstatic->filepath);
2160  $fileinfo = pathinfo($ecmfilesstatic->filepath.'/'.$ecmfilesstatic->filename);
2161  if (image_format_supported($fileinfo['basename']) > 0) {
2162  $minifile = getImageFileNameForSize($fileinfo['basename'], '_mini'); // For new thumbs using same ext (in lower case howerver) than original
2163  if (!dol_is_file($conf->expensereport->dir_output.'/'.$relativepath.'/'.$minifile)) {
2164  $minifile = getImageFileNameForSize($fileinfo['basename'], '_mini', '.png'); // For backward compatibility of old thumbs that were created with filename in lower case and with .png extension
2165  }
2166  //print $file['path'].'/'.$minifile.'<br>';
2167  $urlforhref = getAdvancedPreviewUrl($modulepart, $relativepath.'/'.$fileinfo['filename'].'.'.strtolower($fileinfo['extension']), 1, '&entity='.(!empty($object->entity) ? $object->entity : $conf->entity));
2168  if (empty($urlforhref)) {
2169  $urlforhref = DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.(!empty($object->entity) ? $object->entity : $conf->entity).'&file='.urlencode($relativepath.$fileinfo['filename'].'.'.strtolower($fileinfo['extension']));
2170  print '<a href="'.$urlforhref.'" class="aphoto" target="_blank" rel="noopener noreferrer">';
2171  } else {
2172  print '<a href="'.$urlforhref['url'].'" class="'.$urlforhref['css'].'" target="'.$urlforhref['target'].'" mime="'.$urlforhref['mime'].'">';
2173  }
2174  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="">';
2175  print '</a>';
2176  } else {
2177  $modulepart = 'expensereport';
2178  $thumbshown = 0;
2179  if (preg_match('/\.pdf$/i', $ecmfilesstatic->filename)) {
2180  $filepdf = $conf->expensereport->dir_output.'/'.$relativepath.'/'.$ecmfilesstatic->filename;
2181  $fileimage = $conf->expensereport->dir_output.'/'.$relativepath.'/'.$ecmfilesstatic->filename.'_preview.png';
2182  $relativepathimage = $relativepath.'/'.$ecmfilesstatic->filename.'_preview.png';
2183 
2184  $pdfexists = file_exists($filepdf);
2185  if ($pdfexists) {
2186  // Conversion du PDF en image png si fichier png non existant
2187  if (!file_exists($fileimage) || (filemtime($fileimage) < filemtime($filepdf))) {
2188  if (empty($conf->global->MAIN_DISABLE_PDF_THUMBS)) { // If you experience trouble with pdf thumb generation and imagick, you can disable here.
2189  include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
2190  $ret = dol_convert_file($filepdf, 'png', $fileimage, '0'); // Convert first page of PDF into a file _preview.png
2191  if ($ret < 0) {
2192  $error++;
2193  }
2194  }
2195  }
2196  }
2197 
2198  if ($pdfexists && !$error) {
2199  $heightforphotref = 70;
2200  if (!empty($conf->dol_optimize_smallscreen)) {
2201  $heightforphotref = 60;
2202  }
2203  // If the preview file is found
2204  if (file_exists($fileimage)) {
2205  $thumbshown = 1;
2206  $urlforhref = getAdvancedPreviewUrl($modulepart, $relativepath.'/'.$fileinfo['filename'].'.'.strtolower($fileinfo['extension']), 1, '&entity='.(!empty($object->entity) ? $object->entity : $conf->entity));
2207  print '<a href="'.$urlforhref['url'].'" class="'.$urlforhref['css'].'" target="'.$urlforhref['target'].'" mime="'.$urlforhref['mime'].'">';
2208  print '<img height="'.$heightforphotref.'" class="photo photowithmargin photowithborder" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart=apercu'.$modulepart.'&amp;file='.urlencode($relativepathimage).'">';
2209  print '</a>';
2210  }
2211  }
2212  }
2213 
2214  if (!$thumbshown) {
2215  print img_mime($ecmfilesstatic->filename);
2216  }
2217  }
2218  }
2219  }
2220  print '</td>';
2221 
2222  print '<td class="nowrap right linecolwarning">';
2223  print !empty($line->rule_warning_message) ? img_warning(html_entity_decode($line->rule_warning_message)) : '&nbsp;';
2224  print '</td>';
2225 
2226  // Ajout des boutons de modification/suppression
2227  if (($object->status < ExpenseReport::STATUS_VALIDATED || $object->status == ExpenseReport::STATUS_REFUSED) && $user->rights->expensereport->creer) {
2228  print '<td class="nowrap right linecolaction">';
2229 
2230  print '<a class="editfielda reposition paddingrightonly" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=editline&token='.newToken().'&rowid='.$line->rowid.'">';
2231  print img_edit();
2232  print '</a> &nbsp; ';
2233  print '<a class="paddingrightonly" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete_line&token='.newToken().'&rowid='.$line->rowid.'">';
2234  print img_delete();
2235  print '</a>';
2236 
2237  print '</td>';
2238  }
2239 
2240  print '</tr>';
2241  }
2242 
2243  if ($action == 'editline' && $line->rowid == GETPOST('rowid', 'int')) {
2244  // Add line with link to add new file or attach line to an existing file
2245  $colspan = 11;
2246  if (isModEnabled('project')) {
2247  $colspan++;
2248  }
2249  if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) {
2250  $colspan++;
2251  }
2252 
2253  print '<!-- line of expense report -->'."\n";
2254  print '<tr class="tredited">';
2255 
2256  print '<td class="center">';
2257  print $numline;
2258  print '</td>';
2259 
2260  print '<td colspan="'.($colspan - 1).'" class="liste_titre"> ';
2261  print '<a href="" class="commonlink auploadnewfilenow reposition">'.$langs->trans("UploadANewFileNow");
2262  print img_picto($langs->trans("UploadANewFileNow"), 'chevron-down', '', false, 0, 0, '', 'marginleftonly');
2263  print '</a>';
2264  if (empty($conf->global->EXPENSEREPORT_DISABLE_ATTACHMENT_ON_LINES)) {
2265  print ' &nbsp; - &nbsp; <a href="" class="commonlink aattachtodoc reposition">'.$langs->trans("AttachTheNewLineToTheDocument");
2266  print img_picto($langs->trans("AttachTheNewLineToTheDocument"), 'chevron-down', '', false, 0, 0, '', 'marginleftonly');
2267  print '</a>';
2268  }
2269 
2270  print '<!-- Code to open/close section to submit or link files in edit mode -->'."\n";
2271  print '<script type="text/javascript">'."\n";
2272  print '$(document).ready(function() {
2273  $( ".auploadnewfilenow" ).click(function() {
2274  jQuery(".truploadnewfilenow").toggle();
2275  jQuery(".trattachnewfilenow").hide();
2276  return false;
2277  });
2278  $( ".aattachtodoc" ).click(function() {
2279  jQuery(".trattachnewfilenow").toggle();
2280  jQuery(".truploadnewfilenow").hide();
2281  return false;
2282  });';
2283  if (is_array(GETPOST('attachfile', 'array')) && count(GETPOST('attachfile', 'array'))) {
2284  print 'jQuery(".trattachnewfilenow").toggle();'."\n";
2285  }
2286  print '
2287  jQuery("form[name=\"expensereport\"]").submit(function() {
2288  if (jQuery(".truploadnewfilenow").is(":hidden")) {
2289  jQuery("input[name=\"sendit\"]").val("");
2290  }
2291  });
2292  ';
2293  print '
2294  });
2295  ';
2296  print '</script>'."\n";
2297  print '</td></tr>';
2298 
2299  $filenamelinked = '';
2300  if ($line->fk_ecm_files > 0) {
2301  $result = $ecmfilesstatic->fetch($line->fk_ecm_files);
2302  if ($result > 0) {
2303  $filenamelinked = $ecmfilesstatic->filename;
2304  }
2305  }
2306 
2307  $tredited = 'tredited'; // Case the addfile and linkto file is used for edit (used by following tpl)
2308  include DOL_DOCUMENT_ROOT.'/expensereport/tpl/expensereport_addfile.tpl.php';
2309  include DOL_DOCUMENT_ROOT.'/expensereport/tpl/expensereport_linktofile.tpl.php';
2310 
2311  print '<tr class="oddeven tredited">';
2312 
2313  print '<td></td>';
2314 
2315  // Select date
2316  print '<td class="center">';
2317  print $form->selectDate($line->date, 'date');
2318  print '</td>';
2319 
2320  // Select project
2321  if (isModEnabled('project')) {
2322  print '<td>';
2323  $formproject->select_projects(-1, $line->fk_project, 'fk_project', 0, 0, $projectRequired ? 0 : 1, 1, 0, 0, 0, '', 0, 0, 'maxwidth300');
2324  print '</td>';
2325  }
2326 
2327  // Select type
2328  print '<td class="center">';
2329  print $formexpensereport->selectTypeExpenseReport($line->fk_c_type_fees, 'fk_c_type_fees');
2330  print '</td>';
2331 
2332  if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) {
2333  print '<td class="fk_c_exp_tax_cat">';
2334  $params = array('fk_expense' => $object->id, 'fk_expense_det' => $line->rowid, 'date' => $line->dates);
2335  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);
2336  print '</td>';
2337  }
2338 
2339  // Add comments
2340  print '<td>';
2341  print '<textarea name="comments" class="flat_ndf centpercent">'.dol_escape_htmltag($line->comments, 0, 1).'</textarea>';
2342  print '</td>';
2343 
2344  // VAT
2345  $selectedvat = price2num($line->vatrate).(!empty($line->vat_src_code) ? ' ('.$line->vat_src_code.')' : '');
2346  print '<td class="right">';
2347  print $form->load_tva('vatrate', (GETPOSTISSET("vatrate") ? GETPOST("vatrate") : $selectedvat), $mysoc, '', 0, 0, '', false, 1);
2348  print '</td>';
2349 
2350  // Unit price
2351  print '<td class="right">';
2352  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.' />';
2353  print '</td>';
2354 
2355  // Unit price with tax
2356  print '<td class="right">';
2357  print '<input type="text" min="0" class="right maxwidth50" id="value_unit" name="value_unit" value="'.dol_escape_htmltag(price2num($line->value_unit)).'" />';
2358  print '</td>';
2359 
2360  // Quantity
2361  print '<td class="right">';
2362  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
2363  print '</td>';
2364 
2365  //print '<td class="right">'.$langs->trans('AmountHT').'</td>';
2366  //print '<td class="right">'.$langs->trans('AmountTTC').'</td>';
2367 
2368  // Picture
2369  print '<td class="center">';
2370  //print $line->fk_ecm_files;
2371  print '</td>';
2372  // Information if theres a rule restriction
2373  print '<td class="center">';
2374  print '</td>';
2375 
2376  print '<td>';
2377  print '<input type="hidden" name="rowid" value="'.$line->rowid.'">';
2378  print $form->buttonsSaveCancel('Save', 'Cancel', array(), 0, 'small');
2379  print '</td>';
2380 
2381  print '</tr>';
2382  }
2383 
2384  $i++;
2385  }
2386  }
2387 
2388  // Add a new line
2389  if (($object->status == ExpenseReport::STATUS_DRAFT || $object->status == ExpenseReport::STATUS_REFUSED) && $action != 'editline' && $user->rights->expensereport->creer) {
2390  $colspan = 12;
2391  if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) {
2392  $colspan++;
2393  }
2394  if (isModEnabled('project')) {
2395  $colspan++;
2396  }
2397  if ($action != 'editline') {
2398  $colspan++;
2399  }
2400 
2401  $nbFiles = $nbLinks = 0;
2402  $arrayoffiles = array();
2403  if (empty($conf->global->EXPENSEREPORT_DISABLE_ATTACHMENT_ON_LINES)) {
2404  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
2405  require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
2406  require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php';
2407  $upload_dir = $conf->expensereport->dir_output."/".dol_sanitizeFileName($object->ref);
2408  $arrayoffiles = dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png|'.preg_quote(dol_sanitizeFileName($object->ref.'.pdf'), '/').')$');
2409  $nbFiles = count($arrayoffiles);
2410  $nbLinks = Link::count($db, $object->element, $object->id);
2411  }
2412 
2413  // Add line with link to add new file or attach to an existing file
2414  print '<tr class="liste_titre">';
2415  print '<td colspan="'.$colspan.'" class="liste_titre expensereportautoload">';
2416  print '<a href="" class="commonlink auploadnewfilenow reposition">'.$langs->trans("UploadANewFileNow");
2417  print img_picto($langs->trans("UploadANewFileNow"), 'chevron-down', '', false, 0, 0, '', 'marginleftonly');
2418  print '</a>';
2419  if (empty($conf->global->EXPENSEREPORT_DISABLE_ATTACHMENT_ON_LINES)) {
2420  print ' &nbsp; - &nbsp; <a href="" class="commonlink aattachtodoc reposition">'.$langs->trans("AttachTheNewLineToTheDocument");
2421  print img_picto($langs->trans("AttachTheNewLineToTheDocument"), 'chevron-down', '', false, 0, 0, '', 'marginleftonly');
2422  print '</a>';
2423  }
2424 
2425  print '<!-- Code to open/close section to submit or link files in the form to add new line -->'."\n";
2426  print '<script type="text/javascript">'."\n";
2427  print '$(document).ready(function() {
2428  $( ".auploadnewfilenow" ).click(function() {
2429  console.log("We click on toggle of auploadnewfilenow");
2430  jQuery(".truploadnewfilenow").toggle();
2431  jQuery(".trattachnewfilenow").hide();
2432  if (jQuery(".truploadnewfilenow").is(":hidden")) {
2433  jQuery("input[name=\"sendit\"]").prop("name", "senditdisabled");
2434  } else {
2435  jQuery("input[name=\"senditdisabled\"]").prop("name", "sendit");
2436  }
2437  return false;
2438  });
2439  $( ".aattachtodoc" ).click(function() {
2440  console.log("We click on toggle of aattachtodoc");
2441  jQuery(".trattachnewfilenow").toggle();
2442  jQuery(".truploadnewfilenow").hide();
2443  return false;
2444  });'."\n";
2445  if (is_array(GETPOST('attachfile', 'array')) && count(GETPOST('attachfile', 'array')) && $action != 'updateline') {
2446  print 'jQuery(".trattachnewfilenow").show();'."\n";
2447  }
2448  print '
2449  jQuery("form[name=\"expensereport\"]").submit(function() {
2450  if (jQuery(".truploadnewfilenow").is(":hidden")) {
2451  /* 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. */
2452  jQuery("input[name=\"sendit\"]").val("");
2453  jQuery("input[name=\"sendit\"]").prop("name", "senditdisabled");
2454  } else {
2455  jQuery("input[name=\"senditdisabled\"]").prop("name", "sendit");
2456  }
2457  });
2458  ';
2459  print '
2460  });
2461  ';
2462  print '</script>'."\n";
2463  print '</td></tr>';
2464 
2465  $tredited = ''; // Case the addfile and linkto file is used for edit (used by following tpl)
2466  include DOL_DOCUMENT_ROOT.'/expensereport/tpl/expensereport_linktofile.tpl.php';
2467  include DOL_DOCUMENT_ROOT.'/expensereport/tpl/expensereport_addfile.tpl.php';
2468 
2469  print '<tr class="liste_titre expensereportcreate">';
2470  print '<td></td>';
2471  print '<td class="center expensereportcreatedate">'.$langs->trans('Date').'</td>';
2472  if (isModEnabled('project')) {
2473  print '<td class="minwidth100imp">'.$form->textwithpicto($langs->trans('Project'), $langs->trans("ClosedProjectsAreHidden")).'</td>';
2474  }
2475  print '<td class="center expensereportcreatetype">'.$langs->trans('Type').'</td>';
2476  if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) {
2477  print '<td>'.$langs->trans('CarCategory').'</td>';
2478  }
2479  print '<td class="expensereportcreatedescription">'.$langs->trans('Description').'</td>';
2480  print '<td class="right expensereportcreatevat">'.$langs->trans('VAT').'</td>';
2481  print '<td class="right expensereportcreatepriceuth">'.$langs->trans('PriceUHT').'</td>';
2482  print '<td class="right expensereportcreatepricettc">'.$langs->trans('PriceUTTC').'</td>';
2483  print '<td class="right expensereportcreateqty">'.$langs->trans('Qty').'</td>';
2484  print '<td></td>';
2485  print '<td></td>';
2486  print '<td></td>';
2487  print '<td></td>';
2488  print '<td></td>';
2489  print '</tr>';
2490  print '<tr class="oddeven nohover">';
2491 
2492  // Line number
2493  print '<td></td>';
2494 
2495  // Select date
2496  print '<td class="center inputdate">';
2497  print $form->selectDate(!empty($date) ? $date : -1, 'date', 0, 0, 0, '', 1, 1);
2498  print '</td>';
2499 
2500  // Select project
2501  if (isModEnabled('project')) {
2502  print '<td class="inputproject">';
2503  $formproject->select_projects(-1, !empty($fk_project) ? $fk_project : 0, 'fk_project', 0, 0, $projectRequired ? 0 : 1, -1, 0, 0, 0, '', 0, 0, 'maxwidth300');
2504  print '</td>';
2505  }
2506 
2507  // Select type
2508  print '<td class="center inputtype">';
2509  print $formexpensereport->selectTypeExpenseReport(!empty($fk_c_type_fees) ? $fk_c_type_fees : "", 'fk_c_type_fees', 1);
2510  print '</td>';
2511 
2512  if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) {
2513  print '<td class="fk_c_exp_tax_cat">';
2514  $params = array('fk_expense' => $object->id);
2515  print $form->selectExpenseCategories('', 'fk_c_exp_tax_cat', 1, array(), 'fk_c_type_fees', $userauthor->default_c_exp_tax_cat, $params, 0);
2516  print '</td>';
2517  }
2518 
2519  // Add comments
2520  print '<td class="inputcomment">';
2521  print '<textarea class="flat_ndf centpercent" name="comments" rows="'.ROWS_2.'">'.dol_escape_htmltag(!empty($comments) ? $comments : "", 0, 1).'</textarea>';
2522  print '</td>';
2523 
2524  // Select VAT
2525  print '<td class="right inputvat">';
2526  $defaultvat = -1;
2527  if (!empty($conf->global->EXPENSEREPORT_NO_DEFAULT_VAT)) {
2528  // If option to have no default VAT on expense report is on, we force MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS
2529  $conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS = 'none';
2530  }
2531  print $form->load_tva('vatrate', (!empty($vatrate) ? $vatrate : $defaultvat), $mysoc, '', 0, 0, '', false, 1);
2532  print '</td>';
2533 
2534  // Unit price net
2535  print '<td class="right inputpricenet">';
2536  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.' />';
2537  print '</td>';
2538 
2539  // Unit price with tax
2540  print '<td class="right inputtax">';
2541  print '<input type="text" class="right maxwidth50" id="value_unit" name="value_unit" value="'.dol_escape_htmltag((!empty($value_unit) ? $value_unit : 0)).'">';
2542  print '</td>';
2543 
2544  // Quantity
2545  print '<td class="right inputqty">';
2546  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
2547  print '</td>';
2548 
2549  // Picture
2550  print '<td></td>';
2551 
2552  if ($action != 'editline') {
2553  print '<td class="right"></td>';
2554  print '<td class="right"></td>';
2555  }
2556 
2557  print '<td class="center inputbuttons">';
2558  print $form->buttonsSaveCancel("Add", '', '', 1, 'reposition');
2559  print '</td>';
2560 
2561  print '</tr>';
2562  } // Fin si c'est payé/validé
2563 
2564  print '</table>';
2565  print '</div>';
2566 
2567  print '<script>
2568 
2569  /* JQuery for product free or predefined select */
2570  jQuery(document).ready(function() {
2571  jQuery("#value_unit_ht").keyup(function(event) {
2572  console.log(event.which); // discard event tag and arrows
2573  if (event.which != 9 && (event.which < 37 ||event.which > 40) && jQuery("#value_unit_ht").val() != "") {
2574  jQuery("#value_unit").val("");
2575  }
2576  });
2577  jQuery("#value_unit").keyup(function(event) {
2578  console.log(event.which); // discard event tag and arrows
2579  if (event.which != 9 && (event.which < 37 || event.which > 40) && jQuery("#value_unit").val() != "") {
2580  jQuery("#value_unit_ht").val("");
2581  }
2582  });
2583  ';
2584 
2585  if (! empty($conf->global->MAIN_USE_EXPENSE_IK)) {
2586  print '
2587 
2588  /* unit price coéf calculation */
2589  jQuery(".input_qty, #fk_c_type_fees, #select_fk_c_exp_tax_cat, #vatrate ").change(function(event) {
2590 
2591  let type_fee = jQuery("#fk_c_type_fees").find(":selected").val();
2592  let tax_cat = jQuery("#select_fk_c_exp_tax_cat").find(":selected").val();
2593  let tva = jQuery("#vatrate").find(":selected").val();
2594  let qty = jQuery(".input_qty").val();
2595 
2596 
2597 
2598  let path = "'.dol_buildpath("/expensereport/ajax/ajaxik.php", 1) .'";
2599  path += "?fk_c_exp_tax_cat="+tax_cat;
2600  path +="&fk_expense="+'.$object->id.';
2601  path += "&vatrate="+tva;
2602  path += "&qty="+qty;
2603 
2604  if (type_fee == 4) { // frais_kilométriques
2605 
2606  if (tax_cat == "" || parseInt(tax_cat) <= 0){
2607  return ;
2608  }
2609 
2610  jQuery.ajax({
2611  url: path
2612  ,async:false
2613  ,dataType:"json"
2614  ,success:function(response) {
2615  if (response.response_status == "success"){';
2616 
2617  if (!empty($conf->global->EXPENSEREPORT_FORCE_LINE_AMOUNTS_INCLUDING_TAXES_ONLY)) {
2618  print '
2619  jQuery("#value_unit").val(parseFloat(response.data) * (100 + parseFloat(tva)) / 100);
2620  jQuery("#value_unit").trigger("change");
2621  ';
2622  } else {
2623  print '
2624  jQuery("#value_unit_ht").val(response.data);
2625  jQuery("#value_unit_ht").trigger("change");
2626  jQuery("#value_unit").val("");
2627  ';
2628  }
2629 
2630  print '
2631  } else if(response.response_status == "error" && response.errorMessage != undefined && response.errorMessage.length > 0 ){
2632  $.jnotify(response.errorMessage, "error", {timeout: 0, type: "error"},{ remove: function (){} } );
2633  }
2634  },
2635 
2636  });
2637  }
2638 
2639  /*console.log(event.which); // discard event tag and arrows
2640  if (event.which != 9 && (event.which < 37 || event.which > 40) && jQuery("#value_unit").val() != "") {
2641  jQuery("#value_unit_ht").val("");
2642  }*/
2643  });
2644  ';
2645  }
2646 
2647  print '
2648 
2649  });
2650 
2651  </script>';
2652 
2653  print '</form>';
2654 
2655  print dol_get_fiche_end();
2656  }
2657  } else {
2658  dol_print_error($db);
2659  }
2660 } else {
2661  print 'Record not found';
2662 
2663  llxFooter();
2664  exit(1);
2665 }
2666 
2667 
2668 /*
2669  * Action bar
2670  */
2671 
2672 print '<div class="tabsAction">';
2673 
2674 if ($action != 'create' && $action != 'edit' && $action != 'editline') {
2675  $object = new ExpenseReport($db);
2676  $object->fetch($id, $ref);
2677 
2678  // Send
2679  if (empty($user->socid)) {
2680  if ($object->status > ExpenseReport::STATUS_DRAFT) {
2681  //if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->expensereport->expensereport_advance->send)) {
2682  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>';
2683  //} else
2684  // print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#">' . $langs->trans('SendMail') . '</a></div>';
2685  }
2686  }
2687 
2688  /* Si l'état est "Brouillon"
2689  * ET user à droit "creer/supprimer"
2690  * ET fk_user_author == user courant
2691  * Afficher : "Enregistrer" / "Modifier" / "Supprimer"
2692  */
2693  if ($user->rights->expensereport->creer && $object->status == ExpenseReport::STATUS_DRAFT) {
2694  if (in_array($object->fk_user_author, $user->getAllChildIds(1)) || !empty($user->rights->expensereport->writeall_advance)) {
2695  // Modify
2696  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>';
2697 
2698  // Validate
2699  if (count($object->lines) > 0) {
2700  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>';
2701  }
2702  }
2703  }
2704 
2705  /* Si l'état est "Refusée"
2706  * ET user à droit "creer/supprimer"
2707  * ET fk_user_author == user courant
2708  * Afficher : "Enregistrer" / "Modifier" / "Supprimer"
2709  */
2710  if ($user->rights->expensereport->creer && $object->status == ExpenseReport::STATUS_REFUSED) {
2711  if ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) {
2712  // Modify
2713  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>';
2714 
2715  // setdraft (le statut refusée est identique à brouillon)
2716  //print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=brouillonner&id='.$id.'">'.$langs->trans('ReOpen').'</a>';
2717  // Enregistrer depuis le statut "Refusée"
2718  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>';
2719  }
2720  }
2721 
2722  if ($user->rights->expensereport->to_paid && $object->status == ExpenseReport::STATUS_APPROVED) {
2723  if ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) {
2724  // setdraft
2725  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>';
2726  }
2727  }
2728 
2729  /* Si l'état est "En attente d'approbation"
2730  * ET user à droit de "approve"
2731  * ET fk_user_validator == user courant
2732  * Afficher : "Valider" / "Refuser" / "Supprimer"
2733  */
2734  if ($object->status == ExpenseReport::STATUS_VALIDATED) {
2735  if (in_array($object->fk_user_author, $user->getAllChildIds(1))) {
2736  // set draft
2737  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>';
2738  }
2739  }
2740 
2741  if ($user->rights->expensereport->approve && $object->status == ExpenseReport::STATUS_VALIDATED) {
2742  //if($object->fk_user_validator==$user->id)
2743  //{
2744  // Validate
2745  print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=validate&id='.$object->id.'">'.$langs->trans('Approve').'</a></div>';
2746  // Deny
2747  print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=refuse&id='.$object->id.'">'.$langs->trans('Deny').'</a></div>';
2748  //}
2749 
2750  if ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) {
2751  // Cancel
2752  print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=cancel&id='.$object->id.'">'.$langs->trans("Cancel").'</a></div>';
2753  }
2754  }
2755 
2756 
2757  // If status is Approved
2758  // ---------------------
2759 
2760  if ($user->rights->expensereport->approve && $object->status == ExpenseReport::STATUS_APPROVED) {
2761  print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=refuse&id='.$object->id.'">'.$langs->trans('Deny').'</a></div>';
2762  }
2763 
2764  // If bank module is used
2765  if ($user->rights->expensereport->to_paid && isModEnabled("banque") && $object->status == ExpenseReport::STATUS_APPROVED) {
2766  // Pay
2767  if ($remaintopay == 0) {
2768  print '<div class="inline-block divButAction"><span class="butActionRefused classfortooltip" title="'.$langs->trans("DisabledBecauseRemainderToPayIsZero").'">'.$langs->trans('DoPayment').'</span></div>';
2769  } else {
2770  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>';
2771  }
2772  }
2773 
2774  // If bank module is not used
2775  if (($user->rights->expensereport->to_paid || empty($conf->banque->enabled)) && $object->status == ExpenseReport::STATUS_APPROVED) {
2776  //if ((round($remaintopay) == 0 || empty($conf->banque->enabled)) && $object->paid == 0)
2777  if ($object->paid == 0) {
2778  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>";
2779  }
2780  }
2781 
2782  if ($user->rights->expensereport->creer && ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) && $object->status == ExpenseReport::STATUS_APPROVED) {
2783  // Cancel
2784  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>';
2785  }
2786 
2787  // TODO Replace this. It should be SetUnpaid and should go back to status unpaid not canceled.
2788  if (($user->rights->expensereport->approve || $user->rights->expensereport->to_paid) && $object->status == ExpenseReport::STATUS_CLOSED) {
2789  // Cancel
2790  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>';
2791  }
2792 
2793  if ($user->rights->expensereport->to_paid && $object->paid && $object->status == ExpenseReport::STATUS_CLOSED) {
2794  // Set unpaid
2795  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>';
2796  }
2797 
2798  // Clone
2799  if ($user->rights->expensereport->creer) {
2800  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>';
2801  }
2802 
2803  /* If draft, validated, cancel, and user can create, he can always delete its card before it is approved */
2804  if ($user->rights->expensereport->creer && $user->id == $object->fk_user_author && $object->status < ExpenseReport::STATUS_APPROVED) {
2805  // Delete
2806  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>';
2807  } elseif ($candelete && $object->status != ExpenseReport::STATUS_CLOSED) {
2808  // Delete
2809  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>';
2810  }
2811 
2812  $parameters = array();
2813  $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
2814 }
2815 
2816 print '</div>';
2817 
2818 
2819 // Select mail models is same action as presend
2820 if (GETPOST('modelselected', 'alpha')) {
2821  $action = 'presend';
2822 }
2823 
2824 if ($action != 'presend') {
2825  /*
2826  * Generate documents
2827  */
2828 
2829  print '<div class="fichecenter"><div class="fichehalfleft">';
2830  print '<a name="builddoc"></a>'; // ancre
2831 
2832  if ($user->rights->expensereport->creer && $action != 'create' && $action != 'edit') {
2833  $filename = dol_sanitizeFileName($object->ref);
2834  $filedir = $conf->expensereport->dir_output."/".dol_sanitizeFileName($object->ref);
2835  $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
2836  $genallowed = $user->rights->expensereport->creer;
2837  $delallowed = $user->rights->expensereport->creer;
2838  $var = true;
2839  print $formfile->showdocuments('expensereport', $filename, $filedir, $urlsource, $genallowed, $delallowed);
2840  $somethingshown = $formfile->numoffiles;
2841  }
2842 
2843  // Disabled for expensereport, there is no thirdparty on expensereport, so nothing to define the list of other object we can suggest to link to
2844  /*
2845  if ($action != 'create' && $action != 'edit' && ($id || $ref))
2846  {
2847  $linktoelem = $form->showLinkToObjectBlock($object, null, array('expensereport'));
2848  $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
2849  }
2850  */
2851 
2852  print '</div><div class="fichehalfright">';
2853  // List of actions on element
2854  include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
2855  $formactions = new FormActions($db);
2856  $somethingshown = $formactions->showactions($object, 'expensereport', null);
2857 
2858  print '</div></div>';
2859 }
2860 
2861 // Presend form
2862 $modelmail = 'expensereport';
2863 $defaulttopic = 'SendExpenseReportRef';
2864 $diroutput = $conf->expensereport->dir_output;
2865 $trackid = 'exp'.$object->id;
2866 
2867 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
2868 
2869 
2870 llxFooter();
2871 
2872 $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:47
$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:1996
dol_is_file($pathoffile)
Return if path is a file.
Definition: files.lib.php:481
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:80
$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.