diff --git a/src/Entity/WalletStatement.php b/src/Entity/WalletStatement.php index 08f0ac9..e1e5a49 100644 --- a/src/Entity/WalletStatement.php +++ b/src/Entity/WalletStatement.php @@ -27,7 +27,7 @@ class WalletStatement #[ORM\Column] private ?int $id = null; - #[ORM\OneToOne(cascade: ['persist', 'remove'])] + #[ORM\OneToOne(cascade: ['persist'])] #[ORM\JoinColumn(nullable: false)] private ?Transaction $transaction = null; diff --git a/src/EventListener/WalletTransactionsListener.php b/src/EventListener/WalletTransactionsListener.php index f868e65..33e6939 100644 --- a/src/EventListener/WalletTransactionsListener.php +++ b/src/EventListener/WalletTransactionsListener.php @@ -6,7 +6,6 @@ use App\Entity\Accounting\Transaction; use App\Entity\User; use App\Gateway\Wallet\WalletService; use Doctrine\Bundle\DoctrineBundle\Attribute\AsEntityListener; -use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Event\PostPersistEventArgs; use Doctrine\ORM\Events; @@ -18,7 +17,6 @@ use Doctrine\ORM\Events; final class WalletTransactionsListener { public function __construct( - private EntityManagerInterface $entityManager, private WalletService $wallet, ) {} @@ -29,10 +27,17 @@ final class WalletTransactionsListener Transaction $transaction, PostPersistEventArgs $event, ) { - $target = $transaction->getTarget(); - - if ($target->getOwner() instanceof User) { - $this->wallet->save($transaction); + if (!$transaction->getTarget()->getOwner() instanceof User) { + return; } + + $statement = $this->wallet->save($transaction); + + if ($statement->getId() !== null) { + return; + } + + $event->getObjectManager()->persist($statement); + $event->getObjectManager()->flush(); } } diff --git a/src/Gateway/Wallet/WalletService.php b/src/Gateway/Wallet/WalletService.php index b64f153..763ad12 100644 --- a/src/Gateway/Wallet/WalletService.php +++ b/src/Gateway/Wallet/WalletService.php @@ -16,7 +16,7 @@ class WalletService { public function __construct( private MoneyService $money, - private WalletStatementRepository $walletStatementRepository, + private WalletStatementRepository $statementRepository, private EntityManagerInterface $entityManager, ) {} @@ -25,7 +25,7 @@ class WalletService */ public function getStatements(Accounting $accounting): array { - return $this->walletStatementRepository->findByAccounting($accounting); + return $this->statementRepository->findByAccounting($accounting); } public function getBalance(Accounting $accounting): Money @@ -47,22 +47,25 @@ class WalletService } /** - * Puts the money of a Transaction into the target wallet. + * Obtain an `incoming` WalletStatement for the Transaction. * * @param Transaction $transaction The Transaction targetting a wallet * - * @return WalletStatement An incoming statement for the target wallet + * @return WalletStatement An incoming statement for the transaction */ public function save(Transaction $transaction): WalletStatement { + $statement = $this->statementRepository->findByTransaction($transaction); + + if ($statement) { + return $statement; + } + $statement = new WalletStatement(); $statement->setTransaction($transaction); $statement->setDirection(StatementDirection::Incoming); $statement->setBalance($transaction->getMoney()); - $this->entityManager->persist($statement); - $this->entityManager->flush(); - return $statement; } @@ -117,14 +120,11 @@ class WalletService $outgoing->addFinancedBy($financement); $this->entityManager->persist($incoming); - $this->entityManager->persist($outgoing); $spendGoal = $this->money->substract($balanceSpent, $spendGoal); $spentTotal = $this->money->add($balanceSpent, $spentTotal); } - $this->entityManager->flush(); - return $outgoing; } } diff --git a/src/Repository/WalletStatementRepository.php b/src/Repository/WalletStatementRepository.php index 8987513..755eee7 100644 --- a/src/Repository/WalletStatementRepository.php +++ b/src/Repository/WalletStatementRepository.php @@ -3,6 +3,7 @@ namespace App\Repository; use App\Entity\Accounting\Accounting; +use App\Entity\Accounting\Transaction; use App\Entity\WalletStatement; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\ORM\Query\Expr\Join; @@ -64,6 +65,20 @@ class WalletStatementRepository extends ServiceEntityRepository ; } + public function findByTransaction(Transaction $transaction): ?WalletStatement + { + if ($transaction->getId() === null) { + return null; + } + + return $this->createQueryBuilder('w') + ->andWhere('w.transaction = :val') + ->setParameter('val', $transaction) + ->getQuery() + ->getOneOrNullResult() + ; + } + // /** // * @return WalletStatement[] Returns an array of WalletStatement objects // */