Dlaczego suma Wysyłka ustawia wartość waga_wiersza pozycji oferty handlowej na 0, jeśli obowiązuje darmowa wysyłka?

21

Przedmowa: Ma to służyć zarówno jako pisemna obserwacja architektury Magento dla społeczności (i mnie), jak i jako rzeczywiste pytanie. Pracujemy nad silnie zmodyfikowanym koszykiem i obsługą kasy, ale źródło tego problemu leży w głównej logice Magento.

tło

Stworzyliśmy bezpłatny kupon wysyłkowy, korzystając ze standardowej funkcjonalności reguł ceny w koszyku. Kupon nie ma żadnych warunków, a jedyną czynnością Free Shippingjest ustawienie For matching items only. Ponieważ nie istnieją żadne warunki, to ustawić free_shippingaby 1dla wszystkich elementów cytując sprzedaży.

Jak zwykle, włączyliśmy również metodę bezpłatnej wysyłki. Model Freeshippingprzewoźnika zapewnia stawki, ilekroć żądanie ma bezpłatną wysyłkę lub suma częściowa odpowiada lub przekracza próg (ale nie korzystamy z opcji progu). Zobacz 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 */
}

I Mage_Shipping_Model_Carrier_Freeshipping::_updateFreeMethodQuotewygląda tak:

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);
    }
}

Tak więc, o ile wszystkie elementy mają free_shippingustawioną wartość zgodną z prawdą (którą będą, ze względu na kupon), powinniśmy otrzymać bezpłatną wysyłkę. I my robimy!

Problem

Istnieje jednak poważny efekt uboczny: wszelkie metody wysyłki, które opierają się na elemencie produktu row_weight(jak ma to miejsce w przypadku naszej dostosowanej wersji przewoźnika FedEx), nie obliczą prawidłowych stawek wysyłki, ponieważ dla każdego elementu row_weightjest ustawiona opcja, 0gdy aktywna jest bezpłatna wysyłka.

Co ciekawe, żaden z domyślnych przewoźników Magento tak naprawdę nie polega row_weight, ale przejdziemy do tego po tym, jak ustalimy, dlaczego / kiedy row_weightjest ustawiony 0.

Zrozumienie, dlaczego row_weightjest ustawione0

Ta część była dość łatwa do wykopania. Duży fragment obliczeń żeglugi wydarzy się w Mage_Sales_Model_Quote_Address_Total_Shipping::collecttym otoczeniu row_weightdo 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);
        }
    }

Dlaczego nie wpływa to na domyślnych operatorów Magento

Jeśli nie szukaj regex /row_?weight/i(np getRowWeight, setRowWeight, setData('row_weight'), itd.) Na Mage_Shipping(proste) i nośniki Mage_Usa(FedEx, UPS, i kilka innych przewoźników), nic nie wyskakuje. Czemu? Ponieważ domyślni przewoźnicy używają całkowitej masy adresu, a nie poszczególnych wag.

Na przykład spójrzmy na 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());
    }

A skąd zapytanie bierze wagę paczki? Odpowiedź jest w 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());

Możemy zignorować użycie $item->getRowWeight()tutaj, ponieważ requestShippingRatesjest wywoływane bez podania określonego elementu jako parametru w 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();

Powinno to wyglądać znajomo, ponieważ jest to to samo miejsce, w którym row_weightustawiony jest każdy element, 0jeśli obowiązuje bezpłatna wysyłka. Wskazówki jak $addressWeightpodsumowuje każdego elementu $rowWeight, ale to zrobione przed row_weightjest ustawiona0 .

Zasadniczo waga adresu zawsze będzie całkowitą wagą wszystkich pozycji, niezależnie od free_shippingwartości każdej pozycji. Ponieważ domyślni operatorzy Magento polegają tylko na wadze adresu, problem z row_weightnie pojawia się.

Dlaczego więc potrzebujemy row_weight

Potrzebujemy, row_weightponieważ dostosowaliśmy przewoźnika FedEx Magento do obliczania oddzielnych stawek dla produktów pochodzących z różnych źródeł, nawet jeśli idą do tego samego miejsca docelowego (a zatem są częścią tego samego adresu). Na przykład, jeśli mieszkasz w NJ, tańsze (i szybsze) jest wysłanie przedmiotu z NJ niż z CA - a jeśli masz w zamówieniu przedmioty zarówno z NJ, jak i CA, możesz zobaczyć koszt (i oszacować data dostawy) każdej przesyłki.

