Skip to content

Commit

Permalink
RENT SMS command implemented, success and error notifications added
Browse files Browse the repository at this point in the history
  • Loading branch information
miroc committed Aug 16, 2017
1 parent 773365a commit 4816886
Show file tree
Hide file tree
Showing 16 changed files with 521 additions and 83 deletions.
2 changes: 1 addition & 1 deletion app/Console/Commands/CheckLongRents.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace BikeShare\Console\Commands;

use BikeShare\Http\Services\RentService;
use BikeShare\Http\Services\Rents\RentService;
use Exception;
use Illuminate\Console\Command;

Expand Down
2 changes: 1 addition & 1 deletion app/Console/Commands/CheckManyRents.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace BikeShare\Console\Commands;

use BikeShare\Http\Services\RentService;
use BikeShare\Http\Services\Rents\RentService;
use Exception;
use Illuminate\Console\Command;

Expand Down
12 changes: 4 additions & 8 deletions app/Http/Controllers/Api/v1/Bikes/BikesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
use BikeShare\Domain\Rent\Requests\ReturnRequest;
use BikeShare\Domain\Stand\StandsRepository;
use BikeShare\Http\Controllers\Api\v1\Controller;
use BikeShare\Http\Services\RentService;
use BikeShare\Jobs\CreateRentJob;
use BikeShare\Http\Services\Rents\RentService;
use Carbon\Carbon;
use Illuminate\Http\Request;

Expand Down Expand Up @@ -119,14 +118,11 @@ public function rentBike(RentRequest $request, $uuid, RentService $rentService)
{
// TODO limits, credits
$bike = $this->bikeRepo->findByUuid($uuid);
//$oldCode = $bike->current_code;
//$standFrom = $bike->standFrom;

$rent = $rentService->rentBike($this->user, $bike)->createRentLog();
// TODO catch all exception types
$rent = $rentService->rentBike($this->user, $bike);

//event(new BikeWasRented($bike, $oldCode, $stand));

return $this->response->item($rent->rent, new RentTransformer());
return $this->response->item($rent, new RentTransformer());
}

public function returnBike(ReturnRequest $request, $uuid)
Expand Down
59 changes: 26 additions & 33 deletions app/Http/Controllers/Api/v1/Rents/RentsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
use BikeShare\Domain\Stand\StandsRepository;
use BikeShare\Domain\User\UsersRepository;
use BikeShare\Http\Controllers\Api\v1\Controller;
use BikeShare\Http\Services\RentService;
use BikeShare\Http\Services\Rents\Exceptions\RentException;
use BikeShare\Http\Services\Rents\Exceptions\RentExceptionType as ER;
use BikeShare\Http\Services\Rents\RentService;
use BikeShare\Notifications\NoteCreated;
use Illuminate\Http\Request;
use Notification;
Expand Down Expand Up @@ -66,42 +68,33 @@ public function history()
public function store(CreateRentRequest $request, RentService $rentService)
{
if (! $bike = app(BikesRepository::class)->findByUuid($request->get('bike'))) {
return $this->response->errorNotFound('Bike not found!');
$this->response->errorNotFound('Bike not found!');
}

if ($bike->status != BikeStatus::FREE) {
return $this->response->errorNotFound('Bike is not free!');
}

$currentRents = $this->user->bikes()->get()->count();
if ($currentRents >= $this->user->limit) {
return $this->response->errorBadRequest('You reached the maximum number of rents!');
}

// TODO check too many, i don't understand yet

if (app('AppConfig')->isStackBikeEnabled()) {
if (! $rentService->checkTopOfStack($bike)) {
return $this->response->errorBadRequest('Bike is not on the top!');
$rent = null;
try {
// TODO check too many, i don't understand yet
$rent = $rentService->rentBike($this->user, $bike);
} catch (RentException $e){
switch ($e->type){
case ER::BIKE_NOT_FREE:
$this->response->errorNotFound('Bike is not free!');
break;
case ER::MAXIMUM_NUMBER_OF_RENTS:
$this->response->errorBadRequest('You reached the maximum number of rents!');
break;
case ER::BIKE_NOT_ON_TOP:
$this->response->errorBadRequest('Bike is not on the top!');
break;
case ER::LOW_CREDIT:
$this->response->errorBadRequest('You do not have required credit for rent bike!');
break;
default:
// unknown type, rethrow
throw $e;
}
}

if (app('AppConfig')->isCreditEnabled()) {
$requiredCredit = app('AppConfig')->getRequiredCredit();
if ($this->user->credit < $requiredCredit) {
return $this->response->errorBadRequest('You do not have required credit for rent bike!');
}
}

$rentServiceObj = $rentService->rentBike($this->user, $bike)->createRentLog();

dd($rentServiceObj);
//$rent = app(RentService::class)->rentBike($this->user, $bike);

//event(new RentWasCreated($rent));
//event(new BikeWasRented($bike, $rent->new_code, $this->user));

return $this->response->item($rentServiceObj->rent, new RentTransformer());
return $this->response->item($rent, new RentTransformer());
}

/**
Expand Down
87 changes: 80 additions & 7 deletions app/Http/Controllers/Api/v1/Sms/SmsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,28 @@

namespace BikeShare\Http\Controllers\Api\v1\Sms;

use BikeShare\Domain\Bike\BikesRepository;
use BikeShare\Domain\Sms\Sms;
use BikeShare\Domain\Stand\StandsRepository;
use BikeShare\Http\Controllers\Api\v1\Controller;
use BikeShare\Http\Services\AppConfig;
use BikeShare\Http\Services\Rents\Exceptions\RentException;
use BikeShare\Http\Services\Rents\Exceptions\RentExceptionType as ER;
use BikeShare\Http\Services\Rents\RentService;
use BikeShare\Http\Services\Sms\Receivers\SmsRequestContract;
use BikeShare\Notifications\Sms\BikeAlreadyRented;
use BikeShare\Notifications\Sms\BikeDoesNotExist;
use BikeShare\Notifications\Sms\BikeNotTopOfStack;
use BikeShare\Notifications\Sms\BikeRented;
use BikeShare\Notifications\Sms\Credit;
use BikeShare\Notifications\Sms\Free;
use BikeShare\Notifications\Sms\Help;
use BikeShare\Notifications\Sms\InvalidArgumentsCommand;
use BikeShare\Notifications\Sms\RechargeCredit;
use BikeShare\Notifications\Sms\RentLimitExceeded;
use BikeShare\Notifications\Sms\UnknownCommand;
use Dingo\Api\Routing\Helpers;
use Exception;
use Illuminate\Http\Request;
use Validator;

Expand All @@ -28,18 +40,25 @@ class SmsController extends Controller
* @var AppConfig
*/
private $appConfig;

/**
* @var StandsRepository
*/
private $standsRepo;
/**
* @var BikesRepository
*/
private $bikeRepo;

public function __construct(SmsRequestContract $smsRequest,
AppConfig $appConfig,
StandsRepository $standsRepository)
StandsRepository $standsRepository,
BikesRepository $bikeRepository)
{
$this->smsRequest = $smsRequest;
$this->appConfig = $appConfig;
$this->standsRepo = $standsRepository;
$this->bikeRepo = $bikeRepository;
}

public function receive(Request $request)
Expand Down Expand Up @@ -81,17 +100,20 @@ protected function parseCommand(Sms $sms)
case "CREDIT":
if (!$this->appConfig->isCreditEnabled()){
$this->unknownCommand($sms, $args[0]);
break;
} else {
$this->creditCommand($sms);
}
$this->creditCommand($sms);
break;
case "FREE":
$this->freeCommand($sms);
break;
// case "RENT":
// validateReceivedSMS($sms->Number(),count($args),2,_('with bike number:')." RENT 47");
// rent($sms->Number(),$args[1]);//intval
// break;
case "RENT":
if (count($args) < 2){
$this->invalidArgumentsCommand($sms, "with bike number: RENT 47");
} else {
$this->rentCommand($sms, $args[1]);
}
break;
// case "RETURN":
// validateReceivedSMS($sms->Number(),count($args),3,_('with bike number and stand name:')." RETURN 47 RACKO");
// returnBike($sms->Number(),$args[1],$args[2],trim(urldecode($sms->Text())));
Expand Down Expand Up @@ -182,4 +204,55 @@ private function freeCommand($sms)
$sms->sender->notify(new Free($this->standsRepo));
}

