added RETAIL handling

This commit is contained in:
O K
2025-12-08 13:17:25 +02:00
parent 3d8638eb07
commit 5c2798dedd

View File

@@ -139,7 +139,7 @@ class Usps_Api_Bridge extends Module
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');
@@ -155,59 +155,60 @@ class Usps_Api_Bridge extends Module
$methodCode = Db::getInstance()->getValue($sql);
if (!$methodCode) {
return false;
return false;
}
// 3. Map Old Code to New API Enum
$newApiClass = $this->mapServiceCodeToApiClass($methodCode);
if (!$newApiClass) {
$this->log("Mapping failed for legacy code: " . $methodCode);
return false;
}
// 4. Pack Products
$packedBoxes = $originalModule->getHelper()->getCarrierHelper()->packProducts($products, $params->id);
if (empty($packedBoxes)) {
$this->log("Box packer returned empty.");
return false;
}
// 5. Initialize API Client
// 5. Initialize Client & Settings
$client = new UspsV3Client($token, (bool)Configuration::get('USPS_BRIDGE_LIVE_MODE'));
$totalPrice = 0;
// Determine Price Type from Old Module Settings
// 0 = Regular (Retail), 1 = Commercial, 2 = Commercial Plus
$legacyPriceSetting = (int)Configuration::get('USPSL_COMMERCIAL');
$requestedPriceType = ($legacyPriceSetting > 0) ? 'COMMERCIAL' : 'RETAIL';
// 6. Address Data
$originZip = $this->getOriginZip($originalModule);
$destAddress = new Address($params->id_address_delivery);
$originZip = substr(preg_replace('/[^0-9]/', '', $originZip), 0, 5);
$destZip = substr(preg_replace('/[^0-9]/', '', $destAddress->postcode), 0, 5);
$isInternational = ($destAddress->id_country != Country::getByIso('US'));
// 7. Loop through boxes
foreach ($packedBoxes as $packedBox) {
// Weight Conversion (Grams -> Pounds)
// Weight (Lbs) - Ensure minimum 0.1
$weightInLbs = $this->convertUnit($packedBox->getWeight(), 'g', 'lbs', 3);
if ($weightInLbs < 0.1) $weightInLbs = 0.1;
// USPS requires minimum 0.001 lbs. 0 causes errors.
if ($weightInLbs <= 0) $weightInLbs = 0.1;
// Dimensions (mm -> Inches)
$box = $packedBox->getBox();
// Dimensions (Inches)
$box = $packedBox->getBox();
$length = $this->convertUnit($box->getOuterLength(), 'mm', 'in', 2);
$width = $this->convertUnit($box->getOuterWidth(), 'mm', 'in', 2);
$height = $this->convertUnit($box->getOuterDepth(), 'mm', 'in', 2);
// Determine Processing Category (Crucial for V3 API)
// Machinable: Length <= 22", Width <= 18", Height <= 15", Weight >= 6oz (0.375lbs) and <= 25lbs
// Processing Category Logic
$category = 'MACHINABLE';
if ($length > 22 || $width > 18 || $height > 15 || $weightInLbs > 25 || $weightInLbs < 0.375) {
if ($length > 22 || $width > 18 || $height > 15 || $weightInLbs > 25) {
$category = 'NONSTANDARD';
}
// Build Payload
// Build Base Payload
$payload = [
'originZIPCode' => $originZip,
'weight' => $weightInLbs,
@@ -215,39 +216,31 @@ class Usps_Api_Bridge extends Module
'width' => $width,
'height' => $height,
'mailClass' => $newApiClass,
'priceType' => 'COMMERCIAL',
'priceType' => $requestedPriceType,
'mailingDate' => date('Y-m-d', strtotime('+1 day')),
'processingCategory' => $category,
'rateIndicator' => 'SP' // Single Piece
'rateIndicator' => 'SP'
];
// Flat Rate Override
$flatRateIndicator = $this->mapBoxToRateIndicator($box->getReference());
if ($flatRateIndicator) {
$payload['rateIndicator'] = $flatRateIndicator;
// Dimensions technically ignored for Flat Rate, but required by API schema
// Processing category usually irrelevant for Flat Rate but must be valid Enum
}
if ($isInternational) {
$payload['destinationCountryCode'] = Country::getIsoById($destAddress->id_country);
$payload['originZIPCode'] = $originZip;
// Remove domestic specific fields
unset($payload['destinationEntryFacilityType']);
unset($payload['destinationZIPCode']);
// --- API REQUEST LOGIC WITH RETRY ---
$response = $this->sendApiRequest($client, $payload, $isInternational, $destAddress, $destZip);
$response = $client->getInternationalRate($payload);
} else {
$payload['destinationZIPCode'] = $destZip;
$payload['destinationEntryFacilityType'] = 'NONE';
$response = $client->getDomesticRate($payload);
// If Failed AND we tried COMMERCIAL, try falling back to RETAIL
if (isset($response['error']) && $payload['priceType'] === 'COMMERCIAL') {
$this->log("Commercial rate failed (" . $response['error'] . "). Retrying with RETAIL.");
$payload['priceType'] = 'RETAIL';
$response = $this->sendApiRequest($client, $payload, $isInternational, $destAddress, $destZip);
}
// Log Payload on Error for Debugging
// Final Error Check
if (isset($response['error'])) {
$this->log("API Error: " . $response['error']);
$this->log("Payload causing error: " . json_encode($payload));
$this->log("API Fatal Error: " . $response['error']);
return false;
}
@@ -257,7 +250,7 @@ class Usps_Api_Bridge extends Module
} elseif (isset($response['rateOptions'][0]['totalBasePrice'])) {
$totalPrice += (float)$response['rateOptions'][0]['totalBasePrice'];
} else {
$this->log("API Response missing price. Full response: " . json_encode($response));
$this->log("API Response missing price.");
return false;
}
}
@@ -265,6 +258,27 @@ class Usps_Api_Bridge extends Module
return $totalPrice + $shipping_cost;
}
/**
* Helper to send request and handle Domestic vs International switching
*/
private function sendApiRequest($client, $payload, $isInternational, $destAddress, $destZip)
{
if ($isInternational) {
$payload['destinationCountryCode'] = Country::getIsoById($destAddress->id_country);
// Cleanup domestic fields
unset($payload['destinationEntryFacilityType']);
unset($payload['destinationZIPCode']);
return $client->getInternationalRate($payload);
}
// Domestic
$payload['destinationZIPCode'] = $destZip;
$payload['destinationEntryFacilityType'] = 'NONE';
return $client->getDomesticRate($payload);
}
/**
* Simple Unit Converter to replace the dependency on the old module's class
*/