summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Kersten <jke@odoo.com>2020-08-17 13:27:23 +0000
committerJeremy Kersten <jke@odoo.com>2020-08-17 15:59:03 +0000
commit73b4e9b1b671690a9d235459a6127da3603083a3 (patch)
tree8a54c671bef30e3d27a70c2402e9dd571e449aa3
parent5da1b96fbfda00af595fee747c9cbd76369a43c5 (diff)
[IMP] portal,*: /my counter async
Before this commit, the time to compute all counters was making the rendering of the portal page slow. Now the count is done in rpc after the loading of the page. Now you can decide which part you want to show on the portal, and only compute for these one. It is not because you have purchase installed for your internal process, that it means that your supplier use your portal and it avoid the computation for all end users. We parallelize the counters in arbitrary 3 rpcs. closes odoo/odoo#55999 Related: odoo/enterprise#12456 Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
-rw-r--r--addons/account/controllers/portal.py13
-rw-r--r--addons/account/views/account_portal_templates.xml6
-rw-r--r--addons/hr_timesheet/controllers/portal.py9
-rw-r--r--addons/hr_timesheet/views/hr_timesheet_portal_templates.xml8
-rw-r--r--addons/portal/controllers/portal.py12
-rw-r--r--addons/portal/models/ir_ui_view.py4
-rw-r--r--addons/portal/static/src/js/portal.js40
-rw-r--r--addons/portal/views/portal_templates.xml9
-rw-r--r--addons/project/controllers/portal.py10
-rw-r--r--addons/project/views/project_portal_templates.xml10
-rw-r--r--addons/purchase/controllers/portal.py12
-rw-r--r--addons/purchase/views/portal_templates.xml6
-rw-r--r--addons/sale/controllers/portal.py26
-rw-r--r--addons/sale/views/sale_portal_templates.xml10
-rw-r--r--addons/website/models/ir_ui_view.py1
-rw-r--r--addons/website_crm_partner_assign/controllers/main.py14
-rw-r--r--addons/website_crm_partner_assign/views/website_crm_partner_assign_templates.xml8
17 files changed, 126 insertions, 72 deletions
diff --git a/addons/account/controllers/portal.py b/addons/account/controllers/portal.py
index 6177008ca69..8723334ffcd 100644
--- a/addons/account/controllers/portal.py
+++ b/addons/account/controllers/portal.py
@@ -10,12 +10,13 @@ from odoo.http import request
class PortalAccount(CustomerPortal):
- def _prepare_home_portal_values(self):
- values = super(PortalAccount, self)._prepare_home_portal_values()
- invoice_count = request.env['account.move'].search_count([
- ('move_type', 'in', ('out_invoice', 'in_invoice', 'out_refund', 'in_refund', 'out_receipt', 'in_receipt')),
- ])
- values['invoice_count'] = invoice_count
+ def _prepare_home_portal_values(self, counters):
+ values = super()._prepare_home_portal_values(counters)
+ if 'invoice_count' in counters:
+ invoice_count = request.env['account.move'].search_count([
+ ('move_type', 'in', ('out_invoice', 'in_invoice', 'out_refund', 'in_refund', 'out_receipt', 'in_receipt')),
+ ])
+ values['invoice_count'] = invoice_count
return values
# ------------------------------------------------------------
diff --git a/addons/account/views/account_portal_templates.xml b/addons/account/views/account_portal_templates.xml
index a910e0db8c2..90c4604a4d6 100644
--- a/addons/account/views/account_portal_templates.xml
+++ b/addons/account/views/account_portal_templates.xml
@@ -12,12 +12,12 @@
</xpath>
</template>
- <template id="portal_my_home_invoice" name="Portal My Home : invoice entries" inherit_id="portal.portal_my_home" priority="30">
+ <template id="portal_my_home_invoice" name="Show Invoices &amp; Bills" inherit_id="portal.portal_my_home" customize_show="True" priority="30">
<xpath expr="//div[hasclass('o_portal_docs')]" position="inside">
- <t t-if="invoice_count" t-call="portal.portal_docs_entry">
+ <t t-call="portal.portal_docs_entry">
<t t-set="title">Invoices &amp; Bills</t>
<t t-set="url" t-value="'/my/invoices'"/>
- <t t-set="count" t-value="invoice_count"/>
+ <t t-set="placeholder_count" t-value="'invoice_count'"/>
</t>
</xpath>
</template>
diff --git a/addons/hr_timesheet/controllers/portal.py b/addons/hr_timesheet/controllers/portal.py
index ed98bbd2508..8127b83be6f 100644
--- a/addons/hr_timesheet/controllers/portal.py
+++ b/addons/hr_timesheet/controllers/portal.py
@@ -16,10 +16,11 @@ from odoo.addons.portal.controllers.portal import CustomerPortal, pager as porta
class TimesheetCustomerPortal(CustomerPortal):
- def _prepare_home_portal_values(self):
- values = super(TimesheetCustomerPortal, self)._prepare_home_portal_values()
- domain = request.env['account.analytic.line']._timesheet_get_portal_domain()
- values['timesheet_count'] = request.env['account.analytic.line'].sudo().search_count(domain)
+ def _prepare_home_portal_values(self, counters):
+ values = super()._prepare_home_portal_values(counters)
+ if 'timesheet_count' in counters:
+ domain = request.env['account.analytic.line']._timesheet_get_portal_domain()
+ values['timesheet_count'] = request.env['account.analytic.line'].sudo().search_count(domain)
return values
@http.route(['/my/timesheets', '/my/timesheets/page/<int:page>'], type='http', auth="user", website=True)
diff --git a/addons/hr_timesheet/views/hr_timesheet_portal_templates.xml b/addons/hr_timesheet/views/hr_timesheet_portal_templates.xml
index bef7862b1e1..90f2d679928 100644
--- a/addons/hr_timesheet/views/hr_timesheet_portal_templates.xml
+++ b/addons/hr_timesheet/views/hr_timesheet_portal_templates.xml
@@ -9,12 +9,12 @@
</xpath>
</template>
- <template id="portal_my_home_timesheet" name="Portal My Home : timesheets entries" inherit_id="portal.portal_my_home" priority="45">
+ <template id="portal_my_home_timesheet" name="Show Timesheets" customize_show="True" inherit_id="portal.portal_my_home" priority="45">
<xpath expr="//div[hasclass('o_portal_docs')]" position="inside">
- <t t-if="timesheet_count" t-call="portal.portal_docs_entry">
+ <t t-call="portal.portal_docs_entry">
<t t-set="title">Timesheets</t>
<t t-set="url" t-value="'/my/timesheets'"/>
- <t t-set="count" t-value="timesheet_count"/>
+ <t t-set="placeholder_count" t-value="'timesheet_count'"/>
</t>
</xpath>
</template>
@@ -35,7 +35,7 @@
<t t-call="portal.portal_table">
<t t-foreach="grouped_timesheets" t-as="timesheets_with_hours">
<t t-set="timesheets" t-value="timesheets_with_hours[0]"/>
- <t t-set="hours_spent" t-value="timesheets_with_hours[1]"/>
+ <t t-set="hours_spent" t-value="timesheets_with_hours[1]"/>
<thead>
<tr t-if="not groupby =='none'" t-attf-class="{{'thead-light'}}">
<th t-if="groupby == 'project'" colspan="5">
diff --git a/addons/portal/controllers/portal.py b/addons/portal/controllers/portal.py
index a8e44515574..c2c7901030b 100644
--- a/addons/portal/controllers/portal.py
+++ b/addons/portal/controllers/portal.py
@@ -159,16 +159,22 @@ class CustomerPortal(Controller):
'archive_groups': [],
}
- def _prepare_home_portal_values(self):
+ def _prepare_home_portal_values(self, counters):
"""Values for /my & /my/home routes template rendering.
Includes the record count for the displayed badges.
+ where 'coutners' is the list of the displayed badges
+ and so the list to compute.
"""
- return self._prepare_portal_layout_values()
+ return {}
+
+ @route(['/my/counters'], type='json', auth="user", website=True)
+ def counters(self, counters, **kw):
+ return self._prepare_home_portal_values(counters)
@route(['/my', '/my/home'], type='http', auth="user", website=True)
def home(self, **kw):
- values = self._prepare_home_portal_values()
+ values = self._prepare_portal_layout_values()
return request.render("portal.portal_my_home", values)
@route(['/my/account'], type='http', auth='user', website=True)
diff --git a/addons/portal/models/ir_ui_view.py b/addons/portal/models/ir_ui_view.py
index e51261170aa..ca4051755f7 100644
--- a/addons/portal/models/ir_ui_view.py
+++ b/addons/portal/models/ir_ui_view.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from odoo import api, models
+from odoo import api, models, fields
from odoo.http import request
from odoo.addons.http_routing.models.ir_http import url_for
@@ -9,6 +9,8 @@ from odoo.addons.http_routing.models.ir_http import url_for
class View(models.Model):
_inherit = "ir.ui.view"
+ customize_show = fields.Boolean("Show As Optional Inherit", default=False)
+
@api.model
def _prepare_qcontext(self):
""" Returns the qcontext : rendering context with portal specific value (required
diff --git a/addons/portal/static/src/js/portal.js b/addons/portal/static/src/js/portal.js
index ee6bbe16eb5..f938521b265 100644
--- a/addons/portal/static/src/js/portal.js
+++ b/addons/portal/static/src/js/portal.js
@@ -53,6 +53,46 @@ publicWidget.registry.portalDetails = publicWidget.Widget.extend({
},
});
+publicWidget.registry.PortalHomeCounters = publicWidget.Widget.extend({
+ selector: '.o_portal_my_home',
+
+ /**
+ * @override
+ */
+ start: function () {
+ var def = this._super.apply(this, arguments);
+ this._updateCounters();
+ return def;
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ async _updateCounters(elem) {
+ const numberRpc = 3;
+ const needed = this.$('[data-placeholder_count]')
+ .map((i, o) => $(o).data('placeholder_count'))
+ .toArray();
+ const counterByRpc = Math.ceil(needed.length / numberRpc); // max counter, last can be less
+
+ const proms = [...Array(Math.min(numberRpc, needed.length)).keys()].map(async i => {
+ await this._rpc({
+ route: "/my/counters",
+ params: {
+ counters: needed.slice(i * counterByRpc, (i + 1) * counterByRpc)
+ },
+ }).then(data => {
+ Object.keys(data).map(k => this.$("[data-placeholder_count='" + k + "']").text(data[k]));
+ });
+ });
+ return Promise.all(proms);
+ },
+});
+
publicWidget.registry.portalSearchPanel = publicWidget.Widget.extend({
selector: '.o_portal_search_panel',
events: {
diff --git a/addons/portal/views/portal_templates.xml b/addons/portal/views/portal_templates.xml
index be4a35f2db0..aa4fc556690 100644
--- a/addons/portal/views/portal_templates.xml
+++ b/addons/portal/views/portal_templates.xml
@@ -163,7 +163,14 @@
<template id="portal_docs_entry" name="My Portal Docs Entry">
<a t-att-href="url" t-att-title="title" class="list-group-item list-group-item-action d-flex align-items-center justify-content-between">
<t t-esc="title"/>
- <span class="badge badge-secondary badge-pill" t-esc="count"/>
+ <t t-if='count'>
+ <span class="badge badge-secondary badge-pill" t-esc="count"/>
+ </t>
+ <t t-elif="placeholder_count">
+ <span class="badge badge-secondary badge-pill" t-att-data-placeholder_count="placeholder_count">
+ <i class="fa fa-spin fa-spinner"></i>
+ </span>
+ </t>
</a>
</template>
diff --git a/addons/project/controllers/portal.py b/addons/project/controllers/portal.py
index eef58fab633..f7480d3aedb 100644
--- a/addons/project/controllers/portal.py
+++ b/addons/project/controllers/portal.py
@@ -15,10 +15,12 @@ from odoo.osv.expression import OR
class CustomerPortal(CustomerPortal):
- def _prepare_home_portal_values(self):
- values = super(CustomerPortal, self)._prepare_home_portal_values()
- values['project_count'] = request.env['project.project'].search_count([])
- values['task_count'] = request.env['project.task'].search_count([])
+ def _prepare_home_portal_values(self, counters):
+ values = super()._prepare_home_portal_values(counters)
+ if 'project_count' in counters:
+ values['project_count'] = request.env['project.project'].search_count([])
+ if 'task_count' in counters:
+ values['task_count'] = request.env['project.task'].search_count([])
return values
# ------------------------------------------------------------
diff --git a/addons/project/views/project_portal_templates.xml b/addons/project/views/project_portal_templates.xml
index 9303df97472..49cd2f3218a 100644
--- a/addons/project/views/project_portal_templates.xml
+++ b/addons/project/views/project_portal_templates.xml
@@ -19,17 +19,17 @@
</xpath>
</template>
- <template id="portal_my_home" name="Portal My Home: project entries" inherit_id="portal.portal_my_home" priority="40">
+ <template id="portal_my_home" name="Show Projects / Tasks" customize_show="True" inherit_id="portal.portal_my_home" priority="40">
<xpath expr="//div[hasclass('o_portal_docs')]" position="inside">
- <t t-if="project_count" t-call="portal.portal_docs_entry">
+ <t t-call="portal.portal_docs_entry">
<t t-set="title">Projects</t>
<t t-set="url" t-value="'/my/projects'"/>
- <t t-set="count" t-value="project_count"/>
+ <t t-set="placeholder_count" t-value="'project_count'"/>
</t>
- <t t-if="task_count" t-call="portal.portal_docs_entry">
+ <t t-call="portal.portal_docs_entry">
<t t-set="title">Tasks</t>
<t t-set="url" t-value="'/my/tasks'"/>
- <t t-set="count" t-value="task_count"/>
+ <t t-set="placeholder_count" t-value="'task_count'"/>
</t>
</xpath>
</template>
diff --git a/addons/purchase/controllers/portal.py b/addons/purchase/controllers/portal.py
index c566963c32c..72a60ca2782 100644
--- a/addons/purchase/controllers/portal.py
+++ b/addons/purchase/controllers/portal.py
@@ -16,11 +16,12 @@ from odoo.addons.web.controllers.main import Binary
class CustomerPortal(CustomerPortal):
- def _prepare_home_portal_values(self):
- values = super(CustomerPortal, self)._prepare_home_portal_values()
- values['purchase_count'] = request.env['purchase.order'].search_count([
- ('state', 'in', ['purchase', 'done', 'cancel'])
- ])
+ def _prepare_home_portal_values(self, counters):
+ values = super()._prepare_home_portal_values(counters)
+ if 'purchase_count' in counters:
+ values['purchase_count'] = request.env['purchase.order'].search_count([
+ ('state', 'in', ['purchase', 'done', 'cancel'])
+ ])
return values
def _purchase_order_get_page_view_values(self, order, access_token, **kwargs):
@@ -39,7 +40,6 @@ class CustomerPortal(CustomerPortal):
@http.route(['/my/purchase', '/my/purchase/page/<int:page>'], type='http', auth="user", website=True)
def portal_my_purchase_orders(self, page=1, date_begin=None, date_end=None, sortby=None, filterby=None, **kw):
values = self._prepare_portal_layout_values()
- partner = request.env.user.partner_id
PurchaseOrder = request.env['purchase.order']
domain = []
diff --git a/addons/purchase/views/portal_templates.xml b/addons/purchase/views/portal_templates.xml
index 5ec71184b6d..3974c5814e9 100644
--- a/addons/purchase/views/portal_templates.xml
+++ b/addons/purchase/views/portal_templates.xml
@@ -13,12 +13,12 @@
</xpath>
</template>
- <template id="portal_my_home_purchase" name="Portal My Home : purchase entry" inherit_id="portal.portal_my_home" priority="25">
+ <template id="portal_my_home_purchase" name="Show Purchase Orders" customize_show="True" inherit_id="portal.portal_my_home" priority="25">
<xpath expr="//div[hasclass('o_portal_docs')]" position="inside">
- <t t-if="purchase_count" t-call="portal.portal_docs_entry">
+ <t t-call="portal.portal_docs_entry">
<t t-set="title">Purchase Orders</t>
<t t-set="url" t-value="'/my/purchase'"/>
- <t t-set="count" t-value="purchase_count"/>
+ <t t-set="placeholder_count" t-value="'purchase_count'"/>
</t>
</xpath>
</template>
diff --git a/addons/sale/controllers/portal.py b/addons/sale/controllers/portal.py
index 6267683fba7..c9a7f7a9acf 100644
--- a/addons/sale/controllers/portal.py
+++ b/addons/sale/controllers/portal.py
@@ -14,24 +14,22 @@ from odoo.osv import expression
class CustomerPortal(CustomerPortal):
- def _prepare_home_portal_values(self):
- values = super(CustomerPortal, self)._prepare_home_portal_values()
+ def _prepare_home_portal_values(self, counters):
+ values = super()._prepare_home_portal_values(counters)
partner = request.env.user.partner_id
SaleOrder = request.env['sale.order']
- quotation_count = SaleOrder.search_count([
- ('message_partner_ids', 'child_of', [partner.commercial_partner_id.id]),
- ('state', 'in', ['sent', 'cancel'])
- ])
- order_count = SaleOrder.search_count([
- ('message_partner_ids', 'child_of', [partner.commercial_partner_id.id]),
- ('state', 'in', ['sale', 'done'])
- ])
+ if 'quotation_count' in counters:
+ values['quotation_count'] = SaleOrder.search_count([
+ ('message_partner_ids', 'child_of', [partner.commercial_partner_id.id]),
+ ('state', 'in', ['sent', 'cancel'])
+ ])
+ if 'order_count' in counters:
+ values['order_count'] = SaleOrder.search_count([
+ ('message_partner_ids', 'child_of', [partner.commercial_partner_id.id]),
+ ('state', 'in', ['sale', 'done'])
+ ])
- values.update({
- 'quotation_count': quotation_count,
- 'order_count': order_count,
- })
return values
#
diff --git a/addons/sale/views/sale_portal_templates.xml b/addons/sale/views/sale_portal_templates.xml
index 90e9d03ce4b..27695fb99c1 100644
--- a/addons/sale/views/sale_portal_templates.xml
+++ b/addons/sale/views/sale_portal_templates.xml
@@ -18,17 +18,17 @@
</xpath>
</template>
- <template id="portal_my_home_sale" name="Portal My Home : sales entries" inherit_id="portal.portal_my_home" priority="20">
+ <template id="portal_my_home_sale" name="Show Quotations / Sales Orders" customize_show="True" inherit_id="portal.portal_my_home" priority="20">
<xpath expr="//div[hasclass('o_portal_docs')]" position="inside">
- <t t-if="quotation_count" t-call="portal.portal_docs_entry">
+ <t t-call="portal.portal_docs_entry">
<t t-set="title">Quotations</t>
<t t-set="url" t-value="'/my/quotes'"/>
- <t t-set="count" t-value="quotation_count"/>
+ <t t-set="placeholder_count" t-value="'quotation_count'"/>
</t>
- <t t-if="order_count" t-call="portal.portal_docs_entry">
+ <t t-call="portal.portal_docs_entry">
<t t-set="title">Sales Orders</t>
<t t-set="url" t-value="'/my/orders'"/>
- <t t-set="count" t-value="order_count"/>
+ <t t-set="placeholder_count" t-value="'order_count'"/>
</t>
</xpath>
</template>
diff --git a/addons/website/models/ir_ui_view.py b/addons/website/models/ir_ui_view.py
index 502875e87ef..2a0ab1c31a9 100644
--- a/addons/website/models/ir_ui_view.py
+++ b/addons/website/models/ir_ui_view.py
@@ -21,7 +21,6 @@ class View(models.Model):
_name = "ir.ui.view"
_inherit = ["ir.ui.view", "website.seo.metadata"]
- customize_show = fields.Boolean("Show As Optional Inherit", default=False)
website_id = fields.Many2one('website', ondelete='cascade', string="Website")
page_ids = fields.One2many('website.page', 'view_id')
first_page_id = fields.Many2one('website.page', string='Website Page', help='First page linked to this view', compute='_compute_first_page_id')
diff --git a/addons/website_crm_partner_assign/controllers/main.py b/addons/website_crm_partner_assign/controllers/main.py
index 85bc2e7cc88..d01ad9efa02 100644
--- a/addons/website_crm_partner_assign/controllers/main.py
+++ b/addons/website_crm_partner_assign/controllers/main.py
@@ -32,14 +32,12 @@ class WebsiteAccount(CustomerPortal):
('type', '=', 'opportunity')
]
- def _prepare_home_portal_values(self):
- values = super(WebsiteAccount, self)._prepare_home_portal_values()
- lead_count = request.env['crm.lead'].search_count(self.get_domain_my_lead(request.env.user))
- opp_count = request.env['crm.lead'].search_count(self.get_domain_my_opp(request.env.user))
- values.update({
- 'lead_count': lead_count,
- 'opp_count': opp_count,
- })
+ def _prepare_home_portal_values(self, counters):
+ values = super()._prepare_home_portal_values(counters)
+ if 'lead_count' in counters:
+ values['lead_count'] = request.env['crm.lead'].search_count(self.get_domain_my_lead(request.env.user))
+ if 'opp_count' in counters:
+ values['opp_count'] = request.env['crm.lead'].search_count(self.get_domain_my_opp(request.env.user))
return values
@http.route(['/my/leads', '/my/leads/page/<int:page>'], type='http', auth="user", website=True)
diff --git a/addons/website_crm_partner_assign/views/website_crm_partner_assign_templates.xml b/addons/website_crm_partner_assign/views/website_crm_partner_assign_templates.xml
index 4dee7a3b7a9..3ff7b69a97c 100644
--- a/addons/website_crm_partner_assign/views/website_crm_partner_assign_templates.xml
+++ b/addons/website_crm_partner_assign/views/website_crm_partner_assign_templates.xml
@@ -208,17 +208,17 @@
</xpath>
</template>
- <template id="portal_my_home_lead" name="Portal My Home : lead entries" inherit_id="portal.portal_my_home" priority="15">
+ <template id="portal_my_home_lead" name="Show Leads / Opps" customize_show="True" inherit_id="portal.portal_my_home" priority="15">
<xpath expr="//div[hasclass('o_portal_docs')]" position="inside">
- <t t-if="lead_count" t-call="portal.portal_docs_entry">
+ <t t-call="portal.portal_docs_entry">
<t t-set="title">Leads</t>
<t t-set="url" t-value="'/my/leads'"/>
- <t t-set="count" t-value="lead_count"/>
+ <t t-set="placeholder_count" t-value="'lead_count'"/>
</t>
<t t-call="portal.portal_docs_entry">
<t t-set="title">Opportunities</t>
<t t-set="url" t-value="'/my/opportunities'"/>
- <t t-set="count" t-value="opp_count"/>
+ <t t-set="placeholder_count" t-value="'opp_count'"/>
</t>
</xpath>
</template>