Mengimpor pesanan dari CSV ke Magento secara terprogram


17

Kami beralih dari sistem point-of-sale lama, usang ke menggunakan Magento 1.7 sebagai POS kami secara eksklusif. Tidak disangka, salah satu tantangan yang kami hadapi adalah bagaimana mendapatkan hampir 20 tahun catatan dari sistem lama ke Mage tanpa bencana.

Mengesampingkan tantangan bahkan memigrasi catatan pelanggan, masalah yang saya fokuskan dalam pertanyaan ini adalah bagaimana saya akan memigrasi data pesanan historis dari POS lama ke Mage. Saya tidak 100% yakin pada angka pasti ketika banyak catatan pesanan kita bicarakan, tapi saya akan mengatakan setidaknya satu juta.

Inilah yang saya pikirkan dalam hal bagaimana mendekati ini:

  1. Cari tahu persis bagaimana data perlu diformat agar Magento bisa bermain bagus dengannya. Apakah kita dapat mengeluarkannya dari POS lama dalam format yang berfungsi patut dipertanyakan, tetapi mari kita asumsikan sejenak bahwa ini berjalan dengan baik ...
  2. Buat file .CSV dengan data historis yang diformat dengan baik
  3. Temukan cara untuk membaca .CSV ke objek Magento $orderbaris demi baris -> save ()
  4. Keuntungan!

Masalah saya adalah bahwa saya agak kabur tentang bagaimana mendekati titik 2 & 3, lanjutkan angka. Saya dapat memformat data yang keluar dari POS lama namun saya butuhkan, bahkan jika itu sangat rumit dan melibatkan Perl, tetapi begitu saya memiliki file .CSV (atau tipe file apa pun yang benar-benar berfungsi untuk proses ini) saya cukup tidak jelas tentang bagaimana saya akan memasukkannya ke objek pesanan Magento.

Saya telah melakukan beberapa Googling, dan saya telah menemukan contoh orang yang menggunakan objek pesanan Mage untuk mengimpor pesanan secara terprogram, tetapi sedikit diskusi tentang bagaimana mereka menghubungkan sumber data selain gerobak ujung depan ke objek tersebut. Saya telah mempelajari versi objek pesanan:

$id=1; // get Customer Id
$customer = Mage::getModel('customer/customer')->load($id);

$transaction = Mage::getModel('core/resource_transaction');
$storeId = $customer->getStoreId();
$reservedOrderId = Mage::getSingleton('eav/config')->getEntityType('order')->fetchNewIncrementId($storeId);

$order = Mage::getModel('sales/order')
  ->setIncrementId($reservedOrderId)
  ->setStoreId($storeId)
  ->setQuoteId(0)
  ->setGlobal_currency_code('USD')
  ->setBase_currency_code('USD')
  ->setStore_currency_code('USD')
  ->setOrder_currency_code('USD');

// set Customer data
$order->setCustomer_email($customer->getEmail())
  ->setCustomerFirstname($customer->getFirstname())
  ->setCustomerLastname($customer->getLastname())
  ->setCustomerGroupId($customer->getGroupId())
  ->setCustomer_is_guest(0)
  ->setCustomer($customer);

// set Billing Address
$billing = $customer->getDefaultBillingAddress();
$billingAddress = Mage::getModel('sales/order_address')
  ->setStoreId($storeId)
  ->setAddressType(Mage_Sales_Model_Quote_Address::TYPE_BILLING)
  ->setCustomerId($customer->getId())
  ->setCustomerAddressId($customer->getDefaultBilling())
  ->setCustomer_address_id($billing->getEntityId())
  ->setPrefix($billing->getPrefix())
  ->setFirstname($billing->getFirstname())
  ->setMiddlename($billing->getMiddlename())
  ->setLastname($billing->getLastname())
  ->setSuffix($billing->getSuffix())
  ->setCompany($billing->getCompany())
  ->setStreet($billing->getStreet())
  ->setCity($billing->getCity())
  ->setCountry_id($billing->getCountryId())
  ->setRegion($billing->getRegion())
  ->setRegion_id($billing->getRegionId())
  ->setPostcode($billing->getPostcode())
  ->setTelephone($billing->getTelephone())
  ->setFax($billing->getFax());
