PluginProbe
Tiered Pricing Table for WooCommerce / 7.1.1
Tiered Pricing Table for WooCommerce v7.1.1
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 / TieredPricingCart / TieredPricingCartService.php

TieredPricingCartService.php in Tiered Pricing Table for WooCommerce 7.1.1, at src/Addons/TieredPricingCart/TieredPricingCartService.php

219 lines 8.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace TierPricingTable\Addons\TieredPricingCart;
4
5 /*
6 * Class TieredPricingCartService
7 *
8 * Service modifies product's price in the cart based on quantity and tiered pricing rules
9 *
10 * @package TierPricingTable\Addons\TieredPricingCart
11 */
12 use TierPricingTable\CalculationLogic;
13 use TierPricingTable\Core\ServiceContainerTrait;
14 use TierPricingTable\PriceManager;
15 use WC_Product;
16 use WC_Cart;
17 class TieredPricingCartService {
18 use ServiceContainerTrait;
19 protected $originalPrices = [];
20
21 public function __construct() {
22 add_action(
23 'woocommerce_before_calculate_totals',
24 array($this, 'calculateTieredPricingInCart'),
25 99999,
26 3
27 );
28 add_action(
29 'woocommerce_before_mini_cart_contents',
30 array($this, 'triggerMiniCartUpdate'),
31 9999,
32 3
33 );
34 add_filter(
35 'woocommerce_cart_item_price',
36 array($this, 'calculateCartItemPrice'),
37 999,
38 2
39 );
40 add_filter(
41 'woocommerce_cart_item_subtotal',
42 array($this, 'modifyCartItemSubtotal'),
43 999,
44 3
45 );
46 }
47
48 public function modifyCartItemSubtotal( $subtotal, $cartItem, $cartItemKey ) {
49 $newPrice = $this->getCartItemPrice( $cartItem, $cartItemKey );
50 if ( false === $newPrice ) {
51 return $subtotal;
52 }
53 $recalculateCartItemSubtotal = apply_filters(
54 'tiered_pricing_table/cart/recalculate_cart_item_subtotal',
55 true,
56 $cartItem,
57 $cartItemKey,
58 $subtotal
59 );
60 if ( !$recalculateCartItemSubtotal ) {
61 return $subtotal;
62 }
63 $considerSalePriceAsDiscount = $this->getContainer()->getSettings()->get( 'consider_sale_price_as_discount_in_cart', 'no' ) === 'yes';
64 $considerSalePriceAsDiscount = apply_filters(
65 'tiered_pricing_table/cart/subtotal/consider_sale_price_as_discount',
66 $considerSalePriceAsDiscount,
67 $cartItem,
68 $cartItemKey
69 );
70 // Reset product instance because prices is already modified in the "woocommerce_before_calculate_totals" hook.
71 // We will not be able to get the original price
72 $product = wc_get_product( $cartItem['data']->get_id() );
73 if ( $product->is_taxable() ) {
74 if ( wc()->cart->display_prices_including_tax() ) {
75 $originalCartItemPrice = wc_get_price_including_tax( $product, array(
76 'qty' => $cartItem['quantity'],
77 'price' => ( $considerSalePriceAsDiscount ? $product->get_regular_price() : $product->get_price() ),
78 ) );
79 $newCartItemPrice = wc_get_price_including_tax( $product, array(
80 'qty' => $cartItem['quantity'],
81 'price' => $newPrice,
82 ) );
83 $originalProductSubtotal = wc_price( $originalCartItemPrice );
84 $newProductSubtotal = wc_price( $newCartItemPrice );
85 if ( !wc_prices_include_tax() && wc()->cart->get_subtotal_tax() > 0 ) {
86 $newProductSubtotal .= ' <small class="tax_label">' . WC()->countries->inc_tax_or_vat() . '</small>';
87 }
88 } else {
89 $originalCartItemPrice = wc_get_price_excluding_tax( $product, array(
90 'qty' => $cartItem['quantity'],
91 'price' => ( $considerSalePriceAsDiscount ? $product->get_regular_price() : $product->get_price() ),
92 ) );
93 $newCartItemPrice = wc_get_price_excluding_tax( $product, array(
94 'qty' => $cartItem['quantity'],
95 'price' => $newPrice,
96 ) );
97 $originalProductSubtotal = wc_price( $originalCartItemPrice );
98 $newProductSubtotal = wc_price( $newCartItemPrice );
99 if ( wc_prices_include_tax() && wc()->cart->get_subtotal_tax() > 0 ) {
100 $newProductSubtotal .= ' <small class="tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>';
101 }
102 }
103 } else {
104 $_originalItemPrice = ( $considerSalePriceAsDiscount ? $product->get_regular_price() : $product->get_price() );
105 $originalCartItemPrice = (float) $_originalItemPrice * (float) $cartItem['quantity'];
106 $newCartItemPrice = (float) $newPrice * (float) $cartItem['quantity'];
107 $originalProductSubtotal = wc_price( $originalCartItemPrice );
108 $newProductSubtotal = wc_price( $newCartItemPrice );
109 }
110 return $newProductSubtotal;
111 }
112
113 public function getCartItemPrice( $cartItem, $cartItemKey, $cart = null ) {
114 $cart = ( $cart instanceof WC_Cart ? $cart : wc()->cart );
115 if ( !$cart instanceof WC_Cart ) {
116 return false;
117 }
118 $calculateTieredPriceForItem = apply_filters(
119 'tiered_pricing_table/cart/need_price_recalculation',
120 true,
121 $cartItem,
122 $cart
123 );
124 if ( !$calculateTieredPriceForItem ) {
125 return false;
126 }
127 if ( empty( $cartItem['data'] ) || !$cartItem['data'] instanceof WC_Product ) {
128 return false;
129 }
130 $pricingRule = PriceManager::getPricingRule( $cartItem['data']->get_id() );
131 $totalQuantity = $this->getTotalProductCount( $cartItem );
132 $newPrice = $pricingRule->getTierPrice( $totalQuantity, false, 'cart' );
133 return apply_filters(
134 'tiered_pricing_table/cart/product_cart_price',
135 $newPrice,
136 $cartItem,
137 $cartItemKey,
138 $totalQuantity
139 );
140 }
141
142 /**
143 * Calculate price by quantity rules
144 *
145 * @param WC_Cart $cart
146 */
147 public function calculateTieredPricingInCart( WC_Cart $cart ) {
148 if ( !empty( $cart->get_cart_contents() ) ) {
149 foreach ( $cart->get_cart_contents() as $key => $cartItem ) {
150 $newPrice = $this->getCartItemPrice( $cartItem, $key, $cart );
151 if ( false !== $newPrice ) {
152 if ( !isset( $this->originalPrices[$key] ) ) {
153 $this->originalPrices[$key] = $cartItem['data']->get_price();
154 }
155 $cartItem['data']->set_price( $newPrice );
156 $cartItem['data']->add_meta_data( 'tiered_pricing_cart_price_calculated', 'yes' );
157 } else {
158 if ( isset( $this->originalPrices[$key] ) ) {
159 $cartItem['data']->set_price( $this->originalPrices[$key] );
160 }
161 }
162 // Update tiered pricing data
163 $cart->cart_contents[$key]['tiered_pricing_data'] = array(
164 'total_item_quantity' => $this->getTotalProductCount( $cartItem ),
165 );
166 }
167 }
168 }
169
170 /**
171 * Calculate price in mini cart
172 *
173 * @param string $price
174 * @param array $cartItem
175 *
176 * @return string
177 */
178 public function calculateCartItemPrice( $price, $cartItem ) {
179 $calculateTieredPriceForItem = apply_filters( 'tiered_pricing_table/cart/need_price_recalculation/item', true, $cartItem );
180 if ( $cartItem['data'] instanceof WC_Product && $calculateTieredPriceForItem ) {
181 $product = wc_get_product( $cartItem['data']->get_id() );
182 $pricingRule = PriceManager::getPricingRule( $cartItem['data']->get_id() );
183 $newPrice = $pricingRule->getTierPrice( $this->getTotalProductCount( $cartItem ), true, 'cart' );
184 $newPrice = apply_filters( 'tiered_pricing_table/cart/product_cart_price/item', $newPrice, $cartItem );
185 if ( false !== $newPrice ) {
186 return wc_price( $newPrice );
187 }
188 }
189 return $price;
190 }
191
192 public function triggerMiniCartUpdate() {
193 $cart = wc()->cart;
194 $cart->calculate_totals();
195 }
196
197 /**
198 * Get total product count depends on user's settings
199 *
200 * @param ?array $cartItem
201 *
202 * @return int
203 */
204 public function getTotalProductCount( ?array $cartItem ) : int {
205 if ( CalculationLogic::considerProductVariationAsOneProduct() ) {
206 $count = 0;
207 foreach ( wc()->cart->cart_contents as $cart_content ) {
208 if ( $cart_content['product_id'] == $cartItem['product_id'] ) {
209 $count += $cart_content['quantity'];
210 }
211 }
212 } else {
213 $count = $cartItem['quantity'];
214 }
215 return (int) apply_filters( 'tiered_pricing_table/cart/total_product_count', $count, $cartItem );
216 }
217
218 }
219