Get data from child product - php

I have a module that observes the status and writes a value into the database.
When the product is simple, it works. But when it is configurable, it writes the value of the Pattern Product and not of the Child.
if (($status !== $previousStatus) && ($status == Mage_Sales_Model_Order::STATE_PROCESSING)) {
$order = $observer->getEvent()->getOrder();
$items = $order->getAllVisibleItems();
mysql_connect('localhost', 'user', 'pass');
foreach($items as $item){
$cd = $item->getProduct()->getData('cd');
mysql_query("INSERT INTO `bd`.`table` (`id`, `cd`) VALUES (NULL, '$cd')");
}
return true;
}
How to identify if it is a configurable product, and get data from the child product?

Magento already has a connection initialised, you don't need to spin up another one directly.
You shouldn't have to specify the database you're connecting to directly.
A configurable product can contain a simple product, to access this you'll need to get the childItem.
The preferred approach for this kind of thing would be to store the products data against the order item, so that if a product is deleted etc in the future you have a full history because order items are decoupled from their products data at time of placing. Read more here: https://magento.stackexchange.com/questions/62111/what-is-the-effect-of-deleting-a-product-with-associated-orders/62142#62142
Just a FYI but getAllVisibleItems returns configurables, if you wanted to see configurables and their simples all in one collection you could use getAllItems instead
if (($status !== $previousStatus) && ($status == Mage_Sales_Model_Order::STATE_PROCESSING)) {
/** #var Mage_Sales_Model_Order $order */
$order = $observer->getData('order');
$items = $order->getAllVisibleItems();
/** #var Mage_Sales_Model_Order_Item $item */
foreach($items as $item){
$cd = $item->getProduct()->getData('cd');
//If configurable get the first child item and the cd value from it
if ($item->getProductType() === Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE) {
$childrenItems = $item->getChildrenItems();
$childItem = reset($childrenItems);
if ($childItem instanceof Mage_Sales_Model_Order_Item) {
$cd = $childItem->getProduct()->getData('cd');
}
}
/** #var Mage_Core_Model_Resource $resource */
$resource = Mage::getSingleton('core/resource');
$writeConnection = $resource->getConnection('core_write');
$query = "INSERT INTO `table` (`cd`) VALUES ('{$cd}')";
$writeConnection->query($query);
}
return true;
}

Ignoring your SQL connection - you should revise that - take a look here:http://fishpig.co.uk/magento/tutorials/direct-sql-queries/
To get the chosen child product of a configurable product, do this;
foreach($items as $item){
// Establish product type and if configurable, load the chosen product
if ($item->getProductType() == Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE) {
$simple = reset($item->getChildren());
$_product = $simple->getProduct();
} else {
$_product = $item->getProduct();
}
$cd = $_product->getData('cd');
mysql_query("INSERT INTO `bd`.`table` (`id`, `cd`) VALUES (NULL, '$cd')");
}

Related

Magento2 How to update product information programmatically (PHP Script)?

