Отримання винятку "Будь ласка, вкажіть спосіб доставки" під час оформлення замовлення


18

Я отримую журнали винятків для цієї помилки у виробництві, але я не можу відтворити проблему в моєму локальному або інсценізаційному середовищі, тому вирішити проблеми було досить важко.

Помилка виникає Mage_Sales_Model_Service_Quote::_validate()через те, що $rateповернуте повідомлення $rate = $address->getShippingRateByCode($method)порожнє.

Я додав у деяких журналах, щоб спробувати краще зрозуміти, що відбувається, і я можу побачити, що $methodмістить правильний спосіб доставки.

Я найкраще здогадуюсь, що в якийсь момент процесу доставки тарифи видаляються до того, як вони повинні бути.

Я помітив, що кожного разу, коли цей виняток відбувається, це відбувається одразу після законного винятку, наприклад, недійсної кредитної картки. Я намагався відтворити проблему за допомогою недійсної кредитної картки, а потім дійсної, але вона не відтворюється для мене - в постановці, виробництві чи на місцевому рівні.

Моя первинна думка полягала в тому, що, можливо, метод доставки десь загубився після першого дійсного винятку, але це не так, тому що я бачу, що $methodмає правильне значення на момент скидання цього винятку.

Модуль оформлення замовлень, який я використовую, - це AwesomeCheckout - він, наскільки мені не відомо, не має власної логіки при створенні замовлень, які тут можуть викликати проблеми, але можуть бути пов'язані.

ОНОВЛЕННЯ: Я додав у якийсь код, щоб спробувати пригадати ціни, якщо вони відсутні.

