Skip to content
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

Basket #47

Open
wants to merge 10 commits into
base: master
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ vendor/*
*/cache/*
web/uploads/*
web/bundles/*
web/files/*

# Configuration files
app/config/parameters.ini
Expand Down
1 change: 1 addition & 0 deletions app/AppKernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public function registerBundles()
new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
new Gregwar\ImageBundle\GregwarImageBundle(),
new Knp\Bundle\SnappyBundle\KnpSnappyBundle(),
new Payutc\OnyxBundle\PayutcOnyxBundle(),
new Payutc\AdminBundle\PayutcAdminBundle(),
);
Expand Down
13 changes: 12 additions & 1 deletion app/config/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,15 @@ swiftmailer:
# Gregwar Image Configuration
gregwar_image:
cache_dir: %kernel.root_dir%/cache/gregwar
throw_exception: false
throw_exception: false

# Snappy PDF generation config
knp_snappy:
pdf:
enabled: true
binary: /usr/local/bin/wkhtmltopdf
options: []
image:
enabled: true
binary: /usr/local/bin/wkhtmltoimage
options: []
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
"nategood/httpful": "*",
"ginger/client": "dev-master",
"payutc/php-client": "dev-master",
"gregwar/image-bundle": "dev-master"
"gregwar/image-bundle": "dev-master",
"knplabs/knp-snappy-bundle": "dev-master"
},
"scripts": {
"post-install-cmd": [
Expand Down
285 changes: 285 additions & 0 deletions src/Payutc/OnyxBundle/Basket/Basket.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,285 @@
<?php

namespace Payutc\OnyxBundle\Basket;

use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\HttpFoundation\Session\Session;
use Doctrine\ORM\EntityManager;
use Doctrine\Common\Collections\ArrayCollection;

use Payutc\OnyxBundle\Entity\Ticket;
use Payutc\OnyxBundle\Basket\Exception\BasketException;
use Payutc\OnyxBundle\Basket\Exception\FullEventException;
use Payutc\OnyxBundle\Basket\Exception\FullEventForUserException;
use Payutc\OnyxBundle\Basket\Exception\FullPriceException;
use Payutc\OnyxBundle\Basket\Exception\FullPriceForUserException;
use Payutc\OnyxBundle\Basket\Exception\ExpiredPriceException;

class Basket
{
private $user;
private $em;
protected $session;
protected $collection;

/**
* Magic constructor
*
* @param Session $session
* @return Basket
*/
public function __construct(Session $session, SecurityContext $context, EntityManager $em)
{
$this->collection = new ArrayCollection();

// Minimal ROLE to buy some places
if (!$context->isGranted('ROLE_USER')) {
return $this;
}

$this->session = $session;
$this->em = $em;
$this->user = $context->getToken()->getUser();

if ($this->session->get('onyxBasketCollection') instanceof ArrayCollection) {
$this->collection = $this->session->get('onyxBasketCollection');
}

return $this;
}

/**
* Add a ticket in the basket if it is available
*
* @param Ticket $ticket
* @return boolean
*/
public function add(Ticket $ticket)
{
$ticketIsAdded = false;

if (!$this->collection->contains($ticket)) {
try {
if ($this->isTicketAvailable($ticket)) {
$this->collection->add($ticket);
$this->store();
$ticketIsAdded = true;
}
}
catch (BasketException $e) {
// echo '<pre>';
// exit(var_dump(get_class($e)));
$this->getSession()->getFlashBag()->add('warning', $e->getMessage());
}
}

return $ticketIsAdded;
}

/**
* Remove a ticket from the basket if it is contained.
*
* @param Ticket $ticket
* @return Basket
*/
public function remove(Ticket $ticket)
{
$this->collection->removeElement($ticket);
$this->store();

return $this;
}

/**
* Refresh the basket item in the session.
*
* @return Basket
*/
public function refresh(Ticket $ticket)
{
$this->collection->forAll(function ($key, $item) use ($ticket) {
if ($item->getId() === $ticket->getId()) {
$this->collection->set($key, $ticket);
}
});

return $this->store();
}

/**
* Store the basket content in session
*
* @return Basket
*/
protected function store()
{
$this->session->set('onyxBasketCollection', $this->collection);

return $this;
}

/**
* Count the basket items
*
* @return Basket
*/
public function count()
{
return $this->getCollection()->count();
}

/**
* Validate and pay all items from the basket
*
* @param Ticket $ticket
* @return Basket
*/
public function validate()
{
$this->collection->forAll(function ($key, $ticket) {
$availability = false;

try {
$availability = $this->isTicketAvailable($ticket);
}
catch (BasketException $e) {
$this->getSession()->getFlashBag()->add('warning', $e->getMessage());
$this->remove($ticket);
}

if ($availability) {
// TODO: Paiement ???

$this->getEntityManager()->persist($ticket);
}
});

$this->getEntityManager()->flush();

return $this;
}

