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.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 { internal static readonly FeeStatus[] FeeStatusArray = [FeeStatus.AuditPassed, FeeStatus.PartialSettlement, FeeStatus.SettlementCompleted]; public override TaskBaseTypeEnum AuditType => TaskBaseTypeEnum.APPLICATION_PAYMENT_AUDIT; /// /// 初始化 /// /// public PaymentApplicationAuditService(IServiceProvider serviceProvider) : base(serviceProvider) { } /// /// 获取分页列表 /// /// /// public async Task>> GetListAsync(PageRequest request) { var query = CreateListQuery(); if (!request.QueryCondition.IsNullOrEmpty()) { var whereList = request.GetConditionalModels(Db); query = query.Where(whereList); } switch (request.OtherQueryCondition) { case AuditStatusForQuery.Pending: query = query.Where(x => x.Status == PaymentApplicationStatus.AuditSubmittd); break; case AuditStatusForQuery.Audited: query = query.Where(x => x.Status == PaymentApplicationStatus.AuditPassed || x.Status == PaymentApplicationStatus.AuditRejected); break; case AuditStatusForQuery.MarkerOnly: var ids = await GetCurrentFlowsQuery([AuditType]).Select(x => x.BusinessId).ToListAsync(); if (ids.Count == 0) ids.Add(0L); query = query.Where(x => x.Status == PaymentApplicationStatus.AuditSubmittd && ids.Contains(x.Id)); break; } 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(); var orgs = await Db.Queryable().Where(x => orgIds.Contains(x.Id)).Select(x => new { x.Id, x.OrgName }).ToListAsync(); var userIds = 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.SaleDeptName = orgs.Find(x => x.Id == item.SaleDeptId)?.OrgName; item.SaleDeptName = users.Find(x => x.Id == item.CreateBy)?.UserName; } } return result; } internal ISugarQueryable CreateListQuery() { var query1 = TenantDb.Queryable() .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 { InvoiceNO = a.InvoiceNO, SettlementTypeName = a.SettlementType.StlName, BillNO = s.CustomerNo, //业务编号=委托编号 CustomerBankName = b.BankName, CustomerAccount = b.Account }, true); 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 /// public async Task> GetApplicationStatAsync(long id) { var fees = await TenantDb.Queryable().InnerJoin((f, d) => f.Id == d.RecordId) .Where((f, d) => d.ApplicationId == id) .Select((f, d) => new { f.CustomerId, f.Currency, f.FeeType, f.Amount, RestAmount = f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount }).ToListAsync(); FeeBiz model = new() { PayableCNY = fees.Where(x => x.Currency == FeeCurrency.RMB_CODE).Sum(x => x.Amount), PayableUSD = fees.Where(x => x.Currency == FeeCurrency.USD_CODE).Sum(x => x.Amount), 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 = x.Where(y => y.Currency == x.Key).Sum(y => y.RestAmount) }).ToList() }; if (fees.Count > 0) { var customerId = fees[0].CustomerId; model.RecvByCustomer = await TenantDb.Queryable().Where(x => x.CustomerId == customerId) .SumAsync(x => x.Amount * (x.ExchangeRate == null ? 1 : x.ExchangeRate.Value)); } return DataResult.Success(model); } /// /// 获取按票统计 /// /// 申请单ID /// public async Task>> GetBizStatAsync(long id) { var query1 = TenantDb.Queryable() .InnerJoin((d, f) => d.RecordId == f.Id && f.BusinessType == BusinessType.OceanShippingExport) .InnerJoin((d, f, s) => f.BusinessId == s.Id) .LeftJoin((d, f, s, b) => s.Id == b.BusinessId && b.BusinessType == BusinessType.OceanShippingExport) .Where((d, f, s, b) => d.ApplicationId == id) .GroupBy((d, f, s, b) => s.Id) .Select((d, f, s, b) => new BizFeeStat { BusinessId = s.Id, BusinessType = BusinessType.OceanShippingExport, IsBusinessLocking = b.IsBusinessLocking, IsFeeLocking = b.IsFeeLocking }, true); var list = await TenantDb.UnionAll(query1).ToListAsync(); if (list.Count == 0) return DataResult>.Success(list); var ids = list.Select(x => x.BusinessId).Distinct(); var types = list.Select(x => x.BusinessType).Distinct(); var feeList = await TenantDb.Queryable().Where(f => ids.Contains(f.BusinessId) && types.Contains(f.BusinessType) && FeeStatusArray.Contains(f.FeeStatus)) .Select(x => new { x.BusinessId, x.BusinessType, x.FeeType, x.Currency, x.Amount }).ToListAsync(); var usersId = list.Where(x => x.OperatorId.HasValue).Select(x => x.OperatorId.Value).Distinct(); var users = await Db.Queryable().Where(x => usersId.Contains(x.Id)).Select(x => new { x.Id, x.UserName }).ToListAsync(); foreach (var stat in list) { var fees = feeList.FindAll(x => x.BusinessId == stat.BusinessId && x.BusinessType == stat.BusinessType); 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); stat.Operator = stat.OperatorId.HasValue ? users.Find(x => x.Id == stat.OperatorId.Value)?.UserName : string.Empty; } return DataResult>.Success(list); } 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); } } }