Newer
Older
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
# Copyright 2020-2022 Le Filament (<https://le-filament.com>)
# License AGPL-3 or later (http://www.gnu.org/licenses/agpl.html).
import csv
from datetime import date, datetime
from io import BytesIO, StringIO
from odoo import http
from odoo.http import request
from odoo.tools.misc import xlwt
from odoo.tools.safe_eval import safe_eval
from odoo.addons.web.controllers.main import content_disposition, serialize_exception
class JournalDatasExport(http.Controller):
# ------------------------------------------------------
# Routes
# ------------------------------------------------------
@http.route("/web/export_journal/", type="http", auth="user")
@serialize_exception
def export_journal(
self, export_format, export, export_type, date_start, date_end, **kwargs
):
"""
Sélectionne les account.move.line correspondants aux journaux
et à la plage de date définis
Crée le lignes de valeurs
:param export_format: xls/csv
:param export: id export.journal.type
:param export_type: empty (not already exported lines) / all
:param date_start: date
:param date_end: date
:return: file
"""
export_id = request.env["export.journal.type"].browse(int(export))
domain = [
("date", ">=", date_start),
("date", "<=", date_end),
("journal_id", "in", export_id.journal_ids.ids),
("company_id", "=", export_id.company_id.id),
]
if export_type == "empty":
domain += [("date_export", "=", False)]
if export_id.export_domain:
domain += safe_eval(export_id.export_domain)
export_line_ids = request.env["account.move.line"].search(domain)
# FIXME: Crappy could refactor to [[]] or {} to group by invoice name as key
export_line_grouped_by_invoice = export_line_ids.sorted(lambda l: l.move_id.name)
initial_sum_line = ['' for _ in range(len(export_id.fields_ids))]
sum_line = initial_sum_line[:]
big_sum_line = None
previous_invoice_name = export_line_grouped_by_invoice[0].move_id.name
for line in export_line_grouped_by_invoice:
if line.name != previous_invoice_name:
lines_to_export.append(sum_line)
if not big_sum_line:
# Initialise bigsum to the same size and value of the sum_line
# So it has not to be initialized with list of empty string
big_sum_line = sum_line[:]
else:
big_sum_line = [value + sum_line[i] for i,value in enumerate(big_sum_line)]
sum_line = initial_sum_line[:]
for key,field in enumerate(export_id.fields_ids):
if field.is_python:
value = safe_eval(field["field_name"], {"line": line}, mode="eval")
if field.is_sum and value:
if sum_line[key] == '':
sum_line[key] = 0
sum_line[key] += float(value)
else:
value = safe_eval(field["field_name"])
row.append(value)
lines_to_export.append(row)
line.write({"date_export": datetime.now()})
previous_invoice_name = line.name
lines_to_export.append(sum_line)
lines_to_export.append([value + sum_line[i] for i,value in enumerate(big_sum_line)])
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
filename_ = (
export_id.company_id.name.title().replace(" ", "")
+ date_start.replace("-", "")
+ "_"
+ date_end.replace("-", "")
)
if export_format == "csv":
return self.export_csv(export_id, lines_to_export, filename_)
elif export_format == "xls":
return self.export_xls(export_id, lines_to_export, filename_)
# ------------------------------------------------------
# Common function
# ------------------------------------------------------
def export_csv(self, export_id, lines_to_export, filename_):
fp = StringIO()
export_file = csv.writer(
fp, delimiter=export_id.delimiter, quoting=csv.QUOTE_ALL
)
# Add header line
if export_id.is_header:
row = []
for head in export_id.fields_ids.mapped("name"):
row.append(head)
export_file.writerow(row)
for line in lines_to_export:
# Format date value
line_values = [
value
if not isinstance(value, date)
else value.strftime(export_id.csv_datestyle)
for value in line
]
export_file.writerow(line_values)
fp.seek(0)
data = fp.read()
fp.close()
filename = filename_ + ".csv"
csvhttpheaders = [
("Content-Type", "text/csv;charset=utf8"),
("Content-Disposition", content_disposition(filename)),
]
return request.make_response(data, headers=csvhttpheaders)
def export_xls(self, export_id, lines_to_export, filename_):
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet(filename_)
base_style = xlwt.easyxf("align: wrap yes")
date_style = xlwt.XFStyle()
date_style.num_format_str = export_id.xls_datestyle
if export_id.is_header:
for i, fieldname in enumerate(export_id.fields_ids.mapped("name")):
worksheet.write(0, i, fieldname)
worksheet.col(i).width = 4000 # around 220 pixels
for row_index, line in enumerate(lines_to_export):
for cell_index, value in enumerate(line):
cell_style = base_style
if isinstance(value, date):
cell_style = date_style
worksheet.write(row_index + 1, cell_index, value, cell_style)
fp = BytesIO()
workbook.save(fp)
fp.seek(0)
data = fp.read()
fp.close()
filename = filename_ + ".xls"
xlshttpheaders = [
("Content-Type", "text/csv;charset=utf8"),
("Content-Disposition", content_disposition(filename)),
]
return request.make_response(data, headers=xlshttpheaders)