diff --git a/README.md b/README.md index af0f21b..fc2f733 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,19 @@ $shipment->id; You have created your first shipment! +### Create multiple shipments +``` php +$parcelsCollection = new ParcelCollection(); +$parcelsCollection->add($parcel); +$parcelsCollection->add($anotherParcel); +$shipmentsCollection = $myparcel->shipments->createbatch($parcelsCollection); + +// Get the `id` of the shipments. You may save this value for later reference. +foreach ($shipmentsCollection->collection as $shipment) { + $shipment->id; +} +``` + ### Retrieve a label A label can be retrieved by using `$shipment->id`. This will return a label in A6 format as a string. diff --git a/src/Endpoints/Shipments.php b/src/Endpoints/Shipments.php index 62c509c..9b1f5f9 100644 --- a/src/Endpoints/Shipments.php +++ b/src/Endpoints/Shipments.php @@ -4,7 +4,9 @@ use Mvdnbrk\MyParcel\Exceptions\MyParcelException; use Mvdnbrk\MyParcel\Resources\Parcel; +use Mvdnbrk\MyParcel\Resources\ParcelCollection; use Mvdnbrk\MyParcel\Resources\Shipment as ShipmentResource; +use Mvdnbrk\MyParcel\Resources\ShipmentCollection; use Mvdnbrk\MyParcel\Types\ShipmentStatus; class Shipments extends BaseEndpoint @@ -14,6 +16,11 @@ public function create(Parcel $parcel): ShipmentResource return $this->concept($parcel); } + public function createbatch(ParcelCollection $collection) + { + return $this->conceptbatch($collection); + } + public function concept(Parcel $parcel): ShipmentResource { $response = $this->performApiCall( @@ -29,6 +36,28 @@ public function concept(Parcel $parcel): ShipmentResource ], $parcel->attributesToArray())); } + public function conceptbatch(ParcelCollection $parcelCollection): ShipmentCollection + { + $response = $this->performApiCall( + 'POST', + 'shipments', + $this->getHttpBody($parcelCollection), + ['Content-Type' => 'application/vnd.shipment+json; charset=utf-8'] + ); + + $shipmentCollection = new ShipmentCollection(); + + foreach ($response->data->ids as $item) { + $parcel = $parcelCollection->get($item->reference_identifier); + $shipmentCollection->add(new ShipmentResource(array_merge([ + 'id' => $item->id, + 'status' => ShipmentStatus::CONCEPT, + ], $parcel->attributesToArray()))); + } + + return $shipmentCollection; + } + public function delete($value): bool { if ($value instanceof ShipmentResource) { @@ -81,13 +110,21 @@ protected function getShipmentsResource(string $apiMethod, string $message = '') ); } - protected function getHttpBody(Parcel $parcel): string + protected function getHttpBody($parcel): string { + if ($parcel instanceof ParcelCollection) { + return json_encode([ + 'data' => [ + 'shipments' => $parcel->toArray() + ], + ]); + } + return json_encode([ 'data' => [ 'shipments' => [ - $parcel->toArray(), - ], + $parcel->toArray() + ] ], ]); } diff --git a/src/Resources/ParcelCollection.php b/src/Resources/ParcelCollection.php new file mode 100644 index 0000000..435b919 --- /dev/null +++ b/src/Resources/ParcelCollection.php @@ -0,0 +1,43 @@ +collection = new Collection(); + parent::__construct($attributes); + } + + public function add(Parcel $parcel) + { + $this->collection->add($parcel); + + return $this; + } + + public function get(string $reference_identifier): Parcel + { + return $this + ->collection + ->where('reference_identifier', $reference_identifier) + ->first(); + } + + public function toArray(): array + { + return $this->collection + ->map(function ($parcel) { + return $parcel->toArray(); + }) + ->all(); + } +} diff --git a/src/Resources/ShipmentCollection.php b/src/Resources/ShipmentCollection.php new file mode 100644 index 0000000..1e1c142 --- /dev/null +++ b/src/Resources/ShipmentCollection.php @@ -0,0 +1,43 @@ +collection = new Collection(); + parent::__construct($attributes); + } + + public function add(Shipment $shipment) + { + $this->collection->add($shipment); + + return $this; + } + + public function get(string $reference_identifier): Parcel + { + return $this + ->collection + ->where('reference_identifier', $reference_identifier) + ->first(); + } + + public function toArray(): array + { + return $this->collection + ->map(function ($shipment) { + return $shipment->toArray(); + }) + ->all(); + } +} diff --git a/tests/Feature/Endpoints/ShipmentsTest.php b/tests/Feature/Endpoints/ShipmentsTest.php index 7707ca1..649aec5 100644 --- a/tests/Feature/Endpoints/ShipmentsTest.php +++ b/tests/Feature/Endpoints/ShipmentsTest.php @@ -3,8 +3,10 @@ namespace Mvdnbrk\MyParcel\Tests\Feature\Endpoints; use Mvdnbrk\MyParcel\Resources\Parcel; +use Mvdnbrk\MyParcel\Resources\ParcelCollection; use Mvdnbrk\MyParcel\Resources\ServicePoint; use Mvdnbrk\MyParcel\Resources\Shipment; +use Mvdnbrk\MyParcel\Resources\ShipmentCollection; use Mvdnbrk\MyParcel\Resources\ShipmentOptions; use Mvdnbrk\MyParcel\Tests\TestCase; use Mvdnbrk\MyParcel\Types\PackageType; @@ -31,6 +33,58 @@ private function validRecipient(array $overrides = []): array ], $overrides); } + /** @test */ + public function create_multiple_concept_shipments() + { + // create parcel 1 + $parcel1 = new Parcel([ + 'reference_identifier' => 'test-parcel-1', + 'recipient' => $this->validRecipient(), + 'options' => [ + 'label_description' => 'Test label description', + 'large_format' => false, + 'only_recipient' => false, + 'package_type' => PackageType::PACKAGE, + 'return' => false, + 'signature' => true, + ], + ]); + // create parcel 2 + $parcel2 = new Parcel([ + 'reference_identifier' => 'test-parcel-2', + 'recipient' => $this->validRecipient(), + 'options' => [ + 'label_description' => 'Test label description', + 'large_format' => false, + 'only_recipient' => false, + 'package_type' => PackageType::PACKAGE, + 'return' => false, + 'signature' => true, + ], + ]); + $parcelCollection = new ParcelCollection(); + $parcelCollection->add($parcel1); + $parcelCollection->add($parcel2); + $shipmentCollection = $this->client->shipments->createbatch($parcelCollection); + + $this->assertInstanceOf(ShipmentCollection::class, $shipmentCollection); + $this->assertCount(2, $shipmentCollection->collection); + + $this->assertInstanceOf(Shipment::class, $shipmentCollection->collection->first()); + $this->assertInstanceOf(ShipmentOptions::class, $shipmentCollection->collection->first()->options); + $this->assertNotNull($shipmentCollection->collection->first()->id); + $this->assertEquals('test-parcel-1', $shipmentCollection->collection->first()->reference_identifier); + $this->assertEquals(ShipmentStatus::CONCEPT, $shipmentCollection->collection->first()->status); + $this->assertEquals('John', $shipmentCollection->collection->first()->recipient->first_name); + $this->assertEquals('Doe', $shipmentCollection->collection->first()->recipient->last_name); + // validate 2nd shipment identifier + $this->assertEquals('test-parcel-2', $shipmentCollection->collection->slice(1,1)->first()->reference_identifier); + + foreach ($shipmentCollection->collection as $shipment) { + $this->assertTrue($this->cleanUp($shipment)); + } + } + /** @test */ public function create_a_new_shipment_concept_for_a_parcel() {