+
+
Save this page and come back here to set up the feature.
diff --git a/addons/sale_timesheet/__manifest__.py b/addons/sale_timesheet/__manifest__.py
index 543dad375e7..34cb04b6546 100644
--- a/addons/sale_timesheet/__manifest__.py
+++ b/addons/sale_timesheet/__manifest__.py
@@ -27,4 +27,4 @@ have real delivered quantities in sales orders.
'data/sale_service_demo.xml',
],
'auto_install': True,
-}
+}
\ No newline at end of file
diff --git a/addons/sale_timesheet/models/account.py b/addons/sale_timesheet/models/account.py
index 812b9b09b1b..7f319ead699 100644
--- a/addons/sale_timesheet/models/account.py
+++ b/addons/sale_timesheet/models/account.py
@@ -37,16 +37,28 @@ class AccountAnalyticLine(models.Model):
if values.get('amount'):
return {}
unit_amount = values.get('unit_amount', 0.0) or self.unit_amount
- user_id = values.get('user_id') or self.user_id.id or self._default_user()
- user = self.env['res.users'].browse([user_id])
- emp = self.env['hr.employee'].search([('user_id', '=', user_id)], limit=1)
- cost = emp and emp.timesheet_cost or 0.0
- uom = (emp or user).company_id.project_time_mode_id
- # Nominal employee cost = 1 * company project UoM (project_time_mode_id)
+
+ # find the employee
+ employee_id = values.get('employee_id') or self.employee_id.id or self._default_employee_id().id
+ employee = self.env['hr.employee'].browse(employee_id) if employee_id else self.env['hr.employee']
+ if not employee:
+ user_id = values.get('user_id') or self.user_id.id or self._default_user()
+ employee = self.env['hr.employee'].search([('user_id', '=', user_id)], limit=1)
+
+ # find the analytic account
+ account_id = values.get('account_id') or self.account_id.id
+ analytic_account = self.env['account.analytic.account'].browse(account_id) if account_id else self.env['account.analytic.account']
+
+ # convert employee cost into timesheet (analytic account) currency
+ uom = employee.company_id.project_time_mode_id
+ cost = employee.timesheet_cost or 0.0
+ amount = -unit_amount * cost
+ amount_converted = employee.currency_id.compute(amount, analytic_account.currency_id)
+
return {
- 'amount': -unit_amount * cost,
+ 'amount': amount_converted,
'product_uom_id': uom.id,
- 'account_id': values.get('account_id') or self.account_id.id or emp.account_id.id,
+ 'account_id': account_id,
}
return {}
diff --git a/addons/sale_timesheet/models/hr.py b/addons/sale_timesheet/models/hr.py
index 5964b77ab04..a9f94f57bb9 100644
--- a/addons/sale_timesheet/models/hr.py
+++ b/addons/sale_timesheet/models/hr.py
@@ -8,5 +8,5 @@ class HrEmployee(models.Model):
_inherit = 'hr.employee'
# FIXME: this field should be in module hr_timesheet, not sale_timesheet
- timesheet_cost = fields.Float('Timesheet Cost', default=0.0)
- account_id = fields.Many2one('account.account', string='Account')
+ timesheet_cost = fields.Monetary('Timesheet Cost', currency_field='currency_id', default=0.0)
+ currency_id = fields.Many2one('res.currency', related='company_id.currency_id', readonly=True)
diff --git a/addons/sale_timesheet/tests/test_sale_timesheet.py b/addons/sale_timesheet/tests/test_sale_timesheet.py
index 309650aee2f..d75991411cb 100644
--- a/addons/sale_timesheet/tests/test_sale_timesheet.py
+++ b/addons/sale_timesheet/tests/test_sale_timesheet.py
@@ -6,6 +6,19 @@ from odoo.addons.sale.tests.test_sale_common import TestSale
class TestSaleTimesheet(TestSale):
+
+ def setUp(self):
+ super(TestSaleTimesheet, self).setUp()
+ # link hr employee to res.users of sale tests
+ self.employee_user = self.env['hr.employee'].create({
+ 'name': 'Employee User',
+ 'user_id': self.user.id,
+ })
+ self.employee_manager = self.env['hr.employee'].create({
+ 'name': 'Employee Manager',
+ 'user_id': self.manager.id,
+ })
+
def test_timesheet_order(self):
""" Test timesheet invoicing with 'invoice on order' timetracked products """
# intial so
@@ -26,7 +39,7 @@ class TestSaleTimesheet(TestSale):
'name': 'Test Line',
'project_id': so.project_project_id.id,
'unit_amount': 10.5,
- 'user_id': self.manager.id,
+ 'employee_id': self.employee_user.id,
})
self.assertEqual(so.order_line.qty_delivered, 10.5, 'Sale Timesheet: timesheet does not increase delivered quantity on so line')
self.assertEqual(so.invoice_status, 'invoiced', 'Sale Timesheet: "invoice on order" timesheets should not modify the invoice_status of the so')
@@ -35,7 +48,7 @@ class TestSaleTimesheet(TestSale):
'name': 'Test Line',
'project_id': so.project_project_id.id,
'unit_amount': 39.5,
- 'user_id': self.user.id,
+ 'employee_id': self.employee_user.id,
})
self.assertEqual(so.order_line.qty_delivered, 50, 'Sale Timesheet: timesheet does not increase delivered quantity on so line')
self.assertEqual(so.invoice_status, 'invoiced', 'Sale Timesheet: "invoice on order" timesheets should not modify the invoice_status of the so')
@@ -44,7 +57,7 @@ class TestSaleTimesheet(TestSale):
'name': 'Test Line',
'project_id': so.project_project_id.id,
'unit_amount': 10,
- 'user_id': self.user.id,
+ 'employee_id': self.employee_user.id,
})
self.assertEqual(so.order_line.qty_delivered, 60, 'Sale Timesheet: timesheet does not increase delivered quantity on so line')
self.assertEqual(so.invoice_status, 'upselling', 'Sale Timesheet: "invoice on order" timesheets should not modify the invoice_status of the so')
@@ -69,7 +82,7 @@ class TestSaleTimesheet(TestSale):
'name': 'Test Line',
'project_id': so.project_project_id.id,
'unit_amount': 10.5,
- 'user_id': self.manager.id,
+ 'employee_id': self.employee_manager.id,
})
self.assertEqual(so.invoice_status, 'to invoice', 'Sale Timesheet: "invoice on delivery" timesheets should set the so in "to invoice" status when logged')
inv_id = so.action_invoice_create()
@@ -80,7 +93,7 @@ class TestSaleTimesheet(TestSale):
'name': 'Test Line',
'project_id': so.project_project_id.id,
'unit_amount': 39.5,
- 'user_id': self.user.id,
+ 'employee_id': self.employee_user.id,
})
self.assertEqual(so.invoice_status, 'to invoice', 'Sale Timesheet: "invoice on delivery" timesheets should not modify the invoice_status of the so')
so.action_invoice_create()
@@ -90,7 +103,7 @@ class TestSaleTimesheet(TestSale):
'name': 'Test Line',
'project_id': so.project_project_id.id,
'unit_amount': 10,
- 'user_id': self.user.id,
+ 'employee_id': self.employee_user.id,
})
self.assertEqual(so.invoice_status, 'to invoice', 'Sale Timesheet: supplementary timesheets do not change the status of the SO')
@@ -113,7 +126,7 @@ class TestSaleTimesheet(TestSale):
'name': 'Test Line',
'project_id': so.project_project_id.id,
'unit_amount': 16,
- 'user_id': self.manager.id,
+ 'employee_id': self.employee_manager.id,
})
self.assertEqual(so.order_line.qty_delivered, 2, 'Sale: uom conversion of timesheets is wrong')
@@ -121,7 +134,7 @@ class TestSaleTimesheet(TestSale):
'name': 'Test Line',
'project_id': so.project_project_id.id,
'unit_amount': 24,
- 'user_id': self.user.id,
+ 'employee_id': self.employee_user.id,
})
so.action_invoice_create()
self.assertEqual(so.invoice_status, 'invoiced', 'Sale Timesheet: "invoice on delivery" timesheets should not modify the invoice_status of the so')
diff --git a/addons/sale_timesheet/views/hr_views.xml b/addons/sale_timesheet/views/hr_views.xml
index 7b17e2dc67e..ce032cc01e0 100644
--- a/addons/sale_timesheet/views/hr_views.xml
+++ b/addons/sale_timesheet/views/hr_views.xml
@@ -3,13 +3,17 @@
hr.timesheet.employee.extd_form
hr.employee
-
+
-
-
-
-
-
+
+
+
+ per hour
+
+
+
+
+ 0