src/Entity/Sales/AccountEnrollment.php line 23

Open in your IDE?
  1. <?php
  2. /**
  3.  * Created by simpson <simpsonwork@gmail.com>
  4.  * Date: 2019-06-27
  5.  * Time: 11:00
  6.  */
  7. namespace App\Entity\Sales;
  8. use App\Entity\User;
  9. use App\Repository\AccountEnrollmentRepository;
  10. use App\Security\TeamMateView;
  11. use BigIdea\IdentityBundle\Entity\TeamMate;
  12. use Doctrine\ORM\Mapping as ORM;
  13. use Money\Currency;
  14. use Money\Money;
  15. /**
  16.  * Пополнение счета аккаунта (погашение купленных кодов)
  17.  */
  18. #[ORM\Table(name: 'account_enrollments')]
  19. #[ORM\Entity(repositoryClass: AccountEnrollmentRepository::class)]
  20. class AccountEnrollment
  21. {
  22.     #[ORM\Id]
  23.     #[ORM\Column(name: 'id', type: 'integer')]
  24.     #[ORM\GeneratedValue(strategy: 'AUTO')]
  25.     protected int $id;
  26.     #[ORM\JoinColumn(name: 'account_id', referencedColumnName: 'id')]
  27.     #[ORM\ManyToOne(targetEntity: User::class, inversedBy: 'enrollments')]
  28.     protected User $account;
  29.     /**
  30.      * Аккаунт оператора, совершившего начисление вручную
  31.      */
  32.     #[ORM\JoinColumn(name: 'staff_account_id', referencedColumnName: 'id')]
  33.     #[ORM\ManyToOne(targetEntity: TeamMate::class)]
  34.     protected ?TeamMate $enrolledBy = null;
  35.     #[ORM\Column(name: 'operation_id', type: 'string', length: 64, nullable: true)]
  36.     protected ?string $operationId = null;
  37.     #[ORM\JoinColumn(name: 'payment_product_id', referencedColumnName: 'id')]
  38.     #[ORM\ManyToOne(targetEntity: PaymentProduct::class)]
  39.     protected ?PaymentProduct $paidProduct = null;
  40.     /**
  41.      * Фактическая сумма платежа
  42.      */
  43.     #[ORM\Column(name: 'paid_amount', type: 'integer')]
  44.     protected string $paidAmount;
  45.     /**
  46.      * Начисленная на счет юзера сумма (вместе с бонусной частью)
  47.      */
  48.     #[ORM\Column(name: 'enrolled_amount', type: 'integer')]
  49.     protected string $enrolledAmount;
  50.     #[ORM\Column(name: 'currency', type: 'string', length: 3)]
  51.     protected string $currency;
  52.     #[ORM\Column(name: 'date', type: 'datetimetz_immutable')]
  53.     protected \DateTimeImmutable $date;
  54.     #[ORM\Column(name: 'redeemed_token', type: 'string', length: 64, nullable: true)]
  55.     protected ?string $redeemedToken = null;
  56.     #[ORM\OneToOne(targetEntity: AccountTransaction::class, mappedBy: 'enrollment', cascade: ['all'])]
  57.     protected AccountTransaction $transaction;
  58.     #[ORM\Column(type: 'json', nullable: true)]
  59.     protected ?array $params = null;
  60.     public static function enrollPaidValueByStaff(TeamMate $staff, User $account, Money $enrolledMoney, \DateTimeImmutable $date): self
  61.     {
  62.         $enrollment = new static($account, $enrolledMoney, $enrolledMoney, $date);
  63.         $enrollment->enrolledBy = $staff;
  64.         return $enrollment;
  65.     }
  66.     /**
  67.      * Начисление компенсаций и вознаграждений админами (без реального платежа)
  68.      */
  69.     public static function enrollBonusValueByStaff(TeamMate $staff, User $account, Money $enrolledMoney, \DateTimeImmutable $date): self
  70.     {
  71.         $enrollment = new static($account, null, $enrolledMoney, $date);
  72.         $enrollment->enrolledBy = $staff;
  73.         return $enrollment;
  74.     }
  75.     public static function enrollPaidValue(User $account, Money $paidValue, Money $enrolledMoney, \DateTimeImmutable $date, string $operationId): self
  76.     {
  77.         $enrollment = new static($account, $paidValue, $enrolledMoney, $date);
  78.         $enrollment->operationId = $operationId;
  79.         return $enrollment;
  80.     }
  81.     public static function enrollWithPrepaidToken(PaymentProduct $paymentProduct, User $account, Money $paidMoney, Money $enrolledMoney, \DateTimeImmutable $date, string $operationId, string $redeemedToken, ?TeamMate $staffAccount = null): self
  82.     {
  83.         $enrollment = new static($account, $paidMoney, $enrolledMoney, $date);
  84.         $enrollment->paidProduct = $paymentProduct;
  85.         $enrollment->operationId = $operationId;
  86.         $enrollment->redeemedToken = $redeemedToken;
  87.         $enrollment->enrolledBy = $staffAccount;
  88.         return $enrollment;
  89.     }
  90.     /**
  91.      * Начисление бонуса по промо-коду (без реального платежа)
  92.      */
  93.     public static function enrollWithCustomToken(User $account, Money $enrolledMoney, \DateTimeImmutable $date, string $redeemedToken, ?array  $params): self
  94.     {
  95.         $enrollment = new static($account, null, $enrolledMoney, $date);
  96.         $enrollment->redeemedToken = $redeemedToken;
  97.         $enrollment->params = $params;
  98.         return $enrollment;
  99.     }
  100.     protected function __construct(User $account, ?Money $paidMoney, Money $enrolledMoney, \DateTimeImmutable $date)
  101.     {
  102.         if (null !== $paidMoney && !$enrolledMoney->isSameCurrency($paidMoney)) {
  103.             throw new \LogicException('Currency mismatch between paid and enrolled amounts.');
  104.         }
  105.         $this->account = $account;
  106.         $this->paidAmount = $paidMoney?->getAmount() ?: '0';
  107.         $this->enrolledAmount = $enrolledMoney->getAmount();
  108.         $this->currency = $enrolledMoney->getCurrency()->getCode();
  109.         $this->date = $date;
  110.         $this->transaction = AccountTransaction::fromEnrollment($this);
  111.     }
  112.     public function getId(): int
  113.     {
  114.         return $this->id;
  115.     }
  116.     public function getEnrolledBy(): ?TeamMate
  117.     {
  118.         return $this->enrolledBy;
  119.     }
  120.     public function getEnrolledByDescription(): ?string
  121.     {
  122.         if (null !== $this->enrolledBy) {
  123.             return TeamMateView::email($this->enrolledBy);
  124.         }
  125.         if (null !== $this->paidProduct) {
  126.             return 'Digiseller';
  127.         }
  128.         if ($this->paidAmount > 0) {
  129.             return 'BetaTransfer';
  130.         }
  131.         if (null !== $this->redeemedToken) {
  132.             return 'Bonus';
  133.         }
  134.         return null;
  135.     }
  136.     public function getAccount(): User
  137.     {
  138.         return $this->account;
  139.     }
  140.     public function getOperationId(): ?string
  141.     {
  142.         return $this->operationId;
  143.     }
  144.     public function getPaidProduct(): ?PaymentProduct
  145.     {
  146.         return $this->paidProduct;
  147.     }
  148.     public function isRealPayment(): bool
  149.     {
  150.         return (int)$this->paidAmount > 0
  151.             && null !== $this->operationId
  152.             && null === $this->enrolledBy;
  153.     }
  154.     public function getPaidMoney(): Money
  155.     {
  156.         return new Money($this->paidAmount, new Currency($this->currency));
  157.     }
  158.     public function getEnrolledMoney(): Money
  159.     {
  160.         return new Money($this->enrolledAmount, new Currency($this->currency));
  161.     }
  162.     public function getDate(): \DateTimeImmutable
  163.     {
  164.         return $this->date;
  165.     }
  166.     public function getRedeemedToken(): ?string
  167.     {
  168.         return $this->redeemedToken;
  169.     }
  170.     public function getTransaction(): AccountTransaction
  171.     {
  172.         return $this->transaction;
  173.     }
  174.     public function getParams(): ?array
  175.     {
  176.         return $this->params;
  177.     }
  178. }