mirror of
https://github.com/Sylius/Sylius.git
synced 2026-07-14 17:10:53 +00:00
Merge pull request #4400 from NeverResponse/harden-coupons
[Behat][Promotion] Removed softdeletable from Coupon
This commit is contained in:
commit
9b61490426
28 changed files with 825 additions and 33 deletions
47
app/migrations/Version20160305115221.php
Normal file
47
app/migrations/Version20160305115221.php
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Migrations;
|
||||
|
||||
use Doctrine\DBAL\Migrations\AbstractMigration;
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
class Version20160305115221 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
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_promotion_coupon DROP deleted_at');
|
||||
$this->addSql('ALTER TABLE sylius_order DROP FOREIGN KEY FK_6196A1F917B24436');
|
||||
$this->addSql('ALTER TABLE sylius_order ADD CONSTRAINT FK_6196A1F917B24436 FOREIGN KEY (promotion_coupon_id) REFERENCES sylius_promotion_coupon (id)');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
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 DROP FOREIGN KEY FK_6196A1F917B24436');
|
||||
$this->addSql('ALTER TABLE sylius_order ADD CONSTRAINT FK_6196A1F917B24436 FOREIGN KEY (promotion_coupon_id) REFERENCES sylius_promotion_coupon (id) ON DELETE SET NULL');
|
||||
$this->addSql('ALTER TABLE sylius_promotion_coupon ADD deleted_at DATETIME DEFAULT NULL');
|
||||
}
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@
|
|||
<parameter key="sylius.behat.context.domain.payment.class">Sylius\Behat\Context\Domain\PaymentContext</parameter>
|
||||
<parameter key="sylius.behat.context.domain.shipment.class">Sylius\Behat\Context\Domain\ShippingContext</parameter>
|
||||
<parameter key="sylius.behat.context.domain.product.class">Sylius\Behat\Context\Domain\ProductContext</parameter>
|
||||
<parameter key="sylius.behat.context.domain.promotion.class">Sylius\Behat\Context\Domain\PromotionContext</parameter>
|
||||
</parameters>
|
||||
|
||||
<services>
|
||||
|
|
@ -46,5 +47,12 @@
|
|||
<argument type="service" id="sylius.repository.product_review" container="symfony" />
|
||||
<tag name="sylius.behat.context" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.behat.context.domain.promotion" class="%sylius.behat.context.domain.promotion.class%" scope="scenario">
|
||||
<argument type="service" id="sylius.behat.shared_storage" container="symfony" />
|
||||
<argument type="service" id="sylius.repository.promotion" container="symfony" />
|
||||
<argument type="service" id="sylius.repository.promotion_coupon" container="symfony" />
|
||||
<tag name="sylius.behat.context" />
|
||||
</service>
|
||||
</services>
|
||||
</container>
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@
|
|||
<service id="sylius.behat.context.setup.promotion" class="%sylius.behat.context.setup.promotion.class%" scope="scenario">
|
||||
<argument type="service" id="sylius.behat.shared_storage" container="symfony" />
|
||||
<argument type="service" id="sylius.factory.promotion_action" container="symfony" />
|
||||
<argument type="service" id="sylius.factory.promotion_coupon" container="symfony" />
|
||||
<argument type="service" id="sylius.factory.promotion_rule" container="symfony" />
|
||||
<argument type="service" id="sylius.test.factory.promotion" container="symfony" />
|
||||
<argument type="service" id="sylius.repository.promotion" container="symfony" />
|
||||
|
|
@ -139,7 +140,7 @@
|
|||
<argument type="service" id="sylius.factory.payment" container="symfony" />
|
||||
<argument type="service" id="sylius.factory.order_item" container="symfony" />
|
||||
<argument type="service" id="sylius.order_item_quantity_modifier" container="symfony" />
|
||||
<argument type="service" id="sylius.order_processing.shipping_processor" container="symfony" />
|
||||
<argument type="service" id="sylius.order_processing.order_recalculator" container="symfony" />
|
||||
<argument type="service" id="doctrine.orm.entity_manager" container="symfony" />
|
||||
<tag name="sylius.behat.context" />
|
||||
</service>
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
<parameter key="sylius.behat.context.transform.taxon.class">Sylius\Behat\Context\Transform\TaxonContext</parameter>
|
||||
<parameter key="sylius.behat.context.transform.zone.class">Sylius\Behat\Context\Transform\ZoneContext</parameter>
|
||||
<parameter key="sylius.behat.context.transform.theme.class">Sylius\Behat\Context\Transform\ThemeContext</parameter>
|
||||
<parameter key="sylius.behat.context.transform.promotion.class">Sylius\Behat\Context\Transform\PromotionContext</parameter>
|
||||
</parameters>
|
||||
<services>
|
||||
<service id="sylius.behat.context.transform.customer" class="%sylius.behat.context.transform.customer.class%" scope="scenario">
|
||||
|
|
@ -89,5 +90,11 @@
|
|||
<argument type="service" id="sylius.repository.theme" container="symfony" />
|
||||
<tag name="sylius.behat.context" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.behat.context.transform.promotion" class="%sylius.behat.context.transform.promotion.class%" scope="scenario">
|
||||
<argument type="service" id="sylius.repository.promotion" container="symfony" />
|
||||
<argument type="service" id="sylius.repository.promotion_coupon" container="symfony" />
|
||||
<tag name="sylius.behat.context" />
|
||||
</service>
|
||||
</services>
|
||||
</container>
|
||||
|
|
|
|||
|
|
@ -43,5 +43,6 @@ imports:
|
|||
|
||||
- suites/domain/order.yml
|
||||
- suites/domain/product.yml
|
||||
- suites/domain/promotion.yml
|
||||
|
||||
- suites/cli/installer.yml
|
||||
|
|
|
|||
28
etc/behat/suites/domain/promotion.yml
Normal file
28
etc/behat/suites/domain/promotion.yml
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
# This file is part of the Sylius package.
|
||||
# (c) Paweł Jędrzejewski
|
||||
|
||||
default:
|
||||
suites:
|
||||
domain_promotion:
|
||||
contexts_as_services:
|
||||
- sylius.behat.context.hook.doctrine_orm
|
||||
|
||||
- sylius.behat.context.transform.shared_storage
|
||||
- sylius.behat.context.transform.addressing
|
||||
- sylius.behat.context.transform.customer
|
||||
- sylius.behat.context.transform.payment
|
||||
- sylius.behat.context.transform.product
|
||||
- sylius.behat.context.transform.promotion
|
||||
- sylius.behat.context.transform.shipping
|
||||
|
||||
- sylius.behat.context.setup.channel
|
||||
- sylius.behat.context.setup.payment
|
||||
- sylius.behat.context.setup.product
|
||||
- sylius.behat.context.setup.promotion
|
||||
- sylius.behat.context.setup.shipping
|
||||
- sylius.behat.context.setup.order
|
||||
|
||||
- sylius.behat.context.domain.promotion
|
||||
|
||||
filters:
|
||||
tags: @promotion && @domain
|
||||
|
|
@ -2,14 +2,14 @@
|
|||
Feature: Deleting a coupon
|
||||
In order to remove test, obsolete or incorrect coupons
|
||||
As an Administrator
|
||||
I want to be able to delete coupons from the registry
|
||||
I want to be able to delete a coupon from the registry
|
||||
|
||||
Background:
|
||||
Given the store operates on a single channel in "France"
|
||||
And there is a promotion "Holiday promotion" with coupon "Santa's gift"
|
||||
And I am logged in as administrator
|
||||
And the store has promotion "Christmas sale" with coupon "Santa's gift"
|
||||
|
||||
@todo
|
||||
@domain
|
||||
Scenario: Deleted coupon should disappear from the registry
|
||||
When I delete "Santa's Gift" coupon
|
||||
Then this coupon should no longer exist in the registry
|
||||
Then I should be notified that it has been successfully deleted
|
||||
And this coupon should no longer exist in the registry
|
||||
|
|
|
|||
|
|
@ -2,19 +2,20 @@
|
|||
Feature: Not being able to delete a coupon which is in use
|
||||
In order to maintain proper payment history
|
||||
As an Administrator
|
||||
I want to be prevented from deleting used coupons
|
||||
I want to be prevented from deleting a used coupon
|
||||
|
||||
Background:
|
||||
Given the store operates on a single channel in "France"
|
||||
And the store ships everywhere for free
|
||||
And the store has a product "Jacket"
|
||||
And the store allows paying with "Cash on Delivery"
|
||||
And the store has promotion "Christmas sale" with coupon "Santa's gift"
|
||||
And the customer "john.doe@gmail.com" placed an order "#00000022"
|
||||
And the customer chose "Free" shipping method to "France" with "Cash on Delivery" payment
|
||||
And the customer bought single "Jacket" using "Santa's gift" coupon
|
||||
|
||||
@todo
|
||||
@domain
|
||||
Scenario: Being unable to delete a used coupon
|
||||
When I try to delete "Santa's gift" coupon
|
||||
Then And I should be notified that it is in use and cannot be deleted
|
||||
Then I should be notified that it is in use and cannot be deleted
|
||||
And this coupon should still exist in the registry
|
||||
|
|
|
|||
112
src/Sylius/Behat/Context/Domain/PromotionContext.php
Normal file
112
src/Sylius/Behat/Context/Domain/PromotionContext.php
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Behat\Context\Domain;
|
||||
|
||||
use Behat\Behat\Context\Context;
|
||||
use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
|
||||
use Sylius\Component\Core\Test\Services\SharedStorageInterface;
|
||||
use Sylius\Component\Promotion\Model\CouponInterface;
|
||||
use Sylius\Component\Promotion\Repository\PromotionRepositoryInterface;
|
||||
use Sylius\Component\Resource\Repository\RepositoryInterface;
|
||||
|
||||
/**
|
||||
* @author Jan Góralski <jan.goralski@lakion.com>
|
||||
*/
|
||||
final class PromotionContext implements Context
|
||||
{
|
||||
/**
|
||||
* @var SharedStorageInterface
|
||||
*/
|
||||
private $sharedStorage;
|
||||
|
||||
/**
|
||||
* @var PromotionRepositoryInterface
|
||||
*/
|
||||
private $promotionRepository;
|
||||
|
||||
/**
|
||||
* @var RepositoryInterface
|
||||
*/
|
||||
private $couponRepository;
|
||||
|
||||
/**
|
||||
* @param SharedStorageInterface $sharedStorage
|
||||
* @param PromotionRepositoryInterface $promotionRepository
|
||||
* @param RepositoryInterface $couponRepository
|
||||
*/
|
||||
public function __construct(
|
||||
SharedStorageInterface $sharedStorage,
|
||||
PromotionRepositoryInterface $promotionRepository,
|
||||
RepositoryInterface $couponRepository
|
||||
) {
|
||||
$this->sharedStorage = $sharedStorage;
|
||||
$this->promotionRepository = $promotionRepository;
|
||||
$this->couponRepository = $couponRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @When /^I try to delete ("([^"]+)" coupon)$/
|
||||
*/
|
||||
public function iTryToDeleteCoupon(CouponInterface $coupon)
|
||||
{
|
||||
try {
|
||||
$this->couponRepository->remove($coupon);
|
||||
|
||||
throw new \Exception(sprintf('Coupon "%s" has been removed, but it should not.', $coupon->getCode()));
|
||||
} catch(ForeignKeyConstraintViolationException $exception) {
|
||||
$this->sharedStorage->set('last_exception', $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @When /^I delete ("([^"]+)" coupon)$/
|
||||
*/
|
||||
public function iDeleteCoupon(CouponInterface $coupon)
|
||||
{
|
||||
$this->sharedStorage->set('coupon_id', $coupon->getId());
|
||||
$this->couponRepository->remove($coupon);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^([^"]+ should no longer) exist in the registry$/
|
||||
*/
|
||||
public function couponShouldNotExistInTheRegistry($couponId)
|
||||
{
|
||||
expect($this->couponRepository->find($couponId))->toBe(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then I should be notified that it is in use and cannot be deleted
|
||||
*/
|
||||
public function iShouldBeNotifiedOfFailure()
|
||||
{
|
||||
expect($this->sharedStorage->get('last_exception'))
|
||||
->toBeAnInstanceOf(ForeignKeyConstraintViolationException::class)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^([^"]+) should still exist in the registry$/
|
||||
*/
|
||||
public function couponShouldStillExistInTheRegistry(CouponInterface $coupon)
|
||||
{
|
||||
expect($this->couponRepository->find($coupon->getId()))->toNotBe(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then I should be notified that it has been successfully deleted
|
||||
*/
|
||||
public function iShouldBeNotifiedOfSuccess()
|
||||
{
|
||||
// Not applicable in the domain scope
|
||||
}
|
||||
}
|
||||
|
|
@ -13,6 +13,8 @@ namespace Sylius\Behat\Context\Setup;
|
|||
|
||||
use Behat\Behat\Context\Context;
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use Sylius\Component\Core\Model\CouponInterface;
|
||||
use Sylius\Component\Core\OrderProcessing\OrderRecalculatorInterface;
|
||||
use Sylius\Component\Order\Modifier\OrderItemQuantityModifierInterface;
|
||||
use Sylius\Component\Core\Model\AddressInterface;
|
||||
use Sylius\Component\Core\Model\OrderInterface;
|
||||
|
|
@ -70,9 +72,9 @@ final class OrderContext implements Context
|
|||
private $itemQuantityModifier;
|
||||
|
||||
/**
|
||||
* @var ShippingChargesProcessorInterface
|
||||
* @var OrderRecalculatorInterface
|
||||
*/
|
||||
private $shippingChargesProcessor;
|
||||
private $orderRecalculator;
|
||||
|
||||
/**
|
||||
* @var ObjectManager
|
||||
|
|
@ -87,7 +89,8 @@ final class OrderContext implements Context
|
|||
* @param PaymentFactoryInterface $paymentFactory
|
||||
* @param FactoryInterface $orderItemFactory
|
||||
* @param OrderItemQuantityModifierInterface $itemQuantityModifier
|
||||
* @param ShippingChargesProcessorInterface $shippingChargesProcessor
|
||||
* @param SharedStorageInterface $sharedStorage
|
||||
* @param OrderRecalculatorInterface $orderRecalculator
|
||||
* @param ObjectManager $objectManager
|
||||
*/
|
||||
public function __construct(
|
||||
|
|
@ -98,7 +101,7 @@ final class OrderContext implements Context
|
|||
PaymentFactoryInterface $paymentFactory,
|
||||
FactoryInterface $orderItemFactory,
|
||||
OrderItemQuantityModifierInterface $itemQuantityModifier,
|
||||
ShippingChargesProcessorInterface $shippingChargesProcessor,
|
||||
OrderRecalculatorInterface $orderRecalculator,
|
||||
ObjectManager $objectManager
|
||||
) {
|
||||
$this->sharedStorage = $sharedStorage;
|
||||
|
|
@ -108,7 +111,7 @@ final class OrderContext implements Context
|
|||
$this->paymentFactory = $paymentFactory;
|
||||
$this->orderItemFactory = $orderItemFactory;
|
||||
$this->itemQuantityModifier = $itemQuantityModifier;
|
||||
$this->shippingChargesProcessor = $shippingChargesProcessor;
|
||||
$this->orderRecalculator = $orderRecalculator;
|
||||
$this->objectManager = $objectManager;
|
||||
}
|
||||
|
||||
|
|
@ -144,7 +147,7 @@ final class OrderContext implements Context
|
|||
$this->orderShipmentFactory->processOrderShipment($order);
|
||||
$order->getShipments()->first()->setMethod($shippingMethod);
|
||||
|
||||
$this->shippingChargesProcessor->applyShippingCharges($order);
|
||||
$this->orderRecalculator->recalculate($order);
|
||||
|
||||
$payment = $this->paymentFactory->createWithAmountAndCurrency($order->getTotal(), $order->getCurrency());
|
||||
$payment->setMethod($paymentMethod);
|
||||
|
|
@ -163,6 +166,8 @@ final class OrderContext implements Context
|
|||
public function theCustomerBoughtSingleProduct(ProductInterface $product)
|
||||
{
|
||||
$this->addSingleProductVariantToOrder($product->getMasterVariant(), $product->getPrice());
|
||||
|
||||
$this->objectManager->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -171,15 +176,31 @@ final class OrderContext implements Context
|
|||
public function theCustomerBoughtSingleProductVariant(ProductVariantInterface $productVariant)
|
||||
{
|
||||
$this->addSingleProductVariantToOrder($productVariant, $productVariant->getPrice());
|
||||
|
||||
$this->objectManager->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given the customer bought single :product using :coupon coupon
|
||||
*/
|
||||
public function theCustomerBoughtSingleUsing(ProductInterface $product, CouponInterface $coupon)
|
||||
{
|
||||
$order = $this->addSingleProductVariantToOrder($product->getMasterVariant(), $product->getPrice());
|
||||
$order->setPromotionCoupon($coupon);
|
||||
|
||||
$this->orderRecalculator->recalculate($order);
|
||||
|
||||
$this->objectManager->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ProductVariantInterface $productVariant
|
||||
* @param int $price
|
||||
*
|
||||
* @return OrderInterface
|
||||
*/
|
||||
private function addSingleProductVariantToOrder(ProductVariantInterface $productVariant, $price)
|
||||
{
|
||||
/** @var OrderInterface $order */
|
||||
$order = $this->sharedStorage->get('order');
|
||||
|
||||
/** @var OrderItemInterface $item */
|
||||
|
|
@ -191,6 +212,8 @@ final class OrderContext implements Context
|
|||
|
||||
$order->addItem($item);
|
||||
|
||||
$this->objectManager->flush();
|
||||
$this->orderRecalculator->recalculate($order);
|
||||
|
||||
return $order;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ use Sylius\Component\Core\Model\TaxonInterface;
|
|||
use Sylius\Component\Core\Test\Factory\TestPromotionFactoryInterface;
|
||||
use Sylius\Component\Core\Test\Services\SharedStorageInterface;
|
||||
use Sylius\Component\Promotion\Model\ActionInterface;
|
||||
use Sylius\Component\Promotion\Factory\CouponFactoryInterface;
|
||||
use Sylius\Component\Promotion\Model\CouponInterface;
|
||||
use Sylius\Component\Promotion\Repository\PromotionRepositoryInterface;
|
||||
|
||||
/**
|
||||
|
|
@ -37,6 +39,11 @@ final class PromotionContext implements Context
|
|||
*/
|
||||
private $actionFactory;
|
||||
|
||||
/**
|
||||
* @var CouponFactoryInterface
|
||||
*/
|
||||
private $couponFactory;
|
||||
|
||||
/**
|
||||
* @var RuleFactoryInterface
|
||||
*/
|
||||
|
|
@ -60,6 +67,7 @@ final class PromotionContext implements Context
|
|||
/**
|
||||
* @param SharedStorageInterface $sharedStorage
|
||||
* @param ActionFactoryInterface $actionFactory
|
||||
* @param CouponFactoryInterface $couponFactory
|
||||
* @param RuleFactoryInterface $ruleFactory
|
||||
* @param TestPromotionFactoryInterface $testPromotionFactory
|
||||
* @param PromotionRepositoryInterface $promotionRepository
|
||||
|
|
@ -68,6 +76,7 @@ final class PromotionContext implements Context
|
|||
public function __construct(
|
||||
SharedStorageInterface $sharedStorage,
|
||||
ActionFactoryInterface $actionFactory,
|
||||
CouponFactoryInterface $couponFactory,
|
||||
RuleFactoryInterface $ruleFactory,
|
||||
TestPromotionFactoryInterface $testPromotionFactory,
|
||||
PromotionRepositoryInterface $promotionRepository,
|
||||
|
|
@ -75,6 +84,7 @@ final class PromotionContext implements Context
|
|||
) {
|
||||
$this->sharedStorage = $sharedStorage;
|
||||
$this->actionFactory = $actionFactory;
|
||||
$this->couponFactory = $couponFactory;
|
||||
$this->ruleFactory = $ruleFactory;
|
||||
$this->testPromotionFactory = $testPromotionFactory;
|
||||
$this->promotionRepository = $promotionRepository;
|
||||
|
|
@ -94,6 +104,26 @@ final class PromotionContext implements Context
|
|||
$this->sharedStorage->set('promotion', $promotion);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given the store has promotion :promotionName with coupon :couponCode
|
||||
*/
|
||||
public function thereIsPromotionWithCoupon($promotionName, $couponCode)
|
||||
{
|
||||
/** @var CouponInterface $coupon */
|
||||
$coupon = $this->couponFactory->createNew();
|
||||
$coupon->setCode($couponCode);
|
||||
|
||||
$promotion = $this->testPromotionFactory
|
||||
->createForChannel($promotionName, $this->sharedStorage->get('channel'))
|
||||
;
|
||||
$promotion->addCoupon($coupon);
|
||||
$promotion->setCouponBased(true);
|
||||
|
||||
$this->promotionRepository->add($promotion);
|
||||
$this->sharedStorage->set('promotion', $promotion);
|
||||
$this->sharedStorage->set('coupon', $coupon);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given /^([^"]+) gives ("[^"]+") fixed discount to every order$/
|
||||
*/
|
||||
|
|
|
|||
78
src/Sylius/Behat/Context/Transform/PromotionContext.php
Normal file
78
src/Sylius/Behat/Context/Transform/PromotionContext.php
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Behat\Context\Transform;
|
||||
|
||||
use Behat\Behat\Context\Context;
|
||||
use Sylius\Component\Promotion\Repository\PromotionRepositoryInterface;
|
||||
use Sylius\Component\Resource\Repository\RepositoryInterface;
|
||||
|
||||
/**
|
||||
* @author Jan Góralski <jan.goralski@lakion.com>
|
||||
*/
|
||||
final class PromotionContext implements Context
|
||||
{
|
||||
/**
|
||||
* @var PromotionRepositoryInterface
|
||||
*/
|
||||
private $promotionRepository;
|
||||
|
||||
/**
|
||||
* @var RepositoryInterface
|
||||
*/
|
||||
private $couponRepository;
|
||||
|
||||
/**
|
||||
* @param PromotionRepositoryInterface $promotionRepository
|
||||
* @param RepositoryInterface $couponRepository
|
||||
*/
|
||||
public function __construct(
|
||||
PromotionRepositoryInterface $promotionRepository,
|
||||
RepositoryInterface $couponRepository
|
||||
) {
|
||||
$this->promotionRepository = $promotionRepository;
|
||||
$this->couponRepository = $couponRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Transform /^promotion "([^"]+)"$/
|
||||
* @Transform /^"([^"]+)" promotion$/
|
||||
* @Transform :promotion
|
||||
*/
|
||||
public function getPromotionByName($promotionName)
|
||||
{
|
||||
$promotion = $this->promotionRepository->findOneBy(['name' => $promotionName]);
|
||||
if (null === $promotion) {
|
||||
throw new \InvalidArgumentException(
|
||||
sprintf('Promotion with name "%s" does not exist in the promotion repository.', $promotionName)
|
||||
);
|
||||
}
|
||||
|
||||
return $promotion;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Transform /^coupon "([^"]+)"$/
|
||||
* @Transform /^"([^"]+)" coupon$/
|
||||
* @Transform :coupon
|
||||
*/
|
||||
public function getCouponByCode($couponCode)
|
||||
{
|
||||
$coupon = $this->couponRepository->findOneBy(['code' => $couponCode]);
|
||||
if (null === $coupon) {
|
||||
throw new \InvalidArgumentException(
|
||||
sprintf('Coupon with code "%s" does not exist in the coupon repository.', $couponCode)
|
||||
);
|
||||
}
|
||||
|
||||
return $coupon;
|
||||
}
|
||||
}
|
||||
|
|
@ -40,6 +40,14 @@ final class SharedStorageContext implements Context
|
|||
return $this->sharedStorage->getLatestResource();
|
||||
}
|
||||
|
||||
/**
|
||||
* @Transform /^(?:this|that|the) ([^"]+) should no longer$/
|
||||
*/
|
||||
public function getResourceId($resource)
|
||||
{
|
||||
return $this->sharedStorage->get(sprintf('%s_id', $resource));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Transform /^(?:this|that|the) ([^"]+)$/
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -12,8 +12,6 @@
|
|||
namespace spec\Sylius\Behat\Context\Domain;
|
||||
|
||||
use Behat\Behat\Context\Context;
|
||||
use Behat\Mink\Exception\ExpectationException;
|
||||
use Behat\Mink\Tests\Exception\ExpectationExceptionTest;
|
||||
use PhpSpec\Exception\Example\NotEqualException;
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Prophecy\Argument;
|
||||
|
|
|
|||
144
src/Sylius/Behat/spec/Context/Domain/PromotionContextSpec.php
Normal file
144
src/Sylius/Behat/spec/Context/Domain/PromotionContextSpec.php
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace spec\Sylius\Behat\Context\Domain;
|
||||
|
||||
use Behat\Behat\Context\Context;
|
||||
use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
|
||||
use PhpSpec\Exception\Example\FailureException;
|
||||
use PhpSpec\Exception\Example\NotEqualException;
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Prophecy\Argument;
|
||||
use Sylius\Behat\Context\Domain\PromotionContext;
|
||||
use Sylius\Component\Core\Repository\PromotionRepositoryInterface;
|
||||
use Sylius\Component\Core\Test\Services\SharedStorageInterface;
|
||||
use Sylius\Component\Promotion\Model\CouponInterface;
|
||||
use Sylius\Component\Resource\Repository\RepositoryInterface;
|
||||
|
||||
/**
|
||||
* @mixin PromotionContext
|
||||
*
|
||||
* @author Jan Góralski <jan.goralski@lakion.com>
|
||||
*/
|
||||
class PromotionContextSpec extends ObjectBehavior
|
||||
{
|
||||
function let(
|
||||
SharedStorageInterface $sharedStorage,
|
||||
PromotionRepositoryInterface $promotionRepository,
|
||||
RepositoryInterface $couponRepository
|
||||
) {
|
||||
$this->beConstructedWith($sharedStorage, $promotionRepository, $couponRepository);
|
||||
}
|
||||
|
||||
function it_is_initializable()
|
||||
{
|
||||
$this->shouldHaveType('Sylius\Behat\Context\Domain\PromotionContext');
|
||||
}
|
||||
|
||||
function it_implements_context_interface()
|
||||
{
|
||||
$this->shouldImplement(Context::class);
|
||||
}
|
||||
|
||||
function it_removes_a_coupon(
|
||||
SharedStorageInterface $sharedStorage,
|
||||
RepositoryInterface $couponRepository,
|
||||
CouponInterface $coupon
|
||||
) {
|
||||
$coupon->getId()->willReturn(5);
|
||||
$sharedStorage->set('coupon_id', 5)->shouldBeCalled();
|
||||
$couponRepository->remove($coupon)->shouldBeCalled();
|
||||
|
||||
$this->iDeleteCoupon($coupon);
|
||||
}
|
||||
|
||||
function it_throws_exception_when_there_was_a_problem_with_removing_a_coupon(
|
||||
SharedStorageInterface $sharedStorage,
|
||||
RepositoryInterface $couponRepository,
|
||||
CouponInterface $coupon
|
||||
) {
|
||||
$coupon->getId()->willReturn(5);
|
||||
$sharedStorage->set('coupon_id', 5)->shouldBeCalled();
|
||||
$couponRepository->remove($coupon)->willThrow(ForeignKeyConstraintViolationException::class);
|
||||
|
||||
$this->shouldThrow(ForeignKeyConstraintViolationException::class)->during('iDeleteCoupon', [$coupon]);
|
||||
}
|
||||
|
||||
function it_tries_to_remove_a_coupon_and_catches_exception_in_case_of_failure(
|
||||
SharedStorageInterface $sharedStorage,
|
||||
RepositoryInterface $couponRepository,
|
||||
CouponInterface $coupon
|
||||
) {
|
||||
$coupon->getId()->willReturn(5);
|
||||
$couponRepository->remove($coupon)->willThrow(ForeignKeyConstraintViolationException::class);
|
||||
$sharedStorage->set('last_exception', Argument::type(ForeignKeyConstraintViolationException::class))->shouldBeCalled();
|
||||
|
||||
$this->iTryToDeleteCoupon($coupon);
|
||||
}
|
||||
|
||||
function it_throws_exception_while_trying_to_remove_a_coupon_and_actually_removing_it(
|
||||
SharedStorageInterface $sharedStorage,
|
||||
RepositoryInterface $couponRepository,
|
||||
CouponInterface $coupon
|
||||
) {
|
||||
$coupon->getId()->willReturn(5);
|
||||
$couponRepository->remove($coupon)->shouldBeCalled();
|
||||
$sharedStorage->set('last_exception', Argument::any())->shouldNotBeCalled();
|
||||
|
||||
$this->shouldThrow(\Exception::class)->during('iTryToDeleteCoupon', [$coupon]);
|
||||
}
|
||||
|
||||
function it_checks_whether_a_coupon_is_not_in_the_registry(
|
||||
RepositoryInterface $couponRepository
|
||||
) {
|
||||
$couponRepository->find(5)->willReturn(null);
|
||||
|
||||
$this->couponShouldNotExistInTheRegistry(5);
|
||||
}
|
||||
|
||||
function it_throws_exception_when_a_coupon_is_found_but_it_should_not_exist(
|
||||
SharedStorageInterface $sharedStorage,
|
||||
RepositoryInterface $couponRepository,
|
||||
CouponInterface $coupon
|
||||
) {
|
||||
$coupon->getId()->willReturn(5);
|
||||
$sharedStorage->get('coupon_id')->willReturn(5);
|
||||
$couponRepository->find(5)->willReturn($coupon);
|
||||
|
||||
$this
|
||||
->shouldThrow(NotEqualException::class)
|
||||
->during('couponShouldNotExistInTheRegistry', [5])
|
||||
;
|
||||
}
|
||||
|
||||
function it_checks_whether_a_coupon_is_in_the_registry(
|
||||
RepositoryInterface $couponRepository,
|
||||
CouponInterface $coupon
|
||||
) {
|
||||
$coupon->getId()->willReturn(5);
|
||||
$couponRepository->find(5)->willReturn($coupon);
|
||||
|
||||
$this->couponShouldStillExistInTheRegistry($coupon);
|
||||
}
|
||||
|
||||
function it_throws_exception_when_a_coupon_is_not_found_but_it_should_exist(
|
||||
RepositoryInterface $couponRepository,
|
||||
CouponInterface $coupon
|
||||
) {
|
||||
$coupon->getId()->willReturn(5);
|
||||
$couponRepository->find(5)->willReturn(null);
|
||||
|
||||
$this
|
||||
->shouldThrow(FailureException::class)
|
||||
->during('couponShouldStillExistInTheRegistry', [$coupon])
|
||||
;
|
||||
}
|
||||
}
|
||||
|
|
@ -15,10 +15,12 @@ use Behat\Behat\Context\Context;
|
|||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Sylius\Component\Core\OrderProcessing\OrderRecalculatorInterface;
|
||||
use Sylius\Component\Order\Modifier\OrderItemQuantityModifierInterface;
|
||||
use Sylius\Behat\Context\Setup\OrderContext;
|
||||
use Sylius\Component\Core\Model\AddressInterface;
|
||||
use Sylius\Component\Core\Model\ChannelInterface;
|
||||
use Sylius\Component\Core\Model\CouponInterface;
|
||||
use Sylius\Component\Core\Model\CustomerInterface;
|
||||
use Sylius\Component\Core\Model\OrderInterface;
|
||||
use Sylius\Component\Core\Model\OrderItemInterface;
|
||||
|
|
@ -28,7 +30,6 @@ use Sylius\Component\Core\Model\ProductVariantInterface;
|
|||
use Sylius\Component\Core\Model\ShipmentInterface;
|
||||
use Sylius\Component\Core\Model\ShippingMethodInterface;
|
||||
use Sylius\Component\Core\OrderProcessing\OrderShipmentProcessorInterface;
|
||||
use Sylius\Component\Core\OrderProcessing\ShippingChargesProcessorInterface;
|
||||
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
|
||||
use Sylius\Component\Core\Test\Services\SharedStorageInterface;
|
||||
use Sylius\Component\Currency\Model\CurrencyInterface;
|
||||
|
|
@ -51,7 +52,7 @@ class OrderContextSpec extends ObjectBehavior
|
|||
PaymentFactoryInterface $paymentFactory,
|
||||
FactoryInterface $orderItemFactory,
|
||||
OrderItemQuantityModifierInterface $itemQuantityModifier,
|
||||
ShippingChargesProcessorInterface $chargesProcessor,
|
||||
OrderRecalculatorInterface $orderRecalculator,
|
||||
ObjectManager $objectManager
|
||||
) {
|
||||
$this->beConstructedWith(
|
||||
|
|
@ -62,7 +63,7 @@ class OrderContextSpec extends ObjectBehavior
|
|||
$paymentFactory,
|
||||
$orderItemFactory,
|
||||
$itemQuantityModifier,
|
||||
$chargesProcessor,
|
||||
$orderRecalculator,
|
||||
$objectManager
|
||||
);
|
||||
}
|
||||
|
|
@ -112,7 +113,7 @@ class OrderContextSpec extends ObjectBehavior
|
|||
PaymentMethodInterface $paymentMethod,
|
||||
SharedStorageInterface $sharedStorage,
|
||||
ShipmentInterface $shipment,
|
||||
ShippingChargesProcessorInterface $chargesProcessor,
|
||||
OrderRecalculatorInterface $orderRecalculator,
|
||||
ShippingMethodInterface $shippingMethod,
|
||||
ObjectManager $objectManager
|
||||
) {
|
||||
|
|
@ -135,7 +136,7 @@ class OrderContextSpec extends ObjectBehavior
|
|||
|
||||
$objectManager->flush()->shouldBeCalled();
|
||||
|
||||
$chargesProcessor->applyShippingCharges($order)->shouldBeCalled();
|
||||
$orderRecalculator->recalculate($order)->shouldBeCalled();
|
||||
|
||||
$this->theCustomerChoseShippingToWithPayment($shippingMethod, $address, $paymentMethod);
|
||||
}
|
||||
|
|
@ -185,4 +186,37 @@ class OrderContextSpec extends ObjectBehavior
|
|||
|
||||
$this->theCustomerBoughtSingleProductVariant($variant);
|
||||
}
|
||||
|
||||
function it_adds_single_item_by_customer_and_applies_a_coupon(
|
||||
FactoryInterface $orderItemFactory,
|
||||
OrderInterface $order,
|
||||
OrderItemInterface $item,
|
||||
OrderItemQuantityModifierInterface $itemQuantityModifier,
|
||||
ProductInterface $product,
|
||||
CouponInterface $coupon,
|
||||
SharedStorageInterface $sharedStorage,
|
||||
ProductVariantInterface $variant,
|
||||
OrderRecalculatorInterface $orderRecalculator,
|
||||
ObjectManager $objectManager
|
||||
) {
|
||||
$sharedStorage->get('order')->willReturn($order);
|
||||
|
||||
$orderItemFactory->createNew()->willReturn($item);
|
||||
|
||||
$product->getMasterVariant()->willReturn($variant);
|
||||
$product->getPrice()->willReturn(1234);
|
||||
|
||||
$itemQuantityModifier->modify($item, 1)->shouldBeCalled();
|
||||
|
||||
$item->setVariant($variant)->shouldBeCalled();
|
||||
$item->setUnitPrice(1234)->shouldBeCalled();
|
||||
|
||||
$order->setPromotionCoupon($coupon)->shouldBeCalled();
|
||||
$order->addItem($item)->shouldBeCalled();
|
||||
|
||||
$orderRecalculator->recalculate($order)->shouldBeCalled();
|
||||
$objectManager->flush()->shouldBeCalled();
|
||||
|
||||
$this->theCustomerBoughtSingleUsing($product, $coupon);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,18 +14,23 @@ namespace spec\Sylius\Behat\Context\Setup;
|
|||
use Behat\Behat\Context\Context;
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Sylius\Behat\Context\Setup\PromotionContext;
|
||||
use Sylius\Component\Core\Factory\ActionFactoryInterface;
|
||||
use Sylius\Component\Core\Factory\RuleFactoryInterface;
|
||||
use Sylius\Component\Core\Model\ChannelInterface;
|
||||
use Sylius\Component\Core\Model\CouponInterface;
|
||||
use Sylius\Component\Core\Model\PromotionInterface;
|
||||
use Sylius\Component\Core\Model\TaxonInterface;
|
||||
use Sylius\Component\Core\Test\Factory\TestPromotionFactoryInterface;
|
||||
use Sylius\Component\Core\Test\Services\SharedStorageInterface;
|
||||
use Sylius\Component\Promotion\Factory\CouponFactoryInterface;
|
||||
use Sylius\Component\Promotion\Model\ActionInterface;
|
||||
use Sylius\Component\Promotion\Model\RuleInterface;
|
||||
use Sylius\Component\Promotion\Repository\PromotionRepositoryInterface;
|
||||
|
||||
/**
|
||||
* @mixin PromotionContext
|
||||
*
|
||||
* @author Mateusz Zalewski <mateusz.zalewski@lakion.com>
|
||||
*/
|
||||
class PromotionContextSpec extends ObjectBehavior
|
||||
|
|
@ -33,6 +38,7 @@ class PromotionContextSpec extends ObjectBehavior
|
|||
function let(
|
||||
SharedStorageInterface $sharedStorage,
|
||||
ActionFactoryInterface $actionFactory,
|
||||
CouponFactoryInterface $couponFactory,
|
||||
RuleFactoryInterface $ruleFactory,
|
||||
TestPromotionFactoryInterface $testPromotionFactory,
|
||||
PromotionRepositoryInterface $promotionRepository,
|
||||
|
|
@ -41,6 +47,7 @@ class PromotionContextSpec extends ObjectBehavior
|
|||
$this->beConstructedWith(
|
||||
$sharedStorage,
|
||||
$actionFactory,
|
||||
$couponFactory,
|
||||
$ruleFactory,
|
||||
$testPromotionFactory,
|
||||
$promotionRepository,
|
||||
|
|
@ -75,6 +82,30 @@ class PromotionContextSpec extends ObjectBehavior
|
|||
$this->thereIsPromotion('Super promotion');
|
||||
}
|
||||
|
||||
function it_creates_promotion_with_coupon(
|
||||
SharedStorageInterface $sharedStorage,
|
||||
CouponFactoryInterface $couponFactory,
|
||||
TestPromotionFactoryInterface $testPromotionFactory,
|
||||
PromotionRepositoryInterface $promotionRepository,
|
||||
ChannelInterface $channel,
|
||||
CouponInterface $coupon,
|
||||
PromotionInterface $promotion
|
||||
) {
|
||||
$couponFactory->createNew()->willReturn($coupon);
|
||||
$coupon->setCode('Coupon galore')->shouldBeCalled();
|
||||
|
||||
$sharedStorage->get('channel')->willReturn($channel);
|
||||
$testPromotionFactory->createForChannel('Promotion galore', $channel)->willReturn($promotion);
|
||||
$promotion->addCoupon($coupon)->shouldBeCalled();
|
||||
$promotion->setCouponBased(true)->shouldBeCalled();
|
||||
|
||||
$promotionRepository->add($promotion)->shouldBeCalled();
|
||||
$sharedStorage->set('promotion', $promotion)->shouldBeCalled();
|
||||
$sharedStorage->set('coupon', $coupon)->shouldBeCalled();
|
||||
|
||||
$this->thereIsPromotionWithCoupon('Promotion galore', 'Coupon galore');
|
||||
}
|
||||
|
||||
function it_creates_fixed_discount_action_for_promotion(
|
||||
ActionFactoryInterface $actionFactory,
|
||||
ActionInterface $action,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace spec\Sylius\Behat\Context\Transform;
|
||||
|
||||
use Behat\Behat\Context\Context;
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Prophecy\Argument;
|
||||
use Sylius\Behat\Context\Transform\PromotionContext;
|
||||
use Sylius\Component\Promotion\Model\CouponInterface;
|
||||
use Sylius\Component\Promotion\Model\PromotionInterface;
|
||||
use Sylius\Component\Promotion\Repository\PromotionRepositoryInterface;
|
||||
use Sylius\Component\Resource\Repository\RepositoryInterface;
|
||||
|
||||
/**
|
||||
* @mixin PromotionContext
|
||||
*
|
||||
* @author Jan Góralski <jan.goralski@lakion.com>
|
||||
*/
|
||||
class PromotionContextSpec extends ObjectBehavior
|
||||
{
|
||||
function let(PromotionRepositoryInterface $promotionRepository, RepositoryInterface $couponRepository)
|
||||
{
|
||||
$this->beConstructedWith($promotionRepository, $couponRepository);
|
||||
}
|
||||
|
||||
function it_is_initializable()
|
||||
{
|
||||
$this->shouldHaveType('Sylius\Behat\Context\Transform\PromotionContext');
|
||||
}
|
||||
|
||||
function it_implements_context_interface()
|
||||
{
|
||||
$this->shouldImplement(Context::class);
|
||||
}
|
||||
|
||||
function it_gets_promotion_by_its_name(
|
||||
PromotionRepositoryInterface $promotionRepository,
|
||||
PromotionInterface $promotion
|
||||
) {
|
||||
$promotion->getName()->willReturn('Best Promotion');
|
||||
$promotionRepository->findOneBy(['name' => 'Best Promotion'])->willReturn($promotion);
|
||||
|
||||
$this->getPromotionByName('Best Promotion');
|
||||
}
|
||||
|
||||
function it_throws_exception_when_promotion_with_given_name_was_not_found(
|
||||
PromotionRepositoryInterface $promotionRepository
|
||||
) {
|
||||
$promotionRepository->findOneBy(['name' => 'Wrong Promotion'])->willReturn(null);
|
||||
|
||||
$this->shouldThrow(\InvalidArgumentException::class)->during('getPromotionByName', ['Wrong Promotion']);
|
||||
}
|
||||
|
||||
function it_gets_coupon_by_its_code(RepositoryInterface $couponRepository, CouponInterface $coupon)
|
||||
{
|
||||
$coupon->getCode()->willReturn('BEST-CODE');
|
||||
$couponRepository->findOneBy(['code' => 'BEST-CODE'])->willReturn($coupon);
|
||||
|
||||
$this->getCouponByCode('BEST-CODE');
|
||||
}
|
||||
|
||||
function it_throws_exception_when_coupon_with_given_code_was_not_found(RepositoryInterface $couponRepository)
|
||||
{
|
||||
$couponRepository->findOneBy(['code' => 'NO-CODE'])->willReturn(null);
|
||||
|
||||
$this->shouldThrow(\InvalidArgumentException::class)->during('getCouponByCode', ['NO-CODE']);
|
||||
}
|
||||
}
|
||||
|
|
@ -13,10 +13,13 @@ namespace spec\Sylius\Behat\Context\Transform;
|
|||
|
||||
use Behat\Behat\Context\Context;
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Sylius\Behat\Context\Transform\SharedStorageContext;
|
||||
use Sylius\Component\Core\Model\CustomerInterface;
|
||||
use Sylius\Component\Core\Test\Services\SharedStorageInterface;
|
||||
|
||||
/**
|
||||
* @mixin SharedStorageContext
|
||||
*
|
||||
* @author Mateusz Zalewski <mateusz.zalewski@lakion.com>
|
||||
*/
|
||||
class SharedStorageContextSpec extends ObjectBehavior
|
||||
|
|
@ -43,7 +46,7 @@ class SharedStorageContextSpec extends ObjectBehavior
|
|||
$this->getLatestResource()->shouldReturn('string');
|
||||
}
|
||||
|
||||
function it_transform_this_that_and_the_with_resource_name_to_current_resource_of_this_type(
|
||||
function it_transforms_this_that_and_the_with_resource_name_to_current_resource_of_this_type(
|
||||
$sharedStorage,
|
||||
CustomerInterface $customer
|
||||
) {
|
||||
|
|
@ -51,4 +54,12 @@ class SharedStorageContextSpec extends ObjectBehavior
|
|||
|
||||
$this->getResource('customer')->shouldReturn($customer);
|
||||
}
|
||||
|
||||
function it_transforms_this_that_and_the_should_no_longer_with_resource_name_to_current_id_set_for_that_resource(
|
||||
SharedStorageInterface $sharedStorage
|
||||
) {
|
||||
$sharedStorage->get('customer_id')->willReturn(5);
|
||||
|
||||
$this->getResourceId('customer')->shouldReturn(5);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
</one-to-one>
|
||||
|
||||
<many-to-one field="promotionCoupon" target-entity="Sylius\Component\Promotion\Model\CouponInterface">
|
||||
<join-column name="promotion_coupon_id" on-delete="SET NULL" />
|
||||
<join-column name="promotion_coupon_id" />
|
||||
<cascade>
|
||||
<cascade-persist />
|
||||
</cascade>
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
<parameter key="sylius.order_processing.shipment_processor.class">Sylius\Component\Core\OrderProcessing\OrderShipmentProcessor</parameter>
|
||||
<parameter key="sylius.order_processing.payment_processor.class">Sylius\Component\Core\OrderProcessing\PaymentProcessor</parameter>
|
||||
<parameter key="sylius.order_processing.shipping_processor.class">Sylius\Component\Core\OrderProcessing\ShippingChargesProcessor</parameter>
|
||||
<parameter key="sylius.order_processing.order_recalculator.class">Sylius\Component\Core\OrderProcessing\OrderRecalculator</parameter>
|
||||
|
||||
<parameter key="sylius.taxation.order_taxes_applicator.class">Sylius\Component\Core\Taxation\OrderTaxesApplicator</parameter>
|
||||
<parameter key="sylius.taxation.order_shipment_taxes_by_zone_applicator.class">Sylius\Component\Core\Taxation\OrderShipmentTaxesByZoneApplicator</parameter>
|
||||
|
|
@ -261,6 +262,12 @@
|
|||
<argument type="service" id="sylius.shipping_calculator" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.order_processing.order_recalculator" class="%sylius.order_processing.order_recalculator.class%">
|
||||
<argument type="service" id="sylius.promotion_processor" />
|
||||
<argument type="service" id="sylius.taxation.order_taxes_applicator" />
|
||||
<argument type="service" id="sylius.order_processing.shipping_processor" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.order.purger" class="%sylius.order.purger.class%">
|
||||
<argument type="service" id="sylius.manager.order" />
|
||||
<argument type="service" id="sylius.repository.order" />
|
||||
|
|
|
|||
|
|
@ -34,9 +34,6 @@
|
|||
<field name="updatedAt" column="updated_at" type="datetime" nullable="true">
|
||||
<gedmo:timestampable on="update"/>
|
||||
</field>
|
||||
<field name="deletedAt" column="deleted_at" type="datetime" nullable="true" />
|
||||
|
||||
<gedmo:soft-deleteable field-name="deletedAt" />
|
||||
</mapped-superclass>
|
||||
|
||||
</doctrine-mapping>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Component\Core\OrderProcessing;
|
||||
|
||||
use Sylius\Component\Core\Model\OrderInterface;
|
||||
use Sylius\Component\Core\Taxation\OrderTaxesApplicatorInterface;
|
||||
use Sylius\Component\Promotion\Processor\PromotionProcessorInterface;
|
||||
|
||||
/**
|
||||
* @author Jan Góralski <jan.goralski@lakion.com>
|
||||
*/
|
||||
class OrderRecalculator implements OrderRecalculatorInterface
|
||||
{
|
||||
/**
|
||||
* @var PromotionProcessorInterface
|
||||
*/
|
||||
private $promotionProcessor;
|
||||
|
||||
/**
|
||||
* @var OrderTaxesApplicatorInterface
|
||||
*/
|
||||
private $taxesApplicator;
|
||||
|
||||
/**
|
||||
* @var ShippingChargesProcessorInterface
|
||||
*/
|
||||
private $shippingChargesProcessor;
|
||||
|
||||
/**
|
||||
* @param PromotionProcessorInterface $promotionProcessor
|
||||
* @param OrderTaxesApplicatorInterface $taxesApplicator
|
||||
* @param ShippingChargesProcessorInterface $shippingChargesProcessor
|
||||
*/
|
||||
public function __construct(
|
||||
PromotionProcessorInterface $promotionProcessor,
|
||||
OrderTaxesApplicatorInterface $taxesApplicator,
|
||||
ShippingChargesProcessorInterface $shippingChargesProcessor
|
||||
) {
|
||||
$this->promotionProcessor = $promotionProcessor;
|
||||
$this->taxesApplicator = $taxesApplicator;
|
||||
$this->shippingChargesProcessor = $shippingChargesProcessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param OrderInterface $order
|
||||
*
|
||||
* @return OrderInterface
|
||||
*/
|
||||
public function recalculate(OrderInterface $order)
|
||||
{
|
||||
$this->promotionProcessor->process($order);
|
||||
$this->taxesApplicator->apply($order);
|
||||
$this->shippingChargesProcessor->applyShippingCharges($order);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Component\Core\OrderProcessing;
|
||||
|
||||
use Sylius\Component\Core\Model\OrderInterface;
|
||||
|
||||
/**
|
||||
* @author Jan Góralski <jan.goralski@lakion.com>
|
||||
*/
|
||||
interface OrderRecalculatorInterface
|
||||
{
|
||||
/**
|
||||
* @param OrderInterface $order
|
||||
*
|
||||
* @return OrderInterface
|
||||
*/
|
||||
public function recalculate(OrderInterface $order);
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace spec\Sylius\Component\Core\OrderProcessing;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Sylius\Component\Core\Model\OrderInterface;
|
||||
use Sylius\Component\Core\OrderProcessing\OrderRecalculator;
|
||||
use Sylius\Component\Core\OrderProcessing\OrderRecalculatorInterface;
|
||||
use Sylius\Component\Core\OrderProcessing\ShippingChargesProcessorInterface;
|
||||
use Sylius\Component\Core\Taxation\OrderTaxesApplicatorInterface;
|
||||
use Sylius\Component\Promotion\Processor\PromotionProcessorInterface;
|
||||
|
||||
/**
|
||||
* @mixin OrderRecalculator
|
||||
*
|
||||
* @author Jan Góralski <jan.goralski@lakion.com>
|
||||
*/
|
||||
class OrderRecalculatorSpec extends ObjectBehavior
|
||||
{
|
||||
function let(
|
||||
PromotionProcessorInterface $promotionProcessor,
|
||||
OrderTaxesApplicatorInterface $taxesApplicator,
|
||||
ShippingChargesProcessorInterface $shippingChargesProcessor
|
||||
) {
|
||||
$this->beConstructedWith($promotionProcessor, $taxesApplicator, $shippingChargesProcessor);
|
||||
}
|
||||
|
||||
function it_is_initializable()
|
||||
{
|
||||
$this->shouldHaveType('Sylius\Component\Core\OrderProcessing\OrderRecalculator');
|
||||
}
|
||||
|
||||
function it_implements_order_recalculator_interface()
|
||||
{
|
||||
$this->shouldImplement(OrderRecalculatorInterface::class);
|
||||
}
|
||||
|
||||
function it_recalculates_order_promotions_taxes_and_shipping_charges(
|
||||
PromotionProcessorInterface $promotionProcessor,
|
||||
OrderTaxesApplicatorInterface $taxesApplicator,
|
||||
ShippingChargesProcessorInterface $shippingChargesProcessor,
|
||||
OrderInterface $order
|
||||
) {
|
||||
$promotionProcessor->process($order)->shouldBeCalled();
|
||||
$taxesApplicator->apply($order)->shouldBeCalled();
|
||||
$shippingChargesProcessor->applyShippingCharges($order)->shouldBeCalled();
|
||||
|
||||
$this->recalculate($order);
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
namespace Sylius\Component\Promotion\Factory;
|
||||
|
||||
use Sylius\Component\Promotion\Model\CouponInterface;
|
||||
use Sylius\Component\Resource\Factory\FactoryInterface;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@
|
|||
|
||||
namespace Sylius\Component\Promotion\Model;
|
||||
|
||||
use Sylius\Component\Resource\Model\SoftDeletableTrait;
|
||||
use Sylius\Component\Resource\Model\TimestampableTrait;
|
||||
|
||||
/**
|
||||
|
|
@ -19,7 +18,7 @@ use Sylius\Component\Resource\Model\TimestampableTrait;
|
|||
*/
|
||||
class Coupon implements CouponInterface
|
||||
{
|
||||
use SoftDeletableTrait, TimestampableTrait;
|
||||
use TimestampableTrait;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
|
|
|
|||
|
|
@ -13,13 +13,12 @@ namespace Sylius\Component\Promotion\Model;
|
|||
|
||||
use Sylius\Component\Resource\Model\CodeAwareInterface;
|
||||
use Sylius\Component\Resource\Model\ResourceInterface;
|
||||
use Sylius\Component\Resource\Model\SoftDeletableInterface;
|
||||
use Sylius\Component\Resource\Model\TimestampableInterface;
|
||||
|
||||
/**
|
||||
* @author Saša Stamenković <umpirsky@gmail.com>
|
||||
*/
|
||||
interface CouponInterface extends CodeAwareInterface, SoftDeletableInterface, TimestampableInterface, ResourceInterface
|
||||
interface CouponInterface extends CodeAwareInterface, TimestampableInterface, ResourceInterface
|
||||
{
|
||||
/**
|
||||
* @return int
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue