Regla de promoción personalizada en Magento2

Algunas ocasiones las reglas predeterminadas en las promociones de magento 2 no encajan del todo con nuestras necesidades, en estos casos podemos crear una regla personalizada.

Lo primero que hacemos es sobreescribir los modelos encargados de las reglas de las promociones a través del archivo di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\SalesRule\Model\Rule\Metadata\ValueProvider" type="Vendor\NombreModulo\Model\Rule\Metadata\ValueProvider" />
<preference for="Magento\SalesRule\Model\Rule\Action\Discount\CalculatorFactory" type="Vendor\NombreModulo\Model\Rule\Action\Discount\CalculatorFactory" />
</config>

Magento\SalesRule\Model\Rule\Metadata\ValueProvider Contiene el nombre de las reglas predeterminadas, alimenta las promociones disponibles, nosotros agregaremos un nuevo nombre de regla en Vendor\NombreModulo\Model\Rule\Metadata\ValueProvider

<?php
namespace Vendor\NombreModulo\Model\Rule\Metadata;
use Magento\SalesRule\Model\ResourceModel\Rule\Collection;
use Magento\SalesRule\Model\Rule;
use Magento\Store\Model\System\Store;
use Magento\Customer\Api\GroupRepositoryInterface;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\Convert\DataObject;
class ValueProvider extends \Magento\SalesRule\Model\Rule\Metadata\ValueProvider
{
const NEW_RULE ='new_rule';
public function getMetadataValues(\Magento\SalesRule\Model\Rule $rule){$customerGroups = $this->groupRepository->getList($this->searchCriteriaBuilder->create())->getItems();
$applyOptions = [
['label' => __('Percent of product price discount'),'value' => Rule::BY_PERCENT_ACTION],
['label' => __('Fixed amount discount'),'value' => Rule::BY_FIXED_ACTION],
['label' => __('Fixed amount discount for whole cart'),'value' => Rule::CART_FIXED_ACTION],
['label' => __('Buy X get Y free (discount amount is Y)'),'value' => Rule::BUY_X_GET_Y_ACTION],
['label' => __('Nueva regla personalizada'),'value' => self::NEW_RULE]
];
$couponTypesOptions = [];
$couponTypes = $this->salesRuleFactory->create()->getCouponTypes();
foreach ($couponTypes as $key => $couponType){$couponTypesOptions[] = [
'label' => $couponType,
'value' => $key,
];
} $labels = $rule->getStoreLabels();
return [
'rule_information' => [
'children' => [
'website_ids' => [
'arguments' => [
'data' => [
'config' => [
'options' => $this->store->getWebsiteValuesForForm(),],
],
],
],
'is_active' => [
'arguments' => [
'data' => [
'config' => [
'options' => [
['label' => __('Active'),'value' => '1'],
['label' => __('Inactive'),'value' => '0']
],
],
],
],
],
'customer_group_ids' => [
'arguments' => [
'data' => [
'config' => [
'options' => $this->objectConverter->toOptionArray($customerGroups, 'id', 'code'),],
],
],
],
'coupon_type' => [
'arguments' => [
'data' => [
'config' => [
'options' => $couponTypesOptions,
],
],
],
],
'is_rss' => [
'arguments' => [
'data' => [
'config' => [
'options' => [
['label' => __('Yes'),'value' => '1'],
['label' => __('No'),'value' => '0']
],
],
],
],
],
]
],
'actions' => [
'children' => [
'simple_action' => [
'arguments' => [
'data' => [
'config' => [
'options' => $applyOptions
],
]
]
],
'discount_amount' => [
'arguments' => [
'data' => [
'config' => [
'value' => '0',
],
],
],
],
'discount_qty' => [
'arguments' => [
'data' => [
'config' => [
'value' => '0',
],
],
],
],
'apply_to_shipping' => [
'arguments' => [
'data' => [
'config' => [
'options' => [
['label' => __('Yes'),'value' => '1'],
['label' => __('No'),'value' => '0']
]
],
],
],
],
'stop_rules_processing' => [
'arguments' => [
'data' => [
'config' => [
'options' => [
['label' => __('Yes'),'value' => '1'],
['label' => __('No'),'value' => '0'],
],
],
]
]
],
]
],
'labels' => [
'children' => [
'store_labels[0]' => [
'arguments' => [
'data' => [
'config' => [
'value' => isset($labels[0]) ? $labels[0] : '',
],
]
]
]
]
],
];
} } 

Nuevo nombre regla magento 2

 

Magento\SalesRule\Model\Rule\Action\Discount\CalculatorFactory contiene la relación del nombre de regla y la clase encargada de hacer las operaciones necesarias para aplicar el descuento, agregaremos una nueva en Vendor\NombreModulo\Model\Rule\Action\Discount\CalculatorFactory.

<?php
namespace Vendor\NombreModulo\Model\Rule\Action\Discount;
class CalculatorFactory extends \Magento\SalesRule\Model\Rule\Action\Discount\CalculatorFactory
{
protected $classByType = [
\Magento\SalesRule\Model\Rule::TO_PERCENT_ACTION =>
\Magento\SalesRule\Model\Rule\Action\Discount\ToPercent::class,
\Magento\SalesRule\Model\Rule::BY_PERCENT_ACTION =>
\Magento\SalesRule\Model\Rule\Action\Discount\ByPercent::class,
\Magento\SalesRule\Model\Rule::TO_FIXED_ACTION => \Magento\SalesRule\Model\Rule\Action\Discount\ToFixed::class,
\Magento\SalesRule\Model\Rule::BY_FIXED_ACTION => \Magento\SalesRule\Model\Rule\Action\Discount\ByFixed::class,
\Magento\SalesRule\Model\Rule::CART_FIXED_ACTION =>
\Magento\SalesRule\Model\Rule\Action\Discount\CartFixed::class,
\Magento\SalesRule\Model\Rule::BUY_X_GET_Y_ACTION =>
\Magento\SalesRule\Model\Rule\Action\Discount\BuyXGetY::class,
\Vendor\NombreModulo\Model\Rule\Metadata\ValueProvider::NEW_RULE =>
\Pengo\SpecialPrice\Model\Rule\Action\Discount\NewRule::class,
];
} 

Hemos indicado que la clase \Vendor\NombreModulo\Model\Rule\Action\Discount\NewRule contiene la logica del descuento.

<?php
namespace Vendor\NombreModulo\Model\Rule\Action\Discount;
class NewRule extends \Magento\SalesRule\Model\Rule\Action\Discount\AbstractDiscount
{
/**
* @param \Magento\SalesRule\Model\Rule $rule
* @param \Magento\Quote\Model\Quote\Item\AbstractItem $item
* @param float $qty
* @return Data
*/
public function calculate($rule, $item, $qty){$discountData = $this->_calculate($rule, $item, $qty);
return $discountData;
} /**
* @param float $qty
* @param \Magento\SalesRule\Model\Rule $rule
* @return float
*/
public function fixQuantity($qty, $rule){$step = $rule->getDiscountStep();
if ($step){$qty = floor($qty / $step) * $step;
} return $qty;
} /**
* @param \Magento\SalesRule\Model\Rule $rule
* @param \Magento\Quote\Model\Quote\Item\AbstractItem $item
* @param float $qty
* @param float $rulePercent
* @return Data
*/
protected function _calculate($rule, $item, $qty){$discountData = $this->discountFactory->create();
// $discountData->setAmount();
//Programar nueva regla aqui
return $discountData;
} } 
Fecha: 04 Jul 2018 14:41 Hrs.

Acerca del autor

Sombrero de paja molder