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.

683 lines
32 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 InvoiceApplicationService : ApplicationService<InvoiceApplication>, IInvoiceApplicationService
{
public override TaskBaseTypeEnum AuditType => TaskBaseTypeEnum.APPLICATION_INVOICE_AUDIT;
/// <summary>
/// 初始化
/// </summary>
/// <param name="serviceProvider"></param>
public InvoiceApplicationService(IServiceProvider serviceProvider) : base(serviceProvider)
{
}
/// <summary>
/// 获取分页列表
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public async Task<DataResult<List<InvoiceApplicationDto>>> GetListAsync(PageRequest request)
{
List<IConditionalModel> whereList = request.GetConditionalModels(Db);
var result = await TenantDb.Queryable<InvoiceApplication>().Where(whereList)
.Select((x) => new InvoiceApplicationDto
{
Id = x.Id,
ApplicationNO = x.ApplicationNO,
Status = x.Status,
CustomerName = x.CustomerName,
InvoiceHeader = x.InvoiceHeader,
Currency = x.Currency,
ApplyAmount = x.ApplyAmount,
InvoiceAmount = x.InvoiceAmount,
CreateTime = x.CreateTime, //申请时间
CreateBy = x.CreateBy, //申请人ID
InvoiceNO = x.InvoiceNO,
InvoiceBillNO = x.InvoiceBillNO, //实际开出票号
Note = x.Note,
Reason = x.Reason,
InvoiceDate = x.InvoiceDate,
Category = x.Category, //申请类型
TaxRate = x.TaxRate,
PushMode = x.PushMode,
Email = x.Email,
CellPhoneNO = x.CellPhoneNO,
InvoiceRemark = x.InvoiceRemark, //开票要求
//原币金额
OriginalAmountList = SqlFunc.Subqueryable<ApplicationDetail>().Where(y => x.Id == y.ApplicationId)
.GroupBy(y => y.OriginalCurrency).ToList(y => new CurrencyAmount { Currency = y.OriginalCurrency, Amount = y.OriginalAmount }),
//未结算
UnsettledList = SqlFunc.Subqueryable<ApplicationDetail>().InnerJoin<FeeRecord>((d, f) => d.RecordId == f.Id && (f.Amount - f.SettlementAmount - f.OrderSettlementAmount) != 0)
.GroupBy((d, f) => f.Currency).ToList((d, f) => new CurrencyAmount { Currency = f.Currency, Amount = f.Amount - f.SettlementAmount - f.OrderSettlementAmount })
}).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();
foreach (var item in result.Data)
{
item.CreateByName = users.Find(x => x.Id == item.CreateBy)?.UserName;
}
result.AdditionalData = new Dictionary<string, object>
{
{ "ApplyAmountSum", result.Data.Sum(x => x.ApplyAmount) },
{ "InvoiceAmountSum", result.Data.Sum(x => x.InvoiceAmount.GetValueOrDefault()) }
};
}
return result;
}
/// <summary>
/// 获取待开票的业务列表(编辑用)
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public async Task<DataResult<List<BizInvoiceApplication>>> GetBizListAsync(PageRequest<FeeRange?> request)
{
var query = CreateBizQuery();
if (!request.QueryCondition.IsNullOrEmpty())
{
var whereList = Db.ConfigQuery.Context.Utilities.JsonToConditionalModels(request.QueryCondition);
query = query.Where(whereList);
}
if (request.OtherQueryCondition.HasValue)
{
FeeRange feeRange = request.OtherQueryCondition.Value;
switch (feeRange)
{
case FeeRange.Unsettled:
query = query.Where(x => x.SettlementAmount == 0);
break;
case FeeRange.Settled:
query = query.Where(x => x.SettlementAmount > 0);
break;
case FeeRange.PaidNotReceived:
query = query.Where(x => x.UnSettlementPaid == 0 && x.UnSettlementCharged > 0);
break;
case FeeRange.ReceivedNotPaid:
query = query.Where(x => x.UnSettlementPaid > 0 && x.UnSettlementCharged == 0);
break;
case FeeRange.NotAppliedSettled:
query = query.Where(x => x.OrderAmount == 0 && x.SettlementAmount == 0);
break;
case FeeRange.UnreconciledSettled:
query = query.Where(x => x.DebitNo == null && x.SettlementAmount == 0);
break;
case FeeRange.NotIssuedSettled:
query = query.Where(x => x.InvoiceAmount == 0 && x.SettlementAmount == 0);
break;
case FeeRange.ReconciledNotSettled:
query = query.Where(x => x.DebitNo != null && x.SettlementAmount == 0);
break;
case FeeRange.NotReceivedPaid:
query = query.Where(x => x.UnSettlementPaid > 0 && x.UnSettlementCharged > 0);
break;
case FeeRange.SettledNotIssued:
query = query.Where(x => x.InvoiceAmount == 0 && x.SettlementAmount > 0);
break;
}
}
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();
foreach (var item in result.Data)
{
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<BizInvoiceApplication> CreateBizQuery()
{
//海运出口
var query1 = TenantDb.Queryable<SeaExport>()
.InnerJoin<FeeRecord>((s, f) => s.Id == f.BusinessId && f.BusinessType == BusinessType.OceanShippingExport)
.Where((s, f) => f.FeeStatus == FeeStatus.AuditPassed)
.GroupBy((s, f) => new { s.Id, f.CustomerId })
.Select((s, f) => new BizInvoiceApplication
{
Id = s.Id,
AccountDate = s.AccountDate,
BusinessType = BusinessType.OceanShippingExport,
CntrTotal = s.CntrTotal,
CreateBy = s.CreateBy,
CustomerId = f.CustomerId,//费用对象
CustomerName = f.CustomerName,
CustomerNo = s.CustomerNo,
ClientName = s.CustomerName, //委托单位
DischargePort = s.DischargePort,
ETD = s.ETD,
HBLNO = s.HBLNO,
LoadPort = s.LoadPort,
MBLNO = s.MBLNO,
OperatorId = s.OperatorId,
SaleDeptId = s.SaleDeptId,
SaleId = s.SaleId,
SaleName = s.Sale,//揽货人
Vessel = s.Vessel,//船名
Voyage = s.Voyno,//航次
BookingNO = s.BookingNo,
StlName = s.StlName,
DebitNo = f.DebitNo,
OrderAmount = f.OrderAmount,
InvoiceAmount = f.InvoiceAmount,
SettlementAmount = f.SettlementAmount,
//未申请开票金额=金额-开票金额-申请开票金额+申请开票金额已开票
UnBilledRMB = SqlFunc.Subqueryable<FeeRecord>().Where(f => f.BusinessId == s.Id && f.FeeStatus == FeeStatus.AuditPassed
&& f.Currency == FeeCurrency.RMB_CODE).Select(f => SqlFunc.AggregateSum(f.Amount - f.InvoiceAmount - f.OrderInvoiceAmount + f.OrderInvSettlementAmount)),
UnBilledUSD = SqlFunc.Subqueryable<FeeRecord>().Where(f => f.BusinessId == s.Id && f.FeeStatus == FeeStatus.AuditPassed
&& f.Currency == FeeCurrency.USD_CODE).Select(f => SqlFunc.AggregateSum(f.Amount - f.InvoiceAmount - f.OrderInvoiceAmount + f.OrderInvSettlementAmount)),
UnBilledOther = SqlFunc.Subqueryable<FeeRecord>().Where(f => f.BusinessId == s.Id && f.FeeStatus == FeeStatus.AuditPassed
&& f.Currency != FeeCurrency.RMB_CODE && f.Currency != FeeCurrency.USD_CODE).Select(f => SqlFunc.AggregateSum(f.Amount - f.InvoiceAmount - f.OrderInvoiceAmount + f.OrderInvSettlementAmount)),
//未结算金额=金额-结算金额-申请金额+申请金额已结算
UnSettlementPaid = SqlFunc.Subqueryable<FeeRecord>().Where(f => f.BusinessId == s.Id && f.FeeStatus == FeeStatus.AuditPassed && f.FeeType == FeeType.Payable)
.Select(f => SqlFunc.AggregateSum(f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount)),
UnSettlementCharged = SqlFunc.Subqueryable<FeeRecord>().Where(f => f.BusinessId == s.Id && f.FeeStatus == FeeStatus.AuditPassed && f.FeeType == FeeType.Receivable)
.Select(f => SqlFunc.AggregateSum(f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount)),
});
//海运进口
return TenantDb.UnionAll(new List<ISugarQueryable<BizInvoiceApplication>> { query1 });
}
/// <summary>
/// 根据业务编号及类型获取关联费用记录
/// </summary>
/// <param name="items">业务ID与业务类型</param>
/// <returns></returns>
public async Task<DataResult<InvoiceApplicaitonBiz>> 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 => f.FeeStatus == FeeStatus.AuditPassed &&
bizIds.Contains(f.BusinessId) && types.Contains(f.BusinessType) && cIds.Contains(f.CustomerId))
.Select(f => new FeeInvoiceDto
{
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,
RestAmount = f.Amount - f.InvoiceAmount - f.OrderInvoiceAmount + f.OrderInvSettlementAmount,
Remark = f.Remark,
CreateBy = f.CreateBy
}).ToListAsync();
//移除开票剩余金额为0的项
list.RemoveAll(f => f.RestAmount == 0);
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;
}
}
return DataResult<InvoiceApplicaitonBiz>.Success(new InvoiceApplicaitonBiz(list));
}
/// <summary>
/// 获取发票申请详情
/// </summary>
/// <param name="id">申请单ID</param>
/// <returns></returns>
public async Task<DataResult<InvoiceApplicationDto>> GetAsync(long id)
{
var dto = await TenantDb.Queryable<InvoiceApplication>().Where(a => a.Id == id)
.LeftJoin<InfoClientBank>((a, b1) => a.CustomerBankId == b1.Id)
.LeftJoin<InfoClientBank>((a, b1, b2) => a.USDCustomerBankId == b2.Id)
.Select((a, b1, b2) => new InvoiceApplicationDto
{
Id = a.Id,
ApplicationNO = a.ApplicationNO,
AutualCustomerName = a.AutualCustomerName,
Currency = a.Currency,
CustomerId = a.CustomerId,
CustomerName = a.CustomerName,
Status = a.Status,
CreateTime = a.CreateTime,
CreateBy = a.CreateBy,
InvoiceDate = a.InvoiceDate,
InvoiceAmount = a.InvoiceAmount,
InvoiceHeader = a.InvoiceHeader,
InvoiceNO = a.InvoiceNO,
InvoiceBillNO = a.InvoiceBillNO,
InvoiceRemark = a.InvoiceRemark,
SaleDeptId = a.SaleDeptId,
TaxID = a.TaxID,
Note = a.Note,
ApplyAmount = a.ApplyAmount,
OtherCurrencyAmount = a.OtherCurrencyAmount,
Category = a.Category,
CustomerAddTel = a.CustomerAddTel,
CustomerBankId = a.CustomerBankId,
CustomerBankName = b1.BankName + " " + b1.Account,
USDCustomerBankId = a.USDCustomerBankId,
USDCustomerBankName = b2.BankName + " " + b2.Account
}).FirstAsync();
if (dto != null)
{
dto.CreateByName = await Db.Queryable<SysUser>().Where(x => x.Id == dto.CreateBy).Select(x => x.UserName).FirstAsync();
dto.InvoiceDetails = await TenantDb.Queryable<InvoiceDetail>().Where(x => x.ApplicationId == dto.Id && x.Category == DetailCategory.InvoiceApplication).ToListAsync();
dto.Details = await TenantDb.Queryable<ApplicationDetail>().LeftJoin<FeeRecord>((d, f) => d.RecordId == f.Id)
.Where(d => d.ApplicationId == id).Select((d, f) => new InvoiceApplicationDetailDto
{
Id = d.Id,
RecordId = f.Id,
FeeType = d.FeeType,
FeeId = d.FeeId,
FeeName = d.FeeName,
Amount = d.ApplyAmount,
OriginalAmount = d.OriginalAmount,
//未申请金额=(金额-结算金额-申请金额+申请金额已结算)
RestAmount = f.Amount - f.SettlementAmount - f.OrderAmount + f.OrderSettlementAmount,
Currency = d.Currency,
OriginalCurrency = d.OriginalCurrency,
OriginalRate = f.ExchangeRate,
ExchangeRate = d.ExchangeRate,
AccTaxRate = f.AccTaxRate,
BusinessId = f.BusinessId,
BusinessType = f.BusinessType
}).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.SummaryItems = dto.Details.GroupBy(x => new { x.FeeType, x.Currency }).Select(x => new SummaryItem
{
FeeType = x.Key.FeeType,
Currency = x.Key.Currency,
Amount = x.Sum(y => y.Amount),
OriginalAmount = x.Sum(y => y.OriginalAmount)
}).ToList();
}
return DataResult<InvoiceApplicationDto>.Success(dto);
}
/// <summary>
/// 删除发票明细
/// </summary>
/// <param name="ids">发票明细ID</param>
/// <returns></returns>
public async Task<DataResult> DeleteInvoiceDetailAsync(params long[] ids)
{
int rows = await TenantDb.Deleteable<InvoiceDetail>().Where(x => ids.Contains(x.Id)).ExecuteCommandAsync();
return rows > 0 ? DataResult.Success : DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
}
protected override async Task<List<ApplicationDetail>> GetDetailsAsync(ApplicationRequest<InvoiceApplication> 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))
.Where(request.GetQueryConditions(Db))
.Select(x => new ApplicationDetail
{
RecordId = x.Id,
CustomerName = x.CustomerName,
FeeType = x.FeeType,
FeeId = x.FeeId,
FeeName = x.FeeName,
Currency = x.Currency,
ApplyAmount = x.Amount - x.InvoiceAmount - x.OrderInvoiceAmount + x.OrderInvSettlementAmount,
ExchangeRate = x.ExchangeRate,
OriginalCurrency = x.Currency
}).ToListAsync();
list.RemoveAll(x => x.ApplyAmount == 0);
foreach (var item in list)
item.OriginalAmount = item.ApplyAmount;
return list;
}
protected override DataResult EnsureApplication(InvoiceApplication application, InvoiceApplication? dbValue)
{
if (dbValue != null && dbValue.Status != InvoiceApplicationStatus.Pending && dbValue.Status != InvoiceApplicationStatus.AuditRejected)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.ApplicationSaveStatusError));
return DataResult.Success;
}
protected override DataResult CalculateAmount(InvoiceApplication application, List<FeeRecord> fees)
{
if (fees == null)
return DataResult.Success;
//if (fees.Any(x => x.CustomerId != application.CustomerId))
// return DataResult.FailedWithDesc(nameof(MultiLanguageConst.ApplicationCustomerDetail));
//原始金额为0则禁止提交
if (application.Details.Any(x => x.OriginalAmount == 0))
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;
//检查税率是否一致
if (application.TaxRate != fee.TaxRate)
{
sb.AppendFormat(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.InvoiceRateFee)), detail.FeeName);
sb.Append("");
continue;
}
//未申请开票金额=(金额-已开票金额-申请开票金额+申请开票金额已开票
var restAmount = fee.Amount - fee.InvoiceAmount - fee.OrderInvoiceAmount + fee.OrderInvSettlementAmount;
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;
}
if (detail.OriginalAmount < 0 && detail.OriginalAmount < restAmount)
{
sb.AppendFormat(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DetailExceedingLimit)), fee.FeeName);
sb.Append("");
continue;
}
//更新费用记录的申请开票金额
fee.OrderInvoiceAmount += detail.OriginalAmount;
//类别固定为发票申请
detail.Category = DetailCategory.InvoiceApplication;
}
if (sb.Length > 0)
return DataResult.Failed(sb.ToString());
return DataResult.Success;
}
protected override async Task OnSaveAsync(InvoiceApplication application, List<FeeRecord>? fees)
{
//先清空发票明细
if (application.Id > 0)
await TenantDb.Deleteable<InvoiceDetail>().Where(x => x.ApplicationId == application.Id).ExecuteCommandAsync();
//然后根据申请单明细重新生成
await FillInvoiceDetailsAsync([application]);
if (application.InvoiceDetails?.Count > 0)
{
await TenantDb.Insertable(application.InvoiceDetails).ExecuteCommandAsync();
}
//更新申请开票金额
if (fees != null && fees.Count > 0)
await TenantDb.Updateable(fees)
.PublicSetColumns(x => x.OrderInvoiceAmount, "+")
.UpdateColumns(x => new { x.OrderInvoiceAmount })
.ExecuteCommandAsync();
await base.OnSaveAsync(application, fees);
}
//根据费用明细填充发票明细
async Task FillInvoiceDetailsAsync(IEnumerable<InvoiceApplication> applications)
{
foreach (var application in applications)
{
application.ApplyAmount = application.Details.Sum(x => x.ApplyAmount);
application.AmountUppercase = new Money(application.ApplyAmount).ToString();
if (application.Details.Count > 0 && (application.InvoiceDetails == null || application.InvoiceDetails.Count == 0))
{
var ids = application.Details.Select(x => x.RecordId).ToList();
var feesCodes = await TenantDb.Queryable<FeeRecord>()
.InnerJoin<FeeCode>((f, c) => f.FeeId == c.Id && ids.Contains(f.Id))
.Select((f, c) => new
{
FeeId = c.Id,
c.GoodName
}).ToListAsync();
var list = feesCodes.GroupBy(x => x.GoodName).Select(x => new
{
Name = x.Key,
FeeIds = x.Select(y => y.FeeId)
}).ToList();
var goodsNames = list.Select(x => x.Name);
var invCodes = await TenantDb.Queryable<CodeInvoice>().Where(x => goodsNames.Contains(x.Name))
.Select(x => new
{
x.Id,
x.Name,
x.DefaultCurrency,
x.TaxRate,
x.Specification,
x.Unit
}).ToListAsync();
application.InvoiceDetails = new List<InvoiceDetail>(list.Count);
foreach (var item in list)
{
var invCode = invCodes.Find(x => x.Name == item.Name);
var detail = new InvoiceDetail
{
ApplicationId = application.Id,
Name = item.Name,
TaxRate = application.TaxRate,
Quantity = 1,
TaxUnitPrice = application.Details.FindAll(x => item.FeeIds.Contains(x.FeeId)).Sum(x => x.ApplyAmount),
Category = DetailCategory.InvoiceApplication
};
if (invCode != null)
{
detail.TaxRate = invCode.TaxRate;
detail.Specification = invCode.Specification;
detail.Unit = invCode.Unit;
}
detail.TaxAmount = detail.TaxUnitPrice * application.TaxRate;
detail.UnitPrice = detail.TaxUnitPrice - detail.TaxAmount;
detail.Amount = detail.TaxUnitPrice * detail.Quantity;
application.InvoiceDetails.Add(detail);
}
}
}
}
protected override DataResult PreDelete(List<InvoiceApplication> applications)
{
if (applications.Any(x => x.Status != InvoiceApplicationStatus.Pending && x.Status != InvoiceApplicationStatus.AuditRejected))
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.ApplicationDeleteStatusError));
return DataResult.Success;
}
protected override async Task OnDeleteDetailAsync(List<InvoiceApplication> applications, DeleteOption deleteOption)
{
//还原费用表的申请开票金额
var fees = applications.SelectMany(x => x.Details).Select(x => new FeeRecord
{
Id = x.RecordId,
OrderInvoiceAmount = x.OriginalAmount
}).ToList();
await TenantDb.Updateable(fees)
.PublicSetColumns(it => it.OrderInvoiceAmount, "-")
.UpdateColumns(x => new { x.OrderInvoiceAmount })
.ExecuteCommandAsync();
if (deleteOption == DeleteOption.DetailOnly)
{
//删除明细需要同时变更发票明细
var appIds = applications.Select(x => x.Id).ToList();
var excludeIds = applications.SelectMany(x => x.Details).Select(x => x.Id).ToList();
var details = await TenantDb.Queryable<ApplicationDetail>().Where(x => appIds.Contains(x.ApplicationId) && !excludeIds.Contains(x.Id))
.Select(x => new ApplicationDetail
{
Id = x.Id,
ApplicationId = x.ApplicationId,
RecordId = x.RecordId,
FeeId = x.FeeId,
ApplyAmount = x.ApplyAmount
}).ToListAsync();
foreach (var item in applications)
{
//重新设置申请明细
item.Details = details.FindAll(x => x.ApplicationId == item.Id);
}
await TenantDb.Deleteable<InvoiceDetail>().Where(x => appIds.Contains(x.ApplicationId)).ExecuteCommandAsync();
await FillInvoiceDetailsAsync(applications);
var invDetails = applications.SelectMany(x => x.InvoiceDetails).ToList();
if (invDetails.Count > 0)
await TenantDb.Insertable(invDetails).ExecuteCommandAsync();
await TenantDb.Updateable(applications).UpdateColumns(x => new
{
x.ApplyAmount,
x.AmountUppercase
}).ExecuteCommandAsync();
}
}
protected override DataResult PreSubmitApproval(List<InvoiceApplication> applications)
{
if (applications.Exists(x => x.Status == InvoiceApplicationStatus.AuditSubmittd || x.Status == InvoiceApplicationStatus.AuditPassed))
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.ApplicationIsAuditing));
return DataResult.Success;
}
protected override void OnSubmitApproval(InvoiceApplication application)
{
application.Status = InvoiceApplicationStatus.AuditSubmittd;
}
protected override void OnWithdraw(InvoiceApplication application)
{
application.Status = InvoiceApplicationStatus.Pending;
}
}
}