Browse Source

评选中标解决方案

liangku_skuoptimazation
shanji 1 year ago
parent
commit
d67339947d
  1. 17
      BBWYB.Server.API/Controllers/SkuOptimizationController.cs
  2. 149
      BBWYB.Server.Business/SkuOptimization/OptimizationBusiness.cs
  3. 3
      BBWYB.Server.Business/TaskSchedulerManager.cs
  4. 44
      BBWYB.Server.Business/TimeLimitTask/TimeLimitTaskBusiness.cs
  5. 13
      BBWYB.Server.Model/Db/SpuOptimization/Spuoptimizationcompetitivetendertask.cs
  6. 5
      BBWYB.Server.Model/Dto/Request/Optimization/BatchUpdateCompetitiveTenderQuotationRequest.cs
  7. 5
      BBWYB.Server.Model/Dto/Response/Optimization/MergePurchaseSchemeGroupResponse.cs
  8. 2
      BBWYB.Server.Model/Dto/Response/Optimization/MergePurchaseSchemeProductSkuResponse.cs
  9. 6
      BBWYB.Server.Model/Dto/Response/Optimization/MergePurchaserResponse.cs
  10. 5
      BBWYB.Server.Model/MappingProfiles.cs

17
BBWYB.Server.API/Controllers/SkuOptimizationController.cs

@ -1,5 +1,4 @@
using BBWYB.Common.Models;
using BBWYB.Server.Business;
using BBWYB.Server.Business;
using BBWYB.Server.Model.Dto;
using Microsoft.AspNetCore.Mvc;
@ -8,11 +7,11 @@ namespace BBWYB.Server.API.Controllers
public class SkuOptimizationController : BaseApiController
{
private SkuOptimizationBusiness skuOptimizationBusiness;
private OptimizationBusiness optimizationBusiness;
public SkuOptimizationController(IHttpContextAccessor httpContextAccessor, SkuOptimizationBusiness skuOptimizationBusiness) : base(httpContextAccessor)
public SkuOptimizationController(IHttpContextAccessor httpContextAccessor, OptimizationBusiness optimizationBusiness) : base(httpContextAccessor)
{
this.skuOptimizationBusiness = skuOptimizationBusiness;
this.optimizationBusiness = optimizationBusiness;
}
/// <summary>
@ -22,7 +21,7 @@ namespace BBWYB.Server.API.Controllers
[HttpPost]
public void LKInventoryAlertNotification([FromBody] BatchLKInventoryAlertRequest request)
{
skuOptimizationBusiness.LKInventoryAlertNotification(request);
optimizationBusiness.LKInventoryAlertNotification(request);
}
/// <summary>
@ -33,7 +32,7 @@ namespace BBWYB.Server.API.Controllers
public void CompleteOptimization([FromRoute] long taskId)
{
var userId = GetUserId();
skuOptimizationBusiness.CompleteOptimization(taskId, userId);
optimizationBusiness.CompleteOptimization(taskId, userId);
}
/// <summary>
@ -42,10 +41,10 @@ namespace BBWYB.Server.API.Controllers
/// <param name="request"></param>
/// <returns></returns>
[HttpPost]
public ListResponse<SkuOptimizationTaskResponse> GetNoCompletionSkuOptimizationTask([FromBody] PageRequest request)
public ListResponse<SpuOptimizationTaskResponse> GetNoCompletionSkuOptimizationTask([FromBody] QueryNoCompletionOptimizationTaskRequest request)
{
var userId = GetUserId();
return skuOptimizationBusiness.GetNoCompletionSkuOptimizationTask(request, userId);
return optimizationBusiness.GetNoCompletionSkuOptimizationTask(request, userId);
}
}
}

149
BBWYB.Server.Business/SkuOptimization/SkuOptimizationBusiness.cs → BBWYB.Server.Business/SkuOptimization/OptimizationBusiness.cs

