This commit is contained in:
fuenmao
2025-12-05 11:46:47 +08:00
parent e0ae9bdfc5
commit f96ce8fb07
7 changed files with 147 additions and 8 deletions
@@ -305,7 +305,8 @@ public class PrescriptionService : DbRepository<Prescription>, IPrescriptionServ
}
}
//var all= prescriptionPage.List.Sum(a => a.TotalMedicineCost);
//var cc = await GetAllPrescriptionTotalCost();
return prescriptionPage;
}
catch (Exception ex)
@@ -314,6 +315,111 @@ public class PrescriptionService : DbRepository<Prescription>, IPrescriptionServ
throw;
}
}
/// <summary>
/// 获取所有处方的总药材成本
/// </summary>
/// <returns></returns>
public async Task<decimal> GetAllPrescriptionTotalCost()
{
// 1) 获取所有处方的 ID(按创建时间升序),并明确类型为 long
var allPrescriptionIds = await Context.Queryable<Prescription>()
.OrderBy(p => p.CreateTime)
.Select(p => p.Id) // 确保这里的 Id 类型是 long 或 long?
.ToListAsync();
if (!allPrescriptionIds.Any())
return 0m;
// 把 id 列表规范为 long 列表(处理可能的 nullable)
var allIdsLong = allPrescriptionIds.Select(id => Convert.ToInt64(id)).ToList();
// 2) 获取所有处方的药材使用明细
var allPrescriptionHerbList = await Context.Queryable<PrescriptionHerb>()
.Where(ph => allIdsLong.Contains(Convert.ToInt64(ph.PrescriptionId)))
.ToListAsync();
var allUsageGroups = allPrescriptionHerbList
.GroupBy(h => new { PrescriptionId = Convert.ToInt64(h.PrescriptionId), h.MedicinalId })
.Select(g => new
{
PrescriptionId = g.Key.PrescriptionId,
g.Key.MedicinalId,
TotalUsedWeight = g.Sum(h => h.AmountG)
})
.ToList();
// 3) 获取所有药材的 FIFO 入库记录
var allMedicinalIds = allUsageGroups.Select(u => u.MedicinalId).Distinct().ToList();
var fifoData = await GetMedicinalFifoData(allMedicinalIds);
// 4) 按处方构建使用分组(key 为 long)
var groupedByPrescriptionAll = allUsageGroups
.GroupBy(u => u.PrescriptionId)
.ToDictionary(g => g.Key, g => g.ToList());
// 5) FIFO 偏移量
var fifoOffsets = new Dictionary<long, decimal>();
decimal totalSum = 0m;
// 6) 获取每张处方的人员类型(IsRelative: bool),并把 key 明确为 long,避免类型不匹配
var personTmp = await Context.Queryable<Prescription>()
.LeftJoin<Person>((p, pe) => p.PersonId == pe.Id)
.Where(p => allIdsLong.Contains(Convert.ToInt64(p.Id)))
.Select((p, pe) => new
{
Id = p.Id,
IsRelative = pe.EmployeeId != null
})
.ToListAsync();
// 明确转换 key 为 long(处理 nullable)
var personInfoDict = personTmp
.ToDictionary(x => Convert.ToInt64(x.Id), x => x.IsRelative);
// 7) FIFO 成本计算(按时间顺序已由 allIdsLong 保持)
foreach (var pidObj in allIdsLong)
{
long pid = pidObj; // 明确 pid 是 long
decimal presCost = 0m;
if (groupedByPrescriptionAll.TryGetValue(pid, out var usages))
{
foreach (var usage in usages)
{
var cost = CalculateHerbCostByFifoWithOffset(
fifoData,
fifoOffsets,
usage.MedicinalId,
usage.TotalUsedWeight
);
presCost += cost;
}
}
// 处方级别保留 4 位小数
presCost = Math.Round(presCost, 4, MidpointRounding.AwayFromZero);
// 家属加价 10%(若字典缺失,默认不是家属)
var isRelative = personInfoDict.TryGetValue(pid, out var rel) && rel;
if (isRelative)
{
presCost = Math.Round(presCost * 1.1m, 2, MidpointRounding.AwayFromZero);
}
else
{
presCost = Math.Round(presCost, 2, MidpointRounding.AwayFromZero);
}
totalSum += presCost;
}
return totalSum;
}
/// <summary>