2006-12-07 13:41:40 +00:00
##############################################################################
#
# Copyright (c) 2005-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import ir
import os , time
import netsvc
import random
import StringIO
import tools
import pooler
from report . render import render
from report . interface import report_int
from pychart import *
theme . use_color = 1
#theme.scale = 2
random . seed ( 0 )
class external_pdf ( render ) :
def __init__ ( self , pdf ) :
render . __init__ ( self )
self . pdf = pdf
self . output_type = ' pdf '
def _render ( self ) :
return self . pdf
class report_custom ( report_int ) :
def create ( self , cr , uid , ids , datas , context = { } ) :
assert len ( ids ) , ' You should provide some ids! '
responsible_data = { }
responsible_names = { }
data = [ ]
minbenef = 999999999999999999999
maxbenef = 0
cr . execute ( ' select probability, planned_revenue, planned_cost, user_id, res_users.name as name from crm_case left join res_users on (crm_case.user_id=res_users.id) where crm_case.id in ( ' + ' , ' . join ( map ( str , ids ) ) + ' ) order by user_id ' )
res = cr . dictfetchall ( )
for row in res :
proba = row [ ' probability ' ] or 0
cost = row [ ' planned_cost ' ] or 0
revenue = row [ ' planned_revenue ' ] or 0
userid = row [ ' user_id ' ] or 0
benefit = revenue - cost
if benefit > maxbenef :
maxbenef = benefit
if benefit < minbenef :
minbenef = benefit
tuple = ( proba * 100 , benefit )
responsible_data . setdefault ( userid , [ ] )
responsible_data [ userid ] . append ( tuple )
tuple = ( proba * 100 , cost , benefit )
data . append ( tuple )
responsible_names [ userid ] = ( row [ ' name ' ] or ' / ' ) . replace ( ' / ' , ' // ' )
minbenef - = maxbenef * 0.05
maxbenef * = 1.2
ratio = 0.5
minmaxdiff2 = ( maxbenef - minbenef ) / 2
for l in responsible_data . itervalues ( ) :
for i in range ( len ( l ) ) :
percent , benef = l [ i ]
proba = percent / 100
current_ratio = 1 + ( ratio - 1 ) * proba
newbenef = minmaxdiff2 + ( ( benef - minbenef - minmaxdiff2 ) * current_ratio )
l [ i ] = ( percent , newbenef )
#TODO:
#-group by "categorie de probabilites ds graphe du haut"
#-echelle variable
2006-12-07 21:45:55 +00:00
2006-12-07 13:41:40 +00:00
pdf_string = StringIO . StringIO ( )
can = canvas . init ( fname = pdf_string , format = ' pdf ' )
chart_object . set_defaults ( line_plot . T , line_style = None )
xaxis = axis . X ( label = None , format = " %d %% " , tic_interval = 20 )
yaxis = axis . Y ( )
2006-12-07 21:45:55 +00:00
ar = area . T (
size = ( 300 , 200 ) ,
y_grid_interval = 10000 ,
y_grid_style = None ,
x_range = ( 0 , 100 ) ,
y_range = ( minbenef , maxbenef ) ,
x_axis = xaxis ,
y_axis = None ,
legend = legend . T ( )
)
2006-12-07 13:41:40 +00:00
for k , d in responsible_data . iteritems ( ) :
fill = fill_style . Plain ( bgcolor = color . T ( r = random . random ( ) , g = random . random ( ) , b = random . random ( ) ) )
tick = tick_mark . Square ( size = 6 , fill_style = fill )
ar . add_plot ( line_plot . T ( label = responsible_names [ k ] , data = d , tick_mark = tick ) )
ar . draw ( can )
# second graph (top right)
ar = area . T ( legend = legend . T ( ) ,
size = ( 200 , 100 ) ,
loc = ( 100 , 250 ) ,
2006-12-07 21:45:55 +00:00
x_grid_interval = lambda min , max : [ 40 , 60 , 80 , 100 ] ,
2006-12-07 13:41:40 +00:00
x_grid_style = line_style . gray70_dash1 ,
x_range = ( 33 , 100 ) ,
x_axis = axis . X ( label = None , minor_tic_interval = lambda min , max : [ 50 , 70 , 90 ] , format = lambda x : " " ) ,
y_axis = axis . Y ( label = " Planned amounts " ) )
bar_plot . fill_styles . reset ( ) ;
plot1 = bar_plot . T ( label = " Cost " , data = data , fill_style = fill_style . red )
plot2 = bar_plot . T ( label = " Revenue " , data = data , hcol = 2 , stack_on = plot1 , fill_style = fill_style . blue )
ar . add_plot ( plot1 , plot2 )
ar . draw ( can )
# diagonal "pipeline" lines
can . line ( line_style . black , 0 , 200 , 300 , 150 )
can . line ( line_style . black , 0 , 0 , 300 , 50 )
# vertical lines
ls = line_style . T ( width = 0.4 , color = color . gray70 , dash = ( 2 , 2 ) )
for x in range ( 120 , 300 , 60 ) :
can . line ( ls , x , 0 , x , 250 )
# draw arrows to the right
a = arrow . fat1
for y in range ( 60 , 150 , 10 ) :
a . draw ( [ ( 285 , y ) , ( 315 , y ) ] , can = can )
# close canvas so that the file is written to "disk"
can . close ( )
self . obj = external_pdf ( pdf_string . getvalue ( ) )
self . obj . render ( )
pdf_string . close ( )
return ( self . obj . pdf , ' pdf ' )
report_custom ( ' report.crm.case ' )