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