[IMP] alias and sales teams

bzr revid: chm@openerp.com-20130321100844-5hcdg90900lzt7gs
This commit is contained in:
Christophe Matthieu 2013-03-21 11:08:44 +01:00
commit 8f2961d6f6
39 changed files with 742 additions and 269 deletions

View File

@ -81,6 +81,8 @@ Dashboard for CRM will include:
'crm_lead_view.xml',
'crm_lead_menu.xml',
'crm_salesteams.xml',
'crm_meeting_menu.xml',
'crm_phonecall_view.xml',
@ -114,6 +116,8 @@ Dashboard for CRM will include:
'test/ui/duplicate_lead.yml',
'test/ui/delete_lead.yml',
],
'css': ['static/src/css/crm.css'],
'js': ['static/src/js/crm.js'],
'installable': True,
'application': True,
'auto_install': False,

View File

@ -109,6 +109,19 @@ class crm_case_section(osv.osv):
def get_full_name(self, cr, uid, ids, field_name, arg, context=None):
return dict(self.name_get(cr, uid, ids, context=context))
def get_number_items(self, cr, uid, ids, model, domain, context=None):
res = dict.fromkeys(ids, 0)
obj = self.pool.get(model)
for section_id in ids:
res[section_id] = obj.search(cr, uid, [("section_id", "=", section_id)] + domain, count=True, context=context)
return res
def _get_number_leads(self, cr, uid, ids, field_name, arg, context=None):
return self.get_number_items(cr, uid, ids, 'crm.lead', ['|', '|', ("type", "=", "lead"), ("type", "=", "both"), ("type", "=", False), ('state', 'not in', ['done', 'cancel'])], context=context)
def _get_number_opportunities(self, cr, uid, ids, field_name, arg, context=None):
return self.get_number_items(cr, uid, ids, 'crm.lead', ['|', ("type", "=", "opportunity"), ("type", "=", "both"), ('state', 'not in', ['done', 'cancel'])], context=context)
_columns = {
'name': fields.char('Sales Team', size=64, required=True, translate=True),
'complete_name': fields.function(get_full_name, type='char', size=256, readonly=True, store=True),
@ -128,6 +141,9 @@ class crm_case_section(osv.osv):
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="cascade", required=True,
help="The email address associated with this team. New emails received will automatically "
"create new leads assigned to the team."),
'number_lead': fields.function(_get_number_leads, type='integer', readonly=True),
'number_opportunity': fields.function(_get_number_opportunities, type='integer', readonly=True),
'color': fields.integer('Color Index'),
}
def _get_stage_common(self, cr, uid, context):
@ -137,7 +153,6 @@ class crm_case_section(osv.osv):
_defaults = {
'active': 1,
'stage_ids': _get_stage_common,
'alias_domain': False, # always hide alias during creation
}
_sql_constraints = [

View File

@ -84,6 +84,20 @@ class crm_lead(base_stage, format_address, osv.osv):
},
}
def dynamic_help(self, cr, uid, help, context=None):
if context.get('default_type', None) == 'lead':
context['dynamic_help_model'] = 'crm.case.section'
context['dynamic_help_id'] = context.get('default_section_id', None)
context['dynamic_help_documents'] = _("leads")
return super(crm_lead, self).dynamic_help(cr, uid, help, context=context)
def onchange_user_id(self, cr, uid, ids, section_id, user_id, context=None):
if user_id:
section_ids = self.pool.get('crm.case.section').search(cr, uid, ['|', ('user_id', '=', user_id), ('member_ids', '=', user_id)], context=context)
if section_ids and (not section_id or section_id not in section_ids):
section_id = section_ids[0]
return {'value': {'section_id': section_id}}
def create(self, cr, uid, vals, context=None):
if context is None:
context = {}

View File

@ -45,6 +45,7 @@
</record>
<record model="crm.case.stage" id="stage_lead6">
<field name="name">Won</field>
<field eval="True" name="fold"/>
<field eval="1" name="case_default"/>
<field name="state">done</field>
<field eval="'100'" name="probability"/>

View File

@ -9,11 +9,12 @@
<field name="domain">['|', ('type','=','lead'), ('type','=',False)]</field>
<field name="view_id" ref="crm_case_tree_view_leads"/>
<field name="search_view_id" ref="crm.view_crm_case_leads_filter"/>
<field name="context">{'default_type':'lead', 'stage_type':'lead'}</field>
<field name="context">{
'default_type':'lead',
'stage_type':'lead'
}</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create an unqualified lead.
</p><p>
<p>
Use leads if you need a qualification step before creating an
opportunity or a customer. It can be a business card you received,
a contact form filled in your website, or a file of unqualified
@ -44,7 +45,11 @@
<field name="res_model">crm.lead</field>
<field name="view_mode">kanban,tree,graph,form,calendar</field>
<field name="domain">[('type','=','opportunity')]</field>
<field name="context">{'stage_type': 'opportunity', 'default_type': 'opportunity', 'default_user_id': uid}</field>
<field name="context">{
'stage_type': 'opportunity',
'default_type': 'opportunity',
'default_user_id': uid
}</field>
<field name="view_id" eval="False"/>
<field name="search_view_id" ref="crm.view_crm_case_opportunities_filter"/>
<field name="help" type="html">
@ -82,9 +87,9 @@
<field name="act_window_id" ref="crm_case_category_act_oppor11"/>
</record>
<menuitem name="Sales" id="base.menu_sales" parent="base.menu_base_partner" sequence="1" />
<menuitem name="Leads" id="menu_crm_leads" parent="base.menu_sales" action="crm_case_category_act_leads_all" sequence="2" />
<menuitem name="Opportunities" id="menu_crm_opportunities" parent="base.menu_sales" action="crm_case_category_act_oppor11" sequence="3" />
<menuitem name="Sales" id="base.menu_sales" parent="base.menu_base_partner" sequence="1"/>
<menuitem name="Leads" id="menu_crm_leads" parent="base.menu_sales" action="crm_case_category_act_leads_all" sequence="2" groups="base.group_sale_manager"/>
<menuitem name="Opportunities" id="menu_crm_opportunities" parent="base.menu_sales" action="crm_case_category_act_oppor11" sequence="3" groups="base.group_sale_manager"/>
</data>
</openerp>

View File

