Completed
Push — master ( 3ad42c...16627f )
by Brian
25s queued 14s
created

WPInv_Invoice::is_held()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
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
		'is_viewed'            => false,
84
		'email_cc'             => '',
85
		'template'             => 'quantity', // hours, amount only
86
    );
87
88
    /**
89
	 * Stores meta in cache for future reads.
90
	 *
91
	 * A group must be set to to enable caching.
92
	 *
93
	 * @var string
94
	 */
95
	protected $cache_group = 'getpaid_invoices';
96
97
    /**
98
     * Stores a reference to the original WP_Post object
99
     *
100
     * @var WP_Post
101
     */
102
    protected $post = null;
103
104
    /**
105
     * Stores a reference to the recurring item id instead of looping through the items.
106
     *
107
     * @var int
108
     */
109
	protected $recurring_item = null;
110
111
	/**
112
     * Stores an array of item totals.
113
	 *
114
	 * e.g $totals['discount'] = array(
115
	 * 		'initial'   => 10,
116
	 * 		'recurring' => 10,
117
	 * )
118
     *
119
     * @var array
120
     */
121
	protected $totals = array();
122
123
	/**
124
	 * Stores the status transition information.
125
	 *
126
	 * @since 1.0.19
127
	 * @var bool
128
	 */
129
	protected $status_transition = false;
130
131
    /**
132
	 * Get the invoice if ID is passed, otherwise the invoice is new and empty.
133
	 *
134
	 * @param  int|string|object|WPInv_Invoice|WPInv_Legacy_Invoice|WP_Post $invoice Invoice id, key, transaction id, number or object to read.
135
	 */
136
    public function __construct( $invoice = false ) {
137
138
        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

138
        parent::__construct( /** @scrutinizer ignore-type */ $invoice );
Loading history...
139
140
		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

140
		if ( ! empty( $invoice ) && is_numeric( $invoice ) && getpaid_is_invoice_post_type( get_post_type( /** @scrutinizer ignore-type */ $invoice ) ) ) {
Loading history...
141
			$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

141
			$this->set_id( /** @scrutinizer ignore-type */ $invoice );
Loading history...
142
		} elseif ( $invoice instanceof self ) {
143
			$this->set_id( $invoice->get_id() );
144
		} elseif ( ! empty( $invoice->ID ) ) {
145
			$this->set_id( $invoice->ID );
146
		} elseif ( is_array( $invoice ) ) {
0 ignored issues
show
introduced by
The condition is_array($invoice) is always false.
Loading history...
147
			$this->set_props( $invoice );
148
149
			if ( isset( $invoice['ID'] ) ) {
150
				$this->set_id( $invoice['ID'] );
151
			}
152
153
		} 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

153
		} elseif ( is_scalar( $invoice ) && $invoice_id = self::get_invoice_id_by_field( /** @scrutinizer ignore-type */ $invoice, 'key' ) ) {
Loading history...
154
			$this->set_id( $invoice_id );
155
		} elseif ( is_scalar( $invoice ) && $invoice_id = self::get_invoice_id_by_field( $invoice, 'number' ) ) {
156
			$this->set_id( $invoice_id );
157
		} elseif ( is_scalar( $invoice ) && $invoice_id = self::get_invoice_id_by_field( $invoice, 'transaction_id' ) ) {
158
			$this->set_id( $invoice_id );
159
		}else {
160
			$this->set_object_read( true );
161
		}
162
163
        // Load the datastore.
164
		$this->data_store = GetPaid_Data_Store::load( $this->data_store_name );
165
166
		if ( $this->get_id() > 0 ) {
167
            $this->post = get_post( $this->get_id() );
168
            $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...
169
			$this->data_store->read( $this );
170
        }
171
172
    }
173
174
    /**
175
	 * Given an invoice key/number, it returns its id.
176
	 *
177
	 *
178
	 * @static
179
	 * @param string $value The invoice key or number
180
	 * @param string $field Either key, transaction_id or number.
181
	 * @since 1.0.15
182
	 * @return int
183
	 */
184
	public static function get_invoice_id_by_field( $value, $field = 'key' ) {
185
        global $wpdb;
186
187
		// Trim the value.
188
		$value = trim( $value );
189
190
		if ( empty( $value ) ) {
191
			return 0;
192
		}
193
194
        // Valid fields.
195
        $fields = array( 'key', 'number', 'transaction_id' );
196
197
		// Ensure a field has been passed.
198
		if ( empty( $field ) || ! in_array( $field, $fields ) ) {
199
			return 0;
200
		}
201
202
		// Maybe retrieve from the cache.
203
		$invoice_id   = wp_cache_get( $value, "getpaid_invoice_{$field}s_to_invoice_ids" );
204
		if ( ! empty( $invoice_id ) ) {
205
			return $invoice_id;
206
		}
207
208
        // Fetch from the db.
209
        $table       = $wpdb->prefix . 'getpaid_invoices';
210
        $invoice_id  = $wpdb->get_var(
211
            $wpdb->prepare( "SELECT `post_id` FROM $table WHERE `$field`=%s LIMIT 1", $value )
212
        );
213
214
		if ( empty( $invoice_id ) ) {
215
			return 0;
216
		}
217
218
		// Update the cache with our data
219
		wp_cache_set( $value, $invoice_id, "getpaid_invoice_{$field}s_to_invoice_ids" );
220
221
		return $invoice_id;
222
    }
223
224
    /**
225
     * Checks if an invoice key is set.
226
     */
227
    public function _isset( $key ) {
228
        return isset( $this->data[$key] ) || method_exists( $this, "get_$key" );
229
    }
230
231
    /*
232
	|--------------------------------------------------------------------------
233
	| CRUD methods
234
	|--------------------------------------------------------------------------
235
	|
236
	| Methods which create, read, update and delete items from the database.
237
	|
238
    */
239
240
    /*
241
	|--------------------------------------------------------------------------
242
	| Getters
243
	|--------------------------------------------------------------------------
244
    */
245
246
    /**
247
	 * Get parent invoice ID.
248
	 *
249
	 * @since 1.0.19
250
	 * @param  string $context View or edit context.
251
	 * @return int
252
	 */
253
	public function get_parent_id( $context = 'view' ) {
254
		return (int) $this->get_prop( 'parent_id', $context );
255
    }
256
257
    /**
258
	 * Get parent invoice.
259
	 *
260
	 * @since 1.0.19
261
	 * @return WPInv_Invoice
262
	 */
263
    public function get_parent_payment() {
264
        return new WPInv_Invoice( $this->get_parent_id() );
265
    }
266
267
    /**
268
	 * Alias for self::get_parent_payment().
269
	 *
270
	 * @since 1.0.19
271
	 * @return WPInv_Invoice
272
	 */
273
    public function get_parent() {
274
        return $this->get_parent_payment();
275
    }
276
277
    /**
278
	 * Get invoice status.
279
	 *
280
	 * @since 1.0.19
281
	 * @param  string $context View or edit context.
282
	 * @return string
283
	 */
284
	public function get_status( $context = 'view' ) {
285
		return $this->get_prop( 'status', $context );
286
	}
287
	
288
	/**
289
	 * Retrieves an array of possible invoice statuses.
290
	 *
291
	 * @since 1.0.19
292
	 * @return array
293
	 */
294
	public function get_all_statuses() {
295
		
296
		$statuses = wpinv_get_invoice_statuses( true, true, $this );
297
298
		// For backwards compatibility.
299
		if ( $this->is_quote() && class_exists( 'Wpinv_Quotes_Shared' ) ) {
300
            $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...
301
		}
302
303
		return $statuses;
304
    }
