Browse Source

Add module account_bank_reconciliation_summary_xlsx

pull/322/head
Alexis de Lattre 8 years ago
parent
commit
61d85180a8
  1. 65
      account_bank_reconciliation_summary_xlsx/README.rst
  2. 4
      account_bank_reconciliation_summary_xlsx/__init__.py
  3. 18
      account_bank_reconciliation_summary_xlsx/__manifest__.py
  4. 3
      account_bank_reconciliation_summary_xlsx/models/__init__.py
  5. 22
      account_bank_reconciliation_summary_xlsx/models/account_bank_statement.py
  6. 3
      account_bank_reconciliation_summary_xlsx/report/__init__.py
  7. 200
      account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py
  8. 18
      account_bank_reconciliation_summary_xlsx/report/report.xml
  9. 23
      account_bank_reconciliation_summary_xlsx/views/account_bank_statement_view.xml

65
account_bank_reconciliation_summary_xlsx/README.rst

@ -0,0 +1,65 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
===============================
Bank Reconciliation Report XLSX
===============================
This module adds a Bank Reconciliation Report in Odoo in XLSX format. For each bank journal, the report displays:
1. The balance of the bank account in the accounting,
2. The list of journal items of the bank account not linked to any bank statement lines,
3. The list of draft bank statement lines not linked to any journal items,
4. The computed balance of the bank account at the bank.
The last field (computed balance of the bank account at the bank) must be compared to the real bank account balance at the bank. If there is a difference, you need to find the erreor in the accounting. The field *Computed balance of the bank account at the bank* is a formula, so you can easily change its computation to try to find the difference with the real bank account balance at the bank.
Configuration
=============
This module doesn't require any configuration.
Usage
=====
You can get the Bank Reconciliation Report from:
* the form view of a bank bournal: click on *Print > Bank Reconciliation XLSX*
* the tree view of journals: select one or several journals and click on *Print > Bank Reconciliation XLSX* (if you selected several bank journals, you will get one tab per journal)
* the form view of a bank statement: click on the button *Bank Reconciliation Report*.
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/91/10.0
Bug Tracker
===========
Bugs are tracked on `GitHub Issues
<https://github.com/OCA/account-financial-reporting/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.
Credits
=======
Contributors
------------
* Alexis de Lattre <alexis.delattre@akretion.com>
Maintainer
----------
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
This module is maintained by the OCA.
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.
To contribute to this module, please visit https://odoo-community.org.

4
account_bank_reconciliation_summary_xlsx/__init__.py

@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
from . import models
from . import report

18
account_bank_reconciliation_summary_xlsx/__manifest__.py

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
# © 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'Account Bank Statement Reconciliation Summary',
'version': '10.0.1.0.0',
'license': 'AGPL-3',
'author': "Akretion,Odoo Community Association (OCA)",
'website': 'http://www.akretion.com',
'summary': 'Adds an XLSX report to help on bank statement reconciliation',
'depends': ['account', 'report_xlsx'],
'data': [
'report/report.xml',
'views/account_bank_statement_view.xml',
],
'installable': True,
}

3
account_bank_reconciliation_summary_xlsx/models/__init__.py

@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import account_bank_statement

22
account_bank_reconciliation_summary_xlsx/models/account_bank_statement.py

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# © 2017 Akretion France (Alexis de Lattre <alexis.delattre@akretion.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models
class AccountBankStatement(models.Model):
_inherit = 'account.bank.statement'
def print_reconciliation_xlsx(self):
self.ensure_one()
action = {
'type': 'ir.actions.report.xml',
'report_name': 'bank.reconciliation.xlsx',
'datas': {
'model': 'account.journal',
'ids': [self.journal_id.id],
},
'context': self._context,
}
return action

3
account_bank_reconciliation_summary_xlsx/report/__init__.py

@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import bank_reconciliation_xlsx

200
account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py

@ -0,0 +1,200 @@
# -*- coding: utf-8 -*-
# © 2017 Akretion France (Alexis de Lattre <alexis.delattre@akretion.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo.addons.report_xlsx.report.report_xlsx import ReportXlsx
from odoo import _
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT
from datetime import datetime
class BankReconciliationXlsx(ReportXlsx):
def generate_xlsx_report(self, workbook, data, journals):
no_bank_journal = True
for o in journals.filtered(lambda o: o.type == 'bank'):
no_bank_journal = False
# Start styles
doc_title = workbook.add_format({'bold': True, 'font_size': 16})
col_title = workbook.add_format({
'bold': True, 'bg_color': '#e2e2fa',
'text_wrap': True, 'font_size': 10,
})
title_right = workbook.add_format({
'bold': True, 'bg_color': '#e6e6fa',
'font_size': 10, 'align': 'right',
})
label_bold = workbook.add_format({
'bold': True, 'text_wrap': False, 'font_size': 10})
none = workbook.add_format({
'bold': True, 'font_size': 10, 'align': 'right'})
regular = workbook.add_format({'font_size': 10})
lang_code = self.env.user.lang
lang = False
if lang_code:
lang = self.env['res.lang'].search([('code', '=', lang_code)])
if not lang:
lang = self.env['res.lang'].search([], limit=1)
xls_date_format = lang.date_format.replace('%Y', 'yyyy').\
replace('%m', 'mm').replace('%d', 'dd').replace('%y', 'yy')
if '%' in xls_date_format:
# fallback
xls_date_format = 'yyyy-mm-dd'
regular_date = workbook.add_format({
'num_format': xls_date_format,
'font_size': 10,
'align': 'left'})
cur_format = u'#%s##0%s00 %s' % (
lang.thousands_sep or '',
lang.decimal_point or '',
o.company_id.currency_id.symbol or
o.company_id.currency_id.name)
regular_currency = workbook.add_format(
{'num_format': cur_format, 'font_size': 10})
regular_currency_bg = workbook.add_format({
'num_format': cur_format, 'font_size': 10,
'bg_color': '#f6f6ff'})
# End styles
sheet = workbook.add_worksheet(o.code or o.name)
sheet.write(
0, 0, _('%s - Bank Reconciliation') % o.display_name,
doc_title)
sheet.set_row(0, 26)
sheet.set_row(1, 25)
sheet.set_column(0, 0, 10)
sheet.set_column(1, 1, 40)
sheet.set_column(2, 2, 15)
sheet.set_column(3, 3, 25)
sheet.set_column(4, 4, 12)
sheet.set_column(5, 5, 14)
sheet.set_column(6, 6, 22)
row = 2
sheet.write(row, 0, _("Date:"), label_bold)
# I can't use fields.Date.context_today(self)
sheet.write(row, 1, datetime.today(), regular_date)
# 1) Show accounting balance of bank account
bank_account = o.default_debit_account_id
sheet.write(
row, 3,
_('Balance %s:') % bank_account.code, title_right)
amount_field = 'balance'
# TODO: add support for bank accounts in foreign currency
# if not o.currency_id else 'amount_currency'
query = """
SELECT sum(%s) FROM account_move_line
WHERE account_id=%%s""" % (amount_field,)
self.env.cr.execute(query, (bank_account.id,))
query_results = self.env.cr.dictfetchall()
if query_results:
account_bal = query_results[0].get('sum') or 0.0
else:
account_bal = 0.0
sheet.write(row, 4, account_bal, regular_currency_bg)
bank_bal = account_bal
formula = '=E%d' % (row + 1)
# 2) Show account move line that are not linked to bank account
row += 2
sheet.write(
row, 0, _(
'Journal items of account %s not linked to a bank '
'statement line:') % bank_account.code,
label_bold)
mlines = self.env['account.move.line'].search([
('account_id', '=', bank_account.id),
('journal_id', '=', o.id), # to avoid initial line
('statement_id', '=', False)])
if not mlines:
sheet.write(row, 4, _('NONE'), none)
else:
row += 1
sheet.write(row, 0, _('Date'), col_title)
sheet.write(row, 1, _('Label'), col_title)
sheet.write(row, 2, _('Ref.'), col_title)
sheet.write(row, 3, _('Partner'), col_title)
sheet.write(row, 4, _('Amount'), col_title)
sheet.write(row, 5, _('Move Number'), col_title)
sheet.write(row, 6, _('Counter-part'), col_title)
m_start_row = m_end_row = row + 1
for mline in mlines:
row += 1
m_end_row = row
move = mline.move_id
bank_bal -= mline.balance
date_dt = datetime.strptime(
mline.date, DEFAULT_SERVER_DATE_FORMAT)
sheet.write(row, 0, date_dt, regular_date)
sheet.write(row, 1, mline.name, regular)
sheet.write(row, 2, mline.ref or '', regular)
sheet.write(
row, 3, mline.partner_id.display_name or '', regular)
sheet.write(row, 4, mline.balance, regular_currency)
sheet.write(row, 5, move.name, regular)
# counter-part accounts
cpart = []
for line in move.line_ids:
if (
line.account_id != bank_account and
line.account_id.code not in cpart):
cpart.append(line.account_id.code)
sheet.write(row, 6, ' ,'.join(cpart), regular)
formula += '-SUM(E%d:E%d)' % (m_start_row + 1, m_end_row + 1)
# 3) Add draft bank statement lines
row += 2 # skip 1 line
sheet.write(
row, 0, _(
'Draft bank statement lines:'),
label_bold)
blines = self.env['account.bank.statement.line'].search([
('journal_entry_ids', '=', False),
('journal_id', '=', o.id)])
if not blines:
sheet.write(row, 4, _('NONE'), none)
else:
row += 1
sheet.write(row, 0, _('Date'), col_title)
sheet.write(row, 1, _('Label'), col_title)
sheet.write(row, 2, _('Ref.'), col_title)
sheet.write(row, 3, _('Partner'), col_title)
sheet.write(row, 4, _('Amount'), col_title)
sheet.write(row, 5, _('Statement Ref.'), col_title)
b_start_row = b_end_row = row + 1
for bline in blines:
row += 1
b_end_row = row
bank_bal += bline.amount
date_dt = datetime.strptime(
bline.date, DEFAULT_SERVER_DATE_FORMAT)
sheet.write(row, 0, date_dt, regular_date)
sheet.write(row, 1, bline.name, regular)
sheet.write(row, 2, bline.ref or '', regular)
sheet.write(
row, 3, bline.partner_id.display_name or '', regular)
sheet.write(row, 4, bline.amount, regular_currency)
sheet.write(
row, 5, bline.statement_id.name or '',
regular_currency)
formula += '+SUM(E%d:E%d)' % (b_start_row + 1, b_end_row + 1)
# 4) Theoric bank account balance at the bank
row += 2
sheet.write(
row, 3, _('Computed Bank Account Balance at the Bank:'),
title_right)
sheet.write_formula(
row, 4, formula, regular_currency_bg, bank_bal)
if no_bank_journal:
sheet = workbook.add_worksheet(_('No Bank Journal'))
sheet.set_row(0, 30)
warn_msg = workbook.add_format(
{'bold': True, 'font_size': 16, 'font_color': '#003b6f'})
sheet.write(
0, 0, _(
"No bank journal selected. "
"This report is only for bank journals."), warn_msg)
BankReconciliationXlsx('report.bank.reconciliation.xlsx', 'account.journal')

18
account_bank_reconciliation_summary_xlsx/report/report.xml

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
© 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<report
id="bank_reconciliation_xlsx"
model="account.journal"
string="Bank Reconciliation XLSX"
report_type="xlsx"
name="bank.reconciliation.xlsx"
file="bank.reconciliation.xlsx"
/>
</odoo>

23
account_bank_reconciliation_summary_xlsx/views/account_bank_statement_view.xml

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
© 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="view_bank_statement_form" model="ir.ui.view">
<field name="name">bank_rec_summary.account.bank.statement.form</field>
<field name="model">account.bank.statement</field>
<field name="inherit_id" ref="account.view_bank_statement_form"/>
<field name="arch" type="xml">
<button name="check_confirm_bank" position="after">
<button name="print_reconciliation_xlsx" type="object"
string="Bank Reconciliation Report"/>
</button>
</field>
</record>
</odoo>
Loading…
Cancel
Save