@ -7,8 +7,7 @@ using BBWYB.Server.Model.Db.BBWY;
using BBWYB.Server.Model.Dto;
using FreeSql;
using Newtonsoft.Json;
using Org.BouncyCastle.Tls.Crypto;
using System.Linq;
using System.Numerics;
using Yitter.IdGenerator;
namespace BBWYB.Server.Business
@ -414,8 +413,8 @@ namespace BBWYB.Server.Business
throw new BusinessException("待优化任务已完成");
var spuOptimizationBargainTeamTaskList = fsql.Select<SpuOptimizationBargainTeamTask>()
.Where(sbt => sbt.SpuOptimizationTaskId == taskId && sbt.BelongTeamId == uInfo.department.Id)
.ToList();
.Where(sbt => sbt.SpuOptimizationTaskId == taskId)
.ToList();
var currentspuOptimizationBargainTeamTask = spuOptimizationBargainTeamTaskList.FirstOrDefault(sc => sc.BelongTeamId == uInfo.department.Id);
if (currentspuOptimizationBargainTeamTask == null)
throw new BusinessException($"未找到议价组{uInfo.department.DepartmentName}的议价子任务");
@ -426,35 +425,43 @@ namespace BBWYB.Server.Business
.Where(s => s.SpuOptimizationTaskId == taskId)
.ToList(s => s.SkuId);
//查询该议价组的竞标任务
var competitiveTenderTaskList = fsql.Select<SpuOptimizationCompetitiveTenderTask>()
.Where(ct => ct.BargainTeamId == uInfo.user.DepartmentId &&
ct.SpuOptimizationTaskId == taskId)
.ToList();
var competitiveTenderSchemeIdList = competitiveTenderTaskList.Select(ct => ct.SchemeId.Value).ToList();
//查询全部竞标任务
var allBargainTeamCompetitiveTenderTaskList = fsql.Select<SpuOptimizationCompetitiveTenderTask>()
.Where(ct => ct.SpuOptimizationTaskId == taskId)
.ToList();
//查询当前议价组的竞标任务
var currentBargainTeamCompetitiveTenderTaskList = allBargainTeamCompetitiveTenderTaskList.Where(ct => ct.BargainTeamId == uInfo.department.Id).ToList();
if (currentBargainTeamCompetitiveTenderTaskList.Count() == 0)
throw new BusinessException($"议价组{uInfo.department.DepartmentName}没有参与竞标的采购方案,不能完成优化任务");
var currentBargainTeamCompetitiveTenderSchemeIdList = currentBargainTeamCompetitiveTenderTaskList.Select(ct => ct.SchemeId).ToList();
#region 验证该议价组的符合sku条件的采购方案是否都参与投标
var waitCheckPurchaseSchemeIdList = fsql.Select<PurchaseScheme>()
.Where(ps => ps.BelongBargainTeamId == uInfo.user.DepartmentId &&
skuIdList.Contains(ps.SkuId))
.ToList(ps => ps.Id);
//验证该议价组的符合sku条件的采购方案是否都参与投标
var purchaseSchemeIdList = fsql.Select<PurchaseScheme>().Where(ps => ps.BelongBargainTeamId == uInfo.user.DepartmentId &&
skuIdList.Contains(ps.SkuId))
.ToList(ps => ps.Id);
if (purchaseSchemeIdList.Count() == 0)
if (waitCheckPurchaseSchemeIdList.Count() == 0)
throw new BusinessException($"议价组{uInfo.department.DepartmentName}没有参与竞标的采购方案,不能完成优化任务");
var noJoinCompetitiveTenderSchemeIdList = purchaseSchemeIdList.Except(competitiveTenderSchemeIdList);
var noJoinCompetitiveTenderSchemeIdList = waitCheckPurchaseSchemeIdList.Except(currentBargainTeamCompetitiveTenderSchemeIdList);
if (noJoinCompetitiveTenderSchemeIdList.Count() > 0)
throw new BusinessException($"议价组{uInfo.department.DepartmentName}存在{noJoinCompetitiveTenderSchemeIdList.Count()}个符合条件但未参与竞标的采购方案");
#endregion
//验证该议价组参与投标的采购方案是否都完成报价
if (competitiveTenderTaskList.Any(ct => ct.IsUpdateQuotedPrice == false))
#region 验证该议价组参与投标的采购方案是否都完成报价
if (currentBargainTeamCompetitiveTenderTaskList.Any(ct => ct.IsUpdateQuotedPrice == false))
throw new BusinessException($"议价组{uInfo.department.DepartmentName}存在未更新报价的投标");
#endregion
currentspuOptimizationBargainTeamTask.IsOptimizationCompleted = true;
#endregion
IUpdate<SpuOptimizationBargainTeamTask> updateBargainTask = null;
IUpdate<SpuOptimizationTask> updateSpuTask = null;
IUpdate<SpuTotalSaleInfo> updateSpuSaleInfo = null;
IUpdate<TimeLimitTask> updateTimeLimitTask = null;
IUpdate<SpuOptimizationCompetitiveTenderTask> updateCompetitiveTenderTask = null;
if (!spuOptimizationBargainTeamTaskList.Any(sc => sc.IsOptimizationCompleted == false))
{
@ -491,12 +498,26 @@ namespace BBWYB.Server.Business
t.CompletionTime == null &&
t.TaskType == Enums.TimeLimitTaskType.);
#endregion
#region 评选中标结果
var allBargainTeamCompetitiveTenderSchemeIdList = allBargainTeamCompetitiveTenderTaskList.Select(ct => ct.SchemeId).ToList();
var allBargainTeamPurchaseSchemeList = purchaseSchemeBusiness.GetPurchaseSchemeList(new QuerySchemeRequest()
{
BargainTeamIdList = new List<string>() { uInfo.user.DepartmentId },
SkuIdList = skuIdList,
IncludePurchaseSkuBasicInfo = 0
});
var victoryCompetitiveTenderTaskList = VictoryPlanSelection(allBargainTeamCompetitiveTenderTaskList, allBargainTeamPurchaseSchemeList);
var victoryCompetitiveTenderTaskIdList = victoryCompetitiveTenderTaskList.Select(ct => ct.Id).ToList();
updateCompetitiveTenderTask = fsql.Update<SpuOptimizationCompetitiveTenderTask>(victoryCompetitiveTenderTaskIdList)
.Set(ct => ct.IsWin, true);
#endregion
}
#region 更新待优化议价组任务
updateBargainTask = fsql.Update<SpuOptimizationBargainTeamTask>(currentspuOptimizationBargainTeamTask.Id)
.Set(sc => sc.IsOptimizationCompleted, true)
.Set(sc => sc.CompletionTime, DateTime.Now);
.Set(sc => sc.IsOptimizationCompleted, true)
.Set(sc => sc.CompletionTime, DateTime.Now);
#endregion
fsql.Transaction(() =>
@ -505,9 +526,17 @@ namespace BBWYB.Server.Business
updateBargainTask?.ExecuteAffrows();
updateSpuSaleInfo?.ExecuteAffrows();
updateTimeLimitTask?.ExecuteAffrows();
updateCompetitiveTenderTask?.ExecuteAffrows();
});
}
/// <summary>
/// 查询待优化任务
/// </summary>
/// <param name="request"></param>
/// <param name="userId"></param>
/// <returns></returns>
/// <exception cref="BusinessException"></exception>
public ListResponse<SpuOptimizationTaskResponse> GetNoCompletionSkuOptimizationTask(QueryNoCompletionOptimizationTaskRequest request, string userId)
{
request.EndTime = request.EndTime.Date;
@ -568,6 +597,11 @@ namespace BBWYB.Server.Business
});
#endregion
#region 获取采购方案分组
var purchaseSchemeGroupIdList = purchaseSchemeList.Select(ps => ps.SchemeGroupId).Distinct().ToList();
var purchaseSchemeGroupList = fsql.Select<PurchaseSchemeGroup>(purchaseSchemeGroupIdList).ToList<PurchaseSchemeGroupResponse>();
#endregion
foreach (var task in taskList)
{
task.BargainTeamTaskList = bargainTeamTaskList.Where(sbt => sbt.SpuOptimizationTaskId == task.Id).ToList();
@ -579,8 +613,47 @@ namespace BBWYB.Server.Business
#region 合并分组/采购商/配件
var currentTaskSkuIdList = task.SkuOptimizationTaskList.Select(st => st.SkuId).ToList();
var currentPurchaseSchemeList = purchaseSchemeList.Where(p => currentTaskSkuIdList.Contains(p.SkuId) &&
p.BelongBargainTeamId == uInfo.department.Id).ToList();
var currentPurchaseSchemeGroups = purchaseSchemeList.Where(p => currentTaskSkuIdList.Contains(p.SkuId) &&
p.BelongBargainTeamId == uInfo.department.Id)
.GroupBy(p => p.SchemeGroupId)
.ToList();
task.MergePurchaseScemeGroupList = new List<MergePurchaseSchemeGroupResponse>();
foreach (var schemeGroup in currentPurchaseSchemeGroups)
{
var mergeSchemeGroup = new MergePurchaseSchemeGroupResponse()
{
Id = schemeGroup.Key,
GroupName = purchaseSchemeGroupList.FirstOrDefault(g => g.Id == schemeGroup.Key)?.GroupName
};
task.MergePurchaseScemeGroupList.Add(mergeSchemeGroup);
var schemeList = schemeGroup.ToList();
foreach (var scheme in schemeList)
{
foreach (var psp in scheme.PurchaseSchemeProductList)
{
var mergePurchaser = mergeSchemeGroup.PurchaserList.FirstOrDefault(p => p.Id == psp.PurchaserId);
if (mergePurchaser == null)
{
mergePurchaser = scheme.PurchaserList.FirstOrDefault(p => p.Id == psp.PurchaserId)?.Map<MergePurchaserResponse>();
if (mergePurchaser == null)
throw new BusinessException($"匹配采购商异常 schemeId {scheme.Id} pspProductId {psp.ProductId}");
mergeSchemeGroup.PurchaserList.Add(mergePurchaser);
}
foreach (var pss in psp.PurchaseSchemeProductSkuList)
{
var mergePss = mergePurchaser.MergePurchaseSchemeProductSkuList.FirstOrDefault(mpss => mpss.PurchaseSkuId == pss.PurchaseSkuId);
if (mergePss == null)
{
mergePss = pss.Map<MergePurchaseSchemeProductSkuResponse>();
mergePss.PurchaserId = mergePurchaser.Id;
mergePurchaser.MergePurchaseSchemeProductSkuList.Add(mergePss);
}
}
}
}
}
#endregion
}
@ -590,5 +663,35 @@ namespace BBWYB.Server.Business
TotalCount = total
};
}
/// <summary>
/// 评选结果
/// </summary>
/// <param name="competitiveTenderTaskList"></param>
/// <param name="purchaseSchemeList"></param>
/// <returns></returns>
private IList<SpuOptimizationCompetitiveTenderTask> VictoryPlanSelection(IList<SpuOptimizationCompetitiveTenderTask> competitiveTenderTaskList,
IList<PurchaseSchemeResponse> purchaseSchemeList)
{
var victoryList = new List<SpuOptimizationCompetitiveTenderTask>();
var psGroups = purchaseSchemeList.GroupBy(ps => ps.SkuId);
foreach (var psGroup in psGroups)
{
var psListOrderByCostDescList = psGroup.OrderByDescending(ps => ps.BargainingCost ?? ps.DefaultCost).ToList();
var minCostScheme = psListOrderByCostDescList.FirstOrDefault();
var competitiveTenderTask = competitiveTenderTaskList.FirstOrDefault(ct => ct.SchemeId == minCostScheme.Id);
victoryList.Add(competitiveTenderTask);
}
return victoryList;
}
/// <summary>
/// 限时任务超时回调
/// </summary>
/// <param name="taskId"></param>
public void TimeLimitTaskTimeOutCallBack(long taskId)
{
}
}
}