305
306
    /**
307
	 * Get invoice status nice name.
308
	 *
309
	 * @since 1.0.19
310
	 * @return string
311
	 */
312
    public function get_status_nicename() {
313
		$statuses = $this->get_all_statuses();
314
315
        $status = isset( $statuses[ $this->get_status() ] ) ? $statuses[ $this->get_status() ] : $this->get_status();
316
317
        return apply_filters( 'wpinv_get_invoice_status_nicename', $status, $this );
318
    }
319
320
    /**
321
	 * Get plugin version when the invoice was created.
322
	 *
323
	 * @since 1.0.19
324
	 * @param  string $context View or edit context.
325
	 * @return string
326
	 */
327
	public function get_version( $context = 'view' ) {
328
		return $this->get_prop( 'version', $context );
329
	}
330
331
	/**
332
	 * @deprecated
333
	 */
334
	public function get_invoice_date( $formatted = true ) {
335
        $date_completed = $this->get_date_completed();
336
        $invoice_date   = $date_completed != '0000-00-00 00:00:00' ? $date_completed : '';
337
338
        if ( $invoice_date == '' ) {
339
            $date_created   = $this->get_date_created();
340
            $invoice_date   = $date_created != '0000-00-00 00:00:00' ? $date_created : '';
341
        }
342
343
        if ( $formatted && $invoice_date ) {
344
            $invoice_date   = date_i18n( get_option( 'date_format' ), strtotime( $invoice_date ) );
0 ignored issues
show
Bug introduced by
It seems like get_option('date_format') can also be of type false; however, parameter $format of date_i18n() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

344
            $invoice_date   = date_i18n( /** @scrutinizer ignore-type */ get_option( 'date_format' ), strtotime( $invoice_date ) );
Loading history...
345
        }
346
347
        return apply_filters( 'wpinv_get_invoice_date', $invoice_date, $formatted, $this->get_id(), $this );
348
    }
349
350
    /**
351
	 * Get date when the invoice was created.
352
	 *
353
	 * @since 1.0.19
354
	 * @param  string $context View or edit context.
355
	 * @return string
356
	 */
357
	public function get_date_created( $context = 'view' ) {
358
		return $this->get_prop( 'date_created', $context );
359
	}
360
	
361
	/**
362
	 * Alias for self::get_date_created().
363
	 *
364
	 * @since 1.0.19
365
	 * @param  string $context View or edit context.
366
	 * @return string
367
	 */
368
	public function get_created_date( $context = 'view' ) {
369
		return $this->get_date_created( $context );
370
    }
371
372
    /**
373
	 * Get GMT date when the invoice was created.
374
	 *
375
	 * @since 1.0.19
376
	 * @param  string $context View or edit context.
377
	 * @return string
378
	 */
379
	public function get_date_created_gmt( $context = 'view' ) {
380
        $date = $this->get_date_created( $context );
381
382
        if ( $date ) {
383
            $date = get_gmt_from_date( $date );
384
        }
385
		return $date;
386
    }
387
388
    /**
389
	 * Get date when the invoice was last modified.
390
	 *
391
	 * @since 1.0.19
392
	 * @param  string $context View or edit context.
393
	 * @return string
394
	 */
395
	public function get_date_modified( $context = 'view' ) {
396
		return $this->get_prop( 'date_modified', $context );
397
	}
398
399
	/**
400
	 * Alias for self::get_date_modified().
401
	 *
402
	 * @since 1.0.19
403
	 * @param  string $context View or edit context.
404
	 * @return string
405
	 */
406
	public function get_modified_date( $context = 'view' ) {
407
		return $this->get_date_modified( $context );
408
    }
409
410
    /**
411
	 * Get GMT date when the invoice was last modified.
412
	 *
413
	 * @since 1.0.19
414
	 * @param  string $context View or edit context.
415
	 * @return string
416
	 */
417
	public function get_date_modified_gmt( $context = 'view' ) {
418
        $date = $this->get_date_modified( $context );
419
420
        if ( $date ) {
421
            $date = get_gmt_from_date( $date );
422
        }
423
		return $date;
424
    }
425
426
    /**
427
	 * Get the invoice due date.
428
	 *
429
	 * @since 1.0.19
430
	 * @param  string $context View or edit context.
431
	 * @return string
432
	 */
433
	public function get_due_date( $context = 'view' ) {
434
		return $this->get_prop( 'due_date', $context );
435
    }
436
437
    /**
438
	 * Alias for self::get_due_date().
439
	 *
440
	 * @since 1.0.19
441
	 * @param  string $context View or edit context.
442
	 * @return string
443
	 */
444
	public function get_date_due( $context = 'view' ) {
445
		return $this->get_due_date( $context );
446
    }
447
448
    /**
449
	 * Get the invoice GMT due date.
450
	 *
451
	 * @since 1.0.19
452
	 * @param  string $context View or edit context.
453
	 * @return string
454
	 */
455
	public function get_due_date_gmt( $context = 'view' ) {
456
        $date = $this->get_due_date( $context );
457
458
        if ( $date ) {
459
            $date = get_gmt_from_date( $date );
460
        }
461
		return $date;
462
    }
463
464
    /**
465
	 * Alias for self::get_due_date_gmt().
466
	 *
467
	 * @since 1.0.19
468
	 * @param  string $context View or edit context.
469
	 * @return string
470
	 */
471
	public function get_gmt_date_due( $context = 'view' ) {
472
		return $this->get_due_date_gmt( $context );
473
    }
474
475
    /**
476
	 * Get date when the invoice was completed.
477
	 *
478
	 * @since 1.0.19
479
	 * @param  string $context View or edit context.
480
	 * @return string
481
	 */
482
	public function get_completed_date( $context = 'view' ) {
483
		return $this->get_prop( 'completed_date', $context );
484
    }
485
486
    /**
487
	 * Alias for self::get_completed_date().
488
	 *
489
	 * @since 1.0.19
490
	 * @param  string $context View or edit context.
491
	 * @return string
492
	 */
493
	public function get_date_completed( $context = 'view' ) {
494
		return $this->get_completed_date( $context );
495
    }
496
497
    /**
498
	 * Get GMT date when the invoice was was completed.
499
	 *
500
	 * @since 1.0.19
501
	 * @param  string $context View or edit context.
502
	 * @return string
503
	 */
504
	public function get_completed_date_gmt( $context = 'view' ) {
505
        $date = $this->get_completed_date( $context );
506
507
        if ( $date ) {
508
            $date = get_gmt_from_date( $date );
509
        }
510
		return $date;
511
    }
512
513
    /**
514
	 * Alias for self::get_completed_date_gmt().
515
	 *
516
	 * @since 1.0.19
517
	 * @param  string $context View or edit context.
518
	 * @return string
519
	 */
520
	public function get_gmt_completed_date( $context = 'view' ) {
521
		return $this->get_completed_date_gmt( $context );
522
    }
523
524
    /**
525
	 * Get the invoice number.
526
	 *
527
	 * @since 1.0.19
528
	 * @param  string $context View or edit context.
529
	 * @return string
530
	 */
531
	public function get_number( $context = 'view' ) {
532
        $number = $this->get_prop( 'number', $context );
533
534
        if ( empty( $number ) ) {
535
            $number = $this->generate_number();
536
            $this->set_number( $number );
537
        }
538
539
		return $number;
540
    }
