From 0ce0cf5a441b380cd6bfe2f1bfc80f92fbbf6f59 Mon Sep 17 00:00:00 2001 From: Codeliner Date: Mon, 7 Apr 2014 23:21:09 +0200 Subject: [PATCH] Implement complete booking procedure as single page js app - New resource RouteCandidate - Add endpoint to update CargoRouting - Expand UI functionality - Adapt book new cargo feature test --- README.md | 38 +-- composer.json | 5 +- features/book_new_cargo.feature | 20 +- features/bootstrap/FeatureContext.php | 30 +- module/Application/config/module.config.php | 32 +- .../src/Application/Form/CargoForm.php | 4 +- .../src/Application/Resource/CargoRouting.php | 72 ++++- .../Application/Resource/RouteCandidate.php | 65 ++++ .../Service/RouteCandidateFactory.php | 37 +++ .../view/application/booking-app/add.phtml | 40 --- .../view/application/booking-app/index.phtml | 296 +++++++++++++++++- .../view/application/booking-app/show.phtml | 69 ---- .../booking-app/suggest-itineraries.phtml | 71 ----- .../view/application/index/index.phtml | 2 +- .../Assembler/RouteCandidateDtoAssembler.php | 2 +- .../API/Booking/Dto/CargoRoutingDto.php | 8 +- .../API/Booking/Dto/RouteCandidateDto.php | 19 ++ 17 files changed, 568 insertions(+), 242 deletions(-) create mode 100644 module/Application/src/Application/Resource/RouteCandidate.php create mode 100644 module/Application/src/Application/Resource/Service/RouteCandidateFactory.php delete mode 100644 module/Application/view/application/booking-app/add.phtml delete mode 100644 module/Application/view/application/booking-app/show.phtml delete mode 100644 module/Application/view/application/booking-app/suggest-itineraries.phtml diff --git a/README.md b/README.md index 67d3daf..92dbb40 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,12 @@ the [features folder](https://github.com/codeliner/php-ddd-cargo-sample/tree/mas We make use of [Behat](http://behat.org/) and [Mink](http://mink.behat.org/) to test our business expectations. +You can run the feature tests by navigating to the project root and start the selenium server shipped with the sample app with following command: +`java -jar bin/selenium-server-standalone-2.37.0.jar` +After the server started successful open another console, navigate to project root again and run Behat with the command `php bin/behat`. + +*If it does not work, check that the behat file is executable. + Unit Tests ---------- Unit Tests are of course also available. You can find them in [module/CargoBackend/tests](https://github.com/codeliner/php-ddd-cargo-sample/tree/master/module/CargoBackend/tests). @@ -62,34 +68,4 @@ Maybe I've missed a concept that you hoped to find in the example. Chapter Overview ---------------- -###ChapterOne -`git checkout ChapterOne` - -Chapter One release contains the first draft of the Cargo DDD model. -It contains the Entities `Cargo` and `Voyage` and also an `Application BookingService` that works with an `overbooking policy` -to allow the booking of a Cargo even when the Voyage has not enough free capacity. - -[ChapterOne Review](https://github.com/codeliner/php-ddd-cargo-sample/blob/master/docs/ChapterOne-Review.md) -###ChapterTwo -`git checkout ChapterTwo` - -In Chapter Two we learn the importance of the Ubiquitous Language. With it's help the team works out a Cargo Router and redefines the use cases for the Shipping Application. The `Application BookingService` is replaced with a `Application RoutingService`, cause the system focuses on planing an `Itinerary` for a `Cargo` that satisfies a `RouteSpecification`. - -[ChapterTwo Review](https://github.com/codeliner/php-ddd-cargo-sample/blob/master/docs/ChapterTwo-Review.md) - -###ChapterThree -`git checkout ChapterThree` - -ChapterThree is about Model-Driven Design. - -> "Design a portion of the software system to reflect the domain model in a very literal way, so that -> mapping is obvious. Revisit the model and modify it to be implemented more naturally in software, -> even as you seek to make it reflect deeper insight into the domain. Demand a single model that -> serves both purposes well, in addition to supporting a robust UBIQUITOUS LANGUAGE. -> Draw from the model the terminology used in the design and the basic assignment of responsibilities. -> The code becomes an expression of the model, so a change to the code may be a change to the -> model. Its effect must ripple through the rest of the project's activities accordingly." -> -> -- Eric Evans: Domain-Driven Design: Tackling Complexity in the Heart of Software - -[ChapterThree Review](https://github.com/codeliner/php-ddd-cargo-sample/blob/master/docs/ChapterThree-Review.md) +The chapter overview has moved to the [PHP DDD Cargo Sample project page](http://codeliner.github.io/php-ddd-cargo-sample/) diff --git a/composer.json b/composer.json index d9315a2..3f12e41 100644 --- a/composer.json +++ b/composer.json @@ -5,7 +5,10 @@ "keywords": [ "DDD", "zf2", - "Domain Driven Design" + "doctrine", + "domain driven design", + "sample", + "REST" ], "homepage": "https://github.com/codeliner/php-ddd-cargo-sample", "authors": [ diff --git a/features/book_new_cargo.feature b/features/book_new_cargo.feature index d7036db..5d3b0a2 100644 --- a/features/book_new_cargo.feature +++ b/features/book_new_cargo.feature @@ -1,14 +1,18 @@ Feature: Book new Cargo In order to manage a transport of a Cargo As a booking clerk - I need to define an origin and a destination of a Cargo and assign it to a proper itinerary + I need to define an origin and a destination of a Cargo and assign it to a proper route @javascript -Scenario: Add a Cargo and assign Itinerary - Given I am on "application/cargo/add" - When I select "DEHAM" from "origin" - And I select "USNYC" from "destination" +Scenario: Add a Cargo and assign route + Given I am on "application/bookingApp/index" + Then I should wait until I see "#book-cargo" + When I follow "book-cargo" + And I select "DEHAM" from "origin" + And I select "USNYC" from "final_destination" And I click the submit button - And I follow "assign-itinerary-link-1" - Then the url should match "application/cargo/show/trackingid/[\w-]{36,36}" - And I should see 1 ".itinerary" elements + Then I should wait until I see "#route-candidate-list" + When I follow first ".assign-cargo-btn" link + Then I should wait until I see "#cargo-list" + When I click on first item in the list "#cargo-list" + Then I should see 1 ".itinerary" elements diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index ab4b26e..d5f54fd 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -56,11 +56,11 @@ static public function iniializeZendFramework() public static function clearDatabase() { $em = self::$zendApp->getServiceManager()->get('doctrine.entitymanager.orm_default'); - $q = $em->createQuery('delete from Application\Domain\Model\Cargo\Cargo'); + $q = $em->createQuery('delete from CargoBackend\Model\Cargo\Cargo'); $q->execute(); - $q = $em->createQuery('delete from Application\Domain\Model\Cargo\RouteSpecification'); + $q = $em->createQuery('delete from CargoBackend\Model\Cargo\RouteSpecification'); $q->execute(); - $q = $em->createQuery('delete from Application\Domain\Model\Cargo\Itinerary'); + $q = $em->createQuery('delete from CargoBackend\Model\Cargo\Itinerary'); $q->execute(); } @@ -80,6 +80,16 @@ public function iClickTheSubmitButton() throw new \RuntimeException("Can not find the submit btn"); } } + + /** + * @Then /^I should wait until I see "([^"]*)"$/ + */ + public function iShouldSeeAvailableRoutes($arg1) + { + $this->getSession()->wait(5000, '(0 === jQuery.active)'); + + $this->assertElementOnPage($arg1); + } /** * @When /^I click on first item in the list "([^"]*)"$/ @@ -95,6 +105,20 @@ public function iClickOnFirstItemInTheList($arg1) $li->find('css', 'a')->click(); } + + /** + * @When /^I follow first "([^"]*)" link$/ + */ + public function iFollowFirstLink($arg1) + { + $page = $this->getSession()->getPage(); + + $link = $page->find('css', $arg1); + + if ($link) { + $link->click(); + } + } /** * @Given /^I wait until I am on page "(?P[^"]+)"$/ diff --git a/module/Application/config/module.config.php b/module/Application/config/module.config.php index cba60d7..946e468 100644 --- a/module/Application/config/module.config.php +++ b/module/Application/config/module.config.php @@ -68,6 +68,18 @@ ), ), + 'may_terminate' => true, + 'child_routes' => array( + 'routecandidates' => array( + 'type' => 'Segment', + 'options' => array( + 'route' => '/routecandidates', + 'defaults' => array( + 'controller' => 'Api\Controller\RouteCandidates', + ), + ), + ), + ), ) ) ), @@ -90,9 +102,10 @@ ), 'service_manager' => array( 'factories' => array( - 'main_navigation' => 'Zend\Navigation\Service\DefaultNavigationFactory', - 'cargo_form' => 'Application\Form\Service\CargoFormFactory', - 'cargo_routing_resource' => 'Application\Resource\Service\CargoRoutingFactory', + 'main_navigation' => 'Zend\Navigation\Service\DefaultNavigationFactory', + 'cargo_form' => 'Application\Form\Service\CargoFormFactory', + 'cargo_routing_resource' => 'Application\Resource\Service\CargoRoutingFactory', + 'route_candidate_resource' => 'Application\Resource\Service\RouteCandidateFactory' ), 'abstract_factories' => array( 'Zend\Cache\Service\StorageCacheAbstractServiceFactory', @@ -178,6 +191,15 @@ 'route_name' => 'api/cargoroutings', 'identifier_name' => 'tracking_id', 'collection_name' => 'cargoroutings', + 'collection_http_options' => array('get', 'post'), + 'resource_http_options' => array('get', 'put'), + ), + 'Api\Controller\RouteCandidates' => array( + 'listener' => 'route_candidate_resource', + 'route_name' => 'api/cargoroutings/routecandidates', + 'collection_name' => 'routecandidates', + 'collection_http_options' => array('get'), + 'resource_http_options' => array(), ) ), 'renderer' => array( @@ -188,6 +210,10 @@ 'hydrator' => 'ArraySerializable', 'identifier_name' => 'tracking_id', 'route' => 'api/cargoroutings', + ), + 'CargoBackend\API\Booking\Dto\RouteCandidateDto' => array( + 'hydrator' => 'ArraySerializable', + 'route' => 'api/cargoroutings/routecandidates', ) ), ), diff --git a/module/Application/src/Application/Form/CargoForm.php b/module/Application/src/Application/Form/CargoForm.php index 1d35c5b..2f3f383 100644 --- a/module/Application/src/Application/Form/CargoForm.php +++ b/module/Application/src/Application/Form/CargoForm.php @@ -54,7 +54,7 @@ public function __construct(array $aLocationList, $anOptionList = array()) )); $this->add(array( - 'name' => 'finalDestination', + 'name' => 'final_destination', 'options' => array( 'label' => 'Destination', 'value_options' => $this->locations, @@ -114,7 +114,7 @@ public function getInputFilter() ) )); - $destinationInput = new Input('finalDestination'); + $destinationInput = new Input('final_destination'); $destinationInput->getValidatorChain() ->attach($inArrayValidator) ->attach($notSameValidator); diff --git a/module/Application/src/Application/Resource/CargoRouting.php b/module/Application/src/Application/Resource/CargoRouting.php index 980db6f..7ca5033 100644 --- a/module/Application/src/Application/Resource/CargoRouting.php +++ b/module/Application/src/Application/Resource/CargoRouting.php @@ -14,9 +14,12 @@ use Application\Form\CargoForm; use CargoBackend\API\Booking\BookingServiceInterface; use CargoBackend\API\Booking\Dto\CargoRoutingDto; +use CargoBackend\API\Booking\Dto\LegDto; +use CargoBackend\API\Booking\Dto\RouteCandidateDto; use CargoBackend\API\Exception\CargoNotFoundException; use PhlyRestfully\Exception\CreationException; use PhlyRestfully\Exception\DomainException; +use PhlyRestfully\Exception\UpdateException; use PhlyRestfully\ResourceEvent; use Zend\EventManager\AbstractListenerAggregate; use Zend\EventManager\EventInterface; @@ -63,6 +66,7 @@ public function __construct(BookingServiceInterface $aBookingService, CargoForm public function attach(EventManagerInterface $events) { $this->listeners[] = $events->attach('create', array($this, 'onCreate')); + $this->listeners[] = $events->attach('update', array($this, 'onUpdate')); $this->listeners[] = $events->attach('fetch', array($this, 'onFetch')); $this->listeners[] = $events->attach('fetchAll', array($this, 'onFetchAll')); @@ -71,6 +75,11 @@ public function attach(EventManagerInterface $events) $sharedEvents->attach('PhlyRestfully\Plugin\HalLinks', 'getIdFromResource', array($this, 'onGetIdFromResource')); } + /** + * @param ResourceEvent $e + * @return CargoRoutingDto + * @throws \PhlyRestfully\Exception\CreationException + */ public function onCreate(ResourceEvent $e) { $data = $e->getParam('data'); @@ -87,17 +96,22 @@ public function onCreate(ResourceEvent $e) $trackingId = $this->bookingService->bookNewCargo( $this->cargoFrom->get('origin')->getValue(), - $this->cargoFrom->get('finalDestination')->getValue() + $this->cargoFrom->get('final_destination')->getValue() ); $cargoRouting = new CargoRoutingDto(); $cargoRouting->setTrackingId($trackingId); $cargoRouting->setOrigin($this->cargoFrom->get('origin')->getValue()); - $cargoRouting->setFinalDestination($this->cargoFrom->get('finalDestination')->getValue()); + $cargoRouting->setFinalDestination($this->cargoFrom->get('final_destination')->getValue()); return $cargoRouting; } + /** + * @param ResourceEvent $e + * @return CargoRoutingDto + * @throws \PhlyRestfully\Exception\DomainException + */ public function onFetch(ResourceEvent $e) { $trackingId = $e->getRouteMatch()->getParam('tracking_id'); @@ -111,11 +125,43 @@ public function onFetch(ResourceEvent $e) return $cargoRouting; } + /** + * @param ResourceEvent $e + * @return \CargoBackend\API\Booking\Dto\CargoRoutingDto[] + */ public function onFetchAll(ResourceEvent $e) { return $this->bookingService->listAllCargos(); } + /** + * @param ResourceEvent $e + * @return \CargoBackend\API\Booking\Dto\CargoRoutingDto + * @throws \PhlyRestfully\Exception\UpdateException + */ + public function onUpdate(ResourceEvent $e) + { + $trackingId = $e->getRouteMatch()->getParam('tracking_id'); + + $data = $e->getParam('data'); + + if (! isset($data->legs)) { + throw new UpdateException("Legs missing in CargoRouting payload", 400); + } + + $routeCandidate = new RouteCandidateDto(); + + $routeCandidate->setLegs($this->toLegDtosFromData($data->legs)); + + $this->bookingService->assignCargoToRoute($trackingId, $routeCandidate); + + return $this->bookingService->loadCargoForRouting($trackingId); + } + + /** + * @param EventInterface $e + * @return bool|string + */ public function onGetIdFromResource(EventInterface $e) { $resource = $e->getParam('resource'); @@ -127,6 +173,26 @@ public function onGetIdFromResource(EventInterface $e) return false; } - //@TODO: Implement methods + /** + * @param array $legs + * @return LegDto[] + */ + private function toLegDtosFromData(array $legs) + { + $legDtos = array(); + + foreach ($legs as $legData) { + $legDto = new LegDto(); + + $legDto->setLoadLocation($legData['load_location']); + $legDto->setUnloadLocation($legData['unload_location']); + $legDto->setLoadTime($legData['load_time']); + $legDto->setUnloadTime($legData['unload_time']); + + $legDtos[] = $legDto; + } + + return $legDtos; + } } \ No newline at end of file diff --git a/module/Application/src/Application/Resource/RouteCandidate.php b/module/Application/src/Application/Resource/RouteCandidate.php new file mode 100644 index 0000000..2764ab1 --- /dev/null +++ b/module/Application/src/Application/Resource/RouteCandidate.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * Date: 03.04.14 - 20:08 + */ + +namespace Application\Resource; +use CargoBackend\API\Booking\BookingServiceInterface; +use PhlyRestfully\ResourceEvent; +use Zend\EventManager\AbstractListenerAggregate; +use Zend\EventManager\EventManagerInterface; + +/** + * Class RouteCandidate + * + * @package Application\Resource + * @author Alexander Miertsch + */ +class RouteCandidate extends AbstractListenerAggregate +{ + /** + * @var BookingServiceInterface + */ + private $bookingService; + + /** + * @param BookingServiceInterface $aBookingService + */ + public function __construct(BookingServiceInterface $aBookingService) + { + $this->bookingService = $aBookingService; + } + + /** + * Attach one or more listeners + * + * Implementors may add an optional $priority argument; the EventManager + * implementation will pass this to the aggregate. + * + * @param EventManagerInterface $events + * + * @return void + */ + public function attach(EventManagerInterface $events) + { + $this->listeners[] = $events->attach('fetchAll', array($this, 'onFetchAll')); + } + + /** + * @param ResourceEvent $e + * @return \CargoBackend\API\Booking\Dto\RouteCandidateDto[] + */ + public function onFetchAll(ResourceEvent $e) + { + $trackingId = $e->getRouteMatch()->getParam('tracking_id'); + + return $this->bookingService->requestPossibleRoutesForCargo($trackingId); + } +} + \ No newline at end of file diff --git a/module/Application/src/Application/Resource/Service/RouteCandidateFactory.php b/module/Application/src/Application/Resource/Service/RouteCandidateFactory.php new file mode 100644 index 0000000..8efdda7 --- /dev/null +++ b/module/Application/src/Application/Resource/Service/RouteCandidateFactory.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * Date: 03.04.14 - 22:16 + */ + +namespace Application\Resource\Service; + +use Application\Resource\RouteCandidate; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; + +/** + * Class RouteCandidateFactory + * + * @package Application\Resource\Service + * @author Alexander Miertsch + */ +class RouteCandidateFactory implements FactoryInterface +{ + /** + * Create service + * + * @param ServiceLocatorInterface $serviceLocator + * @return RouteCandidate + */ + public function createService(ServiceLocatorInterface $serviceLocator) + { + return new RouteCandidate($serviceLocator->get('cargo_booking_service')); + } +} + \ No newline at end of file diff --git a/module/Application/view/application/booking-app/add.phtml b/module/Application/view/application/booking-app/add.phtml deleted file mode 100644 index 301dd8d..0000000 --- a/module/Application/view/application/booking-app/add.phtml +++ /dev/null @@ -1,40 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -?> -
-

translate('Add new Cargo') ?>

-

translate('In the ChapterTwo version of the Shipping System you can specify origin and destination of a Cargo. In a second step, the booking system suggest possible routes and you can assign the new Cargo to one of the routes.') ?>

-
-
-
- form; - $form->prepare(); - - $form->setAttribute('method', 'post'); - - echo $this->form()->openTag($form); - - $origin = $form->get('origin'); - echo $this->ztbFormElement($origin); - - $destination = $form->get('destination'); - echo $this->ztbFormElement($destination); - - $trackingId = $form->get('trackingId'); - echo $this->ztbFormElement($trackingId); - - echo '

'; - - echo $this->ztbFormElement($form->get('send')); - - echo $this->form()->closeTag(); - ?> -
-
\ No newline at end of file diff --git a/module/Application/view/application/booking-app/index.phtml b/module/Application/view/application/booking-app/index.phtml index 4a1930a..41fa02b 100644 --- a/module/Application/view/application/booking-app/index.phtml +++ b/module/Application/view/application/booking-app/index.phtml @@ -14,6 +14,9 @@
loading ...
+
+ +
+ + + + + + + + + + + + + diff --git a/module/Application/view/application/booking-app/show.phtml b/module/Application/view/application/booking-app/show.phtml deleted file mode 100644 index d5a1126..0000000 --- a/module/Application/view/application/booking-app/show.phtml +++ /dev/null @@ -1,69 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/* @var $cargo \CargoBackend\API\Dto\CargoDto */ -$cargo = $this->cargo; -?> -
-

translate('Cargo Overview') ?>

-

getTrackingId() ?>

-
-
-
-

Cargo from translate($cargo->getOrigin()) ?>

-
-
-
-
-

Current route specification

-
-
-
-
- From: translate($cargo->getRouteSpecification()->getOrigin()) ?> -
-
- To: translate($cargo->getRouteSpecification()->getDestination()) ?> -
-
-
-
-

Available routes

-
-
-
-
-
-
-

translate('Route') ?>

-
-
- getItinerary()->getLegs() as $leg): ?> -
-
- Load location: translate($leg->getLoadLocation()) ?> -
-
- Load time: getLoadTime() ?> -
-
-
-
- Unload location: translate($leg->getUnloadLocation()) ?> -
-
- Unload time: getUnloadTime() ?> -
-
- -
-
-
-
- diff --git a/module/Application/view/application/booking-app/suggest-itineraries.phtml b/module/Application/view/application/booking-app/suggest-itineraries.phtml deleted file mode 100644 index c42cad8..0000000 --- a/module/Application/view/application/booking-app/suggest-itineraries.phtml +++ /dev/null @@ -1,71 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -?> -
-

translate('Assign Itinerary to Cargo') ?>

-
-
-
-

Cargo from cargo['origin'] ?> (cargo['trackingId'] ?> )

-
-
-
-
-

Current route specification

-
-
-
-
- From: routeSpecification['origin'] ?> -
-
- To: routeSpecification['destination'] ?> -
-
-
-
-

Available routes

-
-
-itineraries as $index => $itinerary): ?> -
-
-
-
-

translate('Route') . ' ' . ($index+1) ?>

-
-
- -
-
- Load location: -
-
- Load time: -
-
-
-
- Unload location: -
-
- Unload time: -
-
- -
- -
-
-
-
-
- diff --git a/module/Application/view/application/index/index.phtml b/module/Application/view/application/index/index.phtml index 52a363b..11e72d7 100644 --- a/module/Application/view/application/index/index.phtml +++ b/module/Application/view/application/index/index.phtml @@ -1,6 +1,6 @@

translate('Welcome to the PHP DDD Cargo Sample') ?>

-

translate('Congratulations! You have successfully installed the Container Shipping System. You are currently running the ChapterThree Version of the Application.') ?>

+

translate('Congratulations! You have successfully installed the Container Shipping System. You are currently running the ChapterFour Version of the Application.') ?>

translate('Fork PHP DDD Cargo Sample on GitHub') ?> »

diff --git a/module/CargoBackend/src/CargoBackend/API/Booking/Assembler/RouteCandidateDtoAssembler.php b/module/CargoBackend/src/CargoBackend/API/Booking/Assembler/RouteCandidateDtoAssembler.php index d1c9132..a4f39b6 100644 --- a/module/CargoBackend/src/CargoBackend/API/Booking/Assembler/RouteCandidateDtoAssembler.php +++ b/module/CargoBackend/src/CargoBackend/API/Booking/Assembler/RouteCandidateDtoAssembler.php @@ -38,7 +38,7 @@ public function toDto(Itinerary $anItinerary) $legDto->setLoadLocation($leg->loadLocation()); $legDto->setUnloadLocation($leg->unloadLocation()); $legDto->setLoadTime($leg->loadTime()->format(\DateTime::ISO8601)); - $legDto->setUnloadTime($leg->loadTime()->format(\DateTime::ISO8601)); + $legDto->setUnloadTime($leg->unloadTime()->format(\DateTime::ISO8601)); $legs[] = $legDto; } diff --git a/module/CargoBackend/src/CargoBackend/API/Booking/Dto/CargoRoutingDto.php b/module/CargoBackend/src/CargoBackend/API/Booking/Dto/CargoRoutingDto.php index 05adb8d..87e94ce 100644 --- a/module/CargoBackend/src/CargoBackend/API/Booking/Dto/CargoRoutingDto.php +++ b/module/CargoBackend/src/CargoBackend/API/Booking/Dto/CargoRoutingDto.php @@ -130,10 +130,10 @@ public function getArrayCopy() } return array( - 'tracking_id' => $this->getTrackingId(), - 'origin' => $this->getOrigin(), - 'final_destination' => $this->getFinalDestination(), - 'legs' => $legsArrayCopy + 'tracking_id' => $this->getTrackingId(), + 'origin' => $this->getOrigin(), + 'final_destination' => $this->getFinalDestination(), + 'legs' => $legsArrayCopy ); } } diff --git a/module/CargoBackend/src/CargoBackend/API/Booking/Dto/RouteCandidateDto.php b/module/CargoBackend/src/CargoBackend/API/Booking/Dto/RouteCandidateDto.php index 04ff7a2..3ede067 100644 --- a/module/CargoBackend/src/CargoBackend/API/Booking/Dto/RouteCandidateDto.php +++ b/module/CargoBackend/src/CargoBackend/API/Booking/Dto/RouteCandidateDto.php @@ -35,5 +35,24 @@ public function getLegs() { return $this->legs; } + + /** + * @return array + */ + public function getArrayCopy() + { + $legsList = array(); + + foreach ($this->getLegs() as $leg) { + $legsList[] = array( + 'load_location' => $leg->getLoadLocation(), + 'unload_location' => $leg->getUnloadLocation(), + 'load_time' => $leg->getLoadTime(), + 'unload_time' => $leg->getUnloadTime() + ); + } + + return array('legs' => $legsList); + } } \ No newline at end of file