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