Commit 4fa0ea166e8de737132850054cd1982a436fa3b6

Authored by “wangming”
1 parent 12ccf031

修复门店领取统计接口SQL语法错误,修复店长工资提成计算逻辑

- 修复GetStoreReceiveStatistics接口:将表别名从usage改为u(usage是MySQL保留关键字)
- 修复店长工资计算:根据门店分类(A/B/C)正确计算老店提成比例
- 开单品项明细接口:返回支付医院和合作机构中文名称
- 修改开单金额接口:支持修改品项备注
- 报销申请接口:返回完成时间并支持按完成时间筛选
- 店内支出导入:使用门店名称匹配并存储门店ID
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqKdKdjlb/BillingItemDetailListOutput.cs
@@ -78,16 +78,26 @@ namespace NCC.Extend.Entitys.Dto.LqKdKdjlb @@ -78,16 +78,26 @@ namespace NCC.Extend.Entitys.Dto.LqKdKdjlb
78 public string storeName { get; set; } 78 public string storeName { get; set; }
79 79
80 /// <summary> 80 /// <summary>
81 - /// 合作机构 81 + /// 合作机构ID
82 /// </summary> 82 /// </summary>
83 public string hgjg { get; set; } 83 public string hgjg { get; set; }
84 84
85 /// <summary> 85 /// <summary>
86 - /// 付款医院 86 + /// 合作机构名称
  87 + /// </summary>
  88 + public string hgjgName { get; set; }
  89 +
  90 + /// <summary>
  91 + /// 付款医院ID
87 /// </summary> 92 /// </summary>
88 public string fkyy { get; set; } 93 public string fkyy { get; set; }
89 94
90 /// <summary> 95 /// <summary>
  96 + /// 付款医院名称
  97 + /// </summary>
  98 + public string fkyyName { get; set; }
  99 +
  100 + /// <summary>
91 /// 付款方式 101 /// 付款方式
92 /// </summary> 102 /// </summary>
93 public string paymentMethod { get; set; } 103 public string paymentMethod { get; set; }
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqKdKdjlb/LqKdKdjlbUpdateAmountInput.cs
@@ -78,5 +78,10 @@ namespace NCC.Extend.Entitys.Dto.LqKdKdjlb @@ -78,5 +78,10 @@ namespace NCC.Extend.Entitys.Dto.LqKdKdjlb
78 /// </summary> 78 /// </summary>
79 [Range(0, double.MaxValue, ErrorMessage = "实付金额必须大于等于0")] 79 [Range(0, double.MaxValue, ErrorMessage = "实付金额必须大于等于0")]
80 public decimal ActualPrice { get; set; } 80 public decimal ActualPrice { get; set; }
  81 +
  82 + /// <summary>
  83 + /// 备注
  84 + /// </summary>
  85 + public string Remark { get; set; }
