فهرست منبع

studiou-wc-custom-reports: fix calculating counts. tested

Dalibor Votruba 1 سال پیش
والد
کامیت
208bba7b84

+ 30 - 1
studiou-wc-custom-reports/includes/class-admin-view.php

@@ -56,7 +56,20 @@ class StudiouWC_Admin_View {
         $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');
-        $statuses = isset($_GET['statuses']) ? array_map('sanitize_text_field', $_GET['statuses']) : ($settings['default_statuses'] ?? array());
+        
+        // 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;
         $orderby = isset($_GET['orderby']) ? sanitize_text_field($_GET['orderby']) : 'category';
@@ -147,6 +160,22 @@ class StudiouWC_Admin_View {
     
     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>';

+ 94 - 17
studiou-wc-custom-reports/includes/class-db-manager.php

@@ -64,34 +64,111 @@ class StudiouWC_DB_Manager {
     public function get_property_counts_for_category($category, $date_from, $date_to, $statuses, $property) {
         global $wpdb;
         
-        if (empty($statuses)) {
+        if (empty($statuses) || empty($property)) {
             return array();
         }
         
         $statuses_placeholder = implode(',', array_fill(0, count($statuses), '%s'));
-        $taxonomy = 'pa_' . $property; // Add the pa_ prefix for WooCommerce attributes
+        $meta_key = 'attribute_pa_' . $property; // WooCommerce stores variation attributes as meta
         
+        // Get order items for this category and date range, then check their variation meta
         if ($this->is_hpos_enabled()) {
-            $sql = $this->get_hpos_property_counts_query($statuses_placeholder);
+            $base_sql = "
+                SELECT oi.product_id, oi.variation_id, oi.product_qty, pm.meta_value as attr_value
+                FROM {$wpdb->prefix}wc_orders o
+                INNER JOIN {$wpdb->prefix}wc_order_product_lookup oi ON o.id = oi.order_id
+                INNER JOIN {$wpdb->posts} p_main ON (
+                    CASE 
+                        WHEN oi.variation_id > 0 THEN 
+                            (SELECT post_parent FROM {$wpdb->posts} WHERE ID = oi.variation_id)
+                        ELSE oi.product_id 
+                    END
+                ) = p_main.ID
+                INNER JOIN {$wpdb->term_relationships} tr_cat ON p_main.ID = tr_cat.object_id
+                INNER JOIN {$wpdb->term_taxonomy} tt_cat ON tr_cat.term_taxonomy_id = tt_cat.term_taxonomy_id
+                INNER JOIN {$wpdb->terms} t_cat ON tt_cat.term_id = t_cat.term_id
+                LEFT JOIN {$wpdb->postmeta} pm ON (
+                    CASE 
+                        WHEN oi.variation_id > 0 THEN oi.variation_id
+                        ELSE oi.product_id 
+                    END
+                ) = pm.post_id AND pm.meta_key = %s
+                WHERE o.date_created_gmt >= %s 
+                AND o.date_created_gmt <= %s 
+                AND o.status IN ($statuses_placeholder)
+                AND tt_cat.taxonomy = 'product_cat'
+                AND t_cat.name = %s
+                AND pm.meta_value IS NOT NULL
+                AND pm.meta_value != ''
+            ";
         } else {
-            $sql = $this->get_legacy_property_counts_query($statuses_placeholder);
+            $base_sql = "
+                SELECT oi.product_id, oi.variation_id, oi.product_qty, pm.meta_value as attr_value
+                FROM {$wpdb->posts} p_order
+                INNER JOIN {$wpdb->prefix}wc_order_product_lookup oi ON p_order.ID = oi.order_id
+                INNER JOIN {$wpdb->posts} p_main ON (
+                    CASE 
+                        WHEN oi.variation_id > 0 THEN 
+                            (SELECT post_parent FROM {$wpdb->posts} WHERE ID = oi.variation_id)
+                        ELSE oi.product_id 
+                    END
+                ) = p_main.ID
+                INNER JOIN {$wpdb->term_relationships} tr_cat ON p_main.ID = tr_cat.object_id
+                INNER JOIN {$wpdb->term_taxonomy} tt_cat ON tr_cat.term_taxonomy_id = tt_cat.term_taxonomy_id
+                INNER JOIN {$wpdb->terms} t_cat ON tt_cat.term_id = t_cat.term_id
+                LEFT JOIN {$wpdb->postmeta} pm ON (
+                    CASE 
+                        WHEN oi.variation_id > 0 THEN oi.variation_id
+                        ELSE oi.product_id 
+                    END
+                ) = pm.post_id AND pm.meta_key = %s
+                WHERE p_order.post_date >= %s 
+                AND p_order.post_date <= %s 
+                AND p_order.post_status IN ($statuses_placeholder)
+                AND p_order.post_type = 'shop_order'
+                AND tt_cat.taxonomy = 'product_cat'
+                AND t_cat.name = %s
+                AND pm.meta_value IS NOT NULL
+                AND pm.meta_value != ''
+            ";
         }
         
         $query_params = array_merge(
-            array($date_from, $date_to),
+            array($meta_key, $date_from, $date_to),
             $statuses,
-            array($category, $taxonomy)
+            array($category)
         );
         
-        $results = $wpdb->get_results($wpdb->prepare($sql, $query_params), ARRAY_A);
+        // Debug: Log the query for troubleshooting
+        if (defined('WP_DEBUG') && WP_DEBUG) {
+            error_log('[Studiou Debug] Updated property counts query: ' . $wpdb->prepare($base_sql, $query_params));
+        }
+        
+        $results = $wpdb->get_results($wpdb->prepare($base_sql, $query_params), ARRAY_A);
         
+        if (defined('WP_DEBUG') && WP_DEBUG) {
+            error_log('[Studiou Debug] Found ' . count($results) . ' items with attribute values');
+            error_log('[Studiou Debug] Sample results: ' . print_r(array_slice($results, 0, 3), true));
+        }
+        
+        // Count quantities by attribute value
         $property_counts = array();
         foreach ($results as $result) {
-            if (!empty($result['property_value'])) {
-                $property_counts[$result['property_value']] = $result['count'];
+            $attr_value = $result['attr_value'];
+            $qty = $result['product_qty'];
+            
+            if (!empty($attr_value)) {
+                if (!isset($property_counts[$attr_value])) {
+                    $property_counts[$attr_value] = 0;
+                }
+                $property_counts[$attr_value] += $qty;
             }
         }
         
+        if (defined('WP_DEBUG') && WP_DEBUG) {
+            error_log('[Studiou Debug] Final property counts: ' . print_r($property_counts, true));
+        }
+        
         return $property_counts;
     }
     
@@ -266,17 +343,17 @@ class StudiouWC_DB_Manager {
         return "
             SELECT 
                 t_attr.slug as property_value,
-                COUNT(DISTINCT oi.order_item_id) as count
+                SUM(oi.product_qty) as count
             FROM {$wpdb->prefix}wc_orders o
             INNER JOIN {$wpdb->prefix}wc_order_product_lookup oi ON o.id = oi.order_id
-            INNER JOIN {$wpdb->posts} p ON oi.product_id = p.ID OR oi.variation_id = p.ID
-            INNER JOIN {$wpdb->term_relationships} tr_cat ON (
+            INNER JOIN {$wpdb->posts} p_main ON (
                 CASE 
                     WHEN oi.variation_id > 0 THEN 
                         (SELECT post_parent FROM {$wpdb->posts} WHERE ID = oi.variation_id)
                     ELSE oi.product_id 
                 END
-            ) = tr_cat.object_id
+            ) = p_main.ID
+            INNER JOIN {$wpdb->term_relationships} tr_cat ON p_main.ID = tr_cat.object_id
             INNER JOIN {$wpdb->term_taxonomy} tt_cat ON tr_cat.term_taxonomy_id = tt_cat.term_taxonomy_id
             INNER JOIN {$wpdb->terms} t_cat ON tt_cat.term_id = t_cat.term_id
             INNER JOIN {$wpdb->term_relationships} tr_attr ON (
@@ -306,17 +383,17 @@ class StudiouWC_DB_Manager {
         return "
             SELECT 
                 t_attr.slug as property_value,
-                COUNT(DISTINCT oi.order_item_id) as count
+                SUM(oi.product_qty) as count
             FROM {$wpdb->posts} p_order
             INNER JOIN {$wpdb->prefix}wc_order_product_lookup oi ON p_order.ID = oi.order_id
-            INNER JOIN {$wpdb->posts} p ON oi.product_id = p.ID OR oi.variation_id = p.ID
-            INNER JOIN {$wpdb->term_relationships} tr_cat ON (
+            INNER JOIN {$wpdb->posts} p_main ON (
                 CASE 
                     WHEN oi.variation_id > 0 THEN 
                         (SELECT post_parent FROM {$wpdb->posts} WHERE ID = oi.variation_id)
                     ELSE oi.product_id 
                 END
-            ) = tr_cat.object_id
+            ) = p_main.ID
+            INNER JOIN {$wpdb->term_relationships} tr_cat ON p_main.ID = tr_cat.object_id
             INNER JOIN {$wpdb->term_taxonomy} tt_cat ON tr_cat.term_taxonomy_id = tt_cat.term_taxonomy_id
             INNER JOIN {$wpdb->terms} t_cat ON tt_cat.term_id = t_cat.term_id
             INNER JOIN {$wpdb->term_relationships} tr_attr ON (

+ 12 - 3
studiou-wc-custom-reports/includes/class-settings-manager.php

@@ -16,14 +16,23 @@ class StudiouWC_Settings_Manager {
     public function activate() {
         $default_settings = array(
             'default_interval' => 'last_month',
-            'default_property' => '',
-            'default_statuses' => array('wc-completed', 'wc-processing', 'wc-on-hold')
+            'default_property' => 'format', // Set format as default since it exists
+            'default_statuses' => array('wc-completed', 'wc-processing', 'wc-on-hold', 'wc-to-print')
         );
         add_option(self::OPTION_NAME, $default_settings);
     }
     
     public function get_settings() {
-        return get_option(self::OPTION_NAME, array());
+        $settings = get_option(self::OPTION_NAME, array());
+        
+        // Ensure we have default values
+        $defaults = array(
+            'default_interval' => 'last_month',
+            'default_property' => 'format',
+            'default_statuses' => array('wc-completed', 'wc-processing', 'wc-on-hold', 'wc-to-print')
+        );
+        
+        return array_merge($defaults, $settings);
     }
     
     public function update_settings($settings) {