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