Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/demirdoven/creating-price-variants-without-attributes-or-variations-on-woocommerce-with-custom-code-easily

You can create your price calculator for products at Woocommerce with custom code easily.
https://github.com/demirdoven/creating-price-variants-without-attributes-or-variations-on-woocommerce-with-custom-code-easily

woocommerce woocommerce-plugin wordpress wordpress-plugin

Last synced: 3 months ago
JSON representation

You can create your price calculator for products at Woocommerce with custom code easily.

Awesome Lists containing this project

README

        

# Creating Price Variants Dynamically on WooCommerce without Attributes or Variations, with just Custom Code #
You can create your price calculator for products at Woocommerce with custom code easily. You don't need to use WooCommerce's attributes or variations.

### Description ###

I assume that I sell carpets online and I want to allow users to choose size and/or underlay for carpets. And the price should be changed by the user's choices.

And also I want users to be able to text their custom sizes.

### The source codes ###

You can copy all codes in the functions.php file in this repo and past them into your functions.php file.
I just explain the code blocks step by step after here.

#### Creating metabox for product add/edit page: ####
```
function carpet_details_metabox(){
add_meta_box( 'carpet_details_metabox_wrapper', 'Details', 'carpet_details_metabox_callback', 'product', 'normal', 'low' );
}
add_action( 'add_meta_boxes' , 'carpet_details_metabox' );

```

