From 9fcf971bd1c1510f6a44046b08b7576c8a54f242 Mon Sep 17 00:00:00 2001 From: Roshyo Date: Fri, 11 Mar 2022 08:27:25 +0100 Subject: [PATCH] WIP: Use the same input for Coupon code and GiftCard --- composer.json | 3 +- src/Applicator/GiftCardApplicator.php | 17 ++----- .../GiftCardApplicatorInterface.php | 14 +----- .../GiftCardOrPromotionApplicator.php | 49 +++++++++++++++++++ ...GiftCardOrPromotionApplicatorInterface.php | 12 +++++ src/Applicator/PromotionApplicator.php | 29 +++++++++++ ...> AddGiftCardOrPromotionToOrderAction.php} | 25 +++++----- .../AddGiftCardOrPromotionToOrderCommand.php | 20 ++++++++ .../Action/AddGiftCardToOrderCommand.php | 22 --------- ...sterGiftCardOrPromotionApplicatorsPass.php | 34 +++++++++++++ .../Compiler/UseSameInputPass.php | 25 ++++++++++ src/DependencyInjection/Configuration.php | 7 +++ .../SetonoSyliusGiftCardExtension.php | 10 ++++ src/Exception/GiftCardNotFoundException.php | 1 + .../PromotionCouponNotFoundException.php | 26 ++++++++++ src/Form/Extension/CartTypeExtension.php | 31 ++++++++++++ ... => AddGiftCardOrPromotionToOrderType.php} | 18 +++---- src/Resources/config/services/applicator.xml | 12 +++++ src/Resources/config/services/controller.xml | 4 +- src/Resources/config/services/form.xml | 16 +++++- ... AddGiftCardOrPromotionToOrderCommand.xml} | 7 +-- .../views/Shop/addGiftCardToOrder.html.twig | 4 +- src/SetonoSyliusGiftCardPlugin.php | 4 ++ .../packages/setono_sylius_gift_card.yaml | 4 ++ 24 files changed, 310 insertions(+), 84 deletions(-) create mode 100644 src/Applicator/GiftCardOrPromotionApplicator.php create mode 100644 src/Applicator/GiftCardOrPromotionApplicatorInterface.php create mode 100644 src/Applicator/PromotionApplicator.php rename src/Controller/Action/{AddGiftCardToOrderAction.php => AddGiftCardOrPromotionToOrderAction.php} (70%) create mode 100644 src/Controller/Action/AddGiftCardOrPromotionToOrderCommand.php delete mode 100644 src/Controller/Action/AddGiftCardToOrderCommand.php create mode 100644 src/DependencyInjection/Compiler/RegisterGiftCardOrPromotionApplicatorsPass.php create mode 100644 src/DependencyInjection/Compiler/UseSameInputPass.php create mode 100644 src/Exception/PromotionCouponNotFoundException.php create mode 100644 src/Form/Extension/CartTypeExtension.php rename src/Form/Type/{AddGiftCardToOrderType.php => AddGiftCardOrPromotionToOrderType.php} (59%) rename src/Resources/config/validation/{AddGiftCardToOrderCommand.xml => AddGiftCardOrPromotionToOrderCommand.xml} (73%) diff --git a/composer.json b/composer.json index b70e4501..90c1c80b 100644 --- a/composer.json +++ b/composer.json @@ -73,7 +73,8 @@ "allow-plugins": { "dealerdirect/phpcodesniffer-composer-installer": false, "ergebnis/composer-normalize": true, - "symfony/thanks": true + "symfony/thanks": true, + "composer/package-versions-deprecated": true }, "sort-packages": true }, diff --git a/src/Applicator/GiftCardApplicator.php b/src/Applicator/GiftCardApplicator.php index 7a81e444..09441c30 100644 --- a/src/Applicator/GiftCardApplicator.php +++ b/src/Applicator/GiftCardApplicator.php @@ -32,17 +32,12 @@ public function __construct( } /** - * @param string|GiftCardInterface|mixed $giftCard + * @throws GiftCardNotFoundException if gift card is not found + * @throws ChannelMismatchException if the orders channel does not match the gift cards channel */ - public function apply(OrderInterface $order, $giftCard): void + public function apply(OrderInterface $order, string $giftCardOrPromotionCode): void { - if (is_string($giftCard)) { - $giftCard = $this->getGiftCard($giftCard); - } - - if (!$giftCard instanceof GiftCardInterface) { - throw new GiftCardNotFoundException($giftCard); - } + $giftCard = $this->getGiftCard($giftCardOrPromotionCode); $orderChannel = $order->getChannel(); if (null === $orderChannel) { @@ -59,10 +54,6 @@ public function apply(OrderInterface $order, $giftCard): void } $order->addGiftCard($giftCard); - - $this->orderProcessor->process($order); - - $this->orderManager->flush(); } /** diff --git a/src/Applicator/GiftCardApplicatorInterface.php b/src/Applicator/GiftCardApplicatorInterface.php index 58c0c9ce..f064c498 100644 --- a/src/Applicator/GiftCardApplicatorInterface.php +++ b/src/Applicator/GiftCardApplicatorInterface.php @@ -4,23 +4,11 @@ namespace Setono\SyliusGiftCardPlugin\Applicator; -use Setono\SyliusGiftCardPlugin\Exception\ChannelMismatchException; -use Setono\SyliusGiftCardPlugin\Exception\GiftCardNotFoundException; use Setono\SyliusGiftCardPlugin\Model\GiftCardInterface; use Setono\SyliusGiftCardPlugin\Model\OrderInterface; -interface GiftCardApplicatorInterface +interface GiftCardApplicatorInterface extends GiftCardOrPromotionApplicatorInterface { - /** - * Applies $giftCard to $order - * - * @param string|GiftCardInterface $giftCard - * - * @throws GiftCardNotFoundException if gift card is not found - * @throws ChannelMismatchException if the orders channel does not match the gift cards channel - */ - public function apply(OrderInterface $order, $giftCard): void; - /** * @param string|GiftCardInterface|mixed $giftCard */ diff --git a/src/Applicator/GiftCardOrPromotionApplicator.php b/src/Applicator/GiftCardOrPromotionApplicator.php new file mode 100644 index 00000000..74c9f290 --- /dev/null +++ b/src/Applicator/GiftCardOrPromotionApplicator.php @@ -0,0 +1,49 @@ +applicators = new PriorityQueue(); + + $this->orderProcessor = $orderProcessor; + $this->orderManager = $orderManager; + } + + public function addApplicator(GiftCardOrPromotionApplicatorInterface $applicator, int $priority = 0): void + { + $this->applicators->insert($applicator, $priority); + } + + public function apply(OrderInterface $order, string $giftCardOrPromotionCode): void + { + foreach ($this->applicators->toArray() as $applicator) { + try { + $applicator->apply($order, $giftCardOrPromotionCode); + + break; + } catch (ExceptionInterface $e) { + } + } + + $this->orderProcessor->process($order); + + $this->orderManager->flush(); + } +} diff --git a/src/Applicator/GiftCardOrPromotionApplicatorInterface.php b/src/Applicator/GiftCardOrPromotionApplicatorInterface.php new file mode 100644 index 00000000..15e1262a --- /dev/null +++ b/src/Applicator/GiftCardOrPromotionApplicatorInterface.php @@ -0,0 +1,12 @@ +promotionCouponRepository = $promotionCouponRepository; + } + + public function apply(OrderInterface $order, string $giftCardOrPromotionCode): void + { + $promotionCoupon = $this->promotionCouponRepository->findOneBy(['code' => $giftCardOrPromotionCode]); + if (null === $promotionCoupon) { + throw new PromotionCouponNotFoundException($giftCardOrPromotionCode); + } + + $order->setPromotionCoupon($promotionCoupon); + } +} diff --git a/src/Controller/Action/AddGiftCardToOrderAction.php b/src/Controller/Action/AddGiftCardOrPromotionToOrderAction.php similarity index 70% rename from src/Controller/Action/AddGiftCardToOrderAction.php rename to src/Controller/Action/AddGiftCardOrPromotionToOrderAction.php index 301be4a0..a9a9cb92 100644 --- a/src/Controller/Action/AddGiftCardToOrderAction.php +++ b/src/Controller/Action/AddGiftCardOrPromotionToOrderAction.php @@ -4,8 +4,8 @@ namespace Setono\SyliusGiftCardPlugin\Controller\Action; -use Setono\SyliusGiftCardPlugin\Applicator\GiftCardApplicatorInterface; -use Setono\SyliusGiftCardPlugin\Form\Type\AddGiftCardToOrderType; +use Setono\SyliusGiftCardPlugin\Applicator\GiftCardOrPromotionApplicatorInterface; +use Setono\SyliusGiftCardPlugin\Form\Type\AddGiftCardOrPromotionToOrderType; use Setono\SyliusGiftCardPlugin\Model\OrderInterface; use Setono\SyliusGiftCardPlugin\Resolver\RedirectUrlResolverInterface; use Sylius\Component\Order\Context\CartContextInterface; @@ -16,9 +16,8 @@ use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Twig\Environment; -use Webmozart\Assert\Assert; -final class AddGiftCardToOrderAction +final class AddGiftCardOrPromotionToOrderAction { private FormFactoryInterface $formFactory; @@ -26,7 +25,7 @@ final class AddGiftCardToOrderAction private FlashBagInterface $flashBag; - private GiftCardApplicatorInterface $giftCardApplicator; + private GiftCardOrPromotionApplicatorInterface $giftCardOrPromotionApplicator; private RedirectUrlResolverInterface $redirectRouteResolver; @@ -36,14 +35,14 @@ public function __construct( FormFactoryInterface $formFactory, CartContextInterface $cartContext, FlashBagInterface $flashBag, - GiftCardApplicatorInterface $giftCardApplicator, + GiftCardOrPromotionApplicatorInterface $giftCardOrPromotionApplicator, RedirectUrlResolverInterface $redirectRouteResolver, Environment $twig ) { $this->formFactory = $formFactory; $this->cartContext = $cartContext; $this->flashBag = $flashBag; - $this->giftCardApplicator = $giftCardApplicator; + $this->giftCardOrPromotionApplicator = $giftCardOrPromotionApplicator; $this->redirectRouteResolver = $redirectRouteResolver; $this->twig = $twig; } @@ -57,14 +56,16 @@ public function __invoke(Request $request): Response throw new NotFoundHttpException(); } - $addGiftCardToOrderCommand = new AddGiftCardToOrderCommand(); - $form = $this->formFactory->create(AddGiftCardToOrderType::class, $addGiftCardToOrderCommand); + $addGiftCardOrPromotionToOrderCommand = new AddGiftCardOrPromotionToOrderCommand(); + $form = $this->formFactory->create( + AddGiftCardOrPromotionToOrderType::class, + $addGiftCardOrPromotionToOrderCommand + ); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - $giftCard = $addGiftCardToOrderCommand->getGiftCard(); - Assert::notNull($giftCard); - $this->giftCardApplicator->apply($order, $giftCard); + $giftCardOrPromotionCode = $addGiftCardOrPromotionToOrderCommand->getCode(); + $this->giftCardOrPromotionApplicator->apply($order, $giftCardOrPromotionCode); $this->flashBag->add('success', 'setono_sylius_gift_card.gift_card_added'); diff --git a/src/Controller/Action/AddGiftCardOrPromotionToOrderCommand.php b/src/Controller/Action/AddGiftCardOrPromotionToOrderCommand.php new file mode 100644 index 00000000..338c84ab --- /dev/null +++ b/src/Controller/Action/AddGiftCardOrPromotionToOrderCommand.php @@ -0,0 +1,20 @@ +code; + } + + public function setCode(?string $code): void + { + $this->code = $code; + } +} diff --git a/src/Controller/Action/AddGiftCardToOrderCommand.php b/src/Controller/Action/AddGiftCardToOrderCommand.php deleted file mode 100644 index 487d7a45..00000000 --- a/src/Controller/Action/AddGiftCardToOrderCommand.php +++ /dev/null @@ -1,22 +0,0 @@ -giftCard; - } - - public function setGiftCard(?GiftCardInterface $giftCard): void - { - $this->giftCard = $giftCard; - } -} diff --git a/src/DependencyInjection/Compiler/RegisterGiftCardOrPromotionApplicatorsPass.php b/src/DependencyInjection/Compiler/RegisterGiftCardOrPromotionApplicatorsPass.php new file mode 100644 index 00000000..04f71421 --- /dev/null +++ b/src/DependencyInjection/Compiler/RegisterGiftCardOrPromotionApplicatorsPass.php @@ -0,0 +1,34 @@ +setAlias( + GiftCardOrPromotionApplicatorInterface::class, + 'setono_sylius_gift_card.gift_card_or_promotion_applicator.applicator' + ); + } +} diff --git a/src/DependencyInjection/Compiler/UseSameInputPass.php b/src/DependencyInjection/Compiler/UseSameInputPass.php new file mode 100644 index 00000000..fe60617e --- /dev/null +++ b/src/DependencyInjection/Compiler/UseSameInputPass.php @@ -0,0 +1,25 @@ +getParameter( + 'setono_sylius_gift_card.cart.use_same_input_for_promotion_and_gift_card' + ); + + if (!$useSameInputForGiftCardAndCoupon) { + if ($container->hasDefinition('setono_sylius_gift_card.applicator.promotion')) { + $container->removeDefinition('setono_sylius_gift_card.applicator.promotion'); + } + } + } +} diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 235023b6..a74541ae 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -44,6 +44,13 @@ public function getConfigTreeBuilder(): TreeBuilder ->min(1) ->max(255) ->example(16) + ->end() + ->arrayNode('cart') + ->addDefaultsIfNotSet() + ->children() + ->booleanNode('use_same_input_for_promotion_and_gift_card')->defaultFalse()->end() + ->end() + ->end() ; $this->addResourcesSection($rootNode); diff --git a/src/DependencyInjection/SetonoSyliusGiftCardExtension.php b/src/DependencyInjection/SetonoSyliusGiftCardExtension.php index 00452b31..adfec6e3 100644 --- a/src/DependencyInjection/SetonoSyliusGiftCardExtension.php +++ b/src/DependencyInjection/SetonoSyliusGiftCardExtension.php @@ -22,6 +22,16 @@ public function load(array $configs, ContainerBuilder $container): void $loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); $container->setParameter('setono_sylius_gift_card.code_length', $config['code_length']); + $useSameInputForPromotionAndGiftCard = false; + if (array_key_exists('cart', $config) + && array_key_exists('use_same_input_for_promotion_and_gift_card', $config['cart']) + ) { + $useSameInputForPromotionAndGiftCard = $config['cart']['use_same_input_for_promotion_and_gift_card']; + } + $container->setParameter( + 'setono_sylius_gift_card.cart.use_same_input_for_promotion_and_gift_card', + $useSameInputForPromotionAndGiftCard + ); $this->registerResources('setono_sylius_gift_card', $config['driver'], $config['resources'], $container); diff --git a/src/Exception/GiftCardNotFoundException.php b/src/Exception/GiftCardNotFoundException.php index 5faf906d..38cc98c0 100644 --- a/src/Exception/GiftCardNotFoundException.php +++ b/src/Exception/GiftCardNotFoundException.php @@ -13,6 +13,7 @@ final class GiftCardNotFoundException extends InvalidArgumentException implement public function __construct(string $giftCard) { + $this->giftCard = $giftCard; $message = sprintf('The gift card with code "%s" was not found', $giftCard); parent::__construct($message); diff --git a/src/Exception/PromotionCouponNotFoundException.php b/src/Exception/PromotionCouponNotFoundException.php new file mode 100644 index 00000000..b8272ebd --- /dev/null +++ b/src/Exception/PromotionCouponNotFoundException.php @@ -0,0 +1,26 @@ +couponCode = $couponCode; + $message = sprintf('The coupon with code "%s" was not found', $couponCode); + + parent::__construct($message); + } + + public function getCouponCode(): string + { + return $this->couponCode; + } +} diff --git a/src/Form/Extension/CartTypeExtension.php b/src/Form/Extension/CartTypeExtension.php new file mode 100644 index 00000000..d2625404 --- /dev/null +++ b/src/Form/Extension/CartTypeExtension.php @@ -0,0 +1,31 @@ +useSameInputForGiftCardAndPromotion = $useSameInputForGiftCardAndPromotion; + } + + public function buildForm(FormBuilderInterface $builder, array $options) + { + if ($this->useSameInputForGiftCardAndPromotion) { + $builder->remove('promotionCoupon'); + } + } + + public static function getExtendedTypes(): iterable + { + return [CartType::class]; + } +} diff --git a/src/Form/Type/AddGiftCardToOrderType.php b/src/Form/Type/AddGiftCardOrPromotionToOrderType.php similarity index 59% rename from src/Form/Type/AddGiftCardToOrderType.php rename to src/Form/Type/AddGiftCardOrPromotionToOrderType.php index 44126ca1..0ca1dcf3 100644 --- a/src/Form/Type/AddGiftCardToOrderType.php +++ b/src/Form/Type/AddGiftCardOrPromotionToOrderType.php @@ -4,29 +4,25 @@ namespace Setono\SyliusGiftCardPlugin\Form\Type; -use Setono\SyliusGiftCardPlugin\Controller\Action\AddGiftCardToOrderCommand; +use Setono\SyliusGiftCardPlugin\Controller\Action\AddGiftCardOrPromotionToOrderCommand; use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\DataTransformerInterface; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; -final class AddGiftCardToOrderType extends AbstractType +final class AddGiftCardOrPromotionToOrderType extends AbstractType { - private DataTransformerInterface $giftCardToCodeDataTransformer; - private array $validationGroups; - public function __construct(DataTransformerInterface $giftCardToCodeDataTransformer, array $validationGroups) + public function __construct(array $validationGroups) { - $this->giftCardToCodeDataTransformer = $giftCardToCodeDataTransformer; $this->validationGroups = $validationGroups; } public function buildForm(FormBuilderInterface $builder, array $options): void { $builder - ->add('giftCard', TextType::class, [ + ->add('code', TextType::class, [ 'label' => false, 'attr' => [ 'placeholder' => 'setono_sylius_gift_card.ui.enter_gift_card_code', @@ -34,20 +30,18 @@ public function buildForm(FormBuilderInterface $builder, array $options): void 'invalid_message' => 'setono_sylius_gift_card.add_gift_card_to_order_command.gift_card.does_not_exist', ]) ; - - $builder->get('giftCard')->addModelTransformer($this->giftCardToCodeDataTransformer); } public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ - 'data_class' => AddGiftCardToOrderCommand::class, + 'data_class' => AddGiftCardOrPromotionToOrderCommand::class, 'validation_groups' => $this->validationGroups, ]); } public function getBlockPrefix(): string { - return 'setono_sylius_gift_card_add_gift_card_to_order'; + return 'setono_sylius_gift_card_add_gift_card_or_promotion_to_order'; } } diff --git a/src/Resources/config/services/applicator.xml b/src/Resources/config/services/applicator.xml index 36ad81a4..d7f21426 100644 --- a/src/Resources/config/services/applicator.xml +++ b/src/Resources/config/services/applicator.xml @@ -10,8 +10,20 @@ + + + + + + + + + + diff --git a/src/Resources/config/services/controller.xml b/src/Resources/config/services/controller.xml index b0325c7d..22ecc094 100644 --- a/src/Resources/config/services/controller.xml +++ b/src/Resources/config/services/controller.xml @@ -8,11 +8,11 @@ + class="Setono\SyliusGiftCardPlugin\Controller\Action\AddGiftCardOrPromotionToOrderAction"> - + diff --git a/src/Resources/config/services/form.xml b/src/Resources/config/services/form.xml index 406e0b6a..6d9bd859 100644 --- a/src/Resources/config/services/form.xml +++ b/src/Resources/config/services/form.xml @@ -39,6 +39,12 @@ + + + + + @@ -51,9 +57,15 @@ + + %setono_sylius_gift_card.cart.use_same_input_for_promotion_and_gift_card% + + + + - + class="Setono\SyliusGiftCardPlugin\Form\Type\AddGiftCardOrPromotionToOrderType"> %setono_sylius_gift_card.form.type.add_gift_card_to_order.validation_groups% diff --git a/src/Resources/config/validation/AddGiftCardToOrderCommand.xml b/src/Resources/config/validation/AddGiftCardOrPromotionToOrderCommand.xml similarity index 73% rename from src/Resources/config/validation/AddGiftCardToOrderCommand.xml rename to src/Resources/config/validation/AddGiftCardOrPromotionToOrderCommand.xml index 6249cf57..80762cc8 100644 --- a/src/Resources/config/validation/AddGiftCardToOrderCommand.xml +++ b/src/Resources/config/validation/AddGiftCardOrPromotionToOrderCommand.xml @@ -3,15 +3,12 @@ - - + + - - - diff --git a/src/Resources/views/Shop/addGiftCardToOrder.html.twig b/src/Resources/views/Shop/addGiftCardToOrder.html.twig index 8fd92a25..96323d4f 100644 --- a/src/Resources/views/Shop/addGiftCardToOrder.html.twig +++ b/src/Resources/views/Shop/addGiftCardToOrder.html.twig @@ -18,12 +18,12 @@
- {{ form_widget(form.giftCard, {'attr': {'form': 'setono-sylius-gift-card-add-gift-card-to-order'}}) }} + {{ form_widget(form.code, {'attr': {'form': 'setono-sylius-gift-card-add-gift-card-to-order'}}) }}

