Skip to content
Permalink
Browse files

[MERGE] forward port branch saas-12.3 up to 9bf0b04

  • Loading branch information...
KangOl committed Sep 9, 2019
2 parents 71cc792 + 9bf0b04 commit 15673076da70c6c3440a7f1377978e8ff3a4bb4c
Showing with 2,390 additions and 1,751 deletions.
  1. +38 −23 addons/account/models/account.py
  2. +30 −21 addons/account/models/account_move.py
  3. +2 −1 addons/account/models/account_payment.py
  4. +4 −2 addons/account/models/account_reconcile_model.py
  5. +12 −6 addons/account/models/reconciliation_widget.py
  6. +1 −0 addons/account/tests/__init__.py
  7. +5 −12 addons/account/tests/test_account_move_entry.py
  8. +98 −0 addons/account/tests/test_account_move_tax_lock_date.py
  9. +80 −16 addons/account/tests/test_reconciliation.py
  10. +77 −0 addons/account/tests/test_reconciliation_widget.py
  11. +255 −7 addons/account/tests/test_tax.py
  12. +1 −1 addons/account/views/report_invoice.xml
  13. +3 −0 addons/account_cancel/views/account_views.xml
  14. +5 −0 addons/account_check_printing/models/account_payment.py
  15. +1 −0 addons/account_check_printing/views/account_payment_views.xml
  16. +4 −0 addons/account_tax_python/models/account_tax.py
  17. +4 −13 addons/auth_oauth/controllers/main.py
  18. +1 −0 addons/base_address_city/models/res_partner.py
  19. +5 −1 addons/base_import/models/base_import.py
  20. +6 −0 addons/bus/static/src/js/crosstab_bus.js
  21. +4 −2 addons/calendar/models/calendar.py
  22. +58 −0 addons/calendar/tests/test_calendar.py
  23. +3 −2 addons/crm_iap_lead_website/models/crm_reveal_rule.py
  24. +1 −0 addons/delivery/models/sale_order.py
  25. +0 −1 addons/delivery/wizard/choose_delivery_carrier.py
  26. +3 −3 addons/gamification/models/challenge.py
  27. +1 −1 addons/gamification/models/goal.py
  28. +3 −3 addons/gamification/views/challenge.xml
  29. +5 −2 addons/gamification/views/goal.xml
  30. +9 −4 addons/hr_expense/models/hr_expense.py
  31. +64 −0 addons/hr_expense/tests/test_expenses.py
  32. +1 −1 addons/hr_expense/wizard/hr_expense_sheet_register_payment.py
  33. +13 −3 addons/hr_holidays/models/hr_leave.py
  34. +1 −0 addons/hr_holidays/tests/__init__.py
  35. +212 −0 addons/hr_holidays/tests/test_automatic_leave_dates.py
  36. +1 −0 addons/hr_recruitment/views/hr_recruitment_views.xml
  37. +5 −2 addons/im_livechat/controllers/main.py
  38. +8 −0 addons/im_livechat/static/src/js/im_livechat.js
  39. +20 −42 addons/l10n_ae/data/account_tax_template_data.xml
  40. +14 −0 addons/l10n_ch/models/account_invoice.py
  41. +1 −0 addons/l10n_ch/models/account_journal.py
  42. +0 −14 addons/l10n_es/data/account_tax_data.xml
  43. +6 −6 addons/l10n_it_edi/models/ir_mail_server.py
  44. +7 −0 addons/l10n_lu/__init__.py
  45. +1 −1 addons/l10n_lu/__manifest__.py
  46. +13 −0 addons/l10n_multilang/models/l10n_multilang.py
  47. +1 −1 addons/l10n_uk/__manifest__.py
  48. +5 −3 addons/lunch/static/src/js/lunch_kanban_controller.js
  49. +47 −10 addons/lunch/static/src/js/lunch_kanban_model.js
  50. +20 −0 addons/lunch/static/src/js/lunch_kanban_view.js
  51. +50 −0 addons/lunch/static/tests/lunch_kanban_tests.js
  52. +1 −1 addons/mail/controllers/main.py
  53. +24 −3 addons/mail/static/src/js/models/threads/document_thread.js
  54. +5 −1 addons/mail/static/src/js/models/threads/searchable_thread.js
  55. +51 −22 addons/mail/static/src/js/services/mail_document_thread_manager.js
  56. +5 −1 addons/mail/static/src/js/services/mail_window_manager.js
  57. +18 −26 addons/mail/static/src/js/thread_windows/thread_window.js
  58. +6 −1 addons/mail/static/src/js/utils.js
  59. +7 −0 addons/mail/static/src/scss/composer.scss
  60. +1 −0 addons/mail/static/src/scss/thread.scss
  61. +54 −13 addons/mail/static/tests/discuss_mobile_tests.js
  62. +13 −7 addons/mail/static/tests/document_thread_window_tests.js
  63. +82 −0 addons/mail/static/tests/systray/systray_messaging_menu_tests.js
  64. +4 −4 addons/maintenance/views/maintenance_views.xml
  65. +3 −0 addons/mrp/models/mrp_production.py
  66. +0 −1 addons/mrp/models/res_config_settings.py
  67. +6 −1 addons/mrp/models/stock_move.py
  68. +0 −11 addons/mrp/views/res_config_settings_views.xml
  69. +0 −25 addons/mrp_subcontracting/__init__.py
  70. +0 −19 addons/mrp_subcontracting/__manifest__.py
  71. +0 −12 addons/mrp_subcontracting/data/mrp_subcontracting_data.xml
  72. +0 −9 addons/mrp_subcontracting/models/__init__.py
  73. +0 −20 addons/mrp_subcontracting/models/mrp_bom.py
  74. +0 −47 addons/mrp_subcontracting/models/res_company.py
  75. +0 −56 addons/mrp_subcontracting/models/res_partner.py
  76. +0 −41 addons/mrp_subcontracting/models/stock_move.py
  77. +0 −133 addons/mrp_subcontracting/models/stock_picking.py
  78. +0 −139 addons/mrp_subcontracting/models/stock_warehouse.py
  79. +0 −4 addons/mrp_subcontracting/tests/__init__.py
  80. +0 −526 addons/mrp_subcontracting/tests/test_subcontracting.py
  81. +0 −14 addons/mrp_subcontracting/views/mrp_bom_views.xml
  82. +0 −23 addons/mrp_subcontracting/views/stock_picking_views.xml
  83. +0 −13 addons/mrp_subcontracting/views/stock_warehouse_views.xml
  84. +1 −1 addons/payment/views/payment_portal_templates.xml
  85. +3 −3 addons/payment_sips/models/payment.py
  86. +3 −3 addons/payment_sips/views/payment_views.xml
  87. +9 −0 addons/point_of_sale/models/account_tax.py
  88. +17 −4 addons/point_of_sale/static/src/css/customer_facing_display.css
  89. +17 −2 addons/point_of_sale/static/src/js/models.js
  90. +22 −14 addons/point_of_sale/static/src/scss/customer_facing_display.scss
  91. +3 −2 addons/product/models/product_pricelist.py
  92. +8 −1 addons/product/models/product_template.py
  93. +22 −0 addons/product/tests/test_variants.py
  94. +0 −2 addons/purchase/models/purchase.py
  95. +0 −4 addons/purchase_mrp_subcontracting/__init__.py
  96. +0 −18 addons/purchase_mrp_subcontracting/__manifest__.py
  97. +0 −5 addons/purchase_mrp_subcontracting/models/__init__.py
  98. +0 −16 addons/purchase_mrp_subcontracting/models/product.py
  99. +0 −16 addons/purchase_mrp_subcontracting/models/stock_picking.py
  100. +0 −7 addons/purchase_mrp_subcontracting/tests/__init__.py
  101. +0 −112 addons/purchase_mrp_subcontracting/tests/test_purchase_subcontracting.py
  102. +0 −25 addons/purchase_mrp_subcontracting/views/supplier_info_views.xml
  103. +4 −2 addons/sale_coupon/models/sale_order.py
  104. +2 −2 addons/sale_coupon/views/sale_coupon_program_views.xml
  105. +2 −2 addons/sale_purchase/models/sale_order.py
  106. +1 −1 addons/sale_stock/models/stock.py
  107. +1 −1 addons/stock/models/stock_move.py
  108. +1 −1 addons/stock/models/stock_picking.py
  109. +2 −2 addons/stock/models/stock_quant.py
  110. +4 −2 addons/stock/models/stock_warehouse.py
  111. +47 −0 addons/stock/tests/test_packing.py
  112. +2 −2 addons/stock_landed_costs/models/stock_landed_cost.py
  113. +1 −0 addons/web/models/ir_qweb.py
  114. +13 −0 addons/web/static/src/js/core/abstract_storage_service.js
  115. +4 −6 addons/web/static/src/js/core/local_storage.js
  116. +14 −0 addons/web/static/src/js/core/ram_storage.js
  117. +7 −5 addons/web/static/src/js/fields/relational_fields.js
  118. +5 −3 addons/web/static/src/js/views/basic/basic_model.js
  119. +3 −1 addons/web/static/src/js/views/form/form_controller.js
  120. +4 −0 addons/web/static/src/js/views/form/form_view.js
  121. +3 −0 addons/web/static/src/js/views/graph/graph_view.js
  122. +8 −0 addons/web/static/src/js/views/kanban/kanban_record.js
  123. +2 −0 addons/web/static/src/js/views/list/list_controller.js
  124. +11 −1 addons/web/static/src/js/widgets/auto_complete.js
  125. +4 −1 addons/web/static/src/js/widgets/date_picker.js
  126. +8 −0 addons/web/static/src/scss/ui.scss
  127. +34 −5 addons/web/static/tests/fields/basic_fields_tests.js
  128. +31 −8 addons/web/static/tests/fields/relational_fields_tests.js
  129. +16 −5 addons/web/static/tests/helpers/mock_server.js
  130. +1 −2 addons/web/static/tests/helpers/test_utils_create.js
  131. +73 −2 addons/web/static/tests/views/form_tests.js
  132. +21 −0 addons/web/static/tests/views/graph_tests.js
  133. +55 −0 addons/web/static/tests/views/kanban_tests.js
  134. +89 −0 addons/web/static/tests/views/list_tests.js
  135. +4 −2 addons/web/static/tests/views/view_dialogs_tests.js
  136. +6 −1 addons/web_editor/static/src/js/wysiwyg/plugin/text.js
  137. +1 −1 addons/web_editor/static/src/js/wysiwyg_snippets/snippets.options.js
  138. +13 −12 addons/website/models/ir_ui_view.py
  139. +2 −5 addons/website/models/website.py
  140. +2 −1 addons/website/static/src/js/content/menu.js
  141. +8 −2 addons/website/static/src/scss/website.scss
  142. +1 −1 addons/website/views/website_templates.xml
  143. +8 −3 addons/website_blog/controllers/main.py
  144. +13 −10 addons/website_blog/static/src/js/website_blog.js
  145. +5 −4 addons/website_blog/views/website_blog_templates.xml
  146. +4 −1 addons/website_event_sale/models/sale_order.py
  147. +1 −1 addons/website_event_track/models/event_track.py
  148. +1 −1 addons/website_sale/models/website.py
  149. +1 −1 addons/website_sale/views/templates.xml
  150. +1 −1 addons/website_sale_comparison/models/website_sale_comparison.py
  151. +22 −0 addons/website_sale_coupon/views/website_sale_templates.xml
  152. +1 −1 addons/website_sale_delivery/static/src/js/website_sale_delivery.js
  153. +17 −0 addons/website_sale_delivery/static/tests/tours/website_free_delivery.js
  154. +4 −0 addons/website_sale_delivery/tests/test_ui.py
  155. +9 −2 addons/website_sale_digital/controllers/main.py
  156. +115 −0 addons/website_sale_slides/controllers/i18n/so.po
  157. +2 −2 addons/website_sale_stock/models/product_template.py
  158. +15 −14 addons/website_slides/static/src/js/slides_course_fullscreen_player.js
  159. +15 −0 doc/cla/corporate/arxilead.md
  160. +5 −2 doc/cla/corporate/tvtmarine-automation.md
  161. +11 −0 doc/cla/individual/hari4274.md
  162. +6 −0 doc/reference/cmdline.rst
  163. +2 −2 doc/reference/javascript_reference.rst
  164. +6 −0 doc/reference/orm.rst
  165. +1 −1 odoo/addons/base/data/ir_module_module.xml
  166. +1 −1 odoo/addons/base/models/ir_actions_report.py
  167. +1 −1 odoo/addons/base/models/ir_model.py
  168. +1 −6 odoo/addons/base/models/res_bank.py
  169. +6 −2 odoo/addons/base/models/res_partner.py
  170. +8 −0 odoo/addons/base/tests/test_base.py
  171. +3 −3 odoo/addons/base/views/ir_qweb_widget_templates.xml
  172. +1 −1 odoo/tools/mail.py