$order->setBillingAddress($billingAddress);

$shipping = $customer->getDefaultShippingAddress();
$shippingAddress = Mage::getModel('sales/order_address')
  ->setStoreId($storeId)
  ->setAddressType(Mage_Sales_Model_Quote_Address::TYPE_SHIPPING)
  ->setCustomerId($customer->getId())
  ->setCustomerAddressId($customer->getDefaultShipping())
  ->setCustomer_address_id($shipping->getEntityId())
  ->setPrefix($shipping->getPrefix())
  ->setFirstname($shipping->getFirstname())
  ->setMiddlename($shipping->getMiddlename())
  ->setLastname($shipping->getLastname())
  ->setSuffix($shipping->getSuffix())
  ->setCompany($shipping->getCompany())
  ->setStreet($shipping->getStreet())
  ->setCity($shipping->getCity())
  ->setCountry_id($shipping->getCountryId())
  ->setRegion($shipping->getRegion())
  ->setRegion_id($shipping->getRegionId())
  ->setPostcode($shipping->getPostcode())
  ->setTelephone($shipping->getTelephone())
->setFax($shipping->getFax());

$order->setShippingAddress($shippingAddress)
  ->setShipping_method('flatrate_flatrate')
  ->setShippingDescription($this->getCarrierName('flatrate'));

$orderPayment = Mage::getModel('sales/order_payment')
  ->setStoreId($storeId)
  ->setCustomerPaymentId(0)
  ->setMethod('purchaseorder')
  ->setPo_number(' - ');
$order->setPayment($orderPayment);

// let say, we have 2 products
$subTotal = 0;
  $products = array(
  '1001' => array(
  'qty' => 1
  ),
  '1002' ->array(
  'qty' => 3
  ),
);
foreach ($products as $productId=>$product) {
  $_product = Mage::getModel('catalog/product')->load($productId);
  $rowTotal = $_product->getPrice() * $product['qty'];
  $orderItem = Mage::getModel('sales/order_item')
    ->setStoreId($storeId)
    ->setQuoteItemId(0)
    ->setQuoteParentItemId(NULL)
    ->setProductId($productId)
    ->setProductType($_product->getTypeId())
    ->setQtyBackordered(NULL)
    ->setTotalQtyOrdered($product['rqty'])
    ->setQtyOrdered($product['qty'])
    ->setName($_product->getName())
    ->setSku($_product->getSku())
    ->setPrice($_product->getPrice())
    ->setBasePrice($_product->getPrice())
    ->setOriginalPrice($_product->getPrice())
    ->setRowTotal($rowTotal)
    ->setBaseRowTotal($rowTotal);

  $subTotal += $rowTotal;
  $order->addItem($orderItem);
}

$order->setSubtotal($subTotal)
  ->setBaseSubtotal($subTotal)
  ->setGrandTotal($subTotal)
  ->setBaseGrandTotal($subTotal);

$transaction->addObject($order);
$transaction->addCommitCallback(array($order, 'place'));
$transaction->addCommitCallback(array($order, 'save'));
$transaction->save();

Jadi, inilah pertanyaan spesifik saya:

  1. Apakah ini tampak seperti pendekatan sensoris yang jauh dari masalah ini? Dan, jika tidak, bagaimana menurut Anda saya bisa mendekati masalah ini seperti orang bodoh?
  2. Jika ini adalah pendekatan yang sensis, apakah saya memerlukan .CSV yang berbeda untuk setiap model yang dipanggil oleh proses pemesanan? yaitu Mage :: getModel ('sales / order'), Mage :: getModel ('sales / order_address'), dll?
  3. Apakah .CSV bahkan cara untuk pergi?
  4. Bagaimana saya memberi makan data saya ke objek ini, apakah data itu terkandung dalam .CSV atau apa yang Anda miliki?
  5. Bagaimana Anda membatasi pengeluaran overhead?

