PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 3.4.1
Tutor LMS – eLearning and online course solution v3.4.1
3.9.15 3.9.14 3.9.13 3.9.12 3.9.11 trunk 1.0.0 1.0.0-alpha 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.2.0 1.2.1 1.2.11 1.2.12 1.2.13 1.2.20 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 1.8.10 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.15 1.9.16 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.10 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.3.0 2.4.0 2.5.0 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.1.0 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.7.0 3.7.1 3.7.2 3.7.3 3.7.4 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 3.9.1 3.9.10 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9
tutor / ecommerce / Tax.php
tutor / ecommerce Last commit date
PaymentGateways 1 year ago AdminMenu.php 1 year ago BillingController.php 1 year ago CartController.php 1 year ago CheckoutController.php 1 year ago CouponController.php 1 year ago Ecommerce.php 1 year ago EmailController.php 1 year ago HooksHandler.php 1 year ago OptionKeys.php 1 year ago OrderActivitiesController.php 1 year ago OrderController.php 1 year ago PaymentHandler.php 1 year ago Settings.php 1 year ago Tax.php 1 year ago currency.php 1 year ago
Tax.php
314 lines
1 <?php
2 /**
3 * Tax calculation class for tutor monetization.
4 *
5 * @package Tutor\Ecommerce
6 * @author Themeum
7 * @link https://themeum.com
8 * @since 3.0.0
9 */
10
11 namespace Tutor\Ecommerce;
12
13 use Tutor\Traits\JsonResponse;
14
15 /**
16 * Class Tax
17 *
18 * @since 3.0.0
19 */
20 class Tax {
21 use JsonResponse;
22
23 /**
24 * Tax type const.
25 */
26 const TYPE_INCLUSIVE = 'inclusive';
27 const TYPE_EXCLUSIVE = 'exclusive';
28
29 /**
30 * Register hooks and dependencies.
31 *
32 * @since 3.0.0
33 *
34 * @param boolean $register_hooks hook register or not.
35 */
36 public function __construct( $register_hooks = true ) {
37 if ( ! $register_hooks ) {
38 return;
39 }
40
41 add_filter( 'tutor_option_input', array( $this, 'format_tax_data_before_save' ) );
42 add_action( 'wp_ajax_tutor_get_tax_settings', array( $this, 'ajax_get_tax_settings' ) );
43 }
44
45 /**
46 * Format ecommerce tax setting data before save it to tutor settings.
47 *
48 * @param array $option option.
49 *
50 * @return array
51 */
52 public function format_tax_data_before_save( $option ) {
53 if ( ! empty( $option['ecommerce_tax'] ) ) {
54 $option['ecommerce_tax'] = wp_unslash( $option['ecommerce_tax'] );
55 }
56
57 return $option;
58 }
59
60 /**
61 * Get the tax settings from the tutor options.
62 *
63 * @since 3.0.0
64 *
65 * @return void
66 */
67 public function ajax_get_tax_settings() {
68 tutor_utils()->checking_nonce();
69 tutor_utils()->check_current_user_capability();
70
71 $tax_settings = self::get_settings();
72
73 if ( ! empty( $tax_settings->active_country ) ) {
74 $tax_settings->active_country = null;
75 }
76
77 $this->json_response( __( 'Success', 'tutor' ), $tax_settings );
78 }
79
80 /**
81 * Get tax settings.
82 *
83 * @since 3.0.0
84 *
85 * @return object
86 */
87 public static function get_settings() {
88 $tax_settings = tutor_utils()->get_option( 'ecommerce_tax' );
89
90 if ( ! empty( $tax_settings ) && is_string( $tax_settings ) ) {
91 $tax_settings = json_decode( $tax_settings );
92 }
93
94 return $tax_settings;
95 }
96
97 /**
98 * Get tax settings key data.
99 *
100 * @since 3.0.0
101 *
102 * @param string $key key.
103 * @param mixed $default default value.
104 *
105 * @return mixed
106 */
107 public static function get_setting( $key, $default = false ) {
108 $tax_settings = self::get_settings();
109
110 if ( ! empty( $tax_settings->$key ) ) {
111 return $tax_settings->$key;
112 }
113
114 return $default;
115 }
116
117 /**
118 * Calculate tax.
119 *
120 * @since 3.0.0
121 *
122 * @param float $amount amount.
123 * @param float $rate tax rate.
124 *
125 * @return float
126 */
127 public static function calculate_tax( $amount, $rate ) {
128 if ( 0 === $rate ) {
129 return $rate;
130 }
131
132 if ( self::is_tax_included_in_price() ) {
133 // Tax = (Tax Rate X Price) / (1 + Tax Rate).
134 $tax = $amount - ( $rate * $amount ) / ( 1 + $rate );
135 } else {
136 try {
137 $tax = $amount * ( $rate / 100 );
138 } catch ( \Throwable $th ) {
139 $tax = 0.0;
140 }
141 }
142
143 // Tax amount should not negative value.
144 return max( 0, round( $tax, 2 ) );
145 }
146
147 /**
148 * Get text rate for a user according to billing country and state.
149 *
150 * @param integer $user_id user id.
151 *
152 * @return float tax rate.
153 */
154 public static function get_user_tax_rate( $user_id = 0 ) {
155 $billing_info = ( new BillingController( false ) )->get_billing_info( $user_id );
156 $billing_country = $billing_info->billing_country ?? '';
157 $billing_state = $billing_info->billing_state ?? '';
158
159 return self::get_country_state_tax_rate( $billing_country, $billing_state );
160 }
161
162 /**
163 * Check site admin configured tax or not.
164 *
165 * @since 3.0.0
166 *
167 * @return boolean
168 */
169 public static function is_tax_configured() {
170 $tax_settings = self::get_settings();
171
172 return ( is_object( $tax_settings )
173 && isset( $tax_settings->rates )
174 && count( $tax_settings->rates ) );
175 }
176
177 /**
178 * Check tax is included in price or not.
179 *
180 * @since 3.0.0
181 *
182 * @return boolean
183 */
184 public static function is_tax_included_in_price() {
185 return (bool) self::get_setting( 'is_tax_included_in_price' );
186 }
187
188 /**
189 * Show price with tax in course list and details.
190 *
191 * @since 3.0.0
192 *
193 * @return bool
194 */
195 public static function show_price_with_tax() {
196 return (bool) self::get_setting( 'show_price_with_tax' );
197 }
198
199 /**
200 * Get tax type.
201 *
202 * @since 3.0.0
203 *
204 * @return string
205 */
206 public static function get_tax_type() {
207 return self::is_tax_included_in_price() ? self::TYPE_INCLUSIVE : self::TYPE_EXCLUSIVE;
208 }
209
210 /**
211 * Get country rate.
212 *
213 * @since 3.0.0
214 *
215 * @since 3.3.0 Country param is optional
216 *
217 * @param string $country the country code for which the tax rate needs to be found.
218 * @param string $state state name.
219 *
220 * @return float tax rate value.
221 */
222 public static function get_country_state_tax_rate( $country = null, $state = null ) {
223 $zero_tax = 0.0;
224
225 $country = apply_filters( 'tutor_ecommerce_tax_country', $country );
226 $state = apply_filters( 'tutor_ecommerce_tax_state', $state );
227
228 if ( empty( $country ) ) {
229 return $zero_tax;
230 }
231
232 $country_info = self::get_country_info( $country );
233 if ( ! $country_info ) {
234 return $zero_tax;
235 }
236
237 $country_code = $country_info['numeric_code'] ?? '';
238 $country_rate_data = null;
239
240 $tax_settings = self::get_settings();
241 if ( empty( $tax_settings->rates ) ) {
242 return $zero_tax;
243 }
244
245 foreach ( $tax_settings->rates as $rate ) {
246 if ( $rate->country === $country_code ) {
247 $country_rate_data = $rate;
248 break;
249 }
250 }
251
252 if ( empty( $country_rate_data ) ) {
253 return $zero_tax;
254 }
255
256 if ( $country_rate_data->is_same_rate || 0 === count( $country_rate_data->states ) ) {
257 return floatval( $country_rate_data->rate );
258 } else {
259 // Get state rate.
260 $state_info = self::get_state_info( $country_info['states'], $state );
261 if ( empty( $state_info ) ) {
262 return $zero_tax;
263 }
264
265 $state_rate = null;
266 foreach ( $country_rate_data->states as $item ) {
267 if ( $item->id === $state_info['id'] ) {
268 $state_rate = floatval( $item->rate );
269 break;
270 }
271 }
272
273 return $state_rate;
274 }
275
276 }
277
278 /**
279 * Get country info by name.
280 *
281 * @since 3.0.0
282 *
283 * @param string $name name of country.
284 *
285 * @return array|null
286 */
287 public static function get_country_info( $name ) {
288 $countries = tutor_get_country_list();
289 foreach ( $countries as $country ) {
290 if ( strtolower( $country['name'] ) === strtolower( $name ) ) {
291 return $country;
292 }
293 }
294 }
295
296 /**
297 * Get state info of a country.
298 *
299 * @since 3.0.0
300 *
301 * @param array $states list of states of a country.
302 * @param string $state_name name of state.
303 *
304 * @return array|null
305 */
306 public static function get_state_info( $states, $state_name ) {
307 foreach ( $states as $state ) {
308 if ( strtolower( $state['name'] ) === strtolower( $state_name ) ) {
309 return $state;
310 }
311 }
312 }
313 }
314