Add composite product to order programmatically in Woocommerce - php

I am struggling to add a composite product to to WC orders programatically. I have been going through the source code to try and figure this out, but keep running into errors.
What I am doing right now is creating at instance of WC_CP_Order to get access to the method add_composite_to_order($composite, $order, $quantity, $args)
$wc_cp = new WC_CP_Order(); // Create instance of WC_CP_Order
$composite_product = wc_get_product('39082'); // Get the composite product
$order = wc_get_order(39250); // Order that I want to add the composite product to
$args = array(
'configuration' => array(
1620281459 => array( // ID of the component.
'quantity' => 1, // Qty of composited product, will fall back to min.
'discount' => 0, // Composited product discount, defaults to the defined value.
'attributes' => array(), // Array of selected variation attribute names, sanitized.
'variation_id' => 39114, // ID of chosen variation, if applicable.
'args' => array() // Custom composited item args to pass into 'WC_Order::add_product()'.
)
)
)
$wc_cp->add_composite_to_order($composite_product, $order, 1, $args);
This configuration returns a 500 error when I trigger this function (this is just all of the code inside the function).
I am probably just overlooking something very simple, but so far am unable to find it. There are the docs that I have been using: https://docs.woocommerce.com/document/composite-products/. Any help or suggestions would be greatly appreciated!!

Related

How to update wp_wc_product_attributes_lookup table after running update_post_meta?

I am using the following code to add attributes to a product:
$product_attr = get_post_meta(2, '_product_attributes',true);
$product_attr["pa_product-type"] = [
'name' => "pa_product-type",
'value' => '',
'is_visible' => '0',
'is_taxonomy' => '1'
];
wp_set_object_terms(2, "Caps", pa_product-type , true );
update_post_meta(2, '_product_attributes', $product_attr);
The attribute is getting updated successfully in the product and is showing up in product edit page. However, the attribute value is not getting updated in wp_wc_product_attributes_lookup table. How to trigger update in this table after updating/adding attributes using the above code?
This is a very interesting question!
The wp_wc_product_attributes_lookup table is used to improve WooCommerce performance and it's normally updated automatically. There is a class DataRegenerator that handles the product attributes regeneration process. But if you change the attributes directly in the wp_postmeta like this:
$product_id = 46;
$product_attr = get_post_meta($product_id, '_product_attributes',true);
$product_attr["pa_color"] = [
'name' => "pa_color",
'value' => '',
'is_visible' => '0',
'is_taxonomy' => '1'
];
wp_set_object_terms($product_id, "Blue", 'pa_color' , true );
update_post_meta($product_id, '_product_attributes', $product_attr);
then the wp_wc_product_attributes_lookup table is not updated immediately.
But you can trigger this update manually by using LookupDataStore class.
First you add
use Automattic\WooCommerce\Internal\ProductAttributesLookup\LookupDataStore;
outside your function, for example on the top of the plugin or theme php file or just above your add_action line.
Then you can call the function to create product attributes in the lookup table for a specific product_id
$lookupDataStore = new LookupDataStore();
$lookupDataStore->create_data_for_product($product_id);
Source

Show product on main page by id opencart

I need to show one certain product on front page. I didn't find a module for this. What do I need to do? I need to show product with countdown timer but I can do this, I only do not know how to get product from database by ID or SKU. I guess the code should be like this:
echo $product_option_data[] = array(
'product_option_id' => $product_option['product_option_id'],
'option_id' => $product_option['option_id'],
'name' => $product_option['name'],
'type' => $product_option['type'],
'option_value' => $product_option['option_value'],
'required' => $product_option['required']
);
In OpenCart controller you can call
$this->load->model('catalog/product'); // only if not yet 'loaded' within the controller
$product = $this->model_catalog_product->getProduct($productId);
print_r($product);
which will return you the product by it's ID. Do with it whatever you need afterwards.

Magento API v1- List prices for all products in one call

I've got the following code:
$filters = array('sku' => array('like'=>'%'));
$items = $magConn->call($sessionID, 'product.list', array($filters));
This will return an array of all the products and their sku, description, and qty.
However, I also need to get the price? Is there a way to get that as well?
I've also got this working,
$properties = ($magConn->call($sessionID, 'product.info', $item['sku']));
which will return all the attributes for one product. I've got over 2,000 products, and this is definitely not feasible if I want it to end tonight. ;)
No way without magento source code modification. You should go to \app\code\core\Mage\Catalog\Model\Product\Api.php, find next lines inside items() method:
$result[] = array( // Basic product data
'product_id' => $product->getId(),
'sku' => $product->getSku(),
'name' => $product->getName(),
'set' => $product->getAttributeSetId(),
'type' => $product->getTypeId(),
'category_ids' => $product->getCategoryIds()
);
and add price here.
Load the collection :
$product = Mage::getModel('catalog/product')->load($productId);
Get actual price :
$product->getPrice();
Get special price :
$product->getFinalPrice();

