First implementation of orders using Doctrine

This commit is contained in:
Andrey
2013-07-02 14:21:46 +02:00
parent 03fe7a6610
commit 07ff0c4d7a
9 changed files with 335 additions and 633 deletions

View File

@@ -40,7 +40,7 @@ use Alchemy\Phrasea\Controller\Prod\Feed;
use Alchemy\Phrasea\Controller\Prod\Language; use Alchemy\Phrasea\Controller\Prod\Language;
use Alchemy\Phrasea\Controller\Prod\Lazaret; use Alchemy\Phrasea\Controller\Prod\Lazaret;
use Alchemy\Phrasea\Controller\Prod\MoveCollection; use Alchemy\Phrasea\Controller\Prod\MoveCollection;
use Alchemy\Phrasea\Controller\Prod\Order; use Alchemy\Phrasea\Controller\Prod\Orders;
use Alchemy\Phrasea\Controller\Prod\Printer; use Alchemy\Phrasea\Controller\Prod\Printer;
use Alchemy\Phrasea\Controller\Prod\Push; use Alchemy\Phrasea\Controller\Prod\Push;
use Alchemy\Phrasea\Controller\Prod\Query; use Alchemy\Phrasea\Controller\Prod\Query;
@@ -768,7 +768,7 @@ class Application extends SilexApplication
$this->mount('/client/baskets', new ClientBasket()); $this->mount('/client/baskets', new ClientBasket());
$this->mount('/prod/query/', new Query()); $this->mount('/prod/query/', new Query());
$this->mount('/prod/order/', new Order()); $this->mount('/prod/order/', new Orders());
$this->mount('/prod/baskets', new Basket()); $this->mount('/prod/baskets', new Basket());
$this->mount('/prod/download', new Download()); $this->mount('/prod/download', new Download());
$this->mount('/prod/story', new Story()); $this->mount('/prod/story', new Story());

View File

