Minimum weight to Checkout

In the official osCommerce Forum, Paul asks;

… I need to prevent any customer that has not got a minimum total weight in their cart from proceeding through the checkout; does anyone have any ideas on how this might be achieved most efficiently? I don’t want to be hand-held through making a contribution to do this, I am quite capable of writing the code myself … I realise that I could do this with a shipping module, in fact I have already written three custom shipping modules specifically for this site into which I could insert the checks on the total cart weight, but I am thinking there may be a more efficient way to implement the functionality we require, without having to resort to checking the cart weight from within 3 separate shipping modules.

This is fairly straightforward and my answer was this (as he did not want the code delivered to him on a plate);

checkout_shipping.php … look for $total_weight and “if” it to a tep_redirect

Paul replied;

Thanks for the reply; think I will hack it then … I was hoping I might stumble across a more elegant and reusable solution, but your suggestion will provide the required functionality with minimal changes.

So, more elegant and re-usable…this will make a good blog post for others to read, so let’s do it!

Step 1: Add the admin configuration

Best place for this is in admin > shipping/packaging

Running this piece of SQL code (in PHPMyAdmin) will add another entry in here:

[php]INSERT INTO configuration (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added)
VALUES (‘Enter the Minimum Weight you will ship’, ‘SHIPPING_MIN_WEIGHT’, ‘0’, ‘The minimum weight that you will ship. 0 = unlimited.’, ‘7’, ‘6’, now());[/php]

So that it now looks like this:

Step 2: Configure the minimum weight

Click on the “Enter the minimum weight you will ship” and press the [edit] button. You should see something like this;

As you can see, you should leave this at zero if you wish to allow ANY weight to checkout. If you wish to allow weight above 10 (units of weight), then insert the number 10 here and press [update]. Easy.

Step 3: Add the “check weight” code

Open up checkout_shipping.php and find these lines of code:

[php]$total_weight = $cart->show_weight();
$total_count = $cart->count_contents();[/php]

Right underneath, add this line of code:

[php]if ((SHIPPING_MIN_WEIGHT > 0) && ($total_weight < SHIPPING_MIN_WEIGHT)) tep_redirect(tep_href_link(FILENAME_SHOPPING_CART, 'error_message=' . urlencode(sprintf(ERROR_UNDERWEIGHT_SHIPPING, SHIPPING_MIN_WEIGHT, SHIPPING_MIN_WEIGHT-$total_weight)), 'NONSSL'));[/php] Save the file and upload it. I'll dissect that line of code later on in this blogpost. Step 4: Add the Error Message to the language file

Open up /includes/languages/english.php and add the following line of code:

[php]define(‘ERROR_UNDERWEIGHT_SHIPPING’, ‘The minimum shipping weight is %s kgs. You need to add another %s kgs to be able to checkout.’);[/php]

In this line of code I have assumed that your “unit of weight” that you use in your shop is Kilograms, hence the use of kgs. If you use ounces, change kgs to ounces, if you use grams, change it to grams. Easy enough? Save the file and upload it. Notice the %s used here? I’ll explain that later on.

That is all the changes that is needed.

And the result?

Assuming that your Minimum Shipping Weight is set above zero, then if the total weight of the cart contents is below this setting, an error message will be displayed, somewhat like this:

And if the Minimum Shipping weight is set to zero OR if the Minimum Shipping Weight has been exceeded, then checkout will simply progress as normal.

Wasn’t that easy? And so much quicker than;

a. asking if a contribution exists and waiting hours/days for a reply
b. installing the contribution if it does exist
c. bug testing and fixing the contribution if it’s broken

And, even better, you now know a bit about how osCommerce code works!

Dissecting the Code

