<commit_before># Copyright 2020 Binovo IT Human Project SL
# Copyright 2021 Landoo Sistemas de Informacion SL
# Copyright 2021 Digital5, S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import _, exceptions, models

from odoo.addons.l10n_es_ticketbai_api.models.ticketbai_invoice import RefundType
from odoo.addons.l10n_es_ticketbai_api.models.ticketbai_invoice_tax import (
    NotSubjectToCause,
    TicketBaiTaxType,
)


class AccountTax(models.Model):
    _inherit = "account.tax"

    def tbai_is_subject_to_tax(self):
        s_iva_ns_tbai_maps = self.env["tbai.tax.map"].search(
            [("code", "in", ("SNS", "BNS"))]
        )
        s_iva_ns_taxes = self.company_id.get_taxes_from_templates(
            s_iva_ns_tbai_maps.mapped("tax_template_ids")
        )
        return self not in s_iva_ns_taxes

    def tbai_is_tax_exempted(self):
        return self.tax_group_id.id == self.env.ref("l10n_es.tax_group_iva_0").id

    def tbai_get_exemption_cause(self, invoice_id):
        return (
            self.env["account.fp.tbai.tax"]
            .search(
                [
                    ("tax_id", "=", self.id),
                    ("position_id", "=", invoice_id.fiscal_position_id.id),
                ],
                limit=1,
            )
            .tbai_vat_exemption_key.code
        )

    def tbai_get_amount_total_company(self, invoice_id):
        if invoice_id.currency_id.id != invoice_id.company_id.currency_id.id:
            currency = invoice_id.currency_id.with_context(
                date=invoice_id.date or invoice_id.invoice_date,
                company_id=invoice_id.company_id.id,
            )
            amount = self.tbai_get_invoice_amount_for_tax_group(invoice_id)
            amount_total = currency.compute(amount, invoice_id.company_id.currency_id)
        else:
            amount_total = self.tbai_get_invoice_amount_for_tax_group(invoice_id)
        return amount_total

    def tbai_get_associated_re_tax(self, invoice_id):
        re_invoice_tax = None
        tbai_maps = self.env["tbai.tax.map"].search([("code", "=", "RE")])
        s_iva_re_taxes = self.company_id.get_taxes_from_templates(
            tbai_maps.mapped("tax_template_ids")
        )
        lines = invoice_id.invoice_line_ids.filtered(lambda l: self in l.tax_ids)
        re_taxes = lines.mapped("tax_ids").filtered(lambda tax: tax in s_iva_re_taxes)
        if 1 < len(re_taxes):
            raise exceptions.ValidationError(
                _(
                    "TicketBAI Invoice %(name)s Error: Tax %(tax)s contains "
                    "multiple Equivalence Surcharge Taxes"
                )
                % {"name": invoice_id.name, "tax": self.name}
            )
        elif 1 == len(re_taxes):
            re_invoice_taxes = (
                invoice_id.invoice_line_ids.filtered(
                    lambda x: any([tax.id == re_taxes.id for tax in x.tax_ids])
                )
                .mapped("tax_ids")
                .filtered(lambda t: t in s_iva_re_taxes)
            )
            if 1 == len(re_invoice_taxes):
                re_invoice_tax = re_invoice_taxes
            else:
                raise exceptions.ValidationError(
                    _(
                        "TicketBAI Invoice %(name)s Error: the Invoice should "
                        "have one tax line for Tax %(tax)s"
                    )
                    % {"name": invoice_id.name, "tax": re_taxes.name}
                )
        return re_invoice_tax

    def tbai_get_value_tax_type(self):
        if self.tbai_es_prestacion_servicios():
            res = TicketBaiTaxType.service.value
        elif self.tbai_es_entrega():
            res = TicketBaiTaxType.provision_of_goods.value
        else:
            res = None
        return res

    def tbai_es_prestacion_servicios(self):
        # No sujeto Repercutido (Servicios)
        # Prestación de servicios intracomunitario y extracomunitario
        # Servicios
        # Servicios Exento Repercutido
        tbai_maps = self.env["tbai.tax.map"].search(
            [("code", "in", ("SNS", "SIE", "S", "SER"))]
        )
        taxes = self.company_id.get_taxes_from_templates(
            tbai_maps.mapped("tax_template_ids")
        )
        return self in taxes

    def tbai_es_entrega(self):
        # Bienes
        # No sujeto Repercutido (Bienes)
        # Entregas Intracomunitarias y Exportaciones exentas
        # Servicios Exento Repercutido
        tbai_maps = self.env["tbai.tax.map"].search(
            [("code", "in", ("B", "BNS", "IEE", "SER"))]
        )
        taxes = self.company_id.get_taxes_from_templates(
            tbai_maps.mapped("tax_template_ids")
        )
        return self in taxes

    def tbai_get_value_causa(self, invoice_id):
        country_code = invoice_id.partner_id.tbai_get_partner_country_code()
        if country_code and self.env.ref("base.es").code.upper() == country_code:
            fp_not_subject_tai = invoice_id.company_id.get_fps_from_templates(
                self.env.ref("l10n_es.fp_not_subject_tai")
            )
            if (
                fp_not_subject_tai
                and fp_not_subject_tai == invoice_id.fiscal_position_id
            ):
                res = NotSubjectToCause.RL.value
            else:
                res = NotSubjectToCause.OT.value
        elif country_code:
            res = NotSubjectToCause.RL.value
        else:
            raise exceptions.ValidationError(
                _("Country code for partner %s not found!") % invoice_id.partner_id.name
            )
        return res

    def tbai_get_value_base_imponible(self, invoice_id):
        if RefundType.differences.value == invoice_id.tbai_refund_type:
            sign = -1
        else:
            sign = 1
        if invoice_id.currency_id.id != invoice_id.company_id.currency_id.id:
            currency = invoice_id.currency_id.with_context(
                date=invoice_id.date or invoice_id.invoice_date,
                company_id=invoice_id.company_id.id,
            )
            base_balance = self.tbai_get_invoice_base_balace_for_tax_group(invoice_id)
            base = currency.compute(base_balance, invoice_id.company_id.currency_id)
        else:
            base = self.tbai_get_invoice_base_balace_for_tax_group(invoice_id)
        return "%.2f" % (sign * base)

    def tbai_get_value_tipo_no_exenta(self):
        tbai_maps = self.env["tbai.tax.map"].search([("code", "=", "ISP")])
        isp_taxes = self.company_id.get_taxes_from_templates(
            tbai_maps.mapped("tax_template_ids")
        )
        if self in isp_taxes:
            res = "S2"
        else:
            res = "S1"
        return res

    def tbai_get_value_cuota_impuesto(self, invoice_id):
        if RefundType.differences.value == invoice_id.tbai_refund_type:<commit_msg>[FIX] l10n_es_ticketbai: currency.compute -> currency._convert<commit_after># Copyright 2020 Binovo IT Human Project SL
