diff --git a/ds-wms-service/DS.Module.Core/Enums/TaskPlat/TaskBaseTypeEnum.cs b/ds-wms-service/DS.Module.Core/Enums/TaskPlat/TaskBaseTypeEnum.cs index 70de45e7..116dce2c 100644 --- a/ds-wms-service/DS.Module.Core/Enums/TaskPlat/TaskBaseTypeEnum.cs +++ b/ds-wms-service/DS.Module.Core/Enums/TaskPlat/TaskBaseTypeEnum.cs @@ -489,10 +489,16 @@ namespace DS.Module.Core #region 报销审核 /// - /// 工作流报销审核 + /// 报销单审核 /// - [Description("工作流报销审核")] - ReimbursementApproval =1101 + [Description("报销单审核")] + ReimbursementApproval =1101, + + /// + /// 报销单审核 + /// + [Description("报销单审核")] + Reimbursement_REJECTED = -1101 #endregion } diff --git a/ds-wms-service/DS.WMS.Core/Fee/Entity/FeeReimbursement.cs b/ds-wms-service/DS.WMS.Core/Fee/Entity/FeeReimbursement.cs index 4583422c..7983de1a 100644 --- a/ds-wms-service/DS.WMS.Core/Fee/Entity/FeeReimbursement.cs +++ b/ds-wms-service/DS.WMS.Core/Fee/Entity/FeeReimbursement.cs @@ -13,7 +13,7 @@ namespace DS.WMS.Core.Fee.Entity /// 报销单 /// [SugarTable("fee_reimbursement", TableDescription = "报销单主表")] - public class Reimbursement : BaseModel + public class FeeReimbursement : BaseModel { /// /// 报销用户Id @@ -40,6 +40,11 @@ namespace DS.WMS.Core.Fee.Entity /// public ReimbursementTypeEnums Status { get; set; } + /// + /// 驳回理由 + /// + public string RejectReason { get; set; } + /// /// 部门 /// diff --git a/ds-wms-service/DS.WMS.Core/Fee/Entity/FeeReimbursementDetail.cs b/ds-wms-service/DS.WMS.Core/Fee/Entity/FeeReimbursementDetail.cs index b95a1a58..f666b081 100644 --- a/ds-wms-service/DS.WMS.Core/Fee/Entity/FeeReimbursementDetail.cs +++ b/ds-wms-service/DS.WMS.Core/Fee/Entity/FeeReimbursementDetail.cs @@ -13,7 +13,7 @@ namespace DS.WMS.Core.Fee.Entity /// /// 报销单详情 /// - [SugarTable("fee_reimbursementDetail", TableDescription = "报销单详情表")] + [SugarTable("fee_reimbursement_detail", TableDescription = "报销单详情表")] public class FeeReimbursementDetail : BaseModel { @@ -39,8 +39,13 @@ namespace DS.WMS.Core.Fee.Entity /// - /// 状态(未提交,审核中,审核通过,审核驳回,撤销) //与主表同步 + /// 状态(未提交,审核中,审核通过,审核驳回,撤销) 与主表 /// public ReimbursementTypeEnums Status { get; set; } + + /// + /// 驳回理由 (与主表同步) + /// + public string RejectReason { get; set; } } } diff --git a/ds-wms-service/DS.WMS.Core/Fee/Entity/InInvoice.cs b/ds-wms-service/DS.WMS.Core/Fee/Entity/InInvoice.cs index 72fc2b68..c4b91488 100644 --- a/ds-wms-service/DS.WMS.Core/Fee/Entity/InInvoice.cs +++ b/ds-wms-service/DS.WMS.Core/Fee/Entity/InInvoice.cs @@ -1,4 +1,5 @@ using DS.Module.Core.Data; +using DS.Module.Core.Enums; using SqlSugar; namespace DS.WMS.Core.Fee.Entity @@ -163,7 +164,7 @@ namespace DS.WMS.Core.Fee.Entity /// /// 报销状态 bxzt /// - public string? ReimbursementStatus { get; set; } + public ReimbursementTypeEnums ReimbursementType { get; set; } /// /// 购方银行账号 gfyhzh diff --git a/ds-wms-service/DS.WMS.Core/Fee/Interface/IReimbursementService.cs b/ds-wms-service/DS.WMS.Core/Fee/Interface/IReimbursementService.cs index 538ace34..c29028d8 100644 --- a/ds-wms-service/DS.WMS.Core/Fee/Interface/IReimbursementService.cs +++ b/ds-wms-service/DS.WMS.Core/Fee/Interface/IReimbursementService.cs @@ -1,8 +1,12 @@ using DS.Module.Core; using DS.WMS.Core.Fee.Dtos; +using DS.WMS.Core.Flow.Dtos; namespace DS.WMS.Core.Fee.Interface { + /// + /// 报销模块 + /// public interface IReimbursementService { @@ -19,7 +23,7 @@ namespace DS.WMS.Core.Fee.Interface /// /// /// - DataResult AddReimbursement(ReimbursementReq model); + Task< DataResult> AddReimbursement(ReimbursementReq model); /// /// 获取详情 @@ -33,20 +37,29 @@ namespace DS.WMS.Core.Fee.Interface /// /// /// - DataResult ReimbursementRevoked(string id); + Task< DataResult> ReimbursementRevoked(string id); + + /// + /// 根据审批结果更新审批状态 + /// + ///回调信息 + /// + Task UpdateStatusAsync(FlowCallback callback); /// - /// 报销单审批通过 + /// 通知审批执行人变更 /// - /// + /// 回调信息 /// - DataResult ReimbursementApproved(string id); + Task MarkerChangedAsync(MarkerChangedCallback callback); + /// - /// 报销单审批驳回 + /// 报销单审核 /// - /// + /// /// - DataResult ReimbursementRejected(string id); + Task AuditAsync(AuditRequest request); + } } diff --git a/ds-wms-service/DS.WMS.Core/Fee/Method/FeeReimbursementService.cs b/ds-wms-service/DS.WMS.Core/Fee/Method/FeeReimbursementService.cs index ccc8b6db..e653cf1a 100644 --- a/ds-wms-service/DS.WMS.Core/Fee/Method/FeeReimbursementService.cs +++ b/ds-wms-service/DS.WMS.Core/Fee/Method/FeeReimbursementService.cs @@ -1,8 +1,4 @@ -using AngleSharp.Dom; -using AngleSharp.Svg.Dom; -using Autofac.Core; -using DS.Module.Core; -using DS.Module.Core.Data; +using DS.Module.Core; using DS.Module.Core.Enums; using DS.Module.Core.Extensions; using DS.Module.SqlSugar; @@ -11,12 +7,11 @@ 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.Entity; -using DS.WMS.Core.Invoice.Dtos; +using DS.WMS.Core.Flow.Interface; using DS.WMS.Core.TaskInteraction.Dtos; -using DS.WMS.Core.TaskInteraction.Method; -using LanguageExt.Common; +using DS.WMS.Core.TaskInteraction.Interface; using Mapster; +using Masuit.Tools.Systems; using Microsoft.Extensions.DependencyInjection; using SqlSugar; @@ -33,7 +28,9 @@ namespace DS.WMS.Core.Fee.Method private readonly ISaasDbService saasService; private readonly ISqlSugarClient db; private readonly IUser user; - + readonly ITaskService taskService; + Lazy taskService2; + Lazy flowService; /// /// @@ -45,6 +42,9 @@ namespace DS.WMS.Core.Fee.Method saasService = _serviceProvider.GetRequiredService(); db = _serviceProvider.GetRequiredService(); user = _serviceProvider.GetRequiredService(); + taskService = serviceProvider.GetRequiredService(); + taskService2 = new Lazy(serviceProvider.GetRequiredService()); + flowService = new Lazy(serviceProvider.GetRequiredService()); } /// @@ -58,7 +58,7 @@ namespace DS.WMS.Core.Fee.Method var whereList = db.ConfigQuery.Context.Utilities.JsonToConditionalModels(request.QueryCondition); var tenantDb = saasService.GetBizDbScopeById(user.TenantId); - var data = tenantDb.Queryable() + var data = tenantDb.Queryable() .Where(whereList) .Select().ToQueryPage(request.PageCondition); return data; @@ -68,7 +68,7 @@ namespace DS.WMS.Core.Fee.Method /// /// /// - public DataResult AddReimbursement(ReimbursementReq req) + public async Task AddReimbursement(ReimbursementReq req) { var tenantDb = saasService.GetBizDbScopeById(user.TenantId); @@ -83,38 +83,59 @@ namespace DS.WMS.Core.Fee.Method } //发票报销状态 校验 待完善 - //if (inviceinfo.ReimbursementType == (int)ReimbursementTypeEnums.UnderReview) //报销中 - //{ - // return DataResult.Failed($"提交失败,发票号{item.InvoiceNumber}正在报销,请检查"); - //} - //if (inviceinfo.ReimbursementType == (int)ReimbursementTypeEnums.Approved) //已报销 - //{ - // 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(); + + var data = req.Adapt(); data.UserId = user.UserId; + data.ReimbursementId = "23"; //报销单编号. var info = tenantDb.Insertable(data).ExecuteReturnEntity(); //添加子表信息 foreach (var item in req.Data) { - var dataDetail = req.Adapt(); + var dataDetail = item.Adapt(); dataDetail.Status = ReimbursementTypeEnums.NotSubmitted; dataDetail.PId = info.Id; + tenantDb.Insertable(dataDetail).ExecuteReturnEntity(); - + + } + + + #region 增加审批任务 + var taskReq = new TaskCreationRequest() + { + BusinessId = info.Id, + + TaskTypeName = TaskBaseTypeEnum.ReimbursementApproval.ToString(), + TaskTitle = $"【{TaskBaseTypeEnum.ReimbursementApproval.GetDescription()}】{user.UserName}提交的报销单审核", + TaskDescription = $"【{TaskBaseTypeEnum.ReimbursementApproval.GetDescription()}】共包含发票{req.Data.Count()}张,报销金额{req.Data.Sum(t=>t.Amount)}元", + }; + var result = await taskService.CreateTaskAsync(taskReq, false); + if (!result.Succeeded) + { + return await Task.FromResult(DataResult.Failed(result.Message)); } + else + { - var entity = tenantDb.Insertable(data).ExecuteReturnEntity(); - + return await Task.FromResult(DataResult.Successed(result.Message)); - return DataResult.Successed("添加成功!"); + } + + #endregion } /// @@ -125,11 +146,11 @@ namespace DS.WMS.Core.Fee.Method public DataResult GetReimbursementInfo(string id) { var tenantDb = saasService.GetBizDbScopeById(user.TenantId); - var data = tenantDb.Queryable() + var data = tenantDb.Queryable() .Where(a => a.Id == long.Parse(id)) .Select() .First(); - + return DataResult.Success(data, MultiLanguageConst.DataQuerySuccess); } @@ -140,13 +161,13 @@ namespace DS.WMS.Core.Fee.Method /// /// /// - public DataResult ReimbursementRevoked(string id) + public async Task ReimbursementRevoked(string id) { //查询当前报销单 var tenantDb = saasService.GetBizDbScopeById(user.TenantId); - var data = tenantDb.Queryable() + var data = tenantDb.Queryable() .Where(a => a.Id == long.Parse(id)) - .Select() + .Select() .First(); if (data.Status != ReimbursementTypeEnums.NotSubmitted) @@ -159,79 +180,140 @@ namespace DS.WMS.Core.Fee.Method var dataDetail = tenantDb.Queryable() .Where(a => a.PId == long.Parse(id)) - .Select() + .Select() .ToList(); foreach (var item in dataDetail) { - item.Status= ReimbursementTypeEnums.Revoked; + item.Status = ReimbursementTypeEnums.Revoked; db.Updateable(item).ExecuteCommand(); } - - return DataResult.Success; + + //撤销审批任务 + 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)); + + } + + } + + /// - /// 审批通过 + /// 根据审批结果更新申请单状态 /// - /// + /// 回调信息 /// - public DataResult ReimbursementApproved(string id) + public async Task UpdateStatusAsync(FlowCallback callback) { - //查询当前报销单 var tenantDb = saasService.GetBizDbScopeById(user.TenantId); - var data = tenantDb.Queryable() - .Where(a => a.Id == long.Parse(id)) - .Select() - .First(); - - data.Status = ReimbursementTypeEnums.Approved; - db.Updateable(data).ExecuteCommand(); + 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) + { - var dataDetail = tenantDb.Queryable() - .Where(a => a.PId == long.Parse(id)) - .Select() - .ToList(); - foreach (var item in dataDetail) + info.Status = 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) { - item.Status = ReimbursementTypeEnums.Approved; - db.Updateable(item).ExecuteCommand(); + info.Status = 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)); } + /// - /// 审批驳回 + /// 通知审批执行人变更 /// - /// + /// 回调信息 /// - public DataResult ReimbursementRejected(string id) + /// 为null时引发 + public virtual async Task MarkerChangedAsync(MarkerChangedCallback callback) { - //查询当前报销单 - var tenantDb = saasService.GetBizDbScopeById(user.TenantId); - var data = tenantDb.Queryable() - .Where(a => a.Id == long.Parse(id)) - .Select() - .First(); + //同步到钉钉 + } + /// + /// 报销单审核 + /// + /// + /// + public async Task AuditAsync(AuditRequest request) + { + 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() + }); + } - data.Status = ReimbursementTypeEnums.Rejected; - db.Updateable(data).ExecuteCommand(); + var list = await flowService.Value.GetInstanceByBSIdAsync(TaskBaseTypeEnum.ReimbursementApproval, ids: request.Ids); + if (list.Count != request.Ids.Length) + return DataResult.FailedWithDesc(nameof(MultiLanguageConst.NotInAudit)); - var dataDetail = tenantDb.Queryable() - .Where(a => a.PId == long.Parse(id)) - .Select() - .ToList(); - foreach (var item in dataDetail) + foreach (var item in list) { - item.Status = ReimbursementTypeEnums.Rejected; - db.Updateable(item).ExecuteCommand(); + var result = await flowService.Value.AuditAsync(new FlowAuditInfo + { + AuditNote = request.Remark, + Status = request.Result, + Instance = item + }); + + if (!result.Succeeded) + return result; } return DataResult.Success; - } + } + } } diff --git a/ds-wms-service/DS.WMS.Core/QuarztJobs/Method/InInvoiceService.cs b/ds-wms-service/DS.WMS.Core/QuarztJobs/Method/InInvoiceService.cs index cc033bf6..6f718f18 100644 --- a/ds-wms-service/DS.WMS.Core/QuarztJobs/Method/InInvoiceService.cs +++ b/ds-wms-service/DS.WMS.Core/QuarztJobs/Method/InInvoiceService.cs @@ -1,4 +1,5 @@ -using DS.WMS.Core.Fee.Entity; +using DS.Module.Core.Enums; +using DS.WMS.Core.Fee.Entity; using DS.WMS.Core.QuarztJobs.Dtos; using DS.WMS.Core.QuarztJobs.Interface; using DS.WMS.Core.QuarztJobs.Other; @@ -113,7 +114,7 @@ namespace DS.WMS.Core.QuarztJobs.Method inInvoice.Amount = Iinfo.data.je; inInvoice.SellerName = Iinfo.data.xfmc; inInvoice.SpecialElements = Iinfo.data.tdys; - inInvoice.ReimbursementStatus = Iinfo.data.bxzt; + inInvoice.ReimbursementType = ReimbursementTypeEnums.NotSubmitted; inInvoice.BuyerBankAccountNumber = Iinfo.data.gfyhzh; inInvoice.SpecialElementTypeCode = Iinfo.data.tdyslxDm; inInvoice.OperatorCode = Iinfo.data.czydm; diff --git a/ds-wms-service/DS.WMS.FeeApi/Controllers/ReimbursementController.cs b/ds-wms-service/DS.WMS.FeeApi/Controllers/ReimbursementController.cs index 0f5ff96d..cb9a65d1 100644 --- a/ds-wms-service/DS.WMS.FeeApi/Controllers/ReimbursementController.cs +++ b/ds-wms-service/DS.WMS.FeeApi/Controllers/ReimbursementController.cs @@ -1,7 +1,12 @@ using DS.Module.Core; using DS.WMS.Core.Fee.Dtos; using DS.WMS.Core.Fee.Interface; +using DS.WMS.Core.Flow.Dtos; +using DS.WMS.Core.TaskPlat.Dtos; using Microsoft.AspNetCore.Mvc; +using Newtonsoft.Json; +using NLog; +using System.Net; namespace DS.WMS.FeeApi.Controllers { @@ -11,7 +16,7 @@ namespace DS.WMS.FeeApi.Controllers public class ReimbursementController : ApiController { readonly IReimbursementService _service; - + private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); /// /// 初始化 /// @@ -21,13 +26,31 @@ namespace DS.WMS.FeeApi.Controllers _service = service; } - //1获取当前登录人收款信息 - // ClientBank/GetClientBankList - - //2获取发票列表 - // feeApi/InInvoicet/GetInInvoicet + /// + /// 获取报销单列表列表 + /// + /// + /// + [HttpPost] + [Route("GetReimbursementList")] + public DataResult> GetReimbursementList([FromBody] PageRequest request) + { + var res = _service.GetListByPage(request); + return res; + } - //3新增报销单,并同步到钉钉 + /// + /// 获取报销单详情 + /// + /// + /// + [HttpGet] + [Route("GetReimbursementInfo")] + public DataResult GetReimbursementInfo([FromQuery] string id) + { + var res = _service.GetReimbursementInfo(id); + return res; + } /// /// 新增 @@ -36,14 +59,12 @@ namespace DS.WMS.FeeApi.Controllers /// [HttpPost] [Route("AddReimbursement")] - public DataResult AddReimbursement([FromBody] ReimbursementReq req) + public async Task AddReimbursement([FromBody] ReimbursementReq req) { - var res = _service.AddReimbursement(req); + var res =await _service.AddReimbursement(req); return res; } - - //4未审批的报销单撤销 - + /// /// 未审批的报销单撤销 /// @@ -51,48 +72,51 @@ namespace DS.WMS.FeeApi.Controllers /// [HttpPost] [Route("ReimbursementRevoked")] - public DataResult ReimbursementRevoked([FromBody] string id) + public async Task ReimbursementRevoked([FromBody] string id) { - var res = _service.ReimbursementRevoked(id); + var res = await _service.ReimbursementRevoked(id); return res; } - - //5报销单审核通过 - - - - //6报销单审核驳回 - - - //7获取报销单列表 - + /// - /// 列表 + /// 按报销单审核 /// /// /// - [HttpPost] - [Route("GetReimbursementList")] - public DataResult> GetReimbursementList([FromBody] PageRequest request) + [HttpPost, Route("Audit")] + public async Task AuditAsync([FromBody] AuditRequest request) { - var res = _service.GetListByPage(request); - return res; + if (request.Ids.Length == 0 || (request.Result != 1 && request.Result != 2)) + return DataResult.Failed("参数无效", MultiLanguageConst.IllegalRequest); + return await _service.AuditAsync(request); } - - //8获取报销单详情 + /// + /// 回调变更申请单审批状态(用于工作流框架的回调) + /// + /// 回调信息 + /// + [HttpPost, Route("ChangeStatus")] + public async Task ChangeStatusAsync([FromBody] FlowCallback callback) + { + var str = JsonConvert.SerializeObject(callback); + _logger.Info($"变更申请单审批状态回调,请求参数为:{str};"); + await _service.UpdateStatusAsync(callback); + return StatusCode((int)HttpStatusCode.NoContent); + } /// - /// 详情 + /// 回调通知审批执行人变更(无需客户端手动调用) /// - /// + /// 回调信息 /// - [HttpGet] - [Route("GetReimbursementInfo")] - public DataResult GetReimbursementInfo([FromQuery] string id) + [HttpPost, Route("MarkerChanged")] + public async Task MarkerChangedAsync([FromBody] MarkerChangedCallback callback) { - var res = _service.GetReimbursementInfo(id); - return res; + var str = JsonConvert.SerializeObject(callback); + _logger.Info($"通知审批执行人变更回调,请求参数为:{str};"); + await _service.MarkerChangedAsync(callback); + return StatusCode((int)HttpStatusCode.NoContent); } //9财务银企直连付款接口 @@ -103,8 +127,5 @@ namespace DS.WMS.FeeApi.Controllers //11钉钉配置相关接口 - - - } }