I tried to update all product information by product id but it's not working for me for all information. With below code "SKU" update successfully but unable to update other information like product name and other custom attribute value.
How can I update all the information about the products using PHP script?
$productFactory = $objectManager->get('\Magento\Catalog\Model\ProductFactory');
$product = $productFactory->create()->setStoreId($storeId)->load($product_id);
$product->setStatus(1);
$product->setName('test pr 123');
$product->setSku('test sku');
$product->setDescription("new product description.");
$product->setShortDescription("new short description.");
$product->save();
Here I'm adding a script hope this will help and solve your problem
use Magento\Framework\App\Bootstrap;
require __DIR__ . 'app/bootstrap.php';
$params = $_SERVER;
$bootstrap = Bootstrap::create(BP, $params);
$objectManager = $bootstrap->getObjectManager();
$instance = \Magento\Framework\App\ObjectManager::getInstance();
$state = $objectManager->get('\Magento\Framework\App\State');
$state->setAreaCode('adminhtml');
$product_collections = $instance ->get('\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory');
$collections = $product_collections->create();
foreach ($collections as $product) {
$id = $product->getId();
$product = $objectManager->create('Magento\Catalog\Model\Product')->load($id);
$product->setWebsiteIds(array(1));
$product->save();
echo $id.'-';
}
Add your attribute which you need to update in code
If you just want to override some attribute values, you should use the addAttributeUpdate function. With that you can also update attribute values for different store views.
I use a kind of this code to update my products descriptions etc. for several stores.
$productRepository = $objectManager->get('Magento\Catalog\Model\ProductRepository');
// YOU WANT TO LOAD BY ID?
$id = "YOUR ID HERE";
// YOU WANT TO LOAD BY SKU?
$sku = "YOUR SKU HERE";
if($id) {
$product = $productRepository->getById($id);
}
if($sku) {
$product = $productRepository->get($sku);
}
$shortDescriptionAttributeCode = "short_description";
$descriptionAttributeCode = "description";
$shortDescriptionAttributeValue = "YOUR NEW VALUE";
$descriptionAttributeValue = "YOUR NEW VALUE";
$product->addAttributeUpdate($shortDescriptionAttributeCode, $shortDescriptionAttributeValue, 0);
$product->addAttributeUpdate($descriptionAttributeCode, $descriptionAttributeValue, 0);

How to create a simple product programmatically using csv data in magento2

I am trying to create a simple product programmatically using csv data.
But my product doest not insert in db and admin panel??? Any suggestion pls
Sku,Name,AttributeSetId,CategoryId,Description,Status,TypeId,Price,WebsiteIds,Visibility,UrlKey //title for the csv data
nailPolish,nailpolish,9,2,verybrightproduct,1,simple,200,base,4,nailpolish//csv data
nailRemover,nailremover,9,2,niceproduct,1,simple,200,base,4,nailremover//csv data
<?php
use Magento\Framework\App\Bootstrap;// add bootstrap
include("app/bootstrap.php");
$bootstrap = Bootstrap::create(BP, $_SERVER);
$objectManager = $bootstrap->getObjectManager();
$objectManager = $bootstrap->getObjectManager();
$state = $objectManager->get('Magento\Framework\App\State');
$state->setAreaCode('frontend');
function readOptions() //to read csv file
{
$options = array();
$file = 'csv/csvSimpleproduct.csv';
$handle = fopen($file, "r");
$headers = false;
if (empty($handle) === false) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
if (!$headers)
$headers[] = $data;
else
$options[] = $data;
}
fclose($handle);
}
return $options;
}
$importProduct = readOptions();
echo '<pre>';
print_r($importProduct);//printing array values
echo '</pre>';
foreach ($importProduct as $importProducts) { //to get single array values
$product = $objectManager->create('\Magento\Catalog\Model\Product');//creating object manager
$product->setSku($importProducts[0]);//to set sku values
$product->setName($importProducts[1]);// to set name of the product
$product->setAttributeSetId($importProducts[2]); //Default attribute set for products
$product->setCategories($importProducts[3]);//
$product->setDescription($importProducts[4]);//to give descriptions
$product->setStatus($importProducts[5]);
$product->setProductType($importProducts[6]);
$product->setPrice($importProducts[7]);// to give price of an product
$product->setWebsiteIds(array(1));//set main website view
$product->setVisibility($importProducts[9]);
$product->setUrlKey($importProducts[10]);//to set url to the product
}
my csv file is:
Sku,Name,AttributeSetId,CategoryId,Description,Status,TypeId,Price,WebsiteIds,Visibility,UrlKey
nailPolish,nailpolish,9,2,verybrightproduct,1,simple,200,base,4,nailpolish
nailRemover,nailremover,9,2,niceproduct,1,simple,200,base,4,nailremover
Maybe something else is wrong, but you need to save your product by product repository
/** #var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */
$product = $productRepository->save($product);
for now, you do not save product at all
also, it's not a best practice to use object manager directly, use product factory for creating new objects

Sylius add to cart via CartItemController gives 0,00 total

