Passed
Push — master ( cb75a2...6929e7 )
by Brian
05:54 queued 11s
created

getpaid_invoice_history()   A

Complexity

Conditions 6
Paths 6

Size

Total Lines 43
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 18
c 0
b 0
f 0
dl 0
loc 43
rs 9.0444
cc 6
nc 6
nop 1
1
<?php
2
/**
3
 * Contains functions related to Invoicing plugin.
4
 *
5
 * @since 1.0.0
6
 * @package Invoicing
7
 */
8
 
9
defined( 'ABSPATH' ) || exit;
10
11
/**
12
 * Retrieves the current invoice.
13
 */
14
function getpaid_get_current_invoice_id() {
15
16
    // Ensure that we have an invoice key.
17
    if ( empty( $_GET['invoice_key'] ) ) {
18
        return 0;
19
    }
20
21
    // Retrieve an invoice using the key.
22
    $invoice = new WPInv_Invoice( $_GET['invoice_key'] );
23
24
    // Compare the invoice key and the parsed key.
25
    if ( $invoice->get_id() != 0 && $invoice->get_key() == $_GET['invoice_key'] ) {
26
        return $invoice->get_id();
27
    }
28
29
    return 0;
30
}
31
32
/**
33
 * Checks if the current user cna view an invoice.
34
 */
35
function wpinv_user_can_view_invoice( $invoice ) {
36
    $invoice = new WPInv_Invoice( $invoice );
37
38
    // Abort if the invoice does not exist.
39
    if ( 0 == $invoice->get_id() ) {
40
        return false;
41
    }
42
43
    // Don't allow trash, draft status
44
    if ( $invoice->is_draft() ) {
45
        return false;
46
    }
47
48
    // If users are not required to login to check out, compare the invoice keys.
49
    if ( ! wpinv_require_login_to_checkout() && isset( $_GET['invoice_key'] ) && trim( $_GET['invoice_key'] ) == $invoice->get_key() ) {
50
        return true;
51
    }
52
53
    // Always enable for admins..
54
    if ( wpinv_current_user_can_manage_invoicing() || current_user_can( 'view_invoices', $invoice->get_id() ) ) { // Admin user
55
        return true;
56
    }
57
58
    // Else, ensure that this is their invoice.
59
    if ( is_user_logged_in() && $invoice->get_user_id() == get_current_user_id() ) {
60
        return true;
61
    }
62
63
    return apply_filters( 'wpinv_current_user_can_view_invoice', false, $invoice );
64
}
65
66
/**
67
 * Checks if the current user cna view an invoice receipt.
68
 */
69
function wpinv_can_view_receipt( $invoice ) {
70
	return (bool) apply_filters( 'wpinv_can_view_receipt', wpinv_user_can_view_invoice( $invoice ), $invoice );
71
}
72
73
/**
74
 * Returns an array of all invoice post types.
75
 * 
76
 * @return array
77
 */
78
function getpaid_get_invoice_post_types() {
79
    $post_types = array(
80
        'wpi_quote'   => __( 'Quote', 'invoicing' ),
81
        'wpi_invoice' => __( 'Invoice', 'invoicing' ),
82
    );
83
84
    return apply_filters( 'getpaid_invoice_post_types', $post_types );
85
}
86
87
/**
88
 * Checks if this is an invocing post type.
89
 * 
90
 * 
91
 * @param string $post_type The post type to check for.
92
 */
93
function getpaid_is_invoice_post_type( $post_type ) {
94
    return ! empty( $post_type ) && array_key_exists( $post_type, getpaid_get_invoice_post_types() );
95
}
96
97
/**
98
 * Creates a new invoice.
99
 * 
100
 * @param  array $data   An array of invoice properties.
101
 * @param  bool  $wp_error       Whether to return false or WP_Error on failure.
102
 * @return int|WP_Error|WPInv_Invoice The value 0 or WP_Error on failure. The WPInv_Invoice object on success.
103
 */
104
function wpinv_create_invoice( $data = array(), $deprecated = null, $wp_error = false ) {
0 ignored issues
show
Unused Code introduced by
The parameter $deprecated is not used and could be removed. ( Ignorable by Annotation )

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

104
function wpinv_create_invoice( $data = array(), /** @scrutinizer ignore-unused */ $deprecated = null, $wp_error = false ) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
105
    $data[ 'invoice_id' ] = 0;
106
    return wpinv_insert_invoice( $data, $wp_error );
107
}
108
109
/**
110
 * Updates an existing invoice.
111
 * 
112
 * @param  array $data   An array of invoice properties.
113
 * @param  bool  $wp_error       Whether to return false or WP_Error on failure.
114
 * @return int|WP_Error|WPInv_Invoice The value 0 or WP_Error on failure. The WPInv_Invoice object on success.
115
 */
116
function wpinv_update_invoice( $data = array(), $wp_error = false ) {
117
118
    // Backwards compatibility.
119
    if ( ! empty( $data['ID'] ) ) {
120
        $data['invoice_id'] = $data['ID'];
121
    }
122
123
    // Do we have an invoice id?
124
    if ( empty( $data['invoice_id'] ) ) {
125
        return $wp_error ? new WP_Error( 'invalid_invoice_id', __( 'Invalid invoice ID.', 'invoicing' ) ) : 0;
126
    }
127
128
    // Retrieve the invoice.
129
    $invoice = wpinv_get_invoice( $data['invoice_id'] );
130
131
    // And abort if it does not exist.
132
    if ( empty( $invoice ) ) {
133
        return $wp_error ? new WP_Error( 'missing_invoice', __( 'Invoice not found.', 'invoicing' ) ) : 0;
134
    }
135
136
    // Do not update totals for paid / refunded invoices.
137
    if ( $invoice->is_paid() || $invoice->is_refunded() ) {
138
139
        if ( ! empty( $data['items'] ) || ! empty( $data['cart_details'] ) ) {
140
            return $wp_error ? new WP_Error( 'paid_invoice', __( 'You can not update cart items for invoices that have already been paid for.', 'invoicing' ) ) : 0;
141
        }
142
143
    }
144
145
    return wpinv_insert_invoice( $data, $wp_error );
146
147
}
148
149
/**
150
 * Create/Update an invoice
151
 * 
152
 * @param  array $data   An array of invoice properties.
153
 * @param  bool  $wp_error       Whether to return false or WP_Error on failure.
154
 * @return int|WP_Error|WPInv_Invoice The value 0 or WP_Error on failure. The WPInv_Invoice object on success.
155
 */
