[IMP] project_sale_expense: add action to see the expenses
Before this commit, the expenses inscreasing the revenues or the costs in the project profitability are not visible for the user because he can just see the result and not which expenses are related to that result. This commit adds the action to see the expenses related to the revenues that is, all expenses reinvoiced to the customer for that project or the expenses related to the costs of the project. However, the user needs to have access to the expenses to access to the action, otherwise the name section is not clickable. task-2710808
This commit is contained in:
committed by
Laurent Stukkens (LTU)
parent
5558d2a578
commit
b187e49cb9
@@ -2,3 +2,4 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import models
|
||||
from . import tests
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import test_project_profitability
|
||||
@@ -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', {}),
|
||||
{},
|
||||
|
||||
Reference in New Issue
Block a user