自由结算

dev
嵇文龙 1 month ago
parent efd9f0194d
commit 4669040d84

@ -6,9 +6,9 @@ using DS.WMS.Core.Settlement.Entity;
namespace DS.WMS.Core.Settlement.Interface
{
/// <summary>
/// 付费自由结算
/// 自由结算
/// </summary>
public interface IFreeSettlementService : ISettlementService<Entity.ApplicationSettlement>
public interface IFreeSettlementService : ISettlementService<ApplicationSettlement>
{
/// <summary>
/// 获取待结算业务分页列表
@ -26,17 +26,24 @@ namespace DS.WMS.Core.Settlement.Interface
Task<DataResult<FeeForm>> GetFeesAsync(params FeeClient[] items);
/// <summary>
/// 获取付费自由结算单
/// 获取自由结算单
/// </summary>
/// <param name="id">结算单ID</param>
/// <returns></returns>
Task<DataResult<ApplicationSettlementDto>> GetAsync(long id);
/// <summary>
/// 获取付费结算明细
/// 获取结算明细
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
Task<DataResult<FreeSettlement>> GetDetailsAsync(PageRequest<long> request);
/// <summary>
/// 根据业务编号及类型获取该票业务的币别
/// </summary>
/// <param name="items">业务ID与业务类型</param>
/// <returns></returns>
Task<DataResult<List<FeeClient>>> GetCurrenciesAsync(params FeeClient[] items);
}
}

@ -1,5 +1,4 @@
using DS.Module.Core;
using DS.WMS.Core.Application.Entity;
using DS.WMS.Core.Settlement.Dtos;
using DS.WMS.Core.Settlement.Entity;
@ -39,15 +38,5 @@ namespace DS.WMS.Core.Settlement.Interface
/// <param name="ids">结算ID</param>
/// <returns></returns>
Task<DataResult> SetLockAsync(bool isLocked, params long[] ids);
/// <summary>
/// 获取待结算的自由结算费用明细
/// 参数为选中的业务或费用明细
/// 返回值为结算明细
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
Task<DataResult<List<SettlementDocument>>> GetExchangesAsync(SettlementRequest<TEntity> request);
}
}

