diff --git a/addons/sale_timesheet_margin/models/sale_order_line.py b/addons/sale_timesheet_margin/models/sale_order_line.py index 21dc60e7fa7e8e9489be54409d762d1d050e7b70..b744c941e0a403ca437d0e0ecd6cf5676d1a40ec 100644 --- a/addons/sale_timesheet_margin/models/sale_order_line.py +++ b/addons/sale_timesheet_margin/models/sale_order_line.py @@ -23,10 +23,11 @@ class SaleOrderLine(models.Model): for line in timesheet_sols: line = line.with_company(line.company_id) product_cost = mapped_sol_timesheet_amount.get(line.id, line.product_id.standard_price) - if line.product_id.uom_id != line.company_id.project_time_mode_id and\ - line.product_id.uom_id.category_id.id == line.company_id.project_time_mode_id.category_id.id: - product_cost = line.company_id.project_time_mode_id._compute_quantity( + product_uom = line.product_uom or line.product_id.uom_id + if product_uom != line.company_id.project_time_mode_id and\ + product_uom.category_id.id == line.company_id.project_time_mode_id.category_id.id: + product_cost = product_uom._compute_quantity( product_cost, - line.product_id.uom_id + line.company_id.project_time_mode_id ) - line.purchase_price = line._convert_price(product_cost, line.product_id.uom_id) + line.purchase_price = line._convert_price(product_cost, product_uom) diff --git a/addons/sale_timesheet_margin/tests/__init__.py b/addons/sale_timesheet_margin/tests/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..24d54ab8d5c8c30b790841e98fc5b7aa114dc099 --- /dev/null +++ b/addons/sale_timesheet_margin/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_sale_timesheet_margin diff --git a/addons/sale_timesheet_margin/tests/test_sale_timesheet_margin.py b/addons/sale_timesheet_margin/tests/test_sale_timesheet_margin.py new file mode 100644 index 0000000000000000000000000000000000000000..c590104ea99fbae452e08fc610fa2d8a251d2e84 --- /dev/null +++ b/addons/sale_timesheet_margin/tests/test_sale_timesheet_margin.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo.addons.sale_timesheet.tests.common import TestCommonSaleTimesheet +from odoo import Command +from odoo.tests import tagged + + +@tagged('-at_install', 'post_install') +class TestSaleTimesheetMargin(TestCommonSaleTimesheet): + + def setUp(self): + super(TestSaleTimesheetMargin, self).setUp() + uom_day_id = self.ref('uom.product_uom_day') + self.uom_day = self.env['uom.uom'].browse(uom_day_id) + self.product_1 = self.env['product.product'].create({ + 'name': "Service Ordered, create no task, uom day", + 'list_price': 1.0, + 'type': 'service', + 'invoice_policy': 'order', + 'uom_id': uom_day_id, + 'uom_po_id': uom_day_id, + 'default_code': 'SERV-ORDERED-DAY', + 'service_type': 'timesheet', + 'service_tracking': 'task_in_project', + 'project_id': False, + 'taxes_id': False, + }) + self.employee_manager.timesheet_cost = 10 + + def test_sale_timesheet_margin(self): + """ Test the timesheet cost is reported correctly in sale order line. """ + sale_order = self.env['sale.order'].create({ + 'name': 'Test_SO0001', + 'order_line': [ + Command.create({ + 'product_id': self.product_1.id, + 'price_unit': 1.0, + 'product_uom': self.uom_day.id, + 'product_uom_qty': 1.0, + })], + 'partner_id': self.partner_b.id, + 'partner_invoice_id': self.partner_b.id, + 'partner_shipping_id': self.partner_b.id, + }) + # Confirm the sales order, create project and task. + sale_order.action_confirm() + + # Add timesheet line + self.env['account.analytic.line'].create({ + 'name': 'Test Line', + 'unit_amount': 2, + 'employee_id': self.employee_manager.id, + 'project_id': sale_order.project_ids.id, + 'task_id': sale_order.order_line.task_id.id, + 'account_id': self.analytic_account_sale.id, + 'so_line': sale_order.order_line.id, + }) + sale_order.order_line._compute_purchase_price() + # Cost is expressed in SO line uom + expected_cost = self.uom_day._compute_quantity( + self.employee_manager.timesheet_cost, + self.env.company.project_time_mode_id + ) + self.assertEqual(sale_order.order_line.purchase_price, expected_cost, "Sale order line cost should be number of working hours on one day * timesheet cost of the employee set on the timesheet linked to the SOL.")