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 platformSDKBusinessList; //private TaskSchedulerManager taskSchedulerManager; private RestApiService restApiService; public BatchPurchaseBusiness(IFreeSql fsql, NLogManager nLogManager, IIdGenerator idGenerator, ProductBusiness productBusiness, IEnumerable platformSDKBusinessList, RestApiService restApiService) : base(fsql, nLogManager, idGenerator) { this.productBusiness = productBusiness; this.platformSDKBusinessList = platformSDKBusinessList; this.restApiService = restApiService; } /// /// 获取包含对应平台采购方案的sku列表 /// /// /// /// public IList 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().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(); 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; } /// /// 预览订单 /// /// /// /// 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(); 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 }; } /// /// 创建订单 /// /// 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(); var failSkuList = new List(); var qikuPackSkuConfigRequestList = new List(); var extJArray = JsonConvert.DeserializeObject(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("PurchaserId") == purchaseGroup.Key); if (purchasePlatform == Enums.Platform.拳探) cardId = extJson.Value("CardId"); else if (purchasePlatform == Enums.Platform.阿里巴巴) tradeMode = extJson.Value("OrderTradeTypeCode"); #region 处理JD SKU和拳探SKU的对应关系 var belongSkus_mappingList = new List(); foreach (var belongSkuGroup in belongSkuGroups) { var firstProductParam = belongSkuGroup.FirstOrDefault(); if (!belongSkus_mappingList.Any(j => j.Value("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 updatePurchaseTimeSchemeIdList = productParamList.Select(p => p.BelongPurchaseSchemeId).Distinct().ToList(); List insertPurchaseOrderSkuList = new List(); List skuPackConfigList = null; if (purchasePlatform == Enums.Platform.拳探) skuPackConfigList = new List(); 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.IsJST ? "qiyuejushuitan" : x.Store.Id, wareName = x.IsJST ? "齐越聚水潭" : x.Store.Name, count = x.PackCount, wareType = x.IsJST ? 3 : GetQiKuWareType(x.Store.Type) }) }); } } } 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(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 }; } private int GetQiKuWareType(Enums.StockType stockType) { if (stockType == Enums.StockType.京仓) return 0; if (stockType == Enums.StockType.云仓) return 1; if (stockType == Enums.StockType.商家仓) return 2; return 0; } public PurchaseOrderV2ListResponse GetPurchaseOrderList(SearchPurchaseOrderV2Request request) { if (request.EndDate != null) request.EndDate = request.EndDate.Value.Date.AddDays(1).AddSeconds(-1); var select = fsql.Select().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().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().Where(posku => purchaseOrderIdList.Contains(posku.PurchaseOrderId)).ToList(); 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().Where(p => p.Id == request.OrderId).ToOne(); fsql.Update(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().Where(p => p.Id == request.OrderId).ToOne(); fsql.Update(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().Where(p => p.Id == request.OrderId).ToOne(); fsql.Update(order) .Set(a => a.OrderState, request.PurchaseOrderState) .ExecuteAffrows(); return new UpdatePackStateResponse(); } public UpdatePackStateResponse UpdatePackState(UpdatePackStateRequest request) { var order = fsql.Select().Where(p => p.Id == request.OrderId).ToOne(); fsql.Update(order) .Set(a => a.PackState, request.PackState) .ExecuteAffrows(); return new UpdatePackStateResponse(); } } }