Question

I want to generate a coupon, when a new user registrates on the website. For that, I use this module, which works very well:

https://github.com/php-cuong/magento2-newsletter-coupon-code

In this module the coupon code is generated when the user subscribes to the newsletter. The code for the generation can be found under magento2-newsletter-coupon-code/Model/Subscriber.php and it looks like this:

protected function generateCouponCode()
{
    try {
        $couponData = [];
        $couponData['name'] = '$5 Gift Voucher Newsletter Subscription ('.$this->getEmail().')';
        $couponData['is_active'] = '1';
        $couponData['simple_action'] = 'by_fixed';
        $couponData['discount_amount'] = '5';
        $couponData['from_date'] = date('Y-m-d');
        $couponData['to_date'] = '2019-12-31 23:59:59';
        $couponData['uses_per_coupon'] = '1';
        $couponData['coupon_type'] = '2';
        $couponData['customer_group_ids'] = $this->getCustomerGroupIds();
        $couponData['website_ids'] = $this->getWebsiteIds();
        /** @var \Magento\SalesRule\Model\Rule $rule */
        $rule = $this->_getSalesRule();
        $couponCode = $rule->getCouponCodeGenerator()->setLength(4)->setAlphabet(
            'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
        )->generateCode().'SUBNEW';
        $couponData['coupon_code'] = $couponCode;
        $rule->loadPost($couponData);
        $rule->save();
        return $couponCode;
    } catch (\Exception $e) {
        return null;
    }
}

Now I know from this post ( Magento 2: Programmatically create & apply shopping cart rule ) that in order to add a condition for the generated coupon, I have to add

        "conditions_serialized" => '',
        "actions_serialized" => ''

So I added them and it looks like this, but it doesn't work for some reason:

    protected function generateCouponCode()
{
    try {
        $couponData = [];
        $couponData['name'] = '2€ Newsletter Anmeldung ('.$this->getEmail().')';
        $couponData['is_active'] = '1';
        $couponData['simple_action'] = 'by_fixed';
        $couponData['discount_amount'] = '2';
        $couponData['from_date'] = date('Y-m-d');
        $couponData['to_date'] = '2029-12-31 23:59:59';
        $couponData['uses_per_coupon'] = '1';
        $couponData['coupon_type'] = '2';
        $couponData['customer_group_ids'] = $this->getCustomerGroupIds();
        $couponData['website_ids'] = $this->getWebsiteIds();
        /** @var \Magento\SalesRule\Model\Rule $rule */
        $rule = $this->_getSalesRule();
        $couponCode = $rule->getCouponCodeGenerator()->setLength(12)->setAlphabet(
            'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
        )->generateCode().'NEWABO';
        $couponData['coupon_code'] = $couponCode;
        $couponData['conditions_serialized'] = '{"type":"Magento\\SalesRule\\Model\\Rule\\Condition\\Combine","attribute":null,"operator":null,"value":"1","is_value_processed":null,"aggregator":"all","conditions":[{"type":"Magento\\SalesRule\\Model\\Rule\\Condition\\Address","attribute":"base_subtotal","operator":">=","value":"50","is_value_processed":false}]}';
        $couponData['actions_serialized'] = '{"type":"Magento\\SalesRule\\Model\\Rule\\Condition\\Product\\Combine","attribute":null,"operator":null,"value":"1","is_value_processed":null,"aggregator":"all"}';
        $rule->loadPost($couponData);
        $rule->save();
        return $couponCode;
    } catch (\Exception $e) {
        return null;
    }
}

I got the string for the conditions_serialized and the actions_serialized by creating the a coupon in the admin backend and then looking for it in the database in the colum of the salesrule table: enter image description here

With this setup, I still get an error message, when I try to register as a new user. Does anyone have an idea what I did wrong?

Thanks for your help and your time!

No correct solution

OTHER TIPS

In my opinion, this module is ~okay~ but not ideal. Firstly, because it will create a brand new sales rule every time someone subscribes to your newsletter - this means it will create more work for you if you ever want to clean up your sales rules.

A better solution would be to change this function entirely so that it loads a rule you have already created in the admin panel. That way, you can define the desired conditions in the rule beforehand, then when someone subscribes, the function will generate a coupon code against the existing rule.

You'll need to add to your construct these dependencies:

 \Magento\SalesRule\Api\RuleRepositoryInterface $ruleRepository,
 \Magento\SalesRule\Model\CouponGenerator $couponGenerator,

e.g.

   /**
   * Generate single coupon code
   *
   * @return string
   */
protected function generateCouponCode()
{
    $ruleId = 1; //enter your rule Id here
    $rule = $this->_ruleRepository->getById($ruleId);

    $data = [
      'rule_id' => $rule->getRuleId(),
      'qty' => '1',
      'length' => '8', //change to your requirements
      'format' => 'alphanum', //options alphanum, num, alpha
      'prefix' => 'NEWSUB',
      'suffix' => '',
      'dash' => '4', 
    ];
    $couponCode = $this->_couponGenerator->generateCodes($data)[0];
    return $couponCode;
}

Optionally, you can actually enter these default parameters in admin panel as well - in Stores > Configuration > Customers > Promotions. If you want to set there, you should add to your construct:

\Magento\SalesRule\Helper\Coupon $couponHelper

And use these functions instead to retrieve that data:

    $data = [
      'rule_id' => $rule->getRuleId(),
      'qty' => '1',
      'length' => $this->couponHelper->getDefaultLength(),
      'format' => $this->couponHelper->getDefaultFormat(),
      'prefix' => $this->couponHelper->getDefaultPrefix(),
      'suffix' => $this->couponHelper->getDefaultSuffix(),
      'dash' => $this->couponHelper->getDefaultDashInterval(),
    ];
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top