Completed
Branch FET/update-txn-admin-request-p... (ba73e5)
by
unknown
07:46 queued 05:48
created
admin_pages/transactions/Transactions_Admin_Page.core.php 2 patches
Indentation   +2525 added lines, -2525 removed lines patch added patch discarded remove patch
@@ -13,2529 +13,2529 @@
 block discarded – undo
13 13
 class Transactions_Admin_Page extends EE_Admin_Page
14 14
 {
15 15
 
16
-    /**
17
-     * @var EE_Transaction
18
-     */
19
-    private $_transaction;
20
-
21
-    /**
22
-     * @var EE_Session
23
-     */
24
-    private $_session;
25
-
26
-    /**
27
-     * @var array $_txn_status
28
-     */
29
-    private static $_txn_status;
30
-
31
-    /**
32
-     * @var array $_pay_status
33
-     */
34
-    private static $_pay_status;
35
-
36
-    /**
37
-     * @var array $_existing_reg_payment_REG_IDs
38
-     */
39
-    protected $_existing_reg_payment_REG_IDs;
40
-
41
-
42
-    /**
43
-     *    _init_page_props
44
-     *
45
-     * @return void
46
-     */
47
-    protected function _init_page_props()
48
-    {
49
-        $this->page_slug        = TXN_PG_SLUG;
50
-        $this->page_label       = esc_html__('Transactions', 'event_espresso');
51
-        $this->_admin_base_url  = TXN_ADMIN_URL;
52
-        $this->_admin_base_path = TXN_ADMIN;
53
-    }
54
-
55
-
56
-    /**
57
-     *    _ajax_hooks
58
-     *
59
-     * @return void
60
-     */
61
-    protected function _ajax_hooks()
62
-    {
63
-        add_action('wp_ajax_espresso_apply_payment', [$this, 'apply_payments_or_refunds']);
64
-        add_action('wp_ajax_espresso_apply_refund', [$this, 'apply_payments_or_refunds']);
65
-        add_action('wp_ajax_espresso_delete_payment', [$this, 'delete_payment']);
66
-    }
67
-
68
-
69
-    /**
70
-     *    _define_page_props
71
-     *
72
-     * @return void
73
-     */
74
-    protected function _define_page_props()
75
-    {
76
-        $this->_admin_page_title = $this->page_label;
77
-        $this->_labels           = [
78
-            'buttons' => [
79
-                'add'    => esc_html__('Add New Transaction', 'event_espresso'),
80
-                'edit'   => esc_html__('Edit Transaction', 'event_espresso'),
81
-                'delete' => esc_html__('Delete Transaction', 'event_espresso'),
82
-            ],
83
-        ];
84
-    }
85
-
86
-
87
-    /**
88
-     *        grab url requests and route them
89
-     *
90
-     * @access private
91
-     * @return void
92
-     * @throws EE_Error
93
-     * @throws InvalidArgumentException
94
-     * @throws InvalidDataTypeException
95
-     * @throws InvalidInterfaceException
96
-     */
97
-    public function _set_page_routes()
98
-    {
99
-
100
-        $this->_set_transaction_status_array();
101
-        $TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
102
-
103
-        $this->_page_routes = [
104
-
105
-            'default' => [
106
-                'func'       => '_transactions_overview_list_table',
107
-                'capability' => 'ee_read_transactions',
108
-            ],
109
-
110
-            'view_transaction' => [
111
-                'func'       => '_transaction_details',
112
-                'capability' => 'ee_read_transaction',
113
-                'obj_id'     => $TXN_ID,
114
-            ],
115
-
116
-            'send_payment_reminder' => [
117
-                'func'       => '_send_payment_reminder',
118
-                'noheader'   => true,
119
-                'capability' => 'ee_send_message',
120
-            ],
121
-
122
-            'espresso_apply_payment' => [
123
-                'func'       => 'apply_payments_or_refunds',
124
-                'noheader'   => true,
125
-                'capability' => 'ee_edit_payments',
126
-            ],
127
-
128
-            'espresso_apply_refund' => [
129
-                'func'       => 'apply_payments_or_refunds',
130
-                'noheader'   => true,
131
-                'capability' => 'ee_edit_payments',
132
-            ],
133
-
134
-            'espresso_delete_payment' => [
135
-                'func'       => 'delete_payment',
136
-                'noheader'   => true,
137
-                'capability' => 'ee_delete_payments',
138
-            ],
139
-
140
-            'espresso_recalculate_line_items' => [
141
-                'func'       => 'recalculateLineItems',
142
-                'noheader'   => true,
143
-                'capability' => 'ee_edit_payments',
144
-            ],
145
-
146
-        ];
147
-    }
148
-
149
-
150
-    protected function _set_page_config()
151
-    {
152
-        $TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
153
-        $this->_page_config = [
154
-            'default'          => [
155
-                'nav'           => [
156
-                    'label' => esc_html__('Overview', 'event_espresso'),
157
-                    'order' => 10,
158
-                ],
159
-                'list_table'    => 'EE_Admin_Transactions_List_Table',
160
-                'help_tabs'     => [
161
-                    'transactions_overview_help_tab'                       => [
162
-                        'title'    => esc_html__('Transactions Overview', 'event_espresso'),
163
-                        'filename' => 'transactions_overview',
164
-                    ],
165
-                    'transactions_overview_table_column_headings_help_tab' => [
166
-                        'title'    => esc_html__('Transactions Table Column Headings', 'event_espresso'),
167
-                        'filename' => 'transactions_overview_table_column_headings',
168
-                    ],
169
-                    'transactions_overview_views_filters_help_tab'         => [
170
-                        'title'    => esc_html__('Transaction Views & Filters & Search', 'event_espresso'),
171
-                        'filename' => 'transactions_overview_views_filters_search',
172
-                    ],
173
-                ],
174
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
175
-                // 'help_tour'     => array('Transactions_Overview_Help_Tour'),
176
-                /**
177
-                 * commented out because currently we are not displaying tips for transaction list table status but this
178
-                 * may change in a later iteration so want to keep the code for then.
179
-                 */
180
-                // 'qtips' => array( 'Transactions_List_Table_Tips' ),
181
-                'require_nonce' => false,
182
-            ],
183
-            'view_transaction' => [
184
-                'nav'       => [
185
-                    'label'      => esc_html__('View Transaction', 'event_espresso'),
186
-                    'order'      => 5,
187
-                    'url'        => $TXN_ID
188
-                        ? add_query_arg(['TXN_ID' => $TXN_ID], $this->_current_page_view_url)
189
-                        : $this->_admin_base_url,
190
-                    'persistent' => false,
191
-                ],
192
-                'help_tabs' => [
193
-                    'transactions_view_transaction_help_tab'                                              => [
194
-                        'title'    => esc_html__('View Transaction', 'event_espresso'),
195
-                        'filename' => 'transactions_view_transaction',
196
-                    ],
197
-                    'transactions_view_transaction_transaction_details_table_help_tab'                    => [
198
-                        'title'    => esc_html__('Transaction Details Table', 'event_espresso'),
199
-                        'filename' => 'transactions_view_transaction_transaction_details_table',
200
-                    ],
201
-                    'transactions_view_transaction_attendees_registered_help_tab'                         => [
202
-                        'title'    => esc_html__('Attendees Registered', 'event_espresso'),
203
-                        'filename' => 'transactions_view_transaction_attendees_registered',
204
-                    ],
205
-                    'transactions_view_transaction_views_primary_registrant_billing_information_help_tab' => [
206
-                        'title'    => esc_html__('Primary Registrant & Billing Information', 'event_espresso'),
207
-                        'filename' => 'transactions_view_transaction_primary_registrant_billing_information',
208
-                    ],
209
-                ],
210
-                'qtips'     => ['Transaction_Details_Tips'],
211
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
212
-                // 'help_tour' => array('Transaction_Details_Help_Tour'),
213
-                'metaboxes' => ['_transaction_details_metaboxes'],
214
-
215
-                'require_nonce' => false,
216
-            ],
217
-        ];
218
-    }
219
-
220
-
221
-    /**
222
-     * The below methods aren't used by this class currently
223
-     */
224
-    protected function _add_screen_options()
225
-    {
226
-        // noop
227
-    }
228
-
229
-
230
-    protected function _add_feature_pointers()
231
-    {
232
-        // noop
233
-    }
234
-
235
-
236
-    public function admin_init()
237
-    {
238
-        $EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
239
-        $event_name = $this->request->getRequestParam('event_name');
240
-        $redirect_from = $this->request->getRequestParam('redirect_from', '', 'url');
241
-        // IF a registration was JUST added via the admin...
242
-        if ($EVT_ID && $event_name && $redirect_from) {
243
-            // then set a cookie so that we can block any attempts to use
244
-            // the back button as a way to enter another registration.
245
-            setcookie('ee_registration_added', $EVT_ID, time() + WEEK_IN_SECONDS, '/');
246
-            // and update the global
247
-            $_COOKIE['ee_registration_added'] = $EVT_ID;
248
-        }
249
-        EE_Registry::$i18n_js_strings['invalid_server_response'] = esc_html__(
250
-            'An error occurred! Your request may have been processed, but a valid response from the server was not received. Please refresh the page and try again.',
251
-            'event_espresso'
252
-        );
253
-        EE_Registry::$i18n_js_strings['error_occurred']          = esc_html__(
254
-            'An error occurred! Please refresh the page and try again.',
255
-            'event_espresso'
256
-        );
257
-        EE_Registry::$i18n_js_strings['txn_status_array']        = self::$_txn_status;
258
-        EE_Registry::$i18n_js_strings['pay_status_array']        = self::$_pay_status;
259
-        EE_Registry::$i18n_js_strings['payments_total']          = esc_html__('Payments Total', 'event_espresso');
260
-        EE_Registry::$i18n_js_strings['transaction_overpaid']    = esc_html__(
261
-            'This transaction has been overpaid ! Payments Total',
262
-            'event_espresso'
263
-        );
264
-    }
265
-
266
-
267
-    public function admin_notices()
268
-    {
269
-        // noop
270
-    }
271
-
272
-
273
-    public function admin_footer_scripts()
274
-    {
275
-        // noop
276
-    }
277
-
278
-
279
-    /**
280
-     * _set_transaction_status_array
281
-     * sets list of transaction statuses
282
-     *
283
-     * @access private
284
-     * @return void
285
-     * @throws EE_Error
286
-     * @throws InvalidArgumentException
287
-     * @throws InvalidDataTypeException
288
-     * @throws InvalidInterfaceException
289
-     */
290
-    private function _set_transaction_status_array()
291
-    {
292
-        self::$_txn_status = EEM_Transaction::instance()->status_array(true);
293
-    }
294
-
295
-
296
-    /**
297
-     * get_transaction_status_array
298
-     * return the transaction status array for wp_list_table
299
-     *
300
-     * @access public
301
-     * @return array
302
-     */
303
-    public function get_transaction_status_array()
304
-    {
305
-        return self::$_txn_status;
306
-    }
307
-
308
-
309
-    /**
310
-     *    get list of payment statuses
311
-     *
312
-     * @access private
313
-     * @return void
314
-     * @throws EE_Error
315
-     * @throws InvalidArgumentException
316
-     * @throws InvalidDataTypeException
317
-     * @throws InvalidInterfaceException
318
-     */
319
-    private function _get_payment_status_array()
320
-    {
321
-        self::$_pay_status                      = EEM_Payment::instance()->status_array(true);
322
-        $this->_template_args['payment_status'] = self::$_pay_status;
323
-    }
324
-
325
-
326
-    /**
327
-     *    _add_screen_options_default
328
-     *
329
-     * @access protected
330
-     * @return void
331
-     * @throws InvalidArgumentException
332
-     * @throws InvalidDataTypeException
333
-     * @throws InvalidInterfaceException
334
-     */
335
-    protected function _add_screen_options_default()
336
-    {
337
-        $this->_per_page_screen_option();
338
-    }
339
-
340
-
341
-    /**
342
-     * load_scripts_styles
343
-     *
344
-     * @access public
345
-     * @return void
346
-     */
347
-    public function load_scripts_styles()
348
-    {
349
-        // enqueue style
350
-        wp_register_style(
351
-            'espresso_txn',
352
-            TXN_ASSETS_URL . 'espresso_transactions_admin.css',
353
-            [],
354
-            EVENT_ESPRESSO_VERSION
355
-        );
356
-        wp_enqueue_style('espresso_txn');
357
-        // scripts
358
-        wp_register_script(
359
-            'espresso_txn',
360
-            TXN_ASSETS_URL . 'espresso_transactions_admin.js',
361
-            [
362
-                'ee_admin_js',
363
-                'ee-datepicker',
364
-                'jquery-ui-datepicker',
365
-                'jquery-ui-draggable',
366
-                'ee-dialog',
367
-                'ee-accounting',
368
-                'ee-serialize-full-array',
369
-            ],
370
-            EVENT_ESPRESSO_VERSION,
371
-            true
372
-        );
373
-        wp_enqueue_script('espresso_txn');
374
-    }
375
-
376
-
377
-    /**
378
-     *    load_scripts_styles_view_transaction
379
-     *
380
-     * @access public
381
-     * @return void
382
-     */
383
-    public function load_scripts_styles_view_transaction()
384
-    {
385
-        // styles
386
-        wp_enqueue_style('espresso-ui-theme');
387
-    }
388
-
389
-
390
-    /**
391
-     *    load_scripts_styles_default
392
-     *
393
-     * @access public
394
-     * @return void
395
-     */
396
-    public function load_scripts_styles_default()
397
-    {
398
-        // styles
399
-        wp_enqueue_style('espresso-ui-theme');
400
-    }
401
-
402
-
403
-    /**
404
-     *    _set_list_table_views_default
405
-     *
406
-     * @access protected
407
-     * @return void
408
-     */
409
-    protected function _set_list_table_views_default()
410
-    {
411
-        $this->_views = [
412
-            'all'        => [
413
-                'slug'  => 'all',
414
-                'label' => esc_html__('View All Transactions', 'event_espresso'),
415
-                'count' => 0,
416
-            ],
417
-            'abandoned'  => [
418
-                'slug'  => 'abandoned',
419
-                'label' => esc_html__('Abandoned Transactions', 'event_espresso'),
420
-                'count' => 0,
421
-            ],
422
-            'incomplete' => [
423
-                'slug'  => 'incomplete',
424
-                'label' => esc_html__('Incomplete Transactions', 'event_espresso'),
425
-                'count' => 0,
426
-            ],
427
-        ];
428
-        if (
429
-            /**
430
-             * Filters whether a link to the "Failed Transactions" list table
431
-             * appears on the Transactions Admin Page list table.
432
-             * List display can be turned back on via the following:
433
-             * add_filter(
434
-             *     'FHEE__Transactions_Admin_Page___set_list_table_views_default__display_failed_txns_list',
435
-             *     '__return_true'
436
-             * );
437
-             *
438
-             * @param boolean                 $display_failed_txns_list
439
-             * @param Transactions_Admin_Page $this
440
-             * @since 4.9.70.p
441
-             */
442
-            apply_filters(
443
-                'FHEE__Transactions_Admin_Page___set_list_table_views_default__display_failed_txns_list',
444
-                false,
445
-                $this
446
-            )
447
-        ) {
448
-            $this->_views['failed'] = [
449
-                'slug'  => 'failed',
450
-                'label' => esc_html__('Failed Transactions', 'event_espresso'),
451
-                'count' => 0,
452
-            ];
453
-        }
454
-    }
455
-
456
-
457
-    /**
458
-     * _set_transaction_object
459
-     * This sets the _transaction property for the transaction details screen
460
-     *
461
-     * @access private
462
-     * @return void
463
-     * @throws EE_Error
464
-     * @throws InvalidArgumentException
465
-     * @throws RuntimeException
466
-     * @throws InvalidDataTypeException
467
-     * @throws InvalidInterfaceException
468
-     * @throws ReflectionException
469
-     */
470
-    private function _set_transaction_object()
471
-    {
472
-        if ($this->_transaction instanceof EE_Transaction) {
473
-            return;
474
-        } //get out we've already set the object
475
-
476
-        $TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
477
-
478
-        // get transaction object
479
-        $this->_transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
480
-        $this->_session     = $this->_transaction instanceof EE_Transaction
481
-            ? $this->_transaction->session_data()
482
-            : null;
483
-        if ($this->_transaction instanceof EE_Transaction) {
484
-            $this->_transaction->verify_abandoned_transaction_status();
485
-        }
486
-
487
-        if (! $this->_transaction instanceof EE_Transaction) {
488
-            $error_msg = sprintf(
489
-                esc_html__(
490
-                    'An error occurred and the details for the transaction with the ID # %d could not be retrieved.',
491
-                    'event_espresso'
492
-                ),
493
-                $TXN_ID
494
-            );
495
-            EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
496
-        }
497
-    }
498
-
499
-
500
-    /**
501
-     *    _transaction_legend_items
502
-     *
503
-     * @access protected
504
-     * @return array
505
-     * @throws EE_Error
506
-     * @throws InvalidArgumentException
507
-     * @throws ReflectionException
508
-     * @throws InvalidDataTypeException
509
-     * @throws InvalidInterfaceException
510
-     */
511
-    protected function _transaction_legend_items()
512
-    {
513
-        EE_Registry::instance()->load_helper('MSG_Template');
514
-        $items = [];
515
-
516
-        if (
517
-            EE_Registry::instance()->CAP->current_user_can(
518
-                'ee_read_global_messages',
519
-                'view_filtered_messages'
520
-            )
521
-        ) {
522
-            $related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
523
-            if (
524
-                is_array($related_for_icon)
525
-                && isset($related_for_icon['css_class'], $related_for_icon['label'])
526
-            ) {
527
-                $items['view_related_messages'] = [
528
-                    'class' => $related_for_icon['css_class'],
529
-                    'desc'  => $related_for_icon['label'],
530
-                ];
531
-            }
532
-        }
533
-
534
-        $items = apply_filters(
535
-            'FHEE__Transactions_Admin_Page___transaction_legend_items__items',
536
-            array_merge(
537
-                $items,
538
-                [
539
-                    'view_details'          => [
540
-                        'class' => 'dashicons dashicons-cart',
541
-                        'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
542
-                    ],
543
-                    'view_invoice'          => [
544
-                        'class' => 'dashicons dashicons-media-spreadsheet',
545
-                        'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
546
-                    ],
547
-                    'view_receipt'          => [
548
-                        'class' => 'dashicons dashicons-media-default',
549
-                        'desc'  => esc_html__('View Transaction Receipt', 'event_espresso'),
550
-                    ],
551
-                    'view_registration'     => [
552
-                        'class' => 'dashicons dashicons-clipboard',
553
-                        'desc'  => esc_html__('View Registration Details', 'event_espresso'),
554
-                    ],
555
-                    'payment_overview_link' => [
556
-                        'class' => 'dashicons dashicons-money',
557
-                        'desc'  => esc_html__('Make Payment on Frontend', 'event_espresso'),
558
-                    ],
559
-                ]
560
-            )
561
-        );
562
-
563
-        if (
564
-            EEH_MSG_Template::is_mt_active('payment_reminder')
565
-            && EE_Registry::instance()->CAP->current_user_can(
566
-                'ee_send_message',
567
-                'espresso_transactions_send_payment_reminder'
568
-            )
569
-        ) {
570
-            $items['send_payment_reminder'] = [
571
-                'class' => 'dashicons dashicons-email-alt',
572
-                'desc'  => esc_html__('Send Payment Reminder', 'event_espresso'),
573
-            ];
574
-        } else {
575
-            $items['blank*'] = [
576
-                'class' => '',
577
-                'desc'  => '',
578
-            ];
579
-        }
580
-        $more_items = apply_filters(
581
-            'FHEE__Transactions_Admin_Page___transaction_legend_items__more_items',
582
-            [
583
-                'overpaid'   => [
584
-                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::overpaid_status_code,
585
-                    'desc'  => EEH_Template::pretty_status(
586
-                        EEM_Transaction::overpaid_status_code,
587
-                        false,
588
-                        'sentence'
589
-                    ),
590
-                ],
591
-                'complete'   => [
592
-                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::complete_status_code,
593
-                    'desc'  => EEH_Template::pretty_status(
594
-                        EEM_Transaction::complete_status_code,
595
-                        false,
596
-                        'sentence'
597
-                    ),
598
-                ],
599
-                'incomplete' => [
600
-                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::incomplete_status_code,
601
-                    'desc'  => EEH_Template::pretty_status(
602
-                        EEM_Transaction::incomplete_status_code,
603
-                        false,
604
-                        'sentence'
605
-                    ),
606
-                ],
607
-                'abandoned'  => [
608
-                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::abandoned_status_code,
609
-                    'desc'  => EEH_Template::pretty_status(
610
-                        EEM_Transaction::abandoned_status_code,
611
-                        false,
612
-                        'sentence'
613
-                    ),
614
-                ],
615
-                'failed'     => [
616
-                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::failed_status_code,
617
-                    'desc'  => EEH_Template::pretty_status(
618
-                        EEM_Transaction::failed_status_code,
619
-                        false,
620
-                        'sentence'
621
-                    ),
622
-                ],
623
-            ]
624
-        );
625
-
626
-        return array_merge($items, $more_items);
627
-    }
628
-
629
-
630
-    /**
631
-     *    _transactions_overview_list_table
632
-     *
633
-     * @access protected
634
-     * @return void
635
-     * @throws DomainException
636
-     * @throws EE_Error
637
-     * @throws InvalidArgumentException
638
-     * @throws InvalidDataTypeException
639
-     * @throws InvalidInterfaceException
640
-     * @throws ReflectionException
641
-     */
642
-    protected function _transactions_overview_list_table()
643
-    {
644
-        $this->_admin_page_title = esc_html__('Transactions', 'event_espresso');
645
-
646
-        $EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
647
-        $event = EEM_Event::instance()->get_one_by_ID($EVT_ID);
648
-        $this->_template_args['admin_page_header'] = $event instanceof EE_Event
649
-            ? sprintf(
650
-                esc_html__('%sViewing Transactions for the Event: %s%s', 'event_espresso'),
651
-                '<h3>',
652
-                '<a href="'
653
-                . EE_Admin_Page::add_query_args_and_nonce(
654
-                    ['action' => 'edit', 'post' => $event->ID()],
655
-                    EVENTS_ADMIN_URL
656
-                )
657
-                . '" title="'
658
-                . esc_attr__('Click to Edit event', 'event_espresso')
659
-                . '">' . $event->name() . '</a>',
660
-                '</h3>'
661
-            )
662
-            : '';
663
-        $this->_template_args['after_list_table']  = $this->_display_legend($this->_transaction_legend_items());
664
-        $this->display_admin_list_table_page_with_no_sidebar();
665
-    }
666
-
667
-
668
-    /**
669
-     *    _transaction_details
670
-     * generates HTML for the View Transaction Details Admin page
671
-     *
672
-     * @access protected
673
-     * @return void
674
-     * @throws DomainException
675
-     * @throws EE_Error
676
-     * @throws InvalidArgumentException
677
-     * @throws InvalidDataTypeException
678
-     * @throws InvalidInterfaceException
679
-     * @throws RuntimeException
680
-     * @throws ReflectionException
681
-     */
682
-    protected function _transaction_details()
683
-    {
684
-        do_action('AHEE__Transactions_Admin_Page__transaction_details__start', $this->_transaction);
685
-
686
-        $this->_set_transaction_status_array();
687
-
688
-        $this->_template_args                      = [];
689
-        $this->_template_args['transactions_page'] = $this->_wp_page_slug;
690
-
691
-        $this->_set_transaction_object();
692
-
693
-        if (! $this->_transaction instanceof EE_Transaction) {
694
-            return;
695
-        }
696
-
697
-        $this->_template_args['txn_nmbr']['value'] = $this->_transaction->ID();
698
-        $this->_template_args['txn_nmbr']['label'] = esc_html__('Transaction Number', 'event_espresso');
699
-
700
-        $this->_template_args['txn_datetime']['value'] = $this->_transaction->get_i18n_datetime('TXN_timestamp');
701
-        $this->_template_args['txn_datetime']['label'] = esc_html__('Date', 'event_espresso');
702
-
703
-        $this->_template_args['txn_status']['value'] = self::$_txn_status[ $this->_transaction->status_ID() ];
704
-        $this->_template_args['txn_status']['label'] = esc_html__('Transaction Status', 'event_espresso');
705
-        $this->_template_args['txn_status']['class'] = 'status-' . $this->_transaction->status_ID();
706
-
707
-        $this->_template_args['grand_total'] = $this->_transaction->total();
708
-        $this->_template_args['total_paid']  = $this->_transaction->paid();
709
-
710
-        $amount_due                         = $this->_transaction->total() - $this->_transaction->paid();
711
-        $this->_template_args['amount_due'] = EEH_Template::format_currency(
712
-            $amount_due,
713
-            true
714
-        );
715
-        if (EE_Registry::instance()->CFG->currency->sign_b4) {
716
-            $this->_template_args['amount_due'] = EE_Registry::instance()->CFG->currency->sign
717
-                                                  . $this->_template_args['amount_due'];
718
-        } else {
719
-            $this->_template_args['amount_due'] .= EE_Registry::instance()->CFG->currency->sign;
720
-        }
721
-        $this->_template_args['amount_due_class'] = '';
722
-
723
-        if ($this->_transaction->paid() === $this->_transaction->total()) {
724
-            // paid in full
725
-            $this->_template_args['amount_due'] = false;
726
-        } elseif ($this->_transaction->paid() > $this->_transaction->total()) {
727
-            // overpaid
728
-            $this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
729
-        } elseif ($this->_transaction->total() > (float) 0) {
730
-            if ($this->_transaction->paid() > (float) 0) {
731
-                // monies owing
732
-                $this->_template_args['amount_due_class'] = 'txn-overview-part-payment-spn';
733
-            } elseif ($this->_transaction->paid() === (float) 0) {
734
-                // no payments made yet
735
-                $this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
736
-            }
737
-        } elseif ($this->_transaction->total() === (float) 0) {
738
-            // free event
739
-            $this->_template_args['amount_due'] = false;
740
-        }
741
-
742
-        $payment_method = $this->_transaction->payment_method();
743
-
744
-        $this->_template_args['method_of_payment_name'] = $payment_method instanceof EE_Payment_Method
745
-            ? $payment_method->admin_name()
746
-            : esc_html__('Unknown', 'event_espresso');
747
-
748
-        $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
749
-        // link back to overview
750
-        $this->_template_args['txn_overview_url'] = $this->request->getServerParam(
751
-            'HTTP_REFERER',
752
-            TXN_ADMIN_URL
753
-        );
754
-
755
-
756
-        // next link
757
-        $next_txn                                 = $this->_transaction->next(
758
-            null,
759
-            [['STS_ID' => ['!=', EEM_Transaction::failed_status_code]]],
760
-            'TXN_ID'
761
-        );
762
-        $this->_template_args['next_transaction'] = $next_txn
763
-            ? $this->_next_link(
764
-                EE_Admin_Page::add_query_args_and_nonce(
765
-                    ['action' => 'view_transaction', 'TXN_ID' => $next_txn['TXN_ID']],
766
-                    TXN_ADMIN_URL
767
-                ),
768
-                'dashicons dashicons-arrow-right ee-icon-size-22'
769
-            )
770
-            : '';
771
-        // previous link
772
-        $previous_txn                                 = $this->_transaction->previous(
773
-            null,
774
-            [['STS_ID' => ['!=', EEM_Transaction::failed_status_code]]],
775
-            'TXN_ID'
776
-        );
777
-        $this->_template_args['previous_transaction'] = $previous_txn
778
-            ? $this->_previous_link(
779
-                EE_Admin_Page::add_query_args_and_nonce(
780
-                    ['action' => 'view_transaction', 'TXN_ID' => $previous_txn['TXN_ID']],
781
-                    TXN_ADMIN_URL
782
-                ),
783
-                'dashicons dashicons-arrow-left ee-icon-size-22'
784
-            )
785
-            : '';
786
-
787
-        $EVT_ID        = $this->request->getRequestParam('EVT_ID', 0, 'int');
788
-        $event_name    = $this->request->getRequestParam('event_name');
789
-        $redirect_from = $this->request->getRequestParam('redirect_from', '', 'url');
790
-
791
-        // were we just redirected here after adding a new registration ???
792
-        if ($EVT_ID && $event_name && $redirect_from) {
793
-            if (
794
-                EE_Registry::instance()->CAP->current_user_can(
795
-                    'ee_edit_registrations',
796
-                    'espresso_registrations_new_registration',
797
-                    $EVT_ID
798
-                )
799
-            ) {
800
-                $this->_admin_page_title .= '<a id="add-new-registration" class="add-new-h2 button-primary" href="';
801
-                $this->_admin_page_title .= EE_Admin_Page::add_query_args_and_nonce(
802
-                    [
803
-                        'page'     => 'espresso_registrations',
804
-                        'action'   => 'new_registration',
805
-                        'return'   => 'default',
806
-                        'TXN_ID'   => $this->_transaction->ID(),
807
-                        'event_id' => $EVT_ID,
808
-                    ],
809
-                    REG_ADMIN_URL
810
-                );
811
-                $this->_admin_page_title .= '">';
812
-
813
-                $this->_admin_page_title .= sprintf(
814
-                    esc_html__('Add Another New Registration to Event: "%1$s" ?', 'event_espresso'),
815
-                    htmlentities(urldecode($event_name), ENT_QUOTES, 'UTF-8')
816
-                );
817
-                $this->_admin_page_title .= '</a>';
818
-            }
819
-            EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
820
-        }
821
-        // grab messages at the last second
822
-        $this->_template_args['notices'] = EE_Error::get_notices();
823
-        // path to template
824
-        $template_path                             = TXN_TEMPLATE_PATH . 'txn_admin_details_header.template.php';
825
-        $this->_template_args['admin_page_header'] = EEH_Template::display_template(
826
-            $template_path,
827
-            $this->_template_args,
828
-            true
829
-        );
830
-
831
-        // the details template wrapper
832
-        $this->display_admin_page_with_sidebar();
833
-    }
834
-
835
-
836
-    /**
837
-     *        _transaction_details_metaboxes
838
-     *
839
-     * @access protected
840
-     * @return void
841
-     * @throws EE_Error
842
-     * @throws InvalidArgumentException
843
-     * @throws InvalidDataTypeException
844
-     * @throws InvalidInterfaceException
845
-     * @throws RuntimeException
846
-     * @throws ReflectionException
847
-     */
848
-    protected function _transaction_details_metaboxes()
849
-    {
850
-
851
-        $this->_set_transaction_object();
852
-
853
-        if (! $this->_transaction instanceof EE_Transaction) {
854
-            return;
855
-        }
856
-        add_meta_box(
857
-            'edit-txn-details-mbox',
858
-            esc_html__('Transaction Details', 'event_espresso'),
859
-            [$this, 'txn_details_meta_box'],
860
-            $this->_wp_page_slug,
861
-            'normal',
862
-            'high'
863
-        );
864
-        add_meta_box(
865
-            'edit-txn-attendees-mbox',
866
-            esc_html__('Attendees Registered in this Transaction', 'event_espresso'),
867
-            [$this, 'txn_attendees_meta_box'],
868
-            $this->_wp_page_slug,
869
-            'normal',
870
-            'high',
871
-            ['TXN_ID' => $this->_transaction->ID()]
872
-        );
873
-        add_meta_box(
874
-            'edit-txn-registrant-mbox',
875
-            esc_html__('Primary Contact', 'event_espresso'),
876
-            [$this, 'txn_registrant_side_meta_box'],
877
-            $this->_wp_page_slug,
878
-            'side',
879
-            'high'
880
-        );
881
-        add_meta_box(
882
-            'edit-txn-billing-info-mbox',
883
-            esc_html__('Billing Information', 'event_espresso'),
884
-            [$this, 'txn_billing_info_side_meta_box'],
885
-            $this->_wp_page_slug,
886
-            'side',
887
-            'high'
888
-        );
889
-    }
890
-
891
-
892
-    /**
893
-     * Callback for transaction actions metabox.
894
-     *
895
-     * @param EE_Transaction|null $transaction
896
-     * @return string
897
-     * @throws DomainException
898
-     * @throws EE_Error
899
-     * @throws InvalidArgumentException
900
-     * @throws InvalidDataTypeException
901
-     * @throws InvalidInterfaceException
902
-     * @throws ReflectionException
903
-     * @throws RuntimeException
904
-     */
905
-    public function getActionButtons(EE_Transaction $transaction = null)
906
-    {
907
-        $content = '';
908
-        $actions = [];
909
-        if (! $transaction instanceof EE_Transaction) {
910
-            return $content;
911
-        }
912
-        /** @var EE_Registration $primary_registration */
913
-        $primary_registration = $transaction->primary_registration();
914
-        $attendee             = $primary_registration instanceof EE_Registration
915
-            ? $primary_registration->attendee()
916
-            : null;
917
-
918
-        if (
919
-            $attendee instanceof EE_Attendee
920
-            && EE_Registry::instance()->CAP->current_user_can(
921
-                'ee_send_message',
922
-                'espresso_transactions_send_payment_reminder'
923
-            )
924
-        ) {
925
-            $actions['payment_reminder'] =
926
-                EEH_MSG_Template::is_mt_active('payment_reminder')
927
-                && $this->_transaction->status_ID() !== EEM_Transaction::complete_status_code
928
-                && $this->_transaction->status_ID() !== EEM_Transaction::overpaid_status_code
929
-                    ? EEH_Template::get_button_or_link(
930
-                        EE_Admin_Page::add_query_args_and_nonce(
931
-                            [
932
-                            'action'      => 'send_payment_reminder',
933
-                            'TXN_ID'      => $this->_transaction->ID(),
934
-                            'redirect_to' => 'view_transaction',
935
-                            ],
936
-                            TXN_ADMIN_URL
937
-                        ),
938
-                        esc_html__(' Send Payment Reminder', 'event_espresso'),
939
-                        'button secondary-button',
940
-                        'dashicons dashicons-email-alt'
941
-                    )
942
-                    : '';
943
-        }
944
-
945
-        if (
946
-            EE_Registry::instance()->CAP->current_user_can(
947
-                'ee_edit_payments',
948
-                'espresso_transactions_recalculate_line_items'
949
-            )
950
-        ) {
951
-            $actions['recalculate_line_items'] = EEH_Template::get_button_or_link(
952
-                EE_Admin_Page::add_query_args_and_nonce(
953
-                    [
954
-                        'action'      => 'espresso_recalculate_line_items',
955
-                        'TXN_ID'      => $this->_transaction->ID(),
956
-                        'redirect_to' => 'view_transaction',
957
-                    ],
958
-                    TXN_ADMIN_URL
959
-                ),
960
-                esc_html__(' Recalculate Taxes and Total', 'event_espresso'),
961
-                'button secondary-button',
962
-                'dashicons dashicons-update'
963
-            );
964
-        }
965
-
966
-        if (
967
-            $primary_registration instanceof EE_Registration
968
-            && EEH_MSG_Template::is_mt_active('receipt')
969
-        ) {
970
-            $actions['receipt'] = EEH_Template::get_button_or_link(
971
-                $primary_registration->receipt_url(),
972
-                esc_html__('View Receipt', 'event_espresso'),
973
-                'button secondary-button',
974
-                'dashicons dashicons-media-default'
975
-            );
976
-        }
977
-
978
-        if (
979
-            $primary_registration instanceof EE_Registration
980
-            && EEH_MSG_Template::is_mt_active('invoice')
981
-        ) {
982
-            $actions['invoice'] = EEH_Template::get_button_or_link(
983
-                $primary_registration->invoice_url(),
984
-                esc_html__('View Invoice', 'event_espresso'),
985
-                'button secondary-button',
986
-                'dashicons dashicons-media-spreadsheet'
987
-            );
988
-        }
989
-        $actions = array_filter(
990
-            apply_filters('FHEE__Transactions_Admin_Page__getActionButtons__actions', $actions, $transaction)
991
-        );
992
-        if ($actions) {
993
-            $content = '<ul>';
994
-            $content .= '<li>' . implode('</li><li>', $actions) . '</li>';
995
-            $content .= '</uL>';
996
-        }
997
-        return $content;
998
-    }
999
-
1000
-
1001
-    /**
1002
-     * txn_details_meta_box
1003
-     * generates HTML for the Transaction main meta box
1004
-     *
1005
-     * @return void
1006
-     * @throws DomainException
1007
-     * @throws EE_Error
1008
-     * @throws InvalidArgumentException
1009
-     * @throws InvalidDataTypeException
1010
-     * @throws InvalidInterfaceException
1011
-     * @throws RuntimeException
1012
-     * @throws ReflectionException
1013
-     */
1014
-    public function txn_details_meta_box()
1015
-    {
1016
-        $this->_set_transaction_object();
1017
-        $this->_template_args['TXN_ID']              = $this->_transaction->ID();
1018
-        $this->_template_args['attendee']            =
1019
-            $this->_transaction->primary_registration() instanceof EE_Registration
1020
-                ? $this->_transaction->primary_registration()->attendee()
1021
-                : null;
1022
-        $this->_template_args['can_edit_payments']   = EE_Registry::instance()->CAP->current_user_can(
1023
-            'ee_edit_payments',
1024
-            'apply_payment_or_refund_from_registration_details'
1025
-        );
1026
-        $this->_template_args['can_delete_payments'] = EE_Registry::instance()->CAP->current_user_can(
1027
-            'ee_delete_payments',
1028
-            'delete_payment_from_registration_details'
1029
-        );
1030
-
1031
-        // get line table
1032
-        EEH_Autoloader::register_line_item_display_autoloaders();
1033
-        $Line_Item_Display                       = new EE_Line_Item_Display(
1034
-            'admin_table',
1035
-            'EE_Admin_Table_Line_Item_Display_Strategy'
1036
-        );
1037
-        $this->_template_args['line_item_table'] = $Line_Item_Display->display_line_item(
1038
-            $this->_transaction->total_line_item()
1039
-        );
1040
-        $this->_template_args['REG_code']        =
1041
-            $this->_transaction->primary_registration() instanceof EE_Registration
1042
-                ? $this->_transaction->primary_registration()->reg_code()
1043
-                : null;
1044
-        // process taxes
1045
-        $taxes                         = $this->_transaction->line_items([['LIN_type' => EEM_Line_Item::type_tax]]);
1046
-        $this->_template_args['taxes'] = ! empty($taxes) ? $taxes : false;
1047
-
1048
-        $this->_template_args['grand_total']     = EEH_Template::format_currency(
1049
-            $this->_transaction->total(),
1050
-            false,
1051
-            false
1052
-        );
1053
-        $this->_template_args['grand_raw_total'] = $this->_transaction->total();
1054
-        $this->_template_args['TXN_status']      = $this->_transaction->status_ID();
1055
-
1056
-        // process payment details
1057
-        $payments = $this->_transaction->payments();
1058
-        if (! empty($payments)) {
1059
-            $this->_template_args['payments']              = $payments;
1060
-            $this->_template_args['existing_reg_payments'] = $this->_get_registration_payment_IDs($payments);
1061
-        } else {
1062
-            $this->_template_args['payments']              = false;
1063
-            $this->_template_args['existing_reg_payments'] = [];
1064
-        }
1065
-
1066
-        $this->_template_args['edit_payment_url']   = add_query_arg(['action' => 'edit_payment'], TXN_ADMIN_URL);
1067
-        $this->_template_args['delete_payment_url'] = add_query_arg(
1068
-            ['action' => 'espresso_delete_payment'],
1069
-            TXN_ADMIN_URL
1070
-        );
1071
-
1072
-        if (isset($txn_details['invoice_number'])) {
1073
-            $this->_template_args['txn_details']['invoice_number']['value'] = $this->_template_args['REG_code'];
1074
-            $this->_template_args['txn_details']['invoice_number']['label'] = esc_html__(
1075
-                'Invoice Number',
1076
-                'event_espresso'
1077
-            );
1078
-        }
1079
-
1080
-        $this->_template_args['txn_details']['registration_session']['value'] =
1081
-            $this->_transaction->primary_registration() instanceof EE_Registration
1082
-                ? $this->_transaction->primary_registration()->session_ID()
1083
-                : null;
1084
-        $this->_template_args['txn_details']['registration_session']['label'] = esc_html__(
1085
-            'Registration Session',
1086
-            'event_espresso'
1087
-        );
1088
-
1089
-        $this->_template_args['txn_details']['ip_address']['value'] = isset($this->_session['ip_address'])
1090
-            ? $this->_session['ip_address']
1091
-            : '';
1092
-        $this->_template_args['txn_details']['ip_address']['label'] = esc_html__(
1093
-            'Transaction placed from IP',
1094
-            'event_espresso'
1095
-        );
1096
-
1097
-        $this->_template_args['txn_details']['user_agent']['value'] = isset($this->_session['user_agent'])
1098
-            ? $this->_session['user_agent']
1099
-            : '';
1100
-        $this->_template_args['txn_details']['user_agent']['label'] = esc_html__(
1101
-            'Registrant User Agent',
1102
-            'event_espresso'
1103
-        );
1104
-
1105
-        $reg_steps = '<ul>';
1106
-        foreach ($this->_transaction->reg_steps() as $reg_step => $reg_step_status) {
1107
-            if ($reg_step_status === true) {
1108
-                $reg_steps .= '<li style="color:#70cc50">'
1109
-                              . sprintf(
1110
-                                  esc_html__('%1$s : Completed', 'event_espresso'),
1111
-                                  ucwords(str_replace('_', ' ', $reg_step))
1112
-                              )
1113
-                              . '</li>';
1114
-            } elseif ($reg_step_status !== false && is_numeric($reg_step_status)) {
1115
-                $reg_steps .= '<li style="color:#2EA2CC">'
1116
-                              . sprintf(
1117
-                                  esc_html__('%1$s : Initiated %2$s', 'event_espresso'),
1118
-                                  ucwords(str_replace('_', ' ', $reg_step)),
1119
-                                  date(
1120
-                                      get_option('date_format') . ' ' . get_option('time_format'),
1121
-                                      $reg_step_status + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1122
-                                  )
1123
-                              )
1124
-                              . '</li>';
1125
-            } else {
1126
-                $reg_steps .= '<li style="color:#E76700">'
1127
-                              . sprintf(
1128
-                                  esc_html__('%1$s : Never Initiated', 'event_espresso'),
1129
-                                  ucwords(str_replace('_', ' ', $reg_step))
1130
-                              )
1131
-                              . '</li>';
1132
-            }
1133
-        }
1134
-        $reg_steps                                                 .= '</ul>';
1135
-        $this->_template_args['txn_details']['reg_steps']['value'] = $reg_steps;
1136
-        $this->_template_args['txn_details']['reg_steps']['label'] = esc_html__(
1137
-            'Registration Step Progress',
1138
-            'event_espresso'
1139
-        );
1140
-
1141
-
1142
-        $this->_get_registrations_to_apply_payment_to();
1143
-        $this->_get_payment_methods($payments);
1144
-        $this->_get_payment_status_array();
1145
-        $this->_get_reg_status_selection(); // sets up the template args for the reg status array for the transaction.
1146
-
1147
-        $this->_template_args['transaction_form_url']    = add_query_arg(
1148
-            [
1149
-                'action'  => 'edit_transaction',
1150
-                'process' => 'transaction',
1151
-            ],
1152
-            TXN_ADMIN_URL
1153
-        );
1154
-        $this->_template_args['apply_payment_form_url']  = add_query_arg(
1155
-            [
1156
-                'page'   => 'espresso_transactions',
1157
-                'action' => 'espresso_apply_payment',
1158
-            ],
1159
-            WP_AJAX_URL
1160
-        );
1161
-        $this->_template_args['delete_payment_form_url'] = add_query_arg(
1162
-            [
1163
-                'page'   => 'espresso_transactions',
1164
-                'action' => 'espresso_delete_payment',
1165
-            ],
1166
-            WP_AJAX_URL
1167
-        );
1168
-
1169
-        $this->_template_args['action_buttons'] = $this->getActionButtons($this->_transaction);
1170
-
1171
-        // 'espresso_delete_payment_nonce'
1172
-
1173
-        $template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_txn_details.template.php';
1174
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);
1175
-    }
1176
-
1177
-
1178
-    /**
1179
-     * _get_registration_payment_IDs
1180
-     *    generates an array of Payment IDs and their corresponding Registration IDs
1181
-     *
1182
-     * @access protected
1183
-     * @param EE_Payment[] $payments
1184
-     * @return array
1185
-     * @throws EE_Error
1186
-     * @throws InvalidArgumentException
1187
-     * @throws InvalidDataTypeException
1188
-     * @throws InvalidInterfaceException
1189
-     * @throws ReflectionException
1190
-     */
1191
-    protected function _get_registration_payment_IDs($payments = [])
1192
-    {
1193
-        $existing_reg_payments = [];
1194
-        // get all reg payments for these payments
1195
-        $reg_payments = EEM_Registration_Payment::instance()->get_all(
1196
-            [
1197
-                [
1198
-                    'PAY_ID' => [
1199
-                        'IN',
1200
-                        array_keys($payments),
1201
-                    ],
1202
-                ],
1203
-            ]
1204
-        );
1205
-        if (! empty($reg_payments)) {
1206
-            foreach ($payments as $payment) {
1207
-                if (! $payment instanceof EE_Payment) {
1208
-                    continue;
1209
-                } elseif (! isset($existing_reg_payments[ $payment->ID() ])) {
1210
-                    $existing_reg_payments[ $payment->ID() ] = [];
1211
-                }
1212
-                foreach ($reg_payments as $reg_payment) {
1213
-                    if (
1214
-                        $reg_payment instanceof EE_Registration_Payment
1215
-                        && $reg_payment->payment_ID() === $payment->ID()
1216
-                    ) {
1217
-                        $existing_reg_payments[ $payment->ID() ][] = $reg_payment->registration_ID();
1218
-                    }
1219
-                }
1220
-            }
1221
-        }
1222
-
1223
-        return $existing_reg_payments;
1224
-    }
1225
-
1226
-
1227
-    /**
1228
-     * _get_registrations_to_apply_payment_to
1229
-     *    generates HTML for displaying a series of checkboxes in the admin payment modal window
1230
-     * which allows the admin to only apply the payment to the specific registrations
1231
-     *
1232
-     * @access protected
1233
-     * @return void
1234
-     * @throws EE_Error
1235
-     * @throws InvalidArgumentException
1236
-     * @throws InvalidDataTypeException
1237
-     * @throws InvalidInterfaceException
1238
-     * @throws ReflectionException
1239
-     */
1240
-    protected function _get_registrations_to_apply_payment_to()
1241
-    {
1242
-        // we want any registration with an active status (ie: not deleted or cancelled)
1243
-        $query_params                      = [
1244
-            [
1245
-                'STS_ID' => [
1246
-                    'IN',
1247
-                    [
1248
-                        EEM_Registration::status_id_approved,
1249
-                        EEM_Registration::status_id_pending_payment,
1250
-                        EEM_Registration::status_id_not_approved,
1251
-                    ],
1252
-                ],
1253
-            ],
1254
-        ];
1255
-        $registrations_to_apply_payment_to = EEH_HTML::br() . EEH_HTML::div(
1256
-            '',
1257
-            'txn-admin-apply-payment-to-registrations-dv',
1258
-            '',
1259
-            'clear: both; margin: 1.5em 0 0; display: none;'
1260
-        );
1261
-        $registrations_to_apply_payment_to .= EEH_HTML::br() . EEH_HTML::div('', '', 'admin-primary-mbox-tbl-wrap');
1262
-        $registrations_to_apply_payment_to .= EEH_HTML::table('', '', 'admin-primary-mbox-tbl');
1263
-        $registrations_to_apply_payment_to .= EEH_HTML::thead(
1264
-            EEH_HTML::tr(
1265
-                EEH_HTML::th(esc_html__('ID', 'event_espresso')) .
1266
-                EEH_HTML::th(esc_html__('Registrant', 'event_espresso')) .
1267
-                EEH_HTML::th(esc_html__('Ticket', 'event_espresso')) .
1268
-                EEH_HTML::th(esc_html__('Event', 'event_espresso')) .
1269
-                EEH_HTML::th(esc_html__('Paid', 'event_espresso'), '', 'txn-admin-payment-paid-td jst-cntr') .
1270
-                EEH_HTML::th(esc_html__('Owing', 'event_espresso'), '', 'txn-admin-payment-owing-td jst-cntr') .
1271
-                EEH_HTML::th(esc_html__('Apply', 'event_espresso'), '', 'jst-cntr')
1272
-            )
1273
-        );
1274
-        $registrations_to_apply_payment_to .= EEH_HTML::tbody();
1275
-        // get registrations for TXN
1276
-        $registrations         = $this->_transaction->registrations($query_params);
1277
-        $existing_reg_payments = $this->_template_args['existing_reg_payments'];
1278
-        foreach ($registrations as $registration) {
1279
-            if ($registration instanceof EE_Registration) {
1280
-                $attendee_name                     = $registration->attendee() instanceof EE_Attendee
1281
-                    ? $registration->attendee()->full_name()
1282
-                    : esc_html__('Unknown Attendee', 'event_espresso');
1283
-                $owing                             = $registration->final_price() - $registration->paid();
1284
-                $taxable                           = $registration->ticket()->taxable()
1285
-                    ? ' <span class="smaller-text lt-grey-text"> ' . esc_html__('+ tax', 'event_espresso') . '</span>'
1286
-                    : '';
1287
-                $checked                           = empty($existing_reg_payments)
1288
-                                                     || in_array($registration->ID(), $existing_reg_payments, true)
1289
-                    ? ' checked="checked"'
1290
-                    : '';
1291
-                $disabled                          = $registration->final_price() > 0 ? '' : ' disabled';
1292
-                $registrations_to_apply_payment_to .= EEH_HTML::tr(
1293
-                    EEH_HTML::td($registration->ID()) .
1294
-                    EEH_HTML::td($attendee_name) .
1295
-                    EEH_HTML::td(
1296
-                        $registration->ticket()->name() . ' : ' . $registration->ticket()->pretty_price() . $taxable
1297
-                    ) .
1298
-                    EEH_HTML::td($registration->event_name()) .
1299
-                    EEH_HTML::td($registration->pretty_paid(), '', 'txn-admin-payment-paid-td jst-cntr') .
1300
-                    EEH_HTML::td(
1301
-                        EEH_Template::format_currency($owing),
1302
-                        '',
1303
-                        'txn-admin-payment-owing-td jst-cntr'
1304
-                    ) .
1305
-                    EEH_HTML::td(
1306
-                        '<input type="checkbox" value="' . $registration->ID()
1307
-                        . '" name="txn_admin_payment[registrations]"'
1308
-                        . $checked . $disabled . '>',
1309
-                        '',
1310
-                        'jst-cntr'
1311
-                    ),
1312
-                    'apply-payment-registration-row-' . $registration->ID()
1313
-                );
1314
-            }
1315
-        }
1316
-        $registrations_to_apply_payment_to                         .= EEH_HTML::tbodyx();
1317
-        $registrations_to_apply_payment_to                         .= EEH_HTML::tablex();
1318
-        $registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1319
-        $registrations_to_apply_payment_to                         .= EEH_HTML::p(
1320
-            esc_html__(
1321
-                'The payment will only be applied to the registrations that have a check mark in their corresponding check box. Checkboxes for free registrations have been disabled.',
1322
-                'event_espresso'
1323
-            ),
1324
-            '',
1325
-            'clear description'
1326
-        );
1327
-        $registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1328
-        $this->_template_args['registrations_to_apply_payment_to'] = $registrations_to_apply_payment_to;
1329
-    }
1330
-
1331
-
1332
-    /**
1333
-     * _get_reg_status_selection
1334
-     *
1335
-     * @return void
1336
-     * @throws EE_Error
1337
-     * @todo   this will need to be adjusted either once MER comes along OR we move default reg status to tickets
1338
-     *         instead of events.
1339
-     * @access protected
1340
-     */
1341
-    protected function _get_reg_status_selection()
1342
-    {
1343
-        // first get all possible statuses
1344
-        $statuses = EEM_Registration::reg_status_array([], true);
1345
-        // let's add a "don't change" option.
1346
-        $status_array['NAN']                                 = esc_html__('Leave the Same', 'event_espresso');
1347
-        $status_array                                        = array_merge($status_array, $statuses);
1348
-        $this->_template_args['status_change_select']        = EEH_Form_Fields::select_input(
1349
-            'txn_reg_status_change[reg_status]',
1350
-            $status_array,
1351
-            'NAN',
1352
-            'id="txn-admin-payment-reg-status-inp"',
1353
-            'txn-reg-status-change-reg-status'
1354
-        );
1355
-        $this->_template_args['delete_status_change_select'] = EEH_Form_Fields::select_input(
1356
-            'delete_txn_reg_status_change[reg_status]',
1357
-            $status_array,
1358
-            'NAN',
1359
-            'delete-txn-admin-payment-reg-status-inp',
1360
-            'delete-txn-reg-status-change-reg-status'
1361
-        );
1362
-    }
1363
-
1364
-
1365
-    /**
1366
-     *    _get_payment_methods
1367
-     * Gets all the payment methods available generally, or the ones that are already
1368
-     * selected on these payments (in case their payment methods are no longer active).
1369
-     * Has the side-effect of updating the template args' payment_methods item
1370
-     *
1371
-     * @access private
1372
-     * @param EE_Payment[] to show on this page
1373
-     * @return void
1374
-     * @throws EE_Error
1375
-     * @throws InvalidArgumentException
1376
-     * @throws InvalidDataTypeException
1377
-     * @throws InvalidInterfaceException
1378
-     * @throws ReflectionException
1379
-     */
1380
-    private function _get_payment_methods($payments = [])
1381
-    {
1382
-        $payment_methods_of_payments = [];
1383
-        foreach ($payments as $payment) {
1384
-            if ($payment instanceof EE_Payment) {
1385
-                $payment_methods_of_payments[] = $payment->ID();
1386
-            }
1387
-        }
1388
-        if ($payment_methods_of_payments) {
1389
-            $query_args = [
1390
-                [
1391
-                    'OR*payment_method_for_payment' => [
1392
-                        'PMD_ID'    => ['IN', $payment_methods_of_payments],
1393
-                        'PMD_scope' => ['LIKE', '%' . EEM_Payment_Method::scope_admin . '%'],
1394
-                    ],
1395
-                ],
1396
-            ];
1397
-        } else {
1398
-            $query_args = [['PMD_scope' => ['LIKE', '%' . EEM_Payment_Method::scope_admin . '%']]];
1399
-        }
1400
-        $this->_template_args['payment_methods'] = EEM_Payment_Method::instance()->get_all($query_args);
1401
-    }
1402
-
1403
-
1404
-    /**
1405
-     * txn_attendees_meta_box
1406
-     *    generates HTML for the Attendees Transaction main meta box
1407
-     *
1408
-     * @access public
1409
-     * @param WP_Post $post
1410
-     * @param array   $metabox
1411
-     * @return void
1412
-     * @throws DomainException
1413
-     * @throws EE_Error
1414
-     * @throws InvalidArgumentException
1415
-     * @throws InvalidDataTypeException
1416
-     * @throws InvalidInterfaceException
1417
-     * @throws ReflectionException
1418
-     */
1419
-    public function txn_attendees_meta_box($post, $metabox = ['args' => []])
1420
-    {
1421
-
1422
-        /** @noinspection NonSecureExtractUsageInspection */
1423
-        extract($metabox['args']);
1424
-        $this->_template_args['post']            = $post;
1425
-        $this->_template_args['event_attendees'] = [];
1426
-        // process items in cart
1427
-        $line_items = $this->_transaction->get_many_related(
1428
-            'Line_Item',
1429
-            [['LIN_type' => 'line-item']]
1430
-        );
1431
-        if (! empty($line_items)) {
1432
-            foreach ($line_items as $item) {
1433
-                if ($item instanceof EE_Line_Item) {
1434
-                    switch ($item->OBJ_type()) {
1435
-                        case 'Event':
1436
-                            break;
1437
-                        case 'Ticket':
1438
-                            $ticket = $item->ticket();
1439
-                            // right now we're only handling tickets here.
1440
-                            // Cause its expected that only tickets will have attendees right?
1441
-                            if (! $ticket instanceof EE_Ticket) {
1442
-                                break;
1443
-                            }
1444
-                            try {
1445
-                                $event_name = $ticket->get_event_name();
1446
-                            } catch (Exception $e) {
1447
-                                EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1448
-                                $event_name = esc_html__('Unknown Event', 'event_espresso');
1449
-                            }
1450
-                            $event_name   .= ' - ' . $item->name();
1451
-                            $ticket_price = EEH_Template::format_currency($item->unit_price());
1452
-                            // now get all of the registrations for this transaction that use this ticket
1453
-                            $registrations = $ticket->registrations(
1454
-                                [['TXN_ID' => $this->_transaction->ID()]]
1455
-                            );
1456
-                            foreach ($registrations as $registration) {
1457
-                                if (! $registration instanceof EE_Registration) {
1458
-                                    break;
1459
-                                }
1460
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['STS_ID']
1461
-                                    = $registration->status_ID();
1462
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['att_num']
1463
-                                    = $registration->count();
1464
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['event_ticket_name']
1465
-                                    = $event_name;
1466
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['ticket_price']
1467
-                                    = $ticket_price;
1468
-                                // attendee info
1469
-                                $attendee = $registration->get_first_related('Attendee');
1470
-                                if ($attendee instanceof EE_Attendee) {
1471
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['att_id']
1472
-                                        = $attendee->ID();
1473
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['attendee']
1474
-                                        = $attendee->full_name();
1475
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['email']
1476
-                                        = '<a href="mailto:' . $attendee->email() . '?subject=' . $event_name
1477
-                                          . esc_html__(
1478
-                                              ' Event',
1479
-                                              'event_espresso'
1480
-                                          )
1481
-                                          . '">' . $attendee->email() . '</a>';
1482
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['address']
1483
-                                        = EEH_Address::format($attendee, 'inline', false, false);
1484
-                                } else {
1485
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['att_id']   = '';
1486
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['attendee'] = '';
1487
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['email']    = '';
1488
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['address']  = '';
1489
-                                }
1490
-                            }
1491
-                            break;
1492
-                    }
1493
-                }
1494
-            }
1495
-
1496
-            $this->_template_args['transaction_form_url'] = add_query_arg(
1497
-                [
1498
-                    'action'  => 'edit_transaction',
1499
-                    'process' => 'attendees',
1500
-                ],
1501
-                TXN_ADMIN_URL
1502
-            );
1503
-            echo EEH_Template::display_template(
1504
-                TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_attendees.template.php',
1505
-                $this->_template_args,
1506
-                true
1507
-            );
1508
-        } else {
1509
-            printf(
1510
-                esc_html__(
1511
-                    '%1$sFor some reason, there are no attendees registered for this transaction. Likely the registration was abandoned in process.%2$s',
1512
-                    'event_espresso'
1513
-                ),
1514
-                '<p class="important-notice">',
1515
-                '</p>'
1516
-            );
1517
-        }
1518
-    }
1519
-
1520
-
1521
-    /**
1522
-     * txn_registrant_side_meta_box
1523
-     * generates HTML for the Edit Transaction side meta box
1524
-     *
1525
-     * @access public
1526
-     * @return void
1527
-     * @throws DomainException
1528
-     * @throws EE_Error
1529
-     * @throws InvalidArgumentException
1530
-     * @throws InvalidDataTypeException
1531
-     * @throws InvalidInterfaceException
1532
-     * @throws ReflectionException
1533
-     */
1534
-    public function txn_registrant_side_meta_box()
1535
-    {
1536
-        $primary_att = $this->_transaction->primary_registration() instanceof EE_Registration
1537
-            ? $this->_transaction->primary_registration()->get_first_related('Attendee')
1538
-            : null;
1539
-        if (! $primary_att instanceof EE_Attendee) {
1540
-            $this->_template_args['no_attendee_message'] = esc_html__(
1541
-                'There is no attached contact for this transaction.  The transaction either failed due to an error or was abandoned.',
1542
-                'event_espresso'
1543
-            );
1544
-            $primary_att                           = EEM_Attendee::instance()->create_default_object();
1545
-        }
1546
-        $this->_template_args['ATT_ID']            = $primary_att->ID();
1547
-        $this->_template_args['prime_reg_fname']   = $primary_att->fname();
1548
-        $this->_template_args['prime_reg_lname']   = $primary_att->lname();
1549
-        $this->_template_args['prime_reg_email']   = $primary_att->email();
1550
-        $this->_template_args['prime_reg_phone']   = $primary_att->phone();
1551
-        $this->_template_args['edit_attendee_url'] = EE_Admin_Page::add_query_args_and_nonce(
1552
-            [
1553
-                'action' => 'edit_attendee',
1554
-                'post'   => $primary_att->ID(),
1555
-            ],
1556
-            REG_ADMIN_URL
1557
-        );
1558
-        // get formatted address for registrant
1559
-        $this->_template_args['formatted_address'] = EEH_Address::format($primary_att);
1560
-        echo EEH_Template::display_template(
1561
-            TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_registrant.template.php',
1562
-            $this->_template_args,
1563
-            true
1564
-        );
1565
-    }
1566
-
1567
-
1568
-    /**
1569
-     * txn_billing_info_side_meta_box
1570
-     *    generates HTML for the Edit Transaction side meta box
1571
-     *
1572
-     * @access public
1573
-     * @return void
1574
-     * @throws DomainException
1575
-     * @throws EE_Error
1576
-     * @throws ReflectionException
1577
-     */
1578
-    public function txn_billing_info_side_meta_box()
1579
-    {
1580
-
1581
-        $this->_template_args['billing_form']     = $this->_transaction->billing_info();
1582
-        $this->_template_args['billing_form_url'] = add_query_arg(
1583
-            ['action' => 'edit_transaction', 'process' => 'billing'],
1584
-            TXN_ADMIN_URL
1585
-        );
1586
-
1587
-        $template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_billing_info.template.php';
1588
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);
1589
-    }
1590
-
1591
-
1592
-    /**
1593
-     * apply_payments_or_refunds
1594
-     *    registers a payment or refund made towards a transaction
1595
-     *
1596
-     * @access public
1597
-     * @return void
1598
-     * @throws EE_Error
1599
-     * @throws InvalidArgumentException
1600
-     * @throws ReflectionException
1601
-     * @throws RuntimeException
1602
-     * @throws InvalidDataTypeException
1603
-     * @throws InvalidInterfaceException
1604
-     */
1605
-    public function apply_payments_or_refunds()
1606
-    {
1607
-        $json_response_data = ['return_data' => false];
1608
-        $valid_data         = $this->_validate_payment_request_data();
1609
-        $has_access         = EE_Registry::instance()->CAP->current_user_can(
1610
-            'ee_edit_payments',
1611
-            'apply_payment_or_refund_from_registration_details'
1612
-        );
1613
-        if (! empty($valid_data) && $has_access) {
1614
-            $PAY_ID = $valid_data['PAY_ID'];
1615
-            // save  the new payment
1616
-            $payment = $this->_create_payment_from_request_data($valid_data);
1617
-            // get the TXN for this payment
1618
-            $transaction = $payment->transaction();
1619
-            // verify transaction
1620
-            if ($transaction instanceof EE_Transaction) {
1621
-                // calculate_total_payments_and_update_status
1622
-                $this->_process_transaction_payments($transaction);
1623
-                $REG_IDs = $this->_get_REG_IDs_to_apply_payment_to($payment);
1624
-                $this->_remove_existing_registration_payments($payment, $PAY_ID);
1625
-                // apply payment to registrations (if applicable)
1626
-                if (! empty($REG_IDs)) {
1627
-                    $this->_update_registration_payments($transaction, $payment, $REG_IDs);
1628
-                    $this->_maybe_send_notifications();
1629
-                    // now process status changes for the same registrations
1630
-                    $this->_process_registration_status_change($transaction, $REG_IDs);
1631
-                }
1632
-                $this->_maybe_send_notifications($payment);
1633
-                // prepare to render page
1634
-                $json_response_data['return_data'] = $this->_build_payment_json_response($payment, $REG_IDs);
1635
-                do_action(
1636
-                    'AHEE__Transactions_Admin_Page__apply_payments_or_refund__after_recording',
1637
-                    $transaction,
1638
-                    $payment
1639
-                );
1640
-            } else {
1641
-                EE_Error::add_error(
1642
-                    esc_html__(
1643
-                        'A valid Transaction for this payment could not be retrieved.',
1644
-                        'event_espresso'
1645
-                    ),
1646
-                    __FILE__,
1647
-                    __FUNCTION__,
1648
-                    __LINE__
1649
-                );
1650
-            }
1651
-        } elseif ($has_access) {
1652
-            EE_Error::add_error(
1653
-                esc_html__(
1654
-                    'The payment form data could not be processed. Please try again.',
1655
-                    'event_espresso'
1656
-                ),
1657
-                __FILE__,
1658
-                __FUNCTION__,
1659
-                __LINE__
1660
-            );
1661
-        } else {
1662
-            EE_Error::add_error(
1663
-                esc_html__(
1664
-                    'You do not have access to apply payments or refunds to a registration.',
1665
-                    'event_espresso'
1666
-                ),
1667
-                __FILE__,
1668
-                __FUNCTION__,
1669
-                __LINE__
1670
-            );
1671
-        }
1672
-        $notices              = EE_Error::get_notices(
1673
-            false,
1674
-            false,
1675
-            false
1676
-        );
1677
-        $this->_template_args = [
1678
-            'data'    => $json_response_data,
1679
-            'error'   => $notices['errors'],
1680
-            'success' => $notices['success'],
1681
-        ];
1682
-        $this->_return_json();
1683
-    }
1684
-
1685
-
1686
-    /**
1687
-     * _validate_payment_request_data
1688
-     *
1689
-     * @return array
1690
-     * @throws EE_Error
1691
-     * @throws InvalidArgumentException
1692
-     * @throws InvalidDataTypeException
1693
-     * @throws InvalidInterfaceException
1694
-     */
1695
-    protected function _validate_payment_request_data()
1696
-    {
1697
-        if (! $this->request->requestParamIsSet('txn_admin_payment')) {
1698
-            return [];
1699
-        }
1700
-        $payment_form = $this->_generate_payment_form_section();
1701
-        try {
1702
-            if ($payment_form->was_submitted()) {
1703
-                $payment_form->receive_form_submission();
1704
-                if (! $payment_form->is_valid()) {
1705
-                    $submission_error_messages = [];
1706
-                    foreach ($payment_form->get_validation_errors_accumulated() as $validation_error) {
1707
-                        if ($validation_error instanceof EE_Validation_Error) {
1708
-                            $form_input = $validation_error->get_form_section();
1709
-                            $submission_error_messages[] = sprintf(
1710
-                                _x('%s : %s', 'Form Section Name : Form Validation Error', 'event_espresso'),
1711
-                                $form_input instanceof EE_Form_Input_Base ? $form_input->html_label_text() : '',
1712
-                                $validation_error->getMessage()
1713
-                            );
1714
-                        }
1715
-                    }
1716
-                    EE_Error::add_error(
1717
-                        implode('<br />', $submission_error_messages),
1718
-                        __FILE__,
1719
-                        __FUNCTION__,
1720
-                        __LINE__
1721
-                    );
1722
-                    return [];
1723
-                }
1724
-            }
1725
-        } catch (EE_Error $e) {
1726
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1727
-            return [];
1728
-        }
1729
-
1730
-        return $payment_form->valid_data();
1731
-    }
1732
-
1733
-
1734
-    /**
1735
-     * _generate_payment_form_section
1736
-     *
1737
-     * @return EE_Form_Section_Proper
1738
-     * @throws EE_Error
1739
-     */
1740
-    protected function _generate_payment_form_section()
1741
-    {
1742
-        return new EE_Form_Section_Proper(
1743
-            [
1744
-                'name'        => 'txn_admin_payment',
1745
-                'subsections' => [
1746
-                    'PAY_ID'          => new EE_Text_Input(
1747
-                        [
1748
-                            'default'               => 0,
1749
-                            'required'              => false,
1750
-                            'html_label_text'       => esc_html__('Payment ID', 'event_espresso'),
1751
-                            'validation_strategies' => [new EE_Int_Normalization()],
1752
-                        ]
1753
-                    ),
1754
-                    'TXN_ID'          => new EE_Text_Input(
1755
-                        [
1756
-                            'default'               => 0,
1757
-                            'required'              => true,
1758
-                            'html_label_text'       => esc_html__('Transaction ID', 'event_espresso'),
1759
-                            'validation_strategies' => [new EE_Int_Normalization()],
1760
-                        ]
1761
-                    ),
1762
-                    'type'            => new EE_Text_Input(
1763
-                        [
1764
-                            'default'               => 1,
1765
-                            'required'              => true,
1766
-                            'html_label_text'       => esc_html__('Payment or Refund', 'event_espresso'),
1767
-                            'validation_strategies' => [new EE_Int_Normalization()],
1768
-                        ]
1769
-                    ),
1770
-                    'amount'          => new EE_Text_Input(
1771
-                        [
1772
-                            'default'               => 0,
1773
-                            'required'              => true,
1774
-                            'html_label_text'       => esc_html__('Payment amount', 'event_espresso'),
1775
-                            'validation_strategies' => [new EE_Float_Normalization()],
1776
-                        ]
1777
-                    ),
1778
-                    'status'          => new EE_Text_Input(
1779
-                        [
1780
-                            'default'         => EEM_Payment::status_id_approved,
1781
-                            'required'        => true,
1782
-                            'html_label_text' => esc_html__('Payment status', 'event_espresso'),
1783
-                        ]
1784
-                    ),
1785
-                    'PMD_ID'          => new EE_Text_Input(
1786
-                        [
1787
-                            'default'               => 2,
1788
-                            'required'              => true,
1789
-                            'html_label_text'       => esc_html__('Payment Method', 'event_espresso'),
1790
-                            'validation_strategies' => [new EE_Int_Normalization()],
1791
-                        ]
1792
-                    ),
1793
-                    'date'            => new EE_Text_Input(
1794
-                        [
1795
-                            'default'         => time(),
1796
-                            'required'        => true,
1797
-                            'html_label_text' => esc_html__('Payment date', 'event_espresso'),
1798
-                        ]
1799
-                    ),
1800
-                    'txn_id_chq_nmbr' => new EE_Text_Input(
1801
-                        [
1802
-                            'default'               => '',
1803
-                            'required'              => false,
1804
-                            'html_label_text'       => esc_html__('Transaction or Cheque Number', 'event_espresso'),
1805
-                            'validation_strategies' => [
1806
-                                new EE_Max_Length_Validation_Strategy(
1807
-                                    esc_html__('Input too long', 'event_espresso'),
1808
-                                    100
1809
-                                ),
1810
-                            ],
1811
-                        ]
1812
-                    ),
1813
-                    'po_number'       => new EE_Text_Input(
1814
-                        [
1815
-                            'default'               => '',
1816
-                            'required'              => false,
1817
-                            'html_label_text'       => esc_html__('Purchase Order Number', 'event_espresso'),
1818
-                            'validation_strategies' => [
1819
-                                new EE_Max_Length_Validation_Strategy(
1820
-                                    esc_html__('Input too long', 'event_espresso'),
1821
-                                    100
1822
-                                ),
1823
-                            ],
1824
-                        ]
1825
-                    ),
1826
-                    'accounting'      => new EE_Text_Input(
1827
-                        [
1828
-                            'default'               => '',
1829
-                            'required'              => false,
1830
-                            'html_label_text'       => esc_html__('Extra Field for Accounting', 'event_espresso'),
1831
-                            'validation_strategies' => [
1832
-                                new EE_Max_Length_Validation_Strategy(
1833
-                                    esc_html__('Input too long', 'event_espresso'),
1834
-                                    100
1835
-                                ),
1836
-                            ],
1837
-                        ]
1838
-                    ),
1839
-                ],
1840
-            ]
1841
-        );
1842
-    }
1843
-
1844
-
1845
-    /**
1846
-     * _create_payment_from_request_data
1847
-     *
1848
-     * @param array $valid_data
1849
-     * @return EE_Payment
1850
-     * @throws EE_Error
1851
-     * @throws InvalidArgumentException
1852
-     * @throws InvalidDataTypeException
1853
-     * @throws InvalidInterfaceException
1854
-     * @throws ReflectionException
1855
-     */
1856
-    protected function _create_payment_from_request_data($valid_data)
1857
-    {
1858
-        $PAY_ID = $valid_data['PAY_ID'];
1859
-        // get payment amount
1860
-        $amount = $valid_data['amount'] ? abs($valid_data['amount']) : 0;
1861
-        // payments have a type value of 1 and refunds have a type value of -1
1862
-        // so multiplying amount by type will give a positive value for payments, and negative values for refunds
1863
-        $amount = $valid_data['type'] < 0 ? $amount * -1 : $amount;
1864
-        // for some reason the date string coming in has extra spaces between the date and time.  This fixes that.
1865
-        $date    = $valid_data['date']
1866
-            ? preg_replace('/\s+/', ' ', $valid_data['date'])
1867
-            : date('Y-m-d g:i a', current_time('timestamp'));
1868
-        $payment = EE_Payment::new_instance(
1869
-            [
1870
-                'TXN_ID'              => $valid_data['TXN_ID'],
1871
-                'STS_ID'              => $valid_data['status'],
1872
-                'PAY_timestamp'       => $date,
1873
-                'PAY_source'          => EEM_Payment_Method::scope_admin,
1874
-                'PMD_ID'              => $valid_data['PMD_ID'],
1875
-                'PAY_amount'          => $amount,
1876
-                'PAY_txn_id_chq_nmbr' => $valid_data['txn_id_chq_nmbr'],
1877
-                'PAY_po_number'       => $valid_data['po_number'],
1878
-                'PAY_extra_accntng'   => $valid_data['accounting'],
1879
-                'PAY_details'         => $valid_data,
1880
-                'PAY_ID'              => $PAY_ID,
1881
-            ],
1882
-            '',
1883
-            ['Y-m-d', 'g:i a']
1884
-        );
1885
-
1886
-        if (! $payment->save()) {
1887
-            EE_Error::add_error(
1888
-                sprintf(
1889
-                    esc_html__('Payment %1$d has not been successfully saved to the database.', 'event_espresso'),
1890
-                    $payment->ID()
1891
-                ),
1892
-                __FILE__,
1893
-                __FUNCTION__,
1894
-                __LINE__
1895
-            );
1896
-        }
1897
-
1898
-        return $payment;
1899
-    }
1900
-
1901
-
1902
-    /**
1903
-     * _process_transaction_payments
1904
-     *
1905
-     * @param EE_Transaction $transaction
1906
-     * @return void
1907
-     * @throws EE_Error
1908
-     * @throws InvalidArgumentException
1909
-     * @throws ReflectionException
1910
-     * @throws InvalidDataTypeException
1911
-     * @throws InvalidInterfaceException
1912
-     */
1913
-    protected function _process_transaction_payments(EE_Transaction $transaction)
1914
-    {
1915
-        /** @type EE_Transaction_Payments $transaction_payments */
1916
-        $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
1917
-        // update the transaction with this payment
1918
-        if ($transaction_payments->calculate_total_payments_and_update_status($transaction)) {
1919
-            EE_Error::add_success(
1920
-                esc_html__(
1921
-                    'The payment has been processed successfully.',
1922
-                    'event_espresso'
1923
-                ),
1924
-                __FILE__,
1925
-                __FUNCTION__,
1926
-                __LINE__
1927
-            );
1928
-        } else {
1929
-            EE_Error::add_error(
1930
-                esc_html__(
1931
-                    'The payment was processed successfully but the amount paid for the transaction was not updated.',
1932
-                    'event_espresso'
1933
-                ),
1934
-                __FILE__,
1935
-                __FUNCTION__,
1936
-                __LINE__
1937
-            );
1938
-        }
1939
-    }
1940
-
1941
-
1942
-    /**
1943
-     * _get_REG_IDs_to_apply_payment_to
1944
-     * returns a list of registration IDs that the payment will apply to
1945
-     *
1946
-     * @param EE_Payment $payment
1947
-     * @return array
1948
-     * @throws EE_Error
1949
-     * @throws InvalidArgumentException
1950
-     * @throws InvalidDataTypeException
1951
-     * @throws InvalidInterfaceException
1952
-     * @throws ReflectionException
1953
-     */
1954
-    protected function _get_REG_IDs_to_apply_payment_to(EE_Payment $payment)
1955
-    {
1956
-        // grab array of IDs for specific registrations to apply changes to
1957
-        $REG_IDs = $this->request->getRequestParam('txn_admin_payment[registrations]', [], 'int', true);
1958
-        // nothing specified ? then get all reg IDs
1959
-        if (empty($REG_IDs)) {
1960
-            $registrations = $payment->transaction()->registrations();
1961
-            $REG_IDs       = ! empty($registrations)
1962
-                ? array_keys($registrations)
1963
-                : $this->_get_existing_reg_payment_REG_IDs($payment);
1964
-        }
1965
-
1966
-        // ensure that REG_IDs are integers and NOT strings
1967
-        return array_map('intval', $REG_IDs);
1968
-    }
1969
-
1970
-
1971
-    /**
1972
-     * @return array
1973
-     */
1974
-    public function existing_reg_payment_REG_IDs()
1975
-    {
1976
-        return $this->_existing_reg_payment_REG_IDs;
1977
-    }
1978
-
1979
-
1980
-    /**
1981
-     * @param array $existing_reg_payment_REG_IDs
1982
-     */
1983
-    public function set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs = null)
1984
-    {
1985
-        $this->_existing_reg_payment_REG_IDs = $existing_reg_payment_REG_IDs;
1986
-    }
1987
-
1988
-
1989
-    /**
1990
-     * _get_existing_reg_payment_REG_IDs
1991
-     * returns a list of registration IDs that the payment is currently related to
1992
-     * as recorded in the database
1993
-     *
1994
-     * @param EE_Payment $payment
1995
-     * @return array
1996
-     * @throws EE_Error
1997
-     * @throws InvalidArgumentException
1998
-     * @throws InvalidDataTypeException
1999
-     * @throws InvalidInterfaceException
2000
-     * @throws ReflectionException
2001
-     */
2002
-    protected function _get_existing_reg_payment_REG_IDs(EE_Payment $payment)
2003
-    {
2004
-        if ($this->existing_reg_payment_REG_IDs() === null) {
2005
-            // let's get any existing reg payment records for this payment
2006
-            $existing_reg_payment_REG_IDs = $payment->get_many_related('Registration');
2007
-            // but we only want the REG IDs, so grab the array keys
2008
-            $existing_reg_payment_REG_IDs = ! empty($existing_reg_payment_REG_IDs)
2009
-                ? array_keys($existing_reg_payment_REG_IDs)
2010
-                : [];
2011
-            $this->set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs);
2012
-        }
2013
-
2014
-        return $this->existing_reg_payment_REG_IDs();
2015
-    }
2016
-
2017
-
2018
-    /**
2019
-     * _remove_existing_registration_payments
2020
-     * this calculates the difference between existing relations
2021
-     * to the supplied payment and the new list registration IDs,
2022
-     * removes any related registrations that no longer apply,
2023
-     * and then updates the registration paid fields
2024
-     *
2025
-     * @param EE_Payment $payment
2026
-     * @param int        $PAY_ID
2027
-     * @return bool;
2028
-     * @throws EE_Error
2029
-     * @throws InvalidArgumentException
2030
-     * @throws ReflectionException
2031
-     * @throws InvalidDataTypeException
2032
-     * @throws InvalidInterfaceException
2033
-     */
2034
-    protected function _remove_existing_registration_payments(EE_Payment $payment, $PAY_ID = 0)
2035
-    {
2036
-        // newly created payments will have nothing recorded for $PAY_ID
2037
-        if (absint($PAY_ID) === 0) {
2038
-            return false;
2039
-        }
2040
-        $existing_reg_payment_REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
2041
-        if (empty($existing_reg_payment_REG_IDs)) {
2042
-            return false;
2043
-        }
2044
-        /** @type EE_Transaction_Payments $transaction_payments */
2045
-        $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
2046
-
2047
-        return $transaction_payments->delete_registration_payments_and_update_registrations(
2048
-            $payment,
2049
-            [
2050
-                [
2051
-                    'PAY_ID' => $payment->ID(),
2052
-                    'REG_ID' => ['IN', $existing_reg_payment_REG_IDs],
2053
-                ],
2054
-            ]
2055
-        );
2056
-    }
2057
-
2058
-
2059
-    /**
2060
-     * _update_registration_payments
2061
-     * this applies the payments to the selected registrations
2062
-     * but only if they have not already been paid for
2063
-     *
2064
-     * @param EE_Transaction $transaction
2065
-     * @param EE_Payment     $payment
2066
-     * @param array          $REG_IDs
2067
-     * @return void
2068
-     * @throws EE_Error
2069
-     * @throws InvalidArgumentException
2070
-     * @throws ReflectionException
2071
-     * @throws RuntimeException
2072
-     * @throws InvalidDataTypeException
2073
-     * @throws InvalidInterfaceException
2074
-     */
2075
-    protected function _update_registration_payments(
2076
-        EE_Transaction $transaction,
2077
-        EE_Payment $payment,
2078
-        $REG_IDs = []
2079
-    ) {
2080
-        // we can pass our own custom set of registrations to EE_Payment_Processor::process_registration_payments()
2081
-        // so let's do that using our set of REG_IDs from the form
2082
-        $registration_query_where_params = [
2083
-            'REG_ID' => ['IN', $REG_IDs],
2084
-        ];
2085
-        // but add in some conditions regarding payment,
2086
-        // so that we don't apply payments to registrations that are free or have already been paid for
2087
-        // but ONLY if the payment is NOT a refund ( ie: the payment amount is not negative )
2088
-        if (! $payment->is_a_refund()) {
2089
-            $registration_query_where_params['REG_final_price']  = ['!=', 0];
2090
-            $registration_query_where_params['REG_final_price*'] = ['!=', 'REG_paid', true];
2091
-        }
2092
-        $registrations = $transaction->registrations([$registration_query_where_params]);
2093
-        if (! empty($registrations)) {
2094
-            /** @type EE_Payment_Processor $payment_processor */
2095
-            $payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
2096
-            $payment_processor->process_registration_payments($transaction, $payment, $registrations);
2097
-        }
2098
-    }
2099
-
2100
-
2101
-    /**
2102
-     * _process_registration_status_change
2103
-     * This processes requested registration status changes for all the registrations
2104
-     * on a given transaction and (optionally) sends out notifications for the changes.
2105
-     *
2106
-     * @param EE_Transaction $transaction
2107
-     * @param array          $REG_IDs
2108
-     * @return bool
2109
-     * @throws EE_Error
2110
-     * @throws InvalidArgumentException
2111
-     * @throws ReflectionException
2112
-     * @throws InvalidDataTypeException
2113
-     * @throws InvalidInterfaceException
2114
-     */
2115
-    protected function _process_registration_status_change(EE_Transaction $transaction, $REG_IDs = [])
2116
-    {
2117
-        // first if there is no change in status then we get out.
2118
-        $reg_status = $this->request->getRequestParam('txn_reg_status_change[reg_status]', 'NAN');
2119
-        if ($reg_status === 'NAN') {
2120
-            // no error message, no change requested, just nothing to do man.
2121
-            return false;
2122
-        }
2123
-        /** @type EE_Transaction_Processor $transaction_processor */
2124
-        $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
2125
-
2126
-        // made it here dude?  Oh WOW.  K, let's take care of changing the statuses
2127
-        return $transaction_processor->manually_update_registration_statuses(
2128
-            $transaction,
2129
-            $reg_status,
2130
-            [['REG_ID' => ['IN', $REG_IDs]]]
2131
-        );
2132
-    }
2133
-
2134
-
2135
-    /**
2136
-     * _build_payment_json_response
2137
-     *
2138
-     * @access public
2139
-     * @param EE_Payment  $payment
2140
-     * @param array       $REG_IDs
2141
-     * @param bool | null $delete_txn_reg_status_change
2142
-     * @return array
2143
-     * @throws EE_Error
2144
-     * @throws InvalidArgumentException
2145
-     * @throws InvalidDataTypeException
2146
-     * @throws InvalidInterfaceException
2147
-     * @throws ReflectionException
2148
-     */
2149
-    protected function _build_payment_json_response(
2150
-        EE_Payment $payment,
2151
-        $REG_IDs = [],
2152
-        $delete_txn_reg_status_change = null
2153
-    ) {
2154
-        // was the payment deleted ?
2155
-        if (is_bool($delete_txn_reg_status_change)) {
2156
-            return [
2157
-                'PAY_ID'                       => $payment->ID(),
2158
-                'amount'                       => $payment->amount(),
2159
-                'total_paid'                   => $payment->transaction()->paid(),
2160
-                'txn_status'                   => $payment->transaction()->status_ID(),
2161
-                'pay_status'                   => $payment->STS_ID(),
2162
-                'registrations'                => $this->_registration_payment_data_array($REG_IDs),
2163
-                'delete_txn_reg_status_change' => $delete_txn_reg_status_change,
2164
-            ];
2165
-        }
2166
-
2167
-        $this->_get_payment_status_array();
2168
-        return [
2169
-            'amount'           => $payment->amount(),
2170
-            'total_paid'       => $payment->transaction()->paid(),
2171
-            'txn_status'       => $payment->transaction()->status_ID(),
2172
-            'pay_status'       => $payment->STS_ID(),
2173
-            'PAY_ID'           => $payment->ID(),
2174
-            'STS_ID'           => $payment->STS_ID(),
2175
-            'status'           => self::$_pay_status[ $payment->STS_ID() ],
2176
-            'date'             => $payment->timestamp('Y-m-d', 'h:i a'),
2177
-            'method'           => strtoupper($payment->source()),
2178
-            'PM_ID'            => $payment->payment_method() ? $payment->payment_method()->ID() : 1,
2179
-            'gateway'          => $payment->payment_method()
2180
-                ? $payment->payment_method()->admin_name()
2181
-                : esc_html__('Unknown', 'event_espresso'),
2182
-            'gateway_response' => $payment->gateway_response(),
2183
-            'txn_id_chq_nmbr'  => $payment->txn_id_chq_nmbr(),
2184
-            'po_number'        => $payment->po_number(),
2185
-            'extra_accntng'    => $payment->extra_accntng(),
2186
-            'registrations'    => $this->_registration_payment_data_array($REG_IDs),
2187
-        ];
2188
-    }
2189
-
2190
-
2191
-    /**
2192
-     * delete_payment
2193
-     *    delete a payment or refund made towards a transaction
2194
-     *
2195
-     * @access public
2196
-     * @return void
2197
-     * @throws EE_Error
2198
-     * @throws InvalidArgumentException
2199
-     * @throws ReflectionException
2200
-     * @throws InvalidDataTypeException
2201
-     * @throws InvalidInterfaceException
2202
-     */
2203
-    public function delete_payment()
2204
-    {
2205
-        $json_response_data = ['return_data' => false];
2206
-        $PAY_ID = $this->request->getRequestParam('delete_txn_admin_payment[PAY_ID]', 0, 'int');
2207
-
2208
-        $can_delete         = EE_Registry::instance()->CAP->current_user_can(
2209
-            'ee_delete_payments',
2210
-            'delete_payment_from_registration_details'
2211
-        );
2212
-        if ($PAY_ID && $can_delete) {
2213
-            $delete_txn_reg_status_change = $this->request->getRequestParam(
2214
-                'delete_txn_reg_status_change',
2215
-                false,
2216
-                'bool'
2217
-            );
2218
-            $payment = EEM_Payment::instance()->get_one_by_ID($PAY_ID);
2219
-            if ($payment instanceof EE_Payment) {
2220
-                $REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
2221
-                /** @type EE_Transaction_Payments $transaction_payments */
2222
-                $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
2223
-                if ($transaction_payments->delete_payment_and_update_transaction($payment)) {
2224
-                    $json_response_data['return_data'] = $this->_build_payment_json_response(
2225
-                        $payment,
2226
-                        $REG_IDs,
2227
-                        $delete_txn_reg_status_change
2228
-                    );
2229
-                    if ($delete_txn_reg_status_change) {
2230
-                        // MAKE sure we also add the delete_txn_req_status_change to the
2231
-                        // request data because that's how messages will be looking for it.
2232
-                        $this->request->setRequestParam('txn_reg_status_change', $delete_txn_reg_status_change);
2233
-                        $this->_maybe_send_notifications();
2234
-                        $this->_process_registration_status_change($payment->transaction(), $REG_IDs);
2235
-                    }
2236
-                }
2237
-            } else {
2238
-                EE_Error::add_error(
2239
-                    esc_html__('Valid Payment data could not be retrieved from the database.', 'event_espresso'),
2240
-                    __FILE__,
2241
-                    __FUNCTION__,
2242
-                    __LINE__
2243
-                );
2244
-            }
2245
-        } elseif ($can_delete) {
2246
-            EE_Error::add_error(
2247
-                esc_html__(
2248
-                    'A valid Payment ID was not received, therefore payment form data could not be loaded.',
2249
-                    'event_espresso'
2250
-                ),
2251
-                __FILE__,
2252
-                __FUNCTION__,
2253
-                __LINE__
2254
-            );
2255
-        } else {
2256
-            EE_Error::add_error(
2257
-                esc_html__(
2258
-                    'You do not have access to delete a payment.',
2259
-                    'event_espresso'
2260
-                ),
2261
-                __FILE__,
2262
-                __FUNCTION__,
2263
-                __LINE__
2264
-            );
2265
-        }
2266
-        $notices              = EE_Error::get_notices(false, false, false);
2267
-        $this->_template_args = [
2268
-            'data'      => $json_response_data,
2269
-            'success'   => $notices['success'],
2270
-            'error'     => $notices['errors'],
2271
-            'attention' => $notices['attention'],
2272
-        ];
2273
-        $this->_return_json();
2274
-    }
2275
-
2276
-
2277
-    /**
2278
-     * _registration_payment_data_array
2279
-     * adds info for 'owing' and 'paid' for each registration to the json response
2280
-     *
2281
-     * @access protected
2282
-     * @param array $REG_IDs
2283
-     * @return array
2284
-     * @throws EE_Error
2285
-     * @throws InvalidArgumentException
2286
-     * @throws InvalidDataTypeException
2287
-     * @throws InvalidInterfaceException
2288
-     * @throws ReflectionException
2289
-     */
2290
-    protected function _registration_payment_data_array($REG_IDs)
2291
-    {
2292
-        $registration_payment_data = [];
2293
-        // if non empty reg_ids lets get an array of registrations and update the values for the apply_payment/refund rows.
2294
-        if (! empty($REG_IDs)) {
2295
-            $registrations = EEM_Registration::instance()->get_all([['REG_ID' => ['IN', $REG_IDs]]]);
2296
-            foreach ($registrations as $registration) {
2297
-                if ($registration instanceof EE_Registration) {
2298
-                    $registration_payment_data[ $registration->ID() ] = [
2299
-                        'paid'  => $registration->pretty_paid(),
2300
-                        'owing' => EEH_Template::format_currency($registration->final_price() - $registration->paid()),
2301
-                    ];
2302
-                }
2303
-            }
2304
-        }
2305
-
2306
-        return $registration_payment_data;
2307
-    }
2308
-
2309
-
2310
-    /**
2311
-     * _maybe_send_notifications
2312
-     * determines whether or not the admin has indicated that notifications should be sent.
2313
-     * If so, will toggle a filter switch for delivering registration notices.
2314
-     * If passed an EE_Payment object, then it will trigger payment notifications instead.
2315
-     *
2316
-     * @access protected
2317
-     * @param EE_Payment | null $payment
2318
-     */
2319
-    protected function _maybe_send_notifications($payment = null)
2320
-    {
2321
-        switch ($payment instanceof EE_Payment) {
2322
-            // payment notifications
2323
-            case true:
2324
-                if ($this->request->getRequestParam('txn_payments[send_notifications]', false, 'bool')) {
2325
-                    $this->_process_payment_notification($payment);
2326
-                }
2327
-                break;
2328
-            // registration notifications
2329
-            case false:
2330
-                if ($this->request->getRequestParam('txn_reg_status_change[send_notifications]', false, 'bool')) {
2331
-                    add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true');
2332
-                }
2333
-                break;
2334
-        }
2335
-    }
2336
-
2337
-
2338
-    /**
2339
-     * _send_payment_reminder
2340
-     *    generates HTML for the View Transaction Details Admin page
2341
-     *
2342
-     * @access protected
2343
-     * @return void
2344
-     * @throws EE_Error
2345
-     * @throws InvalidArgumentException
2346
-     * @throws InvalidDataTypeException
2347
-     * @throws InvalidInterfaceException
2348
-     */
2349
-    protected function _send_payment_reminder()
2350
-    {
2351
-        $TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
2352
-        $transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2353
-        $redirect_to = $this->request->getRequestParam('redirect_to');
2354
-        $query_args  = $redirect_to ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID,] : [];
2355
-        do_action(
2356
-            'AHEE__Transactions_Admin_Page___send_payment_reminder__process_admin_payment_reminder',
2357
-            $transaction
2358
-        );
2359
-        $this->_redirect_after_action(
2360
-            false,
2361
-            esc_html__('payment reminder', 'event_espresso'),
2362
-            esc_html__('sent', 'event_espresso'),
2363
-            $query_args,
2364
-            true
2365
-        );
2366
-    }
2367
-
2368
-
2369
-    /**
2370
-     *  get_transactions
2371
-     *    get transactions for given parameters (used by list table)
2372
-     *
2373
-     * @param int     $per_page how many transactions displayed per page
2374
-     * @param boolean $count   return the count or objects
2375
-     * @param string  $view
2376
-     * @return EE_Transaction[]|int int = count || array of transaction objects
2377
-     * @throws EE_Error
2378
-     * @throws InvalidArgumentException
2379
-     * @throws InvalidDataTypeException
2380
-     * @throws InvalidInterfaceException
2381
-     */
2382
-    public function get_transactions($per_page, $count = false, $view = '')
2383
-    {
2384
-        $start_date = wp_strip_all_tags(
2385
-            $this->request->getRequestParam('txn-filter-start-date', date('m/d/Y', strtotime('-10 year')))
2386
-        );
2387
-        $end_date = wp_strip_all_tags(
2388
-            $this->request->getRequestParam('txn-filter-end-date', date('m/d/Y'))
2389
-        );
2390
-
2391
-        // make sure our timestamps start and end right at the boundaries for each day
2392
-        $start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
2393
-        $end_date   = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
2394
-
2395
-
2396
-        // convert to timestamps
2397
-        $start_date = strtotime($start_date);
2398
-        $end_date   = strtotime($end_date);
2399
-
2400
-        // makes sure start date is the lowest value and vice versa
2401
-        $start_date = min($start_date, $end_date);
2402
-        $end_date   = max($start_date, $end_date);
2403
-
2404
-        // convert to correct format for query
2405
-        $start_date = EEM_Transaction::instance()->convert_datetime_for_query(
2406
-            'TXN_timestamp',
2407
-            date('Y-m-d H:i:s', $start_date),
2408
-            'Y-m-d H:i:s'
2409
-        );
2410
-        $end_date   = EEM_Transaction::instance()->convert_datetime_for_query(
2411
-            'TXN_timestamp',
2412
-            date('Y-m-d H:i:s', $end_date),
2413
-            'Y-m-d H:i:s'
2414
-        );
2415
-
2416
-
2417
-        // set orderby
2418
-        $orderby = $this->request->getRequestParam('orderby');
2419
-
2420
-        switch ($orderby) {
2421
-            case 'TXN_ID':
2422
-                break;
2423
-            case 'ATT_fname':
2424
-                $orderby = 'Registration.Attendee.ATT_fname';
2425
-                break;
2426
-            case 'event_name':
2427
-                $orderby = 'Registration.Event.EVT_name';
2428
-                break;
2429
-            default: // 'TXN_timestamp'
2430
-                $orderby = 'TXN_timestamp';
2431
-        }
2432
-
2433
-        $sort         = $this->request->getRequestParam('order', 'DESC');
2434
-        $current_page = $this->request->getRequestParam('paged', 1, 'int');
2435
-
2436
-        $per_page = absint($per_page) ? $per_page : 10;
2437
-        $per_page = $this->request->getRequestParam('perpage', $per_page, 'int');
2438
-
2439
-        $offset = ($current_page - 1) * $per_page;
2440
-        $limit  = [$offset, $per_page];
2441
-
2442
-        $_where = [
2443
-            'TXN_timestamp'          => ['BETWEEN', [$start_date, $end_date]],
2444
-            'Registration.REG_count' => 1,
2445
-        ];
2446
-
2447
-        $EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
2448
-        if ($EVT_ID) {
2449
-            $_where['Registration.EVT_ID'] = $EVT_ID;
2450
-        }
2451
-
2452
-        $search_term = $this->request->getRequestParam('s');
2453
-        if ($search_term) {
2454
-            $search_term = '%' . $search_term . '%';
2455
-            $_where['OR']  = [
2456
-                'Registration.Event.EVT_name'         => ['LIKE', $search_term],
2457
-                'Registration.Event.EVT_desc'         => ['LIKE', $search_term],
2458
-                'Registration.Event.EVT_short_desc'   => ['LIKE', $search_term],
2459
-                'Registration.Attendee.ATT_full_name' => ['LIKE', $search_term],
2460
-                'Registration.Attendee.ATT_fname'     => ['LIKE', $search_term],
2461
-                'Registration.Attendee.ATT_lname'     => ['LIKE', $search_term],
2462
-                'Registration.Attendee.ATT_short_bio' => ['LIKE', $search_term],
2463
-                'Registration.Attendee.ATT_email'     => ['LIKE', $search_term],
2464
-                'Registration.Attendee.ATT_address'   => ['LIKE', $search_term],
2465
-                'Registration.Attendee.ATT_address2'  => ['LIKE', $search_term],
2466
-                'Registration.Attendee.ATT_city'      => ['LIKE', $search_term],
2467
-                'Registration.REG_final_price'        => ['LIKE', $search_term],
2468
-                'Registration.REG_code'               => ['LIKE', $search_term],
2469
-                'Registration.REG_count'              => ['LIKE', $search_term],
2470
-                'Registration.REG_group_size'         => ['LIKE', $search_term],
2471
-                'Registration.Ticket.TKT_name'        => ['LIKE', $search_term],
2472
-                'Registration.Ticket.TKT_description' => ['LIKE', $search_term],
2473
-                'Payment.PAY_source'                  => ['LIKE', $search_term],
2474
-                'Payment.Payment_Method.PMD_name'     => ['LIKE', $search_term],
2475
-                'TXN_session_data'                    => ['LIKE', $search_term],
2476
-                'Payment.PAY_txn_id_chq_nmbr'         => ['LIKE', $search_term],
2477
-            ];
2478
-        }
2479
-
2480
-        $status = $this->request->getRequestParam('status');
2481
-        // failed transactions
2482
-        $failed     = (! empty($status) && $status === 'failed' && ! $count) || ($count && $view === 'failed');
2483
-        $abandoned  = (! empty($status) && $status === 'abandoned' && ! $count) || ($count && $view === 'abandoned');
2484
-        $incomplete = (! empty($status) && $status === 'incomplete' && ! $count) || ($count && $view === 'incomplete');
2485
-
2486
-        if ($failed) {
2487
-            $_where['STS_ID'] = EEM_Transaction::failed_status_code;
2488
-        } elseif ($abandoned) {
2489
-            $_where['STS_ID'] = EEM_Transaction::abandoned_status_code;
2490
-        } elseif ($incomplete) {
2491
-            $_where['STS_ID'] = EEM_Transaction::incomplete_status_code;
2492
-        } else {
2493
-            $_where['STS_ID']  = ['!=', EEM_Transaction::failed_status_code];
2494
-            $_where['STS_ID*'] = ['!=', EEM_Transaction::abandoned_status_code];
2495
-        }
2496
-
2497
-        $query_params = apply_filters(
2498
-            'FHEE__Transactions_Admin_Page___get_transactions_query_params',
2499
-            [
2500
-                $_where,
2501
-                'order_by'                 => [$orderby => $sort],
2502
-                'limit'                    => $limit,
2503
-                'default_where_conditions' => EEM_Base::default_where_conditions_this_only,
2504
-            ],
2505
-            $this->request->requestParams(),
2506
-            $view,
2507
-            $count
2508
-        );
2509
-
2510
-        return $count
2511
-            ? EEM_Transaction::instance()->count([$query_params[0]], 'TXN_ID', true)
2512
-            : EEM_Transaction::instance()->get_all($query_params);
2513
-    }
2514
-
2515
-
2516
-    /**
2517
-     * @throws EE_Error
2518
-     * @throws InvalidArgumentException
2519
-     * @throws InvalidDataTypeException
2520
-     * @throws InvalidInterfaceException
2521
-     * @throws ReflectionException
2522
-     * @throws RuntimeException
2523
-     * @since 4.9.79.p
2524
-     */
2525
-    public function recalculateLineItems()
2526
-    {
2527
-        $TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
2528
-        /** @var EE_Transaction $transaction */
2529
-        $transaction     = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2530
-        $success         = $transaction->recalculateLineItems();
2531
-        $redirect_to = $this->request->getRequestParam('redirect_to');
2532
-        $query_args = $redirect_to ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID,] : [];
2533
-        $this->_redirect_after_action(
2534
-            $success,
2535
-            esc_html__('Transaction taxes and totals', 'event_espresso'),
2536
-            esc_html__('recalculated', 'event_espresso'),
2537
-            $query_args,
2538
-            true
2539
-        );
2540
-    }
16
+	/**
17
+	 * @var EE_Transaction
18
+	 */
19
+	private $_transaction;
20
+
21
+	/**
22
+	 * @var EE_Session
23
+	 */
24
+	private $_session;
25
+
26
+	/**
27
+	 * @var array $_txn_status
28
+	 */
29
+	private static $_txn_status;
30
+
31
+	/**
32
+	 * @var array $_pay_status
33
+	 */
34
+	private static $_pay_status;
35
+
36
+	/**
37
+	 * @var array $_existing_reg_payment_REG_IDs
38
+	 */
39
+	protected $_existing_reg_payment_REG_IDs;
40
+
41
+
42
+	/**
43
+	 *    _init_page_props
44
+	 *
45
+	 * @return void
46
+	 */
47
+	protected function _init_page_props()
48
+	{
49
+		$this->page_slug        = TXN_PG_SLUG;
50
+		$this->page_label       = esc_html__('Transactions', 'event_espresso');
51
+		$this->_admin_base_url  = TXN_ADMIN_URL;
52
+		$this->_admin_base_path = TXN_ADMIN;
53
+	}
54
+
55
+
56
+	/**
57
+	 *    _ajax_hooks
58
+	 *
59
+	 * @return void
60
+	 */
61
+	protected function _ajax_hooks()
62
+	{
63
+		add_action('wp_ajax_espresso_apply_payment', [$this, 'apply_payments_or_refunds']);
64
+		add_action('wp_ajax_espresso_apply_refund', [$this, 'apply_payments_or_refunds']);
65
+		add_action('wp_ajax_espresso_delete_payment', [$this, 'delete_payment']);
66
+	}
67
+
68
+
69
+	/**
70
+	 *    _define_page_props
71
+	 *
72
+	 * @return void
73
+	 */
74
+	protected function _define_page_props()
75
+	{
76
+		$this->_admin_page_title = $this->page_label;
77
+		$this->_labels           = [
78
+			'buttons' => [
79
+				'add'    => esc_html__('Add New Transaction', 'event_espresso'),
80
+				'edit'   => esc_html__('Edit Transaction', 'event_espresso'),
81
+				'delete' => esc_html__('Delete Transaction', 'event_espresso'),
82
+			],
83
+		];
84
+	}
85
+
86
+
87
+	/**
88
+	 *        grab url requests and route them
89
+	 *
90
+	 * @access private
91
+	 * @return void
92
+	 * @throws EE_Error
93
+	 * @throws InvalidArgumentException
94
+	 * @throws InvalidDataTypeException
95
+	 * @throws InvalidInterfaceException
96
+	 */
97
+	public function _set_page_routes()
98
+	{
99
+
100
+		$this->_set_transaction_status_array();
101
+		$TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
102
+
103
+		$this->_page_routes = [
104
+
105
+			'default' => [
106
+				'func'       => '_transactions_overview_list_table',
107
+				'capability' => 'ee_read_transactions',
108
+			],
109
+
110
+			'view_transaction' => [
111
+				'func'       => '_transaction_details',
112
+				'capability' => 'ee_read_transaction',
113
+				'obj_id'     => $TXN_ID,
114
+			],
115
+
116
+			'send_payment_reminder' => [
117
+				'func'       => '_send_payment_reminder',
118
+				'noheader'   => true,
119
+				'capability' => 'ee_send_message',
120
+			],
121
+
122
+			'espresso_apply_payment' => [
123
+				'func'       => 'apply_payments_or_refunds',
124
+				'noheader'   => true,
125
+				'capability' => 'ee_edit_payments',
126
+			],
127
+
128
+			'espresso_apply_refund' => [
129
+				'func'       => 'apply_payments_or_refunds',
130
+				'noheader'   => true,
131
+				'capability' => 'ee_edit_payments',
132
+			],
133
+
134
+			'espresso_delete_payment' => [
135
+				'func'       => 'delete_payment',
136
+				'noheader'   => true,
137
+				'capability' => 'ee_delete_payments',
138
+			],
139
+
140
+			'espresso_recalculate_line_items' => [
141
+				'func'       => 'recalculateLineItems',
142
+				'noheader'   => true,
143
+				'capability' => 'ee_edit_payments',
144
+			],
145
+
146
+		];
147
+	}
148
+
149
+
150
+	protected function _set_page_config()
151
+	{
152
+		$TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
153
+		$this->_page_config = [
154
+			'default'          => [
155
+				'nav'           => [
156
+					'label' => esc_html__('Overview', 'event_espresso'),
157
+					'order' => 10,
158
+				],
159
+				'list_table'    => 'EE_Admin_Transactions_List_Table',
160
+				'help_tabs'     => [
161
+					'transactions_overview_help_tab'                       => [
162
+						'title'    => esc_html__('Transactions Overview', 'event_espresso'),
163
+						'filename' => 'transactions_overview',
164
+					],
165
+					'transactions_overview_table_column_headings_help_tab' => [
166
+						'title'    => esc_html__('Transactions Table Column Headings', 'event_espresso'),
167
+						'filename' => 'transactions_overview_table_column_headings',
168
+					],
169
+					'transactions_overview_views_filters_help_tab'         => [
170
+						'title'    => esc_html__('Transaction Views & Filters & Search', 'event_espresso'),
171
+						'filename' => 'transactions_overview_views_filters_search',
172
+					],
173
+				],
174
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
175
+				// 'help_tour'     => array('Transactions_Overview_Help_Tour'),
176
+				/**
177
+				 * commented out because currently we are not displaying tips for transaction list table status but this
178
+				 * may change in a later iteration so want to keep the code for then.
179
+				 */
180
+				// 'qtips' => array( 'Transactions_List_Table_Tips' ),
181
+				'require_nonce' => false,
182
+			],
183
+			'view_transaction' => [
184
+				'nav'       => [
185
+					'label'      => esc_html__('View Transaction', 'event_espresso'),
186
+					'order'      => 5,
187
+					'url'        => $TXN_ID
188
+						? add_query_arg(['TXN_ID' => $TXN_ID], $this->_current_page_view_url)
189
+						: $this->_admin_base_url,
190
+					'persistent' => false,
191
+				],
192
+				'help_tabs' => [
193
+					'transactions_view_transaction_help_tab'                                              => [
194
+						'title'    => esc_html__('View Transaction', 'event_espresso'),
195
+						'filename' => 'transactions_view_transaction',
196
+					],
197
+					'transactions_view_transaction_transaction_details_table_help_tab'                    => [
198
+						'title'    => esc_html__('Transaction Details Table', 'event_espresso'),
199
+						'filename' => 'transactions_view_transaction_transaction_details_table',
200
+					],
201
+					'transactions_view_transaction_attendees_registered_help_tab'                         => [
202
+						'title'    => esc_html__('Attendees Registered', 'event_espresso'),
203
+						'filename' => 'transactions_view_transaction_attendees_registered',
204
+					],
205
+					'transactions_view_transaction_views_primary_registrant_billing_information_help_tab' => [
206
+						'title'    => esc_html__('Primary Registrant & Billing Information', 'event_espresso'),
207
+						'filename' => 'transactions_view_transaction_primary_registrant_billing_information',
208
+					],
209
+				],
210
+				'qtips'     => ['Transaction_Details_Tips'],
211
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
212
+				// 'help_tour' => array('Transaction_Details_Help_Tour'),
213
+				'metaboxes' => ['_transaction_details_metaboxes'],
214
+
215
+				'require_nonce' => false,
216
+			],
217
+		];
218
+	}
219
+
220
+
221
+	/**
222
+	 * The below methods aren't used by this class currently
223
+	 */
224
+	protected function _add_screen_options()
225
+	{
226
+		// noop
227
+	}
228
+
229
+
230
+	protected function _add_feature_pointers()
231
+	{
232
+		// noop
233
+	}
234
+
235
+
236
+	public function admin_init()
237
+	{
238
+		$EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
239
+		$event_name = $this->request->getRequestParam('event_name');
240
+		$redirect_from = $this->request->getRequestParam('redirect_from', '', 'url');
241
+		// IF a registration was JUST added via the admin...
242
+		if ($EVT_ID && $event_name && $redirect_from) {
243
+			// then set a cookie so that we can block any attempts to use
244
+			// the back button as a way to enter another registration.
245
+			setcookie('ee_registration_added', $EVT_ID, time() + WEEK_IN_SECONDS, '/');
246
+			// and update the global
247
+			$_COOKIE['ee_registration_added'] = $EVT_ID;
248
+		}
249
+		EE_Registry::$i18n_js_strings['invalid_server_response'] = esc_html__(
250
+			'An error occurred! Your request may have been processed, but a valid response from the server was not received. Please refresh the page and try again.',
251
+			'event_espresso'
252
+		);
253
+		EE_Registry::$i18n_js_strings['error_occurred']          = esc_html__(
254
+			'An error occurred! Please refresh the page and try again.',
255
+			'event_espresso'
256
+		);
257
+		EE_Registry::$i18n_js_strings['txn_status_array']        = self::$_txn_status;
258
+		EE_Registry::$i18n_js_strings['pay_status_array']        = self::$_pay_status;
259
+		EE_Registry::$i18n_js_strings['payments_total']          = esc_html__('Payments Total', 'event_espresso');
260
+		EE_Registry::$i18n_js_strings['transaction_overpaid']    = esc_html__(
261
+			'This transaction has been overpaid ! Payments Total',
262
+			'event_espresso'
263
+		);
264
+	}
265
+
266
+
267
+	public function admin_notices()
268
+	{
269
+		// noop
270
+	}
271
+
272
+
273
+	public function admin_footer_scripts()
274
+	{
275
+		// noop
276
+	}
277
+
278
+
279
+	/**
280
+	 * _set_transaction_status_array
281
+	 * sets list of transaction statuses
282
+	 *
283
+	 * @access private
284
+	 * @return void
285
+	 * @throws EE_Error
286
+	 * @throws InvalidArgumentException
287
+	 * @throws InvalidDataTypeException
288
+	 * @throws InvalidInterfaceException
289
+	 */
290
+	private function _set_transaction_status_array()
291
+	{
292
+		self::$_txn_status = EEM_Transaction::instance()->status_array(true);
293
+	}
294
+
295
+
296
+	/**
297
+	 * get_transaction_status_array
298
+	 * return the transaction status array for wp_list_table
299
+	 *
300
+	 * @access public
301
+	 * @return array
302
+	 */
303
+	public function get_transaction_status_array()
304
+	{
305
+		return self::$_txn_status;
306
+	}
307
+
308
+
309
+	/**
310
+	 *    get list of payment statuses
311
+	 *
312
+	 * @access private
313
+	 * @return void
314
+	 * @throws EE_Error
315
+	 * @throws InvalidArgumentException
316
+	 * @throws InvalidDataTypeException
317
+	 * @throws InvalidInterfaceException
318
+	 */
319
+	private function _get_payment_status_array()
320
+	{
321
+		self::$_pay_status                      = EEM_Payment::instance()->status_array(true);
322
+		$this->_template_args['payment_status'] = self::$_pay_status;
323
+	}
324
+
325
+
326
+	/**
327
+	 *    _add_screen_options_default
328
+	 *
329
+	 * @access protected
330
+	 * @return void
331
+	 * @throws InvalidArgumentException
332
+	 * @throws InvalidDataTypeException
333
+	 * @throws InvalidInterfaceException
334
+	 */
335
+	protected function _add_screen_options_default()
336
+	{
337
+		$this->_per_page_screen_option();
338
+	}
339
+
340
+
341
+	/**
342
+	 * load_scripts_styles
343
+	 *
344
+	 * @access public
345
+	 * @return void
346
+	 */
347
+	public function load_scripts_styles()
348
+	{
349
+		// enqueue style
350
+		wp_register_style(
351
+			'espresso_txn',
352
+			TXN_ASSETS_URL . 'espresso_transactions_admin.css',
353
+			[],
354
+			EVENT_ESPRESSO_VERSION
355
+		);
356
+		wp_enqueue_style('espresso_txn');
357
+		// scripts
358
+		wp_register_script(
359
+			'espresso_txn',
360
+			TXN_ASSETS_URL . 'espresso_transactions_admin.js',
361
+			[
362
+				'ee_admin_js',
363
+				'ee-datepicker',
364
+				'jquery-ui-datepicker',
365
+				'jquery-ui-draggable',
366
+				'ee-dialog',
367
+				'ee-accounting',
368
+				'ee-serialize-full-array',
369
+			],
370
+			EVENT_ESPRESSO_VERSION,
371
+			true
372
+		);
373
+		wp_enqueue_script('espresso_txn');
374
+	}
375
+
376
+
377
+	/**
378
+	 *    load_scripts_styles_view_transaction
379
+	 *
380
+	 * @access public
381
+	 * @return void
382
+	 */
383
+	public function load_scripts_styles_view_transaction()
384
+	{
385
+		// styles
386
+		wp_enqueue_style('espresso-ui-theme');
387
+	}
388
+
389
+
390
+	/**
391
+	 *    load_scripts_styles_default
392
+	 *
393
+	 * @access public
394
+	 * @return void
395
+	 */
396
+	public function load_scripts_styles_default()
397
+	{
398
+		// styles
399
+		wp_enqueue_style('espresso-ui-theme');
400
+	}
401
+
402
+
403
+	/**
404
+	 *    _set_list_table_views_default
405
+	 *
406
+	 * @access protected
407
+	 * @return void
408
+	 */
409
+	protected function _set_list_table_views_default()
410
+	{
411
+		$this->_views = [
412
+			'all'        => [
413
+				'slug'  => 'all',
414
+				'label' => esc_html__('View All Transactions', 'event_espresso'),
415
+				'count' => 0,
416
+			],
417
+			'abandoned'  => [
418
+				'slug'  => 'abandoned',
419
+				'label' => esc_html__('Abandoned Transactions', 'event_espresso'),
420
+				'count' => 0,
421
+			],
422
+			'incomplete' => [
423
+				'slug'  => 'incomplete',
424
+				'label' => esc_html__('Incomplete Transactions', 'event_espresso'),
425
+				'count' => 0,
426
+			],
427
+		];
428
+		if (
429
+			/**
430
+			 * Filters whether a link to the "Failed Transactions" list table
431
+			 * appears on the Transactions Admin Page list table.
432
+			 * List display can be turned back on via the following:
433
+			 * add_filter(
434
+			 *     'FHEE__Transactions_Admin_Page___set_list_table_views_default__display_failed_txns_list',
435
+			 *     '__return_true'
436
+			 * );
437
+			 *
438
+			 * @param boolean                 $display_failed_txns_list
439
+			 * @param Transactions_Admin_Page $this
440
+			 * @since 4.9.70.p
441
+			 */
442
+			apply_filters(
443
+				'FHEE__Transactions_Admin_Page___set_list_table_views_default__display_failed_txns_list',
444
+				false,
445
+				$this
446
+			)
447
+		) {
448
+			$this->_views['failed'] = [
449
+				'slug'  => 'failed',
450
+				'label' => esc_html__('Failed Transactions', 'event_espresso'),
451
+				'count' => 0,
452
+			];
453
+		}
454
+	}
455
+
456
+
457
+	/**
458
+	 * _set_transaction_object
459
+	 * This sets the _transaction property for the transaction details screen
460
+	 *
461
+	 * @access private
462
+	 * @return void
463
+	 * @throws EE_Error
464
+	 * @throws InvalidArgumentException
465
+	 * @throws RuntimeException
466
+	 * @throws InvalidDataTypeException
467
+	 * @throws InvalidInterfaceException
468
+	 * @throws ReflectionException
469
+	 */
470
+	private function _set_transaction_object()
471
+	{
472
+		if ($this->_transaction instanceof EE_Transaction) {
473
+			return;
474
+		} //get out we've already set the object
475
+
476
+		$TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
477
+
478
+		// get transaction object
479
+		$this->_transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
480
+		$this->_session     = $this->_transaction instanceof EE_Transaction
481
+			? $this->_transaction->session_data()
482
+			: null;
483
+		if ($this->_transaction instanceof EE_Transaction) {
484
+			$this->_transaction->verify_abandoned_transaction_status();
485
+		}
486
+
487
+		if (! $this->_transaction instanceof EE_Transaction) {
488
+			$error_msg = sprintf(
489
+				esc_html__(
490
+					'An error occurred and the details for the transaction with the ID # %d could not be retrieved.',
491
+					'event_espresso'
492
+				),
493
+				$TXN_ID
494
+			);
495
+			EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
496
+		}
497
+	}
498
+
499
+
500
+	/**
501
+	 *    _transaction_legend_items
502
+	 *
503
+	 * @access protected
504
+	 * @return array
505
+	 * @throws EE_Error
506
+	 * @throws InvalidArgumentException
507
+	 * @throws ReflectionException
508
+	 * @throws InvalidDataTypeException
509
+	 * @throws InvalidInterfaceException
510
+	 */
511
+	protected function _transaction_legend_items()
512
+	{
513
+		EE_Registry::instance()->load_helper('MSG_Template');
514
+		$items = [];
515
+
516
+		if (
517
+			EE_Registry::instance()->CAP->current_user_can(
518
+				'ee_read_global_messages',
519
+				'view_filtered_messages'
520
+			)
521
+		) {
522
+			$related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
523
+			if (
524
+				is_array($related_for_icon)
525
+				&& isset($related_for_icon['css_class'], $related_for_icon['label'])
526
+			) {
527
+				$items['view_related_messages'] = [
528
+					'class' => $related_for_icon['css_class'],
529
+					'desc'  => $related_for_icon['label'],
530
+				];
531
+			}
532
+		}
533
+
534
+		$items = apply_filters(
535
+			'FHEE__Transactions_Admin_Page___transaction_legend_items__items',
536
+			array_merge(
537
+				$items,
538
+				[
539
+					'view_details'          => [
540
+						'class' => 'dashicons dashicons-cart',
541
+						'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
542
+					],
543
+					'view_invoice'          => [
544
+						'class' => 'dashicons dashicons-media-spreadsheet',
545
+						'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
546
+					],
547
+					'view_receipt'          => [
548
+						'class' => 'dashicons dashicons-media-default',
549
+						'desc'  => esc_html__('View Transaction Receipt', 'event_espresso'),
550
+					],
551
+					'view_registration'     => [
552
+						'class' => 'dashicons dashicons-clipboard',
553
+						'desc'  => esc_html__('View Registration Details', 'event_espresso'),
554
+					],
555
+					'payment_overview_link' => [
556
+						'class' => 'dashicons dashicons-money',
557
+						'desc'  => esc_html__('Make Payment on Frontend', 'event_espresso'),
558
+					],
559
+				]
560
+			)
561
+		);
562
+
563
+		if (
564
+			EEH_MSG_Template::is_mt_active('payment_reminder')
565
+			&& EE_Registry::instance()->CAP->current_user_can(
566
+				'ee_send_message',
567
+				'espresso_transactions_send_payment_reminder'
568
+			)
569
+		) {
570
+			$items['send_payment_reminder'] = [
571
+				'class' => 'dashicons dashicons-email-alt',
572
+				'desc'  => esc_html__('Send Payment Reminder', 'event_espresso'),
573
+			];
574
+		} else {
575
+			$items['blank*'] = [
576
+				'class' => '',
577
+				'desc'  => '',
578
+			];
579
+		}
580
+		$more_items = apply_filters(
581
+			'FHEE__Transactions_Admin_Page___transaction_legend_items__more_items',
582
+			[
583
+				'overpaid'   => [
584
+					'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::overpaid_status_code,
585
+					'desc'  => EEH_Template::pretty_status(
586
+						EEM_Transaction::overpaid_status_code,
587
+						false,
588
+						'sentence'
589
+					),
590
+				],
591
+				'complete'   => [
592
+					'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::complete_status_code,
593
+					'desc'  => EEH_Template::pretty_status(
594
+						EEM_Transaction::complete_status_code,
595
+						false,
596
+						'sentence'
597
+					),
598
+				],
599
+				'incomplete' => [
600
+					'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::incomplete_status_code,
601
+					'desc'  => EEH_Template::pretty_status(
602
+						EEM_Transaction::incomplete_status_code,
603
+						false,
604
+						'sentence'
605
+					),
606
+				],
607
+				'abandoned'  => [
608
+					'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::abandoned_status_code,
609
+					'desc'  => EEH_Template::pretty_status(
610
+						EEM_Transaction::abandoned_status_code,
611
+						false,
612
+						'sentence'
613
+					),
614
+				],
615
+				'failed'     => [
616
+					'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::failed_status_code,
617
+					'desc'  => EEH_Template::pretty_status(
618
+						EEM_Transaction::failed_status_code,
619
+						false,
620
+						'sentence'
621
+					),
622
+				],
623
+			]
624
+		);
625
+
626
+		return array_merge($items, $more_items);
627
+	}
628
+
629
+
630
+	/**
631
+	 *    _transactions_overview_list_table
632
+	 *
633
+	 * @access protected
634
+	 * @return void
635
+	 * @throws DomainException
636
+	 * @throws EE_Error
637
+	 * @throws InvalidArgumentException
638
+	 * @throws InvalidDataTypeException
639
+	 * @throws InvalidInterfaceException
640
+	 * @throws ReflectionException
641
+	 */
642
+	protected function _transactions_overview_list_table()
643
+	{
644
+		$this->_admin_page_title = esc_html__('Transactions', 'event_espresso');
645
+
646
+		$EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
647
+		$event = EEM_Event::instance()->get_one_by_ID($EVT_ID);
648
+		$this->_template_args['admin_page_header'] = $event instanceof EE_Event
649
+			? sprintf(
650
+				esc_html__('%sViewing Transactions for the Event: %s%s', 'event_espresso'),
651
+				'<h3>',
652
+				'<a href="'
653
+				. EE_Admin_Page::add_query_args_and_nonce(
654
+					['action' => 'edit', 'post' => $event->ID()],
655
+					EVENTS_ADMIN_URL
656
+				)
657
+				. '" title="'
658
+				. esc_attr__('Click to Edit event', 'event_espresso')
659
+				. '">' . $event->name() . '</a>',
660
+				'</h3>'
661
+			)
662
+			: '';
663
+		$this->_template_args['after_list_table']  = $this->_display_legend($this->_transaction_legend_items());
664
+		$this->display_admin_list_table_page_with_no_sidebar();
665
+	}
666
+
667
+
668
+	/**
669
+	 *    _transaction_details
670
+	 * generates HTML for the View Transaction Details Admin page
671
+	 *
672
+	 * @access protected
673
+	 * @return void
674
+	 * @throws DomainException
675
+	 * @throws EE_Error
676
+	 * @throws InvalidArgumentException
677
+	 * @throws InvalidDataTypeException
678
+	 * @throws InvalidInterfaceException
679
+	 * @throws RuntimeException
680
+	 * @throws ReflectionException
681
+	 */
682
+	protected function _transaction_details()
683
+	{
684
+		do_action('AHEE__Transactions_Admin_Page__transaction_details__start', $this->_transaction);
685
+
686
+		$this->_set_transaction_status_array();
687
+
688
+		$this->_template_args                      = [];
689
+		$this->_template_args['transactions_page'] = $this->_wp_page_slug;
690
+
691
+		$this->_set_transaction_object();
692
+
693
+		if (! $this->_transaction instanceof EE_Transaction) {
694
+			return;
695
+		}
696
+
697
+		$this->_template_args['txn_nmbr']['value'] = $this->_transaction->ID();
698
+		$this->_template_args['txn_nmbr']['label'] = esc_html__('Transaction Number', 'event_espresso');
699
+
700
+		$this->_template_args['txn_datetime']['value'] = $this->_transaction->get_i18n_datetime('TXN_timestamp');
701
+		$this->_template_args['txn_datetime']['label'] = esc_html__('Date', 'event_espresso');
702
+
703
+		$this->_template_args['txn_status']['value'] = self::$_txn_status[ $this->_transaction->status_ID() ];
704
+		$this->_template_args['txn_status']['label'] = esc_html__('Transaction Status', 'event_espresso');
705
+		$this->_template_args['txn_status']['class'] = 'status-' . $this->_transaction->status_ID();
706
+
707
+		$this->_template_args['grand_total'] = $this->_transaction->total();
708
+		$this->_template_args['total_paid']  = $this->_transaction->paid();
709
+
710
+		$amount_due                         = $this->_transaction->total() - $this->_transaction->paid();
711
+		$this->_template_args['amount_due'] = EEH_Template::format_currency(
712
+			$amount_due,
713
+			true
714
+		);
715
+		if (EE_Registry::instance()->CFG->currency->sign_b4) {
716
+			$this->_template_args['amount_due'] = EE_Registry::instance()->CFG->currency->sign
717
+												  . $this->_template_args['amount_due'];
718
+		} else {
719
+			$this->_template_args['amount_due'] .= EE_Registry::instance()->CFG->currency->sign;
720
+		}
721
+		$this->_template_args['amount_due_class'] = '';
722
+
723
+		if ($this->_transaction->paid() === $this->_transaction->total()) {
724
+			// paid in full
725
+			$this->_template_args['amount_due'] = false;
726
+		} elseif ($this->_transaction->paid() > $this->_transaction->total()) {
727
+			// overpaid
728
+			$this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
729
+		} elseif ($this->_transaction->total() > (float) 0) {
730
+			if ($this->_transaction->paid() > (float) 0) {
731
+				// monies owing
732
+				$this->_template_args['amount_due_class'] = 'txn-overview-part-payment-spn';
733
+			} elseif ($this->_transaction->paid() === (float) 0) {
734
+				// no payments made yet
735
+				$this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
736
+			}
737
+		} elseif ($this->_transaction->total() === (float) 0) {
738
+			// free event
739
+			$this->_template_args['amount_due'] = false;
740
+		}
741
+
742
+		$payment_method = $this->_transaction->payment_method();
743
+
744
+		$this->_template_args['method_of_payment_name'] = $payment_method instanceof EE_Payment_Method
745
+			? $payment_method->admin_name()
746
+			: esc_html__('Unknown', 'event_espresso');
747
+
748
+		$this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
749
+		// link back to overview
750
+		$this->_template_args['txn_overview_url'] = $this->request->getServerParam(
751
+			'HTTP_REFERER',
752
+			TXN_ADMIN_URL
753
+		);
754
+
755
+
756
+		// next link
757
+		$next_txn                                 = $this->_transaction->next(
758
+			null,
759
+			[['STS_ID' => ['!=', EEM_Transaction::failed_status_code]]],
760
+			'TXN_ID'
761
+		);
762
+		$this->_template_args['next_transaction'] = $next_txn
763
+			? $this->_next_link(
764
+				EE_Admin_Page::add_query_args_and_nonce(
765
+					['action' => 'view_transaction', 'TXN_ID' => $next_txn['TXN_ID']],
766
+					TXN_ADMIN_URL
767
+				),
768
+				'dashicons dashicons-arrow-right ee-icon-size-22'
769
+			)
770
+			: '';
771
+		// previous link
772
+		$previous_txn                                 = $this->_transaction->previous(
773
+			null,
774
+			[['STS_ID' => ['!=', EEM_Transaction::failed_status_code]]],
775
+			'TXN_ID'
776
+		);
777
+		$this->_template_args['previous_transaction'] = $previous_txn
778
+			? $this->_previous_link(
779
+				EE_Admin_Page::add_query_args_and_nonce(
780
+					['action' => 'view_transaction', 'TXN_ID' => $previous_txn['TXN_ID']],
781
+					TXN_ADMIN_URL
782
+				),
783
+				'dashicons dashicons-arrow-left ee-icon-size-22'
784
+			)
785
+			: '';
786
+
787
+		$EVT_ID        = $this->request->getRequestParam('EVT_ID', 0, 'int');
788
+		$event_name    = $this->request->getRequestParam('event_name');
789
+		$redirect_from = $this->request->getRequestParam('redirect_from', '', 'url');
790
+
791
+		// were we just redirected here after adding a new registration ???
792
+		if ($EVT_ID && $event_name && $redirect_from) {
793
+			if (
794
+				EE_Registry::instance()->CAP->current_user_can(
795
+					'ee_edit_registrations',
796
+					'espresso_registrations_new_registration',
797
+					$EVT_ID
798
+				)
799
+			) {
800
+				$this->_admin_page_title .= '<a id="add-new-registration" class="add-new-h2 button-primary" href="';
801
+				$this->_admin_page_title .= EE_Admin_Page::add_query_args_and_nonce(
802
+					[
803
+						'page'     => 'espresso_registrations',
804
+						'action'   => 'new_registration',
805
+						'return'   => 'default',
806
+						'TXN_ID'   => $this->_transaction->ID(),
807
+						'event_id' => $EVT_ID,
808
+					],
809
+					REG_ADMIN_URL
810
+				);
811
+				$this->_admin_page_title .= '">';
812
+
813
+				$this->_admin_page_title .= sprintf(
814
+					esc_html__('Add Another New Registration to Event: "%1$s" ?', 'event_espresso'),
815
+					htmlentities(urldecode($event_name), ENT_QUOTES, 'UTF-8')
816
+				);
817
+				$this->_admin_page_title .= '</a>';
818
+			}
819
+			EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
820
+		}
821
+		// grab messages at the last second
822
+		$this->_template_args['notices'] = EE_Error::get_notices();
823
+		// path to template
824
+		$template_path                             = TXN_TEMPLATE_PATH . 'txn_admin_details_header.template.php';
825
+		$this->_template_args['admin_page_header'] = EEH_Template::display_template(
826
+			$template_path,
827
+			$this->_template_args,
828
+			true
829
+		);
830
+
831
+		// the details template wrapper
832
+		$this->display_admin_page_with_sidebar();
833
+	}
834
+
835
+
836
+	/**
837
+	 *        _transaction_details_metaboxes
838
+	 *
839
+	 * @access protected
840
+	 * @return void
841
+	 * @throws EE_Error
842
+	 * @throws InvalidArgumentException
843
+	 * @throws InvalidDataTypeException
844
+	 * @throws InvalidInterfaceException
845
+	 * @throws RuntimeException
846
+	 * @throws ReflectionException
847
+	 */
848
+	protected function _transaction_details_metaboxes()
849
+	{
850
+
851
+		$this->_set_transaction_object();
852
+
853
+		if (! $this->_transaction instanceof EE_Transaction) {
854
+			return;
855
+		}
856
+		add_meta_box(
857
+			'edit-txn-details-mbox',
858
+			esc_html__('Transaction Details', 'event_espresso'),
859
+			[$this, 'txn_details_meta_box'],
860
+			$this->_wp_page_slug,
861
+			'normal',
862
+			'high'
863
+		);
864
+		add_meta_box(
865
+			'edit-txn-attendees-mbox',
866
+			esc_html__('Attendees Registered in this Transaction', 'event_espresso'),
867
+			[$this, 'txn_attendees_meta_box'],
868
+			$this->_wp_page_slug,
869
+			'normal',
870
+			'high',
871
+			['TXN_ID' => $this->_transaction->ID()]
872
+		);
873
+		add_meta_box(
874
+			'edit-txn-registrant-mbox',
875
+			esc_html__('Primary Contact', 'event_espresso'),
876
+			[$this, 'txn_registrant_side_meta_box'],
877
+			$this->_wp_page_slug,
878
+			'side',
879
+			'high'
880
+		);
881
+		add_meta_box(
882
+			'edit-txn-billing-info-mbox',
883
+			esc_html__('Billing Information', 'event_espresso'),
884
+			[$this, 'txn_billing_info_side_meta_box'],
885
+			$this->_wp_page_slug,
886
+			'side',
887
+			'high'
888
+		);
889
+	}
890
+
891
+
892
+	/**
893
+	 * Callback for transaction actions metabox.
894
+	 *
895
+	 * @param EE_Transaction|null $transaction
896
+	 * @return string
897
+	 * @throws DomainException
898
+	 * @throws EE_Error
899
+	 * @throws InvalidArgumentException
900
+	 * @throws InvalidDataTypeException
901
+	 * @throws InvalidInterfaceException
902
+	 * @throws ReflectionException
903
+	 * @throws RuntimeException
904
+	 */
905
+	public function getActionButtons(EE_Transaction $transaction = null)
906
+	{
907
+		$content = '';
908
+		$actions = [];
909
+		if (! $transaction instanceof EE_Transaction) {
910
+			return $content;
911
+		}
912
+		/** @var EE_Registration $primary_registration */
913
+		$primary_registration = $transaction->primary_registration();
914
+		$attendee             = $primary_registration instanceof EE_Registration
915
+			? $primary_registration->attendee()
916
+			: null;
917
+
918
+		if (
919
+			$attendee instanceof EE_Attendee
920
+			&& EE_Registry::instance()->CAP->current_user_can(
921
+				'ee_send_message',
922
+				'espresso_transactions_send_payment_reminder'
923
+			)
924
+		) {
925
+			$actions['payment_reminder'] =
926
+				EEH_MSG_Template::is_mt_active('payment_reminder')
927
+				&& $this->_transaction->status_ID() !== EEM_Transaction::complete_status_code
928
+				&& $this->_transaction->status_ID() !== EEM_Transaction::overpaid_status_code
929
+					? EEH_Template::get_button_or_link(
930
+						EE_Admin_Page::add_query_args_and_nonce(
931
+							[
932
+							'action'      => 'send_payment_reminder',
933
+							'TXN_ID'      => $this->_transaction->ID(),
934
+							'redirect_to' => 'view_transaction',
935
+							],
936
+							TXN_ADMIN_URL
937
+						),
938
+						esc_html__(' Send Payment Reminder', 'event_espresso'),
939
+						'button secondary-button',
940
+						'dashicons dashicons-email-alt'
941
+					)
942
+					: '';
943
+		}
944
+
945
+		if (
946
+			EE_Registry::instance()->CAP->current_user_can(
947
+				'ee_edit_payments',
948
+				'espresso_transactions_recalculate_line_items'
949
+			)
950
+		) {
951
+			$actions['recalculate_line_items'] = EEH_Template::get_button_or_link(
952
+				EE_Admin_Page::add_query_args_and_nonce(
953
+					[
954
+						'action'      => 'espresso_recalculate_line_items',
955
+						'TXN_ID'      => $this->_transaction->ID(),
956
+						'redirect_to' => 'view_transaction',
957
+					],
958
+					TXN_ADMIN_URL
959
+				),
960
+				esc_html__(' Recalculate Taxes and Total', 'event_espresso'),
961
+				'button secondary-button',
962
+				'dashicons dashicons-update'
963
+			);
964
+		}
965
+
966
+		if (
967
+			$primary_registration instanceof EE_Registration
968
+			&& EEH_MSG_Template::is_mt_active('receipt')
969
+		) {
970
+			$actions['receipt'] = EEH_Template::get_button_or_link(
971
+				$primary_registration->receipt_url(),
972
+				esc_html__('View Receipt', 'event_espresso'),
973
+				'button secondary-button',
974
+				'dashicons dashicons-media-default'
975
+			);
976
+		}
977
+
978
+		if (
979
+			$primary_registration instanceof EE_Registration
980
+			&& EEH_MSG_Template::is_mt_active('invoice')
981
+		) {
982
+			$actions['invoice'] = EEH_Template::get_button_or_link(
983
+				$primary_registration->invoice_url(),
984
+				esc_html__('View Invoice', 'event_espresso'),
985
+				'button secondary-button',
986
+				'dashicons dashicons-media-spreadsheet'
987
+			);
988
+		}
989
+		$actions = array_filter(
990
+			apply_filters('FHEE__Transactions_Admin_Page__getActionButtons__actions', $actions, $transaction)
991
+		);
992
+		if ($actions) {
993
+			$content = '<ul>';
994
+			$content .= '<li>' . implode('</li><li>', $actions) . '</li>';
995
+			$content .= '</uL>';
996
+		}
997
+		return $content;
998
+	}
999
+
1000
+
1001
+	/**
1002
+	 * txn_details_meta_box
1003
+	 * generates HTML for the Transaction main meta box
1004
+	 *
1005
+	 * @return void
1006
+	 * @throws DomainException
1007
+	 * @throws EE_Error
1008
+	 * @throws InvalidArgumentException
1009
+	 * @throws InvalidDataTypeException
1010
+	 * @throws InvalidInterfaceException
1011
+	 * @throws RuntimeException
1012
+	 * @throws ReflectionException
1013
+	 */
1014
+	public function txn_details_meta_box()
1015
+	{
1016
+		$this->_set_transaction_object();
1017
+		$this->_template_args['TXN_ID']              = $this->_transaction->ID();
1018
+		$this->_template_args['attendee']            =
1019
+			$this->_transaction->primary_registration() instanceof EE_Registration
1020
+				? $this->_transaction->primary_registration()->attendee()
1021
+				: null;
1022
+		$this->_template_args['can_edit_payments']   = EE_Registry::instance()->CAP->current_user_can(
1023
+			'ee_edit_payments',
1024
+			'apply_payment_or_refund_from_registration_details'
1025
+		);
1026
+		$this->_template_args['can_delete_payments'] = EE_Registry::instance()->CAP->current_user_can(
1027
+			'ee_delete_payments',
1028
+			'delete_payment_from_registration_details'
1029
+		);
1030
+
1031
+		// get line table
1032
+		EEH_Autoloader::register_line_item_display_autoloaders();
1033
+		$Line_Item_Display                       = new EE_Line_Item_Display(
1034
+			'admin_table',
1035
+			'EE_Admin_Table_Line_Item_Display_Strategy'
1036
+		);
1037
+		$this->_template_args['line_item_table'] = $Line_Item_Display->display_line_item(
1038
+			$this->_transaction->total_line_item()
1039
+		);
1040
+		$this->_template_args['REG_code']        =
1041
+			$this->_transaction->primary_registration() instanceof EE_Registration
1042
+				? $this->_transaction->primary_registration()->reg_code()
1043
+				: null;
1044
+		// process taxes
1045
+		$taxes                         = $this->_transaction->line_items([['LIN_type' => EEM_Line_Item::type_tax]]);
1046
+		$this->_template_args['taxes'] = ! empty($taxes) ? $taxes : false;
1047
+
1048
+		$this->_template_args['grand_total']     = EEH_Template::format_currency(
1049
+			$this->_transaction->total(),
1050
+			false,
1051
+			false
1052
+		);
1053
+		$this->_template_args['grand_raw_total'] = $this->_transaction->total();
1054
+		$this->_template_args['TXN_status']      = $this->_transaction->status_ID();
1055
+
1056
+		// process payment details
1057
+		$payments = $this->_transaction->payments();
1058
+		if (! empty($payments)) {
1059
+			$this->_template_args['payments']              = $payments;
1060
+			$this->_template_args['existing_reg_payments'] = $this->_get_registration_payment_IDs($payments);
1061
+		} else {
1062
+			$this->_template_args['payments']              = false;
1063
+			$this->_template_args['existing_reg_payments'] = [];
1064
+		}
1065
+
1066
+		$this->_template_args['edit_payment_url']   = add_query_arg(['action' => 'edit_payment'], TXN_ADMIN_URL);
1067
+		$this->_template_args['delete_payment_url'] = add_query_arg(
1068
+			['action' => 'espresso_delete_payment'],
1069
+			TXN_ADMIN_URL
1070
+		);
1071
+
1072
+		if (isset($txn_details['invoice_number'])) {
1073
+			$this->_template_args['txn_details']['invoice_number']['value'] = $this->_template_args['REG_code'];
1074
+			$this->_template_args['txn_details']['invoice_number']['label'] = esc_html__(
1075
+				'Invoice Number',
1076
+				'event_espresso'
1077
+			);
1078
+		}
1079
+
1080
+		$this->_template_args['txn_details']['registration_session']['value'] =
1081
+			$this->_transaction->primary_registration() instanceof EE_Registration
1082
+				? $this->_transaction->primary_registration()->session_ID()
1083
+				: null;
1084
+		$this->_template_args['txn_details']['registration_session']['label'] = esc_html__(
1085
+			'Registration Session',
1086
+			'event_espresso'
1087
+		);
1088
+
1089
+		$this->_template_args['txn_details']['ip_address']['value'] = isset($this->_session['ip_address'])
1090
+			? $this->_session['ip_address']
1091
+			: '';
1092
+		$this->_template_args['txn_details']['ip_address']['label'] = esc_html__(
1093
+			'Transaction placed from IP',
1094
+			'event_espresso'
1095
+		);
1096
+
1097
+		$this->_template_args['txn_details']['user_agent']['value'] = isset($this->_session['user_agent'])
1098
+			? $this->_session['user_agent']
1099
+			: '';
1100
+		$this->_template_args['txn_details']['user_agent']['label'] = esc_html__(
1101
+			'Registrant User Agent',
1102
+			'event_espresso'
1103
+		);
1104
+
1105
+		$reg_steps = '<ul>';
1106
+		foreach ($this->_transaction->reg_steps() as $reg_step => $reg_step_status) {
1107
+			if ($reg_step_status === true) {
1108
+				$reg_steps .= '<li style="color:#70cc50">'
1109
+							  . sprintf(
1110
+								  esc_html__('%1$s : Completed', 'event_espresso'),
1111
+								  ucwords(str_replace('_', ' ', $reg_step))
1112
+							  )
1113
+							  . '</li>';
1114
+			} elseif ($reg_step_status !== false && is_numeric($reg_step_status)) {
1115
+				$reg_steps .= '<li style="color:#2EA2CC">'
1116
+							  . sprintf(
1117
+								  esc_html__('%1$s : Initiated %2$s', 'event_espresso'),
1118
+								  ucwords(str_replace('_', ' ', $reg_step)),
1119
+								  date(
1120
+									  get_option('date_format') . ' ' . get_option('time_format'),
1121
+									  $reg_step_status + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1122
+								  )
1123
+							  )
1124
+							  . '</li>';
1125
+			} else {
1126
+				$reg_steps .= '<li style="color:#E76700">'
1127
+							  . sprintf(
1128
+								  esc_html__('%1$s : Never Initiated', 'event_espresso'),
1129
+								  ucwords(str_replace('_', ' ', $reg_step))
1130
+							  )
1131
+							  . '</li>';
1132
+			}
1133
+		}
1134
+		$reg_steps                                                 .= '</ul>';
1135
+		$this->_template_args['txn_details']['reg_steps']['value'] = $reg_steps;
1136
+		$this->_template_args['txn_details']['reg_steps']['label'] = esc_html__(
1137
+			'Registration Step Progress',
1138
+			'event_espresso'
1139
+		);
1140
+
1141
+
1142
+		$this->_get_registrations_to_apply_payment_to();
1143
+		$this->_get_payment_methods($payments);
1144
+		$this->_get_payment_status_array();
1145
+		$this->_get_reg_status_selection(); // sets up the template args for the reg status array for the transaction.
1146
+
1147
+		$this->_template_args['transaction_form_url']    = add_query_arg(
1148
+			[
1149
+				'action'  => 'edit_transaction',
1150
+				'process' => 'transaction',
1151
+			],
1152
+			TXN_ADMIN_URL
1153
+		);
1154
+		$this->_template_args['apply_payment_form_url']  = add_query_arg(
1155
+			[
1156
+				'page'   => 'espresso_transactions',
1157
+				'action' => 'espresso_apply_payment',
1158
+			],
1159
+			WP_AJAX_URL
1160
+		);
1161
+		$this->_template_args['delete_payment_form_url'] = add_query_arg(
1162
+			[
1163
+				'page'   => 'espresso_transactions',
1164
+				'action' => 'espresso_delete_payment',
1165
+			],
1166
+			WP_AJAX_URL
1167
+		);
1168
+
1169
+		$this->_template_args['action_buttons'] = $this->getActionButtons($this->_transaction);
1170
+
1171
+		// 'espresso_delete_payment_nonce'
1172
+
1173
+		$template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_txn_details.template.php';
1174
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);
1175
+	}
1176
+
1177
+
1178
+	/**
1179
+	 * _get_registration_payment_IDs
1180
+	 *    generates an array of Payment IDs and their corresponding Registration IDs
1181
+	 *
1182
+	 * @access protected
1183
+	 * @param EE_Payment[] $payments
1184
+	 * @return array
1185
+	 * @throws EE_Error
1186
+	 * @throws InvalidArgumentException
1187
+	 * @throws InvalidDataTypeException
1188
+	 * @throws InvalidInterfaceException
1189
+	 * @throws ReflectionException
1190
+	 */
1191
+	protected function _get_registration_payment_IDs($payments = [])
1192
+	{
1193
+		$existing_reg_payments = [];
1194
+		// get all reg payments for these payments
1195
+		$reg_payments = EEM_Registration_Payment::instance()->get_all(
1196
+			[
1197
+				[
1198
+					'PAY_ID' => [
1199
+						'IN',
1200
+						array_keys($payments),
1201
+					],
1202
+				],
1203
+			]
1204
+		);
1205
+		if (! empty($reg_payments)) {
1206
+			foreach ($payments as $payment) {
1207
+				if (! $payment instanceof EE_Payment) {
1208
+					continue;
1209
+				} elseif (! isset($existing_reg_payments[ $payment->ID() ])) {
1210
+					$existing_reg_payments[ $payment->ID() ] = [];
1211
+				}
1212
+				foreach ($reg_payments as $reg_payment) {
1213
+					if (
1214
+						$reg_payment instanceof EE_Registration_Payment
1215
+						&& $reg_payment->payment_ID() === $payment->ID()
1216
+					) {
1217
+						$existing_reg_payments[ $payment->ID() ][] = $reg_payment->registration_ID();
1218
+					}
1219
+				}
1220
+			}
1221
+		}
1222
+
1223
+		return $existing_reg_payments;
1224
+	}
1225
+
1226
+
1227
+	/**
1228
+	 * _get_registrations_to_apply_payment_to
1229
+	 *    generates HTML for displaying a series of checkboxes in the admin payment modal window
1230
+	 * which allows the admin to only apply the payment to the specific registrations
1231
+	 *
1232
+	 * @access protected
1233
+	 * @return void
1234
+	 * @throws EE_Error
1235
+	 * @throws InvalidArgumentException
1236
+	 * @throws InvalidDataTypeException
1237
+	 * @throws InvalidInterfaceException
1238
+	 * @throws ReflectionException
1239
+	 */
1240
+	protected function _get_registrations_to_apply_payment_to()
1241
+	{
1242
+		// we want any registration with an active status (ie: not deleted or cancelled)
1243
+		$query_params                      = [
1244
+			[
1245
+				'STS_ID' => [
1246
+					'IN',
1247
+					[
1248
+						EEM_Registration::status_id_approved,
1249
+						EEM_Registration::status_id_pending_payment,
1250
+						EEM_Registration::status_id_not_approved,
1251
+					],
1252
+				],
1253
+			],
1254
+		];
1255
+		$registrations_to_apply_payment_to = EEH_HTML::br() . EEH_HTML::div(
1256
+			'',
1257
+			'txn-admin-apply-payment-to-registrations-dv',
1258
+			'',
1259
+			'clear: both; margin: 1.5em 0 0; display: none;'
1260
+		);
1261
+		$registrations_to_apply_payment_to .= EEH_HTML::br() . EEH_HTML::div('', '', 'admin-primary-mbox-tbl-wrap');
1262
+		$registrations_to_apply_payment_to .= EEH_HTML::table('', '', 'admin-primary-mbox-tbl');
1263
+		$registrations_to_apply_payment_to .= EEH_HTML::thead(
1264
+			EEH_HTML::tr(
1265
+				EEH_HTML::th(esc_html__('ID', 'event_espresso')) .
1266
+				EEH_HTML::th(esc_html__('Registrant', 'event_espresso')) .
1267
+				EEH_HTML::th(esc_html__('Ticket', 'event_espresso')) .
1268
+				EEH_HTML::th(esc_html__('Event', 'event_espresso')) .
1269
+				EEH_HTML::th(esc_html__('Paid', 'event_espresso'), '', 'txn-admin-payment-paid-td jst-cntr') .
1270
+				EEH_HTML::th(esc_html__('Owing', 'event_espresso'), '', 'txn-admin-payment-owing-td jst-cntr') .
1271
+				EEH_HTML::th(esc_html__('Apply', 'event_espresso'), '', 'jst-cntr')
1272
+			)
1273
+		);
1274
+		$registrations_to_apply_payment_to .= EEH_HTML::tbody();
1275
+		// get registrations for TXN
1276
+		$registrations         = $this->_transaction->registrations($query_params);
1277
+		$existing_reg_payments = $this->_template_args['existing_reg_payments'];
1278
+		foreach ($registrations as $registration) {
1279
+			if ($registration instanceof EE_Registration) {
1280
+				$attendee_name                     = $registration->attendee() instanceof EE_Attendee
1281
+					? $registration->attendee()->full_name()
1282
+					: esc_html__('Unknown Attendee', 'event_espresso');
1283
+				$owing                             = $registration->final_price() - $registration->paid();
1284
+				$taxable                           = $registration->ticket()->taxable()
1285
+					? ' <span class="smaller-text lt-grey-text"> ' . esc_html__('+ tax', 'event_espresso') . '</span>'
1286
+					: '';
1287
+				$checked                           = empty($existing_reg_payments)
1288
+													 || in_array($registration->ID(), $existing_reg_payments, true)
1289
+					? ' checked="checked"'
1290
+					: '';
1291
+				$disabled                          = $registration->final_price() > 0 ? '' : ' disabled';
1292
+				$registrations_to_apply_payment_to .= EEH_HTML::tr(
1293
+					EEH_HTML::td($registration->ID()) .
1294
+					EEH_HTML::td($attendee_name) .
1295
+					EEH_HTML::td(
1296
+						$registration->ticket()->name() . ' : ' . $registration->ticket()->pretty_price() . $taxable
1297
+					) .
1298
+					EEH_HTML::td($registration->event_name()) .
1299
+					EEH_HTML::td($registration->pretty_paid(), '', 'txn-admin-payment-paid-td jst-cntr') .
1300
+					EEH_HTML::td(
1301
+						EEH_Template::format_currency($owing),
1302
+						'',
1303
+						'txn-admin-payment-owing-td jst-cntr'
1304
+					) .
1305
+					EEH_HTML::td(
1306
+						'<input type="checkbox" value="' . $registration->ID()
1307
+						. '" name="txn_admin_payment[registrations]"'
1308
+						. $checked . $disabled . '>',
1309
+						'',
1310
+						'jst-cntr'
1311
+					),
1312
+					'apply-payment-registration-row-' . $registration->ID()
1313
+				);
1314
+			}
1315
+		}
1316
+		$registrations_to_apply_payment_to                         .= EEH_HTML::tbodyx();
1317
+		$registrations_to_apply_payment_to                         .= EEH_HTML::tablex();
1318
+		$registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1319
+		$registrations_to_apply_payment_to                         .= EEH_HTML::p(
1320
+			esc_html__(
1321
+				'The payment will only be applied to the registrations that have a check mark in their corresponding check box. Checkboxes for free registrations have been disabled.',
1322
+				'event_espresso'
1323
+			),
1324
+			'',
1325
+			'clear description'
1326
+		);
1327
+		$registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1328
+		$this->_template_args['registrations_to_apply_payment_to'] = $registrations_to_apply_payment_to;
1329
+	}
1330
+
1331
+
1332
+	/**
1333
+	 * _get_reg_status_selection
1334
+	 *
1335
+	 * @return void
1336
+	 * @throws EE_Error
1337
+	 * @todo   this will need to be adjusted either once MER comes along OR we move default reg status to tickets
1338
+	 *         instead of events.
1339
+	 * @access protected
1340
+	 */
1341
+	protected function _get_reg_status_selection()
1342
+	{
1343
+		// first get all possible statuses
1344
+		$statuses = EEM_Registration::reg_status_array([], true);
1345
+		// let's add a "don't change" option.
1346
+		$status_array['NAN']                                 = esc_html__('Leave the Same', 'event_espresso');
1347
+		$status_array                                        = array_merge($status_array, $statuses);
1348
+		$this->_template_args['status_change_select']        = EEH_Form_Fields::select_input(
1349
+			'txn_reg_status_change[reg_status]',
1350
+			$status_array,
1351
+			'NAN',
1352
+			'id="txn-admin-payment-reg-status-inp"',
1353
+			'txn-reg-status-change-reg-status'
1354
+		);
1355
+		$this->_template_args['delete_status_change_select'] = EEH_Form_Fields::select_input(
1356
+			'delete_txn_reg_status_change[reg_status]',
1357
+			$status_array,
1358
+			'NAN',
1359
+			'delete-txn-admin-payment-reg-status-inp',
1360
+			'delete-txn-reg-status-change-reg-status'
1361
+		);
1362
+	}
1363
+
1364
+
1365
+	/**
1366
+	 *    _get_payment_methods
1367
+	 * Gets all the payment methods available generally, or the ones that are already
1368
+	 * selected on these payments (in case their payment methods are no longer active).
1369
+	 * Has the side-effect of updating the template args' payment_methods item
1370
+	 *
1371
+	 * @access private
1372
+	 * @param EE_Payment[] to show on this page
1373
+	 * @return void
1374
+	 * @throws EE_Error
1375
+	 * @throws InvalidArgumentException
1376
+	 * @throws InvalidDataTypeException
1377
+	 * @throws InvalidInterfaceException
1378
+	 * @throws ReflectionException
1379
+	 */
1380
+	private function _get_payment_methods($payments = [])
1381
+	{
1382
+		$payment_methods_of_payments = [];
1383
+		foreach ($payments as $payment) {
1384
+			if ($payment instanceof EE_Payment) {
1385
+				$payment_methods_of_payments[] = $payment->ID();
1386
+			}
1387
+		}
1388
+		if ($payment_methods_of_payments) {
1389
+			$query_args = [
1390
+				[
1391
+					'OR*payment_method_for_payment' => [
1392
+						'PMD_ID'    => ['IN', $payment_methods_of_payments],
1393
+						'PMD_scope' => ['LIKE', '%' . EEM_Payment_Method::scope_admin . '%'],
1394
+					],
1395
+				],
1396
+			];
1397
+		} else {
1398
+			$query_args = [['PMD_scope' => ['LIKE', '%' . EEM_Payment_Method::scope_admin . '%']]];
1399
+		}
1400
+		$this->_template_args['payment_methods'] = EEM_Payment_Method::instance()->get_all($query_args);
1401
+	}
1402
+
1403
+
1404
+	/**
1405
+	 * txn_attendees_meta_box
1406
+	 *    generates HTML for the Attendees Transaction main meta box
1407
+	 *
1408
+	 * @access public
1409
+	 * @param WP_Post $post
1410
+	 * @param array   $metabox
1411
+	 * @return void
1412
+	 * @throws DomainException
1413
+	 * @throws EE_Error
1414
+	 * @throws InvalidArgumentException
1415
+	 * @throws InvalidDataTypeException
1416
+	 * @throws InvalidInterfaceException
1417
+	 * @throws ReflectionException
1418
+	 */
1419
+	public function txn_attendees_meta_box($post, $metabox = ['args' => []])
1420
+	{
1421
+
1422
+		/** @noinspection NonSecureExtractUsageInspection */
1423
+		extract($metabox['args']);
1424
+		$this->_template_args['post']            = $post;
1425
+		$this->_template_args['event_attendees'] = [];
1426
+		// process items in cart
1427
+		$line_items = $this->_transaction->get_many_related(
1428
+			'Line_Item',
1429
+			[['LIN_type' => 'line-item']]
1430
+		);
1431
+		if (! empty($line_items)) {
1432
+			foreach ($line_items as $item) {
1433
+				if ($item instanceof EE_Line_Item) {
1434
+					switch ($item->OBJ_type()) {
1435
+						case 'Event':
1436
+							break;
1437
+						case 'Ticket':
1438
+							$ticket = $item->ticket();
1439
+							// right now we're only handling tickets here.
1440
+							// Cause its expected that only tickets will have attendees right?
1441
+							if (! $ticket instanceof EE_Ticket) {
1442
+								break;
1443
+							}
1444
+							try {
1445
+								$event_name = $ticket->get_event_name();
1446
+							} catch (Exception $e) {
1447
+								EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1448
+								$event_name = esc_html__('Unknown Event', 'event_espresso');
1449
+							}
1450
+							$event_name   .= ' - ' . $item->name();
1451
+							$ticket_price = EEH_Template::format_currency($item->unit_price());
1452
+							// now get all of the registrations for this transaction that use this ticket
1453
+							$registrations = $ticket->registrations(
1454
+								[['TXN_ID' => $this->_transaction->ID()]]
1455
+							);
1456
+							foreach ($registrations as $registration) {
1457
+								if (! $registration instanceof EE_Registration) {
1458
+									break;
1459
+								}
1460
+								$this->_template_args['event_attendees'][ $registration->ID() ]['STS_ID']
1461
+									= $registration->status_ID();
1462
+								$this->_template_args['event_attendees'][ $registration->ID() ]['att_num']
1463
+									= $registration->count();
1464
+								$this->_template_args['event_attendees'][ $registration->ID() ]['event_ticket_name']
1465
+									= $event_name;
1466
+								$this->_template_args['event_attendees'][ $registration->ID() ]['ticket_price']
1467
+									= $ticket_price;
1468
+								// attendee info
1469
+								$attendee = $registration->get_first_related('Attendee');
1470
+								if ($attendee instanceof EE_Attendee) {
1471
+									$this->_template_args['event_attendees'][ $registration->ID() ]['att_id']
1472
+										= $attendee->ID();
1473
+									$this->_template_args['event_attendees'][ $registration->ID() ]['attendee']
1474
+										= $attendee->full_name();
1475
+									$this->_template_args['event_attendees'][ $registration->ID() ]['email']
1476
+										= '<a href="mailto:' . $attendee->email() . '?subject=' . $event_name
1477
+										  . esc_html__(
1478
+											  ' Event',
1479
+											  'event_espresso'
1480
+										  )
1481
+										  . '">' . $attendee->email() . '</a>';
1482
+									$this->_template_args['event_attendees'][ $registration->ID() ]['address']
1483
+										= EEH_Address::format($attendee, 'inline', false, false);
1484
+								} else {
1485
+									$this->_template_args['event_attendees'][ $registration->ID() ]['att_id']   = '';
1486
+									$this->_template_args['event_attendees'][ $registration->ID() ]['attendee'] = '';
1487
+									$this->_template_args['event_attendees'][ $registration->ID() ]['email']    = '';
1488
+									$this->_template_args['event_attendees'][ $registration->ID() ]['address']  = '';
1489
+								}
1490
+							}
1491
+							break;
1492
+					}
1493
+				}
1494
+			}
1495
+
1496
+			$this->_template_args['transaction_form_url'] = add_query_arg(
1497
+				[
1498
+					'action'  => 'edit_transaction',
1499
+					'process' => 'attendees',
1500
+				],
1501
+				TXN_ADMIN_URL
1502
+			);
1503
+			echo EEH_Template::display_template(
1504
+				TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_attendees.template.php',
1505
+				$this->_template_args,
1506
+				true
1507
+			);
1508
+		} else {
1509
+			printf(
1510
+				esc_html__(
1511
+					'%1$sFor some reason, there are no attendees registered for this transaction. Likely the registration was abandoned in process.%2$s',
1512
+					'event_espresso'
1513
+				),
1514
+				'<p class="important-notice">',
1515
+				'</p>'
1516
+			);
1517
+		}
1518
+	}
1519
+
1520
+
1521
+	/**
1522
+	 * txn_registrant_side_meta_box
1523
+	 * generates HTML for the Edit Transaction side meta box
1524
+	 *
1525
+	 * @access public
1526
+	 * @return void
1527
+	 * @throws DomainException
1528
+	 * @throws EE_Error
1529
+	 * @throws InvalidArgumentException
1530
+	 * @throws InvalidDataTypeException
1531
+	 * @throws InvalidInterfaceException
1532
+	 * @throws ReflectionException
1533
+	 */
1534
+	public function txn_registrant_side_meta_box()
1535
+	{
1536
+		$primary_att = $this->_transaction->primary_registration() instanceof EE_Registration
1537
+			? $this->_transaction->primary_registration()->get_first_related('Attendee')
1538
+			: null;
1539
+		if (! $primary_att instanceof EE_Attendee) {
1540
+			$this->_template_args['no_attendee_message'] = esc_html__(
1541
+				'There is no attached contact for this transaction.  The transaction either failed due to an error or was abandoned.',
1542
+				'event_espresso'
1543
+			);
1544
+			$primary_att                           = EEM_Attendee::instance()->create_default_object();
1545
+		}
1546
+		$this->_template_args['ATT_ID']            = $primary_att->ID();
1547
+		$this->_template_args['prime_reg_fname']   = $primary_att->fname();
1548
+		$this->_template_args['prime_reg_lname']   = $primary_att->lname();
1549
+		$this->_template_args['prime_reg_email']   = $primary_att->email();
1550
+		$this->_template_args['prime_reg_phone']   = $primary_att->phone();
1551
+		$this->_template_args['edit_attendee_url'] = EE_Admin_Page::add_query_args_and_nonce(
1552
+			[
1553
+				'action' => 'edit_attendee',
1554
+				'post'   => $primary_att->ID(),
1555
+			],
1556
+			REG_ADMIN_URL
1557
+		);
1558
+		// get formatted address for registrant
1559
+		$this->_template_args['formatted_address'] = EEH_Address::format($primary_att);
1560
+		echo EEH_Template::display_template(
1561
+			TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_registrant.template.php',
1562
+			$this->_template_args,
1563
+			true
1564
+		);
1565
+	}
1566
+
1567
+
1568
+	/**
1569
+	 * txn_billing_info_side_meta_box
1570
+	 *    generates HTML for the Edit Transaction side meta box
1571
+	 *
1572
+	 * @access public
1573
+	 * @return void
1574
+	 * @throws DomainException
1575
+	 * @throws EE_Error
1576
+	 * @throws ReflectionException
1577
+	 */
1578
+	public function txn_billing_info_side_meta_box()
1579
+	{
1580
+
1581
+		$this->_template_args['billing_form']     = $this->_transaction->billing_info();
1582
+		$this->_template_args['billing_form_url'] = add_query_arg(
1583
+			['action' => 'edit_transaction', 'process' => 'billing'],
1584
+			TXN_ADMIN_URL
1585
+		);
1586
+
1587
+		$template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_billing_info.template.php';
1588
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);
1589
+	}
1590
+
1591
+
1592
+	/**
1593
+	 * apply_payments_or_refunds
1594
+	 *    registers a payment or refund made towards a transaction
1595
+	 *
1596
+	 * @access public
1597
+	 * @return void
1598
+	 * @throws EE_Error
1599
+	 * @throws InvalidArgumentException
1600
+	 * @throws ReflectionException
1601
+	 * @throws RuntimeException
1602
+	 * @throws InvalidDataTypeException
1603
+	 * @throws InvalidInterfaceException
1604
+	 */
1605
+	public function apply_payments_or_refunds()
1606
+	{
1607
+		$json_response_data = ['return_data' => false];
1608
+		$valid_data         = $this->_validate_payment_request_data();
1609
+		$has_access         = EE_Registry::instance()->CAP->current_user_can(
1610
+			'ee_edit_payments',
1611
+			'apply_payment_or_refund_from_registration_details'
1612
+		);
1613
+		if (! empty($valid_data) && $has_access) {
1614
+			$PAY_ID = $valid_data['PAY_ID'];
1615
+			// save  the new payment
1616
+			$payment = $this->_create_payment_from_request_data($valid_data);
1617
+			// get the TXN for this payment
1618
+			$transaction = $payment->transaction();
1619
+			// verify transaction
1620
+			if ($transaction instanceof EE_Transaction) {
1621
+				// calculate_total_payments_and_update_status
1622
+				$this->_process_transaction_payments($transaction);
1623
+				$REG_IDs = $this->_get_REG_IDs_to_apply_payment_to($payment);
1624
+				$this->_remove_existing_registration_payments($payment, $PAY_ID);
1625
+				// apply payment to registrations (if applicable)
1626
+				if (! empty($REG_IDs)) {
1627
+					$this->_update_registration_payments($transaction, $payment, $REG_IDs);
1628
+					$this->_maybe_send_notifications();
1629
+					// now process status changes for the same registrations
1630
+					$this->_process_registration_status_change($transaction, $REG_IDs);
1631
+				}
1632
+				$this->_maybe_send_notifications($payment);
1633
+				// prepare to render page
1634
+				$json_response_data['return_data'] = $this->_build_payment_json_response($payment, $REG_IDs);
1635
+				do_action(
1636
+					'AHEE__Transactions_Admin_Page__apply_payments_or_refund__after_recording',
1637
+					$transaction,
1638
+					$payment
1639
+				);
1640
+			} else {
1641
+				EE_Error::add_error(
1642
+					esc_html__(
1643
+						'A valid Transaction for this payment could not be retrieved.',
1644
+						'event_espresso'
1645
+					),
1646
+					__FILE__,
1647
+					__FUNCTION__,
1648
+					__LINE__
1649
+				);
1650
+			}
1651
+		} elseif ($has_access) {
1652
+			EE_Error::add_error(
1653
+				esc_html__(
1654
+					'The payment form data could not be processed. Please try again.',
1655
+					'event_espresso'
1656
+				),
1657
+				__FILE__,
1658
+				__FUNCTION__,
1659
+				__LINE__
1660
+			);
1661
+		} else {
1662
+			EE_Error::add_error(
1663
+				esc_html__(
1664
+					'You do not have access to apply payments or refunds to a registration.',
1665
+					'event_espresso'
1666
+				),
1667
+				__FILE__,
1668
+				__FUNCTION__,
1669
+				__LINE__
1670
+			);
1671
+		}
1672
+		$notices              = EE_Error::get_notices(
1673
+			false,
1674
+			false,
1675
+			false
1676
+		);
1677
+		$this->_template_args = [
1678
+			'data'    => $json_response_data,
1679
+			'error'   => $notices['errors'],
1680
+			'success' => $notices['success'],
1681
+		];
1682
+		$this->_return_json();
1683
+	}
1684
+
1685
+
1686
+	/**
1687
+	 * _validate_payment_request_data
1688
+	 *
1689
+	 * @return array
1690
+	 * @throws EE_Error
1691
+	 * @throws InvalidArgumentException
1692
+	 * @throws InvalidDataTypeException
1693
+	 * @throws InvalidInterfaceException
1694
+	 */
1695
+	protected function _validate_payment_request_data()
1696
+	{
1697
+		if (! $this->request->requestParamIsSet('txn_admin_payment')) {
1698
+			return [];
1699
+		}
1700
+		$payment_form = $this->_generate_payment_form_section();
1701
+		try {
1702
+			if ($payment_form->was_submitted()) {
1703
+				$payment_form->receive_form_submission();
1704
+				if (! $payment_form->is_valid()) {
1705
+					$submission_error_messages = [];
1706
+					foreach ($payment_form->get_validation_errors_accumulated() as $validation_error) {
1707
+						if ($validation_error instanceof EE_Validation_Error) {
1708
+							$form_input = $validation_error->get_form_section();
1709
+							$submission_error_messages[] = sprintf(
1710
+								_x('%s : %s', 'Form Section Name : Form Validation Error', 'event_espresso'),
1711
+								$form_input instanceof EE_Form_Input_Base ? $form_input->html_label_text() : '',
1712
+								$validation_error->getMessage()
1713
+							);
1714
+						}
1715
+					}
1716
+					EE_Error::add_error(
1717
+						implode('<br />', $submission_error_messages),
1718
+						__FILE__,
1719
+						__FUNCTION__,
1720
+						__LINE__
1721
+					);
1722
+					return [];
1723
+				}
1724
+			}
1725
+		} catch (EE_Error $e) {
1726
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1727
+			return [];
1728
+		}
1729
+
1730
+		return $payment_form->valid_data();
1731
+	}
1732
+
1733
+
1734
+	/**
1735
+	 * _generate_payment_form_section
1736
+	 *
1737
+	 * @return EE_Form_Section_Proper
1738
+	 * @throws EE_Error
1739
+	 */
1740
+	protected function _generate_payment_form_section()
1741
+	{
1742
+		return new EE_Form_Section_Proper(
1743
+			[
1744
+				'name'        => 'txn_admin_payment',
1745
+				'subsections' => [
1746
+					'PAY_ID'          => new EE_Text_Input(
1747
+						[
1748
+							'default'               => 0,
1749
+							'required'              => false,
1750
+							'html_label_text'       => esc_html__('Payment ID', 'event_espresso'),
1751
+							'validation_strategies' => [new EE_Int_Normalization()],
1752
+						]
1753
+					),
1754
+					'TXN_ID'          => new EE_Text_Input(
1755
+						[
1756
+							'default'               => 0,
1757
+							'required'              => true,
1758
+							'html_label_text'       => esc_html__('Transaction ID', 'event_espresso'),
1759
+							'validation_strategies' => [new EE_Int_Normalization()],
1760
+						]
1761
+					),
1762
+					'type'            => new EE_Text_Input(
1763
+						[
1764
+							'default'               => 1,
1765
+							'required'              => true,
1766
+							'html_label_text'       => esc_html__('Payment or Refund', 'event_espresso'),
1767
+							'validation_strategies' => [new EE_Int_Normalization()],
1768
+						]
1769
+					),
1770
+					'amount'          => new EE_Text_Input(
1771
+						[
1772
+							'default'               => 0,
1773
+							'required'              => true,
1774
+							'html_label_text'       => esc_html__('Payment amount', 'event_espresso'),
1775
+							'validation_strategies' => [new EE_Float_Normalization()],
1776
+						]
1777
+					),
1778
+					'status'          => new EE_Text_Input(
1779
+						[
1780
+							'default'         => EEM_Payment::status_id_approved,
1781
+							'required'        => true,
1782
+							'html_label_text' => esc_html__('Payment status', 'event_espresso'),
1783
+						]
1784
+					),
1785
+					'PMD_ID'          => new EE_Text_Input(
1786
+						[
1787
+							'default'               => 2,
1788
+							'required'              => true,
1789
+							'html_label_text'       => esc_html__('Payment Method', 'event_espresso'),
1790
+							'validation_strategies' => [new EE_Int_Normalization()],
1791
+						]
1792
+					),
1793
+					'date'            => new EE_Text_Input(
1794
+						[
1795
+							'default'         => time(),
1796
+							'required'        => true,
1797
+							'html_label_text' => esc_html__('Payment date', 'event_espresso'),
1798
+						]
1799
+					),
1800
+					'txn_id_chq_nmbr' => new EE_Text_Input(
1801
+						[
1802
+							'default'               => '',
1803
+							'required'              => false,
1804
+							'html_label_text'       => esc_html__('Transaction or Cheque Number', 'event_espresso'),
1805
+							'validation_strategies' => [
1806
+								new EE_Max_Length_Validation_Strategy(
1807
+									esc_html__('Input too long', 'event_espresso'),
1808
+									100
1809
+								),
1810
+							],
1811
+						]
1812
+					),
1813
+					'po_number'       => new EE_Text_Input(
1814
+						[
1815
+							'default'               => '',
1816
+							'required'              => false,
1817
+							'html_label_text'       => esc_html__('Purchase Order Number', 'event_espresso'),
1818
+							'validation_strategies' => [
1819
+								new EE_Max_Length_Validation_Strategy(
1820
+									esc_html__('Input too long', 'event_espresso'),
1821
+									100
1822
+								),
1823
+							],
1824
+						]
1825
+					),
1826
+					'accounting'      => new EE_Text_Input(
1827
+						[
1828
+							'default'               => '',
1829
+							'required'              => false,
1830
+							'html_label_text'       => esc_html__('Extra Field for Accounting', 'event_espresso'),
1831
+							'validation_strategies' => [
1832
+								new EE_Max_Length_Validation_Strategy(
1833
+									esc_html__('Input too long', 'event_espresso'),
1834
+									100
1835
+								),
1836
+							],
1837
+						]
1838
+					),
1839
+				],
1840
+			]
1841
+		);
1842
+	}
1843
+
1844
+
1845
+	/**
1846
+	 * _create_payment_from_request_data
1847
+	 *
1848
+	 * @param array $valid_data
1849
+	 * @return EE_Payment
1850
+	 * @throws EE_Error
1851
+	 * @throws InvalidArgumentException
1852
+	 * @throws InvalidDataTypeException
1853
+	 * @throws InvalidInterfaceException
1854
+	 * @throws ReflectionException
1855
+	 */
1856
+	protected function _create_payment_from_request_data($valid_data)
1857
+	{
1858
+		$PAY_ID = $valid_data['PAY_ID'];
1859
+		// get payment amount
1860
+		$amount = $valid_data['amount'] ? abs($valid_data['amount']) : 0;
1861
+		// payments have a type value of 1 and refunds have a type value of -1
1862
+		// so multiplying amount by type will give a positive value for payments, and negative values for refunds
1863
+		$amount = $valid_data['type'] < 0 ? $amount * -1 : $amount;
1864
+		// for some reason the date string coming in has extra spaces between the date and time.  This fixes that.
1865
+		$date    = $valid_data['date']
1866
+			? preg_replace('/\s+/', ' ', $valid_data['date'])
1867
+			: date('Y-m-d g:i a', current_time('timestamp'));
1868
+		$payment = EE_Payment::new_instance(
1869
+			[
1870
+				'TXN_ID'              => $valid_data['TXN_ID'],
1871
+				'STS_ID'              => $valid_data['status'],
1872
+				'PAY_timestamp'       => $date,
1873
+				'PAY_source'          => EEM_Payment_Method::scope_admin,
1874
+				'PMD_ID'              => $valid_data['PMD_ID'],
1875
+				'PAY_amount'          => $amount,
1876
+				'PAY_txn_id_chq_nmbr' => $valid_data['txn_id_chq_nmbr'],
1877
+				'PAY_po_number'       => $valid_data['po_number'],
1878
+				'PAY_extra_accntng'   => $valid_data['accounting'],
1879
+				'PAY_details'         => $valid_data,
1880
+				'PAY_ID'              => $PAY_ID,
1881
+			],
1882
+			'',
1883
+			['Y-m-d', 'g:i a']
1884
+		);
1885
+
1886
+		if (! $payment->save()) {
1887
+			EE_Error::add_error(
1888
+				sprintf(
1889
+					esc_html__('Payment %1$d has not been successfully saved to the database.', 'event_espresso'),
1890
+					$payment->ID()
1891
+				),
1892
+				__FILE__,
1893
+				__FUNCTION__,
1894
+				__LINE__
1895
+			);
1896
+		}
1897
+
1898
+		return $payment;
1899
+	}
1900
+
1901
+
1902
+	/**
1903
+	 * _process_transaction_payments
1904
+	 *
1905
+	 * @param EE_Transaction $transaction
1906
+	 * @return void
1907
+	 * @throws EE_Error
1908
+	 * @throws InvalidArgumentException
1909
+	 * @throws ReflectionException
1910
+	 * @throws InvalidDataTypeException
1911
+	 * @throws InvalidInterfaceException
1912
+	 */
1913
+	protected function _process_transaction_payments(EE_Transaction $transaction)
1914
+	{
1915
+		/** @type EE_Transaction_Payments $transaction_payments */
1916
+		$transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
1917
+		// update the transaction with this payment
1918
+		if ($transaction_payments->calculate_total_payments_and_update_status($transaction)) {
1919
+			EE_Error::add_success(
1920
+				esc_html__(
1921
+					'The payment has been processed successfully.',
1922
+					'event_espresso'
1923
+				),
1924
+				__FILE__,
1925
+				__FUNCTION__,
1926
+				__LINE__
1927
+			);
1928
+		} else {
1929
+			EE_Error::add_error(
1930
+				esc_html__(
1931
+					'The payment was processed successfully but the amount paid for the transaction was not updated.',
1932
+					'event_espresso'
1933
+				),
1934
+				__FILE__,
1935
+				__FUNCTION__,
1936
+				__LINE__
1937
+			);
1938
+		}
1939
+	}
1940
+
1941
+
1942
+	/**
1943
+	 * _get_REG_IDs_to_apply_payment_to
1944
+	 * returns a list of registration IDs that the payment will apply to
1945
+	 *
1946
+	 * @param EE_Payment $payment
1947
+	 * @return array
1948
+	 * @throws EE_Error
1949
+	 * @throws InvalidArgumentException
1950
+	 * @throws InvalidDataTypeException
1951
+	 * @throws InvalidInterfaceException
1952
+	 * @throws ReflectionException
1953
+	 */
1954
+	protected function _get_REG_IDs_to_apply_payment_to(EE_Payment $payment)
1955
+	{
1956
+		// grab array of IDs for specific registrations to apply changes to
1957
+		$REG_IDs = $this->request->getRequestParam('txn_admin_payment[registrations]', [], 'int', true);
1958
+		// nothing specified ? then get all reg IDs
1959
+		if (empty($REG_IDs)) {
1960
+			$registrations = $payment->transaction()->registrations();
1961
+			$REG_IDs       = ! empty($registrations)
1962
+				? array_keys($registrations)
1963
+				: $this->_get_existing_reg_payment_REG_IDs($payment);
1964
+		}
1965
+
1966
+		// ensure that REG_IDs are integers and NOT strings
1967
+		return array_map('intval', $REG_IDs);
1968
+	}
1969
+
1970
+
1971
+	/**
1972
+	 * @return array
1973
+	 */
1974
+	public function existing_reg_payment_REG_IDs()
1975
+	{
1976
+		return $this->_existing_reg_payment_REG_IDs;
1977
+	}
1978
+
1979
+
1980
+	/**
1981
+	 * @param array $existing_reg_payment_REG_IDs
1982
+	 */
1983
+	public function set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs = null)
1984
+	{
1985
+		$this->_existing_reg_payment_REG_IDs = $existing_reg_payment_REG_IDs;
1986
+	}
1987
+
1988
+
1989
+	/**
1990
+	 * _get_existing_reg_payment_REG_IDs
1991
+	 * returns a list of registration IDs that the payment is currently related to
1992
+	 * as recorded in the database
1993
+	 *
1994
+	 * @param EE_Payment $payment
1995
+	 * @return array
1996
+	 * @throws EE_Error
1997
+	 * @throws InvalidArgumentException
1998
+	 * @throws InvalidDataTypeException
1999
+	 * @throws InvalidInterfaceException
2000
+	 * @throws ReflectionException
2001
+	 */
2002
+	protected function _get_existing_reg_payment_REG_IDs(EE_Payment $payment)
2003
+	{
2004
+		if ($this->existing_reg_payment_REG_IDs() === null) {
2005
+			// let's get any existing reg payment records for this payment
2006
+			$existing_reg_payment_REG_IDs = $payment->get_many_related('Registration');
2007
+			// but we only want the REG IDs, so grab the array keys
2008
+			$existing_reg_payment_REG_IDs = ! empty($existing_reg_payment_REG_IDs)
2009
+				? array_keys($existing_reg_payment_REG_IDs)
2010
+				: [];
2011
+			$this->set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs);
2012
+		}
2013
+
2014
+		return $this->existing_reg_payment_REG_IDs();
2015
+	}
2016
+
2017
+
2018
+	/**
2019
+	 * _remove_existing_registration_payments
2020
+	 * this calculates the difference between existing relations
2021
+	 * to the supplied payment and the new list registration IDs,
2022
+	 * removes any related registrations that no longer apply,
2023
+	 * and then updates the registration paid fields
2024
+	 *
2025
+	 * @param EE_Payment $payment
2026
+	 * @param int        $PAY_ID
2027
+	 * @return bool;
2028
+	 * @throws EE_Error
2029
+	 * @throws InvalidArgumentException
2030
+	 * @throws ReflectionException
2031
+	 * @throws InvalidDataTypeException
2032
+	 * @throws InvalidInterfaceException
2033
+	 */
2034
+	protected function _remove_existing_registration_payments(EE_Payment $payment, $PAY_ID = 0)
2035
+	{
2036
+		// newly created payments will have nothing recorded for $PAY_ID
2037
+		if (absint($PAY_ID) === 0) {
2038
+			return false;
2039
+		}
2040
+		$existing_reg_payment_REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
2041
+		if (empty($existing_reg_payment_REG_IDs)) {
2042
+			return false;
2043
+		}
2044
+		/** @type EE_Transaction_Payments $transaction_payments */
2045
+		$transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
2046
+
2047
+		return $transaction_payments->delete_registration_payments_and_update_registrations(
2048
+			$payment,
2049
+			[
2050
+				[
2051
+					'PAY_ID' => $payment->ID(),
2052
+					'REG_ID' => ['IN', $existing_reg_payment_REG_IDs],
2053
+				],
2054
+			]
2055
+		);
2056
+	}
2057
+
2058
+
2059
+	/**
2060
+	 * _update_registration_payments
2061
+	 * this applies the payments to the selected registrations
2062
+	 * but only if they have not already been paid for
2063
+	 *
2064
+	 * @param EE_Transaction $transaction
2065
+	 * @param EE_Payment     $payment
2066
+	 * @param array          $REG_IDs
2067
+	 * @return void
2068
+	 * @throws EE_Error
2069
+	 * @throws InvalidArgumentException
2070
+	 * @throws ReflectionException
2071
+	 * @throws RuntimeException
2072
+	 * @throws InvalidDataTypeException
2073
+	 * @throws InvalidInterfaceException
2074
+	 */
2075
+	protected function _update_registration_payments(
2076
+		EE_Transaction $transaction,
2077
+		EE_Payment $payment,
2078
+		$REG_IDs = []
2079
+	) {
2080
+		// we can pass our own custom set of registrations to EE_Payment_Processor::process_registration_payments()
2081
+		// so let's do that using our set of REG_IDs from the form
2082
+		$registration_query_where_params = [
2083
+			'REG_ID' => ['IN', $REG_IDs],
2084
+		];
2085
+		// but add in some conditions regarding payment,
2086
+		// so that we don't apply payments to registrations that are free or have already been paid for
2087
+		// but ONLY if the payment is NOT a refund ( ie: the payment amount is not negative )
2088
+		if (! $payment->is_a_refund()) {
2089
+			$registration_query_where_params['REG_final_price']  = ['!=', 0];
2090
+			$registration_query_where_params['REG_final_price*'] = ['!=', 'REG_paid', true];
2091
+		}
2092
+		$registrations = $transaction->registrations([$registration_query_where_params]);
2093
+		if (! empty($registrations)) {
2094
+			/** @type EE_Payment_Processor $payment_processor */
2095
+			$payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
2096
+			$payment_processor->process_registration_payments($transaction, $payment, $registrations);
2097
+		}
2098
+	}
2099
+
2100
+
2101
+	/**
2102
+	 * _process_registration_status_change
2103
+	 * This processes requested registration status changes for all the registrations
2104
+	 * on a given transaction and (optionally) sends out notifications for the changes.
2105
+	 *
2106
+	 * @param EE_Transaction $transaction
2107
+	 * @param array          $REG_IDs
2108
+	 * @return bool
2109
+	 * @throws EE_Error
2110
+	 * @throws InvalidArgumentException
2111
+	 * @throws ReflectionException
2112
+	 * @throws InvalidDataTypeException
2113
+	 * @throws InvalidInterfaceException
2114
+	 */
2115
+	protected function _process_registration_status_change(EE_Transaction $transaction, $REG_IDs = [])
2116
+	{
2117
+		// first if there is no change in status then we get out.
2118
+		$reg_status = $this->request->getRequestParam('txn_reg_status_change[reg_status]', 'NAN');
2119
+		if ($reg_status === 'NAN') {
2120
+			// no error message, no change requested, just nothing to do man.
2121
+			return false;
2122
+		}
2123
+		/** @type EE_Transaction_Processor $transaction_processor */
2124
+		$transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
2125
+
2126
+		// made it here dude?  Oh WOW.  K, let's take care of changing the statuses
2127
+		return $transaction_processor->manually_update_registration_statuses(
2128
+			$transaction,
2129
+			$reg_status,
2130
+			[['REG_ID' => ['IN', $REG_IDs]]]
2131
+		);
2132
+	}
2133
+
2134
+
2135
+	/**
2136
+	 * _build_payment_json_response
2137
+	 *
2138
+	 * @access public
2139
+	 * @param EE_Payment  $payment
2140
+	 * @param array       $REG_IDs
2141
+	 * @param bool | null $delete_txn_reg_status_change
2142
+	 * @return array
2143
+	 * @throws EE_Error
2144
+	 * @throws InvalidArgumentException
2145
+	 * @throws InvalidDataTypeException
2146
+	 * @throws InvalidInterfaceException
2147
+	 * @throws ReflectionException
2148
+	 */
2149
+	protected function _build_payment_json_response(
2150
+		EE_Payment $payment,
2151
+		$REG_IDs = [],
2152
+		$delete_txn_reg_status_change = null
2153
+	) {
2154
+		// was the payment deleted ?
2155
+		if (is_bool($delete_txn_reg_status_change)) {
2156
+			return [
2157
+				'PAY_ID'                       => $payment->ID(),
2158
+				'amount'                       => $payment->amount(),
2159
+				'total_paid'                   => $payment->transaction()->paid(),
2160
+				'txn_status'                   => $payment->transaction()->status_ID(),
2161
+				'pay_status'                   => $payment->STS_ID(),
2162
+				'registrations'                => $this->_registration_payment_data_array($REG_IDs),
2163
+				'delete_txn_reg_status_change' => $delete_txn_reg_status_change,
2164
+			];
2165
+		}
2166
+
2167
+		$this->_get_payment_status_array();
2168
+		return [
2169
+			'amount'           => $payment->amount(),
2170
+			'total_paid'       => $payment->transaction()->paid(),
2171
+			'txn_status'       => $payment->transaction()->status_ID(),
2172
+			'pay_status'       => $payment->STS_ID(),
2173
+			'PAY_ID'           => $payment->ID(),
2174
+			'STS_ID'           => $payment->STS_ID(),
2175
+			'status'           => self::$_pay_status[ $payment->STS_ID() ],
2176
+			'date'             => $payment->timestamp('Y-m-d', 'h:i a'),
2177
+			'method'           => strtoupper($payment->source()),
2178
+			'PM_ID'            => $payment->payment_method() ? $payment->payment_method()->ID() : 1,
2179
+			'gateway'          => $payment->payment_method()
2180
+				? $payment->payment_method()->admin_name()
2181
+				: esc_html__('Unknown', 'event_espresso'),
2182
+			'gateway_response' => $payment->gateway_response(),
2183
+			'txn_id_chq_nmbr'  => $payment->txn_id_chq_nmbr(),
2184
+			'po_number'        => $payment->po_number(),
2185
+			'extra_accntng'    => $payment->extra_accntng(),
2186
+			'registrations'    => $this->_registration_payment_data_array($REG_IDs),
2187
+		];
2188
+	}
2189
+
2190
+
2191
+	/**
2192
+	 * delete_payment
2193
+	 *    delete a payment or refund made towards a transaction
2194
+	 *
2195
+	 * @access public
2196
+	 * @return void
2197
+	 * @throws EE_Error
2198
+	 * @throws InvalidArgumentException
2199
+	 * @throws ReflectionException
2200
+	 * @throws InvalidDataTypeException
2201
+	 * @throws InvalidInterfaceException
2202
+	 */
2203
+	public function delete_payment()
2204
+	{
2205
+		$json_response_data = ['return_data' => false];
2206
+		$PAY_ID = $this->request->getRequestParam('delete_txn_admin_payment[PAY_ID]', 0, 'int');
2207
+
2208
+		$can_delete         = EE_Registry::instance()->CAP->current_user_can(
2209
+			'ee_delete_payments',
2210
+			'delete_payment_from_registration_details'
2211
+		);
2212
+		if ($PAY_ID && $can_delete) {
2213
+			$delete_txn_reg_status_change = $this->request->getRequestParam(
2214
+				'delete_txn_reg_status_change',
2215
+				false,
2216
+				'bool'
2217
+			);
2218
+			$payment = EEM_Payment::instance()->get_one_by_ID($PAY_ID);
2219
+			if ($payment instanceof EE_Payment) {
2220
+				$REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
2221
+				/** @type EE_Transaction_Payments $transaction_payments */
2222
+				$transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
2223
+				if ($transaction_payments->delete_payment_and_update_transaction($payment)) {
2224
+					$json_response_data['return_data'] = $this->_build_payment_json_response(
2225
+						$payment,
2226
+						$REG_IDs,
2227
+						$delete_txn_reg_status_change
2228
+					);
2229
+					if ($delete_txn_reg_status_change) {
2230
+						// MAKE sure we also add the delete_txn_req_status_change to the
2231
+						// request data because that's how messages will be looking for it.
2232
+						$this->request->setRequestParam('txn_reg_status_change', $delete_txn_reg_status_change);
2233
+						$this->_maybe_send_notifications();
2234
+						$this->_process_registration_status_change($payment->transaction(), $REG_IDs);
2235
+					}
2236
+				}
2237
+			} else {
2238
+				EE_Error::add_error(
2239
+					esc_html__('Valid Payment data could not be retrieved from the database.', 'event_espresso'),
2240
+					__FILE__,
2241
+					__FUNCTION__,
2242
+					__LINE__
2243
+				);
2244
+			}
2245
+		} elseif ($can_delete) {
2246
+			EE_Error::add_error(
2247
+				esc_html__(
2248
+					'A valid Payment ID was not received, therefore payment form data could not be loaded.',
2249
+					'event_espresso'
2250
+				),
2251
+				__FILE__,
2252
+				__FUNCTION__,
2253
+				__LINE__
2254
+			);
2255
+		} else {
2256
+			EE_Error::add_error(
2257
+				esc_html__(
2258
+					'You do not have access to delete a payment.',
2259
+					'event_espresso'
2260
+				),
2261
+				__FILE__,
2262
+				__FUNCTION__,
2263
+				__LINE__
2264
+			);
2265
+		}
2266
+		$notices              = EE_Error::get_notices(false, false, false);
2267
+		$this->_template_args = [
2268
+			'data'      => $json_response_data,
2269
+			'success'   => $notices['success'],
2270
+			'error'     => $notices['errors'],
2271
+			'attention' => $notices['attention'],
2272
+		];
2273
+		$this->_return_json();
2274
+	}
2275
+
2276
+
2277
+	/**
2278
+	 * _registration_payment_data_array
2279
+	 * adds info for 'owing' and 'paid' for each registration to the json response
2280
+	 *
2281
+	 * @access protected
2282
+	 * @param array $REG_IDs
2283
+	 * @return array
2284
+	 * @throws EE_Error
2285
+	 * @throws InvalidArgumentException
2286
+	 * @throws InvalidDataTypeException
2287
+	 * @throws InvalidInterfaceException
2288
+	 * @throws ReflectionException
2289
+	 */
2290
+	protected function _registration_payment_data_array($REG_IDs)
2291
+	{
2292
+		$registration_payment_data = [];
2293
+		// if non empty reg_ids lets get an array of registrations and update the values for the apply_payment/refund rows.
2294
+		if (! empty($REG_IDs)) {
2295
+			$registrations = EEM_Registration::instance()->get_all([['REG_ID' => ['IN', $REG_IDs]]]);
2296
+			foreach ($registrations as $registration) {
2297
+				if ($registration instanceof EE_Registration) {
2298
+					$registration_payment_data[ $registration->ID() ] = [
2299
+						'paid'  => $registration->pretty_paid(),
2300
+						'owing' => EEH_Template::format_currency($registration->final_price() - $registration->paid()),
2301
+					];
2302
+				}
2303
+			}
2304
+		}
2305
+
2306
+		return $registration_payment_data;
2307
+	}
2308
+
2309
+
2310
+	/**
2311
+	 * _maybe_send_notifications
2312
+	 * determines whether or not the admin has indicated that notifications should be sent.
2313
+	 * If so, will toggle a filter switch for delivering registration notices.
2314
+	 * If passed an EE_Payment object, then it will trigger payment notifications instead.
2315
+	 *
2316
+	 * @access protected
2317
+	 * @param EE_Payment | null $payment
2318
+	 */
2319
+	protected function _maybe_send_notifications($payment = null)
2320
+	{
2321
+		switch ($payment instanceof EE_Payment) {
2322
+			// payment notifications
2323
+			case true:
2324
+				if ($this->request->getRequestParam('txn_payments[send_notifications]', false, 'bool')) {
2325
+					$this->_process_payment_notification($payment);
2326
+				}
2327
+				break;
2328
+			// registration notifications
2329
+			case false:
2330
+				if ($this->request->getRequestParam('txn_reg_status_change[send_notifications]', false, 'bool')) {
2331
+					add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true');
2332
+				}
2333
+				break;
2334
+		}
2335
+	}
2336
+
2337
+
2338
+	/**
2339
+	 * _send_payment_reminder
2340
+	 *    generates HTML for the View Transaction Details Admin page
2341
+	 *
2342
+	 * @access protected
2343
+	 * @return void
2344
+	 * @throws EE_Error
2345
+	 * @throws InvalidArgumentException
2346
+	 * @throws InvalidDataTypeException
2347
+	 * @throws InvalidInterfaceException
2348
+	 */
2349
+	protected function _send_payment_reminder()
2350
+	{
2351
+		$TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
2352
+		$transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2353
+		$redirect_to = $this->request->getRequestParam('redirect_to');
2354
+		$query_args  = $redirect_to ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID,] : [];
2355
+		do_action(
2356
+			'AHEE__Transactions_Admin_Page___send_payment_reminder__process_admin_payment_reminder',
2357
+			$transaction
2358
+		);
2359
+		$this->_redirect_after_action(
2360
+			false,
2361
+			esc_html__('payment reminder', 'event_espresso'),
2362
+			esc_html__('sent', 'event_espresso'),
2363
+			$query_args,
2364
+			true
2365
+		);
2366
+	}
2367
+
2368
+
2369
+	/**
2370
+	 *  get_transactions
2371
+	 *    get transactions for given parameters (used by list table)
2372
+	 *
2373
+	 * @param int     $per_page how many transactions displayed per page
2374
+	 * @param boolean $count   return the count or objects
2375
+	 * @param string  $view
2376
+	 * @return EE_Transaction[]|int int = count || array of transaction objects
2377
+	 * @throws EE_Error
2378
+	 * @throws InvalidArgumentException
2379
+	 * @throws InvalidDataTypeException
2380
+	 * @throws InvalidInterfaceException
2381
+	 */
2382
+	public function get_transactions($per_page, $count = false, $view = '')
2383
+	{
2384
+		$start_date = wp_strip_all_tags(
2385
+			$this->request->getRequestParam('txn-filter-start-date', date('m/d/Y', strtotime('-10 year')))
2386
+		);
2387
+		$end_date = wp_strip_all_tags(
2388
+			$this->request->getRequestParam('txn-filter-end-date', date('m/d/Y'))
2389
+		);
2390
+
2391
+		// make sure our timestamps start and end right at the boundaries for each day
2392
+		$start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
2393
+		$end_date   = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
2394
+
2395
+
2396
+		// convert to timestamps
2397
+		$start_date = strtotime($start_date);
2398
+		$end_date   = strtotime($end_date);
2399
+
2400
+		// makes sure start date is the lowest value and vice versa
2401
+		$start_date = min($start_date, $end_date);
2402
+		$end_date   = max($start_date, $end_date);
2403
+
2404
+		// convert to correct format for query
2405
+		$start_date = EEM_Transaction::instance()->convert_datetime_for_query(
2406
+			'TXN_timestamp',
2407
+			date('Y-m-d H:i:s', $start_date),
2408
+			'Y-m-d H:i:s'
2409
+		);
2410
+		$end_date   = EEM_Transaction::instance()->convert_datetime_for_query(
2411
+			'TXN_timestamp',
2412
+			date('Y-m-d H:i:s', $end_date),
2413
+			'Y-m-d H:i:s'
2414
+		);
2415
+
2416
+
2417
+		// set orderby
2418
+		$orderby = $this->request->getRequestParam('orderby');
2419
+
2420
+		switch ($orderby) {
2421
+			case 'TXN_ID':
2422
+				break;
2423
+			case 'ATT_fname':
2424
+				$orderby = 'Registration.Attendee.ATT_fname';
2425
+				break;
2426
+			case 'event_name':
2427
+				$orderby = 'Registration.Event.EVT_name';
2428
+				break;
2429
+			default: // 'TXN_timestamp'
2430
+				$orderby = 'TXN_timestamp';
2431
+		}
2432
+
2433
+		$sort         = $this->request->getRequestParam('order', 'DESC');
2434
+		$current_page = $this->request->getRequestParam('paged', 1, 'int');
2435
+
2436
+		$per_page = absint($per_page) ? $per_page : 10;
2437
+		$per_page = $this->request->getRequestParam('perpage', $per_page, 'int');
2438
+
2439
+		$offset = ($current_page - 1) * $per_page;
2440
+		$limit  = [$offset, $per_page];
2441
+
2442
+		$_where = [
2443
+			'TXN_timestamp'          => ['BETWEEN', [$start_date, $end_date]],
2444
+			'Registration.REG_count' => 1,
2445
+		];
2446
+
2447
+		$EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
2448
+		if ($EVT_ID) {
2449
+			$_where['Registration.EVT_ID'] = $EVT_ID;
2450
+		}
2451
+
2452
+		$search_term = $this->request->getRequestParam('s');
2453
+		if ($search_term) {
2454
+			$search_term = '%' . $search_term . '%';
2455
+			$_where['OR']  = [
2456
+				'Registration.Event.EVT_name'         => ['LIKE', $search_term],
2457
+				'Registration.Event.EVT_desc'         => ['LIKE', $search_term],
2458
+				'Registration.Event.EVT_short_desc'   => ['LIKE', $search_term],
2459
+				'Registration.Attendee.ATT_full_name' => ['LIKE', $search_term],
2460
+				'Registration.Attendee.ATT_fname'     => ['LIKE', $search_term],
2461
+				'Registration.Attendee.ATT_lname'     => ['LIKE', $search_term],
2462
+				'Registration.Attendee.ATT_short_bio' => ['LIKE', $search_term],
2463
+				'Registration.Attendee.ATT_email'     => ['LIKE', $search_term],
2464
+				'Registration.Attendee.ATT_address'   => ['LIKE', $search_term],
2465
+				'Registration.Attendee.ATT_address2'  => ['LIKE', $search_term],
2466
+				'Registration.Attendee.ATT_city'      => ['LIKE', $search_term],
2467
+				'Registration.REG_final_price'        => ['LIKE', $search_term],
2468
+				'Registration.REG_code'               => ['LIKE', $search_term],
2469
+				'Registration.REG_count'              => ['LIKE', $search_term],
2470
+				'Registration.REG_group_size'         => ['LIKE', $search_term],
2471
+				'Registration.Ticket.TKT_name'        => ['LIKE', $search_term],
2472
+				'Registration.Ticket.TKT_description' => ['LIKE', $search_term],
2473
+				'Payment.PAY_source'                  => ['LIKE', $search_term],
2474
+				'Payment.Payment_Method.PMD_name'     => ['LIKE', $search_term],
2475
+				'TXN_session_data'                    => ['LIKE', $search_term],
2476
+				'Payment.PAY_txn_id_chq_nmbr'         => ['LIKE', $search_term],
2477
+			];
2478
+		}
2479
+
2480
+		$status = $this->request->getRequestParam('status');
2481
+		// failed transactions
2482
+		$failed     = (! empty($status) && $status === 'failed' && ! $count) || ($count && $view === 'failed');
2483
+		$abandoned  = (! empty($status) && $status === 'abandoned' && ! $count) || ($count && $view === 'abandoned');
2484
+		$incomplete = (! empty($status) && $status === 'incomplete' && ! $count) || ($count && $view === 'incomplete');
2485
+
2486
+		if ($failed) {
2487
+			$_where['STS_ID'] = EEM_Transaction::failed_status_code;
2488
+		} elseif ($abandoned) {
2489
+			$_where['STS_ID'] = EEM_Transaction::abandoned_status_code;
2490
+		} elseif ($incomplete) {
2491
+			$_where['STS_ID'] = EEM_Transaction::incomplete_status_code;
2492
+		} else {
2493
+			$_where['STS_ID']  = ['!=', EEM_Transaction::failed_status_code];
2494
+			$_where['STS_ID*'] = ['!=', EEM_Transaction::abandoned_status_code];
2495
+		}
2496
+
2497
+		$query_params = apply_filters(
2498
+			'FHEE__Transactions_Admin_Page___get_transactions_query_params',
2499
+			[
2500
+				$_where,
2501
+				'order_by'                 => [$orderby => $sort],
2502
+				'limit'                    => $limit,
2503
+				'default_where_conditions' => EEM_Base::default_where_conditions_this_only,
2504
+			],
2505
+			$this->request->requestParams(),
2506
+			$view,
2507
+			$count
2508
+		);
2509
+
2510
+		return $count
2511
+			? EEM_Transaction::instance()->count([$query_params[0]], 'TXN_ID', true)
2512
+			: EEM_Transaction::instance()->get_all($query_params);
2513
+	}
2514
+
2515
+
2516
+	/**
2517
+	 * @throws EE_Error
2518
+	 * @throws InvalidArgumentException
2519
+	 * @throws InvalidDataTypeException
2520
+	 * @throws InvalidInterfaceException
2521
+	 * @throws ReflectionException
2522
+	 * @throws RuntimeException
2523
+	 * @since 4.9.79.p
2524
+	 */
2525
+	public function recalculateLineItems()
2526
+	{
2527
+		$TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
2528
+		/** @var EE_Transaction $transaction */
2529
+		$transaction     = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2530
+		$success         = $transaction->recalculateLineItems();
2531
+		$redirect_to = $this->request->getRequestParam('redirect_to');
2532
+		$query_args = $redirect_to ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID,] : [];
2533
+		$this->_redirect_after_action(
2534
+			$success,
2535
+			esc_html__('Transaction taxes and totals', 'event_espresso'),
2536
+			esc_html__('recalculated', 'event_espresso'),
2537
+			$query_args,
2538
+			true
2539
+		);
2540
+	}
2541 2541
 }
