Importieren von Bestellungen aus einer CSV in Magento programmgesteuert


17

Wir wechseln von einem veralteten Point-of-Sale-System zu Magento 1.7 ausschließlich als POS. Es ist nicht unerwartet, dass wir vor der Herausforderung stehen, fast 20 Jahre Rekorde vom alten System ohne Katastrophe an Mage zu bringen.

Abgesehen von der Herausforderung, sogar Kundendatensätze zu migrieren, besteht das Problem, auf das ich mich in dieser Frage konzentriere, darin, wie ich historische Auftragsdaten vom alten POS zu Mage migrieren werde. Ich bin mir nicht hundertprozentig sicher, ob es sich um genaue Zahlen handelt, wenn es um viele Bestellaufzeichnungen geht, aber ich würde sagen, mindestens eine Million.

Ich überlege, wie ich das angehen soll:

  1. Finde heraus, wie genau die Daten formatiert werden müssen, damit Magento gut damit umgehen kann. Ob wir es aus dem alten POS in einem funktionierenden Format herausholen können, ist fraglich, aber nehmen wir für einen Moment an, dass dies gut geht ...
  2. Erstellen Sie eine CSV-Datei mit gut formatierten Verlaufsdaten
  3. Finde einen Weg, um das .CSV zeilenweise in Magentos $orderObjekt einzulesen -> save ()
  4. Profitieren!

Mein Problem ist, dass ich ein bisschen unklar bin, wie ich mich Punkt 2 und 3 nähere. Ich kann die Daten aus dem alten POS formatieren, wie ich es brauche, auch wenn es sehr umständlich ist und Perl involviert, aber sobald ich die CSV-Datei habe (oder welcher Dateityp auch immer für diesen Prozess funktionieren würde), bin ich mir ziemlich unklar wie ich es in Magentos Bestellobjekt einspeisen würde.

Ich habe ein bisschen gegoogelt und mir Beispiele ausgedacht, bei denen Benutzer das Bestellobjekt von Mage zum programmgesteuerten Importieren von Bestellungen verwenden, aber nur wenig darüber, wie sie andere Datenquellen als den Front-End-Wagen mit dem Objekt verbinden. Ich habe eine Version des Bestellobjekts untersucht:

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

Also hier sind meine spezifischen Fragen:

  1. Scheint dies eine sogar annähernd sinnliche Annäherung an dieses Problem zu sein? Und wenn nicht, wie könnte ich mich dieser Angelegenheit weniger idiotisch nähern?
  2. Wenn dies ein sinnvoller Ansatz ist, benötige ich für jedes Modell, das vom Bestellvorgang aufgerufen wird, eine andere CSV-Datei? zB Mage :: getModel ('sales / order'), Mage :: getModel ('sales / order_address'), etc?
  3. Ist eine .CSV überhaupt der richtige Weg?
  4. Wie würde ich meine Daten in dieses Objekt einspeisen, ob diese Daten in einer CSV-Datei enthalten sind oder was haben Sie?
  5. Wie würden Sie den Overhead begrenzen?

Auch wenn ich total idiotisch darüber nachdenke und du mir das erzählst, schätze ich jeden Input wirklich.

Danke danke danke!


1
Für Ihren Fall nicht wirklich von Bedeutung, aber werfen Sie einen Blick auf meine vorherige Frage und die Antwort von @BenMarks, die das Parsen von CSV in Magento beinhaltet und nützlich sein könnte. magento.stackexchange.com/questions/232/…
pspahn

1
Vielleicht möchten Sie sich dazu inspirieren lassen: github.com/avstudnitz/AvS_FastSimpleImport Es konzentriert sich hauptsächlich auf den Import von Produkten und Kunden, ist aber ein schnelles Importsystem. Wenn Sie von Millionen von Datensätzen sprechen, möchten Sie wahrscheinlich etwas Schnelles. Ich habe dies zuvor zum Importieren von CSV-Produktdateien verwendet. Sie lesen einfach die CSV-Datei und konvertieren die Daten in Arrays. Ich habe nicht versucht, dieses Modul zu erweitern, um Bestellungen zu verwenden. Ich habe also keine Ahnung, wie das funktionieren wird. Viel Glück.
Vicky

