Skip to content

Commit

Permalink
Implement Financials Api
Browse files Browse the repository at this point in the history
  • Loading branch information
marcvdm committed Nov 6, 2023
1 parent 834a68e commit 4934032
Show file tree
Hide file tree
Showing 10 changed files with 389 additions and 0 deletions.
67 changes: 67 additions & 0 deletions src/Api/FinancialApi.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php declare(strict_types = 1);

namespace SandwaveIo\RealtimeRegister\Api;

use SandwaveIo\RealtimeRegister\Domain\ExchangeRates;
use SandwaveIo\RealtimeRegister\Domain\Transaction;
use SandwaveIo\RealtimeRegister\Domain\TransactionCollection;

final class FinancialApi extends AbstractApi
{
/**
* @see https://dm.realtimeregister.com/docs/api/transactions/get
*
* @param int $transactionId
*
* @throws \Exception
*
* @return Transaction
*/
public function getTransaction(int $transactionId): Transaction
{
$response = $this->client->get(sprintf('v2/billing/financialtransactions/%d', $transactionId));
return Transaction::fromArray($response->json());
}

/**
* @see https://dm.realtimeregister.com/docs/api/transactions/list
*
* @param int|null $limit
* @param int|null $offset
* @param string|null $search
* @param array<string, string> $parameters
*
* @return TransactionCollection
*/
public function listTransactions(
?int $limit = null,
?int $offset = null,
?string $search = null,
?array $parameters = null
): TransactionCollection {
$query = [];
if (! is_null($limit)) {
$query['limit'] = $limit;
}
if (! is_null($offset)) {
$query['offset'] = $offset;
}
if (! is_null($search)) {
$query['q'] = $search;
}
if (! is_null($parameters)) {
$query = array_merge($parameters, $query);
}

$response = $this->client->get('v2/billing/financialtransactions', $query);

return TransactionCollection::fromArray($response->json());
}

/* @see https://dm.realtimeregister.com/docs/api/exchangerates */
public function exchangeRates(string $currency): ExchangeRates
{
$response = $this->client->get("v2/exchangerates/{$currency}");
return ExchangeRates::fromArray($response->json());
}
}
28 changes: 28 additions & 0 deletions src/Domain/ExchangeRates.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php declare(strict_types = 1);

namespace SandwaveIo\RealtimeRegister\Domain;

class ExchangeRates implements DomainObjectInterface
{
private function __construct(public readonly string $currency, public readonly ?array $exchangerates = null)
{
}

public static function fromArray(array $json): self
{
return new ExchangeRates(
currency: $json['currency'],
exchangerates: $json['exchangerates'] ?? null
);
}

public function toArray(): array
{
return array_filter([
'currency' => $this->currency,
'exchangerates' => $this->exchangerates ?? null,
], function ($x) {
return ! is_null($x);
});
}
}
75 changes: 75 additions & 0 deletions src/Domain/Transaction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

declare(strict_types = 1);

namespace SandwaveIo\RealtimeRegister\Domain;

use DateTimeImmutable;
use DateTimeInterface;
use Exception;
use Webmozart\Assert\Assert;

final class Transaction implements DomainObjectInterface
{
private function __construct(
public int $id,
public string $customer,
public DateTimeInterface $date,
public int $amount,
public string $currency,
public int $processId,
public string $processType,
public string $processIdentifier,
public string $processAction,
/** @var array<string, int>|null */
public ?array $chargesPerAccount,
public ?BillableCollection $billables
) {
}

public function toArray(): array
{
return array_filter(
[
'id' => $this->id,
'customer' => $this->customer,
'date' => $this->date->format('Y-m-d\TH:i:s\Z'),
'amount' => $this->amount,
'currency' => $this->currency,
'processId' => $this->processId,
'processType' => $this->processType,
'processIdentifier' => $this->processIdentifier,
'processAction' => $this->processAction,
'chargesPerAccount' => $this->chargesPerAccount,
'billables' => $this->billables?->toArray(),
],
static function ($x) {
return ! is_null($x);
}
);
}

/**
* @throws Exception
*/
public static function fromArray(array $json): Transaction
{
if (array_key_exists('chargesPerAccount', $json)) {
Assert::isArray($json['chargesPerAccount']);
}

return new Transaction(
id: $json['id'],
customer: $json['customer'],
date: new DateTimeImmutable($json['date']),
amount: $json['amount'],
currency: $json['currency'],
processId: $json['processId'],
processType: $json['processType'],
processIdentifier: $json['processIdentifier'],
processAction: $json['processAction'],
chargesPerAccount: $json['chargesPerAccount'] ?? null,
billables: isset($json['billables']) ? BillableCollection::fromArray($json['billables']) : null
);
}
}
31 changes: 31 additions & 0 deletions src/Domain/TransactionCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types = 1);

namespace SandwaveIo\RealtimeRegister\Domain;

use Exception;

class TransactionCollection extends AbstractCollection
{
/** @var Transaction[] */
public array $entities;

public static function fromArray(array $json): TransactionCollection
{
return parent::fromArray($json);
}

public function offsetGet($offset): ?Transaction
{
return $this->entities[$offset] ?? null;
}

/**
* @throws Exception
*/
public static function parseChild(array $json): Transaction
{
return Transaction::fromArray($json);
}
}
4 changes: 4 additions & 0 deletions src/RealtimeRegister.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use SandwaveIo\RealtimeRegister\Api\CustomersApi;
use SandwaveIo\RealtimeRegister\Api\DnsTemplatesApi;
use SandwaveIo\RealtimeRegister\Api\DomainsApi;
use SandwaveIo\RealtimeRegister\Api\FinancialApi;
use SandwaveIo\RealtimeRegister\Api\NotificationsApi;
use SandwaveIo\RealtimeRegister\Api\ProcessesApi;
use SandwaveIo\RealtimeRegister\Api\ProvidersApi;
Expand Down Expand Up @@ -39,6 +40,8 @@ final class RealtimeRegister

