AyeCode /
invoicing
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
| 1 | <?php |
||||
| 2 | /** |
||||
| 3 | * Contains the main tax class. |
||||
| 4 | * |
||||
| 5 | * |
||||
| 6 | */ |
||||
| 7 | |||||
| 8 | defined( 'ABSPATH' ) || exit; |
||||
| 9 | |||||
| 10 | /** |
||||
| 11 | * Class GetPaid_Tax |
||||
| 12 | * |
||||
| 13 | */ |
||||
| 14 | class GetPaid_Tax { |
||||
| 15 | |||||
| 16 | /** |
||||
| 17 | * Calculates tax for a line item. |
||||
| 18 | * |
||||
| 19 | * @param float $price The price to calc tax on. |
||||
| 20 | * @param array $rates The rates to apply. |
||||
| 21 | * @param boolean $price_includes_tax Whether the passed price has taxes included. |
||||
| 22 | * @return array Array of tax name => tax amount. |
||||
| 23 | */ |
||||
| 24 | public static function calc_tax( $price, $rates, $price_includes_tax = false ) { |
||||
| 25 | |||||
| 26 | if ( $price_includes_tax ) { |
||||
| 27 | $taxes = self::calc_inclusive_tax( $price, $rates ); |
||||
| 28 | } else { |
||||
| 29 | $taxes = self::calc_exclusive_tax( $price, $rates ); |
||||
| 30 | } |
||||
| 31 | |||||
| 32 | return apply_filters( 'getpaid_calc_tax', $taxes, $price, $rates, $price_includes_tax ); |
||||
| 33 | |||||
| 34 | } |
||||
| 35 | |||||
| 36 | /** |
||||
| 37 | * Calc tax from inclusive price. |
||||
| 38 | * |
||||
| 39 | * @param float $price Price to calculate tax for. |
||||
| 40 | * @param array $rates Array of tax rates. |
||||
| 41 | * @return array |
||||
| 42 | */ |
||||
| 43 | public static function calc_inclusive_tax( $price, $rates ) { |
||||
| 44 | $taxes = array(); |
||||
| 45 | $tax_rates = wp_list_pluck( $rates, 'rate', 'name' ); |
||||
| 46 | |||||
| 47 | // Add tax rates. |
||||
| 48 | $tax_rate = 1 + ( array_sum( $tax_rates ) / 100 ); |
||||
| 49 | |||||
| 50 | foreach ( $tax_rates as $name => $rate ) { |
||||
| 51 | $the_rate = ( $rate / 100 ) / $tax_rate; |
||||
| 52 | $net_price = $price - ( $the_rate * $price ); |
||||
| 53 | $tax_amount = apply_filters( 'getpaid_price_inc_tax_amount', $price - $net_price, $name, $rate, $price ); |
||||
| 54 | $taxes[ $name ] = $tax_amount; |
||||
| 55 | } |
||||
| 56 | |||||
| 57 | // Round all taxes to precision (4DP) before passing them back. |
||||
| 58 | $taxes = array_map( array( __CLASS__, 'round' ), $taxes ); |
||||
| 59 | |||||
| 60 | return $taxes; |
||||
| 61 | } |
||||
| 62 | |||||
| 63 | /** |
||||
| 64 | * Calc tax from exclusive price. |
||||
| 65 | * |
||||
| 66 | * @param float $price Price to calculate tax for. |
||||
| 67 | * @param array $rates Array of tax rates. |
||||
| 68 | * @return array |
||||
| 69 | */ |
||||
| 70 | public static function calc_exclusive_tax( $price, $rates ) { |
||||
| 71 | $taxes = array(); |
||||
| 72 | $tax_rates = wp_list_pluck( $rates, 'rate', 'name' ); |
||||
| 73 | |||||
| 74 | foreach ( $tax_rates as $name => $rate ) { |
||||
| 75 | |||||
| 76 | $tax_amount = $price * ( $rate / 100 ); |
||||
| 77 | $taxes[ $name ] = apply_filters( 'getpaid_price_ex_tax_amount', $tax_amount, $name, $rate, $price ); |
||||
| 78 | |||||
| 79 | } |
||||
| 80 | |||||
| 81 | // Round all taxes to precision (4DP) before passing them back. |
||||
| 82 | $taxes = array_map( array( __CLASS__, 'round' ), $taxes ); |
||||
| 83 | |||||
| 84 | return $taxes; |
||||
| 85 | } |
||||
| 86 | |||||
| 87 | /** |
||||
| 88 | * Get's an array of all tax rates. |
||||
| 89 | * |
||||
| 90 | * @return array |
||||
| 91 | */ |
||||
| 92 | public static function get_all_tax_rates() { |
||||
| 93 | |||||
| 94 | $rates = get_option( 'wpinv_tax_rates', array() ); |
||||
| 95 | |||||
| 96 | return apply_filters( |
||||
| 97 | 'getpaid_get_all_tax_rates', |
||||
| 98 | array_filter( wpinv_parse_list( $rates ) ) |
||||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||
| 99 | ); |
||||
| 100 | |||||
| 101 | } |
||||
| 102 | |||||
| 103 | /** |
||||
| 104 | * Get's an array of default tax rates. |
||||
| 105 | * |
||||
| 106 | * @return array |
||||
| 107 | */ |
||||
| 108 | public static function get_default_tax_rates() { |
||||
| 109 | |||||
| 110 | return apply_filters( |
||||
| 111 | 'getpaid_get_default_tax_rates', |
||||
| 112 | array( |
||||
| 113 | array( |
||||
| 114 | 'country' => wpinv_get_default_country(), |
||||
| 115 | 'state' => wpinv_get_default_state(), |
||||
| 116 | 'global' => true, |
||||
| 117 | 'rate' => wpinv_get_default_tax_rate(), |
||||
| 118 | 'name' => __( 'Tax', 'invoicing' ), |
||||
| 119 | ), |
||||
| 120 | ) |
||||
| 121 | ); |
||||
| 122 | |||||
| 123 | } |
||||
| 124 | |||||
| 125 | /** |
||||
| 126 | * Get's an array of all tax rules. |
||||
| 127 | * |
||||
| 128 | * @return array |
||||
| 129 | */ |
||||
| 130 | public static function get_all_tax_rules() { |
||||
| 131 | |||||
| 132 | $rules = get_option( |
||||
| 133 | 'wpinv_tax_rules', |
||||
| 134 | array( |
||||
| 135 | array( |
||||
| 136 | 'key' => 'physical', |
||||
| 137 | 'label' => __( 'Physical Item', 'invoicing' ), |
||||
| 138 | 'tax_base' => wpinv_get_option( 'tax_base', 'billing' ), |
||||
| 139 | 'same_country_rule' => wpinv_get_option( 'vat_same_country_rule', 'vat_too' ), |
||||
| 140 | ), |
||||
| 141 | array( |
||||
| 142 | 'key' => 'digital', |
||||
| 143 | 'label' => __( 'Digital Item', 'invoicing' ), |
||||
| 144 | 'tax_base' => wpinv_get_option( 'tax_base', 'billing' ), |
||||
| 145 | 'same_country_rule' => wpinv_get_option( 'vat_same_country_rule', 'vat_too' ), |
||||
| 146 | ), |
||||
| 147 | ) |
||||
| 148 | ); |
||||
| 149 | |||||
| 150 | return apply_filters( |
||||
| 151 | 'getpaid_tax_rules', |
||||
| 152 | array_filter( array_values( wpinv_parse_list( $rules ) ) ) |
||||
|
0 ignored issues
–
show
It seems like
$rules can also be of type false; however, parameter $list of wpinv_parse_list() does only seem to accept array|string, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 153 | ); |
||||
| 154 | |||||
| 155 | } |
||||
| 156 | |||||
| 157 | /** |
||||
| 158 | * Get's an array of tax rates for a given address. |
||||
| 159 | * |
||||
| 160 | * @param string $country |
||||
| 161 | * @param string $state |
||||
| 162 | * @return array |
||||
| 163 | */ |
||||
| 164 | public static function get_address_tax_rates( $country, $state ) { |
||||
| 165 | |||||
| 166 | $all_tax_rates = self::get_all_tax_rates(); |
||||
| 167 | $matching_rates = array_merge( |
||||
| 168 | wp_list_filter( $all_tax_rates, array( 'country' => $country ) ), |
||||
| 169 | wp_list_filter( $all_tax_rates, array( 'country' => '' ) ) |
||||
| 170 | ); |
||||
| 171 | |||||
| 172 | foreach ( $matching_rates as $i => $rate ) { |
||||
| 173 | |||||
| 174 | $states = array_filter( wpinv_clean( explode( ',', strtolower( $rate['state'] ) ) ) ); |
||||
| 175 | if ( empty( $rate['global'] ) && ! in_array( strtolower( $state ), $states ) ) { |
||||
| 176 | unset( $matching_rates[ $i ] ); |
||||
| 177 | } |
||||
| 178 | } |
||||
| 179 | |||||
| 180 | return apply_filters( 'getpaid_get_address_tax_rates', $matching_rates, $country, $state ); |
||||
| 181 | |||||
| 182 | } |
||||
| 183 | |||||
| 184 | /** |
||||
| 185 | * Sums a set of taxes to form a single total. Result is rounded to precision. |
||||
| 186 | * |
||||
| 187 | * @param array $taxes Array of taxes. |
||||
| 188 | * @return float |
||||
| 189 | */ |
||||
| 190 | public static function get_tax_total( $taxes ) { |
||||
| 191 | return self::round( array_sum( $taxes ) ); |
||||
| 192 | } |
||||
| 193 | |||||
| 194 | /** |
||||
| 195 | * Round to precision. |
||||
| 196 | * |
||||
| 197 | * Filter example: to return rounding to .5 cents you'd use: |
||||
| 198 | * |
||||
| 199 | * function euro_5cent_rounding( $in ) { |
||||
| 200 | * return round( $in / 5, 2 ) * 5; |
||||
| 201 | * } |
||||
| 202 | * add_filter( 'getpaid_tax_round', 'euro_5cent_rounding' ); |
||||
| 203 | * |
||||
| 204 | * @param float|int $in Value to round. |
||||
| 205 | * @return float |
||||
| 206 | */ |
||||
| 207 | public static function round( $in ) { |
||||
| 208 | return apply_filters( 'getpaid_tax_round', round( $in, 4 ), $in ); |
||||
| 209 | } |
||||
| 210 | |||||
| 211 | } |
||||
| 212 |