541
542
    /**
543
	 * Get the invoice key.
544
	 *
545
	 * @since 1.0.19
546
	 * @param  string $context View or edit context.
547
	 * @return string
548
	 */
549
	public function get_key( $context = 'view' ) {
550
        $key = $this->get_prop( 'key', $context );
551
552
        if ( empty( $key ) ) {
553
            $key = $this->generate_key( $this->get_type() . '_' );
554
            $this->set_key( $key );
555
        }
556
557
		return $key;
558
    }
559
560
    /**
561
	 * Get the invoice type.
562
	 *
563
	 * @since 1.0.19
564
	 * @param  string $context View or edit context.
565
	 * @return string
566
	 */
567
	public function get_type( $context = 'view' ) {
568
        return $this->get_prop( 'type', $context );
569
	}
570
571
	/**
572
	 * @deprecated
573
	 */
574
	public function get_invoice_quote_type( $post_id ) {
575
        if ( empty( $post_id ) ) {
576
            return '';
577
        }
578
579
        $type = get_post_type( $post_id );
580
581
        if ( 'wpi_invoice' === $type ) {
582
            $post_type = __('Invoice', 'invoicing');
583
        } else{
584
            $post_type = __('Quote', 'invoicing');
585
        }
586
587
        return apply_filters('get_invoice_type_label', $post_type, $post_id);
588
    }
589
590
    /**
591
	 * Get the invoice post type.
592
	 *
593
	 * @since 1.0.19
594
	 * @param  string $context View or edit context.
595
	 * @return string
596
	 */
597
	public function get_post_type( $context = 'view' ) {
598
        return $this->get_prop( 'post_type', $context );
599
    }
600
601
    /**
602
	 * Get the invoice mode.
603
	 *
604
	 * @since 1.0.19
605
	 * @param  string $context View or edit context.
606
	 * @return string
607
	 */
608
	public function get_mode( $context = 'view' ) {
609
        return $this->get_prop( 'mode', $context );
610
    }
611
612
    /**
613
	 * Get the invoice path.
614
	 *
615
	 * @since 1.0.19
616
	 * @param  string $context View or edit context.
617
	 * @return string
618
	 */
619
	public function get_path( $context = 'view' ) {
620
        $path = $this->get_prop( 'path', $context );
621
622
        if ( empty( $path ) ) {
623
            $prefix = apply_filters( 'wpinv_post_name_prefix', 'inv-', $this->post_type );
0 ignored issues
show
Bug Best Practice introduced by
The property post_type does not exist on WPInv_Invoice. Since you implemented __get, consider adding a @property annotation.
Loading history...
624
            $path   = sanitize_title( $prefix . $this->get_id() );
625
        }
626
627
		return $path;
628
    }
629
630
    /**
631
	 * Get the invoice name/title.
632
	 *
633
	 * @since 1.0.19
634
	 * @param  string $context View or edit context.
635
	 * @return string
636
	 */
637
	public function get_name( $context = 'view' ) {
638
        $name = $this->get_prop( 'title', $context );
639
640
		return empty( $name ) ? $this->get_number( $context ) : $name;
641
    }
642
643
    /**
644
	 * Alias of self::get_name().
645
	 *
646
	 * @since 1.0.19
647
	 * @param  string $context View or edit context.
648
	 * @return string
649
	 */
650
	public function get_title( $context = 'view' ) {
651
		return $this->get_name( $context );
652
    }
653
654
    /**
655
	 * Get the invoice description.
656
	 *
657
	 * @since 1.0.19
658
	 * @param  string $context View or edit context.
659
	 * @return string
660
	 */
661
	public function get_description( $context = 'view' ) {
662
		return $this->get_prop( 'description', $context );
663
    }
664
665
    /**
666
	 * Alias of self::get_description().
667
	 *
668
	 * @since 1.0.19
669
	 * @param  string $context View or edit context.
670
	 * @return string
671
	 */
672
	public function get_excerpt( $context = 'view' ) {
673
		return $this->get_description( $context );
674
    }
675
676
    /**
677
	 * Alias of self::get_description().
678
	 *
679
	 * @since 1.0.19
680
	 * @param  string $context View or edit context.
681
	 * @return string
682
	 */
683
	public function get_summary( $context = 'view' ) {
684
		return $this->get_description( $context );
685
    }
686
687
    /**
688
	 * Returns the user info.
689
	 *
690
	 * @since 1.0.19
691
     * @param  string $context View or edit context.
692
	 * @return array
693
	 */
694
    public function get_user_info( $context = 'view' ) {
695
696
        $user_info = array(
697
            'user_id'    => $this->get_user_id( $context ),
698
            'email'      => $this->get_email( $context ),
699
            'first_name' => $this->get_first_name( $context ),
700
            'last_name'  => $this->get_last_name( $context ),
701
            'address'    => $this->get_address( $context ),
702
            'phone'      => $this->get_phone( $context ),
703
            'city'       => $this->get_city( $context ),
704
            'country'    => $this->get_country( $context ),
705
            'state'      => $this->get_state( $context ),
706
            'zip'        => $this->get_zip( $context ),
707
            'company'    => $this->get_company( $context ),
708
            'vat_number' => $this->get_vat_number( $context ),
709
            'discount'   => $this->get_discount_code( $context ),
710
		);
711
712
		return apply_filters( 'wpinv_user_info', $user_info, $this->get_id(), $this );
713
714
    }
715
716
    /**
717
	 * Get the customer id.
718
	 *
719
	 * @since 1.0.19
720
	 * @param  string $context View or edit context.
721
	 * @return int
722
	 */
723
	public function get_author( $context = 'view' ) {
724
		return (int) $this->get_prop( 'author', $context );
725
    }
726
727
    /**
728
	 * Alias of self::get_author().
729
	 *
730
	 * @since 1.0.19
731
	 * @param  string $context View or edit context.
732
	 * @return int
733
	 */
734
	public function get_user_id( $context = 'view' ) {
735
		return $this->get_author( $context );
736
    }
737
738
     /**
739
	 * Alias of self::get_author().
740
	 *
741
	 * @since 1.0.19
742
	 * @param  string $context View or edit context.
743
	 * @return int
744
	 */
745
	public function get_customer_id( $context = 'view' ) {
746
		return $this->get_author( $context );
747
    }
748
749
    /**
750
	 * Get the customer's ip.
751
	 *
752
	 * @since 1.0.19
753
	 * @param  string $context View or edit context.
754
	 * @return string
755
	 */
756
	public function get_ip( $context = 'view' ) {
757
		return $this->get_prop( 'user_ip', $context );
758
    }
759
760
    /**
761
	 * Alias of self::get_ip().
762
	 *
763
	 * @since 1.0.19
764
	 * @param  string $context View or edit context.
765
	 * @return string
766
	 */
767
	public function get_user_ip( $context = 'view' ) {
768
		return $this->get_ip( $context );
769
    }
770
771
     /**
772
	 * Alias of self::get_ip().
773
	 *
774
	 * @since 1.0.19
775
	 * @param  string $context View or edit context.
776
	 * @return string
777
	 */
778
	public function get_customer_ip( $context = 'view' ) {
779
		return $this->get_ip( $context );
780
    }
781
782
    /**
783
	 * Get the customer's first name.
784
	 *
785
	 * @since 1.0.19
786
	 * @param  string $context View or edit context.
787
	 * @return string
788
	 */
789
	public function get_first_name( $context = 'view' ) {
790
		return $this->get_prop( 'first_name', $context );
791
    }
