diff --git a/bank_reconciliation/__init__.py b/bank_reconciliation/__init__.py new file mode 100644 index 000000000..87028712d --- /dev/null +++ b/bank_reconciliation/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2018-TODAY Cybrosys Technologies(). +# Author: Fasluca() +# you can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# It is forbidden to publish, distribute, sublicense, or sell copies +# of the Software or modified copies of the Software. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (AGPL v3) along with this program. +# If not, see . +# +############################################################################## +from . import models +from . import wizard diff --git a/bank_reconciliation/__manifest__.py b/bank_reconciliation/__manifest__.py new file mode 100644 index 000000000..8dfda9a88 --- /dev/null +++ b/bank_reconciliation/__manifest__.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2018-TODAY Cybrosys Technologies(). +# Author: Fasluca() +# you can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# It is forbidden to publish, distribute, sublicense, or sell copies +# of the Software or modified copies of the Software. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (AGPL v3) along with this program. +# If not, see . +# +############################################################################## +{ + 'name': 'Manual Bank Reconciliation', + 'version': '11.0.1.0', + 'author': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'website': 'http://www.cybrosys.com', + 'category': 'Accounting', + 'summary': 'Replacing default method by traditional', + 'description': """ Replacing default bank statement reconciliation method by traditional way """, + 'depends': ['account'], + 'data': [ + 'security/ir.model.access.csv', + 'views/account_move_line_view.xml', + 'views/account_journal_dashboard_view.xml', + 'wizard/bank_statement_wiz_view.xml', + ], + 'images': ['static/description/pdc_banner.jpg'], + 'license': 'AGPL-3', + 'installable': True, + 'auto_install': False, +} diff --git a/bank_reconciliation/models/__init__.py b/bank_reconciliation/models/__init__.py new file mode 100644 index 000000000..a59188e04 --- /dev/null +++ b/bank_reconciliation/models/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- +from . import account_move_line +from . import account_journal \ No newline at end of file diff --git a/bank_reconciliation/models/account_journal.py b/bank_reconciliation/models/account_journal.py new file mode 100644 index 000000000..fa213a11f --- /dev/null +++ b/bank_reconciliation/models/account_journal.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +from odoo import api, fields, models, _ +from odoo.tools.misc import formatLang + + +class AccountJournal(models.Model): + _inherit = 'account.journal' + + @api.multi + def create_bank_statement(self): + """return action to create a bank statements. This button should be called only on journals with type =='bank'""" + self.bank_statements_source = 'manual' + action = self.env.ref('bank_reconciliation.action_bank_statement_wiz').read()[0] + action.update({ + # 'views': [[False, 'form']], + 'context': "{'default_journal_id': " + str(self.id) + "}", + }) + return action + + @api.multi + def get_journal_dashboard_datas(self): + res = super(AccountJournal, self).get_journal_dashboard_datas() + print(res) + account_sum = 0.0 + bank_balance = 0.0 + currency = self.currency_id or self.company_id.currency_id + account_ids = tuple(ac for ac in [self.default_debit_account_id.id, self.default_credit_account_id.id] if ac) + if account_ids: + amount_field = 'balance' if ( + not self.currency_id or self.currency_id == self.company_id.currency_id) else 'amount_currency' + query = """SELECT sum(%s) FROM account_move_line WHERE account_id in %%s AND date <= %%s;""" % ( + amount_field,) + self.env.cr.execute(query, (account_ids, fields.Date.today(),)) + query_results = self.env.cr.dictfetchall() + if query_results and query_results[0].get('sum') != None: + account_sum = query_results[0].get('sum') + query = """SELECT sum(%s) FROM account_move_line WHERE account_id in %%s AND date <= %%s AND + statement_date is not NULL;""" % (amount_field,) + self.env.cr.execute(query, (account_ids, fields.Date.today(),)) + query_results = self.env.cr.dictfetchall() + if query_results and query_results[0].get('sum') != None: + bank_balance = query_results[0].get('sum') + # account_id = self.default_debit_account_id.id or self.default_credit_account_id.id + # domain = [('account_id', '=', account_id),('statement_date', '!=', False)] + # lines = self.env['account.move.line'].search(domain) + # statement_balance += sum([line.balance for line in lines]) + difference = currency.round(account_sum - bank_balance) + 0.0 + res.update({ + 'last_balance': formatLang(self.env, currency.round(bank_balance) + 0.0, currency_obj=currency), + 'difference': formatLang(self.env, currency.round(difference) + 0.0, currency_obj=currency) + }) + print(res) + return res diff --git a/bank_reconciliation/models/account_move_line.py b/bank_reconciliation/models/account_move_line.py new file mode 100644 index 000000000..603030222 --- /dev/null +++ b/bank_reconciliation/models/account_move_line.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +from odoo import api, fields, models, _ + + +class AccountMoveLine(models.Model): + _inherit = "account.move.line" + + bank_statement_id = fields.Many2one('bank.statement', 'Bank Statement', copy=False) + statement_date = fields.Date('Bank.St Date', copy=False) + + @api.multi + def write(self, vals): + if not vals.get("statement_date"): + vals.update({"reconciled": False}) + if self.payment_id and self.payment_id.state == 'reconciled': + self.payment_id.state = 'posted' + elif vals.get("statement_date"): + vals.update({"reconciled": True}) + if self.payment_id: + self.payment_id.state = 'reconciled' + res = super(AccountMoveLine, self).write(vals) + return res \ No newline at end of file diff --git a/bank_reconciliation/security/ir.model.access.csv b/bank_reconciliation/security/ir.model.access.csv new file mode 100644 index 000000000..366936056 --- /dev/null +++ b/bank_reconciliation/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_bank_statement,bank_statement,model_bank_statement,account.group_account_user,1,1,1,1 \ No newline at end of file diff --git a/bank_reconciliation/static/description/bank_statement_edited.png b/bank_reconciliation/static/description/bank_statement_edited.png new file mode 100644 index 000000000..ada9c0409 Binary files /dev/null and b/bank_reconciliation/static/description/bank_statement_edited.png differ diff --git a/bank_reconciliation/static/description/bank_statement_wiz.png b/bank_reconciliation/static/description/bank_statement_wiz.png new file mode 100644 index 000000000..bfaab6152 Binary files /dev/null and b/bank_reconciliation/static/description/bank_statement_wiz.png differ diff --git a/bank_reconciliation/static/description/banner.jpg b/bank_reconciliation/static/description/banner.jpg new file mode 100644 index 000000000..424f632c7 Binary files /dev/null and b/bank_reconciliation/static/description/banner.jpg differ diff --git a/bank_reconciliation/static/description/cybro_logo.png b/bank_reconciliation/static/description/cybro_logo.png new file mode 100644 index 000000000..bb309114c Binary files /dev/null and b/bank_reconciliation/static/description/cybro_logo.png differ diff --git a/bank_reconciliation/static/description/dash_board.png b/bank_reconciliation/static/description/dash_board.png new file mode 100644 index 000000000..bb5364b94 Binary files /dev/null and b/bank_reconciliation/static/description/dash_board.png differ diff --git a/bank_reconciliation/static/description/dashboard_change.png b/bank_reconciliation/static/description/dashboard_change.png new file mode 100644 index 000000000..b63c2b67e Binary files /dev/null and b/bank_reconciliation/static/description/dashboard_change.png differ diff --git a/bank_reconciliation/static/description/icon.png b/bank_reconciliation/static/description/icon.png new file mode 100644 index 000000000..0067d211e Binary files /dev/null and b/bank_reconciliation/static/description/icon.png differ diff --git a/bank_reconciliation/static/description/index.html b/bank_reconciliation/static/description/index.html new file mode 100644 index 000000000..3bf3aa94a --- /dev/null +++ b/bank_reconciliation/static/description/index.html @@ -0,0 +1,128 @@ +
+
+
+