@ -151,7 +151,7 @@
-->
</group>
<group>
<field name="user_id"
<field name="user_id" on_change="onchange_user_id(section_id, user_id)"
context="{'default_groups_ref': ['base.group_user', 'base.group_sale_salesman_all_leads']}"/>
<label for="section_id"/>
<div>
@ -427,7 +427,7 @@
</group>
<group>
<field name="user_id" context="{'default_groups_ref': ['base.group_user', 'base.group_sale_salesman_all_leads']}"/>
<field name="user_id" on_change="onchange_user_id(section_id, user_id)" context="{'default_groups_ref': ['base.group_user', 'base.group_sale_salesman_all_leads']}"/>
<label for="section_id"/>
<div>
<field name="section_id" widget="selection"/>

View File

@ -0,0 +1,285 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- CRM lead search by Salesteams -->
<record model="ir.actions.act_window" id="crm_case_form_view_salesteams_lead">
<field name="name">Leads</field>
<field name="res_model">crm.lead</field>
<field name="view_mode">tree,form</field>
<field name="domain">['|', ('type','=','lead'), ('type','=',False)]</field>
<field name="view_id" ref="crm_case_tree_view_leads"/>
<field name="search_view_id" ref="crm.view_crm_case_leads_filter"/>
<field name="context">{
'search_default_section_id': [active_id], 'default_section_id': active_id, 'default_type':'lead', 'stage_type':'lead'
}</field>
<field name="help" type="html">
<p>
Use leads if you need a qualification step before creating an
opportunity or a customer. It can be a business card you received,
a contact form filled in your website, or a file of unqualified
prospects you import, etc.
</p><p>
Once qualified, the lead can be converted into a business
opportunity and/or a new customer in your address book.
</p>
</field>
</record>
<record model="ir.actions.act_window.view" id="action_crm_tag_tree_view_leads_salesteams_all">
<field name="sequence" eval="1"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="crm_case_tree_view_leads"/>
<field name="act_window_id" ref="crm_case_form_view_salesteams_lead"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_tag_form_view_leads_salesteams_all">
<field name="sequence" eval="3"/>
<field name="view_mode">form</field>
<field name="view_id" ref="crm_case_form_view_leads"/>
<field name="act_window_id" ref="crm_case_form_view_salesteams_lead"/>
</record>
<!-- CRM opportunity search by Salesteams -->
<record model="ir.actions.act_window" id="crm_case_form_view_salesteams_opportunity">
<field name="name">Opportunities</field>
<field name="res_model">crm.lead</field>
<field name="view_mode">kanban,tree,graph,form,calendar</field>
<field name="domain">[('type','=','opportunity')]</field>
<field name="view_id" ref="crm.crm_case_kanban_view_leads"/>
<field name="search_view_id" ref="crm.view_crm_case_opportunities_filter"/>
<field name="context">{
'search_default_section_id': [active_id], 'default_section_id': active_id, 'stage_type': 'opportunity', 'default_type': 'opportunity', 'default_user_id': uid
}</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a new opportunity.
</p><p>
OpenERP helps you keep track of your sales pipeline to follow
up potential sales and better forecast your future revenues.
</p><p>
You will be able to plan meetings and phone calls from
opportunities, convert them into quotations, attach related
documents, track all discussions, and much more.
</p>
</field>
</record>
<!-- Case Sections Salesteams kanban view -->
<record model="ir.ui.view" id="crm_case_section_salesteams_view_kanban">
<field name="name">crm.case.section.kanban</field>
<field name="model">crm.case.section</field>
<field name="arch" type="xml">
<kanban version="7.0" class="oe_background_grey">
<field name="name"/>
<field name="user_id"/>
<field name="member_ids"/>
<field name="note"/>
<field name="alias_id"/>
<field name="color"/>
<field name="number_lead"/>
<field name="number_opportunity"/>
<templates>
<t t-name="kanban-box">
<div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_project oe_kanban_global_click oe_kanban_crm_salesteams" style="width:220px;">
<div class="oe_dropdown_toggle oe_dropdown_kanban" groups="base.group_user">
<span class="oe_e">í</span>
<ul class="oe_dropdown_menu">
<li t-if="widget.view.is_action_enabled('edit')"><a type="edit">Sales Teams Settings</a></li>
<li t-if="widget.view.is_action_enabled('delete')"><a type="delete">Delete</a></li>
<li t-if="widget.view.is_action_enabled('edit')"><ul class="oe_kanban_colorpicker" data-field="color"/></li>
</ul>
</div>
<div class="oe_kanban_content">
<h4><field name="name"/></h4>
<div class="oe_kanban_crm_salesteams_alias" t-if="record.alias_id.value">
<span class="oe_e">%%</span><small><field name="alias_id"/></small>
</div>
<div class="oe_kanban_crm_salesteams_list">
<a name="%(crm_case_form_view_salesteams_lead)d" type="action" style="margin-right: 10px">
<t t-raw="record.number_lead.raw_value"/>
<t t-if="record.number_lead.raw_value &gt;= 1">Leads</t><t t-if="record.number_lead.raw_value &lt; 1">Lead</t></a>
<a name="%(crm_case_form_view_salesteams_opportunity)d" type="action" style="margin-right: 10px">
<t t-raw="record.number_opportunity.raw_value"/>
<t t-if="record.number_opportunity.raw_value &gt;= 1">Opportunities</t><t t-if="record.number_opportunity.raw_value &lt; 1">Opportunity</t></a>
</div>
<div class="oe_kanban_crm_salesteams_avatars">
<img t-if="record.user_id.raw_value" t-att-src="kanban_image('res.users', 'image_small', record.user_id.raw_value)" t-att-data-member_id="record.user_id.raw_value"/>
<t t-foreach="record.member_ids.raw_value.slice(0,11)" t-as="member">
<img t-att-src="kanban_image('res.users', 'image_small', member)" t-att-data-member_id="member"/>
</t>
</div>
</div>
</div>
</t>
</templates>
</kanban>
</field>
</record>
<!-- Case Sections Action -->
<record id="crm_case_section_salesteams_act" model="ir.actions.act_window">
<field name="name">Sales Teams</field>
<field name="res_model">crm.case.section</field>
<field name="view_type">form</field>
<field name="view_mode">kanban,tree,form</field>
<field name="view_id" ref="crm_case_section_salesteams_view_kanban"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click here to define a new sales team.
</p><p>
Use sales team to organize your different salespersons or
departments into separate teams. Each team will work in
its own list of opportunities.
</p>
</field>
</record>
<!-- Case Sections Form View -->
<record id="crm_case_section_view_form" model="ir.ui.view">
<field name="name">crm.case.section.form</field>
<field name="model">crm.case.section</field>
<field name="arch" type="xml">
<form string="Sales Team" version="7.0">
<sheet>
<group>
<group>
<field name="name" colspan="2"/>
<field name="parent_id"/>
<field name="code"/>
</group>
<group>
<field name="user_id"/>
<field name="resource_calendar_id"/>
<field name="active"/>
</group>
<group colspan="4">
<label for="alias_id"/>
<div class="oe_inline">
<field name="alias_id" class="oe_inline oe_read_only" required="0" nolabel="1"/>
<span class="oe_edit_only" name="edit_alias">
<field name="alias_name" class="oe_inline" attrs="{'required': [('alias_id', '!=', False)]}"/>@<field class="oe_inline" name="alias_domain"/>
</span>
</div>
</group>
</group>
<notebook colspan="4">
<page string="Sales Team">
<group>
<field name="change_responsible"/>
</group>
<separator string="Team Members"/>
<field name="member_ids" widget="many2many_kanban">
<kanban quick_create="false" create="true">
<field name="name"/>
<templates>
<t t-name="kanban-box">
<div style="position: relative">
<a t-if="! read_only_mode" type="delete" style="position: absolute; right: 0; padding: 4px; diplay: inline-block">X</a>
<div class="oe_module_vignette">
<div class="oe_module_desc">
<field name="name"/>
</div>
</div>
</div>
</t>
</templates>
</kanban>
</field>
</page>
<page string="Stages">
<separator string="Select Stages for this Sales Team"/>
<field name="stage_ids"/>
</page>
<page string="Notes">
<field name="note"/>
</page>
</notebook>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers" help="Follow this salesteam to automatically track the events associated to users of this team."/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
</field>
</record>
<!-- Case Sections Tree View -->
<record id="crm_case_section_view_tree" model="ir.ui.view">
<field name="name">crm.case.section.tree</field>
<field name="model">crm.case.section</field>
<field name="field_parent">child_ids</field>
<field name="arch" type="xml">
<tree string="Sales Team">
<field name="name"/>
<field name="code"/>
<field name="user_id"/>
</tree>
</field>
</record>
<!-- Case Sections Action -->
<record model="ir.actions.act_window.view" id="action_crm_tag_kanban_view_salesteams_oppor11">
<field name="sequence" eval="0"/>
<field name="view_mode">kanban</field>
<field name="view_id" ref="crm_case_kanban_view_leads"/>
<field name="act_window_id" ref="crm_case_form_view_salesteams_opportunity"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_tag_tree_view_salesteams_oppor11">
<field name="sequence" eval="1"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="crm_case_tree_view_oppor"/>
<field name="act_window_id" ref="crm_case_form_view_salesteams_opportunity"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_tag_form_view_salesteams_oppor11">
<field name="sequence" eval="2"/>
<field name="view_mode">form</field>
<field name="view_id" ref="crm_case_form_view_oppor"/>
<field name="act_window_id" ref="crm_case_form_view_salesteams_opportunity"/>
</record>
<record id="crm_case_section_act_tree" model="ir.actions.act_window">
<field name="name">Cases by Sales Team</field>
<field name="res_model">crm.case.section</field>
<field name="domain">[('parent_id','=',False)]</field>
<field name="view_type">tree</field>
<field name="view_id" ref="crm_case_section_view_tree"/>
</record>
<record id="crm_case_section_act" model="ir.actions.act_window">
<field name="name">Sales Teams</field>
<field name="res_model">crm.case.section</field>
<field name="view_type">form</field>
<field name="view_id" ref="crm_case_section_view_tree"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click here to define a new sales team.
</p><p>
Use sales team to organize your different salespersons or
departments into separate teams. Each team will work in
its own list of opportunities.
</p>
</field>
</record>
<menuitem action="crm_case_section_act"
id="menu_crm_case_section_act" sequence="15"
parent="base.menu_base_config" groups="base.group_sale_manager"/>
<menuitem
action="crm_case_section_salesteams_act"
id="crm.menu_crm_case_section_act"
sequence="1"
parent="base.menu_sales"
groups="base.group_sale_manager,base.group_sale_salesman"/>
</data>
</openerp>

