往来单位干系人审核

dev
嵇文龙 2 months ago
parent ede507d6bb
commit 5086f4a0ce

@ -253,6 +253,12 @@ namespace DS.Module.Core
/// </summary>
[Description("客户/供应商审核")]
INFO_CLIENT_AUDIT = 501,
/// <summary>
/// 客户干系人审核
/// </summary>
[Description("客户干系人审核")]
CLIENT_STAKEHOLDER_AUDIT = 502,
#endregion
#region 费用相关审核
@ -319,6 +325,11 @@ namespace DS.Module.Core
[Description("客户/供应商审核驳回")]
INFO_CLIENT_REJECTED = -501,
/// <summary>
/// 客户干系人审核驳回
/// </summary>
[Description("客户干系人审核")]
CLIENT_STAKEHOLDER_REJECTED = -502,
/// <summary>
/// 费用审核驳回
/// </summary>
[Description("费用审核驳回")]

@ -104,6 +104,16 @@ public class ClientAccountDateReq
/// 特批放单客户
/// </summary>
public bool IsSpecial { get; set; }
/// <summary>
/// 人民币账户ID
/// </summary>
public long? RMBAccountId { get; set; }
/// <summary>
/// 美金账户ID
/// </summary>
public long? USDAccountId { get; set; }
}
/// <summary>

@ -117,4 +117,14 @@ public class ClientAccountDateRes
/// 特批放单客户
/// </summary>
public bool IsSpecial { get; set; }
/// <summary>
/// 人民币账户ID
/// </summary>
public long? RMBAccountId { get; set; }
/// <summary>
/// 美金账户ID
/// </summary>
public long? USDAccountId { get; set; }
}

@ -117,4 +117,16 @@ public class InfoClientAccountDate : BaseModelV2<long>
/// </summary>
[SugarColumn(ColumnDescription = "机构Id")]
public long OrgId { get; set; }
/// <summary>
/// 人民币账户ID
/// </summary>
[SugarColumn(ColumnDescription = "人民币账户ID")]
public long? RMBAccountId { get; set; }
/// <summary>
/// 美金账户ID
/// </summary>
[SugarColumn(ColumnDescription = "美金账户ID")]
public long? USDAccountId { get; set; }
}

@ -0,0 +1,90 @@
using System.ComponentModel;
using SqlSugar;
namespace DS.WMS.Core.Info.Entity
{
/// <summary>
/// 往来单位干系人
/// </summary>
[SugarTable("info_client_stakeholder", "往来单位干系人")]
public class InfoClientStakeholder
{
/// <summary>
/// 主键ID
/// </summary>
[SugarColumn(IsPrimaryKey = true)]
public long Id { get; set; }
/// <summary>
/// 客户ID
/// </summary>
[SugarColumn(ColumnDescription = "客户ID", IsNullable = false)]
public long ClientId { get; set; }
/// <summary>
/// 干系人ID
/// </summary>
[SugarColumn(ColumnDescription = "干系人ID", IsNullable = false)]
public long CreateBy { get; set; }
/// <summary>
/// 干系人姓名
/// </summary>
[SugarColumn(ColumnDescription = "干系人姓名", Length = 200, IsNullable = true)]
public string? CreateByName { get; set; }
/// <summary>
/// 生效日期
/// </summary>
[SugarColumn(ColumnDescription = "生效日期", IsNullable = false)]
public DateTime StartDate { get; set; }
/// <summary>
/// 失效日期
/// </summary>
[SugarColumn(ColumnDescription = "失效日期", IsNullable = false)]
public DateTime EndDate { get; set; }
/// <summary>
/// 干系人状态
/// </summary>
[SugarColumn(ColumnDescription = "干系人状态", IsNullable = false)]
public StakeholderStatus Status { get; set; }
/// <summary>
/// 备注
/// </summary>
[SugarColumn(ColumnDescription = "备注", Length = 200, IsNullable = true)]
public string? Remark { get; set; }
}
/// <summary>
/// 干系人状态
/// </summary>
public enum StakeholderStatus
{
/// <summary>
/// 未提交
/// </summary>
[Description("未提交")]
Uncommitted = 0,
/// <summary>
/// 待审批
/// </summary>
[Description("待审批")]
Pending = 1,
/// <summary>
/// 审核通过
/// </summary>
[Description("审核通过")]
Approved = 2,
/// <summary>
/// 审核驳回
/// </summary>
[Description("审核驳回")]
Rejected = 3
}
}