@ -6,8 +6,8 @@ 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;
using DS.WMS.Core.Op.View;
using DS.WMS.Core.Settlement.Dtos;
using DS.WMS.Core.Settlement.Entity;
using DS.WMS.Core.Settlement.Interface;
@ -39,7 +39,7 @@ namespace DS.WMS.Core.Settlement.Method
public async Task<DataResult<List<SettlementBiz>>> GetBizListAsync(PageRequest request)
{
var whereList = request.GetConditionalModels(Db);
var result = await CreateBizQuery().Where(whereList).GroupBy(x => new { x.BusinessId, x.BusinessType })
var result = await CreateBizQuery().Where(whereList).GroupBy(x => new { x.BusinessId, x.BusinessType, x.CustomerId })
.Select<SettlementBiz>().ToQueryPageAsync(request.PageCondition);
if (result.Data.Count > 0)
@ -95,7 +95,6 @@ namespace DS.WMS.Core.Settlement.Method
//创建各项费用数据的查询并集
internal ISugarQueryable<FeeDto> CreateBizQuery()
{
/*
var query1 = TenantDb.Queryable<FeeRecord, SeaExport>((f, s) => new JoinQueryInfos(
JoinType.Inner, s.Id == f.BusinessId && f.BusinessType == BusinessType.OceanShippingExport && (f.FeeStatus == FeeStatus.AuditPassed || f.FeeStatus == FeeStatus.PartialSettlement) &&
(f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount) != 0))
@ -134,49 +133,8 @@ namespace DS.WMS.Core.Settlement.Method
BookingNo = s.BookingNo,
Enterprise = s.Enterprise,
});
*/
//海运进口
//20240929 邓羽 临时修改 改用vw_op_business
var query1 = TenantDb.Queryable<FeeRecord, VW_Op_Business>((f, s) => new JoinQueryInfos(
JoinType.Inner, s.BusinessId == f.BusinessId && f.BusinessType == BusinessType.OceanShippingExport && (f.FeeStatus == FeeStatus.AuditPassed || f.FeeStatus == FeeStatus.PartialSettlement) &&
(f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount) != 0))
.Select((f, s) => new FeeDto
{
Id = f.Id,
FeeId = f.FeeId,
FeeCode = f.FeeCode,
FeeName = f.FeeName,
FeeType = f.FeeType,
CustomerId = f.CustomerId,
CustomerName = f.CustomerName,
BusinessId = f.BusinessId,
BusinessType = BusinessType.OceanShippingExport,
Currency = f.Currency,
DebitNo = f.DebitNo,
SaleOrgId = f.SaleOrgId,
SaleOrg = f.SaleOrg,
CreateBy = f.CreateBy,
AccountDate = s.AccountDate,
BusinessDate = s.CreateTime,//业务日期
ClientName = s.CustomerName,//委托单位
CustomerNo = s.CustomerNo,
CustomNo = s.CustomNo,
DischargePort = s.DischargePort,
ETD = s.ETD,
HBLNO = s.HBLNO,
LoadPort = s.LoadPort,
MBLNO = s.MBLNO,
OperatorId = s.OperatorId,
SaleDeptId = s.SaleDeptId,
Sale = s.Sale,//揽货人
Vessel = s.Vessel,//船名
Voyage = s.Voyno,//航次
BookingNo = s.BookingNo,
Enterprise = s.Enterprise,
});
//海运进口
return TenantDb.UnionAll(new List<ISugarQueryable<FeeDto>> { query1 });
}
@ -194,7 +152,7 @@ namespace DS.WMS.Core.Settlement.Method
var list = await TenantDb.Queryable<FeeRecord>()
.Where(f => bizIds.Contains(f.BusinessId) && types.Contains(f.BusinessType) && cIds.Contains(f.CustomerId) &&
f.FeeStatus == FeeStatus.AuditPassed && (f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount) != 0)
(f.FeeStatus == FeeStatus.AuditPassed || f.FeeStatus == FeeStatus.PartialSettlement) && (f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount) != 0)
.Select(f => new FeeItem
{
RecordId = f.Id,
@ -224,6 +182,42 @@ namespace DS.WMS.Core.Settlement.Method
return DataResult<FeeForm>.Success(new FeeForm(list));
}
/// <summary>
/// 根据业务编号及类型获取该票业务的币别
/// </summary>
/// <param name="items">业务ID与业务类型</param>
/// <returns></returns>
public async Task<DataResult<List<FeeClient>>> GetCurrenciesAsync(params FeeClient[] items)
{
var bizIds = items.Select(x => x.Id).Distinct();
var types = items.Select(x => x.BusinessType).Distinct();
var cIds = 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)
&& (f.FeeStatus == FeeStatus.AuditPassed || f.FeeStatus == FeeStatus.PartialSettlement))
.Select(f => new
{
f.BusinessId,
f.BusinessType,
f.CustomerId,
f.Currency
}).ToListAsync();
var currencies = list.GroupBy(x => new { x.BusinessId, x.BusinessType, x.CustomerId }).Select(x => new FeeClient
{
Id = x.Key.BusinessId,
BusinessType = x.Key.BusinessType,
CustomerId = x.Key.CustomerId,
ExchangeRates = x.GroupBy(y => y.Currency).Select(y => new CurrencyExchangeRate
{
Currency = y.Key
}).ToList()
}).ToList();
return DataResult<List<FeeClient>>.Success(currencies);
}
/// <summary>
/// 获取付费自由结算单
/// </summary>
@ -274,7 +268,7 @@ namespace DS.WMS.Core.Settlement.Method
AdvanceRate = x.AdvanceRate,
}).FirstAsync(x => x.Id == id && x.Mode == SettlementMode.FreeSettlement);
var templist = await TenantDb.Queryable<ApplicationDetail>().Where(x => x.ApplicationId == id) .ToListAsync();
var templist = await TenantDb.Queryable<ApplicationDetail>().Where(x => x.ApplicationId == id).ToListAsync();
model.SettlementDetails = templist.Adapt<List<SettlementDetailDto>>();
@ -373,8 +367,7 @@ namespace DS.WMS.Core.Settlement.Method
return DataResult<FreeSettlement>.Success(model);
}
protected override async Task<DataResult> PreSaveAsync(Entity.ApplicationSettlement settlement)
protected override async Task<DataResult> PreSaveAsync(ApplicationSettlement settlement)
{
//settlement.Mode = SettlementMode.FreeSettlement;
//settlement.BillType = SettlementBillType.Payment;
@ -417,7 +410,7 @@ namespace DS.WMS.Core.Settlement.Method
return sb.Length > 0 ? DataResult.Failed(sb.ToString()) : DataResult.Success;
}
protected override DataResult PreDelete(List<Entity.ApplicationSettlement> settlements)
protected override DataResult PreDelete(List<ApplicationSettlement> settlements)
{
if (settlements.Any(x => x.IsLocked))
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.SettlementIsLocked));
@ -425,9 +418,5 @@ namespace DS.WMS.Core.Settlement.Method
return DataResult.Success;
}
//protected override Task OnSaveAsync(PaymentSettlement settlement)
//{
// return base.OnSaveAsync(settlement);
//}
}
}

@ -1,22 +1,15 @@
using DS.Module.Core;
using DS.Module.Core.Enums;
using DS.Module.Core.Extensions;
using DS.Module.UserModule;
using DS.WMS.ContainerManagement.Info.Entity;
using DS.WMS.Core.Application.Dtos;
using DS.WMS.Core.Application.Entity;
using DS.WMS.Core.Fee.Entity;
using DS.WMS.Core.Fee.Method;
using DS.WMS.Core.Invoice.Dtos;
using DS.WMS.Core.Settlement.Dtos;
using DS.WMS.Core.Settlement.Entity;
using DS.WMS.Core.Settlement.Interface;
using DS.WMS.Core.Sys.Interface;
using Mapster;
using Microsoft.Extensions.DependencyInjection;
using Org.BouncyCastle.Ocsp;
using SqlSugar;
using System;
namespace DS.WMS.Core.Settlement.Method
{
@ -29,10 +22,6 @@ namespace DS.WMS.Core.Settlement.Method
{
readonly Lazy<ICommonService> CommonService;
//readonly Lazy<IFreeSettlementService> FreeSettlementService;
/// <summary>
/// 初始化
/// </summary>
@ -40,53 +29,6 @@ namespace DS.WMS.Core.Settlement.Method
public SettlementService(IServiceProvider serviceProvider) : base(serviceProvider)
{
CommonService = new Lazy<ICommonService>(serviceProvider.GetRequiredService<ICommonService>());
//FreeSettlementService = new Lazy<IFreeSettlementService>(serviceProvider.GetRequiredService<IFreeSettlementService>());
}
/// <summary>
/// 根据业务编号及类型获取关联费用记录
/// </summary>
/// <param name="items">业务ID与业务类型</param>
/// <returns></returns>
public async Task<DataResult<FeeForm>> GetFeesAsync(params FeeClient[] items)
{
var bizIds = items.Select(x => x.Id).Distinct();
var types = items.Select(x => x.BusinessType).Distinct();
var cIds = 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) &&
f.FeeStatus == FeeStatus.AuditPassed && (f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount) != 0)
.Select(f => new FeeItem
{
RecordId = f.Id,
BusinessId = f.BusinessId,
BusinessType = f.BusinessType,
CustomerId = f.CustomerId,
CustomerName = f.CustomerName,
FeeId = f.FeeId,
FeeName = f.FeeName,
FeeType = f.FeeType,
TotalAmount = f.Amount,
Currency = f.Currency,
OriginalRate = f.ExchangeRate,
RestAmount = f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount,
InvoiceAmount = f.InvoiceAmount,
AccTaxRate = f.AccTaxRate,
Remark = f.Remark
}).ToListAsync();
foreach (var item in list)
{
//本次结算金额默认等于剩余金额
item.Amount = item.RestAmount;
item.OriginalAmount = item.RestAmount;
}
return DataResult<FeeForm>.Success(new FeeForm(list));
}
@ -136,73 +78,21 @@ namespace DS.WMS.Core.Settlement.Method
settlement.CustomerName = first.CustomerName;
}
//var tempDetailList = 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(tempDetailList.Count>0) details1 = new List<ApplicationDetail>();
//foreach (var tempDetail in tempDetailList)
//{
// if (tempDetail.DetailId != null)
// {
// details1.Add(tempDetail);
// }
// else {
// //20240929 该业务的所有符合条件的费用
// var feeClient = new FeeClient();
// var _detail = request.Details.First(x => x.BusinessId == tempDetail.BusinessId);
// feeClient.Id = _detail.BusinessId;
// feeClient.BusinessType = _detail.BusinessType;
// feeClient.CustomerId= request.Settlement.CustomerId;
// var paramarray = new FeeClient[]{ feeClient};
// var feeListResult = await GetFeesAsync(paramarray);
// var feeList = feeListResult.Data.Items;
// var _detailList = feeList.Where(x => x.FeeType == tempDetail.FeeType && x.RestAmount > 0)
// .Select(x => new ApplicationDetail
// {
// RefId = x.BusinessId,
// DetailId = 0,
// RecordId = x.RecordId,
// CustomerName = x.CustomerName ?? settlement.CustomerName,
// FeeId = x.FeeId,
// FeeName = x.FeeName,
// FeeType = x.FeeType,
// ApplyAmount = 0,
// Currency = x.Currency,
// ExchangeRate = tempDetail.ExchangeRate,
// OriginalAmount = 0,
// OriginalCurrency = x.Currency,
// })
// .ToList();
// details1.AddRange(_detailList);
// }
//}
details1 = await GetFeeDetailByBill(request);
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();
}
//按付费/发票申请结算
@ -395,7 +285,7 @@ namespace DS.WMS.Core.Settlement.Method
if (settlement.Id == 0)
{
//创建时需要生成申请单编号
var sequence = CommonService.Value. GetSequenceNext<TEntity>();
var sequence = CommonService.Value.GetSequenceNext<TEntity>();
if (!sequence.Succeeded)
{
return DataResult<TEntity>.Failed(sequence.Message, MultiLanguageConst.SequenceSetNotExist);
@ -451,85 +341,6 @@ namespace DS.WMS.Core.Settlement.Method
}
}
/// <summary>
/// 通过前端传递的仅包含businessid的ApplicationDetail 获取这些业务的所有指定结算对象的费用明细
///
/// 如果参数的明细当中包含Detailid 代表传递的是具体费用
/// </summary>
/// <param name="BillList"></param>
/// <returns></returns>
private async Task< List<ApplicationDetail>> GetFeeDetailByBill(SettlementRequest<TEntity> request)
{
var result = new List<ApplicationDetail>();
var settlement = request.Settlement;
var tempDetailList = 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();
foreach (var tempDetail in tempDetailList)
{
if (tempDetail.RecordId != null)
{
result.Add(tempDetail);
}
else
{
//20240929 该业务的所有符合条件的费用
var feeClient = new FeeClient();
var _detail = request.Details.First(x => x.BusinessId == tempDetail.BusinessId);
feeClient.Id = _detail.BusinessId;
feeClient.BusinessType = _detail.BusinessType;
feeClient.CustomerId = request.Settlement.CustomerId;
var paramarray = new FeeClient[] { feeClient };
var feeListResult = await GetFeesAsync(paramarray);
var feeList = feeListResult.Data.Items;
var _detailList = feeList.Where(x => x.FeeType == tempDetail.FeeType && x.RestAmount > 0)
.Select(x => new ApplicationDetail
{
RefId = x.BusinessId,
DetailId = 0,
RecordId = x.RecordId,
CustomerName = x.CustomerName ?? settlement.CustomerName,
FeeId = x.FeeId,
FeeName = x.FeeName,
FeeType = x.FeeType,
ApplyAmount = 0,
Currency = x.Currency,
ExchangeRate = tempDetail.ExchangeRate,
OriginalAmount = 0,
OriginalCurrency = x.Currency,
})
.ToList();
result.AddRange(_detailList);
}
}
return result;
}
/// <summary>
/// 用于结算单的状态检查
/// </summary>
@ -772,34 +583,5 @@ namespace DS.WMS.Core.Settlement.Method
return Task.FromResult(new List<SettlementDetailDto>());
}
/// <summary>
/// 获取待结算费用明细的原始币别
/// </summary>
/// <param name="documents"></param>
/// <returns></returns>
public async Task<DataResult<List<SettlementDocument>>> GetExchangesAsync(SettlementRequest<TEntity> request)
{
var details = await GetFeeDetailByBill(request);
var result = new List<SettlementDocument>();
foreach (var item in request.Details)
{
var document = item.Adapt<SettlementDocument>();
document.Id = item.BusinessId;
if (details.Exists(x => x.BusinessId == document.Id)) {
foreach (var detail in details.Where(x => x.BusinessId == document.Id))
{
if (!document.ExchangeRates.Exists(x => x.Currency == item.OriginalCurrency))
document.ExchangeRates.Add(new CurrencyExchangeRate { Currency = item.OriginalCurrency });
}
}
result.Add(document);
}
return DataResult<List<SettlementDocument>>.Success(result);
}
}
}

