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