@ -1,6 +1,7 @@
using DS.Module.Core;
using DS.Module.Core.Data;
using DS.WMS.Core.Info.Dtos;
using DS.WMS.Core.Sys.Entity;
namespace DS.WMS.Core.Info.Interface;
@ -12,15 +13,15 @@ public interface IClientAccountDateService
/// <param name="request"></param>
/// <returns></returns>
DataResult<List<ClientAccountDateRes>> GetListByPage(PageRequest request);
/// <summary>
/// 编辑
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
DataResult EditClientAccountDate(ClientAccountDateReq model);
/// <summary>
/// 获取详情
/// </summary>
@ -34,4 +35,11 @@ public interface IClientAccountDateService
/// <param name="model"></param>
/// <returns></returns>
Task<DataResult> DeleteAsync(IdModel model);
/// <summary>
/// 获取组织机构银行账户列表
/// </summary>
/// <param name="currency">账户币别</param>
/// <returns></returns>
Task<DataResult<List<SysBank>>> GetTenantBanksAsync(string? currency = null);
}

@ -60,6 +60,13 @@ public interface IClientInfoService
/// <returns></returns>
Task<DataResult> EditAsync(ClientInfoReq model);
/// <summary>
/// 检查客户信息是否重复
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
Task<DataResult> IsAvailableAsync(ClientInfoReq req);
/// <summary>
/// 获取详情
/// </summary>

@ -0,0 +1,32 @@
using DS.Module.Core;
using DS.WMS.Core.Info.Entity;
namespace DS.WMS.Core.Info.Interface
{
/// <summary>
/// 往来单位干系人
/// </summary>
public interface IClientStakeholderService
{
/// <summary>
/// 列表
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
Task<DataResult<List<InfoClientStakeholder>>> GetListByPageAsync(PageRequest request);
/// <summary>
/// 获取客户干系人
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
Task<DataResult<InfoClientStakeholder>> GetAsync(long id);
/// <summary>
/// 创建/更新客户干系人
/// </summary>
/// <param name="stakeholder">干系人</param>
/// <returns></returns>
Task<DataResult> EditAsync(InfoClientStakeholder stakeholder);
}
}

@ -116,4 +116,20 @@ public class ClientAccountDateService : ServiceBase, IClientAccountDateService
int rows = await TenantDb.Deleteable<InfoClientAccountDate>().Where(x => model.Ids.Contains(x.Id)).ExecuteCommandAsync();
return rows > 0 ? DataResult.Success : DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
}
/// <summary>
/// 获取组织机构银行账户列表
/// </summary>
/// <param name="currency">账户币别</param>
/// <returns></returns>
public async Task<DataResult<List<SysBank>>> GetTenantBanksAsync(string? currency = null)
{
var list = await Db.Queryable<SysBank>()
.WhereIF(!string.IsNullOrEmpty(currency), x => x.Currency == currency)
.OrderBy(x => x.OrderNo).ToListAsync();
var result = DataResult<List<SysBank>>.Success(list);
result.Count = list.Count;
return result;
}
}

