[IMP] Stage/State update part 2

- stages: added some fields
-- closed: indicates whether this stage close the working process, for
example task ended, lead lost, applicant hired
-- bar_fold: whether to hide the state in the statusbar; this is different
from fold that is used for kanban views. Viewing a pipe or a specific
record are effectively different things and should use different fields.
-- bar_color: field to customize the stage in the statusbar (still WIP)

- impacted addons: crm, project, project_issue, hr_recruitment
- removed 'closed' addition in project_mrp as this is now in base project
module

bzr revid: tde@openerp.com-20131018132120-h0pv01q2bagtp99x
This commit is contained in:
Thibault Delavallée 2013-10-18 15:21:20 +02:00
parent f0c49f88d0
commit 6c54232c98
13 changed files with 93 additions and 48 deletions

View File

@ -68,8 +68,17 @@ class crm_case_stage(osv.osv):
help="Link between stages and sales teams. When set, this limitate the current stage to the selected sales teams."),
'case_default': fields.boolean('Default to New Sales Team',
help="If you check this field, this stage will be proposed by default on each sales team. It will not assign this stage to existing teams."),
'fold': fields.boolean('Fold by Default',
help="This stage is not visible, for example in status bar or kanban view, when there are no records in that stage to display."),
'fold': fields.boolean('Folded in Kanban View',
help='This stage is folded in the kanban view when'
'there are no records in that stage to display.'),
'bar_fold': fields.boolean('Folded in Status Bar',
help='This stage is folded in the form view when'
'using the statusbar widget.'),
'bar_color': fields.integer('Status Bar Color'),
'closed': fields.boolean('Closing Stage',
help='Indicates whether this field is the end of'
'the maangement process. This is for example a'
'stage considering the lead as won or lost.'),
'type': fields.selection([('lead', 'Lead'),
('opportunity', 'Opportunity'),
('both', 'Both')],

View File

@ -18,6 +18,7 @@
<field name="on_change">1</field>
<field name="sequence">30</field>
<field name="type">lead</field>
<field name="closed" eval="True"/>
</record>
<record model="crm.case.stage" id="stage_lead3">
<field name="name">Qualification</field>
@ -48,6 +49,7 @@
<field name="on_change">1</field>
<field name="sequence">70</field>
<field name="type">opportunity</field>
<field name="closed" eval="True"/>
</record>
<record model="crm.case.stage" id="stage_lead7">
<field name="name">Lost</field>
@ -57,6 +59,7 @@
<field name="on_change">1</field>
<field name="sequence">80</field>
<field name="type">opportunity</field>
<field name="closed" eval="True"/>
</record>
<record model="crm.case.section" id="section_sales_department">

View File

@ -379,10 +379,6 @@
<field name="arch" type="xml">
<form string="Opportunities" version="7.0">
<header>
<button name="case_mark_won" string="Mark Won" type="object" class="oe_highlight"
attrs="{'invisible': [('probability', '=', 100)]}"/>
<button name="case_mark_lost" string="Mark Lost" type="object" class="oe_highlight"
attrs="{'invisible': ['|', ('probability', '=', 0), ('probability', '=', 100)]}"/>
<field name="stage_id" widget="statusbar" clickable="True"
domain="['&amp;', ('section_ids', '=', section_id), '|', ('type', '=', type), ('type', '=', 'both')]"/>
</header>

View File

@ -93,14 +93,23 @@
<field name="priority" eval="1"/>
<field name="arch" type="xml">
<form string="Stage" version="7.0">
<group col="4">
<field name="name"/>
<field name="probability"/>
<field name="type"/>
<field name="on_change"/>
<field name="sequence"/>
<field name="case_default" groups="base.group_multi_salesteams"/>
<field name="fold"/>
<group>
<group>
<field name="name"/>
<field name="sequence"/>
<field name="type"/>
<field name="probability"/>
<field name="closed"/>
<field name="case_default"/>
</group>
<group>
<field name="fold"/>
<field name="bar_fold"/>
<field name="bar_color"/>
<field name="on_change"/>
<field name="case_default" groups="base.group_multi_salesteams"/>
</group>
</group>
<separator string="Requirements"/>
<field name="requirements" nolabel="1"/>

View File

@ -52,12 +52,21 @@ class hr_recruitment_stage(osv.osv):
'name': fields.char('Name', size=64, required=True, translate=True),
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of stages."),
'department_id':fields.many2one('hr.department', 'Specific to a Department', help="Stages of the recruitment process may be different per department. If this stage is common to all departments, keep this field empty."),
'fold': fields.boolean('Hide in views if empty', help="This stage is not visible, for example in status bar or kanban view, when there are no records in that stage to display."),
'requirements': fields.text('Requirements'),
'fold': fields.boolean('Folded in Kanban View',
help='This stage is folded in the kanban view when'
'there are no records in that stage to display.'),
'bar_fold': fields.boolean('Folded in Status Bar',
help='This stage is folded in the form view when'
'using the statusbar widget.'),
'bar_color': fields.integer('Status Bar Color'),
'closed': fields.boolean('Closing Stage',
help='Indicates whether this field is the end of'
'the maangement process. This is for example a'
'stage considering the applicant as hired or refused.'),
}
_defaults = {
'sequence': 1,
'fold': False,
}
class hr_recruitment_degree(osv.osv):
@ -225,7 +234,7 @@ class hr_applicant(osv.Model):
'department_id': lambda s, cr, uid, c: s._get_default_department_id(cr, uid, c),
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'hr.applicant', context=c),
'color': 0,
'date_last_stage_update': fields.datetime.now(),
'date_last_stage_update': fields.datetime.now,
}
_group_by_full = {

View File

@ -71,12 +71,15 @@
<record model="hr.recruitment.stage" id="stage_job5">
<field name="name">Contract Signed</field>
<field name="sequence">5</field>
<field name="closed" eval="True"/>
</record>
<record model="hr.recruitment.stage" id="stage_job6">
<field name="name">Refused</field>
<field name="sequence">6</field>
<field name="fold" eval="True"/>
<field name="closed" eval="True"/>
</record>
<record id="survey_job_0" model="survey">
<field name="title">Job Survey</field>
<field name="max_response_limit">20</field>

View File

@ -342,6 +342,8 @@
<field name="sequence" invisible="1"/>
<field name="name"/>
<field name="department_id"/>
<field name="fold"/>
<field name="bar_fold"/>
</tree>
</field>
</record>
@ -357,10 +359,13 @@
<group>
<field name="name"/>
<field name="department_id"/>
<field name="sequence"/>
<field name="closed"/>
</group>
<group>
<field name="sequence"/>
<field name="fold"/>
<field name="bar_fold"/>
<field name="bar_color"/>
</group>
</group>
<separator string="Requirements"/>

View File

@ -41,14 +41,21 @@ class project_task_type(osv.osv):
'case_default': fields.boolean('Default for New Projects',
help="If you check this field, this stage will be proposed by default on each new project. It will not assign this stage to existing projects."),
'project_ids': fields.many2many('project.project', 'project_task_type_rel', 'type_id', 'project_id', 'Projects'),
'fold': fields.boolean('Folded by Default',
help="This stage is not visible, for example in status bar or kanban view, when there are no records in that stage to display."),
'fold': fields.boolean('Folded in Kanban View',
help='This stage is folded in the kanban view when'
'there are no records in that stage to display.'),
'bar_fold': fields.boolean('Folded in Status Bar',
help='This stage is folded in the form view when'
'using the statusbar widget.'),
'bar_color': fields.integer('Status Bar Color'),
'closed': fields.boolean('Closing Stage',
help='Indicates whether this field is the end of'
'the maangement process. This is for example a'
'stage considering the record as done or canceled.'),
}
_defaults = {
'sequence': 1,
'fold': False,
'case_default': False,
'project_ids': lambda self, cr, uid, ctx=None: self.pool['project.task']._get_default_project_id(cr, uid, context=ctx),
}
_order = 'sequence'
@ -189,6 +196,8 @@ class project(osv.osv):
return res
def _task_count(self, cr, uid, ids, field_name, arg, context=None):
""" :deprecated: this method will be removed with OpenERP v8. Use task_ids
fields instead. """
if context is None:
context = {}
res = dict.fromkeys(ids, 0)
@ -263,7 +272,10 @@ class project(osv.osv):
}),
'resource_calendar_id': fields.many2one('resource.calendar', 'Working Time', help="Timetable working hours to adjust the gantt diagram report", states={'close':[('readonly',True)]} ),
'type_ids': fields.many2many('project.task.type', 'project_task_type_rel', 'project_id', 'type_id', 'Tasks Stages', states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}),
'task_count': fields.function(_task_count, type='integer', string="Open Tasks"),
'task_count': fields.function(_task_count, type='integer', string="Open Tasks",
deprecated="This field will be removed in OpenERP v8. Use task_ids one2many field instead."),
'task_ids': fields.one2many('project.task', 'project_id',
domain=[('stage_id.closed', '=', False)]),
'color': fields.integer('Color Index'),
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="restrict", required=True,
help="Internal email associated with this project. Incoming emails are automatically synchronized"
@ -804,7 +816,7 @@ class task(osv.osv):
_defaults = {
'stage_id': _get_default_stage_id,
'project_id': _get_default_project_id,
'date_last_stage_update': lambda *a: fields.datetime.now(),
'date_last_stage_update': fields.datetime.now,
'kanban_state': 'normal',
'priority': '2',
'progress': 0,

View File

@ -63,12 +63,15 @@
<field name="name">Done</field>
<field name="case_default" eval="True"/>
<field name="fold" eval="True"/>
<field name="closed" eval="True"/>
</record>
<record id="project_tt_cancel" model="project.task.type">
<field name="sequence">30</field>
<field name="name">Cancelled</field>
<field name="case_default" eval="True"/>
<field name="fold" eval="True"/>
<field name="bar_fold" eval="True"/>
<field name="closed" eval="True"/>
</record>
<!-- Task-related subtypes for messaging / Chatter -->

View File

@ -240,6 +240,7 @@
<field name="date"/>
<field name="color"/>
<field name="task_count"/>
<field name="task_ids"/>
<field name="alias_id"/>
<field name="doc_count"/>
<templates>
@ -259,9 +260,10 @@
<span class="oe_e oe_e_alias">%%</span><small><field name="alias_id"/></small>
</div>
<div class="oe_kanban_project_list">
<a t-if="record.use_tasks.raw_value" name="%(act_project_project_2_project_task_all)d" type="action" style="margin-right: 10px">
<span t-if="record.task_count.raw_value gt 1"><field name="task_count"/> Tasks</span>
<span t-if="record.task_count.raw_value lt 2"><field name="task_count"/> Task</span>
<a t-if="record.use_tasks.raw_value" name="%(act_project_project_2_project_task_all)d" type="action" style="margin-right: 10px">
<t t-raw="record.task_ids.raw_value.length"/>
<span t-if="record.task_ids.raw_value.length == 1">Task</span>
<span t-if="record.task_ids.raw_value.length > 1">Tasks</span>
</a>
</div>
<div class="oe_kanban_project_list">
@ -684,11 +686,14 @@
<group>
<group>
<field name="name"/>
<field name="sequence"/>
<field name="closed"/>
<field name="case_default"/>
</group>
<group>
<field name="sequence"/>
<field name="fold"/>
<field name="bar_fold"/>
<field name="bar_color"/>
</group>
</group>
<field name="description" placeholder="Add a description..."/>
@ -704,6 +709,7 @@
<field name="sequence" widget="handle"/>
<field name="name"/>
<field name="fold"/>
<field name="bar_fold"/>
</tree>
</field>
</record>

View File

@ -570,6 +570,8 @@ class project(osv.Model):
return [('project.task', "Tasks"), ("project.issue", "Issues")]
def _issue_count(self, cr, uid, ids, field_name, arg, context=None):
""" :deprecated: this method will be removed with OpenERP v8. Use issue_ids
fields instead. """
res = dict.fromkeys(ids, 0)
issue_ids = self.pool.get('project.issue').search(cr, uid, [('project_id', 'in', ids)])
for issue in self.pool.get('project.issue').browse(cr, uid, issue_ids, context):
@ -581,7 +583,10 @@ class project(osv.Model):
'project_escalation_id': fields.many2one('project.project', 'Project Escalation',
help='If any issue is escalated from the current Project, it will be listed under the project selected here.',
states={'close': [('readonly', True)], 'cancelled': [('readonly', True)]}),
'issue_count': fields.function(_issue_count, type='integer', string="Unclosed Issues"),
'issue_count': fields.function(_issue_count, type='integer', string="Unclosed Issues",
deprecated="This field will be removed in OpenERP v8. Use issue_ids one2many field instead."),
'issue_ids': fields.one2many('project.issue', 'project_id',
domain=[('stage_id.closed', '=', False)])
}
def _check_escalation(self, cr, uid, ids, context=None):

