Create Product with custom option dropdown programatically - php

Im trying to create product with custom option dropdown programatically but it doesnt work and throw error. Maybe somebody know how to do it, I we be glad to hear it. In my opinion this script work well with single field option but not for dropdown.
PHP Warning: Invalid argument supplied for foreach()
My script file at root directory
<?php
use Magento\Framework\App\Bootstrap;
require 'app/bootstrap.php';
$bootstrap = Bootstrap::create(BP, $_SERVER);
$objectManager = $bootstrap->getObjectManager();
$state = $objectManager->get('Magento\Framework\App\State');
$state->setAreaCode('frontend');
$objectManager = \Magento\Framework\App\ObjectManager::getInstance(); // instance of object manager
$product = $objectManager->create('\Magento\Catalog\Model\Product');
$product->setSku('watermelon'); // Set your sku here
$product->setName('Watermelon'); // Name of Product
$product->setAttributeSetId(4); // Attribute set id
$product->setStatus(1); // Status on product enabled/ disabled 1/0
$product->setWeight(10); // weight of product
$product->setVisibility(4); // visibilty of product (catalog / search / catalog, search / Not visible individually)
$product->setTaxClassId(0); // Tax class id
$product->setTypeId('simple'); // type of product (simple/virtual/downloadable/configurable)
$product->setPrice(19); // price of product
$product->setStockData(
array(
'use_config_manage_stock' => 0,
'manage_stock' => 1,
'is_in_stock' => 1,
'qty' => 29
)
);
$product->save();
$options = array(
"title" => "Insurance",
"type" => "drop_down",
"is_require" => 0,
"sort_order" => 10,
"additional_fields" => array(
array(
"title" => "Not necessary",
"price" => 0,
"price_type" => "fixed",
"sku" => "not_necessary",
"sort_order" => 0
),
array(
"title" => "1 Year",
"price" => 0,
"price_type" => "fixed",
"sku" => "one_year",
"sort_order" => 1
),
array(
"title" => "2 Years",
"price" => 0,
"price_type" => "fixed",
"sku" => "two_years",
"sort_order" => 2
),
array(
"title" => "3 Years",
"price" => 0,
"price_type" => "fixed",
"sku" => "three_years",
"sort_order" => 3
),
)
);
foreach ($options as $arrayOption) {
$product->setHasOptions(1);
$product->getResource()->save($product);
$option = $objectManager->create('\Magento\Catalog\Model\Product\Option')
->setProductId($product->getId())
->setStoreId($product->getStoreId())
->addData($arrayOption);
$option->save();
$product->addOption($option);
}

Related

Woocommerce Programmatically change a "simple" product to a "variable" product with variations of downloads and hardcopies

I have a woocommerce (wordpress) up to date, with over 10k products which I need to create variations for, there are four kinds of variations, two are hardcopy with inventory control, the other two variation of the products does not need inventory control.
I have check out so many various ways people have created programmatically variations and attempted their scripts on a dev site, that I am starting to get bug eyed.
<?php
require_once('wp-load.php'); // load the wordpress core
require_once('functions.php') ; // custom functions to grab related data from the wpdb
$import_id = GetTheNextProduct(); // non-wordpress database
$is_variable_product = CheckIfVariable($import_id) ;
$post_id = GetRelatedWPDI($import_id); // returns related word press post `ID` of the product
// ... other variables are set in the same way... ie: $sku = GetSKU($import_id) ;
// the problem I am having is getting the current variation array into woocommerce variations,
// I've been able to do everything else.
if($is_variable_product == 1) {
$variations = GetVariations($import_id) ;
// woocommerce proper way to create variations....????
}
/* out example of $variations...
$variations = array(
"0" => array(
"ProductType" => "Small PDF",
"filepath" => "/path/to/pdf/file.pdf",
"filename" => "file.pdf",
"price" => "5.00",
"_visibility" => "visible",
"_stock_status" => "instock",
"_downloadable" => "yes",
"_weight" => "",
"_length" => "",
"_width" => "",
"_height" => "",
"_width" => "",
"inventory" => "unlimited",
"_sku" => "parent",
),
"1" => array(
"ProductType" => "Large PDF",
"filepath" => "/path/to/pdf/file-large.pdf",
"filename" => "file-large.pdf",
"price" => "10.00",
"_visibility" => "visible",
"_stock_status" => "instock",
"_downloadable" => "yes",
"_weight" => "",
"_length" => "",
"_width" => "",
"_height" => "",
"_width" => "",
"inventory" => "unlimited",
"_sku" => "parent",
),
"2" => array(
"ProductType" => "Small Hardcopy",
"filepath" => "",
"filename" => "",
"price" => "15.00",
"_visibility" => "visible",
"_stock_status" => "instock",
"_downloadable" => "yes",
"_weight" => "0.5",
"_length" => "",
"_width" => "8",
"_height" => "11",
"_width" => "",
"inventory" => "123",
"_sku" => "parent",
),
"4" => array(
"ProductType" => "Large Hardcopy",
"filepath" => "",
"filename" => "",
"price" => "20.00",
"_visibility" => "visible",
"_stock_status" => "instock",
"_downloadable" => "yes",
"_weight" => "0.5",
"_length" => "",
"_width" => "8",
"_height" => "11",
"_width" => "",
"inventory" => "456",
"_sku" => "parent",
),
)
*/
update_post_meta( $post_id, '_sku', $sku);
update_post_meta( $post_id,'_visibility','visible');
wp_set_object_terms($post_id, 'variable', 'product_type');
// do something here to the current $variations array variable to...
$variation_id = wp_insert_post( $variation_post );
$variation = new WC_Product_Variation( $variation_id );
foreach($variations as $vars_sub){
foreach($vars_sub as $key => $value) {
update_post_meta( $variation_id, 'attribute_'.$key, $value );
}
}
I've read, tried, so many of the script suggestions within stack, some which have helped a lot with simple products that remain simple... but this one has me stumped.
I solved this issue by leveraging WC's REST API and Python. My script is here: https://gist.github.com/Antebios/f53807040247b536e1674758a400dc45
Converting the product type from 'Simple' to Variable was easy, it was adding the variations that was tricky. I am doing an iteration loop and creating a variation from an array, I also check if the variation already exists so there are no duplicate variations. Have a look.

Adding item to Square via SquareConnect PHP API -- 'category' and 'fees' defs being excluded

SquareConnect API newbie here.
I am attempting to add an item to Square using the PHP method:
$api_instance = new SquareConnect\Api\V1ItemsApi();
$body = new \SquareConnect\Model\V1Item($request_body);
$result = $api_instance->createItem($location_id, $body);
My request_body definition:
$request_body = array(
"name" => "**ITEM NAME**",
"description" => "**ITEM DESCRIPTION**",
"category" => array(
"id" => "**CATEGORY ID**",
"name" => "**CATEGORY NAME**"
),
"variations" => array(
array(
"name" => "**VARIATION NAME**",
"sku" => "**SKU**",
"pricing_type" => "FIXED_PRICING",
"price_money" => array(
"currency_code" => "USD",
"amount" => "**AMOUNT**"
)
)
),
"fees" => array(
"enabled" => "1",
"name" => "Sales Tax",
"rate" => "0.0775",
"calculation_phase" => "FEE_SUBTOTAL_PHASE",
"adjustment_type" => "TAX",
"inclusion_type" => "ADDITIVE",
"type" => "US_SALES_TAX"
)
);
The item and variation data are being added to Square, but the "category" and "fees" definitions are not being included. As a result the item is ending up in flat space, which requires me to log into the main Square interface, add the item to the appropriate category AND set its tax information. I do not want to have to take these additional steps if they can be avoided.
The tax information in the "fees" section is taken verbatim from the definitions found in items added via the Square interface. I have confirmed and re-confirmed that the category id and category name match those of the desired category. I also tried replacing the "category" array with a simple "category_id" => "CATEGORY ID" definition. Same result.
Can anyone assist? Also, if there is a better method for adding an item to Square via the API, please let me know!
Thank you in advance.
Part one, categories
If you look at the docs about specifying a item category during item creation:
You are specifing an array:
"category" => array(
"id" => "**CATEGORY ID**",
"name" => "**CATEGORY NAME**"
),
you should instead be using a string:
"category" => "**CATEGORY ID**",
Part two, fees
If you look again at the docs, you won't see any reference to fees in V1 items create. That is because you cannot create a fee with that endpoint. Instead you should create a new fee. You can see some sample code here: https://github.com/square/connect-php-sdk/blob/master/docs/Api/V1ItemsApi.md#createfee
I'm going to focus on the category_id since you seemed to have figured out the "fees" issue based on the comments.
I just used this as test code, and the category was set successfully:
$items_api = new \SquareConnect\Api\V1ItemsApi();
$body = array(
"name" => "Test Item",
"category_id" => "YFIHMKYXNFJ7TE5FRBWQAGU6",
"variations" => array(
array(
"name" => "Small",
"pricing_type" => "FIXED_PRICING",
"price_money" => array(
"amount" => 100,
"currency_code" => "USD"
)
))
);
$result = $items_api->createItem($location_id, $body);
echo $result;
Location_id was created earlier, but everything else is there.

