Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions app/config/routing/admin_accounting/journal.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,8 @@ admin_accounting_journal_import:
path: /import
defaults:
_controller: AppBundle\Controller\Admin\Accounting\Journal\ImportAction

admin_accounting_journal_export:
path: /export
defaults:
_controller: AppBundle\Controller\Admin\Accounting\Journal\ExportAction
93 changes: 1 addition & 92 deletions htdocs/pages/administration/compta_journal.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
'ajouter',
'modifier',
'modifier_colonne',
'export',
'upload_attachment',
]);

Expand All @@ -39,7 +38,7 @@
$periode_debut = $listPeriode[$id_periode - 1]['date_debut'];
$periode_fin = $listPeriode[$id_periode - 1]['date_fin'];

if (in_array($action, ['lister', 'debit', 'credit', 'export'])) {
if (in_array($action, ['lister', 'debit', 'credit'])) {
$alsoDisplayClassifed = isset($_GET['also_display_classifed_entries']) && $_GET['also_display_classifed_entries'];

$smarty->assign('also_display_classifed_entries', $alsoDisplayClassifed);
Expand Down Expand Up @@ -251,96 +250,6 @@


$smarty->assign('formulaire', genererFormulaire($formulaire));
} elseif ($action === 'export') {
/*
* This action allows the admin to export the full period in a CSV file.
* This is really useful when you need to filter by columns using Excel.
*/
$journal = $compta->obtenirJournal('', $periode_debut, $periode_fin, !$alsoDisplayClassifed);

// Pointer to output
$fp = fopen('php://output', 'w');

// CSV
$csvDelimiter = ';';
$csvEnclosure = '"';
$csvFilename = sprintf(
'AFUP_%s_journal_from-%s_to-%s.csv',
date('Y-M-d'),
$periode_debut,
$periode_fin,
);

// headers
header('Content-Type: text/csv');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"$csvFilename\"");

// First line
$columns = [
'Date',
'Compte',
'Événement',
'Catégorie',
'Description',
'Débit',
'Crédit',
'Règlement',
'Commentaire',
'Justificatif',
'Nom justificatif',
'Montant HT',
'TVA',
'Montant HT non soumis à TVA',
'Montant HT soumis à TVA 5,5',
'TVA 5,5',
'Montant HT soumis à TVA 10',
'TVA 10',
'Montant HT soumis à TVA 20',
'TVA 20',
"Zone de TVA",
];
fputcsv($fp, $columns, $csvDelimiter, $csvEnclosure);

// Set the current local and get variables to use in number_format
$l = setlocale(LC_ALL, 'fr_FR.utf8');
$locale = localeconv();

foreach ($journal as $line) {
$total = number_format((float) $line['montant'], 2, $locale['decimal_point'], $locale['thousands_sep']);
fputcsv(
$fp,
[
$line['date_ecriture'],
$line['nom_compte'],
$line['evenement'],
$line['categorie'],
$line['description'],
$line['idoperation'] == 1 ? "-$total" : '',
$line['idoperation'] != 1 ? $total : '',
$line['reglement'],
$line['comment'],
$line['attachment_required'] ? 'Oui' : 'Non',
$line['attachment_filename'],
$line['montant_ht'],
$line['montant_tva'],
$line['montant_ht_0'],
$line['montant_ht_5_5'],
$line['montant_tva_5_5'],
$line['montant_ht_10'],
$line['montant_tva_10'],
$line['montant_ht_20'],
$line['montant_tva_20'],
Comptabilite::getTvaZoneLabel($line['tva_zone'], 'Non définie'),
],
$csvDelimiter,
$csvEnclosure,
);
}

fclose($fp);

exit;
}