View File

@ -325,13 +325,14 @@
<field name="arch" type="xml">
<field name="use_tasks" position="after">
<field name="use_issues"/>
<field name="issue_count" invisible="1"/>
<field name="issue_ids" invisible="1"/>
</field>
<xpath expr="//div[contains(@class, 'oe_kanban_project_list')]" position="inside">
<a t-if="record.use_issues.raw_value" style="margin-right: 10px"
name="%(act_project_project_2_project_issue_all)d" type="action">
<span t-if="record.issue_count.raw_value gt 1"><field name="issue_count"/> Issues</span>
<span t-if="record.issue_count.raw_value lt 2"><field name="issue_count"/> Issue</span>
<t t-raw="record.issue_ids.raw_value.length"/>
<span t-if="record.issue_ids.raw_value.length == 1">Issue</span>
<span t-if="record.issue_ids.raw_value.length > 1">Issues</span>
</a>
</xpath>
</field>

View File

@ -23,22 +23,6 @@ from openerp.osv import fields, osv
from openerp import netsvc
class ProjectTaskStageMrp(osv.Model):
""" Override project.task.type model to add a 'closed' boolean field allowing
to know that tasks in this stage are considered as closed. Indeed since
OpenERP 8.0 status is not present on tasks anymore, only stage_id. """
_name = 'project.task.type'
_inherit = 'project.task.type'
_columns = {
'closed': fields.boolean('Close', help="Tasks in this stage are considered as closed."),
}
_defaults = {
'closed': False,
}
class project_task(osv.osv):
_name = "project.task"
_inherit = "project.task"