仓库费用计算时间字段修改梳理-从使用时间改为领取时间.md 13.5 KB

仓库费用计算时间字段修改梳理 - 从使用时间改为领取时间

📋 修改目标

将所有使用使用时间(UsageTime)进行仓库费用计算的地方,改为使用领取时间(ReceiveTime),并且只统计已领取(IsReceived = 1)的记录。


🔍 需要修改的地方

一、薪酬计算相关

1.1 店长工资计算(LqStoreManagerSalaryService.cs)

文件位置: netcore/src/Modularity/Extend/NCC.Extend/LqStoreManagerSalaryService.cs
方法: CalculateStoreManagerSalary
行数: 第317-342行

当前逻辑:

// 1.9 产品物料统计(仓库领用金额,使用上月数据)
var queryMonth = monthStr;
if (month == 1)
{
    queryMonth = $"{year - 1}12";
}
else
{
    queryMonth = $"{year}{(month - 1):D2}";
}
var productMaterialSql = $@"
    SELECT 
        F_StoreId as StoreId,
        COALESCE(SUM(F_TotalAmount), 0) as MaterialAmount
    FROM lq_inventory_usage
    WHERE F_IsEffective = 1
        AND DATE_FORMAT(F_UsageTime, '%Y%m') = @queryMonth
    GROUP BY F_StoreId";

需要修改为:

// 1.9 产品物料统计(仓库领用金额,使用上月数据,基于领取时间)
var queryMonth = monthStr;
if (month == 1)
{
    queryMonth = $"{year - 1}12";
}
else
{
    queryMonth = $"{year}{(month - 1):D2}";
}
var productMaterialSql = $@"
    SELECT 
        u.F_StoreId as StoreId,
        COALESCE(SUM(u.F_TotalAmount), 0) as MaterialAmount
    FROM lq_inventory_usage u
    INNER JOIN lq_inventory_usage_application a ON u.F_UsageBatchId = a.F_UsageBatchId
    WHERE u.F_IsEffective = 1
        AND a.F_IsEffective = 1
        AND a.F_ApprovalStatus = '已通过'
        AND a.F_IsReceived = 1
        AND a.F_ReceiveTime IS NOT NULL
        AND DATE_FORMAT(a.F_ReceiveTime, '%Y%m') = @queryMonth
    GROUP BY u.F_StoreId";

影响: 店长工资计算中的产品物料(用于毛利计算)


1.2 主任工资计算(LqDirectorSalaryService.cs)

文件位置: netcore/src/Modularity/Extend/NCC.Extend/LqDirectorSalaryService.cs
方法: CalculateDirectorSalary
行数: 第363-388行

当前逻辑:

// 1.9 产品物料统计(仓库领用金额,使用上月数据)
var queryMonth = monthStr;
if (month == 1)
{
    queryMonth = $"{year - 1}12";
}
else
{
    queryMonth = $"{year}{(month - 1):D2}";
}
var productMaterialSql = $@"
    SELECT 
        F_StoreId as StoreId,
        COALESCE(SUM(F_TotalAmount), 0) as MaterialAmount
    FROM lq_inventory_usage
    WHERE F_IsEffective = 1
        AND DATE_FORMAT(F_UsageTime, '%Y%m') = @queryMonth
    GROUP BY F_StoreId";

需要修改为:

// 1.9 产品物料统计(仓库领用金额,使用上月数据,基于领取时间)
var queryMonth = monthStr;
if (month == 1)
{
    queryMonth = $"{year - 1}12";
}
else
{
    queryMonth = $"{year}{(month - 1):D2}";
}
var productMaterialSql = $@"
    SELECT 
        u.F_StoreId as StoreId,
        COALESCE(SUM(u.F_TotalAmount), 0) as MaterialAmount
    FROM lq_inventory_usage u
    INNER JOIN lq_inventory_usage_application a ON u.F_UsageBatchId = a.F_UsageBatchId
    WHERE u.F_IsEffective = 1
        AND a.F_IsEffective = 1
        AND a.F_ApprovalStatus = '已通过'
        AND a.F_IsReceived = 1
        AND a.F_ReceiveTime IS NOT NULL
        AND DATE_FORMAT(a.F_ReceiveTime, '%Y%m') = @queryMonth
    GROUP BY u.F_StoreId";

