diff --git a/addons/hr_timesheet/models/__init__.py b/addons/hr_timesheet/models/__init__.py
index 1766ea8ddf9..4db761e1e09 100644
--- a/addons/hr_timesheet/models/__init__.py
+++ b/addons/hr_timesheet/models/__init__.py
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
+from . import hr
from . import hr_timesheet
from . import res_config_settings
from . import project
diff --git a/addons/sale_timesheet/models/hr.py b/addons/hr_timesheet/models/hr.py
similarity index 83%
rename from addons/sale_timesheet/models/hr.py
rename to addons/hr_timesheet/models/hr.py
index a9f94f57bb9..afedd48561e 100644
--- a/addons/sale_timesheet/models/hr.py
+++ b/addons/hr_timesheet/models/hr.py
@@ -7,6 +7,5 @@ from odoo import fields, models
class HrEmployee(models.Model):
_inherit = 'hr.employee'
- # FIXME: this field should be in module hr_timesheet, not sale_timesheet
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/hr_timesheet/models/hr_timesheet.py b/addons/hr_timesheet/models/hr_timesheet.py
index 30bb3c9dff2..dd4b83dad8b 100644
--- a/addons/hr_timesheet/models/hr_timesheet.py
+++ b/addons/hr_timesheet/models/hr_timesheet.py
@@ -40,14 +40,20 @@ class AccountAnalyticLine(models.Model):
line.department_id = line.employee_id.department_id
@api.model
- def create(self, vals):
- vals = self._timesheet_preprocess(vals)
- return super(AccountAnalyticLine, self).create(vals)
+ def create(self, values):
+ values = self._timesheet_preprocess(values)
+ result = super(AccountAnalyticLine, self).create(values)
+ if result.project_id: # applied only for timesheet
+ result._timesheet_postprocess(values)
+ return result
@api.multi
- def write(self, vals):
- vals = self._timesheet_preprocess(vals)
- return super(AccountAnalyticLine, self).write(vals)
+ def write(self, values):
+ values = self._timesheet_preprocess(values)
+ result = super(AccountAnalyticLine, self).write(values)
+ # applied only for timesheet
+ self.filtered(lambda t: t.project_id)._timesheet_postprocess(values)
+ return result
def _timesheet_preprocess(self, vals):
""" Deduce other field values from the one given.
@@ -79,3 +85,34 @@ class AccountAnalyticLine(models.Model):
if partner_id:
vals['partner_id'] = partner_id
return vals
+
+ @api.multi
+ def _timesheet_postprocess(self, values):
+ """ Hook to update record one by one according to the values of a `write` or a `create`. """
+ sudo_self = self.sudo() # this creates only one env for all operation that required sudo() in `_timesheet_postprocess_values`override
+ values_to_write = self._timesheet_postprocess_values(values)
+ for timesheet in sudo_self:
+ if values_to_write[timesheet.id]:
+ timesheet.write(values_to_write[timesheet.id])
+ return values
+
+ @api.multi
+ def _timesheet_postprocess_values(self, values):
+ """ Get the addionnal values to write on record
+ :param dict values: values for the model's fields, as a dictionary::
+ {'field_name': field_value, ...}
+ :return: a dictionary mapping each record id to its corresponding
+ dictionnary values to write (may be empty).
+ """
+ result = dict.fromkeys(self.ids, dict())
+ sudo_self = self.sudo() # this creates only one env for all operation that required sudo()
+ # (re)compute the amount (depending on unit_amount, employee_id for the cost, and account_id for currency)
+ if any([field_name in values for field_name in ['unit_amount', 'employee_id', 'account_id']]):
+ for timesheet in sudo_self:
+ cost = timesheet.employee_id.timesheet_cost or 0.0
+ amount = -timesheet.unit_amount * cost
+ amount_converted = timesheet.employee_id.currency_id.compute(amount, timesheet.account_id.currency_id)
+ result[timesheet.id].update({
+ 'amount': amount_converted,
+ })
+ return result
diff --git a/addons/hr_timesheet/views/hr_views.xml b/addons/hr_timesheet/views/hr_views.xml
index 21c645d8159..170bd7e861f 100644
--- a/addons/hr_timesheet/views/hr_views.xml
+++ b/addons/hr_timesheet/views/hr_views.xml
@@ -19,8 +19,12 @@
-
-
+
+
+
+ per hour
+
+
diff --git a/addons/sale_timesheet/__manifest__.py b/addons/sale_timesheet/__manifest__.py
index f0d059b1e65..b9cfe6c47e0 100644
--- a/addons/sale_timesheet/__manifest__.py
+++ b/addons/sale_timesheet/__manifest__.py
@@ -21,7 +21,6 @@ have real delivered quantities in sales orders.
'views/account_invoice_views.xml',
'views/sale_order_views.xml',
'views/product_views.xml',
- 'views/hr_views.xml',
'views/project_task_views.xml',
'views/hr_timesheet_views.xml',
'views/res_config_settings_views.xml',
diff --git a/addons/sale_timesheet/models/__init__.py b/addons/sale_timesheet/models/__init__.py
index d22baec4d49..e6421022c33 100644
--- a/addons/sale_timesheet/models/__init__.py
+++ b/addons/sale_timesheet/models/__init__.py
@@ -3,7 +3,6 @@
from . import account
from . import account_invoice
-from . import hr
from . import product
from . import project
from . import sale_order
diff --git a/addons/sale_timesheet/models/account.py b/addons/sale_timesheet/models/account.py
index 23a5b3a5f67..87ec0a10f2c 100644
--- a/addons/sale_timesheet/models/account.py
+++ b/addons/sale_timesheet/models/account.py
@@ -21,14 +21,6 @@ class AccountAnalyticLine(models.Model):
timesheet_invoice_id = fields.Many2one('account.invoice', string="Invoice", readonly=True, copy=False, help="Invoice created from the timesheet")
timesheet_revenue = fields.Monetary("Revenue", default=0.0, readonly=True, copy=False)
- @api.model
- def create(self, values):
- result = super(AccountAnalyticLine, self).create(values)
- # applied only for timesheet
- if result.project_id:
- result._timesheet_postprocess(values)
- return result
-
@api.multi
def write(self, values):
# prevent to update invoiced timesheets if one line is of type delivery
@@ -36,8 +28,6 @@ class AccountAnalyticLine(models.Model):
if any([field_name in values for field_name in ['unit_amount', 'employee_id', 'task_id', 'timesheet_revenue', 'so_line', 'amount', 'date']]):
raise UserError(_('You can not modify already invoiced timesheets (linked to a Sales order items invoiced on Time and material).'))
result = super(AccountAnalyticLine, self).write(values)
- # applied only for timesheet
- self.filtered(lambda t: t.project_id)._timesheet_postprocess(values)
return result
@api.model
@@ -55,30 +45,23 @@ class AccountAnalyticLine(models.Model):
return values
@api.multi
- def _timesheet_postprocess(self, values):
+ def _timesheet_postprocess_values(self, values):
sudo_self = self.sudo() # this creates only one env for all operation that required sudo()
- # (re)compute the amount (depending on unit_amount, employee_id for the cost, and account_id for currency)
- if any([field_name in values for field_name in ['unit_amount', 'employee_id', 'account_id']]):
+ result = super(AccountAnalyticLine, self)._timesheet_postprocess_values(values)
+ # (re)compute the UoM from the employee company
+ if any([field_name in values for field_name in ['employee_id']]):
for timesheet in sudo_self:
uom = timesheet.employee_id.company_id.project_time_mode_id
- cost = timesheet.employee_id.timesheet_cost or 0.0
- amount = -timesheet.unit_amount * cost
- amount_converted = timesheet.employee_id.currency_id.compute(amount, timesheet.account_id.currency_id)
- timesheet.write({
- 'amount': amount_converted,
+ result[timesheet.id].update({
'product_uom_id': uom.id,
})
# (re)compute the theorical revenue
if any([field_name in values for field_name in ['so_line', 'unit_amount', 'account_id']]):
- sudo_self._timesheet_compute_theorical_revenue()
- return values
-
- @api.multi
- def _timesheet_compute_theorical_revenue(self):
- for timesheet in self:
- values = timesheet._timesheet_compute_theorical_revenue_values()
- timesheet.write(values)
- return True
+ for timesheet in sudo_self:
+ values_to_write = timesheet._timesheet_compute_theorical_revenue_values()
+ if values_to_write:
+ result[timesheet.id].update(values_to_write)
+ return result
@api.multi
def _timesheet_compute_theorical_revenue_values(self):
@@ -93,6 +76,9 @@ class AccountAnalyticLine(models.Model):
)
else:
0
+
+ :return: a dictionary mapping each record id to its corresponding
+ dictionnary values to write (may be empty).
"""
self.ensure_one()
timesheet = self
diff --git a/addons/sale_timesheet/views/hr_views.xml b/addons/sale_timesheet/views/hr_views.xml
deleted file mode 100644
index ce032cc01e0..00000000000
--- a/addons/sale_timesheet/views/hr_views.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
- hr.timesheet.employee.extd_form
- hr.employee
-
-
-
-
-