using DS.Module.Core; using DS.Module.Core.Enums; using DS.WMS.Core.Application.Dtos; using DS.WMS.Core.Application.Entity; using DS.WMS.Core.Code.Entity; using DS.WMS.Core.Fee.Entity; using DS.WMS.Core.Flow.Dtos; using DS.WMS.Core.Op.Entity; using DS.WMS.Core.Sys.Entity; namespace DS.WMS.Core.Application.Method { /// /// 费用申请单审核服务 /// public class PaymentApplicationAuditService : ApplicationAuditService { /// /// 初始化 /// /// public PaymentApplicationAuditService(IServiceProvider serviceProvider) : base(serviceProvider) { } /// /// 获取申请单明细 /// /// 申请单ID /// public async Task> GetDetailsAsync(long id) { var details = await TenantDb.Queryable() .LeftJoin((d, f) => d.RecordId == f.Id) .LeftJoin((d, f, b) => f.BusinessId == b.BusinessId && f.BusinessType == b.BusinessType) .Where(d => d.ApplicationId == id) .Select((d, f, b) => new PaymentApplicationDetailDto { AccTaxRate = f.AccTaxRate, Amount = d.Amount, CustomerId = f.CustomerId, FeeName = d.FeeName, FeeType = f.FeeType, ClientName = f.CustomerName, OriginalCurrency = d.OriginalCurrency, OriginalRate = f.ExchangeRate, ExchangeRate = d.ExchangeRate, OriginalAmount = d.OriginalAmount, BusinessId = b.BusinessId, BusinessType = b.BusinessType, IsBusinessLocking = b.IsBusinessLocking, IsFeeLocking = b.IsFeeLocking }).ToListAsync(); if (details.Count > 0) { var gList = details.GroupBy(x => x.BusinessType).ToList(); foreach (var g in gList) { var ids = g.Select(x => x.BusinessId).ToList(); switch (g.Key) { case BusinessType.OceanShippingExport: var list1 = await TenantDb.Queryable().Where(x => ids.Contains(x.Id)).Select(x => new { x.Id, x.MBLNO, x.CustomerNo, x.CustomerName, x.ETD, x.CntrTotal, x.AccountDate, x.OperatorCode, x.Vessel, x.Voyno, x.Carrier, x.Forwarder, x.BookingNo }).ToListAsync(); foreach (var item in g) { var biz = list1.Find(x => x.Id == item.BusinessId); if (biz != null) { item.MBLNO = biz.MBLNO; item.CustomerName = biz.CustomerName; item.CustomerNo = biz.CustomerNo; item.ETD = biz.ETD; item.CntrTotal = biz.CntrTotal; item.AccountDate = biz.AccountDate; item.Operator = biz.OperatorCode; item.Vessel = biz.Vessel; item.Voyage = biz.Voyno; item.Carrier = biz.Carrier; item.Forwarder = biz.Forwarder; item.BookingNo = biz.BookingNo; } } break; case BusinessType.OceanShippingImport: break; } } } var model = new FeeApplicationSummary(details); var customerId = details.GroupBy(x => x.CustomerId).Select(x => x.Key).FirstOrDefault(); return DataResult.Success(model); } /// /// 获取业务费用统计 /// /// 业务ID /// 业务类型 /// 结算对象ID /// public async Task> GetFeeBizAsync(long id, BusinessType businessType, long customerId) { FeeBiz model = new() { ReceivableTotal = (await TenantDb.Queryable().Where(x => x.CustomerId == customerId && x.FeeType == FeeType.Receivable && x.FeeStatus == FeeStatus.AuditPassed).SumAsync(x => x.Amount)) }; var fees = await TenantDb.Queryable().Where(x => x.BusinessId == id && x.BusinessType == businessType && x.FeeStatus == FeeStatus.AuditPassed) .Select(x => new { x.Currency, x.FeeType, x.Amount, }).ToListAsync(); model.TotalItems = fees.GroupBy(x => x.Currency).Select(x => new TotalItem { Currency = x.Key, PayableAmount = x.Where(y => y.FeeType == FeeType.Payable && y.Currency == x.Key).Sum(y => y.Amount), ReceivableAmount = x.Where(y => y.FeeType == FeeType.Receivable && y.Currency == x.Key).Sum(y => y.Amount), RestAmount = 0 //todo:未收 }).ToList(); return DataResult.Success(model); } /// /// 获取按票统计 /// /// 业务ID /// 业务类型 /// public async Task> GetStatAsync(long id, BusinessType businessType) { BizFeeStat? stat = null; switch (businessType) { case BusinessType.OceanShippingExport: stat = await TenantDb.Queryable() .InnerJoin((b, s) => b.BusinessId == s.Id) .LeftJoin((b, s, cs) => s.SourceId == cs.Id) .LeftJoin((b, s, cs, csd) => s.SourceDetailId == csd.Id) .Select((b, s, cs, csd) => new BizFeeStat { IsBusinessLocking = b.IsBusinessLocking, IsFeeLocking = b.IsFeeLocking, HBLNO = s.HBLNO, MBLNO = s.MBLNO, CustomerNo = s.CustomerNo, CustomerName = s.CustomerName, ETD = s.ETD, ETA = s.ETA, CntrTotal = s.CntrTotal, AccountDate = s.AccountDate, OperatorId = s.OperatorId, Vessel = s.Vessel, Voyage = s.Voyno, Carrier = s.Carrier, Forwarder = s.Forwarder, BookingNo = s.BookingNo, CustomsDate = s.CustomDate, LoadPort = s.LoadPort, DischargePort = s.DischargePort, Destination = s.Destination, Yard = s.Yard, Agent = s.Agent, TEU = s.TEU, GoodsName = s.GoodsName, IssueType = s.IssueType, SourceName = cs.SourceName, SourceDetailName = csd.DetailName }).FirstAsync(); break; case BusinessType.OceanShippingImport: break; } if (stat == null) return DataResult.Success(stat); var fees = await TenantDb.Queryable().Where(f => f.BusinessId == id && f.BusinessType == businessType && f.FeeStatus == FeeStatus.AuditPassed) .Select(x => new { x.FeeType, x.Currency, x.Amount }).ToListAsync(); stat.ReceivableTotal = fees.FindAll(x => x.FeeType == FeeType.Receivable).Sum(x => x.Amount); stat.ReceivableCNY = fees.FindAll(x => x.FeeType == FeeType.Receivable && x.Currency == RMB_CODE).Sum(x => x.Amount); stat.ReceivableUSD = fees.FindAll(x => x.FeeType == FeeType.Receivable && x.Currency == USD_CODE).Sum(x => x.Amount); stat.ReceivableOther = fees.FindAll(x => x.FeeType == FeeType.Receivable && x.Currency != USD_CODE && x.Currency != RMB_CODE).Sum(x => x.Amount); stat.PayableTotal = fees.FindAll(x => x.FeeType == FeeType.Payable).Sum(x => x.Amount); stat.PayableCNY = fees.FindAll(x => x.FeeType == FeeType.Payable && x.Currency == RMB_CODE).Sum(x => x.Amount); stat.PayableUSD = fees.FindAll(x => x.FeeType == FeeType.Payable && x.Currency == USD_CODE).Sum(x => x.Amount); stat.PayableOther = fees.FindAll(x => x.FeeType == FeeType.Payable && x.Currency != USD_CODE && x.Currency != RMB_CODE).Sum(x => x.Amount); long?[] usersId = [stat.OperatorId]; if (Array.Exists(usersId, x => x.HasValue)) { var users = await Db.Queryable().Where(x => usersId.Contains(x.Id)).Select(x => new { x.Id, x.UserName }).ToListAsync(); stat.Operator = users.Find(x => x.Id == stat.OperatorId)?.UserName; } return DataResult.Success(stat); } protected override DataResult PreAudit(List applications) { if (applications.Exists(x => x.Status != PaymentApplicationStatus.AuditSubmittd)) return DataResult.Failed("提交数据中包含不在待审批状态的申请单"); return DataResult.Success; } protected override async Task OnUpdateStatusAsync(FlowCallback callback, PaymentApplication application) { var auditType = callback.AuditType.ToEnum(); if (auditType != AuditType.PaidApplication) return; if (callback.FlowStatus == FlowStatusEnum.Approve) { application.Status = PaymentApplicationStatus.AuditPassed; application.Reason = string.Empty; } else if (callback.FlowStatus == FlowStatusEnum.Reject) application.Status = PaymentApplicationStatus.AuditRejected; await base.OnUpdateStatusAsync(callback, application); } } }