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