Skip to content

Commit

Permalink
[IMP] l10n_br_account_withholding: handling of partner_id assignment
Browse files Browse the repository at this point in the history
  • Loading branch information
kaynnan committed Aug 28, 2024
1 parent 98b946e commit eb837c6
Show file tree
Hide file tree
Showing 10 changed files with 198 additions and 5 deletions.
9 changes: 9 additions & 0 deletions l10n_br_account_withholding/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ estes passos:
se necessário. Se um diário não for especificado, o módulo usará o
diário da fatura de compra original.

3. **Definir uma Prefeitura para o ISSQN:** Crie ou edite um parceiro,
vá até a aba "Fiscal" e marque a opção "É Prefeitura".

Usage
=====

Expand All @@ -115,6 +118,12 @@ impostos no Odoo:
2. **Confirmação da Fatura:** Ao confirmar a fatura de compra, o módulo
gera automaticamente as faturas de retenção de impostos.

3. **Definir uma Prefeitura para o ISSQN:** Ao incluir um imposto de
retenção e informar a cidade correspondente para o ISSQN, o módulo
busca automaticamente o parceiro marcado como Prefeitura para essa
cidade. Caso não o encontre, ele retorna o parceiro padrão definido
no Grupo de Impostos.

Bug Tracker
===========