View File

@ -70,109 +70,6 @@
<menuitem action="crm_case_channel_action" id="menu_crm_case_channel" parent="base.menu_crm_config_lead" sequence="4" groups="base.group_no_one"/>
<!-- Case Sections Form View -->
<record id="crm_case_section_view_form" model="ir.ui.view">
<field name="name">crm.case.section.form</field>
<field name="model">crm.case.section</field>
<field name="arch" type="xml">
<form string="Sales Team" version="7.0">
<group>
<group>
<field name="name" colspan="2"/>
<field name="parent_id"/>
<field name="code"/>
</group>
<group>
<field name="user_id"/>
<field name="resource_calendar_id"/>
<field name="active"/>
</group>
</group>
<notebook colspan="4">
<page string="Sales Team">
<group>
<field name="alias_id" invisible="1" required="0"/>
<label for="alias_name" attrs="{'invisible': [('alias_domain', '=', False)]}"/>
<div attrs="{'invisible': [('alias_domain', '=', False)]}">
<field name="alias_name" class="oe_inline" attrs="{'required': [('alias_id', '!=', False)]}"/>@<field name="alias_domain" class="oe_inline"/>
</div>
<field name="change_responsible"/>
</group>
<separator string="Team Members"/>
<field name="member_ids" widget="many2many_kanban">
<kanban quick_create="false" create="true">
<field name="name"/>
<templates>
<t t-name="kanban-box">
<div style="position: relative">
<a t-if="! read_only_mode" type="delete" style="position: absolute; right: 0; padding: 4px; diplay: inline-block">X</a>
<div class="oe_module_vignette">
<div class="oe_module_desc">
<field name="name"/>
</div>
</div>
</div>
</t>
</templates>
</kanban>
</field>
</page>
<page string="Stages">
<separator string="Select Stages for this Sales Team"/>
<field name="stage_ids"/>
</page>
<page string="Notes">
<field name="note"/>
</page>
</notebook>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers" help="Follow this salesteam to automatically track the events associated to users of this team."/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
</field>
</record>
<!-- Case Sections Tree View -->
<record id="crm_case_section_view_tree" model="ir.ui.view">
<field name="name">crm.case.section.tree</field>
<field name="model">crm.case.section</field>
<field name="field_parent">child_ids</field>
<field name="arch" type="xml">
<tree string="Sales Team">
<field name="name"/>
<field name="code"/>
<field name="user_id"/>
</tree>
</field>
</record>
<!-- Case Sections Action -->
<record id="crm_case_section_act" model="ir.actions.act_window">
<field name="name">Sales Teams</field>
<field name="res_model">crm.case.section</field>
<field name="view_type">form</field>
<field name="view_id" ref="crm_case_section_view_tree"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to define a new sales team.
</p><p>
Use sales team to organize your different salespersons or
departments into separate teams. Each team will work in
its own list of opportunities.
</p>
</field>
</record>
<menuitem action="crm_case_section_act"
id="menu_crm_case_section_act" sequence="15"
parent="base.menu_base_config" groups="base.group_sale_manager"/>
<!-- CRM Stage Tree View -->
<record model="ir.ui.view" id="crm_case_stage_tree">
@ -295,13 +192,6 @@
groups="base.group_no_one"
parent="base.menu_crm_config_lead"/>
<record id="crm_case_section_act_tree" model="ir.actions.act_window">
<field name="name">Cases by Sales Team</field>
<field name="res_model">crm.case.section</field>
<field name="domain">[('parent_id','=',False)]</field>
<field name="view_type">tree</field>
<field name="view_id" ref="crm_case_section_view_tree"/>
</record>
<!-- Segmentation line Tree View -->

