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