feat: Update module to Odoo 19, migrating tree views to list views, and refining bank statement reconciliation filters and search view grouping.

This commit is contained in:
Suherdy Yacob 2026-01-20 15:28:44 +07:00
parent d75a96007e
commit 7917d4fc06
4 changed files with 180 additions and 167 deletions

15
.gitignore vendored Normal file
View File

@ -0,0 +1,15 @@
# Python
__pycache__/
*.py[cod]
*$py.class
# OS
.DS_Store
Thumbs.db
# Editor
.vscode/
.idea/
# Odoo
*.pot

View File

@ -1,32 +1,32 @@
{ {
'name': 'Bank Statement Reconciliation', 'name': 'Bank Statement Reconciliation',
'version': '17.0.1.0.0', 'version': '19.0.1.0.0',
'category': 'Accounting', 'category': 'Accounting',
'summary': 'Reconcile bank statement lines with journal entries', 'summary': 'Reconcile bank statement lines with journal entries',
'description': """ 'description': """
This module allows users to reconcile bank statement lines with journal entries. This module allows users to reconcile bank statement lines with journal entries.
Features: Features:
- Menu to access bank statement lines - Menu to access bank statement lines
- Filter by bank journal - Filter by bank journal
- Select multiple bank lines to reconcile - Select multiple bank lines to reconcile
- Wizard to select journal entries for reconciliation - Wizard to select journal entries for reconciliation
- Automatic creation of reconciliation journal entries - Automatic creation of reconciliation journal entries
- Total selected amount widget in list view header - Total selected amount widget in list view header
""", """,
'author': 'Suherdy Yacob', 'author': 'Suherdy Yacob',
'depends': [ 'depends': [
'account', 'account',
'base', 'base',
'web', 'web',
], ],
'data': [ 'data': [
'security/ir.model.access.csv', 'security/ir.model.access.csv',
'views/bank_statement_line_views.xml', 'views/bank_statement_line_views.xml',
'views/bank_statement_selector_views.xml', 'views/bank_statement_selector_views.xml',
'wizards/bank_reconcile_wizard_views.xml', 'wizards/bank_reconcile_wizard_views.xml',
'views/menu.xml', 'views/menu.xml',
], ],
# Tree view includes sum="Total Amount" footer for displaying totals # List view includes sum="Total Amount" footer for displaying totals
'installable': True, 'installable': True,
'auto_install': False, 'auto_install': False,
} }

View File

@ -1,29 +1,29 @@
from odoo import models, fields, api from odoo import models, fields, api
class BankStatementSelector(models.TransientModel): class BankStatementSelector(models.TransientModel):
_name = 'bank.statement.selector' _name = 'bank.statement.selector'
_description = 'Bank Statement Selector' _description = 'Bank Statement Selector'
journal_id = fields.Many2one('account.journal', journal_id = fields.Many2one('account.journal',
string='Bank Journal', string='Bank Journal',
domain=[('type', '=', 'bank')], domain=[('type', '=', 'bank')],
required=True) required=True)
def action_show_statement_lines(self): def action_show_statement_lines(self):
"""Open the bank statement lines for the selected journal""" """Open the bank statement lines for the selected journal"""
action = { action = {
'type': 'ir.actions.act_window', 'type': 'ir.actions.act_window',
'name': 'Bank Statement Lines', 'name': 'Bank Statement Lines',
'res_model': 'account.bank.statement.line', 'res_model': 'account.bank.statement.line',
'view_mode': 'tree,form', 'view_mode': 'list,form',
'domain': [('journal_id', '=', self.journal_id.id)], 'domain': [('journal_id', '=', self.journal_id.id)],
'context': { 'context': {
'search_default_journal_id': self.journal_id.id, 'search_default_journal_id': self.journal_id.id,
}, },
'views': [ 'views': [
(self.env.ref('bank_statement_reconciliation.view_account_bank_statement_line_tree').id, 'tree'), (self.env.ref('bank_statement_reconciliation.view_account_bank_statement_line_tree').id, 'list'),
(self.env.ref('bank_statement_reconciliation.view_account_bank_statement_line_form').id, 'form') (self.env.ref('bank_statement_reconciliation.view_account_bank_statement_line_form').id, 'form')
] ]
} }
return action return action

