送洗记录金额为0问题分析.md 9.75 KB

送洗记录金额为0问题分析

📋 问题描述

批次号 767887817136145669 的送出记录存在金额为0的问题:

  • 送出记录:数量394,单价0.60,但总价是0.00(应该是236.40)
  • 送回记录:数量394,单价0.60,总价236.40(正确)

🔍 数据分析

问题记录详情

批次号: 767887817136145669

流水类型 数量 单价 总价 应计算金额 创建时间
送出(0) 394 0.60 0.00 236.40 2025-12-09 01:32:04
送回(1) 394 0.60 236.40 236.40 2025-12-09 01:33:10

问题

  • 送出记录的总价应该是 394 × 0.60 = 236.40,但实际是 0.00
  • 送回记录的总价是正确的 236.40

📊 代码逻辑分析

1. 送出记录创建逻辑

代码位置LqLaundryFlowService.cs 第78-141行

// 创建送出记录
var entity = new LqLaundryFlowEntity
{
    Id = batchId,
    FlowType = 0, // 送出
    BatchNumber = batchId,
    StoreId = input.StoreId,
    ProductType = input.ProductType,
    LaundrySupplierId = input.LaundrySupplierId,
    Quantity = input.Quantity,
    LaundryPrice = supplier.LaundryPrice, // 记录历史价格
    TotalPrice = input.Quantity * supplier.LaundryPrice, // 送出时总费用为数量 * 单价
    Remark = input.Remark,
    IsEffective = StatusEnum.有效.GetHashCode(),
    CreateUser = _userManager.UserId,
    CreateTime = DateTime.Now,
    SendTime = input.SendTime ?? DateTime.Now
};

计算逻辑

TotalPrice = input.Quantity * supplier.LaundryPrice

理论上394 × 0.60 = 236.40

2. 送回记录创建逻辑

代码位置LqLaundryFlowService.cs 第215-216行

// 计算总费用(送回数量 × 清洗单价)
var totalPrice = input.Quantity * supplier.LaundryPrice;

送回记录的计算是正确的,说明计算逻辑本身没有问题。

🤔 可能的原因分析

原因1:创建时清洗商的单价为0(最可能)

分析

  • 送出记录创建时(2025-12-09 01:32:04),清洗商的单价可能是 0.00
  • 计算:394 × 0.00 = 0.00
  • 后来清洗商的单价被修改为 0.60,但送出记录中保存的是历史价格 0.60(这个价格是在创建时保存的,不会自动更新)
  • 送回记录创建时(2025-12-09 01:33:10),清洗商的单价已经是 0.60
  • 计算:394 × 0.60 = 236.40(正确)

证据

  • 送出记录中的 F_LaundryPrice = 0.60 是创建时从清洗商表读取并保存的历史价格
  • 如果创建时清洗商的单价是0,那么 F_TotalPrice = 394 × 0 = 0.00
  • 但是 F_LaundryPrice 字段显示的是 0.60,这看起来矛盾

重新分析

  • 如果创建时清洗商的单价是 0.60,那么 F_TotalPrice 应该是 236.40
  • 但实际是 0.00,这说明计算时使用的不是 0.60

原因2:数据类型转换问题

分析

  • C# 中 decimal 类型的计算
  • input.Quantityint 类型
  • supplier.LaundryPricedecimal 类型
  • int × decimal 应该是 decimal,不应该有问题

原因3:数据库字段默认值或约束问题

分析

  • 表结构:F_TotalPrice DECIMAL(18,2) NULL DEFAULT 0
  • 如果计算结果是 NULL 或异常,可能会使用默认值 0
  • 但代码中直接赋值,不应该触发默认值

原因4:历史数据问题(最可能)

分析

  • 这个记录是2025年12月创建的
  • 可能在系统上线初期,代码逻辑还不完善
  • 或者在某个时间点,代码被修改过,导致这个记录创建时使用了错误的逻辑

🔍 进一步调查建议

1. 查询所有金额为0的送出记录

SELECT 
    F_Id, 
    F_BatchNumber,
    F_StoreId,
    F_ProductType,
    F_Quantity, 
    F_LaundryPrice, 
    F_TotalPrice,
    (F_Quantity * F_LaundryPrice) as CalculatedPrice,
    F_CreateTime
FROM lq_laundry_flow
WHERE F_FlowType = 0 
    AND F_IsEffective = 1 
    AND F_TotalPrice = 0
ORDER BY F_CreateTime;

2. 查看是否有其他类似的记录

  • 统计金额为0的送出记录数量
  • 统计金额不为0的送出记录数量
  • 对比两种记录的特征(创建时间、门店、产品类型等)

3. 检查清洗商价格历史

  • 查看该批次号使用的清洗商ID
  • 检查该清洗商在产品类型"面巾"的价格是否有历史变更
  • 查看是否有价格变更日志

📝 逻辑梳理总结

当前逻辑(代码)

  1. 送出记录创建

    • 从清洗商表读取当前单价:supplier.LaundryPrice
    • 保存历史单价到记录:LaundryPrice = supplier.LaundryPrice
    • 计算总价:TotalPrice = input.Quantity * supplier.LaundryPrice
    • 保存到数据库
  2. 送回记录创建

    • 从清洗商表读取当前单价:supplier.LaundryPrice
    • 保存历史单价到记录:LaundryPrice = supplier.LaundryPrice
    • 计算总价:TotalPrice = input.Quantity * supplier.LaundryPrice
    • 保存到数据库

