Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[17.0][MIG] report_csv #856

Open
wants to merge 36 commits into
base: 17.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
806bf3c
[ADD] report_csv
etobella Feb 5, 2019
04df914
[IMP] report_csv: use dialects
JordiBForgeFlow Feb 5, 2019
54bfc2d
[IMP] report_csv: allow to evaluate print_report_name for multiple re…
JordiBForgeFlow Feb 7, 2019
f158952
[IMP] report_csv: pass multi variable to be able to distingish which …
LoisRForgeFlow Feb 7, 2019
9738524
[UPD] Update report_csv.pot
oca-travis Feb 22, 2019
4a968d4
[12.0][MIG] report_csv
Jul 2, 2019
8ae1025
[UPD] Update report_csv.pot
oca-travis Nov 22, 2019
9ca400f
[UPD] README.rst
OCA-git-bot Nov 22, 2019
74db2b8
[IMP] report_csv: black, isort
kongrattapong Feb 21, 2020
eba8828
[MIG] report_csv: Migration to 13.0
kongrattapong Feb 21, 2020
962ef7c
[UPD] Update report_csv.pot
oca-travis Mar 2, 2020
13017bf
[UPD] README.rst
OCA-git-bot Mar 2, 2020
024233f
report_csv 13.0.1.0.1
OCA-git-bot Mar 2, 2020
c13b96c
pre-commit update
OCA-git-bot Mar 14, 2020
f6daf47
[FIX] report_py3o: prettier xml after merge with master
lmignon May 12, 2020
e08f259
[FIX] eslint error
lmignon May 13, 2020
61bfd0b
[FIX] make prettier happy
sbidoul May 13, 2020
f81c46b
[IMP] report_csv: black, isort, prettier
tupaq Oct 15, 2020
ecc6a90
[MIG] report_csv: Migration to 14.0
tupaq Oct 15, 2020
5b716d6
[IMP] report_csv : black, isort, prettier
adrienpeiffer Apr 5, 2022
4384269
[MIG] report_csv: Migration to 15.0
adrienpeiffer Apr 5, 2022
b06f04b
[MIG] report_csv: Migration to 16.0
AnizR Nov 8, 2022
ac9eaf4
[UPD] Update report_csv.pot
Mar 20, 2023
7bbce6c
[UPD] README.rst
OCA-git-bot Mar 20, 2023
b0e6722
[FIX] report_csv: Assign 'reportname' variable before accessing it
rousseldenis Jun 26, 2023
15039c1
[FIX] report_csv: Return werkzeug Exception
rousseldenis Jun 27, 2023
87075fe
[IMP] report_csv: Add controller tests
rousseldenis Jun 27, 2023
256e19d
report_csv 16.0.1.0.1
OCA-git-bot Jul 14, 2023
14b3d8a
[UPD] README.rst
OCA-git-bot Sep 3, 2023
67fdae0
[IMP] report_csv: add encoding option
AungKoKoLin1997 Jan 18, 2023
a05ea97
[UPD] Update report_csv.pot
Nov 7, 2023
38f2337
[BOT] post-merge updates
OCA-git-bot Nov 7, 2023
53f6b50
Added translation using Weblate (Italian)
mymage Jan 10, 2024
60d7698
Translated using Weblate (Italian)
mymage Jan 18, 2024
8f2e5c0
[IMP] report_csv: pre-commit auto fixes
pedroguirao Feb 22, 2024
0c7163d
[MIG] report_csv: Migration to 17.0
pedroguirao Feb 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 146 additions & 0 deletions report_csv/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
===============
Base report csv
===============

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:3d970690227b2dd444c5359798ce3ea5be684d6fbc82504e90694e193e738938
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Freporting--engine-lightgray.png?logo=github
:target: https://github.com/OCA/reporting-engine/tree/17.0/report_csv
:alt: OCA/reporting-engine
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/reporting-engine-17-0/reporting-engine-17-0-report_csv
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/reporting-engine&target_branch=17.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module provides a basic report class to generate csv report.

