jianghaiqing 4 weeks ago
commit a0cf2c9c8d

@ -1554,6 +1554,12 @@ public static class MultiLanguageConst
public const string TaskMailSenderNotNull = "Task_Mail_Sender_Not_Null";
[Description("驳回成功")]
public const string TaskRejected = "Task_Rejected";
[Description("未传入子任务信息")]
public const string SubTaskCannotNull = "Sub_Task_Cannot_Null";
[Description("同一任务的步骤类型不可重复")]
public const string DuplicateStepType = "Duplicate_Step_Type";
[Description("此任务尚有未完成的子任务或前置条件")]
public const string UnfinishedItems = "Unfinished_Items";
#endregion
#region 任务台相关

@ -489,10 +489,16 @@ namespace DS.Module.Core
#region 报销审核
/// <summary>
/// 工作流报销审核
/// 报销审核
/// </summary>
[Description("工作流报销审核")]
ReimbursementApproval =1101
[Description("报销单审核")]
ReimbursementApproval =1101,
/// <summary>
/// 报销单审核
/// </summary>
[Description("报销单审核")]
Reimbursement_REJECTED = -1101
#endregion
}

@ -101,7 +101,9 @@ namespace DS.WMS.Core.Fee.Dtos.Report
/// <summary>
/// 开船日期
/// </summary>
public DateTime? ETD { get; set; }
public string? ETD => ETDValue.HasValue ? ETDValue.Value.ToString("yyyy-MM-dd") : string.Empty;
public DateTime? ETDValue { get; set; }
///// <summary>
///// 预抵日期
@ -219,14 +221,14 @@ namespace DS.WMS.Core.Fee.Dtos.Report
public string StlName { get; set; }
/// <summary>
/// 件数
/// 包装
/// </summary>
public int? PKGS { get; set; }
public string? KindPkgsName { get; set; }
/// <summary>
/// 包装
/// 件数
/// </summary>
public string? KindPkgs { get; set; }
public int? PKGS { get; set; }
/// <summary>
/// 毛重
@ -293,6 +295,29 @@ namespace DS.WMS.Core.Fee.Dtos.Report
/// </summary>
public int ECCU { get; set; }
/// <summary>
/// 船公司
/// </summary>
public string? Carrier { get; set; }
/// <summary>
/// 船名
/// </summary>
public string? Vessel { get; set; }
/// <summary>
/// 航次
/// </summary>
public string? Voyno { get; set; }
/// <summary>
/// 内部航次
/// </summary>
public string? InnerVoyno { get; set; }
/// <summary>
/// 费用统计
/// </summary>
public FeeAuditStatistics Statistics { get; set; }
}

@ -13,7 +13,7 @@ namespace DS.WMS.Core.Fee.Entity
/// 报销单
/// </summary>
[SugarTable("fee_reimbursement", TableDescription = "报销单主表")]
public class Reimbursement : BaseModel<long>
public class FeeReimbursement : BaseModel<long>
{
/// <summary>
/// 报销用户Id
@ -40,6 +40,11 @@ namespace DS.WMS.Core.Fee.Entity
/// </summary>
public ReimbursementTypeEnums Status { get; set; }
/// <summary>
/// 驳回理由
/// </summary>
public string RejectReason { get; set; }
/// <summary>
/// 部门
/// </summary>

@ -13,7 +13,7 @@ namespace DS.WMS.Core.Fee.Entity
/// <summary>
/// 报销单详情
/// </summary>
[SugarTable("fee_reimbursementDetail", TableDescription = "报销单详情表")]
[SugarTable("fee_reimbursement_detail", TableDescription = "报销单详情表")]
public class FeeReimbursementDetail : BaseModel<long>
{
@ -39,8 +39,13 @@ namespace DS.WMS.Core.Fee.Entity
/// <summary>
/// 状态(未提交,审核中,审核通过,审核驳回,撤销) //与主表同步
/// 状态(未提交,审核中,审核通过,审核驳回,撤销) 与主表
/// </summary>
public ReimbursementTypeEnums Status { get; set; }
/// <summary>
/// 驳回理由 (与主表同步)
/// </summary>
public string RejectReason { get; set; }
}
}

@ -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
/// <summary>
/// 报销状态 bxzt
/// </summary>
public string? ReimbursementStatus { get; set; }
public ReimbursementTypeEnums ReimbursementType { get; set; }
/// <summary>
/// 购方银行账号 gfyhzh

