add NONSTANDARD handling
This commit is contained in:
@@ -139,9 +139,6 @@ class Usps_Api_Bridge extends Module
|
|||||||
return $helper->generateForm([$fields_form]);
|
return $helper->generateForm([$fields_form]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* THE CORE BRIDGE LOGIC
|
|
||||||
*/
|
|
||||||
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');
|
||||||
@@ -152,9 +149,8 @@ class Usps_Api_Bridge extends Module
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Identify which Service (Method) PrestaShop is asking for
|
// 2. Identify Service
|
||||||
$carrierId = $params->id_carrier;
|
$carrierId = $params->id_carrier;
|
||||||
|
|
||||||
$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);
|
||||||
|
|
||||||
@@ -165,11 +161,11 @@ class Usps_Api_Bridge extends Module
|
|||||||
// 3. Map Old Code to New API Enum
|
// 3. Map Old Code to New API Enum
|
||||||
$newApiClass = $this->mapServiceCodeToApiClass($methodCode);
|
$newApiClass = $this->mapServiceCodeToApiClass($methodCode);
|
||||||
if (!$newApiClass) {
|
if (!$newApiClass) {
|
||||||
$this->log("Mapping failed for code: " . $methodCode);
|
$this->log("Mapping failed for legacy code: " . $methodCode);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Pack the Products
|
// 4. Pack Products
|
||||||
$packedBoxes = $originalModule->getHelper()->getCarrierHelper()->packProducts($products, $params->id);
|
$packedBoxes = $originalModule->getHelper()->getCarrierHelper()->packProducts($products, $params->id);
|
||||||
|
|
||||||
if (empty($packedBoxes)) {
|
if (empty($packedBoxes)) {
|
||||||
@@ -181,31 +177,36 @@ class Usps_Api_Bridge extends Module
|
|||||||
$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;
|
||||||
|
|
||||||
// 6. Get Origin/Dest addresses
|
// 6. Address Data
|
||||||
$originZip = $this->getOriginZip($originalModule);
|
$originZip = $this->getOriginZip($originalModule);
|
||||||
$destAddress = new Address($params->id_address_delivery);
|
$destAddress = new Address($params->id_address_delivery);
|
||||||
|
|
||||||
// Clean zip codes (USPS V3 expects 5 digits for domestic)
|
|
||||||
$originZip = substr(preg_replace('/[^0-9]/', '', $originZip), 0, 5);
|
$originZip = substr(preg_replace('/[^0-9]/', '', $originZip), 0, 5);
|
||||||
$destZip = substr(preg_replace('/[^0-9]/', '', $destAddress->postcode), 0, 5);
|
$destZip = substr(preg_replace('/[^0-9]/', '', $destAddress->postcode), 0, 5);
|
||||||
|
|
||||||
$isInternational = ($destAddress->id_country != Country::getByIso('US'));
|
$isInternational = ($destAddress->id_country != Country::getByIso('US'));
|
||||||
|
|
||||||
// 7. Loop through every box and get a rate
|
// 7. Loop through boxes
|
||||||
foreach ($packedBoxes as $packedBox) {
|
foreach ($packedBoxes as $packedBox) {
|
||||||
|
|
||||||
// BoxPacker uses Grams and Millimeters by default
|
// Weight Conversion (Grams -> Pounds)
|
||||||
// USPS requires Pounds and Inches
|
|
||||||
|
|
||||||
// Weight: Grams -> Pounds
|
|
||||||
$weightInLbs = $this->convertUnit($packedBox->getWeight(), 'g', 'lbs', 3);
|
$weightInLbs = $this->convertUnit($packedBox->getWeight(), 'g', 'lbs', 3);
|
||||||
|
|
||||||
// Dimensions: Millimeters -> Inches
|
// USPS requires minimum 0.001 lbs. 0 causes errors.
|
||||||
|
if ($weightInLbs <= 0) $weightInLbs = 0.1;
|
||||||
|
|
||||||
|
// Dimensions (mm -> Inches)
|
||||||
$box = $packedBox->getBox();
|
$box = $packedBox->getBox();
|
||||||
$length = $this->convertUnit($box->getOuterLength(), 'mm', 'in', 2);
|
$length = $this->convertUnit($box->getOuterLength(), 'mm', 'in', 2);
|
||||||
$width = $this->convertUnit($box->getOuterWidth(), 'mm', 'in', 2);
|
$width = $this->convertUnit($box->getOuterWidth(), 'mm', 'in', 2);
|
||||||
$height = $this->convertUnit($box->getOuterDepth(), '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
|
||||||
|
$category = 'MACHINABLE';
|
||||||
|
if ($length > 22 || $width > 18 || $height > 15 || $weightInLbs > 25 || $weightInLbs < 0.375) {
|
||||||
|
$category = 'NONSTANDARD';
|
||||||
|
}
|
||||||
|
|
||||||
// Build Payload
|
// Build Payload
|
||||||
$payload = [
|
$payload = [
|
||||||
'originZIPCode' => $originZip,
|
'originZIPCode' => $originZip,
|
||||||
@@ -216,19 +217,24 @@ class Usps_Api_Bridge extends Module
|
|||||||
'mailClass' => $newApiClass,
|
'mailClass' => $newApiClass,
|
||||||
'priceType' => 'COMMERCIAL',
|
'priceType' => 'COMMERCIAL',
|
||||||
'mailingDate' => date('Y-m-d', strtotime('+1 day')),
|
'mailingDate' => date('Y-m-d', strtotime('+1 day')),
|
||||||
'processingCategory' => 'MACHINABLE',
|
'processingCategory' => $category,
|
||||||
'rateIndicator' => 'SP'
|
'rateIndicator' => 'SP' // Single Piece
|
||||||
];
|
];
|
||||||
|
|
||||||
// -- HANDLE FLAT RATES --
|
// Flat Rate Override
|
||||||
$rateIndicator = $this->mapBoxToRateIndicator($box->getReference());
|
$flatRateIndicator = $this->mapBoxToRateIndicator($box->getReference());
|
||||||
if ($rateIndicator) {
|
if ($flatRateIndicator) {
|
||||||
$payload['rateIndicator'] = $rateIndicator;
|
$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) {
|
if ($isInternational) {
|
||||||
$payload['destinationCountryCode'] = Country::getIsoById($destAddress->id_country);
|
$payload['destinationCountryCode'] = Country::getIsoById($destAddress->id_country);
|
||||||
$payload['originZIPCode'] = $originZip;
|
$payload['originZIPCode'] = $originZip;
|
||||||
|
// Remove domestic specific fields
|
||||||
|
unset($payload['destinationEntryFacilityType']);
|
||||||
|
unset($payload['destinationZIPCode']);
|
||||||
|
|
||||||
$response = $client->getInternationalRate($payload);
|
$response = $client->getInternationalRate($payload);
|
||||||
} else {
|
} else {
|
||||||
@@ -238,18 +244,20 @@ class Usps_Api_Bridge extends Module
|
|||||||
$response = $client->getDomesticRate($payload);
|
$response = $client->getDomesticRate($payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process Response
|
// Log Payload on Error for Debugging
|
||||||
if (isset($response['error'])) {
|
if (isset($response['error'])) {
|
||||||
$this->log("API Error: " . $response['error']);
|
$this->log("API Error: " . $response['error']);
|
||||||
|
$this->log("Payload causing error: " . json_encode($payload));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse Price
|
||||||
if (isset($response['totalBasePrice'])) {
|
if (isset($response['totalBasePrice'])) {
|
||||||
$totalPrice += (float)$response['totalBasePrice'];
|
$totalPrice += (float)$response['totalBasePrice'];
|
||||||
} elseif (isset($response['rateOptions'][0]['totalBasePrice'])) {
|
} elseif (isset($response['rateOptions'][0]['totalBasePrice'])) {
|
||||||
$totalPrice += (float)$response['rateOptions'][0]['totalBasePrice'];
|
$totalPrice += (float)$response['rateOptions'][0]['totalBasePrice'];
|
||||||
} else {
|
} else {
|
||||||
$this->log("API Response missing price: " . print_r($response, true));
|
$this->log("API Response missing price. Full response: " . json_encode($response));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user