dolibarr 23.0.3
element.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2001-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004-2020 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005-2010 Regis Houssin <regis.houssin@inodbox.com>
5 * Copyright (C) 2012-2016 Juanjo Menent <jmenent@2byte.es>
6 * Copyright (C) 2015-2021 Alexandre Spangaro <aspangaro@open-dsi.fr>
7 * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
8 * Copyright (C) 2016 Josep Lluís Amador <joseplluis@lliuretic.cat>
9 * Copyright (C) 2021-2023 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
10 * Copyright (C) 2021 Noé Cendrier <noe.cendrier@altairis.fr>
11 * Copyright (C) 2023-2025 Frédéric France <frederic.france@free.fr>
12 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
13 * Copyright (C) 2025 Günter Lukas <github@gl.co.at>
14 * Copyright (C) 2026 Joachim Kueter <git-jk@bloxera.com>
15 * Copyright (C) 2026 Ferran Marcet <fmarcet@2byte.es>
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 3 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program. If not, see <https://www.gnu.org/licenses/>.
29 */
30
37// Load Dolibarr environment
38require '../main.inc.php';
48require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
49require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
50require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
51require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
52require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
53require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
54require_once DOL_DOCUMENT_ROOT.'/core/class/timespent.class.php';
55
56if (isModEnabled('agenda')) {
57 require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
58}
59if (isModEnabled('bank')) {
60 require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/paymentvarious.class.php';
61}
62if (isModEnabled('category')) {
63 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
64}
65if (isModEnabled('order')) {
66 require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
67}
68if (isModEnabled('contract')) {
69 require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
70}
71if (isModEnabled('deplacement')) {
72 require_once DOL_DOCUMENT_ROOT.'/compta/deplacement/class/deplacement.class.php';
73}
74if (isModEnabled('don')) {
75 require_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php';
76}
77if (isModEnabled('shipping')) {
78 require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php';
79}
80if (isModEnabled('expensereport')) {
81 require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
82}
83if (isModEnabled('invoice')) {
84 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
85 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php';
86}
87if (isModEnabled('intervention')) {
88 require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
89}
90if (isModEnabled('loan')) {
91 require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php';
92 require_once DOL_DOCUMENT_ROOT.'/loan/class/loanschedule.class.php';
93}
94if (isModEnabled('mrp')) {
95 require_once DOL_DOCUMENT_ROOT.'/mrp/class/mo.class.php';
96}
97if (isModEnabled('propal')) {
98 require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
99}
100if (isModEnabled('salaries')) {
101 require_once DOL_DOCUMENT_ROOT.'/salaries/class/salary.class.php';
102}
103if (isModEnabled('stock')) {
104 require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
105 require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
106}
107if (isModEnabled('supplier_invoice')) {
108 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
109}
110if (isModEnabled('supplier_order')) {
111 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
112}
113if (isModEnabled('supplier_proposal')) {
114 require_once DOL_DOCUMENT_ROOT.'/supplier_proposal/class/supplier_proposal.class.php';
115}
116if (isModEnabled('tax')) {
117 require_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php';
118}
119if (isModEnabled('stocktransfer')) {
120 require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/class/stocktransfer.class.php';
121 require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/class/stocktransferline.class.php';
122}
123
124// Load translation files required by the page
125$langs->loadLangs(array('projects', 'companies', 'suppliers', 'compta'));
126if (isModEnabled('invoice')) {
127 $langs->load("bills");
128}
129if (isModEnabled('order')) {
130 $langs->load("orders");
131}
132if (isModEnabled("propal")) {
133 $langs->load("propal");
134}
135if (isModEnabled('intervention')) {
136 $langs->load("interventions");
137}
138if (isModEnabled('deplacement')) {
139 $langs->load("trips");
140}
141if (isModEnabled('expensereport')) {
142 $langs->load("trips");
143}
144if (isModEnabled('don')) {
145 $langs->load("donations");
146}
147if (isModEnabled('loan')) {
148 $langs->load("loan");
149}
150if (isModEnabled('salaries')) {
151 $langs->load("salaries");
152}
153if (isModEnabled('mrp')) {
154 $langs->load("mrp");
155}
156if (isModEnabled('eventorganization')) {
157 $langs->load("eventorganization");
158}
159
160$id = GETPOSTINT('id');
161$ref = GETPOST('ref', 'alpha');
162$action = GETPOST('action', 'aZ09');
163$datesrfc = GETPOST('datesrfc'); // deprecated
164$dateerfc = GETPOST('dateerfc'); // deprecated
165$dates = dol_mktime(0, 0, 0, GETPOSTINT('datesmonth'), GETPOSTINT('datesday'), GETPOSTINT('datesyear'));
166$datee = dol_mktime(23, 59, 59, GETPOSTINT('dateemonth'), GETPOSTINT('dateeday'), GETPOSTINT('dateeyear'));
167if (empty($dates) && !empty($datesrfc)) { // deprecated
168 $dates = dol_stringtotime($datesrfc);
169}
170if (empty($datee) && !empty($dateerfc)) { // deprecated
171 $datee = dol_stringtotime($dateerfc);
172}
173if (!GETPOSTISSET('datesrfc') && !GETPOSTISSET('datesday') && getDolGlobalString('PROJECT_LINKED_ELEMENT_DEFAULT_FILTER_YEAR')) {
174 $new = dol_now();
175 $tmp = dol_getdate($new);
176 //$datee=$now
177 //$dates=dol_time_plus_duree($datee, -1, 'y');
178 $dates = dol_get_first_day($tmp['year'], 1);
179}
180if ($id == '' && $ref == '') {
181 setEventMessage($langs->trans('ErrorBadParameters'), 'errors');
182 header('Location: list.php');
183 exit();
184}
185
186$mine = GETPOST('mode') == 'mine' ? 1 : 0;
187
188$object = new Project($db);
189
190include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be 'include', not 'include_once'
191if (getDolGlobalString('PROJECT_ALLOW_COMMENT_ON_PROJECT') && method_exists($object, 'fetchComments') && empty($object->comments)) {
192 $object->fetchComments();
193}
194
195// Security check
196$socid = $object->socid;
197
198$hookmanager->initHooks(array('projectOverview'));
199
200//if ($user->socid > 0) $socid = $user->socid; // For external user, no check is done on company because readability is managed by public status of project and assignment.
201$result = restrictedArea($user, 'projet', $object->id, 'projet&project');
202
203// Check if user has access to any financial module (not just project time)
204$canSeeFinancials = (
205 (isModEnabled('invoice') && $user->hasRight('facture', 'lire'))
206 || (isModEnabled('supplier_invoice') && ($user->hasRight('fournisseur', 'facture', 'lire') || $user->hasRight('supplier_invoice', 'lire')))
207 || (isModEnabled('salaries') && $user->hasRight('salaries', 'read'))
208 || (isModEnabled('expensereport') && $user->hasRight('expensereport', 'lire'))
209 || (isModEnabled('don') && $user->hasRight('don', 'lire'))
210 || (isModEnabled('tax') && $user->hasRight('tax', 'charges', 'lire'))
211 || (isModEnabled('bank') && $user->hasRight('banque', 'lire'))
212);
213
214$total_duration = 0;
215$total_ttc_by_line = 0;
216$total_ht_by_line = 0;
217$expensereport = null;
218$othermessage = '';
219$tmpprojtime = array();
220$nbAttendees = 0;
221
222$permissiontoadd = $user->hasRight('projet', 'creer');
223$permissiontodelete = $user->hasRight('projet', 'supprimer');
224$permissiondellink = $user->hasRight('projet', 'creer'); // Used by the include of actions_dellink.inc.php
225$permissiontoeditextra = $permissiontoadd;
226if (GETPOST('attribute', 'aZ09') && isset($extrafields->attributes[$object->table_element]['perms'][GETPOST('attribute', 'aZ09')])) {
227 // For action 'update_extras', is there a specific permission set for the attribute to update
228 $permissiontoeditextra = dol_eval($extrafields->attributes[$object->table_element]['perms'][GETPOST('attribute', 'aZ09')]);
229}
230
231/*
232 * Actions
233 */
234
235// Quick edit for extrafields
236if ($action == 'update_extras' && $permissiontoeditextra) {
237 $error = 0;
238 $object->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty
239
240 $attribute_name = GETPOST('attribute', 'aZ09');
241
242 // Fill array 'array_options' with data from update form
243 $ret = $extrafields->setOptionalsFromPost(null, $object, $attribute_name);
244 if ($ret < 0) {
245 $error++;
246 }
247
248 if (!$error) {
249 $result = $object->updateExtraField($attribute_name, 'PROJECT_MODIFY');
250 if ($result < 0) {
251 setEventMessages($object->error, $object->errors, 'errors');
252 $error++;
253 }
254 }
255
256 if ($error) {
257 $action = 'edit_extras';
258 }
259}
260if (($action == 'updateundefinedwithlasthourlyrate' || $action == 'updateallwithlasthourlyrate') && $permissiontoadd) {
261 $error = 0;
262 if (!GETPOSTISSET('taskid')) {
263 $error++;
264 }
265 if (!$error) {
266 $taskid = GETPOSTINT("taskid");
267
268 $sql = "SELECT et.rowid as id, u.thm as thmuser";
269 $sql .= " FROM ".MAIN_DB_PREFIX."element_time as et";
270 $sql .= " INNER JOIN ".MAIN_DB_PREFIX."user as u ON u.rowid = et.fk_user";
271 $sql .= " WHERE et.elementtype = 'task'";
272 $sql .= " AND et.fk_element = ".((int) $taskid);
273 if ($action == 'updateundefinedwithlasthourlyrate') { // Test on permission already done
274 $sql .= " AND et.thm IS NULL"; // Note: If 0, it is defined, we won't update it.
275 }
276
277 $resql = $db->query($sql);
278 if ($resql) {
279 $num = $db->num_rows($resql);
280 $i = 0;
281 while ($i < $num) {
282 $obj = $db->fetch_object($resql);
283 if (empty($obj->thmuser)) {
284 $error++;
285 break;
286 }
287 $timespent = new TimeSpent($db);
288 $res = $timespent->fetch($obj->id);
289 if ($res <= 0) {
290 setEventMessages($timespent->error, $timespent->errors, 'errors');
291 $error++;
292 break;
293 }
294 $timespent->thm = $obj->thmuser;
295 $res = $timespent->update($user);
296 if ($res <= 0) {
297 setEventMessages($timespent->error, $timespent->errors, 'errors');
298 $error++;
299 break;
300 }
301 $i++;
302 }
303 } else {
304 dol_print_error($db);
305 $error++;
306 }
307 }
308 if (!$error) {
309 $db->commit();
310 setEventMessages($langs->trans("TaskHourlyRateUpdated"), null);
311 $action = '';
312 } else {
313 $db->rollback();
314 }
315}
316
317
318/*
319 * View
320 */
321
322$title = $langs->trans('ProjectReferers').' - '.$object->ref.' '.$object->name;
323if (getDolGlobalString('MAIN_HTML_TITLE') && preg_match('/projectnameonly/', getDolGlobalString('MAIN_HTML_TITLE')) && $object->name) {
324 $title = $object->ref.' '.$object->name.' - '.$langs->trans('ProjectReferers');
325}
326
327$help_url = 'EN:Module_Projects|FR:Module_Projets|ES:M&oacute;dulo_Proyectos|DE:Modul_Projekte';
328
329llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-project page-card_element');
330
331$form = new Form($db);
332$formproject = new FormProjets($db);
333$formfile = new FormFile($db);
334
335$userstatic = new User($db);
336
337// To verify role of users
338$userAccess = $object->restrictedProjectArea($user);
339
340$head = project_prepare_head($object);
341print dol_get_fiche_head($head, 'element', $langs->trans("Project"), -1, ($object->public ? 'projectpub' : 'project'));
342
343
344// Project card
345
346if (!empty($_SESSION['pageforbacktolist']) && !empty($_SESSION['pageforbacktolist']['project'])) {
347 $tmpurl = $_SESSION['pageforbacktolist']['project'];
348 $tmpurl = preg_replace('/__SOCID__/', (string) $object->socid, $tmpurl);
349 $linkback = '<a href="'.$tmpurl.(preg_match('/\?/', $tmpurl) ? '&' : '?'). 'restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
350} else {
351 $linkback = '<a href="'.DOL_URL_ROOT.'/projet/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
352}
353
354$morehtmlref = '<div class="refidno">';
355// Title
356$morehtmlref .= $object->title;
357// Thirdparty
358if (!empty($object->thirdparty->id) && $object->thirdparty->id > 0) {
359 $morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1, 'project');
360}
361$morehtmlref .= '</div>';
362
363// Define a complementary filter for search of next/prev ref.
364if (!$user->hasRight('projet', 'all', 'lire')) {
365 $objectsListId = $object->getProjectsAuthorizedForUser($user, 0, 0);
366 $object->next_prev_filter = "te.rowid:IN:".$db->sanitize(count($objectsListId) ? implode(',', array_keys($objectsListId)) : '0');
367}
368
369dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
370
371
372print '<div class="fichecenter">';
373print '<div class="fichehalfleft">';
374print '<div class="underbanner clearboth"></div>';
375
376print '<table class="border tableforfield centpercent">';
377
378// Usage
379if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES') || !getDolGlobalString('PROJECT_HIDE_TASKS') || isModEnabled('eventorganization')) {
380 print '<tr><td class="tdtop">';
381 print $langs->trans("Usage");
382 print '</td>';
383 print '<td>';
384 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) {
385 print '<input type="checkbox" disabled name="usage_opportunity"'.(GETPOSTISSET('usage_opportunity') ? (GETPOST('usage_opportunity', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_opportunity ? ' checked="checked"' : '')).'"> ';
386 $htmltext = $langs->trans("ProjectFollowOpportunity");
387 print $form->textwithpicto($langs->trans("ProjectFollowOpportunity"), $htmltext);
388 print '<br>';
389 }
390 if (!getDolGlobalString('PROJECT_HIDE_TASKS')) {
391 print '<input type="checkbox" disabled name="usage_task"'.(GETPOSTISSET('usage_task') ? (GETPOST('usage_task', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_task ? ' checked="checked"' : '')).'"> ';
392 $htmltext = $langs->trans("ProjectFollowTasks");
393 print $form->textwithpicto($langs->trans("ProjectFollowTasks"), $htmltext);
394 print '<br>';
395 }
396 if (!getDolGlobalString('PROJECT_HIDE_TASKS') && getDolGlobalString('PROJECT_BILL_TIME_SPENT')) {
397 print '<input type="checkbox" disabled name="usage_bill_time"'.(GETPOSTISSET('usage_bill_time') ? (GETPOST('usage_bill_time', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_bill_time ? ' checked="checked"' : '')).'"> ';
398 $htmltext = $langs->trans("ProjectBillTimeDescription");
399 print $form->textwithpicto($langs->trans("BillTime"), $htmltext);
400 print '<br>';
401 }
402 if (isModEnabled('eventorganization')) {
403 print '<input type="checkbox" disabled name="usage_organize_event"'.(GETPOSTISSET('usage_organize_event') ? (GETPOST('usage_organize_event', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_organize_event ? ' checked="checked"' : '')).'"> ';
404 $htmltext = $langs->trans("EventOrganizationDescriptionLong");
405 print $form->textwithpicto($langs->trans("ManageOrganizeEvent"), $htmltext);
406 }
407 print '</td></tr>';
408}
409
410if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES') && !empty($object->usage_opportunity)) {
411 // Opportunity status
412 print '<tr><td>'.$langs->trans("OpportunityStatus").'</td><td>';
413 $code = dol_getIdFromCode($db, $object->opp_status, 'c_lead_status', 'rowid', 'code');
414 if ($code) {
415 print $langs->trans("OppStatus".$code);
416 }
417
418 // Opportunity percent
419 print ' <span title="'.$langs->trans("OpportunityProbability").'"> / ';
420 if (strcmp($object->opp_percent, '')) {
421 print price($object->opp_percent, 0, $langs, 1, 0).' %';
422 }
423 print '</span></td></tr>';
424
425 // Opportunity Amount
426 print '<tr><td>'.$langs->trans("OpportunityAmount").'</td><td>';
427 if (!is_null($object->opp_amount) && strcmp($object->opp_amount, '')) {
428 print '<span class="amount">'.price($object->opp_amount, 0, $langs, 1, 0, 0, $conf->currency).'</span>';
429 if (strcmp($object->opp_percent, '')) {
430 print ' &nbsp; &nbsp; &nbsp; <span title="'.dol_escape_htmltag($langs->trans('OpportunityWeightedAmount')).'"><span class="opacitymedium">'.$langs->trans("OpportunityWeightedAmountShort").'</span>: <span class="amount">'.price($object->opp_amount * $object->opp_percent / 100, 0, $langs, 1, 0, -1, $conf->currency).'</span></span>';
431 }
432 }
433 print '</td></tr>';
434}
435
436// Budget
437print '<tr><td>'.$langs->trans("Budget").'</td><td>';
438if (!is_null($object->budget_amount) && strcmp($object->budget_amount, '')) {
439 print '<span class="amount">'.price($object->budget_amount, 0, $langs, 1, 0, 0, $conf->currency).'</span>';
440}
441print '</td></tr>';
442
443// Date start - end project
444print '<tr><td>'.$langs->trans("Dates").'</td><td>';
445$start = dol_print_date($object->date_start, 'day');
446print($start ? $start : '?');
447$end = dol_print_date($object->date_end, 'day');
448print ' - ';
449print($end ? $end : '?');
450if ($object->hasDelay()) {
451 print img_warning("Late");
452}
453print '</td></tr>';
454
455// Visibility
456print '<tr><td class="titlefield">'.$langs->trans("Visibility").'</td><td>';
457if ($object->public) {
458 print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"');
459 print $langs->trans('SharedProject');
460} else {
461 print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"');
462 print $langs->trans('PrivateProject');
463}
464print '</td></tr>';
465
466// Other attributes
467$cols = 2;
468include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
469
470print '</table>';
471
472print '</div>';
473print '<div class="fichehalfright">';
474print '<div class="underbanner clearboth"></div>';
475
476print '<table class="border tableforfield centpercent">';
477
478// Categories
479if (isModEnabled('category')) {
480 print '<tr><td class="valignmiddle">'.$langs->trans("Categories").'</td><td>';
481 print $form->showCategories($object->id, Categorie::TYPE_PROJECT, 1);
482 print "</td></tr>";
483}
484
485// Description
486print '<tr><td class="titlefield'.($object->description ? ' noborderbottom' : '').'" colspan="2">'.$langs->trans("Description").'</td></tr>';
487if ($object->description) {
488 print '<tr><td class="nottitleforfield" colspan="2">';
489 print '<div class="longmessagecut">';
490 print dolPrintHTML($object->description);
491 print '</div>';
492 print '</td></tr>';
493}
494
495print '</table>';
496
497print '</div>';
498print '</div>';
499
500print '<div class="clearboth"></div>';
501
502print dol_get_fiche_end();
503
504print '<br>';
505
506/*
507 * Referrer types
508 */
509
510$listofreferent = array(
511 'entrepot' => array(
512 'name' => "Warehouse",
513 'title' => "ListWarehouseAssociatedProject",
514 'class' => 'Entrepot',
515 'table' => 'entrepot',
516 'datefieldname' => 'date_entrepot',
517 'urlnew' => DOL_URL_ROOT.'/product/stock/card.php?action=create&projectid='.$id.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
518 'lang' => 'entrepot',
519 'buttonnew' => 'AddWarehouse',
520 'project_field' => 'fk_project',
521 'testnew' => $user->hasRight('stock', 'creer'),
522 'test' => isModEnabled('stock') && $user->hasRight('stock', 'lire') && getDolGlobalString('WAREHOUSE_ASK_WAREHOUSE_DURING_PROJECT')
523 ),
524 'propal' => array(
525 'name' => "Proposals",
526 'title' => "ListProposalsAssociatedProject",
527 'class' => 'Propal',
528 'table' => 'propal',
529 'datefieldname' => 'datep',
530 'urlnew' => DOL_URL_ROOT.'/comm/propal/card.php?action=create&origin=project&originid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
531 'lang' => 'propal',
532 'buttonnew' => 'AddProp',
533 'testnew' => $user->hasRight('propal', 'creer'),
534 'test' => isModEnabled('propal') && $user->hasRight('propal', 'lire')
535 ),
536 'order' => array(
537 'name' => "CustomersOrders",
538 'title' => "ListOrdersAssociatedProject",
539 'class' => 'Commande',
540 'table' => 'commande',
541 'datefieldname' => 'date_commande',
542 'urlnew' => DOL_URL_ROOT.'/commande/card.php?action=create&projectid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
543 'lang' => 'orders',
544 'buttonnew' => 'CreateOrder',
545 'testnew' => $user->hasRight('commande', 'creer'),
546 'test' => isModEnabled('order') && $user->hasRight('commande', 'lire')
547 ),
548 'invoice' => array(
549 'name' => "CustomersInvoices",
550 'title' => "ListInvoicesAssociatedProject",
551 'class' => 'Facture',
552 'margin' => 'add',
553 'table' => 'facture',
554 'datefieldname' => 'datef',
555 'urlnew' => DOL_URL_ROOT.'/compta/facture/card.php?action=create&projectid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
556 'lang' => 'bills',
557 'buttonnew' => 'CreateBill',
558 'testnew' => $user->hasRight('facture', 'creer'),
559 'test' => isModEnabled('invoice') && $user->hasRight('facture', 'lire')
560 ),
561 'invoice_predefined' => array(
562 'name' => "PredefinedInvoices",
563 'title' => "ListPredefinedInvoicesAssociatedProject",
564 'class' => 'FactureRec',
565 'table' => 'facture_rec',
566 'datefieldname' => 'datec',
567 'urlnew' => DOL_URL_ROOT.'/compta/facture/card.php?action=create&projectid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
568 'lang' => 'bills',
569 'buttonnew' => 'CreateBill',
570 'testnew' => $user->hasRight('facture', 'creer'),
571 'test' => isModEnabled('invoice') && $user->hasRight('facture', 'lire')
572 ),
573 'proposal_supplier' => array(
574 'name' => "SupplierProposals",
575 'title' => "ListSupplierProposalsAssociatedProject",
576 'class' => 'SupplierProposal',
577 'table' => 'supplier_proposal',
578 'datefieldname' => 'date_valid',
579 'urlnew' => DOL_URL_ROOT.'/supplier_proposal/card.php?action=create&projectid='.$id.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id), // No socid parameter here, the socid is often the customer and we create a supplier object
580 'lang' => 'supplier_proposal',
581 'buttonnew' => 'AddSupplierProposal',
582 'testnew' => $user->hasRight('supplier_proposal', 'creer'),
583 'test' => isModEnabled('supplier_proposal') && $user->hasRight('supplier_proposal', 'lire')
584 ),
585 'order_supplier' => array(
586 'name' => "SuppliersOrders",
587 'title' => "ListSupplierOrdersAssociatedProject",
588 'class' => 'CommandeFournisseur',
589 'table' => 'commande_fournisseur',
590 'datefieldname' => 'date_commande',
591 'urlnew' => DOL_URL_ROOT.'/fourn/commande/card.php?action=create&projectid='.$id.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id), // No socid parameter here, the socid is often the customer and we create a supplier object
592 'lang' => 'suppliers',
593 'buttonnew' => 'AddSupplierOrder',
594 'testnew' => $user->hasRight('fournisseur', 'commande', 'creer') || $user->hasRight('supplier_order', 'creer'),
595 'test' => isModEnabled('supplier_order') && $user->hasRight('fournisseur', 'commande', 'lire') || $user->hasRight('supplier_order', 'lire')
596 ),
597 'invoice_supplier' => array(
598 'name' => "BillsSuppliers",
599 'title' => "ListSupplierInvoicesAssociatedProject",
600 'class' => 'FactureFournisseur',
601 'margin' => 'minus',
602 'table' => 'facture_fourn',
603 'datefieldname' => 'datef',
604 'urlnew' => DOL_URL_ROOT.'/fourn/facture/card.php?action=create&projectid='.$id.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id), // No socid parameter here, the socid is often the customer and we create a supplier object
605 'lang' => 'suppliers',
606 'buttonnew' => 'AddSupplierInvoice',
607 'testnew' => $user->hasRight('fournisseur', 'facture', 'creer') || $user->hasRight('supplier_invoice', 'creer'),
608 'test' => isModEnabled('supplier_invoice') && $user->hasRight('fournisseur', 'facture', 'lire') || $user->hasRight('supplier_invoice', 'lire')
609 ),
610 'contract' => array(
611 'name' => "Contracts",
612 'title' => "ListContractAssociatedProject",
613 'class' => 'Contrat',
614 'table' => 'contrat',
615 'datefieldname' => 'date_contrat',
616 'urlnew' => DOL_URL_ROOT.'/contrat/card.php?action=create&projectid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
617 'lang' => 'contracts',
618 'buttonnew' => 'AddContract',
619 'testnew' => $user->hasRight('contrat', 'creer'),
620 'test' => isModEnabled('contract') && $user->hasRight('contrat', 'lire')
621 ),
622 'intervention' => array(
623 'name' => "Interventions",
624 'title' => "ListFichinterAssociatedProject",
625 'class' => 'Fichinter',
626 'table' => 'fichinter',
627 'datefieldname' => 'date_valid',
628 'disableamount' => 0,
629 'margin' => '',
630 'urlnew' => DOL_URL_ROOT.'/fichinter/card.php?action=create&origin=project&originid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
631 'lang' => 'interventions',
632 'buttonnew' => 'AddIntervention',
633 'testnew' => $user->hasRight('ficheinter', 'creer'),
634 'test' => isModEnabled('intervention') && $user->hasRight('ficheinter', 'lire')
635 ),
636 'shipping' => array(
637 'name' => "Shippings",
638 'title' => "ListShippingAssociatedProject",
639 'class' => 'Expedition',
640 'table' => 'expedition',
641 'datefieldname' => 'date_valid',
642 'urlnew' => DOL_URL_ROOT.'/expedition/card.php?action=create&origin=project&originid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
643 'lang' => 'sendings',
644 'buttonnew' => 'CreateShipment',
645 'testnew' => 0,
646 'test' => isModEnabled('shipping') && $user->hasRight('expedition', 'lire')
647 ),
648 'mrp' => array(
649 'name' => "MO",
650 'title' => "ListMOAssociatedProject",
651 'class' => 'Mo',
652 'table' => 'mrp_mo',
653 'datefieldname' => 'date_valid',
654 'urlnew' => DOL_URL_ROOT.'/mrp/mo_card.php?action=create&origin=project&originid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
655 'lang' => 'mrp',
656 'buttonnew' => 'CreateMO',
657 'testnew' => $user->hasRight('mrp', 'write'),
658 'project_field' => 'fk_project',
659 'nototal' => 1,
660 'test' => isModEnabled('mrp') && $user->hasRight('mrp', 'read')
661 ),
662 'trip' => array(
663 'name' => "TripsAndExpenses",
664 'title' => "ListExpenseReportsAssociatedProject",
665 'class' => 'Deplacement',
666 'table' => 'deplacement',
667 'datefieldname' => 'dated',
668 'margin' => 'minus',
669 'disableamount' => 1,
670 'urlnew' => DOL_URL_ROOT.'/deplacement/card.php?action=create&projectid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
671 'lang' => 'trips',
672 'buttonnew' => 'AddTrip',
673 'testnew' => $user->hasRight('deplacement', 'creer'),
674 'test' => isModEnabled('deplacement') && $user->hasRight('deplacement', 'lire')
675 ),
676 'expensereport' => array(
677 'name' => "ExpenseReports",
678 'title' => "ListExpenseReportsAssociatedProject",
679 'class' => 'ExpenseReportLine',
680 'table' => 'expensereport_det',
681 'datefieldname' => 'date',
682 'margin' => 'minus',
683 'disableamount' => 0,
684 'urlnew' => DOL_URL_ROOT.'/expensereport/card.php?action=create&projectid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
685 'lang' => 'trips',
686 'buttonnew' => 'AddTrip',
687 'testnew' => $user->hasRight('expensereport', 'creer'),
688 'test' => isModEnabled('expensereport') && $user->hasRight('expensereport', 'lire')
689 ),
690 'donation' => array(
691 'name' => "Donation",
692 'title' => "ListDonationsAssociatedProject",
693 'class' => 'Don',
694 'margin' => 'add',
695 'table' => 'don',
696 'datefieldname' => 'datedon',
697 'disableamount' => 0,
698 'urlnew' => DOL_URL_ROOT.'/don/card.php?action=create&projectid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
699 'lang' => 'donations',
700 'buttonnew' => 'AddDonation',
701 'testnew' => $user->hasRight('don', 'creer'),
702 'test' => isModEnabled('don') && $user->hasRight('don', 'lire')
703 ),
704 'loan' => array(
705 'name' => "Loan",
706 'title' => "ListLoanAssociatedProject",
707 'class' => 'Loan',
708 'margin' => '',
709 'table' => 'loan',
710 'datefieldname' => 'datestart',
711 'disableamount' => 0,
712 'urlnew' => DOL_URL_ROOT.'/loan/card.php?action=create&projectid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
713 'lang' => 'loan',
714 'buttonnew' => 'AddLoan',
715 'testnew' => $user->hasRight('loan', 'write'),
716 'test' => isModEnabled('loan') && $user->hasRight('loan', 'read')
717 ),
718 'chargesociales' => array(
719 'name' => "SocialContribution",
720 'title' => "ListSocialContributionAssociatedProject",
721 'class' => 'ChargeSociales',
722 'margin' => 'minus',
723 'table' => 'chargesociales',
724 'datefieldname' => 'date_ech',
725 'disableamount' => 0,
726 'urlnew' => DOL_URL_ROOT.'/compta/sociales/card.php?action=create&projectid='.$id.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
727 'lang' => 'compta',
728 'buttonnew' => 'AddSocialContribution',
729 'testnew' => $user->hasRight('tax', 'charges', 'lire'),
730 'test' => isModEnabled('tax') && $user->hasRight('tax', 'charges', 'lire')
731 ),
732 'project_task' => array(
733 'name' => "TaskTimeSpent",
734 'title' => "ListTaskTimeUserProject",
735 'class' => 'Task',
736 'margin' => 'minus',
737 'table' => 'projet_task',
738 'datefieldname' => 'element_date',
739 'disableamount' => ($canSeeFinancials ? 0 : 1),
740 'urlnew' => DOL_URL_ROOT.'/projet/tasks/time.php?withproject=1&action=createtime&projectid='.$id.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
741 'buttonnew' => 'AddTimeSpent',
742 'testnew' => $user->hasRight('project', 'creer'),
743 'test' => isModEnabled('project') && $user->hasRight('projet', 'lire') && !getDolGlobalString('PROJECT_HIDE_TASKS')
744 ),
745 'stock_mouvement' => array(
746 'name' => "MouvementStockAssociated",
747 'title' => "ListMouvementStockProject",
748 'class' => 'StockTransfer',
749 'table' => 'stocktransfer_stocktransfer',
750 'datefieldname' => 'datem',
751 'margin' => 'minus',
752 'project_field' => 'fk_project',
753 'disableamount' => 0,
754 'test' => isModEnabled('stock') && $user->hasRight('stock', 'mouvement', 'lire') && getDolGlobalString('STOCK_MOVEMENT_INTO_PROJECT_OVERVIEW')
755 ),
756 'salaries' => array(
757 'name' => "Salaries",
758 'title' => "ListSalariesAssociatedProject",
759 'class' => 'Salary',
760 'table' => 'salary',
761 'datefieldname' => 'datesp',
762 'margin' => 'minus',
763 'disableamount' => 0,
764 'urlnew' => DOL_URL_ROOT.'/salaries/card.php?action=create&projectid='.$id.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
765 'lang' => 'salaries',
766 'buttonnew' => 'AddSalary',
767 'testnew' => $user->hasRight('salaries', 'write'),
768 'test' => isModEnabled('salaries') && $user->hasRight('salaries', 'read')
769 ),
770 'variouspayment' => array(
771 'name' => "VariousPayments",
772 'title' => "ListVariousPaymentsAssociatedProject",
773 'class' => 'PaymentVarious',
774 'table' => 'payment_various',
775 'datefieldname' => 'datev',
776 'margin' => 'minus',
777 'disableamount' => 0,
778 'urlnew' => DOL_URL_ROOT.'/compta/bank/various_payment/card.php?action=create&projectid='.$id.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
779 'lang' => 'banks',
780 'buttonnew' => 'AddVariousPayment',
781 'testnew' => $user->hasRight('banque', 'modifier'),
782 'test' => isModEnabled("bank") && $user->hasRight('banque', 'lire') && !getDolGlobalString('BANK_USE_OLD_VARIOUS_PAYMENT')
783 ),
784 /* No need for this, available on dedicated tab "Agenda/Events"
785 'agenda'=>array(
786 'name'=>"Agenda",
787 'title'=>"ListActionsAssociatedProject",
788 'class'=>'ActionComm',
789 'table'=>'actioncomm',
790 'datefieldname'=>'datep',
791 'disableamount'=>1,
792 'urlnew'=>DOL_URL_ROOT.'/comm/action/card.php?action=create&projectid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
793 'lang'=>'agenda',
794 'buttonnew'=>'AddEvent',
795 'testnew'=>$user->rights->agenda->myactions->create,
796 'test'=> isModEnabled('agenda') && $user->hasRight('agenda', 'myactions', 'read')),
797 */
798);
799
800// Change rules for profit/benefit calculation
801if (getDolGlobalString('PROJECT_ELEMENTS_FOR_PLUS_MARGIN')) {
802 foreach ($listofreferent as $key => $element) {
803 if ($listofreferent[$key]['margin'] == 'add') {
804 unset($listofreferent[$key]['margin']);
805 }
806 }
807 $newelementforplusmargin = explode(',', getDolGlobalString('PROJECT_ELEMENTS_FOR_PLUS_MARGIN'));
808 foreach ($newelementforplusmargin as $value) {
809 $listofreferent[trim($value)]['margin'] = 'add';
810 }
811}
812if (getDolGlobalString('PROJECT_ELEMENTS_FOR_MINUS_MARGIN')) {
813 foreach ($listofreferent as $key => $element) {
814 if ($listofreferent[$key]['margin'] == 'minus') {
815 unset($listofreferent[$key]['margin']);
816 }
817 }
818 $newelementforminusmargin = explode(',', getDolGlobalString('PROJECT_ELEMENTS_FOR_MINUS_MARGIN'));
819 foreach ($newelementforminusmargin as $value) {
820 $listofreferent[trim($value)]['margin'] = 'minus';
821 }
822}
823
824
825$parameters = array('listofreferent' => $listofreferent);
826$resHook = $hookmanager->executeHooks('completeListOfReferent', $parameters, $object, $action);
827
828if (!empty($hookmanager->resArray)) {
829 $listofreferent = array_merge($listofreferent, $hookmanager->resArray);
830} elseif ($resHook > 0 && !empty($hookmanager->resPrint)) {
831 $listofreferent = $hookmanager->resPrint;
832}
833
834if ($action == "addelement") {
835 $tablename = GETPOST("tablename", "aZ09");
836 $elementselectid = GETPOSTINT("elementselect");
837 $result = $object->update_element($tablename, $elementselectid);
838 if ($result < 0) {
839 setEventMessages($object->error, $object->errors, 'errors');
840 }
841} elseif ($action == "unlink") {
842 $tablename = GETPOST("tablename", "aZ09");
843 $projectField = GETPOSTISSET('projectfield') ? GETPOST('projectfield', 'aZ09') : 'fk_projet';
844 $elementselectid = GETPOSTINT("elementselect");
845
846 $result = $object->remove_element($tablename, $elementselectid, $projectField);
847 if ($result < 0) {
848 setEventMessages($object->error, $object->errors, 'errors');
849 }
850}
851
852$elementuser = new User($db);
853
854
855
856$showdatefilter = 0;
857// Show the filter on date on top of element list
858if (!$showdatefilter) {
859 print '<div class="center centpercent">';
860 print '<form action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="POST">';
861 print '<input type="hidden" name="token" value="'.newToken().'">';
862 print '<input type="hidden" name="tablename" value="'.(empty($tablename) ? '' : $tablename).'">';
863 print '<input type="hidden" name="action" value="view">';
864 print '<div class="inline-block">';
865 print $form->selectDate($dates, 'dates', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From"));
866 print '</div>';
867 print '<div class="inline-block">';
868 print $form->selectDate($datee, 'datee', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to"));
869 print '</div>';
870 print '<div class="inline-block">';
871 print '<input type="submit" name="refresh" value="'.$langs->trans("Refresh").'" class="button small">';
872 print '</div>';
873 print '</form>';
874 print '</div>';
875
876 $showdatefilter++;
877}
878
879
880
881// Show balance for whole project
882
883$langs->loadLangs(array("suppliers", "bills", "orders", "proposals", "margins"));
884
885if (isModEnabled('stock')) {
886 $langs->load('stocks');
887}
888
889print '<!-- Begin PROFIT table -->';
890print load_fiche_titre($langs->trans("Profit"), '', 'title_accountancy');
891
892print '<div class="div-table-responsive">';
893print '<table class="noborder centpercent">';
894print '<tr class="liste_titre">';
895print '<td class="left" width="200">';
896$tooltiponprofit = $langs->trans("ProfitIsCalculatedWith")."<br>\n";
897$tooltiponprofitplus = $tooltiponprofitminus = '';
898foreach ($listofreferent as $key => $value) {
899 if (!empty($value['lang'])) {
900 $langs->load($value['lang']);
901 }
902 $name = $langs->trans($value['name']);
903 $qualified = $value['test'];
904 $margin = empty($value['margin']) ? '' : $value['margin'];
905 if ($qualified && $margin) { // If this element must be included into profit calculation ($margin is 'minus' or 'add')
906 if ($margin === 'add') {
907 $tooltiponprofitplus .= ' &gt; '.$name." (+)<br>\n";
908 } elseif ($margin === 'minus') {
909 $tooltiponprofitminus .= ' &gt; '.$name." (-)<br>\n";
910 }
911 }
912}
913$tooltiponprofit .= $tooltiponprofitplus;
914$tooltiponprofit .= $tooltiponprofitminus;
915print $form->textwithpicto($langs->trans("Element"), $tooltiponprofit);
916print '</td>';
917print '<td class="right" width="100">'.$langs->trans("Number").'</td>';
918print '<td class="right" width="100">'.$langs->trans("AmountHT").'</td>';
919print '<td class="right" width="100">'.$langs->trans("AmountTTC").'</td>';
920print '</tr>';
921
922$total_revenue_ht = 0;
923$balance_ht = 0;
924$balance_ttc = 0;
925
926// Loop on each element type (proposal, sale order, invoices, ...)
927foreach ($listofreferent as $key => $value) {
928 $parameters = array(
929 'total_revenue_ht' => & $total_revenue_ht,
930 'balance_ht' => & $balance_ht,
931 'balance_ttc' => & $balance_ttc,
932 'key' => $key,
933 'value' => & $value,
934 'dates' => $dates,
935 'datee' => $datee
936 );
937 $reshook = $hookmanager->executeHooks('printOverviewProfit', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
938 if ($reshook < 0) {
939 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
940 } elseif ($reshook > 0) {
941 print $hookmanager->resPrint;
942 continue;
943 }
944
945 $name = $langs->trans($value['name']);
946 $title = $value['title'];
947 $classname = $value['class'];
948 $tablename = $value['table'];
949 $datefieldname = $value['datefieldname'];
950 $qualified = $value['test'];
951 // Hide project_task amounts in profit section for users without financial access
952 if ($key === 'project_task' && !$canSeeFinancials) {
953 $qualified = false;
954 }
955 $margin = empty($value['margin']) ? 0 : $value['margin'];
956 $project_field = empty($value['project_field']) ? '' : $value['project_field'];
957 if ($qualified) { // If this element must be included into profit summary table ($margin is '', 'minus' or 'add')
958 $element = new $classname($db);
959
960 $elementarray = $object->get_element_list($key, $tablename, $datefieldname, $dates, $datee, !empty($project_field) ? $project_field : 'fk_projet');
961
962 if (is_array($elementarray) && count($elementarray) > 0) {
963 $total_ht = 0;
964 $total_ttc = 0;
965 $i = 0;
966
967 // Loop on each object for the current element type
968 $num = count($elementarray);
969 for ($i = 0; $i < $num; $i++) {
970 $tmp = explode('_', $elementarray[$i]);
971 $idofelement = (int) $tmp[0];
972 $idofelementuser = !empty($tmp[1]) ? (int) $tmp[1] : 0;
973
974 $element->fetch($idofelement);
975 if ($idofelementuser) {
976 $elementuser->fetch($idofelementuser);
977 }
978
979 // Define if record must be used for total or not
980 $qualifiedfortotal = true;
981 if ($key == 'invoice') {
982 if (!empty($element->close_code) && $element->close_code == 'replaced') {
983 $qualifiedfortotal = false; // Replacement invoice, do not include into total
984 }
985 if (getDolGlobalString('FACTURE_DEPOSITS_ARE_JUST_PAYMENTS') && $element->type == Facture::TYPE_DEPOSIT) {
986 $qualifiedfortotal = false; // If hidden option to use deposits as payment (deprecated, not recommended to use this), deposits are not included
987 }
988 }
989 if ($key == 'propal') {
990 if ($element->status != Propal::STATUS_SIGNED && $element->status != Propal::STATUS_BILLED) {
991 $qualifiedfortotal = false; // Only signed proposal must not be included in total
992 }
993 }
994
995 if ($tablename != 'expensereport_det' && method_exists($element, 'fetch_thirdparty')) {
996 $element->fetch_thirdparty();
997 }
998
999 // Define $total_ht_by_line
1000 if ($tablename == 'don' || $tablename == 'chargesociales' || $tablename == 'payment_various' || $tablename == 'salary') {
1001 '@phan-var-force ChargeSociales|PaymentVarious|Salary $element';
1002 $total_ht_by_line = $element->amount;
1003 } elseif ($tablename == 'fichinter') {
1004 '@phan-var-force Fichinter $element';
1005 $total_ht_by_line = $element->getAmount();
1006 } elseif ($tablename == 'stock_mouvement') {
1007 '@phan-var-force MouvementStock $element';
1008 $total_ht_by_line = $element->price * abs($element->qty);
1009 } elseif ($tablename == 'projet_task') {
1010 '@phan-var-force Task $element';
1011 $tmp = $element->getSumOfAmount($idofelementuser ? $elementuser : '', (string) $dates, (string) $datee);
1012 $total_ht_by_line = price2num($tmp['amount'], 'MT');
1013 } elseif ($key == 'loan') {
1014 '@phan-var-force Loan $element';
1015 if ((empty($dates) && empty($datee)) || (intval($dates) <= $element->datestart && intval($datee) >= $element->dateend)) {
1016 // Get total loan
1017 $total_ht_by_line = -$element->capital;
1018 } else {
1019 // Get loan schedule according to date filter
1020 $total_ht_by_line = 0;
1021 $loanScheduleStatic = new LoanSchedule($element->db);
1022 $loanScheduleStatic->fetchAll($element->id);
1023 if (!empty($loanScheduleStatic->lines)) {
1024 foreach ($loanScheduleStatic->lines as $loanSchedule) {
1028 if (($loanSchedule->datep >= $dates && $loanSchedule->datep <= $datee) // dates filter is defined
1029 || !empty($dates) && empty($datee) && $loanSchedule->datep >= $dates && $loanSchedule->datep <= dol_now()
1030 || empty($dates) && !empty($datee) && $loanSchedule->datep <= $datee
1031 ) {
1032 $total_ht_by_line -= $loanSchedule->amount_capital;
1033 }
1034 }
1035 }
1036 }
1037 } else {
1038 $total_ht_by_line = $element->total_ht;
1039 }
1040
1041 // Define $total_ttc_by_line
1042 if ($tablename == 'don' || $tablename == 'chargesociales' || $tablename == 'payment_various' || $tablename == 'salary') {
1043 '@phan-var-force ChargeSociales|PaymentVarious|Salary $element';
1044 $total_ttc_by_line = $element->amount;
1045 } elseif ($tablename == 'fichinter') {
1046 '@phan-var-force Fichinter $element';
1047 $total_ttc_by_line = $element->getAmount();
1048 } elseif ($tablename == 'stock_mouvement') {
1049 '@phan-var-force MouvementStock $element';
1050 $total_ttc_by_line = $element->price * abs($element->qty);
1051 } elseif ($tablename == 'projet_task') {
1052 '@phan-var-force Task $element';
1053 $defaultvat = get_default_tva($mysoc, $mysoc);
1054 $reg = array();
1055 if (preg_replace('/^(\d+\.)\s\‍(.*\‍)/', $defaultvat, $reg)) {
1056 // @phan-suppress-next-line PhanTypeInvalidDimOffset
1057 $defaultvat = $reg[1];
1058 }
1059 $total_ttc_by_line = price2num($total_ht_by_line * (1 + ((float) $defaultvat / 100)), 'MT');
1060 } elseif ($key == 'loan') {
1061 $total_ttc_by_line = $total_ht_by_line; // For loan there is actually no taxe managed in Dolibarr
1062 } else {
1063 $total_ttc_by_line = $element->total_ttc;
1064 }
1065
1066 // Change sign of $total_ht_by_line and $total_ttc_by_line for various payments
1067 if ($tablename == 'payment_various') {
1068 if ($element->sens == 1) {
1069 $total_ht_by_line = -$total_ht_by_line;
1070 $total_ttc_by_line = -$total_ttc_by_line;
1071 }
1072 }
1073
1074 // Change sign of $total_ht_by_line and $total_ttc_by_line for supplier proposal and supplier order.
1075 // Skip when the element already participates to the margin computation via margin='minus'
1076 // (line 1095 below will revert sign too, and double-negation would silently flip the value
1077 // back to positive - see PROJECT_ELEMENTS_FOR_MINUS_MARGIN=order_supplier in #34684).
1078 if (($tablename == 'commande_fournisseur' || $tablename == 'supplier_proposal') && $margin !== 'minus') {
1079 $total_ht_by_line = -$total_ht_by_line;
1080 $total_ttc_by_line = -$total_ttc_by_line;
1081 }
1082
1083 // Add total if we have to
1084 if ($qualifiedfortotal) {
1085 $total_ht += $total_ht_by_line;
1086 $total_ttc += $total_ttc_by_line;
1087 }
1088 }
1089
1090 // Each element with at least one line is output
1091
1092 // Calculate margin
1093 if ($margin) {
1094 if ($margin === 'add') {
1095 $total_revenue_ht += $total_ht;
1096 }
1097
1098 if ($margin === "minus") { // Revert sign
1099 $total_ht = -$total_ht;
1100 $total_ttc = -$total_ttc;
1101 }
1102
1103 $balance_ht += $total_ht;
1104 $balance_ttc += $total_ttc;
1105 }
1106
1107 print '<tr class="oddeven">';
1108 // Module
1109 print '<!-- // Module '.$name.' with tablename '.$tablename.' -->';
1110 print '<td class="left"><a href="#table_'.$tablename.'">'.$name.'</a></td>';
1111 // Nb
1112 print '<td class="right">'.$i.'</td>';
1113 // Amount HT
1114 print '<td class="right">';
1115 if ($key == 'intervention' && !$margin) {
1116 print '<span class="opacitymedium">'.$form->textwithpicto($langs->trans("NA"), $langs->trans("AmountOfInteventionNotIncludedByDefault")).'</span>';
1117 } else {
1118 if ($key == 'propal') {
1119 print '<span class="opacitymedium">'.$form->textwithpicto('', $langs->trans("SignedOnly")).'</span>';
1120 }
1121 print price($total_ht);
1122 }
1123 print '</td>';
1124 // Amount TTC
1125 print '<td class="right">';
1126 if ($key == 'intervention' && !$margin) {
1127 print '<span class="opacitymedium">'.$form->textwithpicto($langs->trans("NA"), $langs->trans("AmountOfInteventionNotIncludedByDefault")).'</span>';
1128 } else {
1129 if ($key == 'propal') {
1130 print '<span class="opacitymedium">'.$form->textwithpicto('', $langs->trans("SignedOnly")).'</span>';
1131 }
1132 print price($total_ttc);
1133 }
1134 print '</td>';
1135 print '</tr>';
1136 }
1137 }
1138}
1139// and the final balance
1140print '<tr class="liste_total">';
1141print '<td class="right" colspan="2">'.$langs->trans("Profit").'</td>';
1142print '<td class="right">'.price(price2num($balance_ht, 'MT')).'</td>';
1143print '<td class="right">'.price(price2num($balance_ttc, 'MT')).'</td>';
1144print '</tr>';
1145
1146// and the cost per attendee
1147if ($object->usage_organize_event) {
1148 require_once DOL_DOCUMENT_ROOT.'/eventorganization/class/conferenceorboothattendee.class.php';
1149 $conforboothattendee = new ConferenceOrBoothAttendee($db);
1150 $result = $conforboothattendee->fetchAll('', '', 0, 0, '(t.fk_project:=:'.((int) $object->id).') AND (t.status:=:'.ConferenceOrBoothAttendee::STATUS_VALIDATED.')');
1151
1152 if (!is_array($result) && $result < 0) {
1153 setEventMessages($conforboothattendee->error, $conforboothattendee->errors, 'errors');
1154 } else {
1155 $nbAttendees = count($result);
1156 }
1157
1158 if ($nbAttendees >= 2) {
1159 $costperattendee_ht = $balance_ht / $nbAttendees;
1160 $costperattendee_ttc = $balance_ttc / $nbAttendees;
1161 print '<tr class="liste_total">';
1162 print '<td class="right" colspan="2">'.$langs->trans("ProfitPerValidatedAttendee").'</td>';
1163 print '<td class="right">'.price(price2num($costperattendee_ht, 'MT')).'</td>';
1164 print '<td class="right">'.price(price2num($costperattendee_ttc, 'MT')).'</td>';
1165 print '</tr>';
1166 }
1167}
1168
1169// and the margin (profit / revenues)
1170if ($total_revenue_ht) {
1171 print '<tr class="liste_total">';
1172 print '<td class="right" colspan="2">'.$langs->trans("Margin").'</td>';
1173 print '<td class="right">'.round(100 * $balance_ht / $total_revenue_ht, 1).'%</td>';
1174 print '<td class="right"></td>';
1175 print '</tr>';
1176}
1177
1178print "</table>";
1179print '</div>';
1180print '<!-- End PROFIT table -->';
1181
1182
1183print '<br><br>';
1184print '<br>';
1185
1186
1187$total_time = 0;
1188
1189// Detail
1190foreach ($listofreferent as $key => $value) {
1191 $parameters = array(
1192 'key' => $key,
1193 'value' => & $value,
1194 'dates' => $dates,
1195 'datee' => $datee
1196 );
1197 $reshook = $hookmanager->executeHooks('printOverviewDetail', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1198 if ($reshook < 0) {
1199 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1200 } elseif ($reshook > 0) {
1201 print $hookmanager->resPrint;
1202 continue;
1203 }
1204
1205 $title = $value['title'];
1206 $classname = $value['class'];
1207 $tablename = $value['table'];
1208 $datefieldname = $value['datefieldname'];
1209 $qualified = $value['test'];
1210 $urlnew = empty($value['urlnew']) ? '' : $value['urlnew'];
1211 $buttonnew = empty($value['buttonnew']) ? '' : $value['buttonnew'];
1212 $testnew = empty($value['testnew']) ? '' : $value['testnew'];
1213 $project_field = empty($value['project_field']) ? '' : $value['project_field'];
1214 $nototal = empty($value['nototal']) ? 0 : 1;
1215
1216 $exclude_select_element = array('payment_various');
1217 if (!empty($value['exclude_select_element'])) {
1218 $exclude_select_element[] = $value['exclude_select_element'];
1219 }
1220
1221 if ($qualified && $tablename !== null) {
1222 // If we want the project task array to have details of users
1223 //if ($key == 'project_task') $key = 'project_task_time';
1224
1225 $element = new $classname($db);
1226
1227 $addform = '';
1228
1229 $idtofilterthirdparty = 0;
1230 $array_of_element_linkable_with_different_thirdparty = array('facture_fourn', 'commande_fournisseur');
1231 if (!in_array($tablename, $array_of_element_linkable_with_different_thirdparty)) {
1232 $idtofilterthirdparty = empty($object->thirdparty->id) ? 0 : $object->thirdparty->id;
1233 if (getDolGlobalString('PROJECT_OTHER_THIRDPARTY_ID_TO_ADD_ELEMENTS')) {
1234 $idtofilterthirdparty .= ',' . getDolGlobalString('PROJECT_OTHER_THIRDPARTY_ID_TO_ADD_ELEMENTS');
1235 }
1236 }
1237
1238 $elementarray = $object->get_element_list($key, $tablename, $datefieldname, $dates, $datee, !empty($project_field) ? $project_field : 'fk_projet');
1239
1240
1241 if (!getDolGlobalString('PROJECT_LINK_ON_OVERWIEW_DISABLED') && $idtofilterthirdparty && !in_array($tablename, $exclude_select_element)) {
1242 $selectList = $formproject->select_element($tablename, $idtofilterthirdparty, 'minwidth300 minwidth75imp', -2, empty($project_field) ? 'fk_projet' : $project_field, $langs->trans("SelectElement"));
1243 if ((int) $selectList < 0) { // cast to int because ''<0 is true.
1244 setEventMessages($formproject->error, $formproject->errors, 'errors');
1245 } elseif ($selectList) {
1246 // Define form with the combo list of elements to link
1247 $addform .= '<div class="inline-block valignmiddle">';
1248 $addform .= '<form action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
1249 $addform .= '<input type="hidden" name="token" value="'.newToken().'">';
1250 $addform .= '<input type="hidden" name="tablename" value="'.$tablename.'">';
1251 $addform .= '<input type="hidden" name="action" value="addelement">';
1252 $addform .= '<input type="hidden" name="datesrfc" value="'.dol_print_date($dates, 'dayhourrfc').'">';
1253 $addform .= '<input type="hidden" name="dateerfc" value="'.dol_print_date($datee, 'dayhourrfc').'">';
1254 $addform .= '<table><tr>';
1255 //$addform .= '<td><span class="hideonsmartphone opacitymedium">'.$langs->trans("SelectElement").'</span></td>';
1256 $addform .= '<td>'.$selectList.'</td>';
1257 $addform .= '<td><input type="submit" class="button button-linkto smallpaddingimp" value="'.dol_escape_htmltag($langs->trans("LinkToElementShort")).'"></td>';
1258 $addform .= '</tr></table>';
1259 $addform .= '</form>';
1260 $addform .= '</div>';
1261 }
1262 }
1263 if (!getDolGlobalString('PROJECT_CREATE_ON_OVERVIEW_DISABLED') && $urlnew) {
1264 $addform .= '<div class="inline-block valignmiddle">';
1265 if ($testnew) {
1266 $addform .= '<a class="buttonxxx marginleftonly" href="'.$urlnew.'" title="'.dol_escape_htmltag($langs->trans($buttonnew)).'"><span class="fa fa-plus-circle valignmiddle paddingleft"></span></a>';
1267 } elseif (!getDolGlobalString('MAIN_BUTTON_HIDE_UNAUTHORIZED')) {
1268 $addform .= '<span title="'.dol_escape_htmltag($langs->trans($buttonnew)).'"><a class="buttonxxx marginleftonly buttonRefused" disabled="disabled" href="#"><span class="fa fa-plus-circle valignmiddle paddingleft"></span></a></span>';
1269 }
1270 $addform .= '<div>';
1271 }
1272
1273 if (is_array($elementarray) && count($elementarray) > 0 && $key == "order_supplier") {
1274 $addform .= '<div class="inline-block valignmiddle"><a id="btnShow" class="buttonxxx marginleftonly" href="#" onClick="return false;">
1275 <span id="textBtnShow" class="valignmiddle text-plus-circle hideonsmartphone">'.$langs->trans("CanceledShown").'</span><span id="minus-circle" class="fa fa-eye valignmiddle paddingleft"></span>
1276 </a>
1277 <script>
1278 $("#btnShow").on("click", function () {
1279 console.log("We click to show or hide the canceled lines");
1280 var attr = $(this).attr("data-canceledarehidden");
1281 if (typeof attr !== "undefined" && attr !== false) {
1282 console.log("Show canceled");
1283 $(".tr_canceled").show();
1284 $("#textBtnShow").text("'.dol_escape_js($langs->transnoentitiesnoconv("CanceledShown")).'");
1285 $("#btnShow").removeAttr("data-canceledarehidden");
1286 $("#minus-circle").removeClass("fa-eye-slash").addClass("fa-eye");
1287 } else {
1288 console.log("Hide canceled");
1289 $(".tr_canceled").hide();
1290 $("#textBtnShow").text("'.dol_escape_js($langs->transnoentitiesnoconv("CanceledHidden")).'");
1291 $("#btnShow").attr("data-canceledarehidden", 1);
1292 $("#minus-circle").removeClass("fa-eye").addClass("fa-eye-slash");
1293 }
1294 });
1295 </script></div>';
1296
1297 $addform .= '<div class="inline-block valignmiddle"><a id="btnShowPaid" class="buttonxxx marginleftonly" href="#" onClick="return false;">
1298 <span id="textBtnShowPaid" class="valignmiddle text-plus-circle hideonsmartphone">'.$langs->trans("PaidShown").'</span><span id="minus-circle-paid" class="fa fa-eye valignmiddle paddingleft"></span>
1299 </a>
1300 <script>
1301 $("#btnShowPaid").on("click", function () {
1302 console.log("We click to show or hide the paid lines");
1303 var attr = $(this).attr("data-paidarehidden");
1304 if (typeof attr !== "undefined" && attr !== false) {
1305 console.log("Show paid");
1306 $(".tr_paid").show();
1307 $("#textBtnShowPaid").text("'.dol_escape_js($langs->transnoentitiesnoconv("PaidShown")).'");
1308 $("#btnShowPaid").removeAttr("data-paidarehidden");
1309 $("#minus-circle-paid").removeClass("fa-eye-slash").addClass("fa-eye");
1310 } else {
1311 console.log("Hide paid");
1312 $(".tr_paid").hide();
1313 $("#textBtnShowPaid").text("'.dol_escape_js($langs->transnoentitiesnoconv("PaidHidden")).'");
1314 $("#btnShowPaid").attr("data-paidarehidden", 1);
1315 $("#minus-circle-paid").removeClass("fa-eye").addClass("fa-eye-slash");
1316 }
1317 });
1318 </script></div>';
1319 }
1320
1321 print '<a id="table_'.$tablename.'"></a>';
1322 print load_fiche_titre($langs->trans($title), $addform, '');
1323
1324 print "\n".'<!-- Table for tablename = '.$tablename.' -->'."\n";
1325 print '<div class="div-table-responsive">';
1326 print '<table class="noborder centpercent">';
1327
1328 print '<tr class="liste_titre">';
1329 // Remove link column
1330 print '<td style="width: 24px"></td>';
1331 // Ref
1332 print '<td'.(($tablename != 'actioncomm' && $tablename != 'projet_task') ? ' style="width: 200px"' : '').'>'.$langs->trans("Ref").'</td>';
1333 // Product and qty on stock_movement
1334 if ('MouvementStock' == $classname) {
1335 print '<td style="width: 200px">'.$langs->trans("Product").'</td>';
1336 print '<td style="width: 50px">'.$langs->trans("Qty").'</td>';
1337 }
1338 // Date
1339 print '<td'.(($tablename != 'actioncomm' && $tablename != 'projet_task') ? ' style="width: 200px"' : '').' class="center">';
1340 if (in_array($tablename, array('projet_task'))) {
1341 print $langs->trans("TimeSpent");
1342 }
1343 if (!in_array($tablename, array('projet_task'))) {
1344 print $langs->trans("Date");
1345 }
1346 print '</td>';
1347 // Thirdparty or user
1348 print '<td>';
1349 if (in_array($tablename, array('projet_task')) && $key == 'project_task') {
1350 print ''; // if $key == 'project_task', we don't want details per user
1351 } elseif (in_array($tablename, array('payment_various'))) {
1352 print $langs->trans("Label"); // complementary info about the payment
1353 } elseif (in_array($tablename, array('expensereport_det', 'don', 'projet_task', 'stock_mouvement', 'salary'))) {
1354 print $langs->trans("User");
1355 } else {
1356 print $langs->trans("ThirdParty");
1357 }
1358 print '</td>';
1359 // Duration of intervention
1360 if ($tablename == 'fichinter') {
1361 print '<td>';
1362 print $langs->trans("TotalDuration");
1363 $total_duration = 0;
1364 print '</td>';
1365 }
1366 // Type from Expense Report
1367 if ($tablename == 'expensereport_det') {
1368 print '<td id="expensereport_type">';
1369 print $langs->trans("Type");
1370 print '</td>';
1371 }
1372 // Description from Expense Report
1373 if ($tablename == 'expensereport_det') {
1374 print '<td id="expensereport_description">';
1375 print $langs->trans("Description");
1376 print '</td>';
1377 }
1378
1379
1380 // Amount HT
1381 //if (empty($value['disableamount']) && ! in_array($tablename, array('projet_task'))) print '<td class="right" width="120">'.$langs->trans("AmountHT").'</td>';
1382 //elseif (empty($value['disableamount']) && in_array($tablename, array('projet_task'))) print '<td class="right" width="120">'.$langs->trans("Amount").'</td>';
1383 if ($key == 'loan') {
1384 print '<td class="right" width="120">'.$langs->trans("LoanCapital").'</td>';
1385 } elseif (empty($value['disableamount'])) {
1386 print '<td class="right" width="120">'.$langs->trans("AmountHT").'</td>';
1387 } else {
1388 print '<td width="120"></td>';
1389 }
1390 // Amount TTC
1391 //if (empty($value['disableamount']) && ! in_array($tablename, array('projet_task'))) print '<td class="right" width="120">'.$langs->trans("AmountTTC").'</td>';
1392 if ($key == 'loan') {
1393 print '<td class="right" width="120">'.$langs->trans("RemainderToPay").'</td>';
1394 } elseif (empty($value['disableamount'])) {
1395 print '<td class="right" width="120">'.$langs->trans("AmountTTC").'</td>';
1396 } else {
1397 print '<td width="120"></td>';
1398 }
1399 // Status
1400 if (in_array($tablename, array('projet_task'))) {
1401 print '<td class="right" width="200">'.$langs->trans("ProgressDeclared").'</td>';
1402 } else {
1403 print '<td class="right" width="200">'.$langs->trans("Status").'</td>';
1404 }
1405 print '</tr>';
1406
1407 if (is_array($elementarray) && count($elementarray) > 0) {
1408 $total_ht = 0;
1409 $total_ttc = 0;
1410 $i = 0;
1411
1412 $total_ht_by_third = 0;
1413 $total_ttc_by_third = 0;
1414
1415 $saved_third_id = 0;
1416 $breakline = '';
1417
1418 if (canApplySubtotalOn($tablename)) {
1419 // Sort
1420 $elementarray = sortElementsByClientName($elementarray);
1421 }
1422
1423 $num = count($elementarray);
1424 $total_time = 0;
1425 for ($i = 0; $i < $num; $i++) {
1426 $tmp = explode('_', $elementarray[$i]);
1427 $idofelement = (int) $tmp[0];
1428 $idofelementuser = isset($tmp[1]) ? (int) $tmp[1] : 0;
1429
1430 $element->fetch($idofelement);
1431 if ($idofelementuser) {
1432 $elementuser->fetch($idofelementuser);
1433 }
1434
1435 // Special cases
1436 if ($tablename != 'expensereport_det') {
1437 if (method_exists($element, 'fetch_thirdparty')) {
1438 $element->fetch_thirdparty();
1439 }
1440 } else {
1441 $expensereport = new ExpenseReport($db);
1442 $expensereport->fetch($element->fk_expensereport);
1443 }
1444
1445 //print 'xxx'.$tablename.'yyy'.$classname;
1446
1447 if ($breakline && $saved_third_id != $element->thirdparty->id) {
1448 print $breakline;
1449
1450 $saved_third_id = $element->thirdparty->id;
1451 $breakline = '';
1452
1453 $total_ht_by_third = 0;
1454 $total_ttc_by_third = 0;
1455 }
1456
1457 $saved_third_id = empty($element->thirdparty->id) ? 0 : $element->thirdparty->id;
1458
1459 $qualifiedfortotal = true;
1460 if ($key == 'invoice') {
1461 if (!empty($element->close_code) && $element->close_code == 'replaced') {
1462 $qualifiedfortotal = false; // Replacement invoice, do not include into total
1463 }
1464 } elseif ($key == 'order_supplier' && ($element->status == 6 || $element->status == 7)) {
1465 $qualifiedfortotal = false; // It makes no sense to include canceled orders in the total
1466 }
1467
1468 if ($key == "order_supplier" && ($element->status == 6 || $element->status == 7)) {
1469 print '<tr class="oddeven tr_canceled">';
1470 } elseif ($key == "order_supplier" && ($element->billed)) {
1471 print '<tr class="oddeven tr_paid">';
1472 } else {
1473 print '<tr class="oddeven" >';
1474 }
1475
1476
1477 // Remove link
1478 print '<td style="width: 24px">';
1479 if ($tablename != 'projet_task' && $tablename != 'stock_mouvement') {
1480 if (!getDolGlobalString('PROJECT_DISABLE_UNLINK_FROM_OVERVIEW') || $user->admin) { // PROJECT_DISABLE_UNLINK_FROM_OVERVIEW is empty by default, so this test true
1481 print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=unlink&tablename='.$tablename.'&elementselect='.$element->id.($project_field ? '&projectfield='.$project_field : '').'" class="reposition">';
1482 print img_picto($langs->trans('Unlink'), 'unlink');
1483 print '</a>';
1484 }
1485 }
1486 print "</td>\n";
1487
1488 // Ref
1489 print '<td class="left nowraponall">';
1490 if ($tablename == 'expensereport_det') {
1491 print $expensereport->getNomUrl(1);
1492 } else {
1493 print '<table><tr><td style="border-bottom: none;">';
1494 // Show ref with link
1495 if ($element instanceof Task) {
1496 print $element->getNomUrl(1, 'withproject', 'time');
1497 print ' - '.dol_trunc($element->label, 48);
1498 } elseif ($key == 'loan') {
1499 print $element->getNomUrl(1);
1500 print ' - '.dol_trunc($element->label, 48);
1501 } else {
1502 print $element->getNomUrl(1);
1503 }
1504
1505 $element_doc = $element->element;
1506 $filename = dol_sanitizeFileName($element->ref);
1507 if (!empty($conf->$element_doc)) {
1508 $confelementdoc = $conf->$element_doc;
1509 $filedir = $confelementdoc->multidir_output[$element->entity ?? $conf->entity].'/'.dol_sanitizeFileName($element->ref);
1510 } else {
1511 $filedir = '';
1512 }
1513
1514 if ($element_doc === 'order_supplier') {
1515 $element_doc = 'commande_fournisseur';
1516 $filedir = $conf->fournisseur->commande->multidir_output[$element->entity ?? $conf->entity].'/'.dol_sanitizeFileName($element->ref);
1517 } elseif ($element_doc === 'invoice_supplier') {
1518 $element_doc = 'facture_fournisseur';
1519 $filename = get_exdir($element->id, 2, 0, 0, $element, 'invoice_supplier').dol_sanitizeFileName($element->ref);
1520 $filedir = $conf->fournisseur->facture->multidir_output[$element->entity ?? $conf->entity].'/'.$filename;
1521 }
1522
1523 print '<div class="inline-block valignmiddle">';
1524 if ($filedir) {
1525 print $formfile->getDocumentsLink($element_doc, $filename, $filedir);
1526 }
1527 print '</div>';
1528
1529 print '</td>';
1530
1531 print '<td class="tdoverflowmax250" style="border-bottom: none;">';
1532
1533 // Show supplier ref
1534 if (!empty($element->ref_supplier)) {
1535 print ' - '.$element->ref_supplier;
1536 }
1537 // Show customer ref
1538 if (!empty($element->ref_customer)) {
1539 print ' - '.$element->ref_customer;
1540 }
1541 // Compatibility propale
1542 if (empty($element->ref_customer) && !empty($element->ref_client)) {
1543 print ' - '.$element->ref_client;
1544 }
1545
1546 print '</td></tr></table>';
1547 }
1548 print "</td>\n";
1549 // Product and qty on stock movement
1550 if ('MouvementStock' == $classname) {
1551 '@phan-var-force MouvementStock $element';
1552 $mvsProd = new Product($element->db);
1553 $mvsProd->fetch($element->product_id);
1554 print '<td>'.$mvsProd->getNomUrl(1).'</td>';
1555 print '<td>'.$element->qty.'</td>';
1556 }
1557 // Date or TimeSpent
1558 $date = '';
1559 $total_time_by_line = 0;
1560 if ($tablename == 'expensereport_det') {
1561 '@phan-var-force ExpenseReportLine $element';
1562 $date = $element->date; // No draft status on lines
1563 } elseif ($tablename == 'stock_mouvement') {
1564 '@phan-var-force MouvementStock $element';
1565 $date = $element->datem;
1566 } elseif ($tablename == 'salary') {
1567 '@phan-var-force Salary $element';
1568 $date = $element->datesp;
1569 } elseif ($tablename == 'payment_various') {
1570 '@phan-var-force PaymentVarious $element';
1571 $date = $element->datev;
1572 } elseif ($tablename == 'chargesociales') {
1573 '@phan-var-force ChargeSociales $element';
1574 $date = $element->date_ech;
1575 } elseif (!empty($element->status) || !empty($element->statut) || !empty($element->fk_status)) {
1576 if ($tablename == 'don') {
1577 '@phan-var-force Don $element';
1578 $date = $element->date;
1579 }
1580 if ($tablename == 'commande_fournisseur' || $tablename == 'supplier_order') {
1581 '@phan-var-force CommandeFournisseur $element';
1582 $date = ($element->date_commande ? $element->date_commande : $element->date_valid);
1583 } elseif ($tablename == 'supplier_proposal') {
1584 '@phan-var-force SupplierProposal $element';
1585 $date = $element->date_validation; // There is no other date for this
1586 } elseif ($tablename == 'fichinter') {
1587 '@phan-var-force Fichinter $element';
1588 $date = $element->datev; // There is no other date for this
1589 } elseif ($tablename == 'projet_task') {
1590 '@phan-var-force Task $element';
1591 $date = ''; // We show no date. Showing date of beginning of task make user think it is date of time consumed
1592 } else {
1593 $date = $element->date; // invoice, ...
1594 if (empty($date)) {
1595 $date = $element->date_contrat;
1596 }
1597 if (empty($date)) {
1598 $date = $element->datev;
1599 }
1600 if (empty($date) && !empty($datefieldname)) {
1601 // @phan-suppress-next-line PhanUndeclaredProperty
1602 $date = $element->$datefieldname;
1603 }
1604 }
1605 } elseif ($key == 'loan') {
1606 '@phan-var-force Loan $element';
1607 $date = $element->datestart;
1608 }
1609
1610 print '<td class="center">';
1611 if ($tablename == 'actioncomm') {
1612 '@phan-var-force ActionComm $element';
1613 print dol_print_date($element->datep, 'dayhour');
1614 if ($element->datef && $element->datef > $element->datep) {
1615 print " - ".dol_print_date($element->datef, 'dayhour');
1616 }
1617 } elseif (in_array($tablename, array('projet_task'))) {
1618 '@phan-var-force Task $element';
1619 $tmpprojtime = $element->getSumOfAmount($idofelementuser ? $elementuser : '', (string) $dates, (string) $datee); // $element is a task. $elementuser may be empty
1620 print '<a href="'.DOL_URL_ROOT.'/projet/tasks/time.php?id='.$idofelement.'&withproject=1">';
1621 print convertSecondToTime($tmpprojtime['nbseconds'], 'allhourmin');
1622 print '</a>';
1623 $total_time_by_line = $tmpprojtime['nbseconds'];
1624 } else {
1625 print dol_print_date($date, 'day');
1626 }
1627 print '</td>';
1628
1629 // Third party or user
1630 print '<td class="tdoverflowmax150">';
1631 if (is_object($element->thirdparty)) {
1632 print $element->thirdparty->getNomUrl(1, '', 48);
1633 } elseif ($tablename == 'expensereport_det') {
1634 $tmpuser = new User($db);
1635 $tmpuser->fetch($expensereport->fk_user_author);
1636 print $tmpuser->getNomUrl(1, '', 48);
1637 } elseif ($tablename == 'salary') {
1638 $tmpuser = new User($db);
1639 $tmpuser->fetch($element->fk_user);
1640 print $tmpuser->getNomUrl(1, '', 48);
1641 } elseif ($tablename == 'don' || $tablename == 'stock_mouvement') {
1642 '@phan-var-force Don|MouvementStock $element';
1643 if ($element->fk_user_author > 0) {
1644 $tmpuser2 = new User($db);
1645 $tmpuser2->fetch($element->fk_user_author);
1646 print $tmpuser2->getNomUrl(1, '', 48);
1647 }
1648 } elseif ($tablename == 'projet_task' && $key == 'element_time') { // if $key == 'project_task', we don't want details per user
1649 print $elementuser->getNomUrl(1);
1650 } elseif ($tablename == 'payment_various') { // payment label
1651 '@phan-var-force PaymentVarious $element';
1652 print $element->label;
1653 }
1654 print '</td>';
1655
1656 // Add duration and store it in counter for fichinter
1657 if ($tablename == 'fichinter') {
1658 '@phan-var-force FichInter $element';
1659 print '<td>';
1660 print convertSecondToTime($element->duration, 'all', $conf->global->MAIN_DURATION_OF_WORKDAY);
1661 $total_duration += $element->duration;
1662 print '</td>';
1663 }
1664
1665 // Type from Expense Report
1666 if ($tablename == 'expensereport_det') {
1667 print '<td class="left linecoltype">';
1668 $labeltype = ($langs->trans(($element->type_fees_code)) == $element->type_fees_code ? $element->type_fees_libelle : $langs->trans($element->type_fees_code));
1669 print (string) $labeltype;
1670 print '</td>';
1671 }
1672 // Description from Expense Report
1673 if ($tablename == 'expensereport_det') {
1674 print '<td class="left linecolcomment">';
1675 print (string) $element->comments;
1676 print '</td>';
1677 }
1678
1679
1680 // Amount without tax
1681 $warning = '';
1682 if (empty($value['disableamount'])) {
1683 $total_ht_by_line = null;
1684 $othermessage = '';
1685 if ($tablename == 'don' || $tablename == 'chargesociales' || $tablename == 'payment_various' || $tablename == 'salary') {
1686 '@phan-var-force Don|ChargeSociales|PaymentVarious|Salary $element';
1687 $total_ht_by_line = $element->amount;
1688 } elseif ($tablename == 'fichinter') {
1689 '@phan-var-force FichInter $element';
1690 $total_ht_by_line = $element->getAmount();
1691 } elseif ($tablename == 'stock_mouvement') {
1692 '@phan-var-force MouvementStock $element';
1693 $total_ht_by_line = $element->price * abs($element->qty);
1694 } elseif (in_array($tablename, array('projet_task'))) {
1695 if (isModEnabled('salaries')) {
1696 // TODO Permission to read daily rate to show value
1697 $total_ht_by_line = price2num($tmpprojtime['amount'], 'MT');
1698 if (isset($tmpprojtime['nblinesnull']) && ($tmpprojtime['nblinesnull'] > 0)) {
1699 $langs->load("errors");
1700 $warning = $langs->trans("WarningSomeLinesWithNullHourlyRate", $conf->currency);
1701 }
1702 } else {
1703 $othermessage = $form->textwithpicto($langs->trans("NotAvailable"), $langs->trans("ModuleSalaryToDefineHourlyRateMustBeEnabled"));
1704 }
1705 } elseif ($key == 'loan') {
1706 '@phan-var-force Loan $element';
1707 $total_ht_by_line = $element->capital;
1708 } else {
1709 $total_ht_by_line = $element->total_ht;
1710 }
1711
1712 // Change sign of $total_ht_by_line and $total_ttc_by_line for some cases
1713 if ($tablename == 'payment_various') {
1714 if ($element->sens == 0) {
1715 $total_ht_by_line = -$total_ht_by_line;
1716 }
1717 }
1718
1719 print '<td class="right">';
1720 if ($othermessage) {
1721 print '<span class="opacitymedium">'.$othermessage.'</span>';
1722 }
1723 if (isset($total_ht_by_line)) {
1724 if (!$qualifiedfortotal) {
1725 print '<strike>';
1726 }
1727 print '<span class="amount">'.price($total_ht_by_line).'</span>';
1728 if (!$qualifiedfortotal) {
1729 print '</strike>';
1730 }
1731 }
1732 if ($warning) {
1733 print ' '.img_warning($warning);
1734 }
1735 if (isset($tmpprojtime['nblinesnull']) && ($tmpprojtime['nblinesnull'] > 0)) {
1736 if ($tmpprojtime['nbuserthmnull'] > 0) {
1737 $title = $langs->trans("EnterUsersHourlyRateFirst");
1738 print ' '.img_picto($title, "sync", '', 0, 0, 0, '', 'opacitymedium');
1739 } else {
1740 $title = $langs->trans("UpdateUndefinedWithLastHourlyRate");
1741 print ' <a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$id.'&action=updateundefinedwithlasthourlyrate&taskid='.$idofelement.'&token='.currentToken().'">'.img_picto($title, "sync", '', 0, 0, 0, '', 'warning').'</a>';
1742 }
1743 }
1744 if (getDolGlobalString('PROJECT_CAN_OVERWRITE_TIMESTPENT_HOURLY_RATE_WITH_LASTONE')) {
1745 $title = $langs->trans("UpdateWithLastHourlyRate");
1746 print ' <a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$id.'&action=updateallwithlasthourlyrate&taskid='.$idofelement.'&token='.currentToken().'">'.img_picto($title, "sync", '', 0, 0, 0, '', '').'</a>';
1747 }
1748 print '</td>';
1749 } else {
1750 print '<td></td>';
1751 }
1752
1753 // Amount inc tax
1754 if (empty($value['disableamount'])) {
1755 $total_ttc_by_line = null;
1756 if ($tablename == 'don' || $tablename == 'chargesociales' || $tablename == 'payment_various' || $tablename == 'salary') {
1757 '@phan-var-force Don|ChargeSociales|PaymentVarious $element';
1758 $total_ttc_by_line = $element->amount;
1759 } elseif ($tablename == 'fichinter') {
1760 '@phan-var-force Fichinter $element';
1761 $total_ttc_by_line = $element->getAmount();
1762 } elseif ($tablename == 'stock_mouvement') {
1763 '@phan-var-force MouvementStock $element';
1764 $total_ttc_by_line = $element->price * abs($element->qty);
1765 } elseif ($tablename == 'projet_task') {
1766 if (isModEnabled('salaries')) {
1767 // TODO Permission to read daily rate
1768 $defaultvat = get_default_tva($mysoc, $mysoc);
1769 $total_ttc_by_line = price2num($total_ht_by_line * (1 + ($defaultvat / 100)), 'MT');
1770 } else {
1771 $othermessage = $form->textwithpicto($langs->trans("NotAvailable"), $langs->trans("ModuleSalaryToDefineHourlyRateMustBeEnabled"));
1772 }
1773 } elseif ($key == 'loan') {
1774 '@phan-var-force Loan $element';
1775 $total_ttc_by_line = $element->capital - $element->getSumPayment();
1776 } else {
1777 $total_ttc_by_line = $element->total_ttc;
1778 }
1779
1780 // Change sign of $total_ht_by_line and $total_ttc_by_line for some cases
1781 if ($tablename == 'payment_various') {
1782 if ($element->sens == 0) {
1783 $total_ttc_by_line = -$total_ttc_by_line;
1784 }
1785 }
1786
1787 print '<td class="right">';
1788 if ($othermessage) {
1789 print $othermessage;
1790 }
1791 if (isset($total_ttc_by_line)) {
1792 if (!$qualifiedfortotal) {
1793 print '<strike>';
1794 }
1795 print '<span class="amount">'.price($total_ttc_by_line).'</span>';
1796 if (!$qualifiedfortotal) {
1797 print '</strike>';
1798 }
1799 }
1800 if ($warning) {
1801 print ' '.img_warning($warning);
1802 }
1803 if (isset($tmpprojtime['nblinesnull']) && ($tmpprojtime['nblinesnull'] > 0)) {
1804 if ($tmpprojtime['nbuserthmnull'] > 0) {
1805 $title = $langs->trans("EnterUsersHourlyRateFirst");
1806 print ' '.img_picto($title, "sync", '', 0, 0, 0, '', 'opacitymedium');
1807 } else {
1808 $title = $langs->trans("UpdateUndefinedWithLastHourlyRate");
1809 print ' <a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$id.'&action=updateundefinedwithlasthourlyrate&taskid='.$idofelement.'&token='.currentToken().'">'.img_picto($title, "sync", '', 0, 0, 0, '', 'warning').'</a>';
1810 }
1811 }
1812 if (getDolGlobalString('PROJECT_CAN_OVERWRITE_TIMESTPENT_HOURLY_RATE_WITH_LASTONE')) {
1813 $title = $langs->trans("UpdateWithLastHourlyRate");
1814 print ' <a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$id.'&action=updateallwithlasthourlyrate&taskid='.$idofelement.'&token='.currentToken().'">'.img_picto($title, "sync").'</a>';
1815 }
1816 print '</td>';
1817 } else {
1818 print '<td></td>';
1819 }
1820
1821 // Status
1822 print '<td class="right">';
1823 if ($tablename == 'expensereport_det') {
1824 print $expensereport->getLibStatut(5);
1825 } elseif ($element instanceof CommonInvoice) {
1826 //This applies for Facture and FactureFournisseur
1827 print $element->getLibStatut(5, $element->getSommePaiement());
1828 } elseif ($element instanceof Task) {
1829 if ($element->progress != '') {
1830 print $element->progress.' %';
1831 }
1832 } elseif ($tablename == 'stock_mouvement') {
1833 '@phan-var-force MouvementStock $element';
1834 print $element->getLibStatut(3);
1835 } else {
1836 print $element->getLibStatut(5);
1837 }
1838 print '</td>';
1839
1840 print '</tr>';
1841
1842 if ($qualifiedfortotal) {
1843 $total_ht += $total_ht_by_line;
1844 $total_ttc += $total_ttc_by_line;
1845
1846 $total_ht_by_third += $total_ht_by_line;
1847 $total_ttc_by_third += $total_ttc_by_line;
1848
1849 if (!isset($total_time)) {
1850 $total_time = $total_time_by_line;
1851 } else {
1852 $total_time += $total_time_by_line;
1853 }
1854 }
1855
1856 if (canApplySubtotalOn($tablename)) {
1857 $breakline = '<tr class="liste_total liste_sub_total">';
1858 $breakline .= '<td colspan="2">';
1859 $breakline .= '</td>';
1860 $breakline .= '<td>';
1861 $breakline .= '</td>';
1862 $breakline .= '<td class="right">';
1863 $breakline .= $langs->trans('SubTotal').' : ';
1864 if (is_object($element->thirdparty)) {
1865 $breakline .= $element->thirdparty->getNomUrl(0, '', 48);
1866 }
1867 $breakline .= '</td>';
1868 $breakline .= '<td class="right">'.price($total_ht_by_third).'</td>';
1869 $breakline .= '<td class="right">'.price($total_ttc_by_third).'</td>';
1870 $breakline .= '<td></td>';
1871 $breakline .= '</tr>';
1872 }
1873
1874 //var_dump($element->thirdparty->name.' - '.$saved_third_id.' - '.$element->thirdparty->id);
1875 }
1876
1877 if ($breakline) {
1878 print $breakline;
1879 }
1880
1881 // Total
1882 if (empty($nototal)) {
1883 $colspan = 4;
1884 if (in_array($tablename, array('projet_task'))) {
1885 $colspan = 2;
1886 }
1887
1888 print '<tr class="liste_total"><td colspan="'.$colspan.'">'.$langs->trans("Number").': '.$i.'</td>';
1889 if (in_array($tablename, array('projet_task'))) {
1890 print '<td class="center">';
1891 print convertSecondToTime((int) $total_time, 'allhourmin');
1892 print '</td>';
1893 print '<td>';
1894 print '</td>';
1895 }
1896 //if (empty($value['disableamount']) && ! in_array($tablename, array('projet_task'))) print '<td class="right" width="100">'.$langs->trans("TotalHT").' : '.price($total_ht).'</td>';
1897 //elseif (empty($value['disableamount']) && in_array($tablename, array('projet_task'))) print '<td class="right" width="100">'.$langs->trans("Total").' : '.price($total_ht).'</td>';
1898 // If fichinter add the total_duration
1899 if ($tablename == 'fichinter') {
1900 print '<td class="left">'.convertSecondToTime($total_duration, 'all', $conf->global->MAIN_DURATION_OF_WORKDAY).'</td>';
1901 }
1902 print '<td class="right">';
1903 if (empty($value['disableamount'])) {
1904 if ($key == 'loan') {
1905 print $langs->trans("Total").' '.$langs->trans("LoanCapital").' : '.price($total_ttc);
1906 } elseif ($tablename != 'projet_task' || isModEnabled('salaries')) {
1907 print ''.$langs->trans("TotalHT").' : '.price($total_ht);
1908 }
1909 }
1910 print '</td>';
1911 //if (empty($value['disableamount']) && ! in_array($tablename, array('projet_task'))) print '<td class="right" width="100">'.$langs->trans("TotalTTC").' : '.price($total_ttc).'</td>';
1912 //elseif (empty($value['disableamount']) && in_array($tablename, array('projet_task'))) print '<td class="right" width="100"></td>';
1913 print '<td class="right">';
1914 if (empty($value['disableamount'])) {
1915 if ($key == 'loan') {
1916 print $langs->trans("Total").' '.$langs->trans("RemainderToPay").' : '.price($total_ttc);
1917 } elseif ($tablename != 'projet_task' || isModEnabled('salaries')) {
1918 print $langs->trans("TotalTTC").' : '.price($total_ttc);
1919 }
1920 }
1921 print '</td>';
1922 print '<td>&nbsp;</td>';
1923 // Because of the added Type and Description columns to Expense Reports
1924 if ($tablename == 'expensereport_det') {
1925 print '<td>&nbsp;</td>';
1926 print '<td>&nbsp;</td>';
1927 }
1928 print '</tr>';
1929 }
1930 } else {
1931 if (!is_array($elementarray)) { // error
1932 print '<tr><td>'.$elementarray.'</td></tr>';
1933 } else {
1934 $colspan = 7;
1935 if ($tablename == 'fichinter') {
1936 $colspan++;
1937 }
1938 print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("None").'</td></tr>';
1939 }
1940 }
1941 print "</table>";
1942 print '</div>';
1943 print "<br>\n";
1944 }
1945}
1946
1947// Enhance with select2
1948if ($conf->use_javascript_ajax) {
1949 include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php';
1950 $comboenhancement = ajax_combobox('.elementselect');
1951
1952 print $comboenhancement;
1953}
1954
1955// End of page
1956llxFooter();
1957$db->close();
1958
1959
1960
1967function canApplySubtotalOn($tablename)
1968{
1969 global $conf;
1970
1971 if (!getDolGlobalString('PROJECT_ADD_SUBTOTAL_LINES')) {
1972 return false;
1973 }
1974 return in_array($tablename, array('facture_fourn', 'commande_fournisseur'));
1975}
1976
1983function sortElementsByClientName($elementarray)
1984{
1985 global $db, $classname;
1986 '@phan-var-force string $classname';
1987
1988 $element = new $classname($db);
1989 '@phan-var-force CommonObject $element';
1990
1991 $clientname = array();
1992 foreach ($elementarray as $key => $id) { // id = id of object
1993 if (empty($clientname[$id])) {
1994 $element->fetch($id);
1995 $element->fetch_thirdparty();
1996
1997 $clientname[$id] = $element->thirdparty->name;
1998 }
1999 }
2000
2001 //var_dump($clientname);
2002 asort($clientname); // sort on name
2003
2004 $elementarray = array();
2005 foreach ($clientname as $id => $name) {
2006 $elementarray[] = $id;
2007 }
2008
2009 return $elementarray;
2010}
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete='resolve', $idforemptyvalue='-1', $morecss='')
Convert a html select field into an ajax combobox.
Definition ajax.lib.php:475
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
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:73
Superclass for invoice classes.
Class for ConferenceOrBoothAttendee.
Class to manage Trips and Expenses.
const TYPE_DEPOSIT
Deposit invoice.
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 Schedule of loans.
Class to manage products or services.
Class to manage projects.
const STATUS_SIGNED
Signed quote.
const STATUS_BILLED
Billed or processed quote.
Class to manage tasks.
Class for TimeSpent.
Class to manage Dolibarr users.
global $mysoc
dol_get_first_day($year, $month=1, $gm=false)
Return GMT time for first day of a month or year.
Definition date.lib.php:603
convertSecondToTime($iSecond, $format='all', $lengthOfDay=86400, $lengthOfWeek=7)
Return, in clear text, value of a number of seconds in days, hours and minutes.
Definition date.lib.php:247
dol_stringtotime($string, $gm=1)
Convert a string date into a GM Timestamps date Warning: YYYY-MM-DDTHH:MM:SS+02:00 (RFC3339) is not s...
Definition date.lib.php:434
sortElementsByClientName($elementarray)
sortElementsByClientName
Definition element.php:1983
canApplySubtotalOn($tablename)
Return if we should do a group by customer with sub-total.
Definition element.php:1967
dol_now($mode='gmt')
Return date for now.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
dol_getIdFromCode($db, $key, $tablename, $fieldkey='code', $fieldid='id', $entityfilter=0, $filters='', $useCache=true)
Return an id or code from a code or id.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
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, $morecssdiv='')
Show tabs of a record.
dolPrintHTML($s, $allowiframe=0)
Return a string (that can be on several lines) ready to be output on a HTML page.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
currentToken()
Return the value of token currently saved into session with name 'token'.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
dol_eval($s, $returnvalue=1, $hideerrors=1, $onlysimplestring='1')
Replace eval function to add more security.
setEventMessage($mesgs, $style='mesgs', $noduplicate=0, $attop=0)
Set event message in dol_events session object.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
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_escape_js($stringtoescape, $mode=0, $noescapebackslashn=0)
Returns text escaped for inclusion into javascript code.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_clone($srcobject, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that return vat rate of a product line (according to seller, buyer and product vat rate) VAT...
get_exdir($num, $level, $alpha, $withoutslash, $object, $modulepart='')
Return a path to have a the directory according to object where files are stored.
dol_getdate($timestamp, $fast=false, $forcetimezone='')
Return an array with locale date info.
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...
project_prepare_head(Project $project, $moreparam='')
Prepare array with list of tabs.
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.