Passed
Push — master ( d57609...3cea45 )
by Brian
05:00
created

GetPaid_Payment_Form_Submission_Taxes   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 207
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 54
c 1
b 0
f 0
dl 0
loc 207
rs 10
wmc 30

10 Methods

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