[MIG] account_bank_statement_import to v14 > account_statement_import

Module renamed to account_statement_import to avoid conflit with Odoo enterprise
Add support for multi-account statement files
Integrate the feature provided by the module account_bank_statement_import_save_file
Improve error messages
Remove dead or annoying features
Improve code !
This commit is contained in:
Alexis de Lattre
2020-11-18 00:22:27 +01:00
committed by Pedro M. Baeza
parent d126f8192a
commit f752e3bc17
30 changed files with 1280 additions and 1558 deletions

View File

@@ -0,0 +1,101 @@
======================
Import Statement Files
======================
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
:alt: License: LGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fbank--statement--import-lightgray.png?logo=github
:target: https://github.com/OCA/bank-statement-import/tree/14.0/account_statement_import
:alt: OCA/bank-statement-import
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/bank-statement-import-14-0/bank-statement-import-14-0-account_statement_import
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/174/14.0
:alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5|
This module is the successor of the module **account_bank_statement_import** that was part of Odoo Community until Odoo v13 and was moved to Odoo Enterprise for Odoo v14 (cf `this commit <https://github.com/odoo/odoo/commit/9ba8734f15e1a292ca27b1a026e8366a91b2a8c9>`_). We decided to change its name and the name of the wizard object it provides in order to avoid a conflict with the Enterprise module.
This module has several additionnal feature:
* support multi-account bank statement files,
* attach the file to the bank statement (to facilitate the diagnostic in case of problem),
* improved error messages.
This module only provides the technical framework for the import of statement files. You must also install the format-specific modules to add support for the statement file formats that your banks/provide use. For example, the OCA module **account_statement_import_ofx** will add support for the OFX (Open Financial Exchange) file format. You will find those modules in the OCA project `bank-statement-import <https://github.com/OCA/bank-statement-import>`_ or, for the country-specific formats, in the OCA localization projects.
**Table of contents**
.. contents::
:local:
Usage
=====
To import a statement file, go to the Invoicing dashboard: on a bank journal, you will see a button to import a statement. When you click on that button, a wizard will start and it will show the list of the supported file formats. Select the statement file that you want to import and click on the **Import** button. Odoo will create a new bank statement (or several if your statement file is a multi-account file).
If your statement file contains transactions that were already imported in Odoo, they will not be created a second time.
If the statement file contains information about the bank account number of the counter-part for some transactions (only a few statement file formats support that, in some countries) and that these bank account numbers exists on partners in Odoo, the partners will be set on the related statement lines.
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/bank-statement-import/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
`feedback <https://github.com/OCA/bank-statement-import/issues/new?body=module:%20account_statement_import%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
~~~~~~~
* Odoo SA
* Akretion
Contributors
~~~~~~~~~~~~
* Odoo S.A.
* Alexis de Lattre <alexis.delattre@akretion.com>
* Tecnativa - Pedro M. Baeza
Maintainers
~~~~~~~~~~~
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
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.
.. |maintainer-alexis-via| image:: https://github.com/alexis-via.png?size=40px
:target: https://github.com/alexis-via
:alt: alexis-via
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
|maintainer-alexis-via|
This module is part of the `OCA/bank-statement-import <https://github.com/OCA/bank-statement-import/tree/14.0/account_statement_import>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

@@ -1,4 +1,2 @@
from . import account_bank_statement_import
from . import account_journal
from . import models
from . import wizard

View File

@@ -1,27 +1,25 @@
# Copyright 2004-2020 Odoo S.A.
# Copyright 2020 Akretion France (http://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# Licence LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0).
{
"name": "Account Bank Statement Import",
"category": "Accounting/Accounting",
"version": "13.0.1.0.0",
"name": "Import Statement Files",
"category": "Accounting",
"version": "14.0.1.0.0",
"license": "LGPL-3",
"depends": ["account"],
"description": """Generic Wizard to Import Bank Statements.
(This module does not include any type of import format.)
OFX and QIF imports are available in Enterprise version.""",
"author": "Odoo SA",
"author": "Odoo SA, Akretion, Odoo Community Association (OCA)",
"maintainers": ["alexis-via"],
"website": "https://github.com/OCA/bank-statement-import",
"data": [
"account_bank_statement_import_view.xml",
"account_import_tip_data.xml",
"wizard/journal_creation.xml",
"views/account_bank_statement_import_templates.xml",
"security/ir.model.access.csv",
"wizard/account_statement_import_view.xml",
"views/account_journal.xml",
"views/account_bank_statement_line.xml",
],
"demo": [
"demo/partner_bank.xml",
],
"installable": True,
"auto_install": True,
}

View File