@@ -954,7 +954,7 @@ def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_ui
@api.depends('company_id')
def _belong_to_company(self):
for journal in self:
journal.belong_to_company = (journal.company_id.id == self.env.company.id)
journal.belongs_to_company = (journal.company_id.id == self.env.company.id)

@api.multi
def _search_company_journals(self, operator, value):
@@ -1361,20 +1361,27 @@ def recompute_base(base_amount, fixed_amount, percent_amount, division_amount):
cached_tax_amounts = {}
if handle_price_include:
for tax in reversed(taxes):
tax_repartition_lines = (
is_refund
and tax.refund_repartition_line_ids
or tax.invoice_repartition_line_ids
).filtered(lambda x: x.repartition_type == "tax")
sum_repartition_factor = sum(tax_repartition_lines.mapped("factor"))

if tax.include_base_amount:
base = recompute_base(base, incl_fixed_amount, incl_percent_amount, incl_division_amount)
incl_fixed_amount = incl_percent_amount = incl_division_amount = 0
store_included_tax_total = True
if tax.price_include or self._context.get('force_price_include'):
if tax.amount_type == 'percent':
incl_percent_amount += tax.amount
incl_percent_amount += tax.amount * sum_repartition_factor
elif tax.amount_type == 'division':
incl_division_amount += tax.amount
incl_division_amount += tax.amount * sum_repartition_factor
elif tax.amount_type == 'fixed':
incl_fixed_amount += quantity * tax.amount
incl_fixed_amount += quantity * tax.amount * sum_repartition_factor
else:
# tax.amount_type == other (python)
tax_amount = tax._compute_amount(base, price_unit, quantity, product, partner)
tax_amount = tax._compute_amount(base, price_unit, quantity, product, partner) * sum_repartition_factor
incl_fixed_amount += tax_amount
# Avoid unecessary re-computation
cached_tax_amounts[i] = tax_amount
@@ -1393,6 +1400,9 @@ def recompute_base(base_amount, fixed_amount, percent_amount, division_amount):
i = 0
cumulated_tax_included_amount = 0
for tax in taxes:
tax_repartition_lines = (is_refund and tax.refund_repartition_line_ids or tax.invoice_repartition_line_ids).filtered(lambda x: x.repartition_type == 'tax')
sum_repartition_factor = sum(tax_repartition_lines.mapped('factor'))