@ -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
{
/// <summary>
/// 报销模块
/// </summary>
public interface IReimbursementService
{
@ -19,7 +23,7 @@ namespace DS.WMS.Core.Fee.Interface
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
DataResult AddReimbursement(ReimbursementReq model);
Task< DataResult> AddReimbursement(ReimbursementReq model);
/// <summary>
/// 获取详情
@ -33,20 +37,29 @@ namespace DS.WMS.Core.Fee.Interface
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
DataResult ReimbursementRevoked(string id);
Task< DataResult> ReimbursementRevoked(string id);
/// <summary>
/// 根据审批结果更新审批状态
/// </summary>
///<param name="callback">回调信息</param>
/// <returns></returns>
Task<DataResult> UpdateStatusAsync(FlowCallback callback);
/// <summary>
/// 报销单审批通过
/// 通知审批执行人变更
/// </summary>
/// <param name="id"></param>
/// <param name="callback">回调信息</param>
/// <returns></returns>
DataResult ReimbursementApproved(string id);
Task MarkerChangedAsync(MarkerChangedCallback callback);
/// <summary>
/// 报销单审批驳回
/// 报销单审
/// </summary>
/// <param name="id"></param>
/// <param name="request"></param>
/// <returns></returns>
DataResult ReimbursementRejected(string id);
Task<DataResult> AuditAsync(AuditRequest request);
}
}

@ -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<ITaskService> taskService2;
Lazy<IClientFlowInstanceService> flowService;
/// <summary>
///
@ -45,6 +42,9 @@ namespace DS.WMS.Core.Fee.Method
saasService = _serviceProvider.GetRequiredService<ISaasDbService>();
db = _serviceProvider.GetRequiredService<ISqlSugarClient>();
user = _serviceProvider.GetRequiredService<IUser>();
taskService = serviceProvider.GetRequiredService<ITaskService>();
taskService2 = new Lazy<ITaskService>(serviceProvider.GetRequiredService<ITaskService>());
flowService = new Lazy<IClientFlowInstanceService>(serviceProvider.GetRequiredService<IClientFlowInstanceService>());
}
/// <summary>
@ -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<Reimbursement>()
var data = tenantDb.Queryable<FeeReimbursement>()
.Where(whereList)
.Select<ReimbursementRes>().ToQueryPage(request.PageCondition);
return data;
@ -68,7 +68,7 @@ namespace DS.WMS.Core.Fee.Method
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
public DataResult AddReimbursement(ReimbursementReq req)
public async Task<DataResult> 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<Reimbursement>();
var data = req.Adapt<FeeReimbursement>();
data.UserId = user.UserId;
data.ReimbursementId = "23"; //报销单编号.
var info = tenantDb.Insertable(data).ExecuteReturnEntity();
//添加子表信息
foreach (var item in req.Data)
{
var dataDetail = req.Adapt<FeeReimbursementDetail>();
var dataDetail = item.Adapt<FeeReimbursementDetail>();
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
}
/// <summary>
@ -125,11 +146,11 @@ namespace DS.WMS.Core.Fee.Method
public DataResult<ReimbursementRes> GetReimbursementInfo(string id)
{
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
var data = tenantDb.Queryable<Reimbursement>()
var data = tenantDb.Queryable<FeeReimbursement>()
.Where(a => a.Id == long.Parse(id))
.Select<ReimbursementRes>()
.First();
return DataResult<ReimbursementRes>.Success(data, MultiLanguageConst.DataQuerySuccess);
}
@ -140,13 +161,13 @@ namespace DS.WMS.Core.Fee.Method
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public DataResult ReimbursementRevoked(string id)
public async Task<DataResult> ReimbursementRevoked(string id)
{
//查询当前报销单
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
var data = tenantDb.Queryable<Reimbursement>()
var data = tenantDb.Queryable<FeeReimbursement>()
.Where(a => a.Id == long.Parse(id))
.Select<Reimbursement>()
.Select<FeeReimbursement>()
.First();
if (data.Status != ReimbursementTypeEnums.NotSubmitted)
@ -159,79 +180,140 @@ namespace DS.WMS.Core.Fee.Method
var dataDetail = tenantDb.Queryable<FeeReimbursementDetail>()
.Where(a => a.PId == long.Parse(id))
.Select<Reimbursement>()
.Select<FeeReimbursement>()
.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));
}
}
/// <summary>
/// 审批通过
/// 根据审批结果更新申请单状态
/// </summary>
/// <param name="id"></param>
/// <param name="callback">回调信息</param>
/// <returns></returns>
public DataResult ReimbursementApproved(string id)
public async Task<DataResult> UpdateStatusAsync(FlowCallback callback)
{
//查询当前报销单
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
var data = tenantDb.Queryable<Reimbursement>()
.Where(a => a.Id == long.Parse(id))
.Select<Reimbursement>()
.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<FeeReimbursement>().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<FeeReimbursementDetail>()
.Where(a => a.PId == long.Parse(id))
.Select<Reimbursement>()
.ToList();
foreach (var item in dataDetail)
info.Status = 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)
{
item.Status = ReimbursementTypeEnums.Approved;
db.Updateable(item).ExecuteCommand();
info.Status = 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="id"></param>
/// <param name="callback">回调信息</param>
/// <returns></returns>
public DataResult ReimbursementRejected(string id)
/// <exception cref="ArgumentNullException"><paramref name="callback"/>为null时引发</exception>
public virtual async Task MarkerChangedAsync(MarkerChangedCallback callback)
{
//查询当前报销单
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
var data = tenantDb.Queryable<Reimbursement>()
.Where(a => a.Id == long.Parse(id))
.Select<Reimbursement>()
.First();
//同步到钉钉
}
/// <summary>
/// 报销单审核
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public async Task<DataResult> 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<FeeReimbursementDetail>()
.Where(a => a.PId == long.Parse(id))
.Select<Reimbursement>()
.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;
}
}
}
}