Podsumowując, wygląda na to, że możemy łatwo obejść ten problem, ignorując row_weighti używając weight * qtybezpośrednio. Ale prowadzi nas to do:

Pytanie

Dlaczego Shippingsuma ustawia row_weightpozycje z ofert sprzedaży, 0jeśli obowiązuje bezpłatna wysyłka? To nie wydaje się być nigdzie wykorzystywane.

Dalsze obserwacje

Zlekceważyłem wspomnienie, że to row_weightmoże być niezerowe, ale wciąż mniejsze niż weight * qty, jeśli free_shippingzamiast jest liczba true. Zakładam, że celem tego jest zapewnienie rozwiązania takiego scenariusza:

Mam w koszyku 3 produkty tego samego produktu, każdy waży 2 funty. Stosuję kupon na bezpłatną wysyłkę, ale jest on ograniczony do ilości 2, więc dotyczy tylko 2 produktów. Teraz, gdy spojrzę na stawki wysyłki, będę patrzeć na stawki wysyłki 2 funtów (2 + 0 + 0) zamiast 6 funtów (2 + 2 + 2).

Wydaje się to mieć sens, ale istnieją dwa główne problemy:

  • Żaden z domyślnych nośników Magento nie działa w ten sposób (używają masy całkowitej adresu, patrz wyżej).

  • Nawet jeśli niektórzy przewoźnicy działali w ten sposób, oznaczałoby to, że mogłem wybrać dowolną metodę wysyłki (np. Przesyłkę na noc) i zapłacić tylko za wagę 1 sztuki - co oznacza, że ​​sprzedawca musiałby pokryć koszt pozostałych 2 produktów . Do kupca należałoby dowiedzieć się, że zapłaciłem tylko za wagę 1 przedmiotu, a następnie wysłałem pozostałe 2 przedmioty przy użyciu bardziej opłacalnej metody, skutecznie tworząc rozbieżność między tym, co wyświetla Magento, a tym, jak rzeczy były w rzeczywistości wysłane.

Agop
źródło
Hej, nie ma chętnych? :)
Agop,
Tyle głosów w górę, tak mało dyskusji! Takie jest życie w rozwoju Magento.
Agop

Odpowiedzi:

2

Pomyślałem, że wezmę w tym pchnięcie ...;)

Dosyć interesujące pytanie, które tu postawiłeś, więc oto dlaczego myślę, że to zrobili, ale wciąż pracuję nad wyśledzeniem, kiedy ten konkretny przypadek wejdzie w grę.

Omawiając metodę przewoźnika USPS, wygląda na to, że Międzynarodowe zapytania do ich API podają wyszczególnione wagi dla każdego produktu. To jedyny przewoźnik, który mogę znaleźć, który to robi. Znajdź pełną metodę poniżej, a podświetloną sekcję poniżej.

protected function _formIntlShipmentRequest(Varien_Object $request)
    {
        $packageParams = $request->getPackageParams();
        $height = $packageParams->getHeight();
        $width = $packageParams->getWidth();
        $length = $packageParams->getLength();
        $girth = $packageParams->getGirth();
        $packageWeight = $request->getPackageWeight();
        if ($packageParams->getWeightUnits() != Zend_Measure_Weight::POUND) {
            $packageWeight = Mage::helper('usa')->convertMeasureWeight(
                $request->getPackageWeight(),
                $packageParams->getWeightUnits(),
                Zend_Measure_Weight::POUND
            );
        }
        if ($packageParams->getDimensionUnits() != Zend_Measure_Length::INCH) {
            $length = round(Mage::helper('usa')->convertMeasureDimension(
                $packageParams->getLength(),
                $packageParams->getDimensionUnits(),
                Zend_Measure_Length::INCH
            ));
            $width = round(Mage::helper('usa')->convertMeasureDimension(
                $packageParams->getWidth(),
                $packageParams->getDimensionUnits(),
                Zend_Measure_Length::INCH
            ));
            $height = round(Mage::helper('usa')->convertMeasureDimension(
                $packageParams->getHeight(),
                $packageParams->getDimensionUnits(),
                Zend_Measure_Length::INCH
            ));
        }
        if ($packageParams->getGirthDimensionUnits() != Zend_Measure_Length::INCH) {
            $girth = round(Mage::helper('usa')->convertMeasureDimension(
                $packageParams->getGirth(),
                $packageParams->getGirthDimensionUnits(),
                Zend_Measure_Length::INCH
            ));
        }

        $container = $request->getPackagingType();
        switch ($container) {
            case 'VARIABLE':
                $container = 'VARIABLE';
                break;
            case 'FLAT RATE ENVELOPE':
                $container = 'FLATRATEENV';
                break;
            case 'FLAT RATE BOX':
                $container = 'FLATRATEBOX';
                break;
            case 'RECTANGULAR':
                $container = 'RECTANGULAR';
                break;
            case 'NONRECTANGULAR':
                $container = 'NONRECTANGULAR';
                break;
            default:
                $container = 'VARIABLE';
        }
        $shippingMethod = $request->getShippingMethod();
        list($fromZip5, $fromZip4) = $this->_parseZip($request->getShipperAddressPostalCode());

        // the wrap node needs for remove xml declaration above
        $xmlWrap = new SimpleXMLElement('<?xml version = "1.0" encoding = "UTF-8"?><wrap/>');
        $method = '';
        $service = $this->getCode('service_to_code', $shippingMethod);
        if ($service == 'Priority') {
            $method = 'Priority';
            $rootNode = 'PriorityMailIntlRequest';
            $xml = $xmlWrap->addChild($rootNode);
        } else if ($service == 'First Class') {
            $method = 'FirstClass';
            $rootNode = 'FirstClassMailIntlRequest';
            $xml = $xmlWrap->addChild($rootNode);
        } else {
            $method = 'Express';
            $rootNode = 'ExpressMailIntlRequest';
            $xml = $xmlWrap->addChild($rootNode);
        }

        $xml->addAttribute('USERID', $this->getConfigData('userid'));
        $xml->addAttribute('PASSWORD', $this->getConfigData('password'));
        $xml->addChild('Option');
        $xml->addChild('Revision', self::DEFAULT_REVISION);
        $xml->addChild('ImageParameters');
        $xml->addChild('FromFirstName', $request->getShipperContactPersonFirstName());
        $xml->addChild('FromLastName', $request->getShipperContactPersonLastName());
        $xml->addChild('FromFirm', $request->getShipperContactCompanyName());
        $xml->addChild('FromAddress1', $request->getShipperAddressStreet2());
        $xml->addChild('FromAddress2', $request->getShipperAddressStreet1());
        $xml->addChild('FromCity', $request->getShipperAddressCity());
        $xml->addChild('FromState', $request->getShipperAddressStateOrProvinceCode());
        $xml->addChild('FromZip5', $fromZip5);
        $xml->addChild('FromZip4', $fromZip4);
        $xml->addChild('FromPhone', $request->getShipperContactPhoneNumber());
        if ($method != 'FirstClass') {
            if ($request->getReferenceData()) {
                $referenceData = $request->getReferenceData() . ' P' . $request->getPackageId();
            } else {
                $referenceData = $request->getOrderShipment()->getOrder()->getIncrementId()
                                 . ' P'
                                 . $request->getPackageId();
            }
            $xml->addChild('FromCustomsReference', 'Order #' . $referenceData);
        }
        $xml->addChild('ToFirstName', $request->getRecipientContactPersonFirstName());
        $xml->addChild('ToLastName', $request->getRecipientContactPersonLastName());
        $xml->addChild('ToFirm', $request->getRecipientContactCompanyName());
        $xml->addChild('ToAddress1', $request->getRecipientAddressStreet1());
        $xml->addChild('ToAddress2', $request->getRecipientAddressStreet2());
        $xml->addChild('ToCity', $request->getRecipientAddressCity());
        $xml->addChild('ToProvince', $request->getRecipientAddressStateOrProvinceCode());
        $xml->addChild('ToCountry', $this->_getCountryName($request->getRecipientAddressCountryCode()));
        $xml->addChild('ToPostalCode', $request->getRecipientAddressPostalCode());
        $xml->addChild('ToPOBoxFlag', 'N');
        $xml->addChild('ToPhone', $request->getRecipientContactPhoneNumber());
        $xml->addChild('ToFax');
        $xml->addChild('ToEmail');
        if ($method != 'FirstClass') {
            $xml->addChild('NonDeliveryOption', 'Return');
        }
        if ($method == 'FirstClass') {
            if (stripos($shippingMethod, 'Letter') !== false) {
                $xml->addChild('FirstClassMailType', 'LETTER');
            } else if (stripos($shippingMethod, 'Flat') !== false) {
                $xml->addChild('FirstClassMailType', 'FLAT');
            } else{
                $xml->addChild('FirstClassMailType', 'PARCEL');
            }
        }
        if ($method != 'FirstClass') {
            $xml->addChild('Container', $container);
        }
        $shippingContents = $xml->addChild('ShippingContents');
        $packageItems = $request->getPackageItems();
        // get countries of manufacture
        $countriesOfManufacture = array();
        $productIds = array();
        foreach ($packageItems as $itemShipment) {
                $item = new Varien_Object();
                $item->setData($itemShipment);

                $productIds[]= $item->getProductId();
        }
        $productCollection = Mage::getResourceModel('catalog/product_collection')
            ->addStoreFilter($request->getStoreId())
            ->addFieldToFilter('entity_id', array('in' => $productIds))
            ->addAttributeToSelect('country_of_manufacture');
        foreach ($productCollection as $product) {
            $countriesOfManufacture[$product->getId()] = $product->getCountryOfManufacture();
        }

        $packagePoundsWeight = $packageOuncesWeight = 0;
        // for ItemDetail
        foreach ($packageItems as $itemShipment) {
            $item = new Varien_Object();
            $item->setData($itemShipment);

            $itemWeight = $item->getWeight() * $item->getQty();
            if ($packageParams->getWeightUnits() != Zend_Measure_Weight::POUND) {
                $itemWeight = Mage::helper('usa')->convertMeasureWeight(
                    $itemWeight,
                    $packageParams->getWeightUnits(),
                    Zend_Measure_Weight::POUND
                );
            }
            if (!empty($countriesOfManufacture[$item->getProductId()])) {
                $countryOfManufacture = $this->_getCountryName(
                    $countriesOfManufacture[$item->getProductId()]
                );
            } else {
                $countryOfManufacture = '';
            }
            $itemDetail = $shippingContents->addChild('ItemDetail');
            $itemDetail->addChild('Description', $item->getName());
            $ceiledQty = ceil($item->getQty());
            if ($ceiledQty < 1) {
                $ceiledQty = 1;
            }
            $individualItemWeight = $itemWeight / $ceiledQty;
            $itemDetail->addChild('Quantity', $ceiledQty);
            $itemDetail->addChild('Value', $item->getCustomsValue() * $item->getQty());
            list($individualPoundsWeight, $individualOuncesWeight) = $this->_convertPoundOunces($individualItemWeight);
            $itemDetail->addChild('NetPounds', $individualPoundsWeight);
            $itemDetail->addChild('NetOunces', $individualOuncesWeight);
            $itemDetail->addChild('HSTariffNumber', 0);
            $itemDetail->addChild('CountryOfOrigin', $countryOfManufacture);

            list($itemPoundsWeight, $itemOuncesWeight) = $this->_convertPoundOunces($itemWeight);
            $packagePoundsWeight += $itemPoundsWeight;
            $packageOuncesWeight += $itemOuncesWeight;
        }
        $additionalPackagePoundsWeight = floor($packageOuncesWeight / self::OUNCES_POUND);
        $packagePoundsWeight += $additionalPackagePoundsWeight;
        $packageOuncesWeight -= $additionalPackagePoundsWeight * self::OUNCES_POUND;
        if ($packagePoundsWeight + $packageOuncesWeight / self::OUNCES_POUND < $packageWeight) {
            list($packagePoundsWeight, $packageOuncesWeight) = $this->_convertPoundOunces($packageWeight);
        }

        $xml->addChild('GrossPounds', $packagePoundsWeight);
        $xml->addChild('GrossOunces', $packageOuncesWeight);
        if ($packageParams->getContentType() == 'OTHER' && $packageParams->getContentTypeOther() != null) {
            $xml->addChild('ContentType', $packageParams->getContentType());
            $xml->addChild('ContentTypeOther ', $packageParams->getContentTypeOther());
        } else {
            $xml->addChild('ContentType', $packageParams->getContentType());
        }

        $xml->addChild('Agreement', 'y');
        $xml->addChild('ImageType', 'PDF');
        $xml->addChild('ImageLayout', 'ALLINONEFILE');
        if ($method == 'FirstClass') {
            $xml->addChild('Container', $container);
        }
        // set size
        if ($packageParams->getSize()) {
            $xml->addChild('Size', $packageParams->getSize());
        }
        // set dimensions
        $xml->addChild('Length', $length);
        $xml->addChild('Width', $width);
        $xml->addChild('Height', $height);
        if ($girth) {
            $xml->addChild('Girth', $girth);
        }

        $xml = $xmlWrap->{$rootNode}->asXML();
        return $xml;
    }

