Escape everything that should be escaped. Add nonce checks where needed. Sanitize all inputs. Apply Code style changes across the codebase. Correct many deprecation notices. Optimize load order of many filters.
418 lines
9.3 KiB
PHP
418 lines
9.3 KiB
PHP
<?php
|
|
/**
|
|
* WP Multisite WaaS Tax Class.
|
|
*
|
|
* @package WP_Ultimo
|
|
* @subpackage Tax
|
|
* @since 2.0.0
|
|
*/
|
|
|
|
namespace WP_Ultimo\Tax;
|
|
|
|
// Exit if accessed directly
|
|
defined('ABSPATH') || exit;
|
|
|
|
/**
|
|
* WP Multisite WaaS Tax Class.
|
|
*
|
|
* @since 2.0.0
|
|
*/
|
|
class Tax {
|
|
|
|
use \WP_Ultimo\Traits\Singleton;
|
|
|
|
/**
|
|
* Adds hooks to be added at the original instantiations.
|
|
*
|
|
* @since 1.9.0
|
|
*/
|
|
public function init(): void {
|
|
|
|
add_action('init', [$this, 'add_settings']);
|
|
|
|
add_action('wu_page_wp-ultimo-settings_load', [$this, 'add_sidebar_widget']);
|
|
|
|
if ($this->is_enabled()) {
|
|
add_action('wp_ultimo_admin_pages', [$this, 'add_admin_page']);
|
|
|
|
add_action('wp_ajax_wu_get_tax_rates', [$this, 'serve_taxes_rates_via_ajax']);
|
|
|
|
add_action('wp_ajax_wu_save_tax_rates', [$this, 'save_taxes_rates']);
|
|
|
|
add_action(
|
|
'wu_before_search_models',
|
|
function () {
|
|
|
|
$model = wu_request('model', 'state');
|
|
|
|
$country = wu_request('country', 'not-present');
|
|
|
|
if ('not-present' === $country) {
|
|
return;
|
|
}
|
|
|
|
if ('state' === $model) {
|
|
$results = wu_get_country_states($country, 'slug', 'name');
|
|
} elseif ('city' === $model) {
|
|
$states = explode(',', (string) wu_request('state', ''));
|
|
|
|
$results = wu_get_country_cities($country, $states, 'slug', 'name');
|
|
}
|
|
|
|
$query = wu_request(
|
|
'query',
|
|
[
|
|
'search' => 'searching....',
|
|
]
|
|
);
|
|
|
|
$s = trim((string) wu_get_isset($query, 'search', 'searching...'), '*');
|
|
|
|
$filtered = [];
|
|
|
|
if ( ! empty($s)) {
|
|
$filtered = \Arrch\Arrch::find(
|
|
$results,
|
|
[
|
|
'sort_key' => 'name',
|
|
'where' => [
|
|
[['slug', 'name'], '~', $s],
|
|
],
|
|
]
|
|
);
|
|
}
|
|
|
|
wp_send_json(array_values($filtered));
|
|
|
|
exit;
|
|
}
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Register tax settings.
|
|
*
|
|
* @since 2.0.0
|
|
* @return void
|
|
*/
|
|
public function add_settings(): void {
|
|
|
|
wu_register_settings_section(
|
|
'taxes',
|
|
[
|
|
'title' => __('Taxes', 'wp-multisite-waas'),
|
|
'desc' => __('Taxes', 'wp-multisite-waas'),
|
|
'icon' => 'dashicons-wu-percent',
|
|
'order' => 55,
|
|
]
|
|
);
|
|
|
|
wu_register_settings_field(
|
|
'taxes',
|
|
'enable_taxes',
|
|
[
|
|
'title' => __('Enable Taxes', 'wp-multisite-waas'),
|
|
'desc' => __('Enable this option to be able to collect sales taxes on your network payments.', 'wp-multisite-waas'),
|
|
'type' => 'toggle',
|
|
'default' => 0,
|
|
]
|
|
);
|
|
|
|
wu_register_settings_field(
|
|
'taxes',
|
|
'inclusive_tax',
|
|
[
|
|
'title' => __('Inclusive Tax', 'wp-multisite-waas'),
|
|
'desc' => __('Enable this option if your prices include taxes. In that case, WP Multisite WaaS will calculate the included tax instead of adding taxes to the price.', 'wp-multisite-waas'),
|
|
'type' => 'toggle',
|
|
'default' => 0,
|
|
'require' => [
|
|
'enable_taxes' => 1,
|
|
],
|
|
]
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Adds the sidebar widget.
|
|
*
|
|
* @since 2.0.0
|
|
* @return void
|
|
*/
|
|
public function add_sidebar_widget(): void {
|
|
|
|
wu_register_settings_side_panel(
|
|
'taxes',
|
|
[
|
|
'title' => __('Tax Rates', 'wp-multisite-waas'),
|
|
'render' => [$this, 'render_taxes_side_panel'],
|
|
]
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Checks if this functionality is available and should be loaded.
|
|
*
|
|
* @since 2.0.0
|
|
* @return boolean
|
|
*/
|
|
public function is_enabled() {
|
|
|
|
$is_enabled = wu_get_setting('enable_taxes', false);
|
|
|
|
return apply_filters('wu_enable_taxes', $is_enabled);
|
|
}
|
|
|
|
/**
|
|
* Adds the Tax Rate edit admin screen.
|
|
*
|
|
* @since 2.0.0
|
|
* @return void
|
|
*/
|
|
public function add_admin_page(): void {
|
|
|
|
new \WP_Ultimo\Admin_Pages\Tax_Rates_Admin_Page();
|
|
}
|
|
|
|
/**
|
|
* Returns the Tax Rate Types available in the platform; Filterable
|
|
*
|
|
* @since 2.0.0
|
|
* @return array
|
|
*/
|
|
public function get_tax_rate_types() {
|
|
|
|
return apply_filters(
|
|
'wu_get_tax_rate_types',
|
|
[
|
|
'regular' => __('Regular', 'wp-multisite-waas'),
|
|
]
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Returns the default elements of a tax rate.
|
|
*
|
|
* @since 2.0.0
|
|
* @return array
|
|
*/
|
|
public function get_tax_rate_defaults() {
|
|
|
|
$defaults = [
|
|
'id' => uniqid(),
|
|
'title' => __('Tax Rate', 'wp-multisite-waas'),
|
|
'country' => '',
|
|
'state' => '',
|
|
'city' => '',
|
|
'tax_type' => 'percentage',
|
|
'tax_amount' => 0,
|
|
'priority' => 10,
|
|
'compound' => false,
|
|
'type' => 'regular',
|
|
];
|
|
|
|
return apply_filters('wu_get_tax_rate_defaults', $defaults);
|
|
}
|
|
|
|
/**
|
|
* Returns the registered tax rates.
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @param bool $fetch_state_options If true, sends the state options along-side the results.
|
|
* @return array
|
|
*/
|
|
public function get_tax_rates($fetch_state_options = false) {
|
|
|
|
$tax_rates_categories = wu_get_option(
|
|
'tax_rates',
|
|
[
|
|
'default' => [
|
|
'name' => __('Default', 'wp-multisite-waas'),
|
|
'rates' => [],
|
|
],
|
|
]
|
|
);
|
|
|
|
if ( ! isset($tax_rates_categories['default'])) {
|
|
/**
|
|
* We need to make sure the default category is always present.
|
|
*/
|
|
$default = array_shift($tax_rates_categories);
|
|
|
|
$tax_rates_categories = array_merge(['default' => $default], $tax_rates_categories);
|
|
}
|
|
|
|
foreach ($tax_rates_categories as &$tax_rate_category) {
|
|
$tax_rate_category['rates'] = array_map(
|
|
function ($rate) use ($fetch_state_options) {
|
|
|
|
if ($fetch_state_options) {
|
|
$rate['state_options'] = wu_get_country_states($rate['country'], 'slug', 'name');
|
|
}
|
|
|
|
$rate['tax_rate'] = is_numeric($rate['tax_rate']) ? $rate['tax_rate'] : 0;
|
|
|
|
return wp_parse_args($rate, $this->get_tax_rate_defaults());
|
|
},
|
|
$tax_rate_category['rates']
|
|
);
|
|
}
|
|
|
|
return apply_filters('wu_get_tax_rates', $tax_rates_categories, $fetch_state_options);
|
|
}
|
|
|
|
/**
|
|
* Retrieves the tax rates to serve via ajax.
|
|
*
|
|
* @since 2.0.0
|
|
* @return void
|
|
*/
|
|
public function serve_taxes_rates_via_ajax(): void {
|
|
|
|
$tax_rates = [];
|
|
|
|
if (current_user_can('read_tax_rates')) {
|
|
$tax_rates = $this->get_tax_rates(true);
|
|
}
|
|
|
|
wp_send_json_success((object) $tax_rates);
|
|
}
|
|
|
|
/**
|
|
* Handles the saving of new tax rates.
|
|
*
|
|
* @since 2.0.0
|
|
* @return void
|
|
*/
|
|
public function save_taxes_rates(): void {
|
|
|
|
if ( ! check_ajax_referer('wu_tax_editing')) {
|
|
wp_send_json(
|
|
[
|
|
'code' => 'not-enough-permissions',
|
|
'message' => __('You don\'t have permission to alter tax rates', 'wp-multisite-waas'),
|
|
]
|
|
);
|
|
}
|
|
|
|
$data = json_decode(file_get_contents('php://input'), true);
|
|
|
|
$tax_rates = $data['tax_rates'] ?? false;
|
|
|
|
if ( ! $tax_rates) {
|
|
wp_send_json(
|
|
[
|
|
'code' => 'tax-rates-not-found',
|
|
'message' => __('No tax rates present in the request', 'wp-multisite-waas'),
|
|
]
|
|
);
|
|
}
|
|
|
|
$treated_tax_rates = [];
|
|
|
|
foreach ($tax_rates as $tax_rate_slug => $tax_rate) {
|
|
if ( ! isset($tax_rate['rates'])) {
|
|
continue;
|
|
}
|
|
|
|
$tax_rate['rates'] = array_map(
|
|
function ($item) {
|
|
|
|
unset($item['selected']);
|
|
|
|
unset($item['state_options']);
|
|
|
|
return $item;
|
|
},
|
|
$tax_rate['rates']
|
|
);
|
|
|
|
$treated_tax_rates[ strtolower(sanitize_title($tax_rate_slug)) ] = $tax_rate;
|
|
}
|
|
|
|
wu_save_option('tax_rates', $treated_tax_rates);
|
|
|
|
wp_send_json(
|
|
[
|
|
'code' => 'success',
|
|
'message' => __('Tax Rates successfully updated!', 'wp-multisite-waas'),
|
|
'tax_category' => strtolower(sanitize_title(wu_get_isset($data, 'tax_category', 'default'))),
|
|
]
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Render the tax side panel.
|
|
*
|
|
* @since 2.0.0
|
|
* @return void
|
|
*/
|
|
public function render_taxes_side_panel(): void {
|
|
?>
|
|
|
|
<div id="wu-taxes-side-panel" class="wu-widget-inset">
|
|
|
|
<div class="wu-p-4">
|
|
|
|
<span class="wu-text-gray-700 wu-font-bold wu-uppercase wu-tracking-wide wu-text-xs">
|
|
<?php esc_html_e('Manage Tax Rates', 'wp-multisite-waas'); ?>
|
|
</span>
|
|
|
|
<div class="wu-py-2">
|
|
<img class="wu-w-full" alt="<?php esc_attr_e('Manage Tax Rates', 'wp-multisite-waas'); ?>" src="<?php echo wu_get_asset('sidebar/invoices.webp'); ?>">
|
|
</div>
|
|
|
|
<p class="wu-text-gray-600 wu-p-0 wu-m-0">
|
|
<?php esc_html_e('Add different tax rates depending on the country of your customers.', 'wp-multisite-waas'); ?>
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div v-cloak v-show="enabled == 0" class="wu-mx-4 wu-p-2 wu-bg-blue-100 wu-text-blue-600 wu-rounded wu-mb-4">
|
|
<?php esc_html_e('You need to activate tax support first.', 'wp-multisite-waas'); ?>
|
|
</div>
|
|
|
|
<?php if (current_user_can('wu_edit_payments')) : ?>
|
|
|
|
<div class="wu-p-4 wu-bg-gray-100 wu-border-solid wu-border-0 wu-border-t wu-border-gray-300">
|
|
|
|
<span v-if="false" class="button wu-w-full wu-text-center">
|
|
<?php esc_html_e('Manage Tax Rates →', 'wp-multisite-waas'); ?>
|
|
</span>
|
|
|
|
<div v-cloak>
|
|
|
|
<a v-if="enabled" class="button wu-w-full wu-text-center" target="_blank" href="<?php echo wu_network_admin_url('wp-ultimo-tax-rates'); ?>">
|
|
<?php esc_html_e('Manage Tax Rates →', 'wp-multisite-waas'); ?>
|
|
</a>
|
|
|
|
<button v-else disabled="disabled" class="button wu-w-full wu-text-center">
|
|
<?php esc_html_e('Manage Tax Rates →', 'wp-multisite-waas'); ?>
|
|
</button>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<?php endif; ?>
|
|
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
new Vue({
|
|
el: "#wu-taxes-side-panel",
|
|
data: {},
|
|
computed: {
|
|
enabled: function() {
|
|
return <?php echo wp_json_encode(wu_get_setting('enable_taxes')); ?>
|
|
}
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
<?php
|
|
}
|
|
}
|