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 Jan 13, 2025
1 parent 707eafd commit 1861cd5
Show file tree
Hide file tree
Showing 10 changed files with 215 additions and 25 deletions.
57 changes: 33 additions & 24 deletions l10n_br_account_withholding/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ Automatize a conformidade fiscal, reduza erros de entrada manual e
aprimore seus processos financeiros relacionados à retenção de impostos
de fornecedores.

- **Automatize a Conformidade Fiscal:** Crie contas a pagar para
impostos retidos em compras de fornecedores automaticamente.
- **Reduza Erros:** Minimize erros manuais e assegure a precisão nas
retenções de impostos.
- **Aprimore a Eficiência:** Melhore seus processos financeiros para
lidar com retenções de impostos de fornecedores.
- **Automatize a Conformidade Fiscal:** Crie contas a pagar para
impostos retidos em compras de fornecedores automaticamente.
- **Reduza Erros:** Minimize erros manuais e assegure a precisão nas
retenções de impostos.
- **Aprimore a Eficiência:** Melhore seus processos financeiros para
lidar com retenções de impostos de fornecedores.

Installation
============
Expand All @@ -60,32 +60,32 @@ Odoo:

1. **Adicione o Repositório:**

- Adicione o repositório ``l10n-brazil`` da OCA no seu projeto
adicionando a URL: ``https://github.com/OCA/l10n-brazil``.
- Verifique os arquivos requirements.txt e oca_dependencies.txt
localizados na raiz do repositório ``l10n-brazil``. Estes arquivos
contêm, respectivamente, as dependências Python necessárias para o
Odoo e os repositórios da OCA dos quais os módulos da localização
brasileira dependem.
- Adicione o repositório ``l10n-brazil`` da OCA no seu projeto
adicionando a URL: ``https://github.com/OCA/l10n-brazil``.
- Verifique os arquivos requirements.txt e oca_dependencies.txt
localizados na raiz do repositório ``l10n-brazil``. Estes arquivos
contêm, respectivamente, as dependências Python necessárias para o
Odoo e os repositórios da OCA dos quais os módulos da localização
brasileira dependem.

2. **Configure o Caminho dos Addons:**

- Adicione o caminho do repositório na configuração do Odoo em
``addons-path``.
- Adicione o caminho do repositório na configuração do Odoo em
``addons-path``.

3. **Atualize a Lista de Módulos:**

- Atualize sua lista de módulos para que o Odoo reconheça o novo
módulo.
- Atualize sua lista de módulos para que o Odoo reconheça o novo
módulo.

4. **Busque pelo Módulo:**

- Pesquise por ``"L10n Br Account Withholding"`` nos addons do Odoo
para localizar o módulo.
- Pesquise por ``"L10n Br Account Withholding"`` nos addons do Odoo
para localizar o módulo.

5. **Instale o Módulo:**

- Prossiga com a instalação do módulo no ambiente Odoo.
- Prossiga com a instalação do módulo no ambiente Odoo.

Configuration
=============
Expand All @@ -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 All @@ -137,13 +146,13 @@ Authors
Contributors
------------

- ``Escodoo <https://www.escodoo.com.br>``\ \_:
- ``Escodoo <https://www.escodoo.com.br>``\ \_:

- Marcel Savegnago [email protected]
- Marcel Savegnago [email protected]

- ``Akretion <https://www.akretion.com.br>``\ \_:
- ``Akretion <https://www.akretion.com.br>``\ \_:

- Renato Lima [email protected]
- Renato Lima [email protected]

Maintainers
-----------
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 @@ -77,8 +77,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 = (

Check warning on line 82 in l10n_br_account_withholding/models/account_move.py

View check run for this annotation

Codecov / codecov/patch

l10n_br_account_withholding/models/account_move.py#L82

Added line #L82 was not covered by tests
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(

Check warning on line 87 in l10n_br_account_withholding/models/account_move.py

View check run for this annotation

Codecov / codecov/patch

l10n_br_account_withholding/models/account_move.py#L87

Added line #L87 was not covered by tests
[("city_id", "=", city_id.id), ("wh_cityhall", "=", True)], limit=1
)
partner_id = partner_wh if partner_wh else fiscal_group.partner_id

Check warning on line 90 in l10n_br_account_withholding/models/account_move.py

View check run for this annotation

Codecov / codecov/patch

l10n_br_account_withholding/models/account_move.py#L90

Added line #L90 was not covered by tests
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.
7 changes: 7 additions & 0 deletions l10n_br_account_withholding/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -453,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 @@ -464,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
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='other_infos']" position="inside">
<field name="wh_cityhall" />
</xpath>
</field>
</record>

</odoo>

0 comments on commit 1861cd5

Please sign in to comment.