[FIX] sale_timesheet: correctly handle multi currency and rounding
This commit is contained in:
@@ -63,6 +63,9 @@ class AccountAnalyticLine(models.Model):
|
||||
|
||||
# find the analytic account
|
||||
account_id = values.get('account_id') or self.account_id.id
|
||||
if not account_id and values.get('project_id'):
|
||||
project = self.env['project.project'].browse(values['project_id'])
|
||||
account_id = project.analytic_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
|
||||
@@ -107,13 +110,13 @@ class AccountAnalyticLine(models.Model):
|
||||
analytic_account = self.env['account.analytic.account'].browse(account_id)
|
||||
# calculate the revenue on the timesheet
|
||||
if so_line.product_id.invoice_policy == 'delivery':
|
||||
delivered_revenue = unit_amount * so_line.price_unit * (1-so_line.discount)
|
||||
revenue = so_line.currency_id.compute(delivered_revenue, analytic_account.currency_id) # amount from SO should be convert into analytic account currency
|
||||
sale_price_unit = so_line.currency_id.compute(so_line.price_unit, analytic_account.currency_id) # amount from SO should be convert into analytic account currency
|
||||
revenue = analytic_account.currency_id.round(unit_amount * sale_price_unit * (1-so_line.discount))
|
||||
billable_type = 'billable_time'
|
||||
elif so_line.product_id.invoice_policy == 'order' and so_line.product_id.track_service == 'task':
|
||||
# compute the total revenue the SO since we are in fixed price
|
||||
total_revenue_so = so_line.product_uom_qty * so_line.price_unit * (1-so_line.discount)
|
||||
total_revenue_so = so_line.currency_id.compute(total_revenue_so, analytic_account.currency_id)
|
||||
sale_price_unit = so_line.currency_id.compute(so_line.price_unit, analytic_account.currency_id)
|
||||
total_revenue_so = analytic_account.currency_id.round(so_line.product_uom_qty * sale_price_unit * (1-so_line.discount))
|
||||
# compute the total revenue already existing (without the current timesheet line)
|
||||
domain = [('so_line', '=', so_line.id)]
|
||||
if self.ids:
|
||||
@@ -122,7 +125,7 @@ class AccountAnalyticLine(models.Model):
|
||||
total_revenue_invoiced = sum(analytic_lines.mapped('timesheet_revenue'))
|
||||
# compute (new) revenue of current timesheet line
|
||||
revenue = min(
|
||||
so_line.currency_id.compute(unit_amount * (so_line.price_unit) * (1-so_line.discount), analytic_account.currency_id),
|
||||
analytic_account.currency_id.round(unit_amount * so_line.currency_id.compute(so_line.price_unit, analytic_account.currency_id) * (1-so_line.discount)),
|
||||
total_revenue_so - total_revenue_invoiced
|
||||
)
|
||||
billable_type = 'billable_fixed'
|
||||
|
||||
@@ -71,14 +71,14 @@ class AccountInvoice(models.Model):
|
||||
total_revenue_per_currency = dict.fromkeys(uninvoiced_timesheet_lines.mapped('company_currency_id').ids, 0.0)
|
||||
for index, timesheet_line in enumerate(uninvoiced_timesheet_lines):
|
||||
if index+1 != len(uninvoiced_timesheet_lines):
|
||||
line_revenue = invoiced_price_per_hour * timesheet_line.unit_amount
|
||||
line_revenue = invoice_line.currency_id.compute(invoiced_price_per_hour, timesheet_line.company_currency_id) * timesheet_line.unit_amount
|
||||
total_revenue_per_currency[timesheet_line.company_currency_id.id] += line_revenue
|
||||
else: # last line: add the difference to avoid rounding problem
|
||||
total_revenue = sum([self.env['res.currency'].browse(currency_id).compute(amount, timesheet_line.company_currency_id) for currency_id, amount in total_revenue_per_currency.items()])
|
||||
line_revenue = invoice_line.price_subtotal - total_revenue
|
||||
line_revenue = invoice_line.currency_id.compute(invoice_line.price_subtotal, timesheet_line.company_currency_id) - total_revenue
|
||||
timesheet_line.write({
|
||||
'timesheet_invoice_id': invoice.id,
|
||||
'timesheet_revenue': float_round(line_revenue, precision),
|
||||
'timesheet_revenue': timesheet_line.company_currency_id.round(line_revenue),
|
||||
})
|
||||
|
||||
# ordered : update revenue with the prorata of theorical revenue
|
||||
@@ -105,5 +105,5 @@ class AccountInvoice(models.Model):
|
||||
|
||||
timesheet_line.write({
|
||||
'timesheet_invoice_id': invoice.id,
|
||||
'timesheet_revenue': float_round(line_revenue, precision),
|
||||
'timesheet_revenue': timesheet_line.company_currency_id.round(line_revenue),
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user