From 722f21403f71130a712f84de529d6f9d25bdf441 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20BEAU?= Date: Tue, 19 Sep 2023 00:23:22 +0200 Subject: [PATCH] script_file_import: improve ui, fix import --- .../models/abstract_script_processor.py | 40 ++++++++++++++----- .../models/script_file_import.py | 24 +++++++++-- .../views/script_file_import.xml | 21 ++++++++-- 3 files changed, 67 insertions(+), 18 deletions(-) diff --git a/script_file_import/models/abstract_script_processor.py b/script_file_import/models/abstract_script_processor.py index f86146fc..aa3d0797 100644 --- a/script_file_import/models/abstract_script_processor.py +++ b/script_file_import/models/abstract_script_processor.py @@ -2,10 +2,15 @@ # @author Kévin Roche # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +import base64 import csv +import io +import logging from odoo import models +_logger = logging.getLogger(__name__) + class AbstractScriptProcessor(models.AbstractModel): _name = "abstract.script.processor" @@ -17,17 +22,30 @@ def _process_line(self, line): def run(self, data): headers = set() output = [] - for line in csv.reader(data): - output.append(self._process_line(line)) - headers |= set(output.keys()) - return self.write_output(headers, output) - - def write_output(self, headers, output): + in_file = io.StringIO(base64.b64decode(data).decode("utf-8")) + reader = csv.DictReader(in_file) + for idx, line in enumerate(reader): + _logger.info("Process line %s", idx) + self.flush() + with self.env.cr.savepoint(): + try: + self._process_line(line) + except Exception as e: + line["error"] = str(e) + output.append(line) + _logger.error("Script import error %s", e) + headers = ["error"] + reader.fieldnames + return self.write_output(headers, output, reader.dialect) + + def write_output(self, headers, data, dialect): + f = io.StringIO() writer = csv.DictWriter( - output, - delimiter=",", - quotechar='"', + f, + dialect=dialect, fieldnames=headers, ) - - return data + writer.writeheader() + for row in data: + writer.writerow(row) + f.seek(0) + return base64.b64encode(f.read().encode("utf-8")) diff --git a/script_file_import/models/script_file_import.py b/script_file_import/models/script_file_import.py index 5b8c59f4..9a4d0624 100644 --- a/script_file_import/models/script_file_import.py +++ b/script_file_import/models/script_file_import.py @@ -9,6 +9,9 @@ class ScriptFileImport(models.Model): _name = "script.file.import" _description = "Script File Import" + in_filename = fields.Char() + out_filename = fields.Char(compute="_compute_out_filename") + in_data = fields.Binary(string="Input CSV file", required=True) out_data = fields.Binary(string="Output CSV file", readonly=True) @@ -16,12 +19,25 @@ class ScriptFileImport(models.Model): processor = fields.Selection( string="Processor", selection="_get_processor", required=True ) + state = fields.Selection( + [ + ("draft", "Draft"), + ("processing", "Processing"), + ("done", "Done"), + ], + ) def _get_processor(self): return [] + def run_in_background(self): + self.state = "processing" + self.with_delay().run() + def run(self): - selected_processor = dict( - self._fields["processor"]._description_selection(self.env) - ).get(self.processor) - self.out_data = self.env[selected_processor].run(self.in_data) + self.out_data = self.env[self.processor].run(self.in_data) + self.state = "done" + + def _compute_out_filename(self): + for record in self: + record.out_filename = "Result-" + record.in_filename diff --git a/script_file_import/views/script_file_import.xml b/script_file_import/views/script_file_import.xml index 9b25ad90..6524a839 100644 --- a/script_file_import/views/script_file_import.xml +++ b/script_file_import/views/script_file_import.xml @@ -9,12 +9,27 @@
-
- - + + + +