Skip to content
Permalink
Browse files

[IMP] account, l10n_*: v13 taxes

- Add repartition lines on taxes

- Link account tags directly to account.move.line; remove the tag_ids field from account.tag

- Add a new report engine dedicated to tax reports, directly generating account tags. It is called as an alternate mode of generic tax report, with a dedicated "Use tax grids" toggle.

>> The biggest change lies in the way the new tax report computes its values.
Everything is now aggregated directly using the tags set on the account move lines. Thanks to that,
modifying the configuration of a tax today will not impact the report for the previous periods anymore.
This is a big improvement, as it means the report will keep on reflecting the values that were submitted
to the state before, whatever the configuration change.

- Add an audit char field to account.move.line telling with tax grids are impacted by the line, with the corresponding amount

- Modify the behavior of cash basis taxes: the cash basis account is now used as the transition account, while the regular account given in tax declaration is used to store the final entry (it was the opposite before)

- Modify every l10n_* module in order to keep them consistent with these changes

closes #32833

Signed-off-by: Quentin De Paoli (qdp) <qdp@openerp.com>
  • Loading branch information...
oco-odoo committed Apr 19, 2019
1 parent 574295d commit 3936d655c4bfd845b6ead724cecdc8e7c62816eb
Showing with 48,828 additions and 13,413 deletions.
  1. +1 −0 addons/account/__manifest__.py
  2. +243 −49 addons/account/models/account.py
  3. +108 −58 addons/account/models/account_invoice.py
  4. +91 −61 addons/account/models/account_move.py
  5. +116 −27 addons/account/models/chart_template.py
  6. +2 −0 addons/account/models/product.py
  7. +7 −0 addons/account/security/account_security.xml
  8. +6 −0 addons/account/security/ir.model.access.csv
  9. +27 −3 addons/account/tests/test_account_customer_invoice.py
  10. +99 −7 addons/account/tests/test_invoice_taxes.py
  11. +32 −9 addons/account/tests/test_reconciliation.py
  12. +24 −2 addons/account/tests/test_tax.py
  13. +2 −0 addons/account/tests/test_templates_consistency.py
  14. +5 −1 addons/account/views/account_invoice_view.xml
  15. +4 −0 addons/account/views/account_move_views.xml
  16. +76 −0 addons/account/views/account_tax_report_views.xml
  17. +40 −26 addons/account/views/account_view.xml
  18. +25 −14 addons/account/wizard/wizard_tax_adjustments.py
  19. +2 −1 addons/account_facturx/data/facturx_templates.xml
  20. +2 −2 addons/account_tax_python/models/account_tax.py
  21. +1 −1 addons/hr_expense/models/hr_expense.py
  22. +48 −4 addons/l10n_ae/data/account_tax_template_data.xml
  23. +1 −0 addons/l10n_ar/__manifest__.py
  24. +230 −187 addons/l10n_ar/data/account_tax_data.xml
  25. +183 −0 addons/l10n_ar/data/account_tax_report_data.xml
  26. +1 −0 addons/l10n_at/__manifest__.py
  27. +367 −253 addons/l10n_at/data/account_tax_data.xml
  28. +205 −0 addons/l10n_at/data/account_tax_report_data.xml
  29. +2 −2 addons/l10n_au/__manifest__.py
  30. +0 −16 addons/l10n_au/data/account.account.tag.csv
  31. +0 −16 addons/l10n_au/data/account.tax.template.csv
  32. +228 −0 addons/l10n_au/data/account_tax_report_data.xml
  33. +550 −0 addons/l10n_au/data/account_tax_template_data.xml
  34. +1 −0 addons/l10n_be/__manifest__.py
  35. +325 −0 addons/l10n_be/data/account_tax_report_data.xml
  36. +2,515 −1,202 addons/l10n_be/data/account_tax_template_data.xml
  37. +1 −0 addons/l10n_bo/__manifest__.py
  38. +99 −137 addons/l10n_bo/data/account_tax_data.xml
  39. +152 −0 addons/l10n_bo/data/account_tax_report_data.xml
  40. +1 −0 addons/l10n_br/__manifest__.py
  41. +910 −0 addons/l10n_br/data/account_tax_report_data.xml
  42. +2,221 −890 addons/l10n_br/data/account_tax_template_data.xml
  43. +597 −135 addons/l10n_ca/data/account_tax_data.xml
  44. +1 −0 addons/l10n_ch/__manifest__.py
  45. +1 −1 addons/l10n_ch/data/account_fiscal_position_data.xml
  46. +261 −0 addons/l10n_ch/data/account_tax_report_data.xml
  47. +585 −186 addons/l10n_ch/data/account_vat2011_data.xml
  48. +1 −0 addons/l10n_cl/__manifest__.py
  49. +59 −113 addons/l10n_cl/data/account_tax_data.xml
  50. +146 −0 addons/l10n_cl/data/account_tax_report_data.xml
  51. +264 −24 addons/l10n_cn_small_business/data/account_tax_template_data.xml
  52. +265 −24 addons/l10n_cn_standard/data/account_tax_template_data.xml
  53. +1 −1 addons/l10n_co/__manifest__.py
  54. +0 −60 addons/l10n_co/data/account.tax.template.csv
  55. +1,847 −0 addons/l10n_co/data/account_tax_template.xml
  56. +48 −16 addons/l10n_cr/data/account_tax_template_data.xml
  57. +0 −1 addons/l10n_de/__manifest__.py
  58. +794 −485 addons/l10n_de/data/account_account_tags_data.xml
  59. +2,018 −583 addons/l10n_de_skr03/data/account_tax_fiscal_position_data.xml
  60. +2,089 −583 addons/l10n_de_skr04/data/account_tax_fiscal_position_data.xml
  61. +1 −0 addons/l10n_do/__manifest__.py
  62. +843 −91 addons/l10n_do/data/account.tax.template.xml
  63. +1 −93 addons/l10n_do/data/account_account_tag_data.xml
  64. +1 −1 addons/l10n_do/data/account_data.xml
  65. +143 −0 addons/l10n_do/data/account_tax_report_data.xml
  66. +1 −1 addons/l10n_do/data/fiscal_position_template.xml
  67. +9 −11 addons/l10n_do/data/l10n_do_chart_data.xml
  68. +1 −1 addons/l10n_do/data/l10n_do_state_data.xml
  69. +366 −175 addons/l10n_ec/data/account_tax_data.xml
  70. +2,769 −647 addons/l10n_es/data/account_tax_data.xml
  71. +2 −2 addons/l10n_et/__manifest__.py
  72. +0 −14 addons/l10n_et/data/account.tax.template.csv
  73. +0 −120 addons/l10n_et/data/account_account_tag_data.xml
  74. +462 −0 addons/l10n_et/data/account_tax_data.xml
  75. +222 −0 addons/l10n_et/data/account_tax_report_data.xml
  76. +1 −0 addons/l10n_fr/__manifest__.py
  77. +1,729 −1,098 addons/l10n_fr/data/account_tax_data.xml
  78. +750 −0 addons/l10n_fr/data/tax_report_data.xml
  79. +64 −18 addons/l10n_generic_coa/data/account_tax_template_data.xml
  80. +1 −0 addons/l10n_gr/__manifest__.py
  81. +211 −95 addons/l10n_gr/data/account_tax_data.xml
  82. +101 −0 addons/l10n_gr/data/account_tax_report_data.xml
  83. +44 −17 addons/l10n_gt/data/account_chart_template_data.xml
  84. +44 −16 addons/l10n_hn/data/account_chart_template_data.xml
  85. +2 −1 addons/l10n_hr/__manifest__.py
  86. +0 −42 addons/l10n_hr/data/account.tax.template.csv
  87. +0 −405 addons/l10n_hr/data/account_chart_tag_data.xml
  88. +643 −0 addons/l10n_hr/data/account_tax_report_data.xml
  89. +1,247 −0 addons/l10n_hr/data/account_tax_template_data.xml
  90. +2 −2 addons/l10n_hu/__manifest__.py
  91. +0 −26 addons/l10n_hu/data/account.account.tag.csv
  92. +0 −18 addons/l10n_hu/data/account.tax.template.csv
  93. +184 −0 addons/l10n_hu/data/account_tax_report_data.xml
  94. +626 −0 addons/l10n_hu/data/account_tax_template_data.xml
  95. +1 −2 addons/l10n_ie/__manifest__.py
  96. +0 −18 addons/l10n_ie/data/account.account.tag.csv
  97. +0 −18 addons/l10n_ie/data/account.tax.template.csv
  98. +479 −0 addons/l10n_ie/data/account_tax_data.xml
  99. +0 −6 addons/l10n_in/data/account_data.xml
  100. +31 −17 addons/l10n_in/data/account_invoice_demo.xml
  101. +1,073 −410 addons/l10n_in/data/account_tax_template_data.xml
  102. +3 −3 addons/l10n_in/models/account_invoice.py
  103. +20 −17 addons/l10n_in/report/account_invoice_report.py
  104. +12 −15 addons/l10n_in/report/account_payment_report.py
  105. +17 −14 addons/l10n_in/report/hsn_gst_report.py
  106. +1 −1 addons/l10n_it/__manifest__.py
  107. +0 −84 addons/l10n_it/data/account.tax.template.csv
  108. +1,738 −0 addons/l10n_it/data/account_tax_template.xml
  109. +0 −181 addons/l10n_it/data/l10n_it_chart_data.xml
  110. +2 −1 addons/l10n_jp/__manifest__.py
  111. +0 −9 addons/l10n_jp/data/account.tax.template.csv
  112. +140 −0 addons/l10n_jp/data/account_tax_report_data.xml
  113. +305 −0 addons/l10n_jp/data/account_tax_template_data.xml
  114. +0 −75 addons/l10n_jp/data/l10n_jp_chart_data.xml
  115. +2 −2 addons/l10n_lu/__manifest__.py
  116. +0 −598 addons/l10n_lu/data/account.account.tag.csv
  117. +0 −48 addons/l10n_lu/data/account.fiscal.position.tax.template-2015.csv
  118. +0 −408 addons/l10n_lu/data/account.tax.template-2015.csv
  119. +1,098 −0 addons/l10n_lu/data/account_tax_report_line.xml
  120. +5,314 −0 addons/l10n_lu/data/account_tax_template_2015.xml
  121. +1 −0 addons/l10n_ma/__manifest__.py
  122. +369 −155 addons/l10n_ma/data/account_tax_data.xml
  123. +301 −0 addons/l10n_ma/data/account_tax_report_data.xml
  124. +313 −57 addons/l10n_mx/data/account_tax_data.xml
  125. +1 −0 addons/l10n_nl/__manifest__.py
  126. +1 −160 addons/l10n_nl/data/account_account_tag.xml
  127. +270 −0 addons/l10n_nl/data/account_tax_report_data.xml
  128. +1,329 −578 addons/l10n_nl/data/account_tax_template.xml
  129. +3 −1 addons/l10n_no/__manifest__.py
  130. +353 −187 addons/l10n_no/data/account_tax_data.xml
  131. +140 −0 addons/l10n_no/data/account_tax_report_data.xml
  132. +1 −2 addons/l10n_nz/__manifest__.py
  133. +0 −9 addons/l10n_nz/data/account.account.tag.csv
  134. +0 −9 addons/l10n_nz/data/account.tax.template.csv
  135. +283 −0 addons/l10n_nz/data/account_tax_template_data.xml
  136. +48 −16 addons/l10n_pa/data/account_tax_data.xml
  137. +91 −43 addons/l10n_pe/data/account_tax_data.xml
  138. +1 −0 addons/l10n_pl/__manifest__.py
  139. +935 −523 addons/l10n_pl/data/account_tax_data.xml
  140. +383 −0 addons/l10n_pl/data/account_tax_report_data.xml
  141. +176 −43 addons/l10n_pt/data/account_tax_data.xml
  142. +1 −0 addons/l10n_ro/__manifest__.py
  143. +906 −642 addons/l10n_ro/data/account_tax_data.xml
  144. +785 −0 addons/l10n_ro/data/account_tax_report_data.xml
  145. +1 −0 addons/l10n_sg/__manifest__.py
  146. +728 −492 addons/l10n_sg/data/account_tax_data.xml
  147. +119 −0 addons/l10n_sg/data/account_tax_report_data.xml
  148. +2 −2 addons/l10n_si/__manifest__.py
  149. +0 −15 addons/l10n_si/data/account.account.tag.csv
  150. +0 −15 addons/l10n_si/data/account.tax.template.csv
  151. +390 −0 addons/l10n_si/data/account_tax_data.xml
  152. +198 −0 addons/l10n_si/data/account_tax_report_data.xml
  153. +86 −29 addons/l10n_syscohada/data/account_tax_template_data.xml
  154. +1 −0 addons/l10n_th/__manifest__.py
  155. +173 −0 addons/l10n_th/data/account_tax_report_data.xml
  156. +363 −38 addons/l10n_th/data/account_tax_template_data.xml
  157. +0 −91 addons/l10n_th/data/l10n_th_chart_data.xml
  158. +44 −12 addons/l10n_tr/data/account_tax_template_data.xml
  159. +2 −2 addons/l10n_uk/__manifest__.py
  160. +0 −8 addons/l10n_uk/data/account.account.tag.csv
  161. +0 −14 addons/l10n_uk/data/account.tax.template.csv
  162. +408 −0 addons/l10n_uk/data/account_tax_data.xml
  163. +99 −0 addons/l10n_uk/data/account_tax_report_data.xml
  164. +1 −0 addons/l10n_uy/__manifest__.py
  165. +207 −95 addons/l10n_uy/data/account_tax_data.xml
  166. +184 −0 addons/l10n_uy/data/account_tax_report_data.xml
  167. +176 −60 addons/l10n_ve/data/account_tax_data.xml
  168. +1 −0 addons/l10n_vn/__manifest__.py
  169. +152 −91 addons/l10n_vn/data/account_tax_data.xml
  170. +138 −0 addons/l10n_vn/data/account_tax_report_data.xml
  171. +8 −3 addons/point_of_sale/models/pos_order.py
  172. +1 −2 addons/point_of_sale/tests/common.py
  173. +4 −3 addons/purchase_stock/models/account_invoice.py
  174. +15 −15 addons/sale_coupon/tests/test_program_numbers.py