Please login to merge, or discard this patch.
Spacing   +101 added lines, -101 removed lines patch added patch discarded remove patch
@@ -250,7 +250,7 @@  discard block
 block discarded – undo
250 250
             'An error occurred! Your request may have been processed, but a valid response from the server was not received. Please refresh the page and try again.',
251 251
             'event_espresso'
252 252
         );
253
-        EE_Registry::$i18n_js_strings['error_occurred']          = esc_html__(
253
+        EE_Registry::$i18n_js_strings['error_occurred'] = esc_html__(
254 254
             'An error occurred! Please refresh the page and try again.',
255 255
             'event_espresso'
256 256
         );
@@ -349,7 +349,7 @@  discard block
 block discarded – undo
349 349
         // enqueue style
350 350
         wp_register_style(
351 351
             'espresso_txn',
352
-            TXN_ASSETS_URL . 'espresso_transactions_admin.css',
352
+            TXN_ASSETS_URL.'espresso_transactions_admin.css',
353 353
             [],
354 354
             EVENT_ESPRESSO_VERSION
355 355
         );
@@ -357,7 +357,7 @@  discard block
 block discarded – undo
357 357
         // scripts
358 358
         wp_register_script(
359 359
             'espresso_txn',
360
-            TXN_ASSETS_URL . 'espresso_transactions_admin.js',
360
+            TXN_ASSETS_URL.'espresso_transactions_admin.js',
361 361
             [
362 362
                 'ee_admin_js',
363 363
                 'ee-datepicker',
@@ -484,7 +484,7 @@  discard block
 block discarded – undo
484 484
             $this->_transaction->verify_abandoned_transaction_status();
485 485
         }
486 486
 
487
-        if (! $this->_transaction instanceof EE_Transaction) {
487
+        if ( ! $this->_transaction instanceof EE_Transaction) {
488 488
             $error_msg = sprintf(
489 489
                 esc_html__(
490 490
                     'An error occurred and the details for the transaction with the ID # %d could not be retrieved.',
@@ -581,7 +581,7 @@  discard block
 block discarded – undo
581 581
             'FHEE__Transactions_Admin_Page___transaction_legend_items__more_items',
582 582
             [
583 583
                 'overpaid'   => [
584
-                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::overpaid_status_code,
584
+                    'class' => 'ee-status-legend ee-status-legend-'.EEM_Transaction::overpaid_status_code,
585 585
                     'desc'  => EEH_Template::pretty_status(
586 586
                         EEM_Transaction::overpaid_status_code,
587 587
                         false,
@@ -589,7 +589,7 @@  discard block
 block discarded – undo
589 589
                     ),
590 590
                 ],
591 591
                 'complete'   => [
592
-                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::complete_status_code,
592
+                    'class' => 'ee-status-legend ee-status-legend-'.EEM_Transaction::complete_status_code,
593 593
                     'desc'  => EEH_Template::pretty_status(
594 594
                         EEM_Transaction::complete_status_code,
595 595
                         false,
@@ -597,7 +597,7 @@  discard block
 block discarded – undo
597 597
                     ),
598 598
                 ],
599 599
                 'incomplete' => [
600
-                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::incomplete_status_code,
600
+                    'class' => 'ee-status-legend ee-status-legend-'.EEM_Transaction::incomplete_status_code,
601 601
                     'desc'  => EEH_Template::pretty_status(
602 602
                         EEM_Transaction::incomplete_status_code,
603 603
                         false,
@@ -605,7 +605,7 @@  discard block
 block discarded – undo
605 605
                     ),
606 606
                 ],
607 607
                 'abandoned'  => [
608
-                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::abandoned_status_code,
608
+                    'class' => 'ee-status-legend ee-status-legend-'.EEM_Transaction::abandoned_status_code,
609 609
                     'desc'  => EEH_Template::pretty_status(
610 610
                         EEM_Transaction::abandoned_status_code,
611 611
                         false,
@@ -613,7 +613,7 @@  discard block
 block discarded – undo
613 613
                     ),
614 614
                 ],
615 615
                 'failed'     => [
616
-                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::failed_status_code,
616
+                    'class' => 'ee-status-legend ee-status-legend-'.EEM_Transaction::failed_status_code,
617 617
                     'desc'  => EEH_Template::pretty_status(
618 618
                         EEM_Transaction::failed_status_code,
619 619
                         false,
@@ -656,11 +656,11 @@  discard block
 block discarded – undo
656 656
                 )
657 657
                 . '" title="'
658 658
                 . esc_attr__('Click to Edit event', 'event_espresso')
659
-                . '">' . $event->name() . '</a>',
659
+                . '">'.$event->name().'</a>',
660 660
                 '</h3>'
661 661
             )
662 662
             : '';
663
-        $this->_template_args['after_list_table']  = $this->_display_legend($this->_transaction_legend_items());
663
+        $this->_template_args['after_list_table'] = $this->_display_legend($this->_transaction_legend_items());
664 664
         $this->display_admin_list_table_page_with_no_sidebar();
665 665
     }
666 666
 
@@ -690,7 +690,7 @@  discard block
 block discarded – undo
690 690
 
691 691
         $this->_set_transaction_object();
692 692
 
693
-        if (! $this->_transaction instanceof EE_Transaction) {
693
+        if ( ! $this->_transaction instanceof EE_Transaction) {
694 694
             return;
695 695
         }
696 696
 
@@ -700,9 +700,9 @@  discard block
 block discarded – undo
700 700
         $this->_template_args['txn_datetime']['value'] = $this->_transaction->get_i18n_datetime('TXN_timestamp');
701 701
         $this->_template_args['txn_datetime']['label'] = esc_html__('Date', 'event_espresso');
702 702
 
703
-        $this->_template_args['txn_status']['value'] = self::$_txn_status[ $this->_transaction->status_ID() ];
703
+        $this->_template_args['txn_status']['value'] = self::$_txn_status[$this->_transaction->status_ID()];
704 704
         $this->_template_args['txn_status']['label'] = esc_html__('Transaction Status', 'event_espresso');
705
-        $this->_template_args['txn_status']['class'] = 'status-' . $this->_transaction->status_ID();
705
+        $this->_template_args['txn_status']['class'] = 'status-'.$this->_transaction->status_ID();
706 706
 
707 707
         $this->_template_args['grand_total'] = $this->_transaction->total();
708 708
         $this->_template_args['total_paid']  = $this->_transaction->paid();
@@ -754,7 +754,7 @@  discard block
 block discarded – undo
754 754
 
755 755
 
756 756
         // next link
757
-        $next_txn                                 = $this->_transaction->next(
757
+        $next_txn = $this->_transaction->next(
758 758
             null,
759 759
             [['STS_ID' => ['!=', EEM_Transaction::failed_status_code]]],
760 760
             'TXN_ID'
@@ -769,7 +769,7 @@  discard block
 block discarded – undo
769 769
             )
770 770
             : '';
771 771
         // previous link
772
-        $previous_txn                                 = $this->_transaction->previous(
772
+        $previous_txn = $this->_transaction->previous(
773 773
             null,
774 774
             [['STS_ID' => ['!=', EEM_Transaction::failed_status_code]]],
775 775
             'TXN_ID'
@@ -821,7 +821,7 @@  discard block
 block discarded – undo
821 821
         // grab messages at the last second
822 822
         $this->_template_args['notices'] = EE_Error::get_notices();
823 823
         // path to template
824
-        $template_path                             = TXN_TEMPLATE_PATH . 'txn_admin_details_header.template.php';
824
+        $template_path                             = TXN_TEMPLATE_PATH.'txn_admin_details_header.template.php';
825 825
         $this->_template_args['admin_page_header'] = EEH_Template::display_template(
826 826
             $template_path,
827 827
             $this->_template_args,
@@ -850,7 +850,7 @@  discard block
 block discarded – undo
850 850
 
851 851
         $this->_set_transaction_object();
852 852
 
853
-        if (! $this->_transaction instanceof EE_Transaction) {
853
+        if ( ! $this->_transaction instanceof EE_Transaction) {
854 854
             return;
855 855
         }
856 856
         add_meta_box(
@@ -906,7 +906,7 @@  discard block
 block discarded – undo
906 906
     {
907 907
         $content = '';
908 908
         $actions = [];
909
-        if (! $transaction instanceof EE_Transaction) {
909
+        if ( ! $transaction instanceof EE_Transaction) {
910 910
             return $content;
911 911
         }
912 912
         /** @var EE_Registration $primary_registration */
@@ -991,7 +991,7 @@  discard block
 block discarded – undo
991 991
         );
992 992
         if ($actions) {
993 993
             $content = '<ul>';
994
-            $content .= '<li>' . implode('</li><li>', $actions) . '</li>';
994
+            $content .= '<li>'.implode('</li><li>', $actions).'</li>';
995 995
             $content .= '</uL>';
996 996
         }
997 997
         return $content;
@@ -1019,7 +1019,7 @@  discard block
 block discarded – undo
1019 1019
             $this->_transaction->primary_registration() instanceof EE_Registration
1020 1020
                 ? $this->_transaction->primary_registration()->attendee()
1021 1021
                 : null;
1022
-        $this->_template_args['can_edit_payments']   = EE_Registry::instance()->CAP->current_user_can(
1022
+        $this->_template_args['can_edit_payments'] = EE_Registry::instance()->CAP->current_user_can(
1023 1023
             'ee_edit_payments',
1024 1024
             'apply_payment_or_refund_from_registration_details'
1025 1025
         );
@@ -1030,7 +1030,7 @@  discard block
 block discarded – undo
1030 1030
 
1031 1031
         // get line table
1032 1032
         EEH_Autoloader::register_line_item_display_autoloaders();
1033
-        $Line_Item_Display                       = new EE_Line_Item_Display(
1033
+        $Line_Item_Display = new EE_Line_Item_Display(
1034 1034
             'admin_table',
1035 1035
             'EE_Admin_Table_Line_Item_Display_Strategy'
1036 1036
         );
@@ -1045,7 +1045,7 @@  discard block
 block discarded – undo
1045 1045
         $taxes                         = $this->_transaction->line_items([['LIN_type' => EEM_Line_Item::type_tax]]);
1046 1046
         $this->_template_args['taxes'] = ! empty($taxes) ? $taxes : false;
1047 1047
 
1048
-        $this->_template_args['grand_total']     = EEH_Template::format_currency(
1048
+        $this->_template_args['grand_total'] = EEH_Template::format_currency(
1049 1049
             $this->_transaction->total(),
1050 1050
             false,
1051 1051
             false
@@ -1055,7 +1055,7 @@  discard block
 block discarded – undo
1055 1055
 
1056 1056
         // process payment details
1057 1057
         $payments = $this->_transaction->payments();
1058
-        if (! empty($payments)) {
1058
+        if ( ! empty($payments)) {
1059 1059
             $this->_template_args['payments']              = $payments;
1060 1060
             $this->_template_args['existing_reg_payments'] = $this->_get_registration_payment_IDs($payments);
1061 1061
         } else {
@@ -1117,7 +1117,7 @@  discard block
 block discarded – undo
1117 1117
                                   esc_html__('%1$s : Initiated %2$s', 'event_espresso'),
1118 1118
                                   ucwords(str_replace('_', ' ', $reg_step)),
1119 1119
                                   date(
1120
-                                      get_option('date_format') . ' ' . get_option('time_format'),
1120
+                                      get_option('date_format').' '.get_option('time_format'),
1121 1121
                                       $reg_step_status + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1122 1122
                                   )
1123 1123
                               )
@@ -1131,7 +1131,7 @@  discard block
 block discarded – undo
1131 1131
                               . '</li>';
1132 1132
             }
1133 1133
         }
1134
-        $reg_steps                                                 .= '</ul>';
1134
+        $reg_steps .= '</ul>';
1135 1135
         $this->_template_args['txn_details']['reg_steps']['value'] = $reg_steps;
1136 1136
         $this->_template_args['txn_details']['reg_steps']['label'] = esc_html__(
1137 1137
             'Registration Step Progress',
@@ -1144,14 +1144,14 @@  discard block
 block discarded – undo
1144 1144
         $this->_get_payment_status_array();
1145 1145
         $this->_get_reg_status_selection(); // sets up the template args for the reg status array for the transaction.
1146 1146
 
1147
-        $this->_template_args['transaction_form_url']    = add_query_arg(
1147
+        $this->_template_args['transaction_form_url'] = add_query_arg(
1148 1148
             [
1149 1149
                 'action'  => 'edit_transaction',
1150 1150
                 'process' => 'transaction',
1151 1151
             ],
1152 1152
             TXN_ADMIN_URL
1153 1153
         );
1154
-        $this->_template_args['apply_payment_form_url']  = add_query_arg(
1154
+        $this->_template_args['apply_payment_form_url'] = add_query_arg(
1155 1155
             [
1156 1156
                 'page'   => 'espresso_transactions',
1157 1157
                 'action' => 'espresso_apply_payment',
@@ -1170,7 +1170,7 @@  discard block
 block discarded – undo
1170 1170
 
1171 1171
         // 'espresso_delete_payment_nonce'
1172 1172
 
1173
-        $template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_txn_details.template.php';
1173
+        $template_path = TXN_TEMPLATE_PATH.'txn_admin_details_main_meta_box_txn_details.template.php';
1174 1174
         echo EEH_Template::display_template($template_path, $this->_template_args, true);
1175 1175
     }
1176 1176
 
@@ -1202,19 +1202,19 @@  discard block
 block discarded – undo
1202 1202
                 ],
1203 1203
             ]
1204 1204
         );
1205
-        if (! empty($reg_payments)) {
1205
+        if ( ! empty($reg_payments)) {
1206 1206
             foreach ($payments as $payment) {
1207
-                if (! $payment instanceof EE_Payment) {
1207
+                if ( ! $payment instanceof EE_Payment) {
1208 1208
                     continue;
1209
-                } elseif (! isset($existing_reg_payments[ $payment->ID() ])) {
1210
-                    $existing_reg_payments[ $payment->ID() ] = [];
1209
+                } elseif ( ! isset($existing_reg_payments[$payment->ID()])) {
1210
+                    $existing_reg_payments[$payment->ID()] = [];
1211 1211
                 }
1212 1212
                 foreach ($reg_payments as $reg_payment) {
1213 1213
                     if (
1214 1214
                         $reg_payment instanceof EE_Registration_Payment
1215 1215
                         && $reg_payment->payment_ID() === $payment->ID()
1216 1216
                     ) {
1217
-                        $existing_reg_payments[ $payment->ID() ][] = $reg_payment->registration_ID();
1217
+                        $existing_reg_payments[$payment->ID()][] = $reg_payment->registration_ID();
1218 1218
                     }
1219 1219
                 }
1220 1220
             }
@@ -1240,7 +1240,7 @@  discard block
 block discarded – undo
1240 1240
     protected function _get_registrations_to_apply_payment_to()
1241 1241
     {
1242 1242
         // we want any registration with an active status (ie: not deleted or cancelled)
1243
-        $query_params                      = [
1243
+        $query_params = [
1244 1244
             [
1245 1245
                 'STS_ID' => [
1246 1246
                     'IN',
@@ -1252,22 +1252,22 @@  discard block
 block discarded – undo
1252 1252
                 ],
1253 1253
             ],
1254 1254
         ];
1255
-        $registrations_to_apply_payment_to = EEH_HTML::br() . EEH_HTML::div(
1255
+        $registrations_to_apply_payment_to = EEH_HTML::br().EEH_HTML::div(
1256 1256
             '',
1257 1257
             'txn-admin-apply-payment-to-registrations-dv',
1258 1258
             '',
1259 1259
             'clear: both; margin: 1.5em 0 0; display: none;'
1260 1260
         );
1261
-        $registrations_to_apply_payment_to .= EEH_HTML::br() . EEH_HTML::div('', '', 'admin-primary-mbox-tbl-wrap');
1261
+        $registrations_to_apply_payment_to .= EEH_HTML::br().EEH_HTML::div('', '', 'admin-primary-mbox-tbl-wrap');
1262 1262
         $registrations_to_apply_payment_to .= EEH_HTML::table('', '', 'admin-primary-mbox-tbl');
1263 1263
         $registrations_to_apply_payment_to .= EEH_HTML::thead(
1264 1264
             EEH_HTML::tr(
1265
-                EEH_HTML::th(esc_html__('ID', 'event_espresso')) .
1266
-                EEH_HTML::th(esc_html__('Registrant', 'event_espresso')) .
1267
-                EEH_HTML::th(esc_html__('Ticket', 'event_espresso')) .
1268
-                EEH_HTML::th(esc_html__('Event', 'event_espresso')) .
1269
-                EEH_HTML::th(esc_html__('Paid', 'event_espresso'), '', 'txn-admin-payment-paid-td jst-cntr') .
1270
-                EEH_HTML::th(esc_html__('Owing', 'event_espresso'), '', 'txn-admin-payment-owing-td jst-cntr') .
1265
+                EEH_HTML::th(esc_html__('ID', 'event_espresso')).
1266
+                EEH_HTML::th(esc_html__('Registrant', 'event_espresso')).
1267
+                EEH_HTML::th(esc_html__('Ticket', 'event_espresso')).
1268
+                EEH_HTML::th(esc_html__('Event', 'event_espresso')).
1269
+                EEH_HTML::th(esc_html__('Paid', 'event_espresso'), '', 'txn-admin-payment-paid-td jst-cntr').
1270
+                EEH_HTML::th(esc_html__('Owing', 'event_espresso'), '', 'txn-admin-payment-owing-td jst-cntr').
1271 1271
                 EEH_HTML::th(esc_html__('Apply', 'event_espresso'), '', 'jst-cntr')
1272 1272
             )
1273 1273
         );
@@ -1282,34 +1282,34 @@  discard block
 block discarded – undo
1282 1282
                     : esc_html__('Unknown Attendee', 'event_espresso');
1283 1283
                 $owing                             = $registration->final_price() - $registration->paid();
1284 1284
                 $taxable                           = $registration->ticket()->taxable()
1285
-                    ? ' <span class="smaller-text lt-grey-text"> ' . esc_html__('+ tax', 'event_espresso') . '</span>'
1285
+                    ? ' <span class="smaller-text lt-grey-text"> '.esc_html__('+ tax', 'event_espresso').'</span>'
1286 1286
                     : '';
1287 1287
                 $checked                           = empty($existing_reg_payments)
1288 1288
                                                      || in_array($registration->ID(), $existing_reg_payments, true)
1289 1289
                     ? ' checked="checked"'
1290 1290
                     : '';
1291
-                $disabled                          = $registration->final_price() > 0 ? '' : ' disabled';
1291
+                $disabled = $registration->final_price() > 0 ? '' : ' disabled';
1292 1292
                 $registrations_to_apply_payment_to .= EEH_HTML::tr(
1293
-                    EEH_HTML::td($registration->ID()) .
1294
-                    EEH_HTML::td($attendee_name) .
1293
+                    EEH_HTML::td($registration->ID()).
1294
+                    EEH_HTML::td($attendee_name).
1295 1295
                     EEH_HTML::td(
1296
-                        $registration->ticket()->name() . ' : ' . $registration->ticket()->pretty_price() . $taxable
1297
-                    ) .
1298
-                    EEH_HTML::td($registration->event_name()) .
1299
-                    EEH_HTML::td($registration->pretty_paid(), '', 'txn-admin-payment-paid-td jst-cntr') .
1296
+                        $registration->ticket()->name().' : '.$registration->ticket()->pretty_price().$taxable
1297
+                    ).
1298
+                    EEH_HTML::td($registration->event_name()).
1299
+                    EEH_HTML::td($registration->pretty_paid(), '', 'txn-admin-payment-paid-td jst-cntr').
1300 1300
                     EEH_HTML::td(
1301 1301
                         EEH_Template::format_currency($owing),
1302 1302
                         '',
1303 1303
                         'txn-admin-payment-owing-td jst-cntr'
1304
-                    ) .
1304
+                    ).
1305 1305
                     EEH_HTML::td(
1306
-                        '<input type="checkbox" value="' . $registration->ID()
1306
+                        '<input type="checkbox" value="'.$registration->ID()
1307 1307
                         . '" name="txn_admin_payment[registrations]"'
1308
-                        . $checked . $disabled . '>',
1308
+                        . $checked.$disabled.'>',
1309 1309
                         '',
1310 1310
                         'jst-cntr'
1311 1311
                     ),
1312
-                    'apply-payment-registration-row-' . $registration->ID()
1312
+                    'apply-payment-registration-row-'.$registration->ID()
1313 1313
                 );
1314 1314
             }
1315 1315
         }
@@ -1324,7 +1324,7 @@  discard block
 block discarded – undo
1324 1324
             '',
1325 1325
             'clear description'
1326 1326
         );
1327
-        $registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1327
+        $registrations_to_apply_payment_to .= EEH_HTML::divx();
1328 1328
         $this->_template_args['registrations_to_apply_payment_to'] = $registrations_to_apply_payment_to;
1329 1329
     }
1330 1330
 
@@ -1390,12 +1390,12 @@  discard block
 block discarded – undo
1390 1390
                 [
1391 1391
                     'OR*payment_method_for_payment' => [
1392 1392
                         'PMD_ID'    => ['IN', $payment_methods_of_payments],
1393
-                        'PMD_scope' => ['LIKE', '%' . EEM_Payment_Method::scope_admin . '%'],
1393
+                        'PMD_scope' => ['LIKE', '%'.EEM_Payment_Method::scope_admin.'%'],
1394 1394
                     ],
1395 1395
                 ],
1396 1396
             ];
1397 1397
         } else {
1398
-            $query_args = [['PMD_scope' => ['LIKE', '%' . EEM_Payment_Method::scope_admin . '%']]];
1398
+            $query_args = [['PMD_scope' => ['LIKE', '%'.EEM_Payment_Method::scope_admin.'%']]];
1399 1399
         }
1400 1400
         $this->_template_args['payment_methods'] = EEM_Payment_Method::instance()->get_all($query_args);
1401 1401
     }
@@ -1428,7 +1428,7 @@  discard block
 block discarded – undo
1428 1428
             'Line_Item',
1429 1429
             [['LIN_type' => 'line-item']]
1430 1430
         );
1431
-        if (! empty($line_items)) {
1431
+        if ( ! empty($line_items)) {
1432 1432
             foreach ($line_items as $item) {
1433 1433
                 if ($item instanceof EE_Line_Item) {
1434 1434
                     switch ($item->OBJ_type()) {
@@ -1438,7 +1438,7 @@  discard block
 block discarded – undo
1438 1438
                             $ticket = $item->ticket();
1439 1439
                             // right now we're only handling tickets here.
1440 1440
                             // Cause its expected that only tickets will have attendees right?
1441
-                            if (! $ticket instanceof EE_Ticket) {
1441
+                            if ( ! $ticket instanceof EE_Ticket) {
1442 1442
                                 break;
1443 1443
                             }
1444 1444
                             try {
@@ -1447,45 +1447,45 @@  discard block
 block discarded – undo
1447 1447
                                 EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1448 1448
                                 $event_name = esc_html__('Unknown Event', 'event_espresso');
1449 1449
                             }
1450
-                            $event_name   .= ' - ' . $item->name();
1450
+                            $event_name   .= ' - '.$item->name();
1451 1451
                             $ticket_price = EEH_Template::format_currency($item->unit_price());
1452 1452
                             // now get all of the registrations for this transaction that use this ticket
1453 1453
                             $registrations = $ticket->registrations(
1454 1454
                                 [['TXN_ID' => $this->_transaction->ID()]]
1455 1455
                             );
1456 1456
                             foreach ($registrations as $registration) {
1457
-                                if (! $registration instanceof EE_Registration) {
1457
+                                if ( ! $registration instanceof EE_Registration) {
1458 1458
                                     break;
1459 1459
                                 }
1460
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['STS_ID']
1460
+                                $this->_template_args['event_attendees'][$registration->ID()]['STS_ID']
1461 1461
                                     = $registration->status_ID();
1462
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['att_num']
1462
+                                $this->_template_args['event_attendees'][$registration->ID()]['att_num']
1463 1463
                                     = $registration->count();
1464
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['event_ticket_name']
1464
+                                $this->_template_args['event_attendees'][$registration->ID()]['event_ticket_name']
1465 1465
                                     = $event_name;
1466
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['ticket_price']
1466
+                                $this->_template_args['event_attendees'][$registration->ID()]['ticket_price']
1467 1467
                                     = $ticket_price;
1468 1468
                                 // attendee info
1469 1469
                                 $attendee = $registration->get_first_related('Attendee');
1470 1470
                                 if ($attendee instanceof EE_Attendee) {
1471
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['att_id']
1471
+                                    $this->_template_args['event_attendees'][$registration->ID()]['att_id']
1472 1472
                                         = $attendee->ID();
1473
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['attendee']
1473
+                                    $this->_template_args['event_attendees'][$registration->ID()]['attendee']
1474 1474
                                         = $attendee->full_name();
1475
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['email']
1476
-                                        = '<a href="mailto:' . $attendee->email() . '?subject=' . $event_name
1475
+                                    $this->_template_args['event_attendees'][$registration->ID()]['email']
1476
+                                        = '<a href="mailto:'.$attendee->email().'?subject='.$event_name
1477 1477
                                           . esc_html__(
1478 1478
                                               ' Event',
1479 1479
                                               'event_espresso'
1480 1480
                                           )
1481
-                                          . '">' . $attendee->email() . '</a>';
1482
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['address']
1481
+                                          . '">'.$attendee->email().'</a>';
1482
+                                    $this->_template_args['event_attendees'][$registration->ID()]['address']
1483 1483
                                         = EEH_Address::format($attendee, 'inline', false, false);
1484 1484
                                 } else {
1485
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['att_id']   = '';
1486
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['attendee'] = '';
1487
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['email']    = '';
1488
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['address']  = '';
1485
+                                    $this->_template_args['event_attendees'][$registration->ID()]['att_id']   = '';
1486
+                                    $this->_template_args['event_attendees'][$registration->ID()]['attendee'] = '';
1487
+                                    $this->_template_args['event_attendees'][$registration->ID()]['email']    = '';
1488
+                                    $this->_template_args['event_attendees'][$registration->ID()]['address']  = '';
1489 1489
                                 }
1490 1490
                             }
1491 1491
                             break;
@@ -1501,7 +1501,7 @@  discard block
 block discarded – undo
1501 1501
                 TXN_ADMIN_URL
1502 1502
             );
1503 1503
             echo EEH_Template::display_template(
1504
-                TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_attendees.template.php',
1504
+                TXN_TEMPLATE_PATH.'txn_admin_details_main_meta_box_attendees.template.php',
1505 1505
                 $this->_template_args,
1506 1506
                 true
1507 1507
             );
@@ -1536,7 +1536,7 @@  discard block
 block discarded – undo
1536 1536
         $primary_att = $this->_transaction->primary_registration() instanceof EE_Registration
1537 1537
             ? $this->_transaction->primary_registration()->get_first_related('Attendee')
1538 1538
             : null;
1539
-        if (! $primary_att instanceof EE_Attendee) {
1539
+        if ( ! $primary_att instanceof EE_Attendee) {
1540 1540
             $this->_template_args['no_attendee_message'] = esc_html__(
1541 1541
                 'There is no attached contact for this transaction.  The transaction either failed due to an error or was abandoned.',
1542 1542
                 'event_espresso'
@@ -1558,7 +1558,7 @@  discard block
 block discarded – undo
1558 1558
         // get formatted address for registrant
1559 1559
         $this->_template_args['formatted_address'] = EEH_Address::format($primary_att);
1560 1560
         echo EEH_Template::display_template(
1561
-            TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_registrant.template.php',
1561
+            TXN_TEMPLATE_PATH.'txn_admin_details_side_meta_box_registrant.template.php',
1562 1562
             $this->_template_args,
1563 1563
             true
1564 1564
         );
@@ -1584,7 +1584,7 @@  discard block
 block discarded – undo
1584 1584
             TXN_ADMIN_URL
1585 1585
         );
1586 1586
 
1587
-        $template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_billing_info.template.php';
1587
+        $template_path = TXN_TEMPLATE_PATH.'txn_admin_details_side_meta_box_billing_info.template.php';
1588 1588
         echo EEH_Template::display_template($template_path, $this->_template_args, true);
1589 1589
     }
1590 1590
 
@@ -1610,7 +1610,7 @@  discard block
 block discarded – undo
1610 1610
             'ee_edit_payments',
1611 1611
             'apply_payment_or_refund_from_registration_details'
1612 1612
         );
1613
-        if (! empty($valid_data) && $has_access) {
1613
+        if ( ! empty($valid_data) && $has_access) {
1614 1614
             $PAY_ID = $valid_data['PAY_ID'];
1615 1615
             // save  the new payment
1616 1616
             $payment = $this->_create_payment_from_request_data($valid_data);
@@ -1623,7 +1623,7 @@  discard block
 block discarded – undo
1623 1623
                 $REG_IDs = $this->_get_REG_IDs_to_apply_payment_to($payment);
1624 1624
                 $this->_remove_existing_registration_payments($payment, $PAY_ID);
1625 1625
                 // apply payment to registrations (if applicable)
1626
-                if (! empty($REG_IDs)) {
1626
+                if ( ! empty($REG_IDs)) {
1627 1627
                     $this->_update_registration_payments($transaction, $payment, $REG_IDs);
1628 1628
                     $this->_maybe_send_notifications();
1629 1629
                     // now process status changes for the same registrations
@@ -1669,7 +1669,7 @@  discard block
 block discarded – undo
1669 1669
                 __LINE__
1670 1670
             );
1671 1671
         }
1672
-        $notices              = EE_Error::get_notices(
1672
+        $notices = EE_Error::get_notices(
1673 1673
             false,
1674 1674
             false,
1675 1675
             false
@@ -1694,14 +1694,14 @@  discard block
 block discarded – undo
1694 1694
      */
1695 1695
     protected function _validate_payment_request_data()
1696 1696
     {
1697
-        if (! $this->request->requestParamIsSet('txn_admin_payment')) {
1697
+        if ( ! $this->request->requestParamIsSet('txn_admin_payment')) {
1698 1698
             return [];
1699 1699
         }
1700 1700
         $payment_form = $this->_generate_payment_form_section();
1701 1701
         try {
1702 1702
             if ($payment_form->was_submitted()) {
1703 1703
                 $payment_form->receive_form_submission();
1704
-                if (! $payment_form->is_valid()) {
1704
+                if ( ! $payment_form->is_valid()) {
1705 1705
                     $submission_error_messages = [];
1706 1706
                     foreach ($payment_form->get_validation_errors_accumulated() as $validation_error) {
1707 1707
                         if ($validation_error instanceof EE_Validation_Error) {
@@ -1883,7 +1883,7 @@  discard block
 block discarded – undo
1883 1883
             ['Y-m-d', 'g:i a']
1884 1884
         );
1885 1885
 
1886
-        if (! $payment->save()) {
1886
+        if ( ! $payment->save()) {
1887 1887
             EE_Error::add_error(
1888 1888
                 sprintf(
1889 1889
                     esc_html__('Payment %1$d has not been successfully saved to the database.', 'event_espresso'),
@@ -2085,12 +2085,12 @@  discard block
 block discarded – undo
2085 2085
         // but add in some conditions regarding payment,
2086 2086
         // so that we don't apply payments to registrations that are free or have already been paid for
2087 2087
         // but ONLY if the payment is NOT a refund ( ie: the payment amount is not negative )
2088
-        if (! $payment->is_a_refund()) {
2088
+        if ( ! $payment->is_a_refund()) {
2089 2089
             $registration_query_where_params['REG_final_price']  = ['!=', 0];
2090 2090
             $registration_query_where_params['REG_final_price*'] = ['!=', 'REG_paid', true];
2091 2091
         }
2092 2092
         $registrations = $transaction->registrations([$registration_query_where_params]);
2093
-        if (! empty($registrations)) {
2093
+        if ( ! empty($registrations)) {
2094 2094
             /** @type EE_Payment_Processor $payment_processor */
2095 2095
             $payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
2096 2096
             $payment_processor->process_registration_payments($transaction, $payment, $registrations);
@@ -2172,7 +2172,7 @@  discard block
 block discarded – undo
2172 2172
             'pay_status'       => $payment->STS_ID(),
2173 2173
             'PAY_ID'           => $payment->ID(),
2174 2174
             'STS_ID'           => $payment->STS_ID(),
2175
-            'status'           => self::$_pay_status[ $payment->STS_ID() ],
2175
+            'status'           => self::$_pay_status[$payment->STS_ID()],
2176 2176
             'date'             => $payment->timestamp('Y-m-d', 'h:i a'),
2177 2177
             'method'           => strtoupper($payment->source()),
2178 2178
             'PM_ID'            => $payment->payment_method() ? $payment->payment_method()->ID() : 1,
@@ -2291,11 +2291,11 @@  discard block
 block discarded – undo
2291 2291
     {
2292 2292
         $registration_payment_data = [];
2293 2293
         // if non empty reg_ids lets get an array of registrations and update the values for the apply_payment/refund rows.
2294
-        if (! empty($REG_IDs)) {
2294
+        if ( ! empty($REG_IDs)) {
2295 2295
             $registrations = EEM_Registration::instance()->get_all([['REG_ID' => ['IN', $REG_IDs]]]);
2296 2296
             foreach ($registrations as $registration) {
2297 2297
                 if ($registration instanceof EE_Registration) {
2298
-                    $registration_payment_data[ $registration->ID() ] = [
2298
+                    $registration_payment_data[$registration->ID()] = [
2299 2299
                         'paid'  => $registration->pretty_paid(),
2300 2300
                         'owing' => EEH_Template::format_currency($registration->final_price() - $registration->paid()),
2301 2301
                     ];
@@ -2351,7 +2351,7 @@  discard block
 block discarded – undo
2351 2351
         $TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
2352 2352
         $transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2353 2353
         $redirect_to = $this->request->getRequestParam('redirect_to');
2354
-        $query_args  = $redirect_to ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID,] : [];
2354
+        $query_args  = $redirect_to ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID, ] : [];
2355 2355
         do_action(
2356 2356
             'AHEE__Transactions_Admin_Page___send_payment_reminder__process_admin_payment_reminder',
2357 2357
             $transaction
@@ -2389,8 +2389,8 @@  discard block
 block discarded – undo
2389 2389
         );
2390 2390
 
2391 2391
         // make sure our timestamps start and end right at the boundaries for each day
2392
-        $start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
2393
-        $end_date   = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
2392
+        $start_date = date('Y-m-d', strtotime($start_date)).' 00:00:00';
2393
+        $end_date   = date('Y-m-d', strtotime($end_date)).' 23:59:59';
2394 2394
 
2395 2395
 
2396 2396
         // convert to timestamps
@@ -2407,7 +2407,7 @@  discard block
 block discarded – undo
2407 2407
             date('Y-m-d H:i:s', $start_date),
2408 2408
             'Y-m-d H:i:s'
2409 2409
         );
2410
-        $end_date   = EEM_Transaction::instance()->convert_datetime_for_query(
2410
+        $end_date = EEM_Transaction::instance()->convert_datetime_for_query(
2411 2411
             'TXN_timestamp',
2412 2412
             date('Y-m-d H:i:s', $end_date),
2413 2413
             'Y-m-d H:i:s'
@@ -2451,8 +2451,8 @@  discard block
 block discarded – undo
2451 2451
 
2452 2452
         $search_term = $this->request->getRequestParam('s');
2453 2453
         if ($search_term) {
2454
-            $search_term = '%' . $search_term . '%';
2455
-            $_where['OR']  = [
2454
+            $search_term = '%'.$search_term.'%';
2455
+            $_where['OR'] = [
2456 2456
                 'Registration.Event.EVT_name'         => ['LIKE', $search_term],
2457 2457
                 'Registration.Event.EVT_desc'         => ['LIKE', $search_term],
2458 2458
                 'Registration.Event.EVT_short_desc'   => ['LIKE', $search_term],
@@ -2479,9 +2479,9 @@  discard block
 block discarded – undo
2479 2479
 
2480 2480
         $status = $this->request->getRequestParam('status');
2481 2481
         // failed transactions
2482
-        $failed     = (! empty($status) && $status === 'failed' && ! $count) || ($count && $view === 'failed');
2483
-        $abandoned  = (! empty($status) && $status === 'abandoned' && ! $count) || ($count && $view === 'abandoned');
2484
-        $incomplete = (! empty($status) && $status === 'incomplete' && ! $count) || ($count && $view === 'incomplete');
2482
+        $failed     = ( ! empty($status) && $status === 'failed' && ! $count) || ($count && $view === 'failed');
2483
+        $abandoned  = ( ! empty($status) && $status === 'abandoned' && ! $count) || ($count && $view === 'abandoned');
2484
+        $incomplete = ( ! empty($status) && $status === 'incomplete' && ! $count) || ($count && $view === 'incomplete');
2485 2485
 
2486 2486
         if ($failed) {
2487 2487
             $_where['STS_ID'] = EEM_Transaction::failed_status_code;
@@ -2529,7 +2529,7 @@  discard block
 block discarded – undo
2529 2529
         $transaction     = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2530 2530
         $success         = $transaction->recalculateLineItems();
2531 2531
         $redirect_to = $this->request->getRequestParam('redirect_to');
2532
-        $query_args = $redirect_to ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID,] : [];
2532
+        $query_args = $redirect_to ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID, ] : [];
2533 2533
         $this->_redirect_after_action(
2534 2534
             $success,
2535 2535
             esc_html__('Transaction taxes and totals', 'event_espresso'),
Please login to merge, or discard this patch.