@ -7,6 +7,7 @@ using DS.WMS.Core.Info.Entity;
using DS.WMS.Core.Op.Entity;
using DS.WMS.Core.TaskInteraction.Dtos;
using Masuit.Tools.Systems;
using SqlSugar;
namespace DS.WMS.Core.Fee.Method.ReportProviders
{
@ -28,6 +29,7 @@ namespace DS.WMS.Core.Fee.Method.ReportProviders
.Select((s, c) => new ProfitAccounting
{
CustomerCode = c.CodeName,
ETDValue = s.ETD,
Sale = s.Sale,
Operator = s.OperatorName,
CustomerService = s.CustomerServiceName,

@ -262,11 +262,15 @@ public class FlowRuntime
{
var scalar = sugarClient.Ado.GetScalar(conditionNode.SQLText,
new SugarParameter($"@{nameof(BaseModel<long>.Id)}", BusinessId));
//符合条件 走下级节点
if (scalar.ObjToInt() > 0 || scalar.ObjToBool())
{
conditionId = conditionNode.Id;
break;
//break;
}
else {
conditionId = conditionNode.Pid;
}
}
else
@ -357,7 +361,14 @@ public class FlowRuntime
if (nextChild.Type == FlowChild.Exclusive)
{
var childId = GetNextConditionNodeId(nextChild);
return ChildNodes.Where(x => x.Id == childId).First(); //下一个节点
if (childId == null) {
childId = "end";
return ChildNodes.Where(x => x.Id == childId).First(); //下一个节点
}
else
{
return ChildNodes.Where(x => x.Id == childId).First(); //下一个节点
}
}
//todo:前端组织JSON结构有误加入临时修复代码待前端改正后移除
else if (nextChild.Type == null)

@ -1538,4 +1538,12 @@ public class SeaExportRes
/// </summary>
[Description("货好时间")]
public Nullable<DateTime> GoodsCompleteTime { get; set; }
/// <summary>
/// 报价
/// </summary>
public int? QuotePrice { get; set; }
/// <summary>
/// 底价
/// </summary>
public int? FloorPrice { get; set; }
}

@ -298,6 +298,16 @@ namespace DS.WMS.Core.Op.Method
if (list.Count > 0)
await tenantDb.Insertable(list).ExecuteCommandAsync();
}
//更新主表货运跟踪
var statusLogs = await tenantDb.Queryable<BookingStatusLog>().Where(x => x.BusinessId == req.Id).ToListAsync();
if (statusLogs.IsNotNull() && statusLogs.Count > 0)
{
foreach (var item in statusLogs)
{
item.BusinessId = newKey;
}
await tenantDb.Updateable(statusLogs).ExecuteCommandAsync();
}
//任务交互表
var taskList = await tenantDb.Queryable<BusinessTask>().Where(x => x.BusinessId == req.Id).ToListAsync();
if (taskList.IsNotNull() && taskList.Count > 0)

@ -113,6 +113,7 @@ public partial class SeaExportService : ISeaExportService
var whereList = db.ConfigQuery.Context.Utilities.JsonToConditionalModels(request.QueryCondition);
//var result = tenantDb.Queryable<SeaExport>()
var statusList = tenantDb.Queryable<BookingStatus>().Select<BookingStatusRes>().ToList();
var ctnPrices = tenantDb.Queryable<BusinessCtnPrice>().ToList();
var result = query.Where(a => (a.IsRefund == false && a.IsChangeETD == false))
.InnerJoin<BusinessFeeStatus>((a, b) => a.Id == b.BusinessId)
//.LeftJoin<SysOrg>((a, b, c) => a.SaleOrgId == c.Id, "shippingweb8_dev.sys_org")
@ -120,6 +121,12 @@ public partial class SeaExportService : ISeaExportService
.Select((a, b) => new SeaExportRes()
{
//SaleDeptName = c.OrgName,
QuotePrice = SqlFunc.Subqueryable<BusinessCtnPrice>()
.Where(s => s.BusinessId == a.Id)
.Select(s => s.QuotePrice),
FloorPrice = SqlFunc.Subqueryable<BusinessCtnPrice>()
.Where(s => s.BusinessId == a.Id)
.Select(s => s.FloorPrice)
},
true)//true表示 其余字段自动映射,根据字段名字
//.Select<SeaExportRes>()
@ -127,6 +134,9 @@ public partial class SeaExportService : ISeaExportService
.Mapper(it =>
{
it.BookingStatus = statusList.Where(x => x.BusinessId == it.Id).ToList();
//var ctnPrice = ctnPrices.First(x => x.BusinessId == it.Id);
//it.QuotePrice = ctnPrice?.QuotePrice;
//it.FloorPrice = ctnPrice?.FloorPrice;
//it.BookingStatus = tenantDb.Queryable<BookingStatus>().Where(x => x.BusinessId == it.Id).Select<BookingStatusRes>().ToList();
//it.StatusLog =
})

@ -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;

@ -1,4 +1,5 @@
using DS.Module.Core;
using DS.WMS.Core.TaskInteraction.Entity;
namespace DS.WMS.Core.TaskInteraction.Dtos
{

@ -39,11 +39,31 @@ namespace DS.WMS.Core.TaskInteraction.Dtos
/// </summary>
public string TaskTypeName { get; set; } = string.Empty;
/// <summary>
/// 父级ID用于子任务
/// </summary>
public long? ParentId { get; set; }
/// <summary>
/// 父级业务ID用于子任务
/// </summary>
public long? ParentBusinessId { get; set; }
/// <summary>
/// 附加数据(内部使用)
/// </summary>
public object? ExtraData { get; set; }
/// <summary>
/// 是否自动同步更新主任务状态
/// </summary>
public bool AutoSync { get; set; }
/// <summary>
/// 任务步骤
/// </summary>
public List<TaskStepDto>? Steps { get; set; }
/// <summary>
/// 确定当前对象是否有效
/// </summary>

@ -0,0 +1,35 @@
using DS.WMS.Core.TaskInteraction.Entity;
using SqlSugar;
namespace DS.WMS.Core.TaskInteraction.Dtos
{
/// <summary>
/// 任务步骤
/// </summary>
public class TaskStepDto
{
/// <summary>
/// 步骤类型
/// </summary>
[SugarColumn(ColumnDescription = "明细类型")]
public StepType Type { get; set; }
/// <summary>
/// 名称
/// </summary>
[SugarColumn(ColumnDescription = "名称", Length = 50, IsNullable = true)]
public string? Name { get; set; }
/// <summary>
/// 值
/// </summary>
[SugarColumn(ColumnDescription = "值", IsNullable = true)]
public object? Value { get; set; }
/// <summary>
/// 是否已完成
/// </summary>
[SugarColumn(ColumnDescription = "是否已完成")]
public bool IsCompleted { get; set; }
}
}

@ -20,7 +20,7 @@ namespace DS.WMS.Core.TaskInteraction.Entity
/// <summary>
/// 上级任务ID
/// </summary>
[SugarColumn(ColumnDescription = "上级任务ID")]
[SugarColumn(ColumnDescription = "上级任务ID", IsNullable = true)]
public long? ParentId { get; set; }
/// <summary>
@ -35,6 +35,12 @@ namespace DS.WMS.Core.TaskInteraction.Entity
[SugarColumn(ColumnDescription = "业务类型", IsNullable = false)]
public BusinessType? BusinessType { get; set; }
/// <summary>
/// 上级业务ID
/// </summary>
[SugarColumn(ColumnDescription = "上级业务ID", IsNullable = true)]
public long? ParentBusinessId { get; set; }
/// <summary>
/// 任务类型
/// </summary>
@ -101,5 +107,11 @@ namespace DS.WMS.Core.TaskInteraction.Entity
/// </summary>
[SugarColumn(ColumnDescription = "审批驳回理由", Length = 200, IsNullable = true)]
public string? RejectReason { get; set; }
/// <summary>
/// 任务步骤
/// </summary>
[Navigate(NavigateType.OneToMany, nameof(TaskStep.TaskId))]
public List<TaskStep>? Steps { get; set; }
}
}

