Skip to content

[WIP] - Add order by phone #11

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: domain-model
Choose a base branch
from
Open
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
230 changes: 226 additions & 4 deletions features/bootstrap/ApplicationContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,38 @@
use Behat\Behat\Tester\Exception\PendingException;
use Behat\Gherkin\Node\PyStringNode;
use Behat\Gherkin\Node\TableNode;
use Behat\Transliterator\Transliterator;
use Example\Domain\Administration\Application\AdministrationService;
use Example\Domain\Administration\Application\HireCandidateCommand;
use Example\Domain\Administration\Application\MenuService;
use Example\Domain\Administration\Application\RegisterNewRecipe;
use Example\Domain\Administration\Application\ReleaseRecipe;
use Example\Domain\Administration\DomainModel\RecipeId;
use Example\Domain\Administration\DomainModel\RecipeName;
use Example\Domain\Common\DomainModel\FullName;
use Example\Domain\Administration\DomainModel\Identity\OwnerId;
use Example\Domain\Administration\DomainModel\Owner;
use Example\Domain\Common\DomainModel\JobTitle;
use Example\Domain\Common\DomainModel\Money;
use Example\Domain\Sale\Application\BuyerService;
use Example\Domain\Sale\Application\CashierService;
use Example\Domain\Sale\Application\CreateMealOnRecipeCreated;
use Example\Domain\Sale\Application\OrderService;
use Example\Domain\Sale\Application\WaitressService;
use Example\Domain\Sale\DomainModel\BuyerId;
use Example\Domain\Sale\DomainModel\BuyerRepository;
use Example\Domain\Sale\DomainModel\CustomerType;
use Example\Domain\Sale\DomainModel\Identity\EmployeeId;
use Example\Domain\Sale\DomainModel\Identity\MealId;
use Example\Domain\Sale\DomainModel\Identity\OrderId;
use Example\Domain\Sale\DomainModel\PhoneNumber;
use Example\Domain\Shipping\Application\CreateDeliveryBoyHandler;
use Example\Infrastructure\ForgedIdGenerator;
use Example\Infrastructure\InMemory\EmployeeCollection;
use Example\Infrastructure\InMemory\OwnerCollection;
use Example\Infrastructure\InMemory\Sale\BuyerCollection;
use Example\Infrastructure\InMemory\Sale\MealCollection;
use Example\Infrastructure\InMemory\Sale\OrderCollection;
use Example\Infrastructure\Symfony\SymfonyPublisher;
use Example\Domain\Sale\Application\CookService;
use PHPUnit_Framework_Assert as Assert;
Expand All @@ -37,11 +58,51 @@ class ApplicationContext implements Context, SnippetAcceptingContext
*/
private $owners;

/**
* @var BuyerRepository
*/
private $buyers;

/**
* @var PhoneNumber[]
*/
private $phones = [];

/**
* @var AdministrationService
*/
private $administrationService;

/**
* @var MenuService
*/
private $menu;

/**
* @var BuyerService
*/
private $buyerService;

/**
* @var OrderService
*/
private $orderService;

/**
* @var OrderCollection
*/
private $orders;

/**
* @var MealCollection
*/
private $meals;

/**
* @var ForgedIdGenerator
*/
private $fakeIdGenerator;