@@ -62,6 +62,7 @@
'data/account_incoterms_data.xml',
'views/digest_views.xml',
'wizard/account_invoice_send_views.xml',
'views/account_tax_report_views.xml',
],
'demo': [
'demo/account_demo.xml',

Large diffs are not rendered by default.

@@ -860,6 +860,7 @@ def _onchange_invoice_line_ids(self):
taxes_grouped = self.get_taxes_values()
tax_lines = self.tax_line_ids.filtered('manual')
for tax in taxes_grouped.values():
# ATTENTION: due to this, fields in tax have to be in the view (possibly invisible), as they won't be saved otherwise (when hitting "save")
tax_lines += tax_lines.new(tax)
self.tax_line_ids = tax_lines
return
@@ -1093,9 +1094,10 @@ def _prepare_tax_line_vals(self, line, tax, tax_ids):
'manual': False,
'sequence': tax['sequence'],
'account_analytic_id': tax['analytic'] and line.account_analytic_id.id or False,
'account_id': self.type in ('out_invoice', 'in_invoice') and (tax['account_id'] or line.account_id.id) or (tax['refund_account_id'] or line.account_id.id),
'account_id': tax['account_id'] or line.account_id.id,
'analytic_tag_ids': tax['analytic'] and line.analytic_tag_ids.ids or False,
'tax_ids': tax_ids and [(6, None, tax_ids)] or False,
'tax_repartition_line_id': tax.get('tax_repartition_line_id'), # For base amount, we let this field empty
}

