Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Financials Api #78

Merged
merged 1 commit into from
Dec 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading