using DS.Module.Core; using DS.Module.Core.Extensions; using DS.WMS.Core.Application.Dtos; using DS.WMS.Core.Code.Entity; using DS.WMS.Core.Fee.Dtos; using DS.WMS.Core.Fee.Entity; using DS.WMS.Core.Fee.Interface; using DS.WMS.Core.Flow.Dtos; using DS.WMS.Core.Flow.Interface; using DS.WMS.Core.Info.Entity; using DS.WMS.Core.Op.Dtos.TaskInteraction; using DS.WMS.Core.Op.Entity; using DS.WMS.Core.Op.Interface.TaskInteraction; using DS.WMS.Core.Sys.Entity; using Mapster; using Microsoft.Extensions.DependencyInjection; using SqlSugar; namespace DS.WMS.Core.Fee.Method { /// /// 费用审核 /// public class FeeAuditService : FeeServiceBase, IFeeAuditService { /// /// 待审核的状态值 /// public static readonly FeeStatus[] AuditStatusArray = [FeeStatus.AuditSubmitted, FeeStatus.ApplyDeletion, FeeStatus.ApplyModification]; //一键审核支持的类型 static readonly TaskBaseTypeEnum[] AuditTypes = [TaskBaseTypeEnum.FEE_AUDIT, TaskBaseTypeEnum.FEE_MODIFY_AUDIT, TaskBaseTypeEnum.FEE_DELETE_AUDIT, TaskBaseTypeEnum.FEE_BUSINESS_AUDIT]; readonly IClientFlowInstanceService flowService; readonly IFeeRecordService feeService; readonly ISeaExportTaskService taskService; /// /// 初始化 /// /// public FeeAuditService(IServiceProvider serviceProvider) : base(serviceProvider) { flowService = serviceProvider.GetRequiredService(); feeService = serviceProvider.GetRequiredService(); taskService = serviceProvider.GetRequiredService(); } /// /// 获取费用审核列表 /// /// /// public async Task>> GetListAsync(PageRequest request) { long[]? ids1 = null; long[]? ids2 = null; if (request.OtherQueryCondition) { var flows = await GetCurrentFlowsQuery(AuditTypes).Select(x => new { x.BusinessId, x.BusinessType, x.AuditType }).ToListAsync(); //没有待审批的列表直接返回不再执行后续查询 if (flows.Count == 0) return DataResult>.PageList(0, null, MultiLanguageConst.DataQuerySuccess); ids1 = flows.Where(x => x.AuditType != TaskBaseTypeEnum.FEE_BUSINESS_AUDIT).Select(x => x.BusinessId).ToArray(); ids2 = flows.Where(x => x.AuditType == TaskBaseTypeEnum.FEE_BUSINESS_AUDIT).Select(x => x.BusinessId).ToArray(); } var queryList = CreateQuery(ids1, ids2); if (!request.QueryCondition.IsNullOrEmpty()) { var whereList = request.GetConditionalModels(Db); queryList = queryList.Where(whereList); } var result = await queryList.Select().ToQueryPageAsync(request.PageCondition); if (result.Data.Count > 0) { //关联用户名称 var userIds = result.Data.Where(x => x.OperatorId.HasValue).Select(x => x.OperatorId.Value) .Union(result.Data.Select(x => x.CreateBy)) .Distinct(); var Users = await Db.Queryable().Where(x => userIds.Contains(x.Id)).Select(x => new { x.Id, x.UserName }).ToListAsync(); foreach (var item in result.Data) { item.CreateByName = Users.Find(x => x.Id == item.CreateBy)?.UserName; if (item.OperatorId.HasValue) { item.Operator = Users.Find(x => x.Id == item.OperatorId.Value)?.UserName; } } } return result; } /// /// 创建各项费用数据的查询并集 /// /// 费用ID /// 业务ID /// internal ISugarQueryable CreateQuery(long[]? ids1, long[]? ids2) { //海运出口 var query1 = TenantDb.Queryable((s, b, f, cs, csd) => new JoinQueryInfos( JoinType.Inner, s.Id == b.BusinessId && b.BusinessType == BusinessType.OceanShippingExport, JoinType.Inner, s.Id == f.BusinessId && f.BusinessType == BusinessType.OceanShippingExport && AuditStatusArray.Contains(f.FeeStatus), JoinType.Left, s.SourceId == cs.Id, JoinType.Left, s.SourceDetailId == csd.Id )) .WhereIF(ids1 != null && ids1.Length > 0 || ids2 != null && ids2.Length > 0, (s, b, f) => ids1.Contains(f.Id) || ids2.Contains(s.Id)) .GroupBy(s => s.Id) .Select((s, b, f, cs, csd) => new FeeAuditBusiness { Id = s.Id, AccountDate = s.AccountDate, APFeeStatus = b.APFeeStatus, ARFeeStatus = b.ARFeeStatus, BusinessType = BusinessType.OceanShippingExport, BusinessStatus = s.BusinessStatusName, BusinessDate = s.CreateTime,//业务日期 BLType = s.BLType, CargoId = s.CargoId, Carrier = s.Carrier, AgentId = s.AgentId, CBM = s.CBM, CntrTotal = s.CntrTotal, ContractNo = s.ContractNo, CreateBy = s.CreateBy, CustomerId = s.CustomerId, CustomerName = s.CustomerName,//委托单位 CustomerNo = s.CustomerNo, CustomerService = s.CustomerService, CustomNo = s.CustomNo, CustomsNum = s.CustomsNum, DangerClass = s.DangerClass, Destination = s.Destination, DischargePort = s.DischargePort, Doc = s.Doc, ETD = s.ETD, Forwarder = s.Forwarder, FeeId = f.FeeId, FeeCustomerId = f.CustomerId, FeeCustomerName = f.CustomerName, GoodsName = s.GoodsName, HBLNO = s.HBLNO, InvoiceNo = s.InvoiceNo, IsBusinessLocking = b.IsBusinessLocking, IsFeeLocking = b.IsFeeLocking, IssueType = s.IssueType, KGS = s.KGS, LoadPort = s.LoadPort, MBLFrt = s.MBLFrt, MBLNO = s.MBLNO, Note = s.Note, OperatorId = s.OperatorId, OrderNo = s.OrderNo, PKGS = s.PKGS, ReceiptPlace = s.ReceiptPlace, Remark = s.Remark, SaleDeptId = s.SaleDeptId, //SaleDeptName //所属部门 SaleId = s.SaleId, SaleName = s.Sale,//揽货人 SourceId = s.SourceId, SourceName = cs.SourceName, SourceDetailId = s.SourceDetailId, DetailName = csd.DetailName, TradeTerm = s.TradeTerm, TransitTerms = s.Service,//运输条款 Vessel = s.Vessel,//船名 Voyage = s.Voyno,//航次 Yard = s.Yard, //BusinessUnit = //经营单位 //ChangeOrder //更改单 //ChangeReason //更改单更改原因 //FreightRatio //运杂费比例 //查询:运输类型 (枚举值,暂未建立) //查询:是否费用提交 //查询:利润减少 }).MergeTable(); //海运进口 //var ids2 = additions?.Where(x => x.BusinessType == BusinessType.OceanShippingImport).Select(x => x.BusinessId).ToArray(); return TenantDb.UnionAll(new List> { query1 }); } /// /// 获取整票审核列表 /// /// /// public async Task>> GetBizListAsync(PageRequest request) { long[]? ids = null; if (request.OtherQueryCondition) { ids = await GetCurrentFlowsQuery(TaskBaseTypeEnum.FEE_BUSINESS_AUDIT).Select(x => x.BusinessId).Distinct().ToArrayAsync(); //没有待审批的列表直接返回不再执行后续查询 if (ids.Length == 0) return DataResult>.PageList(0, null, MultiLanguageConst.DataQuerySuccess); } var queryList = CreateBizQuery(ids); if (!request.QueryCondition.IsNullOrEmpty()) { var whereList = Db.ConfigQuery.Context.Utilities.JsonToConditionalModels(request.QueryCondition); queryList = queryList.Where(whereList); } var result = await queryList.Select().ToQueryPageAsync(request.PageCondition); if (result.Data.Count > 0) { //关联用户名称 var UserIds = result.Data.Where(x => x.OperatorId.HasValue).Select(x => x.OperatorId.Value) .Union(result.Data.Select(x => x.CreateBy)) .Distinct(); var Users = await Db.Queryable().Where(x => UserIds.Contains(x.Id)).Select(x => new { x.Id, x.UserName }).ToListAsync(); foreach (var item in result.Data) { item.CreateByName = Users.Find(x => x.Id == item.CreateBy)?.UserName; if (item.OperatorId.HasValue) { item.Operator = Users.Find(x => x.Id == item.OperatorId.Value)?.UserName; } } } return result; } //创建各项业务数据的查询并集 internal ISugarQueryable CreateBizQuery(params long[]? feeIds) { //海运出口 var query1 = TenantDb.Queryable((s, b, f, cs, csd) => new JoinQueryInfos( JoinType.Inner, s.Id == b.BusinessId && b.BusinessType == BusinessType.OceanShippingExport, JoinType.Inner, s.Id == f.BusinessId && f.BusinessType == BusinessType.OceanShippingExport && AuditStatusArray.Contains(f.FeeStatus), JoinType.Left, s.SourceId == cs.Id, JoinType.Left, s.SourceDetailId == csd.Id )) .WhereIF(feeIds != null && feeIds.Length > 0, (s, b, f, cs, csd) => feeIds.Contains(f.Id)) .GroupBy(s => s.Id) .Select((s, b, f, cs, csd) => new FeeAuditBusiness { Id = s.Id, AccountDate = s.AccountDate, APFeeStatus = b.APFeeStatus, ARFeeStatus = b.ARFeeStatus, BusinessType = BusinessType.OceanShippingExport, BusinessStatus = s.BusinessStatusName, BusinessDate = s.CreateTime,//业务日期 BLType = s.BLType, CargoId = s.CargoId, Carrier = s.Carrier, AgentId = s.AgentId, CBM = s.CBM, CntrTotal = s.CntrTotal, ContractNo = s.ContractNo, CreateBy = s.CreateBy, CustomerId = s.CustomerId, CustomerName = s.CustomerName,//委托单位 CustomerNo = s.CustomerNo, CustomerService = s.CustomerService, CustomNo = s.CustomNo, CustomsNum = s.CustomsNum, DangerClass = s.DangerClass, Destination = s.Destination, DischargePort = s.DischargePort, Doc = s.Doc, ETD = s.ETD, Forwarder = s.Forwarder, FeeId = f.FeeId, FeeCustomerId = f.CustomerId, FeeCustomerName = f.CustomerName, GoodsName = s.GoodsName, HBLNO = s.HBLNO, InvoiceNo = s.InvoiceNo, IsBusinessLocking = b.IsBusinessLocking, IsFeeLocking = b.IsFeeLocking, IssueType = s.IssueType, KGS = s.KGS, LoadPort = s.LoadPort, MBLFrt = s.MBLFrt, MBLNO = s.MBLNO, Note = s.Note, OperatorId = s.OperatorId, OrderNo = s.OrderNo, PKGS = s.PKGS, ReceiptPlace = s.ReceiptPlace, Remark = s.Remark, SaleDeptId = s.SaleDeptId, //SaleDeptName //所属部门 SaleId = s.SaleId, SaleName = s.Sale,//揽货人 SourceId = s.SourceId, SourceName = cs.SourceName, SourceDetailId = s.SourceDetailId, DetailName = csd.DetailName, TradeTerm = s.TradeTerm, TransitTerms = s.Service,//运输条款 Vessel = s.Vessel,//船名 Voyage = s.Voyno,//航次 Yard = s.Yard //BusinessUnit = //经营单位 //ChangeOrder //更改单 //ChangeReason //更改单更改原因 //FreightRatio //运杂费比例 //查询:运输类型 (枚举值,暂未建立) //查询:是否费用提交 //查询:利润减少 }); //海运进口 return TenantDb.UnionAll(new List> { query1 }); } /// /// 根据业务和查询条件获取费用明细 /// /// /// public async Task> GetFeesAsync(AuditDetailRequest request) { var pendingAudit = await TenantDb.Queryable().Where(x => x.Id == request.Id).Select(x => new PendingAuditFee { AccountDate = x.AccountDate, BusinessType = request.BusinessType, Carrier = x.Carrier, CustomerNo = x.CustomerNo, CustomerName = x.CustomerName, DischargePort = x.DischargePort, ETA = x.ETA, ETD = x.ETD, LoadPort = x.LoadPort, MBLNO = x.MBLNO, Vessel = x.Vessel, Voyno = x.Voyno }).FirstAsync(); if (pendingAudit != null) { long[] ids1 = []; long[] ids2 = []; if (request.AuditOnly) { var flows = await GetCurrentFlowsQuery(AuditTypes).Select(x => new { x.BusinessId, x.BusinessType, x.AuditType }).ToListAsync(); //没有待审批的列表直接返回不再执行后续查询 if (flows.Count == 0) return DataResult.Success(pendingAudit, MultiLanguageConst.DataQuerySuccess); ids1 = flows.Where(x => x.AuditType != TaskBaseTypeEnum.FEE_BUSINESS_AUDIT).Select(x => x.BusinessId).ToArray(); ids2 = flows.Where(x => x.AuditType == TaskBaseTypeEnum.FEE_BUSINESS_AUDIT).Select(x => x.BusinessId).ToArray(); } var fees = await TenantDb.Queryable().Where(f => f.BusinessId == request.Id && f.BusinessType == request.BusinessType) .Select(f => new { f.FeeType, f.Amount, f.ExchangeRate }).ToListAsync(); pendingAudit.IsPositiveProfit = fees.Where(x => x.FeeType == FeeType.Receivable).Sum(x => x.Amount * (x.ExchangeRate ?? 1)) - fees.Where(x => x.FeeType == FeeType.Payable).Sum(x => x.Amount * (x.ExchangeRate ?? 1)) > 0; pendingAudit.IsBusinessAudit = await flowService.Exists(TaskBaseTypeEnum.FEE_BUSINESS_AUDIT, request.BusinessType, null, request.Id); var query1 = TenantDb.Queryable().Where(f => f.BusinessId == request.Id && f.BusinessType == request.BusinessType) .InnerJoin((f, s) => f.BusinessId == s.Id) .LeftJoin((f, s, i) => f.CustomerId == i.Id) .WhereIF(ids1.Length > 0, (f, s, i) => (ids1.Contains(f.Id) || ids2.Contains(f.BusinessId)) && AuditStatusArray.Contains(f.FeeStatus)) .Select((f, s, i) => new FeeAuditItemQuery { Id = f.Id, BusinessId = f.BusinessId, BusinessType = f.BusinessType, FeeStatus = f.FeeStatus, FeeType = f.FeeType, FeeId = f.FeeId, FeeName = f.FeeName, FeeEnName = f.FeeEnName, CustomerId = f.CustomerId, CustomerName = f.CustomerName, CustomerFullName = i.Description, //结算对象全称 CustomerType = f.CustomerType, CustomerTypeText = f.CustomerTypeText, Unit = f.Unit, UnitText = f.UnitText, UnitPrice = f.UnitPrice, TaxUnitPrice = f.TaxUnitPrice, Quantity = f.Quantity, TaxRate = f.TaxRate, NoTaxAmount = f.NoTaxAmount, Amount = f.Amount, Currency = f.Currency, CurrencyText = f.CurrencyText, ExchangeRate = f.ExchangeRate, AccTaxRate = f.AccTaxRate,//销项汇率 Remark = f.Remark, IsAdvancedPay = f.IsAdvancedPay,//是否垫付 IsInvoice = f.IsInvoice, //是否开发票 //FRT CommissionRate = f.CommissionRate, //佣金比率 CreateBy = f.CreateBy, CreateTime = f.CreateTime, SettlementAmount = f.SettlementAmount,//结算金额 InvoiceAmount = f.InvoiceAmount,//开票金额 OrderAmount = f.OrderAmount,//申请金额 InvoiceNO = f.InvoiceNO,//发票号 Tax = f.Tax,//税额 DebitNo = f.DebitNo,//对账编号 SaleOrg = f.SaleOrg, Reason = f.Reason, CustomerNo = s.CustomerNo, Vessel = s.Vessel, Voyage = s.Voyno, SaleId = s.SaleId, ClientId = s.CustomerId, ClientName = s.CustomerName, BusinessDate = s.CreateTime, SourceId = s.SourceId, AccountDate = s.AccountDate, OperatorId = s.OperatorId }).MergeTable(); var queryList = TenantDb.UnionAll(new List> { query1 }); if (!request.QueryCondition.IsNullOrEmpty()) { var whereList = Db.ConfigQuery.Context.Utilities.JsonToConditionalModels(request.QueryCondition); queryList = queryList.Where(whereList); } var list = await queryList.Select().ToListAsync(); if (list.Count > 0) { //关联用户名称 var UserIds = list.Select(x => x.CreateBy).Distinct(); var Users = Db.Queryable().Where(x => UserIds.Contains(x.Id)).Select(x => new { x.Id, x.UserName }).ToList(); foreach (var item in list) { item.CreateByName = Users.Find(x => x.Id == item.CreateBy)?.UserName; } } //将查询结果组装成按费用分组的结构 pendingAudit.ItemGroups = []; for (int i = 0; i < list.Count; i++) { var item = list[i]; AuditItemGroup? group = pendingAudit.ItemGroups.Find(x => x.FeeName == item.FeeName && x.Items?.Count < 2); if (group == null) { group = new AuditItemGroup { FeeName = item.FeeName, Items = [item] }; pendingAudit.ItemGroups.Add(group); } else if (group.Items.Exists(x => x.FeeType == item.FeeType)) { group = new AuditItemGroup { FeeName = item.FeeName, Items = [item] }; pendingAudit.ItemGroups.Add(group); } else { group.Items.Add(item); } } } var result = DataResult.Success(pendingAudit); return result; } /// /// 获取业务费用统计 /// /// 业务ID /// 业务类型 /// 费用ID(可空) /// public async Task> GetStatAsync(long id, BusinessType businessType, long? feeId) { List? list = null; var feeQuery = TenantDb.Queryable().Where(x => x.BusinessId == id && x.BusinessType == businessType) .WhereIF(feeId.HasValue, x => x.FeeId == feeId.Value); switch (businessType) { case BusinessType.OceanShippingExport: list = await feeQuery.LeftJoin((f, s) => f.BusinessId == s.Id).Select((f, s) => new FeeRecordRes { BillNO = s.CustomerNo, CustomerName = s.CustomerName, FeeType = f.FeeType, Currency = f.Currency, LocalCurrency = f.LocalCurrency, Amount = f.Amount, NoTaxAmount = f.NoTaxAmount, ExchangeRate = f.ExchangeRate, AccTaxRate = f.AccTaxRate, TaxRate = f.TaxRate }).ToListAsync(); break; case BusinessType.OceanShippingImport: break; } FeeAuditStatistics stat = new(list ?? Enumerable.Empty()); return DataResult.Success(stat); } /// /// 按费用批量审核 /// /// 审批结果:1=通过,2=驳回 /// 备注 /// 待审批的费用ID /// /// 核心审核方法 public async Task AuditAsync(int yesOrNo, string? remark, params long[] idArray) { var fees = await TenantDb.Queryable().Where(x => idArray.Contains(x.Id)).Select(x => new { x.Id, x.FeeName, x.FeeStatus, }).ToListAsync(); if (fees.Count == 0) return DataResult.FailedWithDesc(nameof(MultiLanguageConst.EmptyData)); if (fees.Exists(x => !AuditStatusArray.Contains(x.FeeStatus))) return DataResult.FailedWithDesc(nameof(MultiLanguageConst.NotInAudit)); //未在审批状态中 if (!await flowService.Exists(ids: idArray)) return DataResult.FailedWithDesc(nameof(MultiLanguageConst.NotInAudit)); List> taskTypes = []; foreach (var fee in fees) { switch (fee.FeeStatus) { case FeeStatus.AuditSubmitted: taskTypes.Add(new Tuple(TaskBaseTypeEnum.FEE_AUDIT, fee.Id)); break; case FeeStatus.ApplyModification: taskTypes.Add(new Tuple(TaskBaseTypeEnum.FEE_MODIFY_AUDIT, fee.Id)); break; case FeeStatus.ApplyDeletion: taskTypes.Add(new Tuple(TaskBaseTypeEnum.FEE_DELETE_AUDIT, fee.Id)); break; } } DataResult result; var groups = taskTypes.GroupBy(x => x.Item1); bool hasAuthorized = await taskService.HasAuthorizedAsync(); foreach (var g in groups) { List list = []; var ids = g.Select(x => x.Item2).ToArray(); if (hasAuthorized) { result = await taskService.AuditAsync(new TaskAuditRequest { Ids = ids, Remark = remark, Result = yesOrNo, TaskTypeName = g.Key.ToString() }); if (!result.Succeeded) list.Add(result.Message); } else { var instances = await flowService.GetInstanceByBSIdAsync(g.Key, null, ids); foreach (var item in instances) { result = flowService.AuditFlowInstance(new FlowAuditInfo { Instance = item, Status = yesOrNo, AuditNote = remark }); if (!result.Succeeded) list.Add(fees.Find(x => x.Id == item.BusinessId)?.FeeName ?? string.Empty); } } if (list.Count > 0) return DataResult.Failed(string.Join("、", list)); } return DataResult.Success; } /// ///一键审核当前登录用户的所有待审核项 /// /// /// public async Task AuditAsync(AuditConditionRequest request) { var ids = await GetCurrentFlowsQuery(AuditTypes).Select(x => x.BusinessId).ToArrayAsync(); //没有待审批的列表直接返回不再执行后续查询 if (ids.Length == 0) return DataResult.FailedWithDesc(nameof(MultiLanguageConst.NoAuditItems)); List whereList = []; if (!string.IsNullOrEmpty(request.QueryString)) whereList = Db.Utilities.JsonToConditionalModels(request.QueryString); ids = await TenantDb.Queryable().Where(x => ids.Contains(x.Id)).Where(whereList) .Select(x => x.Id).ToArrayAsync(); return await AuditAsync(request.Result, request.Remark, ids); } /// /// 按业务批量审核 /// /// /// public async Task AuditAsync(BizAuditRequest request) { var ids = await GetCurrentFlowsQuery(TaskBaseTypeEnum.FEE_AUDIT).Select(x => x.BusinessId).ToArrayAsync(); var query = CreateQuery(ids, []); if (!request.QueryCondition.IsNullOrEmpty()) { var whereList = Db.Utilities.JsonToConditionalModels(request.QueryCondition); query = query.Where(whereList); } var bizList = await query.Select(x => new BizItem { Id = x.Id, BusinessType = x.BusinessType }).ToArrayAsync(); //取所选业务与过滤条件所产生的交集 var intersects = request.Items.Intersect(bizList, BizItem.DefaultComparer).ToList(); if (intersects.Count == 0) return DataResult.FailedWithDesc(nameof(MultiLanguageConst.NoAuditItems)); var list1 = intersects.Select(x => x.Id).ToList(); var list2 = intersects.Select(x => x.BusinessType).Distinct(); var recordIds = await TenantDb.Queryable().Where(x => list1.Contains(x.BusinessId) && list2.Contains(x.BusinessType) && x.FeeStatus == FeeStatus.AuditSubmitted) .Select(x => x.Id).ToArrayAsync(); //没有待审批的列表直接返回不再执行后续查询 if (recordIds.Length == 0) return DataResult.FailedWithDesc(nameof(MultiLanguageConst.NoAuditItems)); return await AuditAsync(request.Result, request.Remark, recordIds); } const TaskBaseTypeEnum BIZ_TASK_TYPE = TaskBaseTypeEnum.FEE_BUSINESS_AUDIT; /// /// 整票审核 /// /// 审批请求 /// public async Task AuditBusinessAsync(BizAuditRequest request) { DataResult result; bool hasAuthorized = await taskService.HasAuthorizedAsync(); var gpList = request.Items.GroupBy(x => x.BusinessType).ToList(); foreach (var gp in gpList) { var ids = gp.Select(x => x.Id).ToArray(); var bizList = await TenantDb.Queryable().Where(x => ids.Contains(x.BusinessId) && x.BusinessType == gp.Key) .Select(x => new { x.Id, x.BillAuditStatus, }).ToListAsync(); if (bizList.Count == 0) return DataResult.FailedWithDesc(nameof(MultiLanguageConst.EmptyData)); if (bizList.Any(x => x.BillAuditStatus != BillAuditStatus.AuditSubmitted)) return DataResult.FailedWithDesc(nameof(MultiLanguageConst.BusinessAuditStatusError)); if (hasAuthorized) { result = await taskService.AuditAsync(new TaskAuditRequest { Ids = ids, Remark = request.Remark, Result = request.Result, TaskTypeName = BIZ_TASK_TYPE.ToString() }); if (!result.Succeeded) return result; } else { var flows = await flowService.GetInstanceByBSIdAsync(BIZ_TASK_TYPE, gp.Key, ids); if (flows.Count == 0) return DataResult.FailedWithDesc(nameof(MultiLanguageConst.FlowNotFound)); if (flows.Any(x => !x.MakerList.Contains(User.UserId))) continue; foreach (var flow in flows) { result = flowService.AuditFlowInstance(new FlowAuditInfo { Instance = flow, Status = request.Result, AuditNote = request.Remark }); if (!result.Succeeded) return result; } } } return DataResult.Success; } /// /// 设置业务费用锁定状态 /// /// 业务信息 /// public async Task SetFeeLockingAsync(IEnumerable items) { int rows = await TenantDb.Updateable(items) .WhereColumns(x => new { x.BusinessId, x.BusinessType }) .UpdateColumns(x => new { x.IsFeeLocking }) .ExecuteCommandAsync(); return rows > 0 ? DataResult.Success : DataResult.Failed(MultiLanguageConst.Operation_Failed); } /// /// 根据审批结果更新审批状态 /// /// 回调信息 /// public async Task UpdateStatusAsync(FlowCallback callback) { var auditType = callback.AuditType; FeeRecord? fee = null; BusinessFeeStatus? biz = null; if (auditType == TaskBaseTypeEnum.FEE_BUSINESS_AUDIT) { biz = await TenantDb.Queryable().Where(x => x.Id == callback.BusinessId && x.BusinessType == callback.BusinessType) .Select(x => new BusinessFeeStatus { Id = x.Id, BusinessId = x.BusinessId, BusinessType = x.BusinessType, BillAuditStatus = x.BillAuditStatus }).FirstAsync(); if (biz == null) return DataResult.Failed(MultiLanguageConst.EmptyData); } else { fee = await TenantDb.Queryable().Where(x => x.Id == callback.BusinessId).Select( x => new FeeRecord { Id = x.Id, FeeStatus = x.FeeStatus, BusinessId = x.BusinessId, BusinessType = x.BusinessType }).FirstAsync(); if (fee == null) return DataResult.Failed(MultiLanguageConst.EmptyData); fee.Reason = callback.RejectReason; } long UserId = long.Parse(User.UserId); DateTime dtNow = DateTime.Now; await TenantDb.Ado.BeginTranAsync(); try { switch (auditType) { case TaskBaseTypeEnum.FEE_AUDIT: fee.AuditBy = UserId; fee.AuditOperator = User.UserName; fee.AuditDate = dtNow; if (callback.FlowStatus == FlowStatusEnum.Approve) { fee.FeeStatus = FeeStatus.AuditPassed; fee.Reason = string.Empty; } else if (callback.FlowStatus == FlowStatusEnum.Reject) fee.FeeStatus = FeeStatus.RejectSubmission; await TenantDb.Updateable(fee).UpdateColumns(x => new { x.FeeStatus, x.AuditBy, x.AuditOperator, x.AuditDate, x.Reason }).ExecuteCommandAsync(); break; case TaskBaseTypeEnum.FEE_MODIFY_AUDIT: //申请修改审核成功需要回填费用信息 if (callback.FlowStatus == FlowStatusEnum.Approve) { var fm = await TenantDb.Queryable().Where(x => x.FeeRecordId == fee.Id).OrderByDescending(x => x.CreateTime).FirstAsync(); if (fm == null) return DataResult.Failed(MultiLanguageConst.FeeRecordNotExist); var entity = fm.Adapt(); entity.Id = fm.FeeRecordId; entity.FeeStatus = FeeStatus.AuditPassed; entity.Reason = callback.RejectReason; entity.UpdateBy = UserId; entity.UpdateTime = dtNow; //全表更新 await TenantDb.Updateable(entity).IgnoreColumns( x => new { x.AuditBy, x.AuditDate, x.AuditOperator, x.SubmitBy, x.SubmitDate }).ExecuteCommandAsync(); //逻辑删除暂存数据 fm.Deleted = true; fm.DeleteTime = dtNow; fm.DeleteBy = UserId; await TenantDb.Updateable(fm).UpdateColumns(x => new { x.DeleteBy, x.Deleted, x.DeleteTime }).ExecuteCommandAsync(); } else if (callback.FlowStatus == FlowStatusEnum.Reject) { fee.FeeStatus = FeeStatus.RejectApplication; await TenantDb.Updateable(fee).UpdateColumns(x => new { x.FeeStatus, x.Reason }).ExecuteCommandAsync(); } break; case TaskBaseTypeEnum.FEE_DELETE_AUDIT: if (callback.FlowStatus == FlowStatusEnum.Approve) { fee.Deleted = true; fee.DeleteBy = UserId; fee.DeleteTime = dtNow; await TenantDb.Updateable(fee).UpdateColumns(x => new { x.DeleteBy, x.Deleted, x.DeleteTime, x.Reason }).ExecuteCommandAsync(); //TenantDb.Deleteable(fee).ExecuteCommandAsync(); } else { fee.FeeStatus = FeeStatus.RejectApplication; await TenantDb.Updateable(fee).UpdateColumns(x => new { x.FeeStatus, x.Reason }).ExecuteCommandAsync(); } break; case TaskBaseTypeEnum.FEE_BUSINESS_AUDIT: FeeStatus status = FeeStatus.RejectSubmission; if (callback.FlowStatus == FlowStatusEnum.Approve) { biz.BillAuditStatus = BillAuditStatus.AuditPassed; status = FeeStatus.AuditPassed; } else if (callback.FlowStatus == FlowStatusEnum.Reject) { biz.BillAuditStatus = BillAuditStatus.Rejected; } await TenantDb.Updateable(biz).UpdateColumns(x => new { x.BillAuditStatus }).ExecuteCommandAsync(); await TenantDb.Updateable() .SetColumns(x => x.FeeStatus == status) .SetColumns(x => x.AuditBy == UserId) .SetColumns(x => x.AuditOperator == User.UserName) .SetColumns(x => x.AuditDate == dtNow) .Where(x => x.BusinessId == biz.BusinessId && x.BusinessType == biz.BusinessType && x.FeeStatus != FeeStatus.PartialSettlement && x.FeeStatus != FeeStatus.SettlementCompleted).ExecuteCommandAsync(); break; } ////驳回申请则逻辑删除关联工作流 //if (callback.FlowStatus == FlowStatusEnum.Reject) //{ // await Db.Updateable(new FlowInstance // { // Id = callback.InstanceId, // Deleted = true, // DeleteBy = 0, // DeleteTime = DateTime.Now // }).UpdateColumns(x => new { x.Deleted, x.DeleteBy, x.DeleteTime }).ExecuteCommandAsync(); //} await TenantDb.Ado.CommitTranAsync(); if (auditType != TaskBaseTypeEnum.FEE_BUSINESS_AUDIT) { await feeService.WriteBackStatusAsync( auditType == TaskBaseTypeEnum.FEE_BUSINESS_AUDIT ? biz.BusinessId : fee.BusinessId, auditType == TaskBaseTypeEnum.FEE_BUSINESS_AUDIT ? biz.BusinessType : fee.BusinessType); } return DataResult.Success; } catch (Exception ex) { await TenantDb.Ado.RollbackTranAsync(); await ex.LogAsync(Db); return DataResult.Failed(MultiLanguageConst.Operation_Failed); } } } }