summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorToufik Ben Jaa <tbe@odoo.com>2019-05-29 16:10:19 +0000
committerToufik Ben Jaa <tbe@odoo.com>2019-06-03 08:19:50 +0000
commita7649a3d8634576d4a4dae61d2de36209fed40ae (patch)
tree818af116d247f507714c34f0ff540ece3e075171 /addons
parent15187da85a6f9137bad6a77db2e87d259e0f0f81 (diff)
[FIX] sale_timesheet: performance for project with a lot of tasks
closes odoo/odoo#33766 Signed-off-by: Nicolas Seinlet (nse) <nse@odoo.com>
Diffstat (limited to 'addons')
-rw-r--r--addons/sale_timesheet/models/project_overview.py61
1 files changed, 45 insertions, 16 deletions
diff --git a/addons/sale_timesheet/models/project_overview.py b/addons/sale_timesheet/models/project_overview.py
index 68298b1e3ad..62ccbd510f3 100644
--- a/addons/sale_timesheet/models/project_overview.py
+++ b/addons/sale_timesheet/models/project_overview.py
@@ -82,12 +82,16 @@ class Project(models.Model):
#
# Time Repartition (per employee per billable types)
#
- user_ids = self.env['project.task'].sudo().search_read([('project_id', 'in', self.ids), ('user_id', '!=', False)], ['user_id'])
+ user_ids = self.env['project.task'].sudo().read_group([('project_id', 'in', self.ids), ('user_id', '!=', False)], ['user_id'], ['user_id'])
user_ids = [user_id['user_id'][0] for user_id in user_ids]
employee_ids = self.env['res.users'].sudo().search_read([('id', 'in', user_ids)], ['employee_ids'])
# flatten the list of list
employee_ids = list(itertools.chain.from_iterable([employee_id['employee_ids'] for employee_id in employee_ids]))
- employees = self.env['hr.employee'].sudo().browse(employee_ids) | self.env['account.analytic.line'].search([('project_id', 'in', self.ids)]).mapped('employee_id')
+
+ aal_employee_ids = self.env['account.analytic.line'].read_group([('project_id', 'in', self.ids), ('employee_id', '!=', False)], ['employee_id'], ['employee_id'])
+ employee_ids.extend(list(map(lambda x: x['employee_id'][0], aal_employee_ids)))
+
+ employees = self.env['hr.employee'].sudo().browse(employee_ids)
repartition_domain = [('project_id', 'in', self.ids), ('employee_id', '!=', False), ('timesheet_invoice_type', '!=', False)] # force billable type
repartition_data = self.env['account.analytic.line'].read_group(repartition_domain, ['employee_id', 'timesheet_invoice_type', 'unit_amount'], ['employee_id', 'timesheet_invoice_type'], lazy=False)
@@ -330,8 +334,14 @@ class Project(models.Model):
def _plan_prepare_actions(self, values):
actions = []
if len(self) == 1:
+ task_order_line_ids = []
+ # retrieve all the sale order line that we will need later below
+ if self.env.user.has_group('sales_team.group_sale_salesman') or self.env.user.has_group('sales_team.group_sale_salesman_all_leads'):
+ task_order_line_ids = self.env['project.task'].read_group([('project_id', '=', self.id), ('sale_line_id', '!=', False)], ['sale_line_id'], ['sale_line_id'])
+ task_order_line_ids = [ol['sale_line_id'][0] for ol in task_order_line_ids]
+
if self.env.user.has_group('sales_team.group_sale_salesman'):
- if not self.sale_line_id and not self.tasks.mapped('sale_line_id'):
+ if not self.sale_line_id and not task_order_line_ids:
actions.append({
'label': _("Create a Sales Order"),
'type': 'action',
@@ -340,14 +350,19 @@ class Project(models.Model):
})
if self.env.user.has_group('sales_team.group_sale_salesman_all_leads'):
to_invoice_amount = values['dashboard']['profit'].get('to_invoice', False) # plan project only takes services SO line with timesheet into account
- sale_orders = self.tasks.mapped('sale_line_id.order_id').filtered(lambda so: so.invoice_status == 'to invoice')
- if to_invoice_amount and sale_orders:
- if len(sale_orders) == 1:
+
+ sale_order_ids = self.env['sale.order.line'].read_group([('id', 'in', task_order_line_ids)], ['order_id'], ['order_id'])
+ sale_order_ids = [s['order_id'][0] for s in sale_order_ids]
+ sale_order_ids = self.env['sale.order'].search_read([('id', 'in', sale_order_ids), ('invoice_status', '=', 'to invoice')], ['id'])
+ sale_order_ids = list(map(lambda x: x['id'], sale_order_ids))
+
+ if to_invoice_amount and sale_order_ids:
+ if len(sale_order_ids) == 1:
actions.append({
'label': _("Create Invoice"),
'type': 'action',
'action_id': 'sale.action_view_sale_advance_payment_inv',
- 'context': json.dumps({'active_ids': sale_orders.ids, 'active_model': 'project.project'}),
+ 'context': json.dumps({'active_ids': sale_order_ids, 'active_model': 'project.project'}),
})
else:
actions.append({
@@ -383,9 +398,13 @@ class Project(models.Model):
# if only one project, add it in the context as default value
tasks_domain = [('project_id', 'in', self.ids)]
tasks_context = self.env.context
- tasks_projects = self.env['project.task'].sudo().search(tasks_domain).mapped('project_id')
- if len(tasks_projects) == 1:
- tasks_context = {**tasks_context, 'default_project_id': tasks_projects.id}
+
+ # filter out all the projects that have no tasks
+ task_projects_ids = self.env['project.task'].read_group([('project_id', 'in', self.ids)], ['project_id'], ['project_id'])
+ task_projects_ids = [p['project_id'][0] for p in task_projects_ids]
+
+ if len(task_projects_ids) == 1:
+ tasks_context = {**tasks_context, 'default_project_id': task_projects_ids[0]}
stat_buttons.append({
'name': _('Tasks'),
'count': sum(self.mapped('task_count')),
@@ -398,8 +417,13 @@ class Project(models.Model):
})
if self.env.user.has_group('sales_team.group_sale_salesman_all_leads'):
- sale_orders = self.mapped('sale_line_id.order_id') | self.mapped(
- 'tasks.sale_order_id')
+ # read all the sale orders linked to the projects' tasks
+ task_so_ids = self.env['project.task'].search_read([
+ ('project_id', 'in', self.ids), ('sale_order_id', '!=', False)
+ ], ['sale_order_id'])
+ task_so_ids = [o['sale_order_id'][0] for o in task_so_ids]
+
+ sale_orders = self.mapped('sale_line_id.order_id') | self.env['sale.order'].browse(task_so_ids)
if sale_orders:
stat_buttons.append({
'name': _('Sales Orders'),
@@ -411,15 +435,20 @@ class Project(models.Model):
context={'create': False, 'edit': False, 'delete': False}
)
})
- invoices = sale_orders.mapped('invoice_ids').filtered(lambda inv: inv.type == 'out_invoice')
- if invoices:
+
+ invoice_ids = self.env['sale.order'].search_read([('id', 'in', sale_orders.ids)], ['invoice_ids'])
+ invoice_ids = list(itertools.chain(*[i['invoice_ids'] for i in invoice_ids]))
+ invoice_ids = self.env['account.invoice'].search_read([('id', 'in', invoice_ids), ('type', '=', 'out_invoice')], ['id'])
+ invoice_ids = list(map(lambda x: x['id'], invoice_ids))
+
+ if invoice_ids:
stat_buttons.append({
'name': _('Invoices'),
- 'count': len(invoices),
+ 'count': len(invoice_ids),
'icon': 'fa fa-pencil-square-o',
'action': _to_action_data(
action=self.env.ref('account.action_invoice_tree1'),
- domain=[('id', 'in', invoices.ids), ('type', '=', 'out_invoice')],
+ domain=[('id', 'in', invoice_ids), ('type', '=', 'out_invoice')],
context={'create': False, 'delete': False}
)
})