Passed
Push — master ( 4d2fb8...f16077 )
by Brian
05:24
created

WPInv_Invoice::get_tax_total_by_name()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 6
nc 4
nop 1
dl 0
loc 13
rs 10
c 0
b 0
f 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
		'customer_id'            => 0,
39
		'status'                 => 'wpi-pending',
40
		'version'                => '',
41
		'date_created'           => null,
42
        'date_modified'          => null,
43
        'due_date'               => null,
44
        'completed_date'         => null,
45
        'number'                 => '',
46
        'title'                  => '',
47
        'path'                   => '',
48
        'key'                    => '',
49
        'description'            => '',
50
        'author'                 => 1,
51
        'type'                   => 'invoice',
52
        'post_type'              => 'wpi_invoice',
53
        'mode'                   => 'live',
54
        'user_ip'                => null,
55
        'first_name'             => null,
56
        'last_name'              => null,
57
        'phone'                  => null,
58
        'email'                  => null,
59
        'country'                => null,
60
        'city'                   => null,
61
        'state'                  => null,
62
        'zip'                    => null,
63
        'company'                => null,
64
		'company_id'             => null,
65
        'vat_number'             => null,
66
        'vat_rate'               => null,
67
        'address'                => null,
68
        'address_confirmed'      => false,
69
        'shipping'               => null,
70
		'subtotal'               => 0,
71
        'total_discount'         => 0,
72
        'total_tax'              => 0,
73
		'total_fees'             => 0,
74
		'total'                  => 0,
75
        'fees'                   => array(),
76
        'discounts'              => array(),
77
        'taxes'                  => array(),
78
        'items'                  => array(),
79
        'payment_form'           => 1,
80
        'submission_id'          => null,
81
        'discount_code'          => null,
82
        'gateway'                => 'none',
83
        'transaction_id'         => '',
84
        'currency'               => '',
85
        'disable_taxes'          => false,
86
		'subscription_id'        => null,
87
		'remote_subscription_id' => null,
88
		'is_viewed'              => false,
89
		'email_cc'               => '',
90
		'template'               => 'quantity', // hours, amount only
91
		'created_via'            => null,
92
    );
93
94
    /**
95
	 * Stores meta in cache for future reads.
96
	 *
97
	 * A group must be set to to enable caching.
98
	 *
99
	 * @var string
100
	 */
101
	protected $cache_group = 'getpaid_invoices';
102
103
    /**
104
     * Stores a reference to the original WP_Post object
105
     *
106
     * @var WP_Post
107
     */
108
    protected $post = null;
109
110
    /**
111
     * Stores a reference to the recurring item id instead of looping through the items.
112
     *
113
     * @var int
114
     */
115
	protected $recurring_item = null;
116
117
	/**
118
     * Stores an array of item totals.
119
	 *
120
	 * e.g $totals['discount'] = array(
121
	 *      'initial'   => 10,
122
	 *      'recurring' => 10,
123
	 * )
124
     *
125
     * @var array
126
     */
127
	protected $totals = array();
128
129
	/**
130
     * Tax rate.
131
	 *
132
     * @var float
133
     */
134
	protected $tax_rate = 0;
135
136
	/**
137
	 * Stores the status transition information.
138
	 *
139
	 * @since 1.0.19
140
	 * @var bool|array
141
	 */
142
	protected $status_transition = false;
143
144
    /**
145
	 * Get the invoice if ID is passed, otherwise the invoice is new and empty.
146
	 *
147
	 * @param  int|string|object|WPInv_Invoice|WPInv_Legacy_Invoice|WP_Post $invoice Invoice id, key, transaction id, number or object to read.
148
	 */
