PluginProbe ʕ •ᴥ•ʔ
WooCommerce / 11.1.0-beta.2
WooCommerce v11.1.0-beta.2
11.1.0 11.1.0-rc.2 11.1.0-rc.1 11.1.0-beta.2 11.1.0-beta.1 11.0.1 11.0.0 11.0.0-rc.3 11.0.0-rc.2 11.0.0-rc.1 11.0.0-beta.2 11.0.0-beta.1 10.9.4 10.9.3 10.9.2 10.9.1 10.9.0 10.9.0-rc.1 10.9.0-beta.2 10.9.0-beta.1 10.8.1 10.8.0 10.8.0-rc.1 10.8.0-beta.2 10.8.0-beta.1 7.8.0-beta.1 7.8.0-beta.2 7.8.0-rc.1 7.8.0-rc.2 7.8.1 7.8.2 7.8.3 7.8.4 7.9.0 7.9.0-beta.1 7.9.0-beta.2 7.9.0-rc.2 7.9.0-rc.3 7.9.1 7.9.2 8.0.0 8.0.0-beta.1 8.0.0-beta.2 8.0.0-rc.1 8.0.0-rc.2 8.0.1 8.0.2 8.0.3 8.0.4 8.0.5 8.1.0 8.1.0-beta.1 8.1.0-rc.1 8.1.0-rc.2 8.1.1 8.1.2 8.1.3 8.1.4 8.2.0 8.2.0-beta.1 8.2.0-rc.1 8.2.0-rc.2 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.3.0 8.3.0-beta.1 8.3.0-rc.1 8.3.0-rc.2 8.3.1 8.3.2 8.3.3 8.3.4 8.4.0 8.4.0-beta.1 8.4.0-rc.1 8.4.1 8.4.2 8.4.3 8.5.0 8.5.0-beta.1 8.5.0-rc.1 8.5.1 8.5.2 8.5.3 8.5.4 8.5.5 8.6.0 8.6.0-beta.1 8.6.0-rc.1 8.6.1 8.6.2 8.6.3 8.6.4 8.7.0 8.7.0-beta.1 8.7.0-beta.2 8.7.0-rc.1 8.7.1 8.7.2 8.7.3 8.8.0 8.8.0-beta.1 8.8.0-rc.1 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.8.6 8.8.7 8.9.0 8.9.0-beta.1 8.9.0-rc.1 8.9.1 8.9.2 8.9.3 8.9.4 8.9.5 9.0.0 9.0.0-beta.1 9.0.0-beta.2 9.0.0-rc.1 9.0.1 9.0.2 9.0.3 9.0.4 9.1.0 9.1.0-beta.1 9.1.0-rc.1 9.1.1 9.1.2 9.1.3 9.1.4 9.1.5 9.1.6 9.2.0 9.2.0-beta.1 9.2.0-rc.1 9.2.1 9.2.2 9.2.3 9.2.4 9.2.5 9.3.0 9.3.0-beta.1 9.3.0-rc.1 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.3.6 9.4.0 9.4.0-beta.1 9.4.0-beta.2 9.4.0-rc.1 9.4.0-rc.2 9.4.0-rc.3 9.4.0-rc.4 9.4.1 9.4.2 9.4.3 9.4.4 9.4.5 9.5.0 9.5.0-beta.1 9.5.0-beta.2 9.5.0-rc.1 9.5.1 9.5.2 9.5.3 9.5.4 9.6.0 9.6.0-beta.1 9.6.0-beta.2 9.6.0-rc.1 9.6.1 9.6.2 9.6.3 9.6.4 9.7.0 9.7.0-beta.1 9.7.0-rc.1 9.7.1 9.7.2 9.7.3 9.8.0 9.8.0-beta.1 9.8.0-rc.1 9.8.1 9.8.2 9.8.3 9.8.4 9.8.5 9.8.6 9.8.7 9.9.0 9.9.0-beta.1 9.9.0-rc.1 9.9.1 9.9.2 9.9.3 9.9.4 9.9.5 9.9.6 9.9.7 3.7.3 7.1.2 3.8.0 7.2.0 3.8.0-beta.1 7.2.0-beta.1 3.8.0-rc.1 7.2.0-beta.2 3.8.0-rc.2 7.2.0-rc.1 3.8.1 7.2.0-rc.2 3.8.2 7.2.1 3.8.3 7.2.2 3.9.0 7.2.3 3.9.0-beta.1 7.2.4 3.9.0-beta.2 7.3.0 3.9.0-rc.1 7.3.0-beta.1 3.9.0-rc.2 7.3.0-beta.2 3.9.0-rc.3 7.3.0-rc.1 3.9.0-rc.4 7.3.0-rc.2 3.9.1 7.3.1 3.9.2 7.4.0 3.9.3 7.4.0-beta.1 3.9.4 7.4.0-beta.2 3.9.5 7.4.0-rc.1 4.0.0 7.4.0-rc.2 4.0.0-beta.1 7.4.1 4.0.0-rc.1 7.4.2 4.0.0-rc.2 7.5.0 4.0.1 7.5.0-beta.1 4.0.2 7.5.0-beta.2 4.0.3 7.5.0-rc.1 4.0.4 7.5.1 4.1.0 7.5.2 4.1.0-beta.1 7.6.0 4.1.0-beta.2 7.6.0-beta.1 4.1.0-rc.1 7.6.0-beta.2 4.1.0-rc.2 7.6.0-rc.1 4.1.1 7.6.0-rc.2 4.1.2 7.6.0-rc.3 4.1.3 7.6.1 4.1.4 7.6.2 4.2.0 7.7.0 4.2.0-RC.1 7.7.0-beta.1 4.2.0-RC.2 7.7.0-beta.2 4.2.0-beta.1 7.7.0-rc.1 4.2.1 7.7.1 4.2.2 7.7.2 4.2.3 7.7.3 4.2.4 7.8.0 4.2.5 4.3.0 4.3.0-beta.1 4.3.0-rc.1 4.3.0-rc.2 4.3.0-rc.3 4.3.1 4.3.2 4.3.3 4.3.4 4.3.5 4.3.6 4.4.0 4.4.0-beta.1 4.4.0-rc.1 4.4.1 4.4.2 4.4.3 4.4.4 4.5.0 4.5.0-beta.1 4.5.0-rc.1 4.5.0-rc.3 4.5.1 4.5.2 4.5.3 4.5.4 4.5.5 4.6.0 4.6.0-beta.1 4.6.0-rc.1 4.6.1 4.6.2 4.6.3 4.6.4 4.6.5 4.7.0 4.7.0-beta.1 4.7.0-beta.2 4.7.0-rc.1 4.7.1 4.7.1-beta.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.0-beta.1 4.8.0-rc.1 4.8.0-rc.2 4.8.1 4.8.2 4.8.3 4.9.0 4.9.0-beta.1 4.9.0-rc.1 4.9.0-rc.2 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 5.0.0 5.0.0-beta.1 5.0.0-beta.2 5.0.0-rc.1 5.0.0-rc.2 5.0.0-rc.3 5.0.1 5.0.2 5.0.3 5.1.0 5.1.0-beta.1 5.1.0-rc.1 trunk 5.1.1 10.0.0 5.1.2 10.0.0-rc.1 5.1.3 10.0.0-rc.2 5.2.0 10.0.1 5.2.0-beta.1 10.0.2 5.2.0-rc.1 10.0.3 5.2.0-rc.2 10.0.4 5.2.1 10.0.5 5.2.2 10.0.6 5.2.3 10.1.0 5.2.4 10.1.0-rc.1 5.2.5 10.1.0-rc.2 5.3.0 10.1.0-rc.3 5.3.0-beta.1 10.1.0-rc.4 5.3.0-rc.1 10.1.1 5.3.0-rc.2 10.1.2 5.3.1 10.1.3 5.3.2 10.1.4 5.3.3 10.2.0 5.4.0 10.2.0-beta.1 5.4.0-beta.1 10.2.0-beta.2 5.4.0-rc.1 10.2.0-rc.1 5.4.1 10.2.1 5.4.2 10.2.2 5.4.3 10.2.3 5.4.4 10.2.4 5.4.5 10.3.0 5.5.0 10.3.0-beta.1 5.5.0-beta.1 10.3.0-beta.2 5.5.0-rc.1 10.3.0-rc.1 5.5.0-rc.2 10.3.0-rc.2 5.5.1 10.3.1 5.5.2 10.3.2 5.5.3 10.3.3 5.5.4 10.3.4 5.5.5 10.3.5 5.6.0 10.3.6 5.6.0-beta.1 10.3.7 5.6.0-rc.1 10.3.8 5.6.0-rc.2 10.4.0 5.6.1 10.4.0-beta.1 5.6.2 10.4.0-beta.2 5.6.3 10.4.0-rc.1 5.7.0 10.4.1 5.7.0-beta.1 10.4.2 5.7.0-rc.1 10.4.3 5.7.1 10.4.4 5.7.2 10.5.0 5.7.3 10.5.0-beta.1 5.8.0 10.5.0-beta.2 5.8.0-beta.1 10.5.0-rc.1 5.8.0-beta.2 10.5.0-rc.2 5.8.0-rc.1 10.5.0-rc.3 5.8.1 10.5.1 5.8.2 10.5.2 5.9.0 10.5.3 5.9.0-beta.1 10.6.0 5.9.0-rc.1 10.6.0-beta.1 5.9.0-rc.2 10.6.0-beta.2 5.9.1 10.6.0-rc.1 5.9.2 10.6.1 6.0.0 10.6.2 6.0.0-beta.1 10.7.0 6.0.0-rc.1 10.7.0-beta.1 6.0.1 10.7.0-beta.2 6.0.2 10.7.0-rc.1 6.1.0 3.0.0 6.1.0-beta.1 3.0.1 6.1.0-rc.1 3.0.2 6.1.0-rc.2 3.0.3 6.1.1 3.0.4 6.1.2 3.0.5 6.1.3 3.0.6 6.2.0 3.0.7 6.2.0-beta.1 3.0.8 6.2.0-rc.1 3.0.9 6.2.0-rc.2 3.1.0 6.2.1 3.1.1 6.2.2 3.1.2 6.2.3 3.2.0 6.3.0 3.2.1 6.3.0-beta.1 3.2.2 6.3.0-rc.1 3.2.3 6.3.0-rc.2 3.2.4 6.3.1 3.2.5 6.3.2 3.2.6 6.4.0 3.3.0 6.4.0-beta.1 3.3.1 6.4.0-rc.1 3.3.2 6.4.1 3.3.2-rc.1 6.4.2 3.3.3 6.5.0 3.3.4 6.5.0-beta.1 3.3.5 6.5.0-rc.1 3.3.6 6.5.0-rc.2 3.4.0 6.5.1 3.4.0-beta.1 6.5.2 3.4.0-rc.2 6.6.0 3.4.1 6.6.0-beta.1 3.4.2 6.6.0-rc.1 3.4.3 6.6.0-rc.2 3.4.4 6.6.1 3.4.5 6.6.2 3.4.6 6.7.0 3.4.7 6.7.0-beta.1 3.4.8 6.7.0-beta.2 3.5.0 6.7.0-rc.1 3.5.0-beta.1 6.7.1 3.5.0-rc.1 6.8.0 3.5.0-rc.2 6.8.0-beta.1 3.5.1 6.8.0-beta.2 3.5.10 6.8.0-rc.1 3.5.2 6.8.1 3.5.3 6.8.2 3.5.4 6.8.3 3.5.5 6.9.0 3.5.6 6.9.0-beta.1 3.5.7 6.9.0-beta.2 3.5.8 6.9.0-rc.1 3.5.9 6.9.1 3.6.0 6.9.2 3.6.0-beta.1 6.9.3 3.6.0-rc.1 6.9.4 3.6.0-rc.2 6.9.5 3.6.0-rc.3 7.0.0 3.6.1 7.0.0-beta.1 3.6.2 7.0.0-beta.2 3.6.3 7.0.0-beta.3 3.6.4 7.0.0-rc.1 3.6.5 7.0.0-rc.2 3.6.6 7.0.1 3.6.7 7.0.2 3.7.0 7.1.0 3.7.0-beta.1 7.1.0-beta.1 3.7.0-rc.1 7.1.0-beta.2 3.7.0-rc.2 7.1.0-rc.1 3.7.1 7.1.0-rc.2 3.7.2 7.1.1
woocommerce / src / Admin / Features / OnboardingTasks / Tasks / Tax.php
woocommerce / src / Admin / Features / OnboardingTasks / Tasks Last commit date
AdditionalPayments.php 1 year ago Appearance.php 2 years ago CustomizeStore.php 3 weeks ago ExperimentalShippingRecommendation.php 3 weeks ago ExtendStore.php 1 year ago GetMobileApp.php 3 years ago LaunchYourStore.php 3 weeks ago Marketing.php 3 weeks ago Payments.php 3 weeks ago Products.php 3 weeks ago ReviewShippingOptions.php 4 years ago Shipping.php 3 weeks ago StoreCreation.php 4 years ago StoreDetails.php 3 weeks ago Tax.php 3 weeks ago TourInAppMarketplace.php 2 years ago WooCommercePayments.php 3 weeks ago
Tax.php
287 lines
1 <?php
2
3 namespace Automattic\WooCommerce\Admin\Features\OnboardingTasks\Tasks;
4
5 use Automattic\WooCommerce\Admin\API\Reports\Taxes\Stats\DataStore as TaxDataStore;
6 use Automattic\WooCommerce\Admin\Features\Features;
7 use Automattic\WooCommerce\Admin\Features\OnboardingTasks\Task;
8 use Automattic\WooCommerce\Admin\PluginsHelper;
9 use Automattic\WooCommerce\Internal\Admin\WCAdminAssets;
10
11 /**
12 * Tax Task
13 */
14 class Tax extends Task {
15
16 private const TAX_RATE_EXISTS_CACHE_KEY = 'woocommerce_onboarding_task_tax_rates_exist';
17
18 /**
19 * Used to cache is_complete() method result.
20 *
21 * @var null
22 */
23 private $is_complete_result = null;
24
25 /**
26 * Constructor
27 *
28 * @param TaskList $task_list Parent task list.
29 */
30 public function __construct( $task_list ) {
31 parent::__construct( $task_list );
32 add_action( 'admin_enqueue_scripts', array( $this, 'possibly_add_return_notice_script' ) );
33 add_action( 'woocommerce_tax_rate_added', array( $this, 'on_tax_rate_added' ) );
34 add_action( 'woocommerce_tax_rate_deleted', array( $this, 'on_tax_rate_deleted' ) );
35 }
36
37 /**
38 * Adds a return to task list notice when completing the task.
39 */
40 public function possibly_add_return_notice_script() {
41 $page = isset( $_GET['page'] ) ? $_GET['page'] : ''; // phpcs:ignore csrf ok, sanitization ok.
42 $tab = isset( $_GET['tab'] ) ? $_GET['tab'] : ''; // phpcs:ignore csrf ok, sanitization ok.
43
44 if ( $page !== 'wc-settings' || $tab !== 'tax' ) {
45 return;
46 }
47
48 if ( ! $this->is_active() || $this->is_complete() ) {
49 return;
50 }
51
52 WCAdminAssets::register_script( 'wp-admin-scripts', 'onboarding-tax-notice', true );
53 }
54
55 /**
56 * ID.
57 *
58 * @return string
59 */
60 public function get_id() {
61 return 'tax';
62 }
63
64 /**
65 * Contextual image URL.
66 *
67 * @return string
68 */
69 public function get_image_url() {
70 return WC()->plugin_url() . '/assets/images/task_list/tax-illustration.svg';
71 }
72
73 /**
74 * Alt text for the contextual image.
75 *
76 * @return string
77 */
78 public function get_image_alt() {
79 return __( 'Tax illustration', 'woocommerce' );
80 }
81
82 /**
83 * Title.
84 *
85 * @return string
86 */
87 public function get_title() {
88 return __( 'Collect sales tax', 'woocommerce' );
89 }
90
91 /**
92 * Content.
93 *
94 * @return string
95 */
96 public function get_content() {
97 return self::can_use_automated_taxes()
98 ? __(
99 'Good news! WooCommerce Tax can automate your sales tax calculations for you.',
100 'woocommerce'
101 )
102 : __(
103 'Set your store location and configure tax rate settings.',
104 'woocommerce'
105 );
106 }
107
108 /**
109 * Time.
110 *
111 * @return string
112 */
113 public function get_time() {
114 return __( '1 minute', 'woocommerce' );
115 }
116
117 /**
118 * Action label.
119 *
120 * @return string
121 */
122 public function get_action_label() {
123 return self::can_use_automated_taxes()
124 ? __( 'Yes please', 'woocommerce' )
125 : __( "Let's go", 'woocommerce' );
126 }
127
128 /**
129 * Task completion.
130 *
131 * @return bool
132 */
133 public function is_complete() {
134 if ( $this->is_complete_result === null ) {
135 $wc_connect_taxes_enabled = get_option( 'wc_connect_taxes_enabled' );
136 $is_wc_connect_taxes_enabled = ( $wc_connect_taxes_enabled === 'yes' ) || ( $wc_connect_taxes_enabled === true ); // seems that in some places boolean is used, and other places 'yes' | 'no' is used
137
138 // phpcs:ignore WooCommerce.Commenting.CommentHooks.MissingHookComment -- We will replace this with a formal system by WC 9.6 so lets not advertise it yet.
139 $third_party_complete = apply_filters( 'woocommerce_admin_third_party_tax_setup_complete', false );
140
141 /**
142 * Ideally we would check against `wc_tax_enabled()` instead of `false !== get_option( 'woocommerce_no_sales_tax' )`,
143 * however, tax is disabled by default making this task complete by default if we use it. If we change taxes
144 * to be enabled by default in the future, this can be updated to check against `wc_tax_enabled()` which is
145 * more accurate for this evaluation.
146 */
147 $this->is_complete_result = $is_wc_connect_taxes_enabled ||
148 $third_party_complete ||
149 false !== get_option( 'woocommerce_no_sales_tax' ) ||
150 $this->has_existing_tax_rates();
151 }
152
153 return $this->is_complete_result;
154 }
155
156 /**
157 * Determines if a tax rate exists in the database. Result is indefinitely cached.
158 *
159 * @return bool
160 */
161 private function has_existing_tax_rates() {
162 global $wpdb;
163 $has_existing_tax_rates = wp_cache_get( self::TAX_RATE_EXISTS_CACHE_KEY );
164 if ( false === $has_existing_tax_rates ) {
165 $rate_exists = (bool) $wpdb->get_var( "SELECT 1 FROM {$wpdb->prefix}woocommerce_tax_rates limit 1" );
166 $has_existing_tax_rates = $rate_exists ? 'yes' : 'no';
167 wp_cache_set( self::TAX_RATE_EXISTS_CACHE_KEY, $has_existing_tax_rates );
168 }
169
170 return 'yes' === $has_existing_tax_rates;
171 }
172
173 /**
174 * Marks the task as actioned any time a tax rate has been added. Called from the `woocommerce_tax_rate_added` hook.
175 *
176 * @return void
177 */
178 public function on_tax_rate_added() {
179 $this->mark_actioned();
180 wp_cache_set( self::TAX_RATE_EXISTS_CACHE_KEY, 'yes' );
181 }
182
183 /**
184 * Clears the tax rate exists cache when a tax rate is deleted. Called from the `woocommerce_tax_rate_added` hook.
185 *
186 * @return void
187 */
188 public function on_tax_rate_deleted() {
189 wp_cache_delete( self::TAX_RATE_EXISTS_CACHE_KEY );
190 }
191
192 /**
193 * Additional data.
194 *
195 * @return array
196 */
197 public function get_additional_data() {
198 return array(
199 'avalara_activated' => PluginsHelper::is_plugin_active( 'woocommerce-avatax' ),
200 'tax_jar_activated' => class_exists( 'WC_Taxjar' ),
201 'stripe_tax_activated' => PluginsHelper::is_plugin_active( 'stripe-tax-for-woocommerce' ),
202 'woocommerce_tax_activated' => PluginsHelper::is_plugin_active( 'woocommerce-tax' ),
203 'woocommerce_shipping_activated' => PluginsHelper::is_plugin_active( 'woocommerce-shipping' ),
204 'woocommerce_tax_countries' => self::get_automated_support_countries(),
205 'stripe_tax_countries' => self::get_stripe_tax_support_countries(),
206 );
207 }
208
209 /**
210 * Check if the store has any enabled gateways.
211 *
212 * @return bool
213 */
214 public static function can_use_automated_taxes() {
215 if ( ! class_exists( 'WC_Taxjar' ) ) {
216 return false;
217 }
218
219 return in_array( WC()->countries->get_base_country(), self::get_automated_support_countries(), true );
220 }
221
222 /**
223 * Get an array of countries that support automated tax.
224 *
225 * @return array
226 */
227 public static function get_automated_support_countries() {
228 // https://developers.taxjar.com/api/reference/#countries .
229 $tax_supported_countries = array_merge(
230 array( 'US', 'CA', 'AU', 'GB' ),
231 WC()->countries->get_european_union_countries()
232 );
233
234 return $tax_supported_countries;
235 }
236
237 /**
238 * Get an array of countries that support Stripe tax.
239 *
240 * @return array
241 */
242 private static function get_stripe_tax_support_countries() {
243 // https://docs.stripe.com/tax/supported-countries#supported-countries accurate as of 2024-08-26.
244 // countries with remote sales not included.
245 return array(
246 'AU',
247 'AT',
248 'BE',
249 'BG',
250 'CA',
251 'HR',
252 'CY',
253 'CZ',
254 'DK',
255 'EE',
256 'FI',
257 'FR',
258 'DE',
259 'GR',
260 'HK',
261 'HU',
262 'IE',
263 'IT',
264 'JP',
265 'LV',
266 'LT',
267 'LU',
268 'MT',
269 'NL',
270 'NZ',
271 'NO',
272 'PL',
273 'PT',
274 'RO',
275 'SG',
276 'SK',
277 'SI',
278 'ES',
279 'SE',
280 'CH',
281 'AE',
282 'GB',
283 'US',
284 );
285 }
286 }
287