# If the taxes generate moves on the same financial account as the invoice line,
@@ -1123,7 +1125,7 @@ def is_tax_affecting_base_amount(tax):
continue

price_unit = line.price_unit * (1 - (line.discount or 0.0) / 100.0)
taxes = line.invoice_line_tax_ids.compute_all(price_unit, self.currency_id, line.quantity, line.product_id, self.partner_id)['taxes']
taxes = line.invoice_line_tax_ids.compute_all(price_unit, self.currency_id, line.quantity, line.product_id, self.partner_id, is_refund=self.type in ('in_refund', 'out_refund'))['taxes']

affecting_base_tax_ids = []
for tax_vals in taxes:
@@ -1134,25 +1136,20 @@ def is_tax_affecting_base_amount(tax):
tax = tax_map[tax_vals['id']] = self.env['account.tax'].browse(tax_vals['id'])

val = self._prepare_tax_line_vals(line, tax_vals, affecting_base_tax_ids)
key = tax.get_grouping_key({
'tax_id': val['tax_id'],
'account_id': val['account_id'],
'account_analytic_id': val['account_analytic_id'],
'analytic_tag_ids': val['analytic_tag_ids'],
'tax_ids': affecting_base_tax_ids,
})
key = tax.get_grouping_key(val)

if key not in tax_grouped:
tax_grouped[key] = val
tax_grouped[key]['base'] = round_curr(val['base'])
else:
for field in default_tax_group_fields:
tax_grouped[key][field] += val.get(field) or 0
tax_grouped[key][field] += round_curr(val.get(field)) or 0

