Skip to content

Commit 059bc0a

Browse files
authored
Refonte - Trésorerie > Journal > Upload des justificatifs (#2122)
Co-authored-by: vgreb <vgreb@users.noreply.github.com>
1 parent 9b6b471 commit 059bc0a

File tree

5 files changed

+82
-101
lines changed

5 files changed

+82
-101
lines changed

app/config/routing/admin_accounting/journal.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,11 @@ admin_accounting_journal_update_info:
4242
methods: [POST]
4343
requirements:
4444
id: \d+
45+
46+
admin_accounting_journal_upload:
47+
path: /upload/{id}
48+
defaults:
49+
_controller: AppBundle\Controller\Admin\Accounting\Journal\UploadAttachmentAction
50+
methods: [POST]
51+
requirements:
52+
id: \d+

htdocs/pages/administration/compta_journal.php

Lines changed: 0 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -251,103 +251,3 @@
251251

252252
$smarty->assign('formulaire', genererFormulaire($formulaire));
253253
}
254-
255-
/**
256-
* Upload an attachment and save it on the specific line.
257-
* We save the uploads in a directory at the same month of the line
258-
* and we don't forget to rename the file with the date of the line
259-
* and a unique identifier to keep it safe.
260-
* If the line already has an attachment, we remove it before saving
261-
* the new one in the line.
262-
*/ elseif ($action === 'upload_attachment') {
263-
try {
264-
// Bad request?
265-
if (!isset($_GET['id']) || !($line = $compta->obtenir((int) $_GET['id']))) {
266-
throw new Exception("Please verify parameters", 400);
267-
}
268-
269-
// Test line existence
270-
if (!$line['id']) {
271-
throw new Exception("Not found", 404);
272-
}
273-
274-
// Avoid multiple upload
275-
if (
276-
!isset($_FILES['file']['error'])
277-
|| is_array($_FILES['file']['error'])
278-
) {
279-
throw new RuntimeException('Invalid parameters. You can\'t upload multiple files.');
280-
}
281-
282-
// The directory
283-
$directory = date('Ym', strtotime((string) $line['date_ecriture'])) . DIRECTORY_SEPARATOR;
284-
$uploadDirectory = AFUP_CHEMIN_RACINE . 'uploads' . DIRECTORY_SEPARATOR . $directory;
285-
if (!is_dir($uploadDirectory)) {
286-
mkdir($uploadDirectory, 0750, true);
287-
}
288-
289-
// Get the file, rename it, and move it.
290-
// Check $_FILES['file']['error'] value.
291-
switch ($_FILES['file']['error']) {
292-
case UPLOAD_ERR_OK:
293-
break;
294-
case UPLOAD_ERR_NO_FILE:
295-
throw new RuntimeException('No file sent.');
296-
case UPLOAD_ERR_INI_SIZE:
297-
case UPLOAD_ERR_FORM_SIZE:
298-
throw new RuntimeException('Exceeded filesize limit.');
299-
default:
300-
throw new RuntimeException('Unknown errors.');
301-
}
302-
303-
// You should also check filesize here.
304-
if ($_FILES['upfile']['size'] > 1000000) {
305-
throw new RuntimeException('Exceeded filesize limit.');
306-
}
307-
308-
// Check MIME Type
309-
$finfo = new finfo(FILEINFO_MIME_TYPE);
310-
if (false === $ext = array_search(
311-
$finfo->file($_FILES['file']['tmp_name']),
312-
[
313-
'jpg' => 'image/jpeg',
314-
'png' => 'image/png',
315-
'pdf' => 'application/pdf',
316-
],
317-
true,
318-
)) {
319-
throw new RuntimeException('Invalid file format. Only jpg/png/pdf allowed.');
320-
}
321-
322-
// Move/Rename
323-
$filename = sprintf('%s.%s',
324-
date('Y-m-d', strtotime((string) $line['date_ecriture'])) . '_' . $line['id'] . '_' . substr(sha1_file($_FILES['file']['tmp_name']), 0, 6),
325-
$ext,
326-
);
327-
$moved = move_uploaded_file(
328-
$_FILES['file']['tmp_name'],
329-
$uploadDirectory . $filename,
330-
);
331-
if (!$moved) {
332-
throw new RuntimeException('Failed to move uploaded file.');
333-
}
334-
335-
// Remove old file if exists
336-
if ($line['attachment_filename']) {
337-
$oldFilename = AFUP_CHEMIN_RACINE . 'uploads' . DIRECTORY_SEPARATOR . $line['attachment_filename'];
338-
if (is_file($oldFilename)) {
339-
unlink($oldFilename);
340-
}
341-
}
342-
343-
// Update line
344-
$compta->modifierColonne($line['id'], 'attachment_filename', $directory . $filename);
345-
346-
header('HTTP/1.1 200 OK');
347-
header('X-Info: File uploaded \o/');
348-
} catch (Exception $e) {
349-
header('HTTP/1.1 400 Bad Request');
350-
echo $e->getMessage();
351-
}
352-
exit;
353-
}

