<commit_before># Copyright 2015 <NAME> (<http://www.openforce.it>)
# Copyright 2018 <NAME> - Agile Business Group
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
from odoo.tools.float_utils import float_compare, float_round


class AccountFullReconcile(models.Model):
    _inherit = "account.full.reconcile"

    def _get_wt_moves(self):
        moves = self.mapped("reconciled_line_ids.move_id")
        wt_moves = self.env["withholding.tax.move"].search(
            [("wt_account_move_id", "in", moves.ids)]
        )
        return wt_moves

    @api.model
    def create(self, vals):
        res = super(AccountFullReconcile, self).create(vals)
        wt_moves = res._get_wt_moves()
        for wt_move in wt_moves:
            if wt_move.full_reconcile_id:
                wt_move.action_paid()
        return res

    def unlink(self):
        for rec in self:
            wt_moves = rec._get_wt_moves()
            super(AccountFullReconcile, rec).unlink()
            for wt_move in wt_moves:
                if not wt_move.full_reconcile_id:
                    wt_move.action_set_to_draft()
        return True


class AccountPartialReconcile(models.Model):
    _inherit = "account.partial.reconcile"

    @api.model
    def create(self, vals):
        # In case of WT The amount of reconcile mustn't exceed the tot net
        # amount. The amount residual will be full reconciled with amount net
        # and amount wt created with payment
        invoice = False
        ml_ids = []
        if vals.get("debit_move_id"):
            ml_ids.append(vals.get("debit_move_id"))
        if vals.get("credit_move_id"):
            ml_ids.append(vals.get("credit_move_id"))
        move_lines = self.env["account.move.line"].browse(ml_ids)
        invoice = move_lines.filtered(lambda x: x.exists()).move_id.filtered(
            lambda x: x.is_invoice()
        )
        # XXX
        # the following code mimics 12.0 behaviour; probably it's not correct
        if invoice:
            invoice = invoice[0]

        # Limit value of reconciliation
        if invoice and invoice.withholding_tax and invoice.amount_net_pay:
            # We must consider amount in foreign currency, if present
            # Note that this is always executed, for every reconciliation.
            # Thus, we must not change amount when not in withholding tax case
            amount = vals.get("amount_currency") or vals.get("amount")
            digits_rounding_precision = invoice.company_id.currency_id.rounding
            if (
                float_compare(
                    amount,
                    invoice.amount_net_pay,
                    precision_rounding=digits_rounding_precision,
                )
                == 1
            ):
                vals.update({"amount": invoice.amount_net_pay})

        # Create reconciliation
        reconcile = super(AccountPartialReconcile, self).create(vals)
        # Avoid re-generate wt moves if the move line is an wt move.
        # It's possible if the user unreconciles a wt move under invoice
        ld = self.env["account.move.line"].browse(vals.get("debit_move_id"))
        lc = self.env["account.move.line"].browse(vals.get("credit_move_id"))

        if (
            lc.withholding_tax_generated_by_move_id
            or ld.withholding_tax_generated_by_move_id
        ):
            is_wt_move = True
        else:
            is_wt_move = False
        # Wt moves creation
        if (
            invoice.withholding_tax_line_ids
            and not self._context.get("no_generate_wt_move")
            and not is_wt_move
        ):
            # and not wt_existing_moves\
            reconcile.generate_wt_moves()

        return reconcile

    def _prepare_wt_move(self, vals):
        """
        Hook to change values before wt move creation
        """
        return vals

    @api.model
    def generate_wt_moves(self):
        wt_statement_obj = self.env["withholding.tax.statement"]
        # Reconcile lines
        line_payment_ids = []
        line_payment_ids.append(self.debit_move_id.id)
        line_payment_ids.append(self.credit_move_id.id)
        domain = [("id", "in", line_payment_ids)]
        rec_line_model = self.env["account.move.line"]
        rec_lines = rec_line_model.search(domain)

        # Search statements of competence
        wt_statements = wt_statement_obj.browse()
        rec_line_statement = rec_line_model.browse()
        for rec_line in rec_lines:
            domain = [("move_id", "=", rec_line.move_id.id)]
            wt_statements = wt_statement_obj.search(domain)
            if wt_statements:
                rec_line_statement = rec_line
                break
        # Search payment move
        rec_line_payment = False
        for rec_line in rec_lines:
            if rec_line.id != rec_line_statement.id:
                rec_line_payment = rec_line
        # Generate wt moves
        wt_moves = []
        for wt_st in wt_statements:
            amount_wt = wt_st.get_wt_competence(self.amount)
            # Date maturity
            p_date_maturity = False
            payment_lines = wt_st.withholding_tax_id.payment_term.compute(
                amount_wt, rec_line_payment.date or False
            )
            if payment_lines and payment_lines[0]:
                p_date_maturity = payment_lines[0][0]
            wt_move_vals = {
                "statement_id": wt_st.id,
                "date": rec_line_payment.date,
                "partner_id": rec_line_statement.partner_id.id,
                "reconcile_partial_id": self.id,
                "payment_line_id": rec_line_payment.id,
                "credit_debit_line_id": rec_line_statement.id,
                "withholding_tax_id": wt_st.withholding_tax_id.id,
                "account_move_id": rec_line_payment.move_id.id or False,
                "date_maturity": p_date_maturity or rec_line_payment.date_maturity,
                "amount": amount_wt,
            }
            wt_move_vals = self._prepare_wt_move(wt_move_vals)
            wt_move = self.env["withholding.tax.move"].create(wt_move_vals)
            wt_moves.append(wt_move)
            # Generate account move<commit_msg>[FIX] l10n_it_withholding_tax: Prevent "AttributeError: 'bool' object has no attribute 'date'"<commit_after># Copyright 2015 <NAME> (<http://www.openforce.it>)
# Copyright 2018 <NAME> - Agile Business Group
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
from odoo.tools.float_utils import float_compare, float_round


class AccountFullReconcile(models.Model):
    _inherit = "account.full.reconcile"

    def _get_wt_moves(self):
        moves = self.mapped("reconciled_line_ids.move_id")
        wt_moves = self.env["withholding.tax.move"].search(
            [("wt_account_move_id", "in", moves.ids)]
        )
        return wt_moves

    @api.model
    def create(self, vals):
        res = super(AccountFullReconcile, self).create(vals)
        wt_moves = res._get_wt_moves()
        for wt_move in wt_moves:
            if wt_move.full_reconcile_id:
                wt_move.action_paid()
        return res

    def unlink(self):
        for rec in self:
            wt_moves = rec._get_wt_moves()
            super(AccountFullReconcile, rec).unlink()
            for wt_move in wt_moves:
                if not wt_move.full_reconcile_id:
                    wt_move.action_set_to_draft()
        return True


class AccountPartialReconcile(models.Model):
    _inherit = "account.partial.reconcile"

    @api.model
    def create(self, vals):
        # In case of WT The amount of reconcile mustn't exceed the tot net
        # amount. The amount residual will be full reconciled with amount net
        # and amount wt created with payment
        invoice = False
        ml_ids = []
        if vals.get("debit_move_id"):
            ml_ids.append(vals.get("debit_move_id"))
        if vals.get("credit_move_id"):
            ml_ids.append(vals.get("credit_move_id"))
        move_lines = self.env["account.move.line"].browse(ml_ids)
        invoice = move_lines.filtered(lambda x: x.exists()).move_id.filtered(
            lambda x: x.is_invoice()
        )
        # XXX
        # the following code mimics 12.0 behaviour; probably it's not correct
        if invoice:
            invoice = invoice[0]

        # Limit value of reconciliation
        if invoice and invoice.withholding_tax and invoice.amount_net_pay:
            # We must consider amount in foreign currency, if present
            # Note that this is always executed, for every reconciliation.
            # Thus, we must not change amount when not in withholding tax case
            amount = vals.get("amount_currency") or vals.get("amount")
            digits_rounding_precision = invoice.company_id.currency_id.rounding
            if (
                float_compare(
                    amount,
                    invoice.amount_net_pay,
                    precision_rounding=digits_rounding_precision,
                )
                == 1
            ):
                vals.update({"amount": invoice.amount_net_pay})

        # Create reconciliation
        reconcile = super(AccountPartialReconcile, self).create(vals)
        # Avoid re-generate wt moves if the move line is an wt move.
        # It's possible if the user unreconciles a wt move under invoice
        ld = self.env["account.move.line"].browse(vals.get("debit_move_id"))
        lc = self.env["account.move.line"].browse(vals.get("credit_move_id"))

        if (
            lc.withholding_tax_generated_by_move_id
            or ld.withholding_tax_generated_by_move_id
        ):
            is_wt_move = True
        else:
            is_wt_move = False
        # Wt moves creation
        if (
            invoice.withholding_tax_line_ids
            and not self._context.get("no_generate_wt_move")
            and not is_wt_move
        ):
            # and not wt_existing_moves\
            reconcile.generate_wt_moves()

        return reconcile

    def _prepare_wt_move(self, vals):
        """
        Hook to change values before wt move creation
        """
        return vals

    @api.model
    def generate_wt_moves(self):
        wt_statement_obj = self.env["withholding.tax.statement"]
        # Reconcile lines
        line_payment_ids = []
        line_payment_ids.append(self.debit_move_id.id)
        line_payment_ids.append(self.credit_move_id.id)
        domain = [("id", "in", line_payment_ids)]
        rec_line_model = self.env["account.move.line"]
        rec_lines = rec_line_model.search(domain)

        # Search statements of competence
        wt_statements = wt_statement_obj.browse()
        rec_line_statement = rec_line_model.browse()
        for rec_line in rec_lines:
            domain = [("move_id", "=", rec_line.move_id.id)]
            wt_statements = wt_statement_obj.search(domain)
            if wt_statements:
                rec_line_statement = rec_line
                break
        # Search payment move
        rec_line_payment = rec_line_model.browse()
        for rec_line in rec_lines:
            if rec_line.id != rec_line_statement.id:
                rec_line_payment = rec_line
        # Generate wt moves
        wt_moves = []
        for wt_st in wt_statements:
            amount_wt = wt_st.get_wt_competence(self.amount)
            # Date maturity
            p_date_maturity = False
            payment_lines = wt_st.withholding_tax_id.payment_term.compute(
                amount_wt, rec_line_payment.date or False
            )
            if payment_lines and payment_lines[0]:
                p_date_maturity = payment_lines[0][0]
            wt_move_vals = {
                "statement_id": wt_st.id,
                "date": rec_line_payment.date,
                "partner_id": rec_line_statement.partner_id.id,
                "reconcile_partial_id": self.id,
                "payment_line_id": rec_line_payment.id,
                "credit_debit_line_id": rec_line_statement.id,
                "withholding_tax_id": wt_st.withholding_tax_id.id,
                "account_move_id": rec_line_payment.move_id.id or False,
                "date_maturity": p_date_maturity or rec_line_payment.date_maturity,
                "amount": amount_wt,
            }
            wt_move_vals = self._prepare_wt_move(wt_move_vals)
            wt_move = self.env["withholding.tax.move"].create(wt_move_vals)
            wt_moves.append(wt_move)
            # Generate account move
{'fraction_non_alphanumeric': 0.08428425277406154, 'fraction_numerical': 0.002990477689462501, 'mean_word_length': 2.0807272727272728, 'pattern_counts': {'":': 22, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5819010', 'n_tokens_mistral': 3997, 'n_tokens_neox': 3717, 'n_words': 794}