Skip to content

Commit 5ac9764

Browse files
committed
Merge PR #3207 into 18.0
Signed-off-by thomaspaulb
2 parents 6f6db79 + c4b3e5f commit 5ac9764

40 files changed

Lines changed: 10239 additions & 0 deletions

excel_import_export/README.rst

Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
==========================
2+
Excel Import/Export/Report
3+
==========================
4+
5+
..
6+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
7+
!! This file is generated by oca-gen-addon-readme !!
8+
!! changes will be overwritten. !!
9+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
10+
!! source digest: sha256:40c58b91ccaaaa2b5ead94e8975df9d77a9ae3d08e29f5647422c2a3e1dafd6b
11+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
12+
13+
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
14+
:target: https://odoo-community.org/page/development-status
15+
:alt: Beta
16+
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
17+
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
18+
:alt: License: AGPL-3
19+
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github
20+
:target: https://github.com/OCA/server-tools/tree/18.0/excel_import_export
21+
:alt: OCA/server-tools
22+
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
23+
:target: https://translation.odoo-community.org/projects/server-tools-18-0/server-tools-18-0-excel_import_export
24+
:alt: Translate me on Weblate
25+
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
26+
:target: https://runboat.odoo-community.org/builds?repo=OCA/server-tools&target_branch=18.0
27+
:alt: Try me on Runboat
28+
29+
|badge1| |badge2| |badge3| |badge4| |badge5|
30+
31+
The module provide pre-built functions and wizards for developer to
32+
build excel import / export / report with ease.
33+
34+
Without having to code to create excel file, developer do,
35+
36+
- Create menu, action, wizard, model, view a normal Odoo development.
37+
- Design excel template using standard Excel application, e.g., colors,
38+
fonts, formulas, etc.
39+
- Instruct how the data will be located in Excel with simple dictionary
40+
instruction or from Odoo UI.
41+
- Odoo will combine instruction with excel template, and result in
42+
final excel file.
43+
44+
**Table of contents**
45+
46+
.. contents::
47+
:local:
48+
49+
Installation
50+
============
51+
52+
To install this module, you need to install following python library,
53+
**xlrd, xlwt, openpyxl**.
54+
55+
Then, simply install **excel_import_export**.
56+
57+
For demo, install **excel_import_export_demo**
58+
59+
Configuration
60+
=============
61+
62+
If you have existing templates from the version 16.0.1.2.0 or earlier,
63+
you need to click 'REMOVE EXPORT ACTION' and then click 'ADD EXPORT
64+
ACTION' in these templates for export actions to work as expected.
65+
66+
Usage
67+
=====
68+
69+
Concepts
70+
--------
71+
72+
This module contain pre-defined function and wizards to make exporting,
73+
importing and reporting easy.
74+
75+
At the heart of this module, there are 2 main methods
76+
77+
- ``self.env['xlsx.export'].export_xlsx(...)``
78+
- ``self.env['xlsx.import'].import_xlsx(...)``
79+
80+
For reporting, also call export_xlsx(...) but through following method
81+
82+
- ``self.env['xslx.report'].report_xlsx(...)``
83+
84+
After install this module, go to Settings > Technical > Excel
85+
Import/Export > XLSX Templates, this is where the key component located.
86+
87+
As this module provide tools, it is best to explain as use cases. For
88+
example use cases, please install **excel_import_export_demo**
89+
90+
Use Cases
91+
---------
92+
93+
**Use Case 1:** Export/Import Excel on existing document
94+
95+
This add export/import action menus in existing document (example -
96+
excel_import_export_demo/import_export_sale_order)
97+
98+
1. Create export action menu on document, <act_window> with
99+
res_model="export.xlsx.wizard" and src_model="<document_model>", and
100+
context['template_domain'] to locate the right template --
101+
actions.xml
102+
2. Create import action menu on document, <act_window> with
103+
res_model="import.xlsx.wizard" and src_model="<document_model>", and
104+
context['template_domain'] to locate the right template -- action.xml
105+
3. Create/Design Excel Template File (.xlsx), in the template, name the
106+
underlining tab used for export/import -- <file>.xlsx
107+
4. Create instruction dictionary for export/import in xlsx.template
108+
model -- templates.xml
109+
110+
**Use Case 2:** Import Excel Files
111+
112+
With menu wizard to create new documents (example -
113+
excel_import_export_demo/import_sale_orders)
114+
115+
1. Create report menu with search wizard, res_model="import.xlsx.wizard"
116+
and context['template_domain'] to locate the right template --
117+
menu_action.xml
118+
2. Create Excel Template File (.xlsx), in the template, name the
119+
underlining tab used for import -- <import file>.xlsx
120+
3. Create instruction dictionary for import in xlsx.template model --
121+
templates.xml
122+
123+
**Use Case 3:** Create Excel Report
124+
125+
This create report menu with criteria wizard. (example -
126+
excel_import_export_demo/report_sale_order)
127+
128+
1. Create report's menu, action, and add context['template_domain'] to
129+
locate the right template for this report -- <report>.xml
130+
2. Create report's wizard for search criteria. The view inherits
131+
``excel_import_export.xlsx_report_view`` and mode="primary". In this
132+
view, you only need to add criteria fields, the rest will reuse from
133+
interited view -- <report.xml>
134+
3. Create report model as models.Transient, then define search criteria
135+
fields, and get reporing data into ``results`` field -- <report>.py
136+
4. Create/Design Excel Template File (.xlsx), in the template, name the
137+
underlining tab used for report results -- <report_file>.xlsx
138+
5. Create instruction dictionary for report in xlsx.template model --
139+
templates.xml
140+
141+
**Note:**
142+
143+
Another option for reporting is to use report action
144+
(report_type='excel'), I.e.,
145+
146+
.. code:: xml
147+
148+
<record id="action_report_saleorder_excel" model="ir.actions.report">
149+
<field name="name">Quotation / Order (.xlsx)</field>
150+
<field name="model">ir.model</field>
151+
<field name="report_name">'sale.order'</field>
152+
<field name="report_file">'sale.order'</field>
153+
<field name="binding_model_id" ref="sale.model_sale_order"/>
154+
<field name="binding_type">report</field>
155+
<field name="report_type">excel</field>
156+
</record>
157+
158+
By using report action, Odoo will find template using combination of
159+
model and name, then do the export for the underlining record. Please
160+
see example in excel_import_export_demo/report_action, which shows,
161+
162+
1. Print excel from an active sale.order
163+
2. Run partner list report based on search criteria.
164+
165+
Easy Reporting Option
166+
---------------------
167+
168+
Technically, this option is the same as "Create Excel Report" use case.
169+
But instead of having to write XML / Python code like normally do, this
170+
option allow user to create a report based on a model or view, all by
171+
configuration only.
172+
173+
1. Go to Settings > Technical> Excel Import/Export > XLSX Templates, and
174+
create a new template for a report.
175+
2. On the new template, select "Easy Reporting" option, then select
176+
followings
177+
178+
- Report Model, this can be data model or data view we want to get
179+
the results from.
180+
- Click upload your file and add the excel template (.xlsx)
181+
- Click Save, system will create sample export line, user can add
182+
more fields according to results model.
183+
184+
3. Click Add Report Menu, the report menu will be created, user can
185+
change its location. Now the report is ready to use.
186+
187+
..
188+
189+
|image1|
190+
191+
Note: Using easy reporting mode, system will used a common criteria
192+
wizard.
193+
194+
|image2|
195+
196+
.. |image1| image:: https://raw.githubusercontent.com/OCA/server-tools/18.0/excel_import_export/static/description/xlsx_template.png
197+
.. |image2| image:: https://raw.githubusercontent.com/OCA/server-tools/18.0/excel_import_export/static/description/common_wizard.png
198+
199+
Known issues / Roadmap
200+
======================
201+
202+
- Module extension e.g., excel_import_export_async, that add ability to
203+
execute as async process.
204+
205+
Bug Tracker
206+
===========
207+
208+
Bugs are tracked on `GitHub Issues <https://github.com/OCA/server-tools/issues>`_.
209+
In case of trouble, please check there if your issue has already been reported.
210+
If you spotted it first, help us to smash it by providing a detailed and welcomed
211+
`feedback <https://github.com/OCA/server-tools/issues/new?body=module:%20excel_import_export%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
212+
213+
Do not contact contributors directly about support or help with technical issues.
214+
215+
Credits
216+
=======
217+
218+
Authors
219+
-------
220+
221+
* Ecosoft
222+
223+
Contributors
224+
------------
225+
226+
- Kitti Upariphutthiphong. <kittiu@gmail.com> (http://ecosoft.co.th)
227+
- Saran Lim. <saranl@ecosoft.co.th> (http://ecosoft.co.th)
228+
- Do Anh Duy <duyda@trobz.com>
229+
230+
Maintainers
231+
-----------
232+
233+
This module is maintained by the OCA.
234+
235+
.. image:: https://odoo-community.org/logo.png
236+
:alt: Odoo Community Association
237+
:target: https://odoo-community.org
238+
239+
OCA, or the Odoo Community Association, is a nonprofit organization whose
240+
mission is to support the collaborative development of Odoo features and
241+
promote its widespread use.
242+
243+
.. |maintainer-kittiu| image:: https://github.com/kittiu.png?size=40px
244+
:target: https://github.com/kittiu
245+
:alt: kittiu
246+
247+
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
248+
249+
|maintainer-kittiu|
250+
251+
This module is part of the `OCA/server-tools <https://github.com/OCA/server-tools/tree/18.0/excel_import_export>`_ project on GitHub.
252+
253+
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

