[FIX] account_statement_import_online: further improvements.

This commit is contained in:
Ronald Portier
2021-07-14 11:40:50 +02:00
parent 0578dadc9c
commit 8dae9bb4df
13 changed files with 126 additions and 69 deletions

View File

@@ -21,6 +21,7 @@
"security/ir.model.access.csv", "security/ir.model.access.csv",
"security/online_bank_statement_provider.xml", "security/online_bank_statement_provider.xml",
"wizards/online_bank_statement_pull_wizard.xml", "wizards/online_bank_statement_pull_wizard.xml",
"views/actions.xml",
"views/account_journal.xml", "views/account_journal.xml",
"views/online_bank_statement_provider.xml", "views/online_bank_statement_provider.xml",
], ],

View File

@@ -16,12 +16,16 @@ class AccountJournal(models.Model):
selection=lambda self: self.env[ selection=lambda self: self.env[
"account.journal" "account.journal"
]._selection_online_bank_statement_provider(), ]._selection_online_bank_statement_provider(),
help="Select the type of service provider (a model)",
) )
online_bank_statement_provider_id = fields.Many2one( online_bank_statement_provider_id = fields.Many2one(
string="Statement Provider", string="Statement Provider",
comodel_name="online.bank.statement.provider", comodel_name="online.bank.statement.provider",
ondelete="restrict", ondelete="restrict",
copy=False, copy=False,
help="Select the actual instance of a configured provider (a record).\n"
"Selecting a type of provider will automatically create a provider"
" record linked to this journal.",
) )
def __get_bank_statements_available_sources(self): def __get_bank_statements_available_sources(self):
@@ -37,12 +41,14 @@ class AccountJournal(models.Model):
@api.model @api.model
def values_online_bank_statement_provider(self): def values_online_bank_statement_provider(self):
"""Return values for provider type selection in the form view."""
res = self.env["online.bank.statement.provider"]._get_available_services() res = self.env["online.bank.statement.provider"]._get_available_services()
if self.user_has_groups("base.group_no_one"): if self.user_has_groups("base.group_no_one"):
res += [("dummy", "Dummy")] res += [("dummy", "Dummy")]
return res return res
def _update_online_bank_statement_provider_id(self): def _update_online_bank_statement_provider_id(self):
"""Keep provider synchronized with journal."""
OnlineBankStatementProvider = self.env["online.bank.statement.provider"] OnlineBankStatementProvider = self.env["online.bank.statement.provider"]
for journal in self.filtered("id"): for journal in self.filtered("id"):
provider_id = journal.online_bank_statement_provider_id provider_id = journal.online_bank_statement_provider_id

View File

