diff --git a/addons/project_sale_expense/__init__.py b/addons/project_sale_expense/__init__.py index dc5e6b693d1..90b17558ffc 100644 --- a/addons/project_sale_expense/__init__.py +++ b/addons/project_sale_expense/__init__.py @@ -2,3 +2,4 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from . import models +from . import tests diff --git a/addons/project_sale_expense/models/project_project.py b/addons/project_sale_expense/models/project_project.py index cc4481055d3..04ee75323f0 100644 --- a/addons/project_sale_expense/models/project_project.py +++ b/addons/project_sale_expense/models/project_project.py @@ -1,33 +1,39 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +import json + from odoo import models, _ class Project(models.Model): _inherit = 'project.project' - def _get_expenses_profitability_items(self): + def _get_expenses_profitability_items(self, with_action=True): if not self.analytic_account_id: return {} + can_see_expense = with_action and self.user_has_groups('hr_expense.group_hr_expense_team_approver') expenses_read_group = self.env['hr.expense'].sudo()._read_group( [ ('analytic_account_id', 'in', self.analytic_account_id.ids), ('is_refused', '=', False), ('state', 'in', ['approved', 'done']), ], - ['sale_order_id', 'product_id', 'untaxed_amount'], + ['sale_order_id', 'product_id', 'ids:array_agg(id)', 'untaxed_amount'], ['sale_order_id', 'product_id'], lazy=False, ) if not expenses_read_group: return {} expenses_per_so_id = {} + expense_ids = [] amount_billed = 0.0 for res in expenses_read_group: so_id = res['sale_order_id'] and res['sale_order_id'][0] product_id = res['product_id'] and res['product_id'][0] expenses_per_so_id.setdefault(so_id, {})[product_id] = res['ids'] + if can_see_expense: + expense_ids.extend(res['ids']) amount_billed += res['untaxed_amount'] sol_read_group = self.env['sale.order.line'].sudo()._read_group( [ @@ -64,4 +70,15 @@ class Project(models.Model): 'invoiced': total_amount_expense_invoiced, 'to_invoice': total_amount_expense_to_invoice, } + if can_see_expense: + def get_action(res_ids): + action = {'name': 'action_profitability_items', 'type': 'object', 'section': section_id, 'domain': json.dumps([('id', 'in', res_ids)])} + if len(res_ids) == 1: + action['res_id'] = res_ids[0] + return action + + if reinvoice_expense_ids: + expense_data['revenues']['action'] = get_action(reinvoice_expense_ids) + if expense_ids: + expense_data['costs']['action'] = get_action(expense_ids) return expense_data diff --git a/addons/project_sale_expense/tests/__init__.py b/addons/project_sale_expense/tests/__init__.py new file mode 100644 index 00000000000..4fa67e8be11 --- /dev/null +++ b/addons/project_sale_expense/tests/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import test_project_profitability diff --git a/addons/project_sale_expense/tests/test_project_profitability.py b/addons/project_sale_expense/tests/test_project_profitability.py index 2bd7fe074e4..828ad467700 100644 --- a/addons/project_sale_expense/tests/test_project_profitability.py +++ b/addons/project_sale_expense/tests/test_project_profitability.py @@ -26,7 +26,7 @@ class TestProjectSaleExpenseProfitability(TestProjectProfitabilityCommon, TestPr self.project, self.project_profitability_items_empty) - expense_profitability = self.project._get_expenses_profitability_items() + expense_profitability = self.project._get_expenses_profitability_items(False) self.assertDictEqual( expense_profitability.get('revenues', {}), @@ -56,7 +56,7 @@ class TestProjectSaleExpenseProfitability(TestProjectProfitabilityCommon, TestPr ]) expense_sol = self.sale_order.order_line.filtered(lambda sol: sol.product_id == self.company_data['product_order_sales_price']) - expense_profitability = self.project._get_expenses_profitability_items() + expense_profitability = self.project._get_expenses_profitability_items(False) self.assertDictEqual( expense_profitability.get('revenues', {}), {'id': 'expenses', 'invoiced': 0.0, 'to_invoice': expense_sol.untaxed_amount_to_invoice}, @@ -67,7 +67,7 @@ class TestProjectSaleExpenseProfitability(TestProjectProfitabilityCommon, TestPr ) self.assertDictEqual( - self.project._get_profitability_items(), + self.project._get_profitability_items(False), { 'revenues': { 'data': [expense_profitability['revenues']], @@ -89,7 +89,7 @@ class TestProjectSaleExpenseProfitability(TestProjectProfitabilityCommon, TestPr })._create_invoices(self.sale_order) invoice.action_post() - expense_profitability = self.project._get_expenses_profitability_items() + expense_profitability = self.project._get_expenses_profitability_items(False) self.assertDictEqual( expense_profitability.get('revenues', {}), {'id': 'expenses', 'invoiced': expense_sol.untaxed_amount_invoiced, 'to_invoice': 0.0}, @@ -98,14 +98,14 @@ class TestProjectSaleExpenseProfitability(TestProjectProfitabilityCommon, TestPr credit_note = invoice._reverse_moves() credit_note.action_post() - expense_profitability = self.project._get_expenses_profitability_items() + expense_profitability = self.project._get_expenses_profitability_items(False) self.assertDictEqual( expense_profitability.get('revenues', {}), {'id': 'expenses', 'invoiced': 0.0, 'to_invoice': expense_sol.untaxed_amount_to_invoice}, ) self.sale_order.action_cancel() - expense_profitability = self.project._get_expenses_profitability_items() + expense_profitability = self.project._get_expenses_profitability_items(False) self.assertDictEqual( expense_profitability.get('revenues', {}), {}, @@ -116,7 +116,7 @@ class TestProjectSaleExpenseProfitability(TestProjectProfitabilityCommon, TestPr ) expense_sheet.refuse_sheet('Test Cancel Expense') - expense_profitability = self.project._get_expenses_profitability_items() + expense_profitability = self.project._get_expenses_profitability_items(False) self.assertDictEqual( expense_profitability.get('revenues', {}), {},