2015-09-24 22 views
13

Tôi đang cố thay đổi giao hàng theo đơn đặt hàng hiện có trong Magento. Điều này làm việc tốt từ backend admin, ngay cả khi nó khá là quá trình vì tôi phải cập nhật thủ công nhiều trường/thuộc tính thứ tự sau khi tôi đặt phương thức giao hàng mới trên đối tượng địa chỉ giao hàng và tính toán lại tổng số trích dẫn.Magento: thay đổi phương thức giao hàng theo đơn hàng hiện tại

Vấn đề của tôi là khi chạy cùng mã trên giao diện người dùng, nó hoàn toàn không hoạt động, collectTotals trích dẫn sẽ hoàn nguyên mọi thay đổi tôi đã thực hiện trong shippingAddress và tôi không biết cách giải quyết hoặc tại sao nó hoạt động từ phần phụ trợ.

Đây là cách nó nhìn:

$shippingAddress = $quote->getShippingAddress(); 

    $shippingAddress->setShippingMethod('dynamicshipping_'.$shippingCode); 
    $shippingAddress->setCollectShippingRates(true); 
    $shippingAddress->collectShippingRates(); 

    $quote->setUseCustomerBalance(1)->setTotalsCollectedFlag(false)->collectTotals()->save(); 

    $order->setShippingHiddenTaxAmount($shippingAddress->getShippingHiddenTaxAmount()); 
    $order->setBaseShippingHiddenTaxAmount($shippingAddress->getBaseShippingHiddenTaxAmount()); 
    $order->setBaseShippingHiddenTaxAmnt($shippingAddress->getBaseShippingHiddenTaxAmnt()); 
    $order->setShippingInclTax($shippingAddress->getShippingInclTax()); 
    $order->setBaseShippingInclTax($shippingAddress->getBaseShippingInclTax()); 
    $order->setShippingTaxAmount($shippingAddress->getShippingTaxAmount()); 
    $order->setBaseShippingTaxAmount($shippingAddress->getBaseShippingTaxAmount()); 
    $order->setShippingAmount($shippingAddress->getShippingAmount()); 
    $order->setBaseShippingAmount($shippingAddress->getBaseShippingAmount()); 
    $order->setShippingDiscountAmount($shippingAddress->getShippingDiscountAmount()); 
    $order->setBaseShippingDiscountAmount($shippingAddress->getBaseShippingDiscountAmount()); 
    $order->setGrandTotal($shippingAddress->getGrandTotal()); 
    $order->setBaseGrandTotal($shippingAddress->getBaseGrandTotal()); 
    $order->setShippingMethod('dynamicshipping_'.$shippingCode); 
    $order->setShippingDescription($shippingDescription); 

    $order->setServicePoint($servicePoint); 
    $order->save(); 

Và như tôi đã nói, mà làm việc tốt mỗi khi từ phụ trợ, nhưng không phải khi gọi từ front-end.

Tôi đã thử các biến thể, chẳng hạn như điều này để thử và xóa mọi dấu vết của phương thức giao hàng cũ, không có may mắn.

$quote->getShippingAddress()->removeAllShippingRates() 
     ->setShippingMethod('dynamicshipping_'.$shippingCode) 
     ->setShippingDescription($shippingDescription) 
     //->setBaseShippingAmount(0) 
     //->setBaseShippingTaxAmount(0) 
     //->setShippingTaxAmount(0) 
     //->setShippingInclTax(0) 
     ->setCollectShippingRates(true) 
     //->unsetData('cached_items_all') 
     //->unsetData('cached_items_nominal') 
     //->unsetData('cached_items_nonnominal') 
     ->collectShippingRates() 
     //->collectTotals() 
     ->save(); 

Có vẻ với tôi như thể trích dẫn được sử dụng một cũ/diffrent bản sao của địa chỉ vận chuyển khi tôi gọi collectTotals, bất kể những gì tôi làm.

Bất kỳ đề xuất nào hoặc có lẽ là thông tin chi tiết về cách nó thậm chí có thể thực hiện được điều này trong phần phụ trợ chứ không phải giao diện người dùng?

EDIT

