[Documentation][Cookbook] How to add a custom promotion action?

This commit is contained in:
Magdalena Banasiak 2016-11-16 09:28:18 +01:00
parent b6444aeff7
commit 0685b161c9
3 changed files with 149 additions and 0 deletions

View file

@ -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
<?php
namespace AppBundle\Promotion\Action;
class CheapestProductDiscountPromotionActionCommand extends DiscountPromotionActionCommand
{
const TYPE = 'cheapest_item_discount';
/**
* @var ProportionalIntegerDistributorInterface
*/
private $proportionalDistributor;
/**
* @var UnitsPromotionAdjustmentsApplicatorInterface
*/
private $unitsPromotionAdjustmentsApplicator;
/**
* @param ProportionalIntegerDistributorInterface $proportionalIntegerDistributor
* @param UnitsPromotionAdjustmentsApplicatorInterface $unitsPromotionAdjustmentsApplicator
*/
public function __construct(
ProportionalIntegerDistributorInterface $proportionalIntegerDistributor,
UnitsPromotionAdjustmentsApplicatorInterface $unitsPromotionAdjustmentsApplicator
) {
$this->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
<?php
namespace AppBundle\Form\Type\Action;
use Symfony\Component\Form\AbstractType;
class CheapestProductDiscountConfigurationType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function getName()
{
return 'app_promotion_action_cheapest_product_discount_configuration';
}
}
Register the form type as a service
-----------------------------------
In the ``AppBundle/Resources/config/services.yml`` configure:
.. code-block:: yaml
# AppBundle/Resources/config/services.yml
app.form.type.promotion_action.cheapest_product_discount_configuration:
class: AppBundle\Form\Type\Action\CheapestProductDiscountConfigurationType
tags:
- { name: form.type, alias: app_promotion_action_cheapest_product_discount_configuration }
Create a new promotion with your action
---------------------------------------
Go to the admin panel of your system. On the ``/admin/promotions/new`` url you can create a new promotion.
In its configuration you can choose your new "Cheapest product discount" action.
That's all. **Done!**
Learn more
----------
* :doc:`Customization Guide </customization/index>`
* :doc:`Promotions Concept Documentation </customization/index>`

View file

@ -9,6 +9,7 @@ Cookbook
custom-model
custom-email
custom-promotion-rule
custom-promotion-action
paypal
stripe
api

View file

@ -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`