Merge PR #246 into 13.0

Signed-off-by simahawk
This commit is contained in:
OCA-git-bot
2020-02-07 14:59:09 +00:00
22 changed files with 393 additions and 1 deletions

View File

@@ -9,4 +9,4 @@ line_length=88
known_odoo=odoo
known_odoo_addons=odoo.addons
sections=FUTURE,STDLIB,THIRDPARTY,ODOO,ODOO_ADDONS,FIRSTPARTY,LOCALFOLDER
known_third_party=lxml
known_third_party=lxml,setuptools

View File

@@ -0,0 +1 @@
from . import models

View File

@@ -0,0 +1,12 @@
# Copyright 2019 Camptocamp SA
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
"name": "Bank Account Camt54 Import",
"version": "13.0.1.0.0",
"category": "Account",
"website": "https://github.com/OCA/bank-statement-import",
"author": "camptocamp, " "Odoo Community Association (OCA)",
"license": "AGPL-3",
"installable": True,
"depends": ["account_bank_statement_import_camt_oca"],
}

View File

@@ -0,0 +1,2 @@
from . import account_bank_statement_import
from . import parser

View File

@@ -0,0 +1,40 @@
# Copyright 2019 Camptocamp SA
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
import logging
from odoo import models
_logger = logging.getLogger(__name__)
class AccountBankStatementImport(models.TransientModel):
"""Add process_camt method to account.bank.statement.import."""
_inherit = "account.bank.statement.import"
def _create_bank_statements(self, stmts_vals):
""" Set balance_end_real if not already provided by the file."""
statement_line_ids, notifications = super()._create_bank_statements(stmts_vals)
statements = self.env["account.bank.statement"].search(
[("line_ids", "in", statement_line_ids)]
)
for statement in statements:
if not statement.balance_end_real:
amount = sum(statement.line_ids.mapped("amount"))
statement.balance_end_real = statement.balance_start + amount
return statement_line_ids, notifications
def _complete_stmts_vals(self, stmts_vals, journal, account_number):
"""Search partner from partner reference"""
stmts_vals = super()._complete_stmts_vals(stmts_vals, journal, account_number)
for st_vals in stmts_vals:
for line_vals in st_vals["transactions"]:
if "partner_ref" in line_vals:
partner_ref = line_vals.pop("partner_ref")
partner = self.env["res.partner"].search(
[("ref", "=", partner_ref)], limit=1
)
line_vals["partner_id"] = partner.id
return stmts_vals

View File

@@ -0,0 +1,100 @@
# Copyright 2019 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import _, exceptions, models
class CamtParser(models.AbstractModel):
"""Parser for camt bank statement import files."""
_inherit = "account.bank.statement.import.camt.parser"
def _get_partner_ref(self, isr):
ICP = self.env["ir.config_parameter"]
ref_format = ICP.sudo().get_param("isr_partner_ref")
if not ref_format:
return
config = ref_format.split(",")
if len(config) == 2:
start, size = config
elif len(config) == 1:
start = config[0]
size = 6
else:
raise exceptions.UserError(
_(
"Config parameter `isr_partner_ref` is wrong.\n"
"It must be in format `i[,n]` \n"
"where `i` is the position of the first digit and\n"
"`n` the number of digit in the reference,"
" by default 6.\n"
'e.g. "13,6"'
)
)
try:
start = int(start) - 1 # count from 1 instead of 0
size = int(size)
end = start + size
except ValueError:
raise exceptions.UserError(
_(
"Config parameter `isr_partner_ref` is wrong.\n"
"It must be in format `i[,n]` \n"
"`i` and `n` must be integers.\n"
'e.g. "13,6"'
)
)
return isr[start:end].lstrip("0")
def parse_transaction_details(self, ns, node, transaction):
"""Put ESR in label and add aditional information to label
if no esr is available
"""
super().parse_transaction_details(ns, node, transaction)
# put the esr in the label. odoo reconciles based on the label,
# if there is no esr it tries to use the information textfield
isr_number = node.xpath(
"./ns:RmtInf/ns:Strd/ns:CdtrRefInf/ns:Ref", namespaces={"ns": ns}
)
if len(isr_number):
transaction["name"] = isr_number[0].text
partner_ref = self._get_partner_ref(isr_number[0].text)
if partner_ref:
transaction["partner_ref"] = partner_ref
else:
xpath_exprs = [
"./ns:RmtInf/ns:Ustrd|./ns:RtrInf/ns:AddtlInf",
"./ns:AddtlNtryInf",
"/ns:Refs/ns:InstrId",
]
name = transaction["name"]
for xpath_expr in xpath_exprs:
found_node = node.xpath(xpath_expr, namespaces={"ns": ns})
if found_node:
name = found_node[0].text
break
trans_id_node = (
node.getparent()
.getparent()
.xpath("./ns:AcctSvcrRef", namespaces={"ns": ns})
)
if trans_id_node:
name = "{} ({})".format(name, trans_id_node[0].text)
if name:
transaction["name"] = name
# End add esr to the label.
# add transaction id to ref
self.add_value_from_node(
ns,
node,
[
"./../../ns:AcctSvcrRef",
"./ns:RmtInf/ns:Strd/ns:CdtrRefInf/ns:Ref",
"./ns:Refs/ns:EndToEndId",
],
transaction,
"ref",
)
return True