792
793
    /**
794
	 * Alias of self::get_first_name().
795
	 *
796
	 * @since 1.0.19
797
	 * @param  string $context View or edit context.
798
	 * @return int
799
	 */
800
	public function get_user_first_name( $context = 'view' ) {
801
		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...
802
    }
803
804
     /**
805
	 * Alias of self::get_first_name().
806
	 *
807
	 * @since 1.0.19
808
	 * @param  string $context View or edit context.
809
	 * @return int
810
	 */
811
	public function get_customer_first_name( $context = 'view' ) {
812
		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...
813
    }
814
815
    /**
816
	 * Get the customer's last name.
817
	 *
818
	 * @since 1.0.19
819
	 * @param  string $context View or edit context.
820
	 * @return string
821
	 */
822
	public function get_last_name( $context = 'view' ) {
823
		return $this->get_prop( 'last_name', $context );
824
    }
825
826
    /**
827
	 * Alias of self::get_last_name().
828
	 *
829
	 * @since 1.0.19
830
	 * @param  string $context View or edit context.
831
	 * @return int
832
	 */
833
	public function get_user_last_name( $context = 'view' ) {
834
		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...
835
    }
836
837
    /**
838
	 * Alias of self::get_last_name().
839
	 *
840
	 * @since 1.0.19
841
	 * @param  string $context View or edit context.
842
	 * @return int
843
	 */
844
	public function get_customer_last_name( $context = 'view' ) {
845
		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...
846
    }
847
848
    /**
849
	 * Get the customer's full name.
850
	 *
851
	 * @since 1.0.19
852
	 * @param  string $context View or edit context.
853
	 * @return string
854
	 */
855
	public function get_full_name( $context = 'view' ) {
856
		return trim( $this->get_first_name( $context ) . ' ' . $this->get_last_name( $context ) );
857
    }
858
859
    /**
860
	 * Alias of self::get_full_name().
861
	 *
862
	 * @since 1.0.19
863
	 * @param  string $context View or edit context.
864
	 * @return int
865
	 */
866
	public function get_user_full_name( $context = 'view' ) {
867
		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...
868
    }
869
870
    /**
871
	 * Alias of self::get_full_name().
872
	 *
873
	 * @since 1.0.19
874
	 * @param  string $context View or edit context.
875
	 * @return int
876
	 */
877
	public function get_customer_full_name( $context = 'view' ) {
878
		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...
879
    }
880
881
    /**
882
	 * Get the customer's phone number.
883
	 *
884
	 * @since 1.0.19
885
	 * @param  string $context View or edit context.
886
	 * @return string
887
	 */
888
	public function get_phone( $context = 'view' ) {
889
		return $this->get_prop( 'phone', $context );
890
    }
891
892
    /**
893
	 * Alias of self::get_phone().
894
	 *
895
	 * @since 1.0.19
896
	 * @param  string $context View or edit context.
897
	 * @return int
898
	 */
899
	public function get_phone_number( $context = 'view' ) {
900
		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...
901
    }
902
903
    /**
904
	 * Alias of self::get_phone().
905
	 *
906
	 * @since 1.0.19
907
	 * @param  string $context View or edit context.
908
	 * @return int
909
	 */
910
	public function get_user_phone( $context = 'view' ) {
911
		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...
912
    }
913
914
    /**
915
	 * Alias of self::get_phone().
916
	 *
917
	 * @since 1.0.19
918
	 * @param  string $context View or edit context.
919
	 * @return int
920
	 */
921
	public function get_customer_phone( $context = 'view' ) {
922
		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...
923
    }
924
925
    /**
926
	 * Get the customer's email address.
927
	 *
928
	 * @since 1.0.19
929
	 * @param  string $context View or edit context.
930
	 * @return string
931
	 */
932
	public function get_email( $context = 'view' ) {
933
		return $this->get_prop( 'email', $context );
934
    }
935
936
    /**
937
	 * Alias of self::get_email().
938
	 *
939
	 * @since 1.0.19
940
	 * @param  string $context View or edit context.
941
	 * @return string
942
	 */
943
	public function get_email_address( $context = 'view' ) {
944
		return $this->get_email( $context );
945
    }
946
947
    /**
948
	 * Alias of self::get_email().
949
	 *
950
	 * @since 1.0.19
951
	 * @param  string $context View or edit context.
952
	 * @return int
953
	 */
954
	public function get_user_email( $context = 'view' ) {
955
		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...
956
    }
957
958
    /**
959
	 * Alias of self::get_email().
960
	 *
961
	 * @since 1.0.19
962
	 * @param  string $context View or edit context.
963
	 * @return int
964
	 */
965
	public function get_customer_email( $context = 'view' ) {
966
		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...
967
    }
968
969
    /**
970
	 * Get the customer's country.
971
	 *
972
	 * @since 1.0.19
973
	 * @param  string $context View or edit context.
974
	 * @return string
975
	 */
976
	public function get_country( $context = 'view' ) {
977
		$country = $this->get_prop( 'country', $context );
978
		return empty( $country ) ? wpinv_get_default_country() : $country;
979
    }
980
981
    /**
982
	 * Alias of self::get_country().
983
	 *
984
	 * @since 1.0.19
985
	 * @param  string $context View or edit context.
986
	 * @return int
987
	 */
988
	public function get_user_country( $context = 'view' ) {
989
		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...
990
    }
991
992
    /**
993
	 * Alias of self::get_country().
994
	 *
995
	 * @since 1.0.19
996
	 * @param  string $context View or edit context.
997
	 * @return int
998
	 */
999
	public function get_customer_country( $context = 'view' ) {
1000
		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...
1001
    }
1002
1003
    /**
1004
	 * Get the customer's state.
1005
	 *
1006
	 * @since 1.0.19
1007
	 * @param  string $context View or edit context.
1008
	 * @return string
1009
	 */
1010
	public function get_state( $context = 'view' ) {
1011
		$state = $this->get_prop( 'state', $context );
1012
		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...
1013
    }
1014
1015
    /**
1016
	 * Alias of self::get_state().
1017
	 *
1018
	 * @since 1.0.19
1019
	 * @param  string $context View or edit context.
1020
	 * @return int
1021
	 */
1022
	public function get_user_state( $context = 'view' ) {
1023
		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...
1024
    }
1025
1026
    /**
1027
	 * Alias of self::get_state().
1028
	 *
1029
	 * @since 1.0.19
1030
	 * @param  string $context View or edit context.
1031
	 * @return int
1032
	 */
1033
	public function get_customer_state( $context = 'view' ) {
1034
		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...
1035
    }
1036
1037
    /**
1038
	 * Get the customer's city.
1039
	 *
1040
	 * @since 1.0.19
1041
	 * @param  string $context View or edit context.
1042
	 * @return string
1043
	 */
1044
	public function get_city( $context = 'view' ) {
1045
		return $this->get_prop( 'city', $context );
1046
    }
1047
1048
    /**
1049
	 * Alias of self::get_city().
1050
	 *
1051
	 * @since 1.0.19
1052
	 * @param  string $context View or edit context.
1053
	 * @return string
1054
	 */
1055
	public function get_user_city( $context = 'view' ) {
1056
		return $this->get_city( $context );
1057
    }
1058
1059
    /**
1060
	 * Alias of self::get_city().
1061
	 *
1062
	 * @since 1.0.19
1063
	 * @param  string $context View or edit context.
1064
	 * @return string
1065
	 */
1066
	public function get_customer_city( $context = 'view' ) {
1067
		return $this->get_city( $context );
1068
    }
