You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
355 lines
16 KiB
355 lines
16 KiB
<?php
|
|
|
|
// contains plain-text information as they have to be used for the API or wherever. no objects and stuff
|
|
|
|
namespace App\Services\Camt;
|
|
|
|
use App\Exceptions\ImporterErrorException;
|
|
use App\Services\Shared\Configuration\Configuration;
|
|
use Genkgo\Camt\Camt053\DTO\Statement;
|
|
use Genkgo\Camt\DTO\BBANAccount;
|
|
use Genkgo\Camt\DTO\Entry;
|
|
use Genkgo\Camt\DTO\EntryTransactionDetail;
|
|
use Genkgo\Camt\DTO\IbanAccount;
|
|
use Genkgo\Camt\DTO\Message;
|
|
use Genkgo\Camt\DTO\OtherAccount;
|
|
use Genkgo\Camt\DTO\ProprietaryAccount;
|
|
use Genkgo\Camt\DTO\RelatedParty;
|
|
use Genkgo\Camt\DTO\UPICAccount;
|
|
use Money\Currencies\ISOCurrencies;
|
|
use Money\Formatter\DecimalMoneyFormatter;
|
|
use Money\Money;
|
|
|
|
class Transaction
|
|
{
|
|
public const TIME_FORMAT = 'Y-m-d H:i:s';
|
|
private Configuration $configuration;
|
|
|
|
private Message $levelA;
|
|
|
|
private Statement $levelB;
|
|
|
|
private Statement|Entry|EntryTransactionDetail $levelC;
|
|
|
|
private ?EntryTransactionDetail $levelD;
|
|
private ?RelatedParty $relatedOppositeParty;
|
|
|
|
public function __construct(
|
|
Configuration $configuration, Message $levelA, Statement $levelB, Entry $levelC, EntryTransactionDetail $levelD = null
|
|
) {
|
|
$this->relatedOppositeParty = null;
|
|
$this->configuration = $configuration;
|
|
$this->levelA = $levelA;
|
|
$this->levelB = $levelB;
|
|
$this->levelC = $levelC;
|
|
$this->levelD = null;
|
|
if (null !== $levelD) {
|
|
$this->levelD = $levelD;
|
|
$this->setOpposingInformation($levelD);
|
|
}
|
|
}
|
|
|
|
public function getField(string $fieldName = null): string
|
|
{
|
|
$ret = false;
|
|
switch ($fieldName) {
|
|
default:
|
|
throw new ImporterErrorException(sprintf('Unknown field "%s"', $fieldName));
|
|
case 'messageId':
|
|
return (string)$this->levelA->getGroupHeader()->getMessageId();
|
|
case 'statementId':
|
|
return (string)$this->levelB->getId();
|
|
case 'statementAccountIban':
|
|
$ret = '';
|
|
if (IbanAccount::class === get_class($this->levelB->getAccount())) {
|
|
$ret = $this->levelB->getAccount()->getIdentification();
|
|
}
|
|
|
|
return $ret;
|
|
case 'statementAccountNumber':
|
|
$list = [OtherAccount::class, ProprietaryAccount::class, UPICAccount::class, BBANAccount::class];
|
|
$class = get_class($this->levelB->getAccount());
|
|
$ret = '';
|
|
if (in_array($class, $list, true)) {
|
|
$ret = $this->levelB->getAccount()->getIdentification();
|
|
}
|
|
|
|
return $ret;
|
|
case 'entryDate':
|
|
|
|
return (string)$this->levelC->getValueDate()->format(self::TIME_FORMAT);
|
|
case 'entryAccountServicerReference': // external ID
|
|
// TODO gives a complex object back.
|
|
return (string)$this->levelC->getAccountServicerReference();
|
|
case 'entryReference':
|
|
// TODO gives a complex object back.
|
|
return (string)$this->levelC->getReference();
|
|
case 'entryAdditionalInfo':
|
|
// TODO gives a complex object back.
|
|
return (string)$this->levelC->getAdditionalInfo();
|
|
case 'entryAmount':
|
|
return (string)$this->getDecimalAmount($this->levelC->getAmount());
|
|
case 'entryAmountCurrency':
|
|
return (string)$this->levelC->getAmount()->getCurrency()->getCode();
|
|
case 'entryValueDate':
|
|
// TODO same as entryDate
|
|
return $this->levelC->getValueDate()->format(self::TIME_FORMAT);
|
|
case 'messageCreationDate':
|
|
return (string)$this->levelB->getCreatedOn()->format(self::TIME_FORMAT);
|
|
case 'statementCreationDate':
|
|
// level B
|
|
return (string)$this->levelB->getCreatedOn()->format(self::TIME_FORMAT);
|
|
case 'entryBookingDate':
|
|
return (string)$this->levelC->getBookingDate()->format(self::TIME_FORMAT);
|
|
case 'entryDetailBtcDomainCode':
|
|
case 'entryBtcDomainCode':
|
|
return (string)$this->levelC->getBankTransactionCode()->getDomain()->getCode();
|
|
case 'entryDetailBtcFamilyCode':
|
|
case 'entryBtcFamilyCode':
|
|
return (string)$this->levelC->getBankTransactionCode()->getDomain()->getFamily()->getCode();
|
|
case 'entryDetailBtcSubFamilyCode':
|
|
case 'entryBtcSubFamilyCode':
|
|
return (string)$this->levelC->getBankTransactionCode()->getDomain()->getFamily()->getSubFamilyCode();
|
|
case 'entryOpposingAccountIban':
|
|
case 'entryDetailOpposingAccountIban':
|
|
$ret = '';
|
|
if ($account = $this->relatedOppositeParty?->getAccount()) {
|
|
if (get_class($account) === IbanAccount::class) {
|
|
$ret = (string)$account->getIdentification();
|
|
}
|
|
}
|
|
|
|
return $ret;
|
|
case 'entryOpposingAccountNumber':
|
|
case 'entryDetailOpposingAccountNumber':
|
|
$ret = '';
|
|
if ($account = $this->relatedOppositeParty?->getAccount()) {
|
|
switch (get_class($account)) {
|
|
case OtherAccount::class:
|
|
case ProprietaryAccount::class:
|
|
case UPICAccount::class:
|
|
case BBANAccount::class:
|
|
$ret = $account->getIdentification();
|
|
break;
|
|
}
|
|
}
|
|
|
|
return $ret;
|
|
case 'entryOpposingName':
|
|
case 'entryDetailOpposingName':
|
|
return '';
|
|
// TODO this code doesnt work yet.
|
|
if (empty ($this->relatedOppositeParty)) {
|
|
$ret = $this->getOpposingName();
|
|
}
|
|
|
|
return $ret;
|
|
|
|
case 'entryDetailAmount':
|
|
return (string)$this->getDecimalAmount($this->levelD?->getAmount());
|
|
case 'entryDetailAmountCurrency':
|
|
return (string)$this->levelD?->getAmount()->getCurrency()->getCode();
|
|
case 'entryDetailAccountServicerReference': // external ID
|
|
return (string)$this->levelC?->getAccountServicerReference();
|
|
case 'entryDetailRemittanceInformationUnstructuredBlockMessage': // unstructured description
|
|
$ret = '';
|
|
// TODO assignment in if-statement.
|
|
if ($remittanceInformation = $this->levelD?->getRemittanceInformation()) {
|
|
if ($unstructuredRemittanceInformation = $remittanceInformation->getUnstructuredBlock()) {
|
|
$ret = (string)$unstructuredRemittanceInformation->getMessage();
|
|
}
|
|
}
|
|
|
|
return $ret;
|
|
case 'entryDetailRemittanceInformationStructuredBlockAdditionalRemittanceInformation': // structured description
|
|
$ret = '';
|
|
// TODO assignment in if-statement.
|
|
if ($remittanceInformation = $this->levelD?->getRemittanceInformation()) {
|
|
if ($unstructuredRemittanceInformation = $remittanceInformation->getUnstructuredBlock()) {
|
|
$ret = (string)$unstructuredRemittanceInformation->getMessage();
|
|
}
|
|
}
|
|
|
|
return $ret;
|
|
break;
|
|
|
|
// case 'entryBookingDate':
|
|
// $ret = $this->levelC->getBookingDate();
|
|
//
|
|
// return $ret;
|
|
// break;
|
|
// /*case 'entryTransactionDate': // same as entryBookingDate
|
|
// $ret = $this->getField($entryBookingDate);
|
|
// return $ret;
|
|
// break;*/
|
|
// case 'entryBtcDomainCode':
|
|
// $ret = $this->levelC->getBankTransactionCode()->getDomain()->getCode();
|
|
//
|
|
// return $ret;
|
|
// break;
|
|
// case 'entryBtcFamilyCode':
|
|
// $ret = $this->levelC->getBankTransactionCode()->getDomain()->getFamily()->getCode();
|
|
//
|
|
// return $ret;
|
|
// break;
|
|
// case 'entryBtcSubFamilyCode':
|
|
// $ret = $this->levelC->getBankTransactionCode()->getDomain()->getFamily()->getSubFamilyCode();
|
|
//
|
|
// return $ret;
|
|
// break;
|
|
// case 'entryDetailAccountServicerReference': // external ID
|
|
// $ret = $this->levelD->getAccountServicerReference();
|
|
//
|
|
// return $ret;
|
|
// break;
|
|
// case 'entryDetailRemittanceInformationUnstructuredBlockMessage': // unstructured description
|
|
// if ($remittanceInformation = $this->levelD->getRemittanceInformation()) {
|
|
// if ($unstructuredRemittanceInformation = $remittanceInformation->getUnstructuredBlock()) {
|
|
// $ret = $unstructuredRemittanceInformation->getMessage();
|
|
// }
|
|
// }
|
|
//
|
|
// return $ret;
|
|
// break;
|
|
// case 'entryDetailRemittanceInformationStructuredBlockAdditionalRemittanceInformation': // structured description
|
|
// if ($remittanceInformation = $this->levelD->getRemittanceInformation()) {
|
|
// if ($unstructuredRemittanceInformation = $remittanceInformation->getUnstructuredBlock()) {
|
|
// $ret = $unstructuredRemittanceInformation->getMessage();
|
|
// }
|
|
// }
|
|
//
|
|
// return $ret;
|
|
// break;
|
|
// case 'entryDetailAmount':
|
|
// $ret = $this->getDecimalAmount($this->levelD->getAmount());;
|
|
//
|
|
// return $ret;
|
|
// break;
|
|
// case 'entryDetailAmountCurrency':
|
|
// $ret = $this->levelD->getAmount()->getCurrency()->getCode();
|
|
//
|
|
// return $ret;
|
|
// break;
|
|
// case 'entryDetailOpposingAccountIban':
|
|
// if ($account = $this->relatedParty->getAccount()) {
|
|
// if (get_class($account) === 'Genkgo\Camt\DTO\IbanAccount') {
|
|
// $ret = $account->getIdentification();
|
|
// }
|
|
// }
|
|
//
|
|
// return $ret;
|
|
// break;
|
|
// case 'entryDetailOpposingAccountNumber':
|
|
// if ($account = $this->relatedParty->getAccount()) {
|
|
// switch (get_class($account)) {
|
|
// case 'Genkgo\Camt\DTO\OtherAccount':
|
|
// case 'Genkgo\Camt\DTO\ProprietaryAccount':
|
|
// case 'Genkgo\Camt\DTO\UPICAccount':
|
|
// case 'Genkgo\Camt\DTO\BBANAccount':
|
|
// $ret = $account->getIdentification();
|
|
// break;
|
|
// }
|
|
// }
|
|
//
|
|
// return $ret;
|
|
// break;
|
|
// case 'entryDetailOpposingName':
|
|
// if (empty ($this->relatedOppositeParty)) {
|
|
// $ret = $this->getOpposingName();
|
|
// }
|
|
//
|
|
// return $ret;
|
|
// break;
|
|
// case 'entryDetailBtcDomainCode':
|
|
// $ret = $this->levelC->getBankTransactionCode()->getDomain()->getCode();
|
|
//
|
|
// return $ret;
|
|
// break;
|
|
// case 'entryDetailBtcFamilyCode':
|
|
// $ret = $this->levelC->getBankTransactionCode()->getDomain()->getFamily()->getCode();
|
|
//
|
|
// return $ret;
|
|
// break;
|
|
// case 'entryDetailBtcSubFamilyCode':
|
|
// $ret = $this->levelC->getBankTransactionCode()->getDomain()->getFamily()->getSubFamilyCode();
|
|
//
|
|
// return $ret;
|
|
// break;
|
|
/**
|
|
* Unused entries:
|
|
*/
|
|
|
|
// break;
|
|
// /* case 'entryForeignAmount':
|
|
// $ret = $this->getDecimalAmount($this->levelC->getAmount());;
|
|
// return $ret;
|
|
// break;
|
|
// case 'entryForeignAmountCurrency':
|
|
// $ret = $this->levelC->getAmount()->getCurrency()->getCode();
|
|
// return $ret;
|
|
// break;*/
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param EntryTransactionDetail $transactionDetail
|
|
*
|
|
* @return void
|
|
*/
|
|
private function setOpposingInformation(EntryTransactionDetail $transactionDetail)
|
|
{
|
|
$relatedParties = $transactionDetail->getRelatedParties();
|
|
if ($transactionDetail->getAmount()->getAmount() > 0) { // which part in this array is the interessting one?
|
|
$targetRelatedPartyObject = "Genkgo\Camt\DTO\Debtor";
|
|
} else {
|
|
$targetRelatedPartyObject = "Genkgo\Camt\DTO\Creditor";
|
|
}
|
|
foreach ($relatedParties as $relatedParty) {
|
|
if (get_class($relatedParty->getRelatedPartyType()) == $targetRelatedPartyObject) {
|
|
$this->relatedOppositeParty = $relatedParty;
|
|
}
|
|
}
|
|
}
|
|
|
|
private function getDecimalAmount(?Money $money): string
|
|
{
|
|
if (null === $money) {
|
|
return '';
|
|
}
|
|
$currencies = new ISOCurrencies();
|
|
$moneyDecimalFormatter = new DecimalMoneyFormatter($currencies);
|
|
|
|
return $moneyDecimalFormatter->format($money);
|
|
}
|
|
|
|
/*public function setBTC(\Genkgo\Camt\DTO\BankTransactionCode $btc) {
|
|
$this->btcDomainCode = $btc->getDomain()->getCode();
|
|
$this->btcFamilyCode = $btc->getDomain()->getFamily()->getCode();
|
|
$this->btcSubFamilyCode = $btc->getDomain()->getFamily()->getSubFamilyCode();
|
|
// TODO get reals Description of Codes
|
|
}*/
|
|
|
|
private function getOpposingName(\Genkgo\Camt\DTO\RelatedParty $relatedParty, bool $useEntireAddress = false)
|
|
{ // TODO make depend on configuration
|
|
if (empty($relatedParty->getRelatedPartyType()->getName())) {
|
|
// there is no "name", so use the address instead
|
|
$opposingName = $this->generateAddressLine($relatedParty->getRelatedPartyType()->getAddress());
|
|
} else {
|
|
// there is a name
|
|
$opposingName = $relatedParty->getRelatedPartyType()->getName();
|
|
// but maybe you want also the entire address
|
|
if ($useEntireAddress and $addressLine = $this->generateAddressLine($relatedParty->getRelatedPartyType()->getAddress())) {
|
|
$opposingName .= ', ' . $addressLine;
|
|
}
|
|
}
|
|
|
|
return $opposingName;
|
|
}
|
|
|
|
private function generateAddressLine(\Genkgo\Camt\DTO\Address $address = null)
|
|
{
|
|
$addressLines = implode(", ", $address->getAddressLines());
|
|
|
|
return $addressLines;
|
|
}
|
|
}
|