2009-05-22 11 views
10

Mam bazę danych klientów z szerokim asortymentem produktów, które są przesyłane do Magento jako proste produkty.Magento API: przypisywanie istniejących produktów do konfigurowalnych produktów

Teraz muszę je zgrupować i przypisać je do produktów konfigurowalnych, których rozmiar i kolor stanowią ich konfigurowalne atrybuty.

Magento API ma klasę Product_Link, z obiecującą metodą poszukuje: katalog-product-link.assign (link), ale nie mogę dla życia mnie zorientować się, jakie argumenty muszę zrobić to praca z konfigurowalne produkty, pod warunkiem, że w ten sposób ma być używane przypisanie.

+14

Dokumentacja Magento to śmieci, nieprawdaż? – Dan

+0

Oh, słyszę cię tam! Dostaję od nich spam od czasu do czasu, aby faktycznie kupić dokumentację użytkownika. Pfft! – keith

+0

Tak, dostałem też ich "sugestię", za pośrednictwem Twittera. W rzeczywistości już kupiłem oficjalny podręcznik użytkownika, który nie jest przydatny dla programisty. Kupiłem także książkę php | architect, która jest dobrą lekturą, ale powinna być 10 razy grubsza. –

Odpowiedz

5

Cóż, notatki tutaj pomogły mi uzyskać ten wynik. Pomyślałem, że podzielę się z tobą kodem, aby dodać prosty produkt do istniejącego Produktu Konfigurowalnego.

Kod ten zakłada, że ​​prosty produkt jest prawidłowy, ale nie jestem pewien, co by się stało, gdyby go nie było.

private function _attachProductToConfigurable($_childProduct, $_configurableProduct) { 
    $loader = Mage::getResourceModel('catalog/product_type_configurable')->load($_configurableProduct); 

    $ids = $_configurableProduct->getTypeInstance()->getUsedProductIds(); 
    $newids = array(); 
    foreach ($ids as $id) { 
     $newids[$id] = 1; 
    } 

    $newids[$_childProduct->getId()] = 1; 

    $loader->saveProducts($_configurableProduct->getId(), array_keys($newids));     
} 
+0

Próbuję zrobić to ze skryptu wiersza poleceń, a ja tu ponoszę porażkę: $ loader = Mag :: getResourceModel ("katalog/product_type_configurable") -> load ($ _configurableProduct); (pierwsza linia) Jakieś pomysły? Obecnie prowadzę dochodzenie i poinformuję w przypadku wyniku. –

+0