81 } 86 }
82 } 87 }
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqReimbursementApplicationListOutput.cs
@@ -11,17 +11,17 @@ namespace NCC.Extend.Entitys.Dto.LqReimbursementApplication @@ -11,17 +11,17 @@ namespace NCC.Extend.Entitys.Dto.LqReimbursementApplication
11 /// 申请编号 11 /// 申请编号
12 /// </summary> 12 /// </summary>
13 public string id { get; set; } 13 public string id { get; set; }
14 - 14 +
15 /// <summary> 15 /// <summary>
16 /// 申请人编号 16 /// 申请人编号
17 /// </summary> 17 /// </summary>
18 public string applicationUserId { get; set; } 18 public string applicationUserId { get; set; }
19 - 19 +
20 /// <summary> 20 /// <summary>
21 /// 申请人姓名 21 /// 申请人姓名
22 /// </summary> 22 /// </summary>
23 public string applicationUserName { get; set; } 23 public string applicationUserName { get; set; }
24 - 24 +
25 /// <summary> 25 /// <summary>
26 /// 申请门店 26 /// 申请门店
27 /// </summary> 27 /// </summary>
@@ -31,32 +31,32 @@ namespace NCC.Extend.Entitys.Dto.LqReimbursementApplication @@ -31,32 +31,32 @@ namespace NCC.Extend.Entitys.Dto.LqReimbursementApplication
31 /// 申请门店名称 31 /// 申请门店名称
32 /// </summary> 32 /// </summary>
33 public string applicationStoreName { get; set; } 33 public string applicationStoreName { get; set; }
34 - 34 +
35 /// <summary> 35 /// <summary>
36 /// 申请时间 36 /// 申请时间
37 /// </summary> 37 /// </summary>
38 public DateTime? applicationTime { get; set; } 38 public DateTime? applicationTime { get; set; }
39 - 39 +
40 /// <summary> 40 /// <summary>
41 /// 总金额 41 /// 总金额
42 /// </summary> 42 /// </summary>
43 public string amount { get; set; } 43 public string amount { get; set; }
44 - 44 +
45 /// <summary> 45 /// <summary>
46 /// 审批人 46 /// 审批人
47 /// </summary> 47 /// </summary>
48 public string approveUser { get; set; } 48 public string approveUser { get; set; }
49 - 49 +
50 /// <summary> 50 /// <summary>
51 /// 审批结果 51 /// 审批结果
52 /// </summary> 52 /// </summary>
53 public string approveStatus { get; set; } 53 public string approveStatus { get; set; }
54 - 54 +
55 /// <summary> 55 /// <summary>
56 /// 审批时间 56 /// 审批时间
57 /// </summary> 57 /// </summary>
58 public DateTime? approveTime { get; set; } 58 public DateTime? approveTime { get; set; }
59 - 59 +
60 /// <summary> 60 /// <summary>
61 /// 关联购买编号 61 /// 关联购买编号
62 /// </summary> 62 /// </summary>
@@ -76,6 +76,11 @@ namespace NCC.Extend.Entitys.Dto.LqReimbursementApplication @@ -76,6 +76,11 @@ namespace NCC.Extend.Entitys.Dto.LqReimbursementApplication
76 /// 节点总数 76 /// 节点总数
77 /// </summary> 77 /// </summary>
78 public int? nodeCount { get; set; } 78 public int? nodeCount { get; set; }
79 - 79 +
  80 + /// <summary>
  81 + /// 完成时间(最后一个审批人通过的时间)
  82 + /// </summary>
  83 + public DateTime? completionTime { get; set; }
  84 +
80 } 85 }
81 } 86 }
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqReimbursementApplicationListQueryInput.cs
@@ -23,51 +23,56 @@ namespace NCC.Extend.Entitys.Dto.LqReimbursementApplication @@ -23,51 +23,56 @@ namespace NCC.Extend.Entitys.Dto.LqReimbursementApplication
23 /// 申请编号 23 /// 申请编号
24 /// </summary> 24 /// </summary>
25 public string id { get; set; } 25 public string id { get; set; }
26 - 26 +
27 /// <summary> 27 /// <summary>
28 /// 申请人编号 28 /// 申请人编号
29 /// </summary> 29 /// </summary>
30 public string applicationUserId { get; set; } 30 public string applicationUserId { get; set; }
31 - 31 +
32 /// <summary> 32 /// <summary>
33 /// 申请人姓名 33 /// 申请人姓名
34 /// </summary> 34 /// </summary>
35 public string applicationUserName { get; set; } 35 public string applicationUserName { get; set; }
36 - 36 +
37 /// <summary> 37 /// <summary>
38 /// 申请门店 38 /// 申请门店
39 /// </summary> 39 /// </summary>
40 public string applicationStoreId { get; set; } 40 public string applicationStoreId { get; set; }
41 - 41 +
42 /// <summary> 42 /// <summary>
43 /// 申请时间 43 /// 申请时间
44 /// </summary> 44 /// </summary>
45 public string applicationTime { get; set; } 45 public string applicationTime { get; set; }
46 - 46 +
47 /// <summary> 47 /// <summary>
48 /// 总金额 48 /// 总金额
49 /// </summary> 49 /// </summary>
50 public string amount { get; set; } 50 public string amount { get; set; }
51 - 51 +
52 /// <summary> 52 /// <summary>
53 /// 审批人 53 /// 审批人
54 /// </summary> 54 /// </summary>
55 public string approveUser { get; set; } 55 public string approveUser { get; set; }
56 - 56 +
57 /// <summary> 57 /// <summary>
58 /// 审批结果 58 /// 审批结果
59 /// </summary> 59 /// </summary>
60 public string approveStatus { get; set; } 60 public string approveStatus { get; set; }
61 - 61 +
62 /// <summary> 62 /// <summary>
63 /// 审批时间 63 /// 审批时间
64 /// </summary> 64 /// </summary>
65 public string approveTime { get; set; } 65 public string approveTime { get; set; }
66 - 66 +
67 /// <summary> 67 /// <summary>
68 /// 关联购买编号 68 /// 关联购买编号
69 /// </summary> 69 /// </summary>
70 public string purchaseRecordsId { get; set; } 70 public string purchaseRecordsId { get; set; }
71 - 71 +
  72 + /// <summary>
  73 + /// 完成时间(最后一个审批人通过的时间)
  74 + /// </summary>
  75 + public string completionTime { get; set; }
  76 +
72 } 77 }
73 } 78 }
netcore/src/Modularity/Extend/NCC.Extend/LqInventoryUsageService.cs
@@ -1655,22 +1655,22 @@ namespace NCC.Extend @@ -1655,22 +1655,22 @@ namespace NCC.Extend
1655 1655
1656 // 查询这些批次的使用记录,关联产品表获取仓库信息,计算总金额 1656 // 查询这些批次的使用记录,关联产品表获取仓库信息,计算总金额
1657 var usageRecordsQuery = _db.Queryable<LqInventoryUsageEntity, LqProductEntity>( 1657 var usageRecordsQuery = _db.Queryable<LqInventoryUsageEntity, LqProductEntity>(
1658 - (usage, product) => usage.ProductId == product.Id)  
1659 - .Where((usage, product) => batchIds.Contains(usage.UsageBatchId))  
1660 - .Where((usage, product) => usage.IsEffective == StatusEnum.有效.GetHashCode()); 1658 + (u, product) => u.ProductId == product.Id)
  1659 + .Where((u, product) => batchIds.Contains(u.UsageBatchId))
  1660 + .Where((u, product) => u.IsEffective == StatusEnum.有效.GetHashCode());
1661 1661
1662 // 如果指定了仓库筛选,添加仓库条件 1662 // 如果指定了仓库筛选,添加仓库条件
1663 if (!string.IsNullOrWhiteSpace(input.Warehouse)) 1663 if (!string.IsNullOrWhiteSpace(input.Warehouse))
1664 { 1664 {
1665 - usageRecordsQuery = usageRecordsQuery.Where((usage, product) => product.Warehouse == input.Warehouse); 1665 + usageRecordsQuery = usageRecordsQuery.Where((u, product) => product.Warehouse == input.Warehouse);
1666 } 1666 }
1667 1667
1668 var usageRecords = await usageRecordsQuery 1668 var usageRecords = await usageRecordsQuery
1669 - .Select((usage, product) => new 1669 + .Select((u, product) => new
1670 { 1670 {
1671 - usage.UsageBatchId,  
1672 - usage.StoreId,  
1673 - usage.TotalAmount, 1671 + u.UsageBatchId,
  1672 + u.StoreId,
  1673 + u.TotalAmount,
1674 product.Warehouse 1674 product.Warehouse
1675 }) 1675 })
1676 .ToListAsync(); 1676 .ToListAsync();
netcore/src/Modularity/Extend/NCC.Extend/LqKdKdjlbService.cs
@@ -2303,7 +2303,7 @@ namespace NCC.Extend.LqKdKdjlb @@ -2303,7 +2303,7 @@ namespace NCC.Extend.LqKdKdjlb
2303 throw NCCException.Oh("更新开单记录金额失败"); 2303 throw NCCException.Oh("更新开单记录金额失败");
2304 } 2304 }
2305 2305
2306 - // 更新品项明细金额 2306 + // 更新品项明细金额和备注
2307 if (input.ItemDetails != null && input.ItemDetails.Any()) 2307 if (input.ItemDetails != null && input.ItemDetails.Any())
2308 { 2308 {
2309 foreach (var itemDetail in input.ItemDetails) 2309 foreach (var itemDetail in input.ItemDetails)
@@ -2312,7 +2312,8 @@ namespace NCC.Extend.LqKdKdjlb @@ -2312,7 +2312,8 @@ namespace NCC.Extend.LqKdKdjlb
2312 { 2312 {
2313 Pxjg = itemDetail.Pxjg, 2313 Pxjg = itemDetail.Pxjg,
2314 TotalPrice = itemDetail.TotalPrice, 2314 TotalPrice = itemDetail.TotalPrice,
2315 - ActualPrice = itemDetail.ActualPrice 2315 + ActualPrice = itemDetail.ActualPrice,
  2316 + Remark = itemDetail.Remark
2316 }).Where(w => w.Id == itemDetail.ItemDetailId && w.Glkdbh == input.BillingId).ExecuteCommandAsync(); 2317 }).Where(w => w.Id == itemDetail.ItemDetailId && w.Glkdbh == input.BillingId).ExecuteCommandAsync();
2317 2318
2318 if (itemUpdateResult <= 0) 2319 if (itemUpdateResult <= 0)
@@ -3818,6 +3819,20 @@ namespace NCC.Extend.LqKdKdjlb @@ -3818,6 +3819,20 @@ namespace NCC.Extend.LqKdKdjlb
3818 storeDict = stores.ToDictionary(x => x.Id, x => x.Dm ?? ""); 3819 storeDict = stores.ToDictionary(x => x.Id, x => x.Dm ?? "");
3819 } 3820 }
3820 3821
  3822 + // 批量查询合作机构和医院名称
  3823 + var hgjgIds = billingExtraInfoDict.Values.Where(x => !string.IsNullOrEmpty(x.Hgjg)).Select(x => x.Hgjg).Distinct().ToList();
  3824 + var fkyyIds = billingExtraInfoDict.Values.Where(x => !string.IsNullOrEmpty(x.Fkyy)).Select(x => x.Fkyy).Distinct().ToList();
  3825 + var hzfIds = hgjgIds.Union(fkyyIds).Distinct().ToList();
  3826 + var hzfDict = new Dictionary<string, string>();
  3827 + if (hzfIds.Any())
  3828 + {
  3829 + var hzfList = await _db.Queryable<LqHzfEntity>()
  3830 + .Where(x => hzfIds.Contains(x.Id))
  3831 + .Select(x => new { x.Id, x.Hzmc })
  3832 + .ToListAsync();
  3833 + hzfDict = hzfList.ToDictionary(x => x.Id, x => x.Hzmc ?? "");
  3834 + }
  3835 +