@ -7,9 +7,22 @@ namespace DS.Module.Core.Utils
/// </summary>
public static class PDFUtil
{
public static void AddStramp(Stream stream)
public static async void AddStrampAsync(this Stream stream)
{
ArgumentNullException.ThrowIfNull(stream, nameof(stream));
if (!stream.CanRead)
throw new ArgumentException("流不支持读取", nameof(stream));
var pdfStream = stream;
if (!stream.CanWrite)
{
pdfStream = new MemoryStream();
await stream.CopyToAsync(pdfStream);
}
var pdfReader = new PdfReader(stream);
}
}
}

@ -1,5 +1,6 @@
using DS.Module.Core;
using DS.Module.Core.Data;
using DS.Module.Core.Enums;
using DS.WMS.Core.Application.Dtos;
using DS.WMS.Core.Settlement.Dtos;
using DS.WMS.Core.Settlement.Entity;
@ -9,7 +10,7 @@ using Microsoft.AspNetCore.Mvc;
namespace DS.WMS.FeeApi.Controllers
{
/// <summary>
/// 付费自由结算API
/// 自由结算API
/// </summary>
public class PaymentFreeSettlementController : ApiController
{
@ -47,7 +48,7 @@ namespace DS.WMS.FeeApi.Controllers
}
/// <summary>
/// 获取付费自由结算单
/// 获取自由结算单
/// </summary>
/// <param name="id">结算单ID</param>
/// <returns></returns>
@ -58,7 +59,7 @@ namespace DS.WMS.FeeApi.Controllers
}
/// <summary>
/// 获取付费自由结算明细
/// 获取自由结算明细
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
@ -70,23 +71,28 @@ namespace DS.WMS.FeeApi.Controllers
}
/// <summary>
/// 根据费申请创建结算单
/// 根据申请创建结算单
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost, Route("Save")]
public async Task<DataResult<ApplicationSettlement>> SaveAsync([FromBody] SettlementRequest<ApplicationSettlement> request)
{
request.Settlement.Mode = SettlementMode.FreeSettlement;
return await _service.SaveAsync(request);
}
[HttpPost, Route("GetExchangesAsync")]
public async Task<DataResult<List<SettlementDocument>>> GetExchangesAsync([FromBody] SettlementRequest<ApplicationSettlement> request)
/// <summary>
/// 根据业务编号及类型获取该票业务的币别
/// </summary>
/// <param name="items">业务ID与业务类型</param>
/// <returns></returns>
[HttpPost, Route("GetCurrencies")]
public async Task<DataResult<List<FeeClient>>> GetCurrenciesAsync(params FeeClient[] items)
{
return await _service.GetExchangesAsync(request);
return await _service.GetCurrenciesAsync(items);
}
/// <summary>
/// 删除申请单明细
/// </summary>

@ -96,9 +96,12 @@ namespace DS.WMS.MainApi.Controllers
return DataResult.Failed("请联系站点管理员配置邮件服务URL");
var userEmail = await userEmailService.GetCurrentUserEmailAsync();
if (!userEmail.Succeeded || userEmail.Data == null)
if (!userEmail.Succeeded || userEmail.Data == null || string.IsNullOrEmpty(userEmail.Data.MailAccount))
return DataResult.Failed("你尚未配置邮箱设置,请到系统设置中维护后重试此操作");
if (string.IsNullOrEmpty(userEmail.Data.Password))
return DataResult.Failed("你尚未配置邮箱账户密码,请到系统设置中维护后重试此操作");
if (model.Attachments?.Length > 0)
{
for (int i = 0; i < model.Attachments.Length; i++)

Loading…
Cancel
Save