View File

@ -26,9 +26,6 @@ class crm_configuration(osv.osv_memory):
_inherit = ['sale.config.settings', 'fetchmail.config.settings']
_columns = {
'fetchmail_lead': fields.boolean("Create leads from incoming mails",
fetchmail_model='crm.lead', fetchmail_name='Incoming Leads',
help="""Allows you to configure your incoming mail server, and create leads from incoming emails."""),
'group_fund_raising': fields.boolean("Manage Fund Raising",
implied_group='crm.group_fund_raising',
help="""Allows you to trace and manage your activities for fund raising."""),

View File

@ -23,19 +23,6 @@
</div>
</group>
</div>
<group name="On Mail Client" version="7.0" position="after">
<group>
<label for="id" string="On Mail Server"/>
<div>
<div name="fetchmail_lead">
<field name="fetchmail_lead" class="oe_inline"/>
<label for="fetchmail_lead"/>
<button name="configure_fetchmail_lead" type="object" string="Configure" icon="gtk-go-forward"
attrs="{'invisible': [('fetchmail_lead','=',False)]}" class="oe_link"/>
</div>
</div>
</group>
</group>
</field>
</record>

View File

@ -30,8 +30,11 @@
<field name="res_model">crm.lead</field>
<field name="view_mode">kanban,tree,form,graph,calendar</field>
<field name="domain">[('type','=','opportunity')]</field>
<field name="context">{'search_default_partner_id': active_id,
'stage_type': 'opportunity', 'default_type': 'opportunity'}</field>
<field name="context">{
'search_default_partner_id': active_id,
'stage_type': 'opportunity',
'default_type': 'opportunity'
}</field>
<field name="view_id" eval="False"/>
<field name="search_view_id" ref="crm.view_crm_case_opportunities_filter"/>
<field name="help" type="html">

View File

@ -36,4 +36,4 @@ access_res_partner_bank_type_crm_user,res.partner.bank.type.crm.user,base.model_
access_crm_lead_partner_manager,crm.lead.partner.manager,model_crm_lead,base.group_partner_manager,1,0,0,0
access_crm_phonecall_partner_manager,crm.phonecall.partner.manager,model_crm_phonecall,base.group_partner_manager,1,1,1,1
access_crm_payment_mode_user,crm.payment.mode,model_crm_payment_mode,base.group_sale_salesman,1,0,0,0
access_crm_payment_mode,crm.payment.mode,model_crm_payment_mode,base.group_sale_manager,1,1,1,1
access_crm_payment_mode,crm.payment.mode,model_crm_payment_mode,base.group_sale_manager,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
36 access_crm_lead_partner_manager crm.lead.partner.manager model_crm_lead base.group_partner_manager 1 0 0 0
37 access_crm_phonecall_partner_manager crm.phonecall.partner.manager model_crm_phonecall base.group_partner_manager 1 1 1 1
38 access_crm_payment_mode_user crm.payment.mode model_crm_payment_mode base.group_sale_salesman 1 0 0 0
39 access_crm_payment_mode crm.payment.mode model_crm_payment_mode base.group_sale_manager 1 1 1 1

View File

@ -0,0 +1,41 @@
.oe_kanban_crm_salesteams {
width: 220px;
min-height: 160px;
}
.oe_kanban_crm_salesteams_avatars {
margin-top: 8px;
}
.oe_kanban_crm_salesteams_avatars img {
width: 30px;
height: 30px;
padding-left: 0px;
margin-top: 3px;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
border-radius: 2px;
-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}
.oe_kanban_crm_salesteams_alias {
margin: -8px 0 8px 0;
}
.oe_kanban_crm_salesteams_alias .oe_e {
font-size: 30px;
line-height: 6px;
vertical-align: top;
margin-right: 3px;
color: white;
text-shadow: 0px 0px 2px rgba(0, 0, 0, 1);
float: left;
}
.oe_kanban_crm_salesteams_list a {
white-space: nowrap;
}
.oe_kanban_crm_salesteams_list a:hover {
text-decoration: underline !important;
}

View File

@ -0,0 +1,11 @@
openerp.crm = function(openerp) {
openerp.web_kanban.KanbanRecord.include({
on_card_clicked: function() {
if (this.view.dataset.model === 'crm.case.section') {
this.$('.oe_kanban_crm_salesteams_list a').first().click();
} else {
this._super.apply(this, arguments);
}
},
});
};

View File

@ -21,7 +21,6 @@
import crm_claim
import report
import res_config
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -41,7 +41,6 @@ automatically new claims based on incoming emails.
'crm_claim_menu.xml',
'security/ir.model.access.csv',
'report/crm_claim_report_view.xml',
'res_config_view.xml',
'crm_claim_data.xml',
],
'demo': ['crm_claim_demo.xml'],

View File

@ -1,32 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Business Applications
# Copyright (C) 2004-2012 OpenERP S.A. (<http://openerp.com>).
#
# 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/>.
#
##############################################################################
from openerp.osv import fields, osv
class crm_claim_settings(osv.osv_memory):
_name = 'sale.config.settings'
_inherit = ['sale.config.settings', 'fetchmail.config.settings']
_columns = {
'fetchmail_claim': fields.boolean("Create claims from incoming mails",
fetchmail_model='crm.claim', fetchmail_name='Incoming Claims',
help="""Allows you to configure your incoming mail server, and create claims from incoming emails."""),
}

