Refactor OrderController

This commit is contained in:
Benoît Burnichon
2015-05-25 10:49:39 +02:00
parent 94133aabe4
commit 82da488ba2
4 changed files with 129 additions and 91 deletions

View File

@@ -12,7 +12,6 @@
namespace Alchemy\Phrasea; namespace Alchemy\Phrasea;
use Alchemy\Geonames\GeonamesServiceProvider; use Alchemy\Geonames\GeonamesServiceProvider;
use Alchemy\Phrasea\ControllerProvider\Prod\Order;
use Alchemy\Phrasea\ControllerProvider\Prod\Printer; use Alchemy\Phrasea\ControllerProvider\Prod\Printer;
use Alchemy\Phrasea\ControllerProvider\Prod\Property; use Alchemy\Phrasea\ControllerProvider\Prod\Property;
use Alchemy\Phrasea\ControllerProvider\Prod\Push; use Alchemy\Phrasea\ControllerProvider\Prod\Push;
@@ -315,6 +314,7 @@ class Application extends SilexApplication
'Alchemy\Phrasea\ControllerProvider\Prod\Language' => [], 'Alchemy\Phrasea\ControllerProvider\Prod\Language' => [],
'Alchemy\Phrasea\ControllerProvider\Prod\Lazaret' => [], 'Alchemy\Phrasea\ControllerProvider\Prod\Lazaret' => [],
'Alchemy\Phrasea\ControllerProvider\Prod\MoveCollection' => [], 'Alchemy\Phrasea\ControllerProvider\Prod\MoveCollection' => [],
'Alchemy\Phrasea\ControllerProvider\Prod\Order' => [],
'Alchemy\Phrasea\ControllerProvider\Datafiles' => [], 'Alchemy\Phrasea\ControllerProvider\Datafiles' => [],
'Alchemy\Phrasea\ControllerProvider\Lightbox' => [], 'Alchemy\Phrasea\ControllerProvider\Lightbox' => [],
'Alchemy\Phrasea\ControllerProvider\MediaAccessor' => [], 'Alchemy\Phrasea\ControllerProvider\MediaAccessor' => [],
@@ -626,7 +626,6 @@ class Application extends SilexApplication
$this->mount('/developers/', new Developers()); $this->mount('/developers/', new Developers());
$this->mount('/prod/query/', new Query()); $this->mount('/prod/query/', new Query());
$this->mount('/prod/order/', new Order());
$this->mount('/prod/story', new Story()); $this->mount('/prod/story', new Story());
$this->mount('/prod/WorkZone', new WorkZone()); $this->mount('/prod/WorkZone', new WorkZone());
$this->mount('/prod/lists', new UsrLists()); $this->mount('/prod/lists', new UsrLists());
@@ -680,6 +679,7 @@ class Application extends SilexApplication
'/prod/feeds' => 'Alchemy\Phrasea\ControllerProvider\Prod\Feed', '/prod/feeds' => 'Alchemy\Phrasea\ControllerProvider\Prod\Feed',
'/prod/language' => 'Alchemy\Phrasea\ControllerProvider\Prod\Language', '/prod/language' => 'Alchemy\Phrasea\ControllerProvider\Prod\Language',
'/prod/lazaret/' => 'Alchemy\Phrasea\ControllerProvider\Prod\Lazaret', '/prod/lazaret/' => 'Alchemy\Phrasea\ControllerProvider\Prod\Lazaret',
'/prod/order/' => 'Alchemy\Phrasea\ControllerProvider\Prod\Order',
'/prod/records/edit' => 'Alchemy\Phrasea\ControllerProvider\Prod\Edit', '/prod/records/edit' => 'Alchemy\Phrasea\ControllerProvider\Prod\Edit',
'/prod/records/movecollection' => 'Alchemy\Phrasea\ControllerProvider\Prod\MoveCollection', '/prod/records/movecollection' => 'Alchemy\Phrasea\ControllerProvider\Prod\MoveCollection',
'/setup' => 'Alchemy\Phrasea\ControllerProvider\Setup', '/setup' => 'Alchemy\Phrasea\ControllerProvider\Setup',

