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