仓库费用计算时间字段修改梳理 - 从使用时间改为领取时间
📋 修改目标
将所有使用使用时间(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. 数据验证
- 对比修改前后的计算结果
- 验证只有已领取的记录被统计
- 验证时间筛选基于领取时间而不是使用时间
📋 修改步骤
- 修改店长工资计算 (
LqStoreManagerSalaryService.cs) - 修改主任工资计算 (
LqDirectorSalaryService.cs) - 修改事业部总经理/经理工资计算 (
LqBusinessUnitManagerSalaryService.cs) - 修改门店股份统计 - 产品成本 (
LqShareStatisticsStoreService.cs) - 修改门店股份统计 - 福田成本 (
LqShareStatisticsStoreService.cs) - 测试验证
- 更新相关文档
文档版本: v1.0
创建日期: 2026-01-09
适用范围: 仓库费用计算时间字段修改