影响: 主任工资计算中的产品物料(用于毛利计算)


1.3 事业部总经理/经理工资计算(LqBusinessUnitManagerSalaryService.cs)

文件位置: netcore/src/Modularity/Extend/NCC.Extend/LqBusinessUnitManagerSalaryService.cs
方法: CalculateBusinessUnitManagerSalary
行数: 第275-300行

当前逻辑:

// 1.7 产品物料统计(仓库领用金额,使用上月数据)
var queryMonth = monthStr;
if (month == 1)
{
    queryMonth = $"{year - 1}12";
}
else
{
    queryMonth = $"{year}{(month - 1):D2}";
}
var productMaterialSql = $@"
    SELECT 
        F_StoreId as StoreId,
        COALESCE(SUM(F_TotalAmount), 0) as MaterialAmount
    FROM lq_inventory_usage
    WHERE F_IsEffective = 1
        AND DATE_FORMAT(F_UsageTime, '%Y%m') = @queryMonth
    GROUP BY F_StoreId";

需要修改为:

// 1.7 产品物料统计(仓库领用金额,使用上月数据,基于领取时间)
var queryMonth = monthStr;
if (month == 1)
{
    queryMonth = $"{year - 1}12";
}
else
{
    queryMonth = $"{year}{(month - 1):D2}";
}
var productMaterialSql = $@"
    SELECT 
        u.F_StoreId as StoreId,
        COALESCE(SUM(u.F_TotalAmount), 0) as MaterialAmount
    FROM lq_inventory_usage u
    INNER JOIN lq_inventory_usage_application a ON u.F_UsageBatchId = a.F_UsageBatchId
    WHERE u.F_IsEffective = 1
        AND a.F_IsEffective = 1
        AND a.F_ApprovalStatus = '已通过'
        AND a.F_IsReceived = 1
        AND a.F_ReceiveTime IS NOT NULL
        AND DATE_FORMAT(a.F_ReceiveTime, '%Y%m') = @queryMonth
    GROUP BY u.F_StoreId";

影响: 事业部总经理/经理工资计算中的产品物料(用于毛利计算)


二、股份统计相关

2.1 门店股份统计 - 产品成本(LqShareStatisticsStoreService.cs)

文件位置: netcore/src/Modularity/Extend/NCC.Extend/LqShareStatisticsStoreService.cs
方法: CalculateCost
行数: 第323-326行

当前逻辑:

// 1. 产品成本 = 仓库领用金额
entity.CostProduct = await _db.Queryable<LqInventoryUsageEntity>()
    .Where(x => x.StoreId == entity.StoreId 
        && x.UsageTime >= startDate 
        && x.UsageTime <= endDate 
        && x.IsEffective == 1)
    .SumAsync(x => x.TotalAmount);

需要修改为:

// 1. 产品成本 = 仓库领用金额(基于领取时间,只统计已领取的记录)
entity.CostProduct = await _db.Queryable<LqInventoryUsageEntity, LqInventoryUsageApplicationEntity>(
        (u, a) => u.UsageBatchId == a.UsageBatchId)
    .Where((u, a) => u.StoreId == entity.StoreId
        && u.IsEffective == 1
        && a.IsEffective == 1
        && a.ApprovalStatus == "已通过"
        && a.IsReceived == 1
        && a.ReceiveTime.HasValue
        && a.ReceiveTime.Value >= startDate
        && a.ReceiveTime.Value <= endDate)
    .SumAsync((u, a) => u.TotalAmount);

影响: 门店股份统计中的产品成本


2.2 门店股份统计 - 福田成本(LqShareStatisticsStoreService.cs)

