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

1403 lines
81 KiB

using BBWY.Common.Extensions;
using BBWY.Common.Http;
using BBWY.Common.Models;
using BBWY.Server.Business.PlatformSDK.DataExtension;
using BBWY.Server.Model;
using BBWY.Server.Model.Db;
using BBWY.Server.Model.Dto;
using FreeSql;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Yitter.IdGenerator;
namespace BBWY.Server.Business
{
public class OrderBusiness : BasePlatformRelayBusiness, IDenpendency
{
private ILogger logger;
private IFreeSql fsql;
private IDictionary<Enums.Platform, Action<JArray, long, string, string, string, string, decimal>> syncOrderMethodDic;
private IIdGenerator idGenerator;
private TaskSchedulerManager taskSchedulerManager;
private MDSBusiness mdsBusiness;
public OrderBusiness(RestApiService restApiService,
ILogger logger,
IFreeSql fsql,
IIdGenerator idGenerator,
IOptions<GlobalConfig> options,
TaskSchedulerManager taskSchedulerManager,
MDSBusiness mdsBusiness) : base(restApiService, options)
{
this.logger = logger;
this.fsql = fsql;
this.idGenerator = idGenerator;
this.taskSchedulerManager = taskSchedulerManager;
syncOrderMethodDic = new Dictionary<Enums.Platform, Action<JArray, long, string, string, string, string, decimal>>()
{
{ Enums.Platform., SyncJDOrder }
};
this.mdsBusiness = mdsBusiness;
}
public OrderListResponse GetOrderList(SearchOrderRequest searchOrderRequest)
{
if (searchOrderRequest.OrderState == Enums.OrderState.)
searchOrderRequest.ExcludeCanceled = false;
if (searchOrderRequest.EndDate != null)
searchOrderRequest.EndDate = searchOrderRequest.EndDate.Value.Date.AddDays(1).AddSeconds(-1);
var select = fsql.Select<Order, OrderConsignee, OrderCost, OrderDropShipping>().LeftJoin((o, ocs, oct, ods) => o.Id == ocs.OrderId)
.LeftJoin((o, ocs, oct, ods) => o.Id == oct.OrderId)
.LeftJoin((o, ocs, oct, ods) => o.Id == ods.OrderId);
if (!string.IsNullOrEmpty(searchOrderRequest.OrderId))
{
select = select.Where((o, ocs, oct, ods) => o.Id == searchOrderRequest.OrderId);
}
else
{
if (!string.IsNullOrEmpty(searchOrderRequest.Sku) || !string.IsNullOrEmpty(searchOrderRequest.ProductNo))
{
var childSelect = fsql.Select<OrderSku>().As("osku")
.WhereIf(string.IsNullOrEmpty(searchOrderRequest.Sku) == false, osku => osku.SkuId == searchOrderRequest.Sku)
.WhereIf(string.IsNullOrEmpty(searchOrderRequest.ProductNo) == false, osku => osku.ProductNo == searchOrderRequest.ProductNo);
select = select.Where((o, ocs, oct, ods) => childSelect.Where(osku => osku.OrderId == o.Id).Any());
}
select = select.WhereIf(searchOrderRequest.OrderState != null, (o, ocs, oct, ods) => o.OrderState == searchOrderRequest.OrderState)
.WhereIf(searchOrderRequest.StartDate != null, (o, ocs, oct, ods) => o.StartTime >= searchOrderRequest.StartDate)
.WhereIf(searchOrderRequest.EndDate != null, (o, ocs, oct, ods) => o.StartTime <= searchOrderRequest.EndDate)
.WhereIf(searchOrderRequest.OnlyDF, (o, ocs, oct, ods) => o.StorageType == Enums.StorageType.)
.WhereIf(searchOrderRequest.ExcludeCanceled, (o, ocs, oct, ods) => o.OrderState != Enums.OrderState.)
.WhereIf(searchOrderRequest.ExcludeSD && !searchOrderRequest.OnlyDF, (o, ocs, oct, ods) => o.StorageType == null || o.StorageType != Enums.StorageType.SD)
.WhereIf(string.IsNullOrEmpty(searchOrderRequest.ContactName) == false, (o, ocs, oct, ods) => ocs.ContactName == searchOrderRequest.ContactName)
.WhereIf(string.IsNullOrEmpty(searchOrderRequest.Waybill) == false, (o, ocs, oct, ods) => o.WaybillNo == searchOrderRequest.Waybill);
}
select = select.Where((o, ocs, oct, ods) => o.ShopId == searchOrderRequest.ShopId)
.OrderByDescending((o, ocs, oct, ods) => o.StartTime)
.Count(out var total)
.Page(searchOrderRequest.PageIndex, searchOrderRequest.PageSize);
var orderSourceList = select.ToList((o, ocs, oct, ods) => new Order()
{
Id = o.Id,
BuyerRemark = o.BuyerRemark,
EndTime = o.EndTime,
FreightPrice = o.FreightPrice,
ModifyTime = o.ModifyTime,
OrderPayment = o.OrderPayment,
OrderSellerPrice = o.OrderSellerPrice,
OrderState = o.OrderState,
OrderTotalPrice = o.OrderTotalPrice,
OrderType = o.OrderType,
PayType = o.PayType,
Platform = o.Platform,
ShopId = o.ShopId,
StartTime = o.StartTime,
StorageType = o.StorageType,
StoreId = o.StoreId,
StoreOrder = o.StoreOrder,
VenderRemark = o.VenderRemark,
PurchaseRemark = o.PurchaseRemark,
WaybillNo = o.WaybillNo,
Flag = o.Flag,
SDType = o.SDType,
ContactName = ocs.ContactName,
Address = ocs.Address,
Province = ocs.Province,
County = ocs.County,
Town = ocs.Town,
City = ocs.City,
IsDecode = ocs.IsDecode,
Mobile = ocs.Mobile,
TelePhone = ocs.TelePhone,
DeliveryExpressFreight = oct.DeliveryExpressFreight,
PlatformCommissionAmount = oct.PlatformCommissionAmount,
PlatformCommissionRatio = oct.PlatformCommissionRatio,
PreferentialAmount = oct.PreferentialAmount,
Profit = oct.Profit,
PurchaseAmount = oct.PurchaseAmount,
IsManualEdited = oct.IsManualEdited,
SDCommissionAmount = oct.SDCommissionAmount,
BuyerAccount = ods.BuyerAccount,
DeliveryFreight = ods.DeliveryFreight,
PurchaseOrderId = ods.PurchaseOrderId,
PurchasePlatform = ods.PurchasePlatform,
SellerAccount = ods.SellerAccount,
OrderDropShippingSkuAmount = ods.SkuAmount,
OrderDropShippingPurchaseFreight = ods.PurchaseFreight,
});
var orderList = orderSourceList.Map<IList<OrderResponse>>();
if (orderList.Count > 0)
{
var orderIdList = orderList.Select(o => o.Id).ToList();
#region 处理Sku
var orderSkuList = fsql.Select<OrderSku>().Where(osku => orderIdList.Contains(osku.OrderId)).ToList().Map<IList<OrderSkuResponse>>();
foreach (var order in orderList)
order.ItemList = orderSkuList.Where(osku => osku.OrderId == order.Id).ToList();
#endregion
#region 处理优惠券
var orderCouponList = fsql.Select<OrderCoupon>().Where(oc => orderIdList.Contains(oc.OrderId)).ToList().Map<IList<OrderCouponResponse>>();
foreach (var order in orderList)
order.OrderCouponList = orderCouponList.Where(oc => oc.OrderId == order.Id).ToList();
#endregion
#region 处理订单成本明细
var orderCostDetailList = fsql.Select<OrderCostDetail>().Where(ocd => orderIdList.Contains(ocd.OrderId)).ToList().Map<IList<OrderCostDetailResponse>>();
foreach (var order in orderList)
order.OrderCostDetailList = orderCostDetailList.Where(ocd => ocd.OrderId == order.Id).ToList();
#endregion
#region 翻译仓库Id
foreach (var order in orderList)
order.StoreName = globalConfig.Stores.FirstOrDefault(s => s.StoreId == order.StoreId)?.StoreName ?? order.StoreId;
#endregion
}
var response = new OrderListResponse()
{
Count = total,
Items = orderList
};
return response;
}
public IList<ExportOrderResponse> ExportOrderList(SearchOrderRequest searchOrderRequest)
{
if (searchOrderRequest.OrderState == Enums.OrderState.)
searchOrderRequest.ExcludeCanceled = false;
if (searchOrderRequest.EndDate != null)
searchOrderRequest.EndDate = searchOrderRequest.EndDate.Value.Date.AddDays(1).AddSeconds(-1);
var select = fsql.Select<Order, OrderConsignee, OrderCost, OrderDropShipping>().LeftJoin((o, ocs, oct, ods) => o.Id == ocs.OrderId)
.LeftJoin((o, ocs, oct, ods) => o.Id == oct.OrderId)
.LeftJoin((o, ocs, oct, ods) => o.Id == ods.OrderId);
if (!string.IsNullOrEmpty(searchOrderRequest.OrderId))
{
select = select.Where((o, ocs, oct, ods) => o.Id == searchOrderRequest.OrderId);
}
else
{
if (!string.IsNullOrEmpty(searchOrderRequest.Sku) || !string.IsNullOrEmpty(searchOrderRequest.ProductNo))
{
var childSelect = fsql.Select<OrderSku>().As("osku")
.WhereIf(string.IsNullOrEmpty(searchOrderRequest.Sku) == false, osku => osku.SkuId == searchOrderRequest.Sku)
.WhereIf(string.IsNullOrEmpty(searchOrderRequest.ProductNo) == false, osku => osku.ProductNo == searchOrderRequest.ProductNo);
select = select.Where((o, ocs, oct, ods) => childSelect.Where(osku => osku.OrderId == o.Id).Any());
}
select = select.WhereIf(searchOrderRequest.OrderState != null, (o, ocs, oct, ods) => o.OrderState == searchOrderRequest.OrderState)
.WhereIf(searchOrderRequest.StartDate != null, (o, ocs, oct, ods) => o.StartTime >= searchOrderRequest.StartDate)
.WhereIf(searchOrderRequest.EndDate != null, (o, ocs, oct, ods) => o.StartTime <= searchOrderRequest.EndDate)
.WhereIf(searchOrderRequest.OnlyDF, (o, ocs, oct, ods) => o.StorageType == Enums.StorageType.)
.WhereIf(searchOrderRequest.ExcludeCanceled, (o, ocs, oct, ods) => o.OrderState != Enums.OrderState.)
.WhereIf(searchOrderRequest.ExcludeSD && !searchOrderRequest.OnlyDF, (o, ocs, oct, ods) => o.StorageType == null || o.StorageType != Enums.StorageType.SD)
.WhereIf(string.IsNullOrEmpty(searchOrderRequest.ContactName) == false, (o, ocs, oct, ods) => ocs.ContactName == searchOrderRequest.ContactName)
.WhereIf(string.IsNullOrEmpty(searchOrderRequest.Waybill) == false, (o, ocs, oct, ods) => o.WaybillNo == searchOrderRequest.Waybill);
}
select = select.Where((o, ocs, oct, ods) => o.ShopId == searchOrderRequest.ShopId)
.OrderByDescending((o, ocs, oct, ods) => o.StartTime);
var orderSourceList = select.ToList((o, ocs, oct, ods) => new ExportOrderResponse()
{
OrderId = o.Id,
FreightPrice = o.FreightPrice,
OrderTotalPrice = o.OrderTotalPrice,
OrderStartTime = o.StartTime.Value,
StorageType = o.StorageType,
ConsigneeStr = ocs.ContactName + "|" + ocs.Mobile + "|" + ocs.Province + ocs.City + ocs.County + ocs.Address,
DeliveryExpressFreight = oct.DeliveryExpressFreight,
PlatformCommissionAmount = oct.PlatformCommissionAmount,
Profit = oct.Profit,
TotalCost = oct.SDCommissionAmount + oct.PlatformCommissionAmount + oct.PurchaseAmount + oct.DeliveryExpressFreight,
PurchaseOrderIds = ods.PurchaseOrderId,
OrderState = o.OrderState.Value
});
var orderIdList = orderSourceList.Select(o => o.OrderId).ToList();
var orderSkuList = fsql.Select<OrderSku>().Where(osku => orderIdList.Contains(osku.OrderId)).ToList();
var orderCostDetailGroup = fsql.Select<OrderCostDetail>().Where(ocd => orderIdList.Contains(ocd.OrderId)).GroupBy(ocd => ocd.OrderId).ToList(g => new
{
OrderId = g.Key,
SkuAmount = g.Sum(g.Value.SkuAmount),
FirstFreight = g.Sum(g.Value.FirstFreight),
StorageAmount = g.Sum(g.Value.StorageAmount)
});
foreach (var order in orderSourceList)
{
var statistics = orderCostDetailGroup.FirstOrDefault(g => g.OrderId == order.OrderId);
order.FirstFreight = statistics?.FirstFreight ?? 0M;
order.PurchaseSkuAmount = statistics?.SkuAmount ?? 0M;
order.StorageAmount = statistics?.StorageAmount ?? 0M;
order.SkuIds = string.Join("|", orderSkuList.Where(osku => osku.OrderId == order.OrderId).Select(osku => osku.SkuId));
order.ProfitRatio = order.TotalCost == 0 ? 0 : Math.Round(order.Profit / order.TotalCost * 100, 2);
}
return orderSourceList;
}
public OrderResponse GetOrderById(string orderId)
{
var order = fsql.Select<Order, OrderConsignee, OrderCost, OrderDropShipping>().LeftJoin((o, ocs, oct, ods) => o.Id == ocs.OrderId)
.LeftJoin((o, ocs, oct, ods) => o.Id == oct.OrderId)
.LeftJoin((o, ocs, oct, ods) => o.Id == ods.OrderId)
.Where((o, ocs, oct, ods) => o.Id == orderId)
.ToOne((o, ocs, oct, ods) => new Order()
{
Id = o.Id,
BuyerRemark = o.BuyerRemark,
EndTime = o.EndTime,
FreightPrice = o.FreightPrice,
ModifyTime = o.ModifyTime,
OrderPayment = o.OrderPayment,
OrderSellerPrice = o.OrderSellerPrice,
OrderState = o.OrderState,
OrderTotalPrice = o.OrderTotalPrice,
OrderType = o.OrderType,
PayType = o.PayType,
Platform = o.Platform,
ShopId = o.ShopId,
StartTime = o.StartTime,
StorageType = o.StorageType,
StoreId = o.StoreId,
StoreOrder = o.StoreOrder,
VenderRemark = o.VenderRemark,
PurchaseRemark = o.PurchaseRemark,
WaybillNo = o.WaybillNo,
Flag = o.Flag,
SDType = o.SDType,
ContactName = ocs.ContactName,
Address = ocs.Address,
Province = ocs.Province,
County = ocs.County,
Town = ocs.Town,
City = ocs.City,
IsDecode = ocs.IsDecode,
Mobile = ocs.Mobile,
TelePhone = ocs.TelePhone,
DeliveryExpressFreight = oct.DeliveryExpressFreight,
PlatformCommissionAmount = oct.PlatformCommissionAmount,
PlatformCommissionRatio = oct.PlatformCommissionRatio,
PreferentialAmount = oct.PreferentialAmount,
Profit = oct.Profit,
PurchaseAmount = oct.PurchaseAmount,
IsManualEdited = oct.IsManualEdited,
SDCommissionAmount = oct.SDCommissionAmount,
BuyerAccount = ods.BuyerAccount,
DeliveryFreight = ods.DeliveryFreight,
PurchaseOrderId = ods.PurchaseOrderId,
PurchasePlatform = ods.PurchasePlatform,
SellerAccount = ods.SellerAccount,
OrderDropShippingSkuAmount = ods.SkuAmount,
OrderDropShippingPurchaseFreight = ods.PurchaseFreight,
});
if (order == null)
throw new BusinessException("订单不存在");
var orderResponse = order.Map<OrderResponse>();
var orderSkuList = fsql.Select<OrderSku>().Where(osku => osku.OrderId == orderId).ToList().Map<IList<OrderSkuResponse>>();
var orderCouponList = fsql.Select<OrderCoupon>().Where(oc => oc.OrderId == orderId).ToList().Map<IList<OrderCouponResponse>>();
var orderCostDetailList = fsql.Select<OrderCostDetail>().Where(ocd => ocd.OrderId == orderId).ToList().Map<IList<OrderCostDetailResponse>>();
orderResponse.ItemList = orderSkuList;
orderResponse.OrderCouponList = orderCouponList;
orderResponse.OrderCostDetailList = orderCostDetailList;
orderResponse.StoreName = globalConfig.Stores.FirstOrDefault(s => s.StoreId == orderResponse.StoreId)?.StoreName ?? order.StoreId;
return orderResponse;
}
/// <summary>
/// 解密
/// </summary>
/// <param name="decryptConsigneeRequest"></param>
/// <returns></returns>
/// <exception cref="BusinessException"></exception>
public ConsigneeSimpleResponse DecryptConsignee(DecryptConsigneeRequest decryptConsigneeRequest)
{
var relayAPIHost = GetPlatformRelayAPIHost(decryptConsigneeRequest.Platform);
var sendResult = restApiService.SendRequest(relayAPIHost, "api/PlatformSDK/DecryptConsignee", decryptConsigneeRequest, null, HttpMethod.Post);
if (sendResult.StatusCode != System.Net.HttpStatusCode.OK)
throw new BusinessException(sendResult.Content) { Code = (int)sendResult.StatusCode };
var response = JsonConvert.DeserializeObject<ApiResponse<ConsigneeSimpleResponse>>(sendResult.Content);
if (!response.Success)
throw new BusinessException(response.Msg) { Code = response.Code };
if (!string.IsNullOrEmpty(decryptConsigneeRequest.PlaintextMobile))
response.Data.Mobile = decryptConsigneeRequest.PlaintextMobile;
//将解密后的收货人信息存至数据库
if (decryptConsigneeRequest.SaveDb)
{
fsql.Update<OrderConsignee>(decryptConsigneeRequest.OrderId).Set(oc => oc.ContactName, response.Data.ContactName)
.Set(oc => oc.Address, response.Data.Address)
.SetIf(!string.IsNullOrEmpty(response.Data.Mobile), oc => oc.Mobile, response.Data.Mobile)
.SetIf(!string.IsNullOrEmpty(response.Data.TelePhone), oc => oc.TelePhone, response.Data.TelePhone)
.Set(oc => oc.IsDecode, true)
.ExecuteAffrows();
}
return response.Data;
}
/// <summary>
/// 自动计算成本
/// </summary>
/// <param name="autoCalculationCostRequest"></param>
public void AutoCalculationCost(AutoCalculationCostRequest autoCalculationCostRequest)
{
var dbOrder = fsql.Select<Order>(autoCalculationCostRequest.OrderId).ToOne();
if (dbOrder == null)
throw new BusinessException($"订单号{autoCalculationCostRequest.OrderId}不存在");
var orderSkus = fsql.Select<OrderSku>().Where(osku => osku.OrderId == autoCalculationCostRequest.OrderId).ToList();
var orderSkuIds = orderSkus.Select(osku => osku.SkuId).ToList();
var purchaserOrders = fsql.Select<PurchaseOrder>().Where(po => po.StorageType == autoCalculationCostRequest.StorageType &&
po.RemainingQuantity != 0 &&
orderSkuIds.Contains(po.SkuId)).ToList();
if (purchaserOrders.Count() == 0)
throw new BusinessException("库存为零不能自动计算成本");
var orderCost = fsql.Select<OrderCost>(autoCalculationCostRequest.OrderId).ToOne();
var orderCostDetails = fsql.Select<OrderCostDetail>().Where(ocd => ocd.OrderId == autoCalculationCostRequest.OrderId).ToList();
IUpdate<Order> orderUpdate = null;
IUpdate<OrderCost> updateOrderCost = null;
IInsert<OrderCost> insertOrderCost = null;
IList<IUpdate<PurchaseOrder>> updatePurchaseOrderList = new List<IUpdate<PurchaseOrder>>();
List<OrderCostDetail> insertOrderCostDetailList = new List<OrderCostDetail>();
if (autoCalculationCostRequest.IsSetStorageType)
orderUpdate = fsql.Update<Order>(autoCalculationCostRequest.OrderId).Set(o => o.StorageType, autoCalculationCostRequest.StorageType);
var orderCostPurchaseAmount = 0M;
var orderDeliveryExpressFreight = 0M; //发货总运费,sku购买数量第二个开始半价
foreach (var orderSku in orderSkus)
{
//查询该sku的扣减明细
var currentOrderSkuCostDetails = orderCostDetails.Where(ocd => ocd.SkuId == orderSku.SkuId);
//已扣减数量
var deductedQuantity = currentOrderSkuCostDetails.Count() == 0 ? 0 : currentOrderSkuCostDetails.Sum(ocd => ocd.DeductionQuantity);
//剩余扣减数量
var noDeductionQuantity = orderSku.ItemTotal.Value - deductedQuantity;
if (noDeductionQuantity == 0)
continue;
//是否多次扣减库存
var isReduceMultiTimes = false;
if (currentOrderSkuCostDetails.Count() > 0)
isReduceMultiTimes = true; //之前有过扣减记录,发货运费按半价计算
while (noDeductionQuantity != 0)
{
var purchaseOrder = purchaserOrders.FirstOrDefault(po => po.StorageType == autoCalculationCostRequest.StorageType &&
po.RemainingQuantity != 0 &&
po.SkuId == orderSku.SkuId);
if (purchaseOrder == null)
break; //没有库存了
//本次扣减数量
var deductionQuantity = purchaseOrder.RemainingQuantity >= noDeductionQuantity ? noDeductionQuantity : purchaseOrder.RemainingQuantity;
//本次扣减量的采购成本
var currentPurchaseAmount = purchaseOrder.UnitCost * deductionQuantity;
//本次扣减量的发货运费
var currentSkuDeliveryFreight = isReduceMultiTimes ?
(purchaseOrder.SingleDeliveryFreight / 2 * deductionQuantity) :
(purchaseOrder.SingleDeliveryFreight + purchaseOrder.SingleDeliveryFreight / 2 * (deductionQuantity - 1));
isReduceMultiTimes = true;
noDeductionQuantity -= deductionQuantity;
purchaseOrder.RemainingQuantity -= deductionQuantity;
//累计采购成本
orderCostPurchaseAmount += currentPurchaseAmount;
//累计发货运费(销售运费)
orderDeliveryExpressFreight += currentSkuDeliveryFreight;
var updateSql = fsql.Update<PurchaseOrder>(purchaseOrder.Id).Set(po => po.RemainingQuantity - deductionQuantity);
updatePurchaseOrderList.Add(updateSql);
var orderCostDetail = new OrderCostDetail()
{
Id = idGenerator.NewLong(),
OrderId = autoCalculationCostRequest.OrderId,
ProductId = orderSku.ProductId,
SkuId = orderSku.SkuId,
CreateTime = DateTime.Now,
PurchaseOrderPKId = purchaseOrder.Id,
UnitCost = purchaseOrder.UnitCost,
DeductionQuantity = deductionQuantity,
DeliveryExpressFreight = currentSkuDeliveryFreight,
TotalCost = currentPurchaseAmount,
ConsumableAmount = purchaseOrder.SingleConsumableAmount * deductionQuantity,
FirstFreight = purchaseOrder.SingleFirstFreight * deductionQuantity,
OperationAmount = purchaseOrder.SingleOperationAmount * deductionQuantity,
PurchaseFreight = purchaseOrder.SingleFreight * deductionQuantity,
SkuAmount = purchaseOrder.SingleSkuAmount * deductionQuantity,
StorageAmount = purchaseOrder.SingleStorageAmount * deductionQuantity
};
insertOrderCostDetailList.Add(orderCostDetail);
}
}
if (orderCost == null)
{
if (autoCalculationCostRequest.PlatformCommissionRatio == 0M)
autoCalculationCostRequest.PlatformCommissionRatio = 0.05M;
#region 计算成本
orderCost = new OrderCost()
{
OrderId = autoCalculationCostRequest.OrderId,
PlatformCommissionRatio = autoCalculationCostRequest.PlatformCommissionRatio,
PreferentialAmount = dbOrder.PreferentialAmount,
Profit = 0,
PurchaseAmount = orderCostPurchaseAmount,
DeliveryExpressFreight = orderDeliveryExpressFreight,
CreateTime = DateTime.Now
};
orderCost.PlatformCommissionAmount = dbOrder.OrderSellerPrice * orderCost.PlatformCommissionRatio;
orderCost.Profit = dbOrder.OrderSellerPrice +
dbOrder.FreightPrice -
orderCost.PurchaseAmount -
orderCost.DeliveryExpressFreight -
orderCost.PlatformCommissionAmount;
insertOrderCost = fsql.Insert(orderCost);
#endregion
}
else
{
orderCost.PurchaseAmount += orderCostPurchaseAmount;
orderCost.DeliveryExpressFreight += orderDeliveryExpressFreight;
orderCost.Profit = dbOrder.OrderSellerPrice +
dbOrder.FreightPrice -
orderCost.PurchaseAmount -
orderCost.DeliveryExpressFreight -
orderCost.PlatformCommissionAmount;
updateOrderCost = fsql.Update<OrderCost>().SetSource(orderCost);
}
fsql.Transaction(() =>
{
orderUpdate?.ExecuteAffrows();
updateOrderCost?.ExecuteAffrows();
insertOrderCost?.ExecuteAffrows();
if (updatePurchaseOrderList.Count > 0)
{
foreach (var update in updatePurchaseOrderList)
update.ExecuteAffrows();
}
if (insertOrderCostDetailList.Count > 0)
fsql.Insert(insertOrderCostDetailList).ExecuteAffrows();
});
}
/// <summary>
/// 手动计算成本
/// </summary>
/// <param name="manualCalculationCostRequest"></param>
/// <exception cref="BusinessException"></exception>
public void ManualCalculationCost(ManualCalculationCostRequest manualCalculationCostRequest)
{
var dbOrder = fsql.Select<Order>(manualCalculationCostRequest.OrderId).ToOne();
if (dbOrder == null)
throw new BusinessException($"订单号{manualCalculationCostRequest.OrderId}不存在");
IUpdate<Order> orderUpdate = null;
IUpdate<OrderCost> updateOrderCost = null;
IInsert<OrderCost> insertOrderCost = null;
if (manualCalculationCostRequest.IsSetStorageType)
orderUpdate = fsql.Update<Order>(manualCalculationCostRequest.OrderId).Set(o => o.StorageType, manualCalculationCostRequest.StorageType);
var orderCost = fsql.Select<OrderCost>(manualCalculationCostRequest.OrderId).ToOne();
if (orderCost == null)
{
if (manualCalculationCostRequest.PlatformCommissionRatio == 0M)
manualCalculationCostRequest.PlatformCommissionRatio = 0.05M;
orderCost = new OrderCost()
{
OrderId = manualCalculationCostRequest.OrderId,
PlatformCommissionRatio = manualCalculationCostRequest.PlatformCommissionRatio,
PreferentialAmount = dbOrder.PreferentialAmount,
Profit = 0,
PurchaseAmount = manualCalculationCostRequest.PurchaseCost,
DeliveryExpressFreight = manualCalculationCostRequest.DeliveryExpressFreight,
CreateTime = DateTime.Now,
IsManualEdited = true
};
orderCost.PlatformCommissionAmount = dbOrder.OrderSellerPrice * orderCost.PlatformCommissionRatio;
orderCost.Profit = dbOrder.OrderSellerPrice +
dbOrder.FreightPrice -
orderCost.PurchaseAmount -
orderCost.DeliveryExpressFreight -
orderCost.PlatformCommissionAmount;
insertOrderCost = fsql.Insert(orderCost);
}
else
{
orderCost.PurchaseAmount = manualCalculationCostRequest.PurchaseCost;
orderCost.DeliveryExpressFreight = manualCalculationCostRequest.DeliveryExpressFreight;
orderCost.Profit = dbOrder.OrderSellerPrice +
dbOrder.FreightPrice -
orderCost.PurchaseAmount -
orderCost.DeliveryExpressFreight -
orderCost.PlatformCommissionAmount;
orderCost.IsManualEdited = true;
updateOrderCost = fsql.Update<OrderCost>().SetSource(orderCost);
}
fsql.Transaction(() =>
{
orderUpdate?.ExecuteAffrows();
insertOrderCost?.ExecuteAffrows();
updateOrderCost?.ExecuteAffrows();
});
}
/// <summary>
/// 刷单计算成本
/// </summary>
/// <param name="sdCalculationCostRequest"></param>
/// <exception cref="BusinessException"></exception>
public void SDCalculationCost(SDCalculationCostRequest sdCalculationCostRequest)
{
var dbOrder = fsql.Select<Order>(sdCalculationCostRequest.OrderId).ToOne();
if (dbOrder == null)
throw new BusinessException($"订单号{sdCalculationCostRequest.OrderId}不存在");
//修改平台订单备注
var relayAPIHost = GetPlatformRelayAPIHost(sdCalculationCostRequest.Platform);
var editApiResult = restApiService.SendRequest(relayAPIHost, "/Api/PlatformSDK/EditVenderRemark", new EditVenderRemarkRequest()
{
AppKey = sdCalculationCostRequest.AppKey,
AppSecret = sdCalculationCostRequest.AppSecret,
AppToken = sdCalculationCostRequest.AppToken,
Flag = sdCalculationCostRequest.Flag,
OrderId = sdCalculationCostRequest.OrderId,
Platform = sdCalculationCostRequest.Platform,
VenderRemark = sdCalculationCostRequest.VenderRemark
}, null, HttpMethod.Post);
if (editApiResult.StatusCode != System.Net.HttpStatusCode.OK)
throw new BusinessException($"修改商家备注失败 {editApiResult.Content}") { Code = (int)editApiResult.StatusCode };
var editResponse = JsonConvert.DeserializeObject<ApiResponse>(editApiResult.Content);
if (!editResponse.Success)
throw new BusinessException(editResponse.Msg);
IUpdate<Order> orderUpdate = null;
IUpdate<OrderCost> updateOrderCost = null;
IInsert<OrderCost> insertOrderCost = null;
orderUpdate = fsql.Update<Order>(sdCalculationCostRequest.OrderId).Set(o => o.SDType, sdCalculationCostRequest.SDType)
.Set(o => o.Flag, sdCalculationCostRequest.Flag)
.Set(o => o.VenderRemark, sdCalculationCostRequest.VenderRemark);
if (sdCalculationCostRequest.IsSetStorageType)
orderUpdate = orderUpdate.Set(o => o.StorageType, Enums.StorageType.SD);
var orderCost = fsql.Select<OrderCost>(sdCalculationCostRequest.OrderId).ToOne();
if (orderCost == null)
{
if (sdCalculationCostRequest.PlatformCommissionRatio == 0M)
sdCalculationCostRequest.PlatformCommissionRatio = 0.05M;
orderCost = new OrderCost()
{
OrderId = sdCalculationCostRequest.OrderId,
PlatformCommissionRatio = sdCalculationCostRequest.PlatformCommissionRatio,
PreferentialAmount = dbOrder.PreferentialAmount,
Profit = 0,
DeliveryExpressFreight = sdCalculationCostRequest.DeliveryExpressFreight,
CreateTime = DateTime.Now,
IsManualEdited = true,
SDCommissionAmount = sdCalculationCostRequest.SDCommissionAmount
};
orderCost.PlatformCommissionAmount = dbOrder.OrderSellerPrice * orderCost.PlatformCommissionRatio;
orderCost.Profit = (orderCost.SDCommissionAmount + orderCost.DeliveryExpressFreight + orderCost.PlatformCommissionAmount) * -1;
insertOrderCost = fsql.Insert(orderCost);
}
else
{
orderCost.SDCommissionAmount = sdCalculationCostRequest.SDCommissionAmount;
orderCost.DeliveryExpressFreight = sdCalculationCostRequest.DeliveryExpressFreight;
orderCost.Profit = (orderCost.SDCommissionAmount + orderCost.DeliveryExpressFreight + orderCost.PlatformCommissionAmount) * -1;
orderCost.IsManualEdited = true;
updateOrderCost = fsql.Update<OrderCost>().SetSource(orderCost);
}
fsql.Transaction(() =>
{
orderUpdate?.ExecuteAffrows();
updateOrderCost?.ExecuteAffrows();
insertOrderCost?.ExecuteAffrows();
});
}
/// <summary>
/// 关联外部订单
/// </summary>
/// <param name="relationPurchaseOrderRequest"></param>
public void RelationPurchaseOrder(RelationPurchaseOrderRequest relationPurchaseOrderRequest)
{
var dbOrder = fsql.Select<Order>(relationPurchaseOrderRequest.OrderDropShipping.OrderId).ToOne();
if (dbOrder == null)
throw new BusinessException($"订单号{relationPurchaseOrderRequest.OrderDropShipping.OrderId}不存在");
if (relationPurchaseOrderRequest.PlatformCommissionRatio == 0M)
relationPurchaseOrderRequest.PlatformCommissionRatio = 0.05M;
IInsert<OrderDropShipping> insertOrderDropShipping = null;
IUpdate<OrderDropShipping> updateOrderDropShipping = null;
IInsert<OrderCost> insertOrderCost = null;
IUpdate<OrderCost> updateOrderCost = null;
IDelete<PurchaseOrder> deletePurchaseOrder = null;
IDelete<OrderCostDetail> deleteOrderCostDetail = null;
List<PurchaseOrder> insertPurchaseOrderList = new List<PurchaseOrder>();
List<OrderCostDetail> insertOrderCostDetailList = new List<OrderCostDetail>();
#region 代发信息表
var orderDropShipping = relationPurchaseOrderRequest.OrderDropShipping.Map<OrderDropShipping>();
if (fsql.Select<OrderDropShipping>(relationPurchaseOrderRequest.OrderDropShipping.OrderId).Any())
updateOrderDropShipping = fsql.Update<OrderDropShipping>().SetSource(orderDropShipping);
else
{
orderDropShipping.CreateTime = DateTime.Now;
insertOrderDropShipping = fsql.Insert(orderDropShipping);
}
#endregion
#region 采购单表
var oldPourchaseIdList = fsql.Select<OrderCostDetail>().Where(ocd => ocd.OrderId == relationPurchaseOrderRequest.OrderDropShipping.OrderId)
.ToList(ocd => ocd.PurchaseOrderPKId);
deletePurchaseOrder = fsql.Delete<PurchaseOrder>().Where(po => oldPourchaseIdList.Contains(po.Id));
insertPurchaseOrderList.AddRange(relationPurchaseOrderRequest.RelationPurchaseOrderSkuList.Select(x => new PurchaseOrder()
{
Id = idGenerator.NewLong(),
CreateTime = DateTime.Now,
ProductId = x.ProductId,
PurchaseMethod = Enums.PurchaseMethod.线,
StorageType = Enums.StorageType.,
PurchaseOrderId = relationPurchaseOrderRequest.OrderDropShipping.PurchaseOrderId,
PurchasePlatform = relationPurchaseOrderRequest.OrderDropShipping.PurchasePlatform,
PurchaseQuantity = x.Quantity,
RemainingQuantity = 0,
ShopId = dbOrder.ShopId,
SkuId = x.SkuId,
SingleConsumableAmount = 0,
SingleFirstFreight = 0,
SingleFreight = relationPurchaseOrderRequest.OrderDropShipping.PurchaseFreight / relationPurchaseOrderRequest.RelationPurchaseOrderSkuList.Count() / x.Quantity,
SingleOperationAmount = 0,
SingleStorageAmount = 0,
SingleSkuAmount = x.SingleSkuAmount,
SingleDeliveryFreight = 0
}));
#endregion
#region 订单成本表
var orderCost = fsql.Select<OrderCost>(relationPurchaseOrderRequest.OrderDropShipping.OrderId).ToOne();
if (orderCost != null)
{
orderCost.PlatformCommissionRatio = relationPurchaseOrderRequest.PlatformCommissionRatio;
orderCost.PlatformCommissionAmount = dbOrder.OrderSellerPrice * relationPurchaseOrderRequest.PlatformCommissionRatio;
orderCost.DeliveryExpressFreight = relationPurchaseOrderRequest.OrderDropShipping.DeliveryFreight;
orderCost.PurchaseAmount = relationPurchaseOrderRequest.OrderDropShipping.PurchaseAmount;
orderCost.Profit = dbOrder.OrderSellerPrice +
dbOrder.FreightPrice -
orderCost.PurchaseAmount -
orderCost.DeliveryExpressFreight -
orderCost.PlatformCommissionAmount;
updateOrderCost = fsql.Update<OrderCost>().SetSource(orderCost).IgnoreColumns(oc => new
{
oc.CreateTime,
oc.SDCommissionAmount,
oc.PlatformCommissionAmount,
oc.PlatformCommissionRatio
});
}
else
{
var preferentialAmount = fsql.Select<OrderCoupon>().Where(oc => oc.OrderId == relationPurchaseOrderRequest.OrderDropShipping.OrderId)
.ToAggregate(g => g.Sum(g.Key.CouponPrice));
orderCost = new OrderCost()
{
OrderId = relationPurchaseOrderRequest.OrderDropShipping.OrderId,
CreateTime = DateTime.Now,
DeliveryExpressFreight = relationPurchaseOrderRequest.OrderDropShipping.DeliveryFreight,
PlatformCommissionRatio = relationPurchaseOrderRequest.PlatformCommissionRatio,
SDCommissionAmount = 0,
PurchaseAmount = relationPurchaseOrderRequest.RelationPurchaseOrderSkuList.Sum(s => s.SingleSkuAmount * s.Quantity),
PlatformCommissionAmount = dbOrder.OrderSellerPrice * relationPurchaseOrderRequest.PlatformCommissionRatio,
PreferentialAmount = preferentialAmount,
IsManualEdited = true
};
orderCost.Profit = dbOrder.OrderSellerPrice +
dbOrder.FreightPrice -
orderCost.PurchaseAmount -
orderCost.DeliveryExpressFreight -
orderCost.PlatformCommissionAmount;
insertOrderCost = fsql.Insert(orderCost);
}
#endregion
#region 订单成本明细表
var oldOrderCostDetailIdList = fsql.Select<OrderCostDetail>().Where(ocd => ocd.OrderId == relationPurchaseOrderRequest.OrderDropShipping.OrderId)
.ToList(ocd => ocd.Id);
deleteOrderCostDetail = fsql.Delete<OrderCostDetail>().Where(ocd => oldOrderCostDetailIdList.Contains(ocd.Id));
insertOrderCostDetailList.AddRange(relationPurchaseOrderRequest.RelationPurchaseOrderSkuList.Select(x => new OrderCostDetail()
{
Id = idGenerator.NewLong(),
ConsumableAmount = 0,
CreateTime = DateTime.Now,
DeductionQuantity = x.Quantity,
DeliveryExpressFreight = 0,
FirstFreight = 0,
OperationAmount = 0,
OrderId = relationPurchaseOrderRequest.OrderDropShipping.OrderId,
ProductId = x.ProductId,
PurchaseFreight = relationPurchaseOrderRequest.OrderDropShipping.PurchaseFreight / relationPurchaseOrderRequest.RelationPurchaseOrderSkuList.Count(),
SkuAmount = x.SingleSkuAmount * x.Quantity,
SkuId = x.SkuId,
StorageAmount = 0,
TotalCost = x.SingleSkuAmount * x.Quantity + relationPurchaseOrderRequest.OrderDropShipping.PurchaseFreight / relationPurchaseOrderRequest.RelationPurchaseOrderSkuList.Count(),
UnitCost = x.SingleSkuAmount,
PurchaseOrderPKId = insertPurchaseOrderList.FirstOrDefault(po => po.SkuId == x.SkuId).Id
}));
#endregion
fsql.Transaction(() =>
{
deletePurchaseOrder?.ExecuteAffrows();
deleteOrderCostDetail?.ExecuteAffrows();
insertOrderDropShipping?.ExecuteAffrows();
updateOrderDropShipping?.ExecuteAffrows();
insertOrderCost?.ExecuteAffrows();
updateOrderCost?.ExecuteAffrows();
fsql.Insert(insertPurchaseOrderList).ExecuteAffrows();
fsql.Insert(insertOrderCostDetailList).ExecuteAffrows();
if (dbOrder.StorageType != Enums.StorageType.)
{
fsql.Update<Order>(relationPurchaseOrderRequest.OrderDropShipping.OrderId)
.Set(o => o.StorageType, Enums.StorageType.)
.SetIf(dbOrder.OrderState == Enums.OrderState., o => o.OrderState, Enums.OrderState.)
.ExecuteAffrows();
}
});
}
/// <summary>
/// 出库
/// </summary>
/// <param name="outStockRequest"></param>
/// <exception cref="BusinessException"></exception>
public void OutStock(OutStockRequest outStockRequest)
{
var dbOrder = fsql.Select<Order>(outStockRequest.OrderId).ToOne();
if (dbOrder == null)
throw new BusinessException($"订单{outStockRequest.OrderId}不存在");
if (dbOrder.OrderState != Enums.OrderState.)
throw new BusinessException($"订单{outStockRequest.OrderId} 只有在待出库时才允许出库");
var relayAPIHost = GetPlatformRelayAPIHost(outStockRequest.Platform);
var sendResult = restApiService.SendRequest(relayAPIHost, "api/PlatformSDK/OutStock", outStockRequest, null, HttpMethod.Post);
if (sendResult.StatusCode != System.Net.HttpStatusCode.OK)
throw new BusinessException(sendResult.Content) { Code = (int)sendResult.StatusCode };
var response = JsonConvert.DeserializeObject<ApiResponse<ConsigneeSimpleResponse>>(sendResult.Content);
if (!response.Success)
throw new BusinessException(response.Msg) { Code = response.Code };
fsql.Update<Order>(outStockRequest.OrderId).Set(o => o.OrderState, Enums.OrderState.)
.Set(o => o.WaybillNo, outStockRequest.WayBillNo)
.ExecuteAffrows();
}
/// <summary>
/// 修改商家备注
/// </summary>
/// <param name="editVenderRemarkRequest"></param>
public void EditVenderRemark(EditVenderRemarkRequest editVenderRemarkRequest)
{
//修改平台订单备注
var relayAPIHost = GetPlatformRelayAPIHost(editVenderRemarkRequest.Platform);
if (editVenderRemarkRequest.Platform == Enums.Platform.)
{
var editApiResult = restApiService.SendRequest(relayAPIHost, "/Api/PlatformSDK/EditVenderRemark", editVenderRemarkRequest, null, HttpMethod.Post);
if (editApiResult.StatusCode != System.Net.HttpStatusCode.OK)
throw new BusinessException($"修改商家备注失败 {editApiResult.Content}") { Code = (int)editApiResult.StatusCode };
var editResponse = JsonConvert.DeserializeObject<ApiResponse>(editApiResult.Content);
if (!editResponse.Success)
throw new BusinessException(editResponse.Msg);
}
else
{
throw new NotImplementedException();
}
fsql.Update<Order>(editVenderRemarkRequest.OrderId).Set(o => o.Flag, editVenderRemarkRequest.Flag)
.Set(o => o.VenderRemark, editVenderRemarkRequest.VenderRemark)
.ExecuteAffrows();
}
/// <summary>
/// 同步订单
/// </summary>
/// <param name="shopId"></param>
/// <param name="orderId"></param>
/// <param name="startTime">默认3小时前</param>
/// <param name="endTime">默认当前时间</param>
/// <exception cref="Exception"></exception>
public void SyncOrder(long shopId, string orderId, DateTime? startTime = null, DateTime? endTime = null)
{
var shop = mdsBusiness.GetShopInfoByShopId(shopId);
try
{
if (!syncOrderMethodDic.ContainsKey(shop.Platform))
throw new Exception("不支持的平台");
var relayAPIHost = GetPlatformRelayAPIHost(shop.Platform);
var orderListApiResult = restApiService.SendRequest(relayAPIHost, "api/PlatformSDK/GetOrderList", new SearchPlatformOrderRequest()
{
StartDate = startTime ?? DateTime.Now.AddHours(-3),
EndDate = endTime ?? DateTime.Now,
AppKey = shop.AppKey,
AppSecret = shop.AppSecret,
AppToken = shop.AppToken,
PageIndex = 1,
PageSize = 100,
Platform = shop.Platform,
JDColType = string.IsNullOrEmpty(shop.VenderType) ? "0" : shop.VenderType,
SaveResponseLog = false,
OrderId = orderId
}, null, HttpMethod.Post);
if (orderListApiResult.StatusCode != System.Net.HttpStatusCode.OK)
throw new Exception($"获取订单失败 {orderListApiResult.Content}");
var orderListResponse = JsonConvert.DeserializeObject<ApiResponse<JArray>>(orderListApiResult.Content);
if (!orderListResponse.Success)
throw new Exception($"获取订单失败 {orderListApiResult.Content}");
if (orderListResponse.Data == null || orderListResponse.Data.Count == 0)
return;
syncOrderMethodDic[shop.Platform](orderListResponse.Data, shopId, relayAPIHost, shop.AppKey, shop.AppSecret, shop.AppToken, shop.PlatformCommissionRatio ?? 0.05M);
}
catch (Exception ex)
{
var shopData = JsonConvert.SerializeObject(shop);
logger.Error(ex, $"SyncOrder ShopData:{shopData}");
}
}
public void SyncOrderByDate(SyncOrderByDateRequest syncOrderByDateRequest)
{
if (fsql.Select<OrderSyncTask>().Where(ost => ost.ShopId == syncOrderByDateRequest.ShopId && ost.State == Enums.OrderSyncState.Running).Any())
throw new BusinessException("存在未结束的同步任务,请稍后同步");
syncOrderByDateRequest.EndTime = syncOrderByDateRequest.EndTime.Date.AddDays(1).AddSeconds(-1);
if ((syncOrderByDateRequest.EndTime - syncOrderByDateRequest.StartTime).Days > 7)
throw new BusinessException("同步任务时差最长7天");
var orderSyncTask = new OrderSyncTask()
{
Id = idGenerator.NewLong(),
ShopId = syncOrderByDateRequest.ShopId,
State = Enums.OrderSyncState.Running,
SyncStartTime = syncOrderByDateRequest.StartTime,
SyncEndTime = syncOrderByDateRequest.EndTime
};
fsql.Insert(orderSyncTask).ExecuteAffrows();
Task.Factory.StartNew(() =>
{
var currentStartTime = syncOrderByDateRequest.StartTime;
var currentEndTime = currentStartTime.AddHours(3);
var keeploop = true;
while (keeploop)
{
try
{
SyncOrder(syncOrderByDateRequest.ShopId, String.Empty, currentStartTime, currentEndTime);
}
catch (Exception ex) { }
finally
{
var lessHour = (syncOrderByDateRequest.EndTime - currentEndTime).TotalHours;
if (lessHour > 3)
{
currentStartTime = currentStartTime.AddHours(3);
currentEndTime = currentEndTime.AddHours(3);
}
else if (lessHour > 0 && lessHour < 3)
{
currentStartTime = currentEndTime;
currentEndTime = syncOrderByDateRequest.EndTime;
}
else if (lessHour <= 0)
{
keeploop = false;
}
}
}
try
{
fsql.Update<OrderSyncTask>(orderSyncTask.Id).Set(ost => ost.State, Enums.OrderSyncState.End).ExecuteAffrows();
}
catch (Exception ex) { }
}, System.Threading.CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.SyncOrderTaskScheduler);
}
private void SyncJDOrder(JArray orderTokenJArray, long shopId, string relayAPIHost, string appKey, string appSecret, string appToken, decimal platformCommissionRatio)
{
var orderTokenList = orderTokenJArray.Where(o => o.Value<decimal>("orderTotalPrice") != 0);
var interfaceOrderIdList = orderTokenList.Select(orderJToken => orderJToken.Value<string>("orderId"));
var interfaceCanceledOrderIdList = orderTokenList.Where(orderJToken => orderJToken.Value<string>("orderState").Equals("TRADE_CANCELED"))
.Select(orderJToken => orderJToken.Value<string>("orderId")); //接口查询结果中取消状态的订单Id
var dbOrderList = fsql.Select<Order>().Where(o => interfaceOrderIdList.Contains(o.Id)).ToList(o => new Order()
{
Id = o.Id,
OrderState = o.OrderState,
StorageType = o.StorageType
}); //数据库订单
var dbOrderConsigneeList = fsql.Select<OrderConsignee>().Where(oc => interfaceOrderIdList.Contains(oc.OrderId)).ToList(); //数据库订单收货信息
var dbOrderCostList = fsql.Select<OrderCost>().Where(oc => interfaceOrderIdList.Contains(oc.OrderId)).ToList(); //数据库订单成本信息
var dbOrderCouponList = fsql.Select<OrderCoupon>().Where(oc => interfaceOrderIdList.Contains(oc.OrderId)).ToList(); //数据库订单优惠信息
List<OrderCostDetail> dbOrderCostDetailList = null; //数据库成本明细
if (interfaceCanceledOrderIdList.Count() > 0 &&
dbOrderList.Any(dbOrder => interfaceCanceledOrderIdList.Contains(dbOrder.Id) && dbOrder.OrderState != Enums.OrderState.))
{
dbOrderCostDetailList = fsql.Select<OrderCostDetail>().Where(ocd => interfaceCanceledOrderIdList.Contains(ocd.OrderId)).ToList();
}
var orderSkuIds = new List<string>();
foreach (var orderJToken in orderTokenList)
{
var itemInfoList = orderJToken["itemInfoList"].Where(skuJToken => skuJToken.Value<decimal>("jdPrice") != 0M).Select(skuJToken => skuJToken.Value<string>("skuId"));
foreach (var skuId in itemInfoList)
{
if (!orderSkuIds.Contains(skuId))
orderSkuIds.Add(skuId);
}
}
var dbPurchaseOrderList = fsql.Select<PurchaseOrder>().Where(po => po.RemainingQuantity != 0 && orderSkuIds.Contains(po.SkuId)).ToList(); //数据库采购单
orderSkuIds.Clear();
#region 数据库操作
List<Order> insertOrderList = new List<Order>();
List<OrderConsignee> insertOrderConsigneeList = new List<OrderConsignee>();
List<OrderCost> insertOrderCostList = new List<OrderCost>();
List<OrderCostDetail> insertOrderCostDetailList = new List<OrderCostDetail>();
List<OrderSku> insertOrderSkuList = new List<OrderSku>();
List<OrderCoupon> insertOrderCouponList = new List<OrderCoupon>();
IList<IUpdate<Order>> updateOrderList = new List<IUpdate<Order>>();
IList<IUpdate<PurchaseOrder>> updatePurchaseOrderList = new List<IUpdate<PurchaseOrder>>();
#endregion
foreach (var orderJToken in orderTokenList)
{
var orderId = orderJToken.Value<string>("orderId");
var dbOrder = dbOrderList.FirstOrDefault(o => o.Id == orderId);
var isNewOrder = dbOrder == null;
#region 订单基本信息
var buyerRemark = orderJToken.Value<string>("orderRemark");
var venderRemark = orderJToken.Value<string>("venderRemark");
var modifyTime = orderJToken.Value<DateTime?>("modified");
var endTime = orderJToken.Value<DateTime?>("orderEndTime");
var waybillNo = orderJToken.Value<string>("waybill");
if (dbOrder == null)
{
dbOrder = new Order()
{
Id = orderId,
BuyerRemark = buyerRemark,
VenderRemark = venderRemark,
FreightPrice = orderJToken.Value<decimal>("freightPrice"),
EndTime = endTime,
StartTime = orderJToken.Value<DateTime>("orderStartTime"),
ModifyTime = modifyTime,
OrderPayment = orderJToken.Value<decimal>("orderPayment"),
OrderSellerPrice = orderJToken.Value<decimal>("orderSellerPrice"),
OrderTotalPrice = orderJToken.Value<decimal>("orderTotalPrice"),
OrderType = (Enums.OrderType)orderJToken.Value<int>("orderType"),
Platform = Enums.Platform.,
ShopId = shopId,
//VenderId = orderJToken.Value<long>("venderId"),
WaybillNo = waybillNo,
StoreOrder = orderJToken.Value<string>("storeOrder") ?? string.Empty,
StoreId = orderJToken.Value<string>("storeId")
};
if (dbOrder.StoreOrder.Contains("京仓"))
dbOrder.StorageType = Enums.StorageType.;
else if (dbOrder.StoreOrder.Contains("云仓"))
dbOrder.StorageType = Enums.StorageType.;
var payType = orderJToken.Value<string>("payType");
if (payType.Contains("-"))
dbOrder.PayType = (Enums.PayType)Convert.ToInt32(payType.Substring(0, 1));
insertOrderList.Add(dbOrder);
#region OrderSku
var orderSkuList = orderJToken["itemInfoList"].Where(skuJToken => skuJToken.Value<decimal>("jdPrice") != 0M).Select(skuToken => new OrderSku()
{
Id = idGenerator.NewLong(),
ItemTotal = skuToken.Value<int>("itemTotal"),
Price = skuToken.Value<decimal>("jdPrice"),
ProductId = skuToken.Value<string>("wareId"),
Title = skuToken.Value<string>("skuName").SimplifySkuName(),
ProductNo = skuToken.Value<string>("productNo"),
CreateTime = DateTime.Now,
OrderId = orderId,
SkuId = skuToken.Value<string>("skuId")
}).ToList();
insertOrderSkuList.AddRange(orderSkuList);
#endregion
}
#endregion
#region 收货人信息
if (dbOrderConsigneeList.FirstOrDefault(oc => oc.OrderId == orderId) == null)
{
var orderConsignee = new OrderConsignee()
{
OrderId = orderId,
//Address = orderJToken["consigneeInfo"].Value<string>("fullAddress"),
//ContactName = orderJToken["consigneeInfo"].Value<string>("fullname"),
//Mobile = orderJToken["consigneeInfo"].Value<string>("mobile"),
//TelePhone = orderJToken["consigneeInfo"].Value<string>("telephone"),
City = orderJToken["consigneeInfo"].Value<string>("city"),
Province = orderJToken["consigneeInfo"].Value<string>("province"),
County = orderJToken["consigneeInfo"].Value<string>("county"),
Town = orderJToken["consigneeInfo"].Value<string>("town"),
IsDecode = false,
CreateTime = DateTime.Now
};
insertOrderConsigneeList.Add(orderConsignee);
}
#endregion
#region 订单优惠
if (!dbOrderCouponList.Any(oc => oc.OrderId == orderId))
{
var orderCouponJArray = (JArray)orderJToken["couponDetailList"];
if (orderCouponJArray.HasValues)
{
foreach (var orderCouponJToken in orderCouponJArray)
{
var couponType = orderCouponJToken.Value<string>("couponType");
if (string.IsNullOrEmpty(couponType))
continue;
dbOrder.PreferentialAmount += orderCouponJToken.Value<decimal>("couponPrice");
insertOrderCouponList.Add(new OrderCoupon()
{
Id = idGenerator.NewLong(),
SkuId = orderCouponJToken.Value<string>("skuId"),
OrderId = orderId,
CreateTime = DateTime.Now,
CouponType = couponType,
CouponPrice = orderCouponJToken.Value<decimal>("couponPrice")
});
}
}
}
#endregion
#region 订单状态转换
var jdOrderState = orderJToken.Value<string>("orderState");
Enums.OrderState? orderState = null;
#region SOP状态翻译
if (jdOrderState.Equals("NOT_PAY")) //未付款
{
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("WAIT_SELLER_STOCK_OUT")) //等待出库
{
orderState = Enums.OrderState.;
if (dbOrder.StorageType != null)
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("WAIT_GOODS_RECEIVE_CONFIRM"))
{
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("FINISHED_L"))
{
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("LOCKED"))
{
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("TRADE_CANCELED"))
{
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("POP_ORDER_PAUSE") || jdOrderState.Equals("PAUSE"))
{
orderState = Enums.OrderState.;
}
#endregion
#region FBP状态翻译
else if (jdOrderState.Equals("DengDaiDaYin") || jdOrderState.Equals("DengDaiChuKu") || jdOrderState.Equals("DengDaiDaBao") || jdOrderState.Equals("DengDaiFaHuo"))
{
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("DengDaiQueRenShouHuo"))
{
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("WanCheng"))
{
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("SuoDing") || jdOrderState.Equals("LOCKED"))
{
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("TRADE_CANCELED"))
{
orderState = Enums.OrderState.;
}
#endregion
#endregion
#region 取消订单恢复库存
if (orderState == Enums.OrderState. &&
!isNewOrder &&
dbOrder.OrderState != Enums.OrderState. &&
dbOrder.StorageType != Enums.StorageType.SD &&
dbOrder.StorageType != Enums.StorageType.)
{
var currentOrderCostDetailList = dbOrderCostDetailList.Where(ocd => ocd.OrderId == orderId);
if (currentOrderCostDetailList.Count() > 0)
{
foreach (var orderCostDetail in currentOrderCostDetailList)
{
var updateSql = fsql.Update<PurchaseOrder>(orderCostDetail.PurchaseOrderPKId)
.Set(po => po.RemainingQuantity + orderCostDetail.DeductionQuantity);
updatePurchaseOrderList.Add(updateSql);
}
}
}
#endregion
#region 扣减库存, 计算成本
if (dbOrder.StorageType != null &&
dbOrder.StorageType != Enums.StorageType.SD &&
dbOrder.StorageType != Enums.StorageType. &&
orderState != null &&
orderState != Enums.OrderState. &&
orderState != Enums.OrderState.)
{
var orderCost = dbOrderCostList.FirstOrDefault(oc => oc.OrderId == dbOrder.Id);
if (orderCost == null)
{
//再查询一次数据库,以防同步开始执行后被人为操作扣减库存,造成重复扣减库存
if (!fsql.Select<OrderCost>(dbOrder.Id).Any())
{
var orderSkuJArray = orderJToken["itemInfoList"].Where(skuJToken => skuJToken.Value<decimal>("jdPrice") != 0M);
if (orderSkuJArray != null && orderSkuJArray.Count() > 0)
{
var orderCostPurchaseAmount = 0M;
var orderDeliveryExpressFreight = 0M; //发货总运费,sku购买数量第二个开始半价
#region 扣减库存
foreach (var orderSkuJToken in orderSkuJArray)
{
var orderSkuId = orderSkuJToken.Value<string>("skuId");
var itemTotal = orderSkuJToken.Value<int>("itemTotal"); //sku购买数量
var isReduceMultiTimes = false; //是否多次扣减库存
while (itemTotal != 0)
{
var purchaseOrder = dbPurchaseOrderList.FirstOrDefault(po => po.StorageType == dbOrder.StorageType &&
po.RemainingQuantity != 0 &&
po.SkuId == orderSkuId);
if (purchaseOrder == null)
break; //没有库存了
//本次扣减量
var deductionQuantity = purchaseOrder.RemainingQuantity >= itemTotal ? itemTotal : purchaseOrder.RemainingQuantity;
//本次扣减量的采购成本
var currentPurchaseAmount = purchaseOrder.UnitCost * deductionQuantity;
//本次扣减量的发货运费
var currentSkuDeliveryFreight = isReduceMultiTimes ?
(purchaseOrder.SingleDeliveryFreight / 2 * deductionQuantity) :
(purchaseOrder.SingleDeliveryFreight + purchaseOrder.SingleDeliveryFreight / 2 * (deductionQuantity - 1));
purchaseOrder.RemainingQuantity -= deductionQuantity;
itemTotal -= deductionQuantity;
//累计采购成本
orderCostPurchaseAmount += currentPurchaseAmount;
//累计发货运费(销售运费)
orderDeliveryExpressFreight += currentSkuDeliveryFreight;
isReduceMultiTimes = true;
var updateSql = fsql.Update<PurchaseOrder>(purchaseOrder.Id).Set(po => po.RemainingQuantity - deductionQuantity);
updatePurchaseOrderList.Add(updateSql);
var orderCostDetail = new OrderCostDetail()
{
Id = idGenerator.NewLong(),
OrderId = orderId,
ProductId = orderSkuJToken.Value<string>("wareId"),
SkuId = orderSkuId,
CreateTime = DateTime.Now,
PurchaseOrderPKId = purchaseOrder.Id,
UnitCost = purchaseOrder.UnitCost,
DeductionQuantity = deductionQuantity,
DeliveryExpressFreight = currentSkuDeliveryFreight,
TotalCost = currentPurchaseAmount,
ConsumableAmount = purchaseOrder.SingleConsumableAmount * deductionQuantity,
FirstFreight = purchaseOrder.SingleFirstFreight * deductionQuantity,
OperationAmount = purchaseOrder.SingleOperationAmount * deductionQuantity,
PurchaseFreight = purchaseOrder.SingleFreight * deductionQuantity,
SkuAmount = purchaseOrder.SingleSkuAmount * deductionQuantity,
StorageAmount = purchaseOrder.SingleStorageAmount * deductionQuantity
};
insertOrderCostDetailList.Add(orderCostDetail);
}
}
#endregion
#region 计算成本
orderCost = new OrderCost()
{
OrderId = orderId,
PlatformCommissionRatio = platformCommissionRatio,
PreferentialAmount = dbOrder.PreferentialAmount,
Profit = 0,
PurchaseAmount = orderCostPurchaseAmount,
DeliveryExpressFreight = orderDeliveryExpressFreight,
CreateTime = DateTime.Now
};
orderCost.PlatformCommissionAmount = dbOrder.OrderSellerPrice * orderCost.PlatformCommissionRatio;
orderCost.Profit = dbOrder.OrderSellerPrice +
dbOrder.FreightPrice -
orderCost.PurchaseAmount -
orderCost.DeliveryExpressFreight -
orderCost.PlatformCommissionAmount;
insertOrderCostList.Add(orderCost);
#endregion
}
}
}
}
#endregion
#region 检查订单信息是否变化
if (isNewOrder)
{
dbOrder.OrderState = orderState;
}
else if ((orderState != null && orderState != dbOrder.OrderState) ||
buyerRemark != dbOrder.BuyerRemark ||
venderRemark != dbOrder.VenderRemark ||
modifyTime != dbOrder.ModifyTime ||
endTime != dbOrder.EndTime ||
waybillNo != dbOrder.WaybillNo)
{
var updateSql = fsql.Update<Order>(orderId).SetIf(orderState != null && orderState != dbOrder.OrderState, o => o.OrderState, orderState)
.SetIf(buyerRemark != dbOrder.BuyerRemark, o => o.BuyerRemark, buyerRemark)
.SetIf(venderRemark != dbOrder.VenderRemark, o => o.VenderRemark, venderRemark)
.SetIf(modifyTime != dbOrder.ModifyTime, o => o.ModifyTime, modifyTime)
.SetIf(endTime != dbOrder.EndTime, o => o.EndTime, modifyTime)
.SetIf(waybillNo != dbOrder.WaybillNo, o => o.WaybillNo, waybillNo);
updateOrderList.Add(updateSql);
}
#endregion
}
#region 补齐sku logo
if (insertOrderSkuList.Count() > 0)
{
foreach (var orderSku in insertOrderSkuList)
{
if (!orderSkuIds.Contains(orderSku.SkuId))
orderSkuIds.Add(orderSku.SkuId);
}
var orderSkuRequestCount = (orderSkuIds.Count() - 1) / 50 + 1; //sku最多一次请求50条
for (var i = 0; i < orderSkuRequestCount; i++)
{
var orderSkuIdString = string.Join(",", orderSkuIds.Skip(i * 50).Take(50));
var skuHttpResult = restApiService.SendRequest(relayAPIHost, "Api/PlatformSDK/GetSimpleProductSkuList", new SearchProductSkuRequest()
{
AppKey = appKey,
AppSecret = appSecret,
AppToken = appToken,
Platform = Enums.Platform.,
Sku = orderSkuIdString
}, null, HttpMethod.Post);
if (skuHttpResult.StatusCode != System.Net.HttpStatusCode.OK)
continue;
var skuResponse = JsonConvert.DeserializeObject<ApiResponse<IList<SimpleProductSkuResponse>>>(skuHttpResult.Content);
if (!skuResponse.Success)
continue;
foreach (var sku in skuResponse.Data)
{
var insertSkus = insertOrderSkuList.Where(orderSku => orderSku.SkuId == sku.Id);
foreach (var insertSku in insertSkus) { insertSku.Logo = sku.Logo; }
}
}
}
#endregion
fsql.Transaction(() =>
{
if (insertOrderList.Count() > 0)
fsql.Insert(insertOrderList).ExecuteAffrows();
if (insertOrderSkuList.Count() > 0)
fsql.Insert(insertOrderSkuList).ExecuteAffrows();
if (insertOrderConsigneeList.Count() > 0)
fsql.Insert(insertOrderConsigneeList).ExecuteAffrows();
if (insertOrderCostList.Count() > 0)
fsql.Insert(insertOrderCostList).ExecuteAffrows();
if (insertOrderCostDetailList.Count() > 0)
fsql.Insert(insertOrderCostDetailList).ExecuteAffrows();
if (insertOrderCouponList.Count() > 0)
fsql.Insert(insertOrderCouponList).ExecuteAffrows();
if (updatePurchaseOrderList.Count() > 0)
{
foreach (var update in updatePurchaseOrderList)
update.ExecuteAffrows();
}
if (updateOrderList.Count() > 0)
{
foreach (var update in updateOrderList)
update.ExecuteAffrows();
}
});
}
}
}