if tax.amount_type == "group":
affecting_base_tax_ids += tax.children_tax_ids.filtered(lambda t: is_tax_affecting_base_amount(t)).ids
elif is_tax_affecting_base_amount(tax):
affecting_base_tax_ids.append(tax.id)

return tax_grouped

@api.multi
@@ -1234,13 +1231,19 @@ def invoice_line_move_line_get(self):
continue
if line.quantity==0:
continue
tax_ids = []
for tax in line.invoice_line_tax_ids:
tax_ids.append((4, tax.id, None))
for child in tax.children_tax_ids:
tax_ids.append((4, child.id, None))

taxes_to_flatten = line.invoice_line_tax_ids
flattened_taxes = self.env['account.tax']
while taxes_to_flatten:
tax = taxes_to_flatten[0]
taxes_to_flatten -= tax
flattened_taxes += tax
taxes_to_flatten += tax.children_tax_ids

analytic_tag_ids = [(4, analytic_tag.id, None) for analytic_tag in line.analytic_tag_ids]

tax_repartition_field_name = 'invoice_repartition_line_ids' if line.invoice_type in ('in_invoice', 'out_invoice') else 'refund_repartition_line_ids'
tag_ids = flattened_taxes.mapped(tax_repartition_field_name).filtered(lambda x: x.repartition_type == 'base').mapped('tag_ids.id')
move_line_dict = {
'invl_id': line.id,
'type': 'src',
@@ -1253,13 +1256,13 @@ def invoice_line_move_line_get(self):
'uom_id': line.uom_id.id,
'account_analytic_id': line.account_analytic_id.id,
'analytic_tag_ids': analytic_tag_ids,
'tax_ids': tax_ids,
'tax_ids': [(6, 0, flattened_taxes.ids)],
'invoice_id': self.id,
'tag_ids': [(6, 0, tag_ids)],
}
res.append(move_line_dict)
return res