private function invalidArgumentsCommand($sms, $errorMsg)
{
$sms->sender->notify(new InvalidArgumentsCommand($errorMsg));
}

private function rentCommand($sms, $bikeNumber)
{
$user = $sms->sender;
$bikeNumber = intval($bikeNumber);
if (!$bike = $this->bikeRepo->findByBikeNum($bikeNumber)) {
$user->notify(new BikeDoesNotExist($bikeNumber));
return;
}

try {
$rent = app(RentService::class)
->rentBike($user, $bike);
$user->notify(new BikeRented($rent));
} catch (RentException $e){
switch ($e->type){
case ER::LOW_CREDIT:
$requiredCredit = $e->param1;
$user->notify(new RechargeCredit($this->appConfig,
$user->credit,
$requiredCredit));
break;

case ER::BIKE_NOT_FREE:
if (!$bike->user){
throw new Exception("Bike not free but no owner", [$bike->user]);
}
$user->notify(new BikeAlreadyRented($user, $bike));
break;

case ER::BIKE_NOT_ON_TOP:
$topBike = $e->param1;
$user->notify(new BikeNotTopOfStack($bike, $topBike));
break;

case ER::MAXIMUM_NUMBER_OF_RENTS:
$userLimit = $e->param1;
$currentRents = $e->param2;
$user->notify(new RentLimitExceeded($userLimit, $currentRents));
break;

default:
// unknown type, rethrow
throw $e;
}
}
}
}
34 changes: 34 additions & 0 deletions app/Http/Services/Rents/Exceptions/RentException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace BikeShare\Http\Services\Rents\Exceptions;

class RentException extends \LogicException
{
/**
* @var RentExceptionType
*/
public $type;

/**
* @var mixed
*/
public $param1;

/**
* @var mixed
*/
public $param2;

/**
* RentException constructor.
* @param RentExceptionType $type
* @param null|mixed $param1
* @param null|mixed $param2
*/
public function __construct(RentExceptionType $type, $param1 = null, $param2 = null)
{
$this->type = $type;
$this->param1 = $param1;
$this->param2 = $param2;
}
}
13 changes: 13 additions & 0 deletions app/Http/Services/Rents/Exceptions/RentExceptionType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace BikeShare\Http\Services\Rents\Exceptions;

use MyCLabs\Enum\Enum;

class RentExceptionType extends Enum
{
const BIKE_NOT_FREE = 1;
const MAXIMUM_NUMBER_OF_RENTS = 2;
const BIKE_NOT_ON_TOP = 3;
const LOW_CREDIT = 4;
}
Loading

0 comments on commit 4816886

Please sign in to comment.