【发布时间】:2014-04-07 03:10:11
【问题描述】:
在我的电子商务网站中,我使用 Shipping API 配置了 FedEx 运输。在方法中,我只选择了 1 Allow 方法,即“国际经济”。即使我只有一种方法允许,通过检查 FedEx 的日志,似乎 API 查询所有方法并返回结果。因此,退回运费至少需要将近一分钟。
Magento 正常吗?或者是否有任何方法可以加快查询速度,或者是否有任何修改或破解我可以使其查询只允许方法?
请多多指教。
谢谢。
【问题讨论】:
在我的电子商务网站中,我使用 Shipping API 配置了 FedEx 运输。在方法中,我只选择了 1 Allow 方法,即“国际经济”。即使我只有一种方法允许,通过检查 FedEx 的日志,似乎 API 查询所有方法并返回结果。因此,退回运费至少需要将近一分钟。
Magento 正常吗?或者是否有任何方法可以加快查询速度,或者是否有任何修改或破解我可以使其查询只允许方法?
请多多指教。
谢谢。
【问题讨论】:
我最近看到一些关于 FedEx Magento 和速度的问题。
我不相信是联邦快递的请求导致了延误,但为了帮助我们解决这个问题(并回答您的问题):-
发出请求的代码是:
//file: app/code/core/Mage/Usa/Modell/Shipping/Carrier/Fedex.php
//class: Mage_Usa_Model_Shipping_Carrier_Fedex
//function: _getQuotes()
protected function _getQuotes()
{
$this->_result = Mage::getModel('shipping/rate_result');
// make separate request for Smart Post method
$allowedMethods = explode(',', $this->getConfigData('allowed_methods'));
if (in_array(self::RATE_REQUEST_SMARTPOST, $allowedMethods)) {
$response = $this->_doRatesRequest(self::RATE_REQUEST_SMARTPOST);
$preparedSmartpost = $this->_prepareRateResponse($response);
if (!$preparedSmartpost->getError()) {
$this->_result->append($preparedSmartpost);
}
}
// make general request for all methods
$response = $this->_doRatesRequest(self::RATE_REQUEST_GENERAL);
$preparedGeneral = $this->_prepareRateResponse($response);
if (!$preparedGeneral->getError() || ($this->_result->getError() && $preparedGeneral->getError())) {
$this->_result->append($preparedGeneral);
}
return $this->_result;
}
所以回答 1:是的,Magento 确实收集了所有方法,无论您通过管理员允许哪些方法。它在两个请求中执行此操作,一个用于 SMARTPOST,一个用于所有其他方法。
回答 2:如果您想要求单一服务类型,那么您正在寻求设置,例如,
$ratesRequest['RequestedShipment']['ServiceType'] = 'INTERNATIONAL_ECONOMY';
为了测试*,您可以从
复制文件//file: app/code/core/Mage/Usa/Modell/Shipping/Carrier/Fedex.php
到
//file: app/code/local/Mage/Usa/Modell/Shipping/Carrier/Fedex.php
然后把代码改成:
//file: app/code/local/Mage/Usa/Modell/Shipping/Carrier/Fedex.php
//class: Mage_Usa_Model_Shipping_Carrier_Fedex
//function: _getQuotes()
protected function _getQuotes()
{
$this->_result = Mage::getModel('shipping/rate_result');
// make separate request for Smart Post method
$allowedMethods = explode(',', $this->getConfigData('allowed_methods'));
//a little test code for me; you can omit it
//echo(nl2br(print_r($allowedMethods,true)));
//exit();
/*
Array<br />
(<br />
[0] => EUROPE_FIRST_INTERNATIONAL_PRIORITY<br />
[1] => FEDEX_1_DAY_FREIGHT<br />
[2] => FEDEX_2_DAY_FREIGHT<br />
[3] => FEDEX_2_DAY<br />
[4] => FEDEX_2_DAY_AM<br />
[5] => FEDEX_3_DAY_FREIGHT<br />
[6] => FEDEX_EXPRESS_SAVER<br />
[7] => FEDEX_GROUND<br />
[8] => FIRST_OVERNIGHT<br />
[9] => GROUND_HOME_DELIVERY<br />
[10] => INTERNATIONAL_ECONOMY<br />
[11] => INTERNATIONAL_ECONOMY_FREIGHT<br />
[12] => INTERNATIONAL_FIRST<br />
[13] => INTERNATIONAL_GROUND<br />
[14] => INTERNATIONAL_PRIORITY<br />
[15] => INTERNATIONAL_PRIORITY_FREIGHT<br />
[16] => PRIORITY_OVERNIGHT<br />
[17] => SMART_POST<br />
[18] => STANDARD_OVERNIGHT<br />
[19] => FEDEX_FREIGHT<br />
[20] => FEDEX_NATIONAL_FREIGHT<br />
)<br />
*/
//THIS IS THE NEW BIT (non core)
if(count($allowedMethods)==1){
//then there is only one method so use it
$response = $this->_doRatesRequest($allowedMethods[0]);
$preparedSingleRate = $this->_prepareRateResponse($response);
if (!$preparedSingleRate->getError() || ($this->_result->getError() && $preparedSingleRate->getError())) {
$this->_result->append($preparedSingleRate);
}
}else{
//revert to default treatment:
if (in_array(self::RATE_REQUEST_SMARTPOST, $allowedMethods)) {
$response = $this->_doRatesRequest(self::RATE_REQUEST_SMARTPOST);
$preparedSmartpost = $this->_prepareRateResponse($response);
if (!$preparedSmartpost->getError()) {
$this->_result->append($preparedSmartpost);
}
}
// make general request for all methods
$response = $this->_doRatesRequest(self::RATE_REQUEST_GENERAL);
$preparedGeneral = $this->_prepareRateResponse($response);
if (!$preparedGeneral->getError() || ($this->_result->getError() && $preparedGeneral->getError())) {
$this->_result->append($preparedGeneral);
}
}
return $this->_result;
}
并在同一个文件中编辑函数_formRateRequest的末尾以应对特定的费率请求目的:
//file: app/code/local/Mage/Usa/Modell/Shipping/Carrier/Fedex.php
//class: Mage_Usa_Model_Shipping_Carrier_Fedex
//function: formRateRequest()
protected function _formRateRequest($purpose)
{
$r = $this->_rawRequest;
//...
//...
if ($purpose == self::RATE_REQUEST_GENERAL) {
$ratesRequest['RequestedShipment']['RequestedPackageLineItems'][0]['InsuredValue'] = array(
'Amount' => $r->getValue(),
'Currency' => $this->getCurrencyCode()
);
} else if ($purpose == self::RATE_REQUEST_SMARTPOST) {
$ratesRequest['RequestedShipment']['ServiceType'] = self::RATE_REQUEST_SMARTPOST;
$ratesRequest['RequestedShipment']['SmartPostDetail'] = array(
'Indicia' => ((float)$r->getWeight() >= 1) ? 'PARCEL_SELECT' : 'PRESORTED_STANDARD',
'HubId' => $this->getConfigData('smartpost_hubid')
);
} else { //THIS IS THE NEW BIT (non core)
$ratesRequest['RequestedShipment']['RequestedPackageLineItems'][0]['InsuredValue'] = array(
'Amount' => $r->getValue(),
'Currency' => $this->getCurrencyCode()
);
$ratesRequest['RequestedShipment']['ServiceType'] = $purpose;
}
return $ratesRequest;
}//end function _formRateRequest
应该只获取您想要的费率。 但它可能无法解决您的速度问题。
您可以通过添加一些计时器和一些日志记录(到var/log/shipping_fedex.log)来运行计时测试,如下所示:
//file: app/code/local/Mage/Usa/Modell/Shipping/Carrier/Fedex.php
//class: Mage_Usa_Model_Shipping_Carrier_Fedex
//function:
protected function _getQuotes()
{
$this->_result = Mage::getModel('shipping/rate_result');
// make separate request for Smart Post method
$allowedMethods = explode(',', $this->getConfigData('allowed_methods'));
//THIS IS THE NEW BIT (non core)
if(count($allowedMethods)==1){
//then there is only one method so use it
$time_start = microtime(true);
$response = $this->_doRatesRequest($allowedMethods[0]);
$preparedSingleRate = $this->_prepareRateResponse($response);
if (!$preparedSingleRate->getError() || ($this->_result->getError() && $preparedSingleRate->getError())) {
$this->_result->append($preparedSingleRate);
}
$time_end = microtime(true);
$time = $time_end - $time_start;
$this->_debug('Polled '.$allowedMethods[0].' in '.$time.' seconds');
}else{
//revert to default treatment:
$time_start = microtime(true);
if (in_array(self::RATE_REQUEST_SMARTPOST, $allowedMethods)) {
$response = $this->_doRatesRequest(self::RATE_REQUEST_SMARTPOST);
$preparedSmartpost = $this->_prepareRateResponse($response);
if (!$preparedSmartpost->getError()) {
$this->_result->append($preparedSmartpost);
}
}
$time_end = microtime(true);
$time = $time_end - $time_start;
$this->_debug('Polled SMART_POST in '.$time.' seconds');
// make general request for all methods
$time_start = microtime(true);
$response = $this->_doRatesRequest(self::RATE_REQUEST_GENERAL);
$preparedGeneral = $this->_prepareRateResponse($response);
if (!$preparedGeneral->getError() || ($this->_result->getError() && $preparedGeneral->getError())) {
$this->_result->append($preparedGeneral);
}
$time_end = microtime(true);
$time = $time_end - $time_start;
$this->_debug('Polled all methods in '.$time.' seconds');
}
return $this->_result;
}
我正在访问 FedEx 沙箱,但值得我在日志文件中记录这些时间:
//file: var/log/shipping_fedex.log
Polled SMART_POST in 1.1807501316071 seconds
Polled SMART_POST in 1.3307409286499 seconds
Polled all methods in 0.78275394439697 seconds //returns warning 556 [Message] => There are no valid services available.
Polled all methods in 2.0135650634766 seconds //returns 8 valid shipping methods
Polled all methods in 1.3563330173492 seconds //returns INTERNATIONAL_ECONOMY and INTERNATIONAL_PRIORITY
//single service request results
Polled FEDEX_2_DAY in 3.1365180015564 seconds
Polled FEDEX_2_DAY in 3.6471431255341 seconds
Polled FEDEX_2_DAY in 2.1428818702698 seconds
Polled INTERNATIONAL_ECONOMY in 2.2340540885925 seconds
Polled INTERNATIONAL_ECONOMY in 2.9664940834045 seconds
所以用计时器加载你的文件,让我们知道你得到了什么。
*对于生产来说,这里当然习惯上说“制作你自己的模块来扩展类Mage_Usa_Model_Shipping_Carrier_Fedex”。
**注意:我必须强制将请求中发送的货币代码发送到“USD”以让 FedEx 返回 SMART_POST 以外的服务类型的任何运费,所以如果你正在测试这个东西,请注意为此。
【讨论】:
我已尝试使用 Fedex 为印度里根运送。我面临一些挑战。然后我尝试解决它,我得到了一些解决方案。 如果您的原产国是印度,并且您的发货目的地也在印度和其他国家/地区。
为此,您必须为 Fedex 下载 RateService_v13.wsdl 你可以从this link得到这个文件
下载并保存
app\code\core\Mage\Usa\etc\wsdl\FedEx\
现在去
app\code\core\Mage\Usa\Model\Shipping\Carrier\Fedex.php
然后找到
受保护的函数_formRateRequest
现在用
改变函数体protected function _formRateRequest($purpose)
{
$r = $this->_rawRequest;
$ratesRequest = array(
'WebAuthenticationDetail' => array(
'UserCredential' => array(
'Key' => $r->getKey(),
'Password' => $r->getPassword()
)
),
'ClientDetail' => array(
'AccountNumber' => $r->getAccount(),
'MeterNumber' => $r->getMeterNumber()
),
'Version' => $this->getVersionInfo(),
'RequestedShipment' => array(
'DropoffType' => $r->getDropoffType(),
'ShipTimestamp' => date('c'),
'PackagingType' => $r->getPackaging(),
'Shipper' => array(
'AccountNumber' => $r->getAccount(),
'Address' => array(
'PostalCode' => $r->getOrigPostal(),
'CountryCode' => $r->getOrigCountry()
)
),
'Recipient' => array(
'AccountNumber' => $r->getAccount(),
'Address' => array(
'PostalCode' => $r->getDestPostal(),
'CountryCode' => $r->getDestCountry(),
'Residential' => (bool)$this->getConfigData('residence_delivery')
)
)
)
);
if($r->getDestCountry()=='IN'){
$ratesRequest['RequestedShipment']['ServiceType'] = 'STANDARD_OVERNIGHT';
$ratesRequest['RequestedShipment']['CustomsClearanceDetail'] = array(
'DutiesPayment' => array(
'PaymentType' => 'SENDER',
'Payor' => array(
'ResponsibleParty' => array(
'AccountNumber' => $r->getAccount(),
'Contact' =>array(
'ContactId' => 'sender Contact Id',
'PersonName' => 'Sender Name',
'Title' => 'ABC',
'CompanyName' => 'Sender Company Name',
'PhoneNumber' => '1234567890',
'PhoneExtension' => '91',
'PagerNumber' =>'12',
'FaxNumber' => '1234567890',
'EMailAddress' => 'mahesh@camstech.com'),
'Address' => array('StreetLines' => 'Test Sender Address Line',
'PostalCode' => $r->getOrigPostal(),
'CountryCode' => $r->getOrigCountry())
)
),
),
'DocumentContent' => 'NON_DOCUMENTS',
'CustomsValue' => array('Currency' => 'INR',
'Amount' => '100'),
'CommercialInvoice' => array('Purpose' => 'SOLD')
);
$ratesRequest['RequestedShipment']['RequestedPackageLineItems'] = array(
'SequenceNumber'=>1,
'GroupNumber'=>1,
'GroupPackageCount'=>1,
'Weight' => array(
'Value' => 1.0,
'Units' => 'KG'
),
'Dimensions' => array(
'Length' => 12,
'Width' => 12,
'Height' => 12,
'Units' => 'IN'
)
);
}else{
$ratesRequest['RequestedShipment']['CustomsClearanceDetail'] = array(
'CustomsValue' => array(
'Amount' => $r->getValue(),
'Currency' => $this->getCurrencyCode()
)
);
$ratesRequest['RequestedShipment']['TotalInsuredValue'] = array(
'Amount' => $r->getValue(),
'Currency' => $this->getCurrencyCode()
);
$ratesRequest['RequestedShipment']['ShippingChargesPayment'] = array(
'PaymentType' => 'SENDER',
'Payor' => array(
'AccountNumber' => $r->getAccount(),
'CountryCode' => $r->getOrigCountry()
)
);
$ratesRequest['RequestedShipment']['RateRequestTypes'] = 'LIST';
$ratesRequest['RequestedShipment']['PackageCount'] = '1';
$ratesRequest['RequestedShipment']['PackageDetail'] = 'INDIVIDUAL_PACKAGES';
$ratesRequest['RequestedShipment']['RequestedPackageLineItems'] = array(
'0' => array(
'Weight' => array(
'Value' => (float)$r->getWeight(),
'Units' => $this->getConfigData('unit_of_measure')
),
'GroupPackageCount' => 1,
)
);
if ($purpose == self::RATE_REQUEST_GENERAL) {
$ratesRequest['RequestedShipment']['RequestedPackageLineItems'][0]['InsuredValue'] = array(
'Amount' => $r->getValue(),
'Currency' => $this->getCurrencyCode()
);
} else if ($purpose == self::RATE_REQUEST_SMARTPOST) {
$ratesRequest['RequestedShipment']['ServiceType'] = self::RATE_REQUEST_SMARTPOST;
$ratesRequest['RequestedShipment']['SmartPostDetail'] = array(
'Indicia' => ((float)$r->getWeight() >= 1) ? 'PARCEL_SELECT' : 'PRESORTED_STANDARD',
'HubId' => $this->getConfigData('smartpost_hubid')
);
}
}
return $ratesRequest;
}
【讨论】: