三种结算模式代码分离

dev
嵇文龙 2 weeks ago
parent ac34f341eb
commit 61d32578ab

@ -473,7 +473,11 @@ namespace DS.WMS.Core.Invoice.Method
//invoice.InvoiceRemark = $"购买方地址电话:" + Environment.NewLine + invoice.CustomerAddressTel + Environment.NewLine
// + "购买方开户行/账号:" + invoice.CustomerBankName + " " + invoice.CustomerAccount;
if (!string.IsNullOrEmpty(invRemark))
{
invoice.Note += Environment.NewLine + invRemark;
invoice.InvoiceRemark += Environment.NewLine + invRemark;
}
}
//筛选出新增的费用明细

@ -49,14 +49,14 @@ 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.Currency == FeeCurrency.RMB_CODE)
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.Currency == FeeCurrency.USD_CODE)
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.Currency != FeeCurrency.RMB_CODE && y.Currency != FeeCurrency.USD_CODE)
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)),
CustomerAccount = x.CustomerBank.AccountName + "/" + x.CustomerBank.Currency,
@ -189,16 +189,16 @@ namespace DS.WMS.Core.Settlement.Method
//申请金额
var details = appDetails.Where(x => x.ApplicationId == item.Id);
item.RMBApplyAmount = details.Where(x => x.OriginalCurrency == FeeCurrency.RMB_CODE).Sum(x => x.ApplyAmount);
item.USDApplyAmount = details.Where(x => x.OriginalCurrency == FeeCurrency.USD_CODE).Sum(x => x.ApplyAmount);
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.RMBStlAmount = details.Where(x => appIds.Contains(x.Id) && x.OriginalCurrency == FeeCurrency.RMB_CODE).Sum(x => x.ProcessedAmount);
item.USDStlAmount = details.Where(x => appIds.Contains(x.Id) && x.OriginalCurrency == FeeCurrency.USD_CODE).Sum(x => x.ProcessedAmount);
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 = (item.RMBApplyAmount - item.RMBStlAmount).GetValueOrDefault();
item.RMBStlRestAmount = (item.USDApplyAmount - item.USDStlAmount).GetValueOrDefault();
//剩余结金额
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);
}
return list;
@ -443,6 +443,217 @@ namespace DS.WMS.Core.Settlement.Method
}
}
/// <summary>
/// 保存申请结算
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public override async Task<DataResult<ApplicationSettlement>> SaveAsync(SettlementRequest<ApplicationSettlement> request)
{
var settlement = request.Settlement;
if (settlement.SettlementDate == default)
settlement.SettlementDate = DateTime.Now;
if (settlement.BillType == 0)
return DataResult<ApplicationSettlement>.FailedWithDesc(nameof(MultiLanguageConst.UnknownSettlementType));
settlement.Mode = settlement.BillType == SettlementBillType.Payment ? SettlementMode.Payment : SettlementMode.Charge;
ApplicationSettlement? dbValue = default;
if (request.Settlement.Id > 0)
{
dbValue = await TenantDb.Queryable<ApplicationSettlement>().Select(x => new ApplicationSettlement
{
Id = x.Id,
IsLocked = x.IsLocked,
Mode = x.Mode
}).FirstAsync(x => x.Id == request.Settlement.Id);
if (dbValue != null && dbValue.IsLocked)
return DataResult<ApplicationSettlement>.FailedWithDesc(nameof(MultiLanguageConst.SettlementIsLocked));
}
var result = EnsureSettlement(request.Settlement, dbValue);
if (!result.Succeeded)
return DataResult<ApplicationSettlement>.Failed(result.Message, result.MultiCode);
List<ApplicationDetail>? details1 = null;
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);
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)) //按币别结算
{
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);
}
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)) //指定结算币别
{
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<ApplicationSettlement>.Failed("结算单据与费用明细不一致");
var exchange = doc.ExchangeRates?.Find(x => x.Currency == detail.OriginalCurrency);
if (exchange == null)
return DataResult<ApplicationSettlement>.Failed($"未传入结算币别 {settlement.Currency} 与费用原币别 {detail.OriginalCurrency} 之间的汇率信息");
detail.ExchangeRate = exchange.ExchangeRate;
}
}
//执行结算费用分配
foreach (var doc in request.Documents)
{
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);
if (doc.SettlementRMB.HasValue)
{
var rmbDetails = details2.Where(x => x.OriginalCurrency == 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();
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();
result = AssignAmount(otherDetails, doc.SettlementOther.Value, settlement.Currency);
if (!result.Succeeded)
return DataResult<ApplicationSettlement>.Failed(result.Message, result.MultiCode);
}
}
}
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));
}
}
protected override async Task<DataResult> PreSaveAsync(ApplicationSettlement settlement)
{

@ -174,7 +174,8 @@ namespace DS.WMS.Core.Settlement.Method
var cIds = inquiry.Items.Select(x => x.CustomerId).Distinct();
var list = await TenantDb.Queryable<FeeRecord>()
.Where(f => bizIds.Contains(f.BusinessId) && types.Contains(f.BusinessType) && cIds.Contains(f.CustomerId))
.Where(f => bizIds.Contains(f.BusinessId) && types.Contains(f.BusinessType) && cIds.Contains(f.CustomerId) &&
(f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount) != 0)
.Where(inquiry.GetConditionalModels(Db))
.Select(f => new FeeItem
{
@ -369,11 +370,201 @@ namespace DS.WMS.Core.Settlement.Method
return DataResult<FreeSettlementDto>.Success(model);
}
protected override async Task<DataResult> PreSaveAsync(ApplicationSettlement settlement)
/// <summary>
/// 保存自由结算
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public override async Task<DataResult<ApplicationSettlement>> SaveAsync(SettlementRequest<ApplicationSettlement> request)
{
//settlement.Mode = SettlementMode.FreeSettlement;
//settlement.BillType = SettlementBillType.Payment;
var settlement = request.Settlement;
if (settlement.SettlementDate == default)
settlement.SettlementDate = DateTime.Now;
settlement.Mode = SettlementMode.FreeSettlement;
if (settlement.BillType == 0)
return DataResult<ApplicationSettlement>.FailedWithDesc(nameof(MultiLanguageConst.UnknownSettlementType));
ApplicationSettlement? dbValue = default;
if (request.Settlement.Id > 0)
{
dbValue = await TenantDb.Queryable<ApplicationSettlement>().Select(x => new ApplicationSettlement
{
Id = x.Id,
IsLocked = x.IsLocked,
Mode = x.Mode
}).FirstAsync(x => x.Id == request.Settlement.Id);
if (dbValue != null && dbValue.IsLocked)
return DataResult<ApplicationSettlement>.FailedWithDesc(nameof(MultiLanguageConst.SettlementIsLocked));
}
var result = EnsureSettlement(request.Settlement, dbValue);
if (!result.Succeeded)
return DataResult<ApplicationSettlement>.Failed(result.Message, result.MultiCode);
List<ApplicationDetail>? details1 = null;
if (request.Details?.Count > 0)
{
if (settlement.Id == 0)
{
var first = request.Details[0];
settlement.CustomerId = first.CustomerId;
settlement.CustomerName = first.CustomerName;
}
details1 = request.Details.Select(x => new ApplicationDetail
{
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 (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);
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
{
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<ApplicationSettlement>.Failed("结算单据与费用明细不一致");
var exchange = doc.ExchangeRates?.Find(x => x.Currency == detail.OriginalCurrency);
if (exchange == null)
return DataResult<ApplicationSettlement>.Failed($"未传入结算币别 {settlement.Currency} 与费用原币别 {detail.OriginalCurrency} 之间的汇率信息");
detail.ExchangeRate = exchange.ExchangeRate;
}
}
}
//金额禁止为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));
}
}
protected override async Task<DataResult> PreSaveAsync(ApplicationSettlement settlement)
{
//获取剩余待结算金额
var ids = settlement.Details.Select(x => x.RecordId);
var fees = await TenantDb.Queryable<FeeRecord>().Where(x => ids.Contains(x.Id))

@ -215,6 +215,178 @@ namespace DS.WMS.Core.Settlement.Method
return list;
}
public override async Task<DataResult<ApplicationSettlement>> SaveAsync(SettlementRequest<ApplicationSettlement> request)
{
var settlement = request.Settlement;
if (settlement.SettlementDate == default)
settlement.SettlementDate = DateTime.Now;
if (settlement.BillType == 0)
return DataResult<ApplicationSettlement>.FailedWithDesc(nameof(MultiLanguageConst.UnknownSettlementType));
settlement.Mode = settlement.BillType == SettlementBillType.Payment ? SettlementMode.PaymentInvoiceSettlement : SettlementMode.InvoiceSettlement;
ApplicationSettlement? dbValue = default;
if (request.Settlement.Id > 0)
{
dbValue = await TenantDb.Queryable<ApplicationSettlement>().Select(x => new ApplicationSettlement
{
Id = x.Id,
IsLocked = x.IsLocked,
Mode = x.Mode
}).FirstAsync(x => x.Id == request.Settlement.Id);
if (dbValue != null && dbValue.IsLocked)
return DataResult<ApplicationSettlement>.FailedWithDesc(nameof(MultiLanguageConst.SettlementIsLocked));
}
var result = EnsureSettlement(request.Settlement, dbValue);
if (!result.Succeeded)
return DataResult<ApplicationSettlement>.Failed(result.Message, result.MultiCode);
List<ApplicationDetail>? details1 = null;
//按发票结算
if (request.Documents?.Count > 0)
{
if (settlement.Id == 0)
{
var first = request.Documents[0];
settlement.CustomerId = first.CustomerId;
settlement.CustomerName = first.CustomerName;
}
//发票结算
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)) //按币别结算
{
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);
}
var ids = request.Documents.Select(x => x.Id);
details1 = await TenantDb.Queryable<ApplicationDetail>().Where(x => ids.Contains(x.ApplicationId) && x.Category == DetailCategory.InvoiceIssuance)
.WhereIF(expr != null, expr.ToExpression())
.Select(x => new ApplicationDetail
{
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<ApplicationSettlement>.Failed("结算单据与费用明细不一致");
var exchange = doc.ExchangeRates?.Find(x => x.Currency == settlement.Currency);
if (exchange == null)
return DataResult<ApplicationSettlement>.Failed($"使用发票做结算时,非 {FeeCurrency.RMB_CODE} 的费用必须指定汇率");
detail.ExchangeRate = exchange.ExchangeRate;
}
}
}
//金额禁止为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));
}
}
protected override async Task<DataResult> PreSaveAsync(ApplicationSettlement settlement)
{

@ -22,7 +22,7 @@ namespace DS.WMS.Core.Settlement.Method
public class SettlementService<TEntity> : FeeServiceBase, ISettlementService<TEntity>
where TEntity : SettlementBase, new()
{
readonly Lazy<ICommonService> CommonService;
protected readonly Lazy<ICommonService> SeqService;
/// <summary>
/// 初始化
@ -30,7 +30,7 @@ namespace DS.WMS.Core.Settlement.Method
/// <param name="serviceProvider">DI容器</param>
public SettlementService(IServiceProvider serviceProvider) : base(serviceProvider)
{
CommonService = new Lazy<ICommonService>(serviceProvider.GetRequiredService<ICommonService>());
SeqService = new Lazy<ICommonService>(serviceProvider.GetRequiredService<ICommonService>());
}
@ -41,7 +41,7 @@ namespace DS.WMS.Core.Settlement.Method
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public async Task<DataResult<TEntity>> SaveAsync(SettlementRequest<TEntity> request)
public virtual async Task<DataResult<TEntity>> SaveAsync(SettlementRequest<TEntity> request)
{
var settlement = request.Settlement;
if (settlement.SettlementDate == default)
@ -82,6 +82,7 @@ namespace DS.WMS.Core.Settlement.Method
details1 = request.Details.Select(x => new ApplicationDetail
{
Assigned = true,
RefId = x.ApplicationId,
DetailId = x.Id,
RecordId = x.RecordId,
@ -98,7 +99,7 @@ namespace DS.WMS.Core.Settlement.Method
}
if (request.Documents != null)
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);
//按付费/发票申请/自由业务结算
@ -175,6 +176,7 @@ namespace DS.WMS.Core.Settlement.Method
.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,
@ -221,6 +223,7 @@ namespace DS.WMS.Core.Settlement.Method
.Where(request.GetConditionalModels(Db))
.Select(f => new ApplicationDetail
{
Assigned = true,
ApplicationId = settlement.Id,
BusinessId = f.BusinessId,
BusinessType = f.BusinessType,
@ -310,7 +313,7 @@ namespace DS.WMS.Core.Settlement.Method
if (settlement.Id == 0)
{
//创建时需要生成申请单编号
var sequence = CommonService.Value.GetSequenceNext<TEntity>();
var sequence = SeqService.Value.GetSequenceNext<TEntity>();
if (!sequence.Succeeded)
{
return DataResult<TEntity>.Failed(sequence.Message, MultiLanguageConst.SequenceSetNotExist);
@ -370,7 +373,7 @@ namespace DS.WMS.Core.Settlement.Method
}
}
static DataResult AssignAmount(List<ApplicationDetail> details, decimal stlAmount, string currency)
internal static DataResult AssignAmount(List<ApplicationDetail> details, decimal stlAmount, string currency)
{
if (details.Count == 0)
return DataResult.Success;

Loading…
Cancel
Save