We are currently developing an ERP-based webshop with Sylius. One of the features is that a customer can select multiple sizes and quantities and add them to their cart in one action.
Normally Sylius would work with a request-based ItemResolver for only one variant. We've tried to override the CartItemController so that we would be able to loop the request variables and add all the items to the cart.
We tried to use this code:
try {
// When we have multiple
$reqSize = $request->request->get('size');
$reqQuantity = $request->request->get('quantity');
$reqProductID = $request->request->get('product_id');
$reqColorID = $request->request->get('variant_color_id');
if (null !== $reqSize && null !== $reqQuantity && null !== $reqProductID && null !== $reqColorID && count($reqSize) === count($reqQuantity)) {
$provider = $this->get('sylius.cart_provider'); // Implements the CartProviderInterface.
$currentCart = $provider->getCart();
$priceCalculator = $this->get('sylius.price_calculator');
$availabilityChecker = $this->get('sylius.availability_checker');
$productRepo = $this->get('sylius.repository.product');
$variantRepo = $this->get('sylius.repository.product_variant');
$sizeRepo = $this->get('jartazi.repository.sizegrid_size');
$colorRepo = $this->get('jartazi.repository.color');
$product = $productRepo->find(intval($reqProductID));
$color = $colorRepo->find(intval($reqColorID));
for ($i = 0; $i < count($reqSize); $i++) {
$size = $sizeRepo->find(intval($reqSize[$i]));
$variant = $variantRepo->findOneBy(['object' => $product, 'size' => $size, 'color' => $color]);
$quantity = intval($reqQuantity[$i]);
if (null === $variant) {
throw new ItemResolvingException('Selected item is out of stock.');
}
if (null !== $product && null !== $color && null !== $size && null !== $variant) {
// Make a cart item
$item = $this->get('sylius.factory.cart_item')->createNew();
$item->setSize($size);
$item->setVariant($variant);
$item->setQuantity($quantity);
$context = ['quantity' => $quantity];
if (null !== $customer = $cart->getCustomer()) {
$context['groups'] = $customer->getGroups()->toArray();
}
$item->setUnitPrice($priceCalculator->calculate($variant, $context));
// Check for equal products
foreach ($currentCart->getItems() as $cartItem) {
if ($cartItem->equals($item)) {
$quantity += $cartItem->getQuantity();
break;
}
}
if (!$availabilityChecker->isStockSufficient($variant, $quantity)) {
throw new ItemResolvingException('Selected item is out of stock.');
}
$event = new CartItemEvent($cart, $item);
// Update models
$eventDispatcher->dispatch(SyliusCartEvents::ITEM_ADD_INITIALIZE, $event);
$eventDispatcher->dispatch(SyliusCartEvents::CART_CHANGE, new GenericEvent($cart));
$eventDispatcher->dispatch(SyliusCartEvents::CART_SAVE_INITIALIZE, $event);
// Write flash message
$eventDispatcher->dispatch(SyliusCartEvents::ITEM_ADD_COMPLETED, new FlashEvent());
}
}
return $this->redirectAfterAdd($configuration);
}
} catch (ItemResolvingException $exception) {
// Write flash message
$eventDispatcher->dispatch(SyliusCartEvents::ITEM_ADD_ERROR, new FlashEvent($exception->getMessage()));
return $this->redirectAfterAdd($configuration);
}
But when we add one to the cart, the cart total stays 0,00
Are we missing something in order to have the correct totals when adding a CartItem without an ItemResolver?
Thanks in advance.
Yes, with use of this service we were able to correctly modify the quantity and the unit prices. Thanks, we clearly overlooked this service. Our modification of the CartItem ($item->setQuantity($quantity);) we also deleted as this was a custom method, the setter was normally not available.
As specified by Coudenysj you probably need to call the OrderItemQuantityModifier somewhere in your code.
I think you need to manually call the modifier before you set the quantity
$this->get('sylius.order_item_quantity_modifier')->modify($item, $quantity);
// $item->setQuantity($quantity);
Actually it appears you just need to call the modify function and it updates the quantity to the correct value
I had a lot of trouble making my own add to cart code for this reason. I ended up modifying the CartItemType. But now i do need to be able to add multiple to the cart at once. So i would be very interested to hear if this solves your issues.
Please post an update
Take a look at the sylius.order_item_quantity_modifier service: http://docs.sylius.org/en/latest/bundles/SyliusOrderBundle/services.html#orderitemquantitymodifier.

