cjy 2 weeks ago
commit 34a5f85571

@ -38,7 +38,6 @@ namespace DS.WMS.Core.Application.Method
public async Task<DataResult<PaymentApplicationModel>> GetListAsync(PageRequest request)
{
var query = CreateListQuery();
if (!request.QueryCondition.IsNullOrEmpty())
{
var whereList = request.GetConditionalModels(Db);
@ -68,7 +67,7 @@ namespace DS.WMS.Core.Application.Method
{
x.Currency,
x.ApplyAmount,
SettlementAmount = x.ProcessedAmount,
x.ProcessedAmount,
}).ToListAsync();
PaymentApplicationModel model = new()
@ -79,9 +78,9 @@ namespace DS.WMS.Core.Application.Method
TotalUSD = details.Where(x => x.Currency == FeeCurrency.USD_CODE).Sum(x => x.ApplyAmount),
TotalOther = details.Where(x => x.Currency != FeeCurrency.RMB_CODE && x.Currency != FeeCurrency.USD_CODE).Sum(x => x.ApplyAmount),
SettlementCNY = details.Where(x => x.Currency == FeeCurrency.RMB_CODE).Sum(x => x.SettlementAmount),
SettlementUSD = details.Where(x => x.Currency == FeeCurrency.USD_CODE).Sum(x => x.SettlementAmount),
SettlementOther = details.Where(x => x.Currency != FeeCurrency.RMB_CODE && x.Currency != FeeCurrency.USD_CODE).Sum(x => x.SettlementAmount)
SettlementCNY = details.Where(x => x.Currency == FeeCurrency.RMB_CODE).Sum(x => x.ProcessedAmount),
SettlementUSD = details.Where(x => x.Currency == FeeCurrency.USD_CODE).Sum(x => x.ProcessedAmount),
SettlementOther = details.Where(x => x.Currency != FeeCurrency.RMB_CODE && x.Currency != FeeCurrency.USD_CODE).Sum(x => x.ProcessedAmount)
};
var result2 = DataResult<PaymentApplicationModel>.Success(model);
result2.Count = result.Count;
@ -127,18 +126,150 @@ namespace DS.WMS.Core.Application.Method
CustomerBankId = a.CustomerBankId,
CustomerBankName = a.CustomerBank.BankName, //结算对象银行
CustomerAccount = a.CustomerBank.Account, //结算对象账号
//汇总项
RestAmountRMB = SqlFunc.Subqueryable<FeeRecord>().Where(f => f.Id == d.RecordId && f.FeeStatus == FeeStatus.AuditPassed
&& f.Currency == FeeCurrency.RMB_CODE).Select(f => SqlFunc.AggregateSum(f.Amount - f.SettlementAmount)),
RestAmountUSD = SqlFunc.Subqueryable<FeeRecord>().Where(f => f.Id == d.RecordId && f.FeeStatus == FeeStatus.AuditPassed
&& f.Currency == FeeCurrency.USD_CODE).Select(f => SqlFunc.AggregateSum(f.Amount - f.SettlementAmount)),
RestAmountOther = SqlFunc.Subqueryable<FeeRecord>().Where(f => f.Id == d.RecordId && f.FeeStatus == FeeStatus.AuditPassed
&& f.Currency != FeeCurrency.RMB_CODE && f.Currency != FeeCurrency.USD_CODE).Select(f => SqlFunc.AggregateSum(f.Amount - f.SettlementAmount))
SettlementTime = a.SettlementTime,
//-----汇总项-----
//已结算
SettlementRMB = SqlFunc.Subqueryable<ApplicationDetail>().Where(d => d.ApplicationId == a.Id && d.Currency == FeeCurrency.RMB_CODE).Sum(d => d.ProcessedAmount),
SettlementUSD = SqlFunc.Subqueryable<ApplicationDetail>().Where(d => d.ApplicationId == a.Id && d.Currency == FeeCurrency.USD_CODE).Sum(d => d.ProcessedAmount),
SettlementOther = SqlFunc.Subqueryable<ApplicationDetail>().Where(d => d.ApplicationId == a.Id && d.Currency != FeeCurrency.RMB_CODE && d.Currency != FeeCurrency.USD_CODE).Sum(d => d.ProcessedAmount),
//RestAmountRMB = SqlFunc.Subqueryable<FeeRecord>().Where(f => f.Id == d.RecordId && f.FeeStatus == FeeStatus.AuditPassed
// && f.Currency == FeeCurrency.RMB_CODE).Select(f => SqlFunc.AggregateSum(f.Amount - f.SettlementAmount)),
//RestAmountUSD = SqlFunc.Subqueryable<FeeRecord>().Where(f => f.Id == d.RecordId && f.FeeStatus == FeeStatus.AuditPassed
// && f.Currency == FeeCurrency.USD_CODE).Select(f => SqlFunc.AggregateSum(f.Amount - f.SettlementAmount)),
//RestAmountOther = SqlFunc.Subqueryable<FeeRecord>().Where(f => f.Id == d.RecordId && f.FeeStatus == FeeStatus.AuditPassed
// && f.Currency != FeeCurrency.RMB_CODE && f.Currency != FeeCurrency.USD_CODE).Select(f => SqlFunc.AggregateSum(f.Amount - f.SettlementAmount))
});
return TenantDb.UnionAll(new List<ISugarQueryable<PaymentApplicationDto>> { query1 });
}
/// <summary>
/// 获取申请单详情
/// </summary>
/// <param name="id">申请单ID</param>
/// <returns></returns>
public async Task<DataResult<PaymentApplicationDto>> GetAsync(long id)
{
var dto = await TenantDb.Queryable<PaymentApplication>()
.LeftJoin<InfoClientBank>((a, b) => a.CustomerBankId == b.Id)
.LeftJoin<CodeStlMode>((a, b, c) => a.SettlementTypeId == c.Id)
.Where((a, b, c) => a.Id == id).Select((a, b, c) => new PaymentApplicationDto
{
CustomerBankId = a.CustomerBankId,
CustomerBankName = b.BankName,
CustomerAccount = b.Account,
SettlementTypeId = a.SettlementTypeId,
SettlementTypeName = c.StlName,
CreateByName = a.CreateUserName
}, true).FirstAsync();
var result = DataResult<PaymentApplicationDto>.Success(dto);
if (dto != null)
{
if (dto.SaleDeptId.HasValue)
dto.SaleDeptName = await Db.Queryable<SysOrg>().Where(x => x.Id == dto.SaleDeptId)
.Select(x => x.OrgName).FirstAsync();
dto.Details = await TenantDb.Queryable<ApplicationDetail>().Where(d => d.ApplicationId == id)
.InnerJoin<FeeRecord>((d, f) => d.RecordId == f.Id)
.InnerJoin<BusinessFeeStatus>((d, f, b) => f.BusinessId == b.BusinessId && f.BusinessType == b.BusinessType)
.Select((d, f, b) => new ApplicationDetailDto
{
Id = d.Id,
RecordId = f.Id,
AccTaxRate = f.AccTaxRate,
Amount = d.ApplyAmount,
FeeId = d.FeeId,
FeeName = d.FeeName,
FeeType = d.FeeType,
CustomerId = f.CustomerId,
CustomerName = d.CustomerName,
OriginalCurrency = d.OriginalCurrency,
OriginalRate = f.ExchangeRate,
ExchangeRate = d.ExchangeRate,
OriginalAmount = d.OriginalAmount,
//未申请金额=(金额-结算金额-申请金额+申请金额已结算)
RestAmount = f.Amount - f.SettlementAmount,
BusinessId = f.BusinessId,
BusinessType = f.BusinessType,
IsBusinessLocking = b.IsBusinessLocking,
IsFeeLocking = b.IsFeeLocking
}).ToListAsync();
var gList = dto.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<SeaExport>().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.Sale,
x.SaleDeptName,
}).ToListAsync();
foreach (var item in g)
{
var biz = list1.Find(x => x.Id == item.BusinessId);
if (biz != null)
{
item.MBLNO = biz.MBLNO;
item.ClientName = 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.SaleName = biz.Sale;
item.SaleDeptName = biz.SaleDeptName;
}
}
break;
case BusinessType.OceanShippingImport:
break;
}
}
dto.RestAmountRMB = dto.Details.FindAll(x => x.OriginalCurrency == FeeCurrency.RMB_CODE).Sum(x => x.RestAmount);
dto.RestAmountUSD = dto.Details.FindAll(x => x.OriginalCurrency == FeeCurrency.USD_CODE).Sum(x => x.RestAmount);
dto.AmountOther = dto.Details.FindAll(x => x.OriginalCurrency != FeeCurrency.RMB_CODE && x.OriginalCurrency != FeeCurrency.USD_CODE).Sum(x => x.RestAmount);
result.AdditionalData ??= [];
var recordIds = dto.Details.Select(x => x.RecordId);
var fees = await TenantDb.Queryable<FeeRecord>().Where(f => recordIds.Contains(f.Id) && f.FeeType == FeeType.Receivable)
.Select(f => new
{
f.Currency,
f.Amount,
UnSettlement = f.Amount - f.SettlementAmount
}).ToListAsync();
result.AdditionalData["ReceivablesRMB"] = fees.Where(x => x.Currency == FeeCurrency.RMB_CODE).Sum(x => x.Amount);
result.AdditionalData["ReceivablesUSD"] = fees.Where(x => x.Currency == FeeCurrency.USD_CODE).Sum(x => x.Amount);
result.AdditionalData["UnSettledRMB"] = fees.Where(x => x.Currency == FeeCurrency.RMB_CODE).Sum(x => x.UnSettlement);
result.AdditionalData["UnSettledUSD"] = fees.Where(x => x.Currency == FeeCurrency.USD_CODE).Sum(x => x.UnSettlement);
}
return result;
}
/// <summary>
/// 获取待付费的业务列表
@ -305,132 +436,6 @@ namespace DS.WMS.Core.Application.Method
return DataResult<PaymentApplicaitonBiz>.Success(new PaymentApplicaitonBiz(list));
}
/// <summary>
/// 获取申请单详情
/// </summary>
/// <param name="id">申请单ID</param>
/// <returns></returns>
public async Task<DataResult<PaymentApplicationDto>> GetAsync(long id)
{
var dto = await TenantDb.Queryable<PaymentApplication>()
.LeftJoin<InfoClientBank>((a, b) => a.CustomerBankId == b.Id)
.LeftJoin<CodeStlMode>((a, b, c) => a.SettlementTypeId == c.Id)
.Where((a, b, c) => a.Id == id).Select((a, b, c) => new PaymentApplicationDto
{
CustomerBankId = a.CustomerBankId,
CustomerBankName = b.BankName,
CustomerAccount = b.Account,
SettlementTypeId = a.SettlementTypeId,
SettlementTypeName = c.StlName,
CreateByName = a.CreateUserName
}, true).FirstAsync();
var result = DataResult<PaymentApplicationDto>.Success(dto);
if (dto != null)
{
if (dto.SaleDeptId.HasValue)
dto.SaleDeptName = await Db.Queryable<SysOrg>().Where(x => x.Id == dto.SaleDeptId)
.Select(x => x.OrgName).FirstAsync();
dto.Details = await TenantDb.Queryable<ApplicationDetail>().Where(d => d.ApplicationId == id)
.InnerJoin<FeeRecord>((d, f) => d.RecordId == f.Id)
.InnerJoin<BusinessFeeStatus>((d, f, b) => f.BusinessId == b.BusinessId && f.BusinessType == b.BusinessType)
.Select((d, f, b) => new ApplicationDetailDto
{
Id = d.Id,
RecordId = f.Id,
AccTaxRate = f.AccTaxRate,
Amount = d.ApplyAmount,
FeeId = d.FeeId,
FeeName = d.FeeName,
FeeType = d.FeeType,
CustomerId = f.CustomerId,
CustomerName = d.CustomerName,
OriginalCurrency = d.OriginalCurrency,
OriginalRate = f.ExchangeRate,
ExchangeRate = d.ExchangeRate,
OriginalAmount = d.OriginalAmount,
//未申请金额=(金额-结算金额-申请金额+申请金额已结算)
RestAmount = f.Amount - f.SettlementAmount,
BusinessId = f.BusinessId,
BusinessType = f.BusinessType,
IsBusinessLocking = b.IsBusinessLocking,
IsFeeLocking = b.IsFeeLocking
}).ToListAsync();
var gList = dto.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<SeaExport>().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.Sale,
x.SaleDeptName,
}).ToListAsync();
foreach (var item in g)
{
var biz = list1.Find(x => x.Id == item.BusinessId);
if (biz != null)
{
item.MBLNO = biz.MBLNO;
item.ClientName = 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.SaleName = biz.Sale;
item.SaleDeptName = biz.SaleDeptName;
}
}
break;
case BusinessType.OceanShippingImport:
break;
}
}
dto.RestAmountRMB = dto.Details.FindAll(x => x.OriginalCurrency == FeeCurrency.RMB_CODE).Sum(x => x.RestAmount);
dto.RestAmountUSD = dto.Details.FindAll(x => x.OriginalCurrency == FeeCurrency.USD_CODE).Sum(x => x.RestAmount);
dto.AmountOther = dto.Details.FindAll(x => x.OriginalCurrency != FeeCurrency.RMB_CODE && x.OriginalCurrency != FeeCurrency.USD_CODE).Sum(x => x.RestAmount);
result.AdditionalData ??= [];
var recordIds = dto.Details.Select(x => x.RecordId);
var fees = await TenantDb.Queryable<FeeRecord>().Where(f => recordIds.Contains(f.Id) && f.FeeType == FeeType.Receivable)
.Select(f => new
{
f.Currency,
f.Amount,
UnSettlement = f.Amount - f.SettlementAmount
}).ToListAsync();
result.AdditionalData["ReceivablesRMB"] = fees.Where(x => x.Currency == FeeCurrency.RMB_CODE).Sum(x => x.Amount);
result.AdditionalData["ReceivablesUSD"] = fees.Where(x => x.Currency == FeeCurrency.USD_CODE).Sum(x => x.Amount);
result.AdditionalData["UnSettledRMB"] = fees.Where(x => x.Currency == FeeCurrency.RMB_CODE).Sum(x => x.UnSettlement);
result.AdditionalData["UnSettledUSD"] = fees.Where(x => x.Currency == FeeCurrency.USD_CODE).Sum(x => x.UnSettlement);
}
return result;
}
//获取付费申请关联明细
protected override async Task<List<ApplicationDetail>> GetDetailsAsync(ApplicationRequest<PaymentApplication> request)
{

@ -26,7 +26,7 @@ public class ClientFlowTemplateService : ServiceBase, IClientFlowTemplateService
//序列化查询条件
var whereList = request.GetConditionalModels(Db);
var data = TenantDb.Queryable<FlowTemplate>()
.LeftJoin<SysPermission>((a, b) => a.PermissionId == b.Id)
.LeftJoin<SysPermission>((a, b) => a.PermissionId == b.Id, "shippingweb8_dev.sys_permission")
.Select<FlowTemplateRes>()
.Where(whereList).ToQueryPage(request.PageCondition);
return data;
@ -34,20 +34,6 @@ public class ClientFlowTemplateService : ServiceBase, IClientFlowTemplateService
public DataResult EditClientFlowTemplate(FlowTemplateReq req)
{
//if (req.Id == 0)
//{
// return DataResult.Failed("非法请求!",MultiLanguageConst.IllegalRequest);
//}
//else
//{
// var info = db.Queryable<FlowTemplateTenant>().Where(x => x.Id == req.Id).First();
// info = req.Adapt(info);
// db.Updateable(info).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommand();
// return DataResult.Successed("更新成功!",MultiLanguageConst.DataUpdateSuccess);
//}
if (req.Id == 0)
{
var isExist = TenantDb.Queryable<FlowTemplate>().Where(x => x.Name == req.Name).First();

@ -1,4 +1,5 @@
using DS.Module.Core;
using DS.Module.Core.Data;
using DS.Module.Core.Enums;
using DS.Module.Core.Extensions;
using DS.WMS.Core.Application.Dtos;
@ -34,6 +35,7 @@ namespace DS.WMS.Core.Invoice.Method
public InvoiceService(IServiceProvider provider) : base(provider)
{
CommonService = new Lazy<ICommonService>(provider.GetRequiredService<ICommonService>());
TenantDb.QueryFilter.Clear<IOrgId>();
}
/// <summary>

@ -15,4 +15,20 @@
/// </summary>
public long? PortId { get; set; }
}
/// <summary>
/// 申请单明细查询
/// </summary>
public class DetailQuery
{
/// <summary>
/// 申请单ID
/// </summary>
public long Id { get; set; }
/// <summary>
/// 币别
/// </summary>
public string? Currency { get; set; }
}
}

@ -39,18 +39,12 @@ namespace DS.WMS.Core.Settlement.Interface
Task<DataResult<List<PaymentApplicationDtoV2>>> GetApplicationListAsync(PageRequest<ApplicationListQuery> request);
/// <summary>
/// 获取付费申请的费用明细
/// 获取申请单费用明细
/// </summary>
/// <param name="id">申请单ID</param>
/// <param name="currency">币别</param>
/// <returns></returns>
Task<DataResult<List<PaymentApplicationDetailDto>>> GetApplicationDetailsAsync(long id, string currency);
/// <summary>
/// 获取费用明细
/// </summary>
/// <param name="ids">申请单明细ID</param>
/// <returns></returns>
Task<DataResult<List<PaymentApplicationDetailDto>>> GetSettlementFeeDetailsAsync(params long[] ids);
Task<DataResult<List<PaymentApplicationDetailDto>>> GetApplicationDetailsAsync(long id, string? currency);
/// <summary>
/// 获取发票费用明细的原始币别

@ -5,7 +5,6 @@ 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.Code.Entity;
using DS.WMS.Core.Fee.Entity;
using DS.WMS.Core.Invoice.Dtos;
using DS.WMS.Core.Op.Entity;
@ -49,21 +48,19 @@ namespace DS.WMS.Core.Settlement.Method
ApplicationNO = x.ApplicationNO,
SettlementNO = x.SettlementNO,
SettlementTypeName = x.SettlementType.StlName, //结算方式
RMBAmount = SqlFunc.Subqueryable<ApplicationDetail>().Where(y => y.ApplicationId == x.Id && y.OriginalCurrency == FeeCurrency.RMB_CODE)
.Select(y => SqlFunc.AggregateSum(y.OriginalAmount)),
USDAmount = SqlFunc.Subqueryable<ApplicationDetail>().Where(y => y.ApplicationId == x.Id && y.OriginalCurrency == FeeCurrency.USD_CODE)
.Select(y => SqlFunc.AggregateSum(y.OriginalAmount)),
OtherAmount = SqlFunc.Subqueryable<ApplicationDetail>().Where(y => y.ApplicationId == x.Id && y.OriginalCurrency != FeeCurrency.RMB_CODE && y.OriginalCurrency != FeeCurrency.USD_CODE)
.Select(y => SqlFunc.AggregateSum(y.OriginalAmount)),
//-----结算金额统计-----
RMBAmount = SqlFunc.Subqueryable<ApplicationDetail>().Where(y => y.ApplicationId == x.Id && y.Currency == FeeCurrency.RMB_CODE)
.Select(y => SqlFunc.AggregateSum(y.ApplyAmount)),
USDAmount = SqlFunc.Subqueryable<ApplicationDetail>().Where(y => y.ApplicationId == x.Id && y.Currency == FeeCurrency.USD_CODE)
.Select(y => SqlFunc.AggregateSum(y.ApplyAmount)),
OtherAmount = SqlFunc.Subqueryable<ApplicationDetail>().Where(y => y.ApplicationId == x.Id && y.Currency != FeeCurrency.RMB_CODE && y.Currency != FeeCurrency.USD_CODE)
.Select(y => SqlFunc.AggregateSum(y.ApplyAmount)),
CustomerAccount = x.CustomerBank.AccountName + "/" + x.CustomerBank.Currency,
CustomerBankName = x.CustomerBank.BankName,
//未开票
UnInvoiceList = SqlFunc.Subqueryable<ApplicationDetail>().InnerJoin<FeeRecord>((d, f) => d.ApplicationId == x.Id && d.RecordId == f.Id)
.GroupBy((d, f) => f.Currency).ToList((d, f) => new CurrencyAmount { Currency = f.Currency, Amount = SqlFunc.AggregateSum(f.Amount - f.InvoiceAmount) }),
.GroupBy((d, f) => new { f.BusinessId, f.BusinessType, f.Currency }).ToList((d, f) => new CurrencyAmount { Currency = f.Currency, Amount = SqlFunc.AggregateSum(f.Amount - f.InvoiceAmount) }),
}, true);
var whereList = request.GetConditionalModels(Db);
@ -143,7 +140,7 @@ namespace DS.WMS.Core.Settlement.Method
/// <summary>
/// 获取费用申请结算明细
/// </summary>
/// <param name="id"></param>
/// <param name="id">结算单ID</param>
/// <returns></returns>
protected override async Task<List<SettlementDetailGroup>> GetSettlementDetails(long id)
{
@ -159,16 +156,11 @@ namespace DS.WMS.Core.Settlement.Method
Id = pa.Id,
Status = (int)pa.Status,
BillNO = pa.ApplicationNO,
PaymentDate = pa.PaymentDate,
//RMBApplyAmount = SqlFunc.Subqueryable<ApplicationDetail>().Where(x => x.ApplicationId == d2.RefId && x.Currency == FeeCurrency.RMB_CODE).Sum(x => x.ApplyAmount),
//USDApplyAmount = SqlFunc.Subqueryable<ApplicationDetail>().Where(x => x.ApplicationId == d2.RefId && x.Currency == FeeCurrency.USD_CODE).Sum(x => x.ApplyAmount),
//RMBStlAmount = SqlFunc.Subqueryable<ApplicationDetail>().Where(x => x.ApplicationId == i.Id && x.Currency == FeeCurrency.RMB_CODE).Sum(x => x.ApplyAmount),
//USDStlAmount = SqlFunc.Subqueryable<ApplicationDetail>().Where(x => x.ApplicationId == i.Id && x.Currency == FeeCurrency.USD_CODE).Sum(x => x.ApplyAmount),
//RMBStlRestAmount = SqlFunc.Subqueryable<ApplicationDetail>().Where(x => x.ApplicationId == i.Id && x.Currency == FeeCurrency.RMB_CODE).Sum(x => x.ApplyAmount - x.ProcessedAmount),
//USDStlRestAmount = SqlFunc.Subqueryable<ApplicationDetail>().Where(x => x.ApplicationId == i.Id && x.Currency == FeeCurrency.USD_CODE).Sum(x => x.ApplyAmount - x.ProcessedAmount),
PaymentDate = pa.PaymentDate
}, true).ToListAsync();
var ids = list.Select(x => x.Id);
//获取原申请明细
var appDetails = await TenantDb.Queryable<ApplicationDetail>().Where(x => ids.Contains(x.ApplicationId))
.Select(x => new
{
@ -182,6 +174,21 @@ namespace DS.WMS.Core.Settlement.Method
x.OriginalProcessedAmount
}).ToListAsync();
//获取结算单明细
var stlDetails = await TenantDb.Queryable<ApplicationDetail>().Where(x => x.ApplicationId == id)
.Select(x => new
{
x.ApplicationId,
x.DetailId,
x.RefId,
x.Currency,
x.OriginalCurrency,
x.ApplyAmount,
x.OriginalAmount,
x.ProcessedAmount,
x.OriginalProcessedAmount
}).ToListAsync();
foreach (var item in list)
{
PaymentApplicationStatus status = (PaymentApplicationStatus)item.Status;
@ -191,14 +198,12 @@ namespace DS.WMS.Core.Settlement.Method
var details = appDetails.Where(x => x.ApplicationId == item.Id);
item.RMBApplyAmount = details.Where(x => x.Currency == FeeCurrency.RMB_CODE).Sum(x => x.ApplyAmount);
item.USDApplyAmount = details.Where(x => x.Currency == FeeCurrency.USD_CODE).Sum(x => x.ApplyAmount);
//未结金额
item.RMBStlRestAmount = details.Where(x => appIds.Contains(x.Id) && x.OriginalCurrency == FeeCurrency.RMB_CODE).Sum(x => x.OriginalAmount - x.OriginalProcessedAmount);
item.USDStlRestAmount = details.Where(x => appIds.Contains(x.Id) && x.OriginalCurrency == FeeCurrency.USD_CODE).Sum(x => x.OriginalAmount - x.OriginalProcessedAmount);
//本次结算金额
item.RMBStlAmount = details.Where(x => appIds.Contains(x.Id) && x.Currency == FeeCurrency.RMB_CODE).Sum(x => x.ProcessedAmount);
item.USDStlAmount = details.Where(x => appIds.Contains(x.Id) && x.Currency == FeeCurrency.USD_CODE).Sum(x => x.ProcessedAmount);
//剩余未结金额
item.RMBStlRestAmount = details.Where(x => appIds.Contains(x.Id) && x.Currency == FeeCurrency.RMB_CODE).Sum(x => x.ApplyAmount - x.ProcessedAmount);
item.RMBStlRestAmount = details.Where(x => appIds.Contains(x.Id) && x.Currency == FeeCurrency.RMB_CODE).Sum(x => x.ApplyAmount - x.ProcessedAmount);
item.RMBStlAmount = stlDetails.Where(x => x.RefId == item.Id && x.OriginalCurrency == FeeCurrency.RMB_CODE).Sum(x => x.OriginalAmount);
item.USDStlAmount = stlDetails.Where(x => x.RefId == item.Id && x.OriginalCurrency == FeeCurrency.USD_CODE).Sum(x => x.OriginalAmount);
}
return list;
@ -215,49 +220,6 @@ namespace DS.WMS.Core.Settlement.Method
return DataResult<List<SettlementDetailGroup>>.Success(details);
}
/// <summary>
/// 根据申请获取费用明细
/// </summary>
/// <param name="ids">申请单ID</param>
/// <returns></returns>
public async Task<DataResult<List<PaymentApplicationDetailDto>>> GetSettlementFeeDetailsAsync(params long[] ids)
{
var details = await CreateApplicationDetailQuery((d, f, s) => ids.Contains(d.ApplicationId))
.LeftJoin<PaymentApplication>((d, pa) => d.ApplicationId == pa.Id)
.Select((d, pa) => new PaymentApplicationDetailDto
{
Id = d.Id,
ApplicationId = d.ApplicationId,
BusinessId = d.BusinessId,
BusinessType = d.BusinessType,
RecordId = d.RecordId,
FeeName = d.FeeName,
FeeType = d.FeeType,
Amount = d.Amount, //总金额
ApplyAmount = d.ApplyAmount, //已结算金额
SettlementAmount = d.ApplyAmount,
RestAmount = d.ApplyAmount - d.ProcessedAmount, //剩余结算金额
CustomerId = d.CustomerId,
CustomerName = d.CustomerName,
OriginalCurrency = d.OriginalCurrency, //原始币别
OriginalRate = d.ExchangeRate, //原始汇率
ExchangeRate = d.ExchangeRate, //折算汇率
OriginalAmount = d.OriginalAmount, //原始金额
CustomerNo = d.CustomerNo,
MBLNO = d.MBLNO,
HBLNO = d.HBLNO,
ETD = d.ETD,
SourceName = d.SourceName,
SaleName = d.SaleName,
AccountDate = d.AccountDate,
Vessel = d.Vessel,
Voyage = d.Voyage,
InvoiceNO = pa.InvoiceNO
}).ToListAsync();
return DataResult<List<PaymentApplicationDetailDto>>.Success(details);
}
/// <summary>
/// 获取待结算的申请分页列表
/// </summary>
@ -328,39 +290,50 @@ namespace DS.WMS.Core.Settlement.Method
/// 获取申请单费用明细
/// </summary>
/// <param name="id">申请单ID</param>
/// <param name="currency">结算币别</param>
/// <returns></returns>
public async Task<DataResult<List<PaymentApplicationDetailDto>>> GetApplicationDetailsAsync(long id, string currency)
public async Task<DataResult<List<PaymentApplicationDetailDto>>> GetApplicationDetailsAsync(long id, string? currency = null)
{
var details = await TenantDb.Queryable<ApplicationDetail>().Where(d => d.ApplicationId == id && (d.ApplyAmount - d.ProcessedAmount) != 0)
.InnerJoin<FeeRecord>((d, f) => d.RecordId == f.Id)
.WhereIF(!string.IsNullOrEmpty(currency), x => x.Currency == currency)
.Select((d, f) => new PaymentApplicationDetailDto
{
Id = d.Id,
ApplicationId = d.ApplicationId,
BusinessId = f.BusinessId,
BusinessType = f.BusinessType,
RecordId = d.RecordId,
FeeName = d.FeeName,
FeeType = d.FeeType, //收付
Amount = d.ApplyAmount, //申请金额
ApplyAmount = f.SettlementAmount, //已结算金额
RestAmount = d.ApplyAmount - d.ProcessedAmount, //剩余结算金额
CustomerId = f.CustomerId,
CustomerName = d.CustomerName,
OriginalCurrency = d.OriginalCurrency, //原始币别
OriginalRate = f.ExchangeRate, //原始汇率
ExchangeRate = d.ExchangeRate, //折算汇率
OriginalAmount = d.OriginalAmount //原始金额
}).ToListAsync();
await FulfillDetailsAsync(details);
var details = await CreateApplicationDetailQuery((d, f, s) => d.ApplicationId == id)
.LeftJoin<PaymentApplication>((d, pa) => d.ApplicationId == pa.Id)
.WhereIF(!string.IsNullOrEmpty(currency), d => d.Currency == currency)
.Select((d, pa) => new PaymentApplicationDetailDto
{
Id = d.Id,
ApplicationId = d.ApplicationId,
BusinessId = d.BusinessId,
BusinessType = d.BusinessType,
RecordId = d.RecordId,
FeeName = d.FeeName,
FeeType = d.FeeType,
Amount = d.Amount, //总金额
Currency = d.Currency,
ApplyAmount = d.ApplyAmount, //申请金额
SettlementAmount = d.ProcessedAmount,
RestAmount = d.ApplyAmount - d.ProcessedAmount, //剩余结算金额
CustomerId = d.CustomerId,
CustomerName = d.CustomerName,
OriginalCurrency = d.OriginalCurrency, //原始币别
OriginalRate = d.ExchangeRate, //原始汇率
ExchangeRate = d.ExchangeRate, //折算汇率
OriginalAmount = d.OriginalAmount, //原始金额
CustomerNo = d.CustomerNo,
MBLNO = d.MBLNO,
HBLNO = d.HBLNO,
ETD = d.ETD,
SourceName = d.SourceName,
SaleName = d.SaleName,
AccountDate = d.AccountDate,
Vessel = d.Vessel,
Voyage = d.Voyage,
InvoiceNO = pa.InvoiceNO
}).ToListAsync();
return DataResult<List<PaymentApplicationDetailDto>>.Success(details);
}
/// <summary>
/// 获取发票费用明细的原始币别
/// 获取申请单费用明细的币别
/// </summary>
/// <param name="documents"></param>
/// <returns></returns>
@ -372,77 +345,24 @@ namespace DS.WMS.Core.Settlement.Method
.Select(d => new
{
d.ApplicationId,
d.OriginalCurrency
d.Currency
}).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 });
if (!document.ExchangeRates.Exists(x => x.Currency == item.Currency))
document.ExchangeRates.Add(new CurrencyExchangeRate { Currency = item.Currency });
}
}
return DataResult<List<SettlementDocument>>.Success(documents);
}
internal async Task FulfillDetailsAsync(List<PaymentApplicationDetailDto> details)
{
if (details.Count == 0)
return;
var gList = details.GroupBy(x => x.BusinessType);
foreach (var g in gList)
{
var ids = g.Select(x => x.BusinessId);
switch (g.Key)
{
case BusinessType.OceanShippingExport:
var list1 = await TenantDb.Queryable<SeaExport>().Where(s => ids.Contains(s.Id))
.LeftJoin<CodeSource>((s, cs) => s.SourceId == cs.Id)
.Select((s, cs) => new
{
s.Id,
s.AccountDate,//会计期间
s.Vessel, //船名
s.Voyno, //航次
s.CustomerName,
s.MBLNO, //主提单号
s.CustomerNo, //委托编号
s.ETD, //开船日期
s.Sale, //揽货人
cs.SourceName, //业务来源
s.Note
}).ToListAsync();
foreach (var item in g)
{
var biz = list1.Find(x => x.Id == item.BusinessId);
if (biz != null)
{
item.MBLNO = biz.MBLNO;
item.CustomerNo = biz.CustomerNo;
item.ClientName = biz.CustomerName;
item.ETD = biz.ETD;
item.SourceName = biz.SourceName;
item.SaleName = biz.Sale;
item.AccountDate = biz.AccountDate;
item.Vessel = biz.Vessel;
item.Voyage = biz.Voyno;
item.Note = biz.Note;
}
}
break;
case BusinessType.OceanShippingImport:
break;
}
}
}
/// <summary>
/// 保存申请结算
/// </summary>
@ -527,14 +447,14 @@ namespace DS.WMS.Core.Settlement.Method
if (!string.IsNullOrEmpty(settlement.Currency)) //指定结算币别
{
var details2 = details1.FindAll(x => x.OriginalCurrency != settlement.Currency);
var details2 = details1.FindAll(x => x.Currency != settlement.Currency);
foreach (var detail in details2)
{
var doc = request.Documents.Find(x => x.Id == detail.RefId);
if (doc == null)
return DataResult<ApplicationSettlement>.Failed("结算单据与费用明细不一致");
var exchange = doc.ExchangeRates?.Find(x => x.Currency == detail.OriginalCurrency);
var exchange = doc.ExchangeRates?.Find(x => x.Currency == detail.Currency);
if (exchange == null)
return DataResult<ApplicationSettlement>.Failed($"未传入结算币别 {settlement.Currency} 与费用原币别 {detail.OriginalCurrency} 之间的汇率信息");
@ -551,21 +471,21 @@ namespace DS.WMS.Core.Settlement.Method
if (doc.SettlementRMB.HasValue)
{
var rmbDetails = details2.Where(x => x.OriginalCurrency == FeeCurrency.RMB_CODE).ToList();
var rmbDetails = details2.Where(x => x.Currency == FeeCurrency.RMB_CODE).ToList();
result = AssignAmount(rmbDetails, doc.SettlementRMB.Value, settlement.Currency);
if (!result.Succeeded)
return DataResult<ApplicationSettlement>.Failed(result.Message, result.MultiCode);
}
if (doc.SettlementUSD.HasValue)
{
var usdDetails = details2.Where(x => x.OriginalCurrency == FeeCurrency.USD_CODE).ToList();
var usdDetails = details2.Where(x => x.Currency == FeeCurrency.USD_CODE).ToList();
result = AssignAmount(usdDetails, doc.SettlementUSD.Value, settlement.Currency);
if (!result.Succeeded)
return DataResult<ApplicationSettlement>.Failed(result.Message, result.MultiCode);
}
if (doc.SettlementOther.HasValue)
{
var otherDetails = details2.Where(x => x.OriginalCurrency != FeeCurrency.RMB_CODE && x.OriginalCurrency != FeeCurrency.USD_CODE).ToList();
var otherDetails = details2.Where(x => x.Currency != FeeCurrency.RMB_CODE && x.Currency != FeeCurrency.USD_CODE).ToList();
result = AssignAmount(otherDetails, doc.SettlementOther.Value, settlement.Currency);
if (!result.Succeeded)
return DataResult<ApplicationSettlement>.Failed(result.Message, result.MultiCode);
@ -576,83 +496,7 @@ namespace DS.WMS.Core.Settlement.Method
if (details1?.Count > 0)
settlement.Details.AddRange(details1.FindAll(x => x.Assigned));
//金额禁止为0
if (settlement.Details.Exists(x => x.ApplyAmount == 0 || x.OriginalAmount == 0))
return DataResult<ApplicationSettlement>.FailedWithDesc(nameof(MultiLanguageConst.AmountCannotBeZero));
if (settlement.Details.Exists(x => x.OriginalCurrency.IsNullOrEmpty()))
return DataResult<ApplicationSettlement>.FailedWithDesc(nameof(MultiLanguageConst.OriginalCurrencyCanNotNull));
result = await PreSaveAsync(settlement);
if (!result.Succeeded)
return DataResult<ApplicationSettlement>.Failed(result.Message, result.MultiCode);
var details = settlement.Details.FindAll(x => x.Id == 0);
await TenantDb.Ado.BeginTranAsync();
try
{
//关联导航属性插入
if (settlement.Id == 0)
{
//创建时需要生成申请单编号
var sequence = SeqService.Value.GetSequenceNext<ApplicationSettlement>();
if (!sequence.Succeeded)
{
return DataResult<ApplicationSettlement>.Failed(sequence.Message, MultiLanguageConst.SequenceSetNotExist);
}
settlement.ApplicationNO = "ST" + SnowFlakeSingle.Instance.NextId(); //申请编号
settlement.SettlementNO = sequence.Data; //结算单号
await TenantDb.InsertNav(settlement).Include(x => x.Details).ExecuteCommandAsync();
}
else
{
if (details.Count > 0)
await TenantDb.Insertable(details).ExecuteCommandAsync();
await TenantDb.Updateable(settlement).IgnoreColumns(x => new
{
x.ApplicationNO,
x.SettlementNO,
x.IsLocked,
x.CreateBy,
x.CreateTime,
x.Deleted,
x.DeleteBy,
x.DeleteTime
}).ExecuteCommandAsync();
}
await OnSaveAsync(settlement);
if (details.Count > 0)
{
//更新费用记录的已结算金额
var fees = details.Select(x => new FeeRecord
{
Id = x.RecordId,
SettlementAmount = x.OriginalAmount
}).ToList();
await TenantDb.Updateable(fees)
.PublicSetColumns(x => x.SettlementAmount, "+")
.UpdateColumns(x => new { x.SettlementAmount })
.ExecuteCommandAsync();
}
//计算结算总金额
settlement.Amount = await TenantDb.Queryable<ApplicationDetail>().Where(x => x.ApplicationId == settlement.Id).SumAsync(x => x.ApplyAmount);
await TenantDb.Updateable(settlement).UpdateColumns(x => x.Amount).ExecuteCommandAsync();
await TenantDb.Ado.CommitTranAsync();
await PostSaveAsync(settlement);
return DataResult<ApplicationSettlement>.Success(settlement);
}
catch (Exception ex)
{
await TenantDb.Ado.RollbackTranAsync();
await ex.LogAsync(Db);
return DataResult<ApplicationSettlement>.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
}
return await base.SaveAsync(request);
}
protected override async Task<DataResult> PreSaveAsync(ApplicationSettlement settlement)
@ -723,7 +567,8 @@ namespace DS.WMS.Core.Settlement.Method
var list = settlement.Details.Select(x => new ApplicationDetail
{
Id = x.DetailId.Value,
ProcessedAmount = x.OriginalCurrency == settlement.Currency ? x.ApplyAmount : x.OriginalAmount,
ProcessedAmount = x.Currency == x.OriginalCurrency ?
x.ApplyAmount : x.ApplyAmount / (x.ExchangeRate ?? 1),
OriginalProcessedAmount = x.OriginalAmount
}).ToList();
await TenantDb.Updateable(list)
@ -747,14 +592,16 @@ namespace DS.WMS.Core.Settlement.Method
{
x.ApplicationId,
Count = SqlFunc.AggregateCount(x.Id),
ProcessingCount = SqlFunc.Subqueryable<ApplicationDetail>().Where(y => appIds.Contains(y.ApplicationId) &&
y.Category == DetailCategory.PaidApplication && y.OriginalProcessedAmount != 0 && y.OriginalAmount != y.OriginalProcessedAmount).Count(),
ProcessedCount = SqlFunc.Subqueryable<ApplicationDetail>().Where(y => appIds.Contains(y.ApplicationId) &&
y.Category == DetailCategory.PaidApplication && y.OriginalAmount - y.OriginalProcessedAmount == 0).Count()
y.Category == DetailCategory.PaidApplication && y.OriginalAmount == y.OriginalProcessedAmount).Count()
}).ToListAsync();
List<PaymentApplication> applications = [];
foreach (var item in details)
{
if (item.Count == 0 || item.ProcessedCount == 0)
if (item.Count == 0 && item.ProcessedCount == 0)
continue;
var entity = new PaymentApplication { Id = item.ApplicationId };
@ -762,10 +609,14 @@ namespace DS.WMS.Core.Settlement.Method
{
entity.Status = PaymentApplicationStatus.SettlementCompleted;
}
else if (item.ProcessedCount != 0)
else if (item.ProcessingCount != 0 || item.ProcessedCount != 0)
{
entity.Status = PaymentApplicationStatus.PartialSettlement;
}
else if (item.ProcessingCount == 0 && item.ProcessedCount == 0)
{
entity.Status = PaymentApplicationStatus.AuditPassed;
}
applications.Add(entity);
}

