mirror of
https://github.com/Sylius/Sylius.git
synced 2026-07-14 09:02:12 +00:00
[Documentation][Cookbook] How to add a custom promotion action?
This commit is contained in:
parent
b6444aeff7
commit
0685b161c9
3 changed files with 149 additions and 0 deletions
147
docs/cookbook/custom-promotion-action.rst
Normal file
147
docs/cookbook/custom-promotion-action.rst
Normal 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>`
|
||||
|
|
@ -9,6 +9,7 @@ Cookbook
|
|||
custom-model
|
||||
custom-email
|
||||
custom-promotion-rule
|
||||
custom-promotion-action
|
||||
paypal
|
||||
stripe
|
||||
api
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue