Skip to content
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
30 changes: 30 additions & 0 deletions src/Models/LedgerItem.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace AccessGrid\Models;

use AccessGrid\AccessGridClient;

class LedgerItem
{
private AccessGridClient $client;
public ?string $id;
public ?string $createdAt;
public $amount;
public ?string $kind;
public ?array $metadata;
public ?LedgerItemAccessPass $accessPass;

public function __construct(AccessGridClient $client, array $data)
{
$this->client = $client;
$this->id = $data['id'] ?? null;
$this->createdAt = $data['created_at'] ?? null;
$this->amount = $data['amount'] ?? null;
$this->kind = $data['kind'] ?? null;
$this->metadata = $data['metadata'] ?? null;

$this->accessPass = isset($data['access_pass'])
? new LedgerItemAccessPass($client, $data['access_pass'])
: null;
}
}
30 changes: 30 additions & 0 deletions src/Models/LedgerItemAccessPass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace AccessGrid\Models;

use AccessGrid\AccessGridClient;

class LedgerItemAccessPass
{
private AccessGridClient $client;
public ?string $id;
public ?string $fullName;
public ?string $state;
public ?array $metadata;
public ?string $unifiedAccessPassExId;
public ?LedgerItemPassTemplate $passTemplate;

public function __construct(AccessGridClient $client, array $data)
{
$this->client = $client;
$this->id = $data['id'] ?? null;
$this->fullName = $data['full_name'] ?? null;
$this->state = $data['state'] ?? null;
$this->metadata = $data['metadata'] ?? null;
$this->unifiedAccessPassExId = $data['unified_access_pass_ex_id'] ?? null;

$this->passTemplate = isset($data['pass_template'])
? new LedgerItemPassTemplate($client, $data['pass_template'])
: null;
}
}
25 changes: 25 additions & 0 deletions src/Models/LedgerItemPassTemplate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace AccessGrid\Models;

use AccessGrid\AccessGridClient;

class LedgerItemPassTemplate
{
private AccessGridClient $client;
public ?string $id;
public ?string $name;
public ?string $protocol;
public ?string $platform;
public ?string $useCase;

public function __construct(AccessGridClient $client, array $data)
{
$this->client = $client;
$this->id = $data['id'] ?? null;
$this->name = $data['name'] ?? null;
$this->protocol = $data['protocol'] ?? null;
$this->platform = $data['platform'] ?? null;
$this->useCase = $data['use_case'] ?? null;
}
}
31 changes: 31 additions & 0 deletions src/Models/PassTemplatePair.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace AccessGrid\Models;

use AccessGrid\AccessGridClient;

class PassTemplatePair
{
private AccessGridClient $client;
public ?string $id;
public ?string $name;
public ?string $createdAt;
public ?TemplateInfo $androidTemplate;
public ?TemplateInfo $iosTemplate;

public function __construct(AccessGridClient $client, array $data)
{
$this->client = $client;
$this->id = $data['id'] ?? null;
$this->name = $data['name'] ?? null;
$this->createdAt = $data['created_at'] ?? null;

$this->androidTemplate = isset($data['android_template'])
? new TemplateInfo($client, $data['android_template'])
: null;

$this->iosTemplate = isset($data['ios_template'])
? new TemplateInfo($client, $data['ios_template'])
: null;
}
}
21 changes: 21 additions & 0 deletions src/Models/TemplateInfo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace AccessGrid\Models;

use AccessGrid\AccessGridClient;

class TemplateInfo
{
private AccessGridClient $client;
public ?string $id;
public ?string $name;
public ?string $platform;

public function __construct(AccessGridClient $client, array $data)
{
$this->client = $client;
$this->id = $data['id'] ?? null;
$this->name = $data['name'] ?? null;
$this->platform = $data['platform'] ?? null;
}
}
36 changes: 36 additions & 0 deletions src/Services/Console.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

use AccessGrid\AccessGridClient;
use AccessGrid\Models\Template;
use AccessGrid\Models\PassTemplatePair;
use AccessGrid\Models\LedgerItem;

class Console
{
Expand Down Expand Up @@ -70,6 +72,40 @@ public function eventLog(array $data): array
}, $events);
}

/**
* List pass template pairs
*/
public function listPassTemplatePairs(array $params = []): array
{
$response = $this->client->get('/v1/console/pass-template-pairs', $params);

if (isset($response['pass_template_pairs'])) {
$response['pass_template_pairs'] = array_map(
fn($pair) => new PassTemplatePair($this->client, $pair),
$response['pass_template_pairs']
);
}

return $response;
}

/**
* List ledger items
*/
public function listLedgerItems(array $params = []): array
{
$response = $this->client->get('/v1/console/ledger-items', $params);

if (isset($response['ledger_items'])) {
$response['ledger_items'] = array_map(
fn($item) => new LedgerItem($this->client, $item),
$response['ledger_items']
);
}

return $response;
}

/**
* Get iOS provisioning identifiers for preflight
*/
Expand Down
172 changes: 172 additions & 0 deletions tests/Models/LedgerItemTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
<?php

namespace AccessGrid\Tests\Models;

use AccessGrid\Tests\TestCase;
use AccessGrid\Models\LedgerItem;
use AccessGrid\Models\LedgerItemAccessPass;
use AccessGrid\Models\LedgerItemPassTemplate;

class LedgerItemTest extends TestCase
{
public function testConstructionWithFullData(): void
{
$data = [
'created_at' => '2025-06-15T10:30:00Z',
'amount' => 1.50,
'id' => 'li_123',
'ex_id' => 'li_123',
'kind' => 'access_pass_issued',
'metadata' => ['access_pass_ex_id' => 'pass_456'],
'access_pass' => [
'id' => 'pass_456',
'ex_id' => 'pass_456',
'full_name' => 'Jane Doe',
'state' => 'active',
'metadata' => ['department' => 'engineering'],
'unified_access_pass_ex_id' => 'uap_789',
'pass_template' => [
'id' => 'tmpl_abc',
'ex_id' => 'tmpl_abc',
'name' => 'Employee Badge',
'protocol' => 'desfire',
'platform' => 'apple',
'use_case' => 'employee_badge',
],
],
];

$item = new LedgerItem($this->client, $data);

$this->assertEquals('li_123', $item->id);
$this->assertEquals('2025-06-15T10:30:00Z', $item->createdAt);
$this->assertEquals(1.50, $item->amount);
$this->assertEquals('access_pass_issued', $item->kind);
$this->assertEquals('pass_456', $item->metadata['access_pass_ex_id']);

$this->assertInstanceOf(LedgerItemAccessPass::class, $item->accessPass);
$this->assertEquals('pass_456', $item->accessPass->id);
$this->assertEquals('Jane Doe', $item->accessPass->fullName);
$this->assertEquals('active', $item->accessPass->state);
$this->assertEquals('engineering', $item->accessPass->metadata['department']);
$this->assertEquals('uap_789', $item->accessPass->unifiedAccessPassExId);

$this->assertInstanceOf(LedgerItemPassTemplate::class, $item->accessPass->passTemplate);
$this->assertEquals('tmpl_abc', $item->accessPass->passTemplate->id);
$this->assertEquals('Employee Badge', $item->accessPass->passTemplate->name);
$this->assertEquals('desfire', $item->accessPass->passTemplate->protocol);
$this->assertEquals('apple', $item->accessPass->passTemplate->platform);
$this->assertEquals('employee_badge', $item->accessPass->passTemplate->useCase);
}

public function testConstructionWithNullAccessPass(): void
{
$data = [
'created_at' => '2025-06-15T10:30:00Z',
'amount' => 0.75,
'id' => 'li_no_pass',
'ex_id' => 'li_no_pass',
'kind' => 'adjustment',
'metadata' => [],
'access_pass' => null,
];

$item = new LedgerItem($this->client, $data);

$this->assertEquals('li_no_pass', $item->id);
$this->assertEquals(0.75, $item->amount);
$this->assertEquals('adjustment', $item->kind);
$this->assertNull($item->accessPass);
}

public function testConstructionWithAccessPassButNoPassTemplate(): void
{
$data = [
'created_at' => '2025-06-15T10:30:00Z',
'amount' => 1.00,
'id' => 'li_no_tmpl',
'ex_id' => 'li_no_tmpl',
'kind' => 'access_pass_issued',
'metadata' => [],
'access_pass' => [
'id' => 'pass_456',
'ex_id' => 'pass_456',
'full_name' => 'John Smith',
'state' => 'active',
'metadata' => [],
],
];

$item = new LedgerItem($this->client, $data);

$this->assertInstanceOf(LedgerItemAccessPass::class, $item->accessPass);
$this->assertEquals('pass_456', $item->accessPass->id);
$this->assertEquals('John Smith', $item->accessPass->fullName);
$this->assertNull($item->accessPass->passTemplate);
$this->assertNull($item->accessPass->unifiedAccessPassExId);
}

public function testConstructionWithMinimalData(): void
{
$item = new LedgerItem($this->client, [
'id' => 'li_minimal',
'ex_id' => 'li_minimal',
]);

$this->assertEquals('li_minimal', $item->id);
$this->assertNull($item->createdAt);
$this->assertNull($item->amount);
$this->assertNull($item->kind);
$this->assertNull($item->metadata);
$this->assertNull($item->accessPass);
}

public function testConstructionWithEmptyData(): void
{
$item = new LedgerItem($this->client, []);

$this->assertNull($item->id);
$this->assertNull($item->createdAt);
$this->assertNull($item->amount);
$this->assertNull($item->kind);
$this->assertNull($item->metadata);
$this->assertNull($item->accessPass);
}

public function testIdReadsFromId(): void
{
$item = new LedgerItem($this->client, [
'id' => 'li_123',
]);

$this->assertEquals('li_123', $item->id);
}

public function testAccessPassIdReadsFromId(): void
{
$item = new LedgerItem($this->client, [
'access_pass' => [
'id' => 'pass_123',
'full_name' => 'Test User',
'state' => 'active',
],
]);

$this->assertEquals('pass_123', $item->accessPass->id);
}

public function testPassTemplateIdReadsFromId(): void
{
$item = new LedgerItem($this->client, [
'access_pass' => [
'id' => 'pass_123',
'pass_template' => [
'id' => 'tmpl_456',
'name' => 'Badge',
],
],
]);

$this->assertEquals('tmpl_456', $item->accessPass->passTemplate->id);
}
}
Loading