Magento nhiều đơn hàng trên một lần thanh toán hoặc tách đơn hàng


10

Cửa hàng sản phẩm được cung cấp từ các nhà cung cấp khác nhau. Cần phải tạo nhiều đơn hàng cho mỗi nhà cung cấp dựa trên các sản phẩm của họ trong giỏ hàng trong một lần thanh toán. Có bất kỳ phần mở rộng để đạt được nhiệm vụ này hay tôi nên bắt đầu phát triển mô-đun kiểm tra tùy chỉnh. Còn những điểm nóng để tạo ra tầm nhìn mở rộng như vậy của các nhà phát triển có kinh nghiệm của Magento thì sao? Bạn có thể giải thích cho tôi kiến ​​trúc dòng kiểm tra ngắn gọn thân thiện với Magento (có thể như cấp mã) không? Cảm ơn nhiều hơn nữa!


Có một cái nhìn về Multishipping mà magento cung cấp ra khỏi hộp. Và có dropship nhưng tôi không biết liệu nó tốt hay nó có thể làm được gì. unirgy.com/products/udropship
Fabian Blechschmidt

@mageUz, bạn đã làm việc dưới đây trả lời chưa?. nó không làm việc cho tôi .. Có thể gửi mã của bạn?
Manoj Kumar

@ManojKumar, vâng, tôi đã thực hiện phân tách đơn hàng bằng cách sử dụng logic kiểm tra đa biến, tôi chắc chắn rằng logic được đưa ra dưới đây cũng hoạt động hoàn hảo.
mageUz

@mageUz, khi sử dụng mã này Giỏ hàng không hiển thị .. Mọi đề xuất ..
Manoj Kumar

Xin chào, có thể được thực hiện bằng cách sử dụng mô-đun phân chia giỏ hàng trên thị trường store.webkul.com/Magento-Marketplace-Split-Cart.html . Cảm ơn
webkul

Câu trả lời:


9

Nó có thể thực hiện khá dễ dàng với việc viết lại checkout/type_onepagemô hình.
Trong lớp đó ghi đè saveOrder()phương thức như sau:

public function saveOrder()
{
    $quote = $this->getQuote();

    // First build an array with the items split by vendor
    $sortedItems = array();
    foreach ($quote->getAllItems() as $item) {
        $vendor = $item->getProduct()->getVendor(); // <- whatever you need
        if (! isset($sortedItems[$vendor])) {
            $sortedItems[$vendor] = $item;
        }
    }
    foreach ($sortedItems as $vendor => $items) {
        // Empty quote
        foreach ($quote->getAllItems() as $item) {
            $quote->getItemsCollection()->removeItemByKey($item->getId());
        }
        foreach ($items as $item) {
            $quote->addItem($item);
        }
        // Update totals for vendor
        $quote->setTotalsCollectedFlag(false)->collectTotals();

        // Delegate to parent method to place an order for each vendor
        parent::saveOrder();
    }
    return $this;
}

Nhưng hãy lưu ý rằng trong Magento, một khoản thanh toán được liên kết với một hóa đơn và mỗi hóa đơn được liên kết với một đơn đặt hàng.

Do đó, điều này có nghĩa là ngay khi bạn có nhiều đơn hàng, bạn cũng sẽ chia các khoản thanh toán . Vì vậy, điều này chỉ khả thi nếu phương thức thanh toán không yêu cầu tương tác của người dùng trong quá trình thanh toán.

CẬP NHẬT : Câu trả lời ban đầu giao cho parent::save()mà phải được parent:saveOrder(). Nó được cố định trong mã ví dụ bây giờ.


Sẽ đánh giá cao nếu bạn có thể có một cái nhìn vào câu hỏi tương tự của tôi! magento.stackexchange.com/questions/6974/ Mạnh
CaitlinHavener

bạn có thể phân chia thứ tự bằng cách sử dụng mã ở trên không, vì tôi đang cố gắng làm điều tương tự nhưng không phải không có may mắn
Deepak Mallah

1
Roy, tất nhiên bạn phải mở rộng lớp ban đầu để có cha mẹ, nhưng đó là PHP đơn giản, nó không liên quan gì đến Magento. Phương thức này saveOrdervẫn hiện diện và hoạt động trong Magento CE 1.9 giống như mọi khi.
Vinai