[php]if ((SHIPPING_MIN_WEIGHT > 0) && ($total_weight < SHIPPING_MIN_WEIGHT))[/php] If the Minimum Shipping Weight is greater than Zero AND the total weight of the cart contents is less than the Minimum Shipping Weight, then; [php]tep_redirect(tep_href_link(FILENAME_SHOPPING_CART, 'error_message=' . urlencode(sprintf(ERROR_UNDERWEIGHT_SHIPPING, SHIPPING_MIN_WEIGHT, SHIPPING_MIN_WEIGHT-$total_weight)), 'NONSSL'));[/php] Redirect the buyer back to the shopping cart page, and show an error message asking him/her to buy more stuff! This particular piece of code is interesting; [php]sprintf(ERROR_UNDERWEIGHT_SHIPPING, SHIPPING_MIN_WEIGHT, SHIPPING_MIN_WEIGHT-$total_weight)[/php] sprintf allows us to pass parameters to the language definition. If you remember the language definition contianed a couple of %s "commands"...these %s are what is passed through, so in this case, I am saying: Use the ERROR_UNDERWEIGHT_SHIPPING language definition, but pass to it; 1. the SHIPPING_MIN_WEIGHT setting (which is the admin setting above zero) 2. the SHIPPING_MIN_WEIGHT less the total weight of the cart. This allows us to show the buyer, how much more weight he needs to have in his cart to be able to checkout. Easy as 123?

Adding hundreds of items? By hand???

Scott asks;

I’ve got an OSCommerce site … I need to add hundreds of items. Is there a way to simply upload all of them in a spreadsheet of data base of some sort rather than doing each item individually?

Easy Populate: http://www.oscommerce.com/community/contributions,500

Good luck!

Free Shipping Unless Weight is greater than 1kg

John asks;

I’ve hunted high and low and can’t find a solution to this problem. I want to provide free shipping for orders over £20 … but needs to apply a charge if the total weight exceeds 1kg. Is there a way to do this – or a contribution that can be used to do this.

The simplest way to do this is to enable the shipping order_total module to over-ride all of your shipping modules if the amount of the order is greater than £20. This is easy, follow this previous blog post of mine.

However, you also need to disable this if the weight of the order exceeds 1kg. Easy!

Open up checkout_shipping.php and add this code:

[php]if ($total_weight > 1) $free_shipping = false;[/php]

Right underneath this existing code:

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

include(DIR_WS_LANGUAGES . $language . ‘/modules/order_total/ot_shipping.php’);
}
} else {
$free_shipping = false;
}[/php]

That is it!

Deconstructing the new code

[php]if ($total_weight > 1)[/php]

$total_weight is a variable that is set to the weight of the cart contents. This is set up at line 61 of the standard checkout_shipping.php file;

[php]$total_weight = $cart->show_weight();[/php]

We are simply asking if $total_weight is greater than 1. 1 in this case being 1kg. If this is true, then:

[php]$free_shipping = false;[/php]

Completely obvious – set the $free_shipping to false! This is then used later on in the same file to determine whether or not the order_total module should over-ride your installed shipping modules (or not).

Easy as 123. If you can avoid using a contribution to do something, it is always preferable to do so. After all, the addition of this one line of code;

[php]if ($total_weight > 1) $free_shipping = false;[/php]

is surely simpler than finding and installing a contribution, and is surely simpler than amending all your installed shipping modules.

Find the value of your stock

Some people (myself included) use osCommerce as a stock-keeping program as well as a e-commerce sales program. There are drawbacks to doing it this way (eg, lack of “nice” reports, accountancy etc), but it’s certainly do-able.

A question in the official osCommerce forum went like this;

I need a simple bean counting script that will give me a total cash value of all in stock inventory…I have over 6000 items in stock – so I would rather not do it by hand…

Now, me not being a great whiz at Maths, guessed that the user needed to know the product_quantity multiplied by the product_price (per product of course). This is rather easy and goes like this;

[php]SELECT sum(`products_quantity` * `products_price`)
FROM `products`[/php]

This give the total value of all the product quantities you have in store, as shown;

Then I decided that this would be more useful to only show products that have a quantity greater than zero. After all, depending upon how you have your store set up it’s possible you have negative value quantities (over-sold products) – this would obviously skew the results terribly.

