From 83286d99be429a53eaf116d69efc3308ca860bd1 Mon Sep 17 00:00:00 2001 From: lmarcouiller Date: Wed, 9 Dec 2020 13:31:14 +0100 Subject: [PATCH 01/12] funnel horizontal bar --- .../core/boxes/box_funnel_of_prospection.php | 18 +- htdocs/core/class/dolgraph.class.php | 401 +++++++++--------- 2 files changed, 215 insertions(+), 204 deletions(-) diff --git a/htdocs/core/boxes/box_funnel_of_prospection.php b/htdocs/core/boxes/box_funnel_of_prospection.php index c4cebfcf68a..34b892d142b 100644 --- a/htdocs/core/boxes/box_funnel_of_prospection.php +++ b/htdocs/core/boxes/box_funnel_of_prospection.php @@ -81,6 +81,8 @@ class box_funnel_of_prospection extends ModeleBoxes $sql = "SELECT cls.rowid, cls.code, cls.percent, cls.label"; $sql .= " FROM " . MAIN_DB_PREFIX . "c_lead_status as cls"; $sql .= " WHERE active=1"; + $sql .= " Order by cls.rowid"; + $sql .= " AND cls.code != 'LOST'"; $resql = $this->db->query($sql); if ($resql) { $num = $this->db->num_rows($resql); @@ -108,7 +110,6 @@ class box_funnel_of_prospection extends ModeleBoxes $colorseriesstat[$objp->rowid] = $badgeStatus6; break; default: - $colorseriesstat[$objp->rowid] = $badgeStatus2; break; } $i++; @@ -167,14 +168,16 @@ class box_funnel_of_prospection extends ModeleBoxes $stringtoprint = ''; $stringtoprint .= '
'; $listofstatus = array_keys($listofoppstatus); + $liststatus = array(); + $data = array(''); foreach ($listofstatus as $status) { $labelStatus = ''; if ($status != 7) { $code = dol_getIdFromCode($this->db, $status, 'c_lead_status', 'rowid', 'code'); if ($code) $labelStatus = $langs->transnoentitiesnoconv("OppStatus" . $code); if (empty($labelStatus)) $labelStatus = $listofopplabel[$status]; - - $dataseries[] = array($labelStatus,(isset($valsamount[$status]) ? (float) $valsamount[$status] : 0)); + $liststatus[] = $labelStatus; + $data[] = (isset($valsamount[$status]) ? (float) $valsamount[$status] : 0); if (!$conf->use_javascript_ajax) { $stringtoprint .= ''; $stringtoprint .= '' . $labelStatus . ''; @@ -183,16 +186,21 @@ class box_funnel_of_prospection extends ModeleBoxes } } } + $dataseries[] = $data; if ($conf->use_javascript_ajax) { include_once DOL_DOCUMENT_ROOT . '/core/class/dolgraph.class.php'; $dolgraph = new DolGraph(); + $dolgraph->SetMinValue(0); $dolgraph->SetData($dataseries); + $dolgraph->SetLegend($liststatus); $dolgraph->SetDataColor(array_values($colorseriesstat)); - //$dolgraph->SetLegend(array('PROSP',$dataseries['PROSP'])); $dolgraph->setShowLegend(2); $dolgraph->setShowPercent(1); - $dolgraph->SetType(array('pie')); + $dolgraph->setTitle('FunnelOfProspection'); + $dolgraph->SetType(array('horizontalbars')); $dolgraph->SetHeight('200'); + $dolgraph->SetWidth('600'); + $dolgraph->mode='depth'; $dolgraph->draw('idgraphstatus'); $stringtoprint .= $dolgraph->show($totaloppnb ? 0 : 1); } diff --git a/htdocs/core/class/dolgraph.class.php b/htdocs/core/class/dolgraph.class.php index 80314bcf9ed..ccce9cb1e12 100644 --- a/htdocs/core/class/dolgraph.class.php +++ b/htdocs/core/class/dolgraph.class.php @@ -103,9 +103,8 @@ class DolGraph $this->datacolor = array(array(120, 130, 150), array(160, 160, 180), array(190, 190, 220)); $this->bgcolor = array(235, 235, 224); - $color_file = DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/theme_vars.inc.php'; - if (is_readable($color_file)) - { + $color_file = DOL_DOCUMENT_ROOT . '/theme/' . $conf->theme . '/theme_vars.inc.php'; + if (is_readable($color_file)) { include_once $color_file; if (isset($theme_bordercolor)) $this->bordercolor = $theme_bordercolor; if (isset($theme_datacolor)) $this->datacolor = $theme_datacolor; @@ -261,7 +260,7 @@ class DolGraph * Set type * * @param array $type Array with type for each serie. Example: array('type1', 'type2', ...) where type can be: - * 'pie', 'piesemicircle', 'polar', 'lines', 'linesnopoint', 'bars', 'horirontalbars'... + * 'pie', 'piesemicircle', 'polar', 'lines', 'linesnopoint', 'bars', 'horizontalbars'... * @return void */ public function SetType($type) @@ -466,10 +465,8 @@ class DolGraph // phpcs:enable global $theme_bgcolor, $theme_bgcoloronglet; - if (!is_array($bg_color)) - { - if ($bg_color == 'onglet') - { + if (!is_array($bg_color)) { + if ($bg_color == 'onglet') { //print 'ee'.join(',',$theme_bgcoloronglet); $this->bgcolor = $theme_bgcoloronglet; } else { @@ -492,10 +489,8 @@ class DolGraph // phpcs:enable global $theme_bgcolor, $theme_bgcoloronglet; - if (!is_array($bg_colorgrid)) - { - if ($bg_colorgrid == 'onglet') - { + if (!is_array($bg_colorgrid)) { + if ($bg_colorgrid == 'onglet') { //print 'ee'.join(',',$theme_bgcoloronglet); $this->bgcolorgrid = $theme_bgcoloronglet; } else { @@ -535,10 +530,8 @@ class DolGraph $nblines = count($this->data); $nbvalues = (empty($this->data[0]) ? 0 : count($this->data[0]) - 1); - for ($j = 0; $j < $nblines; $j++) - { - for ($i = 0; $i < $nbvalues; $i++) - { + for ($j = 0; $j < $nblines; $j++) { + for ($i = 0; $i < $nbvalues; $i++) { $vals[$k] = $this->data[$j][$i + 1]; $k++; } @@ -564,10 +557,8 @@ class DolGraph $nblines = count($this->data); $nbvalues = (empty($this->data[0]) ? 0 : count($this->data[0]) - 1); - for ($j = 0; $j < $nblines; $j++) - { - for ($i = 0; $i < $nbvalues; $i++) - { + for ($j = 0; $j < $nblines; $j++) { + for ($i = 0; $i < $nbvalues; $i++) { $vals[$k] = $this->data[$j][$i + 1]; $k++; } @@ -589,8 +580,7 @@ class DolGraph if ($max != 0) $max++; $size = dol_strlen(abs(ceil($max))); $factor = 1; - for ($i = 0; $i < ($size - 1); $i++) - { + for ($i = 0; $i < ($size - 1); $i++) { $factor *= 10; } @@ -615,8 +605,7 @@ class DolGraph if ($min != 0) $min--; $size = dol_strlen(abs(floor($min))); $factor = 1; - for ($i = 0; $i < ($size - 1); $i++) - { + for ($i = 0; $i < ($size - 1); $i++) { $factor *= 10; } @@ -635,24 +624,21 @@ class DolGraph */ public function draw($file, $fileurl = '') { - if (empty($file)) - { + if (empty($file)) { $this->error = "Call to draw method was made with empty value for parameter file."; - dol_syslog(get_class($this)."::draw ".$this->error, LOG_ERR); + dol_syslog(get_class($this) . "::draw " . $this->error, LOG_ERR); return -2; } - if (!is_array($this->data)) - { + if (!is_array($this->data)) { $this->error = "Call to draw method was made but SetData was not called or called with an empty dataset for parameters"; - dol_syslog(get_class($this)."::draw ".$this->error, LOG_ERR); + dol_syslog(get_class($this) . "::draw " . $this->error, LOG_ERR); return -1; } - if (count($this->data) < 1) - { + if (count($this->data) < 1) { $this->error = "Call to draw method was made but SetData was is an empty dataset"; - dol_syslog(get_class($this)."::draw ".$this->error, LOG_WARNING); + dol_syslog(get_class($this) . "::draw " . $this->error, LOG_WARNING); } - $call = "draw_".$this->_library; + $call = "draw_" . $this->_library; call_user_func_array(array($this, $call), array($file, $fileurl)); } @@ -678,10 +664,9 @@ class DolGraph // phpcs:enable global $conf, $langs; - dol_syslog(get_class($this)."::draw_jflot this->type=".join(',', $this->type)." this->MaxValue=".$this->MaxValue); + dol_syslog(get_class($this) . "::draw_jflot this->type=" . join(',', $this->type) . " this->MaxValue=" . $this->MaxValue); - if (empty($this->width) && empty($this->height)) - { + if (empty($this->width) && empty($this->height)) { print 'Error width or height not set'; return; } @@ -701,7 +686,7 @@ class DolGraph while ($i < $nblot) // Loop on each serie { $values = array(); // Array with horizontal y values (specific values of a serie) for each abscisse x - $serie[$i] = "var d".$i." = [];\n"; + $serie[$i] = "var d" . $i . " = [];\n"; // Fill array $values $x = 0; @@ -712,14 +697,13 @@ class DolGraph $x++; } - if (isset($this->type[$firstlot]) && in_array($this->type[$firstlot], array('pie', 'piesemicircle', 'polar'))) - { + if (isset($this->type[$firstlot]) && in_array($this->type[$firstlot], array('pie', 'piesemicircle', 'polar'))) { foreach ($values as $x => $y) { - if (isset($y)) $serie[$i] .= 'd'.$i.'.push({"label":"'.dol_escape_js($legends[$x]).'", "data":'.$y.'});'."\n"; + if (isset($y)) $serie[$i] .= 'd' . $i . '.push({"label":"' . dol_escape_js($legends[$x]) . '", "data":' . $y . '});' . "\n"; } } else { foreach ($values as $x => $y) { - if (isset($y)) $serie[$i] .= 'd'.$i.'.push(['.$x.', '.$y.']);'."\n"; + if (isset($y)) $serie[$i] .= 'd' . $i . '.push([' . $x . ', ' . $y . ']);' . "\n"; } } @@ -728,43 +712,39 @@ class DolGraph } $tag = dol_escape_htmltag(dol_string_unaccent(dol_string_nospecial(basename($file), '_', array('-', '.')))); - $this->stringtoshow = ''."\n"; - if (!empty($this->title)) $this->stringtoshow .= '
'.$this->title.'
'; - if (!empty($this->shownographyet)) - { - $this->stringtoshow .= '
'; - $this->stringtoshow .= '
'.$langs->trans("NotEnoughDataYet").'...
'; + $this->stringtoshow = '' . "\n"; + if (!empty($this->title)) $this->stringtoshow .= '
' . $this->title . '
'; + if (!empty($this->shownographyet)) { + $this->stringtoshow .= '
'; + $this->stringtoshow .= '
' . $langs->trans("NotEnoughDataYet") . '...
'; return; } // Start the div that will contains all the graph $dolxaxisvertical = ''; if (count($this->data) > 20) $dolxaxisvertical = 'dol-xaxis-vertical'; - $this->stringtoshow .= '
'."\n"; + $this->stringtoshow .= '
' . "\n"; - $this->stringtoshow .= ''."\n"; + $this->stringtoshow .= 'plotWithOptions_' . $tag . '();' . "\n"; + $this->stringtoshow .= '});' . "\n"; + $this->stringtoshow .= '' . "\n"; } @@ -947,10 +924,9 @@ class DolGraph // phpcs:enable global $conf, $langs; - dol_syslog(get_class($this)."::draw_chart this->type=".join(',', $this->type)." this->MaxValue=".$this->MaxValue); + dol_syslog(get_class($this) . "::draw_chart this->type=" . join(',', $this->type) . " this->MaxValue=" . $this->MaxValue); - if (empty($this->width) && empty($this->height)) - { + if (empty($this->width) && empty($this->height)) { print 'Error width or height not set'; return; } @@ -971,7 +947,8 @@ class DolGraph // Works with line but not with bars //if ($nblot > 2) $firstlot = ($nblot - 2); // We limit nblot to 2 because jflot can't manage more than 2 bars on same x - $serie = array(); $arrayofgroupslegend = array(); + $serie = array(); + $arrayofgroupslegend = array(); //var_dump($this->data); $i = $firstlot; @@ -989,15 +966,15 @@ class DolGraph $alabelexists = 1; $tmpykey = explode('_', ($array_of_ykeys[$i + ($alabelexists ? 1 : 0)]), 3); if (!empty($tmpykey[2]) || $tmpykey[2] == '0') { // This is a 'Group by' array - $tmpvalue = (array_key_exists('y_'.$tmpykey[1].'_'.$tmpykey[2], $valarray) ? $valarray['y_'.$tmpykey[1].'_'.$tmpykey[2]] : $valarray[$i + 1]); + $tmpvalue = (array_key_exists('y_' . $tmpykey[1] . '_' . $tmpykey[2], $valarray) ? $valarray['y_' . $tmpykey[1] . '_' . $tmpykey[2]] : $valarray[$i + 1]); $values[$x] = (is_numeric($tmpvalue) ? $tmpvalue : null); $arrayofgroupslegend[$i] = array( - 'stacknum'=> $tmpykey[1], + 'stacknum' => $tmpykey[1], 'legend' => $this->Legend[$tmpykey[1]], - 'legendwithgroup' => $this->Legend[$tmpykey[1]].' - '.$tmpykey[2] + 'legendwithgroup' => $this->Legend[$tmpykey[1]] . ' - ' . $tmpykey[2] ); } else { - $tmpvalue = (array_key_exists('y_'.$i, $valarray) ? $valarray['y_'.$i] : $valarray[$i + 1]); + $tmpvalue = (array_key_exists('y_' . $i, $valarray) ? $valarray['y_' . $i] : $valarray[$i + 1]); //var_dump($i.'_'.$x.'_'.$tmpvalue); $values[$x] = (is_numeric($tmpvalue) ? $tmpvalue : null); } @@ -1007,9 +984,9 @@ class DolGraph $j = 0; foreach ($values as $x => $y) { if (isset($y)) { - $serie[$i] .= ($j > 0 ? ", " : "").$y; + $serie[$i] .= ($j > 0 ? ", " : "") . $y; } else { - $serie[$i] .= ($j > 0 ? ", " : "").'null'; + $serie[$i] .= ($j > 0 ? ", " : "") . 'null'; } $j++; } @@ -1022,12 +999,11 @@ class DolGraph $tag = dol_escape_htmltag(dol_string_unaccent(dol_string_nospecial(basename($file), '_', array('-', '.')))); - $this->stringtoshow = ''."\n"; - if (!empty($this->title)) $this->stringtoshow .= '
'.$this->title.'
'; - if (!empty($this->shownographyet)) - { - $this->stringtoshow .= '
'; - $this->stringtoshow .= '
'.$langs->trans("NotEnoughDataYet").'...
'; + $this->stringtoshow = '' . "\n"; + if (!empty($this->title)&&$this->title!='FunnelOfProspection') $this->stringtoshow .= '
' . $this->title . '
'; + if (!empty($this->shownographyet)) { + $this->stringtoshow .= '
'; + $this->stringtoshow .= '
' . $langs->trans("NotEnoughDataYet") . '...
'; return; } @@ -1036,17 +1012,15 @@ class DolGraph if (count($this->data) > 20) $dolxaxisvertical = 'dol-xaxis-vertical'; // No height for the pie grah $cssfordiv = 'dolgraphchart'; - if (isset($this->type[$firstlot])) $cssfordiv .= ' dolgraphchar'.$this->type[$firstlot]; - $this->stringtoshow .= '
'."\n"; + if (isset($this->type[$firstlot])) $cssfordiv .= ' dolgraphchar' . $this->type[$firstlot]; + $this->stringtoshow .= '
' . "\n"; - $this->stringtoshow .= ''."\n"; + $this->stringtoshow .= '' . "\n"; } @@ -1301,14 +1305,13 @@ class DolGraph { global $langs; - if ($shownographyet) - { - $s = '
'; + if ($shownographyet) { + $s = '
'; $s .= '
'; if (is_numeric($shownographyet)) { - $s .= $langs->trans("NotEnoughDataYet").'...'; + $s .= $langs->trans("NotEnoughDataYet") . '...'; } else { - $s .= $shownographyet.'...'; + $s .= $shownographyet . '...'; } $s .= '
'; return $s; From b3ca58d2d0ae2f5fb38b7328664e7869a8b1ac3d Mon Sep 17 00:00:00 2001 From: zuiko Date: Wed, 9 Dec 2020 21:16:25 +0100 Subject: [PATCH 02/12] Update html.form.class.php Complete the Fix to #15565 Enhanced behaviour to select product on customer/supplier order to be able to use barcode reader efficiently. Answer to Eldy, https://github.com/Dolibarr/dolibarr/pull/15704#discussion_r538763166 In fact the change alone to htdocs/core/lib/ajax.lib.php is not, for me, sufficient to fix the issue. if $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, the combo remains even if the product is alone. So I recommend that the code is $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 1, (wihout combo) for product selection only for customer order filling because for this usage the the probability is higher to use a barcode scanner. It is less relevant for filling supplier orders (which are not usually entered by barcode scanner), because the combo gives verification information which then disappears. (This is especially true for the purchase price, which is not pre-filled in the box for the moment I tested(?). --- htdocs/core/class/html.form.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 8faad1f92e9..8c4d24c64cf 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -1995,7 +1995,7 @@ class Form if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) { $urloption .= '&socid='.$socid; } - $out .= ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, $ajaxoptions); + $out .= ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 1, $ajaxoptions); if (!empty($conf->variants->enabled)) { $out .= ' From ecd642e46529d3225ffa7db723bedd716ba083d6 Mon Sep 17 00:00:00 2001 From: lmarcouiller Date: Thu, 10 Dec 2020 10:58:07 +0100 Subject: [PATCH 03/12] Close #15383 : New format for funnel of prospection --- htdocs/core/class/dolgraph.class.php | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/dolgraph.class.php b/htdocs/core/class/dolgraph.class.php index ccce9cb1e12..832047b3c65 100644 --- a/htdocs/core/class/dolgraph.class.php +++ b/htdocs/core/class/dolgraph.class.php @@ -1154,6 +1154,18 @@ class DolGraph $this->stringtoshow .= ', yAxes: [{ stacked: true }]'; } $this->stringtoshow .= ' }'; + if ($isfunnel) { + $this->stringtoshow .= ', tooltips: {mode: \'nearest\', + callbacks: { + title: function(tooltipItem, data) { + return data.datasets[tooltipItem[0].datasetIndex].label; + }, + label: function(tooltipItem, data) { + return data.datasets[tooltipItem.datasetIndex].data[0][1]; + } + } + },'; + } $this->stringtoshow .= '};'; $this->stringtoshow .= ' var ctx = document.getElementById("canvas_' . $tag . '").getContext("2d"); @@ -1265,7 +1277,14 @@ class DolGraph $this->stringtoshow .= 'borderColor: \'' . $bordercolor . '\', '; $this->stringtoshow .= 'backgroundColor: \'' . $color . '\', '; if ($arrayofgroupslegend[$i]) $this->stringtoshow .= 'stack: \'' . $arrayofgroupslegend[$i]['stacknum'] . '\', '; - $this->stringtoshow .= 'data: [' . $serie[$i] . ']'; + $this->stringtoshow .='data: ['; + if($isfunnel){ + $this->stringtoshow .= '['.-$serie[$i].','.$serie[$i].']'; + + }else{ + $this->stringtoshow .= $serie[$i]; + } + $this->stringtoshow .=']'; $this->stringtoshow .= '}' . "\n"; $i++; From 38e03778dcb1498225e207a2fc054b97b0767c7a Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Thu, 10 Dec 2020 10:07:09 +0000 Subject: [PATCH 04/12] Fixing style errors. --- htdocs/core/class/dolgraph.class.php | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/htdocs/core/class/dolgraph.class.php b/htdocs/core/class/dolgraph.class.php index 832047b3c65..3c34668ecd2 100644 --- a/htdocs/core/class/dolgraph.class.php +++ b/htdocs/core/class/dolgraph.class.php @@ -1142,7 +1142,6 @@ class DolGraph $this->stringtoshow .= 'scales: { xAxes: [{ '; if ($isfunnel) { $this->stringtoshow .= ' ticks: { beginAtZero: true}, display: false,'; - } //$this->stringtoshow .= 'type: \'time\', '; // Need Moment.js $this->stringtoshow .= 'distribution: \'linear\''; @@ -1179,12 +1178,12 @@ class DolGraph $i = 0; if (!$isfunnel);{ - foreach ($legends as $val) // Loop on each serie + foreach ($legends as $val) // Loop on each serie { - if ($i > 0) $this->stringtoshow .= ', '; - $this->stringtoshow .= "'".dol_escape_js(dol_trunc($val, 32))."'"; - $i++; - } + if ($i > 0) $this->stringtoshow .= ', '; + $this->stringtoshow .= "'".dol_escape_js(dol_trunc($val, 32))."'"; + $i++; + } } //var_dump($arrayofgroupslegend); @@ -1271,17 +1270,16 @@ class DolGraph if ($isfunnel){ $this->stringtoshow .= 'borderWidth: \'2\', '; } - else if ($type == 'bar' || $type == 'horizontalBar') { + elseif ($type == 'bar' || $type == 'horizontalBar') { $this->stringtoshow .= 'borderWidth: \'1\', '; } $this->stringtoshow .= 'borderColor: \'' . $bordercolor . '\', '; $this->stringtoshow .= 'backgroundColor: \'' . $color . '\', '; if ($arrayofgroupslegend[$i]) $this->stringtoshow .= 'stack: \'' . $arrayofgroupslegend[$i]['stacknum'] . '\', '; $this->stringtoshow .='data: ['; - if($isfunnel){ + if ($isfunnel){ $this->stringtoshow .= '['.-$serie[$i].','.$serie[$i].']'; - - }else{ + }else { $this->stringtoshow .= $serie[$i]; } $this->stringtoshow .=']'; From 492715811c454f816f81913683933e7ba0e0f97e Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Thu, 10 Dec 2020 10:10:12 +0000 Subject: [PATCH 05/12] Fixing style errors. --- htdocs/core/boxes/box_funnel_of_prospection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/boxes/box_funnel_of_prospection.php b/htdocs/core/boxes/box_funnel_of_prospection.php index fd91b8c317f..6fd2795ccdb 100644 --- a/htdocs/core/boxes/box_funnel_of_prospection.php +++ b/htdocs/core/boxes/box_funnel_of_prospection.php @@ -135,7 +135,7 @@ class box_funnel_of_prospection extends ModeleBoxes } global $conf, $user, $langs; -data + data $this->max = $max; $this->info_box_head = array( From a57b01e9bafa7fb467727a4bced9f587630f9de8 Mon Sep 17 00:00:00 2001 From: Hystepik <45882981+Hystepik@users.noreply.github.com> Date: Thu, 10 Dec 2020 11:12:33 +0100 Subject: [PATCH 06/12] Update box_funnel_of_prospection.php --- htdocs/core/boxes/box_funnel_of_prospection.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/core/boxes/box_funnel_of_prospection.php b/htdocs/core/boxes/box_funnel_of_prospection.php index 6fd2795ccdb..5669fab7fe5 100644 --- a/htdocs/core/boxes/box_funnel_of_prospection.php +++ b/htdocs/core/boxes/box_funnel_of_prospection.php @@ -135,7 +135,6 @@ class box_funnel_of_prospection extends ModeleBoxes } global $conf, $user, $langs; - data $this->max = $max; $this->info_box_head = array( From 7360fcd03eff59eaa8bb4541ef23f5acf39237c0 Mon Sep 17 00:00:00 2001 From: Ferran Marcet Date: Thu, 10 Dec 2020 13:11:55 +0100 Subject: [PATCH 07/12] FIX: Bad rigths to send contract --- htdocs/contrat/card.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index dbdba874dda..368e09d8ccd 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -6,7 +6,7 @@ * Copyright (C) 2010-2017 Juanjo Menent * Copyright (C) 2013 Christophe Battarel * Copyright (C) 2013-2014 Florian Henry - * Copyright (C) 2014-2018 Ferran Marcet + * Copyright (C) 2014-2020 Ferran Marcet * Copyright (C) 2014-2016 Marcos García * Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2018-2020 Frédéric France @@ -2108,7 +2108,7 @@ else // Send if (empty($user->socid)) { if ($object->statut == 1) { - if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->commande->order_advance->send)) { + if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->contrat->creer)) { print ''; } else print ''; From 4f6923442a14da233b0554437d3add737cb155e0 Mon Sep 17 00:00:00 2001 From: lmarcouiller Date: Thu, 10 Dec 2020 13:19:10 +0100 Subject: [PATCH 08/12] fix merge and sql synthax --- htdocs/core/boxes/box_funnel_of_prospection.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/boxes/box_funnel_of_prospection.php b/htdocs/core/boxes/box_funnel_of_prospection.php index 5669fab7fe5..50b61f8de0e 100644 --- a/htdocs/core/boxes/box_funnel_of_prospection.php +++ b/htdocs/core/boxes/box_funnel_of_prospection.php @@ -97,8 +97,8 @@ class box_funnel_of_prospection extends ModeleBoxes $sql = "SELECT cls.rowid, cls.code, cls.percent, cls.label"; $sql .= " FROM " . MAIN_DB_PREFIX . "c_lead_status as cls"; $sql .= " WHERE active=1"; - $sql .= " Order by cls.rowid"; - $sql .= " AND cls.code != 'LOST'"; + $sql .= " AND cls.code <> 'LOST'"; + $sql .= $this->db->order('cls.rowid','ASC'); $resql = $this->db->query($sql); if ($resql) { $num = $this->db->num_rows($resql); @@ -201,7 +201,7 @@ class box_funnel_of_prospection extends ModeleBoxes } $data[] = (isset($valsamount[$status]) ? (float) $valsamount[$status] : 0); - + $liststatus[] = $labelStatus; if (!$conf->use_javascript_ajax) { $stringtoprint .= ''; $stringtoprint .= '' . $labelStatus . ''; From 0a2f6561377697b1ecf1a0f5f54589de5e9e1aa1 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Thu, 10 Dec 2020 12:19:43 +0000 Subject: [PATCH 09/12] Fixing style errors. --- htdocs/core/boxes/box_funnel_of_prospection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/boxes/box_funnel_of_prospection.php b/htdocs/core/boxes/box_funnel_of_prospection.php index 50b61f8de0e..44b2bd9a90d 100644 --- a/htdocs/core/boxes/box_funnel_of_prospection.php +++ b/htdocs/core/boxes/box_funnel_of_prospection.php @@ -98,7 +98,7 @@ class box_funnel_of_prospection extends ModeleBoxes $sql .= " FROM " . MAIN_DB_PREFIX . "c_lead_status as cls"; $sql .= " WHERE active=1"; $sql .= " AND cls.code <> 'LOST'"; - $sql .= $this->db->order('cls.rowid','ASC'); + $sql .= $this->db->order('cls.rowid', 'ASC'); $resql = $this->db->query($sql); if ($resql) { $num = $this->db->num_rows($resql); From 716bb433e8e576edd730f379176b7342eab7a1e5 Mon Sep 17 00:00:00 2001 From: lmarcouiller Date: Thu, 10 Dec 2020 15:50:18 +0100 Subject: [PATCH 10/12] ajout pictogramme graph dans info box head --- htdocs/core/boxes/box_funnel_of_prospection.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/boxes/box_funnel_of_prospection.php b/htdocs/core/boxes/box_funnel_of_prospection.php index 44b2bd9a90d..e75e8959a03 100644 --- a/htdocs/core/boxes/box_funnel_of_prospection.php +++ b/htdocs/core/boxes/box_funnel_of_prospection.php @@ -139,7 +139,7 @@ class box_funnel_of_prospection extends ModeleBoxes $this->info_box_head = array( 'text' => $langs->trans("Statistics") . ' - ' . $langs->trans("OpportunitiesStatusForOpenedProjects"), - $max + 'graph' => '1' ); if ($user->rights->projet->lire || !empty($conf->global->PROJECT_USE_OPPORTUNITIES)) { @@ -224,7 +224,7 @@ class box_funnel_of_prospection extends ModeleBoxes $dolgraph->SetType(array('horizontalbars')); $dolgraph->SetHeight('200'); $dolgraph->SetWidth('600'); - $dolgraph->mode='depth'; + $dolgraph->mode = 'depth'; $dolgraph->draw('idgraphstatus'); $stringtoprint .= $dolgraph->show($totaloppnb ? 0 : 1); } From 4fcd3fe49332baab0e424225ad10b76b47ebcbac Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 11 Dec 2020 15:11:51 +0100 Subject: [PATCH 11/12] =?UTF-8?q?Fix=20disallow=20--=20string=20into=20fil?= =?UTF-8?q?ename=20for=20security=20purpose.=20Vulnerability=20reported=20?= =?UTF-8?q?by=20Y=C4=B1lmaz=20De=C4=9Firmenci?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- htdocs/admin/tools/export_files.php | 2 +- htdocs/core/lib/functions.lib.php | 5 +++-- test/phpunit/SecurityTest.php | 25 ++++++++++++++++++++++++- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/htdocs/admin/tools/export_files.php b/htdocs/admin/tools/export_files.php index de10759c92d..587750d129e 100644 --- a/htdocs/admin/tools/export_files.php +++ b/htdocs/admin/tools/export_files.php @@ -34,7 +34,7 @@ $action = GETPOST('action', 'alpha'); $what = GETPOST('what', 'alpha'); $export_type = GETPOST('export_type', 'alpha'); $file = trim(GETPOST('zipfilename_template', 'alpha')); -$compression = GETPOST('compression'); +$compression = GETPOST('compression', 'aZ09'); $file = dol_sanitizeFileName($file); $file = preg_replace('/(\.zip|\.tar|\.tgz|\.gz|\.tar\.gz|\.bz2)$/i', '', $file); diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 5094fad392a..37791d1e72d 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -866,8 +866,9 @@ function dol_sanitizeFileName($str, $newstr = '_', $unaccent = 1) // List of special chars for filenames in windows are defined on page https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file // Char '>' '<' '|' '$' and ';' are special chars for shells. // Char '/' and '\' are file delimiters. - $filesystem_forbidden_chars = array('<', '>', '/', '\\', '?', '*', '|', '"', ':', '°', '$', ';'); - return dol_string_nospecial($unaccent ?dol_string_unaccent($str) : $str, $newstr, $filesystem_forbidden_chars); + // -- car can be used into filename to inject special paramaters like --use-compress-program to make command with file as parameter making remote execution of command + $filesystem_forbidden_chars = array('<', '>', '/', '\\', '?', '*', '|', '"', ':', '°', '$', ';', '--'); + return dol_string_nospecial($unaccent ? dol_string_unaccent($str) : $str, $newstr, $filesystem_forbidden_chars); } /** diff --git a/test/phpunit/SecurityTest.php b/test/phpunit/SecurityTest.php index 5a248006498..6d2a3cf3cd8 100644 --- a/test/phpunit/SecurityTest.php +++ b/test/phpunit/SecurityTest.php @@ -244,7 +244,7 @@ class SecurityTest extends PHPUnit\Framework\TestCase $login=checkLoginPassEntity('admin', 'admin', 1, array('dolibarr')); // Should works because admin/admin exists print __METHOD__." login=".$login."\n"; - $this->assertEquals($login, 'admin'); + $this->assertEquals($login, 'admin', 'The test to check if pass of user "admin" is "admin" has failed'); $login=checkLoginPassEntity('admin', 'admin', 1, array('http','dolibarr')); // Should work because of second authetntication method print __METHOD__." login=".$login."\n"; @@ -326,4 +326,27 @@ class SecurityTest extends PHPUnit\Framework\TestCase $result=restrictedArea($user, 'societe'); $this->assertEquals(1, $result); } + + /** + * testDolSanitizeFileName + * + * @return void + */ + public function testDolSanitizeFileName() + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + + //$dummyuser=new User($db); + //$result=restrictedArea($dummyuser,'societe'); + + $result=dol_sanitizeFileName('bad file | evilaction'); + $this->assertEquals('bad file _ evilaction', $result); + + $result=dol_sanitizeFileName('bad file --evilparam'); + $this->assertEquals('bad file _evilparam', $result); + } } From 8a0c06516336fbe5c45e80e233a437d5f23369f6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 11 Dec 2020 16:30:45 +0100 Subject: [PATCH 12/12] Debug v13 --- htdocs/core/class/html.form.class.php | 4 ++-- htdocs/core/lib/ajax.lib.php | 2 +- htdocs/product/class/product.class.php | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index e1e1fc45228..b487d3f3043 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -6197,6 +6197,7 @@ class Form $tmpfieldstoshow = ''; foreach ($objecttmp->fields as $key => $val) { + if (!dol_eval($val['enabled'], 1, 1)) continue; if ($val['showoncombobox']) $tmpfieldstoshow .= ($tmpfieldstoshow ? ',' : '').'t.'.$key; } if ($tmpfieldstoshow) $fieldstoshow = $tmpfieldstoshow; @@ -6294,8 +6295,7 @@ class Form } if (empty($outputmode)) { - if ($preselectedvalue > 0 && $preselectedvalue == $obj->rowid) - { + if ($preselectedvalue > 0 && $preselectedvalue == $obj->rowid) { $out .= ''; } else { $out .= ''; diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php index 5bcf73ca896..d1c1540cb8a 100644 --- a/htdocs/core/lib/ajax.lib.php +++ b/htdocs/core/lib/ajax.lib.php @@ -34,7 +34,7 @@ * @param string $url Ajax Url to call for request: /path/page.php. Must return a json array ('key'=>id, 'value'=>String shown into input field once selected, 'label'=>String shown into combo list) * @param string $urloption More parameters on URL request * @param int $minLength Minimum number of chars to trigger that Ajax search - * @param int $autoselect Automatic selection if just one value + * @param int $autoselect Automatic selection if just one value (trigger("change") on field is done is search return only 1 result) * @param array $ajaxoptions Multiple options array * - Ex: array('update'=>array('field1','field2'...)) will reset field1 and field2 once select done * - Ex: array('disabled'=> ) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 6505741d5a2..bcf32cdce26 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -413,6 +413,7 @@ class Product extends CommonObject public $fields = array( 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'index'=>1, 'position'=>1, 'comment'=>'Id'), 'ref' =>array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'showoncombobox'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'comment'=>'Reference of object'), + 'barcode' =>array('type'=>'varchar(255)', 'label'=>'Barcode', 'enabled'=>'!empty($conf->barcode->enabled)', 'visible'=>-1, 'showoncombobox'=>1), 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'default'=>1, 'notnull'=>1, 'index'=>1, 'position'=>20), 'label' =>array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'showoncombobox'=>1), 'note_public' =>array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>61),