protected function _validate()
{
    if (!$this->getQuote()->isVirtual()) {
        $address = $this->getQuote()->getShippingAddress();
        $addressValidation = $address->validate();
        if ($addressValidation !== true) {
            Mage::throwException(
                Mage::helper('sales')->__('Please check shipping address information. %s', implode(' ', $addressValidation))
            );
        }
        $method= $address->getShippingMethod();
        $rate  = $address->getShippingRateByCode($method);

        /**
         * Start Customization
         */
        if (!$this->getQuote()->isVirtual() && !$rate) {
            Mage::logException(new Exception("Rate was empty inside quote validate method, trying to forcefully recalculate"));
            $this->getQuote()->getShippingAddress()->setCollectShippingRates(true);
            $this->getQuote()->setTotalsCollectedFlag(false);
            $this->getQuote()->collectTotals();
            $rate  = $address->getShippingRateByCode($method);
        }
        /** End Customization **/             

        if (!$this->getQuote()->isVirtual() && (!$method || !$rate)) {
            Mage::throwException(Mage::helper('sales')->__('Please specify a shipping method.'));
        }
    }

Використовуєте розширення для доставки третьої сторони? Тестування за допомогою рідного методу Magento на зразок flatrate, можливо, дасть деяке розуміння, чи це розширення оформлення замовлення, чи розширення для доставки
Sander Mangel

1
Я також бачив магазин, коли це відбувається у виробництві, часто багато разів поспіль. Ми ніколи не змогли відтворити себе в жодному середовищі.
Peter O'Callaghan

@Sander, так, ми використовуємо розширення сторонніх розробників. Я впевнений, що це не першопричина, тому що вона повертає ставки за методом colleRates () просто добре, і навіть у випадках, коли це не вдається, я можу бачити, що ставки поверталися за API просто чудово.
kalenjordan

@Cags, справді ??! Добре знати, можливо, нам доведеться позначити це командою. Це одна з тих речей, яка важлива, але оскільки вона відтворюється дуже рідко, це не є головним пріоритетом.
kalenjordan

@SanderMangel, на жаль, спробувати це з flatrate - це не варіант, тому що ми не можемо просто припинити подавати правильні тарифи на доставку сотням клієнтів у виробництві, щоб спробувати відтворити проблему. Якби я міг відтворити це в моєму місцевому середовищі, напевне тестування на метод доставки ванілі було б одним із перших речей, які я б спробував.
kalenjordan

Відповіді:


8

Ви повинні зрозуміти, як працюють тарифи та як їх запитують. В основному ставки запитуються, коли ->setCollectShippingRates(true)вони встановлені на об'єкт shippinAddress, і це призводить до того, що тарифи збираються та зберігаються в таблиці тарифів. Цю таблицю після цього спорожняють і знову заповнюють на новий запит тарифу.

у вашому випадку відбувається те, що помилка видається і запит повторюється, а тарифи не запитуються, але, як очікується, вони будуть. Тому спробуйте примусити стягувати тарифи

getQuote()->getShippingAddress()->setCollectShippingRates(true);

а потім спробуйте згадати підсумки, якщо це не працює

getQuote()->setTotalsCollectedFlag(false)->collectTotals();

попередити, що виклик збирання збірних даних кілька разів може зіпсувати підсумки, якщо деяке розширення не реалізує правильно об'єкти підсумки (загальний недолік)


Спасибі, має сенс. Будь-яка ідея, чому це трапляється так рідко? Якщо помилка платежу скидає ставки, я б очікував, що це буде відбуватися кожного разу, коли з’явиться помилка платежу.
kalenjordan

це залежить від прапорів, і якщо він викликається чи ні, якщо ви можете повторити це помилково, то це легко простежити за допомогою налагоджувача. Однак якщо помилка вашого способу оплати не робить повний перехід на сервер і просто порушує запит при виході, він може просто зламати всіх залежних спостерігачів тощо виконання
Anton S

Додано в якийсь код, і він все ще не вдався. Я забув $this->getQuote()->getShippingAddress()->setCollectShippingRates(true)лінію, хоча я зараз спробую це спробувати.
kalenjordan

Проблема повторилася, і наявний у мене код не допустив виникнення виключення. Але транзакція все-таки не вдалася, оскільки SIMULTANEOUSLY брейнтрей був знижений протягом декількох хвилин. Неймовірно.
kalenjordan

1
Добре подряпайте це. Причина, що сталася цього разу, була з зовсім інших причин. Замовлення на підписку намагалися створити для адреси, де фактично не було доступних тарифів на доставку, тому повідомлення про помилку було дійсним. @ProxiBlue
kalenjordan

3

Можливо, це з’ясували. У мене був пов’язаний виняток, який кидався приблизно з тією ж частотою, що і цей, який був "Запрошений спосіб оплати недоступний".

Виявляється, що це сталося через те, що один з моїх спостерігачів не sales_place_order_afterстворював цінового об'єкта (і зберігав його), щоб генерувати певні ціни на передплату.

Мені вдалося відтворити його, спочатку перевіривши погану кредитну карту як нового клієнта (не ввійшов у систему), потім повернувшись назад, виправивши кредитну карту та спробу оформити замовлення ще раз.

Виняток було киданням, оскільки у loadCustomerQuoteспостерігача customer_login, він злиє ваші котирування разом, якщо у вас є більше однієї цитати, і, таким чином, втрачає частину інформації про спосіб оплати в цитаті.

Виправлення полягало в тому, щоб видалити нову цитату, яку я створював у своєму спостерігачі за підпискою.

ОНОВЛЕННЯ: Ні, виправлення для "Запрошений спосіб оплати недоступний" не вирішив цю проблему, все ще виникає.


Досить пізно, але саме тому я більше не використовую цю подію (місце замовлення після продажу). Якщо мені потрібно щось статися після замовлення, я заходжу в чергу.
philwinkle

Так само ви допоможете мені вирішити "Будь ласка, вкажіть спосіб доставки" у сторінці помилки на сторінку оформлення замовлення: magento.stackexchange.com/q/225297/57334
zus

0

Зауваживши, іноді PayPal Express при розміщенні замовлення видає помилку із записом "Платник не визначений". Ця помилка пов'язана з тим самим винятком "Будь ласка, вкажіть спосіб доставки". У Magento 1.8.1.0 це легко відтворити, викликаючи "злиття котирування" або "злиття кошика" при розміщенні замовлення. Об'єднання котирувань або візків призведе до очищення тарифів на доставку, але не перерахунку. Насправді ви не хочете цього виправляти, адже тоді клієнт може платити більше, ніж те, про що домовились! Натомість ви захочете видалити функцію злиття - або оновити Magento.

Це зафіксовано в 1.9; спочатку клієнти повинні увійти, перш ніж вони перенаправляться на PayPal.


0

У моєму випадку ця помилка походить від nullзначення в $methodі$rate

$method= $address->getShippingMethod();
$rate  = $address->getShippingRateByCode($method);
    if (!$this->getQuote()->isVirtual() && (!$method || !$rate)) {
Mage::throwException(Mage::helper('sales')->__('Please specify a 
shipping method.'));
}

тому я встановив ставку від цього. методом та швидкістю, які доступні у вашому магенто

$quote = Mage::getSingleton('checkout/session')->getQuote();
$address = $quote->getShippingAddress();
$shippingMethod = 'amtable_amtable5';
$shippingMethod = 'flatrate_flatrate';
$address->setCollectShippingRates(true)->collectShippingRates()->setShippingMethod($shippingMethod);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.