/*
Expand Down
2 changes: 1 addition & 1 deletion htdocs/templates/administration/compta_journal.html
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ <h2>Journal</h2>
</div>

<div class="ui menu">
<a href="index.php?page=compta_journal&amp;action=export&id_periode={$smarty.get.id_periode|default:''}&also_display_classifed_entries={$also_display_classifed_entries}" class="item">
<a href="/admin/accounting/journal/export?periodId={$smarty.get.id_periode|default:''}&with_reconciled={$also_display_classifed_entries}" class="item">
<i class="icon file"></i>
Exporter la période en CSV
</a>
Expand Down
9 changes: 0 additions & 9 deletions sources/Afup/Comptabilite/Comptabilite.php
Original file line number Diff line number Diff line change
Expand Up @@ -963,13 +963,4 @@ public function modifierRegle($id, $label, $condition, $is_credit, $tva, $catego

return $this->_bdd->executer($requete);
}

public static function getTvaZoneLabel($tvaZoneCode, $defaultValue = null)
{
if (!isset(self::TVA_ZONES[$tvaZoneCode])) {
return $defaultValue;
}

return self::TVA_ZONES[$tvaZoneCode];
}
}
23 changes: 23 additions & 0 deletions sources/AppBundle/Accounting/TvaZone.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace AppBundle\Accounting;

enum TvaZone: string
{
case France = 'france';
case EuropeanUnion = 'ue';
case OutsideEuropeanUnion = 'hors_ue';
case Undefined = '';

public function getLabel(): string
{
return match ($this) {
self::France => 'France',
self::EuropeanUnion => 'Union Européenne hors France',
self::OutsideEuropeanUnion => 'Hors Union Européenne',
self::Undefined => 'Non définie',
};
}
}
111 changes: 111 additions & 0 deletions sources/AppBundle/Controller/Admin/Accounting/Journal/ExportAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<?php

declare(strict_types=1);

namespace AppBundle\Controller\Admin\Accounting\Journal;

use AppBundle\Accounting\Model\Repository\TransactionRepository;
use AppBundle\Accounting\Model\Repository\InvoicingPeriodRepository;
use AppBundle\Accounting\TvaZone;
use SplFileObject;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;

class ExportAction extends AbstractController
{
public function __construct(
private readonly InvoicingPeriodRepository $invoicingPeriodRepository,
private readonly TransactionRepository $accountingRepository,
) {}

public function __invoke(Request $request): Response
{
$periodId = $request->query->has('periodId') && !empty($request->query->get('periodId')) ? $request->query->getInt('periodId') : null;
$withReconciled = $request->query->getBoolean('with_reconciled');
$period = $this->invoicingPeriodRepository->getCurrentPeriod($periodId);

$entries = $this->accountingRepository->getEntriesPerInvoicingPeriod($period, !$withReconciled);

// CSV
$csvFilename = sprintf(
'AFUP_%s_journal_from-%s_to-%s.csv',
date('Y-M-d'),
$period->getStartDate()->format('Y-m-d'),
$period->getEndDate()->format('Y-m-d'),
);
$tmpFile = tempnam(sys_get_temp_dir(), $csvFilename);
$file = new SplFileObject($tmpFile, 'w');
$csvDelimiter = ';';
$csvEnclosure = '"';

$columns = [
'Date',
'Compte',
'Événement',
'Catégorie',
'Description',
'Débit',
'Crédit',
'Règlement',
'Commentaire',
'Justificatif',
'Nom justificatif',
'Montant HT',
'TVA',
'Montant HT non soumis à TVA',
'Montant HT soumis à TVA 5,5',
'TVA 5,5',
'Montant HT soumis à TVA 10',
'TVA 10',
'Montant HT soumis à TVA 20',
'TVA 20',
"Zone de TVA",
];
$file->fputcsv($columns, $csvDelimiter, $csvEnclosure);

// Set the current local and get variables to use in number_format
$l = setlocale(LC_ALL, 'fr_FR.utf8');
$locale = localeconv();

foreach ($entries as $entry) {
$total = number_format((float) $entry['montant'], 2, $locale['decimal_point'], $locale['thousands_sep']);
$file->fputcsv(
[
$entry['date_ecriture'],
$entry['nom_compte'],
$entry['evenement'],
$entry['categorie'],
$entry['description'],
$entry['idoperation'] == 1 ? '-' . $total : '',
$entry['idoperation'] != 1 ? $total : '',
$entry['reglement'],
$entry['comment'],
$entry['attachment_required'] ? 'Oui' : 'Non',
$entry['attachment_filename'],
number_format((float) $entry['montant_ht'], 2, $locale['decimal_point'], $locale['thousands_sep']),
number_format((float) $entry['montant_tva'], 3, $locale['decimal_point'], $locale['thousands_sep']),
$entry['montant_ht_0'],
$entry['montant_ht_5_5'],
$entry['montant_tva_5_5'],
$entry['montant_ht_10'],
$entry['montant_tva_10'],
$entry['montant_ht_20'],
$entry['montant_tva_20'],
TvaZone::from((string) $entry['tva_zone'])->getLabel(),
],
$csvDelimiter,
$csvEnclosure,
);
}
$file->eof();

$response = new BinaryFileResponse($file);
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, $csvFilename);
$response->deleteFileAfterSend(true);

return $response;
}
}
3 changes: 2 additions & 1 deletion tests/behat/features/Admin/Tresorerie/Journal.feature
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ Feature: Administration - Trésorerie - Journal

# Export Excel
When I follow "Exporter la période en CSV"
Then the response header "Content-disposition" should match '#^attachment; filename="AFUP_(.*)_journal_from(.*).csv"#'
Then the response header "content-disposition" should match '#^attachment; filename=AFUP_(.*)_journal_from(.*).csv#'
And the downloaded file should be the same as "admin_journal_export.csv"

@reloadDbWithTestData
Scenario: Compte journal Télécharger les justificatifs groupés par mois
Expand Down
3 changes: 3 additions & 0 deletions tests/behat/files/admin_journal_export.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Date;Compte;Événement;Catégorie;Description;Débit;Crédit;Règlement;Commentaire;Justificatif;"Nom justificatif";"Montant HT";TVA;"Montant HT non soumis à TVA";"Montant HT soumis à TVA 5,5";"TVA 5,5";"Montant HT soumis à TVA 10";"TVA 10";"Montant HT soumis à TVA 20";"TVA 20";"Zone de TVA"
2026-01-01;"Compte courant";AG;"A déterminer";"Description dépense 001";-12001.00;;;;Non;;0.00;0.000;;;;;;;;"Non définie"
2026-01-02;"Compte courant";AG;"A déterminer";"Description recette 001";;12003.00;;;Non;;0.00;0.000;;;;;;;;"Non définie"
Loading