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.
880 lines
36 KiB
C#
880 lines
36 KiB
C#
using DS.Module.Core;
|
|
using DS.Module.Core.Constants;
|
|
using DS.Module.Core.Data;
|
|
using DS.Module.Core.Extensions;
|
|
using DS.WMS.Core.Check.Entity;
|
|
using DS.WMS.Core.Fee.Dtos;
|
|
using DS.WMS.Core.Fee.Entity;
|
|
using DS.WMS.Core.Flow.Dtos;
|
|
using DS.WMS.Core.Flow.Entity;
|
|
using DS.WMS.Core.Flow.Interface;
|
|
using DS.WMS.Core.Info.Dtos;
|
|
using DS.WMS.Core.Info.Entity;
|
|
using DS.WMS.Core.Info.Interface;
|
|
using DS.WMS.Core.Op.Entity;
|
|
using DS.WMS.Core.Sys.Entity;
|
|
using DS.WMS.Core.Sys.Interface;
|
|
using DS.WMS.Core.TaskInteraction.Dtos;
|
|
using DS.WMS.Core.TaskInteraction.Interface;
|
|
using Fasterflect;
|
|
using Mapster;
|
|
using Masuit.Tools.Systems;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using SqlSugar;
|
|
|
|
namespace DS.WMS.Core.Info.Method;
|
|
|
|
/// <summary>
|
|
/// 往来单位服务
|
|
/// </summary>
|
|
public class ClientInfoService : ServiceBase, IClientInfoService
|
|
{
|
|
const TaskBaseTypeEnum INFO_CLIENT_TASK = TaskBaseTypeEnum.INFO_CLIENT_AUDIT;
|
|
|
|
Lazy<IClientFlowInstanceService> flowService;
|
|
Lazy<ITaskService> taskService;
|
|
private readonly ICommonService commonService;
|
|
|
|
/// <summary>
|
|
/// 初始化
|
|
/// </summary>
|
|
/// <param name="serviceProvider"></param>
|
|
public ClientInfoService(IServiceProvider serviceProvider) : base(serviceProvider)
|
|
{
|
|
flowService = new Lazy<IClientFlowInstanceService>(serviceProvider.GetRequiredService<IClientFlowInstanceService>());
|
|
taskService = new Lazy<ITaskService>(serviceProvider.GetRequiredService<ITaskService>());
|
|
commonService = serviceProvider.GetRequiredService<ICommonService>();
|
|
|
|
TenantDb.QueryFilter.Clear<IOrgId>();
|
|
TenantDb.QueryFilter.Clear<ISharedOrgId>();
|
|
}
|
|
|
|
#region 审核
|
|
|
|
/// <summary>
|
|
/// 提交审核
|
|
/// </summary>
|
|
/// <param name="idModel"></param>
|
|
/// <returns></returns>
|
|
public async Task<DataResult> SubmitAuditAsync(IdModel idModel)
|
|
{
|
|
var list = await TenantDb.Queryable<InfoClient>().Where(x => idModel.Ids.Contains(x.Id)).Select(x => new
|
|
{
|
|
x.Id,
|
|
x.AuditStatus,
|
|
x.CodeName,
|
|
x.ShortName,
|
|
x.EnShortName
|
|
}).ToListAsync();
|
|
|
|
if (list.Exists(x => x.AuditStatus == AuditStatusEnum.Auditing))
|
|
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.ItemsAreAuditing));
|
|
|
|
var queryable = TenantDb.Queryable<InfoClientContact>().Where(x => idModel.Ids.Contains(x.ClientId));
|
|
if (await queryable.AnyAsync(x => (SqlFunc.IsNullOrEmpty(x.Tel) && SqlFunc.IsNullOrEmpty(x.Mobile)) || (SqlFunc.IsNullOrEmpty(x.Email) && SqlFunc.IsNullOrEmpty(x.QQ))))
|
|
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.ClientInfoIncomplete));
|
|
|
|
if (await taskService.Value.HasAuthorizedAsync())
|
|
{
|
|
var requests = list.Select(x => new TaskCreationRequest
|
|
{
|
|
BusinessId = x.Id,
|
|
TaskTypeName = INFO_CLIENT_TASK.ToString(),
|
|
TaskTitle = $"【{INFO_CLIENT_TASK.GetDescription()}】{x.CodeName} {x.ShortName}"
|
|
});
|
|
|
|
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<InfoClient>().Where(x => idModel.Ids.Contains(x.Id))
|
|
.SetColumns(x => x.AuditStatus == AuditStatusEnum.Auditing).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(INFO_CLIENT_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<InfoClient>().Where(x => idModel.Ids.Contains(x.Id))
|
|
.SetColumns(x => x.AuditStatus == AuditStatusEnum.Auditing).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 = INFO_CLIENT_TASK.ToString()
|
|
});
|
|
}
|
|
|
|
var list = await flowService.Value.GetInstanceByBSIdAsync(INFO_CLIENT_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 = INFO_CLIENT_TASK.ToString()
|
|
}, false);
|
|
if (!result.Succeeded)
|
|
{
|
|
return result;
|
|
}
|
|
}
|
|
|
|
await TenantDb.Updateable<InfoClient>().Where(x => idModel.Ids.Contains(x.Id))
|
|
.SetColumns(x => x.AuditStatus == AuditStatusEnum.NoAudit)
|
|
.SetColumns(x => x.AuditTime == null)
|
|
.SetColumns(x => x.AuditNote == 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(INFO_CLIENT_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<InfoClient>().Where(x => idModel.Ids.Contains(x.Id))
|
|
.SetColumns(x => x.AuditStatus == AuditStatusEnum.NoAudit).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 != INFO_CLIENT_TASK)
|
|
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.NoAuditItems));
|
|
|
|
InfoClient infoClient = new()
|
|
{
|
|
Id = callback.BusinessId,
|
|
AuditNote = callback.RejectReason,
|
|
AuditTime = DateTime.Now,
|
|
AuditStatus = callback.FlowStatus == FlowStatusEnum.Approve ? AuditStatusEnum.Approve : AuditStatusEnum.Reject,
|
|
Status = callback.FlowStatus == FlowStatusEnum.Approve ? 0 : 1
|
|
};
|
|
|
|
int rows = await TenantDb.Updateable(infoClient).UpdateColumns(x => new
|
|
{
|
|
x.AuditNote,
|
|
x.AuditTime,
|
|
x.AuditStatus,
|
|
x.Status
|
|
}).ExecuteCommandAsync();
|
|
return rows > 0 ? DataResult.Success : DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
|
|
}
|
|
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// 导入
|
|
/// </summary>
|
|
/// <param name="list"></param>
|
|
/// <returns></returns>
|
|
public async Task<DataResult> ImportAsync(List<InfoClientModel> list)
|
|
{
|
|
long userId = long.Parse(User.UserId);
|
|
DateTime dtNow = DateTime.Now;
|
|
TenantDb.QueryFilter.Clear<IOrgId>();
|
|
TenantDb.QueryFilter.Clear<ISharedOrgId>();
|
|
|
|
var clientNames1 = list.Select(x => x.ShortName).Distinct();
|
|
var clientNames2 = list.Select(x => x.CNName).Distinct();
|
|
var clients = await TenantDb.Queryable<InfoClient>().Where(x => clientNames1.Contains(x.ShortName) || clientNames2.Contains(x.Description))
|
|
.Select(x => new InfoClient
|
|
{
|
|
Id = x.Id,
|
|
ShortName = x.ShortName,
|
|
Description = x.Description,
|
|
IsCustomer = x.IsCustomer,
|
|
IsSupplier = x.IsSupplier
|
|
}).ToListAsync();
|
|
|
|
var attrbutes = list.SelectMany(x => x.AttributeNames).Where(x => !string.IsNullOrEmpty(x)).Distinct();
|
|
var dicList = await Db.Queryable<SysDictData>().InnerJoin<SysDictType>((d, t) => d.TypeId == t.Id)
|
|
.Where((d, t) => t.Code == "infoclient-ArrclientTag" && attrbutes.Contains(d.Name))
|
|
.Select((d, t) => new
|
|
{
|
|
d.Name,
|
|
d.Value
|
|
}).ToListAsync();
|
|
|
|
var saleNames = list.Select(x => x.Sale);
|
|
var userNames = list.Select(x => x.Business)
|
|
.Union(list.Select(x => x.OP))
|
|
.Union(list.Select(x => x.CustomerService))
|
|
.Union(saleNames)
|
|
.Where(x => !string.IsNullOrEmpty(x))
|
|
.Distinct();
|
|
var users = await Db.Queryable<SysUser>().Where(x => userNames.Contains(x.UserName)).Select(x => new
|
|
{
|
|
x.Id,
|
|
x.UserName,
|
|
x.DefaultOrgId
|
|
}).ToListAsync();
|
|
|
|
List<InfoClient> newClients = new(list.Count);
|
|
List<InfoClient> existClients = [];
|
|
foreach (var model in list)
|
|
{
|
|
InfoClient? client = clients.Find(x => x.ShortName == model.ShortName && x.Description == model.CNName);
|
|
if (client != null)
|
|
{
|
|
client.IsSupplier = model.IsSupplier;
|
|
//client.Note = "系统导入";
|
|
existClients.Add(client);
|
|
continue;
|
|
}
|
|
|
|
client = new()
|
|
{
|
|
Address = model.Address,
|
|
AuditStatus = model.StatusText == "认证" ? AuditStatusEnum.Approve : AuditStatusEnum.NoAudit,
|
|
Status = model.StatusText == "认证" ? 0 : 1,
|
|
CodeName = model.Code,
|
|
Chief = model.LegalPerson,
|
|
CreateBy = userId,
|
|
CreateUserName = User.UserName,
|
|
CreateTime = dtNow,
|
|
Email = model.Email,
|
|
EnFullName = model.ENName,
|
|
EnShortName = model.ENName,
|
|
Grade = model.Class,
|
|
IsCustomer = model.IsCustomer,
|
|
IsSupplier = model.IsSupplier,
|
|
Country = model.Country,
|
|
OperatorId = users.Find(x => x.UserName == model.OP)?.Id,
|
|
OperatorName = users.Find(x => x.UserName == model.OP)?.UserName,
|
|
OrgId = (users.Find(x => x.UserName == model.Sale)?.DefaultOrgId).GetValueOrDefault(),
|
|
SaleOrgId = users.Find(x => x.UserName == model.Sale)?.DefaultOrgId.ToString(),
|
|
SaleId = users.Find(x => x.UserName == model.Sale)?.Id,
|
|
Sale = users.Find(x => x.UserName == model.Sale)?.UserName,
|
|
CustomerService = users.Find(x => x.UserName == model.CustomerService)?.Id,
|
|
CustomerServiceName = users.Find(x => x.UserName == model.CustomerService)?.UserName,
|
|
QQ = model.QQ,
|
|
ShortName = model.ShortName,
|
|
Description = model.CNName,
|
|
Tel = model.Tel,
|
|
IsOverdueDeduction = model.IsCustomer,
|
|
IsMortgageLastOrder = model.IsCustomer,
|
|
Note = "系统导入",
|
|
ClientTag = new InfoClientTag { IsController = model.IsCustomer },
|
|
AccountDates = []
|
|
};
|
|
|
|
if (model.AttributeNames.Length == 0)
|
|
{
|
|
client.ClientTag.IsOther = model.IsSupplier;
|
|
}
|
|
else
|
|
{
|
|
var dicValues = dicList.FindAll(x => model.AttributeNames.Contains(x.Name));
|
|
foreach (var item in dicValues)
|
|
{
|
|
var dicValue = item.Value.ToUpperCamelCase();
|
|
PropertyExtensions.SetPropertyValue(client.ClientTag, dicValue, true);
|
|
}
|
|
}
|
|
|
|
client.AccountDates.Add(new InfoClientAccountDate
|
|
{
|
|
AccountType = model.StlType,
|
|
BusinessType = ((int)BusinessType.OceanShippingExport).ToString(),
|
|
AllowAmount = model.Quota,
|
|
OrgId = client.OrgId,
|
|
CreateBy = userId,
|
|
CreateUserName = User.UserName,
|
|
CreateTime = dtNow,
|
|
});
|
|
|
|
newClients.Add(client);
|
|
}
|
|
|
|
|
|
await TenantDb.Ado.BeginTranAsync();
|
|
try
|
|
{
|
|
if (existClients.Count > 0)
|
|
await TenantDb.Updateable(existClients).UpdateColumns(x => new { x.IsCustomer, x.IsSupplier }).ExecuteCommandAsync();
|
|
|
|
await TenantDb.Fastest<InfoClient>().RemoveDataCache($"{SqlSugarCacheConst.InfoClient}{User.TenantId}").BulkMergeAsync(newClients);
|
|
foreach (var client in newClients)
|
|
{
|
|
client.ClientTag.ClientId = client.Id;
|
|
|
|
foreach (var item in client.AccountDates)
|
|
item.ClientId = client.Id;
|
|
}
|
|
|
|
var tags = newClients.Select(x => x.ClientTag).ToList();
|
|
await TenantDb.Fastest<InfoClientTag>().BulkMergeAsync(tags);
|
|
|
|
var accountDates = newClients.SelectMany(x => x.AccountDates).ToList();
|
|
await TenantDb.Fastest<InfoClientAccountDate>().BulkMergeAsync(accountDates);
|
|
|
|
await TenantDb.Ado.CommitTranAsync();
|
|
var result = DataResult.Success;
|
|
result.Message = $"新增往来单位:{newClients.Count}项,更新往来单位:{existClients.Count}项";
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
await TenantDb.Ado.RollbackTranAsync();
|
|
await ex.LogAsync(Db);
|
|
return DataResult.Failed("导入失败:" + ex.Message);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 列表
|
|
/// </summary>
|
|
/// <param name="request"></param>
|
|
/// <returns></returns>
|
|
public async Task<DataResult<List<ClientInfoRes>>> GetListAsync(PageRequest<ClientQuery> request)
|
|
{
|
|
//序列化查询条件
|
|
var whereList = request.GetConditionalModels(Db);
|
|
#region 数据权限
|
|
var queryData = TenantDb.Queryable<InfoClient>();
|
|
var conditions = new List<IConditionalModel>();
|
|
var otherConditions = new List<IConditionalModel>();
|
|
var scope = string.Empty;
|
|
(conditions, scope, otherConditions) = await commonService.GetSpecialVisibleDataRuleFilter<InfoClient>(queryData, TenantDb);
|
|
var userids = new List<string>();
|
|
if (otherConditions.Count > 0)
|
|
{
|
|
foreach (ConditionalTree item in otherConditions)
|
|
{
|
|
if (item.ConditionalList.Count > 0)
|
|
{
|
|
foreach (var item1 in item.ConditionalList)
|
|
{
|
|
var temp = item1.Value as ConditionalModel;
|
|
if (temp.FieldName == "Stakeholders")
|
|
{
|
|
userids = temp.FieldValue.Split(',').ToList();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (userids.Count == 0)
|
|
{
|
|
userids.Add(User.UserId);
|
|
}
|
|
#endregion
|
|
//干系人合集
|
|
var exp = Expressionable.Create<InfoClient>();
|
|
exp = exp.And(c => SqlFunc.Subqueryable<InfoClientStakeholder>().Where("SYSDATE() BETWEEN StartDate and EndDate").Where(x => userids.Contains(x.UserId.ToString()) && x.ClientId == c.Id).Any());
|
|
|
|
var queryData1 = TenantDb.Queryable<InfoClient>().ClearFilter<ISharedOrgId>().Where(exp.ToExpression());
|
|
var queryData2 = queryData.Where(conditions);
|
|
var queryData0 = TenantDb.UnionAll(queryData1, queryData2);
|
|
|
|
var query = queryData0//.Where(c => c.Status == StatusEnum.Enable.ToEnumInt())//TenantDb.Queryable<InfoClient>()
|
|
.LeftJoin<InfoClientContact>((c, c1) => c.Id == c1.ClientId)
|
|
.LeftJoin<InfoClientContract>((c, c1, c2) => c.Id == c2.ClientId)
|
|
.InnerJoinIF<InfoClientTag>(request.OtherQueryCondition?.ClientTag != null, (c, c1, c2, ct) => c.Id == ct.ClientId)
|
|
.GroupBy((c, c1, c2) => c.Id);
|
|
|
|
if (!string.IsNullOrEmpty(request.OtherQueryCondition?.ContactInfo))
|
|
query = query.Where((c, c1, c2) => c1.Tel.Contains(request.OtherQueryCondition.ContactInfo) ||
|
|
c1.Mobile.Contains(request.OtherQueryCondition.ContactInfo) || c1.Email.Contains(request.OtherQueryCondition.ContactInfo));
|
|
|
|
if (request.OtherQueryCondition != null && request.OtherQueryCondition.IsContractExpired.GetValueOrDefault())
|
|
query = query.Where((c, c1, c2) => SqlFunc.GetDate() > c2.EndDate);
|
|
|
|
if (request.OtherQueryCondition?.ClientTag != null)
|
|
{
|
|
//合并到主查询条件
|
|
var props = Array.FindAll(request.OtherQueryCondition.ClientTag.GetType().GetProperties(), x => x.Name.StartsWith("Is") && x.PropertyType == typeof(bool));
|
|
List<IConditionalModel> list = [];
|
|
foreach (var prop in props)
|
|
{
|
|
object val = prop.Get(request.OtherQueryCondition.ClientTag);
|
|
if (val != null && val is bool value && value)
|
|
{
|
|
list.Add(new ConditionalModel
|
|
{
|
|
ConditionalType = ConditionalType.Equal,
|
|
FieldName = "ct." + prop.Name,
|
|
FieldValue = "1"
|
|
});
|
|
}
|
|
}
|
|
|
|
query = query.Where(list);
|
|
}
|
|
#region 判断权限范围
|
|
if (scope == "all")
|
|
{
|
|
query = query.ClearFilter<ISharedOrgId>();
|
|
}
|
|
#endregion
|
|
var result = await query.Select((c, c1, c2, ct) => new ClientInfoRes
|
|
{
|
|
CodeName = c.CodeName,
|
|
Name = c.Name,
|
|
ShortName = c.ShortName,
|
|
EnShortName = c.EnShortName,
|
|
EnFullName = c.EnFullName
|
|
}, true).MergeTable().Distinct().Where(whereList).ToQueryPageAsync(request.PageCondition);
|
|
|
|
if (result.Data?.Count > 0)
|
|
{
|
|
var ids = result.Data.Select(x => x.Id);
|
|
var contacts = TenantDb.Queryable<InfoClientContact>().Where(x => ids.Contains(x.ClientId) && x.IsDefault)
|
|
.Select<ClientContactRes>().ToList();
|
|
|
|
var accountDates = TenantDb.Queryable<InfoClientAccountDate>().Where(x => ids.Contains(x.ClientId) && x.Id ==
|
|
SqlFunc.Subqueryable<InfoClientAccountDate>().Where(y => y.Id == x.Id).Select(y => SqlFunc.AggregateMax(y.Id))
|
|
).Select<ClientAccountDateRes>().ToList();
|
|
|
|
var ids2 = result.Data.SelectMany(x => x.SaleOrgIdList).Distinct();
|
|
var orgs = Db.Queryable<SysOrg>().Where(x => ids2.Contains(x.Id)).Select(x => new { x.Id, x.OrgName }).ToList();
|
|
|
|
foreach (var item in result.Data)
|
|
{
|
|
item.DefaultContact = contacts.Find(x => x.ClientId == item.Id);
|
|
item.LastAccountDate = accountDates.Find(x => x.ClientId == item.Id);
|
|
|
|
var list = orgs.FindAll(x => item.SaleOrgIdList.Contains(x.Id));
|
|
item.SaleOrgNames = string.Join(",", list.Select(x => x.OrgName));
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 列表
|
|
/// </summary>
|
|
/// <param name="request"></param>
|
|
/// <returns></returns>
|
|
public async Task<DataResult<List<ClientInfoRes>>> GetSupplierListAsync(PageRequest<ClientQuery> request)
|
|
{
|
|
//序列化查询条件
|
|
var whereList = request.GetConditionalModels(Db);
|
|
|
|
var query = TenantDb.Queryable<InfoClient>()
|
|
.LeftJoin<InfoClientContact>((c, c1) => c.Id == c1.ClientId)
|
|
.LeftJoin<InfoClientContract>((c, c1, c2) => c.Id == c2.ClientId)
|
|
.InnerJoinIF<InfoClientTag>(request.OtherQueryCondition?.ClientTag != null, (c, c1, c2, ct) => c.Id == ct.ClientId)
|
|
.GroupBy((c, c1, c2) => c.Id);
|
|
|
|
if (!string.IsNullOrEmpty(request.OtherQueryCondition?.ContactInfo))
|
|
query = query.Where((c, c1, c2) => c1.Tel.Contains(request.OtherQueryCondition.ContactInfo) ||
|
|
c1.Mobile.Contains(request.OtherQueryCondition.ContactInfo) || c1.Email.Contains(request.OtherQueryCondition.ContactInfo));
|
|
|
|
if (request.OtherQueryCondition != null && request.OtherQueryCondition.IsContractExpired.GetValueOrDefault())
|
|
query = query.Where((c, c1, c2) => SqlFunc.GetDate() > c2.EndDate);
|
|
|
|
if (request.OtherQueryCondition?.ClientTag != null)
|
|
{
|
|
//合并到主查询条件
|
|
var props = Array.FindAll(request.OtherQueryCondition.ClientTag.GetType().GetProperties(), x => x.Name.StartsWith("Is") && x.PropertyType == typeof(bool));
|
|
List<IConditionalModel> list = [];
|
|
foreach (var prop in props)
|
|
{
|
|
object val = prop.Get(request.OtherQueryCondition.ClientTag);
|
|
if (val != null && val is bool value && value)
|
|
{
|
|
list.Add(new ConditionalModel
|
|
{
|
|
ConditionalType = ConditionalType.Equal,
|
|
FieldName = "ct." + prop.Name,
|
|
FieldValue = "1"
|
|
});
|
|
}
|
|
}
|
|
|
|
query = query.Where(list);
|
|
}
|
|
//查询所有机构
|
|
query = query.ClearFilter<ISharedOrgId>();
|
|
var result = await query.Select((c, c1, c2, ct) => new ClientInfoRes
|
|
{
|
|
CodeName = c.CodeName,
|
|
Name = c.Name,
|
|
ShortName = c.ShortName,
|
|
EnShortName = c.EnShortName,
|
|
EnFullName = c.EnFullName
|
|
}, true).MergeTable().Where(whereList).ToQueryPageAsync(request.PageCondition);
|
|
|
|
if (result.Data?.Count > 0)
|
|
{
|
|
var ids = result.Data.Select(x => x.Id);
|
|
var contacts = TenantDb.Queryable<InfoClientContact>().Where(x => ids.Contains(x.ClientId) && x.IsDefault)
|
|
.Select<ClientContactRes>().ToList();
|
|
|
|
var accountDates = TenantDb.Queryable<InfoClientAccountDate>().Where(x => ids.Contains(x.ClientId) && x.Id ==
|
|
SqlFunc.Subqueryable<InfoClientAccountDate>().Where(y => y.Id == x.Id).Select(y => SqlFunc.AggregateMax(y.Id))
|
|
).Select<ClientAccountDateRes>().ToList();
|
|
|
|
var ids2 = result.Data.SelectMany(x => x.SaleOrgIdList).Distinct();
|
|
var orgs = Db.Queryable<SysOrg>().Where(x => ids2.Contains(x.Id)).Select(x => new { x.Id, x.OrgName }).ToList();
|
|
|
|
foreach (var item in result.Data)
|
|
{
|
|
item.DefaultContact = contacts.Find(x => x.ClientId == item.Id);
|
|
item.LastAccountDate = accountDates.Find(x => x.ClientId == item.Id);
|
|
|
|
var list = orgs.FindAll(x => item.SaleOrgIdList.Contains(x.Id));
|
|
item.SaleOrgNames = string.Join(",", list.Select(x => x.OrgName));
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 确定往来单位是否已使用
|
|
/// </summary>
|
|
/// <param name="ids">往来单位ID</param>
|
|
/// <returns></returns>
|
|
public async Task<DataResult<List<ClientUsage>>> GetUsageAsync(params long[] ids)
|
|
{
|
|
TenantDb.QueryFilter.Clear<ISharedOrgId>();
|
|
var list = await TenantDb.Queryable<InfoClient>().Where(x => ids.Contains(x.Id))
|
|
.Select(c => new ClientUsage
|
|
{
|
|
Id = c.Id,
|
|
Name = c.ShortName,
|
|
IsUsed = SqlFunc.Subqueryable<SeaExport>().Where(s => c.Id == s.CustomerId || c.Id == s.ForwarderId ||
|
|
c.Id == s.YardId || c.Id == s.ShipperCnId || c.Id == s.ContractClientId || c.Id == s.TruckerId ||
|
|
c.Id == s.AgentId || c.Id == s.ShipAgencyId || c.Id == s.CustomserId || c.Id == s.WareHouseId).Any() &&
|
|
|
|
SqlFunc.Subqueryable<FeeRecord>().Where(f => c.Id == f.CustomerId).Any() &&
|
|
SqlFunc.Subqueryable<CheckBill>().Where(f => c.Id == f.CustomerId).Any() &&
|
|
SqlFunc.Subqueryable<CheckBillAuto>().Where(f => c.Id == f.CustomerId).Any()
|
|
}).ToListAsync();
|
|
|
|
var result = DataResult<List<ClientUsage>>.Success(list);
|
|
result.Count = list.Count;
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 编辑
|
|
/// </summary>
|
|
/// <param name="req"></param>
|
|
/// <returns></returns>
|
|
public async Task<DataResult> EditAsync(ClientInfoReq req)
|
|
{
|
|
var data = req.Adapt<InfoClient>();
|
|
data.Status = (int)StatusEnum.Disable;
|
|
data.AuditStatus = AuditStatusEnum.NoAudit;
|
|
data.OrgId = User.OrgId;
|
|
|
|
if (string.IsNullOrEmpty(data.CodeName))
|
|
data.CodeName = PinYinUtil.GetFristLetter(data.ShortName); //助记码
|
|
|
|
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)
|
|
{
|
|
var tag = req.ClientTag.Adapt<InfoClientTag>();
|
|
var entity = await TenantDb.Insertable(data).ExecuteReturnEntityAsync();
|
|
tag.ClientId = entity.Id;
|
|
await TenantDb.Insertable(tag).RemoveDataCache($"{SqlSugarCacheConst.InfoClient}{User.TenantId}").ExecuteCommandAsync();
|
|
return DataResult.Successed("添加成功!", entity.Id, MultiLanguageConst.DataCreateSuccess);
|
|
}
|
|
else
|
|
{
|
|
var model = await TenantDb.Queryable<InfoClient>().ClearFilter<ISharedOrgId>().Where(x => x.Id == req.Id)
|
|
.Select(x => new
|
|
{
|
|
x.Status,
|
|
x.AuditStatus
|
|
}).FirstAsync();
|
|
if (model != null && model.AuditStatus == AuditStatusEnum.Auditing)
|
|
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.ItemsAreAuditing));
|
|
|
|
var tag = TenantDb.Queryable<InfoClientTag>().Where(x => x.ClientId == req.Id).First();
|
|
tag = req.ClientTag.Adapt(tag);
|
|
data.ServiceItem ??= string.Empty;
|
|
var updateable = TenantDb.Updateable(data).RemoveDataCache($"{SqlSugarCacheConst.InfoClient}{User.TenantId}")
|
|
.IgnoreColumns(x => new
|
|
{
|
|
x.OrgId,
|
|
x.Status,
|
|
x.ETD,
|
|
x.AuditStatus,
|
|
x.AuditNote,
|
|
x.AuditTime,
|
|
x.DeleteBy,
|
|
x.Deleted,
|
|
x.DeleteTime
|
|
});
|
|
|
|
var list = (await GetUsageAsync(req.Id))?.Data;
|
|
if (list != null && list.Exists(x => x.Id == req.Id && x.IsUsed))
|
|
updateable = updateable.IgnoreColumns(x => x.ShortName);
|
|
|
|
await updateable.ExecuteCommandAsync();
|
|
await TenantDb.Updateable(tag).IgnoreColumns(x => new
|
|
{
|
|
x.ClientId,
|
|
x.OrgId,
|
|
x.DeleteBy,
|
|
x.Deleted,
|
|
x.DeleteTime
|
|
}).ExecuteCommandAsync();
|
|
|
|
return DataResult.Successed("更新成功!", MultiLanguageConst.DataUpdateSuccess);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 检查客户信息是否重复
|
|
/// </summary>
|
|
/// <param name="req"></param>
|
|
/// <returns></returns>
|
|
public async Task<DataResult> IsAvailableAsync(ClientInfoReq req)
|
|
{
|
|
req.ShortName = req.ShortName.Trim();
|
|
req.Description = req.Description.Trim();
|
|
TenantDb.QueryFilter.ClearAndBackup<IOrgId>();
|
|
TenantDb.QueryFilter.ClearAndBackup<ISharedOrgId>();
|
|
|
|
var expr = Expressionable.Create<InfoClient>()
|
|
.And(x => x.ShortName == req.ShortName || x.Description == req.Description)
|
|
.AndIF(req.Id > 0, x => x.Id != req.Id);
|
|
|
|
var client = await TenantDb.Queryable<InfoClient>().Where(expr.ToExpression()).Select(x => new
|
|
{
|
|
ClientId = x.Id,
|
|
x.ShortName,
|
|
x.Description
|
|
}).FirstAsync();
|
|
if (client != null)
|
|
{
|
|
var result = DataResult.Failed("客户信息已存在,请检查客户全称/简称是否重复!", MultiLanguageConst.ClientInfoExist);
|
|
result.Code = ResultCode.Fail;
|
|
result.Data = client;
|
|
return result;
|
|
}
|
|
|
|
TenantDb.QueryFilter.Restore();
|
|
return DataResult.Success;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 详情
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public async Task<DataResult<ClientInfoRes>> GetAsync(long id)
|
|
{
|
|
TenantDb.QueryFilter.Clear<ISharedOrgId>();
|
|
var entity = await TenantDb.Queryable<InfoClient>().Where(a => a.Id == id).FirstAsync();
|
|
if (entity == null)
|
|
return DataResult<ClientInfoRes>.Success(null);
|
|
|
|
var data = entity.Adapt<ClientInfoRes>();
|
|
data.ServiceItemCodes = entity.ServiceItem?.Split(',', StringSplitOptions.RemoveEmptyEntries);
|
|
data.ClientTag = await TenantDb.Queryable<InfoClientTag>().Select<ClientTagRes>().FirstAsync(a => a.ClientId == id);
|
|
data.InvoiceHeaders ??= await TenantDb.Queryable<InvoiceHeader>().Where(x => x.RelativeId == data.Id).ToListAsync();
|
|
|
|
return DataResult<ClientInfoRes>.Success(data, MultiLanguageConst.DataQuerySuccess);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 批量删除发票抬头
|
|
/// </summary>
|
|
/// <param name="idModel"></param>
|
|
/// <returns></returns>
|
|
public async Task<DataResult> DeleteInvoiceHeaderAsync(IdModel idModel)
|
|
{
|
|
int rows = await TenantDb.Deleteable<InvoiceHeader>().Where(x => idModel.Ids.Contains(x.Id)).ExecuteCommandAsync();
|
|
return rows > 0 ? DataResult.Success : DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 批量删除
|
|
/// </summary>
|
|
/// <param name="req"></param>
|
|
/// <returns></returns>
|
|
public async Task<DataResult> DeleteAsync(IdModel req)
|
|
{
|
|
await TenantDb.Ado.BeginTranAsync();
|
|
try
|
|
{
|
|
var result = await GetUsageAsync(req.Ids);
|
|
if (result.Data != null && result.Data.Exists(x => x.IsUsed))
|
|
return DataResult.FailedWithDesc(MultiLanguageConst.ClientIsUsed);
|
|
|
|
//银行信息
|
|
await TenantDb.Deleteable<InfoClientBank>().Where(x => req.Ids.Contains(x.ClientId)).ExecuteCommandAsync();
|
|
//联系人
|
|
await TenantDb.Deleteable<InfoClientContact>().Where(x => req.Ids.Contains(x.ClientId)).ExecuteCommandAsync();
|
|
//合同信息
|
|
await TenantDb.Deleteable<InfoClientContract>().Where(x => req.Ids.Contains(x.ClientId)).ExecuteCommandAsync();
|
|
//账期
|
|
await TenantDb.Deleteable<InfoClientAccountDate>().Where(x => req.Ids.Contains(x.ClientId)).ExecuteCommandAsync();
|
|
//收发货人
|
|
await TenantDb.Deleteable<InfoClientShipper>().Where(x => req.Ids.Contains(x.ClientId)).ExecuteCommandAsync();
|
|
//删除客户信息
|
|
await TenantDb.Deleteable<InfoClient>().RemoveDataCache($"{SqlSugarCacheConst.InfoClient}{User.TenantId}").Where(x => req.Ids.Contains(x.Id)).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));
|
|
}
|
|
}
|
|
|
|
|
|
#region 获取往来单位详情(含有联系人列表)
|
|
/// <summary>
|
|
/// 获取往来单位详情(含有联系人列表)
|
|
/// </summary>
|
|
/// <param name="query">查询往来单位</param>
|
|
/// <returns>返回往来单位详情</returns>
|
|
public async Task<DataResult<ClientInfoRes>> GetClientInfoWithContact(QueryClientInfo query)
|
|
{
|
|
var data = await TenantDb.Queryable<InfoClient>().InnerJoin<InfoClientTag>((c, t) => c.Id == t.ClientId)
|
|
.Where((c, t) => c.Id == query.ClientId)
|
|
.WhereIF(query.IsController, (c, t) => t.IsController)
|
|
.WhereIF(query.IsCarrier, (c, t) => t.IsCarrier)
|
|
.WhereIF(query.IsBooking, (c, t) => t.IsBooking)
|
|
.WhereIF(query.IsYard, (c, t) => t.IsYard)
|
|
.WhereIF(query.IsTruck, (c, t) => t.IsTruck)
|
|
.WhereIF(query.IsCustom, (c, t) => t.IsCustom)
|
|
.WhereIF(query.IsAgent, (c, t) => t.IsAgent)
|
|
.WhereIF(query.IsAgentCn, (c, t) => t.IsAgentCn)
|
|
.WhereIF(query.IsExpress, (c, t) => t.IsExpress)
|
|
.WhereIF(query.IsAirLines, (c, t) => t.IsAirLines)
|
|
.WhereIF(query.IsShipper, (c, t) => t.IsShipper)
|
|
.WhereIF(query.IsConsignee, (c, t) => t.IsConsignee)
|
|
.WhereIF(query.IsNotifyParty, (c, t) => t.IsNotifyParty)
|
|
.WhereIF(query.IsWareHouse, (c, t) => t.IsWareHouse)
|
|
.WhereIF(query.IsWharf, (c, t) => t.IsWharf)
|
|
.WhereIF(query.IsInsurer, (c, t) => t.IsInsurer)
|
|
.WhereIF(query.IsLeasing, (c, t) => t.IsLeasing)
|
|
.WhereIF(query.IsTradingAgency, (c, t) => t.IsTradingAgency)
|
|
.WhereIF(query.IsOther, (c, t) => t.IsOther)
|
|
.WhereIF(!string.IsNullOrWhiteSpace(query.Others), (c, t) => t.Others == query.Others)
|
|
.WhereIF(query.IsShipAgency, (c, t) => t.IsShipAgency)
|
|
.WhereIF(query.IsEnterprise, (c, t) => t.IsEnterprise)
|
|
|
|
.Select((c, t) => new { Client = c, tag = t })
|
|
.FirstAsync();
|
|
|
|
var clientInfo = data.Client.Adapt<ClientInfoRes>();
|
|
|
|
clientInfo.ClientTag = data.tag.Adapt<ClientTagRes>();
|
|
|
|
var contactList = TenantDb.Queryable<InfoClientContact>()
|
|
.Where(a => a.ClientId == clientInfo.Id && a.Status == StatusEnum.Enable).ToList();
|
|
|
|
if (contactList.Count > 0)
|
|
clientInfo.ClientContactList = contactList.Adapt<List<ClientContactRes>>();
|
|
|
|
if (clientInfo == null)
|
|
return DataResult<ClientInfoRes>.FailedData(clientInfo);
|
|
|
|
return DataResult<ClientInfoRes>.Success(clientInfo);
|
|
}
|
|
#endregion
|
|
} |