156
function wpinv_insert_invoice( $data = array(), $wp_error = false ) {
157
158
    // Ensure that we have invoice data.
159
    if ( empty( $data ) ) {
160
        return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type WPInv_Invoice|WP_Error|integer.
Loading history...
161
    }
162
163
    // The invoice id will be provided when updating an invoice.
164
    $data['invoice_id'] = ! empty( $data['invoice_id'] ) ? (int) $data['invoice_id'] : false;
165
166
    // Retrieve the invoice.
167
    $invoice = new WPInv_Invoice( $data['invoice_id'] );
168
169
    // Do we have an error?
170
    if ( ! empty( $invoice->last_error ) ) {
171
        return $wp_error ? new WP_Error( 'invalid_invoice_id', $invoice->last_error ) : 0;
172
    }
173
174
    // Backwards compatibility (billing address).
175
    if ( ! empty( $data['user_info'] ) ) {
176
177
        foreach ( $data['user_info'] as $key => $value ) {
178
179
            if ( $key == 'discounts' ) {
180
                $value = (array) $value;
181
                $data[ 'discount_code' ] = empty( $value ) ? null : $value[0];
182
            } else {
183
                $data[ $key ] = $value;
184
            }
185
186
        }
187
188
    }
189
190
    // Backwards compatibility.
191
    if ( ! empty( $data['payment_details'] ) ) {
192
193
        foreach ( $data['payment_details'] as $key => $value ) {
194
            $data[ $key ] = $value;
195
        }
196
197
    }
198
199
    // Set up the owner of the invoice.
200
    $user_id = ! empty( $data['user_id'] ) ? wpinv_clean( $data['user_id'] ) : get_current_user_id();
201
202
    // Make sure the user exists.
203
    if ( ! get_userdata( $user_id ) ) {
204
        return $wp_error ? new WP_Error( 'wpinv_invalid_user', __( 'There is no user with that ID.', 'invoicing' ) ) : 0;
205
    }
206
207
    $address = wpinv_get_user_address( $user_id );
208
209
    foreach ( $address as $key => $value ) {
210
211
        if ( $value == '' ) {
212
            $address[ $key ] = null;
213
        } else {
214
            $address[ $key ] = wpinv_clean( $value );
215
        }
216
217
    }
218
219
    // Load new data.
220
    $invoice->set_props(
221
222
        array(
223
224
            // Basic info.
225
            'template'             => isset( $data['template'] ) ? wpinv_clean( $data['template'] ) : null,
226
            'email_cc'             => isset( $data['email_cc'] ) ? wpinv_clean( $data['email_cc'] ) : null,
227
            'date_created'         => isset( $data['created_date'] ) ? wpinv_clean( $data['created_date'] ) : null,
228
            'due_date'             => isset( $data['due_date'] ) ? wpinv_clean( $data['due_date'] ) : null,
229
            'date_completed'       => isset( $data['date_completed'] ) ? wpinv_clean( $data['date_completed'] ) : null,
230
            'number'               => isset( $data['number'] ) ? wpinv_clean( $data['number'] ) : null,
231
            'key'                  => isset( $data['key'] ) ? wpinv_clean( $data['key'] ) : null,
232
            'status'               => isset( $data['status'] ) ? wpinv_clean( $data['status'] ) : null,
233
            'post_type'            => isset( $data['post_type'] ) ? wpinv_clean( $data['post_type'] ) : null,
234
            'user_ip'              => isset( $data['ip'] ) ? wpinv_clean( $data['ip'] ) : wpinv_get_ip(),
235
            'parent_id'            => isset( $data['parent'] ) ? intval( $data['parent'] ) : null,
236
            'mode'                 => isset( $data['mode'] ) ? wpinv_clean( $data['mode'] ) : null,
237
            'description'          => isset( $data['description'] ) ? wp_kses_post( $data['description'] ) : null,
238
239
            // Payment info.
240
            'disable_taxes'        => ! empty( $data['disable_taxes'] ),
241
            'currency'             => isset( $data['currency'] ) ? wpinv_clean( $data['currency'] ) : wpinv_get_currency(),
242
            'gateway'              => isset( $data['gateway'] ) ? wpinv_clean( $data['gateway'] ) : null,
243
            'transaction_id'       => isset( $data['transaction_id'] ) ? wpinv_clean( $data['transaction_id'] ) : null,
244
            'discount_code'        => isset( $data['discount_code'] ) ? wpinv_clean( $data['discount_code'] ) : null,
245
            'payment_form'         => isset( $data['payment_form'] ) ? intval( $data['payment_form'] ) : null,
246
            'submission_id'        => isset( $data['submission_id'] ) ? wpinv_clean( $data['submission_id'] ) : null,
247
            'subscription_id'      => isset( $data['subscription_id'] ) ? wpinv_clean( $data['subscription_id'] ) : null,
248
            'is_viewed'            => isset( $data['is_viewed'] ) ? wpinv_clean( $data['is_viewed'] ) : null,
249
            'fees'                 => isset( $data['fees'] ) ? wpinv_clean( $data['fees'] ) : null,
250
            'discounts'            => isset( $data['discounts'] ) ? wpinv_clean( $data['discounts'] ) : null,
251
            'taxes'                => isset( $data['taxes'] ) ? wpinv_clean( $data['taxes'] ) : null,
252
            
253
254
            // Billing details.
255
            'user_id'              => $data['user_id'],
256
            'first_name'           => isset( $data['first_name'] ) ? wpinv_clean( $data['first_name'] ) : $address['first_name'],
257
            'last_name'            => isset( $data['last_name'] ) ? wpinv_clean( $data['last_name'] ) : $address['last_name'],
258
            'address'              => isset( $data['address'] ) ? wpinv_clean( $data['address'] ) : $address['address'] ,
259
            'vat_number'           => isset( $data['vat_number'] ) ? wpinv_clean( $data['vat_number'] ) : $address['vat_number'],
260
            'company'              => isset( $data['company'] ) ? wpinv_clean( $data['company'] ) : $address['company'],
261
            'zip'                  => isset( $data['zip'] ) ? wpinv_clean( $data['zip'] ) : $address['zip'],
262
            'state'                => isset( $data['state'] ) ? wpinv_clean( $data['state'] ) : $address['state'],
263
            'city'                 => isset( $data['city'] ) ? wpinv_clean( $data['city'] ) : $address['city'],
264
            'country'              => isset( $data['country'] ) ? wpinv_clean( $data['country'] ) : $address['country'],
265
            'phone'                => isset( $data['phone'] ) ? wpinv_clean( $data['phone'] ) : $address['phone'],
266
            'address_confirmed'    => ! empty( $data['address_confirmed'] ),
267
268
        )
269
270
    );
271
272
    // Backwards compatibililty.
273
    if ( ! empty( $data['cart_details'] ) && is_array( $data['cart_details'] ) ) {
274
        $data['items'] = array();
275
276
        foreach( $data['cart_details'] as $_item ) {
277
278
            // Ensure that we have an item id.
279
            if ( empty(  $_item['id']  ) ) {
280
                continue;
281
            }
282
283
            // Retrieve the item.
284
            $item = new GetPaid_Form_Item(  $_item['id']  );
285
286
            // Ensure that it is purchasable.
287
            if ( ! $item->can_purchase() ) {
288
                continue;
289
            }
290
291
            // Set quantity.
292
            if ( ! empty( $_item['quantity'] ) && is_numeric( $_item['quantity'] ) ) {
293
                $item->set_quantity( $_item['quantity'] );
294
            }
295
296
            // Set price.
297
            if ( isset( $_item['item_price'] ) ) {
298
                $item->set_price( $_item['item_price'] );
299
            }
300
301
            if ( isset( $_item['custom_price'] ) ) {
302
                $item->set_price( $_item['custom_price'] );
303
            }
304
305
            // Set name.
306
            if ( ! empty( $_item['name'] ) ) {
307
                $item->set_name( $_item['name'] );
308
            }
309
310
            // Set description.
311
            if ( isset( $_item['description'] ) ) {
312
                $item->set_custom_description( $_item['description'] );
313
            }
314
315
            // Set meta.
316
            if ( isset( $_item['meta'] ) && is_array( $_item['meta'] ) ) {
317
318
                $item->set_item_meta( $_item['meta'] );
319
320
                if ( isset( $_item['meta']['description'] ) ) {
321
                    $item->set_custom_description( $_item['meta']['description'] );
322
                }
323
324
            }
325
326
            $data['items'][] = $item;
327
328
        }
329
    }
330
331
    // Add invoice items.
332
    if ( ! empty( $data['items'] ) && is_array( $data['items'] ) ) {
333
334
        $invoice->set_items( array() );
335
336
        foreach ( $data['items'] as $item ) {
337
338
            if ( is_object( $item ) && is_a( $item, 'GetPaid_Form_Item' ) && $item->can_purchase() ) {
339
                $invoice->add_item( $item );
340
            }
341
342
        }
343
344
    }
345
346
    // Save the invoice.
347
    $invoice->save();
348
349
    if ( ! $invoice->get_id() ) {
350
        return $wp_error ? new WP_Error( 'wpinv_insert_invoice_error', __( 'An error occured when saving your invoice.', 'invoicing' ) ) : 0;
351
    }
352
353
    // Add private note.
354
    if ( ! empty( $data['private_note'] ) ) {
355
        $invoice->add_note( $data['private_note'] );
356
    }
357
358
    // User notes.
359
    if ( !empty( $data['user_note'] ) ) {
360
        $invoice->add_note( $data['user_note'], true );
361
    }
362
363
    // Created via.
364
    if ( isset( $data['created_via'] ) ) {
365
        update_post_meta( $invoice->get_id(), 'wpinv_created_via', $data['created_via'] );
366
    }
367
368
    // Backwards compatiblity.
369
    if ( $invoice->is_quote() ) {
370
371
        if ( isset( $data['valid_until'] ) ) {
372
            update_post_meta( $invoice->get_id(), 'wpinv_quote_valid_until', $data['valid_until'] );
373
        }
374
        return $invoice;
375
376
    }
377
378
}
379
380
/**
381
 * Retrieves an invoice.
382
 * 
383
 * @param int|string|object|WPInv_Invoice|WPInv_Legacy_Invoice|WP_Post $invoice Invoice id, key, transaction id, number or object.
384
 * @param $bool $deprecated
0 ignored issues
show
Documentation Bug introduced by
The doc comment $bool at position 0 could not be parsed: Unknown type name '$bool' at position 0 in $bool.
Loading history...
385
 * @return WPInv_Invoice|null
386
 */