@@ -1,342 +0,0 @@
# Copyright 2004-2020 Odoo S.A.
# Licence LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0).
import base64
import logging
from odoo import _, api, fields, models
from odoo.exceptions import UserError
from odoo.addons.base.models.res_bank import sanitize_account_number
_logger = logging.getLogger(__name__)
class AccountBankStatementLine(models.Model):
_inherit = "account.bank.statement.line"
# Ensure transactions can be imported only once (if the import format provides unique transaction ids)
unique_import_id = fields.Char(string="Import ID", readonly=True, copy=False)
_sql_constraints = [
(
"unique_import_id",
"unique (unique_import_id)",
"A bank account transactions can be imported only once !",
)
]
class AccountBankStatementImport(models.TransientModel):
_name = "account.bank.statement.import"
_description = "Import Bank Statement"
attachment_ids = fields.Many2many(
"ir.attachment",
string="Files",
required=True,
help="Get you bank statements in electronic format from your bank and select them here.",
)
def import_file(self):
""" Process the file chosen in the wizard, create bank statement(s) and go to reconciliation. """
self.ensure_one()
statement_line_ids_all = []
notifications_all = []
# Let the appropriate implementation module parse the file and return the required data
# The active_id is passed in context in case an implementation module requires information about the wizard state (see QIF)
for data_file in self.attachment_ids:
currency_code, account_number, stmts_vals = self.with_context(
active_id=self.ids[0]
)._parse_file(base64.b64decode(data_file.datas))
# Check raw data
self._check_parsed_data(stmts_vals)
# Try to find the currency and journal in odoo
currency, journal = self._find_additional_data(
currency_code, account_number
)
# If no journal found, ask the user about creating one
if not journal:
# The active_id is passed in context so the wizard can call import_file again once the journal is created
return self.with_context(
active_id=self.ids[0]
)._journal_creation_wizard(currency, account_number)
if (
not journal.default_debit_account_id
or not journal.default_credit_account_id
):
raise UserError(
_(
"You have to set a Default Debit Account and a Default Credit Account for the journal: %s"
)
% (journal.name,)
)
# Prepare statement data to be used for bank statements creation
stmts_vals = self._complete_stmts_vals(stmts_vals, journal, account_number)
# Create the bank statements
statement_line_ids, notifications = self._create_bank_statements(stmts_vals)
statement_line_ids_all.extend(statement_line_ids)
notifications_all.extend(notifications)
# Now that the import worked out, set it as the bank_statements_source of the journal
if journal.bank_statements_source != "file_import":
# Use sudo() because only 'account.group_account_manager'
# has write access on 'account.journal', but 'account.group_account_user'
# must be able to import bank statement files
journal.sudo().bank_statements_source = "file_import"
# Finally dispatch to reconciliation interface
return {
"type": "ir.actions.client",
"tag": "bank_statement_reconciliation_view",
"context": {
"statement_line_ids": statement_line_ids_all,
"company_ids": self.env.user.company_ids.ids,
"notifications": notifications_all,
},
}
def _journal_creation_wizard(self, currency, account_number):
""" Calls a wizard that allows the user to carry on with journal creation """
return {
"name": _("Journal Creation"),
"type": "ir.actions.act_window",
"res_model": "account.bank.statement.import.journal.creation",
"view_mode": "form",
"target": "new",
"context": {
"statement_import_transient_id": self.env.context["active_id"],
"default_bank_acc_number": account_number,
"default_name": _("Bank") + " " + account_number,
"default_currency_id": currency and currency.id or False,
"default_type": "bank",
},
}
def _parse_file(self, data_file):
"""Each module adding a file support must extends this method. It processes the file if it can, returns super otherwise, resulting in a chain of responsability.
This method parses the given file and returns the data required by the bank statement import process, as specified below.
rtype: triplet (if a value can't be retrieved, use None)
- currency code: string (e.g: 'EUR')
The ISO 4217 currency code, case insensitive
- account number: string (e.g: 'BE1234567890')
The number of the bank account which the statement belongs to
- bank statements data: list of dict containing (optional items marked by o) :
- 'name': string (e.g: '000000123')
- 'date': date (e.g: 2013-06-26)
-o 'balance_start': float (e.g: 8368.56)
-o 'balance_end_real': float (e.g: 8888.88)
- 'transactions': list of dict containing :
- 'name': string (e.g: 'KBC-INVESTERINGSKREDIET 787-5562831-01')
- 'date': date
- 'amount': float
- 'unique_import_id': string
-o 'account_number': string
Will be used to find/create the res.partner.bank in odoo
-o 'note': string
-o 'partner_name': string
-o 'ref': string
"""
raise UserError(
_(
"Could not make sense of the given file.\nDid you install the module to support this type of file ?"
)
)
def _check_parsed_data(self, stmts_vals):
""" Basic and structural verifications """
if len(stmts_vals) == 0:
raise UserError(_("This file doesn't contain any statement."))
no_st_line = True
for vals in stmts_vals:
if vals["transactions"] and len(vals["transactions"]) > 0:
no_st_line = False
break
if no_st_line:
raise UserError(_("This file doesn't contain any transaction."))
def _check_journal_bank_account(self, journal, account_number):
return journal.bank_account_id.sanitized_acc_number == account_number
def _find_additional_data(self, currency_code, account_number):
"""Look for a res.currency and account.journal using values extracted from the
statement and make sure it's consistent.
"""
company_currency = self.env.company.currency_id
journal_obj = self.env["account.journal"]
currency = None
sanitized_account_number = sanitize_account_number(account_number)
if currency_code:
currency = self.env["res.currency"].search(
[("name", "=ilike", currency_code)], limit=1
)
if not currency:
raise UserError(_("No currency found matching '%s'.") % currency_code)
if currency == company_currency:
currency = False
journal = journal_obj.browse(self.env.context.get("journal_id", []))
if account_number:
# No bank account on the journal : create one from the account number of the statement
if journal and not journal.bank_account_id:
journal.set_bank_account(account_number)
# No journal passed to the wizard : try to find one using the account number of the statement
elif not journal:
journal = journal_obj.search(
[
(
"bank_account_id.sanitized_acc_number",
"=",
sanitized_account_number,
)
]
)
# Already a bank account on the journal : check it's the same as on the statement
else:
if not self._check_journal_bank_account(
journal, sanitized_account_number
):
raise UserError(
_(
"The account of this statement (%s) is not the same as the journal (%s)."
)
% (account_number, journal.bank_account_id.acc_number)
)
# If importing into an existing journal, its currency must be the same as the bank statement
if journal:
journal_currency = journal.currency_id
if currency is None:
currency = journal_currency
if currency and currency != journal_currency:
statement_cur_code = (
not currency and company_currency.name or currency.name
)
journal_cur_code = (
not journal_currency
and company_currency.name
or journal_currency.name
)
raise UserError(
_(
"The currency of the bank statement (%s) is not the same as the currency of the journal (%s)."
)
% (statement_cur_code, journal_cur_code)
)
# If we couldn't find / can't create a journal, everything is lost
if not journal and not account_number:
raise UserError(
_(
"Cannot find in which journal import this statement. Please manually select a journal."
)
)
return currency, journal
def _complete_stmts_vals(self, stmts_vals, journal, account_number):
for st_vals in stmts_vals:
st_vals["journal_id"] = journal.id
if not st_vals.get("reference"):
st_vals["reference"] = " ".join(self.attachment_ids.mapped("name"))
if st_vals.get("number"):
# build the full name like BNK/2016/00135 by just giving the number '135'
st_vals["name"] = journal.sequence_id.with_context(
ir_sequence_date=st_vals.get("date")
).get_next_char(st_vals["number"])
del st_vals["number"]
for line_vals in st_vals["transactions"]:
unique_import_id = line_vals.get("unique_import_id")
if unique_import_id:
sanitized_account_number = sanitize_account_number(account_number)
line_vals["unique_import_id"] = (
(
sanitized_account_number
and sanitized_account_number + "-"
or ""
)
+ str(journal.id)
+ "-"
+ unique_import_id
)
if not line_vals.get("bank_account_id"):
# Find the partner and his bank account or create the bank account. The partner selected during the
# reconciliation process will be linked to the bank when the statement is closed.
identifying_string = line_vals.get("account_number")
if identifying_string:
partner_bank = self.env["res.partner.bank"].search(
[("acc_number", "=", identifying_string)], limit=1
)
if partner_bank:
line_vals["bank_account_id"] = partner_bank.id
line_vals["partner_id"] = partner_bank.partner_id.id
return stmts_vals
def _create_bank_statements(self, stmts_vals):
""" Create new bank statements from imported values, filtering out already imported transactions, and returns data used by the reconciliation widget """
BankStatement = self.env["account.bank.statement"]
BankStatementLine = self.env["account.bank.statement.line"]
# Filter out already imported transactions and create statements
statement_line_ids = []
ignored_statement_lines_import_ids = []
for st_vals in stmts_vals:
filtered_st_lines = []
for line_vals in st_vals["transactions"]:
if (
"unique_import_id" not in line_vals
or not line_vals["unique_import_id"]
or not bool(
BankStatementLine.sudo().search(
[("unique_import_id", "=", line_vals["unique_import_id"])],
limit=1,
)
)
):
filtered_st_lines.append(line_vals)
else:
ignored_statement_lines_import_ids.append(
line_vals["unique_import_id"]
)
if "balance_start" in st_vals:
st_vals["balance_start"] += float(line_vals["amount"])
if len(filtered_st_lines) > 0:
# Remove values that won't be used to create records
st_vals.pop("transactions", None)
# Create the statement
st_vals["line_ids"] = [[0, False, line] for line in filtered_st_lines]
statement_line_ids.extend(BankStatement.create(st_vals).line_ids.ids)
if len(statement_line_ids) == 0:
raise UserError(_("You already have imported that file."))
# Prepare import feedback
notifications = []
num_ignored = len(ignored_statement_lines_import_ids)
if num_ignored > 0:
notifications += [
{
"type": "warning",
"message": _(
"%d transactions had already been imported and were ignored."
)
% num_ignored
if num_ignored > 1
else _("1 transaction had already been imported and was ignored."),
"details": {
"name": _("Already imported items"),
"model": "account.bank.statement.line",
"ids": BankStatementLine.search(
[
(
"unique_import_id",
"in",
ignored_statement_lines_import_ids,
)
]
).ids,
},
}
]
return statement_line_ids, notifications

View File

@@ -1,77 +0,0 @@
<?xml version="1.0" ?>
<!--
Copyright 2004-2020 Odoo S.A.
Licence LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0).
-->
<odoo>
<record id="account_bank_statement_import_view" model="ir.ui.view">
<field name="name">Upload Bank Statements</field>
<field name="model">account.bank.statement.import</field>
<field name="priority">1</field>
<field name="arch" type="xml">
<form string="Upload Bank Statements">
<h2>You can upload your bank statement using:</h2>
<ul id="statement_format">
</ul>
<field
name="attachment_ids"
widget="many2many_binary"
colspan="2"
string="Select Files"
nolabel="1"
/>
<footer>
<button
name="import_file"
string="Upload"
type="object"
class="btn-primary"
/>
<button
string="Cancel"
class="btn-secondary"
special="cancel"
/>
</footer>
</form>
</field>
</record>
<record id="install_more_import_formats_action" model="ir.actions.act_window">
<field name="name">Install Import Format</field>
<field name="res_model">ir.module.module</field>
<field name="view_mode">kanban,tree,form</field>
<field
name="context"
eval="{'search_default_name': 'account_bank_statement_import'}"
/>
<field name="search_view_id" ref="base.view_module_filter" />
</record>
<record id="action_account_bank_statement_import" model="ir.actions.act_window">
<field name="name">Upload</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">account.bank.statement.import</field>
<field name="view_mode">form</field>
<field name="target">new</field>
<field name="view_id" ref="account_bank_statement_import_view" />
</record>
<record id="journal_dashboard_view_inherit" model="ir.ui.view">
<field name="name">account.journal.dashboard.kanban.inherit</field>
<field name="model">account.journal</field>
<field name="inherit_id" ref="account.account_journal_dashboard_kanban_view" />
<field name="arch" type="xml">
<xpath expr='//span[@name="button_import_placeholder"]' position='inside'>
<span>or <a type="object" name="import_statement">Import</a></span>
</xpath>
<xpath expr='//div[@name="bank_cash_commands"]' position="before">
<div t-if="journal_type == 'bank'">
<a type="object" name="import_statement">Import Statement</a>
</div>
</xpath>
</field>
</record>
</odoo>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<data>
</data>
</odoo>