excel_import_export/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/)
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
3+
4+
from . import wizard
5+
from . import models
6+
from . import controllers
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/)
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
3+
4+
{
5+
"name": "Excel Import/Export/Report",
6+
"summary": "Base module for developing Excel import/export/report",
7+
"version": "18.0.1.0.0",
8+
"author": "Ecosoft,Odoo Community Association (OCA)",
9+
"license": "AGPL-3",
10+
"website": "https://github.com/OCA/server-tools",
11+
"category": "Tools",
12+
"depends": ["mail"],
13+
"external_dependencies": {"python": ["openpyxl"]},
14+
"data": [
15+
"security/ir.model.access.csv",
16+
"wizard/export_xlsx_wizard.xml",
17+
"wizard/import_xlsx_wizard.xml",
18+
"wizard/report_xlsx_wizard.xml",
19+
"views/xlsx_template_view.xml",
20+
"views/xlsx_report.xml",
21+
],
22+
"installable": True,
23+
"development_status": "Beta",
24+
"maintainers": ["kittiu"],
25+
"assets": {
26+
"web.assets_backend": [
27+
"/excel_import_export/static/src/js/report/action_manager_report.esm.js"
28+
]
29+
},
30+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/)
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
3+
4+
from . import report
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/)
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
3+
4+
import base64
5+
import json
6+
import logging
7+
8+
from werkzeug.urls import url_decode
9+
10+
from odoo import http
11+
from odoo.http import content_disposition, request, route, serialize_exception
12+
from odoo.tools import html_escape
13+
from odoo.tools.safe_eval import safe_eval, time
14+
15+
from odoo.addons.web.controllers.report import ReportController
16+
17+
_logger = logging.getLogger(__name__)
18+
19+
20+
class ReportExcelController(ReportController):
21+
@route()
22+
def report_routes(self, reportname, docids=None, converter=None, **data):
23+
if converter == "excel":
24+
report = request.env["ir.actions.report"]._get_report_from_name(reportname)
25+
context = dict(request.env.context)
26+
if docids:
27+
docids = [int(i) for i in docids.split(",") if i.isdigit()]
28+
if data.get("options"):
29+
data.update(json.loads(data.pop("options")))
30+
if data.get("context"):
31+
# Ignore 'lang' here, because the context in data is the one
32+
# from the webclient *but* if the user explicitely wants to
33+
# change the lang, this mechanism overwrites it.
34+
data["context"] = json.loads(data["context"])
35+
context.update(data["context"])
36+
excel, report_name = report.with_context(**context)._render_excel(
37+
docids, data=data
38+
)
39+
excel = base64.decodebytes(excel)
40+
if docids:
41+
records = request.env[report.model].browse(docids)
42+
if report.print_report_name and not len(records) > 1:
43+
# this is a bad idea, this should only be .xlsx
44+
extension = report_name.split(".")[-1:].pop()
45+
report_name = safe_eval(
46+
report.print_report_name, {"object": records, "time": time}
47+
)
48+
report_name = f"{report_name}.{extension}"
49+
excelhttpheaders = [
50+
(
51+
"Content-Type",
52+
"application/vnd.openxmlformats-"
53+
"officedocument.spreadsheetml.sheet",
54+
),
55+
("Content-Length", len(excel)),
56+
("Content-Disposition", content_disposition(report_name)),
57+
]
58+
return request.make_response(excel, headers=excelhttpheaders)
59+
return super().report_routes(reportname, docids, converter, **data)
60+
61+
@http.route()
62+
def report_download(self, data, context=None):
63+
requestcontent = json.loads(data)
64+
url, report_type = requestcontent[0], requestcontent[1]
65+
if report_type != "excel":
66+
return super().report_download(data, context)
67+
reportname = "???"
68+
try:
69+
pattern = "/report/excel/"
70+
reportname = url.split(pattern)[1].split("?")[0]
71+
docids = None
72+
if "/" in reportname:
73+
reportname, docids = reportname.split("/")
74+
if docids:
75+
return self.report_routes(
76+
reportname, docids=docids, converter="excel", context=context
77+
)
78+
data = dict(url_decode(url.split("?")[1]).items())
79+
if "context" in data:
80+
context, data_context = (
81+
json.loads(context or "{}"),
82+
json.loads(data.pop("context")),
83+
)
84+
context = json.dumps({**context, **data_context})
85+
return self.report_routes(
86+
reportname, converter="excel", context=context, **data
87+
)
88+
except Exception as e:
89+
_logger.exception("Error while generating report %s", reportname)
90+
se = serialize_exception(e)
91+
error = {"code": 200, "message": "Odoo Server Error", "data": se}
92+
return request.make_response(html_escape(json.dumps(error)))

0 commit comments

Comments
 (0)