387
function wpinv_get_invoice( $invoice = 0, $deprecated = false ) {
388
389
    // If we are retrieving the invoice from the cart...
390
    if ( $deprecated && empty( $invoice ) ) {
391
        $invoice = (int) getpaid_get_current_invoice_id();
392
    }
393
394
    // Retrieve the invoice.
395
    $invoice = new WPInv_Invoice( $invoice );
396
397
    // Check if it exists.
398
    if ( $invoice->get_id() != 0 ) {
399
        return $invoice;
400
    }
401
402
    return null;
403
}
404
405
/**
406
 * Retrieves several invoices.
407
 * 
408
 * @param array $args Args to search for.
409
 * @return WPInv_Invoice[]|int[]|object
410
 */
411
function wpinv_get_invoices( $args ) {
412
413
    // Prepare args.
414
    $args = wp_parse_args(
415
        $args,
416
        array(
417
            'status'   => array_keys( wpinv_get_invoice_statuses() ),
418
            'type'     => 'wpi_invoice',
419
            'limit'    => get_option( 'posts_per_page' ),
420
            'return'   => 'objects',
421
        )
422
    );
423
424
    // Map params to wp_query params.
425
    $map_legacy = array(
426
        'numberposts'    => 'limit',
427
        'post_type'      => 'type',
428
        'post_status'    => 'status',
429
        'post_parent'    => 'parent',
430
        'author'         => 'user',
431
        'posts_per_page' => 'limit',
432
        'paged'          => 'page',
433
        'post__not_in'   => 'exclude',
434
        'post__in'       => 'include',
435
    );
436
437
    foreach ( $map_legacy as $to => $from ) {
438
        if ( isset( $args[ $from ] ) ) {
439
            $args[ $to ] = $args[ $from ];
440
            unset( $args[ $from ] );
441
        }
442
    }
443
444
    // Backwards compatibility.
445
    if ( ! empty( $args['email'] ) && empty( $args['user'] ) ) {
446
        $args['user'] = $args['email'];
447
        unset( $args['email'] );
448
    }
449
450
    // Handle cases where the user is set as an email.
451
    if ( ! empty( $args['author'] ) && is_email( $args['author'] ) ) {
452
        $user = get_user_by( 'email', $args['user'] );
453
454
        if ( $user ) {
455
            $args['author'] = $user->user_email;
456
        }
457
458
    }
459
460
    // We only want invoice ids.
461
    $args['fields'] = 'ids';
462
463
    // Show all posts.
464
    $paginate = true;
465
    if ( isset( $args['paginate'] ) ) {
466
        
467
        $paginate = $args['paginate'];
468
        $args['no_found_rows'] = empty( $args['paginate'] );
469
        unset( $args['paginate'] );
470
471
    }
472
473
    // Whether to return objects or fields.
474
    $return = $args['return'];
475
    unset( $args['return'] );
476
477
    // Get invoices.
478
    $invoices = new WP_Query( apply_filters( 'wpinv_get_invoices_args', $args ) );
479
480
    // Prepare the results.
481
    if ( 'objects' === $return ) {
482
        $results = array_map( 'wpinv_get_invoice', $invoices->posts );
483
    } elseif ( 'self' === $return ) {
484
        return $invoices;
485
    } else {
486
        $results = $invoices->posts;
487
    }
488
489
    if ( $paginate ) {
490
        return (object) array(
491
            'invoices'      => $results,
492
            'total'         => $invoices->found_posts,
493
            'max_num_pages' => $invoices->max_num_pages,
494
        );
495
    } else {
496
        return $results;
497
    }
498
499
}
500
501
/**
502
 * Retrieves an invoice's id from a transaction id.
503
 * 
504
 * @param string $transaction_id The transaction id to check.
505
 * @return int Invoice id on success or 0 on failure
506
 */
