forked from Vauxoo/queue
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdelay_export.py
140 lines (117 loc) · 4.81 KB
/
delay_export.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# Copyright 2019 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import base64
import json
import logging
import operator
from dateutil.relativedelta import relativedelta
from odoo import _, api, fields, models
from odoo.addons.queue_job.job import job
from odoo.addons.web.controllers.main import CSVExport, ExcelExport
from odoo.exceptions import UserError
_logger = logging.getLogger(__name__)
class DelayExport(models.Model):
_name = "delay.export"
_description = "Allow to delay the export"
user_id = fields.Many2one("res.users", string="User", index=True)
@api.model
def delay_export(self, data):
params = json.loads(data.get("data"))
if not self.env.user.email:
raise UserError(_("You must set an email address to your user."))
self.with_delay().export(params)
@api.model
def _get_file_content(self, params):
export_format = params.get("format")
raw_data = export_format != "csv"
item_names = ("model", "fields", "ids", "domain", "import_compat", "context")
items = operator.itemgetter(item_names)(params)
model_name, fields_name, ids, domain, import_compat, context = items
user = self.env["res.users"].browse([context.get("uid")])
if not user or not user.email:
raise UserError(_("The user doesn't have an email address."))
model = self.env[model_name].with_context(
import_compat=import_compat, **context
)
records = model.browse(ids) or model.search(
domain, offset=0, limit=False, order=False
)
if not model._is_an_ordinary_table():
fields_name = [field for field in fields_name if field["name"] != "id"]
field_names = [f["name"] for f in fields_name]
import_data = records.export_data(field_names, raw_data).get("datas", [])
if import_compat:
columns_headers = field_names
else:
columns_headers = [val["label"].strip() for val in fields_name]
if export_format == "csv":
csv = CSVExport()
return csv.from_data(columns_headers, import_data)
else:
xls = ExcelExport()
return xls.from_data(columns_headers, import_data)
@api.model
@job
def export(self, params):
content = self._get_file_content(params)
model_name, context, export_format = operator.itemgetter(
"model", "context", "format"
)(params)
user = self.env["res.users"].browse([context.get("uid")])
export_record = self.sudo().create({"user_id": user.id})
name = "{}.{}".format(model_name, export_format)
attachment = self.env["ir.attachment"].create(
{
"name": name,
"datas": base64.b64encode(content),
"datas_fname": name,
"type": "binary",
"res_model": self._name,
"res_id": export_record.id,
}
)
url = "{}/web/content/ir.attachment/{}/datas/{}?download=true".format(
self.env["ir.config_parameter"].sudo().get_param("web.base.url"),
attachment.id,
attachment.name,
)
time_to_live = (
self.env["ir.config_parameter"].sudo().get_param("attachment.ttl", 7)
)
date_today = fields.Date.today()
expiration_date = fields.Date.to_string(
date_today + relativedelta(days=+int(time_to_live))
)
# TODO : move to email template
odoo_bot = self.sudo().env.ref("base.partner_root")
email_from = odoo_bot.email
model_description = self.env[model_name]._description
self.env["mail.mail"].create(
{
"email_from": email_from,
"reply_to": email_from,
"email_to": user.email,
"subject": _("Export {} {}").format(
model_description, fields.Date.to_string(fields.Date.today())
),
"body_html": _(
"""
<p>Your export is available <a href="{}">here</a>.</p>
<p>It will be automatically deleted the {}.</p>
<p> </p>
<p><span style="color: #808080;">
This is an automated message please do not reply.
</span></p>
"""
).format(url, expiration_date),
"auto_delete": True,
}
)
@api.model
def cron_delete(self):
time_to_live = (
self.env["ir.config_parameter"].sudo().get_param("attachment.ttl", 7)
)
date_today = fields.Date.today()
date_to_delete = date_today + relativedelta(days=-int(time_to_live))
self.search([("create_date", "<=", date_to_delete)]).unlink()