View File

@@ -0,0 +1,2 @@
* Yannick Vaucher <yannick.vaucher@camptocamp.com>
* Timon Tschanz <timon.tschanz@camptocamp.com>

View File

@@ -0,0 +1,14 @@
This module allows you to import CAMT.054 file (details of customers payments batch) into a dedicated journal taking care of the start/end balance and the remittance reference number.
Customer invoices will be reconciled/Paid. Payment entries will be posted into an internal transfer account (that you have to create with a type current asset and set on the journal)
After this first step, import normally your CAMT.053 (full bank statement) into the bank journal. You will be able to clear the internal transfer account to end up the accounting flow.
For ISR containing a partner reference, uses the config parameter key `isr_partner_ref`.
Doing so will fill the partners on bank statement lines and speed up the matches in the reconciliation process.
Value to set in `isr_partner_ref` defines the position of the partner reference inside the ISR.
The format is `i[,n]`
For instance `13,6` to start on position 13 with a 6 digit long reference.
`n` is optional and it's default value is `6`.

View File

@@ -0,0 +1 @@
from . import test_get_partner_ref

View File

@@ -0,0 +1,65 @@
# Copyright 2019 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo.exceptions import UserError
from odoo.tests import common
class TestGetPartnerRef(common.TransactionCase):
def setUp(self):
super().setUp()
self.Parser = self.env["account.bank.statement.import.camt.parser"]
self.ICP = self.env["ir.config_parameter"]
def test_no_ICP(self):
"""Test no partner ref is read if param is not set"""
ref = "11 11111 11111 11111 11111 11111".replace(" ", "")
partner_ref = self.Parser._get_partner_ref(ref)
self.assertFalse(partner_ref)
def test_ICP_empty(self):
self.ICP.set_param("isr_partner_ref", "")
ref = "11 11111 11111 11111 11111 11111".replace(" ", "")
partner_ref = self.Parser._get_partner_ref(ref)
self.assertFalse(partner_ref)
def test_ICP_no_len(self):
"""Test a default len of 6 is set if not provided"""
self.ICP.set_param("isr_partner_ref", "12")
ref = "11 11111 11112 34567 11111 11111".replace(" ", "")
partner_ref = self.Parser._get_partner_ref(ref)
self.assertEquals(partner_ref, "234567")
def test_ICP_full(self):
"""Test full format of partner ref definition"""
self.ICP.set_param("isr_partner_ref", "12,6")
ref = "11 11111 11112 34567 11111 11111".replace(" ", "")
partner_ref = self.Parser._get_partner_ref(ref)
self.assertEquals(partner_ref, "234567")
def test_zero_stripped(self):
"""Test full format of partner ref definition"""
self.ICP.set_param("isr_partner_ref", "12,6")
ref = "11 11111 11110 00560 11111 11111".replace(" ", "")
partner_ref = self.Parser._get_partner_ref(ref)
self.assertEquals(partner_ref, "560")
def test_bad_ICP(self):
"""Test ir config parameter validation"""
self.ICP.set_param("isr_partner_ref", "")
ref = "11 11111 11111 11111 11111 11111".replace(" ", "")
self.ICP.set_param("isr_partner_ref", "A")
with self.assertRaises(UserError):
self.Parser._get_partner_ref(ref)
self.ICP.set_param("isr_partner_ref", "A,B")
with self.assertRaises(UserError):
self.Parser._get_partner_ref(ref)
self.ICP.set_param("isr_partner_ref", "1,X")
with self.assertRaises(UserError):
self.Parser._get_partner_ref(ref)
self.ICP.set_param("isr_partner_ref", "A,8")
with self.assertRaises(UserError):
self.Parser._get_partner_ref(ref)

View File

@@ -0,0 +1 @@
from . import models

View File