public TLDsApi $tlds;

public FinancialApi $financial;

public function __construct(
string $apiKey,
?string $baseUrl = null,
Expand All @@ -60,5 +63,6 @@ public function setClient(AuthorizedClient $client): void
$this->providers = new ProvidersApi($client);
$this->dnstemplates = new DnsTemplatesApi($client);
$this->tlds = new TLDsApi($client);
$this->financial = new FinancialApi($client);
}
}
27 changes: 27 additions & 0 deletions tests/Clients/FinancialApiExchangeRatesTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php
declare(strict_types = 1);

namespace Clients;

use PHPUnit\Framework\TestCase;
use SandwaveIo\RealtimeRegister\Domain\ExchangeRates;
use SandwaveIo\RealtimeRegister\Tests\Helpers\MockedClientFactory;
use Webmozart\Assert\Assert;

class FinancialApiExchangeRatesTest extends TestCase
{
public function test_exchangerates(): void
{
/** @var string $responseBody */
$responseBody = json_encode(include __DIR__ . '/../Domain/data/exchangerates_valid.php');
Assert::string($responseBody);
$sdk = MockedClientFactory::makeSdk(
200,
$responseBody,
MockedClientFactory::assertRoute('GET', 'v2/exchangerates/EUR', $this)
);

$response = $sdk->financial->exchangeRates('EUR');
$this->assertInstanceOf(ExchangeRates::class, $response);
}
}
27 changes: 27 additions & 0 deletions tests/Clients/FinancialApiGetTransactionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php
declare(strict_types = 1);

namespace Clients;

use PHPUnit\Framework\TestCase;
use SandwaveIo\RealtimeRegister\Domain\Transaction;
use SandwaveIo\RealtimeRegister\Tests\Helpers\MockedClientFactory;
use Webmozart\Assert\Assert;

class FinancialApiGetTransactionTest extends TestCase
{
public function test_get_transaction(): void
{
/** @var string $responseBody */
$responseBody = json_encode(include __DIR__ . '/../Domain/data/transaction_valid.php');
Assert::string($responseBody);
$sdk = MockedClientFactory::makeSdk(
200,
$responseBody,
MockedClientFactory::assertRoute('GET', 'v2/billing/financialtransactions/654563', $this)
);

$response = $sdk->financial->getTransaction(654563);
$this->assertInstanceOf(Transaction::class, $response);
}
}
102 changes: 102 additions & 0 deletions tests/Clients/FinancialApiListTransactionsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?php
declare(strict_types = 1);

namespace Clients;

use PHPUnit\Framework\TestCase;
use SandwaveIo\RealtimeRegister\Tests\Helpers\MockedClientFactory;
use Webmozart\Assert\Assert;

class FinancialApiListTransactionsTest extends TestCase
{
public function test_list_transactions(): void
{
/** @var string $responseBody */
$responseBody = json_encode(
[
'entities' => [
include __DIR__ . '/../Domain/data/transaction_valid.php',
include __DIR__ . '/../Domain/data/transaction_valid.php',
include __DIR__ . '/../Domain/data/transaction_valid.php',
],
'pagination' => [
'total' => 3,
'offset' => 0,
'limit' => 10,
],
]
);
Assert::string($responseBody);
$sdk = MockedClientFactory::makeSdk(
200,
$responseBody,
MockedClientFactory::assertRoute('GET', 'v2/billing/financialtransactions', $this)
);

$sdk->financial->listTransactions();
}

public function test_list_with_queries(): void
{
/** @var string $responseBody */
$responseBody = json_encode(
[
'entities' => [
include __DIR__ . '/../Domain/data/transaction_valid.php',
include __DIR__ . '/../Domain/data/transaction_valid.php',
],
'pagination' => [
'total' => 2,
'offset' => 0,
'limit' => 2,
],
]
);
Assert::string($responseBody);

$sdk = MockedClientFactory::makeSdk(
200,
$responseBody,
MockedClientFactory::assertRoute('GET', 'v2/billing/financialtransactions', $this)
);

$sdk->financial->listTransactions(2, 0, 'identifier:eq=something');
}

public function test_list_with_search_and_parameters(): void
{
$parameters = [
'processType' => 'incomingTransfer',
'order' => '-updatedDate',
];

/** @var string $responseBody */
$responseBody = json_encode(
[
'entities' => [
include __DIR__ . '/../Domain/data/transaction_valid.php',
include __DIR__ . '/../Domain/data/transaction_valid.php',
],
'pagination' => [
'total' => 2,
'offset' => 0,
'limit' => 2,
],
]
);

$sdk = MockedClientFactory::makeSdk(
200,
$responseBody,
MockedClientFactory::assertRoute('GET', 'v2/billing/financialtransactions', $this, [
'processType' => 'incomingTransfer',
'order' => '-updatedDate',
'limit' => '2',
'offset' => '0',
'q' => 'search',
])
);

$sdk->financial->listTransactions(2, 0, 'search', $parameters);
}
}
8 changes: 8 additions & 0 deletions tests/Domain/data/exchangerates_valid.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php declare(strict_types = 1);

return [
'currency' => 'EUR',
'exchangerates' => [
'USD' => 1000000,
],
];
Loading

0 comments on commit 4934032

Please sign in to comment.