| 1 |
<?php |
| 2 |
|
| 3 |
namespace EasyInvoice\Admin; |
| 4 |
|
| 5 |
class InvoiceAdmin { |
| 6 |
public function init(): void { |
| 7 |
add_action('admin_menu', [$this, 'registerMenus']); |
| 8 |
add_action('admin_enqueue_scripts', [$this, 'enqueueAssets']); |
| 9 |
|
| 10 |
// Add custom columns to invoice list |
| 11 |
add_filter('manage_easy-invoice_posts_columns', [$this, 'addCustomColumns']); |
| 12 |
add_action('manage_easy-invoice_posts_custom_column', [$this, 'renderCustomColumns'], 10, 2); |
| 13 |
|
| 14 |
// Add payment status filter |
| 15 |
add_action('restrict_manage_posts', [$this, 'addPaymentStatusFilter']); |
| 16 |
add_filter('parse_query', [$this, 'filterByPaymentStatus']); |
| 17 |
|
| 18 |
// Add row actions for manual payments |
| 19 |
add_filter('post_row_actions', [$this, 'addManualPaymentRowActions'], 10, 2); |
| 20 |
} |
| 21 |
|
| 22 |
/** |
| 23 |
* Add custom columns to invoice list |
| 24 |
* |
| 25 |
* @param array $columns |
| 26 |
* @return array |
| 27 |
*/ |
| 28 |
public function addCustomColumns($columns): array { |
| 29 |
$new_columns = []; |
| 30 |
|
| 31 |
foreach ($columns as $key => $value) { |
| 32 |
$new_columns[$key] = $value; |
| 33 |
|
| 34 |
if ($key === 'title') { |
| 35 |
$new_columns['invoice_number'] = __('Invoice Number', 'easy-invoice'); |
| 36 |
$new_columns['customer'] = __('Customer', 'easy-invoice'); |
| 37 |
$new_columns['amount'] = __('Amount', 'easy-invoice'); |
| 38 |
$new_columns['due_date'] = __('Due Date', 'easy-invoice'); |
| 39 |
$new_columns['payment_status'] = __('Payment Status', 'easy-invoice'); |
| 40 |
} |
| 41 |
} |
| 42 |
|
| 43 |
return $new_columns; |
| 44 |
} |
| 45 |
|
| 46 |
/** |
| 47 |
* Render custom columns |
| 48 |
* |
| 49 |
* @param string $column |
| 50 |
* @param int $post_id |
| 51 |
*/ |
| 52 |
public function renderCustomColumns($column, $post_id): void { |
| 53 |
$invoice = new \EasyInvoice\Models\Invoice(get_post($post_id)); |
| 54 |
|
| 55 |
switch ($column) { |
| 56 |
case 'invoice_number': |
| 57 |
echo esc_html($invoice->getNumber()); |
| 58 |
break; |
| 59 |
|
| 60 |
case 'customer': |
| 61 |
echo esc_html($invoice->getCustomerName()); |
| 62 |
break; |
| 63 |
|
| 64 |
case 'amount': |
| 65 |
$formatter = new \EasyInvoice\Helpers\InvoiceFormatter($invoice); |
| 66 |
echo esc_html($formatter->format($invoice->getTotal())); |
| 67 |
break; |
| 68 |
|
| 69 |
case 'due_date': |
| 70 |
echo esc_html($invoice->getDueDate()); |
| 71 |
break; |
| 72 |
|
| 73 |
case 'payment_status': |
| 74 |
$status = $invoice->getStatus(); |
| 75 |
$payment_status = get_post_meta($post_id, '_payment_status', true); |
| 76 |
$payment_method = get_post_meta($post_id, '_payment_method', true); |
| 77 |
|
| 78 |
if ($status === 'paid') { |
| 79 |
echo '<span class="status-paid">' . __('Paid', 'easy-invoice') . '</span>'; |
| 80 |
} elseif ($payment_status === 'pending' && in_array($payment_method, ['bank', 'cheque'])) { |
| 81 |
$method_label = $payment_method === 'bank' ? __('Bank Transfer', 'easy-invoice') : __('Cheque', 'easy-invoice'); |
| 82 |
echo '<span class="status-pending">' . sprintf(__('Pending %s', 'easy-invoice'), $method_label) . '</span>'; |
| 83 |
|
| 84 |
// Add verification link |
| 85 |
echo '<br><a href="' . admin_url('admin.php?page=easy-invoice-invoices&action=verify-payment&invoice_id=' . $post_id) . '" class="verify-payment-link">' . __('Verify Payment', 'easy-invoice') . '</a>'; |
| 86 |
} elseif ($payment_status === 'rejected') { |
| 87 |
echo '<span class="status-rejected">' . __('Payment Rejected', 'easy-invoice') . '</span>'; |
| 88 |
} else { |
| 89 |
echo '<span class="status-unpaid">' . __('Unpaid', 'easy-invoice') . '</span>'; |
| 90 |
} |
| 91 |
break; |
| 92 |
} |
| 93 |
} |
| 94 |
|
| 95 |
/** |
| 96 |
* Add payment status filter to invoices list |
| 97 |
*/ |
| 98 |
public function addPaymentStatusFilter(): void { |
| 99 |
global $typenow; |
| 100 |
|
| 101 |
if ($typenow !== 'easy-invoice') { |
| 102 |
return; |
| 103 |
} |
| 104 |
|
| 105 |
$current_status = isset($_GET['payment_status']) ? sanitize_text_field($_GET['payment_status']) : ''; |
| 106 |
|
| 107 |
$statuses = [ |
| 108 |
'' => __('All Payment Statuses', 'easy-invoice'), |
| 109 |
'paid' => __('Paid', 'easy-invoice'), |
| 110 |
'unpaid' => __('Unpaid', 'easy-invoice'), |
| 111 |
'pending_bank' => __('Pending Bank Transfer', 'easy-invoice'), |
| 112 |
'pending_cheque' => __('Pending Cheque', 'easy-invoice'), |
| 113 |
'rejected' => __('Payment Rejected', 'easy-invoice') |
| 114 |
]; |
| 115 |
|
| 116 |
echo '<select name="payment_status">'; |
| 117 |
foreach ($statuses as $value => $label) { |
| 118 |
echo '<option value="' . esc_attr($value) . '" ' . selected($current_status, $value, false) . '>' . esc_html($label) . '</option>'; |
| 119 |
} |
| 120 |
echo '</select>'; |
| 121 |
} |
| 122 |
|
| 123 |
/** |
| 124 |
* Filter invoices by payment status |
| 125 |
* |
| 126 |
* @param \WP_Query $query |
| 127 |
*/ |
| 128 |
public function filterByPaymentStatus($query): void { |
| 129 |
global $pagenow, $typenow; |
| 130 |
|
| 131 |
if ($pagenow !== 'edit.php' || $typenow !== 'easy-invoice' || !isset($_GET['payment_status']) || empty($_GET['payment_status'])) { |
| 132 |
return; |
| 133 |
} |
| 134 |
|
| 135 |
$status = sanitize_text_field($_GET['payment_status']); |
| 136 |
|
| 137 |
switch ($status) { |
| 138 |
case 'paid': |
| 139 |
$query->query_vars['meta_query'][] = [ |
| 140 |
'key' => '_status', |
| 141 |
'value' => 'paid', |
| 142 |
'compare' => '=' |
| 143 |
]; |
| 144 |
break; |
| 145 |
|
| 146 |
case 'unpaid': |
| 147 |
$query->query_vars['meta_query'][] = [ |
| 148 |
[ |
| 149 |
'key' => '_status', |
| 150 |
'value' => 'paid', |
| 151 |
'compare' => '!=' |
| 152 |
], |
| 153 |
[ |
| 154 |
'relation' => 'OR', |
| 155 |
[ |
| 156 |
'key' => '_payment_status', |
| 157 |
'compare' => 'NOT EXISTS' |
| 158 |
], |
| 159 |
[ |
| 160 |
'key' => '_payment_status', |
| 161 |
'value' => ['pending', 'rejected'], |
| 162 |
'compare' => 'NOT IN' |
| 163 |
] |
| 164 |
] |
| 165 |
]; |
| 166 |
break; |
| 167 |
|
| 168 |
case 'pending_bank': |
| 169 |
$query->query_vars['meta_query'][] = [ |
| 170 |
[ |
| 171 |
'key' => '_payment_status', |
| 172 |
'value' => 'pending', |
| 173 |
'compare' => '=' |
| 174 |
], |
| 175 |
[ |
| 176 |
'key' => '_payment_method', |
| 177 |
'value' => 'bank', |
| 178 |
'compare' => '=' |
| 179 |
] |
| 180 |
]; |
| 181 |
break; |
| 182 |
|
| 183 |
case 'pending_cheque': |
| 184 |
$query->query_vars['meta_query'][] = [ |
| 185 |
[ |
| 186 |
'key' => '_payment_status', |
| 187 |
'value' => 'pending', |
| 188 |
'compare' => '=' |
| 189 |
], |
| 190 |
[ |
| 191 |
'key' => '_payment_method', |
| 192 |
'value' => 'cheque', |
| 193 |
'compare' => '=' |
| 194 |
] |
| 195 |
]; |
| 196 |
break; |
| 197 |
|
| 198 |
case 'rejected': |
| 199 |
$query->query_vars['meta_query'][] = [ |
| 200 |
'key' => '_payment_status', |
| 201 |
'value' => 'rejected', |
| 202 |
'compare' => '=' |
| 203 |
]; |
| 204 |
break; |
| 205 |
} |
| 206 |
} |
| 207 |
|
| 208 |
/** |
| 209 |
* Add row actions for manual payments |
| 210 |
* |
| 211 |
* @param array $actions |
| 212 |
* @param \WP_Post $post |
| 213 |
* @return array |
| 214 |
*/ |
| 215 |
public function addManualPaymentRowActions($actions, $post): array { |
| 216 |
if ($post->post_type !== 'easy_invoice') { |
| 217 |
return $actions; |
| 218 |
} |
| 219 |
|
| 220 |
$payment_status = get_post_meta($post->ID, '_payment_status', true); |
| 221 |
$payment_method = get_post_meta($post->ID, '_payment_method', true); |
| 222 |
|
| 223 |
if ($payment_status === 'pending' && in_array($payment_method, ['bank', 'cheque'])) { |
| 224 |
$actions['verify_payment'] = sprintf( |
| 225 |
'<a href="%s">%s</a>', |
| 226 |
admin_url('admin.php?page=easy-invoice-invoices&action=verify-payment&invoice_id=' . $post->ID), |
| 227 |
__('Verify Payment', 'easy-invoice') |
| 228 |
); |
| 229 |
} |
| 230 |
|
| 231 |
return $actions; |
| 232 |
} |
| 233 |
} |