View File

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_project_config_claim" model="ir.ui.view">
<field name="name">crm_claim settings</field>
<field name="model">sale.config.settings</field>
<field name="inherit_id" ref="base_setup.view_sale_config_settings"/>
<field name="priority" eval="20"/>
<field name="arch" type="xml">
<div name="fetchmail_lead" position="after">
<div>
<field name="fetchmail_claim" class="oe_inline"/>
<label for="fetchmail_claim"/>
<button type="object" name="configure_fetchmail_claim" string="Configure" icon="gtk-go-forward"
attrs="{'invisible': [('fetchmail_claim','=',False)]}" class="oe_link"/>
</div>
</div>
</field>
</record>
</data>
</openerp>

View File

@ -341,7 +341,8 @@
</group>
<group>
<field name="company_id" widget="selection" groups="base.group_multi_company"/>
<field name="department_id"/> </group>
<field name="department_id"/>
</group>
</group>
<div>
<label for="description"/>

View File

@ -487,6 +487,12 @@ class hr_applicant(base_stage, osv.Model):
"""
return self.set_priority(cr, uid, ids, '3')
def dynamic_help(self, cr, uid, help, context=None):
context['dynamic_help_model'] = 'hr.job'
context['dynamic_help_id'] = context.get('default_job_id', None)
context['dynamic_help_documents'] = _("job applicants")
return super(hr_applicant, self).dynamic_help(cr, uid, help, context=context)
class hr_job(osv.osv):
_inherit = "hr.job"

View File

@ -10,17 +10,13 @@
<field name="view_id" eval="False"/>
<field name="search_view_id" ref="view_crm_case_jobs_filter"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to add a new job applicant.
</p><p>
<p>
OpenERP helps you track applicants in the recruitment
process and follow up all operations: meetings, interviews, etc.
</p><p>
If you setup the email gateway, applicants and their attached
CV are created automatically when an email is sent to
jobs@yourcompany.com. If you install the document management
modules, all resumes are indexed automatically, so that you can
easily search through their content.
Applicants and their attached CV are created automatically when an email is sent.
If you install the document management modules, all resumes are indexed automatically,
so that you can easily search through their content.
</p>
</field>
</record>

View File

@ -312,12 +312,16 @@
attrs="{'invisible':[('survey_id','=',False)]}"/>
</div>
</field>
<xpath expr="//div[@class='oe_title']" version="7.0" position="after">
<div attrs="{'invisible': [('alias_domain', '=', False)]}">
<field name="alias_id" invisible="1" required="0"/>
<label for="alias_name" class="oe_edit_only"/>
<field name="alias_name" nolabel="1" class="oe_inline" attrs="{'required': [('alias_id', '!=', False)]}"/>@<field name="alias_domain" nolabel="1" class="oe_inline"/>
</div>
<xpath expr="//sheet//group" version="7.0" position="after">
<group colspan="4">
<label for="alias_id"/>
<div class="oe_inline" attrs="{'invisible': [('alias_domain', '=', False)]}">
<field name="alias_id" class="oe_inline oe_read_only" required="0" nolabel="1"/>
<span class="oe_edit_only" name="edit_alias">
<field name="alias_name" class="oe_inline" attrs="{'required': [('alias_id', '!=', False)]}"/>@<field class="oe_inline" name="alias_domain"/>
</span>
</div>
</group>
</xpath>
</field>
</record>

View File

@ -0,0 +1,37 @@
.. _mail_alias:
mail.alias
============
Models
+++++++
``mail.alias`` is a class for mapping of an email address with a given OpenERP Document model. It is used by OpenERP's mail gateway when processing incoming emails sent to the system. If the recipient address (To) of the message matches a Mail Alias, the message will be either processed following the rules of that alias. If the message is a reply it will be attached to the existing discussion on the corresponding record, otherwise a new record of the corresponding model will be created.
This is meant to be used in combination with a catch-all email configuration on the company's mail server, so that as soon as a new mail.alias is created, it becomes immediately usable and OpenERP will accept email for it.
.. versionchanged:: 7.1
Some Fields
+++++++++++
- ``alias_name`` :
The name of the email alias, e.g. 'jobs'
- ``alias_model_id`` :
The model (OpenERP Document Kind) to which this alias corresponds. Any incoming email that does not reply to an existing record will cause the creation of a new record of this model (e.g. a Project Task)
- ``alias_defaults`` :
A Python dictionary that will be evaluated to provide default values when creating new records for this alias.
- ``alias_domain`` :
Methods
+++++++
- ``name_get`` :
Return the mail alias display alias_name, inclusing the implicit mail catchall domain from config.
e.g. `jobs@openerp.my.openerp.com` or `sales@openerp.my.openerp.com`
- ``create_unique_alias`` :
Creates an email.alias record according to the values provided in ``vals``, with 2 alterations: the ``alias_name`` value may be suffixed in order to make it unique, and the ``alias_model_id`` value will set to the model ID of the ``model_name`` value, if provided,
- ``get_alias`` :
Return the mail alias for a document (or the default mail alias of the model).
Arguments:
model (model OpenERP)
alias_defaults (A Python dictionary to provide default values when creating new records for this alias.)

View File

@ -22,6 +22,7 @@
import logging
import re
import unicodedata
import ast
from openerp.osv import fields, osv
from openerp.tools import ustr
@ -117,8 +118,13 @@ class mail_alias(osv.Model):
mail catchall domain from config.
e.g. `jobs@openerp.my.openerp.com` or `sales@openerp.my.openerp.com`
"""
return [(record['id'], "%s@%s" % (record['alias_name'], record['alias_domain']))
for record in self.read(cr, uid, ids, ['alias_name', 'alias_domain'], context=context)]
res = []
for record in self.browse(cr, uid, ids, context=context):
if record.alias_name and record.alias_domain:
res.append((record['id'], "%s@%s" % (record.alias_name, record.alias_domain)))
else:
res.append((record['id'], False))
return res
def _find_unique(self, cr, uid, name, context=None):
"""Find a unique alias name similar to ``name``. If ``name`` is

View File

@ -69,39 +69,39 @@
<field name="arch" type="xml">
<form string="Group Form" version="7.0">
<sheet class="openerp_mail_group_sheet">
<field name="image" widget='image' class="oe_avatar oe_left" options='{"preview_image": "image_medium"}'/>
<field name="image" widget='image' class="oe_avatar oe_left" options='{"preview_image": "image_small"}'/>
<div class="oe_title">
<div class="oe_edit_only">
<label for="name" string="Group Name"/>
</div>
<h1><field name="name" readonly="0"/></h1>
<div name="alias_box" colspan="4" attrs="{'invisible': [('alias_domain', '=', False)]}">
<field name="alias_id" invisible="1" required="0"/>
<label for="alias_name" class="oe_edit_only"/>
<field name="alias_name" nolabel="1" class="oe_inline" attrs="{'required': [('alias_id', '!=', False)]}"/>@<field name="alias_domain" nolabel="1" class="oe_inline"/>
<field name="alias_id" class="oe_read_only" required="0"/>
<span class="oe_edit_only">
<label for="alias_name"/>
<field name="alias_name" nolabel="1" class="oe_inline" attrs="{'required': [('alias_id', '!=', False)]}"/>@<field name="alias_domain" nolabel="1" class="oe_inline" style="padding-left:0;"/>
</span>
</div>
<field name="description" placeholder="Topics discussed in this group..."/>
</div>
<field name="description" placeholder="Topics discussed in this group..."/>
<div class="oe_clear"/>
<group>
<group class="oe_edit_only">
<field name="public"/>
<field name="group_public_id"
attrs="{'invisible': [('public','&lt;&gt;','groups')], 'required': [('public','=','groups')]}"
/>
<field name="group_ids" widget="many2many_tags"/>
</group>
<group>
<div class="oe_grey" attrs="{'invisible': [('public','&lt;&gt;','public')]}">
This group is visible by everyone,
including your customers if you installed
the portal module.
</div>
<div class="oe_grey" attrs="{'invisible': [('public','&lt;&gt;','private')]}">
Only the invited followers can read the
discussions on this group.
</div>
</group>
<group class="oe_edit_only">
<field name="public"/>
<field name="group_public_id"
attrs="{'invisible': [('public','&lt;&gt;','groups')], 'required': [('public','=','groups')]}"
/>
<field name="group_ids" widget="many2many_tags"/>
</group>
<group attrs="{'invisible': [('public','not in',['public','private'])]}">
<div class="oe_grey" attrs="{'invisible': [('public','&lt;&gt;','public')]}">
This group is visible by everyone,
including your customers if you installed
the portal module.
</div>
<div class="oe_grey" attrs="{'invisible': [('public','&lt;&gt;','private')]}">
Only the invited followers can read the
discussions on this group.
</div>
</group>
</sheet>
<div class="oe_chatter">

View File

@ -89,6 +89,28 @@ class mail_thread(osv.AbstractModel):
# :param function lambda: returns whether the tracking should record using this subtype
_track = {}
def dynamic_help(self, cr, uid, help, context=None):
if not context.get('dynamic_help_model', None):
if context.get('dynamic_help_id', None):
object_id = self.pool.get(context.get('dynamic_help_model')).browse(cr, uid, context.get('dynamic_help_id'), context=context)
alias = object_id.alias_id and object_id.alias_id.name_get() or False
if alias and alias[0] and alias[0][1]:
email = alias[0][1]
return "%s %s" % (_("<p class='oe_view_nocontent_create'>Click here to add a new %s or send an email to: <a href='mailto:%s'>%s</a></p>") % (context.get('dynamic_help_documents', _("documents")), email, email), help or "")
else:
model_id = self.pool.get('ir.model').search(cr, uid, [("model", "=", self._name)], context=context)[0]
alias_obj = self.pool.get('mail.alias')
alias_ids = alias_obj.search(cr, uid, [("alias_model_id", "=", model_id)], context=context, limit=5)
if alias_ids:
for alias in alias_obj.browse(cr, uid, alias_ids, context=context):
email = "%s@%s" % (alias.alias_name, alias.alias_domain)
return "%s %s" % (_("<p class='oe_view_nocontent_create'>Click here to add a new %s or send an email, for example, to: <a href='mailto:%s'>%s</a></p>") % (context.get('dynamic_help_documents', _("documents")), email, email), help or "")
if context.get('dynamic_help_documents', None) and ("%s" % help).find("oe_view_nocontent_create") == -1:
return "%s %s" % (_("<p class='oe_view_nocontent_create'>Click here to add a new %s</p>") % context.get('dynamic_help_documents', _("documents")), help or "")
return help
def _get_message_data(self, cr, uid, ids, name, args, context=None):
""" Computes:
- message_unread: has uid unread message for the document

