1414use Magento \Framework \Webapi \Soap \ClientFactory ;
1515use Magento \Framework \Xml \Security ;
1616use Magento \Quote \Model \Quote \Address \RateRequest ;
17+ use Magento \Shipping \Model \Carrier \AbstractCarrier ;
1718use Magento \Shipping \Model \Carrier \AbstractCarrierOnline ;
1819use Magento \Shipping \Model \Rate \Result ;
1920
@@ -31,21 +32,21 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
3132 *
3233 * @var string
3334 */
34- const CODE = 'fedex ' ;
35+ public const CODE = 'fedex ' ;
3536
3637 /**
3738 * Purpose of rate request
3839 *
3940 * @var string
4041 */
41- const RATE_REQUEST_GENERAL = 'general ' ;
42+ public const RATE_REQUEST_GENERAL = 'general ' ;
4243
4344 /**
4445 * Purpose of rate request
4546 *
4647 * @var string
4748 */
48- const RATE_REQUEST_SMARTPOST = 'SMART_POST ' ;
49+ public const RATE_REQUEST_SMARTPOST = 'SMART_POST ' ;
4950
5051 /**
5152 * Code of the carrier
@@ -123,7 +124,7 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
123124 protected $ _productCollectionFactory ;
124125
125126 /**
126- * @inheritdoc
127+ * @var string[]
127128 */
128129 protected $ _debugReplacePrivateDataKeys = [
129130 'Key ' , 'Password ' , 'MeterNumber ' ,
@@ -381,15 +382,16 @@ public function setRequest(RateRequest $request)
381382 $ r ->setDestCity ($ request ->getDestCity ());
382383 }
383384
384- $ weight = $ this ->getTotalNumOfBoxes ($ request ->getPackageWeight ());
385- $ r ->setWeight ($ weight );
386385 if ($ request ->getFreeMethodWeight () != $ request ->getPackageWeight ()) {
387386 $ r ->setFreeMethodWeight ($ request ->getFreeMethodWeight ());
388387 }
389388
389+ $ r ->setWeight ($ request ->getPackageWeight ());
390390 $ r ->setValue ($ request ->getPackagePhysicalValue ());
391391 $ r ->setValueWithDiscount ($ request ->getPackageValueWithDiscount ());
392392
393+ $ r ->setPackages ($ this ->createPackages ((float ) $ request ->getPackageWeight (), (array ) $ request ->getPackages ()));
394+
393395 $ r ->setMeterNumber ($ this ->getConfigData ('meter_number ' ));
394396 $ r ->setKey ($ this ->getConfigData ('key ' ));
395397 $ r ->setPassword ($ this ->getConfigData ('password ' ));
@@ -445,7 +447,6 @@ protected function _formRateRequest($purpose)
445447 'DropoffType ' => $ r ->getDropoffType (),
446448 'ShipTimestamp ' => date ('c ' ),
447449 'PackagingType ' => $ r ->getPackaging (),
448- 'TotalInsuredValue ' => ['Amount ' => $ r ->getValue (), 'Currency ' => $ this ->getCurrencyCode ()],
449450 'Shipper ' => [
450451 'Address ' => ['PostalCode ' => $ r ->getOrigPostal (), 'CountryCode ' => $ r ->getOrigCountry ()],
451452 ],
@@ -464,37 +465,36 @@ protected function _formRateRequest($purpose)
464465 'CustomsValue ' => ['Amount ' => $ r ->getValue (), 'Currency ' => $ this ->getCurrencyCode ()],
465466 ],
466467 'RateRequestTypes ' => 'LIST ' ,
467- 'PackageCount ' => '1 ' ,
468468 'PackageDetail ' => 'INDIVIDUAL_PACKAGES ' ,
469- 'RequestedPackageLineItems ' => [
470- '0 ' => [
471- 'Weight ' => [
472- 'Value ' => (double )$ r ->getWeight (),
473- 'Units ' => $ this ->getConfigData ('unit_of_measure ' ),
474- ],
475- 'GroupPackageCount ' => 1 ,
476- ],
477- ],
478469 ],
479470 ];
480471
472+ foreach ($ r ->getPackages () as $ packageNum => $ package ) {
473+ $ ratesRequest ['RequestedShipment ' ]['RequestedPackageLineItems ' ][$ packageNum ]['GroupPackageCount ' ] = 1 ;
474+ $ ratesRequest ['RequestedShipment ' ]['RequestedPackageLineItems ' ][$ packageNum ]['Weight ' ]['Value ' ]
475+ = (double ) $ package ['weight ' ];
476+ $ ratesRequest ['RequestedShipment ' ]['RequestedPackageLineItems ' ][$ packageNum ]['Weight ' ]['Units ' ]
477+ = $ this ->getConfigData ('unit_of_measure ' );
478+ if (isset ($ package ['price ' ])) {
479+ $ ratesRequest ['RequestedShipment ' ]['RequestedPackageLineItems ' ][$ packageNum ]['InsuredValue ' ]['Amount ' ]
480+ = (double ) $ package ['price ' ];
481+ $ ratesRequest ['RequestedShipment ' ]['RequestedPackageLineItems ' ][$ packageNum ]['InsuredValue ' ]['Currency ' ]
482+ = $ this ->getCurrencyCode ();
483+ }
484+ }
485+
486+ $ ratesRequest ['RequestedShipment ' ]['PackageCount ' ] = count ($ r ->getPackages ());
487+
481488 if ($ r ->getDestCity ()) {
482489 $ ratesRequest ['RequestedShipment ' ]['Recipient ' ]['Address ' ]['City ' ] = $ r ->getDestCity ();
483490 }
484491
485- if ($ purpose == self ::RATE_REQUEST_GENERAL ) {
486- $ ratesRequest ['RequestedShipment ' ]['RequestedPackageLineItems ' ][0 ]['InsuredValue ' ] = [
487- 'Amount ' => $ r ->getValue (),
488- 'Currency ' => $ this ->getCurrencyCode (),
492+ if ($ purpose == self ::RATE_REQUEST_SMARTPOST ) {
493+ $ ratesRequest ['RequestedShipment ' ]['ServiceType ' ] = self ::RATE_REQUEST_SMARTPOST ;
494+ $ ratesRequest ['RequestedShipment ' ]['SmartPostDetail ' ] = [
495+ 'Indicia ' => (double )$ r ->getWeight () >= 1 ? 'PARCEL_SELECT ' : 'PRESORTED_STANDARD ' ,
496+ 'HubId ' => $ this ->getConfigData ('smartpost_hubid ' ),
489497 ];
490- } else {
491- if ($ purpose == self ::RATE_REQUEST_SMARTPOST ) {
492- $ ratesRequest ['RequestedShipment ' ]['ServiceType ' ] = self ::RATE_REQUEST_SMARTPOST ;
493- $ ratesRequest ['RequestedShipment ' ]['SmartPostDetail ' ] = [
494- 'Indicia ' => (double )$ r ->getWeight () >= 1 ? 'PARCEL_SELECT ' : 'PRESORTED_STANDARD ' ,
495- 'HubId ' => $ this ->getConfigData ('smartpost_hubid ' ),
496- ];
497- }
498498 }
499499
500500 return $ ratesRequest ;
@@ -632,6 +632,40 @@ protected function _prepareRateResponse($response)
632632 return $ result ;
633633 }
634634
635+ /**
636+ * Get final price for shipping method with handling fee per package
637+ *
638+ * @param float $cost
639+ * @param string $handlingType
640+ * @param float $handlingFee
641+ * @return float
642+ */
643+ protected function _getPerpackagePrice ($ cost , $ handlingType , $ handlingFee )
644+ {
645+ if ($ handlingType == AbstractCarrier::HANDLING_TYPE_PERCENT ) {
646+ return $ cost + $ cost * $ this ->_numBoxes * $ handlingFee / 100 ;
647+ }
648+
649+ return $ cost + $ this ->_numBoxes * $ handlingFee ;
650+ }
651+
652+ /**
653+ * Get final price for shipping method with handling fee per order
654+ *
655+ * @param float $cost
656+ * @param string $handlingType
657+ * @param float $handlingFee
658+ * @return float
659+ */
660+ protected function _getPerorderPrice ($ cost , $ handlingType , $ handlingFee )
661+ {
662+ if ($ handlingType == self ::HANDLING_TYPE_PERCENT ) {
663+ return $ cost + $ cost * $ handlingFee / 100 ;
664+ }
665+
666+ return $ cost + $ handlingFee ;
667+ }
668+
635669 /**
636670 * Get origin based amount form response of rate estimation
637671 *
@@ -809,14 +843,6 @@ protected function _parseXmlResponse($response)
809843 if (strlen (trim ($ response )) > 0 ) {
810844 $ xml = $ this ->parseXml ($ response , \Magento \Shipping \Model \Simplexml \Element::class);
811845 if (is_object ($ xml )) {
812- if (is_object ($ xml ->Error ) && is_object ($ xml ->Error ->Message )) {
813- $ errorTitle = (string )$ xml ->Error ->Message ;
814- } elseif (is_object ($ xml ->SoftError ) && is_object ($ xml ->SoftError ->Message )) {
815- $ errorTitle = (string )$ xml ->SoftError ->Message ;
816- } else {
817- $ errorTitle = 'Sorry, something went wrong. Please try again or contact us and we \'ll try to help. ' ;
818- }
819-
820846 $ allowedMethods = explode (", " , $ this ->getConfigData ('allowed_methods ' ));
821847
822848 foreach ($ xml ->Entry as $ entry ) {
@@ -833,11 +859,7 @@ protected function _parseXmlResponse($response)
833859 }
834860
835861 asort ($ priceArr );
836- } else {
837- $ errorTitle = 'Response is in the wrong format. ' ;
838862 }
839- } else {
840- $ errorTitle = 'For some reason we can \'t retrieve tracking info right now. ' ;
841863 }
842864
843865 $ result = $ this ->_rateFactory ->create ();
@@ -1212,6 +1234,7 @@ public function getResponse()
12121234 }
12131235 }
12141236 }
1237+ // phpstan:ignore
12151238 if (empty ($ statuses )) {
12161239 $ statuses = __ ('Empty response ' );
12171240 }
@@ -1821,4 +1844,24 @@ private function getPaymentType(DataObject $request): string
18211844 ? 'RECIPIENT '
18221845 : 'SENDER ' ;
18231846 }
1847+
1848+ /**
1849+ * Creates packages for rate request.
1850+ *
1851+ * @param float $totalWeight
1852+ * @param array $packages
1853+ * @return array
1854+ */
1855+ private function createPackages (float $ totalWeight , array $ packages ): array
1856+ {
1857+ if (empty ($ packages )) {
1858+ $ dividedWeight = $ this ->getTotalNumOfBoxes ($ totalWeight );
1859+ for ($ i =0 ; $ i < $ this ->_numBoxes ; $ i ++) {
1860+ $ packages [$ i ]['weight ' ] = $ dividedWeight ;
1861+ }
1862+ }
1863+ $ this ->_numBoxes = count ($ packages );
1864+
1865+ return $ packages ;
1866+ }
18241867}
0 commit comments