Magento 1 – How to Validate All Coupon Code Rules Using Custom Validations

magento-1shopping-cart-price-rules

I am using REST API and want to validate coupon code, whether it is applicable or not.

I have no checkout/session and no quote. I just have cart data and user checkout information.

What I actually want to achieve is, whenever I apply coupon code, it should only accept if it passes all the validations, all the conditions, and all the action rules defined inside the shopping cart price rule.

What is the proper way to validate the coupon code against all its rules ?

How should this be implemented ?

What are the alternatives ?

Best Answer

Finally resolved by myself, using Magento 1.9

First of all Magento V2 API for adding a coupon code on cart does not provide complete validations

e.g. Coupon Dates, Uses Per Coupon, Coupon usage and Customer Group.

Above mentioned point is very important to notice. If you call the coupon code add API, then the API call will surpass these constraints and will not validate or restrict you. Magento V2 API for Coupon codes only validates the Conditions and Action rules but does not validate the Coupon.

e.g. Cart subtotal validations, cart products by category validations and so on.

In the solution of all of above I have solved it using MAgento 1.9 V2 API + Custom API.

I have created custom API to validate if the coupon is applicable or not and this is my first step as well.

e.g. Coupon applicable Date range, User per customer, Coupon usage limit and Customer Group validations

I have used below function in custom API to validate coupon constraints (you can change the business logic according to yours) :

function validateCoupon($coupon,$subtotal=0,$isLoggedIn='',$customerEmail='')
{

    $message = 'success';
    try {
        $oCoupon = Mage::getModel('salesrule/coupon')->load($coupon, 'code');
        $oRule = Mage::getModel('salesrule/rule')->load($oCoupon->getRuleId());
        $rule_arr = unserialize($oRule->getConditionsSerialized());

    } catch (Exception $e) {
        $message = $e->getMessage();
    }

    $todaysDate=strtotime(date('Y-m-d'));

    /* Validation for Coupon code usage --START--@Ahsan Horani */

    //Check if customer exists
    if($isLoggedIn == 1)
    {
        //Load customer by Email
        $customer = Mage::getModel("customer/customer"); 
        $customer->setWebsiteId(1);

        try
        {
            $customer->loadByEmail($customerEmail);
        }
        catch(Exception $ex)
        {
            return array('couponDiscountAmount' => 0,
                'message' => 'Customer does not exist',
                'status' => 'Failed');
        }

        if(!$customer->getId())
        {
            return array('couponDiscountAmount' => 0,
                'message' => 'Customer does not exist',
                'status' => 'Failed');
        }
    }

    $customerGroupIds = $oRule->getCustomerGroupIds();  //Get allowed customer group Ids

    //Check if logged-in customer is required for this coupon, '1' => Logged-in
    if (in_array('1', $customerGroupIds)) {
        //If customer is not logged-in, then fail validation and return
        if ($isLoggedIn == 0) {
            return array('couponDiscountAmount' => intval($oRule->getDiscountAmount()),
                'message' => 'You must login to use this coupon code',
                'status' => 'Failed');
        }

    }

    //Get all orders, filter by Customer Email and Coupon Code
    $customerUsed = Mage::getModel('sales/order')->getCollection();
    $customerUsed->addFieldToFilter('coupon_code', $coupon);
    $customerUsed->addFieldToFilter('customer_email', $customerEmail);

    $timesUsedByCustomer = $customerUsed->count();  //Get number of times customer have used this voucher
    $usagePerCustomer = $oCoupon->getData('usage_per_customer');   //Get allowed limit for per customer usage
    $usageLimit = $oCoupon->getData('usage_limit');          //Get allowed coupon code usage limit
    $timesUsed = $oCoupon->getData('times_used');           //Get number of times coupon have been used
    $fromDate = $oRule->getFromDate();
    $toDate = $oRule->getToDate();
    $currentDate = date("Y-m-d");

    //Check if Coupon is valid within Dates
    if (($fromDate > $currentDate) || ($toDate < $currentDate)) {
        return array('couponDiscountAmount' => intval($oRule->getDiscountAmount()),
            'message' => 'Coupon code is not applicable',
            'status' => 'Failed');
    }

    //Check if Coupon Code's usage limit reached
    if ($timesUsed >= $usageLimit) {
        return array('couponDiscountAmount' => intval($oRule->getDiscountAmount()),
            'message' => 'Coupon code usage limit have been reached',
            'status' => 'Failed');
    }

    //Check if Customer's Coupon code usage limit reached
    if ($timesUsedByCustomer >= $usagePerCustomer) {
        return array('couponDiscountAmount' => intval($oRule->getDiscountAmount()),
            'message' => 'Your coupon code limit have been reached',
            'status' => 'Failed');
    }
    /* Validation for Coupon code usage --END--@Ahsan Horani */

    if ((!$oRule->getIsActive())) 
      {
            $message = 'Invalid or Used Coupon!';
            $status  =  'Failed';
      }
       else
        {
            $message = "Coupon code applied";
            $status  =  'Success';
        }
        return array('couponDiscountAmount' => intval($oRule->getDiscountAmount()), 'message' => $message,'status'=>$status);
    }

    return array('couponDiscountAmount' => intval(0), 'message' => 'Invalid or Used Coupon!','status' => 'Failed');
}

