diff --git a/app/code/core/Mage/Shipping/Model/Resource/Carrier/Tablerate.php b/app/code/core/Mage/Shipping/Model/Resource/Carrier/Tablerate.php index acbf4ee5096..a0686257b2a 100644 --- a/app/code/core/Mage/Shipping/Model/Resource/Carrier/Tablerate.php +++ b/app/code/core/Mage/Shipping/Model/Resource/Carrier/Tablerate.php @@ -108,24 +108,38 @@ public function getRate(Mage_Shipping_Model_Rate_Request $request) $select = $adapter->select() ->from($this->getMainTable()) ->where('website_id = :website_id') - ->order(['dest_country_id DESC', 'dest_region_id DESC', 'dest_zip DESC', 'condition_value DESC']) + ->order(['dest_country_id DESC', 'dest_region_id DESC', 'LENGTH(dest_zip) DESC', 'dest_zip DESC', 'condition_value DESC']) ->limit(1); - // Render destination condition - $orWhere = '(' . implode(') OR (', [ + $conditions = [ "dest_country_id = :country_id AND dest_region_id = :region_id AND dest_zip = :postcode", "dest_country_id = :country_id AND dest_region_id = :region_id AND dest_zip = ''", + "dest_country_id = :country_id AND dest_region_id = '0' AND dest_zip = :postcode", + "dest_country_id = '0' AND dest_region_id = :region_id AND dest_zip = :postcode", + "dest_country_id = '0' AND dest_region_id = '0' AND dest_zip = :postcode", + "dest_country_id = :country_id AND dest_region_id = '0' AND dest_zip = ''" + ]; - // Handle asterix in dest_zip field - "dest_country_id = :country_id AND dest_region_id = :region_id AND dest_zip = '*'", - "dest_country_id = :country_id AND dest_region_id = 0 AND dest_zip = '*'", - "dest_country_id = '0' AND dest_region_id = :region_id AND dest_zip = '*'", - "dest_country_id = '0' AND dest_region_id = 0 AND dest_zip = '*'", + // Handle asterix in dest_zip field + $conditions[] = "dest_country_id = :country_id AND dest_region_id = :region_id AND dest_zip = '*'"; + $conditions[] = "dest_country_id = :country_id AND dest_region_id = '0' AND dest_zip = '*'"; + $conditions[] = "dest_country_id = '0' AND dest_region_id = :region_id AND dest_zip = '*'"; + $conditions[] = "dest_country_id = '0' AND dest_region_id = '0' AND dest_zip = '*'"; + + $i = 0; + $postcode = $request->getDestPostcode(); + while (strlen($postcode) > 1) { + $i++; + $postcode = substr($postcode, 0, -1); + $bind[':wildcard_postcode_' . $i] = "{$postcode}*"; + $conditions[] = "dest_country_id = :country_id AND dest_region_id = :region_id AND dest_zip = :wildcard_postcode_{$i}"; + $conditions[] = "dest_country_id = :country_id AND dest_region_id = '0' AND dest_zip = :wildcard_postcode_{$i}"; + $conditions[] = "dest_country_id = '0' AND dest_region_id = :region_id AND dest_zip = :wildcard_postcode_{$i}"; + $conditions[] = "dest_country_id = '0' AND dest_region_id = '0' AND dest_zip = :wildcard_postcode_{$i}"; + } - "dest_country_id = :country_id AND dest_region_id = 0 AND dest_zip = ''", - "dest_country_id = :country_id AND dest_region_id = 0 AND dest_zip = :postcode", - "dest_country_id = :country_id AND dest_region_id = 0 AND dest_zip = '*'", - ]) . ')'; + // Render destination condition + $orWhere = '(' . implode(') OR (', $conditions) . ')'; $select->where($orWhere); // Render condition by condition name