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