Skip to content

Commit

Permalink
Merge pull request #291 from Cugar15/sepa-b2b
Browse files Browse the repository at this point in the history
Added B2B support for SEPADirectDebit
  • Loading branch information
nemiah authored Aug 17, 2020
2 parents 13c5ee8 + 5c91d2d commit 9b93d6e
Show file tree
Hide file tree
Showing 28 changed files with 395 additions and 73 deletions.
55 changes: 31 additions & 24 deletions lib/Fhp/Action/GetSEPADirectDebitParameters.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,67 +5,74 @@
use Fhp\BaseAction;
use Fhp\Protocol\BPD;
use Fhp\Protocol\UPD;
use Fhp\Segment\DME\HIDXES;
use Fhp\Segment\DME\MinimaleVorlaufzeitSEPALastschrift;
use Fhp\Segment\DSE\HIDXES;
use Fhp\Segment\DSE\MinimaleVorlaufzeitSEPALastschrift;

/**
* Retrieves information about SEPA Direct Debit Requests
*/
class GetSEPADirectDebitParameters extends BaseAction
{
const SEQUENCE_TYPES = ['FRST', 'OOFF', 'FNAL', 'RCUR'];
const CORE_TYPES = ['CORE', 'COR1'];
const DIRECT_DEBIT_TYPES = ['CORE', 'COR1', 'B2B'];

/** @var string */
private $coreType;
private $directDebitType;

/** @var string */
private $seqType;

/** @var bool */
private $singleDirectDebit;

/** @var MinimaleVorlaufzeitSEPALastschrift|null */
private $minimalLeadTime;
/** @var HIDXES */
private $hidxes;

public static function create(string $seqType, bool $singleDirectDebit, string $coreType = 'CORE')
public static function create(string $seqType, bool $singleDirectDebit, string $directDebitType = 'CORE')
{
if (!in_array($coreType, self::CORE_TYPES)) {
throw new \InvalidArgumentException('Unknown CORE type, possible values are ' . implode(', ', self::CORE_TYPES));
if (!in_array($directDebitType, self::DIRECT_DEBIT_TYPES)) {
throw new \InvalidArgumentException('Unknown CORE type, possible values are ' . implode(', ', self::DIRECT_DEBIT_TYPES));
}
if (!in_array($seqType, self::SEQUENCE_TYPES)) {
throw new \InvalidArgumentException('Unknown SEPA sequence type, possible values are ' . implode(', ', self::SEQUENCE_TYPES));
}
$result = new GetSEPADirectDebitParameters();
$result->coreType = $coreType;
$result->directDebitType = $directDebitType;
$result->seqType = $seqType;
$result->singleDirectDebit = $singleDirectDebit;

return $result;
}

public static function getHixxesSegmentName(string $directDebitType, bool $singleDirectDebit): string
{
switch ($directDebitType) {
case 'CORE':
case 'COR1':
return $singleDirectDebit ? 'HIDSES' : 'HIDMES';
case 'B2B':
return $singleDirectDebit ? 'HIBSES' : 'HIBMES';
default:
throw new \InvalidArgumentException('Unknown DirectDebitTypes type, possible values are ' . implode(', ', self::DIRECT_DEBIT_TYPES));
}
}

/** {@inheritdoc} */
protected function createRequest(BPD $bpd, ?UPD $upd)
{
$type = $this->singleDirectDebit ? 'HIDSES' : 'HIDMES';

/** @var HIDXES $hidxes */
$hidxes = $bpd->requireLatestSupportedParameters($type);

$this->minimalLeadTime = $hidxes->getParameter()->getMinimalLeadTime($this->seqType, $this->coreType);

$this->hidxes = $bpd->requireLatestSupportedParameters(static::getHixxesSegmentName($this->directDebitType, $this->singleDirectDebit));
$this->isDone = true;

// No request to the bank required
return [];
return []; // No request to the bank required
}

/**
* @return MinimaleVorlaufzeitSEPALastschrift|null The information about the lead time for the given Sequence Type and Core Type
* @return MinimaleVorlaufzeitSEPALastschrift|null The information about the lead time for the given Sequence Type and Direct Debit Type
*/
public function getMinimalLeadTime(): ?MinimaleVorlaufzeitSEPALastschrift
{
//$this->ensureDone();
return $this->minimalLeadTime;
$parsed = $this->hidxes->getParameter()->getMinimalLeadTime($this->seqType);
if ($parsed instanceof MinimaleVorlaufzeitSEPALastschrift) {
return $parsed;
}
return $parsed[$this->directDebitType] ?? null;
}
}
37 changes: 16 additions & 21 deletions lib/Fhp/Action/SendSEPADirectDebit.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,8 @@
use Fhp\Segment\Common\Kti;
use Fhp\Segment\DME\HIDMESv1;
use Fhp\Segment\DME\HIDMESv2;
use Fhp\Segment\DME\HIDXES;
use Fhp\Segment\DME\HKDMEv1;
use Fhp\Segment\DME\HKDMEv2;
use Fhp\Segment\DSE\HIDSESv2;
use Fhp\Segment\DSE\HKDSEv1;
use Fhp\Segment\DSE\HKDSEv2;
use Fhp\Segment\DSE\HIDXES;
use Fhp\Segment\SPA\HISPAS;
use Fhp\Syntax\Bin;
use Fhp\UnsupportedException;
Expand Down Expand Up @@ -44,6 +40,9 @@ class SendSEPADirectDebit extends BaseAction
/** @var bool */
protected $tryToUseControlSumForSingleTransactions = false;

/** @var string */
private $coreType;

public static function create(SEPAAccount $account, string $painMessage, bool $tryToUseControlSumForSingleTransactions = false): SendSEPADirectDebit
{
if (preg_match('/xmlns="(?<namespace>[^"]+)"/s', $painMessage, $matches) === 1) {
Expand All @@ -56,10 +55,16 @@ public static function create(SEPAAccount $account, string $painMessage, bool $t
$nbOfTxs = substr_count($painMessage, '<DrctDbtTxInf>');
$ctrlSum = null;

if (preg_match('/<GrpHdr>.*<CtrlSum>(?<ctrlsum>[.0-9]+)<\/CtrlSum>.*<\/GrpHdr>/s', $painMessage, $matches) === 1) {
if (preg_match('@<GrpHdr>.*<CtrlSum>(?<ctrlsum>[.0-9]+)</CtrlSum>.*</GrpHdr>@s', $painMessage, $matches) === 1) {
$ctrlSum = $matches['ctrlsum'];
}

if (preg_match('@<PmtTpInf>.*<LclInstrm>.*<Cd>(?<coretype>CORE|COR1|B2B)</Cd>.*</LclInstrm>.*</PmtTpInf>@s', $painMessage, $matches) === 1) {
$coreType = $matches['coretype'];
} else {
throw new \InvalidArgumentException('The type CORE/COR1/B2B is missing in PAIN message');
}

if ($nbOfTxs > 1 && is_null($ctrlSum)) {
throw new \InvalidArgumentException('The control sum aka "<GrpHdr><CtrlSum>xx</CtrlSum></GrpHdr>" is missing in PAIN message');
}
Expand All @@ -69,6 +74,7 @@ public static function create(SEPAAccount $account, string $painMessage, bool $t
$result->painMessage = $painMessage;
$result->painNamespace = $painNamespace;
$result->ctrlSum = $ctrlSum;
$result->coreType = $coreType;

$result->singleDirectDebit = $nbOfTxs === 1;

Expand All @@ -86,8 +92,8 @@ protected function createRequest(BPD $bpd, ?UPD $upd)
$useSingleDirectDebit = false;
}

/** @var HIDXES|BaseSegment $hidxes */
$hidxes = $bpd->requireLatestSupportedParameters($useSingleDirectDebit ? 'HIDSES' : 'HIDMES');
/* @var HIDXES|BaseSegment $hidxes */
$hidxes = $bpd->requireLatestSupportedParameters(GetSEPADirectDebitParameters::getHixxesSegmentName($this->coreType, $useSingleDirectDebit));

$supportedPainNamespaces = null;

Expand All @@ -108,19 +114,8 @@ protected function createRequest(BPD $bpd, ?UPD $upd)
. implode(', ', $supportedPainNamespaces));
}

/** @var HKDMEv1|HKDSEv1 $hkdxe */
$hkdxe = null;
switch ($hidxes->getVersion()) {
case 1:
$hkdxe = $useSingleDirectDebit ? HKDSEv1::createEmpty() : HKDMEv1::createEmpty();
break;
case 2:
$hkdxe = $useSingleDirectDebit ? HKDSEv2::createEmpty() : HKDMEv2::createEmpty();
break;
default:
throw new UnsupportedException('Unsupported HKDME or HKDSE version: ' . $hidxes->getVersion());
}

/** @var mixed $hkdxe */ // TODO Put a new interface type here.
$hkdxe = $hidxes->createRequestSegment();
$hkdxe->kontoverbindungInternational = Kti::fromAccount($this->account);
$hkdxe->sepaDescriptor = $this->painNamespace;
$hkdxe->sepaPainMessage = new Bin($this->painMessage);
Expand Down
Empty file modified lib/Fhp/Model/StatementOfAccount/Transaction.php
100755 → 100644
Empty file.
30 changes: 30 additions & 0 deletions lib/Fhp/Segment/BME/HIBMESv1.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace Fhp\Segment\BME;

use Fhp\Segment\BaseGeschaeftsvorfallparameter;
use Fhp\Segment\BaseSegment;
use Fhp\Segment\DSE\HIDXES;
use Fhp\Segment\DSE\SEPADirectDebitMinimalLeadTimeProvider;

/**
* Segment: Terminierte SEPA-Sammellastschrift einreichen Parameter
*
* @link https://www.hbci-zka.de/dokumente/spezifikation_deutsch/fintsv3/FinTS_3.0_Messages_Geschaeftsvorfaelle_2015-08-07_final_version.pdf
* Section: C.10.3.3.2.1 c)
*/
class HIBMESv1 extends BaseGeschaeftsvorfallparameter implements HIDXES
{
/** @var ParameterTerminierteSEPAFirmenSammellastschriftEinreichenV1 */
public $parameter;

public function getParameter(): SEPADirectDebitMinimalLeadTimeProvider
{
return $this->parameter;
}

public function createRequestSegment(): BaseSegment
{
return HKBMEv1::createEmpty();
}
}
30 changes: 30 additions & 0 deletions lib/Fhp/Segment/BME/HIBMESv2.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace Fhp\Segment\BME;

use Fhp\Segment\BaseGeschaeftsvorfallparameter;
use Fhp\Segment\BaseSegment;
use Fhp\Segment\DSE\HIDXES;
use Fhp\Segment\DSE\SEPADirectDebitMinimalLeadTimeProvider;

/**
* Segment: Terminierte SEPA-Sammellastschrift einreichen Parameter
*
* @link https://www.hbci-zka.de/dokumente/spezifikation_deutsch/fintsv3/FinTS_3.0_Messages_Geschaeftsvorfaelle_2015-08-07_final_version.pdf
* Section: C.10.3.3.2.1 c)
*/
class HIBMESv2 extends BaseGeschaeftsvorfallparameter implements HIDXES
{
/** @var ParameterTerminierteSEPAFirmenSammellastschriftEinreichenV2 */
public $parameter;

public function getParameter(): SEPADirectDebitMinimalLeadTimeProvider
{
return $this->parameter;
}

public function createRequestSegment(): BaseSegment
{
return HKBMEv2::createEmpty();
}
}
15 changes: 15 additions & 0 deletions lib/Fhp/Segment/BME/HKBMEv1.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Fhp\Segment\BME;

use Fhp\Segment\DME\HKDMEv1;

/**
* Einreichung terminierter SEPA-Sammellastschrift (Segmentversion 1)
*
* @link https://www.hbci-zka.de/dokumente/spezifikation_deutsch/fintsv3/FinTS_3.0_Messages_Geschaeftsvorfaelle_2015-08-07_final_version.pdf
* Section: C.10.3.3.2.1
*/
class HKBMEv1 extends HKDMEv1
{
}
13 changes: 13 additions & 0 deletions lib/Fhp/Segment/BME/HKBMEv2.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Fhp\Segment\BME;

/**
* Einreichung terminierter SEPA-Sammellastschrift (Segmentversion 2)
*
* @link https://www.hbci-zka.de/dokumente/spezifikation_deutsch/fintsv3/FinTS_3.0_Messages_Geschaeftsvorfaelle_2015-08-07_final_version.pdf
* Section: C.10.3.3.2.2
*/
class HKBMEv2 extends HKBMEv1
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace Fhp\Segment\BME;

use Fhp\Segment\BSE\ParameterTerminierteSEPAFirmenEinzellastschriftEinreichenV1;

class ParameterTerminierteSEPAFirmenSammellastschriftEinreichenV1 extends ParameterTerminierteSEPAFirmenEinzellastschriftEinreichenV1
{
/** @var int */
public $maximaleAnzahlDirectDebitTransferTransactionInformation;

/** @var bool */
public $summenfeldBenoetigt;

/** @var bool */
public $einzelbuchungErlaubt;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Fhp\Segment\BME;

use Fhp\Segment\BSE\ParameterTerminierteSEPAFirmenLastschriftEinreichenV2;

class ParameterTerminierteSEPAFirmenSammellastschriftEinreichenV2 extends ParameterTerminierteSEPAFirmenLastschriftEinreichenV2
{
/** @var int */
public $maximaleAnzahlDirectDebitTransferTransactionInformation;

/** @var bool */
public $summenfeldBenoetigt;

/** @var bool */
public $einzelbuchungErlaubt;

/** @var string|null Max Length: 4096 */
public $zulaessigePurposecodes;

/** @var string[]|null @Max(9) Max Length: 256 */
public $unterstuetzteSEPADatenformate;
}
30 changes: 30 additions & 0 deletions lib/Fhp/Segment/BSE/HIBSESv1.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace Fhp\Segment\BSE;

use Fhp\Segment\BaseGeschaeftsvorfallparameter;
use Fhp\Segment\BaseSegment;
use Fhp\Segment\DSE\HIDXES;
use Fhp\Segment\DSE\SEPADirectDebitMinimalLeadTimeProvider;

/**
* Segment: Terminierte SEPA-Einzellastschrift einreichen Parameter
*
* @link https://www.hbci-zka.de/dokumente/spezifikation_deutsch/fintsv3/FinTS_3.0_Messages_Geschaeftsvorfaelle_2015-08-07_final_version.pdf
* Section: C.10.2.6.2.1 c)
*/
class HIBSESv1 extends BaseGeschaeftsvorfallparameter implements HIDXES
{
/** @var ParameterTerminierteSEPAFirmenEinzellastschriftEinreichenV1 */
public $parameter;

public function getParameter(): SEPADirectDebitMinimalLeadTimeProvider
{
return $this->parameter;
}

public function createRequestSegment(): BaseSegment
{
return HKBSEv1::createEmpty();
}
}
30 changes: 30 additions & 0 deletions lib/Fhp/Segment/BSE/HIBSESv2.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace Fhp\Segment\BSE;

use Fhp\Segment\BaseGeschaeftsvorfallparameter;
use Fhp\Segment\BaseSegment;
use Fhp\Segment\DSE\HIDXES;
use Fhp\Segment\DSE\SEPADirectDebitMinimalLeadTimeProvider;

/**
* Segment: Terminierte SEPA-Einzellastschrift einreichen Parameter
*
* @link https://www.hbci-zka.de/dokumente/spezifikation_deutsch/fintsv3/FinTS_3.0_Messages_Geschaeftsvorfaelle_2015-08-07_final_version.pdf
* Section: C.10.2.6.2.2 c)
*/
class HIBSESv2 extends BaseGeschaeftsvorfallparameter implements HIDXES
{
/** @var ParameterTerminierteSEPAFirmenEinzellastschriftEinreichenV2 */
public $parameter;

public function getParameter(): SEPADirectDebitMinimalLeadTimeProvider
{
return $this->parameter;
}

public function createRequestSegment(): BaseSegment
{
return HKBSEv2::createEmpty();
}
}
15 changes: 15 additions & 0 deletions lib/Fhp/Segment/BSE/HKBSEv1.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Fhp\Segment\BSE;

use Fhp\Segment\DSE\HKDSEv1;

/**
* Einreichung terminierter SEPA-Einzellastschriften (Segmentversion 1)
*
* @link https://www.hbci-zka.de/dokumente/spezifikation_deutsch/fintsv3/FinTS_3.0_Messages_Geschaeftsvorfaelle_2015-08-07_final_version.pdf
* Section: C.10.2.6.2.1
*/
class HKBSEv1 extends HKDSEv1
{
}
Loading

0 comments on commit 9b93d6e

Please sign in to comment.