From 8039f886fb279a77a41932921fa2cdaa3ac2e39b Mon Sep 17 00:00:00 2001 From: O K Date: Sun, 7 Dec 2025 23:45:27 +0200 Subject: [PATCH] add convertUnit --- usps_api_bridge.php | 94 ++++++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 43 deletions(-) diff --git a/usps_api_bridge.php b/usps_api_bridge.php index 0bb748c..e21ced9 100644 --- a/usps_api_bridge.php +++ b/usps_api_bridge.php @@ -139,7 +139,7 @@ class Usps_Api_Bridge extends Module return $helper->generateForm([$fields_form]); } - /** +/** * THE CORE BRIDGE LOGIC */ public function calculateRate($params, $shipping_cost, $products, $originalModule) @@ -153,16 +153,13 @@ class Usps_Api_Bridge extends Module } // 2. Identify which Service (Method) PrestaShop is asking for - // The old module links PS Carrier ID -> Internal Method Code (e.g. "USA_1") $carrierId = $params->id_carrier; - - // We query the OLD module's table directly to find the code for this carrier + $sql = 'SELECT code FROM `' . _DB_PREFIX_ . 'uspsl_method` WHERE id_carrier = ' . (int)$carrierId; $methodCode = Db::getInstance()->getValue($sql); if (!$methodCode) { - // This carrier isn't a USPS carrier controlled by the module - return false; + return false; } // 3. Map Old Code to New API Enum @@ -172,10 +169,9 @@ class Usps_Api_Bridge extends Module return false; } - // 4. Pack the Products (Using Old Module's Logic) - // This calculates how many boxes and their dimensions/weights + // 4. Pack the Products $packedBoxes = $originalModule->getHelper()->getCarrierHelper()->packProducts($products, $params->id); - + if (empty($packedBoxes)) { $this->log("Box packer returned empty."); return false; @@ -188,33 +184,27 @@ class Usps_Api_Bridge extends Module // 6. Get Origin/Dest addresses $originZip = $this->getOriginZip($originalModule); $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); $destZip = substr(preg_replace('/[^0-9]/', '', $destAddress->postcode), 0, 5); - + $isInternational = ($destAddress->id_country != Country::getByIso('US')); // 7. Loop through every box and get a rate foreach ($packedBoxes as $packedBox) { + + // BoxPacker uses Grams and Millimeters by default + // USPS requires Pounds and Inches + + // Weight: Grams -> Pounds + $weightInLbs = $this->convertUnit($packedBox->getWeight(), 'g', 'lbs', 3); - // Convert Weight: Old module uses grams internally usually, spec needs Pounds/Ounces - // We assume packedBox->getWeight() is in grams based on typical PS behavior - // The old module has a UnitConverter class we can borrow - $weightInLbs = $originalModule->getHelper()->getUnitConverter()->convertUnitFromTo( - $packedBox->getWeight(), - 'g', - 'lbs', - 3 - ); - - // Get Dimensions (in Inches) - $box = $packedBox->getBox(); // This returns the Box object - // The Box object from BoxPacker library stores dims in mm usually, - // we need to convert to Inches. - $length = $originalModule->getHelper()->getUnitConverter()->convertUnitFromTo($box->getOuterLength(), 'mm', 'in', 2); - $width = $originalModule->getHelper()->getUnitConverter()->convertUnitFromTo($box->getOuterWidth(), 'mm', 'in', 2); - $height = $originalModule->getHelper()->getUnitConverter()->convertUnitFromTo($box->getOuterDepth(), 'mm', 'in', 2); + // Dimensions: Millimeters -> 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); // Build Payload $payload = [ @@ -224,31 +214,27 @@ class Usps_Api_Bridge extends Module 'width' => $width, 'height' => $height, 'mailClass' => $newApiClass, - 'priceType' => 'COMMERCIAL', // Defaulting to Commercial - 'mailingDate' => date('Y-m-d', strtotime('+1 day')), // Future date is safer - 'processingCategory' => 'MACHINABLE', // Defaulting to simple logic - 'rateIndicator' => 'SP' // Single Piece (Standard) + 'priceType' => 'COMMERCIAL', + 'mailingDate' => date('Y-m-d', strtotime('+1 day')), + 'processingCategory' => 'MACHINABLE', + 'rateIndicator' => 'SP' ]; // -- HANDLE FLAT RATES -- - // If the old box name contains "Flat Rate", we must map it to correct rateIndicator - // (e.g. "USPS Medium Flat Rate Box" -> "FB") - $rateIndicator = $this->mapBoxToRateIndicator($box->getReference()); // Assuming reference holds name + $rateIndicator = $this->mapBoxToRateIndicator($box->getReference()); if ($rateIndicator) { $payload['rateIndicator'] = $rateIndicator; - // Dimensions technically don't matter for Flat Rate, but API might require them anyway } if ($isInternational) { $payload['destinationCountryCode'] = Country::getIsoById($destAddress->id_country); $payload['originZIPCode'] = $originZip; - // International API needs extra fields? Spec says originZIPCode is required. - + $response = $client->getInternationalRate($payload); } else { $payload['destinationZIPCode'] = $destZip; - $payload['destinationEntryFacilityType'] = 'NONE'; // Required by V3 - + $payload['destinationEntryFacilityType'] = 'NONE'; + $response = $client->getDomesticRate($payload); } @@ -261,19 +247,41 @@ class Usps_Api_Bridge extends Module if (isset($response['totalBasePrice'])) { $totalPrice += (float)$response['totalBasePrice']; } elseif (isset($response['rateOptions'][0]['totalBasePrice'])) { - // Sometimes it returns an array of options $totalPrice += (float)$response['rateOptions'][0]['totalBasePrice']; } else { $this->log("API Response missing price: " . print_r($response, true)); return false; } } - $this->log("API Response price: " . $response['totalBasePrice']); - // Add handling fees if any from original module logic return $totalPrice + $shipping_cost; } + /** + * Simple Unit Converter to replace the dependency on the old module's class + */ + private function convertUnit($value, $from, $to, $precision = 2) + { + $units = [ + 'lb' => 453.59237, + 'lbs' => 453.59237, + 'oz' => 28.3495231, + 'kg' => 1000, + 'g' => 1, + 'in' => 25.4, + 'cm' => 10, + 'mm' => 1 + ]; + + // Normalize to base unit (grams or mm) + $baseValue = $value * (isset($units[$from]) ? $units[$from] : 1); + + // Convert to target unit + $converted = $baseValue / (isset($units[$to]) ? $units[$to] : 1); + + return round($converted, $precision); + } + /** * Helper: Get Origin Zip from Old Module DB */