View File

@@ -9,6 +9,9 @@
*/ */
namespace Alchemy\Phrasea\Controller\Prod; namespace Alchemy\Phrasea\Controller\Prod;
use Alchemy\Phrasea\Application\Helper\DispatcherAware;
use Alchemy\Phrasea\Application\Helper\EntityManagerAware;
use Alchemy\Phrasea\Application\Helper\UserQueryAware;
use Alchemy\Phrasea\Controller\Controller; use Alchemy\Phrasea\Controller\Controller;
use Alchemy\Phrasea\Controller\RecordsRequest; use Alchemy\Phrasea\Controller\RecordsRequest;
use Alchemy\Phrasea\Core\Event\OrderDeliveryEvent; use Alchemy\Phrasea\Core\Event\OrderDeliveryEvent;
@@ -17,7 +20,9 @@ use Alchemy\Phrasea\Core\PhraseaEvents;
use Alchemy\Phrasea\Model\Entities\Basket; use Alchemy\Phrasea\Model\Entities\Basket;
use Alchemy\Phrasea\Model\Entities\BasketElement; use Alchemy\Phrasea\Model\Entities\BasketElement;
use Alchemy\Phrasea\Model\Entities\Order as OrderEntity; use Alchemy\Phrasea\Model\Entities\Order as OrderEntity;
use Alchemy\Phrasea\Model\Entities\Order;
use Alchemy\Phrasea\Model\Entities\OrderElement; use Alchemy\Phrasea\Model\Entities\OrderElement;
use Alchemy\Phrasea\Model\Repositories\OrderRepository;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Silex\Application; use Silex\Application;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
@@ -28,26 +33,29 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class OrderController extends Controller class OrderController extends Controller
{ {
use DispatcherAware;
use EntityManagerAware;
use UserQueryAware;
/** /**
* Create a new order * Create a new order
* *
* @param Application $app
* @param Request $request * @param Request $request
* *
* @return RedirectResponse|JsonResponse * @return RedirectResponse|JsonResponse
*/ */
public function createOrder(Application $app, Request $request) public function createOrder(Request $request)
{ {
$success = false; $success = false;
$collectionHasOrderAdmins = new ArrayCollection(); $collectionHasOrderAdmins = new ArrayCollection();
$toRemove = []; $toRemove = [];
$records = RecordsRequest::fromRequest($app, $request, true, ['cancmd']); $records = RecordsRequest::fromRequest($this->app, $request, true, ['cancmd']);
$hasOneAdmin = []; $hasOneAdmin = [];
if (!$records->isEmpty()) { if (!$records->isEmpty()) {
$order = new OrderEntity(); $order = new OrderEntity();
$order->setUser($app['authentication']->getUser()); $order->setUser($this->getAuthenticatedUser());
$order->setDeadline((null !== $deadLine = $request->request->get('deadline')) ? new \DateTime($deadLine) : $deadLine); $order->setDeadline((null !== $deadLine = $request->request->get('deadline')) ? new \DateTime($deadLine) : $deadLine);
$order->setOrderUsage($request->request->get('use', '')); $order->setOrderUsage($request->request->get('use', ''));
foreach ($records as $key => $record) { foreach ($records as $key => $record) {
@@ -58,7 +66,7 @@ class OrderController extends Controller
} }
if (!isset($hasOneAdmin[$record->get_base_id()])) { if (!isset($hasOneAdmin[$record->get_base_id()])) {
$query = $app['phraseanet.user-query']; $query = $this->createUserQuery();
$hasOneAdmin[$record->get_base_id()] = (Boolean) count($query->on_base_ids([$record->get_base_id()]) $hasOneAdmin[$record->get_base_id()] = (Boolean) count($query->on_base_ids([$record->get_base_id()])
->who_have_right(['order_master']) ->who_have_right(['order_master'])
->execute()->get_results()); ->execute()->get_results());
@@ -74,7 +82,7 @@ class OrderController extends Controller
$orderElement->setOrder($order); $orderElement->setOrder($order);
$orderElement->setBaseId($record->get_base_id()); $orderElement->setBaseId($record->get_base_id());
$orderElement->setRecordId($record->get_record_id()); $orderElement->setRecordId($record->get_record_id());
$app['orm.em']->persist($orderElement); $this->getEntityManager()->persist($orderElement);
} }
} }
@@ -89,188 +97,191 @@ class OrderController extends Controller
}); });
if ($noAdmins) { if ($noAdmins) {
$msg = $app->trans('There is no one to validate orders, please contact an administrator'); $msg = $this->app->trans('There is no one to validate orders, please contact an administrator');
} else { } else {
$order->setTodo($order->getElements()->count()); $order->setTodo($order->getElements()->count());
try { try {
$app['dispatcher']->dispatch(PhraseaEvents::ORDER_CREATE, new OrderEvent($order)); $this->dispatch(PhraseaEvents::ORDER_CREATE, new OrderEvent($order));
$app['orm.em']->persist($order); $this->getEntityManager()->persist($order);
$app['orm.em']->flush(); $this->getEntityManager()->flush();
$msg = $app->trans('The records have been properly ordered'); $msg = $this->app->trans('The records have been properly ordered');
$success = true; $success = true;
} catch (\Exception $e) { } catch (\Exception $e) {
$msg = $app->trans('An error occured'); $msg = $this->app->trans('An error occured');
} }
} }
} else { } else {
$msg = $app->trans('There is no record eligible for an order'); $msg = $this->app->trans('There is no record eligible for an order');
} }
if ('json' === $app['request']->getRequestFormat()) { if ('json' === $request->getRequestFormat()) {
return $app->json([ return $this->app->json([
'success' => $success, 'success' => $success,
'msg' => $msg, 'msg' => $msg,
]); ]);
} }
return $app->redirectPath('prod_orders', [ return $this->app->redirectPath('prod_orders', [
'success' => (int) $success, 'success' => (int) $success,
'action' => 'send' 'action' => 'send',
]); ]);
} }
/** /**
* Display list of orders * Display list of orders
* *
* @param Application $app
* @param Request $request * @param Request $request
* *
* @return Response * @return Response
*/ */
public function displayOrders(Application $app, Request $request) public function displayOrders(Request $request)
{ {
$page = (int) $request->query->get('page', 1); $page = (int) $request->query->get('page', 1);
$offsetStart = $page - 1; $offsetStart = $page - 1;
$perPage = (int) $request->query->get('per-page', 10); $perPage = (int) $request->query->get('per-page', 10);
$sort = $request->query->get('sort'); $sort = $request->query->get('sort');
$baseIds = array_keys($app['acl']->get($app['authentication']->getUser())->get_granted_base(['order_master'])); $baseIds = array_keys($this->getAclForUser()->get_granted_base(['order_master']));
$ordersList = $app['repo.orders']->listOrders($baseIds, $offsetStart, $perPage, $sort); $ordersList = $this->getOrderRepository()->listOrders($baseIds, $offsetStart, $perPage, $sort);
$total = $app['repo.orders']->countTotalOrders($baseIds); $total = $this->getOrderRepository()->countTotalOrders($baseIds);
return $app['twig']->render('prod/orders/order_box.html.twig', [ return $this->render('prod/orders/order_box.html.twig', [
'page' => $page, 'page' => $page,
'perPage' => $perPage, 'perPage' => $perPage,
'total' => $total, 'total' => $total,
'previousPage' => $page < 2 ? false : ($page - 1), 'previousPage' => $page < 2 ? false : ($page - 1),
'nextPage' => $page >= ceil($total / $perPage) ? false : $page + 1, 'nextPage' => $page >= ceil($total / $perPage) ? false : $page + 1,
'orders' => new ArrayCollection($ordersList) 'orders' => new ArrayCollection($ordersList),
]); ]);
} }
/** /**
* Display a single order identified by its id * Display a single order identified by its id
* *
* @param Application $app
* @param Request $request
* @param integer $order_id * @param integer $order_id
* @return Response * @return Response
*/ */
public function displayOneOrder(Application $app, Request $request, $order_id) public function displayOneOrder($order_id)
{ {
$order = $app['repo.orders']->find($order_id); $order = $this->getOrderRepository()->find($order_id);
if (null === $order) { if (null === $order) {
throw new NotFoundHttpException('Order not found'); throw new NotFoundHttpException('Order not found');
} }
return $app['twig']->render('prod/orders/order_item.html.twig', [ return $this->render('prod/orders/order_item.html.twig', [
'order' => $order 'order' => $order,
]); ]);
} }
/** /**
* Send an order * Send an order
* *
* @param Application $app * @param Request $request
* @param Request $request * @param integer $order_id
* @param integer $order_id
* @return RedirectResponse|JsonResponse * @return RedirectResponse|JsonResponse
*/ */
public function sendOrder(Application $app, Request $request, $order_id) public function sendOrder(Request $request, $order_id)
{ {
$success = false; $success = false;
if (null === $order = $app['repo.orders']->find($order_id)) { /** @var Order $order */
if (null === $order = $this->getOrderRepository()->find($order_id)) {
throw new NotFoundHttpException('Order not found'); throw new NotFoundHttpException('Order not found');
} }
$basket = $order->getBasket();
$manager = $this->getEntityManager();
$basket = $order->getBasket();
if (null === $basket) { if (null === $basket) {
$basket = new Basket(); $basket = new Basket();
$basket->setName($app->trans('Commande du %date%', ['%date%' => $order->getCreatedOn()->format('Y-m-d')])); $basket->setName($this->app->trans('Commande du %date%', [
'%date%' => $order->getCreatedOn()->format('Y-m-d'),
]));
$basket->setUser($order->getUser()); $basket->setUser($order->getUser());
$basket->setPusher($app['authentication']->getUser()); $basket->setPusher($this->getAuthenticatedUser());
$app['orm.em']->persist($basket); $manager->persist($basket);
$app['orm.em']->flush(); $manager->flush();
} }
$n = 0; $n = 0;
$elements = $request->request->get('elements', []); $elements = $request->request->get('elements', []);
foreach ($order->getElements() as $orderElement) { foreach ($order->getElements() as $orderElement) {
if (in_array($orderElement->getId(), $elements)) { if (in_array($orderElement->getId(), $elements)) {
$sbas_id = \phrasea::sbasFromBas($app, $orderElement->getBaseId()); $sbas_id = \phrasea::sbasFromBas($this->app, $orderElement->getBaseId());
$record = new \record_adapter($app, $sbas_id, $orderElement->getRecordId()); $record = new \record_adapter($this->app, $sbas_id, $orderElement->getRecordId());
$basketElement = new BasketElement(); $basketElement = new BasketElement();
$basketElement->setRecord($record); $basketElement->setRecord($record);
$basketElement->setBasket($basket); $basketElement->setBasket($basket);
$orderElement->setOrderMaster($app['authentication']->getUser()); $orderElement->setOrderMaster($this->getAuthenticatedUser());
$orderElement->setDeny(false); $orderElement->setDeny(false);
$orderElement->getOrder()->setBasket($basket); $orderElement->getOrder()->setBasket($basket);
$basket->addElement($basketElement); $basket->addElement($basketElement);
$n++; $n++;
$app['acl']->get($basket->getUser())->grant_hd_on($record, $app['authentication']->getUser(), 'order'); $this->getAclForUser($basket->getUser())->grant_hd_on($record, $this->getAuthenticatedUser(), 'order');
} }
} }
try { try {
if ($n > 0) { if ($n > 0) {
$order->setTodo($order->getTodo() - $n); $order->setTodo($order->getTodo() - $n);
$app['dispatcher']->dispatch(PhraseaEvents::ORDER_DELIVER, new OrderDeliveryEvent($order, $app['authentication']->getUser(), $n)); $this->dispatch(PhraseaEvents::ORDER_DELIVER, new OrderDeliveryEvent($order, $this->getAuthenticatedUser(), $n));
} }
$success = true; $success = true;
$app['orm.em']->persist($basket); // There was a basketElement persist here. Seems useless as all entities are managed.
$app['orm.em']->persist($orderElement); $manager->persist($basket);
$app['orm.em']->persist($order); $manager->persist($order);
$app['orm.em']->flush(); $manager->flush();
} catch (\Exception $e) { } catch (\Exception $e) {
} }
if ('json' === $app['request']->getRequestFormat()) { if ('json' === $request->getRequestFormat()) {
return $app->json([ return $this->app->json([
'success' => $success, 'success' => $success,
'msg' => $success ? $app->trans('Order has been sent') : $app->trans('An error occured while sending, please retry or contact an admin if problem persists'), 'msg' => $success
'order_id' => $order_id ? $this->app->trans('Order has been sent')
: $this->app->trans('An error occured while sending, please retry or contact an admin if problem persists'),
'order_id' => $order_id,
]); ]);
} }
return $app->redirectPath('prod_orders', [ return $this->app->redirectPath('prod_orders', [
'success' => (int) $success, 'success' => (int) $success,
'action' => 'send' 'action' => 'send',
]); ]);
} }
/** /**
* Deny an order * Deny an order
* *
* @param Application $app
* @param Request $request * @param Request $request
* @param integer $order_id * @param integer $order_id
* @return RedirectResponse|JsonResponse * @return RedirectResponse|JsonResponse
*/ */
public function denyOrder(Application $app, Request $request, $order_id) public function denyOrder(Request $request, $order_id)
{ {
$success = false; $success = false;
$order = $app['repo.orders']->find($order_id); /** @var Order $order */
$order = $this->getOrderRepository()->find($order_id);
if (null === $order) { if (null === $order) {
throw new NotFoundHttpException('Order not found'); throw new NotFoundHttpException('Order not found');
} }
$n = 0; $n = 0;
$elements = $request->request->get('elements', []); $elements = $request->request->get('elements', []);
$manager = $this->getEntityManager();
foreach ($order->getElements() as $orderElement) { foreach ($order->getElements() as $orderElement) {
if (in_array($orderElement->getId(),$elements)) { if (in_array($orderElement->getId(),$elements)) {
$orderElement->setOrderMaster($app['authentication']->getUser()); $orderElement->setOrderMaster($this->getAuthenticatedUser());
$orderElement->setDeny(true); $orderElement->setDeny(true);
$app['orm.em']->persist($orderElement); $manager->persist($orderElement);
$n++; $n++;
} }
} }
@@ -278,27 +289,37 @@ class OrderController extends Controller
try { try {
if ($n > 0) { if ($n > 0) {
$order->setTodo($order->getTodo() - $n); $order->setTodo($order->getTodo() - $n);
$app['dispatcher']->dispatch(PhraseaEvents::ORDER_DENY, new OrderDeliveryEvent($order, $app['authentication']->getUser(), $n)); $this->dispatch(PhraseaEvents::ORDER_DENY, new OrderDeliveryEvent($order, $this->getAuthenticatedUser(), $n));
} }
$success = true; $success = true;
$app['orm.em']->persist($order); $manager->persist($order);
$app['orm.em']->flush(); $manager->flush();
} catch (\Exception $e) { } catch (\Exception $e) {
} }
if ('json' === $app['request']->getRequestFormat()) { if ('json' === $request->getRequestFormat()) {
return $app->json([ return $this->app->json([
'success' => $success, 'success' => $success,
'msg' => $success ? $app->trans('Order has been denied') : $app->trans('An error occured while denying, please retry or contact an admin if problem persists'), 'msg' => $success
'order_id' => $order_id ? $this->app->trans('Order has been denied')
: $this->app->trans('An error occured while denying, please retry or contact an admin if problem persists'),
'order_id' => $order_id,
]); ]);
} }
return $app->redirectPath('prod_orders', [ return $this->app->redirectPath('prod_orders', [
'success' => (int) $success, 'success' => (int) $success,
'action' => 'send' 'action' => 'send',
]); ]);
} }
/**
* @return OrderRepository
*/
private function getOrderRepository()
{
return $this->app['repo.orders'];
}
} }

