From d3c030f8d23bab0e049a18fbc57fcb2e02d4594c Mon Sep 17 00:00:00 2001 From: ging-dev Date: Fri, 26 Jul 2024 18:36:08 +0700 Subject: [PATCH] feat: better ux --- README.md | 21 ++++++----- src/Api/AuthenticatedApi.php | 34 +++++++++--------- src/Api/UnauthenticatedApi.php | 23 +++--------- src/Builder/BodyBuilder.php | 16 +++++---- src/Builder/TransactionBuilder.php | 58 ++++++++++++++++++++++++++++++ src/Enum/TransactionType.php | 10 ++++++ src/IPayClient.php | 9 +++-- 7 files changed, 118 insertions(+), 53 deletions(-) create mode 100644 src/Builder/TransactionBuilder.php create mode 100644 src/Enum/TransactionType.php diff --git a/README.md b/README.md index 5721ee1..fcab3b0 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ declare(strict_types=1); +use IPay\Enum\TransactionType; use IPay\IPayClient; require __DIR__.'/vendor/autoload.php'; @@ -12,15 +13,17 @@ require __DIR__.'/vendor/autoload.php'; $ipay = IPayClient::create(); try { - $session = $ipay->guest()->login([ - 'userName' => 'yourUsername', - 'accessCode' => 'yourPassword' - ]); - - foreach ($session->historyTransactions([ - 'accountNumber' => $session->customer->accountNumber, - 'startDate' => new \DateTimeImmutable('-5 days'), - ]) as $transaction) { + $session = $ipay->login( + userName: 'username', + accessCode: 'password', + ); + + $transactions = $session->transactions() + ->type(TransactionType::CREDIT) + ->today() + ->getIterator(); + + foreach ($transactions as $transaction) { echo $transaction->remark.PHP_EOL; } } catch (Throwable $e) { diff --git a/src/Api/AuthenticatedApi.php b/src/Api/AuthenticatedApi.php index e5bea86..44a485d 100644 --- a/src/Api/AuthenticatedApi.php +++ b/src/Api/AuthenticatedApi.php @@ -2,6 +2,7 @@ namespace IPay\Api; +use IPay\Builder\TransactionBuilder; use IPay\Entity\Account; use IPay\Entity\Customer; use IPay\Entity\Transaction; @@ -11,6 +12,8 @@ use Symfony\Component\VarExporter\LazyGhostTrait; /** + * @psalm-import-type ParametersType from TransactionBuilder + * * @extends AbstractApi */ final class AuthenticatedApi extends AbstractApi @@ -63,19 +66,24 @@ private function accounts(): array )->toArray(); } + public function transactions(?string $accountNumber = null): TransactionBuilder + { + return new TransactionBuilder( + ['accountNumber' => $accountNumber ?? $this->customer->accountNumber], + $this, + ); + } + /** - * @param array{ - * accountNumber?: string, - * tranType?: 'Credit'|'Debit'|'', - * startDate?: \DateTimeInterface, - * endDate?: \DateTimeInterface, - * } $parameters + * @internal + * + * @param ParametersType $parameters * - * @return iterable + * @return \Traversable * * @throws \IPay\Exception\SessionException */ - public function historyTransactions(array $parameters): iterable + public function historyTransactions(array $parameters): \Traversable { $datetimeNormalizer = static function ( Options $resolver, @@ -85,8 +93,8 @@ public function historyTransactions(array $parameters): iterable }; $resolver = self::createOptionsResolver() - ->setRequired([ - 'accountNumber', + ->setRequired('accountNumber') + ->setDefined([ 'tranType', 'startDate', 'endDate', @@ -97,12 +105,6 @@ public function historyTransactions(array $parameters): iterable ->setAllowedTypes('endDate', \DateTimeInterface::class) ->setNormalizer('startDate', $datetimeNormalizer) ->setNormalizer('endDate', $datetimeNormalizer) - ->setDefaults([ - 'accountNumber' => $this->customer->accountNumber, - 'tranType' => 'Credit', - 'startDate' => new \DateTimeImmutable(), - 'endDate' => new \DateTimeImmutable(), - ]) ; $parameters = $resolver->resolve($parameters); diff --git a/src/Api/UnauthenticatedApi.php b/src/Api/UnauthenticatedApi.php index 3229fab..317491b 100644 --- a/src/Api/UnauthenticatedApi.php +++ b/src/Api/UnauthenticatedApi.php @@ -8,30 +8,15 @@ use Nette\Utils\Random; /** + * @internal + * * @extends AbstractApi */ final class UnauthenticatedApi extends AbstractApi { - /** - * @param array{ - * userName: string, - * accessCode: string, - * } $credentials - * - * @throws \IPay\Exception\LoginException - */ - public function login(array $credentials): AuthenticatedApi + public function login(string $userName, string $accessCode): AuthenticatedApi { - $resolver = self::createOptionsResolver() - ->setRequired([ - 'userName', - 'accessCode', - ]) - ->setAllowedTypes('userName', 'string') - ->setAllowedTypes('accessCode', 'string') - ; - - $parameters = $resolver->resolve($credentials) + $this->bypassCaptcha(); + $parameters = get_defined_vars() + $this->bypassCaptcha(); /** @var array{sessionId: string, ...} */ $result = $this->post('signIn', $parameters); diff --git a/src/Builder/BodyBuilder.php b/src/Builder/BodyBuilder.php index 56a7693..35c36b6 100644 --- a/src/Builder/BodyBuilder.php +++ b/src/Builder/BodyBuilder.php @@ -7,27 +7,29 @@ /** * @extends \ArrayObject + * + * @psalm-type ParametersType = string[] */ final class BodyBuilder extends \ArrayObject implements \Stringable, \JsonSerializable { /** - * @param string[] $data + * @param ParametersType $array */ - private function __construct(array $data) + private function __construct(array $array) { - parent::__construct($data); + parent::__construct($array); } /** - * @param string[] $data + * @param ParametersType $parameters */ - public static function from(array $data): static + public static function from(array $parameters): static { - return new static($data); + return new static($parameters); } /** - * @param string[] $parameters + * @param ParametersType $parameters */ public function enhance(array $parameters): static { diff --git a/src/Builder/TransactionBuilder.php b/src/Builder/TransactionBuilder.php new file mode 100644 index 0000000..9616217 --- /dev/null +++ b/src/Builder/TransactionBuilder.php @@ -0,0 +1,58 @@ +, + * startDate?: \DateTimeInterface, + * endDate?: \DateTimeInterface, + * } + * + * @implements \IteratorAggregate + */ +final class TransactionBuilder implements \IteratorAggregate +{ + /** + * @param ParametersType $parameters + */ + public function __construct( + private array $parameters, + private AuthenticatedApi $api, + ) { + } + + public function between( + \DateTimeInterface $from, + \DateTimeInterface $to, + ): self { + $this->parameters['startDate'] = $from; + $this->parameters['endDate'] = $to; + + return $this; + } + + public function today(): self + { + $today = new \DateTimeImmutable(); + $this->between($today, $today); + + return $this; + } + + public function type(TransactionType $type): self + { + $this->parameters['tranType'] = $type->value; + + return $this; + } + + public function getIterator(): \Traversable + { + return $this->api->historyTransactions($this->parameters); + } +} diff --git a/src/Enum/TransactionType.php b/src/Enum/TransactionType.php new file mode 100644 index 0000000..6461d13 --- /dev/null +++ b/src/Enum/TransactionType.php @@ -0,0 +1,10 @@ +client; } - public function guest(): UnauthenticatedApi + /** + * @throws Exception\LoginException + */ + public function login(string $userName, string $accessCode): AuthenticatedApi { - return new UnauthenticatedApi($this, new UnauthenticatedSession()); + return (new UnauthenticatedApi($this, new UnauthenticatedSession())) + ->login($userName, $accessCode); } }