PluginProbe
Tiered Pricing Table for WooCommerce / 7.1.5
Tiered Pricing Table for WooCommerce v7.1.5
8.0.2 7.1.7 7.1.5 7.1.4 7.1.1 6.5.0 6.4.0 6.1.0 trunk 1.0 1.1 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.2.0 2.2.1 2.2.2 2.2.3 2.3.0 2.3.1 2.3.2 2.3.3 All 91 releases
tier-pricing-table / src / Addons / AdvancedQuantityOptions / QuantityManager.php

QuantityManager.php in Tiered Pricing Table for WooCommerce 7.1.5, at src/Addons/AdvancedQuantityOptions/QuantityManager.php

265 lines 7.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php namespace TierPricingTable\Addons\AdvancedQuantityOptions;
2
3 use TierPricingTable\PriceManager;
4 use TierPricingTable\PricingRule;
5 use TierPricingTable\TierPricingTablePlugin;
6 use WC_Product;
7
8 class QuantityManager {
9
10 public function __construct() {
11
12 add_filter( 'tiered_pricing_table/tiered_pricing/last_tier_postfix',
13 function ( $postfix, $quantity, PricingRule $pricingRule ) {
14
15 if ( $pricingRule->data['maximum_quantity'] && $pricingRule->data['maximum_quantity'] <= $quantity ) {
16 return '';
17 }
18
19 return $postfix;
20 }, 10, 3 );
21
22 add_filter( 'tiered_pricing_table/price/pricing_rule', function ( PricingRule $pricingRule, $productId ) {
23 $pricingRule->data['maximum_quantity'] = DataProvider::getMaximumQuantity( $productId );
24 $pricingRule->data['group_of_quantity'] = DataProvider::getGroupOfQuantity( $productId );
25
26 return $pricingRule;
27 }, 1, 2 );
28
29 add_action( 'woocommerce_before_calculate_totals', function ( \WC_Cart $cart ) {
30
31 foreach ( $cart->get_cart_contents() as $cartItemKey => $cartItem ) {
32
33 if ( $cartItem['data'] instanceof WC_Product ) {
34
35 $productId = ! empty( $cartItem['variation_id'] ) ? $cartItem['variation_id'] : $cartItem['product_id'];
36
37 $pricingRule = PriceManager::getPricingRule( $productId );
38 $max = $pricingRule->data['maximum_quantity'] ?? null;
39 $groupOf = $pricingRule->data['group_of_quantity'] ?? null;
40
41 $cartItemQuantity = $this->getProductCartQuantity( $productId );
42
43 if ( $max ) {
44
45 $max = max( $groupOf, $max );
46
47 if ( $this->getProductCartQuantity( $productId ) > $max ) {
48 $cart->cart_contents[ $cartItemKey ]['quantity'] = $max;
49 // translators: %1$s: item name, %2$s: minimum quantity
50 wc_add_notice( sprintf( __( 'Maximum quantity for the %1$s is %2$d', 'tier-pricing-table' ),
51 $cartItem['data']->get_name(), $max ), 'error' );
52 }
53 }
54
55 if ( $groupOf ) {
56
57 if ( 0 !== $cartItemQuantity % $groupOf ) {
58 // translators: %s: quantity step
59 wc_add_notice( sprintf( __( 'Order quantity must be multiple of %s', 'tier-pricing-table' ),
60 $groupOf ), 'error' );
61
62 $cart->cart_contents[ $cartItemKey ]['quantity'] = ceil( $cartItemQuantity / $groupOf ) * $groupOf;
63 }
64 }
65 }
66 }
67 }, 10, 1 );
68
69 add_filter( 'woocommerce_quantity_input_args', function ( $args, $product ) {
70
71 if ( $product instanceof WC_Product && TierPricingTablePlugin::isSimpleProductSupported( $product ) ) {
72
73 $pricingRule = PriceManager::getPricingRule( $product->get_id() );
74
75 $max = $pricingRule->data['maximum_quantity'] ?? null;
76 $groupOf = $pricingRule->data['group_of_quantity'] ?? null;
77
78 if ( $max ) {
79
80 if ( ! is_cart() && ! is_checkout() ) {
81 $max = max( 1, $max - $this->getProductCartQuantity( $product->get_id() ) );
82 }
83
84 $max = max( $groupOf, $max );
85
86 $args['max_value'] = $max;
87 }
88
89 if ( $groupOf ) {
90 $args['step'] = $groupOf;
91 $args['min_value'] = max( $args['min_value'] ?? 1, $groupOf );
92 $args['value'] = max( $args['value'] ?? 1, $groupOf );
93 }
94 }
95
96 return $args;
97 }, 9999999, 2 );
98
99 add_filter( 'woocommerce_add_to_cart_validation', function ( $passed, $_productId, $qty, $variationId = null ) {
100
101 $productId = $variationId ? $variationId : $_productId;
102
103 // Do not show additional notices if there are already notices
104 if ( ! $passed ) {
105 return false;
106 }
107
108 $pricingRule = PriceManager::getPricingRule( $productId );
109
110 $max = $pricingRule->data['maximum_quantity'] ?? null;
111 $groupOf = $pricingRule->data['group_of_quantity'] ?? null;
112
113 if ( $max ) {
114
115 $max = max( $groupOf, $max );
116
117 if ( $qty + $this->getProductCartQuantity( $_productId ) > $max ) {
118
119 // translators: %s: maximum quantity
120 wc_add_notice( sprintf( __( 'Maximum order quantity for the product is %s', 'tier-pricing-table' ),
121 $max ), 'error' );
122
123 return false;
124 }
125 }
126
127 if ( $groupOf ) {
128
129 if ( 0 !== $qty % $groupOf ) {
130 // translators: %s: quantity step
131 wc_add_notice( sprintf( __( 'Order quantity must be multiple of %s', 'tier-pricing-table' ),
132 $groupOf ), 'error' );
133
134 return false;
135 }
136 }
137
138 return $passed;
139
140 }, 10, 4 );
141
142 add_action( 'wp_head', function () {
143 if ( is_product() ) {
144 ?>
145 <script>
146 jQuery(document).ready(function () {
147
148 let $quantity = jQuery('.single_variation_wrap').find('[name=quantity]');
149
150 jQuery(document).on('found_variation', function (e, variation) {
151
152 if (variation.step) {
153 $quantity.attr('step', variation.step);
154 $quantity.data('step', variation.step);
155 } else {
156 $quantity.attr('step', 1);
157 $quantity.data('step', 1);
158 }
159
160 if (variation.max_qty) {
161 $quantity.attr('max', variation.max_qty);
162 $quantity.data('max', variation.max_qty);
163 } else {
164 $quantity.removeAttr('max');
165 }
166 });
167
168 jQuery(document).on('reset_data', function () {
169 // Do not remove step attr - it can be used for some themes for +\- buttons
170 $quantity.attr('step', 1);
171 $quantity.data('step', 1);
172
173 $quantity.removeAttr('max');
174 });
175 });
176 </script>
177 <?php
178 }
179 } );
180
181 add_filter( 'woocommerce_update_cart_validation', function ( $passed, $cart_item_key, $values, $quantity ) {
182 $product = $values['data'] ?? null;
183
184 if ( ! ( $product instanceof WC_Product ) ) {
185 return $passed;
186 }
187
188 $pricingRule = PriceManager::getPricingRule( $product->get_id() );
189
190 $max = $pricingRule->data['maximum_quantity'] ? intval( $pricingRule->data['maximum_quantity'] ) : null;
191 $groupOf = $pricingRule->data['group_of_quantity'] ? intval( $pricingRule->data['group_of_quantity'] ) : null;
192
193 if ( $max ) {
194
195 if ( $quantity > $max ) {
196
197 // translators: %s: maximum quantity
198 wc_add_notice( sprintf( __( 'Maximum order quantity for the product is %s', 'tier-pricing-table' ),
199 $max ), 'error' );
200
201 return false;
202 }
203 }
204
205 if ( $groupOf ) {
206
207 if ( 0 !== $quantity % $groupOf ) {
208
209 // translators: %s: quantity step
210 wc_add_notice( sprintf( __( 'Order quantity must be multiple of %s', 'tier-pricing-table' ),
211 $groupOf ), 'error' );
212
213 return false;
214 }
215 }
216
217 return $passed;
218
219 }, 10, 4 );
220
221 add_filter( 'woocommerce_available_variation', function ( $variation ) {
222
223 $pricingRule = PriceManager::getPricingRule( $variation['variation_id'] );
224
225 $max = $pricingRule->data['maximum_quantity'] ?? null;
226 $groupOf = $pricingRule->data['group_of_quantity'] ?? null;
227
228 if ( $max ) {
229 $max = max( 1, $max - $this->getProductCartQuantity( $variation['variation_id'], true ) );
230
231 if ( $groupOf ) {
232 $max = max( $groupOf, $max );
233 }
234
235 $variation['max_qty'] = $max;
236 }
237
238 if ( $groupOf ) {
239 $variation['step'] = $groupOf;
240 $variation['min_qty'] = max( $variation['min_qty'], $groupOf );
241 $variation['qty_value'] = max( $variation['min_qty'], $groupOf );
242 }
243
244 return $variation;
245 }, 999 );
246 }
247
248 public function getProductCartQuantity( $productId, $isVariation = false ) {
249 $qty = 0;
250
251 if ( is_array( wc()->cart->cart_contents ) ) {
252 foreach ( wc()->cart->cart_contents as $cart_content ) {
253
254 $compare = $isVariation ? ( $cart_content['variation_id'] ?? false ) : $cart_content['product_id'];
255
256 if ( $compare == $productId ) {
257 $qty += $cart_content['quantity'];
258 }
259
260 }
261 }
262
263 return $qty;
264 }
265 }