3821 // 5. 组装返回数据 3836 // 5. 组装返回数据
3822 var resultList = pagedData.list.Select(pxmx => new BillingItemDetailListOutput 3837 var resultList = pagedData.list.Select(pxmx => new BillingItemDetailListOutput
3823 { 3838 {
@@ -3836,7 +3851,9 @@ namespace NCC.Extend.LqKdKdjlb @@ -3836,7 +3851,9 @@ namespace NCC.Extend.LqKdKdjlb
3836 storeId = pxmx.Glkdbh != null && billingStoreDict.ContainsKey(pxmx.Glkdbh) ? billingStoreDict[pxmx.Glkdbh] : "", 3851 storeId = pxmx.Glkdbh != null && billingStoreDict.ContainsKey(pxmx.Glkdbh) ? billingStoreDict[pxmx.Glkdbh] : "",
3837 storeName = pxmx.Glkdbh != null && billingStoreDict.ContainsKey(pxmx.Glkdbh) && !string.IsNullOrEmpty(billingStoreDict[pxmx.Glkdbh]) && storeDict.ContainsKey(billingStoreDict[pxmx.Glkdbh]) ? storeDict[billingStoreDict[pxmx.Glkdbh]] : "", 3852 storeName = pxmx.Glkdbh != null && billingStoreDict.ContainsKey(pxmx.Glkdbh) && !string.IsNullOrEmpty(billingStoreDict[pxmx.Glkdbh]) && storeDict.ContainsKey(billingStoreDict[pxmx.Glkdbh]) ? storeDict[billingStoreDict[pxmx.Glkdbh]] : "",
3838 hgjg = pxmx.Glkdbh != null && billingExtraInfoDict.ContainsKey(pxmx.Glkdbh) ? billingExtraInfoDict[pxmx.Glkdbh].Hgjg : "", 3853 hgjg = pxmx.Glkdbh != null && billingExtraInfoDict.ContainsKey(pxmx.Glkdbh) ? billingExtraInfoDict[pxmx.Glkdbh].Hgjg : "",
  3854 + hgjgName = pxmx.Glkdbh != null && billingExtraInfoDict.ContainsKey(pxmx.Glkdbh) && !string.IsNullOrEmpty(billingExtraInfoDict[pxmx.Glkdbh].Hgjg) && hzfDict.ContainsKey(billingExtraInfoDict[pxmx.Glkdbh].Hgjg) ? hzfDict[billingExtraInfoDict[pxmx.Glkdbh].Hgjg] : "",
3839 fkyy = pxmx.Glkdbh != null && billingExtraInfoDict.ContainsKey(pxmx.Glkdbh) ? billingExtraInfoDict[pxmx.Glkdbh].Fkyy : "", 3855 fkyy = pxmx.Glkdbh != null && billingExtraInfoDict.ContainsKey(pxmx.Glkdbh) ? billingExtraInfoDict[pxmx.Glkdbh].Fkyy : "",
  3856 + fkyyName = pxmx.Glkdbh != null && billingExtraInfoDict.ContainsKey(pxmx.Glkdbh) && !string.IsNullOrEmpty(billingExtraInfoDict[pxmx.Glkdbh].Fkyy) && hzfDict.ContainsKey(billingExtraInfoDict[pxmx.Glkdbh].Fkyy) ? hzfDict[billingExtraInfoDict[pxmx.Glkdbh].Fkyy] : "",
3840 paymentMethod = pxmx.Glkdbh != null && billingExtraInfoDict.ContainsKey(pxmx.Glkdbh) ? billingExtraInfoDict[pxmx.Glkdbh].Fkfs : "" 3857 paymentMethod = pxmx.Glkdbh != null && billingExtraInfoDict.ContainsKey(pxmx.Glkdbh) ? billingExtraInfoDict[pxmx.Glkdbh].Fkfs : ""
3841 }).ToList(); 3858 }).ToList();
3842 3859
netcore/src/Modularity/Extend/NCC.Extend/LqReimbursementApplicationService.cs
@@ -188,6 +188,9 @@ namespace NCC.Extend.LqReimbursementApplication @@ -188,6 +188,9 @@ namespace NCC.Extend.LqReimbursementApplication
188 List<string> queryApproveTime = input.approveTime != null ? input.approveTime.Split(',').ToObeject<List<string>>() : null; 188 List<string> queryApproveTime = input.approveTime != null ? input.approveTime.Split(',').ToObeject<List<string>>() : null;
189 DateTime? startApproveTime = queryApproveTime != null ? Ext.GetDateTime(queryApproveTime.First()) : null; 189 DateTime? startApproveTime = queryApproveTime != null ? Ext.GetDateTime(queryApproveTime.First()) : null;
190 DateTime? endApproveTime = queryApproveTime != null ? Ext.GetDateTime(queryApproveTime.Last()) : null; 190 DateTime? endApproveTime = queryApproveTime != null ? Ext.GetDateTime(queryApproveTime.Last()) : null;
  191 + List<string> queryCompletionTime = input.completionTime != null ? input.completionTime.Split(',').ToObeject<List<string>>() : null;
  192 + DateTime? startCompletionTime = queryCompletionTime != null ? Ext.GetDateTime(queryCompletionTime.First()) : null;
  193 + DateTime? endCompletionTime = queryCompletionTime != null ? Ext.GetDateTime(queryCompletionTime.Last()) : null;
