Magento 2 REST API – Generate Coupon Codes

couponcoupon-codesmagento2restshopping-cart-price-rules

I am trying to generate a coupon through the Magento 2 REST API. It works, except that I cannot change the usage_limit and expiration_date. They are always set to the values of the rule. Is there any way around this, except creating a new rule for every new coupon?

Request:

{
    "coupon": {
        "rule_id":14,
        "code":"aaabbb",
        "usage_limit":10,
        "expiration_date":"2017-03-19",
        "type":"1"
    }
}

Response:

{
  "coupon_id": 11,
  "rule_id": 14,
  "code": "aaabbb",
  "usage_limit": 2147483647,
  "usage_per_customer": 0,
  "times_used": null,
  "expiration_date": "2064-03-14",
  "is_primary": null,
  "type": 1
}

Best Answer

That happens because you've used salesrule which is used for coupon creation. It means that expiration_date and usage_limit fields will be pulled from the rule and set to the coupon. You must change rule used for that coupon in order to apply different expiration_date / usage_limit.

Here is how it looks in \Magento\SalesRule\Model\CouponRepository, pay attention to $coupon->setExpirationDate(...) and $coupon->setUsageLimit(...):

public function save(\Magento\SalesRule\Api\Data\CouponInterface $coupon)
{
    //if coupon id is provided, use the existing coupon and blend in the new data supplied
    $couponId = $coupon->getCouponId();
    if ($couponId) {
        $existingCoupon = $this->getById($couponId);
        $mergedData = array_merge($existingCoupon->getData(), $coupon->getData());
        $coupon->setData($mergedData);
    }

    //blend in specific fields from the rule
    try {
        $rule = $this->ruleFactory->create()->load($coupon->getRuleId());
        if (!$rule->getRuleId()) {
            throw \Magento\Framework\Exception\NoSuchEntityException::singleField('rule_id', $coupon->getRuleId());
        }
        if ($rule->getCouponType() == $rule::COUPON_TYPE_NO_COUPON) {
            throw new \Magento\Framework\Exception\LocalizedException(
                __('Specified rule does not allow coupons')
            );
        } elseif ($rule->getUseAutoGeneration() && $coupon->getType() == $coupon::TYPE_MANUAL) {
            throw new \Magento\Framework\Exception\LocalizedException(
                __('Specified rule only allows auto generated coupons')
            );
        } elseif (!$rule->getUseAutoGeneration() && $coupon->getType() == $coupon::TYPE_GENERATED) {
            throw new \Magento\Framework\Exception\LocalizedException(
                __('Specified rule does not allow auto generated coupons')
            );
        }
        $coupon->setExpirationDate($rule->getToDate());
        $coupon->setUsageLimit($rule->getUsesPerCoupon());
        $coupon->setUsagePerCustomer($rule->getUsesPerCustomer());
    } catch (\Exception $e) {
        throw new \Magento\Framework\Exception\LocalizedException(
            __('Error occurred when saving coupon: %1', $e->getMessage())
        );
    }

    $this->resourceModel->save($coupon);
    return $coupon;
}

Only thing you can do here is to modify:

$coupon->setExpirationDate($rule->getToDate());
$coupon->setUsageLimit($rule->getUsesPerCoupon());
$coupon->setUsagePerCustomer($rule->getUsesPerCustomer());

Into something like:

if (is_null($coupon->getExpirationDate())) {
    $coupon->setExpirationDate($rule->getToDate());
}

if (is_null($coupon->getUsageLimit())) {
    $coupon->setUsageLimit($rule->getUsesPerCoupon());
}

if (is_null($coupon->getUsagePerCustomer())) {
    $coupon->setUsagePerCustomer($rule->getUsesPerCustomer());
}
Related Topic