/**
* Unvalidate the basket and remove all items
*
* @return Basket
*/
public function unvalidate()
{
$this->collection->clear();

return $this;
}

/**
* Check the ticket availability
*
* @param Ticket $ticket
* @return boolean
*/
protected function isTicketAvailable(Ticket $ticket)
{
$availability = true;

// Check the event global capacity
$eventCapacity = $ticket->getPrice()->getEvent()->getCapacity();
$eventPaidPlaces = $this->getEntityManager()->getRepository('PayutcOnyxBundle:Ticket')->countAllPaidForEvent($ticket->getPrice()->getEvent());

if ($eventCapacity <= $eventPaidPlaces) {
$availability = false;
throw new FullEventException();
}

// Check the places allowed for the user
$allowedPlacesForUser = $ticket->getPrice()->getEvent()->getMaxPlacesForUser();
$eventPaidPlacesByUser = $this->getEntityManager()->getRepository('PayutcOnyxBundle:Ticket')->countAllPaidForEventAndBuyer($ticket->getPrice()->getEvent(), $this->getUser());

if ($allowedPlacesForUser <= $eventPaidPlacesByUser) {
$availability = false;
throw new FullEventForUserException();
}

// Check the price capacity
$priceCapacity = $ticket->getPrice()->getCapacity();
$pricePaidPlaces = $this->getEntityManager()->getRepository('PayutcOnyxBundle:Ticket')->countAllPaidForEventAndPrice($ticket->getPrice()->getEvent(), $ticket->getPrice());

if ($priceCapacity <= $pricePaidPlaces) {
$availability = false;
throw new FullPriceException();
}

// Check the places allowed by price for the user
$allowedPlacesOfPriceForUser = $ticket->getPrice()->getMaxPlacesForUser();
$pricePaidPlaces = $this->getEntityManager()->getRepository('PayutcOnyxBundle:Ticket')->countAllPaidForEventAndPriceAndBuyer($ticket->getPrice()->getEvent(), $ticket->getPrice(), $this->getUser());

if ($priceCapacity <= $pricePaidPlaces) {
$availability = false;
throw new FullPriceForUserException();
}

// Check the price time expiration
$priceEnd = $ticket->getPrice()->getEndAt();
$now = new \DateTime();

if ($now >= $priceEnd) {
$availability = false;
throw new ExpiredPriceException();
}

return $availability;
}

/**
* Get user
*
* @return User
*/
public function getUser()
{
return $this->user;
}

/**
* Get session
*
* @return User
*/
public function getSession()
{
return $this->session;
}

/**
* Get entity manager
*
* @return Entity Manager
*/
public function getEntityManager()
{
return $this->em;
}

/**
* Get collection
*
* @return Collcetion
*/
public function getCollection()
{
return $this->collection;
}

/**
* Get collection
*
* @return Collcetion
*/
public function getAllItems()
{
$items = array();
$this->collection->forAll(function ($key, $item) {
$items[] = $this->getEntityManager()->getRepository(get_class($item))->find($item->getId());
});
return $items;
}
}
14 changes: 14 additions & 0 deletions src/Payutc/OnyxBundle/Basket/Exception/BasketException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Payutc\OnyxBundle\Basket\Exception;

use Exception;
use Symfony\Component\HttpKernel\Exception\HttpException;

class BasketException extends HttpException
{
public function __construct($message = '', $code = 400, Exception $previous = null)
{
parent::__construct($code, printf('. %s', $message), $previous);
}
}
13 changes: 13 additions & 0 deletions src/Payutc/OnyxBundle/Basket/Exception/ExpiredPriceException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Payutc\OnyxBundle\Basket\Exception;

use Exception;

class ExpiredPriceException extends BasketException
{
public function __construct($message = '', $code = 400, Exception $previous = null)
{
parent::__construct(printf('Ce tarif a expiré, veuillez en choisir un autre. %s', $message), $code, $previous);
}
}
13 changes: 13 additions & 0 deletions src/Payutc/OnyxBundle/Basket/Exception/FullEventException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Payutc\OnyxBundle\Basket\Exception;

use Exception;

class FullEventException extends BasketException
{
public function __construct($message = '', $code = 400, Exception $previous = null)
{
parent::__construct(printf('Cet évènement est malheureusement complet. %s', $message), $code, $previous);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Payutc\OnyxBundle\Basket\Exception;

use Exception;

class FullEventForUserException extends BasketException
{
public function __construct($message = '', $code = 400, Exception $previous = null)
{
parent::__construct(printf('Vous avez malheureusement atteint le nombre de places disponibles pour cet évènement. %s', $message), $code, $previous);
}
}
Loading