Bahkan jika saya memikirkan hal ini dengan cara yang benar-benar bodoh dan Anda banyak memberi tahu saya, saya sangat menghargai masukan apa pun.

Terima kasih terima kasih terima kasih!


1
Benar-benar tidak signifikan untuk kasus Anda, tetapi perhatikan pertanyaan saya sebelumnya dan jawaban @BenMarks, yang melibatkan penguraian CSV di Magento dan mungkin berguna. magento.stackexchange.com/questions/232/…
pspahn

1
Anda mungkin ingin melihat ini sebagai inspirasi: github.com/avstudnitz/AvS_FastSimpleImport Ini terutama berfokus pada mengimpor produk dan pelanggan, tetapi ini adalah sistem impor yang cepat. Saat Anda berbicara tentang jutaan rekaman, Anda mungkin menginginkan sesuatu yang cepat. Saya pernah menggunakan ini sebelumnya untuk mengimpor file CSV produk. Anda baru saja membaca file CSV dan mengonversi data menjadi array. Saya belum mencoba memperluas modul ini untuk menggunakan pesanan. Jadi saya tidak tahu bagaimana itu akan berhasil. Semoga berhasil.
Vicky

Jadi, apakah mengotomatiskan Dataflow - Impor untuk mengimpor pesanan adalah ide yang buruk? Dari apa yang saya baca, tampaknya menjadi solusi yang cukup umum.
sparecycle

Jawaban:


9

Terkejut tanpa jawaban dengan begitu banyak suara / pandangan, jadi saya akan gigit:

  1. Ini akan tergantung pada sistem POS lama, memijat data selama impor.
  2. Biasakan diri Anda dengan Varien_Io, khususnya Varien_Io_File. Karena Anda kemungkinan besar akan berhadapan dengan kumpulan data yang begitu besar, ingatlah untuk menggunakan stream seperti StreamReadCsvdan StreamWriteCsv. Detail lebih lanjut tentang "aliran" . Tanpa aliran atau baca / tulis linier, Anda dapat mengalami masalah memori dengan metode memuat / menulis lainnya.

Dengan yang disebutkan di atas di sini adalah contoh: (sumber Atwix.com )

/**
 * Generates CSV file with product's list according to the collection in the $this->_list
 * @return array
 */
public function generateMlnList()
{
    if (!is_null($this->_list)) {
        $items = $this->_list->getItems();
        if (count($items) > 0) {

            $io = new Varien_Io_File();
            $path = Mage::getBaseDir('var') . DS . 'export' . DS;
            $name = md5(microtime());
            $file = $path . DS . $name . '.csv';
            $io->setAllowCreateFolders(true);
            $io->open(array('path' => $path));
            $io->streamOpen($file, 'w+');
            $io->streamLock(true);

            $io->streamWriteCsv($this->_getCsvHeaders($items));
            foreach ($items as $product) {
                $io->streamWriteCsv($product->getData());
            }

            return array(
                'type'  => 'filename',
                'value' => $file,
                'rm'    => true // can delete file after use
            );
        }
    }
}

Sedangkan untuk mengimpor pesanan, contoh ini paling membantu: (Sumber: pastebin )

<?php

require_once 'app/Mage.php';

Mage::app();

$quote = Mage::getModel('sales/quote')
    ->setStoreId(Mage::app()->getStore('default')->getId());

if ('do customer orders') {
    // for customer orders:
    $customer = Mage::getModel('customer/customer')
        ->setWebsiteId(1)
        ->loadByEmail('customer@example.com');
    $quote->assignCustomer($customer);
} else {
    // for guesr orders only:
    $quote->setCustomerEmail('customer@example.com');
}

// add product(s)
$product = Mage::getModel('catalog/product')->load(8);
$buyInfo = array(
    'qty' => 1,
    // custom option id => value id
    // or
    // configurable attribute id => value id
);
$quote->addProduct($product, new Varien_Object($buyInfo));