3
Tôi gặp vấn đề với đoạn trích này vì thứ tự 2 có tổng và tổng phụ bằng toàn bộ đơn hàng. Sau khi gỡ lỗi, tôi phát hiện ra rằng thậm chí loại bỏ và thêm lại các mục, nó sẽ chỉ sử dụng các mục được lưu trong bộ nhớ cache sau khi thu thập Tổng dạng địa chỉ ... Để giải quyết nó chỉ rõ ràng cho từng địa chỉ bộ nhớ cache: $ address-> unsetData (' cacheed_items_all '); $ address-> unsetData ('cacheed_items_nominal'); $ address-> unsetData ('cacheed_items_nonnominal');
Diogo Santiago

1
@Vinai $ quote-> addItem ($ item); mã này không hoạt động. Sau khi thêm mục tôi lặp lại $ quote-> getAllItems () với sự trợ giúp của vòng lặp foreach. Nhưng không có mục nào. Bạn có thể giúp tôi về điều này xin vui lòng?
Amit Bera

1

Sau đây được thử nghiệm trong CE ver 1.9.0.x

/**
 * Overwrite core
 */
class Vendor_Module_Model_Checkout_Type_Onepage extends Mage_Checkout_Model_Type_Onepage
{
    protected $_oriAddresses = array();

    /**
     * Prepare order from quote_items  
     *
     * @param   array of Mage_Sales_Model_Quote_Item 
     * @return  Mage_Sales_Model_Order
     * @throws  Mage_Checkout_Exception
     */
    protected function _prepareOrder2($quoteItems)
    {
        $quote = $this->getQuote();
        $quote->unsReservedOrderId();
        $quote->reserveOrderId();

        // new instance of quote address
        $quote->setIsMultiShipping(true); // required for new instance of Mage_Sales_Model_Quote_Address
        $address = Mage::getModel('sales/quote_address');
        $weight = 0;
        $addressType = 'billing';
        foreach ($quoteItems as $quoteItem) {
            $address->addItem($quoteItem, $quoteItem->getQty());
            $weight += $quoteItem->getWeight();
            if (!$quoteItem->getIsVirtual()) {
                $addressType = 'shipping';
            }
        }
        // get original shipping address that contains multiple quote_items
        if (!isset($this->_oriAddresses[$addressType])) {
            $this->_oriAddresses[$addressType] = Mage::getResourceModel('sales/quote_address_collection')
                ->setQuoteFilter($quote->getId())
                ->addFieldToFilter('address_type', $addressType)
                ->getFirstItem();
        }
        Mage::helper('core')->copyFieldset('sales_convert_quote_address', 'to_customer_address', $this->_oriAddresses[$addressType], $address);
        Mage::helper('core')->copyFieldset('sales_convert_quote_address', 'to_order', $this->_oriAddresses[$addressType], $address);
        $address->setQuote($quote)
            ->setWeight($weight)
            ->setSubtotal(0)
            ->setBaseSubtotal(0)
            ->setGrandTotal(0)
            ->setBaseGrandTotal(0)
            ->setCollectShippingRates(true)
            ->collectTotals()
            ->collectShippingRates()        
            ;

        $convertQuote = Mage::getSingleton('sales/convert_quote');
        $order = $convertQuote->addressToOrder($address);
        $order->setBillingAddress(
            $convertQuote->addressToOrderAddress($quote->getBillingAddress())
        );

        if ($address->getAddressType() == 'billing') {
            $order->setIsVirtual(1);
        } else {
            $order->setShippingAddress($convertQuote->addressToOrderAddress($address));
        }

        $order->setPayment($convertQuote->paymentToOrderPayment($quote->getPayment()));
        if (Mage::app()->getStore()->roundPrice($address->getGrandTotal()) == 0) {
            $order->getPayment()->setMethod('free');
        }

        foreach ($quoteItems as $quoteItem) {
            $orderItem = $convertQuote->itemToOrderItem($quoteItem);  // use quote_item to transfer is_qty_decimal
            if ($quoteItem->getParentItem()) {
                $orderItem->setParentItem($order->getItemByQuoteItemId($quoteItem->getParentItem()->getId()));
            }
            $order->addItem($orderItem);
        }

        return $order;
    }

    /**
     * Overwrite core function
     */
    public function saveOrder()
    {
        $quote = $this->getQuote();
        if ($quote->getItemsCount() > 1) {
            $items = $quote->getAllVisibleItems();
            $group = array();
            $split = array();
            foreach ($items as $item) {
                if (Mage::helper('vendor')->checkSku($item->getSku())) {
                    $split[] = array($item); // one item per order
                } else {
                    $group[] = $item; // all other items in one order
                }
            }
            if (count($split)) {
                if (count($group)) {
                    $split[] = $group;
                }
                return $this->_splitQuote($split);
            }
        }
        return parent::saveOrder();
    }

