[IMP] account_bank_statement_import: black, isort

This commit is contained in:
Pedro M. Baeza
2021-01-07 09:10:51 +01:00
parent b47eb66eb0
commit d126f8192a
15 changed files with 347 additions and 193 deletions

View File

@@ -1,5 +1,3 @@
# -*- encoding: utf-8 -*-
from . import account_bank_statement_import from . import account_bank_statement_import
from . import account_journal from . import account_journal

View File

@@ -1,28 +1,27 @@
# -*- encoding: utf-8 -*-
# Copyright 2004-2020 Odoo S.A. # Copyright 2004-2020 Odoo S.A.
# Licence LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0). # Licence LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0).
{ {
'name': 'Account Bank Statement Import', "name": "Account Bank Statement Import",
'category': 'Accounting/Accounting', "category": "Accounting/Accounting",
'version': '13.0.1.0.0', "version": "13.0.1.0.0",
'license': 'LGPL-3', "license": "LGPL-3",
'depends': ['account'], "depends": ["account"],
'description': """Generic Wizard to Import Bank Statements. "description": """Generic Wizard to Import Bank Statements.
(This module does not include any type of import format.) (This module does not include any type of import format.)
OFX and QIF imports are available in Enterprise version.""", OFX and QIF imports are available in Enterprise version.""",
'author': 'Odoo SA', "author": "Odoo SA",
'data': [ "data": [
'account_bank_statement_import_view.xml', "account_bank_statement_import_view.xml",
'account_import_tip_data.xml', "account_import_tip_data.xml",
'wizard/journal_creation.xml', "wizard/journal_creation.xml",
'views/account_bank_statement_import_templates.xml', "views/account_bank_statement_import_templates.xml",
], ],
'demo': [ "demo": [
'demo/partner_bank.xml', "demo/partner_bank.xml",
], ],
'installable': True, "installable": True,
'auto_install': True, "auto_install": True,
} }

View File

