Files
YunTongJackYunTask/Reportapi/MyCode.Project.Services/BaoDianBLL/NewMemberPlanCalBLL.cs
2025-07-04 09:50:02 +08:00

271 lines
11 KiB
C#

using MyCode.Project.Domain.Message.Response.BaoDian;
using MyCode.Project.Domain.Model;
using MyCode.Project.Domain.Repositories;
using MyCode.Project.Infrastructure.Common;
using MyCode.Project.Infrastructure.Constant;
using MyCode.Project.Infrastructure.Enumeration;
using MyCode.Project.Infrastructure.Extensions;
using MyCode.Project.Repositories.Common;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyCode.Project.Services.BLL
{
public class NewMemberPlanCalBLL:CommonPlanCalBLL
{
#region
private readonly ILxmNewMemberSalesScheduleRepository _lxmNewMemberSalesScheduleRepository;
private readonly ILxmSheetItemRepository _lxmSheetItemRepository;
public NewMemberPlanCalBLL(IRepository repository,
ILxmNewMemberSalesScheduleRepository lxmNewMemberSalesScheduleRepository,
ILxmSheetItemRepository lxmSheetItemRepository) :base(repository)
{
_lxmNewMemberSalesScheduleRepository = lxmNewMemberSalesScheduleRepository;
_lxmSheetItemRepository = lxmSheetItemRepository;
}
#endregion
#region Run(id来运算)
/// <summary>
/// 根据订单id来运算
/// </summary>
/// <param name="objSheetId"></param>
[TransactionCallHandler]
public void Run(object objSheetId)
{
//初始化
base.Init(objSheetId.ToString());
//预转销订单不处理
var checkResult = base.CheckPassed(PlanType.NewMemberSalesPlan);
if (!checkResult) { return; }
//先删掉可以保证该方法不断的被调用计算
_repository.Delete<BdOrderPlan>(p => p.OrderId == SheetId && p.PlanType == (int)PlanType.NewMemberSalesPlan);
//得到该订单中的商品明细
var sheetItems = _repository.Queryable<LxmSheetItem>().Where(p => p.SalesSheetId == SheetId).WithCache(100).ToList();
if (Sheet.Direct == 1)
{
//查看当月的该店员新客套餐计划
var newClerkMemberPlans = _repository
.Queryable<BdClerkNewMemberSalesPlan>()
.Where(p => p.Status == 1 && p.VersionTime == VersionTime && p.PlanQty > 0 && p.ShopId == Sheet.ShopId)
.WhereIF(Sheet.OrderClerkId == null, p => p.ClerkId == null)
.WhereIF(Sheet.OrderClerkId != null, p => p.ClerkId == Sheet.OrderClerkId)
.WithCache(3600)
.ToList();
//没有制定任何的计划
if (newClerkMemberPlans == null || newClerkMemberPlans.Count == 0) { return; }
var productIds = newClerkMemberPlans.Select(p => p.ProductId.Value).Distinct().ToList();
var planSkusAndServices = _lxmNewMemberSalesScheduleRepository.GetPackageProductOrServiceList(productIds);
//var matchSku = planSkusAndServices.FindAll(p => p.Id == 2311091518159431);
var clerkPlanIds = newClerkMemberPlans.Select(p => p.ProductId).ToList();
//移除没有用到的计划
planSkusAndServices.RemoveAll(p => !clerkPlanIds.Contains(p.Id));
CalNormalOrder(newClerkMemberPlans, planSkusAndServices, sheetItems);
}
else
{
CalRefundOrder(sheetItems);
}
}
#endregion
#region CalRefundOrder(退)
/// <summary>
/// 如果是退款单
/// </summary>
private void CalRefundOrder(List<LxmSheetItem> listNorMalSheetItem)
{
if (Sheet.SourceOrderId == null)
{
LogHelper.Info($"[新客运算]退款单={Sheet.Id}找不到原始订单");
return;
}
var sourceOrderId = Sheet.SourceOrderId;
//判断原始销售单是否当月,如果不是当月,则跳出
var sourceOrder = GetSourceSimpleOrder(Sheet.SourceOrderId);
if (sourceOrder.OrderPreorderId != null) { sourceOrderId = sourceOrder.OrderPreorderId; }
var sheetOrderMonthFirstDay = Sheet.CreateTime.Value.GetFirstDayOfMonth();
if (sourceOrder.CreateTime.Value.GetFirstDayOfMonth() != sheetOrderMonthFirstDay)
{
LogHelper.Info($"[新客运算]退款单={Sheet.Id}的原始订单={Sheet.SourceOrderId}非当月,新客计划不运算");
return;
}
var sourceItemQty = _repository.Queryable<LxmSheetItem>().Where(p => p.SalesSheetId == sourceOrderId).Select(p => SqlFunc.AggregateSum(p.Qty)).First();
var sheetTime = Sheet.CreateTime.Value;
//判断当前是否是全退,如果是全退,则当月的需要写一条反的数据,根据退的商品的数量;
//先得到当月1号到今天该订单退的情况
//var refundQty = _lxmSheetItemRepository.GetRefundQty(Sheet.SourceOrderId, sheetOrderMonthFirstDay, Sheet.CreateTime.Value);
var refundQty = _lxmSheetItemRepository.GetRefundQty(sourceOrderId, sheetOrderMonthFirstDay, Sheet.CreateTime.Value.AddSeconds(1));
//只是部分退而已
if (sourceItemQty != refundQty)
{
LogHelper.Info($"[新客运算]退款单={Sheet.Id}只是部分退,不用写反向数据");
return;
}
//全退了,写反向的数据
var orderPlans = _repository.Queryable<BdOrderPlan>()
.Where(p => p.OrderId == Sheet.SourceOrderId
&& p.OrderTime >= sheetOrderMonthFirstDay
&& p.OrderTime <= Sheet.CreateTime.Value
&& p.PlanType == (int)PlanType.NewMemberSalesPlan)
.ToList();
orderPlans.RemoveAll(p => ( p.PackageId == (int)PlanProductId.FirstOrderQty || p.PackageId == (int)PlanProductId.NewMemberQty));
if (orderPlans == null || orderPlans.Count == 0) { return; }
var insertOrderPlans = new List<BdOrderPlan>();
foreach (var plan in orderPlans)
{
var insertOrderPlan = new BdOrderPlan() {
Id = IdHelper.GetNewId(),
OrderId = SheetId,
OrderTime = Sheet.CreateTime.Value,
PackageId = plan.PackageId,
PackageName = plan.PackageName,
PlanId = plan.PlanId,
PlanType = plan.PlanType,
Qty = -plan.Qty,
UpdateTime = DateTime.Now,
SourceOrderId = sourceOrderId,
Info = $"原始订单id={Sheet.SourceOrderId}全退导致[新客运算]产生反向流水"
};
insertOrderPlans.Add(insertOrderPlan);
}
_repository.Add<BdOrderPlan>(insertOrderPlans);
}
#endregion
#region CalNormalOrder()
/// <summary>
/// 计算正常的订单
/// </summary>
/// <param name="listClerkPlan"></param>
/// <param name="listPackage"></param>
/// <param name="listSheetItem"></param>
private void CalNormalOrder(List<BdClerkNewMemberSalesPlan> listClerkPlan, List<PackageListResp> listPackage, List<LxmSheetItem> listSheetItem)
{
var lxmFirstShopOrder = _repository
.Queryable<LxmSheet>()
.Where(p => p.MemberId == Sheet.MemberId && p.ShopId == Sheet.ShopId)
.OrderBy(p => p.CreateTime)
.Select(p => new { p.Id })
.First();
//只要满足一个就符合计划,这里当时正向的,就是不是退款的情况的
foreach (var clerkPlan in listClerkPlan)
{
var orderPlan = new BdOrderPlan()
{
Id = IdHelper.GetNewId(),
OrderId = Sheet.Id,
OrderTime = Sheet.CreateTime.Value,
PackageId = clerkPlan.ProductId.Value,
PackageName = clerkPlan.Name,
PlanId = clerkPlan.Id,
PlanType = (int)PlanType.NewMemberSalesPlan,
Qty = 1,
UpdateTime = DateTime.Now,
SourceOrderId = Sheet.Id
};
if (clerkPlan.ProductId == (int)PlanProductId.FirstOrderQty)
{
if (Sheet.IsFirstOrder == 1 && clerkPlan.AddFromType == Sheet.FromType)
{
orderPlan.Info = "符合[新客计划],首单+来源";
_repository.Add<BdOrderPlan>(orderPlan);
}
continue;
}
//这里新客定义,在宝典里面有所变化,新客指的是在该店铺第一次核销或收银
if (clerkPlan.ProductId == (int)PlanProductId.NewMemberQty)
{
if ((lxmFirstShopOrder == null || Guid.Parse(lxmFirstShopOrder.Id) == Guid.Parse(SheetId)) && clerkPlan.AddFromType == Sheet.FromType)
{
orderPlan.Info = "符合[新客计划],新客+来源";
_repository.Add<BdOrderPlan>(orderPlan);
}
continue;
}
//匹配到的计划配置里面的sku
var IfMatchPlan = IfMatchPlanProductOrService(listPackage, clerkPlan.ProductId.Value, listSheetItem);
if (!IfMatchPlan) { continue; }
//是否匹配来源
if (!(clerkPlan.AddFromType == Sheet.FromType)) { continue; }
//看看订单明细里面是不是有这个商品
if (IfMatchPlan)
{
orderPlan.Info = Info;
_repository.Add<BdOrderPlan>(orderPlan);
}
}
}
#endregion
#region IfMatchPlanProductOrService()
/// <summary>
/// 是否匹配计划中的商品
/// </summary>
/// <param name="orderSkuId"></param>
/// <param name="listPlanSkuId"></param>
/// <returns></returns>
private bool IfMatchPlanProductOrService(List<PackageListResp> listPackage,long packageId, List<LxmSheetItem> listSheetItem)
{
//匹配到的计划配置里面的sku
var matchPlanSkus = listPackage.Where(p => p.Id == packageId).ToList();
foreach (var planSku in matchPlanSkus)
{
if (listSheetItem.Exists(p => p.ItemId.ToLower() == planSku.ProductOrServiceId.ToLower()))
{
Info = $"[新客运算]只要一个商品符合,就符合,skuid={planSku.ProductOrServiceId}在订单明细中存在";
return true;
}
}
Info = "不符合[新客计划],没有一件商品是属于套餐的";
return false;
}
#endregion
}
}