[Order] Introduce immutable order items

This commit is contained in:
stloyd 2014-09-30 09:12:57 +02:00
parent e60e98b8ed
commit 354d47b83e
7 changed files with 108 additions and 41 deletions

View file

@ -0,0 +1,28 @@
<?php
namespace Sylius\Migrations;
use Doctrine\DBAL\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema;
/**
* Auto-generated Migration: Please modify to your needs!
*/
class Version20140930184010 extends AbstractMigration
{
public function up(Schema $schema)
{
// this up() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'mysql', 'Migration can only be executed safely on \'mysql\'.');
$this->addSql('ALTER TABLE sylius_order_item ADD is_immutable TINYINT(1) NOT NULL');
}
public function down(Schema $schema)
{
// this down() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'mysql', 'Migration can only be executed safely on \'mysql\'.');
$this->addSql('ALTER TABLE sylius_order_item DROP is_immutable');
}
}

View file

@ -48,23 +48,23 @@ class OrderPricingListener
public function recalculatePrices(GenericEvent $event)
{
$order = $event->getSubject();
if (!$order instanceof OrderInterface) {
throw new UnexpectedTypeException($order, 'Sylius\Component\Order\Model\OrderInterface');
}
$context = array();
if (null !== $user = $order->getUser()) {
$context['user'] = $user;
$context['groups'] = $user->getGroups()->toArray();
}
foreach ($order->getItems() as $item) {
$priceable = $item->getVariant();
if ($item->isImmutable()) {
continue;
}
$context['quantity'] = $item->getQuantity();
$item->setUnitPrice($this->priceCalculator->calculate($priceable, $context));
$item->setUnitPrice($this->priceCalculator->calculate($item->getVariant(), $context));
}
$order->calculateTotal();

View file

@ -30,6 +30,7 @@
</field>
<field name="adjustmentsTotal" column="adjustments_total" type="integer" />
<field name="total" column="total" type="integer" />
<field name="immutable" column="is_immutable" type="boolean" />
<many-to-one field="order" target-entity="Sylius\Component\Order\Model\OrderInterface" inversed-by="items">
<join-column name="order_id" referenced-column-name="id" nullable="false" />

View file

@ -73,6 +73,8 @@ class AddProductAction implements PromotionActionInterface
}
}
$promotionItem->setImmutable(true);
$subject->addItem($promotionItem);
}
@ -90,6 +92,7 @@ class AddProductAction implements PromotionActionInterface
}
$promotionItem = $this->createItem($configuration);
$promotionItem->setImmutable(true);
foreach ($subject->getItems() as $item) {
if ($item->equals($promotionItem)) {

View file

@ -48,12 +48,13 @@ class AddProductActionSpec extends ObjectBehavior
) {
$configuration = array('variant' => 500, 'quantity' => 2, 'price' => 0);
$variantRepository->find($configuration['variant'])->shouldBeCalled()->willReturn($variant);
$variantRepository->find($configuration['variant'])->willReturn($variant);
$itemRepository->createNew()->willReturn($item);
$item->setUnitPrice($configuration['price'])->shouldBeCalled()->willReturn($item);
$item->setVariant($variant)->shouldBeCalled()->willReturn($item);
$item->setQuantity($configuration['quantity'])->shouldBeCalled()->willReturn($item);
$item->setUnitPrice($configuration['price'])->willReturn($item);
$item->setVariant($variant)->willReturn($item);
$item->setQuantity($configuration['quantity'])->willReturn($item);
$item->setImmutable(true)->shouldBeCalled();
$order->getItems()->willReturn(array());
@ -63,21 +64,21 @@ class AddProductActionSpec extends ObjectBehavior
}
function it_does_not_add_product_if_exists(
RepositoryInterface $variantRepository,
RepositoryInterface $itemRepository,
OrderInterface $order,
OrderItemInterface $item,
ProductVariantInterface $variant,
PromotionInterface $promotion
RepositoryInterface $variantRepository,
RepositoryInterface $itemRepository,
OrderInterface $order,
OrderItemInterface $item,
ProductVariantInterface $variant,
PromotionInterface $promotion
) {
$configuration = array('variant' => 500, 'quantity' => 2, 'price' => 1);
$variantRepository->find($configuration['variant'])->willReturn($variant);
$itemRepository->createNew()->willReturn($item);
$item->setUnitPrice($configuration['price'])->shouldBeCalled()->willReturn($item);
$item->setVariant($variant)->shouldBeCalled()->willReturn($item);
$item->setQuantity($configuration['quantity'])->shouldBeCalled()->willReturn($item);
$item->setUnitPrice($configuration['price'])->willReturn($item);
$item->setVariant($variant)->willReturn($item);
$item->setQuantity($configuration['quantity'])->willReturn($item);
$item->equals($item)->willReturn(true);
$order->getItems()->willReturn(array($item));
@ -88,22 +89,23 @@ class AddProductActionSpec extends ObjectBehavior
}
function it_reverts_product(
RepositoryInterface $variantRepository,
RepositoryInterface $itemRepository,
OrderInterface $order,
OrderItemInterface $item,
ProductVariantInterface $variant,
PromotionInterface $promotion
RepositoryInterface $variantRepository,
RepositoryInterface $itemRepository,
OrderInterface $order,
OrderItemInterface $item,
ProductVariantInterface $variant,
PromotionInterface $promotion
) {
$configuration = array('variant' => 500, 'quantity' => 3, 'price' => 2);
$variantRepository->find($configuration['variant'])->willReturn($variant);
$itemRepository->createNew()->willReturn($item);
$item->setUnitPrice($configuration['price'])->shouldBeCalled()->willReturn($item);
$item->setVariant($variant)->shouldBeCalled()->willReturn($item);
$item->setQuantity($configuration['quantity'])->shouldBeCalled()->willReturn($item);
$item->setUnitPrice($configuration['price'])->willReturn($item);
$item->setVariant($variant)->willReturn($item);
$item->setQuantity($configuration['quantity'])->willReturn($item);
$item->equals($item)->willReturn(true);
$item->setImmutable(true)->shouldBeCalled();
$order->getItems()->willReturn(array($item));

View file

@ -38,14 +38,14 @@ class OrderItem implements OrderItemInterface
/**
* Quantity.
*
* @var integer
* @var int
*/
protected $quantity = 1;
/**
* Unit price.
*
* @var integer
* @var int
*/
protected $unitPrice = 0;
@ -59,17 +59,24 @@ class OrderItem implements OrderItemInterface
/**
* Adjustments total.
*
* @var integer
* @var int
*/
protected $adjustmentsTotal = 0;
/**
* Order item total.
*
* @var integer
* @var int
*/
protected $total = 0;
/**
* Order item is immutable?
*
* @var bool
*/
protected $immutable = false;
/**
* Constructor.
*/
@ -293,7 +300,7 @@ class OrderItem implements OrderItemInterface
*/
public function merge(OrderItemInterface $orderItem, $throwOnInvalid = true)
{
if ($throwOnInvalid && ! $orderItem->equals($this)) {
if ($throwOnInvalid && !$orderItem->equals($this)) {
throw new \RuntimeException('Given item cannot be merged.');
}
@ -303,4 +310,22 @@ class OrderItem implements OrderItemInterface
return $this;
}
/**
* {@inheritdoc}
*/
public function isImmutable()
{
return $this->immutable;
}
/**
* {@inheritdoc}
*/
public function setImmutable($immutable)
{
$this->immutable = (bool) $immutable;
return $this;
}
}

View file

@ -21,42 +21,42 @@ interface OrderItemInterface extends AdjustableInterface, OrderAwareInterface
/**
* Get item quantity.
*
* @return integer
* @return int
*/
public function getQuantity();
/**
* Set quantity.
*
* @param integer $quantity
* @param int $quantity
*/
public function setQuantity($quantity);
/**
* Get unit price of item.
*
* @return integer
* @return int
*/
public function getUnitPrice();
/**
* Define the unit price of item.
*
* @param integer $unitPrice
* @param int $unitPrice
*/
public function setUnitPrice($unitPrice);
/**
* Get item total.
*
* @return integer
* @return int
*/
public function getTotal();
/**
* Set item total.
*
* @param integer $total
* @param int $total
*/
public function setTotal($total);
@ -72,7 +72,7 @@ interface OrderItemInterface extends AdjustableInterface, OrderAwareInterface
*
* @param OrderItemInterface $orderItem
*
* @return Boolean
* @return bool
*/
public function equals(OrderItemInterface $orderItem);
@ -81,9 +81,17 @@ interface OrderItemInterface extends AdjustableInterface, OrderAwareInterface
* the same cart item.
*
* @param OrderItemInterface $orderItem
* @param Boolean $throwOnInvalid
*
* @return $this
* @param bool $throwOnInvalid
*/
public function merge(OrderItemInterface $orderItem, $throwOnInvalid = true);
/**
* @return bool
*/
public function isImmutable();
/**
* @param bool $immutable
*/
public function setImmutable($immutable);
}