Issues (2811)

public/htdocs/projet/element.php (4 issues)

1
<?php
2
3
/* Copyright (C) 2001-2004  Rodolphe Quiedeville        <[email protected]>
4
 * Copyright (C) 2004-2020  Laurent Destailleur         <[email protected]>
5
 * Copyright (C) 2005-2010  Regis Houssin               <[email protected]>
6
 * Copyright (C) 2012-2016  Juanjo Menent               <[email protected]>
7
 * Copyright (C) 2015-2021  Alexandre Spangaro          <[email protected]>
8
 * Copyright (C) 2015       Marcos García               <[email protected]>
9
 * Copyright (C) 2016       Josep Lluís Amador          <[email protected]>
10
 * Copyright (C) 2021-2023  Gauthier VERDOL             <[email protected]>
11
 * Copyright (C) 2021       Noé Cendrier                <[email protected]>
12
 * Copyright (C) 2023      	Frédéric France             <[email protected]>
13
 * Copyright (C) 2024		MDW							<[email protected]>
14
 * Copyright (C) 2024       Frédéric France             <[email protected]>
15
 * Copyright (C) 2024       Rafael San José             <[email protected]>
16
 *
17
 * This program is free software; you can redistribute it and/or modify
18
 * it under the terms of the GNU General Public License as published by
19
 * the Free Software Foundation; either version 3 of the License, or
20
 * (at your option) any later version.
21
 *
22
 * This program is distributed in the hope that it will be useful,
23
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25
 * GNU General Public License for more details.
26
 *
27
 * You should have received a copy of the GNU General Public License
28
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
29
 */
30
31
use Dolibarr\Code\Categories\Classes\Categorie;
32
use Dolibarr\Code\Comm\Classes\Propal;
33
use Dolibarr\Code\Compta\Classes\Facture;
34
use Dolibarr\Code\Core\Classes\CommonInvoice;
35
use Dolibarr\Code\Core\Classes\Form;
36
use Dolibarr\Code\Core\Classes\FormFile;
37
use Dolibarr\Code\Core\Classes\FormProjets;
38
use Dolibarr\Code\EventOrganizaction\Classes\ConferenceOrBoothAttendee;
39
use Dolibarr\Code\ExpenseReport\Classes\ExpenseReport;
40
use Dolibarr\Code\Loan\Classes\LoanSchedule;
41
use Dolibarr\Code\Product\Classes\Product;
42
use Dolibarr\Code\Projet\Classes\Project;
43
use Dolibarr\Code\Projet\Classes\Task;
44
use Dolibarr\Code\User\Classes\User;
45
use Dolibarr\Lib\Misc;
46
use Dolibarr\Lib\ViewMain;
47
48
/**
49
 *      \file       htdocs/projet/element.php
50
 *      \ingroup    projet
51
 *      \brief      Page of project referrers
52
 */
