16 replies [Last post]
KingAndy's picture
Offline
Joined: 04/01/2009
Juice: 94

Okay, first of all I should probably mention that I noticed this while I was going through the 5.x-1.7 code, but while my familiarity with Conditional Actions is negligible it does appear to have been carried over to 6.x-2.x.

The description of the postcode pattern is as follows:

Quote:

Specify a postal code or postal code pattern. Use "*" as a wild card to specify a range of postal codes.

That seems like very useful functionality. Unfortunately the postal code processing functions don't exactly treat the * as a wildcard...

<?php
// Check an order's delivery postal code.
function uc_order_condition_delivery_postal_code($order, $settings) {
 
// Trim the wildcard off the pattern.
 
$pattern = rtrim($settings['pattern'], '*');

 

// Return TRUE if the delivery postal code begins with the pattern.
 
return strpos($order->delivery_postal_code, $pattern) === 0;
}
?>

This code simply removes the wildcard - but only if it occurs at the end of the pattern - and then checks whether the remaining pattern is at the beginning of the postal code regardless of whether there was a wildcard. The wildcard is both broken and unnecessary. (FWIW, the ...billing_postal_code function is identical save the postal code used.)

In my opinion, either the code needs to treat the asterisk as an actual wildcard (perhaps by assembling a regular expression?), or the reference to it should be removed from the #description and replaced with a description of the actual behaviour. Or, if we want to keep the behaviour but give the wildcard a purpose, carry out the trim and strpos only when the wildcard is present, with a generic equality comparison being performed otherwise. And the #description updated to describe that behaviour. Whatever happens, the #description needs to change to match the behaviour.

Well, that is what I think, anyway.

Ryan's picture
Offline
Joined: 08/07/2007
Juice: 15422
Re: Postal Code conditions: Tame wildcards

All valid points, and yeah, the current behavior is just silly. Lyle's coming over to my pad for a code sprint tomorrow, so I'll bookmark this issue for us to address. Seems like a quick fix. I'll probably just go the route of making the wildcard work, since I'm going to guess it's in there b/c people are using it.

Lyle's picture
Offline
AdministratoreLiTe!
Joined: 08/07/2007
Juice: 6841
Re: Re: Postal Code conditions: Tame wildcards

Honestly, it's the way it is because I was copying the way Google Checkout wants postal codes to be formatted in tax rules. I never even questioned that the asterisk wasn't even needed by the time I was done.

ben.stockdale@drupal.org's picture
Offline
Joined: 08/12/2007
Juice: 2
Chaining postal codes in a pattern

Hi,

I have 3 groups of postal codes with different delivery prices. The wildcard won't work for me as the poscodes don't in AU don't group logically in numbers so sorry to sound like an idiot but how do I chain postcodes?

I've tried thing like 3013,3121 as well as 3013 OR 3121 with no success.

It's either that or try and create a couple of hundred conditions and I fear that's not the best solution.

Any solution appreciated.

Cheers

Ben

Ryan's picture
Offline
Joined: 08/07/2007
Juice: 15422
Re: Chaining postal codes in a pattern

Hey Ben - creating a couple hundred conditions would be the solution if you wanted to define the tax rule through the existing CA interface. The alternative, if you know a little PHP, would be to create your own condition and check for postal code against an array or something. Is this possible for you? I'm happy to walk you through the process if so.

KingAndy's picture
Offline
Joined: 04/01/2009
Juice: 94
Re: Re: Chaining postal codes in a pattern

FWIW, I actually have a custom module that administers a list of postcodes and makes conditions available - this is useful with the Flatrate shipping system (so you can "allow shipping rate X" if "delivery postcode is within Zone N"). It's kind of specific to UK postcode formats, so may require reworking before it'll allow zip codes, but I might be able to make it available for reference or mutilation if people are interested.

It's built for Ubercart 5.x-1.x, so somebody would at least need to change all the "workflow-NG" references to "Conditional Actions" (or whatever), on top of whatever other 6.x-2.x changes would be needed. Oh and there's little to no documentation...

petey318's picture
Offline
Joined: 03/25/2008
Juice: 33
Re: Re: Re: Chaining postal codes in a pattern

Hi KingAndy - not sure if you will see this post, but if you could make that module code available, I'd be extremely interested. I'm about to write something fairly similar for Australian Postcodes, mapping to courier zones, and I'd love to get some pointers/tips from your code, since I am very much a PHP-newbie.

And the target site is D5, Ubercart 1.6...

Cheers
Pete

mantra's picture
Offline
Joined: 06/02/2010
Juice: 20
@kingandy i've a similar

@kingandy

i've a similar need(restricting delivery to specofoc uk postcode areas). it would be really helpful if you could share your code, or at least give som details howthis is acieved.

many thanks,
mantra

allanp's picture
Offline
Joined: 05/27/2010
Juice: 74
@mantra Were you able to

@mantra

Were you able to figure out how to restrict delivery? I'm dealing with U.S. zip codes, but it is the same idea.

I can figure out how to set up the condition for a list of zip codes.

$zip = array(
'94501','94502','94506','94619','64807'
);
if (in_array($order->delivery_postal_code, $zip)) return (TRUE); else return (FALSE);

My problem is I don't know how to set up an action to stop the order, or remove the item from the cart, or whatever it takes...

mantra's picture
Offline
Joined: 06/02/2010
Juice: 20
@allanp Yes. Sorry, I should