If the above function responds with success then we can proceed with the simple Magento SOAP V2 APIs to apply Discount code

Following is the working example script to apply Discount Code using Magento V2 APIs :

<?php
error_reporting(E_ALL); 
ini_set("display_errors", 1);

$client = new SoapClient('http://127.0.0.1/yayvo_beta/index.php/api/v2_soap/?wsdl');

$session = $client->login('yayvomobileapi_user', 'yayvomobileapi123+');
$storeId = '1';

$quoteId = $client->shoppingCartCreate($session,$storeId);

echo "<br>Quote ID : " . $quoteId;

/* Set cart customer */
$guest = true;

if ($guest) 
{
    $customerData = array(
        "firstname" => "testFirstname",
        "lastname" => "testLastName",
        "email" => "ahsan.horani@gmail.com",
        "mode" => "guest",
        "website_id" => "1"
    );
} 
else 
{
    $customer  = array(
        "customer_id" => '69301',
        "website_id" => "1",
        "group_id" => "1",
        "store_id" => "1",
        "mode" => "customer",
    );
}

//Set cart customer (assign customer to quote)
$resultCustomerSet = $client->shoppingCartCustomerSet($session, $quoteId, $customerData,$storeId);

echo "<br>Set Customer: ";
var_dump($resultCustomerSet);   //Set customer

/* Set customer addresses Shipping and Billing */

$addresses = array(
    array(
        "mode" => "shipping",
        "firstname" => "Ahsan",
        "lastname" => "testLastname",
        "company" => "testCompany",
        "street" => "testStreet",
        "city" => "Karachi",
        "region" => "Sindh",
        "postcode" => "7502",
        "country_id" => "PK",
        "telephone" => "0123456789",
        "fax" => "0123456789",
        "is_default_shipping" => 0,
        "is_default_billing" => 0
    ),
    array(
        "mode" => "billing",
        "firstname" => "Ahsan",
        "lastname" => "testLastname",
        "company" => "testCompany",
        "street" => "testStreet",
        "city" => "Karachi",
        "region" => "Sindh",
        "postcode" => "7502",
        "country_id" => "PK",
        "telephone" => "0123456789",
        "fax" => "0123456789",
        "is_default_shipping" => 0,
        "is_default_billing" => 0
    )
);

//Set cart customer address
$resultCustomerAddress = $client->shoppingCartCustomerAddresses($session, $quoteId, $addresses,$storeId);   

echo "<br>Set Customer Address: ";
var_dump($resultCustomerAddress);   //Set customer addresses

/* Add products to cart */
$product = array(
                            'product_id' => '905',
                            // 'sku' => 'simple_product',
                            'qty' => '1',
                            'options' => null,
                            'bundle_option' => null,
                            'bundle_option_qty' => null,
                            'links' => null);
$product2 = array(
                            'product_id' => '904',
                            // 'sku' => 'simple_product',
                            'qty' => '2',
                            'options' => null,
                            'bundle_option' => null,
                            'bundle_option_qty' => null,
                            'links' => null);

$addToCart = $client->shoppingCartProductAdd($session, $quoteId, array($product,$product2),$storeId);

echo "<br>Add to Cart: ";
var_dump($addToCart);

/* Set payment method */
$responsePayment = $client->shoppingCartPaymentMethod($session, $quoteId, array(
    'method' => 'cashondelivery',
),$storeId);  

echo "<br>Set Payment method: ";
var_dump($responsePayment);

/* Set shipping method */
$setShipping = $client->shoppingCartShippingMethod($session, $quoteId, 'flatrate_flatrate',$storeId);

echo "<br>Set Shipping method: ";
var_dump($setShipping);

/* Set Discount Code */

try
{
    $result = $client->shoppingCartCouponAdd($session, $quoteId, 'test123',$storeId);
    echo "<br>Apply discount code: ";
    var_dump($result);
}
catch(Exception $ex)
{
    echo "<br>Discount code Failed: " . $ex->getMessage();
    die();
}

Note: Must notice that I have provided Store ID in every API call this is very important. Else your discount code will throw an "Invalid coupon" error every time.

That's it. I hope this might help someone facing problems. Enjoy !

Related Topic