View File

@@ -1,800 +0,0 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_bank_statement_import
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server saas~12.5\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-09-27 09:10+0000\n"
"PO-Revision-Date: 2019-09-27 09:10+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: account_bank_statement_import
#. openerp-web
#: code:addons/account_bank_statement_import/static/src/js/account_bank_statement_import.js:0
#, python-format
msgid " Import Template for Bank Statements"
msgstr ""
#. module: account_bank_statement_import
#: code:addons/account_bank_statement_import/account_bank_statement_import.py:0
#, python-format
msgid "%d transactions had already been imported and were ignored."
msgstr ""
#. module: account_bank_statement_import
#: code:addons/account_bank_statement_import/account_bank_statement_import.py:0
#, python-format
msgid "1 transaction had already been imported and was ignored."
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.constraint,message:account_bank_statement_import.constraint_account_bank_statement_line_unique_import_id
msgid "A bank account transactions can be imported only once !"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__company_partner_id
msgid "Account Holder"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__bank_acc_number
msgid "Account Number"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__type_control_ids
msgid "Account Types Allowed"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__account_control_ids
msgid "Accounts Allowed"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__message_needaction
msgid "Action Needed"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__active
msgid "Active"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__activity_ids
msgid "Activities"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__activity_exception_decoration
msgid "Activity Exception Decoration"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__activity_state
msgid "Activity State"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__alias_id
msgid "Alias"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__alias_name
msgid "Alias Name"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__alias_domain
msgid "Alias domain"
msgstr ""
#. module: account_bank_statement_import
#: code:addons/account_bank_statement_import/account_bank_statement_import.py:0
#, python-format
msgid "Already imported items"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__at_least_one_inbound
msgid "At Least One Inbound"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__at_least_one_outbound
msgid "At Least One Outbound"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__message_attachment_count
msgid "Attachment Count"
msgstr ""
#. module: account_bank_statement_import
#: code:addons/account_bank_statement_import/account_bank_statement_import.py:0
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__bank_id
#, python-format
msgid "Bank"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__bank_account_id
msgid "Bank Account"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__bank_statements_source
msgid "Bank Feeds"
msgstr ""
#. module: account_bank_statement_import
#: model_terms:ir.ui.view,arch_db:account_bank_statement_import.account_bank_statement_import_journal_creation_view
msgid "Bank Journal Name"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model,name:account_bank_statement_import.model_account_bank_statement_line
msgid "Bank Statement Line"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model,name:account_bank_statement_import.model_account_setup_bank_manual_config
msgid "Bank setup manual config"
msgstr ""
#. module: account_bank_statement_import
#: model_terms:ir.ui.view,arch_db:account_bank_statement_import.account_bank_statement_import_journal_creation_view
#: model_terms:ir.ui.view,arch_db:account_bank_statement_import.account_bank_statement_import_view
msgid "Cancel"
msgstr ""
#. module: account_bank_statement_import
#: code:addons/account_bank_statement_import/account_bank_statement_import.py:0
#, python-format
msgid ""
"Cannot find in which journal import this statement. Please manually select a"
" journal."
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__refund_sequence
msgid ""
"Check this box if you don't want to share the same sequence for invoices and"
" credit notes made from this journal"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__color
msgid "Color Index"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__invoice_reference_model
msgid "Communication Standard"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__invoice_reference_type
msgid "Communication Type"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__company_id
msgid "Company"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__company_id
msgid "Company related to this journal"
msgstr ""
#. module: account_bank_statement_import
#: code:addons/account_bank_statement_import/account_bank_statement_import.py:0
#, python-format
msgid ""
"Could not make sense of the given file.\n"
"Did you install the module to support this type of file ?"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import__create_uid
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__create_uid
msgid "Created by"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import__create_date
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__create_date
msgid "Created on"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__refund_sequence_id
msgid "Credit Note Entry Sequence"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__refund_sequence_number_next
msgid "Credit Notes Next Number"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__currency_id
msgid "Currency"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__refund_sequence
msgid "Dedicated Credit Note Sequence"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__default_credit_account_id
msgid "Default Credit Account"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__default_debit_account_id
msgid "Default Debit Account"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__bank_statements_source
msgid "Defines how the bank statements will be registered"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import__display_name
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__display_name
msgid "Display Name"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__sequence_id
msgid "Entry Sequence"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import__filename
msgid "Filename"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import__attachment_ids
msgid "Files"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__message_follower_ids
msgid "Followers"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__message_channel_ids
msgid "Followers (Channels)"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__message_partner_ids
msgid "Followers (Partners)"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__inbound_payment_method_ids
msgid "For Incoming Payments"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__outbound_payment_method_ids
msgid "For Outgoing Payments"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import__attachment_ids
msgid ""
"Get you bank statements in electronic format from your bank and select them "
"here."
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import__id
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__id
msgid "ID"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__activity_exception_icon
msgid "Icon"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__activity_exception_icon
msgid "Icon to indicate an exception activity."
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__message_needaction
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__message_unread
msgid "If checked, new messages require your attention."
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__message_has_error
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__message_has_sms_error
msgid "If checked, some messages have a delivery error."
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__restrict_mode_hash_table
msgid ""
"If ticked, the accounting entry or invoice receives a hash as soon as it is "
"posted and cannot be modified anymore."
msgstr ""
#. module: account_bank_statement_import
#: code:addons/account_bank_statement_import/account_journal.py:0
#: model_terms:ir.ui.view,arch_db:account_bank_statement_import.journal_dashboard_view_inherit
#, python-format
msgid "Import"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model,name:account_bank_statement_import.model_account_bank_statement_import
msgid "Import Bank Statement"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_line__unique_import_id
msgid "Import ID"
msgstr ""
#. module: account_bank_statement_import
#: model_terms:ir.ui.view,arch_db:account_bank_statement_import.journal_dashboard_view_inherit
msgid "Import Statement"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.actions.act_window,name:account_bank_statement_import.install_more_import_formats_action
msgid "Install Import Format"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__message_is_follower
msgid "Is Follower"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__default_credit_account_id
msgid "It acts as a default account for credit amount"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__default_debit_account_id
msgid "It acts as a default account for debit amount"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__alias_name
msgid "It creates draft invoices and bills by sending an email."
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model,name:account_bank_statement_import.model_account_journal
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__journal_id
msgid "Journal"
msgstr ""
#. module: account_bank_statement_import
#: code:addons/account_bank_statement_import/account_bank_statement_import.py:0
#: model_terms:ir.ui.view,arch_db:account_bank_statement_import.account_bank_statement_import_journal_creation_view
#, python-format
msgid "Journal Creation"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model,name:account_bank_statement_import.model_account_bank_statement_import_journal_creation
msgid "Journal Creation on Bank Statement Import"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__journal_group_ids
msgid "Journal Groups"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__name
msgid "Journal Name"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__json_activity_data
msgid "Json Activity Data"
msgstr ""
#. module: account_bank_statement_import
#: model_terms:ir.ui.view,arch_db:account_bank_statement_import.account_bank_statement_import_journal_creation_view
msgid ""
"Just click OK to create the account/journal and finish the upload. If this "
"was a mistake, hit cancel to abort the upload."
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__kanban_dashboard
msgid "Kanban Dashboard"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__kanban_dashboard_graph
msgid "Kanban Dashboard Graph"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import____last_update
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation____last_update
msgid "Last Modified on"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import__write_uid
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__write_uid
msgid "Last Updated by"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import__write_date
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__write_date
msgid "Last Updated on"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__restrict_mode_hash_table
msgid "Lock Posted Entries with Hash"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__loss_account_id
msgid "Loss Account"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__message_main_attachment_id
msgid "Main Attachment"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__inbound_payment_method_ids
msgid ""
"Manual: Get paid by cash, check or any other method outside of Odoo.\n"
"Electronic: Get paid automatically through a payment acquirer by requesting a transaction on a card saved by the customer when buying or subscribing online (payment token).\n"
"Batch Deposit: Encase several customer checks at once by generating a batch deposit to submit to your bank. When encoding the bank statement in Odoo,you are suggested to reconcile the transaction with the batch deposit. Enable this option from the settings."
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__outbound_payment_method_ids
msgid ""
"Manual:Pay bill by cash or any other method outside of Odoo.\n"
"Check:Pay bill by check and print it from Odoo.\n"
"SEPA Credit Transfer: Pay bill from a SEPA Credit Transfer file you submit to your bank. Enable this option from the settings."
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__message_has_error
msgid "Message Delivery error"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__message_ids
msgid "Messages"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__activity_date_deadline
msgid "Next Activity Deadline"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__activity_summary
msgid "Next Activity Summary"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__activity_type_id
msgid "Next Activity Type"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__sequence_number_next
msgid "Next Number"
msgstr ""
#. module: account_bank_statement_import
#: code:addons/account_bank_statement_import/account_bank_statement_import.py:0
#, python-format
msgid "No currency found matching '%s'."
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__message_needaction_counter
msgid "Number of Actions"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__message_has_error_counter
msgid "Number of errors"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__message_needaction_counter
msgid "Number of messages which requires an action"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__message_has_error_counter
msgid "Number of messages with delivery error"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__message_unread_counter
msgid "Number of unread messages"
msgstr ""
#. module: account_bank_statement_import
#: model_terms:ir.ui.view,arch_db:account_bank_statement_import.account_bank_statement_import_journal_creation_view
msgid "OK"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__post_at
msgid "Post At"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__profit_account_id
msgid "Profit Account"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__activity_user_id
msgid "Responsible User"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__message_has_sms_error
msgid "SMS Delivery error"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__secure_sequence_id
msgid "Secure Sequence"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__type
msgid ""
"Select 'Sale' for customer invoices journals.\n"
"Select 'Purchase' for vendor bills journals.\n"
"Select 'Cash' or 'Bank' for journals that are used in customer or vendor payments.\n"
"Select 'General' for miscellaneous operations journals."
msgstr ""
#. module: account_bank_statement_import
#: model_terms:ir.ui.view,arch_db:account_bank_statement_import.account_bank_statement_import_view
msgid "Select Files"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__sequence
msgid "Sequence"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__secure_sequence_id
msgid "Sequence to use to ensure the securisation of data"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__active
msgid "Set active to false to hide the Journal without removing it."
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__code
msgid "Short Code"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__show_on_dashboard
msgid "Show journal on dashboard"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__activity_state
msgid ""
"Status based on activities\n"
"Overdue: Due date is already passed\n"
"Today: Activity date is today\n"
"Planned: Future activities."
msgstr ""
#. module: account_bank_statement_import
#: model_terms:ir.ui.view,arch_db:account_bank_statement_import.account_bank_statement_import_journal_creation_view
msgid ""
"The account of the statement you are uploading is not yet recorded in Odoo. "
"In order to proceed with the upload, you need to create a bank journal for "
"this account."
msgstr ""
#. module: account_bank_statement_import
#: code:addons/account_bank_statement_import/account_bank_statement_import.py:0
#, python-format
msgid ""
"The account of this statement (%s) is not the same as the journal (%s)."
msgstr ""
#. module: account_bank_statement_import
#: code:addons/account_bank_statement_import/account_bank_statement_import.py:0
#, python-format
msgid ""
"The currency of the bank statement (%s) is not the same as the currency of "
"the journal (%s)."
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__currency_id
msgid "The currency used to enter statement"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__code
msgid "The journal entries of this journal will be named using this prefix."
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__refund_sequence_number_next
msgid "The next sequence number will be used for the next credit note."
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__sequence_number_next
msgid "The next sequence number will be used for the next invoice."
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__refund_sequence_id
msgid ""
"This field contains the information related to the numbering of the credit "
"note entries of this journal."
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__sequence_id
msgid ""
"This field contains the information related to the numbering of the journal "
"entries of this journal."
msgstr ""
#. module: account_bank_statement_import
#: code:addons/account_bank_statement_import/account_bank_statement_import.py:0
#, python-format
msgid "This file doesn't contain any statement."
msgstr ""
#. module: account_bank_statement_import
#: code:addons/account_bank_statement_import/account_bank_statement_import.py:0
#, python-format
msgid "This file doesn't contain any transaction."
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__type
msgid "Type"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__activity_exception_decoration
msgid "Type of the exception activity on record."
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__message_unread
msgid "Unread Messages"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__message_unread_counter
msgid "Unread Messages Counter"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.actions.act_window,name:account_bank_statement_import.action_account_bank_statement_import
#: model_terms:ir.ui.view,arch_db:account_bank_statement_import.account_bank_statement_import_view
msgid "Upload"
msgstr ""
#. module: account_bank_statement_import
#: model_terms:ir.ui.view,arch_db:account_bank_statement_import.account_bank_statement_import_view
msgid "Upload Bank Statements"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__sequence
msgid "Used to order Journals in the dashboard view"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__loss_account_id
msgid ""
"Used to register a loss when the ending balance of a cash register differs "
"from what the system computes"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__profit_account_id
msgid ""
"Used to register a profit when the ending balance of a cash register differs"
" from what the system computes"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,field_description:account_bank_statement_import.field_account_bank_statement_import_journal_creation__website_message_ids
msgid "Website Messages"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__website_message_ids
msgid "Website communication history"
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__show_on_dashboard
msgid "Whether this journal should be displayed on the dashboard or not"
msgstr ""
#. module: account_bank_statement_import
#: code:addons/account_bank_statement_import/account_bank_statement_import.py:0
#, python-format
msgid "You already have imported that file."
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__invoice_reference_model
msgid ""
"You can choose different models for each type of reference. The default one "
"is the Odoo reference."
msgstr ""
#. module: account_bank_statement_import
#: model:ir.model.fields,help:account_bank_statement_import.field_account_bank_statement_import_journal_creation__invoice_reference_type
msgid ""
"You can set here the default communication that will appear on customer "
"invoices, once validated, to help the customer to refer to that particular "
"invoice when making the payment."
msgstr ""
#. module: account_bank_statement_import
#: model_terms:ir.ui.view,arch_db:account_bank_statement_import.account_bank_statement_import_view
msgid "You can upload your bank statement using:"
msgstr ""
#. module: account_bank_statement_import
#: code:addons/account_bank_statement_import/account_bank_statement_import.py:0
#, python-format
msgid ""
"You have to set a Default Debit Account and a Default Credit Account for the"
" journal: %s"
msgstr ""
#. module: account_bank_statement_import
#: model_terms:ir.ui.view,arch_db:account_bank_statement_import.journal_dashboard_view_inherit
msgid "or"
msgstr ""