View File

@ -1,109 +1,107 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<!-- Action to open the bank statement lines view --> <!-- Action to open the bank statement lines view -->
<record id="action_bank_statement_lines" model="ir.actions.act_window"> <record id="action_bank_statement_lines" model="ir.actions.act_window">
<field name="name">Bank Statement Lines</field> <field name="name">Bank Statement Lines</field>
<field name="res_model">account.bank.statement.line</field> <field name="res_model">account.bank.statement.line</field>
<field name="view_mode">tree,form</field> <field name="view_mode">list,form</field>
<field name="context">{'tree_view_ref': 'bank_statement_reconciliation.view_account_bank_statement_line_tree'}</field> <field name="context">{'list_view_ref': 'bank_statement_reconciliation.view_account_bank_statement_line_tree'}</field>
<field name="help" type="html"> <field name="help" type="html">
<p class="o_view_nocontent_smiling_face"> <p class="o_view_nocontent_smiling_face">
Select a bank journal to view its statement lines Select a bank journal to view its statement lines
</p> </p>
</field> </field>
</record> </record>
<!-- Server action for reconciliation --> <!-- Server action for reconciliation -->
<record id="action_reconcile_bank_lines" model="ir.actions.server"> <record id="action_reconcile_bank_lines" model="ir.actions.server">
<field name="name">Reconcile Selected Lines</field> <field name="name">Reconcile Selected Lines</field>
<field name="model_id" ref="account.model_account_bank_statement_line"/> <field name="model_id" ref="account.model_account_bank_statement_line"/>
<field name="binding_model_id" ref="account.model_account_bank_statement_line"/> <field name="binding_model_id" ref="account.model_account_bank_statement_line"/>
<field name="state">code</field> <field name="state">code</field>
<field name="code"> <field name="code">
action = { action = {
'name': 'Select Journal Entry to Reconcile', 'name': 'Select Journal Entry to Reconcile',
'type': 'ir.actions.act_window', 'type': 'ir.actions.act_window',
'res_model': 'bank.reconcile.wizard', 'res_model': 'bank.reconcile.wizard',
'view_mode': 'form', 'view_mode': 'form',
'target': 'new', 'target': 'new',
'context': { 'context': {
'default_bank_line_ids': env.context.get('active_ids'), 'default_bank_line_ids': env.context.get('active_ids'),
} }
} }
</field> </field>
</record> </record>
<!-- Tree view for bank statement lines --> <!-- List view for bank statement lines -->
<record id="view_account_bank_statement_line_tree" model="ir.ui.view"> <record id="view_account_bank_statement_line_tree" model="ir.ui.view">
<field name="name">account.bank.statement.line.tree</field> <field name="name">account.bank.statement.line.tree</field>
<field name="model">account.bank.statement.line</field> <field name="model">account.bank.statement.line</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="Bank Statement Lines" create="0" delete="0" decoration-danger="amount &lt; 0" decoration-muted="move_id and 'Reconciliation:' in move_id.name" multi_edit="1"> <list string="Bank Statement Lines" create="0" delete="0" decoration-danger="amount &lt; 0" decoration-muted="move_id and 'Reconciliation:' in move_id.name" multi_edit="1">
<field name="company_id" column_invisible="True"/> <field name="company_id" column_invisible="True"/>
<field name="currency_id" column_invisible="True"/> <field name="currency_id" column_invisible="True"/>
<field name="suitable_journal_ids" column_invisible="True"/> <field name="suitable_journal_ids" column_invisible="True"/>
<field name="date"/> <field name="date"/>
<field name="name"/> <field name="name"/>
<field name="partner_id"/> <field name="partner_id"/>
<field name="amount" sum="Total Amount" widget="monetary"/> <field name="amount" sum="Total Amount" widget="monetary"/>
<field name="journal_id"/> <field name="journal_id"/>
<field name="statement_id"/> <field name="statement_id"/>
<field name="move_id"/> <field name="move_id"/>
</tree> </list>
</field> </field>
</record> </record>
<!-- Form view for bank statement lines --> <!-- Form view for bank statement lines -->
<record id="view_account_bank_statement_line_form" model="ir.ui.view"> <record id="view_account_bank_statement_line_form" model="ir.ui.view">
<field name="name">account.bank.statement.line.form</field> <field name="name">account.bank.statement.line.form</field>
<field name="model">account.bank.statement.line</field> <field name="model">account.bank.statement.line</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Bank Statement Line"> <form string="Bank Statement Line">
<header> <header>
<button name="action_reconcile_selected_lines" type="object" string="Reconcile" class="btn-primary" invisible="move_id and 'Reconciliation:' in move_id.name"/> <button name="action_reconcile_selected_lines" type="object" string="Reconcile" class="btn-primary" invisible="move_id and 'Reconciliation:' in move_id.name"/>
</header> </header>
<sheet> <sheet>
<group> <group>
<group> <group>
<field name="date"/> <field name="date"/>
<field name="name"/> <field name="name"/>
<field name="ref"/> <field name="ref"/>
</group> </group>
<group> <group>
<field name="amount"/> <field name="amount"/>
<field name="partner_id"/> <field name="partner_id"/>
<field name="journal_id" readonly="1"/> <field name="journal_id" readonly="1"/>
</group> </group>
</group> </group>
<group> <group>
<field name="statement_id"/> <field name="statement_id"/>
<field name="move_id"/> <field name="move_id"/>
<field name="company_id" invisible="1"/> <field name="company_id" invisible="1"/>
</group> </group>
</sheet> </sheet>
</form> </form>
</field> </field>
</record> </record>
<!-- Search view for bank statement lines --> <!-- Search view for bank statement lines -->
<record id="view_account_bank_statement_line_search" model="ir.ui.view"> <record id="view_account_bank_statement_line_search" model="ir.ui.view">
<field name="name">account.bank.statement.line.search</field> <field name="name">account.bank.statement.line.search</field>
<field name="model">account.bank.statement.line</field> <field name="model">account.bank.statement.line</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<search> <search>
<field name="name"/> <field name="name"/>
<field name="partner_id"/> <field name="partner_id"/>
<field name="journal_id"/> <field name="journal_id"/>
<field name="date"/> <field name="date"/>
<filter name="positive_amount" string="Income" domain="[('amount', '&gt;', 0)]"/> <filter name="positive_amount" string="Income" domain="[('amount', '&gt;', 0)]"/>
<filter name="negative_amount" string="Expense" domain="[('amount', '&lt;', 0)]"/> <filter name="negative_amount" string="Expense" domain="[('amount', '&lt;', 0)]"/>
<filter name="hide_reconciled" string="Hide Reconciled" domain="[('move_id', 'not ilike', '%Reconciliation:%')]" help="Hide lines that have been reconciled"/> <filter name="hide_reconciled" string="Hide Reconciled" domain="[('is_reconciled', '=', False)]" help="Hide lines that have been reconciled"/>
<filter name="show_all" string="Show All" domain="[]" help="Show all lines including reconciled"/> <filter name="show_all" string="Show All" domain="[]" help="Show all lines including reconciled"/>
<group expand="0" string="Group By"> <filter name="group_by_journal" string="Journal" context="{'group_by': 'journal_id'}"/>
<filter name="group_by_journal" string="Journal" context="{'group_by': 'journal_id'}"/> <filter name="group_by_date" string="Date" context="{'group_by': 'date'}"/>
<filter name="group_by_date" string="Date" context="{'group_by': 'date'}"/> </search>
</group> </field>
</search> </record>
</field>
</record>
</odoo> </odoo>