@@ -1,14 +1,14 @@
# -*- coding: utf-8 -*-
# Copyright 2004-2020 Odoo S.A. # Copyright 2004-2020 Odoo S.A.
# Licence LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0). # Licence LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0).
import base64 import base64
import logging
from odoo import api, fields, models, _ from odoo import _, api, fields, models
from odoo.exceptions import UserError from odoo.exceptions import UserError
from odoo.addons.base.models.res_bank import sanitize_account_number from odoo.addons.base.models.res_bank import sanitize_account_number
import logging
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@@ -16,18 +16,27 @@ class AccountBankStatementLine(models.Model):
_inherit = "account.bank.statement.line" _inherit = "account.bank.statement.line"
# Ensure transactions can be imported only once (if the import format provides unique transaction ids) # 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) unique_import_id = fields.Char(string="Import ID", readonly=True, copy=False)
_sql_constraints = [ _sql_constraints = [
('unique_import_id', 'unique (unique_import_id)', 'A bank account transactions can be imported only once !') (
"unique_import_id",
"unique (unique_import_id)",
"A bank account transactions can be imported only once !",
)
] ]
class AccountBankStatementImport(models.TransientModel): class AccountBankStatementImport(models.TransientModel):
_name = 'account.bank.statement.import' _name = "account.bank.statement.import"
_description = 'Import Bank Statement' _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.') 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): def import_file(self):
""" Process the file chosen in the wizard, create bank statement(s) and go to reconciliation. """ """ Process the file chosen in the wizard, create bank statement(s) and go to reconciliation. """
@@ -37,17 +46,31 @@ class AccountBankStatementImport(models.TransientModel):
# Let the appropriate implementation module parse the file and return the required data # 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) # 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: 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)) currency_code, account_number, stmts_vals = self.with_context(
active_id=self.ids[0]
)._parse_file(base64.b64decode(data_file.datas))
# Check raw data # Check raw data
self._check_parsed_data(stmts_vals) self._check_parsed_data(stmts_vals)
# Try to find the currency and journal in odoo # Try to find the currency and journal in odoo
currency, journal = self._find_additional_data(currency_code, account_number) currency, journal = self._find_additional_data(
currency_code, account_number
)
# If no journal found, ask the user about creating one # If no journal found, ask the user about creating one
if not journal: if not journal:
# The active_id is passed in context so the wizard can call import_file again once the journal is created # 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) return self.with_context(
if not journal.default_debit_account_id or not journal.default_credit_account_id: active_id=self.ids[0]
raise UserError(_('You have to set a Default Debit Account and a Default Credit Account for the journal: %s') % (journal.name,)) )._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 # Prepare statement data to be used for bank statements creation
stmts_vals = self._complete_stmts_vals(stmts_vals, journal, account_number) stmts_vals = self._complete_stmts_vals(stmts_vals, journal, account_number)
# Create the bank statements # Create the bank statements
@@ -55,36 +78,37 @@ class AccountBankStatementImport(models.TransientModel):
statement_line_ids_all.extend(statement_line_ids) statement_line_ids_all.extend(statement_line_ids)
notifications_all.extend(notifications) notifications_all.extend(notifications)
# Now that the import worked out, set it as the bank_statements_source of the journal # Now that the import worked out, set it as the bank_statements_source of the journal
if journal.bank_statements_source != 'file_import': if journal.bank_statements_source != "file_import":
# Use sudo() because only 'account.group_account_manager' # Use sudo() because only 'account.group_account_manager'
# has write access on 'account.journal', but 'account.group_account_user' # has write access on 'account.journal', but 'account.group_account_user'
# must be able to import bank statement files # must be able to import bank statement files
journal.sudo().bank_statements_source = 'file_import' journal.sudo().bank_statements_source = "file_import"
# Finally dispatch to reconciliation interface # Finally dispatch to reconciliation interface
return { return {
'type': 'ir.actions.client', "type": "ir.actions.client",
'tag': 'bank_statement_reconciliation_view', "tag": "bank_statement_reconciliation_view",
'context': {'statement_line_ids': statement_line_ids_all, "context": {
'company_ids': self.env.user.company_ids.ids, "statement_line_ids": statement_line_ids_all,
'notifications': notifications_all, "company_ids": self.env.user.company_ids.ids,
"notifications": notifications_all,
}, },
} }
def _journal_creation_wizard(self, currency, account_number): def _journal_creation_wizard(self, currency, account_number):
""" Calls a wizard that allows the user to carry on with journal creation """ """ Calls a wizard that allows the user to carry on with journal creation """
return { return {
'name': _('Journal Creation'), "name": _("Journal Creation"),
'type': 'ir.actions.act_window', "type": "ir.actions.act_window",
'res_model': 'account.bank.statement.import.journal.creation', "res_model": "account.bank.statement.import.journal.creation",
'view_mode': 'form', "view_mode": "form",
'target': 'new', "target": "new",
'context': { "context": {
'statement_import_transient_id': self.env.context['active_id'], "statement_import_transient_id": self.env.context["active_id"],
'default_bank_acc_number': account_number, "default_bank_acc_number": account_number,
'default_name': _('Bank') + ' ' + account_number, "default_name": _("Bank") + " " + account_number,
'default_currency_id': currency and currency.id or False, "default_currency_id": currency and currency.id or False,
'default_type': 'bank', "default_type": "bank",
} },
} }
def _parse_file(self, data_file): def _parse_file(self, data_file):
@@ -111,20 +135,24 @@ class AccountBankStatementImport(models.TransientModel):
-o 'partner_name': string -o 'partner_name': string
-o 'ref': 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 ?')) 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): def _check_parsed_data(self, stmts_vals):
""" Basic and structural verifications """ """ Basic and structural verifications """
if len(stmts_vals) == 0: if len(stmts_vals) == 0:
raise UserError(_('This file doesn\'t contain any statement.')) raise UserError(_("This file doesn't contain any statement."))
no_st_line = True no_st_line = True
for vals in stmts_vals: for vals in stmts_vals:
if vals['transactions'] and len(vals['transactions']) > 0: if vals["transactions"] and len(vals["transactions"]) > 0:
no_st_line = False no_st_line = False
break break
if no_st_line: if no_st_line:
raise UserError(_('This file doesn\'t contain any transaction.')) raise UserError(_("This file doesn't contain any transaction."))
def _check_journal_bank_account(self, journal, account_number): def _check_journal_bank_account(self, journal, account_number):
return journal.bank_account_id.sanitized_acc_number == account_number return journal.bank_account_id.sanitized_acc_number == account_number
@@ -134,29 +162,46 @@ class AccountBankStatementImport(models.TransientModel):
statement and make sure it's consistent. statement and make sure it's consistent.
""" """
company_currency = self.env.company.currency_id company_currency = self.env.company.currency_id
journal_obj = self.env['account.journal'] journal_obj = self.env["account.journal"]
currency = None currency = None
sanitized_account_number = sanitize_account_number(account_number) sanitized_account_number = sanitize_account_number(account_number)
if currency_code: if currency_code:
currency = self.env['res.currency'].search([('name', '=ilike', currency_code)], limit=1) currency = self.env["res.currency"].search(
[("name", "=ilike", currency_code)], limit=1
)
if not currency: if not currency:
raise UserError(_("No currency found matching '%s'.") % currency_code) raise UserError(_("No currency found matching '%s'.") % currency_code)
if currency == company_currency: if currency == company_currency:
currency = False currency = False
journal = journal_obj.browse(self.env.context.get('journal_id', [])) journal = journal_obj.browse(self.env.context.get("journal_id", []))
if account_number: if account_number:
# No bank account on the journal : create one from the account number of the statement # No bank account on the journal : create one from the account number of the statement
if journal and not journal.bank_account_id: if journal and not journal.bank_account_id:
journal.set_bank_account(account_number) journal.set_bank_account(account_number)
# No journal passed to the wizard : try to find one using the account number of the statement # No journal passed to the wizard : try to find one using the account number of the statement
elif not journal: elif not journal:
journal = journal_obj.search([('bank_account_id.sanitized_acc_number', '=', sanitized_account_number)]) 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 # Already a bank account on the journal : check it's the same as on the statement
else: else:
if not self._check_journal_bank_account(journal, sanitized_account_number): if not self._check_journal_bank_account(
raise UserError(_('The account of this statement (%s) is not the same as the journal (%s).') % (account_number, journal.bank_account_id.acc_number)) 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 importing into an existing journal, its currency must be the same as the bank statement
if journal: if journal:
@@ -164,82 +209,134 @@ class AccountBankStatementImport(models.TransientModel):
if currency is None: if currency is None:
currency = journal_currency currency = journal_currency
if currency and currency != journal_currency: if currency and currency != journal_currency:
statement_cur_code = not currency and company_currency.name or currency.name statement_cur_code = (
journal_cur_code = not journal_currency and company_currency.name or journal_currency.name not currency and company_currency.name or 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)) )
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 we couldn't find / can't create a journal, everything is lost
if not journal and not account_number: if not journal and not account_number:
raise UserError(_('Cannot find in which journal import this statement. Please manually select a journal.')) raise UserError(
_(
"Cannot find in which journal import this statement. Please manually select a journal."
)
)
return currency, journal return currency, journal
def _complete_stmts_vals(self, stmts_vals, journal, account_number): def _complete_stmts_vals(self, stmts_vals, journal, account_number):
for st_vals in stmts_vals: for st_vals in stmts_vals:
st_vals['journal_id'] = journal.id st_vals["journal_id"] = journal.id
if not st_vals.get('reference'): if not st_vals.get("reference"):
st_vals['reference'] = " ".join(self.attachment_ids.mapped('name')) st_vals["reference"] = " ".join(self.attachment_ids.mapped("name"))
if st_vals.get('number'): if st_vals.get("number"):
# build the full name like BNK/2016/00135 by just giving the number '135' # 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']) st_vals["name"] = journal.sequence_id.with_context(
del(st_vals['number']) ir_sequence_date=st_vals.get("date")
for line_vals in st_vals['transactions']: ).get_next_char(st_vals["number"])
unique_import_id = line_vals.get('unique_import_id') del st_vals["number"]
for line_vals in st_vals["transactions"]:
unique_import_id = line_vals.get("unique_import_id")
if unique_import_id: if unique_import_id:
sanitized_account_number = sanitize_account_number(account_number) 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 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'): 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 # 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. # reconciliation process will be linked to the bank when the statement is closed.
identifying_string = line_vals.get('account_number') identifying_string = line_vals.get("account_number")
if identifying_string: if identifying_string:
partner_bank = self.env['res.partner.bank'].search([('acc_number', '=', identifying_string)], limit=1) partner_bank = self.env["res.partner.bank"].search(
[("acc_number", "=", identifying_string)], limit=1
)
if partner_bank: if partner_bank:
line_vals['bank_account_id'] = partner_bank.id line_vals["bank_account_id"] = partner_bank.id
line_vals['partner_id'] = partner_bank.partner_id.id line_vals["partner_id"] = partner_bank.partner_id.id
return stmts_vals return stmts_vals
def _create_bank_statements(self, 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 """ """ 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'] BankStatement = self.env["account.bank.statement"]
BankStatementLine = self.env['account.bank.statement.line'] BankStatementLine = self.env["account.bank.statement.line"]
# Filter out already imported transactions and create statements # Filter out already imported transactions and create statements
statement_line_ids = [] statement_line_ids = []
ignored_statement_lines_import_ids = [] ignored_statement_lines_import_ids = []
for st_vals in stmts_vals: for st_vals in stmts_vals:
filtered_st_lines = [] filtered_st_lines = []
for line_vals in st_vals['transactions']: for line_vals in st_vals["transactions"]:
if 'unique_import_id' not in line_vals \ if (
or not line_vals['unique_import_id'] \ "unique_import_id" not in line_vals
or not bool(BankStatementLine.sudo().search([('unique_import_id', '=', line_vals['unique_import_id'])], limit=1)): 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) filtered_st_lines.append(line_vals)
else: else:
ignored_statement_lines_import_ids.append(line_vals['unique_import_id']) ignored_statement_lines_import_ids.append(
if 'balance_start' in st_vals: line_vals["unique_import_id"]
st_vals['balance_start'] += float(line_vals['amount']) )
if "balance_start" in st_vals:
st_vals["balance_start"] += float(line_vals["amount"])
if len(filtered_st_lines) > 0: if len(filtered_st_lines) > 0:
# Remove values that won't be used to create records # Remove values that won't be used to create records
st_vals.pop('transactions', None) st_vals.pop("transactions", None)
# Create the statement # Create the statement
st_vals['line_ids'] = [[0, False, line] for line in filtered_st_lines] st_vals["line_ids"] = [[0, False, line] for line in filtered_st_lines]
statement_line_ids.extend(BankStatement.create(st_vals).line_ids.ids) statement_line_ids.extend(BankStatement.create(st_vals).line_ids.ids)
if len(statement_line_ids) == 0: if len(statement_line_ids) == 0:
raise UserError(_('You already have imported that file.')) raise UserError(_("You already have imported that file."))
# Prepare import feedback # Prepare import feedback
notifications = [] notifications = []
num_ignored = len(ignored_statement_lines_import_ids) num_ignored = len(ignored_statement_lines_import_ids)
if num_ignored > 0: if num_ignored > 0:
notifications += [{ 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."), "type": "warning",
'details': { "message": _(
'name': _('Already imported items'), "%d transactions had already been imported and were ignored."
'model': 'account.bank.statement.line', )
'ids': BankStatementLine.search([('unique_import_id', 'in', ignored_statement_lines_import_ids)]).ids % 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 return statement_line_ids, notifications

View File

@@ -15,10 +15,25 @@
<ul id="statement_format"> <ul id="statement_format">
</ul> </ul>
<field name="attachment_ids" widget="many2many_binary" colspan="2" string="Select Files" nolabel="1"/> <field
name="attachment_ids"
widget="many2many_binary"
colspan="2"
string="Select Files"
nolabel="1"
/>
<footer> <footer>
<button name="import_file" string="Upload" type="object" class="btn-primary" /> <button
<button string="Cancel" class="btn-secondary" special="cancel"/> name="import_file"
string="Upload"
type="object"
class="btn-primary"
/>
<button
string="Cancel"
class="btn-secondary"
special="cancel"
/>
</footer> </footer>
</form> </form>
</field> </field>
@@ -28,7 +43,10 @@
<field name="name">Install Import Format</field> <field name="name">Install Import Format</field>
<field name="res_model">ir.module.module</field> <field name="res_model">ir.module.module</field>
<field name="view_mode">kanban,tree,form</field> <field name="view_mode">kanban,tree,form</field>
<field name="context" eval="{'search_default_name': 'account_bank_statement_import'}"/> <field
name="context"
eval="{'search_default_name': 'account_bank_statement_import'}"
/>
<field name="search_view_id" ref="base.view_module_filter" /> <field name="search_view_id" ref="base.view_module_filter" />
</record> </record>

View File

@@ -1,16 +1,14 @@
# -*- coding: utf-8 -*-
# Copyright 2004-2020 Odoo S.A. # Copyright 2004-2020 Odoo S.A.
# Licence LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0). # Licence LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0).
from odoo import models, api, _ from odoo import _, api, models
class AccountJournal(models.Model): class AccountJournal(models.Model):
_inherit = "account.journal" _inherit = "account.journal"
def _get_bank_statements_available_import_formats(self): def _get_bank_statements_available_import_formats(self):
""" Returns a list of strings representing the supported import formats. """Returns a list of strings representing the supported import formats."""
"""
return [] return []
def __get_bank_statements_available_sources(self): def __get_bank_statements_available_sources(self):
@@ -18,14 +16,14 @@ class AccountJournal(models.Model):
formats_list = self._get_bank_statements_available_import_formats() formats_list = self._get_bank_statements_available_import_formats()
if formats_list: if formats_list:
formats_list.sort() formats_list.sort()
import_formats_str = ', '.join(formats_list) import_formats_str = ", ".join(formats_list)
rslt.append(("file_import", _("Import") + "(" + import_formats_str + ")")) rslt.append(("file_import", _("Import") + "(" + import_formats_str + ")"))
return rslt return rslt
def import_statement(self): def import_statement(self):
"""return action to import bank/cash statements. This button should be called only on journals with type =='bank'""" """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_name = "action_account_bank_statement_import"
[action] = self.env.ref('account_bank_statement_import.%s' % action_name).read() [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 # 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"}")}) action.update({"context": (u"{'journal_id': " + str(self.id) + u"}")})
return action return action

View File

@@ -3,31 +3,30 @@
Copyright 2004-2020 Odoo S.A. Copyright 2004-2020 Odoo S.A.
Licence LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0). Licence LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0).
--> -->
<odoo> <odoo>
<data> <data>
<record id="ofx_partner_bank_1" model="res.partner.bank"> <record id="ofx_partner_bank_1" model="res.partner.bank">
<field name="acc_number">BE68539007547034</field> <field name="acc_number">BE68539007547034</field>
<field name="partner_id" ref="base.res_partner_2"></field> <field name="partner_id" ref="base.res_partner_2" />
<field name="bank_id" ref="base.res_bank_1" /> <field name="bank_id" ref="base.res_bank_1" />
</record> </record>
<record id="ofx_partner_bank_2" model="res.partner.bank"> <record id="ofx_partner_bank_2" model="res.partner.bank">
<field name="acc_number">00987654322</field> <field name="acc_number">00987654322</field>
<field name="partner_id" ref="base.res_partner_3"></field> <field name="partner_id" ref="base.res_partner_3" />
<field name="bank_id" ref="base.res_bank_1" /> <field name="bank_id" ref="base.res_bank_1" />
</record> </record>
<record id="qif_partner_bank_1" model="res.partner.bank"> <record id="qif_partner_bank_1" model="res.partner.bank">
<field name="acc_number">10987654320</field> <field name="acc_number">10987654320</field>
<field name="partner_id" ref="base.res_partner_4"></field> <field name="partner_id" ref="base.res_partner_4" />
<field name="bank_id" ref="base.res_bank_1" /> <field name="bank_id" ref="base.res_bank_1" />
</record> </record>
<record id="qif_partner_bank_2" model="res.partner.bank"> <record id="qif_partner_bank_2" model="res.partner.bank">
<field name="acc_number">10987654322</field> <field name="acc_number">10987654322</field>
<field name="partner_id" ref="base.res_partner_3"></field> <field name="partner_id" ref="base.res_partner_3" />
<field name="bank_id" ref="base.res_bank_1" /> <field name="bank_id" ref="base.res_bank_1" />
</record> </record>

View File

@@ -3,22 +3,25 @@
Licence LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0). Licence LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0).
*/ */
odoo.define('account_bank_statement_import.import', function (require) { odoo.define("account_bank_statement_import.import", function (require) {
"use strict"; "use strict";
var core = require('web.core'); var core = require("web.core");
var BaseImport = require('base_import.import'); var BaseImport = require("base_import.import");
var _t = core._t; var _t = core._t;
BaseImport.DataImport.include({ BaseImport.DataImport.include({
renderImportLink: function () { renderImportLink: function () {
this._super(); this._super();
if (this.res_model == 'account.bank.statement') { 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.$(".import-link").prop({
this.$(".template-import").removeClass('d-none'); 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,8 +1,15 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<odoo> <odoo>
<template id="assets_backend" name="account_bank_statement_import assets" inherit_id="web.assets_backend"> <template
id="assets_backend"
name="account_bank_statement_import assets"
inherit_id="web.assets_backend"
>
<xpath expr="." position="inside"> <xpath expr="." position="inside">
<script type="text/javascript" src="/account_bank_statement_import/static/src/js/account_bank_statement_import.js"></script> <script
type="text/javascript"
src="/account_bank_statement_import/static/src/js/account_bank_statement_import.js"
/>
</xpath> </xpath>
</template> </template>
</odoo> </odoo>

View File

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

View File

@@ -6,13 +6,18 @@
<odoo> <odoo>
<data> <data>
<record id="account_bank_statement_import_journal_creation_view" model="ir.ui.view"> <record
id="account_bank_statement_import_journal_creation_view"
model="ir.ui.view"
>
<field name="name">Journal Creation</field> <field name="name">Journal Creation</field>
<field name="model">account.bank.statement.import.journal.creation</field> <field name="model">account.bank.statement.import.journal.creation</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Journal Creation"> <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
<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> >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>
<group> <group>
<field name="name" string="Bank Journal Name" /> <field name="name" string="Bank Journal Name" />
@@ -20,13 +25,29 @@
<field name="bank_id" /> <field name="bank_id" />
</group> </group>
<group> <group>
<field name="currency_id" readonly="1" groups="base.group_multi_currency"/> <field
<field name="company_id" groups="base.group_multi_company"/> name="currency_id"
readonly="1"
groups="base.group_multi_currency"
/>
<field
name="company_id"
groups="base.group_multi_company"
/>
</group> </group>
</group> </group>
<footer> <footer>
<button name="create_journal" string="OK" type="object" class="btn-primary"/> <button
<button string="Cancel" class="btn-secondary" special="cancel"/> name="create_journal"
string="OK"
type="object"
class="btn-primary"
/>
<button
string="Cancel"
class="btn-secondary"
special="cancel"
/>
</footer> </footer>
</form> </form>
</field> </field>

View File

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

View File

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

View File

@@ -0,0 +1,6 @@
import setuptools
setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)