Dynamické cenové pravidlá pre WooCommerce

Dynamické Cenové Pravidlá pre WooCommerce umožňuje nastaviť ceny na základe množstva priamo na úrovni produktu. S jednoduchým rozhraním môžete pridávať a spravovať cenové úrovne, ktoré sa automaticky prispôsobia pri rôznych množstvách v košíku. Podporuje aj variabilné produkty a je plne integrovaný s WooCommerce import/export funkciami.

PHP
/*
Plugin Name: Dynamic Quantity Pricing for WooCommerce
Description: Allows setting dynamic prices based on quantity at the product level.
Version: 1.2
Author: Ladislav Dubravský
Author url: https://prosimsi.sk
*/

if (!defined('ABSPATH')) {
    exit; // Exit if accessed directly
}

// Pridanie vlastných polí pre cenové pravidlá v produkte
function dqp_add_custom_pricing_fields() {
    global $post;

    echo '<div id="dynamic_pricing_fields_wrapper" style="padding-left: 15px">';
    echo '<h3>' . __('Dynamic Quantity Pricing', 'woocommerce') . '</h3>';
    echo '<div id="dynamic_pricing_fields">';
    echo '<div class="options_group">';

    $pricing_levels = get_post_meta($post->ID, '_pricing_levels', true);

    if (empty($pricing_levels)) {
        $pricing_levels = array(array('min_quantity' => '', 'price' => ''));
    }

    foreach ($pricing_levels as $index => $pricing_level) {
        echo '<div class="pricing_level" data-index="' . $index . '" style="align-items: center;margin-bottom: 10px">';
        echo '';
        echo '';
        echo '<button type="button" class="remove_pricing_level button" style="background-color: #ff4d4d;color: white;margin-right: 10px">×</button>';
        if ($index === count($pricing_levels) - 1) {
            echo '<button type="button" class="add_pricing_level button" style="background-color: #4CAF50;color: white">+</button>';
        }
        echo '</div>';
    }

    echo '</div>';
    echo '</div>';
    echo '</div>';

    // Pridanie JavaScriptu na dynamické pridávanie a odstraňovanie polí
    ?>

        jQuery(document).ready(function ($) {
            var index = ;

            function updateAddButton() {
                $('.add_pricing_level').remove();
                var newButton = '<button type="button" class="add_pricing_level button" style="background-color: #4CAF50;color: white;margin-left: 10px">+</button>';
                $('.options_group .pricing_level').last().append(newButton);
                $('.add_pricing_level').on('click', addPricingLevel);
            }

            function addPricingLevel() {
                var newIndex = index++;
                var newField = '<div class="pricing_level" data-index="' + newIndex + '" style="align-items: center;margin-bottom: 10px">' +
                    '<input type="number" class="short min_quantity" name="_min_quantity_' + newIndex + '" id="_min_quantity_' + newIndex + '" value="" placeholder="" step="1" min="0" style="width: 20%; margin-right: 10px;">' +
                    '<input type="number" class="short price" name="_price_' + newIndex + '" id="_price_' + newIndex + '" value="" placeholder="" step="0.01" min="0" style="width: 20%; margin-right: 10px;">' +
                    '<button type="button" class="remove_pricing_level button" style="background-color: #ff4d4d;color: white;margin-right: 10px">×</button>' +
                    '</div>';
                $('#dynamic_pricing_fields .options_group').append(newField);
                updateAddButton();
            }

            $(document).on('click', '.remove_pricing_level', function () {
                $(this).closest('.pricing_level').remove();
                if ($('.pricing_level').length === 0) {
                    addPricingLevel();
                } else {
                    updateAddButton();
                }
            });

            // Presuneme sekciu pod sekciu s triedou "_sale_price_field"
            $('#dynamic_pricing_fields_wrapper').insertAfter('.form-field._sale_price_field');

            updateAddButton();
        });

     $value) {
        if (strpos($key, '_min_quantity_') === 0) {
            $index = str_replace('_min_quantity_', '', $key);
            $pricing_levels[$index]['min_quantity'] = sanitize_text_field($value);
        }
        if (strpos($key, '_price_') === 0) {
            $index = str_replace('_price_', '', $key);
            $pricing_levels[$index]['price'] = sanitize_text_field($value);
        }
    }

    update_post_meta($post_id, '_pricing_levels', $pricing_levels);
}
add_action('woocommerce_process_product_meta', 'dqp_save_custom_pricing_fields');

// Úprava ceny na základe množstva v košíku
function dqp_adjust_cart_item_price($cart) {
    if (is_admin() && !defined('DOING_AJAX')) {
        return;
    }

    foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
        $product_id = $cart_item['product_id'];
        $quantity = $cart_item['quantity'];

        $pricing_levels = get_post_meta($product_id, '_pricing_levels', true);

        if (!empty($pricing_levels)) {
            usort($pricing_levels, function($a, $b) {
                return $b['min_quantity'] - $a['min_quantity'];
            });

            foreach ($pricing_levels as $pricing_level) {
                if ($quantity >= $pricing_level['min_quantity']) {
                    $cart_item['data']->set_price($pricing_level['price']);
                    break;
                }
            }
        }
    }
}
add_action('woocommerce_before_calculate_totals', 'dqp_adjust_cart_item_price');

