getEvent()->getRule() in this case * * @var string */ protected $_eventObject = 'rule'; /** * Rule's primary coupon * * @var \Magento\SalesRule\Model\Coupon */ protected $_primaryCoupon; /** * Rule's subordinate coupons * * @var \Magento\SalesRule\Model\Coupon[] */ protected $_coupons; /** * Coupon types cache for lazy getter * * @var array */ protected $_couponTypes; /** * Store already validated addresses and validation results * * @var array */ protected $_validatedAddresses = []; /** * @var \Magento\SalesRule\Model\CouponFactory */ protected $_couponFactory; /** * @var \Magento\SalesRule\Model\Coupon\CodegeneratorFactory */ protected $_codegenFactory; /** * @var \Magento\SalesRule\Model\Rule\Condition\CombineFactory */ protected $_condCombineFactory; /** * @var \Magento\SalesRule\Model\Rule\Condition\Product\CombineFactory */ protected $_condProdCombineF; /** * @var \Magento\SalesRule\Model\ResourceModel\Coupon\Collection */ protected $_couponCollection; /** * @var \Magento\Store\Model\StoreManagerInterface */ protected $_storeManager; /** * Rule constructor * * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry * @param \Magento\Framework\Data\FormFactory $formFactory * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate * @param CouponFactory $couponFactory * @param Coupon\CodegeneratorFactory $codegenFactory * @param Rule\Condition\CombineFactory $condCombineFactory * @param Rule\Condition\Product\CombineFactory $condProdCombineF * @param ResourceModel\Coupon\Collection $couponCollection * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Framework\Model\ResourceModel\AbstractResource|null $resource * @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection * @param array $data * @param ExtensionAttributesFactory|null $extensionFactory * @param AttributeValueFactory|null $customAttributeFactory * @param \Magento\Framework\Serialize\Serializer\Json $serializer * * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( \Magento\Framework\Model\Context $context, \Magento\Framework\Registry $registry, \Magento\Framework\Data\FormFactory $formFactory, \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, \Magento\SalesRule\Model\CouponFactory $couponFactory, \Magento\SalesRule\Model\Coupon\CodegeneratorFactory $codegenFactory, \Magento\SalesRule\Model\Rule\Condition\CombineFactory $condCombineFactory, \Magento\SalesRule\Model\Rule\Condition\Product\CombineFactory $condProdCombineF, \Magento\SalesRule\Model\ResourceModel\Coupon\Collection $couponCollection, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, array $data = [], ExtensionAttributesFactory $extensionFactory = null, AttributeValueFactory $customAttributeFactory = null, \Magento\Framework\Serialize\Serializer\Json $serializer = null ) { $this->_couponFactory = $couponFactory; $this->_codegenFactory = $codegenFactory; $this->_condCombineFactory = $condCombineFactory; $this->_condProdCombineF = $condProdCombineF; $this->_couponCollection = $couponCollection; $this->_storeManager = $storeManager; parent::__construct( $context, $registry, $formFactory, $localeDate, $resource, $resourceCollection, $data, $extensionFactory, $customAttributeFactory, $serializer ); } /** * Set resource model and Id field name * * @return void */ protected function _construct() { parent::_construct(); $this->_init(\Magento\SalesRule\Model\ResourceModel\Rule::class); $this->setIdFieldName('rule_id'); } /** * Set coupon code and uses per coupon * * @return $this */ protected function _afterLoad() { $this->loadRelations(); return parent::_afterLoad(); } /** * Load all relative data * * @return void */ public function loadRelations() { $this->loadCouponCode(); } /** * Load coupon code * * @return void */ public function loadCouponCode() { $this->setCouponCode($this->getPrimaryCoupon()->getCode()); if ($this->getUsesPerCoupon() == null && !$this->getUseAutoGeneration()) { $this->setUsesPerCoupon($this->getPrimaryCoupon()->getUsageLimit()); } } /** * Save/delete coupon * * @return $this */ public function afterSave() { $couponCode = trim($this->getCouponCode()); if (strlen( $couponCode ) && $this->getCouponType() == self::COUPON_TYPE_SPECIFIC && !$this->getUseAutoGeneration() ) { $this->getPrimaryCoupon()->setCode( $couponCode )->setUsageLimit( $this->getUsesPerCoupon() ? $this->getUsesPerCoupon() : null )->setUsagePerCustomer( $this->getUsesPerCustomer() ? $this->getUsesPerCustomer() : null )->setExpirationDate( $this->getToDate() )->save(); } else { $this->getPrimaryCoupon()->delete(); } parent::afterSave(); return $this; } /** * Initialize rule model data from array. Set store labels if applicable. * * @param array $data * @return $this */ public function loadPost(array $data) { parent::loadPost($data); if (isset($data['store_labels'])) { $this->setStoreLabels($data['store_labels']); } return $this; } /** * Get rule condition combine model instance * * @return \Magento\SalesRule\Model\Rule\Condition\Combine */ public function getConditionsInstance() { return $this->_condCombineFactory->create(); } /** * Get rule condition product combine model instance * * @return \Magento\SalesRule\Model\Rule\Condition\Product\Combine */ public function getActionsInstance() { return $this->_condProdCombineF->create(); } /** * Returns code generator instance for auto generated coupons * * @return \Magento\SalesRule\Model\Coupon\CodegeneratorInterface */ public function getCouponCodeGenerator() { if (!$this->_couponCodeGenerator) { return $this->_codegenFactory->create(['data' => ['length' => 16]]); } return $this->_couponCodeGenerator; } /** * Set code generator instance for auto generated coupons * * @param \Magento\SalesRule\Model\Coupon\CodegeneratorInterface $codeGenerator * @return void */ public function setCouponCodeGenerator(\Magento\SalesRule\Model\Coupon\CodegeneratorInterface $codeGenerator) { $this->_couponCodeGenerator = $codeGenerator; } /** * Retrieve rule's primary coupon * * @return \Magento\SalesRule\Model\Coupon */ public function getPrimaryCoupon() { if ($this->_primaryCoupon === null) { $this->_primaryCoupon = $this->_couponFactory->create(); $this->_primaryCoupon->loadPrimaryByRule($this->getId()); $this->_primaryCoupon->setRule($this)->setIsPrimary(true); } return $this->_primaryCoupon; } /** * Get sales rule customer group Ids * * @return array */ public function getCustomerGroupIds() { if (!$this->hasCustomerGroupIds()) { $customerGroupIds = $this->_getResource()->getCustomerGroupIds($this->getId()); $this->setData('customer_group_ids', (array)$customerGroupIds); } return $this->_getData('customer_group_ids'); } /** * Get Rule label by specified store * * @param \Magento\Store\Model\Store|int|bool|null $store * @return string|bool */ public function getStoreLabel($store = null) { $storeId = $this->_storeManager->getStore($store)->getId(); $labels = (array)$this->getStoreLabels(); if (isset($labels[$storeId])) { return $labels[$storeId]; } elseif (isset($labels[0]) && $labels[0]) { return $labels[0]; } return false; } /** * Set if not yet and retrieve rule store labels * * @return array */ public function getStoreLabels() { if (!$this->hasStoreLabels()) { $labels = $this->_getResource()->getStoreLabels($this->getId()); $this->setStoreLabels($labels); } return $this->_getData('store_labels'); } /** * Retrieve subordinate coupons * * @return \Magento\SalesRule\Model\Coupon[] */ public function getCoupons() { if ($this->_coupons === null) { $this->_couponCollection->addRuleToFilter($this); $this->_coupons = $this->_couponCollection->getItems(); } return $this->_coupons; } /** * Retrieve coupon types * * @return array */ public function getCouponTypes() { if ($this->_couponTypes === null) { $this->_couponTypes = [ \Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON => __('No Coupon'), \Magento\SalesRule\Model\Rule::COUPON_TYPE_SPECIFIC => __('Specific Coupon'), ]; $transport = new \Magento\Framework\DataObject( ['coupon_types' => $this->_couponTypes, 'is_coupon_type_auto_visible' => false] ); $this->_eventManager->dispatch('salesrule_rule_get_coupon_types', ['transport' => $transport]); $this->_couponTypes = $transport->getCouponTypes(); if ($transport->getIsCouponTypeAutoVisible()) { $this->_couponTypes[\Magento\SalesRule\Model\Rule::COUPON_TYPE_AUTO] = __('Auto'); } } return $this->_couponTypes; } /** * Acquire coupon instance * * @param bool $saveNewlyCreated Whether or not to save newly created coupon * @param int $saveAttemptCount Number of attempts to save newly created coupon * @return \Magento\SalesRule\Model\Coupon|null * @throws \Exception|\Magento\Framework\Exception\LocalizedException * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ public function acquireCoupon($saveNewlyCreated = true, $saveAttemptCount = 10) { if ($this->getCouponType() == self::COUPON_TYPE_NO_COUPON) { return null; } if ($this->getCouponType() == self::COUPON_TYPE_SPECIFIC) { return $this->getPrimaryCoupon(); } /** @var \Magento\SalesRule\Model\Coupon $coupon */ $coupon = $this->_couponFactory->create(); $coupon->setRule( $this )->setIsPrimary( false )->setUsageLimit( $this->getUsesPerCoupon() ? $this->getUsesPerCoupon() : null )->setUsagePerCustomer( $this->getUsesPerCustomer() ? $this->getUsesPerCustomer() : null )->setExpirationDate( $this->getToDate() )->setType( \Magento\SalesRule\Api\Data\CouponInterface::TYPE_GENERATED ); $couponCode = self::getCouponCodeGenerator()->generateCode(); $coupon->setCode($couponCode); $ok = false; if (!$saveNewlyCreated) { $ok = true; } else { if ($this->getId()) { for ($attemptNum = 0; $attemptNum < $saveAttemptCount; $attemptNum++) { try { $coupon->save(); } catch (\Exception $e) { if ($e instanceof \Magento\Framework\Exception\LocalizedException || $coupon->getId()) { throw $e; } $coupon->setCode( $couponCode . self::getCouponCodeGenerator()->getDelimiter() . sprintf( '%04u', random_int(0, 9999) ) ); continue; } $ok = true; break; } } } if (!$ok) { throw new \Magento\Framework\Exception\LocalizedException(__('Can\'t acquire coupon.')); } return $coupon; } /** * Get from date. * * @return string * @since 100.1.0 */ public function getFromDate() { return $this->getData('from_date'); } /** * Get to date. * * @return string * @since 100.1.0 */ public function getToDate() { return $this->getData('to_date'); } /** * Check cached validation result for specific address * * @param Address $address * @return bool */ public function hasIsValidForAddress($address) { $addressId = $this->_getAddressId($address); return isset($this->_validatedAddresses[$addressId]) ? true : false; } /** * Set validation result for specific address to results cache * * @param Address $address * @param bool $validationResult * @return $this */ public function setIsValidForAddress($address, $validationResult) { $addressId = $this->_getAddressId($address); $this->_validatedAddresses[$addressId] = $validationResult; return $this; } /** * Get cached validation result for specific address * * @param Address $address * @return bool * @SuppressWarnings(PHPMD.BooleanGetMethodName) */ public function getIsValidForAddress($address) { $addressId = $this->_getAddressId($address); return isset($this->_validatedAddresses[$addressId]) ? $this->_validatedAddresses[$addressId] : false; } /** * Return id for address * * @param Address $address * @return string */ private function _getAddressId($address) { if ($address instanceof Address) { return $address->getId(); } return $address; } /** * Get conditions field set id. * * @param string $formName * @return string * @since 100.1.0 */ public function getConditionsFieldSetId($formName = '') { return $formName . 'rule_conditions_fieldset_' . $this->getId(); } /** * Get actions field set id. * * @param string $formName * @return string * @since 100.1.0 */ public function getActionsFieldSetId($formName = '') { return $formName . 'rule_actions_fieldset_' . $this->getId(); } }