@@ -0,0 +1,13 @@
# Copyright 2020 Camptocamp SA
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
"name": "Bank Account Transfer Line",
"version": "13.0.1.0.0",
"category": "Account",
"website": "https://github.com/OCA/bank-statement-import",
"author": "Camptocamp, " "Odoo Community Association (OCA)",
"license": "AGPL-3",
"installable": True,
"depends": ["account_bank_statement_import"],
"data": ["view/account_journal.xml"],
}

View File

@@ -0,0 +1,2 @@
from . import account_bank_statement_import
from . import account_journal

View File

@@ -0,0 +1,36 @@
# Copyright 2020 Camptocamp SA
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import models
class AccountBankStatementImport(models.TransientModel):
_inherit = "account.bank.statement.import"
def _create_bank_statements(self, stmts_vals):
""" Create additional line in statement to set bank statement statement
to 0 balance"""
statement_line_ids, notifications = super()._create_bank_statements(stmts_vals)
statements = self.env["account.bank.statement"].search(
[("line_ids", "in", statement_line_ids)]
)
for statement in statements:
amount = sum(statement.line_ids.mapped("amount"))
if statement.journal_id.transfer_line:
if amount != 0:
amount = -amount
line = statement.line_ids.create(
{
"name": statement.name,
"amount": amount,
"statement_id": statement.id,
"date": statement.date,
}
)
statement_line_ids.append(line.id)
statement.balance_end_real = statement.balance_start
else:
statement.balance_end_real = statement.balance_start + amount
return statement_line_ids, notifications

View File

@@ -0,0 +1,14 @@
# Copyright 2020 Camptocamp SA
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import fields, models
class AccountBankStatementImport(models.Model):
_inherit = "account.journal"
transfer_line = fields.Boolean(
string="Add balance Line",
help="Generate balance line on total of bank statemen import",
)

View File

@@ -0,0 +1 @@
* Iryna Vyshnevska <i.vyshnevska@mobilunity.com>

View File

@@ -0,0 +1,3 @@
This module allows you to add generation of additional line in bank statement.
To enable this option you need properly set flag on Account Journal
Configuration -> Journals -> tab Advanced Settings -> Bank statement configuration

View File

@@ -0,0 +1 @@
from . import test_statement

View File

@@ -0,0 +1,67 @@
# Copyright 2020 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import base64
from odoo.modules.module import get_module_resource
from odoo.tests.common import SavepointCase
class TestGenerateBankStatement(SavepointCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
bank = cls.env["res.partner.bank"].create(
{
"acc_number": "NL77ABNA0574908765",
"partner_id": cls.env.ref("base.main_partner").id,
"company_id": cls.env.ref("base.main_company").id,
"bank_id": cls.env.ref("base.res_bank_1").id,
}
)
cls.env["res.partner.bank"].create(
{
"acc_number": "NL46ABNA0499998748",
"partner_id": cls.env.ref("base.main_partner").id,
"company_id": cls.env.ref("base.main_company").id,
"bank_id": cls.env.ref("base.res_bank_1").id,
}
)
cls.journal = cls.env["account.journal"].create(
{
"name": "Bank Journal - (test camt)",
"code": "TBNKCAMT",
"type": "bank",
"bank_account_id": bank.id,
}
)
def _load_statement(self):
testfile = get_module_resource(
"account_bank_statement_import_camt_oca", "test_files", "test-camt053"
)
with open(testfile, "rb") as datafile:
camt_file = base64.b64encode(datafile.read())
self.env["account.bank.statement.import"].create(
{"attachment_ids": [(0, 0, {"name": "test file", "datas": camt_file})]}
).import_file()
bank_st_record = self.env["account.bank.statement"].search(
[("name", "=", "1234Test/1")], limit=1
)
statement_lines = bank_st_record.line_ids
return statement_lines
def test_statement_import(self):
self.journal.transfer_line = True
lines = self._load_statement()
self.assertEqual(len(lines), 5)
self.assertAlmostEqual(sum(lines.mapped("amount")), 0)
self.journal.transfer_line = False
lines = self._load_statement()
self.assertEqual(len(lines), 4)
self.assertAlmostEqual(sum(lines.mapped("amount")), -12.99)

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_account_journal_form" model="ir.ui.view">
<field name="model">account.journal</field>
<field name="name">account.journal.form</field>
<field name="inherit_id" ref="account.view_account_journal_form"/>
<field name="arch" type="xml">
<xpath expr="//page[@name='advanced_settings']/group" position="inside">
<group string="Bank statement configuration" groups="account.group_account_manager">
<field name="transfer_line"/>
</group>
</xpath>
</field>
</record>
</odoo>