$addressData = array(
    'firstname' => 'Test',
    'lastname' => 'Test',
    'street' => 'Sample Street 10',
    'city' => 'Somewhere',
    'postcode' => '123456',
    'telephone' => '123456',
    'country_id' => 'US',
    'region_id' => 12, // id from directory_country_region table
);

$billingAddress = $quote->getBillingAddress()->addData($addressData);
$shippingAddress = $quote->getShippingAddress()->addData($addressData);

$shippingAddress->setCollectShippingRates(true)->collectShippingRates()
        ->setShippingMethod('flatrate_flatrate')
        ->setPaymentMethod('checkmo');

$quote->getPayment()->importData(array('method' => 'checkmo'));

$quote->collectTotals()->save();

$service = Mage::getModel('sales/service_quote', $quote);
$service->submitAll();
$order = $service->getOrder();

printf("Created order %s\n", $order->getIncrementId());

Dengan contoh yang Anda miliki sekarang akan sumber daya yang berat, karena ada Mage::getModel(...panggilan di loop foreach yang merupakan praktik yang buruk , dan kemungkinan besar akan baik waktu habis, atau mengisi memori lebih cepat. Terutama jika Anda memiliki ini dibalut foreach lain / sementara.

Ini...

foreach ($products as $productId=>$product) {
  $_product = Mage::getModel('catalog/product')->load($productId);

Seharusnya terlihat seperti:

$_product = Mage::getModel('catalog/product');
foreach ($products as $productId=>$product) {
  $_product->load($productId);

Saya tidak akan mencoba untuk mencoba dan menghubungkan setiap bit data CSV ke objek Magento. Ini akan menjadi kegilaan dan sedikit berlebihan, tetap dengan titik masuk model sumber daya $model->load(EntityId).

Perhatikan juga jika Anda mencoba mengimpor lebih dari 100k + pesanan saya akan peduli untuk kinerja setelah impor besar yang diperlukan untuk menjaga MySQL disetel untuk menangani volume besar seperti itu, tidak terlalu menyebutkan jika saya tidak salah objek penjualan masih berbasis EAV, dan tidak berkinerja baik di bawah volume / lalu lintas tinggi. Ada alasan Magento Enterprise memiliki modul Arsip Pesanan Penjualan untuk menarik data lama dari tabel pesanan penjualan "transaksional" untuk mencegah data kembung / basi yang tidak diperlukan untuk menerima pesanan.

Untuk Dibungkus: Saya akan memunculkan persyaratan dan kebutuhan bisnis untuk menyimpan data sebesar itu, jika murni melaporkan ada alternatif yang lebih baik untuk menyesuaikan ini daripada Magento.



3

Memikirkan dampak pesanan bersejarah ini terhadap kinerja magento / mysql ditambah fakta bahwa setiap lini produk yang telah dihentikan akan perlu diimpor juga maka mungkin ada baiknya mempertimbangkan menyimpan pesanan bersejarah bersama dengan pelanggan dan produk dalam sesuatu seperti indeks elasticsearch dan melakukan pencarian sesuai permintaan. yaitu halaman riwayat pesanan pelanggan.


1

Dari membuat kutipan dan kemudian membuat pesanan terlalu banyak waktu untuk data impor pesanan dalam jumlah besar.

Jadi, saya telah meneliti dan menemukan kesimpulan dari data impor pesanan besar dengan permintaan mysql:

  1. Saya memasukkan data ke dalam tabel pesanan saja.

  2. Perbarui increment_iduntuk mengenali magento 1.x, pesanan terakhir increment_idadalah ini

  3. Permintaan ini tidak membuat kuotasi, faktur, dan pengiriman:

    Pertanyaan SQL: -

    1. INSERT INTO `sales_flat_order` (state, status, shipping_description, store_id, customer_id, base_discount_invoiced, base_grand_total, base_shipping_amount, base_shipping_invoiced, base_subtotal, base_subtotal_invoiced, base_tax_amount, base_tax_invoiced, base_total_invoiced, base_total_invoiced_cost, base_total_paid, discount_invoiced, grand_total, shipping_amount, shipping_invoiced, subtotal, subtotal_invoiced, tax_amount, tax_invoiced, total_invoiced, total_paid, customer_group_id, increment_id, base_currency_code, global_currency_code, customer_email, customer_firstname, customer_lastname, customer_middlename, order_currency_code, shipping_method, store_currency_code, store_name, created_at, updated_at, total_item_count, hidden_tax_invoiced, base_hidden_tax_invoiced, is_valid) VALUES ("complete", "complete", "Flat Rate - Fixed", 1, 38322,0,225.7,0,0,214.95,214.95,10.75,10.75,225.7, 0,225.7, 0,225.7,0,0,214.95,214.95,10.75,10.75,225.7,225.7, 1,100026111,"CAD","CAD","abc@gmail.com","abc","abc","", "CAD", "flatrate_flatrate", "CAD", "Main Website\nMain Website Store\nOnline Catalog","2012-01-17 00:00:00","2012-01-17 00:00:00",5,0,0,0);

    2. INSERT INTO `sales_flat_order_grid` (entity_id, status, shipping_description, shipping_method, store_id, customer_id, customer_email, total_qty_ordered, base_grand_total, base_total_paid, grand_total, total_paid, increment_id, base_currency_code, order_currency_code, store_name, created_at, updated_at, payment_validated, billing_name, shipping_name) VALUES (5, "complete", "Flat Rate - Fixed", "flatrate_flatrate", 1, 38322,"abc@gmail.com",5,225.7,225.7,225.7,225.7,100026111,"CAD", "CAD", "Main Website\nMain Website Store\nOnline Catalog","2012-01-17 00:00:00","2012-01-17 00:00:00",1,"abc abc","abc abc");

    3. INSERT INTO `sales_flat_order_address` (parent_id, region_id, customer_id, email, region, postcode, lastname, street, city, telephone, country_id, firstname, address_type, middlename, nick_name) VALUES (5,68,38322,"alicjakeller@gmail.com","Manitoba","R3W 1G9","abc","1607 Concordia Ave E","Winnipeg","204 667-5540","CA","abc","billing","","")

    4. INSERT INTO `sales_flat_order_address` (parent_id, region_id, customer_id, email, region, postcode, lastname, street, city, telephone, country_id, firstname, address_type, middlename, nick_name) VALUES (5,68,38322,"alicjakeller@gmail.com","Manitoba","R3W 1G9","abc","1607 Concordia Ave E","Winnipeg","204 667-5540","CA","abc","shipping","","");

    5. INSERT INTO `sales_flat_order_item` (order_id, store_id, created_at, updated_at, product_id, product_type, sku, name, qty_ordered, price, base_price, original_price, base_original_price, row_total, base_row_total, price_incl_tax, base_price_incl_tax, row_total_incl_tax, base_row_total_incl_tax) VALUES (5,1,"2012-01-17 00:00:00","2012-01-17 00:00:00",4134,"simple","MET2240","ULTRA FLORA IB - 30 CAPS",4,44.99,44.99,44.99,44.99,179.96,179.96,44.99,44.99,179.96,179.96);

    6. INSERT INTO `sales_flat_order_item` (order_id, store_id, created_at, updated_at, product_id, product_type, sku, name, qty_ordered, price, base_price, original_price, base_original_price, row_total, base_row_total, price_incl_tax, base_price_incl_tax, row_total_incl_tax, base_row_total_incl_tax) VALUES (5,1,"2012-01-17 00:00:00","2012-01-17 00:00:00",3198,"simple","WS1600","THYROSENSE - 180 VCAPS + 60 VCAPS FREE",1,34.99,34.99,34.99,34.99,34.99,34.99,34.99,34.99,34.99,34.99);

    7. INSERT INTO `sales_flat_order_payment` (parent_id, base_shipping_amount, shipping_amount, base_amount_paid, amount_paid, base_amount_ordered, amount_ordered, method) VALUES (5,0,0,225.7,225.7,225.7,225.7, "cashondelivery");

    8. UPDATE `eav_entity_store` SET increment_last_id = 100026111 WHERE `entity_type_id` = 5 AND `store_id` = 1;

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.