So, the new code looks like this:

[php]SELECT `products_id`, sum(`products_quantity` * `products_price`) AS total
FROM `products`
WHERE `products_quantity` > 0
GROUP BY `products_id`[/php]

Now the output looks like this;


(Note that I cut the graphics off, but it shows the value of each product individually)

From the two pieces of code above, I am sure that you can make different code to suit your needs. MySQL can be complicated to understand, but if you hunt Google there are loads of tutorials showing all sorts of cool code. To actually use the code, use PHPMyAdmin (comes standard almost all hosts), click the SQL tab and paste the code into the “Run SQL Query” input box, then press “GO”…

Easy as 123? Maybe not. But fairly easy, for sure.

Traffic Lights for showing Stock in osCommerce

The other day a client approached me about a feature which he had seen on a store (not an osCommerce store). To cut a long story short, it showed available levels of stock in a “traffic light” system;

More than 10 on hand = green
Between 2 and 9 = orange
Less than 2 = red

With a bit of thought, I adapted a previous idea of mine, blogged here. And ended up with a good way of showing what’s in stock, what’s limited etc.

In the Categories structure (index.php)

In the Product page (product_info.php)

In the New Product listing (prodcuts_new.php)

Let’s say I want to show traffic lights in the “New Products for Month” box

I open up /includes/modules/new_products.php and add this:

[php]
‘ . clubosc_products_stock((int)$products_new[‘products_id’]) . ‘[/php]

Right after:

[php]’ . $new_products[‘products_name’] . ‘[/php]

So now instead of looking like this:

It looks like this:

Function this, function that

Because I used a function to “power” this, it is really easy to change – so let’s say the shop owner wanted to change the word “Available” (green traffic light) to “We got loads, buy now!”, he can just go to 1 file (includes/languages/english.php), change it and this will be reflected on ALL the pages that show the “traffic lights” – meaning the shop owner doesn’t have to change lots of files. Good, eh?

Making a Test Mirror Site for osCommerce

Barbara asks;

I was asked to transfer the oscommerce site I’ve been working on to a different server and to create a “test mirror site”, where we could change pages, change PRODUCTS and get ready for a new season, so that they could test it and see the new version of the site live and when the right day came we could just switch the mirror for the live site. Any idea how this could be done? Or how easily? Do I need to set up different versions of the site in different databases? Can I just have a copy and have different products on each one?

OK – fairly easy. You need to be aware that osCommerce might work well on one server and totally fail on another – all depends upon the server software…that said;

Option 1. Buy a (temporary) domain name and new hosting

Would be the best way to test changes on a new server. Once the changes are complete, simply “park” the real domain on top of the temporary domain and update the two configure.php files from the temprary to the new domains. Downside = cost of domain name. You’d need to buy hosting on the new server anyway so that is not an issue.

Option 2. Run your new site in a folder/directory on your existing webpace

Not really a great option as it would be so easy to mix up the two sites.

Option 3. Run your new site offline on your computer

This is the option that EVERY person who runs osCommerce should be doing anyway – it’s super simple to set up. Basically, you create a mirror of your existing site to run offline. A good thing in case anything happens to your live site. At the same time you can also create your new site offline and save it onto a USB flash card for example to show your client…

A picture is worth 1000 words…basically you are running two stores (or three, or four, etc) – 1 is live on your webhosting, the other(s) are all on your home computer. You can find this package at oscbooks.com – I am running this exact same setup and at present I have 49 seperate osCommerce shops running on my computer, along with 49 MySQL databases. All working well…

Obviously, when the site is completed, you then upload to your new website hosting on your new server. Easy as 123.

Show Shipping Method elsewhere on invoice.php

In the standard osCommerce invoice page, the shipping method and cost is shown in the order_totals, as below;

You can see that this order used “Flat Rate (Best Way)”…

On the official osCommerce forum, Tony asked;

