using DS.Module.Core; using DS.Module.Core.Enums; using DS.Module.Core.Extensions; using DS.WMS.Core.Application.Dtos; using DS.WMS.Core.Application.Entity; using DS.WMS.Core.Application.Interface; using DS.WMS.Core.Code.Entity; using DS.WMS.Core.Fee.Entity; using DS.WMS.Core.Flow.Dtos; using DS.WMS.Core.Info.Entity; using DS.WMS.Core.Op.Entity; using DS.WMS.Core.Sys.Entity; using SqlSugar; namespace DS.WMS.Core.Application.Method { /// /// 费用申请单审核服务 /// public class PaymentApplicationAuditService : ApplicationAuditService, IPaymentApplicationAuditService { /// /// 初始化 /// /// public PaymentApplicationAuditService(IServiceProvider serviceProvider) : base(serviceProvider) { } /// /// 获取分页列表 /// /// /// public async Task>> GetListAsync(PageRequest request) { var query = CreateListQuery(); if (!request.QueryCondition.IsNullOrEmpty()) { var whereList = Db.ConfigQuery.Context.Utilities.JsonToConditionalModels(request.QueryCondition); switch (request.OtherQueryCondition) { case AuditStatusForQuery.Pending: query = query.Where(x => x.AuditerId == null); break; case AuditStatusForQuery.Audited: query = query.Where(x => x.AuditerId != null); break; case AuditStatusForQuery.MarkerOnly: var ids = await GetCurrentFlowsQuery(AuditTypes).Select(x => x.BusinessId).ToListAsync(); if (ids.Count == 0) ids.Add(0L); query = query.Where(x => ids.Contains(x.Id)); break; } query = query.Where(whereList); } var result = await query.GroupBy(x => x.Id).ToQueryPageAsync(request.PageCondition); if (result.Data.Count > 0) { var orgIds = result.Data.Select(x => x.SaleDeptId).Distinct().ToList(); var orgs = await Db.Queryable().Where(x => orgIds.Contains(x.Id)).Select(x => new { x.Id, x.OrgName }).ToListAsync(); foreach (var item in result.Data) { item.SaleDeptName = orgs.Find(x => x.Id == item.SaleDeptId)?.OrgName; } } return result; } internal ISugarQueryable CreateListQuery() { var query1 = TenantDb.Queryable().Where(x => x.Status == PaymentApplicationStatus.AuditSubmittd) .LeftJoin((a, d) => a.Id == d.ApplicationId) .InnerJoin((a, d, f) => d.RecordId == f.Id) .LeftJoin((a, d, f, s) => f.BusinessId == s.Id) .LeftJoin((a, d, f, s, b) => a.CustomerBankId == b.Id) .Select((a, d, f, s, b) => new PaymentApplicationDto { Id = a.Id, ApplicationNO = a.ApplicationNO, CustomerId = a.CustomerId, CustomerName = a.CustomerName, AmountOther = a.AmountOther, AmountRMB = a.AmountRMB, AmountUSD = a.AmountUSD, SaleDeptId = a.SaleDeptId, CreateBy = a.CreateBy, CreateTime = a.CreateTime,//付费申请日期 Currency = a.Currency, Reason = a.Reason, Status = a.Status, AuditerId = a.AuditerId, AuditerName = a.AuditerName, AuditTime = a.AuditTime, IsInvoiceReceived = a.IsInvoiceReceived, ClientName = s.CustomerName, IsPrinted = a.IsPrinted, PrintTimes = a.PrintTimes, InvoiceAmount = a.InvoiceAmount, InvoiceDate = a.InvoiceDate, InvoiceNO = a.InvoiceNO, SettlementTypeName = a.SettlementType.StlName, PaymentDate = a.PaymentDate, Note = a.Note, BillNO = s.CustomerNo, //业务编号=委托编号 CustomerBankId = a.CustomerBankId, CustomerBank = b.BankName, CustomerAccount = b.Account }); return TenantDb.UnionAll(new List> { query1 }); } /// /// 获取申请单明细 /// /// 申请单ID /// public async Task> GetDetailsAsync(long id) { var details = await TenantDb.Queryable() .InnerJoin((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.ApplyAmount, 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 ApplicationSummary(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 == FeeCurrency.RMB_CODE).Sum(x => x.Amount); stat.ReceivableUSD = fees.FindAll(x => x.FeeType == FeeType.Receivable && x.Currency == FeeCurrency.USD_CODE).Sum(x => x.Amount); stat.ReceivableOther = fees.FindAll(x => x.FeeType == FeeType.Receivable && x.Currency != FeeCurrency.USD_CODE && x.Currency != FeeCurrency.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 == FeeCurrency.RMB_CODE).Sum(x => x.Amount); stat.PayableUSD = fees.FindAll(x => x.FeeType == FeeType.Payable && x.Currency == FeeCurrency.USD_CODE).Sum(x => x.Amount); stat.PayableOther = fees.FindAll(x => x.FeeType == FeeType.Payable && x.Currency != FeeCurrency.USD_CODE && x.Currency != FeeCurrency.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.FailedWithDesc(nameof(MultiLanguageConst.ApplicationIsNotAuditing)); return DataResult.Success; } protected override async Task OnUpdateStatusAsync(FlowCallback callback, PaymentApplication application) { var auditType = callback.AuditType; if (auditType != TaskBaseTypeEnum.APPLICATION_PAYMENT_AUDIT) 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); } } }