Automatic Coupon Code for Existing Buyers (via admin/invoice.php)

Chris writes;

Love the GV DC contribution. Except that my boss wants a 15% coupon that will expire in 30 days attached to each invoice that goes out of here. Any ideas/help on adding:
Random code generator for the codes.
Adding a date field to the coupon.
Checking the date before the coupon is processed.
Automatically generating the code upon Invoice printing

This is quite a departure from how the Coupon System works, but is doable. Here’s how;

Step 1: Upgrade to Version 5 of the Coupon System.

Doing this means that these items are taken care of;

Adding a date field to the coupon.
Checking the date before the coupon is processed.

Step 2: Add Coupon Creation code to admin/invoice.php

This file needs to create a randomly named coupon, good for the next 30 days (from date of purchase). A little lateral thinking enabled me to make an “insert into” line that;

1. Creates a coupon using a random name (invoice_id-5_random_characters), eg; 10-rteop
This meant utilising the tep_create_random_value function, easy enough.
2. Makes the coupon a “single use” coupon good for 1 order only.
This is a standard setting in Version 5 of coupons
3. Makes the expiry date 30 days from the date of purchase.
Expiry dates are standard in V5 – I had to use the mysql interval to add 30 days onto it, fairly straightforward.
4. Make the Coupon 15%
Percentage Coupons are standard in all versions of the Coupon Mod

Step 3: Attach the Coupon Code to the Order / Invoice