Manual Bank Reconciliation

+

Cybrosys Techno Solutions, www.cybrosys.com

+

...The traditional way of reconciling bank statement...

+
+
+
+ +
+
+
+

What it does ?

+
+ This module replaces the Odoo default bank statement reconciliation with traditional way of just putting the date in each line +
+
+ +
+
+
+   When You click on "New Statement" a window will open +
+
+
+ +
+
+
+
+ +
+
+
+   There you can see the list on journal items that are 'not reconciled' +
+
+
+ +
+
+
+

+
+

You can see the details about the current balance as per company books, bank balance based on already reconciled journal entries as 'Balance as per bank' and difference between them as 'Amount not reflected in Bank'

+

+
+
+
+ +
+
+
+    Fill the dates mentioned in bank statement in 'Bank.St Date' column of respective line. Click on 'Save' button before closing the window. +
+
+
+ +
+
+
+

+

Hope you have noticed the changes in Balance as per company books, Balance as per bank and Amount not reflected in Bank

+

+
+
+
+ +
+
+
+    You will be back on dashboard now. Did you notice the status updated there also +
+
+
+ +
+
+
+
+ +
+
+
+    One more thing to point out is, this will also mark the bank payments as 'Reconciled' +
+
+
+ +
+
+
+
+ +
+