507
function wpinv_get_id_by_transaction_id( $transaction_id ) {
508
    return WPInv_Invoice::get_invoice_id_by_field( $transaction_id, 'transaction_id' );
509
}
510
511
/**
512
 * Retrieves an invoice's id from the invoice number.
513
 * 
514
 * @param string $invoice_number The invoice number to check.
515
 * @return int Invoice id on success or 0 on failure
516
 */
517
function wpinv_get_id_by_invoice_number( $invoice_number ) {
518
    return WPInv_Invoice::get_invoice_id_by_field( $invoice_number, 'number' );
519
}
520
521
/**
522
 * Retrieves an invoice's id from the invoice key.
523
 * 
524
 * @param string $invoice_key The invoice key to check.
525
 * @return int Invoice id on success or 0 on failure
526
 */
527
function wpinv_get_invoice_id_by_key( $invoice_key ) {
528
    return WPInv_Invoice::get_invoice_id_by_field( $invoice_key, 'key' );
529
}
530
531
/**
532
 * Retrieves an invoice's notes.
533
 * 
534
 * @param int|string|object|WPInv_Invoice|WPInv_Legacy_Invoice|WP_Post $invoice Invoice id, key, transaction id, number or object.
535
 * @param string $type Optionally filter by type i.e customer|system
536
 * @return WPInv_Invoice|null
537
 */
538
function wpinv_get_invoice_notes( $invoice = 0, $type = '' ) {
539
    global $invoicing;
540
541
    // Prepare the invoice.
542
    $invoice = new WPInv_Invoice( $invoice );
543
    if ( ! $invoice->exists() ) {
544
        return NULL;
545
    }
546
547
    // Fetch notes.
548
    $notes = $invoicing->notes->get_invoice_notes( $invoice->get_id(), $type );
549
550
    // Filter the notes.
551
    return apply_filters( 'wpinv_invoice_notes', $notes, $invoice->get_id(), $type );
552
}
553
554
/**
555
 * Returns an array of columns to display on the invoices page.
556
 */
557
function wpinv_get_user_invoices_columns() {
558
    $columns = array(
559
560
            'invoice-number'  => array(
561
                'title' => __( 'Invoice', 'invoicing' ),
562
                'class' => 'text-left'
563
            ),
564
565
            'created-date'    => array(
566
                'title' => __( 'Created Date', 'invoicing' ),
567
                'class' => 'text-left'
568
            ),
569
570
            'payment-date'    => array(
571
                'title' => __( 'Payment Date', 'invoicing' ),
572
                'class' => 'text-left'
573
            ),
574
575
            'invoice-status'  => array(
576
                'title' => __( 'Status', 'invoicing' ),
577
                'class' => 'text-center'
578
            ),
579
580
            'invoice-total'   => array(
581
                'title' => __( 'Total', 'invoicing' ),
582
                'class' => 'text-right'
583
            ),
584
585
            'invoice-actions' => array(
586
                'title' => '&nbsp;',
587
                'class' => 'text-center'
588
            ),
589
590
        );
591
592
    return apply_filters( 'wpinv_user_invoices_columns', $columns );
593
}
594
595
/**
596
 * Displays the invoice receipt.
597
 */
598
function wpinv_payment_receipt() {
599
600
    // Find the invoice.
601
    $invoice_id = getpaid_get_current_invoice_id();
602
    $invoice = new WPInv_Invoice( $invoice_id );
603
604
    // Abort if non was found.
605
    if ( empty( $invoice_id ) || $invoice->is_draft() ) {
606
607
        return aui()->alert(
608
            array(
609
                'type'    => 'warning',
610
                'content' => __( 'We could not find your invoice', 'invoicing' ),
611
            )
612
        );
613
614
    }
615
616
    // Can the user view this invoice?
617
    if ( ! wpinv_can_view_receipt( $invoice_id ) ) {
618
619
        return aui()->alert(
620
            array(
621
                'type'    => 'warning',
622
                'content' => __( 'You are not allowed to view this receipt', 'invoicing' ),
623
            )
624
        );
625
626
    }
627
628
    // Load the template.
629
    return wpinv_get_template_html( 'invoice-receipt.php', compact( 'invoice' ) );
630
631
}
632
633
/**
634
 * Displays the invoice history.
635
 */
