[IMP] account_bank_statement_import_move_line: black, isort, prettier

This commit is contained in:
João Marques
2020-11-02 12:16:03 +00:00
committed by Luis D. Lafaurie
parent 24346eb062
commit 77762b8c86
6 changed files with 225 additions and 195 deletions

View File

@@ -2,23 +2,20 @@
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html # License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
{ {
'name': 'Bank statement import move lines', "name": "Bank statement import move lines",
'version': '12.0.1.0.0', "version": "12.0.1.0.0",
'category': 'Accounting', "category": "Accounting",
'summary': 'Import journal items into bank statement', "summary": "Import journal items into bank statement",
'author': 'Tecnativa, ' "author": "Tecnativa, " "Odoo Community Association (OCA)",
'Odoo Community Association (OCA)', "maintainers": ["pedrobaeza"],
'maintainers': ['pedrobaeza'], "website": "https://github.com/OCA/bank-statement-import",
'website': 'https://github.com/OCA/bank-statement-import', "depends": ["account",],
'depends': [ "data": [
'account', "wizards/account_statement_line_create_view.xml",
"views/account_bank_statement_view.xml",
], ],
'data': [ "license": "AGPL-3",
'wizards/account_statement_line_create_view.xml', "development_status": "Production/Stable",
'views/account_bank_statement_view.xml', "installable": True,
], "auto_install": False,
'license': 'AGPL-3',
'development_status': 'Production/Stable',
'installable': True,
'auto_install': False,
} }

View File

@@ -5,7 +5,7 @@ from odoo import api, models
class AccountMoveLine(models.Model): class AccountMoveLine(models.Model):
_inherit = 'account.move.line' _inherit = "account.move.line"
@api.multi @api.multi
def _prepare_statement_line_vals(self, statement): def _prepare_statement_line_vals(self, statement):
@@ -16,20 +16,20 @@ class AccountMoveLine(models.Model):
elif self.credit > 0: elif self.credit > 0:
amount = -self.credit amount = -self.credit
vals = { vals = {
'name': self.name or '?', "name": self.name or "?",
'amount': amount, "amount": amount,
'partner_id': self.partner_id.id, "partner_id": self.partner_id.id,
'statement_id': statement.id, "statement_id": statement.id,
'ref': self.ref, "ref": self.ref,
'date': self.date_maturity, "date": self.date_maturity,
'amount_currency': self.amount_currency, "amount_currency": self.amount_currency,
'currency_id': self.currency_id.id, "currency_id": self.currency_id.id,
} }
return vals return vals
@api.multi @api.multi
def create_statement_line_from_move_line(self, statement): def create_statement_line_from_move_line(self, statement):
abslo = self.env['account.bank.statement.line'] abslo = self.env["account.bank.statement.line"]
for mline in self: for mline in self:
abslo.create(mline._prepare_statement_line_vals(statement)) abslo.create(mline._prepare_statement_line_vals(statement))
return return

View File