文件位置: netcore/src/Modularity/Extend/NCC.Extend/LqShareStatisticsStoreService.cs
方法: CalculateCost
行数: 第328-344行

当前逻辑:

// 2. 福田成本 = 福田仓库领用(上一个月的成本)
var prevMonthStart = startDate.AddMonths(-1);
var prevMonthEnd = startDate.AddDays(-1);

entity.CostFutian = await _db.Queryable<LqInventoryUsageEntity, LqProductEntity, LqInventoryUsageApplicationEntity>(
        (u, p, a) => new JoinQueryInfos(
            JoinType.Inner, u.ProductId == p.Id,
            JoinType.Inner, u.UsageBatchId == a.UsageBatchId))
    .Where((u, p, a) => p.Warehouse == "福田仓库"
        && u.StoreId == entity.StoreId
        && u.UsageTime >= prevMonthStart && u.UsageTime <= prevMonthEnd
        && u.IsEffective == 1
        && a.IsEffective == 1
        && a.ApprovalStatus == "已通过"
        && a.IsReceived == 1)
    .SumAsync((u, p, a) => u.TotalAmount);

需要修改为:

// 2. 福田成本 = 福田仓库领用(上一个月的成本,基于领取时间)
var prevMonthStart = startDate.AddMonths(-1);
var prevMonthEnd = startDate.AddDays(-1);

entity.CostFutian = await _db.Queryable<LqInventoryUsageEntity, LqProductEntity, LqInventoryUsageApplicationEntity>(
        (u, p, a) => new JoinQueryInfos(
            JoinType.Inner, u.ProductId == p.Id,
            JoinType.Inner, u.UsageBatchId == a.UsageBatchId))
    .Where((u, p, a) => p.Warehouse == "福田仓库"
        && u.StoreId == entity.StoreId
        && u.IsEffective == 1
        && a.IsEffective == 1
        && a.ApprovalStatus == "已通过"
        && a.IsReceived == 1
        && a.ReceiveTime.HasValue
        && a.ReceiveTime.Value >= prevMonthStart 
        && a.ReceiveTime.Value <= prevMonthEnd)
    .SumAsync((u, p, a) => u.TotalAmount);

影响: 门店股份统计中的福田成本

注意: 这个已经关联了申请表,但使用的是 UsageTime,需要改为 ReceiveTime


📊 数据关联关系

表结构关系

lq_inventory_usage (使用记录表)
├── F_UsageBatchId (使用批次ID)
└── F_TotalAmount (合计金额)

lq_inventory_usage_application (申请表)
├── F_UsageBatchId (使用批次ID) ← 关联字段
├── F_IsReceived (是否已领取: 1-已领取, 0-未领取)
├── F_ReceiveTime (领取时间)
└── F_ApprovalStatus (审批状态: "已通过")

关联逻辑

  • 使用记录表 (lq_inventory_usage) 通过 F_UsageBatchId 关联 申请表 (lq_inventory_usage_application)
  • 领取时间 (F_ReceiveTime) 在申请表中
  • 是否已领取 (F_IsReceived) 在申请表中

🔧 修改要点

1. SQL查询修改要点

原查询:

FROM lq_inventory_usage
WHERE F_IsEffective = 1
    AND DATE_FORMAT(F_UsageTime, '%Y%m') = @queryMonth

新查询:

FROM lq_inventory_usage u
INNER JOIN lq_inventory_usage_application a ON u.F_UsageBatchId = a.F_UsageBatchId
WHERE u.F_IsEffective = 1
    AND a.F_IsEffective = 1
    AND a.F_ApprovalStatus = '已通过'
    AND a.F_IsReceived = 1
    AND a.F_ReceiveTime IS NOT NULL
    AND DATE_FORMAT(a.F_ReceiveTime, '%Y%m') = @queryMonth

2. ORM查询修改要点

原查询:

await _db.Queryable<LqInventoryUsageEntity>()
    .Where(x => x.StoreId == storeId 
        && x.UsageTime >= startDate 
        && x.UsageTime <= endDate 
        && x.IsEffective == 1)
    .SumAsync(x => x.TotalAmount);