View File

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

View File

@@ -0,0 +1,26 @@
# Copyright 2004-2020 Odoo S.A.
# Copyright 2020 Akretion France (http://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# Licence LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0).
from odoo import fields, models
class AccountBankStatementLine(models.Model):
_inherit = "account.bank.statement.line"
# Ensure transactions can be imported only once
# (if the import format provides unique transaction ids)
unique_import_id = fields.Char(string="Import ID", readonly=True, copy=False)
# v13 field: bank_partner_id
# This field was removed in v14, but it is still used in the code, cf the
# method reconcile() !!! So I restore the field here
partner_bank_id = fields.Many2one("res.partner.bank", string="Partner Bank Account")
_sql_constraints = [
(
"unique_import_id",
"unique(unique_import_id)",
"A bank account transaction can be imported only once!",
)
]

View File

@@ -1,7 +1,9 @@
# Copyright 2004-2020 Odoo S.A.
# Copyright 2020 Akretion France (http://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# Licence LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0).
from odoo import _, api, models
from odoo import _, models
class AccountJournal(models.Model):
@@ -12,7 +14,7 @@ class AccountJournal(models.Model):
return []
def __get_bank_statements_available_sources(self):
rslt = super(AccountJournal, self).__get_bank_statements_available_sources()
rslt = super().__get_bank_statements_available_sources()
formats_list = self._get_bank_statements_available_import_formats()
if formats_list:
formats_list.sort()
@@ -21,9 +23,10 @@ class AccountJournal(models.Model):
return rslt
def import_statement(self):
"""return action to import bank/cash statements. This button should be called only on journals with type =='bank'"""
action_name = "action_account_bank_statement_import"
[action] = self.env.ref("account_bank_statement_import.%s" % action_name).read()
# Note: this drops action['context'], which is a dict stored as a string, which is not easy to update
action.update({"context": (u"{'journal_id': " + str(self.id) + u"}")})
"""return action to import bank/cash statements.
This button should be called only on journals with type =='bank'"""
action = self.env.ref(
"account_statement_import.account_statement_import_action"
).read()[0]
action["context"] = {"journal_id": self.id}
return action

