Transaction.php 3.02 KB
Newer Older
Julien Jorry committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
<?php

namespace App\Entity;

use App\Enum\CurrencyEnum;
use App\Utils\OperationFactory;
use Doctrine\ORM\Mapping as ORM;

/**
 * TRANSACTION
 * Dans l'interface de gestion de son compte professionnel, un prestataire peut effectuer deux types de virements internes, vers un autre prestataire ou vers un adhérent
 * Pour ajouter il faut un rôle spécifique:
 *     – Adhérent (paiement numérique avec son compte adhérent)
 *     – Prestataire (entre prestataires et virement vers un compte adhérent)
 * La somme des transactions électroniques sont limitées à un million d'euro par année glissante,
 * important donc de contrôler au moins le montant global des 365 derniers jours.
 *
 * Types de transaction :
 *
 *   - PRESTATAIRES     =>    ADHERENTS         (Virement vers un adherent)
 *   - PRESTATAIRES     =>    PRESTATAIRES      (Virement entre prestataires)
 *   - ADHERENTS        =>    PRESTATAIRES      (Paiement numérique)
 *   - ADHERENTS        =>    ADHERENTS         (transfert de monnaie numérique)
 *
 * @ORM\Entity
 */
class Transaction extends Flux
{
    const TYPE_TRANSACTION_ADHERENT_ADHERENT = 'adherent_adherent';
    const TYPE_TRANSACTION_ADHERENT_PRESTATAIRE = 'adherent_prestataire';
    const TYPE_TRANSACTION_PRESTATAIRE_ADHERENT = 'prestataire_adherent';
    const TYPE_TRANSACTION_PRESTATAIRE_PRESTATAIRE = 'prestataire_prestataire';

    public static function getAvailableTypes(): array
    {
        return [
            self::TYPE_TRANSACTION_ADHERENT_ADHERENT => self::TYPE_TRANSACTION_ADHERENT_ADHERENT,
            self::TYPE_TRANSACTION_ADHERENT_PRESTATAIRE => self::TYPE_TRANSACTION_ADHERENT_PRESTATAIRE,
            self::TYPE_TRANSACTION_PRESTATAIRE_ADHERENT => self::TYPE_TRANSACTION_PRESTATAIRE_ADHERENT,
            self::TYPE_TRANSACTION_PRESTATAIRE_PRESTATAIRE => self::TYPE_TRANSACTION_PRESTATAIRE_PRESTATAIRE,
        ];
    }

    /**
     * @return string
     */
    public function getParenttype(): string
    {
        return parent::TYPE_TRANSACTION;
    }

    public function getAllOperations($em)
    {
        return [
            OperationFactory::getOperation($this, $this->getExpediteur(), CurrencyEnum::CURRENCY_EMLC, -$this->getMontant()),
            OperationFactory::getOperation($this, $this->getDestinataire(), CurrencyEnum::CURRENCY_EMLC, $this->getMontant()),
        ];
    }

    public function operate($em)
    {
        $compteExp = $this->getExpediteur()->getEcompte() - $this->getMontant();
        if ($compteExp < 0) {
            throw new \Exception("[FLUX] Transaction impossible ! Montant supérieur au solde de l'expéditeur !");
        } else {
            $this->getExpediteur()->removeEcompte($this->getMontant());
            $this->getDestinataire()->addEcompte($this->getMontant());

            return [$this->getExpediteur(), $this->getDestinataire()];
        }

        return [];
    }

    /**
     * @return string
     */
    public function getType(): string
    {
        return '';
    }

    public function getUsersToNotify()
    {
        return [];
    }
}