| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391 |
- <?php
- /**
- * Admin View Class - Handles admin interface rendering
- *
- * @package StudiouWCCustomReports
- */
- if (!defined('ABSPATH')) {
- exit;
- }
- class StudiouWC_Admin_View {
-
- private $db_manager;
- private $settings_manager;
-
- public function __construct($db_manager, $settings_manager) {
- $this->db_manager = $db_manager;
- $this->settings_manager = $settings_manager;
- }
-
- public function add_admin_menu() {
- // Add Custom Reports page under WooCommerce > Reports
- add_submenu_page(
- 'woocommerce',
- __('Custom Reports', StudiouWC_Main::get_text_domain()),
- __('Custom Reports', StudiouWC_Main::get_text_domain()),
- 'manage_woocommerce',
- 'studiou-custom-reports',
- array($this, 'display_custom_reports_page')
- );
-
- // Add Settings page under WooCommerce > Reports Settings
- add_submenu_page(
- 'woocommerce',
- __('Custom Report Settings', StudiouWC_Main::get_text_domain()),
- __('Custom Report Settings', StudiouWC_Main::get_text_domain()),
- 'manage_woocommerce',
- 'studiou-reports-settings',
- array($this, 'display_settings_page')
- );
- }
-
- public function enqueue_admin_scripts($hook) {
- if (strpos($hook, 'studiou-') !== false) {
- wp_enqueue_script('jquery');
- wp_enqueue_script('jquery-ui-datepicker');
- wp_enqueue_style('jquery-ui-datepicker', 'https://code.jquery.com/ui/1.12.1/themes/ui-lightness/jquery-ui.css');
- }
- }
-
- public function display_custom_reports_page() {
- $settings = $this->settings_manager->get_settings();
-
- // Handle form submission
- $view = isset($_GET['view']) ? sanitize_text_field($_GET['view']) : 'product_categories_summary';
- $date_from = isset($_GET['date_from']) ? sanitize_text_field($_GET['date_from']) : $this->settings_manager->get_default_date_from();
- $date_to = isset($_GET['date_to']) ? sanitize_text_field($_GET['date_to']) : date('Y-m-d');
-
- // If no statuses selected, use all available statuses (including custom ones)
- if (isset($_GET['statuses']) && !empty($_GET['statuses'])) {
- $statuses = array_map('sanitize_text_field', $_GET['statuses']);
- } else {
- $default_statuses = $settings['default_statuses'] ?? array();
- if (empty($default_statuses)) {
- // Include common statuses + your custom status
- $statuses = array('wc-completed', 'wc-processing', 'wc-on-hold', 'wc-to-print');
- } else {
- $statuses = $default_statuses;
- }
- }
-
- $per_page = isset($_GET['per_page']) ? intval($_GET['per_page']) : 20;
- $paged = isset($_GET['paged']) ? intval($_GET['paged']) : 1;
- $default_orderby = ($view === 'order_customers_list') ? 'customer_name' : 'category';
- $orderby = isset($_GET['orderby']) ? sanitize_text_field($_GET['orderby']) : $default_orderby;
- $order = isset($_GET['order']) ? sanitize_text_field($_GET['order']) : 'ASC';
- // Get report data based on view
- if ($view === 'order_customers_list') {
- $report_data = $this->db_manager->get_order_customers_list($date_from, $date_to, $statuses, $per_page, $paged, $orderby, $order);
- $total_items = $this->db_manager->get_order_customers_total_items($date_from, $date_to, $statuses);
- } else {
- $report_data = $this->db_manager->get_product_categories_summary($date_from, $date_to, $statuses, $per_page, $paged, $orderby, $order);
- $total_items = $this->db_manager->get_total_items($date_from, $date_to, $statuses);
- }
- $total_pages = ceil($total_items / $per_page);
-
- $this->render_reports_page($view, $date_from, $date_to, $statuses, $per_page, $paged, $orderby, $order, $report_data, $total_items, $total_pages, $settings);
- }
-
- public function display_settings_page() {
- $settings = $this->settings_manager->get_settings();
- $this->render_settings_page($settings);
- }
-
- private function render_reports_page($view, $date_from, $date_to, $statuses, $per_page, $paged, $orderby, $order, $report_data, $total_items, $total_pages, $settings) {
- ?>
- <div class="wrap">
- <h1><?php _e('Custom Reports', StudiouWC_Main::get_text_domain()); ?></h1>
-
- <?php $this->render_filter_form($view, $date_from, $date_to, $statuses, $per_page); ?>
-
- <?php if (!empty($report_data)): ?>
- <?php $this->render_pagination_top($total_items, $total_pages, $paged); ?>
- <?php if ($view === 'order_customers_list'): ?>
- <?php $this->render_customers_data_table($report_data, $orderby, $order); ?>
- <?php else: ?>
- <?php $this->render_data_table($report_data, $orderby, $order, $settings); ?>
- <?php endif; ?>
- <?php else: ?>
- <p><?php _e('No data found for the selected criteria.', StudiouWC_Main::get_text_domain()); ?></p>
- <?php endif; ?>
- </div>
-
- <?php $this->render_reports_javascript(); ?>
- <?php
- }
-
- private function render_filter_form($view, $date_from, $date_to, $statuses, $per_page) {
- ?>
- <form method="get" id="studiou-reports-form">
- <input type="hidden" name="page" value="studiou-custom-reports">
-
- <table class="form-table">
- <tr>
- <th><label for="view"><?php _e('View', StudiouWC_Main::get_text_domain()); ?></label></th>
- <td>
- <select name="view" id="view">
- <option value="product_categories_summary" <?php selected($view, 'product_categories_summary'); ?>>
- <?php _e('Product Categories and Variants Summary', StudiouWC_Main::get_text_domain()); ?>
- </option>
- <option value="order_customers_list" <?php selected($view, 'order_customers_list'); ?>>
- <?php _e('Order Customers List', StudiouWC_Main::get_text_domain()); ?>
- </option>
- </select>
- </td>
- </tr>
- <tr>
- <th><label for="date_from"><?php _e('Date From', StudiouWC_Main::get_text_domain()); ?></label></th>
- <td><input type="date" name="date_from" id="date_from" value="<?php echo esc_attr($date_from); ?>"></td>
- </tr>
- <tr>
- <th><label for="date_to"><?php _e('Date To', StudiouWC_Main::get_text_domain()); ?></label></th>
- <td><input type="date" name="date_to" id="date_to" value="<?php echo esc_attr($date_to); ?>"></td>
- </tr>
- <tr>
- <th><label for="statuses"><?php _e('Included Statuses', StudiouWC_Main::get_text_domain()); ?></label></th>
- <td>
- <?php $this->render_status_checkboxes($statuses); ?>
- </td>
- </tr>
- <tr>
- <th><label for="per_page"><?php _e('Items per page', StudiouWC_Main::get_text_domain()); ?></label></th>
- <td>
- <select name="per_page" id="per_page">
- <option value="10" <?php selected($per_page, 10); ?>>10</option>
- <option value="20" <?php selected($per_page, 20); ?>>20</option>
- <option value="50" <?php selected($per_page, 50); ?>>50</option>
- <option value="100" <?php selected($per_page, 100); ?>>100</option>
- </select>
- </td>
- </tr>
- </table>
-
- <p class="submit">
- <input type="submit" name="filter" class="button-primary" value="<?php esc_attr_e('Filter', StudiouWC_Main::get_text_domain()); ?>">
- <button type="button" id="export-csv" class="button"><?php _e('Export', StudiouWC_Main::get_text_domain()); ?></button>
- </p>
- </form>
- <?php
- }
-
- private function render_status_checkboxes($selected_statuses) {
- $order_statuses = wc_get_order_statuses();
-
- // Add custom statuses that might not be in the standard list
- global $wpdb;
- $custom_statuses = $wpdb->get_col("
- SELECT DISTINCT status
- FROM {$wpdb->prefix}wc_orders
- WHERE status NOT IN ('" . implode("','", array_keys($order_statuses)) . "')
- AND date_created_gmt >= DATE_SUB(NOW(), INTERVAL 90 DAY)
- ");
-
- foreach ($custom_statuses as $custom_status) {
- if (!isset($order_statuses[$custom_status])) {
- $order_statuses[$custom_status] = ucwords(str_replace(array('wc-', '-'), array('', ' '), $custom_status));
- }
- }
-
- foreach ($order_statuses as $status_key => $status_label) {
- $checked = in_array($status_key, $selected_statuses) ? 'checked' : '';
- echo '<label><input type="checkbox" name="statuses[]" value="' . esc_attr($status_key) . '" ' . $checked . '> ' . esc_html($status_label) . '</label><br>';
- }
- }
-
- private function render_pagination_top($total_items, $total_pages, $paged) {
- ?>
- <div class="tablenav top">
- <div class="tablenav-pages">
- <span class="displaying-num"><?php
- /* translators: %d: number of items */
- printf(_n('%d item', '%d items', $total_items, StudiouWC_Main::get_text_domain()), $total_items);
- ?></span>
- <?php if ($total_pages > 1): ?>
- <span class="pagination-links">
- <?php if ($paged > 1): ?>
- <a class="prev-page button" href="<?php echo esc_url(add_query_arg('paged', $paged - 1)); ?>" title="<?php esc_attr_e('Previous', StudiouWC_Main::get_text_domain()); ?>"><?php _e('‹', StudiouWC_Main::get_text_domain()); ?></a>
- <?php endif; ?>
- <span class="paging-input">
- <span class="tablenav-paging-text"><?php
- /* translators: 1: current page number, 2: total number of pages */
- printf(__('%1$d of %2$d', StudiouWC_Main::get_text_domain()), $paged, $total_pages);
- ?></span>
- </span>
- <?php if ($paged < $total_pages): ?>
- <a class="next-page button" href="<?php echo esc_url(add_query_arg('paged', $paged + 1)); ?>" title="<?php esc_attr_e('Next', StudiouWC_Main::get_text_domain()); ?>"><?php _e('›', StudiouWC_Main::get_text_domain()); ?></a>
- <?php endif; ?>
- </span>
- <?php endif; ?>
- </div>
- </div>
- <?php
- }
-
- private function render_data_table($report_data, $orderby, $order, $settings) {
- $default_property = $settings['default_property'] ?? '';
- $property_values = array();
-
- if (!empty($default_property)) {
- $property_values = $this->db_manager->get_property_values($default_property);
- }
-
- ?>
- <table class="wp-list-table widefat fixed striped">
- <thead>
- <tr>
- <th><a href="<?php echo esc_url(add_query_arg(array('orderby' => 'category', 'order' => $order === 'ASC' ? 'DESC' : 'ASC'))); ?>"><?php _e('Product Category', StudiouWC_Main::get_text_domain()); ?></a></th>
- <th><a href="<?php echo esc_url(add_query_arg(array('orderby' => 'orders_count', 'order' => $order === 'ASC' ? 'DESC' : 'ASC'))); ?>"><?php _e('Orders Count', StudiouWC_Main::get_text_domain()); ?></a></th>
- <?php foreach ($property_values as $slug => $name): ?>
- <th><?php
- /* translators: %s: property name */
- printf(__('%s Count', StudiouWC_Main::get_text_domain()), esc_html($name));
- ?></th>
- <?php endforeach; ?>
- <th><a href="<?php echo esc_url(add_query_arg(array('orderby' => 'total_price', 'order' => $order === 'ASC' ? 'DESC' : 'ASC'))); ?>"><?php _e('Total Price', StudiouWC_Main::get_text_domain()); ?></a></th>
- </tr>
- </thead>
- <tbody>
- <?php foreach ($report_data as $row): ?>
- <tr>
- <td><?php echo esc_html($row['category']); ?></td>
- <td><?php echo esc_html($row['orders_count']); ?></td>
- <?php foreach ($property_values as $slug => $name): ?>
- <td><?php echo esc_html($row['property_counts'][$slug] ?? 0); ?></td>
- <?php endforeach; ?>
- <td><?php echo wc_price($row['total_price']); ?></td>
- </tr>
- <?php endforeach; ?>
- </tbody>
- </table>
- <?php
- }
-
- private function render_customers_data_table($report_data, $orderby, $order) {
- ?>
- <table class="wp-list-table widefat fixed striped">
- <thead>
- <tr>
- <th><a href="<?php echo esc_url(add_query_arg(array('orderby' => 'customer_name', 'order' => $order === 'ASC' ? 'DESC' : 'ASC'))); ?>"><?php _e('Customer Name', StudiouWC_Main::get_text_domain()); ?></a></th>
- <th><a href="<?php echo esc_url(add_query_arg(array('orderby' => 'customer_email', 'order' => $order === 'ASC' ? 'DESC' : 'ASC'))); ?>"><?php _e('Email', StudiouWC_Main::get_text_domain()); ?></a></th>
- <th><?php _e('Phone', StudiouWC_Main::get_text_domain()); ?></th>
- <th><a href="<?php echo esc_url(add_query_arg(array('orderby' => 'orders_count', 'order' => $order === 'ASC' ? 'DESC' : 'ASC'))); ?>"><?php _e('Orders Count', StudiouWC_Main::get_text_domain()); ?></a></th>
- <th><a href="<?php echo esc_url(add_query_arg(array('orderby' => 'total_price', 'order' => $order === 'ASC' ? 'DESC' : 'ASC'))); ?>"><?php _e('Total Orders Price', StudiouWC_Main::get_text_domain()); ?></a></th>
- </tr>
- </thead>
- <tbody>
- <?php foreach ($report_data as $row): ?>
- <tr>
- <td><?php echo esc_html($row['customer_name']); ?></td>
- <td><?php echo esc_html($row['customer_email']); ?></td>
- <td><?php echo esc_html($row['customer_phone']); ?></td>
- <td><?php echo esc_html($row['orders_count']); ?></td>
- <td><?php echo wc_price($row['total_price']); ?></td>
- </tr>
- <?php endforeach; ?>
- </tbody>
- </table>
- <?php
- }
- private function render_reports_javascript() {
- ?>
- <script>
- jQuery(document).ready(function($) {
- $('#export-csv').click(function() {
- var formData = $('#studiou-reports-form').serialize();
- formData += '&action=studiou_export_csv&export=1';
-
- var form = $('<form method="post" action="' + ajaxurl + '"></form>');
- $.each(formData.split('&'), function(i, field) {
- var parts = field.split('=');
- if (parts.length === 2) {
- form.append('<input type="hidden" name="' + decodeURIComponent(parts[0]) + '" value="' + decodeURIComponent(parts[1]) + '">');
- }
- });
- $('body').append(form);
- form.submit();
- form.remove();
- });
- });
- </script>
- <?php
- }
-
- private function render_settings_page($settings) {
- ?>
- <div class="wrap">
- <h1><?php _e('Custom Report Settings', StudiouWC_Main::get_text_domain()); ?></h1>
-
- <form method="post" id="studiou-settings-form">
- <?php wp_nonce_field('studiou_save_settings', 'studiou_settings_nonce'); ?>
- <table class="form-table">
- <tr>
- <th><label for="default_interval"><?php _e('Default shown interval', StudiouWC_Main::get_text_domain()); ?></label></th>
- <td>
- <select name="default_interval" id="default_interval">
- <option value="last_day" <?php selected($settings['default_interval'] ?? '', 'last_day'); ?>><?php _e('Last day', StudiouWC_Main::get_text_domain()); ?></option>
- <option value="last_week" <?php selected($settings['default_interval'] ?? '', 'last_week'); ?>><?php _e('Last week', StudiouWC_Main::get_text_domain()); ?></option>
- <option value="last_month" <?php selected($settings['default_interval'] ?? '', 'last_month'); ?>><?php _e('Last month', StudiouWC_Main::get_text_domain()); ?></option>
- </select>
- </td>
- </tr>
- <tr>
- <th><label for="default_property"><?php _e('Default property', StudiouWC_Main::get_text_domain()); ?></label></th>
- <td>
- <select name="default_property" id="default_property">
- <option value=""><?php _e('Select property', StudiouWC_Main::get_text_domain()); ?></option>
- <?php
- $properties = $this->db_manager->get_product_properties();
- foreach ($properties as $slug => $name) {
- $selected = selected($settings['default_property'] ?? '', $slug, false);
- echo '<option value="' . esc_attr($slug) . '" ' . $selected . '>' . esc_html($name) . '</option>';
- }
- ?>
- </select>
- </td>
- </tr>
- <tr>
- <th><label for="default_statuses"><?php _e('Default Included statuses', StudiouWC_Main::get_text_domain()); ?></label></th>
- <td>
- <?php
- $order_statuses = wc_get_order_statuses();
- $default_statuses = $settings['default_statuses'] ?? array();
- foreach ($order_statuses as $status_key => $status_label) {
- $checked = in_array($status_key, $default_statuses) ? 'checked' : '';
- echo '<label><input type="checkbox" name="default_statuses[]" value="' . esc_attr($status_key) . '" ' . $checked . '> ' . esc_html($status_label) . '</label><br>';
- }
- ?>
- </td>
- </tr>
- </table>
-
- <p class="submit">
- <button type="button" id="save-settings" class="button-primary"><?php _e('Save Settings', StudiouWC_Main::get_text_domain()); ?></button>
- </p>
- </form>
- </div>
-
- <script>
- jQuery(document).ready(function($) {
- $('#save-settings').click(function() {
- var formData = $('#studiou-settings-form').serialize();
- formData += '&action=studiou_save_settings';
-
- $.post(ajaxurl, formData, function(response) {
- if (response.success) {
- alert('<?php echo esc_js(__('Settings saved successfully!', StudiouWC_Main::get_text_domain())); ?>');
- } else {
- alert('<?php echo esc_js(__('Error saving settings.', StudiouWC_Main::get_text_domain())); ?>');
- }
- }).fail(function() {
- alert('<?php echo esc_js(__('Connection error. Please try again.', StudiouWC_Main::get_text_domain())); ?>');
- });
- });
- });
- </script>
- <?php
- }
- }
|