**Table of contents**

.. contents::
:local:

Configuration
=============

In case the exported CSV report should be encoded in another system than
UTF-8, following fields of the report record (*Settings > Technical >
Reports*) should be populated accordingly.

- Encoding: set an encoding system (such as cp932)
- Encode Error Handling: select 'Ignore' or 'Replace' as necessary.

- 'Ignore': in case of an encoding error, the problematic character
will be removed from the exported file.
- 'Replace': in case of an encoding error, the problematic character
will be replaced with '?' symbol.
- Leaving the field blank: in case of an encoding error, the report
generation fails with an error message.

Usage
=====

An example of CSV report for partners on a module called
\`module_name\`:

A python class :

::

from odoo import models

class PartnerCSV(models.AbstractModel):
_name = 'report.report_csv.partner_csv'
_inherit = 'report.report_csv.abstract'

def generate_csv_report(self, writer, data, partners):
writer.writeheader()
for obj in partners:
writer.writerow({
'name': obj.name,
'email': obj.email,
})

def csv_report_options(self):
res = super().csv_report_options()
res['fieldnames'].append('name')
res['fieldnames'].append('email')
res['delimiter'] = ';'
res['quoting'] = csv.QUOTE_ALL
return res

A report XML record :

::

<report
id="partner_csv"
model="res.partner"
string="Print to CSV"
report_type="csv"
name="module_name.report_name"
file="res_partner"
attachment_use="False"
/>

Update encoding with an appropriate value (e.g. cp932) as necessary.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/reporting-engine/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/reporting-engine/issues/new?body=module:%20report_csv%0Aversion:%2017.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* Creu Blanca

Contributors
------------

- Enric Tobella <etobella@creublanca.es>
- Jaime Arroyo <jaime.arroyo@creublanca.es>
- Rattapong Chokmasermkul <rattapongc@ecosoft.co.th>
- `Quartile <https://www.quartile.co>`__:

- Aung Ko Ko Lin

Maintainers
-----------

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