业务逻辑说明

  1. 送出记录的总价

    • 业务含义:送出时预计的费用(数量 × 单价)
    • 用于统计:工资计算、股份计算等使用送出记录的总价
    • 重要性:关键字段,用于成本计算
  2. 送回记录的总价

    • 业务含义:实际清洗后的费用(实际数量 × 单价)
    • 用于统计:费用统计等
    • 重要性:用于实际成本统计

问题影响

  1. 工资计算影响

    • 工资计算使用送出记录的总价(F_FlowType = 0
    • 如果总价为0,会导致成本计算不准确
    • 影响毛利计算,进而影响提成计算
  2. 股份计算影响

    • 股份计算使用送出记录的总价
    • 如果总价为0,会导致成本统计不准确
  3. 数据一致性

    • 送出记录总价为0,但送回记录总价正确
    • 数据不一致,可能造成统计偏差

💡 建议解决方案

方案1:数据修复(针对历史数据)

如果确定是历史数据问题,可以编写SQL脚本修复:

-- 修复金额为0但单价和数量都不为0的记录
UPDATE lq_laundry_flow
SET F_TotalPrice = F_Quantity * F_LaundryPrice
WHERE F_FlowType = 0
    AND F_IsEffective = 1
    AND F_TotalPrice = 0
    AND F_Quantity > 0
    AND F_LaundryPrice > 0;

方案2:代码增强(防止未来问题)

  1. 添加验证

    • 创建送出记录时,验证总价计算是否正确
    • 如果计算结果异常,记录日志并报错
  2. 添加数据校验

    • 定期检查数据一致性
    • 对于总价为0但单价和数量都不为0的记录,标记为异常
  3. 添加审计日志

    • 记录清洗商价格变更历史
    • 记录送出记录创建时的价格信息

方案3:业务规则调整(如果需要)

如果业务上允许送出时总价为0(例如免费清洗),需要:

  1. 明确业务规则
  2. 在计算逻辑中处理这种情况
  3. 在界面上明确标注

⚠️ 注意事项

  1. 不要随意修复数据

    • 需要先确认业务规则
    • 需要确认是否是业务异常还是数据异常
    • 需要确认修复后对已有计算的影响
  2. 数据修复前备份

    • 修复前必须备份数据库
    • 修复后需要重新计算相关的工资和股份数据
  3. 代码修改要谨慎

    • 修改代码前需要充分测试
    • 考虑对现有数据的影响
    • 考虑向后兼容性

📊 数据统计

金额为0的记录统计

  • 金额为0的送出记录总数:49条
  • 金额不为0的送出记录总数:471条
  • 异常记录(单价>0,数量>0,但总价=0):约10条(从查询结果看)

异常记录特征

从查询结果看,存在以下类型的异常记录:

  1. 单价为0的记录(正常情况,可能是免费清洗):

    • 例如:批次号778860097995539717,数量1,单价0.00,总价0.00
    • 这种情况总价为0是合理的
  2. 单价和数量都不为0,但总价为0的记录(异常情况):

    • 批次号767887817136145669:数量394,单价0.60,总价0.00(应236.40)
    • 批次号767923748534748421:数量354,单价0.60,总价0.00(应212.40)
    • 批次号767923911345046789:数量10,单价2.00,总价0.00(应20.00)
    • 批次号767924041217475845:数量1,单价3.00,总价0.00(应3.00)
    • 批次号767904927287608581:数量2,单价5.00,总价0.00(应10.00)
    • 批次号767905339348616453:数量1,单价2.00,总价0.00(应2.00)
    • 批次号767904852637385989:数量1,单价1.50,总价0.00(应1.50)

异常记录特征

  • 创建时间集中在2025年12月(766、767开头)
  • 单价和数量都不为0,但总价都是0
  • 关键发现:所有检查的异常记录都有对应的送回记录,且送回记录的总价都是正确的
    • 批次号767887817136145669:送出总价0.00,送回总价236.40(正确)
    • 批次号767923748534748421:送出总价0.00,送回总价212.40(正确)
    • 批次号767923911345046789:送出总价0.00,送回总价20.00(正确)
    • 其他异常记录也都有正确的送回记录总价

结论

  • 送出记录创建时,总价计算出现异常(被设置为0)
  • 送回记录创建时,总价计算是正常的
  • 这说明问题出现在送出记录创建的逻辑中,而不是整体计算逻辑的问题

📋 下一步行动

  1. ✅ 确认问题记录的情况
  2. ✅ 查询所有金额为0的送出记录
  3. ✅ 分析这些记录的特征和规律
  4. ⏭️ 检查异常记录的送回记录情况(确认是否送回记录的总价是正确的)
  5. ⏭️ 确认业务规则(送出时是否允许总价为0)
  6. ⏭️ 确定修复方案(数据修复 vs 代码修复 vs 业务规则调整)
  7. ⏭️ 执行修复(如果确定是数据异常)