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