fix: add legacy file fallback and use atomic transactions for document creation

This commit is contained in:
kdeterme 2026-09-22 19:44:35 +02:00
parent 55cad6d6cc
commit c7c76f28dc
2 changed files with 109 additions and 90 deletions

View file

@ -731,9 +731,21 @@ class DocumentFolderAttachment(models.Model):
def duplicate_file(field): def duplicate_file(field):
if not field: if not field:
return None return None
try:
file_name = os.path.basename(field.name) file_name = os.path.basename(field.name)
with field.open("rb") as f: with field.open("rb") as f:
return ContentFile(f.read(), name=file_name) return ContentFile(f.read(), name=file_name)
except Exception:
# Fallback si le fichier historique est présent dans MEDIA_ROOT avant migration vers private storage
try:
if hasattr(settings, "MEDIA_ROOT") and field.name:
alt_path = os.path.join(settings.MEDIA_ROOT, field.name)
if os.path.exists(alt_path):
with open(alt_path, "rb") as f:
return ContentFile(f.read(), name=os.path.basename(field.name))
except Exception:
pass
return None
def ensure_document_for_legacy(instance, old_file_name=None): def ensure_document_for_legacy(instance, old_file_name=None):
@ -757,6 +769,16 @@ def ensure_document_for_legacy(instance, old_file_name=None):
context_object = instance.get_document_context() context_object = instance.get_document_context()
title = instance.get_document_title() title = instance.get_document_title()
file_changed = bool(old_file_name and old_file_name != instance.file.name)
should_create_version = (managed is None) or not managed.versions.exists() or file_changed
if should_create_version:
new_file = duplicate_file(instance.file)
if not new_file:
# Ne pas créer de ManagedDocument orphelin si le fichier physique est inaccessible
return
with transaction.atomic():
if managed is None: if managed is None:
managed = ManagedDocument.objects.create( managed = ManagedDocument.objects.create(
title=title, title=title,
@ -784,11 +806,6 @@ def ensure_document_for_legacy(instance, old_file_name=None):
) )
managed.types.add(doc_type) managed.types.add(doc_type)
file_changed = bool(old_file_name and old_file_name != instance.file.name)
should_create_version = not managed.versions.exists() or file_changed
if should_create_version:
new_file = duplicate_file(instance.file)
thumbnail_file = duplicate_file(getattr(instance, "thumbnail", None)) thumbnail_file = duplicate_file(getattr(instance, "thumbnail", None))
version = DocumentVersion( version = DocumentVersion(
@ -802,6 +819,7 @@ def ensure_document_for_legacy(instance, old_file_name=None):
validated_at=timezone.now(), validated_at=timezone.now(),
) )
version.save() version.save()
managed.touch(version)
elif managed.current_version is None: elif managed.current_version is None:
managed.touch(managed.versions.order_by("-version_number").first()) managed.touch(managed.versions.order_by("-version_number").first())

View file

@ -331,6 +331,7 @@ class DocumentManagementService:
"message": _("New version added to existing document."), "message": _("New version added to existing document."),
} }
else: else:
with transaction.atomic():
# Déterminer la visibilité # Déterminer la visibilité
if visibility is None: if visibility is None:
if content_object and getattr(getattr(content_object, '_meta', None), 'model_name', None) == 'project': if content_object and getattr(getattr(content_object, '_meta', None), 'model_name', None) == 'project':