3
BBWYB.Server.Business/TaskSchedulerManager.cs

@ -11,12 +11,15 @@ namespace BBWYB.Server.Business
public LimitedConcurrencyLevelTaskScheduler AggregationPurchaserTaskScheduler { get; private set; }
public LimitedConcurrencyLevelTaskScheduler OptimizationTaskScheduler { get; private set; }
public TaskSchedulerManager()
{
SyncOrderTaskScheduler = new LimitedConcurrencyLevelTaskScheduler(10);
PurchaseOrderCallbackTaskScheduler = new LimitedConcurrencyLevelTaskScheduler(10);
SyncProductTaskScheduler = new LimitedConcurrencyLevelTaskScheduler(10);
AggregationPurchaserTaskScheduler = new LimitedConcurrencyLevelTaskScheduler(1);
OptimizationTaskScheduler = new LimitedConcurrencyLevelTaskScheduler(3);
}
}
}

44
BBWYB.Server.Business/TimeLimitTask/TimeLimitTaskBusiness.cs

@ -3,19 +3,32 @@ using BBWYB.Common.Models;
using BBWYB.Server.Model;
using BBWYB.Server.Model.Db;
using BBWYB.Server.Model.Dto;
using Microsoft.Extensions.DependencyInjection;
using Yitter.IdGenerator;
namespace BBWYB.Server.Business
{
public class TimeLimitTaskBusiness : BaseBusiness, IDenpendency
{
private VenderBusiness venderBusiness;
private List<Enums.TimeLimitTaskType?> hgzTaskTypeList;
private TimeLimitRules timeLimitRules;
private IServiceProvider serviceProvider;
private Lazy<OptimizationBusiness> optimizationBusinessLazy;
private Lazy<VenderBusiness> venderBusinessLazy;
private Lazy<TaskSchedulerManager> taskSchedulerManagerLazy;
private OptimizationBusiness optimizationBusiness => optimizationBusinessLazy.Value;
private VenderBusiness venderBusiness => venderBusinessLazy.Value;
private TaskSchedulerManager taskSchedulerManager => taskSchedulerManagerLazy.Value;
public TimeLimitTaskBusiness(IFreeSql fsql, NLogManager nLogManager, IIdGenerator idGenerator, VenderBusiness venderBusiness, TimeLimitRules timeLimitRules) : base(fsql, nLogManager, idGenerator)
public TimeLimitTaskBusiness(IFreeSql fsql, NLogManager nLogManager, IIdGenerator idGenerator, VenderBusiness venderBusiness, TimeLimitRules timeLimitRules, IServiceProvider serviceProvider) : base(fsql, nLogManager, idGenerator)
{
this.venderBusiness = venderBusiness;
this.serviceProvider = serviceProvider;
this.optimizationBusinessLazy = new Lazy<OptimizationBusiness>(() => serviceProvider.GetRequiredService<OptimizationBusiness>());
this.venderBusinessLazy = new Lazy<VenderBusiness>(() => serviceProvider.GetRequiredService<VenderBusiness>());
this.taskSchedulerManagerLazy = new Lazy<TaskSchedulerManager>(() => serviceProvider.GetRequiredService<TaskSchedulerManager>());
hgzTaskTypeList = new List<Enums.TimeLimitTaskType?>()
{
Enums.TimeLimitTaskType.,
@ -25,10 +38,27 @@ namespace BBWYB.Server.Business
}
public void CheckTask()
{
fsql.Update<TimeLimitTask>().Set(t => t.IsTimely, false)
.Where(t => t.CompletionTime == null)
.Where(t => t.ExpirationTime < DateTime.Now)
.ExecuteAffrows();
//fsql.Update<TimeLimitTask>().Set(t => t.IsTimely, false)
// .Where(t => t.CompletionTime == null)
// .Where(t => t.ExpirationTime < DateTime.Now)
// .ExecuteAffrows();
var timeoutTaskList = fsql.Select<TimeLimitTask>().Where(t => t.CompletionTime == null && t.ExpirationTime < DateTime.Now).ToList();
if (timeoutTaskList.Count() > 0)
{
var timeoutTaskIdList = timeoutTaskList.Select(t => t.Id).ToList();
fsql.Update<TimeLimitTask>(timeoutTaskIdList).Set(t => t.IsTimely, false).ExecuteAffrows();
}
var optimizationTaskList = timeoutTaskList.Where(t => t.TaskType == Enums.TimeLimitTaskType.).ToList();
if (optimizationTaskList.Count() > 0)
{
//待议价任务超时检查
foreach (var task in optimizationTaskList)
{
Task.Factory.StartNew(() => optimizationBusiness.TimeLimitTaskTimeOutCallBack(task.TaskId), CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.OptimizationTaskScheduler);
}
}
}
/// <summary>

13
BBWYB.Server.Model/Db/SpuOptimization/Spuoptimizationcompetitivetendertask.cs

@ -40,7 +40,7 @@ namespace BBWYB.Server.Model.Db
/// 采购方案Id
/// </summary>
[Column(DbType = "bigint")]
public long? SchemeId { get; set; }
public long SchemeId { get; set; }
[Column(StringLength = 50)]
public string SkuId { get; set; }
@ -57,6 +57,17 @@ namespace BBWYB.Server.Model.Db
[Column(DbType = "bigint")]
public long SpuOptimizationTaskId { get; set; }
/// <summary>
/// 是否中标
/// </summary>
[Column(DbType = "bit")]
public bool IsWin { get; set; } = false;
/// <summary>
/// 运费
/// </summary>
public decimal? Freight { get; set; } = 0.00M;
}
}

5
BBWYB.Server.Model/Dto/Request/Optimization/BatchUpdateCompetitiveTenderQuotationRequest.cs

@ -16,6 +16,11 @@
/// 配件列表
/// </summary>
public IList<BatchUpdateCompetitiveTenderQuotationItemRequest> ItemList { get; set; }
/// <summary>
/// 运费
/// </summary>
public decimal Freight { get; set; }
}
public class BatchUpdateCompetitiveTenderQuotationItemRequest

