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