The previous step (#2) was fairly straightforwad, but I then had to somehow attach the Coupon Code to the order. The easiest way to do this was simnply to add a new column to the DB order table to hold the Random Coupon Code. I just made a has_voucher varchar 32 to hold the details. Then I enclosed the code in the previous step inside a tep_not_null(has_voucher) to determine whether a coupon should be made or not.

Step 4: Add the Coupon Details to the Invoice

Easy. A simple echo with the relevant details, looks like this;

This means that the Invoice they receive in the post (or by email) from you, has the Coupon Code on it, and that Coupon Code is ready for use straightaway.

And here is the Coupon ready to be used;

All of the above works, both in theory and in practice. However, the code base is ugly! For production release it needs refining and that takes money and time.

Conclusion

A great way to get repeat business is to offer existing buyers a discount on their next order. By setting a 30 day expire on the coupon it entices buyers to buy as quicly as possible. Each and every time they order, their Invoice will create a new coupon code for them to use next time.

Free Shipping for Zero Weight Products

The other day I installed my Coupon Discount module on a site and all went smoothly. As I offer Tech Support on the module, the shop owner contacted me a few days later to ask if it was possible that my installation of Coupons has caused his “free shipping” to stop working.

I was sure it had not, as my coupon module doesn’t touch any shipping modules, so couldn’t see how, but I made some investigations anyway. It turns out that the shop owner was using some system of “hard coding” free shipping if the total weight of the order was zero…which is an OK way to do things if it is done right.

In this case, what was happening was something like (in the checkout_shipping page);

IF the total weight of the order is ZERO, then;
DON’T show any shipping modules
DO show the words “you’ve qualified for free shipping”

The problem here is that the system is expecting the buyer to actually select a shipping method – but as the modules were not showing, it was impossible to select anything, hence the checkout_payment page was redirecting back to checkout_shipping. What the shop owner had neglected to do was instantiate a “free” shipping method (to go along with the words “free shipping”).

So, I emailed back to let the shop owner know the problem. My advice was to scrap all teh nonsense code that he already was using for “free” shipping, and do something different…

Ideas, ideas

My first idea was to amend each shipping method to add in a “zero price” for “zero weight” – which would have worked great – but would have given the buyer the opportunity to select 1 of a number of shipping methods (all zero priced). That would have looked unprofessional.

My next idea was to amend the shipping order_total module to give free shipping if the weight is zero. At present this order_total module works only on “price”, but it should be easy to add in an extra weight system to it…

Step 1: to amend the order_total module to add in an extra box to allow weight based instantiation. Easy enough, turn off the module, find the following functions (keys, install, remove) at the bottom of the file, and replace with the following;

[php]function keys() {
return array(‘MODULE_ORDER_TOTAL_SHIPPING_STATUS’, ‘MODULE_ORDER_TOTAL_SHIPPING_SORT_ORDER’, ‘MODULE_ORDER_TOTAL_SHIPPING_FREE_SHIPPING’, ‘MODULE_ORDER_TOTAL_SHIPPING_FREE_SHIPPING_OVER’, ‘MODULE_ORDER_TOTAL_SHIPPING_FREE_SHIPPING_WEIGHT_UNDER’, ‘MODULE_ORDER_TOTAL_SHIPPING_DESTINATION’);
}

function install() {
tep_db_query(“insert into ” . TABLE_CONFIGURATION . ” (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values (‘Display Shipping’, ‘MODULE_ORDER_TOTAL_SHIPPING_STATUS’, ‘true’, ‘Do you want to display the order shipping cost?’, ‘6’, ‘1’,’tep_cfg_select_option(array(\’true\’, \’false\’), ‘, now())”);
tep_db_query(“insert into ” . TABLE_CONFIGURATION . ” (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values (‘Sort Order’, ‘MODULE_ORDER_TOTAL_SHIPPING_SORT_ORDER’, ‘2’, ‘Sort order of display.’, ‘6’, ‘2’, now())”);
tep_db_query(“insert into ” . TABLE_CONFIGURATION . ” (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values (‘Allow Free Shipping’, ‘MODULE_ORDER_TOTAL_SHIPPING_FREE_SHIPPING’, ‘true’, ‘Do you want to allow free shipping?’, ‘6’, ‘3’, ‘tep_cfg_select_option(array(\’true\’, \’false\’), ‘, now())”);
tep_db_query(“insert into ” . TABLE_CONFIGURATION . ” (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, use_function, date_added) values (‘Free Shipping For Orders Over’, ‘MODULE_ORDER_TOTAL_SHIPPING_FREE_SHIPPING_OVER’, ’50’, ‘Provide free shipping for orders over the set amount.’, ‘6’, ‘4’, ‘currencies->format’, now())”);
tep_db_query(“insert into ” . TABLE_CONFIGURATION . ” (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, use_function, date_added) values (‘Free Shipping For Weight Under’, ‘MODULE_ORDER_TOTAL_SHIPPING_FREE_SHIPPING_WEIGHT_UNDER’, ‘0’, ‘Provide free shipping for orders of this weight and below.’, ‘6’, ‘4’, ”, now())”);
tep_db_query(“insert into ” . TABLE_CONFIGURATION . ” (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values (‘Provide Free Shipping For Orders Made’, ‘MODULE_ORDER_TOTAL_SHIPPING_DESTINATION’, ‘both’, ‘Provide free shipping for orders sent to the set destination.’, ‘6’, ‘5’, ‘tep_cfg_select_option(array(\’national\’, \’international\’, \’both\’), ‘, now())”);
}

function remove() {
tep_db_query(“delete from ” . TABLE_CONFIGURATION . ” where configuration_key in (‘” . implode(“‘, ‘”, $this->keys()) . “‘)”);
}[/php]

Step 2: I opened up checkout_shipping.php and changed this:

[php]if ( ($pass == true) && ($order->info[‘total’] >= MODULE_ORDER_TOTAL_SHIPPING_FREE_SHIPPING_OVER) ) {[/php]

To this:

[php]if (($pass == true)&&($order->info[‘total’] >= MODULE_ORDER_TOTAL_SHIPPING_FREE_SHIPPING_OVER)||($cart->show_weight() <= MODULE_ORDER_TOTAL_SHIPPING_FREE_SHIPPING_WEIGHT_UNDER)) {[/php] And that was about it, as far as I recall. If you try it, and it does not work, let me know so that I can go back through my code to see if I had to make any extra changes...

FAQ: Weight calculation is too much – TARE

This question (and variations thereof) have been asked a thousand times in the osCommerce forum…

I set nup my shipping rates to charge $1 per kilogram. My product weighs 2kgs, and it’s charging $5. Why?

For starters, forget Kilograms or pounds/ounces etc. Weights in osCommerce are measured un “units” – and 1 unit can be anything you like. Pounds, ounces, gram, kilograms, magic beans…ok, so once you got that, read on…

The answer is TARE.

Tare weight, sometimes called unladen weight, is the weight of an empty vehicle or container.

Read more at Wikipedia. In osCommerce Tare is automatically set up to 3 (units of weight) when the shop is first installed. It’s one of those settings that most Store Owners know nothing about, and is always, repeat ALWAYS the cause of questions that should never be asked…

How to change the TARE

Enter the admin section of your shop, and go configuration > shipping/packaging – you’ll find this:

Play with the three settings “Enter the maximum weight”, “Package Tare Weight” and “Larger packages % increase”.

I usually have those three settings as; 100, 0, 0 in that order. Which means the largest packet I will post is 100kgs, and this is worked out by the usual shipping modules. I add on zero units of weight for postage and packing costs, and I add on zero% charge for larger packages.

When should you use the Tare feature/setting?

If you sell things that always use the same size packaging, eg, a cardboard box, then you could simply insert the weight of the box in the Tare setting. Any weight that is Tare weight, will simply be added to the total weight of actual products ordered.

Of course, using the Tare weight setting also rather depends upon using a system of shipping based around weight! No point setting this up only to then base your shipping prices on dollar value of purchase (for example!).