一、功能概述
损耗统计功能是生鲜供应链管理系统中的核心模块,旨在通过数字化手段精确追踪生鲜商品从采购到销售全链条的损耗情况,帮助企业优化库存管理、减少浪费、提升利润。
二、核心功能设计
1. 损耗类型定义
- 自然损耗:水分蒸发、腐烂变质等
- 操作损耗:分拣损坏、包装破损等
- 运输损耗:碰撞损坏、温度失控等
- 库存损耗:过期报废、盘点差异等
- 销售损耗:退货损坏、顾客挑选损坏等
2. 数据采集点
- 采购环节:验收数量与订单数量差异
- 仓储环节:库存盘点差异、保质期预警报废
- 分拣环节:分拣前后重量/数量变化
- 配送环节:装车前后数量核对
- 销售环节:退货处理、报损申请
3. 统计维度
- 按商品类别:蔬菜、水果、肉类等
- 按时间维度:日/周/月/季度损耗报告
- 按环节维度:采购、仓储、分拣、配送、销售
- 按供应商维度:不同供应商商品损耗率对比
- 按门店维度:各门店损耗情况排名
三、技术实现方案
1. 数据库设计
```sql
-- 损耗记录表
CREATE TABLE loss_records (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
record_no VARCHAR(32) NOT NULL COMMENT 损耗单号,
business_type TINYINT NOT NULL COMMENT 业务类型:1采购2仓储3分拣4配送5销售,
commodity_id BIGINT NOT NULL COMMENT 商品ID,
commodity_name VARCHAR(100) NOT NULL COMMENT 商品名称,
category_id BIGINT NOT NULL COMMENT 品类ID,
quantity DECIMAL(10,3) NOT NULL COMMENT 损耗数量,
unit VARCHAR(10) NOT NULL COMMENT 单位,
weight DECIMAL(10,3) COMMENT 损耗重量(kg),
loss_type TINYINT NOT NULL COMMENT 损耗类型:1自然2操作3运输4库存5销售,
loss_reason VARCHAR(255) COMMENT 损耗原因,
operator_id BIGINT NOT NULL COMMENT 操作人ID,
operator_name VARCHAR(50) NOT NULL COMMENT 操作人姓名,
related_no VARCHAR(32) COMMENT 关联单号(如采购单号、配送单号等),
loss_amount DECIMAL(12,2) COMMENT 损耗金额,
status TINYINT DEFAULT 1 COMMENT 状态:1正常2作废,
create_time DATETIME NOT NULL COMMENT 创建时间,
update_time DATETIME NOT NULL COMMENT 更新时间
);
-- 损耗统计表(每日汇总)
CREATE TABLE loss_statistics_daily (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
stat_date DATE NOT NULL COMMENT 统计日期,
warehouse_id BIGINT COMMENT 仓库ID,
store_id BIGINT COMMENT 门店ID,
category_id BIGINT COMMENT 品类ID,
total_loss_quantity DECIMAL(12,3) COMMENT 总损耗数量,
total_loss_weight DECIMAL(12,3) COMMENT 总损耗重量,
total_loss_amount DECIMAL(12,2) COMMENT 总损耗金额,
loss_rate DECIMAL(5,2) COMMENT 损耗率(%),
create_time DATETIME NOT NULL COMMENT 创建时间
);
```
2. 关键业务流程实现
采购验收损耗统计
```java
public void recordPurchaseLoss(PurchaseOrder order, List
actualItems) {
for (PurchaseItem orderItem : order.getItems()) {
PurchaseItem actualItem = findActualItem(actualItems, orderItem.getCommodityId());
if (actualItem != null) {
BigDecimal expectedQty = orderItem.getQuantity();
BigDecimal actualQty = actualItem.getQuantity();
if (actualQty.compareTo(expectedQty) < 0) {
BigDecimal lossQty = expectedQty.subtract(actualQty);
// 记录损耗
LossRecord record = new LossRecord();
record.setBusinessType(LossBusinessType.PURCHASE);
record.setCommodityId(orderItem.getCommodityId());
record.setQuantity(lossQty);
record.setLossType(LossType.NATURAL); // 默认自然损耗,可修改
record.setRelatedNo(order.getOrderNo());
record.setLossAmount(calculateLossAmount(orderItem, lossQty));
lossRecordService.save(record);
}
}
}
}
```
仓储盘点损耗统计
```java
public void recordInventoryLoss(InventoryCheck check) {
for (InventoryCheckItem item : check.getItems()) {
BigDecimal systemQty = item.getSystemQuantity();
BigDecimal actualQty = item.getActualQuantity();
if (actualQty.compareTo(systemQty) != 0) {
BigDecimal lossQty = systemQty.subtract(actualQty);
LossRecord record = new LossRecord();
record.setBusinessType(LossBusinessType.INVENTORY);
record.setCommodityId(item.getCommodityId());
record.setQuantity(lossQty);
record.setLossType(LossType.INVENTORY); // 库存损耗
record.setRelatedNo(check.getCheckNo());
record.setLossAmount(calculateLossAmount(item, lossQty));
lossRecordService.save(record);
}
}
}
```
3. 损耗率计算服务
```java
@Service
public class LossRateCalculator {
@Autowired
private LossRecordRepository lossRecordRepository;
@Autowired
private PurchaseOrderRepository purchaseOrderRepository;
@Autowired
private SalesOrderRepository salesOrderRepository;
// 计算某商品在指定时间段的损耗率
public BigDecimal calculateLossRate(Long commodityId, Date startDate, Date endDate) {
// 获取采购总量
BigDecimal totalPurchase = purchaseOrderRepository.sumQuantityByCommodityAndDate(commodityId, startDate, endDate);
if (totalPurchase.compareTo(BigDecimal.ZERO) == 0) {
return BigDecimal.ZERO;
}
// 获取损耗总量
BigDecimal totalLoss = lossRecordRepository.sumQuantityByCommodityAndDate(commodityId, startDate, endDate);
// 损耗率 = 损耗量 / 采购量 * 100%
return totalLoss.divide(totalPurchase, 4, RoundingMode.HALF_UP)
.multiply(new BigDecimal("100"))
.setScale(2, RoundingMode.HALF_UP);
}
// 计算门店综合损耗率
public BigDecimal calculateStoreLossRate(Long storeId, Date date) {
// 实现类似逻辑...
}
}
```
四、前端展示方案
1. 损耗看板
- 关键指标:
- 当日总损耗金额
- 当日损耗率
- 环比/同比变化
- 损耗率排名(品类/门店)
2. 损耗明细查询
- 支持按时间、品类、门店、供应商等条件筛选
- 显示每笔损耗的详细信息:商品、数量、金额、原因、操作人等
3. 损耗趋势分析
- 折线图展示损耗率历史趋势
- 柱状图对比不同品类/门店的损耗情况
- 饼图展示损耗原因分布
五、系统集成与扩展
1. 与采购系统集成:自动获取采购订单信息作为损耗计算基准
2. 与库存系统集成:实时获取库存变动数据
3. 与销售系统集成:获取退货、报损等销售环节损耗数据
4. 预警功能:当某品类损耗率超过阈值时自动预警
5. 报表导出:支持Excel、PDF等多种格式导出
六、实施建议
1. 分阶段实施:
- 第一阶段:实现基础损耗记录功能
- 第二阶段:完善统计分析和报表功能
- 第三阶段:增加预测和预警功能
2. 数据准确性保障:
- 建立严格的数据录入规范
- 增加数据校验机制
- 定期进行数据核对
3. 用户培训:
- 对操作人员进行系统使用培训
- 制定损耗统计标准和流程
4. 持续优化:
- 根据实际使用情况调整损耗类型和统计维度
- 定期分析损耗数据,优化业务流程
通过该功能的实现,美菜生鲜系统可以显著提升损耗管理的精细化水平,帮助企业每年减少数百万的损耗成本,同时为采购决策、库存优化等提供有力的数据支持。