191 var query = _db.Queryable<LqReimbursementApplicationEntity>() 194 var query = _db.Queryable<LqReimbursementApplicationEntity>()
192 .WhereIF(!string.IsNullOrEmpty(input.id), p => p.Id.Contains(input.id)) 195 .WhereIF(!string.IsNullOrEmpty(input.id), p => p.Id.Contains(input.id))
193 .WhereIF(!string.IsNullOrEmpty(input.applicationUserId), p => p.ApplicationUserId.Contains(input.applicationUserId)) 196 .WhereIF(!string.IsNullOrEmpty(input.applicationUserId), p => p.ApplicationUserId.Contains(input.applicationUserId))
@@ -269,6 +272,31 @@ namespace NCC.Extend.LqReimbursementApplication @@ -269,6 +272,31 @@ namespace NCC.Extend.LqReimbursementApplication
269 .GroupBy(x => (string)x.applicationId) 272 .GroupBy(x => (string)x.applicationId)
270 .ToDictionary(g => g.Key, g => string.Join(", ", g.Select(x => (string)x.approverName))); 273 .ToDictionary(g => g.Key, g => string.Join(", ", g.Select(x => (string)x.approverName)));
271 274
  275 + // 如果提供了完成时间筛选,需要先查询完成时间,然后过滤
  276 + if (queryCompletionTime != null && applicationIds.Any())
  277 + {
  278 + var completionTimeRecords = await _db.Queryable<LqReimbursementApprovalRecordEntity>()
  279 + .Where(x => applicationIds.Contains(x.ApplicationId) && x.ApprovalResult == "通过")
  280 + .GroupBy(x => x.ApplicationId)
  281 + .Select(x => new
  282 + {
  283 + ApplicationId = x.ApplicationId,
  284 + MaxApprovalTime = SqlFunc.AggregateMax(x.ApprovalTime)
  285 + })
  286 + .ToListAsync();
  287 +
  288 + var filteredApplicationIds = completionTimeRecords
  289 + .Where(x => x.MaxApprovalTime.HasValue &&
  290 + x.MaxApprovalTime.Value >= new DateTime(startCompletionTime.ToDate().Year, startCompletionTime.ToDate().Month, startCompletionTime.ToDate().Day, 0, 0, 0) &&
  291 + x.MaxApprovalTime.Value <= new DateTime(endCompletionTime.ToDate().Year, endCompletionTime.ToDate().Month, endCompletionTime.ToDate().Day, 23, 59, 59))
  292 + .Select(x => x.ApplicationId)
  293 + .ToList();
  294 +
  295 + entities = entities.Where(x => filteredApplicationIds.Contains(x.Id)).ToList();
  296 + total = entities.Count;
  297 + applicationIds = entities.Select(x => x.Id).ToList();
  298 + }
  299 +
