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