View File

@ -4,7 +4,6 @@
* 'button' element wich comes with a lot of inappropriate
* styling. Entypo is also a headache to center properly
* */
.openerp .oe_topbar_item.oe_topbar_compose_full_email{
padding: 0px;
width: 32px;

View File

@ -14,6 +14,10 @@
padding: 0px 18px;
}
.openerp .oe_form_sheetbg.openerp_mail_group_sheet .oe_avatar {
padding-top: 3px;
}
/* Resize footer width */
.openerp .oe_form div.oe_mail_group_footer {
max-width: 80%;
@ -21,7 +25,7 @@
/* Resize group description */
.openerp .oe_form_sheetbg.openerp_mail_group_sheet .oe_form_field_text > textarea {
height: 40px;
height: 60px;
}
/* ------------------------------ */

View File

@ -19,10 +19,11 @@
#
##############################################################################
from . import test_mail_message, test_mail_features, test_message_read, test_invite
from . import test_mail_message, test_mail_features, test_message_read, test_invite, test_mail_alias
checks = [
test_mail_message,
test_mail_alias,
test_mail_features,
test_message_read,
test_invite,

View File

@ -0,0 +1,53 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Business Applications
# Copyright (c) 2012-TODAY OpenERP S.A. <http://openerp.com>
#
# 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/>.
#
##############################################################################
from openerp.tools import mute_logger
from openerp.tests import common
class test_mail_alias(common.TransactionCase):
def setUp(self):
super(test_mail_alias, self).setUp()
cr, uid = self.cr, self.uid
# Usefull models
self.ir_model = self.registry('ir.model')
self.mail_alias = self.registry('mail.alias')
#@mute_logger('openerp.addons.base.ir.ir_model', 'openerp.osv.orm')
def test_00_mail_alias(self):
""" Testing mail_group access rights and basic mail_thread features """
cr, uid = self.cr, self.uid
alias_name_0 = "global+alias+test_0"
alias_name_1 = "document+alias+test_1"
alias_defaults_1 = {'field_pigs': 11}
alias_name_2 = "document+alias+test_2"
alias_defaults_2 = {'field_pigs': 112}
# Create an alias
partner_model_id = self.ir_model.search(cr, uid, [('model', '=', 'mail.alias')])[0]
alias_id_0 = self.mail_alias.create(cr, uid,
{'alias_model_id': partner_model_id, 'alias_name': alias_name_0, 'alias_defaults': {}})
alias_id_1 = self.mail_alias.create(cr, uid,
{'alias_model_id': partner_model_id, 'alias_name': alias_name_1, 'alias_defaults': alias_defaults_1})
alias_id_2 = self.mail_alias.create(cr, uid,
{'alias_model_id': partner_model_id, 'alias_name': alias_name_2, 'alias_defaults': alias_defaults_2})

View File

@ -286,7 +286,6 @@ class project(osv.osv):
'type_ids': _get_type_common,
'alias_model': 'project.task',
'privacy_visibility': 'public',
'alias_domain': False, # always hide alias during creation
}
# TODO: Why not using a SQL contraints ?
@ -531,11 +530,11 @@ def Project():
context = dict(context, project_creation_in_progress=True)
mail_alias = self.pool.get('mail.alias')
if not vals.get('alias_id') and vals.get('name', False):
vals.pop('alias_name', None) # prevent errors during copy()
alias_name = vals.pop('alias_name', None) # prevent errors during copy()
alias_id = mail_alias.create_unique_alias(cr, uid,
# Using '+' allows using subaddressing for those who don't
# have a catchall domain setup.
{'alias_name': "project+"+short_name(vals['name'])},
{'alias_name': alias_name or "project+"+short_name(vals['name'])},
model_name=vals.get('alias_model', 'project.task'),
context=context)
vals['alias_id'] = alias_id
@ -605,8 +604,7 @@ class task(base_stage, osv.osv):
search_domain = []
project_id = self._resolve_project_id_from_context(cr, uid, context=context)
if project_id:
search_domain += ['|', ('project_ids', '=', project_id)]
search_domain += [('id', 'in', ids)]
search_domain += [('project_ids', '=', project_id)]
stage_ids = stage_obj._search(cr, uid, search_domain, order=order, access_rights_uid=access_rights_uid, context=context)
result = stage_obj.name_get(cr, access_rights_uid, stage_ids, context=context)
# restore order of the search
@ -887,8 +885,16 @@ class task(base_stage, osv.osv):
for f in res['fields']:
if 'Hours' in res['fields'][f]['string']:
res['fields'][f]['string'] = res['fields'][f]['string'].replace('Hours',tm)
return res
def dynamic_help(self, cr, uid, help, context=None):
context['dynamic_help_model'] = 'project.project'
context['dynamic_help_id'] = context.get('default_project_id', None)
context['dynamic_help_documents'] = _("tasks")
return super(task, self).dynamic_help(cr, uid, help, context=context)
# ----------------------------------------
# Case management
# ----------------------------------------

View File

@ -50,12 +50,13 @@
<field name="name">Tasks</field>
<field name="res_model">project.task</field>
<field name="view_mode">kanban,tree,form,calendar,gantt,graph</field>
<field name="context">{'search_default_project_id': [active_id], 'default_project_id': active_id}</field>
<field name="context">{
'search_default_project_id': [active_id],
'default_project_id': active_id,
}</field>
<field name="search_view_id" ref="view_task_search_form"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a new task.
</p><p>
<p>
OpenERP's project management allows you to manage the pipeline
of tasks in order to get things done efficiently. You can
track progress, discuss on tasks, attach documents, etc.
@ -111,6 +112,15 @@
</p>
</group>
</group>
<group colspan="4">
<label for="alias_id"/>
<div class="oe_inline">
<field name="alias_id" class="oe_inline oe_read_only" required="0" nolabel="1"/>
<span class="oe_edit_only" name="edit_alias">
<field name="alias_name" class="oe_inline" attrs="{'required': [('alias_id', '!=', False)]}"/>@<field class="oe_inline" name="alias_domain"/>
</span>
</div>
</group>
<notebook>
<page string="Team" name="team">
<field colspan="4" name="members" widget="many2many_kanban">
@ -133,13 +143,6 @@
</page>
<page string="Other Info">
<group>
<group string="Email Interface" attrs="{'invisible': [('alias_domain', '=', False)]}">
<div>
<field name="alias_id" invisible="1" required="0"/>
<label for="alias_name" class="oe_edit_only "/>
<field name="alias_name" class="oe_inline" attrs="{'required': [('alias_id', '!=', False)]}"/>@<field name="alias_domain" class="oe_inline"/>
</div>
</group>
<group string="Administration" groups="project.group_time_work_estimation_tasks">
<field name="planned_hours" widget="float_time"/>
<field name="effective_hours" widget="float_time"/>
@ -231,7 +234,6 @@
<field name="color"/>
<field name="task_count"/>
<field name="alias_id"/>
<field name="alias_domain"/>
<field name="doc_count"/>
<templates>
<t t-name="kanban-box">
@ -245,8 +247,10 @@
</ul>
</div>
<div class="oe_kanban_content">
<h4><field name="name"/></h4>
<div class="oe_kanban_project_alias" t-if="record.alias_id.value">
<span class="oe_e">%%</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>
@ -622,9 +626,7 @@
<field name="view_mode">kanban,tree,form,calendar,gantt,graph</field>
<field name="search_view_id" ref="view_task_search_form"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a new task.
</p><p>
<p>
OpenERP's project management allows you to manage the pipeline
of tasks in order to get things done efficiently. You can
track progress, discuss on tasks, attach documents, etc.

View File

@ -62,4 +62,21 @@
-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}
.oe_kanban_project_alias {
margin: -8px 0 8px 0;
}
.oe_kanban_project_alias .oe_e {
font-size: 30px;
line-height: 6px;
vertical-align: top;
margin-right: 3px;
color: white;
text-shadow: 0px 0px 2px rgba(0, 0, 0, 1);
float: left;
}
.oe_kanban_project_alias small {
display: block;
margin-left: 20px;
}