    /**
     * Split quote to multiple orders
     * 
     * @param array of Mage_Sales_Model_Quote_Item
     * @return Mage_Checkout_Model_Type_Onepage
     */
    protected function _splitQuote($split)
    {
        $this->validate();
        $isNewCustomer = false;
        switch ($this->getCheckoutMethod()) {
            case self::METHOD_GUEST:
                $this->_prepareGuestQuote();
                break;
            case self::METHOD_REGISTER:
                $this->_prepareNewCustomerQuote();
                $isNewCustomer = true;
                break;
            default:
                $this->_prepareCustomerQuote();
                break;
        }
        if ($isNewCustomer) {
            try {
                $this->_involveNewCustomer();
            } catch (Exception $e) {
                Mage::logException($e);
            }
        }

        $quote = $this->getQuote()->save();
        $orderIds = array();
        Mage::getSingleton('core/session')->unsOrderIds();
        $this->_checkoutSession->clearHelperData();

        /**
         * a flag to set that there will be redirect to third party after confirmation
         * eg: paypal standard ipn
         */
        $redirectUrl = $quote->getPayment()->getOrderPlaceRedirectUrl();

        foreach ($split as $quoteItems) {
            $order = $this->_prepareOrder2($quoteItems);
            $order->place();
            $order->save();
            Mage::dispatchEvent('checkout_type_onepage_save_order_after',
                array('order'=>$order, 'quote'=>$quote));
            /**
             * we only want to send to customer about new order when there is no redirect to third party
             */
            if (!$redirectUrl && $order->getCanSendNewEmailFlag()) {
                $order->sendNewOrderEmail();
            }
            $orderIds[$order->getId()] = $order->getIncrementId();
        }

        Mage::getSingleton('core/session')->setOrderIds($orderIds);

        // add order information to the session
        $this->_checkoutSession
            ->setLastQuoteId($quote->getId())
            ->setLastSuccessQuoteId($quote->getId())
            ->setLastOrderId($order->getId())
            ->setRedirectUrl($redirectUrl)
            ->setLastRealOrderId($order->getIncrementId());

        // as well a billing agreement can be created
        $agreement = $order->getPayment()->getBillingAgreement();
        if ($agreement) {
            $this->_checkoutSession->setLastBillingAgreementId($agreement->getId());
        }

        // add recurring profiles information to the session
        $service = Mage::getModel('sales/service_quote', $quote);
        $profiles = $service->getRecurringPaymentProfiles();
        if ($profiles) {
            $ids = array();
            foreach ($profiles as $profile) {
                $ids[] = $profile->getId();
            }
            $this->_checkoutSession->setLastRecurringProfileIds($ids);
            // TODO: send recurring profile emails
        }

        Mage::dispatchEvent(
            'checkout_submit_all_after',
            array('order' => $order, 'quote' => $quote, 'recurring_profiles' => $profiles)
        );

        return $this;
    }
}

QUAN TRỌNG Bạn cần tùy chỉnh các phương thức thanh toán của mình để lấy tổng số tiền lớn từ báo giá.


Nó đang làm việc. Cảm ơn. Làm thế nào để nhóm báo giá giỏ hàng của nhà cung cấp? khác sau đó "// một mặt hàng trên mỗi đơn hàng" ..
Syed Ibrahim

1
$group[] = $item; // all other items in one ordercó thể giữ nhiều mặt hàng trên mỗi đơn hàng, bạn có thể dễ dàng sửa đổi sao cho mỗi nhà cung cấp có cái riêng $group.
kiatng

Cập nhật và nó đang hoạt động. Nhưng Thanh toán chỉ được thu cho đơn hàng cuối cùng (Nếu chúng tôi chia nhiều đơn hàng). Làm thế nào chúng ta cần cập nhật điều này? Tôi cần phải thu tổng cộng thanh toán.
Syed Ibrahim

Tổng số tiền là trong đối tượng trích dẫn, bạn có thể tải nó với $quote->Mage::getModel('sales/quote')->load($lastOrder->getQuoteId()). Sau đó, có rất nhiều tổng số bạn có thể lấy từ đó $quote, một trong số đó là$quote->getGrandTotal()
kiatng
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.