Sau khi gỡ lỗi hơn, tôi có thể thấy rằng vận chuyển không thay đổi cả trong frontend và backend. Vấn đề là, phí sẽ chỉ thay đổi khi chạy mã này thông qua chương trình phụ trợ. Rất lạ. Nó chỉ từ chối cập nhật phí vận chuyển.

+0

Bạn có thể cung cấp mã hoàn chỉnh hơn (nơi bạn đã đặt đoạn mã của mình) và thông tin thêm về trường hợp sử dụng của bạn không? Tôi sẽ cần một số bối cảnh, để trả lời câu hỏi của bạn. –

+0

Đó là mã hoàn chỉnh và tôi chạy nó từ quản trị viên và giao diện người dùng bất cứ khi nào giao hàng được thay đổi theo thứ tự đã đặt –

+0

Tôi có nghĩa là bạn đã đưa đoạn mã vào lớp nào và bạn đề xuất như thế nào để thu hút mã này từ giao diện người dùng? –

Trả lời

2

Có vẻ như tôi có một số vấn đề với người quan sát trên collectTotals, đó là lý do nó hoạt động trong chương trình phụ trợ mà sự kiện không được kích hoạt.

Mã hoàn chỉnh để tham chiếu, mà gần đây tôi đã thay đổi để sử dụng phương pháp không an toàn hơn để sao chép tất cả các trường trở lại theo thứ tự.

/* @var $order Mage_Sales_Model_Order */ 
    /* @var $quote Mage_Sales_Model_Quote */ 

    $shippingAddress = $quote->getShippingAddress(); 
    $shippingAddress->setShippingMethod('dynamicshipping_'.$shippingCode); 
    $shippingAddress->setShippingDescription($shippingDescription); 

    $shippingAddress->setCollectShippingRates(true)->collectShippingRates(); 
    $quote->collectTotals(); 

    if ($this->updateMagentoOrder($order, $quote)) { 

     // here's where I check if we successfully updated the authorized 
     // amount at the payment gateway, before saving anything 
     // wrapping the payment update and save in a try-catch 

     $quote->save(); 
     $order->save(); 
    } 

Và sử dụng phương pháp này để cập nhật tất cả các lĩnh vực theo thứ tự:

/** 
* Updates a Magento order based on quote changes 
* will not save anything, up to the caller. 
* deleting items not supported. 
* 
* @param $order Mage_Sales_Model_Order 
* @param $quote Mage_Sales_Model_Quote 
* @return bool 
*/ 
public function updateMagentoOrder($order, $quote) { 
    if (!$order instanceof Mage_Sales_Model_Order || !$quote instanceof Mage_Sales_Model_Quote) { 
     return false; 
    } 

    try { 
     $converter = Mage::getSingleton('sales/convert_quote'); 
     $converter->toOrder($quote, $order); 

     foreach ($quote->getAllItems() as $quoteItem) { 

      $orderItem  = $converter->itemToOrderItem($quoteItem); 
      $quoteItemId = $quoteItem->getId(); 
      $origOrderItem = empty($quoteItemId) ? null : $order->getItemByQuoteItemId($quoteItemId); 

      if ($origOrderItem) { 
       $origOrderItem->addData($orderItem->getData()); 
      } else { 
       if ($quoteItem->getParentItem()) { 
        $orderItem->setParentItem(
         $order->getItemByQuoteItemId($quoteItem->getParentItem()->getId()) 
        ); 
        $orderItem->setParentItemId($quoteItem->getParentItemId()); 
       } 
       $order->addItem($orderItem); 
      } 
     } 

     if ($shippingAddress = $quote->getShippingAddress()) { 
      $converter->addressToOrder($shippingAddress, $order); 
     } 
    } catch (Exception $e) { 
     Mage::logException($e); 
     return false; 
    } 

    return true; 
} 

Để tham khảo, các phương pháp trên có thể lặp $order->getAllItems() và làm $orderItem->cancel()->delete(); trên chúng đầu tiên - nhưng tôi sẽ không hỗ trợ xóa các mục đúng hiện nay.

Phần cancel() trước khi xóa để mô-đun CatalogInventory có thể khôi phục kho. Nó đang lắng nghe sự kiện sales_order_item_cancel.

Các vấn đề liên quan