[MIG] account_financial_report_qweb: Migration to 11.0
* dynamize general ledger
This commit is contained in:
committed by
chaule97
parent
caf8ce9698
commit
554ad61027
15
account_financial_report/report/__init__.py
Normal file
15
account_financial_report/report/__init__.py
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
# ?? 2015 Yannick Vaucher (Camptocamp)
|
||||
# ?? 2016 Damien Crier (Camptocamp)
|
||||
# ?? 2016 Julien Coux (Camptocamp)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).-
|
||||
|
||||
from . import abstract_report_xlsx
|
||||
from . import aged_partner_balance
|
||||
from . import aged_partner_balance_xlsx
|
||||
from . import general_ledger
|
||||
from . import general_ledger_xlsx
|
||||
from . import open_items
|
||||
from . import open_items_xlsx
|
||||
from . import trial_balance
|
||||
from . import trial_balance_xlsx
|
||||
301
account_financial_report/report/abstract_report_xlsx.py
Normal file
301
account_financial_report/report/abstract_report_xlsx.py
Normal file
@@ -0,0 +1,301 @@
|
||||
|
||||
# Author: Julien Coux
|
||||
# Copyright 2016 Camptocamp SA
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
from odoo import models
|
||||
|
||||
|
||||
class AbstractReportXslx(models.AbstractModel):
|
||||
_name = 'report.account_financial_report.abstract_report_xlsx'
|
||||
_inherit = 'report.report_xlsx.abstract'
|
||||
|
||||
def __init__(self, pool, cr):
|
||||
# main sheet which will contains report
|
||||
self.sheet = None
|
||||
|
||||
# columns of the report
|
||||
self.columns = None
|
||||
|
||||
# row_pos must be incremented at each writing lines
|
||||
self.row_pos = None
|
||||
|
||||
# Formats
|
||||
self.format_right = None
|
||||
self.format_right_bold_italic = None
|
||||
self.format_bold = None
|
||||
self.format_header_left = None
|
||||
self.format_header_center = None
|
||||
self.format_header_right = None
|
||||
self.format_header_amount = None
|
||||
self.format_amount = None
|
||||
self.format_percent_bold_italic = None
|
||||
|
||||
def get_workbook_options(self):
|
||||
return {'constant_memory': True}
|
||||
|
||||
def generate_xlsx_report(self, workbook, data, objects):
|
||||
report = objects
|
||||
|
||||
self.row_pos = 0
|
||||
|
||||
self._define_formats(workbook)
|
||||
|
||||
report_name = self._get_report_name()
|
||||
filters = self._get_report_filters(report)
|
||||
self.columns = self._get_report_columns(report)
|
||||
|
||||
self.sheet = workbook.add_worksheet(report_name[:31])
|
||||
|
||||
self._set_column_width()
|
||||
|
||||
self._write_report_title(report_name)
|
||||
|
||||
self._write_filters(filters)
|
||||
|
||||
self._generate_report_content(workbook, report)
|
||||
|
||||
def _define_formats(self, workbook):
|
||||
""" Add cell formats to current workbook.
|
||||
Those formats can be used on all cell.
|
||||
|
||||
Available formats are :
|
||||
* format_bold
|
||||
* format_right
|
||||
* format_right_bold_italic
|
||||
* format_header_left
|
||||
* format_header_center
|
||||
* format_header_right
|
||||
* format_header_amount
|
||||
* format_amount
|
||||
* format_percent_bold_italic
|
||||
"""
|
||||
self.format_bold = workbook.add_format({'bold': True})
|
||||
self.format_right = workbook.add_format({'align': 'right'})
|
||||
self.format_right_bold_italic = workbook.add_format(
|
||||
{'align': 'right', 'bold': True, 'italic': True}
|
||||
)
|
||||
self.format_header_left = workbook.add_format(
|
||||
{'bold': True,
|
||||
'border': True,
|
||||
'bg_color': '#FFFFCC'})
|
||||
self.format_header_center = workbook.add_format(
|
||||
{'bold': True,
|
||||
'align': 'center',
|
||||
'border': True,
|
||||
'bg_color': '#FFFFCC'})
|
||||
self.format_header_right = workbook.add_format(
|
||||
{'bold': True,
|
||||
'align': 'right',
|
||||
'border': True,
|
||||
'bg_color': '#FFFFCC'})
|
||||
self.format_header_amount = workbook.add_format(
|
||||
{'bold': True,
|
||||
'border': True,
|
||||
'bg_color': '#FFFFCC'})
|
||||
self.format_header_amount.set_num_format('#,##0.00')
|
||||
self.format_amount = workbook.add_format()
|
||||
self.format_amount.set_num_format('#,##0.00')
|
||||
self.format_percent_bold_italic = workbook.add_format(
|
||||
{'bold': True, 'italic': True}
|
||||
)
|
||||
self.format_percent_bold_italic.set_num_format('#,##0.00%')
|
||||
|
||||
def _set_column_width(self):
|
||||
"""Set width for all defined columns.
|
||||
Columns are defined with `_get_report_columns` method.
|
||||
"""
|
||||
for position, column in self.columns.items():
|
||||
self.sheet.set_column(position, position, column['width'])
|
||||
|
||||
def _write_report_title(self, title):
|
||||
"""Write report title on current line using all defined columns width.
|
||||
Columns are defined with `_get_report_columns` method.
|
||||
"""
|
||||
self.sheet.merge_range(
|
||||
self.row_pos, 0, self.row_pos, len(self.columns) - 1,
|
||||
title, self.format_bold
|
||||
)
|
||||
self.row_pos += 3
|
||||
|
||||
def _write_filters(self, filters):
|
||||
"""Write one line per filters on starting on current line.
|
||||
Columns number for filter name is defined
|
||||
with `_get_col_count_filter_name` method.
|
||||
Columns number for filter value is define
|
||||
with `_get_col_count_filter_value` method.
|
||||
"""
|
||||
col_name = 1
|
||||
col_count_filter_name = self._get_col_count_filter_name()
|
||||
col_count_filter_value = self._get_col_count_filter_value()
|
||||
col_value = col_name + col_count_filter_name + 1
|
||||
for title, value in filters:
|
||||
self.sheet.merge_range(
|
||||
self.row_pos, col_name,
|
||||
self.row_pos, col_name + col_count_filter_name - 1,
|
||||
title, self.format_header_left)
|
||||
self.sheet.merge_range(
|
||||
self.row_pos, col_value,
|
||||
self.row_pos, col_value + col_count_filter_value - 1,
|
||||
value)
|
||||
self.row_pos += 1
|
||||
self.row_pos += 2
|
||||
|
||||
def write_array_title(self, title):
|
||||
"""Write array title on current line using all defined columns width.
|
||||
Columns are defined with `_get_report_columns` method.
|
||||
"""
|
||||
self.sheet.merge_range(
|
||||
self.row_pos, 0, self.row_pos, len(self.columns) - 1,
|
||||
title, self.format_bold
|
||||
)
|
||||
self.row_pos += 1
|
||||
|
||||
def write_array_header(self):
|
||||
"""Write array header on current line using all defined columns name.
|
||||
Columns are defined with `_get_report_columns` method.
|
||||
"""
|
||||
for col_pos, column in self.columns.items():
|
||||
self.sheet.write(self.row_pos, col_pos, column['header'],
|
||||
self.format_header_center)
|
||||
self.row_pos += 1
|
||||
|
||||
def write_line(self, line_object):
|
||||
"""Write a line on current line using all defined columns field name.
|
||||
Columns are defined with `_get_report_columns` method.
|
||||
"""
|
||||
for col_pos, column in self.columns.items():
|
||||
value = getattr(line_object, column['field'])
|
||||
cell_type = column.get('type', 'string')
|
||||
if cell_type == 'string':
|
||||
self.sheet.write_string(self.row_pos, col_pos, value or '')
|
||||
elif cell_type == 'amount':
|
||||
self.sheet.write_number(
|
||||
self.row_pos, col_pos, float(value), self.format_amount
|
||||
)
|
||||
self.row_pos += 1
|
||||
|
||||
def write_initial_balance(self, my_object, label):
|
||||
"""Write a specific initial balance line on current line
|
||||
using defined columns field_initial_balance name.
|
||||
|
||||
Columns are defined with `_get_report_columns` method.
|
||||
"""
|
||||
col_pos_label = self._get_col_pos_initial_balance_label()
|
||||
self.sheet.write(self.row_pos, col_pos_label, label, self.format_right)
|
||||
for col_pos, column in self.columns.items():
|
||||
if column.get('field_initial_balance'):
|
||||
value = getattr(my_object, column['field_initial_balance'])
|
||||
cell_type = column.get('type', 'string')
|
||||
if cell_type == 'string':
|
||||
self.sheet.write_string(self.row_pos, col_pos, value or '')
|
||||
elif cell_type == 'amount':
|
||||
self.sheet.write_number(
|
||||
self.row_pos, col_pos, float(value), self.format_amount
|
||||
)
|
||||
self.row_pos += 1
|
||||
|
||||
def write_ending_balance(self, my_object, name, label):
|
||||
"""Write a specific ending balance line on current line
|
||||
using defined columns field_final_balance name.
|
||||
|
||||
Columns are defined with `_get_report_columns` method.
|
||||
"""
|
||||
for i in range(0, len(self.columns)):
|
||||
self.sheet.write(self.row_pos, i, '', self.format_header_right)
|
||||
row_count_name = self._get_col_count_final_balance_name()
|
||||
col_pos_label = self._get_col_pos_final_balance_label()
|
||||
self.sheet.merge_range(
|
||||
self.row_pos, 0, self.row_pos, row_count_name - 1, name,
|
||||
self.format_header_left
|
||||
)
|
||||
self.sheet.write(self.row_pos, col_pos_label, label,
|
||||
self.format_header_right)
|
||||
for col_pos, column in self.columns.items():
|
||||
if column.get('field_final_balance'):
|
||||
value = getattr(my_object, column['field_final_balance'])
|
||||
cell_type = column.get('type', 'string')
|
||||
if cell_type == 'string':
|
||||
self.sheet.write_string(self.row_pos, col_pos, value or '',
|
||||
self.format_header_right)
|
||||
elif cell_type == 'amount':
|
||||
self.sheet.write_number(
|
||||
self.row_pos, col_pos, float(value),
|
||||
self.format_header_amount
|
||||
)
|
||||
self.row_pos += 1
|
||||
|
||||
def _generate_report_content(self, workbook, report):
|
||||
pass
|
||||
|
||||
def _get_report_name(self):
|
||||
"""
|
||||
Allow to define the report name.
|
||||
Report name will be used as sheet name and as report title.
|
||||
|
||||
:return: the report name
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def _get_report_columns(self, report):
|
||||
"""
|
||||
Allow to define the report columns
|
||||
which will be used to generate report.
|
||||
|
||||
:return: the report columns as dict
|
||||
|
||||
:Example:
|
||||
|
||||
{
|
||||
0: {'header': 'Simple column',
|
||||
'field': 'field_name_on_my_object',
|
||||
'width': 11},
|
||||
1: {'header': 'Amount column',
|
||||
'field': 'field_name_on_my_object',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
}
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def _get_report_filters(self, report):
|
||||
"""
|
||||
:return: the report filters as list
|
||||
|
||||
:Example:
|
||||
|
||||
[
|
||||
['first_filter_name', 'first_filter_value'],
|
||||
['second_filter_name', 'second_filter_value']
|
||||
]
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def _get_col_count_filter_name(self):
|
||||
"""
|
||||
:return: the columns number used for filter names.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def _get_col_count_filter_value(self):
|
||||
"""
|
||||
:return: the columns number used for filter values.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def _get_col_pos_initial_balance_label(self):
|
||||
"""
|
||||
:return: the columns position used for initial balance label.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def _get_col_count_final_balance_name(self):
|
||||
"""
|
||||
:return: the columns number used for final balance name.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def _get_col_pos_final_balance_label(self):
|
||||
"""
|
||||
:return: the columns position used for final balance label.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
628
account_financial_report/report/aged_partner_balance.py
Normal file
628
account_financial_report/report/aged_partner_balance.py
Normal file
@@ -0,0 +1,628 @@
|
||||
# ?? 2016 Julien Coux (Camptocamp)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import models, fields, api
|
||||
|
||||
|
||||
class AgedPartnerBalanceReport(models.TransientModel):
|
||||
""" Here, we just define class fields.
|
||||
For methods, go more bottom at this file.
|
||||
|
||||
The class hierarchy is :
|
||||
* AgedPartnerBalanceReport
|
||||
** AgedPartnerBalanceReportAccount
|
||||
*** AgedPartnerBalanceReportPartner
|
||||
**** AgedPartnerBalanceReportLine
|
||||
**** AgedPartnerBalanceReportMoveLine
|
||||
If "show_move_line_details" is selected
|
||||
"""
|
||||
|
||||
_name = 'report_aged_partner_balance'
|
||||
|
||||
# Filters fields, used for data computation
|
||||
date_at = fields.Date()
|
||||
only_posted_moves = fields.Boolean()
|
||||
company_id = fields.Many2one(comodel_name='res.company')
|
||||
filter_account_ids = fields.Many2many(comodel_name='account.account')
|
||||
filter_partner_ids = fields.Many2many(comodel_name='res.partner')
|
||||
show_move_line_details = fields.Boolean()
|
||||
|
||||
# Open Items Report Data fields, used as base for compute the data reports
|
||||
open_items_id = fields.Many2one(comodel_name='report_open_items')
|
||||
|
||||
# Data fields, used to browse report data
|
||||
account_ids = fields.One2many(
|
||||
comodel_name='report_aged_partner_balance_account',
|
||||
inverse_name='report_id'
|
||||
)
|
||||
|
||||
|
||||
class AgedPartnerBalanceReportAccount(models.TransientModel):
|
||||
_name = 'report_aged_partner_balance_account'
|
||||
_order = 'code ASC'
|
||||
|
||||
report_id = fields.Many2one(
|
||||
comodel_name='report_aged_partner_balance',
|
||||
ondelete='cascade',
|
||||
index=True
|
||||
)
|
||||
|
||||
# Data fields, used to keep link with real object
|
||||
account_id = fields.Many2one(
|
||||
'account.account',
|
||||
index=True
|
||||
)
|
||||
|
||||
# Data fields, used for report display
|
||||
code = fields.Char()
|
||||
name = fields.Char()
|
||||
|
||||
cumul_amount_residual = fields.Float(digits=(16, 2))
|
||||
cumul_current = fields.Float(digits=(16, 2))
|
||||
cumul_age_30_days = fields.Float(digits=(16, 2))
|
||||
cumul_age_60_days = fields.Float(digits=(16, 2))
|
||||
cumul_age_90_days = fields.Float(digits=(16, 2))
|
||||
cumul_age_120_days = fields.Float(digits=(16, 2))
|
||||
cumul_older = fields.Float(digits=(16, 2))
|
||||
|
||||
percent_current = fields.Float(digits=(16, 2))
|
||||
percent_age_30_days = fields.Float(digits=(16, 2))
|
||||
percent_age_60_days = fields.Float(digits=(16, 2))
|
||||
percent_age_90_days = fields.Float(digits=(16, 2))
|
||||
percent_age_120_days = fields.Float(digits=(16, 2))
|
||||
percent_older = fields.Float(digits=(16, 2))
|
||||
|
||||
# Data fields, used to browse report data
|
||||
partner_ids = fields.One2many(
|
||||
comodel_name='report_aged_partner_balance_partner',
|
||||
inverse_name='report_account_id'
|
||||
)
|
||||
|
||||
|
||||
class AgedPartnerBalanceReportPartner(models.TransientModel):
|
||||
_name = 'report_aged_partner_balance_partner'
|
||||
|
||||
report_account_id = fields.Many2one(
|
||||
comodel_name='report_aged_partner_balance_account',
|
||||
ondelete='cascade',
|
||||
index=True
|
||||
)
|
||||
|
||||
# Data fields, used to keep link with real object
|
||||
partner_id = fields.Many2one(
|
||||
'res.partner',
|
||||
index=True
|
||||
)
|
||||
|
||||
# Data fields, used for report display
|
||||
name = fields.Char()
|
||||
|
||||
# Data fields, used to browse report data
|
||||
move_line_ids = fields.One2many(
|
||||
comodel_name='report_aged_partner_balance_move_line',
|
||||
inverse_name='report_partner_id'
|
||||
)
|
||||
line_ids = fields.One2many(
|
||||
comodel_name='report_aged_partner_balance_line',
|
||||
inverse_name='report_partner_id'
|
||||
)
|
||||
|
||||
@api.model
|
||||
def _generate_order_by(self, order_spec, query):
|
||||
"""Custom order to display "No partner allocated" at last position."""
|
||||
return """
|
||||
ORDER BY
|
||||
CASE
|
||||
WHEN
|
||||
"report_aged_partner_balance_partner"."partner_id" IS NOT NULL
|
||||
THEN 0
|
||||
ELSE 1
|
||||
END,
|
||||
"report_aged_partner_balance_partner"."name"
|
||||
"""
|
||||
|
||||
|
||||
class AgedPartnerBalanceReportLine(models.TransientModel):
|
||||
_name = 'report_aged_partner_balance_line'
|
||||
|
||||
report_partner_id = fields.Many2one(
|
||||
comodel_name='report_aged_partner_balance_partner',
|
||||
ondelete='cascade',
|
||||
index=True
|
||||
)
|
||||
|
||||
# Data fields, used for report display
|
||||
partner = fields.Char()
|
||||
amount_residual = fields.Float(digits=(16, 2))
|
||||
current = fields.Float(digits=(16, 2))
|
||||
age_30_days = fields.Float(digits=(16, 2))
|
||||
age_60_days = fields.Float(digits=(16, 2))
|
||||
age_90_days = fields.Float(digits=(16, 2))
|
||||
age_120_days = fields.Float(digits=(16, 2))
|
||||
older = fields.Float(digits=(16, 2))
|
||||
|
||||
|
||||
class AgedPartnerBalanceReportMoveLine(models.TransientModel):
|
||||
_name = 'report_aged_partner_balance_move_line'
|
||||
|
||||
report_partner_id = fields.Many2one(
|
||||
comodel_name='report_aged_partner_balance_partner',
|
||||
ondelete='cascade',
|
||||
index=True
|
||||
)
|
||||
|
||||
# Data fields, used to keep link with real object
|
||||
move_line_id = fields.Many2one('account.move.line')
|
||||
|
||||
# Data fields, used for report display
|
||||
date = fields.Date()
|
||||
date_due = fields.Date()
|
||||
entry = fields.Char()
|
||||
journal = fields.Char()
|
||||
account = fields.Char()
|
||||
partner = fields.Char()
|
||||
label = fields.Char()
|
||||
|
||||
amount_residual = fields.Float(digits=(16, 2))
|
||||
current = fields.Float(digits=(16, 2))
|
||||
age_30_days = fields.Float(digits=(16, 2))
|
||||
age_60_days = fields.Float(digits=(16, 2))
|
||||
age_90_days = fields.Float(digits=(16, 2))
|
||||
age_120_days = fields.Float(digits=(16, 2))
|
||||
older = fields.Float(digits=(16, 2))
|
||||
|
||||
|
||||
class AgedPartnerBalanceReportCompute(models.TransientModel):
|
||||
""" Here, we just define methods.
|
||||
For class fields, go more top at this file.
|
||||
"""
|
||||
|
||||
_inherit = 'report_aged_partner_balance'
|
||||
|
||||
@api.multi
|
||||
def print_report(self, report_type):
|
||||
self.ensure_one()
|
||||
if report_type == 'xlsx':
|
||||
report_name = 'a_f_r.report_aged_partner_balance_xlsx'
|
||||
else:
|
||||
report_name = 'account_financial_report.' \
|
||||
'report_aged_partner_balance_qweb'
|
||||
report = self.env['ir.actions.report'].search(
|
||||
[('report_name', '=', report_name),
|
||||
('report_type', '=', report_type)], limit=1)
|
||||
return report.report_action(self)
|
||||
|
||||
def _get_html(self):
|
||||
result = {}
|
||||
rcontext = {}
|
||||
context = dict(self.env.context)
|
||||
report = self.browse(context.get('active_id'))
|
||||
if report:
|
||||
rcontext['o'] = report
|
||||
result['html'] = self.env.ref(
|
||||
'account_financial_report.report_aged_partner_balance').render(
|
||||
rcontext)
|
||||
return result
|
||||
|
||||
@api.model
|
||||
def get_html(self, given_context=None):
|
||||
return self._get_html()
|
||||
|
||||
def _prepare_report_open_items(self):
|
||||
self.ensure_one()
|
||||
return {
|
||||
'date_at': self.date_at,
|
||||
'only_posted_moves': self.only_posted_moves,
|
||||
'company_id': self.company_id.id,
|
||||
'filter_account_ids': [(6, 0, self.filter_account_ids.ids)],
|
||||
'filter_partner_ids': [(6, 0, self.filter_partner_ids.ids)],
|
||||
}
|
||||
|
||||
@api.multi
|
||||
def compute_data_for_report(self):
|
||||
self.ensure_one()
|
||||
# Compute Open Items Report Data.
|
||||
# The data of Aged Partner Balance Report
|
||||
# are based on Open Items Report data.
|
||||
model = self.env['report_open_items']
|
||||
self.open_items_id = model.create(self._prepare_report_open_items())
|
||||
self.open_items_id.compute_data_for_report()
|
||||
|
||||
# Compute report data
|
||||
self._inject_account_values()
|
||||
self._inject_partner_values()
|
||||
self._inject_line_values()
|
||||
self._inject_line_values(only_empty_partner_line=True)
|
||||
if self.show_move_line_details:
|
||||
self._inject_move_line_values()
|
||||
self._inject_move_line_values(only_empty_partner_line=True)
|
||||
self._compute_accounts_cumul()
|
||||
# Refresh cache because all data are computed with SQL requests
|
||||
self.refresh()
|
||||
|
||||
def _inject_account_values(self):
|
||||
"""Inject report values for report_aged_partner_balance_account"""
|
||||
query_inject_account = """
|
||||
INSERT INTO
|
||||
report_aged_partner_balance_account
|
||||
(
|
||||
report_id,
|
||||
create_uid,
|
||||
create_date,
|
||||
account_id,
|
||||
code,
|
||||
name
|
||||
)
|
||||
SELECT
|
||||
%s AS report_id,
|
||||
%s AS create_uid,
|
||||
NOW() AS create_date,
|
||||
rao.account_id,
|
||||
rao.code,
|
||||
rao.name
|
||||
FROM
|
||||
report_open_items_account rao
|
||||
WHERE
|
||||
rao.report_id = %s
|
||||
"""
|
||||
query_inject_account_params = (
|
||||
self.id,
|
||||
self.env.uid,
|
||||
self.open_items_id.id,
|
||||
)
|
||||
self.env.cr.execute(query_inject_account, query_inject_account_params)
|
||||
|
||||
def _inject_partner_values(self):
|
||||
"""Inject report values for report_aged_partner_balance_partner"""
|
||||
query_inject_partner = """
|
||||
INSERT INTO
|
||||
report_aged_partner_balance_partner
|
||||
(
|
||||
report_account_id,
|
||||
create_uid,
|
||||
create_date,
|
||||
partner_id,
|
||||
name
|
||||
)
|
||||
SELECT
|
||||
ra.id AS report_account_id,
|
||||
%s AS create_uid,
|
||||
NOW() AS create_date,
|
||||
rpo.partner_id,
|
||||
rpo.name
|
||||
FROM
|
||||
report_open_items_partner rpo
|
||||
INNER JOIN
|
||||
report_open_items_account rao ON rpo.report_account_id = rao.id
|
||||
INNER JOIN
|
||||
report_aged_partner_balance_account ra ON rao.code = ra.code
|
||||
WHERE
|
||||
rao.report_id = %s
|
||||
AND ra.report_id = %s
|
||||
"""
|
||||
query_inject_partner_params = (
|
||||
self.env.uid,
|
||||
self.open_items_id.id,
|
||||
self.id,
|
||||
)
|
||||
self.env.cr.execute(query_inject_partner, query_inject_partner_params)
|
||||
|
||||
def _inject_line_values(self, only_empty_partner_line=False):
|
||||
""" Inject report values for report_aged_partner_balance_line.
|
||||
|
||||
The "only_empty_partner_line" value is used
|
||||
to compute data without partner.
|
||||
"""
|
||||
query_inject_line = """
|
||||
WITH
|
||||
date_range AS
|
||||
(
|
||||
SELECT
|
||||
%s AS date_current,
|
||||
DATE %s - INTEGER '30' AS date_less_30_days,
|
||||
DATE %s - INTEGER '60' AS date_less_60_days,
|
||||
DATE %s - INTEGER '90' AS date_less_90_days,
|
||||
DATE %s - INTEGER '120' AS date_less_120_days,
|
||||
DATE %s - INTEGER '150' AS date_older
|
||||
)
|
||||
INSERT INTO
|
||||
report_aged_partner_balance_line
|
||||
(
|
||||
report_partner_id,
|
||||
create_uid,
|
||||
create_date,
|
||||
partner,
|
||||
amount_residual,
|
||||
current,
|
||||
age_30_days,
|
||||
age_60_days,
|
||||
age_90_days,
|
||||
age_120_days,
|
||||
older
|
||||
)
|
||||
SELECT
|
||||
rp.id AS report_partner_id,
|
||||
%s AS create_uid,
|
||||
NOW() AS create_date,
|
||||
rp.name,
|
||||
SUM(rlo.amount_residual) AS amount_residual,
|
||||
SUM(
|
||||
CASE
|
||||
WHEN rlo.date_due > date_range.date_less_30_days
|
||||
THEN rlo.amount_residual
|
||||
END
|
||||
) AS current,
|
||||
SUM(
|
||||
CASE
|
||||
WHEN
|
||||
rlo.date_due > date_range.date_less_60_days
|
||||
AND rlo.date_due <= date_range.date_less_30_days
|
||||
THEN rlo.amount_residual
|
||||
END
|
||||
) AS age_30_days,
|
||||
SUM(
|
||||
CASE
|
||||
WHEN
|
||||
rlo.date_due > date_range.date_less_90_days
|
||||
AND rlo.date_due <= date_range.date_less_60_days
|
||||
THEN rlo.amount_residual
|
||||
END
|
||||
) AS age_60_days,
|
||||
SUM(
|
||||
CASE
|
||||
WHEN
|
||||
rlo.date_due > date_range.date_less_120_days
|
||||
AND rlo.date_due <= date_range.date_less_90_days
|
||||
THEN rlo.amount_residual
|
||||
END
|
||||
) AS age_90_days,
|
||||
SUM(
|
||||
CASE
|
||||
WHEN
|
||||
rlo.date_due > date_range.date_older
|
||||
AND rlo.date_due <= date_range.date_less_120_days
|
||||
THEN rlo.amount_residual
|
||||
END
|
||||
) AS age_120_days,
|
||||
SUM(
|
||||
CASE
|
||||
WHEN rlo.date_due <= date_range.date_older
|
||||
THEN rlo.amount_residual
|
||||
END
|
||||
) AS older
|
||||
FROM
|
||||
date_range,
|
||||
report_open_items_move_line rlo
|
||||
INNER JOIN
|
||||
report_open_items_partner rpo ON rlo.report_partner_id = rpo.id
|
||||
INNER JOIN
|
||||
report_open_items_account rao ON rpo.report_account_id = rao.id
|
||||
INNER JOIN
|
||||
report_aged_partner_balance_account ra ON rao.code = ra.code
|
||||
INNER JOIN
|
||||
report_aged_partner_balance_partner rp
|
||||
ON
|
||||
ra.id = rp.report_account_id
|
||||
"""
|
||||
if not only_empty_partner_line:
|
||||
query_inject_line += """
|
||||
AND rpo.partner_id = rp.partner_id
|
||||
"""
|
||||
elif only_empty_partner_line:
|
||||
query_inject_line += """
|
||||
AND rpo.partner_id IS NULL
|
||||
AND rp.partner_id IS NULL
|
||||
"""
|
||||
query_inject_line += """
|
||||
WHERE
|
||||
rao.report_id = %s
|
||||
AND ra.report_id = %s
|
||||
GROUP BY
|
||||
rp.id
|
||||
"""
|
||||
query_inject_line_params = (self.date_at,) * 6
|
||||
query_inject_line_params += (
|
||||
self.env.uid,
|
||||
self.open_items_id.id,
|
||||
self.id,
|
||||
)
|
||||
self.env.cr.execute(query_inject_line, query_inject_line_params)
|
||||
|
||||
def _inject_move_line_values(self, only_empty_partner_line=False):
|
||||
""" Inject report values for report_aged_partner_balance_move_line
|
||||
|
||||
The "only_empty_partner_line" value is used
|
||||
to compute data without partner.
|
||||
"""
|
||||
query_inject_move_line = """
|
||||
WITH
|
||||
date_range AS
|
||||
(
|
||||
SELECT
|
||||
%s AS date_current,
|
||||
DATE %s - INTEGER '30' AS date_less_30_days,
|
||||
DATE %s - INTEGER '60' AS date_less_60_days,
|
||||
DATE %s - INTEGER '90' AS date_less_90_days,
|
||||
DATE %s - INTEGER '120' AS date_less_120_days,
|
||||
DATE %s - INTEGER '150' AS date_older
|
||||
)
|
||||
INSERT INTO
|
||||
report_aged_partner_balance_move_line
|
||||
(
|
||||
report_partner_id,
|
||||
create_uid,
|
||||
create_date,
|
||||
date,
|
||||
date_due,
|
||||
entry,
|
||||
journal,
|
||||
account,
|
||||
partner,
|
||||
label,
|
||||
amount_residual,
|
||||
current,
|
||||
age_30_days,
|
||||
age_60_days,
|
||||
age_90_days,
|
||||
age_120_days,
|
||||
older
|
||||
)
|
||||
SELECT
|
||||
rp.id AS report_partner_id,
|
||||
%s AS create_uid,
|
||||
NOW() AS create_date,
|
||||
rlo.date,
|
||||
rlo.date_due,
|
||||
rlo.entry,
|
||||
rlo.journal,
|
||||
rlo.account,
|
||||
rlo.partner,
|
||||
rlo.label,
|
||||
rlo.amount_residual AS amount_residual,
|
||||
CASE
|
||||
WHEN rlo.date_due > date_range.date_less_30_days
|
||||
THEN rlo.amount_residual
|
||||
END AS current,
|
||||
CASE
|
||||
WHEN
|
||||
rlo.date_due > date_range.date_less_60_days
|
||||
AND rlo.date_due <= date_range.date_less_30_days
|
||||
THEN rlo.amount_residual
|
||||
END AS age_30_days,
|
||||
CASE
|
||||
WHEN
|
||||
rlo.date_due > date_range.date_less_90_days
|
||||
AND rlo.date_due <= date_range.date_less_60_days
|
||||
THEN rlo.amount_residual
|
||||
END AS age_60_days,
|
||||
CASE
|
||||
WHEN
|
||||
rlo.date_due > date_range.date_less_120_days
|
||||
AND rlo.date_due <= date_range.date_less_90_days
|
||||
THEN rlo.amount_residual
|
||||
END AS age_90_days,
|
||||
CASE
|
||||
WHEN
|
||||
rlo.date_due > date_range.date_older
|
||||
AND rlo.date_due <= date_range.date_less_120_days
|
||||
THEN rlo.amount_residual
|
||||
END AS age_120_days,
|
||||
CASE
|
||||
WHEN rlo.date_due <= date_range.date_older
|
||||
THEN rlo.amount_residual
|
||||
END AS older
|
||||
FROM
|
||||
date_range,
|
||||
report_open_items_move_line rlo
|
||||
INNER JOIN
|
||||
report_open_items_partner rpo ON rlo.report_partner_id = rpo.id
|
||||
INNER JOIN
|
||||
report_open_items_account rao ON rpo.report_account_id = rao.id
|
||||
INNER JOIN
|
||||
report_aged_partner_balance_account ra ON rao.code = ra.code
|
||||
INNER JOIN
|
||||
report_aged_partner_balance_partner rp
|
||||
ON
|
||||
ra.id = rp.report_account_id
|
||||
"""
|
||||
if not only_empty_partner_line:
|
||||
query_inject_move_line += """
|
||||
AND rpo.partner_id = rp.partner_id
|
||||
"""
|
||||
elif only_empty_partner_line:
|
||||
query_inject_move_line += """
|
||||
AND rpo.partner_id IS NULL
|
||||
AND rp.partner_id IS NULL
|
||||
"""
|
||||
query_inject_move_line += """
|
||||
WHERE
|
||||
rao.report_id = %s
|
||||
AND ra.report_id = %s
|
||||
"""
|
||||
query_inject_move_line_params = (self.date_at,) * 6
|
||||
query_inject_move_line_params += (
|
||||
self.env.uid,
|
||||
self.open_items_id.id,
|
||||
self.id,
|
||||
)
|
||||
self.env.cr.execute(query_inject_move_line,
|
||||
query_inject_move_line_params)
|
||||
|
||||
def _compute_accounts_cumul(self):
|
||||
""" Compute cumulative amount for
|
||||
report_aged_partner_balance_account.
|
||||
"""
|
||||
query_compute_accounts_cumul = """
|
||||
WITH
|
||||
cumuls AS
|
||||
(
|
||||
SELECT
|
||||
ra.id AS report_account_id,
|
||||
SUM(rl.amount_residual) AS cumul_amount_residual,
|
||||
SUM(rl.current) AS cumul_current,
|
||||
SUM(rl.age_30_days) AS cumul_age_30_days,
|
||||
SUM(rl.age_60_days) AS cumul_age_60_days,
|
||||
SUM(rl.age_90_days) AS cumul_age_90_days,
|
||||
SUM(rl.age_120_days) AS cumul_age_120_days,
|
||||
SUM(rl.older) AS cumul_older
|
||||
FROM
|
||||
report_aged_partner_balance_line rl
|
||||
INNER JOIN
|
||||
report_aged_partner_balance_partner rp
|
||||
ON rl.report_partner_id = rp.id
|
||||
INNER JOIN
|
||||
report_aged_partner_balance_account ra
|
||||
ON rp.report_account_id = ra.id
|
||||
WHERE
|
||||
ra.report_id = %s
|
||||
GROUP BY
|
||||
ra.id
|
||||
)
|
||||
UPDATE
|
||||
report_aged_partner_balance_account
|
||||
SET
|
||||
cumul_amount_residual = c.cumul_amount_residual,
|
||||
cumul_current = c.cumul_current,
|
||||
cumul_age_30_days = c.cumul_age_30_days,
|
||||
cumul_age_60_days = c.cumul_age_60_days,
|
||||
cumul_age_90_days = c.cumul_age_90_days,
|
||||
cumul_age_120_days = c.cumul_age_120_days,
|
||||
cumul_older = c.cumul_older,
|
||||
percent_current =
|
||||
CASE
|
||||
WHEN c.cumul_amount_residual != 0
|
||||
THEN 100 * c.cumul_current / c.cumul_amount_residual
|
||||
END,
|
||||
percent_age_30_days =
|
||||
CASE
|
||||
WHEN c.cumul_amount_residual != 0
|
||||
THEN 100 * c.cumul_age_30_days / c.cumul_amount_residual
|
||||
END,
|
||||
percent_age_60_days =
|
||||
CASE
|
||||
WHEN c.cumul_amount_residual != 0
|
||||
THEN 100 * c.cumul_age_60_days / c.cumul_amount_residual
|
||||
END,
|
||||
percent_age_90_days =
|
||||
CASE
|
||||
WHEN c.cumul_amount_residual != 0
|
||||
THEN 100 * c.cumul_age_90_days / c.cumul_amount_residual
|
||||
END,
|
||||
percent_age_120_days =
|
||||
CASE
|
||||
WHEN c.cumul_amount_residual != 0
|
||||
THEN 100 * c.cumul_age_120_days / c.cumul_amount_residual
|
||||
END,
|
||||
percent_older =
|
||||
CASE
|
||||
WHEN c.cumul_amount_residual != 0
|
||||
THEN 100 * c.cumul_older / c.cumul_amount_residual
|
||||
END
|
||||
FROM
|
||||
cumuls c
|
||||
WHERE
|
||||
id = c.report_account_id
|
||||
"""
|
||||
params_compute_accounts_cumul = (self.id,)
|
||||
self.env.cr.execute(query_compute_accounts_cumul,
|
||||
params_compute_accounts_cumul)
|
||||
257
account_financial_report/report/aged_partner_balance_xlsx.py
Normal file
257
account_financial_report/report/aged_partner_balance_xlsx.py
Normal file
@@ -0,0 +1,257 @@
|
||||
|
||||
# Author: Julien Coux
|
||||
# Copyright 2016 Camptocamp SA
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import _, models
|
||||
|
||||
|
||||
class AgedPartnerBalanceXslx(models.AbstractModel):
|
||||
_name = 'report.a_f_r.report_aged_partner_balance_xlsx'
|
||||
_inherit = 'report.account_financial_report.abstract_report_xlsx'
|
||||
|
||||
def _get_report_name(self):
|
||||
return _('Aged Partner Balance')
|
||||
|
||||
def _get_report_columns(self, report):
|
||||
if not report.show_move_line_details:
|
||||
return {
|
||||
0: {'header': _('Partner'), 'field': 'partner', 'width': 70},
|
||||
1: {'header': _('Residual'),
|
||||
'field': 'amount_residual',
|
||||
'field_footer_total': 'cumul_amount_residual',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
2: {'header': _('Current'),
|
||||
'field': 'current',
|
||||
'field_footer_total': 'cumul_current',
|
||||
'field_footer_percent': 'percent_current',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
3: {'header': _(u'Age ??? 30 d.'),
|
||||
'field': 'age_30_days',
|
||||
'field_footer_total': 'cumul_age_30_days',
|
||||
'field_footer_percent': 'percent_age_30_days',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
4: {'header': _(u'Age ??? 60 d.'),
|
||||
'field': 'age_60_days',
|
||||
'field_footer_total': 'cumul_age_60_days',
|
||||
'field_footer_percent': 'percent_age_60_days',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
5: {'header': _(u'Age ??? 90 d.'),
|
||||
'field': 'age_90_days',
|
||||
'field_footer_total': 'cumul_age_90_days',
|
||||
'field_footer_percent': 'percent_age_90_days',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
6: {'header': _(u'Age ??? 120 d.'),
|
||||
'field': 'age_120_days',
|
||||
'field_footer_total': 'cumul_age_120_days',
|
||||
'field_footer_percent': 'percent_age_120_days',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
7: {'header': _('Older'),
|
||||
'field': 'older',
|
||||
'field_footer_total': 'cumul_older',
|
||||
'field_footer_percent': 'percent_older',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
}
|
||||
else:
|
||||
return {
|
||||
0: {'header': _('Date'), 'field': 'date', 'width': 11},
|
||||
1: {'header': _('Entry'), 'field': 'entry', 'width': 18},
|
||||
2: {'header': _('Journal'), 'field': 'journal', 'width': 8},
|
||||
3: {'header': _('Account'), 'field': 'account', 'width': 9},
|
||||
4: {'header': _('Partner'), 'field': 'partner', 'width': 25},
|
||||
5: {'header': _('Ref - Label'), 'field': 'label', 'width': 40},
|
||||
6: {'header': _('Due date'), 'field': 'date_due', 'width': 11},
|
||||
7: {'header': _('Residual'),
|
||||
'field': 'amount_residual',
|
||||
'field_footer_total': 'cumul_amount_residual',
|
||||
'field_final_balance': 'amount_residual',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
8: {'header': _('Current'),
|
||||
'field': 'current',
|
||||
'field_footer_total': 'cumul_current',
|
||||
'field_footer_percent': 'percent_current',
|
||||
'field_final_balance': 'current',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
9: {'header': _(u'Age ??? 30 d.'),
|
||||
'field': 'age_30_days',
|
||||
'field_footer_total': 'cumul_age_30_days',
|
||||
'field_footer_percent': 'percent_age_30_days',
|
||||
'field_final_balance': 'age_30_days',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
10: {'header': _(u'Age ??? 60 d.'),
|
||||
'field': 'age_60_days',
|
||||
'field_footer_total': 'cumul_age_60_days',
|
||||
'field_footer_percent': 'percent_age_60_days',
|
||||
'field_final_balance': 'age_60_days',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
11: {'header': _(u'Age ??? 90 d.'),
|
||||
'field': 'age_90_days',
|
||||
'field_footer_total': 'cumul_age_90_days',
|
||||
'field_footer_percent': 'percent_age_90_days',
|
||||
'field_final_balance': 'age_90_days',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
12: {'header': _(u'Age ??? 120 d.'),
|
||||
'field': 'age_120_days',
|
||||
'field_footer_total': 'cumul_age_120_days',
|
||||
'field_footer_percent': 'percent_age_120_days',
|
||||
'field_final_balance': 'age_120_days',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
13: {'header': _('Older'),
|
||||
'field': 'older',
|
||||
'field_footer_total': 'cumul_older',
|
||||
'field_footer_percent': 'percent_older',
|
||||
'field_final_balance': 'older',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
}
|
||||
|
||||
def _get_report_filters(self, report):
|
||||
return [
|
||||
[_('Date at filter'), report.date_at],
|
||||
[_('Target moves filter'),
|
||||
_('All posted entries') if report.only_posted_moves
|
||||
else _('All entries')],
|
||||
]
|
||||
|
||||
def _get_col_count_filter_name(self):
|
||||
return 2
|
||||
|
||||
def _get_col_count_filter_value(self):
|
||||
return 3
|
||||
|
||||
def _get_col_pos_footer_label(self, report):
|
||||
return 0 if not report.show_move_line_details else 5
|
||||
|
||||
def _get_col_count_final_balance_name(self):
|
||||
return 5
|
||||
|
||||
def _get_col_pos_final_balance_label(self):
|
||||
return 5
|
||||
|
||||
def _generate_report_content(self, workbook, report):
|
||||
if not report.show_move_line_details:
|
||||
# For each account
|
||||
for account in report.account_ids:
|
||||
# Write account title
|
||||
self.write_array_title(account.code + ' - ' + account.name)
|
||||
|
||||
# Display array header for partners lines
|
||||
self.write_array_header()
|
||||
|
||||
# Display partner lines
|
||||
for partner in account.partner_ids:
|
||||
self.write_line(partner.line_ids)
|
||||
|
||||
# Display account lines
|
||||
self.write_account_footer(report,
|
||||
account,
|
||||
_('Total'),
|
||||
'field_footer_total',
|
||||
self.format_header_right,
|
||||
self.format_header_amount,
|
||||
False)
|
||||
self.write_account_footer(report,
|
||||
account,
|
||||
_('Percents'),
|
||||
'field_footer_percent',
|
||||
self.format_right_bold_italic,
|
||||
self.format_percent_bold_italic,
|
||||
True)
|
||||
|
||||
# 2 lines break
|
||||
self.row_pos += 2
|
||||
else:
|
||||
# For each account
|
||||
for account in report.account_ids:
|
||||
# Write account title
|
||||
self.write_array_title(account.code + ' - ' + account.name)
|
||||
|
||||
# For each partner
|
||||
for partner in account.partner_ids:
|
||||
# Write partner title
|
||||
self.write_array_title(partner.name)
|
||||
|
||||
# Display array header for move lines
|
||||
self.write_array_header()
|
||||
|
||||
# Display account move lines
|
||||
for line in partner.move_line_ids:
|
||||
self.write_line(line)
|
||||
|
||||
# Display ending balance line for partner
|
||||
self.write_ending_balance(partner.line_ids)
|
||||
|
||||
# Line break
|
||||
self.row_pos += 1
|
||||
|
||||
# Display account lines
|
||||
self.write_account_footer(report,
|
||||
account,
|
||||
_('Total'),
|
||||
'field_footer_total',
|
||||
self.format_header_right,
|
||||
self.format_header_amount,
|
||||
False)
|
||||
self.write_account_footer(report,
|
||||
account,
|
||||
_('Percents'),
|
||||
'field_footer_percent',
|
||||
self.format_right_bold_italic,
|
||||
self.format_percent_bold_italic,
|
||||
True)
|
||||
|
||||
# 2 lines break
|
||||
self.row_pos += 2
|
||||
|
||||
def write_ending_balance(self, my_object):
|
||||
"""
|
||||
Specific function to write ending partner balance
|
||||
for Aged Partner Balance
|
||||
"""
|
||||
name = None
|
||||
label = _('Partner cumul aged balance')
|
||||
super(AgedPartnerBalanceXslx, self).write_ending_balance(
|
||||
my_object, name, label
|
||||
)
|
||||
|
||||
def write_account_footer(self, report, account, label, field_name,
|
||||
string_format, amount_format, amount_is_percent):
|
||||
"""
|
||||
Specific function to write account footer for Aged Partner Balance
|
||||
"""
|
||||
col_pos_footer_label = self._get_col_pos_footer_label(report)
|
||||
for col_pos, column in self.columns.items():
|
||||
if col_pos == col_pos_footer_label or column.get(field_name):
|
||||
if col_pos == col_pos_footer_label:
|
||||
value = label
|
||||
else:
|
||||
value = getattr(account, column[field_name])
|
||||
cell_type = column.get('type', 'string')
|
||||
if cell_type == 'string' or col_pos == col_pos_footer_label:
|
||||
self.sheet.write_string(self.row_pos, col_pos, value or '',
|
||||
string_format)
|
||||
elif cell_type == 'amount':
|
||||
number = float(value)
|
||||
if amount_is_percent:
|
||||
number /= 100
|
||||
self.sheet.write_number(self.row_pos, col_pos,
|
||||
number,
|
||||
amount_format)
|
||||
else:
|
||||
self.sheet.write_string(self.row_pos, col_pos, '',
|
||||
string_format)
|
||||
|
||||
self.row_pos += 1
|
||||
1431
account_financial_report/report/general_ledger.py
Normal file
1431
account_financial_report/report/general_ledger.py
Normal file
File diff suppressed because it is too large
Load Diff
137
account_financial_report/report/general_ledger_xlsx.py
Normal file
137
account_financial_report/report/general_ledger_xlsx.py
Normal file
@@ -0,0 +1,137 @@
|
||||
|
||||
# Author: Damien Crier
|
||||
# Author: Julien Coux
|
||||
# Copyright 2016 Camptocamp SA
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import _, models
|
||||
|
||||
|
||||
class GeneralLedgerXslx(models.AbstractModel):
|
||||
_name = 'report.a_f_r.report_general_ledger_xlsx'
|
||||
_inherit = 'report.account_financial_report.abstract_report_xlsx'
|
||||
|
||||
def _get_report_name(self):
|
||||
return _('General Ledger')
|
||||
|
||||
def _get_report_columns(self, report):
|
||||
return {
|
||||
0: {'header': _('Date'), 'field': 'date', 'width': 11},
|
||||
1: {'header': _('Entry'), 'field': 'entry', 'width': 18},
|
||||
2: {'header': _('Journal'), 'field': 'journal', 'width': 8},
|
||||
3: {'header': _('Account'), 'field': 'account', 'width': 9},
|
||||
4: {'header': _('Partner'), 'field': 'partner', 'width': 25},
|
||||
5: {'header': _('Ref - Label'), 'field': 'label', 'width': 40},
|
||||
6: {'header': _('Cost center'),
|
||||
'field': 'cost_center',
|
||||
'width': 15},
|
||||
7: {'header': _('Rec.'), 'field': 'matching_number', 'width': 5},
|
||||
8: {'header': _('Debit'),
|
||||
'field': 'debit',
|
||||
'field_initial_balance': 'initial_debit',
|
||||
'field_final_balance': 'final_debit',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
9: {'header': _('Credit'),
|
||||
'field': 'credit',
|
||||
'field_initial_balance': 'initial_credit',
|
||||
'field_final_balance': 'final_credit',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
10: {'header': _('Cumul. Bal.'),
|
||||
'field': 'cumul_balance',
|
||||
'field_initial_balance': 'initial_balance',
|
||||
'field_final_balance': 'final_balance',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
11: {'header': _('Cur.'), 'field': 'currency_name', 'width': 7},
|
||||
12: {'header': _('Amount cur.'),
|
||||
'field': 'amount_currency',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
}
|
||||
|
||||
def _get_report_filters(self, report):
|
||||
return [
|
||||
[_('Date range filter'),
|
||||
_('From: %s To: %s') % (report.date_from, report.date_to)],
|
||||
[_('Target moves filter'),
|
||||
_('All posted entries') if report.only_posted_moves
|
||||
else _('All entries')],
|
||||
[_('Account balance at 0 filter'),
|
||||
_('Hide') if report.hide_account_balance_at_0 else _('Show')],
|
||||
[_('Centralize filter'),
|
||||
_('Yes') if report.centralize else _('No')],
|
||||
]
|
||||
|
||||
def _get_col_count_filter_name(self):
|
||||
return 2
|
||||
|
||||
def _get_col_count_filter_value(self):
|
||||
return 2
|
||||
|
||||
def _get_col_pos_initial_balance_label(self):
|
||||
return 5
|
||||
|
||||
def _get_col_count_final_balance_name(self):
|
||||
return 5
|
||||
|
||||
def _get_col_pos_final_balance_label(self):
|
||||
return 5
|
||||
|
||||
def _generate_report_content(self, workbook, report):
|
||||
# For each account
|
||||
for account in report.account_ids:
|
||||
# Write account title
|
||||
self.write_array_title(account.code + ' - ' + account.name)
|
||||
|
||||
if not account.partner_ids:
|
||||
# Display array header for move lines
|
||||
self.write_array_header()
|
||||
|
||||
# Display initial balance line for account
|
||||
self.write_initial_balance(account, _('Initial balance'))
|
||||
|
||||
# Display account move lines
|
||||
for line in account.move_line_ids:
|
||||
self.write_line(line)
|
||||
|
||||
else:
|
||||
# For each partner
|
||||
for partner in account.partner_ids:
|
||||
# Write partner title
|
||||
self.write_array_title(partner.name)
|
||||
|
||||
# Display array header for move lines
|
||||
self.write_array_header()
|
||||
|
||||
# Display initial balance line for partner
|
||||
self.write_initial_balance(partner, _('Initial balance'))
|
||||
|
||||
# Display account move lines
|
||||
for line in partner.move_line_ids:
|
||||
self.write_line(line)
|
||||
|
||||
# Display ending balance line for partner
|
||||
self.write_ending_balance(partner, 'partner')
|
||||
|
||||
# Line break
|
||||
self.row_pos += 1
|
||||
|
||||
# Display ending balance line for account
|
||||
self.write_ending_balance(account, 'account')
|
||||
|
||||
# 2 lines break
|
||||
self.row_pos += 2
|
||||
|
||||
def write_ending_balance(self, my_object, type_object):
|
||||
"""Specific function to write ending balance for General Ledger"""
|
||||
if type_object == 'partner':
|
||||
name = my_object.name
|
||||
label = _('Partner ending balance')
|
||||
elif type_object == 'account':
|
||||
name = my_object.code + ' - ' + my_object.name
|
||||
label = _('Ending balance')
|
||||
super(GeneralLedgerXslx, self).write_ending_balance(
|
||||
my_object, name, label
|
||||
)
|
||||
776
account_financial_report/report/open_items.py
Normal file
776
account_financial_report/report/open_items.py
Normal file
@@ -0,0 +1,776 @@
|
||||
|
||||
# ?? 2016 Julien Coux (Camptocamp)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import models, fields, api, _
|
||||
|
||||
|
||||
class OpenItemsReport(models.TransientModel):
|
||||
""" Here, we just define class fields.
|
||||
For methods, go more bottom at this file.
|
||||
|
||||
The class hierarchy is :
|
||||
* OpenItemsReport
|
||||
** OpenItemsReportAccount
|
||||
*** OpenItemsReportPartner
|
||||
**** OpenItemsReportMoveLine
|
||||
"""
|
||||
|
||||
_name = 'report_open_items'
|
||||
|
||||
# Filters fields, used for data computation
|
||||
date_at = fields.Date()
|
||||
only_posted_moves = fields.Boolean()
|
||||
hide_account_balance_at_0 = fields.Boolean()
|
||||
company_id = fields.Many2one(comodel_name='res.company')
|
||||
filter_account_ids = fields.Many2many(comodel_name='account.account')
|
||||
filter_partner_ids = fields.Many2many(comodel_name='res.partner')
|
||||
|
||||
# Flag fields, used for report display
|
||||
has_second_currency = fields.Boolean()
|
||||
|
||||
# Data fields, used to browse report data
|
||||
account_ids = fields.One2many(
|
||||
comodel_name='report_open_items_account',
|
||||
inverse_name='report_id'
|
||||
)
|
||||
|
||||
|
||||
class OpenItemsReportAccount(models.TransientModel):
|
||||
|
||||
_name = 'report_open_items_account'
|
||||
_order = 'code ASC'
|
||||
|
||||
report_id = fields.Many2one(
|
||||
comodel_name='report_open_items',
|
||||
ondelete='cascade',
|
||||
index=True
|
||||
)
|
||||
|
||||
# Data fields, used to keep link with real object
|
||||
account_id = fields.Many2one(
|
||||
'account.account',
|
||||
index=True
|
||||
)
|
||||
|
||||
# Data fields, used for report display
|
||||
code = fields.Char()
|
||||
name = fields.Char()
|
||||
final_amount_residual = fields.Float(digits=(16, 2))
|
||||
|
||||
# Data fields, used to browse report data
|
||||
partner_ids = fields.One2many(
|
||||
comodel_name='report_open_items_partner',
|
||||
inverse_name='report_account_id'
|
||||
)
|
||||
|
||||
|
||||
class OpenItemsReportPartner(models.TransientModel):
|
||||
|
||||
_name = 'report_open_items_partner'
|
||||
|
||||
report_account_id = fields.Many2one(
|
||||
comodel_name='report_open_items_account',
|
||||
ondelete='cascade',
|
||||
index=True
|
||||
)
|
||||
|
||||
# Data fields, used to keep link with real object
|
||||
partner_id = fields.Many2one(
|
||||
'res.partner',
|
||||
index=True
|
||||
)
|
||||
|
||||
# Data fields, used for report display
|
||||
name = fields.Char()
|
||||
final_amount_residual = fields.Float(digits=(16, 2))
|
||||
|
||||
# Data fields, used to browse report data
|
||||
move_line_ids = fields.One2many(
|
||||
comodel_name='report_open_items_move_line',
|
||||
inverse_name='report_partner_id'
|
||||
)
|
||||
|
||||
@api.model
|
||||
def _generate_order_by(self, order_spec, query):
|
||||
"""Custom order to display "No partner allocated" at last position."""
|
||||
return """
|
||||
ORDER BY
|
||||
CASE
|
||||
WHEN "report_open_items_partner"."partner_id" IS NOT NULL
|
||||
THEN 0
|
||||
ELSE 1
|
||||
END,
|
||||
"report_open_items_partner"."name"
|
||||
"""
|
||||
|
||||
|
||||
class OpenItemsReportMoveLine(models.TransientModel):
|
||||
|
||||
_name = 'report_open_items_move_line'
|
||||
|
||||
report_partner_id = fields.Many2one(
|
||||
comodel_name='report_open_items_partner',
|
||||
ondelete='cascade',
|
||||
index=True
|
||||
)
|
||||
|
||||
# Data fields, used to keep link with real object
|
||||
move_line_id = fields.Many2one('account.move.line')
|
||||
|
||||
# Data fields, used for report display
|
||||
date = fields.Date()
|
||||
date_due = fields.Date()
|
||||
entry = fields.Char()
|
||||
journal = fields.Char()
|
||||
account = fields.Char()
|
||||
partner = fields.Char()
|
||||
label = fields.Char()
|
||||
amount_total_due = fields.Float(digits=(16, 2))
|
||||
amount_residual = fields.Float(digits=(16, 2))
|
||||
currency_name = fields.Char()
|
||||
amount_total_due_currency = fields.Float(digits=(16, 2))
|
||||
amount_residual_currency = fields.Float(digits=(16, 2))
|
||||
|
||||
|
||||
class OpenItemsReportCompute(models.TransientModel):
|
||||
""" Here, we just define methods.
|
||||
For class fields, go more top at this file.
|
||||
"""
|
||||
|
||||
_inherit = 'report_open_items'
|
||||
|
||||
@api.multi
|
||||
def print_report(self, report_type):
|
||||
self.ensure_one()
|
||||
if report_type == 'xlsx':
|
||||
report_name = 'a_f_r.report_open_items_xlsx'
|
||||
else:
|
||||
report_name = 'account_financial_report.' \
|
||||
'report_open_items_qweb'
|
||||
return self.env['ir.actions.report'].search(
|
||||
[('report_name', '=', report_name),
|
||||
('report_type', '=', report_type)], limit=1).report_action(self)
|
||||
|
||||
def _get_html(self):
|
||||
result = {}
|
||||
rcontext = {}
|
||||
context = dict(self.env.context)
|
||||
report = self.browse(context.get('active_id'))
|
||||
if report:
|
||||
rcontext['o'] = report
|
||||
result['html'] = self.env.ref(
|
||||
'account_financial_report.report_open_items').render(
|
||||
rcontext)
|
||||
return result
|
||||
|
||||
@api.model
|
||||
def get_html(self, given_context=None):
|
||||
return self._get_html()
|
||||
|
||||
@api.multi
|
||||
def compute_data_for_report(self):
|
||||
self.ensure_one()
|
||||
# Compute report data
|
||||
self._inject_account_values()
|
||||
self._inject_partner_values()
|
||||
self._inject_line_values()
|
||||
self._inject_line_values(only_empty_partner_line=True)
|
||||
self._clean_partners_and_accounts()
|
||||
self._compute_partners_and_accounts_cumul()
|
||||
if self.hide_account_balance_at_0:
|
||||
self._clean_partners_and_accounts(
|
||||
only_delete_account_balance_at_0=True
|
||||
)
|
||||
# Compute display flag
|
||||
self._compute_has_second_currency()
|
||||
# Refresh cache because all data are computed with SQL requests
|
||||
self.refresh()
|
||||
|
||||
def _inject_account_values(self):
|
||||
"""Inject report values for report_open_items_account."""
|
||||
query_inject_account = """
|
||||
WITH
|
||||
accounts AS
|
||||
(
|
||||
SELECT
|
||||
a.id,
|
||||
a.code,
|
||||
a.name,
|
||||
a.user_type_id
|
||||
FROM
|
||||
account_account a
|
||||
INNER JOIN
|
||||
account_move_line ml ON a.id = ml.account_id AND ml.date <= %s
|
||||
"""
|
||||
if self.filter_partner_ids:
|
||||
query_inject_account += """
|
||||
INNER JOIN
|
||||
res_partner p ON ml.partner_id = p.id
|
||||
"""
|
||||
if self.only_posted_moves:
|
||||
query_inject_account += """
|
||||
INNER JOIN
|
||||
account_move m ON ml.move_id = m.id AND m.state = 'posted'
|
||||
"""
|
||||
query_inject_account += """
|
||||
WHERE
|
||||
a.company_id = %s
|
||||
AND a.reconcile IS true
|
||||
"""
|
||||
if self.filter_account_ids:
|
||||
query_inject_account += """
|
||||
AND
|
||||
a.id IN %s
|
||||
"""
|
||||
if self.filter_partner_ids:
|
||||
query_inject_account += """
|
||||
AND
|
||||
p.id IN %s
|
||||
"""
|
||||
query_inject_account += """
|
||||
GROUP BY
|
||||
a.id
|
||||
)
|
||||
INSERT INTO
|
||||
report_open_items_account
|
||||
(
|
||||
report_id,
|
||||
create_uid,
|
||||
create_date,
|
||||
account_id,
|
||||
code,
|
||||
name
|
||||
)
|
||||
SELECT
|
||||
%s AS report_id,
|
||||
%s AS create_uid,
|
||||
NOW() AS create_date,
|
||||
a.id AS account_id,
|
||||
a.code,
|
||||
a.name
|
||||
FROM
|
||||
accounts a
|
||||
"""
|
||||
query_inject_account_params = (
|
||||
self.date_at,
|
||||
self.company_id.id,
|
||||
)
|
||||
if self.filter_account_ids:
|
||||
query_inject_account_params += (
|
||||
tuple(self.filter_account_ids.ids),
|
||||
)
|
||||
if self.filter_partner_ids:
|
||||
query_inject_account_params += (
|
||||
tuple(self.filter_partner_ids.ids),
|
||||
)
|
||||
query_inject_account_params += (
|
||||
self.id,
|
||||
self.env.uid,
|
||||
)
|
||||
self.env.cr.execute(query_inject_account, query_inject_account_params)
|
||||
|
||||
def _inject_partner_values(self):
|
||||
""" Inject report values for report_open_items_partner. """
|
||||
# pylint: disable=sql-injection
|
||||
query_inject_partner = """
|
||||
WITH
|
||||
accounts_partners AS
|
||||
(
|
||||
SELECT
|
||||
ra.id AS report_account_id,
|
||||
a.id AS account_id,
|
||||
at.include_initial_balance AS include_initial_balance,
|
||||
p.id AS partner_id,
|
||||
COALESCE(
|
||||
CASE
|
||||
WHEN
|
||||
NULLIF(p.name, '') IS NOT NULL
|
||||
AND NULLIF(p.ref, '') IS NOT NULL
|
||||
THEN p.name || ' (' || p.ref || ')'
|
||||
ELSE p.name
|
||||
END,
|
||||
'""" + _('No partner allocated') + """'
|
||||
) AS partner_name
|
||||
FROM
|
||||
report_open_items_account ra
|
||||
INNER JOIN
|
||||
account_account a ON ra.account_id = a.id
|
||||
INNER JOIN
|
||||
account_account_type at ON a.user_type_id = at.id
|
||||
INNER JOIN
|
||||
account_move_line ml ON a.id = ml.account_id AND ml.date <= %s
|
||||
"""
|
||||
if self.only_posted_moves:
|
||||
query_inject_partner += """
|
||||
INNER JOIN
|
||||
account_move m ON ml.move_id = m.id AND m.state = 'posted'
|
||||
"""
|
||||
query_inject_partner += """
|
||||
LEFT JOIN
|
||||
res_partner p ON ml.partner_id = p.id
|
||||
WHERE
|
||||
ra.report_id = %s
|
||||
"""
|
||||
if self.filter_partner_ids:
|
||||
query_inject_partner += """
|
||||
AND
|
||||
p.id IN %s
|
||||
"""
|
||||
query_inject_partner += """
|
||||
GROUP BY
|
||||
ra.id,
|
||||
a.id,
|
||||
p.id,
|
||||
at.include_initial_balance
|
||||
)
|
||||
INSERT INTO
|
||||
report_open_items_partner
|
||||
(
|
||||
report_account_id,
|
||||
create_uid,
|
||||
create_date,
|
||||
partner_id,
|
||||
name
|
||||
)
|
||||
SELECT
|
||||
ap.report_account_id,
|
||||
%s AS create_uid,
|
||||
NOW() AS create_date,
|
||||
ap.partner_id,
|
||||
ap.partner_name
|
||||
FROM
|
||||
accounts_partners ap
|
||||
"""
|
||||
query_inject_partner_params = (
|
||||
self.date_at,
|
||||
self.id,
|
||||
)
|
||||
if self.filter_partner_ids:
|
||||
query_inject_partner_params += (
|
||||
tuple(self.filter_partner_ids.ids),
|
||||
)
|
||||
query_inject_partner_params += (
|
||||
self.env.uid,
|
||||
)
|
||||
self.env.cr.execute(query_inject_partner, query_inject_partner_params)
|
||||
|
||||
def _get_line_sub_query_move_lines(self,
|
||||
only_empty_partner_line=False,
|
||||
positive_balance=True):
|
||||
""" Return subquery used to compute sum amounts on lines """
|
||||
sub_query = """
|
||||
SELECT
|
||||
ml.id,
|
||||
ml.balance,
|
||||
SUM(
|
||||
CASE
|
||||
WHEN ml_past.id IS NOT NULL
|
||||
THEN pr.amount
|
||||
ELSE NULL
|
||||
END
|
||||
) AS partial_amount,
|
||||
ml.amount_currency,
|
||||
SUM(
|
||||
CASE
|
||||
WHEN ml_past.id IS NOT NULL
|
||||
THEN pr.amount_currency
|
||||
ELSE NULL
|
||||
END
|
||||
) AS partial_amount_currency,
|
||||
ml.currency_id
|
||||
FROM
|
||||
report_open_items_partner rp
|
||||
INNER JOIN
|
||||
report_open_items_account ra
|
||||
ON rp.report_account_id = ra.id
|
||||
INNER JOIN
|
||||
account_move_line ml
|
||||
ON ra.account_id = ml.account_id
|
||||
"""
|
||||
if not only_empty_partner_line:
|
||||
sub_query += """
|
||||
AND rp.partner_id = ml.partner_id
|
||||
"""
|
||||
elif only_empty_partner_line:
|
||||
sub_query += """
|
||||
AND ml.partner_id IS NULL
|
||||
"""
|
||||
if not positive_balance:
|
||||
sub_query += """
|
||||
LEFT JOIN
|
||||
account_partial_reconcile pr
|
||||
ON ml.balance < 0 AND pr.credit_move_id = ml.id
|
||||
LEFT JOIN
|
||||
account_move_line ml_future
|
||||
ON ml.balance < 0 AND pr.debit_move_id = ml_future.id
|
||||
AND ml_future.date >= %s
|
||||
LEFT JOIN
|
||||
account_move_line ml_past
|
||||
ON ml.balance < 0 AND pr.debit_move_id = ml_past.id
|
||||
AND ml_past.date < %s
|
||||
"""
|
||||
else:
|
||||
sub_query += """
|
||||
LEFT JOIN
|
||||
account_partial_reconcile pr
|
||||
ON ml.balance > 0 AND pr.debit_move_id = ml.id
|
||||
LEFT JOIN
|
||||
account_move_line ml_future
|
||||
ON ml.balance > 0 AND pr.credit_move_id = ml_future.id
|
||||
AND ml_future.date >= %s
|
||||
LEFT JOIN
|
||||
account_move_line ml_past
|
||||
ON ml.balance > 0 AND pr.credit_move_id = ml_past.id
|
||||
AND ml_past.date < %s
|
||||
"""
|
||||
sub_query += """
|
||||
WHERE
|
||||
ra.report_id = %s
|
||||
GROUP BY
|
||||
ml.id,
|
||||
ml.balance,
|
||||
ml.amount_currency
|
||||
HAVING
|
||||
(
|
||||
ml.full_reconcile_id IS NULL
|
||||
OR MAX(ml_future.id) IS NOT NULL
|
||||
)
|
||||
"""
|
||||
return sub_query
|
||||
|
||||
def _inject_line_values(self, only_empty_partner_line=False):
|
||||
""" Inject report values for report_open_items_move_line.
|
||||
|
||||
The "only_empty_partner_line" value is used
|
||||
to compute data without partner.
|
||||
"""
|
||||
query_inject_move_line = """
|
||||
WITH
|
||||
move_lines_amount AS
|
||||
(
|
||||
"""
|
||||
query_inject_move_line += self._get_line_sub_query_move_lines(
|
||||
only_empty_partner_line=only_empty_partner_line,
|
||||
positive_balance=True
|
||||
)
|
||||
query_inject_move_line += """
|
||||
UNION
|
||||
"""
|
||||
query_inject_move_line += self._get_line_sub_query_move_lines(
|
||||
only_empty_partner_line=only_empty_partner_line,
|
||||
positive_balance=False
|
||||
)
|
||||
query_inject_move_line += """
|
||||
),
|
||||
move_lines AS
|
||||
(
|
||||
SELECT
|
||||
id,
|
||||
CASE
|
||||
WHEN SUM(partial_amount) > 0
|
||||
THEN
|
||||
CASE
|
||||
WHEN balance > 0
|
||||
THEN balance - SUM(partial_amount)
|
||||
ELSE balance + SUM(partial_amount)
|
||||
END
|
||||
ELSE balance
|
||||
END AS amount_residual,
|
||||
CASE
|
||||
WHEN SUM(partial_amount_currency) > 0
|
||||
THEN
|
||||
CASE
|
||||
WHEN amount_currency > 0
|
||||
THEN amount_currency - SUM(partial_amount_currency)
|
||||
ELSE amount_currency + SUM(partial_amount_currency)
|
||||
END
|
||||
ELSE amount_currency
|
||||
END AS amount_residual_currency,
|
||||
currency_id
|
||||
FROM
|
||||
move_lines_amount
|
||||
GROUP BY
|
||||
id,
|
||||
balance,
|
||||
amount_currency,
|
||||
currency_id
|
||||
)
|
||||
INSERT INTO
|
||||
report_open_items_move_line
|
||||
(
|
||||
report_partner_id,
|
||||
create_uid,
|
||||
create_date,
|
||||
move_line_id,
|
||||
date,
|
||||
date_due,
|
||||
entry,
|
||||
journal,
|
||||
account,
|
||||
partner,
|
||||
label,
|
||||
amount_total_due,
|
||||
amount_residual,
|
||||
currency_name,
|
||||
amount_total_due_currency,
|
||||
amount_residual_currency
|
||||
)
|
||||
SELECT
|
||||
rp.id AS report_partner_id,
|
||||
%s AS create_uid,
|
||||
NOW() AS create_date,
|
||||
ml.id AS move_line_id,
|
||||
ml.date,
|
||||
ml.date_maturity,
|
||||
m.name AS entry,
|
||||
j.code AS journal,
|
||||
a.code AS account,
|
||||
"""
|
||||
if not only_empty_partner_line:
|
||||
query_inject_move_line += """
|
||||
CASE
|
||||
WHEN
|
||||
NULLIF(p.name, '') IS NOT NULL
|
||||
AND NULLIF(p.ref, '') IS NOT NULL
|
||||
THEN p.name || ' (' || p.ref || ')'
|
||||
ELSE p.name
|
||||
END AS partner,
|
||||
"""
|
||||
elif only_empty_partner_line:
|
||||
query_inject_move_line += """
|
||||
'""" + _('No partner allocated') + """' AS partner,
|
||||
"""
|
||||
query_inject_move_line += """
|
||||
CONCAT_WS(' - ', NULLIF(ml.ref, ''), NULLIF(ml.name, '')) AS label,
|
||||
ml.balance,
|
||||
ml2.amount_residual,
|
||||
c.name AS currency_name,
|
||||
ml.amount_currency,
|
||||
ml2.amount_residual_currency
|
||||
FROM
|
||||
report_open_items_partner rp
|
||||
INNER JOIN
|
||||
report_open_items_account ra ON rp.report_account_id = ra.id
|
||||
INNER JOIN
|
||||
account_move_line ml ON ra.account_id = ml.account_id
|
||||
INNER JOIN
|
||||
move_lines ml2
|
||||
ON ml.id = ml2.id
|
||||
AND ml2.amount_residual IS NOT NULL
|
||||
AND ml2.amount_residual != 0
|
||||
INNER JOIN
|
||||
account_move m ON ml.move_id = m.id
|
||||
INNER JOIN
|
||||
account_journal j ON ml.journal_id = j.id
|
||||
INNER JOIN
|
||||
account_account a ON ml.account_id = a.id
|
||||
"""
|
||||
if not only_empty_partner_line:
|
||||
query_inject_move_line += """
|
||||
INNER JOIN
|
||||
res_partner p
|
||||
ON ml.partner_id = p.id AND rp.partner_id = p.id
|
||||
"""
|
||||
query_inject_move_line += """
|
||||
LEFT JOIN
|
||||
account_full_reconcile fr ON ml.full_reconcile_id = fr.id
|
||||
LEFT JOIN
|
||||
res_currency c ON ml2.currency_id = c.id
|
||||
WHERE
|
||||
ra.report_id = %s
|
||||
AND
|
||||
ml.date <= %s
|
||||
"""
|
||||
if self.only_posted_moves:
|
||||
query_inject_move_line += """
|
||||
AND
|
||||
m.state = 'posted'
|
||||
"""
|
||||
if only_empty_partner_line:
|
||||
query_inject_move_line += """
|
||||
AND
|
||||
ml.partner_id IS NULL
|
||||
AND
|
||||
rp.partner_id IS NULL
|
||||
"""
|
||||
if not only_empty_partner_line:
|
||||
query_inject_move_line += """
|
||||
ORDER BY
|
||||
a.code, p.name, ml.date, ml.id
|
||||
"""
|
||||
elif only_empty_partner_line:
|
||||
query_inject_move_line += """
|
||||
ORDER BY
|
||||
a.code, ml.date, ml.id
|
||||
"""
|
||||
self.env.cr.execute(
|
||||
query_inject_move_line,
|
||||
(self.date_at,
|
||||
self.date_at,
|
||||
self.id,
|
||||
self.date_at,
|
||||
self.date_at,
|
||||
self.id,
|
||||
self.env.uid,
|
||||
self.id,
|
||||
self.date_at,)
|
||||
)
|
||||
|
||||
def _compute_partners_and_accounts_cumul(self):
|
||||
""" Compute cumulative amount for
|
||||
report_open_items_partner and report_open_items_account.
|
||||
"""
|
||||
query_compute_partners_cumul = """
|
||||
UPDATE
|
||||
report_open_items_partner
|
||||
SET
|
||||
final_amount_residual =
|
||||
(
|
||||
SELECT
|
||||
SUM(rml.amount_residual) AS final_amount_residual
|
||||
FROM
|
||||
report_open_items_move_line rml
|
||||
WHERE
|
||||
rml.report_partner_id = report_open_items_partner.id
|
||||
)
|
||||
WHERE
|
||||
id IN
|
||||
(
|
||||
SELECT
|
||||
rp.id
|
||||
FROM
|
||||
report_open_items_account ra
|
||||
INNER JOIN
|
||||
report_open_items_partner rp
|
||||
ON ra.id = rp.report_account_id
|
||||
WHERE
|
||||
ra.report_id = %s
|
||||
)
|
||||
"""
|
||||
params_compute_partners_cumul = (self.id,)
|
||||
self.env.cr.execute(query_compute_partners_cumul,
|
||||
params_compute_partners_cumul)
|
||||
query_compute_accounts_cumul = """
|
||||
UPDATE
|
||||
report_open_items_account
|
||||
SET
|
||||
final_amount_residual =
|
||||
(
|
||||
SELECT
|
||||
SUM(rp.final_amount_residual) AS final_amount_residual
|
||||
FROM
|
||||
report_open_items_partner rp
|
||||
WHERE
|
||||
rp.report_account_id = report_open_items_account.id
|
||||
)
|
||||
WHERE
|
||||
report_id = %s
|
||||
"""
|
||||
params_compute_accounts_cumul = (self.id,)
|
||||
self.env.cr.execute(query_compute_accounts_cumul,
|
||||
params_compute_accounts_cumul)
|
||||
|
||||
def _clean_partners_and_accounts(self,
|
||||
only_delete_account_balance_at_0=False):
|
||||
""" Delete empty data for
|
||||
report_open_items_partner and report_open_items_account.
|
||||
|
||||
The "only_delete_account_balance_at_0" value is used
|
||||
to delete also the data with cumulative amounts at 0.
|
||||
"""
|
||||
query_clean_partners = """
|
||||
DELETE FROM
|
||||
report_open_items_partner
|
||||
WHERE
|
||||
id IN
|
||||
(
|
||||
SELECT
|
||||
DISTINCT rp.id
|
||||
FROM
|
||||
report_open_items_account ra
|
||||
INNER JOIN
|
||||
report_open_items_partner rp
|
||||
ON ra.id = rp.report_account_id
|
||||
LEFT JOIN
|
||||
report_open_items_move_line rml
|
||||
ON rp.id = rml.report_partner_id
|
||||
WHERE
|
||||
ra.report_id = %s
|
||||
"""
|
||||
if not only_delete_account_balance_at_0:
|
||||
query_clean_partners += """
|
||||
AND rml.id IS NULL
|
||||
"""
|
||||
elif only_delete_account_balance_at_0:
|
||||
query_clean_partners += """
|
||||
AND (
|
||||
rp.final_amount_residual IS NULL
|
||||
OR rp.final_amount_residual = 0
|
||||
)
|
||||
"""
|
||||
query_clean_partners += """
|
||||
)
|
||||
"""
|
||||
params_clean_partners = (self.id,)
|
||||
self.env.cr.execute(query_clean_partners, params_clean_partners)
|
||||
query_clean_accounts = """
|
||||
DELETE FROM
|
||||
report_open_items_account
|
||||
WHERE
|
||||
id IN
|
||||
(
|
||||
SELECT
|
||||
DISTINCT ra.id
|
||||
FROM
|
||||
report_open_items_account ra
|
||||
LEFT JOIN
|
||||
report_open_items_partner rp
|
||||
ON ra.id = rp.report_account_id
|
||||
WHERE
|
||||
ra.report_id = %s
|
||||
"""
|
||||
if not only_delete_account_balance_at_0:
|
||||
query_clean_accounts += """
|
||||
AND rp.id IS NULL
|
||||
"""
|
||||
elif only_delete_account_balance_at_0:
|
||||
query_clean_accounts += """
|
||||
AND (
|
||||
ra.final_amount_residual IS NULL
|
||||
OR ra.final_amount_residual = 0
|
||||
)
|
||||
"""
|
||||
query_clean_accounts += """
|
||||
)
|
||||
"""
|
||||
params_clean_accounts = (self.id,)
|
||||
self.env.cr.execute(query_clean_accounts, params_clean_accounts)
|
||||
|
||||
def _compute_has_second_currency(self):
|
||||
""" Compute "has_second_currency" flag which will used for display."""
|
||||
query_update_has_second_currency = """
|
||||
UPDATE
|
||||
report_open_items
|
||||
SET
|
||||
has_second_currency =
|
||||
(
|
||||
SELECT
|
||||
TRUE
|
||||
FROM
|
||||
report_open_items_move_line l
|
||||
INNER JOIN
|
||||
report_open_items_partner p
|
||||
ON l.report_partner_id = p.id
|
||||
INNER JOIN
|
||||
report_open_items_account a
|
||||
ON p.report_account_id = a.id
|
||||
WHERE
|
||||
a.report_id = %s
|
||||
AND l.currency_name IS NOT NULL
|
||||
LIMIT 1
|
||||
)
|
||||
WHERE id = %s
|
||||
"""
|
||||
params = (self.id,) * 2
|
||||
self.env.cr.execute(query_update_has_second_currency, params)
|
||||
105
account_financial_report/report/open_items_xlsx.py
Normal file
105
account_financial_report/report/open_items_xlsx.py
Normal file
@@ -0,0 +1,105 @@
|
||||
|
||||
# Author: Julien Coux
|
||||
# Copyright 2016 Camptocamp SA
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import _, models
|
||||
|
||||
|
||||
class OpenItemsXslx(models.AbstractModel):
|
||||
_name = 'report.a_f_r.report_open_items_xlsx'
|
||||
_inherit = 'report.account_financial_report.abstract_report_xlsx'
|
||||
|
||||
def _get_report_name(self):
|
||||
return _('Open Items')
|
||||
|
||||
def _get_report_columns(self, report):
|
||||
return {
|
||||
0: {'header': _('Date'), 'field': 'date', 'width': 11},
|
||||
1: {'header': _('Entry'), 'field': 'entry', 'width': 18},
|
||||
2: {'header': _('Journal'), 'field': 'journal', 'width': 8},
|
||||
3: {'header': _('Account'), 'field': 'account', 'width': 9},
|
||||
4: {'header': _('Partner'), 'field': 'partner', 'width': 25},
|
||||
5: {'header': _('Ref - Label'), 'field': 'label', 'width': 40},
|
||||
6: {'header': _('Due date'), 'field': 'date_due', 'width': 11},
|
||||
7: {'header': _('Original'),
|
||||
'field': 'amount_total_due',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
8: {'header': _('Residual'),
|
||||
'field': 'amount_residual',
|
||||
'field_final_balance': 'final_amount_residual',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
9: {'header': _('Cur.'), 'field': 'currency_name', 'width': 7},
|
||||
10: {'header': _('Cur. Original'),
|
||||
'field': 'amount_total_due_currency',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
11: {'header': _('Cur. Residual'),
|
||||
'field': 'amount_residual_currency',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
}
|
||||
|
||||
def _get_report_filters(self, report):
|
||||
return [
|
||||
[_('Date at filter'), report.date_at],
|
||||
[_('Target moves filter'),
|
||||
_('All posted entries') if report.only_posted_moves
|
||||
else _('All entries')],
|
||||
[_('Account balance at 0 filter'),
|
||||
_('Hide') if report.hide_account_balance_at_0 else _('Show')],
|
||||
]
|
||||
|
||||
def _get_col_count_filter_name(self):
|
||||
return 2
|
||||
|
||||
def _get_col_count_filter_value(self):
|
||||
return 2
|
||||
|
||||
def _get_col_count_final_balance_name(self):
|
||||
return 5
|
||||
|
||||
def _get_col_pos_final_balance_label(self):
|
||||
return 5
|
||||
|
||||
def _generate_report_content(self, workbook, report):
|
||||
# For each account
|
||||
for account in report.account_ids:
|
||||
# Write account title
|
||||
self.write_array_title(account.code + ' - ' + account.name)
|
||||
|
||||
# For each partner
|
||||
for partner in account.partner_ids:
|
||||
# Write partner title
|
||||
self.write_array_title(partner.name)
|
||||
|
||||
# Display array header for move lines
|
||||
self.write_array_header()
|
||||
|
||||
# Display account move lines
|
||||
for line in partner.move_line_ids:
|
||||
self.write_line(line)
|
||||
|
||||
# Display ending balance line for partner
|
||||
self.write_ending_balance(partner, 'partner')
|
||||
|
||||
# Line break
|
||||
self.row_pos += 1
|
||||
|
||||
# Display ending balance line for account
|
||||
self.write_ending_balance(account, 'account')
|
||||
|
||||
# 2 lines break
|
||||
self.row_pos += 2
|
||||
|
||||
def write_ending_balance(self, my_object, type_object):
|
||||
"""Specific function to write ending balance for Open Items"""
|
||||
if type_object == 'partner':
|
||||
name = my_object.name
|
||||
label = _('Partner ending balance')
|
||||
elif type_object == 'account':
|
||||
name = my_object.code + ' - ' + my_object.name
|
||||
label = _('Ending balance')
|
||||
super(OpenItemsXslx, self).write_ending_balance(my_object, name, label)
|
||||
@@ -0,0 +1,432 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<template id="account_financial_report.report_aged_partner_balance_qweb">
|
||||
<t t-call="web.html_container">
|
||||
<t t-foreach="docs" t-as="o">
|
||||
<t t-call="account_financial_report.internal_layout">
|
||||
<t t-call="account_financial_report.report_aged_partner_balance_base"/>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="account_financial_report.report_aged_partner_balance_base">
|
||||
<!-- Saved flag fields into variables, used to define columns display -->
|
||||
<t t-set="show_move_line_details" t-value="o.show_move_line_details"/>
|
||||
|
||||
<!-- Defines global variables used by internal layout -->
|
||||
<t t-set="title">Aged Partner Balance</t>
|
||||
<t t-set="company_name" t-value="o.company_id.name"/>
|
||||
|
||||
<div class="page">
|
||||
<!-- Display filters -->
|
||||
<t t-call="account_financial_report.report_aged_partner_balance_filters"/>
|
||||
|
||||
<t t-foreach="o.account_ids" t-as="account">
|
||||
<div class="page_break">
|
||||
<!-- Display account header -->
|
||||
<div class="act_as_table list_table" style="margin-top: 10px;"/>
|
||||
<div class="act_as_caption account_title" style="width: 1141px !important;">
|
||||
<span t-field="account.code"/>
|
||||
-
|
||||
<span t-field="account.name"/>
|
||||
</div>
|
||||
|
||||
<!-- Display account lines -->
|
||||
<t t-if="not show_move_line_details">
|
||||
<div class="act_as_table data_table" style="width: 1140px !important;">
|
||||
<!-- Display account header -->
|
||||
<t t-call="account_financial_report.report_aged_partner_balance_lines_header"/>
|
||||
|
||||
<t t-foreach="account.partner_ids" t-as="partner">
|
||||
|
||||
<!-- Display one line per partner -->
|
||||
<t t-call="account_financial_report.report_aged_partner_balance_lines"/>
|
||||
</t>
|
||||
</div>
|
||||
|
||||
<!-- Display account footer -->
|
||||
<t t-call="account_financial_report.report_aged_partner_balance_account_ending_cumul"/>
|
||||
</t>
|
||||
|
||||
<!-- Display account move lines -->
|
||||
<t t-if="show_move_line_details">
|
||||
|
||||
<!-- Display account partners -->
|
||||
<t t-foreach="account.partner_ids" t-as="partner">
|
||||
<div class="page_break">
|
||||
<!-- Display partner header -->
|
||||
<div class="act_as_caption account_title">
|
||||
<span t-field="partner.name"/>
|
||||
</div>
|
||||
|
||||
<!-- Display partner move lines -->
|
||||
<t t-call="account_financial_report.report_aged_partner_balance_move_lines"/>
|
||||
|
||||
<!-- Display partner footer -->
|
||||
<t t-call="account_financial_report.report_aged_partner_balance_partner_ending_cumul">
|
||||
<t t-set="partner_cumul_line" t-value="partner.line_ids"/>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<!-- Display account footer -->
|
||||
<t t-call="account_financial_report.report_aged_partner_balance_account_ending_cumul"/>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="account_financial_report.report_aged_partner_balance_filters">
|
||||
<div class="act_as_table data_table" style="width: 1140px !important;">
|
||||
<div class="act_as_row labels">
|
||||
<div class="act_as_cell">Date at filter</div>
|
||||
<div class="act_as_cell">Target moves filter</div>
|
||||
</div>
|
||||
<div class="act_as_row">
|
||||
<div class="act_as_cell">
|
||||
<span t-field="o.date_at"/>
|
||||
</div>
|
||||
<div class="act_as_cell">
|
||||
<t t-if="o.only_posted_moves">All posted entries</t>
|
||||
<t t-if="not o.only_posted_moves">All entries</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="account_financial_report.report_aged_partner_balance_lines_header">
|
||||
<!-- Display table headers for lines -->
|
||||
<div class="act_as_thead">
|
||||
<div class="act_as_row labels">
|
||||
<!--## partner-->
|
||||
<div class="act_as_cell" style="width: 370px;">Partner</div>
|
||||
<!--## amount_residual-->
|
||||
<div class="act_as_cell" style="width: 110px;">Residual</div>
|
||||
<!--## current-->
|
||||
<div class="act_as_cell" style="width: 110px;">Current</div>
|
||||
<!--## age_30_days-->
|
||||
<div class="act_as_cell" style="width: 110px;">Age ??? 30 d.</div>
|
||||
<!--## age_60_days-->
|
||||
<div class="act_as_cell" style="width: 110px;">Age ??? 60 d.</div>
|
||||
<!--## age_90_days-->
|
||||
<div class="act_as_cell" style="width: 110px;">Age ??? 90 d.</div>
|
||||
<!--## age_120_days-->
|
||||
<div class="act_as_cell" style="width: 110px;">Age ??? 120 d.</div>
|
||||
<!--## older-->
|
||||
<div class="act_as_cell" style="width: 110px;">Older</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="account_financial_report.report_aged_partner_balance_lines">
|
||||
<!-- Display each lines -->
|
||||
<t t-foreach="partner.line_ids" t-as="line">
|
||||
<!-- # lines -->
|
||||
<div class="act_as_row lines">
|
||||
<!--## partner-->
|
||||
<div class="act_as_cell left">
|
||||
<span t-field="line.partner"/>
|
||||
</div>
|
||||
<!--## amount_residual-->
|
||||
<div class="act_as_cell amount">
|
||||
<span t-field="line.amount_residual"/>
|
||||
</div>
|
||||
<!--## current-->
|
||||
<div class="act_as_cell amount">
|
||||
<span t-field="line.current"/>
|
||||
</div>
|
||||
<!--## age_30_days-->
|
||||
<div class="act_as_cell amount">
|
||||
<span t-field="line.age_30_days"/>
|
||||
</div>
|
||||
<!--## age_60_days-->
|
||||
<div class="act_as_cell amount">
|
||||
<span t-field="line.age_60_days"/>
|
||||
</div>
|
||||
<!--## age_90_days-->
|
||||
<div class="act_as_cell amount">
|
||||
<span t-field="line.age_90_days"/>
|
||||
</div>
|
||||
<!--## age_120_days-->
|
||||
<div class="act_as_cell amount">
|
||||
<span t-field="line.age_120_days"/>
|
||||
</div>
|
||||
<!--## older-->
|
||||
<div class="act_as_cell amount">
|
||||
<span t-field="line.older"/>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="account_financial_report.report_aged_partner_balance_move_lines">
|
||||
<div class="act_as_table data_table" style="width: 1140px !important;">
|
||||
<!-- Display table headers for move lines -->
|
||||
<div class="act_as_thead">
|
||||
<div class="act_as_row labels">
|
||||
<!--## date-->
|
||||
<div class="act_as_cell first_column" style="width: 60px;">Date</div>
|
||||
<!--## move-->
|
||||
<div class="act_as_cell" style="width: 100px;">Entry</div>
|
||||
<!--## journal-->
|
||||
<div class="act_as_cell" style="width: 40px;">Journal</div>
|
||||
<!--## account code-->
|
||||
<div class="act_as_cell" style="width: 50px;">Account</div>
|
||||
<!--## partner-->
|
||||
<div class="act_as_cell" style="width: 120px;">Partner</div>
|
||||
<!--## ref - label-->
|
||||
<div class="act_as_cell" style="width: 220px;">Ref - Label</div>
|
||||
<!--## date_due-->
|
||||
<div class="act_as_cell" style="width: 60px;">Due date</div>
|
||||
<!--## amount_residual-->
|
||||
<div class="act_as_cell" style="width: 70px;">Residual</div>
|
||||
<!--## current-->
|
||||
<div class="act_as_cell" style="width: 70px;">Current</div>
|
||||
<!--## age_30_days-->
|
||||
<div class="act_as_cell" style="width: 70px;">Age ??? 30 d.</div>
|
||||
<!--## age_60_days-->
|
||||
<div class="act_as_cell" style="width: 70px;">Age ??? 60 d.</div>
|
||||
<!--## age_90_days-->
|
||||
<div class="act_as_cell" style="width: 70px;">Age ??? 90 d.</div>
|
||||
<!--## age_120_days-->
|
||||
<div class="act_as_cell" style="width: 70px;">Age ??? 120 d.</div>
|
||||
<!--## older-->
|
||||
<div class="act_as_cell" style="width: 70px;">Older</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Display each move lines -->
|
||||
<t t-foreach="partner.move_line_ids" t-as="line">
|
||||
<!-- # lines or centralized lines -->
|
||||
<div class="act_as_row lines">
|
||||
<!--## date-->
|
||||
<div class="act_as_cell left">
|
||||
<span t-field="line.date"/>
|
||||
</div>
|
||||
<!--## move-->
|
||||
<div class="act_as_cell left">
|
||||
<span t-field="line.entry"/>
|
||||
</div>
|
||||
<!--## journal-->
|
||||
<div class="act_as_cell left">
|
||||
<span t-field="line.journal"/>
|
||||
</div>
|
||||
<!--## account code-->
|
||||
<div class="act_as_cell left">
|
||||
<span t-field="line.account"/>
|
||||
</div>
|
||||
<!--## partner-->
|
||||
<div class="act_as_cell left">
|
||||
<span t-field="line.partner"/>
|
||||
</div>
|
||||
<!--## ref - label-->
|
||||
<div class="act_as_cell left">
|
||||
<span t-field="line.label"/>
|
||||
</div>
|
||||
<!--## date_due-->
|
||||
<div class="act_as_cell left">
|
||||
<span t-field="line.date_due"/>
|
||||
</div>
|
||||
<!--## amount_residual-->
|
||||
<div class="act_as_cell amount">
|
||||
<span t-field="line.amount_residual"/>
|
||||
</div>
|
||||
<!--## current-->
|
||||
<div class="act_as_cell amount">
|
||||
<span t-field="line.current"/>
|
||||
</div>
|
||||
<!--## age_30_days-->
|
||||
<div class="act_as_cell amount">
|
||||
<span t-field="line.age_30_days"/>
|
||||
</div>
|
||||
<!--## age_60_days-->
|
||||
<div class="act_as_cell amount">
|
||||
<span t-field="line.age_60_days"/>
|
||||
</div>
|
||||
<!--## age_90_days-->
|
||||
<div class="act_as_cell amount">
|
||||
<span t-field="line.age_90_days"/>
|
||||
</div>
|
||||
<!--## age_120_days-->
|
||||
<div class="act_as_cell amount">
|
||||
<span t-field="line.age_120_days"/>
|
||||
</div>
|
||||
<!--## older-->
|
||||
<div class="act_as_cell amount">
|
||||
<span t-field="line.older"/>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="account_financial_report.report_aged_partner_balance_partner_ending_cumul">
|
||||
<!-- Display ending balance line for partner -->
|
||||
<div class="act_as_table list_table" style="width: 1141px !important;">
|
||||
<div class="act_as_row labels" style="font-weight: bold;">
|
||||
<!--## date-->
|
||||
<div class="act_as_cell right" style="width: 590px;">Partner cumul aged balance</div>
|
||||
<!--## date_due-->
|
||||
<div class="act_as_cell" style="width: 60px;"/>
|
||||
<!--## amount_residual-->
|
||||
<div class="act_as_cell amount" style="width: 70px;">
|
||||
<span t-field="partner_cumul_line.amount_residual"/>
|
||||
</div>
|
||||
<!--## current-->
|
||||
<div class="act_as_cell amount" style="width: 70px;">
|
||||
<span t-field="partner_cumul_line.current"/>
|
||||
</div>
|
||||
<!--## age_30_days-->
|
||||
<div class="act_as_cell amount" style="width: 70px;">
|
||||
<span t-field="partner_cumul_line.age_30_days"/>
|
||||
</div>
|
||||
<!--## age_60_days-->
|
||||
<div class="act_as_cell amount" style="width: 70px;">
|
||||
<span t-field="partner_cumul_line.age_60_days"/>
|
||||
</div>
|
||||
<!--## age_90_days-->
|
||||
<div class="act_as_cell amount" style="width: 70px;">
|
||||
<span t-field="partner_cumul_line.age_90_days"/>
|
||||
</div>
|
||||
<!--## age_120_days-->
|
||||
<div class="act_as_cell amount" style="width: 70px;">
|
||||
<span t-field="partner_cumul_line.age_120_days"/>
|
||||
</div>
|
||||
<!--## older-->
|
||||
<div class="act_as_cell amount" style="width: 70px;">
|
||||
<span t-field="partner_cumul_line.older"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="account_financial_report.report_aged_partner_balance_account_ending_cumul">
|
||||
<!-- Display ending balance line for account -->
|
||||
<div class="act_as_table list_table" style="width: 1141px !important;">
|
||||
<div class="act_as_row labels" style="font-weight: bold;">
|
||||
<t t-if="not show_move_line_details">
|
||||
<!--## total-->
|
||||
<div class="act_as_cell right" style="width: 370px;">Total</div>
|
||||
<!--## amount_residual-->
|
||||
<div class="act_as_cell amount" style="width: 110px;">
|
||||
<span t-field="account.cumul_amount_residual"/>
|
||||
</div>
|
||||
<!--## current-->
|
||||
<div class="act_as_cell amount" style="width: 110px;">
|
||||
<span t-field="account.cumul_current"/>
|
||||
</div>
|
||||
<!--## age_30_days-->
|
||||
<div class="act_as_cell amount" style="width: 110px;">
|
||||
<span t-field="account.cumul_age_30_days"/>
|
||||
</div>
|
||||
<!--## age_60_days-->
|
||||
<div class="act_as_cell amount" style="width: 110px;">
|
||||
<span t-field="account.cumul_age_60_days"/>
|
||||
</div>
|
||||
<!--## age_90_days-->
|
||||
<div class="act_as_cell amount" style="width: 110px;">
|
||||
<span t-field="account.cumul_age_90_days"/>
|
||||
</div>
|
||||
<!--## age_120_days-->
|
||||
<div class="act_as_cell amount" style="width: 110px;">
|
||||
<span t-field="account.cumul_age_120_days"/>
|
||||
</div>
|
||||
<!--## older-->
|
||||
<div class="act_as_cell amount" style="width: 110px;">
|
||||
<span t-field="account.cumul_older"/>
|
||||
</div>
|
||||
</t>
|
||||
<t t-if="show_move_line_details">
|
||||
<!--## total-->
|
||||
<div class="act_as_cell right" style="width: 590px;">Total</div>
|
||||
<!--## date_due-->
|
||||
<div class="act_as_cell" style="width: 60px;"/>
|
||||
<!--## amount_residual-->
|
||||
<div class="act_as_cell amount" style="width: 70px;">
|
||||
<span t-field="account.cumul_amount_residual"/>
|
||||
</div>
|
||||
<!--## current-->
|
||||
<div class="act_as_cell amount" style="width: 70px;">
|
||||
<span t-field="account.cumul_current"/>
|
||||
</div>
|
||||
<!--## age_30_days-->
|
||||
<div class="act_as_cell amount" style="width: 70px;">
|
||||
<span t-field="account.cumul_age_30_days"/>
|
||||
</div>
|
||||
<!--## age_60_days-->
|
||||
<div class="act_as_cell amount" style="width: 70px;">
|
||||
<span t-field="account.cumul_age_60_days"/>
|
||||
</div>
|
||||
<!--## age_90_days-->
|
||||
<div class="act_as_cell amount" style="width: 70px;">
|
||||
<span t-field="account.cumul_age_90_days"/>
|
||||
</div>
|
||||
<!--## age_120_days-->
|
||||
<div class="act_as_cell amount" style="width: 70px;">
|
||||
<span t-field="account.cumul_age_120_days"/>
|
||||
</div>
|
||||
<!--## older-->
|
||||
<div class="act_as_cell amount" style="width: 70px;">
|
||||
<span t-field="account.cumul_older"/>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
<div class="act_as_row" style="font-weight: bold; font-style: italic;">
|
||||
<t t-if="not show_move_line_details">
|
||||
<!--## total-->
|
||||
<div class="act_as_cell right" style="width: 370px;">Percents</div>
|
||||
<!--## amount_residual-->
|
||||
<div class="act_as_cell amount" style="width: 110px;"/>
|
||||
<!--## current-->
|
||||
<div class="act_as_cell amount" style="width: 110px;"><span t-field="account.percent_current"/>%
|
||||
</div>
|
||||
<!--## age_30_days-->
|
||||
<div class="act_as_cell amount" style="width: 110px;"><span t-field="account.percent_age_30_days"/>%
|
||||
</div>
|
||||
<!--## age_60_days-->
|
||||
<div class="act_as_cell amount" style="width: 110px;"><span t-field="account.percent_age_60_days"/>%
|
||||
</div>
|
||||
<!--## age_90_days-->
|
||||
<div class="act_as_cell amount" style="width: 110px;"><span t-field="account.percent_age_90_days"/>%
|
||||
</div>
|
||||
<!--## age_120_days-->
|
||||
<div class="act_as_cell amount" style="width: 110px;"><span t-field="account.percent_age_120_days"/>
|
||||
%
|
||||
</div>
|
||||
<!--## older-->
|
||||
<div class="act_as_cell amount" style="width: 110px;"><span t-field="account.percent_older"/>%
|
||||
</div>
|
||||
</t>
|
||||
<t t-if="show_move_line_details">
|
||||
<!--## total-->
|
||||
<div class="act_as_cell right" style="width: 590px;">Percents</div>
|
||||
<!--## date_due-->
|
||||
<div class="act_as_cell" style="width: 60px;"/>
|
||||
<!--## amount_residual-->
|
||||
<div class="act_as_cell amount" style="width: 70px;"/>
|
||||
<!--## current-->
|
||||
<div class="act_as_cell amount" style="width: 70px;"><span t-field="account.percent_current"/>%
|
||||
</div>
|
||||
<!--## age_30_days-->
|
||||
<div class="act_as_cell amount" style="width: 70px;"><span t-field="account.percent_age_30_days"/>%
|
||||
</div>
|
||||
<!--## age_60_days-->
|
||||
<div class="act_as_cell amount" style="width: 70px;"><span t-field="account.percent_age_60_days"/>%
|
||||
</div>
|
||||
<!--## age_90_days-->
|
||||
<div class="act_as_cell amount" style="width: 70px;"><span t-field="account.percent_age_90_days"/>%
|
||||
</div>
|
||||
<!--## age_120_days-->
|
||||
<div class="act_as_cell amount" style="width: 70px;"><span t-field="account.percent_age_120_days"/>%
|
||||
</div>
|
||||
<!--## older-->
|
||||
<div class="act_as_cell amount" style="width: 70px;"><span t-field="account.percent_older"/>%
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
263
account_financial_report/report/templates/general_ledger.xml
Normal file
263
account_financial_report/report/templates/general_ledger.xml
Normal file
@@ -0,0 +1,263 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<template id="report_general_ledger_qweb">
|
||||
<t t-call="web.html_container">
|
||||
<t t-foreach="docs" t-as="o">
|
||||
<t t-call="account_financial_report.internal_layout">
|
||||
<t t-call="account_financial_report.report_general_ledger_base"/>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="report_general_ledger_base">
|
||||
<!-- Saved flag fields into variables, used to define columns display -->
|
||||
<t t-set="show_cost_center" t-value="o.show_cost_center"/>
|
||||
<t t-set="has_second_currency" t-value="o.has_second_currency"/>
|
||||
<!-- Defines global variables used by internal layout -->
|
||||
<t t-set="title">General Ledger</t>
|
||||
<t t-set="company_name" t-value="o.company_id.name"/>
|
||||
|
||||
<div class="page">
|
||||
<!-- Display filters -->
|
||||
<t t-call="account_financial_report.report_general_ledger_filters"/>
|
||||
|
||||
<t t-foreach="o.account_ids" t-as="account">
|
||||
<div class="page_break">
|
||||
<!-- Display account header -->
|
||||
<div class="act_as_table list_table" style="margin-top: 10px;"/>
|
||||
<div class="act_as_caption account_title" style="width: 1141px !important;">
|
||||
<span t-field="account.code"/> - <span t-field="account.name"/>
|
||||
</div>
|
||||
|
||||
<t t-if="not account.partner_ids">
|
||||
<!-- Display account move lines without partner regroup -->
|
||||
<t t-call="account_financial_report.report_general_ledger_lines">
|
||||
<t t-set="account_or_partner_object" t-value="account"/>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
<t t-if="account.partner_ids">
|
||||
<!-- Display account partners -->
|
||||
<t t-foreach="account.partner_ids" t-as="partner">
|
||||
<div class="page_break">
|
||||
<!-- Display partner header -->
|
||||
<div class="act_as_caption account_title">
|
||||
<span t-field="partner.name"/>
|
||||
</div>
|
||||
|
||||
<!-- Display partner move lines -->
|
||||
<t t-call="account_financial_report.report_general_ledger_lines">
|
||||
<t t-set="account_or_partner_object" t-value="partner"/>
|
||||
</t>
|
||||
|
||||
<!-- Display partner footer -->
|
||||
<t t-call="account_financial_report.report_general_ledger_ending_cumul">
|
||||
<t t-set="account_or_partner_object" t-value="partner"/>
|
||||
<t t-set="type" t-value='"partner_type"'/>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
<!-- Display account footer -->
|
||||
<t t-call="account_financial_report.report_general_ledger_ending_cumul">
|
||||
<t t-set="account_or_partner_object" t-value="account"/>
|
||||
<t t-set="type" t-value='"account_type"'/>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="account_financial_report.report_general_ledger_filters">
|
||||
<div class="act_as_table data_table" style="width: 1140px !important;">
|
||||
<div class="act_as_row labels">
|
||||
<div class="act_as_cell">Date range filter</div>
|
||||
<div class="act_as_cell">Target moves filter</div>
|
||||
<div class="act_as_cell">Account balance at 0 filter</div>
|
||||
<div class="act_as_cell">Centralize filter</div>
|
||||
</div>
|
||||
<div class="act_as_row">
|
||||
<div class="act_as_cell">
|
||||
From: <span t-field="o.date_from"/> To: <span t-field="o.date_to"/>
|
||||
</div>
|
||||
<div class="act_as_cell">
|
||||
<t t-if="o.only_posted_moves">All posted entries</t>
|
||||
<t t-if="not o.only_posted_moves">All entries</t>
|
||||
</div>
|
||||
<div class="act_as_cell">
|
||||
<t t-if="o.hide_account_balance_at_0">Hide</t>
|
||||
<t t-if="not o.hide_account_balance_at_0">Show</t>
|
||||
</div>
|
||||
<div class="act_as_cell">
|
||||
<t t-if="o.centralize">Yes</t>
|
||||
<t t-if="not o.centralize">No</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="account_financial_report.report_general_ledger_lines">
|
||||
<div class="act_as_table data_table" style="width: 1140px !important;">
|
||||
|
||||
<!-- Display table headers for lines -->
|
||||
<div class="act_as_thead">
|
||||
<div class="act_as_row labels">
|
||||
<!--## date-->
|
||||
<div class="act_as_cell first_column" style="width: 60px;">Date</div>
|
||||
<!--## move-->
|
||||
<div class="act_as_cell" style="width: 100px;">Entry</div>
|
||||
<!--## journal-->
|
||||
<div class="act_as_cell" style="width: 40px;">Journal</div>
|
||||
<!--## account code-->
|
||||
<div class="act_as_cell" style="width: 50px;">Account</div>
|
||||
<!--## partner-->
|
||||
<div class="act_as_cell" style="width: 140px;">Partner</div>
|
||||
<!--## ref - label-->
|
||||
<div class="act_as_cell" style="width: 290px;">Ref - Label</div>
|
||||
<t t-if="show_cost_center">
|
||||
<!--## cost_center-->
|
||||
<div class="act_as_cell" style="width: 100px;">Cost center</div>
|
||||
</t>
|
||||
<!--## matching_number-->
|
||||
<div class="act_as_cell" style="width: 25px;">Rec.</div>
|
||||
<!--## debit-->
|
||||
<div class="act_as_cell amount" style="width: 75px;">Debit</div>
|
||||
<!--## credit-->
|
||||
<div class="act_as_cell amount" style="width: 75px;">Credit</div>
|
||||
<!--## balance cumulated-->
|
||||
<div class="act_as_cell amount" style="width: 75px;">Cumul. Bal.</div>
|
||||
<!--## currency_name-->
|
||||
<div class="act_as_cell" style="width: 35px;">Cur.</div>
|
||||
<!--## amount_currency-->
|
||||
<div class="act_as_cell amount" style="width: 75px;">Amount cur.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Display first line with initial balance -->
|
||||
<div class="act_as_row lines">
|
||||
<!--## date-->
|
||||
<div class="act_as_cell"/>
|
||||
<!--## move-->
|
||||
<div class="act_as_cell"/>
|
||||
<!--## journal-->
|
||||
<div class="act_as_cell"/>
|
||||
<!--## account code-->
|
||||
<div class="act_as_cell"/>
|
||||
<!--## partner-->
|
||||
<div class="act_as_cell"/>
|
||||
<!--## ref - label-->
|
||||
<div class="act_as_cell amount">Initial balance</div>
|
||||
<t t-if="show_cost_center">
|
||||
<!--## cost_center-->
|
||||
<div class="act_as_cell"/>
|
||||
</t>
|
||||
<!--## matching_number-->
|
||||
<div class="act_as_cell"/>
|
||||
<!--## debit-->
|
||||
<div class="act_as_cell amount"><span t-field="account_or_partner_object.initial_debit"/></div>
|
||||
<!--## credit-->
|
||||
<div class="act_as_cell amount"><span t-field="account_or_partner_object.initial_credit"/></div>
|
||||
<!--## balance cumulated-->
|
||||
<div class="act_as_cell amount"><span t-field="account_or_partner_object.initial_balance"/></div>
|
||||
<!--## currency_name-->
|
||||
<div class="act_as_cell"/>
|
||||
<!--## amount_currency-->
|
||||
<div class="act_as_cell"/>
|
||||
</div>
|
||||
|
||||
<!-- Display each lines -->
|
||||
<t t-foreach="account_or_partner_object.move_line_ids" t-as="line">
|
||||
<!-- # lines or centralized lines -->
|
||||
<div class="act_as_row lines">
|
||||
<!--## date-->
|
||||
<div class="act_as_cell left"><span t-field="line.date"/></div>
|
||||
<!--## move-->
|
||||
<div class="act_as_cell left">
|
||||
<t t-set="res_model" t-value="'account.move'"/>
|
||||
<span>
|
||||
<a t-att-data-active-id="line.move_line_id.move_id.id"
|
||||
t-att-data-res-model="res_model"
|
||||
class="o_account_financial_reports_web_action"
|
||||
style="color: black;">
|
||||
<t t-raw="line.entry"/></a>
|
||||
</span>
|
||||
</div>
|
||||
<!--## journal-->
|
||||
<div class="act_as_cell left"><span t-field="line.journal"/></div>
|
||||
<!--## account code-->
|
||||
<div class="act_as_cell left"><span t-field="line.account"/></div>
|
||||
<!--## partner-->
|
||||
<div class="act_as_cell left">
|
||||
<t t-set="res_model" t-value="'res.partner'"/>
|
||||
<span t-if="line.partner">
|
||||
<a t-att-data-active-id="line.move_line_id.partner_id.id"
|
||||
t-att-data-res-model="res_model"
|
||||
class="o_account_financial_reports_web_action"
|
||||
style="color: black;"><t t-raw="line.partner"/></a>
|
||||
</span>
|
||||
</div>
|
||||
<!--## ref - label-->
|
||||
<div class="act_as_cell left"><span t-field="line.label"/></div>
|
||||
<t t-if="show_cost_center">
|
||||
<!--## cost_center-->
|
||||
<div class="act_as_cell left"><span t-field="line.cost_center"/></div>
|
||||
</t>
|
||||
<!--## matching_number-->
|
||||
<div class="act_as_cell"><span t-field="line.matching_number"/></div>
|
||||
<!--## debit-->
|
||||
<div class="act_as_cell amount"><span t-field="line.debit"/></div>
|
||||
<!--## credit-->
|
||||
<div class="act_as_cell amount"><span t-field="line.credit"/></div>
|
||||
<!--## balance cumulated-->
|
||||
<div class="act_as_cell amount"><span t-field="line.cumul_balance"/></div>
|
||||
<!--## currency_name-->
|
||||
<div class="act_as_cell"><span t-field="line.currency_name"/></div>
|
||||
<t t-if="line.currency_name">
|
||||
<!--## amount_currency-->
|
||||
<div class="act_as_cell amount"><span t-field="line.amount_currency"/></div>
|
||||
</t>
|
||||
<t t-if="not line.currency_name">
|
||||
<!--## amount_currency-->
|
||||
<div class="act_as_cell"/>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="account_financial_report.report_general_ledger_ending_cumul">
|
||||
<!-- Display ending balance line for account or partner -->
|
||||
<div class="act_as_table list_table" style="width: 1141px !important;">
|
||||
<div class="act_as_row labels" style="font-weight: bold;">
|
||||
<!--## date-->
|
||||
<t t-if='type == "account_type"'>
|
||||
<div class="act_as_cell first_column" style="width: 380px;"><span t-field="account_or_partner_object.code"/> - <span t-field="account_or_partner_object.name"/></div>
|
||||
<div class="act_as_cell right" style="width: 290px;">Ending balance</div>
|
||||
</t>
|
||||
<t t-if='type == "partner_type"'>
|
||||
<div class="act_as_cell first_column" style="width: 380px;"/>
|
||||
<div class="act_as_cell right" style="width: 290px;">Partner ending balance</div>
|
||||
</t>
|
||||
<t t-if="show_cost_center">
|
||||
<!--## cost_center-->
|
||||
<div class="act_as_cell" style="width: 100px;"/>
|
||||
</t>
|
||||
<!--## matching_number-->
|
||||
<div class="act_as_cell" style="width: 25px;"/>
|
||||
<!--## debit-->
|
||||
<div class="act_as_cell amount" style="width: 75px;"><span t-field="account_or_partner_object.final_debit"/></div>
|
||||
<!--## credit-->
|
||||
<div class="act_as_cell amount" style="width: 75px;"><span t-field="account_or_partner_object.final_credit"/></div>
|
||||
<!--## balance cumulated-->
|
||||
<div class="act_as_cell amount" style="width: 75px; padding-right: 1px;"><span t-field="account_or_partner_object.final_balance"/></div>
|
||||
<!--## currency_name + amount_currency-->
|
||||
<div class="act_as_cell" style="width: 110px;"/>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
36
account_financial_report/report/templates/layouts.xml
Normal file
36
account_financial_report/report/templates/layouts.xml
Normal file
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<template id="account_financial_report.internal_layout">
|
||||
<div class="header">
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<span t-esc="title"/>
|
||||
</div>
|
||||
<div class="col-xs-6 text-right">
|
||||
<span t-esc="company_name"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="article">
|
||||
<link href="/account_financial_report/static/src/css/report.css" rel="stylesheet"/>
|
||||
<t t-raw="0" />
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<div class="row">
|
||||
<div class="col-xs-6 custom_footer">
|
||||
<span t-esc="context_timestamp(datetime.datetime.now()).strftime('%Y-%m-%d %H:%M')"/>
|
||||
</div>
|
||||
<div class="col-xs-6 text-right custom_footer">
|
||||
<ul class="list-inline">
|
||||
<li><span class="page"/></li>
|
||||
<li>/</li>
|
||||
<li><span class="topage"/></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
233
account_financial_report/report/templates/open_items.xml
Normal file
233
account_financial_report/report/templates/open_items.xml
Normal file
@@ -0,0 +1,233 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<template id="account_financial_report.report_open_items_qweb">
|
||||
<t t-call="web.html_container">
|
||||
<t t-foreach="docs" t-as="o">
|
||||
<t t-call="account_financial_report.internal_layout">
|
||||
<t t-call="account_financial_report.report_open_items_base"/>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="account_financial_report.report_open_items_base">
|
||||
<!-- Saved flag fields into variables, used to define columns display -->
|
||||
<t t-set="has_second_currency" t-value="o.has_second_currency"/>
|
||||
|
||||
|
||||
<!-- Defines global variables used by internal layout -->
|
||||
<t t-set="title">Open Items</t>
|
||||
<t t-set="company_name" t-value="o.company_id.name"/>
|
||||
|
||||
<div class="page">
|
||||
<!-- Display filters -->
|
||||
<t t-call="account_financial_report.report_open_items_filters"/>
|
||||
|
||||
<t t-foreach="o.account_ids" t-as="account">
|
||||
<div class="page_break">
|
||||
<!-- Display account header -->
|
||||
<div class="act_as_table list_table" style="margin-top: 10px;"/>
|
||||
<div class="act_as_caption account_title" style="width: 1141px !important;">
|
||||
<span t-field="account.code"/>
|
||||
-
|
||||
<span t-field="account.name"/>
|
||||
</div>
|
||||
|
||||
<!-- Display account partners -->
|
||||
<t t-foreach="account.partner_ids" t-as="partner">
|
||||
<div class="page_break">
|
||||
<!-- Display partner header -->
|
||||
<div class="act_as_caption account_title">
|
||||
<span t-field="partner.name"/>
|
||||
</div>
|
||||
|
||||
<!-- Display partner move lines -->
|
||||
<t t-call="account_financial_report.report_open_items_lines"/>
|
||||
|
||||
<!-- Display partner footer -->
|
||||
<t t-call="account_financial_report.report_open_items_ending_cumul">
|
||||
<t t-set="account_or_partner_object" t-value="partner"/>
|
||||
<t t-set="type" t-value='"partner_type"'/>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<!-- Display account footer -->
|
||||
<t t-call="account_financial_report.report_open_items_ending_cumul">
|
||||
<t t-set="account_or_partner_object" t-value="account"/>
|
||||
<t t-set="type" t-value='"account_type"'/>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="account_financial_report.report_open_items_filters">
|
||||
<div class="act_as_table data_table" style="width: 1140px !important;">
|
||||
<div class="act_as_row labels">
|
||||
<div class="act_as_cell">Date at filter</div>
|
||||
<div class="act_as_cell">Target moves filter</div>
|
||||
<div class="act_as_cell">Account balance at 0 filter</div>
|
||||
</div>
|
||||
<div class="act_as_row">
|
||||
<div class="act_as_cell">
|
||||
<span t-field="o.date_at"/>
|
||||
</div>
|
||||
<div class="act_as_cell">
|
||||
<t t-if="o.only_posted_moves">All posted entries</t>
|
||||
<t t-if="not o.only_posted_moves">All entries</t>
|
||||
</div>
|
||||
<div class="act_as_cell">
|
||||
<t t-if="o.hide_account_balance_at_0">Hide</t>
|
||||
<t t-if="not o.hide_account_balance_at_0">Show</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="account_financial_report.report_open_items_lines">
|
||||
<div class="act_as_table data_table" style="width: 1140px !important;">
|
||||
<!-- Display table headers for lines -->
|
||||
<div class="act_as_thead">
|
||||
<div class="act_as_row labels">
|
||||
<!--## date-->
|
||||
<div class="act_as_cell first_column" style="width: 60px;">Date</div>
|
||||
<!--## move-->
|
||||
<div class="act_as_cell" style="width: 100px;">Entry</div>
|
||||
<!--## journal-->
|
||||
<div class="act_as_cell" style="width: 40px;">Journal</div>
|
||||
<!--## account code-->
|
||||
<div class="act_as_cell" style="width: 50px;">Account</div>
|
||||
<!--## partner-->
|
||||
<div class="act_as_cell" style="width: 140px;">Partner</div>
|
||||
<!--## ref - label-->
|
||||
<div class="act_as_cell" style="width: 290px;">Ref - Label</div>
|
||||
<!--## date_due-->
|
||||
<div class="act_as_cell" style="width: 60px;">Due date</div>
|
||||
<!--## amount_total_due-->
|
||||
<div class="act_as_cell" style="width: 75px;">Original</div>
|
||||
<!--## amount_residual-->
|
||||
<div class="act_as_cell" style="width: 75px;">Residual</div>
|
||||
<!--## currency_name-->
|
||||
<div class="act_as_cell" style="width: 35px;">Cur.</div>
|
||||
<!--## amount_total_due_currency-->
|
||||
<div class="act_as_cell amount" style="width: 75px;">Cur. Original</div>
|
||||
<!--## amount_residual_currency-->
|
||||
<div class="act_as_cell amount" style="width: 75px;">Cur. Residual</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Display each lines -->
|
||||
<t t-foreach="partner.move_line_ids" t-as="line">
|
||||
<!-- # lines or centralized lines -->
|
||||
<div class="act_as_row lines">
|
||||
<!--## date-->
|
||||
<div class="act_as_cell left">
|
||||
<span t-field="line.date"/>
|
||||
</div>
|
||||
<!--## move-->
|
||||
<div class="act_as_cell left">
|
||||
<t t-set="res_model" t-value="'account.move'"/>
|
||||
<span>
|
||||
<a t-att-data-active-id="line.move_line_id.move_id.id"
|
||||
t-att-data-res-model="res_model"
|
||||
class="o_account_financial_reports_web_action"
|
||||
style="color: black;">
|
||||
<t t-raw="line.entry"/>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
<!--## journal-->
|
||||
<div class="act_as_cell left">
|
||||
<span t-field="line.journal"/>
|
||||
</div>
|
||||
<!--## account code-->
|
||||
<div class="act_as_cell left">
|
||||
<span t-field="line.account"/>
|
||||
</div>
|
||||
<!--## partner-->
|
||||
<div class="act_as_cell left">
|
||||
<t t-set="res_model" t-value="'res.partner'"/>
|
||||
<span t-if="line.partner">
|
||||
<a t-att-data-active-id="line.move_line_id.partner_id.id"
|
||||
t-att-data-res-model="res_model"
|
||||
class="o_account_financial_reports_web_action"
|
||||
style="color: black;">
|
||||
<t t-raw="line.partner"/>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
<!--## ref - label-->
|
||||
<div class="act_as_cell left">
|
||||
<span t-field="line.label"/>
|
||||
</div>
|
||||
<!--## date_due-->
|
||||
<div class="act_as_cell left">
|
||||
<span t-field="line.date_due"/>
|
||||
</div>
|
||||
<!--## amount_total_due-->
|
||||
<div class="act_as_cell amount">
|
||||
<span t-field="line.amount_total_due"/>
|
||||
</div>
|
||||
<!--## amount_residual-->
|
||||
<div class="act_as_cell amount">
|
||||
<span t-field="line.amount_residual"/>
|
||||
</div>
|
||||
<!--## currency_name-->
|
||||
<div class="act_as_cell">
|
||||
<span t-field="line.currency_name"/>
|
||||
</div>
|
||||
<t t-if="line.currency_name">
|
||||
<!--## amount_total_due_currency-->
|
||||
<div class="act_as_cell amount">
|
||||
<span t-field="line.amount_total_due_currency"/>
|
||||
</div>
|
||||
<!--## amount_residual_currency-->
|
||||
<div class="act_as_cell amount">
|
||||
<span t-field="line.amount_residual_currency"/>
|
||||
</div>
|
||||
</t>
|
||||
<t t-if="not line.currency_name">
|
||||
<!--## amount_total_due_currency-->
|
||||
<div class="act_as_cell"/>
|
||||
<!--## amount_residual_currency-->
|
||||
<div class="act_as_cell"/>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="account_financial_report.report_open_items_ending_cumul">
|
||||
<!-- Display ending balance line for account or partner -->
|
||||
<div class="act_as_table list_table" style="width: 1141px !important;">
|
||||
<div class="act_as_row labels" style="font-weight: bold;">
|
||||
<!--## date-->
|
||||
<t t-if='type == "account_type"'>
|
||||
<div class="act_as_cell first_column" style="width: 380px;">
|
||||
<span t-field="account_or_partner_object.code"/>
|
||||
-
|
||||
<span t-field="account_or_partner_object.name"/>
|
||||
</div>
|
||||
<div class="act_as_cell right" style="width: 290px;">Ending balance</div>
|
||||
</t>
|
||||
<t t-if='type == "partner_type"'>
|
||||
<div class="act_as_cell first_column" style="width: 380px;"/>
|
||||
<div class="act_as_cell right" style="width: 290px;">Partner ending balance</div>
|
||||
</t>
|
||||
<!--## date_due-->
|
||||
<div class="act_as_cell" style="width: 60px;"/>
|
||||
<!--## amount_total_due-->
|
||||
<div class="act_as_cell amount" style="width: 75px;"/>
|
||||
<!--## amount_currency-->
|
||||
<div class="act_as_cell amount" style="width: 75px;">
|
||||
<span t-field="account_or_partner_object.final_amount_residual"/>
|
||||
</div>
|
||||
<!--## currency_name + amount_total_due_currency + amount_residual_currency -->
|
||||
<div class="act_as_cell" style="width: 185px;"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
155
account_financial_report/report/templates/trial_balance.xml
Normal file
155
account_financial_report/report/templates/trial_balance.xml
Normal file
@@ -0,0 +1,155 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<template id="account_financial_report.report_trial_balance_qweb">
|
||||
<t t-call="web.html_container">
|
||||
<t t-foreach="docs" t-as="o">
|
||||
<t t-call="account_financial_report.internal_layout">
|
||||
<t t-call="account_financial_report.report_trial_balance_base"/>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="account_financial_report.report_trial_balance_base">
|
||||
<!-- Saved flag fields into variables, used to define columns display -->
|
||||
<t t-set="show_partner_details" t-value="o.show_partner_details"/>
|
||||
<!-- Defines global variables used by internal layout -->
|
||||
<t t-set="title">Trial Balance</t>
|
||||
<t t-set="company_name" t-value="o.company_id.name"/>
|
||||
<div class="page">
|
||||
<!-- Display filters -->
|
||||
<t t-call="account_financial_report.report_trial_balance_filters"/>
|
||||
<div class="act_as_table list_table" style="margin-top: 10px;"/>
|
||||
|
||||
<!-- Display account lines -->
|
||||
<t t-if="not show_partner_details">
|
||||
<div class="act_as_table data_table" style="width: 1140px !important;">
|
||||
<!-- Display account header -->
|
||||
<t t-call="account_financial_report.report_trial_balance_lines_header"/>
|
||||
|
||||
<!-- Display each lines -->
|
||||
<t t-foreach="o.account_ids" t-as="line">
|
||||
<!-- Display account lines -->
|
||||
<t t-call="account_financial_report.report_trial_balance_line"/>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<!-- Display partner lines -->
|
||||
<t t-if="show_partner_details">
|
||||
<t t-foreach="o.account_ids" t-as="account">
|
||||
<div class="page_break">
|
||||
<!-- Display account header -->
|
||||
<div class="act_as_table list_table" style="margin-top: 10px;"/>
|
||||
<div class="act_as_caption account_title" style="width: 1141px !important;">
|
||||
<span t-field="account.code"/> - <span t-field="account.name"/>
|
||||
</div>
|
||||
|
||||
<div class="act_as_table data_table" style="width: 1140px !important;">
|
||||
<!-- Display account/partner header -->
|
||||
<t t-call="account_financial_report.report_trial_balance_lines_header"/>
|
||||
|
||||
<!-- Display each partners -->
|
||||
<t t-foreach="account.partner_ids" t-as="line">
|
||||
<!-- Display partner line -->
|
||||
<t t-call="account_financial_report.report_trial_balance_line"/>
|
||||
</t>
|
||||
</div>
|
||||
|
||||
<!-- Display account footer -->
|
||||
<t t-call="account_financial_report.report_trial_balance_account_footer"/>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="account_financial_report.report_trial_balance_filters">
|
||||
<div class="act_as_table data_table" style="width: 1140px !important;">
|
||||
<div class="act_as_row labels">
|
||||
<div class="act_as_cell">Date range filter</div>
|
||||
<div class="act_as_cell">Target moves filter</div>
|
||||
<div class="act_as_cell">Account balance at 0 filter</div>
|
||||
</div>
|
||||
<div class="act_as_row">
|
||||
<div class="act_as_cell">
|
||||
From: <span t-field="o.date_from"/> To: <span t-field="o.date_to"/>
|
||||
</div>
|
||||
<div class="act_as_cell">
|
||||
<t t-if="o.only_posted_moves">All posted entries</t>
|
||||
<t t-if="not o.only_posted_moves">All entries</t>
|
||||
</div>
|
||||
<div class="act_as_cell">
|
||||
<t t-if="o.hide_account_balance_at_0">Hide</t>
|
||||
<t t-if="not o.hide_account_balance_at_0">Show</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="account_financial_report.report_trial_balance_lines_header">
|
||||
<!-- Display table headers for lines -->
|
||||
<div class="act_as_thead">
|
||||
<div class="act_as_row labels">
|
||||
<t t-if="not show_partner_details">
|
||||
<!--## Code-->
|
||||
<div class="act_as_cell" style="width: 100px;">Code</div>
|
||||
<!--## Account-->
|
||||
<div class="act_as_cell" style="width: 600px;">Account</div>
|
||||
</t>
|
||||
<t t-if="show_partner_details">
|
||||
<!--## Partner-->
|
||||
<div class="act_as_cell" style="width: 700px;">Partner</div>
|
||||
</t>
|
||||
<!--## Initial balance-->
|
||||
<div class="act_as_cell" style="width: 110px;">Initial balance</div>
|
||||
<!--## Debit-->
|
||||
<div class="act_as_cell" style="width: 110px;">Debit</div>
|
||||
<!--## Credit-->
|
||||
<div class="act_as_cell" style="width: 110px;">Credit</div>
|
||||
<!--## Ending balance-->
|
||||
<div class="act_as_cell" style="width: 110px;">Ending balance</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="account_financial_report.report_trial_balance_line">
|
||||
<!-- # line -->
|
||||
<div class="act_as_row lines">
|
||||
<t t-if="not show_partner_details">
|
||||
<!--## Code-->
|
||||
<div class="act_as_cell left"><span t-field="line.code"/></div>
|
||||
</t>
|
||||
<!--## Account/Partner-->
|
||||
<div class="act_as_cell left"><span t-field="line.name"/></div>
|
||||
<!--## Initial balance-->
|
||||
<div class="act_as_cell amount"><span t-field="line.initial_balance"/></div>
|
||||
<!--## Debit-->
|
||||
<div class="act_as_cell amount"><span t-field="line.debit"/></div>
|
||||
<!--## Credit-->
|
||||
<div class="act_as_cell amount"><span t-field="line.credit"/></div>
|
||||
<!--## Ending balance-->
|
||||
<div class="act_as_cell amount"><span t-field="line.final_balance"/></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="account_financial_report.report_trial_balance_account_footer">
|
||||
<!-- Display account footer -->
|
||||
<div class="act_as_table list_table" style="width: 1141px !important;">
|
||||
<div class="act_as_row labels" style="font-weight: bold;">
|
||||
<!--## Account-->
|
||||
<div class="act_as_cell left" style="width: 700px;"><span t-field="account.code"/> - <span t-field="account.name"/></div>
|
||||
<!--## Initial balance-->
|
||||
<div class="act_as_cell amount" style="width: 110px;"><span t-field="account.initial_balance"/></div>
|
||||
<!--## Debit-->
|
||||
<div class="act_as_cell amount" style="width: 110px;"><span t-field="account.debit"/></div>
|
||||
<!--## Credit-->
|
||||
<div class="act_as_cell amount" style="width: 110px;"><span t-field="account.credit"/></div>
|
||||
<!--## Ending balance-->
|
||||
<div class="act_as_cell amount" style="width: 110px;"><span t-field="account.final_balance"/></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
263
account_financial_report/report/trial_balance.py
Normal file
263
account_financial_report/report/trial_balance.py
Normal file
@@ -0,0 +1,263 @@
|
||||
# ?? 2016 Julien Coux (Camptocamp)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import models, fields, api
|
||||
|
||||
|
||||
class TrialBalanceReport(models.TransientModel):
|
||||
""" Here, we just define class fields.
|
||||
For methods, go more bottom at this file.
|
||||
|
||||
The class hierarchy is :
|
||||
* TrialBalanceReport
|
||||
** TrialBalanceReportAccount
|
||||
*** TrialBalanceReportPartner
|
||||
If "show_partner_details" is selected
|
||||
"""
|
||||
|
||||
_name = 'report_trial_balance'
|
||||
|
||||
# Filters fields, used for data computation
|
||||
date_from = fields.Date()
|
||||
date_to = fields.Date()
|
||||
fy_start_date = fields.Date()
|
||||
only_posted_moves = fields.Boolean()
|
||||
hide_account_balance_at_0 = fields.Boolean()
|
||||
company_id = fields.Many2one(comodel_name='res.company')
|
||||
filter_account_ids = fields.Many2many(comodel_name='account.account')
|
||||
filter_partner_ids = fields.Many2many(comodel_name='res.partner')
|
||||
show_partner_details = fields.Boolean()
|
||||
|
||||
# General Ledger Report Data fields,
|
||||
# used as base for compute the data reports
|
||||
general_ledger_id = fields.Many2one(
|
||||
comodel_name='report_general_ledger'
|
||||
)
|
||||
|
||||
# Data fields, used to browse report data
|
||||
account_ids = fields.One2many(
|
||||
comodel_name='report_trial_balance_account',
|
||||
inverse_name='report_id'
|
||||
)
|
||||
|
||||
|
||||
class TrialBalanceReportAccount(models.TransientModel):
|
||||
_name = 'report_trial_balance_account'
|
||||
_order = 'code ASC'
|
||||
|
||||
report_id = fields.Many2one(
|
||||
comodel_name='report_trial_balance',
|
||||
ondelete='cascade',
|
||||
index=True
|
||||
)
|
||||
|
||||
# Data fields, used to keep link with real object
|
||||
account_id = fields.Many2one(
|
||||
'account.account',
|
||||
index=True
|
||||
)
|
||||
|
||||
# Data fields, used for report display
|
||||
code = fields.Char()
|
||||
name = fields.Char()
|
||||
|
||||
initial_balance = fields.Float(digits=(16, 2))
|
||||
debit = fields.Float(digits=(16, 2))
|
||||
credit = fields.Float(digits=(16, 2))
|
||||
final_balance = fields.Float(digits=(16, 2))
|
||||
|
||||
# Data fields, used to browse report data
|
||||
partner_ids = fields.One2many(
|
||||
comodel_name='report_trial_balance_partner',
|
||||
inverse_name='report_account_id'
|
||||
)
|
||||
|
||||
|
||||
class TrialBalanceReportPartner(models.TransientModel):
|
||||
_name = 'report_trial_balance_partner'
|
||||
|
||||
report_account_id = fields.Many2one(
|
||||
comodel_name='report_trial_balance_account',
|
||||
ondelete='cascade',
|
||||
index=True
|
||||
)
|
||||
|
||||
# Data fields, used to keep link with real object
|
||||
partner_id = fields.Many2one(
|
||||
'res.partner',
|
||||
index=True
|
||||
)
|
||||
|
||||
# Data fields, used for report display
|
||||
name = fields.Char()
|
||||
|
||||
initial_balance = fields.Float(digits=(16, 2))
|
||||
debit = fields.Float(digits=(16, 2))
|
||||
credit = fields.Float(digits=(16, 2))
|
||||
final_balance = fields.Float(digits=(16, 2))
|
||||
|
||||
@api.model
|
||||
def _generate_order_by(self, order_spec, query):
|
||||
"""Custom order to display "No partner allocated" at last position."""
|
||||
return """
|
||||
ORDER BY
|
||||
CASE
|
||||
WHEN "report_trial_balance_partner"."partner_id" IS NOT NULL
|
||||
THEN 0
|
||||
ELSE 1
|
||||
END,
|
||||
"report_trial_balance_partner"."name"
|
||||
"""
|
||||
|
||||
|
||||
class TrialBalanceReportCompute(models.TransientModel):
|
||||
""" Here, we just define methods.
|
||||
For class fields, go more top at this file.
|
||||
"""
|
||||
|
||||
_inherit = 'report_trial_balance'
|
||||
|
||||
@api.multi
|
||||
def print_report(self, report_type):
|
||||
self.ensure_one()
|
||||
if report_type == 'xlsx':
|
||||
report_name = 'a_f_r.report_trial_balance_xlsx'
|
||||
else:
|
||||
report_name = 'account_financial_report.' \
|
||||
'report_trial_balance_qweb'
|
||||
return self.env['ir.actions.report'].search(
|
||||
[('report_name', '=', report_name),
|
||||
('report_type', '=', report_type)], limit=1).report_action(self)
|
||||
|
||||
def _get_html(self):
|
||||
result = {}
|
||||
rcontext = {}
|
||||
context = dict(self.env.context)
|
||||
report = self.browse(context.get('active_id'))
|
||||
if report:
|
||||
rcontext['o'] = report
|
||||
result['html'] = self.env.ref(
|
||||
'account_financial_report.report_trial_balance').render(
|
||||
rcontext)
|
||||
return result
|
||||
|
||||
@api.model
|
||||
def get_html(self, given_context=None):
|
||||
return self._get_html()
|
||||
|
||||
def _prepare_report_general_ledger(self):
|
||||
self.ensure_one()
|
||||
return {
|
||||
'date_from': self.date_from,
|
||||
'date_to': self.date_to,
|
||||
'only_posted_moves': self.only_posted_moves,
|
||||
'hide_account_balance_at_0': self.hide_account_balance_at_0,
|
||||
'company_id': self.company_id.id,
|
||||
'filter_account_ids': [(6, 0, self.filter_account_ids.ids)],
|
||||
'filter_partner_ids': [(6, 0, self.filter_partner_ids.ids)],
|
||||
'fy_start_date': self.fy_start_date,
|
||||
}
|
||||
|
||||
@api.multi
|
||||
def compute_data_for_report(self):
|
||||
self.ensure_one()
|
||||
# Compute General Ledger Report Data.
|
||||
# The data of Trial Balance Report
|
||||
# are based on General Ledger Report data.
|
||||
model = self.env['report_general_ledger']
|
||||
self.general_ledger_id = model.create(
|
||||
self._prepare_report_general_ledger()
|
||||
)
|
||||
self.general_ledger_id.compute_data_for_report(
|
||||
with_line_details=False, with_partners=self.show_partner_details
|
||||
)
|
||||
|
||||
# Compute report data
|
||||
self._inject_account_values()
|
||||
if self.show_partner_details:
|
||||
self._inject_partner_values()
|
||||
# Refresh cache because all data are computed with SQL requests
|
||||
self.refresh()
|
||||
|
||||
def _inject_account_values(self):
|
||||
"""Inject report values for report_trial_balance_account"""
|
||||
query_inject_account = """
|
||||
INSERT INTO
|
||||
report_trial_balance_account
|
||||
(
|
||||
report_id,
|
||||
create_uid,
|
||||
create_date,
|
||||
account_id,
|
||||
code,
|
||||
name,
|
||||
initial_balance,
|
||||
debit,
|
||||
credit,
|
||||
final_balance
|
||||
)
|
||||
SELECT
|
||||
%s AS report_id,
|
||||
%s AS create_uid,
|
||||
NOW() AS create_date,
|
||||
rag.account_id,
|
||||
rag.code,
|
||||
rag.name,
|
||||
rag.initial_balance AS initial_balance,
|
||||
rag.final_debit - rag.initial_debit AS debit,
|
||||
rag.final_credit - rag.initial_credit AS credit,
|
||||
rag.final_balance AS final_balance
|
||||
FROM
|
||||
report_general_ledger_account rag
|
||||
WHERE
|
||||
rag.report_id = %s
|
||||
"""
|
||||
query_inject_account_params = (
|
||||
self.id,
|
||||
self.env.uid,
|
||||
self.general_ledger_id.id,
|
||||
)
|
||||
self.env.cr.execute(query_inject_account, query_inject_account_params)
|
||||
|
||||
def _inject_partner_values(self):
|
||||
"""Inject report values for report_trial_balance_partner"""
|
||||
query_inject_partner = """
|
||||
INSERT INTO
|
||||
report_trial_balance_partner
|
||||
(
|
||||
report_account_id,
|
||||
create_uid,
|
||||
create_date,
|
||||
partner_id,
|
||||
name,
|
||||
initial_balance,
|
||||
debit,
|
||||
credit,
|
||||
final_balance
|
||||
)
|
||||
SELECT
|
||||
ra.id AS report_account_id,
|
||||
%s AS create_uid,
|
||||
NOW() AS create_date,
|
||||
rpg.partner_id,
|
||||
rpg.name,
|
||||
rpg.initial_balance AS initial_balance,
|
||||
rpg.final_debit - rpg.initial_debit AS debit,
|
||||
rpg.final_credit - rpg.initial_credit AS credit,
|
||||
rpg.final_balance AS final_balance
|
||||
FROM
|
||||
report_general_ledger_partner rpg
|
||||
INNER JOIN
|
||||
report_general_ledger_account rag ON rpg.report_account_id = rag.id
|
||||
INNER JOIN
|
||||
report_trial_balance_account ra ON rag.code = ra.code
|
||||
WHERE
|
||||
rag.report_id = %s
|
||||
AND ra.report_id = %s
|
||||
"""
|
||||
query_inject_partner_params = (
|
||||
self.env.uid,
|
||||
self.general_ledger_id.id,
|
||||
self.id,
|
||||
)
|
||||
self.env.cr.execute(query_inject_partner, query_inject_partner_params)
|
||||
122
account_financial_report/report/trial_balance_xlsx.py
Normal file
122
account_financial_report/report/trial_balance_xlsx.py
Normal file
@@ -0,0 +1,122 @@
|
||||
|
||||
# Author: Julien Coux
|
||||
# Copyright 2016 Camptocamp SA
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
|
||||
from odoo import _, models
|
||||
|
||||
|
||||
class TrialBalanceXslx(models.AbstractModel):
|
||||
_name = 'report.a_f_r.report_trial_balance_xlsx'
|
||||
_inherit = 'report.account_financial_report.abstract_report_xlsx'
|
||||
|
||||
def _get_report_name(self):
|
||||
return _('Trial Balance')
|
||||
|
||||
def _get_report_columns(self, report):
|
||||
if not report.show_partner_details:
|
||||
return {
|
||||
0: {'header': _('Code'), 'field': 'code', 'width': 10},
|
||||
1: {'header': _('Account'), 'field': 'name', 'width': 60},
|
||||
2: {'header': _('Initial balance'),
|
||||
'field': 'initial_balance',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
3: {'header': _('Debit'),
|
||||
'field': 'debit',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
4: {'header': _('Credit'),
|
||||
'field': 'credit',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
5: {'header': _('Ending balance'),
|
||||
'field': 'final_balance',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
}
|
||||
else:
|
||||
return {
|
||||
0: {'header': _('Partner'), 'field': 'name', 'width': 70},
|
||||
1: {'header': _('Initial balance'),
|
||||
'field': 'initial_balance',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
2: {'header': _('Debit'),
|
||||
'field': 'debit',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
3: {'header': _('Credit'),
|
||||
'field': 'credit',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
4: {'header': _('Ending balance'),
|
||||
'field': 'final_balance',
|
||||
'type': 'amount',
|
||||
'width': 14},
|
||||
}
|
||||
|
||||
def _get_report_filters(self, report):
|
||||
return [
|
||||
[_('Date range filter'),
|
||||
_('From: %s To: %s') % (report.date_from, report.date_to)],
|
||||
[_('Target moves filter'),
|
||||
_('All posted entries') if report.only_posted_moves
|
||||
else _('All entries')],
|
||||
[_('Account balance at 0 filter'),
|
||||
_('Hide') if report.hide_account_balance_at_0 else _('Show')],
|
||||
]
|
||||
|
||||
def _get_col_count_filter_name(self):
|
||||
return 2
|
||||
|
||||
def _get_col_count_filter_value(self):
|
||||
return 3
|
||||
|
||||
def _generate_report_content(self, workbook, report):
|
||||
|
||||
if not report.show_partner_details:
|
||||
# Display array header for account lines
|
||||
self.write_array_header()
|
||||
|
||||
# For each account
|
||||
for account in report.account_ids:
|
||||
if not report.show_partner_details:
|
||||
# Display account lines
|
||||
self.write_line(account)
|
||||
|
||||
else:
|
||||
# Write account title
|
||||
self.write_array_title(account.code + ' - ' + account.name)
|
||||
|
||||
# Display array header for partner lines
|
||||
self.write_array_header()
|
||||
|
||||
# For each partner
|
||||
for partner in account.partner_ids:
|
||||
# Display partner lines
|
||||
self.write_line(partner)
|
||||
|
||||
# Display account footer line
|
||||
self.write_account_footer(account,
|
||||
account.code + ' - ' + account.name)
|
||||
|
||||
# Line break
|
||||
self.row_pos += 2
|
||||
|
||||
def write_account_footer(self, account, name_value):
|
||||
"""Specific function to write account footer for Trial Balance"""
|
||||
for col_pos, column in self.columns.items():
|
||||
if column['field'] == 'name':
|
||||
value = name_value
|
||||
else:
|
||||
value = getattr(account, column['field'])
|
||||
cell_type = column.get('type', 'string')
|
||||
if cell_type == 'string':
|
||||
self.sheet.write_string(self.row_pos, col_pos, value or '',
|
||||
self.format_header_left)
|
||||
elif cell_type == 'amount':
|
||||
self.sheet.write_number(self.row_pos, col_pos, float(value),
|
||||
self.format_header_amount)
|
||||
self.row_pos += 1
|
||||
Reference in New Issue
Block a user