inserting value into PHP multi array

i am new in PHP coding, i wanna add some variable value in a multi array dynamically, below is my code...
$books = array (
"finality"=> array (
"title" => 1,
"author" => 2,
"thumbnail" => 3,
"file" => 4,
"comment" => 5,
),
"science"=> array (
"title" => 1,
"author" => 2,
"thumbnail" => 3,
"file" => 4,
"comment" => 5,
),
"morality"=> array (
"title" => 1,
"author" => 2,
"thumbnail" => 3,
"file" => 4,
"comment" => 5,
),
)
i want to add variables like. $title, $author, $pic2, $pic, $comment, in one array like $books['morality']. please help me.
If I undestand your question correctly, this is what you want.
$books['morality']['title'] = $title;
$books['morality']['author'] = $author;
$books['morality']['thumbnail'] = $pic2;
$books['morality']['file'] = $pic;
$books['morality']['comment'] = $comment;
If that's not what you are looking for try and be more precise in what you want to accomplish.
From what I understand, you would like to add a new item to the array.
Does the following look like what you need? If not, can you please try to clarify what it is that you would like?
$books[ $category ] = array(
"title" => $title,
"author" => $author,
"thumbnail" => $thumbnail,
"file" => $file,
"comment" => $comment
);

cannot add configurable product to cart in magento

i want to add a product to cart in magento , product details is :
type = configurable
product id = 1300
product sku = FCC100
Attribute Code= color
Attribute Label= color
Attribute Id= 152
options value = 28,43
options label = blue,red
this configurable product have two color option red and blue, there is two simple product atached to this configurable product.
i try with this code :
$product = array(
"product_id" =>"1300",
"qty" => 2,
"super_attribute" => array(152 => 28));
$result = $proxy->shoppingCartProductAdd($sessionID, $cartID, array($product));
but this code return me this message :
please specify product option(s)
i use this code to add simple product and it`s work fine :
$result = $proxy->shoppingCartProductAdd($sessionID, $cartID, array(array(
'product_id' => $productID ,
'sku' => $sku ,
'qty' => $qty,
'options' =>array(0 =>array('key' => $option1id ,'value' => $option1value),1 =>array('key' => $option2id ,'value' => $option2value)),
'bundle_option' => null,
'bundle_option_qty' => null,
'links' => null
)));
my problem is with configurable product. i try to add with simple child products but problem of this way is often child products have not price and price is setted to parent product.
what is the problem in my code ? is there any way to add configurable product to cart with out using API ?
this is what i found in product page source:
Product.Config({"attributes":{"152":{"id":"152","code":"color","label":"\u0631\u0646\u06af","options":[{"id":"28","label":"\u0622\u0628\u06cc","price":"0","oldPrice":"0","products":["1301"]},{"id":"47","label":"\u0632\u0631\u0634\u06a9\u06cc","price":"0","oldPrice":"0","products":["1302"]}]}},"template":"#{price}\u00a0\u0631\u06cc\u0627\u0644","basePrice":"550000","oldPrice":"550000","productId":"1300","chooseText":"\u0627\u0646\u062a\u062e\u0627\u0628 \u06cc\u06a9 \u06af\u0632\u06cc\u0646\u0647...","taxConfig":{"includeTax":false,"showIncludeTax":false,"showBothPrices":false,"defaultTax":0,"currentTax":0,"inclTaxTitle":"\u0634\u0627\u0645\u0644 \u0645\u0627\u0644\u06cc\u0627\u062a"}});
Your array must be like below
$arrProducts = array(
array(
"product_id" =>"21",
"qty" => 2,
"super_attribute" => array(
92 => 162
)
));
Your $product array is missing the options key values.
You need to add options which should be An array in the form of option_id => content per the documentation.
$product = array(
"product_id" => "1300",
"qty" => 2,
"options" => array(
152 => 28
)
);
Documentation: http://www.magentocommerce.com/api/soap/checkout/cartProduct/cart_product.add.html

MongoDB : Insert and Update in an array

I have "_id" and "ProductLot". How can I Update Qty "0" to "1 " in the Lot array if ProductLot if present or append a new Lot element if it is not present?
"_id" : ObjectId("5462e44c599e5c6c1300000a"),
"LocationName" : "Putaway",
"Owner" : "",
"Status" : "1",
"Scrap" : "0",
"Lot" : [{
"Qty" :"6",
"ProductLot" : ObjectId("5462dbd9599e5c200e000000"),
"Product" : ObjectId("543ca7be4cf59d400c000004"),
"Movement" :[ {"OriginId" : "266",Qty:2,Type:"DN"},
{"OriginId" : "267" , Qty:1 , Type:"DN"},
{"OriginId" : "2" , Qty:3 , Type:"IM"},
]
},
{
"Qty" :"0",
"ProductLot" : ObjectId("5462dbd9599e5c200e000003"),
"Product" : ObjectId("543ca7be4cf59d400c000004"),
"Movement" :[ {"OriginId" : "266",Qty:2,Type:"DN"},
{"OriginId" : "267" , Qty:1 , Type:"DN"},
{"OriginId" : "2" , Qty:-3 , Type:"IM"},
]
}]
}
EG: I have "ProductLot" : ObjectId("5462dbd9599e5c200e000000") present in array so it should update qty 0 to 1; however, "ProductLot" : ObjectId("5462dbd9599e5c200e00000a") is not available in array so that should append a new element to the array.
PHP code, which is not updating creating appending array at every time:
$inventoryId = new \MongoId($_POST["inventoryid"]);
$productLotId = new \MongoId($invlotid);
$originId = $_POST['id'];
//$lotcontent = [ /* whatever this looks like */ ];
$lotcontent = array(
'Qty' => $invqty,
'ProductLot' => new \MongoId($invlotid),
'Product'=>$invproduct,
'Movement'=> array(
array(
'OriginId' => $_POST['id'],
'Qty' => $invqty,
'Type'=> 'DN',
), )
);
$invcolname = 'Inventory';
$result = $mongo->$dbname->$invcolname->update(
// Match an inventory without the specific ProductLot/OriginId element
array(
'_id' => $inventoryId,
'Lot' => array(
'$not' => array(
'$elemMatch' => array(
'ProductLot' => $productLotId,
//'OriginId' => $originId,
),
),
),
),
// Append a new element to the Lot array field
array('$push' => array( 'Lot' => $lotcontent ))
);
$movementcontent = array(
'OriginId' => $_POST['id'],
'Qty' => $invqty,
'Type'=> 'DN',
);
$result = $mongo->$dbname->$invcolname->update(
// Match an inventory without the specific ProductLot/OriginId element
array(
'_id' => $inventoryId,
'Lot' => array(
//'$not' => array(
'$elemMatch' => array(
'ProductLot' => $productLotId,
'Movement'=>array(
'$not' => array(
'$elemMatch' => array(
'OriginId' => $originId,
)
)
)
),
// ),
),
),
// Append a new element to the Lot.Movement array field
array('$push' => array( 'Lot.$.Movement' => $movementcontent ))
);
$result = $mongo->$dbname->$invcolname->update(
// Match an inventory with a specific ProductLot/OriginId element
array(
'_id' => $inventoryId,
'Lot' => array(
'$elemMatch' => array(
'ProductLot' => $productLotId,
//'OriginId' => $originId,
'Movement'=>array(
'$elemMatch' => array(
'OriginId' => $originId,
)
)
),
),
),
// Update the "Qty" field of the first array element matched (if any)
//array( '$set' => array( 'Lot.$.Qty' => 'Updated' )),
array( '$set' => array( 'Lot.$.Movement.$.Qty' => $invqty )),
array('upsert' => true));
Please anyone help me to resolve this?
Using $addToSet is problematic in this case, because the following lot elements would be considered different:
{
"Qty" :0,
"ProductLot" : ObjectId("5462dbd9599e5c200e000003"),
"Product" : ObjectId("543ca7be4cf59d400c000004"),
"OriginId" : "266"
}
{
"Qty" :5,
"ProductLot" : ObjectId("5462dbd9599e5c200e000003"),
"Product" : ObjectId("543ca7be4cf59d400c000004"),
"OriginId" : "266"
}
The first element is likely what you would be adding (either with quantity 0 or 1), and the second element would be the same logical lot element, just with an incremented quantity. If the latter element already existed in the array, I imagine you'd like for your application to increment the quantity from 5 to 6 instead of adding the first element, which is essentially a duplicate.
We definitely need two updates here, but I would propose the following:
// Let's assume the following identifiers...
$inventoryId = new MongoId($_POST['inventoryid']);
$productLotId = new MongoId($invlotid);
$originId = new MongoId($_POST['id']);
$lotcontent = [ /* whatever this looks like */ ];
$result = $collection->update(
// Match an inventory without the specific ProductLot/OriginId element
[
'_id' => $inventoryId,
'Lot' => [
'$not' => [
'$elemMatch' => [
'ProductLot' => $productLotId,
'OriginId' => $originId,
],
],
],
],
// Append a new element to the Lot array field
[ '$push' => [ 'Lot' => $lotcontent ] ]
);
MongoCollection::update() will return a result document with an n field indicating the number of affected documents. Since we aren't using the multiple option and are also matching at most one document by _id, we can expect n to be either 0 or 1. If n was 0, we either couldn't find an inventory document with that _id or we found one but it already had a Lot element with the product and origin identifiers (i.e. our $elemMatch criteria matched something, invalidating our negation). If n was 1, that means we found the inventory document, it did not contain a matching Lot element, and we appended it (i.e. our job is done).
Assuming n was 0, we should issue another update and attempt to increment the quantity:
$result = $collection->update(
// Match an inventory with a specific ProductLot/OriginId element
[
'_id' => $inventoryId,
'Lot' => [
'$elemMatch' => [
'ProductLot' => $productLotId,
'OriginId' => $originId,
],
],
],
// Update the "Qty" field of the first array element matched (if any)
[ '$inc' => [ 'Lot.$.Qty' => 1 ] ]
);
Here, I'm using the $ positional update operator to access a specific array element that was matched in the criteria. This allows us to craft an $inc without worrying about the index of the matched element.
Again, we can check $result['n'] here. If it's still 0, then we can assume that no document matches our _id (a completely separate error). But if n is 1 at this point, we successfully incremented the quantity and our job is done.

Categories