Shipping quote world map update

January 28th, 2011
Old world map - a lot of red

Old world map - a lot of red

Adding Laos (article soon) to the shipping origins in the spider.my data meant I had to update a few things at spider.my – among them the shipping world map. The old shades of red were looking a bit dull, so I used java.awt.Color’s HSVtoRGB() method to map shipping prices onto a range of hues.

The map is very useful for quickly showing if some rates are missing when I update a shipping method. It’s obvious from the Laos Entreprise des Postes Lao EMS map that I’ve only included countries they’ve explicitly listed on the rear of the sheet I got from them in Vientiane.

New colours - Pos Malaysia Air Parcel 6kg

New colours - Pos Malaysia Air Parcel 6kg

Less clear is the fact that the Vietnam rates were missing from the Pos Air Parcel map. It’s easier to see in the large version linked from the thumbnail at right. The technique I use for updating the shipping rates uses the specified “Maximum weight” from Pos’ website. For Vietnam (I think it’s only that one) their rates calculator gives a maximum weight of 20kg for Air Parcel, but then only gives prices up to 10kg! A little bit of defensive coding now copes with that particular oddity, and spider.my will give quotes for Vietnam (they were missing due to my code failing with an error for Vietnam).

I’ve retained the ‘gamboge’ colouring for rejected shipping quotations. You can see in the large Pos Malaysia Air Parcel 6kg map that Nepal is coloured gamboge: Pos Malaysia’s Maximum Weight for Air Parcel to Nepal is 5kg.

Laos Post EMS 0.5kg - zone pricing obvious

Laos Post EMS 0.5kg - zone pricing obvious

I think the new price spectrum makes it a little more obvious where the expensive shipping destinations are. Let me know what you think. If you really need a gigantic version of one of the shipping world maps – for a teeshirt, tea towel, duvet cover, mouse mat, whatever – let me know and I’ll send you the intermediate SVG file so you can print it as large as you like.

Spider.my shipping module for osCommerce / Zen Cart v0.4

January 27th, 2011

These shipping modules have been at Shipping-Quote.net since 2011. Download them from there.

A fairly minor release this one, a little bit of tidying up to remove differences from the osCommerce and Zen Cart modules, but also a couple of changes you should know about:

Small packet methods

Prior to v0.4, small packet methods were added onto the list of methods the module would give quotations for. That produced a weird behaviour where a customer with a lightweight order being delivered by Pos Laju would see two quotations: a cheap one by Pos Laju Document and a more expensive one by Pos Laju Parcel. I was asked if I could make it so that only the small packet option would appear for small packets, so the v0.4 behaviour is to give quotations for only those methods listed in the ‘small packet methods’ admin settings.

This change makes the module simpler and also more robust. You can re-create the old behaviour by adding all the methods from your ‘postal methods’ setting to the small packet methods setting. Note that if you install this version and don’t change your settings, your customers may see fewer shipping options at the checkout than you would wish them to.

Module reports referring page to spider.my

This is a change that is invisible to the shop-owner. Spider.my receives some information about the shop using the module whenever a quotation is requested. All web services receive these basic kinds of information. When your shop requests a quotation, spider.my ‘knows’ the IP address of shop’s webserver. It ‘knows’ the postal origin, destination and weight of the order.

A webserver usually (but not always) ‘knows’ what kind of software requested information. When you look at a web-page, your web-browser ‘tells’ the webserver that you are using ‘Firefox’, ‘Safari’, ‘Opera’ etc. The spider.my shipping module reports its User-Agent (that’s the standard name for this piece of information) as something like “Spider.my shipping module v0.4osCommerce”.

A further piece of information which is commonly sent by your web browser to a website is the address of the page on which you clicked to request the next item of information (or on which an image appears, for example). This referring page is sent by your browser to a webserver as the ‘Referer’ (it’s spelled wrong by standard). From v0.4, the spider.my shipping module sends back a ‘Referer’ telling spider.my which page the shipping quotations appeared on. It’ll commonly look something like “myonlineshop.example.com/checkout_shipping.php” – the shipping options page at your checkout, if your shop is called “myonlineshop.example.com”.

Version reporting

One last minor change in v0.4 is that the version number of the shipping module you are using will be visible in the description of the shipping module when you select it in the Admin panel of your osCommerce / Zen Cart shop. That’s an easy way to tell if your shipping module is up to date.

Spider.my shipping modules v0.3 for osCommerce, Zen Cart (Pos Malaysia)

January 19th, 2011

Updates are coming a bit fast at the moment as various shortcomings are identified and a bugs squashed. The modules are only a few days old, but I’ve rushed them out in the wake of Pos Malaysia’s website changes breaking the old modules.

osCommerce / Zen Cart shipping admin

osCommerce / Zen Cart shipping admin

ISO 3166-2 locations / ‘local’ shipping

The v0.3 modules come without an ISO 3166-2 id specified by default, so will work ‘out of the box’ on a shop without the iso_3166_2 column added to the zones table. The shipping module won’t be able to give local shipping quotes until the db is modified and the field filled in.

Handling charge / Method surcharge

The ‘Handling charge’ field has gone, replaced by ‘Method surcharge’. A shop that wants to give their customers more than one shipping option may need to apply different surcharges per option. This field accepts a comma-separated list of method name:surcharge pairs.

Surcharge per order or per box

The surcharge may be applied once per order or once per box for large orders. For example, if you had to deliver 4 boxes of 20kg each and it was as straightforward for you as it was to ship one box, select ‘per order’. If, for example, you had to buy documents / insurance separately for each box, you would select ‘per box’. Select as appropriate for your business. This may be another field that needs to be ‘per method’: I’m open to suggestions.

Set up Malaysian ISO 3166-2 zones for osCommerce / Zen Cart

January 19th, 2011

The standard ‘zones’ facility of osCommerce has an attribute ‘zone_code’ which at first glance looks as though it might support a standardised shipping quotation system, but osCommerce comes with a database populated with zone codes that are not at all standard. The kinds of codes that are present in the database are what a person who likes abbreviating things might write on an envelope, such as ‘NY’ for New York or ‘KL’ for Kuala Lumpur (or Kirkby Lonsdale).

The default data is completely unsuited to automated shipping quotations, so I recommend you add the ISO standard ISO 3166-2 data to your zones table. The spider.my shipping quotation API will only work with ISO 3166 codes, so unless your data complies with that standard you won’t be able to use the spider.my API.

The changes to the back-end database shown here will (unless you make a mistake and type something else entirely) have no effect on the normal operation of your shop. The changes are purely to add extra information needed for any external or future service that requires standard ISO 3166-2 zones. Note that you cannot just change the existing ‘zone_code’ as osCommerce (and possibly others) uses the zone code to print addresses. As far as I know, the postman will not recognise ‘MY-14’ on an address label.

Add ISO 3166-2 zones to a fresh (no customer addresses) osCommerce / Zen Cart

Here is some SQL that will do the job on a freshly installed osCommerce. IMPORTANT! If your osCommerce installation already has customers using Malaysian zones you have set up yourself, I recommend you execute only the first ‘ALTER TABLE’ line and use a tool like phpMyAdmin to add the values for the iso_3166_2 column by hand. If you run the full set of commands below on an already populated database, you will corrupt your customer / delivery address book.

ALTER TABLE zones ADD COLUMN iso_3166_2 varchar(6);
SELECT @cid:=countries_id from countries where countries_name = 'Malaysia' limit 1;
DELETE FROM zones WHERE zone_country_id = @cid and iso_3166_2 is null;
INSERT INTO zones (zone_country_id, zone_code, zone_name, iso_3166_2) VALUES (@cid,'Johor','Johor','MY-01');
INSERT INTO zones (zone_country_id, zone_code, zone_name, iso_3166_2) VALUES (@cid,'Kedah','Kedah','MY-02');
INSERT INTO zones (zone_country_id, zone_code, zone_name, iso_3166_2) VALUES (@cid,'Kelantan','Kelantan','MY-03');
INSERT INTO zones (zone_country_id, zone_code, zone_name, iso_3166_2) VALUES (@cid,'KL','Kuala Lumpur','MY-14');
INSERT INTO zones (zone_country_id, zone_code, zone_name, iso_3166_2) VALUES (@cid,'Labuan','Labuan','MY-15');
INSERT INTO zones (zone_country_id, zone_code, zone_name, iso_3166_2) VALUES (@cid,'Malacca','Malacca','MY-04');
INSERT INTO zones (zone_country_id, zone_code, zone_name, iso_3166_2) VALUES (@cid,'Negeri Sembilan','Negeri Sembilan','MY-05');
INSERT INTO zones (zone_country_id, zone_code, zone_name, iso_3166_2) VALUES (@cid,'Pahang','Pahang','MY-06');
INSERT INTO zones (zone_country_id, zone_code, zone_name, iso_3166_2) VALUES (@cid,'Penang','Penang','MY-07');
INSERT INTO zones (zone_country_id, zone_code, zone_name, iso_3166_2) VALUES (@cid,'Perak','Perak','MY-08');
INSERT INTO zones (zone_country_id, zone_code, zone_name, iso_3166_2) VALUES (@cid,'Perlis','Perlis','MY-09');
INSERT INTO zones (zone_country_id, zone_code, zone_name, iso_3166_2) VALUES (@cid,'Putrajaya','Putrajaya','MY-16');
INSERT INTO zones (zone_country_id, zone_code, zone_name, iso_3166_2) VALUES (@cid,'Sabah','Sabah','MY-12');
INSERT INTO zones (zone_country_id, zone_code, zone_name, iso_3166_2) VALUES (@cid,'Sarawak','Sarawak','MY-13');
INSERT INTO zones (zone_country_id, zone_code, zone_name, iso_3166_2) VALUES (@cid,'Selangor','Selangor','MY-10');
INSERT INTO zones (zone_country_id, zone_code, zone_name, iso_3166_2) VALUES (@cid,'Terengganu','Terengganu','MY-11');

That’s it. When customers enter a Malaysian address into your shop, they’ll have to choose an existing zone (state), which will enable ISO 3166 -based shipping quotations for your shop (if you install such a shipping module!).

Add ISO 3166-2 zones to osCommerce / Zen Cart when customer addresses exist

The task of adding ISO 3166-2 codes to your zones is more difficult if you already have addresses on your system. If you already have Malaysian zones configured, you can simply modify the zones’ iso_3166_2 column by hand, and your Malaysian customer addresses will qualify for shipping quotes by state.

The most difficult circumstance – one which is likely to apply for any shop that has been in business for any amount of time – is where there are lots of customer address records but no Malaysian state zone records. In this case osCommerce will have been allowing ‘free text’ input to the ‘State/Province’ field. To apply the iso_3166_2 column update in this case requires a great deal of manual effort. Take the following steps:

1. BACKUP YOUR DATABASE!

2. Add the iso_3166_2 column to your zones table:

ALTER TABLE zones ADD COLUMN iso_3166_2 varchar(6);

3. Get the id of Malaysia from the countries table:

select * from countries where countries_name like 'Malaysia%';

4. Find out what zones are already set up for Malaysia. I’m going to use [MYID] for the id found in step 3:

select * from zones where zone_country_id = [MYID];

5. If there are no such zones, use the ‘INSERT’ statements above to create them. If the zones already exist, manually update them so that they show the correct state name and correct ISO 3166-2 code, like:

