FIX Several fix to exclude WON/LOST of reporting of opportunities amount

(sometimes we need, sometimes not).
This commit is contained in:
Laurent Destailleur 2016-07-08 10:59:13 +02:00
parent f47fc3c6ba
commit d940cc392a
10 changed files with 68 additions and 34 deletions

View File

@ -388,6 +388,12 @@ abstract class Stats
if($i>0 && $row->total) $result[$i-1]['total_diff'] = ($result[$i-1]['total'] - $row->total) / $row->total * 100; if($i>0 && $row->total) $result[$i-1]['total_diff'] = ($result[$i-1]['total'] - $row->total) / $row->total * 100;
$result[$i]['avg'] = $row->avg; $result[$i]['avg'] = $row->avg;
if($i>0 && $row->avg) $result[$i-1]['avg_diff'] = ($result[$i-1]['avg'] - $row->avg) / $row->avg * 100; if($i>0 && $row->avg) $result[$i-1]['avg_diff'] = ($result[$i-1]['avg'] - $row->avg) / $row->avg * 100;
// For some $sql only
if (isset($row->weighted))
{
$result[$i]['weighted'] = $row->weighted;
if($i>0 && $row->weighted) $result[$i-1]['avg_weighted'] = ($result[$i-1]['weighted'] - $row->weighted) / $row->weighted * 100;
}
$i++; $i++;
} }
$this->db->free($resql); $this->db->free($resql);

View File

@ -483,12 +483,12 @@ update llx_product_batch set batch = '000000' where batch = '';
update llx_product_lot set batch = '000000' where batch = 'Undefined'; update llx_product_lot set batch = '000000' where batch = 'Undefined';
update llx_stock_mouvement set batch = '000000' where batch = 'Undefined'; update llx_stock_mouvement set batch = '000000' where batch = 'Undefined';
ALTER TABLE llx_import_model MODIFY COLUMN type varchar(50);
-- At end (higher risk of error)
-- VMYSQL4.1 ALTER TABLE llx_c_type_resource CHANGE COLUMN rowid rowid integer NOT NULL AUTO_INCREMENT; UPDATE llx_projet set fk_opp_status = NULL where fk_opp_status = -1;
UPDATE llx_c_lead_status set code = 'WON' where code = 'WIN';
ALTER TABLE llx_product_batch ADD UNIQUE INDEX uk_product_batch (fk_product_stock, batch);
CREATE TABLE llx_oauth_token ( CREATE TABLE llx_oauth_token (
rowid integer AUTO_INCREMENT PRIMARY KEY, rowid integer AUTO_INCREMENT PRIMARY KEY,
@ -508,4 +508,10 @@ CREATE TABLE llx_oauth_state (
entity integer entity integer
)ENGINE=InnoDB; )ENGINE=InnoDB;
ALTER TABLE llx_import_model MODIFY COLUMN type varchar(50); -- At end (higher risk of error)
-- VMYSQL4.1 ALTER TABLE llx_c_type_resource CHANGE COLUMN rowid rowid integer NOT NULL AUTO_INCREMENT;
ALTER TABLE llx_product_batch ADD UNIQUE INDEX uk_product_batch (fk_product_stock, batch);

View File

@ -202,6 +202,8 @@ UPDATE llx_actioncomm set fk_user_action = fk_user_author where fk_user_author >
UPDATE llx_projet_task_time set task_datehour = task_date where task_datehour IS NULL and task_date IS NOT NULL; UPDATE llx_projet_task_time set task_datehour = task_date where task_datehour IS NULL and task_date IS NOT NULL;
UPDATE llx_projet set fk_opp_status = NULL where fk_opp_status = -1;
UPDATE llx_c_lead_status set code = 'WON' where code = 'WIN';
-- Requests to clean old tables or external modules tables -- Requests to clean old tables or external modules tables

View File

@ -130,6 +130,9 @@ OpportunityProbability=Opportunity probability
OpportunityProbabilityShort=Opp. probab. OpportunityProbabilityShort=Opp. probab.
OpportunityAmount=Opportunity amount OpportunityAmount=Opportunity amount
OpportunityAmountShort=Opp. amount OpportunityAmountShort=Opp. amount
OpportunityAmountAverageShort=Average Opp. amount
OpportunityAmountWeigthedShort=Weighted Opp. amount
WonLostExcluded=Won/Lost excluded
##### Types de contacts ##### ##### Types de contacts #####
TypeContact_project_internal_PROJECTLEADER=Project leader TypeContact_project_internal_PROJECTLEADER=Project leader
TypeContact_project_external_PROJECTLEADER=Project leader TypeContact_project_external_PROJECTLEADER=Project leader

View File

@ -248,7 +248,7 @@ class Project extends CommonObject
$sql.= ", description = '" . $this->db->escape($this->description) . "'"; $sql.= ", description = '" . $this->db->escape($this->description) . "'";
$sql.= ", fk_soc = " . ($this->socid > 0 ? $this->socid : "null"); $sql.= ", fk_soc = " . ($this->socid > 0 ? $this->socid : "null");
$sql.= ", fk_statut = " . $this->statut; $sql.= ", fk_statut = " . $this->statut;
$sql.= ", fk_opp_status = " . ((is_numeric($this->opp_status) && $this->opp_status != '') ? $this->opp_status : 'null'); $sql.= ", fk_opp_status = " . ((is_numeric($this->opp_status) && $this->opp_status > 0) ? $this->opp_status : 'null');
$sql.= ", opp_percent = " . ((is_numeric($this->opp_percent) && $this->opp_percent != '') ? $this->opp_percent : 'null'); $sql.= ", opp_percent = " . ((is_numeric($this->opp_percent) && $this->opp_percent != '') ? $this->opp_percent : 'null');
$sql.= ", public = " . ($this->public ? 1 : 0); $sql.= ", public = " . ($this->public ? 1 : 0);
$sql.= ", datec=" . ($this->date_c != '' ? "'".$this->db->idate($this->date_c)."'" : 'null'); $sql.= ", datec=" . ($this->date_c != '' ? "'".$this->db->idate($this->date_c)."'" : 'null');

View File

@ -41,7 +41,8 @@ class ProjectStats extends Stats
/** /**
* Return all leads grouped by status * Return all leads grouped by status.
* Warning: There is no filter on WON/LOST because we want this for statistics.
* *
* @param int $limit Limit results * @param int $limit Limit results
* @return array|int Array with value or -1 if error * @return array|int Array with value or -1 if error
@ -58,7 +59,7 @@ class ProjectStats extends Stats
$sql .= " FROM " . MAIN_DB_PREFIX . "projet as t, ".MAIN_DB_PREFIX."c_lead_status as cls"; $sql .= " FROM " . MAIN_DB_PREFIX . "projet as t, ".MAIN_DB_PREFIX."c_lead_status as cls";
$sql .= $this->buildWhere(); $sql .= $this->buildWhere();
$sql .= " AND t.fk_opp_status = cls.rowid"; $sql .= " AND t.fk_opp_status = cls.rowid";
$sql .= " AND t.fk_statut <> 0"; // We want historic also, so all projects $sql .= " AND t.fk_statut <> 0"; // We want historic also, so all projects not draft
$sql .= " GROUP BY t.fk_opp_status, cls.code, cls.label"; $sql .= " GROUP BY t.fk_opp_status, cls.code, cls.label";
$result = array (); $result = array ();
@ -110,13 +111,16 @@ class ProjectStats extends Stats
$datay = array (); $datay = array ();
$sql = "SELECT date_format(t.datec,'%Y') as year, COUNT(t.rowid) as nb, SUM(t.opp_amount) as total, AVG(t.opp_amount) as avg"; $wonlostfilter=0; // No filter on status WON/LOST
$sql .= " FROM " . MAIN_DB_PREFIX . "projet as t";
$sql = "SELECT date_format(t.datec,'%Y') as year, COUNT(t.rowid) as nb, SUM(t.opp_amount) as total, AVG(t.opp_amount) as avg,";
$sql.= " SUM(t.opp_amount * ".$this->db->ifsql("t.opp_percent IS NULL".($wonlostfilter?" OR cls.code IN ('WON','LOST')":""), '0', 't.opp_percent')." / 100) as weighted";
$sql.= " FROM " . MAIN_DB_PREFIX . "projet as t LEFT JOIN ".MAIN_DB_PREFIX."c_lead_status as cls ON cls.rowid = t.fk_opp_status";
if (! $user->rights->societe->client->voir && ! $user->societe_id) if (! $user->rights->societe->client->voir && ! $user->societe_id)
$sql .= " INNER JOIN " . MAIN_DB_PREFIX . "societe_commerciaux as sc ON sc.fk_soc=t.fk_soc AND sc.fk_user=" . $user->id; $sql .= " INNER JOIN " . MAIN_DB_PREFIX . "societe_commerciaux as sc ON sc.fk_soc=t.fk_soc AND sc.fk_user=" . $user->id;
$sql .= $this->buildWhere(); $sql.= $this->buildWhere();
$sql .= " GROUP BY year"; $sql.= " GROUP BY year";
$sql .= $this->db->order('year', 'DESC'); $sql.= $this->db->order('year', 'DESC');
return $this->_getAllByYear($sql); return $this->_getAllByYear($sql);
} }
@ -213,9 +217,10 @@ class ProjectStats extends Stats
* @param int $endyear Start year * @param int $endyear Start year
* @param int $startyear End year * @param int $startyear End year
* @param int $cachedelay Delay we accept for cache file (0=No read, no save of cache, -1=No read but save) * @param int $cachedelay Delay we accept for cache file (0=No read, no save of cache, -1=No read but save)
* @param int $wonlostfilter Add a filter on status won/lost
* @return array Array of values * @return array Array of values
*/ */
function getWeightedAmountByMonthWithPrevYear($endyear,$startyear,$cachedelay=0) function getWeightedAmountByMonthWithPrevYear($endyear,$startyear,$cachedelay=0,$wonlostfilter=1)
{ {
global $conf,$user,$langs; global $conf,$user,$langs;
@ -262,7 +267,7 @@ class ProjectStats extends Stats
$year=$startyear; $year=$startyear;
while($year <= $endyear) while($year <= $endyear)
{ {
$datay[$year] = $this->getWeightedAmountByMonth($year); $datay[$year] = $this->getWeightedAmountByMonth($year,$wonlostfilter);
$year++; $year++;
} }
@ -302,18 +307,19 @@ class ProjectStats extends Stats
/** /**
* Return the Project weighted opp amount by month for a year * Return the Project weighted opp amount by month for a year.
* *
* @param int $year scan * @param int $year Year to scan
* @return array with amount by month * @param int $wonlostfilter Add a filter on status won/lost
* @return array Array with amount by month
*/ */
function getWeightedAmountByMonth($year) function getWeightedAmountByMonth($year, $wonlostfilter=1)
{ {
global $user; global $user;
$this->yearmonth = $year; $this->yearmonth = $year;
$sql = "SELECT date_format(t.datec,'%m') as dm, SUM(t.opp_amount * ".$this->db->ifsql('cls.percent IS NULL', '0', 'cls.percent')." / 100)"; $sql = "SELECT date_format(t.datec,'%m') as dm, SUM(t.opp_amount * ".$this->db->ifsql("t.opp_percent IS NULL".($wonlostfilter?" OR cls.code IN ('WON','LOST')":""), '0', 't.opp_percent')." / 100)";
$sql .= " FROM " . MAIN_DB_PREFIX . "projet as t LEFT JOIN ".MAIN_DB_PREFIX.'c_lead_status as cls ON t.fk_opp_status = cls.rowid'; $sql .= " FROM " . MAIN_DB_PREFIX . "projet as t LEFT JOIN ".MAIN_DB_PREFIX.'c_lead_status as cls ON t.fk_opp_status = cls.rowid';
if (! $user->rights->societe->client->voir && ! $user->societe_id) if (! $user->rights->societe->client->voir && ! $user->societe_id)
$sql .= " INNER JOIN " . MAIN_DB_PREFIX . "societe_commerciaux as sc ON sc.fk_soc=t.fk_soc AND sc.fk_user=" . $user->id; $sql .= " INNER JOIN " . MAIN_DB_PREFIX . "societe_commerciaux as sc ON sc.fk_soc=t.fk_soc AND sc.fk_user=" . $user->id;

View File

@ -1,13 +1,14 @@
<?php <?php
if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES))
{ {
$sql = "SELECT COUNT(p.rowid) as nb, SUM(p.opp_amount) as opp_amount, SUM(p.opp_amount * p.opp_percent) as ponderated_opp_amount, p.fk_opp_status as opp_status"; $sql = "SELECT p.fk_opp_status as opp_status, cls.code, COUNT(p.rowid) as nb, SUM(p.opp_amount) as opp_amount, SUM(p.opp_amount * p.opp_percent) as ponderated_opp_amount";
$sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; $sql.= " FROM ".MAIN_DB_PREFIX."projet as p, ".MAIN_DB_PREFIX."c_lead_status as cls";
$sql.= " WHERE p.entity = ".$conf->entity; $sql.= " WHERE p.entity = ".$conf->entity;
$sql.= " AND p.fk_statut = 1"; $sql.= " AND p.fk_opp_status = cls.rowid";
$sql.= " AND p.fk_statut = 1"; // Opend projects only
if ($mine || empty($user->rights->projet->all->lire)) $sql.= " AND p.rowid IN (".$projectsListId.")"; if ($mine || empty($user->rights->projet->all->lire)) $sql.= " AND p.rowid IN (".$projectsListId.")";
if ($socid) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")"; if ($socid) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")";
$sql.= " GROUP BY p.fk_opp_status"; $sql.= " GROUP BY p.fk_opp_status, cls.code";
$resql = $db->query($sql); $resql = $db->query($sql);
if ($resql) if ($resql)
@ -34,8 +35,11 @@ if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES))
$valsamount[$obj->opp_status]=$obj->opp_amount; $valsamount[$obj->opp_status]=$obj->opp_amount;
$totalnb+=$obj->nb; $totalnb+=$obj->nb;
if ($obj->opp_status) $totaloppnb+=$obj->nb; if ($obj->opp_status) $totaloppnb+=$obj->nb;
$totalamount+=$obj->opp_amount; if (! in_array($obj->code, array('WON', 'LOST')))
$ponderated_opp_amount+=$obj->ponderated_opp_amount; {
$totalamount+=$obj->opp_amount;
$ponderated_opp_amount+=$obj->ponderated_opp_amount;
}
} }
$total+=$row[0]; $total+=$row[0];
} }
@ -79,8 +83,11 @@ if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES))
} }
//if ($totalinprocess != $total) //if ($totalinprocess != $total)
//print '<tr class="liste_total"><td>'.$langs->trans("Total").' ('.$langs->trans("CustomersOrdersRunning").')</td><td align="right">'.$totalinprocess.'</td></tr>'; //print '<tr class="liste_total"><td>'.$langs->trans("Total").' ('.$langs->trans("CustomersOrdersRunning").')</td><td align="right">'.$totalinprocess.'</td></tr>';
print '<tr class="liste_total"><td>'.$langs->trans("OpportunityTotalAmount").'</td><td align="right">'.price($totalamount, 0, '', 1, -1, -1, $conf->currency).'</td></tr>'; print '<tr class="liste_total"><td>'.$langs->trans("OpportunityTotalAmount").' ('.$langs->trans("WonLostExcluded").')</td><td align="right">'.price($totalamount, 0, '', 1, -1, -1, $conf->currency).'</td></tr>';
print '<tr class="liste_total"><td>'.$langs->trans("OpportunityPonderatedAmount").'</td><td align="right">'.price(price2num($ponderated_opp_amount,'MT'), 0, '', 1, -1, -1, $conf->currency).'</td></tr>'; print '<tr class="liste_total"><td>';
//print $langs->trans("OpportunityPonderatedAmount").' ('.$langs->trans("WonLostExcluded").')';
print $form->textwithpicto($langs->trans("OpportunityPonderatedAmount").' ('.$langs->trans("WonLostExcluded").')', $langs->trans("OpportunityPonderatedAmountDesc"), 1);
print '</td><td align="right">'.price(price2num($ponderated_opp_amount,'MT'), 0, '', 1, -1, -1, $conf->currency).'</td></tr>';
print "</table><br>"; print "</table><br>";
} }
else else