/**
* Initializes context.
*
Expand All @@ -51,17 +112,28 @@ class ApplicationContext implements Context, SnippetAcceptingContext
*/
public function __construct()
{
// Infrastructure
$publisher = new SymfonyPublisher();
$this->buyers = new BuyerCollection();
$this->owners = new OwnerCollection();
$this->employees = new EmployeeCollection();
$this->fakeIdGenerator = new ForgedIdGenerator();
$this->orders = new OrderCollection();
$this->meals = new MealCollection();

// Administration context
$this->owners = new OwnerCollection();
$this->administrationService = new AdministrationService($this->owners, $publisher);
$this->menu = new MenuService($this->owners, $publisher);

// Sale context
$this->employees = new EmployeeCollection();
new CookService($this->employees, $publisher);
new CashierService($this->employees, $publisher);
$this->buyerService = new BuyerService($this->buyers, 'CA'); // default country
new WaitressService($this->employees, $publisher);
$this->orderService = new OrderService(
$this->orders, $publisher, $this->buyers, $this->meals, $this->fakeIdGenerator
);
new CreateMealOnRecipeCreated($this->meals, $publisher);

// Shipping context
new CreateDeliveryBoyHandler($this->employees, $publisher);
Expand All @@ -82,8 +154,40 @@ public function isTheStoreOwner($name)
*/
public function alreadyEmploysAs($ownerName, $employeeName, $role)
{
$this->owners->ownerWithId(new OwnerId(FullName::fromSingleString($ownerName)))
->hire(FullName::fromSingleString($employeeName), JobTitle::fromString($role));
$this->administrationService->hireCandidate(
new HireCandidateCommand(
new OwnerId(FullName::fromSingleString($ownerName)),
FullName::fromSingleString($employeeName),
JobTitle::fromString($role)
)
);
}

/**
* @Given :owner has created the recipe :recipeName with price of :recipePrice each
*/
public function hasCreatedTheRecipeWithPriceOfEach($owner, $recipeName, $recipePrice)
{
$this->menu->registerRecipe(
new RegisterNewRecipe(
new OwnerId(FullName::fromSingleString($owner)),
RecipeName::fromString($recipeName),
Money::fromInt($recipePrice)
)
);
}

/**
* @Given :owner has released the recipe :recipeName
*/
public function hasReleasedTheRecipe($owner, $recipeName)
{
$this->menu->releaseRecipe(
new ReleaseRecipe(
new OwnerId(FullName::fromSingleString($owner)),
new RecipeId(RecipeName::fromString($recipeName))
)
);
}

/**
Expand All @@ -93,6 +197,22 @@ public function postulateOnAJobOffering($applicantName)
{
}

/**
* @Given :customerName never ordered meals to the shop
*/
public function neverOrderedMealsToTheShop($customerName)
{
}

/**
* @Given :customerName gives his phone number :phoneNumber and home address :address
*/
public function givesHisPhoneNumberAndHomeAddress($customerName, $phoneNumber, $address)
{
$this->phones[$customerName] = PhoneNumber::fromString($phoneNumber, 'CA');
$this->buyerService->registerPhoneBuyer($phoneNumber, $address);
}

/**
* @When :ownerName hires :applicantName as the new :role
*/
Expand All @@ -107,6 +227,66 @@ public function hiresAsTheNew($ownerName, $applicantName, $role)
);
}

/**
* @When :waitressName starts the order :orderId of :customerName
*/
public function startsTheOrderOf($waitressName, $orderId, $customerName)
{
$this->fakeIdGenerator->returnsOrderIdOnNextCall(new OrderId($orderId));
$this->orderService->startOrder(
EmployeeId::fromName(FullName::fromSingleString($waitressName)),
CustomerType::PhoneCustomer(),
BuyerId::phoneBuyer($this->getPhoneNumberOfCustomer($customerName))
);
}

/**
* @When :customerName order :quantity meal :mealName on order :orderId
*/
public function orderMealOnOrder($customerName, $quantity, $mealName, $orderId)
{
$this->orderService->orderMeal(
new OrderId($orderId),
$quantity,
new MealId(Transliterator::transliterate($mealName))
);
}

/**
* @When :waitressName confirms that :customerName order confirmation number is :orderId at :time
*/
public function confirmsThatOrderConfirmationNumberIsAt($waitressName, $customerName, $orderId, $time)
{
$this->orderService->confirmOrder(
new OrderId($orderId),
new \DateTime($time)
);
}

/**
* @When :cookName finishes to cook the order :orderId at :time
*/
public function finishesToCookTheOrderAt($cookName, $orderId, $time)
{
throw new PendingException();
}

/**
* @When :deliveryBoyName delivers the order :orderId at :time
*/
public function deliversTheOrderAt($deliveryBoyName, $orderId, $time)
{
throw new PendingException();
}

/**
* @When :customerName pays :price to :deliveryBoyName
*/
public function paysTo($customerName, $price, $deliveryBoyName)
{
throw new PendingException();
}

/**
* @Then :ownerName should have :employeeCount employees
*/
Expand All @@ -126,4 +306,46 @@ public function thereShouldBeEmployeesWithTitle($employeeCount, $role)
(int) $employeeCount, $this->employees->employeesWithTitle(JobTitle::fromString($role))
);
}

/**
* @Then Order :orderId should be closed at :time
*/
public function orderShouldBeClosedAt($orderId, $time)
{
throw new PendingException();
}

/**
* @Then The order :orderId should have an income of :money
*/
public function theOrderShouldHaveAnIncomeOf($orderId, $money)
{
throw new PendingException();
}

/**
* @Then The order :orderId should registers a tip of :money
*/
public function theOrderShouldRegistersATipOf($orderId, $money)
{
throw new PendingException();
}

/**
* @Then The order :orderId should have taken :time to complete
*/
public function theOrderShouldHaveTakenToComplete($orderId, $time)
{
throw new PendingException();
}

/**
* @param string $customerName
*
* @return PhoneNumber
*/
private function getPhoneNumberOfCustomer($customerName)
{
return $this->phones[$customerName];
}
}
43 changes: 34 additions & 9 deletions features/manage-store.feature
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,60 @@ Feature:
And 'John' already employs 'Jake' as 'delivery boy'
And 'John' already employs 'Judy' as 'waitress'
And 'John' already employs 'Mark' as 'cashier'
And 'John' already employs 'Esther' as 'cook'
And 'John' has created the recipe 'All dressed pizza' with price of '10.00$' each
And 'John' has released the recipe 'All dressed pizza'
And 'John' has created the recipe 'Small fries' with price of '5.00$' each
And 'John' has released the recipe 'Small fries'

Scenario: Hiring new cashier to help customer pay for meals
Scenario: Hiring new cashier to help customer pay for recipes
Given 'Jane' postulate on a job offering
When 'John' hires 'Jane' as the new 'cashier'
Then 'John' should have 4 employees
Then 'John' should have 5 employees
And There should be 2 employees with 'cashier' title
# todo cashier receives payment from customer for order
# todo Should be in sale context

Scenario: Hiring new cook to cook meals
Scenario: Hiring new cook to cook recipes
Given 'Luke' postulate on a job offering
When 'John' hires 'Luke' as the new 'cook'
Then 'John' should have 4 employees
And There should be 1 employees with 'cook' title
Then 'John' should have 5 employees
And There should be 2 employees with 'cook' title
# todo cook prepare order of customer
# todo Should be in sale context

Scenario: Hiring new waitress to take order from customer
Given 'Leia' postulate on a job offering
When 'John' hires 'Leia' as the new 'waitress'
Then 'John' should have 4 employees
Then 'John' should have 5 employees
And There should be 2 employees with 'waitress' title
# todo waitress take order from customer (create order)
# todo Should be in sale context

Scenario: Hiring new delivery boy to deliver meals
Scenario: Hiring new delivery boy to deliver recipes
Given 'Han' postulate on a job offering
When 'John' hires 'Han' as the new 'delivery boy'
Then 'John' should have 4 employees
Then 'John' should have 5 employees
And There should be 2 employees with 'delivery boy' title
# todo delivery boy deliver meal to customer
# todo delivery boy deliver recipe to customer
# todo Should be in shipping context

Scenario: Cashier serves a phone customer who wishes its order to be delivered
# todo address must be in range of delivery
Given 'Billy' never ordered meals to the shop
And 'Billy' gives his phone number '555-5555' and home address '1 main street'
When 'Mark' starts the order '333' of 'Billy'
And 'Billy' order 2 meal 'All dressed pizza' on order '333'
And 'Billy' order 1 meal 'Small fries' on order '333'
And 'Mark' confirms that 'Billy' order confirmation number is '333' at '18:00:00'
And 'Esther' finishes to cook the order '333' at '18:10:00'
And 'Jake' delivers the order '333' at '18:30:00'
And 'Billy' pays '12.00$' to 'Jake'
Then Order '333' should be closed at '18:30:00'
And The order '333' should have an income of '25.00$'
And The order '333' should registers a tip of '3.00$'
And The order '333' should have taken '0:30:00' to complete

# Scenario: Cashier serves a front desk customer

# Scenario: Cashier serves a drive-in customer
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

namespace Example\Domain\Administration\Application;

use Example\Domain\Administration\DomainModel\CandidateRepository;
use Example\Domain\Administration\DomainModel\OwnerRepository;
use Example\Domain\Common\Application\EventPublisher;

Expand Down
Loading