@ -0,0 +1,147 @@
using System.ComponentModel;
using Newtonsoft.Json;
using SqlSugar;
namespace DS.WMS.Core.TaskInteraction.Entity
{
/// <summary>
/// 任务步骤表
/// </summary>
[SugarTable("business_task_step", "任务步骤表")]
public class TaskStep
{
/// <summary>
/// ID
/// </summary>
[SugarColumn(IsPrimaryKey = true)]
public long Id { get; set; }
/// <summary>
/// 任务ID
/// </summary>
[SugarColumn(ColumnDescription = "任务ID")]
public long TaskId { get; set; }
/// <summary>
/// 步骤类型
/// </summary>
[SugarColumn(ColumnDescription = "明细类型")]
public StepType Type { get; set; }
/// <summary>
/// 名称
/// </summary>
[SugarColumn(ColumnDescription = "名称", Length = 50, IsNullable = true)]
public string? Name { get; set; }
/// <summary>
/// 值
/// </summary>
[SugarColumn(ColumnDescription = "值", IsNullable = true)]
public string? Value { get; set; }
/// <summary>
/// 是否已完成
/// </summary>
[SugarColumn(ColumnDescription = "是否已完成")]
public bool IsCompleted { get; set; }
/// <summary>
/// 排序值
/// </summary>
[SugarColumn(ColumnDescription = "排序值")]
public int SortOrder { get; set; }
/// <summary>
/// 创建人
/// </summary>
[SugarColumn(ColumnDescription = "创建人", IsNullable = false)]
public long CreateBy { get; set; }
/// <summary>
/// 创建时间
/// </summary>
[SugarColumn(ColumnDescription = "创建时间", IsNullable = false)]
public DateTime CreateTime { get; set; }
/// <summary>
/// 更新人
/// </summary>
[SugarColumn(ColumnDescription = "更新人", IsNullable = true)]
public long? UpdateBy { get; set; }
/// <summary>
/// 更新时间
/// </summary>
[SugarColumn(ColumnDescription = "更新时间", IsNullable = true)]
public DateTime? UpdateTime { get; set; }
/// <summary>
/// 返回指定类型的值
/// </summary>
/// <typeparam name="T">值的类型</typeparam>
/// <returns></returns>
public T? GetValue<T>()
{
if (string.IsNullOrEmpty(Value))
return default;
var type = typeof(T);
if (type.IsEnum)
return (T)Enum.Parse(type, Value);
if (!type.IsClass)
return (T)Convert.ChangeType(Value, type);
return JsonConvert.DeserializeObject<T>(Value);
}
/// <summary>
/// 设置值
/// </summary>
/// <param name="value">要设置的值</param>
/// <returns></returns>
public void SetValue(object? value)
{
if (value == null)
return;
var type = value.GetType();
if (type.IsClass && type != typeof(string))
{
Value = JsonConvert.SerializeObject(value);
}
else
{
Value = value.ToString();
}
}
}
/// <summary>
/// 任务步骤类型
/// </summary>
public enum StepType
{
/// <summary>
/// 未指定
/// </summary>
[Description("未指定")]
NotSpecified = 0,
/// <summary>
/// 客户确认
/// </summary>
[Description("客户确认")]
CustomerConfirm = 1,
/// <summary>
/// 国外代理确认
/// </summary>
[Description("国外代理确认")]
ForeignAgentConfirm = 2,
}
}

