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