@api.multi
def tax_line_move_line_get(self):
self.ensure_one()

@@ -1280,7 +1283,9 @@ def tax_line_move_line_get(self):
'account_analytic_id': tax_line.account_analytic_id.id,
'analytic_tag_ids': analytic_tag_ids,
'invoice_id': self.id,
'tax_ids': [(6, 0, tax_line.tax_ids.ids)],
'tax_ids': tax_line.tax_ids and [(6, 0, tax_line.tax_ids.ids)] or False, # We don't pass an empty recordset here, as it would reset the tax_exibility of the line, due to the condition in account.move.line's create
'tax_repartition_line_id': tax_line.tax_repartition_line_id.id,
'tag_ids': [(6, 0, tax_line.tax_repartition_line_id.tag_ids.ids)],
})
return res

@@ -1543,21 +1548,6 @@ def _refund_cleanup_lines(self, lines):
result.append((0, 0, values))
return result

@api.model
def _refund_tax_lines_account_change(self, lines, taxes_to_change):
# Let's change the account on tax lines when
# @param {list} lines: a list of orm commands
# @param {dict} taxes_to_change
# key: tax ID, value: refund account

if not taxes_to_change:
return lines

for line in lines:
if isinstance(line[2], dict) and line[2]['tax_id'] in taxes_to_change:
line[2]['account_id'] = taxes_to_change[line[2]['tax_id']]
return lines

