-
-
Notifications
You must be signed in to change notification settings - Fork 249
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[12.0][REF] Cálculo da alíquota efetiva para empresas do Simples Nacional. #1831
Changes from all commits
dbd2104
85c4f91
933f72f
59a5865
b57b5ec
43824eb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,7 +37,7 @@ def compute_all( | |
fiscal_price=None, | ||
fiscal_quantity=None, | ||
uot=None, | ||
icmssn_range=None, | ||
cfop_type_move=None, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Deveria ser adicionado o argumento cfop no método compute_all pois além do type_move outros campos do l10n_br_fiscal.cfop pode ser nos método compute_all There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. pode ser também, coloquei o type_move direto pois é só isso que precisei no momento. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. O campo icmssn_range não deveria ser eliminado pois deveria ser usado no calculo dos impostos There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. o mesmo que #1831 (comment) |
||
icms_origin=None, | ||
ind_final=FINAL_CUSTOMER_NO, | ||
): | ||
|
@@ -102,7 +102,7 @@ def compute_all( | |
other_value=other_value, | ||
freight_value=freight_value, | ||
operation_line=operation_line, | ||
icmssn_range=icmssn_range, | ||
cfop_type_move=cfop_type_move, | ||
icms_origin=icms_origin or product.icms_origin, | ||
ind_final=ind_final, | ||
) | ||
|
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -28,6 +28,14 @@ def _get_amount_lines(self): | |||
"""Get object lines instaces used to compute fields""" | ||||
return self.mapped("line_ids") | ||||
|
||||
def is_sale_industry(self): | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Essa parte que define se é uma operação de industria ou comercio deveria estar no mapeamento dos impostos no fiscal.operation.line, lá se a empresa for do simples nacional deveria preencher o icmssn_range_id There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. esse método eu criei ele para facilitar o uso da informação na geração do comentário ( informações adicionais da nota fiscal) eu vou acessar pelo documento, por isso ele foi definido aqui, veja:
o icmssn_range_id no operation line deixa de ser usado com essa pr |
||||
types = self.line_ids.mapped("cfop_id").mapped("type_move") | ||||
return "sale_industry" in types | ||||
|
||||
def is_sale_commerce(self): | ||||
types = self.line_ids.mapped("cfop_id").mapped("type_move") | ||||
return "sale_commerce" in types | ||||
|
||||
@api.model | ||||
def _get_amount_fields(self): | ||||
"""Get all fields with 'amount_' prefix""" | ||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,8 +6,6 @@ | |
|
||
from odoo import api, fields, models | ||
|
||
from odoo.addons import decimal_precision as dp | ||
|
||
from ..constants.fiscal import ( | ||
COEFFICIENT_R, | ||
INDUSTRY_TYPE, | ||
|
@@ -49,12 +47,36 @@ | |
rec["fiscal_dummy_id"] = self._default_fiscal_dummy_id().id | ||
return rec | ||
|
||
sn_effective_tax_ids = fields.One2many( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ao invés de criar outro objeto, esse campo poderia ser um m2m calculado para carregar os anexos que a empresa tem incidência pela dependendo dos CNAEs primário e secundários There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Com esse modelo que fiz acho que fica mais apresentável as informações, se eu por essas informações dentro do CNAEs acho que pode ficar um pouco confuso, não estou usando os CNAEs para determinar os impostos. Antes dessa pr por exemplo, se quisesse saber qual era a alíquota do ICMS que o sistema tava calculando, tinha que primeiro emitir uma nota fiscal e ver dentro dela qual foi o ICMS calculado. Com a PR essa visualização já vem na hora. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cada anexo do simples nacional tem uma relação de CNAEs que a empresa deve ter para ser enquadrada naquele anexo por exemplo: Se a empresa tem o CNAE "4530702 - Comércio por atacado de pneumáticos e câmaras-de-ar" ela se enquadra no "ANEXO 1 Empresas de Comércio", Era dessa forma que dependendo do CNAE Principal eu preenchia o campo do anexo na empresa e a faixa como você colocou alterou o campo para um o2m para outro objeto, o correto seria ter um campo m2m calculado para mostrar as faixas dos anexos que a empresa se enquadra mas usando o objeto l10n_br_fiscal.simplified.tax.range com o campo calculado da taxa efetiva como comentei no #1831 (comment) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sim, o CNAE é uma forma de ver se a empresa se enquadra no anexo 1 ou anexo 2 etc, mas se uma empresa tem vários CNAEs, pode não ser a melhor forma, pois é necessário identificar qual anexo cada linha da fatura se enquadra e a linha da fatura não tem a informação do CNAE dela, o produto também não trás essa informação. por exemplo, se você cria uma fatura com 2 itens:
supondo que o faturamento anual da empresa foi 815 mil no últimos 12 meses, o imposto efetivo para cada linha será: linha 1) 8,44% simples nacional e permite aproveitamento do ICMS de 2,70%. linha 2) 7,94% simples nacional e permite aproveitamento do ICMS de 2,66%. por isso que acho que utilizar o CNAE não é a melhor forma de mapear os impostos do simples nacional. |
||
comodel_name="l10n_br_fiscal.simplified.tax.effective", | ||
inverse_name="company_id", | ||
string="Effective Taxs", | ||
help="Simples Nacional effective tax rate for each annex," | ||
"based on the range the company currently falls into.", | ||
) | ||
|
||
icmssn_credit_industry = fields.Float( | ||
string="ICMS Credit rate for Industry", | ||
help="Rate referring to the icms credit allowed when it is a sale of" | ||
"industrialized product in the establishment." | ||
"Applicable to Simple Nacional.", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo: "Simples Nacional." There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Vou corrigir obrigado! |
||
readonly=True, | ||
compute="_compute_icmssn", | ||
) | ||
|
||
icmssn_credit_commerce = fields.Float( | ||
string="ICMS Credit rate for Commerce", | ||
help="Rate referring to the icms credit allowed when it is a resale" | ||
"of merchandise. Applicable to Simple Nacional.", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo: "Simples Nacional." There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Vou corrigir obrigado! |
||
readonly=True, | ||
compute="_compute_icmssn", | ||
) | ||
|
||
def _get_company_address_fields(self, partner): | ||
"""Read the l10n_br specific functional fields.""" | ||
partner_fields = super()._get_company_address_fields(partner) | ||
partner_fields.update( | ||
{ | ||
"tax_framework": partner.tax_framework, | ||
"cnae_main_id": partner.cnae_main_id, | ||
} | ||
) | ||
|
@@ -65,6 +87,11 @@ | |
for c in self: | ||
c.partner_id.cnae_main_id = c.cnae_main_id | ||
|
||
@api.depends("partner_id", "partner_id.tax_framework") | ||
def _compute_tax_framework(self): | ||
for c in self: | ||
c.tax_framework = c.partner_id.tax_framework | ||
|
||
def _inverse_tax_framework(self): | ||
"""Write the l10n_br specific functional fields.""" | ||
for c in self: | ||
|
@@ -101,53 +128,6 @@ | |
) | ||
return dummy_doc | ||
|
||
@api.depends("cnae_main_id", "annual_revenue", "payroll_amount") | ||
def _compute_simplified_tax(self): | ||
for record in self: | ||
record.coefficient_r = False | ||
if record.payroll_amount and record.annual_revenue: | ||
coefficient_r_percent = record.payroll_amount / record.annual_revenue | ||
if coefficient_r_percent > COEFFICIENT_R: | ||
record.coefficient_r = True | ||
record.coefficient_r_percent = coefficient_r_percent | ||
|
||
simplified_tax_id = self.env["l10n_br_fiscal.simplified.tax"].search( | ||
[ | ||
("cnae_ids", "=", record.cnae_main_id.id), | ||
("coefficient_r", "=", record.coefficient_r), | ||
] | ||
) | ||
record.simplified_tax_id = simplified_tax_id | ||
|
||
if simplified_tax_id: | ||
tax_range = record.env["l10n_br_fiscal.simplified.tax.range"].search( | ||
[ | ||
("simplified_tax_id", "=", simplified_tax_id.id), | ||
("inital_revenue", "<=", record.annual_revenue), | ||
("final_revenue", ">=", record.annual_revenue), | ||
("simplified_tax_id.coefficient_r", "=", record.coefficient_r), | ||
], | ||
limit=1, | ||
) | ||
record.simplified_tax_range_id = tax_range | ||
|
||
if record.simplified_tax_range_id and record.annual_revenue: | ||
record.simplified_tax_percent = round( | ||
( | ||
( | ||
( | ||
record.annual_revenue | ||
* record.simplified_tax_range_id.total_tax_percent | ||
/ 100 | ||
) | ||
- record.simplified_tax_range_id.amount_deduced | ||
) | ||
/ record.annual_revenue | ||
) | ||
* 100, | ||
record.currency_id.decimal_places, | ||
) | ||
|
||
cnae_main_id = fields.Many2one( | ||
comodel_name="l10n_br_fiscal.cnae", | ||
compute="_compute_address", | ||
|
@@ -169,8 +149,9 @@ | |
tax_framework = fields.Selection( | ||
selection=TAX_FRAMEWORK, | ||
default=TAX_FRAMEWORK_NORMAL, | ||
compute="_compute_address", | ||
compute="_compute_tax_framework", | ||
inverse="_inverse_tax_framework", | ||
store=True, | ||
string="Tax Framework", | ||
) | ||
|
||
|
@@ -197,27 +178,6 @@ | |
currency_field="currency_id", | ||
) | ||
|
||
simplified_tax_id = fields.Many2one( | ||
comodel_name="l10n_br_fiscal.simplified.tax", | ||
compute="_compute_simplified_tax", | ||
string="Simplified Tax", | ||
readonly=True, | ||
) | ||
|
||
simplified_tax_range_id = fields.Many2one( | ||
comodel_name="l10n_br_fiscal.simplified.tax.range", | ||
compute="_compute_simplified_tax", | ||
store=True, | ||
readonly=True, | ||
string="Simplified Tax Range", | ||
) | ||
|
||
simplified_tax_percent = fields.Float( | ||
compute="_compute_simplified_tax", | ||
store=True, | ||
digits=dp.get_precision("Fiscal Tax Percent"), | ||
) | ||
|
||
payroll_amount = fields.Monetary( | ||
string="Last Period Payroll Amount", | ||
currency_field="currency_id", | ||
|
@@ -555,3 +515,50 @@ | |
self._set_tax_definition(self.tax_inss_wh_id) | ||
else: | ||
self._del_tax_definition(TAX_DOMAIN_INSS_WH) | ||
|
||
@api.depends("annual_revenue", "payroll_amount") | ||
def _compute_simplified_tax(self): | ||
for record in self: | ||
record._calculate_coefficient_r() | ||
|
||
def _compute_icmssn(self): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Acho que seria informativo ter um docstring aqui para explicar, porque foi feito esse filtro There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No simples nacional a alíquota do ICMS quando é Comércio é um valor, quando é Industria é outro valor. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Eu vou pedir pro @renatonlima comentar de novo sobre esse issue... |
||
for rec in self: | ||
rec.icmssn_credit_commerce = rec.sn_effective_tax_ids.filtered( | ||
lambda t: t.simplified_tax_id.name == "Anexo 1 - Comércio" | ||
).tax_icms_percent | ||
rec.icmssn_credit_industry = rec.sn_effective_tax_ids.filtered( | ||
lambda t: t.simplified_tax_id.name == "Anexo 2 - Indústria" | ||
).tax_icms_percent | ||
|
||
def _calculate_coefficient_r(self): | ||
for record in self: | ||
record.coefficient_r = False | ||
if record.payroll_amount and record.annual_revenue: | ||
coefficient_r_percent = record.payroll_amount / record.annual_revenue | ||
if coefficient_r_percent > COEFFICIENT_R: | ||
record.coefficient_r = True | ||
record.coefficient_r_percent = coefficient_r_percent | ||
|
||
def update_effective_tax_lines(self): | ||
for record in self: | ||
simplified_tax_model = self.env["l10n_br_fiscal.simplified.tax"] | ||
for simplified_id in simplified_tax_model.search([]): | ||
effective_tax = record.sn_effective_tax_ids.filtered( | ||
lambda t: t.simplified_tax_id.id == simplified_id.id | ||
) | ||
if not effective_tax: | ||
record.sn_effective_tax_ids.create( | ||
{ | ||
"simplified_tax_id": simplified_id.id, | ||
"company_id": record.id, | ||
} | ||
) | ||
|
||
def write(self, vals): | ||
result = super().write(vals) | ||
if "tax_framework" in vals: | ||
if vals["tax_framework"] == TAX_FRAMEWORK_SIMPLES: | ||
self.update_effective_tax_lines() | ||
else: | ||
self.sn_effective_tax_ids = [(5, 0, 0)] | ||
return result |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
O campo icmssn_range não deveria ser eliminado pois deveria ser usado no calculo dos impostos
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
com a alteração dessa pr o uso deste campo dentro do calculo do imposto perde o sentido, pois com a pr já temos todos os impostos do simples nacional previamente calculados dentro das tabelas effective_tax, dentro desse modelo já é marcado qual é o range atual da empresa, na hora de calcular os impostos é só puxar desse modelo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mas você precisa calcular o valor do percentual de crédito do ICMS para ser destacado no documento fiscal, isso deveria ser encapsulado no l10n_br_fiscal.tax
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tá tudo encapsulado no modelo effective_tax do simples nacional, que já é calculado no momento que informa a receita bruta dos 12 meses, isso facilita um contador revisar as informações. mas essas informações podem ser usadas pelo 10n_br_fiscal.tax.