get_tax_rates(); } /** * Returns a given tax category * * @since 2.0.0 * @param string $tax_category The tax category to retrieve. * @return array */ function wu_get_tax_category($tax_category = 'default') { $tax_categories = wu_get_tax_categories(); return wu_get_isset( $tax_categories, $tax_category, [ 'rates' => [], ] ); } /** * Returns the tax categories as a slug => name array. * * @since 2.0.0 */ function wu_get_tax_categories_as_options(): array { return array_map(fn($item) => $item['name'], wu_get_tax_categories()); } /** * Calculates the tax value. * * @since 2.0.0 * * @param float $base_price Original price to calculate based upon. * @param float $amount Tax amount. * @param string $type Type of the tax, can be percentage or absolute. * @param boolean $format If we should format the results or not. * @param boolean $inclusive If we should calculate taxes as inclusive. * @return float|string */ function wu_get_tax_amount($base_price, $amount, $type, $format = true, $inclusive = false) { /* * If the tax is an absolute (type == absolute) value, there's nothing * to do, pretty much. */ $tax_total = $amount; if ('percentage' === $type) { if ( ! $inclusive) { /** * Exclusive tax * * Calculates tax to be ADDED to the order. */ $tax_total = $base_price * ($amount / 100); } else { /** * Inclusive tax * * Calculates the tax value inside the total price. */ $tax_total = $base_price - ($base_price / (1 + ($amount / 100))); } } /* * Return results */ if ( ! $format) { return round($tax_total, 2); } return number_format((float) $tax_total, 2); } /** * Searches for applicable tax rates based on the country. * * @todo This can be greatly improved and should support multiple rates * in the future. * * @since 2.0.0 * * @param string $country The country to search for. * @param string $tax_category The tax category of the product. * @param string $state The state to filter by. * @param string $city The city to filter by. * @return array */ function wu_get_applicable_tax_rates($country, $tax_category = 'default', $state = '*', $city = '*') { if ( ! $country) { return []; } $tax_category = wu_get_tax_category($tax_category); $results = []; foreach ($tax_category['rates'] as &$rate) { /* * Step 0: Prepare. */ $rate['state'] = explode(',', (string) $rate['state']); $rate['city'] = explode(',', (string) $rate['city']); $keys_of_interest = array_intersect_key( $rate, [ 'country' => 1, 'state' => 1, 'city' => 1, ] ); $priority = 0; foreach ($keys_of_interest as $key => $value) { $value = is_array($value) ? array_filter($value) : trim((string) $value); /* * Step 1: The country. */ if ('country' === $key && $rate['country'] === $country) { $priority += 10; } /* * Step 2: The state / province */ if ('state' === $key && '*' !== $state) { if (in_array($state, $value, true)) { $priority += 1; } elseif (empty($value) || in_array('*', $value, true)) { $priority += 0.5; } } /* * Step 3: The city */ if ('city' === $key && '*' !== $city) { if (in_array($city, $value, true)) { /* * If it's a full match, gives 1 point. */ $priority += 1; } elseif (empty($value) || in_array('*', $value, true)) { /* * If it is a wildcard, award half a point. */ $priority += 0.5; } } } if ($priority >= 10) { $rate['order'] = $priority; $results[ $rate['id'] ] = $rate; } } uasort($results, 'wu_sort_by_order'); return array_values($results); }