Passed
Pull Request — master (#377)
by Brian
06:57
created

WPInv_Invoice::set_company()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 2
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
// MUST have WordPress.
4
if ( !defined( 'WPINC' ) ) {
5
    exit( 'Do NOT access this file directly: ' . basename( __FILE__ ) );
6
}
7
8
/**
9
 * Invoice class.
10
 */
11
class WPInv_Invoice extends GetPaid_Data {
12
13
    /**
14
	 * Which data store to load.
15
	 *
16
	 * @var string
17
	 */
18
    protected $data_store_name = 'invoice';
19
20
    /**
21
	 * This is the name of this object type.
22
	 *
23
	 * @var string
24
	 */
25
    protected $object_type = 'invoice';
26
27
    /**
28
	 * Item Data array. This is the core item data exposed in APIs.
29
	 *
30
	 * @since 1.0.19
31
	 * @var array
32
	 */
33
	protected $data = array(
34
		'parent_id'            => 0,
35
		'status'               => 'wpi-pending',
36
		'version'              => '',
37
		'date_created'         => null,
38
        'date_modified'        => null,
39
        'due_date'             => null,
40
        'completed_date'       => null,
41
        'number'               => '',
42
        'title'                => '',
43
        'path'                 => '',
44
        'key'                  => '',
45
        'description'          => '',
46
        'author'               => 1,
47
        'type'                 => 'invoice',
48
        'post_type'            => 'wpi_invoice',
49
        'mode'                 => 'live',
50
        'user_ip'              => null,
51
        'first_name'           => null,
52
        'last_name'            => null,
53
        'phone'                => null,
54
        'email'                => null,
55
        'country'              => null,
56
        'city'                 => null,
57
        'state'                => null,
58
        'zip'                  => null,
59
        'company'              => null,
60
        'vat_number'           => null,
61
        'vat_rate'             => null,
62
        'address'              => null,
63
        'address_confirmed'    => false,
64
        'subtotal'             => 0,
65
        'total_discount'       => 0,
66
        'total_tax'            => 0,
67
        'total_fees'           => 0,
68
        'fees'                 => array(),
69
        'discounts'            => array(),
70
        'taxes'                => array(),
71
        'items'                => array(),
72
        'payment_form'         => 1,
73
        'submission_id'        => null,
74
        'discount_code'        => null,
75
        'gateway'              => 'none',
76
        'transaction_id'       => '',
77
        'currency'             => '',
78
        'disable_taxes'        => 0,
79
		'subscription_id'      => null,
80
		'is_viewed'            => false,
81
		'email_cc'             => '',
82
		'template'             => 'quantity', // hours, amount only
83
    );
84
85
    /**
86
	 * Stores meta in cache for future reads.
87
	 *
88
	 * A group must be set to to enable caching.
89
	 *
90
	 * @var string
91
	 */
92
	protected $cache_group = 'getpaid_invoices';
93
94
    /**
95
     * Stores a reference to the original WP_Post object
96
     *
97
     * @var WP_Post
98
     */
99
    protected $post = null;
100
101
    /**
102
     * Stores a reference to the recurring item id instead of looping through the items.
103
     *
104
     * @var int
105
     */
106
	protected $recurring_item = null;
107
108
	/**
109
     * Stores an array of item totals.
110
	 *
111
	 * e.g $totals['discount'] = array(
112
	 * 		'initial'   => 10,
113
	 * 		'recurring' => 10,
114
	 * )
115
     *
116
     * @var array
117
     */
118
	protected $totals = array();
119
120
	/**
121
	 * Stores the status transition information.
122
	 *
123
	 * @since 1.0.19
124
	 * @var bool
125
	 */
126
	protected $status_transition = false;
127
128
    /**
129
	 * Get the invoice if ID is passed, otherwise the invoice is new and empty.
130
	 *
131
	 * @param  int/string|object|WPInv_Invoice|WPInv_Legacy_Invoice|WP_Post $invoice Invoice id, key, number or object to read.
0 ignored issues
show
Documentation Bug introduced by
The doc comment int/string|object|WPInv_..._Legacy_Invoice|WP_Post at position 0 could not be parsed: Unknown type name 'int/string' at position 0 in int/string|object|WPInv_Invoice|WPInv_Legacy_Invoice|WP_Post.
Loading history...
132
	 */
133
    public function __construct( $invoice = false ) {
134
135
        parent::__construct( $invoice );
136
137
		if ( is_numeric( $invoice ) && getpaid_is_invoice_post_type( get_post_type( $invoice ) ) ) {
138
			$this->set_id( $invoice );
139
		} elseif ( $invoice instanceof self ) {
140
			$this->set_id( $invoice->get_id() );
141
		} elseif ( ! empty( $invoice->ID ) ) {
142
			$this->set_id( $invoice->ID );
143
		} elseif ( is_array( $invoice ) ) {
144
			$this->set_props( $invoice );
145
146
			if ( isset( $invoice['ID'] ) ) {
147
				$this->set_id( $invoice['ID'] );
148
			}
149
150
		} elseif ( is_scalar( $invoice ) && $invoice_id = self::get_discount_id_by_code( $invoice, 'key' ) ) {
151
			$this->set_id( $invoice_id );
152
		} elseif ( is_scalar( $invoice ) && $invoice_id = self::get_discount_id_by_code( $invoice, 'number' ) ) {
153
			$this->set_id( $invoice_id );
154
		} else {
155
			$this->set_object_read( true );
156
		}
157
158
        // Load the datastore.
159
		$this->data_store = GetPaid_Data_Store::load( $this->data_store_name );
160
161
		if ( $this->get_id() > 0 ) {
162
            $this->post = get_post( $this->get_id() );
163
            $this->ID   = $this->get_id();
0 ignored issues
show
Bug Best Practice introduced by
The property ID does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
164
			$this->data_store->read( $this );
165
        }
166
167
    }
168
169
    /**
170
	 * Given a discount code, it returns a discount id.
171
	 *
172
	 *
173
	 * @static
174
	 * @param string $discount_code
175
	 * @since 1.0.15
176
	 * @return int
177
	 */
178
	public static function get_discount_id_by_code( $invoice_key_or_number, $field = 'key' ) {
179
        global $wpdb;
180
181
		// Trim the code.
182
        $key = trim( $invoice_key_or_number );
183
184
        // Valid fields.
185
        $fields = array( 'key', 'number' );
186
187
		// Ensure a value has been passed.
188
		if ( empty( $key ) || ! in_array( $field, $fields ) ) {
189
			return 0;
190
		}
191
192
		// Maybe retrieve from the cache.
193
		$invoice_id   = wp_cache_get( $key, 'getpaid_invoice_keys_' . $field );
194
		if ( ! empty( $invoice_id ) ) {
195
			return $invoice_id;
196
		}
197
198
        // Fetch from the db.
199
        $table       = $wpdb->prefix . 'getpaid_invoices';
200
        $invoice_id  = $wpdb->get_var(
201
            $wpdb->prepare( "SELECT `post_id` FROM $table WHERE $field=%s LIMIT 1", $key )
202
        );
203
204
		if ( empty( $invoice_id ) ) {
205
			return 0;
206
		}
207
208
		// Update the cache with our data
209
		wp_cache_set( $key, $invoice_id, 'getpaid_invoice_keys_' . $field );
210
211
		return $invoice_id;
212
    }
213
214
    /**
215
     * Checks if an invoice key is set.
216
     */
217
    public function _isset( $key ) {
218
        return isset( $this->data[$key] ) || method_exists( $this, "get_$key" );
219
    }
220
221
    /*
222
	|--------------------------------------------------------------------------
223
	| CRUD methods
224
	|--------------------------------------------------------------------------
225
	|
226
	| Methods which create, read, update and delete items from the database.
227
	|
228
    */
229
230
    /*
231
	|--------------------------------------------------------------------------
232
	| Getters
233
	|--------------------------------------------------------------------------
234
    */
235
236
    /**
237
	 * Get parent invoice ID.
238
	 *
239
	 * @since 1.0.19
240
	 * @param  string $context View or edit context.
241
	 * @return int
242
	 */
243
	public function get_parent_id( $context = 'view' ) {
244
		return (int) $this->get_prop( 'parent_id', $context );
245
    }
246
247
    /**
248
	 * Get parent invoice.
249
	 *
250
	 * @since 1.0.19
251
	 * @return WPInv_Invoice
252
	 */
253
    public function get_parent_payment() {
254
        return new WPInv_Invoice( $this->get_parent_id() );
255
    }
256
257
    /**
258
	 * Alias for self::get_parent_payment().
259
	 *
260
	 * @since 1.0.19
261
	 * @return WPInv_Invoice
262
	 */
263
    public function get_parent() {
264
        return $this->get_parent_payment();
265
    }
266
267
    /**
268
	 * Get invoice status.
269
	 *
270
	 * @since 1.0.19
271
	 * @param  string $context View or edit context.
272
	 * @return string
273
	 */
274
	public function get_status( $context = 'view' ) {
275
		return $this->get_prop( 'status', $context );
276
    }
277
278
    /**
279
	 * Get invoice status nice name.
280
	 *
281
	 * @since 1.0.19
282
	 * @return string
283
	 */
284
    public function get_status_nicename() {
285
        $statuses = wpinv_get_invoice_statuses( true, true, $this );
286
287
        if ( $this->is_quote() && class_exists( 'Wpinv_Quotes_Shared' ) ) {
288
            $statuses = Wpinv_Quotes_Shared::wpinv_get_quote_statuses();
0 ignored issues
show
Bug introduced by
The type Wpinv_Quotes_Shared was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
289
        }
290
291
        $status = isset( $statuses[ $this->get_status() ] ) ? $statuses[ $this->get_status() ] : $this->get_status();
292
293
        return apply_filters( 'wpinv_get_invoice_status_nicename', $status );
294
    }
295
296
    /**
297
	 * Get plugin version when the invoice was created.
298
	 *
299
	 * @since 1.0.19
300
	 * @param  string $context View or edit context.
301
	 * @return string
302
	 */
303
	public function get_version( $context = 'view' ) {
304
		return $this->get_prop( 'version', $context );
305
	}
306
307
	/**
308
	 * @deprecated
309
	 */
310
	public function get_invoice_date( $formatted = true ) {
311
        $date_completed = $this->get_date_completed();
312
        $invoice_date   = $date_completed != '0000-00-00 00:00:00' ? $date_completed : '';
313
314
        if ( $invoice_date == '' ) {
315
            $date_created   = $this->get_date_created();
316
            $invoice_date   = $date_created != '0000-00-00 00:00:00' ? $date_created : '';
317
        }
318
319
        if ( $formatted && $invoice_date ) {
320
            $invoice_date   = date_i18n( get_option( 'date_format' ), strtotime( $invoice_date ) );
0 ignored issues
show
Bug introduced by
It seems like get_option('date_format') can also be of type false; however, parameter $format of date_i18n() does only seem to accept 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 ignore-type  annotation

320
            $invoice_date   = date_i18n( /** @scrutinizer ignore-type */ get_option( 'date_format' ), strtotime( $invoice_date ) );
Loading history...
321
        }
322
323
        return apply_filters( 'wpinv_get_invoice_date', $invoice_date, $formatted, $this->ID, $this );
324
    }
325
326
    /**
327
	 * Get date when the invoice was created.
328
	 *
329
	 * @since 1.0.19
330
	 * @param  string $context View or edit context.
331
	 * @return string
332
	 */
333
	public function get_date_created( $context = 'view' ) {
334
		return $this->get_prop( 'date_created', $context );
335
	}
336
	
337
	/**
338
	 * Alias for self::get_date_created().
339
	 *
340
	 * @since 1.0.19
341
	 * @param  string $context View or edit context.
342
	 * @return string
343
	 */
344
	public function get_created_date( $context = 'view' ) {
345
		return $this->get_date_created( $context );
346
    }
347
348
    /**
349
	 * Get GMT date when the invoice was created.
350
	 *
351
	 * @since 1.0.19
352
	 * @param  string $context View or edit context.
353
	 * @return string
354
	 */
355
	public function get_date_created_gmt( $context = 'view' ) {
356
        $date = $this->get_date_created( $context );
357
358
        if ( $date ) {
359
            $date = get_gmt_from_date( $date );
360
        }
361
		return $date;
362
    }
363
364
    /**
365
	 * Get date when the invoice was last modified.
366
	 *
367
	 * @since 1.0.19
368
	 * @param  string $context View or edit context.
369
	 * @return string
370
	 */
371
	public function get_date_modified( $context = 'view' ) {
372
		return $this->get_prop( 'date_modified', $context );
373
	}
374
375
	/**
376
	 * Alias for self::get_date_modified().
377
	 *
378
	 * @since 1.0.19
379
	 * @param  string $context View or edit context.
380
	 * @return string
381
	 */
382
	public function get_modified_date( $context = 'view' ) {
383
		return $this->get_date_modified( $context );
384
    }
385
386
    /**
387
	 * Get GMT date when the invoice was last modified.
388
	 *
389
	 * @since 1.0.19
390
	 * @param  string $context View or edit context.
391
	 * @return string
392
	 */
393
	public function get_date_modified_gmt( $context = 'view' ) {
394
        $date = $this->get_date_modified( $context );
395
396
        if ( $date ) {
397
            $date = get_gmt_from_date( $date );
398
        }
399
		return $date;
400
    }
401
402
    /**
403
	 * Get the invoice due date.
404
	 *
405
	 * @since 1.0.19
406
	 * @param  string $context View or edit context.
407
	 * @return string
408
	 */
409
	public function get_due_date( $context = 'view' ) {
410
		return $this->get_prop( 'due_date', $context );
411
    }
412
413
    /**
414
	 * Alias for self::get_due_date().
415
	 *
416
	 * @since 1.0.19
417
	 * @param  string $context View or edit context.
418
	 * @return string
419
	 */
420
	public function get_date_due( $context = 'view' ) {
421
		return $this->get_due_date( $context );
422
    }
423
424
    /**
425
	 * Get the invoice GMT due date.
426
	 *
427
	 * @since 1.0.19
428
	 * @param  string $context View or edit context.
429
	 * @return string
430
	 */
431
	public function get_due_date_gmt( $context = 'view' ) {
432
        $date = $this->get_due_date( $context );
433
434
        if ( $date ) {
435
            $date = get_gmt_from_date( $date );
436
        }
437
		return $date;
438
    }
439
440
    /**
441
	 * Alias for self::get_due_date_gmt().
442
	 *
443
	 * @since 1.0.19
444
	 * @param  string $context View or edit context.
445
	 * @return string
446
	 */
447
	public function get_gmt_date_due( $context = 'view' ) {
448
		return $this->get_due_date_gmt( $context );
449
    }
450
451
    /**
452
	 * Get date when the invoice was completed.
453
	 *
454
	 * @since 1.0.19
455
	 * @param  string $context View or edit context.
456
	 * @return string
457
	 */
458
	public function get_completed_date( $context = 'view' ) {
459
		return $this->get_prop( 'completed_date', $context );
460
    }
461
462
    /**
463
	 * Alias for self::get_completed_date().
464
	 *
465
	 * @since 1.0.19
466
	 * @param  string $context View or edit context.
467
	 * @return string
468
	 */
469
	public function get_date_completed( $context = 'view' ) {
470
		return $this->get_completed_date( $context );
471
    }
472
473
    /**
474
	 * Get GMT date when the invoice was was completed.
475
	 *
476
	 * @since 1.0.19
477
	 * @param  string $context View or edit context.
478
	 * @return string
479
	 */
480
	public function get_completed_date_gmt( $context = 'view' ) {
481
        $date = $this->get_completed_date( $context );
482
483
        if ( $date ) {
484
            $date = get_gmt_from_date( $date );
485
        }
486
		return $date;
487
    }
488
489
    /**
490
	 * Alias for self::get_completed_date_gmt().
491
	 *
492
	 * @since 1.0.19
493
	 * @param  string $context View or edit context.
494
	 * @return string
495
	 */
496
	public function get_gmt_completed_date( $context = 'view' ) {
497
		return $this->get_completed_date_gmt( $context );
498
    }
499
500
    /**
501
	 * Get the invoice number.
502
	 *
503
	 * @since 1.0.19
504
	 * @param  string $context View or edit context.
505
	 * @return string
506
	 */
507
	public function get_number( $context = 'view' ) {
508
        $number = $this->get_prop( 'number', $context );
509
510
        if ( empty( $number ) ) {
511
            $number = $this->generate_number();
512
            $this->set_number( $number );
513
        }
514
515
		return $number;
516
    }
517
518
    /**
519
	 * Get the invoice key.
520
	 *
521
	 * @since 1.0.19
522
	 * @param  string $context View or edit context.
523
	 * @return string
524
	 */
525
	public function get_key( $context = 'view' ) {
526
        $key = $this->get_prop( 'key', $context );
527
528
        if ( empty( $key ) ) {
529
            $key = $this->generate_key( $this->post_type );
0 ignored issues
show
Bug Best Practice introduced by
The property post_type does not exist on WPInv_Invoice. Since you implemented __get, consider adding a @property annotation.
Loading history...
530
            $this->set_key( $key );
531
        }
532
533
		return $key;
534
    }
535
536
    /**
537
	 * Get the invoice type.
538
	 *
539
	 * @since 1.0.19
540
	 * @param  string $context View or edit context.
541
	 * @return string
542
	 */
543
	public function get_type( $context = 'view' ) {
544
        return $this->get_prop( 'type', $context );
545
	}
546
547
	/**
548
	 * @deprecated
549
	 */
550
	public function get_invoice_quote_type( $post_id ) {
551
        if ( empty( $post_id ) ) {
552
            return '';
553
        }
554
555
        $type = get_post_type( $post_id );
556
557
        if ( 'wpi_invoice' === $type ) {
558
            $post_type = __('Invoice', 'invoicing');
559
        } else{
560
            $post_type = __('Quote', 'invoicing');
561
        }
562
563
        return apply_filters('get_invoice_type_label', $post_type, $post_id);
564
    }
565
566
    /**
567
	 * Get the invoice post type.
568
	 *
569
	 * @since 1.0.19
570
	 * @param  string $context View or edit context.
571
	 * @return string
572
	 */
573
	public function get_post_type( $context = 'view' ) {
574
        return $this->get_prop( 'post_type', $context );
575
    }
576
577
    /**
578
	 * Get the invoice mode.
579
	 *
580
	 * @since 1.0.19
581
	 * @param  string $context View or edit context.
582
	 * @return string
583
	 */
584
	public function get_mode( $context = 'view' ) {
585
        return $this->get_prop( 'mode', $context );
586
    }
587
588
    /**
589
	 * Get the invoice path.
590
	 *
591
	 * @since 1.0.19
592
	 * @param  string $context View or edit context.
593
	 * @return string
594
	 */
595
	public function get_path( $context = 'view' ) {
596
        $path = $this->get_prop( 'path', $context );
597
598
        if ( empty( $path ) ) {
599
            $prefix = apply_filters( 'wpinv_post_name_prefix', 'inv-', $this->post_type );
0 ignored issues
show
Bug Best Practice introduced by
The property post_type does not exist on WPInv_Invoice. Since you implemented __get, consider adding a @property annotation.
Loading history...
600
            $path   = sanitize_title( $prefix . $this->get_id() );
601
        }
602
603
		return $path;
604
    }
605
606
    /**
607
	 * Get the invoice name/title.
608
	 *
609
	 * @since 1.0.19
610
	 * @param  string $context View or edit context.
611
	 * @return string
612
	 */
613
	public function get_name( $context = 'view' ) {
614
        $name = $this->get_prop( 'title', $context );
615
616
		return empty( $name ) ? $this->get_number( $context ) : $name;
617
    }
618
619
    /**
620
	 * Alias of self::get_name().
621
	 *
622
	 * @since 1.0.19
623
	 * @param  string $context View or edit context.
624
	 * @return string
625
	 */
626
	public function get_title( $context = 'view' ) {
627
		return $this->get_name( $context );
628
    }
629
630
    /**
631
	 * Get the invoice description.
632
	 *
633
	 * @since 1.0.19
634
	 * @param  string $context View or edit context.
635
	 * @return string
636
	 */
637
	public function get_description( $context = 'view' ) {
638
		return $this->get_prop( 'description', $context );
639
    }
640
641
    /**
642
	 * Alias of self::get_description().
643
	 *
644
	 * @since 1.0.19
645
	 * @param  string $context View or edit context.
646
	 * @return string
647
	 */
648
	public function get_excerpt( $context = 'view' ) {
649
		return $this->get_description( $context );
650
    }
651
652
    /**
653
	 * Alias of self::get_description().
654
	 *
655
	 * @since 1.0.19
656
	 * @param  string $context View or edit context.
657
	 * @return string
658
	 */
659
	public function get_summary( $context = 'view' ) {
660
		return $this->get_description( $context );
661
    }
662
663
    /**
664
	 * Returns the user info.
665
	 *
666
	 * @since 1.0.19
667
     * @param  string $context View or edit context.
668
	 * @return array
669
	 */
670
    public function get_user_info( $context = 'view' ) {
671
        $user_info = array(
672
            'user_id'    => $this->get_user_id( $context ),
673
            'email'      => $this->get_email( $context ),
674
            'first_name' => $this->get_first_name( $context ),
675
            'last_name'  => $this->get_last_name( $context ),
676
            'address'    => $this->get_address( $context ),
677
            'phone'      => $this->get_phone( $context ),
678
            'city'       => $this->get_city( $context ),
679
            'country'    => $this->get_country( $context ),
680
            'state'      => $this->get_state( $context ),
681
            'zip'        => $this->get_zip( $context ),
682
            'company'    => $this->get_company( $context ),
683
            'vat_number' => $this->get_vat_number( $context ),
684
            'discount'   => $this->get_discount_code( $context ),
685
        );
686
        return apply_filters( 'wpinv_user_info', $user_info, $this->ID, $this );
687
    }
688
689
    /**
690
	 * Get the customer id.
691
	 *
692
	 * @since 1.0.19
693
	 * @param  string $context View or edit context.
694
	 * @return int
695
	 */
696
	public function get_author( $context = 'view' ) {
697
		return (int) $this->get_prop( 'author', $context );
698
    }
699
700
    /**
701
	 * Alias of self::get_author().
702
	 *
703
	 * @since 1.0.19
704
	 * @param  string $context View or edit context.
705
	 * @return int
706
	 */
707
	public function get_user_id( $context = 'view' ) {
708
		return $this->get_author( $context );
709
    }
710
711
     /**
712
	 * Alias of self::get_author().
713
	 *
714
	 * @since 1.0.19
715
	 * @param  string $context View or edit context.
716
	 * @return int
717
	 */
718
	public function get_customer_id( $context = 'view' ) {
719
		return $this->get_author( $context );
720
    }
721
722
    /**
723
	 * Get the customer's ip.
724
	 *
725
	 * @since 1.0.19
726
	 * @param  string $context View or edit context.
727
	 * @return string
728
	 */
729
	public function get_ip( $context = 'view' ) {
730
		return $this->get_prop( 'user_ip', $context );
731
    }
732
733
    /**
734
	 * Alias of self::get_ip().
735
	 *
736
	 * @since 1.0.19
737
	 * @param  string $context View or edit context.
738
	 * @return string
739
	 */
740
	public function get_user_ip( $context = 'view' ) {
741
		return $this->get_ip( $context );
742
    }
743
744
     /**
745
	 * Alias of self::get_ip().
746
	 *
747
	 * @since 1.0.19
748
	 * @param  string $context View or edit context.
749
	 * @return string
750
	 */
751
	public function get_customer_ip( $context = 'view' ) {
752
		return $this->get_ip( $context );
753
    }
754
755
    /**
756
	 * Get the customer's first name.
757
	 *
758
	 * @since 1.0.19
759
	 * @param  string $context View or edit context.
760
	 * @return string
761
	 */
762
	public function get_first_name( $context = 'view' ) {
763
		return $this->get_prop( 'first_name', $context );
764
    }
765
766
    /**
767
	 * Alias of self::get_first_name().
768
	 *
769
	 * @since 1.0.19
770
	 * @param  string $context View or edit context.
771
	 * @return int
772
	 */
773
	public function get_user_first_name( $context = 'view' ) {
774
		return $this->get_first_name( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_first_name($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
775
    }
776
777
     /**
778
	 * Alias of self::get_first_name().
779
	 *
780
	 * @since 1.0.19
781
	 * @param  string $context View or edit context.
782
	 * @return int
783
	 */
784
	public function get_customer_first_name( $context = 'view' ) {
785
		return $this->get_first_name( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_first_name($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
786
    }
787
788
    /**
789
	 * Get the customer's last name.
790
	 *
791
	 * @since 1.0.19
792
	 * @param  string $context View or edit context.
793
	 * @return string
794
	 */
795
	public function get_last_name( $context = 'view' ) {
796
		return $this->get_prop( 'last_name', $context );
797
    }
798
799
    /**
800
	 * Alias of self::get_last_name().
801
	 *
802
	 * @since 1.0.19
803
	 * @param  string $context View or edit context.
804
	 * @return int
805
	 */
806
	public function get_user_last_name( $context = 'view' ) {
807
		return $this->get_last_name( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_last_name($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
808
    }
809
810
    /**
811
	 * Alias of self::get_last_name().
812
	 *
813
	 * @since 1.0.19
814
	 * @param  string $context View or edit context.
815
	 * @return int
816
	 */
817
	public function get_customer_last_name( $context = 'view' ) {
818
		return $this->get_last_name( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_last_name($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
819
    }
820
821
    /**
822
	 * Get the customer's full name.
823
	 *
824
	 * @since 1.0.19
825
	 * @param  string $context View or edit context.
826
	 * @return string
827
	 */
828
	public function get_full_name( $context = 'view' ) {
829
		return trim( $this->get_first_name( $context ) . ' ' . $this->get_last_name( $context ) );
830
    }
831
832
    /**
833
	 * Alias of self::get_full_name().
834
	 *
835
	 * @since 1.0.19
836
	 * @param  string $context View or edit context.
837
	 * @return int
838
	 */
839
	public function get_user_full_name( $context = 'view' ) {
840
		return $this->get_full_name( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_full_name($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
841
    }
842
843
    /**
844
	 * Alias of self::get_full_name().
845
	 *
846
	 * @since 1.0.19
847
	 * @param  string $context View or edit context.
848
	 * @return int
849
	 */
850
	public function get_customer_full_name( $context = 'view' ) {
851
		return $this->get_full_name( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_full_name($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
852
    }
853
854
    /**
855
	 * Get the customer's phone number.
856
	 *
857
	 * @since 1.0.19
858
	 * @param  string $context View or edit context.
859
	 * @return string
860
	 */
861
	public function get_phone( $context = 'view' ) {
862
		return $this->get_prop( 'phone', $context );
863
    }
864
865
    /**
866
	 * Alias of self::get_phone().
867
	 *
868
	 * @since 1.0.19
869
	 * @param  string $context View or edit context.
870
	 * @return int
871
	 */
872
	public function get_phone_number( $context = 'view' ) {
873
		return $this->get_phone( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_phone($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
874
    }
875
876
    /**
877
	 * Alias of self::get_phone().
878
	 *
879
	 * @since 1.0.19
880
	 * @param  string $context View or edit context.
881
	 * @return int
882
	 */
883
	public function get_user_phone( $context = 'view' ) {
884
		return $this->get_phone( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_phone($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
885
    }
886
887
    /**
888
	 * Alias of self::get_phone().
889
	 *
890
	 * @since 1.0.19
891
	 * @param  string $context View or edit context.
892
	 * @return int
893
	 */
894
	public function get_customer_phone( $context = 'view' ) {
895
		return $this->get_phone( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_phone($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
896
    }
897
898
    /**
899
	 * Get the customer's email address.
900
	 *
901
	 * @since 1.0.19
902
	 * @param  string $context View or edit context.
903
	 * @return string
904
	 */
905
	public function get_email( $context = 'view' ) {
906
		return $this->get_prop( 'email', $context );
907
    }
908
909
    /**
910
	 * Alias of self::get_email().
911
	 *
912
	 * @since 1.0.19
913
	 * @param  string $context View or edit context.
914
	 * @return string
915
	 */
916
	public function get_email_address( $context = 'view' ) {
917
		return $this->get_email( $context );
918
    }
919
920
    /**
921
	 * Alias of self::get_email().
922
	 *
923
	 * @since 1.0.19
924
	 * @param  string $context View or edit context.
925
	 * @return int
926
	 */
927
	public function get_user_email( $context = 'view' ) {
928
		return $this->get_email( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_email($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
929
    }
930
931
    /**
932
	 * Alias of self::get_email().
933
	 *
934
	 * @since 1.0.19
935
	 * @param  string $context View or edit context.
936
	 * @return int
937
	 */
938
	public function get_customer_email( $context = 'view' ) {
939
		return $this->get_email( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_email($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
940
    }
941
942
    /**
943
	 * Get the customer's country.
944
	 *
945
	 * @since 1.0.19
946
	 * @param  string $context View or edit context.
947
	 * @return string
948
	 */
949
	public function get_country( $context = 'view' ) {
950
		$country = $this->get_prop( 'country', $context );
951
		return empty( $country ) ? wpinv_get_default_country() : $country;
952
    }
953
954
    /**
955
	 * Alias of self::get_country().
956
	 *
957
	 * @since 1.0.19
958
	 * @param  string $context View or edit context.
959
	 * @return int
960
	 */
961
	public function get_user_country( $context = 'view' ) {
962
		return $this->get_country( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_country($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
963
    }
964
965
    /**
966
	 * Alias of self::get_country().
967
	 *
968
	 * @since 1.0.19
969
	 * @param  string $context View or edit context.
970
	 * @return int
971
	 */
972
	public function get_customer_country( $context = 'view' ) {
973
		return $this->get_country( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_country($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
974
    }
975
976
    /**
977
	 * Get the customer's state.
978
	 *
979
	 * @since 1.0.19
980
	 * @param  string $context View or edit context.
981
	 * @return string
982
	 */
983
	public function get_state( $context = 'view' ) {
984
		$state = $this->get_prop( 'state', $context );
985
		return empty( $state ) ? wpinv_get_default_state() : $state;
0 ignored issues
show
Bug Best Practice introduced by
The expression return empty($state) ? w...efault_state() : $state could also return false which is incompatible with the documented return type string. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
986
    }
987
988
    /**
989
	 * Alias of self::get_state().
990
	 *
991
	 * @since 1.0.19
992
	 * @param  string $context View or edit context.
993
	 * @return int
994
	 */
995
	public function get_user_state( $context = 'view' ) {
996
		return $this->get_state( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_state($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
997
    }
998
999
    /**
1000
	 * Alias of self::get_state().
1001
	 *
1002
	 * @since 1.0.19
1003
	 * @param  string $context View or edit context.
1004
	 * @return int
1005
	 */
1006
	public function get_customer_state( $context = 'view' ) {
1007
		return $this->get_state( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_state($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
1008
    }
1009
1010
    /**
1011
	 * Get the customer's city.
1012
	 *
1013
	 * @since 1.0.19
1014
	 * @param  string $context View or edit context.
1015
	 * @return string
1016
	 */
1017
	public function get_city( $context = 'view' ) {
1018
		return $this->get_prop( 'city', $context );
1019
    }
1020
1021
    /**
1022
	 * Alias of self::get_city().
1023
	 *
1024
	 * @since 1.0.19
1025
	 * @param  string $context View or edit context.
1026
	 * @return string
1027
	 */
1028
	public function get_user_city( $context = 'view' ) {
1029
		return $this->get_city( $context );
1030
    }
1031
1032
    /**
1033
	 * Alias of self::get_city().
1034
	 *
1035
	 * @since 1.0.19
1036
	 * @param  string $context View or edit context.
1037
	 * @return string
1038
	 */
1039
	public function get_customer_city( $context = 'view' ) {
1040
		return $this->get_city( $context );
1041
    }
1042
1043
    /**
1044
	 * Get the customer's zip.
1045
	 *
1046
	 * @since 1.0.19
1047
	 * @param  string $context View or edit context.
1048
	 * @return string
1049
	 */
1050
	public function get_zip( $context = 'view' ) {
1051
		return $this->get_prop( 'zip', $context );
1052
    }
1053
1054
    /**
1055
	 * Alias of self::get_zip().
1056
	 *
1057
	 * @since 1.0.19
1058
	 * @param  string $context View or edit context.
1059
	 * @return string
1060
	 */
1061
	public function get_user_zip( $context = 'view' ) {
1062
		return $this->get_zip( $context );
1063
    }
1064
1065
    /**
1066
	 * Alias of self::get_zip().
1067
	 *
1068
	 * @since 1.0.19
1069
	 * @param  string $context View or edit context.
1070
	 * @return string
1071
	 */
1072
	public function get_customer_zip( $context = 'view' ) {
1073
		return $this->get_zip( $context );
1074
    }
1075
1076
    /**
1077
	 * Get the customer's company.
1078
	 *
1079
	 * @since 1.0.19
1080
	 * @param  string $context View or edit context.
1081
	 * @return string
1082
	 */
1083
	public function get_company( $context = 'view' ) {
1084
		return $this->get_prop( 'company', $context );
1085
    }
1086
1087
    /**
1088
	 * Alias of self::get_company().
1089
	 *
1090
	 * @since 1.0.19
1091
	 * @param  string $context View or edit context.
1092
	 * @return string
1093
	 */
1094
	public function get_user_company( $context = 'view' ) {
1095
		return $this->get_company( $context );
1096
    }
1097
1098
    /**
1099
	 * Alias of self::get_company().
1100
	 *
1101
	 * @since 1.0.19
1102
	 * @param  string $context View or edit context.
1103
	 * @return string
1104
	 */
1105
	public function get_customer_company( $context = 'view' ) {
1106
		return $this->get_company( $context );
1107
    }
1108
1109
    /**
1110
	 * Get the customer's vat number.
1111
	 *
1112
	 * @since 1.0.19
1113
	 * @param  string $context View or edit context.
1114
	 * @return string
1115
	 */
1116
	public function get_vat_number( $context = 'view' ) {
1117
		return $this->get_prop( 'vat_number', $context );
1118
    }
1119
1120
    /**
1121
	 * Alias of self::get_vat_number().
1122
	 *
1123
	 * @since 1.0.19
1124
	 * @param  string $context View or edit context.
1125
	 * @return string
1126
	 */
1127
	public function get_user_vat_number( $context = 'view' ) {
1128
		return $this->get_vat_number( $context );
1129
    }
1130
1131
    /**
1132
	 * Alias of self::get_vat_number().
1133
	 *
1134
	 * @since 1.0.19
1135
	 * @param  string $context View or edit context.
1136
	 * @return string
1137
	 */
1138
	public function get_customer_vat_number( $context = 'view' ) {
1139
		return $this->get_vat_number( $context );
1140
    }
1141
1142
    /**
1143
	 * Get the customer's vat rate.
1144
	 *
1145
	 * @since 1.0.19
1146
	 * @param  string $context View or edit context.
1147
	 * @return string
1148
	 */
1149
	public function get_vat_rate( $context = 'view' ) {
1150
		return $this->get_prop( 'vat_rate', $context );
1151
    }
1152
1153
    /**
1154
	 * Alias of self::get_vat_rate().
1155
	 *
1156
	 * @since 1.0.19
1157
	 * @param  string $context View or edit context.
1158
	 * @return string
1159
	 */
1160
	public function get_user_vat_rate( $context = 'view' ) {
1161
		return $this->get_vat_rate( $context );
1162
    }
1163
1164
    /**
1165
	 * Alias of self::get_vat_rate().
1166
	 *
1167
	 * @since 1.0.19
1168
	 * @param  string $context View or edit context.
1169
	 * @return string
1170
	 */
1171
	public function get_customer_vat_rate( $context = 'view' ) {
1172
		return $this->get_vat_rate( $context );
1173
    }
1174
1175
    /**
1176
	 * Get the customer's address.
1177
	 *
1178
	 * @since 1.0.19
1179
	 * @param  string $context View or edit context.
1180
	 * @return string
1181
	 */
1182
	public function get_address( $context = 'view' ) {
1183
		return $this->get_prop( 'address', $context );
1184
    }
1185
1186
    /**
1187
	 * Alias of self::get_address().
1188
	 *
1189
	 * @since 1.0.19
1190
	 * @param  string $context View or edit context.
1191
	 * @return string
1192
	 */
1193
	public function get_user_address( $context = 'view' ) {
1194
		return $this->get_address( $context );
1195
    }
1196
1197
    /**
1198
	 * Alias of self::get_address().
1199
	 *
1200
	 * @since 1.0.19
1201
	 * @param  string $context View or edit context.
1202
	 * @return string
1203
	 */
1204
	public function get_customer_address( $context = 'view' ) {
1205
		return $this->get_address( $context );
1206
    }
1207
1208
    /**
1209
	 * Get whether the customer has viewed the invoice or not.
1210
	 *
1211
	 * @since 1.0.19
1212
	 * @param  string $context View or edit context.
1213
	 * @return bool
1214
	 */
1215
	public function get_is_viewed( $context = 'view' ) {
1216
		return (bool) $this->get_prop( 'is_viewed', $context );
1217
	}
1218
1219
	/**
1220
	 * Get other recipients for invoice communications.
1221
	 *
1222
	 * @since 1.0.19
1223
	 * @param  string $context View or edit context.
1224
	 * @return bool
1225
	 */
1226
	public function get_email_cc( $context = 'view' ) {
1227
		return $this->get_prop( 'email_cc', $context );
1228
	}
1229
1230
	/**
1231
	 * Get invoice template.
1232
	 *
1233
	 * @since 1.0.19
1234
	 * @param  string $context View or edit context.
1235
	 * @return bool
1236
	 */
1237
	public function get_template( $context = 'view' ) {
1238
		return $this->get_prop( 'template', $context );
1239
	}
1240
1241
	/**
1242
	 * Get whether the customer has confirmed their address.
1243
	 *
1244
	 * @since 1.0.19
1245
	 * @param  string $context View or edit context.
1246
	 * @return bool
1247
	 */
1248
	public function get_address_confirmed( $context = 'view' ) {
1249
		return (bool) $this->get_prop( 'address_confirmed', $context );
1250
    }
1251
1252
    /**
1253
	 * Alias of self::get_address_confirmed().
1254
	 *
1255
	 * @since 1.0.19
1256
	 * @param  string $context View or edit context.
1257
	 * @return bool
1258
	 */
1259
	public function get_user_address_confirmed( $context = 'view' ) {
1260
		return $this->get_address_confirmed( $context );
1261
    }
1262
1263
    /**
1264
	 * Alias of self::get_address().
1265
	 *
1266
	 * @since 1.0.19
1267
	 * @param  string $context View or edit context.
1268
	 * @return bool
1269
	 */
1270
	public function get_customer_address_confirmed( $context = 'view' ) {
1271
		return $this->get_address_confirmed( $context );
1272
    }
1273
1274
    /**
1275
	 * Get the invoice subtotal.
1276
	 *
1277
	 * @since 1.0.19
1278
	 * @param  string $context View or edit context.
1279
	 * @return float
1280
	 */
1281
	public function get_subtotal( $context = 'view' ) {
1282
        $subtotal = (float) $this->get_prop( 'subtotal', $context );
1283
1284
        // Backwards compatibility.
1285
        if ( is_bool( $context ) && $context ) {
0 ignored issues
show
introduced by
The condition is_bool($context) is always false.
Loading history...
1286
            return wpinv_price( wpinv_format_amount( $subtotal ), $this->get_currency() );
1287
        }
1288
1289
        return $subtotal;
1290
    }
1291
1292
    /**
1293
	 * Get the invoice discount total.
1294
	 *
1295
	 * @since 1.0.19
1296
	 * @param  string $context View or edit context.
1297
	 * @return float
1298
	 */
1299
	public function get_total_discount( $context = 'view' ) {
1300
		return (float) $this->get_prop( 'total_discount', $context );
1301
    }
1302
1303
    /**
1304
	 * Get the invoice tax total.
1305
	 *
1306
	 * @since 1.0.19
1307
	 * @param  string $context View or edit context.
1308
	 * @return float
1309
	 */
1310
	public function get_total_tax( $context = 'view' ) {
1311
		return (float) $this->get_prop( 'total_tax', $context );
1312
	}
1313
1314
	/**
1315
	 * @deprecated
1316
	 */
1317
	public function get_final_tax( $currency = false ) {
1318
		$tax = $this->get_total_tax();
1319
1320
        if ( $currency ) {
1321
			return wpinv_price( wpinv_format_amount( $tax, NULL, false ), $this->get_currency() );
1322
        }
1323
1324
        return $tax;
1325
    }
1326
1327
    /**
1328
	 * Get the invoice fees total.
1329
	 *
1330
	 * @since 1.0.19
1331
	 * @param  string $context View or edit context.
1332
	 * @return float
1333
	 */
1334
	public function get_total_fees( $context = 'view' ) {
1335
		return (float) $this->get_prop( 'total_fees', $context );
1336
    }
1337
1338
    /**
1339
	 * Alias for self::get_total_fees().
1340
	 *
1341
	 * @since 1.0.19
1342
	 * @param  string $context View or edit context.
1343
	 * @return float
1344
	 */
1345
	public function get_fees_total( $context = 'view' ) {
1346
		return $this->get_total_fees( $context );
1347
    }
1348
1349
    /**
1350
	 * Get the invoice total.
1351
	 *
1352
	 * @since 1.0.19
1353
     * @return float
1354
	 */
1355
	public function get_total() {
1356
		$total = $this->is_renewal() ? $this->get_recurring_total() : $this->get_initial_total();
1357
		return apply_filters( 'getpaid_get_invoice_total_amount', $total, $this  );
1358
    }
1359
1360
    /**
1361
	 * Get the initial invoice total.
1362
	 *
1363
	 * @since 1.0.19
1364
     * @param  string $context View or edit context.
1365
     * @return float
1366
	 */
1367
    public function get_initial_total() {
1368
1369
		if ( empty( $this->totals ) ) {
1370
			$this->recalculate_total();
1371
		}
1372
1373
		$tax      = $this->totals['tax']['initial'];
1374
		$fee      = $this->totals['fee']['initial'];
1375
		$discount = $this->totals['discount']['initial'];
1376
		$subtotal = $this->totals['subtotal']['initial'];
1377
		$total    = $tax + $fee - $discount + $subtotal;
1378
1379
		if ( 0 > $total ) {
1380
			$total = 0;
1381
		}
1382
1383
        return apply_filters( 'wpinv_get_initial_invoice_total', $total, $this );
1384
	}
1385
1386
	/**
1387
	 * Get the recurring invoice total.
1388
	 *
1389
	 * @since 1.0.19
1390
     * @param  string $context View or edit context.
1391
     * @return float
1392
	 */
1393
    public function get_recurring_total() {
1394
1395
		if ( empty( $this->totals ) ) {
1396
			$this->recalculate_total();
1397
		}
1398
1399
		$tax      = $this->totals['tax']['recurring'];
1400
		$fee      = $this->totals['fee']['recurring'];
1401
		$discount = $this->totals['discount']['recurring'];
1402
		$subtotal = $this->totals['subtotal']['recurring'];
1403
		$total    = $tax + $fee - $discount + $subtotal;
1404
1405
		if ( 0 > $total ) {
1406
			$total = 0;
1407
		}
1408
1409
        return apply_filters( 'wpinv_get_recurring_invoice_total', $total, $this );
1410
	}
1411
1412
	/**
1413
	 * Returns recurring payment details.
1414
	 *
1415
	 * @since 1.0.19
1416
     * @param  string $field Optionally provide a field to return.
1417
	 * @param string $currency Whether to include the currency.
1418
     * @return float
1419
	 */
1420
    public function get_recurring_details( $field = '', $currency = false ) {
1421
1422
		// Maybe recalculate totals.
1423
		if ( empty( $this->totals ) ) {
1424
			$this->recalculate_total();
1425
		}
1426
1427
		// Prepare recurring totals.
1428
        $data = apply_filters(
1429
			'wpinv_get_invoice_recurring_details',
1430
			array(
1431
				'cart_details' => $this->get_cart_details(),
1432
				'subtotal'     => $this->totals['subtotal']['recurring'],
1433
				'discount'     => $this->totals['discount']['recurring'],
1434
				'tax'          => $this->totals['tax']['recurring'],
1435
				'fee'          => $this->totals['fee']['recurring'],
1436
				'total'        => $this->get_recurring_total(),
1437
			),
1438
			$this,
1439
			$field,
1440
			$currency
1441
		);
1442
1443
        if ( isset( $data[$field] ) ) {
1444
            return ( $currency ? wpinv_price( $data[$field], $this->get_currency() ) : $data[$field] );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $currency ? wpinv...ency()) : $data[$field] also could return the type string which is incompatible with the documented return type double.
Loading history...
1445
        }
1446
1447
        return $data;
1448
    }
1449
1450
    /**
1451
	 * Get the invoice fees.
1452
	 *
1453
	 * @since 1.0.19
1454
	 * @param  string $context View or edit context.
1455
	 * @return array
1456
	 */
1457
	public function get_fees( $context = 'view' ) {
1458
		return wpinv_parse_list( $this->get_prop( 'fees', $context ) );
1459
    }
1460
1461
    /**
1462
	 * Get the invoice discounts.
1463
	 *
1464
	 * @since 1.0.19
1465
	 * @param  string $context View or edit context.
1466
	 * @return array
1467
	 */
1468
	public function get_discounts( $context = 'view' ) {
1469
		return wpinv_parse_list( $this->get_prop( 'discounts', $context ) );
1470
    }
1471
1472
    /**
1473
	 * Get the invoice taxes.
1474
	 *
1475
	 * @since 1.0.19
1476
	 * @param  string $context View or edit context.
1477
	 * @return array
1478
	 */
1479
	public function get_taxes( $context = 'view' ) {
1480
		return wpinv_parse_list( $this->get_prop( 'taxes', $context ) );
1481
    }
1482
1483
    /**
1484
	 * Get the invoice items.
1485
	 *
1486
	 * @since 1.0.19
1487
	 * @param  string $context View or edit context.
1488
	 * @return GetPaid_Form_Item[]
1489
	 */
1490
	public function get_items( $context = 'view' ) {
1491
        return $this->get_prop( 'items', $context );
1492
    }
1493
1494
    /**
1495
	 * Get the invoice's payment form.
1496
	 *
1497
	 * @since 1.0.19
1498
	 * @param  string $context View or edit context.
1499
	 * @return int
1500
	 */
1501
	public function get_payment_form( $context = 'view' ) {
1502
		return intval( $this->get_prop( 'payment_form', $context ) );
1503
    }
1504
1505
    /**
1506
	 * Get the invoice's submission id.
1507
	 *
1508
	 * @since 1.0.19
1509
	 * @param  string $context View or edit context.
1510
	 * @return string
1511
	 */
1512
	public function get_submission_id( $context = 'view' ) {
1513
		return $this->get_prop( 'submission_id', $context );
1514
    }
1515
1516
    /**
1517
	 * Get the invoice's discount code.
1518
	 *
1519
	 * @since 1.0.19
1520
	 * @param  string $context View or edit context.
1521
	 * @return string
1522
	 */
1523
	public function get_discount_code( $context = 'view' ) {
1524
		return $this->get_prop( 'discount_code', $context );
1525
    }
1526
1527
    /**
1528
	 * Get the invoice's gateway.
1529
	 *
1530
	 * @since 1.0.19
1531
	 * @param  string $context View or edit context.
1532
	 * @return string
1533
	 */
1534
	public function get_gateway( $context = 'view' ) {
1535
		return $this->get_prop( 'gateway', $context );
1536
    }
1537
1538
    /**
1539
	 * Get the invoice's gateway display title.
1540
	 *
1541
	 * @since 1.0.19
1542
	 * @return string
1543
	 */
1544
    public function get_gateway_title() {
1545
        $title =  wpinv_get_gateway_checkout_label( $this->get_gateway() );
1546
        return apply_filters( 'wpinv_gateway_title', $title, $this->ID, $this );
1547
    }
1548
1549
    /**
1550
	 * Get the invoice's transaction id.
1551
	 *
1552
	 * @since 1.0.19
1553
	 * @param  string $context View or edit context.
1554
	 * @return string
1555
	 */
1556
	public function get_transaction_id( $context = 'view' ) {
1557
		return $this->get_prop( 'transaction_id', $context );
1558
    }
1559
1560
    /**
1561
	 * Get the invoice's currency.
1562
	 *
1563
	 * @since 1.0.19
1564
	 * @param  string $context View or edit context.
1565
	 * @return string
1566
	 */
1567
	public function get_currency( $context = 'view' ) {
1568
        $currency = $this->get_prop( 'currency', $context );
1569
        return empty( $currency ) ? wpinv_get_currency() : $currency;
1570
    }
1571
1572
    /**
1573
	 * Checks if we are charging taxes for this invoice.
1574
	 *
1575
	 * @since 1.0.19
1576
	 * @param  string $context View or edit context.
1577
	 * @return bool
1578
	 */
1579
	public function get_disable_taxes( $context = 'view' ) {
1580
        return (bool) $this->get_prop( 'disable_taxes', $context );
1581
    }
1582
1583
    /**
1584
	 * Retrieves the subscription id for an invoice.
1585
	 *
1586
	 * @since 1.0.19
1587
	 * @param  string $context View or edit context.
1588
	 * @return int
1589
	 */
1590
    public function get_subscription_id( $context = 'view' ) {
1591
        $subscription_id = $this->get_prop( 'subscription_id', $context );
1592
1593
        if ( empty( $subscription_id ) && $this->is_renewal() ) {
1594
            $parent = $this->get_parent();
1595
            return $parent->get_subscription_id( $context );
1596
        }
1597
1598
        return $subscription_id;
1599
    }
1600
1601
    /**
1602
	 * Retrieves the payment meta for an invoice.
1603
	 *
1604
	 * @since 1.0.19
1605
	 * @param  string $context View or edit context.
1606
	 * @return array
1607
	 */
1608
    public function get_payment_meta( $context = 'view' ) {
1609
1610
        return array(
1611
            'price'        => $this->get_total( $context ),
0 ignored issues
show
Unused Code introduced by
The call to WPInv_Invoice::get_total() has too many arguments starting with $context. ( Ignorable by Annotation )

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

1611
            'price'        => $this->/** @scrutinizer ignore-call */ get_total( $context ),

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
1612
            'date'         => $this->get_date_created( $context ),
1613
            'user_email'   => $this->get_email( $context ),
1614
            'invoice_key'  => $this->get_key( $context ),
1615
            'currency'     => $this->get_currency( $context ),
1616
            'items'        => $this->get_items( $context ),
1617
            'user_info'    => $this->get_user_info( $context ),
1618
            'cart_details' => $this->get_cart_details(),
1619
            'status'       => $this->get_status( $context ),
1620
            'fees'         => $this->get_fees( $context ),
1621
            'taxes'        => $this->get_taxes( $context ),
1622
        );
1623
1624
    }
1625
1626
    /**
1627
	 * Retrieves the cart details for an invoice.
1628
	 *
1629
	 * @since 1.0.19
1630
	 * @return array
1631
	 */
1632
    public function get_cart_details() {
1633
        $items        = $this->get_items();
1634
        $cart_details = array();
1635
1636
        foreach ( $items as $item_id => $item ) {
1637
            $cart_details[] = $item->prepare_data_for_saving();
1638
        }
1639
1640
        return $cart_details;
1641
	}
1642
1643
	/**
1644
	 * Retrieves the recurring item.
1645
	 *
1646
	 * @return null|GetPaid_Form_Item
1647
	 */
1648
	public function get_recurring( $object = false ) {
1649
1650
		// Are we returning an object?
1651
        if ( $object ) {
1652
            return $this->get_item( $this->recurring_item );
1653
        }
1654
1655
        return $this->recurring_item;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->recurring_item returns the type integer which is incompatible with the documented return type GetPaid_Form_Item|null.
Loading history...
1656
    }
1657
1658
	/**
1659
	 * Retrieves the subscription name.
1660
	 *
1661
	 * @since 1.0.19
1662
	 * @return string
1663
	 */
1664
	public function get_subscription_name() {
1665
1666
		// Retrieve the recurring name
1667
        $item = $this->get_recurring( true );
1668
1669
		// Abort if it does not exist.
1670
        if ( empty( $item ) ) {
1671
            return '';
1672
        }
1673
1674
		// Return the item name.
1675
        return apply_filters( 'wpinv_invoice_get_subscription_name', $item->get_name(), $this );
1676
	}
1677
1678
	/**
1679
	 * Retrieves the view url.
1680
	 *
1681
	 * @since 1.0.19
1682
	 * @return string
1683
	 */
1684
	public function get_view_url() {
1685
        $invoice_url = get_permalink( $this->get_id() );
1686
		$invoice_url = add_query_arg( 'invoice_key', $this->get_key(), $invoice_url );
1687
        return apply_filters( 'wpinv_get_view_url', $invoice_url, $this );
1688
	}
1689
1690
	/**
1691
	 * Retrieves the payment url.
1692
	 *
1693
	 * @since 1.0.19
1694
	 * @return string
1695
	 */
1696
	public function get_checkout_payment_url( $deprecated = false, $secret = false ) {
1697
1698
		// Retrieve the checkout url.
1699
        $pay_url = wpinv_get_checkout_uri();
1700
1701
		// Maybe force ssl.
1702
        if ( is_ssl() ) {
1703
            $pay_url = str_replace( 'http:', 'https:', $pay_url );
1704
        }
1705
1706
		// Add the invoice key.
1707
		$pay_url = add_query_arg( 'invoice_key', $this->get_key(), $pay_url );
1708
1709
		// (Maybe?) add a secret
1710
        if ( $secret ) {
1711
            $pay_url = add_query_arg( array( '_wpipay' => md5( $this->get_user_id() . '::' . $this->get_email() . '::' . $this->get_key() ) ), $pay_url );
1712
        }
1713
1714
        return apply_filters( 'wpinv_get_checkout_payment_url', $pay_url, $this, $deprecated, $secret );
1715
    }
1716
1717
    /**
1718
	 * Magic method for accessing invoice properties.
1719
	 *
1720
	 * @since 1.0.15
1721
	 * @access public
1722
	 *
1723
	 * @param string $key Discount data to retrieve
1724
	 * @param  string $context View or edit context.
1725
	 * @return mixed Value of the given invoice property (if set).
1726
	 */
1727
	public function get( $key, $context = 'view' ) {
1728
        return $this->get_prop( $key, $context );
1729
	}
1730
1731
    /*
1732
	|--------------------------------------------------------------------------
1733
	| Setters
1734
	|--------------------------------------------------------------------------
1735
	|
1736
	| Functions for setting item data. These should not update anything in the
1737
	| database itself and should only change what is stored in the class
1738
	| object.
1739
    */
1740
1741
    /**
1742
	 * Magic method for setting invoice properties.
1743
	 *
1744
	 * @since 1.0.19
1745
	 * @access public
1746
	 *
1747
	 * @param string $key Discount data to retrieve
1748
	 * @param  mixed $value new value.
1749
	 * @return mixed Value of the given invoice property (if set).
1750
	 */
1751
	public function set( $key, $value ) {
1752
1753
        $setter = "set_$key";
1754
        if ( is_callable( array( $this, $setter ) ) ) {
1755
            $this->{$setter}( $value );
1756
        }
1757
1758
	}
1759
1760
	/**
1761
	 * Sets item status.
1762
	 *
1763
	 * @since 1.0.19
1764
	 * @param string $new_status    New status.
1765
	 * @param string $note          Optional note to add.
1766
	 * @param bool   $manual_update Is this a manual status change?.
1767
	 * @return array details of change.
1768
	 */
1769
	public function set_status( $new_status, $note = '', $manual_update = false ) {
1770
		$old_status = $this->get_status();
1771
1772
		$this->set_prop( 'status', $new_status );
1773
1774
		// If setting the status, ensure it's set to a valid status.
1775
		if ( true === $this->object_read ) {
1776
1777
			// Only allow valid new status.
1778
			if ( ! array_key_exists( $new_status, wpinv_get_invoice_statuses( false, true ) ) ) {
1779
				$new_status = 'wpi-pending';
1780
			}
1781
1782
			// If the old status is set but unknown (e.g. draft) assume its pending for action usage.
1783
			if ( $old_status && ! array_key_exists( $new_status, wpinv_get_invoice_statuses( false, true ) ) ) {
1784
				$old_status = 'wpi-pending';
1785
			}
1786
		}
1787
1788
		if ( true === $this->object_read && $old_status !== $new_status ) {
1789
			$this->status_transition = array(
0 ignored issues
show
Documentation Bug introduced by
It seems like array('from' => ! empty(...> (bool)$manual_update) of type array<string,boolean|mixed|string> is incompatible with the declared type boolean of property $status_transition.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
1790
				'from'   => ! empty( $this->status_transition['from'] ) ? $this->status_transition['from'] : $old_status,
1791
				'to'     => $new_status,
1792
				'note'   => $note,
1793
				'manual' => (bool) $manual_update,
1794
			);
1795
1796
			if ( $manual_update ) {
1797
				do_action( 'getpaid_' . $this->object_type .'_edit_status', $this->get_id(), $new_status );
1798
			}
1799
1800
			$this->maybe_set_date_paid();
1801
1802
		}
1803
1804
		return array(
1805
			'from' => $old_status,
1806
			'to'   => $new_status,
1807
		);
1808
	}
1809
1810
	/**
1811
	 * Maybe set date paid.
1812
	 *
1813
	 * Sets the date paid variable when transitioning to the payment complete
1814
	 * order status.
1815
	 *
1816
	 * @since 1.0.19
1817
	 */
1818
	public function maybe_set_date_paid() {
1819
1820
		if ( ! $this->get_date_completed( 'edit' ) && $this->is_paid() ) {
1821
			$this->set_date_completed( current_time( 'mysql' ) );
1822
		}
1823
	}
1824
1825
    /**
1826
	 * Set parent invoice ID.
1827
	 *
1828
	 * @since 1.0.19
1829
	 */
1830
	public function set_parent_id( $value ) {
1831
		if ( $value && ( $value === $this->get_id() || ! get_post( $value ) ) ) {
1832
			return;
1833
		}
1834
		$this->set_prop( 'parent_id', absint( $value ) );
1835
    }
1836
1837
    /**
1838
	 * Set plugin version when the invoice was created.
1839
	 *
1840
	 * @since 1.0.19
1841
	 */
1842
	public function set_version( $value ) {
1843
		$this->set_prop( 'version', $value );
1844
    }
1845
1846
    /**
1847
	 * Set date when the invoice was created.
1848
	 *
1849
	 * @since 1.0.19
1850
	 * @param string $value Value to set.
1851
     * @return bool Whether or not the date was set.
1852
	 */
1853
	public function set_date_created( $value ) {
1854
        $date = strtotime( $value );
1855
1856
        if ( $date && $date !== '0000-00-00 00:00:00' ) {
1857
            $this->set_prop( 'date_created', date( 'Y-m-d H:i:s', $date ) );
1858
            return true;
1859
        }
1860
1861
        return $this->set_prop( 'date_created', '' );
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->set_prop('date_created', '') targeting GetPaid_Data::set_prop() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
1862
1863
    }
1864
1865
    /**
1866
	 * Set date invoice due date.
1867
	 *
1868
	 * @since 1.0.19
1869
	 * @param string $value Value to set.
1870
     * @return bool Whether or not the date was set.
1871
	 */
1872
	public function set_due_date( $value ) {
1873
        $date = strtotime( $value );
1874
1875
        if ( $date && $date !== '0000-00-00 00:00:00' ) {
1876
            $this->set_prop( 'due_date', date( 'Y-m-d H:i:s', $date ) );
1877
            return true;
1878
        }
1879
1880
		$this->set_prop( 'due_date', '' );
1881
        return false;
1882
1883
    }
1884
1885
    /**
1886
	 * Alias of self::set_due_date().
1887
	 *
1888
	 * @since 1.0.19
1889
	 * @param  string $value New name.
1890
	 */
1891
	public function set_date_due( $value ) {
1892
		$this->set_due_date( $value );
1893
    }
1894
1895
    /**
1896
	 * Set date invoice was completed.
1897
	 *
1898
	 * @since 1.0.19
1899
	 * @param string $value Value to set.
1900
     * @return bool Whether or not the date was set.
1901
	 */
1902
	public function set_completed_date( $value ) {
1903
        $date = strtotime( $value );
1904
1905
        if ( $date && $date !== '0000-00-00 00:00:00'  ) {
1906
            $this->set_prop( 'completed_date', date( 'Y-m-d H:i:s', $date ) );
1907
            return true;
1908
        }
1909
1910
		$this->set_prop( 'completed_date', '' );
1911
        return false;
1912
1913
    }
1914
1915
    /**
1916
	 * Alias of self::set_completed_date().
1917
	 *
1918
	 * @since 1.0.19
1919
	 * @param  string $value New name.
1920
	 */
1921
	public function set_date_completed( $value ) {
1922
		$this->set_completed_date( $value );
1923
    }
1924
1925
    /**
1926
	 * Set date when the invoice was last modified.
1927
	 *
1928
	 * @since 1.0.19
1929
	 * @param string $value Value to set.
1930
     * @return bool Whether or not the date was set.
1931
	 */
1932
	public function set_date_modified( $value ) {
1933
        $date = strtotime( $value );
1934
1935
        if ( $date && $date !== '0000-00-00 00:00:00' ) {
1936
            $this->set_prop( 'date_modified', date( 'Y-m-d H:i:s', $date ) );
1937
            return true;
1938
        }
1939
1940
		$this->set_prop( 'date_modified', '' );
1941
        return false;
1942
1943
    }
1944
1945
    /**
1946
	 * Set the invoice number.
1947
	 *
1948
	 * @since 1.0.19
1949
	 * @param  string $value New number.
1950
	 */
1951
	public function set_number( $value ) {
1952
        $number = sanitize_text_field( $value );
1953
		$this->set_prop( 'number', $number );
1954
    }
1955
1956
    /**
1957
	 * Set the invoice type.
1958
	 *
1959
	 * @since 1.0.19
1960
	 * @param  string $value Type.
1961
	 */
1962
	public function set_type( $value ) {
1963
        $type = sanitize_text_field( str_replace( 'wpi_', '', $value ) );
1964
		$this->set_prop( 'type', $type );
1965
    }
1966
1967
    /**
1968
	 * Set the invoice post type.
1969
	 *
1970
	 * @since 1.0.19
1971
	 * @param  string $value Post type.
1972
	 */
1973
	public function set_post_type( $value ) {
1974
        if ( getpaid_is_invoice_post_type( $value ) ) {
1975
            $this->set_prop( 'post_type', $value );
1976
        }
1977
    }
1978
1979
    /**
1980
	 * Set the invoice key.
1981
	 *
1982
	 * @since 1.0.19
1983
	 * @param  string $value New key.
1984
	 */
1985
	public function set_key( $value ) {
1986
        $key = sanitize_text_field( $value );
1987
		$this->set_prop( 'key', $key );
1988
    }
1989
1990
    /**
1991
	 * Set the invoice mode.
1992
	 *
1993
	 * @since 1.0.19
1994
	 * @param  string $value mode.
1995
	 */
1996
	public function set_mode( $value ) {
1997
        if ( ! in_array( $value, array( 'live', 'test' ) ) ) {
1998
            $this->set_prop( 'value', $value );
1999
        }
2000
    }
2001
2002
    /**
2003
	 * Set the invoice path.
2004
	 *
2005
	 * @since 1.0.19
2006
	 * @param  string $value path.
2007
	 */
2008
	public function set_path( $value ) {
2009
        $this->set_prop( 'path', $value );
2010
    }
2011
2012
    /**
2013
	 * Set the invoice name.
2014
	 *
2015
	 * @since 1.0.19
2016
	 * @param  string $value New name.
2017
	 */
2018
	public function set_name( $value ) {
2019
        $name = sanitize_text_field( $value );
2020
		$this->set_prop( 'name', $name );
2021
    }
2022
2023
    /**
2024
	 * Alias of self::set_name().
2025
	 *
2026
	 * @since 1.0.19
2027
	 * @param  string $value New name.
2028
	 */
2029
	public function set_title( $value ) {
2030
		$this->set_name( $value );
2031
    }
2032
2033
    /**
2034
	 * Set the invoice description.
2035
	 *
2036
	 * @since 1.0.19
2037
	 * @param  string $value New description.
2038
	 */
2039
	public function set_description( $value ) {
2040
        $description = wp_kses_post( $value );
2041
		return $this->set_prop( 'description', $description );
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->set_prop('description', $description) targeting GetPaid_Data::set_prop() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
2042
    }
2043
2044
    /**
2045
	 * Alias of self::set_description().
2046
	 *
2047
	 * @since 1.0.19
2048
	 * @param  string $value New description.
2049
	 */
2050
	public function set_excerpt( $value ) {
2051
		$this->set_description( $value );
2052
    }
2053
2054
    /**
2055
	 * Alias of self::set_description().
2056
	 *
2057
	 * @since 1.0.19
2058
	 * @param  string $value New description.
2059
	 */
2060
	public function set_summary( $value ) {
2061
		$this->set_description( $value );
2062
    }
2063
2064
    /**
2065
	 * Set the receiver of the invoice.
2066
	 *
2067
	 * @since 1.0.19
2068
	 * @param  int $value New author.
2069
	 */
2070
	public function set_author( $value ) {
2071
		$this->set_prop( 'author', (int) $value );
2072
    }
2073
2074
    /**
2075
	 * Alias of self::set_author().
2076
	 *
2077
	 * @since 1.0.19
2078
	 * @param  int $value New user id.
2079
	 */
2080
	public function set_user_id( $value ) {
2081
		$this->set_author( $value );
2082
    }
2083
2084
    /**
2085
	 * Alias of self::set_author().
2086
	 *
2087
	 * @since 1.0.19
2088
	 * @param  int $value New user id.
2089
	 */
2090
	public function set_customer_id( $value ) {
2091
		$this->set_author( $value );
2092
    }
2093
2094
    /**
2095
	 * Set the customer's ip.
2096
	 *
2097
	 * @since 1.0.19
2098
	 * @param  string $value ip address.
2099
	 */
2100
	public function set_ip( $value ) {
2101
		$this->set_prop( 'ip', $value );
2102
    }
2103
2104
    /**
2105
	 * Alias of self::set_ip().
2106
	 *
2107
	 * @since 1.0.19
2108
	 * @param  string $value ip address.
2109
	 */
2110
	public function set_user_ip( $value ) {
2111
		$this->set_ip( $value );
2112
    }
2113
2114
    /**
2115
	 * Set the customer's first name.
2116
	 *
2117
	 * @since 1.0.19
2118
	 * @param  string $value first name.
2119
	 */
2120
	public function set_first_name( $value ) {
2121
		$this->set_prop( 'first_name', $value );
2122
    }
2123
2124
    /**
2125
	 * Alias of self::set_first_name().
2126
	 *
2127
	 * @since 1.0.19
2128
	 * @param  string $value first name.
2129
	 */
2130
	public function set_user_first_name( $value ) {
2131
		$this->set_first_name( $value );
2132
    }
2133
2134
    /**
2135
	 * Alias of self::set_first_name().
2136
	 *
2137
	 * @since 1.0.19
2138
	 * @param  string $value first name.
2139
	 */
2140
	public function set_customer_first_name( $value ) {
2141
		$this->set_first_name( $value );
2142
    }
2143
2144
    /**
2145
	 * Set the customer's last name.
2146
	 *
2147
	 * @since 1.0.19
2148
	 * @param  string $value last name.
2149
	 */
2150
	public function set_last_name( $value ) {
2151
		$this->set_prop( 'last_name', $value );
2152
    }
2153
2154
    /**
2155
	 * Alias of self::set_last_name().
2156
	 *
2157
	 * @since 1.0.19
2158
	 * @param  string $value last name.
2159
	 */
2160
	public function set_user_last_name( $value ) {
2161
		$this->set_last_name( $value );
2162
    }
2163
2164
    /**
2165
	 * Alias of self::set_last_name().
2166
	 *
2167
	 * @since 1.0.19
2168
	 * @param  string $value last name.
2169
	 */
2170
	public function set_customer_last_name( $value ) {
2171
		$this->set_last_name( $value );
2172
    }
2173
2174
    /**
2175
	 * Set the customer's phone number.
2176
	 *
2177
	 * @since 1.0.19
2178
	 * @param  string $value phone.
2179
	 */
2180
	public function set_phone( $value ) {
2181
		$this->set_prop( 'phone', $value );
2182
    }
2183
2184
    /**
2185
	 * Alias of self::set_phone().
2186
	 *
2187
	 * @since 1.0.19
2188
	 * @param  string $value phone.
2189
	 */
2190
	public function set_user_phone( $value ) {
2191
		$this->set_phone( $value );
2192
    }
2193
2194
    /**
2195
	 * Alias of self::set_phone().
2196
	 *
2197
	 * @since 1.0.19
2198
	 * @param  string $value phone.
2199
	 */
2200
	public function set_customer_phone( $value ) {
2201
		$this->set_phone( $value );
2202
    }
2203
2204
    /**
2205
	 * Alias of self::set_phone().
2206
	 *
2207
	 * @since 1.0.19
2208
	 * @param  string $value phone.
2209
	 */
2210
	public function set_phone_number( $value ) {
2211
		$this->set_phone( $value );
2212
    }
2213
2214
    /**
2215
	 * Set the customer's email address.
2216
	 *
2217
	 * @since 1.0.19
2218
	 * @param  string $value email address.
2219
	 */
2220
	public function set_email( $value ) {
2221
		$this->set_prop( 'email', $value );
2222
    }
2223
2224
    /**
2225
	 * Alias of self::set_email().
2226
	 *
2227
	 * @since 1.0.19
2228
	 * @param  string $value email address.
2229
	 */
2230
	public function set_user_email( $value ) {
2231
		$this->set_email( $value );
2232
    }
2233
2234
    /**
2235
	 * Alias of self::set_email().
2236
	 *
2237
	 * @since 1.0.19
2238
	 * @param  string $value email address.
2239
	 */
2240
	public function set_email_address( $value ) {
2241
		$this->set_email( $value );
2242
    }
2243
2244
    /**
2245
	 * Alias of self::set_email().
2246
	 *
2247
	 * @since 1.0.19
2248
	 * @param  string $value email address.
2249
	 */
2250
	public function set_customer_email( $value ) {
2251
		$this->set_email( $value );
2252
    }
2253
2254
    /**
2255
	 * Set the customer's country.
2256
	 *
2257
	 * @since 1.0.19
2258
	 * @param  string $value country.
2259
	 */
2260
	public function set_country( $value ) {
2261
		$this->set_prop( 'country', $value );
2262
    }
2263
2264
    /**
2265
	 * Alias of self::set_country().
2266
	 *
2267
	 * @since 1.0.19
2268
	 * @param  string $value country.
2269
	 */
2270
	public function set_user_country( $value ) {
2271
		$this->set_country( $value );
2272
    }
2273
2274
    /**
2275
	 * Alias of self::set_country().
2276
	 *
2277
	 * @since 1.0.19
2278
	 * @param  string $value country.
2279
	 */
2280
	public function set_customer_country( $value ) {
2281
		$this->set_country( $value );
2282
    }
2283
2284
    /**
2285
	 * Set the customer's state.
2286
	 *
2287
	 * @since 1.0.19
2288
	 * @param  string $value state.
2289
	 */
2290
	public function set_state( $value ) {
2291
		$this->set_prop( 'state', $value );
2292
    }
2293
2294
    /**
2295
	 * Alias of self::set_state().
2296
	 *
2297
	 * @since 1.0.19
2298
	 * @param  string $value state.
2299
	 */
2300
	public function set_user_state( $value ) {
2301
		$this->set_state( $value );
2302
    }
2303
2304
    /**
2305
	 * Alias of self::set_state().
2306
	 *
2307
	 * @since 1.0.19
2308
	 * @param  string $value state.
2309
	 */
2310
	public function set_customer_state( $value ) {
2311
		$this->set_state( $value );
2312
    }
2313
2314
    /**
2315
	 * Set the customer's city.
2316
	 *
2317
	 * @since 1.0.19
2318
	 * @param  string $value city.
2319
	 */
2320
	public function set_city( $value ) {
2321
		$this->set_prop( 'city', $value );
2322
    }
2323
2324
    /**
2325
	 * Alias of self::set_city().
2326
	 *
2327
	 * @since 1.0.19
2328
	 * @param  string $value city.
2329
	 */
2330
	public function set_user_city( $value ) {
2331
		$this->set_city( $value );
2332
    }
2333
2334
    /**
2335
	 * Alias of self::set_city().
2336
	 *
2337
	 * @since 1.0.19
2338
	 * @param  string $value city.
2339
	 */
2340
	public function set_customer_city( $value ) {
2341
		$this->set_city( $value );
2342
    }
2343
2344
    /**
2345
	 * Set the customer's zip code.
2346
	 *
2347
	 * @since 1.0.19
2348
	 * @param  string $value zip.
2349
	 */
2350
	public function set_zip( $value ) {
2351
		$this->set_prop( 'zip', $value );
2352
    }
2353
2354
    /**
2355
	 * Alias of self::set_zip().
2356
	 *
2357
	 * @since 1.0.19
2358
	 * @param  string $value zip.
2359
	 */
2360
	public function set_user_zip( $value ) {
2361
		$this->set_zip( $value );
2362
    }
2363
2364
    /**
2365
	 * Alias of self::set_zip().
2366
	 *
2367
	 * @since 1.0.19
2368
	 * @param  string $value zip.
2369
	 */
2370
	public function set_customer_zip( $value ) {
2371
		$this->set_zip( $value );
2372
    }
2373
2374
    /**
2375
	 * Set the customer's company.
2376
	 *
2377
	 * @since 1.0.19
2378
	 * @param  string $value company.
2379
	 */
2380
	public function set_company( $value ) {
2381
		$this->set_prop( 'company', $value );
2382
    }
2383
2384
    /**
2385
	 * Alias of self::set_company().
2386
	 *
2387
	 * @since 1.0.19
2388
	 * @param  string $value company.
2389
	 */
2390
	public function set_user_company( $value ) {
2391
		$this->set_company( $value );
2392
    }
2393
2394
    /**
2395
	 * Alias of self::set_company().
2396
	 *
2397
	 * @since 1.0.19
2398
	 * @param  string $value company.
2399
	 */
2400
	public function set_customer_company( $value ) {
2401
		$this->set_company( $value );
2402
    }
2403
2404
    /**
2405
	 * Set the customer's var number.
2406
	 *
2407
	 * @since 1.0.19
2408
	 * @param  string $value var number.
2409
	 */
2410
	public function set_vat_number( $value ) {
2411
		$this->set_prop( 'vat_number', $value );
2412
    }
2413
2414
    /**
2415
	 * Alias of self::set_vat_number().
2416
	 *
2417
	 * @since 1.0.19
2418
	 * @param  string $value var number.
2419
	 */
2420
	public function set_user_vat_number( $value ) {
2421
		$this->set_vat_number( $value );
2422
    }
2423
2424
    /**
2425
	 * Alias of self::set_vat_number().
2426
	 *
2427
	 * @since 1.0.19
2428
	 * @param  string $value var number.
2429
	 */
2430
	public function set_customer_vat_number( $value ) {
2431
		$this->set_vat_number( $value );
2432
    }
2433
2434
    /**
2435
	 * Set the customer's vat rate.
2436
	 *
2437
	 * @since 1.0.19
2438
	 * @param  string $value var rate.
2439
	 */
2440
	public function set_vat_rate( $value ) {
2441
		$this->set_prop( 'vat_rate', $value );
2442
    }
2443
2444
    /**
2445
	 * Alias of self::set_vat_rate().
2446
	 *
2447
	 * @since 1.0.19
2448
	 * @param  string $value var number.
2449
	 */
2450
	public function set_user_vat_rate( $value ) {
2451
		$this->set_vat_rate( $value );
2452
    }
2453
2454
    /**
2455
	 * Alias of self::set_vat_rate().
2456
	 *
2457
	 * @since 1.0.19
2458
	 * @param  string $value var number.
2459
	 */
2460
	public function set_customer_vat_rate( $value ) {
2461
		$this->set_vat_rate( $value );
2462
    }
2463
2464
    /**
2465
	 * Set the customer's address.
2466
	 *
2467
	 * @since 1.0.19
2468
	 * @param  string $value address.
2469
	 */
2470
	public function set_address( $value ) {
2471
		$this->set_prop( 'address', $value );
2472
    }
2473
2474
    /**
2475
	 * Alias of self::set_address().
2476
	 *
2477
	 * @since 1.0.19
2478
	 * @param  string $value address.
2479
	 */
2480
	public function set_user_address( $value ) {
2481
		$this->set_address( $value );
2482
    }
2483
2484
    /**
2485
	 * Alias of self::set_address().
2486
	 *
2487
	 * @since 1.0.19
2488
	 * @param  string $value address.
2489
	 */
2490
	public function set_customer_address( $value ) {
2491
		$this->set_address( $value );
2492
    }
2493
2494
    /**
2495
	 * Set whether the customer has viewed the invoice or not.
2496
	 *
2497
	 * @since 1.0.19
2498
	 * @param  int|bool $value confirmed.
2499
	 */
2500
	public function set_is_viewed( $value ) {
2501
		$this->set_prop( 'is_viewed', $value );
2502
	}
2503
2504
	/**
2505
	 * Set extra email recipients.
2506
	 *
2507
	 * @since 1.0.19
2508
	 * @param  string $value email recipients.
2509
	 */
2510
	public function set_email_cc( $value ) {
2511
		$this->set_prop( 'email_cc', $value );
2512
	}
2513
2514
	/**
2515
	 * Set the invoice template.
2516
	 *
2517
	 * @since 1.0.19
2518
	 * @param  string $value email recipients.
2519
	 */
2520
	public function set_template( $value ) {
2521
		if ( in_array( $value, array( 'quantity', 'hours', 'amount' ) ) ) {
2522
			$this->set_prop( 'template', $value );
2523
		}
2524
	}
2525
2526
	/**
2527
	 * Set the customer's address confirmed status.
2528
	 *
2529
	 * @since 1.0.19
2530
	 * @param  int|bool $value confirmed.
2531
	 */
2532
	public function set_address_confirmed( $value ) {
2533
		$this->set_prop( 'address_confirmed', $value );
2534
    }
2535
2536
    /**
2537
	 * Alias of self::set_address_confirmed().
2538
	 *
2539
	 * @since 1.0.19
2540
	 * @param  int|bool $value confirmed.
2541
	 */
2542
	public function set_user_address_confirmed( $value ) {
2543
		$this->set_address_confirmed( $value );
2544
    }
2545
2546
    /**
2547
	 * Alias of self::set_address_confirmed().
2548
	 *
2549
	 * @since 1.0.19
2550
	 * @param  int|bool $value confirmed.
2551
	 */
2552
	public function set_customer_address_confirmed( $value ) {
2553
		$this->set_address_confirmed( $value );
2554
    }
2555
2556
    /**
2557
	 * Set the invoice sub total.
2558
	 *
2559
	 * @since 1.0.19
2560
	 * @param  float $value sub total.
2561
	 */
2562
	public function set_subtotal( $value ) {
2563
		$this->set_prop( 'subtotal', $value );
2564
    }
2565
2566
    /**
2567
	 * Set the invoice discount amount.
2568
	 *
2569
	 * @since 1.0.19
2570
	 * @param  float $value discount total.
2571
	 */
2572
	public function set_total_discount( $value ) {
2573
		$this->set_prop( 'total_discount', $value );
2574
    }
2575
2576
    /**
2577
	 * Alias of self::set_total_discount().
2578
	 *
2579
	 * @since 1.0.19
2580
	 * @param  float $value discount total.
2581
	 */
2582
	public function set_discount( $value ) {
2583
		$this->set_total_discount( $value );
2584
    }
2585
2586
    /**
2587
	 * Set the invoice tax amount.
2588
	 *
2589
	 * @since 1.0.19
2590
	 * @param  float $value tax total.
2591
	 */
2592
	public function set_total_tax( $value ) {
2593
		$this->set_prop( 'total_tax', $value );
2594
    }
2595
2596
    /**
2597
	 * Alias of self::set_total_tax().
2598
	 *
2599
	 * @since 1.0.19
2600
	 * @param  float $value tax total.
2601
	 */
2602
	public function set_tax_total( $value ) {
2603
		$this->set_total_tax( $value );
2604
    }
2605
2606
    /**
2607
	 * Set the invoice fees amount.
2608
	 *
2609
	 * @since 1.0.19
2610
	 * @param  float $value fees total.
2611
	 */
2612
	public function set_total_fees( $value ) {
2613
		$this->set_prop( 'total_fees', $value );
2614
    }
2615
2616
    /**
2617
	 * Alias of self::set_total_fees().
2618
	 *
2619
	 * @since 1.0.19
2620
	 * @param  float $value fees total.
2621
	 */
2622
	public function set_fees_total( $value ) {
2623
		$this->set_total_fees( $value );
2624
    }
2625
2626
    /**
2627
	 * Set the invoice fees.
2628
	 *
2629
	 * @since 1.0.19
2630
	 * @param  array $value fees.
2631
	 */
2632
	public function set_fees( $value ) {
2633
2634
        $this->set_prop( 'fees', array() );
2635
2636
        // Ensure that we have an array.
2637
        if ( ! is_array( $value ) ) {
0 ignored issues
show
introduced by
The condition is_array($value) is always true.
Loading history...
2638
            return;
2639
        }
2640
2641
        foreach ( $value as $name => $data ) {
2642
            if ( isset( $data['amount'] ) ) {
2643
                $this->add_fee( $name, $data['amount'], $data['recurring'] );
2644
            }
2645
        }
2646
2647
    }
2648
2649
    /**
2650
	 * Set the invoice taxes.
2651
	 *
2652
	 * @since 1.0.19
2653
	 * @param  array $value taxes.
2654
	 */
2655
	public function set_taxes( $value ) {
2656
		$this->set_prop( 'taxes', $value );
2657
    }
2658
2659
    /**
2660
	 * Set the invoice discounts.
2661
	 *
2662
	 * @since 1.0.19
2663
	 * @param  array $value discounts.
2664
	 */
2665
	public function set_discounts( $value ) {
2666
		$this->set_prop( 'discounts', array() );
2667
2668
        // Ensure that we have an array.
2669
        if ( ! is_array( $value ) ) {
0 ignored issues
show
introduced by
The condition is_array($value) is always true.
Loading history...
2670
            return;
2671
        }
2672
2673
        foreach ( $value as $name => $data ) {
2674
            if ( isset( $data['amount'] ) ) {
2675
                $this->add_discount( $name, $data['amount'], $data['recurring'] );
2676
            }
2677
        }
2678
    }
2679
2680
    /**
2681
	 * Set the invoice items.
2682
	 *
2683
	 * @since 1.0.19
2684
	 * @param  GetPaid_Form_Item[] $value items.
2685
	 */
2686
	public function set_items( $value ) {
2687
2688
        // Remove existing items.
2689
        $this->set_prop( 'items', array() );
2690
2691
        // Ensure that we have an array.
2692
        if ( ! is_array( $value ) ) {
0 ignored issues
show
introduced by
The condition is_array($value) is always true.
Loading history...
2693
            return;
2694
        }
2695
2696
        foreach ( $value as $item ) {
2697
            $this->add_item( $item );
2698
        }
2699
2700
    }
2701
2702
    /**
2703
	 * Set the payment form.
2704
	 *
2705
	 * @since 1.0.19
2706
	 * @param  int $value payment form.
2707
	 */
2708
	public function set_payment_form( $value ) {
2709
		$this->set_prop( 'payment_form', $value );
2710
    }
2711
2712
    /**
2713
	 * Set the submission id.
2714
	 *
2715
	 * @since 1.0.19
2716
	 * @param  string $value submission id.
2717
	 */
2718
	public function set_submission_id( $value ) {
2719
		$this->set_prop( 'submission_id', $value );
2720
    }
2721
2722
    /**
2723
	 * Set the discount code.
2724
	 *
2725
	 * @since 1.0.19
2726
	 * @param  string $value discount code.
2727
	 */
2728
	public function set_discount_code( $value ) {
2729
		$this->set_prop( 'discount_code', $value );
2730
    }
2731
2732
    /**
2733
	 * Set the gateway.
2734
	 *
2735
	 * @since 1.0.19
2736
	 * @param  string $value gateway.
2737
	 */
2738
	public function set_gateway( $value ) {
2739
		$this->set_prop( 'gateway', $value );
2740
    }
2741
2742
    /**
2743
	 * Set the transaction id.
2744
	 *
2745
	 * @since 1.0.19
2746
	 * @param  string $value transaction id.
2747
	 */
2748
	public function set_transaction_id( $value ) {
2749
		$this->set_prop( 'transaction_id', $value );
2750
    }
2751
2752
    /**
2753
	 * Set the currency id.
2754
	 *
2755
	 * @since 1.0.19
2756
	 * @param  string $value currency id.
2757
	 */
2758
	public function set_currency( $value ) {
2759
		$this->set_prop( 'currency', $value );
2760
    }
2761
2762
    /**
2763
	 * Set the subscription id.
2764
	 *
2765
	 * @since 1.0.19
2766
	 * @param  string $value subscription id.
2767
	 */
2768
	public function set_subscription_id( $value ) {
2769
		$this->set_prop( 'subscription_id', $value );
2770
    }
2771
2772
    /*
2773
	|--------------------------------------------------------------------------
2774
	| Boolean methods
2775
	|--------------------------------------------------------------------------
2776
	|
2777
	| Return true or false.
2778
	|
2779
    */
2780
2781
    /**
2782
     * Checks if this is a parent invoice.
2783
     */
2784
    public function is_parent() {
2785
        $parent = $this->get_parent_id();
2786
        return apply_filters( 'wpinv_invoice_is_parent', empty( $parent ), $this );
2787
    }
2788
2789
    /**
2790
     * Checks if this is a renewal invoice.
2791
     */
2792
    public function is_renewal() {
2793
        return ! $this->is_parent();
2794
    }
2795
2796
    /**
2797
     * Checks if this is a recurring invoice.
2798
     */
2799
    public function is_recurring() {
2800
        return $this->is_renewal() || ! empty( $this->recurring_item );
2801
    }
2802
2803
    /**
2804
     * Checks if this is a taxable invoice.
2805
     */
2806
    public function is_taxable() {
2807
        return (int) $this->disable_taxes === 0;
0 ignored issues
show
Bug Best Practice introduced by
The property disable_taxes does not exist on WPInv_Invoice. Since you implemented __get, consider adding a @property annotation.
Loading history...
2808
	}
2809
2810
	/**
2811
	 * @deprecated
2812
	 */
2813
	public function has_vat() {
2814
        global $wpinv_euvat, $wpi_country;
2815
2816
        $requires_vat = false;
2817
2818
        if ( $this->country ) {
0 ignored issues
show
Bug Best Practice introduced by
The property country does not exist on WPInv_Invoice. Since you implemented __get, consider adding a @property annotation.
Loading history...
2819
            $wpi_country        = $this->country;
2820
            $requires_vat       = $wpinv_euvat->requires_vat( $requires_vat, $this->get_user_id(), $wpinv_euvat->invoice_has_digital_rule( $this ) );
2821
        }
2822
2823
        return apply_filters( 'wpinv_invoice_has_vat', $requires_vat, $this );
2824
	}
2825
2826
	/**
2827
	 * Checks to see if the invoice requires payment.
2828
	 */
2829
	public function is_free() {
2830
        $is_free = ! ( (float) wpinv_round_amount( $this->get_initial_total() ) > 0 );
2831
2832
		if ( $is_free && $this->is_recurring() ) {
2833
			$is_free = ! ( (float) wpinv_round_amount( $this->get_recurring_total() ) > 0 );
2834
		}
2835
2836
        return apply_filters( 'wpinv_invoice_is_free', $is_free, $this );
2837
    }
2838
2839
    /**
2840
     * Checks if the invoice is paid.
2841
     */
2842
    public function is_paid() {
2843
        $is_paid = $this->has_status( array( 'publish', 'wpi-processing', 'wpi-renewal' ) );
2844
        return apply_filters( 'wpinv_invoice_is_paid', $is_paid, $this );
2845
	}
2846
2847
	/**
2848
     * Checks if the invoice needs payment.
2849
     */
2850
	public function needs_payment() {
2851
		$needs_payment = ! $this->is_paid() && ! $this->is_free();
2852
        return apply_filters( 'wpinv_needs_payment', $needs_payment, $this );
2853
    }
2854
2855
	/**
2856
     * Checks if the invoice is refunded.
2857
     */
2858
	public function is_refunded() {
2859
        $is_refunded = $this->has_status( 'wpi-refunded' );
2860
        return apply_filters( 'wpinv_invoice_is_refunded', $is_refunded, $this );
2861
	}
2862
2863
	/**
2864
     * Checks if the invoice is draft.
2865
     */
2866
	public function is_draft() {
2867
        return $this->has_status( 'draft, auto-draft' );
2868
	}
2869
2870
    /**
2871
     * Checks if the invoice has a given status.
2872
     */
2873
    public function has_status( $status ) {
2874
        $status = wpinv_parse_list( $status );
2875
        return apply_filters( 'wpinv_has_status', in_array( $this->get_status(), $status ), $status );
2876
	}
2877
2878
	/**
2879
     * Checks if the invoice is of a given type.
2880
     */
2881
    public function is_type( $type ) {
2882
        $type = wpinv_parse_list( $type );
2883
        return in_array( $this->get_type(), $type );
2884
    }
2885
2886
    /**
2887
     * Checks if this is a quote object.
2888
     *
2889
     * @since 1.0.15
2890
     */
2891
    public function is_quote() {
2892
        return $this->has_status( 'wpi_quote' );
2893
    }
2894
2895
    /**
2896
     * Check if the invoice (or it's parent has a free trial).
2897
     *
2898
     */
2899
    public function has_free_trial() {
2900
        return $this->is_recurring() && 0 == $this->get_initial_total();
2901
	}
2902
2903
	/**
2904
     * @deprecated
2905
     */
2906
    public function is_free_trial() {
2907
        $this->has_free_trial();
2908
    }
2909
2910
	/**
2911
     * Check if the initial payment if 0.
2912
     *
2913
     */
2914
	public function is_initial_free() {
2915
        $is_initial_free = ! ( (float) wpinv_round_amount( $this->get_initial_total() ) > 0 );
2916
        return apply_filters( 'wpinv_invoice_is_initial_free', $is_initial_free, $this->get_cart_details(), $this );
2917
    }
2918
	
2919
	/**
2920
     * Check if the recurring item has a free trial.
2921
     *
2922
     */
2923
    public function item_has_free_trial() {
2924
2925
        // Ensure we have a recurring item.
2926
        if ( ! $this->is_recurring() ) {
2927
            return false;
2928
        }
2929
2930
        $item = new WPInv_Item( $this->recurring_item );
2931
        return $item->has_free_trial();
2932
	}
2933
2934
	/**
2935
     * Check if the free trial is a result of a discount.
2936
     */
2937
    public function is_free_trial_from_discount() {
2938
		return $this->has_free_trial() && ! $this->item_has_free_trial();
2939
	}
2940
	
2941
	/**
2942
     * @deprecated
2943
     */
2944
    public function discount_first_payment_only() {
2945
2946
		$discount_code = $this->get_discount_code();
2947
        if ( empty( $this->discount_code ) || ! $this->is_recurring() ) {
0 ignored issues
show
Bug Best Practice introduced by
The property discount_code does not exist on WPInv_Invoice. Since you implemented __get, consider adding a @property annotation.
Loading history...
2948
            return true;
2949
        }
2950
2951
        $discount = wpinv_get_discount_obj( $discount_code );
2952
2953
        if ( ! $discount || ! $discount->exists() ) {
0 ignored issues
show
introduced by
$discount is of type WPInv_Discount, thus it always evaluated to true.
Loading history...
2954
            return true;
2955
        }
2956
2957
        return ! $discount->get_is_recurring();
2958
    }
2959
2960
    /*
2961
	|--------------------------------------------------------------------------
2962
	| Cart related methods
2963
	|--------------------------------------------------------------------------
2964
	|
2965
	| Do not forget to recalculate totals after calling the following methods.
2966
	|
2967
    */
2968
2969
    /**
2970
     * Adds an item to the invoice.
2971
     *
2972
     * @param GetPaid_Form_Item $item
2973
     * @return WP_Error|Bool
2974
     */
2975
    public function add_item( $item ) {
2976
2977
        // Make sure that it is available for purchase.
2978
		if ( $item->get_id() > 0 && ! $item->can_purchase() ) {
2979
			return new WP_Error( 'invalid_item', __( 'This item is not available for purchase', 'invoicing' ) );
2980
        }
2981
2982
        // Do we have a recurring item?
2983
		if ( $item->is_recurring() ) {
2984
			$this->recurring_item = $item->get_id();
2985
        }
2986
2987
        // Invoice id.
2988
        $item->invoice_id = $this->get_id();
2989
2990
        // Retrieve all items.
2991
        $items = $this->get_items();
2992
        $items[ $item->get_id() ] = $item;
2993
2994
        $this->set_prop( 'items', $items );
2995
2996
    }
2997
2998
    /**
2999
	 * Retrieves a specific item.
3000
	 *
3001
	 * @since 1.0.19
3002
	 */
3003
	public function get_item( $item_id ) {
3004
        $items = $this->get_items();
3005
		return ( ! empty( $item_id ) && isset( $items[ $item_id ] ) ) ? $items[ $item_id ] : null;
3006
    }
3007
3008
    /**
3009
	 * Removes a specific item.
3010
	 *
3011
	 * @since 1.0.19
3012
	 */
3013
	public function remove_item( $item_id ) {
3014
        $items = $this->get_items();
3015
3016
        if ( $item_id == $this->recurring_item ) {
3017
            $this->recurring_item = null;
3018
        }
3019
3020
        if ( isset( $items[ $item_id ] ) ) {
3021
            unset( $items[ $item_id ] );
3022
            $this->set_prop( 'items', $items );
3023
        }
3024
    }
3025
3026
    /**
3027
     * Adds a fee to the invoice.
3028
     *
3029
     * @param string $fee
3030
     * @param float $value
3031
     * @return WP_Error|Bool
3032
     */
3033
    public function add_fee( $fee, $value, $recurring = false ) {
3034
3035
        $amount = wpinv_sanitize_amount( $value );
3036
        $fees   = $this->get_fees();
3037
3038
        if ( isset( $fees[ $fee ] ) && isset( $fees[ $fee ]['amount'] ) ) {
3039
3040
            $amount = $fees[ $fee ]['amount'] += $amount;
3041
			$fees[ $fee ] = array(
3042
                'amount'    => $amount,
3043
                'recurring' => (bool) $recurring,
3044
            );
3045
3046
		} else {
3047
			$fees[ $fee ] = array(
3048
                'amount'    => $amount,
3049
                'recurring' => (bool) $recurring,
3050
            );
3051
		}
3052
3053
        $this->set_prop( 'fees', $fee );
3054
3055
    }
3056
3057
    /**
3058
	 * Retrieves a specific fee.
3059
	 *
3060
	 * @since 1.0.19
3061
	 */
3062
	public function get_fee( $fee ) {
3063
        $fees = $this->get_fees();
3064
		return isset( $fees[ $fee ] ) ? $fees[ $fee ] : null;
3065
    }
3066
3067
    /**
3068
	 * Removes a specific fee.
3069
	 *
3070
	 * @since 1.0.19
3071
	 */
3072
	public function remove_fee( $fee ) {
3073
        $fees = $this->get_fees();
3074
        if ( isset( $fees[ $fee ] ) ) {
3075
            unset( $fees[ $fee ] );
3076
            $this->set_prop( 'fees', $fees );
3077
        }
3078
    }
3079
3080
    /**
3081
     * Adds a discount to the invoice.
3082
     *
3083
     * @param string $discount
3084
     * @param float $value
3085
     * @return WP_Error|Bool
3086
     */
3087
    public function add_discount( $discount, $value, $recurring = false ) {
3088
3089
        $amount    = wpinv_sanitize_amount( $value );
3090
        $discounts = $this->get_discounts();
3091
3092
        if ( isset( $discounts[ $discount ] ) && isset( $discounts[ $discount ]['amount'] ) ) {
3093
3094
            $amount = $discounts[ $discount ]['amount'] += $amount;
3095
			$discounts[ $discount ] = array(
3096
                'amount'    => $amount,
3097
                'recurring' => (bool) $recurring,
3098
            );
3099
3100
		} else {
3101
			$discounts[ $discount ] = array(
3102
                'amount'    => $amount,
3103
                'recurring' => (bool) $recurring,
3104
            );
3105
		}
3106
3107
        $this->set_prop( 'discounts', $discount );
3108
3109
    }
3110
3111
    /**
3112
	 * Retrieves a specific discount.
3113
	 *
3114
	 * @since 1.0.19
3115
	 */
3116
	public function get_discount( $discount = false ) {
3117
3118
		// Backwards compatibilty.
3119
		if ( empty( $discount ) ) {
3120
			return $this->get_total_discount();
3121
		}
3122
3123
        $discounts = $this->get_discounts();
3124
		return isset( $discounts[ $discount ] ) ? $discounts[ $discount ] : null;
3125
    }
3126
3127
    /**
3128
	 * Removes a specific discount.
3129
	 *
3130
	 * @since 1.0.19
3131
	 */
3132
	public function remove_discount( $discount ) {
3133
        $discounts = $this->get_discounts();
3134
        if ( isset( $discounts[ $discount ] ) ) {
3135
            unset( $discounts[ $discount ] );
3136
            $this->set_prop( 'discounts', $discounts );
3137
        }
3138
    }
3139
3140
    /**
3141
     * Adds a tax to the invoice.
3142
     *
3143
     * @param string $tax
3144
     * @param float $value
3145
     */
3146
    public function add_tax( $tax, $value, $recurring = true ) {
3147
3148
        if ( ! $this->is_taxable() ) {
3149
            return;
3150
        }
3151
3152
        $amount    = wpinv_sanitize_amount( $value );
3153
        $taxes     = $this->get_taxes();
3154
3155
        if ( isset( $taxes[ $tax ] ) && isset( $taxes[ $tax ]['amount'] ) ) {
3156
3157
            $amount = $taxes[ $tax ]['amount'] += $amount;
3158
			$taxes[ $tax ] = array(
3159
                'amount'    => $amount,
3160
                'recurring' => (bool) $recurring,
3161
            );
3162
3163
		} else {
3164
			$taxes[ $tax ] = array(
3165
                'amount'    => $amount,
3166
                'recurring' => (bool) $recurring,
3167
            );
3168
		}
3169
3170
        $this->set_prop( 'taxes', $tax );
3171
3172
    }
3173
3174
    /**
3175
	 * Retrieves a specific tax.
3176
	 *
3177
	 * @since 1.0.19
3178
	 */
3179
	public function get_tax( $tax ) {
3180
        $taxes = $this->get_taxes();
3181
		return isset( $taxes[ $tax ] ) ? $taxes[ $tax ] : null;
3182
    }
3183
3184
    /**
3185
	 * Removes a specific tax.
3186
	 *
3187
	 * @since 1.0.19
3188
	 */
3189
	public function remove_tax( $tax ) {
3190
        $taxes = $this->get_discounts();
3191
        if ( isset( $taxes[ $tax ] ) ) {
3192
            unset( $taxes[ $tax ] );
3193
            $this->set_prop( 'taxes', $taxes );
3194
        }
3195
    }
3196
3197
    /**
3198
	 * Recalculates the invoice subtotal.
3199
	 *
3200
	 * @since 1.0.19
3201
	 * @return float The recalculated subtotal
3202
	 */
3203
	public function recalculate_subtotal() {
3204
        $items     = $this->get_items();
3205
		$subtotal  = 0;
3206
		$recurring = 0;
3207
3208
        foreach ( $items as $item ) {
3209
			$subtotal  += $item->get_sub_total();
3210
			$recurring += $item->get_recurring_sub_total();
3211
        }
3212
3213
		if ( $this->is_renewal() ) {
3214
			$this->set_subtotal( $recurring );
3215
		} else {
3216
			$this->set_subtotal( $subtotal );
3217
		}
3218
3219
		$this->totals['subtotal'] = array(
3220
			'initial'   => $subtotal,
3221
			'recurring' => $recurring,
3222
		);
3223
3224
        return $this->is_renewal() ? $recurring : $subtotal;
3225
    }
3226
3227
    /**
3228
	 * Recalculates the invoice discount total.
3229
	 *
3230
	 * @since 1.0.19
3231
	 * @return float The recalculated discount
3232
	 */
3233
	public function recalculate_total_discount() {
3234
        $discounts = $this->get_discounts();
3235
		$discount  = 0;
3236
		$recurring = 0;
3237
3238
        foreach ( $discounts as $data ) {
3239
3240
			if ( $data['recurring'] ) {
3241
				$recurring += $data['amount'];
3242
			} else {
3243
				$discount += $data['amount'];
3244
			}
3245
3246
		}
3247
3248
		if ( $this->is_renewal() ) {
3249
			$this->set_total_discount( $recurring );
3250
		} else {
3251
			$this->set_total_discount( $discount );
3252
		}
3253
3254
		$this->totals['discount'] = array(
3255
			'initial'   => $discount,
3256
			'recurring' => $recurring,
3257
		);
3258
3259
		return $this->is_renewal() ? $recurring : $discount;
3260
3261
    }
3262
3263
    /**
3264
	 * Recalculates the invoice tax total.
3265
	 *
3266
	 * @since 1.0.19
3267
	 * @return float The recalculated tax
3268
	 */
3269
	public function recalculate_total_tax() {
3270
        $taxes     = $this->get_taxes();
3271
		$tax       = 0;
3272
		$recurring = 0;
3273
3274
        foreach ( $taxes as $data ) {
3275
3276
			if ( $data['recurring'] ) {
3277
				$recurring += $data['amount'];
3278
			} else {
3279
				$tax += $data['amount'];
3280
			}
3281
3282
		}
3283
3284
		if ( $this->is_renewal() ) {
3285
			$this->set_total_tax( $recurring );
3286
		} else {
3287
			$this->set_total_tax( $tax );
3288
		}
3289
3290
		$this->totals['tax'] = array(
3291
			'initial'   => $tax,
3292
			'recurring' => $recurring,
3293
		);
3294
3295
		return $this->is_renewal() ? $recurring : $tax;
3296
3297
    }
3298
3299
    /**
3300
	 * Recalculates the invoice fees total.
3301
	 *
3302
	 * @since 1.0.19
3303
	 * @return float The recalculated fee
3304
	 */
3305
	public function recalculate_total_fees() {
3306
		$fees      = $this->get_fees();
3307
		$fee       = 0;
3308
		$recurring = 0;
3309
3310
        foreach ( $fees as $data ) {
3311
3312
			if ( $data['recurring'] ) {
3313
				$recurring += $data['amount'];
3314
			} else {
3315
				$fee += $data['amount'];
3316
			}
3317
3318
		}
3319
3320
        if ( $this->is_renewal() ) {
3321
			$this->set_total_fees( $recurring );
3322
		} else {
3323
			$this->set_total_fees( $fee );
3324
		}
3325
3326
		$this->totals['fee'] = array(
3327
			'initial'   => $fee,
3328
			'recurring' => $recurring,
3329
		);
3330
3331
        $this->set_total_fees( $fee );
3332
        return $this->is_renewal() ? $recurring : $fee;
3333
    }
3334
3335
    /**
3336
	 * Recalculates the invoice total.
3337
	 *
3338
	 * @since 1.0.19
3339
     * @return float The invoice total
3340
	 */
3341
	public function recalculate_total() {
3342
        $this->recalculate_subtotal();
3343
        $this->recalculate_total_fees();
3344
        $this->recalculate_total_discount();
3345
        $this->recalculate_total_tax();
3346
		return $this->get_total();
3347
	}
3348
3349
	/**
3350
	 * @deprecated
3351
	 */
3352
    public function recalculate_totals( $temp = false ) {
3353
        $this->update_items( $temp );
0 ignored issues
show
Deprecated Code introduced by
The function WPInv_Invoice::update_items() has been deprecated. ( Ignorable by Annotation )

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

3353
        /** @scrutinizer ignore-deprecated */ $this->update_items( $temp );
Loading history...
3354
        $this->save( true );
0 ignored issues
show
Unused Code introduced by
The call to WPInv_Invoice::save() has too many arguments starting with true. ( Ignorable by Annotation )

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

3354
        $this->/** @scrutinizer ignore-call */ 
3355
               save( true );

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
3355
        return $this;
3356
    }
3357
3358
    /**
3359
     * Convert this to an array.
3360
     */
3361
    public function array_convert() {
3362
        return $this->get_data();
3363
    }
3364
3365
    /**
3366
     * Adds a note to an invoice.
3367
     *
3368
     * @param string $note The note being added.
3369
     *
3370
     */
3371
    public function add_note( $note = '', $customer_type = false, $added_by_user = false, $system = false ) {
3372
3373
        // Bail if no note specified or this invoice is not yet saved.
3374
        if ( ! $note || $this->get_id() == 0 ) {
3375
            return false;
3376
        }
3377
3378
        if ( ( ( is_user_logged_in() && wpinv_current_user_can_manage_invoicing() ) || $added_by_user ) && !$system ) {
0 ignored issues
show
introduced by
Consider adding parentheses for clarity. Current Interpretation: (is_user_logged_in() && ...d_by_user) && ! $system, Probably Intended Meaning: is_user_logged_in() && w...d_by_user && ! $system)
Loading history...
3379
            $user                 = get_user_by( 'id', get_current_user_id() );
3380
            $comment_author       = $user->display_name;
3381
            $comment_author_email = $user->user_email;
3382
        } else {
3383
            $comment_author       = 'System';
3384
            $comment_author_email = 'system@';
3385
            $comment_author_email .= isset( $_SERVER['HTTP_HOST'] ) ? str_replace( 'www.', '', $_SERVER['HTTP_HOST'] ) : 'noreply.com';
3386
            $comment_author_email = sanitize_email( $comment_author_email );
3387
        }
3388
3389
        do_action( 'wpinv_pre_insert_invoice_note', $this->get_id(), $note, $customer_type );
3390
3391
        $note_id = wp_insert_comment( wp_filter_comment( array(
3392
            'comment_post_ID'      => $this->get_id(),
3393
            'comment_content'      => $note,
3394
            'comment_agent'        => 'GetPaid',
3395
            'user_id'              => is_admin() ? get_current_user_id() : 0,
3396
            'comment_date'         => current_time( 'mysql' ),
3397
            'comment_date_gmt'     => current_time( 'mysql', 1 ),
3398
            'comment_approved'     => 1,
3399
            'comment_parent'       => 0,
3400
            'comment_author'       => $comment_author,
3401
            'comment_author_IP'    => wpinv_get_ip(),
3402
            'comment_author_url'   => '',
3403
            'comment_author_email' => $comment_author_email,
3404
            'comment_type'         => 'wpinv_note'
3405
        ) ) );
3406
3407
        do_action( 'wpinv_insert_payment_note', $note_id, $this->get_id(), $note );
3408
3409
        if ( $customer_type ) {
3410
            add_comment_meta( $note_id, '_wpi_customer_note', 1 );
0 ignored issues
show
Bug introduced by
$note_id of type false is incompatible with the type integer expected by parameter $comment_id of add_comment_meta(). ( Ignorable by Annotation )

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

3410
            add_comment_meta( /** @scrutinizer ignore-type */ $note_id, '_wpi_customer_note', 1 );
Loading history...
3411
            do_action( 'wpinv_new_customer_note', array( 'invoice_id' => $this->get_id(), 'user_note' => $note ) );
3412
        }
3413
3414
        return $note_id;
3415
	}
3416
3417
	/**
3418
     * Generates a unique key for the invoice.
3419
     */
3420
    public function generate_key( $string = '' ) {
3421
        $auth_key  = defined( 'AUTH_KEY' ) ? AUTH_KEY : '';
3422
        return strtolower(
3423
            md5( $this->get_id() . $string . date( 'Y-m-d H:i:s' ) . $auth_key . uniqid( 'wpinv', true ) )
3424
        );
3425
    }
3426
3427
    /**
3428
     * Generates a new number for the invoice.
3429
     */
3430
    public function generate_number() {
3431
        $number = $this->get_id();
3432
3433
        if ( $this->has_status( 'auto-draft' ) && wpinv_sequential_number_active( $this->post_type ) ) {
0 ignored issues
show
Bug Best Practice introduced by
The property post_type does not exist on WPInv_Invoice. Since you implemented __get, consider adding a @property annotation.
Loading history...
3434
            $next_number = wpinv_get_next_invoice_number( $this->post_type );
3435
            $number      = $next_number;
3436
        }
3437
3438
		$number = wpinv_format_invoice_number( $number, $this->post_type );
3439
3440
		return $number;
3441
	}
3442
3443
	/**
3444
	 * Handle the status transition.
3445
	 */
3446
	protected function status_transition() {
3447
		$status_transition = $this->status_transition;
3448
3449
		// Reset status transition variable.
3450
		$this->status_transition = false;
3451
3452
		if ( $status_transition ) {
3453
			try {
3454
3455
				// Fire a hook for the status change.
3456
				do_action( 'getpaid_invoice_status_' . $status_transition['to'], $this->get_id(), $this, $status_transition );
3457
3458
				// @deprecated this is deprecated and will be removed in the future.
3459
				do_action( 'wpinv_status_' . $status_transition['to'], $this->get_id(), $status_transition['from'] );
3460
3461
				if ( ! empty( $status_transition['from'] ) ) {
3462
3463
					/* translators: 1: old invoice status 2: new invoice status */
3464
					$transition_note = sprintf( __( 'Status changed from %1$s to %2$s.', 'invoicing' ), wpinv_status_nicename( $status_transition['from'] ), wpinv_status_nicename( $status_transition['to'] ) );
3465
3466
					// Fire another hook.
3467
					do_action( 'getpaid_invoice_status_' . $status_transition['from'] . '_to_' . $status_transition['to'], $this->get_id(), $this );
3468
					do_action( 'getpaid_invoice_status_changed', $this->get_id(), $status_transition['from'], $status_transition['to'], $this );
3469
3470
					// @deprecated this is deprecated and will be removed in the future.
3471
					do_action( 'wpinv_status_' . $status_transition['from'] . '_to_' . $status_transition['to'], $this->ID, $status_transition['from'] );
3472
3473
					// Note the transition occurred.
3474
					$this->add_note( trim( $status_transition['note'] . ' ' . $transition_note ), 0, $status_transition['manual'] );
3475
3476
					// Work out if this was for a payment, and trigger a payment_status hook instead.
3477
					if (
3478
						in_array( $status_transition['from'], array( 'wpi-cancelled', 'wpi-pending', 'wpi-failed' ), true )
3479
						&& in_array( $status_transition['to'], array( 'publish', 'wpi-processing', 'wpi-renewal' ), true )
3480
					) {
3481
						do_action( 'getpaid_invoice_payment_status_changed', $this->get_id(), $this, $status_transition );
3482
					}
3483
				} else {
3484
					/* translators: %s: new invoice status */
3485
					$transition_note = sprintf( __( 'Status set to %s.', 'invoicing' ), wpinv_status_nicename( $status_transition['to'] ) );
3486
3487
					// Note the transition occurred.
3488
					$this->add_note( trim( $status_transition['note'] . ' ' . $transition_note ), 0, $status_transition['manual'] );
3489
3490
				}
3491
			} catch ( Exception $e ) {
3492
				$this->add_note( __( 'Error during status transition.', 'invoicing' ) . ' ' . $e->getMessage() );
3493
			}
3494
		}
3495
	}
3496
3497
	/**
3498
	 * Updates an invoice status.
3499
	 */
3500
	public function update_status( $new_status = false, $note = '', $manual = false ) {
3501
3502
		// Fires before updating a status.
3503
		do_action( 'wpinv_before_invoice_status_change', $this->ID, $new_status, $this->get_status( 'edit' ) );
3504
3505
		// Update the status.
3506
		$this->set_status( $new_status, $note, $manual );
3507
3508
		// Save the order.
3509
		return $this->save();
3510
3511
	}
3512
3513
	/**
3514
	 * @deprecated
3515
	 */
3516
	public function refresh_item_ids() {
3517
        $item_ids = implode( ',', array_unique( array_keys( $this->get_items() ) ) );
3518
        update_post_meta( $this->get_id(), '_wpinv_item_ids', $item_ids );
3519
	}
3520
3521
	/**
3522
	 * @deprecated
3523
	 */
3524
	public function update_items( $temp = false ) {
3525
3526
		$this->set_items( $this->get_items() );
3527
3528
		if ( ! $temp ) {
3529
			$this->save();
3530
		}
3531
3532
        return $this;
3533
	}
3534
3535
	/**
3536
	 * @deprecated
3537
	 */
3538
    public function validate_discount() {
3539
3540
        $discount_code = $this->get_discount_code();
3541
3542
        if ( empty( $discount_code ) ) {
3543
            return false;
3544
        }
3545
3546
        $discount = wpinv_get_discount_obj( $discount_code );
3547
3548
        // Ensure it is active.
3549
        return $discount->exists();
3550
3551
    }
3552
3553
	/**
3554
	 * Refunds an invoice.
3555
	 */
3556
    public function refund() {
3557
		$this->set_status( 'wpi-refunded' );
3558
        $this->save();
3559
    }
3560
3561
	/**
3562
	 * Save data to the database.
3563
	 *
3564
	 * @since 1.0.19
3565
	 * @return int invoice ID
3566
	 */
3567
	public function save() {
3568
		$this->maybe_set_date_paid();
3569
		parent::save();
3570
		$this->status_transition();
3571
		return $this->get_id();
3572
	}
3573
3574
}
3575