Skip to content

Commit

Permalink
[IMP] l10n_br_cnab_structure: add more unittest
Browse files Browse the repository at this point in the history
  • Loading branch information
antoniospneto committed Jan 21, 2023
1 parent 8394c59 commit b068505
Show file tree
Hide file tree
Showing 5 changed files with 253 additions and 27 deletions.
5 changes: 5 additions & 0 deletions l10n_br_cnab_structure/models/cnab_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,11 @@ def check_line(self):

cnab_fields = self.field_ids.sorted(key=lambda r: r.start_pos)

if len(cnab_fields) == 0:
raise UserError(
_(f"{self.name}: The cnab line must have some cnab field defined.")
)

for f in cnab_fields:
f.check_field()

Expand Down
2 changes: 1 addition & 1 deletion l10n_br_cnab_structure/models/l10n_br_cnab_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ def create_liq_move(self):
self._create_discount_move_lines(move_id)
self._create_fees_move_lines(move_id)
self._create_tariff_move_lines(move_id)
move_id.post()
move_id.action_post()
self.generated_move_id = move_id
for to_reconcile in to_reconcile_items:
to_reconcile.reconcile()
Expand Down
259 changes: 240 additions & 19 deletions l10n_br_cnab_structure/tests/test_cnab_structure.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import base64

from odoo import fields
from odoo.tests import Form
from odoo.tests.common import tagged

