[FIX] sale_timesheet: no product on timesheet line

Timesheet lines are meant to have no product, and instead rely
on an implicit "Service" product. The UoM used is the company's
project UOM (project_time_mode_id), and the nominal cost of this
product is set on each employee.

Forcefully using the SO product as was done before is useless
and actually caused inconsistencies. The `unit_amount` value
would be expected in the UoM of the SO product, while still
being computed/set in the company's project UoM.

When no nominal cost can be found for an employee, the cost is
assumed to be 0, so the `amount` value is 0 too.

In addition, the product field is not supposed to be visible on
any form where timesheet lines are recorded.

This patch fixes various bits of logic related to this, including
parts which expected the `amount` value to be non-zero, or
the product to be set.
This commit is contained in:
Olivier Dony
2015-12-18 10:12:53 +01:00
parent 6579fc2d49
commit fde3a529ba
2 changed files with 12 additions and 31 deletions
+1 -1
View File
@@ -12,7 +12,7 @@ class SaleOrderLine(models.Model):
def _compute_analytic(self, domain=None):
lines = {}
if not domain:
domain = [('so_line', 'in', self.ids), ('amount', '<=', 0.0)]
domain = [('so_line', 'in', self.ids), ('unit_amount', '<=', 0.0)]
data = self.env['account.analytic.line'].read_group(
domain,
['so_line', 'unit_amount', 'product_uom_id'], ['product_uom_id', 'so_line'], lazy=False
+11 -30
View File
@@ -56,10 +56,7 @@ class AccountAnalyticLine(models.Model):
('product_id.type', '=', 'service')],
limit=1)
if sol:
result.update({
'so_line': sol.id,
'product_id': sol.product_id.id,
})
result['so_line'] = sol.id
result = self._get_timesheet_cost(result)
result = super(AccountAnalyticLine, self)._get_sale_order_line(vals=result)
@@ -70,33 +67,17 @@ class AccountAnalyticLine(models.Model):
if result.get('is_timesheet') or self.is_timesheet:
if result.get('amount'):
return result
unit_amount = result.get('unit_amount', 0.0) or self.unit_amount
user_id = result.get('user_id', False) or self.user_id.id
user_id = result.get('user_id') or self.user_id.id
user = self.env['res.users'].browse([user_id])
emp = self.env['hr.employee'].search([('user_id', '=', user_id)], limit=1)
if emp and emp.timesheet_cost:
# Most common case: cost obtained on employee
result.update({
'amount': -unit_amount * emp.timesheet_cost,
'product_uom_id': emp.user_id.company_id.project_time_mode_id.id,
})
elif result.get('product_id'):
# Only useful for _get_sale_order_line since it can add a product_id.
product = self.env['product.product'].browse([result.get('product_id')])
result.update({
'amount': -unit_amount * product.standard_price,
'product_uom_id': product.uom_id.id,
})
elif self.product_id:
# Only use case where this should be useful:
# - no cost on employee
# - modification of the unit amount of an existing entry
result.update({
'amount': -unit_amount * self.product_id.standard_price,
'product_uom_id': self.product_id.uom_id.id,
})
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)
result.update(
amount=(-unit_amount * emp.timesheet_cost),
product_uom_id=uom.id
)
return result
@api.multi
@@ -174,7 +155,7 @@ class SaleOrderLine(models.Model):
@api.multi
def _compute_analytic(self, domain=None):
if not domain:
domain = [('so_line', 'in', self.ids), '|', ('amount', '<=', 0.0), ('is_timesheet', '=', True)]
domain = [('so_line', 'in', self.ids), '|', ('unit_amount', '<=', 0.0), ('is_timesheet', '=', True)]
return super(SaleOrderLine, self)._compute_analytic(domain=domain)
@api.model