步步为盈
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.

604 lines
32 KiB

using BBWY.Common.Http;
using BBWY.Common.Models;
using BBWY.Server.Model;
using BBWY.Server.Model.Db;
using BBWY.Server.Model.Db.QK;
using BBWY.Server.Model.Dto;
using FreeSql;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Mail;
using System.Text;
using System.Threading.Tasks;
using Yitter.IdGenerator;
namespace BBWY.Server.Business
{
public class BatchPurchaseBusiness : BaseBusiness, IDenpendency
{
private ProductBusiness productBusiness;
private IEnumerable<PlatformSDKBusiness> platformSDKBusinessList;
//private TaskSchedulerManager taskSchedulerManager;
private RestApiService restApiService;
public BatchPurchaseBusiness(IFreeSql fsql,
NLogManager nLogManager,
IIdGenerator idGenerator,
ProductBusiness productBusiness,
IEnumerable<PlatformSDKBusiness> platformSDKBusinessList,
RestApiService restApiService) : base(fsql, nLogManager, idGenerator)
{
this.productBusiness = productBusiness;
this.platformSDKBusinessList = platformSDKBusinessList;
this.restApiService = restApiService;
}
/// <summary>
/// 获取包含对应平台采购方案的sku列表
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
/// <exception cref="BusinessException"></exception>
public IList<ProductSkuWithSchemeResponse> GetProductSkuAndSchemeList(SearchProductSkuAndSchemeRequest request)
{
if (string.IsNullOrEmpty(request.Spu) && string.IsNullOrEmpty(request.Sku))
throw new BusinessException("至少具备一个Sku或Spu条件");
var productSkuList = productBusiness.GetProductSkuList(new SearchProductSkuRequest()
{
AppKey = request.AppKey,
AppSecret = request.AppSecret,
AppToken = request.AppToken,
Platform = request.Platform,
Sku = request.Sku,
Spu = request.Spu
});
if (productSkuList == null || productSkuList.Count() == 0)
return null;
var skuIdList = productSkuList.Select(s => s.Id).ToList();
var schemeList = fsql.Select<PurchaseScheme, Purchaser>().InnerJoin((ps, p) => ps.PurchaserId == p.Id)
.Where((ps, p) => ps.ShopId == request.ShopId)
.Where((ps, p) => skuIdList.Contains(ps.SkuId))
.ToList((ps, p) => new
{
PurchaseSchemeId = ps.Id,
ps.PurchaserId,
PurchaserName = p.Name,
ps.PurchasePlatform,
ps.SkuId
});
var list = new List<ProductSkuWithSchemeResponse>();
foreach (var productSku in productSkuList)
{
var currentSchemeList = schemeList.Where(ps => ps.SkuId == productSku.Id).ToList();
if (currentSchemeList == null || currentSchemeList.Count() == 0)
{
list.Add(new ProductSkuWithSchemeResponse()
{
Id = productSku.Id,
SkuId = productSku.Id,
ProductId = productSku.ProductId,
CreateTime = productSku.CreateTime,
Logo = productSku.Logo,
Price = productSku.Price,
Title = productSku.Title,
State = productSku.State
});
}
else
{
foreach (var currentScheme in currentSchemeList)
{
list.Add(new ProductSkuWithSchemeResponse()
{
Id = $"{productSku.Id}_{currentScheme.PurchaseSchemeId}",
SkuId = productSku.Id,
ProductId = productSku.ProductId,
CreateTime = productSku.CreateTime,
Logo = productSku.Logo,
Price = productSku.Price,
Title = productSku.Title,
State = productSku.State,
PurchaserName = currentScheme.PurchaserName,
PurchasePlatform = currentScheme.PurchasePlatform,
PurchaserId = currentScheme.PurchaserId,
PurchaseSchemeId = currentScheme.PurchaseSchemeId
});
}
}
}
return list;
}
/// <summary>
/// 预览订单
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
/// <exception cref="BusinessException"></exception>
public PreviewOrderResponse PreviewOrder(BatchPurchasePreviewOrderRequest request)
{
/*
记录报价日志
*/
if (request.ProductParamList == null || request.ProductParamList.Count() == 0)
throw new BusinessException("缺少商品参数");
if (request.Consignee == null ||
string.IsNullOrEmpty(request.Consignee.Address) ||
string.IsNullOrEmpty(request.Consignee.Mobile) ||
string.IsNullOrEmpty(request.Consignee.ContactName))
throw new BusinessException("缺少收货人信息");
if (request.PurchaseAccountList == null || request.PurchaseAccountList.Count() == 0)
throw new BusinessException("缺少采购账号");
var purchaseGroups = request.ProductParamList.GroupBy(p => p.PurchaserId);
var extJArray = new List<object>();
var errorBuilder = new StringBuilder();
var freightAmount = 0M;
var productAmount = 0M;
var totalAmount = 0M;
foreach (var purchaseGroup in purchaseGroups)
{
var productParamList = purchaseGroup.ToList();
try
{
var purchasePlatform = productParamList.FirstOrDefault().PurchasePlatform;
var purchaseAccount = request.PurchaseAccountList.FirstOrDefault(pa => pa.PurchasePlatformId == purchasePlatform);
if (purchaseAccount == null)
throw new BusinessException($"缺少{purchasePlatform}采购平台账号,请在店铺配置中设置");
var platformSDKBusiness = platformSDKBusinessList.FirstOrDefault(p => p.Platform == purchasePlatform);
var previewOrderResponse = platformSDKBusiness.PreviewOrder(new PreviewOrderReuqest()
{
AppKey = purchaseAccount.AppKey,
AppSecret = purchaseAccount.AppSecret,
AppToken = purchaseAccount.AppToken,
Consignee = request.Consignee,
Platform = purchasePlatform,
PurchaseOrderMode = request.PurchaseOrderMode,
CargoParamList = productParamList.Select(p => new CargoParamRequest()
{
ProductId = p.PurchaseProductId,
SkuId = p.PurchaseSkuId,
Quantity = p.Quantity,
SpecId = p.PurchaseSpecId
}).ToList()
});
if (purchasePlatform == Enums.Platform.)
extJArray.Add(new { PurchaserId = purchaseGroup.Key, CardId = previewOrderResponse.Extensions });
else if (purchasePlatform == Enums.Platform.)
extJArray.Add(new { PurchaserId = purchaseGroup.Key, OrderTradeTypeCode = previewOrderResponse.OrderTradeType?.Code });
freightAmount += previewOrderResponse.FreightAmount;
productAmount += previewOrderResponse.ProductAmount;
totalAmount += previewOrderResponse.TotalAmount;
}
catch (Exception ex)
{
errorBuilder.AppendLine($"采购商:{productParamList.FirstOrDefault().PurchaserName}");
errorBuilder.AppendLine(ex.Message);
throw new BusinessException(errorBuilder.ToString());
}
}
return new PreviewOrderResponse()
{
Extensions = JsonConvert.SerializeObject(extJArray),
FreightAmount = freightAmount,
ProductAmount = productAmount,
TotalAmount = totalAmount
};
}
/// <summary>
/// 创建订单
/// </summary>
/// <param name="request"></param>
public BatchCreareOrderResponse BatchCreateOrder(BatchPurchaseCreateOrderRequest request)
{
/*
下单报价日志
*/
if (request.ProductParamList == null || request.ProductParamList.Count() == 0)
throw new BusinessException("缺少商品参数");
if (request.Consignee == null ||
string.IsNullOrEmpty(request.Consignee.Address) ||
string.IsNullOrEmpty(request.Consignee.Mobile) ||
string.IsNullOrEmpty(request.Consignee.ContactName))
throw new BusinessException("缺少收货人信息");
if (request.PurchaseAccountList == null || request.PurchaseAccountList.Count() == 0)
throw new BusinessException("缺少采购账号");
var successSkuIdList = new List<string>();
var failSkuList = new List<BatchCreareOrderFailDetail>();
var qikuPackSkuConfigRequestList = new List<object>();
var extJArray = JsonConvert.DeserializeObject<JArray>(request.Extensions);
var purchaseGroups = request.ProductParamList.GroupBy(p => p.PurchaserId);
foreach (var purchaseGroup in purchaseGroups)
{
var productParamList = purchaseGroup.ToList();
var belongSkuGroups = productParamList.GroupBy(p => p.BelongSkuId);
try
{
var purchasePlatform = productParamList.FirstOrDefault().PurchasePlatform;
var purchaserId = productParamList.FirstOrDefault().PurchaserId;
var purchaserName = productParamList.FirstOrDefault().PurchaserName;
var purchaseAccount = request.PurchaseAccountList.FirstOrDefault(pa => pa.PurchasePlatformId == purchasePlatform);
var platformSDKBusiness = platformSDKBusinessList.FirstOrDefault(p => p.Platform == purchasePlatform);
string tradeMode = "", cardId = "";
var extJson = extJArray.FirstOrDefault(j => j.Value<string>("PurchaserId") == purchaseGroup.Key);
if (purchasePlatform == Enums.Platform.)
cardId = extJson.Value<string>("CardId");
else if (purchasePlatform == Enums.Platform.)
tradeMode = extJson.Value<string>("OrderTradeTypeCode");
#region 处理JD SKU和拳探SKU的对应关系
var belongSkus_mappingList = new List<JObject>();
foreach (var belongSkuGroup in belongSkuGroups)
{
var firstProductParam = belongSkuGroup.FirstOrDefault();
if (!belongSkus_mappingList.Any(j => j.Value<string>("BelongSkuId") == firstProductParam.BelongSkuId))
{
belongSkus_mappingList.Add(JObject.FromObject(new { firstProductParam.BelongSkuId, SkuId = firstProductParam.PurchaseSkuId }));
}
}
#endregion
var createOrderResponse = platformSDKBusinessList.FirstOrDefault(p => p.Platform == purchasePlatform)
.FastCreateOrder(new CreateOnlinePurchaseOrderRequest()
{
AppKey = purchaseAccount.AppKey,
AppSecret = purchaseAccount.AppSecret,
AppToken = purchaseAccount.AppToken,
Platform = purchasePlatform,
Consignee = request.Consignee,
PurchaseOrderMode = request.PurchaseOrderMode,
Remark = request.Remark,
SourceShopName = request.ShopName,
SourceSku = belongSkus_mappingList,
CargoParamList = productParamList.Select(p => new CargoParamRequest()
{
ProductId = p.PurchaseProductId,
SkuId = p.PurchaseSkuId,
Quantity = p.Quantity,
SpecId = p.PurchaseSpecId
}).ToList(),
TradeMode = tradeMode,
Extensions = cardId,
AutoPay = request.AutoPay,
});
var purchaseOrderSimpleInfo = platformSDKBusinessList.FirstOrDefault(p => p.Platform == purchasePlatform).GetOrderSimpleInfo(new GetOrderInfoRequest()
{
AppKey = purchaseAccount.AppKey,
AppSecret = purchaseAccount.AppSecret,
AppToken = purchaseAccount.AppToken,
OrderId = createOrderResponse.PurchaseOrderId,
Platform = purchasePlatform
});
List<long> updatePurchaseTimeSchemeIdList = productParamList.Select(p => p.BelongPurchaseSchemeId).Distinct().ToList();
List<PurchaseOrderSku> insertPurchaseOrderSkuList = new List<PurchaseOrderSku>();
List<object> skuPackConfigList = null;
if (purchasePlatform == Enums.Platform.)
skuPackConfigList = new List<object>();
foreach (var belongSkuGroup in belongSkuGroups)
{
var firstProductParam = belongSkuGroup.FirstOrDefault();
var currentOrderSkuProductAmount = 0M; //采购成本
currentOrderSkuProductAmount = purchaseOrderSimpleInfo.ItemList.Where(p => belongSkuGroup.Any(p1 => p1.PurchaseSkuId == p.SkuId))
?.Sum(p => p.ProductAmount) ?? 0M;
var currentOrderSkuFreightAmount = purchaseOrderSimpleInfo.FreightAmount / belongSkuGroups.Count(); //采购运费(按sku数均分)
var purchaseOrderSku = new PurchaseOrderSku()
{
Id = idGenerator.NewLong(),
ShopId = request.ShopId,
PurchaseOrderId = createOrderResponse.PurchaseOrderId,
ProductId = firstProductParam.BelongProductId,
SkuId = firstProductParam.BelongSkuId,
Price = firstProductParam.BelongPrice,
SkuTitle = firstProductParam.BelongSkuTitle,
Logo = firstProductParam.BelongLogo,
Quantity = firstProductParam.BelongQuantity,
PurchaseSchemeId = firstProductParam.BelongPurchaseSchemeId,
PurchaseSkuIds = string.Join(",", belongSkuGroup.Select(p => p.PurchaseSkuId).ToList()),
PurchaseAmount = currentOrderSkuProductAmount + currentOrderSkuFreightAmount,
ProductAmount = currentOrderSkuProductAmount,
PurchaseFreight = currentOrderSkuFreightAmount,
CreateTime = DateTime.Now
};
insertPurchaseOrderSkuList.Add(purchaseOrderSku);
if (purchasePlatform == Enums.Platform.)
{
var skuPackConfig = request.PackSkuConfigList?.FirstOrDefault(s => s.SkuId == firstProductParam.BelongSkuId);
if (skuPackConfig != null)
{
skuPackConfigList.Add(new
{
skuId = firstProductParam.BelongSkuId,
skuCount = skuPackConfig.PurchaseCount,
markMessage = skuPackConfig.RemarkMessage,
wareHourses = skuPackConfig.PackSkuSplitConfigList.Select(x => new
{
wareId = x.Store.Id,
wareName = x.Store.Name,
count = x.PackCount
})
});
}
}
}
var purchaseOrderV2 = new PurchaseOrderV2()
{
Id = createOrderResponse.PurchaseOrderId,
ShopId = request.ShopId,
OrderState = createOrderResponse.IsPay ? Enums.PurchaseOrderState. : Enums.PurchaseOrderState.,
PurchasePlatform = purchasePlatform,
ConsigneeContactName = request.Consignee.ContactName,
ConsigneeMobile = request.Consignee.Mobile,
ConsigneeProvince = request.Consignee.Province,
ConsigneeCity = request.Consignee.City,
ConsigneeCounty = request.Consignee.County,
ConsigneeTown = request.Consignee.Town,
ConsigneeAddress = request.Consignee.Address,
PurchaserId = purchaserId,
PurchaserName = purchaserName,
PurchaseAccountId = purchaseAccount.Id,
PurchaseAmount = purchaseOrderSimpleInfo.TotalAmount,
ProductAmount = purchaseOrderSimpleInfo.ProductAmount,
PurchaseFreight = purchaseOrderSimpleInfo.FreightAmount,
Remark = request.Remark,
CreateTime = DateTime.Now,
PurchaseMethod = Enums.PurchaseMethod.线,
PurchaseOrderMode = request.PurchaseOrderMode
};
if (createOrderResponse.IsPay)
purchaseOrderV2.PayTime = DateTime.Now;
fsql.Transaction(() =>
{
fsql.Insert(purchaseOrderV2).ExecuteAffrows();
//fsql.Insert(purchaseOrderSku).ExecuteAffrows();
fsql.Insert(insertPurchaseOrderSkuList).ExecuteAffrows();
fsql.Update<PurchaseScheme>(updatePurchaseTimeSchemeIdList).Set(p => p.LastPurchaseTime, DateTime.Now).ExecuteAffrows();
});
successSkuIdList.AddRange(belongSkuGroups.Select(g => g.Key));
if (purchasePlatform == Enums.Platform.)
{
qikuPackSkuConfigRequestList.Add(new
{
orderId = purchaseOrderV2.Id,
//shopId = request.ShopId.ToString(),
shopId = purchaseGroup.Key, //拳探店铺Id(商家Id)
originShopName = request.ShopName,
userName = purchaseAccount.AccountName,
platform = Enums.Platform.,
purchaseTaskModels = skuPackConfigList
});
}
}
catch (Exception ex)
{
failSkuList.AddRange(belongSkuGroups.Select(g => new BatchCreareOrderFailDetail()
{
SkuId = g.Key,
ErrorMsg = ex.Message
}));
//throw new BusinessException(errorBuilder.ToString());
}
}
if (qikuPackSkuConfigRequestList.Count() > 0)
{
Task.Factory.StartNew(() =>
{
foreach (var qikuPackSkuConfigRequest in qikuPackSkuConfigRequestList)
{
try
{
var qikuResponse = restApiService.SendRequest("http://qiku.qiyue666.com/",
"api/PackPurchaseTask/BatchPublicPurchaseTask",
qikuPackSkuConfigRequest,
null,
HttpMethod.Post);
if (qikuResponse.StatusCode != System.Net.HttpStatusCode.OK)
throw new Exception(qikuResponse.Content);
}
catch (Exception ex)
{
nLogManager.GetLogger($"发布打包任务-{request.ShopName}").Error(ex, JsonConvert.SerializeObject(qikuPackSkuConfigRequest));
}
}
});
}
return new BatchCreareOrderResponse()
{
FailSkuList = failSkuList,
SuccessSkuIdList = successSkuIdList
};
}
public PurchaseOrderV2ListResponse GetPurchaseOrderList(SearchPurchaseOrderV2Request request)
{
if (request.EndDate != null)
request.EndDate = request.EndDate.Value.Date.AddDays(1).AddSeconds(-1);
var select = fsql.Select<PurchaseOrderV2, PurchaseAccount>().LeftJoin((po, pa) => po.PurchaseAccountId == pa.Id)
.Where((po, pa) => po.ShopId == request.ShopId);
if (!string.IsNullOrEmpty(request.PurchaseOrderId))
{
select = select.Where((po, pa) => po.Id == request.PurchaseOrderId);
}
else
{
if (!string.IsNullOrEmpty(request.Spu) || !string.IsNullOrEmpty(request.Sku))
{
var childSelect = fsql.Select<PurchaseOrderSku>().As("posku")
.WhereIf(!string.IsNullOrEmpty(request.Sku), posku => posku.SkuId == request.Sku)
.WhereIf(!string.IsNullOrEmpty(request.Spu), posku => posku.ProductId == request.Spu);
select = select.Where((po, pa) => childSelect.Where(posku => posku.PurchaseOrderId == po.Id).Any());
}
select = select.WhereIf(request.PurchaserName != null, (po, pa) => po.PurchaserName == request.PurchaserName)
.WhereIf(request.PurchaseOrderState != null, (po, pa) => po.OrderState == request.PurchaseOrderState)
.WhereIf(request.StartDate != null, (po, pa) => po.CreateTime >= request.StartDate)
.WhereIf(request.EndDate != null, (po, pa) => po.CreateTime <= request.EndDate);
}
var purchaseOrderList = select.OrderByDescending((po, pa) => po.CreateTime)
.Count(out var total)
.Page(request.PageIndex, request.PageSize)
.ToList((po, pa) => new PurchaseOrderV2Response
{
Id = po.Id,
ShopId = po.ShopId,
OrderState = po.OrderState,
PurchasePlatform = po.PurchasePlatform,
ConsigneeContactName = po.ConsigneeContactName,
ConsigneeMobile = po.ConsigneeMobile,
ConsigneeProvince = po.ConsigneeProvince,
ConsigneeCity = po.ConsigneeCity,
ConsigneeCounty = po.ConsigneeCounty,
ConsigneeTown = po.ConsigneeTown,
ConsigneeAddress = po.ConsigneeAddress,
PurchaserId = po.PurchaserId,
PurchaserName = po.PurchaserName,
PurchaseAccountId = po.PurchaseAccountId,
PurchaseAccountName = pa.AccountName,
PurchaseAmount = po.PurchaseAmount,
ProductAmount = po.ProductAmount,
PurchaseFreight = po.PurchaseFreight,
QualityInspectionAmount = po.QualityInspectionAmount,
InStorageAmount = po.InStorageAmount,
ConsumableAmount = po.ConsumableAmount,
FirstFreight = po.FirstFreight,
IsConvertToStock = po.IsConvertToStock,
Remark = po.Remark,
CreateTime = po.CreateTime,
PayTime = po.PayTime,
SignTime = po.SignTime,
CompletionTime = po.CompletionTime,
PurchaseMethod = po.PurchaseMethod,
PurchaseOrderMode = po.PurchaseOrderMode,
ExpressName = po.ExpressName,
WaybillNo = po.WaybillNo,
PackState = po.PackState
});
var purchaseOrderIdList = purchaseOrderList.Select(p => p.Id).ToList();
var purchaseOrderSkuList = fsql.Select<PurchaseOrderSku>().Where(posku => purchaseOrderIdList.Contains(posku.PurchaseOrderId)).ToList<PurchaseOrderSkuResponse>();
foreach (var purchaseOrder in purchaseOrderList)
purchaseOrder.ItemList = purchaseOrderSkuList.Where(posku => posku.PurchaseOrderId == purchaseOrder.Id).ToList();
return new PurchaseOrderV2ListResponse() { Count = total, ItemList = purchaseOrderList };
}
public PayPurchaseOrderResponse PayPurchaseOrder(PayPurchaseOrderRequest request)
{
var platformSDKBusiness = platformSDKBusinessList.FirstOrDefault(p => p.Platform == request.Platform);
var payOrderResponse = platformSDKBusiness.PayPurchaseOrder(request);
if (payOrderResponse.Success)
{
var order = fsql.Select<PurchaseOrderV2>().Where(p => p.Id == request.OrderId).ToOne();
fsql.Update<PurchaseOrderV2>(order)
.Set(a => a.OrderState, payOrderResponse.PurchaseOrderState)
.ExecuteAffrows();
}
return new PayPurchaseOrderResponse()
{
Success = payOrderResponse.Success,
Msg = payOrderResponse.Msg
};
}
public CancelPurchaseOrderResponse CancelPurchaseOrder(CancelPurchaseOrderRequest request)
{
var platformSDKBusiness = platformSDKBusinessList.FirstOrDefault(p => p.Platform == request.Platform);
var payOrderResponse = platformSDKBusiness.CancelPurchaseOrder(request);
if (payOrderResponse.Success)//取消成功
{
//var order = fsql.Select<PurchaseOrderV2>().Where(p => p.Id == request.OrderId).ToOne();
fsql.Update<PurchaseOrderV2>(request.OrderId)
.Set(po => po.OrderState, Enums.PurchaseOrderState.)
.ExecuteAffrows();
try
{
var qikuResponse = restApiService.SendRequest("http://qiku.qiyue666.com/",
$"/api/PackPurchaseTask/CancelOrderPackTask?orderId={request.OrderId}",
null,
null,
HttpMethod.Post);
if (qikuResponse.StatusCode != System.Net.HttpStatusCode.OK)
throw new Exception(qikuResponse.Content);
}
catch (Exception ex)
{
nLogManager.GetLogger($"取消打包任务-{request.OrderId}").Error(ex, JsonConvert.SerializeObject(request));
}
}
return new CancelPurchaseOrderResponse()
{
Success = payOrderResponse.Success,
Msg = payOrderResponse.Msg
};
}
public UpdatePackStateResponse UpdatePurchaseOrderState(UpdatePurchaseOrderStateRequest request)
{
var order = fsql.Select<PurchaseOrderV2>().Where(p => p.Id == request.OrderId).ToOne();
fsql.Update<PurchaseOrderV2>(order)
.Set(a => a.OrderState, request.PurchaseOrderState)
.ExecuteAffrows();
return new UpdatePackStateResponse();
}
public UpdatePackStateResponse UpdatePackState(UpdatePackStateRequest request)
{
var order = fsql.Select<PurchaseOrderV2>().Where(p => p.Id == request.OrderId).ToOne();
fsql.Update<PurchaseOrderV2>(order)
.Set(a => a.PackState, request.PackState)
.ExecuteAffrows();
return new UpdatePackStateResponse();
}
}
}