Magento API: Atribuir pré-existente produtos simples para produtos configuráveis
Pergunta
Eu tenho um banco de dados do cliente com uma grande variedade de itens de estoque, que estão sendo enviados para o Magento como produtos simples.
Agora eu preciso agrupá-los para cima e atribuí-los aos produtos configuráveis ??com seu tamanho e cor sendo seus atributos configuráveis.
A API Magento tem uma classe Product_Link, com um método de procura prometendo:-produto do catálogo-link.assign ( link ), mas eu não posso para a vida de me descobrir o que argumentos eu preciso para fazê-lo funcionar com produtos configuráveis, oferecendo isto é como atribuir era feito para ser usado.
Solução
Bem as notas aqui me ajudou a conseguir esta corrida. Então eu pensei que eu iria compartilhar com você o código para adicionar um produto simples de um configurável de produtos existentes.
Este código assume o produto simples é válida para adicionar, eu não tenho certeza o que aconteceria se não 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 ) );
}
Outras dicas
O código da resposta aceito por Scimon não funciona mais em versões recentes do Magento (pelo menos em 1.7). Mas, felizmente, você precisa de apenas uma pequena correção para fazê-lo funcionar novamente:
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 ) );
}
Eu estou trabalhando em fazer isso agora.
Até agora eu encontrei esses itens úteis como referência:
- http://snippi.net/magento-programmatically-add -produto -configurable-color-api
- http: //www.omnisubsole .com / blog / 2009/07/01 / configuráveis-produtos-em-magento.html
- http://www.magentocommerce.com/boards/viewthread/6941/ P30 /
Vou postar meu código até agora, e espero que atualizá-lo, uma vez que funciona ..
// 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, isso usa 'item_size' como o atributo que diferencia os produtos "simples". Além disso, isso pressupõe que o pai "configurável" SKU é a raiz da criança SKU. Por exemplo, ABC001 é o pai enquanto ABC001-pequenas e ABC001-GRANDE são os simples crianças.
Espero que ajude alguém.
I este é um palpite-un, mas acho que seu pedindo não pode ser feito com a API existente. Você terá que escrever o seu próprio ou só tenho diretamente para o DB.
Aqui é a maneira Hack-y que eu fiz isso em linha reta com PHP. Há três tabelas relacionadas. Eu estava usando cor e tamanho como meus atributos. Meus produtos de origem (configurável) na verdade não existe no meu catálogo. Eles são essencialmente nível do modelo e, em seguida, os produtos são o nível de SKU. Então LIKE 'parentproductsku%' funciona para as crianças.
$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
Surpreendentemente, isso funciona, se todos os seus produtos simples compartilhar o mesmo preço:
$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();
@ do aeno solução não funcionou para mim, então eu refinado um pouco. Isto foi testado usando um produto instanciado através do método 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 );
}