Passed
Push — master ( 578d12...5023d9 )
by Brian
04:33
created

WPInv_Invoice::get_address()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 2
rs 10
cc 1
nc 1
nop 1
1
<?php
2
/**
3
 * Contains the invoice class.
4
 *
5
 * @since 1.0.19
6
 * @package Invoicing
7
 */
8
9
defined( 'ABSPATH' ) || exit;
10
11
/**
12
 * Invoice class.
13
 */
14
class WPInv_Invoice extends GetPaid_Data {
15
16
    /**
17
	 * Which data store to load.
18
	 *
19
	 * @var string
20
	 */
21
    protected $data_store_name = 'invoice';
22
23
    /**
24
	 * This is the name of this object type.
25
	 *
26
	 * @var string
27
	 */
28
    protected $object_type = 'invoice';
29
30
    /**
31
	 * Item Data array. This is the core item data exposed in APIs.
32
	 *
33
	 * @since 1.0.19
34
	 * @var array
35
	 */
36
	protected $data = array(
37
		'parent_id'            => 0,
38
		'status'               => 'wpi-pending',
39
		'version'              => '',
40
		'date_created'         => null,
41
        'date_modified'        => null,
42
        'due_date'             => null,
43
        'completed_date'       => null,
44
        'number'               => '',
45
        'title'                => '',
46
        'path'                 => '',
47
        'key'                  => '',
48
        'description'          => '',
49
        'author'               => 1,
50
        'type'                 => 'invoice',
51
        'post_type'            => 'wpi_invoice',
52
        'mode'                 => 'live',
53
        'user_ip'              => null,
54
        'first_name'           => null,
55
        'last_name'            => null,
56
        'phone'                => null,
57
        'email'                => null,
58
        'country'              => null,
59
        'city'                 => null,
60
        'state'                => null,
61
        'zip'                  => null,
62
        'company'              => null,
63
        'vat_number'           => null,
64
        'vat_rate'             => null,
65
        'address'              => null,
66
        'address_confirmed'    => false,
67
        'subtotal'             => 0,
68
        'total_discount'       => 0,
69
        'total_tax'            => 0,
70
        'total_fees'           => 0,
71
        'fees'                 => array(),
72
        'discounts'            => array(),
73
        'taxes'                => array(),
74
        'items'                => array(),
75
        'payment_form'         => 1,
76
        'submission_id'        => null,
77
        'discount_code'        => null,
78
        'gateway'              => 'none',
79
        'transaction_id'       => '',
80
        'currency'             => '',
81
        'disable_taxes'        => false,
82
		'subscription_id'      => null,
83
		'remote_subscription_id' => null,
84
		'is_viewed'            => false,
85
		'email_cc'             => '',
86
		'template'             => 'quantity', // hours, amount only
87
		'created_via'          => null,
88
    );
89
90
    /**
91
	 * Stores meta in cache for future reads.
92
	 *
93
	 * A group must be set to to enable caching.
94
	 *
95
	 * @var string
96
	 */
97
	protected $cache_group = 'getpaid_invoices';
98
99
    /**
100
     * Stores a reference to the original WP_Post object
101
     *
102
     * @var WP_Post
103
     */
104
    protected $post = null;
105
106
    /**
107
     * Stores a reference to the recurring item id instead of looping through the items.
108
     *
109
     * @var int
110
     */
111
	protected $recurring_item = null;
112
113
	/**
114
     * Stores an array of item totals.
115
	 *
116
	 * e.g $totals['discount'] = array(
117
	 * 		'initial'   => 10,
118
	 * 		'recurring' => 10,
119
	 * )
120
     *
121
     * @var array
122
     */
123
	protected $totals = array();
124
125
	/**
126
	 * Stores the status transition information.
127
	 *
128
	 * @since 1.0.19
129
	 * @var bool
130
	 */
131
	protected $status_transition = false;
132
133
    /**
134
	 * Get the invoice if ID is passed, otherwise the invoice is new and empty.
135
	 *
136
	 * @param  int|string|object|WPInv_Invoice|WPInv_Legacy_Invoice|WP_Post $invoice Invoice id, key, transaction id, number or object to read.
137
	 */
138
    public function __construct( $invoice = false ) {
139
140
        parent::__construct( $invoice );
0 ignored issues
show
Bug introduced by
It seems like $invoice can also be of type false and string; however, parameter $read of GetPaid_Data::__construct() does only seem to accept array|integer|object, 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

140
        parent::__construct( /** @scrutinizer ignore-type */ $invoice );
Loading history...
141
142
		if ( ! empty( $invoice ) && is_numeric( $invoice ) && getpaid_is_invoice_post_type( get_post_type( $invoice ) ) ) {
0 ignored issues
show
Bug introduced by
It seems like $invoice can also be of type string; however, parameter $post of get_post_type() does only seem to accept WP_Post|integer|null, 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

142
		if ( ! empty( $invoice ) && is_numeric( $invoice ) && getpaid_is_invoice_post_type( get_post_type( /** @scrutinizer ignore-type */ $invoice ) ) ) {
Loading history...
143
			$this->set_id( $invoice );
0 ignored issues
show
Bug introduced by
It seems like $invoice can also be of type string; however, parameter $id of GetPaid_Data::set_id() does only seem to accept integer, 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

143
			$this->set_id( /** @scrutinizer ignore-type */ $invoice );
Loading history...
144
		} elseif ( $invoice instanceof self ) {
145
			$this->set_id( $invoice->get_id() );
146
		} elseif ( ! empty( $invoice->ID ) ) {
147
			$this->set_id( $invoice->ID );
148
		} elseif ( is_array( $invoice ) ) {
0 ignored issues
show
introduced by
The condition is_array($invoice) is always false.
Loading history...
149
			$this->set_props( $invoice );
150
151
			if ( isset( $invoice['ID'] ) ) {
152
				$this->set_id( $invoice['ID'] );
153
			}
154
155
		} elseif ( is_scalar( $invoice ) && $invoice_id = self::get_invoice_id_by_field( $invoice, 'key' ) ) {
0 ignored issues
show
Bug introduced by
It seems like $invoice can also be of type false; however, parameter $value of WPInv_Invoice::get_invoice_id_by_field() 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

155
		} elseif ( is_scalar( $invoice ) && $invoice_id = self::get_invoice_id_by_field( /** @scrutinizer ignore-type */ $invoice, 'key' ) ) {
Loading history...
156
			$this->set_id( $invoice_id );
157
		} elseif ( is_scalar( $invoice ) && $invoice_id = self::get_invoice_id_by_field( $invoice, 'number' ) ) {
158
			$this->set_id( $invoice_id );
159
		} elseif ( is_scalar( $invoice ) && $invoice_id = self::get_invoice_id_by_field( $invoice, 'transaction_id' ) ) {
160
			$this->set_id( $invoice_id );
161
		}else {
162
			$this->set_object_read( true );
163
		}
164
165
        // Load the datastore.
166
		$this->data_store = GetPaid_Data_Store::load( $this->data_store_name );
167
168
		if ( $this->get_id() > 0 ) {
169
            $this->post = get_post( $this->get_id() );
170
            $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...
171
			$this->data_store->read( $this );
172
        }
173
174
    }
175
176
    /**
177
	 * Given an invoice key/number, it returns its id.
178
	 *
179
	 *
180
	 * @static
181
	 * @param string $value The invoice key or number
182
	 * @param string $field Either key, transaction_id or number.
183
	 * @since 1.0.15
184
	 * @return int
185
	 */
186
	public static function get_invoice_id_by_field( $value, $field = 'key' ) {
187
        global $wpdb;
188
189
		// Trim the value.
190
		$value = trim( $value );
191
192
		if ( empty( $value ) ) {
193
			return 0;
194
		}
195
196
        // Valid fields.
197
        $fields = array( 'key', 'number', 'transaction_id' );
198
199
		// Ensure a field has been passed.
200
		if ( empty( $field ) || ! in_array( $field, $fields ) ) {
201
			return 0;
202
		}
203
204
		// Maybe retrieve from the cache.
205
		$invoice_id   = wp_cache_get( $value, "getpaid_invoice_{$field}s_to_invoice_ids" );
206
		if ( false !== $invoice_id ) {
207
			return $invoice_id;
208
		}
209
210
        // Fetch from the db.
211
        $table       = $wpdb->prefix . 'getpaid_invoices';
212
        $invoice_id  = (int) $wpdb->get_var(
213
            $wpdb->prepare( "SELECT `post_id` FROM $table WHERE `$field`=%s LIMIT 1", $value )
214
        );
215
216
		// Update the cache with our data
217
		wp_cache_set( $value, $invoice_id, "getpaid_invoice_{$field}s_to_invoice_ids" );
218
219
		return $invoice_id;
220
    }
221
222
    /**
223
     * Checks if an invoice key is set.
224
     */
225
    public function _isset( $key ) {
226
        return isset( $this->data[$key] ) || method_exists( $this, "get_$key" );
227
    }
228
229
    /*
230
	|--------------------------------------------------------------------------
231
	| CRUD methods
232
	|--------------------------------------------------------------------------
233
	|
234
	| Methods which create, read, update and delete items from the database.
235
	|
236
    */
237
238
    /*
239
	|--------------------------------------------------------------------------
240
	| Getters
241
	|--------------------------------------------------------------------------
242
    */
243
244
    /**
245
	 * Get parent invoice ID.
246
	 *
247
	 * @since 1.0.19
248
	 * @param  string $context View or edit context.
249
	 * @return int
250
	 */
251
	public function get_parent_id( $context = 'view' ) {
252
		return (int) $this->get_prop( 'parent_id', $context );
253
    }
254
255
    /**
256
	 * Get parent invoice.
257
	 *
258
	 * @since 1.0.19
259
	 * @return WPInv_Invoice
260
	 */
261
    public function get_parent_payment() {
262
        return new WPInv_Invoice( $this->get_parent_id() );
263
    }
264
265
    /**
266
	 * Alias for self::get_parent_payment().
267
	 *
268
	 * @since 1.0.19
269
	 * @return WPInv_Invoice
270
	 */
271
    public function get_parent() {
272
        return $this->get_parent_payment();
273
    }
274
275
    /**
276
	 * Get invoice status.
277
	 *
278
	 * @since 1.0.19
279
	 * @param  string $context View or edit context.
280
	 * @return string
281
	 */
282
	public function get_status( $context = 'view' ) {
283
		return $this->get_prop( 'status', $context );
284
	}
285
	
286
	/**
287
	 * Retrieves an array of possible invoice statuses.
288
	 *
289
	 * @since 1.0.19
290
	 * @return array
291
	 */
292
	public function get_all_statuses() {
293
294
		$statuses = wpinv_get_invoice_statuses( true, true, $this );
295
296
		// For backwards compatibility.
297
		if ( $this->is_quote() && class_exists( 'Wpinv_Quotes_Shared' ) ) {
298
            $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...
299
		}
300
301
		return $statuses;
302
    }
303
304
    /**
305
	 * Get invoice status nice name.
306
	 *
307
	 * @since 1.0.19
308
	 * @return string
309
	 */
310
    public function get_status_nicename() {
311
		$statuses = $this->get_all_statuses();
312
313
        $status = isset( $statuses[ $this->get_status() ] ) ? $statuses[ $this->get_status() ] : $this->get_status();
314
315
        return apply_filters( 'wpinv_get_invoice_status_nicename', $status, $this );
316
    }
317
318
	/**
319
     * Retrieves the invoice status label html
320
     *
321
     * @since  1.0.0
322
     * @return string
323
     */
324
    public function get_status_label_html() {
325
326
		$status_label = sanitize_text_field( $this->get_status_nicename() );
327
		$status       = sanitize_html_class( $this->get_status() );
328
329
		return "<span class='bsui'><span class='d-inline-block py-2 px-3 rounded getpaid-invoice-status-$status'>$status_label</span></span>";
330
	}
331
332
    /**
333
	 * Get plugin version when the invoice was created.
334
	 *
335
	 * @since 1.0.19
336
	 * @param  string $context View or edit context.
337
	 * @return string
338
	 */
339
	public function get_version( $context = 'view' ) {
340
		return $this->get_prop( 'version', $context );
341
	}
342
343
	/**
344
	 * @deprecated
345
	 */
346
	public function get_invoice_date( $format = true ) {
347
		$date      = getpaid_format_date( $this->get_date_completed() );
348
		$date      = empty( $date ) ? $this->get_date_created() : $this->get_date_completed();
349
		$formatted = getpaid_format_date( $date );
350
351
		if ( $format ) {
352
			return $formatted;
353
		}
354
355
		return empty( $formatted ) ? '' : $date;
356
357
    }
358
359
    /**
360
	 * Get date when the invoice was created.
361
	 *
362
	 * @since 1.0.19
363
	 * @param  string $context View or edit context.
364
	 * @return string
365
	 */
366
	public function get_date_created( $context = 'view' ) {
367
		return $this->get_prop( 'date_created', $context );
368
	}
369
	
370
	/**
371
	 * Alias for self::get_date_created().
372
	 *
373
	 * @since 1.0.19
374
	 * @param  string $context View or edit context.
375
	 * @return string
376
	 */
377
	public function get_created_date( $context = 'view' ) {
378
		return $this->get_date_created( $context );
379
    }
380
381
    /**
382
	 * Get GMT date when the invoice was created.
383
	 *
384
	 * @since 1.0.19
385
	 * @param  string $context View or edit context.
386
	 * @return string
387
	 */
388
	public function get_date_created_gmt( $context = 'view' ) {
389
        $date = $this->get_date_created( $context );
390
391
        if ( $date ) {
392
            $date = get_gmt_from_date( $date );
393
        }
394
		return $date;
395
    }
396
397
    /**
398
	 * Get date when the invoice was last modified.
399
	 *
400
	 * @since 1.0.19
401
	 * @param  string $context View or edit context.
402
	 * @return string
403
	 */
404
	public function get_date_modified( $context = 'view' ) {
405
		return $this->get_prop( 'date_modified', $context );
406
	}
407
408
	/**
409
	 * Alias for self::get_date_modified().
410
	 *
411
	 * @since 1.0.19
412
	 * @param  string $context View or edit context.
413
	 * @return string
414
	 */
415
	public function get_modified_date( $context = 'view' ) {
416
		return $this->get_date_modified( $context );
417
    }
418
419
    /**
420
	 * Get GMT date when the invoice was last modified.
421
	 *
422
	 * @since 1.0.19
423
	 * @param  string $context View or edit context.
424
	 * @return string
425
	 */
426
	public function get_date_modified_gmt( $context = 'view' ) {
427
        $date = $this->get_date_modified( $context );
428
429
        if ( $date ) {
430
            $date = get_gmt_from_date( $date );
431
        }
432
		return $date;
433
    }
434
435
    /**
436
	 * Get the invoice due date.
437
	 *
438
	 * @since 1.0.19
439
	 * @param  string $context View or edit context.
440
	 * @return string
441
	 */
442
	public function get_due_date( $context = 'view' ) {
443
		return $this->get_prop( 'due_date', $context );
444
    }
445
446
    /**
447
	 * Alias for self::get_due_date().
448
	 *
449
	 * @since 1.0.19
450
	 * @param  string $context View or edit context.
451
	 * @return string
452
	 */
453
	public function get_date_due( $context = 'view' ) {
454
		return $this->get_due_date( $context );
455
    }
456
457
    /**
458
	 * Get the invoice GMT due date.
459
	 *
460
	 * @since 1.0.19
461
	 * @param  string $context View or edit context.
462
	 * @return string
463
	 */
464
	public function get_due_date_gmt( $context = 'view' ) {
465
        $date = $this->get_due_date( $context );
466
467
        if ( $date ) {
468
            $date = get_gmt_from_date( $date );
469
        }
470
		return $date;
471
    }
472
473
    /**
474
	 * Alias for self::get_due_date_gmt().
475
	 *
476
	 * @since 1.0.19
477
	 * @param  string $context View or edit context.
478
	 * @return string
479
	 */
480
	public function get_gmt_date_due( $context = 'view' ) {
481
		return $this->get_due_date_gmt( $context );
482
    }
483
484
    /**
485
	 * Get date when the invoice was completed.
486
	 *
487
	 * @since 1.0.19
488
	 * @param  string $context View or edit context.
489
	 * @return string
490
	 */
491
	public function get_completed_date( $context = 'view' ) {
492
		return $this->get_prop( 'completed_date', $context );
493
    }
494
495
    /**
496
	 * Alias for self::get_completed_date().
497
	 *
498
	 * @since 1.0.19
499
	 * @param  string $context View or edit context.
500
	 * @return string
501
	 */
502
	public function get_date_completed( $context = 'view' ) {
503
		return $this->get_completed_date( $context );
504
    }
505
506
    /**
507
	 * Get GMT date when the invoice was was completed.
508
	 *
509
	 * @since 1.0.19
510
	 * @param  string $context View or edit context.
511
	 * @return string
512
	 */
513
	public function get_completed_date_gmt( $context = 'view' ) {
514
        $date = $this->get_completed_date( $context );
515
516
        if ( $date ) {
517
            $date = get_gmt_from_date( $date );
518
        }
519
		return $date;
520
    }
521
522
    /**
523
	 * Alias for self::get_completed_date_gmt().
524
	 *
525
	 * @since 1.0.19
526
	 * @param  string $context View or edit context.
527
	 * @return string
528
	 */
529
	public function get_gmt_completed_date( $context = 'view' ) {
530
		return $this->get_completed_date_gmt( $context );
531
    }
532
533
    /**
534
	 * Get the invoice number.
535
	 *
536
	 * @since 1.0.19
537
	 * @param  string $context View or edit context.
538
	 * @return string
539
	 */
540
	public function get_number( $context = 'view' ) {
541
		$number = $this->get_prop( 'number', $context );
542
543
		if ( empty( $number ) ) {
544
			$number = $this->generate_number();
545
			$this->set_number( $this->generate_number() );
546
		}
547
548
		return $number;
549
    }
550
551
	/**
552
	 * Set the invoice number.
553
	 *
554
	 * @since 1.0.19
555
	 */
556
	public function maybe_set_number() {
557
        $number = $this->get_number();
558
559
        if ( empty( $number ) || $this->get_id() == $number ) {
560
			$this->set_number( $this->generate_number() );
561
        }
562
563
	}
564
565
    /**
566
	 * Get the invoice key.
567
	 *
568
	 * @since 1.0.19
569
	 * @param  string $context View or edit context.
570
	 * @return string
571
	 */
572
	public function get_key( $context = 'view' ) {
573
        return $this->get_prop( 'key', $context );
574
	}
575
576
	/**
577
	 * Set the invoice key.
578
	 *
579
	 * @since 1.0.19
580
	 */
581
	public function maybe_set_key() {
582
        $key = $this->get_key();
583
584
        if ( empty( $key ) ) {
585
            $key = $this->generate_key( $this->get_type() . '_' );
586
            $this->set_key( $key );
587
        }
588
589
    }
590
591
    /**
592
	 * Get the invoice type.
593
	 *
594
	 * @since 1.0.19
595
	 * @param  string $context View or edit context.
596
	 * @return string
597
	 */
598
	public function get_type( $context = 'view' ) {
599
        return $this->get_prop( 'type', $context );
600
	}
601
602
	/**
603
	 * @deprecated
604
	 */
605
	public function get_invoice_quote_type() {
606
        ucfirst( $this->get_type() );
607
    }
608
609
    /**
610
	 * Get the invoice post type.
611
	 *
612
	 * @since 1.0.19
613
	 * @param  string $context View or edit context.
614
	 * @return string
615
	 */
616
	public function get_post_type( $context = 'view' ) {
617
        return $this->get_prop( 'post_type', $context );
618
    }
619
620
    /**
621
	 * Get the invoice mode.
622
	 *
623
	 * @since 1.0.19
624
	 * @param  string $context View or edit context.
625
	 * @return string
626
	 */
627
	public function get_mode( $context = 'view' ) {
628
        return $this->get_prop( 'mode', $context );
629
    }
630
631
    /**
632
	 * Get the invoice path.
633
	 *
634
	 * @since 1.0.19
635
	 * @param  string $context View or edit context.
636
	 * @return string
637
	 */
638
	public function get_path( $context = 'view' ) {
639
        $path   = $this->get_prop( 'path', $context );
640
		$prefix = wpinv_post_name_prefix( $this->get_post_type() );
641
642
		if ( 0 !== strpos( $path, $prefix ) ) {
643
			$path = sanitize_title(  $prefix . $this->get_id()  );
644
			$this->set_path( $path );
645
		}
646
647
		return $path;
648
    }
649
650
    /**
651
	 * Get the invoice name/title.
652
	 *
653
	 * @since 1.0.19
654
	 * @param  string $context View or edit context.
655
	 * @return string
656
	 */
657
	public function get_name( $context = 'view' ) {
658
        return $this->get_prop( 'title', $context );
659
    }
660
661
    /**
662
	 * Alias of self::get_name().
663
	 *
664
	 * @since 1.0.19
665
	 * @param  string $context View or edit context.
666
	 * @return string
667
	 */
668
	public function get_title( $context = 'view' ) {
669
		return $this->get_name( $context );
670
    }
671
672
    /**
673
	 * Get the invoice description.
674
	 *
675
	 * @since 1.0.19
676
	 * @param  string $context View or edit context.
677
	 * @return string
678
	 */
679
	public function get_description( $context = 'view' ) {
680
		return $this->get_prop( 'description', $context );
681
    }
682
683
    /**
684
	 * Alias of self::get_description().
685
	 *
686
	 * @since 1.0.19
687
	 * @param  string $context View or edit context.
688
	 * @return string
689
	 */
690
	public function get_excerpt( $context = 'view' ) {
691
		return $this->get_description( $context );
692
    }
693
694
    /**
695
	 * Alias of self::get_description().
696
	 *
697
	 * @since 1.0.19
698
	 * @param  string $context View or edit context.
699
	 * @return string
700
	 */
701
	public function get_summary( $context = 'view' ) {
702
		return $this->get_description( $context );
703
    }
704
705
    /**
706
	 * Returns the user info.
707
	 *
708
	 * @since 1.0.19
709
     * @param  string $context View or edit context.
710
	 * @return array
711
	 */
712
    public function get_user_info( $context = 'view' ) {
713
714
        $user_info = array(
715
            'user_id'    => $this->get_user_id( $context ),
716
            'email'      => $this->get_email( $context ),
717
            'first_name' => $this->get_first_name( $context ),
718
            'last_name'  => $this->get_last_name( $context ),
719
            'address'    => $this->get_address( $context ),
720
            'phone'      => $this->get_phone( $context ),
721
            'city'       => $this->get_city( $context ),
722
            'country'    => $this->get_country( $context ),
723
            'state'      => $this->get_state( $context ),
724
            'zip'        => $this->get_zip( $context ),
725
            'company'    => $this->get_company( $context ),
726
            'vat_number' => $this->get_vat_number( $context ),
727
            'discount'   => $this->get_discount_code( $context ),
728
		);
729
730
		return apply_filters( 'wpinv_user_info', $user_info, $this->get_id(), $this );
731
732
    }
733
734
    /**
735
	 * Get the customer id.
736
	 *
737
	 * @since 1.0.19
738
	 * @param  string $context View or edit context.
739
	 * @return int
740
	 */
741
	public function get_author( $context = 'view' ) {
742
		return (int) $this->get_prop( 'author', $context );
743
    }
744
745
    /**
746
	 * Alias of self::get_author().
747
	 *
748
	 * @since 1.0.19
749
	 * @param  string $context View or edit context.
750
	 * @return int
751
	 */
752
	public function get_user_id( $context = 'view' ) {
753
		return $this->get_author( $context );
754
    }
755
756
     /**
757
	 * Alias of self::get_author().
758
	 *
759
	 * @since 1.0.19
760
	 * @param  string $context View or edit context.
761
	 * @return int
762
	 */
763
	public function get_customer_id( $context = 'view' ) {
764
		return $this->get_author( $context );
765
    }
766
767
    /**
768
	 * Get the customer's ip.
769
	 *
770
	 * @since 1.0.19
771
	 * @param  string $context View or edit context.
772
	 * @return string
773
	 */
774
	public function get_ip( $context = 'view' ) {
775
		return $this->get_prop( 'user_ip', $context );
776
    }
777
778
    /**
779
	 * Alias of self::get_ip().
780
	 *
781
	 * @since 1.0.19
782
	 * @param  string $context View or edit context.
783
	 * @return string
784
	 */
785
	public function get_user_ip( $context = 'view' ) {
786
		return $this->get_ip( $context );
787
    }
788
789
     /**
790
	 * Alias of self::get_ip().
791
	 *
792
	 * @since 1.0.19
793
	 * @param  string $context View or edit context.
794
	 * @return string
795
	 */
796
	public function get_customer_ip( $context = 'view' ) {
797
		return $this->get_ip( $context );
798
    }
799
800
    /**
801
	 * Get the customer's first name.
802
	 *
803
	 * @since 1.0.19
804
	 * @param  string $context View or edit context.
805
	 * @return string
806
	 */
807
	public function get_first_name( $context = 'view' ) {
808
		return $this->get_prop( 'first_name', $context );
809
    }
810
811
    /**
812
	 * Alias of self::get_first_name().
813
	 *
814
	 * @since 1.0.19
815
	 * @param  string $context View or edit context.
816
	 * @return int
817
	 */
818
	public function get_user_first_name( $context = 'view' ) {
819
		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...
820
    }
821
822
     /**
823
	 * Alias of self::get_first_name().
824
	 *
825
	 * @since 1.0.19
826
	 * @param  string $context View or edit context.
827
	 * @return int
828
	 */
829
	public function get_customer_first_name( $context = 'view' ) {
830
		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...
831
    }
832
833
    /**
834
	 * Get the customer's last name.
835
	 *
836
	 * @since 1.0.19
837
	 * @param  string $context View or edit context.
838
	 * @return string
839
	 */
840
	public function get_last_name( $context = 'view' ) {
841
		return $this->get_prop( 'last_name', $context );
842
    }
843
844
    /**
845
	 * Alias of self::get_last_name().
846
	 *
847
	 * @since 1.0.19
848
	 * @param  string $context View or edit context.
849
	 * @return int
850
	 */
851
	public function get_user_last_name( $context = 'view' ) {
852
		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...
853
    }
854
855
    /**
856
	 * Alias of self::get_last_name().
857
	 *
858
	 * @since 1.0.19
859
	 * @param  string $context View or edit context.
860
	 * @return int
861
	 */
862
	public function get_customer_last_name( $context = 'view' ) {
863
		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...
864
    }
865
866
    /**
867
	 * Get the customer's full name.
868
	 *
869
	 * @since 1.0.19
870
	 * @param  string $context View or edit context.
871
	 * @return string
872
	 */
873
	public function get_full_name( $context = 'view' ) {
874
		return trim( $this->get_first_name( $context ) . ' ' . $this->get_last_name( $context ) );
875
    }
876
877
    /**
878
	 * Alias of self::get_full_name().
879
	 *
880
	 * @since 1.0.19
881
	 * @param  string $context View or edit context.
882
	 * @return int
883
	 */
884
	public function get_user_full_name( $context = 'view' ) {
885
		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...
886
    }
887
888
    /**
889
	 * Alias of self::get_full_name().
890
	 *
891
	 * @since 1.0.19
892
	 * @param  string $context View or edit context.
893
	 * @return int
894
	 */
895
	public function get_customer_full_name( $context = 'view' ) {
896
		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...
897
    }
898
899
    /**
900
	 * Get the customer's phone number.
901
	 *
902
	 * @since 1.0.19
903
	 * @param  string $context View or edit context.
904
	 * @return string
905
	 */
906
	public function get_phone( $context = 'view' ) {
907
		return $this->get_prop( 'phone', $context );
908
    }
909
910
    /**
911
	 * Alias of self::get_phone().
912
	 *
913
	 * @since 1.0.19
914
	 * @param  string $context View or edit context.
915
	 * @return int
916
	 */
917
	public function get_phone_number( $context = 'view' ) {
918
		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...
919
    }
920
921
    /**
922
	 * Alias of self::get_phone().
923
	 *
924
	 * @since 1.0.19
925
	 * @param  string $context View or edit context.
926
	 * @return int
927
	 */
928
	public function get_user_phone( $context = 'view' ) {
929
		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...
930
    }
931
932
    /**
933
	 * Alias of self::get_phone().
934
	 *
935
	 * @since 1.0.19
936
	 * @param  string $context View or edit context.
937
	 * @return int
938
	 */
939
	public function get_customer_phone( $context = 'view' ) {
940
		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...
941
    }
942
943
    /**
944
	 * Get the customer's email address.
945
	 *
946
	 * @since 1.0.19
947
	 * @param  string $context View or edit context.
948
	 * @return string
949
	 */
950
	public function get_email( $context = 'view' ) {
951
		return $this->get_prop( 'email', $context );
952
    }
953
954
    /**
955
	 * Alias of self::get_email().
956
	 *
957
	 * @since 1.0.19
958
	 * @param  string $context View or edit context.
959
	 * @return string
960
	 */
961
	public function get_email_address( $context = 'view' ) {
962
		return $this->get_email( $context );
963
    }
964
965
    /**
966
	 * Alias of self::get_email().
967
	 *
968
	 * @since 1.0.19
969
	 * @param  string $context View or edit context.
970
	 * @return int
971
	 */
972
	public function get_user_email( $context = 'view' ) {
973
		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...
974
    }
975
976
    /**
977
	 * Alias of self::get_email().
978
	 *
979
	 * @since 1.0.19
980
	 * @param  string $context View or edit context.
981
	 * @return int
982
	 */
983
	public function get_customer_email( $context = 'view' ) {
984
		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...
985
    }
986
987
    /**
988
	 * Get the customer's country.
989
	 *
990
	 * @since 1.0.19
991
	 * @param  string $context View or edit context.
992
	 * @return string
993
	 */
994
	public function get_country( $context = 'view' ) {
995
		$country = $this->get_prop( 'country', $context );
996
		return empty( $country ) ? wpinv_get_default_country() : $country;
997
    }
998
999
    /**
1000
	 * Alias of self::get_country().
1001
	 *
1002
	 * @since 1.0.19
1003
	 * @param  string $context View or edit context.
1004
	 * @return int
1005
	 */
1006
	public function get_user_country( $context = 'view' ) {
1007
		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...
1008
    }
1009
1010
    /**
1011
	 * Alias of self::get_country().
1012
	 *
1013
	 * @since 1.0.19
1014
	 * @param  string $context View or edit context.
1015
	 * @return int
1016
	 */
1017
	public function get_customer_country( $context = 'view' ) {
1018
		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...
1019
    }
1020
1021
    /**
1022
	 * Get the customer's state.
1023
	 *
1024
	 * @since 1.0.19
1025
	 * @param  string $context View or edit context.
1026
	 * @return string
1027
	 */
1028
	public function get_state( $context = 'view' ) {
1029
		$state = $this->get_prop( 'state', $context );
1030
		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...
1031
    }
1032
1033
    /**
1034
	 * Alias of self::get_state().
1035
	 *
1036
	 * @since 1.0.19
1037
	 * @param  string $context View or edit context.
1038
	 * @return int
1039
	 */
1040
	public function get_user_state( $context = 'view' ) {
1041
		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...
1042
    }
1043
1044
    /**
1045
	 * Alias of self::get_state().
1046
	 *
1047
	 * @since 1.0.19
1048
	 * @param  string $context View or edit context.
1049
	 * @return int
1050
	 */
1051
	public function get_customer_state( $context = 'view' ) {
1052
		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...
1053
    }
1054
1055
    /**
1056
	 * Get the customer's city.
1057
	 *
1058
	 * @since 1.0.19
1059
	 * @param  string $context View or edit context.
1060
	 * @return string
1061
	 */
1062
	public function get_city( $context = 'view' ) {
1063
		return $this->get_prop( 'city', $context );
1064
    }
1065
1066
    /**
1067
	 * Alias of self::get_city().
1068
	 *
1069
	 * @since 1.0.19
1070
	 * @param  string $context View or edit context.
1071
	 * @return string
1072
	 */
1073
	public function get_user_city( $context = 'view' ) {
1074
		return $this->get_city( $context );
1075
    }
1076
1077
    /**
1078
	 * Alias of self::get_city().
1079
	 *
1080
	 * @since 1.0.19
1081
	 * @param  string $context View or edit context.
1082
	 * @return string
1083
	 */
1084
	public function get_customer_city( $context = 'view' ) {
1085
		return $this->get_city( $context );
1086
    }
1087
1088
    /**
1089
	 * Get the customer's zip.
1090
	 *
1091
	 * @since 1.0.19
1092
	 * @param  string $context View or edit context.
1093
	 * @return string
1094
	 */
1095
	public function get_zip( $context = 'view' ) {
1096
		return $this->get_prop( 'zip', $context );
1097
    }
1098
1099
    /**
1100
	 * Alias of self::get_zip().
1101
	 *
1102
	 * @since 1.0.19
1103
	 * @param  string $context View or edit context.
1104
	 * @return string
1105
	 */
1106
	public function get_user_zip( $context = 'view' ) {
1107
		return $this->get_zip( $context );
1108
    }
1109
1110
    /**
1111
	 * Alias of self::get_zip().
1112
	 *
1113
	 * @since 1.0.19
1114
	 * @param  string $context View or edit context.
1115
	 * @return string
1116
	 */
1117
	public function get_customer_zip( $context = 'view' ) {
1118
		return $this->get_zip( $context );
1119
    }
1120
1121
    /**
1122
	 * Get the customer's company.
1123
	 *
1124
	 * @since 1.0.19
1125
	 * @param  string $context View or edit context.
1126
	 * @return string
1127
	 */
1128
	public function get_company( $context = 'view' ) {
1129
		return $this->get_prop( 'company', $context );
1130
    }
1131
1132
    /**
1133
	 * Alias of self::get_company().
1134
	 *
1135
	 * @since 1.0.19
1136
	 * @param  string $context View or edit context.
1137
	 * @return string
1138
	 */
1139
	public function get_user_company( $context = 'view' ) {
1140
		return $this->get_company( $context );
1141
    }
1142
1143
    /**
1144
	 * Alias of self::get_company().
1145
	 *
1146
	 * @since 1.0.19
1147
	 * @param  string $context View or edit context.
1148
	 * @return string
1149
	 */
1150
	public function get_customer_company( $context = 'view' ) {
1151
		return $this->get_company( $context );
1152
    }
1153
1154
    /**
1155
	 * Get the customer's vat number.
1156
	 *
1157
	 * @since 1.0.19
1158
	 * @param  string $context View or edit context.
1159
	 * @return string
1160
	 */
1161
	public function get_vat_number( $context = 'view' ) {
1162
		return $this->get_prop( 'vat_number', $context );
1163
    }
1164
1165
    /**
1166
	 * Alias of self::get_vat_number().
1167
	 *
1168
	 * @since 1.0.19
1169
	 * @param  string $context View or edit context.
1170
	 * @return string
1171
	 */
1172
	public function get_user_vat_number( $context = 'view' ) {
1173
		return $this->get_vat_number( $context );
1174
    }
1175
1176
    /**
1177
	 * Alias of self::get_vat_number().
1178
	 *
1179
	 * @since 1.0.19
1180
	 * @param  string $context View or edit context.
1181
	 * @return string
1182
	 */
1183
	public function get_customer_vat_number( $context = 'view' ) {
1184
		return $this->get_vat_number( $context );
1185
    }
1186
1187
    /**
1188
	 * Get the customer's vat rate.
1189
	 *
1190
	 * @since 1.0.19
1191
	 * @param  string $context View or edit context.
1192
	 * @return string
1193
	 */
1194
	public function get_vat_rate( $context = 'view' ) {
1195
		return $this->get_prop( 'vat_rate', $context );
1196
    }
1197
1198
    /**
1199
	 * Alias of self::get_vat_rate().
1200
	 *
1201
	 * @since 1.0.19
1202
	 * @param  string $context View or edit context.
1203
	 * @return string
1204
	 */
1205
	public function get_user_vat_rate( $context = 'view' ) {
1206
		return $this->get_vat_rate( $context );
1207
    }
1208
1209
    /**
1210
	 * Alias of self::get_vat_rate().
1211
	 *
1212
	 * @since 1.0.19
1213
	 * @param  string $context View or edit context.
1214
	 * @return string
1215
	 */
1216
	public function get_customer_vat_rate( $context = 'view' ) {
1217
		return $this->get_vat_rate( $context );
1218
    }
1219
1220
    /**
1221
	 * Get the customer's address.
1222
	 *
1223
	 * @since 1.0.19
1224
	 * @param  string $context View or edit context.
1225
	 * @return string
1226
	 */
1227
	public function get_address( $context = 'view' ) {
1228
		return $this->get_prop( 'address', $context );
1229
    }
1230
1231
    /**
1232
	 * Alias of self::get_address().
1233
	 *
1234
	 * @since 1.0.19
1235
	 * @param  string $context View or edit context.
1236
	 * @return string
1237
	 */
1238
	public function get_user_address( $context = 'view' ) {
1239
		return $this->get_address( $context );
1240
    }
1241
1242
    /**
1243
	 * Alias of self::get_address().
1244
	 *
1245
	 * @since 1.0.19
1246
	 * @param  string $context View or edit context.
1247
	 * @return string
1248
	 */
1249
	public function get_customer_address( $context = 'view' ) {
1250
		return $this->get_address( $context );
1251
    }
1252
1253
    /**
1254
	 * Get whether the customer has viewed the invoice or not.
1255
	 *
1256
	 * @since 1.0.19
1257
	 * @param  string $context View or edit context.
1258
	 * @return bool
1259
	 */
1260
	public function get_is_viewed( $context = 'view' ) {
1261
		return (bool) $this->get_prop( 'is_viewed', $context );
1262
	}
1263
1264
	/**
1265
	 * Get other recipients for invoice communications.
1266
	 *
1267
	 * @since 1.0.19
1268
	 * @param  string $context View or edit context.
1269
	 * @return bool
1270
	 */
1271
	public function get_email_cc( $context = 'view' ) {
1272
		return $this->get_prop( 'email_cc', $context );
1273
	}
1274
1275
	/**
1276
	 * Get invoice template.
1277
	 *
1278
	 * @since 1.0.19
1279
	 * @param  string $context View or edit context.
1280
	 * @return bool
1281
	 */
1282
	public function get_template( $context = 'view' ) {
1283
		return $this->get_prop( 'template', $context );
1284
	}
1285
1286
	/**
1287
	 * Get invoice source.
1288
	 *
1289
	 * @since 1.0.19
1290
	 * @param  string $context View or edit context.
1291
	 * @return bool
1292
	 */
1293
	public function get_created_via( $context = 'view' ) {
1294
		return $this->get_prop( 'created_via', $context );
1295
	}
1296
1297
	/**
1298
	 * Get whether the customer has confirmed their address.
1299
	 *
1300
	 * @since 1.0.19
1301
	 * @param  string $context View or edit context.
1302
	 * @return bool
1303
	 */
1304
	public function get_address_confirmed( $context = 'view' ) {
1305
		return (bool) $this->get_prop( 'address_confirmed', $context );
1306
    }
1307
1308
    /**
1309
	 * Alias of self::get_address_confirmed().
1310
	 *
1311
	 * @since 1.0.19
1312
	 * @param  string $context View or edit context.
1313
	 * @return bool
1314
	 */
1315
	public function get_user_address_confirmed( $context = 'view' ) {
1316
		return $this->get_address_confirmed( $context );
1317
    }
1318
1319
    /**
1320
	 * Alias of self::get_address().
1321
	 *
1322
	 * @since 1.0.19
1323
	 * @param  string $context View or edit context.
1324
	 * @return bool
1325
	 */
1326
	public function get_customer_address_confirmed( $context = 'view' ) {
1327
		return $this->get_address_confirmed( $context );
1328
    }
1329
1330
    /**
1331
	 * Get the invoice subtotal.
1332
	 *
1333
	 * @since 1.0.19
1334
	 * @param  string $context View or edit context.
1335
	 * @return float
1336
	 */
1337
	public function get_subtotal( $context = 'view' ) {
1338
        $subtotal = (float) $this->get_prop( 'subtotal', $context );
1339
1340
        // Backwards compatibility.
1341
        if ( is_bool( $context ) && $context ) {
0 ignored issues
show
introduced by
The condition is_bool($context) is always false.
Loading history...
1342
            return wpinv_price( wpinv_format_amount( $subtotal ), $this->get_currency() );
1343
        }
1344
1345
        return $subtotal;
1346
    }
1347
1348
    /**
1349
	 * Get the invoice discount total.
1350
	 *
1351
	 * @since 1.0.19
1352
	 * @param  string $context View or edit context.
1353
	 * @return float
1354
	 */
1355
	public function get_total_discount( $context = 'view' ) {
1356
		return (float) $this->get_prop( 'total_discount', $context );
1357
    }
1358
1359
    /**
1360
	 * Get the invoice tax total.
1361
	 *
1362
	 * @since 1.0.19
1363
	 * @param  string $context View or edit context.
1364
	 * @return float
1365
	 */
1366
	public function get_total_tax( $context = 'view' ) {
1367
		return (float) $this->get_prop( 'total_tax', $context );
1368
	}
1369
1370
	/**
1371
	 * @deprecated
1372
	 */
1373
	public function get_final_tax( $currency = false ) {
1374
		$tax = $this->get_total_tax();
1375
1376
        if ( $currency ) {
1377
			return wpinv_price( wpinv_format_amount( $tax, NULL, false ), $this->get_currency() );
0 ignored issues
show
Bug introduced by
wpinv_format_amount($tax, NULL, false) of type string is incompatible with the type double expected by parameter $amount of wpinv_price(). ( Ignorable by Annotation )

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

1377
			return wpinv_price( /** @scrutinizer ignore-type */ wpinv_format_amount( $tax, NULL, false ), $this->get_currency() );
Loading history...
1378
        }
1379
1380
        return $tax;
1381
    }
1382
1383
    /**
1384
	 * Get the invoice fees total.
1385
	 *
1386
	 * @since 1.0.19
1387
	 * @param  string $context View or edit context.
1388
	 * @return float
1389
	 */
1390
	public function get_total_fees( $context = 'view' ) {
1391
		return (float) $this->get_prop( 'total_fees', $context );
1392
    }
1393
1394
    /**
1395
	 * Alias for self::get_total_fees().
1396
	 *
1397
	 * @since 1.0.19
1398
	 * @param  string $context View or edit context.
1399
	 * @return float
1400
	 */
1401
	public function get_fees_total( $context = 'view' ) {
1402
		return $this->get_total_fees( $context );
1403
    }
1404
1405
    /**
1406
	 * Get the invoice total.
1407
	 *
1408
	 * @since 1.0.19
1409
     * @return float
1410
	 */
1411
	public function get_total() {
1412
		$total = $this->is_renewal() ? $this->get_recurring_total() : $this->get_initial_total();
1413
		return apply_filters( 'getpaid_get_invoice_total_amount', $total, $this  );
1414
	}
1415
	
1416
	/**
1417
	 * Get the invoice totals.
1418
	 *
1419
	 * @since 1.0.19
1420
     * @return float
1421
	 */
1422
	public function get_totals() {
1423
		return $this->totals;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->totals returns the type array which is incompatible with the documented return type double.
Loading history...
1424
    }
1425
1426
    /**
1427
	 * Get the initial invoice total.
1428
	 *
1429
	 * @since 1.0.19
1430
     * @param  string $context View or edit context.
1431
     * @return float
1432
	 */
1433
    public function get_initial_total() {
1434
1435
		if ( empty( $this->totals ) ) {
1436
			$this->recalculate_total();
1437
		}
1438
1439
		$tax      = $this->totals['tax']['initial'];
1440
		$fee      = $this->totals['fee']['initial'];
1441
		$discount = $this->totals['discount']['initial'];
1442
		$subtotal = $this->totals['subtotal']['initial'];
1443
		$total    = $tax + $fee - $discount + $subtotal;
1444
1445
		if ( 0 > $total ) {
1446
			$total = 0;
1447
		}
1448
1449
        return apply_filters( 'wpinv_get_initial_invoice_total', $total, $this );
1450
	}
1451
1452
	/**
1453
	 * Get the recurring invoice total.
1454
	 *
1455
	 * @since 1.0.19
1456
     * @param  string $context View or edit context.
1457
     * @return float
1458
	 */
1459
    public function get_recurring_total() {
1460
1461
		if ( empty( $this->totals ) ) {
1462
			$this->recalculate_total();
1463
		}
1464
1465
		$tax      = $this->totals['tax']['recurring'];
1466
		$fee      = $this->totals['fee']['recurring'];
1467
		$discount = $this->totals['discount']['recurring'];
1468
		$subtotal = $this->totals['subtotal']['recurring'];
1469
		$total    = $tax + $fee - $discount + $subtotal;
1470
1471
		if ( 0 > $total ) {
1472
			$total = 0;
1473
		}
1474
1475
        return apply_filters( 'wpinv_get_recurring_invoice_total', $total, $this );
1476
	}
1477
1478
	/**
1479
	 * Returns recurring payment details.
1480
	 *
1481
	 * @since 1.0.19
1482
     * @param  string $field Optionally provide a field to return.
1483
	 * @param string $currency Whether to include the currency.
1484
     * @return float
1485
	 */
1486
    public function get_recurring_details( $field = '', $currency = false ) {
1487
1488
		// Maybe recalculate totals.
1489
		if ( empty( $this->totals ) ) {
1490
			$this->recalculate_total();
1491
		}
1492
1493
		// Prepare recurring totals.
1494
        $data = apply_filters(
1495
			'wpinv_get_invoice_recurring_details',
1496
			array(
1497
				'cart_details' => $this->get_cart_details(),
1498
				'subtotal'     => $this->totals['subtotal']['recurring'],
1499
				'discount'     => $this->totals['discount']['recurring'],
1500
				'tax'          => $this->totals['tax']['recurring'],
1501
				'fee'          => $this->totals['fee']['recurring'],
1502
				'total'        => $this->get_recurring_total(),
1503
			),
1504
			$this,
1505
			$field,
1506
			$currency
1507
		);
1508
1509
        if ( isset( $data[$field] ) ) {
1510
            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...
1511
        }
1512
1513
        return $data;
1514
    }
1515
1516
    /**
1517
	 * Get the invoice fees.
1518
	 *
1519
	 * @since 1.0.19
1520
	 * @param  string $context View or edit context.
1521
	 * @return array
1522
	 */
1523
	public function get_fees( $context = 'view' ) {
1524
		return wpinv_parse_list( $this->get_prop( 'fees', $context ) );
1525
    }
1526
1527
    /**
1528
	 * Get the invoice discounts.
1529
	 *
1530
	 * @since 1.0.19
1531
	 * @param  string $context View or edit context.
1532
	 * @return array
1533
	 */
1534
	public function get_discounts( $context = 'view' ) {
1535
		return wpinv_parse_list( $this->get_prop( 'discounts', $context ) );
1536
    }
1537
1538
    /**
1539
	 * Get the invoice taxes.
1540
	 *
1541
	 * @since 1.0.19
1542
	 * @param  string $context View or edit context.
1543
	 * @return array
1544
	 */
1545
	public function get_taxes( $context = 'view' ) {
1546
		return wpinv_parse_list( $this->get_prop( 'taxes', $context ) );
1547
    }
1548
1549
    /**
1550
	 * Get the invoice items.
1551
	 *
1552
	 * @since 1.0.19
1553
	 * @param  string $context View or edit context.
1554
	 * @return GetPaid_Form_Item[]
1555
	 */
1556
	public function get_items( $context = 'view' ) {
1557
        return $this->get_prop( 'items', $context );
1558
    }
1559
1560
    /**
1561
	 * Get the invoice's payment form.
1562
	 *
1563
	 * @since 1.0.19
1564
	 * @param  string $context View or edit context.
1565
	 * @return int
1566
	 */
1567
	public function get_payment_form( $context = 'view' ) {
1568
		return intval( $this->get_prop( 'payment_form', $context ) );
1569
    }
1570
1571
    /**
1572
	 * Get the invoice's submission id.
1573
	 *
1574
	 * @since 1.0.19
1575
	 * @param  string $context View or edit context.
1576
	 * @return string
1577
	 */
1578
	public function get_submission_id( $context = 'view' ) {
1579
		return $this->get_prop( 'submission_id', $context );
1580
    }
1581
1582
    /**
1583
	 * Get the invoice's discount code.
1584
	 *
1585
	 * @since 1.0.19
1586
	 * @param  string $context View or edit context.
1587
	 * @return string
1588
	 */
1589
	public function get_discount_code( $context = 'view' ) {
1590
		return $this->get_prop( 'discount_code', $context );
1591
    }
1592
1593
    /**
1594
	 * Get the invoice's gateway.
1595
	 *
1596
	 * @since 1.0.19
1597
	 * @param  string $context View or edit context.
1598
	 * @return string
1599
	 */
1600
	public function get_gateway( $context = 'view' ) {
1601
		return $this->get_prop( 'gateway', $context );
1602
    }
1603
1604
    /**
1605
	 * Get the invoice's gateway display title.
1606
	 *
1607
	 * @since 1.0.19
1608
	 * @return string
1609
	 */
1610
    public function get_gateway_title() {
1611
        $title =  wpinv_get_gateway_checkout_label( $this->get_gateway() );
1612
        return apply_filters( 'wpinv_gateway_title', $title, $this->get_id(), $this );
1613
    }
1614
1615
    /**
1616
	 * Get the invoice's transaction id.
1617
	 *
1618
	 * @since 1.0.19
1619
	 * @param  string $context View or edit context.
1620
	 * @return string
1621
	 */
1622
	public function get_transaction_id( $context = 'view' ) {
1623
		return $this->get_prop( 'transaction_id', $context );
1624
    }
1625
1626
    /**
1627
	 * Get the invoice's currency.
1628
	 *
1629
	 * @since 1.0.19
1630
	 * @param  string $context View or edit context.
1631
	 * @return string
1632
	 */
1633
	public function get_currency( $context = 'view' ) {
1634
        $currency = $this->get_prop( 'currency', $context );
1635
        return empty( $currency ) ? wpinv_get_currency() : $currency;
1636
    }
1637
1638
    /**
1639
	 * Checks if we are charging taxes for this invoice.
1640
	 *
1641
	 * @since 1.0.19
1642
	 * @param  string $context View or edit context.
1643
	 * @return bool
1644
	 */
1645
	public function get_disable_taxes( $context = 'view' ) {
1646
        return (bool) $this->get_prop( 'disable_taxes', $context );
1647
    }
1648
1649
    /**
1650
	 * Retrieves the subscription id for an invoice.
1651
	 *
1652
	 * @since 1.0.19
1653
	 * @param  string $context View or edit context.
1654
	 * @return int
1655
	 */
1656
    public function get_subscription_id( $context = 'view' ) {
1657
		return $this->is_renewal() ? $this->get_parent()->get_subscription_id( $context ) : $this->get_prop( 'subscription_id', $context );
1658
	}
1659
1660
	/**
1661
	 * Retrieves the remote subscription id for an invoice.
1662
	 *
1663
	 * @since 1.0.19
1664
	 * @param  string $context View or edit context.
1665
	 * @return int
1666
	 */
1667
    public function get_remote_subscription_id( $context = 'view' ) {
1668
        $subscription_id = $this->get_prop( 'remote_subscription_id', $context );
1669
1670
        if ( empty( $subscription_id ) && $this->is_renewal() ) {
1671
            $parent = $this->get_parent();
1672
            return $parent->get_subscription_id( $context );
1673
        }
1674
1675
        return $subscription_id;
1676
    }
1677
1678
    /**
1679
	 * Retrieves the payment meta for an invoice.
1680
	 *
1681
	 * @since 1.0.19
1682
	 * @param  string $context View or edit context.
1683
	 * @return array
1684
	 */
1685
    public function get_payment_meta( $context = 'view' ) {
1686
1687
        return array(
1688
            '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

1688
            '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...
1689
            'date'         => $this->get_date_created( $context ),
1690
            'user_email'   => $this->get_email( $context ),
1691
            'invoice_key'  => $this->get_key( $context ),
1692
            'currency'     => $this->get_currency( $context ),
1693
            'items'        => $this->get_items( $context ),
1694
            'user_info'    => $this->get_user_info( $context ),
1695
            'cart_details' => $this->get_cart_details(),
1696
            'status'       => $this->get_status( $context ),
1697
            'fees'         => $this->get_fees( $context ),
1698
            'taxes'        => $this->get_taxes( $context ),
1699
        );
1700
1701
    }
1702
1703
    /**
1704
	 * Retrieves the cart details for an invoice.
1705
	 *
1706
	 * @since 1.0.19
1707
	 * @return array
1708
	 */
1709
    public function get_cart_details() {
1710
        $items        = $this->get_items();
1711
        $cart_details = array();
1712
1713
        foreach ( $items as $item_id => $item ) {
1714
			$item->invoice_id = $this->get_id();
1715
            $cart_details[]   = $item->prepare_data_for_saving();
1716
        }
1717
1718
        return $cart_details;
1719
	}
1720
1721
	/**
1722
	 * Retrieves the recurring item.
1723
	 *
1724
	 * @return null|GetPaid_Form_Item|int
1725
	 */
1726
	public function get_recurring( $object = false ) {
1727
1728
		// Are we returning an object?
1729
        if ( $object ) {
1730
            return $this->get_item( $this->recurring_item );
1731
        }
1732
1733
        return $this->recurring_item;
1734
    }
1735
1736
	/**
1737
	 * Retrieves the subscription name.
1738
	 *
1739
	 * @since 1.0.19
1740
	 * @return string
1741
	 */
1742
	public function get_subscription_name() {
1743
1744
		// Retrieve the recurring name
1745
        $item = $this->get_recurring( true );
1746
1747
		// Abort if it does not exist.
1748
        if ( empty( $item ) ) {
1749
            return '';
1750
        }
1751
1752
		// Return the item name.
1753
        return apply_filters( 'wpinv_invoice_get_subscription_name', $item->get_name(), $this );
1754
	}
1755
1756
	/**
1757
	 * Retrieves the view url.
1758
	 *
1759
	 * @since 1.0.19
1760
	 * @return string
1761
	 */
1762
	public function get_view_url() {
1763
        $invoice_url = get_permalink( $this->get_id() );
1764
		$invoice_url = add_query_arg( 'invoice_key', $this->get_key(), $invoice_url );
1765
        return apply_filters( 'wpinv_get_view_url', $invoice_url, $this );
1766
	}
1767
1768
	/**
1769
	 * Retrieves the payment url.
1770
	 *
1771
	 * @since 1.0.19
1772
	 * @return string
1773
	 */
1774
	public function get_checkout_payment_url( $deprecated = false, $secret = false ) {
1775
1776
		// Retrieve the checkout url.
1777
        $pay_url = wpinv_get_checkout_uri();
1778
1779
		// Maybe force ssl.
1780
        if ( is_ssl() ) {
1781
            $pay_url = str_replace( 'http:', 'https:', $pay_url );
1782
        }
1783
1784
		// Add the invoice key.
1785
		$pay_url = add_query_arg( 'invoice_key', $this->get_key(), $pay_url );
1786
1787
		// (Maybe?) add a secret
1788
        if ( $secret ) {
1789
            $pay_url = add_query_arg( array( '_wpipay' => md5( $this->get_user_id() . '::' . $this->get_email() . '::' . $this->get_key() ) ), $pay_url );
1790
        }
1791
1792
        return apply_filters( 'wpinv_get_checkout_payment_url', $pay_url, $this, $deprecated, $secret );
1793
	}
1794
	
1795
	/**
1796
	 * Retrieves the receipt url.
1797
	 *
1798
	 * @since 1.0.19
1799
	 * @return string
1800
	 */
1801
	public function get_receipt_url() {
1802
1803
		// Retrieve the checkout url.
1804
        $receipt_url = wpinv_get_success_page_uri();
1805
1806
		// Maybe force ssl.
1807
        if ( is_ssl() ) {
1808
            $receipt_url = str_replace( 'http:', 'https:', $receipt_url );
1809
        }
1810
1811
		// Add the invoice key.
1812
		$receipt_url = add_query_arg( 'invoice_key', $this->get_key(), $receipt_url );
1813
1814
        return apply_filters( 'getpaid_get_invoice_receipt_url', $receipt_url, $this );
1815
    }
1816
1817
    /**
1818
	 * Magic method for accessing invoice properties.
1819
	 *
1820
	 * @since 1.0.15
1821
	 * @access public
1822
	 *
1823
	 * @param string $key Discount data to retrieve
1824
	 * @param  string $context View or edit context.
1825
	 * @return mixed Value of the given invoice property (if set).
1826
	 */
1827
	public function get( $key, $context = 'view' ) {
1828
        return $this->get_prop( $key, $context );
1829
	}
1830
1831
    /*
1832
	|--------------------------------------------------------------------------
1833
	| Setters
1834
	|--------------------------------------------------------------------------
1835
	|
1836
	| Functions for setting item data. These should not update anything in the
1837
	| database itself and should only change what is stored in the class
1838
	| object.
1839
    */
1840
1841
    /**
1842
	 * Magic method for setting invoice properties.
1843
	 *
1844
	 * @since 1.0.19
1845
	 * @access public
1846
	 *
1847
	 * @param string $key Discount data to retrieve
1848
	 * @param  mixed $value new value.
1849
	 * @return mixed Value of the given invoice property (if set).
1850
	 */
1851
	public function set( $key, $value ) {
1852
1853
        $setter = "set_$key";
1854
        if ( is_callable( array( $this, $setter ) ) ) {
1855
            $this->{$setter}( $value );
1856
        }
1857
1858
	}
1859
1860
	/**
1861
	 * Sets item status.
1862
	 *
1863
	 * @since 1.0.19
1864
	 * @param string $new_status    New status.
1865
	 * @param string $note          Optional note to add.
1866
	 * @param bool   $manual_update Is this a manual status change?.
1867
	 * @return array details of change.
1868
	 */
1869
	public function set_status( $new_status, $note = '', $manual_update = false ) {
1870
		$old_status = $this->get_status();
1871
1872
		$statuses = $this->get_all_statuses();
1873
1874
		if ( isset( $statuses[ 'draft' ] ) ) {
1875
			unset( $statuses[ 'draft' ] );
1876
		}
1877
1878
		$this->set_prop( 'status', $new_status );
1879
1880
		// If setting the status, ensure it's set to a valid status.
1881
		if ( true === $this->object_read ) {
1882
1883
			// Only allow valid new status.
1884
			if ( ! array_key_exists( $new_status, $statuses ) ) {
1885
				$new_status = 'wpi-pending';
1886
			}
1887
1888
			// If the old status is set but unknown (e.g. draft) assume its pending for action usage.
1889
			if ( $old_status && ! array_key_exists( $new_status, $statuses ) ) {
1890
				$old_status = 'wpi-pending';
1891
			}
1892
1893
			// Paid - Renewal (i.e when duplicating a parent invoice )
1894
			if ( $new_status == 'wpi-pending' && $old_status == 'publish' && ! $this->get_id() ) {
1895
				$old_status = 'wpi-pending';
1896
			}
1897
1898
		}
1899
1900
		if ( true === $this->object_read && $old_status !== $new_status ) {
1901
			$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...
1902
				'from'   => ! empty( $this->status_transition['from'] ) ? $this->status_transition['from'] : $old_status,
1903
				'to'     => $new_status,
1904
				'note'   => $note,
1905
				'manual' => (bool) $manual_update,
1906
			);
1907
1908
			if ( $manual_update ) {
1909
				do_action( 'getpaid_' . $this->object_type .'_edit_status', $this->get_id(), $new_status );
1910
			}
1911
1912
			$this->maybe_set_date_paid();
1913
1914
		}
1915
1916
		return array(
1917
			'from' => $old_status,
1918
			'to'   => $new_status,
1919
		);
1920
	}
1921
1922
	/**
1923
	 * Maybe set date paid.
1924
	 *
1925
	 * Sets the date paid variable when transitioning to the payment complete
1926
	 * order status.
1927
	 *
1928
	 * @since 1.0.19
1929
	 */
1930
	public function maybe_set_date_paid() {
1931
1932
		if ( ! $this->get_date_completed( 'edit' ) && $this->is_paid() ) {
1933
			$this->set_date_completed( current_time( 'mysql' ) );
1934
		}
1935
	}
1936
1937
    /**
1938
	 * Set parent invoice ID.
1939
	 *
1940
	 * @since 1.0.19
1941
	 */
1942
	public function set_parent_id( $value ) {
1943
		if ( $value && ( $value === $this->get_id() ) ) {
1944
			return;
1945
		}
1946
		$this->set_prop( 'parent_id', absint( $value ) );
1947
    }
1948
1949
    /**
1950
	 * Set plugin version when the invoice was created.
1951
	 *
1952
	 * @since 1.0.19
1953
	 */
1954
	public function set_version( $value ) {
1955
		$this->set_prop( 'version', $value );
1956
    }
1957
1958
    /**
1959
	 * Set date when the invoice was created.
1960
	 *
1961
	 * @since 1.0.19
1962
	 * @param string $value Value to set.
1963
     * @return bool Whether or not the date was set.
1964
	 */
1965
	public function set_date_created( $value ) {
1966
        $date = strtotime( $value );
1967
1968
        if ( $date && $value !== '0000-00-00 00:00:00' ) {
1969
            $this->set_prop( 'date_created', date( 'Y-m-d H:i:s', $date ) );
1970
            return true;
1971
        }
1972
1973
        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...
1974
1975
    }
1976
1977
    /**
1978
	 * Set date invoice due date.
1979
	 *
1980
	 * @since 1.0.19
1981
	 * @param string $value Value to set.
1982
     * @return bool Whether or not the date was set.
1983
	 */
1984
	public function set_due_date( $value ) {
1985
        $date = strtotime( $value );
1986
1987
        if ( $date && $value !== '0000-00-00 00:00:00' ) {
1988
            $this->set_prop( 'due_date', date( 'Y-m-d H:i:s', $date ) );
1989
            return true;
1990
        }
1991
1992
		$this->set_prop( 'due_date', '' );
1993
        return false;
1994
1995
    }
1996
1997
    /**
1998
	 * Alias of self::set_due_date().
1999
	 *
2000
	 * @since 1.0.19
2001
	 * @param  string $value New name.
2002
	 */
2003
	public function set_date_due( $value ) {
2004
		$this->set_due_date( $value );
2005
    }
2006
2007
    /**
2008
	 * Set date invoice was completed.
2009
	 *
2010
	 * @since 1.0.19
2011
	 * @param string $value Value to set.
2012
     * @return bool Whether or not the date was set.
2013
	 */
2014
	public function set_completed_date( $value ) {
2015
        $date = strtotime( $value );
2016
2017
        if ( $date && $value !== '0000-00-00 00:00:00'  ) {
2018
            $this->set_prop( 'completed_date', date( 'Y-m-d H:i:s', $date ) );
2019
            return true;
2020
        }
2021
2022
		$this->set_prop( 'completed_date', '' );
2023
        return false;
2024
2025
    }
2026
2027
    /**
2028
	 * Alias of self::set_completed_date().
2029
	 *
2030
	 * @since 1.0.19
2031
	 * @param  string $value New name.
2032
	 */
2033
	public function set_date_completed( $value ) {
2034
		$this->set_completed_date( $value );
2035
    }
2036
2037
    /**
2038
	 * Set date when the invoice was last modified.
2039
	 *
2040
	 * @since 1.0.19
2041
	 * @param string $value Value to set.
2042
     * @return bool Whether or not the date was set.
2043
	 */
2044
	public function set_date_modified( $value ) {
2045
        $date = strtotime( $value );
2046
2047
        if ( $date && $value !== '0000-00-00 00:00:00' ) {
2048
            $this->set_prop( 'date_modified', date( 'Y-m-d H:i:s', $date ) );
2049
            return true;
2050
        }
2051
2052
		$this->set_prop( 'date_modified', '' );
2053
        return false;
2054
2055
    }
2056
2057
    /**
2058
	 * Set the invoice number.
2059
	 *
2060
	 * @since 1.0.19
2061
	 * @param  string $value New number.
2062
	 */
2063
	public function set_number( $value ) {
2064
        $number = sanitize_text_field( $value );
2065
		$this->set_prop( 'number', $number );
2066
    }
2067
2068
    /**
2069
	 * Set the invoice type.
2070
	 *
2071
	 * @since 1.0.19
2072
	 * @param  string $value Type.
2073
	 */
2074
	public function set_type( $value ) {
2075
        $type = sanitize_text_field( str_replace( 'wpi_', '', $value ) );
2076
		$this->set_prop( 'type', $type );
2077
	}
2078
2079
    /**
2080
	 * Set the invoice post type.
2081
	 *
2082
	 * @since 1.0.19
2083
	 * @param  string $value Post type.
2084
	 */
2085
	public function set_post_type( $value ) {
2086
        if ( getpaid_is_invoice_post_type( $value ) ) {
2087
			$this->set_type( $value );
2088
            $this->set_prop( 'post_type', $value );
2089
        }
2090
    }
2091
2092
    /**
2093
	 * Set the invoice key.
2094
	 *
2095
	 * @since 1.0.19
2096
	 * @param  string $value New key.
2097
	 */
2098
	public function set_key( $value ) {
2099
        $key = sanitize_text_field( $value );
2100
		$this->set_prop( 'key', $key );
2101
    }
2102
2103
    /**
2104
	 * Set the invoice mode.
2105
	 *
2106
	 * @since 1.0.19
2107
	 * @param  string $value mode.
2108
	 */
2109
	public function set_mode( $value ) {
2110
        if ( ! in_array( $value, array( 'live', 'test' ) ) ) {
2111
            $this->set_prop( 'value', $value );
2112
        }
2113
    }
2114
2115
    /**
2116
	 * Set the invoice path.
2117
	 *
2118
	 * @since 1.0.19
2119
	 * @param  string $value path.
2120
	 */
2121
	public function set_path( $value ) {
2122
        $this->set_prop( 'path', $value );
2123
    }
2124
2125
    /**
2126
	 * Set the invoice name.
2127
	 *
2128
	 * @since 1.0.19
2129
	 * @param  string $value New name.
2130
	 */
2131
	public function set_name( $value ) {
2132
        $name = sanitize_text_field( $value );
2133
		$this->set_prop( 'name', $name );
2134
    }
2135
2136
    /**
2137
	 * Alias of self::set_name().
2138
	 *
2139
	 * @since 1.0.19
2140
	 * @param  string $value New name.
2141
	 */
2142
	public function set_title( $value ) {
2143
		$this->set_name( $value );
2144
    }
2145
2146
    /**
2147
	 * Set the invoice description.
2148
	 *
2149
	 * @since 1.0.19
2150
	 * @param  string $value New description.
2151
	 */
2152
	public function set_description( $value ) {
2153
        $description = wp_kses_post( $value );
2154
		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...
2155
    }
2156
2157
    /**
2158
	 * Alias of self::set_description().
2159
	 *
2160
	 * @since 1.0.19
2161
	 * @param  string $value New description.
2162
	 */
2163
	public function set_excerpt( $value ) {
2164
		$this->set_description( $value );
2165
    }
2166
2167
    /**
2168
	 * Alias of self::set_description().
2169
	 *
2170
	 * @since 1.0.19
2171
	 * @param  string $value New description.
2172
	 */
2173
	public function set_summary( $value ) {
2174
		$this->set_description( $value );
2175
    }
2176
2177
    /**
2178
	 * Set the receiver of the invoice.
2179
	 *
2180
	 * @since 1.0.19
2181
	 * @param  int $value New author.
2182
	 */
2183
	public function set_author( $value ) {
2184
		$user = get_user_by( 'id', (int) $value );
2185
2186
		if ( $user && $user->ID ) {
2187
			$this->set_prop( 'author', $user->ID );
2188
			$this->set_prop( 'email', $user->user_email );
2189
		}
2190
		
2191
    }
2192
2193
    /**
2194
	 * Alias of self::set_author().
2195
	 *
2196
	 * @since 1.0.19
2197
	 * @param  int $value New user id.
2198
	 */
2199
	public function set_user_id( $value ) {
2200
		$this->set_author( $value );
2201
    }
2202
2203
    /**
2204
	 * Alias of self::set_author().
2205
	 *
2206
	 * @since 1.0.19
2207
	 * @param  int $value New user id.
2208
	 */
2209
	public function set_customer_id( $value ) {
2210
		$this->set_author( $value );
2211
    }
2212
2213
    /**
2214
	 * Set the customer's ip.
2215
	 *
2216
	 * @since 1.0.19
2217
	 * @param  string $value ip address.
2218
	 */
2219
	public function set_ip( $value ) {
2220
		$this->set_prop( 'ip', $value );
2221
    }
2222
2223
    /**
2224
	 * Alias of self::set_ip().
2225
	 *
2226
	 * @since 1.0.19
2227
	 * @param  string $value ip address.
2228
	 */
2229
	public function set_user_ip( $value ) {
2230
		$this->set_ip( $value );
2231
    }
2232
2233
    /**
2234
	 * Set the customer's first name.
2235
	 *
2236
	 * @since 1.0.19
2237
	 * @param  string $value first name.
2238
	 */
2239
	public function set_first_name( $value ) {
2240
		$this->set_prop( 'first_name', $value );
2241
    }
2242
2243
    /**
2244
	 * Alias of self::set_first_name().
2245
	 *
2246
	 * @since 1.0.19
2247
	 * @param  string $value first name.
2248
	 */
2249
	public function set_user_first_name( $value ) {
2250
		$this->set_first_name( $value );
2251
    }
2252
2253
    /**
2254
	 * Alias of self::set_first_name().
2255
	 *
2256
	 * @since 1.0.19
2257
	 * @param  string $value first name.
2258
	 */
2259
	public function set_customer_first_name( $value ) {
2260
		$this->set_first_name( $value );
2261
    }
2262
2263
    /**
2264
	 * Set the customer's last name.
2265
	 *
2266
	 * @since 1.0.19
2267
	 * @param  string $value last name.
2268
	 */
2269
	public function set_last_name( $value ) {
2270
		$this->set_prop( 'last_name', $value );
2271
    }
2272
2273
    /**
2274
	 * Alias of self::set_last_name().
2275
	 *
2276
	 * @since 1.0.19
2277
	 * @param  string $value last name.
2278
	 */
2279
	public function set_user_last_name( $value ) {
2280
		$this->set_last_name( $value );
2281
    }
2282
2283
    /**
2284
	 * Alias of self::set_last_name().
2285
	 *
2286
	 * @since 1.0.19
2287
	 * @param  string $value last name.
2288
	 */
2289
	public function set_customer_last_name( $value ) {
2290
		$this->set_last_name( $value );
2291
    }
2292
2293
    /**
2294
	 * Set the customer's phone number.
2295
	 *
2296
	 * @since 1.0.19
2297
	 * @param  string $value phone.
2298
	 */
2299
	public function set_phone( $value ) {
2300
		$this->set_prop( 'phone', $value );
2301
    }
2302
2303
    /**
2304
	 * Alias of self::set_phone().
2305
	 *
2306
	 * @since 1.0.19
2307
	 * @param  string $value phone.
2308
	 */
2309
	public function set_user_phone( $value ) {
2310
		$this->set_phone( $value );
2311
    }
2312
2313
    /**
2314
	 * Alias of self::set_phone().
2315
	 *
2316
	 * @since 1.0.19
2317
	 * @param  string $value phone.
2318
	 */
2319
	public function set_customer_phone( $value ) {
2320
		$this->set_phone( $value );
2321
    }
2322
2323
    /**
2324
	 * Alias of self::set_phone().
2325
	 *
2326
	 * @since 1.0.19
2327
	 * @param  string $value phone.
2328
	 */
2329
	public function set_phone_number( $value ) {
2330
		$this->set_phone( $value );
2331
    }
2332
2333
    /**
2334
	 * Set the customer's email address.
2335
	 *
2336
	 * @since 1.0.19
2337
	 * @param  string $value email address.
2338
	 */
2339
	public function set_email( $value ) {
2340
		$this->set_prop( 'email', $value );
2341
    }
2342
2343
    /**
2344
	 * Alias of self::set_email().
2345
	 *
2346
	 * @since 1.0.19
2347
	 * @param  string $value email address.
2348
	 */
2349
	public function set_user_email( $value ) {
2350
		$this->set_email( $value );
2351
    }
2352
2353
    /**
2354
	 * Alias of self::set_email().
2355
	 *
2356
	 * @since 1.0.19
2357
	 * @param  string $value email address.
2358
	 */
2359
	public function set_email_address( $value ) {
2360
		$this->set_email( $value );
2361
    }
2362
2363
    /**
2364
	 * Alias of self::set_email().
2365
	 *
2366
	 * @since 1.0.19
2367
	 * @param  string $value email address.
2368
	 */
2369
	public function set_customer_email( $value ) {
2370
		$this->set_email( $value );
2371
    }
2372
2373
    /**
2374
	 * Set the customer's country.
2375
	 *
2376
	 * @since 1.0.19
2377
	 * @param  string $value country.
2378
	 */
2379
	public function set_country( $value ) {
2380
		$this->set_prop( 'country', $value );
2381
    }
2382
2383
    /**
2384
	 * Alias of self::set_country().
2385
	 *
2386
	 * @since 1.0.19
2387
	 * @param  string $value country.
2388
	 */
2389
	public function set_user_country( $value ) {
2390
		$this->set_country( $value );
2391
    }
2392
2393
    /**
2394
	 * Alias of self::set_country().
2395
	 *
2396
	 * @since 1.0.19
2397
	 * @param  string $value country.
2398
	 */
2399
	public function set_customer_country( $value ) {
2400
		$this->set_country( $value );
2401
    }
2402
2403
    /**
2404
	 * Set the customer's state.
2405
	 *
2406
	 * @since 1.0.19
2407
	 * @param  string $value state.
2408
	 */
2409
	public function set_state( $value ) {
2410
		$this->set_prop( 'state', $value );
2411
    }
2412
2413
    /**
2414
	 * Alias of self::set_state().
2415
	 *
2416
	 * @since 1.0.19
2417
	 * @param  string $value state.
2418
	 */
2419
	public function set_user_state( $value ) {
2420
		$this->set_state( $value );
2421
    }
2422
2423
    /**
2424
	 * Alias of self::set_state().
2425
	 *
2426
	 * @since 1.0.19
2427
	 * @param  string $value state.
2428
	 */
2429
	public function set_customer_state( $value ) {
2430
		$this->set_state( $value );
2431
    }
2432
2433
    /**
2434
	 * Set the customer's city.
2435
	 *
2436
	 * @since 1.0.19
2437
	 * @param  string $value city.
2438
	 */
2439
	public function set_city( $value ) {
2440
		$this->set_prop( 'city', $value );
2441
    }
2442
2443
    /**
2444
	 * Alias of self::set_city().
2445
	 *
2446
	 * @since 1.0.19
2447
	 * @param  string $value city.
2448
	 */
2449
	public function set_user_city( $value ) {
2450
		$this->set_city( $value );
2451
    }
2452
2453
    /**
2454
	 * Alias of self::set_city().
2455
	 *
2456
	 * @since 1.0.19
2457
	 * @param  string $value city.
2458
	 */
2459
	public function set_customer_city( $value ) {
2460
		$this->set_city( $value );
2461
    }
2462
2463
    /**
2464
	 * Set the customer's zip code.
2465
	 *
2466
	 * @since 1.0.19
2467
	 * @param  string $value zip.
2468
	 */
2469
	public function set_zip( $value ) {
2470
		$this->set_prop( 'zip', $value );
2471
    }
2472
2473
    /**
2474
	 * Alias of self::set_zip().
2475
	 *
2476
	 * @since 1.0.19
2477
	 * @param  string $value zip.
2478
	 */
2479
	public function set_user_zip( $value ) {
2480
		$this->set_zip( $value );
2481
    }
2482
2483
    /**
2484
	 * Alias of self::set_zip().
2485
	 *
2486
	 * @since 1.0.19
2487
	 * @param  string $value zip.
2488
	 */
2489
	public function set_customer_zip( $value ) {
2490
		$this->set_zip( $value );
2491
    }
2492
2493
    /**
2494
	 * Set the customer's company.
2495
	 *
2496
	 * @since 1.0.19
2497
	 * @param  string $value company.
2498
	 */
2499
	public function set_company( $value ) {
2500
		$this->set_prop( 'company', $value );
2501
    }
2502
2503
    /**
2504
	 * Alias of self::set_company().
2505
	 *
2506
	 * @since 1.0.19
2507
	 * @param  string $value company.
2508
	 */
2509
	public function set_user_company( $value ) {
2510
		$this->set_company( $value );
2511
    }
2512
2513
    /**
2514
	 * Alias of self::set_company().
2515
	 *
2516
	 * @since 1.0.19
2517
	 * @param  string $value company.
2518
	 */
2519
	public function set_customer_company( $value ) {
2520
		$this->set_company( $value );
2521
    }
2522
2523
    /**
2524
	 * Set the customer's var number.
2525
	 *
2526
	 * @since 1.0.19
2527
	 * @param  string $value var number.
2528
	 */
2529
	public function set_vat_number( $value ) {
2530
		$this->set_prop( 'vat_number', $value );
2531
    }
2532
2533
    /**
2534
	 * Alias of self::set_vat_number().
2535
	 *
2536
	 * @since 1.0.19
2537
	 * @param  string $value var number.
2538
	 */
2539
	public function set_user_vat_number( $value ) {
2540
		$this->set_vat_number( $value );
2541
    }
2542
2543
    /**
2544
	 * Alias of self::set_vat_number().
2545
	 *
2546
	 * @since 1.0.19
2547
	 * @param  string $value var number.
2548
	 */
2549
	public function set_customer_vat_number( $value ) {
2550
		$this->set_vat_number( $value );
2551
    }
2552
2553
    /**
2554
	 * Set the customer's vat rate.
2555
	 *
2556
	 * @since 1.0.19
2557
	 * @param  string $value var rate.
2558
	 */
2559
	public function set_vat_rate( $value ) {
2560
		$this->set_prop( 'vat_rate', $value );
2561
    }
2562
2563
    /**
2564
	 * Alias of self::set_vat_rate().
2565
	 *
2566
	 * @since 1.0.19
2567
	 * @param  string $value var number.
2568
	 */
2569
	public function set_user_vat_rate( $value ) {
2570
		$this->set_vat_rate( $value );
2571
    }
2572
2573
    /**
2574
	 * Alias of self::set_vat_rate().
2575
	 *
2576
	 * @since 1.0.19
2577
	 * @param  string $value var number.
2578
	 */
2579
	public function set_customer_vat_rate( $value ) {
2580
		$this->set_vat_rate( $value );
2581
    }
2582
2583
    /**
2584
	 * Set the customer's address.
2585
	 *
2586
	 * @since 1.0.19
2587
	 * @param  string $value address.
2588
	 */
2589
	public function set_address( $value ) {
2590
		$this->set_prop( 'address', $value );
2591
    }
2592
2593
    /**
2594
	 * Alias of self::set_address().
2595
	 *
2596
	 * @since 1.0.19
2597
	 * @param  string $value address.
2598
	 */
2599
	public function set_user_address( $value ) {
2600
		$this->set_address( $value );
2601
    }
2602
2603
    /**
2604
	 * Alias of self::set_address().
2605
	 *
2606
	 * @since 1.0.19
2607
	 * @param  string $value address.
2608
	 */
2609
	public function set_customer_address( $value ) {
2610
		$this->set_address( $value );
2611
    }
2612
2613
    /**
2614
	 * Set whether the customer has viewed the invoice or not.
2615
	 *
2616
	 * @since 1.0.19
2617
	 * @param  int|bool $value confirmed.
2618
	 */
2619
	public function set_is_viewed( $value ) {
2620
		$this->set_prop( 'is_viewed', $value );
2621
	}
2622
2623
	/**
2624
	 * Set extra email recipients.
2625
	 *
2626
	 * @since 1.0.19
2627
	 * @param  string $value email recipients.
2628
	 */
2629
	public function set_email_cc( $value ) {
2630
		$this->set_prop( 'email_cc', $value );
2631
	}
2632
2633
	/**
2634
	 * Set the invoice template.
2635
	 *
2636
	 * @since 1.0.19
2637
	 * @param  string $value template.
2638
	 */
2639
	public function set_template( $value ) {
2640
		if ( in_array( $value, array( 'quantity', 'hours', 'amount' ) ) ) {
2641
			$this->set_prop( 'template', $value );
2642
		}
2643
	}
2644
2645
	/**
2646
	 * Set the invoice source.
2647
	 *
2648
	 * @since 1.0.19
2649
	 * @param  string $value email recipients.
2650
	 */
2651
	public function created_via( $value ) {
2652
		$this->set_prop( 'created_via', sanitize_text_field( $value ) );
2653
	}
2654
2655
	/**
2656
	 * Set the customer's address confirmed status.
2657
	 *
2658
	 * @since 1.0.19
2659
	 * @param  int|bool $value confirmed.
2660
	 */
2661
	public function set_address_confirmed( $value ) {
2662
		$this->set_prop( 'address_confirmed', $value );
2663
    }
2664
2665
    /**
2666
	 * Alias of self::set_address_confirmed().
2667
	 *
2668
	 * @since 1.0.19
2669
	 * @param  int|bool $value confirmed.
2670
	 */
2671
	public function set_user_address_confirmed( $value ) {
2672
		$this->set_address_confirmed( $value );
2673
    }
2674
2675
    /**
2676
	 * Alias of self::set_address_confirmed().
2677
	 *
2678
	 * @since 1.0.19
2679
	 * @param  int|bool $value confirmed.
2680
	 */
2681
	public function set_customer_address_confirmed( $value ) {
2682
		$this->set_address_confirmed( $value );
2683
    }
2684
2685
    /**
2686
	 * Set the invoice sub total.
2687
	 *
2688
	 * @since 1.0.19
2689
	 * @param  float $value sub total.
2690
	 */
2691
	public function set_subtotal( $value ) {
2692
		$this->set_prop( 'subtotal', $value );
2693
    }
2694
2695
    /**
2696
	 * Set the invoice discount amount.
2697
	 *
2698
	 * @since 1.0.19
2699
	 * @param  float $value discount total.
2700
	 */
2701
	public function set_total_discount( $value ) {
2702
		$this->set_prop( 'total_discount', $value );
2703
    }
2704
2705
    /**
2706
	 * Alias of self::set_total_discount().
2707
	 *
2708
	 * @since 1.0.19
2709
	 * @param  float $value discount total.
2710
	 */
2711
	public function set_discount( $value ) {
2712
		$this->set_total_discount( $value );
2713
    }
2714
2715
    /**
2716
	 * Set the invoice tax amount.
2717
	 *
2718
	 * @since 1.0.19
2719
	 * @param  float $value tax total.
2720
	 */
2721
	public function set_total_tax( $value ) {
2722
		$this->set_prop( 'total_tax', $value );
2723
    }
2724
2725
    /**
2726
	 * Alias of self::set_total_tax().
2727
	 *
2728
	 * @since 1.0.19
2729
	 * @param  float $value tax total.
2730
	 */
2731
	public function set_tax_total( $value ) {
2732
		$this->set_total_tax( $value );
2733
    }
2734
2735
    /**
2736
	 * Set the invoice fees amount.
2737
	 *
2738
	 * @since 1.0.19
2739
	 * @param  float $value fees total.
2740
	 */
2741
	public function set_total_fees( $value ) {
2742
		$this->set_prop( 'total_fees', $value );
2743
    }
2744
2745
    /**
2746
	 * Alias of self::set_total_fees().
2747
	 *
2748
	 * @since 1.0.19
2749
	 * @param  float $value fees total.
2750
	 */
2751
	public function set_fees_total( $value ) {
2752
		$this->set_total_fees( $value );
2753
    }
2754
2755
    /**
2756
	 * Set the invoice fees.
2757
	 *
2758
	 * @since 1.0.19
2759
	 * @param  array $value fees.
2760
	 */
2761
	public function set_fees( $value ) {
2762
2763
		if ( ! is_array( $value ) ) {
0 ignored issues
show
introduced by
The condition is_array($value) is always true.
Loading history...
2764
			$value = array();
2765
		}
2766
2767
		$this->set_prop( 'fees', $value );
2768
2769
    }
2770
2771
    /**
2772
	 * Set the invoice taxes.
2773
	 *
2774
	 * @since 1.0.19
2775
	 * @param  array $value taxes.
2776
	 */
2777
	public function set_taxes( $value ) {
2778
2779
		if ( ! is_array( $value ) ) {
0 ignored issues
show
introduced by
The condition is_array($value) is always true.
Loading history...
2780
			$value = array();
2781
		}
2782
2783
		$this->set_prop( 'taxes', $value );
2784
2785
    }
2786
2787
    /**
2788
	 * Set the invoice discounts.
2789
	 *
2790
	 * @since 1.0.19
2791
	 * @param  array $value discounts.
2792
	 */
2793
	public function set_discounts( $value ) {
2794
2795
		if ( ! is_array( $value ) ) {
0 ignored issues
show
introduced by
The condition is_array($value) is always true.
Loading history...
2796
			$value = array();
2797
		}
2798
2799
		$this->set_prop( 'discounts', $value );
2800
    }
2801
2802
    /**
2803
	 * Set the invoice items.
2804
	 *
2805
	 * @since 1.0.19
2806
	 * @param  GetPaid_Form_Item[] $value items.
2807
	 */
2808
	public function set_items( $value ) {
2809
2810
        // Remove existing items.
2811
        $this->set_prop( 'items', array() );
2812
2813
        // Ensure that we have an array.
2814
        if ( ! is_array( $value ) ) {
0 ignored issues
show
introduced by
The condition is_array($value) is always true.
Loading history...
2815
            return;
2816
        }
2817
2818
        foreach ( $value as $item ) {
2819
            $this->add_item( $item );
2820
        }
2821
2822
    }
2823
2824
    /**
2825
	 * Set the payment form.
2826
	 *
2827
	 * @since 1.0.19
2828
	 * @param  int $value payment form.
2829
	 */
2830
	public function set_payment_form( $value ) {
2831
		$this->set_prop( 'payment_form', $value );
2832
    }
2833
2834
    /**
2835
	 * Set the submission id.
2836
	 *
2837
	 * @since 1.0.19
2838
	 * @param  string $value submission id.
2839
	 */
2840
	public function set_submission_id( $value ) {
2841
		$this->set_prop( 'submission_id', $value );
2842
    }
2843
2844
    /**
2845
	 * Set the discount code.
2846
	 *
2847
	 * @since 1.0.19
2848
	 * @param  string $value discount code.
2849
	 */
2850
	public function set_discount_code( $value ) {
2851
		$this->set_prop( 'discount_code', $value );
2852
    }
2853
2854
    /**
2855
	 * Set the gateway.
2856
	 *
2857
	 * @since 1.0.19
2858
	 * @param  string $value gateway.
2859
	 */
2860
	public function set_gateway( $value ) {
2861
		$this->set_prop( 'gateway', $value );
2862
    }
2863
2864
    /**
2865
	 * Set the transaction id.
2866
	 *
2867
	 * @since 1.0.19
2868
	 * @param  string $value transaction id.
2869
	 */
2870
	public function set_transaction_id( $value ) {
2871
		if ( ! empty( $value ) ) {
2872
			$this->set_prop( 'transaction_id', $value );
2873
		}
2874
    }
2875
2876
    /**
2877
	 * Set the currency id.
2878
	 *
2879
	 * @since 1.0.19
2880
	 * @param  string $value currency id.
2881
	 */
2882
	public function set_currency( $value ) {
2883
		$this->set_prop( 'currency', $value );
2884
    }
2885
2886
	/**
2887
	 * Set whether to disable taxes.
2888
	 *
2889
	 * @since 1.0.19
2890
	 * @param  bool $value value.
2891
	 */
2892
	public function set_disable_taxes( $value ) {
2893
		$this->set_prop( 'disable_taxes', (bool) $value );
2894
	}
2895
2896
    /**
2897
	 * Set the subscription id.
2898
	 *
2899
	 * @since 1.0.19
2900
	 * @param  string $value subscription id.
2901
	 */
2902
	public function set_subscription_id( $value ) {
2903
		$this->set_prop( 'subscription_id', $value );
2904
	}
2905
	
2906
	/**
2907
	 * Set the remote subscription id.
2908
	 *
2909
	 * @since 1.0.19
2910
	 * @param  string $value subscription id.
2911
	 */
2912
	public function set_remote_subscription_id( $value ) {
2913
		$this->set_prop( 'remote_subscription_id', $value );
2914
    }
2915
2916
    /*
2917
	|--------------------------------------------------------------------------
2918
	| Boolean methods
2919
	|--------------------------------------------------------------------------
2920
	|
2921
	| Return true or false.
2922
	|
2923
    */
2924
2925
    /**
2926
     * Checks if this is a parent invoice.
2927
     */
2928
    public function is_parent() {
2929
        $parent = $this->get_parent_id();
2930
        return apply_filters( 'wpinv_invoice_is_parent', empty( $parent ), $this );
2931
    }
2932
2933
    /**
2934
     * Checks if this is a renewal invoice.
2935
     */
2936
    public function is_renewal() {
2937
        return ! $this->is_parent();
2938
    }
2939
2940
    /**
2941
     * Checks if this is a recurring invoice.
2942
     */
2943
    public function is_recurring() {
2944
        return $this->is_renewal() || ! empty( $this->recurring_item );
2945
    }
2946
2947
    /**
2948
     * Checks if this is a taxable invoice.
2949
     */
2950
    public function is_taxable() {
2951
        return ! $this->get_disable_taxes();
2952
	}
2953
2954
	/**
2955
	 * @deprecated
2956
	 */
2957
	public function has_vat() {
2958
        global $wpinv_euvat, $wpi_country;
2959
2960
        $requires_vat = false;
2961
2962
        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...
2963
            $wpi_country        = $this->country;
2964
            $requires_vat       = $wpinv_euvat->requires_vat( $requires_vat, $this->get_user_id(), $wpinv_euvat->invoice_has_digital_rule( $this ) );
2965
        }
2966
2967
        return apply_filters( 'wpinv_invoice_has_vat', $requires_vat, $this );
2968
	}
2969
2970
	/**
2971
	 * Checks to see if the invoice requires payment.
2972
	 */
2973
	public function is_free() {
2974
        $is_free = ( (float) wpinv_round_amount( $this->get_initial_total() ) == 0 );
2975
2976
		if ( $this->is_recurring() && $this->get_recurring_total() > 0 ) {
2977
			$is_free = false;
2978
		}
2979
2980
        return apply_filters( 'wpinv_invoice_is_free', $is_free, $this );
2981
    }
2982
2983
    /**
2984
     * Checks if the invoice is paid.
2985
     */
2986
    public function is_paid() {
2987
        $is_paid = $this->has_status( array( 'publish', 'wpi-processing', 'wpi-renewal' ) );
2988
        return apply_filters( 'wpinv_invoice_is_paid', $is_paid, $this );
2989
	}
2990
2991
	/**
2992
     * Checks if the invoice needs payment.
2993
     */
2994
	public function needs_payment() {
2995
		$needs_payment = ! $this->is_paid() && ! $this->is_refunded() && ! $this->is_free();
2996
        return apply_filters( 'wpinv_needs_payment', $needs_payment, $this );
2997
    }
2998
  
2999
	/**
3000
     * Checks if the invoice is refunded.
3001
     */
3002
	public function is_refunded() {
3003
        $is_refunded = $this->has_status( 'wpi-refunded' );
3004
        return apply_filters( 'wpinv_invoice_is_refunded', $is_refunded, $this );
3005
	}
3006
3007
	/**
3008
     * Checks if the invoice is held.
3009
     */
3010
	public function is_held() {
3011
        $is_held = $this->has_status( 'wpi-onhold' );
3012
        return apply_filters( 'wpinv_invoice_is_held', $is_held, $this );
3013
	}
3014
3015
	/**
3016
     * Checks if the invoice is due.
3017
     */
3018
	public function is_due() {
3019
		$due_date = $this->get_due_date();
3020
		return empty( $due_date ) ? false : current_time( 'timestamp' ) > strtotime( $due_date );
3021
	}
3022
3023
	/**
3024
     * Checks if the invoice is draft.
3025
     */
3026
	public function is_draft() {
3027
        return $this->has_status( 'draft, auto-draft' );
3028
	}
3029
3030
    /**
3031
     * Checks if the invoice has a given status.
3032
     */
3033
    public function has_status( $status ) {
3034
        $status = wpinv_parse_list( $status );
3035
        return apply_filters( 'wpinv_has_status', in_array( $this->get_status(), $status ), $status );
3036
	}
3037
3038
	/**
3039
     * Checks if the invoice is of a given type.
3040
     */
3041
    public function is_type( $type ) {
3042
        $type = wpinv_parse_list( $type );
3043
        return in_array( $this->get_type(), $type );
3044
    }
3045
3046
    /**
3047
     * Checks if this is a quote object.
3048
     *
3049
     * @since 1.0.15
3050
     */
3051
    public function is_quote() {
3052
        return 'wpi_quote' == $this->get_post_type();
3053
    }
3054
3055
    /**
3056
     * Check if the invoice (or it's parent has a free trial).
3057
     *
3058
     */
3059
    public function has_free_trial() {
3060
        return $this->is_recurring() && 0 == $this->get_initial_total();
3061
	}
3062
3063
	/**
3064
     * @deprecated
3065
     */
3066
    public function is_free_trial() {
3067
        $this->has_free_trial();
3068
    }
3069
3070
	/**
3071
     * Check if the initial payment if 0.
3072
     *
3073
     */
3074
	public function is_initial_free() {
3075
        $is_initial_free = ! ( (float) wpinv_round_amount( $this->get_initial_total() ) > 0 );
3076
        return apply_filters( 'wpinv_invoice_is_initial_free', $is_initial_free, $this->get_cart_details(), $this );
3077
    }
3078
	
3079
	/**
3080
     * Check if the recurring item has a free trial.
3081
     *
3082
     */
3083
    public function item_has_free_trial() {
3084
3085
        // Ensure we have a recurring item.
3086
        if ( ! $this->is_recurring() ) {
3087
            return false;
3088
        }
3089
3090
        $item = $this->get_recurring( true );
3091
        return $item->has_free_trial();
3092
	}
3093
3094
	/**
3095
     * Check if the free trial is a result of a discount.
3096
     */
3097
    public function is_free_trial_from_discount() {
3098
		return $this->has_free_trial() && ! $this->item_has_free_trial();
3099
	}
3100
	
3101
	/**
3102
     * @deprecated
3103
     */
3104
    public function discount_first_payment_only() {
3105
3106
		$discount_code = $this->get_discount_code();
3107
        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...
3108
            return true;
3109
        }
3110
3111
        $discount = wpinv_get_discount_obj( $discount_code );
3112
3113
        if ( ! $discount || ! $discount->exists() ) {
0 ignored issues
show
introduced by
$discount is of type WPInv_Discount, thus it always evaluated to true.
Loading history...
3114
            return true;
3115
        }
3116
3117
        return ! $discount->get_is_recurring();
3118
    }
3119
3120
    /*
3121
	|--------------------------------------------------------------------------
3122
	| Cart related methods
3123
	|--------------------------------------------------------------------------
3124
	|
3125
	| Do not forget to recalculate totals after calling the following methods.
3126
	|
3127
    */
3128
3129
    /**
3130
     * Adds an item to the invoice.
3131
     *
3132
     * @param GetPaid_Form_Item|array $item
3133
     * @return WP_Error|Bool
3134
     */
3135
    public function add_item( $item ) {
3136
3137
		if ( is_array( $item ) ) {
3138
			$item = $this->process_array_item( $item );
3139
		}
3140
3141
		if ( is_numeric( $item ) ) {
0 ignored issues
show
introduced by
The condition is_numeric($item) is always false.
Loading history...
3142
			$item = new GetPaid_Form_Item( $item );
3143
		}
3144
3145
        // Make sure that it is available for purchase.
3146
		if ( $item->get_id() > 0 && ! $item->can_purchase() ) {
3147
			return new WP_Error( 'invalid_item', __( 'This item is not available for purchase', 'invoicing' ) );
3148
        }
3149
3150
        // Do we have a recurring item?
3151
		if ( $item->is_recurring() ) {
3152
3153
			// An invoice can only contain one recurring item.
3154
			if ( ! empty( $this->recurring_item  && $this->recurring_item != (int) $item->get_id() ) ) {
3155
				return new WP_Error( 'recurring_item', __( 'An invoice can only contain one recurring item', 'invoicing' ) );
3156
			}
3157
3158
			$this->recurring_item = $item->get_id();
3159
        }
3160
3161
        // Invoice id.
3162
        $item->invoice_id = (int) $this->get_id();
3163
3164
        // Retrieve all items.
3165
        $items = $this->get_items();
3166
        $items[ (int) $item->get_id() ] = $item;
3167
3168
        $this->set_prop( 'items', $items );
3169
		return true;
3170
	}
3171
3172
	/**
3173
	 * Converts an array to an item.
3174
	 *
3175
	 * @since 1.0.19
3176
	 * @return GetPaid_Form_Item
3177
	 */
3178
	protected function process_array_item( $array ) {
3179
3180
		$item_id = isset( $array['item_id'] ) ? $array['item_id'] : 0;
3181
		$item    = new GetPaid_Form_Item( $item_id );
3182
3183
		// Set item data.
3184
		foreach ( array( 'name', 'price', 'description' ) as $key ) {
3185
			if ( isset( $array[ "item_$key" ] ) ) {
3186
				$method = "set_$key";
3187
				$item->$method( $array[ "item_$key" ] );
3188
			}
3189
		}
3190
3191
		if ( isset( $array['quantity'] ) ) {
3192
			$item->set_quantity( $array['quantity'] );
3193
		}
3194
3195
		// Set item meta.
3196
		if ( isset( $array['meta'] ) && is_array( $array['meta'] ) ) {
3197
			$item->set_item_meta( $array['meta'] );
3198
		}
3199
3200
		return $item;
3201
3202
	}
3203
3204
    /**
3205
	 * Retrieves a specific item.
3206
	 *
3207
	 * @since 1.0.19
3208
	 */
3209
	public function get_item( $item_id ) {
3210
		$items   = $this->get_items();
3211
		$item_id = (int) $item_id;
3212
		return ( ! empty( $item_id ) && isset( $items[ $item_id ] ) ) ? $items[ $item_id ] : null;
3213
    }
3214
3215
    /**
3216
	 * Removes a specific item.
3217
	 *
3218
	 * @since 1.0.19
3219
	 */
3220
	public function remove_item( $item_id ) {
3221
		$items   = $this->get_items();
3222
		$item_id = (int) $item_id;
3223
3224
        if ( $item_id == $this->recurring_item ) {
3225
            $this->recurring_item = null;
3226
        }
3227
3228
        if ( isset( $items[ $item_id ] ) ) {
3229
            unset( $items[ $item_id ] );
3230
            $this->set_prop( 'items', $items );
3231
        }
3232
    }
3233
3234
    /**
3235
	 * Adds a fee to the invoice.
3236
	 *
3237
	 * @param array $fee An array of fee details. name, initial_fee, and recurring_fee are required.
3238
	 * @since 1.0.19
3239
	 */
3240
    public function add_fee( $fee ) {
3241
3242
		$fees                 = $this->get_fees();
3243
		$fees[ $fee['name'] ] = $fee;
3244
		$this->set_prop( 'fees', $fees );
3245
3246
    }
3247
3248
    /**
3249
	 * Retrieves a specific fee.
3250
	 *
3251
	 * @since 1.0.19
3252
	 */
3253
	public function get_fee( $fee ) {
3254
        $fees = $this->get_fees();
3255
		return isset( $fees[ $fee ] ) ? $fees[ $fee ] : null;
3256
    }
3257
3258
    /**
3259
	 * Removes a specific fee.
3260
	 *
3261
	 * @since 1.0.19
3262
	 */
3263
	public function remove_fee( $fee ) {
3264
        $fees = $this->get_fees();
3265
        if ( isset( $fees[ $fee ] ) ) {
3266
            unset( $fees[ $fee ] );
3267
            $this->set_prop( 'fees', $fees );
3268
        }
3269
    }
3270
3271
	/**
3272
	 * Adds a discount to the invoice.
3273
	 *
3274
	 * @param array $discount An array of discount details. name, initial_discount, and recurring_discount are required. Include discount_code if the discount is from a discount code.
3275
	 * @since 1.0.19
3276
	 */
3277
	public function add_discount( $discount ) {
3278
3279
		$discounts = $this->get_discounts();
3280
		$discounts[ $discount['name'] ] = $discount;
3281
		$this->set_prop( 'discounts', $discounts );
3282
3283
	}
3284
3285
    /**
3286
	 * Retrieves a specific discount.
3287
	 *
3288
	 * @since 1.0.19
3289
	 * @return float
3290
	 */
3291
	public function get_discount( $discount = false ) {
3292
3293
		// Backwards compatibilty.
3294
		if ( empty( $discount ) ) {
3295
			return $this->get_total_discount();
3296
		}
3297
3298
        $discounts = $this->get_discounts();
3299
		return isset( $discounts[ $discount ] ) ? $discounts[ $discount ] : null;
3300
    }
3301
3302
    /**
3303
	 * Removes a specific discount.
3304
	 *
3305
	 * @since 1.0.19
3306
	 */
3307
	public function remove_discount( $discount ) {
3308
        $discounts = $this->get_discounts();
3309
        if ( isset( $discounts[ $discount ] ) ) {
3310
            unset( $discounts[ $discount ] );
3311
            $this->set_prop( 'discounts', $discounts );
3312
        }
3313
    }
3314
3315
    /**
3316
     * Adds a tax to the invoice.
3317
     *
3318
     * @param array $tax An array of tax details. name, initial_tax, and recurring_tax are required.
3319
     */
3320
    public function add_tax( $tax ) {
3321
        if ( $this->is_taxable() ) {
3322
3323
            $taxes                 = $this->get_taxes();
3324
			$taxes[ $tax['name'] ] = $tax;
3325
			$this->set_prop( 'taxes', $tax );
3326
3327
        }
3328
    }
3329
3330
    /**
3331
	 * Retrieves a specific tax.
3332
	 *
3333
	 * @since 1.0.19
3334
	 */
3335
	public function get_tax( $tax = null ) {
3336
3337
		// Backwards compatility.
3338
		if ( empty( $tax ) ) {
3339
			return $this->get_total_tax();
3340
		}
3341
3342
        $taxes = $this->get_taxes();
3343
		return isset( $taxes[ $tax ] ) ? $taxes[ $tax ] : null;
3344
    }
3345
3346
    /**
3347
	 * Removes a specific tax.
3348
	 *
3349
	 * @since 1.0.19
3350
	 */
3351
	public function remove_tax( $tax ) {
3352
        $taxes = $this->get_taxes();
3353
        if ( isset( $taxes[ $tax ] ) ) {
3354
            unset( $taxes[ $tax ] );
3355
            $this->set_prop( 'taxes', $taxes );
3356
        }
3357
    }
3358
3359
    /**
3360
	 * Recalculates the invoice subtotal.
3361
	 *
3362
	 * @since 1.0.19
3363
	 * @return float The recalculated subtotal
3364
	 */
3365
	public function recalculate_subtotal() {
3366
        $items     = $this->get_items();
3367
		$subtotal  = 0;
3368
		$recurring = 0;
3369
3370
        foreach ( $items as $item ) {
3371
			$subtotal  += $item->get_sub_total();
3372
			$recurring += $item->get_recurring_sub_total();
3373
        }
3374
3375
		$current = $this->is_renewal() ? $recurring : $subtotal;
3376
		$this->set_subtotal( $current );
3377
3378
		$this->totals['subtotal'] = array(
3379
			'initial'   => $subtotal,
3380
			'recurring' => $recurring,
3381
		);
3382
3383
        return $current;
3384
    }
3385
3386
    /**
3387
	 * Recalculates the invoice discount total.
3388
	 *
3389
	 * @since 1.0.19
3390
	 * @return float The recalculated discount
3391
	 */
3392
	public function recalculate_total_discount() {
3393
        $discounts = $this->get_discounts();
3394
		$discount  = 0;
3395
		$recurring = 0;
3396
3397
        foreach ( $discounts as $data ) {
3398
			$discount  += wpinv_sanitize_amount( $data['initial_discount'] );
3399
			$recurring += wpinv_sanitize_amount( $data['recurring_discount'] );
3400
		}
3401
3402
		$current = $this->is_renewal() ? $recurring : $discount;
3403
3404
		$this->set_total_discount( $current );
3405
3406
		$this->totals['discount'] = array(
3407
			'initial'   => $discount,
3408
			'recurring' => $recurring,
3409
		);
3410
3411
		return $current;
3412
3413
    }
3414
3415
    /**
3416
	 * Recalculates the invoice tax total.
3417
	 *
3418
	 * @since 1.0.19
3419
	 * @return float The recalculated tax
3420
	 */
3421
	public function recalculate_total_tax() {
3422
        $taxes     = $this->get_taxes();
3423
		$tax       = 0;
3424
		$recurring = 0;
3425
3426
        foreach ( $taxes as $data ) {
3427
			$tax       += wpinv_sanitize_amount( $data['initial_tax'] );
3428
			$recurring += wpinv_sanitize_amount( $data['recurring_tax'] );
3429
		}
3430
3431
		$current = $this->is_renewal() ? $recurring : $tax;
3432
		$this->set_total_tax( $current );
3433
3434
		$this->totals['tax'] = array(
3435
			'initial'   => $tax,
3436
			'recurring' => $recurring,
3437
		);
3438
3439
		return $current;
3440
3441
    }
3442
3443
    /**
3444
	 * Recalculates the invoice fees total.
3445
	 *
3446
	 * @since 1.0.19
3447
	 * @return float The recalculated fee
3448
	 */
3449
	public function recalculate_total_fees() {
3450
		$fees      = $this->get_fees();
3451
		$fee       = 0;
3452
		$recurring = 0;
3453
3454
        foreach ( $fees as $data ) {
3455
			$fee       += wpinv_sanitize_amount( $data['initial_fee'] );
3456
			$recurring += wpinv_sanitize_amount( $data['recurring_fee'] );
3457
		}
3458
3459
		$current = $this->is_renewal() ? $recurring : $fee;
3460
		$this->set_total_fees( $current );
3461
3462
		$this->totals['fee'] = array(
3463
			'initial'   => $fee,
3464
			'recurring' => $recurring,
3465
		);
3466
3467
        $this->set_total_fees( $fee );
3468
        return $current;
3469
    }
3470
3471
    /**
3472
	 * Recalculates the invoice total.
3473
	 *
3474
	 * @since 1.0.19
3475
     * @return float The invoice total
3476
	 */
3477
	public function recalculate_total() {
3478
        $this->recalculate_subtotal();
3479
        $this->recalculate_total_fees();
3480
        $this->recalculate_total_discount();
3481
        $this->recalculate_total_tax();
3482
		return $this->get_total();
3483
	}
3484
3485
	/**
3486
	 * @deprecated
3487
	 */
3488
    public function recalculate_totals( $temp = false ) {
3489
        $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

3489
        /** @scrutinizer ignore-deprecated */ $this->update_items( $temp );
Loading history...
3490
        $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

3490
        $this->/** @scrutinizer ignore-call */ 
3491
               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...
3491
        return $this;
3492
    }
3493
3494
    /**
3495
     * Convert this to an array.
3496
     */
3497
    public function array_convert() {
3498
        return $this->get_data();
3499
    }
3500
3501
    /**
3502
     * Adds a note to an invoice.
3503
     *
3504
     * @param string $note The note being added.
3505
	 * @return int|false The new note's ID on success, false on failure.
3506
     *
3507
     */
3508
    public function add_note( $note = '', $customer_type = false, $added_by_user = false, $system = false ) {
3509
3510
        // Bail if no note specified or this invoice is not yet saved.
3511
        if ( ! $note || $this->get_id() == 0 || ( ! is_user_logged_in() && ! $system ) ) {
3512
            return false;
3513
        }
3514
3515
		$author       = 'System';
3516
		$author_email = '[email protected]';
3517
3518
		// If this is an admin comment or it has been added by the user.
3519
		if ( is_user_logged_in() && ( ! $system || $added_by_user ) ) {
3520
			$user         = get_user_by( 'id', get_current_user_id() );
3521
            $author       = $user->display_name;
3522
            $author_email = $user->user_email;
3523
		}
3524
3525
		return getpaid_notes()->add_invoice_note( $this, $note, $author, $author_email, $customer_type );
3526
3527
	}
3528
3529
	/**
3530
     * Generates a unique key for the invoice.
3531
     */
3532
    public function generate_key( $string = '' ) {
3533
        $auth_key  = defined( 'AUTH_KEY' ) ? AUTH_KEY : '';
3534
        return strtolower(
3535
            $string . md5( $this->get_id() . date( 'Y-m-d H:i:s' ) . $auth_key . uniqid( 'wpinv', true ) )
3536
        );
3537
    }
3538
3539
    /**
3540
     * Generates a new number for the invoice.
3541
     */
3542
    public function generate_number() {
3543
        $number = $this->get_id();
3544
3545
        if ( wpinv_sequential_number_active( $this->get_post_type() ) ) {
3546
            $number = wpinv_get_next_invoice_number( $this->get_post_type() );
3547
        }
3548
3549
		return wpinv_format_invoice_number( $number, $this->get_post_type() );
3550
3551
	}
3552
3553
	/**
3554
	 * Handle the status transition.
3555
	 */
3556
	protected function status_transition() {
3557
		$status_transition = $this->status_transition;
3558
3559
		// Reset status transition variable.
3560
		$this->status_transition = false;
3561
3562
		if ( $status_transition ) {
3563
			try {
3564
3565
				// Fire a hook for the status change.
3566
				do_action( 'getpaid_invoice_status_' . $status_transition['to'], $this, $status_transition );
3567
3568
				// @deprecated this is deprecated and will be removed in the future.
3569
				do_action( 'wpinv_status_' . $status_transition['to'], $this->get_id(), $status_transition['from'] );
3570
3571
				if ( ! empty( $status_transition['from'] ) ) {
3572
3573
					/* translators: 1: old invoice status 2: new invoice status */
3574
					$transition_note = sprintf( __( 'Status changed from %1$s to %2$s.', 'invoicing' ), wpinv_status_nicename( $status_transition['from'] ), wpinv_status_nicename( $status_transition['to'] ) );
3575
3576
					// Fire another hook.
3577
					do_action( 'getpaid_invoice_status_' . $status_transition['from'] . '_to_' . $status_transition['to'], $this );
3578
					do_action( 'getpaid_invoice_status_changed', $this, $status_transition['from'], $status_transition['to'] );
3579
3580
					// @deprecated this is deprecated and will be removed in the future.
3581
					do_action( 'wpinv_status_' . $status_transition['from'] . '_to_' . $status_transition['to'], $this->get_id(), $status_transition['from'] );
3582
3583
					// Note the transition occurred.
3584
					$this->add_note( trim( $status_transition['note'] . ' ' . $transition_note ), 0, $status_transition['manual'] );
3585
3586
					// Work out if this was for a payment, and trigger a payment_status hook instead.
3587
					if (
3588
						in_array( $status_transition['from'], array( 'wpi-cancelled', 'wpi-pending', 'wpi-failed', 'wpi-refunded', 'wpi-onhold' ), true )
3589
						&& in_array( $status_transition['to'], array( 'publish', 'wpi-processing', 'wpi-renewal' ), true )
3590
					) {
3591
						do_action( 'getpaid_invoice_payment_status_changed', $this, $status_transition );
3592
					}
3593
3594
					// Work out if this was for a payment reversal, and trigger a payment_status_reversed hook instead.
3595
					if (
3596
						in_array( $status_transition['from'], array( 'publish', 'wpi-processing', 'wpi-renewal' ), true )
3597
						&& in_array( $status_transition['to'], array( 'wpi-cancelled', 'wpi-pending', 'wpi-failed', 'wpi-refunded', 'wpi-onhold' ), true )
3598
					) {
3599
						do_action( 'getpaid_invoice_payment_status_reversed', $this, $status_transition );
3600
					}
3601
				} else {
3602
					/* translators: %s: new invoice status */
3603
					$transition_note = sprintf( __( 'Status set to %s.', 'invoicing' ), wpinv_status_nicename( $status_transition['to'] ) );
3604
3605
					// Note the transition occurred.
3606
					$this->add_note( trim( $status_transition['note'] . ' ' . $transition_note ), 0, $status_transition['manual'] );
3607
3608
				}
3609
			} catch ( Exception $e ) {
3610
				$this->add_note( __( 'Error during status transition.', 'invoicing' ) . ' ' . $e->getMessage() );
3611
			}
3612
		}
3613
	}
3614
3615
	/**
3616
	 * Updates an invoice status.
3617
	 */
3618
	public function update_status( $new_status = false, $note = '', $manual = false ) {
3619
3620
		// Fires before updating a status.
3621
		do_action( 'wpinv_before_invoice_status_change', $this->get_id(), $new_status, $this->get_status( 'edit' ) );
3622
3623
		// Update the status.
3624
		$this->set_status( $new_status, $note, $manual );
3625
3626
		// Save the order.
3627
		return $this->save();
3628
3629
	}
3630
3631
	/**
3632
	 * @deprecated
3633
	 */
3634
	public function refresh_item_ids() {
3635
        $item_ids = implode( ',', array_unique( array_keys( $this->get_items() ) ) );
3636
        update_post_meta( $this->get_id(), '_wpinv_item_ids', $item_ids );
3637
	}
3638
3639
	/**
3640
	 * @deprecated
3641
	 */
3642
	public function update_items( $temp = false ) {
3643
3644
		$this->set_items( $this->get_items() );
3645
3646
		if ( ! $temp ) {
3647
			$this->save();
3648
		}
3649
3650
        return $this;
3651
	}
3652
3653
	/**
3654
	 * @deprecated
3655
	 */
3656
    public function validate_discount() {
3657
3658
        $discount_code = $this->get_discount_code();
3659
3660
        if ( empty( $discount_code ) ) {
3661
            return false;
3662
        }
3663
3664
        $discount = wpinv_get_discount_obj( $discount_code );
3665
3666
        // Ensure it is active.
3667
        return $discount->exists();
3668
3669
    }
3670
3671
	/**
3672
	 * Refunds an invoice.
3673
	 */
3674
    public function refund() {
3675
		$this->set_status( 'wpi-refunded' );
3676
        $this->save();
3677
	}
3678
3679
	/**
3680
	 * Marks an invoice as paid.
3681
	 * 
3682
	 * @param string $transaction_id
3683
	 */
3684
    public function mark_paid( $transaction_id = null, $note = '' ) {
3685
3686
		// Set the transaction id.
3687
		if ( empty( $transaction_id ) ) {
3688
			$transaction_id = $this->generate_key('trans_');
3689
		}
3690
3691
		if ( ! $this->get_transaction_id() ) {
3692
			$this->set_transaction_id( $transaction_id );
3693
		}
3694
3695
		if ( $this->is_paid() && 'wpi-processing' != $this->get_status() ) {
3696
			return $this->save();
3697
		}
3698
3699
		// Set the completed date.
3700
		$this->set_date_completed( current_time( 'mysql' ) );
3701
3702
		// Set the new status.
3703
		if ( $this->is_renewal() ) {
3704
3705
			$_note = sprintf(
3706
				__( 'Renewed via %s', 'invoicing' ),
3707
				$this->get_gateway_title() . empty( $note ) ? '' : " ($note)"
3708
			);
3709
3710
			if ( 'none' == $this->get_gateway() ) {
3711
				$_note = $note;
3712
			}
3713
3714
			$this->set_status( 'wpi-renewal', $_note );
3715
3716
		} else {
3717
3718
			$_note = sprintf(
3719
				__( 'Paid via %s', 'invoicing' ),
3720
				$this->get_gateway() . empty( $note ) ? '' : " ($note)"
3721
			);
3722
3723
			if ( 'none' == $this->get_gateway() ) {
3724
				$_note = $note;
3725
			}
3726
3727
			$this->set_status( 'publish',$_note );
3728
3729
		}
3730
3731
		// Set checkout mode.
3732
		$mode = wpinv_is_test_mode( $this->get_gateway() ) ? 'test' : 'live';
3733
		$this->set_mode( $mode );
3734
3735
		// Save the invoice.
3736
        $this->save();
3737
	}
3738
3739
3740
	/**
3741
	 * Save data to the database.
3742
	 *
3743
	 * @since 1.0.19
3744
	 * @return int invoice ID
3745
	 */
3746
	public function save() {
3747
		$this->maybe_set_date_paid();
3748
		$this->maybe_set_key();
3749
		parent::save();
3750
		$this->clear_cache();
3751
		$this->status_transition();
3752
		return $this->get_id();
3753
	}
3754
3755
	/**
3756
     * Clears the subscription's cache.
3757
     */
3758
    public function clear_cache() {
3759
		wp_cache_delete( $this->get_key(), 'getpaid_invoice_keys_to_invoice_ids' );
3760
		wp_cache_delete( $this->get_number(), 'getpaid_invoice_numbers_to_invoice_ids' );
3761
		wp_cache_delete( $this->get_transaction_id(), 'getpaid_invoice_transaction_ids_to_invoice_ids' );
3762
	}
3763
3764
}
3765