[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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user