プログラムからCSVからMagentoに注文をインポートする


17

古い、古くなったPOSシステムからMagento 1.7を排他的にPOSとして使用するように切り替えています。予想外のことではありませんが、私たちが直面している課題の1つは、古いシステムから大惨事なしにMageに20年近くの記録を取得する方法です。

顧客レコードの移行という課題は別として、この質問で重点を置いている問題は、過去の注文データを古いPOSからMageに移行する方法です。私たちが話している注文レコードの数が多い場合、正確な数字は100%確信できませんが、少なくとも100万は言うでしょう。

これにアプローチする方法に関して私が考えているのは次のとおりです:

  1. Magentoがデータを適切に再生するために、データをどのようにフォーマットする必要があるかを正確に把握してください。動作する形式で古いPOSから取得できるかどうかは疑問ですが、これがうまくいくとしばらく仮定しましょう...
  2. 適切にフォーマットされた履歴データを含む.CSVファイルを作成する
  3. row- $order> save()でMagentoのオブジェクト行にその.CSVを読み込む方法を見つける
  4. 利益!

私の問題は、ポイント2と3にアプローチする方法が少し曖昧だということです。古いPOSから出力されるデータはフォーマットできますが、非常に面倒でPerlが関係している場合でも、.CSVファイル(またはこのプロセスで実際に機能するファイルの種類)を取得した後でも、 Magentoの注文オブジェクトにどのようにフィードするか。

私はいくつかのグーグルを行い、Mageの注文オブジェクトを使用してプログラムで注文をインポートする人々の例を考え出しましたが、フロントエンドカート以外のデータソースを前述のオブジェクトに接続する方法についてはほとんど議論されていません。私は注文オブジェクトのバージョンを研究しています:

$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();

だからここに私の特定の質問があります:

  1. これは、この問題に対するリモートの感覚的なアプローチのように思えますか?そして、そうでない場合、どうすればこの問題にバカのようにアプローチできると思いますか?
  2. これが感覚的なアプローチである場合、注文プロセスによって呼び出されるモデルごとに異なる.CSVが必要ですか?すなわち、Mage :: getModel( 'sales / order')、Mage :: getModel( 'sales / order_address')など?
  3. .CSVは進むべき道ですか?
  4. データが.CSVに含まれているのか、それとも何を持っているのかに関係なく、どのようにデータをこのオブジェクトにフィードしますか?
  5. オーバーヘッドをどのように制限しますか?

私がこれについて全くばかげた方法で考えていて、あなたがそのように私に言ったとしても、私はすべてのインプットに本当に感謝しています。

ありがとう、ありがとう、ありがとう!


1
あなたの場合には本当に重要ではありませんが、私の以前の質問と@BenMarksの答えを見てください。これはMagentoでCSVを解析することを含み、役に立つかもしれません。magento.stackexchange.com/questions/232/...
pspahn

1
github.com/avstudnitz/AvS_FastSimpleImportからインスピレーションを得るためにこれを見たいかもしれません。これは主に製品と顧客のインポートに焦点を当てていますが、高速なインポートシステムです。数百万件のレコードについて話しているときは、おそらくスピーディなものが必要です。以前にこれを使用して、製品のCSVファイルをインポートしました。CSVファイルを読み取り、データを配列に変換するだけです。ただし、このモジュールを拡張して注文を使用しようとはしていません。だから私はそれがどのように機能するかわからない。幸運を。
ヴィッキー14年

それでは、Dataflowの自動化-注文をインポートするためのインポートは悪い考えでしょうか?私が読んだことから、それはかなり一般的な解決策のようです。
予備自転車

回答:


9

非常に多くの票/ビューで答えがないことに驚いたので、私は噛みます:

  1. これは古いPOSシステムに依存し、インポート中にデータを処理します。
  2. Varien_Io特によく知ってくださいVarien_Io_File。このような大量のデータのコレクションを処理する可能性が最も高いため、StreamReadCsvやなどのストリームを使用することに留意してくださいStreamWriteCsv「ストリーム」の詳細。ストリームまたは線形読み取り/書き込みがなければ、他の読み込み/書き込み方法でメモリの問題が発生する可能性があります。

上記が上記の例です:(ソース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
            );
        }
    }
}

注文のインポートに関しては、この例が最も役立ちました:(ソース: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());

この例でMage::getModel(...は、foreachループの呼び出しが悪いため、リソースが大量に消費されます。これは、タイムアウトになるか、メモリーをすぐにいっぱいにする可能性が高いためです。特に、これを別のforeach / whileでラップしている場合。

この...

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

次のようになります。

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

データのすべての CSVビットをMagentoオブジェクトに関連付けようとするつもりはありません。それは狂気と少しやり過ぎだろう、リソースモデルのエントリポイントを維持し$model->load(EntityId)ます。

また、10万件以上の注文をインポートしようとする場合、MySQLを調整してそのような大容量を処理するために必要な大規模なインポート後のパフォーマンスが懸念されることに注意してください。また、大容量/トラフィックの下ではうまく機能しません。Magento Enterpriseに「トランザクション」販売注文テーブルから古いデータを引き出して、注文の取得に不要な肥大化/古いデータを防ぐ販売注文アーカイブモジュールがある理由があります。

まとめ:純粋にレポートすることが、Magentoよりもスイートに適した選択肢がある場合、そのような大きなデータを保存するためのビジネスの要件とニーズを持ち出します。


誰もがこれを助ける@ magento.stackexchange.com
宝石

3

これらの履歴注文がmagento / mysqlのパフォーマンスに与える影響に加えて、廃止された製品ラインもインポートする必要があるという事実を考えると、顧客と製品とともに履歴注文を何かに保存することを検討する価値があるかもしれませんelasticsearchインデックスのように、オンデマンドで検索を実行します。すなわち、顧客注文履歴ページ。


1

見積もりの​​作成から注文の作成まで、注文インポートの膨大なデータには時間がかかりすぎます。

そのため、mysqlクエリを使用した巨大なインポートデータの結論を調査し、発見しました。

  1. データを注文テーブルにのみ挿入しました。

  2. を更新しincrement_idてmagento 1.xを認識します。最後の順序increment_idはこれです

  3. このクエリは、見積もり、請求書、および出荷を作成していません。

    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;

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.