@ -58,6 +58,14 @@ namespace DS.WMS.Core.TaskInteraction.Interface
/// <returns></returns>
Task<DataResult> SetTaskStatusAsync(TaskUpdateRequest request, bool useTransaction = true);
/// <summary>
/// 设置任务步骤状态
/// </summary>
/// <param name="request"></param>
/// <param name="useTransaction">是否使用事务</param>
/// <returns></returns>
Task<DataResult> SetStepsAsync(TaskRequest request, bool useTransaction = true);
/// <summary>
/// 更新任务台描述
/// </summary>

@ -1,16 +1,19 @@
using DS.WMS.Core.TaskInteraction.Dtos;
using DS.Module.Core;
using DS.WMS.Core.Op.Entity;
using DS.WMS.Core.TaskInteraction.Dtos;
using DS.WMS.Core.TaskInteraction.Entity;
using DS.WMS.Core.TaskInteraction.Interface;
using DS.WMS.Core.TaskPlat.Interface;
using Masuit.Tools.Systems;
using Microsoft.Extensions.DependencyInjection;
namespace DS.WMS.Core.TaskInteraction.Method.ActionExecutor.BLConfirm
{
/// <summary>
/// 分单提单确认
/// 分单提单确认动作
/// </summary>
public class SubBLConfirmActionExecutor : ServiceBase, IActionExecutor
{
ITaskManageBCService bCService;
//ITaskManageBCService bCService;
ISeaExportTaskService taskService;
ITaskLogService logService;
@ -20,7 +23,7 @@ namespace DS.WMS.Core.TaskInteraction.Method.ActionExecutor.BLConfirm
/// <param name="provider"></param>
public SubBLConfirmActionExecutor(IServiceProvider provider) : base(provider)
{
bCService = provider.GetRequiredService<ITaskManageBCService>();
//bCService = provider.GetRequiredService<ITaskManageBCService>();
taskService = provider.GetRequiredService<ISeaExportTaskService>();
logService = provider.GetRequiredService<ITaskLogService>();
}
@ -32,8 +35,77 @@ namespace DS.WMS.Core.TaskInteraction.Method.ActionExecutor.BLConfirm
/// <returns></returns>
public async Task ExecuteAsync(ActionExecutionContext context)
{
//if (await taskService)
//{
//}
var bills = await TenantDb.Queryable<SeaExportBillManage>().Where(x => x.BusinessId == context.TaskInfo.BusinessId)
.Select(x => new
{
x.Id,
x.HBLNO,
x.BillType,
x.Vessel,
x.Voyno,
x.ETD,
}).ToListAsync();
if (bills.Count == 0)
return;
DataResult result;
long userId = long.Parse(User.UserId);
var dtNow = DateTime.Now;
await TenantDb.Ado.BeginTranAsync();
try
{
foreach (var bill in bills)
{
var req = new TaskCreationRequest
{
ParentId = context.TaskInfo.Id,
ParentBusinessId = context.TaskInfo.BusinessId,
BusinessId = bill.Id,
BusinessType = context.TaskInfo.BusinessType,
TaskTypeName = TaskBaseTypeEnum.WAIT_SUB_BILL_CONFIRM.ToString(),
TaskTitle = $"{bill.BillType} {bill.HBLNO} {bill.ETD} {bill.Vessel}|{bill.Voyno}",
Steps = []
};
req.Steps.Add(new TaskStepDto
{
Type = StepType.CustomerConfirm,
Name = StepType.CustomerConfirm.ToString()
});
req.Steps.Add(new TaskStepDto
{
Type = StepType.ForeignAgentConfirm,
Name = StepType.ForeignAgentConfirm.ToString()
});
result = await taskService.CreateTaskAsync(req, false);
if (!result.Succeeded)
{
await logService.WriteLogAsync(new BusinessTask
{
BusinessId = req.BusinessId,
BusinessType = req.BusinessType,
TaskStatus = TaskStatusEnum.Create,
TaskType = req.TaskType,
CreateBy = userId,
CreateTime = dtNow
}, $"创建【{req.TaskType.GetDescription()}】任务时出错:" + result.Message);
return;
}
}
await TenantDb.Ado.CommitTranAsync();
}
catch (Exception ex)
{
await TenantDb.Ado.RollbackTranAsync();
await ex.LogAsync(Db);
}
}
}

@ -433,7 +433,7 @@ namespace DS.WMS.Core.TaskInteraction.Method
SendTo = sendTo,
Title = title,
Body = content,
CCTo = string.Join(",", ccList),
CCTo = string.Join(";", ccList),
ShowName = senderConfig.ShowName.IsNullOrEmpty() ? templateModel.Sender.DisplayName : senderConfig.ShowName,
Account = senderConfig.MailAccount,
senderConfig.Password,

@ -1,5 +1,4 @@
using System.Text;
using System.Threading.Tasks;
using DS.Module.Core;
using DS.Module.Core.Data;
using DS.Module.Core.Helpers;
@ -245,6 +244,9 @@ namespace DS.WMS.Core.TaskInteraction.Method
return result;
}
long userId = long.Parse(User.UserId);
DateTime dtNow = DateTime.Now;
if (useTransaction)
await TenantDb.Ado.BeginTranAsync();
try
@ -355,20 +357,40 @@ namespace DS.WMS.Core.TaskInteraction.Method
task = new BusinessTask
{
ParentId = request.ParentId,
BusinessId = request.BusinessId,
BusinessType = request.BusinessType,
ParentBusinessId = request.ParentBusinessId,
TaskType = request.TaskType,
TaskStatus = TaskStatusEnum.Create,
RecvUsers = string.Join(',', info.Main.RecvUserInfoList.Select(x => x.RecvUserId)) ?? string.Empty,
NextType = request.NextType,
CreateBy = long.Parse(User.UserId),
CreateTime = DateTime.Now
CreateBy = userId,
CreateTime = dtNow
};
if (IsOrderType(request.TaskType) && !task.NextType.HasValue)
task.NextType = await GetNextTypeAsync(task);
await TenantDb.Insertable(task).ExecuteCommandAsync();
if (request.Steps?.Count > 0)
{
if (request.Steps.Where(x => x.Type != StepType.NotSpecified).GroupBy(x => x.Type).Select(x => x.Key).Count() > 1)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.DuplicateStepType));
var steps = request.Steps.Select(x => new TaskStep
{
TaskId = task.Id,
IsCompleted = x.IsCompleted,
Name = x.Name,
Type = x.Type,
SortOrder = request.Steps.IndexOf(x),
CreateBy = userId,
CreateTime = dtNow
}).ToList();
await TenantDb.Insertable(request.Steps).ExecuteCommandAsync();
}
result = await OnTaskCreated(task);
if (!result.Succeeded)
@ -542,8 +564,14 @@ namespace DS.WMS.Core.TaskInteraction.Method
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskNotExists));
if (task.TaskStatus == TaskStatusEnum.Complete)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskCompleted));
//if (task.TaskStatus == TaskStatusEnum.Cancel)
// return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskCancelled));
//检查是否有未完成的任务步骤
var steps = await TenantDb.Queryable<TaskStep>().Where(x => x.TaskId == task.Id && !x.IsCompleted)
.Select(x => new { x.Type, x.Name }).ToListAsync();
if (steps.Count > 0)
return DataResult.Failed(
MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.UnfinishedItems)) + "" + string.Join("|", steps.Select(x => x.Type == StepType.NotSpecified ? x.Name : x.Type.GetDescription())),
nameof(MultiLanguageConst.UnfinishedItems));
//触发任务状态变更通知
if (task.TaskStatus != request.TaskStatus)
@ -616,6 +644,102 @@ namespace DS.WMS.Core.TaskInteraction.Method
}
}
/// <summary>
/// 设置任务步骤状态
/// </summary>
/// <param name="request"></param>
/// <param name="useTransaction">是否使用事务</param>
/// <returns></returns>
public async Task<DataResult> SetStepsAsync(TaskRequest request, bool useTransaction = true)
{
if (!await HasAuthorizedAsync())
return DataResult.FailedWithDesc(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.ModuleUnauthorized)));
if (request.Steps == null || request.Steps.Count == 0)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.SubTaskCannotNull));
if (useTransaction)
await TenantDb.Ado.BeginTranAsync();
try
{
BusinessTask task = await GetQuery(request.BusinessId, request.BusinessType, request.TaskType).FirstAsync();
if (task == null)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskNotExists));
if (task.TaskStatus == TaskStatusEnum.Complete)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskCompleted));
var stepTypes = request.Steps.Select(x => x.Type);
var steps = await TenantDb.Queryable<TaskStep>().Where(x => x.TaskId == task.Id && stepTypes.Contains(x.Type))
.Select(x => new TaskStep
{
Id = x.Id,
Type = x.Type,
Name = x.Name,
SortOrder = x.SortOrder
}).ToListAsync();
long userId = long.Parse(User.UserId);
DateTime dtNow = DateTime.Now;
foreach (var item in steps)
{
var reqStep = request.Steps.Find(x => x.Type == item.Type);
if (reqStep == null)
continue;
item.SetValue(reqStep.Value);
item.IsCompleted = reqStep.IsCompleted;
item.UpdateBy = userId;
item.UpdateTime = dtNow;
}
await TenantDb.Updateable(steps).UpdateColumns(x => new
{
x.Value,
x.IsCompleted,
x.UpdateBy,
x.UpdateTime
}).ExecuteCommandAsync();
if (request.AutoSync)
{
var allSteps = await TenantDb.Queryable<TaskStep>().Where(x => x.TaskId == task.Id)
.Select(x => new
{
x.Id,
x.IsCompleted
}).ToListAsync();
if (allSteps.Count > 0 && allSteps.Count == allSteps.Count(x => x.IsCompleted))
{
var result = await SetTaskStatusAsync(new TaskUpdateRequest
{
BusinessId = task.BusinessId,
BusinessType = task.BusinessType,
TaskTypeName = request.TaskTypeName,
TaskStatus = TaskStatusEnum.Complete
}, false);
if (!result.Succeeded)
return result;
}
}
if (useTransaction)
await TenantDb.Ado.CommitTranAsync();
return DataResult.Success;
}
catch (Exception ex)
{
if (useTransaction)
await TenantDb.Ado.RollbackTranAsync();
await ex.LogAsync(Db);
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
}
}
/// <summary>
/// 当任务状态发生变化时调用
/// </summary>