#### Metabox callback function: ####
(I've added styles and scripts here inside the function but you better include styles and scripts with wp_enqueue_scripts() and admin_enqueue_scripts() actions as external sources)
```
function carpet_details_metabox_callback( $post ){
wp_nonce_field( basename(__FILE__), 'sample_nonce' );
?>

ul.details_list li {
background: #ececec;
padding: 10px 23px 20px;
display: inline-block;
margin-bottom: 20px;
}
ul.details_list button {
background: #3F51B5;
color: #fff;
border: 0;
padding: 5px 15px;
display: inline-block;
border-radius: 2px;
margin-left: 2px;
cursor: pointer;
}
ul.details_list h2 {
font-size: 26px!important;
font-weight: bold!important;
padding-left: 1px!important;
}
ul.details_list table.sizes,
ul.details_list table.underlay_types {
width: 578px;
}
ul.details_list .sizes th,
ul.details_list .underlay_types th {
background: #484848;
color: #fff;
padding: 9px 10px;
text-align: center;
}
ul.details_list .sizes td,
ul.details_list .underlay_types td {
padding: 4px 10px;
background: #dedede;
}
ul.details_list .sizes td input,
.underlay_types td input {
width: 100%;
}
ul.details_list .remove {
cursor: pointer;
}



  • SIZES




    Label
    Width (m)
    Length (m)


    ID, 'size_data', true );
    if ( isset($sizes['label']) ){
    for( $i=0; $i


















    Add New


  • UNDERLAYS




    Label
    Price per m²


    ID, 'underlay_data', true );
    if (isset($underlay_types['label'])){
    for( $i=0; $i
















    Add New




jQuery(function ($){

$(document).on('click', '.add_new_button', function(){
var master = $(this).parent().find('.master').html();
$(this).siblings('table').append('<tr>'+master+'</tr>');
});
$(document).on('click', '.remove', function(){
$(this).parent().parent().remove();
});

});



.calculator_wrapper {
background: #f0f0f0;
padding: 8px;
display: inline-block;
}
table.calculator_table {
border: 0;
margin: 0;
width: auto;
}
.calculator_table tr {
border: 0;
}
.calculator_table td {
border: 0;
padding: .8em 1.2em .2em;
}
.calculator_table tr:last-child td {
padding: .8em 1.2em .8em;
}
.custom_size_inputs_wrapper > label {
background: #e7e7e7;
padding: 10px;
display: flex;
justify-content: space-between;
margin-bottom: 4px;
border-radius: 4px;
align-items: center;
}
.custom_size_inputs input {
line-height: 1;
height: 30px;
font-size: 16px;
width: 90px;
background-color: #fff;
}
.custom_size_inputs input:focus {
background-color: #fff;
}
table.calculator_table tr td select {
width: 100%;
}

get_id();
$sizes = get_post_meta( $product_id, 'size_data', true );
$underlay_types = get_post_meta( $product_id, 'underlay_data', true );

if ( $sizes && !empty($sizes) ){
echo '

';
echo '';
echo '';
echo 'Size';
echo '';
echo 'Choose size';
for( $i = 0; $i < count( $sizes['label'] ); $i++ ){
$width = (float)$sizes['width'][$i];
$length = (float)$sizes['length'][$i];
$meter_sq = $width * $length;
?>
( x )
Custom size';
echo '';
echo '';
?>




Width (m)



Length (m)



Total (㎡)





';
echo 'Underlay';
echo '';
echo 'No underlay';
for( $i = 0; $i < count( $underlay_types['label'] ); $i++ ){
$price = (float)$underlay_types['price'][$i];
?>

';
echo '';
}

echo '';
echo '
';
echo sprintf('
%s %s
', 'Total price:', ''.get_woocommerce_currency_symbol().'0');
}
?>

jQuery(function ($){
var productPrice = '<?php echo $product->get_price(); ?>';
var currency = '<?php echo get_woocommerce_currency_symbol(); ?>';

$('input[name="width_inp"], input[name="length_inp"]').on('keyup change', function(){
if( $('select[name="size_label"]').val() == 'custom_size' ){
var width = $('input[name="width_inp"]').val();
var length = $('input[name="length_inp"]').val();
if( width == '' ){
width = 1;
}
if( length == '' ){
length = 1;
}
width = parseFloat(width);
length = parseFloat(length);
var top = width*length;
$('input[name="total_m2"]').val(width*length);
var underlayPrice = 0;
var underlayPricePerSq = $('select[name="underlay_type"]').val();
if( underlayPricePerSq != '' ){
underlayPrice = width*length*parseFloat(underlayPricePerSq);
}
var newPrice = (width*length*productPrice)+underlayPrice;
$('#product_total_price .price').html( currency + newPrice.toFixed(2));
$('input[name="final_price"]').val(newPrice.toFixed(2));
$('input[name="size_total_metersq"]').val( width*length );
$('input[name="length"]').val( length );
$('input[name="width"]').val( width );
}
});

$('input[name="total_m2"]').on('keyup change', function(){
$('input[name="width_inp"]').val('');
$('input[name="length_inp"]').val('');
var topm2 = $('input[name="total_m2"]').val();
topm2 = parseFloat(topm2);
var underlayPrice = 0;
var underlayPricePerSq = $('select[name="underlay_type"]').val();
if( underlayPricePerSq != '' ){
underlayPrice = topm2*parseFloat(underlayPricePerSq);
}
var newPrice = (topm2*productPrice)+underlayPrice;
$('#product_total_price .price').html( currency + newPrice.toFixed(2));
$('input[name="final_price"]').val(newPrice.toFixed(2));
$('input[name="size_total_metersq"]').val( topm2 );
});

$('select[name="underlay_type"]').on('change', function(){
var total_m2 = '';
if( $('select[name="size_label"]').val() == 'custom_size' ){
total_m2 = $('input[name="total_m2"]').val();
}else{
total_m2 = $('select[name="size_label"]').val();
}
total_m2 = parseFloat(total_m2);
var underlayPrice = 0;
var underlayPricePerSq = $('select[name="underlay_type"]').val();
if( underlayPricePerSq != '' ){
underlayPrice = total_m2*parseFloat(underlayPricePerSq);
}
var newPrice = (total_m2*productPrice)+underlayPrice;
$('#product_total_price .price').html( currency + newPrice.toFixed(2));
$('input[name="final_price"]').val(newPrice.toFixed(2));
$('input[name="underlay"]').val($('select[name="underlay_type"] option:selected').text());

});

$('select[name="size_label"]').on('change', function(){
if( $(this).val() == 'custom_size' ){
$('.custom_size_inputs').show();
$('#product_total_price .price').html( currency + '0');
$('input[name="final_price"]').val(0);
}else if( $(this).val() == '0' ){
$('#product_total_price .price').html( currency + '0');
$('input[name="final_price"]').val(0);
}else{
$('.custom_size_inputs').hide();
$('input[name="width_inp"]').val('');
$('input[name="length_inp"]').val('');
$('input[name="total_m2"]').val('');
var total_m2 = $(this).val();
total_m2 = parseFloat(total_m2);
var underlayPrice = 0;
var underlayPricePerSq = $('select[name="underlay_type"]').val();
if( underlayPricePerSq != '' ){
underlayPrice = total_m2*parseFloat(underlayPricePerSq);
}
var newPrice = (total_m2*productPrice)+underlayPrice;
$('#product_total_price .price').html( currency + newPrice.toFixed(2));
$('input[name="final_price"]').val(newPrice.toFixed(2));
}

var selectedSizeLabel = $('select[name="size_label"] option:selected').text();
$('input[name="size_label"]').val(selectedSizeLabel);
$('input[name="size_total_metersq"]').val( total_m2 );
});
});

is_type('variable') ){
return $button;
}else{
return 'View product';
}
}
add_filter( 'woocommerce_loop_add_to_cart_link', 'modify_add_to_cart_button_for_shop_and_archive', 10, 2 );
```
#### Adding hidden inputs in order to pass parameters from single page to cart ####
```
function add_hidden_inputs_to_single_product() {
$inputs = array('final_price', 'size_label', 'width', 'length', 'size_total_metersq', 'underlay' );
for( $i=0; $i';
}
}
add_action( 'woocommerce_before_add_to_cart_button', 'add_hidden_inputs_to_single_product', 11, 0 );
```

#### Setting the total price of the product by user's choices ####
```
function set_the_final_price( $cart ) {
foreach ($cart->get_cart() as $cart_item){
if( isset($cart_item['final_price']) ){
$cart_item['data']->set_price($cart_item['final_price']);
}
}
}
add_action( 'woocommerce_before_calculate_totals', 'set_the_final_price', 30, 1 );
```

#### Passing values to cart by user's choices ####
```
function add_cart_item_data_from_values( $cart_item_meta, $product_id ) {

$custom_data = array();
$post_array = array('size_label', 'width', 'length', 'size_total_metersq', 'underlay' );

for( $i=0; $i 'Size',
'display' => $custom_data['size_label']
);
if( $custom_data['width'] != '' ){
$other_data[] = array(
'name' => 'Width',
'display' => $custom_data['width'].' m'
);
}
if( $custom_data['length'] != '' ){
$other_data[] = array(
'name' => 'Length',
'display' => $custom_data['length'].' m'
);
}
$other_data[] = array(
'name' => 'Total',
'display' => $custom_data['size_total_metersq'].' m2'
);
$other_data[] = array(
'name' => 'Underlay',
'display' => $custom_data['underlay']
);

}
return $other_data;
}
add_filter( 'woocommerce_get_item_data', 'display_custom_data_on_cart_and_checkout' , 25, 2 );
```

#### Finally we add custom values to the order items in order to display them on the order detail at admin panel and emails ####
```
function add_metadata_to_the_items_on_the_order( $item, $cart_item_key, $values, $order ) {
$custom_data = $values['custom_data'];

if( $custom_data && !empty($custom_data)){
foreach( $custom_data as $key=>$value ){
$label = $key;
if($key=='size_label'){
$label = 'Size';
}
if($key=='size_total_metersq'){
$label = 'Total (m2)';
}
if($key=='underlay'){
$label = 'Underlay';
}
if($key=='width'){
$label = 'Width (m)';
}
if($key=='length'){
$label = 'Length (m)';
}
$item->update_meta_data( $label, $value );
}
}
}
add_action( 'woocommerce_checkout_create_order_line_item', 'add_metadata_to_the_items_on_the_order', 20, 4 );
```

Note that the product price you already set on the product edit page, will be the price per square meter!