diff --git a/UnitTestFiles/Test/OrderTests.php b/UnitTestFiles/Test/OrderTests.php
index 76e5453..bebae13 100644
--- a/UnitTestFiles/Test/OrderTests.php
+++ b/UnitTestFiles/Test/OrderTests.php
@@ -173,8 +173,8 @@ public function testToArray()
'name' => 'Bill Soul',
],
],
- ]
- );
+ ],
+ ]);
}
public function testGetOrders()
@@ -253,6 +253,8 @@ public function testAddOrdersToOptimization()
public function testAddOrdersToRoute()
{
+ $this->markTestSkipped('Read old data.');
+
$body = json_decode(file_get_contents(dirname(__FILE__).'/data/add_order_to_route_data.json'), true);
$routeId = self::$createdProblems[0]->routes[0]->route_id;
@@ -350,6 +352,23 @@ public function testGetOrderByID()
self::assertInstanceOf(Order::class, Order::fromArray($response));
}
+ public function testGetOrderByUUID()
+ {
+ $order = new Order();
+
+ $orderUUID = self::$createdOrders[0]['order_uuid'];
+
+ // Get an order
+ $orderParameters = Order::fromArray([
+ 'order_id' => $orderUUID,
+ ]);
+
+ $response = $order->getOrder($orderParameters);
+
+ self::assertNotNull($response);
+ self::assertInstanceOf(Order::class, Order::fromArray($response));
+ }
+
public function testGetOrderByInsertedDate()
{
$orderParameters = Order::fromArray([
@@ -517,6 +536,23 @@ public function testUpdateOrderWithCustomFiel()
$this->assertEquals(true, $response['custom_user_fields'][0]['order_custom_field_value']);
}
+ public function testDeleteOrderByUuid()
+ {
+ $lastOrder = array_pop(self::$createdOrders);
+ if ($lastOrder != null) {
+ $order = new Order();
+ $ids = [
+ "order_ids" => [$lastOrder['order_uuid']]
+ ];
+
+ $response = $order->removeOrder($ids);
+
+ if (!is_null($response) && isset($response['status']) && $response['status']) {
+ echo "The test order removed by UUID
";
+ }
+ }
+ }
+
public static function tearDownAfterClass()
{
if (sizeof(self::$createdOrders)) {
diff --git a/UnitTestFiles/Test/V5/OrderUnitTests.php b/UnitTestFiles/Test/V5/OrderUnitTests.php
new file mode 100644
index 0000000..13df50a
--- /dev/null
+++ b/UnitTestFiles/Test/V5/OrderUnitTests.php
@@ -0,0 +1,371 @@
+assertInstanceOf(CustomData::class, new CustomData());
+ }
+
+ public function testCustomDataCanBeCreateFromArray() : void
+ {
+ $this->assertInstanceOf(CustomData::class, new CustomData([
+ 'barcode' => '1',
+ 'airbillno' => '2',
+ 'sorted_on_date' => '3',
+ 'sorted_on_utc' => 1
+ ]));
+ }
+
+ public function testCustomFieldCanBeCreateEmpty() : void
+ {
+ $this->assertInstanceOf(CustomField::class, new CustomField());
+ }
+
+ public function testCustomFieldCanBeCreateFromArray() : void
+ {
+ $this->assertInstanceOf(CustomField::class, new CustomField([
+ 'order_custom_field_uuid' => 'uuid',
+ 'order_custom_field_value' => 'value'
+ ]));
+ }
+
+ public function testGPSCoordsCanBeCreateEmpty() : void
+ {
+ $this->assertInstanceOf(GPSCoords::class, new GPSCoords());
+ }
+
+ public function testGPSCoordsCanBeCreateByConstructor() : void
+ {
+ $coords = new GPSCoords(40.5, 90.0);
+ $this->assertInstanceOf(GPSCoords::class, $coords);
+ $this->assertEquals($coords->lat, 40.5);
+ $this->assertEquals($coords->lng, 90.0);
+ }
+
+ public function testGPSCoordsCanBeCreateFromArray() : void
+ {
+ $coords = new GPSCoords([
+ 'lat' => 40.5,
+ 'lng' => 90.0
+ ]);
+ $this->assertInstanceOf(GPSCoords::class, $coords);
+ $this->assertEquals($coords->lat, 40.5);
+ $this->assertEquals($coords->lng, 90.0);
+ }
+
+ public function testLocalTimeWindowCanBeCreateEmpty() : void
+ {
+ $this->assertInstanceOf(LocalTimeWindow::class, new LocalTimeWindow());
+ }
+
+ public function testLocalTimeWindowCanBeCreateByConstructor() : void
+ {
+ $coords = new LocalTimeWindow(1, 2);
+ $this->assertInstanceOf(LocalTimeWindow::class, $coords);
+ $this->assertEquals($coords->start, 1);
+ $this->assertEquals($coords->end, 2);
+ }
+
+ public function testLocalTimeWindowCanBeCreateFromArray() : void
+ {
+ $coords = new LocalTimeWindow([
+ 'start' => 1,
+ 'end' => 2
+ ]);
+ $this->assertInstanceOf(LocalTimeWindow::class, $coords);
+ $this->assertEquals($coords->start, 1);
+ $this->assertEquals($coords->end, 2);
+ }
+
+ public function testOrderCanBeCreateEmpty() : void
+ {
+ $this->assertInstanceOf(Order::class, new Order());
+ }
+
+ public function testOrderCanBeCreateFromArray() : void
+ {
+ $order = new Order([
+ 'first_name' => 'John',
+ 'last_name' => 'Doe',
+ 'email' => 'some@company.com'
+ ]);
+ $this->assertInstanceOf(Order::class, $order);
+ $this->assertEquals($order->first_name, 'John');
+ $this->assertEquals($order->last_name, 'Doe');
+ }
+
+ public function testResponseOrderCanBeCreateEmpty() : void
+ {
+ $this->assertInstanceOf(Order::class, new Order());
+ }
+
+ public function testResponseOrderCanBeCreateFromArray() : void
+ {
+ $order = new ResponseOrder([
+ 'first_name' => 'John',
+ 'last_name' => 'Doe',
+ 'email' => 'some@company.com'
+ ]);
+ $this->assertInstanceOf(ResponseOrder::class, $order);
+ $this->assertEquals($order->first_name, 'John');
+ $this->assertEquals($order->last_name, 'Doe');
+ }
+
+ public function testCreateMustReturnResponseOrder() : void
+ {
+ $orders = new Orders();
+ $order = $orders->create([
+ 'address_1' => '1358 E Luzerne St, Philadelphia, PA 19124, US',
+ 'address_alias' => 'Auto test address',
+ 'address_city' => 'Philadelphia',
+ 'address_geo' => [
+ 'lat' => 48.335991,
+ 'lng' => 31.18287
+ ],
+ 'first_name' => 'John',
+ 'last_name' => 'Doe',
+ 'email' => 'some@company.com'
+ ]);
+
+ $this->assertInstanceOf(ResponseOrder::class, $order);
+ $this->assertNotNull($order->first_name);
+ $this->assertEquals($order->first_name, 'John');
+
+ self::$created_uuid = $order->order_uuid;
+ }
+
+ public function testGetMustReturnResponseOrder() : void
+ {
+ if (self::$created_uuid !== null) {
+ $orders = new Orders();
+ $order = $orders->get(self::$created_uuid);
+
+ $this->assertInstanceOf(ResponseOrder::class, $order);
+ $this->assertNotNull($order->first_name);
+ $this->assertEquals($order->first_name, 'John');
+ }
+ }
+
+ public function testUpdateMustReturnResponseOrder() : void
+ {
+ if (self::$created_uuid !== null) {
+ $orders = new Orders();
+ $order = $orders->update(self::$created_uuid, ['first_name' => 'Jane']);
+
+ $this->assertInstanceOf(ResponseOrder::class, $order);
+ $this->assertNotNull($order->first_name);
+ $this->assertEquals($order->first_name, 'Jane');
+ }
+ }
+
+ public function testSearchMustReturnResponseSearchWithoutParams() : void
+ {
+ $orders = new Orders();
+ $res = $orders->search();
+
+ $this->assertInstanceOf(ResponseSearch::class, $res);
+ $this->assertNotNull($res->total);
+ }
+
+ public function testSearchMustReturnResponseSearchWithParams() : void
+ {
+ if (self::$created_uuid !== null) {
+ $orders = new Orders();
+ $params = [
+ "filters" => [
+ "order_ids" => [self::$created_uuid]
+ ]
+ ];
+ $res = $orders->search($params);
+
+ $this->assertInstanceOf(ResponseSearch::class, $res);
+ $this->assertNotNull($res->total);
+ $this->assertNotNull($res->results);
+ }
+ }
+
+ public function testBatchCreateMustReturnTrue() : void
+ {
+ $this->markTestSkipped('must be revisited, cannot get back IDs or created Orders.');
+
+ $orders = new Orders();
+ $params = [
+ [
+ 'address_1' => '1358 E Luzerne St, Philadelphia, PA 19124, US',
+ 'address_alias' => 'Address for batch workflow 0',
+ 'address_city' => 'Philadelphia',
+ 'address_geo' => [
+ 'lat' => 48.335991,
+ 'lng' => 31.18287
+ ],
+ 'first_name' => 'John',
+ 'last_name' => 'Doe',
+ 'email' => 'some@company.com'
+ ], [
+ 'address_1' => '1358 E Luzerne St, Philadelphia, PA 19124, US',
+ 'address_alias' => 'Address for batch workflow 1',
+ 'address_city' => 'Philadelphia',
+ 'address_geo' => [
+ 'lat' => 48.335991,
+ 'lng' => 31.18287
+ ],
+ 'first_name' => 'John',
+ 'last_name' => 'Doe',
+ 'email' => 'some@company.com'
+ ]
+ ];
+ $res = $orders->batchCreate($params);
+
+ $this->assertIsBool($res);
+ $this->assertTrue($res);
+ }
+
+ public function testBatchUpdateMustReturnArray() : void
+ {
+ $this->markTestSkipped('must be revisited, cannot get back IDs or created Orders.');
+
+ $orders = new Orders();
+ $orderIds = ['', ''];
+ $data = [
+ 'first_name' => 'Jane'
+ ];
+ $res = $orders->batchUpdate($orderIds, $data);
+
+ $this->assertIsArray($res);
+ }
+
+ public function testBatchUpdateByFiltersMustReturnTrue() : void
+ {
+ $this->markTestSkipped('must be revisited, cannot get back IDs or created Orders.');
+
+ $orders = new Orders();
+ $params = [
+ 'data' => [
+ 'first_name' => 'John'
+ ],
+ 'filters' => [
+ 'orderIds' => ['', '']
+ ]
+ ];
+ $res = $orders->batchUpdateByFilters($params);
+
+ $this->assertIsBool($res);
+ $this->assertTrue($res);
+ }
+
+ public function testBatchDeleteMustReturnTrue() : void
+ {
+ $this->markTestSkipped('must be revisited, cannot get back IDs or created Orders.');
+
+ $orders = new Orders();
+ $orderIds = ['', ''];
+ $res = $orders->batchDelete($orderIds);
+
+ $this->assertIsBool($res);
+ $this->assertTrue($res);
+ }
+
+ public function testGetOrderCustomFieldsReturnArray() : void
+ {
+ $orders = new Orders();
+ $res = $orders->getOrderCustomFields();
+
+ $this->assertIsArray($res);
+ }
+
+ public function testCreateOrderCustomFieldMustReturnCustomField() : void
+ {
+ $orders = new Orders();
+ $field = $orders->createOrderCustomField([
+ 'order_custom_field_name' => 'CustomField1',
+ 'order_custom_field_label' => 'Custom Field 1',
+ 'order_custom_field_type' => 'checkbox',
+ 'order_custom_field_type_info' => [
+ 'short_label' => 'cFl1'
+ ]
+ ]);
+
+ $this->assertInstanceOf(CustomField::class, $field);
+ $this->assertNotNull($field->order_custom_field_label);
+ $this->assertEquals($field->order_custom_field_label, 'Custom Field 1');
+
+ self::$created_field_uuid = $field->order_custom_field_uuid;
+ }
+
+ public function testUpdateOrderCustomFieldMustReturnCustomField() : void
+ {
+ if (self::$created_field_uuid !== null) {
+ $orders = new Orders();
+ $field = $orders->updateOrderCustomField(self::$created_field_uuid, [
+ 'order_custom_field_label' => 'Custom Field New',
+ 'order_custom_field_type' => 'checkbox',
+ 'order_custom_field_type_info' => [
+ 'short_label' => 'cFl1'
+ ]
+ ]);
+
+ $this->assertInstanceOf(CustomField::class, $field);
+ $this->assertNotNull($field->order_custom_field_label);
+ $this->assertEquals($field->order_custom_field_label, 'Custom Field New');
+ }
+ }
+
+ public function testDeleteOrderCustomFieldMustReturnCustomField() : void
+ {
+ if (self::$created_field_uuid !== null) {
+ $orders = new Orders();
+ $field = $orders->deleteOrderCustomField(self::$created_field_uuid);
+
+ $this->assertInstanceOf(CustomField::class, $field);
+ self::$created_field_uuid = null;
+ }
+ }
+
+ public function testDeleteMustReturnTrue() : void
+ {
+ if (self::$created_uuid !== null) {
+ $orders = new Orders();
+ $result = $orders->delete(self::$created_uuid);
+
+ $this->assertTrue($result);
+ self::$created_uuid = null;
+ }
+ }
+
+ public static function tearDownAfterClass() : void
+ {
+ sleep(1);
+
+ if (self::$created_uuid !== null || self::$created_field_uuid !== null) {
+ $orders = new Orders();
+ if (self::$created_uuid !== null) {
+ $orders->delete(self::$created_uuid);
+ }
+ if (self::$created_field_uuid !== null) {
+ $orders->deleteOrderCustomField(self::$created_field_uuid);
+ }
+ }
+ }
+}
diff --git a/composer.json b/composer.json
index 211bf5e..6aeed78 100644
--- a/composer.json
+++ b/composer.json
@@ -2,7 +2,7 @@
"name": "route4me/route4me-php",
"description": "Access Route4Me's logistics-as-a-service API using our PHP SDK",
"minimum-stability": "stable",
- "version": "1.2.11",
+ "version": "1.3.1",
"authors": [
{
"name": "Igor Route4Me",
diff --git a/examples/Order/GetOrderByUuid.php b/examples/Order/GetOrderByUuid.php
new file mode 100644
index 0000000..234ae1e
--- /dev/null
+++ b/examples/Order/GetOrderByUuid.php
@@ -0,0 +1,72 @@
+ '1358 E Luzerne St, Philadelphia, PA 19124, US',
+ 'cached_lat' => 48.335991,
+ 'cached_lng' => 31.18287,
+ 'address_alias' => 'Auto test address',
+ 'address_city' => 'Philadelphia',
+ 'EXT_FIELD_first_name' => 'John',
+ 'EXT_FIELD_last_name' => 'Doe',
+ 'EXT_FIELD_email' => 'some@company.com'
+]);
+
+$order = null;
+$orderId = null;
+
+try {
+ $order = new Order();
+
+ // create order
+ $newOrder = $order->addOrder($orderParams);
+ $orderId = $newOrder['order_id'];
+ $orderUuid = $newOrder['order_uuid'];
+ echo "Create Order with id='" . $orderId . "' and uuid='" . $orderUuid . "'" . PHP_EOL;
+
+ // get order by ID
+ $orderById = $order->getOrder(['order_id' => $orderId]);
+ echo "Read Order by id, id='" . $orderId . "' and uuid='" . $orderUuid . "'" . PHP_EOL;
+
+ // get order by UUID
+ $orderByUuid = $order->getOrder(['order_id' => $orderUuid]);
+ echo "Read Order by uuid, id='" . $orderId . "' and uuid='" . $orderUuid . "'" . PHP_EOL;
+
+ // compare orders
+ if ($orderById == $orderByUuid) {
+ echo "The Orders are equal." . PHP_EOL;
+ } else {
+ echo "The Orders are not equal." . PHP_EOL;
+ }
+
+ // delete order
+ $res = $order->removeOrder(['order_ids' => [$orderUuid]]);
+ if ($res) {
+ echo "Order with uuid='" . $orderUuid . "' was deleted successful." . PHP_EOL;
+ } else {
+ echo "Order with uuid='" . $orderUuid . "' was not deleted." . PHP_EOL;
+ }
+} catch (Exception $e) {
+ echo "ERROR: " . $e->getMessage() . PHP_EOL;
+
+ if ($order && $orderId) {
+ try {
+ $order->removeOrder(['order_ids' => [$orderUuid]]);
+ echo "Order with uuid='" . $orderUuid . "' was cleaned up successful." . PHP_EOL;
+ } catch (Exception $e) {
+ echo "Order with uuid='" . $orderUuid . "' was not cleaned up." . PHP_EOL;
+ }
+ }
+}
diff --git a/examples/Order_V5/CreateBatchOfOrders.php b/examples/Order_V5/CreateBatchOfOrders.php
new file mode 100644
index 0000000..fda1167
--- /dev/null
+++ b/examples/Order_V5/CreateBatchOfOrders.php
@@ -0,0 +1,55 @@
+ '1358 E Luzerne St, Philadelphia, PA 19124, US',
+ 'address_alias' => 'Address for batch workflow 0',
+ 'address_city' => 'Philadelphia',
+ 'address_geo' => [
+ 'lat' => 48.335991,
+ 'lng' => 31.18287
+ ],
+ 'first_name' => 'John',
+ 'last_name' => 'Doe',
+ 'email' => 'some@company.com'
+ ], [
+ 'address_1' => '1358 E Luzerne St, Philadelphia, PA 19124, US',
+ 'address_alias' => 'Address for batch workflow 1',
+ 'address_city' => 'Philadelphia',
+ 'address_geo' => [
+ 'lat' => 48.335991,
+ 'lng' => 31.18287
+ ],
+ 'first_name' => 'John',
+ 'last_name' => 'Doe',
+ 'email' => 'some@company.com'
+ ]
+];
+
+try {
+ $orders = new Orders();
+
+ // create a batch of orders
+ $res = $orders->batchCreate($ordersParams);
+ if ($res) {
+ echo "Create a batch of orders." . PHP_EOL;
+ } else {
+ echo "Error to create a batch of orders." . PHP_EOL;
+ }
+} catch (Exception $e) {
+ echo "ERROR: " . $e->getMessage() . PHP_EOL;
+}
diff --git a/examples/Order_V5/CreateOrder.php b/examples/Order_V5/CreateOrder.php
new file mode 100644
index 0000000..53ae506
--- /dev/null
+++ b/examples/Order_V5/CreateOrder.php
@@ -0,0 +1,70 @@
+ '1358 E Luzerne St, Philadelphia, PA 19124, US',
+ 'address_alias' => 'Auto test address',
+ 'address_city' => 'Philadelphia',
+ 'address_geo' => [
+ 'lat' => 48.335991,
+ 'lng' => 31.18287
+ ],
+ 'first_name' => 'John',
+ 'last_name' => 'Doe',
+ 'email' => 'some@company.com'
+]);
+
+$orders = null;
+$orderId = null;
+
+try {
+ $orders = new Orders();
+
+ // create order
+ $newOrder = $orders->create($order);
+ $orderId = $newOrder->order_uuid;
+ echo "Create Order with uuid='" . $orderId . "'" . PHP_EOL;
+
+ // read order
+ $readOrder = $orders->get($orderId);
+ echo "Read Order first_name is '" . $readOrder->first_name . "'" . PHP_EOL;
+
+ // update order
+ $params = [
+ 'first_name' => 'Jane'
+ ];
+ $updateOrder = $orders->update($orderId, $params);
+ echo "Update Order first_name is '" . $updateOrder->first_name . "'" . PHP_EOL;
+
+ // delete order
+ if ($orders->delete($orderId)) {
+ echo "Order with uuid='" . $orderId . "' was deleted successful." . PHP_EOL;
+ } else {
+ echo "Order with uuid='" . $orderId . "' was not deleted." . PHP_EOL;
+ }
+} catch (Exception $e) {
+ echo "ERROR: " . $e->getMessage() . PHP_EOL;
+
+ if ($orders && $orderId) {
+ try {
+ $orders->delete($orderId);
+ echo "Order with uuid='" . $orderId . "' was cleaned up successful." . PHP_EOL;
+ } catch (Exception $e) {
+ echo "Order with uuid='" . $orderId . "' was not cleaned up." . PHP_EOL;
+ }
+ }
+}
diff --git a/examples/Order_V5/CreateOrderCustomField.php b/examples/Order_V5/CreateOrderCustomField.php
new file mode 100644
index 0000000..ca10f24
--- /dev/null
+++ b/examples/Order_V5/CreateOrderCustomField.php
@@ -0,0 +1,70 @@
+ 'CustomField1',
+ 'order_custom_field_label' => 'Custom Field 1',
+ 'order_custom_field_type' => 'checkbox',
+ 'order_custom_field_type_info' => [
+ 'short_label' => 'cFl1'
+ ]
+]);
+
+print_r($customField);
+
+$orders = null;
+$uuid = null;
+
+try {
+ $orders = new Orders();
+
+ // create custom field
+ $newField = $orders->createOrderCustomField($customField);
+ $uuid = $newField->order_custom_field_uuid;
+ echo "Create Custom field, label is '" . $newField->order_custom_field_label . "'" . PHP_EOL;
+
+ // update custom field
+ $customField->order_custom_field_label = 'Custom Field New';
+ $updateField = $orders->updateOrderCustomField($uuid, $customField);
+ echo "Update Custom field, label is '" . $updateField->order_custom_field_label . "'" . PHP_EOL;
+
+ // read custom fields
+ $readFields = $orders->getOrderCustomFields();
+ foreach ($readFields as $key => $field) {
+ if ($field->order_custom_field_uuid === $uuid) {
+ echo "Found Custom field with label '" . $field->order_custom_field_label . "'" . PHP_EOL;
+ break;
+ }
+ }
+ // delete custom field
+ if ($orders->deleteOrderCustomField($uuid)) {
+ echo "Custom field with uuid='" . $uuid . "' was deleted successful." . PHP_EOL;
+ } else {
+ echo "Custom field with uuid='" . $uuid . "' was not deleted." . PHP_EOL;
+ }
+} catch (Exception $e) {
+ echo "ERROR: " . $e->getMessage() . PHP_EOL;
+
+ if ($orders && $uuid) {
+ try {
+ $orders->deleteOrderCustomField($uuid);
+ echo "Custom field with uuid='" . $uuid . "' was cleaned up successful." . PHP_EOL;
+ } catch (Exception $e) {
+ echo "Custom field with uuid='" . $uuid . "' was not cleaned up." . PHP_EOL;
+ }
+ }
+}
diff --git a/examples/Order_V5/GetOrderByUuid.php b/examples/Order_V5/GetOrderByUuid.php
new file mode 100644
index 0000000..39f2373
--- /dev/null
+++ b/examples/Order_V5/GetOrderByUuid.php
@@ -0,0 +1,76 @@
+ '1358 E Luzerne St, Philadelphia, PA 19124, US',
+ 'address_alias' => 'Auto test address',
+ 'address_city' => 'Philadelphia',
+ 'address_geo' => [
+ 'lat' => 48.335991,
+ 'lng' => 31.18287
+ ],
+ 'first_name' => 'John',
+ 'last_name' => 'Doe',
+ 'email' => 'some@company.com'
+]);
+
+$orders = null;
+$orderId = null;
+
+try {
+ $orders = new Orders();
+
+ // create order
+ $newOrder = $orders->create($order);
+ $orderId = $newOrder->order_id;
+ $orderUuid = $newOrder->order_uuid;
+ echo "Create Order with id='" . $orderId . "' and uuid='" . $orderUuid . "'" . PHP_EOL;
+
+ // get order by ID
+ $orderById = $orders->get($orderId);
+ echo "Read Order by id, id='" . $orderId . "' and uuid='" . $orderUuid . "'" . PHP_EOL;
+
+ // get order by UUID
+ $orderByUuid = $orders->get($orderUuid);
+ echo "Read Order by uuid, id='" . $orderId . "' and uuid='" . $orderUuid . "'" . PHP_EOL;
+
+ // compare orders
+ if ($orderById == $orderByUuid) {
+ echo "The Orders are equal." . PHP_EOL;
+ } else {
+ echo "The Orders are not equal." . PHP_EOL;
+ }
+
+ // delete order
+ if ($orders->delete($orderUuid)) {
+ echo "Order with uuid='" . $orderUuid . "' was deleted successful." . PHP_EOL;
+ } else {
+ echo "Order with uuid='" . $orderUuid . "' was not deleted." . PHP_EOL;
+ }
+} catch (Exception $e) {
+ echo "ERROR: " . $e->getMessage() . PHP_EOL;
+
+ if ($orders && $orderId) {
+ try {
+ $orders->delete($orderUuid);
+ echo "Order with uuid='" . $orderUuid . "' was cleaned up successful." . PHP_EOL;
+ } catch (Exception $e) {
+ echo "Order with uuid='" . $orderUuid . "' was not cleaned up." . PHP_EOL;
+ }
+ }
+}
diff --git a/examples/Order_V5/SearchOrders.php b/examples/Order_V5/SearchOrders.php
new file mode 100644
index 0000000..bf86291
--- /dev/null
+++ b/examples/Order_V5/SearchOrders.php
@@ -0,0 +1,45 @@
+search();
+
+ // Search orders by known IDs
+ $params = [
+ "filters" => [
+ "order_ids" => ["B3CBB9C07D37406997EE73D9CEC18264", "D91F4962CC4C468A9563896A93DBE4D7"]
+ ]
+ ];
+ $ordersByIds = $orders->search($params);
+
+ // Search all the orders with specific address_alias, return only specific fields in response.
+ $params = [
+ "return_provided_fields_as_map" => true,
+ "fields" => ["order_uuid", "address_alias", "email", "first_name", "phone"],
+ "search" => [
+ "matches" => ["address_alias" => "Auto test address"]
+ ]
+ ];
+ $ordersWithAddress = $orders->search($params);
+
+ print_r($ordersWithAddress);
+} catch (Exception $e) {
+ echo "ERROR: " . $e->getMessage() . PHP_EOL;
+}
diff --git a/phpunit.xml b/phpunit.xml
index bf578d1..b74246d 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -33,6 +33,7 @@
UnitTestFiles/Test/UserTests.php
UnitTestFiles/Test/VehicleTests.php
UnitTestFiles/Test/V5/AddressBookUnitTests.php
+ UnitTestFiles/Test/V5/OrderUnitTests.php
UnitTestFiles/Test/V5/PodWorkflowUnitTests.php
UnitTestFiles/Test/V5/RecurringRoutesUnitTests.php
UnitTestFiles/Test/V5/RouteTests.php
@@ -41,6 +42,7 @@
UnitTestFiles/Test/V5/AddressBookUnitTests.php
+ UnitTestFiles/Test/V5/OrderUnitTests.php
UnitTestFiles/Test/V5/PodWorkflowUnitTests.php
UnitTestFiles/Test/V5/RecurringRoutesUnitTests.php
UnitTestFiles/Test/V5/RouteTests.php
diff --git a/src/Route4Me/Order.php b/src/Route4Me/Order.php
index 54d1b61..a48bce0 100644
--- a/src/Route4Me/Order.php
+++ b/src/Route4Me/Order.php
@@ -34,6 +34,7 @@ class Order extends Common
public $redirect;
public $optimization_problem_id;
public $order_id;
+ public $order_uuid;
public $order_ids;
public $day_added_YYMMDD;
@@ -103,7 +104,7 @@ public function __construct()
public static function addOrder($params)
{
$excludeFields = ['route_id', 'redirect', 'optimization_problem_id', 'order_id',
- 'order_ids', 'fields', 'offset', 'limit', 'query', 'created_timestamp', ];
+ 'order_ids', 'fields', 'offset', 'limit', 'query', 'created_timestamp', 'order_uuid'];
$allBodyFields = Route4Me::getObjectProperties(new self(), $excludeFields);
@@ -148,7 +149,8 @@ public static function addOrder2Optimization($params)
public static function getOrder($params)
{
- $allQueryFields = ['order_id', 'fields', 'day_added_YYMMDD', 'scheduled_for_YYMMDD', 'query', 'offset', 'limit'];
+ $allQueryFields = ['order_id', 'fields', 'day_added_YYMMDD', 'scheduled_for_YYMMDD', 'query',
+ 'offset', 'limit'];
$response = Route4Me::makeRequst([
'url' => Endpoint::ORDER_V4,
@@ -215,8 +217,8 @@ public static function removeOrder($params)
public static function updateOrder($params)
{
- $excludeFields = ['route_id', 'redirect', 'optimization_problem_id',
- 'order_ids', 'fields', 'offset', 'limit', 'query', 'created_timestamp', ];
+ $excludeFields = ['route_id', 'redirect', 'optimization_problem_id', 'order_ids',
+ 'fields', 'offset', 'limit', 'query', 'created_timestamp', 'route_uuid'];
$allBodyFields = Route4Me::getObjectProperties(new self(), $excludeFields);
@@ -279,8 +281,8 @@ public function addOrdersFromCsvFile($csvFileHandle, $ordersFieldsMapping)
$columns = fgetcsv($csvFileHandle, $max_line_length, $delemietr);
- $excludeFields = ['route_id', 'redirect', 'optimization_problem_id', 'order_id',
- 'order_ids', 'fields', 'offset', 'limit', 'query', 'created_timestamp', ];
+ $excludeFields = ['route_id', 'redirect', 'optimization_problem_id', 'order_id', 'order_ids',
+ 'fields', 'offset', 'limit', 'query', 'created_timestamp', 'order_uuid'];
$allOrderFields = Route4Me::getObjectProperties(new self(), $excludeFields);
diff --git a/src/Route4Me/V5/Enum/Endpoint.php b/src/Route4Me/V5/Enum/Endpoint.php
index c88b89c..e21ba2c 100644
--- a/src/Route4Me/V5/Enum/Endpoint.php
+++ b/src/Route4Me/V5/Enum/Endpoint.php
@@ -125,4 +125,12 @@ class Endpoint
const ADDRESSES_JOB_TRACKER_RESULT = self::MAIN_HOST . "/address-book/addresses/job-tracker/result";
const POD_WORKFLOW = self::MAIN_HOST . "/workflows";
+
+ const ORDER = self::MAIN_HOST . "/orders-platform";
+ const ORDER_CREATE = self::ORDER . "/create";
+ const ORDER_BATCH_CREATE = self::ORDER . "/batch-create";
+ const ORDER_BATCH_DELETE = self::ORDER . "/batch-delete";
+ const ORDER_BATCH_UPDATE = self::ORDER . "/batch-update";
+ const ORDER_BATCH_UPDATE_FILTER = self::ORDER_BATCH_UPDATE . "/filter";
+ const ORDER_CUSTOM_FIELDS = self::ORDER . "/order-custom-user-fields";
}
diff --git a/src/Route4Me/V5/Orders/CustomData.php b/src/Route4Me/V5/Orders/CustomData.php
new file mode 100644
index 0000000..dd1dae7
--- /dev/null
+++ b/src/Route4Me/V5/Orders/CustomData.php
@@ -0,0 +1,42 @@
+fillFromArray($params);
+ }
+ }
+}
diff --git a/src/Route4Me/V5/Orders/CustomField.php b/src/Route4Me/V5/Orders/CustomField.php
new file mode 100644
index 0000000..e1e3365
--- /dev/null
+++ b/src/Route4Me/V5/Orders/CustomField.php
@@ -0,0 +1,52 @@
+fillFromArray($params);
+ }
+ }
+}
diff --git a/src/Route4Me/V5/Orders/GPSCoords.php b/src/Route4Me/V5/Orders/GPSCoords.php
new file mode 100644
index 0000000..3c258d6
--- /dev/null
+++ b/src/Route4Me/V5/Orders/GPSCoords.php
@@ -0,0 +1,35 @@
+fillFromArray($params_or_lat);
+ } elseif (is_float($params_or_lat)) {
+ $this->lat = $params_or_lat;
+ $this->lng = $lng;
+ }
+ }
+}
diff --git a/src/Route4Me/V5/Orders/LocalTimeWindow.php b/src/Route4Me/V5/Orders/LocalTimeWindow.php
new file mode 100644
index 0000000..f686178
--- /dev/null
+++ b/src/Route4Me/V5/Orders/LocalTimeWindow.php
@@ -0,0 +1,35 @@
+fillFromArray($params_or_start);
+ } elseif (is_int($params_or_start)) {
+ $this->start = $params_or_start;
+ $this->end = $end;
+ }
+ }
+}
diff --git a/src/Route4Me/V5/Orders/Order.php b/src/Route4Me/V5/Orders/Order.php
new file mode 100644
index 0000000..44d4aa9
--- /dev/null
+++ b/src/Route4Me/V5/Orders/Order.php
@@ -0,0 +1,255 @@
+ $value) {
+ if (isset($params[$key])) {
+ if ($key === 'local_time_windows') {
+ $this->{$key} = array();
+ foreach ($params[$key] as $ltw_key => $ltw_value) {
+ if (is_array($ltw_value)) {
+ array_push($this->{$key}, new LocalTimeWindow($ltw_value));
+ } elseif (is_object($ltw_value) && $ltw_value instanceof LocalTimeWindow) {
+ array_push($this->{$key}, $ltw_value);
+ }
+ }
+ } elseif ($key === 'custom_fields') {
+ $this->{$key} = array();
+ foreach ($params[$key] as $cf_key => $cf_value) {
+ if (is_array($cf_value)) {
+ array_push($this->{$key}, new CustomField($cf_value));
+ } elseif (is_object($cf_value) && $cf_value instanceof CustomField) {
+ array_push($this->{$key}, $cf_value);
+ }
+ }
+ } elseif ($key === 'address_geo' || $key === 'curbside_geo') {
+ if (is_array($params[$key])) {
+ $this->{$key} = new GPSCoords($params[$key]);
+ } elseif (is_object($params[$key]) && $params[$key] instanceof GPSCoords) {
+ $this->{$key} = $params[$key];
+ }
+ } elseif ($key === 'custom_data') {
+ if (is_array($params[$key])) {
+ $this->{$key} = new CustomData($params[$key]);
+ } elseif (is_object($params[$key]) && $params[$key] instanceof CustomData) {
+ $this->{$key} = $params[$key];
+ }
+ } else {
+ $this->{$key} = $params[$key];
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/Route4Me/V5/Orders/Orders.php b/src/Route4Me/V5/Orders/Orders.php
new file mode 100644
index 0000000..e0cdacd
--- /dev/null
+++ b/src/Route4Me/V5/Orders/Orders.php
@@ -0,0 +1,532 @@
+toResponseOrder(Route4Me::makeRequst([
+ 'url' => Endpoint::ORDER_CREATE,
+ 'method' => 'POST',
+ 'HTTPHEADER' => 'Content-Type: application/json',
+ 'body' => Route4Me::generateRequestParameters($allBodyFields, $params_or_order)
+ ]));
+ }
+
+ /**
+ * Show single order by its id
+ *
+ * @since 1.3.0
+ *
+ * @param string $order_id - Order ID.
+ * @return ResponseOrder
+ * @throws Exception\ApiError
+ */
+ public function get(string $order_id) : ResponseOrder
+ {
+ return $this->toResponseOrder(Route4Me::makeRequst([
+ 'url' => Endpoint::ORDER . '/' . $order_id,
+ 'method' => 'GET'
+ ]));
+ }
+
+ /**
+ * Update single order by its id
+ *
+ * @since 1.3.0
+ *
+ * @param string $order_id - Order ID.
+ * @param object $params - Parameters of order to update, look for more
+ * information in create()
+ * @return ResponseOrder
+ * @throws Exception\ApiError
+ */
+ public function update(string $order_id, $params) : ResponseOrder
+ {
+ $allBodyFields = ['member_id', 'address_1', 'address_2', 'address_alias',
+ 'address_city', 'address_state', 'address_zip', 'address_country', 'address_geo', 'curbside_geo',
+ 'date_scheduled_for', 'order_status_id', 'is_pending', 'is_accepted',
+ 'is_started', 'is_completed', 'is_validated', 'phone', 'first_name',
+ 'last_name', 'email', 'custom_data', 'local_time_windows', 'local_timezone_string',
+ 'service_time', 'color', 'tracking_number', 'address_stop_type', 'last_status', 'weight',
+ 'cost', 'revenue', 'cube', 'pieces', 'group', 'address_priority',
+ 'address_customer_po', 'custom_fields'
+ ];
+
+ return $this->toResponseOrder(Route4Me::makeRequst([
+ 'url' => Endpoint::ORDER . '/' . $order_id,
+ 'method' => 'PUT',
+ 'HTTPHEADER' => 'Content-Type: application/json',
+ 'body' => Route4Me::generateRequestParameters($allBodyFields, $params)
+ ]));
+ }
+
+ /**
+ * Delete (soft) single order by its id
+ *
+ * @since 1.3.0
+ *
+ * @param string $order_id - Order ID.
+ * @return bool
+ * @throws Exception\ApiError
+ */
+ public function delete(string $order_id) : bool
+ {
+ $res = Route4Me::makeRequst([
+ 'url' => Endpoint::ORDER . '/' . $order_id,
+ 'method' => 'DELETE'
+ ]);
+ return (isset($res['status']) ? $res['status'] : false);
+ }
+
+ /**
+ * Search orders in ElasticSearch storage or in Spanner database
+ *
+ * @since 1.3.0
+ *
+ * @param $params - Search and filter parameters.
+ * string[] [order_ids] - Array of order ids, HEX-Strings.
+ * bool return_provided_fields_as_map
+ * array [orderBy] - Sort and direction parameters.
+ * string 0 - The name of the sort field, this is one of
+ * 'address_alias', 'first_name', 'last_name', 'phone',
+ * 'is_pending', 'is_validated', 'is_accepted',
+ * 'is_completed', 'scheduled_for', 'day_added'
+ * string [1 = 'asc'] - Sorting direction, this is one of 'asc', 'ASC', 'desc', 'DESC'
+ * int [limit = 30] - The number of orders per page.
+ * int [offset = 0] - The requested page.
+ * string[] [fields] - An array of returned fields, this is one of
+ * 'order_uuid', 'member_id', 'address_1', 'address_2',
+ * 'address_alias', 'address_city', 'address_state', 'address_zip',
+ * 'address_country', 'coordinates', 'curbside_coordinates',
+ * 'updated_timestamp', 'created_timestamp', 'day_added',
+ * 'scheduled_for', 'order_status_id', 'is_pending', 'is_started',
+ * 'is_completed', 'is_validated', 'phone', 'first_name', 'last_name',
+ * 'email', 'custom_data', 'local_time_windows', 'local_timezone',
+ * 'service_time', 'color', 'icon', 'last_visited_timestamp',
+ * 'visited_count', 'in_route_count', 'last_routed_timestamp',
+ * 'tracking_number', 'organization_id', 'root_member_id',
+ * 'address_stop_type', 'last_status', 'sorted_day_id', 'weight',
+ * 'cost', 'revenue', 'cube', 'pieces', 'done_day_id',
+ * 'possession_day_id', 'group', 'workflow_uuid', 'address_priority'
+ * string[] [addition] - An array of additional returned fields, this is one of
+ * 'territory_ids', 'aggregation_ids'
+ * array [search] - Search parameters.
+ * string [query] - The string to query to ElasticSearch. If set the `matches` and
+ * `terms` sections will be ignored.
+ * array [matches] - The object to query to ElasticSearch.
+ * array [custom_data] - Order custom data.
+ * string [barcode] - Tracking number for order.
+ * string [airbillno] - Additional tracking number for order.
+ * string [sorted_on_date] - Datetime String with "T" delimiter, ISO 8601.
+ * int [sorted_on_utc] - Timestamp only; replaced data in `sorted_on_date` property.
+ * string [first_name] - The first name.
+ * string [last_name] - The last name.
+ * string [email] - E-mail.
+ * string [phone] - The phone number.
+ * string [address_1] - The order Address line 1.
+ * string [address_alias] - Address alias.
+ * string [address_zip] - The zip code of the address.
+ * array [terms] - The object to query to ElasticSearch.
+ * array [custom_data] - Order custom data.
+ * string [barcode] - Tracking number for order.
+ * string [airbillno] - Additional tracking number for order.
+ * string [sorted_on_date] - Datetime String with "T" delimiter, ISO 8601.
+ * int [sorted_on_utc] - Timestamp only; replaced data in `sorted_on_date` property.
+ * string [first_name] - The first name.
+ * string [last_name] - The last name.
+ * string [email] - E-mail.
+ * string [phone] - The phone number.
+ * string [address_1] - The order Address line 1.
+ * string [address_alias] - Address alias.
+ * string [address_zip] - The zip code the address is located in.
+ * array [filters] - Filter parameters.
+ * string[] [order_ids] - Array of included order ids, HEX-Strings.
+ * string[] [excluded_ids] - Array of excluded order ids, HEX-Strings.
+ * string[] [tracking_numbers] - Array of tracking number of orders.
+ * bool [only_geocoded]
+ * int|string|array [updated_timestamp] - Can be unix timestamp or ISO 8601 or array [
+ * "start" => "timestamp or ISO 8601",
+ * "end" => "timestamp or ISO 8601"
+ * ]
+ * int|string|array [created_timestamp] - Can be unix timestamp or ISO 8601 or array [
+ * "start" => "timestamp or ISO 8601",
+ * "end" => "timestamp or ISO 8601"
+ * ]
+ * int|string|array [scheduled_for] - Can be unix timestamp or ISO 8601 or array [
+ * "start" => "timestamp or ISO 8601",
+ * "end" => "timestamp or ISO 8601"
+ * ]
+ * bool [only_unscheduled]
+ * int|string|array [day_added] - Can be unix timestamp or ISO 8601 or array [
+ * "start" => "timestamp or ISO 8601",
+ * "end" => "timestamp or ISO 8601"
+ * ]
+ * int|string|array [sorted_on] - Can be unix timestamp or ISO 8601 or array [
+ * "start" => "timestamp or ISO 8601",
+ * "end" => "timestamp or ISO 8601"
+ * ]
+ * string[] [address_stop_types] - Array of stop type names, possible values
+ * 'DELIVERY', 'PICKUP', 'BREAK', 'MEETUP',
+ * 'SERVICE', 'VISIT' or 'DRIVEBY'.
+ * int[] [last_statuses] - Array of statuses.
+ * int[] [territory_ids] - Array of territory ids.
+ * string [done_day]
+ * string [possession_day]
+ * string[] [groups]
+ * string [display= 'all'] - Filtering by the in_route_count field, is one of
+ * 'routed', 'unrouted', 'all'
+ * @return ResponseSearch
+ * @throws Exception\ApiError
+ */
+ public function search(?array $params = null) : ResponseSearch
+ {
+ $allBodyFields = ['order_ids', 'return_provided_fields_as_map', 'orderBy', 'limit',
+ 'offset', 'fields', 'addition', 'search', 'filters'
+ ];
+
+ $result = Route4Me::makeRequst([
+ 'url' => Endpoint::ORDER,
+ 'method' => 'POST',
+ 'HTTPHEADER' => 'Content-Type: application/json',
+ 'body' => ($params ? Route4Me::generateRequestParameters($allBodyFields, $params) : [])
+ ]);
+
+ if (isset($result)) {
+ return new ResponseSearch($result);
+ }
+ return [];
+ }
+
+ /**
+ * Update the batch of orders (asynchronous, by filters)
+ *
+ * @since 1.3.0
+ *
+ * @param array $params - Batch update parameters.
+ * array data - Order values for batch update, look for more
+ * information in create()
+ * array search - Search parameters for batch update,
+ * look for more information in search()
+ * array filters - Filter parameters for batch update,
+ * look for more information in search()
+ * @return bool
+ * @throws Exception\ApiError
+ */
+ public function batchUpdateByFilters(array $params) : bool
+ {
+ $allBodyFields = ['data', 'search', 'filters'];
+
+ $res = Route4Me::makeRequst([
+ 'url' => Endpoint::ORDER_BATCH_UPDATE_FILTER,
+ 'method' => 'PUT',
+ 'HTTPHEADER' => 'Content-Type: application/json',
+ 'body' => Route4Me::generateRequestParameters($allBodyFields, $params)
+ ]);
+ return (isset($res['success']) && $res['success'] == 1 ? true : false);
+ }
+
+ /**
+ * Delete the batch of orders
+ *
+ * @since 1.3.0
+ *
+ * @param string[] $orderIds - Array of Order IDs, HEX-Strings.
+ * @return bool
+ * @throws Exception\ApiError
+ */
+ public function batchDelete(array $orderIds) : bool
+ {
+ $res = Route4Me::makeRequst([
+ 'url' => Endpoint::ORDER_BATCH_DELETE,
+ 'method' => 'POST',
+ 'HTTPHEADER' => 'Content-Type: application/json',
+ 'body' => ['order_ids' => $orderIds]
+ ]);
+ return (isset($res['status']) ? $res['status'] : false);
+ }
+
+ /**
+ * Update the batch of orders by ids
+ *
+ * @since 1.3.0
+ *
+ * @param string[] $orderIds - Array of Order IDs, HEX-Strings.
+ * @param array $data - Order values for batch update,
+ * look for more information in create()
+ * @return ResponseOrder[]
+ * @throws Exception\ApiError
+ */
+ public function batchUpdate(array $orderIds, $data) : array
+ {
+ $allBodyFields = ['member_id', 'address_1', 'address_2', 'address_alias',
+ 'address_city', 'address_state', 'address_zip', 'address_country', 'address_geo', 'curbside_geo',
+ 'date_scheduled_for', 'order_status_id', 'is_pending', 'is_accepted',
+ 'is_started', 'is_completed', 'is_validated', 'phone', 'first_name',
+ 'last_name', 'email', 'custom_data', 'local_time_windows', 'local_timezone_string',
+ 'service_time', 'color', 'tracking_number', 'address_stop_type', 'last_status', 'weight',
+ 'cost', 'revenue', 'cube', 'pieces', 'group', 'address_priority',
+ 'address_customer_po', 'custom_fields'
+ ];
+
+ $res = Route4Me::makeRequst([
+ 'url' => Endpoint::ORDER_BATCH_UPDATE,
+ 'method' => 'POST',
+ 'HTTPHEADER' => 'Content-Type: application/json',
+ 'body' => [
+ 'order_ids' => $orderIds,
+ 'data' => Route4Me::generateRequestParameters($allBodyFields, $data)
+ ]
+ ]);
+
+ $orders = [];
+ if (is_array($res)) {
+ foreach ($res as $key => $value) {
+ $orders[] = new ResponseOrder($value);
+ }
+ }
+ return $orders;
+ }
+
+ /**
+ * Create the batch of orders
+ *
+ * @since 1.3.0
+ *
+ * @param array $orders - Array of Orders or of array.
+ * look for more information in create()
+ * @return bool
+ * @throws Exception\ApiError
+ */
+ public function batchCreate(array $orders) : bool
+ {
+ $allBodyFields = ['member_id', 'address_1', 'address_2', 'address_alias',
+ 'address_city', 'address_state', 'address_zip', 'address_country', 'address_geo', 'curbside_geo',
+ 'date_scheduled_for', 'order_status_id', 'is_pending', 'is_accepted',
+ 'is_started', 'is_completed', 'is_validated', 'phone', 'first_name',
+ 'last_name', 'email', 'custom_data', 'local_time_windows', 'local_timezone_string',
+ 'service_time', 'color', 'tracking_number', 'address_stop_type', 'last_status', 'weight',
+ 'cost', 'revenue', 'cube', 'pieces', 'group', 'address_priority',
+ 'address_customer_po', 'custom_fields'
+ ];
+
+ $body = [];
+ foreach ($orders as $key => $order) {
+ $body[] = Route4Me::generateRequestParameters($allBodyFields, $order);
+ }
+
+ $res = Route4Me::makeRequst([
+ 'url' => Endpoint::ORDER_BATCH_CREATE,
+ 'method' => 'POST',
+ 'HTTPHEADER' => 'Content-Type: application/json',
+ 'body' => ['data' => $body]
+ ]);
+ return (isset($res['status']) ? $res['status'] : false);
+ }
+
+ /**
+ * Get a list of Order Custom Fields
+ *
+ * @since 1.3.0
+ *
+ * @return CustomField[]
+ * @throws Exception\ApiError
+ */
+ public function getOrderCustomFields() : array
+ {
+ $res = Route4Me::makeRequst([
+ 'url' => Endpoint::ORDER_CUSTOM_FIELDS,
+ 'method' => 'GET'
+ ]);
+ if (isset($result) && isset($result['data']) && is_array($result['data']) && is_array($result['data'][0])) {
+ return new ResponseOrder($result['data'][0]);
+ }
+ $ocf = [];
+ if (isset($res) && isset($res['data']) && is_array($res['data'])) {
+ foreach ($res['data'] as $key => $value) {
+ $ocf[] = new CustomField($value);
+ }
+ }
+ return $ocf;
+ }
+
+ /**
+ * Create one Order Custom Field
+ *
+ * @since 1.3.0
+ *
+ * @param array $params_or_custom_field - Params of CustomField custom field
+ * string data.order_custom_field_name - Name, max 128 characters.
+ * string data.order_custom_field_type - Type, max 128 characters.
+ * string data.order_custom_field_label - Label, max 128 characters.
+ * array data.order_custom_field_type_info - Info, as JSON Object max 4096 characters.
+ * @return CustomField
+ * @throws Exception\ApiError
+ */
+ public function createOrderCustomField($params_or_custom_field) : CustomField
+ {
+ $allBodyFields = ['order_custom_field_name', 'order_custom_field_type',
+ 'order_custom_field_label', 'order_custom_field_type_info'];
+
+ return $this->toCustomField(Route4Me::makeRequst([
+ 'url' => Endpoint::ORDER_CUSTOM_FIELDS,
+ 'method' => 'POST',
+ 'HTTPHEADER' => 'Content-Type: application/json',
+ 'body' => Route4Me::generateRequestParameters($allBodyFields, $params_or_custom_field)
+ ]));
+ }
+
+ /**
+ * Update one Order Custom Fields
+ *
+ * @since 1.3.0
+ *
+ * @param array $uuid - OrderCustomField ID, HEX-string.
+ * @param array $params_or_custom_field - Params of Order custom field
+ * string data.order_custom_field_type - Type, max 128 characters.
+ * string data.order_custom_field_label - Label, max 128 characters.
+ * array data.order_custom_field_type_info - Info, as JSON Object max 4096 characters.
+ * @return CustomField
+ * @throws Exception\ApiError
+ */
+ public function updateOrderCustomField(string $uuid, $params_or_custom_field) : CustomField
+ {
+ $allBodyFields = ['order_custom_field_type', 'order_custom_field_label', 'order_custom_field_type_info'];
+
+ return $this->toCustomField(Route4Me::makeRequst([
+ 'url' => Endpoint::ORDER_CUSTOM_FIELDS . '/' . $uuid,
+ 'method' => 'PUT',
+ 'HTTPHEADER' => 'Content-Type: application/json',
+ 'body' => Route4Me::generateRequestParameters($allBodyFields, $params_or_custom_field)
+ ]));
+ }
+
+ /**
+ * Delete an Order Custom Fields
+ *
+ * @since 1.3.0
+ *
+ * @param array $uuid - OrderCustomField ID, HEX-string.
+ * @return CustomField
+ * @throws Exception\ApiError
+ */
+ public function deleteOrderCustomField(string $uuid) : CustomField
+ {
+ return $this->toCustomField(Route4Me::makeRequst([
+ 'url' => Endpoint::ORDER_CUSTOM_FIELDS . '/' . $uuid,
+ 'method' => 'DELETE'
+ ]));
+ }
+
+ private function toResponseOrder($result) : ResponseOrder
+ {
+ if (is_array($result)) {
+ return new ResponseOrder($result);
+ }
+ throw new ApiError('Can not convert result to ResponseOrder object.');
+ }
+
+ private function toCustomField($result) : CustomField
+ {
+ if (isset($result) && isset($result['data']) && is_array($result['data'])) {
+ return new CustomField($result['data']);
+ }
+ throw new ApiError('Can not convert result to CustomField object.');
+ }
+}
diff --git a/src/Route4Me/V5/Orders/ResponseOrder.php b/src/Route4Me/V5/Orders/ResponseOrder.php
new file mode 100644
index 0000000..e05b8dd
--- /dev/null
+++ b/src/Route4Me/V5/Orders/ResponseOrder.php
@@ -0,0 +1,309 @@
+ $value) {
+ if (isset($params[$key])) {
+ if ($key === 'local_time_windows') {
+ $this->{$key} = array();
+ foreach ($params[$key] as $ltw_key => $ltw_value) {
+ if (is_array($ltw_value)) {
+ array_push($this->{$key}, new LocalTimeWindow($ltw_value));
+ } elseif (is_object($ltw_value) && $ltw_value instanceof LocalTimeWindow) {
+ array_push($this->{$key}, $ltw_value);
+ }
+ }
+ } elseif ($key === 'custom_user_fields') {
+ $this->{$key} = array();
+ foreach ($params[$key] as $cf_key => $cf_value) {
+ if (is_array($cf_value)) {
+ array_push($this->{$key}, new CustomField($cf_value));
+ } elseif (is_object($cf_value) && $cf_value instanceof CustomField) {
+ array_push($this->{$key}, $cf_value);
+ }
+ }
+ } elseif ($key === 'address_geo' || $key === 'curbside_geo') {
+ if (is_array($params[$key])) {
+ $this->{$key} = new GPSCoords($params[$key]);
+ } elseif (is_object($params[$key]) && $params[$key] instanceof GPSCoords) {
+ $this->{$key} = $params[$key];
+ }
+ } elseif ($key === 'custom_data') {
+ if (is_array($params[$key])) {
+ $this->{$key} = new CustomData($params[$key]);
+ } elseif (is_object($params[$key]) && $params[$key] instanceof CustomData) {
+ $this->{$key} = $params[$key];
+ }
+ } else {
+ $this->{$key} = $params[$key];
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/Route4Me/V5/Orders/ResponseSearch.php b/src/Route4Me/V5/Orders/ResponseSearch.php
new file mode 100644
index 0000000..03881ac
--- /dev/null
+++ b/src/Route4Me/V5/Orders/ResponseSearch.php
@@ -0,0 +1,54 @@
+ $value) {
+ if (isset($params[$key])) {
+ if ($key === 'results') {
+ $this->{$key} = array();
+ foreach ($params[$key] as $r_key => $r_value) {
+ if (is_array($r_value)) {
+ array_push($this->{$key}, new ResponseOrder($r_value));
+ } elseif (is_object($r_value) && $r_value instanceof ResponseOrder) {
+ array_push($this->{$key}, $r_value);
+ }
+ }
+ } else {
+ $this->{$key} = $params[$key];
+ }
+ }
+ }
+ }
+ }
+}