Plugin Directory

Changeset 3379390


Ignore:
Timestamp:
10/16/2025 10:56:15 AM (6 months ago)
Author:
thaxam
Message:

version 1.0.25

Location:
custom-customer-pricing-for-woocommerce/trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • custom-customer-pricing-for-woocommerce/trunk/README.md

    r3358463 r3379390  
    1515**woocommerce requires at least:** 10.0
    1616**woocommerce tested up to:** 10.1
    17 **Stable tag:** 1.0.22
     17**Stable tag:** 1.0.25
    1818**License:** GPL-2.0-or-later
    1919**License URI:** https://www.gnu.org/licenses/gpl-2.0.html
     
    9595## Changelog
    9696
     97### 1.0.25
     98- Tweak: Updated version number and readme files.
     99
     100### 1.0.24
     101- Tweak: Updated version number and readme files.
     102
     103### 1.0.23
     104- Tweak: Updated version number and readme files.
     105
    97106### 1.0.22
    98107- Tweak: Updated version number and readme files.
  • custom-customer-pricing-for-woocommerce/trunk/custom-customer-pricing-for-woocommerce.php

    r3358462 r3379390  
    44Plugin URI: https://www.thaxam.no/docs/
    55Description: Custom pricing and discount plugin for WooCommerce customers with Ultimate Members compatibility.
    6 Version: 1.0.22
     6Version: 1.0.25
    77Author: Thomas Amundsen
    88
     
    3636final class Custom_Customer_Pricing {
    3737
    38     const VERSION = '1.0.22';
     38    const VERSION = '1.0.25';
    3939    private static $instance = null;
    4040
     
    686686                <button id="thaxamccp-cleanup-db-btn" class="button" style="margin-left: 10px;"><?php esc_html_e( 'Cleanup Database', 'custom-customer-pricing-for-woocommerce' ); ?></button>
    687687                <div id="thaxamccp-settings-log" style="margin-top:20px; font-style: italic;"></div>
     688
     689                <?php if (current_user_can('administrator')) : ?>
     690                <h2><?php esc_html_e( 'Access Control', 'custom-customer-pricing-for-woocommerce' ); ?></h2>
     691                <label><?php esc_html_e( 'User Roles with Plugin Access', 'custom-customer-pricing-for-woocommerce' ); ?></label>
     692                <br/>
     693                <?php
     694                $roles = wp_roles()->get_names();
     695                unset($roles['administrator']);
     696                $access_roles = get_option('thaxamccp_access_roles', array('shop_manager', 'customer'));
     697                ?>
     698                <select multiple id="thaxamccp-access-roles" style="width: 300px; height: 100px;">
     699                    <?php foreach ($roles as $role_key => $role_name) : ?>
     700                        <option value="<?php echo esc_attr($role_key); ?>" <?php selected(in_array($role_key, $access_roles)); ?>><?php echo esc_html($role_name); ?></option>
     701                    <?php endforeach; ?>
     702                </select>
     703                <br/>
     704                <button id="thaxamccp-save-access-roles"><?php esc_html_e( 'Save Access Roles', 'custom-customer-pricing-for-woocommerce' ); ?></button>
     705                <?php endif; ?>
    688706            </div>
    689707            <div id="thaxamccp-usage-instructions" style="flex: 1; max-width: 30%; overflow-y: auto; height: 100vh; padding-left: 20px; border-left: 1px solid #ccc;">
     
    807825        // Add filter for displaying custom prices on shop and product pages
    808826        add_filter('woocommerce_get_price_html', array($this, 'filter_product_price_html'), 20, 2);
    809 
    810         add_action('woocommerce_cart_calculate_fees', array($this, 'apply_global_percentage_discount'));
    811827    }
    812828
     
    835851        // Shop pages will be handled by JavaScript with the modern tooltip
    836852        if ($minimum_requirement > 0 && is_singular('product')) {
     853            $original_price = $product->get_price();
     854            $normal_net_price = $original_price * (1 - $global_discount / 100);
     855            $custom_net_price = $original_price * (1 - $custom_discount / 100);
    837856            $message = sprintf(
    838                 /* translators: %1$s: global discount percentage, %2$s: custom discount percentage, %3$s: minimum quantity required */
    839                 __('Discount: %1$s%%. Minimum Requirement to get %2$s%% is %3$s', 'custom-customer-pricing-for-woocommerce'),
     857                /* translators: %1$s: global discount percentage, %2$s: normal net price, %3$s: minimum quantity, %4$s: custom discount percentage, %5$s: custom net price */
     858                __('Normal discount: %1$s%% (Net Price: %2$s)<br>Buy minimum %3$s to get %4$s%% discount (Net Price: %5$s)', 'custom-customer-pricing-for-woocommerce'),
    840859                $global_discount,
     860                wc_price($normal_net_price),
     861                $minimum_requirement,
    841862                $custom_discount,
    842                 $minimum_requirement
     863                wc_price($custom_net_price)
    843864            );
    844             $price_html .= '<div class="thaxamccp-minimum-requirement-message" style="display: block; margin: 10px 0 0 0; padding: 6px 12px; border-radius: 6px; background-color: #fff3cd; border: 1px solid #ffeaa7; color: #856404; font-size: 14px; line-height: 1.4;">' . esc_html($message) . '</div>';
     865            $price_html .= '<div class="thaxamccp-minimum-requirement-message" style="display: block; margin: 10px 0 10px 0; padding: 6px 12px; border-radius: 6px; color: #856404; font-size: 14px; line-height: 1.4;">' . $message . '</div>';
    845866        }
    846867
     
    862883}
    863884
    864 public function apply_global_percentage_discount() {
    865     if (!is_admin() && is_user_logged_in()) {
    866         $global_discount = floatval(get_option('thaxamccp_global_percentage_discount', 0));
    867         if ($global_discount > 0) {
    868             $cart = WC()->cart;
    869             if (!$cart) {
    870                 return;
    871             }
    872 
    873             $discount_total = 0;
    874 
    875             foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
    876                 $product = $cart_item['data'];
    877                 $quantity = $cart_item['quantity'];
    878                 $price = $product->get_price();
    879 
    880                 $user_id = get_current_user_id();
    881                 $product_id = $product->get_id();
    882                 $variation_id = 0;
    883                 if ($product->is_type('variation')) {
    884                     $variation_id = $product_id;
    885                     $product_id = $product->get_parent_id();
    886                 }
    887                 $custom_price_data = $this->get_cached_custom_price_data($user_id, $product_id, $variation_id);
    888 
    889                 $apply_global = false;
    890                 if (!$custom_price_data || empty($custom_price_data['custom_discount'])) {
    891                     $apply_global = true;
    892                 }
    893 
    894                 if ($apply_global) {
    895                     $line_discount = ($price * $quantity) * ($global_discount / 100);
    896                     $discount_total += $line_discount;
    897                 }
    898             }
    899 
    900             if ($discount_total > 0) {
    901                 /* translators: %1$s: Global discount percentage value */
    902                 $label = sprintf(
    903                     __('Global Percentage Discount (%1$s%%)', 'custom-customer-pricing-for-woocommerce'),
    904                     $global_discount
    905                 );
    906                 $cart->add_fee($label, -$discount_total);
    907             }
    908         }
    909     }
    910 }
     885
    911886
    912887    public function filter_product_price($price, $product) {
     
    940915            $this->log_error("User ID: $user_id, Product ID: {$product_id}, Variation ID: {$variation_id}, Custom Price: {$custom_price_data['custom_price']}");
    941916            return $custom_price_data['custom_price'];
     917        }
     918
     919        // If no custom data for variation, check for parent product data
     920        if ($variation_id > 0) {
     921            $parent_custom_price_data = $this->get_cached_custom_price_data($user_id, $product_id, 0);
     922            if ($parent_custom_price_data) {
     923                // Log the inherited custom price being returned
     924                $this->log_error("User ID: $user_id, Product ID: {$product_id}, Variation ID: {$variation_id}, Inherited Custom Price: {$parent_custom_price_data['custom_price']}");
     925                return $parent_custom_price_data['custom_price'];
     926            }
    942927        }
    943928
  • custom-customer-pricing-for-woocommerce/trunk/includes/cart-minimum-requirements.php

    r3358460 r3379390  
    2828            $global_discount = floatval(get_option('thaxamccp_global_percentage_discount', 0));
    2929            $cart = WC()->cart;
    30            
     30
    3131            if (!$cart) {
    3232                return;
     
    3535            $discount_total = 0;
    3636            $custom_discount_applied = false;
     37
     38            // Group cart items by parent product to handle variations as one product
     39            $grouped_items = array();
    3740
    3841            foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
     
    4043                $quantity = $cart_item['quantity'];
    4144                $product_id = $product->get_id();
    42                 $variation_id = $product->is_type('variation') ? $product_id : 0;
    43                
    44                 // Get custom price data
     45                $parent_id = $product->is_type('variation') ? $product->get_parent_id() : $product_id;
     46
     47                if (!isset($grouped_items[$parent_id])) {
     48                    $grouped_items[$parent_id] = array(
     49                        'items' => array(),
     50                        'total_quantity' => 0,
     51                        'custom_price_data' => null
     52                    );
     53                }
     54
     55                $grouped_items[$parent_id]['items'][] = $cart_item;
     56                $grouped_items[$parent_id]['total_quantity'] += $quantity;
     57
     58                // Get custom price data for the parent/variation
    4559                $custom_price_data = $this->get_custom_price_data($cart_item);
    46                
     60                if ($custom_price_data && !$grouped_items[$parent_id]['custom_price_data']) {
     61                    $grouped_items[$parent_id]['custom_price_data'] = $custom_price_data;
     62                }
     63            }
     64
     65            // Process each grouped product
     66            foreach ($grouped_items as $parent_id => $group) {
     67                $total_quantity = $group['total_quantity'];
     68                $custom_price_data = $group['custom_price_data'];
     69
    4770                if ($custom_price_data && $custom_price_data['minimum_requirement'] > 0) {
    48                     // Check if minimum requirement is met
    49                     if ($quantity < $custom_price_data['minimum_requirement']) {
     71                    // Check if minimum requirement is met for the total quantity of variations
     72                    if ($total_quantity < $custom_price_data['minimum_requirement']) {
    5073                        // Apply global discount instead of custom discount
    51                         $price = $product->get_price();
    52                         $line_discount = ($price * $quantity) * ($global_discount / 100);
    53                         $discount_total += $line_discount;
     74                        foreach ($group['items'] as $cart_item) {
     75                            $product = $cart_item['data'];
     76                            $quantity = $cart_item['quantity'];
     77                            $price = $product->get_price();
     78                            $line_discount = ($price * $quantity) * ($global_discount / 100);
     79                            $discount_total += $line_discount;
     80                        }
    5481                    } else {
    5582                        // Apply custom discount
    56                         $price = $product->get_price();
    57                         $line_discount = ($price * $quantity) * ($custom_price_data['custom_discount'] / 100);
    58                         $discount_total += $line_discount;
     83                        foreach ($group['items'] as $cart_item) {
     84                            $product = $cart_item['data'];
     85                            $quantity = $cart_item['quantity'];
     86                            $price = $product->get_price();
     87                            $line_discount = ($price * $quantity) * ($custom_price_data['custom_discount'] / 100);
     88                            $discount_total += $line_discount;
     89                        }
    5990                        $custom_discount_applied = true;
    6091                    }
    6192                } else {
    6293                    // Apply global discount
    63                     $price = $product->get_price();
    64                     $line_discount = ($price * $quantity) * ($global_discount / 100);
    65                     $discount_total += $line_discount;
     94                    foreach ($group['items'] as $cart_item) {
     95                        $product = $cart_item['data'];
     96                        $quantity = $cart_item['quantity'];
     97                        $price = $product->get_price();
     98                        $line_discount = ($price * $quantity) * ($global_discount / 100);
     99                        $discount_total += $line_discount;
     100                    }
    66101                }
    67102            }
    68103
    69104            if ($discount_total > 0) {
    70                 $label = $custom_discount_applied ? 
    71                     __('Custom Discount Applied', 'custom-customer-pricing-for-woocommerce') : 
     105                $label = $custom_discount_applied ?
     106                    __('Custom Discount Applied', 'custom-customer-pricing-for-woocommerce') :
    72107                    __('Global Discount Applied', 'custom-customer-pricing-for-woocommerce');
    73108                $cart->add_fee($label, -$discount_total);
     
    86121        $user_id = get_current_user_id();
    87122        $warnings = array();
     123
     124        // Group cart items by parent product to handle variations as one product
     125        $grouped_items = array();
    88126
    89127        foreach (WC()->cart->get_cart() as $cart_item) {
     
    91129            $quantity = $cart_item['quantity'];
    92130            $product_id = $product->get_id();
    93             $variation_id = $product->is_type('variation') ? $product_id : 0;
    94            
     131            $parent_id = $product->is_type('variation') ? $product->get_parent_id() : $product_id;
     132
     133            if (!isset($grouped_items[$parent_id])) {
     134                $grouped_items[$parent_id] = array(
     135                    'items' => array(),
     136                    'total_quantity' => 0,
     137                    'custom_price_data' => null,
     138                    'product_name' => $product->get_name()
     139                );
     140            }
     141
     142            $grouped_items[$parent_id]['items'][] = $cart_item;
     143            $grouped_items[$parent_id]['total_quantity'] += $quantity;
     144
     145            // Get custom price data for the parent/variation
    95146            $custom_price_data = $this->get_custom_price_data($cart_item);
    96            
    97             if ($custom_price_data && $custom_price_data['minimum_requirement'] > 0 && $quantity < $custom_price_data['minimum_requirement']) {
     147            if ($custom_price_data && !$grouped_items[$parent_id]['custom_price_data']) {
     148                $grouped_items[$parent_id]['custom_price_data'] = $custom_price_data;
     149            }
     150        }
     151
     152        // Check minimum requirements for each grouped product
     153        foreach ($grouped_items as $parent_id => $group) {
     154            $total_quantity = $group['total_quantity'];
     155            $custom_price_data = $group['custom_price_data'];
     156            $product_name = $group['product_name'];
     157
     158            if ($custom_price_data && $custom_price_data['minimum_requirement'] > 0 && $total_quantity < $custom_price_data['minimum_requirement']) {
    98159                $warnings[] = sprintf(
    99160                    /* translators: 1: Minimum quantity required, 2: Product name */
    100161                    __('Minimum quantity of %1$d required for %2$s to get custom discount.', 'custom-customer-pricing-for-woocommerce'),
    101162                    $custom_price_data['minimum_requirement'],
    102                     $product->get_name()
     163                    $product_name
    103164                );
    104165            }
  • custom-customer-pricing-for-woocommerce/trunk/languages/custom-customer-pricing-for-woocommerce.pot

    r3358459 r3379390  
    302302
    303303#: custom-customer-pricing-for-woocommerce.php:736
    304 msgid "Discount: %1$s%%. Minimum Requirement to get %2$s%% is %3$s"
     304msgid "Normal discount: %1$s%% (Net Price: %2$s)<br>Buy minimum %3$s to get %4$s%% discount (Net Price: %5$s)"
    305305msgstr ""
    306306
  • custom-customer-pricing-for-woocommerce/trunk/readme.txt

    r3358461 r3379390  
    33Contributors: thaxam
    44Donate link: https://paypal.me/thaxam
    5 Tags: woocommerce, pricing, custom discount, custom pricing, minimum requirement
     5Tags: prices, discount, minimum quantity, user, custom
    66Requires at least: 5.8
    77Tested up to: 6.8
    88Requires PHP: 7.4
    9 Stable tag: 1.0.22
     9Stable tag: 1.0.25
    1010License: GPL-2.0-or-later
    1111License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    8888== Changelog ==
    8989
     90= 1.0.25 =
     91* Tweak: Updated version number and readme files.
     92* Fixed: Issue where discount was calculate twice.
     93
     94= 1.0.24 =
     95* Tweak: Updated version number and readme files.
     96
     97= 1.0.23 =
     98* Tweak: Updated version number and readme files.
     99* Updated Minimum requirement warning text and formatting.
     100* Various small fixes
     101
    90102= 1.0.22 =
    91103* Tweak: Updated version number and readme files.
Note: See TracChangeset for help on using the changeset viewer.