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