Część szczególna:

$packagePoundsWeight = $packageOuncesWeight = 0;
        // for ItemDetail
        foreach ($packageItems as $itemShipment) {
            $item = new Varien_Object();
            $item->setData($itemShipment);

            $itemWeight = $item->getWeight() * $item->getQty();
            if ($packageParams->getWeightUnits() != Zend_Measure_Weight::POUND) {
                $itemWeight = Mage::helper('usa')->convertMeasureWeight(
                    $itemWeight,
                    $packageParams->getWeightUnits(),
                    Zend_Measure_Weight::POUND
                );
            }
            if (!empty($countriesOfManufacture[$item->getProductId()])) {
                $countryOfManufacture = $this->_getCountryName(
                    $countriesOfManufacture[$item->getProductId()]
                );
            } else {
                $countryOfManufacture = '';
            }
            $itemDetail = $shippingContents->addChild('ItemDetail');
            $itemDetail->addChild('Description', $item->getName());
            $ceiledQty = ceil($item->getQty());
            if ($ceiledQty < 1) {
                $ceiledQty = 1;
            }
            $individualItemWeight = $itemWeight / $ceiledQty;
            $itemDetail->addChild('Quantity', $ceiledQty);
            $itemDetail->addChild('Value', $item->getCustomsValue() * $item->getQty());
            list($individualPoundsWeight, $individualOuncesWeight) = $this->_convertPoundOunces($individualItemWeight);
            $itemDetail->addChild('NetPounds', $individualPoundsWeight);
            $itemDetail->addChild('NetOunces', $individualOuncesWeight);
            $itemDetail->addChild('HSTariffNumber', 0);
            $itemDetail->addChild('CountryOfOrigin', $countryOfManufacture);

            list($itemPoundsWeight, $itemOuncesWeight) = $this->_convertPoundOunces($itemWeight);
            $packagePoundsWeight += $itemPoundsWeight;
            $packageOuncesWeight += $itemOuncesWeight;
        }