@@ -24,7 +24,7 @@ class OnlineBankStatementProvider(models.Model):
_description = "Online Bank Statement Provider" _description = "Online Bank Statement Provider"
company_id = fields.Many2one(related="journal_id.company_id", store=True) company_id = fields.Many2one(related="journal_id.company_id", store=True)
active = fields.Boolean() active = fields.Boolean(default=True)
name = fields.Char(string="Name", compute="_compute_name", store=True) name = fields.Char(string="Name", compute="_compute_name", store=True)
journal_id = fields.Many2one( journal_id = fields.Many2one(
comodel_name="account.journal", comodel_name="account.journal",
@@ -122,12 +122,11 @@ class OnlineBankStatementProvider(models.Model):
def values_service(self): def values_service(self):
return self._get_available_services() return self._get_available_services()
@api.depends("service") @api.depends("service", "journal_id.name")
def _compute_name(self): def _compute_name(self):
"""We can have multiple providers/journals for the same service."""
for provider in self: for provider in self:
provider.name = list( provider.name = " ".join([provider.journal_id.name, provider.service])
filter(lambda x: x[0] == provider.service, self._selection_service())
)[0][1]
@api.depends("active", "interval_type", "interval_number") @api.depends("active", "interval_type", "interval_number")
def _compute_update_schedule(self): def _compute_update_schedule(self):

View File

@@ -1,3 +1,4 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from . import test_account_bank_statement_import_online from . import test_account_bank_statement_import_online
from . import test_account_journal

View File

@@ -48,8 +48,15 @@ class TestAccountBankAccountStatementImportOnline(common.TransactionCase):
journal_form.save() journal_form.save()
self.assertTrue(journal.online_bank_statement_provider_id) self.assertTrue(journal.online_bank_statement_provider_id)
save_provider_id = journal.online_bank_statement_provider_id.id
journal.unlink() journal.unlink()
self.assertFalse(self.OnlineBankStatementProvider.search([])) self.assertFalse(
self.OnlineBankStatementProvider.search(
[
("id", "=", save_provider_id),
]
)
)
def test_source_change_cleanup(self): def test_source_change_cleanup(self):
journal = self.AccountJournal.create( journal = self.AccountJournal.create(
@@ -61,13 +68,25 @@ class TestAccountBankAccountStatementImportOnline(common.TransactionCase):
journal_form.save() journal_form.save()
self.assertTrue(journal.online_bank_statement_provider_id) self.assertTrue(journal.online_bank_statement_provider_id)
save_provider_id = journal.online_bank_statement_provider_id.id
# Stuff should not change when doing unrelated write.
journal.write({"code": "BIGBANK"})
self.assertTrue(journal.online_bank_statement_provider_id)
self.assertEqual(journal.online_bank_statement_provider_id.id, save_provider_id)
with common.Form(journal) as journal_form: with common.Form(journal) as journal_form:
journal_form.bank_statements_source = "undefined" journal_form.bank_statements_source = "undefined"
journal_form.save() journal_form.save()
self.assertFalse(journal.online_bank_statement_provider_id) self.assertFalse(journal.online_bank_statement_provider_id)
self.assertFalse(self.OnlineBankStatementProvider.search([])) self.assertFalse(
self.OnlineBankStatementProvider.search(
[
("id", "=", save_provider_id),
]
)
)
def test_pull_mode_daily(self): def test_pull_mode_daily(self):
journal = self.AccountJournal.create( journal = self.AccountJournal.create(
@@ -396,13 +415,13 @@ class TestAccountBankAccountStatementImportOnline(common.TransactionCase):
"online_bank_statement_provider": "dummy", "online_bank_statement_provider": "dummy",
} }
) )
wizard = self.OnlineBankStatementPullWizard.with_context( vals = self.OnlineBankStatementPullWizard.with_context(
active_model="account.journal", active_id=journal.id active_model="account.journal", active_id=journal.id
).create( ).default_get(fields_list=["provider_ids"])
{"date_since": self.now - relativedelta(hours=1), "date_until": self.now} vals["date_since"] = self.now - relativedelta(hours=1)
) vals["date_until"] = self.now
wizard = self.OnlineBankStatementPullWizard.create(vals)
self.assertTrue(wizard.provider_ids) self.assertTrue(wizard.provider_ids)
wizard.action_pull() wizard.action_pull()
self.assertTrue( self.assertTrue(
self.AccountBankStatement.search([("journal_id", "=", journal.id)]) self.AccountBankStatement.search([("journal_id", "=", journal.id)])

View File

@@ -0,0 +1,22 @@
# Copyright 2021 Therp BV (https://therp.nl).
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from mock import patch
from odoo.tests import common
class TestAccountJournal(common.TransactionCase):
"""Test some functions adde d to account.journal model."""
def setUp(self):
super().setUp()
self.AccountJournal = self.env["account.journal"]
def test_values_online_bank_statement_provider(self):
"""Check method to retrieve provider types."""
# Make sure the users seems to have the group_no_one.
with patch.object(
self.AccountJournal.__class__, "user_has_groups", return_value=True
):
values = self.AccountJournal.values_online_bank_statement_provider()
self.assertIn("dummy", [entry[0] for entry in values])

View File

@@ -2,6 +2,7 @@
<!-- <!--
Copyright 2019-2020 Brainbean Apps (https://brainbeanapps.com) Copyright 2019-2020 Brainbean Apps (https://brainbeanapps.com)
Copyright 2019-2020 Dataplug (https://dataplug.io) Copyright 2019-2020 Dataplug (https://dataplug.io)
Copyright 2021 Therp BV (https://therp.nl).
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
--> -->
<odoo> <odoo>
@@ -48,27 +49,15 @@
</group> </group>
</page> </page>
<xpath expr="/form/sheet" position="before"> <xpath expr="/form/sheet" position="before">
<header> <header>
<button <button
type="action" type="action"
name="%(online_bank_statement_pull_wizard_action)d" name="%(action_online_bank_statements_pull_wizard)d"
attrs="{'invisible': ['|', ('bank_statements_source', '!=', 'online'), ('online_bank_statement_provider', '=', False)]}" attrs="{'invisible': [('online_bank_statement_provider', '=', False)]}"
string="Pull Online Bank Statement" string="Pull Online Bank Statement"
/> />
</header> </header>
</xpath> </xpath>
</field> </field>
</record> </record>
<record
id="action_online_bank_statements_pull_wizard"
model="ir.actions.act_window"
>
<field name="name">Online Bank Statements Pull Wizard</field>
<field name="res_model">online.bank.statement.pull.wizard</field>
<field name="target">new</field>
<field name="view_mode">form</field>
<field name="binding_model_id" ref="account.model_account_journal" />
<field name="binding_view_types">list</field>
<field name="groups_id" eval="[(4, ref('account.group_account_user'))]" />
</record>
</odoo> </odoo>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright 2021 Therp BV (https://therp.nl).
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
-->
<odoo>
<record
id="action_online_bank_statements_pull_wizard"
model="ir.actions.act_window"
>
<field name="name">Online Bank Statements Pull Wizard</field>
<field name="res_model">online.bank.statement.pull.wizard</field>
<field name="target">new</field>
<field name="view_mode">form</field>
<field name="binding_model_id" ref="account.model_account_journal" />
<field name="binding_view_types">list</field>
<field name="groups_id" eval="[(4, ref('account.group_account_user'))]" />
</record>
</odoo>

View File

@@ -17,7 +17,7 @@
domain="[('active', '=', False)]" domain="[('active', '=', False)]"
/> />
<group name="groupby"> <group name="groupby">
<filter <filter
name="service_groupby" name="service_groupby"
string="Service" string="Service"
context="{'group_by': 'service'}" context="{'group_by': 'service'}"
@@ -46,13 +46,13 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Online Bank Statement Provider"> <form string="Online Bank Statement Provider">
<sheet> <sheet>
<widget <widget
name="web_ribbon" name="web_ribbon"
title="Archived" title="Archived"
bg_color="bg-danger" bg_color="bg-danger"
attrs="{'invisible': [('active', '=', True)]}" attrs="{'invisible': [('active', '=', True)]}"
/> />
<group name="main" col="2"> <group name="main" col="2">
<group name="params"> <group name="params">
<field name="journal_id" /> <field name="journal_id" />
<field name="currency_id" /> <field name="currency_id" />
@@ -61,25 +61,25 @@
name="company_id" name="company_id"
groups="base.group_multi_company" groups="base.group_multi_company"
/> />
<field <field
name="service" name="service"
widget="dynamic_dropdown" widget="dynamic_dropdown"
values="values_service" values="values_service"
/> />
<field name="active" invisible="1" /> <field name="active" invisible="1" />
</group> </group>
<group name="pull" string="Scheduled Pull"> <group name="pull" string="Scheduled Pull">
<label for="interval_number" /> <label for="interval_number" />
<div class="o_row" id="interval_number"> <div class="o_row" id="interval_number">
<field name="interval_number" class="ml8" /> <field name="interval_number" class="ml8" />
<field name="interval_type" /> <field name="interval_type" />
</div> </div>
<field name="next_run" /> <field name="next_run" />
</group> </group>
<group name="configuration" string="Configuration"> <group name="configuration" string="Configuration">
<field name="statement_creation_mode" /> <field name="statement_creation_mode" />
<field name="tz" /> <field name="tz" />
</group> </group>
</group> </group>
</sheet> </sheet>
<div class="oe_chatter"> <div class="oe_chatter">
@@ -88,12 +88,12 @@
</div> </div>
</form> </form>
</field> </field>
</record> </record>
<record id="online_bank_statement_provider_action" model="ir.actions.act_window"> <record id="online_bank_statement_provider_action" model="ir.actions.act_window">
<field name="name">Online Bank Statement Providers</field> <field name="name">Online Bank Statement Providers</field>
<field name="res_model">online.bank.statement.provider</field> <field name="res_model">online.bank.statement.provider</field>
<field name="view_mode">tree,form</field> <field name="view_mode">tree,form</field>
</record> </record>
<menuitem <menuitem

View File

@@ -19,6 +19,8 @@ class OnlineBankStatementPullWizard(models.TransientModel):
required=True, required=True,
default=fields.Datetime.now, default=fields.Datetime.now,
) )
# The link to providers is Many2many, because you can select multiple
# journals for the action to pull statements.
provider_ids = fields.Many2many( provider_ids = fields.Many2many(
string="Providers", string="Providers",
comodel_name="online.bank.statement.provider", comodel_name="online.bank.statement.provider",
@@ -29,25 +31,25 @@ class OnlineBankStatementPullWizard(models.TransientModel):
@api.model @api.model
def default_get(self, fields_list): def default_get(self, fields_list):
"""Retrieve providers from the journals for which this wizard is launched."""
res = super().default_get(fields_list) res = super().default_get(fields_list)
journal_ids = []
if self.env.context.get("active_model") == "account.journal": if self.env.context.get("active_model") == "account.journal":
if self.env.context.get("active_ids"): if self.env.context.get("active_ids"):
journals = self.env["account.journal"].browse( journal_ids = self.env.context["active_ids"]
self.env.context["active_ids"]
)
res["provider_ids"] = journals.online_bank_statement_provider_id.ids
elif self.env.context.get("active_id"): elif self.env.context.get("active_id"):
journal = self.env["account.journal"].browse( journal_ids = [self.env.context["active_id"]]
self.env.context["active_id"] if journal_ids:
) journals = self.env["account.journal"].browse(journal_ids)
res["provider_ids"] = [journal.online_bank_statement_provider_id.id] res["provider_ids"] = [journals.online_bank_statement_provider_id.id]
return res return res
def action_pull(self): def action_pull(self):
"""Pull statements from providers and then show list of statements."""
self.ensure_one() self.ensure_one()
self.with_context( self.with_context(active_test=False).provider_ids._pull(
active_test=False, self.date_since, self.date_until
).provider_ids._pull(self.date_since, self.date_until) )
action = self.env.ref("account.action_bank_statement_tree").sudo().read([])[0] action = self.env.ref("account.action_bank_statement_tree").sudo().read([])[0]
if len(self.provider_ids) == 1: if len(self.provider_ids) == 1:
action["context"] = { action["context"] = {

View File

@@ -11,9 +11,14 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<form> <form>
<group name="main"> <group name="main">
<field name="provider_ids" widget="many2many_tags" required="1" /> <field
<field name="date_since" /> name="provider_ids"
<field name="date_until" /> widget="many2many_tags"
required="1"
options="{'create': false, 'create_edit': false}"
/>
<field name="date_since" />
<field name="date_until" />
</group> </group>
<footer> <footer>
<button <button
@@ -29,11 +34,4 @@
</field> </field>
</record> </record>
<record id="online_bank_statement_pull_wizard_action" model="ir.actions.act_window">
<field name="name">Pull Online Bank Statement</field>
<field name="res_model">online.bank.statement.pull.wizard</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</odoo> </odoo>

View File

@@ -8,7 +8,7 @@
ref="account_statement_import_online.online_bank_statement_provider_form" ref="account_statement_import_online.online_bank_statement_provider_form"
/> />
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//page[@name='configuration']" position="inside"> <xpath expr="//group[@name='main']" position="inside">
<group name="ponto" attrs="{'invisible':[('service','!=','ponto')]}"> <group name="ponto" attrs="{'invisible':[('service','!=','ponto')]}">
<field name="username" string="Login" /> <field name="username" string="Login" />
<field name="password" string="Secret Key" /> <field name="password" string="Secret Key" />

View File

@@ -1 +1,2 @@
# See https://github.com/OCA/odoo-community.org/blob/master/website/Contribution/CONTRIBUTING.rst#oca_dependencies-txt # See https://github.com/OCA/odoo-community.org/blob/master/website/Contribution/CONTRIBUTING.rst#oca_dependencies-txt
web