Coupons in Magento – Part 1

5 minute read

Let me preface this by stating that the company I work for is very unusual in how it uses coupons. I won’t go into details, but I don’t know of many other online merchants that have the same requirements for coupons as we do.

I’m breaking this post up into two posts. The first post will deal with using direct database inserts into the salesrule table to load coupons. The second will deal with using a custom script or module that makes use of Mage code to populate the salesrule/rule objects and persist them to the database usng $model->save() or $collection->save();

Before I continue, if I had a lawyer they’d probably make me add something like the following:

  • WARNING: Any use of the following is at your own risk. It is not recommended or supported by Varien (or me for that matter). This post is provided for informational purposes only.

There, now that is out of the way we can move on to some content. Coupons (sales promotions/shopping cart rules hereafter referred to simply as coupons) in Magento are a curious beast. For some reason, Varien has provided no built-in way to import/export promotions. They’ve left this for us developers to figure out. I’m a developer. I like to know how things work “under the hood” so that’s perfectly ok with me.

Looking through the code to see where Magento stores the underlying data for a sales rule we find that the data to support a coupon is stored in two tables. The first table is the salesrule table. This table holds the definition of the coupon and how it functions. The second table is the salesrule_label table. This table holds the text that is displayed in the cart next to the discount amount. The reasoning for this separate table is that Magento allows you to have different labels for each store (not really sure how this would be useful, nevertheless, it’s there). For the purposes of this post, we are only going to focus on the salesrule table as the salesrule_label table should be fairly simple to handle on your own (again, see the legal mumbo-jumbo above).

For the most part, the fields in the salesrule table directly relate to fields on the edit screen in the admin:

  • name
  • description
  • from_date
  • to_date
  • coupon_code
  • uses_per_coupon
  • uses_per_customer
  • is_active
  • stop_rules_processing
  • is_advanced
  • sort_order
  • simple_action
  • discount_amount
  • discount_qty
  • discount_step
  • simple_free_shipping
  • apply_to_shipping
  • is_rss
  • times_used

These 4 fields should be fairly obvious.

  • rule_id – Autogenerated id number
  • customer_group_ids – comma delimited list of customer group ids
  • product_ids
  • website_ids – the website id this rule applies to

These 2 are special cases. They are serialized arrays for the condition rules and the action rules.

  • conditions_serialized
  • actions_serialized

The difference between conditions and actions is a little misleading. Conditions can be used to exclude certain transactions from the coupon being used (it’s not limited to exclusions, but it’s also not necessarily needed for a coupon to be effective). Actions are what you use to define the criteria used to apply the coupon to an order.

If you’re like me, I know you are dying for a sample. So without further ado. The below script will insert a coupon with code CPN1234 that will set the price of a product with SKU number SKU-1234 for $14.99. Most of it should be fairly explanatory (if not, let me know in the comments and I’ll update the post with an explanation).

