dolibarr  20.0.0-beta
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 Frédéric France wfrederic.france@netlogic.fr>
12  * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 3 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program. If not, see <https://www.gnu.org/licenses/>.
25  */
26 
33 // Load Dolibarr environment
34 require '../main.inc.php';
35 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
36 require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
37 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
38 require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
39 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
40 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
41 
42 if (isModEnabled('agenda')) {
43  require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
44 }
45 if (isModEnabled('bank')) {
46  require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/paymentvarious.class.php';
47 }
48 if (isModEnabled('category')) {
49  require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
50 }
51 if (isModEnabled('order')) {
52  require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
53 }
54 if (isModEnabled('contract')) {
55  require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
56 }
57 if (isModEnabled('deplacement')) {
58  require_once DOL_DOCUMENT_ROOT.'/compta/deplacement/class/deplacement.class.php';
59 }
60 if (isModEnabled('don')) {
61  require_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php';
62 }
63 if (isModEnabled('shipping')) {
64  require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php';
65 }
66 if (isModEnabled('expensereport')) {
67  require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
68 }
69 if (isModEnabled('invoice')) {
70  require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
71  require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php';
72 }
73 if (isModEnabled('intervention')) {
74  require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
75 }
76 if (isModEnabled('loan')) {
77  require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php';
78  require_once DOL_DOCUMENT_ROOT.'/loan/class/loanschedule.class.php';
79 }
80 if (isModEnabled('mrp')) {
81  require_once DOL_DOCUMENT_ROOT.'/mrp/class/mo.class.php';
82 }
83 if (isModEnabled('propal')) {
84  require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
85 }
86 if (isModEnabled('salaries')) {
87  require_once DOL_DOCUMENT_ROOT.'/salaries/class/salary.class.php';
88 }
89 if (isModEnabled('stock')) {
90  require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
91  require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
92 }
93 if (isModEnabled('supplier_invoice')) {
94  require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
95 }
96 if (isModEnabled('supplier_order')) {
97  require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
98 }
99 if (isModEnabled('supplier_proposal')) {
100  require_once DOL_DOCUMENT_ROOT.'/supplier_proposal/class/supplier_proposal.class.php';
101 }
102 if (isModEnabled('tax')) {
103  require_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php';
104 }
105 if (isModEnabled('stocktransfer')) {
106  require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/class/stocktransfer.class.php';
107  require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/class/stocktransferline.class.php';
108 }
109 
110 
111 
112 // Load translation files required by the page
113 $langs->loadLangs(array('projects', 'companies', 'suppliers', 'compta'));
114 if (isModEnabled('invoice')) {
115  $langs->load("bills");
116 }
117 if (isModEnabled('order')) {
118  $langs->load("orders");
119 }
120 if (isModEnabled("propal")) {
121  $langs->load("propal");
122 }
123 if (isModEnabled('intervention')) {
124  $langs->load("interventions");
125 }
126 if (isModEnabled('deplacement')) {
127  $langs->load("trips");
128 }
129 if (isModEnabled('expensereport')) {
130  $langs->load("trips");
131 }
132 if (isModEnabled('don')) {
133  $langs->load("donations");
134 }
135 if (isModEnabled('loan')) {
136  $langs->load("loan");
137 }
138 if (isModEnabled('salaries')) {
139  $langs->load("salaries");
140 }
141 if (isModEnabled('mrp')) {
142  $langs->load("mrp");
143 }
144 if (isModEnabled('eventorganization')) {
145  $langs->load("eventorganization");
146 }
147 //if (isModEnabled('stocktransfer')) {
148 // $langs->load("stockstransfer");
149 //}
150 
151 $id = GETPOSTINT('id');
152 $ref = GETPOST('ref', 'alpha');
153 $action = GETPOST('action', 'aZ09');
154 $datesrfc = GETPOST('datesrfc'); // deprecated
155 $dateerfc = GETPOST('dateerfc'); // deprecated
156 $dates = dol_mktime(0, 0, 0, GETPOST('datesmonth'), GETPOST('datesday'), GETPOST('datesyear'));
157 $datee = dol_mktime(23, 59, 59, GETPOST('dateemonth'), GETPOST('dateeday'), GETPOST('dateeyear'));
158 if (empty($dates) && !empty($datesrfc)) { // deprecated
159  $dates = dol_stringtotime($datesrfc);
160 }
161 if (empty($datee) && !empty($dateerfc)) { // deprecated
162  $datee = dol_stringtotime($dateerfc);
163 }
164 if (!GETPOSTISSET('datesrfc') && !GETPOSTISSET('datesday') && getDolGlobalString('PROJECT_LINKED_ELEMENT_DEFAULT_FILTER_YEAR')) {
165  $new = dol_now();
166  $tmp = dol_getdate($new);
167  //$datee=$now
168  //$dates=dol_time_plus_duree($datee, -1, 'y');
169  $dates = dol_get_first_day($tmp['year'], 1);
170 }
171 if ($id == '' && $ref == '') {
172  setEventMessage($langs->trans('ErrorBadParameters'), 'errors');
173  header('Location: list.php');
174  exit();
175 }
176 
177 $mine = GETPOST('mode') == 'mine' ? 1 : 0;
178 //if (! $user->rights->projet->all->lire) $mine=1; // Special for projects
179 
180 $object = new Project($db);
181 
182 include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once
183 if (getDolGlobalString('PROJECT_ALLOW_COMMENT_ON_PROJECT') && method_exists($object, 'fetchComments') && empty($object->comments)) {
184  $object->fetchComments();
185 }
186 
187 // Security check
188 $socid = $object->socid;
189 //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.
190 $result = restrictedArea($user, 'projet', $object->id, 'projet&project');
191 
192 $hookmanager->initHooks(array('projectOverview'));
193 
194 
195 /*
196  * View
197  */
198 
199 $title = $langs->trans('ProjectReferers').' - '.$object->ref.' '.$object->name;
200 if (getDolGlobalString('MAIN_HTML_TITLE') && preg_match('/projectnameonly/', getDolGlobalString('MAIN_HTML_TITLE')) && $object->name) {
201  $title = $object->ref.' '.$object->name.' - '.$langs->trans('ProjectReferers');
202 }
203 
204 $help_url = 'EN:Module_Projects|FR:Module_Projets|ES:M&oacute;dulo_Proyectos|DE:Modul_Projekte';
205 
206 llxHeader('', $title, $help_url);
207 
208 $form = new Form($db);
209 $formproject = new FormProjets($db);
210 $formfile = new FormFile($db);
211 
212 $userstatic = new User($db);
213 
214 // To verify role of users
215 $userAccess = $object->restrictedProjectArea($user);
216 
218 print dol_get_fiche_head($head, 'element', $langs->trans("Project"), -1, ($object->public ? 'projectpub' : 'project'));
219 
220 
221 // Project card
222 
223 if (!empty($_SESSION['pageforbacktolist']) && !empty($_SESSION['pageforbacktolist']['project'])) {
224  $tmpurl = $_SESSION['pageforbacktolist']['project'];
225  $tmpurl = preg_replace('/__SOCID__/', (string) $object->socid, $tmpurl);
226  $linkback = '<a href="'.$tmpurl.(preg_match('/\?/', $tmpurl) ? '&' : '?'). 'restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
227 } else {
228  $linkback = '<a href="'.DOL_URL_ROOT.'/projet/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
229 }
230 
231 $morehtmlref = '<div class="refidno">';
232 // Title
233 $morehtmlref .= $object->title;
234 // Thirdparty
235 if (!empty($object->thirdparty->id) && $object->thirdparty->id > 0) {
236  $morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1, 'project');
237 }
238 $morehtmlref .= '</div>';
239 
240 // Define a complementary filter for search of next/prev ref.
241 if (!$user->hasRight('projet', 'all', 'lire')) {
242  $objectsListId = $object->getProjectsAuthorizedForUser($user, 0, 0);
243  $object->next_prev_filter = "te.rowid IN (".$db->sanitize(count($objectsListId) ? implode(',', array_keys($objectsListId)) : '0').")";
244 }
245 
246 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
247 
248 
249 print '<div class="fichecenter">';
250 print '<div class="fichehalfleft">';
251 print '<div class="underbanner clearboth"></div>';
252 
253 print '<table class="border tableforfield centpercent">';
254 
255 // Usage
256 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES') || !getDolGlobalString('PROJECT_HIDE_TASKS') || isModEnabled('eventorganization')) {
257  print '<tr><td class="tdtop">';
258  print $langs->trans("Usage");
259  print '</td>';
260  print '<td>';
261  if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) {
262  print '<input type="checkbox" disabled name="usage_opportunity"'.(GETPOSTISSET('usage_opportunity') ? (GETPOST('usage_opportunity', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_opportunity ? ' checked="checked"' : '')).'"> ';
263  $htmltext = $langs->trans("ProjectFollowOpportunity");
264  print $form->textwithpicto($langs->trans("ProjectFollowOpportunity"), $htmltext);
265  print '<br>';
266  }
267  if (!getDolGlobalString('PROJECT_HIDE_TASKS')) {
268  print '<input type="checkbox" disabled name="usage_task"'.(GETPOSTISSET('usage_task') ? (GETPOST('usage_task', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_task ? ' checked="checked"' : '')).'"> ';
269  $htmltext = $langs->trans("ProjectFollowTasks");
270  print $form->textwithpicto($langs->trans("ProjectFollowTasks"), $htmltext);
271  print '<br>';
272  }
273  if (!getDolGlobalString('PROJECT_HIDE_TASKS') && getDolGlobalString('PROJECT_BILL_TIME_SPENT')) {
274  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"' : '')).'"> ';
275  $htmltext = $langs->trans("ProjectBillTimeDescription");
276  print $form->textwithpicto($langs->trans("BillTime"), $htmltext);
277  print '<br>';
278  }
279  if (isModEnabled('eventorganization')) {
280  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"' : '')).'"> ';
281  $htmltext = $langs->trans("EventOrganizationDescriptionLong");
282  print $form->textwithpicto($langs->trans("ManageOrganizeEvent"), $htmltext);
283  }
284  print '</td></tr>';
285 }
286 
287 // Visibility
288 print '<tr><td class="titlefield">'.$langs->trans("Visibility").'</td><td>';
289 if ($object->public) {
290  print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"');
291  print $langs->trans('SharedProject');
292 } else {
293  print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"');
294  print $langs->trans('PrivateProject');
295 }
296 print '</td></tr>';
297 
298 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) {
299  // Opportunity status
300  print '<tr><td>'.$langs->trans("OpportunityStatus").'</td><td>';
301  $code = dol_getIdFromCode($db, $object->opp_status, 'c_lead_status', 'rowid', 'code');
302  if ($code) {
303  print $langs->trans("OppStatus".$code);
304  }
305  print '</td></tr>';
306 
307  // Opportunity percent
308  print '<tr><td>'.$langs->trans("OpportunityProbability").'</td><td>';
309  if (!is_null($object->opp_percent) && strcmp($object->opp_percent, '')) {
310  print price($object->opp_percent, 0, $langs, 1, 0).' %';
311  }
312  print '</td></tr>';
313 
314  // Opportunity Amount
315  print '<tr><td>'.$langs->trans("OpportunityAmount").'</td><td>';
316  if (!is_null($object->opp_amount) && strcmp($object->opp_amount, '')) {
317  print '<span class="amount">'.price($object->opp_amount, 0, $langs, 1, 0, 0, $conf->currency).'</span>';
318  if (strcmp($object->opp_percent, '')) {
319  print ' &nbsp; &nbsp; &nbsp; <span title="'.dol_escape_htmltag($langs->trans('OpportunityWeightedAmount')).'"><span class="opacitymedium">'.$langs->trans("Weighted").'</span>: <span class="amount">'.price($object->opp_amount * $object->opp_percent / 100, 0, $langs, 1, 0, -1, $conf->currency).'</span></span>';
320  }
321  }
322  print '</td></tr>';
323 }
324 
325 // Budget
326 print '<tr><td>'.$langs->trans("Budget").'</td><td>';
327 if (!is_null($object->budget_amount) && strcmp($object->budget_amount, '')) {
328  print '<span class="amount">'.price($object->budget_amount, 0, $langs, 1, 0, 0, $conf->currency).'</span>';
329 }
330 print '</td></tr>';
331 
332 // Date start - end project
333 print '<tr><td>'.$langs->trans("Dates").'</td><td>';
334 $start = dol_print_date($object->date_start, 'day');
335 print($start ? $start : '?');
336 $end = dol_print_date($object->date_end, 'day');
337 print ' - ';
338 print($end ? $end : '?');
339 if ($object->hasDelay()) {
340  print img_warning("Late");
341 }
342 print '</td></tr>';
343 
344 // Other attributes
345 $cols = 2;
346 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
347 
348 print '</table>';
349 
350 print '</div>';
351 print '<div class="fichehalfright">';
352 print '<div class="underbanner clearboth"></div>';
353 
354 print '<table class="border tableforfield centpercent">';
355 
356 // Description
357 print '<td class="titlefield tdtop">'.$langs->trans("Description").'</td><td>';
358 print dol_htmlentitiesbr($object->description);
359 print '</td></tr>';
360 
361 // Categories
362 if (isModEnabled('category')) {
363  print '<tr><td class="valignmiddle">'.$langs->trans("Categories").'</td><td>';
364  print $form->showCategories($object->id, Categorie::TYPE_PROJECT, 1);
365  print "</td></tr>";
366 }
367 
368 print '</table>';
369 
370 print '</div>';
371 print '</div>';
372 
373 print '<div class="clearboth"></div>';
374 
375 print dol_get_fiche_end();
376 
377 print '<br>';
378 
379 /*
380  * Referrer types
381  */
382 
383 $listofreferent = array(
384  'entrepot' => array(
385  'name' => "Warehouse",
386  'title' => "ListWarehouseAssociatedProject",
387  'class' => 'Entrepot',
388  'table' => 'entrepot',
389  'datefieldname' => 'date_entrepot',
390  'urlnew' => DOL_URL_ROOT.'/product/stock/card.php?action=create&projectid='.$id.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
391  'lang' => 'entrepot',
392  'buttonnew' => 'AddWarehouse',
393  'project_field' => 'fk_project',
394  'testnew' => $user->hasRight('stock', 'creer'),
395  'test' => isModEnabled('stock') && $user->hasRight('stock', 'lire') && getDolGlobalString('WAREHOUSE_ASK_WAREHOUSE_DURING_PROJECT')
396  ),
397  'propal' => array(
398  'name' => "Proposals",
399  'title' => "ListProposalsAssociatedProject",
400  'class' => 'Propal',
401  'table' => 'propal',
402  'datefieldname' => 'datep',
403  'urlnew' => DOL_URL_ROOT.'/comm/propal/card.php?action=create&origin=project&originid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
404  'lang' => 'propal',
405  'buttonnew' => 'AddProp',
406  'testnew' => $user->hasRight('propal', 'creer'),
407  'test' => isModEnabled('propal') && $user->hasRight('propal', 'lire')
408  ),
409  'order' => array(
410  'name' => "CustomersOrders",
411  'title' => "ListOrdersAssociatedProject",
412  'class' => 'Commande',
413  'table' => 'commande',
414  'datefieldname' => 'date_commande',
415  'urlnew' => DOL_URL_ROOT.'/commande/card.php?action=create&projectid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
416  'lang' => 'orders',
417  'buttonnew' => 'CreateOrder',
418  'testnew' => $user->hasRight('commande', 'creer'),
419  'test' => isModEnabled('order') && $user->hasRight('commande', 'lire')
420  ),
421  'invoice' => array(
422  'name' => "CustomersInvoices",
423  'title' => "ListInvoicesAssociatedProject",
424  'class' => 'Facture',
425  'margin' => 'add',
426  'table' => 'facture',
427  'datefieldname' => 'datef',
428  'urlnew' => DOL_URL_ROOT.'/compta/facture/card.php?action=create&projectid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
429  'lang' => 'bills',
430  'buttonnew' => 'CreateBill',
431  'testnew' => $user->hasRight('facture', 'creer'),
432  'test' => isModEnabled('invoice') && $user->hasRight('facture', 'lire')
433  ),
434  'invoice_predefined' => array(
435  'name' => "PredefinedInvoices",
436  'title' => "ListPredefinedInvoicesAssociatedProject",
437  'class' => 'FactureRec',
438  'table' => 'facture_rec',
439  'datefieldname' => 'datec',
440  'urlnew' => DOL_URL_ROOT.'/compta/facture/card.php?action=create&projectid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
441  'lang' => 'bills',
442  'buttonnew' => 'CreateBill',
443  'testnew' => $user->hasRight('facture', 'creer'),
444  'test' => isModEnabled('invoice') && $user->hasRight('facture', 'lire')
445  ),
446  'proposal_supplier' => array(
447  'name' => "SupplierProposals",
448  'title' => "ListSupplierProposalsAssociatedProject",
449  'class' => 'SupplierProposal',
450  'table' => 'supplier_proposal',
451  'datefieldname' => 'date_valid',
452  '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
453  'lang' => 'supplier_proposal',
454  'buttonnew' => 'AddSupplierProposal',
455  'testnew' => $user->hasRight('supplier_proposal', 'creer'),
456  'test' => isModEnabled('supplier_proposal') && $user->hasRight('supplier_proposal', 'lire')
457  ),
458  'order_supplier' => array(
459  'name' => "SuppliersOrders",
460  'title' => "ListSupplierOrdersAssociatedProject",
461  'class' => 'CommandeFournisseur',
462  'table' => 'commande_fournisseur',
463  'datefieldname' => 'date_commande',
464  '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
465  'lang' => 'suppliers',
466  'buttonnew' => 'AddSupplierOrder',
467  'testnew' => $user->hasRight('fournisseur', 'commande', 'creer') || $user->hasRight('supplier_order', 'creer'),
468  'test' => isModEnabled('supplier_order') && $user->hasRight('fournisseur', 'commande', 'lire') || $user->hasRight('supplier_order', 'lire')
469  ),
470  'invoice_supplier' => array(
471  'name' => "BillsSuppliers",
472  'title' => "ListSupplierInvoicesAssociatedProject",
473  'class' => 'FactureFournisseur',
474  'margin' => 'minus',
475  'table' => 'facture_fourn',
476  'datefieldname' => 'datef',
477  '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
478  'lang' => 'suppliers',
479  'buttonnew' => 'AddSupplierInvoice',
480  'testnew' => $user->hasRight('fournisseur', 'facture', 'creer') || $user->hasRight('supplier_invoice', 'creer'),
481  'test' => isModEnabled('supplier_invoice') && $user->hasRight('fournisseur', 'facture', 'lire') || $user->hasRight('supplier_invoice', 'lire')
482  ),
483  'contract' => array(
484  'name' => "Contracts",
485  'title' => "ListContractAssociatedProject",
486  'class' => 'Contrat',
487  'table' => 'contrat',
488  'datefieldname' => 'date_contrat',
489  'urlnew' => DOL_URL_ROOT.'/contrat/card.php?action=create&projectid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
490  'lang' => 'contracts',
491  'buttonnew' => 'AddContract',
492  'testnew' => $user->hasRight('contrat', 'creer'),
493  'test' => isModEnabled('contract') && $user->hasRight('contrat', 'lire')
494  ),
495  'intervention' => array(
496  'name' => "Interventions",
497  'title' => "ListFichinterAssociatedProject",
498  'class' => 'Fichinter',
499  'table' => 'fichinter',
500  'datefieldname' => 'date_valid',
501  'disableamount' => 0,
502  'margin' => '',
503  'urlnew' => DOL_URL_ROOT.'/fichinter/card.php?action=create&origin=project&originid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
504  'lang' => 'interventions',
505  'buttonnew' => 'AddIntervention',
506  'testnew' => $user->hasRight('ficheinter', 'creer'),
507  'test' => isModEnabled('intervention') && $user->hasRight('ficheinter', 'lire')
508  ),
509  'shipping' => array(
510  'name' => "Shippings",
511  'title' => "ListShippingAssociatedProject",
512  'class' => 'Expedition',
513  'table' => 'expedition',
514  'datefieldname' => 'date_valid',
515  'urlnew' => DOL_URL_ROOT.'/expedition/card.php?action=create&origin=project&originid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
516  'lang' => 'sendings',
517  'buttonnew' => 'CreateShipment',
518  'testnew' => 0,
519  'test' => isModEnabled('shipping') && $user->hasRight('expedition', 'lire')
520  ),
521  'mrp' => array(
522  'name' => "MO",
523  'title' => "ListMOAssociatedProject",
524  'class' => 'Mo',
525  'table' => 'mrp_mo',
526  'datefieldname' => 'date_valid',
527  'urlnew' => DOL_URL_ROOT.'/mrp/mo_card.php?action=create&origin=project&originid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
528  'lang' => 'mrp',
529  'buttonnew' => 'CreateMO',
530  'testnew' => $user->hasRight('mrp', 'write'),
531  'project_field' => 'fk_project',
532  'nototal' => 1,
533  'test' => isModEnabled('mrp') && $user->hasRight('mrp', 'read')
534  ),
535  'trip' => array(
536  'name' => "TripsAndExpenses",
537  'title' => "ListExpenseReportsAssociatedProject",
538  'class' => 'Deplacement',
539  'table' => 'deplacement',
540  'datefieldname' => 'dated',
541  'margin' => 'minus',
542  'disableamount' => 1,
543  'urlnew' => DOL_URL_ROOT.'/deplacement/card.php?action=create&projectid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
544  'lang' => 'trips',
545  'buttonnew' => 'AddTrip',
546  'testnew' => $user->hasRight('deplacement', 'creer'),
547  'test' => isModEnabled('deplacement') && $user->hasRight('deplacement', 'lire')
548  ),
549  'expensereport' => array(
550  'name' => "ExpenseReports",
551  'title' => "ListExpenseReportsAssociatedProject",
552  'class' => 'ExpenseReportLine',
553  'table' => 'expensereport_det',
554  'datefieldname' => 'date',
555  'margin' => 'minus',
556  'disableamount' => 0,
557  'urlnew' => DOL_URL_ROOT.'/expensereport/card.php?action=create&projectid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
558  'lang' => 'trips',
559  'buttonnew' => 'AddTrip',
560  'testnew' => $user->hasRight('expensereport', 'creer'),
561  'test' => isModEnabled('expensereport') && $user->hasRight('expensereport', 'lire')
562  ),
563  'donation' => array(
564  'name' => "Donation",
565  'title' => "ListDonationsAssociatedProject",
566  'class' => 'Don',
567  'margin' => 'add',
568  'table' => 'don',
569  'datefieldname' => 'datedon',
570  'disableamount' => 0,
571  'urlnew' => DOL_URL_ROOT.'/don/card.php?action=create&projectid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
572  'lang' => 'donations',
573  'buttonnew' => 'AddDonation',
574  'testnew' => $user->hasRight('don', 'creer'),
575  'test' => isModEnabled('don') && $user->hasRight('don', 'lire')
576  ),
577  'loan' => array(
578  'name' => "Loan",
579  'title' => "ListLoanAssociatedProject",
580  'class' => 'Loan',
581  'margin' => 'add',
582  'table' => 'loan',
583  'datefieldname' => 'datestart',
584  'disableamount' => 0,
585  'urlnew' => DOL_URL_ROOT.'/loan/card.php?action=create&projectid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
586  'lang' => 'loan',
587  'buttonnew' => 'AddLoan',
588  'testnew' => $user->hasRight('loan', 'write'),
589  'test' => isModEnabled('loan') && $user->hasRight('loan', 'read')
590  ),
591  'chargesociales' => array(
592  'name' => "SocialContribution",
593  'title' => "ListSocialContributionAssociatedProject",
594  'class' => 'ChargeSociales',
595  'margin' => 'minus',
596  'table' => 'chargesociales',
597  'datefieldname' => 'date_ech',
598  'disableamount' => 0,
599  'urlnew' => DOL_URL_ROOT.'/compta/sociales/card.php?action=create&projectid='.$id.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
600  'lang' => 'compta',
601  'buttonnew' => 'AddSocialContribution',
602  'testnew' => $user->hasRight('tax', 'charges', 'lire'),
603  'test' => isModEnabled('tax') && $user->hasRight('tax', 'charges', 'lire')
604  ),
605  'project_task' => array(
606  'name' => "TaskTimeSpent",
607  'title' => "ListTaskTimeUserProject",
608  'class' => 'Task',
609  'margin' => 'minus',
610  'table' => 'projet_task',
611  'datefieldname' => 'element_date',
612  'disableamount' => 0,
613  'urlnew' => DOL_URL_ROOT.'/projet/tasks/time.php?withproject=1&action=createtime&projectid='.$id.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
614  'buttonnew' => 'AddTimeSpent',
615  'testnew' => $user->hasRight('project', 'creer'),
616  'test' => isModEnabled('project') && $user->hasRight('projet', 'lire') && !getDolGlobalString('PROJECT_HIDE_TASKS')
617  ),
618  'stock_mouvement' => array(
619  'name' => "MouvementStockAssociated",
620  'title' => "ListMouvementStockProject",
621  'class' => 'StockTransfer',
622  'table' => 'stocktransfer_stocktransfer',
623  'datefieldname' => 'datem',
624  'margin' => 'minus',
625  'project_field' => 'fk_project',
626  'disableamount' => 0,
627  'test' => isModEnabled('stock') && $user->hasRight('stock', 'mouvement', 'lire') && getDolGlobalString('STOCK_MOVEMENT_INTO_PROJECT_OVERVIEW')
628  ),
629  'salaries' => array(
630  'name' => "Salaries",
631  'title' => "ListSalariesAssociatedProject",
632  'class' => 'Salary',
633  'table' => 'salary',
634  'datefieldname' => 'datesp',
635  'margin' => 'minus',
636  'disableamount' => 0,
637  'urlnew' => DOL_URL_ROOT.'/salaries/card.php?action=create&projectid='.$id.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
638  'lang' => 'salaries',
639  'buttonnew' => 'AddSalary',
640  'testnew' => $user->hasRight('salaries', 'write'),
641  'test' => isModEnabled('salaries') && $user->hasRight('salaries', 'read')
642  ),
643  'variouspayment' => array(
644  'name' => "VariousPayments",
645  'title' => "ListVariousPaymentsAssociatedProject",
646  'class' => 'PaymentVarious',
647  'table' => 'payment_various',
648  'datefieldname' => 'datev',
649  'margin' => 'minus',
650  'disableamount' => 0,
651  'urlnew' => DOL_URL_ROOT.'/compta/bank/various_payment/card.php?action=create&projectid='.$id.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
652  'lang' => 'banks',
653  'buttonnew' => 'AddVariousPayment',
654  'testnew' => $user->hasRight('banque', 'modifier'),
655  'test' => isModEnabled("bank") && $user->hasRight('banque', 'lire') && !getDolGlobalString('BANK_USE_OLD_VARIOUS_PAYMENT')
656  ),
657  /* No need for this, available on dedicated tab "Agenda/Events"
658  'agenda'=>array(
659  'name'=>"Agenda",
660  'title'=>"ListActionsAssociatedProject",
661  'class'=>'ActionComm',
662  'table'=>'actioncomm',
663  'datefieldname'=>'datep',
664  'disableamount'=>1,
665  'urlnew'=>DOL_URL_ROOT.'/comm/action/card.php?action=create&projectid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
666  'lang'=>'agenda',
667  'buttonnew'=>'AddEvent',
668  'testnew'=>$user->rights->agenda->myactions->create,
669  'test'=> isModEnabled('agenda') && $user->hasRight('agenda', 'myactions', 'read')),
670  */
671 );
672 
673 // Change rules for profit/benefit calculation
674 if (getDolGlobalString('PROJECT_ELEMENTS_FOR_PLUS_MARGIN')) {
675  foreach ($listofreferent as $key => $element) {
676  if ($listofreferent[$key]['margin'] == 'add') {
677  unset($listofreferent[$key]['margin']);
678  }
679  }
680  $newelementforplusmargin = explode(',', getDolGlobalString('PROJECT_ELEMENTS_FOR_PLUS_MARGIN'));
681  foreach ($newelementforplusmargin as $value) {
682  $listofreferent[trim($value)]['margin'] = 'add';
683  }
684 }
685 if (getDolGlobalString('PROJECT_ELEMENTS_FOR_MINUS_MARGIN')) {
686  foreach ($listofreferent as $key => $element) {
687  if ($listofreferent[$key]['margin'] == 'minus') {
688  unset($listofreferent[$key]['margin']);
689  }
690  }
691  $newelementforminusmargin = explode(',', getDolGlobalString('PROJECT_ELEMENTS_FOR_MINUS_MARGIN'));
692  foreach ($newelementforminusmargin as $value) {
693  $listofreferent[trim($value)]['margin'] = 'minus';
694  }
695 }
696 
697 
698 $parameters = array('listofreferent' => $listofreferent);
699 $resHook = $hookmanager->executeHooks('completeListOfReferent', $parameters, $object, $action);
700 
701 if (!empty($hookmanager->resArray)) {
702  $listofreferent = array_merge($listofreferent, $hookmanager->resArray);
703 }
704 
705 if ($action == "addelement") {
706  $tablename = GETPOST("tablename");
707  $elementselectid = GETPOST("elementselect");
708  $result = $object->update_element($tablename, $elementselectid);
709  if ($result < 0) {
710  setEventMessages($object->error, $object->errors, 'errors');
711  }
712 } elseif ($action == "unlink") {
713  $tablename = GETPOST("tablename", "aZ09");
714  $projectField = GETPOSTISSET('projectfield') ? GETPOST('projectfield', 'aZ09') : 'fk_projet';
715  $elementselectid = GETPOSTINT("elementselect");
716 
717  $result = $object->remove_element($tablename, $elementselectid, $projectField);
718  if ($result < 0) {
719  setEventMessages($object->error, $object->errors, 'errors');
720  }
721 }
722 
723 $elementuser = new User($db);
724 
725 
726 
727 $showdatefilter = 0;
728 // Show the filter on date on top of element list
729 if (!$showdatefilter) {
730  print '<div class="center centpercent">';
731  print '<form action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="POST">';
732  print '<input type="hidden" name="token" value="'.newToken().'">';
733  print '<input type="hidden" name="tablename" value="'.(empty($tablename) ? '' : $tablename).'">';
734  print '<input type="hidden" name="action" value="view">';
735  print '<div class="inline-block">';
736  print $form->selectDate($dates, 'dates', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From"));
737  print '</div>';
738  print '<div class="inline-block">';
739  print $form->selectDate($datee, 'datee', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to"));
740  print '</div>';
741  print '<div class="inline-block">';
742  print '<input type="submit" name="refresh" value="'.$langs->trans("Refresh").'" class="button small">';
743  print '</div>';
744  print '</form>';
745  print '</div>';
746 
747  $showdatefilter++;
748 }
749 
750 
751 
752 // Show balance for whole project
753 
754 $langs->loadLangs(array("suppliers", "bills", "orders", "proposals", "margins"));
755 
756 if (isModEnabled('stock')) {
757  $langs->load('stocks');
758 }
759 
760 print load_fiche_titre($langs->trans("Profit"), '', 'title_accountancy');
761 
762 print '<table class="noborder centpercent">';
763 print '<tr class="liste_titre">';
764 print '<td class="left" width="200">';
765 $tooltiponprofit = $langs->trans("ProfitIsCalculatedWith")."<br>\n";
766 $tooltiponprofitplus = $tooltiponprofitminus = '';
767 foreach ($listofreferent as $key => $value) {
768  if (!empty($value['lang'])) {
769  $langs->load($value['lang']);
770  }
771  $name = $langs->trans($value['name']);
772  $qualified = $value['test'];
773  $margin = empty($value['margin']) ? '' : $value['margin'];
774  if ($qualified && isset($margin)) { // If this element must be included into profit calculation ($margin is 'minus' or 'add')
775  if ($margin === 'add') {
776  $tooltiponprofitplus .= ' &gt; '.$name." (+)<br>\n";
777  }
778  if ($margin === 'minus') {
779  $tooltiponprofitminus .= ' &gt; '.$name." (-)<br>\n";
780  }
781  }
782 }
783 $tooltiponprofit .= $tooltiponprofitplus;
784 $tooltiponprofit .= $tooltiponprofitminus;
785 print $form->textwithpicto($langs->trans("Element"), $tooltiponprofit);
786 print '</td>';
787 print '<td class="right" width="100">'.$langs->trans("Number").'</td>';
788 print '<td class="right" width="100">'.$langs->trans("AmountHT").'</td>';
789 print '<td class="right" width="100">'.$langs->trans("AmountTTC").'</td>';
790 print '</tr>';
791 
792 $total_revenue_ht = 0;
793 $balance_ht = 0;
794 $balance_ttc = 0;
795 
796 // Loop on each element type (proposal, sale order, invoices, ...)
797 foreach ($listofreferent as $key => $value) {
798  $parameters = array(
799  'total_revenue_ht' => & $total_revenue_ht,
800  'balance_ht' => & $balance_ht,
801  'balance_ttc' => & $balance_ttc,
802  'key' => $key,
803  'value' => & $value,
804  'dates' => $dates,
805  'datee' => $datee
806  );
807  $reshook = $hookmanager->executeHooks('printOverviewProfit', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
808  if ($reshook < 0) {
809  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
810  } elseif ($reshook > 0) {
811  print $hookmanager->resPrint;
812  continue;
813  }
814 
815  $name = $langs->trans($value['name']);
816  $title = $value['title'];
817  $classname = $value['class'];
818  $tablename = $value['table'];
819  $datefieldname = $value['datefieldname'];
820  $qualified = $value['test'];
821  $margin = empty($value['margin']) ? 0 : $value['margin'];
822  $project_field = empty($value['project_field']) ? '' : $value['project_field'];
823  if ($qualified && isset($margin)) { // If this element must be included into profit calculation ($margin is 'minus' or 'add')
824  $element = new $classname($db);
825 
826  $elementarray = $object->get_element_list($key, $tablename, $datefieldname, $dates, $datee, !empty($project_field) ? $project_field : 'fk_projet');
827 
828  if (is_array($elementarray) && count($elementarray) > 0) {
829  $total_ht = 0;
830  $total_ttc = 0;
831 
832  // Loop on each object for the current element type
833  $num = count($elementarray);
834  for ($i = 0; $i < $num; $i++) {
835  $tmp = explode('_', $elementarray[$i]);
836  $idofelement = $tmp[0];
837  $idofelementuser = !empty($tmp[1]) ? $tmp[1] : "";
838 
839  $element->fetch($idofelement);
840  if ($idofelementuser) {
841  $elementuser->fetch($idofelementuser);
842  }
843 
844  // Define if record must be used for total or not
845  $qualifiedfortotal = true;
846  if ($key == 'invoice') {
847  if (!empty($element->close_code) && $element->close_code == 'replaced') {
848  $qualifiedfortotal = false; // Replacement invoice, do not include into total
849  }
850  if (getDolGlobalString('FACTURE_DEPOSITS_ARE_JUST_PAYMENTS') && $element->type == Facture::TYPE_DEPOSIT) {
851  $qualifiedfortotal = false; // If hidden option to use deposits as payment (deprecated, not recommended to use this), deposits are not included
852  }
853  }
854  if ($key == 'propal') {
855  if ($element->status != Propal::STATUS_SIGNED && $element->status != Propal::STATUS_BILLED) {
856  $qualifiedfortotal = false; // Only signed proposal must not be included in total
857  }
858  }
859 
860  if ($tablename != 'expensereport_det' && method_exists($element, 'fetch_thirdparty')) {
861  $element->fetch_thirdparty();
862  }
863 
864  // Define $total_ht_by_line
865  if ($tablename == 'don' || $tablename == 'chargesociales' || $tablename == 'payment_various' || $tablename == 'salary') {
866  $total_ht_by_line = $element->amount;
867  } elseif ($tablename == 'fichinter') {
868  $total_ht_by_line = $element->getAmount();
869  } elseif ($tablename == 'stock_mouvement') {
870  $total_ht_by_line = $element->price * abs($element->qty);
871  } elseif ($tablename == 'projet_task') {
872  $tmp = $element->getSumOfAmount($idofelementuser ? $elementuser : '', $dates, $datee);
873  $total_ht_by_line = price2num($tmp['amount'], 'MT');
874  } elseif ($key == 'loan') {
875  if ((empty($dates) && empty($datee)) || (intval($dates) <= $element->datestart && intval($datee) >= $element->dateend)) {
876  // Get total loan
877  $total_ht_by_line = -$element->capital;
878  } else {
879  // Get loan schedule according to date filter
880  $total_ht_by_line = 0;
881  $loanScheduleStatic = new LoanSchedule($element->db);
882  $loanScheduleStatic->fetchAll($element->id);
883  if (!empty($loanScheduleStatic->lines)) {
884  foreach ($loanScheduleStatic->lines as $loanSchedule) {
888  if (($loanSchedule->datep >= $dates && $loanSchedule->datep <= $datee) // dates filter is defined
889  || !empty($dates) && empty($datee) && $loanSchedule->datep >= $dates && $loanSchedule->datep <= dol_now()
890  || empty($dates) && !empty($datee) && $loanSchedule->datep <= $datee
891  ) {
892  $total_ht_by_line -= $loanSchedule->amount_capital;
893  }
894  }
895  }
896  }
897  } else {
898  $total_ht_by_line = $element->total_ht;
899  }
900 
901  // Define $total_ttc_by_line
902  if ($tablename == 'don' || $tablename == 'chargesociales' || $tablename == 'payment_various' || $tablename == 'salary') {
903  $total_ttc_by_line = $element->amount;
904  } elseif ($tablename == 'fichinter') {
905  $total_ttc_by_line = $element->getAmount();
906  } elseif ($tablename == 'stock_mouvement') {
907  $total_ttc_by_line = $element->price * abs($element->qty);
908  } elseif ($tablename == 'projet_task') {
909  $defaultvat = get_default_tva($mysoc, $mysoc);
910  $reg = array();
911  if (preg_replace('/^(\d+\.)\s\‍(.*\‍)/', $defaultvat, $reg)) {
912  $defaultvat = $reg[1];
913  }
914  $total_ttc_by_line = price2num($total_ht_by_line * (1 + ((float) $defaultvat / 100)), 'MT');
915  } elseif ($key == 'loan') {
916  $total_ttc_by_line = $total_ht_by_line; // For loan there is actually no taxe managed in Dolibarr
917  } else {
918  $total_ttc_by_line = $element->total_ttc;
919  }
920 
921  // Change sign of $total_ht_by_line and $total_ttc_by_line for some cases
922  if ($tablename == 'payment_various') {
923  if ($element->sens == 1) {
924  $total_ht_by_line = -$total_ht_by_line;
925  $total_ttc_by_line = -$total_ttc_by_line;
926  }
927  }
928 
929  // Add total if we have to
930  if ($qualifiedfortotal) {
931  $total_ht = $total_ht + $total_ht_by_line;
932  $total_ttc = $total_ttc + $total_ttc_by_line;
933  }
934  }
935 
936  // Each element with at least one line is output
937 
938  // Calculate margin
939  if ($margin) {
940  if ($margin === 'add') {
941  $total_revenue_ht += $total_ht;
942  }
943 
944  if ($margin === "minus") { // Revert sign
945  $total_ht = -$total_ht;
946  $total_ttc = -$total_ttc;
947  }
948 
949  $balance_ht += $total_ht;
950  $balance_ttc += $total_ttc;
951  }
952 
953  print '<tr class="oddeven">';
954  // Module
955  print '<td class="left">'.$name.'</td>';
956  // Nb
957  print '<td class="right">'.$i.'</td>';
958  // Amount HT
959  print '<td class="right">';
960  if ($key == 'intervention' && !$margin) {
961  print '<span class="opacitymedium">'.$form->textwithpicto($langs->trans("NA"), $langs->trans("AmountOfInteventionNotIncludedByDefault")).'</span>';
962  } else {
963  if ($key == 'propal') {
964  print '<span class="opacitymedium">'.$form->textwithpicto('', $langs->trans("SignedOnly")).'</span>';
965  }
966  print price($total_ht);
967  }
968  print '</td>';
969  // Amount TTC
970  print '<td class="right">';
971  if ($key == 'intervention' && !$margin) {
972  print '<span class="opacitymedium">'.$form->textwithpicto($langs->trans("NA"), $langs->trans("AmountOfInteventionNotIncludedByDefault")).'</span>';
973  } else {
974  if ($key == 'propal') {
975  print '<span class="opacitymedium">'.$form->textwithpicto('', $langs->trans("SignedOnly")).'</span>';
976  }
977  print price($total_ttc);
978  }
979  print '</td>';
980  print '</tr>';
981  }
982  }
983 }
984 // and the final balance
985 print '<tr class="liste_total">';
986 print '<td class="right" colspan="2">'.$langs->trans("Profit").'</td>';
987 print '<td class="right">'.price(price2num($balance_ht, 'MT')).'</td>';
988 print '<td class="right">'.price(price2num($balance_ttc, 'MT')).'</td>';
989 print '</tr>';
990 
991 // and the cost per attendee
992 if ($object->usage_organize_event) {
993  require_once DOL_DOCUMENT_ROOT.'/eventorganization/class/conferenceorboothattendee.class.php';
994  $conforboothattendee = new ConferenceOrBoothAttendee($db);
995  $result = $conforboothattendee->fetchAll('', '', 0, 0, '(t.fk_project:=:'.((int) $object->id).') AND (t.status:=:'.ConferenceOrBoothAttendee::STATUS_VALIDATED.')');
996 
997  if (!is_array($result) && $result < 0) {
998  setEventMessages($conforboothattendee->error, $conforboothattendee->errors, 'errors');
999  } else {
1000  $nbAttendees = count($result);
1001  }
1002 
1003  if ($nbAttendees >= 2) {
1004  $costperattendee_ht = $balance_ht / $nbAttendees;
1005  $costperattendee_ttc = $balance_ttc / $nbAttendees;
1006  print '<tr class="liste_total">';
1007  print '<td class="right" colspan="2">'.$langs->trans("ProfitPerValidatedAttendee").'</td>';
1008  print '<td class="right">'.price(price2num($costperattendee_ht, 'MT')).'</td>';
1009  print '<td class="right">'.price(price2num($costperattendee_ttc, 'MT')).'</td>';
1010  print '</tr>';
1011  }
1012 }
1013 
1014 // and the margin (profit / revenues)
1015 if ($total_revenue_ht) {
1016  print '<tr class="liste_total">';
1017  print '<td class="right" colspan="2">'.$langs->trans("Margin").'</td>';
1018  print '<td class="right">'.round(100 * $balance_ht / $total_revenue_ht, 1).'%</td>';
1019  print '<td class="right"></td>';
1020  print '</tr>';
1021 }
1022 
1023 print "</table>";
1024 
1025 
1026 print '<br><br>';
1027 print '<br>';
1028 
1029 
1030 $total_time = 0;
1031 
1032 // Detail
1033 foreach ($listofreferent as $key => $value) {
1034  $parameters = array(
1035  'key' => $key,
1036  'value' => & $value,
1037  'dates' => $dates,
1038  'datee' => $datee
1039  );
1040  $reshook = $hookmanager->executeHooks('printOverviewDetail', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1041  if ($reshook < 0) {
1042  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1043  } elseif ($reshook > 0) {
1044  print $hookmanager->resPrint;
1045  continue;
1046  }
1047 
1048  $title = $value['title'];
1049  $classname = $value['class'];
1050  $tablename = $value['table'];
1051  $datefieldname = $value['datefieldname'];
1052  $qualified = $value['test'];
1053  $urlnew = empty($value['urlnew']) ? '' : $value['urlnew'];
1054  $buttonnew = empty($value['buttonnew']) ? '' : $value['buttonnew'];
1055  $testnew = empty($value['testnew']) ? '' : $value['testnew'];
1056  $project_field = empty($value['project_field']) ? '' : $value['project_field'];
1057  $nototal = empty($value['nototal']) ? 0 : 1;
1058 
1059  $exclude_select_element = array('payment_various');
1060  if (!empty($value['exclude_select_element'])) {
1061  $exclude_select_element[] = $value['exclude_select_element'];
1062  }
1063 
1064  if ($qualified) {
1065  // If we want the project task array to have details of users
1066  //if ($key == 'project_task') $key = 'project_task_time';
1067 
1068  $element = new $classname($db);
1069 
1070  $addform = '';
1071 
1072  $idtofilterthirdparty = 0;
1073  $array_of_element_linkable_with_different_thirdparty = array('facture_fourn', 'commande_fournisseur');
1074  if (!in_array($tablename, $array_of_element_linkable_with_different_thirdparty)) {
1075  $idtofilterthirdparty = empty($object->thirdparty->id) ? 0 : $object->thirdparty->id;
1076  if (getDolGlobalString('PROJECT_OTHER_THIRDPARTY_ID_TO_ADD_ELEMENTS')) {
1077  $idtofilterthirdparty .= ',' . getDolGlobalString('PROJECT_OTHER_THIRDPARTY_ID_TO_ADD_ELEMENTS');
1078  }
1079  }
1080 
1081  $elementarray = $object->get_element_list($key, $tablename, $datefieldname, $dates, $datee, !empty($project_field) ? $project_field : 'fk_projet');
1082 
1083 
1084  if (!getDolGlobalString('PROJECT_LINK_ON_OVERWIEW_DISABLED') && $idtofilterthirdparty && !in_array($tablename, $exclude_select_element)) {
1085  $selectList = $formproject->select_element($tablename, $idtofilterthirdparty, 'minwidth300 minwidth75imp', -2, empty($project_field) ? 'fk_projet' : $project_field, $langs->trans("SelectElement"));
1086  if ($selectList < 0) {
1087  setEventMessages($formproject->error, $formproject->errors, 'errors');
1088  } elseif ($selectList) {
1089  // Define form with the combo list of elements to link
1090  $addform .= '<div class="inline-block valignmiddle">';
1091  $addform .= '<form action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
1092  $addform .= '<input type="hidden" name="token" value="'.newToken().'">';
1093  $addform .= '<input type="hidden" name="tablename" value="'.$tablename.'">';
1094  $addform .= '<input type="hidden" name="action" value="addelement">';
1095  $addform .= '<input type="hidden" name="datesrfc" value="'.dol_print_date($dates, 'dayhourrfc').'">';
1096  $addform .= '<input type="hidden" name="dateerfc" value="'.dol_print_date($datee, 'dayhourrfc').'">';
1097  $addform .= '<table><tr>';
1098  //$addform .= '<td><span class="hideonsmartphone opacitymedium">'.$langs->trans("SelectElement").'</span></td>';
1099  $addform .= '<td>'.$selectList.'</td>';
1100  $addform .= '<td><input type="submit" class="button button-linkto smallpaddingimp" value="'.dol_escape_htmltag($langs->trans("LinkToElementShort")).'"></td>';
1101  $addform .= '</tr></table>';
1102  $addform .= '</form>';
1103  $addform .= '</div>';
1104  }
1105  }
1106  if (!getDolGlobalString('PROJECT_CREATE_ON_OVERVIEW_DISABLED') && $urlnew) {
1107  $addform .= '<div class="inline-block valignmiddle">';
1108  if ($testnew) {
1109  $addform .= '<a class="buttonxxx marginleftonly" href="'.$urlnew.'" title="'.dol_escape_htmltag($langs->trans($buttonnew)).'"><span class="fa fa-plus-circle valignmiddle paddingleft"></span></a>';
1110  } elseif (!getDolGlobalString('MAIN_BUTTON_HIDE_UNAUTHORIZED')) {
1111  $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>';
1112  }
1113  $addform .= '<div>';
1114  }
1115 
1116  if (is_array($elementarray) && count($elementarray) > 0 && $key == "order_supplier") {
1117  $addform = '<div class="inline-block valignmiddle"><a id="btnShow" class="buttonxxx marginleftonly" href="#" onClick="return false;">
1118  <span id="textBtnShow" class="valignmiddle text-plus-circle hideonsmartphone">'.$langs->trans("CanceledShown").'</span><span id="minus-circle" class="fa fa-eye valignmiddle paddingleft"></span>
1119  </a>
1120  <script>
1121  $("#btnShow").on("click", function () {
1122  console.log("We click to show or hide the canceled lines");
1123  var attr = $(this).attr("data-canceledarehidden");
1124  if (typeof attr !== "undefined" && attr !== false) {
1125  console.log("Show canceled");
1126  $(".tr_canceled").show();
1127  $("#textBtnShow").text("'.dol_escape_js($langs->transnoentitiesnoconv("CanceledShown")).'");
1128  $("#btnShow").removeAttr("data-canceledarehidden");
1129  $("#minus-circle").removeClass("fa-eye-slash").addClass("fa-eye");
1130  } else {
1131  console.log("Hide canceled");
1132  $(".tr_canceled").hide();
1133  $("#textBtnShow").text("'.dol_escape_js($langs->transnoentitiesnoconv("CanceledHidden")).'");
1134  $("#btnShow").attr("data-canceledarehidden", 1);
1135  $("#minus-circle").removeClass("fa-eye").addClass("fa-eye-slash");
1136  }
1137  });
1138  </script></div> '.$addform;
1139  }
1140 
1141  print load_fiche_titre($langs->trans($title), $addform, '');
1142 
1143  print "\n".'<!-- Table for tablename = '.$tablename.' -->'."\n";
1144  print '<div class="div-table-responsive">';
1145  print '<table class="noborder centpercent">';
1146 
1147  print '<tr class="liste_titre">';
1148  // Remove link column
1149  print '<td style="width: 24px"></td>';
1150  // Ref
1151  print '<td'.(($tablename != 'actioncomm' && $tablename != 'projet_task') ? ' style="width: 200px"' : '').'>'.$langs->trans("Ref").'</td>';
1152  // Product and qty on stock_movement
1153  if ('MouvementStock' == $classname) {
1154  print '<td style="width: 200px">'.$langs->trans("Product").'</td>';
1155  print '<td style="width: 50px">'.$langs->trans("Qty").'</td>';
1156  }
1157  // Date
1158  print '<td'.(($tablename != 'actioncomm' && $tablename != 'projet_task') ? ' style="width: 200px"' : '').' class="center">';
1159  if (in_array($tablename, array('projet_task'))) {
1160  print $langs->trans("TimeSpent");
1161  }
1162  if (!in_array($tablename, array('projet_task'))) {
1163  print $langs->trans("Date");
1164  }
1165  print '</td>';
1166  // Thirdparty or user
1167  print '<td>';
1168  if (in_array($tablename, array('projet_task')) && $key == 'project_task') {
1169  print ''; // if $key == 'project_task', we don't want details per user
1170  } elseif (in_array($tablename, array('payment_various'))) {
1171  print ''; // if $key == 'payment_various', we don't have any thirdparty
1172  } elseif (in_array($tablename, array('expensereport_det', 'don', 'projet_task', 'stock_mouvement', 'salary'))) {
1173  print $langs->trans("User");
1174  } else {
1175  print $langs->trans("ThirdParty");
1176  }
1177  print '</td>';
1178  // Duration of intervention
1179  if ($tablename == 'fichinter') {
1180  print '<td>';
1181  print $langs->trans("TotalDuration");
1182  $total_duration = 0;
1183  print '</td>';
1184  }
1185  // Amount HT
1186  //if (empty($value['disableamount']) && ! in_array($tablename, array('projet_task'))) print '<td class="right" width="120">'.$langs->trans("AmountHT").'</td>';
1187  //elseif (empty($value['disableamount']) && in_array($tablename, array('projet_task'))) print '<td class="right" width="120">'.$langs->trans("Amount").'</td>';
1188  if ($key == 'loan') {
1189  print '<td class="right" width="120">'.$langs->trans("LoanCapital").'</td>';
1190  } elseif (empty($value['disableamount'])) {
1191  print '<td class="right" width="120">'.$langs->trans("AmountHT").'</td>';
1192  } else {
1193  print '<td width="120"></td>';
1194  }
1195  // Amount TTC
1196  //if (empty($value['disableamount']) && ! in_array($tablename, array('projet_task'))) print '<td class="right" width="120">'.$langs->trans("AmountTTC").'</td>';
1197  if ($key == 'loan') {
1198  print '<td class="right" width="120">'.$langs->trans("RemainderToPay").'</td>';
1199  } elseif (empty($value['disableamount'])) {
1200  print '<td class="right" width="120">'.$langs->trans("AmountTTC").'</td>';
1201  } else {
1202  print '<td width="120"></td>';
1203  }
1204  // Status
1205  if (in_array($tablename, array('projet_task'))) {
1206  print '<td class="right" width="200">'.$langs->trans("ProgressDeclared").'</td>';
1207  } else {
1208  print '<td class="right" width="200">'.$langs->trans("Status").'</td>';
1209  }
1210  print '</tr>';
1211 
1212  if (is_array($elementarray) && count($elementarray) > 0) {
1213  $total_ht = 0;
1214  $total_ttc = 0;
1215 
1216  $total_ht_by_third = 0;
1217  $total_ttc_by_third = 0;
1218 
1219  $saved_third_id = 0;
1220  $breakline = '';
1221 
1222  if (canApplySubtotalOn($tablename)) {
1223  // Sort
1224  $elementarray = sortElementsByClientName($elementarray);
1225  }
1226 
1227  $num = count($elementarray);
1228  for ($i = 0; $i < $num; $i++) {
1229  $tmp = explode('_', $elementarray[$i]);
1230  $idofelement = $tmp[0];
1231  $idofelementuser = isset($tmp[1]) ? $tmp[1] : "";
1232 
1233  $element->fetch($idofelement);
1234  if ($idofelementuser) {
1235  $elementuser->fetch($idofelementuser);
1236  }
1237 
1238  // Special cases
1239  if ($tablename != 'expensereport_det') {
1240  if (method_exists($element, 'fetch_thirdparty')) {
1241  $element->fetch_thirdparty();
1242  }
1243  } else {
1244  $expensereport = new ExpenseReport($db);
1245  $expensereport->fetch($element->fk_expensereport);
1246  }
1247 
1248  //print 'xxx'.$tablename.'yyy'.$classname;
1249 
1250  if ($breakline && $saved_third_id != $element->thirdparty->id) {
1251  print $breakline;
1252 
1253  $saved_third_id = $element->thirdparty->id;
1254  $breakline = '';
1255 
1256  $total_ht_by_third = 0;
1257  $total_ttc_by_third = 0;
1258  }
1259 
1260  $saved_third_id = empty($element->thirdparty->id) ? 0 : $element->thirdparty->id;
1261 
1262  $qualifiedfortotal = true;
1263  if ($key == 'invoice') {
1264  if (!empty($element->close_code) && $element->close_code == 'replaced') {
1265  $qualifiedfortotal = false; // Replacement invoice, do not include into total
1266  }
1267  } elseif ($key == 'order_supplier' && $element->status == 7) {
1268  $qualifiedfortotal = false; // It makes no sense to include canceled orders in the total
1269  }
1270 
1271  if ($key == "order_supplier" && $element->status == 7) {
1272  print '<tr class="oddeven tr_canceled" style=display:none>';
1273  } else {
1274  print '<tr class="oddeven" >';
1275  }
1276 
1277 
1278  // Remove link
1279  print '<td style="width: 24px">';
1280  if ($tablename != 'projet_task' && $tablename != 'stock_mouvement') {
1281  if (!getDolGlobalString('PROJECT_DISABLE_UNLINK_FROM_OVERVIEW') || $user->admin) { // PROJECT_DISABLE_UNLINK_FROM_OVERVIEW is empty by default, so this test true
1282  print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=unlink&tablename='.$tablename.'&elementselect='.$element->id.($project_field ? '&projectfield='.$project_field : '').'" class="reposition">';
1283  print img_picto($langs->trans('Unlink'), 'unlink');
1284  print '</a>';
1285  }
1286  }
1287  print "</td>\n";
1288 
1289  // Ref
1290  print '<td class="left nowraponall tdoverflowmax250">';
1291  if ($tablename == 'expensereport_det') {
1292  print $expensereport->getNomUrl(1);
1293  } else {
1294  // Show ref with link
1295  if ($element instanceof Task) {
1296  print $element->getNomUrl(1, 'withproject', 'time');
1297  print ' - '.dol_trunc($element->label, 48);
1298  } elseif ($key == 'loan') {
1299  print $element->getNomUrl(1);
1300  print ' - '.dol_trunc($element->label, 48);
1301  } else {
1302  print $element->getNomUrl(1);
1303  }
1304 
1305  $element_doc = $element->element;
1306  $filename = dol_sanitizeFileName($element->ref);
1307  if (!empty($conf->$element_doc)) {
1308  $confelementdoc = $conf->$element_doc;
1309  $filedir = $confelementdoc->multidir_output[$element->entity].'/'.dol_sanitizeFileName($element->ref);
1310  } else {
1311  $filedir = '';
1312  }
1313 
1314  if ($element_doc === 'order_supplier') {
1315  $element_doc = 'commande_fournisseur';
1316  $filedir = $conf->fournisseur->commande->multidir_output[$element->entity].'/'.dol_sanitizeFileName($element->ref);
1317  } elseif ($element_doc === 'invoice_supplier') {
1318  $element_doc = 'facture_fournisseur';
1319  $filename = get_exdir($element->id, 2, 0, 0, $element, 'product').dol_sanitizeFileName($element->ref);
1320  $filedir = $conf->fournisseur->facture->multidir_output[$element->entity].'/'.get_exdir($element->id, 2, 0, 0, $element, 'invoice_supplier').dol_sanitizeFileName($element->ref);
1321  }
1322 
1323  print '<div class="inline-block valignmiddle">';
1324  if ($filedir) {
1325  print $formfile->getDocumentsLink($element_doc, $filename, $filedir);
1326  }
1327  print '</div>';
1328 
1329  // Show supplier ref
1330  if (!empty($element->ref_supplier)) {
1331  print ' - '.$element->ref_supplier;
1332  }
1333  // Show customer ref
1334  if (!empty($element->ref_customer)) {
1335  print ' - '.$element->ref_customer;
1336  }
1337  // Compatibility propale
1338  if (empty($element->ref_customer) && !empty($element->ref_client)) {
1339  print ' - '.$element->ref_client;
1340  }
1341  }
1342  print "</td>\n";
1343  // Product and qty on stock movement
1344  if ('MouvementStock' == $classname) {
1345  $mvsProd = new Product($element->db);
1346  $mvsProd->fetch($element->product_id);
1347  print '<td>'.$mvsProd->getNomUrl(1).'</td>';
1348  print '<td>'.$element->qty.'</td>';
1349  }
1350  // Date or TimeSpent
1351  $date = '';
1352  $total_time_by_line = null;
1353  if ($tablename == 'expensereport_det') {
1354  $date = $element->date; // No draft status on lines
1355  } elseif ($tablename == 'stock_mouvement') {
1356  $date = $element->datem;
1357  } elseif ($tablename == 'salary') {
1358  $date = $element->datesp;
1359  } elseif ($tablename == 'payment_various') {
1360  $date = $element->datev;
1361  } elseif ($tablename == 'chargesociales') {
1362  $date = $element->date_ech;
1363  } elseif (!empty($element->status) || !empty($element->statut) || !empty($element->fk_status)) {
1364  if ($tablename == 'don') {
1365  $date = $element->datedon;
1366  }
1367  if ($tablename == 'commande_fournisseur' || $tablename == 'supplier_order') {
1368  $date = ($element->date_commande ? $element->date_commande : $element->date_valid);
1369  } elseif ($tablename == 'supplier_proposal') {
1370  $date = $element->date_validation; // There is no other date for this
1371  } elseif ($tablename == 'fichinter') {
1372  $date = $element->datev; // There is no other date for this
1373  } elseif ($tablename == 'projet_task') {
1374  $date = ''; // We show no date. Showing date of beginning of task make user think it is date of time consumed
1375  } else {
1376  $date = $element->date; // invoice, ...
1377  if (empty($date)) {
1378  $date = $element->date_contrat;
1379  }
1380  if (empty($date)) {
1381  $date = $element->datev;
1382  }
1383  if (empty($date) && !empty($datefieldname)) {
1384  $date = $element->$datefieldname;
1385  }
1386  }
1387  } elseif ($key == 'loan') {
1388  $date = $element->datestart;
1389  }
1390 
1391  print '<td class="center">';
1392  if ($tablename == 'actioncomm') {
1393  print dol_print_date($element->datep, 'dayhour');
1394  if ($element->datef && $element->datef > $element->datep) {
1395  print " - ".dol_print_date($element->datef, 'dayhour');
1396  }
1397  } elseif (in_array($tablename, array('projet_task'))) {
1398  $tmpprojtime = $element->getSumOfAmount($idofelementuser ? $elementuser : '', $dates, $datee); // $element is a task. $elementuser may be empty
1399  print '<a href="'.DOL_URL_ROOT.'/projet/tasks/time.php?id='.$idofelement.'&withproject=1">';
1400  print convertSecondToTime($tmpprojtime['nbseconds'], 'allhourmin');
1401  print '</a>';
1402  $total_time_by_line = $tmpprojtime['nbseconds'];
1403  } else {
1404  print dol_print_date($date, 'day');
1405  }
1406  print '</td>';
1407 
1408  // Third party or user
1409  print '<td class="tdoverflowmax150">';
1410  if (is_object($element->thirdparty)) {
1411  print $element->thirdparty->getNomUrl(1, '', 48);
1412  } elseif ($tablename == 'expensereport_det') {
1413  $tmpuser = new User($db);
1414  $tmpuser->fetch($expensereport->fk_user_author);
1415  print $tmpuser->getNomUrl(1, '', 48);
1416  } elseif ($tablename == 'salary') {
1417  $tmpuser = new User($db);
1418  $tmpuser->fetch($element->fk_user);
1419  print $tmpuser->getNomUrl(1, '', 48);
1420  } elseif ($tablename == 'don' || $tablename == 'stock_mouvement') {
1421  if ($element->fk_user_author > 0) {
1422  $tmpuser2 = new User($db);
1423  $tmpuser2->fetch($element->fk_user_author);
1424  print $tmpuser2->getNomUrl(1, '', 48);
1425  }
1426  } elseif ($tablename == 'projet_task' && $key == 'element_time') { // if $key == 'project_task', we don't want details per user
1427  print $elementuser->getNomUrl(1);
1428  }
1429  print '</td>';
1430 
1431  // Add duration and store it in counter for fichinter
1432  if ($tablename == 'fichinter') {
1433  print '<td>';
1434  print convertSecondToTime($element->duration, 'all', $conf->global->MAIN_DURATION_OF_WORKDAY);
1435  $total_duration += $element->duration;
1436  print '</td>';
1437  }
1438 
1439  // Amount without tax
1440  $warning = '';
1441  if (empty($value['disableamount'])) {
1442  $total_ht_by_line = null;
1443  $othermessage = '';
1444  if ($tablename == 'don' || $tablename == 'chargesociales' || $tablename == 'payment_various' || $tablename == 'salary') {
1445  $total_ht_by_line = $element->amount;
1446  } elseif ($tablename == 'fichinter') {
1447  $total_ht_by_line = $element->getAmount();
1448  } elseif ($tablename == 'stock_mouvement') {
1449  $total_ht_by_line = $element->price * abs($element->qty);
1450  } elseif (in_array($tablename, array('projet_task'))) {
1451  if (isModEnabled('salaries')) {
1452  // TODO Permission to read daily rate to show value
1453  $total_ht_by_line = price2num($tmpprojtime['amount'], 'MT');
1454  if ($tmpprojtime['nblinesnull'] > 0) {
1455  $langs->load("errors");
1456  $warning = $langs->trans("WarningSomeLinesWithNullHourlyRate", $conf->currency);
1457  }
1458  } else {
1459  $othermessage = $form->textwithpicto($langs->trans("NotAvailable"), $langs->trans("ModuleSalaryToDefineHourlyRateMustBeEnabled"));
1460  }
1461  } elseif ($key == 'loan') {
1462  $total_ht_by_line = $element->capital;
1463  } else {
1464  $total_ht_by_line = $element->total_ht;
1465  }
1466 
1467  // Change sign of $total_ht_by_line and $total_ttc_by_line for some cases
1468  if ($tablename == 'payment_various') {
1469  if ($element->sens == 0) {
1470  $total_ht_by_line = -$total_ht_by_line;
1471  }
1472  }
1473 
1474  print '<td class="right">';
1475  if ($othermessage) {
1476  print $othermessage;
1477  }
1478  if (isset($total_ht_by_line)) {
1479  if (!$qualifiedfortotal) {
1480  print '<strike>';
1481  }
1482  print '<span class="amount">'.price($total_ht_by_line).'</span>';
1483  if (!$qualifiedfortotal) {
1484  print '</strike>';
1485  }
1486  }
1487  if ($warning) {
1488  print ' '.img_warning($warning);
1489  }
1490  print '</td>';
1491  } else {
1492  print '<td></td>';
1493  }
1494 
1495  // Amount inc tax
1496  if (empty($value['disableamount'])) {
1497  $total_ttc_by_line = null;
1498  if ($tablename == 'don' || $tablename == 'chargesociales' || $tablename == 'payment_various' || $tablename == 'salary') {
1499  $total_ttc_by_line = $element->amount;
1500  } elseif ($tablename == 'fichinter') {
1501  $total_ttc_by_line = $element->getAmount();
1502  } elseif ($tablename == 'stock_mouvement') {
1503  $total_ttc_by_line = $element->price * abs($element->qty);
1504  } elseif ($tablename == 'projet_task') {
1505  if (isModEnabled('salaries')) {
1506  // TODO Permission to read daily rate
1507  $defaultvat = get_default_tva($mysoc, $mysoc);
1508  $total_ttc_by_line = price2num($total_ht_by_line * (1 + ($defaultvat / 100)), 'MT');
1509  } else {
1510  $othermessage = $form->textwithpicto($langs->trans("NotAvailable"), $langs->trans("ModuleSalaryToDefineHourlyRateMustBeEnabled"));
1511  }
1512  } elseif ($key == 'loan') {
1513  $total_ttc_by_line = $element->capital - $element->getSumPayment();
1514  } else {
1515  $total_ttc_by_line = $element->total_ttc;
1516  }
1517 
1518  // Change sign of $total_ht_by_line and $total_ttc_by_line for some cases
1519  if ($tablename == 'payment_various') {
1520  if ($element->sens == 0) {
1521  $total_ttc_by_line = -$total_ttc_by_line;
1522  }
1523  }
1524 
1525  print '<td class="right">';
1526  if ($othermessage) {
1527  print $othermessage;
1528  }
1529  if (isset($total_ttc_by_line)) {
1530  if (!$qualifiedfortotal) {
1531  print '<strike>';
1532  }
1533  print '<span class="amount">'.price($total_ttc_by_line).'</span>';
1534  if (!$qualifiedfortotal) {
1535  print '</strike>';
1536  }
1537  }
1538  if ($warning) {
1539  print ' '.img_warning($warning);
1540  }
1541  print '</td>';
1542  } else {
1543  print '<td></td>';
1544  }
1545 
1546  // Status
1547  print '<td class="right">';
1548  if ($tablename == 'expensereport_det') {
1549  print $expensereport->getLibStatut(5);
1550  } elseif ($element instanceof CommonInvoice) {
1551  //This applies for Facture and FactureFournisseur
1552  print $element->getLibStatut(5, $element->getSommePaiement());
1553  } elseif ($element instanceof Task) {
1554  if ($element->progress != '') {
1555  print $element->progress.' %';
1556  }
1557  } elseif ($tablename == 'stock_mouvement') {
1558  print $element->getLibStatut(3);
1559  } else {
1560  print $element->getLibStatut(5);
1561  }
1562  print '</td>';
1563 
1564  print '</tr>';
1565 
1566  if ($qualifiedfortotal) {
1567  $total_ht = $total_ht + $total_ht_by_line;
1568  $total_ttc = $total_ttc + $total_ttc_by_line;
1569 
1570  $total_ht_by_third += $total_ht_by_line;
1571  $total_ttc_by_third += $total_ttc_by_line;
1572 
1573  if (!isset($total_time)) {
1574  $total_time = $total_time_by_line;
1575  } else {
1576  $total_time += $total_time_by_line;
1577  }
1578  }
1579 
1580  if (canApplySubtotalOn($tablename)) {
1581  $breakline = '<tr class="liste_total liste_sub_total">';
1582  $breakline .= '<td colspan="2">';
1583  $breakline .= '</td>';
1584  $breakline .= '<td>';
1585  $breakline .= '</td>';
1586  $breakline .= '<td class="right">';
1587  $breakline .= $langs->trans('SubTotal').' : ';
1588  if (is_object($element->thirdparty)) {
1589  $breakline .= $element->thirdparty->getNomUrl(0, '', 48);
1590  }
1591  $breakline .= '</td>';
1592  $breakline .= '<td class="right">'.price($total_ht_by_third).'</td>';
1593  $breakline .= '<td class="right">'.price($total_ttc_by_third).'</td>';
1594  $breakline .= '<td></td>';
1595  $breakline .= '</tr>';
1596  }
1597 
1598  //var_dump($element->thirdparty->name.' - '.$saved_third_id.' - '.$element->thirdparty->id);
1599  }
1600 
1601  if ($breakline) {
1602  print $breakline;
1603  }
1604 
1605  // Total
1606  if (empty($nototal)) {
1607  $colspan = 4;
1608  if (in_array($tablename, array('projet_task'))) {
1609  $colspan = 2;
1610  }
1611 
1612  print '<tr class="liste_total"><td colspan="'.$colspan.'">'.$langs->trans("Number").': '.$i.'</td>';
1613  if (in_array($tablename, array('projet_task'))) {
1614  print '<td class="center">';
1615  print convertSecondToTime($total_time, 'allhourmin');
1616  print '</td>';
1617  print '<td>';
1618  print '</td>';
1619  }
1620  //if (empty($value['disableamount']) && ! in_array($tablename, array('projet_task'))) print '<td class="right" width="100">'.$langs->trans("TotalHT").' : '.price($total_ht).'</td>';
1621  //elseif (empty($value['disableamount']) && in_array($tablename, array('projet_task'))) print '<td class="right" width="100">'.$langs->trans("Total").' : '.price($total_ht).'</td>';
1622  // If fichinter add the total_duration
1623  if ($tablename == 'fichinter') {
1624  print '<td class="left">'.convertSecondToTime($total_duration, 'all', $conf->global->MAIN_DURATION_OF_WORKDAY).'</td>';
1625  }
1626  print '<td class="right">';
1627  if (empty($value['disableamount'])) {
1628  if ($key == 'loan') {
1629  print $langs->trans("Total").' '.$langs->trans("LoanCapital").' : '.price($total_ttc);
1630  } elseif ($tablename != 'projet_task' || isModEnabled('salaries')) {
1631  print ''.$langs->trans("TotalHT").' : '.price($total_ht);
1632  }
1633  }
1634  print '</td>';
1635  //if (empty($value['disableamount']) && ! in_array($tablename, array('projet_task'))) print '<td class="right" width="100">'.$langs->trans("TotalTTC").' : '.price($total_ttc).'</td>';
1636  //elseif (empty($value['disableamount']) && in_array($tablename, array('projet_task'))) print '<td class="right" width="100"></td>';
1637  print '<td class="right">';
1638  if (empty($value['disableamount'])) {
1639  if ($key == 'loan') {
1640  print $langs->trans("Total").' '.$langs->trans("RemainderToPay").' : '.price($total_ttc);
1641  } elseif ($tablename != 'projet_task' || isModEnabled('salaries')) {
1642  print $langs->trans("TotalTTC").' : '.price($total_ttc);
1643  }
1644  }
1645  print '</td>';
1646  print '<td>&nbsp;</td>';
1647  print '</tr>';
1648  }
1649  } else {
1650  if (!is_array($elementarray)) { // error
1651  print '<tr><td>'.$elementarray.'</td></tr>';
1652  } else {
1653  $colspan = 7;
1654  if ($tablename == 'fichinter') {
1655  $colspan++;
1656  }
1657  print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("None").'</td></tr>';
1658  }
1659  }
1660  print "</table>";
1661  print '</div>';
1662  print "<br>\n";
1663  }
1664 }
1665 
1666 // Enhance with select2
1667 if ($conf->use_javascript_ajax) {
1668  include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php';
1669  $comboenhancement = ajax_combobox('.elementselect');
1670 
1671  print $comboenhancement;
1672 }
1673 
1674 // End of page
1675 llxFooter();
1676 $db->close();
1677 
1678 
1679 
1686 function canApplySubtotalOn($tablename)
1687 {
1688  global $conf;
1689 
1690  if (!getDolGlobalString('PROJECT_ADD_SUBTOTAL_LINES')) {
1691  return false;
1692  }
1693  return in_array($tablename, array('facture_fourn', 'commande_fournisseur'));
1694 }
1695 
1702 function sortElementsByClientName($elementarray)
1703 {
1704  global $db, $classname;
1705 
1706  $element = new $classname($db);
1707 
1708  $clientname = array();
1709  foreach ($elementarray as $key => $id) { // id = id of object
1710  if (empty($clientname[$id])) {
1711  $element->fetch($id);
1712  $element->fetch_thirdparty();
1713 
1714  $clientname[$id] = $element->thirdparty->name;
1715  }
1716  }
1717 
1718  //var_dump($clientname);
1719  asort($clientname); // sort on name
1720 
1721  $elementarray = array();
1722  foreach ($clientname as $id => $name) {
1723  $elementarray[] = $id;
1724  }
1725 
1726  return $elementarray;
1727 }
if($user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition: card.php:58
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:456
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
Definition: wrapper.php:55
llxFooter()
Empty footer.
Definition: wrapper.php:69
Superclass for invoices 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.
Definition: task.class.php:41
Class to manage Dolibarr users.
Definition: user.class.php:50
dol_get_first_day($year, $month=1, $gm=false)
Return GMT time for first day of a month or year.
Definition: date.lib.php:595
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:242
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:427
sortElementsByClientName($elementarray)
sortElementsByClientName
Definition: element.php:1702
canApplySubtotalOn($tablename)
Return if we should do a group by customer with sub-total.
Definition: element.php:1686
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.
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning 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.
setEventMessage($mesgs, $style='mesgs', $noduplicate=0)
Set event message in dol_events session object.
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.
dol_escape_js($stringtoescape, $mode=0, $noescapebackslashn=0)
Returns text escaped for inclusion into javascript code.
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).
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
dol_htmlentitiesbr($stringtoencode, $nl2brmode=0, $pagecodefrom='UTF-8', $removelasteolbr=1)
This function is called to encode a string into a HTML string but differs from htmlentities because a...
getDolGlobalString($key, $default='')
Return 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.
Definition: project.lib.php:40
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.