[MERGE] Sync with trunk
authorThibault Delavallée <tde@openerp.com>
Wed, 14 May 2014 15:21:54 +0000 (17:21 +0200)
committerThibault Delavallée <tde@openerp.com>
Wed, 14 May 2014 15:21:54 +0000 (17:21 +0200)
1  2 
addons/crm/sales_team.py
addons/crm/sales_team_view.xml
addons/sale/sales_team.py
addons/sale/sales_team_view.xml
addons/sale_crm/sale_crm.py
addons/sales_team/sales_team.xml
addons/website_sale/controllers/main.py

index 0000000,aeaf2cd..8a1e9f9
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,80 +1,82 @@@
+ import calendar
+ from datetime import date
+ from dateutil import relativedelta
+ from openerp import tools
+ from openerp.osv import fields, osv
+ class crm_case_section(osv.Model):
+     _inherit = 'crm.case.section'
+     _inherits = {'mail.alias': 'alias_id'}
+     def _get_opportunities_data(self, cr, uid, ids, field_name, arg, context=None):
+         """ Get opportunities-related data for salesteam kanban view
+             monthly_open_leads: number of open lead during the last months
+             monthly_planned_revenue: planned revenu of opportunities during the last months
+         """
+         obj = self.pool.get('crm.lead')
+         res = dict.fromkeys(ids, False)
+         month_begin = date.today().replace(day=1)
+         date_begin = month_begin - relativedelta.relativedelta(months=self._period_number - 1)
+         date_end = month_begin.replace(day=calendar.monthrange(month_begin.year, month_begin.month)[1])
+         lead_pre_domain = [('create_date', '>=', date_begin.strftime(tools.DEFAULT_SERVER_DATE_FORMAT)),
+                 ('create_date', '<=', date_end.strftime(tools.DEFAULT_SERVER_DATE_FORMAT)),
+                               ('type', '=', 'lead')]
+         opp_pre_domain = [('date_deadline', '>=', date_begin.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)),
+                       ('date_deadline', '<=', date_end.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)),
+                       ('type', '=', 'opportunity')]
+         for id in ids:
+             res[id] = dict()
+             lead_domain = lead_pre_domain + [('section_id', '=', id)]
+             opp_domain = opp_pre_domain + [('section_id', '=', id)]
+             res[id]['monthly_open_leads'] = self.__get_bar_values(cr, uid, obj, lead_domain, ['create_date'], 'create_date_count', 'create_date', context=context)
+             res[id]['monthly_planned_revenue'] = self.__get_bar_values(cr, uid, obj, opp_domain, ['planned_revenue', 'date_deadline'], 'planned_revenue', 'date_deadline', context=context)
+         return res
+     _columns = {
+         'resource_calendar_id': fields.many2one('resource.calendar', "Working Time", help="Used to compute open days"),
+         'stage_ids': fields.many2many('crm.case.stage', 'section_stage_rel', 'section_id', 'stage_id', 'Stages'),
+         'use_leads': fields.boolean('Leads',
+             help="The first contact you get with a potential customer is a lead you qualify before converting it into a real business opportunity. Check this box to manage leads in this sales team."),
++        'use_opportunities': fields.boolean('Opportunities', help="Check this box to manage opportunities in this sales team."),
+         'monthly_open_leads': fields.function(_get_opportunities_data,
+             type="string", readonly=True, multi='_get_opportunities_data',
+             string='Open Leads per Month'),
+         'monthly_planned_revenue': fields.function(_get_opportunities_data,
+             type="string", readonly=True, multi='_get_opportunities_data',
+             string='Planned Revenue per Month'),
+         'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="restrict", required=True, help="The email address associated with this team. New emails received will automatically create new leads assigned to the team."),
+     }
+     def _auto_init(self, cr, context=None):
+         """Installation hook to create aliases for all lead and avoid constraint errors."""
+         return self.pool.get('mail.alias').migrate_to_alias(cr, self._name, self._table, super(crm_case_section, self)._auto_init,
+             'crm.lead', self._columns['alias_id'], 'name', alias_prefix='Lead+', alias_defaults={}, context=context)
+     def _get_stage_common(self, cr, uid, context):
+         ids = self.pool.get('crm.case.stage').search(cr, uid, [('case_default', '=', 1)], context=context)
+         return ids
+     _defaults = {
+         'stage_ids': _get_stage_common,
+         'use_leads': True,
++        'use_opportunities': True,
+     }
+     def create(self, cr, uid, vals, context=None):
+         if context is None:
+             context = {}
+         create_context = dict(context, alias_model_name='crm.lead', alias_parent_model_name=self._name)
+         section_id = super(crm_case_section, self).create(cr, uid, vals, context=create_context)
+         section = self.browse(cr, uid, section_id, context=context)
+         self.pool.get('mail.alias').write(cr, uid, [section.alias_id.id], {'alias_parent_thread_id': section_id, 'alias_defaults': {'section_id': section_id, 'type': 'lead'}}, context=context)
+         return section_id
+     def unlink(self, cr, uid, ids, context=None):
+         # Cascade-delete mail aliases as well, as they should not exist without the sales team.
+         mail_alias = self.pool.get('mail.alias')
+         alias_ids = [team.alias_id.id for team in self.browse(cr, uid, ids, context=context) if team.alias_id]
+         res = super(crm_case_section, self).unlink(cr, uid, ids, context=context)
+         mail_alias.unlink(cr, uid, alias_ids, context=context)
+         return res
index 0000000,0a1b193..7e0eb2e
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,183 +1,185 @@@
+ <?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>
+         <!-- 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>
+                     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>
+        <record id="action_report_crm_lead_salesteam" model="ir.actions.act_window">
+            <field name="name">Leads Analysis</field>
+            <field name="res_model">crm.lead.report</field>
+            <field name="context">{"search_default_month":1}</field>
+            <field name="view_mode">graph</field>
+            <field name="view_id" ref="crm.view_report_crm_lead_graph_two"/>
+            <field name="domain">[('type','=', 'lead'),('section_id', '=', active_id)]</field>
+            <field name="help">Leads Analysis allows you to check different CRM related information like the treatment delays or number of leads per state. You can sort out your leads analysis by different groups to get accurate grained analysis.</field>
+        </record>
+        <record id="action_report_crm_opportunity_salesteam" model="ir.actions.act_window">
+             <field name="name">Opportunities Analysis</field>
+             <field name="res_model">crm.lead.report</field>
+             <field name="view_mode">graph</field>
+             <field name="view_id" ref="crm.view_report_crm_opportunity_graph"/>
+             <field name="domain">[('type','=', 'opportunity'), ('section_id', '=', active_id)]</field>
+             <field name="help">Opportunities Analysis gives you an instant access to your opportunities with information such as the expected revenue, planned cost, missed deadlines or the number of interactions per opportunity. This report is mainly used by the sales manager in order to do the periodic review with the teams of the sales pipeline.</field>
+         </record>
+         <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="inherit_id" ref="sales_team.crm_case_section_salesteams_view_kanban"/>
+             <field name="arch" type="xml">
+                 <data>
+                     <xpath expr="//templates" position="before">
+                         <field name="alias_id"/>
+                         <field name="use_leads"/>
++                        <field name="use_opportunities"/>
+                         <field name="monthly_open_leads"/>
+                         <field name="monthly_planned_revenue"/>
+                     </xpath>
+                     <xpath expr="//h4[@name='name']" position="after">
+                         <div class="oe_kanban_alias oe_center" t-if="record.use_leads.raw_value and record.alias_id.value">
+                             <small><span class="oe_e oe_e_alias" style="float: none;">%%</span><t t-raw="record.alias_id.raw_value[1]"/></small>
+                         </div>
+                         <div class="oe_items_list">
+                             <div class="oe_salesteams_leads" t-if="record.use_leads.raw_value">
+                                 <a name="%(crm_case_form_view_salesteams_lead)d" type="action">Leads</a>
+                                 <a name="%(action_report_crm_lead_salesteam)d" type="action" class="oe_sparkline_bar_link">
+                                     <field name="monthly_open_leads" widget="sparkline_bar"
+                                         options="{'height': '20px', 'barWidth': 4, 'barSpacing': 1, 'delayIn': '3000', 'tooltip_suffix': ' Leads'}">Open Leads per Month<br/>Click to see a detailed analysis of leads.</field>
+                                 </a>
+                             </div>
 -                            <div class="oe_salesteams_opportunities">
