Initial xentral_oss_20.3.c9ffacf

This commit is contained in:
Alex
2021-05-21 08:49:41 +02:00
parent 5406e4a551
commit 34e5ac43d9
18884 changed files with 2109867 additions and 0 deletions
+159
View File
@@ -0,0 +1,159 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi;
use TCPDF;
class BonPdf
{
public const CHAR_WIDTH = 2;
public const FONTSIZE_NORMAL = 4;
public const FONT_SIZE_BIG = 5;
public const ALIGNMENT_LEFT = 0;
public const ALIGNMENT_CENTER = 1;
public const ALIGNMENT_RIGHT = 2;
public const QR_SIZE = 50;
public const MARGIN_LEFT = 20;
public const MARGIN_TOP = 20;
/** @var TCPDF $pdf */
private $pdf;
/**
* BonPdf constructor.
*/
public function __construct()
{
$this->pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
}
private $column = 0;
private $actualFontSize;
private $isBold = false;
private $actualAlignment;
/**
* @param array $bonPrinter
*/
public function draw(array $bonPrinter): void
{
$this->actualFontSize = self::FONTSIZE_NORMAL;
$this->actualAlignment = self::ALIGNMENT_LEFT;
$this->pdf->AddPage();
$this->pdf->SetMargins(self::MARGIN_LEFT, self::MARGIN_TOP);
$this->pdf->SetFont('pdfacourier', $this->isBold ? 'B' : '', $this->actualFontSize);
$this->pdf->SetX(self::MARGIN_LEFT);
foreach($bonPrinter as $command) {
switch($command['type']) {
case 'text':
$this->drawText($command['value']);
break;
case 'font':
$this->setBold(empty($command['value']));
break;
case 'justification':
$this->setAlignment((int)$command['value']);
break;
case 'print_mode':
$this->setFontWeight($command['value']);
break;
case 'qr_code':
$this->drawQrCode($command['value']);
break;
}
}
}
/**
* @return string
*/
public function Output(): string
{
return $this->pdf->Output('', 'S');
}
/**
* @param string $code
*/
private function drawQrCode(string $code): void
{
$y = $this->pdf->GetY();
if($y > 220) {
$this->pdf->AddPage();
$y = $this->pdf->GetY();
}
$style = [
'border' => 0,
'vpadding' => 'auto',
'hpadding' => 'auto',
'fgcolor' => array(0,0,0),
'bgcolor' => false,
'module_width' => 1,
'module_height' => 1
];
$this->pdf->write2DBarcode($code, 'QRCODE,L', self::MARGIN_LEFT, $y, 70, 70, $style, 'N');
}
private function setAlignment(int $alignment): void
{
$this->actualAlignment = $alignment;
}
private function getAlignmentCode(): string
{
switch ($this->actualAlignment) {
case self::ALIGNMENT_RIGHT:
return 'R';
case self::ALIGNMENT_CENTER:
return 'C';
}
return 'L';
}
private function drawText(string $text): void
{
$chars = mb_str_split(str_replace("\r\n", "\r", $text), 1, 'UTF-8');
foreach($chars as $char) {
if($char === "\r" || $char === "\n") {
$this->pdf->Ln(self::FONTSIZE_NORMAL);
$this->pdf->SetX(self::MARGIN_LEFT);
$this->column = 0;
continue;
}
$this->pdf->Cell(self::CHAR_WIDTH, $this->actualFontSize, $char,0,0, $this->getAlignmentCode());
$this->column++;
}
}
/**
* @param $fontValue
*/
private function setFontWeight($fontValue): void
{
if(!empty($fontValue)) {
$this->actualFontSize = self::FONT_SIZE_BIG;
return;
}
$this->actualFontSize = self::FONTSIZE_NORMAL;
}
private function setBold(bool $isBold): void
{
$this->isBold = $isBold;
$this->pdf->SetFont('pdfacourier', $this->isBold ? 'B' : '', $this->actualFontSize);
}
}
+188
View File
@@ -0,0 +1,188 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi;
use Xentral\Components\SchemaCreator\Collection\SchemaCollection;
use Xentral\Components\SchemaCreator\Index\Index;
use Xentral\Components\SchemaCreator\Index\Primary;
use Xentral\Components\SchemaCreator\Index\Unique;
use Xentral\Components\SchemaCreator\Schema\TableSchema;
use Xentral\Components\SchemaCreator\Type;
use Xentral\Core\DependencyInjection\ContainerInterface;
use Xentral\Modules\FiskalyApi\Factory\FiskalyCashPointClosingFactory;
use Xentral\Modules\FiskalyApi\Service\FiskalyConfig;
use Xentral\Modules\FiskalyApi\Service\FiskalyPosClosingService;
use Xentral\Modules\FiskalyApi\Service\FiskalyTransferService;
use Xentral\Modules\FiskalyApi\Service\FiskalyTransactionCacheService;
use Xentral\Modules\FiskalyApi\Service\FiskalyPosMappingService;
use Xentral\Modules\FiskalyApi\Service\FiskalyTransactionPosSessionService;
use Xentral\Modules\FiskalyApi\Service\FiskalyCashPointClosingDBService;
use Xentral\Modules\FiskalyApi\Factory\FiskalyApiFactory;
use Xentral\Modules\FiskalyApi\Factory\FiskalyTransactionFactory;
use Xentral\Modules\FiskalyApi\Wrapper\TaxSettingWrapper;
final class Bootstrap
{
/**
* @return array
*/
public static function registerServices(): array
{
return [
FiskalyApiFactory::class => 'onInitFiskalyApiFactory',
FiskalyTransferService::class => 'onInitFiskalyTransferService',
FiskalyTransactionCacheService::class => 'onInitFiskalyTransactionCacheService',
FiskalyPosMappingService::class => 'onInitFiskalyPosMappingService',
FiskalyTransactionPosSessionService::class => 'onInitFiskalyTransactionPosSessionService',
FiskalyPosClosingService::class => 'onInitFiskalyPosClosingService',
FiskalyCashPointClosingDBService::class => 'onInitFiskalyCashPointClosingDBService',
FiskalyCashPointClosingFactory::class => 'onInitFiskalyCashPointClosingFactory',
TaxSettingWrapper::class => 'onInitTaxSettingWrapper',
FiskalyTransactionFactory::class => 'onInitFiskalyTransactionFactory',
FiskalyConfig::class => 'onInitFiskalyConfig',
];
}
/**
* @param ContainerInterface $container
*
* @return FiskalyApiFactory
*/
public static function onInitFiskalyApiFactory(ContainerInterface $container): FiskalyApiFactory
{
return new FiskalyApiFactory(
$container->get(FiskalyConfig::class)
);
}
/**
* @param ContainerInterface $container
*
* @return FiskalyPosMappingService
*/
public static function onInitFiskalyPosMappingService(ContainerInterface $container): FiskalyPosMappingService
{
return new FiskalyPosMappingService($container->get('Database'));
}
/**
* @param ContainerInterface $container
*
* @return FiskalyTransactionPosSessionService
*/
public static function onInitFiskalyTransactionPosSessionService(ContainerInterface $container
): FiskalyTransactionPosSessionService {
return new FiskalyTransactionPosSessionService($container->get('Database'));
}
/**
* @param ContainerInterface $container
*
* @return FiskalyPosClosingService
*/
public static function onInitFiskalyPosClosingService(ContainerInterface $container): FiskalyPosClosingService
{
$legacyApi = $container->get('LegacyApplication');
return new FiskalyPosClosingService(
$container->get('Database'),
$container->get(FiskalyCashPointClosingFactory::class),
$container->get(TaxSettingWrapper::class)
);
}
public static function onInitTaxSettingWrapper(ContainerInterface $container): TaxSettingWrapper
{
$legacyApi = $container->get('LegacyApplication');
return new TaxSettingWrapper($legacyApi->erp);
}
/**
* @param ContainerInterface $container
*
* @return FiskalyCashPointClosingDBService
*/
public static function onInitFiskalyCashPointClosingDBService(ContainerInterface $container
): FiskalyCashPointClosingDBService {
return new FiskalyCashPointClosingDBService($container->get('Database'));
}
/**
* @param ContainerInterface $container
*
* @return FiskalyCashPointClosingFactory
*/
public static function onInitFiskalyCashPointClosingFactory(ContainerInterface $container
): FiskalyCashPointClosingFactory {
return new FiskalyCashPointClosingFactory();
}
/**
* @param ContainerInterface $container
*
* @return FiskalyTransactionFactory
*/
public static function onInitFiskalyTransactionFactory(ContainerInterface $container
): FiskalyTransactionFactory {
return new FiskalyTransactionFactory($container->get('Database'));
}
/**
* @param ContainerInterface $container
*
* @return FiskalyConfig
*/
public static function onInitFiskalyConfig(ContainerInterface $container): FiskalyConfig
{
return new FiskalyConfig($container->get('SystemConfigModule'), $container->get('EnvironmentConfig'));
}
/**
* @param ContainerInterface $container
*
* @return FiskalyTransactionCacheService
*/
public static function onInitFiskalyTransactionCacheService(ContainerInterface $container
): FiskalyTransactionCacheService {
return new FiskalyTransactionCacheService();
}
/**
* @param ContainerInterface $container
*
* @return FiskalyTransferService
*/
public static function onInitFiskalyTransferService(ContainerInterface $container): FiskalyTransferService
{
return new FiskalyTransferService(
$container->get(FiskalyApiFactory::class),
$container->get(FiskalyTransactionFactory::class),
$container->get('Database')
);
}
/**
* @param SchemaCollection $collection
*
* @return void
*/
public static function registerTableSchemas(SchemaCollection $collection): void
{
$posMappingTable = new TableSchema('fiskaly_pos_mapping');
$posMappingTable->addColumn(Type\Integer::asAutoIncrement('id'));
$posMappingTable->addColumn(new Type\Integer('pos_id', 10, true, null, false));
$posMappingTable->addColumn(new Type\Varchar('tss_uuid', 36, null, false));
$posMappingTable->addColumn(new Type\Text('tss_description', false));
$posMappingTable->addColumn(new Type\Varchar('client_uuid', 36, null, false));
$posMappingTable->addColumn(new Type\Text('client_description', false));
$posMappingTable->addIndex(new Primary(['id']));
$posMappingTable->addIndex(new Unique(['pos_id', 'tss_uuid', 'client_uuid']));
$posMappingTable->addIndex(new Index(['pos_id']));
$collection->add($posMappingTable);
}
}
@@ -0,0 +1,303 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data;
class BillingAddress
{
/** @var string $uuid */
private $uuid;
/** @var string $type */
private $type;
/** @var array $envs */
private $envs;
/** @var string $name */
private $name;
/** @var string $addressLine1 */
private $addressLine1;
/** @var string|null $addressLine2 */
private $addressLine2;
/** @var string $zip */
private $zip;
/** @var string $town */
private $town;
/** @var string $countryCode */
private $countryCode;
/** @var string|null $displayName */
private $displayName;
/** @var string|null $vatId */
private $vatId;
/** @var bool|null $isVatIdValid */
private $isVatIdValid;
/**
* BillingAddress constructor.
*
* @param string $uuId
* @param string $type
* @param array $envs
* @param string $recipient
* @param string $addressLine1
* @param string $zip
* @param string $town
* @param string $countryCode
* @param string|null $addressLine2
* @param string|null $displayName
* @param string|null $vatId
* @param bool|null $isVatIdValid
*/
public function __construct(
string $uuId,
string $type,
array $envs,
string $recipient,
string $addressLine1,
string $zip,
string $town,
string $countryCode,
?string $addressLine2 = null,
?string $displayName = null,
?string $vatId = null,
?bool $isVatIdValid = null
) {
$this->uuid = $uuId;
$this->type = $type;
$this->envs = $envs;
$this->name = $recipient;
$this->addressLine1 = $addressLine1;
$this->zip = $zip;
$this->town = $town;
$this->countryCode = $countryCode;
$this->addressLine2 = $addressLine2;
$this->displayName = $displayName;
$this->vatId = $vatId;
$this->isVatIdValid = $isVatIdValid;
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self(
$apiResult->_id,
$apiResult->_type,
$apiResult->_envs,
$apiResult->recipient,
$apiResult->address_line1,
$apiResult->zip,
$apiResult->town,
$apiResult->country_code,
$apiResult->address_line2 ?? null,
$apiResult->display_name ?? null,
$apiResult->vat_id ?? null,
isset($apiResult->vat_id_valid) ? (bool)$apiResult->vat_id_valid : null
);
}
/**
* @return string
*/
public function getUuid(): string
{
return $this->uuid;
}
/**
* @param string $uuid
*/
public function setUuid(string $uuid): void
{
$this->uuid = $uuid;
}
/**
* @return string
*/
public function getType(): string
{
return $this->type;
}
/**
* @param string $type
*/
public function setType(string $type): void
{
$this->type = $type;
}
/**
* @return array
*/
public function getEnvs(): array
{
return $this->envs;
}
/**
* @param array $envs
*/
public function setEnvs(array $envs): void
{
$this->envs = $envs;
}
/**
* @return string
*/
public function getName(): string
{
return $this->name;
}
/**
* @param string $name
*/
public function setName(string $name): void
{
$this->name = $name;
}
/**
* @return string
*/
public function getAddressLine1(): string
{
return $this->addressLine1;
}
/**
* @param string $addressLine1
*/
public function setAddressLine1(string $addressLine1): void
{
$this->addressLine1 = $addressLine1;
}
/**
* @return string|null
*/
public function getAddressLine2(): ?string
{
return $this->addressLine2;
}
/**
* @param string|null $addressLine2
*/
public function setAddressLine2(?string $addressLine2): void
{
$this->addressLine2 = $addressLine2;
}
/**
* @return string
*/
public function getZip(): string
{
return $this->zip;
}
/**
* @param string $zip
*/
public function setZip(string $zip): void
{
$this->zip = $zip;
}
/**
* @return string
*/
public function getTown(): string
{
return $this->town;
}
/**
* @param string $town
*/
public function setTown(string $town): void
{
$this->town = $town;
}
/**
* @return string
*/
public function getCountryCode(): string
{
return $this->countryCode;
}
/**
* @param string $countryCode
*/
public function setCountryCode(string $countryCode): void
{
$this->countryCode = $countryCode;
}
/**
* @return string|null
*/
public function getDisplayName(): ?string
{
return $this->displayName;
}
/**
* @param string|null $displayName
*/
public function setDisplayName(?string $displayName): void
{
$this->displayName = $displayName;
}
/**
* @return string|null
*/
public function getVatId(): ?string
{
return $this->vatId;
}
/**
* @param string|null $vatId
*/
public function setVatId(?string $vatId): void
{
$this->vatId = $vatId;
}
/**
* @return bool|null
*/
public function getIsVatIdValid(): ?bool
{
return $this->isVatIdValid;
}
/**
* @param bool|null $isVatIdValid
*/
public function setIsVatIdValid(?bool $isVatIdValid): void
{
$this->isVatIdValid = $isVatIdValid;
}
}
@@ -0,0 +1,178 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
use Xentral\Modules\FiskalyApi\Exception\InvalidArgumentException;
class AmountPerVatId
{
/** @var int $vatDefinitionExportId */
private $vatDefinitionExportId;
/** @var float|null $inclVat */
private $inclVat;
/** @var float|null $exclVat */
private $exclVat;
/** @var float|null $vat */
private $vat;
/**
* AmountPerVatId constructor.
*
* @param int $vatDefinitionExportId
* @param float|null $inclVat
* @param float|null $exclVat
* @param float|null $vat
*/
public function __construct(int $vatDefinitionExportId, ?float $inclVat, ?float $exclVat = null, ?float $vat = null)
{
$this->setVatDefinitionExportId($vatDefinitionExportId);
$this->setAmounts($inclVat, $exclVat, $vat);
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self(
(int)$apiResult->vat_definition_export_id,
$apiResult->incl_vat === null ? null : (float)$apiResult->incl_vat,
$apiResult->excl_vat === null ? null : (float)$apiResult->excl_vat,
$apiResult->vat === null ? null : (float)$apiResult->vat
);
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new self(
(int)$dbState['vat_definition_export_id'],
$dbState['incl_vat'] === null ? null : (float)$dbState['incl_vat'],
$dbState['excl_vat'] === null ? null : (float)$dbState['excl_vat'],
$dbState['vat'] === null ? null : (float)$dbState['vat']
);
}
/**
* @return array
*/
public function toArray(): array
{
return [
'vat_definition_export_id' => $this->getVatDefinitionExportId(),
'incl_vat' => $this->getInclVat(),
'excl_vat' => $this->getExclVat(),
'vat' => $this->getVat(),
];
}
/**
* @return int
*/
public function getVatDefinitionExportId(): int
{
return $this->vatDefinitionExportId;
}
/**
* @param int $vatDefinitionExportId
*/
public function setVatDefinitionExportId(int $vatDefinitionExportId): void
{
if ($vatDefinitionExportId <= 0 || $vatDefinitionExportId > 9999999999) {
throw new InvalidArgumentException(
"{$vatDefinitionExportId} is an invalid vat_definition_export_id. [1 .. 9999999999]"
);
}
if ($vatDefinitionExportId >= 8 && $vatDefinitionExportId > 999) {
throw new InvalidArgumentException(
"{$vatDefinitionExportId} is an invalid vat_definition_export_id. [8 - 999] are reserved"
);
}
$this->vatDefinitionExportId = $vatDefinitionExportId;
}
/**
* @return float
*/
public function getInclVat(): float
{
return (float)number_format($this->inclVat, 5, '.', '');
}
/**
* @param float|null $inclVat
* @param float|null $exclVat
* @param float|null $vat
*/
public function setAmounts(?float $inclVat, ?float $exclVat, ?float $vat = null): void
{
$isInclVatNull = $inclVat === null;
$isExclVatNull = $exclVat === null;
$isVatNull = $vat === null;
if (!$isInclVatNull) {
$inclVat = (float)number_format(round($inclVat, 5), 5, '.', '');
}
if (!$isExclVatNull) {
$exclVat = (float)number_format(round($exclVat, 5), 5, '.', '');
}
if (!$isVatNull) {
$vat = (float)number_format(round($vat, 5), 5, '.', '');
}
if ($isInclVatNull) {
if ($isExclVatNull || $isVatNull) {
throw new InvalidArgumentException("VatInfos: two or three Values must not be null");
}
$inclVat = (float)number_format(round($vat + $exclVat, 5), 5, '.', '');
} elseif ($isExclVatNull) {
if ($isVatNull) {
throw new InvalidArgumentException("VatInfos: two or three Values must not be null");
}
$exclVat = (float)number_format(round($inclVat - $vat, 5), 5, '.', '');
} elseif ($isVatNull) {
$vat = (float)number_format(round($inclVat - $exclVat, 5), 5, '.', '');
} elseif (round($inclVat, 5) !== round(round($exclVat, 5) + round($vat, 5), 5)) {
throw new InvalidArgumentException("VatInfos: {$inclVat} is not {$exclVat} + {$vat}");
}
if (
($inclVat > 0 && $exclVat <= 0)
|| ($inclVat > 0 && $exclVat > $inclVat)
|| ($inclVat < 0 && $exclVat >= 0)
|| ($inclVat < 0 && $exclVat < $inclVat)
|| ($inclVat === 0 && $exclVat !== 0)
) {
throw new InvalidArgumentException("inclVat '{$inclVat}' is not matching to exclVat {$exclVat}");
}
$this->inclVat = $inclVat;
$this->exclVat = $exclVat;
$this->vat = $vat;
}
/**
* @return float|null
*/
public function getExclVat(): ?float
{
return (float)number_format($this->exclVat, 5, '.', '');
}
/**
* @return float|null
*/
public function getVat(): ?float
{
return (float)number_format($this->vat, 5, '.', '');
}
}
@@ -0,0 +1,153 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
use ArrayIterator;
use Countable;
use IteratorAggregate;
class AmountPerVatIdCollection implements IteratorAggregate, Countable
{
/** @var AmountPerVatId[] $amountsPerVatId */
private $amountsPerVatId = [];
/**
* AmountPerVatIdCollection constructor.
*
* @param array $amountsPerVatId
*/
public function __construct(array $amountsPerVatId = [])
{
foreach ($amountsPerVatId as $amountPerVatId) {
$this->addAmountPerVatId($amountPerVatId);
}
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult($apiResult): self
{
$instance = new self();
foreach ($apiResult as $item) {
$instance->addAmountPerVatId(AmountPerVatId::fromApiResult($item));
}
return $instance;
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
$instance = new self();
foreach ($dbState as $item) {
$instance->addAmountPerVatId(AmountPerVatId::fromDbState($item));
}
return $instance;
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [];
/** @var AmountPerVatId $amountPerVat */
foreach($this as $amountPerVat) {
$dbState[] = $amountPerVat->toArray();
}
return $dbState;
}
/**
* @param AmountPerVatId $amountPerVatId
*/
public function addAmountPerVatId(AmountPerVatId $amountPerVatId): void
{
$this->amountsPerVatId[] = AmountPerVatId::fromDbState($amountPerVatId->toArray());
}
/**
* @param AmountPerVatIdCollection $collection
*
* @return $this
*/
public function combine(self $collection): self
{
$instance = new self();
foreach($this as $item) {
$instance->addAmountPerVatId($item);
}
foreach($collection as $item) {
$instance->addAmountPerVatId($item);
}
return $instance->groupByVatDefinitionExportId();
}
/**
* @return $this
*/
public function groupByVatDefinitionExportId(): self
{
$instance = new self();
/** @var AmountPerVatId $item */
$indexByVatDefinitionExportId = [];
foreach($this as $item) {
$vatDefinitionExportId = $item->getVatDefinitionExportId();
if(!isset($indexByVatDefinitionExportId[$vatDefinitionExportId])) {
$indexByVatDefinitionExportId[$vatDefinitionExportId] = $item;
}
else {
$indexByVatDefinitionExportId[$vatDefinitionExportId]->setAmounts(
$indexByVatDefinitionExportId[$vatDefinitionExportId]->getInclVat() + $item->getExclVat(),
$indexByVatDefinitionExportId[$vatDefinitionExportId]->getExclVat() + $item->getExclVat()
);
}
}
foreach($indexByVatDefinitionExportId as $item) {
$instance->addAmountPerVatId($item);
}
return $instance;
}
/**
* @return float
*/
public function getSumInclVat(): float
{
$sum = 0;
foreach($this as $item) {
$sum += $item->getInclVat();
}
return $sum;
}
/**
* @return int
*/
public function count(): int
{
return count($this->amountsPerVatId);
}
/**
* @return ArrayIterator
*/
public function getIterator(): ArrayIterator
{
return new ArrayIterator($this->amountsPerVatId);
}
}
@@ -0,0 +1,204 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
use Xentral\Modules\FiskalyApi\Exception\InvalidArgumentException;
class BusinessCase
{
/** @var string $type */
private $type;
/** @var AmountPerVatIdCollection $amountsPerVatId */
private $amountsPerVatId;
/** @var string|null $name */
private $name;
/** @var string|null $purchaserAgencyId */
private $purchaserAgencyId;
/**
* BusinessCase constructor.
*
* @param string $type
* @param AmountPerVatIdCollection $amountsPerVatId
* @param string|null $name
* @param string|null $purchaserAgencyId
*/
public function __construct(
string $type,
AmountPerVatIdCollection $amountsPerVatId,
?string $name = null,
?string $purchaserAgencyId = null
) {
$this->ensureType($type);
$this->type = $type;
$this->name = $name;
$this->purchaserAgencyId = $purchaserAgencyId;
$this->amountsPerVatId = AmountPerVatIdCollection::fromDbState($amountsPerVatId->toArray());
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self(
$apiResult->type,
AmountPerVatIdCollection::fromApiResult($apiResult->amounts_per_vat_id),
$apiResult->name ?? null,
$apiResult->purchaser_agency_id ?? null
);
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new self(
$dbState['type'],
AmountPerVatIdCollection::fromDbState($dbState['amounts_per_vat_id']),
$dbState['name'] ?? null,
$dbState['purchaser_agency_id'] ?? null
);
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [
'type' => $this->getType(),
'amounts_per_vat_id' => $this->amountsPerVatId->toArray(),
];
if($this->name !== null) {
$dbState['name'] = $this->getName();
}
if($this->purchaserAgencyId !== null) {
$dbState['purchaser_agency_id'] = $this->getPurchaserAgencyId();
}
return $dbState;
}
/**
* @return float
*/
public function getSumInclVat(): float
{
return $this->amountsPerVatId->getSumInclVat();
}
/**
* @param string $type
*/
private function ensureType(string $type): void
{
if (
!in_array(
$type,
[
'Anfangsbestand',
'Umsatz',
'Pfand',
'PfandRueckzahlung',
'MehrzweckgutscheinKauf',
'MehrzweckgutscheinEinloesung',
'EinzweckgutscheinKauf',
'EinzweckgutscheinEinloesung',
'Forderungsentstehung',
'Forderungsaufloesung',
'Anzahlungseinstellung',
'Anzahlungsaufloesung',
'Privateinlage',
'Privatentnahme',
'Geldtransit',
'DifferenzSollIst',
'TrinkgeldAG',
'TrinkgeldAN',
'Auszahlung',
'Einzahlung',
'Rabatt',
'Aufschlag',
'Lohnzahlung',
'ZuschussEcht',
'ZuschussUnecht',
]
)) {
throw new InvalidArgumentException("invalid type {$type}");
}
}
/**
* @return string
*/
public function getType(): string
{
return $this->type;
}
/**
* @param string $type
*/
public function setType(string $type): void
{
$this->type = $type;
}
/**
* @return AmountPerVatIdCollection
*/
public function getAmountsPerVatId(): AmountPerVatIdCollection
{
return AmountPerVatIdCollection::fromDbState($this->amountsPerVatId->toArray());
}
/**
* @param AmountPerVatIdCollection $amountsPerVatId
*/
public function setAmountsPerVatId(AmountPerVatIdCollection $amountsPerVatId): void
{
$this->amountsPerVatId = AmountPerVatIdCollection::fromDbState($amountsPerVatId->toArray());
}
/**
* @return string|null
*/
public function getName(): ?string
{
return $this->name;
}
/**
* @param string|null $name
*/
public function setName(?string $name): void
{
$this->name = $name;
}
/**
* @return string|null
*/
public function getPurchaserAgencyId(): ?string
{
return $this->purchaserAgencyId;
}
/**
* @param string|null $purchaserAgencyId
*/
public function setPurchaserAgencyId(?string $purchaserAgencyId): void
{
$this->purchaserAgencyId = $purchaserAgencyId;
}
}
@@ -0,0 +1,148 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
use ArrayIterator;
use Countable;
use IteratorAggregate;
class BusinessCaseCollection implements IteratorAggregate, Countable
{
private $businessCases = [];
public function __construct(array $businessCases = [])
{
foreach($businessCases as $businessCase) {
$this->addBusinessCase($businessCase);
}
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult($apiResult): self
{
$instance = new self();
foreach ($apiResult as $item) {
$instance->addBusinessCase(BusinessCase::fromApiResult($item));
}
return $instance;
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
$instance = new self();
foreach ($dbState as $item) {
$instance->addBusinessCase(BusinessCase::fromDbState($item));
}
return $instance;
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [];
foreach($this as $businessCase) {
$dbState[] = $businessCase->toArray();
}
return $dbState;
}
/**
* @param BusinessCase $businessCase
*/
public function addBusinessCase(BusinessCase $businessCase): self
{
$this->businessCases[] = BusinessCase::fromDbState($businessCase->toArray());
return $this;
}
/**
* @param BusinessCaseCollection $collection
*
* @return $this
*/
public function combine(BusinessCaseCollection $collection): self
{
$instance = new self();
/** @var BusinessCase $item */
foreach($this as $item) {
$instance->addBusinessCase($item);
}
foreach($collection as $item) {
$instance->addBusinessCase($item);
}
return $instance->groupByType();
}
/**
* @return float
*/
public function getSumInclVat(): float
{
$sum = 0;
foreach($this as $item) {
$sum += $item->getSumInclVat();
}
return $sum;
}
/**
* @return $this
*/
public function groupByType(): self
{
$instance = new self();
$businessTypes = [];
/** @var BusinessCase $item */
foreach($this as $item) {
$type = $item->getType();
if (!isset($businessTypes[$type])) {
$businessTypes[$type] = BusinessCase::fromDbState($item->toArray());
} else {
$actualAmountsPerVatId = $businessTypes[$type]->getAmountsPerVatId();
$itemAmountsPerVatId = $item->getAmountsPerVatId();
$amountsPerVatId = $actualAmountsPerVatId->combine($itemAmountsPerVatId);
$businessTypes[$type]->setAmountsPerVatId($amountsPerVatId);
}
}
foreach($businessTypes as $businessCase) {
$instance->addBusinessCase($businessCase);
}
return $instance;
}
/**
* @return int
*/
public function count(): int
{
return count($this->businessCases);
}
/**
* @return ArrayIterator
*/
public function getIterator(): ArrayIterator
{
return new ArrayIterator($this->businessCases);
}
}
@@ -0,0 +1,111 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
use Xentral\Modules\FiskalyApi\Data\Transaction\AmountsPerPaymentType;
use Xentral\Modules\FiskalyApi\Exception\InvalidArgumentException;
class CashAmountByCurrency
{
/** @var string $currencyCode */
private $currencyCode;
/** @var float $amount */
private $amount;
/**
* CashAmountByCurrency constructor.
*
* @param float $amount
* @param string $currencyCode
*/
public function __construct(float $amount, string $currencyCode = 'EUR')
{
$this->ensureCurrency($currencyCode);
$this->setCurrencyCode($currencyCode);
$this->setAmount($amount);
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self((float)$apiResult->amount, $apiResult->currency_code);
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new self(
(float)$dbState['amount'], empty($dbState['currency_code']) ? 'EUR' : $dbState['currency_code']
);
}
/**
* @return array
*/
public function toArray(): array
{
return [
'currency_code' => $this->getCurrencyCode(),
'amount' => $this->getAmount(),
];
}
/**
* @return string
*/
public function getCurrencyCode(): string
{
return $this->currencyCode;
}
/**
* @param string $currencyCode
*/
public function setCurrencyCode(string $currencyCode): void
{
$this->ensureCurrency($currencyCode);
$this->currencyCode = $currencyCode;
}
/**
* @return float
*/
public function getAmount(): float
{
return $this->amount;
}
/**
* @param float $amount
*/
public function setAmount(float $amount): void
{
$this->amount = (float)number_format($amount, 2, '.', '');
}
/**
* @param string $currencyCode
*/
private function ensureCurrency(string $currencyCode): void
{
if (!in_array(
$currencyCode,
AmountsPerPaymentType::getAllowedCurrencies(),
true
)) {
throw new InvalidArgumentException("invalid currency {$currencyCode}");
}
}
}
@@ -0,0 +1,95 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
use ArrayIterator;
use Countable;
use IteratorAggregate;
class CashAmountByCurrencyCollection implements IteratorAggregate, Countable
{
/** @var CashAmountByCurrency[] $cashAmountsByCurrecy */
private $cashAmountsByCurrecy = [];
/**
* CashAmountByCurrencyCollection constructor.
*
* @param array $cashAmountsByCurrecy
*/
public function __construct(array $cashAmountsByCurrecy = [])
{
foreach ($cashAmountsByCurrecy as $cashAmountByCurrecy) {
$this->addAmountPerCurrecy($cashAmountByCurrecy);
}
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult($apiResult): self
{
$instance = new self();
foreach ($apiResult as $item) {
$instance->addAmountPerCurrecy(CashAmountByCurrency::fromApiResult($item));
}
return $instance;
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
$instance = new self();
foreach ($dbState as $item) {
$instance->addAmountPerCurrecy(CashAmountByCurrency::fromDbState($item));
}
return $instance;
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [];
/** @var CashAmountByCurrency $amountPerCurrency */
foreach ($this as $amountPerCurrency) {
$dbState[] = $amountPerCurrency->toArray();
}
return $dbState;
}
/**
* @param CashAmountByCurrency $amountPerCurrency
*/
public function addAmountPerCurrecy(CashAmountByCurrency $amountPerCurrency): void
{
$this->cashAmountsByCurrecy[] = CashAmountByCurrency::fromDbState($amountPerCurrency->toArray());
}
/**
* @return int
*/
public function count(): int
{
return count($this->cashAmountsByCurrecy);
}
/**
* @return ArrayIterator
*/
public function getIterator(): ArrayIterator
{
return new ArrayIterator($this->cashAmountsByCurrecy);
}
}
@@ -0,0 +1,290 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
use stdClass;
use Xentral\Modules\FiskalyApi\Data\MetaData;
use Xentral\Modules\FiskalyApi\Transaction\Transaction;
use Xentral\Modules\FiskalyApi\UuidTool;
class CashPointClosing
{
/** @var string $clientId */
private $clientId;
/** @var int $cashPointClosingExportId */
private $cashPointClosingExportId;
/** @var CashPointClosingHead $head */
private $head;
/** @var CashPointClosingCashStatement $cashStatement */
private $cashStatement;
/** @var CashPointClosingTransactionCollection $transactions */
private $transactions;
/** @var MetaData|null $metaData */
private $metaData;
/** @var string|null $closingId */
private $closingId;
/**
* CashPointClosing constructor.
*
* @param string $clientId
* @param int $cashPointClosingExportId
* @param CashPointClosingHead|null $head
* @param CashPointClosingCashStatement|null $cashStatement
* @param CashPointClosingTransactionCollection|null $transactions
* @param MetaData|null $metaData
*/
public function __construct(
string $clientId,
int $cashPointClosingExportId,
?CashPointClosingHead $head = null,
?CashPointClosingCashStatement $cashStatement = null,
?CashPointClosingTransactionCollection $transactions = null,
?MetaData $metaData = null
) {
$this->setClientId($clientId);
$this->setCashPointClosingExportId($cashPointClosingExportId);
$this->setHead($head);
$this->setCashStatement($cashStatement);
$this->setTransactions($transactions);
$this->setMetaData($metaData);
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult)
{
return new self(
$apiResult->client_id,
(int)$apiResult->cash_point_closing_export_id,
empty($apiResult->head) ? null : CashPointClosingHead::fromApiResult($apiResult->head),
empty($apiResult->cash_statement) ? null : CashPointClosingCashStatement::fromApiResult($apiResult->cash_statement),
empty($apiResult->transactions) ? null : CashPointClosingTransactionCollection::fromApiResult($apiResult->transactions)
);
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState)
{
return new self(
$dbState['client_id'],
(int)$dbState['cash_point_closing_export_id'],
isset($dbState['head']) ? CashPointClosingHead::fromDbState($dbState['head']) : null,
isset($dbState['cash_statement']) ? CashPointClosingCashStatement::fromDbState(
$dbState['cash_statement']
) : null,
isset($dbState['transactions']) ? CashPointClosingTransactionCollection::fromDbState(
$dbState['transactions']
) : null
);
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [
'client_id' => $this->getClientId(),
'cash_point_closing_export_id' => $this->getCashPointClosingExportId(),
];
if($this->head !== null) {
$dbState['head'] = $this->getHead()->toArray();
}
if($this->cashStatement !== null) {
$dbState['cash_statement'] = $this->getCashStatement()->toArray();
}
if($this->transactions !== null) {
$dbState['transactions'] = $this->getTransactions()->toArray();
}
if ($this->metaData !== null) {
$dbState['metadata'] = $this->metaData->toArray();
}
return $dbState;
}
/**
* @return stdClass
*/
public function toApiResult()
{
$apiResult = new stdClass();
$apiResult->client_id = $this->getClientId();
$apiResult->cash_point_closing_export_id = $this->getCashPointClosingExportId();
$apiResult->head = json_decode(json_encode($this->getHead()->toArray()));
$apiResult->cash_statement = json_decode(json_encode($this->getCashStatement()->toArray()));
$apiResult->transactions = json_decode(json_encode($this->getTransactions()->toArray()));
if ($this->metaData !== null) {
$apiResult->metadata = $this->metaData->toApiResult();
}
return $apiResult;
}
/**
* @param BusinessCase $businessCase
*
* @return $this
*/
public function addBusinessCase(BusinessCase $businessCase): self
{
$this->cashStatement->setBusinessCases(
$this->cashStatement->getBusinessCases()->addBusinessCase($businessCase)
);
return $this;
}
/**
* @param CashPointClosingTransaction $transaction
*
* @return $this
*/
public function addTransaction(CashPointClosingTransaction $transaction): self
{
$this->transactions->addTransaction($transaction);
return $this;
}
/**
* @return string
*/
public function getClientId(): string
{
return $this->clientId;
}
/**
* @param string $clientId
*/
public function setClientId(string $clientId): void
{
$this->clientId = $clientId;
}
/**
* @return int
*/
public function getCashPointClosingExportId(): int
{
return $this->cashPointClosingExportId;
}
/**
* @param int $cashPointClosingExportId
*/
public function setCashPointClosingExportId(int $cashPointClosingExportId): void
{
$this->cashPointClosingExportId = $cashPointClosingExportId;
}
/**
* @return CashPointClosingHead
*/
public function getHead(): ?CashPointClosingHead
{
return $this->head === null ? null : CashPointClosingHead::fromDbState($this->head->toArray());
}
/**
* @param CashPointClosingHead|null $head
*/
public function setHead(?CashPointClosingHead $head): void
{
$this->head = $head === null ? null : CashPointClosingHead::fromDbState($head->toArray());
}
/**
* @return CashPointClosingCashStatement|null
*/
public function getCashStatement(): ?CashPointClosingCashStatement
{
return $this->cashStatement === null ? null : CashPointClosingCashStatement::fromDbState(
$this->cashStatement->toArray()
);
}
/**
* @param CashPointClosingCashStatement|null $cashStatement
*/
public function setCashStatement(?CashPointClosingCashStatement $cashStatement): void
{
$this->cashStatement = $cashStatement === null ? null : CashPointClosingCashStatement::fromDbState(
$cashStatement->toArray()
);
}
/**
* @return CashPointClosingTransactionCollection|null
*/
public function getTransactions(): ?CashPointClosingTransactionCollection
{
return $this->transactions === null ? null : CashPointClosingTransactionCollection::fromDbState(
$this->transactions->toArray()
);
}
/**
* @param CashPointClosingTransactionCollection|null $transactions
*/
public function setTransactions(?CashPointClosingTransactionCollection $transactions): void
{
$this->transactions = $transactions === null ? null : CashPointClosingTransactionCollection::fromDbState(
$transactions->toArray()
);
}
/**
* @return MetaData|null
*/
public function getMetaData(): ?MetaData
{
return $this->metaData === null ? null : MetaData::fromDbState($this->metaData->toArray());
}
/**
* @param MetaData|null $metaData
*/
public function setMetaData(?MetaData $metaData): void
{
$this->metaData = $metaData === null ? null : MetaData::fromDbState($metaData->toArray());
}
/**
* @return string|null
*/
public function getClosingId(): ?string
{
if($this->closingId !== null) {
return $this->closingId;
}
$this->closingId = UuidTool::generateUuid();
return $this->closingId;
}
/**
* @param string|null $closingId
*/
public function setClosingId(?string $closingId): void
{
$this->closingId = $closingId;
}
}
@@ -0,0 +1,392 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
use stdClass;
class CashPointClosingApiResponse
{
/** @var string $closingId */
private $closingId;
/** @var int $cashPointClosingExportId */
private $cashPointClosingExportId;
/** @var string $state */
private $state;
/** @var string $clientId */
private $clientId;
/** @var string $firstTransactionExportId */
private $firstTransactionExportId;
/** @var string $lastTransactionExportId */
private $lastTransactionExportId;
/** @var int $exportCreationDate */
private $exportCreationDate;
/** @var float $fullAmount */
private $fullAmount;
/** @var float $cashAmount */
private $cashAmount;
/** @var int $timeCreation */
private $timeCreation;
/** @var int $timeUpdate */
private $timeUpdate;
/** @var string $type */
private $type;
/** @var string $env */
private $env;
/** @var string $version */
private $version;
/**
* CashPointClosingApiResponse constructor.
*
* @param null $apiResult
*/
public function __construct($apiResult = null)
{
if (isset($apiResult->closing_id)) {
$this->setClosingId($apiResult->closing_id);
}
if (isset($apiResult->cash_point_closing_export_id)) {
$this->setCashPointClosingExportId($apiResult->cash_point_closing_export_id);
}
if (isset($apiResult->state)) {
$this->setState($apiResult->state);
}
if (isset($apiResult->client_id)) {
$this->setClientId($apiResult->client_id);
}
if (isset($apiResult->first_transaction_export_id)) {
$this->setFirstTransactionExportId($apiResult->first_transaction_export_id);
}
if (isset($apiResult->last_transaction_export_id)) {
$this->setLastTransactionExportId($apiResult->last_transaction_export_id);
}
if (isset($apiResult->export_creation_date)) {
$this->setExportCreationDate((int)$apiResult->export_creation_date);
}
if (isset($apiResult->full_amount)) {
$this->setFullAmount((float)$apiResult->full_amount);
}
if (isset($apiResult->cash_amount)) {
$this->setCashAmount((float)$apiResult->cash_amount);
}
if (isset($apiResult->time_creation)) {
$this->setTimeCreation((int)$apiResult->time_creation);
}
if (isset($apiResult->time_update)) {
$this->setTimeUpdate((int)$apiResult->time_update);
}
if (isset($apiResult->_type)) {
$this->setType($apiResult->_type);
}
if (isset($apiResult->_env)) {
$this->setEnv($apiResult->_env);
}
if (isset($apiResult->_version)) {
$this->setVersion($apiResult->_version);
}
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
$apiResult = new stdClass();
$apiResult->closing_id = $dbState['closing_id'] ?? null;
$apiResult->cash_point_closing_export_id = $dbState['cash_point_closing_export_id'] ?? null;
$apiResult->state = $dbState['state'] ?? null;
$apiResult->client_id = $dbState['client_id'] ?? null;
$apiResult->first_transaction_export_id = $dbState['first_transaction_export_id'] ?? null;
$apiResult->last_transaction_export_id = $dbState['last_transaction_export_id'] ?? null;
$apiResult->export_creation_date = $dbState['export_creation_date'] ?? null;
$apiResult->full_amount = $dbState['full_amount'] ?? null;
$apiResult->cash_amount = $dbState['cash_amount'] ?? null;
$apiResult->time_creation = $dbState['time_creation'] ?? null;
$apiResult->time_update = $dbState['time_update'] ?? null;
$apiResult->_type = $dbState['_type'] ?? null;
$apiResult->_env = $dbState['_env'] ?? null;
$apiResult->_version = $dbState['_version'] ?? null;
return new self($apiResult);
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self($apiResult);
}
/**
* @return array
*/
public function toArray(): array
{
return json_decode(json_encode($this->toApiResult()), true);
}
public function toApiResult(): stdClass
{
$apiResult = new stdClass();
$apiResult->closing_id = $this->getClosingId();
$apiResult->cash_point_closing_export_id = $this->getCashPointClosingExportId();
$apiResult->state = $this->getState();
$apiResult->client_id = $this->getClientId();
$apiResult->first_transaction_export_id = $this->getFirstTransactionExportId();
$apiResult->last_transaction_export_id = $this->getLastTransactionExportId();
$apiResult->export_creation_date = $this->getExportCreationDate();
$apiResult->full_amount = $this->getFullAmount();
$apiResult->cash_amount = $this->getCashAmount();
$apiResult->time_creation = $this->getTimeCreation();
$apiResult->time_update = $this->getTimeUpdate();
$apiResult->_type = $this->getType();
$apiResult->_env = $this->getEnv();
$apiResult->_version = $this->getVersion();
return $apiResult;
}
/**
* @return string
*/
public function getClosingId(): string
{
return $this->closingId;
}
/**
* @param string $closingId
*/
public function setClosingId(string $closingId): void
{
$this->closingId = $closingId;
}
/**
* @return int
*/
public function getCashPointClosingExportId(): int
{
return $this->cashPointClosingExportId;
}
/**
* @param int $cashPointClosingExportId
*/
public function setCashPointClosingExportId(int $cashPointClosingExportId): void
{
$this->cashPointClosingExportId = $cashPointClosingExportId;
}
/**
* @return string
*/
public function getState(): string
{
return $this->state;
}
/**
* @param string $state
*/
public function setState(string $state): void
{
$this->state = $state;
}
/**
* @return string
*/
public function getClientId(): string
{
return $this->clientId;
}
/**
* @param string $clientId
*/
public function setClientId(string $clientId): void
{
$this->clientId = $clientId;
}
/**
* @return string
*/
public function getFirstTransactionExportId(): string
{
return $this->firstTransactionExportId;
}
/**
* @param string $firstTransactionExportId
*/
public function setFirstTransactionExportId(string $firstTransactionExportId): void
{
$this->firstTransactionExportId = $firstTransactionExportId;
}
/**
* @return string
*/
public function getLastTransactionExportId(): string
{
return $this->lastTransactionExportId;
}
/**
* @param string $lastTransactionExportId
*/
public function setLastTransactionExportId(string $lastTransactionExportId): void
{
$this->lastTransactionExportId = $lastTransactionExportId;
}
/**
* @return int
*/
public function getExportCreationDate(): int
{
return $this->exportCreationDate;
}
/**
* @param int $exportCreationDate
*/
public function setExportCreationDate(int $exportCreationDate): void
{
$this->exportCreationDate = $exportCreationDate;
}
/**
* @return float
*/
public function getFullAmount(): float
{
return $this->fullAmount;
}
/**
* @param float $fullAmount
*/
public function setFullAmount(float $fullAmount): void
{
$this->fullAmount = $fullAmount;
}
/**
* @return float
*/
public function getCashAmount(): float
{
return $this->cashAmount;
}
/**
* @param float $cashAmount
*/
public function setCashAmount(float $cashAmount): void
{
$this->cashAmount = $cashAmount;
}
/**
* @return int
*/
public function getTimeCreation(): int
{
return $this->timeCreation;
}
/**
* @param int $timeCreation
*/
public function setTimeCreation(int $timeCreation): void
{
$this->timeCreation = $timeCreation;
}
/**
* @return int
*/
public function getTimeUpdate(): int
{
return $this->timeUpdate;
}
/**
* @param int $timeUpdate
*/
public function setTimeUpdate(int $timeUpdate): void
{
$this->timeUpdate = $timeUpdate;
}
/**
* @return string
*/
public function getType(): string
{
return $this->type;
}
/**
* @param string $type
*/
public function setType(string $type): void
{
$this->type = $type;
}
/**
* @return string
*/
public function getEnv(): string
{
return $this->env;
}
/**
* @param string $env
*/
public function setEnv(string $env): void
{
$this->env = $env;
}
/**
* @return string
*/
public function getVersion(): string
{
return $this->version;
}
/**
* @param string $version
*/
public function setVersion(string $version): void
{
$this->version = $version;
}
}
@@ -0,0 +1,107 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
use ArrayIterator;
use Countable;
use IteratorAggregate;
class CashPointClosingApiResponseCollection implements IteratorAggregate, Countable
{
/** @var CashPointClosingApiResponse[] */
private $cashPointClosingApiResponses = [];
/**
* CashPointClosingApiResponseCollection constructor.
*
* @param CashPointClosingApiResponse[] $cashPointClosingApiResponses
*/
public function __construct(array $cashPointClosingApiResponses = [])
{
foreach ($cashPointClosingApiResponses as $apiResponse) {
$this->addCashPointClosingApiResponse($apiResponse);
}
}
/**
* @param CashPointClosingApiResponse $apiResponse
*/
public function addCashPointClosingApiResponse(CashPointClosingApiResponse $apiResponse): void
{
$this->cashPointClosingApiResponses[] = CashPointClosingApiResponse::fromDbState($apiResponse->toArray());
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
$instance = new self();
foreach ($apiResult as $item) {
$instance->addCashPointClosingApiResponse(CashPointClosingApiResponse::fromApiResult($item));
}
return $instance;
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
$instance = new self();
foreach ($dbState as $item) {
$instance->addCashPointClosingApiResponse(CashPointClosingApiResponse::fromDbState($item));
}
return $instance;
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [];
foreach ($this as $item) {
$dbState[] = $item->toArray();
}
return $dbState;
}
/**
* @return array
*/
public function toApiResult(): array
{
$apiResult = [];
foreach ($this as $item) {
$dbState[] = $item->toApiResult();
}
return $apiResult;
}
/**
* @return int
*/
public function count(): int
{
return count($this->cashPointClosingApiResponses);
}
/**
* @return ArrayIterator
*/
public function getIterator(): ArrayIterator
{
return new ArrayIterator($this->cashPointClosingApiResponses);
}
}
@@ -0,0 +1,95 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
class CashPointClosingCashStatement
{
/** @var BusinessCaseCollection $businessCases */
private $businessCases;
/** @var CashPointClosingPayment $payment */
private $payment;
/**
* CashPointClosingCashStatement constructor.
*
* @param BusinessCaseCollection $businessCases
* @param CashPointClosingPayment $payment
*/
public function __construct(BusinessCaseCollection $businessCases, CashPointClosingPayment $payment)
{
$this->setBusinessCases($businessCases);
$this->setPayment($payment);
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self(
BusinessCaseCollection::fromApiResult($apiResult->business_cases),
CashPointClosingPayment::fromApiResult($apiResult->payment)
);
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new self(
BusinessCaseCollection::fromDbState($dbState['business_cases']),
CashPointClosingPayment::fromDbState($dbState['payment'])
);
}
/**
* @return array
*/
public function toArray(): array
{
return [
'business_cases' => $this->getBusinessCases()->toArray(),
'payment' => $this->getPayment()->toArray(),
];
}
/**
* @return BusinessCaseCollection
*/
public function getBusinessCases(): BusinessCaseCollection
{
return BusinessCaseCollection::fromDbState($this->businessCases->toArray());
}
/**
* @param BusinessCaseCollection $businessCases
*/
public function setBusinessCases(BusinessCaseCollection $businessCases): void
{
$this->businessCases = BusinessCaseCollection::fromDbState($businessCases->toArray());
}
/**
* @return CashPointClosingPayment
*/
public function getPayment(): CashPointClosingPayment
{
return CashPointClosingPayment::fromDbState($this->payment->toArray());
}
/**
* @param CashPointClosingPayment $payment
*/
public function setPayment(CashPointClosingPayment $payment): void
{
$this->payment = CashPointClosingPayment::fromDbState($payment->toArray());
}
}
@@ -0,0 +1,105 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
use DateTime;
use DateTimeInterface;
class CashPointClosingExternalDocumentReference extends CashPointClosingTransactionLineReference
{
/** @var string $externalExportId */
private $externalExportId;
/** @var DateTimeInterface $date */
private $date;
/**
* CashPointClosingExternalDocumentReference constructor.
*
* @param string $type
* @param string $externalExportId
* @param DateTimeInterface|null $date
*/
public function __construct(string $type, string $externalExportId, ?DateTimeInterface $date = null)
{
parent::__construct($type);
$this->externalExportId = $externalExportId;
$this->date = $date;
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): CashPointClosingExternalDocumentReference
{
return new self(
$apiResult->type,
$apiResult->external_export_id,
$apiResult->date === null ? null : (new DateTime())->setTimestamp($apiResult->date)
);
}
/**
* @param array $dbState
*
* @return CashPointClosingExternalDocumentReference
*/
public static function fromDbState(array $dbState): CashPointClosingExternalDocumentReference
{
return new self(
$dbState['type'],
$dbState['external_export_id'],
$dbState['date'] === null ? null : (new DateTime())->setTimestamp($dbState['date'])
);
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = parent::toArray();
$dbState['external_export_id'] = $this->externalExportId;
if($this->date !== null) {
$dbState['date'] = $this->date->getTimestamp();
}
return $dbState;
}
/**
* @return string
*/
public function getExternalExportId(): string
{
return $this->externalExportId;
}
/**
* @param string $externalExportId
*/
public function setExternalExportId(string $externalExportId): void
{
$this->externalExportId = $externalExportId;
}
/**
* @return DateTimeInterface
*/
public function getDate(): ?DateTimeInterface
{
return $this->date;
}
/**
* @param DateTimeInterface $date
*/
public function setDate(?DateTimeInterface $date): void
{
$this->date = $date;
}
}
@@ -0,0 +1,155 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
use DateTime;
use DateTimeInterface;
use DateTimeZone;
class CashPointClosingHead
{
/** @var DateTimeInterface $exportCreationDate */
private $exportCreationDate;
/** @var string $firstTransactionExportId */
private $firstTransactionExportId;
/** @var string $lastTransactionExportId */
private $lastTransactionExportId;
/** @var DateTimeInterface|null $businessDate */
private $businessDate;
/**
* CashPointClosingHead constructor.
*
* @param DateTimeInterface $exportCreationDate
* @param string $firstTransactionExportId
* @param string $lastTransactionExportId
* @param DateTimeInterface|null $businessDate
*/
public function __construct(
DateTimeInterface $exportCreationDate,
string $firstTransactionExportId,
string $lastTransactionExportId,
?DateTimeInterface $businessDate = null
) {
$this->setExportCreationDate($exportCreationDate);
$this->setFirstTransactionExportId($firstTransactionExportId);
$this->setLastTransactionExportId($lastTransactionExportId);
$this->setBusinessDate($businessDate);
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self(
(new DateTime())->setTimestamp($apiResult->export_creation_date),
$apiResult->first_transaction_export_id,
$apiResult->last_transaction_export_id,
empty($apiResult->business_date) ? null : new DateTime($apiResult->business_date, new DateTimeZone('UTC'))
);
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new self(
(new DateTime())->setTimestamp($dbState['export_creation_date']),
$dbState['first_transaction_export_id'],
$dbState['last_transaction_export_id'],
empty($dbState['business_date']) ? null : new DateTime($dbState['business_date'], new DateTimeZone('UTC'))
);
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [
'export_creation_date' => $this->getExportCreationDate()->getTimestamp(),
'first_transaction_export_id' => $this->getFirstTransactionExportId(),
'last_transaction_export_id' => $this->getLastTransactionExportId(),
];
if ($this->businessDate !== null) {
$dbState['business_date'] = $this->businessDate->format('Y-m-d');
}
return $dbState;
}
/**
* @return DateTimeInterface
*/
public function getExportCreationDate(): DateTimeInterface
{
return $this->exportCreationDate;
}
/**
* @param DateTimeInterface $exportCreationDate
*/
public function setExportCreationDate(DateTimeInterface $exportCreationDate): void
{
$this->exportCreationDate = $exportCreationDate;
}
/**
* @return string
*/
public function getFirstTransactionExportId(): string
{
return $this->firstTransactionExportId;
}
/**
* @param string $firstTransactionExportId
*/
public function setFirstTransactionExportId(string $firstTransactionExportId): void
{
$this->firstTransactionExportId = $firstTransactionExportId;
}
/**
* @return string
*/
public function getLastTransactionExportId(): string
{
return $this->lastTransactionExportId;
}
/**
* @param string $lastTransactionExportId
*/
public function setLastTransactionExportId(string $lastTransactionExportId): void
{
$this->lastTransactionExportId = $lastTransactionExportId;
}
/**
* @return DateTimeInterface|null
*/
public function getBusinessDate(): ?DateTimeInterface
{
return $this->businessDate;
}
/**
* @param DateTimeInterface|null $businessDate
*/
public function setBusinessDate(?DateTimeInterface $businessDate): void
{
$this->businessDate = $businessDate;
}
}
@@ -0,0 +1,70 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
class CashPointClosingInternalTransaktionReference extends CashPointClosingTransactionLineReference
{
/** @var string $txId */
private $txId;
/**
* CashPointClosingInternalTransaktionReference constructor.
*
* @param string $type
* @param string $txId
*/
public function __construct(string $type, string $txId)
{
parent::__construct($type);
$this->txId = $txId;
}
/**
* @param $apiResult
*
* @return CashPointClosingInternalTransaktionReference
*/
public static function fromApiResult(object $apiResult): CashPointClosingInternalTransaktionReference
{
return new self($apiResult->type, $apiResult->tx_id);
}
/**
* @param array $dbState
*
* @return CashPointClosingInternalTransaktionReference
*/
public static function fromDbState(array $dbState): CashPointClosingInternalTransaktionReference
{
return new self($dbState['type'], $dbState['tx_id']);
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = parent::toArray();
$dbState['tx_id'] = $this->txId;
return $dbState;
}
/**
* @return string
*/
public function getTxId(): string
{
return $this->txId;
}
/**
* @param string $txId
*/
public function setTxId(string $txId): void
{
$this->txId = $txId;
}
}
@@ -0,0 +1,130 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
use DateTime;
use DateTimeInterface;
class CashPointClosingOtherReference extends CashPointClosingTransactionLineReference
{
/** @var string $externalOtherExportId */
private $externalOtherExportId;
/** @var string $name */
private $name;
/** @var DateTimeInterface $date */
private $date;
/**
* CashPointClosingOtherReference constructor.
*
* @param string $type
* @param string $externalOtherExportId
* @param string $name
* @param DateTimeInterface|null $date
*/
public function __construct(string $type, string $externalOtherExportId, string $name, ?DateTimeInterface $date = null)
{
parent::__construct($type);
$this->externalOtherExportId = $externalOtherExportId;
$this->name = $name;
$this->date = $date;
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): CashPointClosingTransactionLineReference
{
return new self(
$apiResult->type,
$apiResult->external_other_export_id,
$apiResult->name,
$apiResult->date === null ? null : (new DateTime())->setTimestamp($apiResult->date)
);
}
/**
* @param array $dbState
*
* @return CashPointClosingTransactionLineReference
*/
public static function fromDbState(array $dbState): CashPointClosingTransactionLineReference
{
return new self(
$dbState['type'],
$dbState['external_other_export_id'],
$dbState['name'],
$dbState['date'] === null ? null : (new DateTime())->setTimestamp($dbState['date'])
);
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = parent::toArray();
$dbState['external_other_export_id'] = $this->externalOtherExportId;
$dbState['name'] = $this->name;
if($this->date !== null) {
$dbState['date'] = $this->date->getTimestamp();
}
return $dbState;
}
/**
* @return string
*/
public function getExternalOtherExportId(): string
{
return $this->externalOtherExportId;
}
/**
* @param string $externalOtherExportId
*/
public function setExternalOtherExportId(string $externalOtherExportId): void
{
$this->externalOtherExportId = $externalOtherExportId;
}
/**
* @return string
*/
public function getName(): string
{
return $this->name;
}
/**
* @param string $name
*/
public function setName(string $name): void
{
$this->name = $name;
}
/**
* @return DateTimeInterface
*/
public function getDate(): ?DateTimeInterface
{
return $this->date;
}
/**
* @param DateTimeInterface $date
*/
public function setDate(?DateTimeInterface $date): void
{
$this->date = $date;
}
}
@@ -0,0 +1,147 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
class CashPointClosingPayment
{
/** @var float $fullAmount */
private $fullAmount;
/** @var float $cashAmount */
private $cashAmount;
/** @var CashAmountByCurrencyCollection $cashAmountsByCurrency */
private $cashAmountsByCurrency;
/** @var CashPointClosingPaymentTypeCollection $paymentTypes */
private $paymentTypes;
/**
* CashPointClosingPayment constructor.
*
* @param float $fullAmount
* @param float $cashAmount
* @param CashAmountByCurrencyCollection $cashAmountsByCurrency
* @param CashPointClosingPaymentTypeCollection $paymentTypes
*/
public function __construct(
float $fullAmount,
float $cashAmount,
CashAmountByCurrencyCollection $cashAmountsByCurrency,
CashPointClosingPaymentTypeCollection $paymentTypes
) {
$this->setFullAmount($fullAmount);
$this->setCashAmount($cashAmount);
$this->setCashAmountsByCurrency($cashAmountsByCurrency);
$this->setPaymentTypes($paymentTypes);
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self(
(float)$apiResult->full_amount,
(float)$apiResult->cash_amount,
CashAmountByCurrencyCollection::fromApiResult($apiResult->cash_amounts_by_currency),
CashPointClosingPaymentTypeCollection::fromApiResult($apiResult->payment_types)
);
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new self(
(float)$dbState['full_amount'],
(float)$dbState['cash_amount'],
CashAmountByCurrencyCollection::fromDbState($dbState['cash_amounts_by_currency']),
CashPointClosingPaymentTypeCollection::fromDbState($dbState['payment_types'])
);
}
/**
* @return array
*/
public function toArray(): array
{
return [
'full_amount' => $this->getFullAmount(),
'cash_amount' => $this->getCashAmount(),
'cash_amounts_by_currency' => $this->getCashAmountsByCurrency()->toArray(),
'payment_types' => $this->getPaymentTypes()->toArray(),
];
}
/**
* @return float
*/
public function getFullAmount(): float
{
return $this->fullAmount;
}
/**
* @param float $fullAmount
*/
public function setFullAmount(float $fullAmount): void
{
$this->fullAmount = (float)number_format($fullAmount, 2, '.', '');
}
/**
* @return mixed
*/
public function getCashAmount()
{
return $this->cashAmount;
}
/**
* @param float $cashAmount
*/
public function setCashAmount(float $cashAmount): void
{
$this->cashAmount = (float)number_format($cashAmount, 2, '.', '');
}
/**
* @return CashAmountByCurrencyCollection
*/
public function getCashAmountsByCurrency(): CashAmountByCurrencyCollection
{
return CashAmountByCurrencyCollection::fromDbState($this->cashAmountsByCurrency->toArray());
}
/**
* @param CashAmountByCurrencyCollection $cashAmountsByCurrency
*/
public function setCashAmountsByCurrency(CashAmountByCurrencyCollection $cashAmountsByCurrency): void
{
$this->cashAmountsByCurrency = CashAmountByCurrencyCollection::fromDbState($cashAmountsByCurrency->toArray());
}
/**
* @return CashPointClosingPaymentTypeCollection
*/
public function getPaymentTypes(): CashPointClosingPaymentTypeCollection
{
return CashPointClosingPaymentTypeCollection::fromDbState($this->paymentTypes->toArray());
}
/**
* @param CashPointClosingPaymentTypeCollection $paymentTypes
*/
public function setPaymentTypes(CashPointClosingPaymentTypeCollection $paymentTypes): void
{
$this->paymentTypes = CashPointClosingPaymentTypeCollection::fromDbState($paymentTypes->toArray());
}
}
@@ -0,0 +1,209 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
use Xentral\Modules\FiskalyApi\Data\Transaction\AmountsPerPaymentType;
use Xentral\Modules\FiskalyApi\Exception\InvalidArgumentException;
class CashPointClosingPaymentType
{
private $type;
private $currencyCode;
private $amount;
private $name;
private $foreignAmount;
/**
* CashPointClosingPaymentType constructor.
*
* @param string $type
* @param float $amount
* @param string $currencyCode
* @param string|null $name
* @param float|null $foreignAmount
*/
public function __construct(
string $type,
float $amount,
string $currencyCode = 'EUR',
?string $name = null,
?float $foreignAmount = null
) {
$this->ensureType($type);
$this->ensureCurrency($currencyCode);
$this->setType($type);
$this->setAmount($amount);
$this->setCurrencyCode($currencyCode);
$this->setName($name);
$this->setForeignAmount($foreignAmount);
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self(
$apiResult->type,
(float)$apiResult->amount,
$apiResult->currency_code,
$apiResult->name ?? null,
$apiResult->foreign_amount ?? null
);
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new self(
$dbState['type'],
(float)$dbState['amount'],
$dbState['currency_code'] ?? 'EUR',
$dbState['name'] ?? null,
$dbState['foreign_amount'] ?? null
);
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [
'type' => $this->getType(),
'amount' => $this->getAmount(),
'currency_code' => $this->getCurrencyCode(),
];
if ($this->name !== null) {
$dbState['name'] = $this->getName();
}
if ($this->foreignAmount !== null) {
$dbState['foreign_amount'] = $this->getForeignAmount();
}
return $dbState;
}
/**
* @return string
*/
public function getType(): string
{
return $this->type;
}
/**
* @param string $type
*/
public function setType(string $type): void
{
$this->ensureType($type);
$this->type = $type;
}
/**
* @return string
*/
public function getCurrencyCode(): string
{
return $this->currencyCode;
}
/**
* @param string $currencyCode
*/
public function setCurrencyCode(string $currencyCode): void
{
$this->ensureCurrency($currencyCode);
$this->currencyCode = $currencyCode;
}
/**
* @return float
*/
public function getAmount(): float
{
return $this->amount;
}
/**
* @param float $amount
*/
public function setAmount(float $amount): void
{
$this->amount = (float)number_format($amount, 2, '.', '');
}
/**
* @return string|null
*/
public function getName(): ?string
{
return $this->name;
}
/**
* @param string|null $name
*/
public function setName(?string $name): void
{
$this->name = $name === null ? null : mb_substr($name, 0, 60);
}
/**
* @return float|null
*/
public function getForeignAmount(): ?float
{
return $this->foreignAmount;
}
/**
* @param float|null $foreignAmount
*/
public function setForeignAmount(?float $foreignAmount): void
{
$this->foreignAmount = $foreignAmount === null ? null : (float)number_format($foreignAmount, 2, '.', '');
}
/**
* @param string $type
*/
private function ensureType(string $type): void
{
if (
!in_array(
$type,
['Bar', 'Unbar', 'ECKarte', 'Kreditkarte', 'ElZahlungsdienstleister', 'GuthabenKarte', 'Keine']
)) {
throw new InvalidArgumentException("invalid type {$type}");
}
}
/**
* @param string $currency
*/
private function ensureCurrency(string $currency): void
{
if (!in_array(
$currency,
AmountsPerPaymentType::getAllowedCurrencies(),
true
)) {
throw new InvalidArgumentException("invalid currency {$currency}");
}
}
}
@@ -0,0 +1,175 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
use ArrayIterator;
use Countable;
use IteratorAggregate;
class CashPointClosingPaymentTypeCollection implements IteratorAggregate, Countable
{
/** @var CashPointClosingPaymentType[] $paymentTypes */
private $paymentTypes = [];
/**
* CashPointClosingPaymentTypeCollection constructor.
*
* @param CashPointClosingPaymentType[] $paymentTypes
*/
public function __construct(array $paymentTypes = [])
{
foreach ($paymentTypes as $paymentType) {
$this->addPaymentType($paymentType);
}
}
/**
* @param CashPointClosingPaymentType $paymentType
*/
public function addPaymentType(CashPointClosingPaymentType $paymentType): void
{
$this->paymentTypes[] = CashPointClosingPaymentType::fromDbState($paymentType->toArray());
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult($apiResult): self
{
$instance = new self();
foreach ($apiResult as $item) {
$instance->addPaymentType(CashPointClosingPaymentType::fromApiResult($item));
}
return $instance;
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
$instance = new self();
foreach ($dbState as $item) {
$instance->addPaymentType(CashPointClosingPaymentType::fromDbState($item));
}
return $instance;
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [];
/** @var CashPointClosingPaymentType $item */
foreach ($this as $item) {
$dbState[] = $item->toArray();
}
return $dbState;
}
/**
* @param CashPointClosingPaymentTypeCollection $paymentTypeCollection
*
* @return $this
*/
public function combine(self $paymentTypeCollection): self
{
/** @var CashPointClosingPaymentType $paymentType */
foreach($paymentTypeCollection as $paymentType) {
$keys = $this->findKeysForType($paymentType);
if(empty($keys)) {
$this->addPaymentType($paymentType);
continue;
}
$key = reset($keys);
$this->paymentTypes[$key]->setAmount($paymentType->getAmount() + $this->paymentTypes[$key]->getAmount());
}
return $this;
}
/**
* @return $this
*/
public function getGrouped(): self
{
$instance = new self();
$byType = [];
/** @var CashPointClosingPaymentType $paymentType */
foreach($this as $paymentType) {
$type = $paymentType->getType();
if(!isset($byType[$type])) {
$byType[$type] = CashPointClosingPaymentType::fromDbState($paymentType->toArray());
} else {
$byType[$type]->setAmount($byType[$type]->getAmount() + $paymentType->getAmount());
}
}
foreach($byType as $paymentType) {
$instance->addPaymentType($paymentType);
}
return $instance;
}
/**
* @param string $type
* @param float $amount
* @param string $currencyCode
* @param string|null $name
* @param float|null $foreignAmount
*
* @return array
*/
private function findKeysForType(CashPointClosingPaymentType $paymentTypeToFind): array
{
$keys = [];
/**
* @var int $key
* @var CashPointClosingPaymentType $paymentType
*/
foreach($this as $key => $paymentType) {
if($paymentType->getType() !== $paymentTypeToFind->getType()) {
continue;
}
if($paymentType->getCurrencyCode() !== $paymentTypeToFind->getCurrencyCode()) {
continue;
}
if($paymentType->getName() !== $paymentTypeToFind->getName()) {
continue;
}
if($paymentType->getForeignAmount() !== $paymentTypeToFind->getForeignAmount()) {
continue;
}
$keys[] = $key;
}
return $keys;
}
/**
* @return ArrayIterator
*/
public function getIterator(): ArrayIterator
{
return new ArrayIterator($this->paymentTypes);
}
/**
* @return int
*/
public function count(): int
{
return count($this->paymentTypes);
}
}
@@ -0,0 +1,237 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
use DateTime;
use DateTimeInterface;
use DateTimeZone;
use Exception;
use stdClass;
use Xentral\Modules\FiskalyApi\Data\ErrorMessage;
use Xentral\Modules\FiskalyApi\Data\MetaData;
class CashPointClosingResponse extends CashPointClosing
{
/** @var DateTimeInterface|null $timeCreation */
private $timeCreation;
/** @var DateTimeInterface|null $timeUpdate */
private $timeUpdate;
/** @var string|null $state */
private $state;
/** @var ErrorMessage|null $error */
private $error;
/** @var string|null $closingId */
private $closingId;
/**
* CashPointClosingResponse constructor.
*
* @param string $clientId
* @param int $cashPointClosingExportId
* @param CashPointClosingHead|null $head
* @param CashPointClosingCashStatement|null $cashStatement
* @param CashPointClosingTransactionCollection|null $transactions
* @param MetaData|null $metaData
* @param DateTimeInterface|null $timeCreation
* @param DateTimeInterface|null $timeUpdate
* @param string|null $state
* @param ErrorMessage|null $error
*/
public function __construct(
string $clientId,
int $cashPointClosingExportId,
?CashPointClosingHead $head,
?CashPointClosingCashStatement $cashStatement,
?CashPointClosingTransactionCollection $transactions,
?MetaData $metaData = null,
?DateTimeInterface $timeCreation = null,
?DateTimeInterface $timeUpdate = null,
?string $state = null,
?ErrorMessage $error = null
) {
parent::__construct($clientId, $cashPointClosingExportId, $head, $cashStatement, $transactions, $metaData);
$this->setTimeCreation($timeCreation);
$this->setTimeUpdate($timeUpdate);
$this->setState($state);
$this->setError($error);
}
/**
* @param $apiResult
*
* @throws Exception
* @return CashPointClosingResponse
*/
public static function fromApiResult(object $apiResult): CashPointClosingResponse
{
$instance = new self(
$apiResult->client_id,
(int)$apiResult->cash_point_closing_export_id,
empty($apiResult->head) ? null : CashPointClosingHead::fromApiResult($apiResult->head),
empty($apiResult->cash_statement) ? null : CashPointClosingCashStatement::fromApiResult($apiResult->cash_statement),
empty($apiResult->transactions) ? null : CashPointClosingTransactionCollection::fromApiResult($apiResult->transactions)
);
if (!empty($apiResult->time_creation)) {
$instance->setTimeCreation(
(new DateTime('now', new DateTimeZone('UTC')))->setTimestamp($apiResult->time_creation)
);
}
if (!empty($apiResult->time_update)) {
$instance->setTimeUpdate(
(new DateTime('now', new DateTimeZone('UTC')))->setTimestamp($apiResult->time_update)
);
}
if (!empty($apiResult->state)) {
$instance->setState($apiResult->state);
}
return $instance;
}
/**
* @param array $dbState
*
* @throws Exception
* @return CashPointClosingResponse
*/
public static function fromDbState(array $dbState): CashPointClosingResponse
{
$instance = new self(
$dbState['client_id'],
(int)$dbState['cash_point_closing_export_id'],
isset($dbState['head']) ? CashPointClosingHead::fromDbState($dbState['head']) : null,
isset($dbState['cash_statement']) ? CashPointClosingCashStatement::fromDbState(
$dbState['cash_statement']
) : null,
isset($dbState['transactions']) ? CashPointClosingTransactionCollection::fromDbState(
$dbState['transactions']
) : null
);
if (!empty($dbState['time_creation'])) {
$instance->setTimeCreation(
(new DateTime('now', new DateTimeZone('UTC')))->setTimestamp($dbState['time_creation'])
);
}
if (!empty($dbState['time_update'])) {
$instance->setTimeUpdate(
(new DateTime('now', new DateTimeZone('UTC')))->setTimestamp($dbState['time_update'])
);
}
if (!empty($dbState['state'])) {
$instance->setState($dbState['state']);
}
return $instance;
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = parent::toArray();
if ($this->timeCreation !== null) {
$dbState['time_creation'] = $this->timeCreation->getTimestamp();
}
if ($this->timeUpdate !== null) {
$dbState['time_update'] = $this->timeUpdate->getTimestamp();
}
if ($this->state !== null) {
$dbState['state'] = $this->state;
}
if ($this->error !== null) {
$dbState['error'] = $this->error->toArray();
}
return $dbState;
}
/**
* @return stdClass
*/
public function toApiResult(): stdClass
{
$apiResult = parent::toApiResult();
if ($this->timeCreation !== null) {
$apiResult->time_creation = $this->timeCreation->getTimestamp();
}
if ($this->timeUpdate !== null) {
$apiResult->time_update = $this->timeUpdate->getTimestamp();
}
if ($this->state !== null) {
$apiResult->state = $this->state;
}
return $apiResult;
}
/**
* @return DateTimeInterface|null
*/
public function getTimeCreation(): ?DateTimeInterface
{
return $this->timeCreation;
}
/**
* @param DateTimeInterface|null $timeCreation
*/
public function setTimeCreation(?DateTimeInterface $timeCreation): void
{
$this->timeCreation = $timeCreation;
}
/**
* @return DateTimeInterface|null
*/
public function getTimeUpdate(): ?DateTimeInterface
{
return $this->timeUpdate;
}
/**
* @param DateTimeInterface|null $timeUpdate
*/
public function setTimeUpdate(?DateTimeInterface $timeUpdate): void
{
$this->timeUpdate = $timeUpdate;
}
/**
* @return string|null
*/
public function getState(): ?string
{
return $this->state;
}
/**
* @param string|null $state
*/
public function setState(?string $state): void
{
$this->state = $state;
}
/**
* @return ErrorMessage|null
*/
public function getError(): ?ErrorMessage
{
return $this->error === null ? null : ErrorMessage::fromDbState($this->error->toArray());
}
/**
* @param ErrorMessage|null $error
*/
public function setError(?ErrorMessage $error): void
{
$this->error = $error === null ? null : ErrorMessage::fromDbState($error->toArray());
}
}
@@ -0,0 +1,119 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
class CashPointClosingTransaction
{
/** @var TransactionHead $head */
private $head;
/** @var TransactionData $data */
private $data;
/** @var TransactionSecurity $security */
private $security;
/**
* CashPointClosingTransaction constructor.
*
* @param TransactionHead $head
* @param TransactionData $data
* @param TransactionSecurity $security
*/
public function __construct(TransactionHead $head, TransactionData $data, TransactionSecurity $security)
{
$this->setHead($head);
$this->setData($data);
$this->setSecurity($security);
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self(
TransactionHead::fromApiResult($apiResult->head),
TransactionData::fromApiResult($apiResult->data),
TransactionSecurity::fromApiResult($apiResult->security)
);
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new self(
TransactionHead::fromDbState($dbState['head']),
TransactionData::fromDbState($dbState['data']),
TransactionSecurity::fromDbState($dbState['security'])
);
}
/**
* @return array
*/
public function toArray(): array
{
return [
'head' => $this->getHead()->toArray(),
'data' => $this->getData()->toArray(),
'security' => $this->getSecurity()->toArray(),
];
}
/**
* @return TransactionHead
*/
public function getHead(): TransactionHead
{
return TransactionHead::fromDbState($this->head->toArray());
}
/**
* @param TransactionHead $head
*/
public function setHead(TransactionHead $head): void
{
$this->head = TransactionHead::fromDbState($head->toArray());
}
/**
* @return TransactionData
*/
public function getData(): TransactionData
{
return TransactionData::fromDbState($this->data->toArray());
}
/**
* @param TransactionData $data
*/
public function setData(TransactionData $data): void
{
$this->data = TransactionData::fromDbState($data->toArray());
}
/**
* @return TransactionSecurity
*/
public function getSecurity(): TransactionSecurity
{
return TransactionSecurity::fromDbState($this->security->toArray());
}
/**
* @param TransactionSecurity $security
*/
public function setSecurity(TransactionSecurity $security): void
{
$this->security = TransactionSecurity::fromDbState($security->toArray());
}
}
@@ -0,0 +1,158 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
class CashPointClosingTransactionAddress
{
/** @var string|null $street */
private $street;
/** @var string|null $postalCode */
private $postalCode;
/** @var string|null $city */
private $city;
/** @var string|null $countryCode */
private $countryCode;
/**
* CashPointClosingTransactionAddress constructor.
*
* @param string|null $street
* @param string|null $postalCode
* @param string|null $city
* @param string|null $countryCode
*/
public function __construct(
?string $street = null,
?string $postalCode = null,
?string $city = null,
?string $countryCode = null
) {
$this->street = $street;
$this->postalCode = $postalCode;
$this->city = $city;
$this->countryCode = $countryCode;
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self(
$apiResult->street ?? null,
$apiResult->postal_code ?? null,
$apiResult->city ?? null,
$apiResult->country_code ?? null
);
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new self(
$dbState['street'] ?? null,
$dbState['postal_code'] ?? null,
$dbState['city'] ?? null,
$dbState['country_code'] ?? null
);
}
/**
* @return null[]|string[]
*/
public function toArray(): array
{
$dbState = [];
if ($this->street !== null) {
$dbState['street'] = $this->getStreet();
}
if ($this->postalCode !== null) {
$dbState['postal_code'] = $this->getPostalCode();
}
if ($this->city !== null) {
$dbState['city'] = $this->getCity();
}
if ($this->countryCode !== null) {
$dbState['country_code'] = $this->getCountryCode();
}
return $dbState;
}
/**
* @return string|null
*/
public function getStreet(): ?string
{
return $this->street;
}
/**
* @param string|null $street
*/
public function setStreet(?string $street): void
{
$this->street = $street;
}
/**
* @return string|null
*/
public function getPostalCode(): ?string
{
return $this->postalCode;
}
/**
* @param string|null $postalCode
*/
public function setPostalCode(?string $postalCode): void
{
$this->postalCode = $postalCode;
}
/**
* @return string|null
*/
public function getCity(): ?string
{
return $this->city;
}
/**
* @param string|null $city
*/
public function setCity(?string $city): void
{
$this->city = $city;
}
/**
* @return string|null
*/
public function getCountryCode(): ?string
{
return $this->countryCode;
}
/**
* @param string|null $countryCode
*/
public function setCountryCode(?string $countryCode): void
{
$this->countryCode = $countryCode;
}
}
@@ -0,0 +1,214 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
use Xentral\Modules\FiskalyApi\Exception\InvalidArgumentException;
class CashPointClosingTransactionBuyer
{
/** @var string $name */
private $name;
/** @var string $buyerExportId */
private $buyerExportId;
/** @var $type */
private $type;
/** @var CashPointClosingTransactionAddress|null $address */
private $address;
/** @var string|null $vatIdNumber */
private $vatIdNumber;
/**
* CashPointClosingTransactionBuyer constructor.
*
* @param string $name
* @param string $buyerExportId
* @param string $type
* @param CashPointClosingTransactionAddress|null $address
* @param string|null $vatIdNumber
*/
public function __construct(
string $name,
string $buyerExportId,
string $type,
?CashPointClosingTransactionAddress $address = null,
?string $vatIdNumber = null
) {
$this->setName($name);
$this->setBuyerExportId($buyerExportId);
$this->setType($type);
$this->setAddress($address);
$this->setVatIdNumber($vatIdNumber);
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self(
$apiResult->name,
$apiResult->buyer_export_id,
$apiResult->type,
empty($apiResult->address) ? null : CashPointClosingTransactionAddress::fromApiResult($apiResult->address),
$apiResult->vat_id_number ?? null
);
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new self(
$dbState['name'],
$dbState['buyer_export_id'],
$dbState['type'],
empty($dbState['address']) ? null : CashPointClosingTransactionAddress::fromDbState($dbState['address']),
$dbState['vat_id_number'] ?? null
);
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [
'name' => $this->getName(),
'buyer_export_id' => $this->getBuyerExportId(),
'type' => $this->getType(),
];
if ($this->address !== null) {
$dbState['address'] = $this->address->toArray();
}
if ($this->vatIdNumber !== null) {
$dbState['vat_id_number'] = $this->getVatIdNumber();
}
return $dbState;
}
/**
* @return string
*/
public function getName(): string
{
return $this->name;
}
/**
* @param string $name
*/
public function setName(string $name): void
{
$this->name = mb_substr($name, 0, 50);
}
/**
* @return string
*/
public function getBuyerExportId(): string
{
return $this->buyerExportId;
}
/**
* @param string $buyerExportId
*/
public function setBuyerExportId(string $buyerExportId): void
{
$this->buyerExportId = mb_substr($buyerExportId, 0, 50);
}
/**
* @return string
*/
public function getType(): string
{
return $this->type;
}
/**
* @param string $type
*/
public function setType(string $type): void
{
$this->ensureType($type);
$this->type = $type;
}
/**
* @return CashPointClosingTransactionAddress|null
*/
public function getAddress(): ?CashPointClosingTransactionAddress
{
return $this->address === null ? null : CashPointClosingTransactionAddress::fromDbState(
$this->address->toArray()
);
}
/**
* @param CashPointClosingTransactionAddress|null $address
*/
public function setAddress(?CashPointClosingTransactionAddress $address): void
{
$this->address = $address === null ? null : CashPointClosingTransactionAddress::fromDbState(
$address->toArray()
);
}
/**
* @return string|null
*/
public function getVatIdNumber(): ?string
{
return $this->vatIdNumber;
}
/**
* @param string|null $vatIdNumber
*/
public function setVatIdNumber(?string $vatIdNumber): void
{
$vatIdNumber = $this->ensureVatIdNumber($vatIdNumber);
$this->vatIdNumber = $vatIdNumber;
}
/**
* @param string $type
*/
private function ensureType(string $type): void
{
if (!in_array($type, ['Kunde', 'Mitarbeiter'])) {
throw new InvalidArgumentException("'{$type}' is a invalid User Type");
}
}
/**
* @param string|null $vatIdNumber
*
* @return string|null
*/
private function ensureVatIdNumber(?string $vatIdNumber): ?string
{
if ($vatIdNumber === null) {
return null;
}
$vatIdNumber = trim($vatIdNumber);
if (!preg_match('/^[A-Z]{2}.{1,13}$/', $vatIdNumber)) {
throw new InvalidArgumentException("'{$vatIdNumber}' is an invalid VatIdNumber");
}
return $vatIdNumber;
}
}
@@ -0,0 +1,97 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
use IteratorAggregate;
use Countable;
use ArrayIterator;
class CashPointClosingTransactionCollection implements IteratorAggregate, Countable
{
/** @var CashPointClosingTransaction[] $transactions */
private $transactions = [];
/**
* CashPointClosingTransactionCollection constructor.
*
* @param array $transactions
*/
public function __construct(array $transactions = [])
{
foreach ($transactions as $transaction) {
$this->addTransaction($transaction);
}
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult($apiResult): self
{
$instance = new self();
foreach ($apiResult as $item) {
$instance->addTransaction(CashPointClosingTransaction::fromApiResult($item));
}
return $instance;
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
$instance = new self();
foreach ($dbState as $item) {
$instance->addTransaction(CashPointClosingTransaction::fromDbState($item));
}
return $instance;
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [];
/** @var CashPointClosingTransaction $item */
foreach ($this as $item) {
$dbState[] = $item->toArray();
}
return $dbState;
}
/**
* @param CashPointClosingTransaction $transaction
*/
public function addTransaction(CashPointClosingTransaction $transaction): self
{
$this->transactions[] = CashPointClosingTransaction::fromDbState($transaction->toArray());
return $this;
}
/**
* @return ArrayIterator
*/
public function getIterator(): ArrayIterator
{
return new ArrayIterator($this->transactions);
}
/**
* @return int
*/
public function count(): int
{
return count($this->transactions);
}
}
@@ -0,0 +1,268 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
class CashPointClosingTransactionLine
{
/** @var BusinessCase $businessCase */
private $businessCase;
/** @var string $lineitemExportId */
private $lineitemExportId;
/** @var bool $storno */
private $storno;
/** @var string $text */
private $text;
/** @var CashPointClosingTransactionLineItem $item */
private $item;
/** @var bool|null $inHouse */
private $inHouse;
/** @var CashPointClosingTransactionLineReferenceCollection $references */
private $references;
/** @var string|null $voucherId */
private $voucherId;
/**
* CashPointClosingTransactionLine constructor.
*
* @param BusinessCase $businessCase
* @param string $lineitemExportId
* @param bool $isStorno
* @param string $text
* @param CashPointClosingTransactionLineItem $item
* @param bool|null $inHouse
* @param CashPointClosingTransactionLineReferenceCollection|null $references
* @param string|null $voucherId
*/
public function __construct(
BusinessCase $businessCase,
string $lineitemExportId,
bool $isStorno,
string $text,
CashPointClosingTransactionLineItem $item,
?bool $inHouse = null,
?CashPointClosingTransactionLineReferenceCollection $references = null,
?string $voucherId = null
) {
$this->businessCase = BusinessCase::fromDbState($businessCase->toArray());
$this->lineitemExportId = $lineitemExportId;
$this->storno = $isStorno;
$this->text = $text;
$this->item = CashPointClosingTransactionLineItem::fromDbState($item->toArray());
$this->inHouse = $inHouse;
if ($references !== null) {
$this->references = CashPointClosingTransactionLineReferenceCollection::fromDbState(
$references->toArray()
);
}
$this->voucherId = $voucherId;
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self(
BusinessCase::fromApiResult($apiResult->business_case),
$apiResult->lineitem_export_id,
(bool)$apiResult->storno,
$apiResult->text,
CashPointClosingTransactionLineItem::fromApiResult($apiResult->item),
isset($apiResult->in_house) ? (bool)$apiResult->in_house : null,
!empty($apiResult->references) ? CashPointClosingTransactionLineReferenceCollection::fromApiResult(
$apiResult->references
) : null,
$apiResult->voucher_id ?? null
);
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new self(
BusinessCase::fromDbState($dbState['business_case']),
$dbState['lineitem_export_id'],
(bool)$dbState['storno'],
$dbState['text'],
CashPointClosingTransactionLineItem::fromDbState($dbState['item']),
isset($dbState['in_house']) ? (bool)$dbState['in_house'] : null,
!empty($dbState['references']) ? CashPointClosingTransactionLineReferenceCollection::fromDbState(
$dbState['references']
) : null,
$dbState['voucher_id'] ?? null
);
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [
'business_case' => $this->businessCase->toArray(),
'lineitem_export_id' => $this->getLineitemExportId(),
'storno' => $this->isStorno(),
'text' => $this->getText(),
'item' => $this->getItem()->toArray(),
];
if ($this->inHouse !== null) {
$dbState['in_house'] = $this->getInHouse();
}
if ($this->references !== null) {
$dbState['references'] = $this->getReferences();
}
if ($this->voucherId !== null) {
$dbState['voucher_id'] = $this->getVoucherId();
}
return $dbState;
}
/**
* @return BusinessCase
*/
public function getBusinessCase(): BusinessCase
{
return $this->businessCase;
}
/**
* @param BusinessCase $businessCase
*/
public function setBusinessCase(BusinessCase $businessCase): void
{
$this->businessCase = $businessCase;
}
/**
* @return string
*/
public function getLineitemExportId(): string
{
return $this->lineitemExportId;
}
/**
* @param string $lineitemExportId
*/
public function setLineitemExportId(string $lineitemExportId): void
{
$this->lineitemExportId = $lineitemExportId;
}
/**
* @return bool
*/
public function isStorno(): bool
{
return $this->storno;
}
/**
* @param bool $storno
*/
public function setStorno(bool $storno): void
{
$this->storno = $storno;
}
/**
* @return string
*/
public function getText(): string
{
return $this->text;
}
/**
* @param string $text
*/
public function setText(string $text): void
{
$this->text = $text;
}
/**
* @return CashPointClosingTransactionLineItem
*/
public function getItem(): CashPointClosingTransactionLineItem
{
return $this->item;
}
/**
* @param CashPointClosingTransactionLineItem $item
*/
public function setItem(CashPointClosingTransactionLineItem $item): void
{
$this->item = $item;
}
/**
* @return bool|null
*/
public function getInHouse(): ?bool
{
return $this->inHouse;
}
/**
* @param bool|null $inHouse
*/
public function setInHouse(?bool $inHouse): void
{
$this->inHouse = $inHouse;
}
/**
* @return CashPointClosingTransactionLineReferenceCollection|null
*/
public function getReferences(): ?CashPointClosingTransactionLineReferenceCollection
{
return $this->references === null ? null : CashPointClosingTransactionLineReferenceCollection::fromDbState(
$this->references->toArray()
);
}
/**
* @param CashPointClosingTransactionLineReferenceCollection|null $references
*/
public function setReferences(?CashPointClosingTransactionLineReferenceCollection $references): void
{
$this->references = $references === null ? null : CashPointClosingTransactionLineReferenceCollection::fromDbState(
$references->toArray()
);
}
/**
* @return string|null
*/
public function getVoucherId(): ?string
{
return $this->voucherId;
}
/**
* @param string|null $voucherId
*/
public function setVoucherId(?string $voucherId): void
{
$this->voucherId = $voucherId;
}
}
@@ -0,0 +1,96 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
use IteratorAggregate;
use Countable;
use ArrayIterator;
class CashPointClosingTransactionLineCollection implements IteratorAggregate, Countable
{
/** @var CashPointClosingTransactionLine[] $lines */
private $lines = [];
/**
* CashPointClosingTransactionLineCollection constructor.
*
* @param CashPointClosingTransactionLine[] $paymentTypes
*/
public function __construct(array $lines = [])
{
foreach ($lines as $line) {
$this->addLine($line);
}
}
/**
* @param CashPointClosingTransactionLine $line
*/
public function addLine(CashPointClosingTransactionLine $line): void
{
$this->lines[] = CashPointClosingTransactionLine::fromDbState($line->toArray());
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult($apiResult): self
{
$instance = new self();
foreach ($apiResult as $item) {
$instance->addLine(CashPointClosingTransactionLine::fromApiResult($item));
}
return $instance;
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
$instance = new self();
foreach ($dbState as $item) {
$instance->addLine(CashPointClosingTransactionLine::fromDbState($item));
}
return $instance;
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [];
/** @var CashPointClosingTransactionLine $item */
foreach ($this as $item) {
$dbState[] = $item->toArray();
}
return $dbState;
}
/**
* @return ArrayIterator
*/
public function getIterator(): ArrayIterator
{
return new ArrayIterator($this->lines);
}
/**
* @return int
*/
public function count(): int
{
return count($this->lines);
}
}
@@ -0,0 +1,406 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
class CashPointClosingTransactionLineItem
{
private $number;
private $quantity;
private $pricePerUnit;
private $gtin;
private $quantityFactor;
private $quantityMeasure;
private $groupId;
private $groupName;
private $baseAmountsPerVatId;
private $discountsPerVatId;
private $extraAmountsPerVatId;
/** @var SubLineItemCollection $subItems */
private $subItems;
/**
* CashPointClosingTransactionLineItem constructor.
*
* @param string $number
* @param float $quantity
* @param float $pricePerUnit
* @param string|null $gtin
* @param float|null $quantityFactor
* @param string|null $quantityMeasure
* @param string|null $groupId
* @param string|null $groupName
* @param AmountPerVatIdCollection|null $baseAmountsPerVatId
* @param AmountPerVatIdCollection|null $discountsPerVatId
* @param AmountPerVatIdCollection|null $extraAmountsPerVatId
* @param SubLineItemCollection|null $subItems
*/
public function __construct(
string $number,
float $quantity,
float $pricePerUnit,
?string $gtin = null,
?float $quantityFactor = null,
?string $quantityMeasure = null,
?string $groupId = null,
?string $groupName = null,
?AmountPerVatIdCollection $baseAmountsPerVatId = null,
?AmountPerVatIdCollection $discountsPerVatId = null,
?AmountPerVatIdCollection $extraAmountsPerVatId = null,
?SubLineItemCollection $subItems = null
) {
$this->setNumber($number);
$this->setQuantity($quantity);
$this->setPricePerUnit($pricePerUnit);
$this->setGtin($gtin);
$this->setQuantityFactor($quantityFactor);
$this->setQuantityMeasure($quantityMeasure);
$this->setGroupId($groupId);
$this->setGroupName($groupName);
if ($subItems !== null) {
$this->setSubItems(SubLineItemCollection::fromDbState($subItems->toArray()));
}
if ($baseAmountsPerVatId !== null) {
$this->setBaseAmountsPerVatId($baseAmountsPerVatId);
}
if ($discountsPerVatId !== null) {
$this->setDiscountsPerVatId($discountsPerVatId);
}
if ($extraAmountsPerVatId !== null) {
$this->setExtraAmountsPerVatId($extraAmountsPerVatId);
}
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
$instance = new self(
$apiResult->number,
(float)$apiResult->quantity,
(float)$apiResult->price_per_unit,
$apiResult->gtin ?? null,
$apiResult->quantity_factor ?? null,
$apiResult->quantity_measure ?? null,
$apiResult->quantity_factor ?? null,
$apiResult->group_id ?? null,
$apiResult->group_name ?? null
);
if (isset($apiResult->sub_items)) {
$instance->setSubItems(SubLineItemCollection::fromApiResult($apiResult->sub_items));
}
if (isset($apiResult->base_amounts_per_vat_id)) {
$instance->setBaseAmountsPerVatId(
AmountPerVatIdCollection::fromApiResult($apiResult->base_amounts_per_vat_id)
);
}
if (isset($apiResult->discounts_per_vat_id)) {
$instance->setDiscountsPerVatId(AmountPerVatIdCollection::fromApiResult($apiResult->discounts_per_vat_id));
}
if (isset($apiResult->extra_amounts_per_vat_id)) {
$instance->setExtraAmountsPerVatId(
AmountPerVatIdCollection::fromApiResult($apiResult->extra_amounts_per_vat_id)
);
}
return $instance;
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
$instance = new self(
$dbState['number'],
(float)$dbState['quantity'],
(float)$dbState['price_per_unit'],
$dbState['gtin'] ?? null,
isset($dbState['quantity_factor']) ? (float)$dbState['quantity_factor'] : null,
$dbState['quantity_measure'] ?? null,
isset($dbState['quantity_factor']) ? (float)$dbState['quantity_factor'] : null,
$dbState['group_id'] ?? null,
$dbState['group_name'] ?? null
);
if (!empty($dbState['sub_items'])) {
$instance->setSubItems(SubLineItemCollection::fromDbState($dbState['sub_items']));
}
if (isset($dbState['base_amounts_per_vat_id'])) {
$instance->setBaseAmountsPerVatId(
AmountPerVatIdCollection::fromDbState($dbState['base_amounts_per_vat_id'])
);
}
if (isset($dbState['discounts_per_vat_id'])) {
$instance->setDiscountsPerVatId(AmountPerVatIdCollection::fromDbState($dbState['discounts_per_vat_id']));
}
if (isset($dbState['extra_amounts_per_vat_id'])) {
$instance->setExtraAmountsPerVatId(
AmountPerVatIdCollection::fromDbState($dbState['extra_amounts_per_vat_id'])
);
}
return $instance;
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [
'number' => $this->getNumber(),
'quantity' => $this->getQuantity(),
'price_per_unit' => $this->getPricePerUnit(),
];
if ($this->gtin !== null) {
$dbState['gtin'] = $this->getGtin();
}
if ($this->quantityFactor !== null) {
$dbState['quantity_factor'] = $this->getQuantityFactor();
}
if ($this->quantityMeasure !== null) {
$dbState['quantity_measure'] = $this->getQuantityMeasure();
}
if ($this->groupId !== null) {
$dbState['group_id'] = $this->getGroupId();
}
if ($this->groupName !== null) {
$dbState['group_name'] = $this->getGroupName();
}
if ($this->subItems !== null) {
$dbState['sub_items'] = $this->subItems->toArray();
}
if ($this->baseAmountsPerVatId !== null) {
$dbState['base_amounts_per_vat_id'] = $this->baseAmountsPerVatId->toArray();
}
if ($this->discountsPerVatId !== null) {
$dbState['discounts_per_vat_id'] = $this->discountsPerVatId->toArray();
}
if ($this->extraAmountsPerVatId !== null) {
$dbState['extra_amounts_per_vat_id'] = $this->extraAmountsPerVatId->toArray();
}
return $dbState;
}
/**
* @return string
*/
public function getNumber(): string
{
return $this->number;
}
/**
* @param string $number
*/
public function setNumber(string $number): void
{
$this->number = mb_substr($number, 0, 50);
}
/**
* @return float
*/
public function getQuantity(): float
{
return $this->quantity;
}
/**
* @param float $quantity
*/
public function setQuantity(float $quantity): void
{
$this->quantity = (float)number_format($quantity, 3, '.', '');
}
/**
* @return float
*/
public function getPricePerUnit(): float
{
return $this->pricePerUnit;
}
/**
* @param float $pricePerUnit
*/
public function setPricePerUnit(float $pricePerUnit): void
{
$this->pricePerUnit = (float)number_format($pricePerUnit, 5, '.', '');
}
/**
* @return string|null
*/
public function getGtin(): ?string
{
return $this->gtin;
}
/**
* @param string|null $gtin
*/
public function setGtin(?string $gtin): void
{
$this->gtin = $gtin;
}
/**
* @return float|null
*/
public function getQuantityFactor(): ?float
{
return $this->quantityFactor;
}
/**
* @param float|null $quantityFactor
*/
public function setQuantityFactor(?float $quantityFactor): void
{
$this->quantityFactor = $quantityFactor === null ? null : (float)number_format($quantityFactor, 3, '.', '');
}
/**
* @return string|null
*/
public function getQuantityMeasure(): ?string
{
return $this->quantityMeasure;
}
/**
* @param string|null $quantityMeasure
*/
public function setQuantityMeasure(?string $quantityMeasure): void
{
$this->quantityMeasure = $quantityMeasure === null ? null : mb_substr($quantityMeasure,0, 50);
}
/**
* @return string|null
*/
public function getGroupId(): ?string
{
return $this->groupId;
}
/**
* @param string|null $groupId
*/
public function setGroupId(?string $groupId): void
{
$this->groupId = $groupId === null ? null : mb_substr($groupId, 0, 40);
}
/**
* @return string|null
*/
public function getGroupName(): ?string
{
return $this->groupName;
}
/**
* @param string|null $groupName
*/
public function setGroupName(?string $groupName): void
{
$this->groupName = $groupName === null ? null : mb_substr($groupName, 0, 50);
}
/**
* @return AmountPerVatIdCollection|null
*/
public function getBaseAmountsPerVatId(): ?AmountPerVatIdCollection
{
return $this->baseAmountsPerVatId === null ? null : AmountPerVatIdCollection::fromDbState(
$this->baseAmountsPerVatId->toArray()
);
}
/**
* @param AmountPerVatIdCollection|null $baseAmountsPerVatId
*/
public function setBaseAmountsPerVatId(?AmountPerVatIdCollection $baseAmountsPerVatId): void
{
$this->baseAmountsPerVatId = $baseAmountsPerVatId === null ? null : AmountPerVatIdCollection::fromDbState(
$baseAmountsPerVatId->toArray()
);
}
/**
* @return AmountPerVatIdCollection|null
*/
public function getDiscountsPerVatId(): ?AmountPerVatIdCollection
{
return $this->discountsPerVatId === null ? null : AmountPerVatIdCollection::fromDbState(
$this->discountsPerVatId->toArray()
);
}
/**
* @param AmountPerVatIdCollection|null $discountsPerVatId
*/
public function setDiscountsPerVatId(?AmountPerVatIdCollection $discountsPerVatId): void
{
$this->discountsPerVatId = $discountsPerVatId === null ? null : AmountPerVatIdCollection::fromDbState(
$discountsPerVatId->toArray()
);
}
/**
* @return AmountPerVatIdCollection|null
*/
public function getExtraAmountsPerVatId(): ?AmountPerVatIdCollection
{
return $this->extraAmountsPerVatId === null ? null : AmountPerVatIdCollection::fromDbState(
$this->extraAmountsPerVatId->toArray()
);
}
/**
* @param AmountPerVatIdCollection|null $extraAmountsPerVatId
*/
public function setExtraAmountsPerVatId(?AmountPerVatIdCollection $extraAmountsPerVatId): void
{
$this->extraAmountsPerVatId = $extraAmountsPerVatId === null ? null : AmountPerVatIdCollection::fromDbState(
$extraAmountsPerVatId->toArray()
);
}
/**
* @return ?SubLineItemCollection
*/
public function getSubItems(): ?SubLineItemCollection
{
return $this->subItems === null ? null : SubLineItemCollection::fromDbState($this->subItems->toArray());
}
/**
* @param SubLineItemCollection|null $subItems
*/
public function setSubItems(?SubLineItemCollection $subItems): void
{
$this->subItems = $subItems === null ? null : SubLineItemCollection::fromDbState($subItems->toArray());
}
}
@@ -0,0 +1,57 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
class CashPointClosingTransactionLineReference
{
/** @var string $type */
protected $type;
public function __construct(string $type)
{
$this->type = $type;
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult)
{
return new self($apiResult->type);
}
/**
* @param array $dbState
*
* @return CashPointClosingTransactionLineReference
*/
public static function fromDbState(array $dbState)
{
return new self($dbState['type']);
}
public function toArray(): array
{
return ['type' => $this->type];
}
/**
* @return string
*/
public function getType(): string
{
return $this->type;
}
/**
* @param string $type
*/
public function setType(string $type): void
{
$this->type = $type;
}
}
@@ -0,0 +1,133 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
use ArrayIterator;
use Countable;
use IteratorAggregate;
use Xentral\Modules\FiskalyApi\Exception\InvalidArgumentException;
class CashPointClosingTransactionLineReferenceCollection implements IteratorAggregate, Countable
{
public const TYPE_TRANSACTION = 'Transaktion';
public const TYPE_EXTERNAL_INVOICE = 'ExterneRechnung';
public const TYPE_EXTERNAL_DELIVERY_NOTE = 'ExternerLieferschein';
public const TYPE_EXTERNAL_OTHER = 'ExterneSonstige';
public const TYPE_INTERNAL_TRANSACTION = 'InterneTransaktion';
/** @var CashPointClosingTransactionLineReference[] $references */
private $references = [];
/**
* CashPointClosingTransactionLineReferenceCollection constructor.
*
* @param array $references
*/
public function __construct(array $references = [])
{
foreach ($references as $reference) {
$this->addReference($reference);
}
}
/**
* @param CashPointClosingTransactionLineReference $reference
*/
public function addReference(CashPointClosingTransactionLineReference $reference): void
{
$this->references[] = $reference::fromDbState($reference->toArray());
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
$instance = new self();
foreach ($apiResult as $item) {
switch ($item->type) {
case self::TYPE_TRANSACTION:
$instance->addReference(CashPointClosingTransaktionReference::fromApiResult($item));
break;
case self::TYPE_EXTERNAL_INVOICE:
case self::TYPE_EXTERNAL_DELIVERY_NOTE:
$instance->addReference(CashPointClosingExternalDocumentReference::fromApiResult($item));
break;
case self::TYPE_EXTERNAL_OTHER:
$instance->addReference(CashPointClosingOtherReference::fromApiResult($item));
break;
case self::TYPE_INTERNAL_TRANSACTION:
$instance->addReference(CashPointClosingInternalTransaktionReference::fromApiResult($item));
break;
default:
throw new InvalidArgumentException("unknown Reference {$item->type}");
}
}
return $instance;
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
$instance = new self();
foreach ($dbState as $item) {
switch ($item['type']) {
case self::TYPE_TRANSACTION:
$instance->addReference(CashPointClosingTransaktionReference::fromDbState($item));
break;
case self::TYPE_EXTERNAL_INVOICE:
case self::TYPE_EXTERNAL_DELIVERY_NOTE:
$instance->addReference(CashPointClosingExternalDocumentReference::fromDbState($item));
break;
case self::TYPE_EXTERNAL_OTHER:
$instance->addReference(CashPointClosingOtherReference::fromDbState($item));
break;
case self::TYPE_INTERNAL_TRANSACTION:
$instance->addReference(CashPointClosingInternalTransaktionReference::fromDbState($item));
break;
default:
throw new InvalidArgumentException("unknown Reference {$item['type']}");
}
}
return $instance;
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [];
foreach ($this as $item) {
$dbState[] = $item->toArray();
}
return $dbState;
}
/**
* @return ArrayIterator
*/
public function getIterator(): ArrayIterator
{
return new ArrayIterator($this->references);
}
/**
* @return int
*/
public function count(): int
{
return count($this->references);
}
}
@@ -0,0 +1,310 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
class CashPointClosingTransactionSubLineItem
{
/** @var string $number */
private $number;
/** @var float $quantity */
private $quantity;
/** @var AmountPerVatIdCollection $amountsPerVatId */
private $amountsPerVatId;
/** @var string|null $gtin */
private $gtin;
/** @var string|null $name */
private $name;
/** @var float|null $quantityFactor */
private $quantityFactor;
/** @var string|null $quantityMeasure */
private $quantityMeasure;
/** @var string|null $groupId */
private $groupId;
/** @var string|null $groupName */
private $groupName;
/**
* CashPointClosingTransactionSubLineItem constructor.
*
* @param string $number
* @param float $quantity
* @param array $amountsPerVatId
* @param string|null $gtin
* @param string|null $name
* @param float|null $quantityFactor
* @param string|null $quantityMeasure
* @param string|null $groupId
* @param string|null $groupName
*/
public function __construct(
string $number,
float $quantity,
AmountPerVatIdCollection $amountsPerVatId,
?string $gtin = null,
?string $name = null,
?float $quantityFactor = null,
?string $quantityMeasure = null,
?string $groupId = null,
?string $groupName = null
) {
$this->number = $number;
$this->quantity = $quantity;
$this->amountsPerVatId = AmountPerVatIdCollection::fromDbState($amountsPerVatId->toArray());
$this->gtin = $gtin;
$this->name = $name;
$this->quantityFactor = $quantityFactor;
$this->quantityMeasure = $quantityMeasure;
$this->groupId = $groupId;
$this->groupName = $groupName;
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
$instance = new self(
$apiResult->number,
(float)$apiResult->quantity,
AmountPerVatIdCollection::fromApiResult($apiResult->amounts_per_vat_id),
$apiResult->gtin ?? null,
$apiResult->name ?? null,
$apiResult->quantity_factor ?? null,
$apiResult->quantity_measure ?? null,
$apiResult->group_id ?? null,
$apiResult->groupName ?? null
);
return $instance;
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
$instance = new self(
$dbState['number'],
(float)$dbState['quantity'],
AmountPerVatIdCollection::fromDbState($dbState['amounts_per_vat_id'])
);
if (isset($dbState['gtin'])) {
$instance->setGtin($dbState['gtin']);
}
if (isset($dbState['name'])) {
$instance->setName($dbState['name']);
}
if (isset($dbState['quantity_factor'])) {
$instance->setQuantityFactor($dbState['quantity_factor']);
}
if (isset($dbState['quantity_meassure'])) {
$instance->setQuantityMeasure($dbState['quantity_meassure']);
}
if (isset($dbState['group_id'])) {
$instance->setGroupId($dbState['group_id']);
}
if (isset($dbState['group_name'])) {
$instance->setGroupName($dbState['group_name']);
}
return new $instance;
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [
'number' => $this->getNumber(),
'quantity' => $this->getQuantity(),
'amount_per_vat_id' => $this->amountsPerVatId->toArray(),
];
if ($this->gtin !== null) {
$dbState['gtin'] = $this->getGtin();
}
if ($this->name !== null) {
$dbState['name'] = $this->getName();
}
if ($this->quantityFactor !== null) {
$dbState['quantity_factor'] = $this->getQuantityFactor();
}
if ($this->quantityMeasure !== null) {
$dbState['quantity_meassure'] = $this->getQuantityMeasure();
}
if ($this->groupId !== null) {
$dbState['group_id'] = $this->getGroupId();
}
if ($this->groupName !== null) {
$dbState['group_name'] = $this->getGroupName();
}
return $dbState;
}
/**
* @param AmountPerVatIdCollection $amountPerVatId
*/
public function addAmountPerVatId(AmountPerVatIdCollection $amountsPerVatId): void
{
$this->amountsPerVatId = AmountPerVatIdCollection::fromDbState($amountsPerVatId->toArray());
}
/**
* @return string
*/
public function getNumber(): string
{
return $this->number;
}
/**
* @param string $number
*/
public function setNumber(string $number): void
{
$this->number = $number;
}
/**
* @return float
*/
public function getQuantity(): float
{
return $this->quantity;
}
/**
* @param float $quantity
*/
public function setQuantity(float $quantity): void
{
$this->quantity = $quantity;
}
/**
* @return AmountPerVatIdCollection
*/
public function getAmountsPerVatId(): AmountPerVatIdCollection
{
return AmountPerVatIdCollection::fromDbState($this->amountsPerVatId->toArray());
}
/**
* @param AmountPerVatIdCollection $amountsPerVatId
*/
public function setAmountsPerVatId(AmountPerVatIdCollection $amountsPerVatId): void
{
$this->amountsPerVatId = AmountPerVatIdCollection::fromDbState($amountsPerVatId->toArray());
}
/**
* @return string|null
*/
public function getGtin(): ?string
{
return $this->gtin;
}
/**
* @param string|null $gtin
*/
public function setGtin(?string $gtin): void
{
$this->gtin = $gtin;
}
/**
* @return string|null
*/
public function getName(): ?string
{
return $this->name;
}
/**
* @param string|null $name
*/
public function setName(?string $name): void
{
$this->name = $name;
}
/**
* @return float|null
*/
public function getQuantityFactor(): ?float
{
return $this->quantityFactor;
}
/**
* @param float|null $quantityFactor
*/
public function setQuantityFactor(?float $quantityFactor): void
{
$this->quantityFactor = $quantityFactor;
}
/**
* @return string|null
*/
public function getQuantityMeasure(): ?string
{
return $this->quantityMeasure;
}
/**
* @param string|null $quantityMeasure
*/
public function setQuantityMeasure(?string $quantityMeasure): void
{
$this->quantityMeasure = $quantityMeasure;
}
/**
* @return string|null
*/
public function getGroupId(): ?string
{
return $this->groupId;
}
/**
* @param string|null $groupId
*/
public function setGroupId(?string $groupId): void
{
$this->groupId = $groupId;
}
/**
* @return string|null
*/
public function getGroupName(): ?string
{
return $this->groupName;
}
/**
* @param string|null $groupName
*/
public function setGroupName(?string $groupName): void
{
$this->groupName = $groupName;
}
}
@@ -0,0 +1,91 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
class CashPointClosingTransactionUser
{
/** @var string $userExportId */
private $userExportId;
/** @var string|null $name */
private $name;
/**
* CashPointClosingTransactionUser constructor.
*
* @param string $userExportId
* @param string|null $name
*/
public function __construct(string $userExportId, ?string $name = null)
{
$this->userExportId = $userExportId;
$this->name = $name;
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self($apiResult->user_export_id, $apiResult->name ?? null);
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new self($dbState['user_export_id'], $dbState['name'] ?? null);
}
/**
* @return null[]|string[]
*/
public function toArray(): array
{
$dbState = ['user_export_id' => $this->getUserExportId()];
if ($this->name !== null) {
$dbState['name'] = $this->getName();
}
return $dbState;
}
/**
* @return string
*/
public function getUserExportId(): string
{
return $this->userExportId;
}
/**
* @param string $userExportId
*/
public function setUserExportId(string $userExportId): void
{
$this->userExportId = $userExportId;
}
/**
* @return string|null
*/
public function getName(): ?string
{
return $this->name;
}
/**
* @param string|null $name
*/
public function setName(?string $name): void
{
$this->name = $name;
}
}
@@ -0,0 +1,150 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
use DateTime;
use DateTimeInterface;
class CashPointClosingTransaktionReference extends CashPointClosingTransactionLineReference
{
/** @var int $cashPointClosingExportId */
private $cashPointClosingExportId;
/** @var string $cashRegisterExportId */
private $cashRegisterExportId;
/** @var string $transactionExportId */
private $transactionExportId;
/** @var DateTimeInterface $date */
private $date;
public function __construct(
string $type, int $cashPointClosingExportId, string $cashRegisterExportId,
string $transactionExportId, ?DateTimeInterface $date = null)
{
parent::__construct($type);
$this->cashPointClosingExportId = $cashPointClosingExportId;
$this->cashRegisterExportId = $cashRegisterExportId;
$this->transactionExportId = $transactionExportId;
$this->date = $date;
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): CashPointClosingTransaktionReference
{
return new self(
$apiResult->type,
(int)$apiResult->cash_point_closing_export_id,
$apiResult->cash_register_export_id,
$apiResult->transaction_export_id,
$apiResult->date === null ? null : (new DateTime())->setTimestamp($apiResult->date)
);
}
/**
* @param array $dbState
*
* @return CashPointClosingTransaktionReference
*/
public static function fromDbState(array $dbState): CashPointClosingTransaktionReference
{
return new self(
$dbState['type'],
(int)$dbState['cash_point_closing_export_id'],
$dbState['cash_register_export_id'],
$dbState['transaction_export_id'],
empty($dbState['date']) ? null : (new DateTime())->setTimestamp($dbState['date'])
);
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [
'type' => $this->type,
'cash_point_closing_export_id' => $this->cashPointClosingExportId,
'cash_register_export_id' => $this->cashRegisterExportId,
'transaction_export_id' => $this->transactionExportId,
];
if($this->date !== null) {
$dbState['date'] = $this->date->getTimestamp();
}
return $dbState;
}
/**
* @return int
*/
public function getCashPointClosingExportId(): int
{
return $this->cashPointClosingExportId;
}
/**
* @param int $cashPointClosingExportId
*/
public function setCashPointClosingExportId(int $cashPointClosingExportId): void
{
$this->cashPointClosingExportId = $cashPointClosingExportId;
}
/**
* @return string
*/
public function getCashRegisterExportId(): string
{
return $this->cashRegisterExportId;
}
/**
* @param string $cashRegisterExportId
*/
public function setCashRegisterExportId(string $cashRegisterExportId): void
{
$this->cashRegisterExportId = $cashRegisterExportId;
}
/**
* @return string
*/
public function getTransactionExportId(): string
{
return $this->transactionExportId;
}
/**
* @param string $transactionExportId
*/
public function setTransactionExportId(string $transactionExportId): void
{
$this->transactionExportId = $transactionExportId;
}
/**
* @return DateTimeInterface
*/
public function getDate(): DateTimeInterface
{
return $this->date;
}
/**
* @param DateTimeInterface $date
*/
public function setDate(DateTimeInterface $date): void
{
$this->date = $date;
}
}
@@ -0,0 +1,89 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
use ArrayIterator;
use Countable;
use IteratorAggregate;
class SubLineItemCollection implements IteratorAggregate, Countable
{
/** @var CashPointClosingTransactionSubLineItem[] $subLineItems */
private $subLineItems = [];
/**
* SubLineItemCollection constructor.
*
* @param array $subLineItems
*/
public function __construct(array $subLineItems = [])
{
foreach($subLineItems as $subLineItem) {
$this->addSubLineItem($subLineItem);
}
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
$instance = new self();
foreach ($apiResult as $item) {
$instance->addSubLineItem(CashPointClosingTransactionSubLineItem::fromApiResult($item));
}
return $instance;
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
$instance = new self();
foreach ($dbState as $item) {
$instance->addSubLineItem(CashPointClosingTransactionSubLineItem::fromDbState($item));
}
return $instance;
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [];
/** @var CashPointClosingTransactionSubLineItem $amountPerVat */
foreach($this as $item) {
$dbState[] = $item->toArray();
}
return $dbState;
}
/**
* @param CashPointClosingTransactionSubLineItem $subLineItem
*/
public function addSubLineItem(CashPointClosingTransactionSubLineItem $subLineItem): void
{
$this->subLineItems[] = CashPointClosingTransactionSubLineItem::fromDbState($subLineItem->toArray());
}
public function getIterator(): ArrayIterator
{
return new ArrayIterator($this->subLineItems);
}
public function count(): int
{
return count($this->subLineItems);
}
}
@@ -0,0 +1,175 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
class TransactionData
{
/** @var float $fullAmountInclVat */
private $fullAmountInclVat;
/** @var CashPointClosingPaymentTypeCollection $paymentTypes */
private $paymentTypes;
/** @var AmountPerVatIdCollection $amountsPerVatId */
private $amountsPerVatId;
/** @var CashPointClosingTransactionLineCollection $lines */
private $lines;
/** @var string $notes */
private $notes;
/**
* TransactionData constructor.
*
* @param float $fullAmountInclVat
* @param AmountPerVatIdCollection $amountsPerVatId
* @param CashPointClosingTransactionLineCollection $lines
* @param string|null $notes
*/
public function __construct(
float $fullAmountInclVat,
CashPointClosingPaymentTypeCollection $paymentTypes,
AmountPerVatIdCollection $amountsPerVatId,
CashPointClosingTransactionLineCollection $lines,
?string $notes = null
) {
$this->setFullAmountInclVat($fullAmountInclVat);
$this->setPaymentTypes($paymentTypes);
$this->setAmountsPerVatId($amountsPerVatId);
$this->setLines($lines);
$this->setNotes($notes);
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self(
(float)$apiResult->full_amount_incl_vat,
CashPointClosingPaymentTypeCollection::fromApiResult($apiResult->payment_types),
AmountPerVatIdCollection::fromApiResult($apiResult->amounts_per_vat_id),
CashPointClosingTransactionLineCollection::fromApiResult($apiResult->lines),
$apiResult->notes ?? null
);
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new self(
(float)$dbState['full_amount_incl_vat'],
CashPointClosingPaymentTypeCollection::fromDbState($dbState['payment_types']),
AmountPerVatIdCollection::fromDbState($dbState['amounts_per_vat_id']),
CashPointClosingTransactionLineCollection::fromDbState($dbState['lines']),
$dbState['notes'] ?? null
);
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [
'full_amount_incl_vat' => $this->getFullAmountInclVat(),
'payment_types' => $this->getPaymentTypes()->toArray(),
'amounts_per_vat_id' => $this->getAmountsPerVatId()->toArray(),
'lines' => $this->getLines()->toArray(),
];
if ($this->notes !== null) {
$dbState['notes'] = $this->getNotes();
}
return $dbState;
}
/**
* @return float
*/
public function getFullAmountInclVat(): float
{
return $this->fullAmountInclVat;
}
/**
* @param float $fullAmountInclVat
*/
public function setFullAmountInclVat(float $fullAmountInclVat): void
{
$this->fullAmountInclVat = $fullAmountInclVat;
}
/**
* @return CashPointClosingPaymentTypeCollection
*/
public function getPaymentTypes(): CashPointClosingPaymentTypeCollection
{
return CashPointClosingPaymentTypeCollection::fromDbState($this->paymentTypes->toArray());
}
/**
* @param CashPointClosingPaymentTypeCollection $paymentTypes
*/
public function setPaymentTypes(CashPointClosingPaymentTypeCollection $paymentTypes): void
{
$this->paymentTypes = CashPointClosingPaymentTypeCollection::fromDbState($paymentTypes->toArray());
}
/**
* @return AmountPerVatIdCollection
*/
public function getAmountsPerVatId(): AmountPerVatIdCollection
{
return AmountPerVatIdCollection::fromDbState($this->amountsPerVatId->toArray());
}
/**
* @param AmountPerVatIdCollection $amountsPerVatId
*/
public function setAmountsPerVatId(AmountPerVatIdCollection $amountsPerVatId): void
{
$this->amountsPerVatId = AmountPerVatIdCollection::fromDbState($amountsPerVatId->toArray());
}
/**
* @return CashPointClosingTransactionLineCollection
*/
public function getLines(): CashPointClosingTransactionLineCollection
{
return CashPointClosingTransactionLineCollection::fromDbState($this->lines->toArray());
}
/**
* @param CashPointClosingTransactionLineCollection $lines
*/
public function setLines(CashPointClosingTransactionLineCollection $lines): void
{
$this->lines = CashPointClosingTransactionLineCollection::fromDbState($lines->toArray());
}
/**
* @return string|null
*/
public function getNotes(): ?string
{
return $this->notes;
}
/**
* @param string|null $notes
*/
public function setNotes(?string $notes): void
{
$this->notes = $notes;
}
}
@@ -0,0 +1,388 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
use DateTime;
use DateTimeInterface;
use Xentral\Modules\FiskalyApi\Exception\InvalidArgumentException;
class TransactionHead
{
/** @var string $txId */
private $txId;
/** @var string $transactionExportId */
private $transactionExportId;
/** @var string $closingClientId */
private $closingClientId;
/** @var string $type */
private $type;
/** @var bool $storno */
private $storno;
/** @var int $number */
private $number;
/** @var DateTimeInterface $timestampStart */
private $timestampStart;
/** @var DateTimeInterface $timestampEnd */
private $timestampEnd;
/** @var CashPointClosingTransactionUser $user */
private $user;
/** @var CashPointClosingTransactionBuyer $buyer */
private $buyer;
/** @var CashPointClosingTransactionLineReferenceCollection $references */
private $references;
/** @var array|null $allocationGroups */
private $allocationGroups;
/**
* TransactionHead constructor.
*
* @param string $txId
* @param string $transactionExportId
* @param string $closingClientId
* @param string $type
* @param bool $storno
* @param int $number
* @param DateTimeInterface $timestampStart
* @param DateTimeInterface $timestampEnd
* @param CashPointClosingTransactionUser $user
* @param CashPointClosingTransactionBuyer $buyer
* @param CashPointClosingTransactionLineReferenceCollection|null $references
* @param array|null $allocationGroups
*/
public function __construct(
string $txId,
string $transactionExportId,
string $closingClientId,
string $type,
bool $storno,
int $number,
DateTimeInterface $timestampStart,
DateTimeInterface $timestampEnd,
CashPointClosingTransactionUser $user,
CashPointClosingTransactionBuyer $buyer,
?CashPointClosingTransactionLineReferenceCollection $references = null,
?array $allocationGroups = null
) {
$this->setTxId($txId);
$this->setTransactionExportId($transactionExportId);
$this->setClosingClientId($closingClientId);
$this->setType($type);
$this->setStorno($storno);
$this->setNumber($number);
$this->setTimestampStart($timestampStart);
$this->setTimestampEnd($timestampEnd);
$this->setUser($user);
$this->setBuyer($buyer);
$this->setReferences($references);
$this->setAllocationGroups($allocationGroups);
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self(
$apiResult->tx_id,
$apiResult->transaction_export_id,
$apiResult->closing_client_id,
$apiResult->type,
(bool)$apiResult->storno,
(int)$apiResult->number,
(new DateTime())->setTimestamp($apiResult->timestamp_start),
(new DateTime())->setTimestamp($apiResult->timestamp_end),
CashPointClosingTransactionUser::fromApiResult($apiResult->user),
CashPointClosingTransactionBuyer::fromApiResult($apiResult->buyer),
!empty($apiResult->references) ? CashPointClosingTransactionLineReferenceCollection::fromApiResult(
$apiResult->references
) : null,
$apiResult->allocation_groups ?? null
);
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new self(
$dbState['tx_id'],
$dbState['transaction_export_id'],
$dbState['closing_client_id'],
$dbState['type'],
(bool)$dbState['storno'],
(int)$dbState['number'],
(new DateTime())->setTimestamp($dbState['timestamp_start']),
(new DateTime())->setTimestamp($dbState['timestamp_end']),
CashPointClosingTransactionUser::fromDbState($dbState['user']),
CashPointClosingTransactionBuyer::fromDbState($dbState['buyer']),
!empty($dbState['references']) ? CashPointClosingTransactionLineReferenceCollection::fromDbState(
$dbState['references']
) : null,
$dbState['allocation_groups'] ?? null
);
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [
'tx_id' => $this->getTxId(),
'transaction_export_id' => $this->getTransactionExportId(),
'closing_client_id' => $this->getClosingClientId(),
'type' => $this->getType(),
'storno' => $this->isStorno(),
'number' => $this->getNumber(),
'timestamp_start' => $this->getTimestampStart()->getTimestamp(),
'timestamp_end' => $this->getTimestampEnd()->getTimestamp(),
'user' => $this->getUser()->toArray(),
'buyer' => $this->getBuyer()->toArray(),
];
if ($this->references !== null) {
$dbState['references'] = $this->getReferences()->toArray();
}
if ($this->allocationGroups !== null) {
$dbState['allocation_groups'] = $this->getAllocationGroups();
}
return $dbState;
}
/**
* @return string
*/
public function getTxId(): string
{
return $this->txId;
}
/**
* @param string $txId
*/
public function setTxId(string $txId): void
{
$this->txId = $txId;
}
/**
* @return string
*/
public function getTransactionExportId(): string
{
return $this->transactionExportId;
}
/**
* @param string $transactionExportId
*/
public function setTransactionExportId(string $transactionExportId): void
{
$this->transactionExportId = $transactionExportId;
}
/**
* @return string
*/
public function getClosingClientId(): string
{
return $this->closingClientId;
}
/**
* @param string $closingClientId
*/
public function setClosingClientId(string $closingClientId): void
{
$this->closingClientId = $closingClientId;
}
/**
* @return string
*/
public function getType(): string
{
return $this->type;
}
/**
* @param string $type
*/
public function setType(string $type): void
{
$this->ensureType($type);
$this->type = $type;
}
/**
* @return bool
*/
public function isStorno(): bool
{
return $this->storno;
}
/**
* @param bool $storno
*/
public function setStorno(bool $storno): void
{
$this->storno = $storno;
}
/**
* @return int
*/
public function getNumber(): int
{
return $this->number;
}
/**
* @param int $number
*/
public function setNumber(int $number): void
{
$this->number = $number;
}
/**
* @return DateTimeInterface
*/
public function getTimestampStart(): DateTimeInterface
{
return $this->timestampStart;
}
/**
* @param DateTimeInterface $timestampStart
*/
public function setTimestampStart(DateTimeInterface $timestampStart): void
{
$this->timestampStart = $timestampStart;
}
/**
* @return DateTimeInterface
*/
public function getTimestampEnd(): DateTimeInterface
{
return $this->timestampEnd;
}
/**
* @param DateTimeInterface $timestampEnd
*/
public function setTimestampEnd(DateTimeInterface $timestampEnd): void
{
$this->timestampEnd = $timestampEnd;
}
/**
* @return CashPointClosingTransactionUser
*/
public function getUser(): CashPointClosingTransactionUser
{
return $this->user;
}
/**
* @param CashPointClosingTransactionUser $user
*/
public function setUser(CashPointClosingTransactionUser $user): void
{
$this->user = $user;
}
/**
* @return CashPointClosingTransactionBuyer
*/
public function getBuyer(): CashPointClosingTransactionBuyer
{
return $this->buyer;
}
/**
* @param CashPointClosingTransactionBuyer $buyer
*/
public function setBuyer(CashPointClosingTransactionBuyer $buyer): void
{
$this->buyer = $buyer;
}
/**
* @return CashPointClosingTransactionLineReferenceCollection|null
*/
public function getReferences(): ?CashPointClosingTransactionLineReferenceCollection
{
return $this->references === null ? null : CashPointClosingTransactionLineReferenceCollection::fromDbState(
$this->references->toArray()
);
}
/**
* @param CashPointClosingTransactionLineReferenceCollection|null $references
*/
public function setReferences(?CashPointClosingTransactionLineReferenceCollection $references): void
{
$this->references = $references === null ? null : CashPointClosingTransactionLineReferenceCollection::fromDbState(
$references->toArray()
);
}
/**
* @return array|null
*/
public function getAllocationGroups(): ?array
{
return $this->allocationGroups;
}
/**
* @param array|null $allocationGroups
*/
public function setAllocationGroups(?array $allocationGroups): void
{
$this->allocationGroups = $allocationGroups;
}
/**
* @param string $type
*/
private function ensureType(string $type): void
{
$validTypes = [
'Beleg',
'AVTransfer',
'AVBestellung',
'AVTraining',
'AVBelegstorno',
'AVBelegabbruch',
'AVSachbezug',
'AVSonstige',
'AVRechnung',
];
if (!in_array($type, $validTypes)) {
throw new InvalidArgumentException("{$type} is an invalid Type");
}
}
}
@@ -0,0 +1,89 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\CashPointClosing;
use Xentral\Modules\FiskalyApi\Exception\InvalidArgumentException;
class TransactionSecurity
{
/** @var string|null $tssTxId */
private $tssTxId;
/** @var string|null $errorMessage */
private $errorMessage;
public function __construct(?string $tssTxId, ?string $errorMessage = null)
{
if($tssTxId === null && $errorMessage) {
throw new InvalidArgumentException('tssTxId or error_message must be not null');
}
$this->tssTxId = $tssTxId;
$this->errorMessage = $errorMessage;
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self($apiResult->tss_tx_id ?? null, $apiResult->error_message ?? null);
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new self($dbState['tss_tx_id'] ?? null, $dbState['error_message'] ?? null);
}
/**
* @return null[]|string[]
*/
public function toArray(): array
{
if($this->tssTxId !== null) {
return ['tss_tx_id' => $this->getTssTxId()];
}
return ['error_message' => $this->getErrorMessage()];
}
/**
* @return string|null
*/
public function getTssTxId(): ?string
{
return $this->tssTxId;
}
/**
* @param string|null $tssTxId
*/
public function setTssTxId(?string $tssTxId): void
{
$this->tssTxId = $tssTxId;
}
/**
* @return string|null
*/
public function getErrorMessage(): ?string
{
return $this->errorMessage;
}
/**
* @param string|null $errorMessage
*/
public function setErrorMessage(?string $errorMessage): void
{
$this->errorMessage = $errorMessage;
}
}
@@ -0,0 +1,353 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data;
use Xentral\Modules\FiskalyApi\Exception\InvalidArgumentException;
use Xentral\Modules\FiskalyApi\Exception\InvalidCredentialsException;
class CashRegister
{
/** @var string $clientId */
private $clientId;
/** @var string $type */
private $type;
/** @var string|null $tssId */
private $tssId;
/** @var string|null $masterClientId */
private $masterClientId;
/** @var string $brand */
private $brand;
/** @var string $model */
private $model;
/** @var string $baseCurrencyCode */
private $baseCurrencyCode;
/** @var string|null $softwareBrand */
private $softwareBrand;
/** @var string|null $softwareVersion */
private $softwareVersion;
/** @var bool|null $vatIdAvailable */
private $vatIdAvailable;
/** @var string|null $env */
private $env;
/**
* CashRegister constructor.
*
* @param string $type
* @param string $clientId
* @param string|null $tssId
* @param string|null $masterClientId
* @param string $brand
* @param string $model
* @param string $baseCurrencyCode
* @param string|null $softwareBrand
* @param string|null $softwareVersion
* @param bool|null $vatIdAvailable
* @param string|null $env
*/
public function __construct(
string $type,
string $clientId,
?string $tssId,
?string $masterClientId,
string $brand,
string $model,
string $baseCurrencyCode = 'EUR',
?string $softwareBrand = null,
string $softwareVersion = null,
?bool $vatIdAvailable = null,
?string $env = null
) {
$this->clientId = $clientId;
$this->type = $type;
$this->tssId = $tssId;
$this->masterClientId = $masterClientId;
$this->brand = $brand;
$this->model = $model;
$this->softwareBrand = $softwareBrand;
$this->baseCurrencyCode = $baseCurrencyCode;
$this->softwareVersion = $softwareVersion;
$this->vatIdAvailable = $vatIdAvailable;
$this->env = $env;
$this->ensureType($type, $tssId, $masterClientId);
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self(
$apiResult->cash_register_type,
$apiResult->client_id,
$apiResult->tss_id ?? null,
$apiResult->master_client_id ?? null,
$apiResult->brand,
$apiResult->model,
$apiResult->base_currency_code ?? 'EUR',
$apiResult->software->brand ?? null,
$apiResult->software->version ?? null,
isset($apiResult->processing_flags->UmsatzsteuerNichtErmittelbar)
? (bool)$apiResult->processing_flags->UmsatzsteuerNichtErmittelbar : null,
$apiResult->_env
);
}
/**
* @return string[]
*/
public function toArray(): array
{
$dbState = [
'client_id' => $this->getClientId(),
'cash_register_type' => [
'type' => $this->getType(),
],
];
if ($this->getMasterClientId() !== null) {
$dbState['cash_register_type']['master_client_id'] = $this->getMasterClientId();
}
if ($this->getTssId() !== null) {
$dbState['cash_register_type']['tss_id'] = $this->getTssId();
}
$dbState['brand'] = $this->getBrand();
$dbState['model'] = $this->getModel();
if ($this->softwareBrand !== null) {
$dbState['software']['brand'] = $this->getSoftwareBrand();
}
if ($this->softwareVersion !== null) {
$dbState['software']['version'] = $this->getSoftwareVersion();
}
$dbState['base_currency_code'] = $this->getBaseCurrencyCode();
return $dbState;
}
/**
* @return string
*/
public function getType(): string
{
return $this->type;
}
/**
* @param string $type
*/
public function setType(string $type): void
{
$this->type = $type;
}
/**
* @return string
*/
public function getClientId(): string
{
return $this->clientId;
}
/**
* @param string $clientId
*/
public function setClientId(string $clientId): void
{
$this->clientId = $clientId;
}
/**
* @return string|null
*/
public function getTssId(): ?string
{
return $this->tssId;
}
/**
* @param string|null $tssId
*/
public function setTssId(?string $tssId): void
{
$this->tssId = $tssId;
}
/**
* @return string|null
*/
public function getMasterClientId(): ?string
{
return $this->masterClientId;
}
/**
* @param string|null $masterClientId
*/
public function setMasterClientId(?string $masterClientId): void
{
$this->masterClientId = $masterClientId;
}
/**
* @return string
*/
public function getBrand(): string
{
return $this->brand;
}
/**
* @param string $brand
*/
public function setBrand(string $brand): void
{
$this->brand = $brand;
}
/**
* @return string
*/
public function getModel(): string
{
return $this->model;
}
/**
* @param string $model
*/
public function setModel(string $model): void
{
$this->model = $model;
}
/**
* @return string
*/
public function getBaseCurrencyCode(): string
{
return $this->baseCurrencyCode;
}
/**
* @param string $baseCurrencyCode
*/
public function setBaseCurrencyCode(string $baseCurrencyCode): void
{
$this->baseCurrencyCode = $baseCurrencyCode;
}
/**
* @return string|null
*/
public function getSoftwareBrand(): ?string
{
return $this->softwareBrand;
}
/**
* @param string|null $softwareBrand
*/
public function setSoftwareBrand(?string $softwareBrand): void
{
$this->softwareBrand = $softwareBrand;
}
/**
* @return string|null
*/
public function getSoftwareVersion(): ?string
{
return $this->softwareVersion;
}
/**
* @param string|null $softwareVersion
*/
public function setSoftwareVersion(?string $softwareVersion): void
{
$this->softwareVersion = $softwareVersion;
}
/**
* @return bool|null
*/
public function getVatIdAvailable(): ?bool
{
return $this->vatIdAvailable;
}
/**
* @param bool|null $vatIdAvailable
*/
public function setVatIdAvailable(?bool $vatIdAvailable): void
{
$this->vatIdAvailable = $vatIdAvailable;
}
/**
* @return string|null
*/
public function getEnv(): ?string
{
return $this->env;
}
/**
* @param string|null $env
*/
public function setEnv(?string $env): void
{
$this->env = $env;
}
/**
* @param string $type
* @param string|null $tssId
* @param string|null $masterClientId
*/
private function ensureType(
string $type,
?string $tssId,
?string $masterClientId
): void {
switch ($type) {
case 'MASTER':
if ($tssId === null) {
throw new InvalidCredentialsException('ss_id must be not null');
}
return;
case 'SLAVE_WITHOUT_TSS':
if ($masterClientId === null) {
throw new InvalidCredentialsException('masterClientId must be not null');
}
return;
case 'SLAVE_WITH_TSS':
if ($tssId === null) {
throw new InvalidCredentialsException('ss_id must be not null');
}
if ($masterClientId === null) {
throw new InvalidCredentialsException('masterClientId must be not null');
}
return;
}
throw new InvalidArgumentException(
"type {$type} is not valid. Allowed are 'MASTER', 'SLAVE_WITHOUT_TSS', 'SLAVE_WITH_TSS'"
);
}
}
@@ -0,0 +1,91 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data;
class Client
{
/** @var string */
private $uuid;
/** @var string */
private $serialNumber;
/** @var string|null $tssId */
private $tssId;
/** @var string|null $env */
private $env;
/**
* Client constructor.
*
* @param string $uuid
* @param string $serialNumber
* @param string|null $tssId
* @param string|null $env
*/
public function __construct(string $uuid, string $serialNumber, ?string $tssId = null, ?string $env = null)
{
$this->uuid = $uuid;
$this->serialNumber = $serialNumber;
$this->tssId = $tssId;
$this->env = $env;
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self(
$apiResult->_id,
$apiResult->serial_number,
$apiResult->tss_id,
$apiResult->_env ?? null
);
}
/**
* @return string
*/
public function getUuid(): string
{
return $this->uuid;
}
/**
* @return string
*/
public function getSerialNumber(): string
{
return $this->serialNumber;
}
/**
* @return string|null
*/
public function getTssId(): ?string
{
return $this->tssId;
}
/**
* @return string|null
*/
public function getEnv(): ?string
{
return $this->env;
}
/**
* @param string|null $env
*/
public function setEnv(?string $env): void
{
$this->env = $env;
}
}
@@ -0,0 +1,97 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data;
use stdClass;
class ErrorMessage
{
/** @var string $code */
private $code;
/** @var string $message */
private $message;
/**
* ErrorMessage constructor.
*
* @param string $code
* @param string $message
*/
public function __construct(string $code, string $message)
{
$this->setCode($code);
$this->setMessage($message);
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self($apiResult->code, $apiResult->message);
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new self($dbState['code'], $dbState['message']);
}
public function toArray(): array
{
return [
'code' => $this->getCode(),
'message' => $this->getMessage(),
];
}
public function toApiResult(): stdClass
{
$apiResult = new stdClass();
$apiResult->code = $this->getCode();
$apiResult->message = $this->getMessage();
return $apiResult;
}
/**
* @return string
*/
public function getCode(): string
{
return $this->code;
}
/**
* @param string $code
*/
public function setCode(string $code): void
{
$this->code = $code;
}
/**
* @return string
*/
public function getMessage(): string
{
return $this->message;
}
/**
* @param string $message
*/
public function setMessage(string $message): void
{
$this->message = $message;
}
}
+234
View File
@@ -0,0 +1,234 @@
<?php
namespace Xentral\Modules\FiskalyApi\Data;
class Export
{
/** @var string */
private $uuId;
/** @var string */
private $type;
/** @var string */
private $env;
/** @var string */
private $tssId;
/** @var string */
private $state;
/** @var string|null */
private $href;
/** @var int|null */
private $timeRequest;
/** @var int|null */
private $timeStart;
/** @var int|null */
private $timeEnd;
/**
* Export constructor.
*
* @param string $uuId
* @param string $type
* @param string $env
* @param string $tssId
* @param string $state
* @param string $href
* @param int $timeRequest
* @param int $timeStart
* @param int $timeEnd
*/
public function __construct(
string $uuId,
string $type,
string $env,
string $tssId,
string $state,
?string $href,
?int $timeRequest,
?int $timeStart,
?int $timeEnd
) {
$this->uuId = $uuId;
$this->type = $type;
$this->env = $env;
$this->tssId = $tssId;
$this->state = $state;
$this->href = $href;
$this->timeRequest = $timeRequest;
$this->timeStart = $timeStart;
$this->timeEnd = $timeEnd;
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self(
$apiResult->_id,
$apiResult->_type,
$apiResult->_env,
$apiResult->tss_id,
$apiResult->state,
$apiResult->href ?? null,
$apiResult->time_request ?? null,
$apiResult->time_start ?? null,
$apiResult->time_end ?? null
);
}
/**
* @return string
*/
public function getUuId(): string
{
return $this->uuId;
}
/**
* @param string $uuId
*/
public function setUuId(string $uuId): void
{
$this->uuId = $uuId;
}
/**
* @return string
*/
public function getType(): string
{
return $this->type;
}
/**
* @param string $type
*/
public function setType(string $type): void
{
$this->type = $type;
}
/**
* @return string
*/
public function getEnv(): string
{
return $this->env;
}
/**
* @param string $env
*/
public function setEnv(string $env): void
{
$this->env = $env;
}
/**
* @return string
*/
public function getTssId(): string
{
return $this->tssId;
}
/**
* @param string $tssId
*/
public function setTssId(string $tssId): void
{
$this->tssId = $tssId;
}
/**
* @return string
*/
public function getState(): string
{
return $this->state;
}
/**
* @param string $state
*/
public function setState(string $state): void
{
$this->state = $state;
}
/**
* @return string|null
*/
public function getHref(): ?string
{
return $this->href;
}
/**
* @param string|null $href
*/
public function setHref(?string $href): void
{
$this->href = $href;
}
/**
* @return int|null
*/
public function getTimeRequest(): ?int
{
return $this->timeRequest;
}
/**
* @param int|null $timeRequest
*/
public function setTimeRequest(?int $timeRequest): void
{
$this->timeRequest = $timeRequest;
}
/**
* @return int|null
*/
public function getTimeStart(): ?int
{
return $this->timeStart;
}
/**
* @param int|null $timeStart
*/
public function setTimeStart(?int $timeStart): void
{
$this->timeStart = $timeStart;
}
/**
* @return int|null
*/
public function getTimeEnd(): ?int
{
return $this->timeEnd;
}
/**
* @param int|null $timeEnd
*/
public function setTimeEnd(?int $timeEnd): void
{
$this->timeEnd = $timeEnd;
}
}
@@ -0,0 +1,106 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data;
use stdClass;
use Xentral\Modules\FiskalyApi\Exception\InvalidArgumentException;
class MetaData
{
/** @var array $metaData */
private $metaData = [];
/**
* MetaData constructor.
*
* @param array $metaData
*/
public function __construct(array $metaData = [])
{
foreach($metaData as $key => $value) {
$this->addMetaElement($key, $value);
}
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new self($dbState);
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
$instance = new self();
if(empty($apiResult)) {
return $instance;
}
foreach($apiResult as $key => $value) {
$instance->addMetaElement($key, $value);
}
return $instance;
}
/**
* @return array
*/
public function toArray(): array
{
return $this->metaData;
}
/**
* @return mixed|stdClass
*/
public function toApiResult()
{
if(empty($this->metaData)) {
return new stdClass();
}
return json_decode(json_encode($this->metaData));
}
/**
* @param string $key
* @param string $value
*/
public function addMetaElement(string $key, string $value): void
{
if(strlen($key) > 40) {
throw new InvalidArgumentException('Meta Key must be less or equal 40 chracters');
}
if(strlen($value) > 500) {
throw new InvalidArgumentException('Meta value must be less or equal 500 chracters');
}
if(count($this->metaData) >= 20 && array_key_exists($key, $this->metaData)) {
throw new InvalidArgumentException('Maximum of 20 Meta-entries are allowed');
}
$this->metaData[$key] = $value;
}
/**
* @param string $key
*
* @return $this
*/
public function removeMetaElementByKey(string $key): self
{
if(array_key_exists($key, $this->metaData)) {
unset($this->metaData[$key]);
}
return $this;
}
}
@@ -0,0 +1,600 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data;
class Organisation
{
/** @var string $uuid */
private $uuid;
/** @var string $type */
private $type;
/** @var array $envs */
private $envs;
/** @var string $name */
private $name;
/** @var string $addressLine1 */
private $addressLine1;
/** @var string|null $addressLine2 */
private $addressLine2;
/** @var string $zip */
private $zip;
/** @var string $town */
private $town;
/** @var string $state */
private $state;
/** @var string $countryCode */
private $countryCode;
/** @var string|null $displayName */
private $displayName;
/** @var string|null $vatId */
private $vatId;
/** @var string|null $taxNumber */
private $taxNumber;
/** @var string|null $economyId */
private $economyId;
/** @var string|null $billingAddressId */
private $billingAddressId;
/** @var string|null $managedByOrganizationId */
private $managedByOrganizationId;
/** @var string|null $createdByUser */
private $createdByUser;
/** @var string|null $gln */
private $gln;
/** @var string|null $withholdBilling */
private $withholdBilling;
/** @var string|null $billToOrganization */
private $billToOrganization;
/** @var string|null $contactPersonId */
private $contactPersonId;
/**
* Organisation constructor.
*
* @param string $uuid
* @param string $type
* @param array $envs
* @param string $name
* @param string $addressLine1
* @param string $zip
* @param string $town
* @param string $state
* @param string $countryCode
* @param string|null $addressLine2
* @param string|null $displayName
* @param string|null $vatId
* @param string|null $taxNumber
* @param string|null $economyId
* @param string|null $billingAddressId
* @param string|null $managedByOrganizationId
* @param string|null $createdByUser
* @param string|null $gln
* @param string|null $withholdBilling
* @param string|null $billToOrganization
* @param string|null $contactPersonId
*/
public function __construct(
string $uuid,
string $type,
array $envs,
string $name,
string $addressLine1,
string $zip,
string $town,
string $state,
string $countryCode,
?string $addressLine2 = null,
?string $displayName = null,
?string $vatId = null,
?string $taxNumber = null,
?string $economyId = null,
?string $billingAddressId = null,
?string $managedByOrganizationId = null,
?string $createdByUser = null,
?string $gln = null,
?string $withholdBilling = null,
?string $billToOrganization = null,
?string $contactPersonId = null
) {
$this->uuid = $uuid;
$this->type = $type;
$this->envs = $envs;
$this->name = $name;
$this->addressLine1 = $addressLine1;
$this->zip = $zip;
$this->town = $town;
$this->state = $state;
$this->countryCode = $countryCode;
$this->addressLine2 = $addressLine2;
$this->displayName = $displayName;
$this->vatId = $vatId;
$this->taxNumber = $taxNumber;
$this->economyId = $economyId;
$this->billingAddressId = $billingAddressId;
$this->managedByOrganizationId = $managedByOrganizationId;
$this->createdByUser = $createdByUser;
$this->gln = $gln;
$this->withholdBilling = $withholdBilling;
$this->billToOrganization = $billToOrganization;
$this->contactPersonId = $contactPersonId;
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self(
$apiResult->_id,
$apiResult->_type,
$apiResult->_envs,
$apiResult->name,
$apiResult->address_line1,
$apiResult->zip,
$apiResult->town,
$apiResult->state,
$apiResult->country_code,
$apiResult->address_line2 ?? null,
$apiResult->display_name ?? null,
$apiResult->vat_id ?? null,
$apiResult->tax_number ?? null,
$apiResult->economy_id ?? null,
$apiResult->billing_address_id ?? null,
$apiResult->managed_by_organization_id ?? null,
$apiResult->created_by_user ?? null,
$apiResult->billing_options->gln ?? null,
$apiResult->billing_options->withhold_billing ?? null,
$apiResult->billing_options->bill_to_organization ?? null,
$apiResult->contactPersonId ?? null
);
}
/**
* @param array $dbState
*
* @return $this
*/
public static function fromDbState(array $dbState): self
{
return new self(
$dbState['_id'],
$dbState['_type'],
$dbState['_envs'],
$dbState['name'],
$dbState['address_line1'],
$dbState['zip'],
$dbState['town'],
$dbState['state'],
$dbState['country_code'],
$dbState['address_line2'] ?? null,
$dbState['display_name'] ?? null,
$dbState['vat_id'] ?? null,
$dbState['tax_number'] ?? null,
$dbState['economy_id'] ?? null,
$dbState['billing_address_id'] ?? null,
$dbState['managed_by_organization_id'] ?? null,
$dbState['created_by_user'] ?? null,
$dbState['billing_options']['gln'] ?? null,
$dbState['billing_options']['withhold_billing'] ?? null,
$dbState['billing_options']['bill_to_organization'] ?? null,
$dbState['contactPersonId'] ?? null
);
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [
'_id' => $this->getUuid(),
'_type' => $this->getType(),
'_envs' => $this->getEnvs(),
'name' => $this->getName(),
'address_line1' => $this->getAddressLine1(),
'zip' => $this->getZip(),
'town' => $this->getTown(),
'country_code' => $this->getCountryCode(),
];
if ($this->displayName !== null) {
$dbState['display_name'] = $this->getDisplayName();
}
if ($this->vatId !== null) {
$dbState['vat_id'] = $this->getVatId();
}
if ($this->contactPersonId !== null) {
$dbState['contact_person_id'] = $this->getContactPersonId();
}
if ($this->addressLine2 !== null) {
$dbState['address_line2'] = $this->getAddressLine2();
}
if ($this->state !== null) {
$dbState['state'] = $this->getState();
}
if ($this->taxNumber !== null) {
$dbState['tax_number'] = $this->getTaxNumber();
}
if ($this->economyId !== null) {
$dbState['economy_id'] = $this->getEconomyId();
}
if ($this->gln !== null) {
$dbState['billing_options']['gln'] = $this->getGln();
}
if ($this->withholdBilling !== null) {
$dbState['billing_options']['withhold_billing'] = $this->getWithholdBilling();
}
if ($this->billToOrganization !== null) {
$dbState['billing_options']['bill_to_organization'] = $this->getBillToOrganization();
}
if ($this->billingAddressId !== null) {
$dbState['billing_address_id'] = $this->getBillingAddressId();
}
if ($this->managedByOrganizationId !== null) {
$dbState['managed_by_organization_id'] = $this->getManagedByOrganizationId();
}
if ($this->createdByUser !== null) {
$dbState['created_by_user'] = $this->getCreatedByUser();
}
return $dbState;
}
/**
* @return string
*/
public function getUuid(): string
{
return $this->uuid;
}
/**
* @param string $uuid
*/
public function setUuid(string $uuid): void
{
$this->uuid = $uuid;
}
/**
* @return string
*/
public function getType(): string
{
return $this->type;
}
/**
* @param string $type
*/
public function setType(string $type): void
{
$this->type = $type;
}
/**
* @return array
*/
public function getEnvs(): array
{
return $this->envs;
}
/**
* @param array $envs
*/
public function setEnvs(array $envs): void
{
$this->envs = $envs;
}
/**
* @return string
*/
public function getName(): string
{
return $this->name;
}
/**
* @param string $name
*/
public function setName(string $name): void
{
$this->name = $name;
}
/**
* @return string
*/
public function getAddressLine1(): string
{
return $this->addressLine1;
}
/**
* @param string $addressLine1
*/
public function setAddressLine1(string $addressLine1): void
{
$this->addressLine1 = $addressLine1;
}
/**
* @return string|null
*/
public function getAddressLine2(): ?string
{
return $this->addressLine2;
}
/**
* @param string|null $addressLine2
*/
public function setAddressLine2(?string $addressLine2): void
{
$this->addressLine2 = $addressLine2;
}
/**
* @return string
*/
public function getZip(): string
{
return $this->zip;
}
/**
* @param string $zip
*/
public function setZip(string $zip): void
{
$this->zip = $zip;
}
/**
* @return string
*/
public function getTown(): string
{
return $this->town;
}
/**
* @param string $town
*/
public function setTown(string $town): void
{
$this->town = $town;
}
/**
* @return string
*/
public function getState(): string
{
return $this->state;
}
/**
* @param string $state
*/
public function setState(string $state): void
{
$this->state = $state;
}
/**
* @return string
*/
public function getCountryCode(): string
{
return $this->countryCode;
}
/**
* @param string $countryCode
*/
public function setCountryCode(string $countryCode): void
{
$this->countryCode = $countryCode;
}
/**
* @return string|null
*/
public function getDisplayName(): ?string
{
return $this->displayName;
}
/**
* @param string|null $displayName
*/
public function setDisplayName(?string $displayName): void
{
$this->displayName = $displayName;
}
/**
* @return string|null
*/
public function getVatId(): ?string
{
return $this->vatId;
}
/**
* @param string|null $vatId
*/
public function setVatId(?string $vatId): void
{
$this->vatId = $vatId;
}
/**
* @return string|null
*/
public function getTaxNumber(): ?string
{
return $this->taxNumber;
}
/**
* @param string|null $taxNumber
*/
public function setTaxNumber(?string $taxNumber): void
{
$this->taxNumber = $taxNumber;
}
/**
* @return string|null
*/
public function getEconomyId(): ?string
{
return $this->economyId;
}
/**
* @param string|null $economyId
*/
public function setEconomyId(?string $economyId): void
{
$this->economyId = $economyId;
}
/**
* @return string|null
*/
public function getBillingAddressId(): ?string
{
return $this->billingAddressId;
}
/**
* @param string|null $billingAddressId
*/
public function setBillingAddressId(?string $billingAddressId): void
{
$this->billingAddressId = $billingAddressId;
}
/**
* @return string|null
*/
public function getManagedByOrganizationId(): ?string
{
return $this->managedByOrganizationId;
}
/**
* @param string|null $managedByOrganizationId
*/
public function setManagedByOrganizationId(?string $managedByOrganizationId): void
{
$this->managedByOrganizationId = $managedByOrganizationId;
}
/**
* @return string|null
*/
public function getCreatedByUser(): ?string
{
return $this->createdByUser;
}
/**
* @param string|null $createdByUser
*/
public function setCreatedByUser(?string $createdByUser): void
{
$this->createdByUser = $createdByUser;
}
/**
* @return string|null
*/
public function getGln(): ?string
{
return $this->gln;
}
/**
* @param string|null $gln
*/
public function setGln(?string $gln): void
{
$this->gln = $gln;
}
/**
* @return string|null
*/
public function getWithholdBilling(): ?string
{
return $this->withholdBilling;
}
/**
* @param string|null $withholdBilling
*/
public function setWithholdBilling(?string $withholdBilling): void
{
$this->withholdBilling = $withholdBilling;
}
/**
* @return string|null
*/
public function getBillToOrganization(): ?string
{
return $this->billToOrganization;
}
/**
* @param string|null $billToOrganization
*/
public function setBillToOrganization(?string $billToOrganization): void
{
$this->billToOrganization = $billToOrganization;
}
/**
* @return string|null
*/
public function getContactPersonId(): ?string
{
return $this->contactPersonId;
}
/**
* @param string|null $contactPersonId
*/
public function setContactPersonId(?string $contactPersonId): void
{
$this->contactPersonId = $contactPersonId;
}
}
@@ -0,0 +1,152 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data;
class TechnicalSecuritySystem
{
/** @var string */
private $uuid;
/** @var string */
private $description;
/** @var string */
private $state;
/** @var string|null $env */
private $env;
/** @var string|null $organizationId */
private $organizationId;
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new TechnicalSecuritySystem(
$apiResult->_id,
$apiResult->description,
$apiResult->state,
$apiResult->_env ?? null
);
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new TechnicalSecuritySystem(
$dbState['_id'],
$dbState['description'],
$dbState['state'],
$dbState['_env'] ?? null
);
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [
'_id' => $this->getUuid(),
'description' => $this->getDescription(),
'state' => $this->getState(),
];
if($this->env !== null) {
$dbState['_env'] = $this->getEnv();
}
return $dbState;
}
/**
* TechnicalSecuritySystem constructor.
*
* @param string $uuid
* @param string $description
* @param string $state
* @param string|null $env
*/
public function __construct(string $uuid, string $description = '', $state = 'ACTIVE', ?string $env = null)
{
$this->uuid = $uuid;
$this->description = $description;
$this->state = $state;
$this->env = $env;
}
/**
* @return string
*/
public function getDescription(): string
{
return $this->description;
}
/**
* @return string
*/
public function getState(): string
{
return $this->state;
}
/**
* @return mixed
*/
public function getUuid(): string
{
return $this->uuid;
}
/**
* @param mixed $uuid
*/
public function setUuid($uuid): void
{
$this->uuid = $uuid;
}
/**
* @return string|null
*/
public function getEnv(): ?string
{
return $this->env;
}
/**
* @param string|null $env
*/
public function setEnv(?string $env): void
{
$this->env = $env;
}
/**
* @return string|null
*/
public function getOrganizationId(): ?string
{
return $this->organizationId;
}
/**
* @param string|null $organizationId
*/
public function setOrganizationId(?string $organizationId): self
{
$this->organizationId = $organizationId;
return $this;
}
}
@@ -0,0 +1,336 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\Transaction;
use Xentral\Modules\FiskalyApi\Exception\InvalidArgumentException;
class AmountsPerPaymentType
{
private $paymentType;
private $currencyCode;
private $amount;
/**
* CashPointClosingPaymentType constructor.
*
* @param string $paymentType
* @param string $amount
* @param string|null $currencyCode
*/
public function __construct(
string $paymentType,
string $amount,
?string $currencyCode = null
) {
$this->ensureType($paymentType);
$this->ensureCurrency($currencyCode);
$this->setType($paymentType);
$this->setAmount($amount);
$this->setCurrencyCode($currencyCode);
}
/**
* @return string[]
*/
public static function getAllowedCurrencies(): array
{
return [
'AED',
'AFN',
'ALL',
'AMD',
'ANG',
'AOA',
'ARS',
'AUD',
'AWG',
'AZN',
'BAM',
'BBD',
'BDT',
'BGN',
'BHD',
'BIF',
'BMD',
'BND',
'BOB',
'BOV',
'BRL',
'BSD',
'BTN',
'BWP',
'BYN',
'BYR',
'BZD',
'CAD',
'CDF',
'CHE',
'CHF',
'CHW',
'CLF',
'CLP',
'CN',
'COP',
'COU',
'CRC',
'CUC',
'CUP',
'CVE',
'CZK',
'DJF',
'DKK',
'DOP',
'DZD',
'EGP',
'ERN',
'ETB',
'EUR',
'FJD',
'FKP',
'GBP',
'GEL',
'GHS',
'GIP',
'GMD',
'GNF',
'GTQ',
'GYD',
'HKD',
'HNL',
'HRK',
'HTG',
'HUF',
'IDR',
'ILS',
'INR',
'IQD',
'IRR',
'ISK',
'JMD',
'JOD',
'JPY',
'KES',
'KGS',
'KHR',
'KMF',
'KPW',
'KRW',
'KWD',
'KYD',
'KZT',
'LAK',
'LBP',
'LKR',
'LRD',
'LSL',
'LYD',
'MAD',
'MDL',
'MGA',
'MKD',
'MMK',
'MNT',
'MOP',
'MRO',
'MUR',
'MVR',
'MWK',
'MXN',
'MXV',
'MYR',
'MZN',
'NAD',
'NGN',
'NIO',
'NOK',
'NPR',
'NZD',
'OMR',
'PAB',
'PEN',
'PGK',
'PHP',
'PKR',
'PLN',
'PYG',
'QAR',
'RON',
'RSD',
'RUB',
'RWF',
'SAR',
'SBD',
'SCR',
'SDG',
'SSP',
'SEK',
'SGD',
'SHP',
'SLL',
'SOS',
'SRD',
'STD',
'SVC',
'SYP',
'SZL',
'THB',
'TJS',
'TMT',
'TND',
'TOP',
'TRY',
'TTD',
'TWD',
'TZS',
'UAH',
'UGX',
'USD',
'UYI',
'UYU',
'UZS',
'VEF',
'VND',
'VUV',
'WST',
'XAF',
'XCD',
'XOF',
'XPF',
'XSU',
'YER',
'ZAR',
'ZMW',
'ZWL',
];
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self(
$apiResult->payment_type,
$apiResult->amount,
$apiResult->currency_code ?? null
);
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new self(
$dbState['payment_type'],
$dbState['amount'],
$dbState['currency_code'] ?? null
);
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [
'payment_type' => $this->getType(),
'amount' => $this->getAmount(),
'currency_code' => $this->getCurrencyCode(),
];
return $dbState;
}
/**
* @return string
*/
public function getType(): string
{
return $this->paymentType;
}
/**
* @param string $type
*/
public function setType(string $type): void
{
$this->ensureType($type);
$this->paymentType = $type;
}
/**
* @return string|null
*/
public function getCurrencyCode(): ?string
{
return $this->currencyCode;
}
/**
* @param string|null $currencyCode
*/
public function setCurrencyCode(?string $currencyCode): void
{
$this->ensureCurrency($currencyCode);
$this->currencyCode = $currencyCode;
}
/**
* @return string
*/
public function getAmount(): string
{
return $this->amount;
}
/**
* @param float $amount
*/
public function setAmount(string $amount): void
{
if(!preg_match('/^-?\d+(\.\d{2,64})$/', $amount)) {
throw new InvalidArgumentException("invalid amount-format: '{$amount}");
}
$this->amount = $amount;
}
/**
* @param string $type
*/
private function ensureType(string $type): void
{
if (
!in_array(
$type,
['CASH', 'NON_CASH']
)) {
throw new InvalidArgumentException("invalid paymentType {$type}");
}
}
/**
* @param string|null $currency
*/
private function ensureCurrency(?string $currency): void
{
if($currency === null) {
return;
}
if (!in_array(
$currency,
self::getAllowedCurrencies(),
true
)) {
throw new InvalidArgumentException("invalid currency {$currency}");
}
}
}
@@ -0,0 +1,203 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\Transaction;
use ArrayIterator;
use Countable;
use IteratorAggregate;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\AmountPerVatId;
class AmountsPerPaymentTypeCollection implements IteratorAggregate, Countable
{
/** @var AmountsPerPaymentType[] $paymentTypes */
private $paymentTypes = [];
/**
* CashPointClosingPaymentTypeCollection constructor.
*
* @param AmountsPerPaymentType[] $paymentTypes
*/
public function __construct(array $paymentTypes = [])
{
foreach ($paymentTypes as $paymentType) {
$this->addPaymentType($paymentType);
}
}
/**
* @param AmountsPerPaymentType $paymentType
*/
public function addPaymentType(AmountsPerPaymentType $paymentType): void
{
$this->paymentTypes[] = AmountsPerPaymentType::fromDbState($paymentType->toArray());
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult($apiResult): self
{
$instance = new self();
foreach ($apiResult as $item) {
$instance->addPaymentType(AmountsPerPaymentType::fromApiResult($item));
}
return $instance;
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
$instance = new self();
foreach ($dbState as $item) {
$instance->addPaymentType(AmountsPerPaymentType::fromDbState($item));
}
return $instance;
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [];
/** @var AmountsPerPaymentType $item */
foreach ($this as $item) {
$dbState[] = $item->toArray();
}
return $dbState;
}
/**
* @param AmountsPerPaymentType $paymentTypeCollection
*
* @return $this
*/
public function combine(self $paymentTypeCollection): self
{
/** @var AmountsPerPaymentType $paymentType */
foreach ($paymentTypeCollection as $paymentType) {
$keys = $this->findKeysForType($paymentType);
if (empty($keys)) {
$this->addPaymentType($paymentType);
continue;
}
$key = reset($keys);
$amount = number_format(
(float)$paymentType->getAmount() + (float)$this->paymentTypes[$key]->getAmount(),
2,
'.',
''
);
$this->paymentTypes[$key]->setAmount($amount);
}
return $this;
}
/**
* @param string $paymentType
*
* @return $this
*/
public function filterByType(string $paymentType): self
{
$instance = new self();
/** @var AmountsPerPaymentType $item */
foreach($this as $item) {
if($item->getType() === $paymentType) {
$instance->addPaymentType($item);
}
}
return $instance;
}
/**
* @param string $currencyCode
*
* @return float
*/
public function getSum(string $currencyCode = 'EUR'): float
{
$sum = 0;
/** @var AmountsPerPaymentType $item */
foreach($this as $item) {
if($item->getCurrencyCode() !== $currencyCode) {
continue;
}
$sum += (float)$item->getAmount();
}
return $sum;
}
/**
* @return array
*/
public function getCurrencyCodes(): array
{
$currencyCodes = [];
/** @var AmountsPerPaymentType $item */
foreach($this as $item) {
$currencyCode = $item->getCurrencyCode();
if(!in_array($currencyCode, $currencyCodes, true)) {
$currencyCodes[] = $currencyCode;
}
}
return $currencyCodes;
}
/**
* @return ArrayIterator
*/
public function getIterator(): ArrayIterator
{
return new ArrayIterator($this->paymentTypes);
}
/**
* @return int
*/
public function count(): int
{
return count($this->paymentTypes);
}
/**
* @param AmountsPerPaymentType $paymentTypeToFind
*
* @return array
*/
private function findKeysForType(AmountsPerPaymentType $paymentTypeToFind): array
{
$keys = [];
/**
* @var int $key
* @var AmountsPerPaymentType $paymentType
*/
foreach ($this as $key => $paymentType) {
if ($paymentType->getType() !== $paymentTypeToFind->getType()) {
continue;
}
if ($paymentType->getCurrencyCode() !== $paymentTypeToFind->getCurrencyCode()) {
continue;
}
$keys[] = $key;
}
return $keys;
}
}
@@ -0,0 +1,107 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\Transaction;
use Xentral\Modules\FiskalyApi\Exception\InvalidArgumentException;
class AmountsPerVatType
{
/** @var string $vatRate */
private $vatRate;
/** @var string $amount */
private $amount;
/**
* AmountsPerVatType constructor.
*
* @param string $vatRate
* @param string $amount
*/
public function __construct(
string $vatRate,
string $amount
) {
$this->setVatRate($vatRate);
$this->setAmount($amount);
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self(
$apiResult->vat_rate,
$apiResult->amount
);
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new self(
$dbState['vat_rate'],
$dbState['amount']
);
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [
'vat_rate' => $this->getVatRate(),
'amount' => $this->getAmount(),
];
return $dbState;
}
/**
* @return string
*/
public function getVatRate(): string
{
return $this->vatRate;
}
/**
* @param string $vatRate
*/
public function setVatRate(string $vatRate): void
{
if(!in_array($vatRate, ['NORMAL','REDUCED_1','SPECIAL_RATE_1','SPECIAL_RATE_2', 'NULL'])) {
throw new InvalidArgumentException("invalid vatRate: '{$vatRate}");
}
$this->vatRate = $vatRate;
}
/**
* @return string
*/
public function getAmount(): string
{
return $this->amount;
}
/**
* @param float $amount
*/
public function setAmount(string $amount): void
{
if(!preg_match('/^-?\d+(\.\d{2,64})$/', $amount)) {
throw new InvalidArgumentException("invalid amount-format: '{$amount}");
}
$this->amount = $amount;
}
}
@@ -0,0 +1,142 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\Transaction;
use ArrayIterator;
use Countable;
use IteratorAggregate;
class AmountsPerVatTypeCollection implements IteratorAggregate, Countable
{
/** @var AmountsPerVatType[] $paymentTypes */
private $paymentTypes = [];
/**
* AmountsPerVatTypeCollection constructor.
*
* @param AmountsPerVatType[] $paymentTypes
*/
public function __construct(array $paymentTypes = [])
{
foreach ($paymentTypes as $paymentType) {
$this->addPaymentType($paymentType);
}
}
/**
* @param AmountsPerVatType $paymentType
*/
public function addPaymentType(AmountsPerVatType $paymentType): void
{
$this->paymentTypes[] = AmountsPerVatType::fromDbState($paymentType->toArray());
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult($apiResult): self
{
$instance = new self();
foreach ($apiResult as $item) {
$instance->addPaymentType(AmountsPerVatType::fromApiResult($item));
}
return $instance;
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
$instance = new self();
foreach ($dbState as $item) {
$instance->addPaymentType(AmountsPerVatType::fromDbState($item));
}
return $instance;
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [];
/** @var AmountsPerVatType $item */
foreach ($this as $item) {
$dbState[] = $item->toArray();
}
return $dbState;
}
/**
* @param AmountsPerVatType $amountsPerVatType
*
* @return $this
*/
public function combine(self $amountsPerVatType): self
{
/** @var AmountsPerVatType $amountPerVatRate */
foreach($amountsPerVatType as $amountPerVatRate) {
$keys = $this->findKeysForType($amountPerVatRate);
if(empty($keys)) {
$this->addPaymentType($amountPerVatRate);
continue;
}
$key = reset($keys);
$amount = (float)$this->paymentTypes[$key]->getAmount() + (float)$amountPerVatRate->getAmount();
$this->paymentTypes[$key]->setAmount(
number_format($amount, 2, '.', '')
);
}
return $this;
}
/**
* @param AmountsPerVatType $paymentTypeToFind
*
* @return array
*/
private function findKeysForType(AmountsPerVatType $paymentTypeToFind): array
{
$keys = [];
/**
* @var int $key
* @var AmountsPerVatType $amountPerVatRate
*/
foreach($this as $key => $amountPerVatRate) {
if($amountPerVatRate->getVatRate() !== $paymentTypeToFind->getVatRate()) {
continue;
}
$keys[] = $key;
}
return $keys;
}
/**
* @return ArrayIterator
*/
public function getIterator(): ArrayIterator
{
return new ArrayIterator($this->paymentTypes);
}
/**
* @return int
*/
public function count(): int
{
return count($this->paymentTypes);
}
}
@@ -0,0 +1,119 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\Transaction;
use Xentral\Modules\FiskalyApi\Exception\InvalidArgumentException;
class OrderLineItem
{
/** @var string $quantity */
private $quantity;
/** @var string $text */
private $text;
/** @var string $pricePerUnit */
private $pricePerUnit;
/**
* OrderLineItem constructor.
*
* @param string $quantity
* @param string $text
* @param string $pricePerUnit
*/
public function __construct(string $quantity, string $text, string $pricePerUnit)
{
$this->setQuantity($quantity);
$this->setText($text);
$this->setPricePerUnit($pricePerUnit);
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self($apiResult->quantity, $apiResult->text, $apiResult->price_per_unit);
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new self($dbState['quantity'], $dbState['text'], $dbState['price_per_unit']);
}
/**
* @return string[]
*/
public function toArray(): array
{
return [
'quantity' => $this->getQuantity(),
'text' => $this->getText(),
'price_per_unit' => $this->getPricePerUnit(),
];
}
/**
* @return string
*/
public function getQuantity(): string
{
return $this->quantity;
}
/**
* @param string $quantity
*/
public function setQuantity(string $quantity): void
{
if (!preg_match('/^-?\d+(\.\d{1,64})?$/', $quantity)) {
throw new InvalidArgumentException("invalid quantity-format '{$quantity}'");
}
$this->quantity = $quantity;
}
/**
* @return string
*/
public function getText(): string
{
return $this->text;
}
/**
* @param string $text
*/
public function setText(string $text): void
{
$this->text = mb_substr($text, 0, 255);
}
/**
* @return string
*/
public function getPricePerUnit(): string
{
return $this->pricePerUnit;
}
/**
* @param string $pricePerUnit
*/
public function setPricePerUnit(string $pricePerUnit): void
{
if (!preg_match('/^-?\d+(\.\d{2,64})?$/', $pricePerUnit)) {
throw new InvalidArgumentException("invalid price-format '{$pricePerUnit}'");
}
$this->pricePerUnit = $pricePerUnit;
}
}
@@ -0,0 +1,91 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\Transaction;
use ArrayIterator;
use Countable;
use IteratorAggregate;
class OrderLineItemCollection implements IteratorAggregate, Countable
{
/** @var OrderLineItem[] $lineItems */
private $lineItems = [];
/**
* OrderLineItemCollection constructor.
*
* @param array $lineItems
*/
public function __construct(array $lineItems = [])
{
foreach($lineItems as $lineItem) {
$this->addLineItem($lineItem);
}
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
$instance = new self();
foreach($apiResult as $item) {
$instance->addLineItem(OrderLineItem::fromApiResult($item));
}
return $instance;
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState = []): self
{
$instance = new self();
foreach($dbState as $item) {
$instance->addLineItem(OrderLineItem::fromDbState($item));
}
return $instance;
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [];
foreach($this as $item) {
$dbState[] = $item->toArray();
}
return $dbState;
}
public function addLineItem(OrderLineItem $lineItem): void
{
$this->lineItems[] = OrderLineItem::fromDbState($lineItem->toArray());;
}
/**
* @return int
*/
public function count(): int
{
return count($this->lineItems);
}
/**
* @return ArrayIterator
*/
public function getIterator(): ArrayIterator
{
return new ArrayIterator($this->lineItems);
}
}
@@ -0,0 +1,63 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\Transaction;
class SchemaOrder
{
/** @var OrderLineItemCollection $lineItems */
private $lineItems;
/**
* SchemaOther constructor.
*/
public function __construct(OrderLineItemCollection $lineItemCollection)
{
$this->setLineItems($lineItemCollection);
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self(OrderLineItemCollection::fromApiResult($apiResult->line_items));
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new self(OrderLineItemCollection::fromDbState($dbState['line_items']));
}
/**
* @return array
*/
public function toArray(): array
{
return ['line_items' => $this->lineItems->toArray()];
}
/**
* @return OrderLineItemCollection
*/
public function getLineItems(): OrderLineItemCollection
{
return OrderLineItemCollection::fromDbState($this->lineItems->toArray());
}
/**
* @param OrderLineItemCollection $lineItems
*/
public function setLineItems(OrderLineItemCollection $lineItems): void
{
$this->lineItems = OrderLineItemCollection::fromDbState($lineItems->toArray());
}
}
@@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\Transaction;
class SchemaOther
{
/**
* SchemaOther constructor.
*/
public function __construct()
{
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self();
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new self();
}
/**
* @return array
*/
public function toArray(): array
{
return [];
}
}
@@ -0,0 +1,91 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\Transaction;
class SchemaRaw
{
/** @var string $processData */
private $processData;
/** @var string|null $processType */
private $processType;
/**
* SchemaRaw constructor.
*
* @param string $processData
* @param string|null $processType
*/
public function __construct(string $processData, ?string $processType = null)
{
$this->setProcessData($processData);
$this->setProcessType($processType);
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self($apiResult->process_data, $apiResult->process_type ?? null);
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new self($dbState['process_data'], $dbState['process_type'] ?? null);
}
/**
* @return string[]
*/
public function toArray(): array
{
$dbState = ['process_data' => $this->getProcessData()];
if($this->processType !== null) {
$dbState['process_type'] = $this->getProcessType();
}
return $dbState;
}
/**
* @return string
*/
public function getProcessData(): string
{
return $this->processData;
}
/**
* @param string $processData
*/
public function setProcessData(string $processData): void
{
$this->processData = $processData;
}
/**
* @return string|null
*/
public function getProcessType(): ?string
{
return $this->processType;
}
/**
* @param string|null $processType
*/
public function setProcessType(?string $processType): void
{
$this->processType = $processType;
}
}
@@ -0,0 +1,151 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\Transaction;
use Xentral\Modules\FiskalyApi\Exception\InvalidArgumentException;
class SchemaReceipt
{
/** @var string $receipType */
private $receiptType;
/** @var AmountsPerVatTypeCollection $amountsPerVatRate */
private $amountsPerVatRate;
/** @var AmountsPerPaymentTypeCollection $amountsPerPaymentType */
private $amountsPerPaymentType;
/**
* SchemaReceipt constructor.
*
* @param string $receiptType
* @param AmountsPerVatTypeCollection $amountsPerVatId
* @param AmountsPerPaymentTypeCollection $amountsPerPaymentType
*/
public function __construct(
string $receiptType,
AmountsPerVatTypeCollection $amountsPerVatId,
AmountsPerPaymentTypeCollection $amountsPerPaymentType
) {
$this->setReceiptType($receiptType);
$this->setAmountsPerVatRate($amountsPerVatId);
$this->setAmountsPerPaymentType($amountsPerPaymentType);
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self(
$apiResult->receipt_type,
AmountsPerVatTypeCollection::fromApiResult($apiResult->amounts_per_vat_rate),
AmountsPerPaymentTypeCollection::fromApiResult($apiResult->amounts_per_payment_type)
);
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new self(
$dbState['receipt_type'],
AmountsPerVatTypeCollection::fromDbState($dbState['amounts_per_vat_rate']),
AmountsPerPaymentTypeCollection::fromDbState($dbState['amounts_per_payment_type'])
);
}
/**
* @return array
*/
public function toArray(): array
{
return [
'receipt_type' => $this->getReceiptType(),
'amounts_per_vat_rate' => $this->amountsPerVatRate->toArray(),
'amounts_per_payment_type' => $this->amountsPerPaymentType->toArray(),
];
}
/**
* @return string
*/
public function getReceiptType(): string
{
return $this->receiptType;
}
/**
* @param string $receiptType
*/
public function setReceiptType(string $receiptType): void
{
$this->ensureType($receiptType);
$this->receiptType = $receiptType;
}
/**
* @return AmountsPerVatTypeCollection
*/
public function getAmountsPerVatRate(): AmountsPerVatTypeCollection
{
return AmountsPerVatTypeCollection::fromDbState($this->amountsPerVatRate->toArray());
}
/**
* @param AmountsPerVatTypeCollection $amountsPerVatRate
*/
public function setAmountsPerVatRate(AmountsPerVatTypeCollection $amountsPerVatRate): void
{
$this->amountsPerVatRate = AmountsPerVatTypeCollection::fromDbState($amountsPerVatRate->toArray());
}
/**
* @return AmountsPerPaymentTypeCollection
*/
public function getAmountsPerPaymentType(): AmountsPerPaymentTypeCollection
{
return AmountsPerPaymentTypeCollection::fromDbState($this->amountsPerPaymentType->toArray());
}
/**
* @param AmountsPerPaymentTypeCollection $amountsPerPaymentType
*/
public function setAmountsPerPaymentType(AmountsPerPaymentTypeCollection $amountsPerPaymentType): void
{
$this->amountsPerPaymentType = AmountsPerPaymentTypeCollection::fromDbState($amountsPerPaymentType->toArray());
}
/**
* @param string $type
*/
private function ensureType(string $type): void
{
if (in_array(
$type,
[
'RECEIPT',
'TRAINING',
'TRANSFER',
'ORDER',
'CANCELLATION',
'ABORT',
'BENEFIT_IN_KIND',
'INVOICE',
'OTHER',
'ANNULATION',
]
)
) {
return;
}
throw new InvalidArgumentException("invalid Type '{$type}'");
}
}
@@ -0,0 +1,126 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\Transaction;
class SchemaStandardV1
{
/** @var SchemaReceipt|null $receipt */
private $receipt;
/** @var SchemaOrder|null $order */
private $order;
/** @var SchemaOther|null $other */
private $other;
/**
* SchemaStandardV1 constructor.
*
* @param SchemaReceipt|null $receipt
* @param SchemaOrder|null $order
* @param SchemaOther|null $other
*/
public function __construct(?SchemaReceipt $receipt, ?SchemaOrder $order = null, ?SchemaOther $other = null)
{
$this->setReceipt($receipt);
$this->setOrder($order);
$this->setOther($other);
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self(
empty($apiResult->receipt) ? null : SchemaReceipt::fromApiResult($apiResult->receipt),
empty($apiResult->order) ? null : SchemaOrder::fromApiResult($apiResult->order),
empty($apiResult->other) ? null : SchemaOther::fromApiResult($apiResult->other)
);
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new self(
empty($dbState['receipt']) ? null : SchemaReceipt::fromDbState($dbState['receipt']),
empty($dbState['order']) ? null : SchemaOrder::fromDbState($dbState['order']),
empty($dbState['other']) ? null : SchemaOther::fromDbState($dbState['other'])
);
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [];
if($this->receipt !== null) {
$dbState['receipt'] = $this->receipt->toArray();
}
if($this->order !== null) {
$dbState['order'] = $this->order->toArray();
}
if($this->other !== null) {
$dbState['other'] = $this->other->toArray();
}
return $dbState;
}
/**
* @return SchemaReceipt|null
*/
public function getReceipt(): ?SchemaReceipt
{
return $this->receipt === null ? null : SchemaReceipt::fromDbState($this->receipt->toArray());
}
/**
* @param SchemaReceipt|null $receipt
*/
public function setReceipt(?SchemaReceipt $receipt): void
{
$this->receipt = $receipt === null ? null : SchemaReceipt::fromDbState($receipt->toArray());
}
/**
* @return SchemaOrder|null
*/
public function getOrder(): ?SchemaOrder
{
return $this->order === null ? null : SchemaOrder::fromDbState($this->order->toArray());
}
/**
* @param SchemaOrder|null $order
*/
public function setOrder(?SchemaOrder $order): void
{
$this->order = $order === null ? null : SchemaOrder::fromDbState($order->toArray());
}
/**
* @return SchemaOther|null
*/
public function getOther(): ?SchemaOther
{
return $this->other === null ? null : SchemaOther::fromDbState($this->other->toArray());
}
/**
* @param SchemaOther|null $other
*/
public function setOther(?SchemaOther $other): void
{
$this->other = $other === null ? null : SchemaOther::fromDbState($other->toArray());
}
}
@@ -0,0 +1,181 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\Transaction;
use stdClass;
use Xentral\Modules\FiskalyApi\Data\MetaData;
use Xentral\Modules\FiskalyApi\Exception\InvalidArgumentException;
class Transaction
{
/** @var string $state */
protected $state;
/** @var string $clientId */
protected $clientId;
/** @var TransactionSchema|null $schema */
protected $schema;
/** @var MetaData|null $metaData */
protected $metaData;
/**
* Transaction constructor.
*
* @param string $state
* @param string $clientId
* @param TransactionSchema|null $schema
* @param MetaData|null $metaData
*/
public function __construct(string $state, string $clientId, ?TransactionSchema $schema = null, ?MetaData $metaData = null)
{
$this->setState($state);
$this->setClientId($clientId);
$this->setSchema($schema);
$this->setMetaData($metaData);
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult)
{
return new self(
$apiResult->state,
$apiResult->client_id,
empty($apiResult->schema) ? null : TransactionSchema::fromApiResult($apiResult->schema),
empty($apiResult->metadata) ? null : MetaData::fromApiResult($apiResult->metadata)
);
}
/**
* @param array $dbState
*
* @return Transaction
*/
public static function fromDbState(array $dbState)
{
return new self(
$dbState['state'],
$dbState['client_id'],
empty($dbState['schema']) ? null : TransactionSchema::fromDbState($dbState['schema']),
empty($dbState['metadata']) ? null : MetaData::fromDbState($dbState['metadata'])
);
}
/**
* @return string[]
*/
public function toArray(): array
{
$dbState = ['state' => $this->getState(), 'client_id' => $this->getClientId()];
if($this->schema !== null) {
$dbState['schema'] = $this->schema->toArray();
}
if($this->metaData !== null) {
$dbState['metadata'] = $this->metaData->toArray();
}
return $dbState;
}
/**
* @return stdClass
*/
public function toApiResult()
{
$apiResult = new stdClass();
$apiResult->state = $this->getState();
$apiResult->client_id = $this->getClientId();
if($this->schema !== null) {
$apiResult->schema = $this->schema->toApiResult();
}
if($this->metaData !== null) {
$apiResult->metadata = $this->metaData->toApiResult();
}
return $apiResult;
}
/**
* @return string
*/
public function getState(): string
{
return $this->state;
}
/**
* @param string $state
*/
public function setState(string $state): void
{
$this->ensureState($state);
$this->state = $state;
}
/**
* @return string
*/
public function getClientId(): string
{
return $this->clientId;
}
/**
* @param string $clientId
*/
public function setClientId(string $clientId): self
{
$this->clientId = $clientId;
return $this;
}
/**
* @return TransactionSchema|null
*/
public function getSchema(): ?TransactionSchema
{
return $this->schema;
}
/**
* @param TransactionSchema|null $schema
*/
public function setSchema(?TransactionSchema $schema): void
{
$this->schema = $schema === null ? null : TransactionSchema::fromDbState($schema->toArray());
}
/**
* @return MetaData|null
*/
public function getMetaData(): ?MetaData
{
return $this->metaData === null ? null : MetaData::fromDbState($this->metaData->toArray());
}
/**
* @param MetaData|null $metaData
*/
public function setMetaData(?MetaData $metaData): void
{
$this->metaData = $metaData === null ? null : MetaData::fromDbState($metaData->toArray());
}
/**
* @param string $state
*/
private function ensureState(string $state):void
{
if(!in_array($state, ['ACTIVE', 'CANCELLED', 'FINISHED'])) {
throw new InvalidArgumentException("invalid state '{$state}'");
}
}
}
@@ -0,0 +1,137 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\Transaction;
use DateTimeInterface;
use DateTimeZone;
use DateTime;
use stdClass;
class TransactionLog
{
/** @var string $operation */
private $operation;
/** @var DateTimeInterface $timestamp */
private $timestamp;
/** @var string $timestampFormat */
private $timestampFormat;
/**
* TransactionLog constructor.
*
* @param string $operation
* @param DateTimeInterface $timestamp
* @param string $timestampFormat
*/
public function __construct(string $operation, DateTimeInterface $timestamp, string $timestampFormat = 'utcTime')
{
$this->setOperation($operation);
$this->setTimestamp($timestamp);
$this->setTimestampFormat($timestampFormat);
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self(
$apiResult->operation,
(new DateTime('now', new DateTimeZone('UTC')))->setTimestamp($apiResult->timestamp),
$apiResult->timestamp_format
);
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new self(
$dbState['operation'],
(new DateTime('now', new DateTimeZone('UTC')))->setTimestamp($dbState['timestamp']),
$dbState['timestamp_format']
);
}
/**
* @return array
*/
public function toArray(): array
{
return [
'operation' => $this->getOperation(),
'timestamp' => $this->getTimestamp()->getTimestamp(),
'timestamp_format' => $this->getTimestampFormat(),
];
}
/**
* @return stdClass
*/
public function toApiResult(): stdClass
{
$apiResult = new stdClass();
$apiResult->operation = $this->getOperation();
$apiResult->timestamp = $this->getTimestamp()->getTimestamp();
$apiResult->timestamp_format = $this->getTimestampFormat();
return $apiResult;
}
/**
* @return string
*/
public function getOperation(): string
{
return $this->operation;
}
/**
* @param string $operation
*/
public function setOperation(string $operation): void
{
$this->operation = $operation;
}
/**
* @return DateTimeInterface
*/
public function getTimestamp(): DateTimeInterface
{
return $this->timestamp;
}
/**
* @param DateTimeInterface $timestamp
*/
public function setTimestamp(DateTimeInterface $timestamp): void
{
$this->timestamp = $timestamp;
}
/**
* @return string
*/
public function getTimestampFormat(): string
{
return $this->timestampFormat;
}
/**
* @param string $timestampFormat
*/
public function setTimestampFormat(string $timestampFormat): void
{
$this->timestampFormat = $timestampFormat;
}
}
@@ -0,0 +1,527 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\Transaction;
use DateTimeInterface;
use DateTime;
use DateTimeZone;
use stdClass;
use Xentral\Modules\FiskalyApi\Data\MetaData;
class TransactionReponse extends Transaction
{
/** @var int|null $number */
private $number;
/** @var string|null */
private $qrCodeData;
/** @var DateTimeInterface|null $timeStart */
private $timeStart;
/** @var DateTimeInterface|null $timeStart */
private $timeEnd;
/** @var string|null $clientSerialNumber */
private $clientSerialNumber;
/** @var string|null $certificateSerial */
private $certificateSerial;
/** @var int|null $revision */
private $revision;
/** @var int|null $latestRevision */
private $latestRevision;
/** @var TransactionLog|null $log */
private $log;
/** @var TransactionSignature|null $signature */
private $signature;
/** @var string|null $tssId */
private $tssId;
/** @var string|null $_type */
private $_type;
/** @var string|null $_id */
private $_id;
/** @var string|null $_env */
private $_env;
/** @var string|null $_version */
private $_version;
public function __construct(
string $state,
string $clientId,
?TransactionSchema $schema = null,
?MetaData $metaData = null,
?int $number = null,
?DateTimeInterface $timeStart = null,
?DateTimeInterface $timeEnd = null,
?string $clientSerialNumber = null,
?string $certificateSerial = null,
?string $qrCodeData = null,
?int $revision = null,
?int $latestRevision = null,
?TransactionLog $log = null,
?TransactionSignature $signature = null,
?string $tssId = null,
?string $type = null,
?string $uuId = null,
?string $env = null,
?string $vesion = null
) {
parent::__construct($state, $clientId, $schema, $metaData);
$this->setNumber($number);
$this->setTimeStart($timeStart);
$this->setTimeEnd($timeEnd);
$this->setClientSerialNumber($clientSerialNumber);
$this->setCertificateSerial($certificateSerial);
$this->setQrCodeData($qrCodeData);
$this->setRevision($revision);
$this->setLatestRevision($latestRevision);
$this->setLog($log);
$this->setSignature($signature);
$this->setTssId($tssId);
$this->setType($type);
$this->setId($uuId);
$this->setEnv($env);
$this->setVersion($vesion);
}
/**
* @param $apiResult
*
* @throws \Exception
* @return Transaction
*/
public static function fromApiResult(object $apiResult): TransactionReponse
{
return new self(
$apiResult->state,
$apiResult->client_id,
empty($apiResult->schema) ? null : TransactionSchema::fromApiResult($apiResult->schema),
empty($apiResult->metadata) ? null : MetaData::fromApiResult($apiResult->metadata),
isset($apiResult->number) ? (int)$apiResult->number : null,
!empty($apiResult->time_start) ? (new DateTime('now', new DateTimeZone('UTC')))->setTimestamp(
$apiResult->time_start
) : null,
!empty($apiResult->time_end) ? (new DateTime('now', new DateTimeZone('UTC')))->setTimestamp(
$apiResult->time_end
) : null,
$apiResult->client_serial_number ?? null,
$apiResult->certificate_serial ?? null,
$apiResult->qr_code_data ?? null,
isset($apiResult->revision) ? (int)$apiResult->revision : null,
isset($apiResult->latest_revision) ? (int)$apiResult->latest_revision : null,
!empty($apiResult->log) ? TransactionLog::fromApiResult($apiResult->log) : null,
!empty($apiResult->signature) ? TransactionSignature::fromApiResult($apiResult->signature) : null,
$apiResult->tss_id ?? null,
$apiResult->_type ?? null,
$apiResult->_id ?? null,
$apiResult->_env ?? null,
$apiResult->_version ?? null
);
}
/**
* @param array $dbState
*
* @return Transaction
*/
public static function fromDbState(array $dbState): TransactionReponse
{
return new self(
$dbState['state'],
$dbState['client_id'],
empty($dbState['schema']) ? null : TransactionSchema::fromDbState($dbState['schema']),
!isset($dbState['metadata']) ? null : MetaData::fromDbState($dbState['metadata']),
isset($dbState['number']) ? (int)$dbState['number'] : null,
!empty($dbState['time_start']) ? (new DateTime('now', new DateTimeZone('UTC')))->setTimestamp(
$dbState['time_start']
) : null,
!empty($dbState['time_end']) ? (new DateTime('now', new DateTimeZone('UTC')))->setTimestamp(
$dbState['time_end']
) : null,
$dbState['client_serial_number'] ?? null,
$dbState['certificate_serial'] ?? null,
$dbState['qr_code_data'] ?? null,
isset($dbState['revision']) ? (int)$dbState['revision'] : null,
isset($dbState['latest_revision']) ? (int)$dbState['latest_revision'] : null,
!empty($dbState['log']) ? TransactionLog::fromDbState($dbState['log']) : null,
!empty($dbState['signature']) ? TransactionSignature::fromDbState($dbState['signature']) : null,
$dbState['tss_id'] ?? null,
$dbState['_type'] ?? null,
$dbState['_id'] ?? null,
$dbState['_env'] ?? null,
$dbState['_version'] ?? null
);
}
public function toArray(): array
{
$dbState = parent::toArray();
if ($this->number !== null) {
$dbState['number'] = $this->getNumber();
}
if ($this->timeStart !== null) {
$dbState['time_start'] = $this->timeStart->getTimestamp();
}
if ($this->timeEnd !== null) {
$dbState['time_end'] = $this->timeEnd->getTimestamp();
}
if ($this->clientSerialNumber !== null) {
$dbState['client_serial_number'] = $this->getClientSerialNumber();
}
if ($this->certificateSerial !== null) {
$dbState['certificate_serial'] = $this->getCertificateSerial();
}
if ($this->qrCodeData !== null) {
$dbState['qr_code_data'] = $this->getQrCodeData();
}
if ($this->revision !== null) {
$dbState['revision'] = $this->getRevision();
}
if ($this->latestRevision !== null) {
$dbState['latest_revision'] = $this->getLatestRevision();
}
if ($this->tssId !== null) {
$dbState['tss_id'] = $this->getTssId();
}
if ($this->log !== null) {
$dbState['log'] = $this->log->toArray();
}
if ($this->signature !== null) {
$dbState['signature'] = $this->signature->toArray();
}
if ($this->tssId !== null) {
$dbState['tss_id'] = $this->getTssId();
}
if ($this->metaData !== null) {
$dbState['metadata'] = $this->metaData->toArray();
}
if ($this->_type !== null) {
$dbState['_type'] = $this->getType();
}
if ($this->_id !== null) {
$dbState['_id'] = $this->getId();
}
if ($this->_version !== null) {
$dbState['_version'] = $this->getVersion();
}
if ($this->_env !== null) {
$dbState['_env'] = $this->getEnv();
}
return $dbState;
}
/**
* @return stdClass
*/
public function toApiResult()
{
$apiResult = parent::toApiResult();
if ($this->number !== null) {
$apiResult->number = $this->getNumber();
}
if ($this->timeStart !== null) {
$apiResult->time_start = $this->timeStart->getTimestamp();
}
if ($this->timeEnd !== null) {
$apiResult->time_end = $this->timeEnd->getTimestamp();
}
if ($this->clientSerialNumber !== null) {
$apiResult->client_serial_number = $this->getClientSerialNumber();
}
if ($this->certificateSerial !== null) {
$apiResult->certificate_serial = $this->getCertificateSerial();
}
if ($this->qrCodeData !== null) {
$apiResult->qr_code_data = $this->getQrCodeData();
}
if ($this->revision !== null) {
$apiResult->revision = $this->getRevision();
}
if ($this->latestRevision !== null) {
$apiResult->latest_revision = $this->getLatestRevision();
}
if ($this->tssId !== null) {
$apiResult->tss_id = $this->getTssId();
}
if ($this->log !== null) {
$apiResult->log = $this->log->toApiResult();
}
if ($this->signature !== null) {
$apiResult->signature = $this->signature->toApiResult();
}
if ($this->tssId !== null) {
$apiResult->tss_id = $this->getTssId();
}
if ($this->metaData !== null) {
$apiResult->metadata = $this->metaData->toApiResult();
}
if ($this->_type !== null) {
$apiResult->_type = $this->getType();
}
if ($this->_id !== null) {
$apiResult->_id = $this->getId();
}
if ($this->_version !== null) {
$apiResult->_version = $this->getVersion();
}
if ($this->_env !== null) {
$apiResult->_env = $this->getEnv();
}
return $apiResult;
}
/**
* @return int|null
*/
public function getNumber(): ?int
{
return $this->number;
}
/**
* @param int|null $number
*/
public function setNumber(?int $number): void
{
$this->number = $number;
}
/**
* @return string|null
*/
public function getQrCodeData(): ?string
{
return $this->qrCodeData;
}
/**
* @param string|null $qrCodeData
*/
public function setQrCodeData(?string $qrCodeData): void
{
$this->qrCodeData = $qrCodeData;
}
/**
* @return DateTimeInterface|null
*/
public function getTimeStart(): ?DateTimeInterface
{
return $this->timeStart;
}
/**
* @param DateTimeInterface|null $timeStart
*/
public function setTimeStart(?DateTimeInterface $timeStart): void
{
$this->timeStart = $timeStart;
}
/**
* @return DateTimeInterface|null
*/
public function getTimeEnd(): ?DateTimeInterface
{
return $this->timeEnd;
}
/**
* @param DateTimeInterface|null $timeEnd
*/
public function setTimeEnd(?DateTimeInterface $timeEnd): void
{
$this->timeEnd = $timeEnd;
}
/**
* @return string|null
*/
public function getClientSerialNumber(): ?string
{
return $this->clientSerialNumber;
}
/**
* @param string|null $clientSerialNumber
*/
public function setClientSerialNumber(?string $clientSerialNumber): void
{
$this->clientSerialNumber = $clientSerialNumber;
}
/**
* @return string|null
*/
public function getCertificateSerial(): ?string
{
return $this->certificateSerial;
}
/**
* @param string|null $certificateSerial
*/
public function setCertificateSerial(?string $certificateSerial): void
{
$this->certificateSerial = $certificateSerial;
}
/**
* @return int|null
*/
public function getRevision(): ?int
{
return $this->revision;
}
/**
* @param int|null $revision
*/
public function setRevision(?int $revision): void
{
$this->revision = $revision;
}
/**
* @return int|null
*/
public function getLatestRevision(): ?int
{
return $this->latestRevision;
}
/**
* @param int|null $latestRevision
*/
public function setLatestRevision(?int $latestRevision): void
{
$this->latestRevision = $latestRevision;
}
/**
* @return TransactionLog|null
*/
public function getLog(): ?TransactionLog
{
return $this->log;
}
/**
* @param TransactionLog|null $log
*/
public function setLog(?TransactionLog $log): void
{
$this->log = $log;
}
/**
* @return TransactionSignature|null
*/
public function getSignature(): ?TransactionSignature
{
return $this->signature;
}
/**
* @param TransactionSignature|null $signature
*/
public function setSignature(?TransactionSignature $signature): void
{
$this->signature = $signature;
}
/**
* @return string|null
*/
public function getTssId(): ?string
{
return $this->tssId;
}
/**
* @param string|null $tssId
*/
public function setTssId(?string $tssId): void
{
$this->tssId = $tssId;
}
/**
* @return string|null
*/
public function getType(): ?string
{
return $this->_type;
}
/**
* @param string|null $type
*/
public function setType(?string $type): void
{
$this->_type = $type;
}
/**
* @return string|null
*/
public function getId(): ?string
{
return $this->_id;
}
/**
* @param string|null $id
*/
public function setId(?string $id): void
{
$this->_id = $id;
}
/**
* @return string|null
*/
public function getEnv(): ?string
{
return $this->_env;
}
/**
* @param string|null $env
*/
public function setEnv(?string $env): void
{
$this->_env = $env;
}
/**
* @return string|null
*/
public function getVersion(): ?string
{
return $this->_version;
}
/**
* @param string|null $version
*/
public function setVersion(?string $version): void
{
$this->_version = $version;
}
}
@@ -0,0 +1,240 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\Transaction;
use ArrayIterator;
use Countable;
use Exception;
use IteratorAggregate;
class TransactionReponseCollection implements IteratorAggregate, Countable
{
/** @var array $transactionResponses */
private $transactionResponses = [];
/**
* TransactionReponseCollection constructor.
*
* @param array $transactionResponses
*/
public function __construct(array $transactionResponses = [])
{
foreach ($transactionResponses as $transactionResponse) {
$this->addTransactionResponse($transactionResponse);
}
}
/**
* @param TransactionReponse $transactionReponse
*/
public function addTransactionResponse(TransactionReponse $transactionReponse): void
{
$this->transactionResponses[] = TransactionReponse::fromDbState($transactionReponse->toArray());
}
/**
* @param $apiResult
*
* @throws Exception
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
$instance = new self();
foreach ($apiResult as $item) {
$instance->addTransactionResponse(TransactionReponse::fromApiResult($item));
}
return $instance;
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
$instance = new self();
foreach ($dbState as $item) {
$instance->addTransactionResponse(TransactionReponse::fromDbState($item));
}
return $instance;
}
/**
* @return array
*/
public function toArray(): array
{
$dbState = [];
/** @var TransactionReponse $item */
foreach ($this as $item) {
$dbState[] = $item->toArray();
}
return $dbState;
}
/**
* @return array
*/
public function toApiResult(): array
{
$dbState = [];
/** @var TransactionReponse $item */
foreach ($this as $item) {
$dbState[] = $item->toApiResult();
}
return $dbState;
}
/**
* @return array
*/
public function getClientIds(): array
{
$clientIds = [];
/** @var TransactionReponse $item */
foreach ($this as $item) {
$clientId = $item->getClientId();
if (!in_array($clientId, $clientIds, true)) {
$clientIds[] = $clientId;
}
}
return $clientIds;
}
/**
* @return array
*/
public function getTrxIds(): array
{
$rxIds = [];
/** @var TransactionReponse $item */
foreach ($this as $item) {
$rxId = $item->getId();
if (!in_array($rxId, $rxIds, true)) {
$rxIds[] = $rxId;
}
}
return $rxIds;
}
/**
* @return array
*/
public function getTransactionDates(): array
{
$dates = [];
/** @var TransactionReponse $item */
foreach ($this as $item) {
$startDate = $item->getTimeStart();
if($startDate === null) {
continue;
}
$date = $startDate->format('Y-m-d');
if(!in_array($date, $dates)) {
$dates[] = $date;
}
}
sort($dates);
return $dates;
}
/**
* @param string $clientId
*
* @return $this
*/
public function filterClientId(string $clientId): self
{
$instance = new self();
/** @var TransactionReponse $item */
foreach ($this as $item) {
if ($clientId !== $item->getClientId()) {
continue;
}
$instance->addTransactionResponse($item);
}
return $instance;
}
/**
* @param string $date
*
* @return $this
*/
public function filterDate(string $date): self
{
$instance = new self();
/** @var TransactionReponse $item */
foreach ($this as $item) {
$startDate = $item->getTimeStart();
if($startDate === null) {
continue;
}
if ($date !== $startDate->format('Y-m-d')) {
continue;
}
$instance->addTransactionResponse($item);
}
return $instance;
}
/**
* @param string $clientId
* @param bool $first
*
* @return TransactionReponse|null
*/
public function getBoundedTransactionWithClientId(string $clientId, bool $first = true): ?TransactionReponse
{
$actualKey = null;
$actualNumber = null;
/** @var TransactionReponse $item */
foreach ($this as $key => $item) {
if ($clientId !== $item->getClientId()) {
continue;
}
$number = $item->getNumber();
if ($number === null) {
continue;
}
if ($actualNumber === null || ($actualNumber > $number && $first) || ($actualNumber < $number && !$first)) {
$actualKey = $key;
$actualNumber = $number;
}
}
return $actualKey === null ? null : TransactionReponse::fromDbState(
$this->transactionResponses[$actualKey]->toArray()
);
}
/**
* @return ArrayIterator
*/
public function getIterator(): ArrayIterator
{
return new ArrayIterator($this->transactionResponses);
}
/**
* @return int
*/
public function count(): int
{
return count($this->transactionResponses);
}
}
@@ -0,0 +1,77 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\Transaction;
use Xentral\Modules\FiskalyApi\UuidTool;
class TransactionRequest extends Transaction
{
/** @var string|null $tssId */
private $tssId;
/** @var string|null $_id */
private $_id;
/** @var int $revision */
private $revision;
/**
* @return string|null
*/
public function getTssId(): ?string
{
return $this->tssId;
}
/**
* @param string|null $tssId
*/
public function setTssId(?string $tssId): self
{
$this->tssId = $tssId;
return $this;
}
/**
* @return string|null
*/
public function getId(): ?string
{
if($this->_id !== null) {
return $this->_id;
}
$this->setId(UuidTool::generateUuid());
return $this->_id;
}
/**
* @param string|null $id
*/
public function setId(?string $id): self
{
$this->_id = $id;
return $this;
}
/**
* @return int
*/
public function getRevision(): int
{
return $this->revision;
}
/**
* @param int $revision
*/
public function setRevision(int $revision): self
{
$this->revision = $revision;
return $this;
}
}
@@ -0,0 +1,112 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\Transaction;
use stdClass;
class TransactionSchema
{
/** @var SchemaStandardV1|null $standardV1 */
private $standardV1;
/** @var SchemaRaw|null $raw */
private $raw;
public function __construct(?SchemaStandardV1 $standardV1, ?SchemaRaw $raw = null)
{
$this->setStandardV1($standardV1);
$this->setRaw($raw);
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self(
empty($apiResult->standard_v1) ? null : SchemaStandardV1::fromApiResult($apiResult->standard_v1),
empty($apiResult->raw) ? null : SchemaRaw::fromApiResult($apiResult->raw)
);
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new self(
empty($dbState['standard_v1']) ? null : SchemaStandardV1::fromDbState($dbState['standard_v1']),
empty($dbState['raw']) ? null : SchemaRaw::fromDbState($dbState['raw'])
);
}
/**
* @return string[]
*/
public function toArray(): array
{
$dbState = [];
if ($this->standardV1 !== null) {
$dbState['standard_v1'] = $this->standardV1->toArray();
}
if ($this->raw !== null) {
$dbState['raw'] = $this->raw->toArray();
}
return $dbState;
}
/**
* @return stdClass
*/
public function toApiResult()
{
$apiResult = new stdClass();
if ($this->standardV1 !== null) {
$apiResult->standard_v1 = json_decode(json_encode($this->standardV1->toArray()));
}
if ($this->raw !== null) {
$apiResult->raw = json_decode(json_encode($this->raw->toArray()));
}
return $apiResult;
}
/**
* @return SchemaStandardV1|null
*/
public function getStandardV1(): ?SchemaStandardV1
{
return $this->standardV1 === null ? null : SchemaStandardV1::fromDbState($this->standardV1->toArray());
}
/**
* @param SchemaStandardV1|null $standardV1
*/
public function setStandardV1(?SchemaStandardV1 $standardV1): void
{
$this->standardV1 = $standardV1 === null ? null : SchemaStandardV1::fromDbState($standardV1->toArray());
}
/**
* @return SchemaRaw|null
*/
public function getRaw(): ?SchemaRaw
{
return $this->raw === null ? null : SchemaRaw::fromDbState($this->raw->toArray());
}
/**
* @param SchemaRaw|null $raw
*/
public function setRaw(?SchemaRaw $raw): void
{
$this->raw = $raw === null ? null : SchemaRaw::fromDbState($raw->toArray());
}
}
@@ -0,0 +1,160 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data\Transaction;
use stdClass;
class TransactionSignature
{
/** @var string $value */
private $value;
/** @var string $algorithm */
private $algorithm;
/** @var int $counter */
private $counter;
/** @var string $publicKey */
private $publicKey;
/**
* TransactionSignature constructor.
*
* @param string $value
* @param string $algorithm
* @param int $counter
* @param string $publicKey
*/
public function __construct(string $value, string $algorithm, int $counter, string $publicKey)
{
$this->setValue($value);
$this->setAlgorithm($algorithm);
$this->setCounter($counter);
$this->setPublicKey($publicKey);
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self(
$apiResult->value,
$apiResult->algorithm,
(int)$apiResult->counter,
$apiResult->public_key
);
}
/**
* @param array $dbState
*
* @return static
*/
public static function fromDbState(array $dbState): self
{
return new self(
$dbState['value'],
$dbState['algorithm'],
(int)$dbState['counter'],
$dbState['public_key']
);
}
/**
* @return array
*/
public function toArray(): array
{
return [
'value' => $this->getValue(),
'algorithm' => $this->getAlgorithm(),
'counter' => $this->getCounter(),
'public_key' => $this->getPublicKey(),
];
}
/**
* @return stdClass
*/
public function toApiResult(): stdClass
{
$apiResult = new stdClass();
$apiResult->value = $this->getValue();
$apiResult->algorithm = $this->getAlgorithm();
$apiResult->counter = $this->getCounter();
$apiResult->public_key = $this->getPublicKey();
return $apiResult;
}
/**
* @return string
*/
public function getValue(): string
{
return $this->value;
}
/**
* @param string $value
*/
public function setValue(string $value): void
{
$this->value = $value;
}
/**
* @return string
*/
public function getAlgorithm(): string
{
return $this->algorithm;
}
/**
* @param string $algorithm
*/
public function setAlgorithm(string $algorithm): void
{
$this->algorithm = $algorithm;
}
/**
* @return int
*/
public function getCounter(): int
{
return $this->counter;
}
/**
* @param int $counter
*/
public function setCounter(int $counter): void
{
$this->counter = $counter;
}
/**
* @return string
*/
public function getPublicKey(): string
{
return $this->publicKey;
}
/**
* @param string $publicKey
*/
public function setPublicKey(string $publicKey): void
{
$this->publicKey = $publicKey;
}
}
+165
View File
@@ -0,0 +1,165 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data;
class User
{
/** @var string */
private $uuId;
/** @var string */
private $type;
/** @var string */
private $email;
/** @var array */
private $envs;
/** @var string|null */
private $firstName;
/** @var string|null */
private $lastName;
/**
* User constructor.
*
* @param string $uuId
* @param string $type
* @param string $email
* @param array $envs
* @param string|null $firstName
* @param string|null $lastName
*/
public function __construct(
string $uuId,
string $type,
string $email,
array $envs,
?string $firstName = null,
?string $lastName = null
) {
$this->uuId = $uuId;
$this->type = $type;
$this->email = $email;
$this->envs = $envs;
$this->firstName = $firstName;
$this->lastName = $lastName;
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self(
$apiResult->_id,
$apiResult->_type,
$apiResult->email,
$apiResult->_envs,
$apiResult->first_name ?? null,
$apiResult->last_name ?? null
);
}
/**
* @return string
*/
public function getUuId(): string
{
return $this->uuId;
}
/**
* @param string $uuId
*/
public function setUuId(string $uuId): void
{
$this->uuId = $uuId;
}
/**
* @return string
*/
public function getType(): string
{
return $this->type;
}
/**
* @param string $type
*/
public function setType(string $type): void
{
$this->type = $type;
}
/**
* @return string
*/
public function getEmail(): string
{
return $this->email;
}
/**
* @param string $email
*/
public function setEmail(string $email): void
{
$this->email = $email;
}
/**
* @return array
*/
public function getEnvs(): array
{
return $this->envs;
}
/**
* @param array $envs
*/
public function setEnvs(array $envs): void
{
$this->envs = $envs;
}
/**
* @return string|null
*/
public function getFirstName(): ?string
{
return $this->firstName;
}
/**
* @param string|null $firstName
*/
public function setFirstName(?string $firstName): void
{
$this->firstName = $firstName;
}
/**
* @return string|null
*/
public function getLastName(): ?string
{
return $this->lastName;
}
/**
* @param string|null $lastName
*/
public function setLastName(?string $lastName): void
{
$this->lastName = $lastName;
}
}
@@ -0,0 +1,143 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Data;
class VatDefinition
{
/** @var int */
private $vatDefinitionExportId;
/** @var string */
private $type;
/** @var string */
private $env;
/** @var float */
private $percentage;
/** @var string */
private $description;
/**
* VatDefinition constructor.
*
* @param int $vatDefinitionExportId
* @param string $type
* @param string $env
* @param float $percentage
* @param string $description
*/
public function __construct(
int $vatDefinitionExportId,
string $type,
string $env,
float $percentage,
string $description
) {
$this->vatDefinitionExportId = $vatDefinitionExportId;
$this->type = $type;
$this->env = $env;
$this->percentage = $percentage;
$this->description = $description;
}
/**
* @param $apiResult
*
* @return static
*/
public static function fromApiResult(object $apiResult): self
{
return new self(
(int)$apiResult->vat_definition_export_id,
$apiResult->_type,
$apiResult->_env,
(float)$apiResult->percentage,
$apiResult->description
);
}
/**
* @return int
*/
public function getVatDefinitionExportId(): int
{
return $this->vatDefinitionExportId;
}
/**
* @param int $vatDefinitionExportId
*/
public function setVatDefinitionExportId(int $vatDefinitionExportId): void
{
$this->vatDefinitionExportId = $vatDefinitionExportId;
}
/**
* @return string
*/
public function getType(): string
{
return $this->type;
}
/**
* @param string $type
*/
public function setType(string $type): void
{
$this->type = $type;
}
/**
* @return string
*/
public function getEnv(): string
{
return $this->env;
}
/**
* @param string $env
*/
public function setEnv(string $env): void
{
$this->env = $env;
}
/**
* @return float
*/
public function getPercentage(): float
{
return $this->percentage;
}
/**
* @param float $percentage
*/
public function setPercentage(float $percentage): void
{
$this->percentage = $percentage;
}
/**
* @return string
*/
public function getDescription(): string
{
return $this->description;
}
/**
* @param string $description
*/
public function setDescription(string $description): void
{
$this->description = $description;
}
}
@@ -0,0 +1,71 @@
<?php
namespace Xentral\Modules\FiskalyApi\DataTable;
use Xentral\Components\Database\SqlQuery\SelectQuery;
use Xentral\Widgets\DataTable\Column\Column;
use Xentral\Widgets\DataTable\Column\ColumnCollection;
use Xentral\Widgets\DataTable\Feature\FeatureCollection;
use Xentral\Widgets\DataTable\Feature\StateSaveFeature;
use Xentral\Widgets\DataTable\Options\DataTableOptions;
use Xentral\Widgets\DataTable\Type\AbstractDataTableType;
class FiskalyTseDataTable extends AbstractDataTableType
{
/**
* @param DataTableOptions $options
*
* @return void
*/
public function configureOptions(DataTableOptions $options)
{
$options->setDefaultSorting(['id' => 'DESC']);
}
/**
* @param SelectQuery $query
*
* @return void
*/
public function configureQuery(SelectQuery $query)
{
$query
->cols([
'f.id',
'IF(o.display_name <> "", o.display_name, o.name) AS organization',
'p.name',
'CONCAT(f.tss_description, " (", f.tss_uuid, ")", IF(f.is_test_environment = 1," (TEST-Client)","")) AS tss_description',
'CONCAT(f.client_description, " (", f.client_uuid, ")") AS client_description',
'CONCAT(\'<a href="index.php?module=fiskaly&action=settings_tse&id=\', f.id, \'"><img src="themes/new/images/edit.svg"></a><img class="button-delete" id="delete-\', f.id, \'" src="themes/new/images/delete.svg">\') as menu'
])
->from('fiskaly_pos_mapping AS f')
->leftJoin('fiskaly_organization AS o', 'f.organization_id = o.fiskaly_organization_id')
->leftJoin('projekt AS p', 'f.pos_id = p.id');
}
/**
* @param ColumnCollection $columns
*
* @return void
*/
public function configureColumns(ColumnCollection $columns)
{
$columns->add(Column::hidden('id', 'id'));
$columns->add(Column::searchable('organization', 'Filiale'));
$columns->add(Column::searchable('name', 'POS Projekt'));
$columns->add(Column::searchable('tss_description', 'TSS'));
$columns->add(Column::searchable('client_description', 'Client'));
$columns->add(Column::fixed('menu', 'Menü'));
}
/**
* @param FeatureCollection $features
*
* @return void
*/
public function configureFeatures(FeatureCollection $features)
{
parent::configureFeatures($features);
$features->remove(StateSaveFeature::class);
}
}
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Exception;
use RuntimeException;
class FiskalyApiBaseException extends RuntimeException implements FiskalyApiExceptionInterface
{
}
@@ -0,0 +1,12 @@
<?php
namespace Xentral\Modules\FiskalyApi\Exception;
use Xentral\Core\Exception\ModuleExceptionInterface;
interface FiskalyApiExceptionInterface extends ModuleExceptionInterface
{
}
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Exception;
use InvalidArgumentException as SplInvalidArgumentException;
class InvalidArgumentException extends SplInvalidArgumentException implements FiskalyApiExceptionInterface
{
}
@@ -0,0 +1,10 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Exception;
class InvalidCredentialsException extends FiskalyApiBaseException
{
}
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Exception;
use InvalidArgumentException;
class InvalidTransactionException extends InvalidArgumentException implements FiskalyApiExceptionInterface
{
}
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Exception;
use RuntimeException as SplRuntimeException;
class SmaEndpointNotFoundException extends SplRuntimeException implements FiskalyApiExceptionInterface
{
}
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Exception;
use RuntimeException as SplRuntimeException;
class SmaEndpointNotReachableException extends SplRuntimeException implements FiskalyApiExceptionInterface
{
}
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Exception;
class VatRateNotFoundException extends FiskalyApiBaseException
{
public static function fromPercentage(float $percentage){
return new VatRateNotFoundException("VAT rate {$percentage} not found");
}
}
@@ -0,0 +1,190 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Factory;
use Exception;
use Xentral\Modules\FiskalyApi\Data\Organisation;
use Xentral\Modules\FiskalyApi\Service\FiskalyApi;
use Xentral\Modules\FiskalyApi\Service\FiskalyConfig;
use Xentral\Modules\FiskalyApi\Service\FiskalyDSFinVKApi;
use Xentral\Modules\FiskalyApi\Service\FiskalyEReceiptApi;
use Xentral\Modules\FiskalyApi\Service\FiskalyKassenSichVApi;
use Xentral\Modules\FiskalyApi\Service\FiskalyManagementApi;
use Xentral\Modules\SystemConfig\SystemConfigModule;
class FiskalyApiFactory
{
/** @var FiskalyConfig */
private $fiskalyConfig;
/**
* FiskalyApiFactory constructor.
*
* @param FiskalyConfig $fiskalyConfig
*/
public function __construct(FiskalyConfig $fiskalyConfig)
{
$this->fiskalyConfig = $fiskalyConfig;
}
/**
* @return int
*/
public function getMaxTssIds(): int
{
return $this->fiskalyConfig->getMaxTss();
}
/**
* @return array
*/
public function getOrganizations(): array
{
return array_map(
static function ($organization){
return Organisation::fromDbState($organization);
},
$this->fiskalyConfig->getOrganisations()
);
}
/**
* @param string $organization
*
* @throws Exception
* @return FiskalyKassenSichVApi
*/
public function createFiskalyKassenSichVApiFromSystemSettings(string $organization): FiskalyKassenSichVApi
{
return $this->createFiskalyKassenSichVApi(
(string)$this->fiskalyConfig->getActiveSmaEndpoint($organization),
(string)$this->fiskalyConfig->getApiKey($organization),
(string)$this->fiskalyConfig->getApiSecret($organization)
);
}
/**
* @param string $organization
*
* @throws Exception
* @return FiskalyManagementApi
*/
public function createFiskalyManagementApiFromSystemSettings(string $organization): FiskalyManagementApi
{
return $this->createFiskalyManagementApi(
$this->fiskalyConfig->getActiveSmaEndpoint($organization),
$this->fiskalyConfig->getApiKey($organization),
$this->fiskalyConfig->getApiSecret($organization)
);
}
/**
* @param string $organization
*
* @throws Exception
* @return FiskalyDSFinVKApi
*/
public function createFiskalyDSFinVkApiFromSystemSettings(string $organization): FiskalyDSFinVKApi
{
return $this->createFiskalyDSFinVkApi(
$this->fiskalyConfig->getActiveSmaEndpoint($organization),
$this->fiskalyConfig->getApiKey($organization),
$this->fiskalyConfig->getApiSecret($organization)
);
}
/**
* @param string $organization
*
* @throws Exception
* @return FiskalyEReceiptApi
*/
public function createFiskalyEReceiptApiFromSystemSettings(string $organization): FiskalyEReceiptApi
{
return $this->createFiskalyEReceiptApi(
$this->fiskalyConfig->getActiveSmaEndpoint($organization),
$this->fiskalyConfig->getApiKey($organization),
$this->fiskalyConfig->getApiSecret($organization)
);
}
/**
* @param string $smaEndpoint
* @param string $apiKey
* @param string $apiSecret
*
* @throws Exception
*
* @return FiskalyKassenSichVApi
*/
public function createFiskalyKassenSichVApi(
string $smaEndpoint,
string $apiKey,
string $apiSecret
): FiskalyKassenSichVApi {
return new FiskalyKassenSichVApi(
$smaEndpoint,
$apiKey,
$apiSecret
);
}
/**
* @param string $smaEndpoint
* @param string $apiKey
* @param string $apiSecret
*
* @throws Exception
*
* @return FiskalyManagementApi
*/
public function createFiskalyManagementApi(
string $smaEndpoint,
string $apiKey,
string $apiSecret
): FiskalyManagementApi {
return new FiskalyManagementApi(
$smaEndpoint,
$apiKey,
$apiSecret
);
}
/**
* @param string $smaEndpoint
* @param string $apiKey
* @param string $apiSecret
*
* @throws Exception
*
* @return FiskalyDSFinVKApi
*/
public function createFiskalyDSFinVkApi(string $smaEndpoint, string $apiKey, string $apiSecret): FiskalyDSFinVKApi
{
return new FiskalyDSFinVKApi(
$smaEndpoint,
$apiKey,
$apiSecret
);
}
/**
* @param string $smaEndpoint
* @param string $apiKey
* @param string $apiSecret
*
* @throws Exception
* @return FiskalyEReceiptApi
*/
public function createFiskalyEReceiptApi(string $smaEndpoint, string $apiKey, string $apiSecret): FiskalyEReceiptApi
{
return new FiskalyEReceiptApi(
$smaEndpoint,
$apiKey,
$apiSecret
);
}
}
@@ -0,0 +1,450 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Factory;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\AmountPerVatId;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\AmountPerVatIdCollection;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\BusinessCase;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\BusinessCaseCollection;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\CashAmountByCurrency;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\CashAmountByCurrencyCollection;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\CashPointClosingPaymentType;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\CashPointClosingPaymentTypeCollection;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\CashPointClosingTransaction;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\CashPointClosingTransactionAddress;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\CashPointClosingTransactionBuyer;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\CashPointClosingTransactionCollection;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\CashPointClosingTransactionLine;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\CashPointClosingTransactionLineCollection;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\CashPointClosingTransactionUser;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\TransactionData;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\TransactionHead;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\TransactionSecurity;
use Xentral\Modules\FiskalyApi\Data\Transaction\AmountsPerPaymentTypeCollection;
use Xentral\Modules\FiskalyApi\Data\Transaction\TransactionReponse;
use Xentral\Modules\FiskalyApi\Data\Transaction\TransactionReponseCollection;
use Xentral\Modules\FiskalyApi\Exception\InvalidArgumentException;
class FiskalyCashPointClosingFactory
{
private const VAT_DEFINITION_EXPORT_ID_NOT_TAXABLE = 5;
private const VAT_DEFINITION_EXPORT_ID_NORMAL = 1;
private const VAT_DEFINITION_EXPORT_ID_REDUCED = 2;
private const BUYER_ADDRESS_THRESHOLD_AMOUNT = 200;
/** @var float|null $thresholdNormal */
private $thresholdNormal;
/**
* CashPointClosingFactory constructor.
*
* @param float|null $thresholdNormal
*/
public function __construct(?float $thresholdNormal = null)
{
$this->thresholdNormal = $thresholdNormal;
}
/**
* @param float $tax
*
* @return $this
*/
public function setTaxNormal(float $tax): self
{
$this->thresholdNormal = $tax;
return $this;
}
/**
* @param float $inclVat
*
* @return BusinessCase
*/
public function getEmployeeTipBusinessCase(float $inclVat): BusinessCase
{
return $this->getNotTaxableBusinessCase('TrinkgeldAN', $inclVat);
}
/**
* @param string $type
* @param float $inclVat
*
* @return BusinessCase
*/
public function getNotTaxableBusinessCase(string $type, float $inclVat): BusinessCase
{
return new BusinessCase(
$type, AmountPerVatIdCollection::fromDbState(
[
[
'vat_definition_export_id' => self::VAT_DEFINITION_EXPORT_ID_NOT_TAXABLE,
'incl_vat' => $inclVat,
'excl_vat' => null,
'vat' => 0,
],
]
)
);
}
/**
* @param float $inclVat
* @param string $baseCurrencyCode
*
* @return CashPointClosingPaymentType
*/
public function getPaymentType(float $inclVat, string $baseCurrencyCode = 'EUR'): CashPointClosingPaymentType
{
return new CashPointClosingPaymentType('Bar', $inclVat, $baseCurrencyCode);
}
/**
* @param array $posJournals
*
* @return AmountPerVatIdCollection
*/
public function createAmountPerVatIdCollectionFromPosJournalDbState(
array $posJournals
): AmountPerVatIdCollection {
$collection = new AmountPerVatIdCollection();
foreach ($posJournals as $posJournal) {
$collection->addAmountPerVatId(
$this->createAmountPerVatIdFromPosJournalDbState($posJournal)
);
}
return $collection->groupByVatDefinitionExportId();
}
/**
* @param array $posJournal
*
* @return AmountPerVatId
*/
public function createAmountPerVatIdFromPosJournalDbState(
array $posJournal
): AmountPerVatId {
if ($this->thresholdNormal === null) {
throw new InvalidArgumentException('no normal tax set');
}
$vatDefinitionExportId = self::VAT_DEFINITION_EXPORT_ID_NOT_TAXABLE;
if ($posJournal['tax'] > $this->thresholdNormal) {
$vatDefinitionExportId = self::VAT_DEFINITION_EXPORT_ID_NORMAL;
} elseif ($posJournal['tax'] > 0) {
$vatDefinitionExportId = self::VAT_DEFINITION_EXPORT_ID_REDUCED;
}
return new AmountPerVatId(
$vatDefinitionExportId,
(float)$posJournal['amount_gross'],
(float)$posJournal['amount_net']
);
}
/**
* @param array $posJournals
*
* @return BusinessCaseCollection
*/
public function createBusinessCaseCollection(
array $posJournals
): BusinessCaseCollection {
$collection = new BusinessCaseCollection();
foreach ($posJournals as $posJournal) {
$collection->addBusinessCase($this->createBusinessCase($posJournal));
}
return $collection->groupByType();
}
/**
* @param TransactionReponse $transactionResponse
*
* @return AmountsPerPaymentTypeCollection
*/
public function getPaymentTypesFromTransaction(TransactionReponse $transactionResponse): AmountsPerPaymentTypeCollection
{
$instance = new AmountsPerPaymentTypeCollection();
$schema = $transactionResponse->getSchema();
if ($schema === null) {
return $instance;
}
$standardV1 = $schema->getStandardV1();
if ($standardV1 === null) {
return $instance;
}
$receipt = $standardV1->getReceipt();
if ($receipt === null) {
return $instance;
}
return $receipt->getAmountsPerPaymentType();
}
/**
* @param TransactionReponseCollection $collection
*
* @return AmountsPerPaymentTypeCollection
*/
public function getPaymentTypesFromTransactionCollection(TransactionReponseCollection $collection
): AmountsPerPaymentTypeCollection {
$instance = new AmountsPerPaymentTypeCollection();
/** @var TransactionReponse $item */
foreach ($collection as $item) {
$instance->combine($this->getPaymentTypesFromTransaction($item));
}
return $instance;
}
/**
* @param AmountsPerPaymentTypeCollection $amountsPerPaymentTypeCollection
*
* @return CashAmountByCurrencyCollection
*/
public function getCashAmountByCurrencyCollection(
AmountsPerPaymentTypeCollection $amountsPerPaymentTypeCollection
): CashAmountByCurrencyCollection {
$currencyCodes = $amountsPerPaymentTypeCollection->getCurrencyCodes();
$collection = new CashAmountByCurrencyCollection();
foreach ($currencyCodes as $currencyCode) {
$collection->addAmountPerCurrecy(
new CashAmountByCurrency($amountsPerPaymentTypeCollection->getSum($currencyCode), $currencyCode)
);
}
return $collection;
}
/**
* @param array $posJournals
*
* @return CashPointClosingPaymentTypeCollection
*/
public function getCashPointClosingPaymentTypeCollection(array $posJournals
): CashPointClosingPaymentTypeCollection {
$collection = new CashPointClosingPaymentTypeCollection();
foreach ($posJournals as $posJournal) {
$collection->addPaymentType($this->getCashPointClosingPaymentType($posJournal));
}
return $collection->getGrouped();
}
/**
* @param array $posJournalCollection
*
* @return CashPointClosingPaymentTypeCollection
*/
public function getCashPointClosingPaymentTypeCollectionByPosJournalCollection(array $posJournalCollection
): CashPointClosingPaymentTypeCollection {
$collection = new CashPointClosingPaymentTypeCollection();
foreach ($posJournalCollection as $posJournals) {
$collection->combine($this->getCashPointClosingPaymentTypeCollection($posJournals));
}
return $collection->getGrouped();
}
/**
* @param array $posJournal
*
* @return CashPointClosingPaymentType
*/
public function getCashPointClosingPaymentType(array $posJournal): CashPointClosingPaymentType
{
$currencyCode = !empty($posJournal['currency']) ? $posJournal['currency'] : 'EUR';
$amount = (float)$posJournal['amount_gross'];
switch ($posJournal['payment_type']) {
case 'ec':
case 'eckarte':
$type = 'ECKarte';
break;
case 'kredit':
case 'kreditkarte':
$type = 'Kreditkarte';
break;
case 'Ueb':
case 'rechnung':
$type = 'Unbar';
break;
default:
$type = 'Bar';
break;
}
if ($amount == 0) {
$type = 'Keine';
}
return new CashPointClosingPaymentType($type, $amount, $currencyCode);
}
public function getCashPointClosingTransactionCollection(
TransactionReponseCollection $transactionResponseCollection,
array $posJournalCollection,
array $posSessions
): CashPointClosingTransactionCollection {
$collection = new CashPointClosingTransactionCollection();
/** @var TransactionReponse $item */
foreach ($transactionResponseCollection as $item) {
$posJournals = $posJournalCollection[$item->getId()];
$posSession = $posSessions[$item->getId()];
$collection->addTransaction($this->getCashPointClosingTransaction($item, $posJournals, $posSession));
}
return $collection;
}
/**
* @param string $receiptType
*
* @return string
*/
public function mapReceiptType(string $receiptType): string
{
switch ($receiptType) {
case 'RECEIPT':
return 'Beleg';
case 'TRANSFER':
return 'AVTransfer';
case 'ORDER':
return 'AVBestellung';
case 'CANCELLATION':
return 'AVBelegabbruch';
case 'ABORT':
return 'AVBelegabbruch';
case 'BENEFIT_IN_KIND':
return 'AVSachbezug';
case 'INVOICE':
return 'AVRechnung';
case 'OTHER':
return 'AVSonstige';
case 'ANNULATION':
return 'AVBelegstorno';
default:
return $receiptType;
}
}
/**
* @param TransactionReponse $transactionResponse
* @param array $posJournals
* @param array $posSession
*
* @return CashPointClosingTransaction
*/
public function getCashPointClosingTransaction(
TransactionReponse $transactionResponse,
array $posJournals,
array $posSession
): CashPointClosingTransaction {
$businessCollection = $this->createBusinessCaseCollection($posJournals);
$user = new CashPointClosingTransactionUser((string)$posSession['kassiererId']);
$isBuyerCustomer = !empty($posSession['address']['kundennummer']);
$needUserAddress = !empty($posSession['soll']) && $posSession['soll'] >= self::BUYER_ADDRESS_THRESHOLD_AMOUNT;
$userAddress = !$needUserAddress ? null : new CashPointClosingTransactionAddress(
$posSession['address']['strasse'],
$posSession['address']['plz'],
$posSession['address']['ort'],
$posSession['land_iso3']
);
$buyer = new CashPointClosingTransactionBuyer(
$posSession['addr']['name'],
$isBuyerCustomer ? $posSession['address']['kundennummer'] : $posSession['address']['mitarbeiternummer'],
$isBuyerCustomer ? 'Kunde' : 'Mitarbeiter',
$userAddress
);
// TODO add error
$schema = $transactionResponse->getSchema();
$standardV1 = $schema === null ? null : $schema->getStandardV1();
$receipt = $standardV1 === null ? null : $standardV1->getReceipt();
$receiptType = $receipt === null ? 'Beleg' : $this->mapReceiptType($receipt->getReceiptType());
$lines = new CashPointClosingTransactionLineCollection();//@todo lines generieren
return new CashPointClosingTransaction(
new TransactionHead(
$transactionResponse->getId(),
$transactionResponse->getId(),
$transactionResponse->getClientId(),
$receiptType,
false,
$transactionResponse->getNumber(),
$transactionResponse->getTimeStart(),
$transactionResponse->getTimeEnd(),
$user,
$buyer
),
new TransactionData(
$businessCollection->getSumInclVat(),
$this->getCashPointClosingPaymentTypeCollection($posJournals),
$this->createAmountPerVatIdCollectionFromPosJournalDbState($posJournals),
$lines
),
new TransactionSecurity($transactionResponse->getId())
);
}
public static function getLines(BusinessCaseCollection $businessCollection
): CashPointClosingTransactionLineCollection {
$lineItemExportId = '';
$lines = new CashPointClosingTransactionLineCollection();
/** @var BusinessCase $businessCase */
foreach ($businessCollection as $businessCase) {
$line = new CashPointClosingTransactionLine($businessCase, $lineItemExportId, false);
$lines->addLine($line);
}
return $lines;
}
/**
* @param array $posJournal
*
* @return BusinessCase
*/
public function createBusinessCase(array $posJournal): BusinessCase
{
switch ($posJournal['type']) {
case 'Anfangsbestand':
$type = 'Anfangsbestand';
break;
case 'Einlage':
case 'Entnahme':
$type = 'Geldtransit';
break;
case 'RE_Beleg':
case 'GS_Beleg':
$type = 'Umsatz';
break;
case 'Gutscheineinlösung':
$type = 'MehrzweckgutscheinEinloesung';
break;
case 'Gutscheinverkauf':
$type = 'MehrzweckgutscheinKauf';
break;
case 'Kassendifferenz':
$type = 'DifferenzSollIst';
break;
case 'Trinkgeld':
$type = 'TrinkgeldAN';
break;
default:
$type = 'Umsatz';
break;
}
return new BusinessCase(
$type,
$this->createAmountPerVatIdCollectionFromPosJournalDbState([$posJournal])
);
}
}
@@ -0,0 +1,100 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Factory;
use Aura\SqlQuery\Exception;
use Xentral\Components\Database\Database;
use Xentral\Modules\FiskalyApi\Data\Transaction\TransactionRequest;
class FiskalyTransactionFactory
{
/** @var Database $database */
private $database;
/**
* FiskalyTransactionFactory constructor.
*
* @param Database $db
*/
public function __construct(Database $db)
{
$this->database = $db;
}
/**
* @param int $projectId
*
* @throws Exception
* @return array
*/
public function getClientAndTssInfoFromProjectId(int $projectId): array
{
$posProjectQuery = $this->database->select()
->from('pos_kassierer AS p')
->cols(['f.tss_uuid', 'f.client_uuid', 'f.organization_id'])
->where('p.projekt=:project_id')
->leftJoin('fiskaly_pos_mapping AS f', 'f.pos_id = p.projekt')
->bindValue('project_id', $projectId);
return $this->database->fetchRow($posProjectQuery->getStatement(), $posProjectQuery->getBindValues());
}
/**
* @param string $cashierId
*
* @throws Exception
* @return array
*/
public function getClientAndTssInfoFromCashierId(string $cashierId): array
{
$posProjectQuery = $this->database->select()
->from('pos_kassierer AS p')
->cols(['f.tss_uuid', 'f.client_uuid', 'f.organization_id'])
->where('p.kassenkennung=:kennung')
->innerJoin('fiskaly_pos_mapping AS f', 'f.pos_id = p.projekt')
->bindValue('kennung', $cashierId);
return $this->database->fetchRow($posProjectQuery->getStatement(), $posProjectQuery->getBindValues());
}
/**
* @param string $tssId
*
* @throws Exception
* @return array
*/
public function getTssFromTssId(string $tssId): array
{
$posProjectQuery = $this->database->select()
->from('pos_kassierer AS p')
->cols(['f.tss_uuid', 'f.client_uuid', 'f.organization_id'])
->where('f.tss_uuid=:tss_uuid')
->innerJoin('fiskaly_pos_mapping AS f', 'f.pos_id = p.projekt')
->bindValue('tss_uuid', $tssId);
return $this->database->fetchRow($posProjectQuery->getStatement(), $posProjectQuery->getBindValues());
}
/**
* @param string $cashierId
*
* @throws Exception
* @return TransactionRequest
*/
public function getTransactionRequestFromPosSession(string $cashierId): TransactionRequest
{
$result = $this->getClientAndTssInfoFromCashierId($cashierId);
return (new TransactionRequest('ACTIVE', $result['client_uuid']))->setTssId($result['tss_uuid']);
}
/**
* @param int $projectId
*
* @throws Exception
* @return TransactionRequest
*/
public function getTransactionRequestFromProjectId(int $projectId): TransactionRequest
{
$result = $this->getClientAndTssInfoFromProjectId($projectId);
return (new TransactionRequest('ACTIVE', $result['client_uuid']))->setTssId($result['tss_uuid']);
}
}
@@ -0,0 +1,206 @@
<?php
namespace Xentral\Modules\FiskalyApi\Service;
use Exception;
use FiskalyClient\errors\exceptions\FiskalyClientException;
use FiskalyClient\errors\exceptions\FiskalyHttpException;
use FiskalyClient\errors\exceptions\FiskalyHttpTimeoutException;
use FiskalyClient\FiskalyClient;
use FiskalyClient\responses\SelfTestResponse;
use Xentral\Components\HttpClient\Exception\ClientErrorException;
use Xentral\Modules\FiskalyApi\Data\TechnicalSecuritySystem;
use Xentral\Modules\FiskalyApi\Data\Client;
use Xentral\Modules\FiskalyApi\Exception\InvalidCredentialsException;
use Xentral\Modules\FiskalyApi\Exception\InvalidTransactionException;
use Xentral\Modules\FiskalyApi\Exception\SmaEndpointNotFoundException;
use Xentral\Modules\FiskalyApi\Exception\SmaEndpointNotReachableException;
use Xentral\Modules\FiskalyApi\Transaction\Transaction;
/**
* Class FiskalyApi
*
* @package Xentral\Modules\FiskalyApi\Service
*/
class FiskalyApi
{
/** @var string */
private $apiKey;
/** @var string */
private $apiSecret;
/** @var string */
private $accessToken = null;
/** @var FiskalyClient */
private $fiskalyClient;
const DEFAULT_SMA_ENDPOINT = 'http://localhost:8080/invoke';
/**
* FiskalyApi constructor.
*
* @param string $smaEndpoint
* @param string $apiKey
* @param string $apiSecret
* @param string $endpoint
*
* @throws Exception
*/
public function __construct(string $smaEndpoint, string $apiKey, string $apiSecret, string $endpoint)
{
if(empty($smaEndpoint)) {
$smaEndpoint = self::DEFAULT_SMA_ENDPOINT;
}
try {
$this->fiskalyClient = FiskalyClient::createUsingCredentials(
$smaEndpoint,
$apiKey,
$apiSecret,
$endpoint
);
}
catch (Exception $e) {
if(strpos($e->getMessage(), '404') === 0) {
throw new SmaEndpointNotFoundException($e->getMessage());
}
if($e->getMessage() === 'Undefined variable: http_response_header') {
throw new SmaEndpointNotReachableException($e->getMessage());
}
throw $e;
}
$this->apiKey = $apiKey;
$this->apiSecret = $apiSecret;
}
/**
* @param string $apiKey
* @param string $apiSecret
*
* @throws ClientErrorException
*
* @return string
*/
protected function generateAccessToken(string $apiKey, string $apiSecret): string
{
$result = $this->callApiPost(
'auth',
json_encode(
[
'api_key' => $apiKey,
'api_secret' => $apiSecret,
]
),
false
);
return $result->access_token;
}
/**
* @param $endpoint
* @param null $body
* @param null $query
*
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
* @return mixed
*/
protected function callApiGet($endpoint, $body = null, $query = null)
{
return $this->callApi('GET', $endpoint, $body, $query);
}
/**
* @param $endpoint
* @param null $body
* @param null $query
*
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
* @return mixed
*/
protected function callApiPost($endpoint, $body = null, $query = null)
{
return $this->callApi('POST', $endpoint, $body, $query);
}
/**
* @param $endpoint
* @param null $body
* @param null $query
*
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
* @return mixed
*/
protected function callApiPut($endpoint, $body = null, $query = null)
{
return $this->callApi('PUT', $endpoint, $body, $query);
}
/**
* @param $method
* @param $endpoint
* @param null $body
* @param null $query
*
* @throws FiskalyClientException
* @throws FiskalyHttpTimeoutException
* @return mixed
*/
private function callApi($method, $endpoint, $body = null, $query = null)
{
if (!empty($body)) {
$body = base64_encode($body);
}
try {
$response = $this->fiskalyClient->request(
$method,
$endpoint,
$query,
null,
$body
);
return json_decode(base64_decode($response->getResponse()['body']));
} catch (ClientErrorException | FiskalyHttpException $e) {
$this->handleClientException($e);
}
}
/**
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
* @return SelfTestResponse
*/
public function selfTest(): SelfTestResponse
{
return $this->fiskalyClient->selfTest();
}
/**
* @param Exception $e
*
* @throws Exception
* @return void
*/
private function handleClientException(Exception $e): void
{
if ($e->getStatus() === 401 || $e->getCode() == 401) {
throw new InvalidCredentialsException('Falsche Zugangsdaten');
}
if ($e->getStatus() === 403 || $e->getCode() == 403) {
throw new InvalidCredentialsException('Nutzer nicht berechtigt');
}
throw $e;
}
}
@@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Service;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\CashPointClosingApiResponse;
use Xentral\Modules\FiskalyApi\Data\Transaction\TransactionReponse;
interface FiskalyCashPointClosingDBInterface
{
public function create(CashPointClosingApiResponse $cashPointClosingApiResponse): int;
public function update(CashPointClosingApiResponse $cashPointClosingApiResponse): void;
public function get(int $id): ?CashPointClosingApiResponse;
public function getIdByClosingId(string $closingId): ?int;
public function getByClosingId(string $closingId): ?CashPointClosingApiResponse;
public function createTransactionMapping(
CashPointClosingApiResponse $cashPointClosing,
TransactionReponse $transaction
): int;
public function getClosingIdsByState(string $clientId, string $state): array;
}
@@ -0,0 +1,197 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Service;
use DateTime;
use DateTimeZone;
use Exception;
use Xentral\Components\Database\Database;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\CashPointClosingApiResponse;
use Xentral\Modules\FiskalyApi\Data\Transaction\TransactionReponse;
use Xentral\Modules\FiskalyApi\Exception\InvalidArgumentException;
final class FiskalyCashPointClosingDBService implements FiskalyCashPointClosingDBInterface
{
/** @var Database $db */
private $db;
/**
* CashPointClosingDBService constructor.
*
* @param Database $db
*/
public function __construct(Database $db)
{
$this->db = $db;
}
/**
* @param CashPointClosingApiResponse $cashPointClosingApiResponse
*
* @throws Exception
* @return int
*/
public function create(CashPointClosingApiResponse $cashPointClosingApiResponse): int
{
$this->db->perform(
'INSERT INTO `fiskaly_cash_point_closing`
(`closing_id`, `client_id`, `cash_point_closing_export_id`, `state`,
`export_creation_date`, `time_start`, `time_end`, `trx_start`, `trx_end`)
VALUES (:closing_id, :client_id, :cash_point_closing_export_id, :state,
:export_creation_date, :time_start, :time_end, :trx_start, :trx_end )',
[
'closing_id' => $cashPointClosingApiResponse->getClosingId(),
'client_id' => $cashPointClosingApiResponse->getClientId(),
'cash_point_closing_export_id' => $cashPointClosingApiResponse->getCashPointClosingExportId(),
'state' => $cashPointClosingApiResponse->getState(),
'export_creation_date' => (new Datetime('now', new DateTimeZone('UTC')))->setTimeStamp(
$cashPointClosingApiResponse->getExportCreationDate()
)->format('Y-m-d H:i:s'),
'time_start' => null,
'time_end' => null,
'trx_start' => $cashPointClosingApiResponse->getFirstTransactionExportId(),
'trx_end' => $cashPointClosingApiResponse->getLastTransactionExportId(),
]
);
return $this->db->lastInsertId();
}
/**
* @param string $closingId
*
* @return CashPointClosingApiResponse|null
*/
public function getByClosingId(string $closingId): ?CashPointClosingApiResponse
{
$id = $this->getIdByClosingId($closingId);
if ($id === null) {
return null;
}
return $this->get($id);
}
/**
* @param int $id
*
* @return CashPointClosingApiResponse|null
*/
public function get(int $id): ?CashPointClosingApiResponse
{
$row = $this->db->fetchRow(
'SELECT * FROM `fiskaly_cash_point_closing` WHERE `id` = :id',
['id' => $id]
);
if (empty($row)) {
return null;
}
return CashPointClosingApiResponse::fromDbState($row);
}
/**
* @param string $closingId
*
* @return int|null
*/
public function getIdByClosingId(string $closingId): ?int
{
$id = $this->db->fetchValue(
'SELECT `id` FROM `fiskaly_cash_point_closing` WHERE `closing_id` = :closing_id',
['closing_id' => $closingId]
);
if ($id === false) {
return null;
}
return (int)$id;
}
/**
* @param CashPointClosingApiResponse $cashPointClosing
* @param TransactionReponse $transaction
*
* @return int
*/
public function createTransactionMapping(
CashPointClosingApiResponse $cashPointClosing,
TransactionReponse $transaction
): int {
$cashPointClosingId = $this->getIdByClosingId($cashPointClosing->getClosingId());
if ($cashPointClosingId === null) {
throw new InvalidArgumentException("cashPointClosingId {$cashPointClosing->getClosingId()} not found");
}
$transactionId = $transaction->getId();
$transactionDbId = $this->getTransactionDbId($transactionId);
if ($transactionDbId === null) {
throw new InvalidArgumentException("Transaction {$transactionId} not found");
}
$this->db->perform(
'INSERT INTO `fiskaly_cash_point_closing_transaction`
(`fiskaly_cash_point_closing_id`, `fiskaly_transaction_id`)
VALUES (:cash_point_closing_id, :transaction_id)',
[
'cash_point_closing_id' => $cashPointClosingId,
'transaction_id' => $transactionDbId,
]
);
return $this->db->lastInsertId();
}
/**
* @param CashPointClosingApiResponse $cashPointClosingApiResponse
*/
public function update(CashPointClosingApiResponse $cashPointClosingApiResponse): void
{
$cashPointClosingId = $this->getIdByClosingId($cashPointClosingApiResponse->getClosingId());
if ($cashPointClosingId === null) {
throw new InvalidArgumentException(
"cashPointClosingId {$cashPointClosingApiResponse->getClosingId()} not found"
);
}
$this->db->perform(
'UPDATE `fiskaly_cash_point_closing` SET `state` = :state WHERE `id` = :id',
['state' => $cashPointClosingApiResponse->getState(), 'id' => $cashPointClosingId]
);
}
/**
* @param string $clientId
* @param string $state
*
* @return array
*/
public function getClosingIdsByState(string $clientId, string $state): array
{
return $this->db->fetchCol(
'SELECT `closing_id` FROM `fiskaly_cash_point_closing` WHERE `client_id` = :client_id AND `state` = :state',
[
'client_id' => $clientId,
'state' => $state,
]
);
}
/**
* @param string $transactionId
*
* @return int|null
*/
private function getTransactionDbId(string $transactionId): ?int
{
$result = $this->db->fetchValue(
'SELECT `id` FROM `fiskaly_transaction` WHERE `trx_id` = :trx_id',
['trx_id' => $transactionId]
);
if ($result === false) {
return null;
}
return (int)$result;
}
}
@@ -0,0 +1,181 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Service;
use Exception;
use FiskalyClient\errors\exceptions\FiskalyClientException;
use FiskalyClient\errors\exceptions\FiskalyHttpException;
use FiskalyClient\errors\exceptions\FiskalyHttpTimeoutException;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\CashPointClosing;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\CashPointClosingApiResponse;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\CashPointClosingApiResponseCollection;
use Xentral\Modules\FiskalyApi\Data\CashRegister;
use Xentral\Modules\FiskalyApi\Data\VatDefinition;
class FiskalyDSFinVKApi extends FiskalyApi
{
/** @var string */
private const ENDPOINT_BASE = 'https://dsfinvk.fiskaly.com/api/v0/';
/**
* FiskalyDSFinVKApi constructor.
*
* @param string $smaEndpoint
* @param string $apiKey
* @param string $apiSecret
*
* @throws Exception
*/
public function __construct(string $smaEndpoint, string $apiKey, string $apiSecret)
{
parent::__construct($smaEndpoint, $apiKey, $apiSecret, self::ENDPOINT_BASE);
}
/**
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
* @return array
*/
public function getVatDefinitions(): array
{
$result = $this->callApiGet('vat_definitions');
return array_map([VatDefinition::class, 'fromApiResult'], $result->data);
}
/**
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
* @return array
*/
public function getCashRegisters(): array
{
$result = $this->callApiGet('cash_registers');
return array_map([CashRegister::class,'fromApiResult'], $result->data);
}
/**
* @param string $clientId
*
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
* @return CashRegister|null
*/
public function getCashRegister(string $clientId): ?CashRegister
{
$result = $this->callApiGet("cash_registers/{$clientId}");
if(empty($result)) {
return null;
}
return CashRegister::fromApiResult($result);
}
/**
* @param string|null $purchaserAgencyId
*
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
*
* @return CashRegister[]
*/
public function getPurchaserAgencies(?string $purchaserAgencyId = null): array
{
if($purchaserAgencyId === null) {
$result = $this->callApiGet('purchaser_agencies');
return array_map([CashRegister::class, 'fromApiResult'] , $result->data);
}
$result = $this->callApiGet("purchaser_agencies/{$purchaserAgencyId}");
return [
CashRegister::fromApiResult($result)
];
}
/**
* @param CashRegister $cashRegister
*
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
* @return CashRegister
*/
public function putRegister(CashRegister $cashRegister): CashRegister
{
$clientId = $cashRegister->getClientId();
$body = $cashRegister->toArray();
$result = $this->callApiPut("cash_registers/{$clientId}", json_encode($body));
return CashRegister::fromApiResult($result);
}
/**
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
*
* @return mixed
*/
public function getCashPointClosings(): CashPointClosingApiResponseCollection
{
$result = $this->callApiGet('cash_point_closings');
return CashPointClosingApiResponseCollection::fromApiResult($result->data);
}
/**
* @param string $closingId
*
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
* @return CashPointClosingApiResponse
*/
public function getCashPointClosing(string $closingId): CashPointClosingApiResponse
{
$result = $this->callApiGet("cash_point_closings/{$closingId}");
return CashPointClosingApiResponse::fromApiResult($result);
}
/**
* @param string $closingId
*
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
* @return mixed
*/
public function getCashPointClosingDetails(string $closingId) {
$result = $this->callApiGet("cash_point_closings/{$closingId}/details");
return $result;
}
/**
* @param CashPointClosing $cashPointClosing
*
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
*
* @return CashPointClosingApiResponse
*/
public function sendCashPointClosings(CashPointClosing $cashPointClosing): CashPointClosingApiResponse
{
$result = $this->callApiPut(
"cash_point_closings/{$cashPointClosing->getClosingId()}", json_encode($cashPointClosing->toApiResult())
);
return CashPointClosingApiResponse::fromApiResult($result);
}
}
@@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Service;
use Exception;
use FiskalyClient\errors\exceptions\FiskalyClientException;
use FiskalyClient\errors\exceptions\FiskalyHttpException;
use FiskalyClient\errors\exceptions\FiskalyHttpTimeoutException;
class FiskalyEReceiptApi extends FiskalyApi
{
/** @var string */
private const ENDPOINT_BASE = 'https://ereceipt.fiskaly.dev/api/v0/';
/**
* FiskalyEReceiptApi constructor.
*
* @param string $smaEndpoint
* @param string $apiKey
* @param string $apiSecret
*
* @throws Exception
*/
public function __construct(string $smaEndpoint, string $apiKey, string $apiSecret)
{
parent::__construct($smaEndpoint, $apiKey, $apiSecret, self::ENDPOINT_BASE);
}
/**
* @param int $limit
* @param int $offset
* @param string|null $tssId
*
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
* @return mixed
*/
public function listEReceipts(int $limit = 100, int $offset = 0, ?string $tssId = null)
{
if($tssId === null) {
$result = $this->callApiGet("issuer/e_receipts");
//$result = $this->callApiGet("issuer/e_receipts?limit={$limit}&offset={$offset}");
}
else {
$result = $this->callApiGet("issuer/e_receipts?limit={$limit}&offset={$offset}&tss_id={$tssId}");
}
return $result;
}
}
@@ -0,0 +1,469 @@
<?php
namespace Xentral\Modules\FiskalyApi\Service;
use Exception;
use FiskalyClient\errors\exceptions\FiskalyClientException;
use FiskalyClient\errors\exceptions\FiskalyHttpException;
use FiskalyClient\errors\exceptions\FiskalyHttpTimeoutException;
use Xentral\Modules\FiskalyApi\Data\Client;
use Xentral\Modules\FiskalyApi\Data\Export;
use Xentral\Modules\FiskalyApi\Data\TechnicalSecuritySystem;
use Xentral\Modules\FiskalyApi\Data\Transaction\AmountsPerPaymentTypeCollection;
use Xentral\Modules\FiskalyApi\Data\Transaction\AmountsPerVatTypeCollection;
use Xentral\Modules\FiskalyApi\Data\Transaction\SchemaReceipt;
use Xentral\Modules\FiskalyApi\Data\Transaction\SchemaStandardV1;
use Xentral\Modules\FiskalyApi\Data\Transaction\TransactionReponse;
use Xentral\Modules\FiskalyApi\Data\Transaction\TransactionReponseCollection;
use Xentral\Modules\FiskalyApi\Data\Transaction\TransactionRequest;
use Xentral\Modules\FiskalyApi\Data\Transaction\TransactionSchema;
use Xentral\Modules\FiskalyApi\Exception\InvalidArgumentException;
use Xentral\Modules\FiskalyApi\Exception\InvalidTransactionException;
use Xentral\Modules\FiskalyApi\Transaction\Transaction;
use Xentral\Modules\FiskalyApi\UuidTool;
class FiskalyKassenSichVApi extends FiskalyApi
{
/** @var string */
private const ENDPOINT_BASE = 'https://kassensichv.io/api/v1/';
/**
* FiskalyKassenSichVApi constructor.
*
* @param string $smaEndpoint
* @param string $apiKey
* @param string $apiSecret
*
* @throws Exception
*/
public function __construct(string $smaEndpoint, string $apiKey, string $apiSecret)
{
parent::__construct($smaEndpoint, $apiKey, $apiSecret, self::ENDPOINT_BASE);
}
/**
* @return TechnicalSecuritySystem[]
*/
public function getTechnicalSecuritySystemList(): array
{
$result = $this->callApiGet('tss');
return array_map([TechnicalSecuritySystem::class, 'fromApiResult'], $result->data);
}
/**
* @param string $tssUuid
*
* @return TechnicalSecuritySystem
*/
public function getTechnicalSecuritySystemByUuid(string $tssUuid): TechnicalSecuritySystem
{
$result = $this->callApiGet("tss/{$tssUuid}");
return TechnicalSecuritySystem::fromApiResult($result);
}
/**
* @param string $tssUuid
* @param string $state
* @param string|null $description
*
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
* @return TechnicalSecuritySystem
*/
public function changeSecuritySystem(
string $tssUuid,
string $state = 'INITIALIZED',
?string $description = null
): TechnicalSecuritySystem {
if (!in_array($state, ['UNINITIALIZED', 'INITIALIZED', 'DISABLED'])) {
throw new InvalidArgumentException("unknown state '{$state}'");
}
$body = ['state' => $state];
if ($description !== null) {
$body['description'] = $description;
}
$result = $this->callApiPut("tss/{$tssUuid}", json_encode($body));
return TechnicalSecuritySystem::fromApiResult($result);
}
/**
* @param null|string $tssUuid
*
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
*
* @return Client[]
*/
public function getClients($tssUuid = null): array
{
if (empty($tssUuid)) {
$result = $this->callApiGet("client");
} else {
$result = $this->callApiGet("tss/{$tssUuid}/client");
}
return array_map([Client::class, 'fromApiResult'], $result->data);
}
/**
* @param string $tssUuid
* @param string|null $clientId
* @param string|null $exportId
*
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
*/
public function triggerExport(string $tssUuid, ?string $clientId = null, ?string $exportId = null): Export
{
if ($exportId === null) {
$exportId = UuidTool::generateUuid();
}
if ($clientId !== null) {
Export::fromApiResult(
$this->callApiPut("tss/{$tssUuid}/export/{$exportId}", '{}', ['client_id' => $clientId])
);
}
return Export::fromApiResult($this->callApiPut("tss/{$tssUuid}/export/{$exportId}", '{}'));
}
/**
* @param string $tssUuid
* @param string $serialNumber
* @param string $clientId
*
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
* @return Client
*/
public function createClient(string $tssUuid, string $serialNumber, string $clientId): Client
{
$result = $this->callApiPut(
"tss/{$tssUuid}/client/{$clientId}",
json_encode(['serial_number' => $serialNumber])
);
return Client::fromApiResult($result);
}
/**
* @param $clientUuid
*
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
*
* @return Client
*/
public function getClientByUuid($tssUuid, $clientUuid): Client
{
$result = $this->callApiGet("tss/{$tssUuid}/client/{$clientUuid}");
return Client::fromApiResult($result);
}
/**
* @param string|null $tssUuid
*
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
* @return TransactionReponseCollection
*/
public function getTransactions(
?string $tssUuid = null,
int $offset = 0,
int $limit = 100
): TransactionReponseCollection {
if ($tssUuid === null) {
$result = $this->callApiGet("tx", null, ['offset' => $offset, 'limit' => $limit,]);
} else {
$result = $this->callApiGet("tss/{$tssUuid}/tx", null, ['offset' => $offset, 'limit' => $limit,]);
}
return TransactionReponseCollection::fromApiResult($result->data);
}
/**
* @param string $tssUuid
* @param string $txId
*
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
* @return TransactionReponse
*/
public function getTransaction(string $tssUuid, string $txId): TransactionReponse
{
$result = $this->callApiGet("tss/{$tssUuid}/tx/{$txId}");
return TransactionReponse::fromApiResult($result);
}
/**
* @param Transaction $transaction
* @param TechnicalSecuritySystem $technicalSecuritySystem
*
* @return Transaction
*/
public function uploadTransaction(
Transaction $transaction,
TechnicalSecuritySystem $technicalSecuritySystem
): Transaction {
$transaction = $this->startTransaction($transaction, $technicalSecuritySystem);
return $this->finishTransactionOld($transaction, $technicalSecuritySystem);
}
/**
* @param Transaction $transaction
* @param TechnicalSecuritySystem $tss
*
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
* @return Transaction
*/
public function startTransaction(Transaction $transaction, TechnicalSecuritySystem $tss)
{
$tssId = $tss->getUuid();
$body = json_encode(
[
'state' => 'ACTIVE',
'client_id' => $transaction->getClientUuid(),
]
);
$result = $this->callApiPut("tss/{$tssId}/tx/" . $transaction->getUuid(), $body);
$transaction->setLastRevision($result->revision);
return $transaction;
}
/**
* @param TransactionRequest $transactionRequest
*
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
* @return TransactionReponse
*/
public function createTransaction(TransactionRequest $transactionRequest): TransactionReponse
{
return TransactionReponse::fromApiResult(
$this->callApiPut(
"tss/{$transactionRequest->getTssId()}/tx/{$transactionRequest->getId()}",
json_encode($transactionRequest->toApiResult())
)
);
}
/**
* @param TransactionRequest $transactionRequest
*
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
* @return TransactionReponse
*/
public function updateTransaction(TransactionRequest $transactionRequest): TransactionReponse
{
return TransactionReponse::fromApiResult(
$this->callApiPut(
"tss/{$transactionRequest->getTssId()}/tx/{$transactionRequest->getId()}",
json_encode($transactionRequest->toApiResult()),
['last_revision' => $transactionRequest->getRevision()]
)
);
}
/**
* @param TransactionReponse $reponse
* @param string $receiptType
* @param AmountsPerVatTypeCollection $amountsPerVatTypeCollection
* @param AmountsPerPaymentTypeCollection $amountsPerPaymentTypeCollection
*
* @return TransactionRequest
*/
public function getFinishTransactionRequest(
TransactionReponse $reponse,
string $receiptType,
AmountsPerVatTypeCollection $amountsPerVatTypeCollection,
AmountsPerPaymentTypeCollection $amountsPerPaymentTypeCollection
): TransactionRequest {
return (new TransactionRequest(
'FINISHED',
$reponse->getClientId(),
new TransactionSchema(
new SchemaStandardV1(
new SchemaReceipt(
$receiptType,
$amountsPerVatTypeCollection,
$amountsPerPaymentTypeCollection
)
)
), $reponse->getMetaData()
)
)->setTssId($reponse->getTssId())
->setId($reponse->getId())
->setRevision($reponse->getLatestRevision());
}
/**
* @param TransactionRequest $request
*
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
* @throws Exception
* @return TransactionReponse
*/
public function finishTransaction(TransactionRequest $request): TransactionReponse
{
$result = $this->callApiPut(
"tss/{$request->getTssId()}/tx/{$request->getId()}",
json_encode($request->toArray()),
['last_revision' => $request->getRevision()]
);
return TransactionReponse::fromApiResult($result);
}
/**
* @param Transaction $transaction
* @param TechnicalSecuritySystem $tss
*
* @return Transaction
*/
public function finishTransactionOld(Transaction $transaction, TechnicalSecuritySystem $tss)
{
$tssId = $tss->getUuid();
$vatTypeAmounts = [];
$paymentTypeAmounts = [];
foreach ($transaction->getAmountsPerVatRate() as $vatTypeAmount) {
$vatTypeAmounts[] = [
'vat_rate' => $vatTypeAmount->getVatType(),
'amount' => (string)number_format($vatTypeAmount->getAmount(), 2, '.', ''),
];
}
foreach ($transaction->getAmountsPerPaymentType() as $paymentTypeAmount) {
$paymentTypeAmounts[] = [
'payment_type' => $paymentTypeAmount->getPaymentType(),
'amount' => (string)number_format($paymentTypeAmount->getAmount(), 2, '.', ''),
'currency_code' => 'EUR',
];
}
$hasOrderLineItems = count($transaction->getOrderLineItems()) > 0;
$body =
[
'state' => 'FINISHED',
'client_id' => $transaction->getClientUuid(),
'schema' => [
'standard_v1' => [],
],
];
$body['schema']['standard_v1'] = [
'receipt' => [
'receipt_type' => 'RECEIPT',
'amounts_per_vat_rate' => $vatTypeAmounts,
'amounts_per_payment_type' => $paymentTypeAmounts,
],
];
if ($hasOrderLineItems) {
foreach ($transaction->getOrderLineItems() as $orderLineItem) {
$body['schema']['standard_v1']['receipt']['line_items'][] = [
'quantity' => $orderLineItem->getQuantity(),
'text' => $orderLineItem->getText(),
'price_per_unit' => $orderLineItem->getPricePerUnit(),
];
}
}
if (!$transaction->isLastRevisionSet()) {
throw new InvalidTransactionException("Transaction last_revision not set");
}
$query = ['last_revision' => $transaction->getLastRevision()];
$uuid = $transaction->getUuid();
$result = $this->callApiPut("tss/{$tssId}/tx/{$uuid}", json_encode($body), $query);
$transaction->setLastRevision($result->revision);
$transaction->setTransactionNumber($result->number);
$transaction->setStartTime($result->time_start);
$transaction->setEndTime($result->time_end);
$transaction->setClientSerialNumber($result->client_serial_number);
$transaction->setCertificateSerial($result->certificate_serial);
$transaction->setSignature($result->signature->value);
$transaction->setSignatureAlgorithm($result->signature->algorithm);
$transaction->setSignatureCounter($result->signature->counter);
$transaction->setPublicKey($result->signature->public_key);
return $transaction;
}
/**
* @param string|null $tssId
* @param bool $orderIsDesc
* @param int $offset
* @param int $limit
* @param string $orderBy
* @param array $states
*
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
* @return array
*/
public function listExports(
?string $tssId = null,
bool $orderIsDesc = false,
int $offset = 0,
int $limit = 100,
string $orderBy = 'time_request',
array $states = []
): array {
$query = null;
if ($orderIsDesc) {
$query['order'] = 'desc';
}
if (!empty($states)) {
$query['states'] = '';
foreach ($states as $keyState => $state) {
$query['states'] .= ($keyState > 0 ? '&' : '') . "states%5B{$keyState}%5D={$state}";
}
}
$query['order_by'] = $orderBy;
$query['limit'] = $limit;
$query['offset'] = $offset;
$endPoint = 'export';
if ($tssId !== null) {
$endPoint = "tss/{$tssId}/export";
}
$result = $this->callApiGet($endPoint, null, $query);
return array_map([Export::class, 'fromApiResult'], $result->data);
}
}
@@ -0,0 +1,60 @@
<?php
namespace Xentral\Modules\FiskalyApi\Service;
use FiskalyClient\errors\exceptions\FiskalyClientException;
use FiskalyClient\errors\exceptions\FiskalyHttpException;
use FiskalyClient\errors\exceptions\FiskalyHttpTimeoutException;
use Xentral\Modules\FiskalyApi\Data\BillingAddress;
use Xentral\Modules\FiskalyApi\Data\Organisation;
use Xentral\Modules\FiskalyApi\Data\User;
class FiskalyManagementApi extends FiskalyApi
{
private const ENDPOINT_BASE = 'https://dashboard.fiskaly.com/api/v0/';
public function __construct(string $smaEndpoint, string $apiKey, string $apiSecret)
{
parent::__construct($smaEndpoint, $apiKey, $apiSecret, self::ENDPOINT_BASE);
}
/**
* @param string|null $uuId
*
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
*
* @return Organisation[]
*/
public function getOrganisations(?string $uuId = null): array
{
if ($uuId === null) {
$organisations = $this->callApiGet('organizations');
return array_map([Organisation::class, 'fromApiResult'], $organisations->data);
}
$organisation = $this->callApiGet("organizations/{$uuId}");
return [Organisation::fromApiResult($organisation)];
}
public function getUsers(string $organisationUuId): array
{
$result = $this->callApiGet("/organizations/{$organisationUuId}/users");
return array_map([User::class, 'fromApiResult'], $result->data);
}
public function getBillingAddresses(): array
{
$result = $this->callApiGet('billing-addresses');
return array_map([BillingAddress::class, 'fromApiResult'], $result->data);
}
}
@@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Service;
use Xentral\Modules\FiskalyApi\Data\Transaction\TransactionReponseCollection;
interface FiskalyPosClosingInterface
{
public function getNextCashPointClosingExportId(string $clientId): int;
public function getOpenTransactions(string $clientId): TransactionReponseCollection;
}
@@ -0,0 +1,324 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Service;
use erpAPI;
use Exception;
use DateTime;
use DateTimeZone;
use Xentral\Components\Database\Database;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\BusinessCaseCollection;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\CashPointClosing;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\CashPointClosingCashStatement;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\CashPointClosingHead;
use Xentral\Modules\FiskalyApi\Data\CashPointClosing\CashPointClosingPayment;
use Xentral\Modules\FiskalyApi\Data\Transaction\TransactionReponse;
use Xentral\Modules\FiskalyApi\Data\Transaction\TransactionReponseCollection;
use Xentral\Modules\FiskalyApi\Factory\FiskalyCashPointClosingFactory;
use Xentral\Modules\FiskalyApi\Wrapper\TaxSettingWrapper;
class FiskalyPosClosingService implements FiskalyPosClosingInterface
{
/** @var Database $db */
private $db;
/** @var FiskalyCashPointClosingFactory $cashPointFactory */
private $cashPointFactory;
/** @var TaxSettingWrapper $taxSettingWrapper */
private $taxSettingWrapper;
/**
* FiskalyPosClosingService constructor.
*
* @param Database $db
* @param FiskalyCashPointClosingFactory $cashPointFactory
* @param TaxSettingWrapper $taxSettingWrapper
*/
public function __construct(
Database $db,
FiskalyCashPointClosingFactory $cashPointFactory,
TaxSettingWrapper $taxSettingWrapper
) {
$this->db = $db;
$this->cashPointFactory = $cashPointFactory;
$this->taxSettingWrapper = $taxSettingWrapper;
}
public function getNextCashPointClosingExportId(string $clientId): int
{
return 1 + (int)$this->db->fetchValue(
'SELECT MAX(`cash_point_closing_export_id`)
FROM `fiskaly_cash_point_closing`
WHERE `client_id` = :client_id',
['client_id' => $clientId]
);
}
/**
* @param string $clientId
* @param string|null $date
*
* @throws Exception
* @return TransactionReponseCollection
*/
public function getOpenTransactions(string $clientId, ?string $date = null): TransactionReponseCollection
{
$transactions = $this->db->fetchCol(
'SELECT ft.json_response
FROM `fiskaly_transaction` AS `ft`
INNER JOIN `fiskaly_tranaction_mapping` AS `ftm` ON ft.id = ftm.fiskaly_transaction_id
LEFT JOIN `fiskaly_cash_point_closing_transaction` AS `fcpct` ON ft.id = fcpct.fiskaly_transaction_id
WHERE ft.client_id = :client_id AND fcpct.id IS NULL
GROUP BY ft.id',
['client_id' => $clientId]
);
$instance = new TransactionReponseCollection();
foreach ($transactions as $transactionJson) {
$instance->addTransactionResponse(TransactionReponse::fromApiResult(json_decode($transactionJson, false)));
}
if ($date !== null) {
return $instance->filterDate($date);
}
return $instance;
}
/**
* @param string $clientId
*
* @throws Exception
* @return array
*/
public function getOpenPointClosingDates(string $clientId): array
{
$openTransactions = $this->getOpenTransactions($clientId);
return $openTransactions->getTransactionDates();
}
/**
* @param int $projectId
* @param string $date
*
* @return bool
*/
public function isPosCountingExistsForDate(int $projectId, string $date): bool
{
return $this->db->fetchValue(
'SELECT `id`
FROM `pos_zaehlungen`
WHERE `projekt` = :project_id AND DATE(`zeitstempel`) = :date
LIMIT 1',
[
'project_id' => $projectId,
'date' => $date,
]
) !== false;
}
/**
* @param string $clientId
* @param string|null $date
*
* @throws Exception
* @return CashPointClosing
*/
public function getNextCashPointClosing(string $clientId, ?string $date = null): CashPointClosing
{
if ($date === null) {
$openTransactions = $this->getOpenTransactions(
$clientId,
(new DateTime('now', new DateTimeZone('UTC')))->format(
'Y-m-d'
)
);
} else {
$openTransactions = $this->getOpenTransactions($clientId, $date);
}
$trxs = $openTransactions->getTrxIds();
$firstTransaction = $openTransactions->getBoundedTransactionWithClientId($clientId, true);
$lastLastTransaction = $openTransactions->getBoundedTransactionWithClientId($clientId, false);
$this->cashPointFactory->setTaxNormal($this->getNormalTaxForClientId($clientId));
$paymentCollection = $this->cashPointFactory->getPaymentTypesFromTransactionCollection($openTransactions);
$sum = $paymentCollection->getSum();
$cashCollection = $paymentCollection->filterByType('CASH');
$cashSum = $cashCollection->getSum();
$posJournalEntries = $this->getPosJounralEntriesByTrxs($trxs);
$posSessions = $this->getPosSessionsByTrxs($trxs);
$businessCases = new BusinessCaseCollection();
foreach ($posJournalEntries as $posJournalArray) {
$businessCases = $businessCases->combine(
$this->cashPointFactory->createBusinessCaseCollection($posJournalArray)
);
}
$payment = new CashPointClosingPayment(
$sum,
$cashSum,
$this->cashPointFactory->getCashAmountByCurrencyCollection($paymentCollection),
$this->cashPointFactory->getCashPointClosingPaymentTypeCollectionByPosJournalCollection($posJournalEntries)
);
$instance = new CashPointClosing(
$clientId, $this->getNextCashPointClosingExportId($clientId),
new CashPointClosingHead(
new DateTime('now', new DateTimeZone('UTC')),
$firstTransaction->getId(),
$lastLastTransaction->getId(),
$date === null ? null : (new DateTime($date, new DateTimeZone('UTC')))
),
new CashPointClosingCashStatement($businessCases, $payment),
$this->cashPointFactory->getCashPointClosingTransactionCollection(
$openTransactions,
$posJournalEntries,
$posSessions
)
);
return $instance;
}
/**
* @param array $trxs
*
* @return array
*/
private function getPosJounralEntriesByTrxs(array $trxs): array
{
return $this->db->fetchGroup(
"SELECT ft.trx_id, pj.*
FROM `fiskaly_transaction` AS `ft`
INNER JOIN `fiskaly_tranaction_mapping` AS `ftm` ON ft.id = ftm.fiskaly_transaction_id
INNER JOIN `pos_journal` AS `pj` ON ftm.document = 'pos_journal' AND ftm.document_id = pj.id
WHERE ft.trx_id IN (:trx_ids)",
[
'trx_ids' => $trxs,
]
);
}
/**
* @param array $trxs
*
* @return array
*/
private function getPosSessionsByTrxs(array $trxs): array
{
$posSessions = $this->db->fetchPairs(
"SELECT ft.trx_id, ps.data
FROM `fiskaly_transaction` AS `ft`
INNER JOIN `fiskaly_tranaction_mapping` AS `ftm` ON ft.id = ftm.fiskaly_transaction_id
INNER JOIN `pos_sessions` AS `ps` ON ftm.document = 'pos_session' AND ftm.document_id = ps.id
WHERE ft.trx_id IN (:trx_ids)",
[
'trx_ids' => $trxs,
]
);
$posSessions = array_map(
static function ($posSession) {
return unserialize($posSession, ['allowed_classes' => false]);
},
$posSessions
);
$addressIds = [];
$cashierIds = [];
foreach ($posSessions as $posSession) {
$cashierId = $posSession['kassiererId'] ?? null;
$addressId = $posSession['addrid'] ?? null;
if ($addressId !== null && !in_array($addressId, $addressIds, true)) {
$addressIds[] = $addressId;
}
if ($cashierId !== null && !in_array($cashierId, $cashierIds, true)) {
$cashierIds[] = $cashierId;
}
}
$cashierAddresses = $this->getAddressesFromCashierIds($cashierIds);
$addesses = $this->getAddressesFromIds($addressIds);
foreach ($posSessions as $positionKey => $posSession) {
$posSessions[$positionKey]['address'] = !empty($addesses[$posSession['addrid'] ?? '']) ? reset(
$addesses[$posSession['addrid']]
) : null;
}
foreach ($posSessions as $positionKey => $posSession) {
if (!empty($posSessions[$positionKey]['address']) || empty($posSession['kassiererId'])) {
continue;
}
if (empty($cashierAddresses[$posSession['kassiererId']])) {
continue;
}
$posSessions[$positionKey]['address'] = reset($cashierAddresses[$posSession['kassiererId']]);
$posSessions[$positionKey]['addrid'] = $posSessions[$positionKey]['address']['id'];
$posSessions[$positionKey]['addr']['name'] = $posSessions[$positionKey]['address']['name'];
}
return $posSessions;
}
/**
* @param array $addressIds
*
* @return array
*/
private function getAddressesFromIds(array $addressIds): array
{
if (empty($addressIds)) {
return [];
}
return $this->db->fetchGroup(
"SELECT adr.id, IF(l.iso3 IS NULL OR l.iso3 = '', IF(l.iso = 'AT', 'AUT', 'DEU'), l.iso3) AS `land_iso3`,
adr.*
FROM `adresse` AS `adr`
LEFT JOIN `laender` AS `l` ON adr.land = l.iso
WHERE adr.id IN (:address_ids)",
['address_ids' => $addressIds]
);
}
/**
* @param array $cashierIds
*
* @return array
*/
private function getAddressesFromCashierIds(array $cashierIds): array
{
if (empty($cashierIds)) {
return [];
}
return $this->db->fetchGroup(
"SELECT pk.kassenkennung,
IF(l.iso3 IS NULL OR l.iso3 = '', IF(l.iso = 'AT', 'AUT', 'DEU'), l.iso3) AS `land_iso3`, adr.*
FROM `adresse` AS `adr`
INNER JOIN `pos_kassierer` AS `pk` ON adr.id = pk.adresse
LEFT JOIN `laender` AS `l` ON adr.land = l.iso
WHERE pk.kassenkennung IN (:cashier_ids)",
['cashier_ids' => $cashierIds]
);
}
/**
* @param string $clientId
*
* @return float
*/
private function getNormalTaxForClientId(string $clientId): float
{
$projectId = $this->db->fetchValue(
'SELECT pr.id
FROM `fiskaly_pos_mapping` AS `fpm`
INNER JOIN `projekt` AS `pr`
WHERE fpm.client_uuid = :client_id
LIMIT 1',
['client_id' => $clientId]
);
return $this->taxSettingWrapper->getStandardTaxRate($projectId);
}
}
@@ -0,0 +1,373 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Service;
use Aura\SqlQuery\Exception;
use Xentral\Components\Database\Database;
use Xentral\Modules\FiskalyApi\Data\Organisation;
final class FiskalyPosMappingService
{
/** @var Database $db */
private $db;
/**
* FiskalyPosMappingService constructor.
*
* @param Database $db
*/
public function __construct(Database $db)
{
$this->db = $db;
}
/**
* @return array
*/
public function listProjects(): array
{
return $this->db->fetchAll(
$this->db->select()
->from('projekt')
->where('geloescht = 0 AND kasse_konto > 0')
->cols(['id', 'name', 'abkuerzung'])
->getStatement()
);
}
/**
* @return array
*/
public function list(): array
{
$query = $this->db->select()
->from('fiskaly_pos_mapping AS f')
->cols(['f.id', 'f.tss_uuid', 'f.client_uuid', 'f.pos_id']);
return $this->db->fetchAll($query->getStatement(), $query->getBindValues());
}
/**
* @param string $cashierId
*
* @throws Exception
* @return array
*/
public function getByCashierId(string $cashierId): array
{
$posProjectQuery = $this->db->select()
->from('pos_kassierer AS p')
->cols(['f.tss_uuid', 'f.client_uuid', 'f.pos_id'])
->where('p.kassenkennung=:kennung')
->leftJoin('fiskaly_pos_mapping AS f', 'f.pos_id = p.projekt')
->bindValue('kennung', $cashierId);
return $this->db->fetchRow($posProjectQuery->getStatement(), $posProjectQuery->getBindValues());
}
/**
* @param int $cashId
*
* @throws Exception
* @return array|null
*/
public function getByCashId(int $cashId): ?array
{
$query = $this->db->select()
->from('fiskaly_pos_mapping AS f')
->innerJoin('projekt AS p', 'f.pos_id = p.id')
->where('p.kasse_konto=:kasse')
->bindValue('kasse', $cashId)
->cols(['f.tss_uuid', 'f.organization_id', 'f.client_uuid', 'p.id']);
return $this->db->fetchRow($query->getStatement(), $query->getBindValues());
}
/**
* @param int $fiskalyPosMappingId
*/
public function delete(int $fiskalyPosMappingId): void
{
$query = $this->db->delete()
->from('fiskaly_pos_mapping')
->where('id=:id')
->bindValue('id', $fiskalyPosMappingId);
$this->db->perform($query->getStatement(), $query->getBindValues());
}
/**
* @param int $projectId
*
* @return array
*/
public function getTssFromProjectId(int $projectId): array
{
$query = $this->db->select()
->from('fiskaly_pos_mapping AS f')
->where('pos_id=:pos_id')
->bindValue('pos_id', $projectId)
->cols(['f.tss_uuid', 'f.organization_id', 'f.client_uuid']);
return $this->db->fetchRow($query->getStatement(), $query->getBindValues());
}
/**
* @param int $projectId
*
* @return string|null
*/
public function getTssIdFromProjectId(int $projectId): ?string
{
$query = $this->db->select()
->from('fiskaly_pos_mapping AS f')
->where('pos_id=:pos_id')
->bindValue('pos_id', $projectId)
->cols(['f.tss_uuid']);
$tssId = $this->db->fetchValue($query->getStatement(), $query->getBindValues());
if ($tssId === false) {
return null;
}
return $tssId;
}
/**
* @param Organisation $organisation
*/
public function tryCreateOrUpdateOrganization(Organisation $organisation): void
{
if ($this->getOrganizationByUuId($organisation->getUuid()) === null) {
$this->createOrganization($organisation);
return;
}
$this->updateOrganization($organisation);
}
/**
* @param int $id
*
* @return Organisation|null
*/
public function getOrganizationById(int $id): ?Organisation
{
$organizationRow = $this->db->fetchRow(
'SELECT * FROM `fiskaly_organization` WHERE `id` = :id',
[
'id' => $id,
]
);
if (empty($organizationRow)) {
return null;
}
return $this->getOrganizationFromDbEntry($organizationRow);
}
/**
* @param string $uuId
*
* @return Organisation|null
*/
public function getOrganizationByUuId(string $uuId): ?Organisation
{
$organizationRow = $this->db->fetchRow(
'SELECT * FROM `fiskaly_organization` WHERE `fiskaly_organization_id` = :uuid',
[
'uuid' => $uuId,
]
);
if (empty($organizationRow)) {
return null;
}
return $this->getOrganizationFromDbEntry($organizationRow);
}
/**
* @param array $organizationRow
*
* @return Organisation
*/
private function getOrganizationFromDbEntry(array $organizationRow): Organisation
{
$envs = [];
if (!empty($organizationRow['is_environment_live'])) {
$envs[] = 'LIVE';
}
if (!empty($organizationRow['is_environment_test'])) {
$envs[] = 'TEST';
}
$organizationRow['_id'] = $organizationRow['fiskaly_organization_id'];
$organizationRow['_type'] = $organizationRow['type'];
$organizationRow['_envs'] = $envs;
if (!empty($organizationRow['gln'])) {
$organizationRow['billing_options']['gln'] = $organizationRow['gln'];
}
if (!empty($organizationRow['withhold_billing'])) {
$organizationRow['billing_options']['withhold_billing'] = $organizationRow['withhold_billing'];
}
if (!empty($organizationRow['bill_to_organization'])) {
$organizationRow['billing_options']['bill_to_organization'] = $organizationRow['bill_to_organization'];
}
return Organisation::fromDbState($organizationRow);
}
/**
* @param Organisation $organisation
*
* @return int
*/
public function createOrganization(Organisation $organisation): int
{
$query = $this->db->insert()
->into('fiskaly_organization')
->cols(
[
'fiskaly_organization_id' => $organisation->getUuid(),
'managed_by_organization_id' => $organisation->getManagedByOrganizationId(),
'type' => $organisation->getType(),
'name' => $organisation->getName(),
'display_name' => $organisation->getDisplayName(),
'address_line1' => $organisation->getAddressLine1(),
'address_line2' => $organisation->getAddressLine2(),
'state' => $organisation->getState(),
'zip' => $organisation->getZip(),
'town' => $organisation->getTown(),
'tax_number' => $organisation->getTaxNumber(),
'vat_id' => $organisation->getVatId(),
'economy_id' => $organisation->getEconomyId(),
'country_code' => $organisation->getCountryCode(),
'is_environment_live' => (int)in_array('LIVE', $organisation->getEnvs()),
'is_environment_test' => (int)in_array('TEST', $organisation->getEnvs()),
]
);
$this->db->perform(
$query->getStatement(),
$query->getBindValues()
);
return $this->db->lastInsertId();
}
/**
* @param Organisation $organisation
*/
public function updateOrganization(Organisation $organisation): void
{
$query = $this->db->update()
->table('fiskaly_organization')
->where('fiskaly_organization_id=:fiskaly_organization_id')
->bindValue('fiskaly_organization_id', $organisation->getUuid())
->cols(
[
'managed_by_organization_id' => $organisation->getManagedByOrganizationId(),
'type' => $organisation->getType(),
'name' => $organisation->getName(),
'display_name' => $organisation->getDisplayName(),
'address_line1' => $organisation->getAddressLine1(),
'address_line2' => $organisation->getAddressLine2(),
'state' => $organisation->getState(),
'zip' => $organisation->getZip(),
'town' => $organisation->getTown(),
'tax_number' => $organisation->getTaxNumber(),
'vat_id' => $organisation->getVatId(),
'economy_id' => $organisation->getEconomyId(),
'country_code' => $organisation->getCountryCode(),
'is_environment_live' => (int)in_array('LIVE', $organisation->getEnvs()),
'is_environment_test' => (int)in_array('TEST', $organisation->getEnvs()),
]
);
$this->db->perform(
$query->getStatement(),
$query->getBindValues()
);
}
/**
* @param int $projectId
* @param string $tseUuid
* @param string $tseDescription
* @param string $clientUuid
* @param string $clientDescription
* @param bool|null $istTestEnvironment
* @param string|null $organizationId
*
* @return int
*/
public function create(
int $projectId,
string $tseUuid,
string $tseDescription,
string $clientUuid,
string $clientDescription,
?bool $istTestEnvironment = null,
?string $organizationId = null
): int {
$query = $this->db->insert()
->into('fiskaly_pos_mapping')
->cols(
[
'pos_id' => $projectId,
'tss_uuid' => $tseUuid,
'tss_description' => $tseDescription,
'client_uuid' => $clientUuid,
'client_description' => $clientDescription,
'is_test_environment' => $istTestEnvironment === null ? null : (int)$istTestEnvironment,
'organization_id' => $organizationId ?? null,
]
);
$this->db->perform(
$query->getStatement(),
$query->getBindValues()
);
return $this->db->lastInsertId();
}
/**
* @param int $fiskalyPosMappingId
* @param int $projectId
* @param string $tseUuid
* @param string $tseDescription
* @param string $clientUuid
* @param string $clientDescription
* @param bool|null $istTestEnvironment
* @param string|null $organizationId
*/
public function update(
int $fiskalyPosMappingId,
int $projectId,
string $tseUuid,
string $tseDescription,
string $clientUuid,
string $clientDescription,
?bool $istTestEnvironment = null,
?string $organizationId = null
): void {
$query = $this->db->update()
->table('fiskaly_pos_mapping')
->where('id=:id')
->bindValue('id', $fiskalyPosMappingId)
->cols(
[
'pos_id' => $projectId,
'tss_uuid' => $tseUuid,
'tss_description' => $tseDescription,
'client_uuid' => $clientUuid,
'client_description' => $clientDescription,
'is_test_environment' => $istTestEnvironment === null ? null : (int)$istTestEnvironment,
'organization_id' => $organizationId ?? null,
]
);
$this->db->perform(
$query->getStatement(),
$query->getBindValues()
);
}
}
@@ -0,0 +1,158 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Service;
use Aura\SqlQuery\Exception;
use Xentral\Modules\FiskalyApi\Data\Transaction\TransactionReponse;
use Xentral\Modules\FiskalyApi\Transaction\Transaction;
class FiskalyTransactionCacheService
{
/** @var array */
private $transactions = [];
/** @var array $transactionResponse */
private $transactionResponse = [];
/** @var array $documentMappings */
private $documentMappings = [];
/** @var array $error */
private $error = [];
public function __construct()
{
}
/**
* @param int $id
* @param string $document
* @param int $documentId
*/
public function addDocumentMapping(int $id, string $document, int $documentId): void
{
$this->documentMappings[$id][] = ['document' => $document, 'document_id' => $documentId];
}
/**
* @param int $id
*
* @return array
*/
public function getDocumentMappings(int $id): array
{
return $this->documentMappings[$id] ?? [];
}
/**
* @param int $id
* @param Transaction $transaction
*
* @return void
*/
public function put(int $id, Transaction $transaction): void
{
$this->transactions[$id] = $transaction;
}
/**
* @param int $id
* @param TransactionReponse $transactionResponse
*/
public function putTransactionResponse(int $id, TransactionReponse $transactionResponse): void
{
$this->transactionResponse[$id] = TransactionReponse::fromDbState($transactionResponse->toArray());
}
/**
* @param int $id
*
* @return TransactionReponse
*/
public function getTransactionResponse(int $id): TransactionReponse
{
return TransactionReponse::fromDbState($this->transactionResponse[$id]->toArray());
}
/**
* @param int $id
* @param string $errorMessage
* @param string $sma
*/
public function putErrorMessage(int $id, string $errorMessage, string $sma): void
{
$this->error[$id] = ['sma' => $sma, 'error_message' => $errorMessage];
}
/**
* @param int $id
*
* @return array|null
*/
public function getErrorMessage(int $id): ?array
{
if (!isset($this->error[$id])) {
return null;
}
return $this->error[$id];
}
/**
* @param int $id
*
* @return Transaction
*/
public function get(int $id): Transaction
{
return $this->transactions[$id];
}
/**
* @param int $id
*/
public function reset(int $id): void
{
if (isset($this->documentMappings[$id])) {
unset($this->documentMappings[$id]);
}
if (isset($this->transactionResponse[$id])) {
unset($this->transactionResponse[$id]);
}
if (isset($this->error[$id])) {
unset($this->error[$id]);
}
}
/**
* @param int $id
*
* @return bool
*/
public function hasTransaction(int $id): bool
{
return array_key_exists($id, $this->transactionResponse);
}
/**
* @param int $id
*
* @return bool
*/
public function hasError(int $id): bool
{
return array_key_exists($id, $this->error);
}
public function getNextOpenKey(): int
{
if (empty($this->transactionResponse)) {
return 0;
}
$keys = array_diff(range(0, count($this->transactionResponse)), array_keys($this->transactionResponse));
return reset($keys);
}
}
@@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Service;
use Xentral\Modules\FiskalyApi\Data\Export;
use Xentral\Modules\FiskalyApi\Data\Transaction\TransactionReponse;
use Xentral\Modules\FiskalyApi\Data\Transaction\TransactionReponseCollection;
use Xentral\Modules\FiskalyApi\Data\Transaction\TransactionRequest;
interface FiskalyTransactionPosSessionInterface
{
public function get(string $trxId): ?array;
public function insertTransactions(TransactionReponseCollection $transactionResponseCollection): void;
public function getTransactionIdFromTrxId(string $trxId): ?int;
public function tryMapDocument(string $trxId, string $document, int $documentId): int;
public function create(
?TransactionRequest $request,
?TransactionReponse $response
): int;
public function update(
int $fiskalyTransactionPosSessionId,
TransactionRequest $request,
TransactionReponse $response
): void;
public function createOrUpdateExport(Export $export): void;
public function updateExport(Export $export): void;
public function getExportUrlsNotInDms(string $tssId): array;
public function getUuIdsByState(string $state, ?string $tssId = null): array;
}
@@ -0,0 +1,383 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Service;
use Datetime;
use DateTimeZone;
use Exception;
use Xentral\Components\Database\Database;
use Xentral\Modules\FiskalyApi\Data\Export;
use Xentral\Modules\FiskalyApi\Data\Transaction\TransactionReponse;
use Xentral\Modules\FiskalyApi\Data\Transaction\TransactionReponseCollection;
use Xentral\Modules\FiskalyApi\Data\Transaction\TransactionRequest;
use Xentral\Modules\FiskalyApi\Exception\InvalidArgumentException;
use Xentral\Modules\FiskalyApi\Exception\InvalidTransactionException;
final class FiskalyTransactionPosSessionService implements FiskalyTransactionPosSessionInterface
{
/** @var Database $db */
private $db;
/**
* FiskalyTransactionPosSessionService constructor.
*
* @param Database $db
*/
public function __construct(Database $db)
{
$this->db = $db;
}
/**
* @param string $trxId
*
* @return array|null
*/
public function get(string $trxId): ?array
{
return $this->db->fetchRow(
'SELECT * FROM `fiskaly_transaction` WHERE `trx_id` = :trx_id',
['trx_id' => $trxId]
);
}
/**
* @param TransactionReponseCollection $transactionResponseCollection
*/
public function insertTransactions(TransactionReponseCollection $transactionResponseCollection): void
{
foreach ($transactionResponseCollection as $transactionResponse) {
$trxId = $transactionResponse->getId();
if (!empty($this->get($trxId))) {
continue;
}
$this->create(null, $transactionResponse);
}
}
/**
* @param string $trxId
*
* @return int|null
*/
public function getTransactionIdFromTrxId(string $trxId): ?int
{
$fiskalyTransactionId = $this->db->fetchValue(
'SELECT `id` FROM `fiskaly_transaction` WHERE `trx_id` = :trx_id',
[
'trx_id' => $trxId,
]
);
return $fiskalyTransactionId === false ? null : (int)$fiskalyTransactionId;
}
/**
* @param string $document
* @param int $documentId
*
* @return array
*/
public function getTransactionFromDocument(string $document, int $documentId): array
{
return $this->db->fetchRow(
'SELECT ft.*
FROM `fiskaly_transaction` AS `ft`
INNER JOIN `fiskaly_tranaction_mapping` AS `ftm` ON ft.id = ftm.fiskaly_transaction_id
WHERE ftm.document = :document AND ftm.document_id = :document_id',
[
'document' => $document,
'document_id' => $documentId,
]
);
}
/**
* @param string $trxId
* @param string $document
* @param int $documentId
*
* @return int
*/
public function tryMapDocument(string $trxId, string $document, int $documentId): int
{
$fiskalyTransactionId = $this->getTransactionIdFromTrxId($trxId);
$mappingId = $fiskalyTransactionId === null ? false : $this->db->fetchValue(
'SELECT ftm.id
FROM `fiskaly_tranaction_mapping` AS `ftm`
WHERE ftm.fiskaly_transaction_id = :fiskaly_transaction_id
AND ftm.document = :document
AND ftm.document_id = :document_id',
[
'fiskaly_transaction_id' => $fiskalyTransactionId,
'document' => $document,
'document_id' => $documentId,
]
);
if ($mappingId !== false) {
return (int)$mappingId;
}
$this->db->perform(
'INSERT INTO `fiskaly_tranaction_mapping` (`fiskaly_transaction_id`, `document`, `document_id`)
VALUES (:fiskaly_transaction_id, :document, :document_id)',
[
'fiskaly_transaction_id' => $fiskalyTransactionId,
'document' => $document,
'document_id' => $documentId,
]
);
return $this->db->lastInsertId();
}
/**
* @param TransactionRequest|null $request
* @param TransactionReponse|null $response
*
* @return int
*/
public function create(
?TransactionRequest $request,
?TransactionReponse $response
): int {
if ($request === null && $response === null) {
throw new InvalidArgumentException('response or request required');
}
$trxId = $request === null ? $response->getId() : $request->getId();
if (!empty($this->get($trxId))) {
throw new InvalidTransactionException('Transaction already exists');
}
$this->db->perform(
'INSERT INTO `fiskaly_transaction`
(`tss_id`, `client_id`, `trx_id`, `state`,
`time_start`, `time_end`, `json_request`, `json_response`)
VALUES (:tss_id, :client_id, :trx_id, :state,
NULL, NULL, :json_request, :json_response)',
[
'tss_id' => $request === null ? $response->getTssId() : $request->getTssId(),
'client_id' => $request === null ? $response->getClientId() : $request->getClientId(),
'trx_id' => $trxId,
'state' => $response === null ? null : $response->getState(),
'json_request' => $request === null ? null : json_encode($request->toArray()),
'json_response' => $response === null ? null : json_encode($response->toArray()),
]
);
$fiskalyTransactionId = $this->db->lastInsertId();
if ($response === null) {
return $fiskalyTransactionId;
}
if ($response->getTimeStart() !== null) {
$this->db->perform(
'UPDATE `fiskaly_transaction`
SET `time_start` = FROM_UNIXTIME(:time_start)
WHERE `id` = :id',
[
'time_start' => $response->getTimeStart()->getTimestamp(),
'id' => $fiskalyTransactionId,
]
);
}
if ($response->getTimeEnd() !== null) {
$this->db->perform(
'UPDATE `fiskaly_transaction`
SET `time_end` = FROM_UNIXTIME(:time_end)
WHERE `id` = :id',
[
'time_end' => $response->getTimeEnd()->getTimestamp(),
'id' => $fiskalyTransactionId,
]
);
}
return $fiskalyTransactionId;
}
/**
* @param int $fiskalyTransactionPosSessionId
* @param TransactionRequest $request
* @param TransactionReponse $response
*/
public function update(
int $fiskalyTransactionPosSessionId,
TransactionRequest $request,
TransactionReponse $response
): void {
if ($response->getTimeEnd() === null) {
$this->db->perform(
'UPDATE `fiskaly_transaction`
SET `state` = :state,
`time_end` = NULL,
`json_request` = :json_request,
`json_response` = :json_response
WHERE `id` = :id',
[
'state' => $response->getState(),
'json_request' => json_encode($request->toApiResult()),
'json_response' => json_encode($response->toApiResult()),
'id' => $fiskalyTransactionPosSessionId,
]
);
return;
}
$this->db->perform(
'UPDATE `fiskaly_transaction`
SET `state` = :state,
`time_end` = FROM_UNIXTIME(:time_end),
`json_request` = :json_request,
`json_response` = :json_response
WHERE `id` = :id',
[
'state' => $response->getState(),
'time_end' => $response->getTimeEnd()->getTimestamp(),
'json_request' => json_encode($request->toApiResult()),
'json_response' => json_encode($response->toApiResult()),
'id' => $fiskalyTransactionPosSessionId,
]
);
}
/**
* @param Export $export
*
* @throws Exception
*/
public function createOrUpdateExport(Export $export): void
{
if ($this->getExportIdFromUuid($export->getUuId()) === null) {
$this->createExport($export);
return;
}
$this->updateExport($export);
}
/**
* @param Export $export
*
* @throws Exception
* @return int
*/
public function createExport(Export $export): int
{
$this->db->perform(
'INSERT INTO `fiskaly_kassensichv_export`
(`uuid`, `type`, `env`, `tssid`, `state`, `href`, `time_request`, `time_start`, `time_end`)
VALUES (:uuid, :type, :env, :tssid, :state, :href, :time_request, :time_start, :time_end)',
[
'uuid' => $export->getUuId(),
'type' => $export->getType(),
'env' => $export->getEnv(),
'tssid' => $export->getTssId(),
'state' => $export->getState(),
'href' => $export->getHref(),
'time_request' => $export->getTimeRequest() === null ? null : (new Datetime(
'now',
new DateTimeZone('UTC')
))->setTimeStamp(
$export->getTimeRequest()
)->format('Y-m-d H:i:s'),
'time_start' => $export->getTimeStart() === null ? null : (new Datetime(
'now', new DateTimeZone('UTC')
))->setTimeStamp($export->getTimeStart())
->format('Y-m-d H:i:s'),
'time_end' => $export->getTimeEnd() === null ? null : (new Datetime(
'now', new DateTimeZone('UTC')
))->setTimeStamp($export->getTimeEnd())
->format('Y-m-d H:i:s'),
]
);
return $this->db->lastInsertId();
}
/**
* @param Export $export
*
* @throws Exception
*/
public function updateExport(Export $export): void
{
$this->db->perform(
'UPDATE `fiskaly_kassensichv_export`
SET `state` = :state,
`href` = :href,
`time_request` = :time_request,
`time_start` = :time_start,
`time_end` = :time_end
WHERE `uuid` = :uuid',
[
'uuid' => $export->getUuId(),
'state' => $export->getState(),
'href' => $export->getHref(),
'time_request' => (new Datetime('now', new DateTimeZone('UTC')))->setTimeStamp(
$export->getTimeRequest()
)->format('Y-m-d H:i:s'),
'time_start' => (new Datetime('now', new DateTimeZone('UTC')))->setTimeStamp($export->getTimeStart())
->format('Y-m-d H:i:s'),
'time_end' => (new Datetime('now', new DateTimeZone('UTC')))->setTimeStamp($export->getTimeEnd())
->format('Y-m-d H:i:s'),
]
);
}
/**
* @param string $tssId
*
* @return array
*/
public function getExportUrlsNotInDms(string $tssId): array
{
return $this->db->fetchAll(
"SELECT fke.id, fke.href, fke.uuid
FROM `fiskaly_kassensichv_export` AS `fke`
LEFT JOIN `datei_stichwoerter` AS `ds` ON fke.id = ds.parameter AND ds.objekt = 'fiskaly_kassensichv_export'
WHERE `fke`.state = 'COMPLETED' AND fke.tssid = :tssid AND ds.id IS NULL",
['tssid' => $tssId]
);
}
/**
* @param string $state
* @param string|null $tssId
*
* @return array
*/
public function getUuIdsByState(string $state, ?string $tssId = null): array
{
if ($tssId === null) {
return $this->db->fetchCol(
'SELECT `uuid` FROM `fiskaly_kassensichv_export` WHERE `state` = :state',
[
'state' => $state,
]
);
}
return $this->db->fetchCol(
'SELECT `uuid` FROM `fiskaly_kassensichv_export` WHERE `tssid` = :tssid AND `state` = :state',
[
'tssid' => $tssId,
'state' => $state,
]
);
}
/**
* @param string $uuid
*
* @return int|null
*/
private function getExportIdFromUuid(string $uuid): ?int
{
$id = $this->db->fetchValue(
'SELECT `id` FROM `fiskaly_kassensichv_export` WHERE `uuid` = :uuid',
['uuid' => $uuid]
);
return $id === false ? null : (int)$id;
}
}
@@ -0,0 +1,340 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Service;
use Aura\SqlQuery\Exception;
use FiskalyClient\errors\exceptions\FiskalyClientException;
use FiskalyClient\errors\exceptions\FiskalyHttpException;
use FiskalyClient\errors\exceptions\FiskalyHttpTimeoutException;
use Xentral\Components\Database\Database;
use Xentral\Modules\FiskalyApi\Data\TechnicalSecuritySystem;
use Xentral\Modules\FiskalyApi\Data\Transaction\AmountsPerPaymentType;
use Xentral\Modules\FiskalyApi\Data\Transaction\AmountsPerPaymentTypeCollection;
use Xentral\Modules\FiskalyApi\Data\Transaction\AmountsPerVatType;
use Xentral\Modules\FiskalyApi\Data\Transaction\AmountsPerVatTypeCollection;
use Xentral\Modules\FiskalyApi\Data\Transaction\TransactionReponse;
use Xentral\Modules\FiskalyApi\Data\Transaction\TransactionReponseCollection;
use Xentral\Modules\FiskalyApi\Data\Transaction\TransactionRequest;
use Xentral\Modules\FiskalyApi\Factory\FiskalyApiFactory;
use Xentral\Modules\FiskalyApi\Factory\FiskalyTransactionFactory;
use Xentral\Modules\FiskalyApi\Transaction\Payment\CashPayment;
use Xentral\Modules\FiskalyApi\Transaction\Payment\NonCashPayment;
use Xentral\Modules\FiskalyApi\Transaction\Payment\OrderLineItem;
use Xentral\Modules\FiskalyApi\Transaction\Transaction;
use Xentral\Modules\FiskalyApi\Transaction\VatAmount\BaseVatAmount;
class FiskalyTransferService
{
/** @var FiskalyKassenSichVApi */
private $fiskalyApi;
/** @var FiskalyTransactionFactory $transactionFactory */
private $transactionFactory;
/** @var Database */
private $database;
/** @var FiskalyApiFactory $fiskalyApiFactory */
private $fiskalyApiFactory;
/**
* FiskalyTransferService constructor.
*
* @param FiskalyApiFactory $fiskalyApiFactory
* @param Database $database
*/
public function __construct(
FiskalyApiFactory $fiskalyApiFactory,
FiskalyTransactionFactory $transactionFactory,
Database $database
) {
$this->fiskalyApiFactory = $fiskalyApiFactory;
$this->transactionFactory = $transactionFactory;
$this->database = $database;
}
/**
* @param string $organizationId
*
* @throws \Exception
*/
public function loadOrganization(string $organizationId): self
{
$this->fiskalyApi = $this->fiskalyApiFactory->createFiskalyKassenSichVApiFromSystemSettings($organizationId);
return $this;
}
/**
* @param int $cashierId
* @param bool $incoming
* @param float $amount
* @param bool $isCash
*
* @throws Exception
* @return Transaction
*
* @depracated
*/
public function createTransactionFromSingleJournal(
int $cashierId,
bool $incoming,
float $amount,
bool $isCash
): Transaction {
$posProjectQuery = $this->database->select()
->from('pos_kassierer AS p')
->cols(['f.tss_uuid', 'f.client_uuid'])
->where('p.kassenkennung=:kennung')
->leftJoin('fiskaly_pos_mapping AS f', 'f.pos_id = p.projekt')
->bindValue('kennung', $cashierId);
$result = $this->database->fetchRow($posProjectQuery->getStatement(), $posProjectQuery->getBindValues());
$tssUuid = $result['tss_uuid'];
$clientId = $result['client_uuid'];
$tssDescription = $result['tss_description'];
if ($isCash) {
$paymentTypePayment = new CashPayment($amount);
} else {
$paymentTypePayment = new NonCashPayment($amount);
}
$vat = (float)0;
$sum = $amount * ($incoming ? 1 : -1);
$vatTypePayment = BaseVatAmount::fromPercentage($vat, $sum);
$transaction = new Transaction([$paymentTypePayment], [$vatTypePayment], [], $clientId);
$tss = new TechnicalSecuritySystem($tssUuid, $tssDescription);
return $this->fiskalyApi->uploadTransaction($transaction, $tss);
}
/**
* @param TransactionRequest $transactionRequest
*
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
* @return TransactionReponse
*/
public function startTransaction(TransactionRequest $transactionRequest): TransactionReponse
{
return $this->fiskalyApi->createTransaction($transactionRequest);
}
/**
* @param string|null $tssUuid
* @param int $offset
* @param int $limit
*
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
* @return TransactionReponseCollection
*/
public function getTransactions(
?string $tssUuid = null,
int $offset = 0,
int $limit = 100
): TransactionReponseCollection {
return $this->fiskalyApi->getTransactions($tssUuid, $offset, $limit);
}
/**
* @param TransactionRequest $transactionRequest
*
* @throws FiskalyClientException
* @throws FiskalyHttpException
* @throws FiskalyHttpTimeoutException
* @return TransactionReponse
*/
public function updateTransaction(TransactionRequest $transactionRequest): TransactionReponse
{
return $this->fiskalyApi->updateTransaction($transactionRequest);
}
/**
* @param TransactionReponse $transactionResponse
* @param bool $incoming
* @param float $value
* @param bool $isTraining
*
* @return TransactionRequest
*/
public function createTransactionRequestFromPosCounting(
TransactionReponse $transactionResponse,
bool $incoming,
float $value,
bool $isTraining = false
): TransactionRequest {
$negativeMultiplier = $incoming ? 1 : -1;
$vatTypePayment = BaseVatAmount::fromPercentage(0, $value);
$amountsPerVatTypeCollection = new AmountsPerVatTypeCollection(
[
new AmountsPerVatType(
$vatTypePayment->getVatType(), number_format($negativeMultiplier * $value, 2, '.', '')
),
]
);
$amountsPerPaymentTypeCollection = new AmountsPerPaymentTypeCollection(
[new AmountsPerPaymentType('CASH', number_format($negativeMultiplier * $value, 2, '.', ''), 'EUR')]
);
$receiptType = $isTraining ? 'TRAINING' : 'TRANSFER';
return $this->fiskalyApi->getFinishTransactionRequest(
$transactionResponse,
!empty($posSession['training']) ? 'TRAINING' : $receiptType,
$amountsPerVatTypeCollection,
$amountsPerPaymentTypeCollection
);
}
/**
* @param TransactionReponse $transactionResponse
* @param array $posSession
*
* @return TransactionRequest
*/
public function createFinishTransactionFromPosSession(
TransactionReponse $transactionResponse,
array $posSession
): TransactionRequest {
$amountsPerVatTypeCollection = new AmountsPerVatTypeCollection();
$amountsPerPaymentTypeCollection = new AmountsPerPaymentTypeCollection();
$paymentType = $posSession['ptype'];
$receiptType = 'RECEIPT';
$type = $posSession['rtype'];
if (in_array($type, ['einlage', 'entnahme'])) {
$type = 'TRANSFER';
}
$negativeMultiplier = 1;
if ($type === 'entnahme' || in_array($posSession['cmd'], ['stornieren', 'teilstornieren'])) {
$negativeMultiplier = -1;
}
$tip = isset($posSession['tip']) ? (float)round(str_replace(',', '.', $posSession['tip']), 2) : 0.;
$amount = (float)$posSession['soll'] * $negativeMultiplier;
if ($paymentType === 'bar') {
$amountsPerPaymentTypeCollection->addPaymentType(
new AmountsPerPaymentType('CASH', number_format($amount + $tip, 2, '.', ''), 'EUR')
);
} else {
$amountsPerPaymentTypeCollection->addPaymentType(
new AmountsPerPaymentType('NON_CASH', number_format($amount, 2, '.', ''), 'EUR')
);
if ($tip > 0) {
$amountsPerPaymentTypeCollection->addPaymentType(
new AmountsPerPaymentType('CASH', number_format($tip, 2, '.', ''), 'EUR')
);
}
}
foreach ($posSession['wk'] as $position) {
$vat = str_replace('%', '', $position['tax']);
$vat = (float)str_replace(',', '.', $vat);
$sum = (float)str_replace(',', '.', $position['preis']) * (float)str_replace(',', '.', $position['amount'])
* (1 - (float)str_replace(',', '.', $position['rabatt']) / 100);
$vatTypePayment = BaseVatAmount::fromPercentage($vat, $sum);
$amountsPerVatTypeCollection->combine(
new AmountsPerVatTypeCollection(
[
new AmountsPerVatType($vatTypePayment->getVatType(), number_format($sum, 2, '.', '')),
]
)
);
}
if ($tip > 0) {
$vatTypePayment = BaseVatAmount::fromPercentage(0, $tip);
$amountsPerVatTypeCollection->combine(
new AmountsPerVatTypeCollection(
[
new AmountsPerVatType($vatTypePayment->getVatType(), number_format($tip, 2, '.', '')),
]
)
);
}
return $this->fiskalyApi->getFinishTransactionRequest(
$transactionResponse,
!empty($posSession['training']) ? 'TRAINING' : $receiptType,
$amountsPerVatTypeCollection,
$amountsPerPaymentTypeCollection
);
}
/**
* @param $posSession
*
* @throws Exception
* @return Transaction
*
* @depracated
*/
public function transferPosSession($posSession): Transaction
{
$cashierId = $posSession['kassiererId'];
$result = $this->transactionFactory->getClientAndTssInfoFromCashierId((string)$cashierId);
$tssUuid = $result['tss_uuid'];
$clientId = $result['client_uuid'];
$tssDescription = $result['tss_description'];
$paymentType = $posSession['ptype'];
$negativeMultiplier = 1;
if (in_array($posSession['cmd'], ['stornieren', 'teilstornieren'])) {
$negativeMultiplier = -1;
}
$tip = isset($posSession['tip']) ? (float)round(str_replace(',', '.', $posSession['tip']), 2) : 0.;
$amount = (float)$posSession['soll'] * $negativeMultiplier;
$paymentTypePayments = [];
if ($paymentType === 'bar') {
$paymentTypePayments[] = new CashPayment($amount + $tip);
} else {
$paymentTypePayments[] = new NonCashPayment($amount);
if ($tip > 0) {
$paymentTypePayments[] = new CashPayment($tip);
}
}
$vatTypeAmounts = [];
$oderLineItems = [];
foreach ($posSession['wk'] as $position) {
$vat = str_replace('%', '', $position['tax']);
$vat = (float)str_replace(',', '.', $vat);
$sum = (float)str_replace(',', '.', $position['preis']);
$amount = (float)$position['amount'];
$oderLineItems[] = new OrderLineItem($amount, (string)$position['artikel'], $sum * $negativeMultiplier);
$sum *= $amount * $negativeMultiplier;
$vatTypePayment = BaseVatAmount::fromPercentage($vat, $sum);
$vatTypeClass = get_class($vatTypePayment);
/** @var BaseVatAmount $vatTypeAmount */
$cachedVatTypePayment = $vatTypeAmounts[$vatTypeClass] ?? null;
if (empty($cachedVatTypePayment)) {
$vatTypeAmounts[$vatTypeClass] = $vatTypePayment;
} else {
$cachedVatTypePayment->add($sum);
}
}
if ($tip > 0) {
$vatTypePayment = BaseVatAmount::fromPercentage(0., $tip);
$vatTypeClass = get_class($vatTypePayment);
/** @var BaseVatAmount $vatTypeAmount */
$cachedVatTypePayment = $vatTypeAmounts[$vatTypeClass] ?? null;
if ($cachedVatTypePayment === null) {
$vatTypeAmounts[$vatTypeClass] = $vatTypePayment;
} else {
$cachedVatTypePayment->add($tip);
}
$oderLineItems[] = new OrderLineItem(1, 'Trinkgeld', $tip);
}
$transaction = new Transaction($paymentTypePayments, array_values($vatTypeAmounts), $oderLineItems, $clientId);
$tss = new TechnicalSecuritySystem($tssUuid, $tssDescription);
return $this->fiskalyApi->uploadTransaction($transaction, $tss);
}
}
@@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Transaction\Payment;
abstract class BasePayment
{
/** @var string */
private $paymentType;
/** @var float */
private $amount;
/**
* BasePayment constructor.
*
* @param string $paymentType
* @param float $amount
*/
protected function __construct(string $paymentType, float $amount)
{
$this->paymentType = $paymentType;
$this->amount = $amount;
}
/**
* @return string
*/
public function getPaymentType(): string {
return $this->paymentType;
}
/**
* @return float
*/
public function getAmount(): float {
return $this->amount;
}
}
@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Transaction\Payment;
final class CashPayment extends BasePayment
{
public function __construct(float $amount)
{
parent::__construct('CASH', $amount);
}
}
@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Transaction\Payment;
final class NonCashPayment extends BasePayment
{
public function __construct(float $amount)
{
parent::__construct('NON_CASH', $amount);
}
}
@@ -0,0 +1,74 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Transaction\Payment;
final class OrderLineItem
{
/** @var float $quantity */
private $quantity;
/** @var string $text */
private $text;
/** @var float $pricePerUnit */
private $pricePerUnit;
public function __construct(float $quantity, string $text, float $pricePerUnit)
{
$this->quantity = $quantity;
$this->text = $text;
$this->pricePerUnit = $pricePerUnit;
}
/**
* @return string
*/
public function getQuantity(): string
{
return number_format($this->quantity, 2, '.', '');
}
/**
* @param float $quantity
*/
public function setQuantity(float $quantity): void
{
$this->quantity = $quantity;
}
/**
* @return string
*/
public function getText(): string
{
return mb_substr($this->text, 0, 255);
}
/**
* @param string $text
*/
public function setText(string $text): void
{
$this->text = $text;
}
/**
* @return string
*/
public function getPricePerUnit(): string
{
return number_format($this->pricePerUnit, 2, '.', '');
}
/**
* @param float $pricePerUnit
*/
public function setPricePerUnit(float $pricePerUnit): void
{
$this->pricePerUnit = $pricePerUnit;
}
}
@@ -0,0 +1,301 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Transaction;
use Xentral\Modules\FiskalyApi\Transaction\Payment\BasePayment;
use Xentral\Modules\FiskalyApi\Transaction\Payment\OrderLineItem;
use Xentral\Modules\FiskalyApi\Transaction\VatAmount\BaseVatAmount;
use Xentral\Modules\FiskalyApi\UuidTool;
/**
* Class Transaction
*
* @package Xentral\Modules\FiskalyApi\Transaction
*/
class Transaction
{
/** @var array */
private $amountsPerVatRate;
/** @var BasePayment[] */
private $amountsPerPaymentType;
private $oderLineItems;
/** @var string */
private $uuid;
/** @var string */
private $clientUuid;
/** @var int */
private $lastRevision = -1;
/** @var int */
private $startTime;
/** @var int */
private $endTime;
/** @var string */
private $clientSerialNumber;
/** @var string */
private $certificateSerial;
// TODO Signature object
/** @var string */
private $signature;
/** @var string */
private $publicKey;
/** @var string */
private $signatureAlgorithm;
/** @var int */
private $signatureCounter;
/** @var string $qrCodeData */
private $qrCodeData;
/**
* @return int
*/
public function getTransactionNumber(): int
{
return $this->transactionNumber;
}
/**
* @param int $transactionNumber
*/
public function setTransactionNumber(int $transactionNumber): void
{
$this->transactionNumber = $transactionNumber;
}
/** @var int */
private $transactionNumber;
/**
* Transaction constructor.
*
* @param array $amountsPerPaymentType
* @param array $amountsPerVatRate
* @param OrderLineItem[] $orderLineItems
* @param string $clientId
* @param string|null $uuid
*/
public function __construct(
array $amountsPerPaymentType,
array $amountsPerVatRate,
array $orderLineItems,
string $clientId,
string $uuid = null
) {
$this->amountsPerPaymentType = $amountsPerPaymentType;
$this->amountsPerVatRate = $amountsPerVatRate;
$this->oderLineItems = $orderLineItems;
$this->uuid = $uuid;
$this->clientUuid = $clientId;
if (empty($this->uuid)) {
$this->uuid = UuidTool::generateUuid();
}
}
/**
* @return BaseVatAmount[]
*/
public function getAmountsPerVatRate(): array
{
return $this->amountsPerVatRate;
}
/**
* @return BasePayment[]
*/
public function getAmountsPerPaymentType(): array
{
return $this->amountsPerPaymentType;
}
/**
* @return OrderLineItem[]
*/
public function getOrderLineItems(): array
{
return $this->oderLineItems;
}
/* @return string */
public function getUuid(): string
{
return $this->uuid;
}
/**
* @return int
*/
public function getLastRevision(): int
{
return $this->lastRevision;
}
/**
* @return int
*/
public function getStartTime(): int
{
return $this->startTime;
}
/**
* @param int $startTime
*/
public function setStartTime(int $startTime): void
{
$this->startTime = $startTime;
}
/**
* @return int
*/
public function getEndTime(): int
{
return $this->endTime;
}
/**
* @param int $endTime
*/
public function setEndTime(int $endTime): void
{
$this->endTime = $endTime;
}
/**
* @return string
*/
public function getClientSerialNumber(): string
{
return $this->clientSerialNumber;
}
/**
* @param string $clientSerialNumber
*/
public function setClientSerialNumber(string $clientSerialNumber): void
{
$this->clientSerialNumber = $clientSerialNumber;
}
/**
* @return string
*/
public function getCertificateSerial(): string
{
return $this->certificateSerial;
}
/**
* @param string $certificateSerial
*/
public function setCertificateSerial(string $certificateSerial): void
{
$this->certificateSerial = $certificateSerial;
}
/**
* @return string
*/
public function getSignature(): string
{
return $this->signature;
}
/**
* @param string $signature
*/
public function setSignature(string $signature): void
{
$this->signature = $signature;
}
/**
* @return string
*/
public function getPublicKey(): string
{
return $this->publicKey;
}
/**
* @param string $publicKey
*/
public function setPublicKey(string $publicKey): void
{
$this->publicKey = $publicKey;
}
/**
* @return string
*/
public function getSignatureAlgorithm(): string
{
return $this->signatureAlgorithm;
}
/**
* @param string $signatureAlgorithm
*/
public function setSignatureAlgorithm(string $signatureAlgorithm): void
{
$this->signatureAlgorithm = $signatureAlgorithm;
}
/**
* @return int
*/
public function getSignatureCounter(): int
{
return $this->signatureCounter;
}
/**
* @param int $signatureCounter
*/
public function setSignatureCounter(int $signatureCounter): void
{
$this->signatureCounter = $signatureCounter;
}
/**
* @return string
*/
public function getClientUuid(): string
{
return $this->clientUuid;
}
/**
* @return bool
*/
public function isLastRevisionSet(): bool
{
return $this->lastRevision > -1;
}
/**
* @param int $lastRevision
*/
public function setLastRevision(int $lastRevision): void
{
$this->lastRevision = $lastRevision;
}
}
@@ -0,0 +1,88 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Transaction\VatAmount;
use Xentral\Modules\FiskalyApi\Exception\VatRateNotFoundException;
abstract class BaseVatAmount
{
/** @var string */
private $vatType;
/** @var float */
private $amount;
/**
* BaseVatAmount constructor.
*
* @param string $vatType
* @param float $amount
*/
protected function __construct(string $vatType, float $amount)
{
$this->vatType = $vatType;
$this->amount = $amount;
}
/**
* @return string
*/
public function getVatType(): string
{
return $this->vatType;
}
/**
* @return float
*/
public function getAmount(): float
{
return $this->amount;
}
/**
* @param float $amount
*/
public function setAmount(float $amount): void
{
$this->amount = $amount;
}
/**
* @param float $amountToAdd
*
* @return void
*/
public function add(float $amountToAdd): void
{
$this->amount += $amountToAdd;
}
/**
* @param float $percentage
* @param float $amount
*
* @throws VatRateNotFoundException
*
* @return BaseVatAmount
*/
public static function fromPercentage(float $percentage, float $amount): BaseVatAmount
{
$mapping = [
19.0 => NormalVatAmount::class,
7.0 => Reduced1VatAmount::class,
10.7 => SpecialRate1VatAmount::class,
5.5 => SpecialRate2VatAmount::class,
0 => NullVatAmount::class
];
$class = $mapping[$percentage];
if(empty($class)){
throw VatRateNotFoundException::fromPercentage($percentage);
}
return new $class($amount);
}
}
@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Transaction\VatAmount;
final class NormalVatAmount extends BaseVatAmount
{
public function __construct(float $amount)
{
parent::__construct('NORMAL', $amount);
}
}
@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Transaction\VatAmount;
class NullVatAmount extends BaseVatAmount
{
public function __construct(float $amount)
{
parent::__construct('NULL', $amount);
}
}
@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Transaction\VatAmount;
class Reduced1VatAmount extends BaseVatAmount
{
public function __construct(float $amount)
{
parent::__construct('REDUCED_1', $amount);
}
}
@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\FiskalyApi\Transaction\VatAmount;
class SpecialRate1VatAmount extends BaseVatAmount
{
public function __construct(float $amount)
{
parent::__construct('SPECIAL_RATE_1', $amount);
}
}

Some files were not shown because too many files have changed in this diff Show More