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