using System.Text; 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.Fee.Entity; using DS.WMS.Core.Invoice.Dtos; using DS.WMS.Core.Op.Entity; using DS.WMS.Core.Settlement.Dtos; using DS.WMS.Core.Settlement.Entity; using DS.WMS.Core.Settlement.Interface; using DS.WMS.Core.Sys.Entity; using SqlSugar; namespace DS.WMS.Core.Settlement.Method { /// /// 发票结算 /// public class InvoiceSettlementService : SettlementService, IInvoiceSettlementService { /// /// 初始化 /// /// public InvoiceSettlementService(IServiceProvider provider) : base(provider) { } /// /// 获取结算单详情 /// /// 结算单ID /// public async Task> GetAsync(long id) { var model = await TenantDb.Queryable().Select(x => new ApplicationSettlementDto { SettlementTypeName = x.SettlementType.StlName, //结算方式 CustomerBankName = x.CustomerBank.BankName, CustomerAccount = x.CustomerBank.Account }, true).FirstAsync(x => x.Id == id); if (model != null) { if (model.SaleDeptId.HasValue) model.SaleDeptName = await Db.Queryable().Where(x => x.Id == model.SaleDeptId.Value) .Select(x => x.OrgName).FirstAsync(); model.SettlementDetails = await GetSettlementDetails(id); if (model.SettlementDetails.Count > 0) { //关联用户名称 var userIds = model.SettlementDetails.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 model.SettlementDetails) { item.CreateByName = users.Find(x => x.Id == item.CreateBy)?.UserName; } } } return DataResult.Success(model); } /// /// 获取待结算的发票列表 /// /// /// public async Task>> GetInvoiceListAsync(PageRequest request) { var whereList = request.GetConditionalModels(Db); var result = await TenantDb.Queryable() .InnerJoin((a, d) => d.Category == DetailCategory.InvoiceIssuance && a.Id == d.ApplicationId) .InnerJoin((a, d, f) => d.RecordId == f.Id && (f.FeeStatus == FeeStatus.AuditPassed || f.FeeStatus == FeeStatus.PartialSettlement) && ((f.Amount > 0 && d.OriginalAmount - d.OriginalProcessedAmount > 0 && d.OriginalAmount - d.OriginalProcessedAmount <= f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount) || (f.Amount < 0 && d.OriginalAmount - d.OriginalProcessedAmount < 0 && d.OriginalAmount - d.OriginalProcessedAmount >= f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount)) ) .GroupBy((a, d, f) => a.Id) .Select((a, d, f) => new InvoiceDto { //RMB未结金额 UnSettledRMB = SqlFunc.Subqueryable().Where(d => d.ApplicationId == a.Id && d.Currency == FeeCurrency.RMB_CODE) .Select(d => SqlFunc.AggregateSum(d.ApplyAmount - d.ProcessedAmount)), //USD未结金额 UnSettledUSD = SqlFunc.Subqueryable().Where(d => d.ApplicationId == a.Id && d.Currency == FeeCurrency.USD_CODE) .Select(d => SqlFunc.AggregateSum(d.ApplyAmount - d.ProcessedAmount)), //USD未结其他 UnSettledOther = SqlFunc.Subqueryable().Where(d => d.ApplicationId == a.Id && d.Currency != FeeCurrency.RMB_CODE && d.Currency != FeeCurrency.USD_CODE) .Select(d => SqlFunc.AggregateSum(d.ApplyAmount - d.ProcessedAmount)), }, true).MergeTable().Where(whereList).ToQueryPageAsync(request.PageCondition); if (result.Data?.Count > 0) { //关联用户名称 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(); 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(); var ids = result.Data.Select(x => x.Id); var details = await TenantDb.Queryable().Where(x => ids.Contains(x.ApplicationId) && x.Category == DetailCategory.InvoiceIssuance).Select().ToListAsync(); foreach (var item in result.Data) { item.CreateByName = users.Find(x => x.Id == item.CreateBy)?.UserName; item.SaleDeptName = orgs.Find(x => x.Id == item.SaleDeptId)?.OrgName; item.SettlementRMB = item.UnSettledRMB; item.SettlementUSD = item.UnSettledUSD; item.SettlementOther = item.UnSettledOther; item.Details = details.FindAll(x => x.ApplicationId == item.Id); } } return result; } /// /// 获取发票申请费用明细 /// /// /// public async Task>> GetInvoiceDetailsAsync(params long[] ids) { var query1 = TenantDb.Queryable() .InnerJoin((d, f) => d.Category == DetailCategory.InvoiceIssuance && d.RecordId == f.Id && (f.FeeStatus == FeeStatus.AuditPassed || f.FeeStatus == FeeStatus.PartialSettlement) && f.BusinessType == BusinessType.OceanShippingExport && ((f.Amount > 0 && d.OriginalAmount - d.OriginalProcessedAmount <= f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount) || (f.Amount < 0 && d.OriginalAmount - d.OriginalProcessedAmount >= f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount)) ) .LeftJoin((d, f, s) => f.BusinessId == s.Id) .Where((d, f, s) => ids.Contains(d.ApplicationId)) .Select((d, f, s) => new ApplicationDetailDto { ClientName = s.CustomerName, Voyage = s.Voyno, SourceName = s.SourceName, }, true); var list = await TenantDb.UnionAll(query1).ToListAsync(); var result = DataResult>.Success(list); result.Count = list.Count; return result; } /// /// 获取发票费用明细的原始币别 /// /// /// public async Task>> GetExchangesAsync(List documents) { var ids = documents.Select(x => x.Id); var list = await TenantDb.Queryable() .Where(d => ids.Contains(d.ApplicationId) && d.Category == DetailCategory.InvoiceIssuance) //.GroupBy(d => d.ApplicationId) .Select(d => new { d.ApplicationId, d.OriginalCurrency }).ToListAsync(); foreach (var document in documents) { document.ExchangeRates ??= []; //获取该发票费用明细的全部币别 var items = list.FindAll(x => x.ApplicationId == document.Id); foreach (var item in items) { if (!document.ExchangeRates.Exists(x => x.Currency == item.OriginalCurrency)) document.ExchangeRates.Add(new CurrencyExchangeRate { Currency = item.OriginalCurrency }); } } return DataResult>.Success(documents); } /// /// 获取发票结算明细 /// /// /// protected override async Task> GetSettlementDetails(long id) { var list = await TenantDb.Queryable() .InnerJoin((i, d1) => i.Id == d1.ApplicationId) .InnerJoin((i, d1, d2) => d1.ApplicationId == d2.RefId) .Where((i, d1, d2) => d2.ApplicationId == id && d2.Category == DetailCategory.InvoiceSettlement && d1.Category == DetailCategory.InvoiceIssuance) .GroupBy((i, d1, d2) => i.Id) .Select((i, d1, d2) => new SettlementDetailDto { Id = i.Id, InvoiceApplyAmount = i.ApplyAmount, InvoiceAmount = i.InvoiceAmount, SettlementAmount = SqlFunc.Subqueryable().Where(d3 => d3.ApplicationId == i.Id).Sum(d3 => d3.ApplyAmount), ApplicationNOList = SqlFunc.Subqueryable().Where(a => a.Id == d1.RefId).ToList(a => a.ApplicationNO) }, true).ToListAsync(); return list; } protected override async Task PreSaveAsync(ApplicationSettlement settlement) { var appIds = settlement.Details.Select(x => x.RefId).Distinct(); var appList = await TenantDb.Queryable().Where(x => appIds.Contains(x.Id)) .Select(x => new { x.Id, x.CustomerId, x.CustomerName, }).ToListAsync(); if (appList.Count == 0) return DataResult.FailedWithDesc(nameof(MultiLanguageConst.EmptyData)); if (appList.GroupBy(x => x.CustomerId).Select(x => x.Key).Count() > 1) return DataResult.FailedWithDesc(nameof(MultiLanguageConst.DetailCustomerOnlyOne)); //获取剩余待结算金额 var ids2 = settlement.Details.Select(x => x.DetailId); var appDetails = await TenantDb.Queryable().Where(x => ids2.Contains(x.Id) && x.Category == DetailCategory.InvoiceIssuance) .Select(x => new { x.Id, OriginalRestAmount = x.OriginalAmount - x.OriginalProcessedAmount }).ToListAsync(); StringBuilder sb = new(); foreach (var detail in settlement.Details) { var item = appDetails.Find(x => x.Id == detail.DetailId); if (item == null) { sb.Append(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.EmptyData))); break; } if (detail.OriginalAmount > 0 && detail.OriginalAmount > item.OriginalRestAmount) { sb.AppendFormat(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DetailExceedingLimit)), detail.FeeName); sb.Append(";"); continue; } else if (detail.OriginalAmount < 0 && detail.OriginalAmount < item.OriginalRestAmount) { sb.AppendFormat(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DetailExceedingLimit)), detail.FeeName); sb.Append(";"); continue; } detail.Category = DetailCategory.InvoiceSettlement; } return sb.Length > 0 ? DataResult.Failed(sb.ToString()) : DataResult.Success; } protected override async Task OnSaveAsync(ApplicationSettlement settlement) { //更新发票费用明细的已处理金额 var list = settlement.Details.Select(x => new ApplicationDetail { Id = x.DetailId.Value, Category = DetailCategory.InvoiceIssuance, ProcessedAmount = x.ApplyAmount, OriginalProcessedAmount = x.OriginalAmount }).ToList(); await TenantDb.Updateable(list) .PublicSetColumns(x => x.ProcessedAmount, "+") .PublicSetColumns(x => x.OriginalProcessedAmount, "+") .UpdateColumns(x => new { x.ProcessedAmount, x.OriginalProcessedAmount }) .ExecuteCommandAsync(); } } }