- {{ form_errors(form.giftCard) }} + {{ form_errors(form.code) }}
diff --git a/src/SetonoSyliusGiftCardPlugin.php b/src/SetonoSyliusGiftCardPlugin.php index 6867a289..373fe278 100644 --- a/src/SetonoSyliusGiftCardPlugin.php +++ b/src/SetonoSyliusGiftCardPlugin.php @@ -5,6 +5,8 @@ namespace Setono\SyliusGiftCardPlugin; use Setono\SyliusGiftCardPlugin\DependencyInjection\Compiler\AddAdjustmentsToOrderAdjustmentClearerPass; +use Setono\SyliusGiftCardPlugin\DependencyInjection\Compiler\RegisterGiftCardOrPromotionApplicatorsPass; +use Setono\SyliusGiftCardPlugin\DependencyInjection\Compiler\UseSameInputPass; use Sylius\Bundle\CoreBundle\Application\SyliusPluginTrait; use Sylius\Bundle\ResourceBundle\AbstractResourceBundle; use Sylius\Bundle\ResourceBundle\SyliusResourceBundle; @@ -19,6 +21,8 @@ public function build(ContainerBuilder $container): void parent::build($container); $container->addCompilerPass(new AddAdjustmentsToOrderAdjustmentClearerPass()); + $container->addCompilerPass(new UseSameInputPass()); + $container->addCompilerPass(new RegisterGiftCardOrPromotionApplicatorsPass()); } public function getSupportedDrivers(): array diff --git a/tests/Application/config/packages/setono_sylius_gift_card.yaml b/tests/Application/config/packages/setono_sylius_gift_card.yaml index ccb4949d..41d7fb9d 100644 --- a/tests/Application/config/packages/setono_sylius_gift_card.yaml +++ b/tests/Application/config/packages/setono_sylius_gift_card.yaml @@ -1,3 +1,7 @@ imports: - { resource: "@SetonoSyliusGiftCardPlugin/Resources/config/app/config.yaml" } - { resource: "@SetonoSyliusGiftCardPlugin/Resources/config/app/fixtures.yaml" } + +setono_sylius_gift_card: + cart: + use_same_input_for_promotion_and_gift_card: true