Passed
Push — master ( 83c95e...e10ac3 )
by Brian
04:25
created

__construct()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 16
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 7
c 1
b 0
f 0
nc 5
nop 1
dl 0
loc 16
rs 10
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
34
		// Validate VAT number.
35
		$this->validate_vat( $submission );
36
37
		if ( $this->skip_taxes ) {
38
			return;
39
		}
40
41
		foreach ( $submission->get_items() as $item ) {
42
			$this->process_item_tax( $item, $submission );
43
		}
44
45
		// Process any existing invoice taxes.
46
		if ( $submission->has_invoice() ) {
47
			$this->taxes = array_replace( $submission->get_invoice()->get_taxes(), $this->taxes );
48
		}
49
50
	}
51
52
	/**
53
	 * Maybe process tax.
54
	 *
55
	 * @since 1.0.19
56
	 * @param GetPaid_Form_Item $item
57
	 * @param GetPaid_Payment_Form_Submission $submission
58
	 */
59
	public function process_item_tax( $item, $submission ) {
60
61
		$rates    = getpaid_get_item_tax_rates( $item, $submission->country, $submission->state );
62
		$rates    = getpaid_filter_item_tax_rates( $item, $rates );
63
		$taxes    = getpaid_calculate_item_taxes( $item->get_sub_total(), $rates );
64
		$r_taxes  = getpaid_calculate_item_taxes( $item->get_recurring_sub_total(), $rates );
65
66
		foreach ( $taxes as $name => $amount ) {
67
			$recurring = isset( $r_taxes[ $name ] ) ? $r_taxes[ $name ] : 0;
68
			$tax       = getpaid_prepare_item_tax( $item, $name, $amount, $recurring );
69
70
			if ( ! isset( $this->taxes[ $name ] ) ) {
71
				$this->taxes[ $name ] = $tax;
72
				continue;
73
			}
74
75
			$this->taxes[ $name ]['initial_tax']   += $tax['initial_tax'];
76
			$this->taxes[ $name ]['recurring_tax'] += $tax['recurring_tax'];
77
78
		}
79
80
	}
81
82
	/**
83
	 * Checks if the submission has a digital item.
84
	 *
85
	 * @param GetPaid_Payment_Form_Submission $submission
86
	 * @since 1.0.19
87
	 * @return bool
88
	 */
89
	public function has_digital_item( $submission ) {
90
91
		foreach ( $submission->get_items() as $item ) {
92
93
			if ( 'digital' == $item->get_vat_rule() ) {
94
				return true;
95
			}
96
97
		}
98
99
		return false;
100
	}
101
102
	/**
103
	 * Checks if this is an eu store.
104
	 *
105
	 * @since 1.0.19
106
	 * @return bool
107
	 */
108
	public function is_eu_store() {
109
		return $this->is_eu_country( wpinv_get_default_country() );
110
	}
111
112
	/**
113
	 * Checks if this is an eu country.
114
	 *
115
	 * @param string $country
116
	 * @since 1.0.19
117
	 * @return bool
118
	 */
119
	public function is_eu_country( $country ) {
120
		return getpaid_is_eu_state( $country ) || getpaid_is_gst_country( $country );
121
	}
122
123
	/**
124
	 * Checks if this is an eu purchase.
125
	 *
126
	 * @param string $customer_country
127
	 * @since 1.0.19
128
	 * @return bool
129
	 */
130
	public function is_eu_transaction( $customer_country ) {
131
		return $this->is_eu_country( $customer_country ) && $this->is_eu_store();
132
	}
133
134
	/**
135
	 * Retrieves the vat number.
136
	 *
137
	 * @param GetPaid_Payment_Form_Submission $submission
138
	 * @since 1.0.19
139
	 * @return string
140
	 */
141
	public function get_vat_number( $submission ) {
142
143
		// Retrieve from the posted number.
144
		$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...
145
		if ( ! empty( $vat_number ) ) {
146
			return wpinv_clean( $vat_number );
0 ignored issues
show
Bug Best Practice introduced by
The expression return wpinv_clean($vat_number) also could return the type array which is incompatible with the documented return type string.
Loading history...
147
		}
148
149
		// Retrieve from the invoice.
150
		return $submission->has_invoice() ? $submission->get_invoice()->get_vat_number() : '';
151
	}
152
153
	/**
154
	 * Retrieves the company.
155
	 *
156
	 * @param GetPaid_Payment_Form_Submission $submission
157
	 * @since 1.0.19
158
	 * @return string
159
	 */
160
	public function get_company( $submission ) {
161
162
		// Retrieve from the posted data.
163
		$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...
164
		if ( ! empty( $company ) ) {
165
			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...
166
		}
167
168
		// Retrieve from the invoice.
169
		return $submission->has_invoice() ? $submission->get_invoice()->get_company() : '';
170
	}
171
172
	/**
173
	 * Checks if we require a VAT number.
174
	 *
175
	 * @param bool $ip_in_eu Whether the customer IP is from the EU
176
	 * @param bool $country_in_eu Whether the customer country is from the EU
177
	 * @since 1.0.19
178
	 * @return string
179
	 */
180
	public function requires_vat( $ip_in_eu, $country_in_eu ) {
181
182
		$prevent_b2c = wpinv_get_option( 'vat_prevent_b2c_purchase' );
183
		$prevent_b2c = ! empty( $prevent_b2c );
184
		$is_eu       = $ip_in_eu || $country_in_eu;
185
186
		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...
187
	}
188
189
	/**
190
	 * Validate VAT data.
191
	 *
192
	 * @param GetPaid_Payment_Form_Submission $submission
193
	 * @since 1.0.19
194
	 */
195
	public function validate_vat( $submission ) {
196
197
		$in_eu = $this->is_eu_transaction( $submission->country );
198
199
		// Abort if we are not validating vat numbers.
200
		if ( ! $in_eu || ! wpinv_should_validate_vat_number() ) {
201
            return;
202
		}
203
204
		// Prepare variables.
205
		$vat_number  = $this->get_vat_number( $submission );
206
		$ip_country  = getpaid_get_ip_country();
207
        $is_eu       = $this->is_eu_country( $submission->country );
208
        $is_ip_eu    = $this->is_eu_country( $ip_country );
209
210
		// If we're preventing business to consumer purchases,
211
		if ( $this->requires_vat( $is_ip_eu, $is_eu ) && empty( $vat_number ) ) {
212
213
			// Ensure that a vat number has been specified.
214
			throw new Exception(
215
				__( 'Please enter your VAT number to verify your purchase is by an EU business.', 'invoicing' )
216
			);
217
218
		}
219
220
		if ( empty( $vat_number ) ) {
221
			return;
222
		}
223
224
		if ( ! wpinv_validate_vat_number( $vat_number, $submission->country ) ) {
225
			throw new Exception( __( 'Your VAT number is invalid', 'invoicing' ) );
226
		}
227
228
		if ( 'vat_too' != wpinv_get_option( 'vat_same_country_rule' ) ) {
229
			$this->skip_taxes = true;
230
		}
231
232
	}
233
234
}
235