Commit 4fa0ea166e8de737132850054cd1982a436fa3b6
1 parent
12ccf031
修复门店领取统计接口SQL语法错误,修复店长工资提成计算逻辑
- 修复GetStoreReceiveStatistics接口:将表别名从usage改为u(usage是MySQL保留关键字) - 修复店长工资计算:根据门店分类(A/B/C)正确计算老店提成比例 - 开单品项明细接口:返回支付医院和合作机构中文名称 - 修改开单金额接口:支持修改品项备注 - 报销申请接口:返回完成时间并支持按完成时间筛选 - 店内支出导入:使用门店名称匹配并存储门店ID
Showing
9 changed files
with
178 additions
and
65 deletions
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 |