PluginProbe
Discount Rules for WooCommerce – Disco | Dynamic Pricing, Conditions, Bulk, Bundle, BOGO / 1.2.18
Discount Rules for WooCommerce – Disco | Dynamic Pricing, Conditions, Bulk, Bundle, BOGO v1.2.18
1.4.15 1.4.14 1.4.13 1.4.12 1.4.11 1.4.10 1.4.9 1.4.8 1.4.7 1.4.6 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.3.54 1.3.53 1.3.52 1.3.51 1.3.50 1.3.49 1.3.48 1.3.47 1.3.46 All 178 releases
disco / app / Disco.php

Disco.php in Discount Rules for WooCommerce – Disco | Dynamic Pricing, Conditions, Bulk, Bundle, BOGO 1.2.18, at app/Disco.php

287 lines 7.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Disco Class File.
4 *
5 * @package Disco
6 * @subpackage \App\Disco.php
7 * @since 1.0.0
8 */
9
10 namespace Disco\App;
11
12 use Disco\App\Calc\CalcFactory;
13 use Disco\App\Features\UserLimit;
14
15 /**
16 * Class Disco
17 *
18 * @package Disco
19 * @subpackage \App
20 * @author Ohidul Islam <wahid0003@gmail.com>
21 * @link https://webappick.com
22 * @license https://opensource.org/licenses/gpl-license.php GNU Public License
23 * @category Discount
24 */
25 class Disco {
26
27 use \Disco\App\Intents\IntentHelper;
28
29 /**
30 * @var array $intents Intents.
31 */
32 private $intents;
33
34 /**
35 * @var int $applied_campaign_id Applied Campaign.
36 */
37 private $applied_campaign_id;
38
39
40 /**
41 * Apply discount to product.
42 *
43 * @param float $price Product Price.
44 * @param \WC_Product $product Product Object.
45 * @return float Product Price.
46 * @throws \Exception If setting is not found.
47 */
48 public function get_product_discounted_price( $price, $product ) {//phpcs:ignore
49 if ( $product instanceof \WC_Product ) {
50 // Init product base intents and exclude cart-based intents.
51 $this->intents = $this->prepare_intents( array( 'Product' ) );
52
53 if ( ! $product->is_type( 'variable' ) ) {
54 $price = CalcFactory::get_product_price( $product );
55 }
56
57 // If no intent is available, return the original price.
58 if ( empty( $this->intents ) ) {
59 return $price;
60 }
61
62 $discounts = array();
63
64 $prev_discount = PHP_INT_MAX;
65
66 // Foreach intent, apply the discount.
67 foreach ( $this->intents as $intent ) {
68 /**
69 * Get a discount limit form campaign.
70 *
71 * Compare with total product meta and apply discount
72 */
73 $discount_limit = $intent->campaign->discount_max_user;
74 $total_applied_campaign = ( new UserLimit )->disco_get_total_applied_campaign( $intent->campaign->id );
75
76 if (
77 ! empty( $discount_limit )
78 && (
79 $discount_limit >= 0
80 && $total_applied_campaign >= $discount_limit
81 )
82 ) {
83 continue;
84 }
85
86 $discount = $intent->get_discounts( (float) $price, $product );
87
88 if ( empty( $discount ) ) {
89 continue;
90 }
91
92 // Get applied discount campaign.
93 if ( $discount > 0 && $prev_discount > $discount ) {
94 $this->applied_campaign_id = $intent->campaign->id;
95 $prev_discount = $discount;
96 }
97
98 $discounts[] = $discount;
99 }
100
101 // If no discount is applied, return the original price.
102 if ( empty( $discounts ) ) {
103 return $price;
104 }
105
106 $discount_type = $intent->campaign->discount_rules[0]['discount_type'];
107
108 /**
109 * Get the min or max discount amount according to plugin settings.
110 * Apply the filter to modify final discounted amount based on discount types.
111 */
112 $discounted_amount = apply_filters( 'disco_final_discounted_amount', $this->min_max_average( $discounts ), $discount_type );
113
114 if ( $discounted_amount < $price ) {
115 // Get an applied campaign from DiscountLimit class.
116 ( new UserLimit )->disco_start_session_on_checkout( $this->applied_campaign_id );
117
118 // Update the products on sale status.
119 apply_filters( 'woocommerce_product_is_on_sale', true, $product );
120
121 return $this->discounted_price( $price, $discounted_amount );
122 }
123 }
124
125 return $price;
126 }
127
128 /** Get Cart Discount.
129 *
130 * @param \WC_Cart $cart Cart Object.
131 * @return \WC_Cart Cart Object.
132 * @throws \Exception If the cart is empty.
133 */
134 public function get_cart_discount( $cart ) { //phpcs:ignore
135 if ( $cart->is_empty() ) {
136 return $cart;
137 }
138
139 // Init Cart - Based Intents except Product & Shipping Intent.
140 $this->intents = $this->prepare_intents( array( 'Cart' ) );
141
142 if ( ! empty( $this->intents ) && $cart->get_cart_contents_count() > 0 ) {
143 $discounts = array();
144
145 foreach ( $this->intents as $intent ) { // Foreach intent, apply the discount.
146 $items = $this->get_items_for_discount( $cart, $intent->campaign );
147
148 $discount = $intent->get_discounts( $items, $cart );
149
150 if ( empty( $discount ) ) {
151 continue;
152 }
153
154 $discounts[] = $discount;
155 }
156
157 // Apply discount to cart subtotal .
158 if ( ! empty( $discounts ) ) {
159 // Get the min or max discount amount according to plugin settings.
160 $cart_fee = $this->min_max_average( $discounts );
161 // TODO: The Discount must be less than cart subtotal.
162 $cart->add_fee( __( 'Discount', 'disco' ), -$cart_fee );
163 }
164 }
165
166 return $cart;
167 }
168
169 /**
170 * Apply Bulk & Bundle discount to cart items.
171 *
172 * @param \WC_Cart $cart Cart Object.
173 * @return \WC_Cart|void Cart Object.
174 * @throws \Exception If translation not found.
175 */
176 public function get_cart_items_discount( $cart ) {//phpcs:ignore
177 if ( ! $this->cart_is_valid() ) {
178 return $cart;
179 }
180
181 if ( ! defined( 'DOING_AJAX' ) && is_admin() ) {
182 return $cart;
183 }
184
185 // Init Cart - Based Intents except Product & Shipping Intent.
186 $this->intents = $this->prepare_intents( array( 'Bulk', 'Bundle', 'BOGO' ) );
187
188 $discounts = $this->prepare_item_discounts( $this->intents, $cart );
189
190 // return $discounts;
191
192 if ( empty( $discounts ) ) {
193 return $cart;
194 }
195
196 $total_discount = 0;
197
198 foreach ( $cart->get_cart() as $item ) {
199 // Get item id.
200 $id = $this->get_cart_item_id( $item );
201
202 if ( empty( $discounts[ $id ] ) ) {
203 continue;
204 }
205
206 $total_discount += $discounts[ $id ];
207 }
208
209 // Add the discount to the cart total.
210 if ( $total_discount > 0 ) {
211 $cart->add_fee( __( 'Discount', 'disco' ), -$total_discount );
212 }
213
214 // Set the cart session.
215 $cart->set_session();
216
217 return $cart;
218 }
219
220 /**
221 * Apply the discount to shipping.
222 *
223 * @return bool
224 */
225 public function apply_free_shipping() {
226 if ( ! $this->cart_is_valid() ) {
227 return false;
228 }
229
230 $cart = WC()->cart;
231 $this->intents = $this->prepare_intents( array( 'Shipping' ) );
232 $shippings = array();
233
234 if ( ! empty( $this->intents ) ) {
235 foreach ( $this->intents as $intent ) {
236 $items = $this->get_items_for_discount( $cart, $intent->campaign );
237 $shippings[] = $intent->get_discounts( $items, $cart );
238 }
239 }
240
241 return in_array( 'free_shipping', $shippings, true );
242 }
243
244 /**
245 * Get offers for a product.
246 *
247 * @param array|null $items item ids.
248 * @return string
249 */
250 public function get_offers( $items = null ) {
251 // Init Cart-Based Intents except Product & Shipping Intent.
252 $this->intents = $this->prepare_intents( array( 'Product', 'Shipping' ) );
253 $table = "<table style='border-collapse: collapse;' class=''>";
254 $table .= '<tr><th>Quantity</th><th>Discount</th></tr>';
255
256 $cart = WC()->cart;
257
258 foreach ( $this->intents as $intent ) {
259 if ( is_null( $items ) || ! $cart->is_empty() ) {
260 $items = $this->get_items_for_discount( $cart, $intent->campaign );
261 } else {
262 $items = array();
263 }
264
265 $discounts = $intent->get_offers( $items, $cart );
266
267 if ( empty( $discounts ) ) {
268 continue;
269 }
270
271 foreach ( $discounts as $discount ) {
272 $table .= '<tr style="font-size: smaller;line-height:15px"><td>' . $discount['condition'] . '</td><td>' . $discount['discount'] . '</td></tr>';
273 }
274 }
275
276 return $table . '</table>';
277 }
278
279 /**
280 * Get Premium Status.
281 */
282 public static function is_pro(): bool {
283 return is_plugin_active( 'disco-pro/disco-pro.php' );
284 }
285
286 }
287