You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

274 lines
10 KiB

# -*- coding: utf-8 -*-
# Copyright 2009-2016 Noviat
# Copyright 2018 Jacques-Etienne Baudoux (BCIM sprl) <je@bcim.be>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
# from datetime import datetime
from openerp.addons.report_xlsx.report.report_xlsx import ReportXlsx
from openerp.addons.account_financial_report_webkit.report.general_ledger \
import GeneralLedgerWebkit
from openerp.tools.translate import _
def cell(row, col, row_abs=False, col_abs=False):
"""
Convert numeric row/col notation to an Excel cell
reference string in A1 notation.
"""
d = col // 26
m = col % 26
chr1 = "" # Most significant character in AA1
if row_abs:
row_abs = '$'
else:
row_abs = ''
if col_abs:
col_abs = '$'
else:
col_abs = ''
if d > 0:
chr1 = chr(ord('A') + d - 1)
chr2 = chr(ord('A') + m)
# Zero index to 1-index
return col_abs + chr1 + chr2 + row_abs + str(row + 1)
class report_xlsx_format:
decimal_format = '#,##0.00'
date_format = '%Y-%m-%d'
styles = {
'xls_title': [('bold', True), ('font_size', 10)],
'bold': [('bold', True)],
'underline': [('underline', True)],
'italic': [('italic', True)],
'fill_green': [('bg_color', '#CCFFCC')],
'fill_yellow': [('bg_color', '#FFFFCC')],
'money': [('num_format', decimal_format)],
'date': [('num_format', date_format)],
'borders_all': [('border', 1)],
'center': [('align', 'center')],
'right': [('align', 'right')],
}
def _get_style(self, wb, keys):
if not isinstance(keys, (list, tuple)):
keys = (keys, )
style = dict(reduce(
lambda x, y: x+y, [self.styles[k] for k in keys]))
style.setdefault('font_size', 9)
return wb.add_format(style)
class AttrDict(dict):
def __init__(self, *args, **kwargs):
super(AttrDict, self).__init__(*args, **kwargs)
self.__dict__ = self
class GeneralLedgerXlsx(ReportXlsx, report_xlsx_format):
column_sizes = [
10, # date
8, # period
15, # move
8, # journal,
8, # account_code
30, # partner
25, # ref
45, # label
30, # counterpart
12, # debit
12, # credit
12, # bal
12, # filtered_bal
12, # cumul_bal
12, # curr_bal
12, # curr_code
]
def generate_xlsx_report(self, wb, data, objects):
_p = AttrDict(self.parser_instance.localcontext)
wb.formats[0].set_font_size(9)
ws = wb.add_worksheet(_p.report_name.upper()[:31])
ws.set_default_row(13)
ws.panes_frozen = True
ws.remove_splits = True
ws.portrait = 0 # Landscape
ws.fit_width_to_pages = 1
row_pos = 0
# set print header/footer
# ws.header_str = self.xls_headers['standard']
# ws.footer_str = self.xls_footers['standard']
# cf. account_report_general_ledger.mako
initial_balance_text = {'initial_balance': _('Computed'),
'opening_balance': _('Opening Entries'),
False: _('No')}
# Title
row_pos = 0
style_title = self._get_style(wb, 'xls_title')
report_name = ' - '.join([_p.report_name.upper(),
_p.company.partner_id.name,
_p.company.currency_id.name])
ws.write(row_pos, 0, report_name, style_title)
for i, size in enumerate(self.column_sizes):
ws.set_column(i, i, size)
row_pos += 2
# Header Table
style_header1 = self._get_style(wb, ('bold', 'fill_green', 'center'))
style_header2 = self._get_style(wb, ('center'))
ws.merge_range(
row_pos, 0, row_pos, 1, _('Chart of Account'), style_header1)
ws.merge_range(
row_pos+1, 0, row_pos+1, 1, _p.chart_account.name, style_header2)
ws.write(row_pos, 2, _('Fiscal Year'), style_header1)
ws.write(row_pos+1, 2, _p.fiscalyear.name if _p.fiscalyear else '-',
style_header2)
df = _('From') + ': %s ' + _('To') + ': %s'
if _p.filter_form(data) == 'filter_date':
dfh = _('Dates Filter')
df = df % (_p.start_date or '', _p.stop_date or '')
else:
dfh = _('Periods Filter')
df = df % (_p.start_period and _p.start_period.name or '',
_p.stop_period and _p.stop_period.name or '')
ws.merge_range(row_pos, 3, row_pos, 5, dfh, style_header1)
ws.merge_range(row_pos+1, 3, row_pos+1, 5, df, style_header2)
ws.write(row_pos, 6, _('Accounts Filter'), style_header1)
text = _p.accounts(data) and ', '.join([
account.code for account in _p.accounts(data)]) or _('All')
ws.write(row_pos+1, 6, text, style_header2)
ws.write(row_pos, 7, _('Target Moves'), style_header1)
ws.write(row_pos+1, 7, _p.display_target_move(data), style_header2)
ws.write(row_pos, 8, _('Initial Balance'), style_header1)
text = initial_balance_text[_p.initial_balance_mode]
ws.write(row_pos+1, 8, text, style_header2)
row_pos += 2
ws.freeze_panes(row_pos, 0)
row_pos += 1
# cell styles for ledger lines
style_account = self._get_style(wb, ('bold'))
style_labels = self._get_style(wb, ('fill_yellow'))
style_labels_r = self._get_style(wb, ('fill_yellow', 'right', 'bold'))
style_initial_balance = self._get_style(wb, ('italic', 'money'))
# style_date = self._get_style(wb, ('date'))
style_lines = self._get_style(wb, ('money'))
style_sums = self._get_style(wb, ('fill_yellow', 'money', 'bold'))
for account in _p.objects:
display_initial_balance = _p['init_balance'][account.id] and \
(_p['init_balance'][account.id].get(
'debit', 0.0) != 0.0 or
_p['init_balance'][account.id].get('credit', 0.0) != 0.0)
if (not display_initial_balance and
not _p['ledger_lines'][account.id]):
# no lines and no initial balance, do no show account in report
continue
# Write account
name = ' - '.join([account.code, account.name])
ws.write(row_pos, 0, name, style_account)
row_pos += 1
# Write labels
ws.write_row(row_pos, 0, [
_('Date'), _('Period'), _('Entry'), _('Journal'), _('Account'),
_('Partner'), _('Reference'), _('Label'), _('Counterpart')],
style_labels)
ws.write_row(row_pos, 9, [
_('Debit'), _('Credit'), _('Filtered Bal.'), _('Cumul. Bal.')
], style_labels_r)
row_pos += 1
row_start = row_pos
cumul_balance = cumul_balance_curr = 0
# Write initial balance
if display_initial_balance:
ws.write(row_pos, 8, _('Initial Balance'),
style_initial_balance)
init_balance = _p['init_balance'][account.id]
cumul_balance += init_balance.get('init_balance') or 0.0
cumul_balance_curr += \
init_balance.get('init_balance_currency') or 0.0
row = [
init_balance.get('debit') or 0.0,
init_balance.get('credit') or 0.0,
'',
cumul_balance,
]
if _p.amount_currency(data):
row.append(cumul_balance_curr)
ws.write_row(row_pos, 9, row, style_initial_balance)
row_pos += 1
# Write lines
for line in _p['ledger_lines'][account.id]:
label_elements = [line.get('lname') or '']
if line.get('invoice_number'):
label_elements.append(
"(%s)" % (line['invoice_number'],))
label = ' '.join(label_elements)
cumul_balance += line.get('balance') or 0.0
if line['ldate']:
ws.write_string(row_pos, 0, line['ldate'])
# FIXME: date format not recognized
# ws.write_datetime(
# row_pos, 0,
# datetime.strptime(line['ldate'], '%Y-%m-%d'),
# style_date)
row = [
line.get('period_code') or '',
line.get('move_name') or '',
line.get('jcode') or '',
account.code,
line.get('partner_name') or '',
line.get('lref'),
label,
line.get('counterparts') or '',
line.get('debit', 0.0),
line.get('credit', 0.0),
line.get('balance', 0.0),
cumul_balance,
]
if _p.amount_currency(data):
cumul_balance_curr += line.get('amount_currency') or 0.0
row += [
line.get('amount_currency') or 0.0,
line.get('currency_code') or '',
]
ws.write_row(row_pos, 1, row, style_lines)
row_pos += 1
# Write Sums
row = [
_('Cumulated Balance on Account'),
'=SUM(%s:%s)' % (cell(row_start, 9), cell(row_pos-1, 9)),
'=SUM(%s:%s)' % (cell(row_start, 10), cell(row_pos-1, 10)),
'=SUM(%s:%s)' % (cell(row_start, 11), cell(row_pos-1, 11)),
'=%s-%s' % (cell(row_pos, 9), cell(row_pos, 10)),
]
if _p.amount_currency(data):
row += [
cumul_balance_curr,
line.get('currency_code') or '',
]
ws.write_row(row_pos, 8, row, style_sums)
row_pos += 1
GeneralLedgerXlsx('report.account.account_report_general_ledger_xlsx',
'account.account',
parser=GeneralLedgerWebkit)