dolibarr 20.0.4
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 various payments
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 // Change sign of $total_ht_by_line and $total_ttc_by_line for supplier proposal and supplier order
931 if ($tablename == 'commande_fournisseur' || $tablename == 'supplier_proposal') {
932 $total_ht_by_line = -$total_ht_by_line;
933 $total_ttc_by_line = -$total_ttc_by_line;
934 }
935
936 // Add total if we have to
937 if ($qualifiedfortotal) {
938 $total_ht = $total_ht + $total_ht_by_line;
939 $total_ttc = $total_ttc + $total_ttc_by_line;
940 }
941 }
942
943 // Each element with at least one line is output
944
945 // Calculate margin
946 if ($margin) {
947 if ($margin === 'add') {
948 $total_revenue_ht += $total_ht;
949 }
950
951 if ($margin === "minus") { // Revert sign
952 $total_ht = -$total_ht;
953 $total_ttc = -$total_ttc;
954 }
955
956 $balance_ht += $total_ht;
957 $balance_ttc += $total_ttc;
958 }
959
960 print '<tr class="oddeven">';
961 // Module
962 print '<td class="left">'.$name.'</td>';
963 // Nb
964 print '<td class="right">'.$i.'</td>';
965 // Amount HT
966 print '<td class="right">';
967 if ($key == 'intervention' && !$margin) {
968 print '<span class="opacitymedium">'.$form->textwithpicto($langs->trans("NA"), $langs->trans("AmountOfInteventionNotIncludedByDefault")).'</span>';
969 } else {
970 if ($key == 'propal') {
971 print '<span class="opacitymedium">'.$form->textwithpicto('', $langs->trans("SignedOnly")).'</span>';
972 }
973 print price($total_ht);
974 }
975 print '</td>';
976 // Amount TTC
977 print '<td class="right">';
978 if ($key == 'intervention' && !$margin) {
979 print '<span class="opacitymedium">'.$form->textwithpicto($langs->trans("NA"), $langs->trans("AmountOfInteventionNotIncludedByDefault")).'</span>';
980 } else {
981 if ($key == 'propal') {
982 print '<span class="opacitymedium">'.$form->textwithpicto('', $langs->trans("SignedOnly")).'</span>';
983 }
984 print price($total_ttc);
985 }
986 print '</td>';
987 print '</tr>';
988 }
989 }
990}
991// and the final balance
992print '<tr class="liste_total">';
993print '<td class="right" colspan="2">'.$langs->trans("Profit").'</td>';
994print '<td class="right">'.price(price2num($balance_ht, 'MT')).'</td>';
995print '<td class="right">'.price(price2num($balance_ttc, 'MT')).'</td>';
996print '</tr>';
997
998// and the cost per attendee
999if ($object->usage_organize_event) {
1000 require_once DOL_DOCUMENT_ROOT.'/eventorganization/class/conferenceorboothattendee.class.php';
1001 $conforboothattendee = new ConferenceOrBoothAttendee($db);
1002 $result = $conforboothattendee->fetchAll('', '', 0, 0, '(t.fk_project:=:'.((int) $object->id).') AND (t.status:=:'.ConferenceOrBoothAttendee::STATUS_VALIDATED.')');
1003
1004 if (!is_array($result) && $result < 0) {
1005 setEventMessages($conforboothattendee->error, $conforboothattendee->errors, 'errors');
1006 } else {
1007 $nbAttendees = count($result);
1008 }
1009
1010 if ($nbAttendees >= 2) {
1011 $costperattendee_ht = $balance_ht / $nbAttendees;
1012 $costperattendee_ttc = $balance_ttc / $nbAttendees;
1013 print '<tr class="liste_total">';
1014 print '<td class="right" colspan="2">'.$langs->trans("ProfitPerValidatedAttendee").'</td>';
1015 print '<td class="right">'.price(price2num($costperattendee_ht, 'MT')).'</td>';
1016 print '<td class="right">'.price(price2num($costperattendee_ttc, 'MT')).'</td>';
1017 print '</tr>';
1018 }
1019}
1020
1021// and the margin (profit / revenues)
1022if ($total_revenue_ht) {
1023 print '<tr class="liste_total">';
1024 print '<td class="right" colspan="2">'.$langs->trans("Margin").'</td>';
1025 print '<td class="right">'.round(100 * $balance_ht / $total_revenue_ht, 1).'%</td>';
1026 print '<td class="right"></td>';
1027 print '</tr>';
1028}
1029
1030print "</table>";
1031
1032
1033print '<br><br>';
1034print '<br>';
1035
1036
1037$total_time = 0;
1038
1039// Detail
1040foreach ($listofreferent as $key => $value) {
1041 $parameters = array(
1042 'key' => $key,
1043 'value' => & $value,
1044 'dates' => $dates,
1045 'datee' => $datee
1046 );
1047 $reshook = $hookmanager->executeHooks('printOverviewDetail', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1048 if ($reshook < 0) {
1049 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1050 } elseif ($reshook > 0) {
1051 print $hookmanager->resPrint;
1052 continue;
1053 }
1054
1055 $title = $value['title'];
1056 $classname = $value['class'];
1057 $tablename = $value['table'];
1058 $datefieldname = $value['datefieldname'];
1059 $qualified = $value['test'];
1060 $urlnew = empty($value['urlnew']) ? '' : $value['urlnew'];
1061 $buttonnew = empty($value['buttonnew']) ? '' : $value['buttonnew'];
1062 $testnew = empty($value['testnew']) ? '' : $value['testnew'];
1063 $project_field = empty($value['project_field']) ? '' : $value['project_field'];
1064 $nototal = empty($value['nototal']) ? 0 : 1;
1065
1066 $exclude_select_element = array('payment_various');
1067 if (!empty($value['exclude_select_element'])) {
1068 $exclude_select_element[] = $value['exclude_select_element'];
1069 }
1070
1071 if ($qualified) {
1072 // If we want the project task array to have details of users
1073 //if ($key == 'project_task') $key = 'project_task_time';
1074
1075 $element = new $classname($db);
1076
1077 $addform = '';
1078
1079 $idtofilterthirdparty = 0;
1080 $array_of_element_linkable_with_different_thirdparty = array('facture_fourn', 'commande_fournisseur');
1081 if (!in_array($tablename, $array_of_element_linkable_with_different_thirdparty)) {
1082 $idtofilterthirdparty = empty($object->thirdparty->id) ? 0 : $object->thirdparty->id;
1083 if (getDolGlobalString('PROJECT_OTHER_THIRDPARTY_ID_TO_ADD_ELEMENTS')) {
1084 $idtofilterthirdparty .= ',' . getDolGlobalString('PROJECT_OTHER_THIRDPARTY_ID_TO_ADD_ELEMENTS');
1085 }
1086 }
1087
1088 $elementarray = $object->get_element_list($key, $tablename, $datefieldname, $dates, $datee, !empty($project_field) ? $project_field : 'fk_projet');
1089
1090
1091 if (!getDolGlobalString('PROJECT_LINK_ON_OVERWIEW_DISABLED') && $idtofilterthirdparty && !in_array($tablename, $exclude_select_element)) {
1092 $selectList = $formproject->select_element($tablename, $idtofilterthirdparty, 'minwidth300 minwidth75imp', -2, empty($project_field) ? 'fk_projet' : $project_field, $langs->trans("SelectElement"));
1093 if ($selectList < 0) {
1094 setEventMessages($formproject->error, $formproject->errors, 'errors');
1095 } elseif ($selectList) {
1096 // Define form with the combo list of elements to link
1097 $addform .= '<div class="inline-block valignmiddle">';
1098 $addform .= '<form action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
1099 $addform .= '<input type="hidden" name="token" value="'.newToken().'">';
1100 $addform .= '<input type="hidden" name="tablename" value="'.$tablename.'">';
1101 $addform .= '<input type="hidden" name="action" value="addelement">';
1102 $addform .= '<input type="hidden" name="datesrfc" value="'.dol_print_date($dates, 'dayhourrfc').'">';
1103 $addform .= '<input type="hidden" name="dateerfc" value="'.dol_print_date($datee, 'dayhourrfc').'">';
1104 $addform .= '<table><tr>';
1105 //$addform .= '<td><span class="hideonsmartphone opacitymedium">'.$langs->trans("SelectElement").'</span></td>';
1106 $addform .= '<td>'.$selectList.'</td>';
1107 $addform .= '<td><input type="submit" class="button button-linkto smallpaddingimp" value="'.dol_escape_htmltag($langs->trans("LinkToElementShort")).'"></td>';
1108 $addform .= '</tr></table>';
1109 $addform .= '</form>';
1110 $addform .= '</div>';
1111 }
1112 }
1113 if (!getDolGlobalString('PROJECT_CREATE_ON_OVERVIEW_DISABLED') && $urlnew) {
1114 $addform .= '<div class="inline-block valignmiddle">';
1115 if ($testnew) {
1116 $addform .= '<a class="buttonxxx marginleftonly" href="'.$urlnew.'" title="'.dol_escape_htmltag($langs->trans($buttonnew)).'"><span class="fa fa-plus-circle valignmiddle paddingleft"></span></a>';
1117 } elseif (!getDolGlobalString('MAIN_BUTTON_HIDE_UNAUTHORIZED')) {
1118 $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>';
1119 }
1120 $addform .= '<div>';
1121 }
1122
1123 if (is_array($elementarray) && count($elementarray) > 0 && $key == "order_supplier") {
1124 $addform = '<div class="inline-block valignmiddle"><a id="btnShow" class="buttonxxx marginleftonly" href="#" onClick="return false;">
1125 <span id="textBtnShow" class="valignmiddle text-plus-circle hideonsmartphone">'.$langs->trans("CanceledShown").'</span><span id="minus-circle" class="fa fa-eye valignmiddle paddingleft"></span>
1126 </a>
1127 <script>
1128 $("#btnShow").on("click", function () {
1129 console.log("We click to show or hide the canceled lines");
1130 var attr = $(this).attr("data-canceledarehidden");
1131 if (typeof attr !== "undefined" && attr !== false) {
1132 console.log("Show canceled");
1133 $(".tr_canceled").show();
1134 $("#textBtnShow").text("'.dol_escape_js($langs->transnoentitiesnoconv("CanceledShown")).'");
1135 $("#btnShow").removeAttr("data-canceledarehidden");
1136 $("#minus-circle").removeClass("fa-eye-slash").addClass("fa-eye");
1137 } else {
1138 console.log("Hide canceled");
1139 $(".tr_canceled").hide();
1140 $("#textBtnShow").text("'.dol_escape_js($langs->transnoentitiesnoconv("CanceledHidden")).'");
1141 $("#btnShow").attr("data-canceledarehidden", 1);
1142 $("#minus-circle").removeClass("fa-eye").addClass("fa-eye-slash");
1143 }
1144 });
1145 </script></div> '.$addform;
1146 }
1147
1148 print load_fiche_titre($langs->trans($title), $addform, '');
1149
1150 print "\n".'<!-- Table for tablename = '.$tablename.' -->'."\n";
1151 print '<div class="div-table-responsive">';
1152 print '<table class="noborder centpercent">';
1153
1154 print '<tr class="liste_titre">';
1155 // Remove link column
1156 print '<td style="width: 24px"></td>';
1157 // Ref
1158 print '<td'.(($tablename != 'actioncomm' && $tablename != 'projet_task') ? ' style="width: 200px"' : '').'>'.$langs->trans("Ref").'</td>';
1159 // Product and qty on stock_movement
1160 if ('MouvementStock' == $classname) {
1161 print '<td style="width: 200px">'.$langs->trans("Product").'</td>';
1162 print '<td style="width: 50px">'.$langs->trans("Qty").'</td>';
1163 }
1164 // Date
1165 print '<td'.(($tablename != 'actioncomm' && $tablename != 'projet_task') ? ' style="width: 200px"' : '').' class="center">';
1166 if (in_array($tablename, array('projet_task'))) {
1167 print $langs->trans("TimeSpent");
1168 }
1169 if (!in_array($tablename, array('projet_task'))) {
1170 print $langs->trans("Date");
1171 }
1172 print '</td>';
1173 // Thirdparty or user
1174 print '<td>';
1175 if (in_array($tablename, array('projet_task')) && $key == 'project_task') {
1176 print ''; // if $key == 'project_task', we don't want details per user
1177 } elseif (in_array($tablename, array('payment_various'))) {
1178 print ''; // if $key == 'payment_various', we don't have any thirdparty
1179 } elseif (in_array($tablename, array('expensereport_det', 'don', 'projet_task', 'stock_mouvement', 'salary'))) {
1180 print $langs->trans("User");
1181 } else {
1182 print $langs->trans("ThirdParty");
1183 }
1184 print '</td>';
1185 // Duration of intervention
1186 if ($tablename == 'fichinter') {
1187 print '<td>';
1188 print $langs->trans("TotalDuration");
1189 $total_duration = 0;
1190 print '</td>';
1191 }
1192 // Amount HT
1193 //if (empty($value['disableamount']) && ! in_array($tablename, array('projet_task'))) print '<td class="right" width="120">'.$langs->trans("AmountHT").'</td>';
1194 //elseif (empty($value['disableamount']) && in_array($tablename, array('projet_task'))) print '<td class="right" width="120">'.$langs->trans("Amount").'</td>';
1195 if ($key == 'loan') {
1196 print '<td class="right" width="120">'.$langs->trans("LoanCapital").'</td>';
1197 } elseif (empty($value['disableamount'])) {
1198 print '<td class="right" width="120">'.$langs->trans("AmountHT").'</td>';
1199 } else {
1200 print '<td width="120"></td>';
1201 }
1202 // Amount TTC
1203 //if (empty($value['disableamount']) && ! in_array($tablename, array('projet_task'))) print '<td class="right" width="120">'.$langs->trans("AmountTTC").'</td>';
1204 if ($key == 'loan') {
1205 print '<td class="right" width="120">'.$langs->trans("RemainderToPay").'</td>';
1206 } elseif (empty($value['disableamount'])) {
1207 print '<td class="right" width="120">'.$langs->trans("AmountTTC").'</td>';
1208 } else {
1209 print '<td width="120"></td>';
1210 }
1211 // Status
1212 if (in_array($tablename, array('projet_task'))) {
1213 print '<td class="right" width="200">'.$langs->trans("ProgressDeclared").'</td>';
1214 } else {
1215 print '<td class="right" width="200">'.$langs->trans("Status").'</td>';
1216 }
1217 print '</tr>';
1218
1219 if (is_array($elementarray) && count($elementarray) > 0) {
1220 $total_ht = 0;
1221 $total_ttc = 0;
1222
1223 $total_ht_by_third = 0;
1224 $total_ttc_by_third = 0;
1225
1226 $saved_third_id = 0;
1227 $breakline = '';
1228
1229 if (canApplySubtotalOn($tablename)) {
1230 // Sort
1231 $elementarray = sortElementsByClientName($elementarray);
1232 }
1233
1234 $num = count($elementarray);
1235 $total_time = 0;
1236 for ($i = 0; $i < $num; $i++) {
1237 $tmp = explode('_', $elementarray[$i]);
1238 $idofelement = $tmp[0];
1239 $idofelementuser = isset($tmp[1]) ? $tmp[1] : "";
1240
1241 $element->fetch($idofelement);
1242 if ($idofelementuser) {
1243 $elementuser->fetch($idofelementuser);
1244 }
1245
1246 // Special cases
1247 if ($tablename != 'expensereport_det') {
1248 if (method_exists($element, 'fetch_thirdparty')) {
1249 $element->fetch_thirdparty();
1250 }
1251 } else {
1252 $expensereport = new ExpenseReport($db);
1253 $expensereport->fetch($element->fk_expensereport);
1254 }
1255
1256 //print 'xxx'.$tablename.'yyy'.$classname;
1257
1258 if ($breakline && $saved_third_id != $element->thirdparty->id) {
1259 print $breakline;
1260
1261 $saved_third_id = $element->thirdparty->id;
1262 $breakline = '';
1263
1264 $total_ht_by_third = 0;
1265 $total_ttc_by_third = 0;
1266 }
1267
1268 $saved_third_id = empty($element->thirdparty->id) ? 0 : $element->thirdparty->id;
1269
1270 $qualifiedfortotal = true;
1271 if ($key == 'invoice') {
1272 if (!empty($element->close_code) && $element->close_code == 'replaced') {
1273 $qualifiedfortotal = false; // Replacement invoice, do not include into total
1274 }
1275 } elseif ($key == 'order_supplier' && $element->status == 7) {
1276 $qualifiedfortotal = false; // It makes no sense to include canceled orders in the total
1277 }
1278
1279 if ($key == "order_supplier" && $element->status == 7) {
1280 print '<tr class="oddeven tr_canceled" style=display:none>';
1281 } else {
1282 print '<tr class="oddeven" >';
1283 }
1284
1285
1286 // Remove link
1287 print '<td style="width: 24px">';
1288 if ($tablename != 'projet_task' && $tablename != 'stock_mouvement') {
1289 if (!getDolGlobalString('PROJECT_DISABLE_UNLINK_FROM_OVERVIEW') || $user->admin) { // PROJECT_DISABLE_UNLINK_FROM_OVERVIEW is empty by default, so this test true
1290 print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=unlink&tablename='.$tablename.'&elementselect='.$element->id.($project_field ? '&projectfield='.$project_field : '').'" class="reposition">';
1291 print img_picto($langs->trans('Unlink'), 'unlink');
1292 print '</a>';
1293 }
1294 }
1295 print "</td>\n";
1296
1297 // Ref
1298 print '<td class="left nowraponall">';
1299 if ($tablename == 'expensereport_det') {
1300 print $expensereport->getNomUrl(1);
1301 } else {
1302 print '<table><tr><td style="border-bottom: none;">';
1303 // Show ref with link
1304 if ($element instanceof Task) {
1305 print $element->getNomUrl(1, 'withproject', 'time');
1306 print ' - '.dol_trunc($element->label, 48);
1307 } elseif ($key == 'loan') {
1308 print $element->getNomUrl(1);
1309 print ' - '.dol_trunc($element->label, 48);
1310 } else {
1311 print $element->getNomUrl(1);
1312 }
1313
1314 $element_doc = $element->element;
1315 $filename = dol_sanitizeFileName($element->ref);
1316 if (!empty($conf->$element_doc)) {
1317 $confelementdoc = $conf->$element_doc;
1318 $filedir = $confelementdoc->multidir_output[$element->entity].'/'.dol_sanitizeFileName($element->ref);
1319 } else {
1320 $filedir = '';
1321 }
1322
1323 if ($element_doc === 'order_supplier') {
1324 $element_doc = 'commande_fournisseur';
1325 $filedir = $conf->fournisseur->commande->multidir_output[$element->entity].'/'.dol_sanitizeFileName($element->ref);
1326 } elseif ($element_doc === 'invoice_supplier') {
1327 $element_doc = 'facture_fournisseur';
1328 $filename = get_exdir($element->id, 2, 0, 0, $element, 'invoice_supplier').dol_sanitizeFileName($element->ref);
1329 $filedir = $conf->fournisseur->facture->multidir_output[$element->entity].'/'.$filename;
1330 }
1331
1332 print '<div class="inline-block valignmiddle">';
1333 if ($filedir) {
1334 print $formfile->getDocumentsLink($element_doc, $filename, $filedir);
1335 }
1336 print '</div>';
1337
1338 print '</td>';
1339
1340 print '<td class="tdoverflowmax250" style="border-bottom: none;">';
1341
1342 // Show supplier ref
1343 if (!empty($element->ref_supplier)) {
1344 print ' - '.$element->ref_supplier;
1345 }
1346 // Show customer ref
1347 if (!empty($element->ref_customer)) {
1348 print ' - '.$element->ref_customer;
1349 }
1350 // Compatibility propale
1351 if (empty($element->ref_customer) && !empty($element->ref_client)) {
1352 print ' - '.$element->ref_client;
1353 }
1354
1355 print '</td></tr></table>';
1356 }
1357 print "</td>\n";
1358 // Product and qty on stock movement
1359 if ('MouvementStock' == $classname) {
1360 $mvsProd = new Product($element->db);
1361 $mvsProd->fetch($element->product_id);
1362 print '<td>'.$mvsProd->getNomUrl(1).'</td>';
1363 print '<td>'.$element->qty.'</td>';
1364 }
1365 // Date or TimeSpent
1366 $date = '';
1367 $total_time_by_line = null;
1368 if ($tablename == 'expensereport_det') {
1369 $date = $element->date; // No draft status on lines
1370 } elseif ($tablename == 'stock_mouvement') {
1371 $date = $element->datem;
1372 } elseif ($tablename == 'salary') {
1373 $date = $element->datesp;
1374 } elseif ($tablename == 'payment_various') {
1375 $date = $element->datev;
1376 } elseif ($tablename == 'chargesociales') {
1377 $date = $element->date_ech;
1378 } elseif (!empty($element->status) || !empty($element->statut) || !empty($element->fk_status)) {
1379 if ($tablename == 'don') {
1380 $date = $element->datedon;
1381 }
1382 if ($tablename == 'commande_fournisseur' || $tablename == 'supplier_order') {
1383 $date = ($element->date_commande ? $element->date_commande : $element->date_valid);
1384 } elseif ($tablename == 'supplier_proposal') {
1385 $date = $element->date_validation; // There is no other date for this
1386 } elseif ($tablename == 'fichinter') {
1387 $date = $element->datev; // There is no other date for this
1388 } elseif ($tablename == 'projet_task') {
1389 $date = ''; // We show no date. Showing date of beginning of task make user think it is date of time consumed
1390 } else {
1391 $date = $element->date; // invoice, ...
1392 if (empty($date)) {
1393 $date = $element->date_contrat;
1394 }
1395 if (empty($date)) {
1396 $date = $element->datev;
1397 }
1398 if (empty($date) && !empty($datefieldname)) {
1399 $date = $element->$datefieldname;
1400 }
1401 }
1402 } elseif ($key == 'loan') {
1403 $date = $element->datestart;
1404 }
1405
1406 print '<td class="center">';
1407 if ($tablename == 'actioncomm') {
1408 print dol_print_date($element->datep, 'dayhour');
1409 if ($element->datef && $element->datef > $element->datep) {
1410 print " - ".dol_print_date($element->datef, 'dayhour');
1411 }
1412 } elseif (in_array($tablename, array('projet_task'))) {
1413 $tmpprojtime = $element->getSumOfAmount($idofelementuser ? $elementuser : '', $dates, $datee); // $element is a task. $elementuser may be empty
1414 print '<a href="'.DOL_URL_ROOT.'/projet/tasks/time.php?id='.$idofelement.'&withproject=1">';
1415 print convertSecondToTime($tmpprojtime['nbseconds'], 'allhourmin');
1416 print '</a>';
1417 $total_time_by_line = $tmpprojtime['nbseconds'];
1418 } else {
1419 print dol_print_date($date, 'day');
1420 }
1421 print '</td>';
1422
1423 // Third party or user
1424 print '<td class="tdoverflowmax150">';
1425 if (is_object($element->thirdparty)) {
1426 print $element->thirdparty->getNomUrl(1, '', 48);
1427 } elseif ($tablename == 'expensereport_det') {
1428 $tmpuser = new User($db);
1429 $tmpuser->fetch($expensereport->fk_user_author);
1430 print $tmpuser->getNomUrl(1, '', 48);
1431 } elseif ($tablename == 'salary') {
1432 $tmpuser = new User($db);
1433 $tmpuser->fetch($element->fk_user);
1434 print $tmpuser->getNomUrl(1, '', 48);
1435 } elseif ($tablename == 'don' || $tablename == 'stock_mouvement') {
1436 if ($element->fk_user_author > 0) {
1437 $tmpuser2 = new User($db);
1438 $tmpuser2->fetch($element->fk_user_author);
1439 print $tmpuser2->getNomUrl(1, '', 48);
1440 }
1441 } elseif ($tablename == 'projet_task' && $key == 'element_time') { // if $key == 'project_task', we don't want details per user
1442 print $elementuser->getNomUrl(1);
1443 }
1444 print '</td>';
1445
1446 // Add duration and store it in counter for fichinter
1447 if ($tablename == 'fichinter') {
1448 print '<td>';
1449 print convertSecondToTime($element->duration, 'all', $conf->global->MAIN_DURATION_OF_WORKDAY);
1450 $total_duration += $element->duration;
1451 print '</td>';
1452 }
1453
1454 // Amount without tax
1455 $warning = '';
1456 if (empty($value['disableamount'])) {
1457 $total_ht_by_line = null;
1458 $othermessage = '';
1459 if ($tablename == 'don' || $tablename == 'chargesociales' || $tablename == 'payment_various' || $tablename == 'salary') {
1460 $total_ht_by_line = $element->amount;
1461 } elseif ($tablename == 'fichinter') {
1462 $total_ht_by_line = $element->getAmount();
1463 } elseif ($tablename == 'stock_mouvement') {
1464 $total_ht_by_line = $element->price * abs($element->qty);
1465 } elseif (in_array($tablename, array('projet_task'))) {
1466 if (isModEnabled('salaries')) {
1467 // TODO Permission to read daily rate to show value
1468 $total_ht_by_line = price2num($tmpprojtime['amount'], 'MT');
1469 if ($tmpprojtime['nblinesnull'] > 0) {
1470 $langs->load("errors");
1471 $warning = $langs->trans("WarningSomeLinesWithNullHourlyRate", $conf->currency);
1472 }
1473 } else {
1474 $othermessage = $form->textwithpicto($langs->trans("NotAvailable"), $langs->trans("ModuleSalaryToDefineHourlyRateMustBeEnabled"));
1475 }
1476 } elseif ($key == 'loan') {
1477 $total_ht_by_line = $element->capital;
1478 } else {
1479 $total_ht_by_line = $element->total_ht;
1480 }
1481
1482 // Change sign of $total_ht_by_line and $total_ttc_by_line for some cases
1483 if ($tablename == 'payment_various') {
1484 if ($element->sens == 0) {
1485 $total_ht_by_line = -$total_ht_by_line;
1486 }
1487 }
1488
1489 print '<td class="right">';
1490 if ($othermessage) {
1491 print '<span class="opacitymedium">'.$othermessage.'</span>';
1492 }
1493 if (isset($total_ht_by_line)) {
1494 if (!$qualifiedfortotal) {
1495 print '<strike>';
1496 }
1497 print '<span class="amount">'.price($total_ht_by_line).'</span>';
1498 if (!$qualifiedfortotal) {
1499 print '</strike>';
1500 }
1501 }
1502 if ($warning) {
1503 print ' '.img_warning($warning);
1504 }
1505 print '</td>';
1506 } else {
1507 print '<td></td>';
1508 }
1509
1510 // Amount inc tax
1511 if (empty($value['disableamount'])) {
1512 $total_ttc_by_line = null;
1513 if ($tablename == 'don' || $tablename == 'chargesociales' || $tablename == 'payment_various' || $tablename == 'salary') {
1514 $total_ttc_by_line = $element->amount;
1515 } elseif ($tablename == 'fichinter') {
1516 $total_ttc_by_line = $element->getAmount();
1517 } elseif ($tablename == 'stock_mouvement') {
1518 $total_ttc_by_line = $element->price * abs($element->qty);
1519 } elseif ($tablename == 'projet_task') {
1520 if (isModEnabled('salaries')) {
1521 // TODO Permission to read daily rate
1522 $defaultvat = get_default_tva($mysoc, $mysoc);
1523 $total_ttc_by_line = price2num($total_ht_by_line * (1 + ($defaultvat / 100)), 'MT');
1524 } else {
1525 $othermessage = $form->textwithpicto($langs->trans("NotAvailable"), $langs->trans("ModuleSalaryToDefineHourlyRateMustBeEnabled"));
1526 }
1527 } elseif ($key == 'loan') {
1528 $total_ttc_by_line = $element->capital - $element->getSumPayment();
1529 } else {
1530 $total_ttc_by_line = $element->total_ttc;
1531 }
1532
1533 // Change sign of $total_ht_by_line and $total_ttc_by_line for some cases
1534 if ($tablename == 'payment_various') {
1535 if ($element->sens == 0) {
1536 $total_ttc_by_line = -$total_ttc_by_line;
1537 }
1538 }
1539
1540 print '<td class="right">';
1541 if ($othermessage) {
1542 print $othermessage;
1543 }
1544 if (isset($total_ttc_by_line)) {
1545 if (!$qualifiedfortotal) {
1546 print '<strike>';
1547 }
1548 print '<span class="amount">'.price($total_ttc_by_line).'</span>';
1549 if (!$qualifiedfortotal) {
1550 print '</strike>';
1551 }
1552 }
1553 if ($warning) {
1554 print ' '.img_warning($warning);
1555 }
1556 print '</td>';
1557 } else {
1558 print '<td></td>';
1559 }
1560
1561 // Status
1562 print '<td class="right">';
1563 if ($tablename == 'expensereport_det') {
1564 print $expensereport->getLibStatut(5);
1565 } elseif ($element instanceof CommonInvoice) {
1566 //This applies for Facture and FactureFournisseur
1567 print $element->getLibStatut(5, $element->getSommePaiement());
1568 } elseif ($element instanceof Task) {
1569 if ($element->progress != '') {
1570 print $element->progress.' %';
1571 }
1572 } elseif ($tablename == 'stock_mouvement') {
1573 print $element->getLibStatut(3);
1574 } else {
1575 print $element->getLibStatut(5);
1576 }
1577 print '</td>';
1578
1579 print '</tr>';
1580
1581 if ($qualifiedfortotal) {
1582 $total_ht = $total_ht + $total_ht_by_line;
1583 $total_ttc = $total_ttc + $total_ttc_by_line;
1584
1585 $total_ht_by_third += $total_ht_by_line;
1586 $total_ttc_by_third += $total_ttc_by_line;
1587
1588 if (!isset($total_time)) {
1589 $total_time = $total_time_by_line;
1590 } else {
1591 $total_time += $total_time_by_line;
1592 }
1593 }
1594
1595 if (canApplySubtotalOn($tablename)) {
1596 $breakline = '<tr class="liste_total liste_sub_total">';
1597 $breakline .= '<td colspan="2">';
1598 $breakline .= '</td>';
1599 $breakline .= '<td>';
1600 $breakline .= '</td>';
1601 $breakline .= '<td class="right">';
1602 $breakline .= $langs->trans('SubTotal').' : ';
1603 if (is_object($element->thirdparty)) {
1604 $breakline .= $element->thirdparty->getNomUrl(0, '', 48);
1605 }
1606 $breakline .= '</td>';
1607 $breakline .= '<td class="right">'.price($total_ht_by_third).'</td>';
1608 $breakline .= '<td class="right">'.price($total_ttc_by_third).'</td>';
1609 $breakline .= '<td></td>';
1610 $breakline .= '</tr>';
1611 }
1612
1613 //var_dump($element->thirdparty->name.' - '.$saved_third_id.' - '.$element->thirdparty->id);
1614 }
1615
1616 if ($breakline) {
1617 print $breakline;
1618 }
1619
1620 // Total
1621 if (empty($nototal)) {
1622 $colspan = 4;
1623 if (in_array($tablename, array('projet_task'))) {
1624 $colspan = 2;
1625 }
1626
1627 print '<tr class="liste_total"><td colspan="'.$colspan.'">'.$langs->trans("Number").': '.$i.'</td>';
1628 if (in_array($tablename, array('projet_task'))) {
1629 print '<td class="center">';
1630 print convertSecondToTime($total_time, 'allhourmin');
1631 print '</td>';
1632 print '<td>';
1633 print '</td>';
1634 }
1635 //if (empty($value['disableamount']) && ! in_array($tablename, array('projet_task'))) print '<td class="right" width="100">'.$langs->trans("TotalHT").' : '.price($total_ht).'</td>';
1636 //elseif (empty($value['disableamount']) && in_array($tablename, array('projet_task'))) print '<td class="right" width="100">'.$langs->trans("Total").' : '.price($total_ht).'</td>';
1637 // If fichinter add the total_duration
1638 if ($tablename == 'fichinter') {
1639 print '<td class="left">'.convertSecondToTime($total_duration, 'all', $conf->global->MAIN_DURATION_OF_WORKDAY).'</td>';
1640 }
1641 print '<td class="right">';
1642 if (empty($value['disableamount'])) {
1643 if ($key == 'loan') {
1644 print $langs->trans("Total").' '.$langs->trans("LoanCapital").' : '.price($total_ttc);
1645 } elseif ($tablename != 'projet_task' || isModEnabled('salaries')) {
1646 print ''.$langs->trans("TotalHT").' : '.price($total_ht);
1647 }
1648 }
1649 print '</td>';
1650 //if (empty($value['disableamount']) && ! in_array($tablename, array('projet_task'))) print '<td class="right" width="100">'.$langs->trans("TotalTTC").' : '.price($total_ttc).'</td>';
1651 //elseif (empty($value['disableamount']) && in_array($tablename, array('projet_task'))) print '<td class="right" width="100"></td>';
1652 print '<td class="right">';
1653 if (empty($value['disableamount'])) {
1654 if ($key == 'loan') {
1655 print $langs->trans("Total").' '.$langs->trans("RemainderToPay").' : '.price($total_ttc);
1656 } elseif ($tablename != 'projet_task' || isModEnabled('salaries')) {
1657 print $langs->trans("TotalTTC").' : '.price($total_ttc);
1658 }
1659 }
1660 print '</td>';
1661 print '<td>&nbsp;</td>';
1662 print '</tr>';
1663 }
1664 } else {
1665 if (!is_array($elementarray)) { // error
1666 print '<tr><td>'.$elementarray.'</td></tr>';
1667 } else {
1668 $colspan = 7;
1669 if ($tablename == 'fichinter') {
1670 $colspan++;
1671 }
1672 print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("None").'</td></tr>';
1673 }
1674 }
1675 print "</table>";
1676 print '</div>';
1677 print "<br>\n";
1678 }
1679}
1680
1681// Enhance with select2
1682if ($conf->use_javascript_ajax) {
1683 include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php';
1684 $comboenhancement = ajax_combobox('.elementselect');
1685
1686 print $comboenhancement;
1687}
1688
1689// End of page
1690llxFooter();
1691$db->close();
1692
1693
1694
1701function canApplySubtotalOn($tablename)
1702{
1703 global $conf;
1704
1705 if (!getDolGlobalString('PROJECT_ADD_SUBTOTAL_LINES')) {
1706 return false;
1707 }
1708 return in_array($tablename, array('facture_fourn', 'commande_fournisseur'));
1709}
1710
1717function sortElementsByClientName($elementarray)
1718{
1719 global $db, $classname;
1720
1721 $element = new $classname($db);
1722
1723 $clientname = array();
1724 foreach ($elementarray as $key => $id) { // id = id of object
1725 if (empty($clientname[$id])) {
1726 $element->fetch($id);
1727 $element->fetch_thirdparty();
1728
1729 $clientname[$id] = $element->thirdparty->name;
1730 }
1731 }
1732
1733 //var_dump($clientname);
1734 asort($clientname); // sort on name
1735
1736 $elementarray = array();
1737 foreach ($clientname as $id => $name) {
1738 $elementarray[] = $id;
1739 }
1740
1741 return $elementarray;
1742}
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:595
convertSecondToTime($iSecond, $format='all', $lengthOfDay=86400, $lengthOfWeek=7)
Return, in clear text, value of a number of seconds in days, hours and minutes.
Definition date.lib.php:242
dol_stringtotime($string, $gm=1)
Convert a string date into a GM Timestamps date Warning: YYYY-MM-DDTHH:MM:SS+02:00 (RFC3339) is not s...
Definition date.lib.php:427
sortElementsByClientName($elementarray)
sortElementsByClientName
Definition element.php:1717
canApplySubtotalOn($tablename)
Return if we should do a group by customer with sub-total.
Definition element.php:1701
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.