5
BBWYB.Server.Model/Dto/Response/Optimization/MergePurchaseSchemeGroupResponse.cs

@ -2,6 +2,11 @@
{
public class MergePurchaseSchemeGroupResponse
{
public MergePurchaseSchemeGroupResponse()
{
PurchaserList = new List<MergePurchaserResponse>();
}
/// <summary>
/// 分组Id
/// </summary>

2
BBWYB.Server.Model/Dto/Response/Optimization/MergePurchaseSchemeProductSkuResponse.cs

@ -3,7 +3,7 @@
/// <summary>
/// 合并配件信息
/// </summary>
public class MergePurchaseSchemeProductSkuResponse : PurchaseSchemeProductSkuResponse
public class MergePurchaseSchemeProductSkuResponse
{
/// <summary>
/// 采购商Id

6
BBWYB.Server.Model/Dto/Response/Optimization/MergePurchaserResponse.cs

@ -4,6 +4,10 @@ namespace BBWYB.Server.Model.Dto
{
public class MergePurchaserResponse : Purchaser
{
public List<MergePurchaseSchemeProductSkuResponse> PurchaseSchemeProductSkuList { get; set; }
public MergePurchaserResponse()
{
MergePurchaseSchemeProductSkuList = new List<MergePurchaseSchemeProductSkuResponse>();
}
public List<MergePurchaseSchemeProductSkuResponse> MergePurchaseSchemeProductSkuList { get; set; }
}
}

5
BBWYB.Server.Model/MappingProfiles.cs

@ -62,9 +62,8 @@ namespace BBWYB.Server.Model
CreateMap<BatchUpdateCompetitiveTenderQuotationRequest, BatchEditPurchaseSkuActualPriceRequest>();
CreateMap<PurchaserResponse, MergePurchaserResponse>();
CreateMap<PurchaseSchemeProductSkuResponse, MergePurchaseSchemeProductSkuResponse>();
}
}
}

Loading…
Cancel
Save