@allanp
Yes. Sorry, I should have posted the solution here.Basically I did the followings:

  1. Created two flatrates i.e. Home Delivery and Store Pickup
  2. Created a conditional action e.g. Restrict Home Delivery by postcode:
  • Selected 'Getting shipping quote via Home Delivery' as trigger
  • Under the conditions: selected 'AND. If all of these conditions are TRUE' operator.'
  • Select 'Check an order's shipping postal code' as the condition and filled out the postal code underneth to indicate that Delivery option will be enabled only for the given postcode.

I used compound set of conditions to allow delivery to multiple postcodes. Please check out my recent Ubercart site www.sundarban.co.uk for demonstration. CAUTION: its a live site so, please don't checkout/pay as they don't deliver curries to US from the UK Smiling

allanp's picture
Offline
Joined: 05/27/2010
Juice: 74
@mantra Thank you for the

@mantra

Thank you for the quick reply and information.

I'm going to get started on trying that approach right away.

(and it's a shame Sandarban does not deliver to the US. Some of those curries sound REALLY good.)

galooph's picture
Offline
Joined: 06/10/2009
Juice: 2
Hey Ryan, I've got to

Hey Ryan,

I've got to implement the exact same thing - a shipping surcharge for a bundle of postcodes. A walkthrough on how to create a custom condition would be great!

foolofatook's picture
Offline
Joined: 06/14/2010
Juice: 29
any luck?

It seems the last post on this topic was a few months ago..

I was curious if there had been any headway on coming up with a solution to being able to list zipcodes (possibly something as simple as separating them by commas)?

I'm looking to set up a CA that charges a higher tax rate based on (some 20 or so) zipcode of the billing address. Short of making about 40 CA, it would be nice to be able to just type in all the zipcodes I need in one place.

As a side note, I don't grasp php fully, but if there were a bit of code or small module that has been written that comes up with a solution for this, it'd be nice to be pointed in the right direction of where to find it. Smiling

Thanks!

allanp's picture
Offline
Joined: 05/27/2010
Juice: 74
Filtering by zipcode

I'm using a little PHP in the condition to apply a discount to certain zipcodes:

$zip = array(
'94501','94502','94506','94507'
);

if (in_array($order->delivery_postal_code, $zip)) return (TRUE); else return (FALSE);

Maybe something like that will work in your situation.

codebrighton's picture
Offline
Joined: 02/18/2010
Juice: 9
List of Postcodes/Zipcodes

Hi I needed this functionality and had to edit uc_order/uc_order.ca.inc (also fixed an issue with postcodes in that they could be in upper or lower case!)

Old code:

function uc_order_condition_delivery_postal_code($order, $settings) {
  // Trim the wildcard off the pattern.
  $pattern = rtrim($settings['pattern'], '*');

  // Return TRUE if the delivery postal code begins with the pattern.
  return strpos($order->delivery_postal_code, $pattern) === 0;
}

My new code:

function uc_order_condition_delivery_postal_code($order, $settings) {
    $found = FALSE;
    $p_array = explode(',', $settings['pattern']);
    foreach ($p_array as $p) {
        // Trim the wildcard off the pattern (don't really need the * anyway!)
        $pattern = rtrim($p, '*');
        if(strpos(strtolower($order->delivery_postal_code), strtolower($pattern)) === 0) {
            $found = TRUE;
        }
    }
    // Return TRUE if the delivery postal code begins with the pattern.
    return $found;
}

Code probably could be a bit more efficient, but hope this helps someone

codebrighton's picture
Offline
Joined: 02/18/2010
Juice: 9
Further develpoment - Confusion in the Scottish Highlands!

Just to follow due to the idiosyncrasies of the UK poscode system and my project requirement I had the situation where my code above didn't do the trick as I initially thought. It will probably work for most peoples requirements but consider a situation where you have a postal charge for postcodes that could start with IV1 and IV15 but not IV14 (this was the case for regioning the Scottish Highlands)

Anyway here's my fairly hacky code that does the job. WARNING it might not be exactly what you need and if the simpler code above does the trick for you I would highly advise you use that in preference. But for the choosen few who had the same headache as me, here tis...

function uc_order_condition_delivery_postal_code($order, $settings) {
    $found = FALSE;
    $delivery_postal_code = strtolower($order->delivery_postal_code);
    $delivery_postal_code = str_replace(" ", "", $delivery_postal_code);
    $p_array = explode(',', $settings['pattern']);
    foreach ($p_array as $p) {
        // Trim the wildcard off the pattern (don't really need the * anyway!)
        $pattern = rtrim($p, '*');
        /* if just the letters or letters and full 2 digits in the postcode need to be checked using e.g. IV14XX */
        /* then all of IV or IV14 is fine */
        $found_this_round = false;
        if(strpos($delivery_postal_code, strtolower($pattern)) === 0) {
            $found = TRUE;
            $found_this_round = true;
        }
        if(strlen($pattern)==3 && $found_this_round){
            /* but if just checking for IV1 but not IV14 */
            /* if the forth character of the delivery postcode is a number then not match */
            if(is_numeric(substr($delivery_postal_code, 3, 1))){
                $found = FALSE;
            }
        }
    }
    // Return TRUE if the delivery postal code begins with the pattern.
    return $found;
}
bojaka's picture
Offline
Joined: 11/29/2011
Juice: 3
Bump!

Hello,

I would really like to know if any progress has been done regarding this.
I need to be able to specify my postal codes in a pattern or list so I don't have to make one condition for each postal code.
I have several hundreds of postal codes that should pay an extra "remote destination fee" and making them one by one is really not an option =(

Best regards // Bo Jaka