Skip to content

Commit 4f73e1b

Browse files
[MIG] base_export_async: Migration to 17.0
1 parent 3faab6c commit 4f73e1b

19 files changed

Lines changed: 278 additions & 74 deletions

base_export_async/README.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,15 @@ Contributors
6868

6969
- Arnaud Pineux (ACSONE SA/NV) authored the initial prototype.
7070
- Guewen Baconnier (Camptocamp)
71+
- Stéphane Mangin (ACSONE SA/NV)
72+
73+
Other credits
74+
-------------
75+
76+
The migration of this module from 16.0 to 17.0 was financially supported
77+
by:
78+
79+
- ACSONE SA/NV (https://www.acsone.eu/)
7180

7281
Maintainers
7382
-----------

base_export_async/__manifest__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
{
55
"name": "Base Export Async",
66
"summary": "Asynchronous export with job queue",
7-
"version": "16.0.1.2.0",
7+
"version": "17.0.1.0.0",
88
"license": "AGPL-3",
99
"author": "ACSONE SA/NV, Odoo Community Association (OCA)",
1010
"website": "https://github.com/OCA/queue",
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="utf-8" ?>
22
<odoo noupdate="1">
3-
<record id="attachment_ttl" model="ir.config_parameter">
4-
<field name="key">attachment.ttl</field>
5-
<field name="value">7</field>
6-
</record>
3+
<record id="attachment_ttl" model="ir.config_parameter">
4+
<field name="key">attachment.ttl</field>
5+
<field name="value">7</field>
6+
</record>
77
</odoo>

base_export_async/data/cron.xml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
<?xml version="1.0" encoding="utf-8" ?>
22
<odoo>
3-
<record id="to_delete_attachment" model="ir.cron">
4-
<field name="name">Delete Generated Exports</field>
5-
<field name="model_id" ref="model_delay_export" />
6-
<field name="state">code</field>
7-
<field name="code">model.cron_delete()</field>
8-
<field name='interval_number'>1</field>
9-
<field name='interval_type'>days</field>
10-
<field name="numbercall">-1</field>
11-
</record>
3+
<record id="to_delete_attachment" model="ir.cron">
4+
<field name="name">Delete Generated Exports</field>
5+
<field name="model_id" ref="model_delay_export" />
6+
<field name="state">code</field>
7+
<field name="code">model.cron_delete()</field>
8+
<field name='interval_number'>1</field>
9+
<field name='interval_type'>days</field>
10+
<field name="numbercall">-1</field>
11+
</record>
1212
</odoo>
Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,24 @@
11
<?xml version="1.0" encoding="utf-8" ?>
22
<odoo noupdate="1">
3-
<record id="delay_export_mail_template" model="mail.template">
4-
<field name="name">Delay Export</field>
5-
<field
3+
<record id="delay_export_mail_template" model="mail.template">
4+
<field name="name">Delay Export</field>
5+
<field
66
name="subject"
77
>Export {{ object.model_description }} {{ datetime.date.today() }}</field>
8-
<field name="model_id" ref="base_export_async.model_delay_export" />
9-
<field name="auto_delete" eval="True" />
10-
<field name="body_html" type="html">
11-
<p>Your export is available <a
8+
<field name="model_id" ref="base_export_async.model_delay_export" />
9+
<field name="auto_delete" eval="True" />
10+
<field name="body_html" type="html">
11+
<p>Your export is available <a
1212
t-attf-href="{{ object.url }}"
1313
target="_blank"
1414
>here</a>.</p>
15-
<p>It will be automatically deleted the <t
16-
t-out="object.expiration_date"
17-
/>.</p>
18-
<br />
19-
<p>
20-
<span
15+
<p>It will be automatically deleted the <t t-out="object.expiration_date" />.</p>
16+
<br />
17+
<p>
18+
<span
2119
style="color: #808080;"
2220
>This is an automated message please do not reply.</span>
23-
</p>
24-
</field>
25-
</record>
21+
</p>
22+
</field>
23+
</record>
2624
</odoo>

base_export_async/export.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Copyright 2026 ACSONE SA/NV
2+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
3+
4+
import io
5+
6+
from odoo.exceptions import UserError
7+
from odoo.tools.misc import xlsxwriter
8+
from odoo.tools.translate import _
9+
10+
from odoo.addons.web.controllers.export import ExportFormat, ExportXlsxWriter
11+
12+
13+
class CleanedExportXlsxWriter(ExportXlsxWriter):
14+
def __init__(self, field_names, row_count=0, decimal_places=None):
15+
self.field_names = field_names
16+
self.output = io.BytesIO()
17+
self.workbook = xlsxwriter.Workbook(self.output, {"in_memory": True})
18+
self.base_style = self.workbook.add_format({"text_wrap": True})
19+
self.header_style = self.workbook.add_format({"bold": True})
20+
self.header_bold_style = self.workbook.add_format(
21+
{"text_wrap": True, "bold": True, "bg_color": "#e9ecef"}
22+
)
23+
self.date_style = self.workbook.add_format(
24+
{"text_wrap": True, "num_format": "yyyy-mm-dd"}
25+
)
26+
self.datetime_style = self.workbook.add_format(
27+
{"text_wrap": True, "num_format": "yyyy-mm-dd hh:mm:ss"}
28+
)
29+
self.worksheet = self.workbook.add_worksheet()
30+
self.value = False
31+
self.float_format = "#,##0.00"
32+
self.monetary_format = f'#,##0.{max(decimal_places or [2]) * "0"}'
33+
34+
if row_count > self.worksheet.xls_rowmax:
35+
raise UserError(
36+
_(
37+
f"There are too many rows ({row_count} rows, limit:"
38+
f" {self.worksheet.xls_rowmax}) to export as Excel"
39+
f"2007-2013 (.xlsx) format. Consider splitting the export."
40+
)
41+
)
42+
43+
44+
class ExcelExport(ExportFormat):
45+
def __init__(self, env):
46+
self.env = env
47+
48+
@property
49+
def content_type(self):
50+
return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
51+
52+
@property
53+
def extension(self):
54+
return ".xlsx"
55+
56+
def from_data(self, fields, rows):
57+
decimal_places = [
58+
res["decimal_places"]
59+
for res in self.env["res.currency"].search_read([], ["decimal_places"])
60+
]
61+
with CleanedExportXlsxWriter(fields, len(rows), decimal_places) as xlsx_writer:
62+
for row_index, row in enumerate(rows):
63+
for cell_index, cell_value in enumerate(row):
64+
xlsx_writer.write_cell(row_index + 1, cell_index, cell_value)
65+
66+
return xlsx_writer.value

base_export_async/models/delay_export.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
from odoo import _, api, fields, models
1111
from odoo.exceptions import UserError
1212

13-
from odoo.addons.web.controllers.export import CSVExport, ExcelExport
13+
from odoo.addons.web.controllers.export import CSVExport
14+
15+
from ..export import ExcelExport
1416

1517

1618
class DelayExport(models.Model):
@@ -61,7 +63,7 @@ def _get_file_content(self, params):
6163
csv = CSVExport()
6264
return csv.from_data(columns_headers, import_data)
6365
else:
64-
xls = ExcelExport()
66+
xls = ExcelExport(self.env)
6567
return xls.from_data(columns_headers, import_data)
6668

6769
@api.model
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
- Arnaud Pineux (ACSONE SA/NV) authored the initial prototype.
22
- Guewen Baconnier (Camptocamp)
3+
- Stéphane Mangin (ACSONE SA/NV)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
The migration of this module from 16.0 to 17.0 was financially supported by:
2+
3+
- ACSONE SA/NV (<https://www.acsone.eu/>)
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
Standard Export can be delayed in asynchronous jobs executed in the
2-
background and then send by email to the user.
1+
Standard Export can be delayed in asynchronous jobs executed in the background and then
2+
send by email to the user.

0 commit comments

Comments
 (0)