def _get_refund_common_fields(self):
return ['partner_id', 'payment_term_id', 'account_id', 'currency_id', 'journal_id']

@@ -1579,6 +1569,87 @@ def _get_refund_copy_fields(self):
def _get_currency_rate_date(self):
return self.date or self.date_invoice

@api.model
def _create_refund_repartition_mapping(self, taxes):
""" Creates a mapping between tax and refund repartition lines of the
provided taxes, using the sequence of repartition lines to match them.
This function is used in order to fix account.invoice.tax objects generated
for refunds when tax amounts have been modified manually.
For example, a tax with the following tax repartition...
- INVOICE:
1) 30%
2) 70%
- REFUND
3) 40%
4) 60%
... will group line 1) with line 3), and line 2) with lines 3) and 4).
:return: A dictionnary, with invoice repartition line ids as keys, and lists
of corresponding refund repartition line ids as values.
"""
rslt = {}
for tax in taxes:
inv_index = 0
ref_index = 0

tax_inv_lines = tax.invoice_repartition_line_ids.filtered(lambda x: x.repartition_type == 'tax')
tax_ref_lines = tax.refund_repartition_line_ids.filtered(lambda x: x.repartition_type == 'tax')

amount_to_match = tax_inv_lines[inv_index].factor_percent
while inv_index < len(tax_inv_lines) or ref_index < len(tax_ref_lines):
inv_rep_line = inv_index < len(tax_inv_lines) and tax_inv_lines[inv_index] or tax_inv_lines[-1]
ref_rep_line = ref_index < len(tax_ref_lines) and tax_ref_lines[ref_index] or tax_ref_lines[-1]

rslt_list = rslt.get(inv_rep_line.id, [])
if ref_rep_line.id not in rslt_list:
rslt_list.append(ref_rep_line.id)
rslt[inv_rep_line.id] = rslt_list

if amount_to_match > 0:
amount_to_match -= ref_rep_line.factor_percent
ref_index += 1
elif amount_to_match < 0:
amount_to_match += inv_rep_line.factor_percent
inv_index +=1
else:
inv_index += 1
if inv_index < len(tax_inv_lines):
amount_to_match = tax_inv_lines[inv_index].factor_percent

return rslt

def _group_tax_lines_by_repartition(self):
self.ensure_one()
rslt = {}
for tax_line in self.tax_line_ids:
rslt[tax_line.tax_repartition_line_id.id] = tax_line
return rslt

@api.model
def _fix_refund_tax_lines(self, invoice, refund):
""" Modifies the tax_line_ids of a draft refund invoice in order to make it
match the manual tax modifications that were made on its original invoice.
"""
invoice_tax_lines_map = invoice._group_tax_lines_by_repartition()
refund_tax_lines_map = refund._group_tax_lines_by_repartition()
refund_repartition_map = self._create_refund_repartition_mapping(invoice.mapped('invoice_line_ids.invoice_line_tax_ids'))
computed_tax_values = invoice.get_taxes_values()

for tax_data in computed_tax_values.values():
rep_line_id = tax_data['tax_repartition_line_id']

matching_invoice_tax = invoice_tax_lines_map.get(rep_line_id)

if matching_invoice_tax:
ref_rep_line_id = refund_repartition_map[rep_line_id][0]
refund_tax_line = refund_tax_lines_map.get(ref_rep_line_id)
manual_difference = matching_invoice_tax.amount - tax_data['amount']

if not invoice.currency_id.is_zero(manual_difference):
refund_tax_line.amount += manual_difference