View File

@ -412,6 +412,12 @@ class project_issue(base_stage, osv.osv):
self.write(cr, uid, ids, {'date_open': False, 'date_closed': False})
return res
def dynamic_help(self, cr, uid, help, context=None):
context['dynamic_help_model'] = 'project.project'
context['dynamic_help_id'] = context.get('default_project_id', None)
context['dynamic_help_documents'] = _("issues")
return super(project_issue, self).dynamic_help(cr, uid, help, context=context)
# -------------------------------------------------------
# Stage management
# -------------------------------------------------------

View File

@ -14,9 +14,7 @@
<field name="domain" eval=""/>
<field name="search_view_id" ref="view_project_issue_filter"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to report a new issue.
</p><p>
<p>
The OpenERP issues tacker allows you to efficiantly manage things
like internal requests, software development bugs, customer
complaints, project troubles, material breakdowns, etc.

View File

@ -302,7 +302,19 @@
<field name="view_type">form</field>
<field name="name">Issues</field>
<field name="view_mode">kanban,tree,form,calendar,graph</field>
<field name="context">{'search_default_project_id': [active_id], 'default_project_id': active_id}</field>
<field name="context">{
'search_default_project_id': [active_id],
'default_project_id': active_id
}</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to report a new issue.
</p><p>
The OpenERP issues tacker allows you to efficiantly manage things
like internal requests, software development bugs, customer
complaints, project troubles, material breakdowns, etc.
</p>
</field>
</record>
<!-- Project -->
@ -324,9 +336,10 @@
<field name="priority" position="before">
<field name="project_escalation_id"/>
</field>
<field name="alias_domain" position="after">
<label for="alias_model" class="oe_edit_only" string="creates"/><field name="alias_model" class="oe_edit_only oe_inline"/>
</field>
<xpath expr='//span[@name="edit_alias"]' position='after'>
<label for="alias_model" string="creates" class="oe_inline"/>
<field name="alias_model" class="oe_inline" widget="radio"/>
</xpath>
</field>
</record>

