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