This module is part of the `OCA/reporting-engine <https://github.com/OCA/reporting-engine/tree/17.0/report_csv>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
3 changes: 3 additions & 0 deletions report_csv/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from . import controllers
from . import models
from . import report
20 changes: 20 additions & 0 deletions report_csv/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright 2019 Creu Blanca
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
{
"name": "Base report csv",
"summary": "Base module to create csv report",
"author": "Creu Blanca, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/reporting-engine",
"category": "Reporting",
"version": "17.0.1.0.0",
"license": "AGPL-3",
"depends": ["base", "web"],
"demo": ["demo/report.xml"],
"data": ["views/ir_actions_views.xml"],
"assets": {
"web.assets_backend": [
"report_csv/static/src/js/report/qwebactionmanager.esm.js"
]
},
"installable": True,
}
1 change: 1 addition & 0 deletions report_csv/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import main
108 changes: 108 additions & 0 deletions report_csv/controllers/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Copyright (C) 2019 Creu Blanca
# License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html).

import json
import logging

from werkzeug.exceptions import InternalServerError
from werkzeug.urls import url_decode

from odoo.http import (
content_disposition,
request,
route,
)
from odoo.http import (
serialize_exception as _serialize_exception,
)
from odoo.tools import html_escape
from odoo.tools.safe_eval import safe_eval, time

from odoo.addons.web.controllers import report

_logger = logging.getLogger(__name__)


class ReportController(report.ReportController):
@route()
def report_routes(self, reportname, docids=None, converter=None, **data):
if converter == "csv":
report = request.env["ir.actions.report"]._get_report_from_name(reportname)
context = dict(request.env.context)
if docids:
docids = [int(i) for i in docids.split(",")]
if data.get("options"):
data.update(json.loads(data.pop("options")))

Check warning on line 35 in report_csv/controllers/main.py

View check run for this annotation

Codecov / codecov/patch

report_csv/controllers/main.py#L35

Added line #L35 was not covered by tests
if data.get("context"):
# Ignore 'lang' here, because the context in data is the one
# from the webclient *but* if the user explicitely wants to
# change the lang, this mechanism overwrites it.
data["context"] = json.loads(data["context"])

Check warning on line 40 in report_csv/controllers/main.py

View check run for this annotation

Codecov / codecov/patch

report_csv/controllers/main.py#L40

Added line #L40 was not covered by tests
if data["context"].get("lang"):
del data["context"]["lang"]
context.update(data["context"])

Check warning on line 43 in report_csv/controllers/main.py

View check run for this annotation

Codecov / codecov/patch

report_csv/controllers/main.py#L42-L43

Added lines #L42 - L43 were not covered by tests
csv = report.with_context(**context)._render_csv(
reportname, docids, data=data
)[0]
csvhttpheaders = [
("Content-Type", "text/csv"),
("Content-Length", len(csv)),
]
return request.make_response(csv, headers=csvhttpheaders)
return super().report_routes(reportname, docids, converter, **data)

@route()
def report_download(self, data, context=None):
requestcontent = json.loads(data)
url, report_type = requestcontent[0], requestcontent[1]
reportname = ""
try:
if report_type == "csv":
reportname = url.split("/report/csv/")[1].split("?")[0]
docids = None
if "/" in reportname:
reportname, docids = reportname.split("/")
if docids:
# Generic report:
response = self.report_routes(
reportname, docids=docids, converter="csv", context=context
)
else:
# Particular report:
data = dict(

Check warning on line 72 in report_csv/controllers/main.py

View check run for this annotation

Codecov / codecov/patch

report_csv/controllers/main.py#L72

Added line #L72 was not covered by tests
url_decode(url.split("?")[1]).items()
) # decoding the args represented in JSON
if "context" in data:
context, data_context = (

Check warning on line 76 in report_csv/controllers/main.py

View check run for this annotation

Codecov / codecov/patch

report_csv/controllers/main.py#L76

Added line #L76 was not covered by tests
json.loads(context or "{}"),
json.loads(data.pop("context")),
)
context = json.dumps({**context, **data_context})
response = self.report_routes(

Check warning on line 81 in report_csv/controllers/main.py

View check run for this annotation

Codecov / codecov/patch

report_csv/controllers/main.py#L80-L81

Added lines #L80 - L81 were not covered by tests
reportname, converter="csv", context=context, **data
)

report = request.env["ir.actions.report"]._get_report_from_name(
reportname
)
filename = f"{report.name}.{report_type}"
if docids:
ids = [int(x) for x in docids.split(",")]
obj = request.env[report.model].browse(ids)
if report.print_report_name and not len(obj) > 1:
report_name = safe_eval(

Check warning on line 93 in report_csv/controllers/main.py

View check run for this annotation

Codecov / codecov/patch

report_csv/controllers/main.py#L93

Added line #L93 was not covered by tests
report.print_report_name, {"object": obj, "time": time}
)
filename = f"{report_name}.{report_type}"

Check warning on line 96 in report_csv/controllers/main.py

View check run for this annotation

Codecov / codecov/patch

report_csv/controllers/main.py#L96

Added line #L96 was not covered by tests
response.headers.add(
"Content-Disposition", content_disposition(filename)
)
return response
else:
return super().report_download(data, context)
except Exception as e:
_logger.exception("Error while generating report %s", reportname)
se = _serialize_exception(e)
error = {"code": 200, "message": "Odoo Server Error", "data": se}
res = request.make_response(html_escape(json.dumps(error)))
raise InternalServerError(response=res) from e
14 changes: 14 additions & 0 deletions report_csv/demo/report.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!--
Copyright 2019 Creu Blanca
License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html).
-->
<record id="partner_csv" model="ir.actions.report">
<field name="name">Print to CSV</field>
<field name="model">res.partner</field>
<field name="report_type">csv</field>
<field name="report_name">report_csv.partner_csv</field>
<field name="report_file">res_partner</field>
</record>
</odoo>
101 changes: 101 additions & 0 deletions report_csv/i18n/it.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * report_csv
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2024-01-18 09:34+0000\n"
"Last-Translator: mymage <stefano.consolaro@mymage.it>\n"
"Language-Team: none\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.17\n"

#. module: report_csv
#: model:ir.model,name:report_csv.model_report_report_csv_abstract
msgid "Abstract Model for CSV reports"
msgstr "Modello astratto per resoconto CSV"

#. module: report_csv
#: model:ir.model.fields,field_description:report_csv.field_ir_actions_report__encode_error_handling
msgid "Encode Error Handling"
msgstr "Gestione errore codifica"

#. module: report_csv
#: model:ir.model.fields,field_description:report_csv.field_ir_actions_report__encoding
msgid "Encoding"
msgstr "Codifica"

#. module: report_csv
#: model:ir.model.fields,help:report_csv.field_ir_actions_report__encoding
msgid "Encoding to be applied to the generated CSV file. e.g. cp932"
msgstr "Codifica da applicare al file CSV generato. Es. cp932"

#. module: report_csv
#. odoo-python
#: code:addons/report_csv/report/report_csv.py:0
#, python-format
msgid "Failed to encode the data with the encoding set in the report."
msgstr "Codifica dati fallita con la codifica impostata nel resoconto."

#. module: report_csv
#: model:ir.model.fields,help:report_csv.field_ir_actions_report__encode_error_handling
msgid ""
"If nothing is selected, CSV export will fail with an error message when "
"there is a character that fail to be encoded."
msgstr ""
"Se non è selezionato nulla, l'esportazione del CSV fallirà con un messaggio "
"di errore qando c'è un carattere che non può essere codificato."

#. module: report_csv
#: model:ir.model.fields.selection,name:report_csv.selection__ir_actions_report__encode_error_handling__ignore
msgid "Ignore"
msgstr "Ignora"

#. module: report_csv
#: model:ir.actions.report,name:report_csv.partner_csv
msgid "Print to CSV"
msgstr "Stampa su CSV"

#. module: report_csv
#: model:ir.model.fields.selection,name:report_csv.selection__ir_actions_report__encode_error_handling__replace
msgid "Replace"
msgstr "Sostituzione"

#. module: report_csv
#: model:ir.model,name:report_csv.model_ir_actions_report
msgid "Report Action"
msgstr "Azione resoconto"

#. module: report_csv
#: model:ir.model,name:report_csv.model_report_report_csv_partner_csv
msgid "Report Partner to CSV"
msgstr "Indica il partner al CSV"

#. module: report_csv
#: model:ir.model.fields,field_description:report_csv.field_ir_actions_report__report_type
msgid "Report Type"
msgstr "Tipo resoconto"

#. module: report_csv
#: model:ir.model.fields,help:report_csv.field_ir_actions_report__report_type
msgid ""
"The type of the report that will be rendered, each one having its own "
"rendering method. HTML means the report will be opened directly in your "
"browser PDF means the report will be rendered using Wkhtmltopdf and "
"downloaded by the user."
msgstr ""
"Il tipo di resoconto che verrà generato, ognuno avente il suo metodo di "
"generazione. HTML vuol dire che il resoconto sarà aperto direttamente nel "
"tuo browser mentre PDF vuol dire che il resoconto sarà generato usando "
"Wkhtmltopdf e scaricato dall'utente."

#. module: report_csv
#: model:ir.model.fields.selection,name:report_csv.selection__ir_actions_report__report_type__csv
msgid "csv"
msgstr "csv"
Loading
Loading