प्रस्तावना: इसका अर्थ समुदाय के लिए मैगेंटो की वास्तुकला के लिखित अवलोकन के रूप में सेवा करना है (और स्वयं), साथ ही साथ एक वास्तविक प्रश्न भी। हम एक भारी संशोधित कार्ट और चेकआउट अनुभव के साथ काम कर रहे हैं, लेकिन इस समस्या की जड़ Magento के मुख्य तर्क के भीतर है।
पृष्ठभूमि
हमने मानक खरीदारी कार्ट मूल्य नियमों की कार्यक्षमता का उपयोग करके एक मुफ़्त शिपिंग कूपन बनाया है। कूपन पर कोई शर्तें नहीं हैं, और केवल वही कार्रवाई है जो Free Shippingसेट की गई है For matching items only। के बाद से कोई शर्त नहीं है, इस सेट हो जाएगा free_shippingकरने के लिए 1बिक्री उद्धरण आइटम के सभी के लिए।
जैसा कि प्रथागत है, हमने मुफ़्त शिपिंग शिपिंग विधि भी सक्षम की है। Freeshippingवाहक मॉडल दरें प्रदान करेगा जब भी अनुरोध मुफ्त शिपिंग या उप-योग मिलान हैं या सीमा से अधिक है (लेकिन हम सीमा विकल्प का उपयोग नहीं कर रहे हैं)। देखें Mage_Shipping_Model_Carrier_Freeshipping::collectRates:
$this->_updateFreeMethodQuote($request);
if (($request->getFreeShipping()) // <-- This is the condition we're relying on
|| ($request->getBaseSubtotalInclTax() >=
$this->getConfigData('free_shipping_subtotal'))
) {
/* Snip: Add $0.00 method to the result */
}
और Mage_Shipping_Model_Carrier_Freeshipping::_updateFreeMethodQuoteइस तरह दिखता है:
protected function _updateFreeMethodQuote($request)
{
$freeShipping = false;
$items = $request->getAllItems();
$c = count($items);
for ($i = 0; $i < $c; $i++) {
if ($items[$i]->getProduct() instanceof Mage_Catalog_Model_Product) {
if ($items[$i]->getFreeShipping()) {
$freeShipping = true;
} else {
return;
}
}
}
if ($freeShipping) {
$request->setFreeShipping(true);
}
}
इसलिए, जब तक कि सभी आइटम free_shippingएक सत्य मान पर सेट हो जाते हैं (जो वे कूपन के कारण करेंगे), हमें मुफ्त शिपिंग चाहिए। और हम करते हैं!
समस्या
हालांकि, इसका एक प्रमुख दुष्प्रभाव है: किसी भी शिपिंग तरीके जो किसी आइटम पर निर्भर करते हैं row_weight(जैसा कि हमारे FedEx वाहक के अनुकूलित संस्करण के साथ होता है) उचित शिपिंग दरों की गणना करने में विफल रहेगा क्योंकि प्रत्येक आइटम तब row_weightहोता है 0जब मुफ़्त शिपिंग सक्रिय होता है।
दिलचस्प रूप से पर्याप्त है, मैगेंटो के डिफ़ॉल्ट शिपिंग वाहक में से कोई भी वास्तव में भरोसा नहीं करता है row_weight, लेकिन हम इस बात पर विचार करेंगे कि हम क्यों / कब निकालते हैंrow_weight सेट होते हैं 0।
यह पता लगाना कि क्यों row_weightसेट किया गया है0
यह हिस्सा वास्तव में खुदाई करने के लिए बहुत आसान था। शिपिंग गणनाओं का एक बड़ा हिस्सा Mage_Sales_Model_Quote_Address_Total_Shipping::collectइसमें शामिल row_weightहै 0:
public function collect(Mage_Sales_Model_Quote_Address $address)
{
parent::collect($address);
foreach ($items as $item) {
/* Snip: Handling virtual items and parent items */
if ($item->getHasChildren() && $item->isShipSeparately()) {
/* Snip: Handling items with children */
}
else {
if (!$item->getProduct()->isVirtual()) {
$addressQty += $item->getQty();
}
$itemWeight = $item->getWeight();
$rowWeight = $itemWeight*$item->getQty();
$addressWeight+= $rowWeight;
if ($freeAddress || $item->getFreeShipping()===true) {
$rowWeight = 0;
} elseif (is_numeric($item->getFreeShipping())) {
$freeQty = $item->getFreeShipping();
if ($item->getQty()>$freeQty) {
$rowWeight = $itemWeight*($item->getQty()-$freeQty);
}
else {
$rowWeight = 0;
}
}
$freeMethodWeight+= $rowWeight;
$item->setRowWeight($rowWeight);
}
}
यह Magento के डिफ़ॉल्ट वाहक को प्रभावित क्यों नहीं करता है
आप के लिए एक regex खोज करते हैं /row_?weight/i(उदाहरण के लिए getRowWeight, setRowWeight, setData('row_weight')में, आदि)Mage_Shipping (सरल वाहक) और Mage_Usa(FedEx, UPS, और कुछ अन्य वाहक), कुछ भी दिखाई नहीं देता। क्यूं कर? क्योंकि डिफ़ॉल्ट वाहक कुल पता भार का उपयोग करते हैं, न कि व्यक्तिगत मद भार।
उदाहरण के लिए, आइए देखें Mage_Usa_Model_Shipping_Carrier_Fedex::setRequest:
public function setRequest(Mage_Shipping_Model_Rate_Request $request)
{
$this->_request = $request;
$r = new Varien_Object();
/* Snip */
$weight = $this->getTotalNumOfBoxes($request->getPackageWeight());
$r->setWeight($weight);
if ($request->getFreeMethodWeight()!= $request->getPackageWeight()) {
$r->setFreeMethodWeight($request->getFreeMethodWeight());
}
और अनुरोध को पैकेज का वजन कहां से मिलता है? जवाब में है Mage_Sales_Model_Quote_Address::requestShippingRates:
public function requestShippingRates(Mage_Sales_Model_Quote_Item_Abstract $item = null)
{
/** @var $request Mage_Shipping_Model_Rate_Request */
$request = Mage::getModel('shipping/rate_request');
/* Snip */
$request->setPackageWeight($item ? $item->getRowWeight() : $this->getWeight());
हम $item->getRowWeight()यहाँ के उपयोग को अनदेखा कर सकते हैं क्योंकि requestShippingRatesएक विशिष्ट वस्तु को एक पैरामीटर के रूप में प्रदान किए बिना कहा जाता है Mage_Sales_Model_Quote_Address_Total_Shipping::collect:
public function collect(Mage_Sales_Model_Quote_Address $address)
{
parent::collect($address);
foreach ($items as $item) {
/* Snip: Handling virtual items and parent items */
if ($item->getHasChildren() && $item->isShipSeparately()) {
/* Snip: Handling items with children */
}
else {
if (!$item->getProduct()->isVirtual()) {
$addressQty += $item->getQty();
}
$itemWeight = $item->getWeight();
$rowWeight = $itemWeight*$item->getQty();
$addressWeight+= $rowWeight;
if ($freeAddress || $item->getFreeShipping()===true) {
$rowWeight = 0;
} elseif (is_numeric($item->getFreeShipping())) {
$freeQty = $item->getFreeShipping();
if ($item->getQty()>$freeQty) {
$rowWeight = $itemWeight*($item->getQty()-$freeQty);
}
else {
$rowWeight = 0;
}
}
$freeMethodWeight+= $rowWeight;
$item->setRowWeight($rowWeight);
}
}
$address->setWeight($addressWeight);
$address->setFreeMethodWeight($freeMethodWeight);
$address->collectShippingRates();
यह परिचित दिखना चाहिए, क्योंकि यह वही स्थान है जो प्रत्येक आइटम के row_weightलिए निर्धारित है 0यदि मुफ्त शिपिंग प्रभावी है। ध्यान दें कि $addressWeightप्रत्येक आइटम पर रकम कैसे लगाई जाती है $rowWeight, लेकिन यह निर्धारित करने से पहलेrow_weight0 किया जाता है ।
मूल रूप से, पता वजन हमेशा सभी वस्तुओं का कुल वजन होगा, चाहे free_shippingप्रत्येक आइटम का मूल्य हो। चूंकि Magento के डिफ़ॉल्ट वाहक केवल पते के वजन पर निर्भर करते हैं, इसलिए समस्या row_weightदिखाई नहीं देती है।
तो हमें आवश्यकता क्यों है row_weight
हमें जरूरत है row_weightक्योंकि हमने विभिन्न मूल से आने वाली वस्तुओं के लिए अलग-अलग दरों की गणना करने के लिए Magento के FedEx वाहक को अनुकूलित किया है, भले ही वे एक ही गंतव्य पर जा रहे हों (और इस तरह एक ही पते का हिस्सा हैं)। उदाहरण के लिए, यदि आप एनजे में रहते हैं, तो एनए की तुलना में एनजे से एक आइटम जहाज करना सस्ता (और तेज) है - और यदि आपके पास ऑर्डर में एनजे और सीए दोनों से आइटम हैं, तो आप लागत (और अनुमानित) देख सकते हैं प्रत्येक शिपमेंट की डिलीवरी की तारीख)।
सब सब में, ऐसा लगता है कि हम इस मुद्दे को आसानी से अनदेखा row_weightऔर weight * qtyसीधे उपयोग करके काम कर सकते हैं । लेकिन, यह हमें निम्न करता है:
प्रश्न
अगर मुफ्त शिपिंग प्रभाव में है, तो बिक्री उद्धरण वस्तुओं का Shippingकुल सेट क्यों होता है? यह कहीं भी उपयोग किया जाना प्रतीत नहीं होता है।row_weight0
इसके अलावा अवलोकन
मैंने यह उल्लेख करने की उपेक्षा की कि row_weightवास्तव में गैर-शून्य हो सकता है, लेकिन फिर भी इससे कम है weight * qty, अगर free_shippingइसके बजाय एक संख्या है true। मेरा मानना है कि इसका उद्देश्य इस तरह से परिदृश्य का समाधान प्रदान करना है:
मेरी गाड़ी में एक ही उत्पाद के 3 आइटम हैं, प्रत्येक आइटम का वजन 2 पाउंड है। मैं एक मुफ्त शिपिंग कूपन लागू करता हूं, लेकिन यह 2 की मात्रा तक सीमित है, इसलिए यह केवल 2 आइटमों पर लागू होता है। अब, जब मैं शिपिंग दरों को देखता हूं, तो मैं 6 पाउंड (2 + 2 + 2) के बजाय 2 एलबीएस (2 + 0 + 0) के लिए शिपिंग दरों को देखूंगा।
यह समझ में आता है, लेकिन इसके साथ दो प्रमुख समस्याएं हैं:
कोई भी डिफ़ॉल्ट Magento के वाहक इस तरह से काम नहीं करते हैं (वे पते के कुल वजन का उपयोग करते हैं, ऊपर देखें)।
यहां तक कि अगर कुछ वाहक इस तरह से काम करते हैं, तो इसका मतलब है कि मैं किसी भी शिपिंग विधि (जैसे रात भर शिपिंग) को चुन सकता हूं और केवल 1 आइटम के वजन के लिए भुगतान कर सकता हूं - मतलब, व्यापारी को अन्य 2 वस्तुओं की लागत को कवर करना होगा । यह व्यापारी पर निर्भर होगा कि मैं केवल 1 आइटम के वजन के लिए भुगतान करता हूं, और फिर अन्य 2 वस्तुओं को अधिक लागत प्रभावी विधि का उपयोग करके जहाज करता हूं, जो प्रभावी रूप से मैगेंटो प्रदर्शित करता है और आइटम वास्तव में कैसे थे के बीच एक बेमेल निर्माण करता है। बाहर भेज दिया।