from odoo.addons.account.tests.common import AccountTestInvoicingCommon
Expand All @@ -19,7 +20,9 @@ def replace_chars(string, index, replacement):
@tagged("post_install", "-at_install")
class TestCNABStructure(AccountTestInvoicingCommon):
@classmethod
def setUpClass(cls, chart_template_ref=None):
def setUpClass(
cls, chart_template_ref="l10n_br_coa_generic.l10n_br_coa_generic_template"
):
super().setUpClass(chart_template_ref=chart_template_ref)
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
cls.company = cls.company_data["company"]
Expand All @@ -30,11 +33,15 @@ def setUpClass(cls, chart_template_ref=None):
cls.payment_order_model = cls.env["account.payment.order"]
cls.payment_line_model = cls.env["account.payment.line"]
cls.attachment_model = cls.env["ir.attachment"]
cls.account_payment_method_model = cls.env["account.payment.method"]
cls.res_partner_pix_model = cls.env["res.partner.pix"]
cls.bank_341 = cls.env.ref("l10n_br_base.res_bank_341")
cls.import_wizard_obj = cls.env["cnab.import.wizard"]
cls.cnab_log_obj = cls.env["l10n_br_cnab.return.log"]
cls.partner_a.update({"cnpj_cpf": "45823449000198"})
cls.cnab_structure_itau_240 = cls.env.ref(
"l10n_br_cnab_structure.cnab_itau_240"
)
cls.res_partner_pix_model.create(
{
"partner_id": cls.partner_a.id,
Expand Down Expand Up @@ -73,9 +80,7 @@ def setUpClass(cls, chart_template_ref=None):
"payment_order_ok": True,
"fixed_journal_id": cls.bank_journal_itau.id,
"cnab_processor": "oca_processor",
"cnab_structure_id": cls.env.ref(
"l10n_br_cnab_structure.cnab_itau_240"
).id,
"cnab_structure_id": cls.cnab_structure_itau_240.id,
"cnab_payment_way_ids": [
(
6,
Expand Down Expand Up @@ -120,37 +125,253 @@ def setUpClass(cls, chart_template_ref=None):
cls.payment_order_model.search(cls.domain).unlink()

def test_file_generete_and_return(self):
# Open invoice
self.invoice.action_post()
# Add to payment order using the wizard
self.env["account.invoice.payment.line.multi"].with_context(
active_model="account.move", active_ids=self.invoice.ids
).create({}).run()
payment_order = self.env["account.payment.order"].search(self.domain)
self.assertEqual(len(payment_order), 1)
payment_order_id = self._create_and_get_payment_order()
self.assertEqual(len(payment_order_id), 1)
# Open payment order
payment_order.draft2open()
action = payment_order.open2generated()
payment_order_id.draft2open()
action = payment_order_id.open2generated()
delivery_cnab_file = self.attachment_model.browse(action["res_id"])
self.assertIsNotNone(delivery_cnab_file)

# Transform the send file (remessa) into a return file (retorno)
cnab_data = base64.b64decode(delivery_cnab_file.datas).decode()
lines = cnab_data.splitlines()
# payment effective date
lines[2] = replace_chars(lines[2], 154, "10112022")
# actual payment amount
lines[2] = replace_chars(lines[2], 172, "300")
# occurrence
lines[2] = replace_chars(lines[2], 230, "00")

return_data = "\r\n".join(lines).encode()

self.wizard = self.import_wizard_obj.create(
import_wizard = self.import_wizard_obj.create(
{
"journal_id": self.bank_journal_itau.id,
"return_file": base64.b64encode(return_data),
"filename": "TEST.RET",
"type": "outbound",
"cnab_structure_id": self.env.ref(
"l10n_br_cnab_structure.cnab_itau_240"
).id,
"cnab_structure_id": self.cnab_structure_itau_240.id,
}
)
action = self.wizard.import_cnab()
action = import_wizard.with_context(default_type="outbound").import_cnab()
cnab_log = self.cnab_log_obj.browse(action["res_id"])

self.assertIsNotNone(cnab_log)
self.assertFalse(cnab_log.event_ids.mapped("generated_move_id"))

cnab_log.action_confirm_return_log()

self.assertTrue(cnab_log.event_ids.mapped("generated_move_id"))

def test_cnab_yaml_output(self):
payment_order_id = self._create_and_get_payment_order()
preview_wizard_obj = self.env["cnab.preview.wizard"]
preview_wizard = preview_wizard_obj.create(
{
"payment_order_id": payment_order_id.id,
"cnab_structure_id": self.cnab_structure_itau_240.id,
}
)
self.assertIsNotNone(preview_wizard.output_yaml)
self.assertIn(
" 103_132_nome_do_banco: 'BANCO ITAU '\n",
preview_wizard.output_yaml,
)

def _create_and_get_payment_order(self):
# Open invoice
self.invoice.action_post()
# Add to payment order using the wizard
self.env["account.invoice.payment.line.multi"].with_context(
active_model="account.move", active_ids=self.invoice.ids
).create({}).run()
payment_order_id = self.env["account.payment.order"].search(self.domain)
return payment_order_id

def _create_valid_cnab_structure(self):
cnab_structure_form = Form(self.env["l10n_br_cnab.structure"])
cnab_structure_form.payment_method_id = self.env.ref(
"l10n_br_account_payment_order.payment_mode_type_cnab240_out"
)
cnab_structure_form.name = "Test CNAB Structure"
cnab_structure_form.bank_id = self.bank_341
# FILE HEADER
with cnab_structure_form.line_ids.new() as line_form:
line_form.type = "header"
line_form.communication_flow = "both"
with line_form.field_ids.new() as field_form:
field_form.start_pos = 1
field_form.end_pos = 240
# BATCH
with cnab_structure_form.batch_ids.new() as batch_form:
batch_form.name = "Test Batch 1"
cnab_structure = cnab_structure_form.save()

# BATCH HEADER
line_form = Form(self.env["l10n_br_cnab.line"])
line_form.cnab_structure_id = cnab_structure
line_form.batch_id = cnab_structure.batch_ids[0]
line_form.type = "header"
line_form.communication_flow = "both"
with line_form.field_ids.new() as field_form:
field_form.start_pos = 1
field_form.end_pos = 240
line_form.save()

# BATCH SEGMENT
line_form = Form(self.env["l10n_br_cnab.line"])
line_form.cnab_structure_id = cnab_structure
line_form.batch_id = cnab_structure.batch_ids[0]
line_form.type = "segment"
line_form.segment_code = "X"
line_form.communication_flow = "both"
with line_form.field_ids.new() as field_form:
field_form.start_pos = 1
field_form.end_pos = 240
line_form.save()

# BATCH TRAILER
line_form = Form(self.env["l10n_br_cnab.line"])
line_form.cnab_structure_id = cnab_structure
line_form.batch_id = cnab_structure.batch_ids[0]
line_form.type = "trailer"
line_form.communication_flow = "both"
with line_form.field_ids.new() as field_form:
field_form.start_pos = 1
field_form.end_pos = 240
line_form.save()

# FILE TRAILER
line_form = Form(self.env["l10n_br_cnab.line"])
line_form.cnab_structure_id = cnab_structure
line_form.type = "trailer"
line_form.communication_flow = "both"
with line_form.field_ids.new() as field_form:
field_form.start_pos = 1
field_form.end_pos = 240
line_form.save()
return cnab_structure

def test_cnab_structure_240_outbound(self):
cnab_structure_form = Form(self.env["l10n_br_cnab.structure"])
cnab_structure_form.payment_method_id = self.env.ref(
"l10n_br_account_payment_order.payment_mode_type_cnab240_out"
)
cnab_structure = cnab_structure_form.save()
self.assertTrue(cnab_structure)
self.assertEqual(cnab_structure.conf_bank_start_pos, 1)
self.assertEqual(cnab_structure.conf_bank_end_pos, 3)
self.assertEqual(cnab_structure.conf_record_type_start_pos, 8)
self.assertEqual(cnab_structure.conf_record_type_end_pos, 8)
self.assertEqual(cnab_structure.conf_batch_start_pos, 4)
self.assertEqual(cnab_structure.conf_bank_start_pos, 1)
self.assertEqual(cnab_structure.conf_batch_end_pos, 7)
self.assertEqual(cnab_structure.conf_payment_way_start_pos, 12)
self.assertEqual(cnab_structure.conf_payment_way_end_pos, 13)
self.assertEqual(cnab_structure.record_type_file_header_id, 0)
self.assertEqual(cnab_structure.record_type_file_trailer_id, 9)
self.assertEqual(cnab_structure.record_type_batch_header_id, 1)
self.assertEqual(cnab_structure.record_type_batch_trailer_id, 5)
self.assertEqual(cnab_structure.record_type_detail_id, 3)

def test_cnab_structure_240_inbound(self):
# Please note: support for CNAB 240 inbound is not fully implemented.
cnab_structure_form = Form(self.env["l10n_br_cnab.structure"])
cnab_structure_form.payment_method_id = self.env.ref(
"l10n_br_account_payment_order.payment_mode_type_cnab240"
)
cnab_structure = cnab_structure_form.save()
self.assertTrue(cnab_structure)
self.assertEqual(cnab_structure.conf_bank_start_pos, 1)
self.assertEqual(cnab_structure.conf_bank_end_pos, 3)
self.assertEqual(cnab_structure.conf_record_type_start_pos, 8)
self.assertEqual(cnab_structure.conf_record_type_end_pos, 8)
self.assertEqual(cnab_structure.conf_batch_start_pos, 4)
self.assertEqual(cnab_structure.conf_bank_start_pos, 1)
self.assertEqual(cnab_structure.conf_batch_end_pos, 7)
self.assertEqual(cnab_structure.conf_payment_way_start_pos, 0)
self.assertEqual(cnab_structure.conf_payment_way_end_pos, 0)
self.assertEqual(cnab_structure.record_type_file_header_id, 0)
self.assertEqual(cnab_structure.record_type_file_trailer_id, 9)
self.assertEqual(cnab_structure.record_type_batch_header_id, 1)
self.assertEqual(cnab_structure.record_type_batch_trailer_id, 5)
self.assertEqual(cnab_structure.record_type_detail_id, 3)

def test_cnab_structure_400_inbound(self):
# Please note: support for CNAB 400 is not fully implemented.
cnab_structure_form = Form(self.env["l10n_br_cnab.structure"])
cnab_structure_form.payment_method_id = self.env.ref(
"l10n_br_account_payment_order.payment_mode_type_cnab400"
)
cnab_structure = cnab_structure_form.save()
self.assertTrue(cnab_structure)
self.assertEqual(cnab_structure.conf_record_type_start_pos, 8)
self.assertEqual(cnab_structure.conf_record_type_end_pos, 8)
self.assertEqual(cnab_structure.record_type_file_trailer_id, 9)
self.assertEqual(cnab_structure.record_type_detail_id, 1)

def test_cnab_structure_500_inbound(self):
# Please note: support for CNAB 500 is not fully implemented.
cnab_structure_form = Form(self.env["l10n_br_cnab.structure"])
cnab_structure_form.payment_method_id = self.env.ref(
"l10n_br_account_payment_order.payment_mode_type_cnab500"
)
cnab_structure = cnab_structure_form.save()
self.assertEqual(cnab_structure.conf_record_type_start_pos, 0)

def test_cnab_structure_states(self):
cnab_structure = self._create_valid_cnab_structure()
self.assertEqual(cnab_structure.state, "draft")
cnab_structure.action_review()
self.assertEqual(cnab_structure.state, "review")
cnab_structure.action_approve()
self.assertEqual(cnab_structure.state, "approved")
cnab_structure.action_draft()
self.assertEqual(cnab_structure.state, "draft")

def test_field_select_wizard(self):

cnab_field_id = self._create_valid_cnab_structure().line_ids[0].field_ids[0]
wiz_action = cnab_field_id.action_change_field_sending()

self.assertEqual(wiz_action["res_model"], "field.select.wizard")
self.assertEqual(wiz_action["target"], "new")
self.assertEqual(wiz_action["type"], "ir.actions.act_window")
self.assertEqual(wiz_action["view_mode"], "form")
self.assertEqual(wiz_action["view_type"], "form")

field_select_wizard = (
self.env[wiz_action["res_model"]]
.with_context(wiz_action["context"])
.create({})
)

def find_field(name):
model = field_select_wizard.parent_model_id
field = self.env["ir.model.fields"].search(
[("model_id", "=", model.id), ("name", "=", name)]
)
return field

# select and confirm new field in wizard
self.assertFalse(field_select_wizard.notation_field)
field_select_wizard.new_field_id = find_field("company_partner_bank_id")
field_select_wizard._update_dot_notation()
self.assertEqual(field_select_wizard.notation_field, "company_partner_bank_id")

# select and confirm new sub-field in wizard
field_select_wizard.new_field_id = find_field("bank_id")
field_select_wizard._update_dot_notation()
self.assertEqual(
field_select_wizard.notation_field, "company_partner_bank_id.bank_id"
)

# remove sub-field in wizard
field_select_wizard.action_remove_last_field()
self.assertEqual(field_select_wizard.notation_field, "company_partner_bank_id")

# confirm wizard
self.assertFalse(cnab_field_id.content_source_field)
field_select_wizard.action_confirm()
self.assertEqual(cnab_field_id.content_source_field, "company_partner_bank_id")
11 changes: 5 additions & 6 deletions l10n_br_cnab_structure/wizard/cnab_preview_wizard.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,17 @@ def _selection_target_model(self):

output = fields.Text(string="CNAB Text Output")

output_yaml = fields.Text(string="CNAB YAML Output")
output_yaml = fields.Text(
string="CNAB YAML Output",
compute="_compute_cnab_txt",
)

cnab_file = fields.Binary(
string="CNAB File",
)

cnab_file_name = fields.Char(compute="_compute_cnab_file_name")

@api.onchange("payment_order_id")
def _onchange_payment_order_id(self):
self._compute_cnab_txt()

def _compute_cnab_file_name(self):
for rec in self:
file_name = f"CNAB_TEST_{rec.payment_order_id.name}.REM"
Expand All @@ -49,7 +48,7 @@ def _compute_cnab_file_name(self):
@api.depends("cnab_structure_id", "payment_order_id")
def _compute_cnab_txt(self):
txt = yaml = ""
if self.payment_order_id:
if self.cnab_structure_id and self.payment_order_id:
txt = self.cnab_structure_id.output(self.payment_order_id)
yaml = self.cnab_structure_id.output_yaml(self.payment_order_id)
self.output = txt
Expand Down
3 changes: 2 additions & 1 deletion l10n_br_cnab_structure/wizard/field_select_wizard.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class FieldSelectWizard(models.TransientModel):
compute="_compute_parent_model_id",
)

@api.depends("model_id")
@api.depends("model_id", "notation_field")
def _compute_parent_model_id(self):
model = self.model_id
if self.notation_field:
Expand Down Expand Up @@ -90,6 +90,7 @@ def action_remove_last_field(self):
},
}

@api.depends("notation_field")
def _compute_notation_field_view(self):
self.notation_field_view = self.notation_field.replace(".", "→")

Expand Down

0 comments on commit b068505

Please sign in to comment.