新查询:

await _db.Queryable<LqInventoryUsageEntity, LqInventoryUsageApplicationEntity>(
        (u, a) => u.UsageBatchId == a.UsageBatchId)
    .Where((u, a) => u.StoreId == storeId
        && u.IsEffective == 1
        && a.IsEffective == 1
        && a.ApprovalStatus == "已通过"
        && a.IsReceived == 1
        && a.ReceiveTime.HasValue
        && a.ReceiveTime.Value >= startDate
        && a.ReceiveTime.Value <= endDate)
    .SumAsync((u, a) => u.TotalAmount);

📝 修改清单

薪酬计算(3处)

序号 文件 方法 行数 说明
1 LqStoreManagerSalaryService.cs CalculateStoreManagerSalary 330-337 店长工资 - 产品物料计算
2 LqDirectorSalaryService.cs CalculateDirectorSalary 376-383 主任工资 - 产品物料计算
3 LqBusinessUnitManagerSalaryService.cs CalculateBusinessUnitManagerSalary 288-295 事业部总经理/经理工资 - 产品物料计算

股份统计(2处)

序号 文件 方法 行数 说明
4 LqShareStatisticsStoreService.cs CalculateCost 324-326 门店股份统计 - 产品成本
5 LqShareStatisticsStoreService.cs CalculateCost 334-344 门店股份统计 - 福田成本

⚠️ 注意事项

1. 数据完整性

  • 确保所有使用记录都有对应的申请记录(通过 UsageBatchId 关联)
  • 如果使用记录没有对应的申请记录,这些记录将不会被统计(符合"未领取不计算"的要求)

2. 时间规则保持不变

  • 薪酬计算: 仍然使用上月数据(计算12月工资,使用11月的领取时间数据)
  • 股份统计:
    • 产品成本:使用当月数据(基于领取时间)
    • 福田成本:使用上月数据(基于领取时间)

3. 筛选条件

必须同时满足以下条件:

  • ✅ 使用记录有效 (u.F_IsEffective = 1)
  • ✅ 申请记录有效 (a.F_IsEffective = 1)
  • ✅ 审批状态为"已通过" (a.F_ApprovalStatus = '已通过')
  • ✅ 已领取 (a.F_IsReceived = 1)
  • ✅ 领取时间不为空 (a.F_ReceiveTime IS NOT NULL)
  • ✅ 领取时间在指定月份范围内

4. 旧数据处理

  • 对于没有申请记录的历史数据(旧数据),将不会被统计
  • 这是符合业务逻辑的:如果没有领取,就不应该计入成本

🧪 测试建议

1. 单元测试

  • 测试已领取的记录是否被正确统计
  • 测试未领取的记录是否被排除
  • 测试审批未通过的记录是否被排除
  • 测试领取时间为空的记录是否被排除
  • 测试时间范围筛选是否正确

2. 集成测试

  • 测试店长工资计算:产品物料是否正确
  • 测试主任工资计算:产品物料是否正确
  • 测试事业部总经理/经理工资计算:产品物料是否正确
  • 测试门店股份统计:产品成本和福田成本是否正确

3. 数据验证

  • 对比修改前后的计算结果
  • 验证只有已领取的记录被统计
  • 验证时间筛选基于领取时间而不是使用时间

📋 修改步骤

  1. 修改店长工资计算 (LqStoreManagerSalaryService.cs)
  2. 修改主任工资计算 (LqDirectorSalaryService.cs)
  3. 修改事业部总经理/经理工资计算 (LqBusinessUnitManagerSalaryService.cs)
  4. 修改门店股份统计 - 产品成本 (LqShareStatisticsStoreService.cs)
  5. 修改门店股份统计 - 福田成本 (LqShareStatisticsStoreService.cs)
  6. 测试验证
  7. 更新相关文档

文档版本: v1.0
创建日期: 2026-01-09
适用范围: 仓库费用计算时间字段修改