133 lines
5.5 KiB
Python
133 lines
5.5 KiB
Python
import io
|
|
|
|
from odoo import _, api, models
|
|
from odoo.exceptions import UserError
|
|
|
|
|
|
class JournalReportCustomHandler(models.AbstractModel):
|
|
_inherit = 'account.journal.report.handler'
|
|
|
|
def _custom_options_initializer(self, report, options, previous_options):
|
|
super()._custom_options_initializer(report, options, previous_options)
|
|
|
|
if self.env.company.partner_id.country_id.code != 'ES':
|
|
return
|
|
|
|
# Add the libro diario XLSX download button
|
|
options['buttons'].append({
|
|
'name': _('Libro Diario XLSX'),
|
|
'sequence': 21,
|
|
'action': 'export_file',
|
|
'action_param': 'es_libro_diario_export_to_xlsx',
|
|
'file_export_type': 'XLSX',
|
|
'branch_allowed': True,
|
|
'always_show': True,
|
|
})
|
|
|
|
def es_libro_diario_export_to_xlsx(self, options):
|
|
""" Exports a xlsx document containing the required libro diario data, compliant with the official format."""
|
|
return self._es_libro_diario_generate_xlsx_report(options=options)
|
|
|
|
@api.model
|
|
def _es_libro_diario_generate_xlsx_report(self, options):
|
|
import xlsxwriter # noqa: PLC0415
|
|
with io.BytesIO() as output:
|
|
with xlsxwriter.Workbook(output, {
|
|
'in_memory': True,
|
|
'strings_to_formulas': False,
|
|
}) as workbook:
|
|
self._es_libro_diario_inject_report_into_xlsx_sheet(options, workbook, workbook.add_worksheet())
|
|
return {
|
|
'file_name': "libro_diario.xlsx",
|
|
'file_content': output.getvalue(),
|
|
'file_type': 'xlsx',
|
|
}
|
|
|
|
@api.model
|
|
def _es_libro_diario_inject_report_into_xlsx_sheet(self, options, workbook, sheet):
|
|
header_style = workbook.add_format({'font_name': 'Arial', 'bold': True})
|
|
title_style = workbook.add_format({'font_name': 'Arial', 'bold': True, 'bottom': 2})
|
|
line_style = workbook.add_format({'font_name': 'Arial', 'font_size': 11})
|
|
|
|
sheet.set_column(0, 0, 20) # Company data + Entry
|
|
sheet.set_column(1, 1, 10) # Line
|
|
sheet.set_column(2, 2, 15) # Date
|
|
sheet.set_column(3, 3, 70) # Label
|
|
sheet.set_column(4, 4, 25) # Move Name
|
|
sheet.set_column(5, 5, 15) # Account code
|
|
sheet.set_column(6, 6, 30) # Account name
|
|
sheet.set_column(7, 8, 13) # Debit and Credit
|
|
|
|
header, data = self._es_libro_diario_xlsx_get_data(options)
|
|
padding = 2 # nb of lines between the header and AMLs data
|
|
|
|
for line_offset, line in enumerate(header):
|
|
for col_offset, value in enumerate(line):
|
|
sheet.write(line_offset, col_offset, value, header_style)
|
|
|
|
for line_offset, line in enumerate(data):
|
|
style = title_style if line_offset == 0 else line_style
|
|
for col_offset, value in enumerate(line):
|
|
sheet.write(len(header) + padding + line_offset, col_offset, value, style)
|
|
|
|
@api.model
|
|
def _es_libro_diario_xlsx_get_data(self, options):
|
|
company_ids = [company['id'] for company in options['companies']]
|
|
companies = self.env['res.company'].browse(company_ids)
|
|
if any(companies.filtered(lambda company: company.partner_id.country_id.code != 'ES')):
|
|
raise UserError(_('This report export is only available for ES companies.'))
|
|
|
|
custom_libro_diario_columns = {
|
|
'entry': _("Entry"),
|
|
'line': _("Line"),
|
|
'date': _("Date"),
|
|
'line_name': _("Description"),
|
|
'move_name': _("Document"),
|
|
'account_code': _("Account Code"),
|
|
'account_name': _("Account Name"),
|
|
'debit': _("Debit"),
|
|
'credit': _("Credit"),
|
|
}
|
|
|
|
# Add company data and report dates
|
|
report = self.env['account.report'].browse(options['report_id'])
|
|
report._init_currency_table(options)
|
|
company = report._get_sender_company_for_export(options)
|
|
company_data = [company.name, company.vat or ""]
|
|
report_data = [_("General Ledger - %(date_from)s_%(date_to)s", date_from=options['date']['date_from'], date_to=options['date']['date_to'])]
|
|
|
|
header = [company_data, report_data]
|
|
|
|
# Add the column names
|
|
data = [list(custom_libro_diario_columns.values())]
|
|
|
|
# Get General Ledger report handler and use its engine
|
|
gl_handler = self.env['account.general.ledger.report.handler']
|
|
engine_result = gl_handler._report_custom_engine_general_ledger(None, options, None, 'id_with_accumulated_balance', None)
|
|
# Add lines data
|
|
current_move = ''
|
|
entry_index = 0
|
|
for aml_key, engine_result_dict in engine_result:
|
|
if 'balance_line' in aml_key:
|
|
continue
|
|
if not current_move or current_move != engine_result_dict['move_name']:
|
|
current_move = engine_result_dict['move_name']
|
|
entry_index += 1
|
|
line_index = 1
|
|
else:
|
|
line_index += 1
|
|
|
|
res_line = []
|
|
for column in custom_libro_diario_columns:
|
|
if column == 'entry':
|
|
res_line.append(entry_index)
|
|
elif column == 'line':
|
|
res_line.append(line_index)
|
|
elif column == 'date':
|
|
res_line.append(engine_result_dict['date'].strftime("%d/%m/%Y"))
|
|
else:
|
|
res_line.append(engine_result_dict[column])
|
|
data.append(res_line)
|
|
|
|
return header, data
|