53
54
// Load Dolibarr environment
55
require constant('DOL_DOCUMENT_ROOT') . '/main.inc.php';
56
require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/project.lib.php';
57
require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/date.lib.php';
58
59
// Load translation files required by the page
60
$langs->loadLangs(array('projects', 'companies', 'suppliers', 'compta'));
61
if (isModEnabled('invoice')) {
62
    $langs->load("bills");
63
}
64
if (isModEnabled('order')) {
65
    $langs->load("orders");
66
}
67
if (isModEnabled("propal")) {
68
    $langs->load("propal");
69
}
70
if (isModEnabled('intervention')) {
71
    $langs->load("interventions");
72
}
73
if (isModEnabled('deplacement')) {
74
    $langs->load("trips");
75
}
76
if (isModEnabled('expensereport')) {
77
    $langs->load("trips");
78
}
79
if (isModEnabled('don')) {
80
    $langs->load("donations");
81
}
82
if (isModEnabled('loan')) {
83
    $langs->load("loan");
84
}
85
if (isModEnabled('salaries')) {
86
    $langs->load("salaries");
87
}
88
if (isModEnabled('mrp')) {
89
    $langs->load("mrp");
90
}
91
if (isModEnabled('eventorganization')) {
92
    $langs->load("eventorganization");
93
}
94
//if (isModEnabled('stocktransfer')) {
95
//  $langs->load("stockstransfer");
96
//}
97
98
$id = GETPOSTINT('id');
99
$ref = GETPOST('ref', 'alpha');
100
$action = GETPOST('action', 'aZ09');
101
$datesrfc = GETPOST('datesrfc');    // deprecated
102
$dateerfc = GETPOST('dateerfc');    // deprecated
103
$dates = dol_mktime(0, 0, 0, GETPOST('datesmonth'), GETPOST('datesday'), GETPOST('datesyear'));
104
$datee = dol_mktime(23, 59, 59, GETPOST('dateemonth'), GETPOST('dateeday'), GETPOST('dateeyear'));
105
if (empty($dates) && !empty($datesrfc)) {   // deprecated
106
    $dates = dol_stringtotime($datesrfc);
107
}
108
if (empty($datee) && !empty($dateerfc)) {   // deprecated
109
    $datee = dol_stringtotime($dateerfc);
110
}
111
if (!GETPOSTISSET('datesrfc') && !GETPOSTISSET('datesday') && getDolGlobalString('PROJECT_LINKED_ELEMENT_DEFAULT_FILTER_YEAR')) {
112
    $new = dol_now();
113
    $tmp = dol_getdate($new);
114
    //$datee=$now
115
    //$dates=dol_time_plus_duree($datee, -1, 'y');
116
    $dates = dol_get_first_day($tmp['year'], 1);
117
}
118
if ($id == '' && $ref == '') {
119
    setEventMessage($langs->trans('ErrorBadParameters'), 'errors');
120
    header('Location: list.php');
121
    exit();
122
}
123
124
$mine = GETPOST('mode') == 'mine' ? 1 : 0;
125
//if (! $user->rights->projet->all->lire) $mine=1;  // Special for projects
126
127
$object = new Project($db);
128
129
include DOL_DOCUMENT_ROOT . '/core/actions_fetchobject.inc.php'; // Must be include, not include_once
130
if (getDolGlobalString('PROJECT_ALLOW_COMMENT_ON_PROJECT') && method_exists($object, 'fetchComments') && empty($object->comments)) {
131
    $object->fetchComments();
132
}
133
134
// Security check
135
$socid = $object->socid;
136
//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.
137
$result = restrictedArea($user, 'projet', $object->id, 'projet&project');
138
139
$hookmanager->initHooks(array('projectOverview'));
140
141
142
/*
143
 *	View
144
 */
145
146
$title = $langs->trans('ProjectReferers') . ' - ' . $object->ref . ' ' . $object->name;
147
if (getDolGlobalString('MAIN_HTML_TITLE') && preg_match('/projectnameonly/', getDolGlobalString('MAIN_HTML_TITLE')) && $object->name) {
148
    $title = $object->ref . ' ' . $object->name . ' - ' . $langs->trans('ProjectReferers');
149
}
150
151
$help_url = 'EN:Module_Projects|FR:Module_Projets|ES:M&oacute;dulo_Proyectos|DE:Modul_Projekte';
152
153
ViewMain::llxHeader('', $title, $help_url);
154
155
$form = new Form($db);
156
$formproject = new FormProjets($db);
157
$formfile = new FormFile($db);
158
159
$userstatic = new User($db);
160
161
// To verify role of users
162
$userAccess = $object->restrictedProjectArea($user);
163
164
$head = project_prepare_head($object);
165
print dol_get_fiche_head($head, 'element', $langs->trans("Project"), -1, ($object->public ? 'projectpub' : 'project'));
166
167
168
// Project card
169
170
if (!empty($_SESSION['pageforbacktolist']) && !empty($_SESSION['pageforbacktolist']['project'])) {
171
    $tmpurl = $_SESSION['pageforbacktolist']['project'];
172
    $tmpurl = preg_replace('/__SOCID__/', (string)$object->socid, $tmpurl);
173
    $linkback = '<a href="' . $tmpurl . (preg_match('/\?/', $tmpurl) ? '&' : '?') . 'restore_lastsearch_values=1">' . $langs->trans("BackToList") . '</a>';
174
} else {
175
    $linkback = '<a href="' . constant('BASE_URL') . '/projet/list.php?restore_lastsearch_values=1">' . $langs->trans("BackToList") . '</a>';
176
}
177
178
$morehtmlref = '<div class="refidno">';
179
// Title
180
$morehtmlref .= $object->title;
181
// Thirdparty
182
if (!empty($object->thirdparty->id) && $object->thirdparty->id > 0) {
183
    $morehtmlref .= '<br>' . $object->thirdparty->getNomUrl(1, 'project');
0 ignored issues
show
The method getNomUrl() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

183
    $morehtmlref .= '<br>' . $object->thirdparty->/** @scrutinizer ignore-call */ getNomUrl(1, 'project');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

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