Skip to main content
page last edited on 13 March 2017

Creating global discount

Version: 5.4 and early

Introduction

This article teaches X-Cart developers how they can create discounts via custom module. For the sake of example, we will show how to create a straight-forward 10% discount to order subtotal.

Video tutorial

Video showing the process of creating the module for X-Cart 5.1.x:

Implementation

We start with creating an empty module. We create the module with developer ID XCExample and module ID DiscountDemo.

You can create a discount in X-Cart by extending the \XLite\Logic\Order\Modifier\Discount class. The \XLite\Logic\Order\Modifier type of class defines different types of order surcharges, e.g. shipping, taxes, discounts, etc. We use one that is typical discount: \XLite\Logic\Order\Modifier\Discount.

We create classes/XLite/Module/XCExample/DiscountDemo/Logic/Order/Modifier/Discount.php file with the following content: 

<?php

namespace XLite\Module\XCExample\DiscountDemo\Logic\Order\Modifier;

class Discount extends \XLite\Logic\Order\Modifier\Discount
{
const MODIFIER_CODE = 'DISCOUNT';

protected $type = \XLite\Model\Base\Surcharge::TYPE_DISCOUNT;

protected $code = self::MODIFIER_CODE;

public function calculate()
{
$surcharge = null;
$discount = $this->getOrder()->getSubtotal() * 0.1;
$surcharge = $this->addOrderSurcharge($this->code, $discount * -1);
$this->distributeDiscount($discount);
return $surcharge;
}
}

Let us have a closer look at this class' code.

  1. The code below defines that this order modifier is a discount and the surcharge value should be aggregated into single Discount line in order totals: 

    const MODIFIER_CODE = 'DISCOUNT';

    protected $type = \XLite\Model\Base\Surcharge::TYPE_DISCOUNT;

    protected $code = self::MODIFIER_CODE;
  2. calculate() method is the most important part of this class. It defines the routine of calculating discount and applying it to the order object. This method will be called in the calculate() method of the \XLite\Model\Order object in this foreach()

    foreach ($this->getModifiers() as $modifier) {
    if ($modifier->canApply()) {
    $modifier->calculate();
    }
    }
  3. Note: our mod does not use it, but you can define canApply() method in your class in order to define whether this modifier must be applied or not.

  4. Let us get back to our implementation of calculate() method. First we calculate the discount value: 

    $discount = $this->getOrder()->getSubtotal() * 0.1;

    and then we apply this discount to the order as a negative value

    $surcharge = $this->addOrderSurcharge($this->code, $discount * -1);

    We get the $surcharge object as a result, which will be returned as a result of calculate() method.

  5. Final step is we distribute the discount value across all order items in the cart: 

    $this->distributeDiscount($discount);

That is it with discount class.

Now we need to register this order modifier in X-Cart and for that purpose we create the classes/XLite/Module/XCExample/DiscountDemo/install.yaml file with the following content: 

XLite\Model\Order\Modifier:
- { class: '\XLite\Module\XCExample\DiscountDemo\Logic\Order\Modifier\Discount', weight: 100 }

This way we tell X-Cart that our class described above must be registered as order modifier with weight 100. The higher the weight, the later this order modifier will be run in foreach() of bullet-point 3.

Note: if you want to check all currently registered order modifiers, you can pull this info from the xc_order_modifiers MySQL table.

Once our install.yaml file is ready, we need to push it to the database. After that re-deploy the store and check the results: add any product to a cart and go to cart page. You will see a discount applied there:

Module pack

You can download this module's pack from here: XCExample-DiscountDemo-v5_3_0.tar

Attachments: