Passed
Push — master ( eaa771...59160c )
by Kiran
22:17 queued 16:33
created

get_company()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 4
nc 3
nop 1
dl 0
loc 10
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Processes taxes for a payment form submission.
4
 *
5
 */
6
7
defined( 'ABSPATH' ) || exit;
8
9
/**
10
 * Payment form submission taxes class
11
 *
12
 */
13
class GetPaid_Payment_Form_Submission_Taxes {
14
15
	/**
16
	 * Submission taxes.
17
	 * @var array
18
	 */
19
	public $taxes = array();
20
21
	/**
22
	 * Whether or not we should skip the taxes.
23
	 * @var bool
24
	 */
25
	protected $skip_taxes = false;
26
27
    /**
28
	 * Class constructor
29
	 *
30
	 * @param GetPaid_Payment_Form_Submission $submission
31
	 */
32
	public function __construct( $submission ) {
33
		// Validate VAT number.
34
		$this->validate_vat( $submission );
35
36
		if ( $this->skip_taxes ) {
37
			return;
38
		}
39
40
		foreach ( $submission->get_items() as $item ) {
41
			$this->process_item_tax( $item, $submission );
42
		}
43
44
		// Process any existing invoice taxes.
45
		if ( $submission->has_invoice() ) {
46
			$invoice = $submission->get_invoice();
47
			$invoice = $this->refresh_totals( $invoice, $submission );
48
49
			$this->taxes = array_replace( $invoice->get_taxes(), $this->taxes );
50
		}
51
	}
52
53
	/**
54
	 * Maybe process tax.
55
	 *
56
	 * @since 1.0.19
57
	 * @param GetPaid_Form_Item $item
58
	 * @param GetPaid_Payment_Form_Submission $submission
59
	 */
60
	public function process_item_tax( $item, $submission ) {
61
62
		$rates    = getpaid_get_item_tax_rates( $item, $submission->country, $submission->state );
63
		$rates    = getpaid_filter_item_tax_rates( $item, $rates );
64
		$taxes    = getpaid_calculate_item_taxes( getpaid_get_taxable_amount( $item, false ), $rates );
0 ignored issues
show
Bug introduced by
getpaid_get_taxable_amount($item, false) of type string is incompatible with the type double expected by parameter $amount of getpaid_calculate_item_taxes(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

64
		$taxes    = getpaid_calculate_item_taxes( /** @scrutinizer ignore-type */ getpaid_get_taxable_amount( $item, false ), $rates );
Loading history...
Bug introduced by
false of type false is incompatible with the type string expected by parameter $recurring of getpaid_get_taxable_amount(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

64
		$taxes    = getpaid_calculate_item_taxes( getpaid_get_taxable_amount( $item, /** @scrutinizer ignore-type */ false ), $rates );
Loading history...
65
		$r_taxes  = getpaid_calculate_item_taxes( getpaid_get_taxable_amount( $item, true ), $rates );
0 ignored issues
show
Bug introduced by
true of type true is incompatible with the type string expected by parameter $recurring of getpaid_get_taxable_amount(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

65
		$r_taxes  = getpaid_calculate_item_taxes( getpaid_get_taxable_amount( $item, /** @scrutinizer ignore-type */ true ), $rates );
Loading history...
66
67
		foreach ( $taxes as $name => $amount ) {
68
			$recurring = isset( $r_taxes[ $name ] ) ? $r_taxes[ $name ] : 0;
69
			$tax       = getpaid_prepare_item_tax( $item, $name, $amount, $recurring );
70
71
			$item->item_tax += wpinv_sanitize_amount( $tax['initial_tax'] );
72
73
			if ( ! isset( $this->taxes[ $name ] ) ) {
74
				$this->taxes[ $name ] = $tax;
75
				continue;
76
			}
77
78
			$this->taxes[ $name ]['initial_tax']   += $tax['initial_tax'];
79
			$this->taxes[ $name ]['recurring_tax'] += $tax['recurring_tax'];
80
81
		}
82
83
	}
84
85
	/**
86
	 * Checks if the submission has a digital item.
87
	 *
88
	 * @param GetPaid_Payment_Form_Submission $submission
89
	 * @since 1.0.19
90
	 * @return bool
91
	 */
92
	public function has_digital_item( $submission ) {
93
94
		foreach ( $submission->get_items() as $item ) {
95
96
			if ( 'digital' == $item->get_vat_rule() ) {
97
				return true;
98
			}
99
}
100
101
		return false;
102
	}
103
104
	/**
105
	 * Checks if this is an eu store.
106
	 *
107
	 * @since 1.0.19
108
	 * @return bool
109
	 */
110
	public static function is_eu_store() {
111
		return self::is_eu_country( wpinv_get_default_country() );
112
	}
113
114
	/**
115
	 * Checks if this is an eu country.
116
	 *
117
	 * @param string $country
118
	 * @since 1.0.19
119
	 * @return bool
120
	 */
121
	public static function is_eu_country( $country ) {
122
		return getpaid_is_eu_state( $country );
123
	}
124
125
	/**
126
	 * Checks if this is an eu purchase.
127
	 *
128
	 * @param string $customer_country
129
	 * @since 1.0.19
130
	 * @return bool
131
	 */
132
	public static function is_eu_transaction( $customer_country ) {
133
		return self::is_eu_country( $customer_country ) && self::is_eu_store();
134
	}
135
136
	/**
137
	 * Retrieves the vat number.
138
	 *
139
	 * @param GetPaid_Payment_Form_Submission $submission
140
	 * @since 1.0.19
141
	 * @return string
142
	 */
143
	public function get_vat_number( $submission ) {
144
145
		// Retrieve from the posted number.
146
		$vat_number = $submission->get_field( 'wpinv_vat_number', 'billing' );
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $vat_number is correct as $submission->get_field('...vat_number', 'billing') targeting GetPaid_Payment_Form_Submission::get_field() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
147
		if ( ! is_null( $vat_number ) ) {
0 ignored issues
show
introduced by
The condition is_null($vat_number) is always true.
Loading history...
148
			return wpinv_clean( $vat_number );
149
		}
150
151
		return $submission->has_invoice() ? $submission->get_invoice()->get_vat_number() : '';
152
	}
153
154
	/**
155
	 * Retrieves the company.
156
	 *
157
	 * @param GetPaid_Payment_Form_Submission $submission
158
	 * @since 1.0.19
159
	 * @return string
160
	 */
161
	public function get_company( $submission ) {
162
163
		// Retrieve from the posted data.
164
		$company = $submission->get_field( 'wpinv_company', 'billing' );
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $company is correct as $submission->get_field('...nv_company', 'billing') targeting GetPaid_Payment_Form_Submission::get_field() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
165
		if ( ! empty( $company ) ) {
166
			return wpinv_clean( $company );
0 ignored issues
show
Bug Best Practice introduced by
The expression return wpinv_clean($company) also could return the type array which is incompatible with the documented return type string.
Loading history...
167
		}
168
169
		// Retrieve from the invoice.
170
		return $submission->has_invoice() ? $submission->get_invoice()->get_company() : '';
171
	}
172
173
	/**
174
	 * Checks if we require a VAT number.
175
	 *
176
	 * @param bool $ip_in_eu Whether the customer IP is from the EU
177
	 * @param bool $country_in_eu Whether the customer country is from the EU
178
	 * @since 1.0.19
179
	 * @return string
180
	 */
181
	public function requires_vat( $ip_in_eu, $country_in_eu ) {
182
183
		$prevent_b2c = wpinv_get_option( 'vat_prevent_b2c_purchase' );
184
		$prevent_b2c = ! empty( $prevent_b2c );
185
		$is_eu       = $ip_in_eu || $country_in_eu;
186
187
		return $prevent_b2c && $is_eu;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $prevent_b2c && $is_eu returns the type boolean which is incompatible with the documented return type string.
Loading history...
188
	}
189
190
	/**
191
	 * Validate VAT data.
192
	 *
193
	 * @param GetPaid_Payment_Form_Submission $submission
194
	 * @since 1.0.19
195
	 */
196
	public function validate_vat( $submission ) {
197
198
		$in_eu = $this->is_eu_transaction( $submission->country );
199
200
		// Abort if we are not validating vat numbers.
201
		if ( ! $in_eu ) {
202
            return;
203
		}
204
205
		// Prepare variables.
206
		$vat_number  = $this->get_vat_number( $submission );
207
		$ip_country  = getpaid_get_ip_country();
208
        $is_eu       = $this->is_eu_country( $submission->country );
209
        $is_ip_eu    = $this->is_eu_country( $ip_country );
210
211
		// Maybe abort early for initial fetches.
212
		if ( $submission->is_initial_fetch() && empty( $vat_number ) ) {
213
			return;
214
		}
215
216
		// If we're preventing business to consumer purchases,
217
		if ( $this->requires_vat( $is_ip_eu, $is_eu ) && empty( $vat_number ) ) {
218
219
			// Ensure that a vat number has been specified.
220
			throw new GetPaid_Payment_Exception( '.getpaid-error-billingwpinv_vat_number.getpaid-custom-payment-form-errors', __( 'Please enter your VAT number to verify your purchase is by an EU business.', 'invoicing' ) );
221
222
		}
223
224
		if ( empty( $vat_number ) ) {
225
			return;
226
		}
227
228
		if ( wpinv_should_validate_vat_number() && ! wpinv_validate_vat_number( $vat_number, $submission->country ) ) {
229
			throw new GetPaid_Payment_Exception( '.getpaid-error-billingwpinv_vat_number.getpaid-custom-payment-form-errors', __( 'Your VAT number is invalid', 'invoicing' ) );
230
		}
231
232
		if ( wpinv_default_billing_country() == $submission->country && 'vat_too' == wpinv_get_option( 'vat_same_country_rule', 'vat_too' ) ) {
233
			return;
234
		}
235
236
		$this->skip_taxes = true;
237
	}
238
239
	 /**
240
	 * Refresh totals if country or region changed in payment form.
241
	 *
242
	 * @since 2.8.8
243
	 *
244
	 * @param object $invoice Invoice object.
245
	 * @param GetPaid_Payment_Form_Submission $submission Payment form submission object.
246
	 * @return object Invoice object.
247
	 */
248
	public function refresh_totals( $invoice, $submission ) {
249
		if ( ! ( ! empty( $_POST['action'] ) && ( $_POST['action'] == 'wpinv_payment_form_refresh_prices' || $_POST['action'] == 'wpinv_payment_form' ) && isset( $_POST['billing']['wpinv_country'] ) ) ) {
250
			return $invoice;
251
		}
252
253
		if ( ! ( ! $invoice->is_paid() && ! $invoice->is_refunded() && ! $invoice->is_held() ) ) {
254
			return $invoice;
255
		}
256
257
		// Maybe check the country, state.
258
		if ( $submission->country != $invoice->get_country() || $submission->state != $invoice->get_state() ) {
259
			$invoice->set_country( sanitize_text_field( $submission->country ) );
260
			$invoice->set_state( sanitize_text_field( $submission->state ) );
261
262
			// Recalculate totals.
263
			$invoice->recalculate_total();
264
		}
265
266
		return $invoice;
267
	}
268
}
269