You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

675 lines
34 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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.Application.Interface;
using DS.WMS.Core.Code.Entity;
using DS.WMS.Core.Fee.Dtos;
using DS.WMS.Core.Fee.Entity;
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
{
/// <summary>
/// 付费申请实现
/// </summary>
public class PaymentApplicationService : ApplicationService<PaymentApplication>, IPaymentApplicationService
{
public override TaskBaseTypeEnum AuditType => TaskBaseTypeEnum.APPLICATION_PAYMENT_AUDIT;
/// <summary>
/// 初始化
/// </summary>
/// <param name="serviceProvider"></param>
public PaymentApplicationService(IServiceProvider serviceProvider) : base(serviceProvider)
{
}
/// <summary>
/// 获取分页列表
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public async Task<DataResult<PaymentApplicationModel>> GetListAsync(PageRequest request)
{
var query = CreateListQuery();
if (!request.QueryCondition.IsNullOrEmpty())
{
var whereList = request.GetConditionalModels(Db);
query = query.Where(whereList);
}
var result = await query.GroupBy(x => x.Id).ToQueryPageAsync(request.PageCondition);
if (result.Data?.Count > 0)
{
//关联用户名称
var userIds = result.Data.Select(x => x.CreateBy).Distinct();
var users = await Db.Queryable<SysUser>().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<SysOrg>().Where(x => orgIds.Contains(x.Id)).Select(x => new { x.Id, x.OrgName }).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;
}
}
var ids = result.Data.Select(x => x.Id);
var details = await TenantDb.Queryable<ApplicationDetail>().Where(x => ids.Contains(x.ApplicationId))
.Select(x => new
{
x.Currency,
x.ApplyAmount,
SettlementAmount = x.ProcessedAmount,
}).ToListAsync();
PaymentApplicationModel model = new()
{
List = result.Data,
TotalCNY = details.Where(x => x.Currency == FeeCurrency.RMB_CODE).Sum(x => x.ApplyAmount),
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)
};
var result2 = DataResult<PaymentApplicationModel>.Success(model);
result2.Count = result.Count;
return result2;
}
internal ISugarQueryable<PaymentApplicationDto> CreateListQuery()
{
var query1 = TenantDb.Queryable<PaymentApplication>()
.LeftJoin<ApplicationDetail>((a, d) => a.Id == d.ApplicationId)
.LeftJoin<FeeRecord>((a, d, f) => d.RecordId == f.Id)
.LeftJoin<SeaExport>((a, d, f, s) => f.BusinessId == s.Id)
.Select((a, d, f, s) => new PaymentApplicationDto
{
Id = a.Id,
ApplicationNO = a.ApplicationNO,
Status = a.Status,
CustomerId = a.CustomerId,
CustomerName = a.CustomerName, //结算单位
ClientName = s.CustomerName, //委托单位
AmountOther = a.AmountOther,
AmountRMB = a.AmountRMB,
AmountUSD = a.AmountUSD,
SaleDeptId = a.SaleDeptId,
SettlementTypeId = a.SettlementTypeId,
SettlementTypeName = a.SettlementType.StlName, //结算方式
CreateBy = a.CreateBy, //申请人
CreateTime = a.CreateTime, //申请日期
PaymentDate = a.PaymentDate, //申请支付日期
Currency = a.Currency,
Reason = a.Reason,
AuditerId = a.AuditerId,
AuditerName = a.AuditerName, //审核人
AuditTime = a.AuditTime, //审核时间
IsInvoiceReceived = a.IsInvoiceReceived,
IsPrinted = a.IsPrinted,
PrintTimes = a.PrintTimes,
InvoiceAmount = a.InvoiceAmount,
InvoiceDate = a.InvoiceDate,
InvoiceNO = a.InvoiceNO,
Note = a.Note,
BillNO = s.CustomerNo, //业务编号=委托编号
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 - f.OrderAmount + f.OrderSettlementAmount)),
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 - f.OrderAmount + f.OrderSettlementAmount)),
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 - f.OrderAmount + f.OrderSettlementAmount))
});
return TenantDb.UnionAll(new List<ISugarQueryable<PaymentApplicationDto>> { query1 });
}
/// <summary>
/// 获取待付费的业务列表
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public async Task<DataResult<List<BizPaymentApplication>>> GetBizListAsync(PageRequest request)
{
var conditions = request.GetConditionalModels(Db);
var query = CreateBizQuery(conditions);
var result = await query.ToQueryPageAsync(request.PageCondition);
if (result.Data.Count > 0)
{
//关联用户名称
var userIds = result.Data.Where(x => x.OperatorId.HasValue).Select(x => x.OperatorId.Value)
.Union(result.Data.Select(x => x.CreateBy))
.Distinct();
var users = await Db.Queryable<SysUser>().Where(x => userIds.Contains(x.Id)).Select(x => new { x.Id, x.UserName }).ToListAsync();
//关联机构名称
var orgIds = result.Data.Select(x => x.SaleDeptId).Distinct();
var orgs = await Db.Queryable<SysOrg>().Where(x => userIds.Contains(x.Id)).Select(x => new { x.Id, x.OrgName }).ToListAsync();
var ids1 = result.Data.Select(x => x.Id);
var ids2 = result.Data.Select(x => x.BusinessType).Distinct();
var fees = await CreateFeeQuery((s, f) => ids1.Contains(f.BusinessId) && ids2.Contains(f.BusinessType) && f.FeeStatus == FeeStatus.AuditPassed)
.Where(conditions).Select(x => new
{
x.BusinessId,
x.BusinessType,
x.CustomerId,
x.FeeType,
x.Amount,
x.InvoiceAmount,
x.OrderInvoiceAmount,
x.OrderInvSettlementAmount,
x.SettlementAmount,
x.OrderAmount,
x.OrderSettlementAmount,
x.Currency,
}).ToListAsync();
foreach (var item in result.Data)
{
//--------统计项--------
item.UnpaidRMB = fees.Where(f => f.BusinessId == item.Id && f.BusinessType == item.BusinessType &&
f.CustomerId == item.CustomerId && f.FeeType == FeeType.Payable && f.Currency == FeeCurrency.RMB_CODE)
.Sum(f => f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount);
item.UnpaidUSD = fees.Where(f => f.BusinessId == item.Id && f.BusinessType == item.BusinessType &&
f.CustomerId == item.CustomerId && f.FeeType == FeeType.Payable && f.Currency == FeeCurrency.USD_CODE)
.Sum(f => f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount);
item.UnpaidOther = fees.Where(f => f.BusinessId == item.Id && f.BusinessType == item.BusinessType &&
f.CustomerId == item.CustomerId && f.FeeType == FeeType.Payable && f.Currency != FeeCurrency.RMB_CODE && f.Currency != FeeCurrency.USD_CODE)
.Sum(f => f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount);
item.UnreceivedRMB = fees.Where(f => f.BusinessId == item.Id && f.BusinessType == item.BusinessType &&
f.CustomerId == item.CustomerId && f.FeeType == FeeType.Receivable && f.Currency == FeeCurrency.RMB_CODE)
.Sum(f => f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount);
item.UnreceivedUSD = fees.Where(f => f.BusinessId == item.Id && f.BusinessType == item.BusinessType &&
f.CustomerId == item.CustomerId && f.FeeType == FeeType.Receivable && f.Currency == FeeCurrency.USD_CODE)
.Sum(f => f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount);
item.UnreceivedOther = fees.Where(f => f.BusinessId == item.Id && f.BusinessType == item.BusinessType &&
f.CustomerId == item.CustomerId && f.FeeType == FeeType.Receivable && f.Currency != FeeCurrency.RMB_CODE && f.Currency != FeeCurrency.USD_CODE)
.Sum(f => f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount);
item.UnpaidRMBInv = fees.Where(f => f.BusinessId == item.Id && f.BusinessType == item.BusinessType && f.CustomerId == item.CustomerId && f.Currency == FeeCurrency.RMB_CODE)
.Sum(f => f.Amount - f.InvoiceAmount - f.OrderInvoiceAmount + f.OrderInvSettlementAmount);
item.UnpaidUSDInv = fees.Where(f => f.BusinessId == item.Id && f.BusinessType == item.BusinessType && f.CustomerId == item.CustomerId && f.Currency == FeeCurrency.USD_CODE)
.Sum(f => f.Amount - f.InvoiceAmount - f.OrderInvoiceAmount + f.OrderInvSettlementAmount);
item.CreateByName = users.Find(x => x.Id == item.CreateBy)?.UserName;
if (item.OperatorId.HasValue)
item.Operator = users.Find(x => x.Id == item.OperatorId.Value)?.UserName;
item.SaleDeptName = orgs.Find(x => x.Id == item.SaleDeptId)?.OrgName;
}
}
return result;
}
//创建各项业务数据的查询并集
internal ISugarQueryable<BizPaymentApplication> CreateBizQuery(List<IConditionalModel> conditionals)
{
var query = CreateFeeQuery((s, f) => f.FeeStatus == FeeStatus.AuditPassed && f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount != 0);
return query.MergeTable().Where(conditionals)
.GroupBy(s => new { s.BusinessId, s.BusinessType, s.CustomerId })
.Select(s => new BizPaymentApplication
{
Id = s.BusinessId,
BusinessType = s.BusinessType,
CustomerNo = s.CustomerNo, //委托编号
ClientName = s.ClientName, //委托单位
MBLNO = s.MBLNO,
HBLNO = s.HBLNO,
CustomerId = s.CustomerId,
CustomerName = s.CustomerName, //结费单位
AccountDate = s.AccountDate,
BookingNo = s.BookingNo, //订舱编号
CntrTotal = s.CntrTotal,
CreateBy = s.CreateBy,
ETD = s.ETD,
DischargePort = s.DischargePort,
LoadPort = s.LoadPort,
OperatorId = s.OperatorId,
SaleDeptId = s.SaleDeptId, //所属分部
SaleId = s.SaleId,
SaleName = s.Sale, //揽货人
Vessel = s.Vessel, //船名
Voyage = s.Voyage, //航次
StlName = s.StlName //结算方式
});
}
/// <summary>
/// 根据业务编号及类型获取关联费用记录
/// </summary>
/// <param name="inquiry">业务ID与业务类型</param>
/// <returns></returns>
public async Task<DataResult<PaymentApplicaitonBiz>> GetFeesAsync(DetailInquiry inquiry)
{
var ids = inquiry.Items.Select(x => x.Id).Distinct();
var types = inquiry.Items.Select(x => x.BusinessType).Distinct();
var cIds = inquiry.Items.Select(x => x.CustomerId).Distinct();
var list = await TenantDb.Queryable<FeeRecord>()
.Where(f => ids.Contains(f.BusinessId) && types.Contains(f.BusinessType) && cIds.Contains(f.CustomerId) &&
f.FeeStatus == FeeStatus.AuditPassed && f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount != 0)
.Where(inquiry.GetConditionalModels(Db))
.Select(f => new FeePaymentDto
{
RecordId = f.Id,
BusinessId = f.BusinessId,
BusinessType = f.BusinessType,
CustomerId = f.CustomerId,
CustomerName = f.CustomerName,
FeeId = f.FeeId,
FeeName = f.FeeName,
FeeType = f.FeeType,
Amount = f.Amount,
Currency = f.Currency,
OriginalCurrency = f.Currency,
OriginalRate = f.ExchangeRate,
RestAmount = f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount,
InvoiceAmount = f.InvoiceAmount,
Remark = f.Remark,
CreateBy = f.CreateBy,
TaxRate = f.TaxRate
}).ToListAsync();
if (list.Count > 0)
{
//关联用户名称
var userIds = list.Select(x => x.CreateBy).Distinct();
var users = await Db.Queryable<SysUser>().Where(x => userIds.Contains(x.Id)).Select(x => new { x.Id, x.UserName }).ToListAsync();
foreach (var item in list)
{
item.CreateByName = users.Find(x => x.Id == item.CreateBy)?.UserName;
item.ApplyAmount = item.RestAmount; //申请金额默认=剩余金额
}
}
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,
}, 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 - f.OrderAmount + f.OrderSettlementAmount,
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
}).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;
}
}
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 - f.OrderAmount + f.OrderSettlementAmount
}).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)
{
var ids1 = request.Items.Select(x => x.Id).Distinct();
var ids2 = request.Items.Select(x => x.BusinessType).Distinct();
var ids3 = request.Items.Select(x => x.CustomerId).Distinct();
var list = await TenantDb.Queryable<FeeRecord>().Where(x => x.FeeStatus == FeeStatus.AuditPassed &&
ids1.Contains(x.BusinessId) && ids2.Contains(x.BusinessType) && ids3.Contains(x.CustomerId) &&
x.Amount - x.SettlementAmount - x.OrderAmount + x.OrderSettlementAmount != 0)
.Where(request.GetQueryConditions(Db))
.Select(x => new ApplicationDetail
{
BusinessId = x.BusinessId,
BusinessType = x.BusinessType,
RecordId = x.Id,
CustomerName = x.CustomerName,
FeeType = x.FeeType,
FeeId = x.FeeId,
FeeName = x.FeeName,
Currency = x.Currency,
ApplyAmount = x.Amount - x.SettlementAmount - x.OrderAmount + x.OrderSettlementAmount,
ExchangeRate = x.ExchangeRate,
OriginalCurrency = x.Currency
}).ToListAsync();
foreach (var item in list)
item.OriginalAmount = item.ApplyAmount;
return list;
}
protected override DataResult EnsureApplication(PaymentApplication application, PaymentApplication? dbValue)
{
if (dbValue != null)
{
if (dbValue.Status == PaymentApplicationStatus.AuditSubmittd || dbValue.Status == PaymentApplicationStatus.AuditPassed)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.ApplicationSaveStatusError));
if (application.Id > 0 && !string.Equals(dbValue.Currency, application.Currency, StringComparison.OrdinalIgnoreCase))
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.ApplicationSaveCurrencyError));
}
return DataResult.Success;
}
protected override DataResult CalculateAmount(PaymentApplication application, List<FeeRecord> fees)
{
if (fees == null)
return DataResult.Success;
//非原币申请且原始金额为0则禁止提交
if (application.Details.Any(x => x.OriginalAmount == 0 && !application.Currency.IsNullOrEmpty()))
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.OriginalAmountCannotBeZero));
StringBuilder sb = new();
foreach (var detail in application.Details)
{
var fee = fees.Find(x => x.Id == detail.RecordId);
if (fee == null)
{
sb.AppendFormat(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.ApplicationCannotRelateFee)), detail.FeeName);
sb.Append("");
continue;
}
detail.Record = fee;
//未申请金额=总金额-结算金额-申请金额+申请金额已结算
var restAmount = fee.Amount - fee.SettlementAmount - fee.OrderAmount + fee.OrderSettlementAmount;
if (restAmount == 0)
{
sb.AppendFormat(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.FeeNobalance)), fee.FeeName);
sb.Append("");
continue;
}
if (detail.OriginalAmount > 0 && detail.OriginalAmount > restAmount)
{
sb.AppendFormat(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DetailExceedingLimit)), fee.FeeName);
sb.Append("");
continue;
}
else if (detail.OriginalAmount < 0 && detail.OriginalAmount < restAmount)
{
sb.AppendFormat(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DetailExceedingLimit)), fee.FeeName);
sb.Append("");
continue;
}
//更新费用记录的已申请金额
fee.OrderAmount += detail.OriginalAmount;
//类别固定为付费申请
detail.Category = DetailCategory.PaidApplication;
}
return sb.Length > 0 ? DataResult.Failed(sb.ToString()) : DataResult.Success;
}
//保存前调用
protected override async Task PreSaveAsync(PaymentApplication application)
{
if (application.Id == 0 && application.CustomerBankId == null)
{
var bankCurrency = application.Currency;
if (string.IsNullOrEmpty(bankCurrency) && application.Details.Count > 0)
bankCurrency = application.Details[0].Currency;
var bankId = await TenantDb.Queryable<InfoClientBank>().Where(x => x.ClientId == application.CustomerId &&
x.Currency == bankCurrency).OrderByDescending(x => x.IsInvoiceDefault)
.Select(x => x.Id).FirstAsync();
if (bankId > 0)
application.CustomerBankId = bankId;
}
//获取所有应收项
var recvDetails = application.Details.FindAll(x => x.FeeType == FeeType.Receivable);
foreach (var item in recvDetails)
{
item.ApplyAmount *= -1;
}
}
protected override async Task OnSaveAsync(PaymentApplication application, List<FeeRecord>? fees)
{
var details = application.Details;
if (application.Id > 0)
details = await TenantDb.Queryable<ApplicationDetail>().Where(x => x.ApplicationId == application.Id).ToListAsync();
//更新申请单总金额
application.AmountRMB = details.Where(x => x.Currency == FeeCurrency.RMB_CODE).Sum(x => x.ApplyAmount);
application.AmountUSD = details.Where(x => x.Currency == FeeCurrency.USD_CODE).Sum(x => x.ApplyAmount);
application.AmountOther = details.Where(x => x.Currency != FeeCurrency.RMB_CODE && x.Currency != FeeCurrency.USD_CODE).Sum(x => x.ApplyAmount);
await TenantDb.Updateable(application).IgnoreColumns(x => new
{
x.ApplicationNO,
x.CreateBy,
x.CreateTime,
x.Deleted,
x.DeleteBy,
x.DeleteTime
}).ExecuteCommandAsync();
if (fees != null && fees.Count > 0)
await TenantDb.Updateable(fees)
.PublicSetColumns(x => x.OrderAmount, "+").UpdateColumns(x => new { x.OrderAmount })
.ExecuteCommandAsync();
}
protected override async Task<DataResult<PaymentApplication>> PostSaveAsync(PaymentApplication application)
{
var app = await TenantDb.Queryable<PaymentApplication>().Includes(x => x.Details).FirstAsync(x => x.Id == application.Id);
return DataResult<PaymentApplication>.Success(app);
}
protected override DataResult PreDelete(List<PaymentApplication> applications)
{
if (applications.Any(x => x.Status != PaymentApplicationStatus.Pending && x.Status != PaymentApplicationStatus.AuditRejected))
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.ApplicationDeleteStatusError));
return base.PreDelete(applications);
}
protected override async Task OnDeleteDetailAsync(List<PaymentApplication> applications, DeleteOption deleteOption)
{
var detailList = applications.SelectMany(x => x.Details);
//还原费用表的已申请金额
var fees = detailList.Select(x => new FeeRecord { Id = x.RecordId, OrderAmount = x.OriginalAmount }).ToList();
await TenantDb.Updateable(fees)
.PublicSetColumns(it => it.OrderAmount, "-")
.UpdateColumns(x => new { x.OrderAmount })
.ExecuteCommandAsync();
if (deleteOption == DeleteOption.DetailOnly)
{
//更新总申请金额
var appIds = applications.Select(x => x.Id);
var dIds = detailList.Select(x => x.Id);
var details = await TenantDb.Queryable<ApplicationDetail>().Where(x => appIds.Contains(x.ApplicationId) && !dIds.Contains(x.Id))
.Select(x => new { x.ApplicationId, x.ApplyAmount, x.Currency }).ToListAsync();
var gList = details.GroupBy(x => x.ApplicationId).ToList();
foreach (var item in applications)
{
var gItems = gList.Find(x => x.Key == item.Id);
if (gItems == null)
{
item.AmountRMB = item.AmountUSD = item.AmountOther = 0m;
item.CustomerId = 0;
item.CustomerName = null;
item.CustomerBankId = null;
await TenantDb.Updateable(item)
.UpdateColumns(x => new { x.AmountRMB, x.AmountUSD, x.AmountOther, x.CustomerId, x.CustomerName, x.CustomerBankId })
.ExecuteCommandAsync();
}
else
{
item.AmountRMB = gItems.Where(x => x.Currency == FeeCurrency.RMB_CODE).Sum(x => x.ApplyAmount);
item.AmountUSD = gItems.Where(x => x.Currency == FeeCurrency.USD_CODE).Sum(x => x.ApplyAmount);
item.AmountOther = gItems.Where(x => x.Currency != FeeCurrency.RMB_CODE && x.Currency != FeeCurrency.USD_CODE).Sum(x => x.ApplyAmount);
await TenantDb.Updateable(item)
.UpdateColumns(x => new { x.AmountRMB, x.AmountUSD, x.AmountOther })
.ExecuteCommandAsync();
}
}
}
}
protected override DataResult PreSubmitApproval(List<PaymentApplication> applications)
{
if (applications.Exists(x => x.Status == PaymentApplicationStatus.AuditSubmittd || x.Status == PaymentApplicationStatus.AuditPassed))
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.ApplicationIsAuditing));
return DataResult.Success;
}
protected override void OnSubmitApproval(PaymentApplication application)
{
application.Status = PaymentApplicationStatus.AuditSubmittd;
}
protected override void OnWithdraw(PaymentApplication application)
{
application.Status = PaymentApplicationStatus.Pending;
}
/// <summary>
/// 设置是否收到发票
/// </summary>
/// <param name="isInvoiceReceived"></param>
/// <param name="ids"></param>
/// <returns></returns>
public async Task<DataResult> SetInvoiceReceivedAsync(bool isInvoiceReceived, params long[] ids)
{
var list = ids.Select(x => new PaymentApplication { Id = x, IsInvoiceReceived = isInvoiceReceived }).ToList();
int rows = await TenantDb.Updateable(list)
.UpdateColumns(x => new { x.IsInvoiceReceived })
.ExecuteCommandAsync();
return rows > 0 ? DataResult.Success : DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
}
}
}