Skip to content

refonte comptabilité avec Doctrine - #2345

Closed
vgreb wants to merge 1 commit into
afup:masterfrom
vgreb:refacto/doctrine-accounting
Closed

refonte comptabilité avec Doctrine#2345
vgreb wants to merge 1 commit into
afup:masterfrom
vgreb:refacto/doctrine-accounting

Conversation

@vgreb

@vgreb vgreb commented Aug 16, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

@vgreb vgreb self-assigned this Aug 20, 2026
# Conflicts:
#	sources/AppBundle/Accounting/InvoicingPdfGenerator.php

diff --git c/config/packages/ting.yaml i/config/packages/ting.yaml
index 50e74aa9c..6ddf960e9 100644
--- c/config/packages/ting.yaml
+++ i/config/packages/ting.yaml
@@ -17,13 +17,6 @@ ting:
                 default:
                     connection: main
                     database: '%database_name%'
-        accounting:
-            namespace: AppBundle\Accounting\Model\Repository
-            directory: "@AppBundle/Accounting/Model/Repository"
-            options:
-                default:
-                    connection: main
-                    database: "%database_name%"
         association:
             namespace : AppBundle\Association\Model\Repository
             directory : "@AppBundle/Association/Model/Repository"
diff --git c/db/migrations/20260816000000_make_transaction_payment_type_nullable.php i/db/migrations/20260816000000_make_transaction_payment_type_nullable.php
new file mode 100644
index 000000000..8cfccc2eb
--- /dev/null
+++ i/db/migrations/20260816000000_make_transaction_payment_type_nullable.php
@@ -0,0 +1,34 @@
+<?php
+
+declare(strict_types=1);
+
+use Phinx\Migration\AbstractMigration;
+
+final class MakeTransactionPaymentTypeNullable extends AbstractMigration
+{
+    public function up(): void
+    {
+        $this->table('compta')
+            ->changeColumn('idmode_regl', 'integer', [
+                'limit' => 5,
+                'null' => true,
+                'default' => null,
+            ])
+            ->update();
+
+        $this->execute('UPDATE compta SET idmode_regl = NULL WHERE idmode_regl = 0');
+    }
+
+    public function down(): void
+    {
+        $this->execute('UPDATE compta SET idmode_regl = 0 WHERE idmode_regl IS NULL');
+
+        $this->table('compta')
+            ->changeColumn('idmode_regl', 'integer', [
+                'limit' => 5,
+                'null' => false,
+                'default' => 0,
+            ])
+            ->update();
+    }
+}
diff --git c/db/seeds/ComptaCompte.php i/db/seeds/ComptaCompte.php
index d515d6e77..05b5e4874 100644
--- c/db/seeds/ComptaCompte.php
+++ i/db/seeds/ComptaCompte.php
@@ -27,6 +27,14 @@ class ComptaCompte extends AbstractSeed
                 'nom_compte' => 'Paypal',
                 'archived_at' => new DateTime('last year')->format('Y-m-d H:i:s'),
             ],
+            [
+                'id' => 5,
+                'nom_compte' => 'Compte courant CMUT',
+            ],
+            [
+                'id' => 6,
+                'nom_compte' => 'Livret CMUT',
+            ],
         ];

         $table = $this->table('compta_compte');
diff --git c/phpstan-baseline.php i/phpstan-baseline.php
index 8d46fc323..69f470ffe 100644
--- c/phpstan-baseline.php
+++ i/phpstan-baseline.php
@@ -199,6 +199,30 @@ $ignoreErrors[] = [
 	'count' => 1,
 	'path' => __DIR__ . '/sources/Afup/Utils/Vat.php',
 ];
