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..cbe4ef03 --- /dev/null +++ b/bank_statement_reconciliation_summary/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- +from . import report +from . import wizard diff --git a/bank_statement_reconciliation_summary/__manifest__.py b/bank_statement_reconciliation_summary/__manifest__.py new file mode 100644 index 00000000..8cedf007 --- /dev/null +++ b/bank_statement_reconciliation_summary/__manifest__.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Copyright 2016 Eficent Business and IT Consulting Services S.L. +# Copyright 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': '10.0.1.0.0', + 'author': 'Eficent, ' + 'Serpent Consulting Services Pvt. Ltd.,' + 'Odoo Community Association (OCA)', + 'depends': ['account'], + 'data': [ + 'report/summary_report.xml', + 'report/report.xml', + 'wizard/bank_statement_reconciliation_summary_wizard_view.xml', + ], + 'installable': True, +} diff --git a/bank_statement_reconciliation_summary/report/__init__.py b/bank_statement_reconciliation_summary/report/__init__.py new file mode 100644 index 00000000..cd53ea7e --- /dev/null +++ b/bank_statement_reconciliation_summary/report/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +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..101712e2 --- /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..4efa0490 --- /dev/null +++ b/bank_statement_reconciliation_summary/report/summary_report.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- +# Copyright 2016 Eficent Business and IT Consulting Services S.L. +# Copyright 2016 Serpent Consulting Services Pvt. Ltd. +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +import time +from odoo import api, models, _ + + +class SummaryReport(models.AbstractModel): + _name = 'report.bank_statement_reconciliation_summary.summary_report' + + @api.model + def _plus_outstanding_payments(self, journals, end_date): + rec = {} + for journal in journals: + account_id = journal.default_debit_account_id.id + account_move_line_records = self.env['account.move.line'].search([ + ('account_id', '=', account_id), + ('reconciled', '=', False), + ('account_id.reconcile', '=', False), + ('credit', '>', 0.00), + ('date', '<=', end_date), + ], order='date') + rec[journal.id] = account_move_line_records + return rec + + @api.model + def _less_outstanding_receipts(self, journals, end_date): + rec = {} + for journal in journals: + account_id = journal.default_debit_account_id.id + account_move_line_records = self.env['account.move.line'].search([ + ('account_id', '=', account_id), + ('reconciled', '=', False), + ('account_id.reconcile', '=', False), + ('debit', '>', 0.00), + ('date', '<=', end_date), + ], order='date') + rec[journal.id] = account_move_line_records + return rec + + @api.model + def _plus_unreconciled_statement_lines(self, journals, end_date): + rec = {} + for journal in journals: + statement_lines = self.env['account.bank.statement.line'].search( + [('date', '<=', end_date), + ('journal_id', '=', journal.id)]) + for line in statement_lines: + if not line.journal_entry_ids: + statement_lines += line + rec[journal.id] = statement_lines or False + return rec + + @api.model + def _get_bank_end_balance(self, journals, end_date): + rec = {} + for journal in journals: + bank_account = journal.default_credit_account_id + amount_field = 'balance' + query = """ + SELECT sum(%s) FROM account_move_line + WHERE account_id=%%s + AND date<=%%s""" % (amount_field,) + self.env.cr.execute(query, (bank_account.id, end_date)) + query_results = self.env.cr.dictfetchall() + if query_results: + account_bal = query_results[0].get('sum') or 0.0 + else: + account_bal = 0.0 + rec[journal.id] = account_bal + return rec + + @api.multi + def render_html(self, docids, 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.journal'].browse(docids) + docargs = { + 'doc_ids': docids, + 'doc_model': report.model, + 'data': data, + 'docs': records, + 'time': time, + 'plus_outstanding_payments': + self._plus_outstanding_payments(records, data['end_date']), + 'less_outstanding_receipts': + self._less_outstanding_receipts(records, data['end_date']), + 'plus_unreconciled_statement_lines': + self._plus_unreconciled_statement_lines(records, + data['end_date']), + 'bank_end_balance': self._get_bank_end_balance( + records, data['end_date']), + 'balance_end_real': data['balance_end_real'] + } + 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..38b1c3e4 --- /dev/null +++ b/bank_statement_reconciliation_summary/report/summary_report.xml @@ -0,0 +1,221 @@ + + + + + + + + \ No newline at end of file diff --git a/bank_statement_reconciliation_summary/wizard/__init__.py b/bank_statement_reconciliation_summary/wizard/__init__.py new file mode 100644 index 00000000..31841a4e --- /dev/null +++ b/bank_statement_reconciliation_summary/wizard/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import bank_statement_reconciliation_summary_wizard diff --git a/bank_statement_reconciliation_summary/wizard/bank_statement_reconciliation_summary_wizard.py b/bank_statement_reconciliation_summary/wizard/bank_statement_reconciliation_summary_wizard.py new file mode 100644 index 00000000..f5f35049 --- /dev/null +++ b/bank_statement_reconciliation_summary/wizard/bank_statement_reconciliation_summary_wizard.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# © 2017 Akretion (Alexis de Lattre ) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + + +class BankReconciliationReportWizard(models.TransientModel): + _name = "bank.statement.reconciliation.summary.wizard" + _description = "Bank Statement Reconciliation Summary Wizard" + + @api.model + def _default_journal_id(self): + journal = self.env['account.journal'].search([ + ('type', '=', 'bank'), + ('company_id', '=', self.env.user.company_id.id)], limit=1) + return journal + + end_date = fields.Date( + required=True, + default=fields.Date.context_today) + journal_id = fields.Many2one( + 'account.journal', string='Bank Journal', + domain=[('type', '=', 'bank')], required=True, + default=_default_journal_id) + balance_end_real = fields.Float('Bank Ending Balance') + + def open_qweb(self): + action = { + 'type': 'ir.actions.report.xml', + 'report_name': + 'bank_statement_reconciliation_summary.summary_report', + 'docids': self.journal_id.ids, + 'datas': { + 'docids': self.journal_id.ids, + 'ids': self.journal_id.ids, + 'end_date': self.end_date, + 'balance_end_real': self.balance_end_real, + }, + 'context': self._context, + } + return action diff --git a/bank_statement_reconciliation_summary/wizard/bank_statement_reconciliation_summary_wizard_view.xml b/bank_statement_reconciliation_summary/wizard/bank_statement_reconciliation_summary_wizard_view.xml new file mode 100644 index 00000000..d12c8817 --- /dev/null +++ b/bank_statement_reconciliation_summary/wizard/bank_statement_reconciliation_summary_wizard_view.xml @@ -0,0 +1,42 @@ + + + + + + + + bank.statement.reconciliation.summary.wizard.form + bank.statement.reconciliation.summary.wizard + +
+ + + + + +
+
+
+
+
+ + + Bank Statement Reconciliation + bank.statement.reconciliation.summary.wizard + form + new + + + + + +