feat: better data wf

This commit is contained in:
Ondrej Vlach 2024-01-18 16:41:03 +01:00
parent 9bd3b5efff
commit 1a3cf1c2e0
Signed by: ovlach
GPG Key ID: 4FF1A23B4914DE70
22 changed files with 186 additions and 77 deletions

View File

@ -2,8 +2,9 @@
namespace App\Controller; namespace App\Controller;
use App\Entity\QRCode\QRCode; use App\Entity\Input\QRCode\QRCode;
use App\Form\Type\QRCodeType; use App\Form\Type\QRCodeType;
use App\Service\DTO\QRCodeEntityConverter;
use App\Service\QRCodeGeneratorInterface; use App\Service\QRCodeGeneratorInterface;
use App\Service\QRCodeQROptionsProviderInterface; use App\Service\QRCodeQROptionsProviderInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@ -12,7 +13,7 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Routing\Attribute\Route;
class IndexController extends AbstractController { class IndexController extends AbstractController {
public function __construct(private readonly QRCodeQROptionsProviderInterface $qrCodeQROptionsFactory) {} public function __construct(private readonly QRCodeQROptionsProviderInterface $qrCodeQROptionsFactory, private readonly QRCodeEntityConverter $codeEntityConverter) {}
#[Route('/', name: 'homepage')] #[Route('/', name: 'homepage')]
public function indexAction( public function indexAction(
Request $request, Request $request,
@ -33,7 +34,7 @@ class IndexController extends AbstractController {
do session, nicmene u takovehleho typu aplikace me to prijde naopak kontraproduktivni. do session, nicmene u takovehleho typu aplikace me to prijde naopak kontraproduktivni.
a zadani o tom mlci. Navic v pripade ze aplikace bude provozovana ve vice instancich a zadani o tom mlci. Navic v pripade ze aplikace bude provozovana ve vice instancich
by se musela resit memcache, redis... */ by se musela resit memcache, redis... */
$qrCodeImage = $qrCodeGenerator->generateQRCodeFromEntity($qrCode); $qrCodeImage = $qrCodeGenerator->generateQRCodeFromEntity($this->codeEntityConverter->convert($qrCode));
$form = $this->createForm(QRCodeType::class, $this->createQrCodeEntity()); $form = $this->createForm(QRCodeType::class, $this->createQrCodeEntity());
} }
} }

View File

@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace App\Entity\DTO\QRCode;
readonly class QRCode {
public function __construct(
public string $iban,
public \DateTimeImmutable $dueDate,
public string $message,
public QRCodeMoney $money,
public QRCodeQROptions $qrOptions,
public ?QRCodePaymentIdentification $paymentIdentification)
{ }
}

View File

@ -0,0 +1,9 @@
<?php
declare(strict_types=1);
namespace App\Entity\DTO\QRCode;
readonly class QRCodeMoney
{
public function __construct(public string $amount, public string $currency) { }
}

View File

@ -0,0 +1,9 @@
<?php
declare(strict_types=1);
namespace App\Entity\DTO\QRCode;
readonly class QRCodePaymentIdentification
{
public function __construct(public ?string $variableSymbol, public ?string $specificSymbol, public ?string $constantSymbol) { }
}

View File

@ -0,0 +1,11 @@
<?php
declare(strict_types=1);
namespace App\Entity\DTO\QRCode;
readonly class QRCodeQROptions
{
public function __construct(public int $scale, public int $margin)
{
}
}

View File

@ -1,7 +1,7 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace App\Entity\QRCode; namespace App\Entity\Input\QRCode;
use Symfony\Component\Validator\Constraints as Assert; use Symfony\Component\Validator\Constraints as Assert;
/** /**

View File

@ -1,7 +1,7 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace App\Entity\QRCode; namespace App\Entity\Input\QRCode;
use App\Validator\Currency; use App\Validator\Currency;
use App\Validator\Money; use App\Validator\Money;

View File

@ -1,10 +1,9 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace App\Entity\QRCode; namespace App\Entity\Input\QRCode;
use App\Validator\BankPaymentIdentificationNumber; use App\Validator\BankPaymentIdentificationNumber;
use Symfony\Component\Validator\Constraints as Assert;
/** /**
* Payment identification for QR code * Payment identification for QR code

View File

@ -1,7 +1,7 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace App\Entity\QRCode; namespace App\Entity\Input\QRCode;
use Symfony\Component\Validator\Constraints as Assert; use Symfony\Component\Validator\Constraints as Assert;

View File

@ -3,7 +3,7 @@ declare(strict_types=1);
namespace App\Form\Type; namespace App\Form\Type;
use App\Entity\QRCode\QRCodeMoney; use App\Entity\Input\QRCode\QRCodeMoney;
use App\Service\CurrencyListerInterface; use App\Service\CurrencyListerInterface;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType;

View File

@ -3,7 +3,7 @@ declare(strict_types=1);
namespace App\Form\Type; namespace App\Form\Type;
use App\Entity\QRCode\QRCodePaymentIdentification; use App\Entity\Input\QRCode\QRCodePaymentIdentification;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType; use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;

View File

@ -4,7 +4,7 @@ declare(strict_types=1);
namespace App\Form\Type; namespace App\Form\Type;
use App\Entity\QRCode\QRCode; use App\Entity\Input\QRCode\QRCode;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\DateType; use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\SubmitType;

View File

@ -3,7 +3,7 @@ declare(strict_types=1);
namespace App\Service; namespace App\Service;
use App\Entity\QRCode\QRCode; use App\Entity\DTO\QRCode\QRCode;
interface CacheableQRCodeGeneratorInterface extends QRCodeGeneratorInterface interface CacheableQRCodeGeneratorInterface extends QRCodeGeneratorInterface
{ {

View File

@ -3,9 +3,8 @@ declare(strict_types=1);
namespace App\Service; namespace App\Service;
use App\Entity\QRCode\QRCode; use App\Entity\DTO\QRCode\QRCode;
use Exception; use Exception;
use Psr\Cache\InvalidArgumentException;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Symfony\Contracts\Cache\CacheInterface; use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Cache\ItemInterface; use Symfony\Contracts\Cache\ItemInterface;

View File

@ -0,0 +1,58 @@
<?php
namespace App\Service\DTO;
use App\Entity\DTO\QRCode\QRCode;
use App\Entity\DTO\QRCode\QRCodeMoney;
use App\Entity\DTO\QRCode\QRCodePaymentIdentification;
use App\Entity\DTO\QRCode\QRCodeQROptions;
use Symfony\Component\Validator\Validator\ValidatorInterface;
final readonly class QRCodeEntityConverter
{
public function __construct(private ValidatorInterface $validator) {
}
public function convert(\App\Entity\Input\QRCode\QRCode $code): QRCode {
if (count($this->validator->validate($code)) !== 0) {
throw new \InvalidArgumentException("QRCode entity is not valid");
}
return new QRCode(
$code->getIban() ?? throw new \InvalidArgumentException("iban not set"),
\DateTimeImmutable::createFromMutable($code->getDueDate() ?? throw new \InvalidArgumentException("due date not set")),
$code->getMessage() ?? throw new \InvalidArgumentException("message not set"),
$this->convertMoney($code->getMoney() ?? throw new \InvalidArgumentException("money not set")),
$this->convertCodeOptions($code->getCodeQROptions() ?? throw new \InvalidArgumentException("codeQROptions not set")),
$this->convertIdentification($code->getPaymentIdentification())
);
}
protected function convertMoney(\App\Entity\Input\QRCode\QRCodeMoney $money): QRCodeMoney
{
return new QRCodeMoney(
$money->getAmount() ?? throw new \InvalidArgumentException("amount not set"),
$money->getCurrency() ?? throw new \InvalidArgumentException("currency not set")
);
}
protected function convertCodeOptions(\App\Entity\Input\QRCode\QRCodeQROptions $options): QRCodeQROptions
{
return new QRCodeQROptions(
$options->getScale(),
$options->getMargin()
);
}
protected function convertIdentification(?\App\Entity\Input\QRCode\QRCodePaymentIdentification $ident): ?QRCodePaymentIdentification {
return match ($ident) {
null => null,
default => new QRCodePaymentIdentification(
$ident->getVariableSymbol(),
$ident->getSpecificSymbol(),
$ident->getConstantSymbol()
)
};
}
}

View File

@ -3,7 +3,7 @@ declare(strict_types=1);
namespace App\Service; namespace App\Service;
use App\Entity\QRCode\QRCode; use App\Entity\DTO\QRCode\QRCode;
use App\Service\Exception\QRCodeGeneratorException; use App\Service\Exception\QRCodeGeneratorException;
interface QRCodeGeneratorInterface interface QRCodeGeneratorInterface

View File

@ -3,7 +3,7 @@ declare(strict_types=1);
namespace App\Service; namespace App\Service;
use App\Entity\QRCode\QRCodeQROptions; use App\Entity\Input\QRCode\QRCodeQROptions;
readonly final class QRCodeQROptionsDefaultProvider implements QRCodeQROptionsProviderInterface { readonly final class QRCodeQROptionsDefaultProvider implements QRCodeQROptionsProviderInterface {
const DEFAULT_SCALE = 8; const DEFAULT_SCALE = 8;

View File

@ -3,7 +3,7 @@ declare(strict_types=1);
namespace App\Service; namespace App\Service;
use App\Entity\QRCode\QRCodeQROptions; use App\Entity\Input\QRCode\QRCodeQROptions;
interface QRCodeQROptionsProviderInterface { interface QRCodeQROptionsProviderInterface {
public function getDefault(): QRCodeQROptions; public function getDefault(): QRCodeQROptions;

View File

@ -3,10 +3,10 @@ declare(strict_types=1);
namespace App\Service\Remote\Edge; namespace App\Service\Remote\Edge;
use App\Entity\QRCode\QRCode; use App\Entity\DTO\QRCode\QRCode;
use App\Entity\QRCode\QRCodeMoney; use App\Entity\DTO\QRCode\QRCodeMoney;
use App\Entity\QRCode\QRCodePaymentIdentification; use App\Entity\DTO\QRCode\QRCodePaymentIdentification;
use App\Entity\QRCode\QRCodeQROptions; use App\Entity\DTO\QRCode\QRCodeQROptions;
use App\Entity\Remote\Usetreno\Edge\EdgeQRCode; use App\Entity\Remote\Usetreno\Edge\EdgeQRCode;
use App\Entity\Remote\Usetreno\Edge\EdgeQRCodeMoney; use App\Entity\Remote\Usetreno\Edge\EdgeQRCodeMoney;
use App\Entity\Remote\Usetreno\Edge\EdgeQRCodePaymentIdentification; use App\Entity\Remote\Usetreno\Edge\EdgeQRCodePaymentIdentification;
@ -19,28 +19,28 @@ class QRCodeEntityConverter
public function convert(QRCode $code): EdgeQRCode { public function convert(QRCode $code): EdgeQRCode {
return new EdgeQRCode( return new EdgeQRCode(
$code->getIban() ?? throw new MissingParameterException("iban not set"), $code->iban,
$code->getDueDate() ? $code->getDueDate()->format('Y-m-d') : throw new MissingParameterException("due date not set"), $code->dueDate->format('Y-m-d'),
$code->getMessage() ?? throw new MissingParameterException("message not set"), $code->message,
$this->convertMoney($code->getMoney() ?? throw new MissingParameterException("money not set")), $this->convertMoney($code->money),
$this->convertCodeOptions($code->getCodeQROptions() ?? throw new MissingParameterException("codeQROptions not set")), $this->convertCodeOptions($code->qrOptions),
$this->convertIdentification($code->getPaymentIdentification()) $this->convertIdentification($code->paymentIdentification)
); );
} }
protected function convertMoney(QRCodeMoney $money): EdgeQRCodeMoney protected function convertMoney(QRCodeMoney $money): EdgeQRCodeMoney
{ {
return new EdgeQRCodeMoney( return new EdgeQRCodeMoney(
$money->getAmount() ?? throw new MissingParameterException("amount not set"), $money->amount,
$money->getCurrency() ?? throw new MissingParameterException("currency not set") $money->currency
); );
} }
protected function convertCodeOptions(QRCodeQROptions $options): EdgeQRCodeQROptions protected function convertCodeOptions(QRCodeQROptions $options): EdgeQRCodeQROptions
{ {
return new EdgeQRCodeQROptions( return new EdgeQRCodeQROptions(
$options->getScale(), $options->scale,
$options->getMargin() $options->margin
); );
} }
@ -53,9 +53,9 @@ class QRCodeEntityConverter
"0" "0"
), ),
default => new EdgeQRCodePaymentIdentification( default => new EdgeQRCodePaymentIdentification(
$ident->getVariableSymbol() ?? "0", $ident->variableSymbol ?? "0",
$ident->getSpecificSymbol() ?? "0", $ident->specificSymbol ?? "0",
$ident->getConstantSymbol() ?? "0" $ident->constantSymbol ?? "0"
) )
}; };
} }

View File

@ -3,7 +3,7 @@ declare(strict_types=1);
namespace App\Service\Remote; namespace App\Service\Remote;
use App\Entity\QRCode\QRCode; use App\Entity\DTO\QRCode\QRCode;
use App\Service\CacheableQRCodeGeneratorInterface; use App\Service\CacheableQRCodeGeneratorInterface;
use App\Service\Remote\Edge\QRCodeEntityConverter; use App\Service\Remote\Edge\QRCodeEntityConverter;
use App\Service\Remote\Exception\UsetrenoQRCodeException; use App\Service\Remote\Exception\UsetrenoQRCodeException;

View File

@ -3,7 +3,7 @@ declare(strict_types=1);
namespace App\Service; namespace App\Service;
use App\Entity\QRCode\QRCode; use App\Entity\DTO\QRCode\QRCode;
readonly final class StubQRCodeGenerator implements QRCodeGeneratorInterface readonly final class StubQRCodeGenerator implements QRCodeGeneratorInterface
{ {

View File

@ -2,7 +2,10 @@
namespace App\Tests\Service\Remote; namespace App\Tests\Service\Remote;
use App\Entity\QRCode\QRCode; use App\Entity\DTO\QRCode\QRCode;
use App\Entity\DTO\QRCode\QRCodeMoney;
use App\Entity\DTO\QRCode\QRCodePaymentIdentification;
use App\Entity\DTO\QRCode\QRCodeQROptions;
use App\Entity\Remote\Usetreno\Edge\EdgeQRCode; use App\Entity\Remote\Usetreno\Edge\EdgeQRCode;
use App\Entity\Remote\Usetreno\Edge\EdgeQRCodeMoney; use App\Entity\Remote\Usetreno\Edge\EdgeQRCodeMoney;
use App\Entity\Remote\Usetreno\Edge\EdgeQRCodePaymentIdentification; use App\Entity\Remote\Usetreno\Edge\EdgeQRCodePaymentIdentification;
@ -30,57 +33,24 @@ class UsetrenoQRCodeProviderTest extends TestCase
] ]
]; ];
$edgeEntity = new EdgeQRCode( [$edgeEntity, $qrCodeEntity] = $this->createQRCodeEntityPair();
"CZ0000",
(new \DateTime("now"))->format('Y-m-d'),
"foo",
new EdgeQRCodeMoney(
100,
"CZK"
),
new EdgeQRCodeQROptions(
1,
1
),
new EdgeQRCodePaymentIdentification(
"0", "0", "0"
)
);
$entity = $this->createMock(QRCode::class); $qrCodeProvider = $this->createQRCodeProvider($successRequest, 200, $edgeEntity, $qrCodeEntity);
$data = $qrCodeProvider->generateQRCodeFromEntity($qrCodeEntity);
$qrCodeProvider = $this->createQRCodeProvider($successRequest, 200, $edgeEntity, $entity);
$data = $qrCodeProvider->generateQRCodeFromEntity($entity);
$this->assertEquals($base64Image, $data); $this->assertEquals($base64Image, $data);
} }
public function testFailureRequest() { public function testFailureRequest() {
$this->expectException(QRCodeGeneratorException::class); $this->expectException(QRCodeGeneratorException::class);
$failureRequest = [ $failureRequest = [
"error" => "internal server error", "error" => "internal server error",
]; ];
$edgeEntity = new EdgeQRCode( [$edgeEntity, $qrCodeEntity] = $this->createQRCodeEntityPair();
"CZ0000",
(new \DateTime("now"))->format('Y-m-d'),
"foo",
new EdgeQRCodeMoney(
100,
"CZK"
),
new EdgeQRCodeQROptions(
1,
1
),
new EdgeQRCodePaymentIdentification(
"0", "0", "0"
)
);
$entity = $this->createMock(QRCode::class); $qrCodeProvider = $this->createQRCodeProvider($failureRequest, 500, $edgeEntity, $qrCodeEntity);
$data = $qrCodeProvider->generateQRCodeFromEntity($qrCodeEntity);
$qrCodeProvider = $this->createQRCodeProvider($failureRequest, 500, $edgeEntity, $entity);
$data = $qrCodeProvider->generateQRCodeFromEntity($entity);
$this->assertEquals($failureRequest["data"]["base64Data"], $data); $this->assertEquals($failureRequest["data"]["base64Data"], $data);
} }
@ -107,4 +77,42 @@ class UsetrenoQRCodeProviderTest extends TestCase
return new UsetrenoQRCodeProvider($this->getLogger(), $mock, $converterMock); return new UsetrenoQRCodeProvider($this->getLogger(), $mock, $converterMock);
} }
protected function createQRCodeEntityPair() {
$edgeEntity = new EdgeQRCode(
"CZ0000",
(new \DateTime("now"))->format('Y-m-d'),
"foo",
new EdgeQRCodeMoney(
100,
"CZK"
),
new EdgeQRCodeQROptions(
1,
1
),
new EdgeQRCodePaymentIdentification(
"0", "0", "0"
)
);
$qrCodeEntity = new QRCode(
"CZ0000",
new \DateTimeImmutable("now"),
"foo",
new QRCodeMoney(
100,
"CZK"
),
new QRCodeQROptions(
1,
1
),
new QRCodePaymentIdentification(
"0", "0", "0"
)
);
return [$edgeEntity, $qrCodeEntity];
}
} }