// Zabezpečenie kompatibility s variabilnými produktmi
function dqp_variation_options_pricing($loop, $variation_data, $variation) {
    $pricing_levels = get_post_meta($variation->ID, '_pricing_levels', true);

    echo '<div id="dynamic_pricing_fields_wrapper_' . $loop . '" style="padding-left: 10px">';
    echo '<h3>' . __('Dynamic Quantity Pricing for Variation', 'woocommerce') . '</h3>';
    echo '<div id="dynamic_pricing_fields">';
    echo '<div class="options_group">';

    if (empty($pricing_levels)) {
        $pricing_levels = array(array('min_quantity' => '', 'price' => ''));
    }

    foreach ($pricing_levels as $index => $pricing_level) {
        echo '<div class="pricing_level" data-index="' . $index . '" style="align-items: center;margin-bottom: 10px">';
        echo '';
        echo '';
        echo '<button type="button" class="remove_pricing_level button" style="background-color: #ff4d4d;color: white;margin-right: 10px">×</button>';
        if ($index === count($pricing_levels) - 1) {
            echo '<button type="button" class="add_pricing_level button" style="background-color: #4CAF50;color: white">+</button>';
        }
        echo '</div>';
    }

    echo '</div>';
    echo '</div>';
    echo '</div>';

    // Pridanie JavaScriptu na dynamické pridávanie a odstraňovanie polí pre variácie
    ?>

        jQuery(document).ready(function ($) {
            var index = ;

            function updateAddButton() {
                $('.add_pricing_level').remove();
                var newButton = '<button type="button" class="add_pricing_level button" style="background-color: #4CAF50;color: white;margin-left: 10px">+</button>';
                $('.options_group .pricing_level').last().append(newButton);
                $('.add_pricing_level').on('click', addPricingLevel);
            }

            function addPricingLevel() {
                var newIndex = index++;
                var newField = '<div class="pricing_level" data-index="' + newIndex + '" style="align-items: center;margin-bottom: 10px">' +
                    '<input type="number" class="short min_quantity" name="variation_min_quantity_' + newIndex + '" id="variation_min_quantity_' + newIndex + '" value="" placeholder="" step="1" min="0" style="width: 20%; margin-right: 10px;">' +
                    '<input type="number" class="short price" name="variation_price_' + newIndex + '" id="variation_price_' + newIndex + '" value="" placeholder="" step="0.01" min="0" style="width: 20%; margin-right: 10px;">' +
                    '<button type="button" class="remove_pricing_level button" style="background-color: #ff4d4d;color: white;margin-right: 10px">×</button>' +
                    '</div>';
                $('#dynamic_pricing_fields_' + newIndex + ' .options_group').append(newField);
                updateAddButton();
            }

            $(document).on('click', '.remove_pricing_level', function () {
                $(this).closest('.pricing_level').remove();
                if ($('.pricing_level').length === 0) {
                    addPricingLevel();
                } else {
                    updateAddButton();
                }
            });

            updateAddButton();
        });

     $value) {
        if (strpos($key, 'variation_min_quantity_' . $i . '_') === 0) {
            $index = str_replace('variation_min_quantity_' . $i . '_', '', $key);
            $pricing_levels[$index]['min_quantity'] = sanitize_text_field($value);
        }
        if (strpos($key, 'variation_price_' . $i . '_') === 0) {
            $index = str_replace('variation_price_' . $i . '_', '', $key);
            $pricing_levels[$index]['price'] = sanitize_text_field($value);
        }
    }

    update_post_meta($variation_id, '_pricing_levels', $pricing_levels);
}
add_action('woocommerce_save_product_variation', 'dqp_save_variation_fields', 10, 2);

// Export vlastných polí pre produkty
function dqp_add_custom_fields_to_export($column_headers) {
    $column_headers['pricing_levels'] = __('Pricing Levels', 'woocommerce');
    return $column_headers;
}
add_filter('woocommerce_product_export_column_names', 'dqp_add_custom_fields_to_export');
add_filter('woocommerce_product_export_product_default_columns', 'dqp_add_custom_fields_to_export');

function dqp_export_custom_field($value, $product) {
    $pricing_levels = get_post_meta($product->get_id(), '_pricing_levels', true);
    if (!empty($pricing_levels)) {
        $pricing_levels_json = json_encode($pricing_levels);
        return $pricing_levels_json;
    }
    return $value;
}
add_filter('woocommerce_product_export_product_column_pricing_levels', 'dqp_export_custom_field', 10, 2);

// Import vlastných polí pre produkty
function dqp_import_custom_field($product, $data) {
    if (!empty($data['pricing_levels'])) {
        $pricing_levels = json_decode($data['pricing_levels'], true);
        update_post_meta($product->get_id(), '_pricing_levels', $pricing_levels);
    }
}
add_action('woocommerce_product_import_inserted_product_object', 'dqp_import_custom_field', 10, 2);