htdocs/templates/administration/compta_journal.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ <h2>Journal</h2>
163163
data-position="left center"
164164
data-tooltip="Cliquez ou déposez un fichier dans la zone pour ajouter un justificatif"
165165
>
166-
<form action="index.php?page=compta_journal&amp;action=upload_attachment&amp;id={$ecriture.idtmp}"
166+
<form action="/admin/accounting/journal/upload/{$ecriture.idtmp}"
167167
class="js-dropzone{if !$ecriture.attachment_required}--lazy{/if} dz-journal-form ui center aligned tertiary blue segment"
168168
style="display:none;cursor: pointer"
169169
>

htdocs/templates/administration/compta_journal.js.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333
var initDropzone = function(container) {
3434
$('.js-dropzone', container).each(function () {
3535
var elmt = $(this);
36+
// Skip if already initialized
37+
if (elmt.hasClass('dz-clickable')) {
38+
return;
39+
}
3640
elmt.dropzone({
3741
url: elmt.attr('href'),
3842
previewTemplate: $('.js-dz-preview-template').html(),
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace AppBundle\Controller\Admin\Accounting\Journal;
6+
7+
use AppBundle\Accounting\Model\Repository\TransactionRepository;
8+
use AppBundle\Accounting\Model\Transaction;
9+
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
10+
use Symfony\Component\DependencyInjection\Attribute\Autowire;
11+
use Symfony\Component\HttpFoundation\File\UploadedFile;
12+
use Symfony\Component\HttpFoundation\Request;
13+
use Symfony\Component\HttpFoundation\Response;
14+
use Symfony\Component\Validator\Constraints\File;
15+
use Symfony\Component\Validator\Validator\ValidatorInterface;
16+
17+
class UploadAttachmentAction extends AbstractController
18+
{
19+
public function __construct(
20+
private readonly TransactionRepository $transactionRepository,
21+
private readonly ValidatorInterface $validator,
22+
#[Autowire('%kernel.project_dir%/../htdocs/uploads/')] private readonly string $uploadDir,
23+
) {}
24+
25+
public function __invoke(Request $request, int $id): Response
26+
{
27+
$transaction = $this->transactionRepository->get($id);
28+
if (!$transaction instanceof Transaction) {
29+
throw $this->createNotFoundException();
30+
}
31+
32+
if (!$request->files->get('file') instanceof UploadedFile) {
33+
return new Response('No file uploaded', 400);
34+
}
35+
36+
$directory = $transaction->getAccountingDate()->format('Ym') . DIRECTORY_SEPARATOR;
37+
$targetDir = $this->uploadDir . $directory;
38+
if (!is_dir($targetDir)) {
39+
mkdir($targetDir, 0750, true);
40+
}
41+
/** @var UploadedFile $file */
42+
$file = $request->files->get('file');
43+
44+
$violations = $this->validator->validate($file, [
45+
new File(mimeTypes: ['image/jpeg', 'image/png', 'application/pdf'], maxSize: '1M'),
46+
]);
47+
foreach ($violations as $violation) {
48+
return new Response($violation->getMessage(), 400);
49+
}
50+
51+
$filename = sprintf('%s.%s',
52+
$transaction->getAccountingDate()->format('Y-m-d') . '_' . $transaction->getId() . '_' . substr(sha1_file($file->getPathname()), 0, 6),
53+
$file->guessExtension(),
54+
);
55+
$file->move($targetDir, $filename);
56+
57+
if (!empty($transaction->getAttachmentFilename())) {
58+
$oldFilename = $this->uploadDir . $transaction->getAttachmentFilename();
59+
if (is_file($oldFilename)) {
60+
unlink($oldFilename);
61+
}
62+
}
63+
64+
$transaction->setAttachmentFilename($directory . $filename);
65+
$this->transactionRepository->save($transaction);
66+
67+
return new Response();
68+
}
69+
}

0 commit comments

Comments
 (0)