@ -374,11 +374,12 @@ public class ClientInfoService : ServiceBase, IClientInfoService
if (req.ServiceItemCodes?.Length > 0)
data.ServiceItem = string.Join(",", req.ServiceItemCodes);
var result = await IsAvailableAsync(req);
if (!result.Succeeded)
return result;
if (req.Id == 0)
{
if (TenantDb.Queryable<InfoClient>().Where(x => (x.ShortName == req.ShortName.Trim() || x.Description == req.Description.Trim() || x.TaxNo == req.TaxNo.Trim())).Any())
return DataResult.Failed("客户信息已存在,请检查客户全称、简称或社会信用代码是否重复!", MultiLanguageConst.ClientInfoExist);
var tag = req.ClientTag.Adapt<InfoClientTag>();
var entity = await TenantDb.Insertable(data).ExecuteReturnEntityAsync();
tag.ClientId = entity.Id;
@ -396,9 +397,6 @@ public class ClientInfoService : ServiceBase, IClientInfoService
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.ItemsAreAuditing));
var tag = TenantDb.Queryable<InfoClientTag>().Where(x => x.ClientId == req.Id).First();
if (TenantDb.Queryable<InfoClient>().Where(x => x.Id != data.Id && (x.ShortName == req.ShortName.Trim() || x.Description == req.Description.Trim() || x.TaxNo == req.TaxNo.Trim())).Any())
return DataResult.Failed("请检查客户全称、简称或社会信用代码是否重复!", MultiLanguageConst.ClientInfoExist);
tag = req.ClientTag.Adapt(tag);
data.ServiceItem = data.ServiceItem ?? string.Empty;
var updateable = TenantDb.Updateable(data).RemoveDataCache($"{SqlSugarCacheConst.InfoClient}{User.TenantId}")
@ -416,6 +414,23 @@ public class ClientInfoService : ServiceBase, IClientInfoService
}
}
/// <summary>
/// 检查客户信息是否重复
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
public async Task<DataResult> IsAvailableAsync(ClientInfoReq req)
{
var expr = Expressionable.Create<InfoClient>()
.And(x => x.ShortName == req.ShortName.Trim() || x.Description == req.Description.Trim())
.AndIF(req.Id > 0, x => x.Id != req.Id);
if (await TenantDb.Queryable<InfoClient>().Where(expr.ToExpression()).AnyAsync())
return DataResult.Failed("客户信息已存在,请检查客户全称/简称是否重复!", MultiLanguageConst.ClientInfoExist);
return DataResult.Success;
}
/// <summary>
/// 详情
/// </summary>

