# Copyright 2019 Le Filament (<http://www.le-filament.com>) # License AGPL-3 or later (http://www.gnu.org/licenses/agpl.html). import csv import re from datetime import datetime from io import BytesIO, StringIO from odoo import models, fields, api, http from odoo.addons.web.controllers.main import serialize_exception from odoo.addons.web.controllers.main import content_disposition from odoo.fields import Date from odoo.http import request from odoo.tools import pycompat from odoo.tools.misc import xlwt HEADER_DEFAULT = [ 'date', 'journal', 'compte', 'debit', 'credit', 'libelle', 'piece', 'echeance', 'ref_piece' ] HEADER_DEFAULT_CEGID = [ 'journal', 'date', 'compte', 'auxiliaire', 'ref_piece', 'libelle', 'debit', 'credit', ] HEADER_DEFAULT_CEGID_FILE = [ 'Journal', 'Date', 'Général', 'Auxiliaire', 'Référence', 'Libellé', 'Débit', 'Crédit', ] class AccountDatasExportWizard(models.TransientModel): _name = "invoice.line.export" date_start = fields.Date('Date de début', required=True) date_end = fields.Date('Date de fin', required=True, default=datetime.today().strftime('%Y-%m-%d')) export_format = fields.Selection([('csv', 'CSV'), ('xls', 'Excel')], 'Format', default="csv") journal = fields.Selection([('ventes', 'Ventes'), ('achats', 'Achats')], 'Journal', default='ventes') @api.multi def get_data_file(self): nom_outil_compta = self.env['ir.config_parameter'].sudo().get_param( 'account.nom_outil_compta') return { 'type': 'ir.actions.act_url', 'url': '/web/export_journal?format=%s&journal=%s&nom_outil_compta=%s' % (self.export_format, self.journal, nom_outil_compta) + '&date_start=%s&date_end=%s' % (self.date_start, self.date_end), 'target': 'new', } class AccountDatasExport(http.Controller): def export_csv(self, lignes_export, columns, filename_, nom_outil_compta): fp = StringIO() export_file = csv.writer(fp, delimiter=';', quoting=csv.QUOTE_ALL) row = [] # Add header line only if outil = cegid if nom_outil_compta == 'cegid': header_file = HEADER_DEFAULT_CEGID_FILE for head in header_file: row.append(head) export_file.writerow(row) for line in lignes_export: row = [] for column in columns: if isinstance(line[column], str): try: value = line[column] except UnicodeError: pass else: if ((column == 'date') or (column == 'echeance') and line[column]): value = Date.to_date(line[column]).strftime('%d/%m/%Y') elif (column == 'credit') or (column == 'debit'): value = str(line[column]).replace('.', ',') else: value = line[column] row.append(value) export_file.writerow(row) 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, lignes_export, columns, filename_, nom_outil_compta): workbook = xlwt.Workbook() worksheet = workbook.add_sheet(filename_) if nom_outil_compta == 'cegid': header_file = HEADER_DEFAULT_CEGID_FILE else: header_file = columns for i, fieldname in enumerate(header_file): worksheet.write(0, i, fieldname) worksheet.col(i).width = 8000 # around 220 pixels base_style = xlwt.easyxf('align: wrap yes') for row_index, line in enumerate(lignes_export): for cell_index, column in enumerate(columns): cell_style = base_style if ((column == 'date') or (column == 'echeance') and line[column]): cell_value = Date.to_date(line[column]).strftime( '%d/%m/%Y') elif (column == 'credit') or (column == 'debit'): cell_value = line[column] elif isinstance(line[column], pycompat.string_types): cell_value = re.sub("\r", " ", line[column]) else: cell_value = line[column] worksheet.write(row_index + 1, cell_index, cell_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) def datas_export_ventes(self, format, date_start, date_end, nom_outil_compta): if nom_outil_compta == 'ibiza': columns = HEADER_DEFAULT journal_value = 'VT' elif nom_outil_compta == 'cegid': columns = HEADER_DEFAULT_CEGID journal_value = 'VEN' else: columns = HEADER_DEFAULT journal_value = 'VT' # requete request.cr.execute(""" SELECT l.date, %s AS journal, a.code AS compte, '' AS auxiliaire, l.debit, l.credit, (CASE WHEN l.name = '/' OR l.name = '' THEN p.name ELSE CONCAT('Facture ',i.number,' - ',l.name) END) AS libelle, i.number AS piece, l.date_maturity AS echeance, i.number AS ref_piece FROM account_move_line AS l LEFT JOIN account_invoice AS i ON l.invoice_id = i.id LEFT JOIN account_account AS a ON l.account_id = a.id LEFT JOIN res_partner AS p ON l.partner_id = p.id WHERE l.journal_id = 1 AND l.date >= %s AND l.date <= %s ORDER BY l.date, l.move_id, a.code DESC; """, (journal_value, date_start, date_end)) lignes_export = request.cr.dictfetchall() company_name = request.env['res.company'].search([('id', '=', 1)]).name filename_ = (company_name.title().replace(' ', '') + 'JournalVentes_' + date_start.replace('-', '') + '_' + date_end.replace('-', '')) if format == 'csv': return self.export_csv( lignes_export, columns, filename_, nom_outil_compta) return self.export_xls( lignes_export, columns, filename_, nom_outil_compta) def datas_export_achats(self, format, date_start, date_end, nom_outil_compta): if nom_outil_compta == 'ibiza': columns = HEADER_DEFAULT journal_value = 'HA' elif nom_outil_compta == 'cegid': columns = HEADER_DEFAULT_CEGID journal_value = 'ACH' else: columns = HEADER_DEFAULT journal_value = 'HA' request.cr.execute(""" SELECT l.date, %s AS journal, a.code AS compte, '' AS auxiliaire, l.debit, l.credit, (CASE WHEN l.name = '/' OR '' THEN p.name ELSE CONCAT('Facture ',i.number,' - ',l.name) END) AS libelle, i.number AS piece, i.date_due AS echeance, i.reference AS ref_piece FROM account_move_line AS l LEFT JOIN account_invoice AS i ON l.invoice_id = i.id LEFT JOIN account_account AS a ON l.account_id = a.id LEFT JOIN res_partner AS p ON l.partner_id = p.id WHERE l.journal_id = 2 AND i.type='in_invoice' AND l.date >= %s AND l.date <= %s ORDER BY l.date, l.move_id, a.code DESC; """, (journal_value, date_start, date_end)) lignes_export = request.cr.dictfetchall() company_name = request.env['res.company'].search([('id', '=', 1)]).name filename_ = (company_name.title().replace(' ', '') + 'JournalAchats_' + date_start.replace('-', '') + '_' + date_end.replace('-', '')) if format == 'csv': return self.export_csv( lignes_export, columns, filename_, nom_outil_compta) return self.export_xls( lignes_export, columns, filename_, nom_outil_compta) @http.route('/web/export_journal/', type='http', auth="user") @serialize_exception def datas_export(self, format, journal, nom_outil_compta, date_start, date_end, **kw): if journal == 'ventes': return self.datas_export_ventes(format, date_start, date_end, nom_outil_compta) elif journal == 'achats': return self.datas_export_achats(format, date_start, date_end, nom_outil_compta)