@@ -13,6 +13,10 @@ namespace Alchemy\Phrasea\Controller\Prod;
use Alchemy\Phrasea\Controller\RecordsRequest; use Alchemy\Phrasea\Controller\RecordsRequest;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Entities\Basket;
use Entities\BasketElement;
use Entities\Order;
use Entities\OrderElement;
use Silex\Application; use Silex\Application;
use Silex\ControllerProviderInterface; use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@@ -25,7 +29,7 @@ use Symfony\Component\HttpFoundation\Response;
* @license http://opensource.org/licenses/gpl-3.0 GPLv3 * @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com * @link www.phraseanet.com
*/ */
class Order implements ControllerProviderInterface class Orders implements ControllerProviderInterface
{ {
/** /**
@@ -156,42 +160,60 @@ class Order implements ControllerProviderInterface
$records = RecordsRequest::fromRequest($app, $request, true, array('cancmd')); $records = RecordsRequest::fromRequest($app, $request, true, array('cancmd'));
$query = new \User_Query($app); $query = new \User_Query($app);
foreach ($records as $key => $record) { if (count($records) > 0) {
if ($collectionHasOrderAdmins->containsKey($record->get_base_id())) { $order = new Order();
if (!$collectionHasOrderAdmins->get($record->get_base_id())) { $order->setUsrId($app['authentication']->getUser()->get_id());
$order->setDeadline((null !== $deadLine = $request->request->get('deadline')) ? new \DateTime($deadLine) : $deadLine);
$order->setOrderUsage($request->request->get('use', ''));
foreach ($records as $key => $record) {
if ($collectionHasOrderAdmins->containsKey($record->get_base_id())) {
if (!$collectionHasOrderAdmins->get($record->get_base_id())) {
$records->remove($key);
}
}
$hasOneAdmin = !!count($query->on_base_ids(array($record->get_base_id()))
->who_have_right(array('order_master'))
->execute()->get_results());
$collectionHasOrderAdmins->set($record->get_base_id(), $hasOneAdmin);
if (!$hasOneAdmin) {
$toRemove[] = $key;
} else {
$orderElement = new OrderElement();
$order->addElement($orderElement);
$orderElement->setOrder($order);
$orderElement->setBaseId($record->get_base_id());
$orderElement->setRecordId($record->get_record_id());
$app['EM']->persist($orderElement);
}
}
foreach ($toRemove as $key) {
if ($records->containsKey($key)) {
$records->remove($key); $records->remove($key);
} }
} }
$hasOneAdmin = !!count($query->on_base_ids(array($record->get_base_id())) $noAdmins = $collectionHasOrderAdmins->forAll(function($key, $hasAdmin) {
->who_have_right(array('order_master')) return false === $hasAdmin;
->execute()->get_results()); });
$collectionHasOrderAdmins->set($record->get_base_id(), $hasOneAdmin); if ($noAdmins) {
$msg = _('There is no one to validate orders, please contact an administrator');
if (!$hasOneAdmin) {
$toRemove[] = $key;
} }
}
foreach ($toRemove as $key) { $order->setTodo($order->getElements()->count());
if ($records->containsKey($key)) {
$records->remove($key);
}
}
$noAdmins = $collectionHasOrderAdmins->forAll(function($key, $hasAdmin) { $app['EM']->persist($order);
return false === $hasAdmin; $app['EM']->flush();
});
if ($noAdmins) { $app['events-manager']->trigger('__NEW_ORDER__', array(
$msg = _('There is no one to validate orders, please contact an administrator'); 'order_id' => $order->getId(),
} 'usr_id' => $order->getUsrId()
));
if (count($records) > 0) { $success = true;
$success = (Boolean) \set_order::create(
$app, $records, $app['authentication']->getUser(), $request->request->get('use', ''), ( (null !== $deadLine = $request->request->get('deadline')) ? new \DateTime($deadLine) : $deadLine)
);
if ($success) { if ($success) {
$msg = _('The records have been properly ordered'); $msg = _('The records have been properly ordered');
@@ -202,7 +224,7 @@ class Order implements ControllerProviderInterface
$msg = _('There is no record eligible for an order'); $msg = _('There is no record eligible for an order');
} }
} catch (\Exception $e) { } catch (\Exception $e) {
$msg = _('An error occured'); $msg = _('An error occured') . $e->getMessage();
} }
if ('json' === $app['request']->getRequestFormat()) { if ('json' === $app['request']->getRequestFormat()) {
@@ -235,8 +257,8 @@ class Order implements ControllerProviderInterface
$baseIds = array_keys($app['authentication']->getUser()->ACL()->get_granted_base(array('order_master'))); $baseIds = array_keys($app['authentication']->getUser()->ACL()->get_granted_base(array('order_master')));
$ordersList = \set_order::listOrders($app, $baseIds, $offsetStart, $perPage, $sort); $ordersList = $app['EM']->getRepository('Entities\Order')->listOrders($baseIds, $offsetStart, $perPage, $sort);
$total = \set_order::countTotalOrder($app['phraseanet.appbox'], $baseIds); $total = $app['EM']->getRepository('Entities\Order')->countTotalOrders($baseIds);
return $app['twig']->render('prod/orders/order_box.html.twig', array( return $app['twig']->render('prod/orders/order_box.html.twig', array(
'page' => $page, 'page' => $page,
@@ -258,7 +280,11 @@ class Order implements ControllerProviderInterface
*/ */
public function displayOneOrder(Application $app, Request $request, $order_id) public function displayOneOrder(Application $app, Request $request, $order_id)
{ {
$order = new \set_order($app, $order_id); try {
$order = $app['EM']->getRepository('Entities\Order')->find($order_id);
} catch (\Exception_NotFound $e) {
$app->abort(404);
}
return $app['twig']->render('prod/orders/order_item.html.twig', array( return $app['twig']->render('prod/orders/order_item.html.twig', array(
'order' => $order 'order' => $order
@@ -276,12 +302,85 @@ class Order implements ControllerProviderInterface
public function sendOrder(Application $app, Request $request, $order_id) public function sendOrder(Application $app, Request $request, $order_id)
{ {
$success = false; $success = false;
try {
$order = new \set_order($app, $order_id); $order = $app['EM']->getRepository('Entities\Order')->find($order_id);
} catch (\Exception_NotFound $e) {
$app->abort(404);
}
try { try {
$order->send_elements($app, $request->request->get('elements', array()), !!$request->request->get('force', false)); $dest_user = \User_Adapter::getInstance($order->getUsrId(), $app);
$basket = null;
if ($order->getSselId()) {
$repository = $app['EM']->getRepository('\Entities\Basket');
try {
$basket = $repository->findUserBasket($app, $order->getSselId(), $dest_user, false);
} catch (\Exception $e) {
$basket = null;
}
}
if (null === $basket) {
$basket = new Basket();
$basket->setName(sprintf(_('Commande du %s'), $order->getCreatedOn()->format('Y-m-d')));
$basket->setOwner($dest_user);
$basket->setPusher($app['authentication']->getUser());
$app['EM']->persist($basket);
$app['EM']->flush(); // this is necessary in order to use $basket->getId()
$order->setSselId($basket->getId());
$app['EM']->persist($order);
$app['EM']->flush();
}
$n = 0;
foreach ($order->getElements() as $orderElement) {
if (in_array($orderElement->getId(), $request->request->get('elements', array()))) {
$sbas_id = \phrasea::sbasFromBas($app, $orderElement->getBaseId());
$record = new \record_adapter($app, $sbas_id, $orderElement->getRecordId());
$basketElement = new BasketElement();
$basketElement->setRecord($record);
$basketElement->setBasket($basket);
$orderElement->setOrderMasterId($app['authentication']->getUser()->get_id());
$orderElement->setDeny(false);
$orderElement->setBasket($basket);
$basket->addElement($basketElement);
$app['EM']->persist($basket);
$app['EM']->persist($orderElement);
$app['EM']->flush();
$n++;
$dest_user->ACL()->grant_hd_on($record, $app['authentication']->getUser(), 'order');
}
}
$success = true; $success = true;
if ($n > 0) {
$order->setTodo($order->getTodo() - $n);
$app['EM']->persist($order);
$app['EM']->flush();
$params = array(
'ssel_id' => $order->getSselId(),
'from' => $app['authentication']->getUser()->get_id(),
'to' => $dest_user->get_id(),
'n' => $n
);
$app['events-manager']->trigger('__ORDER_DELIVER__', $params);
}
} catch (\Exception $e) { } catch (\Exception $e) {
} }
@@ -312,10 +411,42 @@ class Order implements ControllerProviderInterface
{ {
$success = false; $success = false;
$order = new \set_order($app, $order_id); try {
$order = $app['EM']->getRepository('Entities\Order')->find($order_id);
} catch (\Exception_NotFound $e) {
$app->abort(404);
}
try { try {
$order->deny_elements($request->request->get('elements', array())); $n = 0;
foreach ($order->getElements() as $orderElement) {
if (in_array($orderElement->getId(), $request->request->get('elements', array()))) {
$orderElement->setOrderMasterId($app['authentication']->getUser()->get_id());
$orderElement->setDeny(true);
$app['EM']->persist($orderElement);
$n++;
}
}
$app['EM']->flush();
if ($n > 0) {
$order->setTodo($order->getTodo() - $n);
$app['EM']->persist($order);
$app['EM']->flush();
$params = array(
'from' => $app['authentication']->getUser()->get_id(),
'to' => $order->getUsrId(),
'n' => $n
);
$app['events-manager']->trigger('__ORDER_NOT_DELIVERED__', $params);
}
$success = true; $success = true;
} catch (\Exception $e) { } catch (\Exception $e) {

View File

@@ -1,550 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Controller\RecordsRequest;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
*
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class set_order extends set_abstract
{
/**
*
* @var int
*/
protected $id;
/**
*
* @var user
*/
protected $user;
/**
*
* @var int
*/
protected $todo;
/**
*
* @var DateTime
*/
protected $created_on;
/**
*
* @var string
*/
protected $usage;
/**
*
* @var DateTime
*/
protected $deadline;
/**
*
* @var int
*/
protected $total;
/**
*
* @var int
*/
protected $ssel_id;
protected $app;
/**
* Create a new order entry
*
* @param Application $app
* @param RecordsRequest $records
* @param \User_Adapter $orderer
* @param string $usage
* @param \DateTime $deadline
*
* @return boolean
*/
public static function create(Application $app, RecordsRequest $records, \User_Adapter $orderer, $usage, \DateTime $deadline = null)
{
$app['phraseanet.appbox']->get_connection()->beginTransaction();
try {
$sql = 'INSERT INTO `order` (`id`, `usr_id`, `created_on`, `usage`, `deadline`)
VALUES (null, :from_usr_id, NOW(), :usage, :deadline)';
$stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute(array(
':from_usr_id' => $orderer->get_id(),
':usage' => $usage,
':deadline' => (null !== $deadline ? $app['date-formatter']->format_mysql($deadline) : $deadline)
));
$stmt->closeCursor();
$orderId = $app['phraseanet.appbox']->get_connection()->lastInsertId();
$sql = 'INSERT INTO order_elements (id, order_id, base_id, record_id, order_master_id)
VALUES (null, :order_id, :base_id, :record_id, null)';
$stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql);
foreach ($records as $record) {
$stmt->execute(array(
':order_id' => $orderId,
':base_id' => $record->get_base_id(),
':record_id' => $record->get_record_id()
));
}
$stmt->closeCursor();
$app['phraseanet.appbox']->get_connection()->commit();
} catch (Exception $e) {
$app['phraseanet.appbox']->get_connection()->rollBack();
return false;
}
$app['events-manager']->trigger('__NEW_ORDER__', array(
'order_id' => $orderId,
'usr_id' => $orderer->get_id()
));
return $orderId;
}
/**
* List orders
*
* @param Application $app
* @param array $baseIds
* @param integer $offsetStart
* @param integer $perPage
* @param string $sort
*
* @return array
*/
public static function listOrders(Application $app, array $baseIds, $offsetStart = 0, $perPage = 10, $sort = null)
{
$sql = 'SELECT distinct o.id, o.usr_id, created_on, deadline, `usage`
FROM (`order_elements` e, `order` o)
WHERE e.base_id IN (' . implode(', ', $baseIds) . ')
AND e.order_id = o.id
GROUP BY o.id
ORDER BY o.id DESC
LIMIT ' . $offsetStart . ',' . $perPage;
$elements = array();
$stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute();
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
foreach ($rs as $row) {
$id = (int) $row['id'];
$elements[$id] = new static($app, $id);
}
unset($stmt);
if ($sort && count($elements) > 0) {
if ($sort == 'created_on') {
uasort($elements, array(__CLASS__, 'date_orders_sort'));
} elseif ($sort == 'user') {
uasort($elements, array(__CLASS__, 'user_orders_sort'));
} elseif ($sort == 'usage') {
uasort($elements, array(__CLASS__, 'usage_orders_sort'));
}
}
return $elements;
}
/**
* Get total orders for selected base ids
*
* @param appbox $appbox
* @param array $baseIds
* @return integer
*/
public static function countTotalOrder(appbox $appbox, array $baseIds = array())
{
$sql = 'SELECT distinct o.id
FROM (`order_elements` e, `order` o)
WHERE ' . (count($baseIds > 0 ) ? 'e.base_id IN (' . implode(', ', $baseIds) . ') AND ': '' ).
'e.order_id = o.id
GROUP BY o.id
ORDER BY o.id DESC';
$stmt = $appbox->get_connection()->prepare($sql);
$stmt->execute();
$total = $stmt->rowCount();
$stmt->closeCursor();
unset($stmt);
return (int) $total;
}
/**
*
* @param Application $app
* @param int $id
*
* @return set_order
*/
public function __construct(Application $app, $id)
{
$this->app = $app;
$conn = $app['phraseanet.appbox']->get_connection();
$sql = 'SELECT o.id, o.usr_id, o.created_on, o.`usage`, o.deadline,
COUNT(e.id) as total, o.ssel_id, COUNT(e2.id) as todo
FROM (`order` o, order_elements e)
LEFT JOIN order_elements e2
ON (
ISNULL(e2.order_master_id)
AND e.id = e2.id
)
WHERE o.id = e.order_id
AND o.id = :order_id';
$stmt = $conn->prepare($sql);
$stmt->execute(array(':order_id' => $id));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if ( ! $row)
throw new NotFoundHttpException('unknown order ' . $id);
$current_user = User_Adapter::getInstance($row['usr_id'], $app);
$this->id = $row['id'];
$this->user = $current_user;
$this->todo = $row['todo'];
$this->created_on = new DateTime($row['created_on']);
$this->usage = $row['usage'];
$this->deadline = new DateTime($row['deadline']);
$this->total = (int) $row['total'];
$this->ssel_id = (int) $row['ssel_id'];
$base_ids = array_keys($app['authentication']->getUser()->ACL()->get_granted_base(array('order_master')));
$sql = 'SELECT e.base_id, e.record_id, e.order_master_id, e.id, e.deny
FROM order_elements e
WHERE order_id = :order_id
AND e.base_id
IN (' . implode(',', $base_ids) . ')';
$stmt = $conn->prepare($sql);
$stmt->execute(array(':order_id' => $id));
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
$elements = array();
foreach ($rs as $row) {
$order_master_id = $row['order_master_id'] ? $row['order_master_id'] : false;
$elements[$row['id']] = new record_orderElement(
$app,
phrasea::sbasFromBas($this->app, $row['base_id']),
$row['record_id'],
$row['deny'],
$order_master_id
);
}
$this->elements = $elements;
return $this;
}
/**
*
* @return User_Adapter
*/
public function get_user()
{
return $this->user;
}
/**
*
* @return DateTime
*/
public function get_created_on()
{
return $this->created_on;
}
/**
*
* @return DateTime
*/
public function get_deadline()
{
return $this->deadline;
}
/**
*
* @return string
*/
public function get_usage()
{
return $this->usage;
}
/**
*
* @return int
*/
public function get_total()
{
return $this->total;
}
/**
*
* @return int
*/
public function get_order_id()
{
return $this->id;
}
/**
*
* @return int
*/
public function get_todo()
{
return $this->todo;
}
/**
*
* @param Application $app
* @param Array $elements_ids
* @param boolean $force
*
* @return set_order
*/
public function send_elements(Application $app, Array $elements_ids, $force)
{
$conn = $app['phraseanet.appbox']->get_connection();
$basrecs = array();
foreach ($elements_ids as $id) {
if (isset($this->elements[$id])) {
$basrecs[$id] = array(
'base_id' => $this->elements[$id]->get_base_id(),
'record_id' => $this->elements[$id]->get_record_id()
);
}
}
$dest_user = $this->user;
$Basket = null;
/* @var $repository \Repositories\BasketRepository */
if ($this->ssel_id) {
$repository = $app['EM']->getRepository('\Entities\Basket');
try {
$Basket = $repository->findUserBasket($app, $this->ssel_id, $dest_user, false);
} catch (\Exception $e) {
$Basket = null;
}
}
if (! $Basket) {
$Basket = new \Entities\Basket();
$Basket->setName(sprintf(_('Commande du %s'), $this->created_on->format('Y-m-d')));
$Basket->setOwner($this->user);
$Basket->setPusher($app['authentication']->getUser());
$app['EM']->persist($Basket);
$app['EM']->flush();
$this->ssel_id = $Basket->getId();
$sql = 'UPDATE `order` SET ssel_id = :ssel_id WHERE id = :order_id';
$stmt = $conn->prepare($sql);
$stmt->execute(array(':ssel_id' => $Basket->getId(), ':order_id' => $this->id));
$stmt->closeCursor();
}
$n = 0;
$sql = 'UPDATE order_elements
SET deny="0", order_master_id = :usr_id
WHERE order_id = :order_id
AND id = :order_element_id';
if (! $force) {
$sql .= ' AND ISNULL(order_master_id)';
}
$stmt = $conn->prepare($sql);
foreach ($basrecs as $order_element_id => $basrec) {
try {
$sbas_id = phrasea::sbasFromBas($app, $basrec['base_id']);
$record = new record_adapter($app, $sbas_id, $basrec['record_id']);
$BasketElement = new \Entities\BasketElement();
$BasketElement->setRecord($record);
$BasketElement->setBasket($Basket);
$Basket->addElement($BasketElement);
$app['EM']->persist($BasketElement);
$params = array(
':usr_id' => $app['authentication']->getUser()->get_id()
, ':order_id' => $this->id
, ':order_element_id' => $order_element_id
);
$stmt->execute($params);
$n ++;
$this->user->ACL()->grant_hd_on($record, $app['authentication']->getUser(), 'order');
unset($record);
} catch (Exception $e) {
}
}
$app['EM']->flush();
$stmt->closeCursor();
if ($n > 0) {
$params = array(
'ssel_id' => $this->ssel_id,
'from' => $app['authentication']->getUser()->get_id(),
'to' => $this->user->get_id(),
'n' => $n
);
$app['events-manager']->trigger('__ORDER_DELIVER__', $params);
}
return $this;
}
/**
*
* @param Array $elements_ids
* @return set_order
*/
public function deny_elements(Array $elements_ids)
{
$conn = $this->app['phraseanet.appbox']->get_connection();
$n = 0;
foreach ($elements_ids as $order_element_id) {
$sql = 'UPDATE order_elements
SET deny="1", order_master_id = :order_master_id
WHERE order_id = :order_id AND id = :order_element_id
AND ISNULL(order_master_id)';
$params = array(
':order_master_id' => $this->app['authentication']->getUser()->get_id()
, ':order_id' => $this->id
, ':order_element_id' => $order_element_id
);
$stmt = $conn->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
$n ++;
}
if ($n > 0) {
$params = array(
'from' => $this->app['authentication']->getUser()->get_id(),
'to' => $this->user->get_id(),
'n' => $n
);
$this->app['events-manager']->trigger('__ORDER_NOT_DELIVERED__', $params);
}
return $this;
}
/**
* Order orders by usage
*
* @param string $a
* @param string $b
* @return int
*/
private static function usage_orders_sort($a, $b)
{
$comp = strcasecmp($a['usage'], $b['usage']);
if ($comp == 0) {
return 0;
}
return $comp < 0 ? -1 : 1;
}
/**
* Order orders by user
*
* @param string $a
* @param string $b
* @return int
*/
private static function user_orders_sort($a, $b)
{
$comp = strcasecmp($a['usr_display'], $b['usr_display']);
if ($comp == 0) {
return 0;
}
return $comp < 0 ? -1 : 1;
}
/**
* Order orders by date
*
* @param DateTime $a
* @param DateTime $b
* @return int
*/
private static function date_orders_sort(DateTime $a, DateTime $b)
{
$comp = $b->format('U') - $a->format('U');
if ($comp == 0) {
return 0;
}
return $comp < 0 ? -1 : 1;
}
}

View File

@@ -0,0 +1,34 @@
Entities\Order:
type: entity
repositoryClass: Repositories\OrderRepository
table: Orders
id:
id:
type: integer
generator:
strategy: AUTO
fields:
usr_id:
type: integer
ssel_id:
type: integer
nullable: true
order_usage:
type: string
length: 2048
deadline:
type: datetime
todo:
type: integer
nullable: true
created_on:
type: datetime
gedmo:
timestampable:
on: create
oneToMany:
elements:
targetEntity: OrderElement
mappedBy: order
cascade: ["ALL"]

View File

@@ -0,0 +1,31 @@
Entities\OrderElement:
type: entity
repositoryClass: Repositories\OrderElementRepository
table: OrderElements
uniqueConstraints:
unique_ordercle:
columns: base_id,record_id,order_id
id:
id:
type: integer
generator:
strategy: AUTO
fields:
base_id:
type: integer
record_id:
type: integer
order_master_id:
type: integer
nullable: true
deny:
type: boolean
nullable: true
manyToOne:
order:
targetEntity: Order
inversedBy: elements
joinColumn:
name: order_id
referencedColumnName: id
cascade: ["persist"]

View File

@@ -40,10 +40,10 @@
</thead> </thead>
<tbody> <tbody>
{% for order in orders %} {% for order in orders %}
{% set deadline = app['date-formatter'].getPrettyString(order.get_deadline()) %} {% set deadline = app['date-formatter'].getPrettyString(order.getDeadline()) %}
<tr id="order_{{ order.get_order_id() }}" class="order_row" {{ current_date > order.get_deadline() ? "style=color:#777": "" }}> <tr id="order_{{ order.getId() }}" class="order_row" {{ current_date > order.getDeadline() ? "style=color:#777": "" }}>
<td>{{ order.get_user().get_display_name() }}</td> <td>{{ order.getUser(app).get_display_name() }}</td>
<td>{{ app['date-formatter'].getPrettyString(order.get_created_on()) }}</td> <td>{{ app['date-formatter'].getPrettyString(order.getCreatedOn()) }}</td>
<td> <td>
{% if deadline != '' %} {% if deadline != '' %}
{{deadline}} {{deadline}}
@@ -51,8 +51,8 @@
{% trans 'Aucune' %} {% trans 'Aucune' %}
{% endif %} {% endif %}
</td> </td>
<td>{{ order.get_usage() | nl2br }}</td> <td>{{ order.getOrderUsage() | nl2br }}</td>
<td>{% if order.get_todo() == 0 %}<img src="/skins/icons/ok.png" />{% endif %}</td> <td>{% if order.getTodo() == 0 %}<img src="/skins/icons/ok.png" />{% endif %}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>

View File

@@ -1,5 +1,5 @@
{% import 'common/thumbnail.html.twig' as thumbnail %} {% import 'common/thumbnail.html.twig' as thumbnail %}
{% set displayName = order.get_user().get_display_name() %} {% set displayName = order.getUser(app).get_display_name() %}
<div class="page-header"> <div class="page-header">
<h1>{% trans %} {{ displayName }} wants to place an order {% endtrans %}</h1> <h1>{% trans %} {{ displayName }} wants to place an order {% endtrans %}</h1>
@@ -29,23 +29,23 @@
<table class="table" style="color:#333;"> <table class="table" style="color:#333;">
<tr> <tr>
<td>{% trans 'Destinataire' %}</td> <td>{% trans 'Destinataire' %}</td>
<td>{{ displayName }}({{ order.get_user().get_email() }})</td> <td>{{ displayName }}({{ order.getUser(app).get_email() }})</td>
</tr> </tr>
<tr> <tr>
<td>{% trans 'Date de commande' %}</td> <td>{% trans 'Date de commande' %}</td>
<td>{{ app['date-formatter'].getPrettyString(order.get_created_on()) }}</td> <td>{{ app['date-formatter'].getPrettyString(order.getCreatedOn()) }}</td>
</tr> </tr>
<tr> <tr>
<td>{% trans 'Deadline' %}</td> <td>{% trans 'Deadline' %}</td>
<td>{{ app['date-formatter'].getPrettyString(order.get_deadline()) }}</td> <td>{{ app['date-formatter'].getPrettyString(order.getDeadline()) }}</td>
</tr> </tr>
<tr> <tr>
<td>{% trans 'Utilisation prevue' %}</td> <td>{% trans 'Utilisation prevue' %}</td>
<td>{{ order.get_usage() | nl2br }}</td> <td>{{ order.getOrderUsage() | nl2br }}</td>
</tr> </tr>
<tr> <tr>
<td>{% trans 'Nombre total d\'element commandes' %}</td> <td>{% trans 'Nombre total d\'element commandes' %}</td>
<td>{{ order.get_total() }}</td> <td>{{ order.getTotal() }}</td>
</tr> </tr>
</table> </table>
</div> </div>
@@ -55,13 +55,13 @@
<div class="order_list well-small"> <div class="order_list well-small">
<ul> <ul>
{% for order_element_id,element in order %} {% for element in order.getElements() %}
<li> <li>
<div id="order_wrapper_{{order.get_order_id()}}_{{element.get_base_id()}}_{{element.get_record_id()}}" class="order_wrapper {% if element.get_order_master_id() == false %}selectable{% endif %}"> <div id="order_wrapper_{{order.getId()}}_{{element.getBaseId()}}_{{element.getRecordId()}}" class="order_wrapper {% if element.getOrderMasterId() == false %}selectable{% endif %}">
{{ thumbnail.format(element.get_thumbnail() ,80, 80, '', true, false) }} {{ thumbnail.format(element.getRecord(app).get_thumbnail() ,80, 80, '', true, false) }}
{% if element.get_order_master_id() %} {% if element.getOrderMasterId() %}
{% set name = element.get_order_master_name() %} {% set name = element.getOrderMasterName(app) %}
{% if element.get_deny() == 1 %} {% if element.getDeny() == true %}
{% set title %} {% set title %}
{% trans %}Document refuse par {{name}} {% endtrans %} {% trans %}Document refuse par {{name}} {% endtrans %}
{% endset %} {% endset %}
@@ -78,11 +78,11 @@
{% endif %} {% endif %}
{% endif %} {% endif %}
<div style="position:absolute;bottom:4px;right:4px;"> <div style="position:absolute;bottom:4px;right:4px;">
<img class="infoTips" tooltipsrc="{{ path('prod_tooltip_technical_data', { 'sbas_id' : element.get_sbas_id(), 'record_id' : element.get_record_id() }) }}" src="/skins/icons/info.gif"/> <img class="infoTips" tooltipsrc="{{ path('prod_tooltip_technical_data', { 'sbas_id' : element.getSbasId(app), 'record_id' : element.getRecordId() }) }}" src="/skins/icons/info.gif"/>
<div tooltipsrc="{{ path('prod_tooltip_preview', { 'sbas_id' : element.get_sbas_id(), 'record_id' : element.get_record_id() }) }}" class="previewTips"></div> <div tooltipsrc="{{ path('prod_tooltip_preview', { 'sbas_id' : element.getSbasId(app), 'record_id' : element.getRecordId() }) }}" class="previewTips"></div>
<div tooltipsrc="{{ path('prod_tooltip_caption', { 'sbas_id' : element.get_sbas_id(), 'record_id' : element.get_record_id(), 'context' : 'preview' }) }}" class="captionRolloverTips"></div> <div tooltipsrc="{{ path('prod_tooltip_caption', { 'sbas_id' : element.getSbasId(app), 'record_id' : element.getRecordId(), 'context' : 'preview' }) }}" class="captionRolloverTips"></div>
</div> </div>
<input type="hidden" name="order_element_id" value="{{order_element_id}}"/> <input type="hidden" name="order_element_id" value="{{element.getId()}}"/>
</div> </div>
</li> </li>
{% endfor %} {% endfor %}
@@ -95,7 +95,7 @@
<button class="btn deny">Refuser</button> <button class="btn deny">Refuser</button>
<button class="order_launcher btn">{% trans 'Retour aux commandes' %}</button> <button class="order_launcher btn">{% trans 'Retour aux commandes' %}</button>
<img src="/skins/icons/loader000000.gif" class="activity_indicator" style="display:none;"/> <img src="/skins/icons/loader000000.gif" class="activity_indicator" style="display:none;"/>
<input name="order_id" type="hidden" value="{{ order.get_order_id() }}" /> <input name="order_id" type="hidden" value="{{ order.getId() }}" />
</div> </div>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">

View File

@@ -4,6 +4,8 @@ namespace Alchemy\Tests\Phrasea\Controller\Prod;
use Alchemy\Phrasea\Controller\RecordsRequest; use Alchemy\Phrasea\Controller\RecordsRequest;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Entities\Order;
use Entities\OrderElement;
class OrderTest extends \PhraseanetWebTestCaseAuthenticatedAbstract class OrderTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
{ {
@@ -62,7 +64,7 @@ class OrderTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
public function testDisplayOneOrder() public function testDisplayOneOrder()
{ {
$order = $this->createOneOrder('I need this pictures'); $order = $this->createOneOrder('I need this pictures');
self::$DI['client']->request('GET', '/prod/order/' . $order->get_order_id() . '/'); self::$DI['client']->request('GET', '/prod/order/' . $order->getId() . '/');
$this->assertTrue(self::$DI['client']->getResponse()->isOk()); $this->assertTrue(self::$DI['client']->getResponse()->isOk());
} }
@@ -76,10 +78,10 @@ class OrderTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
$this->mockNotificationDeliverer('Alchemy\Phrasea\Notification\Mail\MailInfoOrderDelivered'); $this->mockNotificationDeliverer('Alchemy\Phrasea\Notification\Mail\MailInfoOrderDelivered');
$parameters = array(); $parameters = array();
foreach ($order as $id => $element) { foreach ($order->getElements() as $element) {
$parameters[] = $id; $parameters[] = $element->getId();
} }
self::$DI['client']->request('POST', '/prod/order/' . $order->get_order_id() . '/send/', array('elements' => $parameters)); self::$DI['client']->request('POST', '/prod/order/' . $order->getId() . '/send/', array('elements' => $parameters));
$this->assertTrue(self::$DI['client']->getResponse()->isRedirect()); $this->assertTrue(self::$DI['client']->getResponse()->isRedirect());
$url = parse_url(self::$DI['client']->getResponse()->headers->get('location')); $url = parse_url(self::$DI['client']->getResponse()->headers->get('location'));
parse_str($url['query']); parse_str($url['query']);
@@ -96,10 +98,10 @@ class OrderTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
$this->mockNotificationDeliverer('Alchemy\Phrasea\Notification\Mail\MailInfoOrderDelivered'); $this->mockNotificationDeliverer('Alchemy\Phrasea\Notification\Mail\MailInfoOrderDelivered');
$parameters = array(); $parameters = array();
foreach ($order as $id => $element) { foreach ($order->getElements() as $element) {
$parameters[] = $id; $parameters[] = $element->getId();
} }
$this->XMLHTTPRequest('POST', '/prod/order/' . $order->get_order_id() . '/send/', array('elements' => $parameters)); $this->XMLHTTPRequest('POST', '/prod/order/' . $order->getId() . '/send/', array('elements' => $parameters));
$this->assertTrue(self::$DI['client']->getResponse()->isOk()); $this->assertTrue(self::$DI['client']->getResponse()->isOk());
$response = self::$DI['client']->getResponse(); $response = self::$DI['client']->getResponse();
$this->assertTrue($response->isOk()); $this->assertTrue($response->isOk());
@@ -122,10 +124,10 @@ class OrderTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
$this->mockNotificationDeliverer('Alchemy\Phrasea\Notification\Mail\MailInfoOrderCancelled'); $this->mockNotificationDeliverer('Alchemy\Phrasea\Notification\Mail\MailInfoOrderCancelled');
$parameters = array(); $parameters = array();
foreach ($order as $id => $element) { foreach ($order->getElements() as $element) {
$parameters[] = $id; $parameters[] = $element->getId();
} }
self::$DI['client']->request('POST', '/prod/order/' . $order->get_order_id() . '/deny/', array('elements' => $parameters)); self::$DI['client']->request('POST', '/prod/order/' . $order->getId() . '/deny/', array('elements' => $parameters));
$this->assertTrue(self::$DI['client']->getResponse()->isRedirect()); $this->assertTrue(self::$DI['client']->getResponse()->isRedirect());
$url = parse_url(self::$DI['client']->getResponse()->headers->get('location')); $url = parse_url(self::$DI['client']->getResponse()->headers->get('location'));
parse_str($url['query']); parse_str($url['query']);
@@ -142,10 +144,10 @@ class OrderTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
$this->mockNotificationDeliverer('Alchemy\Phrasea\Notification\Mail\MailInfoOrderCancelled'); $this->mockNotificationDeliverer('Alchemy\Phrasea\Notification\Mail\MailInfoOrderCancelled');
$parameters = array(); $parameters = array();
foreach ($order as $id => $element) { foreach ($order->getElements() as $element) {
$parameters[] = $id; $parameters[] = $element->getId();
} }
$this->XMLHTTPRequest('POST', '/prod/order/' . $order->get_order_id() . '/deny/', array('elements' => $parameters)); $this->XMLHTTPRequest('POST', '/prod/order/' . $order->getId() . '/deny/', array('elements' => $parameters));
$response = self::$DI['client']->getResponse(); $response = self::$DI['client']->getResponse();
$this->assertTrue($response->isOk()); $this->assertTrue($response->isOk());
$this->assertEquals('application/json', $response->headers->get('Content-Type')); $this->assertEquals('application/json', $response->headers->get('Content-Type'));
@@ -157,20 +159,74 @@ class OrderTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
$this->assertObjectHasAttribute('order_id', $content, $response->getContent()); $this->assertObjectHasAttribute('order_id', $content, $response->getContent());
} }
public function testTodo()
{
$order = $this->createOneOrder('I need this pictures');
$this->mockNotificationDeliverer('Alchemy\Phrasea\Notification\Mail\MailInfoOrderDelivered');
$parameters = array();
foreach ($order->getElements() as $element) {
$parameters[] = $element->getId();
}
self::$DI['client']->request('POST', '/prod/order/' . $order->getId() . '/send/', array('elements' => $parameters));
$testOrder = self::$DI['app']['EM']->getRepository('Entities\Order')->find($order->getId());
$this->assertEquals(0, $testOrder->getTodo());
}
public function testTodoOnDenied()
{
$order = $this->createOneOrder('I need this pictures');
$orderElement = new OrderElement();
$orderElement->setBaseId(self::$DI['record_2']->get_base_id());
$orderElement->setRecordId(self::$DI['record_2']->get_record_id());
$orderElement->setOrder($order);
$order->addElement($orderElement);
$order->setTodo(2);
self::$DI['app']['EM']->persist($order);
self::$DI['app']['EM']->persist($orderElement);
self::$DI['app']['EM']->flush();
$parameters = array($order->getElements()->first()->getId());
self::$DI['client']->request('POST', '/prod/order/' . $order->getId() . '/send/', array('elements' => $parameters));
$testOrder = self::$DI['app']['EM']->getRepository('Entities\Order')->find($order->getId());
$this->assertEquals(1, $testOrder->getTodo());
$parameters = array($orderElement->getId());
self::$DI['client']->request('POST', '/prod/order/' . $order->getId() . '/deny/', array('elements' => $parameters));
$testOrder = self::$DI['app']['EM']->getRepository('Entities\Order')->find($order->getId());
$this->assertEquals(0, $testOrder->getTodo());
}
private function createOneOrder($usage) private function createOneOrder($usage)
{ {
self::$DI['app']['notification.deliverer'] = $this->getMockBuilder('Alchemy\Phrasea\Notification\Deliverer') self::$DI['app']['notification.deliverer'] = $this->getMockBuilder('Alchemy\Phrasea\Notification\Deliverer')
->disableOriginalConstructor() ->disableOriginalConstructor()
->getMock(); ->getMock();
self::$DI['app']['notification.deliverer']->expects($this->atLeastOnce())
->method('deliver')
->with($this->isInstanceOf('Alchemy\Phrasea\Notification\Mail\MailInfoNewOrder'), $this->equalTo(null));
$receveid = array(self::$DI['record_1']->get_serialize_key() => self::$DI['record_1']); $receveid = array(self::$DI['record_1']->get_serialize_key() => self::$DI['record_1']);
return new \set_order(self::$DI['app'], \set_order::create( $order = new Order();
self::$DI['app'], new RecordsRequest($receveid, new ArrayCollection($receveid)), self::$DI['user_alt2'] ,$usage, new \DateTime('+10 minutes') $order->setOrderUsage($usage);
)); $order->setUsrId(self::$DI['user_alt2']->get_id());
$order->setDeadline(new \DateTime('+10 minutes'));
$orderElement = new OrderElement();
$orderElement->setBaseId(self::$DI['record_1']->get_base_id());
$orderElement->setRecordId(self::$DI['record_1']->get_record_id());
$orderElement->setOrder($order);
$order->addElement($orderElement);
$order->setTodo(1);
self::$DI['app']['EM']->persist($order);
self::$DI['app']['EM']->persist($orderElement);
self::$DI['app']['EM']->flush();
return $order;
} }
} }

View File

@@ -971,7 +971,7 @@ abstract class PhraseanetPHPUnitAbstract extends WebTestCase
self::$DI['app']['notification.deliverer'] = $this->getMockBuilder('Alchemy\Phrasea\Notification\Deliverer') self::$DI['app']['notification.deliverer'] = $this->getMockBuilder('Alchemy\Phrasea\Notification\Deliverer')
->disableOriginalConstructor() ->disableOriginalConstructor()
->getMock(); ->getMock();
//
self::$DI['app']['notification.deliverer']->expects($this->exactly($qty)) self::$DI['app']['notification.deliverer']->expects($this->exactly($qty))
->method('deliver') ->method('deliver')
->with($this->isInstanceOf($expectedMail), $this->equalTo($receipt)); ->with($this->isInstanceOf($expectedMail), $this->equalTo($receipt));