Programmatically stop decreasing stock qty while placing an order in magento and increaging qty when order state is Compleate

In Magento 1.9.0.1 by default, it decreases stock qty while placing an order. I want to stop decreasing stock qty while placing an order for the purpose of fake order. And I also want the functionality of increasing stock qty while order state is complete, not pending, not processing. How to do it programmatically or by setting up in Admin panel. If any one knows about it, please reply back.
Thank You
Ankan
Just simply open your admin panel, go to System->Configuration->Catalog Tab->Inventory Then click on Stack Option and change Decrease Stock When Order is Placed to NO.
Thanks,
Lovekesh
In Admin panel, System->Configuration->Catalog Tab->Inventory Then click on Stack Option and change Decrease Stock When Order is Placed to NO. So that it stops the stock qty increasing.In Model/Automatically/Complete/Order/Observer.php page, class Webspidy_Customoption_Model_Automatically_Complete_Order_Observer
{ public function __construct(){}
public function automaticallycompleteorder($observer)
{
//Mage::log('Ankan');
$order = $observer->getEvent()->getOrder();
/$orders = Mage::getModel('sales/order_invoice')->getCollection()
->addAttributeToFilter('order_id', array('eq'=>$order->getId()));/
/*if ((int)$orders->count() !== 0) {
return $this;
}*/
//Mage::log($orderstate);
//if($order->getState() == 'complete'){
if(($order->getState() == 'processing') || ($order->getState() == 'pending_payment')){
if($order->hasInvoices()){
//Mage::log($orderstate);
//Mage::log('Ankan');
//Mage::log($order->getData());
//====== Order Details ================
$orderNumber = $order->getIncrementId(); //Mage::log($orderNumber);
$orderDet = Mage::getModel('sales/order')->load($orderNumber, 'increment_id');
//Mage::log($orderDet->getData());
$orderItems = $orderDet->getItemsCollection()
->addAttributeToSelect('*')
->load();
foreach($orderItems as $orderItem){
$productId = $orderItem->getProductId();
$productOptionSku = $orderItem->getSku();
$productQty = $orderItem->getQtyOrdered();
$product = Mage::getModel('catalog/product')->load($productId);
$sku = $product->getSku();
$centralqty = $product->getStockItem()->getQty();
$values = array();
foreach ($product->getOptions() as $o) {
$p = $o->getValues();
}
foreach($p as $v)
{
$optionSku = $v->getSku();
$optionItem = $v->getQty();
//Mage::log($optionItem);
//Mage::log($productOptionSku.".....".$sku."-".$optionSku.".....".$optionItem);
if($productOptionSku == ($sku."-".$optionSku)){
if($centralqty >= ($optionItem*(int)$productQty)){
//$stockQty = (($centralqty-($optionItem*(int)$productQty))+$productQty);
$stockQty = ($centralqty-($optionItem*(int)$productQty));
}
}
}
$product->save();
//Mage::log($stockQty);
$stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($productId);
//$stockItem = Mage::getModel('cataloginventory/stock_item')->load($productId);
$stockItemId = $stockItem->getId();
$stockItem->setData('qty', $stockQty);//(integer)$XMLproduct->QtyInStock
$stockItem->setData('manage_stock',1);
$stockItem->save();
}
}
//======== End ======
}
}
}
And in etc/config.xml,
<global><events>
<sales_order_save_after><observers>
<webspidy_customoption_automatically_complete_order_observer>
<type>singleton</type> <class>Webspidy_Customoption_Model_Automatically_Complete_Order_Observer</class>
<method>automaticallycompleteorder</method>
</webspidy_customoption_automatically_complete_order_observer>
</observers></sales_order_save_after></events></global> After a long process, I have got a success by creating Observer in my custom module.
I am using Magento 1.9
I have tried with the following code. it's OK But i have another smart code
$stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($productId);
$stockItemId = $stockItem->getId();
$stockItem->setData('qty', $stockQty);
$stockItem->setData('manage_stock',1);
$stockItem->save();
My code is following:-
Mage::getModel('cataloginventory/stock')->backItemQty($productId,$new_qty);

