首页 / 教程文章 / WordPress柔性供应链软件实现动态安全库存设置的教程

WordPress柔性供应链软件实现动态安全库存设置的教程

WordPress柔性供应链软件实现动态安全库存设置的教程

引言:为什么需要动态安全库存?

在当今快速变化的电商环境中,静态的安全库存设置已经无法满足企业的需求。传统固定安全库存模式往往导致库存积压或缺货风险,影响企业现金流和客户满意度。柔性供应链系统通过动态调整安全库存水平,能够根据实际需求波动、供应链可靠性和市场变化自动优化库存水平,显著降低运营成本并提高服务水平。

本教程将详细介绍如何在WordPress环境中实现动态安全库存设置,通过完整的代码示例和分步指导,帮助您构建智能化的库存管理系统。

环境准备与插件选择

1. 系统要求

  • WordPress 5.0或更高版本
  • PHP 7.4或更高版本
  • MySQL 5.6或更高版本
  • WooCommerce插件(如果涉及电商功能)

2. 推荐插件

  • Advanced Custom Fields:用于创建自定义库存设置字段
  • WooCommerce:作为电商基础平台(可选)
  • Query Monitor:调试和性能分析

3. 创建自定义插件

首先,我们需要创建一个自定义插件来处理动态安全库存逻辑:

<?php
/**
 * Plugin Name: 柔性供应链动态安全库存系统
 * Plugin URI: https://yourwebsite.com/
 * Description: 为WordPress网站提供动态安全库存管理功能
 * Version: 1.0.0
 * Author: 您的名称
 * License: GPL v2 or later
 */

// 防止直接访问
if (!defined('ABSPATH')) {
    exit;
}

// 定义插件常量
define('FLEXIBLE_SCM_VERSION', '1.0.0');
define('FLEXIBLE_SCM_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('FLEXIBLE_SCM_PLUGIN_URL', plugin_dir_url(__FILE__));

// 初始化插件
add_action('plugins_loaded', 'flexible_scm_init');

function flexible_scm_init() {
    // 检查必要组件
    if (!class_exists('ACF')) {
        add_action('admin_notices', 'flexible_scm_acf_notice');
        return;
    }
    
    // 加载核心功能
    require_once FLEXIBLE_SCM_PLUGIN_DIR . 'includes/class-dynamic-inventory.php';
    require_once FLEXIBLE_SCM_PLUGIN_DIR . 'includes/class-safety-stock-calculator.php';
    
    // 初始化主类
    $dynamic_inventory = new Dynamic_Inventory();
    $dynamic_inventory->init();
}

function flexible_scm_acf_notice() {
    ?>
    <div class="notice notice-error">
        <p>柔性供应链系统需要Advanced Custom Fields插件。请先安装并激活ACF插件。</p>
    </div>
    <?php
}

动态安全库存算法实现

1. 安全库存计算模型

动态安全库存的核心是基于统计学的需求预测模型。以下是基于服务水平法的安全库存计算实现:

<?php
/**
 * 安全库存计算器类
 * 实现动态安全库存算法
 */
class Safety_Stock_Calculator {
    
    /**
     * 计算动态安全库存
     * 
     * @param float $avg_demand 平均日需求量
     * @param float $demand_std 需求标准差
     * @param float $lead_time 平均交货期(天)
     * @param float $lead_time_std 交货期标准差
     * @param float $service_level 服务水平(0-1之间,如0.95表示95%)
     * @return float 计算出的安全库存量
     */
    public function calculate_dynamic_safety_stock($avg_demand, $demand_std, $lead_time, $lead_time_std, $service_level) {
        
        // 验证输入参数
        if ($avg_demand <= 0 || $lead_time <= 0 || $service_level <= 0 || $service_level >= 1) {
            throw new InvalidArgumentException('无效的输入参数');
        }
        
        // 计算Z值(基于服务水平的标准正态分布分位数)
        $z_score = $this->calculate_z_score($service_level);
        
        // 计算联合标准差(考虑需求和交货期的波动性)
        $combined_variance = ($lead_time * pow($demand_std, 2)) + (pow($avg_demand, 2) * pow($lead_time_std, 2));
        $combined_std = sqrt($combined_variance);
        
        // 计算安全库存
        $safety_stock = $z_score * $combined_std;
        
        // 确保安全库存不为负数
        return max(0, round($safety_stock, 2));
    }
    
    /**
     * 计算Z分数(标准正态分布的分位数)
     * 使用近似公式计算,避免依赖统计库
     * 
     * @param float $probability 概率值(0-1)
     * @return float Z分数
     */
    private function calculate_z_score($probability) {
        // 使用Hastings近似公式计算Z分数
        if ($probability <= 0 || $probability >= 1) {
            return 0;
        }
        
        // 对于常见的服务水平,使用预定义值提高性能
        $common_z_scores = [
            0.90 => 1.28,
            0.95 => 1.65,
            0.99 => 2.33
        ];
        
        if (isset($common_z_scores[$probability])) {
            return $common_z_scores[$probability];
        }
        
        // 使用近似公式计算
        $t = sqrt(log(1 / pow($probability, 2)));
        $c0 = 2.515517;
        $c1 = 0.802853;
        $c2 = 0.010328;
        $d1 = 1.432788;
        $d2 = 0.189269;
        $d3 = 0.001308;
        
        $z = $t - (($c0 + $c1 * $t + $c2 * pow($t, 2)) / 
                   (1 + $d1 * $t + $d2 * pow($t, 2) + $d3 * pow($t, 3)));
        
        return $probability > 0.5 ? $z : -$z;
    }
    
    /**
     * 基于历史销售数据计算需求统计
     * 
     * @param array $sales_data 历史销售数据数组
     * @return array 包含平均需求和标准差的数组
     */
    public function calculate_demand_statistics($sales_data) {
        if (empty($sales_data) || count($sales_data) < 2) {
            return ['avg' => 0, 'std' => 0];
        }
        
        $n = count($sales_data);
        $sum = array_sum($sales_data);
        $avg = $sum / $n;
        
        // 计算标准差
        $variance_sum = 0;
        foreach ($sales_data as $value) {
            $variance_sum += pow($value - $avg, 2);
        }
        $std = sqrt($variance_sum / ($n - 1));
        
        return [
            'avg' => round($avg, 2),
            'std' => round($std, 2)
        ];
    }
}

WordPress集成实现

1. 创建产品库存管理界面

/**
 * 动态库存管理主类
 */
class Dynamic_Inventory {
    
    public function init() {
        // 添加管理菜单
        add_action('admin_menu', [$this, 'add_admin_menu']);
        
        // 添加产品自定义字段
        add_action('acf/init', [$this, 'add_product_inventory_fields']);
        
        // 覆盖WooCommerce库存管理(如果启用)
        if (class_exists('WooCommerce')) {
            add_filter('woocommerce_product_get_stock_quantity', [$this, 'adjust_stock_quantity'], 10, 2);
            add_action('woocommerce_product_options_inventory_product_data', [$this, 'add_inventory_settings']);
        }
        
        // 定期重新计算安全库存
        add_action('flexible_scm_daily_cron', [$this, 'recalculate_safety_stocks']);
    }
    
    /**
     * 添加管理菜单
     */
    public function add_admin_menu() {
        add_menu_page(
            '动态库存管理',
            '动态库存',
            'manage_options',
            'dynamic-inventory',
            [$this, 'render_admin_page'],
            'dashicons-chart-line',
            56
        );
    }
    
    /**
     * 渲染管理页面
     */
    public function render_admin_page() {
        ?>
        <div class="wrap">
            <h1>动态安全库存管理系统</h1>
            
            <div class="card">
                <h2>系统概览</h2>
                <p>当前系统状态:<span class="status-active">运行中</span></p>
                
                <div class="stats-container">
                    <div class="stat-box">
                        <h3>已监控产品</h3>
                        <p class="stat-number"><?php echo $this->get_monitored_product_count(); ?></p>
                    </div>
                    <div class="stat-box">
                        <h3>平均安全库存水平</h3>
                        <p class="stat-number"><?php echo $this->get_avg_safety_stock(); ?> 单位</p>
                    </div>
                    <div class="stat-box">
                        <h3>缺货风险降低</h3>
                        <p class="stat-number"><?php echo $this->get_stockout_reduction(); ?>%</p>
                    </div>
                </div>
            </div>
            
            <div class="card">
                <h2>批量重新计算</h2>
                <button id="recalculate-all" class="button button-primary">重新计算所有产品安全库存</button>
                <div id="recalculation-progress" style="display:none; margin-top:10px;">
                    <p>处理中... <span id="progress-percentage">0%</span></p>
                    <div class="progress-bar">
                        <div class="progress-fill" style="width:0%"></div>
                    </div>
                </div>
            </div>
        </div>
        
        <style>
            .stat-box {
                display: inline-block;
                width: 30%;
                padding: 15px;
                margin: 10px;
                background: #f5f5f5;
                border-radius: 5px;
                text-align: center;
            }
            .stat-number {
                font-size: 24px;
                font-weight: bold;
                color: #0073aa;
            }
            .progress-bar {
                width: 100%;
                height: 20px;
                background: #ddd;
                border-radius: 10px;
                overflow: hidden;
            }
            .progress-fill {
                height: 100%;
                background: #0073aa;
                transition: width 0.3s;
            }
        </style>
        
        <script>
        jQuery(document).ready(function($) {
            $('#recalculate-all').click(function() {
                $('#recalculation-progress').show();
                recalculateBatch(0);
            });
            
            function recalculateBatch(offset) {
                $.post(ajaxurl, {
                    action: 'recalculate_safety_stock_batch',
                    offset: offset,
                    nonce: '<?php echo wp_create_nonce("recalculate_batch"); ?>'
                }, function(response) {
                    if (response.success) {
                        var percentage = Math.round((response.data.processed / response.data.total) * 100);
                        $('#progress-percentage').text(percentage + '%');
                        $('.progress-fill').css('width', percentage + '%');
                        
                        if (response.data.completed) {
                            alert('重新计算完成!');
                            $('#recalculation-progress').hide();
                        } else {
                            recalculateBatch(response.data.next_offset);
                        }
                    }
                });
            }
        });
        </script>
        <?php
    }
    
    /**
     * 添加产品库存自定义字段
     */
    public function add_product_inventory_fields() {
        if (function_exists('acf_add_local_field_group')) {
            acf_add_local_field_group([
                'key' => 'group_dynamic_inventory',
                'title' => '动态库存设置',
                'fields' => [
                    [
                        'key' => 'field_enable_dynamic_stock',
                        'label' => '启用动态安全库存',
                        'name' => 'enable_dynamic_stock',
                        'type' => 'true_false',
                        'instructions' => '启用后系统将自动计算和调整安全库存',
                        'default_value' => 1
                    ],
                    [
                        'key' => 'field_target_service_level',
                        'label' => '目标服务水平',
                        'name' => 'target_service_level',
                        'type' => 'number',
                        'instructions' => '期望的服务水平(0-1之间,如0.95表示95%)',
                        'min' => 0.5,
                        'max' => 0.99,
                        'step' => 0.01,
                        'default_value' => 0.95
                    ],
                    [
                        'key' => 'field_lead_time_days',
                        'label' => '平均交货期(天)',
                        'name' => 'lead_time_days',
                        'type' => 'number',
                        'instructions' => '从下单到收货的平均时间',
                        'min' => 1,
                        'default_value' => 7
                    ],
                    [
                        'key' => 'field_lead_time_std',
                        'label' => '交货期标准差',
                        'name' => 'lead_time_std',
                        'type' => 'number',
                        'instructions' => '交货期的波动程度',
                        'min' => 0,
                        'default_value' => 2
                    ]
                ],
                'location' => [
                    [
                        [
                            'param' => 'post_type',
                            'operator' => '==',
                            'value' => 'product',
                        ],
                    ],
                ],
            ]);
        }
    }
}

数据收集与自动化处理

1. 销售数据收集器

/**
 * 销售数据收集与分析类
 */
class Sales_Data_Collector {
    
    private $calculator;
    
    public function __construct() {
        $this->calculator = new Safety_Stock_Calculator();
    }
    
    /**
     * 收集产品历史销售数据
     * 
     * @param int $product_id 产品ID
     * @param int $days 回溯天数
     * @return array 销售数据数组
     */
    public function collect_sales_data($product_id, $days = 90) {
        global $wpdb;
        
        $start_date = date('Y-m-d', strtotime("-{$days} days"));
        
        // 查询销售数据
        $query = $wpdb->prepare("
            SELECT 
                DATE(post_date) as sale_date,
                SUM(meta_value) as daily_quantity
            FROM {$wpdb->prefix}posts p
            INNER JOIN {$wpdb->prefix}woocommerce_order_items oi ON p.ID = oi.order_id
            INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta oim ON oi.order_item_id = oim.order_item_id
            WHERE p.post_type = 'shop_order'
            AND p.post_status IN ('wc-completed', 'wc-processing')
            AND oi.order_item_type = 'line_item'
            AND oim.meta_key = '_product_id'
            AND oim.meta_value = %d
            AND p.post_date >= %s
            GROUP BY DATE(p.post_date)
            ORDER BY sale_date ASC
        ", $product_id, $start_date);
        
        $results = $wpdb->get_results($query);
        
        $sales_data = [];
        foreach ($results as $row) {
            $sales_data[] = (float) $row->daily_quantity;
        }
        
        return $sales_data;
    }
    
    /**
     * 更新产品安全库存
     * 
     * @param int $product_id 产品ID
     * @return bool 是否成功更新
     */
    public function update_product_safety_stock($product_id) {
        // 检查是否启用动态库存
        $enable_dynamic = get_field('enable_dynamic_stock', $product_id);
        if (!$enable_dynamic) {
            return false;
        }
        
        // 收集销售数据
        $sales_data = $this->collect_sales_data($product_id);
        
        if (count($sales_data) < 7) {
            // 数据不足,使用默认值
            return false;
        }
        
        // 计算需求统计
        $demand_stats = $this->calculator->calculate_demand_statistics($sales_data);
        
        // 获取产品设置
        $service_level = get_field('target_service_level', $product_id) ?: 0.95;
        $lead_time = get_field('lead_time_days', $product_id) ?: 7;
        $lead_time_std = get_field('lead_time_std', $product_id) ?: 2;
        
        // 计算安全库存
        $safety_stock = $this->calculator->calculate_dynamic_safety_stock(
            $demand_stats['avg'],
            $demand_stats['std'],
            $lead_time,
            $lead_time_std,
            $service_level
        );
        
        // 保存安全库存值
        update_post_meta($product_id, '_dynamic_safety_stock', $safety_stock);
        update_post_meta($product_id, '_last_safety_stock_calculation', current_time('mysql'));
        
        // 更新WooCommerce库存阈值(如果适用)
        if (class_exists('WooCommerce')) {
            $product = wc_get_product($product_id);
            if ($product && $product->managing_stock()) {
                // 设置低库存阈值
                $product->set_low_stock_amount($safety_stock);
                $product->save();
            }
        }
        
        return true;
    }
}

部署与优化建议

1. 性能优化策略

/**
 * 性能优化与缓存管理
 */
class Inventory_Performance_Optimizer {
    
    /**
     * 实现缓存机制,减少数据库查询
     */
    public static function get_cached_safety_stock($product_id) {
        $cache_key = 'safety_stock_' . $product_id;
        $cached_value = wp_cache_get($cache_key, 'dynamic_inventory');
        
        if (false !== $cached_value) {
            return $cached_value;
        }
        
        // 从数据库获取
        $safety_stock = get_post_meta($product_id, '_dynamic_safety_stock', true);
        
        if ('' === $safety_stock) {
            // 如果不存在,计算并保存
            $collector = new Sales_Data_Collector();
            $collector->update_product_safety_stock($product_id);
            $safety_stock = get_post_meta($product_id, '_dynamic_safety_stock', true);
        }
        
        // 缓存12小时
        wp_cache_set($cache_key, $safety_stock, 'dynamic_inventory', 12 * HOUR_IN_SECONDS);
        
        return $safety_stock;
    }
    
    /**
     * 批量处理优化
     */
    public static function batch_update_safety_stocks($product_ids, $batch_size = 50) {
        $results = [
            'success' => 0,
            'failed' => 0,
            'skipped' => 0
        ];
        
        $collector = new Sales_Data_Collector();
        
        foreach (array_chunk($product_ids, $batch_size) as $chunk) {
            foreach ($chunk as $product_id) {
                // 检查是否启用动态库存
                if (!get_field('enable_dynamic_stock', $product_id)) {
                    $results['skipped']++;
                    continue;
                }
                
                try {
                    if ($collector->update_product_safety_stock($product_id)) {
                        $results['success']++;
                    } else {
                        $results['failed']++;
                    }
                } catch (Exception $e) {
                    error_log('安全库存更新失败 - 产品ID: ' . $product_id . ' - 错误: ' . $e->getMessage());
                    $results['failed']++;
                }
            }
            
            // 每批处理后暂停,减少服务器负载
            usleep(100000); // 0.1秒
        }
        
        return $results;
    }
}

2. 自动化调度系统

/**
 * 自动化任务调度器
 */
class Inventory_Scheduler {
    
    public function init() {
        // 注册定时任务
        add_filter('cron_schedules', [$this, 'add_custom_schedules']);
        add_action('init', [$this, 'schedule_events']);
    }
    
    /**
     * 添加自定义调度间隔
     */
    public function add_custom_schedules($schedules) {
        $schedules['six_hours'] = [
            'interval' => 6 * HOUR_IN_SECONDS,
            'display'  => __('每6小时')
        ];
        
        $schedules['weekly'] = [
            'interval' => 7 * DAY_IN_SECONDS,
            'display'  => __('每周')
        ];
        
        return $schedules;
    }
    
    /**
     * 安排定时事件
     */
    public function schedule_events() {
        if (!wp_next_scheduled('flexible_scm_daily_calculation')) {
            wp_schedule_event(time(), 'daily', 'flexible_scm_daily_calculation');
        }
        
        if (!wp_next_scheduled('flexible_scm_weekly_report')) {
            wp_schedule_event(time(), 'weekly', 'flexible_scm_weekly_report');
        }
        
        // 绑定事件处理函数
        add_action('flexible_scm_daily_calculation', [$this, 'run_daily_calculations']);
        add_action('flexible_scm_weekly_report', [$this, 'generate_weekly_report']);
    }
    
    /**
     * 执行每日计算任务
     */
    public function run_daily_calculations() {
        global $wpdb;
        
        // 获取所有启用动态库存的产品
        $query = "
            SELECT p.ID 
            FROM {$wpdb->posts} p
            INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
            WHERE p.post_type = 'product'
            AND p.post_status = 'publish'
            AND pm.meta_key = 'enable_dynamic_stock'
            AND pm.meta_value = '1'
            LIMIT 200
        ";
        
        $product_ids = $wpdb->get_col($query);
        
        if (!empty($product_ids)) {
            $optimizer = new Inventory_Performance_Optimizer();
            $results = $optimizer->batch_update_safety_stocks($product_ids);
            
            // 记录执行日志
            $this->log_calculation_results($results);
        }
    }
    
    /**
     * 生成周度报告
     */
    public function generate_weekly_report() {
        global $wpdb;
        
        $report_data = [
            'period' => date('Y-m-d', strtotime('-7 days')) . ' 至 ' . date('Y-m-d'),
            'total_products' => 0,
            'active_products' => 0,
            'avg_safety_stock' => 0,
            'stockout_events' => 0,
            'inventory_turnover' => 0
        ];
        
        // 获取统计数据
        $query = "
            SELECT 
                COUNT(DISTINCT p.ID) as total_products,
                COUNT(DISTINCT CASE WHEN pm.meta_value = '1' THEN p.ID END) as active_products,
                AVG(CAST(pm2.meta_value AS DECIMAL(10,2))) as avg_safety_stock
            FROM {$wpdb->posts} p
            LEFT JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id AND pm.meta_key = 'enable_dynamic_stock'
            LEFT JOIN {$wpdb->postmeta} pm2 ON p.ID = pm2.post_id AND pm2.meta_key = '_dynamic_safety_stock'
            WHERE p.post_type = 'product'
            AND p.post_status = 'publish'
        ";
        
        $stats = $wpdb->get_row($query);
        
        if ($stats) {
            $report_data['total_products'] = $stats->total_products;
            $report_data['active_products'] = $stats->active_products;
            $report_data['avg_safety_stock'] = round($stats->avg_safety_stock, 2);
        }
        
        // 发送报告邮件
        $this->send_report_email($report_data);
    }
    
    /**
     * 记录计算日志
     */
    private function log_calculation_results($results) {
        $log_entry = sprintf(
            "[%s] 安全库存计算完成 - 成功: %d, 失败: %d, 跳过: %d",
            current_time('mysql'),
            $results['success'],
            $results['failed'],
            $results['skipped']
        );
        
        error_log($log_entry);
    }
    
    /**
     * 发送报告邮件
     */
    private function send_report_email($report_data) {
        $to = get_option('admin_email');
        $subject = '柔性供应链系统周度报告 - ' . date('Y-m-d');
        
        $message = "
        <h2>柔性供应链系统周度报告</h2>
        <p>报告周期: {$report_data['period']}</p>
        
        <table border='1' cellpadding='10' style='border-collapse: collapse;'>
            <tr>
                <th>指标</th>
                <th>数值</th>
            </tr>
            <tr>
                <td>总产品数</td>
                <td>{$report_data['total_products']}</td>
            </tr>
            <tr>
                <td>启用动态库存产品数</td>
                <td>{$report_data['active_products']}</td>
            </tr>
            <tr>
                <td>平均安全库存水平</td>
                <td>{$report_data['avg_safety_stock']}</td>
            </tr>
        </table>
        
        <p>报告生成时间: " . current_time('mysql') . "</p>
        ";
        
        $headers = ['Content-Type: text/html; charset=UTF-8'];
        
        wp_mail($to, $subject, $message, $headers);
    }
}

前端展示与用户界面

1. 产品库存状态显示

/**
 * 前端库存显示增强
 */
class Frontend_Inventory_Display {
    
    public function init() {
        // 在产品页面显示动态库存信息
        add_action('woocommerce_single_product_summary', [$this, 'display_safety_stock_info'], 25);
        
        // 在库存管理页面添加列
        add_filter('manage_product_posts_columns', [$this, 'add_inventory_columns']);
        add_action('manage_product_posts_custom_column', [$this, 'render_inventory_columns'], 10, 2);
        
        // 添加库存预警短代码
        add_shortcode('inventory_alert', [$this, 'inventory_alert_shortcode']);
    }
    
    /**
     * 在产品页面显示安全库存信息
     */
    public function display_safety_stock_info() {
        global $product;
        
        if (!$product || !$product->get_id()) {
            return;
        }
        
        $product_id = $product->get_id();
        $enable_dynamic = get_field('enable_dynamic_stock', $product_id);
        
        if (!$enable_dynamic) {
            return;
        }
        
        $safety_stock = Inventory_Performance_Optimizer::get_cached_safety_stock($product_id);
        $current_stock = $product->get_stock_quantity();
        
        if ($current_stock === null) {
            return;
        }
        
        $stock_status = '';
        $stock_class = '';
        
        if ($current_stock <= $safety_stock) {
            $stock_status = '库存预警';
            $stock_class = 'stock-warning';
        } elseif ($current_stock <= $safety_stock * 1.5) {
            $stock_status = '库存适中';
            $stock_class = 'stock-moderate';
        } else {
            $stock_status = '库存充足';
            $stock_class = 'stock-good';
        }
        
        ?>
        <div class="dynamic-inventory-info">
            <h3>库存状态</h3>
            <div class="stock-status <?php echo esc_attr($stock_class); ?>">
                <span class="status-label"><?php echo esc_html($stock_status); ?></span>
                <div class="stock-details">
                    <p>当前库存: <strong><?php echo esc_html($current_stock); ?></strong> 单位</p>
                    <p>安全库存水平: <strong><?php echo esc_html($safety_stock); ?></strong> 单位</p>
                    <p>最后更新: <?php echo esc_html(get_post_meta($product_id, '_last_safety_stock_calculation', true)); ?></p>
                </div>
            </div>
        </div>
        
        <style>
            .dynamic-inventory-info {
                margin: 20px 0;
                padding: 15px;
                border: 1px solid #ddd;
                border-radius: 5px;
                background: #f9f9f9;
            }
            .stock-status {
                padding: 10px;
                border-radius: 4px;
                margin: 10px 0;
            }
            .stock-warning {
                background: #ffe6e6;
                border-left: 4px solid #ff3333;
            }
            .stock-moderate {
                background: #fff9e6;
                border-left: 4px solid #ffcc00;
            }
            .stock-good {
                background: #e6ffe6;
                border-left: 4px solid #33cc33;
            }
            .status-label {
                font-weight: bold;
                font-size: 16px;
            }
            .stock-details {
                margin-top: 10px;
                font-size: 14px;
            }
        </style>
        <?php
    }
    
    /**
     * 添加库存管理列
     */
    public function add_inventory_columns($columns) {
        $new_columns = [];
        
        foreach ($columns as $key => $value) {
            $new_columns[$key] = $value;
            
            if ($key === 'price') {
                $new_columns['safety_stock'] = __('安全库存', 'flexible-scm');
                $new_columns['stock_status'] = __('库存状态', 'flexible-scm');
            }
        }
        
        return $new_columns;
    }
    
    /**
     * 渲染库存管理列
     */
    public function render_inventory_columns($column, $product_id) {
        if ($column === 'safety_stock') {
            $enable_dynamic = get_field('enable_dynamic_stock', $product_id);
            
            if ($enable_dynamic) {
                $safety_stock = get_post_meta($product_id, '_dynamic_safety_stock', true);
                echo $safety_stock ? esc_html($safety_stock) : '<em>未计算</em>';
            } else {
                echo '<em>未启用</em>';
            }
        }
        
        if ($column === 'stock_status') {
            $product = wc_get_product($product_id);
            $current_stock = $product->get_stock_quantity();
            
            if ($current_stock !== null) {
                $safety_stock = get_post_meta($product_id, '_dynamic_safety_stock', true);
                
                if ($current_stock <= $safety_stock) {
                    echo '<span style="color: #ff3333; font-weight: bold;">⚠️ 预警</span>';
                } elseif ($current_stock <= $safety_stock * 1.5) {
                    echo '<span style="color: #ffcc00;">⚠️ 注意</span>';
                } else {
                    echo '<span style="color: #33cc33;">✓ 正常</span>';
                }
            }
        }
    }
    
    /**
     * 库存预警短代码
     */
    public function inventory_alert_shortcode($atts) {
        $atts = shortcode_atts([
            'category' => '',
            'limit' => 10,
            'show_all' => false
        ], $atts);
        
        $args = [
            'post_type' => 'product',
            'posts_per_page' => intval($atts['limit']),
            'meta_query' => [
                [
                    'key' => 'enable_dynamic_stock',
                    'value' => '1',
                    'compare' => '='
                ]
            ]
        ];
        
        if (!empty($atts['category'])) {
            $args['tax_query'] = [
                [
                    'taxonomy' => 'product_cat',
                    'field' => 'slug',
                    'terms' => $atts['category']
                ]
            ];
        }
        
        $products = new WP_Query($args);
        
        if (!$products->have_posts()) {
            return '<p>暂无库存预警产品</p>';
        }
        
        $output = '<div class="inventory-alert-list">';
        $output .= '<h3>库存预警产品</h3>';
        $output .= '<table class="inventory-alert-table">';
        $output .= '<thead><tr><th>产品名称</th><th>当前库存</th><th>安全库存</th><th>状态</th></tr></thead>';
        $output .= '<tbody>';
        
        while ($products->have_posts()) {
            $products->the_post();
            $product_id = get_the_ID();
            $product = wc_get_product($product_id);
            $current_stock = $product->get_stock_quantity();
            $safety_stock = get_post_meta($product_id, '_dynamic_safety_stock', true);
            
            if ($atts['show_all'] || $current_stock <= $safety_stock) {
                $status = $current_stock <= $safety_stock ? '预警' : '正常';
                $status_class = $current_stock <= $safety_stock ? 'alert' : 'normal';
                
                $output .= sprintf(
                    '<tr class="%s">
                        <td><a href="%s">%s</a></td>
                        <td>%s</td>
                        <td>%s</td>
                        <td><span class="status-%s">%s</span></td>
                    </tr>',
                    esc_attr($status_class),
                    get_permalink(),
                    get_the_title(),
                    esc_html($current_stock),
                    esc_html($safety_stock),
                    esc_attr($status_class),
                    esc_html($status)
                );
            }
        }
        
        wp_reset_postdata();
        
        $output .= '</tbody></table></div>';
        
        $output .= '
        <style>
            .inventory-alert-table {
                width: 100%;
                border-collapse: collapse;
                margin: 15px 0;
            }
            .inventory-alert-table th,
            .inventory-alert-table td {
                padding: 10px;
                border: 1px solid #ddd;
                text-align: left;
            }
            .inventory-alert-table th {
                background: #f5f5f5;
                font-weight: bold;
            }
            .inventory-alert-table tr.alert {
                background: #ffe6e6;
            }
            .inventory-alert-table tr.normal {
                background: #e6ffe6;
            }
            .status-alert {
                color: #ff3333;
                font-weight: bold;
            }
            .status-normal {
                color: #33cc33;
            }
        </style>';
        
        return $output;
    }
}

系统测试与验证

1. 单元测试类

/**
 * 系统测试类
 */
class Flexible_SCM_Test {
    
    /**
     * 运行所有测试
     */
    public static function run_all_tests() {
        $results = [
            'calculator' => self::test_calculator(),
            'data_collection' => self::test_data_collection(),
            'performance' => self::test_performance(),
            'integration' => self::test_integration()
        ];
        
        return $results;
    }
    
    /**
     * 测试安全库存计算器
     */
本文来自网络,不代表柔性供应链服务中心立场,转载请注明出处:https://mall.org.cn/6485.html

EXCHANGES®作者

上一篇
下一篇

为您推荐

发表回复

联系我们

联系我们

18559313275

在线咨询: QQ交谈

邮箱: vip@exchanges.center

工作时间:周一至周五,9:00-17:30,节假日休息
返回顶部