dolibarr 24.0.0-beta
index.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004-2011 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
5 * Copyright (C) 2012 Marcos García <marcosgdf@gmail.com>
6 * Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
7 * Copyright (C) 2020 Maxime DEMAREST <maxime@indelog.fr>
8 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
9 * Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <https://www.gnu.org/licenses/>.
23 */
24
31// Load Dolibarr environment
32require '../../../main.inc.php';
33require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propalestats.class.php';
34require_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php';
35require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
36require_once DOL_DOCUMENT_ROOT.'/core/class/html.formpropal.class.php';
37require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
38require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
39
50
51$mode = GETPOSTISSET("mode") ? GETPOST("mode", 'aZ09') : 'customer';
52
53$hookmanager->initHooks(array('propalstats', 'globalcard'));
54
55$object_status = GETPOST('object_status', 'intcomma');
56$typent_id = GETPOSTINT('typent_id');
57$categ_id = GETPOSTINT('categ_id');
58$select_categ_propal_id=GETPOST('select_categ_propal_id', 'array');
59
60$userid = GETPOSTINT('userid');
61$socid = GETPOSTINT('socid');
62// Security check
63if ($user->socid > 0) {
64 $action = '';
65 $socid = $user->socid;
66}
67
68$parameters = array();
69$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
70if ($reshook < 0) {
71 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
72}
73
74$nowyear = dol_print_date(dol_now('gmt'), "%Y", 'gmt');
75$year = GETPOST('year') > 0 ? GETPOSTINT('year') : $nowyear;
76$startyear = $year - (!getDolGlobalString('MAIN_STATS_GRAPHS_SHOW_N_YEARS') ? 2 : max(1, min(10, getDolGlobalString('MAIN_STATS_GRAPHS_SHOW_N_YEARS'))));
77$endyear = $year;
78
79// Load translation files required by the page
80$langs->loadLangs(array('orders', 'companies', 'other', 'suppliers', 'supplier_proposal'));
81
82if ($mode == 'customer' && !$user->hasRight('propal', 'lire')) {
84}
85if ($mode == 'supplier' && !$user->hasRight('supplier_proposal', 'lire')) {
87}
88
89
90/*
91 * View
92 */
93
94$form = new Form($db);
95$formpropal = new FormPropal($db);
96$formcompany = new FormCompany($db);
97$formother = new FormOther($db);
98
99$langs->loadLangs(array('propal', 'other', 'companies'));
100
101$picto = 'propal';
102$title = $langs->trans("ProposalsStatistics");
103$dir = $conf->propal->dir_temp;
104$cat_type = Categorie::TYPE_CUSTOMER;
105$cat_label = $langs->trans("Category").' '.lcfirst($langs->trans("Customer"));
106
107if ($mode == 'supplier') {
108 $picto = 'supplier_proposal';
109 $title = $langs->trans("ProposalsStatisticsSuppliers");
110 $dir = $conf->supplier_proposal->dir_temp;
111 $cat_type = Categorie::TYPE_SUPPLIER;
112 $cat_label = $langs->trans("Category").' '.lcfirst($langs->trans("Supplier"));
113}
114
115llxHeader('', $title);
116
117$page = 0;
118$param = '';
119$sortfield = '';
120$sortorder = '';
121$massactionbutton = '';
122$num = 0;
123$nbtotalofrecords = $langs->trans("Statistics");
124$limit = 0;
125
126$url = DOL_URL_ROOT.'/comm/propal/card.php?action=create';
127if (!empty($socid)) {
128 $url .= '&socid='.$socid;
129}
130
131$newcardbutton = '';
132$newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/comm/propal/list.php?mode=common'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', 1, array('morecss' => 'reposition'));
133$newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', DOL_URL_ROOT.'/comm/propal/list.php?mode=kanban'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', 1, array('morecss' => 'reposition'));
134$newcardbutton .= dolGetButtonTitle($langs->trans('Statistics'), '', 'fa fa-chart-bar imgforviewmode', DOL_URL_ROOT.'/comm/propal/stats/index.php'.preg_replace('/(&|\?)*(mode|groupby)=[^&]+/', '', $param), '', 2, array('morecss' => 'reposition'));
135$newcardbutton .= dolGetButtonTitleSeparator();
136$newcardbutton .= dolGetButtonTitle($langs->trans('NewPropal'), '', 'fa fa-plus-circle', $url, '', $user->hasRight('propal', 'creer'));
137
138print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, $picto, 0, $newcardbutton, '', $limit, 0, 0, 1);
139
140
141dol_mkdir($dir);
142
143
144$stats = new PropaleStats($db, $socid, ($userid > 0 ? $userid : 0), $mode, ($typent_id > 0 ? $typent_id : 0), ($categ_id > 0 ? $categ_id : 0));
145if ($object_status != '' && $object_status >= 0) {
146 $stats->where .= ' AND p.fk_statut IN ('.$db->sanitize($object_status).')';
147}
148
149// Build graphic number of object
150$data = $stats->getNbByMonthWithPrevYear($endyear, $startyear);
151// $data = array(array('Lib',val1,val2,val3),...)
152if ($mode == 'customer') {
153 if (is_array($select_categ_propal_id) && !empty($select_categ_propal_id)) {
154 $stats->from .= ' LEFT JOIN '.MAIN_DB_PREFIX.'categorie_propal as cat ON (p.rowid = cat.fk_propal)';
155 $stats->where .= ' AND cat.fk_categorie IN ('.$db->sanitize(implode(',', $select_categ_propal_id)).')';
156 }
157}
158if ($mode == 'supplier') {
159 if (is_array($select_categ_propal_id) && !empty($select_categ_propal_id)) {
160 $stats->from .= ' LEFT JOIN '.MAIN_DB_PREFIX.'categorie_supplier_proposal as cat ON (p.rowid = cat.fk_supplier_proposal)';
161 $stats->where .= ' AND cat.fk_categorie IN ('.$db->sanitize(implode(',', $select_categ_propal_id)).')';
162 }
163}
164
165if (!$user->hasRight('societe', 'client', 'voir')) {
166 $filenamenb = $dir.'/proposalsnbinyear-'.$user->id.'-'.$year.'.png';
167 $fileurlnb = DOL_URL_ROOT.'/viewimage.php?modulepart=propalstats&file=proposalsnbinyear-'.$user->id.'-'.$year.'.png';
168} else {
169 $filenamenb = $dir.'/proposalsnbinyear-'.$year.'.png';
170 $fileurlnb = DOL_URL_ROOT.'/viewimage.php?modulepart=propalstats&file=proposalsnbinyear-'.$year.'.png';
171}
172
173$px1 = new DolGraph();
174$mesg = $px1->isGraphKo();
175if (!$mesg) {
176 $px1->SetData($data);
177 $i = $startyear;
178 $legend = array();
179 while ($i <= $endyear) {
180 $legend[] = $i;
181 $i++;
182 }
183 $px1->SetLegend($legend);
184 $px1->SetMaxValue($px1->GetCeilMaxValue());
185 $px1->SetMinValue(min(0, $px1->GetFloorMinValue()));
186 $px1->SetWidth($WIDTH);
187 $px1->SetHeight($HEIGHT);
188 $px1->SetYLabel($langs->trans("NbOfProposals"));
189 $px1->SetShading(3);
190 $px1->SetHorizTickIncrement(1);
191 $px1->mode = 'depth';
192 $px1->SetTitle($langs->trans("NumberOfProposalsByMonth"));
193
194 $px1->draw($filenamenb, $fileurlnb);
195}
196
197// Build graphic amount of object
198$data = $stats->getAmountByMonthWithPrevYear($endyear, $startyear, 0);
199// $data = array(array('Lib',val1,val2,val3),...)
200
201if (!$user->hasRight('societe', 'client', 'voir')) {
202 $filenameamount = $dir.'/proposalsamountinyear-'.$user->id.'-'.$year.'.png';
203 $fileurlamount = DOL_URL_ROOT.'/viewimage.php?modulepart=propalstats&file=proposalsamountinyear-'.$user->id.'-'.$year.'.png';
204} else {
205 $filenameamount = $dir.'/proposalsamountinyear-'.$year.'.png';
206 $fileurlamount = DOL_URL_ROOT.'/viewimage.php?modulepart=propalstats&file=proposalsamountinyear-'.$year.'.png';
207}
208
209$px2 = new DolGraph();
210$mesg = $px2->isGraphKo();
211if (!$mesg) {
212 $px2->SetData($data);
213 $i = $startyear;
214 $legend = array();
215 while ($i <= $endyear) {
216 $legend[] = $i;
217 $i++;
218 }
219 $px2->SetLegend($legend);
220 $px2->SetMaxValue($px2->GetCeilMaxValue());
221 $px2->SetMinValue(min(0, $px2->GetFloorMinValue()));
222 $px2->SetWidth($WIDTH);
223 $px2->SetHeight($HEIGHT);
224 $px2->SetYLabel($langs->trans("AmountOfProposals"));
225 $px2->SetShading(3);
226 $px2->SetHorizTickIncrement(1);
227 $px2->mode = 'depth';
228 $px2->SetTitle($langs->trans("AmountOfProposalsByMonthHT"));
229
230 $px2->draw($filenameamount, $fileurlamount);
231}
232
233$data = $stats->getAverageByMonthWithPrevYear($endyear, $startyear);
234
235$fileurl_avg = '';
236if (!$user->hasRight('societe', 'client', 'voir')) {
237 $filename_avg = $dir.'/ordersaverage-'.$user->id.'-'.$year.'.png';
238 if ($mode == 'customer') {
239 $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstats&file=ordersaverage-'.$user->id.'-'.$year.'.png';
240 }
241 if ($mode == 'supplier') {
242 $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstatssupplier&file=ordersaverage-'.$user->id.'-'.$year.'.png';
243 }
244} else {
245 $filename_avg = $dir.'/ordersaverage-'.$year.'.png';
246 if ($mode == 'customer') {
247 $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstats&file=ordersaverage-'.$year.'.png';
248 }
249 if ($mode == 'supplier') {
250 $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstatssupplier&file=ordersaverage-'.$year.'.png';
251 }
252}
253
254$px3 = new DolGraph();
255$mesg = $px3->isGraphKo();
256if (!$mesg) {
257 $px3->SetData($data);
258 $i = $startyear;
259 $legend = array();
260 while ($i <= $endyear) {
261 $legend[] = $i;
262 $i++;
263 }
264 $px3->SetLegend($legend);
265 $px3->SetYLabel($langs->trans("AmountAverage"));
266 $px3->SetMaxValue($px3->GetCeilMaxValue());
267 $px3->SetMinValue((int) $px3->GetFloorMinValue());
268 $px3->SetWidth($WIDTH);
269 $px3->SetHeight($HEIGHT);
270 $px3->SetShading(3);
271 $px3->SetHorizTickIncrement(1);
272 $px3->mode = 'depth';
273 $px3->SetTitle($langs->trans("AmountAverage"));
274
275 $px3->draw($filename_avg, $fileurl_avg);
276}
277
278
279// Show array
280$data = $stats->getAllByYear();
281$arrayyears = array();
282foreach ($data as $val) {
283 if (!empty($val['year'])) {
284 $arrayyears[$val['year']] = $val['year'];
285 }
286}
287if (!count($arrayyears)) {
288 $arrayyears[$nowyear] = $nowyear;
289}
290
291
292$h = 0;
293$head = array();
294$head[$h][0] = DOL_URL_ROOT.'/comm/propal/stats/index.php';
295$head[$h][1] = $langs->trans("ByMonthYear");
296$head[$h][2] = 'byyear';
297$h++;
298
299complete_head_from_modules($conf, $langs, null, $head, $h, 'propal_stats');
300
301print dol_get_fiche_head($head, 'byyear', '', -1);
302
303
304print '<div class="fichecenter"><div class="fichethirdleft">';
305
306
307// Show filter box
308print '<form name="stats" method="POST" action="'.dolBuildUrl($_SERVER["PHP_SELF"]).'">';
309print '<input type="hidden" name="token" value="'.newToken().'">';
310print '<input type="hidden" name="mode" value="'.$mode.'">';
311
312print '<table class="noborder centpercent">';
313print '<tr class="liste_titre"><td class="liste_titre" colspan="2">'.$langs->trans("Filter").'</td></tr>';
314// Company
315print '<tr><td class="left">'.$langs->trans("ThirdParty").'</td><td class="left">';
316print img_picto('', 'company', 'class="pictofixedwidth"');
317$filter = '(s.client:IN:1,2,3)';
318print $form->select_company($socid, 'socid', $filter, 1, 0, 0, array(), 0, 'widthcentpercentminusx maxwidth300', '');
319print '</td></tr>';
320// ThirdParty Type
321print '<tr><td>'.$langs->trans("ThirdPartyType").'</td><td>';
322$sortparam_typent = (!getDolGlobalString('SOCIETE_SORT_ON_TYPEENT') ? 'ASC' : $conf->global->SOCIETE_SORT_ON_TYPEENT); // NONE means we keep sort of original array, so we sort on position. ASC, means next function will sort on label.
323print $form->selectarray("typent_id", $formcompany->typent_array(0), $typent_id, 1, 0, 0, '', 0, 0, 0, $sortparam_typent, '', 1);
324if ($user->admin) {
325 print ' '.info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
326}
327print '</td></tr>';
328// Category
329print '<tr><td>'.$cat_label.'</td><td>';
330print img_picto('', 'category', 'class="pictofixedwidth"');
331print $formother->select_categories($cat_type, $categ_id, 'categ_id', 0, 1, 'widthcentpercentminusx maxwidth300');
332print '</td></tr>';
333
334if (isModEnabled('category')) {
335 $cat_type = '';
336 $cat_label = '';
337 if ($mode == 'customer') {
338 $cat_type = Categorie::TYPE_PROPOSAL;
339 $cat_label = $langs->trans("Category").' '.lcfirst($langs->trans("Proposals"));
340 }
341 if ($mode == 'supplier') {
342 $cat_type = Categorie::TYPE_SUPPLIER_PROPOSAL;
343 $cat_label = $langs->trans("Category").' '.lcfirst($langs->trans("SupplierProposals"));
344 }
345 print '<tr><td>'.$cat_label.'</td><td>';
346 $cate_arbo = $form->select_all_categories($cat_type, '', 'parent', 0, 0, 1);
347 print img_picto('', 'category', 'class="pictofixedwidth"');
348 print $form->multiselectarray('select_categ_propal_id', $cate_arbo, GETPOST('select_categ_propal_id', 'array'), 0, 0, 'widthcentpercentminusx maxwidth300');
349 //print $formother->select_categories($cat_type, $categ_id, 'categ_id', true);
350 print '</td></tr>';
351}
352// User
353print '<tr><td>'.$langs->trans("CreatedBy").'</td><td>';
354print img_picto('', 'user', 'class="pictofixedwidth"');
355print $form->select_dolusers($userid, 'userid', 1, null, 0, '', '', '0', 0, 0, '', 0, '', 'widthcentpercentminusx maxwidth300');
356print '</td></tr>';
357// Status
358print '<tr><td>'.$langs->trans("Status").'</td><td>';
359$formpropal->selectProposalStatus(($object_status != '' ? $object_status : -1), 0, 0, 1, $mode, 'object_status');
360print '</td></tr>';
361// Year
362print '<tr><td>'.$langs->trans("Year").'</td><td>';
363if (!in_array($year, $arrayyears)) {
364 $arrayyears[$year] = $year;
365}
366if (!in_array($nowyear, $arrayyears)) {
367 $arrayyears[$nowyear] = $nowyear;
368}
369arsort($arrayyears);
370print img_picto('', 'calendar', 'class="pictofixedwidth"');
371print $form->selectarray('year', $arrayyears, $year, 0, 0, 0, '', 0, 0, 0, '', 'width75');
372print '</td></tr>';
373print '<tr><td align="center" colspan="2"><input type="submit" name="submit" class="button small" value="'.$langs->trans("Refresh").'"></td></tr>';
374print '</table>';
375print '</form>';
376print '<br><br>';
377
378print '<div class="div-table-responsive-no-min">';
379print '<table class="noborder centpercent">';
380print '<tr class="liste_titre" height="24">';
381print '<td class="center">'.$langs->trans("Year").'</td>';
382print '<td class="right">'.$langs->trans("NbOfProposals").'</td>';
383print '<td class="right">%</td>';
384print '<td class="right">'.$langs->trans("AmountTotal").'</td>';
385print '<td class="right">%</td>';
386print '<td class="right">'.$langs->trans("AmountAverage").'</td>';
387print '<td class="right">%</td>';
388print '</tr>';
389
390$oldyear = 0;
391foreach ($data as $val) {
392 $year = $val['year'];
393 while (!empty($year) && $oldyear > (int) $year + 1) { // If we have empty year
394 $oldyear--;
395
396 print '<tr class="oddeven" height="24">';
397 print '<td align="center"><a href="'.$_SERVER["PHP_SELF"].'?year='.$oldyear.'&amp;mode='.$mode.($socid > 0 ? '&socid='.$socid : '').($userid > 0 ? '&userid='.$userid : '').'">'.$oldyear.'</a></td>';
398 print '<td class="right">0</td>';
399 print '<td class="right"></td>';
400 print '<td class="right">0</td>';
401 print '<td class="right"></td>';
402 print '<td class="right">0</td>';
403 print '<td class="right"></td>';
404 print '</tr>';
405 }
406 print '<tr class="oddeven" height="24">';
407 print '<td align="center"><a href="'.$_SERVER["PHP_SELF"].'?year='.$year.($socid > 0 ? '&socid='.$socid : '').($userid > 0 ? '&userid='.$userid : '').'">'.$year.'</a></td>';
408 print '<td class="right">'.$val['nb'].'</td>';
409 print '<td class="right opacitylow" style="'.((!isset($val['nb_diff']) || $val['nb_diff'] >= 0) ? 'color: green;' : 'color: red;').'">'.(isset($val['nb_diff']) ? round($val['nb_diff']) : "0").'%</td>';
410 print '<td class="right">'.price(price2num($val['total'], 'MT'), 1).'</td>';
411 print '<td class="right opacitylow" style="'.((!isset($val['total_diff']) || $val['total_diff'] >= 0) ? 'color: green;' : 'color: red;').'">'.(isset($val['total_diff']) ? round($val['total_diff']) : "0").'%</td>';
412 print '<td class="right">'.price(price2num($val['avg'], 'MT'), 1).'</td>';
413 print '<td class="right opacitylow" style="'.((!isset($val['avg_diff']) || $val['avg_diff'] >= 0) ? 'color: green;' : 'color: red;').'">'.(isset($val['avg_diff']) ? round($val['avg_diff']) : "0").'%</td>';
414 print '</tr>';
415 $oldyear = $year;
416}
417
418print '</table>';
419print '</div>';
420
421print '</div><div class="fichetwothirdright">';
422
423
424// Show graphs
425print '<table class="border centpercent"><tr class="pair nohover"><td align="center">';
426if ($mesg) {
427 print $mesg;
428} else {
429 print $px1->show();
430 print "<br>\n";
431 print $px2->show();
432 print "<br>\n";
433 print $px3->show();
434}
435print '</td></tr></table>';
436
437
438print '</div></div>';
439print '<div class="clearboth"></div>';
440
441
442print dol_get_fiche_end();
443
444// End of page
445llxFooter();
446$db->close();
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:73
Class to build graphs.
static getDefaultGraphSizeForStats($direction, $defaultsize='')
getDefaultGraphSizeForStats
Class to build HTML component for third parties management Only common components are here.
Class to manage generation of HTML components Only common components must be here.
Class to help generate other html components Only common components are here.
Class to manage generation of HTML components for proposal management.
Class to manage proposals statistics.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
dol_now($mode='gmt')
Return date for now.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
print_barre_liste($title, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $selectlimitsuffix=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
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.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
complete_head_from_modules($conf, $langs, $object, &$head, &$h, $type, $mode='add', $filterorigmodule='')
Complete or removed entries into a head array (used to build tabs).
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.