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.

259 lines
12 KiB
C#

2 months ago
using System.Text;
using DS.Module.Core;
using DS.Module.Core.Enums;
using DS.Module.Core.Extensions;
using DS.WMS.Core.Application.Dtos;
using DS.WMS.Core.Application.Entity;
using DS.WMS.Core.Fee.Entity;
using DS.WMS.Core.Invoice.Dtos;
using DS.WMS.Core.Op.Entity;
using DS.WMS.Core.Settlement.Dtos;
2 months ago
using DS.WMS.Core.Settlement.Entity;
using DS.WMS.Core.Settlement.Interface;
using DS.WMS.Core.Sys.Entity;
using Masuit.Tools.Systems;
namespace DS.WMS.Core.Settlement.Method
{
/// <summary>
/// 发票结算
/// </summary>
public class InvoiceSettlementService : SettlementService<ApplicationSettlement>, IInvoiceSettlementService
{
/// <summary>
/// 初始化
/// </summary>
/// <param name="provider"></param>
public InvoiceSettlementService(IServiceProvider provider) : base(provider)
{
}
/// <summary>
/// 获取待结算的发票列表
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public async Task<DataResult<List<InvoiceDto>>> GetInvoiceListAsync(PageRequest request)
{
var whereList = request.GetConditionalModels(Db);
var result = await TenantDb.Queryable<Invoice.Entity.Invoice>()
.InnerJoin<ApplicationDetail>((a, d) => d.Category == DetailCategory.InvoiceIssuance && a.Id == d.ApplicationId && d.OriginalAmount - d.OriginalProcessedAmount != 0)
.InnerJoin<FeeRecord>((a, d, f) => (f.FeeStatus == FeeStatus.AuditPassed || f.FeeStatus == FeeStatus.PartialSettlement) && d.RecordId == f.Id &&
((f.Amount > 0 && d.OriginalAmount - d.OriginalProcessedAmount <= f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount) ||
(f.Amount < 0 && d.OriginalAmount - d.OriginalProcessedAmount >= f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount))
)
.GroupBy((a, d, f) => a.Id)
.Select((a, d, f) => new InvoiceDto
{
}, true).MergeTable().Where(whereList).ToQueryPageAsync(request.PageCondition);
if (result.Data?.Count > 0)
{
//关联用户名称
var userIds = result.Data.Select(x => x.CreateBy)
.Distinct();
var users = await Db.Queryable<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();
var ids = result.Data.Select(x => x.Id);
var details = await TenantDb.Queryable<ApplicationDetail>().Where(x => ids.Contains(x.ApplicationId) &&
x.Category == DetailCategory.InvoiceIssuance).Select<ApplicationDetailDto>().ToListAsync();
foreach (var item in result.Data)
{
item.CreateByName = users.Find(x => x.Id == item.CreateBy)?.UserName;
item.SaleDeptName = orgs.Find(x => x.Id == item.SaleDeptId)?.OrgName;
item.Details = details.FindAll(x => x.ApplicationId == item.Id);
}
}
return result;
}
/// <summary>
/// 获取发票申请费用明细
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
public async Task<DataResult<List<ApplicationDetailDto>>> GetInvoiceDetailsAsync(params long[] ids)
{
var query1 = TenantDb.Queryable<ApplicationDetail>()
.InnerJoin<FeeRecord>((d, f) => d.Category == DetailCategory.InvoiceIssuance && d.RecordId == f.Id &&
(f.FeeStatus == FeeStatus.AuditPassed || f.FeeStatus == FeeStatus.PartialSettlement) && f.BusinessType == BusinessType.OceanShippingExport &&
((f.Amount > 0 && d.OriginalAmount - d.OriginalProcessedAmount <= f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount) ||
(f.Amount < 0 && d.OriginalAmount - d.OriginalProcessedAmount >= f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount))
)
.LeftJoin<SeaExport>((d, f, s) => f.BusinessId == s.Id)
.Where((d, f, s) => ids.Contains(d.ApplicationId))
.Select((d, f, s) => new ApplicationDetailDto
{
ClientName = s.CustomerName,
Voyage = s.Voyno,
SourceName = s.SourceName,
}, true);
var list = await TenantDb.UnionAll(query1).ToListAsync();
var result = DataResult<List<ApplicationDetailDto>>.Success(list);
result.Count = list.Count;
return result;
}
protected override async Task<List<SettlementDetailDto>> GetSettlementDetails(long id)
{
var list = await TenantDb.Queryable<ApplicationDetail>()
.InnerJoin<ApplicationDetail>((d, pd) => d.DetailId == pd.Id)
.InnerJoin<InvoiceApplication>((d, pd, pa) => pd.ApplicationId == pa.Id)
.Where(d => d.ApplicationId == id)
.Select((d, pd, pa) => new
{
d.Id,
d.ApplicationId,
d.ApplyAmount,
d.Currency,
d.OriginalCurrency,
d.OriginalAmount,
pa.ApplicationNO,
pa.Status,
pa.CreateTime,
pa.CreateBy,
pa.Note
}).ToListAsync();
var details = new List<SettlementDetailDto>();
if (list.Count == 0)
return details;
var gp = list.GroupBy(d => d.ApplicationId);
var uids = list.Select(x => x.CreateBy).Distinct();
var users = await Db.Queryable<SysUser>().Where(x => uids.Contains(x.Id)).Select(x => new
{
x.Id,
x.UserName
}).ToListAsync();
foreach (var g in gp)
{
var firstItem = g.FirstOrDefault();
var dto = new SettlementDetailDto
{
ApplicationId = g.Key,
//Ids = g.Select(x => x.Id),
RMBApplyAmount = g.Where(x => x.OriginalCurrency == FeeCurrency.RMB_CODE).Sum(x => x.ApplyAmount),
USDApplyAmount = g.Where(x => x.OriginalCurrency == FeeCurrency.USD_CODE).Sum(x => x.ApplyAmount),
ApplicationNO = firstItem.ApplicationNO,
Status = (int)firstItem.Status,
StatusText = firstItem.Status.GetDescription(),
CreateTime = firstItem?.CreateTime,
CreateBy = firstItem?.CreateBy,
CreateByName = users.Find(x => x.Id == firstItem?.CreateBy)?.UserName,
PaymentDate = firstItem?.CreateTime,
Note = firstItem?.Note
};
//包含多个币别
if (g.GroupBy(x => x.OriginalCurrency).Select(x => x.Key).Count() > 1)
{
//原始币别=不等于结算单币别的首个币别参考DS7
dto.OriginalCurrency = g.Select(x => x.OriginalCurrency).FirstOrDefault();
//原始金额=当前结算单的币别合计
dto.OriginalAmount = g.Sum(x => x.ApplyAmount);
}
else
{
dto.OriginalCurrency = firstItem?.OriginalCurrency;
dto.OriginalAmount = g.Where(x => x.OriginalCurrency == dto.OriginalCurrency).Sum(x => x.ApplyAmount);
}
//结算金额=原申请的原始币别合计
dto.SettlementAmount = g.Where(x => x.OriginalCurrency == dto.OriginalCurrency).Sum(x => x.ApplyAmount);
details.Add(dto);
}
return details;
}
2 months ago
protected override async Task<DataResult> PreSaveAsync(ApplicationSettlement settlement)
2 months ago
{
//settlement.Mode = SettlementMode.InvoiceSettlement;
var appIds = settlement.Details.Select(x => x.ApplicationId).Distinct();
var appList = await TenantDb.Queryable<InvoiceApplication>().Where(x => appIds.Contains(x.Id))
.Select(x => new
{
x.Id,
x.Status,
x.CustomerId,
x.CustomerName,
}).ToListAsync();
if (appList.Count == 0)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.EmptyData));
if (appList.Exists(x => x.Status != InvoiceApplicationStatus.AuditPassed))
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.ApplicationSelectStatusError));
if (appList.GroupBy(x => x.CustomerId).Select(x => x.Key).Count() > 1)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.DetailCustomerOnlyOne));
//获取剩余待结算金额
var ids2 = settlement.Details.Select(x => x.DetailId);
var appDetails = await TenantDb.Queryable<ApplicationDetail>().Where(x => ids2.Contains(x.Id) && x.Category == DetailCategory.InvoiceIssuance)
2 months ago
.Select(x => new
{
x.Id,
OriginalRestAmount = x.OriginalAmount - x.OriginalProcessedAmount
2 months ago
}).ToListAsync();
StringBuilder sb = new();
foreach (var detail in settlement.Details)
{
var item = appDetails.Find(x => x.Id == detail.DetailId);
if (item == null)
{
sb.Append(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.EmptyData)));
break;
}
if (detail.OriginalAmount > 0 && detail.OriginalAmount > item.OriginalRestAmount)
{
sb.AppendFormat(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DetailExceedingLimit)), detail.FeeName);
sb.Append("");
continue;
}
else if (detail.OriginalAmount < 0 && detail.OriginalAmount < item.OriginalRestAmount)
{
sb.AppendFormat(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DetailExceedingLimit)), detail.FeeName);
sb.Append("");
continue;
}
detail.Category = DetailCategory.InvoiceSettlement;
}
return sb.Length > 0 ? DataResult.Failed(sb.ToString()) : DataResult.Success;
}
protected override async Task OnSaveAsync(ApplicationSettlement settlement)
{
//更新发票费用明细的已处理金额
var list = settlement.Details.Select(x => new ApplicationDetail
{
Id = x.DetailId.Value,
Category = DetailCategory.InvoiceIssuance,
ProcessedAmount = x.ApplyAmount,
OriginalProcessedAmount = x.OriginalAmount
}).ToList();
await TenantDb.Updateable(list)
.PublicSetColumns(x => x.ProcessedAmount, "+")
.PublicSetColumns(x => x.OriginalProcessedAmount, "+")
.UpdateColumns(x => new { x.ProcessedAmount, x.OriginalProcessedAmount })
.ExecuteCommandAsync();
}
}
}