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