Magento: how to load product along its all data as it is used in admin

I'm trying to get bundle options data. using this : $product->getBundleOptionsData I need to use this, as I'm trying to change data programmatically and I would like to do it in a way that's as close as used in admin .
However, when I var_dump the result of the above function I get NULL while in admin side in bundle model product type I get correctly the data.
When I var_dump $product in my own file I get much shorter data than when I var_dump in bundle model product type save function.
what do I need to do to load all data of the product, so I can use getBundleOptionsData. I looked in several files and googled, but can't find an answer.
Finally I made it work to get bundle options data so I can manipulate it. I found the main code in magento's model bundle observer class duplicateProduct function: I needed however to add option_id (careful not to forget that)
here is the code in it's final stage.
$product->getTypeInstance(true)->setStoreFilter($product->getStoreId(), $product);
$optionCollection = $product->getTypeInstance(true)->getOptionsCollection($product);
$selectionCollection = $product->getTypeInstance(true)->getSelectionsCollection(
$product->getTypeInstance(true)->getOptionsIds($product),
$product
);
$optionCollection->appendSelections($selectionCollection);
$optionRawData = array();
$selectionRawData = array();
$i = 0;
foreach ($optionCollection as $option) {
$optionRawData[$i] = array(
'option_id' => $option->getOptionId(), //my addition. important otherwise, options going to be duplicated
'required' => $option->getData('required'),
'position' => $option->getData('position'),
'type' => $option->getData('type'),
'title' => $option->getData('title')?$option->getData('title'):$option->getData('default_title'),
'delete' => ''
);
foreach ($option->getSelections() as $selection) {
$selectionRawData[$i][] = array(
'product_id' => $selection->getProductId(),
'position' => $selection->getPosition(),
'is_default' => $selection->getIsDefault(),
'selection_price_type' => $selection->getSelectionPriceType(),
'selection_price_value' => $selection->getSelectionPriceValue(),
'selection_qty' => $selection->getSelectionQty(),
'selection_can_change_qty' => $selection->getSelectionCanChangeQty(),
'delete' => ''
);
}
$i++;
}
$product->setBundleOptionsData($optionRawData); //changed it to $product
$product->setBundleSelectionsData($selectionRawData); //changed it to $product
you can either now change on the raw data in optionsrawdata. or getBundleOptionsData. and same for the other one.

Magento custom options: success.. almost!

Alright, so I'm working on my own script that reads specific xml files, and imports products. Now, each of these products may have a set of attributes, (i.e. color for example).
So, what I'm doing is importing each custom attribute, and generating a specific string, "Yellow, black finish wood" for example, and that would be a radio button you could select from when you go to order the product. Now, when I come to a product that has the same "parentid" but a different unique id, I need to generate a new row for the custom option radio button, so if there is another product where the color is red, I would have the following to select from:
Red, black finish wood
Yellow, black finish wood
This is working great for the first product with the same parent id, in other words, if I'm creating a brand new product, and not just adding custom options to the same product.
My question is, how do I generate a new custom option value, for the specific option? In other words, how do I add a new row to a certain option that is already created?
Here is basically what I'm doing to generate the first option on a new product.
$options = array();
$options[$ParentID] = array(
'title' => 'Option Title',
'type' => 'radio',
'is_require' => 1,
'values' => array()
);
$options[$ParentID]['values'][] = array(
'title' => 'Option Value Title',
'price' => 0.00,
'price_type' => 'fixed',
'sku' => $UniqueID,
);
foreach($options as $ParentID => $option) {
$id = Mage::getModel('catalog/product')->getIdBySku($ParentID);
$product = Mage::getModel('catalog/product')->load($id);
if(!$product->getOptionsReadonly()) {
$product->setProductOptions(array($option));
$product->setCanSaveCustomOptions(true);
$product->save();
}
}
this works out great, because magento generates an sku when they order a certain product in the format of $ParentID_$UniqueID, and then I can send the $UniqueID off to the vendor for the order.
So again, I'm open to suggestions as to how to add a Option Value to an already created Custom Option
load all options in and create array map with unique and already existing options to get their id -s in place

Categories