PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 3.9.3
Tutor LMS – eLearning and online course solution v3.9.3
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
Cart 10 months ago PaymentGateways 8 months ago AdminMenu.php 9 months ago BillingController.php 1 year ago CartController.php 1 year ago CheckoutController.php 7 months ago CouponController.php 11 months ago Ecommerce.php 1 year ago EmailController.php 11 months ago HooksHandler.php 7 months ago OptionKeys.php 1 year ago OrderActivitiesController.php 1 year ago OrderController.php 7 months ago PaymentHandler.php 9 months ago Settings.php 9 months ago Tax.php 9 months ago currency.php 1 year ago
Tax.php
321 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_action( 'wp_ajax_tutor_get_tax_settings', array( $this, 'ajax_get_tax_settings' ) );
42 }
43
44 /**
45 * Get the tax settings from the tutor options.
46 *
47 * @since 3.0.0
48 *
49 * @return void
50 */
51 public function ajax_get_tax_settings() {
52 tutor_utils()->checking_nonce();
53 tutor_utils()->check_current_user_capability();
54
55 $tax_settings = self::get_settings();
56
57 if ( ! empty( $tax_settings->active_country ) ) {
58 $tax_settings->active_country = null;
59 }
60
61 $this->json_response( __( 'Success', 'tutor' ), $tax_settings );
62 }
63
64 /**
65 * Get tax settings.
66 *
67 * @since 3.0.0
68 *
69 * @return object
70 */
71 public static function get_settings() {
72 $tax_settings = tutor_utils()->get_option( 'ecommerce_tax' );
73
74 if ( ! empty( $tax_settings ) && is_string( $tax_settings ) ) {
75 $tax_settings = json_decode( $tax_settings );
76 }
77
78 return $tax_settings;
79 }
80
81 /**
82 * Get tax settings key data.
83 *
84 * @since 3.0.0
85 *
86 * @param string $key key.
87 * @param mixed $default default value.
88 *
89 * @return mixed
90 */
91 public static function get_setting( $key, $default = false ) {
92 $tax_settings = self::get_settings();
93
94 if ( isset( $tax_settings->$key ) ) {
95 return $tax_settings->$key;
96 }
97
98 return $default;
99 }
100
101 /**
102 * Check individual tax control is enabled or not.
103 *
104 * @since 3.7.0
105 *
106 * @return boolean
107 */
108 public static function is_individual_control_enabled() {
109 return self::get_setting( 'enable_individual_tax_control', false );
110 }
111
112 /**
113 * Should calculate tax or not.
114 *
115 * @since 3.7.0
116 *
117 * @return boolean
118 */
119 public static function should_calculate_tax() {
120 return self::get_setting( 'enable_tax', true ) && self::is_tax_configured();
121 }
122
123 /**
124 * Calculate tax.
125 *
126 * @since 3.0.0
127 *
128 * @param float $amount amount.
129 * @param float $rate tax rate.
130 *
131 * @return float
132 */
133 public static function calculate_tax( $amount, $rate ) {
134 if ( 0 === $rate ) {
135 return $rate;
136 }
137
138 if ( self::is_tax_included_in_price() ) {
139 // Tax = (Tax Rate X Price) / (1 + Tax Rate).
140 // Amount Without Tax = Amount With Tax / (1 + Tax Rate).
141 $tax_rate = $rate / 100;
142 $tax = ( $tax_rate * $amount ) / ( 1 + $tax_rate );
143 } else {
144 try {
145 $tax = $amount * ( $rate / 100 );
146 } catch ( \Throwable $th ) {
147 $tax = 0.0;
148 }
149 }
150
151 // Tax amount should not negative value.
152 return max( 0, round( $tax, 2 ) );
153 }
154
155 /**
156 * Get text rate for a user according to billing country and state.
157 *
158 * @param integer $user_id user id.
159 *
160 * @return float tax rate.
161 */
162 public static function get_user_tax_rate( $user_id = 0 ) {
163 $billing_info = ( new BillingController( false ) )->get_billing_info( $user_id );
164 $billing_country = $billing_info->billing_country ?? '';
165 $billing_state = $billing_info->billing_state ?? '';
166
167 return self::get_country_state_tax_rate( $billing_country, $billing_state );
168 }
169
170 /**
171 * Check site admin configured tax or not.
172 *
173 * @since 3.0.0
174 *
175 * @return boolean
176 */
177 public static function is_tax_configured() {
178 $tax_settings = self::get_settings();
179
180 return ( is_object( $tax_settings )
181 && isset( $tax_settings->rates )
182 && count( $tax_settings->rates ) );
183 }
184
185 /**
186 * Check tax is included in price or not.
187 *
188 * @since 3.0.0
189 *
190 * @return boolean
191 */
192 public static function is_tax_included_in_price() {
193 return (bool) self::get_setting( 'is_tax_included_in_price' );
194 }
195
196 /**
197 * Show price with tax in course list and details.
198 *
199 * @since 3.0.0
200 *
201 * @return bool
202 */
203 public static function show_price_with_tax() {
204 return (bool) self::get_setting( 'show_price_with_tax' );
205 }
206
207 /**
208 * Get tax type.
209 *
210 * @since 3.0.0
211 *
212 * @return string
213 */
214 public static function get_tax_type() {
215 return self::is_tax_included_in_price() ? self::TYPE_INCLUSIVE : self::TYPE_EXCLUSIVE;
216 }
217
218 /**
219 * Get country rate.
220 *
221 * @since 3.0.0
222 *
223 * @since 3.3.0 Country param is optional
224 *
225 * @param string $country the country code for which the tax rate needs to be found.
226 * @param string $state state name.
227 *
228 * @return float tax rate value.
229 */
230 public static function get_country_state_tax_rate( $country = null, $state = null ) {
231 $zero_tax = 0.0;
232
233 $country = apply_filters( 'tutor_ecommerce_tax_country', $country );
234 $state = apply_filters( 'tutor_ecommerce_tax_state', $state );
235
236 if ( empty( $country ) ) {
237 return $zero_tax;
238 }
239
240 $country_info = self::get_country_info( $country );
241 if ( ! $country_info ) {
242 return $zero_tax;
243 }
244
245 $country_code = $country_info['numeric_code'] ?? '';
246 $country_rate_data = null;
247
248 $tax_settings = self::get_settings();
249 if ( empty( $tax_settings->rates ) ) {
250 return $zero_tax;
251 }
252
253 foreach ( $tax_settings->rates as $rate ) {
254 if ( $rate->country === $country_code ) {
255 $country_rate_data = $rate;
256 break;
257 }
258 }
259
260 if ( empty( $country_rate_data ) ) {
261 return $zero_tax;
262 }
263
264 if ( $country_rate_data->is_same_rate || 0 === count( $country_rate_data->states ) ) {
265 return floatval( $country_rate_data->rate );
266 } else {
267 // Get state rate.
268 $state_info = self::get_state_info( $country_info['states'], $state );
269 if ( empty( $state_info ) ) {
270 return $zero_tax;
271 }
272
273 $state_rate = null;
274 foreach ( $country_rate_data->states as $item ) {
275 if ( $item->id === $state_info['id'] ) {
276 $state_rate = floatval( $item->rate );
277 break;
278 }
279 }
280
281 return $state_rate;
282 }
283 }
284
285 /**
286 * Get country info by name.
287 *
288 * @since 3.0.0
289 *
290 * @param string $name name of country.
291 *
292 * @return array|null
293 */
294 public static function get_country_info( $name ) {
295 $countries = tutor_get_country_list();
296 foreach ( $countries as $country ) {
297 if ( strtolower( $country['name'] ) === strtolower( $name ) ) {
298 return $country;
299 }
300 }
301 }
302
303 /**
304 * Get state info of a country.
305 *
306 * @since 3.0.0
307 *
308 * @param array $states list of states of a country.
309 * @param string $state_name name of state.
310 *
311 * @return array|null
312 */
313 public static function get_state_info( $states, $state_name ) {
314 foreach ( $states as $state ) {
315 if ( strtolower( $state['name'] ) === strtolower( $state_name ) ) {
316 return $state;
317 }
318 }
319 }
320 }
321