@ -487,83 +487,7 @@ namespace DS.WMS.Core.Settlement.Method
if (details1?.Count > 0)
settlement.Details.AddRange(details1);
//金额禁止为0
if (settlement.Details.Exists(x => x.ApplyAmount == 0 || x.OriginalAmount == 0))
return DataResult<ApplicationSettlement>.FailedWithDesc(nameof(MultiLanguageConst.AmountCannotBeZero));
if (settlement.Details.Exists(x => x.OriginalCurrency.IsNullOrEmpty()))
return DataResult<ApplicationSettlement>.FailedWithDesc(nameof(MultiLanguageConst.OriginalCurrencyCanNotNull));
result = await PreSaveAsync(settlement);
if (!result.Succeeded)
return DataResult<ApplicationSettlement>.Failed(result.Message, result.MultiCode);
var details = settlement.Details.FindAll(x => x.Id == 0);
await TenantDb.Ado.BeginTranAsync();
try
{
//关联导航属性插入
if (settlement.Id == 0)
{
//创建时需要生成申请单编号
var sequence = SeqService.Value.GetSequenceNext<ApplicationSettlement>();
if (!sequence.Succeeded)
{
return DataResult<ApplicationSettlement>.Failed(sequence.Message, MultiLanguageConst.SequenceSetNotExist);
}
settlement.ApplicationNO = "ST" + SnowFlakeSingle.Instance.NextId(); //申请编号
settlement.SettlementNO = sequence.Data; //结算单号
await TenantDb.InsertNav(settlement).Include(x => x.Details).ExecuteCommandAsync();
}
else
{
if (details.Count > 0)
await TenantDb.Insertable(details).ExecuteCommandAsync();
await TenantDb.Updateable(settlement).IgnoreColumns(x => new
{
x.ApplicationNO,
x.SettlementNO,
x.IsLocked,
x.CreateBy,
x.CreateTime,
x.Deleted,
x.DeleteBy,
x.DeleteTime
}).ExecuteCommandAsync();
}
await OnSaveAsync(settlement);
if (details.Count > 0)
{
//更新费用记录的已结算金额
var fees = details.Select(x => new FeeRecord
{
Id = x.RecordId,
SettlementAmount = x.OriginalAmount
}).ToList();
await TenantDb.Updateable(fees)
.PublicSetColumns(x => x.SettlementAmount, "+")
.UpdateColumns(x => new { x.SettlementAmount })
.ExecuteCommandAsync();
}
//计算结算总金额
settlement.Amount = await TenantDb.Queryable<ApplicationDetail>().Where(x => x.ApplicationId == settlement.Id).SumAsync(x => x.ApplyAmount);
await TenantDb.Updateable(settlement).UpdateColumns(x => x.Amount).ExecuteCommandAsync();
await TenantDb.Ado.CommitTranAsync();
await PostSaveAsync(settlement);
return DataResult<ApplicationSettlement>.Success(settlement);
}
catch (Exception ex)
{
await TenantDb.Ado.RollbackTranAsync();
await ex.LogAsync(Db);
return DataResult<ApplicationSettlement>.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
}
return await base.SaveAsync(request);
}
protected override async Task<DataResult> PreSaveAsync(ApplicationSettlement settlement)

