引言

呆滞库存是企业的隐形杀手,占用资金、浪费空间、影响现金流。本文将探讨呆滞库存的识别、预警和处理方法。


1. 呆滞库存定义

1.1 分类标准

呆滞库存

  • 定义:90天无销售
  • 占比:一般不超过总库存的10%

死库存

  • 定义:180天无销售
  • 占比:应控制在5%以内

1.2 呆滞率计算

呆滞率 = 呆滞库存金额 / 总库存金额 × 100%

示例:
总库存金额:1000万元
呆滞库存金额:80万元
呆滞率 = 80 / 1000 × 100% = 8%

1.3 Java实现

public class ObsoleteInventoryAnalyzer {

    public Map<String, BigDecimal> analyzeObsoleteRate() {
        // 1. 获取所有库存
        List<Inventory> all = inventoryMapper.selectAll();

        BigDecimal totalValue = all.stream()
            .map(inv -> inv.getAvailableQty() * inv.getUnitCost())
            .map(BigDecimal::valueOf)
            .reduce(BigDecimal.ZERO, BigDecimal::add);

        // 2. 识别呆滞库存
        List<Inventory> obsolete = identifyObsolete(all, 90);

        BigDecimal obsoleteValue = obsolete.stream()
            .map(inv -> inv.getAvailableQty() * inv.getUnitCost())
            .map(BigDecimal::valueOf)
            .reduce(BigDecimal.ZERO, BigDecimal::add);

        // 3. 计算呆滞率
        BigDecimal rate = obsoleteValue.divide(totalValue, 4, RoundingMode.HALF_UP)
            .multiply(new BigDecimal("100"));

        Map<String, BigDecimal> result = new HashMap<>();
        result.put("totalValue", totalValue);
        result.put("obsoleteValue", obsoleteValue);
        result.put("obsoleteRate", rate);

        return result;
    }

    private List<Inventory> identifyObsolete(List<Inventory> inventories, int days) {
        LocalDate threshold = LocalDate.now().minusDays(days);

        return inventories.stream()
            .filter(inv -> {
                LocalDate lastSaleDate = salesDataService.getLastSaleDate(inv.getSku());
                return lastSaleDate != null && lastSaleDate.isBefore(threshold);
            })
            .collect(Collectors.toList());
    }
}

2. 呆滞预警

2.1 预警级别

一级预警(黄色)

  • 条件:60天无销售
  • 动作:关注监控

二级预警(橙色)

  • 条件:90天无销售
  • 动作:启动促销

三级预警(红色)

  • 条件:180天无销售
  • 动作:报废处理

2.2 预警实现

@Component
public class ObsoleteAlertTask {

    @Scheduled(cron = "0 0 2 1 * ?")  // 每月1日凌晨2点
    public void checkObsoleteAlert() {
        log.info("开始呆滞库存检查");

        List<Inventory> inventories = inventoryMapper.selectAll();
        LocalDate today = LocalDate.now();

        for (Inventory inventory : inventories) {
            LocalDate lastSaleDate = salesDataService.getLastSaleDate(inventory.getSku());

            if (lastSaleDate == null) continue;

            long daysSinceLastSale = ChronoUnit.DAYS.between(lastSaleDate, today);

            AlertLevel level = null;
            if (daysSinceLastSale >= 180) {
                level = AlertLevel.RED;
            } else if (daysSinceLastSale >= 90) {
                level = AlertLevel.ORANGE;
            } else if (daysSinceLastSale >= 60) {
                level = AlertLevel.YELLOW;
            }

            if (level != null) {
                sendAlert(inventory, level, daysSinceLastSale);
                handleByLevel(inventory, level);
            }
        }

        log.info("呆滞库存检查完成");
    }

    private void handleByLevel(Inventory inventory, AlertLevel level) {
        switch (level) {
            case YELLOW:
                // 关注监控,暂不处理
                break;
            case ORANGE:
                // 启动促销
                startPromotion(inventory);
                break;
            case RED:
                // 建议报废
                suggestDisposal(inventory);
                break;
        }
    }
}

3. 呆滞处理

3.1 促销清仓

打折促销

public void createClearanceSale(String sku, int daysSinceLastSale) {
    // 根据呆滞天数确定折扣
    BigDecimal discount;
    if (daysSinceLastSale >= 180) {
        discount = new BigDecimal("0.3");  // 3折
    } else if (daysSinceLastSale >= 120) {
        discount = new BigDecimal("0.5");  // 5折
    } else {
        discount = new BigDecimal("0.7");  // 7折
    }

    Product product = productService.getBySku(sku);
    BigDecimal originalPrice = product.getPrice();
    BigDecimal salePrice = originalPrice.multiply(discount);

    Promotion promo = new Promotion();
    promo.setSku(sku);
    promo.setType("CLEARANCE");
    promo.setOriginalPrice(originalPrice);
    promo.setSalePrice(salePrice);
    promo.setStartDate(LocalDate.now());
    promo.setEndDate(LocalDate.now().plusDays(30));

    promotionService.create(promo);

    log.info("已创建清仓促销: sku={}, discount={}, salePrice={}",
        sku, discount, salePrice);
}

买一赠一

public void createBuyOneGetOne(String sku) {
    Promotion promo = new Promotion();
    promo.setSku(sku);
    promo.setType("BUY_ONE_GET_ONE");
    promo.setStartDate(LocalDate.now());
    promo.setEndDate(LocalDate.now().plusDays(14));

    promotionService.create(promo);
}

捆绑销售

public void createBundle(String obsoleteSku, String popularSku) {
    // 呆滞商品与畅销商品捆绑
    Bundle bundle = new Bundle();
    bundle.setMainSku(popularSku);
    bundle.setGiftSku(obsoleteSku);
    bundle.setPrice(productService.getPrice(popularSku));  // 不加价

    bundleService.create(bundle);
}

3.2 渠道转移

线上→线下

- 线上滞销 → 线下门店促销
- 适用:服装、家居等

一线城市→二三线城市

- 一线滞销 → 二三线促销
- 适用:时尚品、潮品

3.3 退货/换货

与供应商协商退货

public void negotiateReturn(String sku) {
    Supplier supplier = supplierService.getSupplier(sku);
    Inventory inventory = inventoryService.getBySku(sku);

    ReturnRequest request = new ReturnRequest();
    request.setSku(sku);
    request.setQuantity(inventory.getAvailableQty());
    request.setReason("OBSOLETE");
    request.setSupplier(supplier);

    // 根据合同条款判断是否可退货
    if (supplier.getAllowReturn() && inventory.getDaysSinceInbound() <= 90) {
        request.setStatus("PENDING");
        returnRequestService.create(request);
    } else {
        log.warn("不符合退货条件: sku={}", sku);
    }
}

以旧换新

- 旧品回收
- 新品折扣
- 适用:电子产品、家电

3.4 报废处理

过期商品

public void disposeExpired() {
    List<Inventory> expired = inventoryMapper.selectExpired();

    for (Inventory inventory : expired) {
        // 创建报废单
        DisposalOrder order = new DisposalOrder();
        order.setSku(inventory.getSku());
        order.setQuantity(inventory.getAvailableQty());
        order.setReason("EXPIRED");
        order.setCost(inventory.getUnitCost().multiply(
            BigDecimal.valueOf(inventory.getAvailableQty())
        ));

        disposalService.create(order);

        // 扣减库存
        inventoryService.deduct(inventory.getSku(), inventory.getAvailableQty());

        log.info("已报废过期商品: sku={}, qty={}",
            inventory.getSku(), inventory.getAvailableQty());
    }
}

破损商品

- 质检不合格
- 损坏无法销售
- 报废或折价处理

4. 损失控制

4.1 事前控制

精准预测

- 提高预测准确率
- 减少预测偏差
- 降低积压风险

小批量采购

- 首单小批量测试
- 验证市场需求
- 避免大量积压

4.2 事中控制

动态监控

@Component
public class InventoryMonitor {

    @Scheduled(fixedRate = 3600000)  // 每小时
    public void monitorSalesVelocity() {
        List<Product> newProducts = productService.listNew(30);  // 上架30天内

        for (Product product : newProducts) {
            // 计算销售速度
            int soldQty = salesDataService.getSoldQty(product.getSku(), 7);
            int stockQty = inventoryService.getAvailableQty(product.getSku());

            double salesVelocity = soldQty / 7.0;  // 日均销量
            int daysToSellOut = (int) (stockQty / salesVelocity);

            if (daysToSellOut > 90) {
                // 预计90天卖不完,发送预警
                alertService.send(String.format(
                    "新品滞销风险: SKU %s, 预计%d天售罄",
                    product.getSku(), daysToSellOut
                ));

                // 建议促销
                promotionService.suggest(product.getSku());
            }
        }
    }
}

及时预警

- 60天预警
- 90天促销
- 180天报废

4.3 事后控制

快速清仓

- 大幅折扣
- 限时抢购
- 快速去化

止损离场

- 不再追加投入
- 接受损失
- 及时止损

5. 实战案例:服装行业的呆滞处理

5.1 业务背景

服装行业季节性强,过季商品容易积压。

5.2 处理策略

反季促销

- 冬装夏季清仓
- 夏装冬季清仓
- 折扣:3-5折

奥特莱斯

- 专门的折扣店
- 品牌授权
- 常年促销

尾货市场

- 批发给尾货商
- 快速回笼资金
- 减少损失

5.3 优化成果

ZARA的呆滞率:< 5%
传统品牌:15-20%

核心策略:
- 小批量生产
- 快速周转
- 及时下架滞销款

6. 呆滞处理决策树

public class ObsoleteHandlingDecisionEngine {

    public String suggest(Inventory inventory) {
        int daysSinceLastSale = getDaysSinceLastSale(inventory);
        BigDecimal unitCost = inventory.getUnitCost();
        int quantity = inventory.getAvailableQty();

        // 180天以上 → 报废
        if (daysSinceLastSale >= 180) {
            return "DISPOSAL";
        }

        // 120-180天 → 深度促销
        if (daysSinceLastSale >= 120) {
            if (unitCost.compareTo(new BigDecimal("50")) < 0) {
                return "DEEP_DISCOUNT";  // 低价商品:3折
            } else {
                return "RETURN_TO_SUPPLIER";  // 高价商品:尝试退货
            }
        }

        // 90-120天 → 促销
        if (daysSinceLastSale >= 90) {
            if (quantity > 100) {
                return "BUNDLE_SALE";  // 数量多:捆绑销售
            } else {
                return "MODERATE_DISCOUNT";  // 数量少:7折促销
            }
        }

        // 60-90天 → 关注
        return "MONITOR";
    }
}

7. 总结

呆滞库存管理是库存优化的重要环节,需要提前预防、及时发现、快速处理。

核心要点

  1. 定义:90天无销售=呆滞,180天无销售=死库存
  2. 预警:60天黄色、90天橙色、180天红色
  3. 处理:促销清仓、渠道转移、退货换货、报废处理
  4. 控制:事前预防、事中监控、事后止损

库存管理专题的5篇基础文章至此完成!在下一个系列中,我们将探讨供应链系统集成,敬请期待!