View File

@ -1,6 +1,6 @@
<?php <?php
/* Copyright (C) 2001-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org> /* Copyright (C) 2001-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
* Copyright (C) 2004-2015 Laurent Destailleur <eldy@users.sourceforge.net> * Copyright (C) 2004-2016 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2010 Regis Houssin <regis.houssin@capnetworks.com> * Copyright (C) 2005-2010 Regis Houssin <regis.houssin@capnetworks.com>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify

View File

@ -303,7 +303,7 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
$sql.= $db->plimit($limit + 1,$offset); $sql.= $db->plimit($limit + 1,$offset);
//print $sql;
dol_syslog("list allowed project", LOG_DEBUG); dol_syslog("list allowed project", LOG_DEBUG);
//print $sql; //print $sql;
$resql = $db->query($sql); $resql = $db->query($sql);

View File

@ -215,7 +215,7 @@ if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES))
if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES))
{ {
// Build graphic with transformation rate // Build graphic with transformation rate
$data = $stats_project->getWeightedAmountByMonthWithPrevYear($endyear,$startyear); $data = $stats_project->getWeightedAmountByMonthWithPrevYear($endyear,$startyear, 0, 0);
//var_dump($data); //var_dump($data);
// $data = array(array('Lib',val1,val2,val3),...) // $data = array(array('Lib',val1,val2,val3),...)
@ -253,6 +253,7 @@ if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES))
// Show array // Show array
$stats_project->year=0; $stats_project->year=0;
$data_all_year = $stats_project->getAllByYear(); $data_all_year = $stats_project->getAllByYear();
if (!empty($year)) $stats_project->year=$year; if (!empty($year)) $stats_project->year=$year;
$arrayyears=array(); $arrayyears=array();
foreach($data_all_year as $val) { foreach($data_all_year as $val) {
@ -307,8 +308,9 @@ print '<td align="center">'.$langs->trans("Year").'</td>';
print '<td align="right">'.$langs->trans("NbOfProjects").'</td>'; print '<td align="right">'.$langs->trans("NbOfProjects").'</td>';
if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES))
{ {
print '<td align="right">'.$langs->trans("OpportunityAmount").'</td>'; print '<td align="right">'.$langs->trans("OpportunityAmountShort").'</td>';
print '<td align="right">'.$langs->trans("AmountAverage").'</td>'; print '<td align="right">'.$langs->trans("OpportunityAmountAverageShort").'</td>';
print '<td align="right">'.$langs->trans("OpportunityAmountWeigthedShort").'</td>';
} }
print '</tr>'; print '</tr>';
@ -327,6 +329,7 @@ foreach ($data_all_year as $val)
{ {
print '<td align="right">0</td>'; print '<td align="right">0</td>';
print '<td align="right">0</td>'; print '<td align="right">0</td>';
print '<td align="right">0</td>';
} }
print '<td align="right">0</td>'; print '<td align="right">0</td>';
print '</tr>'; print '</tr>';
@ -337,8 +340,9 @@ foreach ($data_all_year as $val)
print '<td align="right">'.$val['nb'].'</td>'; print '<td align="right">'.$val['nb'].'</td>';
if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES))
{ {
print '<td align="right">'.price(price2num($val['total'],'MT'),1).'</td>'; print '<td align="right">'.($val['total']?price(price2num($val['total'],'MT'),1):'0').'</td>';
print '<td align="right">'.price(price2num($val['avg'],'MT'),1).'</td>'; print '<td align="right">'.($val['avg']?price(price2num($val['avg'],'MT'),1):'0').'</td>';
print '<td align="right">'.($val['weighted']?price(price2num($val['weighted'],'MT'),1):'0').'</td>';
} }
print '</tr>'; print '</tr>';
$oldyear=$year; $oldyear=$year;