update zones set zone_name='Malacca', iso_3166_2='MY-04' where zone_id = [Malacca'sZoneID];

6. Now the zones are prepared, check to see how many address entries need updating:

select count(address_book_id) from address_book left join zones on entry_zone_id = zone_id where entry_country_id = [MYID] and zone_id is null;

If this number is larger than about 20, make sure you’re not feeling drowsy before proceeding. What follows is very dull and an error could be catastrophic.

7. Print out the results from step 4, they’ll be handy for reference.

8. What needs to be done is to match up the address book records with the new ISO 3166-2 zones. If you’re lucky, there may be some data (the only shop I have tried this on with many existing customers, this field was blank) in the address book’s entry_state column – start there:

select distinct entry_state from zones where entry_country_id = [MYID];

9. It’ll be obvious which entries are useful here, they’ll be reasonable attempts at entering a state into the address, but maybe wrong case (negeri sembilan), misspelled (Johore), abbreviated (Tereng.) For each useful entry_state value, update the address book like this:

update address_book set entry_state = '[StateName]', entry_zone_id = [ZoneID] where entry_state = '[Step8State]' and entry_country_id = [MYID];

In the above SQL statement, [StateName] and [ZoneID] are read from your cheat sheet printed in step 7. [Step8State] is the distinct value from the results of step 8. So for example, you could fix all addresses whose state line was ‘K.L.’ like this:

update address_book set entry_state = 'Kuala Lumpur', entry_zone_id = [ZoneID] where entry_state = 'K.L.' and entry_country_id = [MYID];

Repeat this step as many times as you have recognisable entries from step 8. When you’ve finished, repeat step 6 to see whether you’ve finished or need a break.

10. If you’re left with only unrecognisable or blank entries in the entry_state field, you’re going to have to use other address parts to see if you can decide which state they’re in. Typing names of villages into Wikipedia can help if you’re not sure. Start with the city:

select distinct entry_city from address_book left join zones on entry_zone_id = zone_id where entry_country_id = [MYID] and zone_id is null;

11. Use your Malaysian city knowledge (and Wikipedia) and your cheat sheet to update each recognisable city similar to step 9:

update address_book left join zones on entry_zone_id = zone_id set entry_zone_id = [ZoneID], entry_state = '[StateName]' where entry_country_id = [MYID] and zone_id is null and entry_city = '[Step10City]';

Repeat this step as many times as you have recognisable entries from step 10. When you’ve finished, repeat step 6 to see whether you’ve finished or need a break.

12. The remaining addresses may be in very bad shape – don’t expect to be able to fix every one. Some may well have been created with no intention of receiving shipments from you, so don’t worry too much about bad addresses. Now to fix the really bad addresses:

select address_book_id, entry_firstname, entry_lastname, entry_street_address, entry_suburb, entry_postcode, entry_city, entry_state from address_book left join zones on entry_zone_id = zone_id where entry_country_id = [MYID] and zone_id is null;

13. For each one with an address you recognise in step 12 and care about linking properly so that local shipping quotations work, do this:

update address_book left join zones on entry_zone_id = zone_id set entry_zone_id = [ZoneID], entry_state = '[StateName]' where entry_country_id = [MYID] and zone_id is null and address_book_id = [AddressBookID];

[AddressBookID] is the id of a single entry in the address book, read from the first column of results from step 12.

14. You have finished a very tedious job. You can repeat step 6 if you like, to see how many irreconcilable entries are left. They’re probably bad records not intended to be delivery addresses.

osCommerce shipping module for spider.my (Pos Malaysia rates) pre-release

January 17th, 2011

The shipping quote API and shipping modules for osCommerce and Zen Cart is now at Shipping-Quote.net

If you’ve been caught out by Pos Malaysia’s recent site updates and now can’t quote for international deliveries from your shop, this module is functional at one Malaysian online shop. Pos Malaysia’s update has come while I’ve been re-vamping the shipping quotation back-end and so I only have Pos Malaysia Air Parcel and Surface Parcel rates online as of 17th Jan 2011.

Spider.my shipping module admin

Spider.my shipping module admin

You can download the new osCommerce shipping module from spider.my. It is only hours old, so may well have some ‘quirks’. It’s a significant improvement over no shipping calculations at all, so give it a spin and I’ll do my best to attend quickly to any problems you find in the module.

The config is all fairly obvious. It’ll only quote at the moment (until I rip some more rates) for ‘Pos Air Parcel’ and ‘Pos Surface Parcel’ for overseas destinations. You probably don’t want Pos Surface Parcel (it has very long delivery times, but it is cheap), so in the ‘Postal Methods’ field in admin section for shipping module, enter ‘Pos Air Parcel’, and you’ll only get Pos Air Parcel quotes from spider.my.

There are a couple of obvious candidates for system-wide setttings, but some doubt over the standardisation of osCommerce settings convinced me it would be safer to add them to the module settings. Weight units – I don’t recall seeing an osCommerce setting for this, so specify it here. Spider.my will quote for several different units, including kg, g (or gm) lb, oz etc.

‘Ship from’ location – the spider.my quotation API relies on valid ISO 3166-1 country and ISO 3166-2 subdivision location codes. Here’s the ISO 3166-2 list for Malaysia (MY).

Handling Fee is handy if you want to add a fixed fee for packaging, standing in the queue at Pos Malaysia’s counter etc. It may need some refining, as the same fee may not be appropriate for shipping by Pos Laju when they come to your house to pickup, but is appropriate to cover the effort of driving to your local office and waiting in the queue.

Postal Methods can be used to restrict which methods are quoted. For example as I write this there are only 2 full sets of international rates online: Pos Surface Parcel and Pos Air Parcel. If you don’t want to quote Pos Surface Parcel (it’s very cheap, but very slow), you can enter ‘Pos Air Parcel’ (as shown in the image) and only Pos Air Parcel quotes will be shown.

Update 18th Jan 2011, 2am MYT: I haven’t been updating the version from 0 of the shipping module while I’ve been hacking from the back-end to the front to get it quoting for local (ISO 3166-2) shipments. The version last modified at 01:54am is the first one which works reliably for both local (in-Malaysia) shipping and international.

There are some non-trivial changes to your osCommerce database (a new column on the zones table) needed to support local deliveries, I’ll write an article about that tomorrow. Today… but later when I wake up.

It’s tomorrow now and that first version has a fatal bug if it’s used without the table changes. I’ve updated the zipfile to a v0.1 with a workaround for an un-modified table. Just delete the region code (the ‘MY-05’ in the image above) from the admin page, and the module won’t attempt to fetch data from a column that doesn’t exist.

Update – hopefully the last for a while: squashed a few bugs with multi-method quotes. The shipping module myspider v0.2 is available for osCommerce as oscommerce_myspider.zip and as v0.1 for Zen Cart as zencart_myspider.zip