Skip to content
Permalink
Browse files

[MERGE] forward port branch saas-12.3 up to 50e571a

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

# -------------------------------------------------------------------------
@@ -1971,6 +1990,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 = []

@@ -2033,6 +2053,7 @@ def action_invoice_print(self):
"""
if any(not move.is_invoice(include_receipts=True) for move in self):
raise UserError(_("Only invoices could be printed."))
self._check_tax_lock_date()

self.filtered(lambda inv: not inv.invoice_sent).write({'invoice_sent': True})
if self.user_has_groups('account.group_account_invoice'):
@@ -2715,7 +2736,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
@@ -2787,24 +2808,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"""
@@ -2817,7 +2820,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

# -------------------------------------------------------------------------
@@ -2976,7 +2982,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:
@@ -3010,6 +3015,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 2832703

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