Bir kasada veya sipariş ayırmada Magento çoklu sipariş


10

Mağaza ürünleri farklı satıcılardan temin edilir. Bir ödeme sırasında alışveriş sepetindeki ürünlerine dayanarak her satıcı için birden fazla sipariş oluşturulması gerekir. Bu görevi gerçekleştirmek için herhangi bir uzantı var mı veya özel ödeme modülü geliştirmeye başlamalı mıyım? Magento'nun deneyimli geliştiricilerinin böyle bir uzatma vizyonunu oluşturmak için sıcak noktalar ne olacak? Bana kısa ödeme akış mimarisi Magento dostu (kod düzeyinde mümkün olduğunca) açıklayabilir misiniz? Çok teşekkürler!


Magento'nun kutudan çıktığı Multishipping'e bir göz atın. Ve dropship var ama bunun iyi olup olmadığını veya ne yapabileceğini bilmiyorum. unirgy.com/products/udropship
Fabian Blechschmidt

@mageUz, cevabın altında çalıştın mı? benim için işe yaramadı .. Kodunuzu gönderebilir misiniz?
Manoj Kumar

@ManojKumar, evet zaten çoklu adres ödeme mantığı kullanarak sipariş bölme uygulamak var, eminim aşağıda verilen mantık da mükemmel çalışır.
mageUz

@mageUz, bu kodu kullandığınızda Alışveriş Sepeti Boş Gösteriliyor .. Herhangi bir öneri ..
Manoj Kumar

Merhaba bu marketplace bölünmüş sepeti modülü store.webkul.com/Magento-Marketplace-Split-Cart.html kullanılarak yapılabilir . Teşekkürler
webkul

Yanıtlar:


9

checkout/type_onepageModelin yeniden yazılmasıyla kolayca yapılabilir .
Bu sınıfta saveOrder()yöntemi aşağıdaki gibi geçersiz kılın :

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

Ancak Magento'da bir ödemenin bir faturayla ve her faturanın bir siparişle ilişkili olduğunu unutmayın.

Sonuç olarak bu, birden fazla siparişiniz olur olmaz ödemeleri de bölebileceğiniz anlamına gelir . Bu nedenle, yalnızca ödeme yöntemi ödeme sırasında kullanıcı etkileşimi gerektirmiyorsa mümkündür.

GÜNCELLEME : orjinal cevap devredilmiş parent::save()olan gerekiyordu parent:saveOrder(). Şimdi örnek kodda düzeltildi.


Benzer soruma bir göz atabilirseniz sevinirim! magento.stackexchange.com/questions/6974/…
CaitlinHavener

yukarıdaki kodu kullanarak sipariş bölmek mümkün oldu, ben aynı yapmaya çalışıyorum ama herhangi bir şans olmadan
Deepak Mallah

1
Roy, elbette bir ebeveyn olabilmek için orijinal sınıfı genişletmeniz gerekiyor, ancak bu basit PHP, Magento ile ilgisi yok. Yöntem saveOrderhala her zaman olduğu gibi Magento CE 1.9'da mevcut ve aktiftir.
Vinai

3
2 Sipariş grandtotal ve subtotal tüm sipariş eşit olduğu gibi bu snippet ile ilgili bir sorun vardı. Hata ayıklama sonra bile öğeleri kaldırma ve yeniden ekleme, sadece adres toplam formunu topladıktan sonra adres önbelleğe alınan öğeleri kullanacağını öğrendim ... Çözmek için her adres için öğeleri önbellek temizleyin: $ address-> unsetData (' ) 'cached_items_all; $ adresi-> unsetData ( 'cached_items_nominal'); $ adresi-> unsetData ( 'cached_items_nonnominal');
Diogo Santiago

1
@Vinai $ quote-> addItem ($ item); bu kod çalışmıyor. Öğe ekledikten sonra foreach döngüsü yardımı ile $ quote-> getAllItems () yankılarım. Ama hiçbir şey yoktu. Bana bu konuda yardımcı olabilir misiniz?
Amit Bera

1

Aşağıdakiler CE sürüm 1.9.0.x'de test edilmiştir.

/**
 * 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;
    }
}

ÖNEMLİ Tekliften genel toplamı almak için ödeme yöntemlerinizi özelleştirmeniz gerekir.


Çalışıyor. Teşekkürler. Sepet teklifini satıcıya göre nasıl gruplayabilirim? diğer sonra "// sipariş başına bir ürün" ..
Syed Ibrahim

1
$group[] = $item; // all other items in one ordersipariş başına birden fazla öğe tutabilir, her satıcının kendine ait olduğu şekilde kolayca değiştirebilirsiniz $group.
kiatng

Güncellenmiş ve çalışıyor. Ancak Ödeme sadece son sipariş için yakalanır (Birden fazla siparişi bölersek). Bunu nasıl güncellememiz gerekiyor? Toplam ödeme toplamı toplamam gerekiyor.
Syed Ibrahim

Toplam tutar alıntı nesnesinde, ile yükleyebilirsiniz $quote->Mage::getModel('sales/quote')->load($lastOrder->getQuoteId()). Sonra alabileceğiniz birçok toplam var $quote, bunlardan biri$quote->getGrandTotal()
kiatng
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.