Zaktualizowałem kod przez Scimon do pracy w najnowszych wersjach magento: [patrz poniżej] (http://stackoverflow.com/a/14461333/219467) – aeno

1

To jest niewykształcone domysły, ale myślę, że nie można tego zrobić z istniejącym API. Będziesz musiał napisać własną lub właśnie dostałeś się bezpośrednio do DB.

+1

Korzystając ze schematu dbV db, nie ma "just" przy bezpośrednim dostępie do DB. Ból!!! –

2

Pracuję nad zrobieniem tego teraz.

tej pory znalazłem te elementy pomocne jako odniesienia:

wyślę mojego kodu do tej pory, i mam nadzieję, że go zaktualizować po uruchomieniu ..

// Set 'item_size' as the super attribute # choose your own attribute! 
// this is the 'choose-able' field that differenciates products 
$super_attributes=array(Mage::getModel('eav/entity_attribute') 
    ->loadByCode('catalog_product','item_size') 
    ->getData('attribute_id') 
); 
$product_collection=Mage::getModel('catalog/product')->getCollection(); 

// Fetch configurable orders 
$product_collection->addFieldToFilter('type_id',Array('eq'=>"configurable")); 
#$product_collection->addFieldToFilter('sku',Array('eq'=>"ASMCL000002")); 

$product_collection->addAttributeToSelect('*'); 

$count=0; 
foreach($product_collection as $product) { 
    $sku = $product->getSku(); 
    echo "SKU: $sku\n"; 

    $simple_children_collection = Mage::getModel('catalog/product')->getCollection(); 
    $simple_children_collection->addAttributeToSelect('*'); 
    $simple_children_collection->addFieldToFilter('sku',Array('like'=>$sku . "-%")); 
    echo "children: "; 
    foreach($simple_children_collection as $child) { 
     $child_sku = $child->getSku(); 
     echo "$child_sku "; 
     #visiblity should be 'nowhere' 
    } 
    echo "\n"; 

if (!$product->getTypeInstance()->getUsedProductAttributeIds()) { 
    # This is a new product without the Configurable Attribue Ids set 
    $product->getTypeInstance() 
    ->setUsedProductAttributeIds($super_attributes); 

    //$product->setConfigurableAttributesData(array($_attributeData)); 
    $product->setCanSaveConfigurableAttributes(true); # Not sure if this is needed. 

    $product->setConfigurableProductsData(''); # Use this to add child products. 

} 


    $count++; 

    try { 
     $product->save(); 
     $productId = $product->getId(); 
     echo $product->getId() . ", $sku updated\n"; 
    } 
    catch (Exception $e){ 
     echo "$sku not added\n"; 
     echo "exception:$e"; 
    } 

} 
echo "\nCount is $count\n"; 

OK, to używa "item_size" jako atrybutu odróżniającego "proste" produkty. Ponadto zakłada się, że "konfigurowalna" nadrzędna jednostka SKU jest źródłem kodu SKU dziecka. Na przykład ABC001 jest rodzicem, a ABC001-SMALL i ABC001-LARGE są prostymi dziećmi.

Nadzieję, że pomaga komuś.

+0

Nie wiem, czy wciąż nad tym pracujesz, ale myślę, że go złamałem. – Scimon

1

Oto hack-y sposób, że zrobiłem to prosto z PHP. Istnieją trzy powiązane tabele. Używałem koloru i rozmiaru jako moich atrybutów. Moje produkty macierzyste (konfigurowalne) w rzeczywistości nie istnieją w moim katalogu. Zasadniczo są to poziom modelu, a następnie produkty to poziom SKU. Tak LIKE "parentproductsku%" działa dla dzieci.

$query1 = "SELECT * FROM mage_catalog_product_entity WHERE type_id= 'configurable'"; 
    //Find the parent id 
    $statusMessage = "Ok, found a product with a confgurable attribute"; 
    $result1 = $this->runQuery($query1, "query1", $statusMessage); 
    while ($row1 = mysql_fetch_assoc($result1)) { //entering the first loop where products are configurable 
     $this->parentId = $row1['entity_id']; 
     $this->parentSku = $row1['sku']; 

     echo "The SKU was $this->parentSku" . "<br />"; 

    //insert these into the link table for association 
    $query2 = "SELECT * FROM mage_catalog_product_entity WHERE type_id= 'simple' AND sku LIKE '" . $this->parentSku . "%';"; 
    // find the child ids that belong to the parent 
    $statusMessage = "Found some children for $this->parentSku"; 
    $result2 = $this->runQuery($query2, "query2", $statusMessage); 
    while ($row2 = mysql_fetch_assoc($result2)) {//entering the second loop where SKU is like model sku 
     $this->childId = $row2['entity_id']; 
     $this->childSku = $row2['sku']; 

     echo "Now we're working with a child SKU $this->childSku" . "<br />"; 

     //"REPLACE INTO catalog_product_super_attribute SET product_id='".$product->entity_id."', attribute_id='".$attribute->attribute_id."', position='".$position."'"; 
     $query3 = "REPLACE INTO mage_catalog_product_super_attribute (product_id, attribute_id, position) VALUES ('" . $this->childId . "', '76', '0');"; 
     $message3 = "Inserted attribute for color for ID $this->childId SKU $this->childSku"; 
     $result3 = $this->runQuery($query3, "query3", $message3); 

     $query4 = "REPLACE INTO mage_catalog_product_super_attribute_label (product_super_attribute_id, store_id, use_default, value) VALUES (LAST_REPLACE_ID(), '0', '0', 'Color');"; 
     $message4 = "Inserted attribute for Color SKU $this->childSku ID was $this->db->insert_id"; 
     $result4 = $this->runQuery($query4, "query4", $message4); 

     $query5 = "REPLACE INTO mage_catalog_product_super_attribute (product_id, attribute_id, position) VALUES ('" . $this->childId . "', '529', '0');"; 
     $message5 = "Inserted attribute for Product Size SKU $this->childSku"; 
     $result5= $this->runQuery($query5, "query5", $message5); 


     $query6 = "REPLACE INTO mage_catalog_product_super_attribute_label (product_super_attribute_id, store_id, use_default, value) VALUES (LAST_REPLACE_ID(), '0', '0', 'Size');"; 
     $message6 = "Inserted attribute for Size SKU $this->childSku ID was $this->db->insert_id"; 
     $result6 = $this->runQuery($query6, "query6", $message6); 

     $query7 = "REPLACE INTO mage_catalog_product_super_link (product_id, parent_id) VALUES ('" . $this->childId . "', '" . $this->parentId . "');"; 
     $message7 = "Inserted $this->childId and $this->parentId into the link table"; 
     $result7 = $this->runQuery($query7, "query7", $message7); 

     $query8 = "REPLACE INTO mage_catalog_product_relation (parent_id, child_id) VALUES ('" . $this->parentId . "', '" . $this->childId . "');"; 
     $message8 = "Inserted $this->childId and $this->parentId into the link table"; 
     $result8 = $this->runQuery($query8, "query8", $message8); 

     } //end while row 2 the child ID 

      } //end while row 1 the parent id 
1

Co ciekawe, to działa, jeśli wszystkie produkty Twoje proste dzielić tę samą cenę:

 $childProducts = $configurable->getTypeInstance(true)->getUsedProductIds($configurable); 

     // Don't add this product if it's already there 
     if(!in_array($child->getId(), $childProducts)) {  
      $childProducts[] = $child->getId(); 
     } 


     $existingIds = $configurable->getTypeInstance(true)->getUsedProductAttributeIds($configurable); 
     $newAttributes = array(); 

     foreach($configurable->getTypeInstance(true)->getSetAttributes($configurable) as $attribute) { 

     if(!in_array($attribute->getId(), $existingIds) && $configurable->getTypeInstance(true)->canUseAttribute($attribute) 
      && $child->getAttributeText($attribute->getAttributeCode())) { 

      // Init configurable attribute 
      $configurableAtt = Mage::getModel('catalog/product_type_configurable_attribute') 
       ->setProductAttribute($attribute); 

      // Add new attribute to array 
      $newAttributes[] = array(
       'id'    => $configurableAtt->getId(), 
       'label'   => $configurableAtt->getLabel(), 
       'position'  => $attribute->getPosition(), 
       'values'   => $configurableAtt->getPrices() ? $configurable->getPrices() : array(), 
       'attribute_id' => $attribute->getId(), 
       'attribute_code' => $attribute->getAttributeCode(), 
       'frontend_label' => $attribute->getFrontend()->getLabel(), 
      ); 
     } 
    } 

    if(!empty($newAttributes)) { 

     $configurable->setCanSaveConfigurableAttributes(true); 
     $configurable->setConfigurableAttributesData($newAttributes); 
    } 
     $configurable->setConfigurableProductsData(array_flip($childProducts)); 
     $configurable->save(); 
3

Kod z przyjętym Odpowiedź Scimon nie działa już w ostatnich wersjach Magento (przynajmniej w 1.7). Na szczęście wystarczy mała poprawka, aby ponownie zadziałać:

private function _attachProductToConfigurable($_childProduct, $_configurableProduct) { 
    $loader = Mage::getResourceModel('catalog/product_type_configurable')->load($_configurableProduct, $_configurableProduct->getId()); 

    $ids = $_configurableProduct->getTypeInstance()->getUsedProductIds(); 
    $newids = array(); 
    foreach ($ids as $id) { 
     $newids[$id] = 1; 
    } 

    $newids[$_childProduct->getId()] = 1; 

    //$loader->saveProducts($_configurableProduct->getid(), array_keys($newids));     
    $loader->saveProducts($_configurableProduct, array_keys($newids));     
} 
+0

Miałem wyjątkową odpowiedź? To było jakiś czas temu, nie robiłem żadnego rozwoju Magento od roku, więc idź z tym. – Scimon

+0

To prawdopodobnie powinna być zmiana do zaakceptowanej odpowiedzi IMHO. –

+0

@Joseph: Nie miałem wystarczająco dużo reputacji, aby to zrobić w momencie pisania, więc wysłałem nową odpowiedź. – aeno

0

@ Rozwiązanie Aeno nie działa dla mnie, więc trochę go udoskonaliłem.Zostało to przetestowane przy użyciu produktu utworzonego za pomocą metody Mage::getModel('catalog/product')->load().

private function _attachProductToConfigurable($childProduct, $configurableProduct) 
{ 
    $childIds = $configurableProduct->getTypeInstance()->getUsedProductIds(); 
    $childIds[] = $childProduct->getId(); 
    $childIds = array_unique($childIds); 

    Mage::getResourceModel('catalog/product_type_configurable') 
     ->saveProducts($configurableProduct, $childIds); 
} 
Powiązane problemy