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