diff --git a/Makefile b/Makefile index e6a549ba6..a45d166cb 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,9 @@ SHELL := /bin/bash server: @python manage.py runserver 0.0.0.0:8001 +worker: + @python -m celery -A core.worker worker -B -l INFO + fmt: @pre-commit run --all-files diff --git a/conventions/services/avenants.py b/conventions/services/avenants.py index 2eefe7037..5bb8e1065 100644 --- a/conventions/services/avenants.py +++ b/conventions/services/avenants.py @@ -13,6 +13,8 @@ from conventions.services.search import AvenantListSearchService from upload.services import UploadService +from .utils import convention_upload_filename + logger = logging.getLogger(__name__) @@ -141,14 +143,16 @@ def complete_avenants_for_avenant( if avenant_form.is_valid(): file = request.FILES["nom_fichier_signe"] if file: - now = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M") - filename = f"{now}_convention_{avenant.uuid}_signed.pdf" + upload_filename = convention_upload_filename(avenant) + upload_service = UploadService( convention_dirpath=f"conventions/{avenant.uuid}/convention_docs", - filename=filename, + filename=upload_filename, ) + upload_service.upload_file(file) - avenant.nom_fichier_signe = filename + avenant.nom_fichier_signe = upload_filename + for avenant_type in avenant_form.cleaned_data["avenant_types"]: avenanttype = AvenantType.objects.get(nom=avenant_type) avenant.avenant_types.add(avenanttype) diff --git a/conventions/services/file.py b/conventions/services/file.py index ff572c10e..54ec1bd8c 100644 --- a/conventions/services/file.py +++ b/conventions/services/file.py @@ -8,6 +8,8 @@ from core.storage import client from upload.services import UploadService +from .utils import convention_upload_filename + logger = logging.getLogger(__name__) @@ -16,11 +18,11 @@ class ConventionFileService: def upload_convention_file( cls, convention: Convention, file: File, update_statut: bool = True ): - now = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M") - filename = f"{now}_convention_{convention.uuid}_signed.pdf" + upload_filename = convention_upload_filename(convention) + upload_service = UploadService( convention_dirpath=f"conventions/{convention.uuid}/convention_docs", - filename=filename, + filename=upload_filename, ) upload_service.upload_file(file) @@ -28,7 +30,7 @@ def upload_convention_file( convention.statut = ConventionStatut.SIGNEE.label convention.televersement_convention_signee_le = datetime.date.today() - convention.nom_fichier_signe = filename + convention.nom_fichier_signe = upload_filename convention.save() @classmethod diff --git a/conventions/services/utils.py b/conventions/services/utils.py index 55579ff68..f64708256 100644 --- a/conventions/services/utils.py +++ b/conventions/services/utils.py @@ -1,4 +1,5 @@ import json +from datetime import datetime from enum import Enum from django.http import HttpRequest @@ -147,3 +148,29 @@ def set_from_form_or_object(field, form, obj): else getattr(obj, field) ), ) + + +def convention_upload_filename(convention: Convention) -> str: + + def _normalize(numero: str | None) -> str | None: + if numero: + return numero.replace(" ", "_") + + parts = [] + + if convention.parent: + parts += [ + f"convention_{_normalize(convention.parent.numero)}", + f"avenant_{_normalize(convention.numero) or 'N'}", + ] + else: + parts += [ + f"convention_{_normalize(convention.numero) or 'NUM'}", + ] + + if convention.statut == ConventionStatut.PROJET.label: + parts.append("projet") + + parts.append(datetime.now().strftime("%Y-%m-%d_%H-%M")) + + return f"{'_'.join(parts)}.pdf" diff --git a/conventions/tests/services/test_utils.py b/conventions/tests/services/test_utils.py new file mode 100644 index 000000000..f34005918 --- /dev/null +++ b/conventions/tests/services/test_utils.py @@ -0,0 +1,70 @@ +import time_machine +from django.test import SimpleTestCase +from unittest_parametrize import ParametrizedTestCase, parametrize + +from conventions.models import ConventionStatut +from conventions.services.utils import convention_upload_filename +from conventions.tests.factories import ConventionFactory + + +class UtilsTest(ParametrizedTestCase, SimpleTestCase): + + @parametrize( + "conv_data, expected_result", + [ + ( + { + "numero": "123/456/789", + }, + "convention_123/456/789_projet_2024-06-21_00-00.pdf", + ), + ( + { + "numero": None, + }, + "convention_NUM_projet_2024-06-21_00-00.pdf", + ), + ( + { + "numero": "", + }, + "convention_NUM_projet_2024-06-21_00-00.pdf", + ), + ( + { + "numero": "123 456 789", + "statut": ConventionStatut.INSTRUCTION.label, + }, + "convention_123_456_789_2024-06-21_00-00.pdf", + ), + ( + { + "numero": "1", + "parent": ConventionFactory.build(numero="123/456/789"), + }, + "convention_123/456/789_avenant_1_projet_2024-06-21_00-00.pdf", + ), + ( + { + "numero": None, + "parent": ConventionFactory.build(numero="123/456/789"), + }, + "convention_123/456/789_avenant_N_projet_2024-06-21_00-00.pdf", + ), + ( + { + "numero": "", + "parent": ConventionFactory.build(numero="123/456/789"), + }, + "convention_123/456/789_avenant_N_projet_2024-06-21_00-00.pdf", + ), + ], + ) + def test_convention_upload_filename(self, conv_data, expected_result): + with time_machine.travel("2024-06-21"): + assert ( + convention_upload_filename( + convention=ConventionFactory.build(**conv_data) + ) + == expected_result + ) diff --git a/requirements.txt b/requirements.txt index 69bd29aed..af6d41ccc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -127,9 +127,9 @@ django-sql-explorer[xls]==4.3 \ --hash=sha256:9c0735b08270ac60276ea2697a499cb9457acf00f0d0016a230c092ab3b4d310 \ --hash=sha256:c853bc0a270b290646d4ca731769f1e223a151e5724aee69e3b3967f0cf7b96f # via -r requirements.in -django-storages==1.14.4 \ - --hash=sha256:69aca94d26e6714d14ad63f33d13619e697508ee33ede184e462ed766dc2a73f \ - --hash=sha256:d61930acb4a25e3aebebc6addaf946a3b1df31c803a6bf1af2f31c9047febaa3 +django-storages==1.14.3 \ + --hash=sha256:31f263389e95ce3a1b902fb5f739a7ed32895f7d8b80179fe7453ecc0dfe102e \ + --hash=sha256:95a12836cd998d4c7a4512347322331c662d9114c4344f932f5e9c0fce000608 # via -r requirements.in django-waffle==4.1.0 \ --hash=sha256:5979a2f3dd674ef7086480525b39651fc2045427f6d8e6a614192656d3402c5b \