Commit 14910706 by Damien Moulard

create allocation entity and save it when saving allocation flux

parent 2f379ae2
...@@ -181,11 +181,17 @@ class Adherent extends AccountableObject implements AccountableInterface ...@@ -181,11 +181,17 @@ class Adherent extends AccountableObject implements AccountableInterface
*/ */
private $thirdPartyFinancer; private $thirdPartyFinancer;
/**
* @ORM\OneToMany(targetEntity=Allocation::class, mappedBy="adherent", orphanRemoval=true)
*/
private $allocations;
public function __construct() public function __construct()
{ {
$this->accounts = new ArrayCollection(); $this->accounts = new ArrayCollection();
$this->dependentChildren = new ArrayCollection(); $this->dependentChildren = new ArrayCollection();
$this->externalDatedDataCollection = new ArrayCollection(); $this->externalDatedDataCollection = new ArrayCollection();
$this->allocations = new ArrayCollection();
} }
public function getId() public function getId()
...@@ -593,4 +599,34 @@ class Adherent extends AccountableObject implements AccountableInterface ...@@ -593,4 +599,34 @@ class Adherent extends AccountableObject implements AccountableInterface
return $this; return $this;
} }
/**
* @return Collection<int, Allocation>
*/
public function getAllocations(): Collection
{
return $this->allocations;
}
public function addAllocation(Allocation $allocation): self
{
if (!$this->allocations->contains($allocation)) {
$this->allocations[] = $allocation;
$allocation->setAdherent($this);
}
return $this;
}
public function removeAllocation(Allocation $allocation): self
{
if ($this->allocations->removeElement($allocation)) {
// set the owning side to null (unless already changed)
if ($allocation->getAdherent() === $this) {
$allocation->setAdherent(null);
}
}
return $this;
}
} }
<?php
namespace App\Entity;
use App\Repository\AllocationRepository;
use Gedmo\Timestampable\Traits\TimestampableEntity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=AllocationRepository::class)
*
* In SSA environment, defines the allocation an Adhérent gets when they pay their cotisation.
* An allocation is composed of a cotisation, which is the amount they will pay,
* and an optional complementary flux to add to or withdraw from the user eMLC account so they get an allocation of [amount] eMLC.
*
* This table is primarily used in an external context (i.e. Metabase), to simplify access to allocation data.
*/
class Allocation
{
use TimestampableEntity;
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity=adherent::class, inversedBy="allocations")
* @ORM\JoinColumn(nullable=false)
*/
private $adherent;
/**
* @ORM\OneToOne(targetEntity=Flux::class, inversedBy="allocation", cascade={"persist", "remove"})
* @ORM\JoinColumn(nullable=false)
*/
private $cotisationFlux;
/**
* @ORM\OneToOne(targetEntity=Flux::class, inversedBy="allocation", cascade={"persist", "remove"})
*
* Can be null if the user gets the same amount of allocation as their cotisation.
*/
private $complementaryFlux;
/**
* @ORM\Column(type="float")
*
* Amount of the allocation, combinaison of cotisation flux to which is added or added the complementary flux
*/
private $amount;
public function getId(): ?int
{
return $this->id;
}
public function getAdherent(): ?adherent
{
return $this->adherent;
}
public function setAdherent(?adherent $adherent): self
{
$this->adherent = $adherent;
return $this;
}
public function getCotisationFlux(): ?Flux
{
return $this->cotisationFlux;
}
public function setCotisationFlux(Flux $cotisationFlux): self
{
$this->cotisationFlux = $cotisationFlux;
return $this;
}
public function getComplementaryFlux(): ?Flux
{
return $this->complementaryFlux;
}
public function setComplementaryFlux(?Flux $complementaryFlux): self
{
$this->complementaryFlux = $complementaryFlux;
return $this;
}
public function getAmount(): ?float
{
return $this->amount;
}
public function setAmount(float $amount): self
{
$this->amount = $amount;
return $this;
}
}
...@@ -241,6 +241,11 @@ abstract class Flux implements FluxInterface ...@@ -241,6 +241,11 @@ abstract class Flux implements FluxInterface
*/ */
protected $historical; protected $historical;
/**
* @ORM\OneToOne(targetEntity=Allocation::class, mappedBy="cotisationFlux")
*/
private $allocation;
abstract public function getParenttype(): string; abstract public function getParenttype(): string;
abstract public function getType(): string; abstract public function getType(): string;
...@@ -678,4 +683,29 @@ abstract class Flux implements FluxInterface ...@@ -678,4 +683,29 @@ abstract class Flux implements FluxInterface
Transaction::TYPE_TRANSACTION_ADHERENT_PRESTATAIRE => Transaction::TYPE_TRANSACTION_ADHERENT_PRESTATAIRE Transaction::TYPE_TRANSACTION_ADHERENT_PRESTATAIRE => Transaction::TYPE_TRANSACTION_ADHERENT_PRESTATAIRE
]; ];
} }
public function getAllocation(): ?Allocation
{
return $this->allocation;
}
public function setAllocation(Allocation $allocation): self
{
// set the other side of the relation if necessary
if (
($this->type == 'vente_emlc_adherent' || $this->type == 'achat_monnaie_adherent')
&& $allocation->getCotisationFlux() !== $this
) {
$allocation->setCotisationFlux($this);
} else if (
($this->type == 'prelevement_cotisation_adherent' || $this->type == 'reversement_cotisation_adherent')
&& $allocation->complementaryFlux() !== $this
) {
$allocation->complementaryFlux($this);
}
$this->allocation = $allocation;
return $this;
}
} }
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20260121105005 extends AbstractMigration
{
public function getDescription() : string
{
return '';
}
public function up(Schema $schema) : void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE allocation (id INT AUTO_INCREMENT NOT NULL, adherent_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', cotisation_flux_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', complementary_flux_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', amount DOUBLE PRECISION NOT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, INDEX IDX_5C44232A25F06C53 (adherent_id), UNIQUE INDEX UNIQ_5C44232A363D74 (cotisation_flux_id), UNIQUE INDEX UNIQ_5C44232A7D9C219F (complementary_flux_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_general_ci` ENGINE = InnoDB');
$this->addSql('ALTER TABLE allocation ADD CONSTRAINT FK_5C44232A25F06C53 FOREIGN KEY (adherent_id) REFERENCES adherent (id)');
$this->addSql('ALTER TABLE allocation ADD CONSTRAINT FK_5C44232A363D74 FOREIGN KEY (cotisation_flux_id) REFERENCES flux (id)');
$this->addSql('ALTER TABLE allocation ADD CONSTRAINT FK_5C44232A7D9C219F FOREIGN KEY (complementary_flux_id) REFERENCES flux (id)');
}
public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('DROP TABLE allocation');
}
}
<?php
namespace App\Repository;
use App\Entity\Allocation;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\OptimisticLockException;
use Doctrine\ORM\ORMException;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<Allocation>
*
* @method Allocation|null find($id, $lockMode = null, $lockVersion = null)
* @method Allocation|null findOneBy(array $criteria, array $orderBy = null)
* @method Allocation[] findAll()
* @method Allocation[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class AllocationRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Allocation::class);
}
/**
* @throws ORMException
* @throws OptimisticLockException
*/
public function add(Allocation $entity, bool $flush = true): void
{
$this->_em->persist($entity);
if ($flush) {
$this->_em->flush();
}
}
/**
* @throws ORMException
* @throws OptimisticLockException
*/
public function remove(Allocation $entity, bool $flush = true): void
{
$this->_em->remove($entity);
if ($flush) {
$this->_em->flush();
}
}
// /**
// * @return Allocation[] Returns an array of Allocation objects
// */
/*
public function findByExampleField($value)
{
return $this->createQueryBuilder('a')
->andWhere('a.exampleField = :val')
->setParameter('val', $value)
->orderBy('a.id', 'ASC')
->setMaxResults(10)
->getQuery()
->getResult()
;
}
*/
/*
public function findOneBySomeField($value): ?Allocation
{
return $this->createQueryBuilder('a')
->andWhere('a.exampleField = :val')
->setParameter('val', $value)
->getQuery()
->getOneOrNullResult()
;
}
*/
}
...@@ -13,6 +13,7 @@ use App\Entity\Flux; ...@@ -13,6 +13,7 @@ use App\Entity\Flux;
use App\Entity\CotisationTavReversement; use App\Entity\CotisationTavReversement;
use App\Entity\CotisationTavPrelevement; use App\Entity\CotisationTavPrelevement;
use App\Entity\ThirdPartyAllocationFunding; use App\Entity\ThirdPartyAllocationFunding;
use App\Entity\Allocation;
use App\Enum\MoyenEnum; use App\Enum\MoyenEnum;
use App\Repository\PaymentRepository; use App\Repository\PaymentRepository;
use App\Utils\CustomEntityManager; use App\Utils\CustomEntityManager;
...@@ -132,12 +133,18 @@ class TAVCotisationUtils ...@@ -132,12 +133,18 @@ class TAVCotisationUtils
$adherent = $flux->getDestinataire(); $adherent = $flux->getDestinataire();
$profile = $adherent->getProfilDeCotisation(); $profile = $adherent->getProfilDeCotisation();
$cotisationTaux = $profile->getTauxCotisation(); $cotisationTaux = $profile->getTauxCotisation();
// create the Allocation
$allocation = new Allocation();
$allocation->setAdherent($adherent);
$allocation->setCotisationFlux($flux);
// don't need to create an other Flux if the rate is 1 // don't need to create an other Flux if the rate is 1
if ($cotisationTaux != 1) { if ($cotisationTaux != 1) {
// calculate the mlc amount the user will receive // calculate the mlc amount the user will receive
$cotisationAmount = $profile->getMontant(); $cotisationAmount = $profile->getMontant();
$mlcAmount = round($cotisationAmount * $cotisationTaux); $mlcAmount = round($cotisationAmount * $cotisationTaux);
$allocation->setAmount($mlcAmount);
// get the difference between what the user paid and what he•she's supposed to receive // get the difference between what the user paid and what he•she's supposed to receive
$amountDiff = $mlcAmount - $cotisationAmount; $amountDiff = $mlcAmount - $cotisationAmount;
...@@ -175,7 +182,16 @@ class TAVCotisationUtils ...@@ -175,7 +182,16 @@ class TAVCotisationUtils
$fluxCotis->setRole($flux->getRole()); $fluxCotis->setRole($flux->getRole());
$fluxCotis->setMoyen(MoyenEnum::MOYEN_EMLC); $fluxCotis->setMoyen(MoyenEnum::MOYEN_EMLC);
$this->em->persist($fluxCotis); $this->em->persist($fluxCotis);
$allocation->setComplementaryFlux($fluxCotis);
$this->em->persist($allocation);
$this->operationUtils->executeOperations($fluxCotis); $this->operationUtils->executeOperations($fluxCotis);
} else {
$cotisationAmount = $profile->getMontant();
$allocation->setAmount($cotisationAmount);
$this->em->persist($allocation);
$this->em->flush();
} }
} }
...@@ -317,6 +333,7 @@ class TAVCotisationUtils ...@@ -317,6 +333,7 @@ class TAVCotisationUtils
/** /**
* Method called to create Flux based on allowance amount (for household based allowance). * Method called to create Flux based on allowance amount (for household based allowance).
* Only create flux if amount paid != allowance amount. * Only create flux if amount paid != allowance amount.
* Also creates an Allocation instance.
* Also creates a ThirdPartyAllocationFunding instance if needed. * Also creates a ThirdPartyAllocationFunding instance if needed.
*/ */
public function applyHouseholdAllowance(Flux $flux) { public function applyHouseholdAllowance(Flux $flux) {
...@@ -338,6 +355,12 @@ class TAVCotisationUtils ...@@ -338,6 +355,12 @@ class TAVCotisationUtils
$mlcAllowanceAmount = $adherent->getAllocationAmount(); $mlcAllowanceAmount = $adherent->getAllocationAmount();
} }
// create the Allocation
$allocation = new Allocation();
$allocation->setAdherent($adherent);
$allocation->setCotisationFlux($flux);
$allocation->setAmount($mlcAllowanceAmount);
// get the difference between what the user paid and what he•she's supposed to receive // get the difference between what the user paid and what he•she's supposed to receive
$amountDiff = $mlcAllowanceAmount - $cotisationAmount; $amountDiff = $mlcAllowanceAmount - $cotisationAmount;
...@@ -375,7 +398,14 @@ class TAVCotisationUtils ...@@ -375,7 +398,14 @@ class TAVCotisationUtils
$fluxCotis->setRole($flux->getRole()); $fluxCotis->setRole($flux->getRole());
$fluxCotis->setMoyen(MoyenEnum::MOYEN_EMLC); $fluxCotis->setMoyen(MoyenEnum::MOYEN_EMLC);
$this->em->persist($fluxCotis); $this->em->persist($fluxCotis);
$allocation->setComplementaryFlux($fluxCotis);
$this->em->persist($allocation);
$this->operationUtils->executeOperations($fluxCotis); $this->operationUtils->executeOperations($fluxCotis);
} else {
$this->em->persist($allocation);
$this->em->flush();
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment