<?php
namespace App\AtechNet\CoreBundle\Entity;
use App\AtechNet\CoreBundle\DTO\Camt052\Camt052Message;
use App\AtechNet\CoreBundle\Enum\PaymentSource;
use App\AtechNet\CoreBundle\Enum\PaymentSubSource;
use App\AtechNet\CoreBundle\ValueObject\PaymentIban;
use DateTimeImmutable;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\HasLifecycleCallbacks;
use Doctrine\ORM\Mapping\JoinColumn;
use Doctrine\ORM\Mapping\ManyToOne;
use Doctrine\ORM\Mapping\OneToMany;
use Doctrine\ORM\Mapping\OrderBy;
use Doctrine\ORM\Mapping\Table as Table;
/**
* PaymentData
*
* @Table(name="payment_data")
* @Entity(repositoryClass="App\AtechNet\CoreBundle\Repository\PaymentDataRepository")
* @HasLifecycleCallbacks
*/
class PaymentData extends AbstractSignedEntity
{
public const TYPE_IN = 1;
public const TYPE_OUT = 2;
public const DOCUMENT_TYPE_CENTRALIS = 1;
public const DOCUMENT_TYPE_BILLINGO = 2;
public const IMPORT_TYPE_ALL = 1;
public const IMPORT_TYPE_BANK = 2;
public const IMPORT_TYPE_GLS = 3;
/**
* @return string[]
*/
public static function getSourceTypes(): array
{
return PaymentSource::getSourceTypes();
}
public function getSubSourceType(): ?string
{
$allSubSourceTypes = PaymentSource::from($this->source)->getSubSourceTypes();
return $allSubSourceTypes[$this->subSource];
}
/**
* @return array
*/
public static function getTypes(): array
{
return [
self::TYPE_IN => 'IN',
self::TYPE_OUT => 'OUT',
];
}
/**
* @return array
*/
public static function getImportTypes(): array
{
return [
self::IMPORT_TYPE_ALL,
self::IMPORT_TYPE_BANK,
self::IMPORT_TYPE_GLS,
];
}
/**
* @return array
*/
public static function getDocumentTypes(): array
{
return [
self::DOCUMENT_TYPE_CENTRALIS,
self::DOCUMENT_TYPE_BILLINGO,
];
}
/**
* @var string
*
* @Column(name="transaction_id", type="string", length=128, nullable=true)
*/
private $transId;
/**
* @var int
*
* @Column(name="source", type="integer")
*/
private $source;
/**
* @var int
*
* @Column(name="sub_source", type="integer", nullable=true)
*/
private $subSource;
/**
* @var string
*
* @Column(name="bank_transaction_id", type="string", nullable=true)
*/
private $bankTransactionId;
/**
* @var int
*
* @Column(name="type", type="integer")
*/
private $type;
/**
* @var int
*
* @Column(name="document_type", type="integer")
*/
private $documentType = self::DOCUMENT_TYPE_CENTRALIS;
/**
* @var string
*
* @Column(name="variable_symbol", type="string", length=128)
*/
private $variableSymbol;
/**
* @var string
*
* @Column(name="const_symbol", type="string", length=128, nullable=true)
*/
private $constSymbol;
/**
* @var string
*
* @Column(name="spec_symbol", type="string", length=128, nullable=true)
*/
private $specSymbol;
/**
* @var string
*
* @Column(name="sender", type="string", length=128)
*/
private $sender;
/**
* @var string
*
* @Column(name="description", type="string", length=256)
*/
private $description;
/**
* @var string
*
* @Column(name="internal_note", type="string", length=256, nullable=true)
*/
private $internalNote;
/**
* @var Document
*
* @ManyToOne(targetEntity="Document", inversedBy="paymentDatas")
* @JoinColumn(name="document_id", referencedColumnName="id", nullable=true)
*/
private $document;
/**
* @var CustomerBillingoData
*
* @ManyToOne(targetEntity="CustomerBillingoData", inversedBy="paymentDatas")
* @JoinColumn(name="billingo_data_id", referencedColumnName="id", nullable=true)
*/
private $billingoDocument;
/**
* @var string
*
* @Column(name="amount", type="decimal", precision=10, scale=2)
*/
private $amount = 0;
/**
* @var string
*
* @Column(name="currency", type="string", length=4)
*/
private $currency;
/**
* @var \DateTime
*
* @Column(name="payment_date", type="datetime")
*/
private $paymentDate;
/**
* @var User
*
* @ManyToOne(targetEntity="User")
* @JoinColumn(name="paired_by", referencedColumnName="id", nullable=true)
*/
private $pairedBy;
/**
* @var \DateTime
*
* @Column(name="paired_date", type="datetime", nullable=true)
*/
private $pairedDate;
/**
* @var bool
*
* @Column(name="pairable", type="boolean")
*/
private $pairable = true;
/**
* @var string
*
* @Column(name="account_iban", type="string", length=32, nullable=true)
*/
private $accountIban;
/**
* @var string
*
* @Column(name="counter_iban", type="string", length=32, nullable=true)
*/
private $counterIban;
/**
* @var string
*
* @Column(name="reference_payer", type="string", length=256, nullable=true)
*/
private $referencePayer;
/**
* @var PaymentData
*
* @ManyToOne(targetEntity="PaymentData", inversedBy="children")
* @JoinColumn(name="parent", referencedColumnName="id", nullable=true)
*/
private $parent;
/**
* @var ArrayCollection
*
* @OneToMany(targetEntity="PaymentData", mappedBy="parent", orphanRemoval=true)
* @OrderBy({"created" = "DESC"})
**/
private $children;
/**
* @var User
*
* @ManyToOne(targetEntity="User")
* @JoinColumn(name="description_updated_by", referencedColumnName="id", nullable=true)
*/
private $descriptionUpdatedBy;
/**
* @var \DateTime
*
* @Column(name="description_updated_date", type="datetime", nullable=true)
*/
private $descriptionUpdatedDate;
/**
* @var User
*
* @ManyToOne(targetEntity="User")
* @JoinColumn(name="internal_note_updated_by", referencedColumnName="id", nullable=true)
*/
private $internalNoteUpdatedBy;
/**
* @var \DateTime
*
* @Column(name="internal_note_updated_date", type="datetime", nullable=true)
*/
private $internalNoteUpdatedDate;
public function __construct()
{
parent::__construct();
$this->children = new ArrayCollection();
}
/**
* @return string
*/
public function getTransId()
{
return $this->transId;
}
/**
* @param string $transId
*/
public function setTransId($transId)
{
$this->transId = $transId;
}
public function getSubSource(): ?PaymentSubSource
{
return $this->subSource
? PaymentSubSource::from($this->subSource)
: null; // TODO: refactor to NullObject?
}
public function setSubSource(?PaymentSubSource $subSource)
{
$this->subSource = $subSource->value;
}
/**
* @return int
*/
public function getType()
{
return $this->type;
}
/**
* @param int $type
*/
public function setType($type)
{
$this->type = $type;
}
public function getSource(): PaymentSource
{
return PaymentSource::from($this->source);
}
public function setSource(PaymentSource $source)
{
$this->source = $source->value;
}
/**
* @return string
*/
public function getVariableSymbol()
{
return $this->variableSymbol;
}
/**
* @param string $variableSymbol
*/
public function setVariableSymbol($variableSymbol)
{
$this->variableSymbol = $variableSymbol;
}
/**
* @return string
*/
public function getConstSymbol()
{
return $this->constSymbol;
}
/**
* @param string $constSymbol
*/
public function setConstSymbol($constSymbol)
{
$this->constSymbol = $constSymbol;
}
/**
* @return string
*/
public function getSpecSymbol()
{
return $this->specSymbol;
}
/**
* @param string $specSymbol
*/
public function setSpecSymbol($specSymbol)
{
$this->specSymbol = $specSymbol;
}
/**
* @return string
*/
public function getSender()
{
return $this->sender;
}
/**
* @param string $sender
*/
public function setSender($sender)
{
$this->sender = $sender;
}
/**
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
* @param string $description
*/
public function setDescription($description)
{
$this->description = $description;
}
/**
* @return string
*/
public function getInternalNote()
{
return $this->internalNote;
}
/**
* @param string $internalNote
*/
public function setInternalNote(string $internalNote)
{
$this->internalNote = $internalNote;
}
/**
* @return Document
*/
public function getDocument()
{
return $this->document;
}
/**
* @param Document $document
*/
public function setDocument($document)
{
$this->document = $document;
}
/**
* @return string
*/
public function getAmount()
{
return $this->amount;
}
/**
* @param string $amount
*/
public function setAmount($amount)
{
$this->amount = $amount;
}
/**
* @return string
*/
public function getCurrency()
{
return $this->currency;
}
/**
* @param string $currency
*/
public function setCurrency($currency)
{
$this->currency = $currency;
}
/**
* @return \DateTime
*/
public function getPaymentDate()
{
return $this->paymentDate;
}
/**
* @param \DateTime $paymentDate
*/
public function setPaymentDate($paymentDate)
{
$this->paymentDate = $paymentDate;
}
/**
* @return boolean
*/
public function isPairable(): bool
{
return $this->pairable;
}
/**
* @param boolean $pairable
*/
public function setPairable(bool $pairable)
{
$this->pairable = $pairable;
}
/**
* @return User|null
*/
public function getPairedBy(): ?User
{
return $this->pairedBy;
}
/**
* @param User|null $pairedBy
*/
public function setPairedBy(?User $pairedBy): void
{
$this->pairedBy = $pairedBy;
}
/**
* @return \DateTime|null
*/
public function getPairedDate(): ?\DateTime
{
return $this->pairedDate;
}
/**
* @param \DateTime|null $pairedDate
*/
public function setPairedDate(?\DateTime $pairedDate): void
{
$this->pairedDate = $pairedDate;
}
/**
* @return string|null
*/
public function getAccountIban(): ?string
{
return $this->accountIban;
}
/**
* @param string|null $accountIban
*/
public function setAccountIban(?string $accountIban): void
{
$this->accountIban = $accountIban;
}
/**
* @return string|null
*/
public function getCounterIban(): ?string
{
return $this->counterIban;
}
/**
* @param string|null $counterIban
*/
public function setCounterIban(?string $counterIban): void
{
$this->counterIban = $counterIban;
}
/**
* @return string|null
*/
public function getReferencePayer(): ?string
{
return $this->referencePayer;
}
/**
* @param string|null $referencePayer
*/
public function setReferencePayer(?string $referencePayer): void
{
$this->referencePayer = $referencePayer;
}
/**
* @return PaymentData|null
*/
public function getParent(): ?PaymentData
{
return $this->parent;
}
/**
* @param PaymentData|null $parent
*/
public function setParent(?PaymentData $parent): void
{
$this->parent = $parent;
}
public function getChildren()
{
return $this->children;
}
/**
* @return CustomerBillingoData|null
*/
public function getBillingoDocument(): ?CustomerBillingoData
{
return $this->billingoDocument;
}
/**
* @param ?CustomerBillingoData|null $billingoDocument
*/
public function setBillingoDocument(?CustomerBillingoData $billingoDocument): void
{
$this->billingoDocument = $billingoDocument;
}
/**
* @return int
*/
public function getDocumentType(): int
{
return $this->documentType;
}
/**
* @param int $documentType
*/
public function setDocumentType(int $documentType): void
{
$this->documentType = $documentType;
}
/**
* @return User|null
*/
public function getDescriptionUpdatedBy(): ?User
{
return $this->descriptionUpdatedBy;
}
/**
* @param User|null $descriptionUpdatedBy
*/
public function setDescriptionUpdatedBy(?User $descriptionUpdatedBy): void
{
$this->descriptionUpdatedBy = $descriptionUpdatedBy;
}
/**
* @return \DateTime|null
*/
public function getDescriptionUpdatedDate(): ?\DateTime
{
return $this->descriptionUpdatedDate;
}
/**
* @param \DateTime|null $descriptionUpdatedDate
*/
public function setDescriptionUpdatedDate(?\DateTime $descriptionUpdatedDate): void
{
$this->descriptionUpdatedDate = $descriptionUpdatedDate;
}
/**
* @return User|null
*/
public function getInternalNoteUpdatedBy(): ?User
{
return $this->internalNoteUpdatedBy;
}
/**
* @param User|null $internalNoteUpdatedBy
*/
public function setInternalNoteUpdatedBy(?User $internalNoteUpdatedBy): void
{
$this->internalNoteUpdatedBy = $internalNoteUpdatedBy;
}
/**
* @return \DateTime|null
*/
public function getInternalNoteUpdatedDate(): ?\DateTime
{
return $this->internalNoteUpdatedDate;
}
/**
* @param \DateTime|null $internalNoteUpdatedDate
*/
public function setInternalNoteUpdatedDate(?\DateTime $internalNoteUpdatedDate): void
{
$this->internalNoteUpdatedDate = $internalNoteUpdatedDate;
}
public static function fromCamt052Message(Camt052Message $message, User $createdByUser): self
{
$rpt = $message->Rpt[0];
$entry = $rpt->Ntry[0];
$entryDetails = $entry->NtryDtls[0];
$txDetails = $entryDetails->TxDtls[0];
$creditDebit = $entry->CdtDbtInd == $entry::CREDIT
? self::TYPE_IN
: self::TYPE_OUT;
$subSource = match ($rpt->Acct->Id->IBAN) {
PaymentIban::IBAN_RAIFFEISEN_1 => PaymentSubSource::BANK_HU_RAIFFEISEN_1,
PaymentIban::IBAN_RAIFFEISEN_2 => PaymentSubSource::BANK_HU_RAIFFEISEN_2,
default => null,
};
$self = new self();
$self->setTransId($entry->NtryRef);
$self->setSource(PaymentSource::BANK_HU_RAIFFEISEN);
$self->setDocumentType(self::DOCUMENT_TYPE_CENTRALIS);
$self->setSubSource($subSource);
$self->setType($creditDebit);
$self->setVariableSymbol($txDetails->Refs->InstrId);
$self->setConstSymbol(null);
$self->setSpecSymbol(null);
$self->setSender(trim($txDetails->RltdPties->Dbtr->Party->Nm));
$self->setDescription($txDetails->RmtInf->Ustrd[0] ?? '');
$self->setAmount($entry->Amt->Amt);
$self->setCurrency(trim($entry->Amt->Ccy));
$self->setPaymentDate(new DateTimeImmutable($entry->ValDt->Dt));
$self->setAccountIban(trim($txDetails->RltdPties->DbtrAcct->Id->IBAN));
$self->setCounterIban(trim($txDetails->RltdPties->CdtrAcct->Id->IBAN));
$self->setPairable(true);
$self->setCreatedBy($createdByUser);
return $self;
}
public function getBankTransactionId(): string
{
return $this->bankTransactionId ?? '';
}
public function setBankTransactionId(string $bankTransactionId): void
{
$this->bankTransactionId = $bankTransactionId;
}
}