+$ignoreErrors[] = [
+	'message' => '#^Property AppBundle\\\\Accounting\\\\Entity\\\\InvoicingDetail\\:\\:\\$designation type mapping mismatch\\: property can contain string\\|null but database expects string\\.$#',
+	'identifier' => 'doctrine.columnType',
+	'count' => 1,
+	'path' => __DIR__ . '/sources/AppBundle/Accounting/Entity/InvoicingDetail.php',
+];
+$ignoreErrors[] = [
+	'message' => '#^Property AppBundle\\\\Accounting\\\\Entity\\\\InvoicingDetail\\:\\:\\$prixUnitaire type mapping mismatch\\: property can contain float\\|null but database expects float\\|int\\.$#',
+	'identifier' => 'doctrine.columnType',
+	'count' => 1,
+	'path' => __DIR__ . '/sources/AppBundle/Accounting/Entity/InvoicingDetail.php',
+];
+$ignoreErrors[] = [
+	'message' => '#^Property AppBundle\\\\Accounting\\\\Entity\\\\InvoicingDetail\\:\\:\\$quantite type mapping mismatch\\: property can contain float\\|null but database expects float\\|int\\.$#',
+	'identifier' => 'doctrine.columnType',
+	'count' => 1,
+	'path' => __DIR__ . '/sources/AppBundle/Accounting/Entity/InvoicingDetail.php',
+];
+$ignoreErrors[] = [
+	'message' => '#^Property AppBundle\\\\Accounting\\\\Entity\\\\InvoicingDetail\\:\\:\\$reference type mapping mismatch\\: property can contain string\\|null but database expects string\\.$#',
+	'identifier' => 'doctrine.columnType',
+	'count' => 1,
+	'path' => __DIR__ . '/sources/AppBundle/Accounting/Entity/InvoicingDetail.php',
+];
 $ignoreErrors[] = [
 	'message' => '#^Method AppBundle\\\\Accounting\\\\Entity\\\\Repository\\\\AccountRepository\\:\\:getAllSortedByName\\(\\) should return array\\<AppBundle\\\\Accounting\\\\Entity\\\\Account\\> but returns mixed\\.$#',
 	'identifier' => 'return.type',
@@ -217,6 +241,30 @@ $ignoreErrors[] = [
 	'count' => 1,
 	'path' => __DIR__ . '/sources/AppBundle/Accounting/Entity/Repository/EventRepository.php',
 ];
+$ignoreErrors[] = [
+	'message' => '#^Method AppBundle\\\\Accounting\\\\Entity\\\\Repository\\\\InvoicingPeriodRepository\\:\\:getCurrentPeriod\\(\\) should return AppBundle\\\\Accounting\\\\Entity\\\\InvoicingPeriod but returns AppBundle\\\\Accounting\\\\Entity\\\\InvoicingPeriod\\|null\\.$#',
+	'identifier' => 'return.type',
+	'count' => 1,
+	'path' => __DIR__ . '/sources/AppBundle/Accounting/Entity/Repository/InvoicingPeriodRepository.php',
+];
+$ignoreErrors[] = [
+	'message' => '#^Cannot access property \\$dateDebut on AppBundle\\\\Accounting\\\\Entity\\\\InvoicingPeriod\\|null\\.$#',
+	'identifier' => 'property.nonObject',
+	'count' => 2,
+	'path' => __DIR__ . '/sources/AppBundle/Accounting/Entity/Repository/InvoicingRepository.php',
+];
+$ignoreErrors[] = [
+	'message' => '#^Cannot access property \\$dateFin on AppBundle\\\\Accounting\\\\Entity\\\\InvoicingPeriod\\|null\\.$#',
+	'identifier' => 'property.nonObject',
+	'count' => 2,
+	'path' => __DIR__ . '/sources/AppBundle/Accounting/Entity/Repository/InvoicingRepository.php',
+];
+$ignoreErrors[] = [
+	'message' => '#^Cannot cast mixed to int\\.$#',
+	'identifier' => 'cast.int',
+	'count' => 2,
+	'path' => __DIR__ . '/sources/AppBundle/Accounting/Entity/Repository/InvoicingRepository.php',
+];
 $ignoreErrors[] = [
 	'message' => '#^Method AppBundle\\\\Accounting\\\\Entity\\\\Repository\\\\PaymentRepository\\:\\:getAllSortedByName\\(\\) should return array\\<AppBundle\\\\Accounting\\\\Entity\\\\Payment\\> but returns mixed\\.$#',
 	'identifier' => 'return.type',
@@ -235,6 +283,18 @@ $ignoreErrors[] = [
 	'count' => 1,
 	'path' => __DIR__ . '/sources/AppBundle/Accounting/Entity/Repository/RuleRepository.php',
 ];
+$ignoreErrors[] = [
+	'message' => '#^Cannot call method format\\(\\) on DateTime\\|null\\.$#',
+	'identifier' => 'method.nonObject',
+	'count' => 2,
+	'path' => __DIR__ . '/sources/AppBundle/Accounting/Entity/Repository/TransactionRepository.php',
+];
+$ignoreErrors[] = [
+	'message' => '#^Method AppBundle\\\\Accounting\\\\Entity\\\\Repository\\\\TransactionRepository\\:\\:getNextTransaction\\(\\) should return AppBundle\\\\Accounting\\\\Entity\\\\Transaction\\|null but returns mixed\\.$#',
+	'identifier' => 'return.type',
+	'count' => 1,
+	'path' => __DIR__ . '/sources/AppBundle/Accounting/Entity/Repository/TransactionRepository.php',
+];
 $ignoreErrors[] = [
 	'message' => '#^Class AppBundle\\\\Accounting\\\\Form\\\\AccountType extends generic class Symfony\\\\Component\\\\Form\\\\AbstractType but does not specify its types\\: TData$#',
 	'identifier' => 'missingType.generics',
@@ -325,36 +385,6 @@ $ignoreErrors[] = [
 	'count' => 1,
 	'path' => __DIR__ . '/sources/AppBundle/Accounting/Form/TransactionType.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method AppBundle\\\\Accounting\\\\Form\\\\TransactionType\\:\\:buildAccountChoice\\(\\) return type has no value type specified in iterable type array\\.$#',
-	'identifier' => 'missingType.iterableValue',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Form/TransactionType.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method AppBundle\\\\Accounting\\\\Form\\\\TransactionType\\:\\:buildCategoryChoice\\(\\) return type has no value type specified in iterable type array\\.$#',
-	'identifier' => 'missingType.iterableValue',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Form/TransactionType.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method AppBundle\\\\Accounting\\\\Form\\\\TransactionType\\:\\:buildEventChoice\\(\\) return type has no value type specified in iterable type array\\.$#',
-	'identifier' => 'missingType.iterableValue',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Form/TransactionType.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method AppBundle\\\\Accounting\\\\Form\\\\TransactionType\\:\\:buildOperationTypeChoice\\(\\) return type has no value type specified in iterable type array\\.$#',
-	'identifier' => 'missingType.iterableValue',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Form/TransactionType.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method AppBundle\\\\Accounting\\\\Form\\\\TransactionType\\:\\:buildPaymentTypeChoice\\(\\) return type has no value type specified in iterable type array\\.$#',
-	'identifier' => 'missingType.iterableValue',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Form/TransactionType.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Class AppBundle\\\\Accounting\\\\Form\\\\TransactionsImportType extends generic class Symfony\\\\Component\\\\Form\\\\AbstractType but does not specify its types\\: TData$#',
 	'identifier' => 'missingType.generics',
@@ -391,12 +421,6 @@ $ignoreErrors[] = [
 	'count' => 1,
 	'path' => __DIR__ . '/sources/AppBundle/Accounting/InvoicingPdfGenerator.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Parameter \\#1 \\$id of method Afup\\\\Site\\\\Utils\\\\Pays\\:\\:obtenirNom\\(\\) expects string, string\\|null given\\.$#',
-	'identifier' => 'argument.type',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/InvoicingPdfGenerator.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Parameter \\#1 \\$num of function number_format expects float, float\\|null given\\.$#',
 	'identifier' => 'argument.type',
@@ -409,150 +433,6 @@ $ignoreErrors[] = [
 	'count' => 1,
 	'path' => __DIR__ . '/sources/AppBundle/Accounting/InvoicingPdfGenerator.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Property AppBundle\\\\Accounting\\\\Model\\\\Invoicing\\:\\:\\$countryId \\(string\\) does not accept string\\|null\\.$#',
-	'identifier' => 'assign.propertyType',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Model/Invoicing.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot access offset \'id\' on mixed\\.$#',
-	'identifier' => 'offsetAccess.nonOffsetAccessible',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Model/Repository/InvoicingDetailRepository.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method AppBundle\\\\Accounting\\\\Model\\\\Repository\\\\InvoicingDetailRepository\\:\\:getRowsIdsPerInvoicingId\\(\\) return type has no value type specified in iterable type array\\.$#',
-	'identifier' => 'missingType.iterableValue',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Model/Repository/InvoicingDetailRepository.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method AppBundle\\\\Accounting\\\\Model\\\\Repository\\\\InvoicingDetailRepository\\:\\:initMetadata\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#',
-	'identifier' => 'missingType.iterableValue',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Model/Repository/InvoicingDetailRepository.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method AppBundle\\\\Accounting\\\\Model\\\\Repository\\\\InvoicingDetailRepository\\:\\:initMetadata\\(\\) should return M of CCMBenchmark\\\\Ting\\\\Repository\\\\Metadata but returns CCMBenchmark\\\\Ting\\\\Repository\\\\Metadata\\<object\\>\\.$#',
-	'identifier' => 'return.type',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Model/Repository/InvoicingDetailRepository.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Parameter \\#1 \\$databaseName of method CCMBenchmark\\\\Ting\\\\Repository\\\\Metadata\\<object\\>\\:\\:setDatabase\\(\\) expects string, mixed given\\.$#',
-	'identifier' => 'argument.type',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Model/Repository/InvoicingDetailRepository.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method AppBundle\\\\Accounting\\\\Model\\\\Repository\\\\InvoicingPeriodRepository\\:\\:getCurrentPeriod\\(\\) should return AppBundle\\\\Accounting\\\\Model\\\\InvoicingPeriod but returns AppBundle\\\\Accounting\\\\Model\\\\InvoicingPeriod\\|null\\.$#',
-	'identifier' => 'return.type',
-	'count' => 2,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Model/Repository/InvoicingPeriodRepository.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method AppBundle\\\\Accounting\\\\Model\\\\Repository\\\\InvoicingPeriodRepository\\:\\:initMetadata\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#',
-	'identifier' => 'missingType.iterableValue',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Model/Repository/InvoicingPeriodRepository.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method AppBundle\\\\Accounting\\\\Model\\\\Repository\\\\InvoicingPeriodRepository\\:\\:initMetadata\\(\\) should return M of CCMBenchmark\\\\Ting\\\\Repository\\\\Metadata but returns CCMBenchmark\\\\Ting\\\\Repository\\\\Metadata\\<object\\>\\.$#',
-	'identifier' => 'return.type',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Model/Repository/InvoicingPeriodRepository.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Parameter \\#1 \\$databaseName of method CCMBenchmark\\\\Ting\\\\Repository\\\\Metadata\\<object\\>\\:\\:setDatabase\\(\\) expects string, mixed given\\.$#',
-	'identifier' => 'argument.type',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Model/Repository/InvoicingPeriodRepository.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot access offset \'next_index\' on mixed\\.$#',
-	'identifier' => 'offsetAccess.nonOffsetAccessible',
-	'count' => 2,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Model/Repository/InvoicingRepository.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot cast mixed to int\\.$#',
-	'identifier' => 'cast.int',
-	'count' => 2,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Model/Repository/InvoicingRepository.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method AppBundle\\\\Accounting\\\\Model\\\\Repository\\\\InvoicingRepository\\:\\:findOneWithDetails\\(\\) has parameter \\$params with no value type specified in iterable type array\\.$#',
-	'identifier' => 'missingType.iterableValue',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Model/Repository/InvoicingRepository.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method AppBundle\\\\Accounting\\\\Model\\\\Repository\\\\InvoicingRepository\\:\\:getInvoicesByPeriodId\\(\\) return type with generic interface CCMBenchmark\\\\Ting\\\\Repository\\\\CollectionInterface does not specify its types\\: T$#',
-	'identifier' => 'missingType.generics',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Model/Repository/InvoicingRepository.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method AppBundle\\\\Accounting\\\\Model\\\\Repository\\\\InvoicingRepository\\:\\:getQuotationsByPeriodId\\(\\) return type with generic interface CCMBenchmark\\\\Ting\\\\Repository\\\\CollectionInterface does not specify its types\\: T$#',
-	'identifier' => 'missingType.generics',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Model/Repository/InvoicingRepository.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method AppBundle\\\\Accounting\\\\Model\\\\Repository\\\\InvoicingRepository\\:\\:initMetadata\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#',
-	'identifier' => 'missingType.iterableValue',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Model/Repository/InvoicingRepository.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method AppBundle\\\\Accounting\\\\Model\\\\Repository\\\\InvoicingRepository\\:\\:initMetadata\\(\\) should return M of CCMBenchmark\\\\Ting\\\\Repository\\\\Metadata but returns CCMBenchmark\\\\Ting\\\\Repository\\\\Metadata\\<object\\>\\.$#',
-	'identifier' => 'return.type',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Model/Repository/InvoicingRepository.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Parameter \\#1 \\$databaseName of method CCMBenchmark\\\\Ting\\\\Repository\\\\Metadata\\<object\\>\\:\\:setDatabase\\(\\) expects string, mixed given\\.$#',
-	'identifier' => 'argument.type',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Model/Repository/InvoicingRepository.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot call method format\\(\\) on DateTime\\|null\\.$#',
-	'identifier' => 'method.nonObject',
-	'count' => 2,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Model/Repository/TransactionRepository.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method AppBundle\\\\Accounting\\\\Model\\\\Repository\\\\TransactionRepository\\:\\:getEntriesPerInvoicingPeriod\\(\\) has no return type specified\\.$#',
-	'identifier' => 'missingType.return',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Model/Repository/TransactionRepository.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method AppBundle\\\\Accounting\\\\Model\\\\Repository\\\\TransactionRepository\\:\\:getNextTransaction\\(\\) should return AppBundle\\\\Accounting\\\\Model\\\\Transaction\\|null but returns mixed\\.$#',
-	'identifier' => 'return.type',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Model/Repository/TransactionRepository.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method AppBundle\\\\Accounting\\\\Model\\\\Repository\\\\TransactionRepository\\:\\:initMetadata\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#',
-	'identifier' => 'missingType.iterableValue',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Model/Repository/TransactionRepository.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method AppBundle\\\\Accounting\\\\Model\\\\Repository\\\\TransactionRepository\\:\\:initMetadata\\(\\) should return M of CCMBenchmark\\\\Ting\\\\Repository\\\\Metadata but returns CCMBenchmark\\\\Ting\\\\Repository\\\\Metadata\\<object\\>\\.$#',
-	'identifier' => 'return.type',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Model/Repository/TransactionRepository.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Parameter \\#1 \\$databaseName of method CCMBenchmark\\\\Ting\\\\Repository\\\\Metadata\\<object\\>\\:\\:setDatabase\\(\\) expects string, mixed given\\.$#',
-	'identifier' => 'argument.type',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Accounting/Model/Repository/TransactionRepository.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Cannot cast mixed to int\\.$#',
 	'identifier' => 'cast.int',
@@ -560,8 +440,8 @@ $ignoreErrors[] = [
 	'path' => __DIR__ . '/sources/AppBundle/Accounting/TransactionModification.php',
 ];
 $ignoreErrors[] = [
-	'message' => '#^Parameter \\#1 \\$comment of method AppBundle\\\\Accounting\\\\Model\\\\Transaction\\:\\:setComment\\(\\) expects string\\|null, mixed given\\.$#',
-	'identifier' => 'argument.type',
+	'message' => '#^Property AppBundle\\\\Accounting\\\\Entity\\\\Transaction\\:\\:\\$commentaire \\(string\\|null\\) does not accept mixed\\.$#',
+	'identifier' => 'assign.propertyType',
 	'count' => 1,
 	'path' => __DIR__ . '/sources/AppBundle/Accounting/TransactionModification.php',
 ];
@@ -2263,48 +2143,6 @@ $ignoreErrors[] = [
 	'count' => 1,
 	'path' => __DIR__ . '/sources/AppBundle/Command/VideosDataCommand.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Parameter \\#1 \\$amount of method AppBundle\\\\Accounting\\\\Model\\\\Transaction\\:\\:setAmount\\(\\) expects float, mixed given\\.$#',
-	'identifier' => 'argument.type',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Compta/CsvExtractor.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Parameter \\#1 \\$amountTva0 of method AppBundle\\\\Accounting\\\\Model\\\\Transaction\\:\\:setAmountTva0\\(\\) expects float\\|null, mixed given\\.$#',
-	'identifier' => 'argument.type',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Compta/CsvExtractor.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Parameter \\#1 \\$amountTva10 of method AppBundle\\\\Accounting\\\\Model\\\\Transaction\\:\\:setAmountTva10\\(\\) expects float\\|null, mixed given\\.$#',
-	'identifier' => 'argument.type',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Compta/CsvExtractor.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Parameter \\#1 \\$amountTva20 of method AppBundle\\\\Accounting\\\\Model\\\\Transaction\\:\\:setAmountTva20\\(\\) expects float\\|null, mixed given\\.$#',
-	'identifier' => 'argument.type',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Compta/CsvExtractor.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Parameter \\#1 \\$amountTva5_5 of method AppBundle\\\\Accounting\\\\Model\\\\Transaction\\:\\:setAmountTva55\\(\\) expects float\\|null, mixed given\\.$#',
-	'identifier' => 'argument.type',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Compta/CsvExtractor.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Parameter \\#1 \\$attachmentRequired of method AppBundle\\\\Accounting\\\\Model\\\\Transaction\\:\\:setAttachmentRequired\\(\\) expects bool, mixed given\\.$#',
-	'identifier' => 'argument.type',
-	'count' => 2,
-	'path' => __DIR__ . '/sources/AppBundle/Compta/CsvExtractor.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Parameter \\#1 \\$categoryId of method AppBundle\\\\Accounting\\\\Model\\\\Transaction\\:\\:setCategoryId\\(\\) expects int\\|null, mixed given\\.$#',
-	'identifier' => 'argument.type',
-	'count' => 2,
-	'path' => __DIR__ . '/sources/AppBundle/Compta/CsvExtractor.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Parameter \\#1 \\$datetime of class DateTime constructor expects string, mixed given\\.$#',
 	'identifier' => 'argument.type',
@@ -2312,26 +2150,44 @@ $ignoreErrors[] = [
 	'path' => __DIR__ . '/sources/AppBundle/Compta/CsvExtractor.php',
 ];
 $ignoreErrors[] = [
-	'message' => '#^Parameter \\#1 \\$description of method AppBundle\\\\Accounting\\\\Model\\\\Transaction\\:\\:setDescription\\(\\) expects string, mixed given\\.$#',
-	'identifier' => 'argument.type',
+	'message' => '#^Property AppBundle\\\\Accounting\\\\Entity\\\\Transaction\\:\\:\\$description \\(string\\) does not accept mixed\\.$#',
+	'identifier' => 'assign.propertyType',
 	'count' => 1,
 	'path' => __DIR__ . '/sources/AppBundle/Compta/CsvExtractor.php',
 ];
 $ignoreErrors[] = [
-	'message' => '#^Parameter \\#1 \\$eventId of method AppBundle\\\\Accounting\\\\Model\\\\Transaction\\:\\:setEventId\\(\\) expects int\\|null, mixed given\\.$#',
-	'identifier' => 'argument.type',
+	'message' => '#^Property AppBundle\\\\Accounting\\\\Entity\\\\Transaction\\:\\:\\$justificatifRequis \\(bool\\) does not accept mixed\\.$#',
+	'identifier' => 'assign.propertyType',
 	'count' => 2,
 	'path' => __DIR__ . '/sources/AppBundle/Compta/CsvExtractor.php',
 ];
 $ignoreErrors[] = [
-	'message' => '#^Parameter \\#1 \\$operationId of method AppBundle\\\\Accounting\\\\Model\\\\Transaction\\:\\:setOperationId\\(\\) expects int\\|null, mixed given\\.$#',
-	'identifier' => 'argument.type',
+	'message' => '#^Property AppBundle\\\\Accounting\\\\Entity\\\\Transaction\\:\\:\\$montant \\(float\\) does not accept mixed\\.$#',
+	'identifier' => 'assign.propertyType',
 	'count' => 1,
 	'path' => __DIR__ . '/sources/AppBundle/Compta/CsvExtractor.php',
 ];
 $ignoreErrors[] = [
-	'message' => '#^Parameter \\#1 \\$paymentTypeId of method AppBundle\\\\Accounting\\\\Model\\\\Transaction\\:\\:setPaymentTypeId\\(\\) expects int\\|null, mixed given\\.$#',
-	'identifier' => 'argument.type',
+	'message' => '#^Property AppBundle\\\\Accounting\\\\Entity\\\\Transaction\\:\\:\\$montantTva0 \\(float\\|null\\) does not accept mixed\\.$#',
+	'identifier' => 'assign.propertyType',
+	'count' => 1,
+	'path' => __DIR__ . '/sources/AppBundle/Compta/CsvExtractor.php',
+];
+$ignoreErrors[] = [
+	'message' => '#^Property AppBundle\\\\Accounting\\\\Entity\\\\Transaction\\:\\:\\$montantTva10 \\(float\\|null\\) does not accept mixed\\.$#',
+	'identifier' => 'assign.propertyType',
+	'count' => 1,
+	'path' => __DIR__ . '/sources/AppBundle/Compta/CsvExtractor.php',
+];
+$ignoreErrors[] = [
+	'message' => '#^Property AppBundle\\\\Accounting\\\\Entity\\\\Transaction\\:\\:\\$montantTva20 \\(float\\|null\\) does not accept mixed\\.$#',
+	'identifier' => 'assign.propertyType',
+	'count' => 1,
+	'path' => __DIR__ . '/sources/AppBundle/Compta/CsvExtractor.php',
+];
+$ignoreErrors[] = [
+	'message' => '#^Property AppBundle\\\\Accounting\\\\Entity\\\\Transaction\\:\\:\\$montantTva5_5 \\(float\\|null\\) does not accept mixed\\.$#',
+	'identifier' => 'assign.propertyType',
 	'count' => 1,
 	'path' => __DIR__ . '/sources/AppBundle/Compta/CsvExtractor.php',
 ];
@@ -2456,7 +2312,7 @@ $ignoreErrors[] = [
 	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Configuration/EditRuleAction.php',
 ];
 $ignoreErrors[] = [
-	'message' => '#^Parameter \\#1 \\$number of method AppBundle\\\\Accounting\\\\Model\\\\Repository\\\\InvoicingRepository\\:\\:getOneByInvoiceNumber\\(\\) expects string, string\\|null given\\.$#',
+	'message' => '#^Parameter \\#1 \\$number of method AppBundle\\\\Accounting\\\\Entity\\\\Repository\\\\InvoicingRepository\\:\\:getOneByInvoiceNumber\\(\\) expects string, string\\|null given\\.$#',
 	'identifier' => 'argument.type',
 	'count' => 1,
 	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Invoice/DownloadInvoiceAction.php',
@@ -2468,95 +2324,11 @@ $ignoreErrors[] = [
 	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Invoice/ListInvoiceAction.php',
 ];
 $ignoreErrors[] = [
-	'message' => '#^Parameter \\#1 \\$number of method AppBundle\\\\Accounting\\\\Model\\\\Repository\\\\InvoicingRepository\\:\\:getOneByInvoiceNumber\\(\\) expects string, string\\|null given\\.$#',
+	'message' => '#^Parameter \\#1 \\$number of method AppBundle\\\\Accounting\\\\Entity\\\\Repository\\\\InvoicingRepository\\:\\:getOneByInvoiceNumber\\(\\) expects string, string\\|null given\\.$#',
 	'identifier' => 'argument.type',
 	'count' => 1,
 	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Invoice/SendInvoiceEmailAction.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Cannot call method getAccountId\\(\\) on AppBundle\\\\Accounting\\\\Model\\\\Transaction\\|null\\.$#',
-	'identifier' => 'method.nonObject',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/AllocateAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot call method getAccountingDate\\(\\) on AppBundle\\\\Accounting\\\\Model\\\\Transaction\\|null\\.$#',
-	'identifier' => 'method.nonObject',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/AllocateAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot call method getAmount\\(\\) on AppBundle\\\\Accounting\\\\Model\\\\Transaction\\|null\\.$#',
-	'identifier' => 'method.nonObject',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/AllocateAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot call method getComment\\(\\) on AppBundle\\\\Accounting\\\\Model\\\\Transaction\\|null\\.$#',
-	'identifier' => 'method.nonObject',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/AllocateAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot call method getDescription\\(\\) on AppBundle\\\\Accounting\\\\Model\\\\Transaction\\|null\\.$#',
-	'identifier' => 'method.nonObject',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/AllocateAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot call method getNumber\\(\\) on AppBundle\\\\Accounting\\\\Model\\\\Transaction\\|null\\.$#',
-	'identifier' => 'method.nonObject',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/AllocateAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot call method getOperationId\\(\\) on AppBundle\\\\Accounting\\\\Model\\\\Transaction\\|null\\.$#',
-	'identifier' => 'method.nonObject',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/AllocateAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot call method getOperationNumber\\(\\) on AppBundle\\\\Accounting\\\\Model\\\\Transaction\\|null\\.$#',
-	'identifier' => 'method.nonObject',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/AllocateAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot call method getPaymentDate\\(\\) on AppBundle\\\\Accounting\\\\Model\\\\Transaction\\|null\\.$#',
-	'identifier' => 'method.nonObject',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/AllocateAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot call method getPaymentTypeId\\(\\) on AppBundle\\\\Accounting\\\\Model\\\\Transaction\\|null\\.$#',
-	'identifier' => 'method.nonObject',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/AllocateAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot call method getTvaIntra\\(\\) on AppBundle\\\\Accounting\\\\Model\\\\Transaction\\|null\\.$#',
-	'identifier' => 'method.nonObject',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/AllocateAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot call method getVendorName\\(\\) on AppBundle\\\\Accounting\\\\Model\\\\Transaction\\|null\\.$#',
-	'identifier' => 'method.nonObject',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/AllocateAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot call method setAmount\\(\\) on AppBundle\\\\Accounting\\\\Model\\\\Transaction\\|null\\.$#',
-	'identifier' => 'method.nonObject',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/AllocateAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Parameter \\#1 \\$entity of method CCMBenchmark\\\\Ting\\\\Repository\\\\Repository\\<AppBundle\\\\Accounting\\\\Model\\\\Transaction\\>\\:\\:save\\(\\) expects AppBundle\\\\Accounting\\\\Model\\\\Transaction, AppBundle\\\\Accounting\\\\Model\\\\Transaction\\|null given\\.$#',
-	'identifier' => 'argument.type',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/AllocateAction.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Cannot call method format\\(\\) on DateTime\\|null\\.$#',
 	'identifier' => 'method.nonObject',
@@ -2576,149 +2348,17 @@ $ignoreErrors[] = [
 	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/DownloadAttachmentsAction.php',
 ];
 $ignoreErrors[] = [
-	'message' => '#^Cannot call method getId\\(\\) on AppBundle\\\\Accounting\\\\Model\\\\Transaction\\|null\\.$#',
-	'identifier' => 'method.nonObject',
+	'message' => '#^Cannot access property \\$id on AppBundle\\\\Accounting\\\\Entity\\\\Transaction\\|null\\.$#',
+	'identifier' => 'property.nonObject',
 	'count' => 2,
 	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/EditTransactionAction.php',
 ];
 $ignoreErrors[] = [
-	'message' => '#^Parameter \\#1 \\$transactionId of method AppBundle\\\\Accounting\\\\Model\\\\Repository\\\\TransactionRepository\\:\\:getNextTransaction\\(\\) expects int, int\\|null given\\.$#',
+	'message' => '#^Parameter \\#1 \\$transactionId of method AppBundle\\\\Accounting\\\\Entity\\\\Repository\\\\TransactionRepository\\:\\:getNextTransaction\\(\\) expects int, int\\|null given\\.$#',
 	'identifier' => 'argument.type',
 	'count' => 1,
 	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/EditTransactionAction.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\\.$#',
-	'identifier' => 'foreach.nonIterable',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/ExportAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot access offset \'attachment_filename\' on mixed\\.$#',
-	'identifier' => 'offsetAccess.nonOffsetAccessible',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/ExportAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot access offset \'attachment_required\' on mixed\\.$#',
-	'identifier' => 'offsetAccess.nonOffsetAccessible',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/ExportAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot access offset \'categorie\' on mixed\\.$#',
-	'identifier' => 'offsetAccess.nonOffsetAccessible',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/ExportAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot access offset \'comment\' on mixed\\.$#',
-	'identifier' => 'offsetAccess.nonOffsetAccessible',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/ExportAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot access offset \'date_ecriture\' on mixed\\.$#',
-	'identifier' => 'offsetAccess.nonOffsetAccessible',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/ExportAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot access offset \'description\' on mixed\\.$#',
-	'identifier' => 'offsetAccess.nonOffsetAccessible',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/ExportAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot access offset \'evenement\' on mixed\\.$#',
-	'identifier' => 'offsetAccess.nonOffsetAccessible',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/ExportAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot access offset \'idoperation\' on mixed\\.$#',
-	'identifier' => 'offsetAccess.nonOffsetAccessible',
-	'count' => 2,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/ExportAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot access offset \'montant\' on mixed\\.$#',
-	'identifier' => 'offsetAccess.nonOffsetAccessible',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/ExportAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot access offset \'montant_ht\' on mixed\\.$#',
-	'identifier' => 'offsetAccess.nonOffsetAccessible',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/ExportAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot access offset \'montant_ht_0\' on mixed\\.$#',
-	'identifier' => 'offsetAccess.nonOffsetAccessible',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/ExportAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot access offset \'montant_ht_10\' on mixed\\.$#',
-	'identifier' => 'offsetAccess.nonOffsetAccessible',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/ExportAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot access offset \'montant_ht_20\' on mixed\\.$#',
-	'identifier' => 'offsetAccess.nonOffsetAccessible',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/ExportAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot access offset \'montant_ht_5_5\' on mixed\\.$#',
-	'identifier' => 'offsetAccess.nonOffsetAccessible',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/ExportAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot access offset \'montant_tva\' on mixed\\.$#',
-	'identifier' => 'offsetAccess.nonOffsetAccessible',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/ExportAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot access offset \'montant_tva_10\' on mixed\\.$#',
-	'identifier' => 'offsetAccess.nonOffsetAccessible',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/ExportAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot access offset \'montant_tva_20\' on mixed\\.$#',
-	'identifier' => 'offsetAccess.nonOffsetAccessible',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/ExportAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot access offset \'montant_tva_5_5\' on mixed\\.$#',
-	'identifier' => 'offsetAccess.nonOffsetAccessible',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/ExportAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot access offset \'nom_compte\' on mixed\\.$#',
-	'identifier' => 'offsetAccess.nonOffsetAccessible',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/ExportAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot access offset \'reglement\' on mixed\\.$#',
-	'identifier' => 'offsetAccess.nonOffsetAccessible',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/ExportAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Cannot access offset \'tva_zone\' on mixed\\.$#',
-	'identifier' => 'offsetAccess.nonOffsetAccessible',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Journal/ExportAction.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Cannot call method format\\(\\) on DateTime\\|null\\.$#',
 	'identifier' => 'method.nonObject',
@@ -2834,29 +2474,11 @@ $ignoreErrors[] = [
 	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/MembershipFee/EditMembershipFeeAction.php',
 ];
 $ignoreErrors[] = [
-	'message' => '#^Parameter \\#1 \\$number of method AppBundle\\\\Accounting\\\\Model\\\\Repository\\\\InvoicingRepository\\:\\:getOneByQuotationNumber\\(\\) expects string, string\\|null given\\.$#',
+	'message' => '#^Parameter \\#1 \\$number of method AppBundle\\\\Accounting\\\\Entity\\\\Repository\\\\InvoicingRepository\\:\\:getOneByQuotationNumber\\(\\) expects string, string\\|null given\\.$#',
 	'identifier' => 'argument.type',
 	'count' => 1,
 	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Quotation/DownloadQuotationAction.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Parameter \\#1 \\$array of function array_diff expects an array of values castable to string, array given\\.$#',
-	'identifier' => 'argument.type',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Quotation/EditQuotationAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Parameter \\#1 \\$ids of method AppBundle\\\\Accounting\\\\Model\\\\Repository\\\\InvoicingDetailRepository\\:\\:removeRowsPerIds\\(\\) expects array\\<int\\>, array given\\.$#',
-	'identifier' => 'argument.type',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Quotation/EditQuotationAction.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Parameter \\#1 \\$invoicingId of method AppBundle\\\\Accounting\\\\Model\\\\Repository\\\\InvoicingDetailRepository\\:\\:getRowsIdsPerInvoicingId\\(\\) expects int, int\\|null given\\.$#',
-	'identifier' => 'argument.type',
-	'count' => 1,
-	'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Accounting/Quotation/EditQuotationAction.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Parameter \\#1 \\$date of static method Afup\\\\Site\\\\Utils\\\\Vat\\:\\:isSubjectedToVat\\(\\) expects DateTimeInterface, DateTime\\|null given\\.$#',
 	'identifier' => 'argument.type',
diff --git c/sources/AppBundle/Accounting/Entity/Invoicing.php i/sources/AppBundle/Accounting/Entity/Invoicing.php
new file mode 100644
index 000000000..952fd7463
--- /dev/null
+++ i/sources/AppBundle/Accounting/Entity/Invoicing.php
@@ -0,0 +1,118 @@
+<?php
+
+declare(strict_types=1);
+
+namespace AppBundle\Accounting\Entity;
+
+use Afup\Site\Utils\Utils;
+use AppBundle\Accounting\Entity\Repository\InvoicingRepository;
+use AppBundle\Accounting\InvoicingCurrency;
+use AppBundle\Accounting\InvoicingPaymentStatus;
+use Doctrine\Common\Collections\ArrayCollection;
+use Doctrine\Common\Collections\Collection;
+use Doctrine\ORM\Mapping as ORM;
+use Symfony\Component\Validator\Constraints as Assert;
+
+#[ORM\Entity(repositoryClass: InvoicingRepository::class)]
+#[ORM\Table(name: 'afup_compta_facture')]
+class Invoicing
+{
+    #[ORM\Id]
+    #[ORM\GeneratedValue]
+    #[ORM\Column]
+    public ?int $id = null;
+
+    #[ORM\Column(name: 'date_devis', nullable: true)]
+    public ?\DateTime $dateDevis = null;
+
+    #[ORM\Column(name: 'numero_devis', nullable: true)]
+    public ?string $numeroDevis = null;
+
+    #[ORM\Column(name: 'date_facture', nullable: true)]
+    public ?\DateTime $dateFacture = null;
+
+    #[ORM\Column(name: 'numero_facture', nullable: true)]
+    public ?string $numeroFacture = null;
+
+    #[ORM\Column(name: 'societe', length: 50, nullable: false)]
+    public string $societe = '';
+
+    #[ORM\Column(name: 'service', length: 50, nullable: false)]
+    public string $service = '';
+
+    #[ORM\Column(name: 'adresse', type: 'text', nullable: false)]
+    public string $adresse = '';
+
+    #[ORM\Column(name: 'code_postal', length: 10, nullable: false)]
+    public string $codePostal = '';
+
+    #[ORM\Column(name: 'ville', length: 50, nullable: false)]
+    public string $ville = '';
+
+    #[ORM\Column(name: 'id_pays', length: 10, nullable: false)]
+    public string $idPays = '';
+
+    #[ORM\Column(length: 100, nullable: false)]
+    public string $email = '';
+
+    #[ORM\Column(name: 'tva_intra', length: 20, nullable: true)]
+    public ?string $tvaIntra = null;
+
+    #[ORM\Column(type: 'text', nullable: false)]
+    public string $observation = '';
+
+    #[ORM\Column(name: 'ref_clt1', length: 50, nullable: false)]
+    public string $referenceClient1 = '';
+
+    #[ORM\Column(name: 'ref_clt2', length: 50, nullable: false)]
+    public string $referenceClient2 = '';
+
+    #[ORM\Column(name: 'ref_clt3', length: 50, nullable: false)]
+    public string $referenceClient3 = '';
+
+    #[ORM\Column(name: 'nom', length: 50, nullable: false)]
+    public string $nom = '';
+
+    #[ORM\Column(name: 'prenom', length: 50, nullable: false)]
+    public string $prenom = '';
+
+    #[ORM\Column(name: 'tel', length: 30, nullable: false)]
+    public string $telephone = '';
+
+    #[ORM\Column(name: 'etat_paiement', nullable: false, enumType: InvoicingPaymentStatus::class)]
+    public InvoicingPaymentStatus $etatPaiement = InvoicingPaymentStatus::Waiting;
+
+    #[ORM\Column(name: 'date_paiement', nullable: true)]
+    public ?\DateTime $datePaiement = null;
+
+    #[ORM\Column(name: 'devise_facture', nullable: true, enumType: InvoicingCurrency::class)]
+    public ?InvoicingCurrency $deviseFacture = null;
+
+    /** @var Collection<int, InvoicingDetail> */
+    #[Assert\Valid]
+    #[ORM\OneToMany(targetEntity: InvoicingDetail::class, mappedBy: 'facture', cascade: ['persist', 'remove'], orphanRemoval: true)]
+    public Collection $details;
+
+    // Non persistee - total calcule depuis les lignes de detail, alimente par les requetes de listing
+    public ?float $prix = null;
+
+    public function __construct()
+    {
+        $this->details = new ArrayCollection();
+    }
+
+    public function addDetail(InvoicingDetail $detail): void
+    {
+        $this->details->add($detail);
+        $detail->facture = $this;
+    }
+
+    public function getPaymentUrlRef(): string
+    {
+        if (empty($this->numeroFacture)) {
+            return '';
+        }
+
+        return urlencode(Utils::cryptFromText($this->id));
+    }
+}
diff --git c/sources/AppBundle/Accounting/Entity/InvoicingDetail.php i/sources/AppBundle/Accounting/Entity/InvoicingDetail.php
new file mode 100644
index 000000000..22c7a6660
--- /dev/null
+++ i/sources/AppBundle/Accounting/Entity/InvoicingDetail.php
@@ -0,0 +1,44 @@
+<?php
+
+declare(strict_types=1);
+
+namespace AppBundle\Accounting\Entity;
+
+use Doctrine\ORM\Mapping as ORM;
+use Symfony\Component\Validator\Constraints as Assert;
+
+#[ORM\Entity]
+#[ORM\Table(name: 'afup_compta_facture_details')]
+class InvoicingDetail
+{
+    #[ORM\Id]
+    #[ORM\GeneratedValue]
+    #[ORM\Column]
+    public ?int $id = null;
+
+    #[ORM\ManyToOne(targetEntity: Invoicing::class, inversedBy: 'details')]
+    #[ORM\JoinColumn(name: 'idafup_compta_facture', referencedColumnName: 'id', nullable: false)]
+    public Invoicing $facture;
+
+    #[Assert\NotBlank]
+    #[Assert\Length(max: 20)]
+    #[ORM\Column(name: 'ref', length: 50, nullable: false)]
+    public ?string $reference = null;
+
+    #[Assert\NotBlank]
+    #[Assert\Length(max: 100)]
+    #[ORM\Column(length: 100, nullable: false)]
+    public ?string $designation = null;
+
+    #[Assert\NotBlank]
+    #[ORM\Column(name: 'quantite', type: 'float', nullable: false)]
+    public ?float $quantite = null;
+
+    #[Assert\NotBlank]
+    #[ORM\Column(name: 'pu', type: 'float', nullable: false)]
+    public ?float $prixUnitaire = null;
+
+    #[Assert\NotBlank]
+    #[ORM\Column(type: 'float', nullable: true)]
+    public ?float $tva = null;
+}
diff --git c/sources/AppBundle/Accounting/Entity/InvoicingPeriod.php i/sources/AppBundle/Accounting/Entity/InvoicingPeriod.php
new file mode 100644
index 000000000..c31ff7ffa
--- /dev/null
+++ i/sources/AppBundle/Accounting/Entity/InvoicingPeriod.php
@@ -0,0 +1,27 @@
+<?php
+
+declare(strict_types=1);
+
+namespace AppBundle\Accounting\Entity;
+
+use AppBundle\Accounting\Entity\Repository\InvoicingPeriodRepository;
+use Doctrine\ORM\Mapping as ORM;
+
+#[ORM\Entity(repositoryClass: InvoicingPeriodRepository::class)]
+#[ORM\Table(name: 'compta_periode')]
+class InvoicingPeriod
+{
+    #[ORM\Id]
+    #[ORM\GeneratedValue]
+    #[ORM\Column]
+    public ?int $id = null;
+
+    #[ORM\Column(name: 'date_debut', nullable: true)]
+    public ?\DateTime $dateDebut = null;
+
+    #[ORM\Column(name: 'date_fin', nullable: true)]
+    public ?\DateTime $dateFin = null;
+
+    #[ORM\Column(name: 'verouiller', nullable: true)]
+    public ?bool $verrouille = false;
+}
diff --git c/sources/AppBundle/Accounting/Entity/Repository/InvoicingPeriodRepository.php i/sources/AppBundle/Accounting/Entity/Repository/InvoicingPeriodRepository.php
new file mode 100644
index 000000000..c02160edc
--- /dev/null
+++ i/sources/AppBundle/Accounting/Entity/Repository/InvoicingPeriodRepository.php
@@ -0,0 +1,43 @@
+<?php
+
+declare(strict_types=1);
+
+namespace AppBundle\Accounting\Entity\Repository;
+
+use AppBundle\Accounting\Entity\InvoicingPeriod;
+use AppBundle\Doctrine\EntityRepository;
+use Doctrine\Persistence\ManagerRegistry;
+
+/**
+ * @extends EntityRepository<InvoicingPeriod>
+ */
+final class InvoicingPeriodRepository extends EntityRepository
+{
+    public function __construct(ManagerRegistry $registry)
+    {
+        parent::__construct($registry, InvoicingPeriod::class);
+    }
+
+    public function getCurrentPeriod(?int $periodId = null): InvoicingPeriod
+    {
+        if ($periodId !== null) {
+            return $this->find($periodId);
+        }
+
+        $startDate = new \DateTime(date('Y') . '-01-01');
+        $endDate = new \DateTime(date('Y') . '-12-31');
+        $period = $this->findOneBy([
+            'dateDebut' => $startDate,
+            'dateFin' => $endDate,
+        ]);
+
+        if (!$period instanceof InvoicingPeriod) {
+            $period = new InvoicingPeriod();
+            $period->dateDebut = $startDate;
+            $period->dateFin = $endDate;
+            $this->save($period);
+        }
+
+        return $period;
+    }
+}
diff --git c/sources/AppBundle/Accounting/Entity/Repository/InvoicingRepository.php i/sources/AppBundle/Accounting/Entity/Repository/InvoicingRepository.php
new file mode 100644
index 000000000..ca5574973
--- /dev/null
+++ i/sources/AppBundle/Accounting/Entity/Repository/InvoicingRepository.php
@@ -0,0 +1,127 @@
+<?php
+
+declare(strict_types=1);
+
+namespace AppBundle\Accounting\Entity\Repository;
+
+use AppBundle\Accounting\Entity\Invoicing;
+use AppBundle\Doctrine\EntityRepository;
+use Doctrine\Persistence\ManagerRegistry;
+
+/**
+ * @extends EntityRepository<Invoicing>
+ */
+final class InvoicingRepository extends EntityRepository
+{
+    public function __construct(
+        ManagerRegistry $registry,
+        private readonly InvoicingPeriodRepository $invoicingPeriodRepository,
+    ) {
+        parent::__construct($registry, Invoicing::class);
+    }
+
+    public function getById(int $id): ?Invoicing
+    {
+        return $this->find($id);
+    }
+
+    public function getOneByInvoiceNumber(string $number): ?Invoicing
+    {
+        return $this->findOneBy(['numeroFacture' => $number]);
+    }
+
+    public function getOneByQuotationNumber(string $number): ?Invoicing
+    {
+        return $this->findOneBy(['numeroDevis' => $number]);
+    }
+
+    /**
+     * @return array<Invoicing>
+     */
+    public function getQuotationsByPeriodId(?int $periodId = null, string $sort = 'date', string $direction = 'desc'): array
+    {
+        $field = $sort === 'client' ? 'i.societe' : 'i.dateDevis';
+
+        $qb = $this->createQueryBuilder('i')
+            ->addSelect('SUM(d.quantite * d.prixUnitaire) as prix')
+            ->leftJoin('i.details', 'd')
+            ->where("i.numeroDevis != ''")
+            ->groupBy('i.id')
+            ->orderBy($field, $direction);
+
+        if ($periodId !== null && $periodId !== 0) {
+            $period = $this->invoicingPeriodRepository->find($periodId);
+            $qb->andWhere('i.dateDevis >= :periodStart')
+                ->andWhere('i.dateDevis <= :periodEnd')
+                ->setParameter('periodStart', $period->dateDebut)
+                ->setParameter('periodEnd', $period->dateFin);
+        }
+
+        return $this->mapRowsToInvoicings($qb->getQuery()->getResult());
+    }
+
+    /**
+     * @return array<Invoicing>
+     */
+    public function getInvoicesByPeriodId(?int $periodId = null, string $sort = 'date', string $direction = 'desc'): array
+    {
+        $field = $sort === 'client' ? 'i.societe' : 'i.dateFacture';
+
+        $qb = $this->createQueryBuilder('i')
+            ->addSelect('SUM(d.quantite * d.prixUnitaire) as prix')
+            ->leftJoin('i.details', 'd')
+            ->where("i.numeroFacture != ''")
+            ->groupBy('i.id')
+            ->orderBy($field, $direction);
+
+        if ($periodId !== null && $periodId !== 0) {
+            $period = $this->invoicingPeriodRepository->find($periodId);
+            $qb->andWhere('i.dateFacture >= :periodStart')
+                ->andWhere('i.dateFacture <= :periodEnd')
+                ->setParameter('periodStart', $period->dateDebut)
+                ->setParameter('periodEnd', $period->dateFin);
+        }
+
+        return $this->mapRowsToInvoicings($qb->getQuery()->getResult());
+    }
+
+    public function getNextInvoiceIndex(int $year): ?int
+    {
+        $result = $this->getEntityManager()->getConnection()->executeQuery(
+            "SELECT MAX(CAST(SUBSTRING_INDEX(numero_facture, '-', -1) AS UNSIGNED)) + 1 AS next_index FROM afup_compta_facture WHERE LEFT(numero_facture, 4) = :year",
+            ['year' => (string) $year],
+        )->fetchOne();
+
+        return $result !== null ? (int) $result : null;
+    }
+
+    public function getNextQuotationIndex(int $year): ?int
+    {
+        $result = $this->getEntityManager()->getConnection()->executeQuery(
+            "SELECT MAX(CAST(SUBSTRING_INDEX(numero_devis, '-', -1) AS UNSIGNED)) + 1 AS next_index FROM afup_compta_facture WHERE LEFT(numero_devis, 4) = :year",
+            ['year' => (string) $year],
+        )->fetchOne();
+
+        return $result !== null ? (int) $result : null;
+    }
+
+    public function convertQuotationToInvoice(Invoicing $quotation, string $invoiceNumber): void
+    {
+        $quotation->numeroFacture = $invoiceNumber;
+        $quotation->dateFacture = new \DateTime();
+        $this->save($quotation);
+    }
+
+    /**
+     * @param array<array{0: Invoicing, prix: float|null}> $rows
+     * @return array<Invoicing>
+     */
+    private function mapRowsToInvoicings(array $rows): array
+    {
+        return array_map(static function (array $row): Invoicing {
+            $row[0]->prix = (float) $row['prix'];
+
+            return $row[0];
+        }, $rows);
+    }
+}
diff --git c/sources/AppBundle/Accounting/Entity/Repository/TransactionRepository.php i/sources/AppBundle/Accounting/Entity/Repository/TransactionRepository.php
new file mode 100644
index 000000000..3c5f4724c
--- /dev/null
+++ i/sources/AppBundle/Accounting/Entity/Repository/TransactionRepository.php
@@ -0,0 +1,99 @@
+<?php
+
+declare(strict_types=1);
+
+namespace AppBundle\Accounting\Entity\Repository;
+
+use AppBundle\Accounting\Entity\Category;
+use AppBundle\Accounting\Entity\Event;
+use AppBundle\Accounting\Entity\InvoicingPeriod;
+use AppBundle\Accounting\Entity\Transaction;
+use AppBundle\Compta\Importer\AutoQualifier;
+use AppBundle\Doctrine\EntityRepository;
+use Doctrine\Persistence\ManagerRegistry;
+
+/**
+ * @extends EntityRepository<Transaction>
+ */
+final class TransactionRepository extends EntityRepository
+{
+    public function __construct(ManagerRegistry $registry)
+    {
+        parent::__construct($registry, Transaction::class);
+    }
+
+    public function getNextTransaction(int $transactionId): ?Transaction
+    {
+        $undeterminedCategory = $this->getEntityManager()->getReference(Category::class, AutoQualifier::DEFAULT_CATEGORIE);
+        $undeterminedEvent = $this->getEntityManager()->getReference(Event::class, AutoQualifier::DEFAULT_EVENEMENT);
+
+        return $this->createQueryBuilder('t')
+            ->where('t.categorie = :undeterminedCategory OR t.evenement = :undeterminedEvent')
+            ->andWhere('t.id > :transactionId')
+            ->setParameter('undeterminedCategory', $undeterminedCategory)
+            ->setParameter('undeterminedEvent', $undeterminedEvent)
+            ->setParameter('transactionId', $transactionId)
+            ->orderBy('t.id', 'ASC')
+            ->setMaxResults(1)
+            ->getQuery()
+            ->getOneOrNullResult();
+    }
+
+    /**
+     * @return array<int, array<string, mixed>>
+     */
+    public function getEntriesPerInvoicingPeriod(InvoicingPeriod $period, bool $onlyUnclasifedEntries, int $operationType = 0): array
+    {
+        $filtre = $operationType === 1 || $operationType === 2 ? ' AND compta.idoperation = :operationType ' : '';
+
+        $sql = 'SELECT '
+            . 'compta.date_ecriture, compta.description, compta.montant, compta.idoperation, compta.id as idtmp, '
+            . 'compta.comment, compta.attachment_required, compta.attachment_filename, '
+            . 'compta_reglement.reglement, '
+            . 'compta_evenement.evenement, '
+            . 'compta_categorie.categorie, '
+            . 'compta_compte.nom_compte, '
+            . '(COALESCE(compta.montant_ht_soumis_tva_0,0) + COALESCE(compta.montant_ht_soumis_tva_5_5,0) + COALESCE(compta.montant_ht_soumis_tva_10, 0) + COALESCE(compta.montant_ht_soumis_tva_20, 0)) as montant_ht, '
+            . '((COALESCE(compta.montant_ht_soumis_tva_5_5, 0)*0.055) + (COALESCE(compta.montant_ht_soumis_tva_10, 0)*0.1) + (COALESCE(compta.montant_ht_soumis_tva_20, 0)*0.2)) as montant_tva, '
+            . 'compta.montant_ht_soumis_tva_0 as montant_ht_0, '
+            . 'compta.montant_ht_soumis_tva_5_5 as montant_ht_5_5, '
+            . 'compta.montant_ht_soumis_tva_5_5*0.055 as montant_tva_5_5, '
+            . 'compta.montant_ht_soumis_tva_10 as montant_ht_10, '
+            . 'compta.montant_ht_soumis_tva_10*0.1 as montant_tva_10, '
+            . 'compta.montant_ht_soumis_tva_20 as montant_ht_20, '
+            . 'compta.montant_ht_soumis_tva_20*0.2 as montant_tva_20, '
+            . 'compta.tva_zone '
+            . 'FROM compta '
+            . 'LEFT JOIN compta_categorie on compta_categorie.id = compta.idcategorie '
+            . 'LEFT JOIN compta_reglement on compta_reglement.id = compta.idmode_regl '
+            . 'LEFT JOIN compta_evenement on compta_evenement.id = compta.idevenement '
+            . 'LEFT JOIN compta_compte on compta_compte.id = compta.idcompte '
+            . 'WHERE compta.date_ecriture >= :startDate '
+            . 'AND compta.date_ecriture <= :endDate '
+            . $filtre;
+
+        if ($onlyUnclasifedEntries === true) {
+            $sql .= ' AND (
+                  compta_evenement.evenement = "A déterminer"
+                OR
+                  compta_categorie.categorie = "A déterminer"
+                OR
+                  compta_reglement.reglement = "A déterminer"
+                OR
+                  (compta.attachment_required = 1 AND compta.attachment_filename IS NULL)
+            ) ';
+        }
+
+        $sql .= 'ORDER BY compta.date_ecriture, numero_operation';
+
+        $params = [
+            'startDate' => $period->dateDebut->format('Y-m-d'),
+            'endDate' => $period->dateFin->format('Y-m-d'),
+        ];
+        if ($filtre !== '') {
+            $params['operationType'] = $operationType;
+        }
+
+        return $this->getEntityManager()->getConnection()->executeQuery($sql, $params)->fetchAllAssociative();
+    }
+}
diff --git c/sources/AppBundle/Accounting/Entity/Transaction.php i/sources/AppBundle/Accounting/Entity/Transaction.php
new file mode 100644
index 000000000..c89f56e85
--- /dev/null
+++ i/sources/AppBundle/Accounting/Entity/Transaction.php
@@ -0,0 +1,99 @@
+<?php
+
+declare(strict_types=1);
+
+namespace AppBundle\Accounting\Entity;
+
+use AppBundle\Accounting\Entity\Repository\TransactionRepository;
+use AppBundle\Accounting\TvaZone;
+use Doctrine\ORM\Mapping as ORM;
+
+#[ORM\Entity(repositoryClass: TransactionRepository::class)]
+#[ORM\Table(name: 'compta')]
+class Transaction
+{
+    #[ORM\Id]
+    #[ORM\GeneratedValue]
+    #[ORM\Column]
+    public ?int $id = null;
+
+    #[ORM\Column(name: 'idclef', nullable: true)]
+    public ?string $idClef = null;
+
+    #[ORM\ManyToOne(targetEntity: Operation::class)]
+    #[ORM\JoinColumn(name: 'idoperation', referencedColumnName: 'id', nullable: true)]
+    public ?Operation $operation = null;
+
+    #[ORM\ManyToOne(targetEntity: Category::class)]
+    #[ORM\JoinColumn(name: 'idcategorie', referencedColumnName: 'id', nullable: true)]
+    public ?Category $categorie = null;
+
+    #[ORM\Column(name: 'date_ecriture', nullable: true)]
+    public ?\DateTime $dateEcriture = null;
+
+    #[ORM\Column(name: 'numero_operation', nullable: true)]
+    public ?string $numeroOperation = null;
+
+    #[ORM\Column(name: 'nom_frs', nullable: false)]
+    public string $nomFournisseur = '';
+
+    #[ORM\Column(name: 'tva_intra', nullable: true)]
+    public ?string $tvaIntra = null;
+
+    #[ORM\Column(name: 'tva_zone', nullable: true, enumType: TvaZone::class)]
+    public ?TvaZone $tvaZone = null;
+
+    #[ORM\Column(name: 'montant', type: 'float', nullable: false)]
+    public float $montant = 0.0;
+
+    #[ORM\Column(nullable: false)]
+    public string $description = '';
+
+    #[ORM\Column(name: 'comment', nullable: true)]
+    public ?string $commentaire = null;
+
+    #[ORM\Column(name: 'attachment_required', nullable: false)]
+    public bool $justificatifRequis = false;
+
+    #[ORM\Column(name: 'attachment_filename', nullable: true)]
+    public ?string $nomJustificatif = null;
+
+    #[ORM\Column(name: 'numero', nullable: false)]
+    public string $numero = '';
+
+    #[ORM\ManyToOne(targetEntity: Payment::class)]
+    #[ORM\JoinColumn(name: 'idmode_regl', referencedColumnName: 'id', nullable: true)]
+    public ?Payment $modeReglement = null;
+
+    #[ORM\Column(name: 'date_regl', nullable: true)]
+    public ?\DateTime $dateReglement = null;
+
+    #[ORM\Column(name: 'obs_regl', nullable: true)]
+    public ?string $commentaireReglement = '';
+
+    #[ORM\ManyToOne(targetEntity: Event::class)]
+    #[ORM\JoinColumn(name: 'idevenement', referencedColumnName: 'id', nullable: true)]
+    public ?Event $evenement = null;
+
+    #[ORM\ManyToOne(targetEntity: Account::class)]
+    #[ORM\JoinColumn(name: 'idcompte', referencedColumnName: 'id', nullable: true)]
+    public ?Account $compte = null;
+
+    #[ORM\Column(name: 'montant_ht_soumis_tva_20', type: 'float', nullable: true)]
+    public ?float $montantTva20 = null;
+
+    #[ORM\Column(name: 'montant_ht_soumis_tva_10', type: 'float', nullable: true)]
+    public ?float $montantTva10 = null;
+
+    #[ORM\Column(name: 'montant_ht_soumis_tva_5_5', type: 'float', nullable: true)]
+    public ?float $montantTva5_5 = null;
+
+    #[ORM\Column(name: 'montant_ht_soumis_tva_0', type: 'float', nullable: true)]
+    public ?float $montantTva0 = null;
+
+    public function __construct()
+    {
+        $this->dateEcriture = new \DateTime();
+        $this->dateReglement = new \DateTime();
+    }
+}
diff --git c/sources/AppBundle/Accounting/Form/InvoiceType.php i/sources/AppBundle/Accounting/Form/InvoiceType.php
index c31316a6b..f7dc057f5 100644
--- c/sources/AppBundle/Accounting/Form/InvoiceType.php
+++ i/sources/AppBundle/Accounting/Form/InvoiceType.php
@@ -24,10 +24,10 @@ class InvoiceType extends AbstractType

     public function buildForm(FormBuilderInterface $builder, array $options): void
     {
-        $builder->add('invoiceDate', DateType::class, [
+        $builder->add('dateFacture', DateType::class, [
             'label' => 'Date facture',
             'widget' => 'single_text',
-        ])->add('company', TextType::class, [
+        ])->add('societe', TextType::class, [
             'label' => 'Société',
             'constraints' => [
                 new Assert\NotBlank(),
@@ -40,38 +40,38 @@ class InvoiceType extends AbstractType
             'constraints' => [
                 new Assert\Length(max: 50),
             ],
-        ])->add('address', TextareaType::class, [
+        ])->add('adresse', TextareaType::class, [
             'label' => 'Adresse',
-        ])->add('zipcode', TextType::class, [
+        ])->add('codePostal', TextType::class, [
             'label' => 'Code postal',
             'constraints' => [
                 new Assert\NotBlank(),
                 new Assert\Length(max: 10),
             ],
-        ])->add('city', TextType::class, [
+        ])->add('ville', TextType::class, [
             'label' => 'Ville',
             'constraints' => [
                 new Assert\NotBlank(),
                 new Assert\Length(max: 50),
             ],
-        ])->add('countryId', ChoiceType::class, [
+        ])->add('idPays', ChoiceType::class, [
             'label' => 'Pays',
             'choices' => array_flip($this->pays->obtenirPays()),
-        ])->add('lastname', TextType::class, [
+        ])->add('nom', TextType::class, [
             'label' => 'Nom',
             'required' => false,
             'empty_data' => '',
             'constraints' => [
                 new Assert\Length(max: 50),
             ],
-        ])->add('firstname', TextType::class, [
+        ])->add('prenom', TextType::class, [
             'label' => 'Prénom',
             'required' => false,
             'empty_data' => '',
             'constraints' => [
                 new Assert\Length(max: 50),
             ],
-        ])->add('phone', TextType::class, [
+        ])->add('telephone', TextType::class, [
             'label' => 'Tel',
             'required' => false,
             'empty_data' => '',
@@ -90,21 +90,21 @@ class InvoiceType extends AbstractType
             'constraints' => [
                 new Assert\Length(max: 20),
             ],
-        ])->add('refClt1', TextType::class, [
+        ])->add('referenceClient1', TextType::class, [
             'label' => 'Référence client',
             'required' => false,
             'empty_data' => '',
             'constraints' => [
                 new Assert\Length(max: 50),
             ],
-        ])->add('refClt2', TextType::class, [
+        ])->add('referenceClient2', TextType::class, [
             'label' => 'Référence client 2',
             'required' => false,
             'empty_data' => '',
             'constraints' => [
                 new Assert\Length(max: 50),
             ],
-        ])->add('refClt3', TextType::class, [
+        ])->add('referenceClient3', TextType::class, [
   …
@vgreb
vgreb force-pushed the refacto/doctrine-accounting branch from 6f5a7a5 to dfaf790 Compare September 2, 2026 21:37
@vgreb

vgreb commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator Author

Je vais découper la MR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant