Skip to content
Extraits de code Groupes Projets
main.py 6,25 ko
Newer Older
  • Learn to ignore specific revisions
  • Thibaud - Le Filament's avatar
    Thibaud - Le Filament a validé
    # 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)
    
    Thibaud - Le Filament's avatar
    Thibaud - Le Filament a validé
            lines_to_export = []
    
            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[:]
    
    Thibaud - Le Filament's avatar
    Thibaud - Le Filament a validé
                row = []
    
                for key,field in enumerate(export_id.fields_ids):
    
    Thibaud - Le Filament's avatar
    Thibaud - Le Filament a validé
                    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)
    
    Thibaud - Le Filament's avatar
    Thibaud - Le Filament a validé
                    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)])
    
    Thibaud - Le Filament's avatar
    Thibaud - Le Filament a validé
    
            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)