Wäre es also eine schlechte Idee, den Datenfluss - Import zum Importieren von Bestellungen zu automatisieren? Nach dem, was ich gelesen habe, scheint es eine Lösung zu sein, die ziemlich verbreitet ist.
Ersatzrad

Antworten:


9

Überrascht keine Antworten mit so vielen Stimmen / Ansichten, so werde ich beißen:

  1. Dies wäre abhängig vom alten Kassensystem, das die Daten beim Import massiert.
  2. Machen Sie sich Varien_Ioinsbesondere mit Varien_Io_File. Da Sie höchstwahrscheinlich mit einer so großen Datenmenge zu tun haben, sollten Sie Streams wie StreamReadCsvund verwenden StreamWriteCsv. Weitere Details zu einem "Stream" . Ohne Stream oder lineares Lesen / Schreiben können Speicherprobleme mit anderen Lade- / Schreibmethoden auftreten.

Mit dem oben Gesagten ist hier ein Beispiel: (Quelle 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
            );
        }
    }
}

Für den Import von Bestellungen hat dieses Beispiel am meisten geholfen: (Quelle: 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());

Mit dem Beispiel, das Sie jetzt haben, werden Sie ressourcenintensiv sein, da es Mage::getModel(...Aufrufe in foreach-Schleifen gibt, was eine schlechte Praxis ist und höchstwahrscheinlich entweder eine Zeitüberschreitung verursacht oder den Speicher ziemlich schnell auffüllt. Vor allem, wenn Sie dies in eine andere Zeit eingewickelt haben.

Dies...

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

Sollte aussehen, wie:

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

Ich würde nicht versuchen, alle CSV-Datenbits mit Magento-Objekten zu verknüpfen . Es wäre Wahnsinn und ein bisschen übertrieben, mit Ressourcenmodell Einstiegspunkten von zu halten $model->load(EntityId).

Beachten Sie auch, wenn Sie versuchen, mehr als 100.000 Bestellungen zu importieren , dass ich nach den großen Importen um die Leistung besorgt bin, da MySQL für die Verarbeitung so großer Mengen optimiert bleiben muss. und nicht gut unter hohem Volumen / Verkehr durchführen. Es gibt einen Grund, warum Magento Enterprise über ein Modul für das Kundenauftragsarchiv verfügt, mit dem alte Daten aus den "Transaktions" -Kundenauftragstabellen abgerufen werden können, um zu verhindern, dass veraltete Daten aufgebläht werden und nicht zum Entgegennehmen von Bestellungen benötigt werden.

To Wrap: Ich würde die Anforderungen und Bedürfnisse des Unternehmens zur Speicherung so großer Datenmengen ansprechen, wenn es lediglich Berichte gibt, für die es bessere Alternativen als für Magento gibt.



3

Wenn Sie über die Auswirkungen dieser historischen Bestellungen auf die Leistung von Magento / MySQL nachdenken und die Tatsache, dass nicht mehr unterstützte Produktlinien ebenfalls importiert werden müssen, könnte es sich lohnen, die historischen Bestellungen zusammen mit dem Kunden und den Produkten in einem Ordner zu speichern wie ein Elasticsearch-Index und führen Sie eine Suche nach Bedarf durch. dh die Kundenbestellhistorie Seite.


1

Das Erstellen eines Angebots und das anschließende Erstellen einer Bestellung nimmt zu viel Zeit in Anspruch, um umfangreiche Daten für den Import von Bestellungen zu erhalten.

Also habe ich recherchiert und die Schlussfolgerung von riesigen Auftragsimportdaten mit MySQL-Abfrage gefunden:

  1. Ich habe die Daten nur in Auftragstabellen eingefügt.

  2. Aktualisieren Sie das increment_id, um Magento 1.x zu erkennen, die letzte Bestellung increment_idist dies

  3. Diese Abfrage erstellt kein Angebot, keine Rechnung und keinen Versand:

    SQL-Abfragen: -

    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;

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.