WooCommerce custom child products to variable products - php

I have some variable products (different 3-4 variations) with different prices. I want to add some simple products as child products (show as optional checkbox in front). I don't know how to manage that for adding to the cart.
For example let's assume I have a cellphone as main product and when user added it to it's cart it should see 3 sub product (child product) :
Handsfree (in three type of color)
Glass guard (in two type of color )
cell phone shield case ( just black)
as you can understand from above example I wanna to:
add all of this items as one product (includes handsfree, glass guard , cellphone case and cellphone itself ) and calculate it's price .I've read Add a checkbox on single product pages that adds an additional cost in Woocommerce and after that I have codes below to adding options in product edit page.
//custom product tab to woocommerce edit
function sm_wccpd_custom_product_tabs($tabs)
{
$tabs['sm_wcpa_extra_products'] = array(
'label' => __('Samanik Extra Products', 'sm-wcpa'),
'target' => 'sm_wc_extra_products_options',
'class' => array('show_if_variable'),
);
return $tabs;
}
add_filter('woocommerce_product_data_tabs', 'sm_wccpd_custom_product_tabs');
and here is tab content
function extra_products_options_product_tab_content()
{
global $post;
// Note the 'id' attribute needs to match the 'target' parameter set above
?>
<div id='sm_wc_extra_products_options' class='panel woocommerce_options_panel'><?php
?>
<div class='options_group'><?php
woocommerce_wp_checkbox(
[
'id' => '_has_extra_products',
'label' => __('has extra products', 'sm-wcpa'),
]);
woocommerce_wp_select(
[
'class' => 'multiselect attribute_values wc-enhanced-select',
'custom_attributes' => ['multiple' => 'multiple', 'style' => 'width:100% !importan;'],
'id' => '_sm_wcpa_product[]',
'label' => __('Extra Products to be add here', 'sm-wcpa'),
'value' => array_values(json_decode(get_post_meta($post->ID, '_sm_wcpa_product'), true)),
'options' => sm_wcpa_get_products_as_options(),//this is function that I pass Products as array like [product_id => product name]
]);
?></div>
</div><?php
}
// add_filter('woocommerce_product_data_tabs', 'extra_products_options_product_tab_content'); // WC 2.5 and below
add_filter('woocommerce_product_data_panels', 'extra_products_options_product_tab_content'); // WC 2.6 and up
also I can save the data and I think they are not necessary here.
now what I need to do is how to manage this in front. I mean show child products as checkbox, add price to parent price if checked, what about changing variables(those have different prices).
thanks for your patient to read my question.

Related

Update user repeater meta (ACF) with another user meta field value

