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