636
function getpaid_invoice_history( $user_id = 0 ) {
637
638
    // Ensure that we have a user id.
639
    if ( empty( $user_id ) || ! is_numeric( $user_id ) ) {
640
        $user_id = get_current_user_id();
641
    }
642
643
    // View user id.
644
    if ( empty( $user_id ) ) {
645
646
        return aui()->alert(
647
            array(
648
                'type'    => 'warning',
649
                'content' => __( 'You must be logged in to view your invoice history.', 'invoicing' ),
650
            )
651
        );
652
653
    }
654
655
    // Fetch invoices.
656
    $invoices = wpinv_get_invoices(
657
658
        array(
659
            'page'     => ( get_query_var( 'paged' ) ) ? absint( get_query_var( 'paged' ) ) : 1,
660
            'user'     => $user_id,
661
            'paginate' => true,
662
        )
663
664
    );
665
666
    if ( empty( $invoices->total ) ) {
667
668
        return aui()->alert(
669
            array(
670
                'type'    => 'info',
671
                'content' => __( 'No invoices found.', 'invoicing' ),
672
            )
673
        );
674
675
    }
676
677
    // Load the template.
678
    return wpinv_get_template_html( 'invoice-history.php', compact( 'invoices' ) );
679
680
}
681
682
function wpinv_pay_for_invoice() {
683
    global $wpinv_euvat;
684
    
685
    if ( isset( $_GET['invoice_key'] ) ) {
686
        $checkout_uri   = wpinv_get_checkout_uri();
687
        $invoice_key    = sanitize_text_field( $_GET['invoice_key'] );
688
        
689
        if ( empty( $invoice_key ) ) {
690
            wpinv_set_error( 'invalid_invoice', __( 'Invoice not found', 'invoicing' ) );
691
            wp_redirect( $checkout_uri );
0 ignored issues
show
Bug introduced by
It seems like $checkout_uri can also be of type false; however, parameter $location of wp_redirect() 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

691
            wp_redirect( /** @scrutinizer ignore-type */ $checkout_uri );
Loading history...
692
            exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
693
        }
694
        
695
        do_action( 'wpinv_check_pay_for_invoice', $invoice_key );
696
697
        $invoice_id    = wpinv_get_invoice_id_by_key( $invoice_key );
698
        $user_can_view = wpinv_can_view_receipt( $invoice_key );
699
        if ( $user_can_view && isset( $_GET['invoice-id'] ) ) {
700
            $invoice_id     = (int)$_GET['invoice-id'];
701
            $user_can_view  = $invoice_key == wpinv_get_payment_key( (int)$_GET['invoice-id'] ) ? true : false;
0 ignored issues
show
Deprecated Code introduced by
The function wpinv_get_payment_key() has been deprecated. ( Ignorable by Annotation )

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

701
            $user_can_view  = $invoice_key == /** @scrutinizer ignore-deprecated */ wpinv_get_payment_key( (int)$_GET['invoice-id'] ) ? true : false;
Loading history...
702
        }
703
        
704
        if ( $invoice_id && $user_can_view && ( $invoice = wpinv_get_invoice( $invoice_id ) ) ) {
705
            if ( $invoice->needs_payment() ) {
706
                $data                   = array();
707
                $data['invoice_id']     = $invoice_id;
708
                $data['cart_discounts'] = $invoice->get_discounts( true );
0 ignored issues
show
Bug introduced by
true of type true is incompatible with the type string expected by parameter $context of WPInv_Invoice::get_discounts(). ( Ignorable by Annotation )

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

708
                $data['cart_discounts'] = $invoice->get_discounts( /** @scrutinizer ignore-type */ true );
Loading history...
709
                
710
                wpinv_set_checkout_session( $data );
0 ignored issues
show
Deprecated Code introduced by
The function wpinv_set_checkout_session() has been deprecated. ( Ignorable by Annotation )

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

710
                /** @scrutinizer ignore-deprecated */ wpinv_set_checkout_session( $data );
Loading history...
Unused Code introduced by
The call to wpinv_set_checkout_session() has too many arguments starting with $data. ( Ignorable by Annotation )

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

710
                /** @scrutinizer ignore-call */ 
711
                wpinv_set_checkout_session( $data );

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...
711
                
712
                if ( wpinv_get_option( 'vat_ip_country_default' ) ) {
713
                    $_POST['country']   = $wpinv_euvat->get_country_by_ip();
714
                    $_POST['state']     = $_POST['country'] == $invoice->country ? $invoice->state : '';
0 ignored issues
show
Bug Best Practice introduced by
The property country does not exist on WPInv_Invoice. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property state does not exist on WPInv_Invoice. Since you implemented __get, consider adding a @property annotation.
Loading history...
715
                    
716
                    wpinv_recalculate_tax( true );
717
                }
718
                
719
            } else {
720
                $checkout_uri = $invoice->get_view_url();
721
            }
722
        } else {
723
            wpinv_set_error( 'invalid_invoice', __( 'You are not allowed to view this invoice', 'invoicing' ) );
724
            
725
            $checkout_uri = is_user_logged_in() ? wpinv_get_history_page_uri() : wp_login_url( get_permalink() );
0 ignored issues
show
Bug introduced by
It seems like get_permalink() can also be of type false; however, parameter $redirect of wp_login_url() 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

725
            $checkout_uri = is_user_logged_in() ? wpinv_get_history_page_uri() : wp_login_url( /** @scrutinizer ignore-type */ get_permalink() );
Loading history...
726
        }
727
        
728
        if(wp_redirect( $checkout_uri )){
729
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
730
        };
731
        wpinv_die();
732
    }
733
}
734
add_action( 'wpinv_pay_for_invoice', 'wpinv_pay_for_invoice' );
735
736
function wpinv_invoice_status_label( $status, $status_display = '' ) {
737
    if ( empty( $status_display ) ) {
738
        $status_display = wpinv_status_nicename( $status );
739
    }
740
    
741
    switch ( $status ) {
742
        case 'publish' :
743
        case 'wpi-renewal' :
744
            $class = 'label-success';
745
        break;
746
        case 'wpi-pending' :
747
            $class = 'label-primary';
748
        break;
749
        case 'wpi-processing' :
750
            $class = 'label-warning';
751
        break;
752
        case 'wpi-onhold' :
753
            $class = 'label-info';
754
        break;
755
        case 'wpi-cancelled' :
756
        case 'wpi-failed' :
757
            $class = 'label-danger';
758
        break;
759
        default:
760
            $class = 'label-default';
761
        break;
762
    }
763
764
    $label = '<span class="label label-inv-' . $status . ' ' . $class . '">' . $status_display . '</span>';
765
766
    return apply_filters( 'wpinv_invoice_status_label', $label, $status, $status_display );
767
}
768
769
function wpinv_format_invoice_number( $number, $type = '' ) {
770
    $check = apply_filters( 'wpinv_pre_format_invoice_number', null, $number, $type );
771
    if ( null !== $check ) {
772
        return $check;
773
    }
774
775
    if ( !empty( $number ) && !is_numeric( $number ) ) {
776
        return $number;
777
    }
778
779
    $padd  = wpinv_get_option( 'invoice_number_padd' );
780
    $prefix  = wpinv_get_option( 'invoice_number_prefix' );
781
    $postfix = wpinv_get_option( 'invoice_number_postfix' );
782
    
783
    $padd = absint( $padd );
784
    $formatted_number = absint( $number );
785
    
786
    if ( $padd > 0 ) {
787
        $formatted_number = zeroise( $formatted_number, $padd );
788
    }    
789
790
    $formatted_number = $prefix . $formatted_number . $postfix;
0 ignored issues
show
Bug introduced by
Are you sure $postfix of type false|mixed can be used in concatenation? ( Ignorable by Annotation )

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

790
    $formatted_number = $prefix . $formatted_number . /** @scrutinizer ignore-type */ $postfix;
Loading history...
Bug introduced by
Are you sure $prefix of type false|mixed can be used in concatenation? ( Ignorable by Annotation )

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

790
    $formatted_number = /** @scrutinizer ignore-type */ $prefix . $formatted_number . $postfix;
Loading history...
791
792
    return apply_filters( 'wpinv_format_invoice_number', $formatted_number, $number, $prefix, $postfix, $padd );
793
}
794
795
function wpinv_get_next_invoice_number( $type = '' ) {
796
    $check = apply_filters( 'wpinv_get_pre_next_invoice_number', null, $type );
797
    if ( null !== $check ) {
798
        return $check;
799
    }
800
    
801
    if ( !wpinv_sequential_number_active() ) {
802
        return false;
803
    }
804
805
    $number = $last_number = get_option( 'wpinv_last_invoice_number', 0 );
806
    $start  = wpinv_get_option( 'invoice_sequence_start', 1 );
807
    if ( !absint( $start ) > 0 ) {
808
        $start = 1;
809
    }
810
    $increment_number = true;
811
    $save_number = false;
812
813
    if ( !empty( $number ) && !is_numeric( $number ) && $number == wpinv_format_invoice_number( $number ) ) {
814
        $number = wpinv_clean_invoice_number( $number );
815
    }
816
817
    if ( empty( $number ) ) {
818
        if ( !( $last_number === 0 || $last_number === '0' ) ) {
819
            $last_invoice = wpinv_get_invoices( array( 'limit' => 1, 'order' => 'DESC', 'orderby' => 'ID', 'return' => 'posts', 'fields' => 'ids', 'status' => array_keys( wpinv_get_invoice_statuses( true, true ) ) ) );
820
821
            if ( !empty( $last_invoice[0] ) && $invoice_number = wpinv_get_invoice_number( $last_invoice[0] ) ) {
0 ignored issues
show
Deprecated Code introduced by
The function wpinv_get_invoice_number() has been deprecated. ( Ignorable by Annotation )

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

821
            if ( !empty( $last_invoice[0] ) && $invoice_number = /** @scrutinizer ignore-deprecated */ wpinv_get_invoice_number( $last_invoice[0] ) ) {
Loading history...
822
                if ( is_numeric( $invoice_number ) ) {
823
                    $number = $invoice_number;
824
                } else {
825
                    $number = wpinv_clean_invoice_number( $invoice_number );
826
                }
827
            }
828
829
            if ( empty( $number ) ) {
830
                $increment_number = false;
831
                $number = $start;
832
                $save_number = ( $number - 1 );
833
            } else {
834
                $save_number = $number;
835
            }
836
        }
837
    }
838
839
    if ( $start > $number ) {
840
        $increment_number = false;
841
        $number = $start;
842
        $save_number = ( $number - 1 );
843
    }
844
845
    if ( $save_number !== false ) {
846
        update_option( 'wpinv_last_invoice_number', $save_number );
847
    }
848
    
849
    $increment_number = apply_filters( 'wpinv_increment_payment_number', $increment_number, $number );
850
851
    if ( $increment_number ) {
852
        $number++;
853
    }
854
855
    return apply_filters( 'wpinv_get_next_invoice_number', $number );
856
}
857
858
function wpinv_clean_invoice_number( $number, $type = '' ) {
859
    $check = apply_filters( 'wpinv_pre_clean_invoice_number', null, $number, $type );
860
    if ( null !== $check ) {
861
        return $check;
862
    }
863
    
864
    $prefix  = wpinv_get_option( 'invoice_number_prefix' );
865
    $postfix = wpinv_get_option( 'invoice_number_postfix' );
866
867
    $number = preg_replace( '/' . $prefix . '/', '', $number, 1 );
0 ignored issues
show
Bug introduced by
Are you sure $prefix of type false|mixed can be used in concatenation? ( Ignorable by Annotation )

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

867
    $number = preg_replace( '/' . /** @scrutinizer ignore-type */ $prefix . '/', '', $number, 1 );
Loading history...
868
869
    $length      = strlen( $number );
870
    $postfix_pos = strrpos( $number, $postfix );
0 ignored issues
show
Bug introduced by
It seems like $postfix can also be of type false; however, parameter $needle of strrpos() 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

870
    $postfix_pos = strrpos( $number, /** @scrutinizer ignore-type */ $postfix );
Loading history...
871
    
872
    if ( false !== $postfix_pos ) {
873
        $number      = substr_replace( $number, '', $postfix_pos, $length );
874
    }
875
876
    $number = intval( $number );
877
878
    return apply_filters( 'wpinv_clean_invoice_number', $number, $prefix, $postfix );
879
}
880
881
function wpinv_update_invoice_number( $post_ID, $save_sequential = false, $type = '' ) {
882
    global $wpdb;
883
884
    $check = apply_filters( 'wpinv_pre_update_invoice_number', null, $post_ID, $save_sequential, $type );
885
    if ( null !== $check ) {
886
        return $check;
887
    }
888
889
    if ( wpinv_sequential_number_active() ) {
890
        $number = wpinv_get_next_invoice_number();
891
892
        if ( $save_sequential ) {
893
            update_option( 'wpinv_last_invoice_number', $number );
894
        }
895
    } else {
896
        $number = $post_ID;
897
    }
898
899
    $number = wpinv_format_invoice_number( $number );
900
901
    update_post_meta( $post_ID, '_wpinv_number', $number );
902
903
    $wpdb->update( $wpdb->posts, array( 'post_title' => $number ), array( 'ID' => $post_ID ) );
904
905
    clean_post_cache( $post_ID );
906
907
    return $number;
908
}
909
910
function wpinv_post_name_prefix( $post_type = 'wpi_invoice' ) {
911
    return apply_filters( 'wpinv_post_name_prefix', 'inv-', $post_type );
912
}
913
914
function wpinv_generate_post_name( $post_ID ) {
915
    $prefix = wpinv_post_name_prefix( get_post_type( $post_ID ) );
916
    $post_name = sanitize_title( $prefix . $post_ID );
917
918
    return apply_filters( 'wpinv_generate_post_name', $post_name, $post_ID, $prefix );
919
}
920
921
/**
922
 * Checks if an invoice was viewed by the customer.
923
 * 
924
 * @param int|string|object|WPInv_Invoice|WPInv_Legacy_Invoice|WP_Post $invoice Invoice id, key, transaction id, number or object.
925
 */
926
function wpinv_is_invoice_viewed( $invoice ) {
927
    $invoice = new WPInv_Invoice( $invoice );
928
    return (bool) $invoice->get_is_viewed();
929
}
930
931
/**
932
 * Marks an invoice as viewed.
933
 * 
934
 * @param int|string|object|WPInv_Invoice|WPInv_Legacy_Invoice|WP_Post $invoice Invoice id, key, transaction id, number or object.
935
 */
936
function getpaid_maybe_mark_invoice_as_viewed( $invoice ) {
937
    $invoice = new WPInv_Invoice( $invoice );
938
939
    if ( get_current_user_id() == $invoice->get_user_id() && ! $invoice->get_is_viewed() ) {
940
        $invoice->set_is_viewed( true );
941
        $invoice->save();
942
    }
943
944
}
945
add_action( 'wpinv_invoice_print_before_display', 'getpaid_maybe_mark_invoice_as_viewed' );
946
add_action( 'wpinv_before_receipt', 'getpaid_maybe_mark_invoice_as_viewed' );
947
948
/**
949
 * Fetch a subscription given an invoice.
950
 *
951
 * @return WPInv_Subscription|bool
952
 */
953
function wpinv_get_subscription( $invoice ) {
954
955
    // Abort if we do not have an invoice.
956
    if ( empty( $invoice ) ) {
957
        return false;
958
    }
959
960
    // Retrieve the invoice.
961
    $invoice = new WPInv_Invoice( $invoice );
962
963
    // Ensure it is a recurring invoice.
964
    if ( ! $invoice->is_recurring() ) {
965
        return false;
966
    }
967
968
    // Fetch the subscription handler.
969
    $subs_db    = new WPInv_Subscriptions_DB();
970
971
    // Fetch the parent in case it is a renewal.
972
    if ( $invoice->is_renewal() ) {
973
        $subs = $subs_db->get_subscriptions( array( 'parent_payment_id' => $invoice->get_parent_id(), 'number' => 1 ) );
974
    } else {
975
        $subs = $subs_db->get_subscriptions( array( 'parent_payment_id' => $invoice->get_id(), 'number' => 1 ) );
976
    }
977
978
    // Return the subscription if it exists.
979
    if ( ! empty( $subs ) ) {
980
        return reset( $subs );
981
    }
982
983
    return false;
984
}
985
986
/**
987
 * Processes an invoice refund.
988
 * 
989
 * @param int $invoice_id
990
 * @param WPInv_Invoice $invoice
991
 * @param array $status_transition
992
 * @todo: descrease customer/store earnings
993
 */
994
function getpaid_maybe_process_refund( $invoice_id, $invoice, $status_transition ) {
995
996
    if ( empty( $status_transition['from'] ) || ! in_array( $status_transition['from'], array( 'publish', 'wpi-processing', 'wpi-renewal' ) ) ) {
997
        return;
998
    }
999
1000
    $discount_code = $invoice->get_discount_code();
1001
    if ( ! empty( $discount_code ) ) {
1002
        $discount = wpinv_get_discount_obj( $discount_code );
1003
1004
        if ( $discount->exists() ) {
1005
            $discount->increase_usage( -1 );
1006
        }
1007
1008
    }
1009
1010
    do_action( 'wpinv_pre_refund_invoice', $invoice, $invoice_id );
1011
    do_action( 'wpinv_refund_invoice', $invoice, $invoice_id );
1012
    do_action( 'wpinv_post_refund_invoice', $invoice, $invoice_id );
1013
}
1014
add_action( 'getpaid_invoice_status_wpi-refunded', 'getpaid_maybe_process_refund', 10, 3 );
1015
1016
1017
/**
1018
 * Processes invoice payments.
1019
 *
1020
 * @param int $invoice_id
1021
 */
1022
function getpaid_process_invoice_payment( $invoice_id ) {
1023
1024
    // Fetch the invoice.
1025
    $invoice = new WPInv_Invoice( $invoice_id );
1026
1027
    // We only want to do this once.
1028
    if ( 1 ==  get_post_meta( $invoice_id, 'wpinv_processed_payment', true ) ) {
1029
        return;
1030
    }
1031
1032
    update_post_meta( $invoice_id, 'wpinv_processed_payment', 1 );
1033
1034
    // Fires when processing a payment.
1035
    do_action( 'getpaid_process_payment', $invoice );
1036
1037
    // Fire an action for each invoice item.
1038
    foreach( $invoice->get_items() as $item ) {
1039
        do_action( 'getpaid_process_item_payment', $item, $invoice );
1040
    }
1041
1042
    // Increase discount usage.
1043
    $discount_code = $invoice->get_discount_code();
1044
    if ( ! empty( $discount_code ) ) {
1045
        $discount = wpinv_get_discount_obj( $discount_code );
1046
1047
        if ( $discount->exists() ) {
1048
            $discount->increase_usage();
1049
        }
1050
1051
    }
1052
1053
    // Record reverse vat.
1054
    if ( 'invoice' == $invoice->get_type() && wpinv_use_taxes() && ! $invoice->get_disable_taxes() ) {
1055
1056
        if ( WPInv_EUVat::same_country_rule() == 'no' && wpinv_is_base_country( $invoice->get_country() ) ) {
1057
            $invoice->add_note( __( 'VAT was reverse charged', 'invoicing' ), false, false, true );
1058
        }
1059
1060
    }
1061
1062
}
1063
add_action( 'getpaid_invoice_payment_status_changed', 'getpaid_process_invoice_payment' );
1064
1065
/**
1066
 * Returns an array of invoice item columns
1067
 * 
1068
 * @param int|WPInv_Invoice $invoice
1069
 * @return array
1070
 */
1071
function getpaid_invoice_item_columns( $invoice ) {
1072
1073
    // Prepare the invoice.
1074
    $invoice = new WPInv_Invoice( $invoice );
1075
1076
    // Abort if there is no invoice.
1077
    if ( 0 == $invoice->get_id() ) {
1078
        return array();
1079
    }
1080
1081
    // Line item columns.
1082
    $columns = apply_filters(
1083
        'getpaid_invoice_item_columns',
1084
        array(
1085
            'name'     => __( 'Item', 'invoicing' ),
1086
            'price'    => __( 'Price', 'invoicing' ),
1087
            'quantity' => __( 'Quantity', 'invoicing' ),
1088
            'subtotal' => __( 'Subtotal', 'invoicing' ),
1089
        ),
1090
        $invoice
1091
    );
1092
1093
    // Quantities.
1094
    if ( isset( $columns[ 'quantity' ] ) ) {
1095
1096
        if ( 'hours' == $invoice->get_template() ) {
1097
            $columns[ 'quantity' ] = __( 'Hours', 'invoicing' );
1098
        }
1099
1100
        if ( ! wpinv_item_quantities_enabled() || 'amount' == $invoice->get_template() ) {
1101
            unset( $columns[ 'quantity' ] );
1102
        }
1103
1104
    }
1105
1106
1107
    // Price.
1108
    if ( isset( $columns[ 'price' ] ) ) {
1109
1110
        if ( 'amount' == $invoice->get_template() ) {
1111
            $columns[ 'price' ] = __( 'Amount', 'invoicing' );
1112
        }
1113
1114
        if ( 'hours' == $invoice->get_template() ) {
1115
            $columns[ 'price' ] = __( 'Rate', 'invoicing' );
1116
        }
1117
1118
    }
1119
1120
1121
    // Sub total.
1122
    if ( isset( $columns[ 'subtotal' ] ) ) {
1123
1124
        if ( 'amount' == $invoice->get_template() ) {
1125
            unset( $columns[ 'subtotal' ] );
1126
        }
1127
1128
    }
1129
1130
    return $columns;
1131
}
1132
1133
/**
1134
 * Returns an array of invoice totals rows
1135
 * 
1136
 * @param int|WPInv_Invoice $invoice
1137
 * @return array
1138
 */
1139
function getpaid_invoice_totals_rows( $invoice ) {
1140
1141
    // Prepare the invoice.
1142
    $invoice = new WPInv_Invoice( $invoice );
1143
1144
    // Abort if there is no invoice.
1145
    if ( 0 == $invoice->get_id() ) {
1146
        return array();
1147
    }
1148
1149
    $totals = apply_filters(
1150
        'getpaid_invoice_totals_rows',
1151
        array(
1152
            'subtotal' => __( 'Subtotal', 'invoicing' ),
1153
            'tax'      => __( 'Tax', 'invoicing' ),
1154
            'discount' => __( 'Discount', 'invoicing' ),
1155
            'total'    => __( 'Total', 'invoicing' ),
1156
        ),
1157
        $invoice
1158
    );
1159
1160
    if ( ( $invoice->get_disable_taxes() || ! wpinv_use_taxes() ) && isset( $totals['tax'] ) ) {
1161
        unset( $totals['tax'] );
1162
    }
1163
1164
    return $totals;
1165
}
1166
1167
/**
1168
 * This function is called whenever an invoice is created.
1169
 * 
1170
 * @param int $invoice_id
1171
 * @param WPInv_Invoice $invoice
1172
 */
1173
function getpaid_new_invoice( $invoice_id, $invoice ) {
0 ignored issues
show
Unused Code introduced by
The parameter $invoice_id is not used and could be removed. ( Ignorable by Annotation )

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

1173
function getpaid_new_invoice( /** @scrutinizer ignore-unused */ $invoice_id, $invoice ) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1174
1175
    // Add an invoice created note.
1176
    $invoice->add_note(
1177
        wp_sprintf(
1178
            __( 'Invoice created with the status "%s".', 'invoicing' ),
1179
            wpinv_status_nicename( $invoice->get_status() )
1180
        )
1181
    );
1182
1183
}
1184
add_action( 'getpaid_new_invoice', 'getpaid_new_invoice', 10, 2 );
1185
1186
/**
1187
 * This function updates invoice caches.
1188
 * 
1189
 * @param int $invoice_id
1190
 * @param WPInv_Invoice $invoice
1191
 */
1192
function getpaid_update_invoice_caches( $invoice_id, $invoice ) {
1193
1194
    // Cache invoice number.
1195
    wp_cache_set( $invoice->get_number(), $invoice_id, "getpaid_invoice_numbers_to_invoice_ids" );
1196
1197
    // Cache invoice key.
1198
    wp_cache_set( $invoice->get_key(), $invoice_id, "getpaid_invoice_keys_to_invoice_ids" );
1199
1200
    // (Maybe) cache transaction id.
1201
    $transaction_id = $invoice->get_transaction_id();
1202
1203
    if ( ! empty( $transaction_id ) ) {
1204
        wp_cache_set( $transaction_id, $invoice_id, "getpaid_invoice_transaction_ids_to_invoice_ids" );
1205
    }
1206
1207
}
1208
add_action( 'getpaid_new_invoice', 'getpaid_update_invoice_caches', 5, 2 );
1209
add_action( 'getpaid_update_invoice', 'getpaid_update_invoice_caches', 5, 2 );
1210