Use financement entity to hold money amounts drawed between wallet statements

This commit is contained in:
2024-11-11 10:09:01 +01:00
parent 621b0b96d8
commit 8630957dd9
3 changed files with 197 additions and 47 deletions
+79
View File
@@ -0,0 +1,79 @@
<?php
namespace App\Entity;
use App\Repository\WalletFinancementRepository;
use Doctrine\ORM\Mapping as ORM;
/**
* A Financement represents how much money was moved from incoming to outgoing Wallet Statements.
*/
#[ORM\Entity(repositoryClass: WalletFinancementRepository::class)]
class WalletFinancement
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
/**
* The monetary value used in this Financement.
*/
#[ORM\Embedded(class: Money::class)]
private ?Money $money = null;
/**
* An incoming Statement that originally saved the money in this Financement.
*/
#[ORM\ManyToOne(inversedBy: 'financesto')]
#[ORM\JoinColumn(nullable: false)]
private ?WalletStatement $origin = null;
/**
* An outgoing Statement that eventually spent the money in this Financement.
*/
#[ORM\ManyToOne(inversedBy: 'financedBy')]
#[ORM\JoinColumn(nullable: false)]
private ?WalletStatement $target = null;
public function getId(): ?int
{
return $this->id;
}
public function getMoney(): ?Money
{
return $this->money;
}
public function setMoney(Money $money): static
{
$this->money = $money;
return $this;
}
public function getOrigin(): ?WalletStatement
{
return $this->origin;
}
public function setOrigin(?WalletStatement $origin): static
{
$this->origin = $origin;
return $this;
}
public function getTarget(): ?WalletStatement
{
return $this->target;
}
public function setTarget(?WalletStatement $target): static
{
$this->target = $target;
return $this;
}
}
+75 -47
View File
@@ -2,7 +2,7 @@
namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata as API;
use App\Entity\Accounting\Transaction;
use App\Gateway\Wallet\StatementDirection;
use App\Repository\WalletStatementRepository;
@@ -10,7 +10,15 @@ use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
#[ApiResource()]
/**
* WalletStatements are used by the Wallet Gateway to track available balances and money movements.\
* \
* Statements are relative to a Transaction, which either:\
* \
* a. Targets an User's Accounting, for which an incoming Statement will be created and which will hold the money until it is spent.\
* b. Originates from an User's Accounting via the Wallet Gateway, which will create an outgoing Statement with money financed from previous incoming statements.
*/
#[API\ApiResource()]
#[ORM\Entity(repositoryClass: WalletStatementRepository::class)]
class WalletStatement
{
@@ -23,33 +31,44 @@ class WalletStatement
#[ORM\JoinColumn(nullable: false)]
private ?Transaction $transaction = null;
/**
* An `incoming` direction Statement means the Transaction saved money into the wallet.\
* An `outgoing` direction Statement means the Transaction spent money from the wallet.
*/
#[ORM\Column(enumType: StatementDirection::class)]
private ?StatementDirection $direction = null;
/**
* For incoming Statements, the balance tells the available money.\
* i.e: money not used yet by outgoing Statements.
*/
#[ORM\Embedded(class: Money::class)]
private ?Money $balance = null;
/**
* The Statements from which the money in the Transaction was drawed out of.
*
* @var Collection<int, WalletStatement>
* A collection of Financements for outgoing Statements that were made using money from this Statement.
*
* Only not empty for incoming Statements.
*
* @var Collection<int, WalletFinancement>
*/
#[ORM\ManyToMany(targetEntity: WalletStatement::class, mappedBy: 'financesTo')]
private Collection $financedBy;
#[ORM\OneToMany(mappedBy: 'origin', targetEntity: WalletFinancement::class)]
private Collection $financesTo;
/**
* The Statements that drawed money out of this Statement for their Transactions.\
* Inverse of `financedBy`.
*
* @var Collection<int, WalletStatement>
* A collection of Financements from incoming Statements that provided money for this Statement.
*
* Only not empty for outgoing Statements.
*
* @var Collection<int, WalletFinancement>
*/
#[ORM\ManyToMany(targetEntity: WalletStatement::class, inversedBy: 'financedBy')]
private Collection $financesTo;
#[ORM\OneToMany(mappedBy: 'target', targetEntity: WalletFinancement::class)]
private Collection $financedBy;
public function __construct()
{
$this->financedBy = new ArrayCollection();
$this->financesTo = new ArrayCollection();
$this->financedBy = new ArrayCollection();
}
public function getId(): ?int
@@ -94,52 +113,61 @@ class WalletStatement
}
/**
* @return Collection<int, WalletStatement>
*/
public function getFinancedBy(): Collection
{
return $this->financedBy;
}
public function addFinancedBy(WalletStatement $financedBy): static
{
if (!$this->financedBy->contains($financedBy)) {
$this->financedBy->add($financedBy);
$financedBy->addFinanceTo($this);
}
return $this;
}
public function removeFinancedBy(WalletStatement $financedBy): static
{
if ($this->financedBy->removeElement($financedBy)) {
$financedBy->removeFinanceTo($this);
}
return $this;
}
/**
* @return Collection<int, WalletStatement>
* @return Collection<int, WalletFinancement>
*/
public function getFinancesTo(): Collection
{
return $this->financesTo;
}
public function addFinanceTo(WalletStatement $finance): static
public function addFinancesTo(WalletFinancement $financesTo): static
{
if (!$this->financesTo->contains($finance)) {
$this->financesTo->add($finance);
if (!$this->financesTo->contains($financesTo)) {
$this->financesTo->add($financesTo);
$financesTo->setOrigin($this);
}
return $this;
}
public function removeFinanceTo(WalletStatement $finance): static
public function removeFinancesTo(WalletFinancement $financesTo): static
{
$this->financesTo->removeElement($finance);
if ($this->financesTo->removeElement($financesTo)) {
// set the owning side to null (unless already changed)
if ($financesTo->getOrigin() === $this) {
$financesTo->setOrigin(null);
}
}
return $this;
}
/**
* @return Collection<int, WalletFinancement>
*/
public function getFinancedBy(): Collection
{
return $this->financedBy;
}
public function addFinancedBy(WalletFinancement $financedBy): static
{
if (!$this->financedBy->contains($financedBy)) {
$this->financedBy->add($financedBy);
$financedBy->setTarget($this);
}
return $this;
}
public function removeFinancedBy(WalletFinancement $financedBy): static
{
if ($this->financedBy->removeElement($financedBy)) {
// set the owning side to null (unless already changed)
if ($financedBy->getTarget() === $this) {
$financedBy->setTarget(null);
}
}
return $this;
}
@@ -0,0 +1,43 @@
<?php
namespace App\Repository;
use App\Entity\WalletFinancement;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<WalletFinancement>
*/
class WalletFinancementRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, WalletFinancement::class);
}
// /**
// * @return WalletFinancement[] Returns an array of WalletFinancement objects
// */
// public function findByExampleField($value): array
// {
// return $this->createQueryBuilder('w')
// ->andWhere('w.exampleField = :val')
// ->setParameter('val', $value)
// ->orderBy('w.id', 'ASC')
// ->setMaxResults(10)
// ->getQuery()
// ->getResult()
// ;
// }
// public function findOneBySomeField($value): ?WalletFinancement
// {
// return $this->createQueryBuilder('w')
// ->andWhere('w.exampleField = :val')
// ->setParameter('val', $value)
// ->getQuery()
// ->getOneOrNullResult()
// ;
// }
}