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