Need Any Help?

+ +
+ + + + + + + + diff --git a/bank_reconciliation/static/description/payment_done.png b/bank_reconciliation/static/description/payment_done.png new file mode 100644 index 000000000..f133d7f8a Binary files /dev/null and b/bank_reconciliation/static/description/payment_done.png differ diff --git a/bank_reconciliation/static/description/payments.png b/bank_reconciliation/static/description/payments.png new file mode 100644 index 000000000..8465d35f3 Binary files /dev/null and b/bank_reconciliation/static/description/payments.png differ diff --git a/bank_reconciliation/views/account_journal_dashboard_view.xml b/bank_reconciliation/views/account_journal_dashboard_view.xml new file mode 100644 index 000000000..dad24c163 --- /dev/null +++ b/bank_reconciliation/views/account_journal_dashboard_view.xml @@ -0,0 +1,28 @@ + + + + account.journal.dashboard.kanban + account.journal + + +
+
+
+ Latest Statement +
+
+ +
+
+
+
+ Difference +
+
+ +
+
+
+
+
+
diff --git a/bank_reconciliation/views/account_move_line_view.xml b/bank_reconciliation/views/account_move_line_view.xml new file mode 100644 index 000000000..b7de4a67c --- /dev/null +++ b/bank_reconciliation/views/account_move_line_view.xml @@ -0,0 +1,41 @@ + + + + account.move.line.form + account.move.line + + + + + + + + + account.bank.statement.move.line.tree + account.move.line + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bank_reconciliation/wizard/__init__.py b/bank_reconciliation/wizard/__init__.py new file mode 100644 index 000000000..a0f401ce4 --- /dev/null +++ b/bank_reconciliation/wizard/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +from . import bank_statement_wiz diff --git a/bank_reconciliation/wizard/bank_statement_wiz.py b/bank_reconciliation/wizard/bank_statement_wiz.py new file mode 100644 index 000000000..1ad5a12b0 --- /dev/null +++ b/bank_reconciliation/wizard/bank_statement_wiz.py @@ -0,0 +1,76 @@ +# -*- coding: utf-8 -*- +from odoo import api, fields, models, _ + + +class BankStatement(models.Model): + _name = 'bank.statement' + + @api.onchange('journal_id', 'date_from', 'date_to') + def _get_lines(self): + self.account_id = self.journal_id.default_debit_account_id.id or self.journal_id.default_credit_account_id.id + self.currency_id = self.journal_id.currency_id or self.journal_id.company_id.currency_id or \ + self.env.user.company_id.currency_id + domain = [('account_id', '=', self.account_id.id), ('statement_date', '=', False)] + if self.date_from: + domain += [('date', '>=', self.date_from)] + if self.date_to: + domain += [('date', '<=', self.date_to)] + s_lines = [] + lines = self.env['account.move.line'].search(domain) + for line in self.statement_lines: + line.bank_statement_id = self.id + self.statement_lines = lines + + + @api.one + @api.depends('statement_lines.statement_date') + def _compute_amount(self): + print("_compute_amount") + gl_balance = 0 + bank_balance = 0 + current_update = 0 + domain = [('account_id', '=', self.account_id.id)] + lines = self.env['account.move.line'].search(domain) + gl_balance += sum([line.debit - line.credit for line in lines]) + domain += [('id', 'not in', self.statement_lines.ids), ('statement_date', '!=', False)] + lines = self.env['account.move.line'].search(domain) + bank_balance += sum([line.balance for line in lines]) + current_update += sum([line.debit - line.credit if line.statement_date else 0 for line in self.statement_lines]) + + self.gl_balance = gl_balance + self.bank_balance = bank_balance + current_update + self.balance_difference = self.gl_balance - self.bank_balance + + journal_id = fields.Many2one('account.journal', 'Bank', domain=[('type', '=', 'bank')]) + account_id = fields.Many2one('account.account', 'Bank Account') + date_from = fields.Date('Date From') + date_to = fields.Date('Date To') + statement_lines = fields.One2many('account.move.line', 'bank_statement_id') + # statement_lines = fields.One2many('bank.statement.line', 'bank_statement_id') + gl_balance = fields.Monetary('Balance as per Company Books', readonly=True, compute='_compute_amount') + bank_balance = fields.Monetary('Balance as per Bank', readonly=True, compute='_compute_amount') + balance_difference = fields.Monetary('Amounts not Reflected in Bank', readonly=True, compute='_compute_amount') + current_update = fields.Monetary('Balance of entries updated now') + currency_id = fields.Many2one('res.currency', string='Currency') + company_id = fields.Many2one('res.company', string='Company', + default=lambda self: self.env['res.company']._company_default_get('bank.statement')) + + +# class BankStatementLine(models.Model): +# _name = 'bank.statement.line' +# +# bank_statement_id = fields.Many2one('bank.statement', 'Bank Statement') +# move_id = fields.Many2one('account.move.line', 'Journal Item') +# date = fields.Date(related='move_id.date', string='Date') +# name = fields.Char(string="Label", related='move_id.name') +# ref = fields.Char(related='move_id.ref', string='Reference') +# partner_id = fields.Many2one('res.partner', string='Partner', related='move_id.partner_id') +# account_id = fields.Many2one('account.account', 'Account', related='move_id.account_id') +# debit = fields.Monetary(currency_field='company_currency_id', related='move_id.debit') +# credit = fields.Monetary(currency_field='company_currency_id', related='move_id.credit') +# amount_currency = fields.Monetary(related='move_id.amount_currency') +# currency_id = fields.Many2one('res.currency', string='Currency', related='move_id.currency_id') +# company_currency_id = fields.Many2one('res.currency', string="Company Currency", readonly=True, +# related='move_id.currency_id') +# date_maturity = fields.Date(string='Due date', related='move_id.date_maturity') +# statement_date = fields.Date('Bank.St Date', related='move_id.statement_date') diff --git a/bank_reconciliation/wizard/bank_statement_wiz_view.xml b/bank_reconciliation/wizard/bank_statement_wiz_view.xml new file mode 100644 index 000000000..a8eca171d --- /dev/null +++ b/bank_reconciliation/wizard/bank_statement_wiz_view.xml @@ -0,0 +1,57 @@ + + + + + bank.statement.reconciliation + bank.statement + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + Bank Statement Reconciliation + bank.statement + ir.actions.act_window + form + form + new + + + +
\ No newline at end of file