View File

@@ -11,55 +11,71 @@
namespace Alchemy\Phrasea\ControllerProvider\Prod; namespace Alchemy\Phrasea\ControllerProvider\Prod;
use Alchemy\Phrasea\Application as PhraseaApplication;
use Alchemy\Phrasea\Controller\Prod\OrderController;
use Alchemy\Phrasea\ControllerProvider\ControllerProviderTrait; use Alchemy\Phrasea\ControllerProvider\ControllerProviderTrait;
use Silex\Application; use Silex\Application;
use Silex\ControllerProviderInterface; use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\Request; use Silex\ServiceProviderInterface;
class Order implements ControllerProviderInterface class Order implements ControllerProviderInterface, ServiceProviderInterface
{ {
use ControllerProviderTrait; use ControllerProviderTrait;
public function register(Application $app)
{
$app['controller.prod.order'] = $app->share(function (PhraseaApplication $app) {
return (new OrderController($app))
->setDispatcher($app['dispatcher'])
->setEntityManagerLocator(function () use ($app) {
return $app['orm.em'];
})
->setUserQueryFactory(function () use ($app) {
return $app['phraseanet.user-query'];
})
;
});
}
public function boot(Application $app)
{
// no-op
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public function connect(Application $app) public function connect(Application $app)
{ {
$app['controller.prod.order'] = $this;
$controllers = $this->createAuthenticatedCollection($app); $controllers = $this->createAuthenticatedCollection($app);
$firewall = $this->getFirewall($app);
$ensureOrdersAdmin = function () use ($firewall) {
$firewall->requireOrdersAdmin();
};
$controllers->before(function (Request $request) use ($app) { $controllers->before(function () use ($firewall) {
$app['firewall']->requireRight('order'); $firewall->requireRight('order');
}); });
$controllers->get('/', 'controller.prod.order:displayOrders') $controllers->get('/', 'controller.prod.order:displayOrders')
->before(function (Request $request) use ($app) { ->before($ensureOrdersAdmin)
$app['firewall']->requireOrdersAdmin();
})
->bind('prod_orders'); ->bind('prod_orders');
$controllers->post('/', 'controller.prod.order:createOrder') $controllers->post('/', 'controller.prod.order:createOrder')
->bind('prod_order_new'); ->bind('prod_order_new');
$controllers->get('/{order_id}/', 'controller.prod.order:displayOneOrder') $controllers->get('/{order_id}/', 'controller.prod.order:displayOneOrder')
->before(function (Request $request) use ($app) { ->before($ensureOrdersAdmin)
$app['firewall']->requireOrdersAdmin();
})
->bind('prod_order') ->bind('prod_order')
->assert('order_id', '\d+'); ->assert('order_id', '\d+');
$controllers->post('/{order_id}/send/', 'controller.prod.order:sendOrder') $controllers->post('/{order_id}/send/', 'controller.prod.order:sendOrder')
->before(function (Request $request) use ($app) { ->before($ensureOrdersAdmin)
$app['firewall']->requireOrdersAdmin();
})
->bind('prod_order_send') ->bind('prod_order_send')
->assert('order_id', '\d+'); ->assert('order_id', '\d+');
$controllers->post('/{order_id}/deny/', 'controller.prod.order:denyOrder') $controllers->post('/{order_id}/deny/', 'controller.prod.order:denyOrder')
->before(function (Request $request) use ($app) { ->before($ensureOrdersAdmin)
$app['firewall']->requireOrdersAdmin();
})
->bind('prod_order_deny') ->bind('prod_order_deny')
->assert('order_id', '\d+'); ->assert('order_id', '\d+');

View File

@@ -11,6 +11,7 @@
namespace Alchemy\Phrasea\Model\Entities; namespace Alchemy\Phrasea\Model\Entities;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo; use Gedmo\Mapping\Annotation as Gedmo;
@@ -71,7 +72,7 @@ class Order
*/ */
public function __construct() public function __construct()
{ {
$this->elements = new \Doctrine\Common\Collections\ArrayCollection(); $this->elements = new ArrayCollection();
} }
/** /**
@@ -176,7 +177,7 @@ class Order
/** /**
* Get elements * Get elements
* *
* @return \Doctrine\Common\Collections\Collection * @return OrderElement[]|\Doctrine\Common\Collections\Collection
*/ */
public function getElements() public function getElements()
{ {