# Copyright 2021 Landoo Sistemas de Informacion SL
# Copyright 2021 Digital5, S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import _, exceptions, models

from odoo.addons.l10n_es_ticketbai_api.models.ticketbai_invoice import RefundType
from odoo.addons.l10n_es_ticketbai_api.models.ticketbai_invoice_tax import (
    NotSubjectToCause,
    TicketBaiTaxType,
)


class AccountTax(models.Model):
    _inherit = "account.tax"

    def tbai_is_subject_to_tax(self):
        s_iva_ns_tbai_maps = self.env["tbai.tax.map"].search(
            [("code", "in", ("SNS", "BNS"))]
        )
        s_iva_ns_taxes = self.company_id.get_taxes_from_templates(
            s_iva_ns_tbai_maps.mapped("tax_template_ids")
        )
        return self not in s_iva_ns_taxes

    def tbai_is_tax_exempted(self):
        return self.tax_group_id.id == self.env.ref("l10n_es.tax_group_iva_0").id

    def tbai_get_exemption_cause(self, invoice_id):
        return (
            self.env["account.fp.tbai.tax"]
            .search(
                [
                    ("tax_id", "=", self.id),
                    ("position_id", "=", invoice_id.fiscal_position_id.id),
                ],
                limit=1,
            )
            .tbai_vat_exemption_key.code
        )

    def tbai_get_amount_total_company(self, invoice_id):
        if invoice_id.currency_id.id != invoice_id.company_id.currency_id.id:
            currency = invoice_id.currency_id
            amount = self.tbai_get_invoice_amount_for_tax_group(invoice_id)
            amount_total = currency._convert(
                amount,
                invoice_id.company_id.currency_id,
                invoice_id.company_id,
                invoice_id.date or invoice_id.invoice_date,
            )
        else:
            amount_total = self.tbai_get_invoice_amount_for_tax_group(invoice_id)
        return amount_total

    def tbai_get_associated_re_tax(self, invoice_id):
        re_invoice_tax = None
        tbai_maps = self.env["tbai.tax.map"].search([("code", "=", "RE")])
        s_iva_re_taxes = self.company_id.get_taxes_from_templates(
            tbai_maps.mapped("tax_template_ids")
        )
        lines = invoice_id.invoice_line_ids.filtered(lambda l: self in l.tax_ids)
        re_taxes = lines.mapped("tax_ids").filtered(lambda tax: tax in s_iva_re_taxes)
        if 1 < len(re_taxes):
            raise exceptions.ValidationError(
                _(
                    "TicketBAI Invoice %(name)s Error: Tax %(tax)s contains "
                    "multiple Equivalence Surcharge Taxes"
                )
                % {"name": invoice_id.name, "tax": self.name}
            )
        elif 1 == len(re_taxes):
            re_invoice_taxes = (
                invoice_id.invoice_line_ids.filtered(
                    lambda x: any([tax.id == re_taxes.id for tax in x.tax_ids])
                )
                .mapped("tax_ids")
                .filtered(lambda t: t in s_iva_re_taxes)
            )
            if 1 == len(re_invoice_taxes):
                re_invoice_tax = re_invoice_taxes
            else:
                raise exceptions.ValidationError(
                    _(
                        "TicketBAI Invoice %(name)s Error: the Invoice should "
                        "have one tax line for Tax %(tax)s"
                    )
                    % {"name": invoice_id.name, "tax": re_taxes.name}
                )
        return re_invoice_tax

    def tbai_get_value_tax_type(self):
        if self.tbai_es_prestacion_servicios():
            res = TicketBaiTaxType.service.value
        elif self.tbai_es_entrega():
            res = TicketBaiTaxType.provision_of_goods.value
        else:
            res = None
        return res

    def tbai_es_prestacion_servicios(self):
        # No sujeto Repercutido (Servicios)
        # Prestación de servicios intracomunitario y extracomunitario
        # Servicios
        # Servicios Exento Repercutido
        tbai_maps = self.env["tbai.tax.map"].search(
            [("code", "in", ("SNS", "SIE", "S", "SER"))]
        )
        taxes = self.company_id.get_taxes_from_templates(
            tbai_maps.mapped("tax_template_ids")
        )
        return self in taxes

    def tbai_es_entrega(self):
        # Bienes
        # No sujeto Repercutido (Bienes)
        # Entregas Intracomunitarias y Exportaciones exentas
        # Servicios Exento Repercutido
        tbai_maps = self.env["tbai.tax.map"].search(
            [("code", "in", ("B", "BNS", "IEE", "SER"))]
        )
        taxes = self.company_id.get_taxes_from_templates(
            tbai_maps.mapped("tax_template_ids")
        )
        return self in taxes

    def tbai_get_value_causa(self, invoice_id):
        country_code = invoice_id.partner_id.tbai_get_partner_country_code()
        if country_code and self.env.ref("base.es").code.upper() == country_code:
            fp_not_subject_tai = invoice_id.company_id.get_fps_from_templates(
                self.env.ref("l10n_es.fp_not_subject_tai")
            )
            if (
                fp_not_subject_tai
                and fp_not_subject_tai == invoice_id.fiscal_position_id
            ):
                res = NotSubjectToCause.RL.value
            else:
                res = NotSubjectToCause.OT.value
        elif country_code:
            res = NotSubjectToCause.RL.value
        else:
            raise exceptions.ValidationError(
                _("Country code for partner %s not found!") % invoice_id.partner_id.name
            )
        return res

    def tbai_get_value_base_imponible(self, invoice_id):
        if RefundType.differences.value == invoice_id.tbai_refund_type:
            sign = -1
        else:
            sign = 1
        if invoice_id.currency_id.id != invoice_id.company_id.currency_id.id:
            currency = invoice_id.currency_id
            base_balance = self.tbai_get_invoice_base_balace_for_tax_group(invoice_id)
            base = currency._convert(
                base_balance,
                invoice_id.company_id.currency_id,
                invoice_id.company_id,
                invoice_id.date or invoice_id.invoice_date,
            )
        else:
            base = self.tbai_get_invoice_base_balace_for_tax_group(invoice_id)
        return "%.2f" % (sign * base)

    def tbai_get_value_tipo_no_exenta(self):
        tbai_maps = self.env["tbai.tax.map"].search([("code", "=", "ISP")])
        isp_taxes = self.company_id.get_taxes_from_templates(
            tbai_maps.mapped("tax_template_ids")
        )
        if self in isp_taxes:
            res = "S2"
        else:
            res = "S1"
        return res

    def tbai_get_value_cuota_impuesto(self, invoice_id):
        if RefundType.differences.value == invoice_id.tbai_refund_type:
{'fraction_non_alphanumeric': 0.09322340348593332, 'fraction_numerical': 0.004917914225790121, 'mean_word_length': 2.0178961152335226, 'pattern_counts': {'":': 8, '<': 5, '<?xml version=': 0, '>': 4, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, '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': '353928', 'n_tokens_mistral': 4680, 'n_tokens_neox': 4454, 'n_words': 724}