You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

288 lines
15 KiB

using BBWYB.Common.Log;
using BBWYB.Common.Models;
using BBWYB.Server.Model;
using BBWYB.Server.Model.Db;
using BBWYB.Server.Model.Db.BBWY;
using BBWYB.Server.Model.Dto;
using FreeSql;
using Newtonsoft.Json;
using Yitter.IdGenerator;
namespace BBWYB.Server.Business
{
public class SkuOptimizationBusiness : BaseBusiness, IDenpendency
{
private FreeSqlMultiDBManager fsqlManager;
private VenderBusiness venderBusiness;
private TimeLimitRules timeLimitRules;
public SkuOptimizationBusiness(IFreeSql fsql, NLogManager nLogManager, IIdGenerator idGenerator, FreeSqlMultiDBManager fsqlManager, VenderBusiness venderBusiness, TimeLimitRules timeLimitRules) : base(fsql, nLogManager, idGenerator)
{
this.fsqlManager = fsqlManager;
this.venderBusiness = venderBusiness;
this.timeLimitRules = timeLimitRules;
}
public Enums.TriggerOptimizationReason? GetOptimizationReason(SpuTotalSaleInfo s)
{
if (s.IsFirstPurchaseCompleted == false)
return Enums.TriggerOptimizationReason.;
if (s.IsFirstPurchaseCompleted == true &&
s.IsFirstOptimizationCompleted == false &&
s.ItemCount - s.FirstPurchaseCompletedItemCount >= 20)
return Enums.TriggerOptimizationReason.;
if (s.IsFirstOptimizationCompleted == true && s.LastOptimizationItemCount != 0 && s.ItemCount * 1.0 / s.LastOptimizationItemCount >= 2)
return Enums.TriggerOptimizationReason.;
return null;
}
public void LKInventoryAlertNotification(BatchLKInventoryAlertRequest request)
{
nLogManager.Default().Info($"LKInventoryAlertNotification {JsonConvert.SerializeObject(request)}");
#region 确定JDSKU对应的拳探SKU和拳探SPU
var jdSkuIdList = request.Items.Select(x => x.Sku).Distinct().ToList();
var jdqtskuList = fsqlManager.BBWYCfsql.Select<PurchaseOrderSku>()
.Where(ps1 => ps1.ShopId == request.ShopId && jdSkuIdList.Contains(ps1.SkuId))
.GroupBy(ps1 => ps1.SkuId)
.WithTempQuery(g => new { MaxId = g.Max(g.Value.Id) })
.From<PurchaseOrderSku>()
.InnerJoin((ps1, ps2) => ps1.MaxId == ps2.Id)
.ToList((ps1, ps2) => ps2);
var qtSkuIdList = jdqtskuList.Select(x => x.PurchaseSkuIds).Distinct().ToList();
var productSkuList = fsql.Select<Model.Db.ProductSku>(qtSkuIdList).ToList();
var productIdList = productSkuList.Select(ps => ps.ProductId).Distinct().ToList();
var spuTotalInfoList = fsql.Select<SpuTotalSaleInfo>().Where(spi => productIdList.Contains(spi.ProductId)).ToList();
#endregion
//查询已存在未结束的优化任务
var dbSkuOptimizationTaskList = fsql.Select<SkuOptimizationTask>()
.Where(t => t.ShopId == request.ShopId &&
t.IsOptimizationCompleted == false &&
qtSkuIdList.Contains(t.SkuId))
.ToList();
//优化历史
var dbSkuOptimizationHistoryList = fsql.Select<SkuOptimizationHistory>()
.Where(s1 => s1.ShopId == request.ShopId && qtSkuIdList.Contains(s1.SkuId))
.GroupBy(s1 => s1.SkuId)
.WithTempQuery(g => new { MaxId = g.Max(g.Value.Id) })
.From<SkuOptimizationHistory>()
.InnerJoin((s1, s2) => s1.MaxId == s2.Id)
.ToList((s1, s2) => s2);
#region DB Operation
var insertSkuOptimizationTaskList = new List<SkuOptimizationTask>();
var insertSkuOptimizationChildTaskList = new List<SkuOptimizationChildTask>();
var insertTimeLimitTaskList = new List<TimeLimitTask>();
#endregion
var belongShop = venderBusiness.GetShopList(request.ShopId).FirstOrDefault();
if (belongShop == null)
throw new BusinessException("店铺不存在");
foreach (var reqItem in request.Items)
{
var qtsku = jdqtskuList.FirstOrDefault(x => x.SkuId == reqItem.Sku);
if (qtsku == null)
continue;
var qtskuId = qtsku.PurchaseSkuIds; //拳探skuId
if (dbSkuOptimizationTaskList.Any(s => s.SkuId == qtskuId)) //过滤未结束的sku
continue;
var productSku = productSkuList.FirstOrDefault(ps => ps.Id == qtskuId);
if (productSku == null)
continue;
var spuTotalInfo = spuTotalInfoList.FirstOrDefault(psi => psi.ProductId == productSku.ProductId); //spu销量
if (spuTotalInfo == null)
continue;
var reason = GetOptimizationReason(spuTotalInfo); //过滤不需要优化的spu
if (reason == null)
continue;
var skuOptimizationHistory = dbSkuOptimizationHistoryList.FirstOrDefault(h => h.SkuId == qtskuId);
#region 创建待议价任务
var skuOptimizationTask = new SkuOptimizationTask()
{
Id = idGenerator.NewLong(),
BelongShopName = belongShop.ShopName,
ShopId = productSku.ShopId,
CompletionTime = null,
CreateTime = DateTime.Now,
IsOptimizationCompleted = false,
IsPurchasementCompleted = false,
JDSkuId = reqItem.Sku,
PreItemCount = reqItem.PreItemCount,
ProductId = productSku.ProductId,
SafeWarningRemainingDay = reqItem.SafeWarningRemainingDay,
SkuId = qtskuId,
TriggerOptimizationReason = reason,
LastOptimizationRatio = skuOptimizationHistory?.OptimizationRatio ?? 0M,
LastPurchasePrice = skuOptimizationHistory?.CurrentPurchasePrice,
PrePurchasedAmount = (skuOptimizationHistory?.CurrentPurchasePrice ?? 0M) * reqItem.PreItemCount,
LastOptimizationTime = skuOptimizationHistory?.CreateTime
};
#endregion
#region 创建待优化子任务
{
var yijiagroups = venderBusiness.GetYiJiaGroup();
foreach (var department in yijiagroups)
{
var skuOptimizationChildTask = new SkuOptimizationChildTask()
{
Id = idGenerator.NewLong(),
BelongTeamId = department.Id,
BelongTeamName = department.DepartmentName,
CompletionTime = null,
IsOptimizationCompleted = false,
OptimizationTaskId = skuOptimizationTask.Id
};
insertSkuOptimizationChildTaskList.Add(skuOptimizationChildTask);
}
}
#endregion
#region 创建待优化限时任务
insertTimeLimitTaskList.Add(new TimeLimitTask()
{
Id = idGenerator.NewLong(),
CreateTme = DateTime.Now,
//ExpirationTime = DateTime.Now.AddDays(isFirst ? 2 : 1),
ExpirationTime = timeLimitRules.CalculateExpirationTime(Enums.TimeLimitTaskType., DateTime.Now.AddDays(reason == Enums.TriggerOptimizationReason. ? 1 : 0)),
//OrderId = o.OrderId,
//OrderSn = o.OrderSn,
ShopId = productSku.ShopId,
SkuId = qtskuId,
TaskType = Enums.TimeLimitTaskType.,
TaskId = skuOptimizationTask.Id,
Remark = reason.ToString()
});
#endregion
}
fsql.Transaction(() =>
{
if (insertSkuOptimizationTaskList.Count() > 0)
fsql.Insert(insertSkuOptimizationTaskList).ExecuteAffrows();
if (insertSkuOptimizationChildTaskList.Count() > 0)
fsql.Insert(insertSkuOptimizationChildTaskList).ExecuteAffrows();
if (insertTimeLimitTaskList.Count() > 0)
fsql.Insert(insertTimeLimitTaskList).ExecuteAffrows();
});
}
/// <summary>
/// 完成优化
/// </summary>
/// <param name="taskId"></param>
/// <param name="userId"></param>
/// <exception cref="BusinessException"></exception>
public void CompleteOptimization(long taskId, string userId)
{
#region 验证待议价任务
var optimazaionTask = fsql.Select<SkuOptimizationTask>(taskId).ToOne();
if (optimazaionTask == null)
throw new BusinessException("优化任务不存在");
if (optimazaionTask.IsOptimizationCompleted == true)
throw new BusinessException("优化任务已完成");
#endregion
#region 获取用户和部门信息
var user = fsqlManager.MDSfsql.Select<User>(userId).ToOne();
if (user == null)
throw new BusinessException("用户不存在");
if (string.IsNullOrEmpty(user.DepartmentId))
throw new BusinessException("该用户没有归属部门");
var department = fsqlManager.MDSfsql.Select<Userdepartment>(user.DepartmentId).ToOne();
if (department == null)
throw new BusinessException("部门不存在");
if (department.ParentDepartmentId != "1760971468360912896")
throw new BusinessException("该用户所在部门不属于议价组");
#endregion
#region 验证待议价子任务
var optimazaionChildTaskList = fsql.Select<SkuOptimizationChildTask>()
.Where(sc => sc.OptimizationTaskId == optimazaionTask.Id)
.ToList();
var currentOptimazaionChildTaskList = optimazaionChildTaskList.FirstOrDefault(sc => sc.BelongTeamId == department.Id);
if (currentOptimazaionChildTaskList == null)
throw new BusinessException($"未找到议价组{department.DepartmentName}的议价子任务");
if (currentOptimazaionChildTaskList.IsOptimizationCompleted == true)
throw new BusinessException($"{department.DepartmentName}的议价子任务已完成");
currentOptimazaionChildTaskList.IsOptimizationCompleted = true;
#endregion
IUpdate<SkuOptimizationChildTask> updateChildTask = null;
IUpdate<SkuOptimizationTask> updateTask = null;
IUpdate<SpuTotalSaleInfo> updateSpuSaleInfo = null;
IUpdate<TimeLimitTask> updateTimeLimitTask = null;
if (!optimazaionChildTaskList.Any(sc => sc.IsOptimizationCompleted == false))
{
//全部完成
#region 更新spu销量表
var spuSaleInfo = fsql.Select<SpuTotalSaleInfo>(optimazaionTask.ProductId).ToOne();
if (spuSaleInfo == null)
throw new BusinessException($"未找到spu{optimazaionTask.ProductId}销量");
updateSpuSaleInfo = fsql.Update<SpuTotalSaleInfo>(optimazaionTask.ProductId)
.SetIf(spuSaleInfo.IsFirstPurchaseCompleted == false, s => s.IsFirstPurchaseCompleted, true)
.SetIf(spuSaleInfo.IsFirstPurchaseCompleted == false, s => s.FirstPurchaseCompletedItemCount == s.ItemCount)
.SetIf(spuSaleInfo.IsFirstPurchaseCompleted == true &&
spuSaleInfo.IsFirstOptimizationCompleted == false, s => s.IsFirstOptimizationCompleted, true)
.SetIf(spuSaleInfo.IsFirstPurchaseCompleted == true &&
spuSaleInfo.IsFirstOptimizationCompleted == false, s => s.FirstOptimizationCompletedItemCount == s.ItemCount)
.Set(s => s.LastOptimizationItemCount == s.ItemCount)
.Set(s => s.LastOptimizationTime, DateTime.Now)
.Set(s => s.UpdateTime, DateTime.Now);
#endregion
#region 更新待议价任务
updateTask = fsql.Update<SkuOptimizationTask>(optimazaionTask.Id)
.Set(t => t.IsOptimizationCompleted, true)
.Set(t => t.CompletionTime, DateTime.Now);
#endregion
#region 更新待议价限时任务
updateTimeLimitTask = fsql.Update<TimeLimitTask>().Set(t => t.CompletionTime, DateTime.Now)
.Set(t => t.IsTimely == (DateTime.Now < t.ExpirationTime ? true : false))
.Where(t => t.TaskId == optimazaionTask.Id &&
t.CompletionTime == null &&
t.TaskType == Enums.TimeLimitTaskType.);
#endregion
}
#region 更新待议价子任务
updateChildTask = fsql.Update<SkuOptimizationChildTask>(currentOptimazaionChildTaskList.Id)
.Set(sc => sc.IsOptimizationCompleted, true)
.Set(sc => sc.CompletionTime, DateTime.Now);
#endregion
fsql.Transaction(() =>
{
updateChildTask?.ExecuteAffrows();
updateTask?.ExecuteAffrows();
updateSpuSaleInfo?.ExecuteAffrows();
updateTimeLimitTask?.ExecuteAffrows();
});
}
}
}