From a2e301920e692d7f1e6a6c31f283a0a95019d1c8 Mon Sep 17 00:00:00 2001 From: Luc De Meyer Date: Sun, 5 Aug 2018 20:05:42 +0200 Subject: [PATCH] [10.0][MIG]account_move_line_export_xls --- account_move_line_report_xls/README.rst | 25 +- account_move_line_report_xls/__init__.py | 31 +- account_move_line_report_xls/__manifest__.py | 32 +- .../account_move_line.py | 57 -- account_move_line_report_xls/i18n/fr.po | 15 +- account_move_line_report_xls/i18n/nl.po | 15 +- .../models/__init__.py | 2 + .../models/account_move_line.py | 49 ++ .../report/__init__.py | 23 +- .../report/move_line_list_xls.py | 721 ++++++++++-------- .../report/move_line_list_xls.xml | 36 +- .../static/description/index.html | 39 +- .../tests/__init__.py | 2 + .../tests/test_aml_report_xlsx.py | 21 + 14 files changed, 550 insertions(+), 518 deletions(-) delete mode 100644 account_move_line_report_xls/account_move_line.py create mode 100644 account_move_line_report_xls/models/__init__.py create mode 100644 account_move_line_report_xls/models/account_move_line.py create mode 100644 account_move_line_report_xls/tests/__init__.py create mode 100644 account_move_line_report_xls/tests/test_aml_report_xlsx.py diff --git a/account_move_line_report_xls/README.rst b/account_move_line_report_xls/README.rst index 446f6f0a..c4634e25 100644 --- a/account_move_line_report_xls/README.rst +++ b/account_move_line_report_xls/README.rst @@ -1,6 +1,8 @@ -.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg - :alt: License +.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png + :target: https://www.gnu.org/licenses/agpl + :alt: License: AGPL-3 +========================== Journal Items Excel Export ========================== @@ -10,7 +12,7 @@ This module extends the functionality of the journal items Installation ============ -To install this module, you need also the **report_xls** +To install this module, you need also the **report_xlsx_helper** module located in: https://github.com/OCA/reporting-engine @@ -46,6 +48,18 @@ of the 'account.move.line' object: Change/extend the Excel template. +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/91/10.0 + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues +`_. In case of trouble, please +check there if your issue has already been reported. If you spotted it first, +help us smashing it by providing a detailed and welcomed feedback. + Credits ======= @@ -63,9 +77,10 @@ Icon Maintainer ---------- -.. image:: http://odoo-community.org/logo.png + +.. image:: https://odoo-community.org/logo.png :alt: Odoo Community Association - :target: http://odoo-community.org + :target: https://odoo-community.org This module is maintained by the OCA. diff --git a/account_move_line_report_xls/__init__.py b/account_move_line_report_xls/__init__.py index 0d4ee376..a59de054 100644 --- a/account_move_line_report_xls/__init__.py +++ b/account_move_line_report_xls/__init__.py @@ -1,30 +1,9 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# -# Copyright (c) 2014 Noviat nv/sa (www.noviat.com). All rights reserved. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - +# -*- coding: utf-8 -*- +from . import models try: - from . import account_move_line from . import report except ImportError: import logging - logging.getLogger('openerp.module').\ - warning('''report_xls not available in addons path. - account_financial_report_webkit_xls will not be usable''') + logging.getLogger('odoo.module').\ + warning('''report_xlsx_helper not available in addons path. + account_move_line_report_xls will not be usable''') diff --git a/account_move_line_report_xls/__manifest__.py b/account_move_line_report_xls/__manifest__.py index c8c1c8e0..dc1c0068 100644 --- a/account_move_line_report_xls/__manifest__.py +++ b/account_move_line_report_xls/__manifest__.py @@ -1,35 +1,17 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# -# Copyright (c) 2014 Noviat nv/sa (www.noviat.com). All rights reserved. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## +# -*- coding: utf-8 -*- +# Copyright 2009-2018 Noviat. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). { - 'name': 'Account Move Line XLS export', - 'version': '8.0.0.6.0', + 'name': 'Account Move Line XLSX export', + 'version': '10.0.1.0.0', 'license': 'AGPL-3', 'author': "Noviat, Odoo Community Association (OCA)", 'category': 'Accounting & Finance', 'summary': 'Journal Items Excel export', - 'depends': ['account', 'report_xls'], + 'depends': ['account', 'report_xlsx_helper'], 'data': [ 'report/move_line_list_xls.xml', ], - 'installable': False, + 'installable': True, } diff --git a/account_move_line_report_xls/account_move_line.py b/account_move_line_report_xls/account_move_line.py deleted file mode 100644 index c13a74f9..00000000 --- a/account_move_line_report_xls/account_move_line.py +++ /dev/null @@ -1,57 +0,0 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# -# Copyright (c) 2014 Noviat nv/sa (www.noviat.com). All rights reserved. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - -from openerp import models, api - - -class account_move_line(models.Model): - _inherit = 'account.move.line' - - # override list in custom module to add/drop columns or change order - @api.model - def _report_xls_fields(self): - return [ - 'move', 'name', 'date', 'journal', 'period', 'partner', 'account', - 'date_maturity', 'debit', 'credit', 'balance', - 'reconcile', 'reconcile_partial', 'analytic_account', - # 'ref', 'partner_ref', 'tax_code', 'tax_amount', - # 'amount_residual', 'amount_currency', 'currency_name', - # 'company_currency', 'amount_residual_currency', - # 'product', 'product_ref', 'product_uom', 'quantity', - # 'statement', 'invoice', 'narration', 'blocked', - ] - - # Change/Add Template entries - @api.model - def _report_xls_template(self): - """ - Template updates, e.g. - - my_change = { - 'move':{ - 'header': [1, 20, 'text', _('My Move Title')], - 'lines': [1, 0, 'text', _render("line.move_id.name or ''")], - 'totals': [1, 0, 'text', None]}, - } - return my_change - """ - return {} diff --git a/account_move_line_report_xls/i18n/fr.po b/account_move_line_report_xls/i18n/fr.po index fdddd143..0e8e8639 100644 --- a/account_move_line_report_xls/i18n/fr.po +++ b/account_move_line_report_xls/i18n/fr.po @@ -1,13 +1,13 @@ -# French translation of OpenERP Server 7.0. +# French translation of Odoo. # This file contains the translation of the following modules: -# * account_move_line_report_xls +# * account_move_line_report_xls # msgid "" msgstr "" -"Project-Id-Version: OpenERP Server 7.0\n" +"Project-Id-Version: Odoo Server 8.0\n" "Report-Msgid-Bugs-To: support@noviat.com\n" -"POT-Creation-Date: 2014-01-08 23:46:06.568000\n" -"PO-Revision-Date: 2014-01-08 23:46:06.568000\n" +"POT-Creation-Date: 2016-05-16 12:31:16.568000\n" +"PO-Revision-Date: 2016-05-16 12:31:16.568000\n" "Last-Translator: Luc De Meyer (Noviat nv/sa)\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -124,6 +124,11 @@ msgstr "Dev. Soc." msgid "Analytic Account" msgstr "Compte analytique" +#. module: account_move_line_report_xls +#: report:move.line.list.xls:0 +msgid "Analytic Account Reference" +msgstr "Référence compte analytique" + #. module: account_move_line_report_xls #: report:move.line.list.xls:0 msgid "Product" diff --git a/account_move_line_report_xls/i18n/nl.po b/account_move_line_report_xls/i18n/nl.po index cdfad823..fed06d5c 100644 --- a/account_move_line_report_xls/i18n/nl.po +++ b/account_move_line_report_xls/i18n/nl.po @@ -1,13 +1,13 @@ -# Dutch translation of OpenERP Server 7.0. +# Dutch translation of Odoo. # This file contains the translation of the following modules: -# * account_move_line_report_xls +# * account_move_line_report_xls # msgid "" msgstr "" -"Project-Id-Version: OpenERP Server 7.0\n" +"Project-Id-Version: Odoo Server 8.0\n" "Report-Msgid-Bugs-To: support@noviat.com\n" -"POT-Creation-Date: 2014-01-08 23:46:06.564000\n" -"PO-Revision-Date: 2014-01-08 23:46:06.564000\n" +"POT-Creation-Date: 2016-05-16 12:31:16.564000\n" +"PO-Revision-Date: 2016-05-16 12:31:16.564000\n" "Last-Translator: Luc De Meyer (Noviat nv/sa)\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -124,6 +124,11 @@ msgstr "Bedr. Val." msgid "Analytic Account" msgstr "Kostenplaats" +#. module: account_move_line_report_xls +#: report:move.line.list.xls:0 +msgid "Analytic Account Reference" +msgstr "Kostenplaats referentie" + #. module: account_move_line_report_xls #: report:move.line.list.xls:0 msgid "Product" diff --git a/account_move_line_report_xls/models/__init__.py b/account_move_line_report_xls/models/__init__.py new file mode 100644 index 00000000..d32a961a --- /dev/null +++ b/account_move_line_report_xls/models/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +from . import account_move_line diff --git a/account_move_line_report_xls/models/account_move_line.py b/account_move_line_report_xls/models/account_move_line.py new file mode 100644 index 00000000..7969b919 --- /dev/null +++ b/account_move_line_report_xls/models/account_move_line.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# Copyright 2009-2018 Noviat. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, models +from odoo.addons.report_xlsx_helper.report.abstract_report_xlsx \ + import AbstractReportXlsx +_render = AbstractReportXlsx._render + + +class AccountMoveLine(models.Model): + _inherit = 'account.move.line' + + # Change list in custom module e.g. to add/drop columns or change order + @api.model + def _report_xlsx_fields(self): + return [ + 'move', 'name', 'date', 'journal', 'partner', 'account', + 'date_maturity', 'debit', 'credit', 'balance', + 'full_reconcile', 'reconcile_amount', + # 'analytic_account_name', 'analytic_account', + # 'ref', 'partner_ref', + # 'amount_residual', 'amount_currency', 'currency_name', + # 'company_currency', 'amount_residual_currency', + # 'product', 'product_ref', 'product_uom', 'quantity', + # 'statement', 'invoice', 'narration', 'blocked', + # 'id', 'matched_debit_ids', 'matched_credit_ids', + ] + + # Change/Add Template entries + @api.model + def _report_xlsx_template(self): + """ + Template updates, e.g. + + my_change = { + 'move': { + 'header': { + 'value': 'My Move Title', + }, + 'lines': { + 'value': _render("line.move_id.name or ''"), + }, + 'width': 20, + }, + } + return my_change + """ + return {} diff --git a/account_move_line_report_xls/report/__init__.py b/account_move_line_report_xls/report/__init__.py index 4938e74e..28addd91 100644 --- a/account_move_line_report_xls/report/__init__.py +++ b/account_move_line_report_xls/report/__init__.py @@ -1,23 +1,2 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# -# Copyright (c) 2014 Noviat nv/sa (www.noviat.com). All rights reserved. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - +# -*- coding: utf-8 -*- from . import move_line_list_xls diff --git a/account_move_line_report_xls/report/move_line_list_xls.py b/account_move_line_report_xls/report/move_line_list_xls.py index 0bb4e496..bf6d4c15 100644 --- a/account_move_line_report_xls/report/move_line_list_xls.py +++ b/account_move_line_report_xls/report/move_line_list_xls.py @@ -1,373 +1,450 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# -# Copyright (c) 2014 Noviat nv/sa (www.noviat.com). All rights reserved. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## +# -*- coding: utf-8 -*- +# Copyright 2009-2018 Noviat +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -import xlwt -from datetime import datetime -from openerp.osv import orm -from openerp.report import report_sxw -from openerp.addons.report_xls.report_xls import report_xls -from openerp.addons.report_xls.utils import rowcol_to_cell, _render -from openerp.tools.translate import translate, _ import logging -_logger = logging.getLogger(__name__) - -_ir_translation_name = 'move.line.list.xls' +from odoo.addons.report_xlsx_helper.report.abstract_report_xlsx \ + import AbstractReportXlsx +from odoo.report import report_sxw +from odoo.tools.translate import translate -class move_line_xls_parser(report_sxw.rml_parse): - - def __init__(self, cr, uid, name, context): - super(move_line_xls_parser, self).__init__( - cr, uid, name, context=context) - move_obj = self.pool.get('account.move.line') - self.context = context - wanted_list = move_obj._report_xls_fields(cr, uid, context) - template_changes = move_obj._report_xls_template(cr, uid, context) - self.localcontext.update({ - 'datetime': datetime, - 'wanted_list': wanted_list, - 'template_changes': template_changes, - '_': self._, - }) +_logger = logging.getLogger(__name__) - def _(self, src): - lang = self.context.get('lang', 'en_US') - return translate(self.cr, _ir_translation_name, 'report', lang, src) \ - or src +IR_TRANSLATION_NAME = 'move.line.list.xls' -class move_line_xls(report_xls): +class MoveLineXlsx(AbstractReportXlsx): - def __init__(self, name, table, rml=False, parser=False, header=True, - store=False): - super(move_line_xls, self).__init__( - name, table, rml, parser, header, store) + def _(self, src): + lang = self.env.context.get('lang', 'en_US') + val = translate( + self.env.cr, IR_TRANSLATION_NAME, 'report', lang, src) or src + return val - # Cell Styles - _xs = self.xls_styles - # header - rh_cell_format = _xs['bold'] + _xs['fill'] + _xs['borders_all'] - self.rh_cell_style = xlwt.easyxf(rh_cell_format) - self.rh_cell_style_center = xlwt.easyxf(rh_cell_format + _xs['center']) - self.rh_cell_style_right = xlwt.easyxf(rh_cell_format + _xs['right']) - # lines - aml_cell_format = _xs['borders_all'] - self.aml_cell_style = xlwt.easyxf(aml_cell_format) - self.aml_cell_style_center = xlwt.easyxf( - aml_cell_format + _xs['center']) - self.aml_cell_style_date = xlwt.easyxf( - aml_cell_format + _xs['left'], - num_format_str=report_xls.date_format) - self.aml_cell_style_decimal = xlwt.easyxf( - aml_cell_format + _xs['right'], - num_format_str=report_xls.decimal_format) - # totals - rt_cell_format = _xs['bold'] + _xs['fill'] + _xs['borders_all'] - self.rt_cell_style = xlwt.easyxf(rt_cell_format) - self.rt_cell_style_right = xlwt.easyxf(rt_cell_format + _xs['right']) - self.rt_cell_style_decimal = xlwt.easyxf( - rt_cell_format + _xs['right'], - num_format_str=report_xls.decimal_format) + def _get_ws_params(self, workbook, data, amls): - # XLS Template - self.col_specs_template = { + # XLSX Template + col_specs = { 'move': { - 'header': [1, 20, 'text', _render("_('Entry')")], - 'lines': [1, 0, 'text', _render("line.move_id.name or ''")], - 'totals': [1, 0, 'text', None]}, + 'header': { + 'value': self._('Entry'), + }, + 'lines': { + 'value': self._render("line.move_id.name"), + }, + 'width': 20, + }, 'name': { - 'header': [1, 42, 'text', _render("_('Name')")], - 'lines': [1, 0, 'text', _render("line.name or ''")], - 'totals': [1, 0, 'text', None]}, + 'header': { + 'value': self._('Name'), + }, + 'lines': { + 'value': self._render("line.name"), + }, + 'width': 42, + }, 'ref': { - 'header': [1, 42, 'text', _render("_('Reference')")], - 'lines': [1, 0, 'text', _render("line.ref or ''")], - 'totals': [1, 0, 'text', None]}, + 'header': { + 'value': self._('Reference'), + }, + 'lines': { + 'value': self._render("line.ref"), + }, + 'width': 42, + }, 'date': { - 'header': [1, 13, 'text', _render("_('Effective Date')")], - 'lines': [1, 0, 'date', - _render("datetime.strptime(line.date,'%Y-%m-%d')"), - None, self.aml_cell_style_date], - 'totals': [1, 0, 'text', None]}, - 'period': { - 'header': [1, 12, 'text', _render("_('Period')")], - 'lines': - [1, 0, 'text', - _render("line.period_id.code or line.period_id.name")], - 'totals': [1, 0, 'text', None]}, + 'header': { + 'value': self._('Effective Date'), + }, + 'lines': { + 'value': self._render( + "datetime.strptime(line.date, '%Y-%m-%d')"), + 'format': self.format_tcell_date_left, + }, + 'width': 13, + }, 'partner': { - 'header': [1, 36, 'text', _render("_('Partner')")], - 'lines': - [1, 0, 'text', - _render("line.partner_id and line.partner_id.name or ''")], - 'totals': [1, 0, 'text', None]}, + 'header': { + 'value': self._('Partner'), + }, + 'lines': { + 'value': self._render( + "line.partner_id and line.partner_id.name"), + }, + 'width': 36, + }, 'partner_ref': { - 'header': [1, 36, 'text', _render("_('Partner Reference')")], - 'lines': - [1, 0, 'text', - _render("line.partner_id and line.partner_id.ref or ''")], - 'totals': [1, 0, 'text', None]}, + 'header': { + 'value': self._('Partner Reference'), + }, + 'lines': { + 'value': self._render( + "line.partner_id and line.partner_id.ref"), + }, + 'width': 36, + }, 'account': { - 'header': [1, 12, 'text', _render("_('Account')")], - 'lines': [1, 0, 'text', _render("line.account_id.code")], - 'totals': [1, 0, 'text', None]}, + 'header': { + 'value': self._('Account'), + }, + 'lines': { + 'value': self._render( + "line.account_id.code"), + }, + 'width': 12, + }, 'date_maturity': { - 'header': [1, 13, 'text', _render("_('Maturity Date')")], - 'lines': - [1, 0, - _render("line.date_maturity and 'date' or 'text'"), - _render( - "line.date_maturity" - " and datetime.strptime(line.date_maturity,'%Y-%m-%d')" - " or None"), - None, self.aml_cell_style_date], - 'totals': [1, 0, 'text', None]}, + 'header': { + 'value': self._('Maturity Date'), + }, + 'lines': { + 'value': self._render( + "datetime.strptime(line.date_maturity,'%Y-%m-%d')"), + 'format': self.format_tcell_date_left, + }, + 'width': 13, + }, 'debit': { - 'header': [1, 18, 'text', _render("_('Debit')"), None, - self.rh_cell_style_right], - 'lines': [1, 0, 'number', _render("line.debit"), None, - self.aml_cell_style_decimal], - 'totals': [1, 0, 'number', None, _render("debit_formula"), - self.rt_cell_style_decimal]}, + 'header': { + 'value': self._('Debit'), + 'format': self.format_theader_yellow_right, + }, + 'lines': { + 'value': self._render("line.debit"), + 'format': self.format_tcell_amount_right, + }, + 'totals': { + 'type': 'formula', + 'value': self._render("debit_formula"), + 'format': self.format_theader_yellow_amount_right, + }, + 'width': 18, + }, 'credit': { - 'header': [1, 18, 'text', _render("_('Credit')"), None, - self.rh_cell_style_right], - 'lines': [1, 0, 'number', _render("line.credit"), None, - self.aml_cell_style_decimal], - 'totals': [1, 0, 'number', None, _render("credit_formula"), - self.rt_cell_style_decimal]}, + 'header': { + 'value': self._('Credit'), + 'format': self.format_theader_yellow_right, + }, + 'lines': { + 'value': self._render("line.credit"), + 'format': self.format_tcell_amount_right, + }, + 'totals': { + 'type': 'formula', + 'value': self._render("credit_formula"), + 'format': self.format_theader_yellow_amount_right, + }, + 'width': 18, + }, 'balance': { - 'header': [1, 18, 'text', _render("_('Balance')"), None, - self.rh_cell_style_right], - 'lines': [1, 0, 'number', None, _render("bal_formula"), - self.aml_cell_style_decimal], - 'totals': [1, 0, 'number', None, _render("bal_formula"), - self.rt_cell_style_decimal]}, - 'reconcile': { - 'header': [1, 12, 'text', _render("_('Rec.')"), None, - self.rh_cell_style_center], - 'lines': [1, 0, 'text', - _render("line.reconcile_id.name or ''"), None, - self.aml_cell_style_center], - 'totals': [1, 0, 'text', None]}, - 'reconcile_partial': { - 'header': [1, 12, 'text', _render("_('Part. Rec.')"), None, - self.rh_cell_style_center], - 'lines': [1, 0, 'text', - _render("line.reconcile_partial_id.name or ''"), - None, self.aml_cell_style_center], - 'totals': [1, 0, 'text', None]}, - 'tax_code': { - 'header': [1, 12, 'text', _render("_('Tax Code')"), None, - self.rh_cell_style_center], - 'lines': [1, 0, 'text', _render("line.tax_code_id.code or ''"), - None, self.aml_cell_style_center], - 'totals': [1, 0, 'text', None]}, - 'tax_amount': { - 'header': [1, 18, 'text', _render("_('Tax/Base Amount')"), - None, self.rh_cell_style_right], - 'lines': [1, 0, 'number', _render("line.tax_amount"), None, - self.aml_cell_style_decimal], - 'totals': [1, 0, 'text', None]}, + 'header': { + 'value': self._('Balance'), + 'format': self.format_theader_yellow_right, + }, + 'lines': { + 'value': self._render("line.balance"), + 'format': self.format_tcell_amount_right, + }, + 'totals': { + 'type': 'formula', + 'value': self._render("bal_formula"), + 'format': self.format_theader_yellow_amount_right, + }, + 'width': 18, + }, + 'full_reconcile': { + 'header': { + 'value': self._('Rec.'), + 'format': self.format_theader_yellow_center, + }, + 'lines': { + 'value': self._render( + "line.full_reconcile_id " + "and line.full_reconcile_id.name"), + 'format': self.format_tcell_center, + }, + 'width': 12, + }, + 'reconcile_amount': { + 'header': { + 'value': self._('Reconcile Amount'), + }, + 'lines': { + 'value': self._render( + "line.full_reconcile_id and line.balance or " + "(sum(line.matched_credit_ids.mapped('amount')) - " + "sum(line.matched_debit_ids.mapped('amount')))"), + 'format': self.format_tcell_amount_right, + }, + 'width': 12, + }, + 'matched_debit_ids': { + 'header': { + 'value': self._('Matched Debits'), + }, + 'lines': { + 'value': self._render( + "line.matched_debit_ids " + "and str([x.debit_move_id.id " + "for x in line.matched_debit_ids])"), + }, + 'width': 20, + }, + 'matched_credit_ids': { + 'header': { + 'value': self._('Matched Credits'), + }, + 'lines': { + 'value': self._render( + "line.matched_credit_ids " + "and str([x.credit_move_id.id " + "for x in line.matched_credit_ids])"), + }, + 'width': 20, + }, 'amount_currency': { - 'header': [1, 18, 'text', _render("_('Am. Currency')"), None, - self.rh_cell_style_right], - 'lines': - [1, 0, - _render("line.amount_currency and 'number' or 'text'"), - _render("line.amount_currency or None"), - None, self.aml_cell_style_decimal], - 'totals': [1, 0, 'text', None]}, + 'header': { + 'value': self._('Am. Currency'), + 'format': self.format_theader_yellow_right, + }, + 'lines': { + 'value': self._render("line.amount_currency"), + 'format': self.format_tcell_amount_right, + }, + 'width': 18, + }, 'currency_name': { - 'header': [1, 6, 'text', _render("_('Curr.')"), None, - self.rh_cell_style_center], - 'lines': - [1, 0, 'text', - _render("line.currency_id and line.currency_id.name or ''"), - None, self.aml_cell_style_center], - 'totals': [1, 0, 'text', None]}, + 'header': { + 'value': self._('Curr.'), + 'format': self.format_theader_yellow_center, + }, + 'lines': { + 'value': self._render( + "line.currency_id and line.currency_id.name"), + 'format': self.format_tcell_center, + }, + 'width': 6, + }, 'journal': { - 'header': [1, 12, 'text', _render("_('Journal')")], - 'lines': [1, 0, 'text', _render("line.journal_id.code or ''")], - 'totals': [1, 0, 'text', None]}, + 'header': { + 'value': self._('Journal'), + }, + 'lines': { + 'value': self._render("line.journal_id.code"), + }, + 'width': 12, + }, 'company_currency': { - 'header': [1, 10, 'text', _render("_('Comp. Curr.')")], - 'lines': [1, 0, 'text', - _render("line.company_id.currency_id.name or ''"), - None, self.aml_cell_style_center], - 'totals': [1, 0, 'text', None]}, + 'header': { + 'value': self._('Comp. Curr.'), + 'format': self.format_theader_yellow_center, + }, + 'lines': { + 'value': self._render( + "line.company_id.currency_id.name"), + 'format': self.format_tcell_center, + }, + 'width': 10, + }, 'analytic_account': { - 'header': [1, 36, 'text', _render("_('Analytic Account')")], - 'lines': [1, 0, 'text', - _render("line.analytic_account_id.code or ''")], - 'totals': [1, 0, 'text', None]}, + 'header': { + 'value': self._('Analytic Account Reference'), + }, + 'lines': { + 'value': self._render( + "line.analytic_account_id " + "and line.analytic_account_id.code"), + }, + 'width': 36, + }, + 'analytic_account_name': { + 'header': { + 'value': self._('Analytic Account'), + }, + 'lines': { + 'value': self._render( + "line.analytic_account_id " + "and line.analytic_account_id.name"), + }, + 'width': 36, + }, 'product': { - 'header': [1, 36, 'text', _render("_('Product')")], - 'lines': [1, 0, 'text', _render("line.product_id.name or ''")], - 'totals': [1, 0, 'text', None]}, + 'header': { + 'value': self._('Product'), + }, + 'lines': { + 'value': self._render( + "line.product_id and line.product_id.name"), + }, + 'width': 36, + }, 'product_ref': { - 'header': [1, 36, 'text', _render("_('Product Reference')")], - 'lines': [1, 0, 'text', - _render("line.product_id.default_code or ''")], - 'totals': [1, 0, 'text', None]}, + 'header': { + 'value': self._('Product Reference'), + }, + 'lines': { + 'value': self._render( + "line.product_id and line.product_id.default_code " + "or ''"), + }, + 'width': 36, + }, 'product_uom': { - 'header': [1, 20, 'text', _render("_('Unit of Measure')")], - 'lines': [1, 0, 'text', - _render("line.product_uom_id.name or ''")], - 'totals': [1, 0, 'text', None]}, + 'header': { + 'value': self._('Unit of Measure'), + }, + 'lines': { + 'value': self._render( + "line.product_uom_id and line.product_uom_id.name"), + }, + 'width': 20, + }, 'quantity': { - 'header': [1, 8, 'text', _render("_('Qty')"), None, - self.rh_cell_style_right], - 'lines': [1, 0, - _render("line.quantity and 'number' or 'text'"), - _render("line.quantity or None"), None, - self.aml_cell_style_decimal], - 'totals': [1, 0, 'text', None]}, + 'header': { + 'value': self._('Qty'), + 'format': self.format_theader_yellow_right, + }, + 'lines': { + 'value': self._render("line.quantity"), + 'format': self.format_tcell_amount_right, + }, + 'width': 8, + }, 'statement': { - 'header': [1, 20, 'text', _render("_('Statement')")], - 'lines': - [1, 0, 'text', - _render("line.statement_id and line.statement_id.name or ''") - ], - 'totals': [1, 0, 'text', None]}, + 'header': { + 'value': self._('Statement'), + }, + 'lines': { + 'value': self._render( + "line.statement_id and line.statement_id.name"), + }, + 'width': 20, + }, 'invoice': { - 'header': [1, 20, 'text', _render("_('Invoice')")], - 'lines': - [1, 0, 'text', - _render("line.invoice and line.invoice.number or ''")], - 'totals': [1, 0, 'text', None]}, + 'header': { + 'value': self._('Invoice'), + }, + 'lines': { + 'value': self._render( + "line.invoice_id and line.invoice_id.number"), + }, + 'width': 20, + }, 'amount_residual': { - 'header': [1, 18, 'text', _render("_('Residual Amount')"), - None, self.rh_cell_style_right], - 'lines': - [1, 0, - _render("line.amount_residual and 'number' or 'text'"), - _render("line.amount_residual or None"), - None, self.aml_cell_style_decimal], - 'totals': [1, 0, 'text', None]}, + 'header': { + 'value': self._('Residual Amount'), + 'format': self.format_theader_yellow_right, + }, + 'lines': { + 'value': self._render("line.amount_residual"), + 'format': self.format_tcell_amount_right, + }, + 'width': 18, + }, 'amount_residual_currency': { - 'header': [1, 18, 'text', _render("_('Res. Am. in Curr.')"), - None, self.rh_cell_style_right], - 'lines': - [1, 0, - _render( - "line.amount_residual_currency and 'number' or 'text'"), - _render("line.amount_residual_currency or None"), - None, self.aml_cell_style_decimal], - 'totals': [1, 0, 'text', None]}, + 'header': { + 'value': self._('Res. Am. in Curr.'), + 'format': self.format_theader_yellow_right, + }, + 'lines': { + 'value': self._render("line.amount_residual_currency"), + 'format': self.format_tcell_amount_right, + }, + 'width': 18, + }, 'narration': { - 'header': [1, 42, 'text', _render("_('Notes')")], - 'lines': [1, 0, 'text', - _render("line.move_id.narration or ''")], - 'totals': [1, 0, 'text', None]}, + 'header': { + 'value': self._('Notes'), + }, + 'lines': { + 'value': self._render("line.move_id.narration or ''"), + }, + 'width': 42, + }, 'blocked': { - 'header': [1, 4, 'text', _('Lit.'), - None, self.rh_cell_style_right], - 'lines': [1, 0, 'text', _render("line.blocked and 'x' or ''"), - None, self.aml_cell_style_center], - 'totals': [1, 0, 'text', None]}, + 'header': { + 'value': self._('Lit.'), + 'format': self.format_theader_yellow_center, + }, + 'lines': { + 'value': self._render("line.blocked and 'x' or ''"), + 'format': self.format_tcell_center, + }, + 'width': 4, + }, + 'id': { + 'header': { + 'value': self._('Id'), + 'format': self.format_theader_yellow_right, + }, + 'lines': { + 'value': self._render("line.id"), + 'format': self.format_tcell_integer_right, + }, + 'width': 12, + }, } + col_specs.update(self.env['account.move.line']._report_xlsx_template()) + wanted_list = self.env['account.move.line']._report_xlsx_fields() + title = self._("Journal Items") - def generate_xls_report(self, _p, _xs, data, objects, wb): + return [{ + 'ws_name': title, + 'generate_ws_method': '_amls_export', + 'title': title, + 'wanted_list': wanted_list, + 'col_specs': col_specs, + }] - wanted_list = _p.wanted_list - self.col_specs_template.update(_p.template_changes) - _ = _p._ + def _amls_export(self, workbook, ws, ws_params, data, amls): - debit_pos = 'debit' in wanted_list and wanted_list.index('debit') - credit_pos = 'credit' in wanted_list and wanted_list.index('credit') - if not (credit_pos and debit_pos) and 'balance' in wanted_list: - raise orm.except_orm( - _('Customisation Error!'), - _("The 'Balance' field is a calculated XLS field requiring \ - the presence of the 'Debit' and 'Credit' fields !")) + ws.set_landscape() + ws.fit_to_pages(1, 0) + ws.set_header(self.xls_headers['standard']) + ws.set_footer(self.xls_footers['standard']) + + self._set_column_width(ws, ws_params) - # report_name = objects[0]._description or objects[0]._name - report_name = _("Journal Items") - ws = wb.add_sheet(report_name[:31]) - ws.panes_frozen = True - ws.remove_splits = True - ws.portrait = 0 # Landscape - ws.fit_width_to_pages = 1 row_pos = 0 + row_pos = self._write_ws_title(ws, row_pos, ws_params) - # set print header/footer - ws.header_str = self.xls_headers['standard'] - ws.footer_str = self.xls_footers['standard'] + row_pos = self._write_line( + ws, row_pos, ws_params, col_specs_section='header', + default_format=self.format_theader_yellow_left) - # Title - cell_style = xlwt.easyxf(_xs['xls_title']) - c_specs = [ - ('report_name', 1, 0, 'text', report_name), - ] - row_data = self.xls_row_template(c_specs, ['report_name']) - row_pos = self.xls_write_row( - ws, row_pos, row_data, row_style=cell_style) - row_pos += 1 + ws.freeze_panes(row_pos, 0) - # Column headers - c_specs = map(lambda x: self.render( - x, self.col_specs_template, 'header', render_space={'_': _p._}), - wanted_list) - row_data = self.xls_row_template(c_specs, [x[0] for x in c_specs]) - row_pos = self.xls_write_row( - ws, row_pos, row_data, row_style=self.rh_cell_style, - set_column_size=True) - ws.set_horz_split_pos(row_pos) + wanted_list = ws_params['wanted_list'] + debit_pos = 'debit' in wanted_list and wanted_list.index('debit') + credit_pos = 'credit' in wanted_list and wanted_list.index('credit') - # account move lines - for line in objects: - debit_cell = rowcol_to_cell(row_pos, debit_pos) - credit_cell = rowcol_to_cell(row_pos, credit_pos) - bal_formula = debit_cell + '-' + credit_cell - _logger.debug('dummy call - %s', bal_formula) - c_specs = map( - lambda x: self.render(x, self.col_specs_template, 'lines'), - wanted_list) - row_data = self.xls_row_template(c_specs, [x[0] for x in c_specs]) - row_pos = self.xls_write_row( - ws, row_pos, row_data, row_style=self.aml_cell_style) + for line in amls: + row_pos = self._write_line( + ws, row_pos, ws_params, col_specs_section='lines', + render_space={'line': line}, + default_format=self.format_tcell_left) - # Totals - aml_cnt = len(objects) - debit_start = rowcol_to_cell(row_pos - aml_cnt, debit_pos) - debit_stop = rowcol_to_cell(row_pos - 1, debit_pos) + aml_cnt = len(amls) + debit_start = self._rowcol_to_cell(row_pos - aml_cnt, debit_pos) + debit_stop = self._rowcol_to_cell(row_pos - 1, debit_pos) debit_formula = 'SUM(%s:%s)' % (debit_start, debit_stop) - _logger.debug('dummy call - %s', debit_formula) - credit_start = rowcol_to_cell(row_pos - aml_cnt, credit_pos) - credit_stop = rowcol_to_cell(row_pos - 1, credit_pos) + credit_start = self._rowcol_to_cell(row_pos - aml_cnt, credit_pos) + credit_stop = self._rowcol_to_cell(row_pos - 1, credit_pos) credit_formula = 'SUM(%s:%s)' % (credit_start, credit_stop) - _logger.debug('dummy call - %s', credit_formula) - debit_cell = rowcol_to_cell(row_pos, debit_pos) - credit_cell = rowcol_to_cell(row_pos, credit_pos) + debit_cell = self._rowcol_to_cell(row_pos, debit_pos) + credit_cell = self._rowcol_to_cell(row_pos, credit_pos) bal_formula = debit_cell + '-' + credit_cell - _logger.debug('dummy call - %s', bal_formula) - c_specs = map( - lambda x: self.render(x, self.col_specs_template, 'totals'), - wanted_list) - row_data = self.xls_row_template(c_specs, [x[0] for x in c_specs]) - row_pos = self.xls_write_row( - ws, row_pos, row_data, row_style=self.rt_cell_style_right) + row_pos = self._write_line( + ws, row_pos, ws_params, col_specs_section='totals', + render_space={ + 'debit_formula': debit_formula, + 'credit_formula': credit_formula, + 'bal_formula': bal_formula, + }, + default_format=self.format_theader_yellow_left) + -move_line_xls('report.move.line.list.xls', - 'account.move.line', - parser=move_line_xls_parser) +MoveLineXlsx('report.move.line.list.xls', + 'account.move.line', + parser=report_sxw.rml_parse) diff --git a/account_move_line_report_xls/report/move_line_list_xls.xml b/account_move_line_report_xls/report/move_line_list_xls.xml index fcd4f00a..3b9c8e64 100644 --- a/account_move_line_report_xls/report/move_line_list_xls.xml +++ b/account_move_line_report_xls/report/move_line_list_xls.xml @@ -1,22 +1,20 @@ - - + - - Export Selected Lines - account.move.line - ir.actions.report.xml - move.line.list.xls - xls - - + + Export Selected Lines + account.move.line + ir.actions.report.xml + move.line.list.xls + xlsx + + - - Export Selected Lines - client_action_multi - - account.move.line - - - - + + Export Selected Lines + client_action_multi + + account.move.line + + + diff --git a/account_move_line_report_xls/static/description/index.html b/account_move_line_report_xls/static/description/index.html index a0fcca0a..ed6e2b8e 100644 --- a/account_move_line_report_xls/static/description/index.html +++ b/account_move_line_report_xls/static/description/index.html @@ -38,25 +38,26 @@ The Excel export can be tailored to your exact needs via the following methods of the 'account.move.line' object:
  • - _report_xls_fields + _report_xlsx_fields
    Add/drop columns or change order from the list of columns that are defined in the Excel template.
    The following fields are available:
    - move, name, date, journal, period, partner, account, + move, name, date, journal, partner, account,
    date_maturity, debit, credit, balance,
    - reconcile, reconcile_partial, analytic_account, + reconcile, analytic_account,
    - ref, partner_ref, tax_code, tax_amount, amount_residual, + ref, partner_ref, amount_residual,
    amount_currency, currency_name, company_currency,
    amount_residual_currency, product, product_ref', product_uom, quantity, -
    statement, invoice, narration, blocked +
    + statement, invoice, narration, blocked
    @@ -66,7 +67,7 @@

    • - _report_xls_template + _report_xlsx_template
      Change/extend the Excel template.
      @@ -77,32 +78,6 @@ -
      -
      -

      Credits

      -
      -

      - Author: -

      -

      -
      -
      -

      - Contributors: -

      -

      -
      -
      -
      -
      diff --git a/account_move_line_report_xls/tests/__init__.py b/account_move_line_report_xls/tests/__init__.py new file mode 100644 index 00000000..19415be6 --- /dev/null +++ b/account_move_line_report_xls/tests/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +from . import test_aml_report_xlsx diff --git a/account_move_line_report_xls/tests/test_aml_report_xlsx.py b/account_move_line_report_xls/tests/test_aml_report_xlsx.py new file mode 100644 index 00000000..3549bdde --- /dev/null +++ b/account_move_line_report_xls/tests/test_aml_report_xlsx.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Copyright 2009-2018 Noviat. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.tests.common import TransactionCase + + +class TestAmlReportXlsx(TransactionCase): + + def setUp(self): + super(TestAmlReportXlsx, self).setUp() + ctx = {'xlsx_export': True} + self.report = self.env['ir.actions.report.xml'].with_context(ctx) + self.report_name = 'move.line.list.xls' + inv = self.env.ref('l10n_generic_coa.demo_invoice_1') + self.amls = inv.move_id.line_ids + + def test_aml_report_xlsx(self): + report_xls = self.report.render_report( + self.amls.ids, self.report_name, {}) + self.assertEqual(report_xls[1], 'xlsx')