1069
1070
    /**
1071
	 * Get the customer's zip.
1072
	 *
1073
	 * @since 1.0.19
1074
	 * @param  string $context View or edit context.
1075
	 * @return string
1076
	 */
1077
	public function get_zip( $context = 'view' ) {
1078
		return $this->get_prop( 'zip', $context );
1079
    }
1080
1081
    /**
1082
	 * Alias of self::get_zip().
1083
	 *
1084
	 * @since 1.0.19
1085
	 * @param  string $context View or edit context.
1086
	 * @return string
1087
	 */
1088
	public function get_user_zip( $context = 'view' ) {
1089
		return $this->get_zip( $context );
1090
    }
1091
1092
    /**
1093
	 * Alias of self::get_zip().
1094
	 *
1095
	 * @since 1.0.19
1096
	 * @param  string $context View or edit context.
1097
	 * @return string
1098
	 */
1099
	public function get_customer_zip( $context = 'view' ) {
1100
		return $this->get_zip( $context );
1101
    }
1102
1103
    /**
1104
	 * Get the customer's company.
1105
	 *
1106
	 * @since 1.0.19
1107
	 * @param  string $context View or edit context.
1108
	 * @return string
1109
	 */
1110
	public function get_company( $context = 'view' ) {
1111
		return $this->get_prop( 'company', $context );
1112
    }
1113
1114
    /**
1115
	 * Alias of self::get_company().
1116
	 *
1117
	 * @since 1.0.19
1118
	 * @param  string $context View or edit context.
1119
	 * @return string
1120
	 */
1121
	public function get_user_company( $context = 'view' ) {
1122
		return $this->get_company( $context );
1123
    }
1124
1125
    /**
1126
	 * Alias of self::get_company().
1127
	 *
1128
	 * @since 1.0.19
1129
	 * @param  string $context View or edit context.
1130
	 * @return string
1131
	 */
1132
	public function get_customer_company( $context = 'view' ) {
1133
		return $this->get_company( $context );
1134
    }
1135
1136
    /**
1137
	 * Get the customer's vat number.
1138
	 *
1139
	 * @since 1.0.19
1140
	 * @param  string $context View or edit context.
1141
	 * @return string
1142
	 */
1143
	public function get_vat_number( $context = 'view' ) {
1144
		return $this->get_prop( 'vat_number', $context );
1145
    }
1146
1147
    /**
1148
	 * Alias of self::get_vat_number().
1149
	 *
1150
	 * @since 1.0.19
1151
	 * @param  string $context View or edit context.
1152
	 * @return string
1153
	 */
1154
	public function get_user_vat_number( $context = 'view' ) {
1155
		return $this->get_vat_number( $context );
1156
    }
1157
1158
    /**
1159
	 * Alias of self::get_vat_number().
1160
	 *
1161
	 * @since 1.0.19
1162
	 * @param  string $context View or edit context.
1163
	 * @return string
1164
	 */
1165
	public function get_customer_vat_number( $context = 'view' ) {
1166
		return $this->get_vat_number( $context );
1167
    }
1168
1169
    /**
1170
	 * Get the customer's vat rate.
1171
	 *
1172
	 * @since 1.0.19
1173
	 * @param  string $context View or edit context.
1174
	 * @return string
1175
	 */
1176
	public function get_vat_rate( $context = 'view' ) {
1177
		return $this->get_prop( 'vat_rate', $context );
1178
    }
1179
1180
    /**
1181
	 * Alias of self::get_vat_rate().
1182
	 *
1183
	 * @since 1.0.19
1184
	 * @param  string $context View or edit context.
1185
	 * @return string
1186
	 */
1187
	public function get_user_vat_rate( $context = 'view' ) {
1188
		return $this->get_vat_rate( $context );
1189
    }
1190
1191
    /**
1192
	 * Alias of self::get_vat_rate().
1193
	 *
1194
	 * @since 1.0.19
1195
	 * @param  string $context View or edit context.
1196
	 * @return string
1197
	 */
1198
	public function get_customer_vat_rate( $context = 'view' ) {
1199
		return $this->get_vat_rate( $context );
1200
    }
1201
1202
    /**
1203
	 * Get the customer's address.
1204
	 *
1205
	 * @since 1.0.19
1206
	 * @param  string $context View or edit context.
1207
	 * @return string
1208
	 */
1209
	public function get_address( $context = 'view' ) {
1210
		return $this->get_prop( 'address', $context );
1211
    }
1212
1213
    /**
1214
	 * Alias of self::get_address().
1215
	 *
1216
	 * @since 1.0.19
1217
	 * @param  string $context View or edit context.
1218
	 * @return string
1219
	 */
1220
	public function get_user_address( $context = 'view' ) {
1221
		return $this->get_address( $context );
1222
    }
1223
1224
    /**
1225
	 * Alias of self::get_address().
1226
	 *
1227
	 * @since 1.0.19
1228
	 * @param  string $context View or edit context.
1229
	 * @return string
1230
	 */
1231
	public function get_customer_address( $context = 'view' ) {
1232
		return $this->get_address( $context );
1233
    }
1234
1235
    /**
1236
	 * Get whether the customer has viewed the invoice or not.
1237
	 *
1238
	 * @since 1.0.19
1239
	 * @param  string $context View or edit context.
1240
	 * @return bool
1241
	 */
1242
	public function get_is_viewed( $context = 'view' ) {
1243
		return (bool) $this->get_prop( 'is_viewed', $context );
1244
	}
1245
1246
	/**
1247
	 * Get other recipients for invoice communications.
1248
	 *
1249
	 * @since 1.0.19
1250
	 * @param  string $context View or edit context.
1251
	 * @return bool
1252
	 */
1253
	public function get_email_cc( $context = 'view' ) {
1254
		return $this->get_prop( 'email_cc', $context );
1255
	}
1256
1257
	/**
1258
	 * Get invoice template.
1259
	 *
1260
	 * @since 1.0.19
1261
	 * @param  string $context View or edit context.
1262
	 * @return bool
1263
	 */
1264
	public function get_template( $context = 'view' ) {
1265
		return $this->get_prop( 'template', $context );
1266
	}
1267
1268
	/**
1269
	 * Get whether the customer has confirmed their address.
1270
	 *
1271
	 * @since 1.0.19
1272
	 * @param  string $context View or edit context.
1273
	 * @return bool
1274
	 */
1275
	public function get_address_confirmed( $context = 'view' ) {
1276
		return (bool) $this->get_prop( 'address_confirmed', $context );
1277
    }
1278
1279
    /**
1280
	 * Alias of self::get_address_confirmed().
1281
	 *
1282
	 * @since 1.0.19
1283
	 * @param  string $context View or edit context.
1284
	 * @return bool
1285
	 */
1286
	public function get_user_address_confirmed( $context = 'view' ) {
1287
		return $this->get_address_confirmed( $context );
1288
    }
1289
1290
    /**
1291
	 * Alias of self::get_address().
1292
	 *
1293
	 * @since 1.0.19
1294
	 * @param  string $context View or edit context.
1295
	 * @return bool
1296
	 */
1297
	public function get_customer_address_confirmed( $context = 'view' ) {
1298
		return $this->get_address_confirmed( $context );
1299
    }
1300
1301
    /**
1302
	 * Get the invoice subtotal.
1303
	 *
1304
	 * @since 1.0.19
1305
	 * @param  string $context View or edit context.
1306
	 * @return float
1307
	 */
