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