@ -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();
/// <summary>
/// 初始化
/// </summary>
@ -21,13 +26,31 @@ namespace DS.WMS.FeeApi.Controllers
_service = service;
}
//1获取当前登录人收款信息
// ClientBank/GetClientBankList
//2获取发票列表
// feeApi/InInvoicet/GetInInvoicet
/// <summary>
/// 获取报销单列表列表
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost]
[Route("GetReimbursementList")]
public DataResult<List<ReimbursementRes>> GetReimbursementList([FromBody] PageRequest request)
{
var res = _service.GetListByPage(request);
return res;
}
//3新增报销单,并同步到钉钉
/// <summary>
/// 获取报销单详情
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet]
[Route("GetReimbursementInfo")]
public DataResult<ReimbursementRes> GetReimbursementInfo([FromQuery] string id)
{
var res = _service.GetReimbursementInfo(id);
return res;
}
/// <summary>
/// 新增
@ -36,14 +59,12 @@ namespace DS.WMS.FeeApi.Controllers
/// <returns></returns>
[HttpPost]
[Route("AddReimbursement")]
public DataResult AddReimbursement([FromBody] ReimbursementReq req)
public async Task<DataResult> AddReimbursement([FromBody] ReimbursementReq req)
{
var res = _service.AddReimbursement(req);
var res =await _service.AddReimbursement(req);
return res;
}
//4未审批的报销单撤销
/// <summary>
/// 未审批的报销单撤销
/// </summary>
@ -51,48 +72,51 @@ namespace DS.WMS.FeeApi.Controllers
/// <returns></returns>
[HttpPost]
[Route("ReimbursementRevoked")]
public DataResult ReimbursementRevoked([FromBody] string id)
public async Task<DataResult> ReimbursementRevoked([FromBody] string id)
{
var res = _service.ReimbursementRevoked(id);
var res = await _service.ReimbursementRevoked(id);
return res;
}
//5报销单审核通过
//6报销单审核驳回
//7获取报销单列表
/// <summary>
/// 列表
/// 按报销单审核
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost]
[Route("GetReimbursementList")]
public DataResult<List<ReimbursementRes>> GetReimbursementList([FromBody] PageRequest request)
[HttpPost, Route("Audit")]
public async Task<DataResult> 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获取报销单详情
/// <summary>
/// 回调变更申请单审批状态(用于工作流框架的回调)
/// </summary>
/// <param name="callback">回调信息</param>
/// <returns></returns>
[HttpPost, Route("ChangeStatus")]
public async Task<IActionResult> ChangeStatusAsync([FromBody] FlowCallback callback)
{
var str = JsonConvert.SerializeObject(callback);
_logger.Info($"变更申请单审批状态回调,请求参数为:{str}");
await _service.UpdateStatusAsync(callback);
return StatusCode((int)HttpStatusCode.NoContent);
}
/// <summary>
/// 详情
/// 回调通知审批执行人变更(无需客户端手动调用)
/// </summary>
/// <param name="id"></param>
/// <param name="callback">回调信息</param>
/// <returns></returns>
[HttpGet]
[Route("GetReimbursementInfo")]
public DataResult<ReimbursementRes> GetReimbursementInfo([FromQuery] string id)
[HttpPost, Route("MarkerChanged")]
public async Task<IActionResult> 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钉钉配置相关接口
}
}