View File

@@ -0,0 +1,3 @@
* Odoo S.A.
* Alexis de Lattre <alexis.delattre@akretion.com>
* Tecnativa - Pedro M. Baeza

View File

@@ -0,0 +1,9 @@
This module is the successor of the module **account_bank_statement_import** that was part of Odoo Community until Odoo v13 and was moved to Odoo Enterprise for Odoo v14 (cf `this commit <https://github.com/odoo/odoo/commit/9ba8734f15e1a292ca27b1a026e8366a91b2a8c9>`_). We decided to change its name and the name of the wizard object it provides in order to avoid a conflict with the Enterprise module.
This module has several additionnal feature:
* support multi-account bank statement files,
* attach the file to the bank statement (to facilitate the diagnostic in case of problem),
* improved error messages.
This module only provides the technical framework for the import of statement files. You must also install the format-specific modules to add support for the statement file formats that your banks/provide use. For example, the OCA module **account_statement_import_ofx** will add support for the OFX (Open Financial Exchange) file format. You will find those modules in the OCA project `bank-statement-import <https://github.com/OCA/bank-statement-import>`_ or, for the country-specific formats, in the OCA localization projects.

View File

@@ -0,0 +1,5 @@
To import a statement file, go to the Invoicing dashboard: on a bank journal, you will see a button to import a statement. When you click on that button, a wizard will start and it will show the list of the supported file formats. Select the statement file that you want to import and click on the **Import** button. Odoo will create a new bank statement (or several if your statement file is a multi-account file).
If your statement file contains transactions that were already imported in Odoo, they will not be created a second time.
If the statement file contains information about the bank account number of the counter-part for some transactions (only a few statement file formats support that, in some countries) and that these bank account numbers exists on partners in Odoo, the partners will be set on the related statement lines.

View File

@@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_account_statement_import_user,Full access on account.statement.import wizard,model_account_statement_import,account.group_account_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_account_statement_import_user Full access on account.statement.import wizard model_account_statement_import account.group_account_user 1 1 1 1

View File

@@ -1,6 +0,0 @@
Journal,Name,Date,Starting Balance,Ending Balance,Statement lines / Date,Statement lines / Label,Statement lines / Partner,Statement lines / Reference,Statement lines / Amount,Statement lines / Amount Currency,Statement lines / Currency
Bank,Statement May 01,2017-05-15,100,5124.5,2017-05-10,INV/2017/0001,,#01,4610,,
,,,,,2017-05-11,Payment bill 20170521,,#02,-100,,
,,,,,2017-05-15,INV/2017/0003 discount 2% early payment,,#03,514.5,,
Bank,Statement May 02,2017-05-30,5124.5,9847.35,2017-05-30,INV/2017/0002 + INV/2017/0004,,#01,5260,,
,,,,,2017-05-31,Payment bill EUR 001234565,,#02,-537.15,-500,EUR
1 Journal Name Date Starting Balance Ending Balance Statement lines / Date Statement lines / Label Statement lines / Partner Statement lines / Reference Statement lines / Amount Statement lines / Amount Currency Statement lines / Currency
2 Bank Statement May 01 2017-05-15 100 5124.5 2017-05-10 INV/2017/0001 #01 4610
3 2017-05-11 Payment bill 20170521 #02 -100
4 2017-05-15 INV/2017/0003 discount 2% early payment #03 514.5
5 Bank Statement May 02 2017-05-30 5124.5 9847.35 2017-05-30 INV/2017/0002 + INV/2017/0004 #01 5260
6 2017-05-31 Payment bill EUR 001234565 #02 -537.15 -500 EUR

View File

