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