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