1308
	public function get_subtotal( $context = 'view' ) {
1309
        $subtotal = (float) $this->get_prop( 'subtotal', $context );
1310
1311
        // Backwards compatibility.
1312
        if ( is_bool( $context ) && $context ) {
0 ignored issues
show
introduced by
The condition is_bool($context) is always false.
Loading history...
1313
            return wpinv_price( wpinv_format_amount( $subtotal ), $this->get_currency() );
1314
        }
1315
1316
        return $subtotal;
1317
    }
1318
1319
    /**
1320
	 * Get the invoice discount total.
1321
	 *
1322
	 * @since 1.0.19
1323
	 * @param  string $context View or edit context.
1324
	 * @return float
1325
	 */
1326
	public function get_total_discount( $context = 'view' ) {
1327
		return (float) $this->get_prop( 'total_discount', $context );
1328
    }
1329
1330
    /**
1331
	 * Get the invoice tax total.
1332
	 *
1333
	 * @since 1.0.19
1334
	 * @param  string $context View or edit context.
1335
	 * @return float
1336
	 */
1337
	public function get_total_tax( $context = 'view' ) {
1338
		return (float) $this->get_prop( 'total_tax', $context );
1339
	}
1340
1341
	/**
1342
	 * @deprecated
1343
	 */
1344
	public function get_final_tax( $currency = false ) {
1345
		$tax = $this->get_total_tax();
1346
1347
        if ( $currency ) {
1348
			return wpinv_price( wpinv_format_amount( $tax, NULL, false ), $this->get_currency() );
1349
        }
1350
1351
        return $tax;
1352
    }
1353
1354
    /**
1355
	 * Get the invoice fees total.
1356
	 *
1357
	 * @since 1.0.19
1358
	 * @param  string $context View or edit context.
1359
	 * @return float
1360
	 */
1361
	public function get_total_fees( $context = 'view' ) {
1362
		return (float) $this->get_prop( 'total_fees', $context );
1363
    }
1364
1365
    /**
1366
	 * Alias for self::get_total_fees().
1367
	 *
1368
	 * @since 1.0.19
1369
	 * @param  string $context View or edit context.
1370
	 * @return float
1371
	 */
1372
	public function get_fees_total( $context = 'view' ) {
1373
		return $this->get_total_fees( $context );
1374
    }
1375
1376
    /**
1377
	 * Get the invoice total.
1378
	 *
1379
	 * @since 1.0.19
1380
     * @return float
1381
	 */
1382
	public function get_total() {
1383
		$total = $this->is_renewal() ? $this->get_recurring_total() : $this->get_initial_total();
1384
		return apply_filters( 'getpaid_get_invoice_total_amount', $total, $this  );
1385
    }
1386
1387
    /**
1388
	 * Get the initial invoice total.
1389
	 *
1390
	 * @since 1.0.19
1391
     * @param  string $context View or edit context.
1392
     * @return float
1393
	 */
1394
    public function get_initial_total() {
1395
1396
		if ( empty( $this->totals ) ) {
1397
			$this->recalculate_total();
1398
		}
1399
1400
		$tax      = $this->totals['tax']['initial'];
1401
		$fee      = $this->totals['fee']['initial'];
1402
		$discount = $this->totals['discount']['initial'];
1403
		$subtotal = $this->totals['subtotal']['initial'];
1404
		$total    = $tax + $fee - $discount + $subtotal;
1405
1406
		if ( 0 > $total ) {
1407
			$total = 0;
1408
		}
1409
1410
        return apply_filters( 'wpinv_get_initial_invoice_total', $total, $this );
1411
	}
1412
1413
	/**
1414
	 * Get the recurring invoice total.
1415
	 *
1416
	 * @since 1.0.19
1417
     * @param  string $context View or edit context.
1418
     * @return float
1419
	 */
1420
    public function get_recurring_total() {
1421
1422
		if ( empty( $this->totals ) ) {
1423
			$this->recalculate_total();
1424
		}
1425
1426
		$tax      = $this->totals['tax']['recurring'];
1427
		$fee      = $this->totals['fee']['recurring'];
1428
		$discount = $this->totals['discount']['recurring'];
1429
		$subtotal = $this->totals['subtotal']['recurring'];
1430
		$total    = $tax + $fee - $discount + $subtotal;
1431
1432
		if ( 0 > $total ) {
1433
			$total = 0;
1434
		}
1435
1436
        return apply_filters( 'wpinv_get_recurring_invoice_total', $total, $this );
1437
	}
1438
1439
	/**
1440
	 * Returns recurring payment details.
1441
	 *
1442
	 * @since 1.0.19
1443
     * @param  string $field Optionally provide a field to return.
1444
	 * @param string $currency Whether to include the currency.
1445
     * @return float
1446
	 */
1447
    public function get_recurring_details( $field = '', $currency = false ) {
1448
1449
		// Maybe recalculate totals.
1450
		if ( empty( $this->totals ) ) {
1451
			$this->recalculate_total();
1452
		}
1453
1454
		// Prepare recurring totals.
1455
        $data = apply_filters(
1456
			'wpinv_get_invoice_recurring_details',
1457
			array(
1458
				'cart_details' => $this->get_cart_details(),
1459
				'subtotal'     => $this->totals['subtotal']['recurring'],
1460
				'discount'     => $this->totals['discount']['recurring'],
1461
				'tax'          => $this->totals['tax']['recurring'],
1462
				'fee'          => $this->totals['fee']['recurring'],
1463
				'total'        => $this->get_recurring_total(),
1464
			),
1465
			$this,
1466
			$field,
1467
			$currency
1468
		);
1469
1470
        if ( isset( $data[$field] ) ) {
1471
            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...
1472
        }
1473
1474
        return $data;
1475
    }
1476
1477
    /**
1478
	 * Get the invoice fees.
1479
	 *
1480
	 * @since 1.0.19
1481
	 * @param  string $context View or edit context.
1482
	 * @return array
1483
	 */
1484
	public function get_fees( $context = 'view' ) {
1485
		return wpinv_parse_list( $this->get_prop( 'fees', $context ) );
1486
    }
1487
1488
    /**
1489
	 * Get the invoice discounts.
1490
	 *
1491
	 * @since 1.0.19
1492
	 * @param  string $context View or edit context.
1493
	 * @return array
1494
	 */
1495
	public function get_discounts( $context = 'view' ) {
1496
		return wpinv_parse_list( $this->get_prop( 'discounts', $context ) );
1497
    }
1498
1499
    /**
1500
	 * Get the invoice taxes.
1501
	 *
1502
	 * @since 1.0.19
1503
	 * @param  string $context View or edit context.
1504
	 * @return array
1505
	 */
1506
	public function get_taxes( $context = 'view' ) {
1507
		return wpinv_parse_list( $this->get_prop( 'taxes', $context ) );
1508
    }
1509
1510
    /**
1511
	 * Get the invoice items.
1512
	 *
1513
	 * @since 1.0.19
1514
	 * @param  string $context View or edit context.
1515
	 * @return GetPaid_Form_Item[]
1516
	 */
1517
	public function get_items( $context = 'view' ) {
1518
        return $this->get_prop( 'items', $context );
1519
    }
1520
1521
    /**
1522
	 * Get the invoice's payment form.
1523
	 *
1524
	 * @since 1.0.19
1525
	 * @param  string $context View or edit context.
1526
	 * @return int
1527
	 */
1528
	public function get_payment_form( $context = 'view' ) {
1529
		return intval( $this->get_prop( 'payment_form', $context ) );
1530
    }
1531
1532
    /**
1533
	 * Get the invoice's submission id.
1534
	 *
1535
	 * @since 1.0.19
1536
	 * @param  string $context View or edit context.
1537
	 * @return string
1538
	 */
1539
	public function get_submission_id( $context = 'view' ) {
1540
		return $this->get_prop( 'submission_id', $context );
1541
    }
1542
1543
    /**
1544
	 * Get the invoice's discount code.
1545
	 *
1546
	 * @since 1.0.19
1547
	 * @param  string $context View or edit context.
1548
	 * @return string
1549
	 */
1550
	public function get_discount_code( $context = 'view' ) {
1551
		return $this->get_prop( 'discount_code', $context );
1552
    }
1553
1554
    /**
1555
	 * Get the invoice's gateway.
1556
	 *
1557
	 * @since 1.0.19
1558
	 * @param  string $context View or edit context.
1559
	 * @return string
1560
	 */
1561
	public function get_gateway( $context = 'view' ) {
1562
		return $this->get_prop( 'gateway', $context );
1563
    }
1564
1565
    /**
1566
	 * Get the invoice's gateway display title.
1567
	 *
1568
	 * @since 1.0.19
1569
	 * @return string
1570
	 */
1571
    public function get_gateway_title() {
1572
        $title =  wpinv_get_gateway_checkout_label( $this->get_gateway() );
1573
        return apply_filters( 'wpinv_gateway_title', $title, $this->get_id(), $this );
1574
    }
1575
1576
    /**
1577
	 * Get the invoice's transaction id.
1578
	 *
1579
	 * @since 1.0.19
1580
	 * @param  string $context View or edit context.
1581
	 * @return string
1582
	 */
1583
	public function get_transaction_id( $context = 'view' ) {
1584
		return $this->get_prop( 'transaction_id', $context );
1585
    }
1586
1587
    /**
1588
	 * Get the invoice's currency.
1589
	 *
1590
	 * @since 1.0.19
1591
	 * @param  string $context View or edit context.
1592
	 * @return string
1593
	 */
1594
	public function get_currency( $context = 'view' ) {
1595
        $currency = $this->get_prop( 'currency', $context );
1596
        return empty( $currency ) ? wpinv_get_currency() : $currency;
1597
    }
1598
1599
    /**
1600
	 * Checks if we are charging taxes for this invoice.
1601
	 *
1602
	 * @since 1.0.19
1603
	 * @param  string $context View or edit context.
1604
	 * @return bool
1605
	 */
1606
	public function get_disable_taxes( $context = 'view' ) {
1607
        return (bool) $this->get_prop( 'disable_taxes', $context );
1608
    }
1609
1610
    /**
1611
	 * Retrieves the remote subscription id for an invoice.
1612
	 *
1613
	 * @since 1.0.19
1614
	 * @param  string $context View or edit context.
1615
	 * @return int
1616
	 */
1617
    public function get_subscription_id( $context = 'view' ) {
1618
        $subscription_id = $this->get_prop( 'subscription_id', $context );
1619
1620
        if ( empty( $subscription_id ) && $this->is_renewal() ) {
1621
            $parent = $this->get_parent();
1622
            return $parent->get_subscription_id( $context );
1623
        }
1624
1625
        return $subscription_id;
1626
    }
1627
1628
    /**
1629
	 * Retrieves the payment meta for an invoice.
1630
	 *
1631
	 * @since 1.0.19
1632
	 * @param  string $context View or edit context.
1633
	 * @return array
1634
	 */
1635
    public function get_payment_meta( $context = 'view' ) {
1636
1637
        return array(
1638
            '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

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

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

3463
        $this->/** @scrutinizer ignore-call */ 
3464
               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...
3464
        return $this;
3465
    }
3466
3467
    /**
3468
     * Convert this to an array.
3469
     */
3470
    public function array_convert() {
3471
        return $this->get_data();
3472
    }
3473
3474
    /**
3475
     * Adds a note to an invoice.
3476
     *
3477
     * @param string $note The note being added.
3478
     *
3479
     */
3480
    public function add_note( $note = '', $customer_type = false, $added_by_user = false, $system = false ) {
3481
3482
        // Bail if no note specified or this invoice is not yet saved.
3483
        if ( ! $note || $this->get_id() == 0 ) {
3484
            return false;
3485
        }
3486
3487
        if ( ( ( is_user_logged_in() && wpinv_current_user_can_manage_invoicing() ) || $added_by_user ) && !$system ) {
0 ignored issues
show
introduced by
Consider adding parentheses for clarity. Current Interpretation: (is_user_logged_in() && ...d_by_user) && ! $system, Probably Intended Meaning: is_user_logged_in() && w...d_by_user && ! $system)
Loading history...
3488
            $user                 = get_user_by( 'id', get_current_user_id() );
3489
            $comment_author       = $user->display_name;
3490
            $comment_author_email = $user->user_email;
3491
        } else {
3492
            $comment_author       = 'System';
3493
            $comment_author_email = 'system@';
3494
            $comment_author_email .= isset( $_SERVER['HTTP_HOST'] ) ? str_replace( 'www.', '', $_SERVER['HTTP_HOST'] ) : 'noreply.com';
3495
            $comment_author_email = sanitize_email( $comment_author_email );
3496
        }
3497
3498
        do_action( 'wpinv_pre_insert_invoice_note', $this->get_id(), $note, $customer_type );
3499
3500
        $note_id = wp_insert_comment( wp_filter_comment( array(
3501
            'comment_post_ID'      => $this->get_id(),
3502
            'comment_content'      => $note,
3503
            'comment_agent'        => 'GetPaid',
3504
            'user_id'              => is_admin() ? get_current_user_id() : 0,
3505
            'comment_date'         => current_time( 'mysql' ),
3506
            'comment_date_gmt'     => current_time( 'mysql', 1 ),
3507
            'comment_approved'     => 1,
3508
            'comment_parent'       => 0,
3509
            'comment_author'       => $comment_author,
3510
            'comment_author_IP'    => wpinv_get_ip(),
3511
            'comment_author_url'   => '',
3512
            'comment_author_email' => $comment_author_email,
3513
            'comment_type'         => 'wpinv_note'
3514
        ) ) );
3515
3516
        do_action( 'wpinv_insert_payment_note', $note_id, $this->get_id(), $note );
3517
3518
        if ( $customer_type ) {
3519
            add_comment_meta( $note_id, '_wpi_customer_note', 1 );
0 ignored issues
show
Bug introduced by
$note_id of type false is incompatible with the type integer expected by parameter $comment_id of add_comment_meta(). ( Ignorable by Annotation )

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

3519
            add_comment_meta( /** @scrutinizer ignore-type */ $note_id, '_wpi_customer_note', 1 );
Loading history...
3520
            do_action( 'wpinv_new_customer_note', array( 'invoice_id' => $this->get_id(), 'user_note' => $note ) );
3521
        }
3522
3523
        return $note_id;
3524
	}
3525
3526
	/**
3527
     * Generates a unique key for the invoice.
3528
     */
3529
    public function generate_key( $string = '' ) {
3530
        $auth_key  = defined( 'AUTH_KEY' ) ? AUTH_KEY : '';
3531
        return strtolower(
3532
            $string . md5( $this->get_id() . date( 'Y-m-d H:i:s' ) . $auth_key . uniqid( 'wpinv', true ) )
3533
        );
3534
    }
3535
3536
    /**
3537
     * Generates a new number for the invoice.
3538
     */
3539
    public function generate_number() {
3540
        $number = $this->get_id();
3541
3542
        if ( $this->has_status( 'auto-draft' ) && wpinv_sequential_number_active( $this->post_type ) ) {
0 ignored issues
show
Bug Best Practice introduced by
The property post_type does not exist on WPInv_Invoice. Since you implemented __get, consider adding a @property annotation.
Loading history...
3543
            $number = wpinv_get_next_invoice_number( $this->post_type );
3544
        }
3545
3546
		$number = wpinv_format_invoice_number( $number, $this->post_type );
3547
3548
		return $number;
3549
	}
3550
3551
	/**
3552
	 * Handle the status transition.
3553
	 */
3554
	protected function status_transition() {
3555
		$status_transition = $this->status_transition;
3556
3557
		// Reset status transition variable.
3558
		$this->status_transition = false;
3559
3560
		if ( $status_transition ) {
3561
			try {
3562
3563
				// Fire a hook for the status change.
3564
				do_action( 'getpaid_invoice_status_' . $status_transition['to'], $this->get_id(), $this, $status_transition );
3565
3566
				// @deprecated this is deprecated and will be removed in the future.
3567
				do_action( 'wpinv_status_' . $status_transition['to'], $this->get_id(), $status_transition['from'] );
3568
3569
				if ( ! empty( $status_transition['from'] ) ) {
3570
3571
					/* translators: 1: old invoice status 2: new invoice status */
3572
					$transition_note = sprintf( __( 'Status changed from %1$s to %2$s.', 'invoicing' ), wpinv_status_nicename( $status_transition['from'] ), wpinv_status_nicename( $status_transition['to'] ) );
3573
3574
					// Fire another hook.
3575
					do_action( 'getpaid_invoice_status_' . $status_transition['from'] . '_to_' . $status_transition['to'], $this->get_id(), $this );
3576
					do_action( 'getpaid_invoice_status_changed', $this->get_id(), $status_transition['from'], $status_transition['to'], $this );
3577
3578
					// @deprecated this is deprecated and will be removed in the future.
3579
					do_action( 'wpinv_status_' . $status_transition['from'] . '_to_' . $status_transition['to'], $this->get_id(), $status_transition['from'] );
3580
3581
					// Note the transition occurred.
3582
					$this->add_note( trim( $status_transition['note'] . ' ' . $transition_note ), 0, $status_transition['manual'] );
3583
3584
					// Work out if this was for a payment, and trigger a payment_status hook instead.
3585
					if (
3586
						in_array( $status_transition['from'], array( 'wpi-cancelled', 'wpi-pending', 'wpi-failed', 'wpi-refunded' ), true )
3587
						&& in_array( $status_transition['to'], array( 'publish', 'wpi-processing', 'wpi-renewal' ), true )
3588
					) {
3589
						do_action( 'getpaid_invoice_payment_status_changed', $this->get_id(), $this, $status_transition );
3590
					}
3591
				} else {
3592
					/* translators: %s: new invoice status */
3593
					$transition_note = sprintf( __( 'Status set to %s.', 'invoicing' ), wpinv_status_nicename( $status_transition['to'] ) );
3594
3595
					// Note the transition occurred.
3596
					$this->add_note( trim( $status_transition['note'] . ' ' . $transition_note ), 0, $status_transition['manual'] );
3597
3598
				}
3599
			} catch ( Exception $e ) {
3600
				$this->add_note( __( 'Error during status transition.', 'invoicing' ) . ' ' . $e->getMessage() );
3601
			}
3602
		}
3603
	}
3604
3605
	/**
3606
	 * Updates an invoice status.
3607
	 */
3608
	public function update_status( $new_status = false, $note = '', $manual = false ) {
3609
3610
		// Fires before updating a status.
3611
		do_action( 'wpinv_before_invoice_status_change', $this->get_id(), $new_status, $this->get_status( 'edit' ) );
3612
3613
		// Update the status.
3614
		$this->set_status( $new_status, $note, $manual );
3615
3616
		// Save the order.
3617
		return $this->save();
3618
3619
	}
3620
3621
	/**
3622
	 * @deprecated
3623
	 */
3624
	public function refresh_item_ids() {
3625
        $item_ids = implode( ',', array_unique( array_keys( $this->get_items() ) ) );
3626
        update_post_meta( $this->get_id(), '_wpinv_item_ids', $item_ids );
3627
	}
3628
3629
	/**
3630
	 * @deprecated
3631
	 */
3632
	public function update_items( $temp = false ) {
3633
3634
		$this->set_items( $this->get_items() );
3635
3636
		if ( ! $temp ) {
3637
			$this->save();
3638
		}
3639
3640
        return $this;
3641
	}
3642
3643
	/**
3644
	 * @deprecated
3645
	 */
3646
    public function validate_discount() {
3647
3648
        $discount_code = $this->get_discount_code();
3649
3650
        if ( empty( $discount_code ) ) {
3651
            return false;
3652
        }
3653
3654
        $discount = wpinv_get_discount_obj( $discount_code );
3655
3656
        // Ensure it is active.
3657
        return $discount->exists();
3658
3659
    }
3660
3661
	/**
3662
	 * Refunds an invoice.
3663
	 */
3664
    public function refund() {
3665
		$this->set_status( 'wpi-refunded' );
3666
        $this->save();
3667
	}
3668
3669
	/**
3670
	 * Marks an invoice as paid.
3671
	 * 
3672
	 * @param string $transaction_id
3673
	 */
3674
    public function mark_paid( $transaction_id = null, $note = '' ) {
3675
3676
		// Set the transaction id.
3677
		if ( empty( $transaction_id ) ) {
3678
			$transaction_id = $this->generate_key('trans_');
3679
		}
3680
3681
		if ( ! $this->get_transaction_id() ) {
3682
			$this->set_transaction_id( $transaction_id );
3683
		}
3684
3685
		if ( $this->is_paid() && 'wpi-processing' != $this->get_status() ) {
3686
			return $this->save();
3687
		}
3688
3689
		// Set the completed date.
3690
		$this->set_date_completed( current_time( 'mysql' ) );
3691
3692
		// Set the new status.
3693
		if ( $this->is_renewal() ) {
3694
3695
			$_note = sprintf(
3696
				__( 'Renewed via %s', 'invoicing' ),
3697
				$this->get_gateway_title() . empty( $note ) ? '' : " ($note)"
3698
			);
3699
3700
			if ( 'none' == $this->get_gateway() ) {
3701
				$_note = $note;
3702
			}
3703
3704
			$this->set_status( 'wpi-renewal', $_note );
3705
3706
		} else {
3707
3708
			$_note = sprintf(
3709
				__( 'Paid via %s', 'invoicing' ),
3710
				$this->get_gateway_title() . empty( $note ) ? '' : " ($note)"
3711
			);
3712
3713
			if ( 'none' == $this->get_gateway() ) {
3714
				$_note = $note;
3715
			}
3716
3717
			$this->set_status( 'publish',$_note );
3718
3719
		}
3720
3721
		// Set checkout mode.
3722
		$mode = wpinv_is_test_mode( $this->get_gateway() ) ? 'test' : 'live';
3723
		$this->set_mode( $mode );
3724
3725
		// Save the invoice.
3726
        $this->save();
3727
	}
3728
3729
3730
	/**
3731
	 * Save data to the database.
3732
	 *
3733
	 * @since 1.0.19
3734
	 * @return int invoice ID
3735
	 */
3736
	public function save() {
3737
		$this->maybe_set_date_paid();
3738
		parent::save();
3739
		$this->status_transition();
3740
		return $this->get_id();
3741
	}
3742
3743
}
3744