@api.model
def _prepare_refund(self, invoice, date_invoice=None, date=None, description=None, journal_id=None):
""" Prepare the dict of values to create the new credit note from the invoice.
@@ -1602,14 +1673,6 @@ def _prepare_refund(self, invoice, date_invoice=None, date=None, description=Non

values['invoice_line_ids'] = self._refund_cleanup_lines(invoice.invoice_line_ids)

tax_lines = invoice.tax_line_ids
taxes_to_change = {
line.tax_id.id: line.tax_id.refund_account_id.id
for line in tax_lines.filtered(lambda l: l.tax_id.refund_account_id != l.tax_id.account_id)
}
cleaned_tax_lines = self._refund_cleanup_lines(tax_lines)
values['tax_line_ids'] = self._refund_tax_lines_account_change(cleaned_tax_lines, taxes_to_change)

if journal_id:
journal = self.env['account.journal'].browse(journal_id)
elif invoice['type'] == 'in_invoice':
@@ -1650,6 +1713,7 @@ def refund(self, date_invoice=None, date=None, description=None, journal_id=None
message = _("This customer invoice credit note has been created from: <a href=# data-oe-model=account.invoice data-oe-id=%d>%s</a><br>Reason: %s") % (invoice.id, invoice.number, description)
else:
message = _("This vendor bill credit note has been created from: <a href=# data-oe-model=account.invoice data-oe-id=%d>%s</a><br>Reason: %s") % (invoice.id, invoice.number, description)
self._fix_refund_tax_lines(invoice, refund_invoice)

refund_invoice.message_post(body=message)
new_invoices += refund_invoice
@@ -1769,7 +1833,7 @@ def _compute_price(self):
price = self.price_unit * (1 - (self.discount or 0.0) / 100.0)
taxes = False
if self.invoice_line_tax_ids:
taxes = self.invoice_line_tax_ids.compute_all(price, currency, self.quantity, product=self.product_id, partner=self.invoice_id.partner_id)
taxes = self.invoice_line_tax_ids.compute_all(price, currency, self.quantity, product=self.product_id, partner=self.invoice_id.partner_id, is_refund=self.invoice_id.type in ('in_refund', 'out_refund'))
self.price_subtotal = price_subtotal_signed = taxes['total_excluded'] if taxes else self.quantity * price
self.price_total = taxes['total_included'] if taxes else self.price_subtotal
if self.invoice_id.currency_id and self.invoice_id.currency_id != self.invoice_id.company_id.currency_id:
@@ -2064,26 +2128,12 @@ def _prepare_invoice_tax_val(self):
'account_id': self.account_id.id,
'account_analytic_id': self.account_analytic_id.id,
'analytic_tag_ids': self.analytic_tag_ids.ids or False,
'tax_ids': self.tax_ids and tax.tax_ids.ids,
}

@api.depends('invoice_id.invoice_line_ids')
def _compute_base_amount(self):
tax_grouped = {}
for invoice in self.mapped('invoice_id'):
tax_grouped[invoice.id] = invoice.get_taxes_values()
for tax in self:
tax.base = 0.0
if tax.tax_id:
key = tax.tax_id.get_grouping_key(tax._prepare_invoice_tax_val())
if tax.invoice_id and key in tax_grouped[tax.invoice_id.id]:
tax.base = tax_grouped[tax.invoice_id.id][key]['base']
else:
_logger.warning('Tax Base Amount not computable probably due to a change in an underlying tax (%s).', tax.tax_id.name)

invoice_id = fields.Many2one('account.invoice', string='Invoice', ondelete='cascade', index=True)
name = fields.Char(string='Tax Description', required=True)
tax_id = fields.Many2one('account.tax', string='Tax', ondelete='restrict')
tax_repartition_line_id = fields.Many2one(string="Originating Repartition Line", comodel_name='account.tax.repartition.line')
account_id = fields.Many2one('account.account', string='Tax Account', required=True, domain=[('deprecated', '=', False)])
account_analytic_id = fields.Many2one('account.analytic.account', string='Analytic account')
analytic_tag_ids = fields.Many2many('account.analytic.tag', string='Analytic Tags')
@@ -2094,7 +2144,7 @@ def _compute_base_amount(self):
sequence = fields.Integer(help="Gives the sequence order when displaying a list of invoice tax.")
company_id = fields.Many2one('res.company', string='Company', related='account_id.company_id', store=True, readonly=True)
currency_id = fields.Many2one('res.currency', related='invoice_id.currency_id', store=True, readonly=True)
base = fields.Monetary(string='Base', compute='_compute_base_amount', store=True)
base = fields.Monetary(string='Base')
tax_ids = fields.Many2many('account.tax', string='Affecting Base Taxes',
help='Taxes affecting the tax base amount applied before this one.')

0 comments on commit 3936d65

Please sign in to comment.
You can’t perform that action at this time.