diff --git a/docs/cookbook/custom-promotion-action.rst b/docs/cookbook/custom-promotion-action.rst new file mode 100644 index 0000000000..e843861706 --- /dev/null +++ b/docs/cookbook/custom-promotion-action.rst @@ -0,0 +1,147 @@ +How to add a custom promotion action? +===================================== + +Let's assume that you would like to have a promotion that gives **100% discount on the cheapest item in the cart**. + +See what steps need to be taken to achieve that: + +Create a new promotion action +----------------------------- + +You will need a new class ``CheapestProductDiscountPromotionActionCommand``. + +It will give a discount equal to the unit price of the cheapest item. That's why it needs to have the Proportional Distributor and +the Adjustments Applicator. The ``execute`` method applies the discount and distributes it properly on the totals. +This class needs also a ``isConfigurationValid()`` method which was omitted in the snippet below. + +.. code-block:: php + + proportionalDistributor = $proportionalIntegerDistributor; + $this->unitsPromotionAdjustmentsApplicator = $unitsPromotionAdjustmentsApplicator; + } + + /** + * {@inheritdoc} + */ + public function execute(PromotionSubjectInterface $subject, array $configuration, PromotionInterface $promotion) + { + if (!$subject instanceof OrderInterface) { + throw new UnexpectedTypeException($subject, OrderInterface::class); + } + + $items = $subject->getItems(); + + $cheapestItem = $items->first(); + + $itemsTotals = []; + + foreach ($items as $item) { + $itemsTotals[] = $item->getTotal(); + + $cheapestItem = ($item->getVariant()->getPrice() < $cheapestItem->getVariant()->getPrice()) ? $item : $cheapestItem; + } + + $splitPromotion = $this->proportionalDistributor->distribute($itemsTotals, -1 * $cheapestItem->getVariant()->getPrice()); + $this->unitsPromotionAdjustmentsApplicator->apply($subject, $promotion, $splitPromotion); + } + + /** + * {@inheritdoc} + */ + public function getConfigurationFormType() + { + return 'app_promotion_action_cheapest_product_discount_configuration'; + } + } + +Register the action as a service +-------------------------------- + +In the ``AppBundle/Resources/config/services.yml`` configure: + +.. code-block:: yaml + + # AppBundle/Resources/config/services.yml + app.promotion_action.cheapest_product_discount: + class: AppBundle\Promotion\Action\CheapestProductDiscountPromotionActionCommand + arguments: ['@sylius.proportional_integer_distributor', '@sylius.promotion.units_promotion_adjustments_applicator'] + tags: + - { name: sylius.promotion_action, type: cheapest_product_discount, label: Cheapest product discount } + +Prepare a configuration form type for the admin panel +----------------------------------------------------- + +The new action needs a form type to be available in the admin panel, while creating a new promotion. + +.. code-block:: php + + ` +* :doc:`Promotions Concept Documentation ` diff --git a/docs/cookbook/index.rst b/docs/cookbook/index.rst index dc8100be4a..ba9c24e36b 100644 --- a/docs/cookbook/index.rst +++ b/docs/cookbook/index.rst @@ -9,6 +9,7 @@ Cookbook custom-model custom-email custom-promotion-rule + custom-promotion-action paypal stripe api diff --git a/docs/cookbook/map.rst.inc b/docs/cookbook/map.rst.inc index e25d0109c5..b3155206f5 100644 --- a/docs/cookbook/map.rst.inc +++ b/docs/cookbook/map.rst.inc @@ -3,6 +3,7 @@ * :doc:`/cookbook/custom-model` * :doc:`/cookbook/custom-email` * :doc:`/cookbook/custom-promotion-rule` +* :doc:`/cookbook/custom-promotion-action` * :doc:`/cookbook/paypal` * :doc:`/cookbook/stripe` * :doc:`/cookbook/api`