Skip to content

Instantly share code, notes, and snippets.

@geomagilles
Last active July 21, 2018 16:24
Show Gist options
  • Save geomagilles/99a6c205144381ff4fc3ffd831137dd0 to your computer and use it in GitHub Desktop.
Save geomagilles/99a6c205144381ff4fc3ffd831137dd0 to your computer and use it in GitHub Desktop.
<?php
use Zenaton\Interfaces\WorkflowInterface;
use Zenaton\Tasks\Wait;
use Zenaton\Traits\Zenatonable;
class RequestManagementWorkflow implements WorkflowInterface
{
use Zenatonable;
const ENOUGH_PROVIDERS = 3;
protected $request;
protected $quotations;
public function __construct($request)
{
$this->request = $request;
$this->quotations = [];
}
public function getId()
{
return $this->request->id;
}
public function handle()
{
// wait for moderation
$event = (new Wait(ModerationEvent::class))->execute();
// if rejected, tell user
if ($event->rejected) {
(new SendRejectionNotification($this->request, $event->reason))->execute();
return;
}
// select a set of providers for this request
$providers = (new SelectProvidersForRequest($this->request))->execute();
// notify these providers
foreach ($providers as $provider) {
(new NotifyProviderOfNewRequest($provider, $this->request))->dispatch();
}
// wait for at most 3 providers quotation, 3 days maximum
$event = (new Wait(ProvidersQuotationGatheredEvent::class))->days(3)->execute();
// if no response received in 3 days
if (0 == count($this->quotations)) {
(new NotifyUserOfNoResponse($this->request))->execute();
return;
}
// notify quotation to user
(new NotifyQuotationsToUser($this->request, $this->quotations))->execute();
// wait user choice
$event = (new Wait(QuotationChosenByUserEvent::class))->execute();
// notify user choice to providers
foreach ($this->quotations as $providerId => $quotation) {
if ($providerId == $event->provider->id) {
(new NotifiyChosenProvider($providerId, $this->request))->dispatch();
} else {
(new NotifiyNotChosenProvider($providerId, $this->request))->dispatch();
}
}
}
public function onEvent($event)
{
if ($event instanceof ProviderQuotationEvent) {
// tell provider it's too late, if we already have enough quotations
if (count($this->quotations) >= self::ENOUGH_PROVIDERS) {
(new NotifyProviderItsTooLate($event->provider, $event->quotation))->execute();
return;
}
// update or add provider quotation in quotations array
$this->quotation[$event->provider->id] = $event->quotation;
// if enough quotation, continue the main flow
if (count($this->quotations) >= self::ENOUGH_PROVIDERS) {
// send an event to itself
self::whereId($this->getId())->send(new ProvidersQuotationGatheredEvent());
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment