diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2023-09-13 14:19:19 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2024-02-05 10:51:51 +0100 |
commit | b02d86f02416edb7724db8145ae19c6d9a454c6e (patch) | |
tree | 859a3d5a013cf5441691a51aa0e42b3a86984f9d /ishtar_common/models_imports.py | |
parent | bd4190a50935678ba7f618813b193d3a8a37e3a7 (diff) | |
download | Ishtar-b02d86f02416edb7724db8145ae19c6d9a454c6e.tar.bz2 Ishtar-b02d86f02416edb7724db8145ae19c6d9a454c6e.zip |
✨ Pre-import form: manage import
Diffstat (limited to 'ishtar_common/models_imports.py')
-rw-r--r-- | ishtar_common/models_imports.py | 102 |
1 files changed, 94 insertions, 8 deletions
diff --git a/ishtar_common/models_imports.py b/ishtar_common/models_imports.py index 454bed7e8..c03dd208b 100644 --- a/ishtar_common/models_imports.py +++ b/ishtar_common/models_imports.py @@ -65,14 +65,16 @@ from ishtar_common.model_managers import SlugModelManager from ishtar_common.utils import ( create_slug, + generate_dict_from_list, get_all_related_m2m_objects_with_model, - put_session_message, - put_session_var, get_session_var, - num2col, - max_size_help, import_class, + max_size_help, + num2col, + put_session_message, + put_session_var, reverse_coordinates, + update_data ) from ishtar_common.data_importer import ( Importer, @@ -237,7 +239,7 @@ class ImporterType(models.Model): return col_number = 1 # user number so we start with 1 lst_col_number = 0 - for column in self.columns.order_by("col_number").all(): + for column in self.columns.filter(col_number__gt=0).order_by("col_number").all(): while column.col_number > col_number: col_number += 1 # header @@ -291,10 +293,13 @@ class ImporterType(models.Model): DEFAULTS = dict( [(default.keys, default.values) for default in self.defaults.all()] ) + PRE_IMPORT_VALUES = {} + if import_instance: + PRE_IMPORT_VALUES = import_instance.pre_import_values LINE_FORMAT = [] LINE_EXPORT_FORMAT = [] idx = 0 - for column in self.columns.order_by("col_number").all(): + for column in self.columns.filter(col_number__gt=0).order_by("col_number").all(): idx += 1 while column.col_number > idx: LINE_FORMAT.append(None) @@ -354,6 +359,7 @@ class ImporterType(models.Model): "OBJECT_CLS": OBJECT_CLS, "DESC": self.description, "DEFAULTS": DEFAULTS, + "PRE_IMPORT_VALUES": PRE_IMPORT_VALUES, "LINE_FORMAT": LINE_FORMAT, "UNICITY_KEYS": UNICITY_KEYS, "LINE_EXPORT_FORMAT": LINE_EXPORT_FORMAT, @@ -1129,6 +1135,26 @@ class FormaterType(models.Model): def natural_key(self): return self.formater_type, self.options, self.many_split + @property + def associated_model(self): + if hasattr(self, "__associated_model"): + return self.__associated_model + if self.formater_type != "TypeFormater" or not self.options: + self.__associated_model = None + return + self.__associated_model = None + options = self.options.split(".") + if len(options) == 1: + app = "ishtar_common" + else: + app = options[0] + model_name = options[-1] + try: + self.__associated_model = apps.get_model(app, model_name) + except LookupError: + pass + return self.__associated_model + def __str__(self): return " - ".join( [ @@ -1331,6 +1357,14 @@ class BaseImport(models.Model): class Meta: abstract = True + @property + def has_pre_import_form(self) -> bool: + raise NotImplemented() + + @property + def pre_import_form_is_valid(self) -> bool: + raise NotImplemented() + class ImportGroup(BaseImport): importer_type = models.ForeignKey(ImporterGroup, on_delete=models.CASCADE, @@ -1353,6 +1387,10 @@ class ImportGroup(BaseImport): return False @property + def pre_import_form_is_valid(self) -> bool: + return not any(-1 for imp in self.imports.all() if not imp.pre_import_form_is_valid) + + @property def import_id(self): return f"group-{self.id}" @@ -1386,7 +1424,8 @@ class ImportGroup(BaseImport): actions.append(("A", _("Analyse"))) if self.state == "A": actions.append(("A", _("Re-analyse"))) - actions.append(("I", _("Launch import"))) + if not any(-1 for imp in self.import_list() if not imp.pre_import_form_is_valid): + actions.append(("I", _("Launch import"))) if self.state in ("F", "FE"): actions.append(("A", _("Re-analyse"))) actions.append(("I", _("Re-import"))) @@ -1614,6 +1653,52 @@ class Import(BaseImport): return False return True + @property + def pre_import_values(self) -> dict: + values = {} + for column in self.importer_type.columns.filter(col_number__lte=0): + q = ImportColumnValue.objects.filter(column=column, import_item=self) + if not q.count(): + continue + column_value = q.all()[0] + q = column_value.column.targets.all() + if not q.count(): + continue + target = q.all()[0] + + value = column_value.value + if value == "": + continue + many = target.formater_type.many_split + if many: + if value.startswith("['") and value.endswith("']"): + value = value[2:-2].split("', '") + associated_model = target.formater_type.associated_model + if associated_model: + if many: + try: + value = [associated_model.objects.get(pk=int(pk)) for pk in value] + except (associated_model.DoesNotExist, ValueError): + continue + else: + try: + value = associated_model.objects.get(pk=value) + except (associated_model.DoesNotExist, ValueError): + continue + + keys = target.target.split("__") + dct = generate_dict_from_list(keys, value) + values = update_data(values, dct) + + q = column_value.column.duplicate_fields.all() + if not q.count(): + continue + for dup in q.all(): + keys = dup.field_name.split("__") + dct = generate_dict_from_list(keys, value) + values = update_data(values, dct) + return values + def get_number_of_lines(self): if self.number_of_line: return self.number_of_line @@ -1704,7 +1789,8 @@ class Import(BaseImport): actions.append(("A", _("Analyse"))) if self.state in ("A", "PI"): actions.append(("A", _("Re-analyse"))) - actions.append(("I", _("Launch import"))) + if self.pre_import_form_is_valid: + actions.append(("I", _("Launch import"))) if profile.experimental_feature: if self.changed_checked: actions.append(("IS", _("Step by step import"))) |