improve address detection logic

This commit is contained in:
O K
2026-01-02 09:32:44 +02:00
parent 3e168ea046
commit cdb9341a4f
2 changed files with 58 additions and 35 deletions

View File

@@ -10,6 +10,8 @@ class Zh_UspsLabelsOverride extends Zh_UspsLabels
* Intercept the rate calculation call. * Intercept the rate calculation call.
*/ */
public function getPackageShippingCost($params, $shipping_cost, $products) public function getPackageShippingCost($params, $shipping_cost, $products)
{ {
// 1. Check if Bridge Module exists and is active // 1. Check if Bridge Module exists and is active
/** @var Usps_Api_Bridge $bridge */ /** @var Usps_Api_Bridge $bridge */

View File

@@ -153,7 +153,7 @@ class Usps_Api_Bridge extends Module
return $helper->generateForm([$fields_form]); return $helper->generateForm([$fields_form]);
} }
public function calculateRate($params, $shipping_cost, $products, $originalModule) public function calculateRate($params, $shipping_cost, $products, $originalModule)
{ {
require_once(dirname(__FILE__) . '/classes/UspsV3Client.php'); require_once(dirname(__FILE__) . '/classes/UspsV3Client.php');
@@ -161,38 +161,32 @@ class Usps_Api_Bridge extends Module
$token = $this->getAccessToken(); $token = $this->getAccessToken();
if (!$token) return false; if (!$token) return false;
// 2. Identify Service (Module Loop context)
// 2. Identify Service (Use the Module's ID, not the Cart's ID)
// $originalModule->id_carrier is the carrier currently being calculated in the loop.
$carrierId = (int)$originalModule->id_carrier; $carrierId = (int)$originalModule->id_carrier;
// Fallback
// Fallback for edge cases where module ID might be missing (rare)
if (!$carrierId && isset($params->id_carrier)) { if (!$carrierId && isset($params->id_carrier)) {
$carrierId = (int)$params->id_carrier; $carrierId = (int)$params->id_carrier;
} }
// 3. Get Method Code // 3. Get Method Code
$sql = 'SELECT code FROM `' . _DB_PREFIX_ . 'uspsl_method` WHERE id_carrier = ' . (int)$carrierId; $sql = 'SELECT code FROM `' . _DB_PREFIX_ . 'uspsl_method` WHERE id_carrier = ' . (int)$carrierId;
$methodCode = Db::getInstance()->getValue($sql); $methodCode = \Db::getInstance()->getValue($sql);
// If this carrier ID isn't in the USPS table, it's not a USPS carrier (or map is broken)
if (!$methodCode) return false; if (!$methodCode) return false;
// --- 4. CHECK LEGACY DB CACHE --- // --- 4. CHECK LEGACY DB CACHE ---
// (Moved after method identification so we query cache for the CORRECT carrier)
$zhCache = false; $zhCache = false;
$canCache = class_exists('\UspsPsLabels\Cache') && class_exists('\UspsPsLabels\CacheRate'); $canCache = class_exists('\UspsPsLabels\Cache') && class_exists('\UspsPsLabels\CacheRate');
if ($canCache) { if ($canCache) {
$zhCache = \UspsPsLabels\Cache::cacheCart($params->id); $zhCache = \UspsPsLabels\Cache::cacheCart($params->id);
if (Validate::isLoadedObject($zhCache)) { if (\Validate::isLoadedObject($zhCache)) {
$sql = 'SELECT rate FROM `' . _DB_PREFIX_ . 'uspsl_cache_rate` $sql = 'SELECT rate FROM `' . _DB_PREFIX_ . 'uspsl_cache_rate`
WHERE id_cache = ' . (int)$zhCache->id . ' WHERE id_cache = ' . (int)$zhCache->id . '
AND id_carrier = ' . (int)$carrierId; // Use the correct ID here too! AND id_carrier = ' . (int)$carrierId;
$cachedRate = Db::getInstance()->getValue($sql); $cachedRate = \Db::getInstance()->getValue($sql);
if ($cachedRate !== false && $cachedRate !== null) { if ($cachedRate !== false && $cachedRate !== null) {
return (float)$cachedRate + $shipping_cost; return (float)$cachedRate + $shipping_cost;
@@ -201,10 +195,42 @@ class Usps_Api_Bridge extends Module
} }
// ------------------------------- // -------------------------------
// 5. Determine International Status & Map Code // 5. Determine International Status & Address Data (Cookie/Object Hybrid)
$destAddress = new Address($params->id_address_delivery); $destAddress = new \Address($params->id_address_delivery);
$isInternational = ($destAddress->id_country != Country::getByIso('US')); $destZip = '';
$destCountryIso = 'US';
if (\Validate::isLoadedObject($destAddress)) {
// Real Address exists
$destZip = $destAddress->postcode;
$destCountryIso = \Country::getIsoById($destAddress->id_country);
} else {
// Fallback for Estimator (Cookies)
$context = \Context::getContext();
if (isset($context->cookie->id_country) && $context->cookie->id_country) {
$destCountryIso = \Country::getIsoById($context->cookie->id_country);
} elseif (isset($params->id_country) && $params->id_country) {
$destCountryIso = \Country::getIsoById($params->id_country);
}
if (isset($context->cookie->postcode) && $context->cookie->postcode) {
$destZip = $context->cookie->postcode;
}
// If absolutely no data, we can't calculate
if (empty($destZip) && empty($destCountryIso)) {
return false;
}
}
// Clean Data
$originZip = $this->getOriginZip($originalModule);
$originZip = substr(preg_replace('/[^0-9]/', '', $originZip), 0, 5);
$destZip = substr(preg_replace('/[^0-9]/', '', $destZip), 0, 5);
$isInternational = ($destCountryIso !== 'US');
// Map Code
$newApiClass = $this->mapServiceCodeToApiClass($methodCode, $isInternational); $newApiClass = $this->mapServiceCodeToApiClass($methodCode, $isInternational);
if (!$newApiClass) return false; if (!$newApiClass) return false;
@@ -213,18 +239,13 @@ class Usps_Api_Bridge extends Module
if (empty($packedBoxes)) return false; if (empty($packedBoxes)) return false;
// 7. Setup Client // 7. Setup Client
$client = new UspsV3Client($token, (bool)Configuration::get('USPS_BRIDGE_LIVE_MODE')); $client = new UspsV3Client($token, (bool)\Configuration::get('USPS_BRIDGE_LIVE_MODE'));
$totalPrice = 0; $totalPrice = 0;
$legacyPriceSetting = (int)Configuration::get('USPSL_COMMERCIAL'); $legacyPriceSetting = (int)\Configuration::get('USPSL_COMMERCIAL');
$requestedPriceType = ($legacyPriceSetting > 0) ? 'COMMERCIAL' : 'RETAIL'; $requestedPriceType = ($legacyPriceSetting > 0) ? 'COMMERCIAL' : 'RETAIL';
// 8. Address Data // 8. Loop through boxes
$originZip = $this->getOriginZip($originalModule);
$originZip = substr(preg_replace('/[^0-9]/', '', $originZip), 0, 5);
$destZip = substr(preg_replace('/[^0-9]/', '', $destAddress->postcode), 0, 5);
// 9. Loop through boxes
foreach ($packedBoxes as $packedBox) { foreach ($packedBoxes as $packedBox) {
$weightInLbs = $this->convertUnit($packedBox->getWeight(), 'g', 'lbs', 3); $weightInLbs = $this->convertUnit($packedBox->getWeight(), 'g', 'lbs', 3);
@@ -260,14 +281,16 @@ class Usps_Api_Bridge extends Module
$payload['rateIndicator'] = $flatRateIndicator; $payload['rateIndicator'] = $flatRateIndicator;
} }
$response = $this->sendApiRequest($client, $payload, $isInternational, $destAddress, $destZip); // FIX: Pass destCountryIso directly, do not rely on Address object inside this helper
$response = $this->sendApiRequest($client, $payload, $isInternational, $destCountryIso, $destZip);
if (isset($response['error']) && $payload['priceType'] === 'COMMERCIAL') { if (isset($response['error']) && $payload['priceType'] === 'COMMERCIAL') {
$payload['priceType'] = 'RETAIL'; $payload['priceType'] = 'RETAIL';
$response = $this->sendApiRequest($client, $payload, $isInternational, $destAddress, $destZip); $response = $this->sendApiRequest($client, $payload, $isInternational, $destCountryIso, $destZip);
} }
if (isset($response['error'])) { if (isset($response['error'])) {
// $this->log("API Fatal Error: " . $response['error']);
return false; return false;
} }
@@ -280,11 +303,11 @@ class Usps_Api_Bridge extends Module
} }
} }
// --- 10. SAVE TO LEGACY DB CACHE --- // --- 9. SAVE TO LEGACY DB CACHE ---
if ($canCache && Validate::isLoadedObject($zhCache)) { if ($canCache && \Validate::isLoadedObject($zhCache)) {
$newCacheRate = new \UspsPsLabels\CacheRate(); $newCacheRate = new \UspsPsLabels\CacheRate();
$newCacheRate->id_cache = $zhCache->id; $newCacheRate->id_cache = $zhCache->id;
$newCacheRate->id_carrier = $carrierId; // Use Correct ID $newCacheRate->id_carrier = $carrierId;
$newCacheRate->code = $methodCode; $newCacheRate->code = $methodCode;
$newCacheRate->rate = $totalPrice; $newCacheRate->rate = $totalPrice;
$newCacheRate->save(); $newCacheRate->save();
@@ -298,7 +321,7 @@ class Usps_Api_Bridge extends Module
/** /**
* Helper to send request with Runtime Caching & Domestic/Intl switching * Helper to send request with Runtime Caching & Domestic/Intl switching
*/ */
private function sendApiRequest($client, $payload, $isInternational, $destAddress, $destZip) private function sendApiRequest($client, $payload, $isInternational, $destCountryIso, $destZip)
{ {
// 1. Prepare the specific payload for the cache key // 1. Prepare the specific payload for the cache key
@@ -306,7 +329,7 @@ class Usps_Api_Bridge extends Module
$cachePayload = $payload; $cachePayload = $payload;
$cachePayload['destinationEntryFacilityType'] = 'NONE'; $cachePayload['destinationEntryFacilityType'] = 'NONE';
if ($isInternational) { if ($isInternational) {
$cachePayload['destinationCountryCode'] = Country::getIsoById($destAddress->id_country); $cachePayload['destinationCountryCode'] = $destCountryIso; // Use string directly
$cachePayload['originZIPCode'] = $payload['originZIPCode']; // Ensure consistency $cachePayload['originZIPCode'] = $payload['originZIPCode']; // Ensure consistency
// unset($cachePayload['destinationEntryFacilityType']); // unset($cachePayload['destinationEntryFacilityType']);
unset($cachePayload['destinationZIPCode']); unset($cachePayload['destinationZIPCode']);
@@ -323,12 +346,10 @@ class Usps_Api_Bridge extends Module
// 3. Check Cache // 3. Check Cache
if (isset($this->apiRuntimeCache[$cacheKey])) { if (isset($this->apiRuntimeCache[$cacheKey])) {
// Uncomment for deep debugging if needed
// $this->log("Returning cached rate for key: " . $cacheKey);
return $this->apiRuntimeCache[$cacheKey]; return $this->apiRuntimeCache[$cacheKey];
} }
$this->externalLog(['sendApiRequest' => ['payload' => $payload, 'isInternational' => $isInternational, 'destAddress' => $destAddress, 'destZip' => $destZip]]); $this->externalLog(['sendApiRequest' => ['payload' => $payload, 'isInternational' => $isInternational, 'destCountryIso' => $destCountryIso, 'destZip' => $destZip]]);
// 4. Perform Request // 4. Perform Request
if ($isInternational) { if ($isInternational) {