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.

539 lines
21 KiB
C#

using AngleSharp.Dom;
using DS.Module.Core;
using DS.Module.Core.Enums;
using DS.Module.Core.Extensions;
using DS.Module.SqlSugar;
using DS.Module.UserModule;
using DS.WMS.Core.Fee.Dtos;
using DS.WMS.Core.Fee.Entity;
using DS.WMS.Core.Fee.Interface;
using DS.WMS.Core.Flow.Dtos;
using DS.WMS.Core.Flow.Interface;
using DS.WMS.Core.Sys.Entity;
using DS.WMS.Core.Sys.Interface;
using DS.WMS.Core.Sys.Method;
using DS.WMS.Core.TaskInteraction.Dtos;
using DS.WMS.Core.TaskInteraction.Interface;
using DS.WMS.Core.TaskPlat.Entity;
using LanguageExt.Common;
using Mapster;
using Masuit.Tools.Database;
using Masuit.Tools.Systems;
using Microsoft.Extensions.DependencyInjection;
using SqlSugar;
using static AnyDiff.DifferenceLines;
namespace DS.WMS.Core.Fee.Method
{
/// <summary>
/// 报销单相关
/// </summary>
public class FeeReimbursementService : IReimbursementService
{
private readonly IServiceProvider _serviceProvider;
private readonly ISaasDbService saasService;
private readonly ISqlSugarClient db;
private readonly IUser user;
readonly IAuditTaskService taskService;
Lazy<IAuditTaskService> taskService2;
Lazy<IClientFlowInstanceService> flowService;
private readonly ICommonService commonService;
/// <summary>
///
/// </summary>
/// <param name="serviceProvider"></param>
public FeeReimbursementService(IServiceProvider serviceProvider, ICommonService commonService)
{
_serviceProvider = serviceProvider;
saasService = _serviceProvider.GetRequiredService<ISaasDbService>();
db = _serviceProvider.GetRequiredService<ISqlSugarClient>();
user = _serviceProvider.GetRequiredService<IUser>();
taskService = serviceProvider.GetRequiredService<IAuditTaskService>();
taskService2 = new Lazy<IAuditTaskService>(serviceProvider.GetRequiredService<IAuditTaskService>());
flowService = new Lazy<IClientFlowInstanceService>(serviceProvider.GetRequiredService<IClientFlowInstanceService>());
this.commonService = commonService;
}
/// <summary>
/// 列表
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public DataResult<List<ReimbursementRes>> GetListByPage(PageRequest request)
{
//序列化查询条件
var whereList = db.ConfigQuery.Context.Utilities.JsonToConditionalModels(request.QueryCondition);
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
var data = tenantDb.Queryable<FeeReimbursement>()
.Where(whereList)
.Select<ReimbursementRes>().ToQueryPage(request.PageCondition);
return data;
}
/// <summary>
/// 新增报销申请
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
public async Task<DataResult> AddReimbursement(ReimbursementReq req)
{
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
//修改
if (req.Id>0)
{
var FeeR = tenantDb.Queryable<FeeReimbursement>().Where(t => t.Id == req.Id).First();
if (FeeR == null)
{
return DataResult.Failed($"数据不存在,请检查");
}
if (FeeR.ReimbursementType!= ReimbursementTypeEnums.NotSubmitted)
{
return DataResult.Failed($"报销单状态不为未提交,不可修改");
}
var data = req.Adapt<FeeReimbursement>();
data.UserId = user.UserId;
data.ReimbursementType = ReimbursementTypeEnums.NotSubmitted;
data.Reimburser = user.UserName;
data.OrgId = user.OrgId;
var info = tenantDb.Updateable(data).ExecuteCommand();
//将子表数据删除,重新添加
var datadtl = tenantDb.Queryable<FeeReimbursementDetail>().Where(t => t.PId == req.Id).ToList();
foreach (var item in datadtl)
{
var ininfo = tenantDb.Queryable<InInvoice>().Where(t => t.InvoiceNumber == item.InvoiceNumber).First();
if (ininfo.ReimbursementType != ReimbursementTypeEnums.NotSubmitted)
{
return DataResult.Failed($"发票状态异常,不可修改");
}
}
tenantDb.Deleteable(datadtl).ExecuteCommand();
foreach (var item in req.Data)
{
//查询发票信息是否存在
var inviceinfo = tenantDb.Queryable<InInvoice>().Where(t => t.InvoiceNumber == item.InvoiceNumber).First();
if (inviceinfo == null)
{
return DataResult.Failed($"发票号{item.InvoiceNumber}不存在,请检查");
}
//发票报销状态 校验
if (inviceinfo.ReimbursementType == ReimbursementTypeEnums.UnderReview) //报销中
{
return DataResult.Failed($"提交失败,发票号{item.InvoiceNumber}正在报销,请检查");
}
if (inviceinfo.ReimbursementType == ReimbursementTypeEnums.Approved) //已报销
{
return DataResult.Failed($"提交失败,发票号{item.InvoiceNumber}已报销,请检查");
}
inviceinfo.ReimbursementType = ReimbursementTypeEnums.UnderReview;
tenantDb.Updateable(inviceinfo).ExecuteCommand();
var dataDetail = item.Adapt<FeeReimbursementDetail>();
dataDetail.Status = ReimbursementTypeEnums.NotSubmitted;
dataDetail.PId = req.Id;
tenantDb.Insertable(dataDetail).ExecuteCommand();
}
}
//新增
else
{
#region 提交报销数据校验
foreach (var item in req.Data)
{
//查询发票信息是否存在
var inviceinfo = tenantDb.Queryable<InInvoice>().Where(t => t.InvoiceNumber == item.InvoiceNumber).First();
if (inviceinfo == null)
{
return DataResult.Failed($"发票号{item.InvoiceNumber}不存在,请检查");
}
//发票报销状态 校验 待完善
if (inviceinfo.ReimbursementType == ReimbursementTypeEnums.UnderReview) //报销中
{
return DataResult.Failed($"提交失败,发票号{item.InvoiceNumber}正在报销,请检查");
}
if (inviceinfo.ReimbursementType == ReimbursementTypeEnums.Approved) //已报销
{
return DataResult.Failed($"提交失败,发票号{item.InvoiceNumber}已报销,请检查");
}
}
#endregion
//添加主表信息
var data = req.Adapt<FeeReimbursement>();
data.UserId = user.UserId;
//data.ReimbursementId = "23"; //报销单编号.
//data.CreationTime = DateTime.Now;//制单时间
data.ReimbursementType = ReimbursementTypeEnums.NotSubmitted;
data.Reimburser = user.UserName;
data.OrgId = user.OrgId;
data.Amount = req.Data.Sum(t=>t.Amount);
var info = tenantDb.Insertable(data).ExecuteReturnEntity();
//添加子表信息
foreach (var item in req.Data)
{
var inviceinfo = tenantDb.Queryable<InInvoice>().Where(t => t.InvoiceNumber == item.InvoiceNumber).First();
var dataDetail = item.Adapt<FeeReimbursementDetail>();
dataDetail.Status = ReimbursementTypeEnums.NotSubmitted;
dataDetail.PId = info.Id;
dataDetail.Amount = (decimal)inviceinfo.Amount;
tenantDb.Insertable(dataDetail).ExecuteReturnEntity();
inviceinfo.ReimbursementType = ReimbursementTypeEnums.UnderReview;
tenantDb.Updateable(inviceinfo).ExecuteCommand();
}
return DataResult.Successed("添加成功!", info.Id, MultiLanguageConst.DataCreateSuccess);
}
return await Task.FromResult(DataResult.Successed("操作成功"));
}
/// <summary>
/// 提交报销单审核
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
public async Task<DataResult> SubmitReimbursement(SubmitReimbursementReq req)
{
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
var info= tenantDb.Queryable<FeeReimbursement>().Where(t => t.Id == req.Id).First();
if (info==null)
{
return DataResult.Failed($"报销单不存在,请检查");
}
if (info.ReimbursementType!=ReimbursementTypeEnums.NotSubmitted)
{
return DataResult.Failed($"报销单状态异常,请检查");
}
var Pinfo = tenantDb.Queryable<FeeReimbursementDetail>().Where(t => t.PId == req.Id).ToList();
#region 提交报销数据校验
foreach (var item in Pinfo)
{
//查询发票信息是否存在
var inviceinfo = tenantDb.Queryable<InInvoice>().Where(t => t.InvoiceNumber == item.InvoiceNumber).First();
if (inviceinfo == null)
{
return DataResult.Failed($"发票号{item.InvoiceNumber}不存在,请检查");
}
////发票报销状态 校验 待完善
//if (inviceinfo.ReimbursementType == ReimbursementTypeEnums.UnderReview) //报销中
//{
// return DataResult.Failed($"提交失败,发票号{item.InvoiceNumber}正在报销,请检查");
//}
//if (inviceinfo.ReimbursementType == ReimbursementTypeEnums.Approved) //已报销
//{
// return DataResult.Failed($"提交失败,发票号{item.InvoiceNumber}已报销,请检查");
//}
}
#endregion
//修改主表信息
DataResult<string> sequence = commonService.GetSequenceNext<FeeReimbursement>(tenantDb, user);
string No = sequence.Data ?? "";
info.ReimbursementId = No; //报销单编号.
info.CreationTime = DateTime.Now;//制单时间
info.ReimbursementType = ReimbursementTypeEnums.UnderReview;
info.Reimburser = user.UserName;
info.OrgId = user.OrgId;
var data = tenantDb.Updateable(info).ExecuteCommand();
//修改子表信息
foreach (var item in Pinfo)
{
item.Status = ReimbursementTypeEnums.UnderReview;
tenantDb.Updateable(item).ExecuteCommand();
}
#region 增加审批任务
var taskReq = new TaskCreationRequest()
{
BusinessId = info.Id,
TaskTypeName = TaskBaseTypeEnum.ReimbursementApproval.ToString(),
TaskTitle = $"【{TaskBaseTypeEnum.ReimbursementApproval.GetDescription()}】{user.UserName}提交的报销单审核",
TaskDescription = $"【{TaskBaseTypeEnum.ReimbursementApproval.GetDescription()}】共包含发票{Pinfo.Count}张,报销金额{Pinfo.Sum(t => t.Amount)}元",
};
var result = await taskService.CreateTaskAsync(taskReq, false);
if (!result.Succeeded)
{
return await Task.FromResult(DataResult.Failed(result.Message));
}
else
{
return await Task.FromResult(DataResult.Successed(result.Message));
}
#endregion
}
/// <summary>
/// 详情
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public DataResult<GetReimbursementRes> GetReimbursementInfo(string id)
{
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
var data = tenantDb.Queryable<FeeReimbursement>()
.Where(a => a.Id == long.Parse(id))
.Select<GetReimbursementRes>()
.First();
var dtlist= tenantDb.Queryable<FeeReimbursementDetail>().Where(t => t.PId == data.Id).ToList();
data.Data = new List<GetReimbursementResData>();
foreach (var item in dtlist)
{
var dt= tenantDb.Queryable<InInvoice>().Where(t => t.InvoiceNumber == item.InvoiceNumber).Select<GetReimbursementResData>().First();
if (dt != null)
{
data.Data.Add(dt);
}
}
foreach (var itemdata in data.Data)
{
itemdata.Data = new List<InInvoiceDetail>();
itemdata.Data = tenantDb.Queryable<InInvoiceDetail>().Where(t => t.InvoiceNumber == itemdata.InvoiceNumber).ToList();
}
return DataResult<GetReimbursementRes>.Success(data, MultiLanguageConst.DataQuerySuccess);
}
/// <summary>
/// 未审批的报销单撤销
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<DataResult> ReimbursementRevoked(long id)
{
//查询当前报销单
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
var data = tenantDb.Queryable<FeeReimbursement>()
.Where(a => a.Id == id)
.Select<FeeReimbursement>()
.First();
if (data.ReimbursementType == ReimbursementTypeEnums.Approved)
{
return DataResult.Failed("报销单审批已通过,不可撤回!");
}
if (data.ReimbursementType == ReimbursementTypeEnums.Rejected)
{
return DataResult.Failed("报销单已审批,不可撤回!");
}
if (data.ReimbursementType == ReimbursementTypeEnums.Revoked)
{
return DataResult.Failed("报销单已撤销,不可重复撤回!");
}
data.ReimbursementType = ReimbursementTypeEnums.Revoked;
tenantDb.Updateable(data).ExecuteCommand();
var dataDetail = tenantDb.Queryable<FeeReimbursementDetail>()
.Where(a => a.PId == id)
.ToList();
foreach (var item in dataDetail)
{
item.Status = ReimbursementTypeEnums.Revoked;
tenantDb.Updateable(item).ExecuteCommand();
var inviceinfo = tenantDb.Queryable<InInvoice>().Where(t => t.InvoiceNumber == item.InvoiceNumber).First();
inviceinfo.ReimbursementType = ReimbursementTypeEnums.NotSubmitted; //审核撤销,将对应的报销发票设为未审核状态
tenantDb.Updateable(inviceinfo).ExecuteCommand();
}
if (data.ReimbursementType == ReimbursementTypeEnums.UnderReview)
{
#region 撤销钉钉审批任务
#endregion
#region 撤销东胜8工作流的审批任务
//撤销审批任务
var tsreq = new TaskRequest
{
BusinessId = data.Id,
TaskTypeName = TaskBaseTypeEnum.ReimbursementApproval.ToString(),
};
var result = await taskService.WithdrawAsync(tsreq);
if (!result.Succeeded)
{
return await Task.FromResult(DataResult.Failed(result.Message));
}
else
{
return await Task.FromResult(DataResult.Successed(result.Message));
}
#endregion
}
return await Task.FromResult(DataResult.Successed("操作成功"));
}
/// <summary>
/// 根据审批结果更新申请单状态
/// </summary>
/// <param name="callback">回调信息</param>
/// <returns></returns>
public async Task<DataResult> UpdateStatusAsync(FlowCallback callback)
{
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
if (callback.AuditType != TaskBaseTypeEnum.ReimbursementApproval)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.NoAuditItems));
var info = await tenantDb.Queryable<FeeReimbursement>().Where(x => x.Id == callback.BusinessId).FirstAsync();
if (info.IsNull())
return await Task.FromResult(DataResult.Failed("不存在的报销单信息!"));
//审核通过
if (callback.FlowStatus == FlowStatusEnum.Approve)
{
info.ReimbursementType = ReimbursementTypeEnums.Approved;
tenantDb.Updateable(info).ExecuteCommand();
var dtllist = tenantDb.Queryable<FeeReimbursementDetail>().Where(t => t.PId == info.Id).ToList();
foreach (var item in dtllist)
{
item.Status = ReimbursementTypeEnums.Approved;
tenantDb.Updateable(item).ExecuteCommand();
}
}
if (callback.FlowStatus == FlowStatusEnum.Reject)
{
info.ReimbursementType = ReimbursementTypeEnums.Rejected;
info.RejectReason = callback.RejectReason;
tenantDb.Updateable(info).ExecuteCommand();
var dtllist = tenantDb.Queryable<FeeReimbursementDetail>().Where(t => t.PId == info.Id).ToList();
foreach (var item in dtllist)
{
item.Status = ReimbursementTypeEnums.Approved;
item.RejectReason = callback.RejectReason;
tenantDb.Updateable(item).ExecuteCommand();
}
}
return DataResult.Success;
//return rows > 0 ? DataResult.Success : DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
}
/// <summary>
/// 通知审批执行人变更
/// </summary>
/// <param name="callback">回调信息</param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"><paramref name="callback"/>为null时引发</exception>
public virtual async Task MarkerChangedAsync(MarkerChangedCallback callback)
{
//同步到钉钉
}
/// <summary>
/// 报销单审核
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public async Task<DataResult> AuditAsync(ReimbursementAuditRequest request)
{
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
var info = await tenantDb.Queryable<FeeReimbursement>().Where(x =>request.Ids.Contains( x.Id)).ToListAsync();
if (info.IsNull())
return await Task.FromResult(DataResult.Failed("不存在的报销单信息!"));
//修改会计科目
foreach (var item in info)
{
item.LedgerAccount = request.LedgerAccount;
}
db.Updateable(info).ExecuteCommand();
//获取当前审批人信息
var userinfo= db.Queryable<SysUser>().Where(t => t.Id.ToString()== user.UserId).First();
if (!string.IsNullOrWhiteSpace( userinfo.DingUserId))
{
//TODO 窦汉东 同步钉钉当前审批人的审批状态
}
if (await taskService2.Value.HasAuthorizedAsync())
{
return await taskService2.Value.AuditAsync(new TaskAuditRequest
{
Ids = request.Ids,
Remark = request.Remark,
Result = request.Result,
TaskTypeName = TaskBaseTypeEnum.ReimbursementApproval.ToString()
});
}
var list = await flowService.Value.GetInstanceByBSIdAsync(TaskBaseTypeEnum.ReimbursementApproval, ids: request.Ids);
if (list.Count != request.Ids.Length)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.NotInAudit));
foreach (var item in list)
{
var result = await flowService.Value.AuditAsync(new FlowAuditInfo
{
AuditNote = request.Remark,
Status = request.Result,
Instance = item
});
if (!result.Succeeded)
return result;
}
return DataResult.Success;
}
}
}