@ -168,11 +168,10 @@ namespace DS.WMS.Core.Settlement.Method
var ids = documents.Select(x => x.Id);
var list = await TenantDb.Queryable<ApplicationDetail>()
.Where(d => ids.Contains(d.ApplicationId) && d.Category == DetailCategory.InvoiceIssuance)
//.GroupBy(d => d.ApplicationId)
.Select(d => new
{
d.ApplicationId,
d.OriginalCurrency
d.Currency
}).ToListAsync();
foreach (var document in documents)
@ -182,8 +181,8 @@ namespace DS.WMS.Core.Settlement.Method
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 });
if (!document.ExchangeRates.Exists(x => x.Currency == item.Currency))
document.ExchangeRates.Add(new CurrencyExchangeRate { Currency = item.Currency });
}
}
@ -290,11 +289,9 @@ namespace DS.WMS.Core.Settlement.Method
if (settlement.Currency != FeeCurrency.RMB_CODE) //发票结算非人民币需做转换
{
var details2 = details1.FindAll(x => x.OriginalCurrency != settlement.Currency);
var details2 = details1.FindAll(x => x.Currency != settlement.Currency);
foreach (var detail in details2)
{
detail.Currency = settlement.Currency;
var doc = request.Documents.Find(x => x.Id == detail.ApplicationId);
if (doc == null)
return DataResult<ApplicationSettlement>.Failed("结算单据与费用明细不一致");
@ -313,83 +310,7 @@ namespace DS.WMS.Core.Settlement.Method
if (details1?.Count > 0)
settlement.Details.AddRange(details1);
//金额禁止为0
if (settlement.Details.Exists(x => x.ApplyAmount == 0 || x.OriginalAmount == 0))
return DataResult<ApplicationSettlement>.FailedWithDesc(nameof(MultiLanguageConst.AmountCannotBeZero));
if (settlement.Details.Exists(x => x.OriginalCurrency.IsNullOrEmpty()))
return DataResult<ApplicationSettlement>.FailedWithDesc(nameof(MultiLanguageConst.OriginalCurrencyCanNotNull));
result = await PreSaveAsync(settlement);
if (!result.Succeeded)
return DataResult<ApplicationSettlement>.Failed(result.Message, result.MultiCode);
var details = settlement.Details.FindAll(x => x.Id == 0);
await TenantDb.Ado.BeginTranAsync();
try
{
//关联导航属性插入
if (settlement.Id == 0)
{
//创建时需要生成申请单编号
var sequence = SeqService.Value.GetSequenceNext<ApplicationSettlement>();
if (!sequence.Succeeded)
{
return DataResult<ApplicationSettlement>.Failed(sequence.Message, MultiLanguageConst.SequenceSetNotExist);
}
settlement.ApplicationNO = "ST" + SnowFlakeSingle.Instance.NextId(); //申请编号
settlement.SettlementNO = sequence.Data; //结算单号
await TenantDb.InsertNav(settlement).Include(x => x.Details).ExecuteCommandAsync();
}
else
{
if (details.Count > 0)
await TenantDb.Insertable(details).ExecuteCommandAsync();
await TenantDb.Updateable(settlement).IgnoreColumns(x => new
{
x.ApplicationNO,
x.SettlementNO,
x.IsLocked,
x.CreateBy,
x.CreateTime,
x.Deleted,
x.DeleteBy,
x.DeleteTime
}).ExecuteCommandAsync();
}
await OnSaveAsync(settlement);
if (details.Count > 0)
{
//更新费用记录的已结算金额
var fees = details.Select(x => new FeeRecord
{
Id = x.RecordId,
SettlementAmount = x.OriginalAmount
}).ToList();
await TenantDb.Updateable(fees)
.PublicSetColumns(x => x.SettlementAmount, "+")
.UpdateColumns(x => new { x.SettlementAmount })
.ExecuteCommandAsync();
}
//计算结算总金额
settlement.Amount = await TenantDb.Queryable<ApplicationDetail>().Where(x => x.ApplicationId == settlement.Id).SumAsync(x => x.ApplyAmount);
await TenantDb.Updateable(settlement).UpdateColumns(x => x.Amount).ExecuteCommandAsync();
await TenantDb.Ado.CommitTranAsync();
await PostSaveAsync(settlement);
return DataResult<ApplicationSettlement>.Success(settlement);
}
catch (Exception ex)
{
await TenantDb.Ado.RollbackTranAsync();
await ex.LogAsync(Db);
return DataResult<ApplicationSettlement>.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
}
return await base.SaveAsync(request);
}
protected override async Task<DataResult> PreSaveAsync(ApplicationSettlement settlement)

@ -1,6 +1,5 @@
using System.Linq.Expressions;
using DS.Module.Core;
using DS.Module.Core.Enums;
using DS.Module.Core.Extensions;
using DS.WMS.Core.Application.Entity;
using DS.WMS.Core.Fee.Entity;
@ -36,263 +35,78 @@ namespace DS.WMS.Core.Settlement.Method
#region 保存
/// <summary>
/// 提交结算单
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public virtual async Task<DataResult<TEntity>> SaveAsync(SettlementRequest<TEntity> request)
internal static DataResult AssignAmount(List<ApplicationDetail> details, decimal stlAmount, string currency)
{
var settlement = request.Settlement;
if (settlement.SettlementDate == default)
settlement.SettlementDate = DateTime.Now;
if (settlement.Mode == 0)
return DataResult<TEntity>.FailedWithDesc(nameof(MultiLanguageConst.UnknownSettlementMode));
if (settlement.BillType == 0)
return DataResult<TEntity>.FailedWithDesc(nameof(MultiLanguageConst.UnknownSettlementType));
if (details.Count == 0)
return DataResult.Success;
TEntity? dbValue = default;
if (request.Settlement.Id > 0)
{
dbValue = await TenantDb.Queryable<TEntity>().Select(x => new TEntity
{
Id = x.Id,
IsLocked = x.IsLocked,
Mode = x.Mode
}).FirstAsync(x => x.Id == request.Settlement.Id);
if (stlAmount == 0)
return DataResult.Failed("结算金额不能为零");
if (dbValue != null && dbValue.IsLocked)
return DataResult<TEntity>.FailedWithDesc(nameof(MultiLanguageConst.SettlementIsLocked));
}
var result = EnsureSettlement(request.Settlement, dbValue);
if (!result.Succeeded)
return DataResult<TEntity>.Failed(result.Message, result.MultiCode);
var totalAmount = details.Sum(x => x.ApplyAmount);
if (Math.Abs(stlAmount) > totalAmount)
return DataResult.Failed("申请结算金额不能大于剩余结算金额");
List<ApplicationDetail>? details1 = null;
//自由结算
if (settlement.Mode == SettlementMode.FreeSettlement && request.Details?.Count > 0)
decimal rest = stlAmount;
decimal currentAmount = default;
foreach (var detail in details)
{
if (settlement.Id == 0)
{
var first = request.Details[0];
settlement.CustomerId = first.CustomerId;
settlement.CustomerName = first.CustomerName;
}
details1 = request.Details.Select(x => new ApplicationDetail
{
Assigned = true,
RefId = x.ApplicationId,
DetailId = x.Id,
RecordId = x.RecordId,
CustomerName = x.CustomerName ?? settlement.CustomerName,
FeeId = x.FeeId,
FeeName = x.FeeName,
FeeType = x.FeeType,
ApplyAmount = x.RestAmount.GetValueOrDefault(),
Currency = x.Currency,
ExchangeRate = x.ExchangeRate,
OriginalAmount = x.OriginalAmount,
OriginalCurrency = x.OriginalCurrency ?? (settlement.Currency.IsNullOrEmpty() ? x.Currency : settlement.Currency),
}).ToList();
if (rest <= 0)
break;
}
if (request.Documents != null && (settlement.Mode == SettlementMode.Payment || settlement.Mode == SettlementMode.Charge))
request.Documents = request.Documents.FindAll(x => x.SettlementUSD.HasValue || x.SettlementRMB.HasValue || x.SettlementOther.HasValue);
//按付费/发票申请/自由业务结算
if (request.Documents?.Count > 0)
{
if (settlement.Id == 0)
{
var first = request.Documents[0];
settlement.CustomerId = first.CustomerId;
settlement.CustomerName = first.CustomerName;
}
var ids = request.Documents.Select(x => x.Id);
//收/付费申请结算
if (settlement.Mode == SettlementMode.Payment || settlement.Mode == SettlementMode.Charge)
if (totalAmount != stlAmount) //非全额结算
{
Expressionable<ApplicationDetail>? expr = null;
if (request.Documents.Any(x => x.SettlementRMB.GetValueOrDefault() == 0) || request.Documents.Any(x => x.SettlementUSD.GetValueOrDefault() == 0) ||
request.Documents.Any(x => x.SettlementOther.GetValueOrDefault() == 0)) //按币别结算
if (rest >= detail.ApplyAmount)
{
expr = Expressionable.Create<ApplicationDetail>();
if (request.Documents.Any(x => x.SettlementRMB.GetValueOrDefault() != 0))
expr = expr.Or(x => x.Currency == FeeCurrency.RMB_CODE);
if (request.Documents.Any(x => x.SettlementUSD.GetValueOrDefault() != 0))
expr = expr.Or(x => x.Currency == FeeCurrency.USD_CODE);
rest -= detail.ApplyAmount;
}
var detailCategory = settlement.Mode == SettlementMode.Payment ? DetailCategory.PaidApplication : DetailCategory.ChargeApplication;
details1 = await TenantDb.Queryable<ApplicationDetail>()
.Where(x => ids.Contains(x.ApplicationId) && x.Category == detailCategory)
.WhereIF(expr != null, expr.ToExpression())
.Select(x => new ApplicationDetail
{
ApplicationId = settlement.Id,
RefId = x.ApplicationId,
DetailId = x.Id,
RecordId = x.RecordId,
Category = settlement.Mode == SettlementMode.Payment ? DetailCategory.PaidApplicationSettlement : DetailCategory.ChargeApplicationSettlement,
CustomerName = x.CustomerName ?? settlement.CustomerName,
FeeId = x.FeeId,
FeeName = x.FeeName,
FeeType = x.FeeType,
ApplyAmount = x.ApplyAmount - x.ProcessedAmount,
Currency = x.Currency,
OriginalAmount = x.OriginalAmount - x.OriginalProcessedAmount,
OriginalCurrency = x.OriginalCurrency,
ExchangeRate = x.ExchangeRate
}).ToListAsync();
if (!string.IsNullOrEmpty(settlement.Currency)) //指定结算币别
else
{
var details2 = details1.FindAll(x => x.OriginalCurrency != settlement.Currency);
foreach (var detail in details2)
{
var doc = request.Documents.Find(x => x.Id == detail.RefId);
if (doc == null)
return DataResult<TEntity>.Failed("结算单据与费用明细不一致");
var exchange = doc.ExchangeRates?.Find(x => x.Currency == detail.OriginalCurrency);
if (exchange == null)
return DataResult<TEntity>.Failed($"未传入结算币别 {settlement.Currency} 与费用原币别 {detail.OriginalCurrency} 之间的汇率信息");
detail.ExchangeRate = exchange.ExchangeRate;
}
detail.ApplyAmount = rest;
rest = 0;
}
}
//发票结算
else if (settlement.Mode == SettlementMode.InvoiceSettlement || settlement.Mode == SettlementMode.PaymentInvoiceSettlement)
{
details1 = await TenantDb.Queryable<ApplicationDetail>().Where(x => ids.Contains(x.ApplicationId) && x.Category == DetailCategory.InvoiceIssuance)
.WhereIF(request.Documents.Any(x => x.SettlementRMB.HasValue), x => x.Currency == FeeCurrency.RMB_CODE)
.WhereIF(request.Documents.Any(x => x.SettlementUSD.HasValue), x => x.Currency == FeeCurrency.USD_CODE)
.WhereIF(request.Documents.Any(x => x.SettlementOther.HasValue), x => x.Currency != FeeCurrency.RMB_CODE && x.Currency != FeeCurrency.USD_CODE)
.Select(x => new ApplicationDetail
{
Assigned = true,
ApplicationId = settlement.Id,
RefId = x.ApplicationId,
DetailId = x.Id,
RecordId = x.RecordId,
Category = DetailCategory.InvoiceSettlement,
CustomerName = x.CustomerName ?? settlement.CustomerName,
FeeId = x.FeeId,
FeeName = x.FeeName,
FeeType = x.FeeType,
ApplyAmount = x.ApplyAmount - x.ProcessedAmount,
Currency = x.Currency,
OriginalAmount = x.OriginalAmount - x.OriginalProcessedAmount,
OriginalCurrency = x.OriginalCurrency,
ExchangeRate = x.ExchangeRate
}).ToListAsync();
if (settlement.Currency != FeeCurrency.RMB_CODE) //发票结算非人民币需做转换
{
var details2 = details1.FindAll(x => x.OriginalCurrency != settlement.Currency);
foreach (var detail in details2)
{
detail.Currency = settlement.Currency;
var doc = request.Documents.Find(x => x.Id == detail.ApplicationId);
if (doc == null)
return DataResult<TEntity>.Failed("结算单据与费用明细不一致");
currentAmount = detail.ApplyAmount;
var exchange = doc.ExchangeRates?.Find(x => x.Currency == settlement.Currency);
if (exchange == null)
return DataResult<TEntity>.Failed($"使用发票做结算时,非 {FeeCurrency.RMB_CODE} 的费用必须指定汇率");
detail.ExchangeRate = exchange.ExchangeRate;
}
}
}
//按业务自由结算
else if (settlement.Mode == SettlementMode.FreeSettlement)
if (detail.Currency == currency)
{
var types = request.Documents.Select(x => x.BusinessType.GetValueOrDefault());
var custIds = request.Documents.Select(x => x.CustomerId);
details1 = await TenantDb.Queryable<FeeRecord>().Where(f => ids.Contains(f.BusinessId) && types.Contains(f.BusinessType) && custIds.Contains(f.CustomerId) &&
(f.FeeStatus == FeeStatus.AuditPassed || f.FeeStatus == FeeStatus.PartialSettlement) && (f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount) != 0)
.Where(request.GetConditionalModels(Db))
.Select(f => new ApplicationDetail
{
Assigned = true,
ApplicationId = settlement.Id,
BusinessId = f.BusinessId,
BusinessType = f.BusinessType,
RecordId = f.Id,
Category = f.FeeType == FeeType.Payable ? DetailCategory.PaidFreeSettlement : DetailCategory.ChargeFreeSettlement,
CustomerName = f.CustomerName ?? settlement.CustomerName,
FeeId = f.FeeId,
FeeName = f.FeeName,
FeeType = f.FeeType,
ApplyAmount = f.Amount - f.SettlementAmount,
Currency = f.Currency,
OriginalAmount = f.Amount - f.SettlementAmount,
OriginalCurrency = f.Currency,
ExchangeRate = f.ExchangeRate
}).ToListAsync();
if (!string.IsNullOrEmpty(settlement.Currency)) //指定结算币别
{
var details2 = details1.FindAll(x => x.OriginalCurrency != settlement.Currency);
foreach (var detail in details2)
{
detail.Currency = settlement.Currency;
var doc = request.Documents.Find(x => x.Id == detail.BusinessId && x.BusinessType == detail.BusinessType && x.CustomerName == x.CustomerName);
if (doc == null)
return DataResult<TEntity>.Failed("结算单据与费用明细不一致");
var exchange = doc.ExchangeRates?.Find(x => x.Currency == detail.OriginalCurrency);
if (exchange == null)
return DataResult<TEntity>.Failed($"未传入结算币别 {settlement.Currency} 与费用原币别 {detail.OriginalCurrency} 之间的汇率信息");
detail.ExchangeRate = exchange.ExchangeRate;
}
}
detail.ExchangeRate = 1;
detail.OriginalAmount = detail.ApplyAmount;
}
//执行结算费用分配
foreach (var doc in request.Documents)
else //结算币别与费用币别不一致
{
var details2 = settlement.Mode != SettlementMode.FreeSettlement ?
details1.Where(x => x.RefId == doc.Id).OrderBy(x => x.ApplyAmount) :
details1.Where(x => x.BusinessId == doc.Id && x.BusinessType == doc.BusinessType && x.CustomerName == doc.CustomerName).OrderBy(x => x.ApplyAmount);
detail.ExchangeRate ??= 1;
detail.ApplyAmount *= detail.ExchangeRate.Value;
if (doc.SettlementRMB.HasValue)
if (detail.OriginalCurrency == detail.Currency)
{
var rmbDetails = details2.Where(x => x.OriginalCurrency == FeeCurrency.RMB_CODE).ToList();
result = AssignAmount(rmbDetails, doc.SettlementRMB.Value, settlement.Currency);
if (!result.Succeeded)
return DataResult<TEntity>.Failed(result.Message, result.MultiCode);
detail.OriginalAmount = currentAmount;
}
if (doc.SettlementUSD.HasValue)
{
var usdDetails = details2.Where(x => x.OriginalCurrency == FeeCurrency.USD_CODE).ToList();
result = AssignAmount(usdDetails, doc.SettlementUSD.Value, settlement.Currency);
if (!result.Succeeded)
return DataResult<TEntity>.Failed(result.Message, result.MultiCode);
}
if (doc.SettlementOther.HasValue)
else
{
var otherDetails = details2.Where(x => x.OriginalCurrency != FeeCurrency.RMB_CODE && x.OriginalCurrency != FeeCurrency.USD_CODE).ToList();
result = AssignAmount(otherDetails, doc.SettlementOther.Value, settlement.Currency);
if (!result.Succeeded)
return DataResult<TEntity>.Failed(result.Message, result.MultiCode);
detail.OriginalAmount = currentAmount * detail.ExchangeRate.Value;
}
detail.Currency = currency;
}
detail.Assigned = true;
}
if (details1?.Count > 0)
settlement.Details.AddRange(details1.FindAll(x => x.Assigned));
return DataResult.Success;
}
/// <summary>
/// 提交结算单
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public virtual async Task<DataResult<TEntity>> SaveAsync(SettlementRequest<TEntity> request)
{
var settlement = request.Settlement;
if (settlement.SettlementDate == default)
settlement.SettlementDate = DateTime.Now;
//金额禁止为0
if (settlement.Details.Exists(x => x.ApplyAmount == 0 || x.OriginalAmount == 0))
@ -301,7 +115,7 @@ namespace DS.WMS.Core.Settlement.Method
if (settlement.Details.Exists(x => x.OriginalCurrency.IsNullOrEmpty()))
return DataResult<TEntity>.FailedWithDesc(nameof(MultiLanguageConst.OriginalCurrencyCanNotNull));
result = await PreSaveAsync(settlement);
var result = await PreSaveAsync(settlement);
if (!result.Succeeded)
return DataResult<TEntity>.Failed(result.Message, result.MultiCode);
@ -373,67 +187,6 @@ namespace DS.WMS.Core.Settlement.Method
}
}
internal static DataResult AssignAmount(List<ApplicationDetail> details, decimal stlAmount, string currency)
{
if (details.Count == 0)
return DataResult.Success;
if (stlAmount == 0)
return DataResult.Failed("结算金额不能为零");
var totalAmount = details.Exists(x => x.Currency != currency) ?
details.Sum(x => x.OriginalAmount) : details.Sum(x => x.ApplyAmount);
if (Math.Abs(stlAmount) > totalAmount)
return DataResult.Failed("申请结算金额不能大于剩余结算金额");
if (totalAmount != stlAmount) //非全额结算
{
decimal rest = stlAmount;
foreach (var detail in details)
{
if (rest <= 0)
break;
if (rest >= detail.OriginalAmount)
{
rest = rest - detail.OriginalAmount;
}
else
{
detail.OriginalAmount = rest;
rest = 0;
}
if (detail.Currency == currency)
detail.ApplyAmount = detail.OriginalAmount;
else
{
detail.Currency = currency;
detail.ApplyAmount = detail.OriginalAmount * detail.ExchangeRate.GetValueOrDefault();
}
detail.Assigned = true;
}
}
else
{
foreach (var detail in details)
{
if (detail.Currency == currency)
detail.ApplyAmount = detail.OriginalAmount;
else
{
detail.Currency = currency;
detail.ApplyAmount = detail.OriginalAmount * detail.ExchangeRate.GetValueOrDefault();
}
detail.Assigned = true;
}
}
return DataResult.Success;
}
/// <summary>
/// 用于结算单的状态检查
/// </summary>
@ -657,9 +410,7 @@ namespace DS.WMS.Core.Settlement.Method
BusinessType = x.BusinessType,
FeeStatus = x.FeeStatus,
Amount = x.Amount,
SettlementAmount = x.SettlementAmount,
OrderAmount = x.OrderAmount,
OrderSettlementAmount = x.OrderSettlementAmount
SettlementAmount = x.SettlementAmount
}).ToList();
if (fees.Count == 0)
return [];
@ -672,14 +423,14 @@ namespace DS.WMS.Core.Settlement.Method
item.FeeStatus = FeeStatus.SettlementCompleted;
list.Add(item);
}
else if (item.Amount - item.SettlementAmount != 0)
else if (item.SettlementAmount == 0)
{
item.FeeStatus = FeeStatus.PartialSettlement;
item.FeeStatus = FeeStatus.AuditPassed;
list.Add(item);
}
else if (item.SettlementAmount == 0)
else if (item.Amount != item.SettlementAmount)
{
item.FeeStatus = FeeStatus.AuditPassed;
item.FeeStatus = FeeStatus.PartialSettlement;
list.Add(item);
}
}

