উপস্থাপনা: এটি সম্প্রদায়ের (এবং আমার) জন্য ম্যাজেন্টোর স্থাপত্যের লিখিত পর্যবেক্ষণ, পাশাপাশি একটি আসল প্রশ্ন উভয় হিসাবে পরিবেশন করা। আমরা একটি ভারী পরিবর্তিত কার্ট এবং চেকআউট অভিজ্ঞতা নিয়ে কাজ করছি, তবে এই সমস্যার মূলে রয়েছে ম্যাগান্তোর মূল যুক্তি।
পটভূমি
আমরা স্ট্যান্ডার্ড শপিং কার্টের মূল্য বিধি কার্যকারিতা ব্যবহার করে একটি নিখরচায় শিপিং কুপন তৈরি করেছি। কুপনে কোনও শর্ত নেই এবং কেবলমাত্র অ্যাকশন 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(যেমনটি আমাদের ফেডেক্স ক্যারিয়ারের নিজস্ব কাস্টমাইজড সংস্করণে হয়) উপযুক্ত শিপিং হারগুলি গণনা করতে ব্যর্থ হবে কারণ ফ্রি শিপিং সক্রিয় থাকাকালীন প্রতিটি আইটেম 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);
}
}
কেন এটি ম্যাজেন্টোর ডিফল্ট ক্যারিয়ারগুলিকে প্রভাবিত করে না
আপনার জন্য একটি Regex অনুসন্ধান করেন তাহলে /row_?weight/i(যেমন getRowWeight, setRowWeight, setData('row_weight'), ইত্যাদি) Mage_Shipping(সাধারণ বাহকদের) এবংMage_Usa (আপনি FedEx, ইউ.পি. এস, এবং কিছু অন্যান্য বাহক), কিছুই পপ আপ। কেন? কারণ ডিফল্ট ক্যারিয়ারগুলি পৃথক আইটেমের ওজন নয়, মোট ঠিকানার ওজন ব্যবহার করে।
উদাহরণস্বরূপ, আসুন দেখুন 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_weightসেট হয়ে গেছে0 ।
মূলত, ঠিকানাটির ওজন সর্বদা free_shippingপ্রতিটি আইটেমের মূল্য নির্বিশেষে সমস্ত আইটেমের মোট ওজন হবে । যেহেতু ম্যাজেন্টোর ডিফল্ট ক্যারিয়ার কেবল ঠিকানা ওজনের উপর নির্ভরশীল, তাই সমস্যাটি প্রদর্শিত row_weightহবে না।
তাহলে আমাদের কেন দরকার? row_weight
আমাদের দরকার row_weight কারণ আমরা একই গন্তব্যে (এমনকি একই ঠিকানাটির অংশ হিসাবে) চলে গেলেও বিভিন্ন উত্স থেকে আগত আইটেমগুলির জন্য পৃথক হার গণনা করার জন্য আমরা ম্যাগেন্টোর ফেডেক্স ক্যারিয়ারকে কাস্টমাইজ করেছি। উদাহরণস্বরূপ, আপনি যদি এনজে থাকেন তবে সিএ থেকে এনজে থেকে কোনও জিনিস বহন করা সস্তা (এবং দ্রুত) - এবং যদি আপনার ক্রমে এনজে এবং সিএ উভয় থেকে আইটেম থাকে তবে আপনি ব্যয়টি দেখতে পারবেন (এবং আনুমানিক অনুমান) প্রতিটি চালানের ডেলিভারি তারিখ)।
সব মিলিয়ে দেখে মনে হচ্ছে আমরা সরাসরি উপেক্ষা করে row_weightএবং ব্যবহার করে সহজেই এই সমস্যাটি ঘিরে কাজ করতে পারি weight * qty। তবে, এটি আমাদের দিকে নিয়ে যায়:
প্রশ্নটি
নিখরচায় শিপিং কার্যকর হলে Shippingমোট কেন row_weightবিক্রয় মূল্য আইটেম সেট করে 0? এটি কোথাও ব্যবহার করা হবে বলে মনে হয় না।
আরও পর্যবেক্ষণ
আমি উল্লেখ করতে অবহেলা করেছি যে row_weightএটি আসলে শূন্য-শূন্য হতে পারে, তবে তার চেয়ে কম weight * qty, যদি এর free_shippingপরিবর্তে একটি সংখ্যা হয় true। আমি ধরে নিই এর উদ্দেশ্য হল এর মতো দৃশ্যের সমাধান দেওয়া:
আমার কার্টে একই পণ্যটির 3 টি আইটেম রয়েছে, প্রতিটি আইটেম 2 পাউন্ড ওজনের। আমি একটি নিখরচায় শিপিং কুপন প্রয়োগ করি, তবে এটি 2 এর পরিমাণের মধ্যে সীমাবদ্ধ, সুতরাং এটি কেবলমাত্র 2 টি আইটেমের ক্ষেত্রে প্রযোজ্য। এখন, আমি যখন শিপিংয়ের হারগুলি দেখি, আমি শিপিং রেটগুলি 6 পাউন্ডের (2 + 2 + 2) এর পরিবর্তে 2 পাউন্ডের (2 + 0 + 0) খুঁজছি।
এটি বোধগম্য মনে হয় তবে এর সাথে দুটি বড় সমস্যা রয়েছে:
ডিফল্ট ম্যাজেন্টো ক্যারিয়ারগুলির মধ্যে কেউই এ জাতীয় কাজ করে না (তারা ঠিকানাটি মোট ওজন ব্যবহার করে, উপরে দেখুন)।
এমনকি কিছু ক্যারিয়ার যদি এটির মতো কাজ করে, তার অর্থ হ'ল আমি যে কোনও শিপিং পদ্ধতি বাছাই করতে পারি (উদাহরণস্বরূপ রাতারাতি শিপিং) এবং কেবলমাত্র 1 আইটেমের ওজনের জন্য অর্থ প্রদান করতে পারি - অর্থ্যাৎ বণিককে অন্য 2 টি আইটেমের ব্যয় বহন করতে হবে । মার্চেন্টের উপর নির্ভর করে কোনওভাবে এটি নির্ধারণ করা হবে যে আমি কেবল 1 টি আইটেমের ওজনের জন্য অর্থ প্রদান করেছি এবং তারপরে আরও 2 টি আইটেমকে আরও ব্যয়বহুল কার্যকর পদ্ধতি ব্যবহার করে জাহাজে পাঠিয়েছি, কার্যকরভাবে ম্যাজেন্টো কী প্রদর্শন করে এবং কীভাবে আইটেমগুলি আসলে ছিল তার মধ্যে একটি অমিল সৃষ্টি করে বাইরে পাঠানো