++                            <div class="oe_salesteams_opportunities" t-if="record.use_opportunities.raw_value">
+                                 <a name="%(crm_case_form_view_salesteams_opportunity)d" type="action">Opportunities</a>
+                                 <a name="%(action_report_crm_opportunity_salesteam)d" type="action">
+                                     <field name="monthly_planned_revenue" widget="sparkline_bar"
+                                         options="{'height': '20px', 'barWidth': '4', 'barSpacing': '1', 'delayIn': '3000', 'tooltip_suffix': ' (Planned Revenue)'}">Planned Revenue per Month<br/>Click to see a detailed analysis of opportunities.</field>
+                                 </a>
+                             </div>
+                         </div>
+                     </xpath>
+                 </data>
+             </field>
+         </record>
+         <record model="ir.ui.view" id="sales_team_form_view_in_crm">
+                 <field name="name">crm.case.section.form</field>
+                 <field name="model">crm.case.section</field>
+                 <field name="inherit_id" ref="sales_team.crm_case_section_view_form"/>
+                 <field name="arch" type="xml">
 -                    <xpath expr="//field[@name='name']" position="after">
 -                        <h6><field name="use_leads"/><label for="use_leads" string="Leads"/></h6>
++                    <xpath expr="//div[@name='options_active']" position="inside">
++                        <field name="use_leads"/><label for="use_leads" string="Leads"/>
++                        <field name="use_opportunities" class="oe_inline"/><label for="use_opportunities"/>
+                     </xpath>
+                     <xpath expr="//group/field[@name='active']" position="inside">
+                         <group>
+                             <label for="alias_name" string="Email Alias"
+                                     attrs="p'invisible': [('alias_domain', '=', False)]}"/>
+                             <div name="alias_def"
+                                     attrs="{'invisible': [('alias_domain', '=', False)]}">
+                                 <field name="alias_id" class="oe_read_only oe_inline"
+                                         string="Email Alias" required="0"/>
+                                 <div class="oe_edit_only oe_inline" name="edit_alias" style="display: inline;" >
+                                     <field name="alias_name" class="oe_inline"/>@<field name="alias_domain" class="oe_inline" readonly="1"/>
+                                 </div>
+                             </div>
+                             <field name="alias_contact" class="oe_inline"
+                                     string="Accept Emails From"
+                                     attrs="{'invisible': [('alias_domain', '=', False)]}"/>
+                         </group>
+                     </xpath>
+                     <xpath expr="//page[@string='Team Members']" position="after">
+                         <page string="Stages">
+                             <separator string="Select Stages for this Sales Team"/>
+                                 <field name="stage_ids"/>
+                         </page>
+                    </xpath>
+                 </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="sales_team.crm_case_section_view_tree"/>
+         </record>
+   </data>
+ </openerp>
index 0000000,10acac1..ba9f3e3
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,61 +1,66 @@@
+ # -*- coding: utf-8 -*-
+ import calendar
+ from datetime import date
+ from dateutil import relativedelta
+ from openerp import tools
+ from openerp.osv import fields, osv
+ class crm_case_section(osv.osv):
+     _inherit = 'crm.case.section'
+     def _get_sale_orders_data(self, cr, uid, ids, field_name, arg, context=None):
+         obj = self.pool.get('sale.order')
+         res = dict.fromkeys(ids, False)
+         month_begin = date.today().replace(day=1)
+         date_begin = (month_begin - relativedelta.relativedelta(months=self._period_number - 1)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
+         date_end = month_begin.replace(day=calendar.monthrange(month_begin.year, month_begin.month)[1]).strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
+         for id in ids:
+             res[id] = dict()
 -            created_domain = [('section_id', '=', id), ('state', '=', ['draft']), ('date_order', '>=', date_begin), ('date_order', '<=', date_end)]
++            created_domain = [('section_id', '=', id), ('state', '=', 'draft'), ('date_order', '>=', date_begin), ('date_order', '<=', date_end)]
+             res[id]['monthly_quoted'] = self.__get_bar_values(cr, uid, obj, created_domain, ['amount_total', 'date_order'], 'amount_total', 'date_order', context=context)
+             validated_domain = [('section_id', '=', id), ('state', 'not in', ['draft', 'sent', 'cancel']), ('date_order', '>=', date_begin), ('date_order', '<=', date_end)]
+             res[id]['monthly_confirmed'] = self.__get_bar_values(cr, uid, obj, validated_domain, ['amount_total', 'date_order'], 'amount_total', 'date_order', context=context)
+         return res
+     def _get_invoices_data(self, cr, uid, ids, field_name, arg, context=None):
+         obj = self.pool.get('account.invoice.report')
+         res = dict.fromkeys(ids, False)
+         month_begin = date.today().replace(day=1)
+         date_begin = (month_begin - relativedelta.relativedelta(months=self._period_number - 1)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
+         date_end = month_begin.replace(day=calendar.monthrange(month_begin.year, month_begin.month)[1]).strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
+         for id in ids:
+             created_domain = [('section_id', '=', id), ('state', 'not in', ['draft', 'cancel']), ('date', '>=', date_begin), ('date', '<=', date_end)]
+             res[id] = self.__get_bar_values(cr, uid, obj, created_domain, ['price_total', 'date'], 'price_total', 'date', context=context)
+         return res
+     _columns = {
++        'use_quotations': fields.boolean('Opportunities', help="Check this box to manage quotations in this sales team."),
+         'invoiced_forecast': fields.integer(string='Invoice Forecast',
+             help="Forecast of the invoice revenue for the current month. This is the amount the sales \n"
+                     "team should invoice this month. It is used to compute the progression ratio \n"
+                     " of the current and forecast revenue on the kanban view."),
+         'invoiced_target': fields.integer(string='Invoice Target',
+             help="Target of invoice revenue for the current month. This is the amount the sales \n"
+                     "team estimates to be able to invoice this month."),
+         'monthly_quoted': fields.function(_get_sale_orders_data,
+             type='string', readonly=True, multi='_get_sale_orders_data',
+             string='Rate of created quotation per duration'),
+         'monthly_confirmed': fields.function(_get_sale_orders_data,
+             type='string', readonly=True, multi='_get_sale_orders_data',
+             string='Rate of validate sales orders per duration'),
+         'monthly_invoiced': fields.function(_get_invoices_data,
+             type='string', readonly=True,
+             string='Rate of sent invoices per duration'),
+     }
++    _defaults = {
++        'use_quotations': True,
++    }
++
+     def action_forecast(self, cr, uid, id, value, context=None):
+         return self.write(cr, uid, [id], {'invoiced_forecast': round(float(value))}, context=context)
+ # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
index 0000000,c577a67..922caa9
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,74 +1,78 @@@
+ <?xml version="1.0" encoding="utf-8"?>
+ <openerp>
+     <data>
+         <record id="crm_case_section_salesteams_view_form" model="ir.ui.view">
+             <field name="name">crm.case.section.form</field>
+             <field name="model">crm.case.section</field>
+             <field name="inherit_id" ref="sales_team.crm_case_section_view_form"/>
+             <field name="arch" type="xml">
+             <data>
++                <xpath expr="//div[@name='options_active']" position="inside">
++                    <field name="use_quotations" class="oe_inline"/><label for="use_quotations"/>
++                </xpath>
+                 <xpath expr="//field[@name='code']" position="after">
+                     <field name="invoiced_target"/>
+                     <field name="invoiced_forecast"/>
+                 </xpath>
+             </data>
+             </field>
+         </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="sales_team.crm_case_section_salesteams_view_kanban"/>
+             <field name="arch" type="xml">
+             <data>
+                 <xpath expr="//field[@name='name']" position="after">
++                    <field name="use_quotations"/>
+                     <field name="monthly_quoted"/>
+                     <field name="monthly_confirmed"/>
+                     <field name="monthly_invoiced"/>
+                     <field name="invoiced_forecast"/>
+                     <field name="invoiced_target"/>
+                 </xpath>
+                 <xpath expr="//div[@class='oe_clear']" position="before">
+                     <div class="oe_items_list">
 -                        <div class="oe_salesteams_quotations">
++                        <div class="oe_salesteams_quotations" t-if="record.use_quotations.raw_value">
+                             <a name="%(action_quotations_salesteams)d" type="action" class="oe_sparkline_bar_link">Quotations</a>
+                             <a name="%(action_order_report_quotation_salesteam)d" type="action" class="oe_sparkline_bar_link">
+                                 <field name="monthly_quoted" widget="sparkline_bar" options="{'delayIn': '3000'}">
+                                     Revenue of created quotations per month.<br/>Click to see a detailed analysis.
+                                 </field>
+                             </a>
+                         </div>
+                         <div class="oe_salesteams_orders">
+                             <a name="%(action_orders_salesteams)d" type="action">Sales Orders</a>
+                             <a name="%(action_order_report_so_salesteam)d" type="action" class="oe_sparkline_bar_link">
+                                 <field name="monthly_confirmed" widget="sparkline_bar" options="{'delayIn': '3000'}">
+                                     Revenue of confirmed sales orders per month.<br/>Click to acces the Sales Analysis.
+                                 </field>
+                             </a>
+                         </div>
+                         <div class="oe_salesteams_invoices" groups="account.group_account_invoice">
+                             <a name="%(action_invoice_salesteams)d" type="action">Invoices</a>
+                             <a name="%(action_account_invoice_report_salesteam)d" type="action" class="oe_sparkline_bar_link">
+                                 <field name="monthly_invoiced" widget="sparkline_bar" options="{'delayIn': '3000'}">
+                                     Revenue of sent invoices per month.<br/>Click to see a detailed analysis of invoices.
+                                 </field>
+                             </a>
+                         </div>
+                       </div>
+                 </xpath>
+                 <xpath expr="//div[@class='oe_clear']" position="after">
+                     <div class="oe_center" t-if="record.invoiced_target.raw_value">
+                         <field name="monthly_invoiced" widget="gauge" style="width:160px; height: 120px; cursor: pointer;"
+                             options="{'max_field': 'invoiced_target'}">Invoiced</field>
+                         <field name="invoiced_forecast" widget="gauge" style="width:160px; height: 120px; cursor: pointer;"
+                             options="{'max_field': 'invoiced_target', 'on_change': 'action_forecast'}">Forecast</field>
+                     </div>
+                     <div class="oe_center oe_salesteams_help" style="color:#bbbbbb;" t-if="!record.invoiced_target.raw_value">
+                         <br/>Define an invoicing target in the sales team settings to see the period's achievement and forecast at a glance.
+                     </div>
+                 </xpath>
+             </data>
+            </field>
+         </record>
+     </data>
+ </openerp>
@@@ -45,103 -32,5 +32,3 @@@ class sale_order(osv.osv)
          'categ_ids': fields.many2many('crm.case.categ', 'sale_order_category_rel', 'order_id', 'category_id', 'Tags', \
              domain="['|', ('section_id', '=', section_id), ('section_id', '=', False), ('object_id.model', '=', 'crm.lead')]", context="{'object_name': 'crm.lead'}")
      }
-     def _get_default_section_id(self, cr, uid, context=None):
-         """ Gives default section by checking if present in the context """
-         section_id = self.pool.get('crm.lead')._resolve_section_id_from_context(cr, uid, context=context) or False
-         if not section_id:
-             section_id = self.pool.get('res.users').browse(cr, uid, uid, context).default_section_id.id or False
-         return section_id
-     _defaults = {
-         'section_id': lambda s, cr, uid, c: s._get_default_section_id(cr, uid, c),
-     }
-     def _prepare_invoice(self, cr, uid, order, lines, context=None):
-         invoice_vals = super(sale_order, self)._prepare_invoice(cr, uid, order, lines, context=context)
-         if order.section_id and order.section_id.id:
-             invoice_vals['section_id'] = order.section_id.id
-         return invoice_vals
- class crm_case_section(osv.osv):
-     _inherit = 'crm.case.section'
-     def _get_sale_orders_data(self, cr, uid, ids, field_name, arg, context=None):
-         obj = self.pool.get('sale.order')
-         res = dict.fromkeys(ids, False)
-         month_begin = date.today().replace(day=1)
-         date_begin = (month_begin - relativedelta.relativedelta(months=self._period_number - 1)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
-         date_end = month_begin.replace(day=calendar.monthrange(month_begin.year, month_begin.month)[1]).strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
-         for id in ids:
-             res[id] = dict()
-             created_domain = [('section_id', '=', id), ('state', '=', 'draft'), ('date_order', '>=', date_begin), ('date_order', '<=', date_end)]
-             res[id]['monthly_quoted'] = self.__get_bar_values(cr, uid, obj, created_domain, ['amount_total', 'date_order'], 'amount_total', 'date_order', context=context)
-             validated_domain = [('section_id', '=', id), ('state', 'not in', ['draft', 'sent', 'cancel']), ('date_order', '>=', date_begin), ('date_order', '<=', date_end)]
-             res[id]['monthly_confirmed'] = self.__get_bar_values(cr, uid, obj, validated_domain, ['amount_total', 'date_order'], 'amount_total', 'date_order', context=context)
-         return res
-     def _get_invoices_data(self, cr, uid, ids, field_name, arg, context=None):
-         obj = self.pool.get('account.invoice.report')
-         res = dict.fromkeys(ids, False)
-         month_begin = date.today().replace(day=1)
-         date_begin = (month_begin - relativedelta.relativedelta(months=self._period_number - 1)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
-         date_end = month_begin.replace(day=calendar.monthrange(month_begin.year, month_begin.month)[1]).strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
-         for id in ids:
-             created_domain = [('section_id', '=', id), ('state', 'not in', ['draft', 'cancel']), ('date', '>=', date_begin), ('date', '<=', date_end)]
-             res[id] = self.__get_bar_values(cr, uid, obj, created_domain, ['price_total', 'date'], 'price_total', 'date', context=context)
-         return res
-     _columns = {
-         'use_quotations': fields.boolean('Opportunities', help="Check this box to manage quotations in this sales team."),
-         'invoiced_forecast': fields.integer(string='Invoice Forecast',
-             help="Forecast of the invoice revenue for the current month. This is the amount the sales \n"
-                     "team should invoice this month. It is used to compute the progression ratio \n"
-                     " of the current and forecast revenue on the kanban view."),
-         'invoiced_target': fields.integer(string='Invoice Target',
-             help="Target of invoice revenue for the current month. This is the amount the sales \n"
-                     "team estimates to be able to invoice this month."),
-         'monthly_quoted': fields.function(_get_sale_orders_data,
-             type='string', readonly=True, multi='_get_sale_orders_data',
-             string='Rate of created quotation per duration'),
-         'monthly_confirmed': fields.function(_get_sale_orders_data,
-             type='string', readonly=True, multi='_get_sale_orders_data',
-             string='Rate of validate sales orders per duration'),
-         'monthly_invoiced': fields.function(_get_invoices_data,
-             type='string', readonly=True,
-             string='Rate of sent invoices per duration'),
-     }
-     _defaults = {
-         'use_quotations': True,
-     }
-     def action_forecast(self, cr, uid, id, value, context=None):
-         return self.write(cr, uid, [id], {'invoiced_forecast': round(float(value))}, context=context)
- class sale_crm_lead(osv.Model):
-     _inherit = 'crm.lead'
-     def on_change_user(self, cr, uid, ids, user_id, context=None):
-         """ Override of on change user_id on lead/opportunity; when having sale
-             the new logic is :
-             - use user.default_section_id
-             - or fallback on previous behavior """
-         if user_id:
-             user = self.pool.get('res.users').browse(cr, uid, user_id, context=context)
-             if user.default_section_id and user.default_section_id.id:
-                 return {'value': {'section_id': user.default_section_id.id}}
-         return super(sale_crm_lead, self).on_change_user(cr, uid, ids, user_id, context=context)
- class account_invoice(osv.osv):
-     _inherit = 'account.invoice'
-     _columns = {
-         'section_id': fields.many2one('crm.case.section', 'Sales Team'),
-     }
-     _defaults = {
-         'section_id': lambda self, cr, uid, c=None: self.pool.get('res.users').browse(cr, uid, uid, c).default_section_id.id or False,
-     }
- # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
 -    
 -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
index 0000000,67907c3..5ac8e24
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,210 +1,211 @@@
+ <?xml version="1.0" encoding="utf-8"?>
+ <openerp>
+   <data>
+         <menuitem name="Sales"
+             id="base.menu_base_partner"
+             groups="base.group_sale_salesman,base.group_sale_manager"/>
+  <!-- Update user form !-->
+         <record model="ir.ui.view" id="res_user_form">
+             <field name="name">Users Preferences</field>
+             <field name="model">res.users</field>
+             <field name="inherit_id" ref="base.view_users_form"/>
+             <field name="arch" type="xml">
+                 <data>
+                     <xpath expr="//field[@name='tz']" position="after">
+                         <field name="default_section_id"/>
+                     </xpath>
+                 </data>
+             </field>
+         </record>
+         <!-- Update Preferences form !-->
+         <record id="view_users_form_preferences" model="ir.ui.view">
+             <field name="name">res.users.preferences.form</field>
+             <field name="model">res.users</field>
+             <field name="inherit_id" ref="base.view_users_form_simple_modif"/>
+             <field name="arch" type="xml">
+                 <data>
+                     <xpath expr="//field[@name='company_id']" position="before">
+                         <field name="default_section_id" readonly="0"/>
+                     </xpath>
+                 </data>
+             </field>
+         </record>
+         <!-- Case Sections Salesteams kanban view -->
+        <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="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="color"/>
+                     <templates>
+                         <t t-name="kanban-box">
+                             <div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click oe_kanban_crm_salesteams">
+                                 <div class="oe_dropdown_toggle oe_dropdown_kanban" groups="base.group_sale_manager">
+                                     <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 class="oe_center" name="name"><field name="name"/></h4>
+                                     <div class="oe_clear"></div>
+                                     <div class="oe_kanban_salesteams_avatars">
+                                         <t t-foreach="record.member_ids.raw_value.slice(0,10)" 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 Search view -->
+         <record id="crm_case_section_salesteams_search" model="ir.ui.view">
+             <field name="name">Case Sections - Search</field>
+             <field name="model">crm.case.section</field>
+             <field name="arch" type="xml">
+                 <search string="Salesteams Search">
+                     <filter name="personal" string="My Salesteams" domain="['|', ('member_ids', '=', uid), ('user_id', '=', uid)]"/>
+                     <field name="name"/>
+                     <field name="parent_id"/>
+                     <field name="user_id"/>
+                     <field name="note"/>
+                     <field name="code"/>
+                     <group expand="0" string="Group By...">
+                         <filter string="Team Leader" domain="[]" context="{'group_by':'user_id'}"/>
+                         <filter string="Parent Sales Teams" domain="[]" context="{'group_by':'parent_id'}"/>
+                     </group>
+                 </search>
+             </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="context">{}</field>
+             <field name="view_id" ref="crm_case_section_salesteams_search"/>
+             <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>
+                         <div class="oe_title">
+                             <label for="name" class="oe_edit_only" string="Sales team"/>
+                             <h1>
+                                 <field name="name" string="Salesteam"/>
+                             </h1>
++                            <div name="options_active"></div>
+                         </div>
+                         <group>
+                             <group>
+                                 <field name="user_id" context="{'default_groups_ref': ['base.group_user', 'base.group_partner_manager', 'base.group_sale_salesman_all_leads']}"/>
+                                 <field name="code"/>
+                                 <field name="parent_id"/>
+                                 <field name="change_responsible"/>
+                                 <field name="active"/>
+                             </group>
+                         </group>
+                         <notebook colspan="4">
+                             <page 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="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>
+         <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 id="sales_team.menu_sales_team_act" action="crm_case_section_salesteams_act" sequence="1" parent="base.menu_sales" groups="base.group_multi_salesteams"/>
+         <!-- add css / js -->
+         <template id="assets_backend" name="sales_team assets" inherit_id="web.assets_backend">
+             <xpath expr="." position="inside">
+                 <link rel="stylesheet" href="/sales_team/static/src/css/sales_team.css"/>
+                 <script type="text/javascript" src="/sales_team/static/src/js/sales_team.js"></script>
+             </xpath>
+         </template>
+     </data>
+ </openerp>