# Copyright 2022 ForgeFlow S.L. # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) from odoo import _, api, fields, models from odoo.exceptions import UserError from odoo.osv import expression class RmaOrderLine(models.Model): _inherit = "rma.order.line" unreconciled = fields.Boolean( compute="_compute_unreconciled", search="_search_unreconciled", help="Indicates that a Purchase Order has related Journal items not " "reconciled.\nNote that if it is false it can be either that " "everything is reconciled or that the related accounts do not " "allow reconciliation", ) def _compute_unreconciled(self): acc_item = self.env["account.move.line"] for rec in self: domain = rec._get_rma_unreconciled_base_domain() unreconciled_domain = expression.AND( [domain, [("rma_line_id", "=", rec.id)]] ) unreconciled_items = acc_item.search(unreconciled_domain) rec.unreconciled = len(unreconciled_items) > 0 def _search_unreconciled(self, operator, value): if operator != "=" or not isinstance(value, bool): raise ValueError(_("Unsupported search operator")) acc_item = self.env["account.move.line"] domain = self._get_rma_unreconciled_base_domain() unreconciled_domain = expression.AND([domain, [("rma_line_id", "!=", False)]]) unreconciled_items = acc_item.search(unreconciled_domain) unreconciled_pos = unreconciled_items.mapped("rma_line_id") if value: return [("id", "in", unreconciled_pos.ids)] else: return [("id", "not in", unreconciled_pos.ids)] @api.model def _get_rma_unreconciled_base_domain(self): categories = self.env["product.category"].search( [("property_valuation", "=", "real_time")] ) included_accounts = ( categories.mapped("property_stock_account_input_categ_id").ids ) + (categories.mapped("property_stock_account_output_categ_id").ids) unreconciled_domain = [ ("account_id.reconcile", "=", True), ("account_id", "in", included_accounts), ("move_id.state", "=", "posted"), # for some reason when amount_residual is zero # is marked as reconciled, this is better check ("full_reconcile_id", "=", False), ("company_id", "in", self.env.companies.ids), ] return unreconciled_domain def action_view_unreconciled(self): self.ensure_one() acc_item = self.env["account.move.line"] domain = self._get_rma_unreconciled_base_domain() unreconciled_domain = expression.AND([domain, [("rma_line_id", "=", self.id)]]) unreconciled_items = acc_item.search(unreconciled_domain) action = self.env.ref("account.action_account_moves_all") action_dict = action.read()[0] action_dict["domain"] = [("id", "in", unreconciled_items.ids)] return action_dict def action_open_reconcile(self): aml_model = self.env["account.move.line"] action = self.action_view_unreconciled() amls = ( action.get("domain") and aml_model.search(action.get("domain")) or aml_model ) if getattr(aml_model, "action_reconcile", False): return amls.action_reconcile() elif getattr(aml_model, "action_reconcile_manually", False): return amls.action_reconcile_manually() else: raise UserError( _("Could not find a method to open the reconciliation view.") )