Skip to content

Commit

Permalink
Manage partial shipment (#113)
Browse files Browse the repository at this point in the history
- Add a function to get Shipment list for a order
- Operation ship updated to allow partial shipment
  • Loading branch information
hbouffi authored Jan 2, 2024
1 parent 40d2020 commit cea1e01
Show file tree
Hide file tree
Showing 10 changed files with 203 additions and 14 deletions.
33 changes: 31 additions & 2 deletions docs/manual/resources/order.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,9 @@ The ship operation accepts 3 parameters :
1. [mandatory] `$reference` : Order reference (eg: 'reference1')
2. [mandatory] `$channelName` : The channel where the order is from (eg: 'amazon')
3. [optional] `$carrier` : The carrier name used for the shipment (eq: 'ups')
3. [optional] `$trackingNumber` : Tracking number (eq: '01234598abcdef')
3. [optional] `$trackingLink` : Tracking link (eq: 'http://tracking.url/')
4. [optional] `$trackingNumber` : Tracking number (eq: '01234598abcdef')
5. [optional] `$trackingLink` : Tracking link (eq: 'http://tracking.url/')
6. [optional] `$items` : Array of order item id and quantity to be shipped (eq: [['id' => 1234, 'quantity' => 1]])

Example :

Expand Down Expand Up @@ -279,3 +280,31 @@ $operation

$orderApi->execute($operation);
```

## Retrieve shipments
To retrieve shipments, you can use these methods :

### getShipmentsByOrder
1. [mandatory] `$orderId` : id (eg: 1234)

Example :

```php
namespace ShoppingFeed\Sdk\Api\Order;

$shipments = $orderApi->getShipmentsByOrder(1234);
```

### getShipments
In the order object :

Example :

```php
namespace ShoppingFeed\Sdk\Api\Order;

foreach($orderApi->getAll($criteria['filters']) as $order) {
$shipments = $order->getShipments();
}
```

14 changes: 11 additions & 3 deletions src/Api/Order/OrderDomain.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<?php
namespace ShoppingFeed\Sdk\Api\Order;

use ShoppingFeed\Sdk\Resource\AbstractDomainResource;
use ShoppingFeed\Sdk\Api\Order\Shipment\ShipmentDomain;
use ShoppingFeed\Sdk\Api\Order\Shipment\ShipmentResource;
use ShoppingFeed\Sdk\Resource;

/**
* @method OrderResource[] getIterator()
Expand All @@ -10,19 +12,25 @@
* @method OrderResource[] getPages(array $criteria = [])
* @method OrderResource getOne($identity)
*/
class OrderDomain extends AbstractDomainResource
class OrderDomain extends Resource\AbstractDomainResource
{
/**
* @var string
*/
protected $resourceClass = OrderResource::class;

/** @return Resource\PaginatedResourceIterator<ShipmentResource> */
public function getShipmentsByOrder(int $orderId)
{
return (new ShipmentDomain($this->link->withAddedHref($orderId . '/shipment')))->getAll();
}

/**
* @param OrderOperation $operation
*
* @return OrderOperationResult
*/
public function execute(OrderOperation $operation)
public function execute(OrderOperation $operation): OrderOperationResult
{
return $operation->execute($this->link);
}
Expand Down
22 changes: 15 additions & 7 deletions src/Api/Order/OrderOperation.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,23 +90,31 @@ public function cancel($reference, $channelName, $reason = '')
/**
* Notify market place of order shipment sent
*
* @param string $reference Order reference
* @param string $channelName Channel to notify
* @param string $carrier Optional carrier name
* @param string $trackingNumber Optional tracking number
* @param string $trackingLink Optional tracking link
* @param string $reference Order reference
* @param string $channelName Channel to notify
* @param string $carrier Optional carrier name
* @param string $trackingNumber Optional tracking number
* @param string $trackingLink Optional tracking link
* @param array<array{id: int, quantity: int}> $items Optional items
*
* @return OrderOperation
*
* @throws Exception\InvalidArgumentException
*/
public function ship($reference, $channelName, $carrier = '', $trackingNumber = '', $trackingLink = '')
public function ship(
$reference,
$channelName,
$carrier = '',
$trackingNumber = '',
$trackingLink = '',
$items = []
)
{
$this->addOperation(
$reference,
$channelName,
self::TYPE_SHIP,
compact('carrier', 'trackingNumber', 'trackingLink')
compact('carrier', 'trackingNumber', 'trackingLink', 'items')
);

return $this;
Expand Down
16 changes: 14 additions & 2 deletions src/Api/Order/OrderResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
namespace ShoppingFeed\Sdk\Api\Order;

use ShoppingFeed\Sdk\Api\Channel\ChannelResource;
use ShoppingFeed\Sdk\Resource\AbstractResource;
use ShoppingFeed\Sdk\Api\Order\Shipment\ShipmentDomain;
use ShoppingFeed\Sdk\Api\Order\Shipment\ShipmentResource;
use ShoppingFeed\Sdk\Resource;

class OrderResource extends AbstractResource
class OrderResource extends Resource\AbstractResource
{
/**
* @return int
Expand Down Expand Up @@ -124,4 +126,14 @@ public function getChannel()
$this->resource->getFirstResource('channel')
);
}

/**
* @return Resource\PaginatedResourceIterator<ShipmentResource>
*/
public function getShipments()
{
$link = $this->resource->getLink('self');

return (new ShipmentDomain($link->withAddedHref('/shipment')))->getAll();
}
}
10 changes: 10 additions & 0 deletions src/Api/Order/Shipment/ShipmentDomain.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace ShoppingFeed\Sdk\Api\Order\Shipment;

use ShoppingFeed\Sdk\Resource\AbstractDomainResource;

class ShipmentDomain extends AbstractDomainResource
{
protected $resourceClass = ShipmentResource::class;
}
38 changes: 38 additions & 0 deletions src/Api/Order/Shipment/ShipmentResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace ShoppingFeed\Sdk\Api\Order\Shipment;

use ShoppingFeed\Sdk\Resource\AbstractResource;

class ShipmentResource extends AbstractResource
{
public function getCarrier(): string
{
return (string) $this->getProperty('carrier');
}

public function getTrackingNumber(): string
{
return (string) $this->getProperty('trackingNumber');
}

public function getTrackingUrl(): string
{
return (string) $this->getProperty('trackingLink');
}

public function getReturnInfo(): array
{
return (array) $this->getProperty('returnInfo');
}

public function getCreatedAt(): \DateTimeImmutable
{
return $this->getPropertyDatetime('createdAt');
}

public function getItems(): ?array
{
return $this->getProperty('items');
}
}
23 changes: 23 additions & 0 deletions tests/unit/Api/Order/OrderDomainTest.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
<?php

namespace ShoppingFeed\Sdk\Test\Api\Order;

use PHPUnit\Framework\TestCase;
use ShoppingFeed\Sdk\Api\Order\OrderDomain;
use ShoppingFeed\Sdk\Api\Order\OrderOperation;
use ShoppingFeed\Sdk\Api\Order\OrderOperationResult;
use ShoppingFeed\Sdk\Api\Order\Shipment\ShipmentResource;
use ShoppingFeed\Sdk\Hal\HalLink;
use ShoppingFeed\Sdk\Hal\HalResource;

class OrderDomainTest extends TestCase
{
Expand All @@ -22,4 +25,24 @@ public function testExecute()
$instance = new OrderDomain($link);
$instance->execute($operations);
}

public function testShipmentGetters(): void
{
$orderId = 1234;

$link = $this->createMock(HalLink::class);
$link
->expects($this->once())
->method('withAddedHref')
->with($orderId . '/shipment')
->willReturn($link);

$link
->expects($this->once())
->method('get')
->willReturn($this->createMock(HalResource::class));

$instance = new OrderDomain($link);
$instance->getShipmentsByOrder($orderId);
}
}
1 change: 1 addition & 0 deletions tests/unit/Api/Order/OrderOperationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ public function testShipOperation()
'carrier' => 'ups',
'trackingNumber' => '123654abc',
'trackingLink' => 'http://tracking.lnk',
'items' => [],
]
);

Expand Down
29 changes: 29 additions & 0 deletions tests/unit/Api/Order/OrderResourceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
namespace ShoppingFeed\Sdk\Test\Api\Order;

use ShoppingFeed\Sdk;
use ShoppingFeed\Sdk\Hal\HalLink;
use ShoppingFeed\Sdk\Hal\HalResource;
use ShoppingFeed\Sdk\Resource\PaginatedResourceIterator;

class OrderResourceTest extends Sdk\Test\Api\AbstractResourceTest
{
Expand Down Expand Up @@ -55,6 +58,7 @@ public function setUp(): void
'item2' => 'alias2',
],
];

}

public function testPropertiesGetters()
Expand Down Expand Up @@ -127,4 +131,29 @@ public function testGetChannel()

$this->assertInstanceOf(Sdk\Api\Channel\ChannelResource::class, $channel);
}

public function testGetShipments(): void
{
$resource = $this->initHalResourceProperties();
$instance = new Sdk\Api\Order\OrderResource($this->halResource);

$resource
->expects($this->any())
->method('getLink')
->with('self')
->willReturn($link = $this->createMock(HalLink::class));

$link
->expects($this->once())
->method('withAddedHref')
->with('/shipment')
->willReturn($link);

$link
->expects($this->once())
->method('get')
->willReturn($this->createMock(HalResource::class));

$this->assertInstanceOf(PaginatedResourceIterator::class, $instance->getShipments());
}
}
31 changes: 31 additions & 0 deletions tests/unit/Api/Order/Shipment/ShipmentResourceTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php
namespace ShoppingFeed\Sdk\Test\Api\Order\Shipment;

use ShoppingFeed\Sdk;

class ShipmentResourceTest extends Sdk\Test\Api\AbstractResourceTest
{
public function testPropertiesGetters(): void
{
$this->initHalResourceProperties([
'items' => null,
'carrier' => 'ES_CORREOS',
'trackingNumber' => 'PQ9P3N0710096540184000K',
'trackingLink' => 'https://url.test/link',
'returnInfo' => [
'carrier' => null,
'trackingNumber' => null,
],
'createdAt' => '2023-11-28T14:25:18+00:00',
]);

$instance = new Sdk\Api\Order\Shipment\ShipmentResource($this->halResource);

$this->assertNull($instance->getItems());
$this->assertEquals('ES_CORREOS', $instance->getCarrier());
$this->assertEquals('PQ9P3N0710096540184000K', $instance->getTrackingNumber());
$this->assertEquals('https://url.test/link', $instance->getTrackingUrl());
$this->assertEquals(['carrier' => null, 'trackingNumber' => null], $instance->getReturnInfo());
$this->assertEquals(new \DateTimeImmutable('2023-11-28T14:25:18+00:00'), $instance->getCreatedAt());
}
}

0 comments on commit cea1e01

Please sign in to comment.