@@ -1,178 +1,207 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
enable-background="new 0 0 100 100"
height="100px"
id="Layer_1"
version="1.1"
viewBox="0 0 100 100"
width="100px"
xml:space="preserve"
inkscape:version="0.48.2 r9819"
sodipodi:docname="1409271720_Noun_Project_100Icon_10px_grid-17.svg"
inkscape:export-filename="/Users/arthurmaniet/Desktop/icon.png"
inkscape:export-xdpi="115.2"
inkscape:export-ydpi="115.2"><metadata
id="metadata9"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs7" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1733"
inkscape:window-height="1001"
id="namedview5"
showgrid="false"
inkscape:zoom="11.62"
inkscape:cx="21.99675"
inkscape:cy="56.127828"
inkscape:window-x="76"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="Layer_1" /><path
d="M79.043,31.615l-5.742,5.742V13h-58v74h58V48.67l11.398-11.399L79.043,31.615z M71.301,39.357L50.758,59.898l-1.414,4.242 l-1.414,4.244l8.486-2.828L71.301,50.67V85h-54V15h54V39.357z M54.564,65.119l-3.182,1.06l-1.248-1.248l1.061-3.182l3.1,3.099 L54.564,65.119z"
id="path3" /><text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="18.006462"
y="17.887218"
id="text2986"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
x="18.006462"
y="17.887218"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3520">08/12/13 1000.00 Delta PC</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="21.637218"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3731">08/15/13 75.46 Walts Drugs</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="25.387218"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3733">03/03/13 379.00 Epic Technologies</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="29.137218"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3735">03/04/13 20.28 YOUR LOCAL SU</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="32.887218"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3737">03/03/13 421.35 SPRINGFIELD WA</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="36.637218"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3739">03/03/13 379.00 Epic Technologies</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="40.387218"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3743">03/04/13 20.28 YOUR LOCAL SUP</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="44.137218"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3846">08/15/13 75.46 Walts Drugs</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="47.887218"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3745">08/12/13 1000.00 Delta PC</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="51.637218"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3747">03/03/13 421.35 SPRINGFIELD WA</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="55.387218"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3749">03/04/13 20.28 YOUR LOCAL SU</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="59.137218"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3751">03/03/13 379.00 Epic Technologies</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="62.887218"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3753">08/12/13 1000.00 De a PC</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="66.637222"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3755">03/03/13 379.00 E Technologies</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="70.387222"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3757">08/15/13 75.46 Walts Drugs</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="74.137222"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3759">03/04/13 20.28 YOUR LOCAL SU</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="77.887222"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3761">03/03/13 379.00 Epic Technologies</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="81.637222"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3763">08/12/13 1000.00 Delta PC</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="85.387222"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3765">08/15/13 75.46 Walts Drugs</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="89.137222"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3783" /><tspan
sodipodi:role="line"
x="18.006462"
y="92.887222"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3799" /><tspan
sodipodi:role="line"
x="18.006462"
y="96.637222"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3801" /></text>
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
enable-background="new 0 0 100 100"
height="100px"
id="Layer_1"
version="1.1"
viewBox="0 0 100 100"
width="100px"
xml:space="preserve"
inkscape:version="0.48.2 r9819"
sodipodi:docname="1409271720_Noun_Project_100Icon_10px_grid-17.svg"
inkscape:export-filename="/Users/arthurmaniet/Desktop/icon.png"
inkscape:export-xdpi="115.2"
inkscape:export-ydpi="115.2"
><metadata id="metadata9"><rdf:RDF><cc:Work rdf:about=""><dc:format
>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage"
/><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs7"
/><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1733"
inkscape:window-height="1001"
id="namedview5"
showgrid="false"
inkscape:zoom="11.62"
inkscape:cx="21.99675"
inkscape:cy="56.127828"
inkscape:window-x="76"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="Layer_1"
/><path
d="M79.043,31.615l-5.742,5.742V13h-58v74h58V48.67l11.398-11.399L79.043,31.615z M71.301,39.357L50.758,59.898l-1.414,4.242 l-1.414,4.244l8.486-2.828L71.301,50.67V85h-54V15h54V39.357z M54.564,65.119l-3.182,1.06l-1.248-1.248l1.061-3.182l3.1,3.099 L54.564,65.119z"
id="path3"
/><text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="18.006462"
y="17.887218"
id="text2986"
sodipodi:linespacing="125%"
><tspan
sodipodi:role="line"
x="18.006462"
y="17.887218"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3520"
>08/12/13 1000.00 Delta PC</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="21.637218"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3731"
>08/15/13 75.46 Walts Drugs</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="25.387218"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3733"
>03/03/13 379.00 Epic Technologies</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="29.137218"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3735"
>03/04/13 20.28 YOUR LOCAL SU</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="32.887218"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3737"
>03/03/13 421.35 SPRINGFIELD WA</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="36.637218"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3739"
>03/03/13 379.00 Epic Technologies</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="40.387218"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3743"
>03/04/13 20.28 YOUR LOCAL SUP</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="44.137218"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3846"
>08/15/13 75.46 Walts Drugs</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="47.887218"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3745"
>08/12/13 1000.00 Delta PC</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="51.637218"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3747"
>03/03/13 421.35 SPRINGFIELD WA</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="55.387218"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3749"
>03/04/13 20.28 YOUR LOCAL SU</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="59.137218"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3751"
>03/03/13 379.00 Epic Technologies</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="62.887218"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3753"
>08/12/13 1000.00 De a PC</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="66.637222"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3755"
>03/03/13 379.00 E Technologies</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="70.387222"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3757"
>08/15/13 75.46 Walts Drugs</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="74.137222"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3759"
>03/04/13 20.28 YOUR LOCAL SU</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="77.887222"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3761"
>03/03/13 379.00 Epic Technologies</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="81.637222"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3763"
>08/12/13 1000.00 Delta PC</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="85.387222"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3765"
>08/15/13 75.46 Walts Drugs</tspan><tspan
sodipodi:role="line"
x="18.006462"
y="89.137222"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3783"
/><tspan
sodipodi:role="line"
x="18.006462"
y="92.887222"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3799"
/><tspan
sodipodi:role="line"
x="18.006462"
y="96.637222"
style="font-size:3px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold"
id="tspan3801"
/></text>
<text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="43.851177"
y="32.13871"
id="text3838"
sodipodi:linespacing="125%"
inkscape:export-filename="/Users/arthurmaniet/Desktop/icon.png"
inkscape:export-xdpi="115.2"
inkscape:export-ydpi="115.2"><tspan
sodipodi:role="line"
id="tspan3840"
x="43.851177"
y="32.13871"
style="font-size:16px;font-weight:bold;text-align:center;text-anchor:middle;-inkscape-font-specification:Sans Bold" /></text>
</svg>
xml:space="preserve"
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="43.851177"
y="32.13871"
id="text3838"
sodipodi:linespacing="125%"
inkscape:export-filename="/Users/arthurmaniet/Desktop/icon.png"
inkscape:export-xdpi="115.2"
inkscape:export-ydpi="115.2"
><tspan
sodipodi:role="line"
id="tspan3840"
x="43.851177"
y="32.13871"
style="font-size:16px;font-weight:bold;text-align:center;text-anchor:middle;-inkscape-font-specification:Sans Bold"
/></text>
</svg>

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -0,0 +1,438 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.15.1: http://docutils.sourceforge.net/" />
<title>Import Statement Files</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: grey; } /* 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 }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="import-statement-files">
<h1 class="title">Import Statement Files</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/lgpl-3.0-standalone.html"><img alt="License: LGPL-3" src="https://img.shields.io/badge/licence-LGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/bank-statement-import/tree/14.0/account_statement_import"><img alt="OCA/bank-statement-import" src="https://img.shields.io/badge/github-OCA%2Fbank--statement--import-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/bank-statement-import-14-0/bank-statement-import-14-0-account_statement_import"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/174/14.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
<p>This module is the successor of the module <strong>account_bank_statement_import</strong> that was part of Odoo Community until Odoo v13 and was moved to Odoo Enterprise for Odoo v14 (cf <a class="reference external" href="https://github.com/odoo/odoo/commit/9ba8734f15e1a292ca27b1a026e8366a91b2a8c9">this commit</a>). We decided to change its name and the name of the wizard object it provides in order to avoid a conflict with the Enterprise module.</p>
<p>This module has several additionnal feature:</p>
<ul class="simple">
<li>support multi-account bank statement files,</li>
<li>attach the file to the bank statement (to facilitate the diagnostic in case of problem),</li>
<li>improved error messages.</li>
</ul>
<p>This module only provides the technical framework for the import of statement files. You must also install the format-specific modules to add support for the statement file formats that your banks/provide use. For example, the OCA module <strong>account_statement_import_ofx</strong> will add support for the OFX (Open Financial Exchange) file format. You will find those modules in the OCA project <a class="reference external" href="https://github.com/OCA/bank-statement-import">bank-statement-import</a> or, for the country-specific formats, in the OCA localization projects.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#usage" id="id1">Usage</a></li>
<li><a class="reference internal" href="#bug-tracker" id="id2">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id3">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id4">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id5">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="id6">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="usage">
<h1><a class="toc-backref" href="#id1">Usage</a></h1>
<p>To import a statement file, go to the Invoicing dashboard: on a bank journal, you will see a button to import a statement. When you click on that button, a wizard will start and it will show the list of the supported file formats. Select the statement file that you want to import and click on the <strong>Import</strong> button. Odoo will create a new bank statement (or several if your statement file is a multi-account file).</p>
<p>If your statement file contains transactions that were already imported in Odoo, they will not be created a second time.</p>
<p>If the statement file contains information about the bank account number of the counter-part for some transactions (only a few statement file formats support that, in some countries) and that these bank account numbers exists on partners in Odoo, the partners will be set on the related statement lines.</p>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#id2">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/bank-statement-import/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/bank-statement-import/issues/new?body=module:%20account_statement_import%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#id3">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#id4">Authors</a></h2>
<ul class="simple">
<li>Odoo SA</li>
<li>Akretion</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#id5">Contributors</a></h2>
<ul class="simple">
<li>Odoo S.A.</li>
<li>Alexis de Lattre &lt;<a class="reference external" href="mailto:alexis.delattre&#64;akretion.com">alexis.delattre&#64;akretion.com</a>&gt;</li>
<li>Tecnativa - Pedro M. Baeza</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#id6">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>
<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>
<p>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainer</a>:</p>
<p><a class="reference external" href="https://github.com/alexis-via"><img alt="alexis-via" src="https://github.com/alexis-via.png?size=40px" /></a></p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/bank-statement-import/tree/14.0/account_statement_import">OCA/bank-statement-import</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</body>
</html>

View File

@@ -1,27 +0,0 @@
/*
Copyright 2004-2020 Odoo S.A.
Licence LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0).
*/
odoo.define("account_bank_statement_import.import", function (require) {
"use strict";
var core = require("web.core");
var BaseImport = require("base_import.import");
var _t = core._t;
BaseImport.DataImport.include({
renderImportLink: function () {
this._super();
if (this.res_model == "account.bank.statement") {
this.$(".import-link").prop({
text: _t(" Import Template for Bank Statements"),
href:
"/account_bank_statement_import/static/csv/account.bank.statement.csv",
});
this.$(".template-import").removeClass("d-none");
}
},
});
});

