diff --git a/README.md b/README.md index e15978d..2d16a9a 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,11 @@ Solves Odoo's restrictive `Access to unauthorized or invalid companies` error/wa - **Environment & Session Sanitization**: Overrides `ir.http._pre_dispatch` and `_dispatch` to safely query the cashier's authorized companies using `sudo()`, and dynamically filters out unauthorized or parent company IDs (such as parent company `2`) from `allowed_company_ids` in request parameters (`request.params`), HTTP sessions (`request.session.context`), and environment context (`request.env.context`). - **Sudo Order Post-Processing**: Inherits `pos.order` to run post-processing (`_process_saved_order`, including picking generation, cost/method computation, and payment posting) under `sudo()`. This allows Odoo to safely read company-dependent properties (like `cost_method` or `property_cost_method`) and generate inventory pickings without triggering security warnings in `environments.py`. +### 5. Centralized Cash Bank Reconciliation Patch +Enables matching of cash journal entries (e.g. from the centralized cash journal) in Odoo's standard bank reconciliation widget: +- **Reconciliation Candidate Expansion**: Patches the standard `account.move.line` search method (`_search_account_id`) to automatically include `asset_cash` accounts when filtering candidate line searches. This allows users to reconcile bank statement lines in the parent company directly against mirror/clearing cash entries. + + ## Configuration ### 1. POS Inter-Company Clearing diff --git a/models/account_move.py b/models/account_move.py index f019ced..352fce2 100644 --- a/models/account_move.py +++ b/models/account_move.py @@ -139,6 +139,39 @@ class AccountMove(models.Model): class AccountMoveLine(models.Model): _inherit = 'account.move.line' + @api.model + def _search_account_id(self, operator, value): + res = super()._search_account_id(operator, value) + if res and isinstance(res, list) and len(res) == 1: + term = res[0] + if len(term) == 3 and term[0] == 'account_id' and term[1] in ('in', 'not in') and isinstance(term[2], (list, tuple, set)): + resolved_ids = list(term[2]) + reconcile_accounts = self.env['account.account'].sudo().browse(resolved_ids).filtered('reconcile') + if reconcile_accounts: + cash_accounts = self.env['account.account'].sudo().search([('account_type', '=', 'asset_cash')]) + if cash_accounts: + if term[1] == 'in': + res = [ + '|', + ('account_id', 'in', tuple(reconcile_accounts.ids)), + '&', + '&', + ('account_id', 'in', tuple(cash_accounts.ids)), + ('journal_id.type', '=', 'cash'), + ('journal_id.company_id', '=', self.env.company.id) + ] + elif term[1] == 'not in': + res = [ + '&', + ('account_id', 'not in', tuple(reconcile_accounts.ids)), + '|', + '|', + ('account_id', 'not in', tuple(cash_accounts.ids)), + ('journal_id.type', '!=', 'cash'), + ('journal_id.company_id', '!=', self.env.company.id) + ] + return res + def _related_analytic_distribution(self): res = super()._related_analytic_distribution() if res: