[IMP] sale_project: add action to get all SOLs related to revenues

Before this commit, the materials row displayed in the revenues of the
project profitability in the right side panel shows only the result of
all SOLs containing a material product. The user cannot see which SOLs
give that result.

This commit adds an action to see all SOLs related to that row. If the
user has access to the Sales app then the name in that row (that is,
'Material') will be clickable to redirect the user to the view of SOLs
found for that row.

task-2710808
This commit is contained in:
Xavier BOL (xbo)
2022-04-01 15:33:00 +02:00
committed by Laurent Stukkens (LTU)
parent b187e49cb9
commit ca8aaa0a0d
2 changed files with 43 additions and 12 deletions
+36 -5
View File
@@ -105,6 +105,24 @@ class Project(models.Model):
})
return action_window
def action_profitability_items(self, section_name, domain=None, res_id=False):
if section_name in ['service_revenues', 'other_revenues']:
view_types = ['list', 'kanban', 'form']
action = {
'name': _('Sales Order Items'),
'type': 'ir.actions.act_window',
'res_model': 'sale.order.line',
'context': {'no_create': True},
}
if res_id:
action['res_id'] = res_id
view_types = ['form']
else:
action['domain'] = domain
action['views'] = [(False, v) for v in view_types]
return action
return super().action_profitability_items(section_name, domain, res_id)
@api.depends('sale_order_id.invoice_status', 'tasks.sale_order_id.invoice_status')
def _compute_has_any_so_with_nothing_to_invoice(self):
"""Has any Sale Order whose invoice_status is set as No"""
@@ -282,7 +300,7 @@ class Project(models.Model):
'delivered_manual': 'service_revenues',
}
def _get_revenues_items_from_sol(self):
def _get_revenues_items_from_sol(self, with_action=True):
sale_line_read_group = self.env['sale.order.line'].read_group(
[
('order_id', 'in', self._get_sale_orders().ids),
@@ -292,9 +310,10 @@ class Project(models.Model):
('state', 'in', ['sale', 'done']),
'|', ('qty_to_invoice', '>', 0), ('qty_invoiced', '>', 0),
],
['product_id', 'untaxed_amount_to_invoice', 'untaxed_amount_invoiced'],
['product_id', 'ids:array_agg(id)', 'untaxed_amount_to_invoice', 'untaxed_amount_invoiced'],
['product_id'],
)
display_sol_action = with_action and len(self) == 1 and self.user_has_groups('sales_team.group_sale_salesman')
revenues_dict = {}
total_to_invoice = total_invoiced = 0.0
if sale_line_read_group:
@@ -328,14 +347,26 @@ class Project(models.Model):
total_to_invoice += amount_to_invoice
revenue['invoiced'] += amount_invoiced
total_invoiced += amount_invoiced
if display_sol_action and invoice_type in ['service_revenues', 'other_revenues']:
revenue.setdefault('record_ids', []).extend(sol_ids)
if display_sol_action:
section_name = 'other_revenues'
other_revenues = revenues_dict.get(section_name, {})
sol_ids = other_revenues.pop('record_ids', [])
if sol_ids:
action_params = {'name': 'action_profitability_items', 'type': 'object', 'section': section_name, 'domain': json.dumps(domain)}
if len(sol_ids) == 1:
action_params['res_id'] = sol_ids[0]
other_revenues['action'] = action_params
return {
'data': [{'id': invoice_type, **vals} for invoice_type, vals in revenues_dict.items()],
'total': {'to_invoice': total_to_invoice, 'invoiced': total_invoiced},
}
def _get_profitability_items(self):
profitability_items = super()._get_profitability_items()
revenue_items_from_sol = self._get_revenues_items_from_sol()
def _get_profitability_items(self, with_action=True):
profitability_items = super()._get_profitability_items(with_action)
revenue_items_from_sol = self._get_revenues_items_from_sol(with_action)
revenues = profitability_items['revenues']
revenues['data'] += revenue_items_from_sol['data']
revenues['total']['to_invoice'] += revenue_items_from_sol['total']['to_invoice']
@@ -57,7 +57,7 @@ class TestSaleProjectProfitability(TestProjectProfitabilityCommon, TestSaleCommo
def test_project_profitability(self):
self.assertFalse(self.project.allow_billable, 'The project should be non billable.')
self.assertDictEqual(
self.project._get_profitability_items(),
self.project._get_profitability_items(False),
self.project_profitability_items_empty,
'No data for the project profitability should be found since the project is not billable, so no SOL is linked to the project.'
)
@@ -65,7 +65,7 @@ class TestSaleProjectProfitability(TestProjectProfitabilityCommon, TestSaleCommo
self.assertTrue(self.project.allow_billable, 'The project should be billable.')
self.project.sale_line_id = self.delivery_service_order_line
self.assertDictEqual(
self.project._get_profitability_items(),
self.project._get_profitability_items(False),
self.project_profitability_items_empty,
'No data for the project profitability should be found since no product is delivered in the SO linked.'
)
@@ -77,7 +77,7 @@ class TestSaleProjectProfitability(TestProjectProfitabilityCommon, TestSaleCommo
['billable_manual', 'service_revenues'],
'invoice_type="billable_manual" if sale_timesheet is installed otherwise it is equal to "service_revenues"')
self.assertDictEqual(
self.project._get_profitability_items(),
self.project._get_profitability_items(False),
{
'revenues': {
'data': [
@@ -122,7 +122,7 @@ class TestSaleProjectProfitability(TestProjectProfitabilityCommon, TestSaleCommo
['billable_manual', 'service_revenues'],
'invoice_type="billable_manual" if sale_timesheet is installed otherwise it is equal to "service_revenues"')
self.assertDictEqual(
self.project._get_profitability_items(),
self.project._get_profitability_items(False),
{
'revenues': {
'data': [
@@ -163,7 +163,7 @@ class TestSaleProjectProfitability(TestProjectProfitabilityCommon, TestSaleCommo
['billable_manual', 'service_revenues'],
'invoice_type="billable_manual" if sale_timesheet is installed otherwise it is equal to "service_revenues"')
self.assertDictEqual(
self.project._get_profitability_items(),
self.project._get_profitability_items(False),
{
'revenues': {
'data': [
@@ -197,7 +197,7 @@ class TestSaleProjectProfitability(TestProjectProfitabilityCommon, TestSaleCommo
credit_notes = invoices._reverse_moves()
credit_notes.action_post()
self.assertDictEqual(
self.project._get_profitability_items(),
self.project._get_profitability_items(False),
{
'revenues': {
'data': [
@@ -226,6 +226,6 @@ class TestSaleProjectProfitability(TestProjectProfitabilityCommon, TestSaleCommo
self.sale_order._action_cancel()
self.assertDictEqual(
self.project._get_profitability_items(),
self.project._get_profitability_items(False),
self.project_profitability_items_empty,
)