272 // 获取门店名称 300 // 获取门店名称
273 var storeIds = entities.Where(x => !string.IsNullOrEmpty(x.ApplicationStoreId)).Select(x => x.ApplicationStoreId).Distinct().ToList(); 301 var storeIds = entities.Where(x => !string.IsNullOrEmpty(x.ApplicationStoreId)).Select(x => x.ApplicationStoreId).Distinct().ToList();
274 var storeDict = new Dictionary<string, string>(); 302 var storeDict = new Dictionary<string, string>();
@@ -281,6 +309,23 @@ namespace NCC.Extend.LqReimbursementApplication @@ -281,6 +309,23 @@ namespace NCC.Extend.LqReimbursementApplication
281 storeDict = stores.ToDictionary(x => x.Id, x => x.Dm ?? ""); 309 storeDict = stores.ToDictionary(x => x.Id, x => x.Dm ?? "");
282 } 310 }
283 311
  312 + // 获取完成时间(最后一个审批通过的时间)
  313 + var completionTimeDict = new Dictionary<string, DateTime?>();
  314 + if (applicationIds.Any())
  315 + {
  316 + // 查询每个申请的最后一次审批通过的记录
  317 + var completionRecords = await _db.Queryable<LqReimbursementApprovalRecordEntity>()
  318 + .Where(x => applicationIds.Contains(x.ApplicationId) && x.ApprovalResult == "通过")
  319 + .GroupBy(x => x.ApplicationId)
  320 + .Select(x => new
  321 + {
  322 + ApplicationId = x.ApplicationId,
  323 + MaxApprovalTime = SqlFunc.AggregateMax(x.ApprovalTime)
  324 + })
  325 + .ToListAsync();
  326 + completionTimeDict = completionRecords.ToDictionary(x => x.ApplicationId, x => x.MaxApprovalTime);
  327 + }
  328 +
