diff --git a/expenses/forms.py b/expenses/forms.py index 5a7773e..76e3389 100644 --- a/expenses/forms.py +++ b/expenses/forms.py @@ -12,6 +12,12 @@ import os class MultipleFileInput(forms.FileInput): allow_multiple_selected = True + + def value_from_datadict(self, data, files, name): + if hasattr(files, 'getlist'): + return files.getlist(name) + else: + return files.get(name) class MultipleFileField(forms.FileField): def __init__(self, *args, **kwargs): diff --git a/templates/expenses/expense_form.html b/templates/expenses/expense_form.html index b197125..3a5937e 100644 --- a/templates/expenses/expense_form.html +++ b/templates/expenses/expense_form.html @@ -136,8 +136,8 @@ Formatos aceptados: PDF, PNG, JPG, JPEG (Múltiple) - -
+ +
{{ form.receipt }}
@@ -674,11 +674,29 @@ // Handle standard file selection fileInput.addEventListener('change', () => { + let hasError = false; for (let i = 0; i < fileInput.files.length; i++) { - dt.items.add(fileInput.files[i]); + const f = fileInput.files[i]; + const ext = f.name.split('.').pop().toLowerCase(); + if (['pdf', 'png', 'jpg', 'jpeg'].includes(ext)) { + dt.items.add(f); + } else { + hasError = true; + Swal.fire({ + icon: 'error', + title: 'Archivo no permitido', + text: `El archivo "${f.name}" no es una evidencia válida (PDF, PNG, JPG, JPEG).`, + confirmButtonColor: 'var(--efintel-blue)' + }); + } } fileInput.files = dt.files; renderNewFiles(); + + // Si hubo error, resetear el input nativo temporalmente para evitar que se envíe el archivo inválido + if (hasError && dt.files.length === 0) { + fileInput.value = ''; + } }); function renderNewFiles() {