@ -0,0 +1,274 @@
using DS.Module.Core;
using DS.Module.Core.Data;
using DS.Module.Core.Extensions;
using DS.WMS.Core.Fee.Dtos;
using DS.WMS.Core.Flow.Dtos;
using DS.WMS.Core.Flow.Entity;
using DS.WMS.Core.Flow.Interface;
using DS.WMS.Core.Info.Entity;
using DS.WMS.Core.Info.Interface;
using DS.WMS.Core.Op.Dtos.TaskInteraction;
using DS.WMS.Core.Op.Interface.TaskInteraction;
using Masuit.Tools.Systems;
using Microsoft.Extensions.DependencyInjection;
namespace DS.WMS.Core.Info.Method
{
/// <summary>
/// 往来单位干系人
/// </summary>
public class ClientStakeholderService : ServiceBase, IClientStakeholderService
{
const TaskBaseTypeEnum CLIENT_STAKEHOLDER_TASK = TaskBaseTypeEnum.CLIENT_STAKEHOLDER_AUDIT;
Lazy<IClientFlowInstanceService> flowService;
Lazy<ITaskService> taskService;
/// <summary>
/// 初始化
/// </summary>
/// <param name="serviceProvider"></param>
public ClientStakeholderService(IServiceProvider serviceProvider) : base(serviceProvider)
{
flowService = new Lazy<IClientFlowInstanceService>(serviceProvider.GetRequiredService<IClientFlowInstanceService>());
taskService = new Lazy<ITaskService>(serviceProvider.GetRequiredService<ITaskService>());
}
#region 审核
/// <summary>
/// 提交审核
/// </summary>
/// <param name="idModel"></param>
/// <returns></returns>
public async Task<DataResult> SubmitAuditAsync(IdModel idModel)
{
var list = await TenantDb.Queryable<InfoClientStakeholder>().Where(x => idModel.Ids.Contains(x.Id)).Select(x => new
{
x.Id,
x.Status,
x.CreateByName,
}).ToListAsync();
if (list.Exists(x => x.Status == StakeholderStatus.Pending))
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.ItemsAreAuditing));
if (await taskService.Value.HasAuthorizedAsync())
{
var requests = list.Select(x => new TaskCreationRequest
{
BusinessId = x.Id,
TaskTypeName = CLIENT_STAKEHOLDER_TASK.ToString(),
TaskTitle = $"【{CLIENT_STAKEHOLDER_TASK.GetDescription()}】{x.CreateByName}"
});
await TenantDb.Ado.BeginTranAsync();
try
{
DataResult result;
foreach (var request in requests)
{
result = await taskService.Value.CreateTaskAsync(request, false);
if (!result.Succeeded)
return result;
}
await TenantDb.Updateable<InfoClientStakeholder>().Where(x => idModel.Ids.Contains(x.Id))
.SetColumns(x => x.Status == StakeholderStatus.Pending).ExecuteCommandAsync();
await TenantDb.Ado.CommitTranAsync();
return DataResult.Success;
}
catch (Exception ex)
{
await TenantDb.Ado.RollbackTranAsync();
await ex.LogAsync(Db);
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
}
}
var template = await FindTemplateAsync(CLIENT_STAKEHOLDER_TASK);
if (template == null)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TemplateNotFound));
for (int i = 0; i < idModel.Ids.Length; i++)
{
var id = idModel.Ids[i];
var result = flowService.Value.CreateFlowInstance(new CreateFlowInstanceReq
{
BusinessId = id,
TemplateId = template.Id
});
if (!result.Succeeded || result.Data is not FlowInstance instance)
return result;
result = flowService.Value.StartFlowInstance(instance.Id.ToString());
if (!result.Succeeded)
return result;
}
var rows = await TenantDb.Updateable<InfoClientStakeholder>().Where(x => idModel.Ids.Contains(x.Id))
.SetColumns(x => x.Status == StakeholderStatus.Pending).ExecuteCommandAsync();
return rows > 0 ? DataResult.Success : DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
}
/// <summary>
/// 执行审核
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public async Task<DataResult> AuditAsync(AuditRequest request)
{
if (await taskService.Value.HasAuthorizedAsync())
{
return await taskService.Value.AuditAsync(new TaskAuditRequest
{
Ids = request.Ids,
Remark = request.Remark,
Result = request.Result,
TaskTypeName = CLIENT_STAKEHOLDER_TASK.ToString()
});
}
var list = await flowService.Value.GetInstanceByBSIdAsync(CLIENT_STAKEHOLDER_TASK, ids: request.Ids);
if (list.Count != request.Ids.Length)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.NotInAudit));
foreach (var item in list)
{
var result = flowService.Value.AuditFlowInstance(new FlowAuditInfo
{
AuditNote = request.Remark,
Status = request.Result,
Instance = item
});
if (!result.Succeeded)
return result;
}
return DataResult.Success;
}
/// <summary>
/// 撤销审核
/// </summary>
/// <param name="idModel"></param>
/// <returns></returns>
public async Task<DataResult> WithdrawAsync(IdModel idModel)
{
DataResult result;
if (await taskService.Value.HasAuthorizedAsync())
{
await TenantDb.Ado.BeginTranAsync();
try
{
for (int i = 0; i < idModel.Ids.Length; i++)
{
result = await taskService.Value.WithdrawAsync(new TaskRequest
{
BusinessId = idModel.Ids[i],
TaskTypeName = CLIENT_STAKEHOLDER_TASK.ToString()
}, false);
if (!result.Succeeded)
{
return result;
}
}
await TenantDb.Updateable<InfoClientStakeholder>().Where(x => idModel.Ids.Contains(x.Id))
.SetColumns(x => x.Status == StakeholderStatus.Uncommitted)
.SetColumns(x => x.Remark == null)
.ExecuteCommandAsync();
await TenantDb.Ado.CommitTranAsync();
return DataResult.Success;
}
catch
{
await TenantDb.Ado.RollbackTranAsync();
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
}
}
var list = await flowService.Value.GetInstanceByBSIdAsync(CLIENT_STAKEHOLDER_TASK, ids: idModel.Ids);
if (list.Count != idModel.Ids.Length)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.NotInAudit));
result = await flowService.Value.WithdrawAsync(idModel.Ids);
if (!result.Succeeded)
return result;
int rows = await TenantDb.Updateable<InfoClientStakeholder>().Where(x => idModel.Ids.Contains(x.Id))
.SetColumns(x => x.Status == StakeholderStatus.Uncommitted).ExecuteCommandAsync();
return rows > 0 ? DataResult.Success : DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
}
/// <summary>
/// 审核完成回调
/// </summary>
/// <param name="callback">回调信息</param>
/// <returns></returns>
public async Task<DataResult> AuditCallbackAsync(FlowCallback callback)
{
if (callback.AuditType != CLIENT_STAKEHOLDER_TASK)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.NoAuditItems));
InfoClientStakeholder entity = new()
{
Id = callback.BusinessId,
Remark = callback.RejectReason,
Status = callback.FlowStatus == FlowStatusEnum.Approve ? StakeholderStatus.Approved : StakeholderStatus.Rejected
};
int rows = await TenantDb.Updateable(entity).UpdateColumns(x => new
{
x.Remark,
x.Status
}).ExecuteCommandAsync();
return rows > 0 ? DataResult.Success : DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
}
#endregion
/// <summary>
/// 列表
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public async Task<DataResult<List<InfoClientStakeholder>>> GetListByPageAsync(PageRequest request)
{
//序列化查询条件
var whereList = request.GetConditionalModels(Db);
var result = await TenantDb.Queryable<InfoClientStakeholder>()
.Where(whereList)
.ToQueryPageAsync(request.PageCondition);
return result;
}
/// <summary>
/// 获取客户干系人
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<DataResult<InfoClientStakeholder>> GetAsync(long id)
{
var model = await TenantDb.Queryable<InfoClientStakeholder>().FirstAsync(x => x.Id == id);
return DataResult<InfoClientStakeholder>.Success(model);
}
/// <summary>
/// 创建/更新客户干系人
/// </summary>
/// <param name="stakeholder">干系人</param>
/// <returns></returns>
public async Task<DataResult> EditAsync(InfoClientStakeholder stakeholder)
{
await TenantDb.Storageable(stakeholder).DefaultAddElseUpdate().ExecuteCommandAsync();
return DataResult.Success;
}
}
}

@ -3,6 +3,7 @@ using DS.Module.Core.Data;
using DS.WMS.Core.Info.Dtos;
using DS.WMS.Core.Info.Interface;
using DS.WMS.Core.Sys.Dtos;
using DS.WMS.Core.Sys.Entity;
using DS.WMS.Core.Sys.Interface;
using Microsoft.AspNetCore.Mvc;
@ -76,4 +77,15 @@ public class ClientAccountDateController : ApiController
return await _invokeService.DeleteAsync(model);
}
/// <summary>
/// 获取组织机构银行账户列表
/// </summary>
/// <param name="currency">账户币别,可空</param>
/// <returns></returns>
[HttpPost, Route("GetTenantBanks")]
public async Task<DataResult<List<SysBank>>> GetTenantBanksAsync(string? currency = null)
{
return await _invokeService.GetTenantBanksAsync(currency);
}
}
Loading…
Cancel
Save