2009-05-22 20 views
10

Ho un database client con una vasta gamma di articoli di magazzino, che vengono caricati su Magento come prodotti semplici.API Magento: assegnazione di prodotti preesistenti semplici a prodotti configurabili

Ora ho bisogno di raggrupparli e assegnarli a prodotti configurabili con le loro dimensioni e colori come attributi configurabili.

L'API Magento ha una classe Product_Link, con un metodo di ricerca promettente: catalog-product-link.assign (link), ma non posso per la vita di me capire quali argomenti ho bisogno per farlo funzionare con prodotti configurabili, a condizione che questo fosse il modo in cui assegnare era destinato.

+14

La documentazione di Magento è spazzatura, non è vero? – Dan

+0

Oh, ti sento lì! Ogni tanto ricevo spam da loro per acquistare effettivamente la documentazione dell'utente. Pfft! – keith

+0

Sì, ho ricevuto il loro "suggerimento" anche via Twitter. In effetti, ho già acquistato la Guida utente ufficiale, che non è utile per uno sviluppatore. Comprato anche il libro php | architect, che è una buona lettura ma dovrebbe essere 10 volte più spessa. –

risposta

5

Bene, le note qui mi hanno aiutato a farlo funzionare. Quindi ho pensato di condividere con voi il codice per aggiungere un prodotto semplice a un prodotto configurabile esistente.

Questo codice presuppone che il prodotto semplice sia valido da aggiungere, non sono sicuro di cosa succederebbe se non lo fosse.

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

Sto provando a farlo da uno script da riga di comando e non riesco a farlo qui: $ loader = Mage :: getResourceModel ('catalog/product_type_configurable') -> load ($ _configurableProduct); (prima riga) Qualche idea? Attualmente sto indagando e informerò in caso di un risultato. –

+0

Ho aggiornato il codice di Scimon per funzionare di nuovo nelle versioni recenti di Magento: [vedi sotto] (http://stackoverflow.com/a/14461333/219467) – aeno

1

Questa è un'ipotesi non istruita, ma penso che ciò che si richiede non può essere fatto con l'API esistente. Dovrai scrivere da solo o direttamente sul DB.

+1

Con lo schema db EAV che usano non c'è 'solo' quando si accede direttamente al DB. Il dolore!!! –

2

Sto lavorando per farlo ora.

Finora ho trovato questi oggetti utili come riferimenti:

vi posterò il mio codice finora, e si spera aggiornarlo una volta che funziona ..

// 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, utilizza "item_size" come attributo che differenzia i prodotti "semplici". Inoltre, ciò presuppone che lo SKU principale "configurabile" sia la radice dello SKU secondario. Ad esempio, ABC001 è il genitore mentre ABC001-SMALL e ABC001-LARGE sono i bambini semplici.

La speranza che aiuta qualcuno.

+0

Non so se stai ancora lavorando su questo, ma penso di averlo risolto. – Scimon

1

Ecco il modo di hacking che ho fatto direttamente con PHP. Ci sono tre tabelle correlate. Stavo usando colori e dimensioni come miei attributi. I miei prodotti principali (configurabili) non esistono realmente nel mio catalogo. Sono essenzialmente a livello di modello e quindi i prodotti sono il livello SKU. COSÌ COME 'parentproductsku%' funziona per i bambini.

$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

Sorprendentemente, questo funziona, se tutti i vostri prodotti semplici condividono lo stesso prezzo:

 $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

Il codice della risposta accettata dalla Scimon non funziona più nelle ultime versioni di Magento (almeno in 1.7). Ma per fortuna, è necessario solo un piccolo fix per farlo funzionare di nuovo:

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

Ho avuto una risposta esente? E 'stato un po' di tempo fa, non ho fatto nessuno sviluppo di Magento per un anno o giù di lì ora, quindi andate con questo. – Scimon

+0

Probabilmente avrebbe dovuto essere una modifica alla risposta accettata IMHO. –

+0

@Joseph: Non avevo abbastanza reputazione per farlo al momento della scrittura, quindi ho postato una nuova risposta. – aeno

0

@ soluzione AENO non ha funzionato per me, così ho raffinato un po '.Questo è stato testato utilizzando un prodotto istanziato tramite il metodo 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); 
}