View File

@ -340,6 +340,7 @@
</p>
</field>
</record>
<menuitem action="action_orders" id="menu_sale_order" parent="base.menu_sales" sequence="5" groups="base.group_sale_salesman,base.group_sale_manager"/>
<record id="action_orders_exception" model="ir.actions.act_window">

View File

@ -29,6 +29,23 @@ class sale_order(osv.osv):
domain="['|',('section_id','=',section_id),('section_id','=',False), ('object_id.model', '=', 'crm.lead')]")
}
class crm_case_section(osv.osv):
_inherit = 'crm.case.section'
def _get_number_saleorder(self, cr, uid, ids, field_name, arg, context=None):
return self.get_number_items(cr, uid, ids, 'sale.order', [('state','not in',('draft','sent','cancel'))], context=context)
def _get_number_quotation(self, cr, uid, ids, field_name, arg, context=None):
return self.get_number_items(cr, uid, ids, 'sale.order', [('state','in',('draft','sent','cancel'))], context=context)
def _get_number_invoice(self, cr, uid, ids, field_name, arg, context=None):
return self.get_number_items(cr, uid, ids, 'account.invoice', [('state','not in',('draft','cancel'))], context=context)
_columns = {
'number_saleorder': fields.function(_get_number_saleorder, type='integer', readonly=True),
'number_quotation': fields.function(_get_number_quotation, type='integer', readonly=True),
'number_invoice': fields.function(_get_number_invoice, type='integer', readonly=True),
}
class res_users(osv.Model):
_inherit = 'res.users'

View File

@ -113,5 +113,93 @@
</field>
</record>
<!-- search by Salesteams -->
<record id="action_orders_salesteams" model="ir.actions.act_window">
<field name="name">Sales Orders</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.order</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,calendar,graph</field>
<field name="search_view_id" ref="sale.view_sales_order_filter"/>
<field name="domain">[('state','not in',('draft','sent','cancel'))]</field>
<field name="context">{
'search_default_section_id': [active_id], 'default_section_id': active_id
}</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a quotation that can be converted into a sales
order.
</p><p>
OpenERP will help you efficiently handle the complete sales flow:
quotation, sales order, delivery, invoicing and payment.
</p>
</field>
</record>
<record id="action_quotations_salesteams" model="ir.actions.act_window">
<field name="name">Quotations</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.order</field>
<field name="view_type">form</field>
<field name="view_id" ref="sale.view_quotation_tree"/>
<field name="view_mode">tree,form,calendar,graph</field>
<field name="context">{
'search_default_section_id': [active_id], 'default_section_id': active_id, 'show_address': 1
}</field>
<field name="domain">[('state','in',('draft','sent','cancel'))]</field>
<field name="search_view_id" ref="sale.view_sales_order_filter"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a quotation, the first step of a new sale.
</p><p>
OpenERP will help you handle efficiently the complete sale flow:
from the quotation to the sales order, the
delivery, the invoicing and the payment collection.
</p><p>
The social feature helps you organize discussions on each sales
order, and allow your customers to keep track of the evolution
of the sales order.
</p>
</field>
</record>
<record id="action_invoice_salesteams" model="ir.actions.act_window">
<field name="name">Invoices</field>
<field name="res_model">account.invoice</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,calendar,graph</field>
<field name="view_id" ref="account.invoice_tree"/>
<field name="domain">[('state','not in',['draft','cancel'])]</field>
<field name="context">{'search_default_section_id': [active_id], 'default_section_id': active_id}</field>
<field name="search_view_id" ref="account.view_account_invoice_filter"/>
</record>
<record id="crm_case_section_salesteams_view_kanban" model="ir.ui.view">
<field name="name">crm.case.section.kanban</field>
<field name="model">crm.case.section</field>
<field name="inherit_id" ref="crm.crm_case_section_salesteams_view_kanban"/>
<field name="arch" type="xml">
<data>
<xpath expr="//field[@name='number_opportunity']" position="after">
<field name="number_quotation"/>
<field name="number_saleorder"/>
<field name="number_invoice"/>
</xpath>
<xpath expr="//div[@class='oe_kanban_crm_salesteams_list']" position="inside">
<a name="%(action_quotations_salesteams)d" type="action" style="margin-right: 10px">
<t t-raw="record.number_quotation.raw_value"/>
<t t-if="record.number_quotation.raw_value &gt;= 1">Quotation</t><t t-if="record.number_quotation.raw_value &lt; 1">Quotations</t></a>
<a name="%(action_orders_salesteams)d" type="action" style="margin-right: 10px">
<t t-raw="record.number_saleorder.raw_value"/>
<t t-if="record.number_saleorder.raw_value &gt;= 1">Sales Order</t><t t-if="record.number_saleorder.raw_value &lt; 1">Sales Orders</t></a>
<a name="%(action_invoice_salesteams)d" type="action" style="margin-right: 10px">
<t t-raw="record.number_invoice.raw_value"/>
<t t-if="record.number_invoice.raw_value &gt;= 1">Invoice</t><t t-if="record.number_invoice.raw_value &lt; 1">Invoices</t></a>
</xpath>
</data>
</field>
</record>
</data>
</openerp>