[MERGE] various: improve search filters, menu organizations and some labels

Impacted applications: crm (and dependencies), sale (and website_sale), point
of sale, accounting, purchase, base/mail, calendar, mrp.

This commit is related to task #1878516 and closes PR #26929 .
This commit is contained in:
Thibault Delavallée
2018-09-19 13:25:10 +02:00
32 changed files with 122 additions and 243 deletions
@@ -27,8 +27,8 @@ class AccountInvoiceReport(models.Model):
record.user_currency_price_average = base_currency_id._convert(record.price_average, user_currency_id, company, date)
record.user_currency_residual = base_currency_id._convert(record.residual, user_currency_id, company, date)
number = fields.Char('Invoice Number', readonly=True)
date = fields.Date(readonly=True)
number = fields.Char('Invoice #', readonly=True)
date = fields.Date(readonly=True, string="Invoice Date")
product_id = fields.Many2one('product.product', string='Product', readonly=True)
product_qty = fields.Float(string='Product Quantity', readonly=True)
uom_name = fields.Char(string='Reference Unit of Measure', readonly=True)
@@ -41,7 +41,7 @@ class AccountInvoiceReport(models.Model):
commercial_partner_id = fields.Many2one('res.partner', string='Partner Company', help="Commercial Entity")
company_id = fields.Many2one('res.company', string='Company', readonly=True)
user_id = fields.Many2one('res.users', string='Salesperson', readonly=True)
price_total = fields.Float(string='Total Without Tax', readonly=True)
price_total = fields.Float(string='Untaxed Total', readonly=True)
user_currency_price_total = fields.Float(string="Total Without Tax in Currency", compute='_compute_amounts_in_user_currency', digits=0)
price_average = fields.Float(string='Average Price', readonly=True, group_operator="avg")
user_currency_price_average = fields.Float(string="Average Price in Currency", compute='_compute_amounts_in_user_currency', digits=0)
@@ -61,13 +61,14 @@ class AccountInvoiceReport(models.Model):
('cancel', 'Cancelled')
], string='Invoice Status', readonly=True)
date_due = fields.Date(string='Due Date', readonly=True)
account_id = fields.Many2one('account.account', string='Account', readonly=True, domain=[('deprecated', '=', False)])
account_line_id = fields.Many2one('account.account', string='Account Line', readonly=True, domain=[('deprecated', '=', False)])
account_id = fields.Many2one('account.account', string='Receivable/Payable Account', readonly=True, domain=[('deprecated', '=', False)])
account_line_id = fields.Many2one('account.account', string='Revenue/Expense Account', readonly=True, domain=[('deprecated', '=', False)])
partner_bank_id = fields.Many2one('res.partner.bank', string='Bank Account', readonly=True)
residual = fields.Float(string='Due Amount', readonly=True)
user_currency_residual = fields.Float(string="Total Residual", compute='_compute_amounts_in_user_currency', digits=0)
country_id = fields.Many2one('res.country', string='Country of the Partner Company')
country_id = fields.Many2one('res.country', string="Partner Company's Country")
account_analytic_id = fields.Many2one('account.analytic.account', string='Analytic Account', groups="analytic.group_analytic_accounting")
amount_total = fields.Float(string='Total', readonly=True)
_order = 'date desc'
@@ -95,7 +96,7 @@ class AccountInvoiceReport(models.Model):
sub.payment_term_id, sub.uom_name, sub.currency_id, sub.journal_id,
sub.fiscal_position_id, sub.user_id, sub.company_id, sub.nbr, sub.invoice_id, sub.type, sub.state,
sub.categ_id, sub.date_due, sub.account_id, sub.account_line_id, sub.partner_bank_id,
sub.product_qty, sub.price_total as price_total, sub.price_average as price_average,
sub.product_qty, sub.price_total as price_total, sub.price_average as price_average, sub.amount_total as amount_total,
COALESCE(cr.rate, 1) as currency_rate, sub.residual as residual, sub.commercial_partner_id as commercial_partner_id
"""
return select_str
@@ -113,6 +114,7 @@ class AccountInvoiceReport(models.Model):
ai.partner_bank_id,
SUM ((invoice_type.sign_qty * ail.quantity) / u.factor * u2.factor) AS product_qty,
SUM(ail.price_subtotal_signed * invoice_type.sign) AS price_total,
SUM(ai.amount_total * invoice_type.sign) AS amount_total,
SUM(ABS(ail.price_subtotal_signed)) / CASE
WHEN SUM(ail.quantity / u.factor * u2.factor) <> 0::numeric
THEN SUM(ail.quantity / u.factor * u2.factor)
@@ -69,31 +69,29 @@
<filter string="My Invoices" name="my_invoice" domain="[('user_id', '=', uid)]"/>
<separator/>
<field name="date"/>
<filter string="This Year" name="thisyear" domain="['|', ('date', '=', False), '&amp;',('date','&lt;=', time.strftime('%%Y-12-31')),('date','&gt;=',time.strftime('%%Y-01-01'))]" help="Journal invoices with period in current year"/>
<separator/>
<filter string="To Invoice" name="toinvoice" domain="[('state','=','draft')]" help = "Draft Invoices"/>
<filter string="Invoiced" name="current" domain="[('state','not in', ('draft','cancel'))]"/>
<separator/>
<filter string="Date" name="date_filter" date="date"/>
<filter string="Customer" name="customer" domain="['|', ('type','=','out_invoice'),('type','=','out_refund')]"/>
<filter string="Vendor" name="supplier" domain="['|', ('type','=','in_invoice'),('type','=','in_refund')]"/>
<filter string="Customers" name="customer" domain="['|', ('type','=','out_invoice'),('type','=','out_refund')]"/>
<filter string="Vendors" name="supplier" domain="['|', ('type','=','in_invoice'),('type','=','in_refund')]"/>
<separator/>
<filter string="Invoice" name="invoice" domain="['|', ('type','=','out_invoice'),('type','=','in_invoice')]"/>
<filter string="Credit Note" name="creditnote" domain="['|', ('type','=','out_refund'),('type','=','in_refund')]"/>
<filter string="Invoices" name="invoice" domain="['|', ('type','=','out_invoice'),('type','=','in_invoice')]"/>
<filter string="Credit Notes" name="creditnote" domain="['|', ('type','=','out_refund'),('type','=','in_refund')]"/>
<field name="partner_id" operator="child_of"/>
<field name="user_id" />
<field name="product_id" />
<field name="categ_id" filter_domain="[('categ_id', 'child_of', self)]"/>
<field name="account_analytic_id"/>
<group expand="1" string="Group By">
<filter string="Partner" name="partner_id" context="{'group_by':'partner_id','residual_visible':True}"/>
<filter string="Salesperson" name='user' context="{'group_by':'user_id'}"/>
<filter string="Partner" name="partner_id" context="{'group_by':'partner_id','residual_visible':True}"/>
<filter string="Product Category" name="category_product" context="{'group_by':'categ_id','residual_invisible':True}"/>
<filter string="Status" name="status" context="{'group_by':'state'}"/>
<filter string="Analytic Account" name="account_analytic_id" context="{'group_by':'account_analytic_id'}" groups="analytic.group_analytic_accounting" />
<filter string="Company" name="company" context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
<separator orientation="vertical" />
<filter string="Date" name="date" context="{'group_by':'date'}"/>
<filter string="Due Date" name="duemonth" context="{'group_by':'date_due:month'}"/>
<filter string="Analytic Account" name="account_analytic_id" context="{'group_by':'account_analytic_id'}" groups="analytic.group_analytic_accounting" />
</group>
</search>
</field>
@@ -118,7 +116,7 @@
<field name="help">From this report, you can have an overview of the amount invoiced to your customers. The search tool can also be used to personalise your Invoices reports and so, match this analysis to your needs.</field>
</record>
<menuitem name="Invoices" action="action_account_invoice_report_all" id="menu_action_account_invoice_report_all" parent="account.account_reports_management_menu" sequence="25"/>
<menuitem name="Invoices" action="action_account_invoice_report_all" id="menu_action_account_invoice_report_all" parent="account.account_reports_management_menu" sequence="1"/>
</data>
</odoo>
@@ -632,7 +632,8 @@
<field name="arch" type="xml">
<search string="Search Invoice">
<field name="number" string="Invoice" filter_domain="['|','|','|', ('number','ilike',self), ('origin','ilike',self), ('reference', 'ilike', self), ('partner_id', 'child_of', self)]"/>
<field name="journal_id" />
<filter domain="[('user_id','=',uid)]" name="myinvoices" help="My Invoices"/>
<separator/>
<filter name="draft" string="Draft" domain="[('state','=','draft')]"/>
<filter name="unpaid" string="Open" domain="[('state', '=', 'open')]"/>
<filter name="in_payment" string="In Payment" domain="[('state', '=', 'in_payment')]"/>
@@ -643,8 +644,6 @@
<field name="user_id" string="Salesperson" domain="[('share','=', False)]"/>
<field name="date" string="Period"/>
<separator/>
<filter domain="[('user_id','=',uid)]" name="myinvoices" help="My Invoices"/>
<separator/>
<filter string="My Activities" name="activities_my"
domain="[('activity_ids.user_id', '=', uid)]"/>
<separator/>
-2
View File
@@ -291,9 +291,7 @@
<field name="user_id"/>
<field name="show_as"/>
<field name="privacy" string="Privacy"/>
<filter string="My Events" name="myevents" domain="[('user_id','=',uid)]" help="My Events"/>
<filter string="My Meetings" help="My Meetings" name="mymeetings" context='{"mymeetings": 1}'/>
<filter string="Unread Messages" name="message_needaction" domain="[('message_needaction','=',True)]"/>
<separator/>
<group expand="0" string="Group By">
<filter string="Responsible" name="responsible" domain="[]" context="{'group_by':'user_id'}"/>
@@ -67,7 +67,7 @@
groups="sales_team.group_sale_manager"
parent="crm_menu_report"
action="crm_activity_report_action"
sequence="6"/>
sequence="3"/>
<record id="crm_activity_report_action_team" model="ir.actions.act_window">
<field name="name">Activities Analysis</field>
@@ -126,7 +126,7 @@ mainly used by the sales manager in order to do the periodic review with the
teams of the sales pipeline.</field>
</record>
<menuitem id="crm_opportunity_report_menu" name="Pipeline"
parent="crm_menu_report" action="crm_opportunity_report_action" sequence="5"/>
parent="crm_menu_report" action="crm_opportunity_report_action" sequence="2"/>
<record id="crm_opportunity_report_action_graph" model="ir.actions.act_window">
<field name="name">Pipeline Analysis</field>
+22 -15
View File
@@ -830,21 +830,28 @@ for rec in records:
Menu Actions
-->
<menuitem
id="crm_menu_pipeline"
name="Pipeline"
id="crm_menu_sales"
name="Sales"
parent="crm_menu_root"
sequence="1"/>
<menuitem id="res_partner_menu_crm"
parent="crm_menu_root"
action="base.action_partner_form"
sequence="2"/>
<menuitem id="sales_team_menu_report_crm"
name="Sales Teams"
parent="crm_menu_pipeline"
<menuitem id="sales_team_menu_team_pipeline"
name="Team Pipelines"
parent="crm_menu_sales"
action="sales_team.crm_team_salesteams_act"
sequence="10"/>
sequence="4"/>
<menuitem id="res_partner_menu_customer"
name="Customers"
parent="crm_menu_sales"
action="base.action_partner_form"
sequence="5"/>
<menuitem id="crm_menu_leads"
name="Leads"
parent="crm_menu_root"
groups="crm.group_use_lead"
sequence="5"/>
<!-- Lead Menu -->
<record model="ir.actions.act_window" id="crm_lead_all_leads">
@@ -899,7 +906,7 @@ for rec in records:
<menuitem
id="menu_crm_leads"
name="Leads"
parent="crm_menu_pipeline"
parent="crm_menu_leads"
sequence="1"
action="crm_lead_all_leads"
groups="crm.group_use_lead"/>
@@ -1025,9 +1032,9 @@ for rec in records:
<menuitem
id="menu_crm_opportunities"
action="action_your_pipeline"
name="Pipeline"
parent="crm_menu_pipeline"
sequence="5"/>
name="My Pipeline"
parent="crm_menu_sales"
sequence="1"/>
<menuitem
id="crm.crm_menu_root"
+1 -1
View File
@@ -34,7 +34,7 @@
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_res_partner_filter"/>
<field name="arch" type="xml">
<filter name="supplier" position="after">
<filter name="inactive" position="after">
<separator />
<filter string="My Activities" name="activities_my"
domain="[('activity_ids.user_id', '=', uid)]"/>
+2 -3
View File
@@ -255,11 +255,11 @@
help="Manufacturing Orders which are in confirmed state."/>
<separator/>
<filter string="Confirmed" name="confirmed" domain="[('state','=','confirmed')]"/>
<filter string="Waiting for Materials" name="waiting" domain="[('availability', '=', 'waiting')]"/>
<filter string="Planned" name="planned" domain="[('state','=','planned')]" groups="mrp.group_mrp_routings"/>
<filter string="In Progress" name="inprogress" domain="[('state','=','progress')]"
help="Manufacturing Orders which are currently in production."/>
<filter string="Done" name="done" domain="[('state', '=', 'done')]"/>
<filter string="Waiting" name="waiting" domain="[('availability', '=', 'waiting')]"/>
<separator/>
<filter string="Late" domain="['&amp;', ('date_planned_start', '&lt;', current_date), ('state', '=', 'confirmed')]"
name="late" help="Production started late"/>
@@ -268,7 +268,6 @@
<filter string="My Activities" name="activities_my"
domain="[('activity_ids.user_id', '=', uid)]"/>
<separator/>
<filter string="No Routing" domain="[('routing_id','=', False)]" name="norouting" groups="mrp.group_mrp_routings"/>
<field name="product_id"/>
<field name="move_raw_ids" string="Raw Material" filter_domain="[('move_raw_ids.product_id','ilike',self)]"/>
<field name="name" string="Work Center" filter_domain="[('routing_id.operation_ids.workcenter_id','ilike',self)]"/>
@@ -285,7 +284,7 @@
<group expand="0" string="Group By...">
<filter string="Product" name="product" domain="[]" context="{'group_by':'product_id'}"/>
<filter string="Routing" name="routing" domain="[]" context="{'group_by':'routing_id'}" groups="mrp.group_mrp_routings"/>
<filter string="Scheduled Month" name="scheduled_month" domain="[]" context="{'group_by':'date_planned_start'}" help="Scheduled Date by Month"/>
<filter string="Scheduled Date" name="scheduled_date" domain="[]" context="{'group_by':'date_planned_start'}" help="Scheduled Date by Month"/>
<filter string="Status" name="status" domain="[]" context="{'group_by': 'state'}"/>
</group>
</search>
@@ -537,8 +537,6 @@
<field name="arch" type="xml">
<search string="Operations">
<field name="workcenter_id"/>
<filter string="Start Date" name="date_start_filter" date="date_start"/>
<separator/>
<field name="workcenter_id"/>
<field name="loss_id"/>
<separator/>
+1 -1
View File
@@ -483,7 +483,7 @@ class PosOrder(models.Model):
company_id = fields.Many2one('res.company', string='Company', required=True, readonly=True, default=lambda self: self.env.user.company_id)
date_order = fields.Datetime(string='Order Date', readonly=True, index=True, default=fields.Datetime.now)
user_id = fields.Many2one(
comodel_name='res.users', string='Salesman',
comodel_name='res.users', string='Salesperson',
help="Person who uses the cash register. It can be a reliever, a student or an interim employee.",
default=lambda self: self.env.uid,
states={'done': [('readonly', True)], 'invoiced': [('readonly', True)]},
@@ -10,7 +10,7 @@ class PosOrderReport(models.Model):
_auto = False
_order = 'date desc'
date = fields.Datetime(string='Date Order', readonly=True)
date = fields.Datetime(string='Order Date', readonly=True)
order_id = fields.Many2one('pos.order', string='Order', readonly=True)
partner_id = fields.Many2one('res.partner', string='Customer', readonly=True)
product_id = fields.Many2one('product.product', string='Product', readonly=True)
@@ -29,9 +29,9 @@
<field name="model">account.journal</field>
<field name="inherit_id" ref="account.view_account_journal_search" />
<field name="arch" type="xml">
<field name="name" position="after">
<xpath expr="//filter[@name='inactive']" position="before">
<filter name="available_in_pos" string="Available for Point of Sale" domain="[('journal_user', '=', True)]"/>
</field>
</xpath>
</field>
</record>
@@ -30,12 +30,10 @@
<field name="arch" type="xml">
<search string="Point of Sale Analysis">
<field name="date"/>
<filter string="My Sales" name="my_sales" help="My Sales" domain="[('user_id','=',uid)]"/>
<separator/>
<filter string="Invoiced" name="invoiced" domain="[('state','=',('invoiced'))]"/>
<filter string="Not Invoiced" name="not_invoiced" domain="[('state','=',('paid'))]"/>
<separator/>
<filter string="Order Date" name="filter_date" date="date" default_period="this_year"/>
<separator/>
<filter string="My Sales" name="my_sales" help="My Sales" domain="[('user_id','=',uid)]"/>
<field name="config_id"/>
<field name="partner_id"/>
<field name="user_id"/>
@@ -43,8 +41,9 @@
<field name="product_categ_id"/>
<group expand="1" string="Group By">
<filter string="Salesperson" name="User" context="{'group_by':'user_id'}"/>
<filter string="Product Category" name="product_category" context="{'group_by':'product_categ_id'}"/>
<filter string="Point of Sale" name="pos" context="{'group_by':'config_id'}"/>
<filter string="Product" name="product" context="{'group_by':'product_id'}"/>
<filter string="Product Category" name="product_category" context="{'group_by':'product_categ_id'}"/>
<separator/>
<filter string="Order Date" name="order_month" context="{'group_by':'date:month'}"/>
</group>
@@ -303,9 +303,10 @@
<field name="user_id"/>
<field name="partner_id"/>
<field name="session_id"/>
<field name="config_id"/>
<group expand="0" string="Group By">
<filter string="Customer" name="customer" domain="[]" context="{'group_by':'partner_id'}"/>
<filter string="Salesman" name="salesman" domain="[]" context="{'group_by':'user_id'}"/>
<filter string="Salesperson" name="salesman" domain="[]" context="{'group_by':'user_id'}"/>
<filter string="Session" name="session" domain="[]" context="{'group_by':'session_id'}"/>
<filter string="Status" name="status" domain="[]" context="{'group_by':'state'}"/>
<filter string="Order Date" name="order_month" domain="[]" context="{'group_by':'date_order'}"/>
@@ -9,7 +9,7 @@ class ResConfigSettings(models.TransientModel):
lock_confirmed_po = fields.Boolean("Lock Confirmed Orders", default=lambda self: self.env.user.company_id.po_lock == 'lock')
po_lock = fields.Selection(related='company_id.po_lock', string="Purchase Order Modification *")
po_order_approval = fields.Boolean("Order Approval", default=lambda self: self.env.user.company_id.po_double_validation == 'two_step')
po_order_approval = fields.Boolean("Purchase Order Approval", default=lambda self: self.env.user.company_id.po_double_validation == 'two_step')
po_double_validation = fields.Selection(related='company_id.po_double_validation', string="Levels of Approvals *")
po_double_validation_amount = fields.Monetary(related='company_id.po_double_validation_amount', string="Minimum Amount", currency_field='company_currency_id')
company_currency_id = fields.Many2one('res.currency', related='company_id.currency_id', string="Company Currency", readonly=True,
@@ -69,14 +69,14 @@
</group>
<group expand="1" string="Group By">
<filter string="Vendor" name="group_partner_id" context="{'group_by':'partner_id'}"/>
<filter string="Partner's Country" name="country_id" context="{'group_by':'country_id'}"/>
<filter string="Vendor Country" name="country_id" context="{'group_by':'country_id'}"/>
<filter string="Purchase Representative" name="user_id" context="{'group_by':'user_id'}"/>
<filter string="Product Category" name="group_category_id" context="{'group_by':'category_id'}"/>
<filter string="Order Date" name="order_month" context="{'group_by': 'date_order:month'}"/>
<filter string="Fiscal Position" name="fiscal_position" context="{'group_by':'fiscal_position_id'}" help="Purchase Order Fiscal Position"/>
<filter string="Status" name="status" context="{'group_by':'state'}"/>
<filter string="Company" name="company" context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
<separator/>
<filter string="Fiscal Position" name="fiscal_position" context="{'group_by':'fiscal_position_id'}" help="Purchase Order Fiscal Position"/>
<filter string="Order Date" name="order_month" context="{'group_by': 'date_order:month'}"/>
</group>
</search>
</field>
+2 -2
View File
@@ -283,14 +283,14 @@
<field name="product_id"/>
<field name="create_uid"/>
<field name="user_id"/>
<filter name="my_purchases" string="My Purchases" domain="[('user_id','=', uid)]"/>
<separator/>
<filter name="draft" string="Quotations" domain="[('state','in',('draft','sent','to approve'))]"/>
<filter name="approved" string="Purchase Orders" domain="[('state','in',('purchase','done'))]"/>
<filter name="to_approve" string="To Approve" domain="[('state', '=', 'to approve')]"/>
<filter name="my_purchases" string="My Purchases" domain="[('user_id','=', uid)]"/>
<separator/>
<filter name="not_invoiced" string="Waiting Bills" domain="[('invoice_status','=', 'to invoice')]" help="Purchase orders that include lines not invoiced."/>
<filter name="invoiced" string="Bills Received" domain="[('invoice_status','=', 'invoiced')]" help="Purchase orders that have been invoiced."/>
<filter string="Unread Messages" name="message_needaction" domain="[('message_needaction','=',True)]"/>
<separator/>
<filter string="My Activities" name="activities_my"
domain="[('activity_ids.user_id', '=', uid)]"/>
-1
View File
@@ -32,7 +32,6 @@
<field name="date"/>
<filter string="Date" name="year" invisible="1" date="date" default_period="this_year"/>
<filter name="Quotations" string="Quotations" domain="[('state','=', 'draft')]"/>
<filter name="quotation_sent" string="Quotation Sent" domain="[('state', '=', 'sent')]"/>
<filter name="Sales" string="Sales Orders" domain="[('state','not in',('draft', 'cancel', 'sent'))]"/>
<separator/>
<field name="user_id"/>
+12 -13
View File
@@ -603,8 +603,6 @@
<field name="order_line" string="Product" filter_domain="[('order_line.product_id.name', 'ilike', self)]"/>
<filter string="My Orders" domain="[('user_id','=',uid)]" name="my_sale_orders_filter"/>
<separator/>
<filter string="Unread Messages" name="message_needaction" domain="[('message_needaction','=',True)]"/>
<separator/>
<filter string="My Activities" name="activities_my"
domain="[('activity_ids.user_id', '=', uid)]"/>
<separator/>
@@ -631,14 +629,14 @@
<field name="mode">primary</field>
<field name="inherit_id" ref="sale.view_sales_order_filter"/>
<field name="arch" type="xml">
<xpath expr="//filter[@name='my_sale_orders_filter']" position="after">
<xpath expr="//filter[@name='my_sale_orders_filter']" position="replace">
<separator/>
<filter string="Quotations" name="draft" domain="[('state','=','draft')]"/>
<filter string="Quotations Sent" name="sent" domain="[('state','=','sent')]"/>
<filter string="Sales" name="sales" domain="[('state','in',('sale','done'))]"/>
<filter string="My Quotations" name="my_quotation" domain="[('state','=','draft'), ('user_id','=',uid)]"/>
<separator/>
<filter string="Creation Date" name="filter_create_date" date="create_date"/>
<filter string="Expiration Date" name="filter_validity_date" date="validity_date"/>
<filter string="Quotations" name="draft" domain="[('state','in',('draft', 'sent'))]"/>
<filter string="Sales Orders" name="sales" domain="[('state','in',('sale','done'))]"/>
<separator/>
<filter string="Order Date" name="filter_order_date" date="date_order"/>
</xpath>
</field>
</record>
@@ -650,12 +648,11 @@
<field name="inherit_id" ref="sale.view_sales_order_filter"/>
<field name="arch" type="xml">
<xpath expr="//filter[@name='my_sale_orders_filter']" position="after">
<filter string="To Invoice" name="to_invoice" domain="[('invoice_status','=','to invoice')]" />
<filter string="Upselling" name="upselling" domain="[('invoice_status','=','upselling')]" />
</xpath>
<xpath expr="//filter[@name='activities_upcoming_all']" position="after">
<separator/>
<filter string="Confirmation Date" name="confirmation_date_filter" date="confirmation_date"/>
<filter string="To Invoice" name="to_invoice" domain="[('invoice_status','=','to invoice')]" />
<filter string="To Upsell" name="upselling" domain="[('invoice_status','=','upselling')]" />
<separator/>
<filter string="Order Date" name="order_date" date="date_order"/>
</xpath>
</field>
</record>
@@ -790,6 +787,7 @@
<field name="view_id" ref="view_quotation_tree_with_onboarding"/>
<field name="view_mode">tree,kanban,form,calendar,pivot,graph</field>
<field name="search_view_id" ref="sale_order_view_search_inherit_quotation"/>
<field name="context">{'search_default_my_quotation': 1}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create a new quotation, the first step of a new sale!
@@ -804,6 +802,7 @@
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.order</field>
<field name="search_view_id" ref="sale_order_view_search_inherit_quotation"/>
<field name="context">{'search_default_my_quotation': 1}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create a new quotation, the first step of a new sale!
+3
View File
@@ -29,6 +29,9 @@
<xpath expr="//group/filter[@name='user']" position="after">
<filter string="Sales Team" name="sales_channel" domain="[]" context="{'group_by':'team_id'}"/>
</xpath>
<xpath expr="//field[@name='user_id']" position="after">
<field name="team_id"/>
</xpath>
</field>
</record>
+3 -2
View File
@@ -47,8 +47,9 @@
<!-- This menu is display in CRM app when sale is installed-->
<menuitem
id="sale_order_menu_quotations_crm"
name="My Quotations"
action="sale.action_quotations"
parent="crm.crm_menu_pipeline"
sequence="10"/>
parent="crm.crm_menu_sales"
sequence="2"/>
</odoo>
+2 -1
View File
@@ -22,11 +22,12 @@
<!-- Case Teams Action -->
<record id="crm_team_salesteams_act" model="ir.actions.act_window">
<field name="name">Sales Dashboard</field>
<field name="name">Team Pipelines</field>
<field name="res_model">crm.team</field>
<field name="view_type">form</field>
<field name="view_mode">kanban,form</field>
<field name="context">{'search_default_my_favorites': 1}</field>
<field name="domain">[('use_opportunities', '=', True)]</field>
<field name="view_id" ref="crm_team_salesteams_search"/>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
@@ -31,7 +31,6 @@ The automatic assignation is figured from the weight of partner levels and the g
'views/res_partner_views.xml',
'views/crm_lead_views.xml',
'views/website_crm_partner_assign_templates.xml',
'report/crm_lead_report_view.xml',
'report/crm_partner_report_view.xml',
],
'demo': [
@@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import crm_lead_report
from . import crm_partner_report
@@ -1,76 +0,0 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models
from odoo import tools
from odoo.addons.crm.models import crm_stage
class CrmLeadReportAssign(models.Model):
""" CRM Lead Report """
_name = "crm.lead.report.assign"
_auto = False
_description = "CRM Lead Report"
partner_assigned_id = fields.Many2one('res.partner', 'Partner', readonly=True)
grade_id = fields.Many2one('res.partner.grade', 'Grade', readonly=True)
user_id = fields.Many2one('res.users', 'User', readonly=True)
country_id = fields.Many2one('res.country', 'Country', readonly=True)
team_id = fields.Many2one('crm.team', 'Sales Team', oldname='section_id', readonly=True)
company_id = fields.Many2one('res.company', 'Company', readonly=True)
date_assign = fields.Date('Assign Date', readonly=True)
delay_open = fields.Float('Delay to Assign', digits=(16, 2), readonly=True, group_operator="avg", help="Number of Days to open the case")
delay_close = fields.Float('Delay to Close', digits=(16, 2), readonly=True, group_operator="avg", help="Number of Days to close the case")
delay_expected = fields.Float('Overpassed Deadline', digits=(16, 2), readonly=True, group_operator="avg")
probability = fields.Float('Avg Probability', digits=(16, 2), readonly=True, group_operator="avg")
probability_max = fields.Float('Max Probability', digits=(16, 2), readonly=True, group_operator="max")
planned_revenue = fields.Float('Planned Revenue', digits=(16, 2), readonly=True)
probable_revenue = fields.Float('Probable Revenue', digits=(16, 2), readonly=True)
tag_ids = fields.Many2many('crm.lead.tag', 'crm_lead_tag_rel', 'lead_id', 'tag_id', 'Tags')
partner_id = fields.Many2one('res.partner', 'Customer', readonly=True)
opening_date = fields.Datetime('Opening Date', readonly=True)
date_closed = fields.Datetime('Close Date', readonly=True)
nbr_cases = fields.Integer('# of Cases', readonly=True, oldname='nbr')
priority = fields.Selection(crm_stage.AVAILABLE_PRIORITIES, 'Priority')
type = fields.Selection([
('lead', 'Lead'),
('opportunity', 'Opportunity')
], 'Type', help="Type is used to separate Leads and Opportunities")
@api.model_cr
def init(self):
"""
CRM Lead Report
@param cr: the current row, from the database cursor
"""
tools.drop_view_if_exists(self._cr, 'crm_lead_report_assign')
self._cr.execute("""
CREATE OR REPLACE VIEW crm_lead_report_assign AS (
SELECT
c.id,
c.date_open as opening_date,
c.date_closed as date_closed,
c.date_assign,
c.user_id,
c.probability,
c.probability as probability_max,
c.type,
c.company_id,
c.priority,
c.team_id,
c.partner_id,
c.country_id,
c.planned_revenue,
c.partner_assigned_id,
p.grade_id,
p.date as partner_date,
c.planned_revenue*(c.probability/100) as probable_revenue,
1 as nbr_cases,
c.create_date as create_date,
extract('epoch' from (c.write_date-c.create_date))/(3600*24) as delay_close,
extract('epoch' from (c.date_deadline - c.date_closed))/(3600*24) as delay_expected,
extract('epoch' from (c.date_open-c.create_date))/(3600*24) as delay_open
FROM
crm_lead c
left join res_partner p on (c.partner_assigned_id=p.id)
)""")
@@ -1,75 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Opportunity tree view -->
<record id="view_report_crm_lead_assign_filter" model="ir.ui.view">
<field name="name">crm.lead.report.assign.select</field>
<field name="model">crm.lead.report.assign</field>
<field name="arch" type="xml">
<search string="Leads Analysis">
<field name="team_id" context="{'invisible_team': False}"/>
<field name="grade_id"/>
<field name="user_id"/>
<field name="partner_assigned_id"/>
<group expand="0" string="Extended Filters...">
<field name="partner_id"/>
<separator/>
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
<field name="opening_date"/>
<field name="date_closed"/>
</group>
<group expand="1" string="Group By">
<filter string="Salesperson" name="user"
context="{'group_by':'user_id'}" />
<filter string="Sales Team" name="sales_channel" context="{'group_by':'team_id'}"/>
<filter string="Country" name="country" context="{'group_by':'country_id'}" />
<filter string="Company" name="company" context="{'group_by':'company_id'}" />
<separator/>
<filter string="Assign Date" name="assign_month" context="{'group_by':'date_assign:month'}"/>
</group>
</search>
</field>
</record>
<!-- Crm Lead Assign report pivot View -->
<record id="view_report_crm_lead_assign_pivot" model="ir.ui.view">
<field name="name">crm.lead.assign.pivot</field>
<field name="model">crm.lead.report.assign</field>
<field name="arch" type="xml">
<pivot string="Lead Assign" disable_linking="True">
<field name="date_assign" interval="month" type="col"/>
<field name="delay_open" type="measure"/>
<field name="probability" type="measure"/>
</pivot>
</field>
</record>
<!-- Crm Lead Assign report Graph View -->
<record id="view_report_crm_lead_assign_graph" model="ir.ui.view">
<field name="name">crm.lead.assign.graph</field>
<field name="model">crm.lead.report.assign</field>
<field name="arch" type="xml">
<graph string="Lead Assign">
<field name="date_assign"/>
<field name="delay_open" type="measure"/>
</graph>
</field>
</record>
<!-- Leads by user and Team Action -->
<record id="action_report_crm_opportunity_assign" model="ir.actions.act_window">
<field name="name">Opp. Assignment Analysis</field>
<field name="res_model">crm.lead.report.assign</field>
<field name="view_type">form</field>
<field name="context">{'default_type': 'opportunity', 'group_by_no_leaf':1,'group_by':[]}</field>
<field name="view_mode">graph,pivot</field>
<field name="domain">[('type', '=', 'opportunity')]</field>
</record>
<menuitem id="menu_report_crm_opportunities_assign_tree"
parent="crm.crm_menu_report" name="Opp. Assignment" action="action_report_crm_opportunity_assign" sequence="3"/>
</odoo>
@@ -51,6 +51,6 @@
</record>
<menuitem name="Partnerships" id="menu_report_crm_partner_assign_tree"
parent="crm.crm_menu_report" action="action_report_crm_partner_assign" sequence="4"/>
parent="crm.crm_menu_report" action="action_report_crm_partner_assign" sequence="5"/>
</odoo>
@@ -1,6 +1,4 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_crm_lead_report_assign,crm.lead.report.assign,model_crm_lead_report_assign,sales_team.group_sale_salesman,1,1,1,0
access_crm_lead_report_assign_all,crm.lead.report.assign.all,model_crm_lead_report_assign,base.group_user,1,0,0,0
access_crm_partner_report,crm.partner.report.assign.all,model_crm_partner_report_assign,sales_team.group_sale_salesman,1,0,0,0
access_res_partner_grade,res.partner.grade,model_res_partner_grade,sales_team.group_sale_salesman,1,1,1,0
access_res_partner_grade_employee,res.partner.grade,model_res_partner_grade,base.group_user,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
access_crm_lead_report_assign crm.lead.report.assign model_crm_lead_report_assign sales_team.group_sale_salesman 1 1 1 0
access_crm_lead_report_assign_all crm.lead.report.assign.all model_crm_lead_report_assign base.group_user 1 0 0 0
2 access_crm_partner_report crm.partner.report.assign.all model_crm_partner_report_assign sales_team.group_sale_salesman 1 0 0 0
3 access_res_partner_grade res.partner.grade model_res_partner_grade sales_team.group_sale_salesman 1 1 1 0
4 access_res_partner_grade_employee res.partner.grade model_res_partner_grade base.group_user 1 0 0 0
@@ -308,7 +308,7 @@
</div>
</div>
</div>
<div class="col-xs-12 col-lg-6 o_setting_box" id="abandoned_carts_setting" title="Abandoned carts are all carts for which no transaction has been confirmed while the customer has filled in their address. You can find them in *Website > Orders > Abandoned Carts*. From there you can send a recovery email to stimulate the customers to resume their order.">
<div class="col-xs-12 col-lg-6 o_setting_box" id="abandoned_carts_setting" title="Abandoned carts are all carts left unconfirmed by website visitors. You can find them in *Website > Orders > Abandoned Carts*. From there you can send recovery emails to visitors who entered their contact details.">
<div class="o_setting_left_pane"/>
<div class="o_setting_right_pane">
<span class="o_form_label">Abandoned Carts</span>
+36 -7
View File
@@ -4,14 +4,30 @@
<field name="name">sale.order.ecommerce.search.view</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_sales_order_filter"/>
<field name="mode">primary</field>
<field name="arch" type="xml">
<search>
<xpath expr="//filter[@name='my_sale_orders_filter']" position="replace">
<filter string="Confirmed Orders" name="order_confirmed" domain="[('state', 'in', ('sale', 'done'))]"/>
<filter string="Unpaid Orders" name="order_unpaid" domain="[('state', '=', 'sent'), ('team_id.team_type', '=', 'website')]"/>
<filter string="Abandoned Carts" name="order_abandoned" domain="[('is_abandoned_cart', '=', True)]"/>
<separator/>
<filter string="Order Date" name="order_date" date="date_order"/>
<separator/>
<filter string="From Website" name="from_website" domain="[('team_id.team_type', '=', 'website')]"/>
<separator/>
<filter string="Recovery Email to Send" name="recovery_email" domain="[('cart_recovery_email_sent', '=', False)]" />
</search>
</xpath>
</field>
</record>
<record id="view_sales_order_filter_ecommerce_unpaid" model="ir.ui.view">
<field name="name">sale.order.ecommerce.search.unpaid.view</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_sales_order_filter"/>
<field name="mode">primary</field>
<field name="arch" type="xml">
<xpath expr="//filter[@name='my_sale_orders_filter']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
</field>
</record>
@@ -67,6 +83,17 @@
</field>
</record>
<record id="view_sales_order_filter_ecommerce_abondand" model="ir.ui.view">
<field name="name">sale.order.ecommerce.abondand.view</field>
<field name="model">sale.order</field>
<field name="arch" type="xml">
<search string="Search Abandoned Sales Orders">
<filter string="Recovery Email to Send" name="recovery_email" domain="[('cart_recovery_email_sent', '=', False)]" />
<filter string="Recovery Email Sent" name="recovery_email_set" domain="[('cart_recovery_email_sent', '=', True)]" />
</search>
</field>
</record>
<record id="action_abandoned_orders_ecommerce" model="ir.actions.act_window">
<field name="name">Abandoned Carts</field>
<field name="res_model">sale.order</field>
@@ -78,8 +105,8 @@
<p class="o_view_nocontent_empty_folder">
No abandoned carts found
</p><p>
You'll find here all the carts abandoned by your visitors, if they completed their address.
You should send them a recovery email!
You'll find here all the carts abandoned by your visitors.
If they completed their address, you should send them a recovery email!
</p><p>
The time to mark a cart as abandoned can be changed in the settings.
</p>
@@ -121,6 +148,7 @@
<field name="domain">[('state', '=', 'sent'), ('team_id.team_type', '=', 'website')]</field>
<field name="context" eval="{'show_sale': True, 'create': False}"/>
<field name="view_id" ref="sale.view_quotation_tree"/>
<field name="search_view_id" ref="view_sales_order_filter_ecommerce_unpaid"/>
<field name="help" type="html">
<p class="o_view_nocontent_empty_folder">
There is no unpaid order from the website yet
@@ -138,12 +166,13 @@
<field name="domain">[('state', '=', 'draft'), ('order_line', '!=', False), ('partner_id', '!=', context.get('public_partner_id')), ('team_id.team_type', '=', 'website'), ('date_order', '&lt;=', (datetime.datetime.utcnow() - datetime.timedelta(hours=1)).strftime('%Y-%m-%d %H:%M:%S'))]</field>
<field name="context" eval="{'show_sale': True, 'create': False, 'public_partner_id': ref('base.public_partner'), 'search_default_recovery_email': True}"/>
<field name="view_id" ref="sale.view_quotation_tree"/>
<field name="search_view_id" ref="view_sales_order_filter_ecommerce_abondand"/>
<field name="help" type="html">
<p class="o_view_nocontent_empty_folder">
No abandoned carts found
</p><p>
You'll find here all the carts abandoned by your visitors, if they completed their address.
You should send them a recovery email!
You'll find here all the carts abandoned by your visitors.
If they completed their address, you should send them a recovery email!
</p><p>
The time to mark a cart as abandoned can be changed in the settings.
</p>
+2 -1
View File
@@ -444,6 +444,7 @@
<search string="Search Partner">
<field name="name"
filter_domain="['|','|',('display_name','ilike',self),('ref','=',self),('email','ilike',self)]"/>
<field name="parent_id" domain="[('is_company','=',1)]" operator="child_of"/>
<filter name="filter_my_partners" help="My Contacts"
domain="[('user_id','=',uid)]"/>
<separator/>
@@ -456,7 +457,7 @@
<separator/>
<field name="category_id" string="Tag" filter_domain="[('category_id','ilike', self)]"/>
<field name="user_id"/>
<field name="parent_id" domain="[('is_company','=',1)]" operator="child_of"/>
<field name="phone" filter_domain="['|',('phone','ilike',self),('mobile','=',self)]"/>
<group expand="0" name="group_by" string="Group By">
<filter name="salesperson" string="Salesperson" domain="[]" context="{'group_by' : 'user_id'}" />
<filter name="group_company" string="Company" context="{'group_by': 'parent_id'}"/>