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 { /// /// 报销单相关 /// public class FeeReimbursementService : IReimbursementService { private readonly IServiceProvider _serviceProvider; private readonly ISaasDbService saasService; private readonly ISqlSugarClient db; private readonly IUser user; readonly IAuditTaskService taskService; Lazy taskService2; Lazy flowService; private readonly ICommonService commonService; /// /// /// /// public FeeReimbursementService(IServiceProvider serviceProvider, ICommonService commonService) { _serviceProvider = serviceProvider; saasService = _serviceProvider.GetRequiredService(); db = _serviceProvider.GetRequiredService(); user = _serviceProvider.GetRequiredService(); taskService = serviceProvider.GetRequiredService(); taskService2 = new Lazy(serviceProvider.GetRequiredService()); flowService = new Lazy(serviceProvider.GetRequiredService()); this.commonService = commonService; } /// /// 列表 /// /// /// public DataResult> GetListByPage(PageRequest request) { //序列化查询条件 var whereList = db.ConfigQuery.Context.Utilities.JsonToConditionalModels(request.QueryCondition); var tenantDb = saasService.GetBizDbScopeById(user.TenantId); var data = tenantDb.Queryable() .Where(whereList) .Select().ToQueryPage(request.PageCondition); return data; } /// /// 新增报销申请 /// /// /// public async Task AddReimbursement(ReimbursementReq req) { var tenantDb = saasService.GetBizDbScopeById(user.TenantId); //修改 if (req.Id>0) { var FeeR = tenantDb.Queryable().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(); 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().Where(t => t.PId == req.Id).ToList(); foreach (var item in datadtl) { var ininfo = tenantDb.Queryable().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().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(); dataDetail.Status = ReimbursementTypeEnums.NotSubmitted; dataDetail.PId = req.Id; tenantDb.Insertable(dataDetail).ExecuteCommand(); } } //新增 else { #region 提交报销数据校验 foreach (var item in req.Data) { //查询发票信息是否存在 var inviceinfo = tenantDb.Queryable().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(); 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().Where(t => t.InvoiceNumber == item.InvoiceNumber).First(); var dataDetail = item.Adapt(); 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("操作成功")); } /// /// 提交报销单审核 /// /// /// public async Task SubmitReimbursement(SubmitReimbursementReq req) { var tenantDb = saasService.GetBizDbScopeById(user.TenantId); var info= tenantDb.Queryable().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().Where(t => t.PId == req.Id).ToList(); #region 提交报销数据校验 foreach (var item in Pinfo) { //查询发票信息是否存在 var inviceinfo = tenantDb.Queryable().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 sequence = commonService.GetSequenceNext(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 } /// /// 详情 /// /// /// public DataResult GetReimbursementInfo(string id) { var tenantDb = saasService.GetBizDbScopeById(user.TenantId); var data = tenantDb.Queryable() .Where(a => a.Id == long.Parse(id)) .Select() .First(); var dtlist= tenantDb.Queryable().Where(t => t.PId == data.Id).ToList(); data.Data = new List(); foreach (var item in dtlist) { var dt= tenantDb.Queryable().Where(t => t.InvoiceNumber == item.InvoiceNumber).Select().First(); if (dt != null) { data.Data.Add(dt); } } foreach (var itemdata in data.Data) { itemdata.Data = new List(); itemdata.Data = tenantDb.Queryable().Where(t => t.InvoiceNumber == itemdata.InvoiceNumber).ToList(); } return DataResult.Success(data, MultiLanguageConst.DataQuerySuccess); } /// /// 未审批的报销单撤销 /// /// /// public async Task ReimbursementRevoked(long id) { //查询当前报销单 var tenantDb = saasService.GetBizDbScopeById(user.TenantId); var data = tenantDb.Queryable() .Where(a => a.Id == id) .Select() .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() .Where(a => a.PId == id) .ToList(); foreach (var item in dataDetail) { item.Status = ReimbursementTypeEnums.Revoked; tenantDb.Updateable(item).ExecuteCommand(); var inviceinfo = tenantDb.Queryable().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("操作成功")); } /// /// 根据审批结果更新申请单状态 /// /// 回调信息 /// public async Task 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().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().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().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)); } /// /// 通知审批执行人变更 /// /// 回调信息 /// /// 为null时引发 public virtual async Task MarkerChangedAsync(MarkerChangedCallback callback) { //同步到钉钉 } /// /// 报销单审核 /// /// /// public async Task AuditAsync(ReimbursementAuditRequest request) { var tenantDb = saasService.GetBizDbScopeById(user.TenantId); var info = await tenantDb.Queryable().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().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; } } }