Wydaje mi się, że Magento ponownie oblicza wagę paczki w oparciu o rzeczywistą wagę przedmiotu i nie wykorzystuje wagi adresu. Zastanawiam się, czy przesyłane elementy paczki nie mają wyzerowanej wagi, ponieważ prowadziłoby to do fałszywych wag przedmiotów, biorąc pod uwagę, że odpowiedzi szybkości byłyby oparte na złych danych dotyczących masy.

Strzał w ciemność.

Daniel Kenney
źródło
1

Miałem też kłopot z tym i znalazłem coś interesującego w tej linii kodu

$item->setRowWeight($rowWeight);

został wprowadzony w wersji 1.1.5 wcześniej, że funkcja była taka.

Magento Mirror Import Magento Release 1.1.5 - Shipping.php

Magento Mirror Import Magento Release 1.1.1 - Shipping.php

            else {
            if (!$item->getProduct()->getTypeInstance()->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;
        }
    }

Rozumiem, że Mage_Sales_Model_Quote_Address_Total_Shipping :: zbierać trzeba obliczyć / zaktualizować $ addressWeight i $ freeMethodWeight

    $addressWeight      = $address->getWeight();
    $freeMethodWeight   = $address->getFreeMethodWeight();

i $ item-> setRowWeight nie powinno być tutaj użyte, ponieważ jest związane z przedmiotem, a nie z cytatem i adresem.

Założę się, że to błąd. Prawdopodobnie row_total nigdy nie był przeznaczony do stosowania w metodach wysyłki, dlatego domyślne moduły go nie używają.

Nie byłem w stanie wyśledzić żadnego dziennika zmian, który mógłby wyjaśnić, dlaczego został wprowadzony w wersji 1.1.5.

Daniel Yovchev
źródło