Magento Configurable Product working but not showing until re-saved

I am currently learning how to create configurable product for Magento. Its all working fine, the product was successfully imported using my codes including its associated products. The problem is the product does not show up in front-end. I have to manually go to the back-end, edit the product and save it. Take note I do not have to change anything, I just need to open it, and save. Only then it will show up in front-end. Any idea why is that?
define('MAGENTO', dirname(dirname(__FILE__)));
require_once MAGENTO . '/app/Mage.php';
require_once 'FeedMag.php';
$myFeed = new FeedMag();
Mage::app();
// test data
$sku = "TESTSKU2";
$inventory = "10";
$stockData['qty'] = $inventory;
$stockData['is_in_stock'] = 1;
$simple['Description'] = 'Configurable Product 1';
$simple['ShortDescription'] = 'Short Description';
$simple['LongDescription'] = 'Long Description';
$simple['BrandCode'] = 'Nike';
$attr['color'] = 'Blue';
$attr['size'] = 1;
$price = 11;
// get attribute id
foreach($attr AS $key=>$value) {
$attr_ids[] = $myFeed->attributeValueExists($key, $value);
}
$new = false;
echo "<pre>";
try {
// get product id from SKU
$id = Mage::getModel('catalog/product')->getIdBySku($sku);
// load product if id exist or create a new one
if($id && $id > 0) {
$product = Mage::getModel('catalog/product')->load($id);
}
else {
$product = Mage::getModel('catalog/product')->setSku($sku);
$new = true;
}
// set it to configurable
$product->setTypeId('configurable');
// get attributes' id
$usingAttributeIds = $new_array = array();
foreach( $attr as $key=>$value ) {
$attribute = $product -> getResource() -> getAttribute( $key );
if ( $product -> getTypeInstance() -> canUseAttribute( $attribute ) ) {
if ( $new ) { // fix for duplicating attributes error
$usingAttributeIds[] = $attribute -> getAttributeId();
}
}
}
// if we have attributes' ID, set it to the product
if ( !empty( $usingAttributeIds ) ) {
$product -> getTypeInstance() -> setUsedProductAttributeIds( $usingAttributeIds );
$attributes_array = $product->getTypeInstance()->getConfigurableAttributesAsArray();
foreach($attributes_array as $key => $attribute_value) {
$attributes_array[$key]['label'] = $attribute_value['frontend_label'];
}
$product -> setConfigurableAttributesData($attributes_array);
$product -> setCanSaveConfigurableAttributes( true );
$product -> setCanSaveCustomOptions( true );
}
// set product data
$product->setStoreId(0)
->setAttributeSetId(4)
->setStockData($stockData)
->setPrice($price)
->setName($simple['Description'])
->setShortDescription($simple['ShortDescription'])
->setDescription($simple['LongDescription'])
->setCategoryIds(array(3))
->setVisibility(Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH)
->setBrand($simple['BrandCode'])
->setStatus(1)
->setTaxClassId(2) //Taxable goods
->save();
// get previous children if any
$associated = Mage::getModel('catalog/product_type_configurable')
->getChildrenIds($product->getId());
// add new simple product to configurable product
$associated[0][] = Mage::getModel('catalog/product')->getIdBySku('SIMPLE1');
// add all simple product to configurable product
Mage::getResourceModel('catalog/product_type_configurable')
->saveProducts($product->getId(), array_unique($associated[0]));
}
catch (Mage_Core_Exception $e) {
echo $e->getMessage();
}
catch (Exception $e) {
echo $e;
}
echo "</pre>";
FeedMag is a custom class made by my colleague. There's a lot of method in there but for this purpose I'll be using just one; attributeValueExists to check if said attribute exists and if it does, its ID will be returned.
Simple product already exists so I just need to use it (SIMPLE1).
Its an issue with the indices when importing. You must be missing a field in the export sheet that is required to associate the items and the store. The reason it works when you save is because its rebuilding the table indices which is filling in that missing data.

Categories