I wish to add the shipping/postal method selected during checkout as part of the delivery label. Does anybody know the code to do this?

I am using integrated label paper (the paper with a sticker attached which I peel off with the delivery address) and have got everything else I want to display on the label (OID, Shipping Address, Return Address).

My answer was;

Stored in order_totals table of database, so easiest way would be to create a function that gets the value of text based on order_id and ot_shipping. Sounds complicated but should be straightforward once you dig in.

The asked found a solution, but it’s a horrible way;

[php]for ($i = 0, $n = sizeof($order->totals); $i < $n; $i++) { if ($order->totals[$i][‘code’] == ‘ot_shipping’) {
$myshipping = $order->totals[$i][‘title’];
}
}
echo $myshipping;[/php]

Which is iterating through all the order_totals in order to match “ot_shipping” and then display it. OK, so, it works fine and is not causing much overhead. But so ugly!

Here’s a piece of code I just cooked up which gets the shipping method;

Step 1. Add this to /admin/includes/functions/general.php

[php]function clubosc_get_shipping_method($oID) {
$shipping_query = tep_db_query(“select title from ” . TABLE_ORDERS_TOTAL . ” where class=’ot_shipping’ AND orders_id = ‘” . (int)$oID . “‘”);
$shipping_value = tep_db_fetch_array($shipping_query);
return substr($shipping_value[‘title’], 0, -1);
}[/php]

Step 2. Add this whereever you want in admin/invoice.php

[php][/php]

For this blog post, let’s add it near the “Payment Method” line of text, so do this:

[php]

info[‘payment_method’]; ?>

[/php]

Step 3. Add this to admin/includes/languages/english/invoice.php

[php]define(‘ENTRY_SHIPPING_METHOD’, ‘Shipping Method:’);[/php]

Save all files and upload. This are of your invoice should now look like this:

Easy as 123. Or is it?

Deconstructing the code

[php]function clubosc_get_shipping_method($oID)[/php]
Simply a name, and a variable to pass through.

[php] $shipping_query = tep_db_query(“select title from ” . TABLE_ORDERS_TOTAL . ” where class=’ot_shipping’ AND orders_id = ‘” . (int)$oID . “‘”);
$shipping_value = tep_db_fetch_array($shipping_query); [/php]

Grabbing the correct data from the database. In this case scanning the orders_total table for the text column that has column values of the “order_id” and where the class text is “ot_shipping”.

[php] return substr($shipping_value[‘title’], 0, -1);[/php]

Showing the data on the page, without the ending “:” – this is necessary as the actual textual methos of shipping is “Flat Rate (Best Way):” – obviously we don’t want to show the end colon!

Yes, it is as easy as 123!

osCommerce v3 and Thrashbox

Thrashbox is a css way to create great looking boxes. You can view the homepage and a load of reading material at http://www.vertexwerks.com/tests/sidebox/. Enjoy!

It’s really simple to get this effect into osCommerce, image below;

Look good, don’t they. All you need to do id be using the “default” layout of osc v3 (not the tables based version). Amend each of the template infobox files directly so that they read a bit like this:

Then add the thrashbox .css to the template stylesheet file and save the thrashbox images into the right place in your template file structure. Once you got it done and working, you will want to make your own images to suit the look of your site – simply open up each original thrashbox gif, change it and resave as the same name.

DONE!

Should I use the new v3 osCommerce?

Ellie asks;

…finally version 3 of osc is available, so should I upgrade my existing store?

That’s kind of a tough question, as the new v3 osCommerce is much better than previous versions of osCommerce. It’s leaner, meaner and faster. The codebase is changed a lot from the previous versions…

However, this update has caused problems, almost all (if not ALL) contributions will not work with the new version. In addition, the templating system being used is not at all straightforward, so it will be very difficult to change the default install to match whatever your store looks like now (assuming it’s not “out of the box” osCommerce already)…

So, my advice:

Avoid v3 of osCommerce until some of the more important contributions have been updated!