diff --git a/account_reconcile_model_oca/README.rst b/account_reconcile_model_oca/README.rst index df9483c6..f6976d47 100644 --- a/account_reconcile_model_oca/README.rst +++ b/account_reconcile_model_oca/README.rst @@ -17,13 +17,13 @@ Account Reconcile Model Oca :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html :alt: License: LGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Faccount--reconcile-lightgray.png?logo=github - :target: https://github.com/OCA/account-reconcile/tree/17.0/account_reconcile_model_oca + :target: https://github.com/OCA/account-reconcile/tree/18.0/account_reconcile_model_oca :alt: OCA/account-reconcile .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/account-reconcile-17-0/account-reconcile-17-0-account_reconcile_model_oca + :target: https://translation.odoo-community.org/projects/account-reconcile-18-0/account-reconcile-18-0-account_reconcile_model_oca :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/account-reconcile&target_branch=17.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/account-reconcile&target_branch=18.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| @@ -42,7 +42,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -62,6 +62,16 @@ Contributors - Enric Tobella +- Trobz + + - Do Anh Duy + +Other credits +------------- + +The migration of this module from 17.0 to 18.0 was financially supported +by Camptocamp. + Maintainers ----------- @@ -75,6 +85,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -This module is part of the `OCA/account-reconcile `_ project on GitHub. +This module is part of the `OCA/account-reconcile `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/account_reconcile_model_oca/__manifest__.py b/account_reconcile_model_oca/__manifest__.py index 1a3478de..7e5f4ac9 100644 --- a/account_reconcile_model_oca/__manifest__.py +++ b/account_reconcile_model_oca/__manifest__.py @@ -5,7 +5,7 @@ "name": "Account Reconcile Model Oca", "summary": """ This includes the logic moved from Odoo Community to Odoo Enterprise""", - "version": "17.0.1.0.1", + "version": "18.0.1.0.0", "license": "LGPL-3", "author": "Dixmit,Odoo,Odoo Community Association (OCA)", "website": "https://github.com/OCA/account-reconcile", diff --git a/account_reconcile_model_oca/models/account_bank_statement_line.py b/account_reconcile_model_oca/models/account_bank_statement_line.py index 652a3aa6..b807e3f6 100644 --- a/account_reconcile_model_oca/models/account_bank_statement_line.py +++ b/account_reconcile_model_oca/models/account_bank_statement_line.py @@ -2,14 +2,13 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from odoo import models -from odoo.osv.expression import get_unaccent_wrapper -from odoo.tools import html2plaintext +from odoo.tools import SQL, html2plaintext from odoo.addons.base.models.res_bank import sanitize_account_number class AccountBankStatementLine(models.Model): - _inherit = ("account.bank.statement.line",) + _inherit = "account.bank.statement.line" def _retrieve_partner(self): self.ensure_one() @@ -55,7 +54,7 @@ class AccountBankStatementLine(models.Model): # Retrieve the partner from statement line text values. st_line_text_values = self._get_st_line_strings_for_matching() - unaccent = get_unaccent_wrapper(self._cr) + unaccent = self.env.registry.unaccent sub_queries = [] params = [] for text_value in st_line_text_values: @@ -66,35 +65,45 @@ class AccountBankStatementLine(models.Model): # Take care a partner could contain some special characters in its name that # needs to be escaped. sub_queries.append( - rf""" - {unaccent("%s")} ~* ('^' || ( - SELECT STRING_AGG(CONCAT('(?=.*\m', chunk[1], '\M)'), '') - FROM regexp_matches({unaccent('partner.name')}, '\w{{3,}}', 'g') - AS chunk - )) - """ + SQL( + rf""" + {unaccent("%s")} ~* ('^' || ( + SELECT STRING_AGG(CONCAT('(?=.*\m', chunk[1], '\M)'), '') + FROM regexp_matches({unaccent('partner.name')}, '\w{{3,}}', 'g') + AS chunk + )) + """, + text_value, + ) ) params.append(text_value) if sub_queries: self.env["res.partner"].flush_model(["company_id", "name"]) self.env["account.move.line"].flush_model(["partner_id", "company_id"]) - self._cr.execute( + query = SQL(""" + SELECT aml.partner_id + FROM account_move_line aml + JOIN res_partner partner ON + aml.partner_id = partner.id + AND partner.name IS NOT NULL + AND partner.active + AND ( + """) + query_parts = SQL(") OR (").join(sub_queries) + final_query = SQL( """ - SELECT aml.partner_id - FROM account_move_line aml - JOIN res_partner partner ON - aml.partner_id = partner.id - AND partner.name IS NOT NULL - AND partner.active - AND ((""" - + ") OR (".join(sub_queries) - + """)) - WHERE aml.company_id = %s - LIMIT 1 - """, - params + [self.company_id.id], + %s + %s + ) + WHERE aml.company_id = %s + LIMIT 1 + """, + query, + query_parts, + self.company_id.id, ) + self._cr.execute(final_query) row = self._cr.fetchone() if row: return self.env["res.partner"].browse(row[0]) diff --git a/account_reconcile_model_oca/models/account_reconcile_model.py b/account_reconcile_model_oca/models/account_reconcile_model.py index a3ec70e5..1fe0f392 100644 --- a/account_reconcile_model_oca/models/account_reconcile_model.py +++ b/account_reconcile_model_oca/models/account_reconcile_model.py @@ -362,16 +362,21 @@ class AccountReconcileModel(models.Model): aml_domain = self._get_invoice_matching_amls_domain(st_line, partner) query = self.env["account.move.line"]._where_calc(aml_domain) - tables, where_clause, where_params = query.get_sql() + from_string, from_params = query.from_clause + where_string, where_params = query.where_clause + from_clause = from_string + where_clause = where_string + query_params = from_params + where_params tokens = self._get_invoice_matching_st_line_tokens(st_line) if tokens: - sub_queries = [] - for table_alias, field in ( + search_fields = [ ("account_move_line", "name"), ("account_move_line__move_id", "name"), ("account_move_line__move_id", "ref"), - ): + ] + sub_queries = [] + for table_alias, field in search_fields: sub_queries.append( rf""" SELECT @@ -389,7 +394,7 @@ class AccountReconcileModel(models.Model): '\s+' ) ) AS token - FROM {tables} + FROM {from_clause} JOIN account_move account_move_line__move_id ON account_move_line__move_id.id = account_move_line.move_id WHERE {where_clause} AND {table_alias}.{field} IS NOT NULL @@ -411,7 +416,7 @@ class AccountReconcileModel(models.Model): + order_by + """ """, - (where_params * 3) + [tuple(tokens)], + (query_params * 3) + [tuple(tokens)], ) candidate_ids = [r[0] for r in self._cr.fetchall()] if candidate_ids: diff --git a/account_reconcile_model_oca/readme/CONTRIBUTORS.md b/account_reconcile_model_oca/readme/CONTRIBUTORS.md index becca427..8baa4dbe 100644 --- a/account_reconcile_model_oca/readme/CONTRIBUTORS.md +++ b/account_reconcile_model_oca/readme/CONTRIBUTORS.md @@ -1,3 +1,6 @@ - Dixmit - Enric Tobella + +- Trobz \<\> + - Do Anh Duy \<\> diff --git a/account_reconcile_model_oca/readme/CREDITS.md b/account_reconcile_model_oca/readme/CREDITS.md new file mode 100644 index 00000000..83b3ec91 --- /dev/null +++ b/account_reconcile_model_oca/readme/CREDITS.md @@ -0,0 +1 @@ +The migration of this module from 17.0 to 18.0 was financially supported by Camptocamp. diff --git a/account_reconcile_model_oca/static/description/index.html b/account_reconcile_model_oca/static/description/index.html index 846d951a..6c40c302 100644 --- a/account_reconcile_model_oca/static/description/index.html +++ b/account_reconcile_model_oca/static/description/index.html @@ -8,10 +8,11 @@ /* :Author: David Goodger (goodger@python.org) -:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $ +:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $ :Copyright: This stylesheet has been placed in the public domain. Default cascading style sheet for the HTML output of Docutils. +Despite the name, some widely supported CSS2 features are used. See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to customize this style sheet. @@ -274,7 +275,7 @@ pre.literal-block, pre.doctest-block, pre.math, pre.code { margin-left: 2em ; margin-right: 2em } -pre.code .ln { color: grey; } /* line numbers */ +pre.code .ln { color: gray; } /* line numbers */ pre.code, code { background-color: #eeeeee } pre.code .comment, code .comment { color: #5C6576 } pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold } @@ -300,7 +301,7 @@ span.option { span.pre { white-space: pre } -span.problematic { +span.problematic, pre.problematic { color: red } span.section-subtitle { @@ -368,7 +369,7 @@ ul.auto-toc { !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! source digest: sha256:cead010f67ccc5d4b9700540c9d8d0b4fb20d497a38d36cea80cf6f78563a756 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: LGPL-3 OCA/account-reconcile Translate me on Weblate Try me on Runboat