284 // 组装返回数据 329 // 组装返回数据
285 var result = entities.Select(item => new LqReimbursementApplicationListOutput 330 var result = entities.Select(item => new LqReimbursementApplicationListOutput
286 { 331 {
@@ -299,7 +344,8 @@ namespace NCC.Extend.LqReimbursementApplication @@ -299,7 +344,8 @@ namespace NCC.Extend.LqReimbursementApplication
299 purchaseRecordsId = item.PurchaseRecordsId, 344 purchaseRecordsId = item.PurchaseRecordsId,
300 currentApprovers = approverDict.ContainsKey(item.Id) ? approverDict[item.Id] : null, 345 currentApprovers = approverDict.ContainsKey(item.Id) ? approverDict[item.Id] : null,
301 currentNodeOrder = item.CurrentNodeOrder, 346 currentNodeOrder = item.CurrentNodeOrder,
302 - nodeCount = item.NodeCount 347 + nodeCount = item.NodeCount,
  348 + completionTime = completionTimeDict.ContainsKey(item.Id) ? completionTimeDict[item.Id] : null
303 }).ToList(); 349 }).ToList();
304 350
305 return PageResult<LqReimbursementApplicationListOutput>.SqlSugarPageResult( 351 return PageResult<LqReimbursementApplicationListOutput>.SqlSugarPageResult(
@@ -1515,8 +1561,8 @@ namespace NCC.Extend.LqReimbursementApplication @@ -1515,8 +1561,8 @@ namespace NCC.Extend.LqReimbursementApplication
1515 // 查询本月已审核通过的报销申请 1561 // 查询本月已审核通过的报销申请
1516 var applications = await _db.Queryable<LqReimbursementApplicationEntity>() 1562 var applications = await _db.Queryable<LqReimbursementApplicationEntity>()
1517 .Where(x => (x.ApprovalStatus ?? x.ApproveStatus) == "已通过") 1563 .Where(x => (x.ApprovalStatus ?? x.ApproveStatus) == "已通过")
1518 - .Where(x => x.ApplicationTime.HasValue &&  
1519 - x.ApplicationTime.Value.Year == queryYear && 1564 + .Where(x => x.ApplicationTime.HasValue &&
  1565 + x.ApplicationTime.Value.Year == queryYear &&
1520 x.ApplicationTime.Value.Month == int.Parse(queryMonth)) 1566 x.ApplicationTime.Value.Month == int.Parse(queryMonth))
1521 .ToListAsync(); 1567 .ToListAsync();
1522 1568
@@ -1552,7 +1598,7 @@ namespace NCC.Extend.LqReimbursementApplication @@ -1552,7 +1598,7 @@ namespace NCC.Extend.LqReimbursementApplication
1552 foreach (var app in applications) 1598 foreach (var app in applications)
1553 { 1599 {
1554 var appPurchaseRecords = purchaseRecords.Where(x => x.ApplicationId == app.Id).ToList(); 1600 var appPurchaseRecords = purchaseRecords.Where(x => x.ApplicationId == app.Id).ToList();
1555 - 1601 +
1556 if (appPurchaseRecords.Any()) 1602 if (appPurchaseRecords.Any())
1557 { 1603 {
1558 // 每个购买记录作为一行 1604 // 每个购买记录作为一行
netcore/src/Modularity/Extend/NCC.Extend/LqStoreExpenseService.cs
@@ -461,32 +461,46 @@ namespace NCC.Extend.LqStoreExpense @@ -461,32 +461,46 @@ namespace NCC.Extend.LqStoreExpense
461 try 461 try
462 { 462 {
463 var row = dataTable.Rows[i]; 463 var row = dataTable.Rows[i];
464 - var storeId = row[0]?.ToString()?.Trim();  
465 - var storeName = row[1]?.ToString()?.Trim();  
466 - var expenseCategoryId = row[2]?.ToString()?.Trim();  
467 - var expenseCategoryName = row[3]?.ToString()?.Trim();  
468 - var expenseDateText = row[4]?.ToString()?.Trim();  
469 - var unitPriceText = row[5]?.ToString()?.Trim();  
470 - var quantityText = row[6]?.ToString()?.Trim();  
471 - var amountText = row[7]?.ToString()?.Trim();  
472 - var memo = row[8]?.ToString()?.Trim();  
473 - var relatedReimbursementId = row[9]?.ToString()?.Trim();  
474 - var relatedPurchaseRecordId = row[10]?.ToString()?.Trim(); 464 + var storeName = row[0]?.ToString()?.Trim(); // 第0列:门店名称
  465 + var expenseCategoryId = row[1]?.ToString()?.Trim(); // 第1列:支出分类ID(原第2列)
  466 + var expenseCategoryName = row[2]?.ToString()?.Trim(); // 第2列:支出分类名称(原第3列)
  467 + var expenseDateText = row[3]?.ToString()?.Trim(); // 第3列:支出日期(原第4列)
  468 + var unitPriceText = row[4]?.ToString()?.Trim(); // 第4列:单价(原第5列)
  469 + var quantityText = row[5]?.ToString()?.Trim(); // 第5列:数量(原第6列)
  470 + var amountText = row[6]?.ToString()?.Trim(); // 第6列:金额(原第7列)
  471 + var memo = row[7]?.ToString()?.Trim(); // 第7列:备注说明(原第8列)
  472 + var relatedReimbursementId = row[8]?.ToString()?.Trim(); // 第8列:关联报销申请ID(原第9列)
  473 + var relatedPurchaseRecordId = row[9]?.ToString()?.Trim(); // 第9列:关联购买记录ID(原第10列)
475 474
476 // 跳过空行 475 // 跳过空行
477 - if (string.IsNullOrEmpty(storeId) && string.IsNullOrEmpty(storeName)) 476 + if (string.IsNullOrEmpty(storeName))
478 { 477 {
479 continue; 478 continue;
480 } 479 }
481 480
482 - // 验证必填字段  
483 - if (string.IsNullOrEmpty(storeId)) 481 + // 验证必填字段:门店名称
  482 + if (string.IsNullOrEmpty(storeName))
484 { 483 {
485 - failMessages.Add($"第{i + 1}行:门店ID不能为空"); 484 + failMessages.Add($"第{i + 1}行:门店名称不能为空");
486 failCount++; 485 failCount++;
487 continue; 486 continue;
488 } 487 }
489 488
  489 + // 通过门店名称匹配门店ID
  490 + var store = await _db.Queryable<LqMdxxEntity>()
  491 + .Where(x => x.Dm == storeName)
  492 + .Select(x => new { x.Id, x.Dm })
  493 + .FirstAsync();
  494 +
  495 + if (store == null)
  496 + {
  497 + failMessages.Add($"第{i + 1}行:未找到名称为【{storeName}】的门店");
  498 + failCount++;
  499 + continue;
  500 + }
  501 +
  502 + var storeId = store.Id;
  503 +
490 if (string.IsNullOrEmpty(expenseDateText) || !DateTime.TryParse(expenseDateText, out DateTime expenseDate)) 504 if (string.IsNullOrEmpty(expenseDateText) || !DateTime.TryParse(expenseDateText, out DateTime expenseDate))
491 { 505 {
492 failMessages.Add($"第{i + 1}行:支出日期格式错误(应为日期格式,如:2025-01-15)"); 506 failMessages.Add($"第{i + 1}行:支出日期格式错误(应为日期格式,如:2025-01-15)");
@@ -514,15 +528,8 @@ namespace NCC.Extend.LqStoreExpense @@ -514,15 +528,8 @@ namespace NCC.Extend.LqStoreExpense
514 quantity = qty; 528 quantity = qty;
515 } 529 }
516 530
517 - // 如果未提供门店名称,根据门店ID查询  
518 - if (string.IsNullOrEmpty(storeName))  
519 - {  
520 - var store = await _db.Queryable<LqMdxxEntity>()  
521 - .Where(x => x.Id == storeId)  
522 - .Select(x => x.Dm)  
523 - .FirstAsync();  
524 - storeName = store ?? "";  
525 - } 531 + // 门店名称已从查询中获取
  532 + storeName = store.Dm ?? "";
526 533
527 // 创建记录 534 // 创建记录
528 var entity = new LqStoreExpenseEntity 535 var entity = new LqStoreExpenseEntity
@@ -588,3 +595,4 @@ namespace NCC.Extend.LqStoreExpense @@ -588,3 +595,4 @@ namespace NCC.Extend.LqStoreExpense
588 } 595 }
589 } 596 }
590 597
  598 +
netcore/src/Modularity/Extend/NCC.Extend/LqStoreManagerSalaryService.cs
@@ -597,14 +597,31 @@ namespace NCC.Extend @@ -597,14 +597,31 @@ namespace NCC.Extend
597 } 597 }
598 else 598 else
599 { 599 {
600 - // 老店:不区分门店分类和门店类型,使用统一比例  
601 - if (performanceReached) 600 + // 老店:根据门店分类和业绩是否达标确定提成比例
  601 + int? storeCategory = salary.StoreCategory;
  602 +
  603 + if (!storeCategory.HasValue)
602 { 604 {
603 - commissionRate = 0.04m; // 4%(业绩达标) 605 + throw new Exception($"老店【{salary.StoreName}】的门店分类未设置,无法计算提成");
604 } 606 }
605 - else 607 +
  608 + // 根据门店分类和业绩是否达标确定提成比例
  609 + // A类门店:未达标3%,达标3.5%
  610 + // B类门店:未达标3.5%,达标4%
  611 + // C类门店:未达标4%,达标4.5%
  612 + switch (storeCategory.Value)
606 { 613 {
607 - commissionRate = 0.035m; // 3.5%(业绩未达标) 614 + case (int)StoreCategoryEnum.A类门店: // A类门店
  615 + commissionRate = performanceReached ? 0.035m : 0.03m; // 达标3.5%,未达标3%
  616 + break;
  617 + case (int)StoreCategoryEnum.B类门店: // B类门店
  618 + commissionRate = performanceReached ? 0.04m : 0.035m; // 达标4%,未达标3.5%
  619 + break;
  620 + case (int)StoreCategoryEnum.C类门店: // C类门店
  621 + commissionRate = performanceReached ? 0.045m : 0.04m; // 达标4.5%,未达标4%
  622 + break;
  623 + default:
  624 + throw new Exception($"门店【{salary.StoreName}】的门店分类值无效:{storeCategory.Value},有效值为1(A类)、2(B类)、3(C类)");
608 } 625 }
609 } 626 }
610 627