bzr revid: fp@tinyerp.com-20100303074014-psur4r4lxo4h0kcw
This commit is contained in:
Fabien Pinckaers
2010-03-03 08:40:14 +01:00
30 changed files with 795 additions and 2233 deletions
+1 -76
View File
@@ -4,88 +4,13 @@
<!-- Example employee -->
<record id="timesheet_group1" model="resource.calendar">
<field name="name">38 Hours/Week</field>
</record>
<record id="employee1" model="hr.employee">
<field name="name">Fabien Pinckaers</field>
<field name="calendar_id" ref="timesheet_group1"/>
<field name="calendar_id" ref="resource.timesheet_group1"/>
<!--<field name="regime">45</field>-->
<field name="user_id" ref="base.user_root"/>
<!--<field name="holiday_max">25</field>-->
</record>
<record model="resource.calendar.week">
<field name="name">Monday morning</field>
<field name="dayofweek">0</field>
<field name="hour_from">08</field>
<field name="hour_to">12</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record model="resource.calendar.week">
<field name="name">Monday evening</field>
<field name="dayofweek">0</field>
<field name="hour_from">13</field>
<field name="hour_to">18</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record model="resource.calendar.week">
<field name="name">Tuesday morning</field>
<field name="dayofweek">1</field>
<field name="hour_from">08</field>
<field name="hour_to">12</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record model="resource.calendar.week">
<field name="name">Tuesday evening</field>
<field name="dayofweek">1</field>
<field name="hour_from">13</field>
<field name="hour_to">18</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record model="resource.calendar.week">
<field name="name">Wednesday morning</field>
<field name="dayofweek">2</field>
<field name="hour_from">08</field>
<field name="hour_to">12</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record model="resource.calendar.week">
<field name="name">Wednesday evening</field>
<field name="dayofweek">2</field>
<field name="hour_from">13</field>
<field name="hour_to">18</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record model="resource.calendar.week">
<field name="name">Thursday morning</field>
<field name="dayofweek">3</field>
<field name="hour_from">08</field>
<field name="hour_to">12</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record model="resource.calendar.week">
<field name="name">Thursday evening</field>
<field name="hour_from">13</field>
<field name="hour_to">18</field>
<field name="dayofweek">3</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record model="resource.calendar.week">
<field name="name">Friday morning</field>
<field name="dayofweek">4</field>
<field name="hour_from">08</field>
<field name="hour_to">12</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record model="resource.calendar.week">
<field name="name">Friday evening</field>
<field name="dayofweek">4</field>
<field name="hour_from">13</field>
<field name="hour_to">18</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
</data>
</openerp>
+3 -3
View File
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
#
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
@@ -15,7 +15,7 @@
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
@@ -26,7 +26,7 @@
"author" : "Tiny",
"website" : "http://www.openerp.com",
"category" : "Generic Modules/Production",
"depends" : ["stock", "hr", "purchase", "product","process"],
"depends" : ["stock", "resource", "purchase", "product","process"],
"description": """
This is the base module to manage the manufacturing process in Open ERP.
+16 -18
View File
@@ -1,26 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<!--
Resource: mrp.workcenter
-->
<record id="mrp_workcenter_0" model="mrp.workcenter">
<field name="name">Assembly workshop</field>
<field name="calendar_id" ref="hr.timesheet_group1"/>
<field name="type">hr</field>
<field name="calendar_id" ref="resource.timesheet_group1"/>
</record>
<record id="mrp_workcenter_1" model="mrp.workcenter">
<field name="name">Repairs workshop</field>
<field name="calendar_id" ref="hr.timesheet_group1"/>
<field name="type">hr</field>
<field name="calendar_id" ref="resource.timesheet_group1"/>
</record>
<!--
Resource: mrp.property.group
-->
<record id="mrp_property_group_ram" model="mrp.property.group">
<field name="name">RAM</field>
</record>
@@ -54,11 +52,11 @@
<record id="mrp_property_group_psu" model="mrp.property.group">
<field name="name">PSU</field>
</record>
<!--
Resource: mrp.property
-->
<record id="mrp_property_0" model="mrp.property">
<field name="group_id" ref="mrp_property_group_ram"/>
<field name="name">DDR 512MB PC400</field>
@@ -140,7 +138,7 @@
<!--
Resource: mrp.routing.workcenter
-->
<record id="mrp_routing_workcenter_0" model="mrp.routing.workcenter">
<field name="routing_id" ref="mrp_routing_0"/>
<field name="workcenter_id" ref="mrp_workcenter_0"/>
@@ -160,11 +158,11 @@
<field name="hour_nbr">3</field>
<field name="name">assembly main + processor + fan</field>
</record>
<!--
Resource: mrp.bom
-->
<record id="mrp_bom_0" model="mrp.bom">
<field name="name">Regular processor config</field>
<field name="product_uom" ref="product.product_uom_unit"/>
@@ -173,7 +171,7 @@
<field name="type">normal</field>
<field model="product.product" name="product_id" search="[('default_code','=','CPU_GEN')]"/>
</record>
<record id="mrp_bom_1" model="mrp.bom">
<field name="name">Assembly Basic+ PC</field>
<field name="product_uom" ref="product.product_uom_unit"/>
@@ -249,14 +247,14 @@
<field name="type">phantom</field>
<field model="product.product" name="product_id" search="[('default_code','=','RAM_GEN')]"/>
</record>
<record id="mrp_bom_13" model="mrp.bom">
<field name="name">High Speed Processor + main board on demand</field>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field model="product.product" name="product_id" search="[('default_code','=','CPU2')]"/>
</record>
<record id="mrp_bom_kit" model="mrp.bom">
<field name="code">KIT</field>
<field name="name">Kit Mouse</field>
@@ -486,7 +484,7 @@
<field name="bom_id" ref="mrp_bom_9"/>
<field model="product.product" name="product_id" search="[('default_code','=','TOW1')]"/>
</record>
<record id="mrp_bom_kit2" model="mrp.bom">
<field name="code">KIT</field>
<field name="name">Kit Keyboard + Mouse</field>
@@ -510,6 +508,6 @@
<field name="bom_id" ref="mrp_bom_kit2"/>
<field model="product.product" name="product_id" search="[('default_code','=','KEYA')]"/>
</record>
</data>
</openerp>
+1 -1
View File
@@ -26,7 +26,7 @@
"author" : "Tiny",
"website" : "http://www.openerp.com",
"category" : "Generic Modules/Projects & Services",
"depends" : ["product", "analytic", "hr", "process", "mail_gateway"],
"depends" : ["product", "analytic", "process", "mail_gateway"],
"description": """Project management module that track multi-level projects, tasks,
works done on tasks, eso. It is able to render planning, order tasks, eso.
""",
+3 -100
View File
@@ -134,8 +134,7 @@ class project(osv.osv):
'warn_customer': fields.boolean('Warn Partner', help="If you check this, the user will have a popup when closing a task that propose a message to send by email to the customer."),
'warn_header': fields.text('Mail Header', help="Header added at the beginning of the email for the warning message sent to the customer when a task is closed."),
'warn_footer': fields.text('Mail Footer', help="Footer added at the beginning of the email for the warning message sent to the customer when a task is closed."),
'resource_calendar_id': fields.many2one('resource.calendar', 'Working Time', help="Timetable working hours to adjust the gantt diagram report"),
# 'state': fields.selection([('template', 'Template'), ('open', 'Running'), ('pending', 'Pending'), ('cancelled', 'Cancelled'), ('done', 'Done')], 'State', required=True, readonly=True,
# 'state': fields.selection([('template', 'Template'), ('open', 'Running'), ('pending', 'Pending'), ('cancelled', 'Cancelled'), ('done', 'Done')], 'State', required=True, readonly=True,
# help='The project can be in either if the states \'Template\' and \'Running\'.\n If it is template then we can make projects based on the template projects. If its in \'Running\' state it is a normal project.\
# \n If it is to be reviewed then the state is \'Pending\'.\n When the project is completed the state is set to \'Done\'.'),
'type_ids': fields.many2many('project.task.type', 'project_task_type_rel', 'project_id', 'type_id', 'Tasks Stages'),
@@ -256,25 +255,8 @@ class task(osv.osv):
res[task.id]['delay_hours'] = res[task.id]['total_hours'] - task.planned_hours
return res
def onchange_planned(self, cr, uid, ids, project, user_id = False,planned=0.0, effective=0.0,date_start=None,occupation_rate=0.0):
result = {}
if date_start:
resource_pool = self.pool.get('resource.resource')
project_pool = self.pool.get('project.project')
resource_calendar = self.pool.get('resource.calendar')
dt_start = mx.DateTime.strptime(date_start,'%Y-%m-%d %H:%M:%S')
resource_id = resource_pool.search(cr,uid,[('user_id','=',user_id)])
if resource_id:
resource_obj = resource_pool.browse(cr,uid,resource_id)[0]
hrs = planned/(float(occupation_rate) * resource_obj.time_efficiency)
calendar_id = resource_obj.calendar_id.id
else:
hrs = float(planned / occupation_rate)
calendar_id = project_pool.browse(cr,uid,project).resource_calendar_id .id
work_times = resource_calendar.interval_get(cr, uid, calendar_id or False, dt_start, hrs or 0.0,resource_id or False)
result['date_end'] = work_times[-1][1].strftime('%Y-%m-%d %H:%M:%S')
result['remaining_hours'] = planned-effective
return {'value':result}
def onchange_planned(self, cr, uid, ids, planned = 0.0, effective = 0.0):
return {'value':{'remaining_hours' : planned - effective}}
def _default_project(self, cr, uid, context={}):
if 'project_id' in context and context['project_id']:
@@ -315,7 +297,6 @@ class task(osv.osv):
'parent_ids': fields.many2many('project.task', 'project_task_parent_rel', 'task_id', 'parent_id', 'Parent Tasks'),
'child_ids': fields.many2many('project.task', 'project_task_parent_rel', 'parent_id', 'task_id', 'Delegated Tasks'),
'notes': fields.text('Notes'),
'occupation_rate': fields.float('Occupation Rate', help='The occupation rate fields indicates how much of his time a user is working on a task. A 100% occupation rate means the user works full time on the tasks. The ending date of a task is computed like this: Starting Date + Duration / Occupation Rate.'),
'planned_hours': fields.float('Planned Hours', required=True, help='Estimated time to do the task, usually set by the project manager when the task is in draft state.'),
'effective_hours': fields.function(_hours_get, method=True, string='Hours Spent', multi='hours', store=True, help="Computed using the sum of the task work done."),
'remaining_hours': fields.float('Remaining Hours', digits=(16,4), help="Total remaining time, can be re-estimated periodically by the assignee of the task."),
@@ -339,7 +320,6 @@ class task(osv.osv):
'active': lambda *a: True,
'date_start': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
'project_id': _default_project,
'occupation_rate':lambda *a: '1',
'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'project.task', context=c)
}
_order = "sequence, priority, date_start, id"
@@ -479,83 +459,6 @@ class task(osv.osv):
self.write(cr, uid, typ.id, {'type': index and types[index-1] or False})
return True
def constraint_date_start(self,cr,uid,task,date_end,context=None):
# Recursive call for all previous tasks if change in date_start < older time
resource_cal_pool = self.pool.get('resource.calendar')
resource_pool = self.pool.get('resource.resource')
calendar_id = task.project_id.resource_calendar_id.id
hours = task.remaining_hours / task.occupation_rate
resource_id = resource_pool.search(cr,uid,[('user_id','=',task.user_id.id)])
if resource_id:
resource_obj = resource_pool.browse(cr,uid,resource_id[0])
calendar_id = resource_obj.calendar_id.id
hours = task.planned_hours/(float(task.occupation_rate) * resource_obj.time_efficiency)
work_time = resource_cal_pool.interval_min_get(cr, uid, calendar_id or False, date_end, hours or 0.0,resource_id or False)
dt_start = work_time[0][0].strftime('%Y-%m-%d %H:%M:%S')
self.write(cr,uid,[task.id],{'date_start':dt_start,'date_end':date_end.strftime('%Y-%m-%d %H:%M:%S')})
def constraint_date_end(self,cr,uid,task,date_start,context=None):
# Recursive call for all next tasks if change in date_end > older time
resource_cal_pool = self.pool.get('resource.calendar')
resource_pool = self.pool.get('resource.resource')
calendar_id = task.project_id.resource_calendar_id.id
hours = task.remaining_hours / task.occupation_rate
resource_id = resource_pool.search(cr,uid,[('user_id','=',task.user_id.id)])
if resource_id:
resource_obj = resource_pool.browse(cr,uid,resource_id[0])
calendar_id = resource_obj.calendar_id.id
hours = task.planned_hours/(float(task.occupation_rate) * resource_obj.time_efficiency)
work_time = resource_cal_pool.interval_get(cr, uid, calendar_id or False, date_start, hours or 0.0,resource_id or False)
dt_end = work_time[-1][1].strftime('%Y-%m-%d %H:%M:%S')
self.write(cr,uid,[task.id],{'date_start':date_start.strftime('%Y-%m-%d %H:%M:%S'),'date_end':dt_end})
def write_old(self, cr, uid, ids, vals,context=None):
if not context:
context = {}
if context.get('scheduler',False):
return super(task, self).write(cr, uid, ids, vals, context=context)
# if the task is performed by a resource then its calendar and efficiency also taken
# otherwise the project's working calendar considered
tasks = self.browse(cr,uid,ids[0])
resource_cal_pool = self.pool.get('resource.calendar')
resource_pool = self.pool.get('resource.resource')
calendar_id = tasks.project_id.resource_calendar_id.id
hrs = tasks.remaining_hours / tasks.occupation_rate
resource_id = resource_pool.search(cr,uid,[('user_id','=',tasks.user_id.id)])
if resource_id:
resource_obj = resource_pool.browse(cr,uid,resource_id[0])
calendar_id = resource_obj.calendar_id.id
hrs = tasks.planned_hours/(float(tasks.occupation_rate) * resource_obj.time_efficiency)
# write method changes the date_start and date_end
# for previous and next tasks respectively based on valid condition
if vals.get('date_start'):
if vals['date_start'] < tasks.date_start:
dt_start = mx.DateTime.strptime(vals['date_start'],'%Y-%m-%d %H:%M:%S')
work_times = resource_cal_pool.interval_get(cr, uid, calendar_id or False, dt_start, hrs or 0.0,resource_id or False)
vals['date_end'] = work_times[-1][1].strftime('%Y-%m-%d %H:%M:%S')
super(task, self).write(cr, uid, ids, vals, context=context)
for prv_task in tasks.parent_ids:
self.constraint_date_start(cr,uid,prv_task,dt_start)
if vals.get('date_end'):
if vals['date_end'] > tasks.date_end:
dt_end = mx.DateTime.strptime(vals['date_end'],'%Y-%m-%d %H:%M:%S')
hrs = tasks.remaining_hours / tasks.occupation_rate
work_times = resource_cal_pool.interval_min_get(cr, uid, calendar_id or False, dt_end, hrs or 0.0,resource_id or False)
vals['date_start'] = work_times[0][0].strftime('%Y-%m-%d %H:%M:%S')
super(task, self).write(cr, uid, ids, vals, context=context)
for next_task in tasks.child_ids:
self.constraint_date_end(cr,uid,next_task,dt_end)
return super(task, self).write(cr, uid, ids, vals, context=context)
task()
class project_work(osv.osv):
+3 -5
View File
@@ -25,8 +25,7 @@
<page string="Administration">
<group col="2" colspan="2">
<separator colspan="2" string="Scheduling"/>
<field name="resource_calendar_id"/>
<field name="priority"/>
<field name="priority"/>
<field name="active" select="2"/>
</group>
<group col="2" colspan="2">
@@ -247,7 +246,7 @@
name="planned_hours"
widget="float_time"
attrs="{'readonly':[('state','!=','draft')]}"
on_change="onchange_planned(project_id,user_id,planned_hours,effective_hours,date_start,occupation_rate)"/>
on_change="onchange_planned(planned_hours, effective_hours)"/>
<field name="remaining_hours" select="2" widget="float_time" attrs="{'readonly':[('state','!=','draft')]}" colspan="2"/>
<button name="%(action_config_compute_remaining)d" string="Review" type="action" colspan="1" target="new" states="open,pending" icon="gtk-edit"/>
</group>
@@ -304,7 +303,6 @@
<separator string="Dates" colspan="2"/>
<field name="date_start"/>
<field name="date_end"/>
<field name="occupation_rate"/>
</group>
<separator string="Miscelleanous" colspan="4"/>
<field name="partner_id" select="2"/>
@@ -331,7 +329,7 @@
<tree colors="grey:state in ('cancelled','done');blue:remaining_hours&lt;0;red:bool(date_deadline) and (date_deadline&lt;current_date) and (state in ('draft','open'));black:state not in ('cancelled','done')" string="Tasks">
<field name="sequence" invisible="1"/>
<field name="name"/>
<field name="planned_hours" widget="float_time" on_change="onchange_planned(planned_hours)" invisible="not context.get('set_visible',False)"/>
<field name="planned_hours" widget="float_time" on_change="onchange_planned(planned_hours, effective_hours)" invisible="not context.get('set_visible',False)"/>
<field name="project_id" icon="gtk-indent" domain="['|',('user_id','=',uid),('members','=',uid)]"/>
<field name="user_id"/>
<field name="delegated_user_id" invisible="context.get('show_delegated', True)"/>
-10
View File
@@ -3,16 +3,6 @@
<data>
<wizard id="wizard_close_task" menu="False" model="project.task" name="project.task.close" string="Close Task"/>
<wizard id="wizard_delegate_task" menu="False" model="project.task" name="project.task.delegate" string="Delegate Task"/>
<wizard id="wizard_compute_task" model="project.task" menu="False" name="wizard.compute.tasks" string="Compute Task Scheduling"/>
<menuitem id="base.menu_pm_planning" name="Planning" parent="base.menu_main" sequence="3"/>
<menuitem
action="wizard_compute_task"
id="menu_wizard_compute_task"
parent="base.menu_pm_planning"
type="wizard"
sequence="1"/>
<wizard
id="wizard_duplicate_template"
menu="False"
-2
View File
@@ -21,9 +21,7 @@
import close_task
import task_delegate
import compute_tasks_date
import duplicate_template_wizard
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+1 -1
View File
@@ -26,7 +26,7 @@
"author" : "Tiny",
"website" : "http://www.openerp.com",
"category" : "Generic Modules/Projects & Services",
"depends" : ["project"],
"depends" : ["project","resource"],
"description": """Long Term Project management module that track planning, scheduling, resources allocation.
""",
"init_xml" : [],
+155 -36
View File
@@ -78,6 +78,19 @@ class project_phase(osv.osv):
return False
return True
def _check_constraint_start(self, cr, uid, ids):
phase = self.read(cr, uid, ids[0],['date_start','constraint_date_start'])
if phase['date_start'] and phase['constraint_date_start']:
if phase['date_start'] < phase['constraint_date_start']:
return False
return True
def _check_constraint_end(self, cr, uid, ids):
phase = self.read(cr, uid, ids[0],['date_end','constraint_date_end'])
if phase['date_end'] and phase['constraint_date_end']:
if phase['date_end'] > phase['constraint_date_end']:
return False
return True
_columns = {
'name': fields.char("Phase Name", size=64, required=True),
@@ -110,52 +123,55 @@ class project_phase(osv.osv):
_order = "name"
_constraints = [
(_check_recursion,'Error ! Loops In Phases Not Allowed',['next_phase_ids','previous_phase_ids']),
(_check_dates, 'Error! Phase start-date must be lower then Phase end-date.', ['date_start', 'date_end'])
(_check_dates, 'Error! Phase start-date must be lower then Phase end-date.', ['date_start', 'date_end']),
(_check_constraint_start, 'Error! Phase must start-after Constraint Start Date.', ['date_start', 'constraint_date_start']),
(_check_constraint_end, 'Error! Phase must end-before Constraint End Date.', ['date_end', 'constraint_date_end']),
]
def onchange_project(self,cr,uid,ids,project):
def onchange_project(self, cr, uid, ids, project):
result = {}
if project:
project_pool = self.pool.get('project.project')
project_id = project_pool.browse(cr,uid,project)
project_id = project_pool.browse(cr, uid, project)
if project_id.date_start:
result['date_start'] = mx.DateTime.strptime(project_id.date_start,"%Y-%m-%d").strftime('%Y-%m-%d %H:%M:%S')
return {'value':result}
return {'value':{'date_start':[]}}
result['date_start'] = mx.DateTime.strptime(project_id.date_start, "%Y-%m-%d").strftime('%Y-%m-%d %H:%M:%S')
return {'value' : result}
return {'value' : {'date_start' : []}}
def constraint_date_start(self,cr,uid,phase,date_end,context=None):
def constraint_date_start(self, cr, uid, phase, date_end, context=None):
# Recursive call for all previous phases if change in date_start < older time
resource_cal_pool = self.pool.get('resource.calendar')
uom_pool = self.pool.get('product.uom')
resource_pool = self.pool.get('resource.resource')
calendar_id = phase.project_id.resource_calendar_id.id
if phase.responsible_id.id:
resource_id = resource_pool.search(cr,uid,[('user_id','=',phase.responsible_id.id)])
calendar_id = resource_pool.browse(cr,uid,resource_id[0]).calendar_id.id
default_uom_id = uom_pool.search(cr,uid,[('name','=','Hour')])[0]
avg_hours = uom_pool._compute_qty(cr, uid, phase.product_uom.id, phase.duration,default_uom_id)
work_time = resource_cal_pool.interval_min_get(cr, uid, calendar_id or False, date_end, avg_hours or 0.0,resource_id or False)
resource_id = resource_pool.search(cr, uid, [('user_id','=',phase.responsible_id.id)])
if resource_id:
calendar_id = resource_pool.browse(cr, uid, resource_id[0]).calendar_id.id
default_uom_id = uom_pool.search(cr, uid, [('name','=','Hour')])[0]
avg_hours = uom_pool._compute_qty(cr, uid, phase.product_uom.id, phase.duration, default_uom_id)
work_time = resource_cal_pool.interval_min_get(cr, uid, calendar_id or False, date_end, avg_hours or 0.0, resource_id or False)
dt_start = work_time[0][0].strftime('%Y-%m-%d %H:%M:%S')
self.write(cr,uid,[phase.id],{'date_start':dt_start,'date_end':date_end.strftime('%Y-%m-%d %H:%M:%S')})
self.write(cr, uid, [phase.id], {'date_start' : dt_start, 'date_end' : date_end.strftime('%Y-%m-%d %H:%M:%S')})
def constraint_date_end(self,cr,uid,phase,date_start,context=None):
def constraint_date_end(self, cr, uid, phase, date_start, context=None):
# Recursive call for all next phases if change in date_end > older time
resource_cal_pool = self.pool.get('resource.calendar')
uom_pool = self.pool.get('product.uom')
resource_pool = self.pool.get('resource.resource')
calendar_id = phase.project_id.resource_calendar_id.id
if phase.responsible_id.id:
resource_id = resource_pool.search(cr,uid,[('user_id','=',phase.responsible_id.id)])
calendar_id = resource_pool.browse(cr,uid,resource_id[0]).calendar_id.id
default_uom_id = uom_pool.search(cr,uid,[('name','=','Hour')])[0]
avg_hours = uom_pool._compute_qty(cr, uid, phase.product_uom.id, phase.duration,default_uom_id)
work_time = resource_cal_pool.interval_get(cr, uid, calendar_id or False, date_start, avg_hours or 0.0,resource_id or False)
resource_id = resource_pool.search(cr, uid, [('user_id','=',phase.responsible_id.id)])
if resource_id:
calendar_id = resource_pool.browse(cr, uid, resource_id[0]).calendar_id.id
default_uom_id = uom_pool.search(cr, uid, [('name','=','Hour')])[0]
avg_hours = uom_pool._compute_qty(cr, uid, phase.product_uom.id, phase.duration, default_uom_id)
work_time = resource_cal_pool.interval_get(cr, uid, calendar_id or False, date_start, avg_hours or 0.0, resource_id or False)
dt_end = work_time[-1][1].strftime('%Y-%m-%d %H:%M:%S')
self.write(cr,uid,[phase.id],{'date_start':date_start.strftime('%Y-%m-%d %H:%M:%S'),'date_end':dt_end})
self.write(cr, uid, [phase.id], {'date_start' : date_start.strftime('%Y-%m-%d %H:%M:%S'), 'date_end' : dt_end})
def write(self, cr, uid, ids, vals,context=None):
def write(self, cr, uid, ids, vals, context=None):
if not context:
context = {}
@@ -165,19 +181,17 @@ class project_phase(osv.osv):
# if the phase is performed by a resource then its calendar and efficiency also taken
# otherwise the project's working calendar considered
phase = self.browse(cr,uid,ids[0])
phase = self.browse(cr, uid, ids[0])
resource_cal_pool = self.pool.get('resource.calendar')
resource_pool = self.pool.get('resource.resource')
uom_pool = self.pool.get('product.uom')
resource_id = False
calendar_id = phase.project_id.resource_calendar_id.id
if phase.responsible_id.id:
resource_id = resource_pool.search(cr,uid,[('user_id','=',phase.responsible_id.id)])
if resource_id:
calendar_id = resource_pool.browse(cr,uid,resource_id[0]).calendar_id.id
default_uom_id = uom_pool.search(cr,uid,[('name','=','Hour')])[0]
avg_hours = uom_pool._compute_qty(cr, uid, phase.product_uom.id, phase.duration,default_uom_id)
resource_id = resource_pool.search(cr, uid, [('user_id','=',phase.responsible_id.id)])
if resource_id:
calendar_id = resource_pool.browse(cr, uid, resource_id[0]).calendar_id.id
default_uom_id = uom_pool.search(cr, uid, [('name','=','Hour')])[0]
avg_hours = uom_pool._compute_qty(cr, uid, phase.product_uom.id, phase.duration, default_uom_id)
# write method changes the date_start and date_end
#for previous and next phases respectively based on valid condition
@@ -185,22 +199,22 @@ class project_phase(osv.osv):
if vals.get('date_start'):
if vals['date_start'] < phase.date_start:
dt_start = mx.DateTime.strptime(vals['date_start'],'%Y-%m-%d %H:%M:%S')
work_times = resource_cal_pool.interval_get(cr, uid, calendar_id or False, dt_start, avg_hours or 0.0,resource_id or False)
work_times = resource_cal_pool.interval_get(cr, uid, calendar_id or False, dt_start, avg_hours or 0.0, resource_id or False)
vals['date_end'] = work_times[-1][1].strftime('%Y-%m-%d %H:%M:%S')
super(project_phase, self).write(cr, uid, ids, vals, context=context)
for prv_phase in phase.previous_phase_ids:
self.constraint_date_start(cr,uid,prv_phase,dt_start)
self.constraint_date_start(cr, uid, prv_phase, dt_start)
if vals.get('date_end'):
if vals['date_end'] > phase.date_end:
dt_end = mx.DateTime.strptime(vals['date_end'],'%Y-%m-%d %H:%M:%S')
work_times = resource_cal_pool.interval_min_get(cr, uid, calendar_id or False, dt_end, avg_hours or 0.0,resource_id or False)
work_times = resource_cal_pool.interval_min_get(cr, uid, calendar_id or False, dt_end, avg_hours or 0.0, resource_id or False)
vals['date_start'] = work_times[0][0].strftime('%Y-%m-%d %H:%M:%S')
super(project_phase, self).write(cr, uid, ids, vals, context=context)
for next_phase in phase.next_phase_ids:
self.constraint_date_end(cr,uid,next_phase,dt_end)
self.constraint_date_end(cr, uid, next_phase, dt_end)
return super(project_phase, self).write(cr, uid, ids, vals, context=context)
@@ -246,6 +260,7 @@ class project(osv.osv):
_columns = {
'phase_ids': fields.one2many('project.phase', 'project_id', "Project Phases")
}
project()
@@ -254,8 +269,112 @@ class task(osv.osv):
_inherit = "project.task"
_columns = {
'phase_id': fields.many2one('project.phase', 'Project Phase')
'phase_id': fields.many2one('project.phase', 'Project Phase'),
'occupation_rate': fields.float('Occupation Rate', help='The occupation rate fields indicates how much of his time a user is working on a task. A 100% occupation rate means the user works full time on the tasks. The ending date of a task is computed like this: Starting Date + Duration / Occupation Rate.'),
'planned_hours': fields.float('Planned Hours', required=True, help='Estimated time to do the task, usually set by the project manager when the task is in draft state.'),
}
_defaults = {
'occupation_rate':lambda *a: '1'
}
def onchange_planned(self, cr, uid, ids, project, user_id=False, planned=0.0, effective=0.0, date_start=None, occupation_rate=0.0):
result = {}
if date_start:
resource_pool = self.pool.get('resource.resource')
project_pool = self.pool.get('project.project')
resource_calendar = self.pool.get('resource.calendar')
dt_start = mx.DateTime.strptime(date_start, '%Y-%m-%d %H:%M:%S')
resource_id = resource_pool.search(cr, uid, [('user_id','=',user_id)])
if resource_id:
resource_obj = resource_pool.browse(cr, uid, resource_id)[0]
hrs = planned / (float(occupation_rate) * resource_obj.time_efficiency)
calendar_id = resource_obj.calendar_id.id
else:
hrs = float(planned / occupation_rate)
calendar_id = project_pool.browse(cr, uid, project).resource_calendar_id .id
work_times = resource_calendar.interval_get(cr, uid, calendar_id or False, dt_start, hrs or 0.0, resource_id or False)
result['date_end'] = work_times[-1][1].strftime('%Y-%m-%d %H:%M:%S')
result['remaining_hours'] = planned - effective
return {'value' : result}
def constraint_date_start(self, cr, uid, task, date_end, context=None):
# Recursive call for all previous tasks if change in date_start < older time
resource_cal_pool = self.pool.get('resource.calendar')
resource_pool = self.pool.get('resource.resource')
calendar_id = task.project_id.resource_calendar_id.id
hours = task.remaining_hours / task.occupation_rate
resource_id = resource_pool.search(cr, uid, [('user_id','=',task.user_id.id)])
if resource_id:
resource_obj = resource_pool.browse(cr, uid, resource_id[0])
calendar_id = resource_obj.calendar_id.id
hours = task.planned_hours / (float(task.occupation_rate) * resource_obj.time_efficiency)
work_time = resource_cal_pool.interval_min_get(cr, uid, calendar_id or False, date_end, hours or 0.0, resource_id or False)
dt_start = work_time[0][0].strftime('%Y-%m-%d %H:%M:%S')
self.write(cr, uid, [task.id], {'date_start' : dt_start,'date_end' : date_end.strftime('%Y-%m-%d %H:%M:%S')})
def constraint_date_end(self, cr, uid, task, date_start, context=None):
# Recursive call for all next tasks if change in date_end > older time
resource_cal_pool = self.pool.get('resource.calendar')
resource_pool = self.pool.get('resource.resource')
calendar_id = task.project_id.resource_calendar_id.id
hours = task.remaining_hours / task.occupation_rate
resource_id = resource_pool.search(cr,uid,[('user_id','=',task.user_id.id)])
if resource_id:
resource_obj = resource_pool.browse(cr, uid, resource_id[0])
calendar_id = resource_obj.calendar_id.id
hours = task.planned_hours / (float(task.occupation_rate) * resource_obj.time_efficiency)
work_time = resource_cal_pool.interval_get(cr, uid, calendar_id or False, date_start, hours or 0.0, resource_id or False)
dt_end = work_time[-1][1].strftime('%Y-%m-%d %H:%M:%S')
self.write(cr, uid, [task.id], {'date_start' : date_start.strftime('%Y-%m-%d %H:%M:%S'),'date_end' : dt_end})
def write(self, cr, uid, ids, vals, context=None):
if not context:
context = {}
if context.get('scheduler',False):
return super(task, self).write(cr, uid, ids, vals, context=context)
# if the task is performed by a resource then its calendar and efficiency also taken
# otherwise the project's working calendar considered
tasks = self.browse( cr, uid, ids[0])
resource_cal_pool = self.pool.get('resource.calendar')
resource_pool = self.pool.get('resource.resource')
calendar_id = tasks.project_id.resource_calendar_id.id
hrs = tasks.remaining_hours / tasks.occupation_rate
resource_id = resource_pool.search(cr, uid, [('user_id','=',tasks.user_id.id)])
if resource_id:
resource_obj = resource_pool.browse(cr, uid, resource_id[0])
calendar_id = resource_obj.calendar_id.id
hrs = tasks.planned_hours / (float(tasks.occupation_rate) * resource_obj.time_efficiency)
# write method changes the date_start and date_end
# for previous and next tasks respectively based on valid condition
if vals.get('date_start'):
if vals['date_start'] < tasks.date_start:
dt_start = mx.DateTime.strptime(vals['date_start'],'%Y-%m-%d %H:%M:%S')
work_times = resource_cal_pool.interval_get(cr, uid, calendar_id or False, dt_start, hrs or 0.0, resource_id or False)
vals['date_end'] = work_times[-1][1].strftime('%Y-%m-%d %H:%M:%S')
super(task, self).write(cr, uid, ids, vals, context=context)
for prv_task in tasks.parent_ids:
self.constraint_date_start(cr, uid, prv_task, dt_start)
if vals.get('date_end'):
if vals['date_end'] > tasks.date_end:
dt_end = mx.DateTime.strptime(vals['date_end'],'%Y-%m-%d %H:%M:%S')
hrs = tasks.remaining_hours / tasks.occupation_rate
work_times = resource_cal_pool.interval_min_get(cr, uid, calendar_id or False, dt_end, hrs or 0.0, resource_id or False)
vals['date_start'] = work_times[0][0].strftime('%Y-%m-%d %H:%M:%S')
super(task, self).write(cr, uid, ids, vals, context=context)
for next_task in tasks.child_ids:
self.constraint_date_end(cr, uid, next_task, dt_end)
return super(task, self).write(cr, uid, ids, vals, context=context)
task()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+19 -29
View File
@@ -34,7 +34,7 @@
<field name="password">manager1</field>
<field eval="[(6,0,[])]" name="company_ids"/>
</record>
<record id="res_users_manager1" model="res.users">
<field model="ir.actions.actions" name="menu_id" search="[('name', '=', u'Menu')]"/>
<field name="context_lang">en_US</field>
@@ -49,7 +49,7 @@
<field name="password">manager2</field>
<field eval="[(6,0,[])]" name="company_ids"/>
</record>
<record id="res_users_user0" model="res.users">
<field model="ir.actions.actions" name="menu_id" search="[('name', '=', u'Menu')]"/>
<field name="context_lang">en_US</field>
@@ -64,7 +64,7 @@
<field name="password">USER1</field>
<field eval="[(6,0,[])]" name="company_ids"/>
</record>
<record id="res_users_user1" model="res.users">
<field model="ir.actions.actions" name="menu_id" search="[('name', '=', u'Menu')]"/>
<field name="context_lang">en_US</field>
@@ -79,7 +79,7 @@
<field name="password">user2</field>
<field eval="[(6,0,[])]" name="company_ids"/>
</record>
<record id="res_users_userfinance0" model="res.users">
<field model="ir.actions.actions" name="menu_id" search="[('name', '=', u'Menu')]"/>
<field name="context_lang">en_US</field>
@@ -94,7 +94,7 @@
<field name="password">user_finance</field>
<field eval="[(6,0,[])]" name="company_ids"/>
</record>
<record id="res_users_userdesign0" model="res.users">
<field model="ir.actions.actions" name="menu_id" search="[('name', '=', u'Menu')]"/>
<field name="context_lang">en_US</field>
@@ -109,7 +109,7 @@
<field name="password">user_design1</field>
<field eval="[(6,0,[])]" name="company_ids"/>
</record>
<record id="res_users_userdesign1" model="res.users">
<field model="ir.actions.actions" name="menu_id" search="[('name', '=', u'Menu')]"/>
<field name="context_lang">en_US</field>
@@ -201,23 +201,13 @@
</record>
<!-- Resources -->
<record id="resource_resource_fabienpinckaers0" model="resource.resource">
<field eval="1.0" name="time_efficiency"/>
<field name="user_id" ref="base.user_root"/>
<field name="name">Fabien Pinckaers</field>
<field name="company_id" ref="base.main_company"/>
<field eval="1" name="active"/>
<field name="calendar_id" ref="hr.timesheet_group1"/>
<field name="resource_type">user</field>
</record>
<record id="resource_resource_analyst0" model="resource.resource">
<field eval="1.0" name="time_efficiency"/>
<field name="user_id" ref="res_users_useranalyst0"/>
<field name="name">Analyst</field>
<field name="company_id" ref="base.main_company"/>
<field eval="1" name="active"/>
<field name="calendar_id" ref="hr.timesheet_group1"/>
<field name="calendar_id" ref="resource.timesheet_group1"/>
<field name="resource_type">user</field>
</record>
@@ -227,7 +217,7 @@
<field name="name">Programmer</field>
<field name="company_id" ref="base.main_company"/>
<field eval="1" name="active"/>
<field name="calendar_id" ref="hr.timesheet_group1"/>
<field name="calendar_id" ref="resource.timesheet_group1"/>
<field name="resource_type">user</field>
</record>
@@ -237,7 +227,7 @@
<field name="name">Tester</field>
<field name="company_id" ref="base.main_company"/>
<field eval="1" name="active"/>
<field name="calendar_id" ref="hr.timesheet_group1"/>
<field name="calendar_id" ref="resource.timesheet_group1"/>
<field name="resource_type">user</field>
</record>
@@ -247,7 +237,7 @@
<field name="name">Web Designer</field>
<field name="company_id" ref="base.main_company"/>
<field eval="1" name="active"/>
<field name="calendar_id" ref="hr.timesheet_group1"/>
<field name="calendar_id" ref="resource.timesheet_group1"/>
<field name="resource_type">user</field>
</record>
@@ -271,7 +261,7 @@
<field eval="[(6,0,[])]" name="type_ids"/>
<field name="name">OpenERP Website Development</field>
</record>
<!-- Project Phases -->
<record id="project_phase_informationgatheringandunderstanding0" model="project.phase">
<field eval="[(6,0,[])]" name="previous_phase_ids"/>
@@ -284,7 +274,7 @@
<field name="responsible_id" ref="res_users_demouser1"/>
<field eval="10.0" name="duration"/>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field name="constraint_date_start">2010-02-26 15:37:00</field>
<field name="constraint_date_start">2010-02-24 15:37:00</field>
<field name="date_end">2010-03-10 15:33:00</field>
</record>
@@ -293,7 +283,7 @@
<field name="name">Planning</field>
<field name="product_uom" ref="product.uom_day"/>
<field eval="10" name="sequence"/>
<field name="constraint_date_end">2010-02-18 15:49:00</field>
<field name="constraint_date_end">2010-03-25 15:49:00</field>
<field name="date_start">2010-02-18 15:48:00</field>
<field name="state">draft</field>
<field name="responsible_id" ref="res_users_manager0"/>
@@ -308,13 +298,13 @@
<field name="name">Web Design </field>
<field name="product_uom" ref="product.uom_day"/>
<field eval="10" name="sequence"/>
<field name="constraint_date_end">2010-04-10 16:08:00</field>
<field name="constraint_date_end">2010-04-15 16:08:00</field>
<field name="date_start">2010-04-01 16:02:00</field>
<field name="state">draft</field>
<field name="responsible_id" ref="res_users_userdesign0"/>
<field eval="10.0" name="duration"/>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field name="constraint_date_start">2010-04-01 16:08:00</field>
<field name="constraint_date_start">2010-03-09 16:00:00</field>
<field name="date_end">2010-04-10 16:02:00</field>
</record>
@@ -329,7 +319,7 @@
<field name="responsible_id" ref="res_users_manager0"/>
<field eval="15.0" name="duration"/>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field name="constraint_date_start">2010-04-14 16:11:00</field>
<field name="constraint_date_start">2010-03-10 16:11:00</field>
<field name="date_end">2010-04-26 16:10:00</field>
</record>
@@ -338,13 +328,13 @@
<field name="name">Website Deployment</field>
<field name="product_uom" ref="product.uom_day"/>
<field eval="10" name="sequence"/>
<field name="constraint_date_end">2010-04-28 16:35:00</field>
<field name="constraint_date_end">2010-04-30 16:35:00</field>
<field name="date_start">2010-04-26 16:35:00</field>
<field name="state">draft</field>
<field name="responsible_id" ref="res_users_manager0"/>
<field eval="2.0" name="duration"/>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field name="constraint_date_start">2010-04-27 16:35:00</field>
<field name="constraint_date_start">2010-03-10 16:35:00</field>
<field name="date_end">2010-04-27 16:34:00</field>
</record>
@@ -402,7 +392,7 @@
<field name="phase_id" ref="project_phase_developmentintegrationandtesting0"/>
<field eval="50.0" name="useability"/>
</record>
<!-- Tasks -->
<record id="project_task_preparerequirementsdocument0" model="project.task">
<field eval="10" name="sequence"/>
+39 -1
View File
@@ -96,7 +96,7 @@
<field name="arch" type="xml">
<tree string="Project Phases">
<field name="name"/>
<field name="project_id"/>
<field name="project_id" on_change="onchange_project(project_id)"/>
<field name="date_start"/>
<field name="date_end"/>
<field name="duration"/>
@@ -112,6 +112,44 @@
<field name="view_type">form</field>
</record>
<record id="view_phase_project_form1" model="ir.ui.view">
<field name="name">phase.project.form1</field>
<field name="model">project.project</field>
<field name="type">form</field>
<field name="inherit_id" ref="project.edit_project"/>
<field name="arch" type="xml">
<field name="priority" position="before">
<field name="resource_calendar_id"/>
</field>
</field>
</record>
<record id="view_project_phase_task_form1" model="ir.ui.view">
<field name="name">project.phase.task.form1</field>
<field name="model">project.task</field>
<field name="type">form</field>
<field name="inherit_id" ref="project.view_task_form2"/>
<field name="arch" type="xml">
<field name="planned_hours" position="replace">
<field name="planned_hours" widget="float_time" attrs="{'readonly':[('state','!=','draft')]}" on_change="onchange_planned(project_id, user_id, planned_hours, effective_hours, date_start, occupation_rate)"/>
</field>
</field>
</record>
<record id="view_project_phase_task_form2" model="ir.ui.view">
<field name="name">project.phase.task.form2</field>
<field name="model">project.task</field>
<field name="type">form</field>
<field name="inherit_id" ref="project.view_task_form2"/>
<field name="arch" type="xml">
<field name="date_end" position = "after">
<field name="occupation_rate"/>
</field>
</field>
</record>
<act_window
id="project_phase_task_list"
name="Related Tasks"
+9 -1
View File
@@ -3,12 +3,20 @@
<data>
<wizard id="wizard_compute_phase" menu="False" model="project.phase" name="wizard.compute.phases" string="Compute Phase Scheduling"/>
<wizard id="wizard_schedule_task" menu="False" model="project.phase" name="phase.schedule.tasks" string="Schedule Tasks"/>
<menuitem id="base.menu_pm_planning" name="Planning" parent="base.menu_main" sequence="3"/>
<wizard id="wizard_compute_task" model="project.task" menu="False" name="wizard.compute.tasks" string="Compute Task Scheduling"/>
<menuitem id="base.menu_pm_planning" name="Planning" parent="base.menu_main" sequence="3"/>
<menuitem
action="wizard_compute_phase"
id="menu_wizard_compute_phase"
parent="base.menu_pm_planning"
type="wizard"
sequence="1"/>
<menuitem
action="wizard_compute_task"
id="menu_wizard_compute_task"
parent="base.menu_pm_planning"
type="wizard"
sequence="1"/>
</data>
</openerp>
@@ -20,7 +20,9 @@
##############################################################################
import compute_phases_date
import compute_tasks_date
import schedule_tasks
import project_resource
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -25,7 +25,7 @@ from tools.translate import _
import datetime
from resource.faces import *
from new import classobj
import project.project_resource as proj
import project_resource as proj
compute_form = """<?xml version="1.0" ?>
<form string="Compute Scheduling of Phases">
@@ -44,7 +44,7 @@ success_msg = """<?xml version="1.0" ?>
<label string="Phase Scheduling completed successfully."/>
</form>"""
def phase_schedule(cr,uid,phase,start_date,calendar_id=False):
def phase_schedule(cr, uid, phase, start_date, calendar_id=False):
pool = pooler.get_pool(cr.dbname)
phase_pool = pool.get('project.phase')
resource_pool = pool.get('resource.resource')
@@ -53,13 +53,13 @@ def phase_schedule(cr,uid,phase,start_date,calendar_id=False):
resource_cal = False
phase_resource = False
if phase:
resource_id = resource_pool.search(cr,uid,[('user_id','=',phase.responsible_id.id)])
resource_id = resource_pool.search(cr, uid, [('user_id','=',phase.responsible_id.id)])
if resource_id:
resource_obj = resource_pool.browse(cr,uid,resource_id)[0]
leaves = proj.leaves_resource(cr,uid,calendar_id or False ,resource_id,resource_obj.calendar_id.id)
phase_resource = classobj(str(resource_obj.name),(Resource,),{'__doc__':resource_obj.name,'__name__':resource_obj.name,'vacation':tuple(leaves),'efficiency':resource_obj.time_efficiency})
default_uom_id = uom_pool.search(cr,uid,[('name','=','Hour')])[0]
avg_hours = uom_pool._compute_qty(cr, uid, phase.product_uom.id, phase.duration,default_uom_id)
resource_obj = resource_pool.browse(cr, uid, resource_id)[0]
leaves = proj.leaves_resource(cr, uid, calendar_id or False , resource_id, resource_obj.calendar_id.id)
phase_resource = classobj(str(resource_obj.name), (Resource,), {'__doc__' : resource_obj.name, '__name__' : resource_obj.name, 'vacation' : tuple(leaves), 'efficiency' : resource_obj.time_efficiency})
default_uom_id = uom_pool.search(cr, uid, [('name','=','Hour')])[0]
avg_hours = uom_pool._compute_qty(cr, uid, phase.product_uom.id, phase.duration, default_uom_id)
duration = str(avg_hours) + 'H'
# Creating a new project for each phase
@@ -69,8 +69,8 @@ def phase_schedule(cr,uid,phase,start_date,calendar_id=False):
resource = phase_resource
# If project has working calendar else the default one would be considered
if calendar_id:
working_days = proj.compute_working_calendar(cr,uid,calendar_id)
vacation = tuple(proj.leaves_resource(cr,uid,calendar_id))
working_days = proj.compute_working_calendar(cr, uid, calendar_id)
vacation = tuple(proj.leaves_resource(cr, uid, calendar_id))
def phase():
effort = duration
@@ -78,26 +78,25 @@ def phase_schedule(cr,uid,phase,start_date,calendar_id=False):
project = BalancedProject(Project)
s_date = project.phase.start.to_datetime()
e_date = project.phase.end.to_datetime()
# According to constraints on date start and date end on phase recalculation done
if phase.constraint_date_start and str(s_date) < phase.constraint_date_start:
start_date = datetime.datetime.strptime(phase.constraint_date_start,'%Y-%m-%d %H:%M:%S')
start_date = datetime.datetime.strptime(phase.constraint_date_start, '%Y-%m-%d %H:%M:%S')
else:
start_date = s_date
if phase.constraint_date_end and str(e_date) > phase.constraint_date_end:
end_date= datetime.datetime.strptime(phase.constraint_date_end,'%Y-%m-%d %H:%M:%S')
end_date= datetime.datetime.strptime(phase.constraint_date_end, '%Y-%m-%d %H:%M:%S')
date_start = phase.constraint_date_end[:-3]
else:
end_date = e_date
date_start = end_date
# Writing the dates back
phase_pool.write(cr,uid,[phase.id],{'date_start':start_date.strftime('%Y-%m-%d %H:%M:%S'),'date_end':end_date.strftime('%Y-%m-%d %H:%M:%S')},context={'scheduler':True})
phase_pool.write(cr, uid, [phase.id], {'date_start' :start_date.strftime('%Y-%m-%d %H:%M:%S'), 'date_end' :end_date.strftime('%Y-%m-%d %H:%M:%S')}, context={'scheduler' :True})
# Recursive calling the next phases till all the phases are scheduled
for phase in phase.next_phase_ids:
if phase.state in ['draft','open','pending']:
phase_schedule(cr,uid,phase,date_start,phase.project_id.resource_calendar_id.id or False)
phase_schedule(cr, uid, phase, date_start, phase.project_id.resource_calendar_id.id or False)
else:
continue
@@ -111,22 +110,22 @@ class wizard_compute_phases(wizard.interface):
# if project mentioned
if data['form']['project_id']:
project_id = project_pool.browse(cr,uid,data['form']['project_id'])
phase_ids = phase_pool.search(cr,uid,[('project_id','=',project_id.id),('state','in',['draft','open','pending']),('previous_phase_ids','=',False)])
project_id = project_pool.browse(cr, uid, data['form']['project_id'])
phase_ids = phase_pool.search(cr, uid, [('project_id','=',project_id.id), ('state','in',['draft','open','pending']), ('previous_phase_ids','=',False)])
# else all the draft,open,pending states phases taken
else:
phase_ids = phase_pool.search(cr,uid,[('state','in',['draft','open','pending']),('previous_phase_ids','=',False)])
phase_ids = phase_pool.search(cr, uid,[('state','in',['draft','open','pending']), ('previous_phase_ids','=',False)])
phase_ids.sort()
phase_objs = phase_pool.browse(cr,uid,phase_ids)
phase_objs = phase_pool.browse(cr, uid, phase_ids)
for phase in phase_objs:
start_date = phase.project_id.date_start
if not phase.project_id.date_start:
start_date = datetime.datetime.now().strftime("%Y-%m-%d")
start_dt = datetime.datetime.strftime((datetime.datetime.strptime(start_date,"%Y-%m-%d")),"%Y-%m-%d %H:%M")
start_dt = datetime.datetime.strftime((datetime.datetime.strptime(start_date, "%Y-%m-%d")), "%Y-%m-%d %H:%M")
calendar_id = phase.project_id.resource_calendar_id.id
phase_schedule(cr,uid,phase,start_dt,calendar_id or False)
phase_schedule(cr, uid, phase, start_dt, calendar_id or False)
return {}
states = {
@@ -0,0 +1,150 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import wizard
import pooler
from tools.translate import _
import datetime
from resource.faces import *
from new import classobj
import operator
import project_resource as proj
compute_form = """<?xml version="1.0" ?>
<form string="Compute Scheduling of Tasks">
<field name="project_id" colspan="4"/>
</form>"""
success_msg = """<?xml version="1.0" ?>
<form string="Compute Scheduling of Tasks">
<label string="Task Scheduling completed successfully."/>
</form>"""
compute_fields = {
'project_id': {'string':'Project', 'type':'many2one', 'relation': 'project.project', 'required':'True'},
}
class wizard_compute_tasks(wizard.interface):
def _compute_date(self, cr, uid, data, context):
pool = pooler.get_pool(cr.dbname)
project_pool = pool.get('project.project')
task_pool = pool.get('project.task')
resource_pool = pool.get('resource.resource')
user_pool = pool.get('res.users')
project_id = data['form']['project_id']
project = project_pool.browse(cr, uid, project_id)
task_ids = task_pool.search(cr, uid, [('project_id','=',project_id), ('state','in',['draft','open','pending'])])
if task_ids:
wktime_cal = []
task_ids.sort()
task_obj = task_pool.browse(cr, uid, task_ids)
calendar_id = project.resource_calendar_id.id
start_date = project.date_start
if not project.date_start:
start_date = datetime.datetime.now().strftime("%Y-%m-%d")
date_start = datetime.datetime.strftime(datetime.datetime.strptime(start_date, "%Y-%m-%d"), "%Y-%m-%d %H:%M")
# To create resources which are the Project Members
resource_objs = []
for resource in project.members:
leaves = []
resource_id = resource_pool.search(cr, uid, [('user_id','=',resource.id)])
if resource_id:
resource_obj = resource_pool.browse(cr, uid, resource_id)[0]
leaves = proj.leaves_resource(cr, uid, calendar_id or False , resource_id, resource_obj.calendar_id.id)
resource_objs.append(classobj(str(resource.name), (Resource,), {'__doc__' : resource.name, '__name__' : resource.name, 'vacation' : tuple(leaves), 'efficiency' : resource_obj.time_efficiency}))
priority_dict = {'0' :1000, '1' :800, '2' :500, '3' :300,'4' :100}
# To create dynamic no of tasks with the resource specified
def tasks_resource(j, eff, priorty=500, obj=None):
def task():
"""
task is a dynamic method!
"""
effort = eff
if obj:
resource = obj
priority = priorty
task.__doc__ = "TaskNO%d" %j
task.__name__ = "task%d" %j
return task
# Creating the project with all the tasks and resources
def Project():
title = project.name
start = date_start
resource = reduce(operator.or_, resource_objs)
minimum_time_unit = 1
# If project has calendar
if calendar_id:
working_days = proj.compute_working_calendar(cr, uid, calendar_id)
vacation = tuple(proj.leaves_resource(cr, uid, calendar_id))
# Dynamic Creation of tasks
i = 0
for each_task in task_obj:
hours = str(each_task.planned_hours / each_task.occupation_rate)+ 'H'
if each_task.priority in priority_dict.keys():
priorty = priority_dict[each_task.priority]
if each_task.user_id:
for resource_object in resource_objs:
if resource_object.__name__ == each_task.user_id.name:
task = tasks_resource(i, hours, priorty, resource_object)
else:
task = tasks_resource(i, hours, priorty)
i += 1
# Writing back the dates
project = BalancedProject(Project)
loop_no = 0
for t in project:
s_date = t.start.to_datetime()
e_date = t.end.to_datetime()
if loop_no == 0:
project_pool.write(cr, uid, [project_id], {'date' : e_date})
else:
user_id = user_pool.search(cr, uid, [('name','=',t.booked_resource[0].__name__)])
task_pool.write(cr, uid, [task_obj[loop_no-1].id], {'date_start' :s_date.strftime('%Y-%m-%d %H:%M:%S'), 'date_deadline' :e_date.strftime('%Y-%m-%d %H:%M:%S'), 'user_id' :user_id[0]}, context={'scheduler' :True})
loop_no +=1
return {}
states = {
'init': {
'actions': [],
'result': {'type':'form', 'arch':compute_form, 'fields':compute_fields, 'state':[
('end', 'Cancel'),
('compute', 'Compute')
]},
},
'compute': {
'actions': [_compute_date],
'result': {'type':'form','arch':success_msg,'fields':{}, 'state':[('end', 'Ok')]},
}
}
wizard_compute_tasks('wizard.compute.tasks')
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -0,0 +1,81 @@
import pooler
import datetime
def timeformat_convert(cr, uid, time_string, context={}):
# Function to convert input time string:: 8.5 to output time string 8:30
split_list = str(time_string).split('.')
hour_part = split_list[0]
mins_part = split_list[1]
round_mins = int(round(float(mins_part) * 60,-2))
converted_string = hour_part + ':' + str(round_mins)[0:2]
return converted_string
def leaves_resource(cr, uid, calendar_id, resource_id=False, resource_calendar=False):
# To get the leaves for the resource_ids working on phase
pool = pooler.get_pool(cr.dbname)
resource_leaves_pool = pool.get('resource.calendar.leaves')
leaves = []
if resource_id:
resource_leave_ids = resource_leaves_pool.search(cr, uid, ['|', ('calendar_id','=',calendar_id), ('calendar_id','=',resource_calendar), ('resource_id','=',resource_id)])
else:
resource_leave_ids = resource_leaves_pool.search(cr, uid, [('calendar_id','=',calendar_id), ('resource_id','=',False)])
res_leaves = resource_leaves_pool.read(cr, uid, resource_leave_ids, ['date_from', 'date_to'])
for leave in range(len(res_leaves)):
dt_start = datetime.datetime.strptime(res_leaves[leave]['date_from'], '%Y-%m-%d %H:%M:%S')
dt_end = datetime.datetime.strptime(res_leaves[leave]['date_to'], '%Y-%m-%d %H:%M:%S')
no = dt_end - dt_start
[leaves.append((dt_start + datetime.timedelta(days=x)).strftime('%Y-%m-%d')) for x in range(int(no.days + 1))]
leaves.sort()
return leaves
def compute_working_calendar(cr, uid, calendar_id):
# To change the format of working calendar to bring it into 'faces' format
pool = pooler.get_pool(cr.dbname)
resource_week_pool = pool.get('resource.calendar.week')
time_range = "8:00-8:00"
non_working = ""
wk = {"0":"mon","1":"tue","2":"wed","3":"thu","4":"fri","5":"sat","6":"sun"}
wk_days = {}
wk_time = {}
wktime_list = []
wktime_cal = []
week_ids = resource_week_pool.search(cr, uid, [('calendar_id','=',calendar_id)])
week_obj = resource_week_pool.read(cr, uid, week_ids, ['dayofweek', 'hour_from', 'hour_to'])
# Converting time formats into appropriate format required
# and creating a list like [('mon', '8:00-12:00'), ('mon', '13:00-18:00')]
for week in week_obj:
res_str = ""
if wk.has_key(week['dayofweek']):
day = wk[week['dayofweek']]
wk_days[week['dayofweek']] = wk[week['dayofweek']]
hour_from_str = timeformat_convert(cr, uid, week['hour_from'])
hour_to_str = timeformat_convert(cr, uid, week['hour_to'])
res_str = hour_from_str + '-' + hour_to_str
wktime_list.append((day, res_str))
# Converting it to format like [('mon', '8:00-12:00', '13:00-18:00')]
for item in wktime_list:
if wk_time.has_key(item[0]):
wk_time[item[0]].append(item[1])
else:
wk_time[item[0]] = [item[0]]
wk_time[item[0]].append(item[1])
for k,v in wk_time.items():
wktime_cal.append(tuple(v))
# For non working days adding [('tue,wed,fri,sat,sun', '8:00-8:00')]
for k,v in wk_days.items():
if wk.has_key(k):
wk.pop(k)
for v in wk.itervalues():
non_working += v + ','
if non_working:
wktime_cal.append((non_working[:-1], time_range))
return wktime_cal
@@ -27,14 +27,14 @@ from resource.faces import *
from new import classobj
import operator
import time
import project.project_resource as proj
import project_resource as proj
success_msg = """<?xml version="1.0" ?>
<form string="Compute Scheduling of Tasks">
<label string="Task Scheduling completed successfully."/>
</form>"""
def resource_list(cr,uid,phase):
def resource_list(cr, uid, phase):
# To create resources which are the Project Members
resource_objs = []
@@ -43,9 +43,9 @@ def resource_list(cr,uid,phase):
leaves = []
resource_eff = res.time_efficiency
resource_cal = res.calendar_id.id
wktime_cal = proj.compute_working_calendar(cr,uid,resource_cal)
leaves = proj.leaves_resource(cr,uid,phase.project_id.resource_calendar_id.id or False ,res.id,resource_cal)
resource_objs.append(classobj(str(res.user_id.name),(Resource,),{'__doc__':res.user_id.name,'__name__':res.user_id.name,'vacation':tuple(leaves),'efficiency':resource_eff}))
wktime_cal = proj.compute_working_calendar(cr, uid, resource_cal)
leaves = proj.leaves_resource(cr, uid, phase.project_id.resource_calendar_id.id or False , res.id, resource_cal)
resource_objs.append(classobj(str(res.user_id.name), (Resource,), {'__doc__' : res.user_id.name, '__name__' : res.user_id.name, 'vacation' : tuple(leaves), 'efficiency' : resource_eff}))
return resource_objs
class wizard_schedule_task(wizard.interface):
@@ -55,12 +55,12 @@ class wizard_schedule_task(wizard.interface):
phase_pool = pool.get('project.phase')
task_pool = pool.get('project.task')
user_pool = pool.get('res.users')
phase = phase_pool.browse(cr,uid,data['id'])
task_ids = map(lambda x:x.id,(filter(lambda x:x.state in ['open','draft','pending'] ,phase.task_ids)))
phase = phase_pool.browse(cr, uid, data['id'])
task_ids = map(lambda x : x.id, (filter(lambda x : x.state in ['open','draft','pending'] , phase.task_ids)))
if task_ids:
task_ids.sort()
tasks = task_pool.browse(cr,uid,task_ids)
tasks = task_pool.browse(cr, uid, task_ids)
wktime_cal = []
start_date = str(phase.date_start)[:-9]
if not phase.date_start:
@@ -68,13 +68,13 @@ class wizard_schedule_task(wizard.interface):
start_date = datetime.datetime.now().strftime("%Y-%m-%d")
else:
start_date = phase.project_id.date_start
date_start = datetime.datetime.strftime(datetime.datetime.strptime(start_date,"%Y-%m-%d"),"%Y-%m-%d %H:%M")
date_start = datetime.datetime.strftime(datetime.datetime.strptime(start_date, "%Y-%m-%d"), "%Y-%m-%d %H:%M")
calendar_id = phase.project_id.resource_calendar_id.id
resource_objs = resource_list(cr,uid,phase)
priority_dict = {'0':1000,'1':800,'2':500,'3':300,'4':100}
resource_objs = resource_list(cr, uid, phase)
priority_dict = {'0' :1000,'1' :800,'2' :500,'3' :300,'4' :100}
# To create dynamic no of tasks with the resource specified
def tasks_resource(j,eff,priorty = 500,obj=False):
def tasks_resource(j, eff, priorty=500, obj=False):
def task():
"""
task is a dynamic method!
@@ -91,13 +91,13 @@ class wizard_schedule_task(wizard.interface):
def Project():
title = "Test Project"
start = date_start
resource = reduce(operator.or_,resource_objs)
resource = reduce(operator.or_, resource_objs)
minimum_time_unit = 1
# If project has calendar
if calendar_id:
working_days = proj.compute_working_calendar(cr,uid,calendar_id)
vacation = tuple(proj.leaves_resource(cr,uid,calendar_id))
working_days = proj.compute_working_calendar(cr, uid, calendar_id)
vacation = tuple(proj.leaves_resource(cr, uid, calendar_id))
# Dynamic Creation of tasks
i = 0
@@ -108,9 +108,9 @@ class wizard_schedule_task(wizard.interface):
if each_task.user_id:
for resource_object in resource_objs:
if resource_object.__name__ == each_task.user_id.name:
task = tasks_resource(i,hours,priorty,resource_object)
task = tasks_resource(i, hours, priorty, resource_object)
else:
task = tasks_resource(i,hours,priorty)
task = tasks_resource(i, hours, priorty)
i += 1
# Writing back the dates
@@ -120,8 +120,8 @@ class wizard_schedule_task(wizard.interface):
s_date = t.start.to_datetime()
e_date = t.end.to_datetime()
if loop_no > 0:
user_id = user_pool.search(cr,uid,[('name','=',t.booked_resource[0].__name__)])
task_pool.write(cr,uid,[tasks[loop_no-1].id],{'date_start':s_date.strftime('%Y-%m-%d %H:%M:%S'),'date_deadline':e_date.strftime('%Y-%m-%d %H:%M:%S'),'user_id':user_id[0]},context={'scheduler':True})
user_id = user_pool.search(cr, uid, [('name','=',t.booked_resource[0].__name__)])
task_pool.write(cr, uid, [tasks[loop_no-1].id], {'date_start' :s_date.strftime('%Y-%m-%d %H:%M:%S'), 'date_deadline' :e_date.strftime('%Y-%m-%d %H:%M:%S'), 'user_id' :user_id[0]}, context={'scheduler' :True})
loop_no +=1
return {}
+1 -1
View File
@@ -30,7 +30,7 @@
'website': 'http://www.openerp.com',
'depends': ['crm'],
'init_xml': [],
'update_xml': ['security/ir.model.access.csv',
'update_xml': [#'security/ir.model.access.csv',
'report_crm_view.xml',
'report_crm_lead_view.xml',
'report_crm_claim_view.xml',
+16 -211
View File
@@ -1,9 +1,8 @@
from osv import fields,osv
import tools
class report_crm_claim_user(osv.osv):
_name = "report.crm.claim.user"
_description = "Claim by user and section"
class report_crm_claim(osv.osv):
_name = "report.crm.claim"
_auto = False
_inherit = "report.crm.case.user"
_columns = {
@@ -12,226 +11,32 @@ class report_crm_claim_user(osv.osv):
'amount_costs': fields.float('Est.Cost', readonly=True),
'amount_revenue_prob': fields.float('Est. Rev*Prob.', readonly=True),
'delay_close': fields.char('Delay to close', size=20, readonly=True),
}
def init(self, cr):
tools.drop_view_if_exists(cr, 'report_crm_claim_user')
cr.execute("""
create or replace view report_crm_claim_user as (
select
min(c.id) as id,
to_char(c.create_date, 'YYYY') as name,
to_char(c.create_date, 'MM') as month,
c.state,
c.user_id,
c.section_id,
count(*) as nbr,
sum(planned_revenue) as amount_revenue,
sum(planned_cost) as amount_costs,
sum(planned_revenue*probability)::decimal(16,2) as amount_revenue_prob,
avg(probability)::decimal(16,2) as probability,
to_char(avg(date_closed-c.create_date), 'DD"d" HH24:MI:SS') as delay_close
from
crm_claim c
group by to_char(c.create_date, 'YYYY'), to_char(c.create_date, 'MM'), c.state, c.user_id,c.section_id
)""")
report_crm_claim_user()
class report_crm_claim_categ(osv.osv):
_name = "report.crm.claim.categ"
_description = "Claim by section and category"
_auto = False
_inherit = "report.crm.case.categ"
_columns = {
'categ_id': fields.many2one('crm.case.categ', 'Category', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.claim')]"),
'amount_revenue': fields.float('Est.Revenue', readonly=True),
'amount_costs': fields.float('Est.Cost', readonly=True),
'amount_revenue_prob': fields.float('Est. Rev*Prob.', readonly=True),
'probability': fields.float('Avg. Probability', readonly=True),
'delay_close': fields.char('Delay Close', size=20, readonly=True),
}
def init(self, cr):
tools.drop_view_if_exists(cr, 'report_crm_claim_categ')
cr.execute("""
create or replace view report_crm_claim_categ as (
select
min(c.id) as id,
to_char(c.create_date, 'YYYY') as name,
to_char(c.create_date, 'MM') as month,
c.categ_id,
c.state,
c.section_id,
count(*) as nbr,
sum(planned_revenue) as amount_revenue,
sum(planned_cost) as amount_costs,
sum(planned_revenue*probability)::decimal(16,2) as amount_revenue_prob,
avg(probability)::decimal(16,2) as probability,
to_char(avg(date_closed-c.create_date), 'DD"d" HH24:MI:SS') as delay_close
from
crm_claim c
group by c.categ_id,to_char(c.create_date, 'YYYY'), to_char(c.create_date, 'MM'), c.state,c.section_id
)""")
report_crm_claim_categ()
class report_crm_claim_section(osv.osv):
_name = "report.crm.claim.section"
_description = "Claim by Section"
_auto = False
_inherit = "report.crm.case.section"
def _get_data(self, cr, uid, ids, field_name, arg, context={}):
res = {}
state_perc = 0.0
avg_ans = 0.0
for case in self.browse(cr, uid, ids, context):
if field_name != 'avg_answers':
state = field_name[5:]
cr.execute("select count(*) from crm_claim where section_id =%s and state='%s'"%(case.section_id.id,state))
state_cases = cr.fetchone()[0]
perc_state = (state_cases / float(case.nbr_cases) ) * 100
res[case.id] = perc_state
else:
cr.execute('select count(*) from crm_case_log l where l.section_id=%s'%(case.section_id.id))
logs = cr.fetchone()[0]
avg_ans = logs / case.nbr_cases
res[case.id] = avg_ans
return res
_columns = {
'avg_answers': fields.function(_get_data,string='Avg. Answers', method=True,type="integer"),
'perc_done': fields.function(_get_data,string='%Done', method=True,type="float"),
'perc_cancel': fields.function(_get_data,string='%Cancel', method=True,type="float"),
'delay_close': fields.char('Delay to close', size=20, readonly=True),
}
_order = 'name desc, section_id'
def init(self, cr):
tools.drop_view_if_exists(cr, 'report_crm_claim_section')
cr.execute("""
create or replace view report_crm_claim_section as (
select
min(c.id) as id,
to_char(c.create_date, 'YYYY') as name,
to_char(c.create_date, 'MM') as month,
count(*) as nbr_cases,
c.section_id as section_id,
0 as avg_answers,
0.0 as perc_done,
0.0 as perc_cancel,
to_char(avg(date_closed-c.create_date), 'DD"d" HH24:MI:SS') as delay_close
from
crm_claim c
group by to_char(c.create_date, 'YYYY'),to_char(c.create_date, 'MM'),c.section_id
)""")
report_crm_claim_section()
class report_crm_claim_section_type(osv.osv):
_name = "report.crm.claim.section.type"
_inherit = "report.crm.case.section.type"
_description = "Claims by section and type"
_auto = False
_columns = {
'type_id': fields.many2one('crm.case.resource.type', 'Claim Type', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.claim')]", readonly=True),
'stage_id': fields.many2one ('crm.case.stage', 'Stage', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.claim')]", readonly=True),
'amount_revenue': fields.float('Est.Revenue', readonly=True),
'delay_close': fields.char('Delay Close', size=20, readonly=True),
'categ_id': fields.many2one('crm.case.categ', 'Category', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.claim')]"),
}
_order = 'type_id'
def init(self, cr):
tools.sql.drop_view_if_exists(cr, "report_crm_claim_section_type")
tools.drop_view_if_exists(cr, 'report_crm_claim')
cr.execute("""
create view report_crm_claim_section_type as (
select
min(c.id) as id,
to_char(c.create_date,'YYYY') as name,
to_char(c.create_date, 'MM') as month,
c.user_id,
c.state,
c.type_id,
c.stage_id,
c.section_id,
count(*) as nbr,
sum(planned_revenue) as amount_revenue,
to_char(avg(date_closed-c.create_date), 'DD"d" HH24:MI:SS') as delay_close
from
crm_claim c
where c.type_id is not null
group by to_char(c.create_date, 'YYYY'), to_char(c.create_date, 'MM'), c.user_id, c.state, c.stage_id, c.type_id, c.section_id)""")
report_crm_claim_section_type()
class report_crm_claim_section_categ_stage(osv.osv):
_name = "report.crm.claim.section.categ.stage"
_inherit = "report.crm.case.section.categ.stage"
_description = "Claims by Section, Category and Stage"
_auto = False
_columns = {
'categ_id': fields.many2one('crm.case.categ','Category', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.claim')]", readonly=True),
'stage_id':fields.many2one('crm.case.stage', 'Stage', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.claim')]", readonly=True),
'delay_close': fields.char('Delay Close', size=20, readonly=True),
}
_order = 'stage_id, categ_id'
def init(self, cr):
tools.sql.drop_view_if_exists(cr, "report_crm_claim_section_categ_stage")
cr.execute("""
create view report_crm_claim_section_categ_stage as (
select
min(c.id) as id,
to_char(c.create_date,'YYYY') as name,
to_char(c.create_date, 'MM') as month,
c.user_id,
c.categ_id,
c.state,
c.stage_id,
c.section_id,
count(*) as nbr,
to_char(avg(date_closed-c.create_date), 'DD"d" HH24:MI:SS') as delay_close
from
crm_claim c
where c.categ_id is not null AND c.stage_id is not null
group by to_char(c.create_date, 'YYYY'), to_char(c.create_date, 'MM'),c.user_id, c.categ_id, c.state, c.stage_id, c.section_id)""")
report_crm_claim_section_categ_stage()
class report_crm_claim_section_categ_type(osv.osv):
_name = "report.crm.claim.section.categ.type"
_inherit = "report.crm.case.section.categ.type"
_description = "Claims by Section, Category and Type"
_auto = False
_columns = {
'categ_id':fields.many2one('crm.case.categ', 'Category', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.claim')]", readonly=True),
'type_id': fields.many2one('crm.case.resource.type', 'Claim Type', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.claim')]", readonly=True),
'stage_id':fields.many2one('crm.case.stage', 'Stage', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.claim')]", readonly=True),
'delay_close': fields.char('Delay Close', size=20, readonly=True),
}
_order = 'categ_id, type_id'
def init(self, cr):
tools.sql.drop_view_if_exists(cr, "report_crm_claim_section_categ_type")
cr.execute("""
create view report_crm_claim_section_categ_type as (
create or replace view report_crm_claim as (
select
min(c.id) as id,
to_char(c.create_date, 'YYYY') as name,
to_char(c.create_date, 'MM') as month,
c.user_id,
c.categ_id,
c.type_id,
c.state,
c.stage_id,
c.user_id,
c.section_id,
c.stage_id,
c.categ_id,
count(*) as nbr,
sum(planned_revenue) as amount_revenue,
sum(planned_cost) as amount_costs,
sum(planned_revenue*probability)::decimal(16,2) as amount_revenue_prob,
avg(probability)::decimal(16,2) as probability,
to_char(avg(date_closed-c.create_date), 'DD"d" HH24:MI:SS') as delay_close
from
crm_claim c
where c.categ_id is not null AND c.type_id is not null
group by to_char(c.create_date, 'YYYY'), to_char(c.create_date, 'MM'),c.user_id, c.categ_id, c.type_id, c.state, c.stage_id, c.section_id)""")
group by to_char(c.create_date, 'YYYY'), to_char(c.create_date, 'MM'), c.state, c.user_id,c.section_id, c.stage_id,c.categ_id
)""")
report_crm_claim()
report_crm_claim_section_categ_type()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+35 -376
View File
@@ -5,24 +5,27 @@
Claim by user and section
-->
<record id="view_crm_claim_user_tree" model="ir.ui.view">
<field name="name">report.crm.claim.user.tree</field>
<field name="model">report.crm.claim.user</field>
<field name="inherit_id" ref="view_crm_case_user_tree"/>
<record id="view_report_crm_claim_tree" model="ir.ui.view">
<field name="name">report.crm.claim.tree</field>
<field name="model">report.crm.claim</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<field name="nbr" position="after">
<tree string="Leads">
<field name="name" />
<field name="month"/>
<field name="nbr" string="#Claim"/>
<field name="delay_close"/>
<field name="amount_revenue"/>
<field name="amount_costs"/>
<field name="amount_revenue_prob"/>
<field name="probability"/>
</field>
<field name="stage_id" invisible="1"/>
<field name="categ_id" invisible="1"/>
</tree>
</field>
</record>
<record id="view_crm_claim_user_form" model="ir.ui.view">
<field name="name">report.crm.claim.user.form</field>
<field name="model">report.crm.claim.user</field>
<record id="view_crm_claim_form" model="ir.ui.view">
<field name="name">report.crm.claim.form</field>
<field name="model">report.crm.claim</field>
<field name="inherit_id" ref="view_crm_case_user_form"/>
<field name="type">form</field>
<field name="arch" type="xml">
@@ -36,12 +39,12 @@
</field>
</record>
<record id="view_crm_claim_user_graph" model="ir.ui.view">
<field name="name">report.crm.claim.user.graph</field>
<field name="model">report.crm.claim.user</field>
<record id="view_crm_claim_graph" model="ir.ui.view">
<field name="name">report.crm.claim.graph</field>
<field name="model">report.crm.claim</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph orientation="horizontal" string="Claims by User and Section" type="bar">
<graph orientation="horizontal" string="Claims" type="bar">
<field name="state"/>
<field name="nbr" operator="+"/>
<field group="True" name="user_id"/>
@@ -49,9 +52,9 @@
</field>
</record>
<record id="view_crm_claim_user_filter" model="ir.ui.view">
<field name="name">report.crm.claim.user.select</field>
<field name="model">report.crm.claim.user</field>
<record id="view_crm_claim_filter" model="ir.ui.view">
<field name="name">report.crm.claim.select</field>
<field name="model">report.crm.claim</field>
<field name="inherit_id" ref="view_crm_case_user_filter"/>
<field name="type">search</field>
<field name="arch" type="xml">
@@ -60,368 +63,24 @@
</field>
</record>
<record id="action_report_crm_claim_user_tree" model="ir.actions.act_window">
<field name="name">Claim by User and Section</field>
<field name="res_model">report.crm.claim.user</field>
<record id="action_report_crm_claim_tree" model="ir.actions.act_window">
<field name="name">Claim</field>
<field name="res_model">report.crm.claim</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree</field>
<field name="view_id" ref="view_crm_claim_user_graph"/>
<field name="search_view_id" ref="view_crm_claim_user_filter"/>
<field name="view_id" ref="view_crm_claim_graph"/>
<!-- field name="search_view_id" ref="view_crm_claim_filter"/ -->
</record>
<menuitem name="Claim" id="menu_crm_claim_tree" parent="crm.next_id_52"/>
<menuitem action="action_report_crm_claim_user_tree" id="menu_crm_claim_user_tree" parent="menu_crm_claim_tree"/>
<record model="ir.actions.act_window.view" id="action_report_crm_lead_tree1">
<field name="sequence" eval="2"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_report_crm_claim_tree"/>
<field name="act_window_id" ref="action_report_crm_claim_tree"/>
</record>
<!-- # Claims by section and category of case -->
<menuitem name="Claim" id="menu_crm_claim_tree" action="action_report_crm_claim_tree" parent="crm.next_id_52"/>
<record id="view_crm_claim_categ_tree" model="ir.ui.view">
<field name="name">report.crm.claim.categ.tree</field>
<field name="model">report.crm.claim.categ</field>
<field name="inherit_id" ref="view_crm_case_categ_tree"/>
<field name="type">tree</field>
<field name="arch" type="xml">
<field name="nbr" position="after">
<field name="delay_close"/>
<field name="amount_revenue"/>
<field name="amount_costs"/>
<field name="amount_revenue_prob"/>
<field name="probability"/>
</field>
</field>
</record>
<record id="view_crm_claim_categ_form" model="ir.ui.view">
<field name="name">report.crm.claim.categ.form</field>
<field name="model">report.crm.claim.categ</field>
<field name="inherit_id" ref="view_crm_case_categ_form"/>
<field name="type">form</field>
<field name="arch" type="xml">
<field name="nbr" position="after">
<field name="delay_close"/>
<field name="amount_revenue"/>
<field name="amount_costs"/>
<field name="amount_revenue_prob"/>
<field name="probability"/>
</field>
</field>
</record>
<record id="view_crm_claim_categ_graph" model="ir.ui.view">
<field name="name">report.crm.claim.categ.graph</field>
<field name="model">report.crm.claim.categ</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph orientation="horizontal" string="Claims by Section and Categories" type="bar">
<field name="state"/>
<field name="nbr" operator="+"/>
<field group="True" name="categ_id"/>
</graph>
</field>
</record>
<record id="view_crm_claim_categ_filter" model="ir.ui.view">
<field name="name">report.crm.claim.categ.select</field>
<field name="model">report.crm.claim.categ</field>
<field name="inherit_id" ref="view_crm_case_categ_filter"/>
<field name="type">search</field>
<field name="arch" type="xml">
<field name="state" position="before">
</field>
</field>
</record>
<record id="action_report_crm_claim_categ_tree" model="ir.actions.act_window">
<field name="name">Claims by Categories and Section</field>
<field name="res_model">report.crm.claim.categ</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree</field>
<field name="view_id" ref="view_crm_claim_categ_graph"/>
<field name="search_view_id" ref="view_crm_claim_categ_filter"/>
</record>
<menuitem action="action_report_crm_claim_categ_tree" id="menu_crm_claim_categ_tree" parent="menu_crm_claim_tree"/>
<!-- Claim by Section -->
<record id="view_report_crm_claim_section_tree" model="ir.ui.view">
<field name="name">report.crm.claim.section.tree</field>
<field name="model">report.crm.claim.section</field>
<field name="inherit_id" ref="view_report_crm_case_section_tree"/>
<field name="type">tree</field>
<field name="arch" type="xml">
<field name="nbr_cases" position="after">
<field name="avg_answers"/>
<field name="perc_done" select="2"/>
<field name="perc_cancel" select="2"/>
<field name="delay_close"/>
</field>
</field>
</record>
<record id="view_report_crm_claim_section_graph" model="ir.ui.view">
<field name="name">report.crm.claim.section.graph</field>
<field name="model">report.crm.claim.section</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph orientation="horizontal" string="claims by Section" type="bar">
<field name="name"/>
<field name="nbr_cases" operator="+"/>
</graph>
</field>
</record>
<record id="view_report_crm_claim_section_filter" model="ir.ui.view">
<field name="name">report.crm.claim.section.select</field>
<field name="model">report.crm.claim.section</field>
<field name="inherit_id" ref="view_report_crm_case_section_filter"/>
<field name="type">search</field>
<field name="arch" type="xml">
<field name="nbr_cases" position="before">
</field>
</field>
</record>
<record id="action_report_crm_claim_section_tree" model="ir.actions.act_window">
<field name="name">Claims by Section</field>
<field name="res_model">report.crm.claim.section</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree</field>
<field name="view_id" ref="view_report_crm_claim_section_graph"/>
<field name="search_view_id" ref="view_report_crm_claim_section_filter"/>
</record>
<menuitem action="action_report_crm_claim_section_tree" id="menu_crm_claim_section_tree" parent="menu_crm_claim_tree"/>
#
# Claims by section and type
#
<record model="ir.ui.view" id="view_crm_claim_section_categ_tree">
<field name="name">CRM Report - Sections and Type(Tree)</field>
<field name="model">report.crm.claim.section.type</field>
<field name="inherit_id" ref="view_crm_case_section_categ_tree"/>
<field name="type">tree</field>
<field name="arch" type="xml">
<field name="user_id" position="after">
<field name="type_id"/>
<field name="stage_id"/>
<field name="amount_revenue"/>
<field name="delay_close"/>
</field>
</field>
</record>
<record model="ir.ui.view" id="view_crm_claim_section_categ_form">
<field name="name">CRM Report - Sections and Type(Form)</field>
<field name="model">report.crm.claim.section.type</field>
<field name="inherit_id" ref="view_crm_case_section_categ_form"/>
<field name="type">form</field>
<field name="arch" type="xml">
<field name="user_id" position="after">
<field name="type_id"/>
<field name="stage_id"/>
<field name="amount_revenue"/>
<field name="delay_close"/>
</field>
</field>
</record>
<record model="ir.ui.view" id="view_crm_claim_section_categ_graph">
<field name="name">CRM Report - Sections and Type(Graph)</field>
<field name="model">report.crm.claim.section.type</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Cases by Section and Type" type="bar" orientation="horizontal">
<field name="type_id"/>
<field name="amount_revenue" operator="+"/>
<field name="section_id" group="True"/>
</graph>
</field>
</record>
<record id="view_crm_claim_section_categ_filter" model="ir.ui.view">
<field name="name">CRM Report - Sections and Type(Select)</field>
<field name="model">report.crm.claim.section.type</field>
<field name="inherit_id" ref="view_crm_case_section_categ_filter"/>
<field name="type">search</field>
<field name="arch" type="xml">
<field name="section_id" position="after">
<field name="type_id"/>
</field>
</field>
</record>
<record model="ir.actions.act_window" id="action_report_crm_claim_section_categ_tree">
<field name="res_model">report.crm.claim.section.type</field>
<field name="name">Claims by section and type</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree</field>
<field name="search_view_id" ref="view_crm_claim_section_categ_filter"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_claim_section_categ_graph">
<field name="sequence" eval="1"/>
<field name="view_mode">graph</field>
<field name="view_id" ref="view_crm_claim_section_categ_graph"/>
<field name="act_window_id" ref="action_report_crm_claim_section_categ_tree"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_claim_section_categ_tree">
<field name="sequence" eval="2"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_crm_claim_section_categ_tree"/>
<field name="act_window_id" ref="action_report_crm_claim_section_categ_tree"/>
</record>
<menuitem action="action_report_crm_claim_section_categ_tree" id="menu_crm_claim_section_categ_tree" parent="menu_crm_claim_tree"/>
#
# Claims by section, category and stage
#
<record model="ir.ui.view" id="view_crm_claim_section_categ_stage_tree">
<field name="name">CRM Report - Section, Category and Stage(Tree)</field>
<field name="model">report.crm.claim.section.categ.stage</field>
<field name="inherit_id" ref="view_crm_case_section_categ_stage_tree"/>
<field name="type">tree</field>
<field name="arch" type="xml">
<field name="user_id" position="after">
<field name="categ_id"/>
<field name="stage_id"/>
<field name="delay_close"/>
</field>
</field>
</record>
<record model="ir.ui.view" id="view_crm_claim_section_categ_stage_form">
<field name="name">CRM Report - Section, Category and Stage(Form)</field>
<field name="model">report.crm.claim.section.categ.stage</field>
<field name="inherit_id" ref="view_crm_case_section_categ_stage_form"/>
<field name="type">form</field>
<field name="arch" type="xml">
<field name="user_id" position="after">
<field name="categ_id"/>
<field name="stage_id"/>
<field name="delay_close"/>
</field>
</field>
</record>
<record model="ir.ui.view" id="view_crm_claim_section_categ_stage_graph">
<field name="name">CRM Report - Section, Category and Stage(Select)</field>
<field name="model">report.crm.claim.section.categ.stage</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Claims by Section, Category and Stage" type="bar" orientation="horizontal">
<field name="categ_id"/>
<field name="nbr" operator="+"/>
<field name="section_id" group="True"/>
</graph>
</field>
</record>
<record id="view_crm_claim_section_categ_stage_filter" model="ir.ui.view">
<field name="name">CRM Report - Section, Category and Stage(Select)</field>
<field name="model">report.crm.claim.section.categ.stage</field>
<field name="inherit_id" ref="view_crm_case_section_categ_filter"/>
<field name="type">search</field>
<field name="arch" type="xml">
<field name="section_id" position="after">
<field name="categ_id"/>
<field name="stage_id"/>
</field>
</field>
</record>
<record model="ir.actions.act_window" id="action_report_crm_claim_section_categ_stage_tree">
<field name="res_model">report.crm.claim.section.categ.stage</field>
<field name="name">Claims by section, category and stage</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree</field>
<field name="search_view_id" ref="view_crm_claim_section_categ_stage_filter"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_claim_section_categ_stage_graph">
<field name="sequence" eval="1"/>
<field name="view_mode">graph</field>
<field name="view_id" ref="view_crm_claim_section_categ_stage_graph"/>
<field name="act_window_id" ref="action_report_crm_claim_section_categ_stage_tree"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_claim_section_categ_stage_tree">
<field name="sequence" eval="2"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_crm_claim_section_categ_stage_tree"/>
<field name="act_window_id" ref="action_report_crm_claim_section_categ_stage_tree"/>
</record>
<menuitem action="action_report_crm_claim_section_categ_stage_tree" id="menu_crm_claim_section_categ_stage_tree" parent="menu_crm_claim_tree"/>
#
# Claims by section, category and type
#
<record model="ir.ui.view" id="view_crm_claim_section_categ_type_tree">
<field name="name">CRM Report - Section, Category and Type(Tree)</field>
<field name="model">report.crm.claim.section.categ.type</field>
<field name="inherit_id" ref="view_crm_case_section_categ_type_tree"/>
<field name="type">tree</field>
<field name="arch" type="xml">
<field name="user_id" position="after">
<field name="categ_id"/>
<field name="type_id"/>
<field name="stage_id"/>
<field name="delay_close"/>
</field>
</field>
</record>
<record model="ir.ui.view" id="view_crm_claim_section_categ_type_form">
<field name="name">CRM Report - Section, Category and Type(Form)</field>
<field name="model">report.crm.claim.section.categ.type</field>
<field name="inherit_id" ref="view_crm_case_section_categ_type_form"/>
<field name="type">form</field>
<field name="arch" type="xml">
<field name="user_id" position="after">
<field name="categ_id"/>
<field name="type_id"/>
<field name="stage_id"/>
<field name="delay_close"/>
</field>
</field>
</record>
<record model="ir.ui.view" id="view_crm_claim_section_categ_type_graph">
<field name="name">CRM Report - Section, Category and Type(Select)</field>
<field name="model">report.crm.claim.section.categ.type</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Claims by Section, Category and Type" type="bar" orientation="horizontal">
<field name="type_id"/>
<field name="nbr" operator="+"/>
<field name="section_id" group="True"/>
</graph>
</field>
</record>
<record id="view_crm_claim_section_categ_type_filter" model="ir.ui.view">
<field name="name">CRM Report - Section, Category and Type(Select)</field>
<field name="model">report.crm.claim.section.categ.type</field>
<field name="inherit_id" ref="view_crm_case_section_categ_type_filter"/>
<field name="type">search</field>
<field name="arch" type="xml">
<field name="section_id" position="after">
<field name="categ_id" select="1"/>
<field name="type_id" select="1"/>
<field name="stage_id" select="1"/>
</field>
</field>
</record>
<record model="ir.actions.act_window" id="action_report_crm_claim_section_categ_type_tree">
<field name="res_model">report.crm.claim.section.categ.type</field>
<field name="name">Claims by section, category and type</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree</field>
<field name="search_view_id" ref="view_crm_claim_section_categ_type_filter"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_claim_section_categ_type_graph">
<field name="sequence" eval="1"/>
<field name="view_mode">graph</field>
<field name="view_id" ref="view_crm_claim_section_categ_type_graph"/>
<field name="act_window_id" ref="action_report_crm_claim_section_categ_type_tree"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_claim_section_categ_type_tree">
<field name="sequence" eval="2"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_crm_claim_section_categ_type_tree"/>
<field name="act_window_id" ref="action_report_crm_claim_section_categ_type_tree"/>
</record>
<menuitem action="action_report_crm_claim_section_categ_type_tree" id="menu_crm_claim_section_categ_type_tree" parent="menu_crm_claim_tree"/>
</data>
</openerp>
</openerp>
+9 -251
View File
@@ -1,273 +1,31 @@
from osv import fields,osv
import tools
class report_crm_lead_user(osv.osv):
_name = "report.crm.lead.user"
_description = "Leads by user and section"
class report_crm_lead(osv.osv):
_name = "report.crm.lead"
_auto = False
_inherit = "report.crm.case.user"
_columns = {
'probability': fields.float('Avg. Probability', readonly=True),
'amount_revenue': fields.float('Est.Revenue', readonly=True),
'amount_costs': fields.float('Est.Cost', readonly=True),
'amount_revenue_prob': fields.float('Est. Rev*Prob.', readonly=True),
'delay_close': fields.char('Delay to close', size=20, readonly=True),
}
def init(self, cr):
tools.drop_view_if_exists(cr, 'report_crm_lead_user')
cr.execute("""
create or replace view report_crm_lead_user as (
select
min(c.id) as id,
to_char(c.create_date, 'YYYY') as name,
to_char(c.create_date, 'MM') as month,
c.state,
c.user_id,
c.section_id,
count(*) as nbr,
sum(planned_revenue) as amount_revenue,
sum(planned_cost) as amount_costs,
sum(planned_revenue*probability)::decimal(16,2) as amount_revenue_prob,
avg(probability)::decimal(16,2) as probability,
to_char(avg(date_closed-c.create_date), 'DD"d" HH24:MI:SS') as delay_close
from
crm_lead c
group by to_char(c.create_date, 'YYYY'), to_char(c.create_date, 'MM'), c.state, c.user_id,c.section_id
)""")
report_crm_lead_user()
class report_crm_lead_categ(osv.osv):
_name = "report.crm.lead.categ"
_description = "Leads by section and category"
_auto = False
_inherit = "report.crm.case.categ"
_columns = {
'categ_id': fields.many2one('crm.case.categ', 'Category', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.lead')]"),
'amount_revenue': fields.float('Est.Revenue', readonly=True),
'amount_costs': fields.float('Est.Cost', readonly=True),
'amount_revenue_prob': fields.float('Est. Rev*Prob.', readonly=True),
'probability': fields.float('Avg. Probability', readonly=True),
'delay_close': fields.char('Delay Close', size=20, readonly=True),
}
def init(self, cr):
tools.drop_view_if_exists(cr, 'report_crm_lead_categ')
cr.execute("""
create or replace view report_crm_lead_categ as (
select
min(c.id) as id,
to_char(c.create_date, 'YYYY') as name,
to_char(c.create_date, 'MM') as month,
c.categ_id,
c.state,
c.section_id,
count(*) as nbr,
sum(planned_revenue) as amount_revenue,
sum(planned_cost) as amount_costs,
sum(planned_revenue*probability)::decimal(16,2) as amount_revenue_prob,
avg(probability)::decimal(16,2) as probability,
to_char(avg(date_closed-c.create_date), 'DD"d" HH24:MI:SS') as delay_close
from
crm_lead c
group by c.categ_id,to_char(c.create_date, 'YYYY'), to_char(c.create_date, 'MM'), c.state,c.section_id
)""")
report_crm_lead_categ()
class report_crm_lead_section(osv.osv):
_name = "report.crm.lead.section"
_description = "Leads by Section"
_auto = False
_inherit = "report.crm.case.section"
def _get_data(self, cr, uid, ids, field_name, arg, context={}):
res = {}
state_perc = 0.0
avg_ans = 0.0
for case in self.browse(cr, uid, ids, context):
if field_name != 'avg_answers':
state = field_name[5:]
cr.execute("select count(*) from crm_lead where section_id =%s and state='%s'"%(case.section_id.id,state))
state_cases = cr.fetchone()[0]
perc_state = (state_cases / float(case.nbr_cases) ) * 100
res[case.id] = perc_state
else:
cr.execute('select count(*) from crm_case_log l where l.section_id=%s'%(case.section_id.id))
logs = cr.fetchone()[0]
avg_ans = logs / case.nbr_cases
res[case.id] = avg_ans
return res
_columns = {
'avg_answers': fields.function(_get_data,string='Avg. Answers', method=True,type="integer"),
'perc_done': fields.function(_get_data,string='%Done', method=True,type="float"),
'perc_cancel': fields.function(_get_data,string='%Cancel', method=True,type="float"),
'delay_close': fields.char('Delay to close', size=20, readonly=True),
}
_order = 'name desc, section_id'
def init(self, cr):
tools.drop_view_if_exists(cr, 'report_crm_lead_section')
cr.execute("""
create or replace view report_crm_lead_section as (
select
min(c.id) as id,
to_char(c.create_date, 'YYYY') as name,
to_char(c.create_date, 'MM') as month,
count(*) as nbr_cases,
c.section_id as section_id,
0 as avg_answers,
0.0 as perc_done,
0.0 as perc_cancel,
to_char(avg(date_closed-c.create_date), 'DD"d" HH24:MI:SS') as delay_close
from
crm_lead c
group by to_char(c.create_date, 'YYYY'),to_char(c.create_date, 'MM'),c.section_id
)""")
report_crm_lead_section()
class report_crm_lead_section_stage(osv.osv):
_name = "report.crm.lead.section.stage"
_description = "Leads by section and stage"
_auto = False
_inherit = "report.crm.case.section.stage"
_columns = {
'categ_id': fields.many2one('crm.case.categ', 'Category', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.lead')]", readonly=True),
'stage_id': fields.many2one ('crm.case.stage', 'Stage', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.lead')]", readonly=True),
'amount_revenue': fields.float('Est.Revenue', readonly=True),
'delay_close': fields.char('Delay Close', size=20, readonly=True),
}
_order = 'stage_id, section_id'
def init(self, cr):
tools.sql.drop_view_if_exists(cr, "report_crm_lead_section_stage")
cr.execute("""
create view report_crm_lead_section_stage as (
select
min(c.id) as id,
to_char(c.create_date,'YYYY') as name,
to_char(c.create_date, 'MM') as month,
c.user_id,
c.state,
c.stage_id,
c.section_id,
c.categ_id,
count(*) as nbr,
sum(planned_revenue) as amount_revenue,
to_char(avg(date_closed-c.create_date), 'DD"d" HH24:MI:SS') as delay_close
from
crm_lead c
where c.stage_id is not null
group by to_char(c.create_date, 'YYYY'), to_char(c.create_date, 'MM'), c.user_id, c.state, c.stage_id, c.categ_id, c.section_id)""")
report_crm_lead_section_stage()
class report_crm_lead_section_type(osv.osv):
_name = "report.crm.lead.section.type"
_inherit = "report.crm.case.section.type"
_description = "Leads by section and type"
_auto = False
_columns = {
'type_id': fields.many2one('crm.case.resource.type', 'Lead Type', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.lead')]", readonly=True),
'stage_id': fields.many2one ('crm.case.stage', 'Stage', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.lead')]", readonly=True),
'amount_revenue': fields.float('Est.Revenue', readonly=True),
'delay_close': fields.char('Delay Close', size=20, readonly=True),
}
_order = 'type_id'
def init(self, cr):
tools.sql.drop_view_if_exists(cr, "report_crm_lead_section_type")
tools.drop_view_if_exists(cr, 'report_crm_lead')
cr.execute("""
create view report_crm_lead_section_type as (
select
min(c.id) as id,
to_char(c.create_date,'YYYY') as name,
to_char(c.create_date, 'MM') as month,
c.user_id,
c.state,
c.type_id,
c.stage_id,
c.section_id,
count(*) as nbr,
sum(planned_revenue) as amount_revenue,
to_char(avg(date_closed-c.create_date), 'DD"d" HH24:MI:SS') as delay_close
from
crm_lead c
where c.type_id is not null
group by to_char(c.create_date, 'YYYY'), to_char(c.create_date, 'MM'), c.user_id, c.state, c.stage_id, c.type_id, c.section_id)""")
report_crm_lead_section_type()
class report_crm_lead_section_categ_stage(osv.osv):
_name = "report.crm.lead.section.categ.stage"
_inherit = "report.crm.case.section.categ.stage"
_description = "Leads by Section, Category and Stage"
_auto = False
_columns = {
'categ_id': fields.many2one('crm.case.categ','Category', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.lead')]", readonly=True),
'stage_id':fields.many2one('crm.case.stage', 'Stage', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.lead')]", readonly=True),
'delay_close': fields.char('Delay Close', size=20, readonly=True),
}
_order = 'stage_id, categ_id'
def init(self, cr):
tools.sql.drop_view_if_exists(cr, "report_crm_lead_section_categ_stage")
cr.execute("""
create view report_crm_lead_section_categ_stage as (
select
min(c.id) as id,
to_char(c.create_date,'YYYY') as name,
to_char(c.create_date, 'MM') as month,
c.user_id,
c.categ_id,
c.state,
c.stage_id,
c.section_id,
count(*) as nbr,
to_char(avg(date_closed-c.create_date), 'DD"d" HH24:MI:SS') as delay_close
from
crm_lead c
where c.categ_id is not null AND c.stage_id is not null
group by to_char(c.create_date, 'YYYY'), to_char(c.create_date, 'MM'),c.user_id, c.categ_id, c.state, c.stage_id, c.section_id)""")
report_crm_lead_section_categ_stage()
class report_crm_lead_section_categ_type(osv.osv):
_name = "report.crm.lead.section.categ.type"
_inherit = "report.crm.case.section.categ.type"
_description = "Leads by Section, Category and Type"
_auto = False
_columns = {
'categ_id':fields.many2one('crm.case.categ', 'Category', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.lead')]", readonly=True),
'type_id': fields.many2one('crm.case.resource.type', 'Lead Type', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.lead')]", readonly=True),
'stage_id':fields.many2one('crm.case.stage', 'Stage', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.lead')]", readonly=True),
'delay_close': fields.char('Delay Close', size=20, readonly=True),
}
_order = 'categ_id, type_id'
def init(self, cr):
tools.sql.drop_view_if_exists(cr, "report_crm_lead_section_categ_type")
cr.execute("""
create view report_crm_lead_section_categ_type as (
create or replace view report_crm_lead as (
select
min(c.id) as id,
to_char(c.create_date, 'YYYY') as name,
to_char(c.create_date, 'MM') as month,
c.user_id,
c.categ_id,
c.type_id,
c.state,
c.user_id,
c.stage_id,
c.section_id,
count(*) as nbr,
to_char(avg(date_closed-c.create_date), 'DD"d" HH24:MI:SS') as delay_close
from
crm_lead c
where c.categ_id is not null AND c.type_id is not null
group by to_char(c.create_date, 'YYYY'), to_char(c.create_date, 'MM'),c.user_id, c.categ_id, c.type_id, c.state, c.stage_id, c.section_id)""")
report_crm_lead_section_categ_type()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
group by to_char(c.create_date, 'YYYY'), to_char(c.create_date, 'MM'), c.state, c.user_id,c.section_id,c.stage_id
)""")
report_crm_lead()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+41 -446
View File
@@ -5,43 +5,39 @@
Leads by user and section
-->
<record id="view_crm_lead_user_tree" model="ir.ui.view">
<field name="name">report.crm.lead.user.tree</field>
<field name="model">report.crm.lead.user</field>
<field name="inherit_id" ref="view_crm_case_user_tree"/>
<record id="view_crm_lead_tree" model="ir.ui.view">
<field name="name">report.crm.lead.tree</field>
<field name="model">report.crm.lead</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<field name="nbr" position="after">
<field name="delay_close"/>
<field name="amount_revenue"/>
<field name="amount_costs"/>
<field name="amount_revenue_prob"/>
<field name="probability"/>
</field>
<tree string="Leads">
<field name="name" />
<field name="month"/>
<field name="nbr" />
<field name="delay_close"/>
<field name="stage_id" invisible="1"/>
</tree>
</field>
</record>
<record id="view_crm_lead_user_form" model="ir.ui.view">
<field name="name">report.crm.lead.user.form</field>
<field name="model">report.crm.lead.user</field>
<record id="view_crm_lead_form" model="ir.ui.view">
<field name="name">report.crm.lead.form</field>
<field name="model">report.crm.lead</field>
<field name="inherit_id" ref="view_crm_case_user_form"/>
<field name="type">form</field>
<field name="arch" type="xml">
<field name="nbr" position="after">
<field name="delay_close"/>
<field name="amount_revenue"/>
<field name="amount_costs"/>
<field name="amount_revenue_prob"/>
<field name="probability"/>
<field name="stage_id"/>
</field>
</field>
</record>
<record id="view_crm_lead_user_graph" model="ir.ui.view">
<field name="name">report.crm.lead.user.graph</field>
<field name="model">report.crm.lead.user</field>
<record id="view_crm_lead_graph" model="ir.ui.view">
<field name="name">report.crm.lead.graph</field>
<field name="model">report.crm.lead</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph orientation="horizontal" string="Leads by User and Section" type="bar">
<graph orientation="horizontal" string="Leads" type="bar">
<field name="state"/>
<field name="nbr" operator="+"/>
<field group="True" name="user_id"/>
@@ -49,437 +45,36 @@
</field>
</record>
<record id="view_crm_lead_user_filter" model="ir.ui.view">
<field name="name">report.crm.lead.user.select</field>
<field name="model">report.crm.lead.user</field>
<record id="view_crm_lead_filter" model="ir.ui.view">
<field name="name">report.crm.lead.select</field>
<field name="model">report.crm.lead</field>
<field name="inherit_id" ref="view_crm_case_user_filter"/>
<field name="type">search</field>
<field name="arch" type="xml">
<field name="state" position="before">
</field>
<search string="Search">
<field name="state" position="before"/>
</search>
</field>
</record>
<record id="action_report_crm_lead_user_tree" model="ir.actions.act_window">
<field name="name">Leads by User and Section</field>
<field name="res_model">report.crm.lead.user</field>
<record id="action_report_crm_lead_tree" model="ir.actions.act_window">
<field name="name">Leads</field>
<field name="res_model">report.crm.lead</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree</field>
<field name="view_id" ref="view_crm_lead_user_graph"/>
<field name="search_view_id" ref="view_crm_lead_user_filter"/>
<field name="view_id" ref="view_crm_lead_graph"/>
<!-- field name="search_view_id" ref="view_crm_lead_filter"/ -->
</record>
<menuitem name="Leads" id="menu_crm_leads_tree" parent="crm.next_id_52"/>
<menuitem action="action_report_crm_lead_user_tree" id="menu_crm_lead_user_tree" parent="menu_crm_leads_tree"/>
<!-- # Leads by section and category of case -->
<record id="view_crm_lead_categ_tree" model="ir.ui.view">
<field name="name">report.crm.lead.categ.tree</field>
<field name="model">report.crm.lead.categ</field>
<field name="inherit_id" ref="view_crm_case_categ_tree"/>
<field name="type">tree</field>
<field name="arch" type="xml">
<field name="nbr" position="after">
<field name="delay_close"/>
<field name="amount_revenue"/>
<field name="amount_costs"/>
<field name="amount_revenue_prob"/>
<field name="probability"/>
</field>
</field>
</record>
<record id="view_crm_lead_categ_form" model="ir.ui.view">
<field name="name">report.crm.lead.categ.form</field>
<field name="model">report.crm.lead.categ</field>
<field name="inherit_id" ref="view_crm_case_categ_form"/>
<field name="type">form</field>
<field name="arch" type="xml">
<field name="nbr" position="after">
<field name="delay_close"/>
<field name="amount_revenue"/>
<field name="amount_costs"/>
<field name="amount_revenue_prob"/>
<field name="probability"/>
</field>
</field>
</record>
<record id="view_crm_lead_categ_graph" model="ir.ui.view">
<field name="name">report.crm.lead.categ.graph</field>
<field name="model">report.crm.lead.categ</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph orientation="horizontal" string="Leads by Section and Categories" type="bar">
<field name="state"/>
<field name="nbr" operator="+"/>
<field group="True" name="categ_id"/>
</graph>
</field>
</record>
<record id="view_crm_lead_categ_filter" model="ir.ui.view">
<field name="name">report.crm.lead.categ.select</field>
<field name="model">report.crm.lead.categ</field>
<field name="inherit_id" ref="view_crm_case_categ_filter"/>
<field name="type">search</field>
<field name="arch" type="xml">
<field name="state" position="before">
</field>
</field>
</record>
<record id="action_report_crm_lead_categ_tree" model="ir.actions.act_window">
<field name="name">Leads by Categories and Section</field>
<field name="res_model">report.crm.lead.categ</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree</field>
<field name="view_id" ref="view_crm_lead_categ_graph"/>
<field name="search_view_id" ref="view_crm_lead_categ_filter"/>
</record>
<menuitem action="action_report_crm_lead_categ_tree" id="menu_crm_lead_categ_tree" parent="menu_crm_leads_tree"/>
<!-- Leads by Section -->
<record id="view_report_crm_lead_section_tree" model="ir.ui.view">
<field name="name">report.crm.lead.section.tree</field>
<field name="model">report.crm.lead.section</field>
<field name="inherit_id" ref="view_report_crm_case_section_tree"/>
<field name="type">tree</field>
<field name="arch" type="xml">
<field name="nbr_cases" position="after">
<field name="avg_answers"/>
<field name="perc_done" select="2"/>
<field name="perc_cancel" select="2"/>
<field name="delay_close"/>
</field>
</field>
</record>
<record id="view_report_crm_lead_section_graph" model="ir.ui.view">
<field name="name">report.crm.lead.section.graph</field>
<field name="model">report.crm.lead.section</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph orientation="horizontal" string="Leads by Section" type="bar">
<field name="name"/>
<field name="nbr_cases" operator="+"/>
</graph>
</field>
</record>
<record id="view_report_crm_lead_section_filter" model="ir.ui.view">
<field name="name">report.crm.lead.section.select</field>
<field name="model">report.crm.lead.section</field>
<field name="inherit_id" ref="view_report_crm_case_section_filter"/>
<field name="type">search</field>
<field name="arch" type="xml">
<field name="nbr_cases" position="before">
</field>
</field>
</record>
<record id="action_report_crm_lead_section_tree" model="ir.actions.act_window">
<field name="name">Leads by Section</field>
<field name="res_model">report.crm.lead.section</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree</field>
<field name="view_id" ref="view_report_crm_lead_section_graph"/>
<field name="search_view_id" ref="view_report_crm_lead_section_filter"/>
</record>
<menuitem action="action_report_crm_lead_section_tree" id="menu_crm_lead_section_tree" parent="menu_crm_leads_tree"/>
<!-- Cases by section and stage -->
<record model="ir.ui.view" id="view_crm_lead_section_stage_tree">
<field name="name">Leads Report - Sections and Stage(Tree)</field>
<field name="model">report.crm.lead.section.stage</field>
<field name="inherit_id" ref="view_crm_case_section_stage_tree"/>
<field name="type">tree</field>
<field name="arch" type="xml">
<field name="nbr" position="after">
<field name="categ_id"/>
<field name="stage_id" select="2"/>
<field name="amount_revenue" select="2"/>
<field name="delay_close"/>
</field>
</field>
</record>
<record model="ir.ui.view" id="view_crm_lead_section_stage_form">
<field name="name">Leads Report - Sections and Stage(Form)</field>
<field name="model">report.crm.lead.section.stage</field>
<field name="type">form</field>
<field name="arch" type="xml">
<field name="nbr" position="after">
<field name="categ_id"/>
<field name="stage_id" select="2"/>
<field name="amount_revenue" select="2"/>
<field name="delay_close"/>
</field>
</field>
</record>
<record model="ir.ui.view" id="view_crm_lead_section_stage_graph">
<field name="name">Leads Report - Sections and Stage(Graph)</field>
<field name="model">report.crm.lead.section.stage</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Leads by Section and Stage" type="bar" orientation="horizontal">
<field name="stage_id"/>
<field name="amount_revenue" operator="+"/>
<field name="section_id" group="True"/>
</graph>
</field>
</record>
<record id="view_crm_lead_section_stage_filter" model="ir.ui.view">
<field name="name">Leads Report - Sections and Stage(Select)</field>
<field name="model">report.crm.lead.section.stage</field>
<field name="type">search</field>
<field name="arch" type="xml">
<field name="state" position="before">
</field>
</field>
</record>
<record model="ir.actions.act_window" id="action_report_crm_lead_section_stage_tree">
<field name="res_model">report.crm.lead.section.stage</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree</field>
<field name="view_id" ref="view_crm_lead_section_stage_tree"/>
<field name="search_view_id" ref="view_crm_lead_section_stage_filter"/>
</record>
#
# Leads by section and type
#
<record model="ir.ui.view" id="view_crm_lead_section_categ_tree">
<field name="name">CRM Report - Sections and Type(Tree)</field>
<field name="model">report.crm.lead.section.type</field>
<field name="inherit_id" ref="view_crm_case_section_categ_tree"/>
<field name="type">tree</field>
<field name="arch" type="xml">
<field name="user_id" position="after">
<field name="type_id"/>
<field name="stage_id"/>
<field name="amount_revenue"/>
<field name="delay_close"/>
</field>
</field>
</record>
<record model="ir.ui.view" id="view_crm_lead_section_categ_form">
<field name="name">CRM Report - Sections and Type(Form)</field>
<field name="model">report.crm.lead.section.type</field>
<field name="inherit_id" ref="view_crm_case_section_categ_form"/>
<field name="type">form</field>
<field name="arch" type="xml">
<field name="user_id" position="after">
<field name="type_id"/>
<field name="stage_id"/>
<field name="amount_revenue"/>
<field name="delay_close"/>
</field>
</field>
</record>
<record model="ir.ui.view" id="view_crm_lead_section_categ_graph">
<field name="name">CRM Report - Sections and Type(Graph)</field>
<field name="model">report.crm.lead.section.type</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Leads by Section and Type" type="bar" orientation="horizontal">
<field name="type_id"/>
<field name="amount_revenue" operator="+"/>
<field name="section_id" group="True"/>
</graph>
</field>
</record>
<record id="view_crm_lead_section_categ_filter" model="ir.ui.view">
<field name="name">CRM Report - Sections and Type(Select)</field>
<field name="model">report.crm.lead.section.type</field>
<field name="inherit_id" ref="view_crm_case_section_categ_filter"/>
<field name="type">search</field>
<field name="arch" type="xml">
<field name="section_id" position="after">
<field name="type_id"/>
</field>
</field>
</record>
<record model="ir.actions.act_window" id="action_report_crm_lead_section_categ_tree">
<field name="res_model">report.crm.lead.section.type</field>
<field name="name">Leads by section and type</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree</field>
<field name="search_view_id" ref="view_crm_lead_section_categ_filter"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_lead_section_categ_graph">
<field name="sequence" eval="1"/>
<field name="view_mode">graph</field>
<field name="view_id" ref="view_crm_lead_section_categ_graph"/>
<field name="act_window_id" ref="action_report_crm_lead_section_categ_tree"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_lead_section_categ_tree">
<field name="sequence" eval="2"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_crm_lead_section_categ_tree"/>
<field name="act_window_id" ref="action_report_crm_lead_section_categ_tree"/>
</record>
<menuitem action="action_report_crm_lead_section_categ_tree" id="menu_crm_lead_section_categ_tree" parent="menu_crm_leads_tree"/>
#
# Leads by section, category and stage
#
<record model="ir.ui.view" id="view_crm_lead_section_categ_stage_tree">
<field name="name">CRM Report - Section, Category and Stage(Tree)</field>
<field name="model">report.crm.lead.section.categ.stage</field>
<field name="inherit_id" ref="view_crm_case_section_categ_stage_tree"/>
<field name="type">tree</field>
<field name="arch" type="xml">
<field name="user_id" position="after">
<field name="categ_id"/>
<field name="stage_id"/>
<field name="delay_close"/>
</field>
</field>
</record>
<record model="ir.ui.view" id="view_crm_lead_section_categ_stage_form">
<field name="name">CRM Report - Section, Category and Stage(Form)</field>
<field name="model">report.crm.lead.section.categ.stage</field>
<field name="inherit_id" ref="view_crm_case_section_categ_stage_form"/>
<field name="type">form</field>
<field name="arch" type="xml">
<field name="user_id" position="after">
<field name="categ_id"/>
<field name="stage_id"/>
<field name="delay_close"/>
</field>
</field>
</record>
<record model="ir.ui.view" id="view_crm_lead_section_categ_stage_graph">
<field name="name">CRM Report - Section, Category and Stage(Select)</field>
<field name="model">report.crm.lead.section.categ.stage</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Leads by Section, Category and Stage" type="bar" orientation="horizontal">
<field name="categ_id"/>
<field name="nbr" operator="+"/>
<field name="section_id" group="True"/>
</graph>
</field>
</record>
<record id="view_crm_lead_section_categ_stage_filter" model="ir.ui.view">
<field name="name">CRM Report - Section, Category and Stage(Select)</field>
<field name="model">report.crm.lead.section.categ.stage</field>
<field name="inherit_id" ref="view_crm_case_section_categ_filter"/>
<field name="type">search</field>
<field name="arch" type="xml">
<field name="section_id" position="after">
<field name="categ_id"/>
<field name="stage_id"/>
</field>
</field>
</record>
<record model="ir.actions.act_window" id="action_report_crm_lead_section_categ_stage_tree">
<field name="res_model">report.crm.lead.section.categ.stage</field>
<field name="name">Leads by section, category and stage</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree</field>
<field name="search_view_id" ref="view_crm_lead_section_categ_stage_filter"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_lead_section_categ_stage_graph">
<field name="sequence" eval="1"/>
<field name="view_mode">graph</field>
<field name="view_id" ref="view_crm_lead_section_categ_stage_graph"/>
<field name="act_window_id" ref="action_report_crm_lead_section_categ_stage_tree"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_lead_section_categ_stage_tree">
<field name="sequence" eval="2"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_crm_lead_section_categ_stage_tree"/>
<field name="act_window_id" ref="action_report_crm_lead_section_categ_stage_tree"/>
</record>
<menuitem action="action_report_crm_lead_section_categ_stage_tree" id="menu_crm_lead_section_categ_stage_tree" parent="menu_crm_leads_tree"/>
#
# Leads by section, category and type
#
<record model="ir.ui.view" id="view_crm_lead_section_categ_type_tree">
<field name="name">CRM Report - Section, Category and Type(Tree)</field>
<field name="model">report.crm.lead.section.categ.type</field>
<field name="inherit_id" ref="view_crm_case_section_categ_type_tree"/>
<field name="type">tree</field>
<field name="arch" type="xml">
<field name="user_id" position="after">
<field name="categ_id"/>
<field name="type_id"/>
<field name="stage_id"/>
<field name="delay_close"/>
</field>
</field>
</record>
<record model="ir.ui.view" id="view_crm_lead_section_categ_type_form">
<field name="name">CRM Report - Section, Category and Type(Form)</field>
<field name="model">report.crm.lead.section.categ.type</field>
<field name="inherit_id" ref="view_crm_case_section_categ_type_form"/>
<field name="type">form</field>
<field name="arch" type="xml">
<field name="user_id" position="after">
<field name="categ_id"/>
<field name="type_id"/>
<field name="stage_id"/>
<field name="delay_close"/>
</field>
</field>
</record>
<record model="ir.ui.view" id="view_crm_lead_section_categ_type_graph">
<field name="name">CRM Report - Section, Category and Type(Select)</field>
<field name="model">report.crm.lead.section.categ.type</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Leads by Section, Category and Type" type="bar" orientation="horizontal">
<field name="type_id"/>
<field name="nbr" operator="+"/>
<field name="section_id" group="True"/>
</graph>
</field>
</record>
<record id="view_crm_lead_section_categ_type_filter" model="ir.ui.view">
<field name="name">CRM Report - Section, Category and Type(Select)</field>
<field name="model">report.crm.lead.section.categ.type</field>
<field name="inherit_id" ref="view_crm_case_section_categ_type_filter"/>
<field name="type">search</field>
<field name="arch" type="xml">
<field name="section_id" position="after">
<field name="categ_id" select="1"/>
<field name="type_id" select="1"/>
<field name="stage_id" select="1"/>
</field>
</field>
</record>
<record model="ir.actions.act_window" id="action_report_crm_lead_section_categ_type_tree">
<field name="res_model">report.crm.lead.section.categ.type</field>
<field name="name">Leads by section, category and type</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree</field>
<field name="search_view_id" ref="view_crm_lead_section_categ_type_filter"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_lead_section_categ_type_graph">
<field name="sequence" eval="1"/>
<field name="view_mode">graph</field>
<field name="view_id" ref="view_crm_lead_section_categ_type_graph"/>
<field name="act_window_id" ref="action_report_crm_lead_section_categ_type_tree"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_lead_section_categ_type_tree">
<field name="sequence" eval="2"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_crm_lead_section_categ_type_tree"/>
<field name="act_window_id" ref="action_report_crm_lead_section_categ_type_tree"/>
</record>
<menuitem action="action_report_crm_lead_section_categ_type_tree" id="menu_crm_lead_section_categ_type_tree" parent="menu_crm_leads_tree"/>
<record model="ir.actions.act_window.view" id="action_report_crm_lead_tree1">
<field name="sequence" eval="2"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_crm_lead_tree"/>
<field name="act_window_id" ref="action_report_crm_lead_tree"/>
</record>
<menuitem name="Leads" id="menu_crm_leads_tree" parent="crm.next_id_52" action="action_report_crm_lead_tree"/>
</data>
</openerp>
+10 -203
View File
@@ -1,9 +1,8 @@
from osv import fields,osv
import tools
class report_crm_opportunity_user(osv.osv):
_name = "report.crm.opportunity.user"
_description = "Opportunity by user and section"
class report_crm_opportunity(osv.osv):
_name = "report.crm.opportunity"
_auto = False
_inherit = "report.crm.case.user"
_columns = {
@@ -11,53 +10,22 @@ class report_crm_opportunity_user(osv.osv):
'amount_revenue': fields.float('Est.Revenue', readonly=True),
'amount_revenue_prob': fields.float('Est. Rev*Prob.', readonly=True),
'delay_close': fields.char('Delay to close', size=20, readonly=True),
}
def init(self, cr):
tools.drop_view_if_exists(cr, 'report_crm_opportunity_user')
cr.execute("""
create or replace view report_crm_opportunity_user as (
select
min(c.id) as id,
to_char(c.create_date, 'YYYY') as name,
to_char(c.create_date, 'MM') as month,
c.state,
c.user_id,
c.section_id,
count(*) as nbr,
sum(planned_revenue) as amount_revenue,
sum(planned_revenue*probability)::decimal(16,2) as amount_revenue_prob,
avg(probability)::decimal(16,2) as probability,
to_char(avg(date_closed-c.create_date), 'DD"d" HH24:MI:SS') as delay_close
from
crm_opportunity c
group by to_char(c.create_date, 'YYYY'), to_char(c.create_date, 'MM'), c.state, c.user_id,c.section_id
)""")
report_crm_opportunity_user()
class report_crm_opportunity_categ(osv.osv):
_name = "report.crm.opportunity.categ"
_description = "Opportunity by section and category"
_auto = False
_inherit = "report.crm.case.categ"
_columns = {
'categ_id': fields.many2one('crm.case.categ', 'Category', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.opportunity')]"),
'amount_revenue': fields.float('Est.Revenue', readonly=True),
'amount_revenue_prob': fields.float('Est. Rev*Prob.', readonly=True),
'probability': fields.float('Avg. Probability', readonly=True),
'delay_close': fields.char('Delay Close', size=20, readonly=True),
'stage_id':fields.many2one('crm.case.stage', 'Stage', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.opportunity')]", readonly=True),
}
def init(self, cr):
tools.drop_view_if_exists(cr, 'report_crm_opportunity_categ')
tools.drop_view_if_exists(cr, 'report_crm_opportunity')
cr.execute("""
create or replace view report_crm_opportunity_categ as (
create or replace view report_crm_opportunity as (
select
min(c.id) as id,
to_char(c.create_date, 'YYYY') as name,
to_char(c.create_date, 'MM') as month,
c.categ_id,
c.state,
c.user_id,
c.section_id,
c.categ_id,
c.stage_id,
count(*) as nbr,
sum(planned_revenue) as amount_revenue,
sum(planned_revenue*probability)::decimal(16,2) as amount_revenue_prob,
@@ -65,168 +33,7 @@ class report_crm_opportunity_categ(osv.osv):
to_char(avg(date_closed-c.create_date), 'DD"d" HH24:MI:SS') as delay_close
from
crm_opportunity c
group by c.categ_id,to_char(c.create_date, 'YYYY'), to_char(c.create_date, 'MM'), c.state,c.section_id
group by to_char(c.create_date, 'YYYY'), to_char(c.create_date, 'MM'), c.state, c.user_id,c.section_id,c.stage_id,c.categ_id
)""")
report_crm_opportunity_categ()
class report_crm_opportunity_section(osv.osv):
_name = "report.crm.opportunity.section"
_description = "Opportunity by Section"
_auto = False
_inherit = "report.crm.case.section"
def _get_data(self, cr, uid, ids, field_name, arg, context={}):
res = {}
state_perc = 0.0
avg_ans = 0.0
for case in self.browse(cr, uid, ids, context):
if field_name != 'avg_answers':
state = field_name[5:]
cr.execute("select count(*) from crm_opportunity where section_id =%s and state='%s'"%(case.section_id.id,state))
state_cases = cr.fetchone()[0]
perc_state = (state_cases / float(case.nbr_cases) ) * 100
res[case.id] = perc_state
else:
cr.execute('select count(*) from crm_case_log l where l.section_id=%s'%(case.section_id.id))
logs = cr.fetchone()[0]
avg_ans = logs / case.nbr_cases
res[case.id] = avg_ans
return res
_columns = {
'avg_answers': fields.function(_get_data,string='Avg. Answers', method=True,type="integer"),
'perc_done': fields.function(_get_data,string='%Done', method=True,type="float"),
'perc_cancel': fields.function(_get_data,string='%Cancel', method=True,type="float"),
'delay_close': fields.char('Delay to close', size=20, readonly=True),
}
_order = 'name desc, section_id'
def init(self, cr):
tools.drop_view_if_exists(cr, 'report_crm_opportunity_section')
cr.execute("""
create or replace view report_crm_opportunity_section as (
select
min(c.id) as id,
to_char(c.create_date, 'YYYY') as name,
to_char(c.create_date, 'MM') as month,
count(*) as nbr_cases,
c.section_id as section_id,
0 as avg_answers,
0.0 as perc_done,
0.0 as perc_cancel,
to_char(avg(date_closed-c.create_date), 'DD"d" HH24:MI:SS') as delay_close
from
crm_opportunity c
group by to_char(c.create_date, 'YYYY'),to_char(c.create_date, 'MM'),c.section_id
)""")
report_crm_opportunity_section()
class report_crm_opportunity_section_type(osv.osv):
_name = "report.crm.opportunity.section.type"
_inherit = "report.crm.case.section.type"
_description = "Opportunity by section and type"
_auto = False
_columns = {
'type_id': fields.many2one('crm.case.resource.type', 'Opportunity Type', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.opportunity')]", readonly=True),
'stage_id': fields.many2one ('crm.case.stage', 'Stage', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.opportunity')]", readonly=True),
'amount_revenue': fields.float('Est.Revenue', readonly=True),
'delay_close': fields.char('Delay Close', size=20, readonly=True),
}
_order = 'type_id'
def init(self, cr):
tools.sql.drop_view_if_exists(cr, "report_crm_opportunity_section_type")
cr.execute("""
create view report_crm_opportunity_section_type as (
select
min(c.id) as id,
to_char(c.create_date,'YYYY') as name,
to_char(c.create_date, 'MM') as month,
c.user_id,
c.state,
c.type_id,
c.stage_id,
c.section_id,
count(*) as nbr,
sum(planned_revenue) as amount_revenue,
to_char(avg(date_closed-c.create_date), 'DD"d" HH24:MI:SS') as delay_close
from
crm_opportunity c
where c.type_id is not null
group by to_char(c.create_date, 'YYYY'), to_char(c.create_date, 'MM'), c.user_id, c.state, c.stage_id, c.type_id, c.section_id)""")
report_crm_opportunity_section_type()
class report_crm_opportunity_section_categ_stage(osv.osv):
_name = "report.crm.opportunity.section.categ.stage"
_inherit = "report.crm.case.section.categ.stage"
_description = "Opportunity by Section, Category and Stage"
_auto = False
_columns = {
'categ_id': fields.many2one('crm.case.categ','Category', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.opportunity')]", readonly=True),
'stage_id':fields.many2one('crm.case.stage', 'Stage', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.opportunity')]", readonly=True),
'delay_close': fields.char('Delay Close', size=20, readonly=True),
}
_order = 'stage_id, categ_id'
def init(self, cr):
tools.sql.drop_view_if_exists(cr, "report_crm_opportunity_section_categ_stage")
cr.execute("""
create view report_crm_opportunity_section_categ_stage as (
select
min(c.id) as id,
to_char(c.create_date,'YYYY') as name,
to_char(c.create_date, 'MM') as month,
c.user_id,
c.categ_id,
c.state,
c.stage_id,
c.section_id,
count(*) as nbr,
to_char(avg(date_closed-c.create_date), 'DD"d" HH24:MI:SS') as delay_close
from
crm_opportunity c
where c.categ_id is not null AND c.stage_id is not null
group by to_char(c.create_date, 'YYYY'), to_char(c.create_date, 'MM'),c.user_id, c.categ_id, c.state, c.stage_id, c.section_id)""")
report_crm_opportunity_section_categ_stage()
class report_crm_opportunity_section_categ_type(osv.osv):
_name = "report.crm.opportunity.section.categ.type"
_inherit = "report.crm.case.section.categ.type"
_description = "Opportunity by Section, Category and Type"
_auto = False
_columns = {
'categ_id':fields.many2one('crm.case.categ', 'Category', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.opportunity')]", readonly=True),
'type_id': fields.many2one('crm.case.resource.type', 'Opportunity Type', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.opportunity')]", readonly=True),
'stage_id':fields.many2one('crm.case.stage', 'Stage', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.opportunity')]", readonly=True),
'delay_close': fields.char('Delay Close', size=20, readonly=True),
}
_order = 'categ_id, type_id'
def init(self, cr):
tools.sql.drop_view_if_exists(cr, "report_crm_opportunity_section_categ_type")
cr.execute("""
create view report_crm_opportunity_section_categ_type as (
select
min(c.id) as id,
to_char(c.create_date, 'YYYY') as name,
to_char(c.create_date, 'MM') as month,
c.user_id,
c.categ_id,
c.type_id,
c.state,
c.stage_id,
c.section_id,
count(*) as nbr,
to_char(avg(date_closed-c.create_date), 'DD"d" HH24:MI:SS') as delay_close
from
crm_opportunity c
where c.categ_id is not null AND c.type_id is not null
group by to_char(c.create_date, 'YYYY'), to_char(c.create_date, 'MM'),c.user_id, c.categ_id, c.type_id, c.state, c.stage_id, c.section_id)""")
report_crm_opportunity_section_categ_type()
report_crm_opportunity()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+35 -377
View File
@@ -5,24 +5,29 @@
Opportunities by user and section
-->
<record id="view_crm_opportunity_user_tree" model="ir.ui.view">
<field name="name">report.crm.opportunity.user.tree</field>
<field name="model">report.crm.opportunity.user</field>
<field name="inherit_id" ref="view_crm_case_user_tree"/>
<record id="view_crm_opportunity_tree" model="ir.ui.view">
<field name="name">report.crm.opportunity.tree</field>
<field name="model">report.crm.opportunity</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<field name="nbr" position="after">
<tree string="Opportunities">
<field name="name" />
<field name="month"/>
<field name="nbr" string="#Opportunities"/>
<field name="delay_close"/>
<field name="amount_revenue"/>
<field name="amount_costs"/>
<field name="amount_revenue_prob"/>
<field name="probability"/>
</field>
</field>
<field name="state"/>
<field name="user_id" invisible="1"/>
<field name="stage_id" invisible="1"/>
<field name="categ_id" invisible="1"/>
</tree>
</field>
</record>
<record id="view_crm_opportunity_user_form" model="ir.ui.view">
<field name="name">report.crm.opportunity.user.form</field>
<field name="model">report.crm.opportunity.user</field>
<record id="view_crm_opportunity_form" model="ir.ui.view">
<field name="name">report.crm.opportunity.form</field>
<field name="model">report.crm.opportunity</field>
<field name="inherit_id" ref="view_crm_case_user_form"/>
<field name="type">form</field>
<field name="arch" type="xml">
@@ -36,12 +41,12 @@
</field>
</record>
<record id="view_crm_opportunity_user_graph" model="ir.ui.view">
<field name="name">report.crm.opportunity.user.graph</field>
<field name="model">report.crm.opportunity.user</field>
<record id="view_crm_opportunity_graph" model="ir.ui.view">
<field name="name">report.crm.opportunity.graph</field>
<field name="model">report.crm.opportunity</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph orientation="horizontal" string="Opportunity by User and Section" type="bar">
<graph orientation="horizontal" string="Opportunity" type="bar">
<field name="state"/>
<field name="nbr" operator="+"/>
<field group="True" name="user_id"/>
@@ -49,9 +54,9 @@
</field>
</record>
<record id="view_crm_opportunity_user_filter" model="ir.ui.view">
<field name="name">report.crm.opportunity.user.select</field>
<field name="model">report.crm.opportunity.user</field>
<record id="view_crm_opportunity_filter" model="ir.ui.view">
<field name="name">report.crm.opportunity.select</field>
<field name="model">report.crm.opportunity</field>
<field name="inherit_id" ref="view_crm_case_user_filter"/>
<field name="type">search</field>
<field name="arch" type="xml">
@@ -60,367 +65,20 @@
</field>
</record>
<record id="action_report_crm_opportunity_user_tree" model="ir.actions.act_window">
<field name="name">Opportunity by User and Section</field>
<field name="res_model">report.crm.opportunity.user</field>
<record id="action_report_crm_opportunity_tree" model="ir.actions.act_window">
<field name="name">Opportunity</field>
<field name="res_model">report.crm.opportunity</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree</field>
<field name="view_id" ref="view_crm_opportunity_user_graph"/>
<field name="search_view_id" ref="view_crm_opportunity_user_filter"/>
<field name="view_id" ref="view_crm_opportunity_graph"/>
<!-- field name="search_view_id" ref="view_crm_opportunity_filter"/ -->
</record>
<menuitem name="Opportinities" id="menu_crm_opportunity_tree" parent="crm.next_id_52"/>
<menuitem action="action_report_crm_opportunity_user_tree" id="menu_crm_opportunity_user_tree" parent="menu_crm_opportunity_tree"/>
<!-- # Opportunity by section and category of case -->
<record id="view_crm_opportunity_categ_tree" model="ir.ui.view">
<field name="name">report.crm.opportunity.categ.tree</field>
<field name="model">report.crm.opportunity.categ</field>
<field name="inherit_id" ref="view_crm_case_categ_tree"/>
<field name="type">tree</field>
<field name="arch" type="xml">
<field name="nbr" position="after">
<field name="delay_close"/>
<field name="amount_revenue"/>
<field name="amount_costs"/>
<field name="amount_revenue_prob"/>
<field name="probability"/>
</field>
</field>
</record>
<record id="view_crm_opportunity_categ_form" model="ir.ui.view">
<field name="name">report.crm.opportunity.categ.form</field>
<field name="model">report.crm.opportunity.categ</field>
<field name="inherit_id" ref="view_crm_case_categ_form"/>
<field name="type">form</field>
<field name="arch" type="xml">
<field name="nbr" position="after">
<field name="delay_close"/>
<field name="amount_revenue"/>
<field name="amount_costs"/>
<field name="amount_revenue_prob"/>
<field name="probability"/>
</field>
</field>
</record>
<record id="view_crm_opportunity_categ_graph" model="ir.ui.view">
<field name="name">report.crm.opportunity.categ.graph</field>
<field name="model">report.crm.opportunity.categ</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph orientation="horizontal" string="Opportunity by Section and Categories" type="bar">
<field name="state"/>
<field name="nbr" operator="+"/>
<field group="True" name="categ_id"/>
</graph>
</field>
</record>
<record id="view_crm_opportunity_categ_filter" model="ir.ui.view">
<field name="name">report.crm.opportunity.categ.select</field>
<field name="model">report.crm.opportunity.categ</field>
<field name="inherit_id" ref="view_crm_case_categ_filter"/>
<field name="type">search</field>
<field name="arch" type="xml">
<field name="state" position="before">
</field>
</field>
</record>
<record id="action_report_crm_opportunity_categ_tree" model="ir.actions.act_window">
<field name="name">Opportunity by Categories and Section</field>
<field name="res_model">report.crm.opportunity.categ</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree</field>
<field name="view_id" ref="view_crm_opportunity_categ_graph"/>
<field name="search_view_id" ref="view_crm_opportunity_categ_filter"/>
</record>
<menuitem action="action_report_crm_opportunity_categ_tree" id="menu_crm_opportunity_categ_tree" parent="menu_crm_opportunity_tree"/>
<!-- Opportunity by Section -->
<record id="view_report_crm_opportunity_section_tree" model="ir.ui.view">
<field name="name">report.crm.opportunity.section.tree</field>
<field name="model">report.crm.opportunity.section</field>
<field name="inherit_id" ref="view_report_crm_case_section_tree"/>
<field name="type">tree</field>
<field name="arch" type="xml">
<field name="nbr_cases" position="after">
<field name="avg_answers"/>
<field name="perc_done" select="2"/>
<field name="perc_cancel" select="2"/>
<field name="delay_close"/>
</field>
</field>
</record>
<record id="view_report_crm_opportunity_section_graph" model="ir.ui.view">
<field name="name">report.crm.opportunity.section.graph</field>
<field name="model">report.crm.opportunity.section</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph orientation="horizontal" string="Opportunity by Section" type="bar">
<field name="name"/>
<field name="nbr_cases" operator="+"/>
</graph>
</field>
</record>
<record id="view_report_crm_opportunity_section_filter" model="ir.ui.view">
<field name="name">report.crm.opportunity.section.select</field>
<field name="model">report.crm.opportunity.section</field>
<field name="inherit_id" ref="view_report_crm_case_section_filter"/>
<field name="type">search</field>
<field name="arch" type="xml">
<field name="nbr_cases" position="before">
</field>
</field>
</record>
<record id="action_report_crm_opportunity_section_tree" model="ir.actions.act_window">
<field name="name">Opportunity by Section</field>
<field name="res_model">report.crm.opportunity.section</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree</field>
<field name="view_id" ref="view_report_crm_opportunity_section_graph"/>
<field name="search_view_id" ref="view_report_crm_opportunity_section_filter"/>
</record>
<menuitem action="action_report_crm_opportunity_section_tree" id="menu_crm_opportunity_section_tree" parent="menu_crm_opportunity_tree"/>
#
# Opportunity by section and type
#
<record model="ir.ui.view" id="view_crm_opportunity_section_categ_tree">
<field name="name">CRM Report - Sections and Type(Tree)</field>
<field name="model">report.crm.opportunity.section.type</field>
<field name="inherit_id" ref="view_crm_case_section_categ_tree"/>
<field name="type">tree</field>
<field name="arch" type="xml">
<field name="user_id" position="after">
<field name="type_id"/>
<field name="stage_id"/>
<field name="amount_revenue"/>
<field name="delay_close"/>
</field>
</field>
</record>
<record model="ir.ui.view" id="view_crm_opportunity_section_categ_form">
<field name="name">CRM Report - Sections and Type(Form)</field>
<field name="model">report.crm.opportunity.section.type</field>
<field name="inherit_id" ref="view_crm_case_section_categ_form"/>
<field name="type">form</field>
<field name="arch" type="xml">
<field name="user_id" position="after">
<field name="type_id"/>
<field name="stage_id"/>
<field name="amount_revenue"/>
<field name="delay_close"/>
</field>
</field>
</record>
<record model="ir.ui.view" id="view_crm_opportunity_section_categ_graph">
<field name="name">CRM Report - Sections and Type(Graph)</field>
<field name="model">report.crm.opportunity.section.type</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Opportunity by Section and Type" type="bar" orientation="horizontal">
<field name="type_id"/>
<field name="amount_revenue" operator="+"/>
<field name="section_id" group="True"/>
</graph>
</field>
</record>
<record id="view_crm_opportunity_section_categ_filter" model="ir.ui.view">
<field name="name">CRM Report - Sections and Type(Select)</field>
<field name="model">report.crm.opportunity.section.type</field>
<field name="inherit_id" ref="view_crm_case_section_categ_filter"/>
<field name="type">search</field>
<field name="arch" type="xml">
<field name="section_id" position="after">
<field name="type_id"/>
</field>
</field>
</record>
<record model="ir.actions.act_window" id="action_report_crm_opportunity_section_categ_tree">
<field name="res_model">report.crm.opportunity.section.type</field>
<field name="name">Opportunity by section and type</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree</field>
<field name="search_view_id" ref="view_crm_opportunity_section_categ_filter"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_opportunity_section_categ_graph">
<field name="sequence" eval="1"/>
<field name="view_mode">graph</field>
<field name="view_id" ref="view_crm_opportunity_section_categ_graph"/>
<field name="act_window_id" ref="action_report_crm_opportunity_section_categ_tree"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_opportunity_section_categ_tree">
<field name="sequence" eval="2"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_crm_opportunity_section_categ_tree"/>
<field name="act_window_id" ref="action_report_crm_opportunity_section_categ_tree"/>
</record>
<menuitem action="action_report_crm_opportunity_section_categ_tree" id="menu_crm_opportunity_section_categ_tree" parent="menu_crm_opportunity_tree"/>
#
# Opportunity by section, category and stage
#
<record model="ir.ui.view" id="view_crm_opportunity_section_categ_stage_tree">
<field name="name">CRM Report - Section, Category and Stage(Tree)</field>
<field name="model">report.crm.opportunity.section.categ.stage</field>
<field name="inherit_id" ref="view_crm_case_section_categ_stage_tree"/>
<field name="type">tree</field>
<field name="arch" type="xml">
<field name="user_id" position="after">
<field name="categ_id"/>
<field name="stage_id"/>
<field name="delay_close"/>
</field>
</field>
</record>
<record model="ir.ui.view" id="view_crm_opportunity_section_categ_stage_form">
<field name="name">CRM Report - Section, Category and Stage(Form)</field>
<field name="model">report.crm.opportunity.section.categ.stage</field>
<field name="inherit_id" ref="view_crm_case_section_categ_stage_form"/>
<field name="type">form</field>
<field name="arch" type="xml">
<field name="user_id" position="after">
<field name="categ_id"/>
<field name="stage_id"/>
<field name="delay_close"/>
</field>
</field>
</record>
<record model="ir.ui.view" id="view_crm_opportunity_section_categ_stage_graph">
<field name="name">CRM Report - Section, Category and Stage(Select)</field>
<field name="model">report.crm.opportunity.section.categ.stage</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Opportunity by Section, Category and Stage" type="bar" orientation="horizontal">
<field name="categ_id"/>
<field name="nbr" operator="+"/>
<field name="section_id" group="True"/>
</graph>
</field>
</record>
<record id="view_crm_opportunity_section_categ_stage_filter" model="ir.ui.view">
<field name="name">CRM Report - Section, Category and Stage(Select)</field>
<field name="model">report.crm.opportunity.section.categ.stage</field>
<field name="inherit_id" ref="view_crm_case_section_categ_filter"/>
<field name="type">search</field>
<field name="arch" type="xml">
<field name="section_id" position="after">
<field name="categ_id"/>
<field name="stage_id"/>
</field>
</field>
</record>
<record model="ir.actions.act_window" id="action_report_crm_opportunity_section_categ_stage_tree">
<field name="res_model">report.crm.opportunity.section.categ.stage</field>
<field name="name">Opportunity by section, category and stage</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree</field>
<field name="search_view_id" ref="view_crm_opportunity_section_categ_stage_filter"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_opportunity_section_categ_stage_graph">
<field name="sequence" eval="1"/>
<field name="view_mode">graph</field>
<field name="view_id" ref="view_crm_opportunity_section_categ_stage_graph"/>
<field name="act_window_id" ref="action_report_crm_opportunity_section_categ_stage_tree"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_opportunity_section_categ_stage_tree">
<field name="sequence" eval="2"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_crm_opportunity_section_categ_stage_tree"/>
<field name="act_window_id" ref="action_report_crm_opportunity_section_categ_stage_tree"/>
</record>
<menuitem action="action_report_crm_opportunity_section_categ_stage_tree" id="menu_crm_opportunity_section_categ_stage_tree" parent="menu_crm_opportunity_tree"/>
#
# opportunitys by section, category and type
#
<record model="ir.ui.view" id="view_crm_opportunity_section_categ_type_tree">
<field name="name">CRM Report - Section, Category and Type(Tree)</field>
<field name="model">report.crm.opportunity.section.categ.type</field>
<field name="inherit_id" ref="view_crm_case_section_categ_type_tree"/>
<field name="type">tree</field>
<field name="arch" type="xml">
<field name="user_id" position="after">
<field name="categ_id"/>
<field name="type_id"/>
<field name="stage_id"/>
<field name="delay_close"/>
</field>
</field>
</record>
<record model="ir.ui.view" id="view_crm_opportunity_section_categ_type_form">
<field name="name">CRM Report - Section, Category and Type(Form)</field>
<field name="model">report.crm.opportunity.section.categ.type</field>
<field name="inherit_id" ref="view_crm_case_section_categ_type_form"/>
<field name="type">form</field>
<field name="arch" type="xml">
<field name="user_id" position="after">
<field name="categ_id"/>
<field name="type_id"/>
<field name="stage_id"/>
<field name="delay_close"/>
</field>
</field>
</record>
<record model="ir.ui.view" id="view_crm_opportunity_section_categ_type_graph">
<field name="name">CRM Report - Section, Category and Type(Select)</field>
<field name="model">report.crm.opportunity.section.categ.type</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Opportunity by Section, Category and Type" type="bar" orientation="horizontal">
<field name="type_id"/>
<field name="nbr" operator="+"/>
<field name="section_id" group="True"/>
</graph>
</field>
</record>
<record id="view_crm_opportunity_section_categ_type_filter" model="ir.ui.view">
<field name="name">CRM Report - Section, Category and Type(Select)</field>
<field name="model">report.crm.opportunity.section.categ.type</field>
<field name="inherit_id" ref="view_crm_case_section_categ_type_filter"/>
<field name="type">search</field>
<field name="arch" type="xml">
<field name="section_id" position="after">
<field name="categ_id" select="1"/>
<field name="type_id" select="1"/>
<field name="stage_id" select="1"/>
</field>
</field>
</record>
<record model="ir.actions.act_window" id="action_report_crm_opportunity_section_categ_type_tree">
<field name="res_model">report.crm.opportunity.section.categ.type</field>
<field name="name">Opportunity by section, category and type</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree</field>
<field name="search_view_id" ref="view_crm_opportunity_section_categ_type_filter"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_opportunity_section_categ_type_graph">
<field name="sequence" eval="1"/>
<field name="view_mode">graph</field>
<field name="view_id" ref="view_crm_opportunity_section_categ_type_graph"/>
<field name="act_window_id" ref="action_report_crm_opportunity_section_categ_type_tree"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_opportunity_section_categ_type_tree">
<field name="sequence" eval="2"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_crm_opportunity_section_categ_type_tree"/>
<field name="act_window_id" ref="action_report_crm_opportunity_section_categ_type_tree"/>
</record>
<menuitem action="action_report_crm_opportunity_section_categ_type_tree" id="menu_crm_opportunity_section_categ_type_tree" parent="menu_crm_opportunity_tree"/>
<record model="ir.actions.act_window.view" id="action_report_crm_l_opportunity_tree1">
<field name="sequence" eval="2"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_crm_opportunity_tree"/>
<field name="act_window_id" ref="action_report_crm_opportunity_tree"/>
</record>
<menuitem name="Opportinities" action="action_report_crm_opportunity_tree" id="menu_crm_opportunity_tree" parent="crm.next_id_52"/>
</data>
</openerp>
+13 -1
View File
@@ -56,11 +56,13 @@
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Search Cases by User">
<group col="12" colspan="4">
<group col="16" colspan="8">
<filter string="My Cases" icon="terp-hr" domain="[('user_id','=',uid)]" help="My cases by section"/>
<separator orientation="vertical"/>
<filter string="This Year" icon="terp-hr" domain="[('name','=',time.localtime()[0])]"/>
<filter string="This Month" icon="terp-hr" domain="[('month','=',time.strftime('%%m'))]"/>
<filter string="Won" icon="terp-hr" domain="[('state','=','done')]"/>
<filter string="Lost" icon="terp-hr" domain="[('state','=','cancel')]"/>
<separator orientation="vertical"/>
<field name="name" select="1"/>
<field name="month" select="1"/>
@@ -69,6 +71,16 @@
<field name="nbr" select="1"/>
<field name="state" select="1"/>
</group>
<group expand="1" string="Group By..." colspan="4" col="8">
<filter string="User" icon="terp-sale" domain="[]" context="{'group_by':'user_id'}"/>
<filter string="Section" icon="terp-sale" domain="[]" context="{'group_by':'section_id'}"/>
<filter string="State" icon="terp-sale" domain="[]" context="{'group_by':'state'}"/>
<filter string="Stage" icon="terp-sale" domain="[]" context="{'group_by':'stage_id'}"/>
<filter string="Month" icon="terp-sale" domain="[]" context="{'group_by':'month'}"/>
<filter string="Category" icon="terp-sale" domain="[]" context="{'group_by':'categ_id'}"/>
</group>
</search>
</field>
</record>
+7 -7
View File
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
#
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
@@ -15,7 +15,7 @@
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
@@ -29,7 +29,7 @@
"description": """
Module for resource management. You can manage:
* Leave/Holidays or Days off of the company
""",
'author': 'Tiny',
'website': 'http://www.openerp.com',
@@ -37,11 +37,11 @@
'init_xml': [],
'update_xml': [
#'security/resource_security.xml',
# 'security/ir.model.access.csv',
'resource_view.xml',
# 'security/ir.model.access.csv',
'resource_view.xml',
],
'demo_xml': ['resource_demo.xml'
],
'demo_xml': [#'resource_demo.xml'
],
'installable': True,
'active': False,
'certificate': None,
+22 -23
View File
@@ -37,16 +37,16 @@ class resource_calendar(osv.osv):
'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'resource.calendar', c)
}
def interval_min_get(self, cr, uid, id, dt_from, hours,resource=False):
def interval_min_get(self, cr, uid, id, dt_from, hours, resource=False):
resource_cal_leaves = self.pool.get('resource.calendar.leaves')
dt_leave = []
if not id:
return [(dt_from-mx.DateTime.RelativeDateTime(hours=int(hours)*3), dt_from)]
resource_leave_ids = resource_cal_leaves.search(cr,uid,[('calendar_id','=',id),'|',('resource_id','=',False),('resource_id','=',resource)])
res_leaves = resource_cal_leaves.read(cr,uid,resource_leave_ids,['date_from','date_to'])
return [(dt_from - mx.DateTime.RelativeDateTime(hours=int(hours)*3), dt_from)]
resource_leave_ids = resource_cal_leaves.search(cr, uid, [('calendar_id','=',id), '|', ('resource_id','=',False), ('resource_id','=',resource)])
res_leaves = resource_cal_leaves.read(cr, uid, resource_leave_ids, ['date_from', 'date_to'])
for leave in res_leaves:
dtf = mx.DateTime.strptime(leave['date_from'],'%Y-%m-%d %H:%M:%S')
dtt = mx.DateTime.strptime(leave['date_to'],'%Y-%m-%d %H:%M:%S')
dtf = mx.DateTime.strptime(leave['date_from'], '%Y-%m-%d %H:%M:%S')
dtt = mx.DateTime.strptime(leave['date_to'], '%Y-%m-%d %H:%M:%S')
no = dtt - dtf
[dt_leave.append((dtf + mx.DateTime.RelativeDateTime(days=x)).strftime('%Y-%m-%d')) for x in range(int(no.days + 1))]
dt_leave.sort()
@@ -72,8 +72,8 @@ class resource_calendar(osv.osv):
if leave_flag:
break
else:
d1 = mx.DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(hour_from)),int((hour_from%1) * 60))
d2 = mx.DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(m)),int((m%1) * 60))
d1 = mx.DateTime.DateTime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(hour_from)), int((hour_from%1) * 60))
d2 = mx.DateTime.DateTime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(m)), int((m%1) * 60))
result.append((d1, d2))
current_hour = hour_from
todo -= (m-hour_from)
@@ -87,16 +87,15 @@ class resource_calendar(osv.osv):
resource_cal_leaves = self.pool.get('resource.calendar.leaves')
dt_leave = []
if not id:
return [(dt_from,dt_from+mx.DateTime.RelativeDateTime(hours=int(hours)*3))]
resource_leave_ids = resource_cal_leaves.search(cr,uid,[('calendar_id','=',id),'|',('resource_id','=',False),('resource_id','=',resource)])
res_leaves = resource_cal_leaves.read(cr,uid,resource_leave_ids,['date_from','date_to'])
return [(dt_from,dt_from + mx.DateTime.RelativeDateTime(hours=int(hours)*3))]
resource_leave_ids = resource_cal_leaves.search(cr, uid, [('calendar_id','=',id), '|', ('resource_id','=',False), ('resource_id','=',resource)])
res_leaves = resource_cal_leaves.read(cr, uid, resource_leave_ids, ['date_from', 'date_to'])
for leave in res_leaves:
dtf = mx.DateTime.strptime(leave['date_from'],'%Y-%m-%d %H:%M:%S')
dtt = mx.DateTime.strptime(leave['date_to'],'%Y-%m-%d %H:%M:%S')
dtf = mx.DateTime.strptime(leave['date_from'], '%Y-%m-%d %H:%M:%S')
dtt = mx.DateTime.strptime(leave['date_to'], '%Y-%m-%d %H:%M:%S')
no = dtt - dtf
[dt_leave.append((dtf + mx.DateTime.RelativeDateTime(days=x)).strftime('%Y-%m-%d')) for x in range(int(no.days + 1))]
dt_leave.sort()
print 'dtLevae',dt_leave
todo = hours
cycle = 0
result = []
@@ -113,13 +112,13 @@ class resource_calendar(osv.osv):
dt_check = dt_from.strftime('%Y-%m-%d')
for leave in dt_leave:
if dt_check == leave:
dt_check = mx.DateTime.strptime(dt_check,"%Y-%m-%d") + mx.DateTime.RelativeDateTime(days=1)
dt_check = mx.DateTime.strptime(dt_check, "%Y-%m-%d") + mx.DateTime.RelativeDateTime(days=1)
leave_flag = True
if leave_flag:
break
else:
d1 = mx.DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(m)),int((m%1) * 60))
d2 = mx.DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(hour_to)),int((hour_to%1) * 60))
d1 = mx.DateTime.DateTime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(m)), int((m%1) * 60))
d2 = mx.DateTime.DateTime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(hour_to)), int((hour_to%1) * 60))
result.append((d1, d2))
current_hour = hour_to
todo -= (hour_to - m)
@@ -170,11 +169,11 @@ class resource_resource(osv.osv):
if context.get('project_id',False):
project_pool = self.pool.get('project.project')
project_rec = project_pool.browse(cr,uid,context['project_id'])
project_rec = project_pool.browse(cr, uid, context['project_id'])
user_ids = [user_id.id for user_id in project_rec.members]
args.append(('user_id','in',user_ids))
return super(resource_resource, self).search(cr, uid, args, offset, limit,order, context, count)
return super(resource_resource, self).search(cr, uid, args, offset, limit, order, context, count)
resource_resource()
class resource_calendar_leaves(osv.osv):
@@ -189,7 +188,7 @@ class resource_calendar_leaves(osv.osv):
'resource_id' : fields.many2one("resource.resource", "Resource", help="If empty, this is a generic holiday for the company. If a resource is set, the holiday/leave is only for this resource"),
}
def check_dates(self, cr, uid, ids):
leave = self.read(cr, uid, ids[0],['date_from','date_to'])
leave = self.read(cr, uid, ids[0], ['date_from', 'date_to'])
if leave['date_from'] and leave['date_to']:
if leave['date_from'] > leave['date_to']:
return False
@@ -203,9 +202,9 @@ class resource_calendar_leaves(osv.osv):
result = {}
if resource:
resource_pool = self.pool.get('resource.resource')
result['calendar_id'] = resource_pool.browse(cr,uid,resource).calendar_id.id
return {'value':result}
return {'value':{'calendar_id':[]}}
result['calendar_id'] = resource_pool.browse(cr, uid, resource).calendar_id.id
return {'value': result}
return {'value': {'calendar_id': []}}
resource_calendar_leaves()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+83
View File
@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- Example employee -->
<record id="timesheet_group1" model="resource.calendar">
<field name="name">38 Hours/Week</field>
</record>
<record model="resource.calendar.week">
<field name="name">Monday morning</field>
<field name="dayofweek">0</field>
<field name="hour_from">08</field>
<field name="hour_to">12</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record model="resource.calendar.week">
<field name="name">Monday evening</field>
<field name="dayofweek">0</field>
<field name="hour_from">13</field>
<field name="hour_to">18</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record model="resource.calendar.week">
<field name="name">Tuesday morning</field>
<field name="dayofweek">1</field>
<field name="hour_from">08</field>
<field name="hour_to">12</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record model="resource.calendar.week">
<field name="name">Tuesday evening</field>
<field name="dayofweek">1</field>
<field name="hour_from">13</field>
<field name="hour_to">18</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record model="resource.calendar.week">
<field name="name">Wednesday morning</field>
<field name="dayofweek">2</field>
<field name="hour_from">08</field>
<field name="hour_to">12</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record model="resource.calendar.week">
<field name="name">Wednesday evening</field>
<field name="dayofweek">2</field>
<field name="hour_from">13</field>
<field name="hour_to">18</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record model="resource.calendar.week">
<field name="name">Thursday morning</field>
<field name="dayofweek">3</field>
<field name="hour_from">08</field>
<field name="hour_to">12</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record model="resource.calendar.week">
<field name="name">Thursday evening</field>
<field name="hour_from">13</field>
<field name="hour_to">18</field>
<field name="dayofweek">3</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record model="resource.calendar.week">
<field name="name">Friday morning</field>
<field name="dayofweek">4</field>
<field name="hour_from">08</field>
<field name="hour_to">12</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record model="resource.calendar.week">
<field name="name">Friday evening</field>
<field name="dayofweek">4</field>
<field name="hour_from">13</field>
<field name="hour_to">18</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
</data>
</openerp>
+1 -14
View File
@@ -120,8 +120,7 @@
<field name="view_mode">tree,form</field>
</record>
<menuitem id="base.menu_pm_planning" name="Planning" parent="base.menu_main" sequence="3"/>
<menuitem action="action_resource_resource_tree" id="base.menu_resource_resource_tree" parent="base.menu_pm_planning" />
<menuitem action="action_resource_resource_tree" id="base.menu_resource_resource_tree" parent="base.menu_pm_resources" />
<record id="resource_calendar_leave_form" model="ir.ui.view">
<field name="name">resource.calendar.leaves.form</field>
@@ -161,17 +160,5 @@
<menuitem action="action_resource_calendar_leave_tree" id="menu_resource_calendar_leave_tree" parent="base.menu_pm_resources"/>
<!-- project member -->
<record id="view_project_member_tree" model="ir.ui.view">
<field name="name">project.member.tree</field>
<field name="model">resource.resource</field>
<field name="type">tree</field>
<field eval="99" name="priority"/>
<field name="arch" type="xml">
<tree string="Project's Members">
<field name="name"/>
</tree>
</field>
</record>
</data>
</openerp>