@@ -1,64 +1,75 @@
# Copyright 2017 Tecnativa - Luis M. Ontalba # Copyright 2017 Tecnativa - Luis M. Ontalba
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0 # License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0
from odoo.tests import common
from odoo import fields from odoo import fields
from odoo.tests import common
class TestAccountBankStatementImportMoveLine(common.SavepointCase): class TestAccountBankStatementImportMoveLine(common.SavepointCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
super(TestAccountBankStatementImportMoveLine, cls).setUpClass() super(TestAccountBankStatementImportMoveLine, cls).setUpClass()
cls.account_type = cls.env['account.account.type'].create({ cls.account_type = cls.env["account.account.type"].create(
'name': 'Test Account Type'}) {"name": "Test Account Type"}
cls.a_receivable = cls.env['account.account'].create({ )
'code': 'TAA', cls.a_receivable = cls.env["account.account"].create(
'name': 'Test Receivable Account', {
'internal_type': 'receivable', "code": "TAA",
'user_type_id': cls.account_type.id, "name": "Test Receivable Account",
}) "internal_type": "receivable",
cls.partner = cls.env['res.partner'].create({ "user_type_id": cls.account_type.id,
'name': 'Test Partner 2', }
'parent_id': False, )
}) cls.partner = cls.env["res.partner"].create(
cls.journal = cls.env['account.journal'].create({ {"name": "Test Partner 2", "parent_id": False,}
'name': 'Test Journal', )
'type': 'bank', cls.journal = cls.env["account.journal"].create(
}) {"name": "Test Journal", "type": "bank",}
cls.invoice = cls.env['account.invoice'].create({ )
'name': 'Test Invoice 3', cls.invoice = cls.env["account.invoice"].create(
'partner_id': cls.partner.id, {
'type': 'out_invoice', "name": "Test Invoice 3",
'journal_id': cls.journal.id, "partner_id": cls.partner.id,
'invoice_line_ids': [(0, 0, { "type": "out_invoice",
'account_id': cls.a_receivable.id, "journal_id": cls.journal.id,
'name': 'Test line', "invoice_line_ids": [
'quantity': 1.0, (
'price_unit': 100.00, 0,
})], 0,
}) {
cls.statement = cls.env['account.bank.statement'].create({ "account_id": cls.a_receivable.id,
'journal_id': cls.journal.id}) "name": "Test line",
"quantity": 1.0,
"price_unit": 100.00,
},
)
],
}
)
cls.statement = cls.env["account.bank.statement"].create(
{"journal_id": cls.journal.id}
)
def test_global(self): def test_global(self):
self.invoice.action_invoice_open() self.invoice.action_invoice_open()
self.assertTrue(self.invoice.move_id) self.assertTrue(self.invoice.move_id)
self.invoice.move_id.post() self.invoice.move_id.post()
wizard_o = self.env['account.statement.line.create'] wizard_o = self.env["account.statement.line.create"]
context = wizard_o._context.copy() context = wizard_o._context.copy()
context.update({ context.update(
'active_model': 'account.bank.statement', {"active_model": "account.bank.statement", "active_id": self.statement.id,}
'active_id': self.statement.id, )
}) wizard = wizard_o.with_context(context).create(
wizard = wizard_o.with_context(context).create({ {
'statement_id': self.statement.id, "statement_id": self.statement.id,
'partner_id': self.partner.id, "partner_id": self.partner.id,
'journal_ids': [(4, self.journal.id)], "journal_ids": [(4, self.journal.id)],
'allow_blocked': True, "allow_blocked": True,
'date_type': 'move', "date_type": "move",
'move_date': fields.Date.today(), "move_date": fields.Date.today(),
'invoice': False, "invoice": False,
}) }
)
wizard.populate() wizard.populate()
self.assertEqual(len(wizard.move_line_ids), 1) self.assertEqual(len(wizard.move_line_ids), 1)
line = wizard.move_line_ids line = wizard.move_line_ids

View File

@@ -1,20 +1,20 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8" ?>
<odoo> <odoo>
<record id="view_bank_statement_form" model="ir.ui.view"> <record id="view_bank_statement_form" model="ir.ui.view">
<field name="name">account.bank.statement.form.population</field> <field name="name">account.bank.statement.form.population</field>
<field name="model">account.bank.statement</field> <field name="model">account.bank.statement</field>
<field name="inherit_id" ref="account.view_bank_statement_form"/> <field name="inherit_id" ref="account.view_bank_statement_form" />
<field name="arch" type="xml"> <field name="arch" type="xml">
<field name="all_lines_reconciled" position="after"> <field name="all_lines_reconciled" position="after">
<button name="%(account_statement_line_create_action)d" <button
string="Import Journal Items" type="action" name="%(account_statement_line_create_action)d"
class="oe_highlight" string="Import Journal Items"
attrs="{'invisible':[('state', '!=', 'open')]}" type="action"
groups="account.group_account_user"/> class="oe_highlight"
attrs="{'invisible':[('state', '!=', 'open')]}"
groups="account.group_account_user"
/>
</field> </field>
</field> </field>
</record> </record>
</odoo> </odoo>

View File

@@ -5,115 +5,127 @@ from odoo import _, api, fields, models
class AccountStatementLineCreate(models.TransientModel): class AccountStatementLineCreate(models.TransientModel):
_name = 'account.statement.line.create' _name = "account.statement.line.create"
_description = 'Wizard to create statement lines' _description = "Wizard to create statement lines"
statement_id = fields.Many2one( statement_id = fields.Many2one("account.bank.statement", string="Bank Statement")
'account.bank.statement', string='Bank Statement') partner_id = fields.Many2one(
partner_id = fields.Many2one('res.partner', string='Partner Related', "res.partner",
domain=['|', ('parent_id', '=', False), string="Partner Related",
('is_company', '=', True)]) domain=["|", ("parent_id", "=", False), ("is_company", "=", True)],
journal_ids = fields.Many2many( )
'account.journal', string='Journals Filter') journal_ids = fields.Many2many("account.journal", string="Journals Filter")
target_move = fields.Selection([ target_move = fields.Selection(
('posted', 'All Posted Entries'), [("posted", "All Posted Entries"), ("all", "All Entries"),],
('all', 'All Entries'), string="Target Moves",
], string='Target Moves') )
allow_blocked = fields.Boolean( allow_blocked = fields.Boolean(string="Allow Litigation Move Lines")
string='Allow Litigation Move Lines') invoice = fields.Boolean(string="Linked to an Invoice or Refund")
invoice = fields.Boolean( date_type = fields.Selection(
string='Linked to an Invoice or Refund') [("due", "Due Date"), ("move", "Move Date"),],
date_type = fields.Selection([ string="Type of Date Filter",
('due', 'Due Date'), required=True,
('move', 'Move Date'), )
], string="Type of Date Filter", required=True) due_date = fields.Date(string="Due Date", default=fields.Date.context_today)
due_date = fields.Date(string="Due Date", move_date = fields.Date(string="Move Date", default=fields.Date.context_today)
default=fields.Date.context_today) move_line_ids = fields.Many2many("account.move.line", string="Move Lines")
move_date = fields.Date(string='Move Date',
default=fields.Date.context_today)
move_line_ids = fields.Many2many(
'account.move.line', string='Move Lines')
@api.model @api.model
def default_get(self, field_list): def default_get(self, field_list):
res = super().default_get(field_list) res = super().default_get(field_list)
active_model = self.env.context.get('active_model') active_model = self.env.context.get("active_model")
if active_model == 'account.bank.statement': if active_model == "account.bank.statement":
statement = self.env[active_model].browse( statement = (
self.env.context.get('active_id')).exists() self.env[active_model]
.browse(self.env.context.get("active_id"))
.exists()
)
if statement: if statement:
res.update({ res.update(
'target_move': 'posted', {
'date_type': 'due', "target_move": "posted",
'invoice': True, "date_type": "due",
'statement_id': statement.id, "invoice": True,
}) "statement_id": statement.id,
}
)
return res return res
@api.multi @api.multi
def _prepare_move_line_domain(self): def _prepare_move_line_domain(self):
self.ensure_one() self.ensure_one()
domain = [('reconciled', '=', False), domain = [
('account_id.internal_type', 'in', ('payable', ("reconciled", "=", False),
'receivable')), ("account_id.internal_type", "in", ("payable", "receivable")),
('company_id', '=', self.env.user.company_id.id)] ("company_id", "=", self.env.user.company_id.id),
]
if self.journal_ids: if self.journal_ids:
domain += [('journal_id', 'in', self.journal_ids.ids)] domain += [("journal_id", "in", self.journal_ids.ids)]
else: else:
journals = self.env['account.journal'].search([]) journals = self.env["account.journal"].search([])
domain += [('journal_id', 'in', journals.ids)] domain += [("journal_id", "in", journals.ids)]
if self.partner_id: if self.partner_id:
domain += [('partner_id', '=', self.partner_id.id)] domain += [("partner_id", "=", self.partner_id.id)]
if self.target_move == 'posted': if self.target_move == "posted":
domain += [('move_id.state', '=', 'posted')] domain += [("move_id.state", "=", "posted")]
if not self.allow_blocked: if not self.allow_blocked:
domain += [('blocked', '!=', True)] domain += [("blocked", "!=", True)]
if self.date_type == 'due': if self.date_type == "due":
domain += [ domain += [
'|', "|",
('date_maturity', '<=', self.due_date), ("date_maturity", "<=", self.due_date),
('date_maturity', '=', False)] ("date_maturity", "=", False),
elif self.date_type == 'move': ]
domain.append(('date', '<=', self.move_date)) elif self.date_type == "move":
domain.append(("date", "<=", self.move_date))
if self.invoice: if self.invoice:
domain.append(('invoice_id', '!=', False)) domain.append(("invoice_id", "!=", False))
paylines = self.env['account.payment'].search([ paylines = self.env["account.payment"].search(
('state', 'in', ('draft', 'posted', 'sent')), [
('move_line_ids', '!=', False)]) ("state", "in", ("draft", "posted", "sent")),
("move_line_ids", "!=", False),
]
)
if paylines: if paylines:
move_in_payment_ids = paylines.mapped('move_line_ids.id') move_in_payment_ids = paylines.mapped("move_line_ids.id")
domain += [('id', 'not in', move_in_payment_ids)] domain += [("id", "not in", move_in_payment_ids)]
return domain return domain
@api.multi @api.multi
def populate(self): def populate(self):
domain = self._prepare_move_line_domain() domain = self._prepare_move_line_domain()
lines = self.env['account.move.line'].search(domain) lines = self.env["account.move.line"].search(domain)
self.move_line_ids = False self.move_line_ids = False
self.move_line_ids = lines self.move_line_ids = lines
action = { action = {
'name': _('Select Move Lines to Create Statement'), "name": _("Select Move Lines to Create Statement"),
'type': 'ir.actions.act_window', "type": "ir.actions.act_window",
'res_model': 'account.statement.line.create', "res_model": "account.statement.line.create",
'view_mode': 'form', "view_mode": "form",
'target': 'new', "target": "new",
'res_id': self.id, "res_id": self.id,
'context': self._context, "context": self._context,
} }
return action return action
@api.onchange( @api.onchange(
'date_type', 'move_date', 'due_date', 'journal_ids', 'invoice', "date_type",
'target_move', 'allow_blocked', 'partner_id') "move_date",
"due_date",
"journal_ids",
"invoice",
"target_move",
"allow_blocked",
"partner_id",
)
def move_line_filters_change(self): def move_line_filters_change(self):
domain = self._prepare_move_line_domain() domain = self._prepare_move_line_domain()
res = {'domain': {'move_line_ids': domain}} res = {"domain": {"move_line_ids": domain}}
return res return res
@api.multi @api.multi
def create_statement_lines(self): def create_statement_lines(self):
for rec in self: for rec in self:
if rec.move_line_ids and rec.statement_id: if rec.move_line_ids and rec.statement_id:
rec.move_line_ids.create_statement_line_from_move_line( rec.move_line_ids.create_statement_line_from_move_line(rec.statement_id)
rec.statement_id)
return True return True

View File

@@ -1,63 +1,73 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8" ?>
<odoo> <odoo>
<record id="account_statement_line_create_view_form" model="ir.ui.view"> <record id="account_statement_line_create_view_form" model="ir.ui.view">
<field name="name">account_statement_line_create_form</field> <field name="name">account_statement_line_create_form</field>
<field name="model">account.statement.line.create</field> <field name="model">account.statement.line.create</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Choose Move Lines Filter Options"> <form string="Choose Move Lines Filter Options">
<group name="main"> <group name="main">
<field name="statement_id" invisible="1"/> <field name="statement_id" invisible="1" />
<field name="partner_id"/> <field name="partner_id" />
<field name="date_type"/> <field name="date_type" />
<field name="move_date" <field
attrs="{'required': [('date_type', '=', 'move')], name="move_date"
'invisible': [('date_type', '!=', 'move')]}"/> attrs="{'required': [('date_type', '=', 'move')],
<field name="due_date" 'invisible': [('date_type', '!=', 'move')]}"
attrs="{'required': [('date_type', '=', 'due')], />
'invisible': [('date_type', '!=', 'due')]}"/> <field
<field name="journal_ids" widget="many2many_tags" name="due_date"
placeholder="Keep empty for using all journals"/> attrs="{'required': [('date_type', '=', 'due')],
<field name="target_move" widget="radio"/> 'invisible': [('date_type', '!=', 'due')]}"
<field name="invoice"/> />
<field name="allow_blocked"/> <field
<label for="populate" string="Click on Add All Move Lines to auto-select the move lines matching the above criteria or click on Add an item to manually select the move lines filtered by the above criteria." colspan="2"/> name="journal_ids"
<button name="populate" type="object" string="Add All Move Lines"/> widget="many2many_tags"
placeholder="Keep empty for using all journals"
/>
<field name="target_move" widget="radio" />
<field name="invoice" />
<field name="allow_blocked" />
<label
for="populate"
string="Click on Add All Move Lines to auto-select the move lines matching the above criteria or click on Add an item to manually select the move lines filtered by the above criteria."
colspan="2"
/>
<button name="populate" type="object" string="Add All Move Lines" />
</group> </group>
<group name="move_lines" <group name="move_lines" string="Selected Move Lines to Create Lines">
string="Selected Move Lines to Create Lines">
<field name="move_line_ids" nolabel="1"> <field name="move_line_ids" nolabel="1">
<tree> <tree>
<field name="date"/> <field name="date" />
<field name="move_id" required="0"/> <field name="move_id" required="0" />
<field name="journal_id"/> <field name="journal_id" />
<field name="partner_id"/> <field name="partner_id" />
<field name="account_id"/> <field name="account_id" />
<field name="date_maturity"/> <field name="date_maturity" />
<field name="debit"/> <field name="debit" />
<field name="credit"/> <field name="credit" />
<field name="amount_residual" sum="Total Residual"/> <field name="amount_residual" sum="Total Residual" />
<field name="amount_currency"/> <field name="amount_currency" />
<field name="amount_residual_currency"/> <field name="amount_residual_currency" />
<field name="company_currency_id" invisible="1"/> <field name="company_currency_id" invisible="1" />
</tree> </tree>
</field> </field>
</group> </group>
<footer> <footer>
<button name="create_statement_lines" type="object" <button
string="Create Statement Lines" class="oe_highlight"/> name="create_statement_lines"
<button string="Cancel" special="cancel" class="oe_link"/> type="object"
string="Create Statement Lines"
class="oe_highlight"
/>
<button string="Cancel" special="cancel" class="oe_link" />
</footer> </footer>
</form> </form>
</field> </field>
</record> </record>
<record id="account_statement_line_create_action" model="ir.actions.act_window">
<record id="account_statement_line_create_action"
model="ir.actions.act_window">
<field name="name">Create Lines from Move Lines</field> <field name="name">Create Lines from Move Lines</field>
<field name="res_model">account.statement.line.create</field> <field name="res_model">account.statement.line.create</field>
<field name="view_mode">form</field> <field name="view_mode">form</field>
<field name="target">new</field> <field name="target">new</field>
</record> </record>
</odoo> </odoo>