@ -6,7 +6,7 @@ namespace DS.WMS.Core.Sys.Entity;
/// <summary>
/// 权限信息
/// </summary>
[SqlSugar.SugarTable("sys_permission")]
[SugarTable("sys_permission")]
public class SysPermission : BaseModel<long>
{
/// <summary>

@ -77,7 +77,7 @@ namespace DS.WMS.FeeApi.Controllers
/// <param name="currency">费用币别(可空)</param>
/// <returns></returns>
[HttpGet, Route("GetApplicationDetailsById")]
public async Task<DataResult<List<PaymentApplicationDetailDto>>> GetApplicationDetailsAsync([FromQuery] long id, [FromQuery] string currency = null)
public async Task<DataResult<List<PaymentApplicationDetailDto>>> GetApplicationDetailsAsync([FromQuery] long id, [FromQuery] string? currency = null)
{
return await _service.GetApplicationDetailsAsync(id, currency);
}
@ -85,10 +85,10 @@ namespace DS.WMS.FeeApi.Controllers
/// <summary>
/// 根据申请获取费用明细
/// </summary>
/// <param name="model">申请明细ID</param>
/// <param name="query"></param>
/// <returns></returns>
[HttpPost, Route("GetApplicationDetailsByDetail")]
public async Task<DataResult<List<PaymentApplicationDetailDto>>> GetSettlementFeeDetailsAsync([FromBody] IdModel model)
[HttpPost, Route("GetApplicationDetailsByDetail"), Obsolete]
public async Task<DataResult<List<PaymentApplicationDetailDto>>> GetApplicationDetailsAsync([FromBody] DetailQuery query)
{
if (!ModelState.IsValid)
{
@ -96,7 +96,7 @@ namespace DS.WMS.FeeApi.Controllers
ModelState.GetErrorMessage(), MultiLanguageConst.IllegalRequest);
}
return await _service.GetSettlementFeeDetailsAsync(model.Ids?.Length > 0 ? model.Ids : [long.Parse(model.Id)]);
return await _service.GetApplicationDetailsAsync(query.Id, query.Currency);
}
/// <summary>

Loading…
Cancel
Save