<figcaption></figcaption>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
<span class="line"><span class="x">require_once('app/Mage.php');</span>
</span><span class="line"><span class="x">// Instantiate Mage</span>
</span><span class="line"><span class="x">Mage::app('default');</span>
</span><span class="line"><span class="x">// Status logging</span>
</span><span class="line"><span class="x">Mage::log('Beginning Coupon Import', null, 'coupons.log');</span>
</span><span class="line"><span class="x">// Get a connection to the database using Mage</span>
</span><span class="line"><span class="x">$w = Mage::getSingleton('core/resource')->getConnection('core_write');</span>
</span><span class="line"><span class="x">require_once('app/Mage.php');</span>
</span><span class="line"><span class="x">// Instantiate </span>
</span><span class="line"><span class="x">MageMage::app('default');</span>
</span><span class="line"><span class="x">// Status logging</span>
</span><span class="line"><span class="x">Mage::log('Beginning Coupon Import', null, 'coupons.log');</span>
</span><span class="line"><span class="x">// Get a connection to the database using Mage</span>
</span><span class="line"><span class="x">$w = Mage::getSingleton('core/resource')->getConnection('core_write');</span>
</span><span class="line"><span class="x">$conditions = array();</span>
</span><span class="line"><span class="x">$ctype = '';</span>
</span><span class="line"><span class="x">$cond = array();</span>
</span><span class="line"><span class="x">$act = array();</span>
</span><span class="line"><span class="x">$cond = array (</span>
</span><span class="line"><span class="x">    'type'=>'salesrule/rule_condition_combine',</span>
</span><span class="line"><span class="x">    'attribute'=>'',</span>
</span><span class="line"><span class="x">    'operator'=>'',</span>
</span><span class="line"><span class="x">    'value' => 1,</span>
</span><span class="line"><span class="x">    'is_value_processed'=>'',</span>
</span><span class="line"><span class="x">    'aggregator'=>'all',</span>
</span><span class="line"><span class="x">    'conditions'=> array()</span>
</span><span class="line"><span class="x">);</span>
</span><span class="line"><span class="x">$act = array (</span>
</span><span class="line"><span class="x">    'type'=>'salesrule/rule_condition_product_combine',</span>
</span><span class="line"><span class="x">    'attribute'=>'',</span>
</span><span class="line"><span class="x">    'operator'=>'',</span>
</span><span class="line"><span class="x">    'value' => 1,</span>
</span><span class="line"><span class="x">    'is_value_processed'=>'',</span>
</span><span class="line"><span class="x">    'aggregator'=>'any',</span>
</span><span class="line"><span class="x">    'conditions'=> array(</span>
</span><span class="line"><span class="x">        'type'=> 'salesrule/rule_condition_product',</span>
</span><span class="line"><span class="x">        'attribute' => 'sku',</span>
</span><span class="line"><span class="x">        'operator' => '==',</span>
</span><span class="line"><span class="x">        'value' => 'SKU-1234',</span>
</span><span class="line"><span class="x">        'is_value_processed' => ''</span>
</span><span class="line"><span class="x">    )</span>
</span><span class="line"><span class="x">);</span>
</span><span class="line"><span class="x">$insData = array(</span>
</span><span class="line"><span class="x">    'name'=> 'Coupon Name',</span>
</span><span class="line"><span class="x">    'description'=> 'Long description',</span>
</span><span class="line"><span class="x">    'from_date'=> '2010-05-01',</span>
</span><span class="line"><span class="x">    'to_date'=> '2010-05-31',</span>
</span><span class="line"><span class="x">    'coupon_code'=> 'CPN1234',</span>
</span><span class="line"><span class="x">    'uses_per_coupon'=> 1,</span>
</span><span class="line"><span class="x">    'uses_per_customer'=> 1,</span>
</span><span class="line"><span class="x">    'customer_group_ids'=> '0,1,2,3',</span>
</span><span class="line"><span class="x">    'is_active'=> 1,</span>
</span><span class="line"><span class="x">    'conditions_serialized'=> serialize($cond),</span>
</span><span class="line"><span class="x">    'actions_serialized'=> serialize($act),</span>
</span><span class="line"><span class="x">    'stop_rules_processing'=> 0,</span>
</span><span class="line"><span class="x">    'is_advanced'=> 1,</span>
</span><span class="line"><span class="x">    'product_ids'=> ' ',</span>
</span><span class="line"><span class="x">    'sort_order'=> 0,</span>
</span><span class="line"><span class="x">    'simple_action'=> 'to_fixed',</span>
</span><span class="line"><span class="x">    'discount_amount'=> '14.99',</span>
</span><span class="line"><span class="x">    'discount_qty'=> 1,</span>
</span><span class="line"><span class="x">    'discount_step'=> 0,</span>
</span><span class="line"><span class="x">    'simple_free_shipping'=> 0,</span>
</span><span class="line"><span class="x">    'times_used'=> 0,</span>
</span><span class="line"><span class="x">    'apply_to_shipping'=> 0,</span>
</span><span class="line"><span class="x">    'is_rss'=> 1,</span>
</span><span class="line"><span class="x">    'website_ids'=> 1</span>
</span><span class="line"><span class="x">);</span>
</span><span class="line"><span class="x">$rs = $w->query("select rule_id from salesrule where coupon_code='CPN1234';");</span>
</span><span class="line"><span class="x">$rows = $rs->fetchAll();</span>
</span><span class="line"><span class="x">if (count($rows)) {</span>
</span><span class="line"><span class="x">    $w->update('salesrule_label', array(</span>
</span><span class="line"><span class="x">        'label'=>'My Coupon Label'</span>
</span><span class="line"><span class="x">        ), 'rule_id=' . $rows[0]['rule_id'] . ' and store_id=1');</span>
</span><span class="line"><span class="x">        $w->update('salesrule', $insData, 'rule_id=' . $rows[0]['rule_id']);</span>
</span><span class="line"><span class="x">} else {</span>
</span><span class="line"><span class="x">    $w->insert('salesrule', $insData);</span>
</span><span class="line"><span class="x">    $w->insert('salesrule_label', array(</span>
</span><span class="line"><span class="x">        'rule_id'=>$w->lastInsertId(),</span>
</span><span class="line"><span class="x">        'store_id'=>1,</span>
</span><span class="line"><span class="x">        'label'=>'My Coupon Label'</span>
</span><span class="line"><span class="x">    ));</span>
</span><span class="line"><span class="x">}</span>
</span>

</figure>

Categories:

Updated:

Leave a Comment