Magento 2 Programatically create a product on the checkout_cart_product_add_after event
-
08-01-2021 - |
Question
I'm currently working on a module that adds specific products to the cart when the customer adds a normal product. I created an observer for the checkout_cart_product_add_after. The user will select a few options which will be posted and this observer will form a sku with that, get the specific product and add it to the cart.
The problem is that sometimes a product with the formed sku might not exist, so I want to create and then add it to the cart. I've tried a few things, but it doesn't seem to work.
Here is the code I currently have, which adds the specific products to the cart.
Thanks for the help.
// Get the custom variations values added through the VariationsInput block.
$post = $this->_request->getParam('variations');
// Create the custom sku.
$customSku = 'SV';
foreach ($post as $key => $value) {
if ($key == '' || $value == '') {
continue;
}
$customSku .= $value;
}
// Get the current product the user is trying to add to cart.
$currentProduct = $observer->getEvent()->getData('product');
// Get the additional product that needs to be added to cart.
$productToAdd = $this->_productRepository->get($customSku);
// Here is the part where I need to check if the product doesn't exist and then create it.
if (empty($productToAdd)) {
//Code to create the product and assign it to the $productToAdd variable.
}
// Enter the id of the prouduct which are required to be added to avoid recurrssion
if ($currentProduct->getId() != $productToAdd->getId()) {
$params = array(
'product' => $productToAdd->getId(),
'qty' => $currentProduct->getQty()
);
$this->_cart->addProduct($productToAdd, $params);
$this->_cart->save();
}
Solution
After days of so much researching, and debugging I finally found a solution! It might be too specific, but I hope someday it will save someone hours of work.
I was using the following code to create the product, but it was not creating anything:
$objectManager = \Magento\Framework\App\ObjectManager::getInstance(); // instance of object manager
$productToAdd = $objectManager->create('\Magento\Catalog\Model\Product');
$productToAdd->setSku($customSku); // Set your sku here
$productToAdd->setName($customSku); // Name of Product
$productToAdd->setAttributeSetId(10); // Attribute set id
$productToAdd->setStatus(1); // Status on product enabled/ disabled 1/0
$productToAdd->setVisibility(4); // visibilty of product (catalog / search / catalog, search / Not visible individually)
$productToAdd->setTypeId('simple'); // type of product (simple/virtual/downloadable/configurable)
$productToAdd->setPrice(0); // price of product
$productToAdd->setStockData(
array(
'use_config_manage_stock' => 0,
'manage_stock' => 1,
'is_in_stock' => 1,
'qty' => 999999999
)
);
$productToAdd->save();
As shown in my question, I was getting the generated sku and trying to create the product object with $this->_productRepository->get($customSku);
. In my mind, if the product with the generated sku existed, the object would be generated, and if it didn't exist, it would just return empty. And that's where I was wrong. If I try to retrieve a product with an sku that doesn't exist, it will create something different and skip the code and so the if (empty($productToAdd)) {}
will not work.
What I needed to do was to check if a product with the generated sku existed, before trying to retrieve it. If it did, then use $this->_productRepository->get($customSku);
, but if not, then use the code to create the product and add it to the cart. In the end it looked like this:
if($this->_product->getIdBySku($customSku)) {
$productToAdd = $this->_productRepository->get($customSku); // Get the additional product that needs to be added to cart.
} else {
$objectManager = \Magento\Framework\App\ObjectManager::getInstance(); // instance of object manager
$productToAdd = $objectManager->create('\Magento\Catalog\Model\Product');
$productToAdd->setSku($customSku); // Set your sku here
$productToAdd->setName($customSku); // Name of Product
$productToAdd->setAttributeSetId(10); // Attribute set id
$productToAdd->setStatus(1); // Status on product enabled/ disabled 1/0
$productToAdd->setVisibility(4); // visibilty of product (catalog / search / catalog, search / Not visible individually)
$productToAdd->setTypeId('simple'); // type of product (simple/virtual/downloadable/configurable)
$productToAdd->setPrice(0); // price of product
$productToAdd->setStockData(
array(
'use_config_manage_stock' => 0,
'manage_stock' => 1,
'is_in_stock' => 1,
'qty' => 999999999
)
);
$productToAdd->save();
}
$params = array(
'form_key' => $this->formKey->getFormKey(),
'product' => $productToAdd->getId(),
'qty' => $currentProduct->getQty()
);
$this->_cart->addProduct($productToAdd, $params); // Add the product to cart.