dolibarr 19.0.4
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 && $fileinfo['extension'] == 'pdf' && !empty($filepdf) && !empty($relativepath) && !empty($fileinfo['filename'])) {
2234 $formFile = new FormFile($db);
2235 $imgpreview = $formFile->showPreview([], $modulepart, $relativepath.'/'.$fileinfo['filename'].'.'.strtolower($fileinfo['extension']), 0);
2236 print $imgpreview;
2237 } elseif (!$thumbshown) {
2238 print img_mime($ecmfilesstatic->filename);
2239 }
2240 }
2241 }
2242 }
2243 print '</td>';
2244
2245 print '<td class="nowrap right linecolwarning">';
2246 print !empty($line->rule_warning_message) ? img_warning(html_entity_decode($line->rule_warning_message)) : '&nbsp;';
2247 print '</td>';
2248
2249 // Ajout des boutons de modification/suppression
2250 if (($object->status < ExpenseReport::STATUS_VALIDATED || $object->status == ExpenseReport::STATUS_REFUSED) && $user->hasRight('expensereport', 'creer')) {
2251 print '<td class="nowrap right linecolaction">';
2252
2253 print '<a class="editfielda reposition paddingrightonly" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=editline&token='.newToken().'&rowid='.$line->rowid.'">';
2254 print img_edit();
2255 print '</a> &nbsp; ';
2256 print '<a class="paddingrightonly" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete_line&token='.newToken().'&rowid='.$line->rowid.'">';
2257 print img_delete();
2258 print '</a>';
2259
2260 print '</td>';
2261 }
2262
2263 print '</tr>';
2264 }
2265
2266 if ($action == 'editline' && $line->id == GETPOST('rowid', 'int')) {
2267 // Add line with link to add new file or attach line to an existing file
2268 $colspan = 11;
2269 if (isModEnabled('project')) {
2270 $colspan++;
2271 }
2272 if (getDolGlobalString('MAIN_USE_EXPENSE_IK')) {
2273 $colspan++;
2274 }
2275
2276 print '<!-- line of expense report -->'."\n";
2277 print '<tr class="tredited">';
2278
2279 print '<td class="center">';
2280 print $numline;
2281 print '</td>';
2282
2283 print '<td colspan="'.($colspan - 1).'" class="liste_titre"> ';
2284 print '<a href="" class="commonlink auploadnewfilenow reposition">'.$langs->trans("UploadANewFileNow");
2285 print img_picto($langs->trans("UploadANewFileNow"), 'chevron-down', '', false, 0, 0, '', 'marginleftonly');
2286 print '</a>';
2287 if (!getDolGlobalString('EXPENSEREPORT_DISABLE_ATTACHMENT_ON_LINES')) {
2288 print ' &nbsp; - &nbsp; <a href="" class="commonlink aattachtodoc reposition">'.$langs->trans("AttachTheNewLineToTheDocument");
2289 print img_picto($langs->trans("AttachTheNewLineToTheDocument"), 'chevron-down', '', false, 0, 0, '', 'marginleftonly');
2290 print '</a>';
2291 }
2292
2293 print '<!-- Code to open/close section to submit or link files in edit mode -->'."\n";
2294 print '<script type="text/javascript">'."\n";
2295 print '$(document).ready(function() {
2296 $( ".auploadnewfilenow" ).click(function() {
2297 jQuery(".truploadnewfilenow").toggle();
2298 jQuery(".trattachnewfilenow").hide();
2299 return false;
2300 });
2301 $( ".aattachtodoc" ).click(function() {
2302 jQuery(".trattachnewfilenow").toggle();
2303 jQuery(".truploadnewfilenow").hide();
2304 return false;
2305 });';
2306 if (is_array(GETPOST('attachfile', 'array')) && count(GETPOST('attachfile', 'array'))) {
2307 print 'jQuery(".trattachnewfilenow").toggle();'."\n";
2308 }
2309 print '
2310 jQuery("form[name=\"expensereport\"]").submit(function() {
2311 if (jQuery(".truploadnewfilenow").is(":hidden")) {
2312 jQuery("input[name=\"sendit\"]").val("");
2313 }
2314 });
2315 ';
2316 print '
2317 });
2318 ';
2319 print '</script>'."\n";
2320 print '</td></tr>';
2321
2322 $filenamelinked = '';
2323 if ($line->fk_ecm_files > 0) {
2324 $result = $ecmfilesstatic->fetch($line->fk_ecm_files);
2325 if ($result > 0) {
2326 $filenamelinked = $ecmfilesstatic->filename;
2327 }
2328 }
2329
2330 $tredited = 'tredited'; // Case the addfile and linkto file is used for edit (used by following tpl)
2331 include DOL_DOCUMENT_ROOT.'/expensereport/tpl/expensereport_addfile.tpl.php';
2332 include DOL_DOCUMENT_ROOT.'/expensereport/tpl/expensereport_linktofile.tpl.php';
2333
2334 print '<tr class="oddeven tredited">';
2335
2336 print '<td></td>';
2337
2338 // Select date
2339 print '<td class="center">';
2340 print $form->selectDate($line->date, 'date');
2341 print '</td>';
2342
2343 // Select project
2344 if (isModEnabled('project')) {
2345 print '<td>';
2346 $formproject->select_projects(-1, $line->fk_project, 'fk_project', 0, 0, $projectRequired ? 0 : 1, 1, 0, 0, 0, '', 0, 0, 'maxwidth300');
2347 print '</td>';
2348 }
2349
2350 // Select type
2351 print '<td class="center">';
2352 print $formexpensereport->selectTypeExpenseReport($line->fk_c_type_fees, 'fk_c_type_fees');
2353 print '</td>';
2354
2355 if (getDolGlobalString('MAIN_USE_EXPENSE_IK')) {
2356 print '<td class="fk_c_exp_tax_cat">';
2357 $params = array('fk_expense' => $object->id, 'fk_expense_det' => $line->id, 'date' => $line->date);
2358 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);
2359 print '</td>';
2360 }
2361
2362 // Add comments
2363 print '<td>';
2364 print '<textarea name="comments" class="flat_ndf centpercent">'.dol_escape_htmltag($line->comments, 0, 1).'</textarea>';
2365 print '</td>';
2366
2367 // VAT
2368 $selectedvat = price2num($line->vatrate).(!empty($line->vat_src_code) ? ' ('.$line->vat_src_code.')' : '');
2369 print '<td class="right">';
2370 print $form->load_tva('vatrate', (GETPOSTISSET("vatrate") ? GETPOST("vatrate") : $selectedvat), $mysoc, '', 0, 0, '', false, 1);
2371 print '</td>';
2372
2373 // Unit price
2374 print '<td class="right">';
2375 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.' />';
2376 print '</td>';
2377
2378 // Unit price with tax
2379 print '<td class="right">';
2380 print '<input type="text" min="0" class="right maxwidth50" id="value_unit" name="value_unit" value="'.dol_escape_htmltag(price2num($line->value_unit)).'" />';
2381 print '</td>';
2382
2383 // Quantity
2384 print '<td class="right">';
2385 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
2386 print '</td>';
2387
2388 //print '<td class="right">'.$langs->trans('AmountHT').'</td>';
2389 //print '<td class="right">'.$langs->trans('AmountTTC').'</td>';
2390
2391 // Picture
2392 print '<td class="center">';
2393 //print $line->fk_ecm_files;
2394 print '</td>';
2395 // Information if theres a rule restriction
2396 print '<td class="center">';
2397 print '</td>';
2398
2399 print '<td>';
2400 print '<input type="hidden" name="rowid" value="'.$line->rowid.'">';
2401 print $form->buttonsSaveCancel('Save', 'Cancel', array(), 0, 'small');
2402 print '</td>';
2403
2404 print '</tr>';
2405 }
2406
2407 $i++;
2408 }
2409 }
2410
2411 // Add a new line
2412 if (($object->status == ExpenseReport::STATUS_DRAFT || $object->status == ExpenseReport::STATUS_REFUSED) && $action != 'editline' && $user->hasRight('expensereport', 'creer')) {
2413 $colspan = 12;
2414 if (getDolGlobalString('MAIN_USE_EXPENSE_IK')) {
2415 $colspan++;
2416 }
2417 if (isModEnabled('project')) {
2418 $colspan++;
2419 }
2420 if ($action != 'editline') {
2421 $colspan++;
2422 }
2423
2424 $nbFiles = $nbLinks = 0;
2425 $arrayoffiles = array();
2426 if (!getDolGlobalString('EXPENSEREPORT_DISABLE_ATTACHMENT_ON_LINES')) {
2427 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
2428 require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
2429 require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php';
2430 $upload_dir = $conf->expensereport->dir_output."/".dol_sanitizeFileName($object->ref);
2431 $arrayoffiles = dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png|'.preg_quote(dol_sanitizeFileName($object->ref.'.pdf'), '/').')$');
2432 $nbFiles = count($arrayoffiles);
2433 $nbLinks = Link::count($db, $object->element, $object->id);
2434 }
2435
2436 // Add line with link to add new file or attach to an existing file
2437 print '<tr class="liste_titre">';
2438 print '<td colspan="'.$colspan.'" class="liste_titre expensereportautoload">';
2439 print '<a href="" class="commonlink auploadnewfilenow reposition">'.$langs->trans("UploadANewFileNow");
2440 print img_picto($langs->trans("UploadANewFileNow"), 'chevron-down', '', false, 0, 0, '', 'marginleftonly');
2441 print '</a>';
2442 if (!getDolGlobalString('EXPENSEREPORT_DISABLE_ATTACHMENT_ON_LINES')) {
2443 print ' &nbsp; - &nbsp; <a href="" class="commonlink aattachtodoc reposition">'.$langs->trans("AttachTheNewLineToTheDocument");
2444 print img_picto($langs->trans("AttachTheNewLineToTheDocument"), 'chevron-down', '', false, 0, 0, '', 'marginleftonly');
2445 print '</a>';
2446 }
2447
2448 print '<!-- Code to open/close section to submit or link files in the form to add new line -->'."\n";
2449 print '<script type="text/javascript">'."\n";
2450 print '$(document).ready(function() {
2451 $( ".auploadnewfilenow" ).click(function() {
2452 console.log("We click on toggle of auploadnewfilenow");
2453 jQuery(".truploadnewfilenow").toggle();
2454 jQuery(".trattachnewfilenow").hide();
2455 if (jQuery(".truploadnewfilenow").is(":hidden")) {
2456 jQuery("input[name=\"sendit\"]").prop("name", "senditdisabled");
2457 } else {
2458 jQuery("input[name=\"senditdisabled\"]").prop("name", "sendit");
2459 }
2460 // TODO Switch css fa-chevron-dow and add fa-chevron-up
2461 return false;
2462 });
2463 $( ".aattachtodoc" ).click(function() {
2464 console.log("We click on toggle of aattachtodoc");
2465 jQuery(".trattachnewfilenow").toggle();
2466 jQuery(".truploadnewfilenow").hide();
2467 // TODO Switch css fa-chevron-dow and add fa-chevron-up
2468 return false;
2469 });'."\n";
2470 if (is_array(GETPOST('attachfile', 'array')) && count(GETPOST('attachfile', 'array')) && $action != 'updateline') {
2471 print 'jQuery(".trattachnewfilenow").show();'."\n";
2472 }
2473 print '
2474 jQuery("form[name=\"expensereport\"]").submit(function() {
2475 if (jQuery(".truploadnewfilenow").is(":hidden")) {
2476 /* 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. */
2477 jQuery("input[name=\"sendit\"]").val("");
2478 jQuery("input[name=\"sendit\"]").prop("name", "senditdisabled");
2479 } else {
2480 jQuery("input[name=\"senditdisabled\"]").prop("name", "sendit");
2481 }
2482 });
2483 ';
2484 print '
2485 });
2486 ';
2487 print '</script>'."\n";
2488 print '</td></tr>';
2489
2490 $tredited = ''; // Case the addfile and linkto file is used for edit (used by following tpl)
2491 include DOL_DOCUMENT_ROOT.'/expensereport/tpl/expensereport_linktofile.tpl.php';
2492 include DOL_DOCUMENT_ROOT.'/expensereport/tpl/expensereport_addfile.tpl.php';
2493
2494 print '<tr class="liste_titre expensereportcreate">';
2495 print '<td></td>';
2496 print '<td class="center expensereportcreatedate">'.$langs->trans('Date').'</td>';
2497 if (isModEnabled('project')) {
2498 print '<td class="minwidth100imp">'.$form->textwithpicto($langs->trans('Project'), $langs->trans("ClosedProjectsAreHidden")).'</td>';
2499 }
2500 print '<td class="center expensereportcreatetype">'.$langs->trans('Type').'</td>';
2501 if (getDolGlobalString('MAIN_USE_EXPENSE_IK')) {
2502 print '<td>'.$langs->trans('CarCategory').'</td>';
2503 }
2504 print '<td class="expensereportcreatedescription">'.$langs->trans('Description').'</td>';
2505 print '<td class="right expensereportcreatevat">'.$langs->trans('VAT').'</td>';
2506 print '<td class="right expensereportcreatepriceuth">'.$langs->trans('PriceUHT').'</td>';
2507 print '<td class="right expensereportcreatepricettc">'.$langs->trans('PriceUTTC').'</td>';
2508 print '<td class="right expensereportcreateqty">'.$langs->trans('Qty').'</td>';
2509 print '<td></td>';
2510 print '<td></td>';
2511 print '<td></td>';
2512 print '<td></td>';
2513 print '<td></td>';
2514 print '</tr>';
2515 print '<tr class="oddeven nohover">';
2516
2517 // Line number
2518 print '<td></td>';
2519
2520 // Select date
2521 print '<td class="center inputdate">';
2522 print $form->selectDate(!empty($date) ? $date : -1, 'date', 0, 0, 0, '', 1, 1);
2523 print '</td>';
2524
2525 // Select project
2526 if (isModEnabled('project')) {
2527 print '<td class="inputproject">';
2528 $formproject->select_projects(-1, !empty($fk_project) ? $fk_project : 0, 'fk_project', 0, 0, $projectRequired ? 0 : 1, -1, 0, 0, 0, '', 0, 0, 'maxwidth300');
2529 print '</td>';
2530 }
2531
2532 // Select type
2533 print '<td class="center inputtype">';
2534 print $formexpensereport->selectTypeExpenseReport(!empty($fk_c_type_fees) ? $fk_c_type_fees : "", 'fk_c_type_fees', 1);
2535 print '</td>';
2536
2537 if (getDolGlobalString('MAIN_USE_EXPENSE_IK')) {
2538 print '<td class="fk_c_exp_tax_cat">';
2539 $params = array('fk_expense' => $object->id);
2540 print $form->selectExpenseCategories('', 'fk_c_exp_tax_cat', 1, array(), 'fk_c_type_fees', $userauthor->default_c_exp_tax_cat, $params, 0);
2541 print '</td>';
2542 }
2543
2544 // Add comments
2545 print '<td class="inputcomment">';
2546 print '<textarea class="flat_ndf centpercent" name="comments" rows="'.ROWS_2.'">'.dol_escape_htmltag(!empty($comments) ? $comments : "", 0, 1).'</textarea>';
2547 print '</td>';
2548
2549 // Select VAT
2550 print '<td class="right inputvat">';
2551 $defaultvat = -1;
2552 if (getDolGlobalString('EXPENSEREPORT_NO_DEFAULT_VAT')) {
2553 // If option to have no default VAT on expense report is on, we force MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS
2554 $conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS = 'none';
2555 }
2556 print $form->load_tva('vatrate', (!empty($vatrate) ? $vatrate : $defaultvat), $mysoc, '', 0, 0, '', false, 1);
2557 print '</td>';
2558
2559 // Unit price net
2560 print '<td class="right inputpricenet">';
2561 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.' />';
2562 print '</td>';
2563
2564 // Unit price with tax
2565 print '<td class="right inputtax">';
2566 print '<input type="text" class="right maxwidth50" id="value_unit" name="value_unit" value="'.dol_escape_htmltag((!empty($value_unit) ? $value_unit : 0)).'">';
2567 print '</td>';
2568
2569 // Quantity
2570 print '<td class="right inputqty">';
2571 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
2572 print '</td>';
2573
2574 // Picture
2575 print '<td></td>';
2576
2577 if ($action != 'editline') {
2578 print '<td class="right"></td>';
2579 print '<td class="right"></td>';
2580 }
2581
2582 print '<td class="center inputbuttons">';
2583 print $form->buttonsSaveCancel("Add", '', '', 1, 'reposition');
2584 print '</td>';
2585
2586 print '</tr>';
2587 } // Fin si c'est payé/validé
2588
2589 print '</table>';
2590 print '</div>';
2591
2592 print '<script>
2593
2594 /* JQuery for product free or predefined select */
2595 jQuery(document).ready(function() {
2596 jQuery("#value_unit_ht").keyup(function(event) {
2597 console.log(event.which); // discard event tag and arrows
2598 if (event.which != 9 && (event.which < 37 ||event.which > 40) && jQuery("#value_unit_ht").val() != "") {
2599 jQuery("#value_unit").val("");
2600 }
2601 });
2602 jQuery("#value_unit").keyup(function(event) {
2603 console.log(event.which); // discard event tag and arrows
2604 if (event.which != 9 && (event.which < 37 || event.which > 40) && jQuery("#value_unit").val() != "") {
2605 jQuery("#value_unit_ht").val("");
2606 }
2607 });
2608 ';
2609
2610 if (getDolGlobalString('MAIN_USE_EXPENSE_IK')) {
2611 print '
2612
2613 /* unit price coef calculation */
2614 jQuery(".input_qty, #fk_c_type_fees, #select_fk_c_exp_tax_cat, #vatrate ").change(function(event) {
2615 console.log("We change a parameter");
2616
2617 let type_fee = jQuery("#fk_c_type_fees").find(":selected").val();
2618 let tax_cat = jQuery("#select_fk_c_exp_tax_cat").find(":selected").val();
2619 let tva = jQuery("#vatrate").find(":selected").val();
2620 let qty = jQuery(".input_qty").val();
2621
2622 let path = "'.dol_buildpath("/expensereport/ajax/ajaxik.php", 1).'";
2623 path += "?fk_c_exp_tax_cat="+tax_cat;
2624 path += "&fk_expense="+'.((int) $object->id).';
2625 path += "&vatrate="+tva;
2626 path += "&qty="+qty;
2627
2628 if (type_fee == 4) { // frais_kilométriques
2629 if (tax_cat == "" || parseInt(tax_cat) <= 0){
2630 return ;
2631 }
2632
2633 jQuery.ajax({
2634 url: path,
2635 async: true,
2636 dataType: "json",
2637 success: function(response) {
2638 if (response.response_status == "success"){';
2639
2640 if (getDolGlobalString('EXPENSEREPORT_FORCE_LINE_AMOUNTS_INCLUDING_TAXES_ONLY')) {
2641 print '
2642 jQuery("#value_unit").val(parseFloat(response.data) * (100 + parseFloat(tva)) / 100);
2643 jQuery("#value_unit").trigger("change");
2644 ';
2645 } else {
2646 print '
2647 jQuery("#value_unit_ht").val(response.data);
2648 jQuery("#value_unit_ht").trigger("change");
2649 jQuery("#value_unit").val("");
2650 ';
2651 }
2652
2653 print '
2654 } else if(response.response_status == "error" && response.errorMessage != undefined && response.errorMessage.length > 0 ) {
2655 console.log("We get an error result");
2656 $.jnotify(response.errorMessage, "error", {timeout: 0, type: "error"},{ remove: function (){} } );
2657 }
2658 }
2659 });
2660 }
2661
2662 /*console.log(event.which); // discard event tag and arrows
2663 if (event.which != 9 && (event.which < 37 || event.which > 40) && jQuery("#value_unit").val() != "") {
2664 jQuery("#value_unit_ht").val("");
2665 }*/
2666 });
2667 ';
2668 }
2669
2670 print '
2671
2672 });
2673
2674 </script>';
2675
2676 print '</form>';
2677
2678 print dol_get_fiche_end();
2679 }
2680 } else {
2681 dol_print_error($db);
2682 }
2683} else {
2684 print 'Record not found';
2685
2686 llxFooter();
2687 exit(1);
2688}
2689
2690
2691/*
2692 * Action bar
2693 */
2694
2695print '<div class="tabsAction">';
2696
2697if ($action != 'create' && $action != 'edit' && $action != 'editline') {
2698 $object = new ExpenseReport($db);
2699 $object->fetch($id, $ref);
2700
2701 // Send
2702 if (empty($user->socid)) {
2703 if ($object->status > ExpenseReport::STATUS_DRAFT) {
2704 //if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->expensereport->expensereport_advance->send)) {
2705 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>';
2706 //} else
2707 // print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#">' . $langs->trans('SendMail') . '</a></div>';
2708 }
2709 }
2710
2711 /* Si l'état est "Brouillon"
2712 * ET user à droit "creer/supprimer"
2713 * ET fk_user_author == user courant
2714 * Afficher : "Enregistrer" / "Modifier" / "Supprimer"
2715 */
2716 if ($user->hasRight('expensereport', 'creer') && $object->status == ExpenseReport::STATUS_DRAFT) {
2717 if (in_array($object->fk_user_author, $user->getAllChildIds(1)) || $user->hasRight('expensereport', 'writeall_advance')) {
2718 // Modify
2719 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>';
2720
2721 // Validate
2722 if (count($object->lines) > 0) {
2723 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>';
2724 }
2725 }
2726 }
2727
2728 /* Si l'état est "Refusée"
2729 * ET user à droit "creer/supprimer"
2730 * ET fk_user_author == user courant
2731 * Afficher : "Enregistrer" / "Modifier" / "Supprimer"
2732 */
2733 if ($user->hasRight('expensereport', 'creer') && $object->status == ExpenseReport::STATUS_REFUSED) {
2734 if ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) {
2735 // Modify
2736 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>';
2737
2738 // setdraft (le statut refusée est identique à brouillon)
2739 //print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=brouillonner&id='.$id.'">'.$langs->trans('ReOpen').'</a>';
2740 // Enregistrer depuis le statut "Refusée"
2741 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>';
2742 }
2743 }
2744
2745 if ($user->hasRight('expensereport', 'to_paid') && $object->status == ExpenseReport::STATUS_APPROVED) {
2746 if ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) {
2747 // setdraft
2748 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>';
2749 }
2750 }
2751
2752 /* Si l'état est "En attente d'approbation"
2753 * ET user à droit de "approve"
2754 * ET fk_user_validator == user courant
2755 * Afficher : "Valider" / "Refuser" / "Supprimer"
2756 */
2757 if ($object->status == ExpenseReport::STATUS_VALIDATED) {
2758 if (in_array($object->fk_user_author, $user->getAllChildIds(1))) {
2759 // set draft
2760 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>';
2761 }
2762 }
2763
2764 if ($user->hasRight('expensereport', 'approve') && $object->status == ExpenseReport::STATUS_VALIDATED) {
2765 //if($object->fk_user_validator==$user->id)
2766 //{
2767 // Validate
2768 print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=validate&id='.$object->id.'">'.$langs->trans('Approve').'</a></div>';
2769 // Deny
2770 print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=refuse&id='.$object->id.'">'.$langs->trans('Deny').'</a></div>';
2771 //}
2772
2773 if ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) {
2774 // Cancel
2775 print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=cancel&id='.$object->id.'">'.$langs->trans("Cancel").'</a></div>';
2776 }
2777 }
2778
2779
2780 // If status is Approved
2781 // ---------------------
2782
2783 if ($user->hasRight('expensereport', 'approve') && $object->status == ExpenseReport::STATUS_APPROVED) {
2784 print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=refuse&id='.$object->id.'">'.$langs->trans('Deny').'</a></div>';
2785 }
2786
2787 // If bank module is used
2788 if ($user->hasRight('expensereport', 'to_paid') && isModEnabled("banque") && $object->status == ExpenseReport::STATUS_APPROVED) {
2789 // Pay
2790 if ($remaintopay == 0) {
2791 print '<div class="inline-block divButAction"><span class="butActionRefused classfortooltip" title="'.$langs->trans("DisabledBecauseRemainderToPayIsZero").'">'.$langs->trans('DoPayment').'</span></div>';
2792 } else {
2793 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>';
2794 }
2795 }
2796
2797 // If bank module is not used
2798 if (($user->hasRight('expensereport', 'to_paid') || empty(isModEnabled("banque"))) && $object->status == ExpenseReport::STATUS_APPROVED) {
2799 //if ((round($remaintopay) == 0 || !isModEnabled("banque")) && $object->paid == 0)
2800 if ($object->paid == 0) {
2801 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>";
2802 }
2803 }
2804
2805 if ($user->hasRight('expensereport', 'creer') && ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) && $object->status == ExpenseReport::STATUS_APPROVED) {
2806 // Cancel
2807 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>';
2808 }
2809
2810 // TODO Replace this. It should be SetUnpaid and should go back to status unpaid not canceled.
2811 if (($user->hasRight('expensereport', 'approve') || $user->hasRight('expensereport', 'to_paid')) && $object->status == ExpenseReport::STATUS_CLOSED) {
2812 // Cancel
2813 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>';
2814 }
2815
2816 if ($user->hasRight('expensereport', 'to_paid') && $object->paid && $object->status == ExpenseReport::STATUS_CLOSED) {
2817 // Set unpaid
2818 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>';
2819 }
2820
2821 // Clone
2822 if ($user->hasRight('expensereport', 'creer')) {
2823 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>';
2824 }
2825
2826 /* If draft, validated, cancel, and user can create, he can always delete its card before it is approved */
2827 if ($user->hasRight('expensereport', 'creer') && $user->id == $object->fk_user_author && $object->status < ExpenseReport::STATUS_APPROVED) {
2828 // Delete
2829 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>';
2830 } elseif ($candelete && $object->status != ExpenseReport::STATUS_CLOSED) {
2831 // Delete
2832 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>';
2833 }
2834
2835 $parameters = array();
2836 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
2837}
2838
2839print '</div>';
2840
2841
2842// Select mail models is same action as presend
2843if (GETPOST('modelselected', 'alpha')) {
2844 $action = 'presend';
2845}
2846
2847if ($action != 'presend') {
2848 /*
2849 * Generate documents
2850 */
2851
2852 print '<div class="fichecenter"><div class="fichehalfleft">';
2853 print '<a name="builddoc"></a>'; // ancre
2854
2855 if ($user->hasRight('expensereport', 'creer') && $action != 'create' && $action != 'edit') {
2856 $filename = dol_sanitizeFileName($object->ref);
2857 $filedir = $conf->expensereport->dir_output."/".dol_sanitizeFileName($object->ref);
2858 $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
2859 $genallowed = $user->rights->expensereport->creer;
2860 $delallowed = $user->rights->expensereport->creer;
2861 $var = true;
2862 print $formfile->showdocuments('expensereport', $filename, $filedir, $urlsource, $genallowed, $delallowed);
2863 $somethingshown = $formfile->numoffiles;
2864 }
2865
2866 // Disabled for expensereport, there is no thirdparty on expensereport, so nothing to define the list of other object we can suggest to link to
2867 /*
2868 if ($action != 'create' && $action != 'edit' && ($id || $ref))
2869 {
2870 $linktoelem = $form->showLinkToObjectBlock($object, null, array('expensereport'));
2871 $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
2872 }
2873 */
2874
2875 print '</div><div class="fichehalfright">';
2876 // List of actions on element
2877 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
2878 $formactions = new FormActions($db);
2879 $somethingshown = $formactions->showactions($object, 'expensereport', null);
2880
2881 print '</div></div>';
2882}
2883
2884// Presend form
2885$modelmail = 'expensereport_send';
2886$defaulttopic = 'SendExpenseReportRef';
2887$diroutput = $conf->expensereport->dir_output;
2888$trackid = 'exp'.$object->id;
2889
2890include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
2891
2892
2893llxFooter();
2894
2895$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.