#compute the tax_amount
if (self._context.get('force_price_include') or tax.price_include) and total_included_checkpoints.get(i):
# We know the total to reach for that tax, so we make a substraction to avoid any rounding issues
@@ -1402,11 +1412,12 @@ def recompute_base(base_amount, fixed_amount, percent_amount, division_amount):
tax_amount = tax.with_context(force_price_include=False)._compute_amount(
base, sign * price_unit, quantity, product, partner)

# Round the tax_amount
# Round the tax_amount multiplied by the computed repartition lines factor.
tax_amount = round(tax_amount, prec)
factorized_tax_amount = round(tax_amount * sum_repartition_factor, prec)

if tax.price_include and not total_included_checkpoints.get(i):
cumulated_tax_included_amount += tax_amount
cumulated_tax_included_amount += factorized_tax_amount

# If the tax affects the base of subsequent taxes, its tax move lines must
# receive the base tags and tag_ids of these taxes, so that the tax report computes
@@ -1417,18 +1428,24 @@ def recompute_base(base_amount, fixed_amount, percent_amount, division_amount):
subsequent_taxes = taxes[i+1:]
subsequent_tags = subsequent_taxes.get_tax_tags(is_refund, 'base')

# Compute the tax lines
tax_repartition_lines = (is_refund and tax.refund_repartition_line_ids or tax.invoice_repartition_line_ids).filtered(lambda x: x.repartition_type == 'tax')
sum_factor = sum(tax_repartition_lines.mapped('factor'))
repartition_lines_to_treat = len(tax_repartition_lines)
total_amount = 0
for repartition_line in tax_repartition_lines:
if repartition_lines_to_treat != 1 or sum_factor != 1.0:
line_amount = round(tax_amount * repartition_line.factor, prec)
else:
# When the sum of the repartition lines factor is 100%, we need to ensure the whole tax amount has
# been spread into the repartition lines.
line_amount = round(tax_amount - total_amount, prec)
# Compute the tax line amounts by multiplying each factor with the tax amount.
# Then, spread the tax rounding to ensure the consistency of each line independently with the factorized
# amount. E.g:
#
# Suppose a tax having 4 x 50% repartition line applied on a tax amount of 0.03 with 2 decimal places.
# The factorized_tax_amount will be 0.06 (200% x 0.03). However, each line taken independently will compute
# 50% * 0.03 = 0.01 with rounding. It means there is 0.06 - 0.04 = 0.02 as total_rounding_error to dispatch
# in lines as 2 x 0.01.
repartition_line_amounts = [round(tax_amount * line.factor, prec) for line in tax_repartition_lines]
total_rounding_error = round(factorized_tax_amount - sum(repartition_line_amounts), prec)
nber_rounding_steps = int(abs(total_rounding_error / currency.rounding))
rounding_error = round(nber_rounding_steps and total_rounding_error / nber_rounding_steps or 0.0, prec)