View File

@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<template
id="assets_backend"
name="account_bank_statement_import assets"
inherit_id="web.assets_backend"
>
<xpath expr="." position="inside">
<script
type="text/javascript"
src="/account_bank_statement_import/static/src/js/account_bank_statement_import.js"
/>
</xpath>
</template>
</odoo>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" ?>
<!--
Copyright 2020 Akretion France (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
Licence LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0).
-->
<odoo>
<record id="view_bank_statement_line_form" model="ir.ui.view">
<field name="model">account.bank.statement.line</field>
<field name="inherit_id" ref="account.view_bank_statement_line_form" />
<field name="arch" type="xml">
<field name="transaction_type" position="before">
<field name="account_number" />
</field>
<field name="transaction_type" position="after">
<field name="partner_bank_id" />
</field>
<field name="move_id" position="after">
<field name="unique_import_id" groups="base.group_no_one" />
</field>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" ?>
<!--
Copyright 2004-2020 Odoo S.A.
Copyright 2020 Akretion France (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
Licence LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0).
-->
<odoo>
<record id="journal_dashboard_view_inherit" model="ir.ui.view">
<field name="model">account.journal</field>
<field name="inherit_id" ref="account.account_journal_dashboard_kanban_view" />
<field name="arch" type="xml">
<xpath expr='//span[@name="button_import_placeholder"]' position='inside'>
<span>or <a type="object" name="import_statement">Import</a></span>
</xpath>
<xpath expr='//div[@name="bank_cash_commands"]' position="before">
<div t-if="journal_type == 'bank'">
<a type="object" name="import_statement">Import Statement</a>
</div>
</xpath>
</field>
</record>
</odoo>

View File

@@ -1,2 +1 @@
from . import journal_creation
from . import setup_wizards
from . import account_statement_import

View File

@@ -0,0 +1,369 @@
# Copyright 2004-2020 Odoo S.A.
# Licence LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0).
import base64
import logging
from odoo import _, api, fields, models
from odoo.exceptions import UserError
from odoo.addons.base.models.res_bank import sanitize_account_number
logger = logging.getLogger(__name__)
class AccountStatementImport(models.TransientModel):
_name = "account.statement.import"
_description = "Import Bank Statement Files"
statement_file = fields.Binary(
string="Statement File",
required=True,
help="Get you bank statements in electronic format from your bank "
"and select them here.",
)
statement_filename = fields.Char()
def import_file_button(self):
"""Process the file chosen in the wizard, create bank statement(s)
and return an action."""
self.ensure_one()
result = {
"statement_ids": [],
"notifications": [],
}
logger.info("Start to import bank statement file %s", self.statement_filename)
file_data = base64.b64decode(self.statement_file)
self.import_single_file(file_data, result)
logger.debug("result=%s", result)
self.env["ir.attachment"].create(self._prepare_create_attachment(result))
if self.env.context.get("return_regular_interface_action"):
action = self.env.ref("account.action_bank_statement_tree").read([])[0]
if len(result["statement_ids"]) == 1:
action.update(
{
"view_mode": "form,tree",
"views": False,
"res_id": result["statement_ids"][0],
}
)
else:
action["domain"] = [("id", "in", result["statement_ids"])]
else:
# dispatch to reconciliation interface
lines = self.env["account.bank.statement.line"].search(
[("statement_id", "in", result["statement_ids"])]
)
action = {
"type": "ir.actions.client",
"tag": "bank_statement_reconciliation_view",
"context": {
"statement_line_ids": lines.ids,
"company_ids": self.env.user.company_ids.ids,
"notifications": result["notifications"],
},
}
return action
def _prepare_create_attachment(self, result):
vals = {
"name": self.statement_filename,
# Attach to first bank statement
"res_id": result["statement_ids"][0],
"res_model": "account.bank.statement",
"datas": self.statement_file,
}
return vals
def import_single_file(self, file_data, result):
parsing_data = self.with_context(active_id=self.ids[0])._parse_file(file_data)
if not isinstance(parsing_data, list): # for backward compatibility
parsing_data = [parsing_data]
logger.info(
"Bank statement file %s contains %d accounts",
self.statement_filename,
len(parsing_data),
)
i = 0
for single_statement_data in parsing_data:
i += 1
logger.debug(
"account %d: single_statement_data=%s", i, single_statement_data
)
self.import_single_statement(single_statement_data, result)
def import_single_statement(self, single_statement_data, result):
if not isinstance(single_statement_data, tuple):
raise UserError(
_("The parsing of the statement file returned an invalid result.")
)
currency_code, account_number, stmts_vals = single_statement_data
# Check raw data
self._check_parsed_data(stmts_vals)
if not currency_code:
raise UserError(_("Missing currency code in the bank statement file."))
# account_number can be None (example : QIF)
currency = self._match_currency(currency_code)
journal = self._match_journal(account_number, currency)
if not journal.default_account_id:
raise UserError(
_("The Bank Accounting Account in not set on the " "journal '%s'.")
% journal.display_name
)
# Prepare statement data to be used for bank statements creation
stmts_vals = self._complete_stmts_vals(stmts_vals, journal, account_number)
# Create the bank statements
self._create_bank_statements(stmts_vals, result)
# Now that the import worked out, set it as the bank_statements_source
# of the journal
if journal.bank_statements_source != "file_import":
# Use sudo() because only 'account.group_account_manager'
# has write access on 'account.journal', but 'account.group_account_user'
# must be able to import bank statement files
journal.sudo().write({"bank_statements_source": "file_import"})
def _parse_file(self, data_file):
"""Each module adding a file support must extends this method.
It processes the file if it can, returns super otherwise,
resulting in a chain of responsability.
This method parses the given file and returns the data required
by the bank statement import process, as specified below.
rtype: triplet
- currency code: string (e.g: 'EUR')
The ISO 4217 currency code, case insensitive
- account number: string (e.g: 'BE1234567890')
The number of the bank account which the statement belongs to
None if it can't be retreived from the statement file
- bank statements data: list of dict containing
(optional items marked by o) :
- 'name': string (e.g: '000000123')
- 'date': date (e.g: 2013-06-26)
-o 'balance_start': float (e.g: 8368.56)
-o 'balance_end_real': float (e.g: 8888.88)
- 'transactions': list of dict containing :
- 'payment_ref': string (label of the line)
- 'date': date
- 'amount': float
- 'unique_import_id': string
-o 'account_number': string
Will be used to find/create the res.partner.bank in odoo
-o 'partner_name': string
If the file is a multi-statement file, this method must return
a list of triplets.
"""
raise UserError(
_(
"This bank statement file format is not supported.\n"
"Did you install the Odoo module to support this format?"
)
)
def _check_parsed_data(self, stmts_vals):
""" Basic and structural verifications """
if len(stmts_vals) == 0:
raise UserError(_("This file doesn't contain any statement."))
no_st_line = True
for vals in stmts_vals:
if vals["transactions"] and len(vals["transactions"]) > 0:
no_st_line = False
break
if no_st_line:
raise UserError(_("This file doesn't contain any transaction."))
@api.model
def _match_currency(self, currency_code):
currency = self.env["res.currency"].search(
[("name", "=ilike", currency_code)], limit=1
)
if not currency:
raise UserError(
_(
"The bank statement file uses currency '%s' "
"but there is no such currency in Odoo."
)
% currency_code
)
return currency
@api.model
def _match_journal(self, account_number, currency):
company = self.env.company
journal_obj = self.env["account.journal"]
if not account_number: # exemple : QIF
if not self.env.context.get("journal_id"):
raise UserError(
_(
"The format of this bank statement file doesn't "
"contain the bank account number, so you must "
"start the wizard from the right bank journal "
"in the dashboard."
)
)
journal = journal_obj.browse(self.env.context.get("journal_id"))
else:
sanitized_account_number = sanitize_account_number(account_number)
journal = journal_obj.search(
[
("type", "=", "bank"),
(
"bank_account_id.sanitized_acc_number",
"ilike",
sanitized_account_number,
),
],
limit=1,
)
if not journal:
bank_accounts = self.env["res.partner.bank"].search(
[
("partner_id", "=", company.partner_id.id),
("sanitized_acc_number", "ilike", sanitized_account_number),
],
limit=1,
)
if bank_accounts:
raise UserError(
_(
"The bank account with number '%s' exists in Odoo "
"but it is not set on any bank journal. You should "
"set it on the related bank journal. If the related "
"bank journal doesn't exist yet, you should create "
"a new one."
)
% (account_number, company.partner_id.display_name)
)
else:
raise UserError(
_(
"Could not find any bank account with number '%s' "
"linked to partner '%s'. You should create the bank "
"account and set it on the related bank journal. "
"If the related bank journal doesn't exist yet, you "
"should create a new one."
)
% (account_number, company.partner_id.display_name)
)
# We support multi-file and multi-statement in a file
# so self.env.context.get('journal_id') doesn't mean much
# I don't think we should really use it
journal_currency = journal.currency_id or company.currency_id
if journal_currency != currency:
raise UserError(
_(
"The currency of the bank statement (%s) is not the same as the "
"currency of the journal '%s' (%s)."
)
% (currency.name, journal.display_name, journal_currency.name)
)
return journal
@api.model
def _update_partner_from_account_number(self, lvals):
partner_bank = self.env["res.partner.bank"].search(
[("acc_number", "=", lvals["account_number"])], limit=1
)
if partner_bank:
lvals["partner_bank_id"] = partner_bank.id
lvals["partner_id"] = partner_bank.partner_id.id
def _complete_stmts_vals(self, stmts_vals, journal, account_number):
for st_vals in stmts_vals:
st_vals["journal_id"] = journal.id
for lvals in st_vals["transactions"]:
unique_import_id = lvals.get("unique_import_id")
if unique_import_id:
sanitized_account_number = sanitize_account_number(account_number)
lvals["unique_import_id"] = (
(
sanitized_account_number
and sanitized_account_number + "-"
or ""
)
+ str(journal.id)
+ "-"
+ unique_import_id
)
if (
not lvals.get("partner_bank_id")
and lvals.get("account_number")
and not lvals.get("partner_id")
):
# Find the partner from his bank account number
# The partner selected during the
# reconciliation process will be linked to the bank account
# when the statement is closed (code in the account module)
self._update_partner_from_account_number(lvals)
if not lvals.get("payment_ref"):
raise UserError(_("Missing payment_ref on a transaction."))
return stmts_vals
def _create_bank_statements(self, stmts_vals, result):
"""Create new bank statements from imported values,
filtering out already imported transactions,
and return data used by the reconciliation widget"""
abs_obj = self.env["account.bank.statement"]
absl_obj = self.env["account.bank.statement.line"]
# Filter out already imported transactions and create statements
statement_ids = []
existing_st_line_ids = {}
for st_vals in stmts_vals:
st_lines_to_create = []
for lvals in st_vals["transactions"]:
existing_line = False
if lvals.get("unique_import_id"):
existing_line = absl_obj.sudo().search(
[
("unique_import_id", "=", lvals["unique_import_id"]),
],
limit=1,
)
# we can only have 1 anyhow because we have a unicity SQL constraint
if existing_line:
existing_st_line_ids[existing_line.id] = True
if "balance_start" in st_vals:
st_vals["balance_start"] += float(lvals["amount"])
else:
st_lines_to_create.append(lvals)
if len(st_lines_to_create) > 0:
# Remove values that won't be used to create records
st_vals.pop("transactions", None)
# Create the statement with lines
st_vals["line_ids"] = [[0, False, line] for line in st_lines_to_create]
statement = abs_obj.create(st_vals)
statement_ids.append(statement.id)
if not statement_ids:
raise UserError(
_(
"You have already imported this file, or this file "
"only contains already imported transactions."
)
)
result["statement_ids"].extend(statement_ids)
# Prepare import feedback
num_ignored = len(existing_st_line_ids)
if num_ignored > 0:
result["notifications"].append(
{
"type": "warning",
"message": _(
"%d transactions had already been imported and were ignored."
)
% num_ignored
if num_ignored > 1
else _("1 transaction had already been imported and was ignored."),
"details": {
"name": _("Already imported items"),
"model": "account.bank.statement.line",
"ids": list(existing_st_line_ids.keys()),
},
}
)

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" ?>
<!--
Copyright 2004-2020 Odoo S.A.
Copyright 2020 Akretion France (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
Licence LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0).
-->
<odoo>
<record id="account_statement_import_form" model="ir.ui.view">
<field name="model">account.statement.import</field>
<field name="arch" type="xml">
<form string="Upload Bank Statements">
<h2>Upload a bank statement file</h2>
<p>Supported formats:</p>
<ul id="statement_format">
<!-- <li>xxx format</li> is added by format-specific modules -->
</ul>
<field name="statement_file" filename="statement_filename" />
<field name="statement_filename" invisible="1" />
<footer>
<button
name="import_file_button"
string="Import"
type="object"
class="btn-primary"
context="{'return_regular_interface_action': True}"
/> <!-- The context may be temporary... waiting for the port of the reconcile interface -->
<button string="Cancel" class="btn-default" special="cancel" />
</footer>
</form>
</field>
</record>
<record id="account_statement_import_action" model="ir.actions.act_window">
<field name="name">Import Bank Statement File</field>
<field name="res_model">account.statement.import</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</odoo>

