From 88d94c852ac458e09a710e27e9317f4589d0d446 Mon Sep 17 00:00:00 2001 From: "Xavier BOL (xbo)" Date: Fri, 18 Mar 2022 10:28:37 +0100 Subject: [PATCH] [IMP] sale_timesheet: add billable_{milestones,manual} in timesheet_invoice_type --- addons/sale_project_stock/models/sale_order_line.py | 4 +--- addons/sale_timesheet/models/account.py | 7 +++++-- addons/sale_timesheet/models/project.py | 4 +++- addons/sale_timesheet/tests/test_project_profitability.py | 2 +- addons/sale_timesheet/tests/test_sale_timesheet.py | 4 ++-- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/addons/sale_project_stock/models/sale_order_line.py b/addons/sale_project_stock/models/sale_order_line.py index 5008b7395d1..79d008f4a7c 100644 --- a/addons/sale_project_stock/models/sale_order_line.py +++ b/addons/sale_project_stock/models/sale_order_line.py @@ -6,12 +6,10 @@ from odoo import fields, models class SaleOrderLine(models.Model): _inherit = 'sale.order.line' - # FIXME: see if we move this computed field into sale_stock module. stock_move_count = fields.Integer(compute='_compute_stock_move_count') - @api.depends('move_ids') def _compute_stock_move_count(self): - stock_move_read_group = self.env['stock.move'].read_group([('sale_line_id', 'in', self.ids)], ['sale_line_id'], ['sale_line_id']) + stock_move_read_group = self.env['stock.move']._read_group([('sale_line_id', 'in', self.ids)], ['sale_line_id'], ['sale_line_id']) stock_move_count_per_sol = {res['sale_line_id'][0]: res['sale_line_id_count'] for res in stock_move_read_group} for sol in self: sol.stock_move_count = stock_move_count_per_sol.get(sol.id, 0) diff --git a/addons/sale_timesheet/models/account.py b/addons/sale_timesheet/models/account.py index b2c0a737fef..4f77f7f8ab6 100644 --- a/addons/sale_timesheet/models/account.py +++ b/addons/sale_timesheet/models/account.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo.exceptions import UserError, ValidationError +from odoo.exceptions import UserError from odoo import api, fields, models, _ from odoo.osv import expression @@ -17,6 +17,8 @@ class AccountAnalyticLine(models.Model): timesheet_invoice_type = fields.Selection([ ('billable_time', 'Billed on Timesheets'), ('billable_fixed', 'Billed at a Fixed price'), + ('billable_milestones', 'Billed on Milestones'), + ('billable_manual', 'Billed Manually'), ('non_billable', 'Non Billable Tasks'), ('timesheet_revenues', 'Timesheet Revenues'), ('service_revenues', 'Service Revenues'), @@ -45,7 +47,8 @@ class AccountAnalyticLine(models.Model): if timesheet.so_line.product_id.service_type == 'timesheet': invoice_type = 'timesheet_revenues' if timesheet.amount > 0 else 'billable_time' else: - invoice_type = 'billable_fixed' + service_type = timesheet.so_line.product_id.service_type + invoice_type = f'billable_{service_type}' if service_type in ['milestones', 'manual'] else 'billable_fixed' elif timesheet.so_line.product_id.invoice_policy == 'order': invoice_type = 'billable_fixed' timesheet.timesheet_invoice_type = invoice_type diff --git a/addons/sale_timesheet/models/project.py b/addons/sale_timesheet/models/project.py index 91801fd0a34..e25449e2cc8 100644 --- a/addons/sale_timesheet/models/project.py +++ b/addons/sale_timesheet/models/project.py @@ -389,6 +389,8 @@ class Project(models.Model): **super()._get_profitability_labels(), 'billable_fixed': _lt('Timesheets (Fixed Price)'), 'billable_time': _lt('Timesheets (Billed on Timesheets)'), + 'billable_milestones': _lt('Timesheets (Billed on Milestones)'), + 'billable_manual': _lt('Timesheets (Billed Manually)'), 'non_billable': _lt('Timesheets (Non Billable)'), } @@ -404,7 +406,7 @@ class Project(models.Model): total_invoiced = total_to_invoice = 0.0 revenue_data = [] for revenue in profitability_items['revenues']['data']: - if revenue['id'] in ['billable_fixed', 'billable_time', 'billable_milestones']: + if revenue['id'] in ['billable_fixed', 'billable_time', 'billable_milestones', 'billable_manual']: continue total_invoiced += revenue['invoiced'] total_to_invoice += revenue['to_invoice'] diff --git a/addons/sale_timesheet/tests/test_project_profitability.py b/addons/sale_timesheet/tests/test_project_profitability.py index 8be9cbcf221..99c08176245 100644 --- a/addons/sale_timesheet/tests/test_project_profitability.py +++ b/addons/sale_timesheet/tests/test_project_profitability.py @@ -87,7 +87,7 @@ class TestSaleTimesheetProjectProfitability(TestCommonSaleTimesheet): 'costs': { 'data': [ { - 'id': 'billable_fixed', + 'id': 'billable_manual', 'billed': (timesheet1.unit_amount + timesheet2.unit_amount) * -self.employee_user.timesheet_cost, 'to_bill': 0.0, }, diff --git a/addons/sale_timesheet/tests/test_sale_timesheet.py b/addons/sale_timesheet/tests/test_sale_timesheet.py index ac1caf39f18..a05b9bd03c4 100644 --- a/addons/sale_timesheet/tests/test_sale_timesheet.py +++ b/addons/sale_timesheet/tests/test_sale_timesheet.py @@ -322,13 +322,13 @@ class TestSaleTimesheet(TestCommonSaleTimesheet): self.assertEqual(len(sale_order.project_ids), 2, "One project should have been created by the SO, when confirmed + the one coming from SO line 1 'task in global project'.") self.assertEqual(so_line_manual_global_project.task_id.sale_line_id, so_line_manual_global_project, "Task from a milestone product should be linked to its SO line too") - self.assertEqual(timesheet1.timesheet_invoice_type, 'billable_fixed', "Milestone timesheet goes in billable fixed category") + self.assertEqual(timesheet1.timesheet_invoice_type, 'billable_manual', "Milestone timesheet goes in billable manual category") self.assertTrue(float_is_zero(so_line_manual_global_project.qty_delivered, precision_digits=2), "Milestone Timesheeting should not incremented the delivered quantity on the SO line") self.assertEqual(so_line_manual_global_project.qty_to_invoice, 0.0, "Manual service should not be affected by timesheet on their created task.") self.assertEqual(so_line_manual_only_project.qty_to_invoice, 0.0, "Manual service should not be affected by timesheet on their created project.") self.assertEqual(sale_order.invoice_status, 'no', 'Sale Timesheet: "invoice on delivery" should not need to be invoiced on so confirmation') - self.assertEqual(timesheet1.timesheet_invoice_type, 'billable_fixed', "Timesheets linked to SO line with ordered product shoulbe be billable fixed since it is a milestone") + self.assertEqual(timesheet1.timesheet_invoice_type, 'billable_manual', "Timesheets linked to SO line with ordered product shoulbe be billable fixed since it is a prepaid product.") self.assertEqual(timesheet2.timesheet_invoice_type, 'non_billable', "Timesheets without SO should be be 'non-billable'") self.assertFalse(timesheet1.timesheet_invoice_id, "The timesheet1 should not be linked to the invoice") self.assertFalse(timesheet2.timesheet_invoice_id, "The timesheet2 should not be linked to the invoice")