diff --git a/l10n_br_account/models/account_move.py b/l10n_br_account/models/account_move.py index b9ebe11edf38..9ad472788566 100644 --- a/l10n_br_account/models/account_move.py +++ b/l10n_br_account/models/account_move.py @@ -424,7 +424,7 @@ def _compute_taxes_mapped(self, base_line): tax_type == "purchase" and base_line.credit ) price_unit_wo_discount = base_line.amount_currency - + manual_tax_values = base_line._prepare_br_manual_tax_dict() balance_taxes_res = base_line.tax_ids._origin.with_context( force_sign=move._get_tax_force_sign() ).compute_all( @@ -453,6 +453,7 @@ def _compute_taxes_mapped(self, base_line): icmssn_range=base_line.icmssn_range_id, icms_origin=base_line.icms_origin, ind_final=base_line.ind_final, + **manual_tax_values, ) return balance_taxes_res diff --git a/l10n_br_account/models/account_move_line.py b/l10n_br_account/models/account_move_line.py index 157897a91db8..16fbfd673f79 100644 --- a/l10n_br_account/models/account_move_line.py +++ b/l10n_br_account/models/account_move_line.py @@ -5,6 +5,10 @@ from odoo import api, fields, models +from odoo.addons.l10n_br_fiscal.models.document_line_mixin_methods import ( + FISCAL_TAX_PREFIXES, +) + from .account_move import InheritsCheckMuteLogger # These fields have the same name in account.move.line @@ -381,6 +385,10 @@ def _get_price_total_and_subtotal( move_type=None, ): self.ensure_one() + + # get the dict with the values of the taxes entered manually. + manual_tax_values = self._prepare_br_manual_tax_dict() + return super( AccountMoveLine, self.with_context( @@ -403,6 +411,7 @@ def _get_price_total_and_subtotal( icms_origin=self.icms_origin, ind_final=self.ind_final, icms_relief_value=self.icms_relief_value, + **manual_tax_values, ), )._get_price_total_and_subtotal( price_unit=price_unit or self.price_unit, @@ -415,6 +424,17 @@ def _get_price_total_and_subtotal( move_type=move_type or self.move_id.move_type, ) + def _get_manual_tax_values_from_context(self): + tax_values = {} + suffixes = ["_base_manual", "_value_manual"] + + for tax_prefix in FISCAL_TAX_PREFIXES: + for suffix in suffixes: + attr_name = tax_prefix + suffix + tax_values[attr_name] = self.env.context.get(attr_name) + + return tax_values + @api.model def _get_price_total_and_subtotal_model( self, @@ -456,6 +476,7 @@ def _get_price_total_and_subtotal_model( force_sign = ( -1 if move_type in ("out_invoice", "in_refund", "out_receipt") else 1 ) + manual_tax_values = self._get_manual_tax_values_from_context() taxes_res = taxes._origin.with_context(force_sign=force_sign).compute_all( line_discount_price_unit, currency=currency, @@ -482,6 +503,7 @@ def _get_price_total_and_subtotal_model( icmssn_range=self.env.context.get("icmssn_range"), icms_origin=self.env.context.get("icms_origin"), ind_final=self.env.context.get("ind_final"), + **manual_tax_values, ) result["price_subtotal"] = taxes_res["total_excluded"] @@ -509,7 +531,47 @@ def _onchange_fiscal_document_line_id(self): # override the default product uom (set by the onchange): self.product_uom_id = self.fiscal_document_line_id.uom_id.id - @api.onchange("fiscal_tax_ids") + @api.onchange( + "fiscal_tax_ids", + "icms_base_manual", + "icms_value_manual", + "icmsst_base_manual", + "icmsst_value_manual", + "issqn_base_manual", + "issqn_value_manual", + "issqn_wh_base_manual", + "issqn_wh_value_manual", + "icmsst_wh_base_manual", + "icmsst_wh_value_manual", + "ipi_base_manual", + "ipi_value_manual", + "ii_base_manual", + "ii_value_manual", + "cofins_base_manual", + "cofins_value_manual", + "cofinsst_base_manual", + "cofinsst_value_manual", + "cofins_wh_base_manual", + "cofins_wh_value_manual", + "pis_base_manual", + "pis_value_manual", + "pisst_base_manual", + "pisst_value_manual", + "pis_wh_base_manual", + "pis_wh_value_manual", + "csll_base_manual", + "csll_value_manual", + "csll_wh_base_manual", + "csll_wh_value_manual", + "irpj_base_manual", + "irpj_value_manual", + "irpj_wh_base_manual", + "irpj_wh_value_manual", + "inss_base_manual", + "inss_value_manual", + "inss_wh_base_manual", + "inss_wh_value_manual", + ) def _onchange_fiscal_tax_ids(self): """Ao alterar o campo fiscal_tax_ids que contém os impostos fiscais, são atualizados os impostos contábeis relacionados""" diff --git a/l10n_br_account/models/account_tax.py b/l10n_br_account/models/account_tax.py index 90aa2a1e3149..43679429fc7b 100644 --- a/l10n_br_account/models/account_tax.py +++ b/l10n_br_account/models/account_tax.py @@ -44,6 +44,7 @@ def compute_all( icmssn_range=None, icms_origin=None, ind_final=FINAL_CUSTOMER_NO, + **kwargs, ): """Returns all information required to apply taxes (in self + their children in case of a tax goup). @@ -117,6 +118,7 @@ def compute_all( icmssn_range=icmssn_range, icms_origin=icms_origin or product.icms_origin, ind_final=ind_final, + **kwargs, ) taxes_results["amount_tax_included"] = fiscal_taxes_results["amount_included"] diff --git a/l10n_br_fiscal/models/document_line_mixin.py b/l10n_br_fiscal/models/document_line_mixin.py index 1ac41117f2b5..1ce1724394b5 100644 --- a/l10n_br_fiscal/models/document_line_mixin.py +++ b/l10n_br_fiscal/models/document_line_mixin.py @@ -301,6 +301,18 @@ def _operation_domain(self): default=ISSQN_INCENTIVE_DEFAULT, ) + issqn_base_manual = fields.Monetary( + string="Manual ISSQN Base", + help="Value of the ISSQN Base calculated manually. " + "Leave this field blank for automatic calculation.", + ) + + issqn_value_manual = fields.Monetary( + string="Manual ISSQN Value", + help="Value of the ISSQN Value calculated manually. " + "Leave this field blank for automatic calculation.", + ) + issqn_base = fields.Monetary(string="ISSQN Base") issqn_percent = fields.Float(string="ISSQN %") @@ -315,6 +327,18 @@ def _operation_domain(self): domain=[("tax_domain", "=", TAX_DOMAIN_ISSQN_WH)], ) + issqn_wh_base_manual = fields.Monetary( + string="Manual ISSQN RET Base", + help="Value of the ISSQN RET Base calculated manually. " + "Leave this field blank for automatic calculation.", + ) + + issqn_wh_value_manual = fields.Monetary( + string="Manual ISSQN RET Value", + help="Value of the ISSQN RET Value calculated manually. " + "Leave this field blank for automatic calculation.", + ) + issqn_wh_base = fields.Monetary(string="ISSQN RET Base") issqn_wh_percent = fields.Float(string="ISSQN RET %") @@ -364,6 +388,18 @@ def _operation_domain(self): selection=ICMS_ORIGIN, string="ICMS Origin", default=ICMS_ORIGIN_DEFAULT ) + icms_base_manual = fields.Monetary( + string="Manual ICMS Base", + help="Value of the ICMS Base calculated manually. " + "Leave this field blank for automatic calculation.", + ) + + icms_value_manual = fields.Monetary( + string="Manual ICMS Value", + help="Value of the ICMS Value calculated manually. " + "Leave this field blank for automatic calculation.", + ) + # vBC - Valor da base de cálculo do ICMS icms_base = fields.Monetary(string="ICMS Base") @@ -404,6 +440,18 @@ def _operation_domain(self): default=ICMS_ST_BASE_TYPE_DEFAULT, ) + icmsst_base_manual = fields.Monetary( + string="Manual ICMS ST Base", + help="Value of the ICMS ST Base calculated manually. " + "Leave this field blank for automatic calculation.", + ) + + icmsst_value_manual = fields.Monetary( + string="Manual ICMS ST Value", + help="Value of the ICMS ST Value calculated manually. " + "Leave this field blank for automatic calculation.", + ) + # pMVAST - Percentual da margem de valor Adicionado do ICMS ST icmsst_mva_percent = fields.Float(string="ICMS ST MVA %") @@ -419,6 +467,18 @@ def _operation_domain(self): # vICMSST - Valor do ICMS ST icmsst_value = fields.Monetary(string="ICMS ST Value") + icmsst_wh_base_manual = fields.Monetary( + string="Manual ICMS ST RET Base", + help="Value of the ICMS ST RET Base calculated manually. " + "Leave this field blank for automatic calculation.", + ) + + icmsst_wh_value_manual = fields.Monetary( + string="Manual ICMS ST RET Value", + help="Value of the ICMS ST RET Value calculated manually. " + "Leave this field blank for automatic calculation.", + ) + # vBCSTRet - Valor da base de cálculo do ICMS ST retido icmsst_wh_base = fields.Monetary(string="ICMS ST WH Base") @@ -553,6 +613,18 @@ def _operation_domain(self): selection=TAX_BASE_TYPE, string="IPI Base Type", default=TAX_BASE_TYPE_PERCENT ) + ipi_base_manual = fields.Monetary( + string="Manual IPI Base", + help="Value of the IPI Base calculated manually. " + "Leave this field blank for automatic calculation.", + ) + + ipi_value_manual = fields.Monetary( + string="Manual IPI Value", + help="Value of the IPI Value calculated manually. " + "Leave this field blank for automatic calculation.", + ) + ipi_base = fields.Monetary(string="IPI Base") ipi_percent = fields.Float(string="IPI %") @@ -575,6 +647,18 @@ def _operation_domain(self): domain=[("tax_domain", "=", TAX_DOMAIN_II)], ) + ii_base_manual = fields.Monetary( + string="Manual II Base", + help="Value of the II Base calculated manually. " + "Leave this field blank for automatic calculation.", + ) + + ii_value_manual = fields.Monetary( + string="Manual II Value", + help="Value of the II Value calculated manually. " + "Leave this field blank for automatic calculation.", + ) + ii_base = fields.Monetary(string="II Base") ii_percent = fields.Float(string="II %") @@ -611,6 +695,18 @@ def _operation_domain(self): default=TAX_BASE_TYPE_PERCENT, ) + cofins_base_manual = fields.Monetary( + string="Manual COFINS Base", + help="Value of the COFINS Base calculated manually. " + "Leave this field blank for automatic calculation.", + ) + + cofins_value_manual = fields.Monetary( + string="Manual COFINS Value", + help="Value of the COFINS Value calculated manually. " + "Leave this field blank for automatic calculation.", + ) + cofins_base = fields.Monetary(string="COFINS Base") cofins_percent = fields.Float(string="COFINS %") @@ -652,6 +748,18 @@ def _operation_domain(self): default=TAX_BASE_TYPE_PERCENT, ) + cofinsst_base_manual = fields.Monetary( + string="Manual COFINS ST Base", + help="Value of the COFINS ST Base calculated manually. " + "Leave this field blank for automatic calculation.", + ) + + cofinsst_value_manual = fields.Monetary( + string="Manual COFINS ST Value", + help="Value of the COFINS ST Value calculated manually. " + "Leave this field blank for automatic calculation.", + ) + cofinsst_base = fields.Monetary(string="COFINS ST Base") cofinsst_percent = fields.Float(string="COFINS ST %") @@ -672,6 +780,18 @@ def _operation_domain(self): default=TAX_BASE_TYPE_PERCENT, ) + cofins_wh_base_manual = fields.Monetary( + string="Manual COFINS RET Base", + help="Value of the COFINS RET Base calculated manually. " + "Leave this field blank for automatic calculation.", + ) + + cofins_wh_value_manual = fields.Monetary( + string="Manual COFINS RET Value", + help="Value of the COFINS RET Value calculated manually. " + "Leave this field blank for automatic calculation.", + ) + cofins_wh_base = fields.Monetary(string="COFINS RET Base") cofins_wh_percent = fields.Float(string="COFINS RET %") @@ -703,6 +823,18 @@ def _operation_domain(self): selection=TAX_BASE_TYPE, string="PIS Base Type", default=TAX_BASE_TYPE_PERCENT ) + pis_base_manual = fields.Monetary( + string="Manual PIS Base", + help="Value of the PIS Base calculated manually. " + "Leave this field blank for automatic calculation.", + ) + + pis_value_manual = fields.Monetary( + string="Manual PIS Value", + help="Value of the PIS Value calculated manually. " + "Leave this field blank for automatic calculation.", + ) + pis_base = fields.Monetary(string="PIS Base") pis_percent = fields.Float(string="PIS %") @@ -744,6 +876,18 @@ def _operation_domain(self): default=TAX_BASE_TYPE_PERCENT, ) + pisst_base_manual = fields.Monetary( + string="Manual PIS ST Base", + help="Value of the PIS ST Base calculated manually. " + "Leave this field blank for automatic calculation.", + ) + + pisst_value_manual = fields.Monetary( + string="Manual PIS ST Value", + help="Value of the PIS ST Value calculated manually. " + "Leave this field blank for automatic calculation.", + ) + pisst_base = fields.Monetary(string="PIS ST Base") pisst_percent = fields.Float(string="PIS ST %") @@ -764,6 +908,18 @@ def _operation_domain(self): default=TAX_BASE_TYPE_PERCENT, ) + pis_wh_base_manual = fields.Monetary( + string="Manual PIS RET Base", + help="Value of the PIS RET Base calculated manually. " + "Leave this field blank for automatic calculation.", + ) + + pis_wh_value_manual = fields.Monetary( + string="Manual PIS RET Value", + help="Value of the PIS RET Value calculated manually. " + "Leave this field blank for automatic calculation.", + ) + pis_wh_base = fields.Monetary(string="PIS RET Base") pis_wh_percent = fields.Float(string="PIS RET %") @@ -779,6 +935,18 @@ def _operation_domain(self): domain=[("tax_domain", "=", TAX_DOMAIN_CSLL)], ) + csll_base_manual = fields.Monetary( + string="Manual CSLL Base", + help="Value of the CSLL Base calculated manually. " + "Leave this field blank for automatic calculation.", + ) + + csll_value_manual = fields.Monetary( + string="Manual CSLL Value", + help="Value of the CSLL Value calculated manually. " + "Leave this field blank for automatic calculation.", + ) + csll_base = fields.Monetary(string="CSLL Base") csll_percent = fields.Float(string="CSLL %") @@ -793,6 +961,18 @@ def _operation_domain(self): domain=[("tax_domain", "=", TAX_DOMAIN_CSLL_WH)], ) + csll_wh_base_manual = fields.Monetary( + string="Manual CSLL RET Base", + help="Value of the CSLL RET Base calculated manually. " + "Leave this field blank for automatic calculation.", + ) + + csll_wh_value_manual = fields.Monetary( + string="Manual CSLL RET Value", + help="Value of the CSLL RET Value calculated manually. " + "Leave this field blank for automatic calculation.", + ) + csll_wh_base = fields.Monetary(string="CSLL RET Base") csll_wh_percent = fields.Float(string="CSLL RET %") @@ -807,6 +987,18 @@ def _operation_domain(self): domain=[("tax_domain", "=", TAX_DOMAIN_IRPJ)], ) + irpj_base_manual = fields.Monetary( + string="Manual IRPJ Base", + help="Value of the IRPJ Base calculated manually. " + "Leave this field blank for automatic calculation.", + ) + + irpj_value_manual = fields.Monetary( + string="Manual IRPJ Value", + help="Value of the IRPJ Value calculated manually. " + "Leave this field blank for automatic calculation.", + ) + irpj_base = fields.Monetary(string="IRPJ Base") irpj_percent = fields.Float(string="IRPJ %") @@ -821,6 +1013,18 @@ def _operation_domain(self): domain=[("tax_domain", "=", TAX_DOMAIN_IRPJ_WH)], ) + irpj_wh_base_manual = fields.Monetary( + string="Manual IRPJ RET Base", + help="Value of the IRPJ RET Base calculated manually. " + "Leave this field blank for automatic calculation.", + ) + + irpj_wh_value_manual = fields.Monetary( + string="Manual IRPJ RET Value", + help="Value of the IRPJ RET Value calculated manually. " + "Leave this field blank for automatic calculation.", + ) + irpj_wh_base = fields.Monetary(string="IRPJ RET Base") irpj_wh_percent = fields.Float(string="IRPJ RET %") @@ -835,6 +1039,18 @@ def _operation_domain(self): domain=[("tax_domain", "=", TAX_DOMAIN_INSS)], ) + inss_base_manual = fields.Monetary( + string="Manual INSS Base", + help="Value of the INSS Base calculated manually. " + "Leave this field blank for automatic calculation.", + ) + + inss_value_manual = fields.Monetary( + string="Manual INSS Value", + help="Value of the INSS Value calculated manually. " + "Leave this field blank for automatic calculation.", + ) + inss_base = fields.Monetary(string="INSS Base") inss_percent = fields.Float(string="INSS %") @@ -849,6 +1065,18 @@ def _operation_domain(self): domain=[("tax_domain", "=", TAX_DOMAIN_INSS_WH)], ) + inss_wh_base_manual = fields.Monetary( + string="Manual INSS RET Base", + help="Value of the INSS RET Base calculated manually. " + "Leave this field blank for automatic calculation.", + ) + + inss_wh_value_manual = fields.Monetary( + string="Manual INSS Value", + help="Value of the INSS Value calculated manually. " + "Leave this field blank for automatic calculation.", + ) + inss_wh_base = fields.Monetary(string="INSS RET Base") inss_wh_percent = fields.Float(string="INSS RET %") diff --git a/l10n_br_fiscal/models/document_line_mixin_methods.py b/l10n_br_fiscal/models/document_line_mixin_methods.py index 902d55cc635d..8d32ecf1cbb9 100644 --- a/l10n_br_fiscal/models/document_line_mixin_methods.py +++ b/l10n_br_fiscal/models/document_line_mixin_methods.py @@ -44,6 +44,28 @@ "cofinsst_cst_id", ] +FISCAL_TAX_PREFIXES = [ + "icms", + "icmsst", + "issqn", + "issqn_wh", + "icmsst_wh", + "ipi", + "ii", + "cofins", + "cofinsst", + "cofins_wh", + "pis", + "pisst", + "pis_wh", + "csll", + "csll_wh", + "irpj", + "irpj_wh", + "inss", + "inss_wh", +] + class FiscalDocumentLineMixinMethods(models.AbstractModel): _name = "l10n_br_fiscal.document.line.mixin.methods" @@ -188,6 +210,10 @@ def _compute_amounts(self): def _compute_taxes(self, taxes, cst=None): self.ensure_one() + + # get the dict with the values of the taxes entered manually. + manual_tax_values = self._prepare_br_manual_tax_dict() + return taxes.compute_taxes( company=self.company_id, partner=self._get_fiscal_partner(), @@ -213,6 +239,7 @@ def _compute_taxes(self, taxes, cst=None): icmssn_range=self.icmssn_range_id, icms_origin=self.icms_origin, icms_cst_id=self.icms_cst_id, + **manual_tax_values, ind_final=self.ind_final, icms_relief_id=self.icms_relief_id, ) @@ -244,6 +271,17 @@ def _prepare_br_fiscal_dict(self, default=False): return {f"default_{k}": vals[k] for k in vals.keys()} return vals + def _prepare_br_manual_tax_dict(self): + manual_tax_dict = {} + suffixes = ["_base_manual", "_value_manual"] + + for tax_prefix in FISCAL_TAX_PREFIXES: + for suffix in suffixes: + attr_name = tax_prefix + suffix + manual_tax_dict[attr_name] = getattr(self, attr_name) + + return manual_tax_dict + def _get_all_tax_id_fields(self): self.ensure_one() taxes = self.env["l10n_br_fiscal.tax"] @@ -852,6 +890,44 @@ def _onchange_cofinsst_fields(self): "insurance_value", "other_value", "freight_value", + "icms_base_manual", + "icms_value_manual", + "icmsst_base_manual", + "icmsst_value_manual", + "issqn_base_manual", + "issqn_value_manual", + "issqn_wh_base_manual", + "issqn_wh_value_manual", + "icmsst_wh_base_manual", + "icmsst_wh_value_manual", + "ipi_base_manual", + "ipi_value_manual", + "ii_base_manual", + "ii_value_manual", + "cofins_base_manual", + "cofins_value_manual", + "cofinsst_base_manual", + "cofinsst_value_manual", + "cofins_wh_base_manual", + "cofins_wh_value_manual", + "pis_base_manual", + "pis_value_manual", + "pisst_base_manual", + "pisst_value_manual", + "pis_wh_base_manual", + "pis_wh_value_manual", + "csll_base_manual", + "csll_value_manual", + "csll_wh_base_manual", + "csll_wh_value_manual", + "irpj_base_manual", + "irpj_value_manual", + "irpj_wh_base_manual", + "irpj_wh_value_manual", + "inss_base_manual", + "inss_value_manual", + "inss_wh_base_manual", + "inss_wh_value_manual", ) def _onchange_fiscal_taxes(self): self._update_fiscal_tax_ids(self._get_all_tax_id_fields()) diff --git a/l10n_br_fiscal/models/tax.py b/l10n_br_fiscal/models/tax.py index 1a583402aa80..29362f8ea09c 100644 --- a/l10n_br_fiscal/models/tax.py +++ b/l10n_br_fiscal/models/tax.py @@ -2,7 +2,6 @@ # License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html from odoo import api, fields, models -from odoo.tools import float_is_zero from ..constants.fiscal import ( CFOP_DESTINATION_EXPORT, @@ -184,6 +183,8 @@ def cst_from_tax(self, fiscal_operation_type=FISCAL_OUT): @api.model def _compute_tax_base(self, tax, tax_dict, **kwargs): + """Calculates the base, percentage, and tax amount.""" + company = kwargs.get("company", tax.env.company) currency = kwargs.get("currency", company.currency_id) fiscal_price = kwargs.get("fiscal_price", 0.00) @@ -194,53 +195,55 @@ def _compute_tax_base(self, tax, tax_dict, **kwargs): freight_value = kwargs.get("freight_value", 0.00) other_value = kwargs.get("other_value", 0.00) - if tax.tax_group_id.base_with_additional_values: - tax_dict["add_to_base"] += sum( - [freight_value, insurance_value, other_value] - ) - tax_dict["remove_from_base"] += sum([discount_value]) - - base = 0.00 - if not tax_dict.get("percent_amount") and tax.percent_amount: tax_dict["percent_amount"] = tax.percent_amount if not tax_dict.get("value_amount") and tax.value_amount: tax_dict["value_amount"] = tax.value_amount - if tax_dict["base_type"] == "percent": - # Compute initial Tax Base for base_type Percent - base = currency.round(fiscal_price * fiscal_quantity) - - if tax_dict["base_type"] == "quantity": - # Compute initial Tax Base for base_type Quantity - base = fiscal_quantity - - if tax_dict["base_type"] == "fixed": - # Compute initial Tax Base - base = currency.round(tax_dict["value_amount"] * fiscal_quantity) + if tax_dict.get("base_manual"): + base_amount = tax_dict["base_manual"] + else: + # calculate base + if tax.tax_group_id.base_with_additional_values: + tax_dict["add_to_base"] += sum( + [freight_value, insurance_value, other_value] + ) + tax_dict["remove_from_base"] += sum([discount_value]) - # Update Base Value - base_amount = currency.round( - (base + tax_dict["add_to_base"]) - tax_dict["remove_from_base"] - ) + if tax_dict["base_type"] == "percent": + # Compute initial Tax Base for base_type Percent + base = currency.round(fiscal_price * fiscal_quantity) - # Compute Tax Base Reduction - base_reduction = base_amount * abs(tax.percent_reduction / 100) + if tax_dict["base_type"] == "quantity": + # Compute initial Tax Base for base_type Quantity + base = fiscal_quantity - # Compute Tax Base Amount - if compute_reduction: - base_amount = currency.round(base_amount - base_reduction) + if tax_dict["base_type"] == "fixed": + # Compute initial Tax Base + base = currency.round(tax_dict["value_amount"] * fiscal_quantity) - if tax_dict.get("icmsst_mva_percent"): + # Update Base Value base_amount = currency.round( - base_amount * (1 + (tax_dict["icmsst_mva_percent"] / 100)) + (base + tax_dict["add_to_base"]) - tax_dict["remove_from_base"] ) - if tax_dict.get("compute_with_tax_value"): - base_amount = currency.round( - base_amount / (1 - (tax_dict["percent_amount"] / 100)) - ) + # Compute Tax Base Reduction + base_reduction = base_amount * abs(tax.percent_reduction / 100) + + # Compute Tax Base Amount + if compute_reduction: + base_amount = currency.round(base_amount - base_reduction) + + if tax_dict.get("icmsst_mva_percent"): + base_amount = currency.round( + base_amount * (1 + (tax_dict["icmsst_mva_percent"] / 100)) + ) + + if tax_dict.get("compute_with_tax_value"): + base_amount = currency.round( + base_amount / (1 - (tax_dict["percent_amount"] / 100)) + ) if ( not tax.percent_amount @@ -264,6 +267,11 @@ def _compute_tax(self, tax, taxes_dict, **kwargs): fiscal_operation_type = operation_line.fiscal_operation_type or FISCAL_OUT tax_dict = taxes_dict.get(tax.tax_domain) + + # extract manual values + base_manual = kwargs.get(f"{tax.tax_domain}_base_manual") + tax_value_manual = kwargs.get(f"{tax.tax_domain}_value_manual") + tax_dict.update( { "name": tax.name, @@ -275,6 +283,8 @@ def _compute_tax(self, tax, taxes_dict, **kwargs): "percent_reduction": tax.percent_reduction, "percent_amount": tax_dict.get("percent_amount", tax.percent_amount), "cst_id": tax.cst_from_tax(fiscal_operation_type), + "base_manual": base_manual, + "tax_value_manual": tax_value_manual, } ) @@ -283,21 +293,22 @@ def _compute_tax(self, tax, taxes_dict, **kwargs): tax_dict_icms = taxes_dict.get("icms", {}) tax_dict["remove_from_base"] += tax_dict_icms.get("tax_value", 0.00) - # TODO futuramente levar em consideração outros tipos de base de calculo - if float_is_zero(tax_dict.get("base", 0.00), currency.decimal_places): - tax_dict = self._compute_tax_base(tax, tax_dict, **kwargs) + tax_dict = self._compute_tax_base(tax, tax_dict, **kwargs) base_amount = tax_dict.get("base", 0.00) - if tax_dict["base_type"] == "percent": - tax_dict["tax_value"] = currency.round( - base_amount * (tax_dict["percent_amount"] / 100) - ) + if tax_dict.get("tax_value_manual"): + tax_dict["tax_value"] = tax_dict["tax_value_manual"] + else: + if tax_dict["base_type"] == "percent": + tax_dict["tax_value"] = currency.round( + base_amount * (tax_dict["percent_amount"] / 100) + ) - if tax_dict["base_type"] in ("quantity", "fixed"): - tax_dict["tax_value"] = currency.round( - base_amount * tax_dict["value_amount"] - ) + if tax_dict["base_type"] in ("quantity", "fixed"): + tax_dict["tax_value"] = currency.round( + base_amount * tax_dict["value_amount"] + ) return tax_dict @@ -537,12 +548,8 @@ def _compute_icmsst(self, tax, taxes_dict, **kwargs): if taxes_dict.get(tax.tax_domain): taxes_dict[tax.tax_domain]["icmsst_mva_percent"] = tax.icmsst_mva_percent - taxes_dict[tax.tax_domain].update( - self._compute_tax_base(tax, taxes_dict.get(tax.tax_domain), **kwargs) - ) - tax_dict = self._compute_tax(tax, taxes_dict, **kwargs) - if tax_dict.get("icmsst_mva_percent"): + if tax_dict.get("icmsst_mva_percent") and not tax_dict.get("tax_value_manual"): tax_dict["tax_value"] -= taxes_dict.get("icms", {}).get("tax_value", 0.0) return tax_dict diff --git a/l10n_br_fiscal/views/document_fiscal_line_mixin_view.xml b/l10n_br_fiscal/views/document_fiscal_line_mixin_view.xml index a11242c6a9cd..267c63d7892b 100644 --- a/l10n_br_fiscal/views/document_fiscal_line_mixin_view.xml +++ b/l10n_br_fiscal/views/document_fiscal_line_mixin_view.xml @@ -1,351 +1,463 @@ - - l10n_br_fiscal.document.line.mixin.form - l10n_br_fiscal.document.line - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + l10n_br_fiscal.document.line.mixin.form + l10n_br_fiscal.document.line + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - + - - - - - - - + + + - - - - - - + +
Keep empty for automatic + calculation
+ + +
+ + - - - - - -
- - + + + - - - - - + + + + - - - - - - -
- + +
Keep empty for automatic + calculation
+ + +
+
+
+ - - + - - - - + - - - - - + + + + - - - - - - - - - - - - - - - - - - - - + +
Keep empty for automatic + calculation
+ - - - - - - - - -
- + + + + + + + + + + + + + + + +
Keep empty for + automatic calculation
+ + +
+ + + + + + + +
Keep empty for + automatic calculation
+ + +
+
+
+ - - - - - + - - - - - - - - - - + - - - - - - -
- + + + - - + - - - + - - - - + + + - - - - - - - - - - + +
Keep empty for automatic + calculation
+ + +
+ +
+ - - + - - - - - - - - - - - - - - - + + + + + + +
Keep empty for automatic + calculation
+ + +
+ + + + +
+
+ + + - - - + - - - - + + + - - - - - - - - - - - + +
Keep empty for automatic + calculation
+ + +
+
+ + - - - - - - + + + + - - - - - - - - - - + +
Keep empty for automatic + calculation
+ + +
+
+ + - - - - + + + - - - - - - - -
- - - + +
Keep empty for automatic + calculation
+ + +
+
+
+ + + - - - + - - - - + + + - - - - - - - - - - - + +
Keep empty for automatic + calculation
+ + +
+
+ + - - - - - - + + + + - - - - - - - - - - + +
Keep empty for automatic + calculation
+ + +
+
+ + - - - - + + + - - - - - - - -
- + +
Keep empty for automatic + calculation
+ + +
+ +
+ - - - - - - + + + + + - - - - - - - - - + +
Keep empty for automatic + calculation
+ + +
+
+ + - - - - + + + - - - - - - - -
- + +
Keep empty for automatic + calculation
+ + +
+ +
+ - - + - - - - + + + - - - - - - - - - + +
Keep empty for automatic + calculation
+ + +
+
+ + - - - - + + + - - - - - - - -
- + +
Keep empty for automatic + calculation
+ + +
+ +
+ - - + - - - - + + + - - - - - - - - - + +
Keep empty for automatic + calculation
+ + +
+
+ + - - - - + + + - - - - - + + +
Keep empty for automatic + calculation
+ + +
+
+
+
+ + + + + + + + + + - - - - - - - - - - - - - - - - -
-
-
+ + + + +