View File

@@ -1,22 +0,0 @@
# Copyright 2004-2020 Odoo S.A.
# Licence LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0).
from odoo import api, fields, models
class AccountBankStatementImportJounalCreation(models.TransientModel):
_name = "account.bank.statement.import.journal.creation"
_description = "Journal Creation on Bank Statement Import"
journal_id = fields.Many2one(
"account.journal", delegate=True, required=True, ondelete="cascade"
)
def create_journal(self):
""" Create the journal (the record is automatically created in the process of calling this method) and reprocess the statement """
statement_import_transient = self.env["account.bank.statement.import"].browse(
self.env.context["statement_import_transient_id"]
)
return statement_import_transient.with_context(
journal_id=self.journal_id.id
).import_file()

View File

@@ -1,57 +0,0 @@
<?xml version="1.0" ?>
<!--
Copyright 2004-2020 Odoo S.A.
Licence LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0).
-->
<odoo>
<data>
<record
id="account_bank_statement_import_journal_creation_view"
model="ir.ui.view"
>
<field name="name">Journal Creation</field>
<field name="model">account.bank.statement.import.journal.creation</field>
<field name="arch" type="xml">
<form string="Journal Creation">
<p
>The account of the statement you are uploading is not yet recorded in Odoo. In order to proceed with the upload, you need to create a bank journal for this account.</p>
<p
>Just click OK to create the account/journal and finish the upload. If this was a mistake, hit cancel to abort the upload.</p>
<group>
<group>
<field name="name" string="Bank Journal Name" />
<field name="bank_acc_number" readonly="1" />
<field name="bank_id" />
</group>
<group>
<field
name="currency_id"
readonly="1"
groups="base.group_multi_currency"
/>
<field
name="company_id"
groups="base.group_multi_company"
/>
</group>
</group>
<footer>
<button
name="create_journal"
string="OK"
type="object"
class="btn-primary"
/>
<button
string="Cancel"
class="btn-secondary"
special="cancel"
/>
</footer>
</form>
</field>
</record>
</data>
</odoo>

View File

@@ -1,15 +1,15 @@
# Copyright 2004-2020 Odoo S.A.
# Licence LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0).
from odoo import api, fields, models
from odoo import models
class SetupBarBankConfigWizard(models.TransientModel):
class AccountSetupBankManualConfig(models.TransientModel):
_inherit = "account.setup.bank.manual.config"
def validate(self):
"""Default the bank statement source of new bank journals as 'file_import'"""
super(SetupBarBankConfigWizard, self).validate()
super().validate()
if (
self.num_journals_without_account == 0
or self.linked_journal_id.bank_statements_source == "undefined"

View File

@@ -1 +0,0 @@
../../../../account_bank_statement_import

View File

@@ -0,0 +1 @@
../../../../account_statement_import/