My goal is to get a signed-in user to select a color( via front end form and saved in ACF user meta field group) that will be applied to another user meta field inside a repeater. The field must be the same for each row inside the repeater ( for front-end design reasons ). I am using ACF pro, and a plugin called ACF Front end admin (let's call it FEA from now on) for the front-end form. I'm pretty new to PHP and have referenced ACF & FEA's s documentation, which can be found below, spin up a custom function. I am currently running this through the code snippets plugin if this helps. I've run an error log and nothing related to this shows. Tried running this through wp-config and it crashes my site.
Front end admin documentation
ACF documentation - update sub field
ACF documentation - getting values from a user
Edit, Additional information:
ACF Field composition of 'button color' (color of the buttons that user wants displayed in front end, and saved as user meta):
acf_add_local_field_group(array(
'key' => 'group_60000aaa00000',
'title' => 'Color Selector',
'fields' => array(
array(
'key' => 'field_60000aaa00000',
'label' => 'Button color',
'name' => 'button_color',
'type' => 'color_picker',
Button color in repeater field that needs to updated based on the above mentioned 'button_color' meta value:
acf_add_local_field_group(array(
'key' => 'group_70000bbb00000',
'title' => 'front end user profile',
'fields' => array(
array(
'key' => 'field_70000bbb00000',
'label' => 'Quick Link selector',
'name' => 'quick_link_selector',
'type' => 'repeater',
),
array(
'key' => 'field_70000ccc00000',
'label' => 'repeater button color',
'name' => 'repeater_button_color',
'type' => 'text',
The title of the forum is: "QL color selector form" (created through the FEA plugin) and has a short code of [frontend_admin form="3030"] if this helps.
I'm running the following code with no luck and would really appreciate any help!
/// Hooks into any(?) form and does something
add_action('acf_frontend/save_user', 'retrieve_colors_2_update', 10, 2);
function retrieve_colors_2_update( $form, $user_id ) {
$user = get_user_by('ID',$user_id);
//get important fields
$btn_color = get_field('button_color', 'user_' .$user_id);
//// update a repeater loop (ACF)
if( have_rows('quick_link_selector', 'user_'.$user_id) ) {
$i = 0;
while( have_rows('quick_link_selector') ) {
the_row();
$i++;
update_sub_field('repeater_button_color', $btn_color );
}
}
}

Customizing checkout Postcode field into a custom drop-down menu

I am building a WooCommerce based store. I have a list of postcodes, each one has a different shipping cost attached through Shipping Zones (some provide free shipping, some have a flat rate).
When the customer goes to the checkout page, he needs to type his postcode number in the input field. Depending on postcode, an order preview will show different shipping total (free or flat rate).
Here's how the input field looks like in class-wc-countries.php:
public function get_default_address_fields() {
$fields = array(
'postcode' => array(
'label' => __( 'Postcode/ZIP', 'woocommerce' ),
'required' => true,
'class' => array( 'form-row-first', 'address-field' ),
'clear' => true,
'validate' => array( 'postcode' ),
'autocomplete' => 'postal-code',
),
);
However, what I want to do is to turn this field into a drop-down menu, so the customer could just select his postcode option rather than type it.
I managed to make it drop-down, but whenever I choose any option it doesn't seem to change shipping total as it would with input field.
Here's what I did:
public function get_default_address_fields() {
$fields = array(
'postcode' => array(
'label' => __( 'Postcode/ZIP', 'woocommerce' ),
'required' => true,
'class' => array( 'form-row-first', 'address-field' ),
'clear' => true,
'validate' => array( 'postcode' ),
'autocomplete' => 'postal-code',
'type' => 'select',
'options' => array(
'opt1' => "001122", "112200", "334400")
),
);
But this don't work.
Am I missing something?
How do I make these drop-down options change shipping total?
Thanks
This will answer very partially to your question, and just show you the way to customize checkout fields.
Overriding core files is not really something to do, as you will loose everithing each time Woocommerce is going to be updated and is not recommended.
To override checkout fields in a clean way, first you need to use a custom function hooked in one of that 2 filter hooks:
woocommerce_default_address_fields (when customizing billing and shipping address default fields)
woocommerce_checkout_fields (when customizing billing or shipping address fields and also others fields).
Related official documentation: Customizing checkout fields using actions and filters
So here I have chose the first hook, and I have corrected your post codes array. You will get that:
Here is that functional and tested code:
add_filter( 'woocommerce_default_address_fields' , 'custom_override_default_postcode_field' );
function custom_override_default_postcode_field( $address_fields ) {
// Your postcodes array
$postcode_array = array(
'opt1' => "001122",
'opt2' => "112200",
'opt3' => "334400"
);
$address_fields['postcode']['type'] = 'select';
$address_fields['postcode']['options'] = $postcode_array;
return $address_fields;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
As selecting a post-code is a live front-end event, you will need to use a complex javascript/ajax script with some remote php function to achieve what you want to do, and this is a real development... It also depends on your settings and is complex to handle as there is already some woocommerce ajax scripts operating in that checkout page.

Magento. Create attribute for grouped products only

I am trying to create attribute programmatically for all grouped products on my site. I am trying to create custom attribute set with group.
$oEntitySetup = $this;
$oEntitySetup->removeAttribute('catalog_product', 'grouped_base_price');
$skeletonID=$oEntitySetup->getAttributeSetId('catalog_product','Default');
$entityTypeId = Mage::getModel('catalog/product')
->getResource()
->getEntityType()
->getId(); //product entity type
$attributeSet = Mage::getModel('eav/entity_attribute_set')
->setEntityTypeId($entityTypeId)
->setAttributeSetName("oggy_attr_set");
$attributeSet->validate();
$attributeSet->save();
$attributeSet->initFromSkeleton($skeletonID)->save();
$data = array(
'attribute_set' => 'oggy_attr_set',
'group' => 'General',
'label' => 'Base Price',
'apply_to' => 'grouped',
'input' => 'text',
'visible' => true,
'visible_on_front' => true,
'required' => true,
'position' => 1,
'global' => 'Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL',
'note' => "Default Price For Configurable Products"
);
$oEntitySetup->addAttribute('catalog_product', 'grouped_base_price', $data);
$oEntitySetup->endSetup();
The problem is that attribute appears in all product types. But i need for grouped products only. What i am doing wrong ?
Assign created attribute to a particular "attribute set" and then while creating any group product - select this attribute set.
in your code $oEntitySetup have all products, you never take a specific group, and is sure you gift the new attribute to all products

adding quantity to related products in magento backend

I'm new to magento and trying to add quantity column to the grid in related products tab (edit product -> related products).
this is what I did:
overwrite related.php file:
Mage\Adminhtml\Block\Catalog\Product\Edit\Tab\Related.php
added to _prepareCollection() method this code:
$collection->joinField(
'qty',
'cataloginventory_stock_item',
'qty',
'product_id = entity_id',
'{{table}}.stock_id = 1',
'left'
);
and added to _prepareColumns() methods this code:
$this->addColumn('qty',
array(
'header' => Mage::helper('catalog')->__('QTY'),
'width' => 80,
'index' => 'qty'
Now I can see the new column but the quantity is float number (for example 100.00) and I can't filter results based on my new QTY column.
My questions:
is that all I need to add column or I have to do some thing else??
how to display QTY in integer format (for example 100 not 100.00)??
why I can't filter results based on the QTY??
any idea will be appreciated, Thanks in advance..
Quantity as integer format
'getter' => array($this, 'getFormattedQty')
public function getFormattedQty($row)
{
return intVal($row->getQtyOrdered());
}
To cover the three questions simply add the 'type' option with the value set to 'number' in the to _prepareColumns() method. Example Below:
$this->addColumn('qty', array(
'header' => Mage::helper('catalog')->__('QTY'),
'type' => 'number',
'width' => 80,
'index' => 'qty'
));
This will set the value as a whole number or integer rather than a float and will let you filter for a particular range.
I have used this myself to add the QTY to the Associated Products grid.

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