Expand Down
1 change: 1 addition & 0 deletions l10n_br_account_withholding/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"l10n_br_account",
],
"data": [
"views/res_partner.xml",
"views/l10n_br_fiscal_tax_group.xml",
"views/account_move.xml",
],
Expand Down
1 change: 1 addition & 0 deletions l10n_br_account_withholding/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from . import account_move
from . import l10n_br_fiscal_tax_group
from . import account_move_line
from . import res_partner
16 changes: 15 additions & 1 deletion l10n_br_account_withholding/models/account_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,22 @@ def _prepare_wh_invoice(self, move_line, fiscal_group):
"""
wh_date_invoice = move_line.move_id.date
wh_due_invoice = wh_date_invoice.replace(day=fiscal_group.wh_due_day)

if fiscal_group.tax_scope == "city":
city_id = (
self.invoice_line_ids[0].issqn_fg_city_id
if self.invoice_line_ids[0].issqn_fg_city_id
else self.partner_id.city_id
)
partner_wh = self.env["res.partner"].search(
[("city_id", "=", city_id.id), ("wh_cityhall", "=", True)], limit=1
)
partner_id = partner_wh if partner_wh else fiscal_group.partner_id
else:
partner_id = fiscal_group.partner_id

values = {
"partner_id": fiscal_group.partner_id.id,
"partner_id": partner_id.id,
"date": wh_date_invoice,
"invoice_date": wh_date_invoice,
"invoice_date_due": wh_due_invoice + relativedelta(months=1),
Expand Down
20 changes: 20 additions & 0 deletions l10n_br_account_withholding/models/res_partner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright 2024 - TODAY, Kaynnan Lemes <[email protected]>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import fields, models


class ResPartner(models.Model):

_inherit = "res.partner"

# TODO: Add WH fields for State and Country
wh_cityhall = fields.Boolean(string="Is City Hall?")

_sql_constraints = [
(
"unique_wh_cityhall",
"UNIQUE(city_id, wh_cityhall)",
"Only one partner with the same City Hall can exist in the same city.",
),
]
2 changes: 2 additions & 0 deletions l10n_br_account_withholding/readme/CONFIGURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ Configure a geração de faturas de retenção de impostos no Odoo seguindo este
1. **Acesse Configurações Fiscais:** Vá até `Fiscal -> Configurações -> Grupos de Impostos`. Procure por impostos retidos do tipo entrada.

2. **Configure os Impostos Retidos:** Para cada imposto que requer uma fatura de retenção, garanta que esteja corretamente configurado. Defina um fornecedor e o diário para a geração da fatura do imposto se necessário. Se um diário não for especificado, o módulo usará o diário da fatura de compra original.

3. **Definir uma Prefeitura para o ISSQN:** Crie ou edite um parceiro, vá até a aba "Fiscal" e marque a opção "É Prefeitura".
2 changes: 2 additions & 0 deletions l10n_br_account_withholding/readme/USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ Siga estes passos para utilizar a geração de faturas de retenção de impostos
1. **Criando uma Fatura de Compra:** Ao criar uma fatura de compra, aplique o imposto retido nas linhas necessárias.

2. **Confirmação da Fatura:** Ao confirmar a fatura de compra, o módulo gera automaticamente as faturas de retenção de impostos.

3. **Definir uma Prefeitura para o ISSQN:** Ao incluir um imposto de retenção e informar a cidade correspondente para o ISSQN, o módulo busca automaticamente o parceiro marcado como Prefeitura para essa cidade. Caso não o encontre, ele retorna o parceiro padrão definido no Grupo de Impostos.
18 changes: 14 additions & 4 deletions l10n_br_account_withholding/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@

/*
:Author: David Goodger ([email protected])
:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.

Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.

See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
Expand Down Expand Up @@ -274,7 +275,7 @@
margin-left: 2em ;
margin-right: 2em }

pre.code .ln { color: grey; } /* line numbers */
pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
Expand All @@ -300,7 +301,7 @@
span.pre {
white-space: pre }

span.problematic {
span.problematic, pre.problematic {
color: red }

span.section-subtitle {
Expand Down Expand Up @@ -452,6 +453,8 @@ <h1><a class="toc-backref" href="#toc-entry-3">Configuration</a></h1>
Defina um fornecedor e o diário para a geração da fatura do imposto
se necessário. Se um diário não for especificado, o módulo usará o
diário da fatura de compra original.</li>
<li><strong>Definir uma Prefeitura para o ISSQN:</strong> Crie ou edite um parceiro,
vá até a aba “Fiscal” e marque a opção “É Prefeitura”.</li>
</ol>
</div>
<div class="section" id="usage">
Expand All @@ -463,6 +466,11 @@ <h1><a class="toc-backref" href="#toc-entry-4">Usage</a></h1>
aplique o imposto retido nas linhas necessárias.</li>
<li><strong>Confirmação da Fatura:</strong> Ao confirmar a fatura de compra, o módulo
gera automaticamente as faturas de retenção de impostos.</li>
<li><strong>Definir uma Prefeitura para o ISSQN:</strong> Ao incluir um imposto de
retenção e informar a cidade correspondente para o ISSQN, o módulo
busca automaticamente o parceiro marcado como Prefeitura para essa
cidade. Caso não o encontre, ele retorna o parceiro padrão definido
no Grupo de Impostos.</li>
</ol>
</div>
<div class="section" id="bug-tracker">
Expand Down Expand Up @@ -498,7 +506,9 @@ <h2><a class="toc-backref" href="#toc-entry-8">Contributors</a></h2>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-9">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
</a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
Expand Down
115 changes: 115 additions & 0 deletions l10n_br_account_withholding/tests/test_account_wh_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,3 +310,118 @@ def test_compra_para_revenda(self):
2,
"The invoice should have 2 withholding invoices (PIS and COFINS).",
)

def test_with_partner_issqn_without_city_partner(self):
"Test move with Partner defined and no ISSQN City Partner"
self.env.ref("l10n_br_fiscal.tax_group_pis_wh").generate_wh_invoice = False
self.env.ref("l10n_br_fiscal.tax_group_cofins_wh").generate_wh_invoice = False
product = self.env.ref("l10n_br_sale_commission.service_commission")
product.write(
{
"standard_price": 1000.0,
"tax_icms_or_issqn": "issqn",
"ncm_id": self.env.ref("l10n_br_fiscal.ncm_00000000").id,
"fiscal_genre_id": self.env.ref("l10n_br_fiscal.product_genre_00").id,
"fiscal_type": "09",
"taxes_id": False,
}
)
tax_group = self.env.ref("l10n_br_fiscal.tax_group_issqn_wh")
tax_group.generate_wh_invoice = True
tax_group.journal_id = self.company_data["default_journal_purchase"].id
move_issqn = self.init_invoice(
"in_invoice",
products=[product],
partner=self.env.ref("l10n_br_base.res_partner_amd"),
document_type=self.env.ref("l10n_br_fiscal.document_55"),
fiscal_operation=self.env.ref("l10n_br_fiscal.fo_compras"),
fiscal_operation_lines=[self.env.ref("l10n_br_fiscal.fo_compras_servico")],
document_serie="1",
document_number="56",
)

for line_ids in move_issqn.invoice_line_ids:
line_ids.issqn_tax_id = None
line_ids.issqn_fg_city_id = self.env.ref("l10n_br_base.city_3550308")
line_ids.issqn_wh_tax_id = (
self.env["l10n_br_fiscal.tax"]
.search([("name", "=", "ISSQN RET 5%")], order="id DESC", limit=1)
.id
)

move_issqn.action_post()
move_issqn._compute_wh_invoice_ids()

partner_wh = self.env["res.partner"].search(
[
("city_id", "=", move_issqn.invoice_line_ids[0].issqn_fg_city_id.id),
("wh_cityhall", "=", True),
],
limit=1,
)

expected_partner_id = partner_wh if partner_wh else tax_group.partner_id

self.assertTrue(
all(
wh_inv.partner_id == expected_partner_id
for wh_inv in move_issqn.wh_invoice_ids
)
)

def test_with_partner_issqn_with_city_partner(self):
"Test move with Partner and ISSQN City Partner"
self.env.ref("l10n_br_fiscal.tax_group_pis_wh").generate_wh_invoice = False
self.env.ref("l10n_br_fiscal.tax_group_cofins_wh").generate_wh_invoice = False
product = self.env.ref("l10n_br_sale_commission.service_commission")
product.write(
{
"standard_price": 1000.0,
"tax_icms_or_issqn": "issqn",
"ncm_id": self.env.ref("l10n_br_fiscal.ncm_00000000").id,
"fiscal_genre_id": self.env.ref("l10n_br_fiscal.product_genre_00").id,
"fiscal_type": "09",
"taxes_id": False,
}
)
tax_group = self.env.ref("l10n_br_fiscal.tax_group_issqn_wh")
tax_group.generate_wh_invoice = True
tax_group.journal_id = self.company_data["default_journal_purchase"].id
partner_cityhall = self.env["res.partner"].create(
{
"name": "Prefeitura de São Paulo",
"city_id": self.env.ref("l10n_br_base.city_3550308").id,
"state_id": self.env.ref("base.state_br_sp").id,
"country_id": self.env.ref("base.br").id,
"wh_cityhall": True,
}
)
move_issqn = self.init_invoice(
"in_invoice",
products=[product],
partner=partner_cityhall,
document_type=self.env.ref("l10n_br_fiscal.document_55"),
fiscal_operation=self.env.ref("l10n_br_fiscal.fo_compras"),
fiscal_operation_lines=[self.env.ref("l10n_br_fiscal.fo_compras_servico")],
document_serie="1",
document_number="56",
)

for line_ids in move_issqn.invoice_line_ids:
line_ids.issqn_tax_id = None
line_ids.issqn_fg_city_id = self.env.ref("l10n_br_base.city_3550308")
line_ids.issqn_wh_tax_id = (
self.env["l10n_br_fiscal.tax"]
.search([("name", "=", "ISSQN RET 5%")], order="id DESC", limit=1)
.id
)

move_issqn.action_post()
move_issqn._compute_wh_invoice_ids()

self.assertTrue(
all(
wh_inv.partner_id == partner_cityhall.id
for wh_inv in move_issqn.wh_invoice_ids
)
)
19 changes: 19 additions & 0 deletions l10n_br_account_withholding/views/res_partner.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2024 - TODAY, Kaynnan Lemes <[email protected]>
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>

<record model="ir.ui.view" id="partner_form_view">
<field
name="name"
>l10n_br_fiscal.partner.form (in l10n_br_account_withholding)</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="l10n_br_base.l10n_br_base_partner_form" />
<field name="arch" type="xml">
<xpath expr="//group[@name='fiscal_profile']" position="inside">
<field name="wh_cityhall" />
</xpath>
</field>
</record>

</odoo>

0 comments on commit eb837c6

Please sign in to comment.