PluginProbe
Discount Rules for WooCommerce – Disco | Dynamic Pricing, Conditions, Bulk, Bundle, BOGO / 1.3.50
Discount Rules for WooCommerce – Disco | Dynamic Pricing, Conditions, Bulk, Bundle, BOGO v1.3.50
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 / Calc / CalcPercent.php

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

187 lines 4.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Disco\App\Calc;
4
5 /**
6 * Class CalcPercent
7 *
8 * @package Disco
9 * @subpackage Disco\App\Calc
10 * @author Ohidul Islam <wahid0003@gmail.com>
11 * @link https://webappick.com
12 * @license https://opensource.org/licenses/gpl-license.php GNU Public License
13 * @category Plugin
14 */
15 class CalcPercent extends CalcAbstract {
16
17 use \Disco\App\Intents\IntentHelper;
18
19 /**
20 * @var object $cart Cart.
21 * @phpstan-ignore-next-line
22 */
23 private $cart;
24
25 /**
26 * @var mixed $discounted_quantities
27 */
28 private $discounted_quantities;
29
30 /**
31 * @var array $rule Campaign Rule.
32 */
33 private $rule;
34
35 /**
36 * @var array $item Cart Item.
37 */
38 private $item;
39
40 /**
41 * @var string $discount_intent
42 */
43 private $discount_intent;
44
45 /**
46 * CalcPercent constructor.
47 *
48 * @param array $rule Campaign Rule.
49 * @param array $item Cart Item.
50 * @param object $cart Cart.
51 * @param object $campaign Campaign.
52 */
53 public function __construct( $rule, $item, $cart, $campaign ) {
54 $this->item = $item;
55 $this->rule = $rule;
56 $this->cart = $cart;
57
58 // @phpstan-ignore-next-line
59 $this->discount_intent = $campaign->get_discount_intent(); // phpcs:ignore
60 }
61
62 /**
63 * Calculate Discount.
64 *
65 * @return array $discount
66 */
67 public function calculate(): array {
68 $discount = $this->calculate_discount();
69
70 return array(
71 'price' => $this->calculate_price( $discount ),
72 'discount' => $discount,
73 'line_subtotal' => $this->calculate_line_subtotal( $discount ),
74 'discounted_quantities' => $this->discounted_quantities,
75 );
76 }
77
78 /**
79 * Calculate Discount.
80 *
81 * @return float Discount Amount.
82 */
83 public function calculate_discount(): float { // phpcs:ignore
84 $discount_amount = 0;
85 $discount_value = $this->rule['discount_value'];
86 $price = CalcFactory::get_price( $this->item );
87 $quantity = (int) $this->item['quantity'];
88 $min = $this->rule['min'] ? (int) $this->rule['min'] : 0; //phpcs:ignore
89 $max = ! empty( $this->rule['max'] ) ? (int) $this->rule['max'] : ( $this->discount_intent === 'Bulk' ? PHP_INT_MAX : 0 ); // phpcs:ignore
90 $recursive = ! empty( $this->rule['recursive'] ) && $this->rule['recursive'] === 'yes'; // phpcs:ignore
91 $item_id = $this->item['product_id'];
92 $rule_ids = array_column( $this->rule['get_ids'], 'id' );
93 $discount_qty = $this->rule['get_quantity'] ? (int) $this->rule['get_quantity'] : 0; // phpcs:ignore
94
95 // Default discount for quantities.
96 $discount_for_quantities = $min;
97
98 // Apply for the Bulk Discount when max is set.
99 if ( $max && $quantity >= $max ) {
100 $discount_for_quantities = $max;
101 }
102
103 // If quantity between min and max then apply discount.
104 if ( $quantity >= $min && $quantity <= $max ) {
105 $discount_for_quantities = $quantity;
106 }
107
108 /**
109 * If discount intent is BuyXGetY then set the discount for quantities to 1.
110 * This is to ensure that the discount for selected item for BOGO discount.
111 * Here no need to check for min and max quantity.
112 */
113
114 if (
115 $this->discount_intent === 'BuyXGetY'
116 && ! empty( $rule_ids )
117 && (
118 in_array( $item_id, $rule_ids, true )
119 || $this->is_in_category( $item_id, $rule_ids )
120 )
121 ) {
122 $discount_for_quantities = $discount_qty;
123 }
124
125 // Apply for the Bundle & BOGO Discount when recursive is set.
126 $multiplier = 1;
127
128 if ( $recursive ) {
129 if ( $quantity % $min === 0 || $quantity > $discount_for_quantities ) {
130 $multiplier = floor( $quantity / $discount_for_quantities );
131 $discount_for_quantities *= $multiplier;
132 }
133 }
134
135 // Discount per product.
136 $product_discount = 0;
137
138 if ( $price ) {
139 $product_discount = $price * $discount_value / 100;
140 }
141
142 // Limit discount to Min or Max quantity.
143 if ( $quantity >= $discount_for_quantities ) {
144 $discount_for_quantities = min( $quantity, $discount_for_quantities );
145
146 // Set the discounted quantity for BOGO.
147 if ( ! empty( $this->rule['get_quantity'] ) ) {
148 $discount_for_quantities = (int) $this->rule['get_quantity'];
149 $discount_for_quantities *= $multiplier;
150 }
151
152 $discount_amount = $discount_for_quantities * $product_discount;
153 }
154
155 $this->discounted_quantities = $discount_for_quantities;
156
157 return apply_filters( 'disco_final_discounted_amount', $discount_amount, 'percent' );
158 }
159
160 /**
161 * Calculate Price.
162 *
163 * @param float $discount Discount Amount.
164 * @return float Price.
165 */
166 public function calculate_price( $discount ): float {
167 $discounted_subtotal = $this->calculate_line_subtotal( $discount );
168
169 return $discounted_subtotal / $this->item['quantity'];
170 }
171
172 /**
173 * Calculate Line Subtotal.
174 *
175 * @param float $discount Discount Amount.
176 * @return float Line Subtotal.
177 */
178 public function calculate_line_subtotal( $discount ): float {
179 if ( isset( $this->item['line_subtotal'] ) ) {
180 return $this->item['line_subtotal'] - $discount;
181 }
182
183 return 0.0;
184 }
185
186 }
187