Support bank reconciliation summary on date != today
Add wizard for that reportpull/699/head
parent
0fa1370d7e
commit
03c1a8924a
|
@ -2,3 +2,4 @@
|
||||||
|
|
||||||
from . import models
|
from . import models
|
||||||
from . import report
|
from . import report
|
||||||
|
from . import wizard
|
||||||
|
|
|
@ -12,7 +12,9 @@
|
||||||
'depends': ['account', 'report_xlsx'],
|
'depends': ['account', 'report_xlsx'],
|
||||||
'data': [
|
'data': [
|
||||||
'report/report.xml',
|
'report/report.xml',
|
||||||
'views/account_bank_statement_view.xml',
|
'views/account_bank_statement.xml',
|
||||||
|
'views/account_move_line.xml',
|
||||||
|
'wizard/bank_reconciliation_report_wizard_view.xml',
|
||||||
],
|
],
|
||||||
'installable': True,
|
'installable': True,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from . import account_bank_statement
|
from . import account_bank_statement
|
||||||
|
from . import account_move_line
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# © 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
from odoo import fields, models
|
||||||
|
|
||||||
|
|
||||||
|
class AccountMoveLine(models.Model):
|
||||||
|
_inherit = 'account.move.line'
|
||||||
|
|
||||||
|
statement_line_date = fields.Date(
|
||||||
|
string='Statement Line Date',
|
||||||
|
related='move_id.statement_line_id.date', store=True, readonly=True)
|
|
@ -3,7 +3,7 @@
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
from odoo.addons.report_xlsx.report.report_xlsx import ReportXlsx
|
from odoo.addons.report_xlsx.report.report_xlsx import ReportXlsx
|
||||||
from odoo import _
|
from odoo import fields, _
|
||||||
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT
|
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
@ -11,10 +11,22 @@ from datetime import datetime
|
||||||
class BankReconciliationXlsx(ReportXlsx):
|
class BankReconciliationXlsx(ReportXlsx):
|
||||||
|
|
||||||
def generate_xlsx_report(self, workbook, data, journals):
|
def generate_xlsx_report(self, workbook, data, journals):
|
||||||
|
# I can't use fields.Date.context_today(self)
|
||||||
|
date = data.get('date') or datetime.today()
|
||||||
|
date_dt = fields.Date.from_string(date)
|
||||||
no_bank_journal = True
|
no_bank_journal = True
|
||||||
for o in journals.filtered(lambda o: o.type == 'bank'):
|
for o in journals.filtered(lambda o: o.type == 'bank'):
|
||||||
no_bank_journal = False
|
no_bank_journal = False
|
||||||
# Start styles
|
# Start styles
|
||||||
|
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')
|
||||||
|
|
||||||
doc_title = workbook.add_format({'bold': True, 'font_size': 16})
|
doc_title = workbook.add_format({'bold': True, 'font_size': 16})
|
||||||
col_title = workbook.add_format({
|
col_title = workbook.add_format({
|
||||||
'bold': True, 'bg_color': '#e2e2fa',
|
'bold': True, 'bg_color': '#e2e2fa',
|
||||||
|
@ -24,19 +36,16 @@ class BankReconciliationXlsx(ReportXlsx):
|
||||||
'bold': True, 'bg_color': '#e6e6fa',
|
'bold': True, 'bg_color': '#e6e6fa',
|
||||||
'font_size': 10, 'align': 'right',
|
'font_size': 10, 'align': 'right',
|
||||||
})
|
})
|
||||||
|
title_date = workbook.add_format({
|
||||||
|
'bg_color': '#f6f6ff', 'bold': True,
|
||||||
|
'num_format': xls_date_format,
|
||||||
|
'font_size': 10,
|
||||||
|
'align': 'left'})
|
||||||
label_bold = workbook.add_format({
|
label_bold = workbook.add_format({
|
||||||
'bold': True, 'text_wrap': False, 'font_size': 10})
|
'bold': True, 'text_wrap': False, 'font_size': 10})
|
||||||
none = workbook.add_format({
|
none = workbook.add_format({
|
||||||
'bold': True, 'font_size': 10, 'align': 'right'})
|
'bold': True, 'font_size': 10, 'align': 'right'})
|
||||||
regular = workbook.add_format({'font_size': 10})
|
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:
|
if '%' in xls_date_format:
|
||||||
# fallback
|
# fallback
|
||||||
xls_date_format = 'yyyy-mm-dd'
|
xls_date_format = 'yyyy-mm-dd'
|
||||||
|
@ -71,10 +80,10 @@ class BankReconciliationXlsx(ReportXlsx):
|
||||||
sheet.set_column(5, 5, 14)
|
sheet.set_column(5, 5, 14)
|
||||||
sheet.set_column(6, 6, 22)
|
sheet.set_column(6, 6, 22)
|
||||||
row = 2
|
row = 2
|
||||||
sheet.write(row, 0, _("Date:"), label_bold)
|
sheet.write(row, 0, _("Date:"), title_right)
|
||||||
# I can't use fields.Date.context_today(self)
|
sheet.write(row, 1, date_dt, title_date)
|
||||||
sheet.write(row, 1, datetime.today(), regular_date)
|
|
||||||
# 1) Show accounting balance of bank account
|
# 1) Show accounting balance of bank account
|
||||||
|
row += 1
|
||||||
bank_account = o.default_debit_account_id
|
bank_account = o.default_debit_account_id
|
||||||
sheet.write(
|
sheet.write(
|
||||||
row, 3,
|
row, 3,
|
||||||
|
@ -84,8 +93,8 @@ class BankReconciliationXlsx(ReportXlsx):
|
||||||
# if not o.currency_id else 'amount_currency'
|
# if not o.currency_id else 'amount_currency'
|
||||||
query = """
|
query = """
|
||||||
SELECT sum(%s) FROM account_move_line
|
SELECT sum(%s) FROM account_move_line
|
||||||
WHERE account_id=%%s""" % (amount_field,)
|
WHERE account_id=%%s AND date <= %%s""" % (amount_field, )
|
||||||
self.env.cr.execute(query, (bank_account.id,))
|
self.env.cr.execute(query, (bank_account.id, date))
|
||||||
query_results = self.env.cr.dictfetchall()
|
query_results = self.env.cr.dictfetchall()
|
||||||
if query_results:
|
if query_results:
|
||||||
account_bal = query_results[0].get('sum') or 0.0
|
account_bal = query_results[0].get('sum') or 0.0
|
||||||
|
@ -95,7 +104,8 @@ class BankReconciliationXlsx(ReportXlsx):
|
||||||
sheet.write(row, 4, account_bal, regular_currency_bg)
|
sheet.write(row, 4, account_bal, regular_currency_bg)
|
||||||
bank_bal = account_bal
|
bank_bal = account_bal
|
||||||
formula = '=E%d' % (row + 1)
|
formula = '=E%d' % (row + 1)
|
||||||
# 2) Show account move line that are not linked to bank account
|
# 2) Show account move line that are not linked to bank statement
|
||||||
|
# line or linked to a statement line after the date
|
||||||
row += 2
|
row += 2
|
||||||
sheet.write(
|
sheet.write(
|
||||||
row, 0, _(
|
row, 0, _(
|
||||||
|
@ -105,7 +115,9 @@ class BankReconciliationXlsx(ReportXlsx):
|
||||||
mlines = self.env['account.move.line'].search([
|
mlines = self.env['account.move.line'].search([
|
||||||
('account_id', '=', bank_account.id),
|
('account_id', '=', bank_account.id),
|
||||||
('journal_id', '=', o.id), # to avoid initial line
|
('journal_id', '=', o.id), # to avoid initial line
|
||||||
('statement_id', '=', False)])
|
('date', '<=', date),
|
||||||
|
'|', ('statement_line_date', '=', False),
|
||||||
|
('statement_line_date', '>', date)])
|
||||||
if not mlines:
|
if not mlines:
|
||||||
sheet.write(row, 4, _('NONE'), none)
|
sheet.write(row, 4, _('NONE'), none)
|
||||||
else:
|
else:
|
||||||
|
@ -115,8 +127,9 @@ class BankReconciliationXlsx(ReportXlsx):
|
||||||
sheet.write(row, 2, _('Ref.'), col_title)
|
sheet.write(row, 2, _('Ref.'), col_title)
|
||||||
sheet.write(row, 3, _('Partner'), col_title)
|
sheet.write(row, 3, _('Partner'), col_title)
|
||||||
sheet.write(row, 4, _('Amount'), col_title)
|
sheet.write(row, 4, _('Amount'), col_title)
|
||||||
sheet.write(row, 5, _('Move Number'), col_title)
|
sheet.write(row, 5, _('Statement Line Date'), col_title)
|
||||||
sheet.write(row, 6, _('Counter-part'), col_title)
|
sheet.write(row, 6, _('Move Number'), col_title)
|
||||||
|
sheet.write(row, 7, _('Counter-part'), col_title)
|
||||||
m_start_row = m_end_row = row + 1
|
m_start_row = m_end_row = row + 1
|
||||||
for mline in mlines:
|
for mline in mlines:
|
||||||
row += 1
|
row += 1
|
||||||
|
@ -131,7 +144,9 @@ class BankReconciliationXlsx(ReportXlsx):
|
||||||
sheet.write(
|
sheet.write(
|
||||||
row, 3, mline.partner_id.display_name or '', regular)
|
row, 3, mline.partner_id.display_name or '', regular)
|
||||||
sheet.write(row, 4, mline.balance, regular_currency)
|
sheet.write(row, 4, mline.balance, regular_currency)
|
||||||
sheet.write(row, 5, move.name, regular)
|
sheet.write(
|
||||||
|
row, 5, mline.statement_line_date, regular_date)
|
||||||
|
sheet.write(row, 6, move.name, regular)
|
||||||
# counter-part accounts
|
# counter-part accounts
|
||||||
cpart = []
|
cpart = []
|
||||||
for line in move.line_ids:
|
for line in move.line_ids:
|
||||||
|
@ -139,7 +154,7 @@ class BankReconciliationXlsx(ReportXlsx):
|
||||||
line.account_id != bank_account and
|
line.account_id != bank_account and
|
||||||
line.account_id.code not in cpart):
|
line.account_id.code not in cpart):
|
||||||
cpart.append(line.account_id.code)
|
cpart.append(line.account_id.code)
|
||||||
sheet.write(row, 6, ' ,'.join(cpart), regular)
|
sheet.write(row, 7, ' ,'.join(cpart), regular)
|
||||||
|
|
||||||
formula += '-SUM(E%d:E%d)' % (m_start_row + 1, m_end_row + 1)
|
formula += '-SUM(E%d:E%d)' % (m_start_row + 1, m_end_row + 1)
|
||||||
|
|
||||||
|
@ -151,7 +166,8 @@ class BankReconciliationXlsx(ReportXlsx):
|
||||||
label_bold)
|
label_bold)
|
||||||
blines = self.env['account.bank.statement.line'].search([
|
blines = self.env['account.bank.statement.line'].search([
|
||||||
('journal_entry_ids', '=', False),
|
('journal_entry_ids', '=', False),
|
||||||
('journal_id', '=', o.id)])
|
('journal_id', '=', o.id),
|
||||||
|
('date', '<=', date)])
|
||||||
if not blines:
|
if not blines:
|
||||||
sheet.write(row, 4, _('NONE'), none)
|
sheet.write(row, 4, _('NONE'), none)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?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_move_line_form" model="ir.ui.view">
|
||||||
|
<field name="name">bank_rec_summarry.account_move_line_form</field>
|
||||||
|
<field name="model">account.move.line</field>
|
||||||
|
<field name="inherit_id" ref="account.view_move_line_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="statement_id" position="after">
|
||||||
|
<field name="statement_line_date"/>
|
||||||
|
</field>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
</odoo>
|
|
@ -0,0 +1,3 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from . import bank_reconciliation_report_wizard
|
|
@ -0,0 +1,41 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# © 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
from odoo import api, fields, models
|
||||||
|
|
||||||
|
|
||||||
|
class BankReconciliationReportWizard(models.TransientModel):
|
||||||
|
_name = "bank.reconciliation.report.wizard"
|
||||||
|
_description = "Bank Reconciliation Report Wizard"
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def _default_journal_ids(self):
|
||||||
|
journals = self.env['account.journal'].search([
|
||||||
|
('type', '=', 'bank'),
|
||||||
|
('company_id', '=', self.env.user.company_id.id)])
|
||||||
|
return journals
|
||||||
|
|
||||||
|
company_id = fields.Many2one(
|
||||||
|
'res.company', string='Company',
|
||||||
|
default=lambda self: self.env.user.company_id)
|
||||||
|
date = fields.Date(
|
||||||
|
required=True,
|
||||||
|
default=fields.Date.context_today)
|
||||||
|
journal_ids = fields.Many2many(
|
||||||
|
'account.journal', string='Bank Journals',
|
||||||
|
domain=[('type', '=', 'bank')], required=True,
|
||||||
|
default=_default_journal_ids)
|
||||||
|
|
||||||
|
def open_xlsx(self):
|
||||||
|
action = {
|
||||||
|
'type': 'ir.actions.report.xml',
|
||||||
|
'report_name': 'bank.reconciliation.xlsx',
|
||||||
|
'datas': {
|
||||||
|
'model': 'account.journal',
|
||||||
|
'ids': self.journal_ids.ids,
|
||||||
|
'date': self.date,
|
||||||
|
},
|
||||||
|
'context': self._context,
|
||||||
|
}
|
||||||
|
return action
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?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="bank_reconciliation_report_wizard_form" model="ir.ui.view">
|
||||||
|
<field name="name">bank.reconciliation.report.wizard.form</field>
|
||||||
|
<field name="model">bank.reconciliation.report.wizard</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="Bank Reconciliation Report">
|
||||||
|
<group name="main">
|
||||||
|
<field name="company_id" groups="base.group_multi_company"/>
|
||||||
|
<field name="date"/>
|
||||||
|
<field name="journal_ids" widget="many2many_tags"/>
|
||||||
|
</group>
|
||||||
|
<footer>
|
||||||
|
<button name="open_xlsx" string="Export XLSX" type="object" class="btn-primary"/>
|
||||||
|
<button special="cancel" string="Cancel" class="oe_link"/>
|
||||||
|
</footer>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="bank_reconciliation_report_wizard_action" model="ir.actions.act_window">
|
||||||
|
<field name="name">Bank Reconciliation Report</field>
|
||||||
|
<field name="res_model">bank.reconciliation.report.wizard</field>
|
||||||
|
<field name="view_mode">form</field>
|
||||||
|
<field name="target">new</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<menuitem id="bank_reconciliation_report_wizard_menu" action="bank_reconciliation_report_wizard_action" parent="account.menu_finance_reports" groups="account.group_account_manager,account.group_account_user"/>
|
||||||
|
|
||||||
|
</odoo>
|
Loading…
Reference in New Issue