1

i am doing an updation in an opencart project.we create coupons that will apply a rebate. it is included in checkout page. we are adding this coupon details like coupon code,discount,exp date etc from admin side.but nothing happens on user side. while entering coupon code nothing happens. no reduction in price and also we didn't get any error message.

konsolenfreddy
  • 9,551
  • 1
  • 25
  • 36
Natasha
  • 980
  • 4
  • 16
  • 33

4 Answers4

6

The normal way coupons work does render them as being invalid. The reason is that the dates are a bit awkward. You need to set the start date as being one day before you want to use it and the end date as being one day after. It's weird I know, but that's the way it works, so make sure that the dates are valid for the coupon

Jay Gilford
  • 15,141
  • 5
  • 37
  • 56
3

Just had a similar problem where the coupon was applied successfully but no discount.

Found the issue was due to the way the order total ordering, the 'sub total' needs to come before the 'coupon'.

Feels wrong posting an answer without any code so here is where I did my debugging: catalog/model/total/coupon.php

The $total was 0 so discount was getting reset.

public function getTotal(&$total_data, &$total, &$taxes) {
    if (isset($this->session->data['coupon'])) {
        $this->load->language('total/coupon');

        $this->load->model('checkout/coupon');

        $coupon_info = $this->model_checkout_coupon->getCoupon($this->session->data['coupon']);

        if ($coupon_info) {
            $discount_total = 0;

            if (!$coupon_info['product']) {
                $sub_total = $this->cart->getSubTotal();
            } else {
                $sub_total = 0;

                foreach ($this->cart->getProducts() as $product) {
                    if (in_array($product['product_id'], $coupon_info['product'])) {
                        $sub_total += $product['total'];
                    }
                }
            }

            if ($coupon_info['type'] == 'F') {
                $coupon_info['discount'] = min($coupon_info['discount'], $sub_total);
            }

            foreach ($this->cart->getProducts() as $product) {
                $discount = 0;

                if (!$coupon_info['product']) {
                    $status = true;
                } else {
                    if (in_array($product['product_id'], $coupon_info['product'])) {
                        $status = true;
                    } else {
                        $status = false;
                    }
                }

                if ($status) {
                    if ($coupon_info['type'] == 'F') {
                        $discount = $coupon_info['discount'] * ($product['total'] / $sub_total);
                    } elseif ($coupon_info['type'] == 'P') {
                        $discount = $product['total'] / 100 * $coupon_info['discount'];
                    }

                    if ($product['tax_class_id']) {
                        $tax_rates = $this->tax->getRates($product['total'] - ($product['total'] - $discount), $product['tax_class_id']);

                        foreach ($tax_rates as $tax_rate) {
                            if ($tax_rate['type'] == 'P') {
                                $taxes[$tax_rate['tax_rate_id']] -= $tax_rate['amount'];
                            }
                        }
                    }
                }

                $discount_total += $discount;
            }

            if ($coupon_info['shipping'] && isset($this->session->data['shipping_method'])) {
                if (!empty($this->session->data['shipping_method']['tax_class_id'])) {
                    $tax_rates = $this->tax->getRates($this->session->data['shipping_method']['cost'], $this->session->data['shipping_method']['tax_class_id']);

                    foreach ($tax_rates as $tax_rate) {
                        if ($tax_rate['type'] == 'P') {
                            $taxes[$tax_rate['tax_rate_id']] -= $tax_rate['amount'];
                        }
                    }
                }

                $discount_total += $this->session->data['shipping_method']['cost'];
            }

            // If discount greater than total
            if ($discount_total > $total) {
                $discount_total = $total;
            }

            $total_data[] = array(
                'code'       => 'coupon',
                'title'      => sprintf($this->language->get('text_coupon'), $this->session->data['coupon']),
                'value'      => -$discount_total,
                'sort_order' => $this->config->get('coupon_sort_order')
            );

            $total -= $discount_total;
        }
    }
}
John Magnolia
  • 16,769
  • 36
  • 159
  • 270
1

Following on from John's answer... In catalog/model/total/coupon.php I swapped out

// If discount greater than total
if ($discount_total > $total) {
    $discount_total = $total;
}

For:

// If discount greater than total
if ($coupon_info['type'] == 'F' && $discount_total > $subtotal) {
    $discount_total = $subtotal;
}

Hope no one else ever has to debug this one!!!

Derek Nolan
  • 744
  • 5
  • 11
0

Expanding on Jay's answer...

If it is the date problem, it is because OpenCart wants the coupon to be greater/less than (not equal to) the date

Open /catalog/model/checkout/coupon.php

First function should be getCoupon

Find this line:

$coupon_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "coupon WHERE code = '" . $this->db->escape($code) . "' AND ((date_start = '0000-00-00' OR date_start < NOW()) AND (date_end = '0000-00-00' OR date_end > NOW())) AND status = '1'");

Change date_start < NOW() to date_start <= NOW()

And date_end < NOW() to date_end <= NOW()

resulting in:

$coupon_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "coupon WHERE code = '" . $this->db->escape($code) . "' AND ((date_start = '0000-00-00' OR date_start <= NOW()) AND (date_end = '0000-00-00' OR date_end >= NOW())) AND status = '1'");
CarpeNoctumDC
  • 1,760
  • 1
  • 12
  • 16