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
54 changes: 54 additions & 0 deletions docs/manual/resources/order.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,60 @@ foreach ($result->wait(60)->getTickets() as $ticket) {
$ticket->getId();
$ticket->getStatus();
}

// Fetch all Batches objects generated for the operation
foreach ($result->getBatches() as $batch) {
$response = $batch->getResponse();
$batchId = $response->getBatchId();

// Fetch all tickets generated for the operation
foreach ($response->getTickets() as $ticket) {
$ticket->getId();
$ticket->getStatus();
}
Comment thread
mdumoulin marked this conversation as resolved.

// Fetch all reports generated for the operation
foreach ($response->getReport() as $operationReport) {
$operationReport['id]'];
$operationReport['channelName'];
$operationReport['reference'];
$operationReport['state'];
$operationReport['message'];
}
}

// Both writing will work
$tickets = $result->wait(60)->getTickets();
$batchs = $result->wait(60)->getBatches();

// But if you want to check what append for each operation :
$ignoredOperations = [];
$failedOperations = []:
$succeedOperations = [];
$stillProcessingOperations = [];

foreach ($result->wait(60)->getBatches() as $batch) {
$response = $batch->getResponse();

foreach ($response->getTickets() as $ticket) {
if (null !== $ticket->getFinishedAt()) {
if ('succeed' === $ticket->getStatus()) {
$succeedOperations[] = $ticket->getPayload()['id'];
} else {
$failedOperations[] = $ticket->getPayload()['id'];
}
} else {
$stillProcessingOperations = $ticket->getPayload()['id'];
}
}

foreach ($response->getReport() as $operationReport) {
if ('ignored' === $operationReport['state']) {
$ignoredOperations[] = $operationReport['id'];
}
}
}

```

### Accept
Expand Down
20 changes: 1 addition & 19 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -262,32 +262,14 @@ parameters:
message: '#^Call to an undefined method iterable\<ShoppingFeed\\Sdk\\Api\\Task\\TicketResource\>&Traversable\:\:wait\(\)\.$#'
identifier: method.notFound
count: 1
path: src/Api/Order/OrderOperationResult.php
path: src/Api/Order/OrderOperationResponse.php

-
message: '#^Method ShoppingFeed\\Sdk\\Api\\Order\\OrderOperationResult\:\:__construct\(\) has parameter \$resources with no value type specified in iterable type array\.$#'
identifier: missingType.iterableValue
count: 1
path: src/Api/Order/OrderOperationResult.php

-
message: '#^Method ShoppingFeed\\Sdk\\Api\\Order\\OrderOperationResult\:\:setBatches\(\) has no return type specified\.$#'
identifier: missingType.return
count: 1
path: src/Api/Order/OrderOperationResult.php

-
message: '#^Method ShoppingFeed\\Sdk\\Api\\Order\\OrderOperationResult\:\:setBatches\(\) has parameter \$resources with no value type specified in iterable type array\.$#'
identifier: missingType.iterableValue
count: 1
path: src/Api/Order/OrderOperationResult.php

-
message: '#^PHPDoc tag @var above a method has no effect\.$#'
identifier: varTag.misplaced
count: 1
path: src/Api/Order/OrderOperationResult.php

-
message: '#^Cannot call method withAddedHref\(\) on ShoppingFeed\\Sdk\\Hal\\HalLink\|null\.$#'
identifier: method.nonObject
Expand Down
23 changes: 23 additions & 0 deletions src/Api/Order/OrderOperationBatch.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace ShoppingFeed\Sdk\Api\Order;

use ShoppingFeed\Sdk\Hal\HalResource;

Comment thread
olivierh94 marked this conversation as resolved.
/**
* This class was designed this way to make possible to add the request associate to the batch in future version.
*/
class OrderOperationBatch
{
private OrderOperationResponse $response;

public function __construct(HalResource $resource)
{
$this->response = new OrderOperationResponse($resource);
}

public function getResponse(): OrderOperationResponse
{
return $this->response;
}
}
83 changes: 83 additions & 0 deletions src/Api/Order/OrderOperationResponse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php

namespace ShoppingFeed\Sdk\Api\Order;

use ShoppingFeed\Sdk\Api\Task;
use ShoppingFeed\Sdk\Exception\RuntimeException;
use ShoppingFeed\Sdk\Hal\HalLink;
use ShoppingFeed\Sdk\Hal\HalResource;

class OrderOperationResponse
{
private string $batchId;

private Task\TicketDomain $ticketDomain;

/**
* @var array{int, array{
* id: int|null,
* channelName: string|null,
* reference: string|null,
* state: string,
* message: string
* }} $report
*/
private array $report;

public function __construct(HalResource $resource)
{
$this->batchId = $resource->getProperty('id');
$this->report = $resource->getProperty('report');
$link = $resource->getLink('ticket');

if (! $link instanceof HalLink) {
throw new RuntimeException('Ticket link is missing from the OrderOperationResponse resource.');
}
Comment thread
olivierh94 marked this conversation as resolved.

$this->ticketDomain = new Task\TicketDomain($link);
}

public function getBatchId(): string
{
return $this->batchId;
}

/**
* Get the iterator for all tickets generated by the operation
*
* @return Task\TicketResource[]
*/
public function getTickets(): iterable
{
yield from $this->ticketDomain->getByBatch($this->batchId);
}

/**
* Wait for all tickets to be processed.
*
* $timeout Seconds to wait for each batch until stop
* $sleepSecs Seconds to wait between to calls
*
* @return $this The current instance
*/
public function wait(?int $timeout = null, int $sleepSecs = 1): self
{
$this->ticketDomain->getByBatch($this->batchId)->wait($timeout, $sleepSecs);

return $this;
}

/**
* @return array{int, array{
* id: int|null,
* channelName: string|null,
* reference: string|null,
* state: string,
* message: string
* }}
*/
public function getReport(): array
{
return $this->report;
}
}
46 changes: 26 additions & 20 deletions src/Api/Order/OrderOperationResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@

namespace ShoppingFeed\Sdk\Api\Order;

use ShoppingFeed\Sdk\Api\Task;

class OrderOperationResult
{
/** @var Task\TicketDomain[] */
private $batches;
/** @var OrderOperationBatch[] $batches */
private array $batches;

public function __construct(array $resources = [])
{
Expand All @@ -17,14 +15,12 @@ public function __construct(array $resources = [])
/**
* Get the iterator for all tickets generated by the operation
*
* @return Task\TicketResource[]|\Traversable
* @return \ShoppingFeed\Sdk\Api\Task\TicketResource[]|\Traversable
*/
public function getTickets()
{
foreach ($this->batches as $id => $domain) {
foreach ($domain->getByBatch($id) as $ticket) {
yield $ticket;
}
foreach ($this->batches as $batch) {
yield from $batch->getResponse()->getTickets();
}
}

Expand All @@ -33,39 +29,49 @@ public function getTickets()
*/
public function getBatchIds()
{
return array_keys($this->batches);
$batchIds = [];

foreach ($this->batches as $batch) {
$batchIds[] = $batch->getResponse()->getBatchId();
}

return $batchIds;
}

/**
* Wait for all tickets to be processed.
*
* @param int $timeout Seconds to wait for each batch until stop
* @param ?int $timeout Seconds to wait for each batch until stop
* @param int $sleepSecs Seconds to wait between to calls
*
* @return $this The current instance
*/
public function wait($timeout = null, $sleepSecs = 1)
{
foreach ($this->batches as $id => $domain) {
$domain->getByBatch($id)->wait($timeout, $sleepSecs);
foreach ($this->batches as $batch) {
$batch->getResponse()->wait((int) $timeout, (int) $sleepSecs);
}

return $this;
}

/**
* @var \ShoppingFeed\Sdk\Hal\HalResource[] $resources
* @param \ShoppingFeed\Sdk\Hal\HalResource[] $resources
*/
private function setBatches(array $resources)
private function setBatches(array $resources): void
{
$this->batches = [];

foreach ($resources as $resource) {
// Stored element is the domain in order to avoid early api calls
$batchId = $resource->getProperty('id');
$domain = new Task\TicketDomain($resource->getLink('ticket'));

$this->batches[$batchId] = $domain;
$this->batches[] = new OrderOperationBatch($resource);
}
}

/**
* @return OrderOperationBatch[]
*/
public function getBatches(): array
{
return $this->batches;
}
}
59 changes: 59 additions & 0 deletions tests/unit/Api/Order/OrderOperationResponseTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

namespace ShoppingFeed\Sdk\Test\Api\Order;

use ShoppingFeed\Sdk\Api\Order\OrderOperationResponse;
use ShoppingFeed\Sdk\Api\Order\OrderOperationResult;
use ShoppingFeed\Sdk\Hal\HalResource;

class OrderOperationResponseTest extends OrderOperationTestCase
{
private HalResource $resource;
private OrderOperationResponse $response;

protected function setUp(): void
{
parent::setUp();
$this->resource = $this->createResourceMock('a', 1, 'REF123', $this->link);
$this->response = new OrderOperationResponse($this->resource);
}

protected function getInstance(): OrderOperationResponse|OrderOperationResult
{
return $this->response;
}

protected function getWaitCallCount(): int
{
return 1;
}

public function testBatchId(): void
{
$this->assertSame('a', $this->response->getBatchId());
}

public function testGetReport(): void
{
$expectedReport = [
[
'id' => 1,
'channelName' => 'Channel A',
'reference' => 'REF123',
'state' => 'success',
'message' => 'Order processed successfully.'
]
];

$this->assertSame($expectedReport, $this->response->getReport());
}

public function testExceptionOnMissingTicketLink(): void
{
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('Ticket link is missing from the OrderOperationResponse resource.');

$resource = $this->createResourceMock('a', 1, 'REF123');
new OrderOperationResponse($resource);
}
}
Loading