149
    public function __construct( $invoice = 0 ) {
150
151
        parent::__construct( $invoice );
152
153
		if ( ! empty( $invoice ) && is_numeric( $invoice ) && getpaid_is_invoice_post_type( get_post_type( (int) $invoice ) ) ) {
0 ignored issues
show
Bug introduced by
It seems like get_post_type((int)$invoice) can also be of type false; however, parameter $post_type of getpaid_is_invoice_post_type() 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
		if ( ! empty( $invoice ) && is_numeric( $invoice ) && getpaid_is_invoice_post_type( /** @scrutinizer ignore-type */ get_post_type( (int) $invoice ) ) ) {
Loading history...
154
			$this->set_id( (int) $invoice );
155
		} elseif ( $invoice instanceof self ) {
156
			$this->set_id( $invoice->get_id() );
157
		} elseif ( ! empty( $invoice->ID ) ) {
158
			$this->set_id( $invoice->ID );
159
		} elseif ( is_array( $invoice ) ) {
160
			$this->set_props( $invoice );
161
162
			if ( isset( $invoice['ID'] ) ) {
163
				$this->set_id( $invoice['ID'] );
164
			}
165
} elseif ( is_string( $invoice ) && $invoice_id = self::get_invoice_id_by_field( $invoice, 'key' ) ) {
166
			$this->set_id( $invoice_id );
167
		} elseif ( is_string( $invoice ) && $invoice_id = self::get_invoice_id_by_field( $invoice, 'number' ) ) {
168
			$this->set_id( $invoice_id );
169
		} elseif ( is_string( $invoice ) && $invoice_id = self::get_invoice_id_by_field( $invoice, 'transaction_id' ) ) {
170
			$this->set_id( $invoice_id );
171
		} else {
172
			$this->set_object_read( true );
173
		}
174
175
        // Load the datastore.
176
		$this->data_store = GetPaid_Data_Store::load( $this->data_store_name );
177
178
		if ( $this->get_id() > 0 ) {
179
            $this->post = get_post( $this->get_id() );
0 ignored issues
show
Documentation Bug introduced by
It seems like get_post($this->get_id()) can also be of type array. However, the property $post is declared as type WP_Post. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
180
            $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...
181
			$this->data_store->read( $this );
182
        }
183
184
    }
185
186
    /**
187
	 * Given an invoice key/number, it returns its id.
188
	 *
189
	 *
190
	 * @static
191
	 * @param string $value The invoice key or number
192
	 * @param string $field Either key, transaction_id or number.
193
	 * @since 1.0.15
194
	 * @return int
195
	 */
196
	public static function get_invoice_id_by_field( $value, $field = 'key' ) {
197
        global $wpdb;
198
199
		// Trim the value.
200
		$value = trim( $value );
201
202
		if ( empty( $value ) ) {
203
			return 0;
204
		}
205
206
        // Valid fields.
207
        $fields = array( 'key', 'number', 'transaction_id' );
208
209
		// Ensure a field has been passed.
210
		if ( empty( $field ) || ! in_array( $field, $fields ) ) {
211
			return 0;
212
		}
213
214
		// Maybe retrieve from the cache.
215
		$invoice_id   = wp_cache_get( $value, "getpaid_invoice_{$field}s_to_invoice_ids" );
216
		if ( false !== $invoice_id ) {
217
			return $invoice_id;
218
		}
219
220
        // Fetch from the db.
221
        $table       = $wpdb->prefix . 'getpaid_invoices';
222
		$db_field    = 'key' === $field ? 'invoice_key' : $field;
223
        $invoice_id  = (int) $wpdb->get_var(
224
            $wpdb->prepare( "SELECT `post_id` FROM $table WHERE `$db_field`=%s LIMIT 1", $value )
225
        );
226
227
		// Update the cache with our data
228
		wp_cache_set( $value, $invoice_id, "getpaid_invoice_{$field}s_to_invoice_ids" );
229
230
		return $invoice_id;
231
    }
232
233
    /**
234
     * Checks if an invoice key is set.
235
     */
236
    public function _isset( $key ) {
237
        return isset( $this->data[ $key ] ) || method_exists( $this, "get_$key" );
238
    }
239
240
    /*
241
	|--------------------------------------------------------------------------
242
	| CRUD methods
243
	|--------------------------------------------------------------------------
244
	|
245
	| Methods which create, read, update and delete items from the database.
246
	|
247
    */
248
249
    /*
250
	|--------------------------------------------------------------------------
251
	| Getters
252
	|--------------------------------------------------------------------------
253
    */
254
255
    /**
256
	 * Get parent invoice ID.
257
	 *
258
	 * @since 1.0.19
259
	 * @param  string $context View or edit context.
260
	 * @return int
261
	 */
262
	public function get_parent_id( $context = 'view' ) {
263
		return (int) $this->get_prop( 'parent_id', $context );
264
    }
265
266
    /**
267
	 * Get parent invoice.
268
	 *
269
	 * @since 1.0.19
270
	 * @return WPInv_Invoice
271
	 */
272
    public function get_parent_payment() {
273
        return new WPInv_Invoice( $this->get_parent_id() );
274
    }
275
276
    /**
277
	 * Alias for self::get_parent_payment().
278
	 *
279
	 * @since 1.0.19
280
	 * @return WPInv_Invoice
281
	 */
282
    public function get_parent() {
283
        return $this->get_parent_payment();
284
    }
285
286
    /**
287
	 * Get invoice status.
288
	 *
289
	 * @since 1.0.19
290
	 * @param  string $context View or edit context.
291
	 * @return string
292
	 */
293
	public function get_status( $context = 'view' ) {
294
		return $this->get_prop( 'status', $context );
295
	}
296
297
	/**
298
	 * Retrieves an array of possible invoice statuses.
299
	 *
300
	 * @since 1.0.19
301
	 * @return array
302
	 */
303
	public function get_all_statuses() {
304
		return wpinv_get_invoice_statuses( true, true, $this );
305
    }
306
307
    /**
308
	 * Get invoice status nice name.
309
	 *
310
	 * @since 1.0.19
311
	 * @return string
312
	 */
313
    public function get_status_nicename() {
314
		$statuses = $this->get_all_statuses();
315
316
        $status = isset( $statuses[ $this->get_status() ] ) ? $statuses[ $this->get_status() ] : $this->get_status();
317
318
        return apply_filters( 'wpinv_get_invoice_status_nicename', $status, $this );
319
    }
320
321
	/**
322
	 * Retrieves the invoice status class
323
	 *
324
	 * @since  1.0.19
325
	 * @return string
326
	 */
327
	public function get_status_class() {
328
		$statuses = getpaid_get_invoice_status_classes();
329
		return isset( $statuses[ $this->get_status() ] ) ? $statuses[ $this->get_status() ] : 'bg-dark';
330
	}
331
332
	/**
333
     * Retrieves the invoice status label html
334
     *
335
     * @since  1.0.0
336
     * @return string
337
     */
338
    public function get_status_label_html() {
339
340
		$status_label = sanitize_text_field( $this->get_status_nicename() );
341
		$status       = sanitize_html_class( $this->get_status() );
342
		$class        = esc_attr( $this->get_status_class() );
343
344
		return "<span class='bsui'><span class='badge $class $status'>$status_label</span></span>";
345
	}
346
347
    /**
348
	 * Get plugin version when the invoice was created.
349
	 *
350
	 * @since 1.0.19
351
	 * @param  string $context View or edit context.
352
	 * @return string
353
	 */
354
	public function get_version( $context = 'view' ) {
355
		return $this->get_prop( 'version', $context );
356
	}
357
358
	/**
359
	 * @deprecated
360
	 */
361
	public function get_invoice_date( $format = true ) {
362
		$date      = getpaid_format_date( $this->get_date_completed() );
363
		$date      = empty( $date ) ? $this->get_date_created() : $this->get_date_completed();
364
		$formatted = getpaid_format_date( $date );
365
366
		if ( $format ) {
367
			return $formatted;
368
		}
369
370
		return empty( $formatted ) ? '' : $date;
371
372
    }
373
374
    /**
375
	 * Get date when the invoice was created.
376
	 *
377
	 * @since 1.0.19
378
	 * @param  string $context View or edit context.
379
	 * @return string
380
	 */
381
	public function get_date_created( $context = 'view' ) {
382
		return $this->get_prop( 'date_created', $context );
383
	}
384
385
	/**
386
	 * Alias for self::get_date_created().
387
	 *
388
	 * @since 1.0.19
389
	 * @param  string $context View or edit context.
390
	 * @return string
391
	 */
392
	public function get_created_date( $context = 'view' ) {
393
		return $this->get_date_created( $context );
394
    }
395
396
    /**
397
	 * Get GMT date when the invoice was created.
398
	 *
399
	 * @since 1.0.19
400
	 * @param  string $context View or edit context.
401
	 * @return string
402
	 */
403
	public function get_date_created_gmt( $context = 'view' ) {
404
        $date = $this->get_date_created( $context );
405
406
        if ( $date ) {
407
            $date = get_gmt_from_date( $date );
408
        }
409
		return $date;
410
    }
411
412
    /**
413
	 * Get date when the invoice was last modified.
414
	 *
415
	 * @since 1.0.19
416
	 * @param  string $context View or edit context.
417
	 * @return string
418
	 */
419
	public function get_date_modified( $context = 'view' ) {
420
		return $this->get_prop( 'date_modified', $context );
421
	}
422
423
	/**
424
	 * Alias for self::get_date_modified().
425
	 *
426
	 * @since 1.0.19
427
	 * @param  string $context View or edit context.
428
	 * @return string
429
	 */
430
	public function get_modified_date( $context = 'view' ) {
431
		return $this->get_date_modified( $context );
432
    }
433
434
    /**
435
	 * Get GMT date when the invoice was last modified.
436
	 *
437
	 * @since 1.0.19
438
	 * @param  string $context View or edit context.
439
	 * @return string
440
	 */
441
	public function get_date_modified_gmt( $context = 'view' ) {
442
        $date = $this->get_date_modified( $context );
443
444
        if ( $date ) {
445
            $date = get_gmt_from_date( $date );
446
        }
447
		return $date;
448
    }
449
450
    /**
451
	 * Get the invoice due date.
452
	 *
453
	 * @since 1.0.19
454
	 * @param  string $context View or edit context.
455
	 * @return string
456
	 */
457
	public function get_due_date( $context = 'view' ) {
458
		return $this->get_prop( 'due_date', $context );
459
    }
460
461
    /**
462
	 * Alias for self::get_due_date().
463
	 *
464
	 * @since 1.0.19
465
	 * @param  string $context View or edit context.
466
	 * @return string
467
	 */
468
	public function get_date_due( $context = 'view' ) {
469
		return $this->get_due_date( $context );
470
    }
471
472
    /**
473
	 * Get the invoice GMT due date.
474
	 *
475
	 * @since 1.0.19
476
	 * @param  string $context View or edit context.
477
	 * @return string
478
	 */
479
	public function get_due_date_gmt( $context = 'view' ) {
480
        $date = $this->get_due_date( $context );
481
482
        if ( $date ) {
483
            $date = get_gmt_from_date( $date );
484
        }
485
		return $date;
486
    }
487
488
    /**
489
	 * Alias for self::get_due_date_gmt().
490
	 *
491
	 * @since 1.0.19
492
	 * @param  string $context View or edit context.
493
	 * @return string
494
	 */
495
	public function get_gmt_date_due( $context = 'view' ) {
496
		return $this->get_due_date_gmt( $context );
497
    }
498
499
    /**
500
	 * Get date when the invoice was completed.
501
	 *
502
	 * @since 1.0.19
503
	 * @param  string $context View or edit context.
504
	 * @return string
505
	 */
506
	public function get_completed_date( $context = 'view' ) {
507
		return $this->get_prop( 'completed_date', $context );
508
    }
509
510
    /**
511
	 * Alias for self::get_completed_date().
512
	 *
513
	 * @since 1.0.19
514
	 * @param  string $context View or edit context.
515
	 * @return string
516
	 */
517
	public function get_date_completed( $context = 'view' ) {
518
		return $this->get_completed_date( $context );
519
    }
520
521
    /**
522
	 * Get GMT date when the invoice was was completed.
523
	 *
524
	 * @since 1.0.19
525
	 * @param  string $context View or edit context.
526
	 * @return string
527
	 */
528
	public function get_completed_date_gmt( $context = 'view' ) {
529
        $date = $this->get_completed_date( $context );
530
531
        if ( $date ) {
532
            $date = get_gmt_from_date( $date );
533
        }
534
		return $date;
535
    }
536
537
    /**
538
	 * Alias for self::get_completed_date_gmt().
539
	 *
540
	 * @since 1.0.19
541
	 * @param  string $context View or edit context.
542
	 * @return string
543
	 */
544
	public function get_gmt_completed_date( $context = 'view' ) {
545
		return $this->get_completed_date_gmt( $context );
546
    }
547
548
    /**
549
	 * Get the invoice number.
550
	 *
551
	 * @since 1.0.19
552
	 * @param  string $context View or edit context.
553
	 * @return string
554
	 */
555
	public function get_number( $context = 'view' ) {
556
		$number = $this->get_prop( 'number', $context );
557
558
		if ( empty( $number ) ) {
559
			$number = $this->generate_number();
560
			$this->set_number( $this->generate_number() );
561
		}
562
563
		return $number;
564
    }
565
566
	/**
567
	 * Set the invoice number.
568
	 *
569
	 * @since 1.0.19
570
	 */
571
	public function maybe_set_number() {
572
        $number = $this->get_number();
573
574
        if ( empty( $number ) || $this->get_id() == $number ) {
575
			$this->set_number( $this->generate_number() );
576
        }
577
578
	}
579
580
    /**
581
	 * Get the invoice key.
582
	 *
583
	 * @since 1.0.19
584
	 * @param  string $context View or edit context.
585
	 * @return string
586
	 */
587
	public function get_key( $context = 'view' ) {
588
        return $this->get_prop( 'key', $context );
589
	}
590
591
	/**
592
	 * Set the invoice key.
593
	 *
594
	 * @since 1.0.19
595
	 */
596
	public function maybe_set_key() {
597
        $key = $this->get_key();
598
599
        if ( empty( $key ) ) {
600
            $key = $this->generate_key( $this->get_type() . '_' );
601
            $this->set_key( $key );
602
        }
603
604
    }
605
606
    /**
607
	 * Get the invoice type.
608
	 *
609
	 * @since 1.0.19
610
	 * @param  string $context View or edit context.
611
	 * @return string
612
	 */
613
	public function get_type( $context = 'view' ) {
614
        return $this->get_prop( 'type', $context );
615
	}
616
617
	/**
618
	 * Returns the post type name.
619
	 *
620
	 * @since 1.0.19
621
	 * @return string
622
	 */
623
	public function get_invoice_quote_type() {
624
        return getpaid_get_post_type_label( $this->get_post_type(), false );
625
    }
626
627
    /**
628
	 * Get the invoice post type label.
629
	 *
630
	 * @since 1.0.19
631
	 * @param  string $context View or edit context.
632
	 * @return string
633
	 */
634
	public function get_label( $context = 'view' ) {
635
        return getpaid_get_post_type_label( $this->get_post_type( $context ), false );
636
	}
637
638
	/**
639
	 * Get the invoice post type.
640
	 *
641
	 * @since 1.0.19
642
	 * @param  string $context View or edit context.
643
	 * @return string
644
	 */
645
	public function get_post_type( $context = 'view' ) {
646
        return $this->get_prop( 'post_type', $context );
647
    }
648
649
    /**
650
	 * Get the invoice mode.
651
	 *
652
	 * @since 1.0.19
653
	 * @param  string $context View or edit context.
654
	 * @return string
655
	 */
656
	public function get_mode( $context = 'view' ) {
657
        return $this->get_prop( 'mode', $context );
658
    }
659
660
    /**
661
	 * Get the invoice path.
662
	 *
663
	 * @since 1.0.19
664
	 * @param  string $context View or edit context.
665
	 * @return string
666
	 */
667
	public function get_path( $context = 'view' ) {
668
        $path   = $this->get_prop( 'path', $context );
669
		$prefix = $this->get_type();
670
671
		if ( 0 !== strpos( $path, $prefix ) ) {
672
			$path = sanitize_title( $prefix . '-' . $this->get_id() );
673
			$this->set_path( $path );
674
		}
675
676
		return $path;
677
    }
678
679
    /**
680
	 * Get the invoice name/title.
681
	 *
682
	 * @since 1.0.19
683
	 * @param  string $context View or edit context.
684
	 * @return string
685
	 */
686
	public function get_name( $context = 'view' ) {
687
        return $this->get_prop( 'title', $context );
688
    }
689
690
    /**
691
	 * Alias of self::get_name().
692
	 *
693
	 * @since 1.0.19
694
	 * @param  string $context View or edit context.
695
	 * @return string
696
	 */
697
	public function get_title( $context = 'view' ) {
698
		return $this->get_name( $context );
699
    }
700
701
    /**
702
	 * Get the invoice description.
703
	 *
704
	 * @since 1.0.19
705
	 * @param  string $context View or edit context.
706
	 * @return string
707
	 */
708
	public function get_description( $context = 'view' ) {
709
		return $this->get_prop( 'description', $context );
710
    }
711
712
    /**
713
	 * Alias of self::get_description().
714
	 *
715
	 * @since 1.0.19
716
	 * @param  string $context View or edit context.
717
	 * @return string
718
	 */
719
	public function get_excerpt( $context = 'view' ) {
720
		return $this->get_description( $context );
721
    }
722
723
    /**
724
	 * Alias of self::get_description().
725
	 *
726
	 * @since 1.0.19
727
	 * @param  string $context View or edit context.
728
	 * @return string
729
	 */
730
	public function get_summary( $context = 'view' ) {
731
		return $this->get_description( $context );
732
    }
733
734
    /**
735
	 * Returns the user info.
736
	 *
737
	 * @since 1.0.19
738
     * @param  string $context View or edit context.
739
	 * @return array
740
	 */
741
    public function get_user_info( $context = 'view' ) {
742
743
        $user_info = array(
744
            'user_id'    => $this->get_user_id( $context ),
745
            'email'      => $this->get_email( $context ),
746
            'first_name' => $this->get_first_name( $context ),
747
            'last_name'  => $this->get_last_name( $context ),
748
            'address'    => $this->get_address( $context ),
749
            'phone'      => $this->get_phone( $context ),
750
            'city'       => $this->get_city( $context ),
751
            'country'    => $this->get_country( $context ),
752
            'state'      => $this->get_state( $context ),
753
            'zip'        => $this->get_zip( $context ),
754
            'company'    => $this->get_company( $context ),
755
			'company_id' => $this->get_company_id( $context ),
756
            'vat_number' => $this->get_vat_number( $context ),
757
            'discount'   => $this->get_discount_code( $context ),
758
		);
759
760
		return apply_filters( 'wpinv_user_info', $user_info, $this->get_id(), $this );
761
762
    }
763
764
    /**
765
	 * Get the user id.
766
	 *
767
	 * @since 1.0.19
768
	 * @param  string $context View or edit context.
769
	 * @return int
770
	 */
771
	public function get_author( $context = 'view' ) {
772
		return (int) $this->get_prop( 'author', $context );
773
    }
774
775
    /**
776
	 * Alias of self::get_author().
777
	 *
778
	 * @since 1.0.19
779
	 * @param  string $context View or edit context.
780
	 * @return int
781
	 */
782
	public function get_user_id( $context = 'view' ) {
783
		return $this->get_author( $context );
784
    }
785
786
     /**
787
	 * Get customer ID.
788
	 *
789
	 * @since 1.0.19
790
	 * @param  string $context View or edit context.
791
	 * @return int
792
	 */
793
	public function get_customer_id( $context = 'view' ) {
794
		return (int) $this->get_prop( 'customer_id', $context );
795
    }
796
797
    /**
798
	 * Get the customer's ip.
799
	 *
800
	 * @since 1.0.19
801
	 * @param  string $context View or edit context.
802
	 * @return string
803
	 */
804
	public function get_ip( $context = 'view' ) {
805
		return $this->get_prop( 'user_ip', $context );
806
    }
807
808
    /**
809
	 * Alias of self::get_ip().
810
	 *
811
	 * @since 1.0.19
812
	 * @param  string $context View or edit context.
813
	 * @return string
814
	 */
815
	public function get_user_ip( $context = 'view' ) {
816
		return $this->get_ip( $context );
817
    }
818
819
     /**
820
	 * Alias of self::get_ip().
821
	 *
822
	 * @since 1.0.19
823
	 * @param  string $context View or edit context.
824
	 * @return string
825
	 */
826
	public function get_customer_ip( $context = 'view' ) {
827
		return $this->get_ip( $context );
828
    }
829
830
    /**
831
	 * Get the customer's first name.
832
	 *
833
	 * @since 1.0.19
834
	 * @param  string $context View or edit context.
835
	 * @return string
836
	 */
837
	public function get_first_name( $context = 'view' ) {
838
		return $this->get_prop( 'first_name', $context );
839
    }
840
841
    /**
842
	 * Alias of self::get_first_name().
843
	 *
844
	 * @since 1.0.19
845
	 * @param  string $context View or edit context.
846
	 * @return string
847
	 */
848
	public function get_user_first_name( $context = 'view' ) {
849
		return $this->get_first_name( $context );
850
    }
851
852
     /**
853
	 * Alias of self::get_first_name().
854
	 *
855
	 * @since 1.0.19
856
	 * @param  string $context View or edit context.
857
	 * @return string
858
	 */
859
	public function get_customer_first_name( $context = 'view' ) {
860
		return $this->get_first_name( $context );
861
    }
862
863
    /**
864
	 * Get the customer's last name.
865
	 *
866
	 * @since 1.0.19
867
	 * @param  string $context View or edit context.
868
	 * @return string
869
	 */
870
	public function get_last_name( $context = 'view' ) {
871
		return $this->get_prop( 'last_name', $context );
872
    }
873
874
    /**
875
	 * Alias of self::get_last_name().
876
	 *
877
	 * @since 1.0.19
878
	 * @param  string $context View or edit context.
879
	 * @return string
880
	 */
881
	public function get_user_last_name( $context = 'view' ) {
882
		return $this->get_last_name( $context );
883
    }
884
885
    /**
886
	 * Alias of self::get_last_name().
887
	 *
888
	 * @since 1.0.19
889
	 * @param  string $context View or edit context.
890
	 * @return string
891
	 */
892
	public function get_customer_last_name( $context = 'view' ) {
893
		return $this->get_last_name( $context );
894
    }
895
896
    /**
897
	 * Get the customer's full name.
898
	 *
899
	 * @since 1.0.19
900
	 * @param  string $context View or edit context.
901
	 * @return string
902
	 */
903
	public function get_full_name( $context = 'view' ) {
904
		$name = trim( $this->get_first_name( $context ) . ' ' . $this->get_last_name( $context ) );
905
906
		if ( ! $name ) {
907
			$user = get_userdata( $this->get_author( $context ) );
908
909
			if ( $user ) {
910
				$name = $user->display_name;
911
			}
912
		}
913
914
		if ( ! $name ) {
915
			$name = $this->get_email( $context );
916
		}
917
918
		return apply_filters( 'wpinv_invoice_user_full_name', $name, $this );
919
    }
920
921
    /**
922
	 * Alias of self::get_full_name().
923
	 *
924
	 * @since 1.0.19
925
	 * @param  string $context View or edit context.
926
	 * @return string
927
	 */
928
	public function get_user_full_name( $context = 'view' ) {
929
		return $this->get_full_name( $context );
930
    }
931
932
    /**
933
	 * Alias of self::get_full_name().
934
	 *
935
	 * @since 1.0.19
936
	 * @param  string $context View or edit context.
937
	 * @return string
938
	 */
939
	public function get_customer_full_name( $context = 'view' ) {
940
		return $this->get_full_name( $context );
941
    }
942
943
    /**
944
	 * Get the customer's phone number.
945
	 *
946
	 * @since 1.0.19
947
	 * @param  string $context View or edit context.
948
	 * @return string
949
	 */
950
	public function get_phone( $context = 'view' ) {
951
		return $this->get_prop( 'phone', $context );
952
    }
953
954
    /**
955
	 * Alias of self::get_phone().
956
	 *
957
	 * @since 1.0.19
958
	 * @param  string $context View or edit context.
959
	 * @return string
960
	 */
961
	public function get_phone_number( $context = 'view' ) {
962
		return $this->get_phone( $context );
963
    }
964
965
    /**
966
	 * Alias of self::get_phone().
967
	 *
968
	 * @since 1.0.19
969
	 * @param  string $context View or edit context.
970
	 * @return string
971
	 */
972
	public function get_user_phone( $context = 'view' ) {
973
		return $this->get_phone( $context );
974
    }
975
976
    /**
977
	 * Alias of self::get_phone().
978
	 *
979
	 * @since 1.0.19
980
	 * @param  string $context View or edit context.
981
	 * @return string
982
	 */
983
	public function get_customer_phone( $context = 'view' ) {
984
		return $this->get_phone( $context );
985
    }
986
987
    /**
988
	 * Get the customer's email address.
989
	 *
990
	 * @since 1.0.19
991
	 * @param  string $context View or edit context.
992
	 * @return string
993
	 */
994
	public function get_email( $context = 'view' ) {
995
		return $this->get_prop( 'email', $context );
996
    }
997
998
    /**
999
	 * Alias of self::get_email().
1000
	 *
1001
	 * @since 1.0.19
1002
	 * @param  string $context View or edit context.
1003
	 * @return string
1004
	 */
1005
	public function get_email_address( $context = 'view' ) {
1006
		return $this->get_email( $context );
1007
    }
1008
1009
    /**
1010
	 * Alias of self::get_email().
1011
	 *
1012
	 * @since 1.0.19
1013
	 * @param  string $context View or edit context.
1014
	 * @return string
1015
	 */
1016
	public function get_user_email( $context = 'view' ) {
1017
		return $this->get_email( $context );
1018
    }
1019
1020
    /**
1021
	 * Alias of self::get_email().
1022
	 *
1023
	 * @since 1.0.19
1024
	 * @param  string $context View or edit context.
1025
	 * @return string
1026
	 */
1027
	public function get_customer_email( $context = 'view' ) {
1028
		return $this->get_email( $context );
1029
    }
1030
1031
    /**
1032
	 * Get the customer's country.
1033
	 *
1034
	 * @since 1.0.19
1035
	 * @param  string $context View or edit context.
1036
	 * @return string
1037
	 */
1038
	public function get_country( $context = 'view' ) {
1039
		$country = $this->get_prop( 'country', $context );
1040
		return empty( $country ) ? wpinv_get_default_country() : $country;
1041
    }
1042
1043
    /**
1044
	 * Alias of self::get_country().
1045
	 *
1046
	 * @since 1.0.19
1047
	 * @param  string $context View or edit context.
1048
	 * @return string
1049
	 */
1050
	public function get_user_country( $context = 'view' ) {
1051
		return $this->get_country( $context );
1052
    }
1053
1054
    /**
1055
	 * Alias of self::get_country().
1056
	 *
1057
	 * @since 1.0.19
1058
	 * @param  string $context View or edit context.
1059
	 * @return string
1060
	 */
1061
	public function get_customer_country( $context = 'view' ) {
1062
		return $this->get_country( $context );
1063
    }
1064
1065
    /**
1066
	 * Get the customer's state.
1067
	 *
1068
	 * @since 1.0.19
1069
	 * @param  string $context View or edit context.
1070
	 * @return string
1071
	 */
1072
	public function get_state( $context = 'view' ) {
1073
		$state = $this->get_prop( 'state', $context );
1074
		return empty( $state ) ? wpinv_get_default_state() : $state;
1075
    }
1076
1077
    /**
1078
	 * Alias of self::get_state().
1079
	 *
1080
	 * @since 1.0.19
1081
	 * @param  string $context View or edit context.
1082
	 * @return string
1083
	 */
1084
	public function get_user_state( $context = 'view' ) {
1085
		return $this->get_state( $context );
1086
    }
1087
1088
    /**
1089
	 * Alias of self::get_state().
1090
	 *
1091
	 * @since 1.0.19
1092
	 * @param  string $context View or edit context.
1093
	 * @return string
1094
	 */
1095
	public function get_customer_state( $context = 'view' ) {
1096
		return $this->get_state( $context );
1097
    }
1098
1099
    /**
1100
	 * Get the customer's city.
1101
	 *
1102
	 * @since 1.0.19
1103
	 * @param  string $context View or edit context.
1104
	 * @return string
1105
	 */
1106
	public function get_city( $context = 'view' ) {
1107
		return $this->get_prop( 'city', $context );
1108
    }
1109
1110
    /**
1111
	 * Alias of self::get_city().
1112
	 *
1113
	 * @since 1.0.19
1114
	 * @param  string $context View or edit context.
1115
	 * @return string
1116
	 */
1117
	public function get_user_city( $context = 'view' ) {
1118
		return $this->get_city( $context );
1119
    }
1120
1121
    /**
1122
	 * Alias of self::get_city().
1123
	 *
1124
	 * @since 1.0.19
1125
	 * @param  string $context View or edit context.
1126
	 * @return string
1127
	 */
1128
	public function get_customer_city( $context = 'view' ) {
1129
		return $this->get_city( $context );
1130
    }
1131
1132
    /**
1133
	 * Get the customer's zip.
1134
	 *
1135
	 * @since 1.0.19
1136
	 * @param  string $context View or edit context.
1137
	 * @return string
1138
	 */
1139
	public function get_zip( $context = 'view' ) {
1140
		return $this->get_prop( 'zip', $context );
1141
    }
1142
1143
    /**
1144
	 * Alias of self::get_zip().
1145
	 *
1146
	 * @since 1.0.19
1147
	 * @param  string $context View or edit context.
1148
	 * @return string
1149
	 */
1150
	public function get_user_zip( $context = 'view' ) {
1151
		return $this->get_zip( $context );
1152
    }
1153
1154
    /**
1155
	 * Alias of self::get_zip().
1156
	 *
1157
	 * @since 1.0.19
1158
	 * @param  string $context View or edit context.
1159
	 * @return string
1160
	 */
1161
	public function get_customer_zip( $context = 'view' ) {
1162
		return $this->get_zip( $context );
1163
    }
1164
1165
    /**
1166
	 * Get the customer's company.
1167
	 *
1168
	 * @since 1.0.19
1169
	 * @param  string $context View or edit context.
1170
	 * @return string
1171
	 */
1172
	public function get_company( $context = 'view' ) {
1173
		return $this->get_prop( 'company', $context );
1174
    }
1175
1176
    /**
1177
	 * Alias of self::get_company().
1178
	 *
1179
	 * @since 1.0.19
1180
	 * @param  string $context View or edit context.
1181
	 * @return string
1182
	 */
1183
	public function get_user_company( $context = 'view' ) {
1184
		return $this->get_company( $context );
1185
    }
1186
1187
    /**
1188
	 * Alias of self::get_company().
1189
	 *
1190
	 * @since 1.0.19
1191
	 * @param  string $context View or edit context.
1192
	 * @return string
1193
	 */
1194
	public function get_customer_company( $context = 'view' ) {
1195
		return $this->get_company( $context );
1196
    }
1197
1198
	/**
1199
	 * Get the customer's company id.
1200
	 *
1201
	 * @since 1.0.19
1202
	 * @param  string $context View or edit context.
1203
	 * @return string
1204
	 */
1205
	public function get_company_id( $context = 'view' ) {
1206
		return $this->get_prop( 'company_id', $context );
1207
    }
1208
1209
    /**
1210
	 * Get the customer's vat number.
1211
	 *
1212
	 * @since 1.0.19
1213
	 * @param  string $context View or edit context.
1214
	 * @return string
1215
	 */
1216
	public function get_vat_number( $context = 'view' ) {
1217
		return $this->get_prop( 'vat_number', $context );
1218
    }
1219
1220
    /**
1221
	 * Alias of self::get_vat_number().
1222
	 *
1223
	 * @since 1.0.19
1224
	 * @param  string $context View or edit context.
1225
	 * @return string
1226
	 */
1227
	public function get_user_vat_number( $context = 'view' ) {
1228
		return $this->get_vat_number( $context );
1229
    }
1230
1231
    /**
1232
	 * Alias of self::get_vat_number().
1233
	 *
1234
	 * @since 1.0.19
1235
	 * @param  string $context View or edit context.
1236
	 * @return string
1237
	 */
1238
	public function get_customer_vat_number( $context = 'view' ) {
1239
		return $this->get_vat_number( $context );
1240
    }
1241
1242
    /**
1243
	 * Get the customer's vat rate.
1244
	 *
1245
	 * @since 1.0.19
1246
	 * @param  string $context View or edit context.
1247
	 * @return string
1248
	 */
1249
	public function get_vat_rate( $context = 'view' ) {
1250
		return $this->get_prop( 'vat_rate', $context );
1251
    }
1252
1253
    /**
1254
	 * Alias of self::get_vat_rate().
1255
	 *
1256
	 * @since 1.0.19
1257
	 * @param  string $context View or edit context.
1258
	 * @return string
1259
	 */
1260
	public function get_user_vat_rate( $context = 'view' ) {
1261
		return $this->get_vat_rate( $context );
1262
    }
1263
1264
    /**
1265
	 * Alias of self::get_vat_rate().
1266
	 *
1267
	 * @since 1.0.19
1268
	 * @param  string $context View or edit context.
1269
	 * @return string
1270
	 */
1271
	public function get_customer_vat_rate( $context = 'view' ) {
1272
		return $this->get_vat_rate( $context );
1273
    }
1274
1275
    /**
1276
	 * Get the customer's address.
1277
	 *
1278
	 * @since 1.0.19
1279
	 * @param  string $context View or edit context.
1280
	 * @return string
1281
	 */
1282
	public function get_address( $context = 'view' ) {
1283
		return $this->get_prop( 'address', $context );
1284
    }
1285
1286
    /**
1287
	 * Alias of self::get_address().
1288
	 *
1289
	 * @since 1.0.19
1290
	 * @param  string $context View or edit context.
1291
	 * @return string
1292
	 */
1293
	public function get_user_address( $context = 'view' ) {
1294
		return $this->get_address( $context );
1295
    }
1296
1297
    /**
1298
	 * Alias of self::get_address().
1299
	 *
1300
	 * @since 1.0.19
1301
	 * @param  string $context View or edit context.
1302
	 * @return string
1303
	 */
1304
	public function get_customer_address( $context = 'view' ) {
1305
		return $this->get_address( $context );
1306
    }
1307
1308
    /**
1309
	 * Get whether the customer has viewed the invoice or not.
1310
	 *
1311
	 * @since 1.0.19
1312
	 * @param  string $context View or edit context.
1313
	 * @return bool
1314
	 */
1315
	public function get_is_viewed( $context = 'view' ) {
1316
		return (bool) $this->get_prop( 'is_viewed', $context );
1317
	}
1318
1319
	/**
1320
	 * Get other recipients for invoice communications.
1321
	 *
1322
	 * @since 1.0.19
1323
	 * @param  string $context View or edit context.
1324
	 * @return bool
1325
	 */
1326
	public function get_email_cc( $context = 'view' ) {
1327
		return $this->get_prop( 'email_cc', $context );
1328
	}
1329
1330
	/**
1331
	 * Get invoice template.
1332
	 *
1333
	 * @since 1.0.19
1334
	 * @param  string $context View or edit context.
1335
	 * @return bool
1336
	 */
1337
	public function get_template( $context = 'view' ) {
1338
		return $this->get_prop( 'template', $context );
1339
	}
1340
1341
	/**
1342
	 * Get invoice source.
1343
	 *
1344
	 * @since 1.0.19
1345
	 * @param  string $context View or edit context.
1346
	 * @return bool
1347
	 */
1348
	public function get_created_via( $context = 'view' ) {
1349
		return $this->get_prop( 'created_via', $context );
1350
	}
1351
1352
	/**
1353
	 * Get whether the customer has confirmed their address.
1354
	 *
1355
	 * @since 1.0.19
1356
	 * @param  string $context View or edit context.
1357
	 * @return bool
1358
	 */
1359
	public function get_address_confirmed( $context = 'view' ) {
1360
		return (bool) $this->get_prop( 'address_confirmed', $context );
1361
    }
1362
1363
    /**
1364
	 * Alias of self::get_address_confirmed().
1365
	 *
1366
	 * @since 1.0.19
1367
	 * @param  string $context View or edit context.
1368
	 * @return bool
1369
	 */
1370
	public function get_user_address_confirmed( $context = 'view' ) {
1371
		return $this->get_address_confirmed( $context );
1372
    }
1373
1374
    /**
1375
	 * Alias of self::get_address().
1376
	 *
1377
	 * @since 1.0.19
1378
	 * @param  string $context View or edit context.
1379
	 * @return bool
1380
	 */
1381
	public function get_customer_address_confirmed( $context = 'view' ) {
1382
		return $this->get_address_confirmed( $context );
1383
    }
1384
1385
	/**
1386
	 * Get the shipping address.
1387
	 *
1388
	 * @since 1.0.19
1389
	 * @return array|false
1390
	 */
1391
	public function get_shipping_address() {
1392
1393
		$shipping_address = get_post_meta( $this->get_id(), 'shipping_address', true );
1394
		return is_array( $shipping_address ) ? $shipping_address : false;
1395
    }
1396
1397
	/**
1398
	 * Check if the invoice has a shipping address.
1399
	 */
1400
	public function has_shipping_address() {
1401
		return false !== $this->get_shipping_address();
1402
    }
1403
1404
	/**
1405
	 * Get the shipping amount.
1406
	 *
1407
	 * @since 1.0.19
1408
	 * @param  string $context View or edit context.
1409
	 * @return float
1410
	 */
1411
	public function get_shipping( $context = 'view' ) {
1412
1413
		if ( $context = 'view' ) {
1414
			return floatval( $this->get_prop( 'shipping', $context ) );
1415
		}
1416
1417
		return $this->get_prop( 'shipping', $context );
1418
    }
1419
1420
	public function has_shipping() {
1421
		return defined( 'GETPAID_SHIPPING_CALCULATOR_VERSION' ) && null !== $this->get_prop( 'shipping', 'edit' );
1422
    }
1423
1424
    /**
1425
	 * Get the invoice subtotal.
1426
	 *
1427
	 * @since 1.0.19
1428
	 * @param  string $context View or edit context.
1429
	 * @return float
1430
	 */
1431
	public function get_subtotal( $context = 'view' ) {
1432
        $subtotal = (float) $this->get_prop( 'subtotal', $context );
1433
1434
        // Backwards compatibility.
1435
        if ( is_bool( $context ) && $context ) {
0 ignored issues
show
introduced by
The condition is_bool($context) is always false.
Loading history...
1436
            return wpinv_price( $subtotal, $this->get_currency() );
1437
        }
1438
1439
        return $subtotal;
1440
    }
1441
1442
    /**
1443
	 * Get the invoice discount total.
1444
	 *
1445
	 * @since 1.0.19
1446
	 * @param  string $context View or edit context.
1447
	 * @return float
1448
	 */
1449
	public function get_total_discount( $context = 'view' ) {
1450
		return wpinv_round_amount( wpinv_sanitize_amount( $this->get_prop( 'total_discount', $context ) ) );
1451
    }
1452
1453
    /**
1454
	 * Get the invoice tax total.
1455
	 *
1456
	 * @since 1.0.19
1457
	 * @param  string $context View or edit context.
1458
	 * @return float
1459
	 */
1460
	public function get_total_tax( $context = 'view' ) {
1461
		return wpinv_round_amount( wpinv_sanitize_amount( $this->get_prop( 'total_tax', $context ) ) );
1462
	}
1463
1464
	/**
1465
	 * @deprecated
1466
	 */
1467
	public function get_final_tax( $currency = false ) {
1468
		$tax = $this->get_total_tax();
1469
1470
        if ( $currency ) {
1471
			return wpinv_price( $tax, $this->get_currency() );
1472
        }
1473
1474
        return $tax;
1475
    }
1476
1477
    /**
1478
	 * Get the invoice fees total.
1479
	 *
1480
	 * @since 1.0.19
1481
	 * @param  string $context View or edit context.
1482
	 * @return float
1483
	 */
1484
	public function get_total_fees( $context = 'view' ) {
1485
		return wpinv_round_amount( wpinv_sanitize_amount( $this->get_prop( 'total_fees', $context ) ) );
1486
    }
1487
1488
    /**
1489
	 * Alias for self::get_total_fees().
1490
	 *
1491
	 * @since 1.0.19
1492
	 * @param  string $context View or edit context.
1493
	 * @return float
1494
	 */
1495
	public function get_fees_total( $context = 'view' ) {
1496
		return $this->get_total_fees( $context );
1497
    }
1498
1499
    /**
1500
	 * Get the invoice total.
1501
	 *
1502
	 * @since 1.0.19
1503
     * @return float
1504
	 */
1505
	public function get_total( $context = 'view' ) {
1506
		$total = $this->get_prop( 'total', $context );
1507
1508
		if ( $this->has_shipping() && $context == 'view' ) {
1509
			$total = $this->get_prop( 'total', $context ) + $this->get_shipping( $context );
1510
		}
1511
1512
		return wpinv_round_amount( wpinv_sanitize_amount( $total ) );
1513
	}
1514
1515
	/**
1516
	 * Retrieves the non-recurring total of items.
1517
	 *
1518
	 * @since 2.3.0
1519
	 * @return float
1520
	 */
1521
	public function get_non_recurring_total() {
1522
1523
		$subtotal = 0;
1524
		foreach ( $this->get_items() as $item ) {
1525
			if ( ! $item->is_recurring() ) {
1526
				$subtotal += $item->get_sub_total();
1527
			}
1528
		}
1529
1530
		foreach ( $this->get_fees() as $fee ) {
1531
			if ( empty( $fee['recurring_fee'] ) ) {
1532
				$subtotal += wpinv_sanitize_amount( $fee['initial_fee'] );
1533
			}
1534
		}
1535
1536
		$subtotal = wpinv_round_amount( wpinv_sanitize_amount( $subtotal ) );
1537
        return apply_filters( 'wpinv_get_non_recurring_invoice_total', $subtotal, $this );
1538
1539
    }
1540
1541
	/**
1542
	 * Get the invoice totals.
1543
	 *
1544
	 * @since 1.0.19
1545
     * @return array
1546
	 */
1547
	public function get_totals() {
1548
		return $this->totals;
1549
    }
1550
1551
    /**
1552
	 * Get the initial invoice total.
1553
	 *
1554
	 * @since 1.0.19
1555
     * @param  string $context View or edit context.
1556
     * @return float
1557
	 */
1558
    public function get_initial_total() {
1559
1560
		if ( empty( $this->totals ) ) {
1561
			$this->recalculate_total();
1562
		}
1563
1564
		$tax      = $this->totals['tax']['initial'];
1565
		$fee      = $this->totals['fee']['initial'];
1566
		$discount = $this->totals['discount']['initial'];
1567
		$subtotal = $this->totals['subtotal']['initial'];
1568
		$total    = $tax + $fee - $discount + $subtotal;
1569
1570
		if ( 0 > $total ) {
1571
			$total = 0;
1572
		}
1573
1574
		$total = wpinv_round_amount( wpinv_sanitize_amount( $total ) );
1575
        return apply_filters( 'wpinv_get_initial_invoice_total', $total, $this );
1576
	}
1577
1578
	/**
1579
	 * Get the recurring invoice total.
1580
	 *
1581
	 * @since 1.0.19
1582
     * @param  string $context View or edit context.
1583
     * @return float
1584
	 */
1585
    public function get_recurring_total() {
1586
1587
		if ( empty( $this->totals ) ) {
1588
			$this->recalculate_total();
1589
		}
1590
1591
		$tax      = $this->totals['tax']['recurring'];
1592
		$fee      = $this->totals['fee']['recurring'];
1593
		$discount = $this->totals['discount']['recurring'];
1594
		$subtotal = $this->totals['subtotal']['recurring'];
1595
		$total    = $tax + $fee - $discount + $subtotal;
1596
1597
		if ( 0 > $total ) {
1598
			$total = 0;
1599
		}
1600
1601
		$total = wpinv_round_amount( wpinv_sanitize_amount( $total ) );
1602
        return apply_filters( 'wpinv_get_recurring_invoice_total', $total, $this );
1603
	}
1604
1605
	/**
1606
	 * Returns recurring payment details.
1607
	 *
1608
	 * @since 1.0.19
1609
     * @param  string $field Optionally provide a field to return.
1610
	 * @param string $currency Whether to include the currency.
1611
     * @return float|string
1612
	 */
1613
    public function get_recurring_details( $field = '', $currency = false ) {
1614
1615
		// Maybe recalculate totals.
1616
		if ( empty( $this->totals ) ) {
1617
			$this->recalculate_total();
1618
		}
1619
1620
		// Prepare recurring totals.
1621
        $data = apply_filters(
1622
			'wpinv_get_invoice_recurring_details',
1623
			array(
1624
				'cart_details' => $this->get_cart_details(),
1625
				'subtotal'     => $this->totals['subtotal']['recurring'],
1626
				'discount'     => $this->totals['discount']['recurring'],
1627
				'tax'          => $this->totals['tax']['recurring'],
1628
				'fee'          => $this->totals['fee']['recurring'],
1629
				'total'        => $this->get_recurring_total(),
1630
			),
1631
			$this,
1632
			$field,
1633
			$currency
1634
		);
1635
1636
        if ( isset( $data[ $field ] ) ) {
1637
            return ( $currency ? wpinv_price( $data[ $field ], $this->get_currency() ) : $data[ $field ] );
1638
        }
1639
1640
        return $data;
1641
    }
1642
1643
    /**
1644
	 * Get the invoice fees.
1645
	 *
1646
	 * @since 1.0.19
1647
	 * @param  string $context View or edit context.
1648
	 * @return array
1649
	 */
1650
	public function get_fees( $context = 'view' ) {
1651
		return wpinv_parse_list( $this->get_prop( 'fees', $context ) );
1652
    }
1653
1654
    /**
1655
	 * Get the invoice discounts.
1656
	 *
1657
	 * @since 1.0.19
1658
	 * @param  string $context View or edit context.
1659
	 * @return array
1660
	 */
1661
	public function get_discounts( $context = 'view' ) {
1662
		return wpinv_parse_list( $this->get_prop( 'discounts', $context ) );
1663
    }
1664
1665
    /**
1666
	 * Get the invoice taxes.
1667
	 *
1668
	 * @since 1.0.19
1669
	 * @param  string $context View or edit context.
1670
	 * @return array
1671
	 */
1672
	public function get_taxes( $context = 'view' ) {
1673
		return wpinv_parse_list( $this->get_prop( 'taxes', $context ) );
1674
    }
1675
1676
    /**
1677
	 * Get the invoice items.
1678
	 *
1679
	 * @since 1.0.19
1680
	 * @param  string $context View or edit context.
1681
	 * @return GetPaid_Form_Item[]
1682
	 */
1683
	public function get_items( $context = 'view' ) {
1684
        return $this->get_prop( 'items', $context );
1685
	}
1686
1687
	/**
1688
	 * Get the invoice item ids.
1689
	 *
1690
	 * @since 1.0.19
1691
	 * @return string
1692
	 */
1693
	public function get_item_ids() {
1694
		return implode( ', ', wp_list_pluck( $this->get_cart_details(), 'item_id' ) );
1695
    }
1696
1697
    /**
1698
	 * Get the invoice's payment form.
1699
	 *
1700
	 * @since 1.0.19
1701
	 * @param  string $context View or edit context.
1702
	 * @return int
1703
	 */
1704
	public function get_payment_form( $context = 'view' ) {
1705
		return intval( $this->get_prop( 'payment_form', $context ) );
1706
    }
1707
1708
    /**
1709
	 * Get the invoice's submission id.
1710
	 *
1711
	 * @since 1.0.19
1712
	 * @param  string $context View or edit context.
1713
	 * @return string
1714
	 */
1715
	public function get_submission_id( $context = 'view' ) {
1716
		return $this->get_prop( 'submission_id', $context );
1717
    }
1718
1719
    /**
1720
	 * Get the invoice's discount code.
1721
	 *
1722
	 * @since 1.0.19
1723
	 * @param  string $context View or edit context.
1724
	 * @return string
1725
	 */
1726
	public function get_discount_code( $context = 'view' ) {
1727
		return $this->get_prop( 'discount_code', $context );
1728
    }
1729
1730
    /**
1731
	 * Get the invoice's gateway.
1732
	 *
1733
	 * @since 1.0.19
1734
	 * @param  string $context View or edit context.
1735
	 * @return string
1736
	 */
1737
	public function get_gateway( $context = 'view' ) {
1738
		return $this->get_prop( 'gateway', $context );
1739
    }
1740
1741
    /**
1742
	 * Get the invoice's gateway display title.
1743
	 *
1744
	 * @since 1.0.19
1745
	 * @return string
1746
	 */
1747
    public function get_gateway_title() {
1748
        $title = wpinv_get_gateway_checkout_label( $this->get_gateway() );
1749
        return apply_filters( 'wpinv_gateway_title', $title, $this->get_id(), $this );
1750
    }
1751
1752
    /**
1753
	 * Get the invoice's transaction id.
1754
	 *
1755
	 * @since 1.0.19
1756
	 * @param  string $context View or edit context.
1757
	 * @return string
1758
	 */
1759
	public function get_transaction_id( $context = 'view' ) {
1760
		return $this->get_prop( 'transaction_id', $context );
1761
    }
1762
1763
    /**
1764
	 * Get the invoice's currency.
1765
	 *
1766
	 * @since 1.0.19
1767
	 * @param  string $context View or edit context.
1768
	 * @return string
1769
	 */
1770
	public function get_currency( $context = 'view' ) {
1771
        $currency = $this->get_prop( 'currency', $context );
1772
        return empty( $currency ) ? wpinv_get_currency() : $currency;
1773
    }
1774
1775
    /**
1776
	 * Checks if we are charging taxes for this invoice.
1777
	 *
1778
	 * @since 1.0.19
1779
	 * @param  string $context View or edit context.
1780
	 * @return bool
1781
	 */
1782
	public function get_disable_taxes( $context = 'view' ) {
1783
        return (bool) $this->get_prop( 'disable_taxes', $context );
1784
    }
1785
1786
    /**
1787
	 * Retrieves the subscription id for an invoice.
1788
	 *
1789
	 * @since 1.0.19
1790
	 * @param  string $context View or edit context.
1791
	 * @return int
1792
	 */
1793
    public function get_subscription_id( $context = 'view' ) {
1794
		return $this->is_renewal() ? $this->get_parent()->get_subscription_id( $context ) : $this->get_prop( 'subscription_id', $context );
1795
	}
1796
1797
	/**
1798
	 * Retrieves the remote subscription id for an invoice.
1799
	 *
1800
	 * @since 1.0.19
1801
	 * @param  string $context View or edit context.
1802
	 * @return int
1803
	 */
1804
    public function get_remote_subscription_id( $context = 'view' ) {
1805
        $subscription_id = $this->get_prop( 'remote_subscription_id', $context );
1806
1807
        if ( empty( $subscription_id ) && $this->is_renewal() ) {
1808
            $parent = $this->get_parent();
1809
            return $parent->get_remote_subscription_id( $context );
1810
        }
1811
1812
        return $subscription_id;
1813
    }
1814
1815
    /**
1816
	 * Retrieves the payment meta for an invoice.
1817
	 *
1818
	 * @since 1.0.19
1819
	 * @param  string $context View or edit context.
1820
	 * @return array
1821
	 */
1822
    public function get_payment_meta( $context = 'view' ) {
1823
1824
        return array(
1825
            'price'        => $this->get_total( $context ),
1826
            'date'         => $this->get_date_created( $context ),
1827
            'user_email'   => $this->get_email( $context ),
1828
            'invoice_key'  => $this->get_key( $context ),
1829
            'currency'     => $this->get_currency( $context ),
1830
            'items'        => $this->get_items( $context ),
1831
            'user_info'    => $this->get_user_info( $context ),
1832
            'cart_details' => $this->get_cart_details(),
1833
            'status'       => $this->get_status( $context ),
1834
            'fees'         => $this->get_fees( $context ),
1835
            'taxes'        => $this->get_taxes( $context ),
1836
        );
1837
1838
    }
1839
1840
    /**
1841
	 * Retrieves the cart details for an invoice.
1842
	 *
1843
	 * @since 1.0.19
1844
	 * @return array
1845
	 */
1846
    public function get_cart_details() {
1847
        $items        = $this->get_items();
1848
        $cart_details = array();
1849
1850
        foreach ( $items as $item ) {
1851
			$item->invoice_id = $this->get_id();
1852
            $cart_details[]   = $item->prepare_data_for_saving();
1853
        }
1854
1855
        return $cart_details;
1856
	}
1857
1858
	/**
1859
	 * Retrieves the recurring item.
1860
	 *
1861
	 * @return null|GetPaid_Form_Item|int
1862
	 */
1863
	public function get_recurring( $object = false ) {
1864
1865
		// Are we returning an object?
1866
        if ( $object ) {
1867
            return $this->get_item( $this->recurring_item );
1868
        }
1869
1870
        return $this->recurring_item;
1871
    }
1872
1873
	/**
1874
	 * Retrieves the subscription name.
1875
	 *
1876
	 * @since 1.0.19
1877
	 * @return string
1878
	 */
1879
	public function get_subscription_name() {
1880
1881
		// Retrieve the recurring name
1882
        $item = $this->get_recurring( true );
1883
1884
		// Abort if it does not exist.
1885
        if ( empty( $item ) ) {
1886
            return '';
1887
        }
1888
1889
		// Return the item name.
1890
        return apply_filters( 'wpinv_invoice_get_subscription_name', $item->get_name(), $this );
1891
	}
1892
1893
	/**
1894
	 * Retrieves the view url.
1895
	 *
1896
	 * @since 1.0.19
1897
	 * @return string
1898
	 */
1899
	public function get_view_url() {
1900
        $invoice_url = get_permalink( $this->get_id() );
1901
		$invoice_url = add_query_arg( 'invoice_key', $this->get_key(), $invoice_url );
1902
        return apply_filters( 'wpinv_get_view_url', $invoice_url, $this );
1903
	}
1904
1905
	/**
1906
	 * Retrieves the payment url.
1907
	 *
1908
	 * @since 1.0.19
1909
	 * @return string
1910
	 */
1911
	public function get_checkout_payment_url( $deprecated = false, $secret = false ) {
1912
1913
		// Retrieve the checkout url.
1914
        $pay_url = wpinv_get_checkout_uri();
1915
1916
		// Maybe force ssl.
1917
        if ( is_ssl() ) {
1918
            $pay_url = str_replace( 'http:', 'https:', $pay_url );
1919
        }
1920
1921
		// Add the invoice key.
1922
		$pay_url = add_query_arg( 'invoice_key', $this->get_key(), $pay_url );
1923
1924
		// (Maybe?) add a secret
1925
        if ( $secret ) {
1926
            $pay_url = add_query_arg( array( '_wpipay' => md5( $this->get_user_id() . '::' . $this->get_email() . '::' . $this->get_key() ) ), $pay_url );
1927
        }
1928
1929
        return apply_filters( 'wpinv_get_checkout_payment_url', $pay_url, $this, $deprecated, $secret );
1930
	}
1931
1932
	/**
1933
	 * Retrieves the receipt url.
1934
	 *
1935
	 * @since 1.0.19
1936
	 * @return string
1937
	 */
1938
	public function get_receipt_url() {
1939
1940
		// Retrieve the checkout url.
1941
        $receipt_url = wpinv_get_success_page_uri();
1942
1943
		// Maybe force ssl.
1944
        if ( is_ssl() ) {
1945
            $receipt_url = str_replace( 'http:', 'https:', $receipt_url );
1946
        }
1947
1948
		// Add the invoice key.
1949
		$receipt_url = add_query_arg( 'invoice_key', $this->get_key(), $receipt_url );
1950
1951
        return apply_filters( 'getpaid_get_invoice_receipt_url', $receipt_url, $this );
1952
	}
1953
1954
	/**
1955
	 * Retrieves the remote transaction url.
1956
	 *
1957
	 * @since 1.6.0
1958
	 * @return string
1959
	 */
1960
	public function get_transaction_url() {
1961
		return apply_filters( 'getpaid_gateway_' . $this->get_gateway() . '_transaction_url', '', $this );
1962
	}
1963
1964
	/**
1965
	 * Retrieves the default status.
1966
	 *
1967
	 * @since 1.0.19
1968
	 * @return string
1969
	 */
1970
	public function get_default_status() {
1971
1972
		$type   = $this->get_type();
1973
		$status = "wpi-$type-pending";
1974
		return str_replace( '-invoice', '', $status );
1975
1976
	}
1977
1978
    /**
1979
	 * Magic method for accessing invoice properties.
1980
	 *
1981
	 * @since 1.0.15
1982
	 * @access public
1983
	 *
1984
	 * @param string $key Discount data to retrieve
1985
	 * @param  string $context View or edit context.
1986
	 * @return mixed Value of the given invoice property (if set).
1987
	 */
1988
	public function get( $key, $context = 'view' ) {
1989
		$method = "get_$key";
1990
1991
		if ( is_callable( array( $this, $method ) ) ) {
1992
			return $this->$method( $context );
1993
		}
1994
1995
        return $this->get_prop( $key, $context );
1996
	}
1997
1998
    /*
1999
	|--------------------------------------------------------------------------
2000
	| Setters
2001
	|--------------------------------------------------------------------------
2002
	|
2003
	| Functions for setting item data. These should not update anything in the
2004
	| database itself and should only change what is stored in the class
2005
	| object.
2006
    */
2007
2008
    /**
2009
	 * Magic method for setting invoice properties.
2010
	 *
2011
	 * @since 1.0.19
2012
	 * @access public
2013
	 *
2014
	 * @param string $key Discount data to retrieve
2015
	 * @param  mixed $value new value.
2016
	 * @return mixed Value of the given invoice property (if set).
2017
	 */
2018
	public function set( $key, $value ) {
2019
2020
        $setter = "set_$key";
2021
        if ( is_callable( array( $this, $setter ) ) ) {
2022
            $this->{$setter}( $value );
2023
        }
2024
2025
	}
2026
2027
	/**
2028
	 * Sets item status.
2029
	 *
2030
	 * @since 1.0.19
2031
	 * @param string $new_status    New status.
2032
	 * @param string $note          Optional note to add.
2033
	 * @param bool   $manual_update Is this a manual status change?.
2034
	 * @return array details of change.
2035
	 */
2036
	public function set_status( $new_status, $note = '', $manual_update = false ) {
2037
		$old_status = $this->get_status();
2038
2039
		$statuses = $this->get_all_statuses();
2040
2041
		if ( isset( $statuses['draft'] ) ) {
2042
			unset( $statuses['draft'] );
2043
		}
2044
2045
		$this->set_prop( 'status', $new_status );
2046
2047
		// If setting the status, ensure it's set to a valid status.
2048
		if ( true === $this->object_read ) {
2049
2050
			// Only allow valid new status.
2051
			if ( ! array_key_exists( $new_status, $statuses ) ) {
2052
				$new_status = $this->get_default_status();
2053
			}
2054
2055
			// If the old status is set but unknown (e.g. draft) assume its pending for action usage.
2056
			if ( $old_status && ! array_key_exists( $new_status, $statuses ) ) {
2057
				$old_status = $this->get_default_status();
2058
			}
2059
2060
			// Paid - Renewal (i.e when duplicating a parent invoice )
2061
			if ( $new_status == 'wpi-pending' && $old_status == 'publish' && ! $this->get_id() ) {
2062
				$old_status = 'wpi-pending';
2063
			}
2064
2065
			if ( $old_status !== $new_status ) {
2066
				$this->status_transition = array(
2067
					'from'   => ! empty( $this->status_transition['from'] ) ? $this->status_transition['from'] : $old_status,
2068
					'to'     => $new_status,
2069
					'note'   => $note,
2070
					'manual' => (bool) $manual_update,
2071
				);
2072
2073
				if ( $manual_update ) {
2074
					do_action( 'getpaid_' . $this->object_type . '_edit_status', $this->get_id(), $new_status );
2075
				}
2076
2077
				$this->maybe_set_date_paid();
2078
2079
			}
2080
		}
2081
2082
		return array(
2083
			'from' => $old_status,
2084
			'to'   => $new_status,
2085
		);
2086
	}
2087
2088
	/**
2089
	 * Maybe set date paid.
2090
	 *
2091
	 * Sets the date paid variable when transitioning to the payment complete
2092
	 * order status.
2093
	 *
2094
	 * @since 1.0.19
2095
	 */
2096
	public function maybe_set_date_paid() {
2097
2098
		if ( ! $this->get_date_completed( 'edit' ) && $this->is_paid() ) {
2099
			$this->set_date_completed( current_time( 'mysql' ) );
2100
		}
2101
	}
2102
2103
    /**
2104
	 * Set parent invoice ID.
2105
	 *
2106
	 * @since 1.0.19
2107
	 */
2108
	public function set_parent_id( $value ) {
2109
		if ( $value && ( $value === $this->get_id() ) ) {
2110
			return;
2111
		}
2112
		$this->set_prop( 'parent_id', absint( $value ) );
2113
    }
2114
2115
    /**
2116
	 * Set plugin version when the invoice was created.
2117
	 *
2118
	 * @since 1.0.19
2119
	 */
2120
	public function set_version( $value ) {
2121
		$this->set_prop( 'version', $value );
2122
    }
2123
2124
    /**
2125
	 * Set date when the invoice was created.
2126
	 *
2127
	 * @since 1.0.19
2128
	 * @param string $value Value to set.
2129
     * @return bool Whether or not the date was set.
2130
	 */
2131
	public function set_date_created( $value ) {
2132
        $date = strtotime( $value );
2133
2134
        if ( $date && $value !== '0000-00-00 00:00:00' ) {
2135
            $this->set_prop( 'date_created', date( 'Y-m-d H:i:s', $date ) );
2136
            return true;
2137
        }
2138
2139
		$this->set_prop( 'date_created', '' );
2140
		return false;
2141
2142
    }
2143
2144
    /**
2145
	 * Set date invoice due date.
2146
	 *
2147
	 * @since 1.0.19
2148
	 * @param string $value Value to set.
2149
     * @return bool Whether or not the date was set.
2150
	 */
2151
	public function set_due_date( $value ) {
2152
        $date = strtotime( $value );
2153
2154
        if ( $date && $value !== '0000-00-00 00:00:00' ) {
2155
            $this->set_prop( 'due_date', date( 'Y-m-d H:i:s', $date ) );
2156
            return true;
2157
        }
2158
2159
		$this->set_prop( 'due_date', '' );
2160
        return false;
2161
2162
    }
2163
2164
    /**
2165
	 * Alias of self::set_due_date().
2166
	 *
2167
	 * @since 1.0.19
2168
	 * @param  string $value New name.
2169
	 */
2170
	public function set_date_due( $value ) {
2171
		$this->set_due_date( $value );
2172
    }
2173
2174
    /**
2175
	 * Set date invoice was completed.
2176
	 *
2177
	 * @since 1.0.19
2178
	 * @param string $value Value to set.
2179
     * @return bool Whether or not the date was set.
2180
	 */
2181
	public function set_completed_date( $value ) {
2182
        $date = strtotime( $value );
2183
2184
        if ( $date && $value !== '0000-00-00 00:00:00' ) {
2185
            $this->set_prop( 'completed_date', date( 'Y-m-d H:i:s', $date ) );
2186
            return true;
2187
        }
2188
2189
		$this->set_prop( 'completed_date', '' );
2190
        return false;
2191
2192
    }
2193
2194
    /**
2195
	 * Alias of self::set_completed_date().
2196
	 *
2197
	 * @since 1.0.19
2198
	 * @param  string $value New name.
2199
	 */
2200
	public function set_date_completed( $value ) {
2201
		$this->set_completed_date( $value );
2202
    }
2203
2204
    /**
2205
	 * Set date when the invoice was last modified.
2206
	 *
2207
	 * @since 1.0.19
2208
	 * @param string $value Value to set.
2209
     * @return bool Whether or not the date was set.
2210
	 */
2211
	public function set_date_modified( $value ) {
2212
        $date = strtotime( $value );
2213
2214
        if ( $date && $value !== '0000-00-00 00:00:00' ) {
2215
            $this->set_prop( 'date_modified', date( 'Y-m-d H:i:s', $date ) );
2216
            return true;
2217
        }
2218
2219
		$this->set_prop( 'date_modified', '' );
2220
        return false;
2221
2222
    }
2223
2224
    /**
2225
	 * Set the invoice number.
2226
	 *
2227
	 * @since 1.0.19
2228
	 * @param  string $value New number.
2229
	 */
2230
	public function set_number( $value ) {
2231
        $number = sanitize_text_field( $value );
2232
		$this->set_prop( 'number', $number );
2233
    }
2234
2235
    /**
2236
	 * Set the invoice type.
2237
	 *
2238
	 * @since 1.0.19
2239
	 * @param  string $value Type.
2240
	 */
2241
	public function set_type( $value ) {
2242
        $type = sanitize_text_field( str_replace( 'wpi_', '', $value ) );
2243
		$this->set_prop( 'type', $type );
2244
	}
2245
2246
    /**
2247
	 * Set the invoice post type.
2248
	 *
2249
	 * @since 1.0.19
2250
	 * @param  string $value Post type.
2251
	 */
2252
	public function set_post_type( $value ) {
2253
        if ( getpaid_is_invoice_post_type( $value ) ) {
2254
			$this->set_type( $value );
2255
            $this->set_prop( 'post_type', $value );
2256
        }
2257
    }
2258
2259
    /**
2260
	 * Set the invoice key.
2261
	 *
2262
	 * @since 1.0.19
2263
	 * @param  string $value New key.
2264
	 */
2265
	public function set_key( $value ) {
2266
        $key = sanitize_text_field( $value );
2267
		$this->set_prop( 'key', $key );
2268
    }
2269
2270
    /**
2271
	 * Set the invoice mode.
2272
	 *
2273
	 * @since 1.0.19
2274
	 * @param  string $value mode.
2275
	 */
2276
	public function set_mode( $value ) {
2277
        if ( in_array( $value, array( 'live', 'test' ) ) ) {
2278
            $this->set_prop( 'mode', $value );
2279
        }
2280
    }
2281
2282
    /**
2283
	 * Set the invoice path.
2284
	 *
2285
	 * @since 1.0.19
2286
	 * @param  string $value path.
2287
	 */
2288
	public function set_path( $value ) {
2289
        $this->set_prop( 'path', $value );
2290
    }
2291
2292
    /**
2293
	 * Set the invoice name.
2294
	 *
2295
	 * @since 1.0.19
2296
	 * @param  string $value New name.
2297
	 */
2298
	public function set_name( $value ) {
2299
        $name = sanitize_text_field( $value );
2300
		$this->set_prop( 'name', $name );
2301
    }
2302
2303
    /**
2304
	 * Alias of self::set_name().
2305
	 *
2306
	 * @since 1.0.19
2307
	 * @param  string $value New name.
2308
	 */
2309
	public function set_title( $value ) {
2310
		$this->set_name( $value );
2311
    }
2312
2313
    /**
2314
	 * Set the invoice description.
2315
	 *
2316
	 * @since 1.0.19
2317
	 * @param  string $value New description.
2318
	 */
2319
	public function set_description( $value ) {
2320
        $description = wp_kses_post( $value );
2321
		$this->set_prop( 'description', $description );
2322
    }
2323
2324
    /**
2325
	 * Alias of self::set_description().
2326
	 *
2327
	 * @since 1.0.19
2328
	 * @param  string $value New description.
2329
	 */
2330
	public function set_excerpt( $value ) {
2331
		$this->set_description( $value );
2332
    }
2333
2334
    /**
2335
	 * Alias of self::set_description().
2336
	 *
2337
	 * @since 1.0.19
2338
	 * @param  string $value New description.
2339
	 */
2340
	public function set_summary( $value ) {
2341
		$this->set_description( $value );
2342
    }
2343
2344
    /**
2345
	 * Set the receiver of the invoice.
2346
	 *
2347
	 * @since 1.0.19
2348
	 * @param  int $value New author.
2349
	 */
2350
	public function set_author( $value ) {
2351
		$user = get_user_by( 'id', (int) $value );
2352
2353
		if ( $user && $user->ID ) {
2354
			$this->set_prop( 'author', $user->ID );
2355
			$this->set_prop( 'email', $user->user_email );
2356
		}
2357
2358
    }
2359
2360
    /**
2361
	 * Alias of self::set_author().
2362
	 *
2363
	 * @since 1.0.19
2364
	 * @param  int $value New user id.
2365
	 */
2366
	public function set_user_id( $value ) {
2367
		$this->set_author( $value );
2368
    }
2369
2370
    /**
2371
	 * Sets the customer ID.
2372
	 *
2373
	 * @since 1.0.19
2374
	 * @param  int $value New user id.
2375
	 */
2376
	public function set_customer_id( $value ) {
2377
		$this->set_prop( 'customer_id', (int) $value );
2378
    }
2379
2380
    /**
2381
	 * Set the customer's ip.
2382
	 *
2383
	 * @since 1.0.19
2384
	 * @param  string $value ip address.
2385
	 */
2386
	public function set_ip( $value ) {
2387
		$this->set_prop( 'ip', $value );
2388
    }
2389
2390
    /**
2391
	 * Alias of self::set_ip().
2392
	 *
2393
	 * @since 1.0.19
2394
	 * @param  string $value ip address.
2395
	 */
2396
	public function set_user_ip( $value ) {
2397
		$this->set_ip( $value );
2398
    }
2399
2400
    /**
2401
	 * Set the customer's first name.
2402
	 *
2403
	 * @since 1.0.19
2404
	 * @param  string $value first name.
2405
	 */
2406
	public function set_first_name( $value ) {
2407
		$this->set_prop( 'first_name', $value );
2408
    }
2409
2410
    /**
2411
	 * Alias of self::set_first_name().
2412
	 *
2413
	 * @since 1.0.19
2414
	 * @param  string $value first name.
2415
	 */
2416
	public function set_user_first_name( $value ) {
2417
		$this->set_first_name( $value );
2418
    }
2419
2420
    /**
2421
	 * Alias of self::set_first_name().
2422
	 *
2423
	 * @since 1.0.19
2424
	 * @param  string $value first name.
2425
	 */
2426
	public function set_customer_first_name( $value ) {
2427
		$this->set_first_name( $value );
2428
    }
2429
2430
    /**
2431
	 * Set the customer's last name.
2432
	 *
2433
	 * @since 1.0.19
2434
	 * @param  string $value last name.
2435
	 */
2436
	public function set_last_name( $value ) {
2437
		$this->set_prop( 'last_name', $value );
2438
    }
2439
2440
    /**
2441
	 * Alias of self::set_last_name().
2442
	 *
2443
	 * @since 1.0.19
2444
	 * @param  string $value last name.
2445
	 */
2446
	public function set_user_last_name( $value ) {
2447
		$this->set_last_name( $value );
2448
    }
2449
2450
    /**
2451
	 * Alias of self::set_last_name().
2452
	 *
2453
	 * @since 1.0.19
2454
	 * @param  string $value last name.
2455
	 */
2456
	public function set_customer_last_name( $value ) {
2457
		$this->set_last_name( $value );
2458
    }
2459
2460
    /**
2461
	 * Set the customer's phone number.
2462
	 *
2463
	 * @since 1.0.19
2464
	 * @param  string $value phone.
2465
	 */
2466
	public function set_phone( $value ) {
2467
		$this->set_prop( 'phone', $value );
2468
    }
2469
2470
    /**
2471
	 * Alias of self::set_phone().
2472
	 *
2473
	 * @since 1.0.19
2474
	 * @param  string $value phone.
2475
	 */
2476
	public function set_user_phone( $value ) {
2477
		$this->set_phone( $value );
2478
    }
2479
2480
    /**
2481
	 * Alias of self::set_phone().
2482
	 *
2483
	 * @since 1.0.19
2484
	 * @param  string $value phone.
2485
	 */
2486
	public function set_customer_phone( $value ) {
2487
		$this->set_phone( $value );
2488
    }
2489
2490
    /**
2491
	 * Alias of self::set_phone().
2492
	 *
2493
	 * @since 1.0.19
2494
	 * @param  string $value phone.
2495
	 */
2496
	public function set_phone_number( $value ) {
2497
		$this->set_phone( $value );
2498
    }
2499
2500
    /**
2501
	 * Set the customer's email address.
2502
	 *
2503
	 * @since 1.0.19
2504
	 * @param  string $value email address.
2505
	 */
2506
	public function set_email( $value ) {
2507
		$this->set_prop( 'email', $value );
2508
    }
2509
2510
    /**
2511
	 * Alias of self::set_email().
2512
	 *
2513
	 * @since 1.0.19
2514
	 * @param  string $value email address.
2515
	 */
2516
	public function set_user_email( $value ) {
2517
		$this->set_email( $value );
2518
    }
2519
2520
    /**
2521
	 * Alias of self::set_email().
2522
	 *
2523
	 * @since 1.0.19
2524
	 * @param  string $value email address.
2525
	 */
2526
	public function set_email_address( $value ) {
2527
		$this->set_email( $value );
2528
    }
2529
2530
    /**
2531
	 * Alias of self::set_email().
2532
	 *
2533
	 * @since 1.0.19
2534
	 * @param  string $value email address.
2535
	 */
2536
	public function set_customer_email( $value ) {
2537
		$this->set_email( $value );
2538
    }
2539
2540
    /**
2541
	 * Set the customer's country.
2542
	 *
2543
	 * @since 1.0.19
2544
	 * @param  string $value country.
2545
	 */
2546
	public function set_country( $value ) {
2547
		$this->set_prop( 'country', $value );
2548
    }
2549
2550
    /**
2551
	 * Alias of self::set_country().
2552
	 *
2553
	 * @since 1.0.19
2554
	 * @param  string $value country.
2555
	 */
2556
	public function set_user_country( $value ) {
2557
		$this->set_country( $value );
2558
    }
2559
2560
    /**
2561
	 * Alias of self::set_country().
2562
	 *
2563
	 * @since 1.0.19
2564
	 * @param  string $value country.
2565
	 */
2566
	public function set_customer_country( $value ) {
2567
		$this->set_country( $value );
2568
    }
2569
2570
    /**
2571
	 * Set the customer's state.
2572
	 *
2573
	 * @since 1.0.19
2574
	 * @param  string $value state.
2575
	 */
2576
	public function set_state( $value ) {
2577
		$this->set_prop( 'state', $value );
2578
    }
2579
2580
    /**
2581
	 * Alias of self::set_state().
2582
	 *
2583
	 * @since 1.0.19
2584
	 * @param  string $value state.
2585
	 */
2586
	public function set_user_state( $value ) {
2587
		$this->set_state( $value );
2588
    }
2589
2590
    /**
2591
	 * Alias of self::set_state().
2592
	 *
2593
	 * @since 1.0.19
2594
	 * @param  string $value state.
2595
	 */
2596
	public function set_customer_state( $value ) {
2597
		$this->set_state( $value );
2598
    }
2599
2600
    /**
2601
	 * Set the customer's city.
2602
	 *
2603
	 * @since 1.0.19
2604
	 * @param  string $value city.
2605
	 */
2606
	public function set_city( $value ) {
2607
		$this->set_prop( 'city', $value );
2608
    }
2609
2610
    /**
2611
	 * Alias of self::set_city().
2612
	 *
2613
	 * @since 1.0.19
2614
	 * @param  string $value city.
2615
	 */
2616
	public function set_user_city( $value ) {
2617
		$this->set_city( $value );
2618
    }
2619
2620
    /**
2621
	 * Alias of self::set_city().
2622
	 *
2623
	 * @since 1.0.19
2624
	 * @param  string $value city.
2625
	 */
2626
	public function set_customer_city( $value ) {
2627
		$this->set_city( $value );
2628
    }
2629
2630
    /**
2631
	 * Set the customer's zip code.
2632
	 *
2633
	 * @since 1.0.19
2634
	 * @param  string $value zip.
2635
	 */
2636
	public function set_zip( $value ) {
2637
		$this->set_prop( 'zip', $value );
2638
    }
2639
2640
    /**
2641
	 * Alias of self::set_zip().
2642
	 *
2643
	 * @since 1.0.19
2644
	 * @param  string $value zip.
2645
	 */
2646
	public function set_user_zip( $value ) {
2647
		$this->set_zip( $value );
2648
    }
2649
2650
    /**
2651
	 * Alias of self::set_zip().
2652
	 *
2653
	 * @since 1.0.19
2654
	 * @param  string $value zip.
2655
	 */
2656
	public function set_customer_zip( $value ) {
2657
		$this->set_zip( $value );
2658
    }
2659
2660
    /**
2661
	 * Set the customer's company.
2662
	 *
2663
	 * @since 1.0.19
2664
	 * @param  string $value company.
2665
	 */
2666
	public function set_company( $value ) {
2667
		$this->set_prop( 'company', $value );
2668
    }
2669
2670
    /**
2671
	 * Alias of self::set_company().
2672
	 *
2673
	 * @since 1.0.19
2674
	 * @param  string $value company.
2675
	 */
2676
	public function set_user_company( $value ) {
2677
		$this->set_company( $value );
2678
    }
2679
2680
    /**
2681
	 * Alias of self::set_company().
2682
	 *
2683
	 * @since 1.0.19
2684
	 * @param  string $value company.
2685
	 */
2686
	public function set_customer_company( $value ) {
2687
		$this->set_company( $value );
2688
    }
2689
2690
	/**
2691
	 * Set the customer's company id.
2692
	 *
2693
	 * @since 1.0.19
2694
	 * @param  string $value company id.
2695
	 */
2696
	public function set_company_id( $value ) {
2697
		$this->set_prop( 'company_id', $value );
2698
    }
2699
2700
    /**
2701
	 * Set the customer's var number.
2702
	 *
2703
	 * @since 1.0.19
2704
	 * @param  string $value var number.
2705
	 */
2706
	public function set_vat_number( $value ) {
2707
		$this->set_prop( 'vat_number', $value );
2708
    }
2709
2710
    /**
2711
	 * Alias of self::set_vat_number().
2712
	 *
2713
	 * @since 1.0.19
2714
	 * @param  string $value var number.
2715
	 */
2716
	public function set_user_vat_number( $value ) {
2717
		$this->set_vat_number( $value );
2718
    }
2719
2720
    /**
2721
	 * Alias of self::set_vat_number().
2722
	 *
2723
	 * @since 1.0.19
2724
	 * @param  string $value var number.
2725
	 */
2726
	public function set_customer_vat_number( $value ) {
2727
		$this->set_vat_number( $value );
2728
    }
2729
2730
    /**
2731
	 * Set the customer's vat rate.
2732
	 *
2733
	 * @since 1.0.19
2734
	 * @param  string $value var rate.
2735
	 */
2736
	public function set_vat_rate( $value ) {
2737
		$this->set_prop( 'vat_rate', $value );
2738
    }
2739
2740
    /**
2741
	 * Alias of self::set_vat_rate().
2742
	 *
2743
	 * @since 1.0.19
2744
	 * @param  string $value var number.
2745
	 */
2746
	public function set_user_vat_rate( $value ) {
2747
		$this->set_vat_rate( $value );
2748
    }
2749
2750
    /**
2751
	 * Alias of self::set_vat_rate().
2752
	 *
2753
	 * @since 1.0.19
2754
	 * @param  string $value var number.
2755
	 */
2756
	public function set_customer_vat_rate( $value ) {
2757
		$this->set_vat_rate( $value );
2758
    }
2759
2760
    /**
2761
	 * Set the customer's address.
2762
	 *
2763
	 * @since 1.0.19
2764
	 * @param  string $value address.
2765
	 */
2766
	public function set_address( $value ) {
2767
		$this->set_prop( 'address', $value );
2768
    }
2769
2770
    /**
2771
	 * Alias of self::set_address().
2772
	 *
2773
	 * @since 1.0.19
2774
	 * @param  string $value address.
2775
	 */
2776
	public function set_user_address( $value ) {
2777
		$this->set_address( $value );
2778
    }
2779
2780
    /**
2781
	 * Alias of self::set_address().
2782
	 *
2783
	 * @since 1.0.19
2784
	 * @param  string $value address.
2785
	 */
2786
	public function set_customer_address( $value ) {
2787
		$this->set_address( $value );
2788
    }
2789
2790
    /**
2791
	 * Set whether the customer has viewed the invoice or not.
2792
	 *
2793
	 * @since 1.0.19
2794
	 * @param  int|bool $value confirmed.
2795
	 */
2796
	public function set_is_viewed( $value ) {
2797
		$this->set_prop( 'is_viewed', $value );
2798
	}
2799
2800
	/**
2801
	 * Set extra email recipients.
2802
	 *
2803
	 * @since 1.0.19
2804
	 * @param  string $value email recipients.
2805
	 */
2806
	public function set_email_cc( $value ) {
2807
		$this->set_prop( 'email_cc', $value );
2808
	}
2809
2810
	/**
2811
	 * Set the invoice template.
2812
	 *
2813
	 * @since 1.0.19
2814
	 * @param  string $value template.
2815
	 */
2816
	public function set_template( $value ) {
2817
		if ( in_array( $value, array( 'quantity', 'hours', 'amount' ) ) ) {
2818
			$this->set_prop( 'template', $value );
2819
		}
2820
	}
2821
2822
	/**
2823
	 * Set the invoice source.
2824
	 *
2825
	 * @since 1.0.19
2826
	 * @param  string $value source.
2827
	 * @deprecated
2828
	 */
2829
	public function created_via( $value ) {
2830
		$this->set_created_via( sanitize_text_field( $value ) );
2831
	}
2832
2833
	/**
2834
	 * Set the invoice source.
2835
	 *
2836
	 * @since 1.0.19
2837
	 * @param  string $value source.
2838
	 */
2839
	public function set_created_via( $value ) {
2840
		$this->set_prop( 'created_via', sanitize_text_field( $value ) );
2841
	}
2842
2843
	/**
2844
	 * Set the customer's address confirmed status.
2845
	 *
2846
	 * @since 1.0.19
2847
	 * @param  int|bool $value confirmed.
2848
	 */
2849
	public function set_address_confirmed( $value ) {
2850
		$this->set_prop( 'address_confirmed', $value );
2851
    }
2852
2853
    /**
2854
	 * Alias of self::set_address_confirmed().
2855
	 *
2856
	 * @since 1.0.19
2857
	 * @param  int|bool $value confirmed.
2858
	 */
2859
	public function set_user_address_confirmed( $value ) {
2860
		$this->set_address_confirmed( $value );
2861
    }
2862
2863
    /**
2864
	 * Alias of self::set_address_confirmed().
2865
	 *
2866
	 * @since 1.0.19
2867
	 * @param  int|bool $value confirmed.
2868
	 */
2869
	public function set_customer_address_confirmed( $value ) {
2870
		$this->set_address_confirmed( $value );
2871
    }
2872
2873
    /**
2874
	 * Set the shipping fee
2875
	 *
2876
	 * @since 1.0.19
2877
	 * @param  float $value shipping amount.
2878
	 */
2879
	public function set_shipping( $value ) {
2880
2881
		if ( ! is_numeric( $value ) ) {
0 ignored issues
show
introduced by
The condition is_numeric($value) is always true.
Loading history...
2882
			return $this->set_prop( 'shipping', null );
2883
		}
2884
2885
		$this->set_prop( 'shipping', max( 0, floatval( $value ) ) );
2886
	}
2887
2888
	/**
2889
	 * Set the invoice sub total.
2890
	 *
2891
	 * @since 1.0.19
2892
	 * @param  float $value sub total.
2893
	 */
2894
	public function set_subtotal( $value ) {
2895
		$this->set_prop( 'subtotal', max( 0, $value ) );
2896
	}
2897
2898
	/**
2899
	 * Set the invoice total.
2900
	 *
2901
	 * @since 1.0.19
2902
	 * @param  float $value sub total.
2903
	 */
2904
	public function set_total( $value ) {
2905
		$this->set_prop( 'total', max( 0, $value ) );
2906
    }
2907
2908
    /**
2909
	 * Set the invoice discount amount.
2910
	 *
2911
	 * @since 1.0.19
2912
	 * @param  float $value discount total.
2913
	 */
2914
	public function set_total_discount( $value ) {
2915
		$this->set_prop( 'total_discount', max( 0, $value ) );
2916
    }
2917
2918
    /**
2919
	 * Alias of self::set_total_discount().
2920
	 *
2921
	 * @since 1.0.19
2922
	 * @param  float $value discount total.
2923
	 */
2924
	public function set_discount( $value ) {
2925
		$this->set_total_discount( $value );
2926
    }
2927
2928
    /**
2929
	 * Set the invoice tax amount.
2930
	 *
2931
	 * @since 1.0.19
2932
	 * @param  float $value tax total.
2933
	 */
2934
	public function set_total_tax( $value ) {
2935
		$this->set_prop( 'total_tax', max( 0, $value ) );
2936
    }
2937
2938
    /**
2939
	 * Alias of self::set_total_tax().
2940
	 *
2941
	 * @since 1.0.19
2942
	 * @param  float $value tax total.
2943
	 */
2944
	public function set_tax_total( $value ) {
2945
		$this->set_total_tax( $value );
2946
    }
2947
2948
    /**
2949
	 * Set the invoice fees amount.
2950
	 *
2951
	 * @since 1.0.19
2952
	 * @param  float $value fees total.
2953
	 */
2954
	public function set_total_fees( $value ) {
2955
		$this->set_prop( 'total_fees', max( 0, $value ) );
2956
    }
2957
2958
    /**
2959
	 * Alias of self::set_total_fees().
2960
	 *
2961
	 * @since 1.0.19
2962
	 * @param  float $value fees total.
2963
	 */
2964
	public function set_fees_total( $value ) {
2965
		$this->set_total_fees( $value );
2966
    }
2967
2968
    /**
2969
	 * Set the invoice fees.
2970
	 *
2971
	 * @since 1.0.19
2972
	 * @param  array $value fees.
2973
	 */
2974
	public function set_fees( $value ) {
2975
2976
		if ( ! is_array( $value ) ) {
0 ignored issues
show
introduced by
The condition is_array($value) is always true.
Loading history...
2977
			$value = array();
2978
		}
2979
2980
		$this->set_prop( 'fees', $value );
2981
2982
    }
2983
2984
    /**
2985
	 * Set the invoice taxes.
2986
	 *
2987
	 * @since 1.0.19
2988
	 * @param  array $value taxes.
2989
	 */
2990
	public function set_taxes( $value ) {
2991
2992
		if ( ! is_array( $value ) ) {
0 ignored issues
show
introduced by
The condition is_array($value) is always true.
Loading history...
2993
			$value = array();
2994
		}
2995
2996
		$this->set_prop( 'taxes', $value );
2997
2998
    }
2999
3000
    /**
3001
	 * Set the invoice discounts.
3002
	 *
3003
	 * @since 1.0.19
3004
	 * @param  array $value discounts.
3005
	 */
3006
	public function set_discounts( $value ) {
3007
3008
		if ( ! is_array( $value ) ) {
0 ignored issues
show
introduced by
The condition is_array($value) is always true.
Loading history...
3009
			$value = array();
3010
		}
3011
3012
		$this->set_prop( 'discounts', $value );
3013
    }
3014
3015
    /**
3016
	 * Set the invoice items.
3017
	 *
3018
	 * @since 1.0.19
3019
	 * @param  GetPaid_Form_Item[] $value items.
3020
	 */
3021
	public function set_items( $value ) {
3022
3023
        // Remove existing items.
3024
        $this->set_prop( 'items', array() );
3025
		$this->recurring_item = null;
3026
3027
        // Ensure that we have an array.
3028
        if ( ! is_array( $value ) ) {
0 ignored issues
show
introduced by
The condition is_array($value) is always true.
Loading history...
3029
            return;
3030
        }
3031
3032
        foreach ( $value as $item ) {
3033
            $this->add_item( $item );
3034
        }
3035
3036
    }
3037
3038
    /**
3039
	 * Set the payment form.
3040
	 *
3041
	 * @since 1.0.19
3042
	 * @param  int $value payment form.
3043
	 */
3044
	public function set_payment_form( $value ) {
3045
		$this->set_prop( 'payment_form', $value );
3046
    }
3047
3048
    /**
3049
	 * Set the submission id.
3050
	 *
3051
	 * @since 1.0.19
3052
	 * @param  string $value submission id.
3053
	 */
3054
	public function set_submission_id( $value ) {
3055
		$this->set_prop( 'submission_id', $value );
3056
    }
3057
3058
    /**
3059
	 * Set the discount code.
3060
	 *
3061
	 * @since 1.0.19
3062
	 * @param  string $value discount code.
3063
	 */
3064
	public function set_discount_code( $value ) {
3065
		$this->set_prop( 'discount_code', sanitize_text_field( $value ) );
3066
    }
3067
3068
    /**
3069
	 * Set the gateway.
3070
	 *
3071
	 * @since 1.0.19
3072
	 * @param  string $value gateway.
3073
	 */
3074
	public function set_gateway( $value ) {
3075
		$this->set_prop( 'gateway', $value );
3076
    }
3077
3078
    /**
3079
	 * Set the transaction id.
3080
	 *
3081
	 * @since 1.0.19
3082
	 * @param  string $value transaction id.
3083
	 */
3084
	public function set_transaction_id( $value ) {
3085
		if ( ! empty( $value ) ) {
3086
			$this->set_prop( 'transaction_id', $value );
3087
		}
3088
    }
3089
3090
    /**
3091
	 * Set the currency id.
3092
	 *
3093
	 * @since 1.0.19
3094
	 * @param  string $value currency id.
3095
	 */
3096
	public function set_currency( $value ) {
3097
		$this->set_prop( 'currency', $value );
3098
    }
3099
3100
	/**
3101
	 * Set whether to disable taxes.
3102
	 *
3103
	 * @since 1.0.19
3104
	 * @param  bool $value value.
3105
	 */
3106
	public function set_disable_taxes( $value ) {
3107
		$this->set_prop( 'disable_taxes', (bool) $value );
3108
	}
3109
3110
    /**
3111
	 * Set the subscription id.
3112
	 *
3113
	 * @since 1.0.19
3114
	 * @param  string $value subscription id.
3115
	 */
3116
	public function set_subscription_id( $value ) {
3117
		$this->set_prop( 'subscription_id', $value );
3118
	}
3119
3120
	/**
3121
	 * Set the remote subscription id.
3122
	 *
3123
	 * @since 1.0.19
3124
	 * @param  string $value subscription id.
3125
	 */
3126
	public function set_remote_subscription_id( $value ) {
3127
		$this->set_prop( 'remote_subscription_id', $value );
3128
    }
3129
3130
    /*
3131
	|--------------------------------------------------------------------------
3132
	| Boolean methods
3133
	|--------------------------------------------------------------------------
3134
	|
3135
	| Return true or false.
3136
	|
3137
    */
3138
3139
    /**
3140
     * Checks if this is a parent invoice.
3141
     */
3142
    public function is_parent() {
3143
        $parent = $this->get_parent_id();
3144
        return apply_filters( 'wpinv_invoice_is_parent', empty( $parent ), $this );
3145
    }
3146
3147
    /**
3148
     * Checks if this is a renewal invoice.
3149
     */
3150
    public function is_renewal() {
3151
        return $this->is_recurring() && ! $this->is_parent();
3152
    }
3153
3154
    /**
3155
     * Checks if this is a recurring invoice.
3156
     */
3157
    public function is_recurring() {
3158
        return ! empty( $this->recurring_item );
3159
    }
3160
3161
    /**
3162
     * Checks if this is a taxable invoice.
3163
     */
3164
    public function is_taxable() {
3165
        return ! $this->get_disable_taxes();
3166
	}
3167
3168
	/**
3169
	 * @deprecated
3170
	 */
3171
	public function has_vat() {
3172
        return $this->is_taxable();
3173
	}
3174
3175
	/**
3176
	 * Checks to see if the invoice requires payment.
3177
	 */
3178
	public function is_free() {
3179
        $is_free = ( (float) wpinv_round_amount( $this->get_initial_total() ) == 0 );
3180
3181
		if ( $this->is_recurring() && $this->get_recurring_total() > 0 ) {
3182
			$is_free = false;
3183
		}
3184
3185
        return apply_filters( 'wpinv_invoice_is_free', $is_free, $this );
3186
    }
3187
3188
    /**
3189
     * Checks if the invoice is paid.
3190
     */
3191
    public function is_paid() {
3192
        $is_paid = $this->has_status( array( 'publish', 'wpi-processing', 'wpi-renewal' ) );
3193
        return apply_filters( 'wpinv_invoice_is_paid', $is_paid, $this );
3194
	}
3195
3196
	/**
3197
     * Checks if the invoice needs payment.
3198
     */
3199
	public function needs_payment() {
3200
		$needs_payment = ! $this->is_paid() && ! $this->is_refunded() && ! $this->is_free();
3201
        return apply_filters( 'wpinv_needs_payment', $needs_payment, $this );
3202
    }
3203
3204
	/**
3205
     * Checks if the invoice is refunded.
3206
     */
3207
	public function is_refunded() {
3208
        $is_refunded = $this->has_status( 'wpi-refunded' );
3209
        return apply_filters( 'wpinv_invoice_is_refunded', $is_refunded, $this );
3210
	}
3211
3212
	/**
3213
     * Checks if the invoice is held.
3214
     */
3215
	public function is_held() {
3216
        $is_held = $this->has_status( 'wpi-onhold' );
3217
        return apply_filters( 'wpinv_invoice_is_held', $is_held, $this );
3218
	}
3219
3220
	/**
3221
     * Checks if the invoice is due.
3222
     */
3223
	public function is_due() {
3224
		$due_date = $this->get_due_date();
3225
		return empty( $due_date ) ? false : current_time( 'timestamp' ) > strtotime( $due_date );
3226
	}
3227
3228
	/**
3229
     * Checks if the invoice is draft.
3230
     */
3231
	public function is_draft() {
3232
        return $this->has_status( 'draft, auto-draft' );
3233
	}
3234
3235
    /**
3236
     * Checks if the invoice has a given status.
3237
     */
3238
    public function has_status( $status ) {
3239
        $status = wpinv_parse_list( $status );
3240
        return apply_filters( 'wpinv_has_status', in_array( $this->get_status(), $status ), $status );
3241
	}
3242
3243
	/**
3244
     * Checks if the invoice is of a given type.
3245
     */
3246
    public function is_type( $type ) {
3247
        $type = wpinv_parse_list( $type );
3248
        return in_array( $this->get_type(), $type );
3249
    }
3250
3251
    /**
3252
     * Checks if this is a quote object.
3253
     *
3254
     * @since 1.0.15
3255
     */
3256
    public function is_quote() {
3257
        return 'wpi_quote' == $this->get_post_type();
3258
    }
3259
3260
    /**
3261
     * Check if the invoice (or it's parent has a free trial).
3262
     *
3263
     */
3264
    public function has_free_trial() {
3265
        return $this->is_recurring() && 0 == $this->get_initial_total();
3266
	}
3267
3268
	/**
3269
     * @deprecated
3270
     */
3271
    public function is_free_trial() {
3272
        return $this->has_free_trial();
3273
    }
3274
3275
	/**
3276
     * Check if the initial payment if 0.
3277
     *
3278
     */
3279
	public function is_initial_free() {
3280
        $is_initial_free = ! ( (float) wpinv_round_amount( $this->get_initial_total() ) > 0 );
3281
        return apply_filters( 'wpinv_invoice_is_initial_free', $is_initial_free, $this->get_cart_details(), $this );
3282
    }
3283
3284
	/**
3285
     * Check if the recurring item has a free trial.
3286
     *
3287
     */
3288
    public function item_has_free_trial() {
3289
3290
        // Ensure we have a recurring item.
3291
        if ( ! $this->is_recurring() ) {
3292
            return false;
3293
        }
3294
3295
        $item = $this->get_recurring( true );
3296
        return $item->has_free_trial();
3297
	}
3298
3299
	/**
3300
     * Check if the free trial is a result of a discount.
3301
     */
3302
    public function is_free_trial_from_discount() {
3303
		return $this->has_free_trial() && ! $this->item_has_free_trial();
3304
	}
3305
3306
	/**
3307
     * @deprecated
3308
     */
3309
    public function discount_first_payment_only() {
3310
3311
		$discount = wpinv_get_discount_obj( $this->get_discount_code() );
3312
        if ( ! $discount->exists() || ! $this->is_recurring() ) {
3313
            return true;
3314
        }
3315
3316
        return ! $discount->get_is_recurring();
3317
    }
3318
3319
    /*
3320
	|--------------------------------------------------------------------------
3321
	| Cart related methods
3322
	|--------------------------------------------------------------------------
3323
	|
3324
	| Do not forget to recalculate totals after calling the following methods.
3325
	|
3326
    */
3327
3328
    /**
3329
     * Adds an item to the invoice.
3330
     *
3331
     * @param GetPaid_Form_Item|array $item
3332
     * @return WP_Error|Bool
3333
     */
3334
    public function add_item( $item ) {
3335
3336
		if ( is_array( $item ) ) {
3337
			$item = $this->process_array_item( $item );
3338
		}
3339
3340
		if ( is_numeric( $item ) ) {
0 ignored issues
show
introduced by
The condition is_numeric($item) is always false.
Loading history...
3341
			$item = new GetPaid_Form_Item( $item );
3342
		}
3343
3344
        // Make sure that it is available for purchase.
3345
		if ( $item->get_id() > 0 && ! $item->can_purchase() ) {
3346
			return new WP_Error( 'invalid_item', __( 'This item is not available for purchase', 'invoicing' ) );
3347
        }
3348
3349
        // Do we have a recurring item?
3350
		if ( $item->is_recurring() ) {
3351
			$this->recurring_item = $item->get_id();
3352
        }
3353
3354
        // Invoice id.
3355
        $item->invoice_id = (int) $this->get_id();
3356
3357
		// Remove duplicates.
3358
		$this->remove_item( $item->get_id() );
3359
3360
		if ( 0 == $item->get_quantity() ) {
3361
			return;
3362
		}
3363
3364
		// Retrieve all items.
3365
        $items   = $this->get_items();
3366
3367
		// Add new item.
3368
        $items[] = $item;
3369
3370
        $this->set_prop( 'items', $items );
3371
3372
		return true;
3373
	}
3374
3375
	/**
3376
	 * Converts an array to an item.
3377
	 *
3378
	 * @since 1.0.19
3379
	 * @return GetPaid_Form_Item
3380
	 */
3381
	protected function process_array_item( $array ) {
3382
3383
		$item_id = isset( $array['item_id'] ) ? $array['item_id'] : 0;
3384
		$item    = new GetPaid_Form_Item( $item_id );
3385
3386
		// Set item data.
3387
		foreach ( array( 'name', 'price', 'description' ) as $key ) {
3388
			if ( isset( $array[ "item_$key" ] ) ) {
3389
				$method = "set_$key";
3390
				$item->$method( $array[ "item_$key" ] );
3391
			}
3392
		}
3393
3394
		if ( isset( $array['quantity'] ) ) {
3395
			$item->set_quantity( $array['quantity'] );
3396
		}
3397
3398
		// Set item meta.
3399
		if ( isset( $array['meta'] ) && is_array( $array['meta'] ) ) {
3400
			$item->set_item_meta( $array['meta'] );
3401
		}
3402
3403
		return $item;
3404
3405
	}
3406
3407
    /**
3408
	 * Retrieves a specific item.
3409
	 *
3410
	 * @since 1.0.19
3411
	 * @return GetPaid_Form_Item|null
3412
	 */
3413
	public function get_item( $item_id ) {
3414
3415
		foreach ( $this->get_items() as $item ) {
3416
			if ( (int) $item_id == $item->get_id() ) {
3417
				return $item;
3418
			}
3419
		}
3420
3421
		return null;
3422
    }
3423
3424
    /**
3425
	 * Removes a specific item.
3426
	 *
3427
	 * @since 1.0.19
3428
	 */
3429
	public function remove_item( $item_id ) {
3430
		$items   = $this->get_items();
3431
		$item_id = (int) $item_id;
3432
3433
		foreach ( $items as $index => $item ) {
3434
			if ( (int) $item_id == $item->get_id() ) {
3435
				unset( $items[ $index ] );
3436
				$this->set_prop( 'items', $items );
3437
3438
				if ( $item_id == $this->recurring_item ) {
3439
					$this->recurring_item = null;
3440
				}
3441
}
3442
		}
3443
3444
    }
3445
3446
    /**
3447
	 * Adds a fee to the invoice.
3448
	 *
3449
	 * @param array $fee An array of fee details. name, initial_fee, and recurring_fee are required.
3450
	 * @since 1.0.19
3451
	 */
3452
    public function add_fee( $fee ) {
3453
3454
		$fees                 = $this->get_fees();
3455
		$fees[ $fee['name'] ] = $fee;
3456
		$this->set_prop( 'fees', $fees );
3457
3458
    }
3459
3460
    /**
3461
	 * Retrieves a specific fee.
3462
	 *
3463
	 * @since 1.0.19
3464
	 */
3465
	public function get_fee( $fee ) {
3466
        $fees = $this->get_fees();
3467
		return isset( $fees[ $fee ] ) ? $fees[ $fee ] : null;
3468
    }
3469
3470
    /**
3471
	 * Removes a specific fee.
3472
	 *
3473
	 * @since 1.0.19
3474
	 */
3475
	public function remove_fee( $fee ) {
3476
        $fees = $this->get_fees();
3477
        if ( isset( $fees[ $fee ] ) ) {
3478
            unset( $fees[ $fee ] );
3479
            $this->set_prop( 'fees', $fees );
3480
        }
3481
    }
3482
3483
	/**
3484
	 * Adds a discount to the invoice.
3485
	 *
3486
	 * @param array $discount An array of discount details. name, initial_discount, and recurring_discount are required. Include discount_code if the discount is from a discount code.
3487
	 * @since 1.0.19
3488
	 */
3489
	public function add_discount( $discount ) {
3490
3491
		$discounts = $this->get_discounts();
3492
		$discounts[ $discount['name'] ] = $discount;
3493
		$this->set_prop( 'discounts', $discounts );
3494
3495
	}
3496
3497
    /**
3498
	 * Retrieves a specific discount.
3499
	 *
3500
	 * @since 1.0.19
3501
	 * @return float
3502
	 */
3503
	public function get_discount( $discount = false ) {
3504
3505
		// Backwards compatibilty.
3506
		if ( empty( $discount ) ) {
3507
			return $this->get_total_discount();
3508
		}
3509
3510
        $discounts = $this->get_discounts();
3511
		return isset( $discounts[ $discount ] ) ? $discounts[ $discount ] : null;
3512
    }
3513
3514
    /**
3515
	 * Removes a specific discount.
3516
	 *
3517
	 * @since 1.0.19
3518
	 */
3519
	public function remove_discount( $discount ) {
3520
        $discounts = $this->get_discounts();
3521
        if ( isset( $discounts[ $discount ] ) ) {
3522
            unset( $discounts[ $discount ] );
3523
            $this->set_prop( 'discounts', $discounts );
3524
        }
3525
3526
		if ( 'discount_code' == $discount ) {
3527
			foreach ( $this->get_items() as $item ) {
3528
				$item->item_discount           = 0;
3529
				$item->recurring_item_discount = 0;
3530
			}
3531
		}
3532
3533
    }
3534
3535
    /**
3536
     * Adds a tax to the invoice.
3537
     *
3538
     * @param array $tax An array of tax details. name, initial_tax, and recurring_tax are required.
3539
     */
3540
    public function add_tax( $tax ) {
3541
        if ( $this->is_taxable() ) {
3542
3543
            $taxes                 = $this->get_taxes();
3544
			$taxes[ $tax['name'] ] = $tax;
3545
			$this->set_prop( 'taxes', $tax );
3546
3547
        }
3548
    }
3549
3550
    /**
3551
	 * Retrieves a specific tax.
3552
	 *
3553
	 * @since 1.0.19
3554
	 */
3555
	public function get_tax( $tax = null ) {
3556
3557
		// Backwards compatility.
3558
		if ( empty( $tax ) ) {
3559
			return $this->get_total_tax();
3560
		}
3561
3562
        $taxes = $this->get_taxes();
3563
		return isset( $taxes[ $tax ] ) ? $taxes[ $tax ] : null;
3564
    }
3565
3566
	public function get_tax_total_by_name( $name ) {
3567
3568
		if ( empty( $name ) ) {
3569
			return 0;
3570
		}
3571
3572
		$tax = $this->get_tax( $name );
3573
3574
		if ( empty( $tax ) ) {
3575
			return 0;
3576
		}
3577
3578
        return $this->is_renewal() ? $tax['recurring_tax'] : $tax['initial_tax'];
3579
    }
3580
3581
    /**
3582
	 * Removes a specific tax.
3583
	 *
3584
	 * @since 1.0.19
3585
	 */
3586
	public function remove_tax( $tax ) {
3587
        $taxes = $this->get_taxes();
3588
        if ( isset( $taxes[ $tax ] ) ) {
3589
            unset( $taxes[ $tax ] );
3590
            $this->set_prop( 'taxes', $taxes );
3591
        }
3592
    }
3593
3594
    /**
3595
	 * Recalculates the invoice subtotal.
3596
	 *
3597
	 * @since 1.0.19
3598
	 * @return float The recalculated subtotal
3599
	 */
3600
	public function recalculate_subtotal() {
3601
        $items     = $this->get_items();
3602
		$subtotal  = 0;
3603
		$recurring = 0;
3604
3605
        foreach ( $items as $item ) {
3606
			$subtotal  += $item->get_sub_total( 'edit' );
3607
			$recurring += $item->get_recurring_sub_total( 'edit' );
3608
        }
3609
3610
		if ( wpinv_prices_include_tax() ) {
3611
			$subtotal  = max( 0, $subtotal - $this->totals['tax']['initial'] );
3612
			$recurring = max( 0, $recurring - $this->totals['tax']['recurring'] );
3613
		}
3614
3615
		$current = $this->is_renewal() ? $recurring : $subtotal;
3616
		$this->set_subtotal( $current );
3617
3618
		$this->totals['subtotal'] = array(
3619
			'initial'   => $subtotal,
3620
			'recurring' => $recurring,
3621
		);
3622
3623
        return $current;
3624
    }
3625
3626
    /**
3627
	 * Recalculates the invoice discount total.
3628
	 *
3629
	 * @since 1.0.19
3630
	 * @return float The recalculated discount
3631
	 */
3632
	public function recalculate_total_discount() {
3633
        $discounts = $this->get_discounts();
3634
		$discount  = 0;
3635
		$recurring = 0;
3636
3637
        foreach ( $discounts as $data ) {
3638
			$discount  += wpinv_sanitize_amount( $data['initial_discount'] );
3639
			$recurring += wpinv_sanitize_amount( $data['recurring_discount'] );
3640
		}
3641
3642
		$current = $this->is_renewal() ? $recurring : $discount;
3643
3644
		$this->set_total_discount( $current );
3645
3646
		$this->totals['discount'] = array(
3647
			'initial'   => $discount,
3648
			'recurring' => $recurring,
3649
		);
3650
3651
		return $current;
3652
3653
    }
3654
3655
    /**
3656
	 * Recalculates the invoice tax total.
3657
	 *
3658
	 * @since 1.0.19
3659
	 * @return float The recalculated tax
3660
	 */
3661
	public function recalculate_total_tax() {
3662
3663
		// Maybe disable taxes.
3664
		$vat_number = $this->get_vat_number();
3665
		$skip_tax   = GetPaid_Payment_Form_Submission_Taxes::is_eu_transaction( $this->get_country() ) && ! empty( $vat_number );
3666
3667
		if ( wpinv_is_base_country( $this->get_country() ) && 'vat_too' === wpinv_get_option( 'vat_same_country_rule', 'vat_too' ) ) {
3668
			$skip_tax = false;
3669
		}
3670
3671
		if ( ! wpinv_use_taxes() || $this->get_disable_taxes() || ! wpinv_is_country_taxable( $this->get_country() ) || $skip_tax ) {
3672
3673
			$this->totals['tax'] = array(
3674
				'initial'   => 0,
3675
				'recurring' => 0,
3676
			);
3677
3678
			$this->tax_rate = 0;
3679
3680
			$this->set_taxes( array() );
3681
			$current = 0;
3682
		} else {
3683
3684
			$item_taxes = array();
3685
3686
			foreach ( $this->get_items() as $item ) {
3687
				$rates    = getpaid_get_item_tax_rates( $item, $this->get_country(), $this->get_state() );
3688
				$rates    = getpaid_filter_item_tax_rates( $item, $rates );
3689
				$taxes    = getpaid_calculate_item_taxes( getpaid_get_taxable_amount( $item, false ), $rates );
0 ignored issues
show
Bug introduced by
getpaid_get_taxable_amount($item, false) of type string is incompatible with the type double expected by parameter $amount of getpaid_calculate_item_taxes(). ( Ignorable by Annotation )

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

3689
				$taxes    = getpaid_calculate_item_taxes( /** @scrutinizer ignore-type */ getpaid_get_taxable_amount( $item, false ), $rates );
Loading history...
Bug introduced by
false of type false is incompatible with the type string expected by parameter $recurring of getpaid_get_taxable_amount(). ( Ignorable by Annotation )

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

3689
				$taxes    = getpaid_calculate_item_taxes( getpaid_get_taxable_amount( $item, /** @scrutinizer ignore-type */ false ), $rates );
Loading history...
3690
				$r_taxes  = getpaid_calculate_item_taxes( getpaid_get_taxable_amount( $item, true ), $rates );
0 ignored issues
show
Bug introduced by
true of type true is incompatible with the type string expected by parameter $recurring of getpaid_get_taxable_amount(). ( Ignorable by Annotation )

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

3690
				$r_taxes  = getpaid_calculate_item_taxes( getpaid_get_taxable_amount( $item, /** @scrutinizer ignore-type */ true ), $rates );
Loading history...
3691
				foreach ( $taxes as $name => $amount ) {
3692
					$recurring = isset( $r_taxes[ $name ] ) ? $r_taxes[ $name ] : 0;
3693
					$tax       = getpaid_prepare_item_tax( $item, $name, $amount, $recurring );
3694
3695
					if ( ! isset( $item_taxes[ $name ] ) ) {
3696
						$item_taxes[ $name ] = $tax;
3697
						continue;
3698
					}
3699
3700
					$item_taxes[ $name ]['initial_tax']   += $tax['initial_tax'];
3701
					$item_taxes[ $name ]['recurring_tax'] += $tax['recurring_tax'];
3702
3703
				}
3704
			}
3705
3706
			$item_taxes = array_replace( $this->get_taxes(), $item_taxes );
3707
			$this->set_taxes( $item_taxes );
3708
3709
			$initial_tax   = array_sum( wp_list_pluck( $item_taxes, 'initial_tax' ) );
3710
			$recurring_tax = array_sum( wp_list_pluck( $item_taxes, 'recurring_tax' ) );
3711
3712
			$current = $this->is_renewal() ? $recurring_tax : $initial_tax;
3713
3714
			$this->totals['tax'] = array(
3715
				'initial'   => $initial_tax,
3716
				'recurring' => $recurring_tax,
3717
			);
3718
3719
		}
3720
3721
		$this->set_total_tax( $current );
3722
3723
		return $current;
3724
3725
    }
3726
3727
    /**
3728
	 * Recalculates the invoice fees total.
3729
	 *
3730
	 * @since 1.0.19
3731
	 * @return float The recalculated fee
3732
	 */
3733
	public function recalculate_total_fees() {
3734
		$fees      = $this->get_fees();
3735
		$fee       = 0;
3736
		$recurring = 0;
3737
3738
        foreach ( $fees as $data ) {
3739
			$fee       += wpinv_sanitize_amount( $data['initial_fee'] );
3740
			$recurring += wpinv_sanitize_amount( $data['recurring_fee'] );
3741
		}
3742
3743
		$current = $this->is_renewal() ? $recurring : $fee;
3744
		$this->set_total_fees( $current );
3745
3746
		$this->totals['fee'] = array(
3747
			'initial'   => $fee,
3748
			'recurring' => $recurring,
3749
		);
3750
3751
        $this->set_total_fees( $fee );
3752
        return $current;
3753
    }
3754
3755
    /**
3756
	 * Recalculates the invoice total.
3757
	 *
3758
	 * @since 1.0.19
3759
     * @return float The invoice total
3760
	 */
3761
	public function recalculate_total() {
3762
        $this->recalculate_total_fees();
3763
        $this->recalculate_total_discount();
3764
		$this->recalculate_total_tax();
3765
		$this->recalculate_subtotal();
3766
		$this->set_total( $this->get_total_tax( 'edit' ) + $this->get_total_fees( 'edit' ) + $this->get_subtotal( 'edit' ) - $this->get_total_discount( 'edit' ) );
3767
		return $this->get_total();
3768
	}
3769
3770
	/**
3771
	 * @deprecated
3772
	 */
3773
    public function recalculate_totals() {
3774
        $this->recalculate_total();
3775
        $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

3775
        $this->/** @scrutinizer ignore-call */ 
3776
               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...
3776
        return $this;
3777
    }
3778
3779
    /**
3780
     * Convert this to an array.
3781
     */
3782
    public function array_convert() {
3783
        return $this->get_data();
3784
    }
3785
3786
	/**
3787
     * Adds a system note to an invoice.
3788
     *
3789
     * @param string $note The note being added.
3790
	 * @return int|false The new note's ID on success, false on failure.
3791
     *
3792
     */
3793
    public function add_system_note( $note ) {
3794
		return $this->add_note( $note, false, false, true );
3795
	}
3796
3797
    /**
3798
     * Adds a note to an invoice.
3799
     *
3800
     * @param string $note The note being added.
3801
	 * @return int|false The new note's ID on success, false on failure.
3802
     *
3803
     */
3804
    public function add_note( $note = '', $customer_type = false, $added_by_user = false, $system = false ) {
3805
3806
        // Bail if no note specified or this invoice is not yet saved.
3807
        if ( ! $note || $this->get_id() == 0 || ( ! is_user_logged_in() && ! $system ) ) {
3808
            return false;
3809
        }
3810
3811
		$author       = 'System';
3812
		$author_email = '[email protected]';
3813
3814
		// If this is an admin comment or it has been added by the user.
3815
		if ( is_user_logged_in() && ( ! $system || $added_by_user ) ) {
3816
			$user         = get_user_by( 'id', get_current_user_id() );
3817
            $author       = $user->display_name;
3818
            $author_email = $user->user_email;
3819
		}
3820
3821
		return getpaid_notes()->add_invoice_note( $this, $note, $author, $author_email, $customer_type );
3822
3823
	}
3824
3825
	/**
3826
     * Generates a unique key for the invoice.
3827
     */
3828
    public function generate_key( $string = '' ) {
3829
        $auth_key  = defined( 'AUTH_KEY' ) ? AUTH_KEY : '';
3830
        return strtolower(
3831
            $string . md5( $this->get_id() . date( 'Y-m-d H:i:s' ) . $auth_key . uniqid( 'wpinv', true ) )
3832
        );
3833
    }
3834
3835
    /**
3836
     * Generates a new number for the invoice.
3837
     */
3838
    public function generate_number() {
3839
        $number = $this->get_id();
3840
3841
        if ( wpinv_sequential_number_active( $this->get_post_type() ) ) {
3842
            $number = wpinv_get_next_invoice_number( $this->get_post_type() );
3843
        }
3844
3845
		return wpinv_format_invoice_number( $number, $this->get_post_type() );
3846
3847
	}
3848
3849
	/**
3850
	 * Handle the status transition.
3851
	 */
3852
	protected function status_transition() {
3853
		$status_transition = $this->status_transition;
3854
3855
		// Reset status transition variable.
3856
		$this->status_transition = false;
3857
3858
		if ( $status_transition ) {
3859
			try {
3860
3861
				// Fire a hook for the status change.
3862
				do_action( 'getpaid_invoice_status_' . $status_transition['to'], $this, $status_transition );
3863
3864
				// @deprecated this is deprecated and will be removed in the future.
3865
				do_action( 'wpinv_status_' . $status_transition['to'], $this->get_id(), $status_transition['from'] );
3866
3867
				if ( ! empty( $status_transition['from'] ) ) {
3868
3869
					/* translators: 1: old invoice status 2: new invoice status */
3870
					$transition_note = sprintf( __( 'Status changed from %1$s to %2$s.', 'invoicing' ), wpinv_status_nicename( $status_transition['from'], $this ), wpinv_status_nicename( $status_transition['to'], $this ) );
3871
3872
					// Fire another hook.
3873
					do_action( 'getpaid_invoice_status_' . $status_transition['from'] . '_to_' . $status_transition['to'], $this );
3874
					do_action( 'getpaid_invoice_status_changed', $this, $status_transition['from'], $status_transition['to'] );
3875
3876
					// @deprecated this is deprecated and will be removed in the future.
3877
					do_action( 'wpinv_status_' . $status_transition['from'] . '_to_' . $status_transition['to'], $this->get_id(), $status_transition['from'] );
3878
3879
					// Note the transition occurred.
3880
					$this->add_note( trim( $status_transition['note'] . ' ' . $transition_note ), false, $status_transition['manual'] );
3881
3882
					// Work out if this was for a payment, and trigger a payment_status hook instead.
3883
					if (
3884
						in_array( $status_transition['from'], array( 'wpi-cancelled', 'wpi-pending', 'wpi-failed', 'wpi-refunded', 'wpi-onhold' ), true )
3885
						&& in_array( $status_transition['to'], array( 'publish', 'wpi-processing', 'wpi-renewal' ), true )
3886
					) {
3887
						do_action( 'getpaid_invoice_payment_status_changed', $this, $status_transition );
3888
					}
3889
3890
					// Work out if this was for a payment reversal, and trigger a payment_status_reversed hook instead.
3891
					if (
3892
						in_array( $status_transition['from'], array( 'publish', 'wpi-processing', 'wpi-renewal' ), true )
3893
						&& in_array( $status_transition['to'], array( 'wpi-cancelled', 'wpi-pending', 'wpi-failed', 'wpi-refunded', 'wpi-onhold' ), true )
3894
					) {
3895
						do_action( 'getpaid_invoice_payment_status_reversed', $this, $status_transition );
3896
					}
3897
				} else {
3898
					/* translators: %s: new invoice status */
3899
					$transition_note = sprintf( __( 'Status set to %s.', 'invoicing' ), wpinv_status_nicename( $status_transition['to'], $this ) );
3900
3901
					// Note the transition occurred.
3902
					$this->add_note( trim( $status_transition['note'] . ' ' . $transition_note ), 0, $status_transition['manual'] );
3903
3904
				}
3905
			} catch ( Exception $e ) {
3906
				$this->add_note( __( 'Error during status transition.', 'invoicing' ) . ' ' . $e->getMessage() );
3907
			}
3908
		}
3909
	}
3910
3911
	/**
3912
	 * Updates an invoice status.
3913
	 */
3914
	public function update_status( $new_status = false, $note = '', $manual = false ) {
3915
3916
		// Fires before updating a status.
3917
		do_action( 'wpinv_before_invoice_status_change', $this->get_id(), $new_status, $this->get_status( 'edit' ) );
3918
3919
		// Update the status.
3920
		$this->set_status( $new_status, $note, $manual );
3921
3922
		// Save the order.
3923
		return $this->save();
3924
3925
	}
3926
3927
	/**
3928
	 * @deprecated
3929
	 */
3930
	public function refresh_item_ids() {
3931
        $item_ids = implode( ',', array_unique( wp_list_pluck( $this->get_cart_details(), 'item_id' ) ) );
3932
        update_post_meta( $this->get_id(), '_wpinv_item_ids', $item_ids );
3933
	}
3934
3935
	/**
3936
	 * @deprecated
3937
	 */
3938
	public function update_items( $temp = false ) {
3939
3940
		$this->set_items( $this->get_items() );
3941
3942
		if ( ! $temp ) {
3943
			$this->save();
3944
		}
3945
3946
        return $this;
3947
	}
3948
3949
	/**
3950
	 * @deprecated
3951
	 */
3952
    public function validate_discount() {
3953
3954
        $discount_code = $this->get_discount_code();
3955
3956
        if ( empty( $discount_code ) ) {
3957
            return false;
3958
        }
3959
3960
        $discount = wpinv_get_discount_obj( $discount_code );
3961
3962
        // Ensure it is active.
3963
        return $discount->exists();
3964
3965
    }
3966
3967
	/**
3968
	 * Refunds an invoice.
3969
	 */
3970
    public function refund() {
3971
		$this->set_status( 'wpi-refunded' );
3972
        $this->save();
3973
	}
3974
3975
	/**
3976
	 * Marks an invoice as paid.
3977
	 *
3978
	 * @param string $transaction_id
3979
	 */
3980
    public function mark_paid( $transaction_id = null, $note = '' ) {
3981
3982
		// Set the transaction id.
3983
		if ( empty( $transaction_id ) ) {
3984
			$transaction_id = $this->generate_key( 'trans_' );
3985
		}
3986
3987
		if ( ! $this->get_transaction_id() ) {
3988
			$this->set_transaction_id( $transaction_id );
3989
		}
3990
3991
		if ( $this->is_paid() && 'wpi-processing' !== $this->get_status() ) {
3992
			return $this->save();
3993
		}
3994
3995
		// Set the completed date.
3996
		$this->set_date_completed( current_time( 'mysql' ) );
3997
3998
		// Set the new status.
3999
		$gateway = sanitize_text_field( $this->get_gateway_title() );
4000
		if ( $this->is_renewal() || ! $this->is_parent() ) {
4001
4002
			$_note = wp_sprintf( __( 'Renewed via %s', 'invoicing' ), $gateway );
4003
			$_note = $_note . empty( $note ) ? '' : " ($note)";
4004
4005
			if ( 'none' == $this->get_gateway() ) {
4006
				$_note = $note;
4007
			}
4008
4009
			$this->set_status( 'wpi-renewal', $_note );
4010
4011
		} else {
4012
4013
			$_note = wp_sprintf( __( 'Paid via %s', 'invoicing' ), $gateway );
4014
			$_note = $_note . empty( $note ) ? '' : " ($note)";
4015
4016
			if ( 'none' == $this->get_gateway() ) {
4017
				$_note = $note;
4018
			}
4019
4020
			$this->set_status( 'publish', $_note );
4021
4022
		}
4023
4024
		// Set checkout mode.
4025
		$mode = wpinv_is_test_mode( $this->get_gateway() ) ? 'test' : 'live';
4026
		$this->set_mode( $mode );
4027
4028
		// Save the invoice.
4029
        $this->save();
4030
	}
4031
4032
	/**
4033
	 * Save data to the database.
4034
	 *
4035
	 * @since 1.0.19
4036
	 * @return int invoice ID
4037
	 */
4038
	public function save() {
4039
		$this->maybe_set_date_paid();
4040
		$this->maybe_set_key();
4041
		parent::save();
4042
		$this->clear_cache();
4043
		$this->status_transition();
4044
		return $this->get_id();
4045
	}
4046
4047
	/**
4048
     * Clears the subscription's cache.
4049
     */
4050
    public function clear_cache() {
4051
		if ( $this->get_key() ) {
4052
			wp_cache_delete( $this->get_key(), 'getpaid_invoice_keys_to_invoice_ids' );
4053
		}
4054
4055
		if ( $this->get_number() ) {
4056
			wp_cache_delete( $this->get_number(), 'getpaid_invoice_numbers_to_invoice_ids' );
4057
		}
4058
4059
		if ( $this->get_transaction_id() ) {
4060
			wp_cache_delete( $this->get_transaction_id(), 'getpaid_invoice_transaction_ids_to_invoice_ids' );
4061
		}
4062
	}
4063
4064
}
4065