displayClientsPage(); break; case PagesSlugs::CLIENT_EDIT: $this->displayClientEditPage(); break; case PagesSlugs::CLIENT_VIEW: $this->displayClientViewPage(); break; default: $this->displayClientsPage(); break; } } /** * Display clients page */ protected function displayClientsPage() { // Pagination settings $per_page = 20; $current_page = isset($_GET['paged']) ? max(1, intval($_GET['paged'])) : 1; // Get repository $repository = ClientServiceProvider::getClientRepository(); // Get all clients first to calculate total $all_clients = $repository->all(); $total_clients = count($all_clients); $total_pages = ceil($total_clients / $per_page); // Get paginated clients $offset = ($current_page - 1) * $per_page; $clients = array_slice($all_clients, $offset, $per_page); // Initialize stats $stats = [ 'total_clients' => $total_clients, 'total_invoices' => 0, 'total_revenue' => [], 'pending_invoices' => 0 ]; // Calculate total revenue from all clients' invoices $invoice_repository = InvoiceServiceProvider::getInvoiceRepository(); $all_invoices = $invoice_repository->all(); $revenue_by_currency = []; // First, get all currencies that exist in the system $all_currencies = []; foreach ($all_invoices as $invoice) { $currency_code = $invoice->getCurrencyCode(); // If currency is empty or "global", get the actual currency that was used if (empty($currency_code) || $currency_code === 'global') { // Get the actual currency from invoice meta $actual_currency = get_post_meta($invoice->getId(), '_easy_invoice_currency_code', true); $currency_code = !empty($actual_currency) ? $actual_currency : get_option('easy_invoice_currency_code', 'USD'); } // If currency is still "global", use the global setting if ($currency_code === 'global') { $currency_code = get_option('easy_invoice_currency_code', 'USD'); } // Normalize currency code to uppercase for consistent grouping $currency_code = strtoupper($currency_code); if (!empty($currency_code)) { $all_currencies[$currency_code] = \EasyInvoice\Helpers\CurrencyHelper::getCurrencySymbol($currency_code); } } // Initialize revenue for all currencies found foreach ($all_currencies as $currency_code => $currency_symbol) { $revenue_by_currency[$currency_code] = [ 'amount' => 0, 'symbol' => $currency_symbol, 'currency_code' => $currency_code ]; } // Now calculate revenue for paid invoices foreach ($all_invoices as $invoice) { if ($invoice->getStatus() === 'paid') { $invoice_total = $invoice->getTotal(); if (!is_numeric($invoice_total)) { continue; } // Get the actual currency from the invoice $currency_code = $invoice->getCurrencyCode(); // If currency is empty or "global", get the actual currency that was used if (empty($currency_code) || $currency_code === 'global') { // Get the actual currency from invoice meta $actual_currency = get_post_meta($invoice->getId(), '_easy_invoice_currency_code', true); $currency_code = !empty($actual_currency) ? $actual_currency : get_option('easy_invoice_currency_code', 'USD'); } // If currency is still "global", use the global setting if ($currency_code === 'global') { $currency_code = get_option('easy_invoice_currency_code', 'USD'); } // Normalize currency code to uppercase for consistent grouping $currency_code = strtoupper($currency_code); if (isset($revenue_by_currency[$currency_code])) { $revenue_by_currency[$currency_code]['amount'] += $invoice_total; } } } $stats['total_revenue'] = $revenue_by_currency; $stats['total_invoices'] = count($all_invoices); $stats['pending_invoices'] = count($invoice_repository->findByStatus('pending')); // Prepare template data with pagination $template_data = [ 'clients' => $clients, 'stats' => $stats, 'current_page' => $current_page, 'per_page' => $per_page, 'total_clients' => $total_clients, 'total_pages' => $total_pages ]; // Display the template $this->displayTemplate( EASY_INVOICE_PLUGIN_DIR . 'templates/clients-page.php', $template_data ); } /** * Display client edit page */ protected function displayClientEditPage() { $check = $this->checkCapability(); if (is_wp_error($check)) { wp_die($check->get_error_message()); } $client_id = isset($_GET['client_id']) ? intval($_GET['client_id']) : 0; if ($client_id <= 0) { wp_die(__('Invalid client ID', 'easy-invoice')); } // Get client from repository $repository = ClientServiceProvider::getClientRepository(); $client = $repository->find($client_id); if (!$client) { wp_die(__('Client not found', 'easy-invoice')); } // Display the template $this->displayTemplate( EASY_INVOICE_PLUGIN_DIR . 'templates/client-edit-page.php', ['client' => $client] ); } /** * Display client view page */ protected function displayClientViewPage() { $check = $this->checkCapability(); if (is_wp_error($check)) { wp_die($check->get_error_message()); } $client_id = isset($_GET['client_id']) ? intval($_GET['client_id']) : 0; if ($client_id <= 0) { wp_die(__('Invalid client ID', 'easy-invoice')); } // Get client from repository $repository = ClientServiceProvider::getClientRepository(); $client = $repository->find($client_id); if (!$client) { wp_die(__('Client not found', 'easy-invoice')); } // Get client invoices $invoices = []; $invoice_repository = InvoiceServiceProvider::getInvoiceRepository(); // Query invoices for this client $args = array( 'post_type' => 'easy_invoice', 'post_status' => 'publish', 'meta_query' => array( array( 'key' => '_easy_invoice_client_id', 'value' => $client_id, 'compare' => '=' ) ), 'posts_per_page' => -1, 'orderby' => 'date', 'order' => 'DESC' ); $invoice_posts = get_posts($args); foreach ($invoice_posts as $post) { $invoice = $invoice_repository->find($post->ID); if ($invoice) { $invoices[] = array( 'id' => $invoice->getId(), 'title' => $invoice->getTitle() ?: $invoice->getNumber(), 'invoice_number' => $invoice->getNumber(), 'date' => $invoice->getIssueDate(), 'due_date' => $invoice->getDueDate(), 'amount' => $invoice->getTotal(), 'status' => $invoice->getStatus() ); } } // Get client quotes $quotes = []; $quote_repository = QuoteServiceProvider::getQuoteRepository(); // Query quotes for this client $quote_args = array( 'post_type' => 'easy_invoice_quote', 'post_status' => 'publish', 'meta_query' => array( array( 'key' => '_easy_invoice_client_id', 'value' => $client_id, 'compare' => '=' ) ), 'posts_per_page' => -1, 'orderby' => 'date', 'order' => 'DESC' ); $quote_posts = get_posts($quote_args); foreach ($quote_posts as $post) { $quote = $quote_repository->find($post->ID); if ($quote) { $quotes[] = array( 'id' => $quote->getId(), 'title' => $quote->getTitle() ?: $quote->getNumber(), 'quote_number' => $quote->getNumber(), 'date' => $quote->getIssueDate(), 'expiry_date' => $quote->getExpiryDate(), 'amount' => $quote->getTotal(), 'status' => $quote->getStatus() ); } } // Get client role information $user = get_user_by('ID', $client_id); $client_role = $user ? $user->roles[0] ?? 'client' : 'client'; // Display the template $this->displayTemplate( EASY_INVOICE_PLUGIN_DIR . 'templates/client-view-page.php', [ 'client' => $client, 'invoices' => $invoices, 'quotes' => $quotes, 'client_role' => $client_role ] ); } /** * Get client stats * * @return array */ public function getClientStats() { $repository = ClientServiceProvider::getClientRepository(); $clients = $repository->all(); return [ 'total_clients' => count($clients) ]; } /** * Delete a client */ public function deleteClient() { if (!$this->handleAjaxSecurity($_POST['nonce'])) { return; } // Check client ID if (!isset($_POST['client_id']) || empty($_POST['client_id'])) { wp_send_json_error(array('message' => 'Invalid client ID')); } $client_id = intval($_POST['client_id']); // Delete client $repository = ClientServiceProvider::getClientRepository(); $result = $repository->delete($client_id); if ($result) { wp_send_json_success(array('message' => 'Client deleted successfully')); } else { wp_send_json_error(array('message' => 'Error deleting client')); } } }