+

Beta License: LGPL-3 OCA/account-reconcile Translate me on Weblate Try me on Runboat

This module restores account reconciliation models functions moved from Odoo community to enterpise in V. 17.0

Table of contents

@@ -378,7 +379,8 @@ Odoo community to enterpise in V. 17.0

  • Credits
  • @@ -388,7 +390,7 @@ Odoo community to enterpise in V. 17.0

    Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -feedback.

    +feedback.

    Do not contact contributors directly about support or help with technical issues.

    @@ -407,16 +409,27 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
  • Enric Tobella
  • +
  • Trobz <https://www.trobz.com/> +
  • +
    +

    Other credits

    +

    The migration of this module from 17.0 to 18.0 was financially supported +by Camptocamp.

    +
    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    -Odoo Community Association + +Odoo Community Association +

    OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.

    -

    This module is part of the OCA/account-reconcile project on GitHub.

    +

    This module is part of the OCA/account-reconcile project on GitHub.

    You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

    diff --git a/account_reconcile_model_oca/tests/common.py b/account_reconcile_model_oca/tests/common.py index 14e968a9..58d8c2ae 100644 --- a/account_reconcile_model_oca/tests/common.py +++ b/account_reconcile_model_oca/tests/common.py @@ -13,8 +13,8 @@ class TestAccountReconciliationCommon(AccountTestInvoicingCommon): """ @classmethod - def setUpClass(cls, chart_template_ref=None): - super().setUpClass(chart_template_ref=chart_template_ref) + def setUpClass(cls): + super().setUpClass() cls.company = cls.company_data["company"] cls.company.currency_id = cls.env.ref("base.EUR") @@ -69,7 +69,7 @@ class TestAccountReconciliationCommon(AccountTestInvoicingCommon): "code": "TWAIT", "account_type": "liability_current", "reconcile": True, - "company_id": cls.company.id, + "company_ids": cls.company.ids, } ) # cash basis final account @@ -78,7 +78,7 @@ class TestAccountReconciliationCommon(AccountTestInvoicingCommon): "name": "TAX_TO_DEDUCT", "code": "TDEDUCT", "account_type": "asset_current", - "company_id": cls.company.id, + "company_ids": cls.company.ids, } ) cls.tax_base_amount_account = cls.env["account.account"].create( @@ -86,7 +86,7 @@ class TestAccountReconciliationCommon(AccountTestInvoicingCommon): "name": "TAX_BASE", "code": "TBASE", "account_type": "asset_current", - "company_id": cls.company.id, + "company_ids": cls.company.ids, } ) cls.company.account_cash_basis_base_account_id = cls.tax_base_amount_account.id @@ -190,7 +190,7 @@ class TestAccountReconciliationCommon(AccountTestInvoicingCommon): 0, 0, { - "name": "product that cost %s" % invoice_amount, + "name": f"product that cost {invoice_amount}", "quantity": 1, "price_unit": invoice_amount, "tax_ids": [Command.set([])], diff --git a/account_reconcile_model_oca/tests/test_reconciliation_match.py b/account_reconcile_model_oca/tests/test_reconciliation_match.py index 9c99f101..595175c7 100644 --- a/account_reconcile_model_oca/tests/test_reconciliation_match.py +++ b/account_reconcile_model_oca/tests/test_reconciliation_match.py @@ -1,8 +1,7 @@ from freezegun import freeze_time from odoo import Command -from odoo.tests import tagged -from odoo.tests.common import Form +from odoo.tests import Form, tagged from odoo.addons.account.tests.common import AccountTestInvoicingCommon @@ -10,21 +9,14 @@ from odoo.addons.account.tests.common import AccountTestInvoicingCommon @tagged("post_install", "-at_install") class TestReconciliationMatchingRules(AccountTestInvoicingCommon): @classmethod - def setUpClass(cls, chart_template_ref=None): - super().setUpClass(chart_template_ref=chart_template_ref) + def setUpClass(cls): + super().setUpClass() ################# # Company setup # ################# - cls.currency_data_2 = cls.setup_multi_currency_data( - { - "name": "Dark Chocolate Coin", - "symbol": "🍫", - "currency_unit_label": "Dark Choco", - "currency_subunit_label": "Dark Cacao Powder", - }, - rate2016=10.0, - rate2017=20.0, + cls.other_currency = cls.setup_other_currency( + "EUR", rates=[("2016-01-01", 10.0), ("2017-01-01", 20.0)] ) cls.company = cls.company_data["company"] @@ -33,7 +25,7 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon): cls.current_assets_account = cls.env["account.account"].search( [ ("account_type", "=", "asset_current"), - ("company_id", "=", cls.company.id), + ("company_ids", "in", cls.company.id), ], limit=1, ) @@ -188,6 +180,9 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon): }, ] ) + cls.payment_credit_account_id = ( + cls.outbound_payment_method_line.payment_account_id + ) @classmethod def _create_invoice_line( @@ -212,8 +207,6 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon): invoice_form.partner_id = partner if currency: invoice_form.currency_id = currency - if pay_reference: - invoice_form.payment_reference = pay_reference if ref: invoice_form.ref = ref if name: @@ -224,6 +217,8 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon): invoice_line_form.price_unit = amount invoice_line_form.tax_ids.clear() invoice = invoice_form.save() + if pay_reference: + invoice.payment_reference = pay_reference invoice.action_post() lines = invoice.line_ids return lines.filtered( @@ -1031,7 +1026,7 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon): def test_reverted_move_matching(self): partner = self.partner_1 AccountMove = self.env["account.move"] - account = self.bank_journal.company_id.account_journal_payment_credit_account_id + account = self.payment_credit_account_id move = AccountMove.create( { "journal_id": self.bank_journal.id, @@ -1061,8 +1056,7 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon): ) payment_bnk_line = move.line_ids.filtered( - lambda line: line.account_id - == self.bank_journal.company_id.account_journal_payment_credit_account_id + lambda line: line.account_id == self.payment_credit_account_id ) move.action_post() @@ -1262,7 +1256,7 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon): "name": "test_match_multi_currencies", "code": "xxxx", "type": "bank", - "currency_id": self.currency_data["currency"].id, + "currency_id": self.company_data["currency"].id, } ) @@ -1287,7 +1281,7 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon): "date": "2016-01-01", "payment_ref": "line", "partner_id": partner.id, - "foreign_currency_id": self.currency_data_2["currency"].id, + "foreign_currency_id": self.other_currency.id, "amount": 300.0, # Rate is 3 GOL = 1 USD in 2016. # Rate is 10 DAR = 1 USD in 2016 but the rate used by the bank is 9:1. "amount_currency": 900.0, @@ -1310,7 +1304,7 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon): "default_account_receivable" ].id, "partner_id": partner.id, - "currency_id": self.currency_data["currency"].id, + "currency_id": self.other_currency.id, "debit": 100.0, "credit": 0.0, "amount_currency": 200.0, @@ -1325,7 +1319,7 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon): "default_account_receivable" ].id, "partner_id": partner.id, - "currency_id": self.currency_data_2["currency"].id, + "currency_id": self.other_currency.id, "debit": 14.0, "credit": 0.0, "amount_currency": 280.0, @@ -1364,7 +1358,7 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon): @freeze_time("2020-01-01") def test_matching_with_write_off_foreign_currency(self): journal_foreign_curr = self.company_data["default_journal_bank"].copy() - journal_foreign_curr.currency_id = self.currency_data["currency"] + journal_foreign_curr.currency_id = self.company_data["currency"] reco_model = self._create_reconcile_model( auto_reconcile=True, @@ -1400,7 +1394,7 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon): "payment_type": "inbound", "partner_type": "customer", "partner_id": partner.id, - "ref": memo, + "memo": memo, "destination_account_id": self.company_data[ "default_account_receivable" ].id, @@ -1408,7 +1402,7 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon): ) payment.action_post() - return payment.line_ids.filtered( + return payment.move_id.line_ids.filtered( lambda x: x.account_id.account_type not in {"asset_receivable", "liability_payable"} )