@ -84,7 +84,12 @@ namespace DS.WMS.OpApi.Controllers
{
var result = await taskService.GetTasks(request.BusinessId, request.BusinessType, request.TaskType);
if (result.Data?.Count > 0)
return await actionService.TriggerActionAsync(result.Data[0].Adapt<BusinessTask>(), false);
{
var task = result.Data[0].Adapt<BusinessTask>();
task.BusinessId = request.BusinessId;
task.BusinessType = request.BusinessType;
return await actionService.TriggerActionAsync(task, false);
}
return DataResult.FailedWithDesc(MultiLanguageConst.EmptyData);
}
@ -159,6 +164,20 @@ namespace DS.WMS.OpApi.Controllers
return await taskService.SetTaskStatusAsync(request);
}
/// <summary>
/// 设置任务步骤
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost, Route("SetSteps")]
public async Task<DataResult> SetStepsAsync(TaskRequest request)
{
if (!ModelState.IsValid)
return DataResult.Failed(ModelState.GetErrorMessage(), MultiLanguageConst.IllegalRequest);
return await taskService.SetStepsAsync(request);
}
/// <summary>
/// 手动发起任务审核(用于二次审核)
/// </summary>

@ -120,7 +120,7 @@
"Port": 465,
"UseSSL": true,
"Receivers": "candy@sunniness.net",
"CCTo": "yee@sunniness.net,daisusu@dongshengsoft.com",
"CCTo": "yee@sunniness.net;daisusu@dongshengsoft.com",
"Title": "WSL Volume Daily Increase Report",
"Body": "<article class='4ever-article'><p style='line-height: 1;'>Dear WSL Team,</p><p style='line-height: 1;'>Pls kindly check the daily report for your member's nomination booking:&nbsp;</p><p style='line-height: 1;'>&nbsp;</p><p style='line-height: 1;'>Thanks &amp; Best regards</p><p style='line-height: 1;'>Candy SHAO 邵芳</p><p style='line-height: 1;'>General Manager| <strong><span style='color: #e67e23;'>SUNNINESS LOGISTICS CO.,LTD.</span></strong></p><p style='line-height: 1;'>TEL: +(86) (0532-80688387)1 MB./We chat: +(86)(18866622731) | QQ:2853083553|Email:candy@sunniness. net |WCA ID: 60272</p></article>"
}

Loading…
Cancel
Save