From 2994f9e634d8b41663bd915250a3c8f38cba66f2 Mon Sep 17 00:00:00 2001 From: jbeficent Date: Tue, 31 May 2016 14:46:46 +0200 Subject: [PATCH] [ADD][8.0] module "bank_statement_reconciliation_summary" --- .../README.rst | 141 ++++++++++++ .../__init__.py | 8 + .../__openerp__.py | 21 ++ .../models/__init__.py | 6 + .../models/account_account.py | 12 ++ .../models/account_bank_statement.py | 23 ++ .../report/__init__.py | 5 + .../report/report.xml | 33 +++ .../report/summary_report.py | 63 ++++++ .../report/summary_report.xml | 202 ++++++++++++++++++ .../view/account_account_view.xml | 17 ++ .../view/account_bank_statement.xml | 34 +++ .../wizard/__init__.py | 5 + .../wizard/account_bank_unreconcile.py | 93 ++++++++ .../wizard/account_bank_unreconcile_view.xml | 30 +++ 15 files changed, 693 insertions(+) create mode 100644 bank_statement_reconciliation_summary/README.rst create mode 100644 bank_statement_reconciliation_summary/__init__.py create mode 100644 bank_statement_reconciliation_summary/__openerp__.py create mode 100644 bank_statement_reconciliation_summary/models/__init__.py create mode 100644 bank_statement_reconciliation_summary/models/account_account.py create mode 100644 bank_statement_reconciliation_summary/models/account_bank_statement.py create mode 100644 bank_statement_reconciliation_summary/report/__init__.py create mode 100644 bank_statement_reconciliation_summary/report/report.xml create mode 100644 bank_statement_reconciliation_summary/report/summary_report.py create mode 100644 bank_statement_reconciliation_summary/report/summary_report.xml create mode 100644 bank_statement_reconciliation_summary/view/account_account_view.xml create mode 100644 bank_statement_reconciliation_summary/view/account_bank_statement.xml create mode 100644 bank_statement_reconciliation_summary/wizard/__init__.py create mode 100644 bank_statement_reconciliation_summary/wizard/account_bank_unreconcile.py create mode 100644 bank_statement_reconciliation_summary/wizard/account_bank_unreconcile_view.xml diff --git a/bank_statement_reconciliation_summary/README.rst b/bank_statement_reconciliation_summary/README.rst new file mode 100644 index 00000000..12f9f050 --- /dev/null +++ b/bank_statement_reconciliation_summary/README.rst @@ -0,0 +1,141 @@ +.. 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 Statement Reconciliation Summary +===================================== + +The Bank Reconciliation Summary shows how your actual bank statement balance +and the balance of the bank account in Odoo match, after taking into account +any unreconciled items. + +This report is useful if your bank account's statement balance and balance +in Odoo do not match, and you need to check for duplicate or manually created +transactions that might cause the discrepancy. + +This report was created, inspired by Xero’s bank reconciliation summary, +https://help.xero.com/Report_BankRec, and from a basic explanation of the +bank statement reconciliation summary: +http://www.accountingcoach.com/bank-reconciliation/explanation. + + +Usage +===== + +Define Accounts +--------------- +There are three accounts associated to a bank account: +* Bank account view +* Bank Account. Matches the statement +* Bank Clearing Account. Is used for uncleared payments and receipts. The + Bank Clearing Account is a reconcilable account. + +In the definition of the bank account that is used to match with the bank +statement, define what will be the GL account used to record the uncleared +payments and receipts. + +Define Account Journals +----------------------- +Create the following journals: +* Journal for Bank Statement reconciliation +* Journal to enter Payments and Receipts that have not yet cleared to the bank + + +Enter payments and receipts +--------------------------- +Every time an invoice is paid, use the Journal to enter Payments and Receipts. +It will generate: +Dr. Accounts Payable +Cr. Bank Clearing Account + +Create a bank statement +----------------------- +Create a bank statement and select the Journal defined for bank statement +reconciliation. + +If you do not use a tool to integrate automatically the bank statement feed +into Odoo, you can press press the button “Import Payments and Receipts” +in order to add to the statements the payments and receipts that have been +generated, but that have not yet cleared the bank. + +Use the “Reconcile” button to reconcile the entries in the bank statement +with the payments and receipts that have already cleared the bank. + +If you chose to import the statement lines from uncleared payments and +receipts, this will be the moment where you will visually compare with the +online/paper bank statement, and reconcile the items that truly cleared the +bank. + +The Odoo Bank Reconciliation Wizard will be used by the user to specifically +create the Bank Account entries by linking the Bank Statement lines with the +Bank Clearing Account items. + +Dr. Bank Clearing Account +Cr. Bank Account + +Once you have completed this process, some statement lines may be left +unreconciled (because they were truly not present in the online/physical +statement). In that case you can press the button “Remove Unreconciled”. + +Print bank statement reconciliation summary +------------------------------------------- +It will report on the current balance of the Bank Account, and will show the +unreconciled entries of the Bank Clearing Account, classifying the them +between Outstanding Payments (that is, credits in the Bank Clearing Account) +and Outstanding Receipts (that is, debits in the Bank Clearing Account). + +The application will also show the bank statement lines that have not yet +been reconciled yet, if any exists. + +Once the user has fully processed the reconciliation with the bank clearing +account, all the entries in this bank clearing account should be reconciled, +and the bank account (used to match with the Statement) will truly +reflect the same information as the bank statement balance. + +From a bank account perspective, the total amount held in the bank is the +sum of the balances of the bank clearing account (which should normally +show undeposited checks, for example) and the bank account used to match +with the statement. + + +.. 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/8.0 + + +Known issues / Roadmap +====================== + +* For Odoo v9 there will be no need to use the clearing account. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub 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 +`here `_. + +Credits +======= + +Contributors +------------ + +* Jordi Ballester Alomar + +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 http://odoo-community.org. diff --git a/bank_statement_reconciliation_summary/__init__.py b/bank_statement_reconciliation_summary/__init__.py new file mode 100644 index 00000000..d350e54f --- /dev/null +++ b/bank_statement_reconciliation_summary/__init__.py @@ -0,0 +1,8 @@ +# -*- coding: utf-8 -*- +# © 2016 Eficent Business and IT Consulting Services S.L. +# © 2016 Serpent Consulting Services Pvt. Ltd. +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +import models +import report +import wizard diff --git a/bank_statement_reconciliation_summary/__openerp__.py b/bank_statement_reconciliation_summary/__openerp__.py new file mode 100644 index 00000000..db8f4c5b --- /dev/null +++ b/bank_statement_reconciliation_summary/__openerp__.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# © 2016 Eficent Business and IT Consulting Services S.L. +# © 2016 Serpent Consulting Services Pvt. Ltd. +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +{ + 'name': 'Bank Statement Reconciliation Summary', + 'category': 'Account', + 'summary': 'Bank Statement Reconciliation Summary', + 'version': '8.0.1.0.0', + 'author': 'Eficent Business and IT Consulting Services S.L., ' + 'Serpent Consulting Services Pvt. Ltd.', + 'depends': ['account'], + 'data': [ + 'report/summary_report.xml', + 'report/report.xml', + 'view/account_account_view.xml', + 'wizard/account_bank_unreconcile_view.xml', + 'view/account_bank_statement.xml', + ], + 'installable': True, +} diff --git a/bank_statement_reconciliation_summary/models/__init__.py b/bank_statement_reconciliation_summary/models/__init__.py new file mode 100644 index 00000000..d1b0e8ea --- /dev/null +++ b/bank_statement_reconciliation_summary/models/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# © 2016 Eficent Business and IT Consulting Services S.L. +# © 2016 Serpent Consulting Services Pvt. Ltd. +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from . import account_account +from . import account_bank_statement diff --git a/bank_statement_reconciliation_summary/models/account_account.py b/bank_statement_reconciliation_summary/models/account_account.py new file mode 100644 index 00000000..2f35ba60 --- /dev/null +++ b/bank_statement_reconciliation_summary/models/account_account.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +# © 2016 Eficent Business and IT Consulting Services S.L. +# © 2016 Serpent Consulting Services Pvt. Ltd. +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from openerp import models, fields + + +class AccountAccount(models.Model): + _inherit = 'account.account' + + clearing_account_id = fields.Many2one('account.account', + 'Clearing Account') diff --git a/bank_statement_reconciliation_summary/models/account_bank_statement.py b/bank_statement_reconciliation_summary/models/account_bank_statement.py new file mode 100644 index 00000000..43c54e4f --- /dev/null +++ b/bank_statement_reconciliation_summary/models/account_bank_statement.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# © 2016 Eficent Business and IT Consulting Services S.L. +# © 2016 Serpent Consulting Services Pvt. Ltd. +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from openerp import api, fields, models + + +class AccountBankStatement(models.Model): + _inherit = 'account.bank.statement' + + @api.multi + def delete_unreconciled(self): + self.ensure_one() + for line in self.line_ids: + if not line.journal_entry_id: + line.unlink() + + +class AccountBankStatementLine(models.Model): + _inherit = 'account.bank.statement.line' + + clearing_move_line_id = fields.Many2one('account.move.line', + 'Clearing Move Line') diff --git a/bank_statement_reconciliation_summary/report/__init__.py b/bank_statement_reconciliation_summary/report/__init__.py new file mode 100644 index 00000000..994b44a8 --- /dev/null +++ b/bank_statement_reconciliation_summary/report/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# © 2016 Eficent Business and IT Consulting Services S.L. +# © 2016 Serpent Consulting Services Pvt. Ltd. +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +import summary_report diff --git a/bank_statement_reconciliation_summary/report/report.xml b/bank_statement_reconciliation_summary/report/report.xml new file mode 100644 index 00000000..3da5b8d3 --- /dev/null +++ b/bank_statement_reconciliation_summary/report/report.xml @@ -0,0 +1,33 @@ + + + + + + Bank Statement Reconcillation Summary Paperformat + + A4 + 0 + 0 + Portrait + 0 + 0 + 5 + 5 + + 0 + 90 + + + + + + + + + + diff --git a/bank_statement_reconciliation_summary/report/summary_report.py b/bank_statement_reconciliation_summary/report/summary_report.py new file mode 100644 index 00000000..bb3e347b --- /dev/null +++ b/bank_statement_reconciliation_summary/report/summary_report.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# © 2016 Eficent Business and IT Consulting Services S.L. +# © 2016 Serpent Consulting Services Pvt. Ltd. +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +import time +from openerp import api, models + + +class SummaryReport(models.AbstractModel): + _name = 'report.bank_statement_reconciliation_summary.summary_report' + + @api.model + def _plus_outstanding_payments(self, journal_record): + account_id = journal_record.default_credit_account_id and\ + journal_record.default_credit_account_id.clearing_account_id and\ + journal_record.default_credit_account_id.clearing_account_id.id + account_move_line_records = self.env['account.move.line'].search([ + ('account_id', '=', account_id), + ('reconcile_id', '=', False), + ('account_id.reconcile', '=', True), + ('credit', '>', 0.00) + ], order='date') + return account_move_line_records + + @api.model + def _less_outstanding_receipts(self, journal_record): + account_id = journal_record.default_credit_account_id and\ + journal_record.default_credit_account_id.clearing_account_id and\ + journal_record.default_credit_account_id.clearing_account_id.id + account_move_line_records = self.env['account.move.line'].search([ + ('account_id', '=', account_id), + ('reconcile_id', '=', False), + ('account_id.reconcile', '=', True), + ('debit', '>', 0.00) + ], order='date') + return account_move_line_records + + @api.model + def _plus_unreconciled_statement_lines(self, statement): + statement_lines = self.env['account.bank.statement.line'].browse() + for line in statement.line_ids: + if not line.journal_entry_id: + statement_lines += line + return statement_lines or False + + @api.multi + def render_html(self, data=None): + Report = self.env['report'] + report_name = 'bank_statement_reconciliation_summary.summary_report' + report = Report._get_report_from_name(report_name) + records = self.env['account.bank.statement'].browse(self.ids) + docargs = { + 'doc_ids': self.ids, + 'doc_model': report.model, + 'data': data, + 'docs': records, + 'time': time, + 'plus_outstanding_payments': self._plus_outstanding_payments, + 'less_outstanding_receipts': self._less_outstanding_receipts, + 'plus_unreconciled_statement_lines': + self._plus_unreconciled_statement_lines + } + return self.env['report'].render(report_name, docargs) diff --git a/bank_statement_reconciliation_summary/report/summary_report.xml b/bank_statement_reconciliation_summary/report/summary_report.xml new file mode 100644 index 00000000..6c8ce32d --- /dev/null +++ b/bank_statement_reconciliation_summary/report/summary_report.xml @@ -0,0 +1,202 @@ + + + + + + + + \ No newline at end of file diff --git a/bank_statement_reconciliation_summary/view/account_account_view.xml b/bank_statement_reconciliation_summary/view/account_account_view.xml new file mode 100644 index 00000000..0f9d59e6 --- /dev/null +++ b/bank_statement_reconciliation_summary/view/account_account_view.xml @@ -0,0 +1,17 @@ + + + + + + inherit.account.form + account.account + + + + + + + + + + \ No newline at end of file diff --git a/bank_statement_reconciliation_summary/view/account_bank_statement.xml b/bank_statement_reconciliation_summary/view/account_bank_statement.xml new file mode 100644 index 00000000..86f44de5 --- /dev/null +++ b/bank_statement_reconciliation_summary/view/account_bank_statement.xml @@ -0,0 +1,34 @@ + + + + + + account.bank.statement.form.view + account.bank.statement + + + + + + + + + + diff --git a/bank_statement_reconciliation_summary/wizard/__init__.py b/bank_statement_reconciliation_summary/wizard/__init__.py new file mode 100644 index 00000000..7e6b6e86 --- /dev/null +++ b/bank_statement_reconciliation_summary/wizard/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# © 2016 Eficent Business and IT Consulting Services S.L. +# © 2016 Serpent Consulting Services Pvt. Ltd. +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +import account_bank_unreconcile diff --git a/bank_statement_reconciliation_summary/wizard/account_bank_unreconcile.py b/bank_statement_reconciliation_summary/wizard/account_bank_unreconcile.py new file mode 100644 index 00000000..98f9d82c --- /dev/null +++ b/bank_statement_reconciliation_summary/wizard/account_bank_unreconcile.py @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- +# © 2016 Eficent Business and IT Consulting Services S.L. +# © 2016 Serpent Consulting Services Pvt. Ltd. +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from openerp import api, fields, models +from openerp.tools import misc +from openerp.exceptions import Warning +from openerp.tools.translate import _ + + +class SummaryReport(models.TransientModel): + _name = 'wiz.bank.unreconcile' + + @api.model + def _get_unreconcile_entries(self): + cr, uid, context = self.env.args + context = dict(context) + statement_line_obj = self.env['account.bank.statement.line'] + move_line_obj = self.env['account.move.line'] + bank_id = context.get('active_id') + self.env.args = cr, uid, misc.frozendict(context) + bank = self.env['account.bank.statement'].browse(bank_id) + clearing_account_id = bank.journal_id and\ + bank.journal_id.default_credit_account_id and\ + bank.journal_id.default_credit_account_id.clearing_account_id and\ + bank.journal_id.default_credit_account_id.clearing_account_id.id + if clearing_account_id: + to_add_move_lines = move_line_obj.browse() + account_move_line_records = self.env['account.move.line'].search([ + ('account_id', '=', clearing_account_id), + ('account_id.reconcile', '=', True), + '|', + ('reconcile_id', '=', False), + ('reconcile_partial_id', '!=', False) + ], order='date') + statements = statement_line_obj.search( + [('statement_id', '=', bank_id), + ('clearing_move_line_id', 'in', + account_move_line_records.ids)]) + in_statement_clearing_lines = [] + for statement in statements: + in_statement_clearing_lines += \ + statement.clearing_move_line_id + for move_line in account_move_line_records: + if move_line not in in_statement_clearing_lines: + to_add_move_lines += move_line + else: + raise Warning(_("Create an Clearing Account to get " + "the Unreconciled Journal Items.")) + return to_add_move_lines + + line_ids = fields.Many2many('account.move.line', + 'wiz_unreconciles_move_line_rel', + 'reconciles_id', 'accounts_id', + 'Journal Items to Reconcile', + default=_get_unreconcile_entries) + + @api.multi + def process_wiz(self): + context = dict(self._context) + bank_stmt_obj = self.env['account.bank.statement'] + currency_obj = self.env['res.currency'] + statement = bank_stmt_obj.browse(context.get('active_ids')) + lines = [] + for line in self.line_ids: + currency_obj = currency_obj.with_context(date=statement.date) + amount = 0.0 + if line.debit > 0: + amount = line.debit + elif line.credit > 0: + amount = -line.credit + if line.amount_currency: + if line.company_id.currency_id.id != statement.currency.id: + amount = line.currency_id.with_context( + date=statement.date).compute(line.amount_currency, + statement.currency) + elif (line.currency_id and + line.currency_id.id != statement.currency.id): + amount = line.currency_id.with_context( + date=statement.date).compute(amount, + statement.currency) + lines.append((0, 0, { + 'name': line.name or '?', + 'ref': line.ref, + 'partner_id': line.partner_id.id, + 'amount': amount, + 'date': line.date, + 'amount_currency': line.amount_currency, + 'currency_id': line.currency_id.id, + 'clearing_move_line_id': line.id, + })) + statement.write({'line_ids': lines}) + return True diff --git a/bank_statement_reconciliation_summary/wizard/account_bank_unreconcile_view.xml b/bank_statement_reconciliation_summary/wizard/account_bank_unreconcile_view.xml new file mode 100644 index 00000000..3f896c1c --- /dev/null +++ b/bank_statement_reconciliation_summary/wizard/account_bank_unreconcile_view.xml @@ -0,0 +1,30 @@ + + + + + + wiz.bank.unreconcile.form + wiz.bank.unreconcile + +
+ +
+
+ +
+
+ + + +
+