for repartition_line, line_amount in zip(tax_repartition_lines, repartition_line_amounts):

if nber_rounding_steps:
line_amount += rounding_error
nber_rounding_steps -= 1

taxes_vals.append({
'id': tax.id,
@@ -1445,16 +1462,14 @@ def recompute_base(base_amount, fixed_amount, percent_amount, division_amount):
'tax_ids': subsequent_taxes.ids,
})

total_amount += line_amount
if not repartition_line.account_id:
total_void += line_amount
repartition_lines_to_treat -= 1

# Affect subsequent taxes
if tax.include_base_amount:
base += tax_amount
base += factorized_tax_amount

total_included += tax_amount
total_included += factorized_tax_amount
i += 1

return {
@@ -1334,6 +1334,24 @@ def _check_fiscalyear_lock_date(self):
raise UserError(message)
return True

def _check_tax_lock_date(self):
for move in self:
if (
move.company_id.tax_lock_date
and move.date <= move.company_id.tax_lock_date
and any(
line.tax_ids
or line.tax_line_id
or line.tag_ids.filtered(lambda x: x.applicability == "taxes")
for line in move.line_ids
)
):
raise UserError(
_(
"The operation is refused as it would impact an already issued tax statement. Please change the journal entry date or the tax lock date set in the settings ({}) to proceed"
).format(move.company_id.tax_lock_date or date.min)
)

@api.multi
def _check_move_consistency(self):
for move in self:
@@ -1342,6 +1360,7 @@ def _check_move_consistency(self):
raise UserError(_("Cannot create moves for different companies."))

self._check_balanced()
self._check_tax_lock_date()
self._check_fiscalyear_lock_date()

# -------------------------------------------------------------------------
@@ -1964,6 +1983,7 @@ def button_draft(self):

@api.multi
def button_cancel(self):
self._check_tax_lock_date()
AccountMoveLine = self.env['account.move.line']
excluded_move_ids = []

@@ -2708,7 +2728,7 @@ def _amount_residual(self):
else:
date = partial_line.credit_move_id.date if partial_line.debit_move_id == line else partial_line.debit_move_id.date
rate = line.currency_id.with_context(date=date).rate
amount_residual_currency += sign_partial_line * partial_line.amount * rate
amount_residual_currency += sign_partial_line * line.currency_id.round(partial_line.amount * rate)

#computing the `reconciled` field.
reconciled = False
@@ -2780,24 +2800,6 @@ def _check_constrains_account_id(self):
if control_type_failed or control_account_failed:
raise UserError(_('You cannot use this general account in this journal, check the tab \'Entry Controls\' on the related journal.'))

@api.constrains('tax_ids', 'tax_line_id')
def _check_tax_lock_date1(self):
for line in self:
if line.date <= (line.company_id.tax_lock_date or date.min):
raise ValidationError(
_("The operation is refused as it would impact an already issued tax statement. " +
"Please change the journal entry date or the tax lock date set in the settings ({}) to proceed").format(
line.company_id.tax_lock_date or date.min))

@api.constrains('credit', 'debit', 'date')
def _check_tax_lock_date2(self):
for line in self:
if (line.tax_ids or line.tax_line_id) and line.date <= (line.company_id.tax_lock_date or date.min):
raise ValidationError(
_("The operation is refused as it would impact an already issued tax statement. " +
"Please change the journal entry date or the tax lock date set in the settings ({}) to proceed").format(
line.company_id.tax_lock_date or date.min))

@api.multi
def _update_check(self):
""" Raise Warning to cause rollback if the move is posted, some entries are reconciled or the move is older than the lock date"""
@@ -2810,7 +2812,10 @@ def _update_check(self):
raise UserError(_('You cannot do this modification on a reconciled entry. You can just change some non legal fields or you must unreconcile first.\n%s.') % err_msg)
if line.move_id.id not in move_ids:
move_ids.add(line.move_id.id)
self.env['account.move'].browse(list(move_ids))._check_fiscalyear_lock_date()
if move_ids:
moves = self.env['account.move'].browse(list(move_ids))
moves._check_fiscalyear_lock_date()
moves._check_tax_lock_date()
return True

# -------------------------------------------------------------------------
@@ -2969,7 +2974,6 @@ def write(self, vals):
@api.multi
def unlink(self):
self._update_check()
self._check_tax_lock_date2()
move_ids = set()
for line in self:
if line.move_id.id not in move_ids:
@@ -3003,6 +3007,11 @@ def default_get(self, default_fields):

# Suggest default value for debit / credit to balance the journal entry.
balance = sum(line['debit'] - line['credit'] for line in move.line_ids)
# if we are here, line_ids is in context, so journal_id should also be.
journal = self.env['account.journal'].browse(self._context.get('default_journal_id') or self._context['journal_id'])
currency = journal.exists() and journal.company_id.currency_id
if currency:
balance = currency.round(balance)
if balance < 0.0:
values.update({'debit': -balance})
if balance > 0.0:
@@ -452,7 +452,8 @@ def cancel(self):
for move in rec.move_line_ids.mapped('move_id'):
if rec.reconciled_invoice_ids:
move.line_ids.remove_move_reconcile()
move.button_cancel()
if move.state != 'draft':
move.button_cancel()
move.unlink()
rec.write({
'state': 'cancelled',
@@ -361,7 +361,7 @@ def _apply_conditions(self, query, params):
query += ' AND st_line.name NOT ILIKE %s'
params += ['%%%s%%' % rule.match_label_param]
elif rule.match_label == 'match_regex':
query += ' AND st_line.name ~ %s'
query += ' AND st_line.name ~* %s'
params += [rule.match_label_param]

# Filter on partners.
@@ -621,8 +621,10 @@ def _check_rule_propositions(self, statement_line, candidates):

if line_residual > total_residual:
amount_percentage = (total_residual / line_residual) * 100
else:
elif total_residual:
amount_percentage = (line_residual / total_residual) * 100 if total_residual else 0
else:
return False
return amount_percentage >= self.match_total_amount_param

@api.multi
@@ -116,7 +116,8 @@ def _get_bank_statement_line_partners(self, st_lines):
query += 'LEFT JOIN res_partner_bank bank ON bank.id = st_line.bank_account_id OR bank.acc_number = st_line.account_number %s\n' % (where_bank)
query += 'LEFT JOIN res_partner p1 ON st_line.partner_id=p1.id \n'
query += 'LEFT JOIN res_partner p2 ON bank.partner_id=p2.id \n'
query += 'LEFT JOIN res_partner p3 ON p3.name ILIKE st_line.partner_name %s\n' % (where_partner)
# By definition the commercial partner_id doesn't have a parent_id set
query += 'LEFT JOIN res_partner p3 ON p3.name ILIKE st_line.partner_name %s AND p3.parent_id is NULL \n' % (where_partner)
query += 'WHERE st_line.id IN %s'

params += [tuple(st_lines.ids)]
@@ -520,17 +521,22 @@ def _domain_move_lines_for_reconciliation(self, st_line, aml_accounts, partner_i
])

domain = expression.OR([domain_reconciliation, domain_matching])
partner_domain = []
if partner_id:
domain = expression.AND([domain, [('partner_id', '=', partner_id)]])
partner_domain = [('partner_id', '=', partner_id)]
domain = expression.AND([domain, partner_domain])

# Domain factorized for all reconciliation use cases
if search_str:
str_domain = self._domain_move_lines(search_str=search_str)
if not partner_id:
str_domain = expression.OR([
str_domain,
[('partner_id.name', 'ilike', search_str)]
])
partner_domain = [('partner_id.name', 'ilike', search_str)]

str_domain = expression.OR([
str_domain,
partner_domain,
])

domain = expression.AND([
domain,
str_domain
@@ -19,3 +19,4 @@
from . import test_account_fiscal_year
from . import test_account_all_l10n
from . import test_reconciliation_matching_rules
from . import test_account_move_tax_lock_date
@@ -69,41 +69,34 @@ def test_misc_tax_lock_date_1(self):
# lines[3] = 'revenue line 2'
lines = self.test_move.line_ids.sorted('debit')

# Writing not affecting a tax is allowed.
self.test_move.write({
'line_ids': [
(1, lines[0].id, {'credit': 1750.0}), # counterpart line
(1, lines[2].id, {'debit': 600.0}), # revenue line 1
],
})

self.cr.execute('SAVEPOINT test_misc_tax_lock_date_1')

# Writing something affecting a tax is not allowed.
with self.assertRaises(ValidationError):
with self.assertRaises(UserError):
self.test_move.write({
'line_ids': [
(1, lines[0].id, {'credit': 2750.0}),
(1, lines[3].id, {'debit': 2000.0}),
(1, lines[3].id, {'debit': 2100.0}),
],
})

with self.assertRaises(ValidationError):
with self.assertRaises(UserError):
self.test_move.write({
'line_ids': [
(1, lines[3].id, {'tax_ids': [(6, 0, self.company_data['default_tax_purchase'].ids)]}),
],
})

with self.assertRaises(ValidationError):
with self.assertRaises(UserError):
self.test_move.write({
'line_ids': [
(1, lines[0].id, {'credit': 1900.0}),
(1, lines[1].id, {'debit': 300.0}),
],
})

with self.assertRaises(ValidationError):
with self.assertRaises(UserError):
self.test_move.unlink()

self.cr.execute('ROLLBACK TO SAVEPOINT test_misc_tax_lock_date_1')

0 comments on commit 1567307

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