<?php
namespace App\Entity;
use App\Dictionary\BalanceType;
use App\Dictionary\PaymentType;
use App\Dto\Payment\WpfReconcileResponse;
use App\Lib\Payment\Encashment\AuerWitteThielCsv;
use App\Lib\Payment\PayMethod\AdminBonusMethod;
use App\Lib\Payment\PayMethod\LiquibyteDirectdebitMethod;
use App\Lib\Payment\Vendor\EmerchantpayVendor;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as Serializer;
use JMS\Serializer\Annotation\Groups;
/**
* @ORM\Table("Payment")
*
* @ORM\HasLifecycleCallbacks()
*
* @ORM\Entity(repositoryClass="App\Repository\PaymentRepository")
*/
class Payment
{
/**
* @Groups({"adminindex"})
*
* @ORM\Id()
*
* @ORM\GeneratedValue()
*
* @ORM\Column(type="integer")
*/
private $id;
/**
* @Groups({"adminindex"})
*
* @ORM\Column(type="string", length=255)
*/
private ?string $vendor = null;
/**
* @Groups({"adminindex"})
*
* @ORM\Column(type="string", length=120)
*/
private string $type = PaymentType::BOOKING;
/**
* @Groups({"adminindex"})
*
* @ORM\Column(type="string", length=120, nullable=true)
*/
private ?string $method = null;
/**
* @ORM\Column(type="string", length=255)
*/
private $customer_id;
/**
* @Groups({"adminindex"})
*
* @ORM\Column(type="string", length=255)
*/
private ?string $booking_id = null;
/**
* @Groups({"topbuyerindex", "adminindex"})
*
* @ORM\ManyToOne(targetEntity="App\Entity\Account", cascade={"persist"})
*
* @ORM\JoinColumn(name="account_id", referencedColumnName="id", onDelete="CASCADE")
*/
private ?Account $account = null;
/**
* @Groups({"adminindex"})
*
* @ORM\Column(type="decimal", precision=10, scale=2)
*/
private float $amount = 0;
/**
* @Groups({"paymenthistory", "chargebackdetail"})
*
* @ORM\Column(type="decimal", precision=10, scale=2, nullable=true)
*/
private ?float $fee = null;
/**
* @Groups({"paymenthistory", "chargebackdetail"})
*
* @ORM\Column(type="decimal", precision=10, scale=2, nullable=true)
*/
private ?float $realamount = null;
/**
* @Groups({"adminindex"})
*
* @ORM\Column(type="text", nullable=true)
*/
private ?string $details = null;
/**
* @Groups({"adminindex", "paymenthistory"})
*
* @ORM\Column(type="boolean")
*/
private bool $on_hold = false;
/**
* @Groups({"adminindex"})
*
* @ORM\ManyToOne(targetEntity="App\Entity\AdminPaymentSepaDownload", cascade={"persist"})
*
* @ORM\JoinColumn(name="admin_sepa_download_id", referencedColumnName="id", onDelete="SET NULL")
*/
private ?AdminPaymentSepaDownload $sepaDownload = null;
/**
* @Groups({"adminindex", "paymenthistory"})
*
* @ORM\Column(type="datetime")
*/
private $created_at;
/**
* @ORM\Column(type="datetime")
*/
private $updated_at;
/**
* total payments of the user for this payment.
*
* @Groups({"adminindex", "paymenthistory"})
*/
private $total_payments;
/**
* @ORM\OneToMany(targetEntity="App\Entity\BalanceMember", mappedBy="payment")
*
* @Groups({"paymenthistory"})
*/
private $balance_members;
/**
* @Groups({"paymenthistory"})
*/
private $coins;
/**
* @ORM\OneToOne(targetEntity="App\Entity\PaymentProcess", mappedBy="payment", cascade={"persist", "remove"})
*
* @ORM\JoinColumn(name="payment_process_id", referencedColumnName="id", nullable=true)
*/
private ?PaymentProcess $payment_process = null;
/**
* @ORM\OneToOne(targetEntity="App\Entity\PaymentReference", cascade={"persist", "remove"})
*
* @ORM\JoinColumn(name="payment_reference_id", referencedColumnName="id", nullable=true)
*/
private ?PaymentReference $payment_reference = null;
/**
* @Serializer\Exclude()
*/
private ?WpfReconcileResponse $reconcileResponse = null;
public function __construct()
{
$this->balance_members = new ArrayCollection();
$this->created_at = new \DateTime();
}
/**
* @ORM\PrePersist()
*/
public function prePersist()
{
if (!$this->getVendor() && $this->getMethod()) {
$vendor = strpos($this->getMethod(), '_');
$this->setVendor(substr($this->getMethod(), 0, $vendor));
}
if (!$this->getCustomerId() && $this->getAccount()) {
$this->setCustomerId((int) $this->getAccount()->getId());
}
if (!$this->getCreatedAt()) {
$this->setCreatedAt(new \DateTime());
}
if (!$this->getUpdatedAt()) {
$this->setUpdatedAt($this->getCreatedAt());
}
}
public function getId()
{
return $this->id;
}
public function getVendor(): ?string
{
return $this->vendor;
}
public function setVendor(string $vendor): self
{
$this->vendor = $vendor;
return $this;
}
public function vendorEquals(string $name): bool
{
return $this->vendor === $name;
}
public function getType(): string
{
return $this->type;
}
public function setType(string $type): self
{
$this->type = $type;
return $this;
}
public function isType(string $type): bool
{
return $this->getType() === $type;
}
public function isTypeBooking(): bool
{
return PaymentType::BOOKING === $this->type;
}
public function isTypeChargeback(): bool
{
return PaymentType::CHARGEBACK === $this->type;
}
public function isTypeSettlement(): bool
{
return PaymentType::SETTLEMENT === $this->type;
}
public function getMethod(): ?string
{
return $this->method;
}
public function setMethod(?string $method): self
{
$this->method = $method;
return $this;
}
public function getCustomerId(): ?int
{
return $this->customer_id;
}
public function setCustomerId(int $customer_id): self
{
$this->customer_id = $customer_id;
return $this;
}
public function getBookingId(): ?string
{
return $this->booking_id;
}
public function setBookingId(string $booking_id): self
{
$this->booking_id = $booking_id;
return $this;
}
public function getAccount(): ?Account
{
return $this->account;
}
public function setAccount(?Account $account): self
{
$this->account = $account;
if ($account && !$this->getCustomerId()) {
$this->setCustomerId($account->getId());
}
return $this;
}
public function getSepaDownload(): ?AdminPaymentSepaDownload
{
return $this->sepaDownload;
}
/**
* @return $this
*/
public function setSepaDownload(?AdminPaymentSepaDownload $sepaDownload): self
{
$this->sepaDownload = $sepaDownload;
return $this;
}
public function getAmount()
{
return $this->amount;
}
public function setAmount($amount): self
{
$this->amount = $amount;
return $this;
}
public function getFee()
{
return $this->fee;
}
public function setFee($fee): self
{
$this->fee = $fee;
return $this;
}
public function getRealamount()
{
return $this->realamount;
}
public function setRealamount($realamount): self
{
$this->realamount = $realamount;
return $this;
}
public function getDetails(bool $unserialize = false)
{
if ($unserialize && !empty($this->details)) {
return unserialize($this->details);
}
return $this->details;
}
public function setDetails(?string $details): self
{
$this->details = $details;
return $this;
}
public function getOnHold(): ?bool
{
return $this->on_hold;
}
public function setOnHold(bool $on_hold): self
{
$this->on_hold = $on_hold;
return $this;
}
public function getCreatedAt(): ?\DateTimeInterface
{
return $this->created_at;
}
public function setCreatedAt(\DateTimeInterface $created_at): self
{
$this->created_at = $created_at;
return $this;
}
public function getUpdatedAt(): ?\DateTimeInterface
{
return $this->updated_at;
}
public function setUpdatedAt(\DateTimeInterface $updated_at): self
{
$this->updated_at = $updated_at;
return $this;
}
public function setTotalPayments(int $totalPayments)
{
$this->total_payments = $totalPayments;
}
public function setBalanceMembers(Collection $balance_members)
{
$this->balance_members = $balance_members;
}
/**
* @return Collection|BalanceMember[]
*/
public function getBalanceMembers(): Collection
{
return $this->balance_members;
}
public function addBalanceMember(BalanceMember $balanceMember): self
{
if (!$this->balance_members->contains($balanceMember)) {
$this->balance_members[] = $balanceMember;
$balanceMember->setPayment($this);
}
return $this;
}
public function removeBalanceMember(BalanceMember $balanceMember): self
{
if ($this->balance_members->contains($balanceMember)) {
$this->balance_members->removeElement($balanceMember);
// set the owning side to null (unless already changed)
if ($balanceMember->getPayment() === $this) {
$balanceMember->setPayment(null);
}
}
return $this;
}
public function getCoins(): int
{
$coins = 0;
foreach ($this->getBalanceMembers() as $balanceMember) {
if (BalanceType::OUTPUT === $balanceMember->getType()) {
continue;
}
$coins += $balanceMember->getAmount();
}
return $coins;
}
public function setCoins(int $coins): self
{
$this->coins = $coins;
return $this;
}
public function getPaymentProcess(): ?PaymentProcess
{
return $this->payment_process;
}
public function setPaymentProcess(PaymentProcess $payment_process): self
{
$this->payment_process = $payment_process;
return $this;
}
public function appliesForIncomeCommission(): bool
{
if (!$this->isTypeBooking() || !$this->getAmount()) {
return false;
}
if ($this->getOnHold() || AdminBonusMethod::NAME === $this->getMethod()) {
return false;
}
return true;
}
public function blacklistsBankAccount(): bool
{
// not a chargeback with a negative value? nope
if (!$this->isTypeChargeback() || $this->getAmount() > 0) {
return false;
}
if (LiquibyteDirectdebitMethod::NAME === $this->getMethod()) {
return true;
}
return false;
}
public function resetsBankAccountBlacklist(): bool
{
// not a settlement with a negative value? nope
if (!$this->isTypeSettlement()) {
return false;
}
if (LiquibyteDirectdebitMethod::NAME === $this->getMethod()) {
return true;
}
return false;
}
public function hasConfirmationEmail(): bool
{
if (!$this->isTypeBooking()) {
return false;
}
if (LiquibyteDirectdebitMethod::NAME === $this->getMethod() || $this->vendorEquals(EmerchantpayVendor::EMERCHANT)) {
return true;
}
return false;
}
public function hasChargebackEmail(): bool
{
if (!$this->isTypeChargeback()) {
return false;
}
if (LiquibyteDirectdebitMethod::NAME === $this->getMethod()) {
return true;
}
return false;
}
/**
* @Serializer\VirtualProperty()
*
* @Groups({"paymenthistory", "chargebackdetail"})
*/
public function getEncashmentFee(): float
{
return AuerWitteThielCsv::FEE_ENCASHMENT;
}
/**
* @Serializer\VirtualProperty()
*
* @Groups({"paymenthistory", "chargebackdetail"})
*
* @return float
*/
public function getChargebackFee()
{
return AuerWitteThielCsv::FEE_CHARGEBACK;
}
public function getPaymentReference(): ?PaymentReference
{
return $this->payment_reference;
}
public function setPaymentReference(?PaymentReference $payment_reference): Payment
{
$this->payment_reference = $payment_reference;
return $this;
}
public function setReconcileResponse(WpfReconcileResponse $reconcileResponse): self
{
$this->reconcileResponse = $reconcileResponse;
return $this;
}
public function getReconcileResponse(): ?WpfReconcileResponse
{
return $this->reconcileResponse;
}
}