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